diff --git a/doc/src/debugger/creator-only/creator-debugger-setup.qdoc b/doc/src/debugger/creator-only/creator-debugger-setup.qdoc index bf956faa48c..379e821eb5a 100644 --- a/doc/src/debugger/creator-only/creator-debugger-setup.qdoc +++ b/doc/src/debugger/creator-only/creator-debugger-setup.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. @@ -77,10 +77,9 @@ \QC supports native debuggers when working with compiled code. On most supported platforms, the GNU Symbolic Debugger GDB can be used. On - Microsoft Windows, when using the Microsoft tool chain the Microsoft Console - Debugger CDB, is needed. On \macos, the LLDB debugger can be used. Basic - support for LLDB is also available on Linux, but it is restricted by LLDB's - capabilities there, and considered experimental. + Microsoft Windows, when using the Microsoft tool chain, the Microsoft + Console Debugger CDB is needed. On \macos and Linux, the LLDB debugger + can be used. The following table summarizes the support for debugging C++ code: @@ -92,7 +91,7 @@ \row \li Linux \li GCC, ICC - \li GDB, LLDB (experimental) + \li GDB, LLDB \row \li Unix \li GCC, ICC @@ -340,29 +339,4 @@ of the project. \endlist - - \section1 Setting Up Experimental LLDB Support - - To use the experimental interface to LLDB, you must set up a kit that uses - the LLDB engine and select the kit for your project: - - \list 1 - - \li Select \uicontrol Tools > \uicontrol Options > - \uicontrol Kits. - - \li Select an automatically created kit in the list, and then select - \uicontrol Clone to create a copy of the kit. - - \li In the \uicontrol Debugger field, select an LLDB Engine. If an LLDB - Engine is not listed, select \uicontrol Manage to add it in - \uicontrol Tools > \uicontrol Options > \uicontrol Kits > - \uicontrol Debuggers. For more information, see - \l {Adding Debuggers}. - - \li To use the debugger, add the kit in the \uicontrol {Build Settings} - of the project. - - \endlist - */ diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorEditor.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorEditor.qml index 39fb95fce14..878d26c15e3 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorEditor.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorEditor.qml @@ -518,8 +518,8 @@ Column { height: 20 visible: colorEditor.supportGradient - color: "white" - border.color: "white" + color: Theme.qmlDesignerButtonColor() + border.color: Theme.qmlDesignerBorderColor() border.width: 1 ToolTipArea { @@ -566,20 +566,18 @@ Column { } } - Rectangle { - width: 18 - height: 18 + Image { + id: image + width: 16 + height: 16 + smooth: false anchors.centerIn: parent - color: "steelblue" - - border.color: "black" - border.width: 1 - - MouseArea { - anchors.fill: parent - onClicked: { - presetList.open() - } + source: "images/icon-gradient-list.png" + } + MouseArea { + anchors.fill: parent + onClicked: { + presetList.open() } } } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/images/icon-gradient-list.png b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/images/icon-gradient-list.png new file mode 100644 index 00000000000..ee53d078983 Binary files /dev/null and b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/images/icon-gradient-list.png differ diff --git a/share/qtcreator/templates/wizards/projects/cpplibrary/project.qbs b/share/qtcreator/templates/wizards/projects/cpplibrary/project.qbs new file mode 100644 index 00000000000..0e5df73e84f --- /dev/null +++ b/share/qtcreator/templates/wizards/projects/cpplibrary/project.qbs @@ -0,0 +1,59 @@ +import qbs.FileInfo + +@if %{IsStatic} +StaticLibrary { +@else +DynamicLibrary { +@endif +@if '%{QtModule}' === 'none' + Depends { name: "cpp" } +@else + Depends { name: "Qt.%{QtModule}" } +@endif + + cpp.cxxLanguageVersion: "c++11" + cpp.defines: [ +@if %{IsShared} + "%{LibraryDefine}", +@endif +@if %{IsQtPlugin} + "QT_PLUGIN", +@endif + + // The following define makes your compiler emit warnings if you use + // any Qt feature that has been marked deprecated (the exact warnings + // depend on your compiler). Please consult the documentation of the + // deprecated API in order to know how to port your code away from it. + "QT_DEPRECATED_WARNINGS", + + // You can also make your code fail to compile if it uses deprecated APIs. + // In order to do so, uncomment the following line. + // You can also select to disable deprecated APIs only up to a certain version of Qt. + // "QT_DISABLE_DEPRECATED_BEFORE=0x060000", // disables all the APIs deprecated before Qt 6.0.0 + ] + + files: [ + "%{SrcFileName}", +@if %{IsShared} + "%{GlobalHdrFileName}", +@endif + "%{HdrFileName}", +@if %{IsQtPlugin} + "%{PluginJsonFile}", +@endif + ] + +@if '%{TargetInstallPath}' != '' + // Default rules for deployment. + qbs.installPrefix: "" + Properties { + condition: qbs.targetOS.contains("unix") + install: true +@if %{IsQtPlugin} + installDir: FileInfo.joinPaths(Qt.core.pluginPath, "%{PluginTargetPath}") +@else + installDir: "%{TargetInstallPath}" +@endif + } +@endif +} diff --git a/share/qtcreator/templates/wizards/projects/cpplibrary/wizard.json b/share/qtcreator/templates/wizards/projects/cpplibrary/wizard.json index af209105bfd..8f4c264499c 100644 --- a/share/qtcreator/templates/wizards/projects/cpplibrary/wizard.json +++ b/share/qtcreator/templates/wizards/projects/cpplibrary/wizard.json @@ -1,6 +1,6 @@ { "version": 1, - "supportedProjectTypes": [ "CMakeProjectManager.CMakeProject", "Qt4ProjectManager.Qt4Project" ], + "supportedProjectTypes": [ "CMakeProjectManager.CMakeProject", "Qbs.QbsProject", "Qt4ProjectManager.Qt4Project" ], "id": "H.CppLibrary", "category": "G.Library", "trDescription": "Creates a C++ library. This can be used to create:", @@ -11,8 +11,8 @@ "options": [ - { "key": "ProjectFile", "value": "%{JS: value('BuildSystem') === 'qmake' ? value('ProFile') : value('CMakeFile')}" }, - { "key": "ProFile", "value": "%{JS: Util.fileName(value('ProjectDirectory') + '/' + value('ProjectName'), 'pro')}" }, + { "key": "ProjectFile", "value": "%{JS: value('BuildSystem') === 'cmake' ? value('CMakeFile') : value('ProFile')}" }, + { "key": "ProFile", "value": "%{JS: Util.fileName(value('ProjectDirectory') + '/' + value('ProjectName'), value('BuildSystem') === 'qmake' ? 'pro' : 'qbs')}" }, { "key": "CMakeFile", "value": "%{ProjectDirectory}/CMakeLists.txt" }, { "key": "PluginJsonFile", "value": "%{JS: Util.fileName(value('ProjectName'), 'json')}" }, { "key": "IsShared", "value": "%{JS: value('Type') === 'shared'}" }, @@ -59,7 +59,7 @@ "items": [ { - "trKey": "Qmake", + "trKey": "qmake", "value": "qmake", "condition": "%{JS: value('Plugins').indexOf('QmakeProjectManager') >= 0}" }, @@ -67,6 +67,11 @@ "trKey": "CMake", "value": "cmake", "condition": "%{JS: value('Plugins').indexOf('CMakeProjectManager') >= 0}" + }, + { + "trKey": "Qbs", + "value": "qbs", + "condition": "%{JS: value('Plugins').indexOf('QbsProjectManager') >= 0}" } ] } @@ -291,6 +296,12 @@ "openAsProject": true, "condition": "%{JS: value('BuildSystem') === 'qmake'}" }, + { + "source": "project.qbs", + "target": "%{ProFile}", + "openAsProject": true, + "condition": "%{JS: value('BuildSystem') === 'qbs'}" + }, { "source": "CMakeLists.txt", "openAsProject": true, diff --git a/src/libs/languageserverprotocol/jsonkeys.h b/src/libs/languageserverprotocol/jsonkeys.h index 4c4ee054ab4..cccf0789b9e 100644 --- a/src/libs/languageserverprotocol/jsonkeys.h +++ b/src/libs/languageserverprotocol/jsonkeys.h @@ -145,6 +145,7 @@ constexpr char optionsKey[] = "options"; constexpr char parametersKey[] = "params"; constexpr char patternKey[] = "pattern"; constexpr char positionKey[] = "position"; +constexpr char prepareProviderKey[] = "prepareProvider"; constexpr char processIdKey[] = "processId"; constexpr char queryKey[] = "query"; constexpr char rangeFormattingKey[] = "rangeFormatting"; diff --git a/src/libs/languageserverprotocol/servercapabilities.cpp b/src/libs/languageserverprotocol/servercapabilities.cpp index f9dce15b35c..a8e932ad50a 100644 --- a/src/libs/languageserverprotocol/servercapabilities.cpp +++ b/src/libs/languageserverprotocol/servercapabilities.cpp @@ -111,6 +111,44 @@ Utils::optional> ServerCapabilities::cod return Utils::nullopt; } +Utils::optional> ServerCapabilities::renameProvider() const +{ + using RetType = Utils::variant; + const QJsonValue &localValue = value(renameProviderKey); + if (localValue.isBool()) + return RetType(localValue.toBool()); + if (localValue.isObject()) + return RetType(RenameOptions(localValue.toObject())); + return Utils::nullopt; +} + +void ServerCapabilities::setRenameProvider(Utils::variant renameProvider) +{ + if (Utils::holds_alternative(renameProvider)) + insert(renameProviderKey, Utils::get(renameProvider)); + else if (Utils::holds_alternative(renameProvider)) + insert(renameProviderKey, Utils::get(renameProvider)); +} + +Utils::optional> ServerCapabilities::colorProvider() const +{ + using RetType = Utils::variant; + const QJsonValue &localValue = value(colorProviderKey); + if (localValue.isBool()) + return RetType(localValue.toBool()); + if (localValue.isObject()) + return RetType(JsonObject(localValue.toObject())); + return Utils::nullopt; +} + +void ServerCapabilities::setColorProvider(Utils::variant colorProvider) +{ + if (Utils::holds_alternative(colorProvider)) + insert(renameProviderKey, Utils::get(colorProvider)); + else if (Utils::holds_alternative(colorProvider)) + insert(renameProviderKey, Utils::get(colorProvider)); +} + bool ServerCapabilities::isValid(QStringList *error) const { return checkOptional(error, textDocumentSyncKey) @@ -128,9 +166,9 @@ bool ServerCapabilities::isValid(QStringList *error) const && checkOptional(error, codeLensProviderKey) && checkOptional(error, documentFormattingProviderKey) && checkOptional(error, documentRangeFormattingProviderKey) - && checkOptional(error, renameProviderKey) + && checkOptional(error, renameProviderKey) && checkOptional(error, documentLinkProviderKey) - && checkOptional(error, colorProviderKey) + && checkOptional(error, colorProviderKey) && checkOptional(error, executeCommandProviderKey) && checkOptional(error, workspaceKey) && checkOptional(error, semanticHighlightingKey); diff --git a/src/libs/languageserverprotocol/servercapabilities.h b/src/libs/languageserverprotocol/servercapabilities.h index 6345178c570..7365449b0fb 100644 --- a/src/libs/languageserverprotocol/servercapabilities.h +++ b/src/libs/languageserverprotocol/servercapabilities.h @@ -357,9 +357,23 @@ public: { insert(documentRangeFormattingProviderKey, documentRangeFormattingProvider); } void clearDocumentRangeFormattingProvider() { remove(documentRangeFormattingProviderKey); } + class RenameOptions : public JsonObject + { + public: + using JsonObject::JsonObject; + + // Renames should be checked and tested before being executed. + Utils::optional prepareProvider() const { return optionalValue(prepareProviderKey); } + void setPrepareProvider(bool prepareProvider) { insert(prepareProviderKey, prepareProvider); } + void clearPrepareProvider() { remove(prepareProviderKey); } + + bool isValid(QStringList * error) const override + { return checkOptional(error, prepareProviderKey); } + }; + // The server provides rename support. - Utils::optional renameProvider() const { return optionalValue(renameProviderKey); } - void setRenameProvider(bool renameProvider) { insert(renameProviderKey, renameProvider); } + Utils::optional> renameProvider() const; + void setRenameProvider(Utils::variant renameProvider); void clearRenameProvider() { remove(renameProviderKey); } // The server provides document link support. @@ -370,10 +384,8 @@ public: void clearDocumentLinkProvider() { remove(documentLinkProviderKey); } // The server provides color provider support. - Utils::optional colorProvider() const - { return optionalValue(colorProviderKey); } - void setColorProvider(TextDocumentRegistrationOptions colorProvider) - { insert(colorProviderKey, colorProvider); } + Utils::optional> colorProvider() const; + void setColorProvider(Utils::variant colorProvider); void clearColorProvider() { remove(colorProviderKey); } // The server provides execute command support. diff --git a/src/libs/utils/filesearch.cpp b/src/libs/utils/filesearch.cpp index 0bdf3991c5e..03aa1cf9b20 100644 --- a/src/libs/utils/filesearch.cpp +++ b/src/libs/utils/filesearch.cpp @@ -651,11 +651,16 @@ SubDirFileIterator::SubDirFileIterator(const QStringList &directories, const QSt { m_encoding = (encoding == nullptr ? QTextCodec::codecForLocale() : encoding); qreal maxPer = qreal(MAX_PROGRESS) / directories.count(); - foreach (const QString &directoryEntry, directories) { + for (const QString &directoryEntry : directories) { if (!directoryEntry.isEmpty()) { - m_dirs.push(QDir(directoryEntry)); - m_progressValues.push(maxPer); - m_processedValues.push(false); + const QDir dir(directoryEntry); + const QString canonicalPath = dir.canonicalPath(); + if (!canonicalPath.isEmpty() && dir.exists()) { + m_dirs.push(dir); + m_knownDirs.insert(canonicalPath); + m_progressValues.push(maxPer); + m_processedValues.push(false); + } } } } @@ -676,10 +681,18 @@ void SubDirFileIterator::update(int index) const bool processed = m_processedValues.pop(); if (dir.exists()) { const QString dirPath = dir.path(); - QStringList subDirs; - if (!processed) - subDirs = dir.entryList(QDir::Dirs|QDir::Hidden|QDir::NoDotAndDotDot); - if (subDirs.isEmpty()) { + using Dir = QString; + using CanonicalDir = QString; + std::vector> subDirs; + if (!processed) { + for (const QFileInfo &info : + dir.entryInfoList(QDir::Dirs | QDir::Hidden | QDir::NoDotAndDotDot)) { + const QString canonicalDir = info.canonicalFilePath(); + if (!m_knownDirs.contains(canonicalDir)) + subDirs.emplace_back(info.filePath(), canonicalDir); + } + } + if (subDirs.empty()) { const QStringList allFileEntries = dir.entryList(QDir::Files|QDir::Hidden); const QStringList allFilePaths = Utils::transform(allFileEntries, [&dirPath](const QString &entry) { @@ -696,14 +709,13 @@ void SubDirFileIterator::update(int index) m_dirs.push(dir); m_progressValues.push(subProgress); m_processedValues.push(true); - QStringListIterator it(subDirs); - it.toBack(); - while (it.hasPrevious()) { - const QString &directory = it.previous(); - m_dirs.push(QDir(dirPath + QLatin1Char('/') + directory)); - m_progressValues.push(subProgress); - m_processedValues.push(false); - } + Utils::reverseForeach(subDirs, + [this, subProgress](const std::pair &dir) { + m_dirs.push(QDir(dir.first)); + m_knownDirs.insert(dir.second); + m_progressValues.push(subProgress); + m_processedValues.push(false); + }); } } else { m_progress += dirProgressMax; diff --git a/src/libs/utils/filesearch.h b/src/libs/utils/filesearch.h index cddb637184f..546a7334cc9 100644 --- a/src/libs/utils/filesearch.h +++ b/src/libs/utils/filesearch.h @@ -159,6 +159,7 @@ private: std::function m_filterFiles; QTextCodec *m_encoding; QStack m_dirs; + QSet m_knownDirs; QStack m_progressValues; QStack m_processedValues; qreal m_progress; diff --git a/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp b/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp index 8d3f1b54a08..cb8105a33a1 100644 --- a/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp +++ b/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp @@ -655,6 +655,7 @@ void ClangCodeCompletionTest::testCompleteProjectDependingCodeAfterChangingProje // Check completion with project configuration 2 QVERIFY(projectLoader.updateProject({{"PROJECT_CONFIGURATION_2"}})); + openEditor.waitUntilBackendIsNotified(); proposal = completionResults(openEditor.editor()); QVERIFY(!hasItem(proposal, "projectConfiguration1")); diff --git a/src/plugins/genericprojectmanager/genericproject.cpp b/src/plugins/genericprojectmanager/genericproject.cpp index a50ccf6d2f3..4c6be63f8d6 100644 --- a/src/plugins/genericprojectmanager/genericproject.cpp +++ b/src/plugins/genericprojectmanager/genericproject.cpp @@ -384,10 +384,13 @@ void GenericProject::parseProject(RefreshOptions options) } } -QString GenericProject::findCommonSourceRoot(const QStringList &list) +FilePath GenericProject::findCommonSourceRoot() { - QString root = list.front(); - for (const QString &item : list) { + if (m_files.isEmpty()) + return FilePath::fromFileInfo(QFileInfo(m_filesFileName).absolutePath()); + + QString root = m_files.front(); + for (const QString &item : m_files) { if (root.length() > item.length()) root.truncate(item.length()); @@ -398,7 +401,7 @@ QString GenericProject::findCommonSourceRoot(const QStringList &list) } } } - return QFileInfo(root).absolutePath(); + return FilePath::fromString(QFileInfo(root).absolutePath()); } void GenericProject::refresh(RefreshOptions options) @@ -410,7 +413,7 @@ void GenericProject::refresh(RefreshOptions options) auto newRoot = std::make_unique(this); // find the common base directory of all source files - Utils::FilePath baseDir = FilePath::fromFileInfo(QFileInfo(findCommonSourceRoot(m_files))); + Utils::FilePath baseDir = findCommonSourceRoot(); for (const QString &f : m_files) { FileType fileType = FileType::Source; // ### FIXME diff --git a/src/plugins/genericprojectmanager/genericproject.h b/src/plugins/genericprojectmanager/genericproject.h index 213bd60471d..18d1e238d2c 100644 --- a/src/plugins/genericprojectmanager/genericproject.h +++ b/src/plugins/genericprojectmanager/genericproject.h @@ -69,7 +69,7 @@ private: QStringList processEntries(const QStringList &paths, QHash *map = nullptr) const; - static QString findCommonSourceRoot(const QStringList &list); + Utils::FilePath findCommonSourceRoot(); void refreshCppCodeModel(); void updateDeploymentData(); void activeTargetWasChanged(); diff --git a/src/plugins/languageclient/client.cpp b/src/plugins/languageclient/client.cpp index a17bb47a131..430e03091c2 100644 --- a/src/plugins/languageclient/client.cpp +++ b/src/plugins/languageclient/client.cpp @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -487,6 +488,7 @@ void Client::documentContentsChanged(TextEditor::TextDocument *document, cursor.setPosition(position + charsRemoved); cursor.setPosition(position, QTextCursor::KeepAnchor); change.setRange(Range(cursor)); + change.setRangeLength(cursor.selectionEnd() - cursor.selectionStart()); change.setText(document->textAt(position, charsAdded)); params.setContentChanges({change}); } else { @@ -1175,8 +1177,10 @@ void Client::intializeCallback(const InitializeRequest::Response &initResponse) } else { const InitializeResult &result = _result.value(); QStringList error; - if (!result.isValid(&error)) // continue on ill formed result + if (!result.isValid(&error)) { // continue on ill formed result + std::reverse(error.begin(), error.end()); log(tr("Initialize result is not valid: ") + error.join("->")); + } m_serverCapabilities = result.capabilities().value_or(ServerCapabilities()); } @@ -1193,6 +1197,10 @@ void Client::intializeCallback(const InitializeRequest::Response &initResponse) if (auto textEditor = qobject_cast(editor)) textEditor->editorWidget()->addHoverHandler(&m_hoverHandler); } + if (m_dynamicCapabilities.isRegistered(DocumentSymbolsRequest::methodName) + .value_or(capabilities().documentSymbolProvider().value_or(false))) { + TextEditor::IOutlineWidgetFactory::updateOutline(); + } emit initialized(m_serverCapabilities); } diff --git a/src/plugins/projectexplorer/deployconfiguration.cpp b/src/plugins/projectexplorer/deployconfiguration.cpp index 4d16599a12f..fcc0c886bf9 100644 --- a/src/plugins/projectexplorer/deployconfiguration.cpp +++ b/src/plugins/projectexplorer/deployconfiguration.cpp @@ -223,7 +223,10 @@ DeployConfiguration *DeployConfigurationFactory::restore(Target *parent, const Q if (!dc->fromMap(map)) { delete dc; dc = nullptr; + } else if (factory->postRestore()) { + factory->postRestore()(dc, map); } + return dc; } diff --git a/src/plugins/projectexplorer/deployconfiguration.h b/src/plugins/projectexplorer/deployconfiguration.h index 1d9ff883383..66d387291c9 100644 --- a/src/plugins/projectexplorer/deployconfiguration.h +++ b/src/plugins/projectexplorer/deployconfiguration.h @@ -97,6 +97,10 @@ public: void setConfigWidgetCreator(const std::function &configWidgetCreator); void setUseDeploymentDataView(); + using PostRestore = std::function; + void setPostRestore(const PostRestore &postRestore) { m_postRestore = postRestore; } + PostRestore postRestore() const { return m_postRestore; } + protected: using DeployConfigurationCreator = std::function; void setConfigBaseId(Core::Id deployConfigBaseId); @@ -109,6 +113,7 @@ private: QList m_initialSteps; QString m_defaultDisplayName; std::function m_configWidgetCreator; + PostRestore m_postRestore; }; class DefaultDeployConfigurationFactory : public DeployConfigurationFactory diff --git a/src/plugins/projectexplorer/kitmanager.h b/src/plugins/projectexplorer/kitmanager.h index 4cc80230c6d..b3185446475 100644 --- a/src/plugins/projectexplorer/kitmanager.h +++ b/src/plugins/projectexplorer/kitmanager.h @@ -55,7 +55,7 @@ class KitAspectWidget; class KitManager; namespace Internal { -class KitModel; +class KitManagerConfigWidget; } // namespace Internal /** @@ -220,7 +220,7 @@ private: friend class ProjectExplorerPlugin; // for constructor friend class Kit; - friend class Internal::KitModel; + friend class Internal::KitManagerConfigWidget; friend class KitAspect; // for notifyAboutUpdate and self-registration }; diff --git a/src/plugins/projectexplorer/kitmanagerconfigwidget.cpp b/src/plugins/projectexplorer/kitmanagerconfigwidget.cpp index cdd508b0785..f49c61824fc 100644 --- a/src/plugins/projectexplorer/kitmanagerconfigwidget.cpp +++ b/src/plugins/projectexplorer/kitmanagerconfigwidget.cpp @@ -172,6 +172,7 @@ void KitManagerConfigWidget::apply() const auto copyIntoKit = [this](Kit *k) { k->copyFrom(m_modifiedKit.get()); }; if (m_kit) { copyIntoKit(m_kit); + KitManager::notifyAboutUpdate(m_kit); } else { m_isRegistering = true; m_kit = KitManager::registerKit(copyIntoKit); diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index 41f00ea7792..8baf3368107 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -3320,20 +3320,21 @@ void ProjectExplorerPluginPrivate::updateContextMenuActions() m_addExistingFilesAction->setEnabled(supports(AddExistingFile)); m_addExistingDirectoryAction->setEnabled(supports(AddExistingDirectory)); m_renameFileAction->setEnabled(supports(Rename)); - } else if (currentNode->asFileNode()) { + } else if (auto fileNode = currentNode->asFileNode()) { // Enable and show remove / delete in magic ways: // If both are disabled show Remove // If both are enabled show both (can't happen atm) // If only removeFile is enabled only show it // If only deleteFile is enable only show it - bool enableRemove = supports(RemoveFile); + bool isTypeProject = fileNode->fileType() == FileType::Project; + bool enableRemove = !isTypeProject && supports(RemoveFile); m_removeFileAction->setEnabled(enableRemove); - bool enableDelete = supports(EraseFile); + bool enableDelete = !isTypeProject && supports(EraseFile); m_deleteFileAction->setEnabled(enableDelete); m_deleteFileAction->setVisible(enableDelete); m_removeFileAction->setVisible(!enableDelete || enableRemove); - m_renameFileAction->setEnabled(supports(Rename)); + m_renameFileAction->setEnabled(!isTypeProject && supports(Rename)); const bool currentNodeIsTextFile = isTextFile( currentNode->filePath().toString()); m_diffFileAction->setEnabled(DiffService::instance() diff --git a/src/plugins/projectexplorer/userfileaccessor.cpp b/src/plugins/projectexplorer/userfileaccessor.cpp index 838507e544d..f166425a1de 100644 --- a/src/plugins/projectexplorer/userfileaccessor.cpp +++ b/src/plugins/projectexplorer/userfileaccessor.cpp @@ -155,6 +155,18 @@ public: static QVariant process(const QVariant &entry); }; +// Version 21 adds a "make install" step to an existing RemoteLinux deploy configuration +// if and only if such a step would be added when creating a new one. +// See QTCREATORBUG-22689. +class UserFileVersion21Upgrader : public VersionUpgrader +{ +public: + UserFileVersion21Upgrader() : VersionUpgrader(21, "4.10-pre1") { } + QVariantMap upgrade(const QVariantMap &map) final; + + static QVariant process(const QVariant &entry); +}; + } // namespace // @@ -315,6 +327,7 @@ UserFileAccessor::UserFileAccessor(Project *project) : addVersionUpgrader(std::make_unique()); addVersionUpgrader(std::make_unique()); addVersionUpgrader(std::make_unique()); + addVersionUpgrader(std::make_unique()); } Project *UserFileAccessor::project() const @@ -855,6 +868,33 @@ QVariant UserFileVersion20Upgrader::process(const QVariant &entry) } } +QVariantMap UserFileVersion21Upgrader::upgrade(const QVariantMap &map) +{ + return process(map).toMap(); +} + +QVariant UserFileVersion21Upgrader::process(const QVariant &entry) +{ + switch (entry.type()) { + case QVariant::List: + return Utils::transform(entry.toList(), &UserFileVersion21Upgrader::process); + case QVariant::Map: { + QVariantMap entryMap = entry.toMap(); + if (entryMap.value("ProjectExplorer.ProjectConfiguration.Id").toString() + == "DeployToGenericLinux") { + entryMap.insert("_checkMakeInstall", true); + return entryMap; + } + return Utils::transform( + entryMap.toStdMap(), [](const std::pair &item) { + return qMakePair(item.first, UserFileVersion21Upgrader::process(item.second)); + }); + } + default: + return entry; + } +} + #if defined(WITH_TESTS) #include diff --git a/src/plugins/qbsprojectmanager/qbsnodes.cpp b/src/plugins/qbsprojectmanager/qbsnodes.cpp index 285ad6710b9..9490aadc4f8 100644 --- a/src/plugins/qbsprojectmanager/qbsnodes.cpp +++ b/src/plugins/qbsprojectmanager/qbsnodes.cpp @@ -218,17 +218,8 @@ static bool supportsNodeAction(ProjectAction action, const Node *node) const QbsProject * const project = parentQbsProjectNode(node)->project(); if (!project->isProjectEditable()) return false; - - auto equalsNodeFilePath = [node](const QString &str) - { - return str == node->filePath().toString(); - }; - - if (action == RemoveFile || action == Rename) { - if (node->asFileNode()) - return !Utils::contains(project->qbsProject().buildSystemFiles(), equalsNodeFilePath); - } - + if (action == RemoveFile || action == Rename) + return node->asFileNode(); return false; } diff --git a/src/plugins/qtsupport/uicgenerator.cpp b/src/plugins/qtsupport/uicgenerator.cpp index abf8790016f..19248f3b366 100644 --- a/src/plugins/qtsupport/uicgenerator.cpp +++ b/src/plugins/qtsupport/uicgenerator.cpp @@ -67,7 +67,7 @@ Utils::FilePath UicGenerator::command() const QStringList UicGenerator::arguments() const { - return {"-p", source().toString()}; + return {"-p"}; } FileNameToContentsHash UicGenerator::handleProcessFinished(QProcess *process) @@ -87,6 +87,12 @@ FileNameToContentsHash UicGenerator::handleProcessFinished(QProcess *process) return result; } +void UicGenerator::handleProcessStarted(QProcess *process, const QByteArray &sourceContents) +{ + process->write(sourceContents); + process->closeWriteChannel(); +} + FileType UicGeneratorFactory::sourceType() const { return FileType::Form; diff --git a/src/plugins/qtsupport/uicgenerator.h b/src/plugins/qtsupport/uicgenerator.h index 1253e8f1abe..e1c7f013d04 100644 --- a/src/plugins/qtsupport/uicgenerator.h +++ b/src/plugins/qtsupport/uicgenerator.h @@ -43,6 +43,7 @@ protected: Utils::FilePath command() const override; QStringList arguments() const override; ProjectExplorer::FileNameToContentsHash handleProcessFinished(QProcess *process) override; + void handleProcessStarted(QProcess *process, const QByteArray &sourceContents) override; }; class UicGeneratorFactory : public ProjectExplorer::ExtraCompilerFactory diff --git a/src/plugins/remotelinux/remotelinuxdeployconfiguration.cpp b/src/plugins/remotelinux/remotelinuxdeployconfiguration.cpp index 88cd76f66d4..6bdef06dab9 100644 --- a/src/plugins/remotelinux/remotelinuxdeployconfiguration.cpp +++ b/src/plugins/remotelinux/remotelinuxdeployconfiguration.cpp @@ -61,11 +61,19 @@ RemoteLinuxDeployConfigurationFactory::RemoteLinuxDeployConfigurationFactory() "Deploy to Remote Linux Host")); setUseDeploymentDataView(); - addInitialStep(MakeInstallStep::stepId(), [](Target *target) { + const auto needsMakeInstall = [](Target *target) + { const Project * const prj = target->project(); return prj->deploymentKnowledge() == DeploymentKnowledge::Bad && prj->hasMakeInstallEquivalent(); + }; + setPostRestore([needsMakeInstall](DeployConfiguration *dc, const QVariantMap &map) { + // 4.9 -> 4.10. See QTCREATORBUG-22689. + if (map.value("_checkMakeInstall").toBool() && needsMakeInstall(dc->target())) + dc->stepList()->insertStep(0, new MakeInstallStep(dc->stepList())); }); + + addInitialStep(MakeInstallStep::stepId(), needsMakeInstall); addInitialStep(RemoteLinuxCheckForFreeDiskSpaceStep::stepId()); addInitialStep(RemoteLinuxKillAppStep::stepId()); addInitialStep(RsyncDeployStep::stepId(), [](Target *target) { diff --git a/src/plugins/texteditor/ioutlinewidget.h b/src/plugins/texteditor/ioutlinewidget.h index 875181d8f07..ff0efa37b5e 100644 --- a/src/plugins/texteditor/ioutlinewidget.h +++ b/src/plugins/texteditor/ioutlinewidget.h @@ -56,6 +56,8 @@ public: virtual bool supportsEditor(Core::IEditor *editor) const = 0; virtual IOutlineWidget *createWidget(Core::IEditor *editor) = 0; + + static void updateOutline(); }; } // namespace TextEditor diff --git a/src/plugins/texteditor/outlinefactory.cpp b/src/plugins/texteditor/outlinefactory.cpp index 96011f4154a..038cd58cab4 100644 --- a/src/plugins/texteditor/outlinefactory.cpp +++ b/src/plugins/texteditor/outlinefactory.cpp @@ -30,6 +30,7 @@ #include #include +#include #include #include @@ -40,6 +41,7 @@ namespace TextEditor { static QList g_outlineWidgetFactories; +static QPointer g_outlineFactory; IOutlineWidgetFactory::IOutlineWidgetFactory() { @@ -51,6 +53,12 @@ IOutlineWidgetFactory::~IOutlineWidgetFactory() g_outlineWidgetFactories.removeOne(this); } +void IOutlineWidgetFactory::updateOutline() +{ + if (QTC_GUARD(!g_outlineFactory.isNull())) + emit g_outlineFactory->updateOutline(); +} + namespace Internal { OutlineWidgetStack::OutlineWidgetStack(OutlineFactory *factory) : @@ -88,8 +96,10 @@ OutlineWidgetStack::OutlineWidgetStack(OutlineFactory *factory) : m_filterButton->setMenu(m_filterMenu); connect(Core::EditorManager::instance(), &Core::EditorManager::currentEditorChanged, + this, &OutlineWidgetStack::updateEditor); + connect(factory, &OutlineFactory::updateOutline, this, &OutlineWidgetStack::updateCurrentEditor); - updateCurrentEditor(Core::EditorManager::currentEditor()); + updateCurrentEditor(); } OutlineWidgetStack::~OutlineWidgetStack() = default; @@ -159,7 +169,12 @@ void OutlineWidgetStack::updateFilterMenu() m_filterButton->setVisible(!m_filterMenu->actions().isEmpty()); } -void OutlineWidgetStack::updateCurrentEditor(Core::IEditor *editor) +void OutlineWidgetStack::updateCurrentEditor() +{ + updateEditor(Core::EditorManager::currentEditor()); +} + +void OutlineWidgetStack::updateEditor(Core::IEditor *editor) { IOutlineWidget *newWidget = nullptr; @@ -195,6 +210,8 @@ void OutlineWidgetStack::updateCurrentEditor(Core::IEditor *editor) OutlineFactory::OutlineFactory() { + QTC_CHECK(g_outlineFactory.isNull()); + g_outlineFactory = this; setDisplayName(tr("Outline")); setId("Outline"); setPriority(600); diff --git a/src/plugins/texteditor/outlinefactory.h b/src/plugins/texteditor/outlinefactory.h index 00a5732c83f..375caf02ac5 100644 --- a/src/plugins/texteditor/outlinefactory.h +++ b/src/plugins/texteditor/outlinefactory.h @@ -55,7 +55,8 @@ private: QWidget *dummyWidget() const; void updateFilterMenu(); void toggleCursorSynchronization(); - void updateCurrentEditor(Core::IEditor *editor); + void updateEditor(Core::IEditor *editor); + void updateCurrentEditor(); QStackedWidget *m_widgetStack; OutlineFactory *m_factory; @@ -76,6 +77,9 @@ public: Core::NavigationView createWidget() override; void saveSettings(QSettings *settings, int position, QWidget *widget) override; void restoreSettings(QSettings *settings, int position, QWidget *widget) override; + +signals: + void updateOutline(); }; } // namespace Internal diff --git a/tests/auto/debugger/tst_dumpers.cpp b/tests/auto/debugger/tst_dumpers.cpp index 11383b93c55..5b614860595 100644 --- a/tests/auto/debugger/tst_dumpers.cpp +++ b/tests/auto/debugger/tst_dumpers.cpp @@ -5344,11 +5344,11 @@ void tst_Dumpers::dumper_data() + CheckType("t", "char [5]") % CdbEngine + Check("t.0", "[0]", "97", "char") + CheckType("w", "wchar_t [4]") - + Check("ch.0", "[0]", "97", "CHAR") + + Check("ch.0", "[0]", "97", TypeDef("char", "CHAR")) + CheckType("ch", "CHAR [5]") % NoCdbEngine - + CheckType("ch", "CHAR [4]") % CdbEngine - + Check("wch.0", "[0]", "97", "WCHAR") - + CheckType("wch", "WCHAR [4]"); + + CheckType("ch", "char [4]") % CdbEngine + + Check("wch.0", "[0]", "97", TypeDef("wchar_t", "WCHAR")) + + CheckType("wch", TypeDef("wchar_t[4]", "WCHAR [4]")); QTest::newRow("CharPointers")