diff options
36 files changed, 297 insertions, 72 deletions
diff --git a/share/qtcreator/qml-type-descriptions/qbs-base.qmltypes b/share/qtcreator/qml-type-descriptions/qbs-base.qmltypes new file mode 100644 index 0000000000..a25ea0807e --- /dev/null +++ b/share/qtcreator/qml-type-descriptions/qbs-base.qmltypes @@ -0,0 +1,154 @@ +import QtQuick.tooling 1.0 + +Module { + Component { + name: "AndroidApk" + exports: ["qbs/AndroidApk 1.0"] + prototype: "Product" + Property { name: "packageName"; type: "string"} + Property { name: "automaticSources"; type: "bool"} + Property { name: "legacyLayout"; type: "bool"} + Property { name: "sourceSetDir"; type: "string"} + Property { name: "resourceDir"; type: "string"} + Property { name: "assetsDir"; type: "string"} + Property { name: "sourcesDir"; type: "string"} + Property { name: "manifestFile"; type: "string"} + Property { name: "defaultManifestFile"; type: "string"; isReadonly: true } + } + Component { + name: "AppleApplicationDiskImage" + exports: ["qbs/AppleApplicationDiskImage 1.0"] + prototype: "AppleDiskImage" + Property { name: "sourceBase"; type: "string" } + Property { name: "absoluteSourceBase"; type: "string"; isReadonly: true} + Property { name: "symlinks"; type: "string"; isList: true } + Property { name: "stageDirectory"; type: "string"; isReadonly: true} + + } + Component { + name: "AppleDiskImage" + exports: ["qbs/AppleDiskImage 1.0"] + prototype: "Product" + } + Component { + name: "ApplicationExtension" + exports: ["qbs/ApplicationExtension 1.0"] + prototype: "XPCService" + Property { name: "_useLegacyExtensionLibraries"; type: "bool" } + Property { name: "extensionAttributes"; type: "QVariant" } + Property { name: "extensionPointIdentifier"; type: "string" } + Property { name: "extensionPrincipalClass"; type: "string" } + } + Component { + name: "Application" + exports: ["qbs/Application 1.0"] + prototype: "NativeBinary" + } + Component { + name: "AutotestRunner" + exports: ["qbs/AutotestRunner 1.0"] + prototype: "Product" + } + Component { + name: "CppApplication" + exports: ["qbs/CppApplication 1.0"] + prototype: "Application" + } + Component { + name: "DynamicLibrary" + exports: ["qbs/DynamicLibrary 1.0"] + prototype: "Library" + } + Component { + name: "InnoSetup" + exports: ["qbs/InnoSetup 1.0"] + prototype: "Installer" + } + Component { + name: "Installer" + exports: ["qbs/Installer 1.0"] + prototype: "Product" + Property { name: "dependsOnInstallables"; type: "bool" } + Property { name: "auxiliaryInputs"; type: "string"; isList: true } + } + Component { + name: "InstallPackage" + exports: ["qbs/InstallPackage 1.0"] + prototype: "Product" + } + Component { + name: "JavaClassCollection" + exports: ["qbs/InstallPackage 1.0"] + prototype: "Product" + } + Component { + name: "JavaJarFile" + exports: ["qbs/JavaJarFile 1.0"] + prototype: "Product" + Property { name: "entryPoint"; type: "string" } + } + Component { + name: "Library" + exports: ["qbs/Library 1.0"] + prototype: "NativeBinary" + } + Component { + name: "LoadableModule" + exports: ["qbs/LoadableModule 1.0"] + prototype: "DynamicLibrary" + } + Component { + name: "NativeBinary" + exports: ["qbs/NativeBinary 1.0"] + prototype: "Product" + Property { name: "isForAndroid"; type: "bool" } + Property { name: "isForDarwin"; type: "bool" } + } + Component { + name: "NetModule" + exports: ["qbs/NetModule 1.0"] + prototype: "Product" + } + Component { + name: "NodeJSApplication" + exports: ["qbs/NodeJSApplication 1.0"] + prototype: "Product" + } + Component { + name: "NSISSetup" + exports: ["qbs/NSISSetup 1.0"] + prototype: "Installer" + } + Component { + name: "QtApplication" + exports: ["qbs/QtApplication 1.0"] + prototype: "CppApplication" + } + Component { + name: "QtGuiApplication" + exports: ["qbs/QtGuiApplication 1.0"] + prototype: "CppApplication" + Property { name: "linkDefaultQpaPlugin"; type: "bool" } + } + Component { + name: "StaticLibrary" + exports: ["qbs/StaticLibrary 1.0"] + prototype: "Library" + } + Component { + name: "WindowsInstallerPackage" + exports: ["qbs/WindowsInstallerPackage 1.0"] + prototype: "Installer" + } + Component { + name: "WindowsSetupPackage" + exports: ["qbs/WindowsSetupPackage 1.0"] + prototype: "Product" + } + Component { + name: "XPCService" + exports: ["qbs/XPCService 1.0"] + prototype: "Application" + Property { name: "xpcServiceType"; type: "string" } + } +} diff --git a/share/qtcreator/qml/qmlpuppet/qmlprivategate/qmlprivategate_56.cpp b/share/qtcreator/qml/qmlpuppet/qmlprivategate/qmlprivategate_56.cpp index 2f3f4efeb3..5e7818e3d6 100644 --- a/share/qtcreator/qml/qmlpuppet/qmlprivategate/qmlprivategate_56.cpp +++ b/share/qtcreator/qml/qmlpuppet/qmlprivategate/qmlprivategate_56.cpp @@ -425,6 +425,9 @@ QAbstractFileEngine *QrcEngineHandler::create(const QString &fileName) const QString fixedPath = fileName; fixedPath.replace(":" + qrcDefintion.first(), qrcDefintion.last() + '/'); + if (fileName == fixedPath) + return nullptr; + if (QFileInfo::exists(fixedPath)) { fixedPath.replace("//", "/"); fixedPath.replace('\\', '/'); diff --git a/share/qtcreator/translations/translations.pro b/share/qtcreator/translations/translations.pro index 9a3e296dda..0df9762fcc 100644 --- a/share/qtcreator/translations/translations.pro +++ b/share/qtcreator/translations/translations.pro @@ -87,7 +87,7 @@ for(file, files) { $$v = extract QMAKE_EXTRA_TARGETS += ts-$$lang } -ts-all.commands = cd $$wd && $$LUPDATE $$include_options $$sources $$MIME_TR_H $$CUSTOMWIZARD_TR_H $$JSONWIZARD_TR_H $$QMLWIZARD_TR_H $$QTQUICKWIZARD_TR_H $$EXTERNALTOOLS_TR_H SNIPPETS_TR_H -ts $$files +ts-all.commands = cd $$wd && $$LUPDATE $$include_options $$sources $$MIME_TR_H $$CUSTOMWIZARD_TR_H $$JSONWIZARD_TR_H $$QMLWIZARD_TR_H $$QTQUICKWIZARD_TR_H $$EXTERNALTOOLS_TR_H $$SNIPPETS_TR_H -ts $$files ts-all.depends = extract QMAKE_EXTRA_TARGETS += ts-all diff --git a/src/libs/qmljs/qmljscheck.cpp b/src/libs/qmljs/qmljscheck.cpp index 42558f65a4..5b184d37b0 100644 --- a/src/libs/qmljs/qmljscheck.cpp +++ b/src/libs/qmljs/qmljscheck.cpp @@ -855,6 +855,10 @@ static bool checkTopLevelBindingForParentReference(ExpressionStatement *expStmt, void Check::visitQmlObject(Node *ast, UiQualifiedId *typeId, UiObjectInitializer *initializer) { + // TODO: currently Qbs checks are not working properly + if (_doc->language() == Dialect::QmlQbs) + return; + // Don't do type checks if it's a grouped property binding. // For instance: anchors { ... } if (_doc->bind()->isGroupedPropertyBinding(ast)) { diff --git a/src/libs/qmljs/qmljslink.cpp b/src/libs/qmljs/qmljslink.cpp index 61cdcd15d2..9c7855c5fd 100644 --- a/src/libs/qmljs/qmljslink.cpp +++ b/src/libs/qmljs/qmljslink.cpp @@ -392,6 +392,15 @@ Import LinkPrivate::importNonFile(Document::Ptr doc, const ImportInfo &importInf import.object->setPrototype(valueOwner->cppQmlTypes().objectByCppName(moduleApi.cppName)); } + // TODO: at the moment there is not any types information on Qbs imports. + // Just check that tha the import is listed in the Qbs bundle. + if (doc->language() == Dialect::QmlQbs) { + QmlBundle qbs = ModelManagerInterface::instance() + ->activeBundles().bundleForLanguage(Dialect::QmlQbs); + if (qbs.supportedImports().contains(importInfo.name())) + importFound = true; + } + if (!importFound && importInfo.ast()) { import.valid = false; error(doc, locationFromRange(importInfo.ast()->firstSourceLocation(), diff --git a/src/libs/utils/detailswidget.cpp b/src/libs/utils/detailswidget.cpp index ff03150af4..e0e4139f1d 100644 --- a/src/libs/utils/detailswidget.cpp +++ b/src/libs/utils/detailswidget.cpp @@ -189,9 +189,9 @@ void DetailsWidgetPrivate::changeHoverState(bool hovered) if (!m_toolWidget) return; if (HostOsInfo::isMacHost()) - m_toolWidget->setOpacity(hovered ? 1.0 : 0); + m_toolWidget->setOpacity(hovered ? .999 : 0); else - m_toolWidget->fadeTo(hovered ? 1.0 : 0); + m_toolWidget->fadeTo(hovered ? .999 : 0); m_hovered = hovered; } @@ -387,7 +387,7 @@ void DetailsWidget::setToolWidget(FadingPanel *widget) d->m_grid->addWidget(d->m_toolWidget, 0, 1, 1, 1, Qt::AlignRight); if (HostOsInfo::isMacHost()) - d->m_toolWidget->setOpacity(1.0); + d->m_toolWidget->setOpacity(.999); d->changeHoverState(d->m_hovered); } diff --git a/src/plugins/autotest/autotestplugin.cpp b/src/plugins/autotest/autotestplugin.cpp index 46defa4a57..1d850f1240 100644 --- a/src/plugins/autotest/autotestplugin.cpp +++ b/src/plugins/autotest/autotestplugin.cpp @@ -190,16 +190,16 @@ void AutotestPlugin::onRunSelectedTriggered() void AutotestPlugin::updateMenuItemsEnabledState() { - const bool enabled = !ProjectExplorer::BuildManager::isBuilding() - && !TestRunner::instance()->isTestRunning() - && TestTreeModel::instance()->parser()->state() == TestCodeParser::Idle + const bool canScan = !TestRunner::instance()->isTestRunning() + && TestTreeModel::instance()->parser()->state() == TestCodeParser::Idle; + const bool hasTests = TestTreeModel::instance()->hasTests(); + const bool canRun = hasTests && canScan && ProjectExplorer::ProjectExplorerPlugin::canRunStartupProject( ProjectExplorer::Constants::NORMAL_RUN_MODE); - const bool hasTests = TestTreeModel::instance()->hasTests(); - ActionManager::command(Constants::ACTION_RUN_ALL_ID)->action()->setEnabled(enabled && hasTests); - ActionManager::command(Constants::ACTION_RUN_SELECTED_ID)->action()->setEnabled(enabled && hasTests); - ActionManager::command(Constants::ACTION_SCAN_ID)->action()->setEnabled(enabled); + ActionManager::command(Constants::ACTION_RUN_ALL_ID)->action()->setEnabled(canRun); + ActionManager::command(Constants::ACTION_RUN_SELECTED_ID)->action()->setEnabled(canRun); + ActionManager::command(Constants::ACTION_SCAN_ID)->action()->setEnabled(canScan); } QList<QObject *> AutotestPlugin::createTestObjects() const diff --git a/src/plugins/autotest/gtest/gtestoutputreader.cpp b/src/plugins/autotest/gtest/gtestoutputreader.cpp index cc82bccc1a..d3d915d96f 100644 --- a/src/plugins/autotest/gtest/gtestoutputreader.cpp +++ b/src/plugins/autotest/gtest/gtestoutputreader.cpp @@ -65,7 +65,7 @@ void GTestOutputReader::processOutput(const QByteArray &outputLine) static QRegExp testEnds("^\\[-{10}\\] \\d+ tests? from (.*) \\((.*)\\)$"); static QRegExp newTestSetStarts("^\\[ RUN \\] (.*)$"); static QRegExp testSetSuccess("^\\[ OK \\] (.*) \\((.*)\\)$"); - static QRegExp testSetFail("^\\[ FAILED \\] (.*) \\((.*)\\)$"); + static QRegExp testSetFail("^\\[ FAILED \\] (.*) \\((\\d+ ms)\\)$"); static QRegExp disabledTests("^ YOU HAVE (\\d+) DISABLED TESTS?$"); static QRegExp failureLocation("^(.*):(\\d+): Failure$"); static QRegExp errorLocation("^(.*)\\((\\d+)\\): error:.*$"); diff --git a/src/plugins/autotest/testnavigationwidget.cpp b/src/plugins/autotest/testnavigationwidget.cpp index a5cfd8f09d..948af3af72 100644 --- a/src/plugins/autotest/testnavigationwidget.cpp +++ b/src/plugins/autotest/testnavigationwidget.cpp @@ -117,7 +117,6 @@ void TestNavigationWidget::contextMenuEvent(QContextMenuEvent *event) const bool enabled = !ProjectExplorer::BuildManager::isBuilding() && !TestRunner::instance()->isTestRunning() && m_model->parser()->state() == TestCodeParser::Idle; - const bool hasTests = m_model->hasTests(); QMenu menu; QAction *runThisTest = nullptr; @@ -172,10 +171,6 @@ void TestNavigationWidget::contextMenuEvent(QContextMenuEvent *event) connect(selectAll, &QAction::triggered, m_view, &TestTreeView::selectAll); connect(deselectAll, &QAction::triggered, m_view, &TestTreeView::deselectAll); - selectAll->setEnabled(enabled && hasTests); - deselectAll->setEnabled(enabled && hasTests); - rescan->setEnabled(enabled); - if (runThisTest) { menu.addAction(runThisTest); menu.addAction(runWithoutDeploy); diff --git a/src/plugins/autotest/testrunner.cpp b/src/plugins/autotest/testrunner.cpp index 5d74ec9f62..cdc6dd592b 100644 --- a/src/plugins/autotest/testrunner.cpp +++ b/src/plugins/autotest/testrunner.cpp @@ -45,9 +45,10 @@ #include <projectexplorer/session.h> #include <projectexplorer/target.h> +#include <utils/hostosinfo.h> #include <utils/outputformat.h> +#include <utils/qtcprocess.h> #include <utils/runextensions.h> -#include <utils/hostosinfo.h> #include <QComboBox> #include <QDialogButtonBox> @@ -468,7 +469,9 @@ void TestRunner::debugTests() QStringList omitted; ProjectExplorer::StandardRunnable inferior = config->runnable(); inferior.executable = commandFilePath; - inferior.commandLineArguments = config->argumentsForTestRunner(&omitted).join(' '); + + const QStringList args = config->argumentsForTestRunner(&omitted); + inferior.commandLineArguments = Utils::QtcProcess::joinArgs(args); if (!omitted.isEmpty()) { const QString &details = constructOmittedDetailsString(omitted); emit testResultReady(TestResultPtr(new FaultyTestResult(Result::MessageWarn, diff --git a/src/plugins/coreplugin/progressmanager/progressmanager.cpp b/src/plugins/coreplugin/progressmanager/progressmanager.cpp index 2e4ca5dc72..039cd76dd8 100644 --- a/src/plugins/coreplugin/progressmanager/progressmanager.cpp +++ b/src/plugins/coreplugin/progressmanager/progressmanager.cpp @@ -272,7 +272,7 @@ ProgressManagerPrivate::ProgressManagerPrivate() m_progressViewPinned(false), m_hovered(false) { - m_opacityEffect->setOpacity(1); + m_opacityEffect->setOpacity(.999); m_instance = this; m_progressView = new ProgressView; // withDelay, so the statusBarWidget has the chance to get the enter event @@ -540,7 +540,7 @@ void ProgressManagerPrivate::stopFadeOfSummaryProgress() { if (m_opacityAnimation) { m_opacityAnimation->stop(); - m_opacityEffect->setOpacity(1.); + m_opacityEffect->setOpacity(.999); delete m_opacityAnimation; } } @@ -686,7 +686,7 @@ void ProgressManagerPrivate::updateStatusDetailsWidget() void ProgressManagerPrivate::summaryProgressFinishedFading() { m_summaryProgressWidget->setVisible(false); - m_opacityEffect->setOpacity(1.); + m_opacityEffect->setOpacity(.999); } void ProgressManagerPrivate::progressDetailsToggled(bool checked) diff --git a/src/plugins/debugger/debuggeritem.h b/src/plugins/debugger/debuggeritem.h index 5526c52130..7dbdf5949d 100644 --- a/src/plugins/debugger/debuggeritem.h +++ b/src/plugins/debugger/debuggeritem.h @@ -88,7 +88,7 @@ public: void setAbis(const QList<ProjectExplorer::Abi> &abis); void setAbi(const ProjectExplorer::Abi &abi); - enum MatchLevel { DoesNotMatch, MatchesSomewhat, MatchesWell, MatchesPerfectly }; + enum MatchLevel { DoesNotMatch, MatchesSomewhat, MatchesWell, MatchesPerfectly, MatchesPerfectlyInPath }; MatchLevel matchTarget(const ProjectExplorer::Abi &targetAbi) const; QStringList abiNames() const; diff --git a/src/plugins/debugger/debuggerkitinformation.cpp b/src/plugins/debugger/debuggerkitinformation.cpp index 5bdd0272d4..bc37572a3d 100644 --- a/src/plugins/debugger/debuggerkitinformation.cpp +++ b/src/plugins/debugger/debuggerkitinformation.cpp @@ -103,13 +103,20 @@ void DebuggerKitInformation::setup(Kit *k) DebuggerItem bestItem; DebuggerItem::MatchLevel bestLevel = DebuggerItem::DoesNotMatch; - + const Environment systemEnvironment = Environment::systemEnvironment(); foreach (const DebuggerItem &item, DebuggerItemManager::debuggers()) { DebuggerItem::MatchLevel level = DebuggerItem::DoesNotMatch; if (rawId.isNull()) { // Initial setup of a kit. level = item.matchTarget(tcAbi); + // Hack to prefer a debugger from PATH (e.g. autodetected) over other matches. + // This improves the situation a bit if a cross-compilation tool chain has the + // same ABI as the host. + if (level == DebuggerItem::MatchesPerfectly + && systemEnvironment.path().contains(item.command().parentDir().toString())) { + level = DebuggerItem::MatchesPerfectlyInPath; + } } else if (rawId.type() == QVariant::String) { // New structure. if (item.id() == rawId) { diff --git a/src/plugins/debugger/debuggerprotocol.cpp b/src/plugins/debugger/debuggerprotocol.cpp index 07f5e1658f..b0d3e3787e 100644 --- a/src/plugins/debugger/debuggerprotocol.cpp +++ b/src/plugins/debugger/debuggerprotocol.cpp @@ -438,7 +438,8 @@ void extractGdbVersion(const QString &msg, const QChar dot(QLatin1Char('.')); const bool ignoreParenthesisContent = msg.contains(QLatin1String("rubenvb")) - || msg.contains(QLatin1String("SUSE")); + || msg.contains(QLatin1String("openSUSE")) + || msg.contains(QLatin1String("SUSE Linux Enterprise")); const QChar parOpen(QLatin1Char('(')); const QChar parClose(QLatin1Char(')')); diff --git a/src/plugins/debugger/lldb/lldbengine.cpp b/src/plugins/debugger/lldb/lldbengine.cpp index 80f2fd411c..9cd2e4db0a 100644 --- a/src/plugins/debugger/lldb/lldbengine.cpp +++ b/src/plugins/debugger/lldb/lldbengine.cpp @@ -743,6 +743,8 @@ void LldbEngine::handleLldbError(QProcess::ProcessError error) showMessage(QString("LLDB PROCESS ERROR: %1").arg(error)); switch (error) { case QProcess::Crashed: + m_lldbProc.disconnect(); + notifyEngineShutdownFinished(); break; // will get a processExited() as well // impossible case QProcess::FailedToStart: case QProcess::ReadError: diff --git a/src/plugins/projectexplorer/appoutputpane.cpp b/src/plugins/projectexplorer/appoutputpane.cpp index a5f1d35a75..d6644e1255 100644 --- a/src/plugins/projectexplorer/appoutputpane.cpp +++ b/src/plugins/projectexplorer/appoutputpane.cpp @@ -727,7 +727,7 @@ void AppOutputPane::slotRunControlFinished2(RunControl *sender) #ifdef Q_OS_WIN const bool isRunning = Utils::anyOf(m_runControlTabs, [](const RunControlTab &rt) { - return rt.runControl->isRunning(); + return rt.runControl && rt.runControl->isRunning(); }); if (!isRunning) WinDebugInterface::instance()->stop(); diff --git a/src/plugins/projectexplorer/buildstepspage.cpp b/src/plugins/projectexplorer/buildstepspage.cpp index 3e05c09b31..70eecbec88 100644 --- a/src/plugins/projectexplorer/buildstepspage.cpp +++ b/src/plugins/projectexplorer/buildstepspage.cpp @@ -136,9 +136,9 @@ void ToolWidget::setBuildStepEnabled(bool b) m_firstWidget->fadeTo(m_targetOpacity); } else { if (HostOsInfo::isMacHost()) - m_firstWidget->setOpacity(1.0); + m_firstWidget->setOpacity(.999); else - m_firstWidget->fadeTo(1.0); + m_firstWidget->fadeTo(.999); } m_disableButton->setChecked(!b); } diff --git a/src/plugins/qmakeprojectmanager/qmakekitinformation.cpp b/src/plugins/qmakeprojectmanager/qmakekitinformation.cpp index afa40a033e..07455b9bca 100644 --- a/src/plugins/qmakeprojectmanager/qmakekitinformation.cpp +++ b/src/plugins/qmakeprojectmanager/qmakekitinformation.cpp @@ -94,11 +94,23 @@ void QmakeKitInformation::setup(Kit *k) && version->qtAbis().contains(t->targetAbi()); }); if (!possibleTcs.isEmpty()) { - ToolChain *possibleTc - = Utils::findOr(possibleTcs, possibleTcs.last(), - [&spec](const ToolChain *t) { return t->suggestedMkspecList().contains(spec); }); - if (possibleTc) - ToolChainKitInformation::setAllToolChainsToMatch(k, possibleTc); + const QList<ToolChain *> goodTcs = Utils::filtered(possibleTcs, + [&spec](const ToolChain *t) { + return t->suggestedMkspecList().contains(spec); + }); + // Hack to prefer a tool chain from PATH (e.g. autodetected) over other matches. + // This improves the situation a bit if a cross-compilation tool chain has the + // same ABI as the host. + const Environment systemEnvironment = Environment::systemEnvironment(); + ToolChain *bestTc = Utils::findOrDefault(goodTcs, + [&systemEnvironment](const ToolChain *t) { + return systemEnvironment.path().contains(t->compilerCommand().parentDir().toString()); + }); + if (!bestTc) { + bestTc = goodTcs.isEmpty() ? possibleTcs.last() : goodTcs.last(); + } + if (bestTc) + ToolChainKitInformation::setAllToolChainsToMatch(k, bestTc); } } } diff --git a/src/plugins/qmldesigner/components/integration/designdocumentview.cpp b/src/plugins/qmldesigner/components/integration/designdocumentview.cpp index 89d27cd5f0..c30a392cef 100644 --- a/src/plugins/qmldesigner/components/integration/designdocumentview.cpp +++ b/src/plugins/qmldesigner/components/integration/designdocumentview.cpp @@ -170,17 +170,17 @@ Model *DesignDocumentView::pasteToModel() { Model *parentModel = currentModel(); - QTC_ASSERT(parentModel, return 0); + QTC_ASSERT(parentModel, return nullptr); Model *pasteModel(Model::create("empty", 1, 0, parentModel)); - pasteModel->setFileUrl(parentModel->fileUrl()); - pasteModel->changeImports(parentModel->imports(), {}); - Q_ASSERT(pasteModel); if (!pasteModel) - return 0; + return nullptr; + + pasteModel->setFileUrl(parentModel->fileUrl()); + pasteModel->changeImports(parentModel->imports(), {}); DesignDocumentView view; pasteModel->attachView(&view); diff --git a/src/plugins/qmlprojectmanager/fileformat/qmlprojectitem.cpp b/src/plugins/qmlprojectmanager/fileformat/qmlprojectitem.cpp index b462bf48b8..426db64df1 100644 --- a/src/plugins/qmlprojectmanager/fileformat/qmlprojectitem.cpp +++ b/src/plugins/qmlprojectmanager/fileformat/qmlprojectitem.cpp @@ -47,8 +47,6 @@ void QmlProjectItem::setSourceDirectory(const QString &directoryPath) this, &QmlProjectItem::qmlFilesChanged); } } - - setImportPaths(m_importPaths); } void QmlProjectItem::setTargetDirectory(const QString &directoryPath) @@ -60,17 +58,6 @@ void QmlProjectItem::setImportPaths(const QStringList &importPaths) { if (m_importPaths != importPaths) m_importPaths = importPaths; - - // convert to absolute paths - QStringList absoluteImportPaths; - const QDir sourceDir(sourceDirectory()); - foreach (const QString &importPath, importPaths) - absoluteImportPaths += QDir::cleanPath(sourceDir.absoluteFilePath(importPath)); - - if (m_absoluteImportPaths == absoluteImportPaths) - return; - - m_absoluteImportPaths = absoluteImportPaths; } /* Returns list of absolute paths */ diff --git a/src/plugins/qmlprojectmanager/fileformat/qmlprojectitem.h b/src/plugins/qmlprojectmanager/fileformat/qmlprojectitem.h index e3c65e7ef1..2fcbe5de40 100644 --- a/src/plugins/qmlprojectmanager/fileformat/qmlprojectitem.h +++ b/src/plugins/qmlprojectmanager/fileformat/qmlprojectitem.h @@ -51,7 +51,7 @@ public: QString targetDirectory() const { return m_targetDirectory; } void setTargetDirectory(const QString &directoryPath); - QStringList importPaths() const { return m_absoluteImportPaths; } + QStringList importPaths() const { return m_importPaths; } void setImportPaths(const QStringList &paths); QStringList files() const; @@ -72,7 +72,6 @@ protected: QString m_sourceDirectory; QString m_targetDirectory; QStringList m_importPaths; - QStringList m_absoluteImportPaths; QString m_mainFile; QList<Utils::EnvironmentItem> m_environment; QList<QmlProjectContentItem *> m_content; // content property diff --git a/src/plugins/qmlprojectmanager/qmlproject.cpp b/src/plugins/qmlprojectmanager/qmlproject.cpp index cd943af141..c110faf91c 100644 --- a/src/plugins/qmlprojectmanager/qmlproject.cpp +++ b/src/plugins/qmlprojectmanager/qmlproject.cpp @@ -177,7 +177,7 @@ void QmlProject::refresh(RefreshOptions options) QmlJS::ModelManagerInterface::ProjectInfo projectInfo = modelManager->defaultProjectInfoForProject(this); - foreach (const QString &searchPath, customImportPaths()) + foreach (const QString &searchPath, makeAbsolute(canonicalProjectDir(), customImportPaths())) projectInfo.importPaths.maybeInsert(Utils::FileName::fromString(searchPath), QmlJS::Dialect::Qml); @@ -249,6 +249,17 @@ void QmlProject::refreshProjectFile() refresh(QmlProject::ProjectFile | Files); } +QStringList QmlProject::makeAbsolute(const Utils::FileName &path, const QStringList &relativePaths) +{ + if (path.isEmpty()) + return relativePaths; + + const QDir baseDir(path.toString()); + return Utils::transform(relativePaths, [&baseDir](const QString &path) { + return QDir::cleanPath(baseDir.absoluteFilePath(path)); + }); +} + void QmlProject::refreshFiles(const QSet<QString> &/*added*/, const QSet<QString> &removed) { refresh(Files); diff --git a/src/plugins/qmlprojectmanager/qmlproject.h b/src/plugins/qmlprojectmanager/qmlproject.h index 9741fb4177..cd4fc21b29 100644 --- a/src/plugins/qmlprojectmanager/qmlproject.h +++ b/src/plugins/qmlprojectmanager/qmlproject.h @@ -75,6 +75,7 @@ public: void refreshProjectFile(); + static QStringList makeAbsolute(const Utils::FileName &path, const QStringList &relativePaths); protected: RestoreResult fromMap(const QVariantMap &map, QString *errorMessage) override; bool setupTarget(ProjectExplorer::Target *t) override; diff --git a/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp b/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp index 11afeee224..9e8df4546f 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp +++ b/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp @@ -125,18 +125,20 @@ QString QmlProjectRunConfiguration::commandLineArguments() const { // arguments in .user file QString args = m_qmlViewerArgs; - const IDevice::ConstPtr device = DeviceKitInformation::device(target()->kit()); + const Target *currentTarget = target(); + const IDevice::ConstPtr device = DeviceKitInformation::device(currentTarget->kit()); const Utils::OsType osType = device ? device->osType() : Utils::HostOsInfo::hostOs(); // arguments from .qmlproject file - QmlProject *project = static_cast<QmlProject *>(target()->project()); - foreach (const QString &importPath, project->customImportPaths()) { + const QmlProject *project = static_cast<QmlProject *>(currentTarget->project()); + foreach (const QString &importPath, + QmlProject::makeAbsolute(project->targetDirectory(currentTarget), project->customImportPaths())) { Utils::QtcProcess::addArg(&args, QLatin1String("-I"), osType); Utils::QtcProcess::addArg(&args, importPath, osType); } - const QString main - = project->targetFile(Utils::FileName::fromString(mainScript()), target()).toString(); ; + const QString main = project->targetFile(Utils::FileName::fromString(mainScript()), + currentTarget).toString(); if (!main.isEmpty()) Utils::QtcProcess::addArg(&args, main, osType); return args; diff --git a/src/plugins/texteditor/generichighlighter/highlighter.cpp b/src/plugins/texteditor/generichighlighter/highlighter.cpp index 2902f09a63..fd875eae28 100644 --- a/src/plugins/texteditor/generichighlighter/highlighter.cpp +++ b/src/plugins/texteditor/generichighlighter/highlighter.cpp @@ -372,29 +372,33 @@ void Highlighter::iterateThroughRules(const QString &text, progress->clearBracesMatches(); } + const QString itemData = rule->itemData(); + const QSharedPointer<HighlightDefinition> definition = rule->definition(); + const bool lookAhead = rule->isLookAhead(); if (progress->isWillContinueLine()) { createWillContinueBlock(); progress->setWillContinueLine(false); } else { if (rule->hasChildren()) iterateThroughRules(text, length, progress, true, rule->children()); - if (!rule->context().isEmpty() && contextChangeRequired(rule->context())) { m_currentCaptures = progress->captures(); - changeContext(rule->context(), rule->definition()); + changeContext(rule->context(), definition); contextChanged = true; } } + // Do NOT access rule frome here on, because a context change might delete rule + // Format is not applied to child rules directly (but relative to the offset of their // parent) nor to look ahead rules. - if (!childRule && !rule->isLookAhead()) { - if (rule->itemData().isEmpty()) + if (!childRule && !lookAhead) { + if (itemData.isEmpty()) applyFormat(startOffset, progress->offset() - startOffset, m_currentContext->itemData(), m_currentContext->definition()); else - applyFormat(startOffset, progress->offset() - startOffset, rule->itemData(), - rule->definition()); + applyFormat(startOffset, progress->offset() - startOffset, itemData, + definition); } // When there is a match of one child rule the others should be skipped. Otherwise diff --git a/src/plugins/texteditor/generichighlighter/manager.cpp b/src/plugins/texteditor/generichighlighter/manager.cpp index 0cd730a168..d6fdc002b2 100644 --- a/src/plugins/texteditor/generichighlighter/manager.cpp +++ b/src/plugins/texteditor/generichighlighter/manager.cpp @@ -394,7 +394,7 @@ QList<DefinitionMetaDataPtr> Manager::parseAvailableDefinitionsList(QIODevice *d void Manager::downloadAvailableDefinitionsMetaData() { - QUrl url(QLatin1String("https://www.kate-editor.org/syntax/update-5.35.xml")); + QUrl url(QLatin1String("https://www.kate-editor.org/syntax/update-5.60.xml")); QNetworkRequest request(url); // Currently this takes a couple of seconds on Windows 7: QTBUG-10106. QNetworkReply *reply = Utils::NetworkAccessManager::instance()->get(request); diff --git a/src/plugins/texteditor/generichighlighter/progressdata.cpp b/src/plugins/texteditor/generichighlighter/progressdata.cpp index 6075a1a4e4..d79d5b0152 100644 --- a/src/plugins/texteditor/generichighlighter/progressdata.cpp +++ b/src/plugins/texteditor/generichighlighter/progressdata.cpp @@ -108,3 +108,8 @@ void ProgressData::trackRule(Rule *rule) { m_trackedRules.append(rule); } + +void ProgressData::unTrackRule(Rule *rule) +{ + m_trackedRules.removeAll(rule); +} diff --git a/src/plugins/texteditor/generichighlighter/progressdata.h b/src/plugins/texteditor/generichighlighter/progressdata.h index 9563a1601e..d2b158146d 100644 --- a/src/plugins/texteditor/generichighlighter/progressdata.h +++ b/src/plugins/texteditor/generichighlighter/progressdata.h @@ -65,6 +65,7 @@ public: const QStringList &captures() const; void trackRule(Rule *rule); + void unTrackRule(Rule *rule); private: int m_offset; diff --git a/src/plugins/texteditor/generichighlighter/specificrules.cpp b/src/plugins/texteditor/generichighlighter/specificrules.cpp index 02e5ed4230..8c4b80dc66 100644 --- a/src/plugins/texteditor/generichighlighter/specificrules.cpp +++ b/src/plugins/texteditor/generichighlighter/specificrules.cpp @@ -172,6 +172,12 @@ bool StringDetectRule::doMatchSucceed(const QString &text, } // RegExpr +RegExprRule::~RegExprRule() +{ + if (m_progress) + m_progress->unTrackRule(this); +} + void RegExprRule::setPattern(const QString &pattern) { if (pattern.startsWith(QLatin1Char('^'))) @@ -194,6 +200,7 @@ void RegExprRule::doReplaceExpressions(const QStringList &captures) void RegExprRule::doProgressFinished() { + m_progress = nullptr; m_isCached = false; } @@ -234,6 +241,7 @@ bool RegExprRule::doMatchSucceed(const QString &text, return true; m_isCached = true; + m_progress = progress; progress->trackRule(this); return false; diff --git a/src/plugins/texteditor/generichighlighter/specificrules.h b/src/plugins/texteditor/generichighlighter/specificrules.h index 051ab81d26..63beaf8df9 100644 --- a/src/plugins/texteditor/generichighlighter/specificrules.h +++ b/src/plugins/texteditor/generichighlighter/specificrules.h @@ -114,7 +114,7 @@ private: class RegExprRule : public DynamicRule { public: - virtual ~RegExprRule() {} + virtual ~RegExprRule(); void setPattern(const QString &pattern); void setInsensitive(const QString &insensitive); @@ -136,6 +136,7 @@ private: int m_length = 0; QStringList m_captures; QRegExp m_expression; + ProgressData *m_progress = nullptr; }; class KeywordRule : public Rule diff --git a/tests/auto/debugger/tst_gdb.cpp b/tests/auto/debugger/tst_gdb.cpp index 5b946a1936..1c1c6f7338 100644 --- a/tests/auto/debugger/tst_gdb.cpp +++ b/tests/auto/debugger/tst_gdb.cpp @@ -98,6 +98,10 @@ void tst_gdb::version_data() << "GNU gdb (GDB) SUSE (6.8.91.20090930-2.4)" << 60891 << 20090930 << false << false; + QTest::newRow("SLES") + << "GNU gdb (GDB; SUSE Linux Enterprise 10) 7.9.1" + << 70901 << 0 << false << false; + QTest::newRow("Apple") << "GNU gdb 6.3.50-20050815 (Apple version gdb-1461.2)" << 60350 << 1461 << true << false; diff --git a/tests/system/shared/workarounds.py b/tests/system/shared/workarounds.py index cb1cc0ba84..7ab37d4473 100644 --- a/tests/system/shared/workarounds.py +++ b/tests/system/shared/workarounds.py @@ -255,9 +255,18 @@ class JIRA: # for later lookup which function to call for which bug # ALWAYS update this dict when adding a new function for a workaround! def __initBugDict__(self): - self.__bugs__= {} + self.__bugs__= { + 'QTCREATORBUG-19717':self._workaroundCreator19717_, + } # helper function - will be called if no workaround for the requested bug is deposited def _exitFatal_(self, bugType, number): test.fatal("No workaround found for bug %s-%d" % (bugType, number)) ############### functions that hold workarounds ################################# + + def _workaroundCreator19717_(self, *args): + targetname = Targets.getStringForTarget(Targets.DESKTOP_5_3_1_DEFAULT) + switchViewTo(ViewConstants.PROJECTS) + mouseClick(waitForObjectItem(":Projects.ProjectNavigationTreeView", + "Build & Run." + targetname.replace(".", "\\."))) + switchViewTo(ViewConstants.EDIT) diff --git a/tests/system/suite_WELP/tst_WELP01/test.py b/tests/system/suite_WELP/tst_WELP01/test.py index 700ccdcd8c..d4d2d25bde 100755 --- a/tests/system/suite_WELP/tst_WELP01/test.py +++ b/tests/system/suite_WELP/tst_WELP01/test.py @@ -158,7 +158,7 @@ def main(): for (qType, prop, info) in expect: test.verify(checkIfObjectExists(search % (qType, prop)), "Verifying whether %s is shown" % info) - checkTableViewForContent(search % (expect[0][0], expect[0][1]), "Creating.*", "Tutorials", + checkTableViewForContent(search % (expect[0][0], expect[0][1]), "Help: Create .*", "Tutorials", "Verifying that at least one tutorial is displayed.") # exit Qt Creator invokeMenuItem("File", "Exit") diff --git a/tests/system/suite_WELP/tst_WELP04/test.py b/tests/system/suite_WELP/tst_WELP04/test.py index 3d1bff2f7f..18659f2262 100644 --- a/tests/system/suite_WELP/tst_WELP04/test.py +++ b/tests/system/suite_WELP/tst_WELP04/test.py @@ -53,7 +53,7 @@ def main(): tutorial = findExampleOrTutorial(tableView, ".*", True) test.verify(tutorial is None, "Verifying: 'Tutorials' topic is opened and nothing is shown.") - bnr = "Building and Running an Example Application" + bnr = "Help: Build and Run Examples" replaceEditorContent(searchTutorials, bnr.lower()) waitFor('findExampleOrTutorial(tableView, "%s.*") is not None' % bnr, 3000) tutorial = findExampleOrTutorial(tableView, "%s.*" % bnr, True) @@ -68,8 +68,8 @@ def main(): # check a demonstration video link mouseClick(searchTutorials) replaceEditorContent(searchTutorials, "embedded device") - waitFor('findExampleOrTutorial(tableView, "Qt for Device Creation.*") is not None', 3000) - tutorial = findExampleOrTutorial(tableView, "Qt for Device Creation.*", True) + waitFor('findExampleOrTutorial(tableView, "Online: Qt for Device Creation.*") is not None', 3000) + tutorial = findExampleOrTutorial(tableView, "Online: Qt for Device Creation.*", True) test.verify(tutorial is not None, "Verifying: Link to the expected demonstration video exists.") # exit Qt Creator diff --git a/tests/system/suite_debugger/tst_qml_js_console/test.py b/tests/system/suite_debugger/tst_qml_js_console/test.py index 7187fc9cea..7c324b6970 100644 --- a/tests/system/suite_debugger/tst_qml_js_console/test.py +++ b/tests/system/suite_debugger/tst_qml_js_console/test.py @@ -124,6 +124,8 @@ def main(): if not startedWithoutPluginError(): return + JIRA.performWorkaroundForBug(19717) + # if Debug is enabled - 1 valid kit is assigned - real check for this is done in tst_qml_locals fancyDebugButton = waitForObject(":*Qt Creator.Start Debugging_Core::Internal::FancyToolButton") if test.verify(waitFor('fancyDebugButton.enabled', 5000), "Start Debugging is enabled."): diff --git a/tests/system/suite_debugger/tst_qml_locals/test.py b/tests/system/suite_debugger/tst_qml_locals/test.py index fb6d45c649..54be9f918a 100644 --- a/tests/system/suite_debugger/tst_qml_locals/test.py +++ b/tests/system/suite_debugger/tst_qml_locals/test.py @@ -43,6 +43,7 @@ def main(): startApplication('qtcreator' + SettingsPath + ' "%s"' % qmlProjFile) if not startedWithoutPluginError(): return + JIRA.performWorkaroundForBug(19717) waitFor('object.exists(":Qt Creator_Utils::NavigationTreeView")', 10000) fancyConfButton = findObject(":*Qt Creator_Core::Internal::FancyToolButton") fancyRunButton = findObject(":*Qt Creator.Run_Core::Internal::FancyToolButton") |