diff --git a/src/plugins/qmldesigner/components/componentcore/bundleimporter.cpp b/src/plugins/qmldesigner/components/componentcore/bundleimporter.cpp index 7bd75751647..e83757a549a 100644 --- a/src/plugins/qmldesigner/components/componentcore/bundleimporter.cpp +++ b/src/plugins/qmldesigner/components/componentcore/bundleimporter.cpp @@ -12,7 +12,9 @@ #include #include +#ifndef QDS_USE_PROJECTSTORAGE #include +#endif #include #include @@ -52,15 +54,19 @@ QString BundleImporter::importComponent(const QString &bundleDir, if (!bundleImportPath.exists() && !bundleImportPath.createDir()) return QStringLiteral("Failed to create bundle import folder: '%1'").arg(bundleImportPath.toUrlishString()); +#ifndef QDS_USE_PROJECTSTORAGE bool doScan = false; bool doReset = false; +#endif FilePath qmldirPath = bundleImportPath.pathAppended("qmldir"); QString qmldirContent = QString::fromUtf8(qmldirPath.fileContents().value_or(QByteArray())); if (qmldirContent.isEmpty()) { qmldirContent.append("module "); qmldirContent.append(module); qmldirContent.append('\n'); +#ifndef QDS_USE_PROJECTSTORAGE doScan = true; +#endif } FilePath qmlSourceFile = bundleImportPath.pathAppended(qmlFile); @@ -75,7 +81,9 @@ QString BundleImporter::importComponent(const QString &bundleDir, qmldirContent.append(qmlFile); qmldirContent.append('\n'); qmldirPath.writeFileContents(qmldirContent.toUtf8()); +#ifndef QDS_USE_PROJECTSTORAGE doReset = true; +#endif } QStringList allFiles; @@ -118,15 +126,15 @@ QString BundleImporter::importComponent(const QString &bundleDir, ImportData data; data.isImport = true; data.type = type; + Import import = Import::createLibraryImport(module, "1.0"); +#ifdef QDS_USE_PROJECTSTORAGE + model->changeImports({import}, {}); +#else if (doScan) data.pathToScan = bundleImportPath; else data.fullReset = doReset; - Import import = Import::createLibraryImport(module, "1.0"); -#ifdef QDS_USE_PROJECTSTORAGE - model->changeImports({import}, {}); -#else if (!model->hasImport(import)) { if (model->possibleImports().contains(import)) { try { @@ -151,6 +159,51 @@ QString BundleImporter::importComponent(const QString &bundleDir, void BundleImporter::handleImportTimer() { +#ifdef QDS_USE_PROJECTSTORAGE + auto handleFailure = [this] { + m_importTimer.stop(); + m_importTimerCount = 0; + + // Emit dummy finished signals for all pending types + const QList pendingTypes = m_pendingImports.keys(); + for (const TypeName &pendingType : pendingTypes) { + ImportData data = m_pendingImports.take(pendingType); + if (data.isImport) + emit importFinished({}, m_bundleId); + else + emit unimportFinished({}, m_bundleId); + } + m_bundleId.clear(); + }; + + auto doc = QmlDesignerPlugin::instance()->currentDesignDocument(); + Model *model = doc ? doc->currentModel() : nullptr; + if (!model || ++m_importTimerCount > 100) { + handleFailure(); + return; + } + + const QList keys = m_pendingImports.keys(); + for (const TypeName &type : keys) { + ImportData &data = m_pendingImports[type]; + // Verify that code model has the new type fully available (or removed for unimport) + NodeMetaInfo metaInfo = model->metaInfo(type); + const bool typeComplete = metaInfo.isValid() && !metaInfo.prototypes().empty(); + if (data.isImport == typeComplete) { + m_pendingImports.remove(type); + if (data.isImport) + emit importFinished(type, m_bundleId); + else + emit unimportFinished(metaInfo, m_bundleId); + } + } + + if (m_pendingImports.isEmpty()) { + m_bundleId.clear(); + m_importTimer.stop(); + m_importTimerCount = 0; + } +#else auto handleFailure = [this] { m_importTimer.stop(); m_importTimerCount = 0; @@ -277,11 +330,7 @@ void BundleImporter::handleImportTimer() if (data.isImport == typeComplete) { m_pendingImports.remove(type); if (data.isImport) -#ifdef QDS_USE_PROJECTSTORAGE - emit importFinished(type, m_bundleId); -#else emit importFinished(metaInfo, m_bundleId); -#endif else emit unimportFinished(metaInfo, m_bundleId); } @@ -296,6 +345,7 @@ void BundleImporter::handleImportTimer() m_importTimerCount = 0; disconnect(m_libInfoConnection); } +#endif } QVariantHash BundleImporter::loadAssetRefMap(const FilePath &bundlePath) @@ -411,7 +461,9 @@ QString BundleImporter::unimportComponent(const TypeName &type, const QString &q ImportData data; data.isImport = false; data.type = type; +#ifndef QDS_USE_PROJECTSTORAGE data.fullReset = true; +#endif m_pendingImports.insert(type, data); m_importTimerCount = 0; diff --git a/src/plugins/qmldesigner/components/componentcore/bundleimporter.h b/src/plugins/qmldesigner/components/componentcore/bundleimporter.h index 7e3463adc38..3c743bfe55b 100644 --- a/src/plugins/qmldesigner/components/componentcore/bundleimporter.h +++ b/src/plugins/qmldesigner/components/componentcore/bundleimporter.h @@ -7,7 +7,9 @@ #include +#ifndef QDS_USE_PROJECTSTORAGE #include +#endif #include #include @@ -48,6 +50,13 @@ private: QTimer m_importTimer; int m_importTimerCount = 0; QString m_bundleId; +#ifdef QDS_USE_PROJECTSTORAGE + struct ImportData + { + bool isImport = true; // false = unimport + TypeName type; + }; +#else struct ImportData { enum State { @@ -66,8 +75,10 @@ private: State state = Starting; }; - QHash m_pendingImports; QMetaObject::Connection m_libInfoConnection; +#endif + + QHash m_pendingImports; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/componentcore/utils3d.cpp b/src/plugins/qmldesigner/components/componentcore/utils3d.cpp index e8d79cfa600..34fab1415c7 100644 --- a/src/plugins/qmldesigner/components/componentcore/utils3d.cpp +++ b/src/plugins/qmldesigner/components/componentcore/utils3d.cpp @@ -369,18 +369,20 @@ ModelNode createMaterial(AbstractView *view, const NodeMetaInfo &metaInfo) } #endif -void addQuick3DImportAndView3D(AbstractView *view) +bool addQuick3DImportAndView3D(AbstractView *view, bool suppressWarningDialog) { DesignDocument *document = QmlDesignerPlugin::instance()->currentDesignDocument(); if (!view || !view->model() || !document || document->inFileComponentModelActive()) { - Core::AsynchronousMessageBox::warning(Tr::tr("Failed to Add Import"), - Tr::tr("Could not add QtQuick3D import to the document.")); - return; + if (!suppressWarningDialog) { + Core::AsynchronousMessageBox::warning(Tr::tr("Failed to Add Import"), + Tr::tr("Could not add QtQuick3D import to the document.")); + } + return false; } QString importName{"QtQuick3D"}; if (view->model()->hasImport(importName)) - return; + return true; view->executeInTransaction(__FUNCTION__, [&] { Import import = Import::createLibraryImport(importName); @@ -417,6 +419,7 @@ void addQuick3DImportAndView3D(AbstractView *view) if (!models.isEmpty()) assignMaterialTo3dModel(view, models.at(0)); }); + return true; } // Assigns given material to a 3D model. diff --git a/src/plugins/qmldesigner/components/componentcore/utils3d.h b/src/plugins/qmldesigner/components/componentcore/utils3d.h index 4531f3ee36b..3f77326e53d 100644 --- a/src/plugins/qmldesigner/components/componentcore/utils3d.h +++ b/src/plugins/qmldesigner/components/componentcore/utils3d.h @@ -60,7 +60,7 @@ ModelNode createMaterial(AbstractView *view); void renameMaterial(const ModelNode &material, const QString &newName); void duplicateMaterial(AbstractView *view, const ModelNode &material); -void addQuick3DImportAndView3D(AbstractView *view); +bool addQuick3DImportAndView3D(AbstractView *view, bool suppressWarningDialog = false); void assignMaterialTo3dModel(AbstractView *view, const ModelNode &modelNode, const ModelNode &materialNode = {}); diff --git a/src/plugins/qmldesigner/components/edit3d/bakelights.cpp b/src/plugins/qmldesigner/components/edit3d/bakelights.cpp index c7a441e21bf..0410bbf3e5e 100644 --- a/src/plugins/qmldesigner/components/edit3d/bakelights.cpp +++ b/src/plugins/qmldesigner/components/edit3d/bakelights.cpp @@ -22,7 +22,9 @@ #include #include +#ifndef QDS_USE_PROJECTSTORAGE #include +#endif #include #include @@ -283,11 +285,12 @@ void BakeLights::exposeModelsAndLights(const QString &nodeId) } } +#ifndef QDS_USE_PROJECTSTORAGE QmlJS::ModelManagerInterface *modelManager = QmlJS::ModelManagerInterface::instance(); QmlJS::Document::Ptr doc = rewriter.document(); modelManager->updateDocument(doc); - m_view->model()->rewriterView()->forceAmend(); +#endif compModel->setRewriterView({}); diff --git a/src/plugins/qmldesigner/components/import3d/import3dimporter.cpp b/src/plugins/qmldesigner/components/import3d/import3dimporter.cpp index a249250122a..bcec14f7199 100644 --- a/src/plugins/qmldesigner/components/import3d/import3dimporter.cpp +++ b/src/plugins/qmldesigner/components/import3d/import3dimporter.cpp @@ -16,8 +16,11 @@ #include "viewmanager.h" #include +#include +#ifndef QDS_USE_PROJECTSTORAGE #include +#endif #include #include @@ -241,7 +244,6 @@ void Import3dImporter::reset() m_importFiles.clear(); m_puppetProcess.reset(); m_parseData.clear(); - m_requiredImports.clear(); m_currentImportId = 0; m_puppetQueue.clear(); m_importIdToAssetNameMap.clear(); @@ -449,13 +451,7 @@ void Import3dImporter::postParseQuick3DAsset(ParseData &pd) } } } - - // Add quick3D import unless it is already added - if (impVersionMajor > 0 && (m_requiredImports.isEmpty() - || m_requiredImports.first() != "QtQuick3D")) { - m_requiredImports.prepend("QtQuick3D"); - } - } + } } } } @@ -698,6 +694,11 @@ void Import3dImporter::finalizeQuick3DImport() addInfo(progressTitle); notifyProgress(0, progressTitle); + QTimer *timer = new QTimer(parent()); + static int counter; + counter = 0; + +#ifndef QDS_USE_PROJECTSTORAGE auto modelManager = QmlJS::ModelManagerInterface::instance(); QFuture result; if (modelManager) { @@ -711,49 +712,17 @@ void Import3dImporter::finalizeQuick3DImport() true, true); } - // First 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. - QTimer *timer = new QTimer(parent()); - static int counter; - counter = 0; - timer->callOnTimeout([this, timer, progressTitle, model, result]() { if (!isCancelled()) { notifyProgress(++counter * 2, progressTitle); - if (counter < 49) { + if (counter == 1) { + if (!Utils3D::addQuick3DImportAndView3D(model->rewriterView(), true)) + addError(tr("Failed to insert QtQuick3D import to the qml document.")); + } else if (counter < 50) { if (result.isCanceled() || result.isFinished()) - counter = 48; // skip to next step - } else if (counter == 49) { -#ifndef QDS_USE_PROJECTSTORAGE - QmlDesignerPlugin::instance()->documentManager().resetPossibleImports(); - model->rewriterView()->forceAmend(); - try { - RewriterTransaction transaction = model->rewriterView()->beginRewriterTransaction( - QByteArrayLiteral("Import3dImporter::finalizeQuick3DImport")); - bool success = ModelUtils::addImportsWithCheck(m_requiredImports, model); - if (!success) - addError(tr("Failed to insert import statement into qml document.")); - transaction.commit(); -#else - const Imports &imports = model->imports(); - Imports importsToAdd; - for (const QString &importName : std::as_const(m_requiredImports)) { - auto hasName = [&](const auto &import) { - return import.url() == importName || import.file() == importName; - }; - if (!Utils::anyOf(imports, hasName)) { - Import import = Import::createLibraryImport(importName); - importsToAdd.push_back(import); - } - } - - try { - model->changeImports(std::move(importsToAdd), {}); -#endif - } catch (const RewritingException &e) { - addError(tr("Failed to update imports: %1").arg(e.description())); - } + counter = 49; // skip to next step } else if (counter >= 50) { for (const ParseData &pd : std::as_const(m_parseData)) { if (!pd.overwrittenImports.isEmpty()) { @@ -766,6 +735,27 @@ void Import3dImporter::finalizeQuick3DImport() notifyFinished(); model->rewriterView()->emitCustomNotification("asset_import_finished"); } +#else + counter = 0; + timer->callOnTimeout([this, timer, progressTitle, model]() { + if (!isCancelled()) { + notifyProgress(++counter * 50, progressTitle); + if (counter == 1) { + if (!Utils3D::addQuick3DImportAndView3D(model->rewriterView(), true)) + addError(tr("Failed to insert QtQuick3D import to the qml document.")); + } else if (counter > 1) { + for (const ParseData &pd : std::as_const(m_parseData)) { + if (!pd.overwrittenImports.isEmpty()) { + model->rewriterView()->resetPuppet(); + model->rewriterView()->emitCustomNotification("asset_import_update"); + break; + } + } + timer->stop(); + notifyFinished(); + model->rewriterView()->emitCustomNotification("asset_import_finished"); + } +#endif } else { timer->stop(); } diff --git a/src/plugins/qmldesigner/components/import3d/import3dimporter.h b/src/plugins/qmldesigner/components/import3d/import3dimporter.h index 594a1c98603..b08789954da 100644 --- a/src/plugins/qmldesigner/components/import3d/import3dimporter.h +++ b/src/plugins/qmldesigner/components/import3d/import3dimporter.h @@ -126,7 +126,6 @@ private: QHash m_importIdToAssetNameMap; QHash m_parseData; // Key: asset name QString m_progressTitle; - QStringList m_requiredImports; QList m_puppetQueue; }; } // QmlDesigner