forked from qt-creator/qt-creator
EffectMaker: Update changed effect to 2D/property views
The effect directory will be rescanned to update the types, and the puppet is reset if updated types are in use in the current document. If updated effect was also selected, selection is refreshed to update property view. Fixes: QDS-11367 Change-Id: I79cf476d8a70295f79525b6e1a5eeda27bb0b637 Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io> Reviewed-by: Qt CI Patch Build Bot <ci_patchbuild_bot@qt.io>
This commit is contained in:
@@ -720,6 +720,8 @@ void EffectMakerModel::exportResources(const QString &name)
|
||||
if (!source.copyFile(target))
|
||||
qWarning() << __FUNCTION__ << " Failed to copy file: " << source;
|
||||
}
|
||||
|
||||
emit resourcesExported(QString("Effects.%1.%1").arg(name).toUtf8(), effectPath);
|
||||
}
|
||||
|
||||
void EffectMakerModel::resetEffectError(int type)
|
||||
|
||||
@@ -100,6 +100,7 @@ signals:
|
||||
|
||||
void currentCompositionChanged();
|
||||
void nodesChanged();
|
||||
void resourcesExported(const QByteArray &type, const Utils::FilePath &path);
|
||||
|
||||
private:
|
||||
enum Roles {
|
||||
|
||||
@@ -17,16 +17,21 @@
|
||||
|
||||
#include <coreplugin/icore.h>
|
||||
|
||||
#include <qmldesigner/documentmanager.h>
|
||||
#include <qmldesigner/qmldesignerconstants.h>
|
||||
#include <qmldesigner/qmldesignerplugin.h>
|
||||
#include <studioquickwidget.h>
|
||||
|
||||
#include <qmljs/qmljsmodelmanagerinterface.h>
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/async.h>
|
||||
#include <utils/environment.h>
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QQmlEngine>
|
||||
#include <QTimer>
|
||||
|
||||
namespace EffectMaker {
|
||||
|
||||
@@ -77,9 +82,27 @@ EffectMakerWidget::EffectMakerWidget(EffectMakerView *view)
|
||||
QmlDesigner::QmlDesignerPlugin::trackWidgetFocusTime(
|
||||
this, QmlDesigner::Constants::EVENT_NEWEFFECTMAKER_TIME);
|
||||
|
||||
connect(m_effectMakerModel.data(), &EffectMakerModel::nodesChanged, [this]() {
|
||||
connect(m_effectMakerModel.data(), &EffectMakerModel::nodesChanged, this, [this]() {
|
||||
m_effectMakerNodesModel->updateCanBeAdded(m_effectMakerModel->uniformNames());
|
||||
});
|
||||
|
||||
connect(m_effectMakerModel.data(), &EffectMakerModel::resourcesExported,
|
||||
this, [this](const QmlDesigner::TypeName &type, const Utils::FilePath &path) {
|
||||
if (!m_importScan.timer) {
|
||||
m_importScan.timer = new QTimer(this);
|
||||
connect(m_importScan.timer, &QTimer::timeout,
|
||||
this, &EffectMakerWidget::handleImportScanTimer);
|
||||
}
|
||||
|
||||
if (m_importScan.timer->isActive() && !m_importScan.future.isFinished())
|
||||
m_importScan.future.cancel();
|
||||
|
||||
m_importScan.counter = 0;
|
||||
m_importScan.type = type;
|
||||
m_importScan.path = path;
|
||||
|
||||
m_importScan.timer->start(100);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -177,5 +200,65 @@ void EffectMakerWidget::reloadQmlSource()
|
||||
m_quickWidget->setSource(QUrl::fromLocalFile(effectMakerQmlPath));
|
||||
}
|
||||
|
||||
void EffectMakerWidget::handleImportScanTimer()
|
||||
{
|
||||
++m_importScan.counter;
|
||||
|
||||
if (m_importScan.counter == 1) {
|
||||
// Rescan the effect import to update code model
|
||||
auto modelManager = QmlJS::ModelManagerInterface::instance();
|
||||
if (modelManager) {
|
||||
QmlJS::PathsAndLanguages pathToScan;
|
||||
pathToScan.maybeInsert(m_importScan.path);
|
||||
m_importScan.future = ::Utils::asyncRun(&QmlJS::ModelManagerInterface::importScan,
|
||||
modelManager->workingCopy(),
|
||||
pathToScan, modelManager, true, true, true);
|
||||
}
|
||||
} else if (m_importScan.counter < 100) {
|
||||
// We have to wait a while to ensure qmljs detects new files and updates its
|
||||
// internal model. Then we force amend on rewriter to trigger qmljs snapshot update.
|
||||
if (m_importScan.future.isCanceled() || m_importScan.future.isFinished())
|
||||
m_importScan.counter = 100; // skip the timeout step
|
||||
} else if (m_importScan.counter == 100) {
|
||||
// Scanning is taking too long, abort
|
||||
m_importScan.future.cancel();
|
||||
m_importScan.timer->stop();
|
||||
m_importScan.counter = 0;
|
||||
} else if (m_importScan.counter == 101) {
|
||||
if (m_effectMakerView->model() && m_effectMakerView->model()->rewriterView()) {
|
||||
QmlDesigner::QmlDesignerPlugin::instance()->documentManager().resetPossibleImports();
|
||||
m_effectMakerView->model()->rewriterView()->forceAmend();
|
||||
}
|
||||
} else if (m_importScan.counter == 102) {
|
||||
if (m_effectMakerView->model()) {
|
||||
// If type is in use, we have to reset puppet to update 2D view
|
||||
if (!m_effectMakerView->allModelNodesOfType(
|
||||
m_effectMakerView->model()->metaInfo(m_importScan.type)).isEmpty()) {
|
||||
m_effectMakerView->resetPuppet();
|
||||
}
|
||||
}
|
||||
} else if (m_importScan.counter >= 103) {
|
||||
// Refresh property view by resetting selection if any selected node is of updated type
|
||||
if (m_effectMakerView->model() && m_effectMakerView->hasSelectedModelNodes()) {
|
||||
const auto nodes = m_effectMakerView->selectedModelNodes();
|
||||
QmlDesigner::MetaInfoType metaType
|
||||
= m_effectMakerView->model()->metaInfo(m_importScan.type).type();
|
||||
bool match = false;
|
||||
for (const QmlDesigner::ModelNode &node : nodes) {
|
||||
if (node.metaInfo().type() == metaType) {
|
||||
match = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (match) {
|
||||
m_effectMakerView->clearSelectedModelNodes();
|
||||
m_effectMakerView->setSelectedModelNodes(nodes);
|
||||
}
|
||||
}
|
||||
m_importScan.timer->stop();
|
||||
m_importScan.counter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace EffectMaker
|
||||
|
||||
|
||||
@@ -9,9 +9,14 @@
|
||||
#include <coreplugin/icontext.h>
|
||||
|
||||
#include <QFrame>
|
||||
#include <QFuture>
|
||||
|
||||
class StudioQuickWidget;
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QTimer;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace EffectMaker {
|
||||
|
||||
class EffectMakerView;
|
||||
@@ -51,6 +56,7 @@ protected:
|
||||
|
||||
private:
|
||||
void reloadQmlSource();
|
||||
void handleImportScanTimer();
|
||||
|
||||
QPointer<EffectMakerModel> m_effectMakerModel;
|
||||
QPointer<EffectMakerNodesModel> m_effectMakerNodesModel;
|
||||
@@ -58,6 +64,16 @@ private:
|
||||
QPointer<StudioQuickWidget> m_quickWidget;
|
||||
QmlDesigner::QmlModelNodeProxy m_backendModelNode;
|
||||
QmlDesigner::QmlAnchorBindingProxy m_backendAnchorBinding;
|
||||
|
||||
struct ImportScanData {
|
||||
QFuture<void> future;
|
||||
int counter = 0;
|
||||
QTimer *timer = nullptr;
|
||||
QmlDesigner::TypeName type;
|
||||
Utils::FilePath path;
|
||||
};
|
||||
|
||||
ImportScanData m_importScan;
|
||||
};
|
||||
|
||||
} // namespace EffectMaker
|
||||
|
||||
Reference in New Issue
Block a user