forked from qt-creator/qt-creator
QmlDesigner: Simplify conditional import adding
Change-Id: I78e110a81f8117b711968b6be5b4241f96763c41 Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
This commit is contained in:
@@ -343,6 +343,8 @@ extend_qtc_library(QmlDesignerCore
|
|||||||
modelnodepositionstorage.cpp
|
modelnodepositionstorage.cpp
|
||||||
modeltotextmerger.cpp
|
modeltotextmerger.cpp
|
||||||
modeltotextmerger.h
|
modeltotextmerger.h
|
||||||
|
modelutils.cpp
|
||||||
|
modelutils.h
|
||||||
nodeabstractproperty.cpp
|
nodeabstractproperty.cpp
|
||||||
nodelistproperty.cpp
|
nodelistproperty.cpp
|
||||||
nodeproperty.cpp
|
nodeproperty.cpp
|
||||||
|
@@ -67,7 +67,7 @@ public:
|
|||||||
void disableWidgets();
|
void disableWidgets();
|
||||||
void enableWidgets();
|
void enableWidgets();
|
||||||
|
|
||||||
void pushFileOnCrumbleBar(const Utils::FilePath &fileName);
|
void pushFileOnCrumbleBar(const ::Utils::FilePath &fileName);
|
||||||
void pushInFileComponentOnCrumbleBar(const ModelNode &modelNode);
|
void pushInFileComponentOnCrumbleBar(const ModelNode &modelNode);
|
||||||
void nextFileIsCalledInternally();
|
void nextFileIsCalledInternally();
|
||||||
|
|
||||||
|
@@ -23,6 +23,8 @@
|
|||||||
#include "seekerslider.h"
|
#include "seekerslider.h"
|
||||||
#include "theme.h"
|
#include "theme.h"
|
||||||
|
|
||||||
|
#include <model/modelutils.h>
|
||||||
|
|
||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
#include <coreplugin/messagebox.h>
|
#include <coreplugin/messagebox.h>
|
||||||
|
|
||||||
@@ -919,25 +921,12 @@ Edit3DBakeLightsAction *Edit3DView::bakeLightsAction() const
|
|||||||
void Edit3DView::addQuick3DImport()
|
void Edit3DView::addQuick3DImport()
|
||||||
{
|
{
|
||||||
DesignDocument *document = QmlDesignerPlugin::instance()->currentDesignDocument();
|
DesignDocument *document = QmlDesignerPlugin::instance()->currentDesignDocument();
|
||||||
if (document && !document->inFileComponentModelActive() && model()) {
|
if (document && !document->inFileComponentModelActive() && model()
|
||||||
Import qtQuick3DImport;
|
&& Utils::addImportWithCheck(
|
||||||
differenceCall(model()->possibleImports(), model()->imports(), [&](const auto &import) {
|
"QtQuick3D",
|
||||||
if (import.url() == "QtQuick3D")
|
[](const Import &import) { return !import.hasVersion() || import.majorVersion() >= 6; },
|
||||||
qtQuick3DImport = import;
|
model())) {
|
||||||
});
|
return;
|
||||||
if (!qtQuick3DImport.isEmpty()) {
|
|
||||||
if (!qtQuick3DImport.version().isEmpty() && qtQuick3DImport.majorVersion() >= 6) {
|
|
||||||
// Prefer empty version number in Qt6 and beyond
|
|
||||||
model()->changeImports({Import::createLibraryImport(qtQuick3DImport.url(),
|
|
||||||
{},
|
|
||||||
qtQuick3DImport.alias(),
|
|
||||||
qtQuick3DImport.importPaths())},
|
|
||||||
{});
|
|
||||||
} else {
|
|
||||||
model()->changeImports({qtQuick3DImport}, {});
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Core::AsynchronousMessageBox::warning(tr("Failed to Add Import"),
|
Core::AsynchronousMessageBox::warning(tr("Failed to Add Import"),
|
||||||
tr("Could not add QtQuick3D import to project."));
|
tr("Could not add QtQuick3D import to project."));
|
||||||
|
@@ -14,6 +14,8 @@
|
|||||||
#include "rewritingexception.h"
|
#include "rewritingexception.h"
|
||||||
#include "viewmanager.h"
|
#include "viewmanager.h"
|
||||||
|
|
||||||
|
#include <model/modelutils.h>
|
||||||
|
|
||||||
#include <qmljs/qmljsmodelmanagerinterface.h>
|
#include <qmljs/qmljsmodelmanagerinterface.h>
|
||||||
|
|
||||||
#include <utils/algorithm.h>
|
#include <utils/algorithm.h>
|
||||||
@@ -300,7 +302,7 @@ bool ItemLibraryAssetImporter::preParseQuick3DAsset(const QString &file, ParseDa
|
|||||||
if (exitVal == QDialog::Accepted)
|
if (exitVal == QDialog::Accepted)
|
||||||
overwriteFiles = dlg.selectedFiles();
|
overwriteFiles = dlg.selectedFiles();
|
||||||
if (!overwriteFiles.isEmpty()) {
|
if (!overwriteFiles.isEmpty()) {
|
||||||
overwriteFiles.append(Utils::toList(alwaysOverwrite));
|
overwriteFiles.append(::Utils::toList(alwaysOverwrite));
|
||||||
m_overwrittenImports.insert(pd.targetDirPath, overwriteFiles);
|
m_overwrittenImports.insert(pd.targetDirPath, overwriteFiles);
|
||||||
} else {
|
} else {
|
||||||
addWarning(tr("No files selected for overwrite, skipping import: \"%1\".").arg(pd.assetName));
|
addWarning(tr("No files selected for overwrite, skipping import: \"%1\".").arg(pd.assetName));
|
||||||
@@ -359,9 +361,8 @@ void ItemLibraryAssetImporter::postParseQuick3DAsset(ParseData &pd)
|
|||||||
qmlInfo.append(".");
|
qmlInfo.append(".");
|
||||||
qmlInfo.append(pd.assetName);
|
qmlInfo.append(pd.assetName);
|
||||||
qmlInfo.append('\n');
|
qmlInfo.append('\n');
|
||||||
m_requiredImports.append(Import::createLibraryImport(
|
m_requiredImports.append(
|
||||||
QStringLiteral("%1.%2").arg(pd.targetDir.dirName(),
|
QStringLiteral("%1.%2").arg(pd.targetDir.dirName(), pd.assetName));
|
||||||
pd.assetName), version));
|
|
||||||
while (qmlIt.hasNext()) {
|
while (qmlIt.hasNext()) {
|
||||||
qmlIt.next();
|
qmlIt.next();
|
||||||
QFileInfo fi = QFileInfo(qmlIt.filePath());
|
QFileInfo fi = QFileInfo(qmlIt.filePath());
|
||||||
@@ -417,11 +418,8 @@ void ItemLibraryAssetImporter::postParseQuick3DAsset(ParseData &pd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add quick3D import unless it is already added
|
// Add quick3D import unless it is already added
|
||||||
if (impVersionMajor > 0
|
if (impVersionMajor > 0 && m_requiredImports.first() != "QtQuick3D")
|
||||||
&& m_requiredImports.first().url() != "QtQuick3D") {
|
m_requiredImports.prepend("QtQuick3D");
|
||||||
m_requiredImports.prepend(Import::createLibraryImport(
|
|
||||||
"QtQuick3D", impVersionStr));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (impVersionMajor > 0 && impVersionMajor < 6) {
|
if (impVersionMajor > 0 && impVersionMajor < 6) {
|
||||||
pd.iconFile = iconFileName;
|
pd.iconFile = iconFileName;
|
||||||
@@ -683,66 +681,42 @@ void ItemLibraryAssetImporter::finalizeQuick3DImport()
|
|||||||
QFuture<void> result;
|
QFuture<void> result;
|
||||||
if (modelManager) {
|
if (modelManager) {
|
||||||
QmlJS::PathsAndLanguages pathToScan;
|
QmlJS::PathsAndLanguages pathToScan;
|
||||||
pathToScan.maybeInsert(Utils::FilePath::fromString(m_importPath));
|
pathToScan.maybeInsert(::Utils::FilePath::fromString(m_importPath));
|
||||||
result = Utils::runAsync(&QmlJS::ModelManagerInterface::importScan,
|
result = ::Utils::runAsync(&QmlJS::ModelManagerInterface::importScan,
|
||||||
modelManager->workingCopy(), pathToScan,
|
modelManager->workingCopy(),
|
||||||
modelManager, true, true, true);
|
pathToScan,
|
||||||
|
modelManager,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// First we have to wait a while to ensure qmljs detects new files and updates its
|
// First we have to wait a while to ensure qmljs detects new files and updates its
|
||||||
// internal model. Then we make a non-change to the document to trigger qmljs snapshot
|
// internal model. Then we force amend on rewriter to trigger qmljs snapshot update.
|
||||||
// update. There is an inbuilt delay before rewriter change actually updates the data
|
|
||||||
// model, so we need to wait for another moment to allow the change to take effect.
|
|
||||||
// Otherwise subsequent subcomponent manager update won't detect new imports properly.
|
|
||||||
QTimer *timer = new QTimer(parent());
|
QTimer *timer = new QTimer(parent());
|
||||||
static int counter;
|
static int counter;
|
||||||
counter = 0;
|
counter = 0;
|
||||||
|
|
||||||
timer->callOnTimeout([this, timer, progressTitle, model, result]() {
|
timer->callOnTimeout([this, timer, progressTitle, model, result]() {
|
||||||
if (!isCancelled()) {
|
if (!isCancelled()) {
|
||||||
notifyProgress(++counter, progressTitle);
|
notifyProgress(++counter * 2, progressTitle);
|
||||||
if (counter < 50) {
|
if (counter < 49) {
|
||||||
if (result.isCanceled() || result.isFinished())
|
if (result.isCanceled() || result.isFinished())
|
||||||
counter = 49; // skip to next step
|
counter = 48; // skip to next step
|
||||||
} else if (counter == 50) {
|
} else if (counter == 49) {
|
||||||
QmlDesignerPlugin::instance()->documentManager().resetPossibleImports();
|
QmlDesignerPlugin::instance()->documentManager().resetPossibleImports();
|
||||||
model->rewriterView()->textModifier()->replace(0, 0, {});
|
model->rewriterView()->forceAmend();
|
||||||
} else if (counter < 100) {
|
|
||||||
try {
|
try {
|
||||||
const Imports posImports = model->possibleImports();
|
RewriterTransaction transaction = model->rewriterView()->beginRewriterTransaction(
|
||||||
const Imports currentImports = model->imports();
|
QByteArrayLiteral("ItemLibraryAssetImporter::finalizeQuick3DImport"));
|
||||||
Imports newImportsToAdd;
|
bool success = Utils::addImportsWithCheck(m_requiredImports, model);
|
||||||
|
if (!success)
|
||||||
for (auto &imp : std::as_const(m_requiredImports)) {
|
|
||||||
const bool isPos = Utils::contains(posImports, [imp](const Import &posImp) {
|
|
||||||
return posImp.url() == imp.url();
|
|
||||||
});
|
|
||||||
const bool isCur = Utils::contains(currentImports, [imp](const Import &curImp) {
|
|
||||||
return curImp.url() == imp.url();
|
|
||||||
});
|
|
||||||
if (!(isPos || isCur))
|
|
||||||
return;
|
|
||||||
// Check again with 'contains' to ensure we insert latest version
|
|
||||||
if (!currentImports.contains(imp))
|
|
||||||
newImportsToAdd.append(imp);
|
|
||||||
}
|
|
||||||
if (counter == 99)
|
|
||||||
addError(tr("Failed to insert import statement into qml document."));
|
addError(tr("Failed to insert import statement into qml document."));
|
||||||
else
|
transaction.commit();
|
||||||
counter = 99;
|
|
||||||
if (!newImportsToAdd.isEmpty()) {
|
|
||||||
RewriterTransaction transaction
|
|
||||||
= model->rewriterView()->beginRewriterTransaction(
|
|
||||||
QByteArrayLiteral("ItemLibraryAssetImporter::finalizeQuick3DImport"));
|
|
||||||
|
|
||||||
model->changeImports(newImportsToAdd, {});
|
|
||||||
transaction.commit();
|
|
||||||
}
|
|
||||||
} catch (const RewritingException &e) {
|
} catch (const RewritingException &e) {
|
||||||
addError(tr("Failed to update imports: %1").arg(e.description()));
|
addError(tr("Failed to update imports: %1").arg(e.description()));
|
||||||
counter = 99;
|
|
||||||
}
|
}
|
||||||
} else if (counter >= 100) {
|
} else if (counter >= 50) {
|
||||||
if (!m_overwrittenImports.isEmpty())
|
if (!m_overwrittenImports.isEmpty())
|
||||||
model->rewriterView()->emitCustomNotification("asset_import_update");
|
model->rewriterView()->emitCustomNotification("asset_import_update");
|
||||||
timer->stop();
|
timer->stop();
|
||||||
@@ -752,7 +726,7 @@ void ItemLibraryAssetImporter::finalizeQuick3DImport()
|
|||||||
timer->stop();
|
timer->stop();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
timer->start(50);
|
timer->start(100);
|
||||||
} else {
|
} else {
|
||||||
notifyFinished();
|
notifyFinished();
|
||||||
}
|
}
|
||||||
|
@@ -107,7 +107,7 @@ private:
|
|||||||
int m_currentImportId = 0;
|
int m_currentImportId = 0;
|
||||||
QHash<int, ParseData> m_parseData;
|
QHash<int, ParseData> m_parseData;
|
||||||
QString m_progressTitle;
|
QString m_progressTitle;
|
||||||
Imports m_requiredImports;
|
QStringList m_requiredImports;
|
||||||
QList<int> m_puppetQueue;
|
QList<int> m_puppetQueue;
|
||||||
};
|
};
|
||||||
} // QmlDesigner
|
} // QmlDesigner
|
||||||
|
@@ -18,6 +18,7 @@
|
|||||||
#include <itemlibrarymodel.h>
|
#include <itemlibrarymodel.h>
|
||||||
#include <metainfo.h>
|
#include <metainfo.h>
|
||||||
#include <model.h>
|
#include <model.h>
|
||||||
|
#include <model/modelutils.h>
|
||||||
#include <rewritingexception.h>
|
#include <rewritingexception.h>
|
||||||
#include <qmldesignerconstants.h>
|
#include <qmldesignerconstants.h>
|
||||||
#include <qmldesignerplugin.h>
|
#include <qmldesignerplugin.h>
|
||||||
@@ -59,7 +60,7 @@ namespace QmlDesigner {
|
|||||||
static QString propertyEditorResourcesPath()
|
static QString propertyEditorResourcesPath()
|
||||||
{
|
{
|
||||||
#ifdef SHARE_QML_PATH
|
#ifdef SHARE_QML_PATH
|
||||||
if (Utils::qtcEnvironmentVariableIsSet("LOAD_QML_FROM_SOURCE"))
|
if (::Utils::qtcEnvironmentVariableIsSet("LOAD_QML_FROM_SOURCE"))
|
||||||
return QLatin1String(SHARE_QML_PATH) + "/propertyEditorQmlSources";
|
return QLatin1String(SHARE_QML_PATH) + "/propertyEditorQmlSources";
|
||||||
#endif
|
#endif
|
||||||
return Core::ICore::resourcePath("qmldesigner/propertyEditorQmlSources").toString();
|
return Core::ICore::resourcePath("qmldesigner/propertyEditorQmlSources").toString();
|
||||||
@@ -80,26 +81,16 @@ bool ItemLibraryWidget::eventFilter(QObject *obj, QEvent *event)
|
|||||||
ItemLibraryEntry entry = m_itemToDrag.value<ItemLibraryEntry>();
|
ItemLibraryEntry entry = m_itemToDrag.value<ItemLibraryEntry>();
|
||||||
// For drag to be handled correctly, we must have the component properly imported
|
// For drag to be handled correctly, we must have the component properly imported
|
||||||
// beforehand, so we import the module immediately when the drag starts
|
// beforehand, so we import the module immediately when the drag starts
|
||||||
if (!entry.requiredImport().isEmpty()) {
|
if (!entry.requiredImport().isEmpty()
|
||||||
// We don't know if required import is library of file import, so try both.
|
&& !Utils::addImportWithCheck(entry.requiredImport(), m_model)) {
|
||||||
Import libImport = Import::createLibraryImport(entry.requiredImport());
|
qWarning() << __FUNCTION__ << "Required import adding failed:"
|
||||||
Import fileImport = Import::createFileImport(entry.requiredImport());
|
<< entry.requiredImport();
|
||||||
if (!m_model->hasImport(libImport, true, true)
|
|
||||||
&& !m_model->hasImport(fileImport, true, true)) {
|
|
||||||
const Imports possImports = m_model->possibleImports();
|
|
||||||
for (const auto &possImport : possImports) {
|
|
||||||
if ((!possImport.url().isEmpty() && possImport.url() == libImport.url())
|
|
||||||
|| (!possImport.file().isEmpty() && possImport.file() == fileImport.file())) {
|
|
||||||
m_model->changeImports({possImport}, {});
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (model) {
|
if (model) {
|
||||||
model->startDrag(m_itemLibraryModel->getMimeData(entry),
|
model->startDrag(m_itemLibraryModel->getMimeData(entry),
|
||||||
Utils::StyleHelper::dpiSpecificImageFile(entry.libraryEntryIconPath()));
|
::Utils::StyleHelper::dpiSpecificImageFile(
|
||||||
|
entry.libraryEntryIconPath()));
|
||||||
}
|
}
|
||||||
|
|
||||||
m_itemToDrag = {};
|
m_itemToDrag = {};
|
||||||
@@ -154,7 +145,7 @@ ItemLibraryWidget::ItemLibraryWidget(AsynchronousImageCache &imageCache)
|
|||||||
updateSearch();
|
updateSearch();
|
||||||
|
|
||||||
setStyleSheet(Theme::replaceCssColors(
|
setStyleSheet(Theme::replaceCssColors(
|
||||||
QString::fromUtf8(Utils::FileReader::fetchQrc(":/qmldesigner/stylesheet.css"))));
|
QString::fromUtf8(::Utils::FileReader::fetchQrc(":/qmldesigner/stylesheet.css"))));
|
||||||
|
|
||||||
m_qmlSourceUpdateShortcut = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_F5), this);
|
m_qmlSourceUpdateShortcut = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_F5), this);
|
||||||
connect(m_qmlSourceUpdateShortcut, &QShortcut::activated, this, &ItemLibraryWidget::reloadQmlSource);
|
connect(m_qmlSourceUpdateShortcut, &QShortcut::activated, this, &ItemLibraryWidget::reloadQmlSource);
|
||||||
@@ -176,10 +167,9 @@ ItemLibraryWidget::ItemLibraryWidget(AsynchronousImageCache &imageCache)
|
|||||||
{"itemLibraryIconHeight", m_itemIconSize.height()},
|
{"itemLibraryIconHeight", m_itemIconSize.height()},
|
||||||
{"rootView", QVariant::fromValue(this)},
|
{"rootView", QVariant::fromValue(this)},
|
||||||
{"widthLimit", HORIZONTAL_LAYOUT_WIDTH_LIMIT},
|
{"widthLimit", HORIZONTAL_LAYOUT_WIDTH_LIMIT},
|
||||||
{"highlightColor", Utils::StyleHelper::notTooBrightHighlightColor()},
|
{"highlightColor", ::Utils::StyleHelper::notTooBrightHighlightColor()},
|
||||||
{"tooltipBackend", QVariant::fromValue(m_previewTooltipBackend.get())}});
|
{"tooltipBackend", QVariant::fromValue(m_previewTooltipBackend.get())}});
|
||||||
|
|
||||||
|
|
||||||
reloadQmlSource();
|
reloadQmlSource();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -303,7 +293,7 @@ void ItemLibraryWidget::setModel(Model *model)
|
|||||||
QString ItemLibraryWidget::qmlSourcesPath()
|
QString ItemLibraryWidget::qmlSourcesPath()
|
||||||
{
|
{
|
||||||
#ifdef SHARE_QML_PATH
|
#ifdef SHARE_QML_PATH
|
||||||
if (Utils::qtcEnvironmentVariableIsSet("LOAD_QML_FROM_SOURCE"))
|
if (::Utils::qtcEnvironmentVariableIsSet("LOAD_QML_FROM_SOURCE"))
|
||||||
return QLatin1String(SHARE_QML_PATH) + "/itemLibraryQmlSources";
|
return QLatin1String(SHARE_QML_PATH) + "/itemLibraryQmlSources";
|
||||||
#endif
|
#endif
|
||||||
return Core::ICore::resourcePath("qmldesigner/itemLibraryQmlSources").toString();
|
return Core::ICore::resourcePath("qmldesigner/itemLibraryQmlSources").toString();
|
||||||
|
@@ -9,23 +9,24 @@
|
|||||||
#include "qmldesignerplugin.h"
|
#include "qmldesignerplugin.h"
|
||||||
#include "assetslibrarywidget.h"
|
#include "assetslibrarywidget.h"
|
||||||
|
|
||||||
|
#include <abstractview.h>
|
||||||
#include <bindingproperty.h>
|
#include <bindingproperty.h>
|
||||||
|
#include <coreplugin/icore.h>
|
||||||
|
#include <designeractionmanager.h>
|
||||||
#include <designersettings.h>
|
#include <designersettings.h>
|
||||||
|
#include <import.h>
|
||||||
|
#include <invalididexception.h>
|
||||||
|
#include <materialutils.h>
|
||||||
|
#include <metainfo.h>
|
||||||
|
#include <model/modelutils.h>
|
||||||
#include <nodeabstractproperty.h>
|
#include <nodeabstractproperty.h>
|
||||||
#include <nodehints.h>
|
#include <nodehints.h>
|
||||||
#include <nodelistproperty.h>
|
#include <nodelistproperty.h>
|
||||||
#include <nodeproperty.h>
|
#include <nodeproperty.h>
|
||||||
#include <variantproperty.h>
|
|
||||||
#include <metainfo.h>
|
|
||||||
#include <materialutils.h>
|
|
||||||
#include <abstractview.h>
|
|
||||||
#include <invalididexception.h>
|
|
||||||
#include <rewritingexception.h>
|
#include <rewritingexception.h>
|
||||||
|
#include <variantproperty.h>
|
||||||
#include <qmldesignerconstants.h>
|
#include <qmldesignerconstants.h>
|
||||||
#include <qmlitemnode.h>
|
#include <qmlitemnode.h>
|
||||||
#include <designeractionmanager.h>
|
|
||||||
#include <import.h>
|
|
||||||
#include <coreplugin/icore.h>
|
|
||||||
|
|
||||||
#include <qmlprojectmanager/qmlproject.h>
|
#include <qmlprojectmanager/qmlproject.h>
|
||||||
|
|
||||||
@@ -210,7 +211,7 @@ QVariant NavigatorTreeModel::data(const QModelIndex &index, int role) const
|
|||||||
return modelNode.displayName();
|
return modelNode.displayName();
|
||||||
} else if (role == Qt::DecorationRole) {
|
} else if (role == Qt::DecorationRole) {
|
||||||
if (currentQmlObjectNode.hasError())
|
if (currentQmlObjectNode.hasError())
|
||||||
return Utils::Icons::WARNING.icon();
|
return ::Utils::Icons::WARNING.icon();
|
||||||
|
|
||||||
return modelNode.typeIcon();
|
return modelNode.typeIcon();
|
||||||
|
|
||||||
@@ -314,14 +315,14 @@ QList<ModelNode> NavigatorTreeModel::filteredList(const NodeListProperty &proper
|
|||||||
if (m_nameFilter.isEmpty()) {
|
if (m_nameFilter.isEmpty()) {
|
||||||
nameFilteredList = propertyNodes;
|
nameFilteredList = propertyNodes;
|
||||||
} else {
|
} else {
|
||||||
nameFilteredList.append(Utils::filtered(propertyNodes, [&] (const ModelNode &arg){
|
nameFilteredList.append(::Utils::filtered(propertyNodes, [&](const ModelNode &arg) {
|
||||||
const bool value = m_nameFilteredList.contains(arg);
|
const bool value = m_nameFilteredList.contains(arg);
|
||||||
return value;
|
return value;
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filter) {
|
if (filter) {
|
||||||
list.append(Utils::filtered(nameFilteredList, [] (const ModelNode &arg) {
|
list.append(::Utils::filtered(nameFilteredList, [](const ModelNode &arg) {
|
||||||
const bool value = (QmlItemNode::isValidQmlItemNode(arg) || NodeHints::fromModelNode(arg).visibleInNavigator())
|
const bool value = (QmlItemNode::isValidQmlItemNode(arg) || NodeHints::fromModelNode(arg).visibleInNavigator())
|
||||||
&& arg.id() != Constants::MATERIAL_LIB_ID;
|
&& arg.id() != Constants::MATERIAL_LIB_ID;
|
||||||
return value;
|
return value;
|
||||||
@@ -899,18 +900,8 @@ ModelNode NavigatorTreeModel::handleItemLibraryFontDrop(const QString &fontFamil
|
|||||||
|
|
||||||
void NavigatorTreeModel::addImport(const QString &importName)
|
void NavigatorTreeModel::addImport(const QString &importName)
|
||||||
{
|
{
|
||||||
Import import = Import::createLibraryImport(importName);
|
if (!Utils::addImportWithCheck(importName, m_view->model()))
|
||||||
if (!m_view->model()->hasImport(import, true, true)) {
|
qWarning() << __FUNCTION__ << "Adding import failed:" << importName;
|
||||||
const Imports possImports = difference(m_view->model()->possibleImports(),
|
|
||||||
m_view->model()->imports());
|
|
||||||
for (const auto &possImport : possImports) {
|
|
||||||
if (possImport.url() == import.url()) {
|
|
||||||
import = possImport;
|
|
||||||
m_view->model()->changeImports({import}, {});
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QmlDesigner::NavigatorTreeModel::moveNodeToParent(const NodeAbstractProperty &targetProperty,
|
bool QmlDesigner::NavigatorTreeModel::moveNodeToParent(const NodeAbstractProperty &targetProperty,
|
||||||
@@ -1269,12 +1260,12 @@ static QList<ModelNode> collectParents(const QList<ModelNode> &modelNodes)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Utils::toList(parents);
|
return ::Utils::toList(parents);
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<QPersistentModelIndex> NavigatorTreeModel::nodesToPersistentIndex(const QList<ModelNode> &modelNodes)
|
QList<QPersistentModelIndex> NavigatorTreeModel::nodesToPersistentIndex(const QList<ModelNode> &modelNodes)
|
||||||
{
|
{
|
||||||
return Utils::transform(modelNodes, [this](const ModelNode &modelNode) {
|
return ::Utils::transform(modelNodes, [this](const ModelNode &modelNode) {
|
||||||
return QPersistentModelIndex(indexForModelNode(modelNode));
|
return QPersistentModelIndex(indexForModelNode(modelNode));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
93
src/plugins/qmldesigner/designercore/model/modelutils.cpp
Normal file
93
src/plugins/qmldesigner/designercore/model/modelutils.cpp
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
#include "modelutils.h"
|
||||||
|
|
||||||
|
#include <utils/expected.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace QmlDesigner::Utils {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
enum class ImportError { EmptyImportName, HasAlreadyImport, NoModule };
|
||||||
|
|
||||||
|
::Utils::expected<Import, ImportError> findImport(const QString &importName,
|
||||||
|
const std::function<bool(const Import &)> &predicate,
|
||||||
|
const Imports &imports,
|
||||||
|
const Imports &modules)
|
||||||
|
{
|
||||||
|
if (importName.isEmpty())
|
||||||
|
return ::Utils::make_unexpected(ImportError::EmptyImportName);
|
||||||
|
|
||||||
|
auto hasName = [&](const auto &import) {
|
||||||
|
return import.url() == importName || import.file() == importName;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool hasImport = std::any_of(imports.begin(), imports.end(), hasName);
|
||||||
|
|
||||||
|
if (hasImport)
|
||||||
|
return ::Utils::make_unexpected(ImportError::HasAlreadyImport);
|
||||||
|
|
||||||
|
auto foundModule = std::find_if(modules.begin(), modules.end(), [&](const Import &import) {
|
||||||
|
return hasName(import) && predicate(import);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (foundModule == modules.end())
|
||||||
|
return ::Utils::make_unexpected(ImportError::NoModule);
|
||||||
|
|
||||||
|
return *foundModule;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
bool addImportWithCheck(const QString &importName,
|
||||||
|
const std::function<bool(const Import &)> &predicate,
|
||||||
|
Model *model)
|
||||||
|
{
|
||||||
|
return addImportsWithCheck({importName}, predicate, model);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool addImportWithCheck(const QString &importName, Model *model)
|
||||||
|
{
|
||||||
|
return addImportWithCheck(
|
||||||
|
importName, [](const Import &) { return true; }, model);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool addImportsWithCheck(const QStringList &importNames, Model *model)
|
||||||
|
{
|
||||||
|
return addImportsWithCheck(
|
||||||
|
importNames, [](const Import &) { return true; }, model);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool addImportsWithCheck(const QStringList &importNames,
|
||||||
|
const std::function<bool(const Import &)> &predicate,
|
||||||
|
Model *model)
|
||||||
|
{
|
||||||
|
const Imports &imports = model->imports();
|
||||||
|
const Imports &modules = model->possibleImports();
|
||||||
|
|
||||||
|
Imports importsToAdd;
|
||||||
|
importsToAdd.reserve(importNames.size());
|
||||||
|
|
||||||
|
for (const QString &importName : importNames) {
|
||||||
|
auto import = findImport(importName, predicate, imports, modules);
|
||||||
|
|
||||||
|
if (import) {
|
||||||
|
importsToAdd.push_back(*import);
|
||||||
|
} else {
|
||||||
|
if (import.error() == ImportError::NoModule)
|
||||||
|
return false;
|
||||||
|
else
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!importsToAdd.isEmpty())
|
||||||
|
model->changeImports(std::move(importsToAdd), {});
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace QmlDesigner::Utils
|
24
src/plugins/qmldesigner/designercore/model/modelutils.h
Normal file
24
src/plugins/qmldesigner/designercore/model/modelutils.h
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "qmldesignercorelib_global.h"
|
||||||
|
|
||||||
|
#include <import.h>
|
||||||
|
#include <model.h>
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
namespace QmlDesigner::Utils {
|
||||||
|
|
||||||
|
QMLDESIGNERCORE_EXPORT bool addImportsWithCheck(const QStringList &importNames,
|
||||||
|
const std::function<bool(const Import &)> &predicate,
|
||||||
|
Model *model);
|
||||||
|
QMLDESIGNERCORE_EXPORT bool addImportsWithCheck(const QStringList &importNames, Model *model);
|
||||||
|
QMLDESIGNERCORE_EXPORT bool addImportWithCheck(const QString &importName,
|
||||||
|
const std::function<bool(const Import &)> &predicate,
|
||||||
|
Model *model);
|
||||||
|
QMLDESIGNERCORE_EXPORT bool addImportWithCheck(const QString &importName, Model *model);
|
||||||
|
|
||||||
|
} // namespace QmlDesigner::Utils
|
Reference in New Issue
Block a user