From f00b805da17bc7a25237c0bbde713f0d2deed7d7 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Wed, 10 Jan 2018 09:36:56 +0100 Subject: [PATCH 1/9] QmlDesigner: Add features to .metainfo file Allows black listing and white listing of imports. The .metainfo files of QML and QmlDesigner plugins currently define the contents of the item library. This patch also allows to blacklist imports in the import manager and to define important imports that can e. g. be added using a tag list. Change-Id: I358cf7abe6dc68d54f33488ae7d164fc10e5ea94 Reviewed-by: Tim Jenssen Reviewed-by: Thomas Hartmann --- .../designercore/include/itemlibraryinfo.h | 9 +++++ .../designercore/include/metainforeader.h | 2 ++ .../designercore/metainfo/itemlibraryinfo.cpp | 26 ++++++++++++++ .../designercore/metainfo/metainforeader.cpp | 21 ++++++++++- .../designercore/model/texttomodelmerger.cpp | 35 ++++++++++++++----- 5 files changed, 84 insertions(+), 9 deletions(-) diff --git a/src/plugins/qmldesigner/designercore/include/itemlibraryinfo.h b/src/plugins/qmldesigner/designercore/include/itemlibraryinfo.h index 6233b315788..8b743352091 100644 --- a/src/plugins/qmldesigner/designercore/include/itemlibraryinfo.h +++ b/src/plugins/qmldesigner/designercore/include/itemlibraryinfo.h @@ -106,6 +106,12 @@ public: bool containsEntry(const ItemLibraryEntry &entry); void clearEntries(); + QStringList blacklistImports() const; + QStringList showTagsForImports() const; + + void addBlacklistImports(const QStringList &list); + void addShowTagsForImports(const QStringList &list); + signals: void entriesChanged(); @@ -116,6 +122,9 @@ private: // functions private: // variables QHash m_nameToEntryHash; QPointer m_baseInfo; + + QStringList m_blacklistImports; + QStringList m_showTagsForImports; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/include/metainforeader.h b/src/plugins/qmldesigner/designercore/include/metainforeader.h index de8e2206983..375d161885e 100644 --- a/src/plugins/qmldesigner/designercore/include/metainforeader.h +++ b/src/plugins/qmldesigner/designercore/include/metainforeader.h @@ -66,6 +66,7 @@ private: ParsingDocument, ParsingMetaInfo, ParsingType, + ParsingImports, ParsingItemLibrary, ParsingHints, ParsingProperty, @@ -81,6 +82,7 @@ private: ParserSate readQmlSourceElement(const QString &name); void readTypeProperty(const QString &name, const QVariant &value); + void readImportsProperty(const QString &name, const QVariant &value); void readItemLibraryEntryProperty(const QString &name, const QVariant &value); void readPropertyProperty(const QString &name, const QVariant &value); void readQmlSourceProperty(const QString &name, const QVariant &value); diff --git a/src/plugins/qmldesigner/designercore/metainfo/itemlibraryinfo.cpp b/src/plugins/qmldesigner/designercore/metainfo/itemlibraryinfo.cpp index d18f252c884..30fe3b4cc27 100644 --- a/src/plugins/qmldesigner/designercore/metainfo/itemlibraryinfo.cpp +++ b/src/plugins/qmldesigner/designercore/metainfo/itemlibraryinfo.cpp @@ -337,6 +337,32 @@ void ItemLibraryInfo::clearEntries() emit entriesChanged(); } +QStringList ItemLibraryInfo::blacklistImports() const +{ + auto list = m_blacklistImports; + if (m_baseInfo) + list.append(m_baseInfo->m_blacklistImports); + return list; +} + +QStringList ItemLibraryInfo::showTagsForImports() const +{ + auto list = m_showTagsForImports; + if (m_baseInfo) + list.append(m_baseInfo->m_showTagsForImports); + return list; +} + +void ItemLibraryInfo::addBlacklistImports(const QStringList &list) +{ + m_blacklistImports.append(list); +} + +void ItemLibraryInfo::addShowTagsForImports(const QStringList &list) +{ + m_showTagsForImports.append(list); +} + void ItemLibraryInfo::setBaseInfo(ItemLibraryInfo *baseInfo) { m_baseInfo = baseInfo; diff --git a/src/plugins/qmldesigner/designercore/metainfo/metainforeader.cpp b/src/plugins/qmldesigner/designercore/metainfo/metainforeader.cpp index 1caff4817e3..9df2a85c7d5 100644 --- a/src/plugins/qmldesigner/designercore/metainfo/metainforeader.cpp +++ b/src/plugins/qmldesigner/designercore/metainfo/metainforeader.cpp @@ -40,6 +40,7 @@ enum { const QString rootElementName = QStringLiteral("MetaInfo"); const QString typeElementName = QStringLiteral("Type"); +const QString importsElementName = QStringLiteral("Imports"); const QString ItemLibraryEntryElementName = QStringLiteral("ItemLibraryEntry"); const QString HintsElementName = QStringLiteral("Hints"); const QString QmlSourceElementName = QStringLiteral("QmlSource"); @@ -106,6 +107,7 @@ void MetaInfoReader::elementEnd() switch (parserState()) { case ParsingMetaInfo: setParserState(Finished); break; case ParsingType: setParserState(ParsingMetaInfo); break; + case ParsingImports: setParserState(ParsingMetaInfo); break; case ParsingItemLibrary: keepCurrentItemLibraryEntry(); setParserState((ParsingType)); break; case ParsingHints: setParserState(ParsingType); break; case ParsingProperty: insertProperty(); setParserState(ParsingItemLibrary); break; @@ -123,6 +125,7 @@ void MetaInfoReader::propertyDefinition(const QString &name, const QVariant &val { switch (parserState()) { case ParsingType: readTypeProperty(name, value); break; + case ParsingImports: readImportsProperty(name, value); break; case ParsingItemLibrary: readItemLibraryEntryProperty(name, value); break; case ParsingProperty: readPropertyProperty(name, value); break; case ParsingQmlSource: readQmlSourceProperty(name, value); break; @@ -156,6 +159,8 @@ MetaInfoReader::ParserSate MetaInfoReader::readMetaInfoRootElement(const QString m_currentIcon.clear(); m_currentHints.clear(); return ParsingType; + } else if (name == importsElementName) { + return ParsingImports; } else { addErrorInvalidType(name); return Error; @@ -207,6 +212,20 @@ MetaInfoReader::ParserSate MetaInfoReader::readQmlSourceElement(const QString &n return Error; } +void MetaInfoReader::readImportsProperty(const QString &name, const QVariant &value) +{ + const auto values = value.toStringList(); + + if (name == "blacklistImports" && !values.isEmpty()) { + m_metaInfo.itemLibraryInfo()->addBlacklistImports(values); + } else if (name == "showTagsForImports" && !values.isEmpty()) { + m_metaInfo.itemLibraryInfo()->addShowTagsForImports(values); + } else { + addError(tr("Unknown property for Imports %1").arg(name), currentSourceLocation()); + setParserState(Error); + } +} + void MetaInfoReader::readTypeProperty(const QString &name, const QVariant &value) { if (name == QLatin1String("name")) { @@ -242,7 +261,7 @@ void MetaInfoReader::readItemLibraryEntryProperty(const QString &name, const QVa void MetaInfoReader::readPropertyProperty(const QString &name, const QVariant &value) { if (name == QStringLiteral("name")) { - m_currentPropertyName = value.toByteArray(); + m_currentPropertyName = value.toByteArray(); } else if (name == QStringLiteral("type")) { m_currentPropertyType = value.toString(); } else if (name == QStringLiteral("value")) { diff --git a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp index f94cd99fb7f..3f4e60fb32e 100644 --- a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp +++ b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp @@ -29,16 +29,18 @@ #include "modelnodepositionstorage.h" #include "abstractproperty.h" #include "bindingproperty.h" +#include "enumeration.h" #include "filemanager/firstdefinitionfinder.h" #include "filemanager/objectlengthcalculator.h" #include "filemanager/qmlrefactoring.h" +#include "itemlibraryinfo.h" +#include "metainfo.h" +#include "nodemetainfo.h" #include "nodeproperty.h" +#include "signalhandlerproperty.h" #include "propertyparser.h" #include "rewriterview.h" #include "variantproperty.h" -#include "signalhandlerproperty.h" -#include "nodemetainfo.h" -#include "enumeration.h" #include #include @@ -790,7 +792,20 @@ static bool isLatestImportVersion(const ImportKey &importKey, const QHashmetaInfo().itemLibraryInfo()->blacklistImports()) { + if (importKey.libraryQualifiedPath().contains(filter)) + return true; + } + + } + + return false; +} + +static bool isBlacklistImport(const ImportKey &importKey, Model *model) { const QString &importPathFirst = importKey.splitPath.constFirst(); const QString &importPathLast = importKey.splitPath.constLast(); @@ -799,6 +814,7 @@ static bool isBlacklistImport(const ImportKey &importKey) || importPathFirst == QStringLiteral("QtQml") || (importPathFirst == QStringLiteral("QtQuick") && importPathLast == QStringLiteral("PrivateWidgets")) || importPathLast == QStringLiteral("Private") + || importPathLast == QStringLiteral("private") || importKey.libraryQualifiedPath() == QStringLiteral("QtQuick.Particles") //Unsupported || importKey.libraryQualifiedPath() == QStringLiteral("QtQuick.Dialogs") //Unsupported || importKey.libraryQualifiedPath() == QStringLiteral("QtQuick.Controls.Styles") //Unsupported @@ -813,14 +829,16 @@ static bool isBlacklistImport(const ImportKey &importKey) || importKey.libraryQualifiedPath() == QStringLiteral("QtBluetooth") || importKey.libraryQualifiedPath() == QStringLiteral("Enginio") - || (importKey.splitPath.count() == 1 && importPathFirst == QStringLiteral("QtQuick")); // Don't show Quick X.X imports + // Don't show Quick X.X imports + || (importKey.splitPath.count() == 1 && importPathFirst == QStringLiteral("QtQuick")) + || filterByMetaInfo(importKey, model); } -static QHash filterPossibleImportKeys(const QSet &possibleImportKeys) +static QHash filterPossibleImportKeys(const QSet &possibleImportKeys, Model *model) { QHash filteredPossibleImportKeys; foreach (const ImportKey &importKey, possibleImportKeys) { - if (isLatestImportVersion(importKey, filteredPossibleImportKeys) && !isBlacklistImport(importKey)) + if (isLatestImportVersion(importKey, filteredPossibleImportKeys) && !isBlacklistImport(importKey, model)) filteredPossibleImportKeys.insert(importKey.path(), importKey); } @@ -868,7 +886,8 @@ static QList generatePossibleLibraryImports(const QHash filteredPossibleImportKeys = filterPossibleImportKeys(snapshot.importDependencies()->libraryImports(viewContext)); + QHash filteredPossibleImportKeys = + filterPossibleImportKeys(snapshot.importDependencies()->libraryImports(viewContext), m_rewriterView->model()); removeUsedImports(filteredPossibleImportKeys, m_scopeChain->context()->imports(m_document.data())->all()); From 59a01d9a1d42da2676c8647b6c567d359eebb123 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Sat, 13 Jan 2018 16:21:07 +0100 Subject: [PATCH 2/9] QmlDesigner: Add tags for important imports This makes the relevant imports a lot more discoverable. Change-Id: Ide0396cf844c071aaee050a8993eb06a9c544daf Reviewed-by: Tim Jenssen --- .../itemlibrary/itemlibrarywidget.cpp | 107 +++++++++++++----- .../itemlibrary/itemlibrarywidget.h | 11 +- .../qmldesigner/designercore/include/model.h | 2 + .../qmldesigner/designercore/model/model.cpp | 36 ++++++ 4 files changed, 125 insertions(+), 31 deletions(-) diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp index 1bf7725b989..81313c43022 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp @@ -29,32 +29,38 @@ #include +#include +#include +#include +#include +#include +#include +#include + +#include #include -#include #include +#include +#include #include #include -#include "itemlibrarymodel.h" -#include "itemlibraryimageprovider.h" -#include -#include -#include "rewritingexception.h" +#include #include #include #include -#include #include -#include #include +#include #include #include -#include -#include -#include -#include #include +#include +#include +#include +#include +#include #include #include @@ -69,6 +75,7 @@ ItemLibraryWidget::ItemLibraryWidget(QWidget *parent) : m_itemIconSize(24, 24), m_itemViewQuickWidget(new QQuickWidget), m_resourcesView(new ItemLibraryResourceView(this)), + m_importTagsWidget(new QWidget(this)), m_filterFlag(QtBasic) { m_compressionTimer.setInterval(200); @@ -126,7 +133,6 @@ ItemLibraryWidget::ItemLibraryWidget(QWidget *parent) : lineEditLayout->addItem(new QSpacerItem(5, 5, QSizePolicy::Fixed, QSizePolicy::Fixed), 1, 2); connect(m_filterLineEdit.data(), &Utils::FancyLineEdit::filterChanged, this, &ItemLibraryWidget::setSearchFilter); - m_stackedWidget = new QStackedWidget(this); m_stackedWidget->addWidget(m_itemViewQuickWidget.data()); m_stackedWidget->addWidget(m_resourcesView.data()); @@ -141,7 +147,8 @@ ItemLibraryWidget::ItemLibraryWidget(QWidget *parent) : layout->addWidget(tabBar, 0, 0, 1, 1); layout->addWidget(spacer, 1, 0); layout->addWidget(lineEditFrame, 2, 0, 1, 1); - layout->addWidget(m_stackedWidget.data(), 3, 0, 1, 1); + layout->addWidget(m_importTagsWidget.data(), 3, 0, 1, 1); + layout->addWidget(m_stackedWidget.data(), 4, 0, 1, 1); setSearchFilter(QString()); @@ -154,6 +161,9 @@ ItemLibraryWidget::ItemLibraryWidget(QWidget *parent) : connect(&m_compressionTimer, &QTimer::timeout, this, &ItemLibraryWidget::updateModel); + auto *flowLayout = new Utils::FlowLayout(m_importTagsWidget.data()); + flowLayout->setMargin(4); + // init the first load of the QML UI elements reloadQmlSource(); } @@ -175,12 +185,8 @@ void ItemLibraryWidget::setItemLibraryInfo(ItemLibraryInfo *itemLibraryInfo) void ItemLibraryWidget::updateImports() { - if (m_model) { - QStringList imports; - foreach (const Import &import, m_model->imports()) - if (import.isLibraryImport()) - imports << import.url(); - } + if (m_model) + setupImportTagWidget(); } void ItemLibraryWidget::setImportsWidget(QWidget *importsWidget) @@ -223,10 +229,16 @@ void ItemLibraryWidget::setModel(Model *model) void ItemLibraryWidget::setCurrentIndexOfStackedWidget(int index) { - if (index == 2) + if (index == 2) { m_filterLineEdit->setVisible(false); - else + m_importTagsWidget->setVisible(true); + } if (index == 1) { m_filterLineEdit->setVisible(true); + m_importTagsWidget->setVisible(false); + } else { + m_filterLineEdit->setVisible(true); + m_importTagsWidget->setVisible(true); + } m_stackedWidget->setCurrentIndex(index); } @@ -249,6 +261,38 @@ void ItemLibraryWidget::reloadQmlSource() m_itemViewQuickWidget->setSource(QUrl::fromLocalFile(itemLibraryQmlFilePath)); } +void ItemLibraryWidget::setupImportTagWidget() +{ + QTC_ASSERT(m_model, return); + + const QStringList imports = m_model->metaInfo().itemLibraryInfo()->showTagsForImports(); + + qDeleteAll(m_importTagsWidget->findChildren("", Qt::FindDirectChildrenOnly)); + + auto *flowLayout = m_importTagsWidget->layout(); + + auto createButton = [this](const QString &import) { + auto button = new QToolButton(m_importTagsWidget.data()); + auto font = button->font(); + font.setPixelSize(9); + button->setFont(font); + button->setIcon(Utils::Icons::PLUS.icon()); + button->setText(import); + button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + connect(button, &QToolButton::clicked, this, [this, import]() { + addPossibleImport(import); + }); + return button; + }; + + for (const QString &importPath : imports) { + const Import import = Import::createLibraryImport(importPath); + if (!m_model->hasImport(import, true, true) + && m_model->isImportPossible(import, true, true)) + flowLayout->addWidget(createButton(importPath)); + } +} + void ItemLibraryWidget::updateModel() { m_itemLibraryModel->update(m_itemLibraryInfo.data(), m_model.data()); @@ -293,8 +337,7 @@ void ItemLibraryWidget::startDragAndDrop(QQuickItem *mouseArea, QVariant itemLib void ItemLibraryWidget::removeImport(const QString &name) { - if (!m_model) - return; + QTC_ASSERT(m_model, return); QList toBeRemovedImportList; foreach (const Import &import, m_model->imports()) @@ -306,9 +349,21 @@ void ItemLibraryWidget::removeImport(const QString &name) void ItemLibraryWidget::addImport(const QString &name, const QString &version) { - if (!m_model) - return; + QTC_ASSERT(m_model, return); m_model->changeImports({Import::createLibraryImport(name, version)}, {}); } +void ItemLibraryWidget::addPossibleImport(const QString &name) +{ + QTC_ASSERT(m_model, return); + const Import import = m_model->highestPossibleImport(name); + try { + m_model->changeImports({Import::createLibraryImport(name, import.version())}, {}); + } + catch (const RewritingException &e) { + e.showException(); + } + QmlDesignerPlugin::instance()->currentDesignDocument()->updateSubcomponentManager(); +} + } diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h index a831b4c5fd1..8ca7467bfee 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h @@ -86,18 +86,17 @@ public: Q_INVOKABLE void startDragAndDrop(QQuickItem *mouseArea, QVariant itemLibId); -protected: - void removeImport(const QString &name); - void addImport(const QString &name, const QString &version); - signals: void itemActivated(const QString& itemName); private: void setCurrentIndexOfStackedWidget(int index); void reloadQmlSource(); + void setupImportTagWidget(); + void removeImport(const QString &name); + void addImport(const QString &name, const QString &version); + void addPossibleImport(const QString &name); -private: QTimer m_compressionTimer; QSize m_itemIconSize; @@ -111,6 +110,8 @@ private: QPointer m_filterLineEdit; QScopedPointer m_itemViewQuickWidget; QScopedPointer m_resourcesView; + QScopedPointer m_importTagsWidget; + QShortcut *m_qmlSourceUpdateShortcut; QPointer m_model; diff --git a/src/plugins/qmldesigner/designercore/include/model.h b/src/plugins/qmldesigner/designercore/include/model.h index d5f16be0ed4..d959f4eb0fc 100644 --- a/src/plugins/qmldesigner/designercore/include/model.h +++ b/src/plugins/qmldesigner/designercore/include/model.h @@ -99,8 +99,10 @@ public: void setPossibleImports(const QList &possibleImports); void setUsedImports(const QList &usedImports); bool hasImport(const Import &import, bool ignoreAlias = true, bool allowHigherVersion = false); + bool isImportPossible(const Import &import, bool ignoreAlias = true, bool allowHigherVersion = false); QString pathForImport(const Import &import); QStringList importPaths() const; + Import highestPossibleImport(const QString &importPath); RewriterView *rewriterView() const; void setRewriterView(RewriterView *rewriterView); diff --git a/src/plugins/qmldesigner/designercore/model/model.cpp b/src/plugins/qmldesigner/designercore/model/model.cpp index 70dd0f4fd43..8c79fee4c71 100644 --- a/src/plugins/qmldesigner/designercore/model/model.cpp +++ b/src/plugins/qmldesigner/designercore/model/model.cpp @@ -1874,6 +1874,8 @@ void Model::setUsedImports(const QList &usedImports) static bool compareVersions(const QString &version1, const QString &version2, bool allowHigherVersion) { + if (version2.isEmpty()) + return true; if (version1 == version2) return true; if (!allowHigherVersion) @@ -1921,6 +1923,26 @@ bool Model::hasImport(const Import &import, bool ignoreAlias, bool allowHigherVe return false; } +bool Model::isImportPossible(const Import &import, bool ignoreAlias, bool allowHigherVersion) +{ + if (imports().contains(import)) + return true; + if (!ignoreAlias) + return false; + + const auto importList = possibleImports(); + + for (const Import &possibleImport : importList) { + if (possibleImport.isFileImport() && import.isFileImport()) + if (possibleImport.file() == import.file()) + return true; + if (possibleImport.isLibraryImport() && import.isLibraryImport()) + if (possibleImport.url() == import.url() && compareVersions(possibleImport.version(), import.version(), allowHigherVersion)) + return true; + } + return false; +} + QString Model::pathForImport(const Import &import) { if (!rewriterView()) @@ -1944,6 +1966,20 @@ QStringList Model::importPaths() const return importPathList; } +Import Model::highestPossibleImport(const QString &importPath) +{ + Import candidate; + + for (const Import &import : possibleImports()) { + if (import.url() == importPath) { + if (candidate.isEmpty() || compareVersions(import.version(), candidate.version(), true)) + candidate = import; + } + } + + return candidate; +} + RewriterView *Model::rewriterView() const { return d->rewriterView(); From 85fbd5a366c835b1af81a67e7408909980e454e1 Mon Sep 17 00:00:00 2001 From: Jochen Becher Date: Sat, 13 Jan 2018 19:35:16 +0100 Subject: [PATCH 3/9] ModelEditor: Avoid temporary extensive copy Change-Id: I8e77ea98e4e3c6086c3dd8a424da6dfd3f95a0fa Reviewed-by: Tobias Hunger --- src/plugins/modeleditor/componentviewcontroller.cpp | 2 +- src/plugins/modeleditor/modelindexer.cpp | 2 +- src/plugins/modeleditor/pxnodecontroller.cpp | 6 +++--- src/plugins/modeleditor/pxnodeutilities.cpp | 10 +++++----- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/plugins/modeleditor/componentviewcontroller.cpp b/src/plugins/modeleditor/componentviewcontroller.cpp index 52501649cd8..c8c0f1b1c30 100644 --- a/src/plugins/modeleditor/componentviewcontroller.cpp +++ b/src/plugins/modeleditor/componentviewcontroller.cpp @@ -344,7 +344,7 @@ bool UpdateIncludeDependenciesVisitor::haveDependency(const qmt::MObject *source aToB = qmt::MDependency::BToA; bToA = qmt::MDependency::AToB; } - foreach (const qmt::Handle &handle, source->relations()) { + for (const qmt::Handle &handle : source->relations()) { if (auto dependency = dynamic_cast(handle.target())) { if (dependency->source() == source->uid() && dependency->target() == target->uid() diff --git a/src/plugins/modeleditor/modelindexer.cpp b/src/plugins/modeleditor/modelindexer.cpp index 4df25cd54ed..aa84b689548 100644 --- a/src/plugins/modeleditor/modelindexer.cpp +++ b/src/plugins/modeleditor/modelindexer.cpp @@ -215,7 +215,7 @@ ModelIndexer::DiagramsCollectorVisitor::DiagramsCollectorVisitor(IndexedModel *i void ModelIndexer::DiagramsCollectorVisitor::visitMObject(const qmt::MObject *object) { - foreach (const qmt::Handle &child, object->children()) { + for (const qmt::Handle &child : object->children()) { if (child.hasTarget()) child.target()->accept(this); } diff --git a/src/plugins/modeleditor/pxnodecontroller.cpp b/src/plugins/modeleditor/pxnodecontroller.cpp index bdbadae8a07..c1181fba983 100644 --- a/src/plugins/modeleditor/pxnodecontroller.cpp +++ b/src/plugins/modeleditor/pxnodecontroller.cpp @@ -205,7 +205,7 @@ qmt::MDiagram *PxNodeController::findDiagramForExplorerNode(const ProjectExplore qmt::MPackage *package = roots.takeFirst(); // append all sub-packages of the same level as next root packages - foreach (const qmt::Handle &handle, package->children()) { + for (const qmt::Handle &handle : package->children()) { if (handle.hasTarget()) { if (auto childPackage = dynamic_cast(handle.target())) roots.append(childPackage); @@ -219,7 +219,7 @@ qmt::MDiagram *PxNodeController::findDiagramForExplorerNode(const ProjectExplore QString relativeSearchId = qmt::NameController::calcElementNameSearchId( relativeElements.at(relativeIndex)); found = false; - foreach (const qmt::Handle &handle, package->children()) { + for (const qmt::Handle &handle : package->children()) { if (handle.hasTarget()) { if (auto childPackage = dynamic_cast(handle.target())) { if (qmt::NameController::calcElementNameSearchId(childPackage->name()) == relativeSearchId) { @@ -241,7 +241,7 @@ qmt::MDiagram *PxNodeController::findDiagramForExplorerNode(const ProjectExplore if (diagram) return diagram; // find first diagram within deepest package - foreach (const qmt::Handle &handle, package->children()) { + for (const qmt::Handle &handle : package->children()) { if (handle.hasTarget()) { if (auto diagram = dynamic_cast(handle.target())) return diagram; diff --git a/src/plugins/modeleditor/pxnodeutilities.cpp b/src/plugins/modeleditor/pxnodeutilities.cpp index 4deec764ccb..7e6c986a509 100644 --- a/src/plugins/modeleditor/pxnodeutilities.cpp +++ b/src/plugins/modeleditor/pxnodeutilities.cpp @@ -120,7 +120,7 @@ qmt::MPackage *PxNodeUtilities::createBestMatchingPackagePath( roots.takeFirst(); // append all sub-packages of the same level as next root packages - foreach (const qmt::Handle &handle, package->children()) { + for (const qmt::Handle &handle : package->children()) { if (handle.hasTarget()) { if (auto childPackage = dynamic_cast(handle.target())) { // only accept root packages in the same path as the suggested parent package @@ -139,7 +139,7 @@ qmt::MPackage *PxNodeUtilities::createBestMatchingPackagePath( QString relativeSearchId = qmt::NameController::calcElementNameSearchId( relativeElements.at(relativeIndex)); found = false; - foreach (const qmt::Handle &handle, package->children()) { + for (const qmt::Handle &handle : package->children()) { if (handle.hasTarget()) { if (auto childPackage = dynamic_cast(handle.target())) { if (qmt::NameController::calcElementNameSearchId(childPackage->name()) == relativeSearchId) { @@ -198,7 +198,7 @@ qmt::MObject *PxNodeUtilities::findSameObject(const QStringList &relativeElement qmt::MPackage *package = roots.takeFirst(); // append all sub-packages of the same level as next root packages - foreach (const qmt::Handle &handle, package->children()) { + for (const qmt::Handle &handle : package->children()) { if (handle.hasTarget()) { if (auto childPackage = dynamic_cast(handle.target())) roots.append(childPackage); @@ -212,7 +212,7 @@ qmt::MObject *PxNodeUtilities::findSameObject(const QStringList &relativeElement QString relativeSearchId = qmt::NameController::calcElementNameSearchId( relativeElements.at(relativeIndex)); found = false; - foreach (const qmt::Handle &handle, package->children()) { + for (const qmt::Handle &handle : package->children()) { if (handle.hasTarget()) { if (auto childPackage = dynamic_cast(handle.target())) { if (qmt::NameController::calcElementNameSearchId(childPackage->name()) == relativeSearchId) { @@ -230,7 +230,7 @@ qmt::MObject *PxNodeUtilities::findSameObject(const QStringList &relativeElement QMT_CHECK(relativeIndex >= relativeElements.size()); // chain was found so check for given object within deepest package QString objectSearchId = qmt::NameController::calcElementNameSearchId(object->name()); - foreach (const qmt::Handle &handle, package->children()) { + for (const qmt::Handle &handle : package->children()) { if (handle.hasTarget()) { qmt::MObject *target = handle.target(); if (typeid(*target) == typeid(*object) From 1d763d19419ea1da24c47a45398a626ed7a65949 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Wed, 24 Jan 2018 06:42:02 +0100 Subject: [PATCH 4/9] QbsPM: Fix compile with Qt5.6 + gcc4.9 Broke with a40f11e071d78eca267edb75f8808025fcd26a9c. Change-Id: If647f1a66ddd47795598cc1825c17b73d712d409 Reviewed-by: Orgad Shaneh --- src/plugins/qbsprojectmanager/qbsrunconfiguration.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/qbsprojectmanager/qbsrunconfiguration.cpp b/src/plugins/qbsprojectmanager/qbsrunconfiguration.cpp index e63a28e0bdc..8595b7dfbfa 100644 --- a/src/plugins/qbsprojectmanager/qbsrunconfiguration.cpp +++ b/src/plugins/qbsprojectmanager/qbsrunconfiguration.cpp @@ -73,7 +73,7 @@ const char QBS_RC_PREFIX[] = "Qbs.RunConfiguration:"; static QString rcNameSeparator() { return QLatin1String("---Qbs.RC.NameSeparator---"); } -static QString usingLibraryPathsKey() { return "Qbs.RunConfiguration.UsingLibraryPaths"; } +static QString usingLibraryPathsKey() { return QString("Qbs.RunConfiguration.UsingLibraryPaths"); } const qbs::ProductData findProduct(const qbs::ProjectData &pro, const QString &uniqeName) { From 9e066c7b17ecc7399a94763003b23e751bab93e5 Mon Sep 17 00:00:00 2001 From: Robert Loehning Date: Wed, 13 Sep 2017 15:56:47 +0200 Subject: [PATCH 5/9] Move HTML out of translated strings Change-Id: I4664427086619f33e9a882eb3f0a5f2f52e1b42a Reviewed-by: Jochen Becher Reviewed-by: Leena Miettinen Reviewed-by: Friedemann Kleint Reviewed-by: Eike Ziller --- .../qmt/model_widgets_ui/propertiesviewmview.cpp | 2 +- src/plugins/clearcase/versionselector.cpp | 7 ++++--- .../cmakeprojectmanager/cmakekitinformation.cpp | 4 ++-- src/plugins/cmakeprojectmanager/cmakeprojectnodes.cpp | 2 +- src/plugins/cpaster/kdepasteprotocol.cpp | 3 ++- src/plugins/debugger/breakhandler.cpp | 10 +++++----- src/plugins/debugger/commonoptionspage.cpp | 9 +++++---- src/plugins/debugger/debuggeritemmanager.cpp | 9 +++++---- src/plugins/modeleditor/actionhandler.cpp | 3 ++- 9 files changed, 27 insertions(+), 22 deletions(-) diff --git a/src/libs/modelinglib/qmt/model_widgets_ui/propertiesviewmview.cpp b/src/libs/modelinglib/qmt/model_widgets_ui/propertiesviewmview.cpp index f0d18509fed..519f9ca15cb 100644 --- a/src/libs/modelinglib/qmt/model_widgets_ui/propertiesviewmview.cpp +++ b/src/libs/modelinglib/qmt/model_widgets_ui/propertiesviewmview.cpp @@ -1180,7 +1180,7 @@ void PropertiesView::MView::onClassMembersStatusChanged(bool valid) if (valid) m_classMembersStatusLabel->clear(); else - m_classMembersStatusLabel->setText(tr("Invalid syntax.")); + m_classMembersStatusLabel->setText("" + tr("Invalid syntax.") + ""); } void PropertiesView::MView::onParseClassMembers() diff --git a/src/plugins/clearcase/versionselector.cpp b/src/plugins/clearcase/versionselector.cpp index 42067fd0417..453ce132ab7 100644 --- a/src/plugins/clearcase/versionselector.cpp +++ b/src/plugins/clearcase/versionselector.cpp @@ -39,9 +39,10 @@ VersionSelector::VersionSelector(const QString &fileName, const QString &message { ui->setupUi(this); ui->headerLabel->setText(ui->headerLabel->text().arg(fileName)); - ui->loadedText->setHtml(tr("

Note: You will not be able to check in " - "this file without merging the changes (not supported by the " - "plugin)

")); + ui->loadedText->setHtml("

" + + tr("Note: You will not be able to check in this file without merging " + "the changes (not supported by the plugin)") + + "

"); m_stream = new QTextStream(message.toLocal8Bit(), QIODevice::ReadOnly | QIODevice::Text); QString line; while (!m_stream->atEnd() && !line.contains(QLatin1String("1) Loaded version"))) diff --git a/src/plugins/cmakeprojectmanager/cmakekitinformation.cpp b/src/plugins/cmakeprojectmanager/cmakekitinformation.cpp index 3a52d6911ce..b59fb5e2353 100644 --- a/src/plugins/cmakeprojectmanager/cmakekitinformation.cpp +++ b/src/plugins/cmakeprojectmanager/cmakekitinformation.cpp @@ -450,9 +450,9 @@ KitInformation::ItemList CMakeGeneratorKitInformation::toUserOutput(const Kit *k } else { message = tr("Generator: %1
Extra generator: %2").arg(info.generator).arg(info.extraGenerator); if (!info.platform.isEmpty()) - message += tr("
Platform: %1").arg(info.platform); + message += "
" + tr("Platform: %1").arg(info.platform); if (!info.toolset.isEmpty()) - message += tr("
Toolset: %1").arg(info.toolset); + message += "
" + tr("Toolset: %1").arg(info.toolset); } return ItemList() << qMakePair(tr("CMake Generator"), message); } diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectnodes.cpp b/src/plugins/cmakeprojectmanager/cmakeprojectnodes.cpp index 98e6b4efc22..3740aee8be5 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectnodes.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeprojectnodes.cpp @@ -115,7 +115,7 @@ void CMakeTargetNode::setTargetInformation(const QList &artifac m_tooltip += QCoreApplication::translate("CMakeTargetNode", "No build artifacts"); } else { const QStringList tmp = Utils::transform(artifacts, &Utils::FileName::toUserOutput); - m_tooltip += QCoreApplication::translate("CMakeTargetNode", "Build artifacts:
") + m_tooltip += QCoreApplication::translate("CMakeTargetNode", "Build artifacts:") + "
" + tmp.join("
"); } } diff --git a/src/plugins/cpaster/kdepasteprotocol.cpp b/src/plugins/cpaster/kdepasteprotocol.cpp index c5c09cb9bf5..bafe229e3d6 100644 --- a/src/plugins/cpaster/kdepasteprotocol.cpp +++ b/src/plugins/cpaster/kdepasteprotocol.cpp @@ -286,7 +286,8 @@ void KdePasteProtocol::paste(const QString &text, Protocol::ContentType ct, int QString details = tr("Pasting to KDE paster needs authentication.
" "Enter your KDE Identity credentials to continue."); if (m_loginFailed) - details.prepend(tr("Login failed

")); + details.prepend("" + + tr("Login failed") + "

"); AuthenticationDialog authDialog(details, Core::ICore::dialogParent()); authDialog.setWindowTitle("Authenticate for KDE paster"); diff --git a/src/plugins/debugger/breakhandler.cpp b/src/plugins/debugger/breakhandler.cpp index df579b8a602..3488be43047 100644 --- a/src/plugins/debugger/breakhandler.cpp +++ b/src/plugins/debugger/breakhandler.cpp @@ -447,9 +447,9 @@ BreakpointDialog::BreakpointDialog(Breakpoint b, QWidget *parent) m_labelUseFullPath->setToolTip(pathToolTip); const QString moduleToolTip = - tr("

Specifying the module (base name of the library or executable) " - "for function or file type breakpoints can significantly speed up " - "debugger startup times (CDB, LLDB)."); + "

" + tr("Specifying the module (base name of the library or executable) " + "for function or file type breakpoints can significantly speed up " + "debugger startup times (CDB, LLDB).") + "

"; m_lineEditModule = new QLineEdit(groupBoxAdvanced); m_lineEditModule->setToolTip(moduleToolTip); m_labelModule = new QLabel(tr("&Module:"), groupBoxAdvanced); @@ -457,8 +457,8 @@ BreakpointDialog::BreakpointDialog(Breakpoint b, QWidget *parent) m_labelModule->setToolTip(moduleToolTip); const QString commandsToolTip = - tr("

Debugger commands to be executed when the breakpoint is hit. " - "This feature is only available for GDB."); + "

" + tr("Debugger commands to be executed when the breakpoint is hit. " + "This feature is only available for GDB.") + "

"; m_textEditCommands = new SmallTextEdit(groupBoxAdvanced); m_textEditCommands->setToolTip(commandsToolTip); m_labelCommands = new QLabel(tr("&Commands:"), groupBoxAdvanced); diff --git a/src/plugins/debugger/commonoptionspage.cpp b/src/plugins/debugger/commonoptionspage.cpp index 7aeb3a7cb5e..d78e1b89481 100644 --- a/src/plugins/debugger/commonoptionspage.cpp +++ b/src/plugins/debugger/commonoptionspage.cpp @@ -320,10 +320,11 @@ QWidget *LocalsAndExpressionsOptionsPage::widget() auto groupBoxCustomDumperCommands = new QGroupBox(debuggingHelperGroupBox); groupBoxCustomDumperCommands->setTitle(tr("Debugging Helper Customization")); - groupBoxCustomDumperCommands->setToolTip(tr( - "

Python commands entered here will be executed after built-in " - "debugging helpers have been loaded and fully initialized. You can load additional " - "debugging helpers or modify existing ones here.

")); + groupBoxCustomDumperCommands->setToolTip("

" + + tr("Python commands entered here will be executed after built-in " + "debugging helpers have been loaded and fully initialized. You can " + "load additional debugging helpers or modify existing ones here.") + + "

"); auto textEditCustomDumperCommands = new QTextEdit(groupBoxCustomDumperCommands); textEditCustomDumperCommands->setAcceptRichText(false); diff --git a/src/plugins/debugger/debuggeritemmanager.cpp b/src/plugins/debugger/debuggeritemmanager.cpp index 9f543f01ab7..f78f9807995 100644 --- a/src/plugins/debugger/debuggeritemmanager.cpp +++ b/src/plugins/debugger/debuggeritemmanager.cpp @@ -401,10 +401,11 @@ void DebuggerItemConfigWidget::load(const DebuggerItem *item) const bool is64bit = is64BitWindowsSystem(); const QString versionString = is64bit ? tr("64-bit version") : tr("32-bit version"); //: Label text for path configuration. %2 is "x-bit version". - text = tr("

Specify the path to the " - "Windows Console Debugger executable" - " (%2) here.

"""). - arg(QLatin1String(debuggingToolsWikiLinkC), versionString); + text = "

" + + tr("Specify the path to the " + "Windows Console Debugger executable" + " (%2) here.").arg(QLatin1String(debuggingToolsWikiLinkC), versionString) + + "

"; versionCommand = QLatin1String("-version"); } else { versionCommand = QLatin1String("--version"); diff --git a/src/plugins/modeleditor/actionhandler.cpp b/src/plugins/modeleditor/actionhandler.cpp index d03730ccfe0..7af2c6c5fbc 100644 --- a/src/plugins/modeleditor/actionhandler.cpp +++ b/src/plugins/modeleditor/actionhandler.cpp @@ -218,7 +218,8 @@ void ActionHandler::createActions() registerCommand(Constants::ACTION_ADD_CANVAS_DIAGRAM, nullptr, Core::Context(), true, tr("Add Canvas Diagram")); d->synchronizeBrowserAction = registerCommand( Constants::ACTION_SYNC_BROWSER, nullptr, Core::Context(), true, - tr("Synchronize Browser and Diagram
Press&Hold for options"))->action(); + tr("Synchronize Browser and Diagram") + "
" + + tr("Press && Hold for options") + "")->action(); d->synchronizeBrowserAction->setIcon(Utils::Icons::LINK.icon()); d->synchronizeBrowserAction->setCheckable(true); From 193e3de80a31503f597fd04c471172d40aaf03be Mon Sep 17 00:00:00 2001 From: David Schulz Date: Wed, 24 Jan 2018 10:20:59 +0100 Subject: [PATCH 6/9] Core: modernize HelpManager Change-Id: Ia5468ee5113f85206d1a714f4580297d166fbafd Reviewed-by: Eike Ziller --- src/plugins/coreplugin/helpmanager.cpp | 55 ++++++++++++++------------ src/plugins/coreplugin/helpmanager.h | 2 +- 2 files changed, 31 insertions(+), 26 deletions(-) diff --git a/src/plugins/coreplugin/helpmanager.cpp b/src/plugins/coreplugin/helpmanager.cpp index 376323b6019..3d6780b9097 100644 --- a/src/plugins/coreplugin/helpmanager.cpp +++ b/src/plugins/coreplugin/helpmanager.cpp @@ -53,10 +53,12 @@ namespace Core { struct HelpManagerPrivate { HelpManagerPrivate() : - m_needsSetup(true), m_helpEngine(0), m_collectionWatcher(0) + m_needsSetup(true), m_helpEngine(nullptr), m_collectionWatcher(nullptr) {} - QStringList documentationFromInstaller(); + ~HelpManagerPrivate(); + + const QStringList documentationFromInstaller(); void readSettings(); void writeSettings(); void cleanUpDocumentation(); @@ -73,8 +75,8 @@ struct HelpManagerPrivate QSet m_userRegisteredFiles; }; -static HelpManager *m_instance = 0; -static HelpManagerPrivate *d; +static HelpManager *m_instance = nullptr; +static HelpManagerPrivate *d = nullptr; static const char linksForKeyQuery[] = "SELECT d.Title, f.Name, e.Name, " "d.Name, a.Anchor FROM IndexTable a, FileNameTable d, FolderTable e, " @@ -102,11 +104,8 @@ HelpManager::HelpManager(QObject *parent) : HelpManager::~HelpManager() { - d->writeSettings(); - delete d->m_helpEngine; - d->m_helpEngine = 0; - m_instance = 0; delete d; + m_instance = nullptr; } HelpManager *HelpManager::instance() @@ -124,13 +123,13 @@ QString HelpManager::collectionFilePath() void HelpManager::registerDocumentation(const QStringList &files) { if (d->m_needsSetup) { - foreach (const QString &filePath, files) + for (const QString &filePath : files) d->m_filesToRegister.insert(filePath); return; } bool docsChanged = false; - foreach (const QString &file, files) { + for (const QString &file : files) { const QString &nameSpace = d->m_helpEngine->namespaceName(file); if (nameSpace.isEmpty()) continue; @@ -162,13 +161,13 @@ void HelpManager::registerDocumentation(const QStringList &files) void HelpManager::unregisterDocumentation(const QStringList &nameSpaces) { if (d->m_needsSetup) { - foreach (const QString &name, nameSpaces) + for (const QString &name : nameSpaces) d->m_nameSpacesToUnregister.insert(name); return; } bool docsChanged = false; - foreach (const QString &nameSpace, nameSpaces) { + for (const QString &nameSpace : nameSpaces) { const QString filePath = d->m_helpEngine->documentationFileName(nameSpace); if (d->m_helpEngine->unregisterDocumentation(nameSpace)) { docsChanged = true; @@ -185,7 +184,7 @@ void HelpManager::unregisterDocumentation(const QStringList &nameSpaces) void HelpManager::registerUserDocumentation(const QStringList &filePaths) { - foreach (const QString &filePath, filePaths) + for (const QString &filePath : filePaths) d->m_userRegisteredFiles.insert(filePath); registerDocumentation(filePaths); } @@ -219,7 +218,7 @@ QMap HelpManager::linksForKeyword(const QString &key) QSqlDatabase db = QSqlDatabase::addDatabase(sqlite, name); if (db.driver() && db.driver()->lastError().type() == QSqlError::NoError) { const QStringList ®isteredDocs = d->m_helpEngine->registeredDocumentations(); - foreach (const QString &nameSpace, registeredDocs) { + for (const QString &nameSpace : registeredDocs) { db.setDatabaseName(d->m_helpEngine->documentationFileName(nameSpace)); if (db.open()) { QSqlQuery query = QSqlQuery(db); @@ -308,7 +307,7 @@ HelpManager::Filters HelpManager::filters() Filters filters; const QStringList &customFilters = d->m_helpEngine->customFilters(); - foreach (const QString &filter, customFilters) + for (const QString &filter : customFilters) filters.insert(filter, d->m_helpEngine->filterAttributes(filter)); return filters; } @@ -325,7 +324,7 @@ HelpManager::Filters HelpManager::fixedFilters() QSqlDatabase db = QSqlDatabase::addDatabase(sqlite, name); if (db.driver() && db.driver()->lastError().type() == QSqlError::NoError) { const QStringList ®isteredDocs = d->m_helpEngine->registeredDocumentations(); - foreach (const QString &nameSpace, registeredDocs) { + for (const QString &nameSpace : registeredDocs) { db.setDatabaseName(d->m_helpEngine->documentationFileName(nameSpace)); if (db.open()) { QSqlQuery query = QSqlQuery(db); @@ -382,7 +381,7 @@ void HelpManager::setupHelpManager() d->m_helpEngine = new QHelpEngineCore(collectionFilePath(), m_instance); d->m_helpEngine->setupData(); - foreach (const QString &filePath, d->documentationFromInstaller()) + for (const QString &filePath : d->documentationFromInstaller()) d->m_filesToRegister.insert(filePath); d->cleanUpDocumentation(); @@ -409,7 +408,7 @@ void HelpManagerPrivate::cleanUpDocumentation() // mark documentation for removal for which there is no documentation file anymore // mark documentation for removal that is neither user registered, nor marked for registration const QStringList ®isteredDocs = m_helpEngine->registeredDocumentations(); - foreach (const QString &nameSpace, registeredDocs) { + for (const QString &nameSpace : registeredDocs) { const QString filePath = m_helpEngine->documentationFileName(nameSpace); if (!QFileInfo::exists(filePath) || (!m_filesToRegister.contains(filePath) @@ -419,22 +418,28 @@ void HelpManagerPrivate::cleanUpDocumentation() } } -QStringList HelpManagerPrivate::documentationFromInstaller() +HelpManagerPrivate::~HelpManagerPrivate() +{ + writeSettings(); + delete m_helpEngine; + m_helpEngine = nullptr; +} + +const QStringList HelpManagerPrivate::documentationFromInstaller() { QSettings *installSettings = ICore::settings(); - QStringList documentationPaths = installSettings->value(QLatin1String("Help/InstalledDocumentation")) + const QStringList documentationPaths = installSettings->value(QLatin1String("Help/InstalledDocumentation")) .toStringList(); QStringList documentationFiles; - foreach (const QString &path, documentationPaths) { + for (const QString &path : documentationPaths) { QFileInfo pathInfo(path); if (pathInfo.isFile() && pathInfo.isReadable()) { documentationFiles << pathInfo.absoluteFilePath(); } else if (pathInfo.isDir()) { - QDir dir(path); - foreach (const QFileInfo &fileInfo, dir.entryInfoList(QStringList(QLatin1String("*.qch")), - QDir::Files | QDir::Readable)) { + const QFileInfoList files(QDir(path).entryInfoList(QStringList(QLatin1String("*.qch")), + QDir::Files | QDir::Readable)); + for (const QFileInfo &fileInfo : files) documentationFiles << fileInfo.absoluteFilePath(); - } } } return documentationFiles; diff --git a/src/plugins/coreplugin/helpmanager.h b/src/plugins/coreplugin/helpmanager.h index 07b22cbe9e8..d2205444962 100644 --- a/src/plugins/coreplugin/helpmanager.h +++ b/src/plugins/coreplugin/helpmanager.h @@ -99,7 +99,7 @@ signals: void helpRequested(const QUrl &url, Core::HelpManager::HelpViewerLocation location); private: - explicit HelpManager(QObject *parent = 0); + explicit HelpManager(QObject *parent = nullptr); ~HelpManager(); static void setupHelpManager(); From b31978a2f7974237f2d2363bcaed18c51b734172 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Mon, 22 Jan 2018 09:18:37 +0100 Subject: [PATCH 7/9] Clang: Use reference instead of pointer in editor processor ...because the pointer can't be null. Change-Id: I318f5d7ff2d2ac7de188718ec6281b083965dfd4 Reviewed-by: Ivan Donchevskii --- .../clangeditordocumentprocessor.cpp | 47 ++++++++----------- .../clangeditordocumentprocessor.h | 4 +- 2 files changed, 21 insertions(+), 30 deletions(-) diff --git a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp index cf0ca4b80d1..03f0d2609e5 100644 --- a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp +++ b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp @@ -405,7 +405,7 @@ void ClangEditorDocumentProcessor::updateProjectPartAndTranslationUnitForEditor( const CppTools::ProjectPart::Ptr projectPart = m_parser->projectPartInfo().projectPart; if (isProjectPartLoadedOrIsFallback(projectPart)) { - registerTranslationUnitForEditor(projectPart.data()); + registerTranslationUnitForEditor(*projectPart.data()); m_projectPart = projectPart; m_isProjectFile = m_parser->projectPartInfo().hints @@ -421,7 +421,8 @@ void ClangEditorDocumentProcessor::onParserFinished() updateProjectPartAndTranslationUnitForEditor(); } -void ClangEditorDocumentProcessor::registerTranslationUnitForEditor(CppTools::ProjectPart *projectPart) +void ClangEditorDocumentProcessor::registerTranslationUnitForEditor( + CppTools::ProjectPart &projectPart) { // On registration we send the document content immediately as an unsaved // file, because @@ -433,7 +434,7 @@ void ClangEditorDocumentProcessor::registerTranslationUnitForEditor(CppTools::Pr // like on Windows. if (m_projectPart) { - if (projectPart->id() == m_projectPart->id()) + if (projectPart.id() == m_projectPart->id()) return; } @@ -503,35 +504,26 @@ ClangBackEnd::FileContainer ClangEditorDocumentProcessor::simpleFileContainer( Utf8String::fromByteArray(codecName)); } -static CppTools::ProjectPart projectPartForLanguageOption(CppTools::ProjectPart *projectPart) +static QStringList languageOptions(const QString &filePath, CppTools::ProjectPart &projectPart) { - if (projectPart) - return *projectPart; - return *CppTools::CppModelManager::instance()->fallbackProjectPart().data(); -} - -static QStringList languageOptions(const QString &filePath, CppTools::ProjectPart *projectPart) -{ - const auto theProjectPart = projectPartForLanguageOption(projectPart); - // Determine file kind with respect to ambiguous headers. CppTools::ProjectFile::Kind fileKind = CppTools::ProjectFile::classify(filePath); if (fileKind == CppTools::ProjectFile::AmbiguousHeader) { - fileKind = theProjectPart.languageVersion <= CppTools::ProjectPart::LatestCVersion + fileKind = projectPart.languageVersion <= CppTools::ProjectPart::LatestCVersion ? CppTools::ProjectFile::CHeader : CppTools::ProjectFile::CXXHeader; } - CppTools::CompilerOptionsBuilder builder(theProjectPart); + CppTools::CompilerOptionsBuilder builder(projectPart); builder.addLanguageOption(fileKind); return builder.options(); } -static QStringList warningOptions(CppTools::ProjectPart *projectPart) +static QStringList warningOptions(CppTools::ProjectPart &projectPart) { - if (projectPart && projectPart->project) { - ClangProjectSettings projectSettings(projectPart->project); + if (projectPart.project) { + ClangProjectSettings projectSettings(projectPart.project); if (!projectSettings.useGlobalConfig()) { const Core::Id warningConfigId = projectSettings.warningConfigId(); const CppTools::ClangDiagnosticConfigsModel configsModel( @@ -581,13 +573,13 @@ static QStringList clazyCommandLine() return result; } -static QStringList commandLineOptions(CppTools::ProjectPart *projectPart) +static QStringList commandLineOptions(CppTools::ProjectPart &projectPart) { QStringList result; - if (!projectPart || !projectPart->project) + if (!projectPart.project) result.append(ClangProjectSettings::globalCommandLineOptions()); else - result.append(ClangProjectSettings{projectPart->project}.commandLineOptions()); + result.append(ClangProjectSettings{projectPart.project}.commandLineOptions()); result.append(tidyCommandLine()); result.append(clazyCommandLine()); return result; @@ -595,24 +587,23 @@ static QStringList commandLineOptions(CppTools::ProjectPart *projectPart) static QStringList precompiledHeaderOptions( const QString& filePath, - CppTools::ProjectPart *projectPart) + CppTools::ProjectPart &projectPart) { using namespace CppTools; if (CppTools::getPchUsage() == CompilerOptionsBuilder::PchUsage::None) return QStringList(); - if (projectPart->precompiledHeaders.contains(filePath)) + if (projectPart.precompiledHeaders.contains(filePath)) return QStringList(); - const CppTools::ProjectPart theProjectPart = projectPartForLanguageOption(projectPart); - CppTools::CompilerOptionsBuilder builder(theProjectPart); + CppTools::CompilerOptionsBuilder builder(projectPart); builder.addPrecompiledHeaderOptions(CompilerOptionsBuilder::PchUsage::Use); return builder.options(); } -static QStringList fileArguments(const QString &filePath, CppTools::ProjectPart *projectPart) +static QStringList fileArguments(const QString &filePath, CppTools::ProjectPart &projectPart) { return languageOptions(filePath, projectPart) + warningOptions(projectPart) @@ -622,12 +613,12 @@ static QStringList fileArguments(const QString &filePath, CppTools::ProjectPart ClangBackEnd::FileContainer ClangEditorDocumentProcessor::fileContainerWithArgumentsAndDocumentContent( - CppTools::ProjectPart *projectPart) const + CppTools::ProjectPart &projectPart) const { const QStringList theFileArguments = fileArguments(filePath(), projectPart); return ClangBackEnd::FileContainer(filePath(), - projectPart->id(), + projectPart.id(), Utf8StringVector(theFileArguments), textDocument()->toPlainText(), true, diff --git a/src/plugins/clangcodemodel/clangeditordocumentprocessor.h b/src/plugins/clangcodemodel/clangeditordocumentprocessor.h index 27c4b355dc0..0363392e8f6 100644 --- a/src/plugins/clangcodemodel/clangeditordocumentprocessor.h +++ b/src/plugins/clangcodemodel/clangeditordocumentprocessor.h @@ -104,14 +104,14 @@ public: private: void onParserFinished(); void updateProjectPartAndTranslationUnitForEditor(); - void registerTranslationUnitForEditor(CppTools::ProjectPart *projectPart); + void registerTranslationUnitForEditor(CppTools::ProjectPart &projectPart); void updateTranslationUnitIfProjectPartExists(); void requestDocumentAnnotations(const QString &projectpartId); HeaderErrorDiagnosticWidgetCreator creatorForHeaderErrorDiagnosticWidget( const ClangBackEnd::DiagnosticContainer &firstHeaderErrorDiagnostic); ClangBackEnd::FileContainer simpleFileContainer(const QByteArray &codecName = QByteArray()) const; ClangBackEnd::FileContainer fileContainerWithArgumentsAndDocumentContent( - CppTools::ProjectPart *projectPart) const; + CppTools::ProjectPart &projectPart) const; ClangBackEnd::FileContainer fileContainerWithDocumentContent(const QString &projectpartId) const; private: From 6b38c73205135834cd30fb2efea613b05f677127 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Mon, 22 Jan 2018 09:40:04 +0100 Subject: [PATCH 8/9] Clang: Centralize gathering file argument into one class Similar to CompilerOptionsBuilder. Change-Id: Ifac0efe37608562912af20a1c22f85e5e9308094 Reviewed-by: Ivan Donchevskii --- .../clangeditordocumentprocessor.cpp | 238 +++++++++--------- .../clangeditordocumentprocessor.h | 4 +- 2 files changed, 126 insertions(+), 116 deletions(-) diff --git a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp index 03f0d2609e5..b0c1959dbb0 100644 --- a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp +++ b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp @@ -421,6 +421,125 @@ void ClangEditorDocumentProcessor::onParserFinished() updateProjectPartAndTranslationUnitForEditor(); } +namespace { +// TODO: Can we marry this with CompilerOptionsBuilder? +class FileOptionsBuilder +{ +public: + FileOptionsBuilder(const QString &filePath, CppTools::ProjectPart &projectPart) + : m_filePath(filePath) + , m_projectPart(projectPart) + { + addLanguageOptions(); + addDiagnosticOptions(); + addGlobalOptions(); + addPrecompiledHeaderOptions(); + } + + const QStringList &options() const { return m_options; } + +private: + void addLanguageOptions() + { + // Determine file kind with respect to ambiguous headers. + CppTools::ProjectFile::Kind fileKind = CppTools::ProjectFile::classify(m_filePath); + if (fileKind == CppTools::ProjectFile::AmbiguousHeader) { + fileKind = m_projectPart.languageVersion <= CppTools::ProjectPart::LatestCVersion + ? CppTools::ProjectFile::CHeader + : CppTools::ProjectFile::CXXHeader; + } + + CppTools::CompilerOptionsBuilder builder(m_projectPart); + builder.addLanguageOption(fileKind); + + m_options.append(builder.options()); + } + + void addDiagnosticOptions() + { + if (m_projectPart.project) { + ClangProjectSettings projectSettings(m_projectPart.project); + if (!projectSettings.useGlobalConfig()) { + const Core::Id warningConfigId = projectSettings.warningConfigId(); + const CppTools::ClangDiagnosticConfigsModel configsModel( + CppTools::codeModelSettings()->clangCustomDiagnosticConfigs()); + if (configsModel.hasConfigWithId(warningConfigId)) { + m_options.append( + configsModel.configWithId(warningConfigId).commandLineWarnings()); + return; + } + } + } + + m_options.append( + CppTools::codeModelSettings()->clangDiagnosticConfig().commandLineWarnings()); + } + + void addXclangArg(const QString &argName, const QString &argValue = QString()) + { + m_options.append("-Xclang"); + m_options.append(argName); + if (!argValue.isEmpty()) { + m_options.append("-Xclang"); + m_options.append(argValue); + } + } + + void addTidyOptions() + { + const QString tidyChecks = CppTools::codeModelSettings()->tidyChecks(); + if (tidyChecks.isEmpty()) + return; + + addXclangArg("-add-plugin", "clang-tidy"); + addXclangArg("-plugin-arg-clang-tidy", "-checks='-*" + tidyChecks + "'"); + } + + void addClazyOptions() + { + const QString clazyChecks = CppTools::codeModelSettings()->clazyChecks(); + if (clazyChecks.isEmpty()) + return; + + addXclangArg("-add-plugin", "clang-lazy"); + addXclangArg("-plugin-arg-clang-lazy", clazyChecks); + } + + void addGlobalOptions() + { + if (!m_projectPart.project) + m_options.append(ClangProjectSettings::globalCommandLineOptions()); + else + m_options.append(ClangProjectSettings{m_projectPart.project}.commandLineOptions()); + + addTidyOptions(); + addClazyOptions(); + } + + void addPrecompiledHeaderOptions() + { + using namespace CppTools; + + if (getPchUsage() == CompilerOptionsBuilder::PchUsage::None) + return; + + if (m_projectPart.precompiledHeaders.contains(m_filePath)) + return; + + CompilerOptionsBuilder builder(m_projectPart); + builder.addPrecompiledHeaderOptions(CompilerOptionsBuilder::PchUsage::Use); + + m_options.append(builder.options()); + } + +private: + const QString &m_filePath; + const CppTools::ProjectPart &m_projectPart; + + QStringList m_options; +}; +} // namespace + void ClangEditorDocumentProcessor::registerTranslationUnitForEditor( CppTools::ProjectPart &projectPart) { @@ -438,8 +557,9 @@ void ClangEditorDocumentProcessor::registerTranslationUnitForEditor( return; } + const FileOptionsBuilder fileOptions(filePath(), projectPart); m_communicator.registerTranslationUnitsForEditor( - {fileContainerWithArgumentsAndDocumentContent(projectPart)}); + {fileContainerWithOptionsAndDocumentContent(projectPart, fileOptions.options())}); ClangCodeModel::Utils::setLastSentDocumentRevision(filePath(), revision()); } @@ -504,122 +624,12 @@ ClangBackEnd::FileContainer ClangEditorDocumentProcessor::simpleFileContainer( Utf8String::fromByteArray(codecName)); } -static QStringList languageOptions(const QString &filePath, CppTools::ProjectPart &projectPart) +ClangBackEnd::FileContainer ClangEditorDocumentProcessor::fileContainerWithOptionsAndDocumentContent( + CppTools::ProjectPart &projectPart, const QStringList &fileOptions) const { - // Determine file kind with respect to ambiguous headers. - CppTools::ProjectFile::Kind fileKind = CppTools::ProjectFile::classify(filePath); - if (fileKind == CppTools::ProjectFile::AmbiguousHeader) { - fileKind = projectPart.languageVersion <= CppTools::ProjectPart::LatestCVersion - ? CppTools::ProjectFile::CHeader - : CppTools::ProjectFile::CXXHeader; - } - - CppTools::CompilerOptionsBuilder builder(projectPart); - builder.addLanguageOption(fileKind); - - return builder.options(); -} - -static QStringList warningOptions(CppTools::ProjectPart &projectPart) -{ - if (projectPart.project) { - ClangProjectSettings projectSettings(projectPart.project); - if (!projectSettings.useGlobalConfig()) { - const Core::Id warningConfigId = projectSettings.warningConfigId(); - const CppTools::ClangDiagnosticConfigsModel configsModel( - CppTools::codeModelSettings()->clangCustomDiagnosticConfigs()); - if (configsModel.hasConfigWithId(warningConfigId)) - return configsModel.configWithId(warningConfigId).commandLineWarnings(); - } - } - - return CppTools::codeModelSettings()->clangDiagnosticConfig().commandLineWarnings(); -} - -static void addXclangArg(QStringList &list, const QString &argName, - const QString &argValue = QString()) -{ - list.append("-Xclang"); - list.append(argName); - if (!argValue.isEmpty()) { - list.append("-Xclang"); - list.append(argValue); - } -} - -static QStringList tidyCommandLine() -{ - const QString tidyChecks = CppTools::codeModelSettings()->tidyChecks(); - - if (tidyChecks.isEmpty()) - return QStringList(); - - QStringList result; - addXclangArg(result, "-add-plugin", "clang-tidy"); - addXclangArg(result, "-plugin-arg-clang-tidy", "-checks='-*" + tidyChecks + "'"); - return result; -} - -static QStringList clazyCommandLine() -{ - const QString clazyChecks = CppTools::codeModelSettings()->clazyChecks(); - - if (clazyChecks.isEmpty()) - return QStringList(); - - QStringList result; - addXclangArg(result, "-add-plugin", "clang-lazy"); - addXclangArg(result, "-plugin-arg-clang-lazy", clazyChecks); - return result; -} - -static QStringList commandLineOptions(CppTools::ProjectPart &projectPart) -{ - QStringList result; - if (!projectPart.project) - result.append(ClangProjectSettings::globalCommandLineOptions()); - else - result.append(ClangProjectSettings{projectPart.project}.commandLineOptions()); - result.append(tidyCommandLine()); - result.append(clazyCommandLine()); - return result; -} - -static QStringList precompiledHeaderOptions( - const QString& filePath, - CppTools::ProjectPart &projectPart) -{ - using namespace CppTools; - - if (CppTools::getPchUsage() == CompilerOptionsBuilder::PchUsage::None) - return QStringList(); - - if (projectPart.precompiledHeaders.contains(filePath)) - return QStringList(); - - CppTools::CompilerOptionsBuilder builder(projectPart); - builder.addPrecompiledHeaderOptions(CompilerOptionsBuilder::PchUsage::Use); - - return builder.options(); -} - -static QStringList fileArguments(const QString &filePath, CppTools::ProjectPart &projectPart) -{ - return languageOptions(filePath, projectPart) - + warningOptions(projectPart) - + commandLineOptions(projectPart) - + precompiledHeaderOptions(filePath, projectPart); -} - -ClangBackEnd::FileContainer -ClangEditorDocumentProcessor::fileContainerWithArgumentsAndDocumentContent( - CppTools::ProjectPart &projectPart) const -{ - const QStringList theFileArguments = fileArguments(filePath(), projectPart); - return ClangBackEnd::FileContainer(filePath(), projectPart.id(), - Utf8StringVector(theFileArguments), + Utf8StringVector(fileOptions), textDocument()->toPlainText(), true, revision()); diff --git a/src/plugins/clangcodemodel/clangeditordocumentprocessor.h b/src/plugins/clangcodemodel/clangeditordocumentprocessor.h index 0363392e8f6..67ef0bc8a5d 100644 --- a/src/plugins/clangcodemodel/clangeditordocumentprocessor.h +++ b/src/plugins/clangcodemodel/clangeditordocumentprocessor.h @@ -110,8 +110,8 @@ private: HeaderErrorDiagnosticWidgetCreator creatorForHeaderErrorDiagnosticWidget( const ClangBackEnd::DiagnosticContainer &firstHeaderErrorDiagnostic); ClangBackEnd::FileContainer simpleFileContainer(const QByteArray &codecName = QByteArray()) const; - ClangBackEnd::FileContainer fileContainerWithArgumentsAndDocumentContent( - CppTools::ProjectPart &projectPart) const; + ClangBackEnd::FileContainer fileContainerWithOptionsAndDocumentContent( + CppTools::ProjectPart &projectPart, const QStringList &fileOptions) const; ClangBackEnd::FileContainer fileContainerWithDocumentContent(const QString &projectpartId) const; private: From 17c64e27f8b47a03fee3c748d0caf20d24c1cce6 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Tue, 23 Jan 2018 10:22:45 +0100 Subject: [PATCH 9/9] Utils: Change processing of children in reverseFindAnyChild() This changes the processing of children to step down into the children first (and their children recursively) instead of just processing direct children in reverse. Fixes an issue with AutoTest plugin where results of data tags got a new intermediate although there was already one present. Change-Id: I1fe42942db975c7a1aa3ddb0b6596979c1164dd7 Reviewed-by: hjk Reviewed-by: Eike Ziller --- src/libs/utils/treemodel.cpp | 4 ++-- src/libs/utils/treemodel.h | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/libs/utils/treemodel.cpp b/src/libs/utils/treemodel.cpp index 61a6a8974c1..6c182ba48e6 100644 --- a/src/libs/utils/treemodel.cpp +++ b/src/libs/utils/treemodel.cpp @@ -866,10 +866,10 @@ TreeItem *TreeItem::reverseFindAnyChild(const std::function & { auto end = m_children.rend(); for (auto it = m_children.rbegin(); it != end; ++it) { - if (pred(*it)) - return *it; if (TreeItem *found = (*it)->reverseFindAnyChild(pred)) return found; + if (pred(*it)) + return *it; } return nullptr; } diff --git a/src/libs/utils/treemodel.h b/src/libs/utils/treemodel.h index 41300b7dbc4..1cef3645111 100644 --- a/src/libs/utils/treemodel.h +++ b/src/libs/utils/treemodel.h @@ -82,7 +82,8 @@ public: void forSelectedChildren(const std::function &pred) const; void forAllChildren(const std::function &pred) const; TreeItem *findAnyChild(const std::function &pred) const; - // like findAnyChild() but processes children from bottom to top + // like findAnyChild() but processes children in exact reverse order + // (bottom to top, most inner children first) TreeItem *reverseFindAnyChild(const std::function &pred) const; // Levels are 1-based: Child at Level 1 is an immediate child.