diff --git a/doc/src/android/androiddev.qdoc b/doc/src/android/androiddev.qdoc index 34cf3f7d6a1..cd928146474 100644 --- a/doc/src/android/androiddev.qdoc +++ b/doc/src/android/androiddev.qdoc @@ -72,10 +72,14 @@ \li \l{http://developer.android.com/sdk/index.html}{Android SDK Tools} - After installing the Tools, you can use the - \l{https://developer.android.com/studio/command-line/sdkmanager.html} - {sdkmanager} to get the API and tools packages required for - development. + The following Android SDK packages and tools are required for + development: + + \list + \li Platform tools + \li Build tools + \li At least one SDK platform + \endlist \li On Windows, you also need the following: @@ -98,13 +102,33 @@ \section1 Setting Up the Development Environment - You must download and install the latest Android NDK and SDK, and update the - SDK to get the build and platform tools needed for development. Since - SDK tools version 25.3.0, \QC, you must use the - \l{https://developer.android.com/studio/command-line/sdkmanager.html} - {sdkmanager} command line tool for SDK package management and the - \l{https://developer.android.com/studio/command-line/avdmanager.html} - {avdmanager} tool for Android Virtual Device (AVD) management. + You must download and install the latest Android NDK and SDK, and then + update or install the tools and packages needed for development. The SDK + tool used to update and install the other SDK tools and packages depends on + the Android SDK Tools version that you have installed: + + \list + + \li Android SDK Tools version 25.2.5, or earlier + + Use the + \l{https://developer.android.com/studio/tools/help/android.html} + {android} tool that comes with the SDK Tools package. For example, + on Ubuntu the following command starts the SDK update: + + \code + ./android update sdk + \endcode + + \li Android SDK Tools version 25.3.0, or later + + Use the + \l{https://developer.android.com/studio/command-line/sdkmanager.html} + {sdkmanager} command line tool for SDK package management and the + \l{https://developer.android.com/studio/command-line/avdmanager.html} + {avdmanager} tool for Android Virtual Device (AVD) management. + + \endlist In addition, you must install Qt for Android as part of Qt 5.2, or later. diff --git a/doc/src/debugger/creator-debugger.qdoc b/doc/src/debugger/creator-debugger.qdoc index 4d3f9228468..f283e31d245 100644 --- a/doc/src/debugger/creator-debugger.qdoc +++ b/doc/src/debugger/creator-debugger.qdoc @@ -1090,7 +1090,7 @@ size = value["_size"].integer() d.putItemCount(size) if d.isExpanded(): - d.putArrayData(value.type[0], value["_array"], size) + d.putArrayData(value["_array"], size, value.type[0]) \endcode \note To create dumper functions usable with both LLDB and GDB backends, @@ -1211,7 +1211,7 @@ \endlist - \li \c{putArrayData(self, type, address, itemCount)} - Creates the + \li \c{putArrayData(self, address, itemCount, type)} - Creates the number of children specified by \c itemCount of the type \c type of an array-like object located at \c address. diff --git a/doc/src/ios/creator-ios-dev.qdoc b/doc/src/ios/creator-ios-dev.qdoc index d3678c0d1c2..5b2aacd0fd8 100644 --- a/doc/src/ios/creator-ios-dev.qdoc +++ b/doc/src/ios/creator-ios-dev.qdoc @@ -32,7 +32,7 @@ \title Connecting iOS Devices - You can connect iOS devices to a Mac computer with a USB cable to + You can connect iOS devices to your local machine with a USB cable to run applications built for them from \QC. To be able to use \QC on \macos, you must install Xcode, and therefore, @@ -52,7 +52,7 @@ {enroll in the Apple Developer Program}. The certificate is copied to the device when you configure the device. - The first time you connect the device to the Mac, you are asked to enable + The first time you connect the device to your local machine, you are asked to enable developer mode on the device. The next time you connect the device, \QC detects it automatically. To disable automatic connections to a device that you do not use for development, select \uicontrol Preferences > @@ -69,7 +69,7 @@ \li Make sure that you have Xcode and Qt for iOS installed. - \li Connect the device to the Mac computer with a USB cable. + \li Connect the device to your local machine with a USB cable. \li Start Xcode to configure the device. @@ -96,6 +96,11 @@ \image qtcreator-build-settings-ios.png "iOS build settings" + \li Select the \uicontrol {Automatically manage signing} check box + to automatically select the provisioning profile and signing + certificate on your local machine that matches the entitlements + and the bundle identifier of the iOS device. + \endlist \li Select \uicontrol Run to specify run settings. @@ -112,13 +117,13 @@ \note If you cannot deploy applications, because a provisioning profile is missing, check that provisioning profiles are listed in Xcode by selecting - \uicontrol Xcode > \uicontrol Preferences > \uicontrol Accounts > - \uicontrol {View Details}. For more information about how to acquire and - install a provisioning profile, see Apple documentation. + \uicontrol Xcode > \uicontrol Preferences > \uicontrol Accounts. For more + information about how to acquire and install a provisioning profile, see + Apple documentation. \section1 Viewing Device Connection Status - When you connect an iOS device to a Mac computer with USB, \QC + When you connect an iOS device to your local machine with USB, \QC automatically detects the device if you have configured it by using Xcode. To view information about the connected device, select \uicontrol Preferences > \uicontrol Devices. @@ -186,7 +191,7 @@ \li In the \uicontrol {Device type} field, select the device type from a list of devices supported by the Xcode version set as current on - the Mac computer. + your local machine. \li In the \uicontrol {OS version} field, select an OS version from a list of OS versions supported by the selected device and the current diff --git a/src/plugins/autotest/gtest/gtestconfiguration.cpp b/src/plugins/autotest/gtest/gtestconfiguration.cpp index 62f910df2e5..7be52a69c12 100644 --- a/src/plugins/autotest/gtest/gtestconfiguration.cpp +++ b/src/plugins/autotest/gtest/gtestconfiguration.cpp @@ -35,7 +35,7 @@ namespace Internal { TestOutputReader *GTestConfiguration::outputReader(const QFutureInterface &fi, QProcess *app) const { - return new GTestOutputReader(fi, app, buildDirectory()); + return new GTestOutputReader(fi, app, buildDirectory(), projectFile()); } QStringList GTestConfiguration::argumentsForTestRunner() const diff --git a/src/plugins/autotest/gtest/gtestoutputreader.cpp b/src/plugins/autotest/gtest/gtestoutputreader.cpp index a455282476c..19712035110 100644 --- a/src/plugins/autotest/gtest/gtestoutputreader.cpp +++ b/src/plugins/autotest/gtest/gtestoutputreader.cpp @@ -25,6 +25,8 @@ #include "gtestoutputreader.h" #include "gtestresult.h" +#include "../testtreemodel.h" +#include "../testtreeitem.h" #include #include @@ -39,9 +41,11 @@ static QString constructSourceFilePath(const QString &path, const QString &fileP } GTestOutputReader::GTestOutputReader(const QFutureInterface &futureInterface, - QProcess *testApplication, const QString &buildDirectory) + QProcess *testApplication, const QString &buildDirectory, + const QString &projectFile) : TestOutputReader(futureInterface, testApplication, buildDirectory) , m_executable(testApplication ? testApplication->program() : QString()) + , m_projectFile(projectFile) { } @@ -94,8 +98,9 @@ void GTestOutputReader::processOutput(const QByteArray &outputLine) m_futureInterface.reportResult(TestResultPtr(testResult)); m_currentTestName.clear(); m_currentTestSet.clear(); + m_normalizedCurrentTestSet.clear(); } else if (newTestStarts.exactMatch(line)) { - m_currentTestName = newTestStarts.cap(1); + setCurrentTestName(newTestStarts.cap(1)); TestResultPtr testResult = TestResultPtr(createDefaultResult()); testResult->setResult(Result::MessageTestCaseStart); if (m_iteration > 1) { @@ -106,7 +111,7 @@ void GTestOutputReader::processOutput(const QByteArray &outputLine) } m_futureInterface.reportResult(testResult); } else if (newTestSetStarts.exactMatch(line)) { - m_currentTestSet = newTestSetStarts.cap(1); + setCurrentTestSet(newTestSetStarts.cap(1)); TestResultPtr testResult = TestResultPtr(new GTestResult); testResult->setResult(Result::MessageCurrentTest); testResult->setDescription(tr("Entering test set %1").arg(m_currentTestSet)); @@ -155,13 +160,87 @@ void GTestOutputReader::processOutput(const QByteArray &outputLine) } } +void GTestOutputReader::setCurrentTestSet(const QString &testSet) +{ + m_currentTestSet = testSet; + m_normalizedCurrentTestSet = normalizeName(testSet); +} + +void GTestOutputReader::setCurrentTestName(const QString &testName) +{ + m_currentTestName = testName; + m_normalizedTestName = normalizeTestName(testName); +} + +QString GTestOutputReader::normalizeName(const QString &name) const +{ + static QRegExp parameterIndex("/\\d+"); + + QString nameWithoutParameterIndices = name; + nameWithoutParameterIndices.remove(parameterIndex); + + return nameWithoutParameterIndices.split('/').last(); +} + +QString GTestOutputReader::normalizeTestName(const QString &testname) const +{ + QString nameWithoutTypeParam = testname.split(',').first(); + + return normalizeName(nameWithoutTypeParam); +} + GTestResult *GTestOutputReader::createDefaultResult() const { GTestResult *result = new GTestResult(m_executable, m_currentTestName); result->setTestSetName(m_currentTestSet); result->setIteration(m_iteration); + + const TestTreeItem *testItem = findTestTreeItemForCurrentLine(); + if (testItem && testItem->line()) { + result->setFileName(testItem->filePath()); + result->setLine(static_cast(testItem->line())); + } + return result; } +const TestTreeItem *GTestOutputReader::findTestTreeItemForCurrentLine() const +{ + const auto item = TestTreeModel::instance()->findNonRooItem([&](const Utils::TreeItem *item) { + const TestTreeItem &treeItem = static_cast(*item); + return matches(treeItem); + }); + + return static_cast(item); +} + +bool GTestOutputReader::matches(const TestTreeItem &treeItem) const +{ + if (treeItem.proFile() != m_projectFile) + return false; + + if (m_currentTestSet.isEmpty()) + return matchesTestCase(treeItem); + + return matchesTestFunctionOrSet(treeItem); +} + +bool GTestOutputReader::matchesTestFunctionOrSet(const TestTreeItem &treeItem) const +{ + if (treeItem.type() != TestTreeItem::TestFunctionOrSet) + return false; + + const QString testItemTestSet = treeItem.parentItem()->name() + '.' + treeItem.name(); + return testItemTestSet == m_normalizedCurrentTestSet; +} + +bool GTestOutputReader::matchesTestCase(const TestTreeItem &treeItem) const +{ + if (treeItem.type() != TestTreeItem::TestCase) + return false; + + return treeItem.name() == m_normalizedTestName; +} + } // namespace Internal } // namespace Autotest diff --git a/src/plugins/autotest/gtest/gtestoutputreader.h b/src/plugins/autotest/gtest/gtestoutputreader.h index 5cedffed006..e46e29fcd3f 100644 --- a/src/plugins/autotest/gtest/gtestoutputreader.h +++ b/src/plugins/autotest/gtest/gtestoutputreader.h @@ -33,6 +33,7 @@ namespace Autotest { namespace Internal { class GTestResult; +class TestTreeItem; class GTestOutputReader : public TestOutputReader { @@ -40,16 +41,29 @@ class GTestOutputReader : public TestOutputReader public: GTestOutputReader(const QFutureInterface &futureInterface, - QProcess *testApplication, const QString &buildDirectory); + QProcess *testApplication, const QString &buildDirectory, + const QString &projectFile); protected: void processOutput(const QByteArray &outputLine) override; private: + void setCurrentTestSet(const QString &testSet); + void setCurrentTestName(const QString &testName); + QString normalizeName(const QString &name) const; + QString normalizeTestName(const QString &testname) const; GTestResult *createDefaultResult() const; + const TestTreeItem *findTestTreeItemForCurrentLine() const; + bool matches(const TestTreeItem &treeItem) const; + bool matchesTestFunctionOrSet(const TestTreeItem &treeItem) const; + bool matchesTestCase(const TestTreeItem &treeItem) const; + QString m_executable; + QString m_projectFile; QString m_currentTestName; + QString m_normalizedTestName; QString m_currentTestSet; + QString m_normalizedCurrentTestSet; QString m_description; int m_iteration = 1; }; diff --git a/src/plugins/autotest/testconfiguration.h b/src/plugins/autotest/testconfiguration.h index 8d620859828..248b9aaeb76 100644 --- a/src/plugins/autotest/testconfiguration.h +++ b/src/plugins/autotest/testconfiguration.h @@ -73,6 +73,7 @@ public: QString executableFilePath() const; QString workingDirectory() const; QString buildDirectory() const { return m_buildDir; } + QString projectFile() const { return m_projectFile; } QString displayName() const { return m_displayName; } Utils::Environment environment() const { return m_environment; } ProjectExplorer::Project *project() const { return m_project.data(); } diff --git a/src/plugins/clangrefactoring/clangqueryexampletexteditorwidget.cpp b/src/plugins/clangrefactoring/clangqueryexampletexteditorwidget.cpp index 19273d5edea..79ff5576b92 100644 --- a/src/plugins/clangrefactoring/clangqueryexampletexteditorwidget.cpp +++ b/src/plugins/clangrefactoring/clangqueryexampletexteditorwidget.cpp @@ -36,6 +36,7 @@ ClangQueryExampleTextEditorWidget::ClangQueryExampleTextEditorWidget(QWidget *pa { m_syntaxHighlighter = new ClangQueryExampleHighlighter; textDocument()->setSyntaxHighlighter(m_syntaxHighlighter); + textDocument()->setPlainText("class Foo {\n void function() { int local; }\n int field;\n};"); } ClangQueryExampleHighlighter *ClangQueryExampleTextEditorWidget::syntaxHighlighter() const diff --git a/src/plugins/clangrefactoring/clangqueryprojectsfindfilter.ui b/src/plugins/clangrefactoring/clangqueryprojectsfindfilter.ui index 9fbad01f0bf..819fae485db 100644 --- a/src/plugins/clangrefactoring/clangqueryprojectsfindfilter.ui +++ b/src/plugins/clangrefactoring/clangqueryprojectsfindfilter.ui @@ -6,14 +6,29 @@ 0 0 - 1241 - 471 + 512 + 390 + + + 1 + 1 + + + + + 512 + 0 + + Form + + QLayout::SetMinimumSize + 0 @@ -30,20 +45,32 @@ - 0 + 1 3 + + class Foo { void function() { int x; } }; + - 0 + 1 1 + + + 700 + 0 + + + + functionDecl() + diff --git a/src/plugins/clangrefactoring/clangquerytexteditorwidget.cpp b/src/plugins/clangrefactoring/clangquerytexteditorwidget.cpp index 2d0552680c9..e24d6eab5e4 100644 --- a/src/plugins/clangrefactoring/clangquerytexteditorwidget.cpp +++ b/src/plugins/clangrefactoring/clangquerytexteditorwidget.cpp @@ -38,6 +38,7 @@ ClangQueryTextEditorWidget::ClangQueryTextEditorWidget(QWidget *parent) m_hoverHandler(std::make_unique(m_syntaxHighlighter)) { textDocument()->setSyntaxHighlighter(m_syntaxHighlighter); + textDocument()->setPlainText("functionDecl()"); addHoverHandler(m_hoverHandler.get()); } diff --git a/src/plugins/coreplugin/locator/locatorwidget.cpp b/src/plugins/coreplugin/locator/locatorwidget.cpp index 63abc858fc5..dcacc1a4f1a 100644 --- a/src/plugins/coreplugin/locator/locatorwidget.cpp +++ b/src/plugins/coreplugin/locator/locatorwidget.cpp @@ -746,7 +746,8 @@ QList LocatorWidget::filtersFor(const QString &text, QString & break; } const int whiteSpace = text.indexOf(QChar::Space, firstNonSpace); - const QList filters = Locator::filters(); + const QList filters = Utils::filtered(Locator::filters(), + &ILocatorFilter::isEnabled); if (whiteSpace >= 0) { const QString prefix = text.mid(firstNonSpace, whiteSpace - firstNonSpace).toLower(); QList prefixFilters; diff --git a/src/plugins/projectexplorer/jsonwizard/jsonsummarypage.cpp b/src/plugins/projectexplorer/jsonwizard/jsonsummarypage.cpp index 5f02bc7779d..27b4b682ab5 100644 --- a/src/plugins/projectexplorer/jsonwizard/jsonsummarypage.cpp +++ b/src/plugins/projectexplorer/jsonwizard/jsonsummarypage.cpp @@ -31,6 +31,8 @@ #include "../projectnodes.h" #include "../session.h" +#include "../projecttree.h" + #include #include @@ -125,10 +127,19 @@ void JsonSummaryPage::initializePage() }); } - Node *contextNode = m_wizard->value(QLatin1String(Constants::PREFERRED_PROJECT_NODE)) - .value(); - initializeProjectTree(contextNode, files, kind, - isProject ? AddSubProject : AddNewFile); + // Use static cast from void * to avoid qobject_cast (which needs a valid object) in value() + // in the following code: + auto contextNode = findWizardContextNode(static_cast(m_wizard->value(Constants::PREFERRED_PROJECT_NODE).value())); + const ProjectAction currentAction = isProject ? AddSubProject : AddNewFile; + + initializeProjectTree(contextNode, files, kind, currentAction); + + // Refresh combobox on project tree changes: + connect(ProjectTree::instance(), &ProjectTree::treeChanged, + this, [this, files, kind, currentAction]() { + initializeProjectTree(findWizardContextNode(currentNode()), files, kind, currentAction); + }); + bool hideProjectUi = JsonWizard::boolFromVariant(m_hideProjectUiValue, m_wizard->expander()); setProjectUiVisible(!hideProjectUi); @@ -207,6 +218,23 @@ void JsonSummaryPage::summarySettingsHaveChanged() updateProjectData(currentNode()); } +Node *JsonSummaryPage::findWizardContextNode(Node *contextNode) const +{ + if (contextNode && !ProjectTree::hasNode(contextNode)) { + contextNode = nullptr; + + // Static cast from void * to avoid qobject_cast (which needs a valid object) in value(). + auto project = static_cast(m_wizard->value(Constants::PROJECT_POINTER).value()); + if (SessionManager::projects().contains(project) && project->rootProjectNode()) { + const QString path = m_wizard->value(Constants::PREFERRED_PROJECT_NODE_PATH).toString(); + contextNode = project->rootProjectNode()->findNode([path](const Node *n) { + return path == n->filePath().toString(); + }); + } + } + return contextNode; +} + void JsonSummaryPage::updateFileList() { m_fileList = m_wizard->generateFileList(); diff --git a/src/plugins/projectexplorer/jsonwizard/jsonsummarypage.h b/src/plugins/projectexplorer/jsonwizard/jsonsummarypage.h index 1e0bd1800f1..2fa134a38f7 100644 --- a/src/plugins/projectexplorer/jsonwizard/jsonsummarypage.h +++ b/src/plugins/projectexplorer/jsonwizard/jsonsummarypage.h @@ -33,6 +33,7 @@ namespace ProjectExplorer { class FolderNode; +class Node; // Documentation inside. class JsonSummaryPage : public Internal::ProjectWizardPage @@ -52,6 +53,7 @@ public: void summarySettingsHaveChanged(); private: + Node *findWizardContextNode(Node *contextNode) const; void updateFileList(); void updateProjectData(FolderNode *node); diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index b4ebdd6ffa0..cd2a3e10631 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -3132,10 +3132,14 @@ void ProjectExplorerPluginPrivate::addNewFile() QString location = directoryFor(currentNode); QVariantMap map; - map.insert(QLatin1String(Constants::PREFERRED_PROJECT_NODE), QVariant::fromValue(currentNode)); - if (ProjectTree::currentProject()) { - QList profileIds = Utils::transform(ProjectTree::currentProject()->targets(), &Target::id); + // store void pointer to avoid QVariant to use qobject_cast, which might core-dump when trying + // to access meta data on an object that get deleted in the meantime: + map.insert(QLatin1String(Constants::PREFERRED_PROJECT_NODE), QVariant::fromValue(static_cast(currentNode))); + map.insert(Constants::PREFERRED_PROJECT_NODE_PATH, currentNode->filePath().toString()); + if (Project *p = ProjectTree::currentProject()) { + QList profileIds = Utils::transform(p->targets(), &Target::id); map.insert(QLatin1String(Constants::PROJECT_KIT_IDS), QVariant::fromValue(profileIds)); + map.insert(Constants::PROJECT_POINTER, QVariant::fromValue(static_cast(p))); } ICore::showNewItemDialog(tr("New File", "Title of dialog"), Utils::filtered(IWizardFactory::allWizardFactories(), @@ -3204,7 +3208,8 @@ void ProjectExplorerPluginPrivate::addExistingDirectory() void ProjectExplorerPlugin::addExistingFiles(FolderNode *folderNode, const QStringList &filePaths) { - if (!folderNode) // can happen when project is not yet parsed + // can happen when project is not yet parsed or finished parsing while the dialog was open: + if (!folderNode || !ProjectTree::hasNode(folderNode)) return; const QString dir = directoryFor(folderNode); diff --git a/src/plugins/projectexplorer/projectexplorerconstants.h b/src/plugins/projectexplorer/projectexplorerconstants.h index aa9f92e5b64..f0f4b2762af 100644 --- a/src/plugins/projectexplorer/projectexplorerconstants.h +++ b/src/plugins/projectexplorer/projectexplorerconstants.h @@ -127,6 +127,8 @@ const char IMPORT_WIZARD_CATEGORY_DISPLAY[] = QT_TRANSLATE_NOOP("ProjectExplorer // Wizard extra values const char PREFERRED_PROJECT_NODE[] = "ProjectExplorer.PreferredProjectNode"; +const char PREFERRED_PROJECT_NODE_PATH[] = "ProjectExplorer.PreferredProjectPath"; +const char PROJECT_POINTER[] = "ProjectExplorer.Project"; const char PROJECT_KIT_IDS[] = "ProjectExplorer.Profile.Ids"; // Build step lists ids: diff --git a/src/plugins/projectexplorer/projectfilewizardextension.cpp b/src/plugins/projectexplorer/projectfilewizardextension.cpp index c7bf50e2467..e6bf826e7b2 100644 --- a/src/plugins/projectexplorer/projectfilewizardextension.cpp +++ b/src/plugins/projectexplorer/projectfilewizardextension.cpp @@ -41,6 +41,7 @@ #include #include #include +#include #include #include # @@ -120,7 +121,8 @@ void ProjectFileWizardExtension::firstExtensionPageShown( QStringList filePaths; ProjectAction projectAction; - if (m_context->wizard->kind()== IWizardFactory::ProjectWizard) { + const IWizardFactory::WizardKind kind = m_context->wizard->kind(); + if (kind == IWizardFactory::ProjectWizard) { projectAction = AddSubProject; filePaths << generatedProjectFilePath(files); } else { @@ -128,13 +130,38 @@ void ProjectFileWizardExtension::firstExtensionPageShown( filePaths = Utils::transform(files, &GeneratedFile::path); } - Node *contextNode = extraValues.value(QLatin1String(Constants::PREFERRED_PROJECT_NODE)).value(); + // Static cast from void * to avoid qobject_cast (which needs a valid object) in value(). + auto contextNode = static_cast(extraValues.value(QLatin1String(Constants::PREFERRED_PROJECT_NODE)).value()); + auto project = static_cast(extraValues.value(Constants::PROJECT_POINTER).value()); + const QString path = extraValues.value(Constants::PREFERRED_PROJECT_NODE_PATH).toString(); - m_context->page->initializeProjectTree(contextNode, filePaths, m_context->wizard->kind(), + m_context->page->initializeProjectTree(findWizardContextNode(contextNode, project, path), + filePaths, m_context->wizard->kind(), projectAction); + // Refresh combobox on project tree changes: + connect(ProjectTree::instance(), &ProjectTree::treeChanged, + m_context->page, [this, project, path, filePaths, kind, projectAction]() { + m_context->page->initializeProjectTree( + findWizardContextNode(m_context->page->currentNode(), project, path), filePaths, + kind, projectAction); + }); + m_context->page->initializeVersionControls(); } +Node *ProjectFileWizardExtension::findWizardContextNode(Node *contextNode, Project *project, + const QString &path) +{ + if (contextNode && !ProjectTree::hasNode(contextNode)) { + if (SessionManager::projects().contains(project) && project->rootProjectNode()) { + contextNode = project->rootProjectNode()->findNode([path](const Node *n) { + return path == n->filePath().toString(); + }); + } + } + return contextNode; +} + QList ProjectFileWizardExtension::extensionPages(const IWizardFactory *wizard) { if (!m_context) diff --git a/src/plugins/projectexplorer/projectfilewizardextension.h b/src/plugins/projectexplorer/projectfilewizardextension.h index fe9d3f8d92f..df1c61a6508 100644 --- a/src/plugins/projectexplorer/projectfilewizardextension.h +++ b/src/plugins/projectexplorer/projectfilewizardextension.h @@ -31,6 +31,8 @@ namespace ProjectExplorer { class FolderNode; +class Node; +class Project; namespace Internal { @@ -52,6 +54,7 @@ public slots: void firstExtensionPageShown(const QList &files, const QVariantMap &extraValues) override; private: + Node *findWizardContextNode(Node *contextNode, Project *project, const QString &path); bool processProject(const QList &files, bool *removeOpenProjectAttribute, QString *errorMessage); diff --git a/src/plugins/projectexplorer/projecttree.cpp b/src/plugins/projectexplorer/projecttree.cpp index 4461b20c79d..5e76ed15362 100644 --- a/src/plugins/projectexplorer/projecttree.cpp +++ b/src/plugins/projectexplorer/projecttree.cpp @@ -72,10 +72,15 @@ ProjectTree::ProjectTree(QObject *parent) : QObject(parent) connect(SessionManager::instance(), &SessionManager::projectAdded, this, &ProjectTree::sessionChanged); + connect(SessionManager::instance(), &SessionManager::projectAdded, + this, &ProjectTree::treeChanged); connect(SessionManager::instance(), &SessionManager::projectRemoved, this, &ProjectTree::sessionChanged); + connect(SessionManager::instance(), &SessionManager::projectRemoved, + this, &ProjectTree::treeChanged); connect(SessionManager::instance(), &SessionManager::startupProjectChanged, this, &ProjectTree::sessionChanged); + connect(this, &ProjectTree::subtreeChanged, this, &ProjectTree::treeChanged); } ProjectTree::~ProjectTree() @@ -253,7 +258,8 @@ void ProjectTree::updateContext() void ProjectTree::emitSubtreeChanged(FolderNode *node) { - emit s_instance->subtreeChanged(node); + if (hasNode(node)) + emit s_instance->subtreeChanged(node); } void ProjectTree::collapseAll() @@ -369,6 +375,13 @@ void ProjectTree::applyTreeManager(FolderNode *folder) f(folder); } +bool ProjectTree::hasNode(const Node *node) +{ + return Utils::contains(SessionManager::projects(), [node](const Project *p) { + return p && p->rootProjectNode() && p->rootProjectNode()->findNode([node](const Node *n) { return n == node; }); + }); +} + void ProjectTree::hideContextMenu() { m_focusForContextMenu = nullptr; diff --git a/src/plugins/projectexplorer/projecttree.h b/src/plugins/projectexplorer/projecttree.h index 87bcb7216cd..3d880d8355b 100644 --- a/src/plugins/projectexplorer/projecttree.h +++ b/src/plugins/projectexplorer/projecttree.h @@ -68,6 +68,8 @@ public: static void registerTreeManager(const TreeManagerFunction &treeChange); static void applyTreeManager(FolderNode *folder); + static bool hasNode(const Node *node); + void collapseAll(); // for nodes to emit signals, do not call unless you are a node @@ -83,6 +85,9 @@ signals: void aboutToShowContextMenu(ProjectExplorer::Project *project, ProjectExplorer::Node *node); + // Emitted on any change to the tree + void treeChanged(); + private: void sessionChanged(); void update(); diff --git a/src/plugins/qmldesigner/components/formeditor/abstractformeditortool.cpp b/src/plugins/qmldesigner/components/formeditor/abstractformeditortool.cpp index 291f17fad50..2cf53f0e79c 100644 --- a/src/plugins/qmldesigner/components/formeditor/abstractformeditortool.cpp +++ b/src/plugins/qmldesigner/components/formeditor/abstractformeditortool.cpp @@ -152,8 +152,8 @@ bool AbstractFormEditorTool::selectedItemCursorInMovableArea(const QPointF &pos) QRectF boundingRect = boundingRectInSceneSpace.boundingRect(); QRectF innerRect = boundingRect; - innerRect.adjust(10, 10, -10, -10); - boundingRect.adjust(-10, -20, 10, 10); + innerRect.adjust(2, 2, -2, -2); + boundingRect.adjust(-2, -20, 2, 2); return !innerRect.contains(pos) && boundingRect.contains(pos); } diff --git a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp index 45d7c2891a2..0b6c3cc6ae8 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp +++ b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp @@ -224,14 +224,14 @@ QVariant NavigatorTreeModel::data(const QModelIndex &index, int role) const if (role == Qt::CheckStateRole) return currentQmlObjectNode.isAliasExported() ? Qt::Checked : Qt::Unchecked; else if (role == Qt::ToolTipRole) - return tr("Toggles the visibility of this item in the form editor.\n" - "This is independent of the visibility property in QML."); + return tr("Toggles whether this item is exported as an " + "alias property of the root item."); } else if (index.column() == 2) { //visible if (role == Qt::CheckStateRole) return m_view->isNodeInvisible(modelNode) ? Qt::Unchecked : Qt::Checked; else if (role == Qt::ToolTipRole) - return tr("Toggles whether this item is exported as an " - "alias property of the root item."); + return tr("Toggles the visibility of this item in the form editor.\n" + "This is independent of the visibility property in QML."); } return QVariant(); diff --git a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp index 7bba1c88e6e..0af1d0a2344 100644 --- a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp +++ b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp @@ -792,7 +792,6 @@ static bool isBlacklistImport(const ImportKey &importKey) || importKey.libraryQualifiedPath() == QStringLiteral("Qt.WebSockets") || importKey.libraryQualifiedPath() == QStringLiteral("QtWebkit") || importKey.libraryQualifiedPath() == QStringLiteral("QtLocation") - || importKey.libraryQualifiedPath() == QStringLiteral("QtWebEngine") || importKey.libraryQualifiedPath() == QStringLiteral("QtWebChannel") || importKey.libraryQualifiedPath() == QStringLiteral("QtWinExtras") || importKey.libraryQualifiedPath() == QStringLiteral("QtPurchasing") diff --git a/src/plugins/qmlprofiler/tests/localqmlprofilerrunner_test.cpp b/src/plugins/qmlprofiler/tests/localqmlprofilerrunner_test.cpp index 6275067d892..53489eaee8b 100644 --- a/src/plugins/qmlprofiler/tests/localqmlprofilerrunner_test.cpp +++ b/src/plugins/qmlprofiler/tests/localqmlprofilerrunner_test.cpp @@ -92,8 +92,8 @@ void LocalQmlProfilerRunnerTest::testRunner() runControl->initiateStart(); - QTRY_COMPARE_WITH_TIMEOUT(startCount, 1, 10000); - QTRY_VERIFY_WITH_TIMEOUT(!started, 10000); + QTRY_COMPARE_WITH_TIMEOUT(startCount, 1, 20000); + QTRY_VERIFY_WITH_TIMEOUT(!started, 20000); QCOMPARE(stopCount, 1); QCOMPARE(runCount, 0); @@ -113,8 +113,8 @@ void LocalQmlProfilerRunnerTest::testRunner() connectRunner(); runControl->initiateStart(); - QTRY_VERIFY_WITH_TIMEOUT(running, 10000); - QTRY_VERIFY_WITH_TIMEOUT(!running, 10000); + QTRY_VERIFY_WITH_TIMEOUT(running, 20000); + QTRY_VERIFY_WITH_TIMEOUT(!running, 20000); QCOMPARE(startCount, 2); QCOMPARE(stopCount, 2); QCOMPARE(runCount, 1); @@ -133,9 +133,9 @@ void LocalQmlProfilerRunnerTest::testRunner() connectRunner(); runControl->initiateStart(); - QTRY_VERIFY_WITH_TIMEOUT(running, 10000); + QTRY_VERIFY_WITH_TIMEOUT(running, 20000); runControl->initiateStop(); - QTRY_VERIFY_WITH_TIMEOUT(!running, 10000); + QTRY_VERIFY_WITH_TIMEOUT(!running, 20000); QCOMPARE(startCount, 3); QCOMPARE(stopCount, 3); QCOMPARE(runCount, 2); diff --git a/src/plugins/qtsupport/qtcreator_tutorials.xml b/src/plugins/qtsupport/qtcreator_tutorials.xml index 003ee887554..d018570278c 100644 --- a/src/plugins/qtsupport/qtcreator_tutorials.xml +++ b/src/plugins/qtsupport/qtcreator_tutorials.xml @@ -34,7 +34,10 @@ qt creator,embedded,device creation - + + + qt creator,embedded,device creation + qt creator,qt quick,embedded diff --git a/src/plugins/resourceeditor/resourcenode.cpp b/src/plugins/resourceeditor/resourcenode.cpp index 4fa45e21848..0ca93ea5b5a 100644 --- a/src/plugins/resourceeditor/resourcenode.cpp +++ b/src/plugins/resourceeditor/resourcenode.cpp @@ -270,6 +270,7 @@ ResourceTopLevelNode::ResourceTopLevelNode(const FileName &filePath, bool genera setIsGenerated(generated); setIcon(FileIconProvider::icon(filePath.toString())); setPriority(Node::DefaultFilePriority); + setListInProject(true); if (!filePath.isEmpty()) { QFileInfo fi = filePath.toFileInfo(); if (fi.isFile() && fi.isReadable()) { diff --git a/src/shared/qbs b/src/shared/qbs index 0f647796788..7d85fed02c1 160000 --- a/src/shared/qbs +++ b/src/shared/qbs @@ -1 +1 @@ -Subproject commit 0f647796788494947632c0874931e4d84bccad46 +Subproject commit 7d85fed02c14d87fbea8a2573f947d2a1ce940a8 diff --git a/src/tools/sdktool/sdktool.qbs b/src/tools/sdktool/sdktool.qbs index a904956eac2..60095bdb879 100644 --- a/src/tools/sdktool/sdktool.qbs +++ b/src/tools/sdktool/sdktool.qbs @@ -72,4 +72,13 @@ QtcTool { "savefile.cpp", "savefile.h" ] } + Group { + name: "Utils/macOS" + condition: qbs.targetOS.contains("macos") + prefix: libsDir + "/utils/" + files: [ + "fileutils_mac.h", + "fileutils_mac.mm", + ] + } } diff --git a/tests/auto/utils/stringutils/tst_stringutils.cpp b/tests/auto/utils/stringutils/tst_stringutils.cpp index 5a5933b323c..6fbdfb4326c 100644 --- a/tests/auto/utils/stringutils/tst_stringutils.cpp +++ b/tests/auto/utils/stringutils/tst_stringutils.cpp @@ -233,6 +233,16 @@ void tst_StringUtils::testParseUsedPortFromNetstatOutput_data() // Linux QTest::newRow("Linux1") << "sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt ..." << -1; QTest::newRow("Linux2") << "0: 00000000:2805 00000000:0000 0A 00000000:00000000 00:00000000 00000000 ..." << 10245; + + // Mac + QTest::newRow("Mac1") << "Active Internet connections (including servers)" << -1; + QTest::newRow("Mac2") << "Proto Recv-Q Send-Q Local Address Foreign Address (state)" << -1; + QTest::newRow("Mac3") << "tcp4 0 0 192.168.1.12.55687 88.198.14.66.443 ESTABLISHED" << 55687; + QTest::newRow("Mac4") << "tcp6 0 0 2a01:e34:ee42:d0.55684 2a02:26f0:ff::5c.443 ESTABLISHED" << 55684; + QTest::newRow("Mac5") << "tcp4 0 0 *.631 *.* LISTEN" << 631; + QTest::newRow("Mac6") << "tcp6 0 0 *.631 *.* LISTEN" << 631; + QTest::newRow("Mac7") << "udp4 0 0 192.168.79.1.123 *.*" << 123; + QTest::newRow("Mac9") << "udp4 0 0 192.168.8.1.123 *.*" << 123; } QTEST_MAIN(tst_StringUtils) diff --git a/tests/system/shared/editor_utils.py b/tests/system/shared/editor_utils.py index 72a844fec37..e5a652aae96 100644 --- a/tests/system/shared/editor_utils.py +++ b/tests/system/shared/editor_utils.py @@ -380,13 +380,13 @@ def openDocument(treeElement): except: treeElement = addBranchWildcardToRoot(treeElement) item = waitForObjectItem(navigator, treeElement) + expected = str(item.text).split("/")[-1] for _ in range(2): # Expands items as needed what might make scrollbars appear. # These might cover the item to click. # In this case, do it again to hit the item then. doubleClickItem(navigator, treeElement, 5, 5, 0, Qt.LeftButton) mainWindow = waitForObject(":Qt Creator_Core::Internal::MainWindow") - expected = str(item.text).split("/")[-1] if waitFor("str(mainWindow.windowTitle).startswith(expected + ' ')", 5000): return True test.log("Expected file (%s) was not being opened in openDocument()" % expected)