From fc573254b74ef2aa173fa4604b4647b7f8d87bbc Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Fri, 1 Mar 2019 14:07:54 +0100 Subject: [PATCH 01/27] Bump version to 4.9.0-beta2 Change-Id: I7ba0b4651f5a718c09ecf72fdc25b26cceaaf966 Reviewed-by: Eike Ziller --- qbs/modules/qtc/qtc.qbs | 6 +++--- qtcreator.pri | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/qbs/modules/qtc/qtc.qbs b/qbs/modules/qtc/qtc.qbs index b87523a9c39..9a9d6c4021d 100644 --- a/qbs/modules/qtc/qtc.qbs +++ b/qbs/modules/qtc/qtc.qbs @@ -4,16 +4,16 @@ import qbs.FileInfo import "qtc.js" as HelperFunctions Module { - property string qtcreator_display_version: '4.9.0-beta1' + property string qtcreator_display_version: '4.9.0-beta2' property string ide_version_major: '4' property string ide_version_minor: '8' - property string ide_version_release: '82' + property string ide_version_release: '83' property string qtcreator_version: ide_version_major + '.' + ide_version_minor + '.' + ide_version_release property string ide_compat_version_major: '4' property string ide_compat_version_minor: '8' - property string ide_compat_version_release: '82' + property string ide_compat_version_release: '83' property string qtcreator_compat_version: ide_compat_version_major + '.' + ide_compat_version_minor + '.' + ide_compat_version_release diff --git a/qtcreator.pri b/qtcreator.pri index e222ab79b3f..ff69b3c405c 100644 --- a/qtcreator.pri +++ b/qtcreator.pri @@ -1,10 +1,10 @@ !isEmpty(QTCREATOR_PRI_INCLUDED):error("qtcreator.pri already included") QTCREATOR_PRI_INCLUDED = 1 -QTCREATOR_VERSION = 4.8.82 -QTCREATOR_COMPAT_VERSION = 4.8.82 +QTCREATOR_VERSION = 4.8.83 +QTCREATOR_COMPAT_VERSION = 4.8.83 VERSION = $$QTCREATOR_VERSION -QTCREATOR_DISPLAY_VERSION = 4.9.0-beta1 +QTCREATOR_DISPLAY_VERSION = 4.9.0-beta2 QTCREATOR_COPYRIGHT_YEAR = 2019 BINARY_ARTIFACTS_BRANCH = master From e31020a60ee2c982527bce6e61bf6e3fe9953327 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Tue, 19 Feb 2019 10:28:52 +0100 Subject: [PATCH 02/27] Squish: Fix expected default setting Pre-compiled headers are no more ignored by default. Change-Id: Ia107495626f8050fb2537443ef69ea732a93b530 Reviewed-by: Robert Loehning --- tests/system/shared/clang.py | 4 ++-- tests/system/shared/utils.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/system/shared/clang.py b/tests/system/shared/clang.py index 810f652b0b3..04cd836e66a 100644 --- a/tests/system/shared/clang.py +++ b/tests/system/shared/clang.py @@ -65,6 +65,6 @@ def getCodeModelString(useClang): def checkCodeModelSettings(useClang): __openCodeModelOptions__() - test.verify(verifyChecked("{name='ignorePCHCheckBox' type='QCheckBox' visible='1'}"), - "Verifying whether 'Ignore pre-compiled headers' is checked by default.") + test.log("Verifying whether 'Ignore pre-compiled headers' is unchecked by default.") + verifyChecked("{name='ignorePCHCheckBox' type='QCheckBox' visible='1'}", False) clickButton(waitForObject(":Options.OK_QPushButton")) diff --git a/tests/system/shared/utils.py b/tests/system/shared/utils.py index f89b9c6e2d3..36b5fbfc4e8 100644 --- a/tests/system/shared/utils.py +++ b/tests/system/shared/utils.py @@ -42,9 +42,9 @@ def tempDir(): def deleteDirIfExists(path): shutil.rmtree(path, True) -def verifyChecked(objectName): +def verifyChecked(objectName, checked=True): object = waitForObject(objectName) - test.compare(object.checked, True) + test.compare(object.checked, checked) return object def ensureChecked(objectName, shouldBeChecked = True, timeout=20000): From 5a1d4fbb304fb6d95868bd6f3b1a412d8cd06382 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Mon, 18 Feb 2019 15:05:13 +0100 Subject: [PATCH 03/27] BaseFileFind: Save an allocation Change-Id: I243c81c498247a6d3722fab1937c83d80e701ec2 Reviewed-by: Eike Ziller --- src/plugins/texteditor/basefilefind.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/plugins/texteditor/basefilefind.cpp b/src/plugins/texteditor/basefilefind.cpp index a910de019c0..eb449251c16 100644 --- a/src/plugins/texteditor/basefilefind.cpp +++ b/src/plugins/texteditor/basefilefind.cpp @@ -111,8 +111,6 @@ public: class BaseFileFindPrivate { public: - BaseFileFindPrivate() : m_internalSearchEngine(std::make_unique()) {} - QPointer m_currentFindSupport; QLabel *m_resultLabel = nullptr; @@ -125,7 +123,7 @@ public: QPointer m_filterCombo; QPointer m_exclusionCombo; QVector m_searchEngines; - std::unique_ptr m_internalSearchEngine; + InternalEngine m_internalSearchEngine; int m_currentSearchEngineIndex = -1; }; @@ -182,7 +180,7 @@ void SearchEngine::setEnabled(bool enabled) BaseFileFind::BaseFileFind() : d(new BaseFileFindPrivate) { - addSearchEngine(d->m_internalSearchEngine.get()); + addSearchEngine(&d->m_internalSearchEngine); } BaseFileFind::~BaseFileFind() From 2cad90a55999119b5023f670f2970719c996ff24 Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 19 Feb 2019 14:56:41 +0100 Subject: [PATCH 04/27] Debugger: Fix toolbar-oversizing on perspective switch The true reason for the overshooting is still unknown. This here works around the issue by wrapping the toolbar into an additional QScrollArea. Task-number: QTCREATORBUG-21903 Task-number: QTCREATORBUG-21889 Change-Id: If6e89d138cd3e617e4eaa44227b078f31df1a627 Reviewed-by: Eike Ziller --- src/plugins/debugger/debuggermainwindow.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/plugins/debugger/debuggermainwindow.cpp b/src/plugins/debugger/debuggermainwindow.cpp index a5da08055bb..c177b3ffcaa 100644 --- a/src/plugins/debugger/debuggermainwindow.cpp +++ b/src/plugins/debugger/debuggermainwindow.cpp @@ -45,6 +45,7 @@ #include #include #include +#include #include #include @@ -52,6 +53,7 @@ #include #include #include +#include #include #include #include @@ -189,14 +191,22 @@ DebuggerMainWindowPrivate::DebuggerMainWindowPrivate(DebuggerMainWindow *parent) hbox->addWidget(viewButton); hbox->addWidget(closeButton); + auto scrolledToolbar = new QScrollArea; + scrolledToolbar->setWidget(toolbar); + scrolledToolbar->setFrameStyle(QFrame::NoFrame); + scrolledToolbar->setWidgetResizable(true); + scrolledToolbar->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + scrolledToolbar->setFixedHeight(StyleHelper::navigationWidgetHeight()); + scrolledToolbar->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + auto dock = new QDockWidget(DebuggerMainWindow::tr("Toolbar"), q); dock->setObjectName("Toolbar"); dock->setFeatures(QDockWidget::NoDockWidgetFeatures); dock->setAllowedAreas(Qt::BottomDockWidgetArea); dock->setTitleBarWidget(new QWidget(dock)); // hide title bar dock->setProperty("managed_dockwidget", "true"); - toolbar->setParent(dock); - dock->setWidget(toolbar); + dock->setWidget(scrolledToolbar); + m_toolBarDock = dock; q->addDockWidget(Qt::BottomDockWidgetArea, m_toolBarDock); From e1ac54c33b607d5880f7257fa836a09f0f455072 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 1 Mar 2019 10:26:59 +0100 Subject: [PATCH 05/27] Python projects: Add error handling to the JSON parser Display parse errors in case the file is invalid. Amends f7e1354ae563ae6c475ee2e18764127e58073d2b. Task-number: QTCREATORBUG-21824 Change-Id: I0d357597257fcbc49719fae781c61f251a5392fe Reviewed-by: Cristian Maureira-Fredes Reviewed-by: hjk --- .../pythoneditor/pythoneditorplugin.cpp | 54 +++++++++++++------ 1 file changed, 39 insertions(+), 15 deletions(-) diff --git a/src/plugins/pythoneditor/pythoneditorplugin.cpp b/src/plugins/pythoneditor/pythoneditorplugin.cpp index dfd9c6a50ea..1d6af67381d 100644 --- a/src/plugins/pythoneditor/pythoneditorplugin.cpp +++ b/src/plugins/pythoneditor/pythoneditorplugin.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -61,6 +62,7 @@ #include #include #include +#include #include #include @@ -344,30 +346,48 @@ static QStringList readLines(const Utils::FileName &projectFile) return lines; } -static QStringList readLinesJson(const Utils::FileName &projectFile) +static QStringList readLinesJson(const Utils::FileName &projectFile, + QString *errorMessage) { const QString projectFileName = projectFile.fileName(); QStringList lines = { projectFileName }; QFile file(projectFile.toString()); - if (!file.open(QFile::ReadOnly)) + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { + *errorMessage = PythonProject::tr("Unable to open \"%1\" for reading: %2") + .arg(projectFile.toUserOutput(), file.errorString()); return lines; + } + const QByteArray content = file.readAll(); // This assumes te project file is formed with only one field called // 'files' that has a list associated of the files to include in the project. - if (!content.isEmpty()) { - const QJsonDocument doc = QJsonDocument::fromJson(content); - const QJsonObject obj = doc.object(); - if (obj.contains("files")) { - QJsonValue files = obj.value("files"); - QJsonArray files_array = files.toArray(); - QSet visited; - for (const auto &file : files_array) - visited.insert(file.toString()); + if (content.isEmpty()) { + *errorMessage = PythonProject::tr("Unable read \"%1\": The file is empty.") + .arg(projectFile.toUserOutput()); + return lines; + } - lines.append(visited.toList()); - } + QJsonParseError error; + const QJsonDocument doc = QJsonDocument::fromJson(content, &error); + if (doc.isNull()) { + const int line = content.left(error.offset).count('\n') + 1; + *errorMessage = PythonProject::tr("Unable parse %1:%2: %3") + .arg(projectFile.toUserOutput()).arg(line) + .arg(error.errorString()); + return lines; + } + + const QJsonObject obj = doc.object(); + if (obj.contains("files")) { + QJsonValue files = obj.value("files"); + QJsonArray files_array = files.toArray(); + QSet visited; + for (const auto &file : files_array) + visited.insert(file.toString()); + + lines.append(visited.toList()); } return lines; @@ -453,8 +473,12 @@ void PythonProject::parseProject() m_rawListEntries.clear(); const Utils::FileName filePath = projectFilePath(); // The PySide project file is JSON based - if (filePath.endsWith(".pyproject")) - m_rawFileList = readLinesJson(filePath); + if (filePath.endsWith(".pyproject")) { + QString errorMessage; + m_rawFileList = readLinesJson(filePath, &errorMessage); + if (!errorMessage.isEmpty()) + Core::MessageManager::write(errorMessage); + } // To keep compatibility with PyQt we keep the compatibility with plain // text files as project files. else if (filePath.endsWith(".pyqtc")) From cb6fb2cf9136b10d23b1d587e71d0b7f0e51c829 Mon Sep 17 00:00:00 2001 From: Robert Loehning Date: Fri, 1 Mar 2019 13:53:04 +0100 Subject: [PATCH 06/27] VCS: Improve misleading comment Change-Id: I7d3b03219014fda3ad9bcef97ee607a05484e6bb Reviewed-by: Orgad Shaneh --- src/plugins/vcsbase/vcsbasesubmiteditor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/vcsbase/vcsbasesubmiteditor.cpp b/src/plugins/vcsbase/vcsbasesubmiteditor.cpp index 7def2dc94f7..d66759cd171 100644 --- a/src/plugins/vcsbase/vcsbasesubmiteditor.cpp +++ b/src/plugins/vcsbase/vcsbasesubmiteditor.cpp @@ -575,7 +575,7 @@ VcsBaseSubmitEditor::PromptSubmitResult message = tr("What do you want to do with these changes?"); } else { message = tr("Cannot %1%2.\nWhat do you want to do?", - "%2 is an optional error message with ': ' prefix. Do not separate it from %1.") + "%2 is an optional error message with ': ' prefix. Don't add space in front.") .arg(commitName.toLower(), errorMessage.isEmpty() ? errorMessage : ": " + errorMessage); } From b26febac83bea8f7c73f4de6ae928ace99e9d697 Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Fri, 1 Mar 2019 09:06:24 +0200 Subject: [PATCH 07/27] Git: Suppress command logging for "log" in fixup commit editor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ib4aee0a38f0e1cf8d2bdf1ae4884f8e75dbb5193 Reviewed-by: André Hartmann --- src/plugins/git/gitclient.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index 9fdd6a27905..8dac6098973 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -2524,7 +2524,8 @@ bool GitClient::getCommitData(const QString &workingDirectory, // Run status. Note that it has exitcode 1 if there are no added files. QString output; if (commitData.commitType == FixupCommit) { - synchronousLog(repoDirectory, {HEAD, "--not", "--remotes", "-n1"}, &output, errorMessage); + synchronousLog(repoDirectory, {HEAD, "--not", "--remotes", "-n1"}, &output, errorMessage, + VcsCommand::SuppressCommandLogging); if (output.isEmpty()) { *errorMessage = msgNoCommits(false); return false; From 728ad535bc3837816a6e37cba2dc45680c5872c2 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Tue, 26 Feb 2019 15:05:18 +0100 Subject: [PATCH 08/27] SilverSearcher: Fix widget construction if not available Setting a layout on a widget only works after the old layout has been destroyed. Otherwise it just refuses and prints out a warning on the cmdline which in turn results in not displaying the failure inside the UI and keeping the line edit for the optional search options. Change-Id: Id4ff4679d67b625a7248569f6debf1912dc5bcf0 Reviewed-by: Przemyslaw Gorszkowski --- src/plugins/silversearcher/findinfilessilversearcher.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/plugins/silversearcher/findinfilessilversearcher.cpp b/src/plugins/silversearcher/findinfilessilversearcher.cpp index fc65d06a07c..5b22cc2cd4a 100644 --- a/src/plugins/silversearcher/findinfilessilversearcher.cpp +++ b/src/plugins/silversearcher/findinfilessilversearcher.cpp @@ -176,8 +176,6 @@ FindInFilesSilverSearcher::FindInFilesSilverSearcher(QObject *parent) setEnabled(isSilverSearcherAvailable()); if (!isEnabled()) { - auto layout = new QHBoxLayout(m_widget); - layout->setMargin(0); QLabel *label = new QLabel(tr("Silver Searcher is not available on the system.")); label->setStyleSheet("QLabel { color : red; }"); layout->addWidget(label); From c0cd990ab874b427ccac8bda787a64cb65d99f69 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Thu, 28 Feb 2019 14:11:26 +0100 Subject: [PATCH 09/27] Doc: Fix typo in Bare Metal instructions Fixes: QTCREATORBUG-22062 Change-Id: Ie3b57768c946b59b95e6d1c8c245e1287d6b749f Reviewed-by: Lorn Potter --- doc/src/baremetal/creator-baremetal-dev.qdoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/src/baremetal/creator-baremetal-dev.qdoc b/doc/src/baremetal/creator-baremetal-dev.qdoc index 73eaa37ec33..594ad80ae5d 100644 --- a/doc/src/baremetal/creator-baremetal-dev.qdoc +++ b/doc/src/baremetal/creator-baremetal-dev.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2018 The Qt Company Ltd. +** Copyright (C) 2019 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Creator documentation. @@ -53,7 +53,7 @@ \li Select \uicontrol Tools > \uicontrol Options > \uicontrol Devices > \uicontrol {Bare Metal} > \uicontrol Add > \uicontrol Default, - \uicontrol OpenCD, or \uicontrol {ST-LINK Utility} to specify + \uicontrol OpenOCD, or \uicontrol {ST-LINK Utility} to specify connections to GDB servers or hardware debuggers: \image creator-baremetal-device.png "Bare Metal options" From d722edb7724198228d486cd7cae221acef64d41a Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Fri, 1 Mar 2019 17:04:47 +0100 Subject: [PATCH 10/27] SSH: Fix UI text Change-Id: Iabd0a3278ac2f241b8880f41d0cfad729cdea1fd Reviewed-by: Christian Kandeler --- src/libs/ssh/sftptransfer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/ssh/sftptransfer.cpp b/src/libs/ssh/sftptransfer.cpp index 57674cc94dd..7b65048a32d 100644 --- a/src/libs/ssh/sftptransfer.cpp +++ b/src/libs/ssh/sftptransfer.cpp @@ -149,7 +149,7 @@ void SftpTransfer::doStart() break; case Internal::FileTransferType::Download: if (!QDir::root().mkdir(dir)) { - emitError(tr("Failed to create local directory \"%1\"") + emitError(tr("Failed to create local directory \"%1\".") .arg(QDir::toNativeSeparators(dir))); return; } From 1825a05f5896ffce64e0c945e000a743f35db846 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Fri, 1 Mar 2019 17:07:54 +0100 Subject: [PATCH 11/27] Bin editor: Fix UI text Change-Id: Id32a861c832360f8e559947da5911ed91820c7d0 Reviewed-by: hjk --- src/plugins/bineditor/bineditorwidget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/bineditor/bineditorwidget.cpp b/src/plugins/bineditor/bineditorwidget.cpp index b27fc5de78b..89ab6f634b5 100644 --- a/src/plugins/bineditor/bineditorwidget.cpp +++ b/src/plugins/bineditor/bineditorwidget.cpp @@ -1625,7 +1625,7 @@ void BinEditorWidget::contextMenuEvent(QContextMenuEvent *event) } else { jumpToBeAddressHereAction->setText(tr("Jump to Address in This Window")); jumpToBeAddressNewWindowAction->setText(tr("Jump to Address in New Window")); - copyBeValue->setText(tr("Copy value")); + copyBeValue->setText(tr("Copy Value")); jumpToBeAddressHereAction->setEnabled(false); jumpToBeAddressNewWindowAction->setEnabled(false); copyBeValue->setEnabled(false); From 031a82cd7148011ec963e6f471c413646a22e962 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Fri, 1 Mar 2019 17:10:38 +0100 Subject: [PATCH 12/27] Android: Fix UI text Change-Id: I918ded69e64ec3f91d7deeda086d36c6b73fdf8d Reviewed-by: Vikas Pachdha --- src/plugins/android/androidrunnerworker.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/plugins/android/androidrunnerworker.cpp b/src/plugins/android/androidrunnerworker.cpp index 6497f50d627..aed4e60d7ef 100644 --- a/src/plugins/android/androidrunnerworker.cpp +++ b/src/plugins/android/androidrunnerworker.cpp @@ -461,7 +461,7 @@ void AndroidRunnerWorker::asyncStartHelper() if (!m_gdbserverPath.isEmpty() && uploadGdbServer()) { gdbServerPrefix = "./"; } else { - emit remoteProcessFinished(tr("Cannot find/copy C++ debug server.")); + emit remoteProcessFinished(tr("Cannot find or copy C++ debug server.")); return; } } else { @@ -517,7 +517,7 @@ void AndroidRunnerWorker::asyncStartHelper() } if (!runAdb(args)) { - emit remoteProcessFinished(tr("Failed to start the activity")); + emit remoteProcessFinished(tr("Failed to start the activity.")); return; } } @@ -584,7 +584,7 @@ void AndroidRunnerWorker::handleJdbWaiting() runAdb(removeForward); if (!runAdb({"forward", "tcp:" + m_localJdbServerPort.toString(), "jdwp:" + QString::number(m_processPID)})) { - emit remoteProcessFinished(tr("Failed to forward jdb debugging ports.")); + emit remoteProcessFinished(tr("Failed to forward JDB debugging ports.")); return; } m_afterFinishAdbCommands.push_back(removeForward.join(' ')); @@ -603,7 +603,7 @@ void AndroidRunnerWorker::handleJdbWaiting() jdbProcess->setProcessChannelMode(QProcess::MergedChannels); jdbProcess->start(jdbPath.toString(), jdbArgs); if (!jdbProcess->waitForStarted()) { - emit remoteProcessFinished(tr("Failed to start jdb.")); + emit remoteProcessFinished(tr("Failed to start JDB.")); return; } m_jdbProcess = std::move(jdbProcess); @@ -643,7 +643,7 @@ void AndroidRunnerWorker::handleJdbSettled() } } } - emit remoteProcessFinished(tr("Cannot attach jdb to the running application")); + emit remoteProcessFinished(tr("Cannot attach JDB to the running application.")); } void AndroidRunnerWorker::onProcessIdChanged(qint64 pid) From 2a7a4f08a32c537c6af758edced2aa19a5ef1b04 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Fri, 1 Mar 2019 16:45:51 +0100 Subject: [PATCH 13/27] Clang: Fix UI text Change-Id: I395aa4311aca8f880a9181e639dddebb306566fb Reviewed-by: Ivan Donchevskii --- src/plugins/clangtools/clangtoolsdiagnosticmodel.cpp | 2 +- src/plugins/cpptools/clangdiagnosticconfigsmodel.cpp | 2 +- src/plugins/cpptools/clazychecks.ui | 2 +- src/plugins/projectexplorer/gcctoolchain.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/plugins/clangtools/clangtoolsdiagnosticmodel.cpp b/src/plugins/clangtools/clangtoolsdiagnosticmodel.cpp index c52f670e703..ea6ec38fa38 100644 --- a/src/plugins/clangtools/clangtoolsdiagnosticmodel.cpp +++ b/src/plugins/clangtools/clangtoolsdiagnosticmodel.cpp @@ -245,7 +245,7 @@ static QString createDiagnosticToolTipString(const Diagnostic &diagnostic, Fixit createFullLocationString(diagnostic.location)); lines << qMakePair( - QCoreApplication::translate("ClangTools::Diagnostic", "Fixit Status:"), + QCoreApplication::translate("ClangTools::Diagnostic", "Fixit status:"), fixitStatus(fixItStatus)); QString html = QLatin1String("" diff --git a/src/plugins/cpptools/clangdiagnosticconfigsmodel.cpp b/src/plugins/cpptools/clangdiagnosticconfigsmodel.cpp index 777dd27ca26..236bcfde202 100644 --- a/src/plugins/cpptools/clangdiagnosticconfigsmodel.cpp +++ b/src/plugins/cpptools/clangdiagnosticconfigsmodel.cpp @@ -167,7 +167,7 @@ static void addConfigForBuildSystem(ClangDiagnosticConfigsModel &model) ClangDiagnosticConfig config; config.setId("Builtin.BuildSystem"); config.setDisplayName(QCoreApplication::translate("ClangDiagnosticConfigsModel", - "Build-systems' warnings")); + "Build-system warnings")); config.setIsReadOnly(true); config.setUseBuildSystemWarnings(true); diff --git a/src/plugins/cpptools/clazychecks.ui b/src/plugins/cpptools/clazychecks.ui index 34d9aaf0c80..3abdd85aed7 100644 --- a/src/plugins/cpptools/clazychecks.ui +++ b/src/plugins/cpptools/clazychecks.ui @@ -23,7 +23,7 @@ - See <a href="https://github.com/KDE/clazy">clazy's homepage</a> for more information. + See <a href="https://github.com/KDE/clazy">Clazy's homepage</a> for more information. true diff --git a/src/plugins/projectexplorer/gcctoolchain.cpp b/src/plugins/projectexplorer/gcctoolchain.cpp index 26763ed5d55..c9c28846f6a 100644 --- a/src/plugins/projectexplorer/gcctoolchain.cpp +++ b/src/plugins/projectexplorer/gcctoolchain.cpp @@ -1490,7 +1490,7 @@ ClangToolChainConfigWidget::ClangToolChainConfigWidget(ClangToolChain *tc) : m_parentToolchainCombo = new QComboBox(this); m_mainLayout->insertRow(m_mainLayout->rowCount() - 1, - tr("Parent Toolchain:"), + tr("Parent toolchain:"), m_parentToolchainCombo); ToolChainManager *tcManager = ToolChainManager::instance(); From 473352940fddfe8e6ca93995615107a2bfa84a06 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Fri, 1 Mar 2019 17:14:20 +0100 Subject: [PATCH 14/27] QNX: Fix UI text Change-Id: Idb059a21bd85bb55b0d0596e024472e6fa3cfd36 Reviewed-by: hjk Reviewed-by: James McDonnell Reviewed-by: Christian Kandeler --- src/plugins/qnx/qnxdevicetester.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/qnx/qnxdevicetester.cpp b/src/plugins/qnx/qnxdevicetester.cpp index a710210ce3b..b1374519d8a 100644 --- a/src/plugins/qnx/qnxdevicetester.cpp +++ b/src/plugins/qnx/qnxdevicetester.cpp @@ -130,7 +130,7 @@ void QnxDeviceTester::handleVarRunProcessFinished(const QString &error) m_result = TestFailure; } } else { - emit errorMessage(tr("An error occurred checking that" + emit errorMessage(tr("An error occurred while checking that" " files can be created in /var/run.") + QLatin1Char('\n')); m_result = TestFailure; @@ -162,7 +162,7 @@ void QnxDeviceTester::handleProcessFinished(const QString &error) m_result = TestFailure; } } else { - emit errorMessage(tr("An error occurred checking for %1.").arg(command) + QLatin1Char('\n')); + emit errorMessage(tr("An error occurred while checking for %1.").arg(command) + QLatin1Char('\n')); m_result = TestFailure; } testNextCommand(); From 51e24f5ad4fda308f6d6875969318ccf7158bffa Mon Sep 17 00:00:00 2001 From: David Schulz Date: Thu, 21 Feb 2019 13:25:17 +0100 Subject: [PATCH 15/27] TextEditor: Hide controls in scheme editor for builtin schemes Show a label instead with a link that copies the current color scheme. Fixes: QTCREATORBUG-21874 Change-Id: I74083bac8d7124341b4b63d8e172172235c5e184 Reviewed-by: Leena Miettinen Reviewed-by: Eike Ziller --- src/plugins/texteditor/colorschemeedit.cpp | 48 +- src/plugins/texteditor/colorschemeedit.h | 3 + src/plugins/texteditor/colorschemeedit.ui | 790 ++++++++++---------- src/plugins/texteditor/fontsettingspage.cpp | 2 + 4 files changed, 422 insertions(+), 421 deletions(-) diff --git a/src/plugins/texteditor/colorschemeedit.cpp b/src/plugins/texteditor/colorschemeedit.cpp index 5f999835c53..76fcf7b29b7 100644 --- a/src/plugins/texteditor/colorschemeedit.cpp +++ b/src/plugins/texteditor/colorschemeedit.cpp @@ -155,6 +155,7 @@ ColorSchemeEdit::ColorSchemeEdit(QWidget *parent) : m_ui->detailsScrollArea->viewport()->setAutoFillBackground(false); m_ui->scrollAreaWidgetContents->setAutoFillBackground(false); m_ui->itemList->setModel(m_formatsModel); + m_ui->builtinSchemeLabel->setVisible(m_readOnly); populateUnderlineStyleComboBox(); @@ -186,6 +187,7 @@ ColorSchemeEdit::ColorSchemeEdit(QWidget *parent) : this, &ColorSchemeEdit::eraseUnderlineColor); connect(m_ui->underlineComboBox, static_cast(&QComboBox::currentIndexChanged), this, &ColorSchemeEdit::changeUnderlineStyle); + connect(m_ui->builtinSchemeLabel, &QLabel::linkActivated, this, &ColorSchemeEdit::copyScheme); } ColorSchemeEdit::~ColorSchemeEdit() @@ -214,31 +216,9 @@ void ColorSchemeEdit::setReadOnly(bool readOnly) m_readOnly = readOnly; - const bool enabled = !readOnly; - m_ui->foregroundLabel->setEnabled(enabled); - m_ui->foregroundToolButton->setEnabled(enabled); - m_ui->backgroundLabel->setEnabled(enabled); - m_ui->backgroundToolButton->setEnabled(enabled); - m_ui->eraseBackgroundToolButton->setEnabled(enabled); - m_ui->eraseForegroundToolButton->setEnabled(enabled); - m_ui->relativeForegroundHeadline->setEnabled(enabled); - m_ui->foregroundSaturationLabel->setEnabled(enabled); - m_ui->foregroundLightnessLabel->setEnabled(enabled); - m_ui->foregroundSaturationSpinBox->setEnabled(enabled); - m_ui->foregroundLightnessSpinBox->setEnabled(enabled); - m_ui->relativeBackgroundHeadline->setEnabled(enabled); - m_ui->backgroundSaturationLabel->setEnabled(enabled); - m_ui->backgroundLightnessLabel->setEnabled(enabled); - m_ui->backgroundSaturationSpinBox->setEnabled(enabled); - m_ui->backgroundLightnessSpinBox->setEnabled(enabled); - m_ui->fontHeadline->setEnabled(enabled); - m_ui->boldCheckBox->setEnabled(enabled); - m_ui->italicCheckBox->setEnabled(enabled); - m_ui->underlineHeadline->setEnabled(enabled); - m_ui->underlineLabel->setEnabled(enabled); - m_ui->underlineColorToolButton->setEnabled(enabled); - m_ui->eraseUnderlineColorToolButton->setEnabled(enabled); - m_ui->underlineComboBox->setEnabled(enabled); + m_ui->detailsScrollArea->setVisible(!readOnly); + m_ui->builtinSchemeLabel->setVisible(readOnly); + updateControls(); } void ColorSchemeEdit::setColorScheme(const ColorScheme &colorScheme) @@ -278,7 +258,8 @@ void ColorSchemeEdit::updateForegroundControls() const auto &formatDescription = m_descriptions[m_curItem]; const Format &format = m_scheme.formatFor(formatDescription.id()); - bool isVisible = formatDescription.showControl(FormatDescription::ShowForegroundControl); + bool isVisible = !m_readOnly + && formatDescription.showControl(FormatDescription::ShowForegroundControl); m_ui->relativeForegroundHeadline->setEnabled(isVisible); m_ui->foregroundLabel->setVisible(isVisible); @@ -297,7 +278,8 @@ void ColorSchemeEdit::updateBackgroundControls() const auto formatDescription = m_descriptions[m_curItem]; const Format &format = m_scheme.formatFor(formatDescription.id()); - bool isVisible = formatDescription.showControl(FormatDescription::ShowBackgroundControl); + bool isVisible = !m_readOnly + && formatDescription.showControl(FormatDescription::ShowBackgroundControl); m_ui->relativeBackgroundHeadline->setVisible(isVisible); m_ui->backgroundLabel->setVisible(isVisible); @@ -319,7 +301,8 @@ void ColorSchemeEdit::updateRelativeForegroundControls() QSignalBlocker saturationSignalBlocker(m_ui->foregroundSaturationSpinBox); QSignalBlocker lightnessSignalBlocker(m_ui->foregroundLightnessSpinBox); - bool isVisible = formatDescription.showControl(FormatDescription::ShowRelativeForegroundControl); + bool isVisible = !m_readOnly + && formatDescription.showControl(FormatDescription::ShowRelativeForegroundControl); m_ui->relativeForegroundHeadline->setVisible(isVisible); m_ui->foregroundSaturationLabel->setVisible(isVisible); @@ -350,7 +333,8 @@ void ColorSchemeEdit::updateRelativeBackgroundControls() QSignalBlocker saturationSignalBlocker(m_ui->backgroundSaturationSpinBox); QSignalBlocker lightnessSignalBlocker(m_ui->backgroundLightnessSpinBox); - bool isVisible = formatDescription.showControl(FormatDescription::ShowRelativeBackgroundControl); + bool isVisible = !m_readOnly + && formatDescription.showControl(FormatDescription::ShowRelativeBackgroundControl); m_ui->relativeBackgroundHeadline->setVisible(isVisible); m_ui->backgroundSaturationLabel->setVisible(isVisible); @@ -381,7 +365,8 @@ void ColorSchemeEdit::updateFontControls() QSignalBlocker boldSignalBlocker(m_ui->boldCheckBox); QSignalBlocker italicSignalBlocker(m_ui->italicCheckBox); - bool isVisible= formatDescription.showControl(FormatDescription::ShowFontControls); + bool isVisible = !m_readOnly + && formatDescription.showControl(FormatDescription::ShowFontControls); m_ui->fontHeadline->setVisible(isVisible); m_ui->boldCheckBox->setVisible(isVisible); @@ -401,7 +386,8 @@ void ColorSchemeEdit::updateUnderlineControls() QSignalBlocker comboBoxSignalBlocker(m_ui->underlineComboBox); - bool isVisible= formatDescription.showControl(FormatDescription::ShowUnderlineControl); + bool isVisible = !m_readOnly + && formatDescription.showControl(FormatDescription::ShowUnderlineControl); m_ui->underlineHeadline->setVisible(isVisible); m_ui->underlineLabel->setVisible(isVisible); diff --git a/src/plugins/texteditor/colorschemeedit.h b/src/plugins/texteditor/colorschemeedit.h index 6a1356609bf..f7504c170f8 100644 --- a/src/plugins/texteditor/colorschemeedit.h +++ b/src/plugins/texteditor/colorschemeedit.h @@ -59,6 +59,9 @@ public: void setColorScheme(const ColorScheme &colorScheme); const ColorScheme &colorScheme() const; +signals: + void copyScheme(); + private: void currentItemChanged(const QModelIndex &index); void changeForeColor(); diff --git a/src/plugins/texteditor/colorschemeedit.ui b/src/plugins/texteditor/colorschemeedit.ui index e9bb34596ba..ded11ef21f0 100644 --- a/src/plugins/texteditor/colorschemeedit.ui +++ b/src/plugins/texteditor/colorschemeedit.ui @@ -6,7 +6,7 @@ 0 0 - 462 + 513 416 @@ -39,6 +39,16 @@ + + + + <p align='center'><b>Builtin color schemes need to be <a href="copy">copied</a><br/> before they can be changed</b></p> + + + false + + + @@ -87,36 +97,68 @@ 0 - - - - - 75 - true - + + + + Qt::Vertical - - Relative Foreground + + + 200 + 0 + + + + + + + + + 0 + 0 + + + + + 0 + 6 + + + + + 16777215 + 6 + - - + + - + 0 0 - Foreground: - - - foregroundToolButton + - + + + + + 0 + 0 + + + + Lightness: + + + + @@ -138,251 +180,7 @@ - - - - - 0 - 0 - - - - Lightness: - - - - - - - - 0 - 0 - - - - - - - - - - - Qt::Vertical - - - - 200 - 0 - - - - - - - - - 0 - 0 - - - - Erase background. - - - x - - - Qt::LeftArrow - - - - - - - - 0 - 0 - - - - - 0 - 6 - - - - - 16777215 - 6 - - - - - - - - -1.000000000000000 - - - 1.000000000000000 - - - 0.050000000000000 - - - - - - - - 0 - 0 - - - - Lightness: - - - - - - - - 0 - 0 - - - - Erase foreground. - - - x - - - Qt::LeftArrow - - - - - - - - 0 - 0 - - - - Saturation: - - - - - - - Italic - - - - - - - -1.000000000000000 - - - 1.000000000000000 - - - 0.050000000000000 - - - - - - - - 0 - 0 - - - - - 0 - 6 - - - - - 16777215 - 6 - - - - - - - - -1.000000000000000 - - - 1.000000000000000 - - - 0.050000000000000 - - - - - - - - 0 - 0 - - - - Background: - - - backgroundToolButton - - - - - - - - 0 - 0 - - - - - 0 - 18 - - - - - 16777215 - 18 - - - - - - - - - 75 - true - - - - Font - - - - + @@ -395,14 +193,7 @@ - - - - Bold - - - - + @@ -424,73 +215,7 @@ - - - - - 0 - 0 - - - - - 0 - 6 - - - - - 16777215 - 6 - - - - - - - - - 0 - 0 - - - - - 0 - 18 - - - - - 16777215 - 18 - - - - - - - - - 0 - 0 - - - - - 0 - 6 - - - - - 16777215 - 6 - - - - - + @@ -512,20 +237,23 @@ - - + + - + 0 0 - + Foreground: + + + foregroundToolButton - + @@ -538,23 +266,122 @@ - - + + + + + 75 + true + + + + Relative Foreground + + + + + - + + 0 + 0 + + + + + 0 + 6 + + + + + 16777215 + 6 + + + + + + + + -1.000000000000000 + + + 1.000000000000000 + + + 0.050000000000000 + + + + + + + + 0 + 0 + + + + Erase background. + + + x + + + Qt::LeftArrow + + + + + + + + 0 + 0 + + + + + 0 + 6 + + + + + 16777215 + 6 + + + + + + + + 0 0 - Color: - - - backgroundToolButton + - + + + + + 0 + 0 + + + + Lightness: + + + + @@ -567,7 +394,173 @@ - + + + + + 75 + true + + + + Font + + + + + + + + 0 + 0 + + + + Saturation: + + + + + + + -1.000000000000000 + + + 1.000000000000000 + + + 0.050000000000000 + + + + + + + + 0 + 0 + + + + Erase background. + + + x + + + Qt::LeftArrow + + + + + + + + + + + 0 + 0 + + + + Erase foreground. + + + x + + + Qt::LeftArrow + + + + + + + + 0 + 0 + + + + + 0 + 6 + + + + + 16777215 + 6 + + + + + + + + Bold + + + + + + + + 0 + 0 + + + + + 0 + 18 + + + + + 16777215 + 18 + + + + + + + + + 0 + 0 + + + + + + + + + + + + 0 + 0 + + + + + 0 + 6 + + + + + 16777215 + 6 + + + + + @@ -589,8 +582,8 @@ - - + + -1.000000000000000 @@ -602,42 +595,20 @@ - - - - - 0 - 0 - + + + + -1.000000000000000 - - + + 1.000000000000000 + + + 0.050000000000000 - - - - - 0 - 0 - - - - Erase background. - - - x - - - Qt::LeftArrow - - - - - - - + @@ -659,8 +630,47 @@ - - + + + + + 0 + 0 + + + + Color: + + + backgroundToolButton + + + + + + + + 0 + 0 + + + + Background: + + + backgroundToolButton + + + + + + + Italic + + + + + 0 @@ -670,13 +680,13 @@ 0 - 6 + 18 16777215 - 6 + 18 diff --git a/src/plugins/texteditor/fontsettingspage.cpp b/src/plugins/texteditor/fontsettingspage.cpp index 1a6235789e2..36ee3ac6c6d 100644 --- a/src/plugins/texteditor/fontsettingspage.cpp +++ b/src/plugins/texteditor/fontsettingspage.cpp @@ -377,6 +377,8 @@ QWidget *FontSettingsPage::widget() this, &FontSettingsPage::colorSchemeSelected); connect(d_ptr->m_ui->copyButton, &QPushButton::clicked, this, &FontSettingsPage::openCopyColorSchemeDialog); + connect(d_ptr->m_ui->schemeEdit, &ColorSchemeEdit::copyScheme, + this, &FontSettingsPage::openCopyColorSchemeDialog); connect(d_ptr->m_ui->deleteButton, &QPushButton::clicked, this, &FontSettingsPage::confirmDeleteColorScheme); From 10a04ce40d294cbca03d2aef46318324bc8ba05c Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Tue, 26 Feb 2019 07:20:05 +0100 Subject: [PATCH 16/27] AutoTest: Fix updating of parent Amends d886285ff0f9. Fixes: QTCREATORBUG-22028 Change-Id: Ief97520a7db9bc90ed43a0b463008fc57ced0cea Reviewed-by: David Schulz --- src/plugins/autotest/testresultmodel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/autotest/testresultmodel.cpp b/src/plugins/autotest/testresultmodel.cpp index 99e1ee15ac2..46561c5d3f1 100644 --- a/src/plugins/autotest/testresultmodel.cpp +++ b/src/plugins/autotest/testresultmodel.cpp @@ -121,7 +121,7 @@ void TestResultItem::updateResult(bool &changed, Result::Type addedChildType) if (!TestResult::isMessageCaseStart(old)) return; - Result::Type newResult = Result::MessageTestCaseSuccess; + Result::Type newResult = old; switch (addedChildType) { case Result::Fail: case Result::MessageFatal: From c6b6a6a0773275a7c1b803bef62dc37dc5fe010e Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Mon, 4 Mar 2019 10:36:25 +0100 Subject: [PATCH 17/27] Preserve non-breaking space on saving text files Use toRawText instead of toPlainText, see QTBUG-56538. Fixes: QTCREATORBUG-22052 Change-Id: I01eaa57d2d1afed12e45ee88568667b161fd89fd Reviewed-by: David Schulz --- src/plugins/clangtools/clangfixitsrefactoringchanges.cpp | 2 +- .../projectexplorer/jsonwizard/jsonwizardgeneratorfactory.cpp | 2 +- src/plugins/projectexplorer/projectfilewizardextension.cpp | 2 +- src/plugins/texteditor/refactoringchanges.cpp | 4 ++-- src/plugins/texteditor/textdocument.cpp | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/plugins/clangtools/clangfixitsrefactoringchanges.cpp b/src/plugins/clangtools/clangfixitsrefactoringchanges.cpp index c3b6f4ac3ef..f2493b10cac 100644 --- a/src/plugins/clangtools/clangfixitsrefactoringchanges.cpp +++ b/src/plugins/clangtools/clangfixitsrefactoringchanges.cpp @@ -126,7 +126,7 @@ bool FixitsRefactoringFile::apply() QString error; for (auto it = m_documents.begin(); it != m_documents.end(); ++it) { - if (!m_textFileFormat.writeFile(it.key(), it.value()->toPlainText(), &error)) { + if (!m_textFileFormat.writeFile(it.key(), it.value()->toRawText(), &error)) { qCDebug(fixitsLog) << "ERROR: Could not write file" << it.key() << ":" << error; return false; // Error writing file } diff --git a/src/plugins/projectexplorer/jsonwizard/jsonwizardgeneratorfactory.cpp b/src/plugins/projectexplorer/jsonwizard/jsonwizardgeneratorfactory.cpp index e0a06c824e5..80ee8ffeedd 100644 --- a/src/plugins/projectexplorer/jsonwizard/jsonwizardgeneratorfactory.cpp +++ b/src/plugins/projectexplorer/jsonwizard/jsonwizardgeneratorfactory.cpp @@ -117,7 +117,7 @@ bool JsonWizardGenerator::formatFile(const JsonWizard *wizard, GeneratedFile *fi block = block.next(); } } - file->setContents(doc.toPlainText()); + file->setContents(doc.toRawText()); return true; } diff --git a/src/plugins/projectexplorer/projectfilewizardextension.cpp b/src/plugins/projectexplorer/projectfilewizardextension.cpp index 5dab7bbf997..6f44a829bf3 100644 --- a/src/plugins/projectexplorer/projectfilewizardextension.cpp +++ b/src/plugins/projectexplorer/projectfilewizardextension.cpp @@ -277,7 +277,7 @@ void ProjectFileWizardExtension::applyCodeStyle(GeneratedFile *file) const block = block.next(); } } - file->setContents(doc.toPlainText()); + file->setContents(doc.toRawText()); } } // namespace Internal diff --git a/src/plugins/texteditor/refactoringchanges.cpp b/src/plugins/texteditor/refactoringchanges.cpp index 1d43972e68d..ad4bc44243f 100644 --- a/src/plugins/texteditor/refactoringchanges.cpp +++ b/src/plugins/texteditor/refactoringchanges.cpp @@ -97,7 +97,7 @@ bool RefactoringChanges::createFile(const QString &fileName, const QString &cont TextFileFormat format; format.codec = EditorManager::defaultTextCodec(); QString error; - bool saveOk = format.writeFile(fileName, document->toPlainText(), &error); + bool saveOk = format.writeFile(fileName, document->toRawText(), &error); delete document; if (!saveOk) return false; @@ -367,7 +367,7 @@ bool RefactoringFile::apply() QString error; // suppress "file has changed" warnings if the file is open in a read-only editor Core::FileChangeBlocker block(m_fileName); - if (!m_textFileFormat.writeFile(m_fileName, doc->toPlainText(), &error)) { + if (!m_textFileFormat.writeFile(m_fileName, doc->toRawText(), &error)) { qWarning() << "Could not apply changes to" << m_fileName << ". Error: " << error; result = false; } diff --git a/src/plugins/texteditor/textdocument.cpp b/src/plugins/texteditor/textdocument.cpp index 2bfb51439a1..bfd709d5fef 100644 --- a/src/plugins/texteditor/textdocument.cpp +++ b/src/plugins/texteditor/textdocument.cpp @@ -569,7 +569,7 @@ bool TextDocument::save(QString *errorString, const QString &saveFileName, bool } } - const bool ok = write(fName, saveFormat, d->m_document.toPlainText(), errorString); + const bool ok = write(fName, saveFormat, d->m_document.toRawText(), errorString); // restore text cursor and scroll bar positions if (autoSave && undos < d->m_document.availableUndoSteps()) { From 6aed8223a9285d2488ad9bd74e1adeb02469de39 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Mon, 4 Mar 2019 09:12:20 +0100 Subject: [PATCH 18/27] SyntaxHighlighter: Update to latest master Adapt the respective include inside the TextEditor. Change-Id: Ie3cb17f1b0e3c0639840bc135156edd354a0aeda Reviewed-by: David Schulz --- .../autogenerated/src/lib/DefinitionDownloader | 1 + src/libs/3rdparty/syntax-highlighting/syntax-highlighting.qbs | 1 + src/plugins/texteditor/highlighter.cpp | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 src/libs/3rdparty/syntax-highlighting/autogenerated/src/lib/DefinitionDownloader diff --git a/src/libs/3rdparty/syntax-highlighting/autogenerated/src/lib/DefinitionDownloader b/src/libs/3rdparty/syntax-highlighting/autogenerated/src/lib/DefinitionDownloader new file mode 100644 index 00000000000..2a82740d19b --- /dev/null +++ b/src/libs/3rdparty/syntax-highlighting/autogenerated/src/lib/DefinitionDownloader @@ -0,0 +1 @@ +#include "definitiondownloader.h" diff --git a/src/libs/3rdparty/syntax-highlighting/syntax-highlighting.qbs b/src/libs/3rdparty/syntax-highlighting/syntax-highlighting.qbs index 248ebe0fd4f..526265220c2 100644 --- a/src/libs/3rdparty/syntax-highlighting/syntax-highlighting.qbs +++ b/src/libs/3rdparty/syntax-highlighting/syntax-highlighting.qbs @@ -16,6 +16,7 @@ Project { files: [ "AbstractHighlighter", "Definition", + "DefinitionDownloader", "FoldingRegion", "Format", "Repository", diff --git a/src/plugins/texteditor/highlighter.cpp b/src/plugins/texteditor/highlighter.cpp index b21af3644c8..4178dc7195f 100644 --- a/src/plugins/texteditor/highlighter.cpp +++ b/src/plugins/texteditor/highlighter.cpp @@ -25,7 +25,6 @@ #include "highlighter.h" -#include "definitiondownloader.h" #include "highlightersettings.h" #include "textdocumentlayout.h" #include "texteditorsettings.h" @@ -34,6 +33,7 @@ #include #include +#include #include #include #include From 3824fcbe2808649ed0726cd5f578c2fb0495b25d Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Mon, 25 Feb 2019 14:05:46 +0100 Subject: [PATCH 19/27] Doc: Describe selecting base environment for running external tools Change-Id: I3f63f23fae8730e8bcff063d52ac96e6592547a6 Reviewed-by: Eike Ziller --- doc/images/qtcreator-external-tools.png | Bin 17035 -> 52038 bytes .../creator-only/creator-external-tools.qdoc | 18 ++++++++++++------ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/doc/images/qtcreator-external-tools.png b/doc/images/qtcreator-external-tools.png index fbcdb1086e624fd138281e20449a4c6cd21f6971..8caa35a2371ba9e9ee28036c29e729c13e7008e4 100644 GIT binary patch literal 52038 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 KpUXO@geCy%pqwTE diff --git a/doc/src/howto/creator-only/creator-external-tools.qdoc b/doc/src/howto/creator-only/creator-external-tools.qdoc index b7f911dcd9a..a5038a65918 100644 --- a/doc/src/howto/creator-only/creator-external-tools.qdoc +++ b/doc/src/howto/creator-only/creator-external-tools.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2018 The Qt Company Ltd. +** Copyright (C) 2019 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Creator documentation. @@ -53,13 +53,12 @@ translation files for use by the released application. To synchronize translation source (TS) files from a translator with the - application code, - select \uicontrol {Tools > External > Text > Linguist > Update Translations - (lupdate)}. + application code, select \uicontrol Tools > \uicontrol External > + \uicontrol Linguist > \uicontrol {Update Translations (lupdate)}. To generate from the TS files Qt message (QM) files that can be used by an - application, select \uicontrol {Tools > External > Text > Linguist > Release - Translations (lrelease)}. + application, select \uicontrol Tools > \uicontrol External > + \uicontrol Linguist > \uicontrol {Release Translations (lrelease)}. By default, the project .pro file is passed to the tools as an argument. To specify other command line arguments for the tools, select \uicontrol {Tools > @@ -127,6 +126,13 @@ \li In the \uicontrol {Error output} field, select how to handle error messages from the tool. + \li In the \uicontrol {Base environment} field, select whether to run + the tool in the system environment or the \l{Build Environment} + {build environment} or \l {Selecting the Run Environment} + {run environment} of the active project. Select the build or run + environment if the system environment does not contain the necessary + PATH settings to find the tool chain, for example. + \li In the \uicontrol Environment field, select \uicontrol Change to modify environment variable values for build and run environments in the \uicontrol {Edit Environment Changes} dialog. For more information From 211aef94e6ca38df921010c06995c7b7dd4785b1 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Fri, 22 Feb 2019 11:37:30 +0100 Subject: [PATCH 20/27] Clang: Share executeInLoop Change-Id: Id02902e1e7abdb8b3430e7b228547c4372a424ce Reviewed-by: Ivan Donchevskii --- src/libs/clangsupport/clangsupport-lib.pri | 1 + src/libs/clangsupport/executeinloop.h | 72 +++++++++++++++++++ .../clangpchmanagerbackendmain.cpp | 43 +---------- .../source/taskscheduler.h | 42 +---------- .../clangrefactoringbackendmain.cpp | 43 +---------- 5 files changed, 76 insertions(+), 125 deletions(-) create mode 100644 src/libs/clangsupport/executeinloop.h diff --git a/src/libs/clangsupport/clangsupport-lib.pri b/src/libs/clangsupport/clangsupport-lib.pri index 221ccfd001e..7ab8e47ac78 100644 --- a/src/libs/clangsupport/clangsupport-lib.pri +++ b/src/libs/clangsupport/clangsupport-lib.pri @@ -108,6 +108,7 @@ HEADERS += \ $$PWD/clangrefactoringservermessages.h \ $$PWD/alivemessage.h \ $$PWD/completionsmessage.h \ + $$PWD/executeinloop.h \ $$PWD/requestcompletionsmessage.h \ $$PWD/echomessage.h \ $$PWD/endmessage.h \ diff --git a/src/libs/clangsupport/executeinloop.h b/src/libs/clangsupport/executeinloop.h new file mode 100644 index 00000000000..9c3eddeb4d1 --- /dev/null +++ b/src/libs/clangsupport/executeinloop.h @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include +#include +#include + +#if QT_VERSION < QT_VERSION_CHECK(5, 10, 0) +template +class CallableEvent : public QEvent +{ +public: + using Callable = std::decay_t; + CallableEvent(Callable &&callable) + : QEvent(QEvent::None) + , callable(std::move(callable)) + {} + CallableEvent(const Callable &callable) + : QEvent(QEvent::None) + , callable(callable) + {} + + ~CallableEvent() { callable(); } + +public: + Callable callable; +}; + +template +void executeInLoop(Callable &&callable, QObject *object = QCoreApplication::instance()) +{ + if (QThread *thread = qobject_cast(object)) + object = QAbstractEventDispatcher::instance(thread); + + QCoreApplication::postEvent(object, + new CallableEvent(std::forward(callable)), + Qt::HighEventPriority); +} +#else +template +void executeInLoop(Callable &&callable, QObject *object = QCoreApplication::instance()) +{ + if (QThread *thread = qobject_cast(object)) + object = QAbstractEventDispatcher::instance(thread); + + QMetaObject::invokeMethod(object, std::forward(callable)); +} +#endif diff --git a/src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp b/src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp index 17af1a2bc31..89567b8d386 100644 --- a/src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp +++ b/src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -72,48 +73,6 @@ using ClangBackEnd::FilePathCache; using ClangBackEnd::FilePathView; using ClangBackEnd::TimeStamp; -#if QT_VERSION < QT_VERSION_CHECK(5, 10, 0) -template -class CallableEvent : public QEvent -{ -public: - using Callable = std::decay_t; - CallableEvent(Callable &&callable) - : QEvent(QEvent::None) - , callable(std::move(callable)) - {} - CallableEvent(const Callable &callable) - : QEvent(QEvent::None) - , callable(callable) - {} - - ~CallableEvent() { callable(); } - -public: - Callable callable; -}; - -template -void executeInLoop(Callable &&callable, QObject *object = QCoreApplication::instance()) -{ - if (QThread *thread = qobject_cast(object)) - object = QAbstractEventDispatcher::instance(thread); - - QCoreApplication::postEvent(object, - new CallableEvent(std::forward(callable)), - Qt::HighEventPriority); -} -#else -template -void executeInLoop(Callable &&callable, QObject *object = QCoreApplication::instance()) -{ - if (QThread *thread = qobject_cast(object)) - object = QAbstractEventDispatcher::instance(thread); - - QMetaObject::invokeMethod(object, std::forward(callable)); -} -#endif - class PchManagerApplication final : public QCoreApplication { public: diff --git a/src/tools/clangpchmanagerbackend/source/taskscheduler.h b/src/tools/clangpchmanagerbackend/source/taskscheduler.h index 37fdc744a84..31d82ed2c4d 100644 --- a/src/tools/clangpchmanagerbackend/source/taskscheduler.h +++ b/src/tools/clangpchmanagerbackend/source/taskscheduler.h @@ -30,6 +30,7 @@ #include "queueinterface.h" #include "progresscounter.h" +#include #include #include #include @@ -149,47 +150,6 @@ private: m_futures.erase(split, m_futures.end()); } - #if QT_VERSION < QT_VERSION_CHECK(5, 10, 0) - template - class CallableEvent : public QEvent { - public: - using Callable = std::decay_t; - CallableEvent(Callable &&callable) - : QEvent(QEvent::None), - callable(std::move(callable)) - {} - CallableEvent(const Callable &callable) - : QEvent(QEvent::None), - callable(callable) - {} - - ~CallableEvent() - { - callable(); - } - public: - Callable callable; - }; - - template - void executeInLoop(Callable &&callable, QObject *object = QCoreApplication::instance()) { - if (QThread *thread = qobject_cast(object)) - object = QAbstractEventDispatcher::instance(thread); - - QCoreApplication::postEvent(object, - new CallableEvent(std::forward(callable)), - Qt::HighEventPriority); - } - #else - template - void executeInLoop(Callable &&callable, QObject *object = QCoreApplication::instance()) { - if (QThread *thread = qobject_cast(object)) - object = QAbstractEventDispatcher::instance(thread); - - QMetaObject::invokeMethod(object, std::forward(callable)); - } - #endif - private: std::vector m_futures; ProcessorManager &m_processorManager; diff --git a/src/tools/clangrefactoringbackend/clangrefactoringbackendmain.cpp b/src/tools/clangrefactoringbackend/clangrefactoringbackendmain.cpp index 876c047fb85..9579f760c9c 100644 --- a/src/tools/clangrefactoringbackend/clangrefactoringbackendmain.cpp +++ b/src/tools/clangrefactoringbackend/clangrefactoringbackendmain.cpp @@ -30,6 +30,7 @@ #include #include +#include #include #include #include @@ -51,48 +52,6 @@ using ClangBackEnd::RefactoringDatabaseInitializer; using ClangBackEnd::ConnectionServer; using ClangBackEnd::SymbolIndexing; -#if QT_VERSION < QT_VERSION_CHECK(5, 10, 0) -template -class CallableEvent : public QEvent -{ -public: - using Callable = std::decay_t; - CallableEvent(Callable &&callable) - : QEvent(QEvent::None) - , callable(std::move(callable)) - {} - CallableEvent(const Callable &callable) - : QEvent(QEvent::None) - , callable(callable) - {} - - ~CallableEvent() { callable(); } - -public: - Callable callable; -}; - -template -void executeInLoop(Callable &&callable, QObject *object = QCoreApplication::instance()) -{ - if (QThread *thread = qobject_cast(object)) - object = QAbstractEventDispatcher::instance(thread); - - QCoreApplication::postEvent(object, - new CallableEvent(std::forward(callable)), - Qt::HighEventPriority); -} -#else -template -void executeInLoop(Callable &&callable, QObject *object = QCoreApplication::instance()) -{ - if (QThread *thread = qobject_cast(object)) - object = QAbstractEventDispatcher::instance(thread); - - QMetaObject::invokeMethod(object, std::forward(callable)); -} -#endif - QStringList processArguments(QCoreApplication &application) { QCommandLineParser parser; From 2358415b58c67a4b11c8e749e2b2a5686254f5c6 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Fri, 22 Feb 2019 16:44:40 +0100 Subject: [PATCH 21/27] Clang: Move fetchPrecompiledHeader to PrecompiledHeaderStorage It went for historical reasons in the symbol storage. Change-Id: If05edb868901884f3951d0eb2f152566e99b4d1a Reviewed-by: Ivan Donchevskii --- .../source/precompiledheaderstorage.h | 8 +++++ .../precompiledheaderstorageinterface.h | 4 +++ .../source/symbolindexer.cpp | 25 +++++++------- .../source/symbolindexer.h | 5 ++- .../source/symbolindexing.h | 4 +++ .../source/symbolstorage.h | 9 ----- .../source/symbolstorageinterface.h | 2 -- .../unittest/mockprecompiledheaderstorage.h | 2 ++ tests/unit/unittest/mocksymbolstorage.h | 2 -- .../precompiledheaderstorage-test.cpp | 33 +++++++++++++------ tests/unit/unittest/symbolindexer-test.cpp | 31 +++++++++++------ tests/unit/unittest/symbolstorage-test.cpp | 19 ----------- 12 files changed, 80 insertions(+), 64 deletions(-) diff --git a/src/tools/clangpchmanagerbackend/source/precompiledheaderstorage.h b/src/tools/clangpchmanagerbackend/source/precompiledheaderstorage.h index 022f5d926bd..e2d53ee0a94 100644 --- a/src/tools/clangpchmanagerbackend/source/precompiledheaderstorage.h +++ b/src/tools/clangpchmanagerbackend/source/precompiledheaderstorage.h @@ -126,6 +126,11 @@ public: return FilePath(""); } + Utils::optional fetchPrecompiledHeader(int projectPartId) const + { + return m_getPrecompiledHeader.template value(projectPartId); + } + public: Sqlite::ImmediateNonThrowingDestructorTransaction m_transaction; Database &m_database; @@ -155,6 +160,9 @@ public: "SELECT systemPchPath FROM precompiledHeaders WHERE projectPartId = (SELECT projectPartId " "FROM projectParts WHERE projectPartName = ?)", m_database}; + mutable ReadStatement m_getPrecompiledHeader{"SELECT projectPchPath, projectPchBuildTime FROM " + "precompiledHeaders WHERE projectPartId = ?", + m_database}; }; } diff --git a/src/tools/clangpchmanagerbackend/source/precompiledheaderstorageinterface.h b/src/tools/clangpchmanagerbackend/source/precompiledheaderstorageinterface.h index 2a7e11604b2..06833be4a2b 100644 --- a/src/tools/clangpchmanagerbackend/source/precompiledheaderstorageinterface.h +++ b/src/tools/clangpchmanagerbackend/source/precompiledheaderstorageinterface.h @@ -25,9 +25,12 @@ #pragma once +#include "projectpartpch.h" + #include #include +#include namespace ClangBackEnd { @@ -50,6 +53,7 @@ public: = 0; virtual void deleteSystemPrecompiledHeaders(const Utils::SmallStringVector &projectPartNames) = 0; virtual FilePath fetchSystemPrecompiledHeaderPath(Utils::SmallStringView projectPartName) = 0; + virtual Utils::optional fetchPrecompiledHeader(int projectPartId) const = 0; protected: ~PrecompiledHeaderStorageInterface() = default; diff --git a/src/tools/clangrefactoringbackend/source/symbolindexer.cpp b/src/tools/clangrefactoringbackend/source/symbolindexer.cpp index 2b4e90cf5a4..6928e497125 100644 --- a/src/tools/clangrefactoringbackend/source/symbolindexer.cpp +++ b/src/tools/clangrefactoringbackend/source/symbolindexer.cpp @@ -60,18 +60,20 @@ private: SymbolIndexer::SymbolIndexer(SymbolIndexerTaskQueueInterface &symbolIndexerTaskQueue, SymbolStorageInterface &symbolStorage, - BuildDependenciesStorageInterface &usedMacroAndSourceStorage, + BuildDependenciesStorageInterface &buildDependenciesStorage, + PrecompiledHeaderStorageInterface &precompiledHeaderStorage, ClangPathWatcherInterface &pathWatcher, FilePathCachingInterface &filePathCache, FileStatusCache &fileStatusCache, Sqlite::TransactionInterface &transactionInterface) - : m_symbolIndexerTaskQueue(symbolIndexerTaskQueue), - m_symbolStorage(symbolStorage), - m_buildDependencyStorage(usedMacroAndSourceStorage), - m_pathWatcher(pathWatcher), - m_filePathCache(filePathCache), - m_fileStatusCache(fileStatusCache), - m_transactionInterface(transactionInterface) + : m_symbolIndexerTaskQueue(symbolIndexerTaskQueue) + , m_symbolStorage(symbolStorage) + , m_buildDependencyStorage(buildDependenciesStorage) + , m_precompiledHeaderStorage(precompiledHeaderStorage) + , m_pathWatcher(pathWatcher) + , m_filePathCache(filePathCache) + , m_fileStatusCache(fileStatusCache) + , m_transactionInterface(transactionInterface) { pathWatcher.setNotifier(this); } @@ -97,7 +99,8 @@ void SymbolIndexer::updateProjectPart(ProjectPartContainer &&projectPart) projectPart.languageExtension); if (optionalArtefact) projectPartId = optionalArtefact->projectPartId; - const Utils::optional optionalProjectPartPch = m_symbolStorage.fetchPrecompiledHeader(projectPartId); + const Utils::optional optionalProjectPartPch + = m_precompiledHeaderStorage.fetchPrecompiledHeader(projectPartId); FilePathIds sourcePathIds = updatableFilePathIds(projectPart, optionalArtefact); transaction.commit(); @@ -179,8 +182,8 @@ void SymbolIndexer::updateChangedPath(FilePathId filePathId, if (!optionalArtefact) return; - const Utils::optional optionalProjectPartPch = m_symbolStorage.fetchPrecompiledHeader( - optionalArtefact->projectPartId); + const Utils::optional optionalProjectPartPch + = m_precompiledHeaderStorage.fetchPrecompiledHeader(optionalArtefact->projectPartId); transaction.commit(); const ProjectPartArtefact &artefact = optionalArtefact.value(); diff --git a/src/tools/clangrefactoringbackend/source/symbolindexer.h b/src/tools/clangrefactoringbackend/source/symbolindexer.h index bee726abf42..33c691e4dd5 100644 --- a/src/tools/clangrefactoringbackend/source/symbolindexer.h +++ b/src/tools/clangrefactoringbackend/source/symbolindexer.h @@ -31,6 +31,7 @@ #include "builddependenciesstorageinterface.h" #include "clangpathwatcher.h" +#include #include #include @@ -43,7 +44,8 @@ class SymbolIndexer final : public ClangPathWatcherNotifier public: SymbolIndexer(SymbolIndexerTaskQueueInterface &symbolIndexerTaskQueue, SymbolStorageInterface &symbolStorage, - BuildDependenciesStorageInterface &usedMacroAndSourceStorage, + BuildDependenciesStorageInterface &buildDependenciesStorage, + PrecompiledHeaderStorageInterface &precompiledHeaderStorage, ClangPathWatcherInterface &pathWatcher, FilePathCachingInterface &filePathCache, FileStatusCache &fileStatusCache, @@ -71,6 +73,7 @@ private: SymbolIndexerTaskQueueInterface &m_symbolIndexerTaskQueue; SymbolStorageInterface &m_symbolStorage; BuildDependenciesStorageInterface &m_buildDependencyStorage; + PrecompiledHeaderStorageInterface &m_precompiledHeaderStorage; ClangPathWatcherInterface &m_pathWatcher; FilePathCachingInterface &m_filePathCache; FileStatusCache &m_fileStatusCache; diff --git a/src/tools/clangrefactoringbackend/source/symbolindexing.h b/src/tools/clangrefactoringbackend/source/symbolindexing.h index 62be193682c..5b8b2221f06 100644 --- a/src/tools/clangrefactoringbackend/source/symbolindexing.h +++ b/src/tools/clangrefactoringbackend/source/symbolindexing.h @@ -35,6 +35,7 @@ #include "symbolstorage.h" #include +#include #include #include @@ -83,6 +84,7 @@ public: ProgressCounter::SetProgressCallback &&setProgressCallback) : m_filePathCache(filePathCache) , m_buildDependencyStorage(database) + , m_recompiledHeaderStorage(database) , m_symbolStorage(database) , m_collectorManger(generatedFiles, database) , m_progressCounter(std::move(setProgressCallback)) @@ -119,6 +121,7 @@ private: using SymbolIndexerTaskScheduler = TaskScheduler; FilePathCachingInterface &m_filePathCache; BuildDependenciesStorage m_buildDependencyStorage; + PrecompiledHeaderStorage m_recompiledHeaderStorage; SymbolStorage m_symbolStorage; ClangPathWatcher m_sourceWatcher{m_filePathCache}; FileStatusCache m_fileStatusCache{m_filePathCache}; @@ -127,6 +130,7 @@ private: SymbolIndexer m_indexer{m_indexerQueue, m_symbolStorage, m_buildDependencyStorage, + m_recompiledHeaderStorage, m_sourceWatcher, m_filePathCache, m_fileStatusCache, diff --git a/src/tools/clangrefactoringbackend/source/symbolstorage.h b/src/tools/clangrefactoringbackend/source/symbolstorage.h index f1fdbc7c02e..3b7141c7838 100644 --- a/src/tools/clangrefactoringbackend/source/symbolstorage.h +++ b/src/tools/clangrefactoringbackend/source/symbolstorage.h @@ -223,11 +223,6 @@ public: m_deleteNewLocationsTableStatement.execute(); } - Utils::optional fetchPrecompiledHeader(int projectPartId) const - { - return m_getPrecompiledHeader.template value(projectPartId); - } - SourceLocationEntries sourceLocations() const { return SourceLocationEntries(); @@ -350,10 +345,6 @@ public: "projectIncludeSearchPaths, projectPartId, language, languageVersion, languageExtension " "FROM projectParts WHERE projectPartName = ?", m_database}; - mutable ReadStatement m_getPrecompiledHeader{ - "SELECT projectPchPath, projectPchBuildTime FROM precompiledHeaders WHERE projectPartId = ?", - m_database - }; }; } // namespace ClangBackEnd diff --git a/src/tools/clangrefactoringbackend/source/symbolstorageinterface.h b/src/tools/clangrefactoringbackend/source/symbolstorageinterface.h index c10c7fca48e..5f2e6c30e68 100644 --- a/src/tools/clangrefactoringbackend/source/symbolstorageinterface.h +++ b/src/tools/clangrefactoringbackend/source/symbolstorageinterface.h @@ -27,7 +27,6 @@ #include "filestatus.h" #include "projectpartentry.h" -#include "projectpartpch.h" #include "projectpartartefact.h" #include "sourcelocationentry.h" #include "sourcedependency.h" @@ -67,7 +66,6 @@ public: FilePathId sourceId) const = 0; virtual Utils::optional fetchProjectPartArtefact( Utils::SmallStringView projectPartName) const = 0; - virtual Utils::optional fetchPrecompiledHeader(int projectPartId) const = 0; protected: ~SymbolStorageInterface() = default; diff --git a/tests/unit/unittest/mockprecompiledheaderstorage.h b/tests/unit/unittest/mockprecompiledheaderstorage.h index a2bc0fddf0a..72eefcc1d1a 100644 --- a/tests/unit/unittest/mockprecompiledheaderstorage.h +++ b/tests/unit/unittest/mockprecompiledheaderstorage.h @@ -45,4 +45,6 @@ public: void(const Utils::SmallStringVector &projectPartNames)); MOCK_METHOD1(fetchSystemPrecompiledHeaderPath, ClangBackEnd::FilePath(Utils::SmallStringView projectPartName)); + MOCK_CONST_METHOD1(fetchPrecompiledHeader, + Utils::optional(int projectPartId)); }; diff --git a/tests/unit/unittest/mocksymbolstorage.h b/tests/unit/unittest/mocksymbolstorage.h index 0e4422012e7..325e18b1c97 100644 --- a/tests/unit/unittest/mocksymbolstorage.h +++ b/tests/unit/unittest/mocksymbolstorage.h @@ -53,6 +53,4 @@ public: Utils::optional (ClangBackEnd::FilePathId sourceId)); MOCK_CONST_METHOD1(fetchProjectPartArtefact, Utils::optional (Utils::SmallStringView projectPartName)); - MOCK_CONST_METHOD1(fetchPrecompiledHeader, - Utils::optional (int projectPartId)); }; diff --git a/tests/unit/unittest/precompiledheaderstorage-test.cpp b/tests/unit/unittest/precompiledheaderstorage-test.cpp index fb65aa7c809..22dffe3c29c 100644 --- a/tests/unit/unittest/precompiledheaderstorage-test.cpp +++ b/tests/unit/unittest/precompiledheaderstorage-test.cpp @@ -43,16 +43,12 @@ protected: NiceMock database; Storage storage{database}; MockSqliteWriteStatement &insertProjectPartStatement = storage.m_insertProjectPartStatement; - MockSqliteWriteStatement &insertProjectPrecompiledHeaderStatement - = storage.m_insertProjectPrecompiledHeaderStatement; - MockSqliteWriteStatement &deleteProjectPrecompiledHeaderStatement - = storage.m_deleteProjectPrecompiledHeaderStatement; - MockSqliteWriteStatement &insertSystemPrecompiledHeaderStatement - = storage.m_insertSystemPrecompiledHeaderStatement; - MockSqliteWriteStatement &deleteSystemPrecompiledHeaderStatement - = storage.m_deleteSystemPrecompiledHeaderStatement; - MockSqliteReadStatement &fetchSystemPrecompiledHeaderPathStatement - = storage.m_fetchSystemPrecompiledHeaderPathStatement; + MockSqliteWriteStatement &insertProjectPrecompiledHeaderStatement = storage.m_insertProjectPrecompiledHeaderStatement; + MockSqliteWriteStatement &deleteProjectPrecompiledHeaderStatement = storage.m_deleteProjectPrecompiledHeaderStatement; + MockSqliteWriteStatement &insertSystemPrecompiledHeaderStatement = storage.m_insertSystemPrecompiledHeaderStatement; + MockSqliteWriteStatement &deleteSystemPrecompiledHeaderStatement = storage.m_deleteSystemPrecompiledHeaderStatement; + MockSqliteReadStatement &fetchSystemPrecompiledHeaderPathStatement = storage.m_fetchSystemPrecompiledHeaderPathStatement; + MockSqliteReadStatement &getPrecompiledHeader = storage.m_getPrecompiledHeader; }; TEST_F(PrecompiledHeaderStorage, UseTransaction) @@ -241,4 +237,21 @@ TEST_F(PrecompiledHeaderStorage, FetchSystemPrecompiledHeaderReturnsNullOptional ASSERT_THAT(path, IsEmpty()); } + +TEST_F(PrecompiledHeaderStorage, FetchPrecompiledHeaderCallsValueInStatement) +{ + EXPECT_CALL(getPrecompiledHeader, valueReturnProjectPartPch(Eq(25))); + + storage.fetchPrecompiledHeader(25); +} + +TEST_F(PrecompiledHeaderStorage, FetchPrecompiledHeader) +{ + ClangBackEnd::ProjectPartPch pch{"", "/path/to/pch", 131}; + EXPECT_CALL(getPrecompiledHeader, valueReturnProjectPartPch(Eq(25))).WillRepeatedly(Return(pch)); + + auto precompiledHeader = storage.fetchPrecompiledHeader(25); + + ASSERT_THAT(precompiledHeader.value(), Eq(pch)); +} } diff --git a/tests/unit/unittest/symbolindexer-test.cpp b/tests/unit/unittest/symbolindexer-test.cpp index 0a7b6acba19..eecd388f024 100644 --- a/tests/unit/unittest/symbolindexer-test.cpp +++ b/tests/unit/unittest/symbolindexer-test.cpp @@ -26,6 +26,7 @@ #include "googletest.h" #include "filesystem-utilities.h" #include "mockclangpathwatcher.h" +#include "mockprecompiledheaderstorage.h" #include "mocksymbolscollector.h" #include "mocksymbolstorage.h" #include "mockfilepathcaching.h" @@ -237,6 +238,7 @@ protected: NiceMock mockSqliteTransactionBackend; NiceMock mockSymbolStorage; NiceMock mockBuildDependenciesStorage; + NiceMock mockPrecompiledHeaderStorage; NiceMock mockPathWatcher; ClangBackEnd::FileStatusCache fileStatusCache{filePathCache}; ClangBackEnd::GeneratedFiles generatedFiles; @@ -246,6 +248,7 @@ protected: ClangBackEnd::SymbolIndexer indexer{indexerQueue, mockSymbolStorage, mockBuildDependenciesStorage, + mockPrecompiledHeaderStorage, mockPathWatcher, filePathCache, fileStatusCache, @@ -292,7 +295,8 @@ TEST_F(SymbolIndexer, UpdateProjectPartsCallsAddFilesInCollector) TEST_F(SymbolIndexer, UpdateProjectPartsCallsAddFilesWithPrecompiledHeaderInCollector) { ON_CALL(mockSymbolStorage, fetchProjectPartArtefact(TypedEq(projectPart1.projectPartId))).WillByDefault(Return(emptyArtefact)); - ON_CALL(mockSymbolStorage, fetchPrecompiledHeader(Eq(artefact.projectPartId))).WillByDefault(Return(projectPartPch)); + ON_CALL(mockPrecompiledHeaderStorage, fetchPrecompiledHeader(Eq(artefact.projectPartId))) + .WillByDefault(Return(projectPartPch)); EXPECT_CALL(mockCollector, setFile(main1PathId, @@ -506,7 +510,7 @@ TEST_F(SymbolIndexer, UpdateProjectPartsCallsInOrderWithoutProjectPartArtifact) Eq(Utils::LanguageVersion::CXX14), Eq(Utils::LanguageExtension::None))) .WillOnce(Return(12)); - EXPECT_CALL(mockSymbolStorage, fetchPrecompiledHeader(Eq(12))); + EXPECT_CALL(mockPrecompiledHeaderStorage, fetchPrecompiledHeader(Eq(12))); EXPECT_CALL(mockBuildDependenciesStorage, fetchLowestLastModifiedTime(Eq(main1PathId))).Times(0); EXPECT_CALL(mockSqliteTransactionBackend, commit()); EXPECT_CALL(mockCollector, @@ -559,7 +563,7 @@ TEST_F(SymbolIndexer, UpdateProjectPartsCallsInOrderWithProjectPartArtifact) Eq(Utils::LanguageVersion::CXX14), Eq(Utils::LanguageExtension::None))) .WillOnce(Return(-1)); - EXPECT_CALL(mockSymbolStorage, fetchPrecompiledHeader(Eq(artefact.projectPartId))); + EXPECT_CALL(mockPrecompiledHeaderStorage, fetchPrecompiledHeader(Eq(artefact.projectPartId))); EXPECT_CALL(mockBuildDependenciesStorage, fetchLowestLastModifiedTime(Eq(main1PathId))).WillOnce(Return(-1)); EXPECT_CALL(mockSqliteTransactionBackend, commit()); EXPECT_CALL(mockCollector, @@ -614,7 +618,7 @@ TEST_F(SymbolIndexer, UpdateProjectPartsCallsInOrderButGetsAnErrorForCollectingS Eq(Utils::LanguageVersion::CXX14), Eq(Utils::LanguageExtension::None))) .WillOnce(Return(12)); - EXPECT_CALL(mockSymbolStorage, fetchPrecompiledHeader(Eq(12))); + EXPECT_CALL(mockPrecompiledHeaderStorage, fetchPrecompiledHeader(Eq(12))); EXPECT_CALL(mockBuildDependenciesStorage, fetchLowestLastModifiedTime(Eq(main1PathId))).Times(0); EXPECT_CALL(mockSqliteTransactionBackend, commit()); EXPECT_CALL(mockCollector, @@ -656,7 +660,14 @@ TEST_F(SymbolIndexer, CallSetNotifier) { EXPECT_CALL(mockPathWatcher, setNotifier(_)); - ClangBackEnd::SymbolIndexer indexer{indexerQueue, mockSymbolStorage, mockBuildDependenciesStorage, mockPathWatcher, filePathCache, fileStatusCache, mockSqliteTransactionBackend}; + ClangBackEnd::SymbolIndexer indexer{indexerQueue, + mockSymbolStorage, + mockBuildDependenciesStorage, + mockPrecompiledHeaderStorage, + mockPathWatcher, + filePathCache, + fileStatusCache, + mockSqliteTransactionBackend}; } TEST_F(SymbolIndexer, PathChangedCallsFetchProjectPartArtefactInStorage) @@ -673,7 +684,7 @@ TEST_F(SymbolIndexer, UpdateChangedPathCallsInOrder) EXPECT_CALL(mockSqliteTransactionBackend, deferredBegin()); EXPECT_CALL(mockSymbolStorage, fetchProjectPartArtefact(TypedEq(sourceFileIds[0]))).WillOnce(Return(artefact)); - EXPECT_CALL(mockSymbolStorage, fetchPrecompiledHeader(Eq(artefact.projectPartId))); + EXPECT_CALL(mockPrecompiledHeaderStorage, fetchPrecompiledHeader(Eq(artefact.projectPartId))); EXPECT_CALL(mockSqliteTransactionBackend, commit()); EXPECT_CALL(mockCollector, setFile(Eq(sourceFileIds[0]), @@ -715,7 +726,7 @@ TEST_F(SymbolIndexer, HandleEmptyOptionalArtifactInUpdateChangedPath) EXPECT_CALL(mockSqliteTransactionBackend, deferredBegin()); EXPECT_CALL(mockSymbolStorage, fetchProjectPartArtefact(sourceFileIds[0])).WillOnce(Return(nullArtefact)); - EXPECT_CALL(mockSymbolStorage, fetchPrecompiledHeader(_)).Times(0); + EXPECT_CALL(mockPrecompiledHeaderStorage, fetchPrecompiledHeader(_)).Times(0); EXPECT_CALL(mockSqliteTransactionBackend, commit()).Times(0); EXPECT_CALL(mockCollector, setFile(_, _)).Times(0); EXPECT_CALL(mockCollector, collectSymbols()).Times(0); @@ -737,7 +748,7 @@ TEST_F(SymbolIndexer, UpdateChangedPathCallsInOrderButGetsAnErrorForCollectingSy EXPECT_CALL(mockSqliteTransactionBackend, deferredBegin()); EXPECT_CALL(mockSymbolStorage, fetchProjectPartArtefact(TypedEq(sourceFileIds[0]))) .WillOnce(Return(artefact)); - EXPECT_CALL(mockSymbolStorage, fetchPrecompiledHeader(Eq(artefact.projectPartId))); + EXPECT_CALL(mockPrecompiledHeaderStorage, fetchPrecompiledHeader(Eq(artefact.projectPartId))); EXPECT_CALL(mockSqliteTransactionBackend, commit()); EXPECT_CALL(mockCollector, setFile(Eq(sourceFileIds[0]), @@ -779,8 +790,8 @@ TEST_F(SymbolIndexer, UpdateChangedPathIsUsingPrecompiledHeader) { ON_CALL(mockSymbolStorage, fetchProjectPartArtefact(TypedEq(sourceFileIds[0]))) .WillByDefault(Return(artefact)); - ON_CALL(mockSymbolStorage, fetchPrecompiledHeader(Eq(artefact.projectPartId))) - .WillByDefault(Return(projectPartPch)); + ON_CALL(mockPrecompiledHeaderStorage, fetchPrecompiledHeader(Eq(artefact.projectPartId))) + .WillByDefault(Return(projectPartPch)); std::vector symbolIndexerTask; EXPECT_CALL(mockCollector, diff --git a/tests/unit/unittest/symbolstorage-test.cpp b/tests/unit/unittest/symbolstorage-test.cpp index c960a028bc3..f9a3d0a7dee 100644 --- a/tests/unit/unittest/symbolstorage-test.cpp +++ b/tests/unit/unittest/symbolstorage-test.cpp @@ -74,7 +74,6 @@ protected: MockSqliteWriteStatement &insertProjectPartSourcesStatement = storage.m_insertProjectPartSourcesStatement; MockSqliteReadStatement &getProjectPartArtefactsBySourceId = storage.m_getProjectPartArtefactsBySourceId; MockSqliteReadStatement &getProjectPartArtefactsByProjectPartName = storage.m_getProjectPartArtefactsByProjectPartName; - MockSqliteReadStatement &getPrecompiledHeader = storage.m_getPrecompiledHeader; SymbolEntries symbolEntries{{1, {"functionUSR", "function", SymbolKind::Function}}, {2, {"function2USR", "function2", SymbolKind::Function}}}; @@ -261,24 +260,6 @@ TEST_F(SymbolStorage, FetchProjectPartArtefactByProjectNameReturnArtefact) ASSERT_THAT(result, Eq(artefact)); } -TEST_F(SymbolStorage, FetchPrecompiledHeaderCallsValueInStatement) -{ - EXPECT_CALL(getPrecompiledHeader, valueReturnProjectPartPch(Eq(25))); - - storage.fetchPrecompiledHeader(25); -} - -TEST_F(SymbolStorage, FetchPrecompiledHeader) -{ - ClangBackEnd::ProjectPartPch pch{"", "/path/to/pch", 131}; - EXPECT_CALL(getPrecompiledHeader, valueReturnProjectPartPch(Eq(25))) - .WillRepeatedly(Return(pch)); - - auto precompiledHeader = storage.fetchPrecompiledHeader(25); - - ASSERT_THAT(precompiledHeader.value(), Eq(pch)); -} - TEST_F(SymbolStorage, AddNewSymbolsTable) { InSequence s; From a7de90d0d56fe4b6529917dfa0be972a9983b52b Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Fri, 22 Feb 2019 18:23:39 +0100 Subject: [PATCH 22/27] Clang: Use system PCH if projectpart PCH does not exists Then entry can be empty or null, so we test for both. Task-number: QTCREATORBUG-21978 Change-Id: Ic824d897b3c38051a2304c9487ea5f2f7c9eeef8 Reviewed-by: Ivan Donchevskii --- .../source/precompiledheaderstorage.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/tools/clangpchmanagerbackend/source/precompiledheaderstorage.h b/src/tools/clangpchmanagerbackend/source/precompiledheaderstorage.h index e2d53ee0a94..7d1069b9988 100644 --- a/src/tools/clangpchmanagerbackend/source/precompiledheaderstorage.h +++ b/src/tools/clangpchmanagerbackend/source/precompiledheaderstorage.h @@ -160,9 +160,10 @@ public: "SELECT systemPchPath FROM precompiledHeaders WHERE projectPartId = (SELECT projectPartId " "FROM projectParts WHERE projectPartName = ?)", m_database}; - mutable ReadStatement m_getPrecompiledHeader{"SELECT projectPchPath, projectPchBuildTime FROM " - "precompiledHeaders WHERE projectPartId = ?", - m_database}; + mutable ReadStatement m_getPrecompiledHeader{ + "SELECT ifnull(nullif(projectPchPath, ''), systemPchPath), " + "projectPchBuildTime FROM precompiledHeaders WHERE projectPartId = ?", + m_database}; }; } From 75f74791a16eccd973eb84db08393ee931f4f7fd Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Mon, 25 Feb 2019 14:58:29 +0100 Subject: [PATCH 23/27] Sqlite: Use exclusive lock for table initialization We cannot change tables if other connections access the database. Change-Id: I1915ab491952d9684cb9839957c84c8f7a15c308 Reviewed-by: Ivan Donchevskii --- src/libs/sqlite/sqlitedatabase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/sqlite/sqlitedatabase.cpp b/src/libs/sqlite/sqlitedatabase.cpp index 1ddaf2cfbcb..ef5205484c6 100644 --- a/src/libs/sqlite/sqlitedatabase.cpp +++ b/src/libs/sqlite/sqlitedatabase.cpp @@ -164,7 +164,7 @@ void Database::execute(Utils::SmallStringView sqlStatement) void Database::initializeTables() { try { - ImmediateTransaction transaction(*this); + ExclusiveTransaction transaction(*this); for (Table &table : m_sqliteTables) table.initialize(*this); From af318f9723fe729556b2a6495216803360b7c83d Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Mon, 4 Mar 2019 15:38:34 +0100 Subject: [PATCH 24/27] CppTools: Fit ClangDiagnosticConfigsWidget on manager's laptop screen Managers have laptops with small screens. ClangDiagnosticConfigsWidget had a widget with too big height as minimum size. The Clang Diagnostics dialog did therefore not fit of Portale's screen. This patch removes the minimumSize and makes the dialog fit. Change-Id: I056c10c8a4e51ba4652c30616035a7c649287f58 Reviewed-by: Marco Bubke --- src/plugins/cpptools/clangdiagnosticconfigswidget.ui | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/plugins/cpptools/clangdiagnosticconfigswidget.ui b/src/plugins/cpptools/clangdiagnosticconfigswidget.ui index af4824ae228..e80ccef4feb 100644 --- a/src/plugins/cpptools/clangdiagnosticconfigswidget.ui +++ b/src/plugins/cpptools/clangdiagnosticconfigswidget.ui @@ -105,14 +105,7 @@ - - - - 700 - 500 - - - + From 15777d11ef94b2dda4ee496f1bba0a0b229bcd1f Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Mon, 4 Mar 2019 16:26:00 +0100 Subject: [PATCH 25/27] Revert "Preserve non-breaking space on saving text files" The reverted patch resulted in corrupted text files that had Unicode paragraph separators instead of newlines. This reverts commit c6b6a6a0773275a7c1b803bef62dc37dc5fe010e. Change-Id: Ia2559937afefbe39213ac73551377220b8077cef Reviewed-by: Eike Ziller --- src/plugins/clangtools/clangfixitsrefactoringchanges.cpp | 2 +- .../projectexplorer/jsonwizard/jsonwizardgeneratorfactory.cpp | 2 +- src/plugins/projectexplorer/projectfilewizardextension.cpp | 2 +- src/plugins/texteditor/refactoringchanges.cpp | 4 ++-- src/plugins/texteditor/textdocument.cpp | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/plugins/clangtools/clangfixitsrefactoringchanges.cpp b/src/plugins/clangtools/clangfixitsrefactoringchanges.cpp index f2493b10cac..c3b6f4ac3ef 100644 --- a/src/plugins/clangtools/clangfixitsrefactoringchanges.cpp +++ b/src/plugins/clangtools/clangfixitsrefactoringchanges.cpp @@ -126,7 +126,7 @@ bool FixitsRefactoringFile::apply() QString error; for (auto it = m_documents.begin(); it != m_documents.end(); ++it) { - if (!m_textFileFormat.writeFile(it.key(), it.value()->toRawText(), &error)) { + if (!m_textFileFormat.writeFile(it.key(), it.value()->toPlainText(), &error)) { qCDebug(fixitsLog) << "ERROR: Could not write file" << it.key() << ":" << error; return false; // Error writing file } diff --git a/src/plugins/projectexplorer/jsonwizard/jsonwizardgeneratorfactory.cpp b/src/plugins/projectexplorer/jsonwizard/jsonwizardgeneratorfactory.cpp index 80ee8ffeedd..e0a06c824e5 100644 --- a/src/plugins/projectexplorer/jsonwizard/jsonwizardgeneratorfactory.cpp +++ b/src/plugins/projectexplorer/jsonwizard/jsonwizardgeneratorfactory.cpp @@ -117,7 +117,7 @@ bool JsonWizardGenerator::formatFile(const JsonWizard *wizard, GeneratedFile *fi block = block.next(); } } - file->setContents(doc.toRawText()); + file->setContents(doc.toPlainText()); return true; } diff --git a/src/plugins/projectexplorer/projectfilewizardextension.cpp b/src/plugins/projectexplorer/projectfilewizardextension.cpp index 6f44a829bf3..5dab7bbf997 100644 --- a/src/plugins/projectexplorer/projectfilewizardextension.cpp +++ b/src/plugins/projectexplorer/projectfilewizardextension.cpp @@ -277,7 +277,7 @@ void ProjectFileWizardExtension::applyCodeStyle(GeneratedFile *file) const block = block.next(); } } - file->setContents(doc.toRawText()); + file->setContents(doc.toPlainText()); } } // namespace Internal diff --git a/src/plugins/texteditor/refactoringchanges.cpp b/src/plugins/texteditor/refactoringchanges.cpp index ad4bc44243f..1d43972e68d 100644 --- a/src/plugins/texteditor/refactoringchanges.cpp +++ b/src/plugins/texteditor/refactoringchanges.cpp @@ -97,7 +97,7 @@ bool RefactoringChanges::createFile(const QString &fileName, const QString &cont TextFileFormat format; format.codec = EditorManager::defaultTextCodec(); QString error; - bool saveOk = format.writeFile(fileName, document->toRawText(), &error); + bool saveOk = format.writeFile(fileName, document->toPlainText(), &error); delete document; if (!saveOk) return false; @@ -367,7 +367,7 @@ bool RefactoringFile::apply() QString error; // suppress "file has changed" warnings if the file is open in a read-only editor Core::FileChangeBlocker block(m_fileName); - if (!m_textFileFormat.writeFile(m_fileName, doc->toRawText(), &error)) { + if (!m_textFileFormat.writeFile(m_fileName, doc->toPlainText(), &error)) { qWarning() << "Could not apply changes to" << m_fileName << ". Error: " << error; result = false; } diff --git a/src/plugins/texteditor/textdocument.cpp b/src/plugins/texteditor/textdocument.cpp index bfd709d5fef..2bfb51439a1 100644 --- a/src/plugins/texteditor/textdocument.cpp +++ b/src/plugins/texteditor/textdocument.cpp @@ -569,7 +569,7 @@ bool TextDocument::save(QString *errorString, const QString &saveFileName, bool } } - const bool ok = write(fName, saveFormat, d->m_document.toRawText(), errorString); + const bool ok = write(fName, saveFormat, d->m_document.toPlainText(), errorString); // restore text cursor and scroll bar positions if (autoSave && undos < d->m_document.availableUndoSteps()) { From 0c177cd0d19a64270ee4d3eb1f588962ae835dbe Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Wed, 20 Feb 2019 17:26:36 +0100 Subject: [PATCH 26/27] Add ICore::cacheResourcePath() We need some directory where we save the index database and the precompiled headers. This files should be persistent but the user can delete them if he wants because we will rebuild them. Task-number: QTCREATORBUG-22012 Change-Id: I9f25eb48a9992d6385a96427ef9c10bc739a3567 Reviewed-by: Eike Ziller --- src/plugins/clangpchmanager/clangpchmanagerplugin.cpp | 4 +++- src/plugins/clangpchmanager/pchmanagerconnectionclient.cpp | 4 ++-- src/plugins/clangrefactoring/clangrefactoringplugin.cpp | 4 +++- .../clangrefactoring/refactoringconnectionclient.cpp | 4 ++-- src/plugins/coreplugin/icore.cpp | 6 ++++++ src/plugins/coreplugin/icore.h | 1 + tests/unit/mockup/coreplugin/icore.h | 6 ++++++ 7 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/plugins/clangpchmanager/clangpchmanagerplugin.cpp b/src/plugins/clangpchmanager/clangpchmanagerplugin.cpp index 8f7ea722426..7d564399b65 100644 --- a/src/plugins/clangpchmanager/clangpchmanagerplugin.cpp +++ b/src/plugins/clangpchmanager/clangpchmanagerplugin.cpp @@ -62,7 +62,9 @@ QString backendProcessPath() class ClangPchManagerPluginData { public: - Sqlite::Database database{Utils::PathString{Core::ICore::userResourcePath() + "/symbol-experimental-v1.db"}, 1000ms}; + Sqlite::Database database{Utils::PathString{Core::ICore::cacheResourcePath() + + "/symbol-experimental-v1.db"}, + 1000ms}; ClangBackEnd::RefactoringDatabaseInitializer databaseInitializer{database}; ClangBackEnd::FilePathCaching filePathCache{database}; ClangPchManager::ProgressManager pchCreationProgressManager{[](QFutureInterface &promise) { diff --git a/src/plugins/clangpchmanager/pchmanagerconnectionclient.cpp b/src/plugins/clangpchmanager/pchmanagerconnectionclient.cpp index 6db0db09745..a8e7e7a2ef4 100644 --- a/src/plugins/clangpchmanager/pchmanagerconnectionclient.cpp +++ b/src/plugins/clangpchmanager/pchmanagerconnectionclient.cpp @@ -51,11 +51,11 @@ ClangPchManager::PchManagerConnectionClient::PchManagerConnectionClient( { m_processCreator.setTemporaryDirectoryPattern("clangpchmanagerbackend-XXXXXX"); - QDir pchsDirectory(Core::ICore::userResourcePath()); + QDir pchsDirectory(Core::ICore::cacheResourcePath()); pchsDirectory.mkdir("pchs"); pchsDirectory.cd("pchs"); m_processCreator.setArguments({connectionName(), - Core::ICore::userResourcePath() + "/symbol-experimental-v1.db", + Core::ICore::cacheResourcePath() + "/symbol-experimental-v1.db", pchsDirectory.absolutePath()}); stdErrPrefixer().setPrefix("PchManagerConnectionClient.stderr: "); diff --git a/src/plugins/clangrefactoring/clangrefactoringplugin.cpp b/src/plugins/clangrefactoring/clangrefactoringplugin.cpp index 917823152e3..ea765bed5f8 100644 --- a/src/plugins/clangrefactoring/clangrefactoringplugin.cpp +++ b/src/plugins/clangrefactoring/clangrefactoringplugin.cpp @@ -77,7 +77,9 @@ class ClangRefactoringPluginData public: using QuerySqliteReadStatementFactory = QuerySqliteStatementFactory; - Sqlite::Database database{Utils::PathString{Core::ICore::userResourcePath() + "/symbol-experimental-v1.db"}, 1000ms}; + Sqlite::Database database{Utils::PathString{Core::ICore::cacheResourcePath() + + "/symbol-experimental-v1.db"}, + 1000ms}; ClangBackEnd::RefactoringDatabaseInitializer databaseInitializer{database}; ClangBackEnd::FilePathCaching filePathCache{database}; ClangPchManager::ProgressManager progressManager{ diff --git a/src/plugins/clangrefactoring/refactoringconnectionclient.cpp b/src/plugins/clangrefactoring/refactoringconnectionclient.cpp index ff66ec20cbf..a42ed38a161 100644 --- a/src/plugins/clangrefactoring/refactoringconnectionclient.cpp +++ b/src/plugins/clangrefactoring/refactoringconnectionclient.cpp @@ -48,8 +48,8 @@ RefactoringConnectionClient::RefactoringConnectionClient(RefactoringClientInterf , m_serverProxy(client) { m_processCreator.setTemporaryDirectoryPattern("clangrefactoringbackend-XXXXXX"); - m_processCreator.setArguments({connectionName(), - Core::ICore::userResourcePath() + "/symbol-experimental-v1.db"}); + m_processCreator.setArguments( + {connectionName(), Core::ICore::cacheResourcePath() + "/symbol-experimental-v1.db"}); stdErrPrefixer().setPrefix("RefactoringConnectionClient.stderr: "); stdOutPrefixer().setPrefix("RefactoringConnectionClient.stdout: "); diff --git a/src/plugins/coreplugin/icore.cpp b/src/plugins/coreplugin/icore.cpp index f16f4369bb2..9cb23af6562 100644 --- a/src/plugins/coreplugin/icore.cpp +++ b/src/plugins/coreplugin/icore.cpp @@ -35,6 +35,7 @@ #include #include +#include /*! \namespace Core @@ -439,6 +440,11 @@ QString ICore::userResourcePath() return urp; } +QString ICore::cacheResourcePath() +{ + return QStandardPaths::writableLocation(QStandardPaths::CacheLocation); +} + QString ICore::installerResourcePath() { return QFileInfo(settings(QSettings::SystemScope)->fileName()).path() + '/' diff --git a/src/plugins/coreplugin/icore.h b/src/plugins/coreplugin/icore.h index 80e387658f4..5125345cffd 100644 --- a/src/plugins/coreplugin/icore.h +++ b/src/plugins/coreplugin/icore.h @@ -94,6 +94,7 @@ public: static QString resourcePath(); static QString userResourcePath(); + static QString cacheResourcePath(); static QString installerResourcePath(); static QString libexecPath(); static QString clangExecutable(const QString &clangBinDirectory); diff --git a/tests/unit/mockup/coreplugin/icore.h b/tests/unit/mockup/coreplugin/icore.h index cfec03f999a..579fbc3b56f 100644 --- a/tests/unit/mockup/coreplugin/icore.h +++ b/tests/unit/mockup/coreplugin/icore.h @@ -6,5 +6,11 @@ inline static QString userResourcePath() { return QDir::tempPath(); } + +inline static QString cacheResourcePath() +{ + return QDir::tempPath(); +} + } // namespace ICore } // namespace Core From 26f6cbf8b59dffa7f47b315031b7055ec3421315 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Fri, 1 Mar 2019 16:58:35 +0100 Subject: [PATCH 27/27] Perf profiler: Fix UI text Change-Id: I3a2e7a67db1259f847f04ff523bd9a2b12863510 Reviewed-by: Ulf Hermann --- src/plugins/perfprofiler/perfconfigwidget.cpp | 4 +-- src/plugins/perfprofiler/perfdatareader.cpp | 18 +++++------ src/plugins/perfprofiler/perfloaddialog.ui | 6 ++-- .../perfprofiler/perfprofilerruncontrol.cpp | 8 ++--- src/plugins/perfprofiler/perfprofilertool.cpp | 32 +++++++++---------- .../perfprofiler/perfprofilertracemanager.cpp | 8 ++--- .../perfprofiler/perftracepointdialog.ui | 4 +-- 7 files changed, 40 insertions(+), 40 deletions(-) diff --git a/src/plugins/perfprofiler/perfconfigwidget.cpp b/src/plugins/perfprofiler/perfconfigwidget.cpp index 1aaefcd77d2..c6049cc451c 100644 --- a/src/plugins/perfprofiler/perfconfigwidget.cpp +++ b/src/plugins/perfprofiler/perfconfigwidget.cpp @@ -211,7 +211,7 @@ void PerfConfigWidget::handleProcessFinished() if (tracePoints.isEmpty()) { Core::AsynchronousMessageBox::warning( - tr("No trace points found"), + tr("No Trace Points Found"), tr("Trace points can be defined with \"perf probe -a\".")); } else { for (const QByteArray &event : qAsConst(tracePoints)) { @@ -233,7 +233,7 @@ void PerfConfigWidget::handleProcessError(QProcess::ProcessError error) { if (error == QProcess::FailedToStart) { Core::AsynchronousMessageBox::warning( - tr("Cannot list trace points"), + tr("Cannot List Trace Points"), tr("\"perf probe -l\" failed to start. Is perf installed?")); m_ui->useTracePointsButton->setEnabled(true); } diff --git a/src/plugins/perfprofiler/perfdatareader.cpp b/src/plugins/perfprofiler/perfdatareader.cpp index 3cfb7c2989c..0c34ed583b1 100644 --- a/src/plugins/perfprofiler/perfdatareader.cpp +++ b/src/plugins/perfprofiler/perfdatareader.cpp @@ -75,8 +75,8 @@ PerfDataReader::PerfDataReader(QObject *parent) : } if (exitCode != 0) { QMessageBox::warning(Core::ICore::mainWindow(), - tr("Perf data parser failed"), - tr("The perf data parser failed to process all the samples. " + tr("Perf Data Parser Failed"), + tr("The Perf data parser failed to process all the samples. " "Your trace is incomplete. The exit code was %1.") .arg(exitCode)); } @@ -101,17 +101,17 @@ PerfDataReader::PerfDataReader(QObject *parent) : connect(&m_input, &QProcess::errorOccurred, this, [this](QProcess::ProcessError e){ switch (e) { case QProcess::FailedToStart: - emit processFailed(tr("perfparser failed to start")); + emit processFailed(tr("perfparser failed to start.")); QMessageBox::warning(Core::ICore::mainWindow(), - tr("Perf data parser failed"), - tr("Could not start the 'perfparser' utility program. " - "Make sure a working perf parser is available at the location " + tr("Perf Data Parser Failed"), + tr("Could not start the perfparser utility program. " + "Make sure a working Perf parser is available at the location " "given by the PERFPROFILER_PARSER_FILEPATH environment " "variable.")); break; case QProcess::Crashed: QMessageBox::warning(Core::ICore::mainWindow(), - tr("Perf data parser crashed"), + tr("Perf Data Parser Crashed"), tr("This is a bug. Please report it.")); break; case QProcess::ReadError: @@ -346,8 +346,8 @@ void PerfDataReader::writeChunk() m_input.kill(); emit finished(); QMessageBox::warning(Core::ICore::mainWindow(), - tr("Cannot send data to Perf data parser"), - tr("The perf data parser doesn't accept further input. " + tr("Cannot Send Data to Perf Data Parser"), + tr("The Perf data parser does not accept further input. " "Your trace is incomplete.")); } } diff --git a/src/plugins/perfprofiler/perfloaddialog.ui b/src/plugins/perfprofiler/perfloaddialog.ui index 5bc41cd26ba..c08b6433f1a 100644 --- a/src/plugins/perfprofiler/perfloaddialog.ui +++ b/src/plugins/perfprofiler/perfloaddialog.ui @@ -19,7 +19,7 @@ - &Trace File: + &Trace file: traceFileLineEdit @@ -39,7 +39,7 @@ - Directory of &Executable: + Directory of &executable: executableDirLineEdit @@ -64,7 +64,7 @@ - + diff --git a/src/plugins/perfprofiler/perfprofilerruncontrol.cpp b/src/plugins/perfprofiler/perfprofilerruncontrol.cpp index d01d5c07568..50aa9696a11 100644 --- a/src/plugins/perfprofiler/perfprofilerruncontrol.cpp +++ b/src/plugins/perfprofiler/perfprofilerruncontrol.cpp @@ -138,10 +138,10 @@ public: // The terminate() below will frequently lead to QProcess::Crashed. We're not interested // in that. FailedToStart is the only actual failure. if (e == QProcess::FailedToStart) { - QString msg = tr("perf process failed to start"); + QString msg = tr("Perf Process Failed to Start"); QMessageBox::warning(Core::ICore::mainWindow(), - msg, tr("Make sure you are running a recent Linux kernel and " - "that the 'perf' utility is available.")); + msg, tr("Make sure that you are running a recent Linux kernel and " + "that the \"perf\" utility is available.")); reportFailure(msg); } }); @@ -227,7 +227,7 @@ void PerfProfilerRunner::start() }); connect(recorder, &DeviceProcess::readyReadStandardOutput, this, [this, reader, recorder] { if (!reader->feedParser(recorder->readAllStandardOutput())) - reportFailure(tr("Failed to transfer perf data to perfparser")); + reportFailure(tr("Failed to transfer Perf data to perfparser.")); }); } diff --git a/src/plugins/perfprofiler/perfprofilertool.cpp b/src/plugins/perfprofiler/perfprofilertool.cpp index 17361031890..ff5a171a6f7 100644 --- a/src/plugins/perfprofiler/perfprofilertool.cpp +++ b/src/plugins/perfprofiler/perfprofilertool.cpp @@ -89,19 +89,19 @@ PerfProfilerTool::PerfProfilerTool(QObject *parent) : options->menu()->setEnabled(true); const Core::Context globalContext(Core::Constants::C_GLOBAL); - m_loadPerfData = new QAction(tr("Load perf.data file"), options); + m_loadPerfData = new QAction(tr("Load perf.data File"), options); Core::Command *command = Core::ActionManager::registerAction( m_loadPerfData, Constants::PerfProfilerTaskLoadPerf, globalContext); connect(m_loadPerfData, &QAction::triggered, this, &PerfProfilerTool::showLoadPerfDialog); options->addAction(command); - m_loadTrace = new QAction(tr("Load trace file"), options); + m_loadTrace = new QAction(tr("Load Trace File"), options); command = Core::ActionManager::registerAction(m_loadTrace, Constants::PerfProfilerTaskLoadTrace, globalContext); connect(m_loadTrace, &QAction::triggered, this, &PerfProfilerTool::showLoadTraceDialog); options->addAction(command); - m_saveTrace = new QAction(tr("Save trace file"), options); + m_saveTrace = new QAction(tr("Save Trace File"), options); command = Core::ActionManager::registerAction(m_saveTrace, Constants::PerfProfilerTaskSaveTrace, globalContext); connect(m_saveTrace, &QAction::triggered, this, &PerfProfilerTool::showSaveTraceDialog); @@ -126,7 +126,7 @@ PerfProfilerTool::PerfProfilerTool(QObject *parent) : }); options->addAction(command); - QAction *tracePointsAction = new QAction(tr("Create memory trace points"), options); + QAction *tracePointsAction = new QAction(tr("Create Memory Trace Points"), options); tracePointsAction->setIcon(Debugger::Icons::TRACEPOINT_TOOLBAR.icon()); tracePointsAction->setIconVisibleInMenu(false); tracePointsAction->setToolTip(tr("Create trace points for memory profiling on the target " @@ -141,7 +141,7 @@ PerfProfilerTool::PerfProfilerTool(QObject *parent) : m_tracePointsButton->setDefaultAction(tracePointsAction); auto action = new QAction(tr("Performance Analyzer"), this); - action->setToolTip(tr("The Performance Analyzer can be used to find performance bottlenecks")); + action->setToolTip(tr("Finds performance bottlenecks.")); menu->addAction(ActionManager::registerAction(action, Constants::PerfProfilerLocalActionId), Debugger::Constants::G_ANALYZER_TOOLS); QObject::connect(action, &QAction::triggered, this, [this] { @@ -251,7 +251,7 @@ void PerfProfilerTool::createViews() connect(m_recordButton, &QAbstractButton::clicked, this, &PerfProfilerTool::setRecording); m_clearButton->setIcon(Utils::Icons::CLEAN_TOOLBAR.icon()); - m_clearButton->setToolTip(tr("Discard data")); + m_clearButton->setToolTip(tr("Discard data.")); connect(m_clearButton, &QAbstractButton::clicked, this, &PerfProfilerTool::clear); m_filterButton->setIcon(Utils::Icons::FILTER.icon()); @@ -410,10 +410,10 @@ void PerfProfilerTool::onReaderFinished() m_readerRunning = false; if (m_traceManager->traceDuration() <= 0) { QMessageBox::warning(Core::ICore::mainWindow(), - tr("No data loaded"), + tr("No Data Loaded"), tr("The profiler did not produce any samples. " - "Make sure you are running a recent Linux kernel and that the " - "'perf' utility is available and generates useful call " + "Make sure that you are running a recent Linux kernel and that " + "the \"perf\" utility is available and generates useful call " "graphs.")); clear(); } else { @@ -612,7 +612,7 @@ void PerfProfilerTool::showLoadTraceDialog() m_perspective.select(); QString filename = QFileDialog::getOpenFileName( - ICore::mainWindow(), tr("Load trace file"), + ICore::mainWindow(), tr("Load Trace File"), "", tr("Trace File (*.ptr)")); if (filename.isEmpty()) return; @@ -627,7 +627,7 @@ void PerfProfilerTool::showSaveTraceDialog() m_perspective.select(); QString filename = QFileDialog::getSaveFileName( - ICore::mainWindow(), tr("Save trace file"), + ICore::mainWindow(), tr("Save Trace File"), "", tr("Trace File (*.ptr)")); if (filename.isEmpty()) return; @@ -641,8 +641,8 @@ void PerfProfilerTool::showSaveTraceDialog() void PerfProfilerTool::setAggregated(bool aggregated) { m_aggregateButton->setChecked(aggregated); - m_aggregateButton->setToolTip(aggregated ? tr("Show all addresses") - : tr("Aggregate by functions")); + m_aggregateButton->setToolTip(aggregated ? tr("Show all addresses.") + : tr("Aggregate by functions.")); emit aggregatedChanged(aggregated); } @@ -653,8 +653,8 @@ void PerfProfilerTool::setRecording(bool recording) m_recordButton->setIcon(recording ? recordOn : recordOff); m_recordButton->setChecked(recording); - m_recordButton->setToolTip(recording ? tr("Stop collecting profile data") : - tr("Collect profile data")); + m_recordButton->setToolTip(recording ? tr("Stop collecting profile data.") : + tr("Collect profile data.")); emit recordingChanged(recording); } @@ -668,7 +668,7 @@ void PerfProfilerTool::updateTime(qint64 duration, qint64 delay) m_recordedLabel->clear(); if (delay > 0) - m_delayLabel->setText(tr("Processing Delay: %1.%2s").arg(delay / e9) + m_delayLabel->setText(tr("Processing delay: %1.%2s").arg(delay / e9) .arg(qAbs(delay / e8) % ten)); else if (delay == 0) m_delayLabel->clear(); diff --git a/src/plugins/perfprofiler/perfprofilertracemanager.cpp b/src/plugins/perfprofiler/perfprofilertracemanager.cpp index a4272ad1177..4e98b969548 100644 --- a/src/plugins/perfprofiler/perfprofilertracemanager.cpp +++ b/src/plugins/perfprofiler/perfprofilertracemanager.cpp @@ -94,13 +94,13 @@ void PerfProfilerEventStorage::clear() m_file.clear(); m_size = 0; if (!m_file.open()) - m_errorHandler(tr("Failed to reset temporary trace file")); + m_errorHandler(tr("Failed to reset temporary trace file.")); } void PerfProfilerEventStorage::finalize() { if (!m_file.flush()) - m_errorHandler(tr("Failed to flush temporary trace file")); + m_errorHandler(tr("Failed to flush temporary trace file.")); } bool PerfProfilerEventStorage::replay( @@ -110,13 +110,13 @@ bool PerfProfilerEventStorage::replay( case Timeline::TraceStashFile::ReplaySuccess: return true; case Timeline::TraceStashFile::ReplayOpenFailed: - m_errorHandler(tr("Cannot re-open temporary trace file")); + m_errorHandler(tr("Cannot re-open temporary trace file.")); break; case Timeline::TraceStashFile::ReplayLoadFailed: // Happens if the loader rejects an event. Not an actual error break; case Timeline::TraceStashFile::ReplayReadPastEnd: - m_errorHandler(tr("Read past end from temporary trace file")); + m_errorHandler(tr("Read past end from temporary trace file.")); break; } return false; diff --git a/src/plugins/perfprofiler/perftracepointdialog.ui b/src/plugins/perfprofiler/perftracepointdialog.ui index 8b2a077a998..ce2f1f4c408 100644 --- a/src/plugins/perfprofiler/perftracepointdialog.ui +++ b/src/plugins/perfprofiler/perftracepointdialog.ui @@ -11,7 +11,7 @@ - Creating memory trace points + Creating Memory Trace Points @@ -29,7 +29,7 @@ - Elevate privileges using + Elevate privileges using: