diff --git a/src/plugins/autotest/gtest/gtesttreeitem.cpp b/src/plugins/autotest/gtest/gtesttreeitem.cpp index 92d24bc5a39..3b2c680fe98 100644 --- a/src/plugins/autotest/gtest/gtesttreeitem.cpp +++ b/src/plugins/autotest/gtest/gtesttreeitem.cpp @@ -29,6 +29,7 @@ #include #include +#include #include namespace Autotest { @@ -293,11 +294,16 @@ QSet GTestTreeItem::internalTargets() const QSet result; const auto cppMM = CppTools::CppModelManager::instance(); const auto projectInfo = cppMM->projectInfo(ProjectExplorer::SessionManager::startupProject()); + const QString file = filePath(); for (const CppTools::ProjectPart::Ptr projectPart : projectInfo.projectParts()) { - if (projectPart->buildTargetType != CppTools::ProjectPart::Executable) - continue; - if (projectPart->projectFile == proFile()) + if (projectPart->projectFile == proFile() + && Utils::anyOf(projectPart->files, [&file] (const CppTools::ProjectFile &pf) { + return pf.path == file; + })) { result.insert(projectPart->buildSystemTarget + '|' + projectPart->projectFile); + if (projectPart->buildTargetType != CppTools::ProjectPart::Executable) + result.unite(TestTreeItem::dependingInternalTargets(cppMM, file)); + } } return result; } diff --git a/src/plugins/autotest/testconfiguration.cpp b/src/plugins/autotest/testconfiguration.cpp index 396fbb4f1c8..b4af50e8a99 100644 --- a/src/plugins/autotest/testconfiguration.cpp +++ b/src/plugins/autotest/testconfiguration.cpp @@ -72,11 +72,66 @@ static QString ensureExeEnding(const QString& file) return Utils::HostOsInfo::withExecutableSuffix(file); } +void TestConfiguration::completeTestInformation(ProjectExplorer::RunConfiguration *rc, + TestRunMode runMode) +{ + QTC_ASSERT(rc, return); + Project *project = SessionManager::startupProject(); + if (!project) + return; + + Target *target = project->activeTarget(); + if (!target) + return; + + if (!Utils::findOr(target->runConfigurations(), nullptr, + [&rc] (RunConfiguration *config) { return rc == config; })) { + return; + } + + Runnable runnable = rc->runnable(); + if (!runnable.is()) + return; + m_runnable = runnable.as(); + m_displayName = rc->displayName(); + m_project = rc->project(); + + const QString buildSystemTarget = rc->buildSystemTarget(); + BuildTargetInfo targetInfo + = Utils::findOrDefault(target->applicationTargets().list, + [&buildSystemTarget] (const BuildTargetInfo &bti) { + return bti.targetName == buildSystemTarget; + }); + if (!targetInfo.targetFilePath.isEmpty()) + m_runnable.executable = ensureExeEnding(targetInfo.targetFilePath.toString()); + + QString buildBase; + if (auto buildConfig = target->activeBuildConfiguration()) { + buildBase = buildConfig->buildDirectory().toString(); + const QString projBase = m_project->projectDirectory().toString(); + if (m_projectFile.startsWith(projBase)) + m_buildDir = QFileInfo(buildBase + m_projectFile.mid(projBase.length())).absolutePath(); + } + if (runMode == TestRunMode::Debug || runMode == TestRunMode::DebugWithoutDeploy) + m_runConfig = new TestRunConfiguration(rc->target(), this); +} + void TestConfiguration::completeTestInformation(TestRunMode runMode) { QTC_ASSERT(!m_projectFile.isEmpty(), return); QTC_ASSERT(!m_buildTargets.isEmpty(), return); + if (m_origRunConfig) { + qCDebug(LOG) << "Using run configuration specified by user or found by first call"; + completeTestInformation(m_origRunConfig, runMode); + if (hasExecutable()) { + qCDebug(LOG) << "Completed.\nRunnable:" << m_runnable.executable + << "\nArgs:" << m_runnable.commandLineArguments + << "\nWorking directory:" << m_runnable.workingDirectory; + return; + } + qCDebug(LOG) << "Failed to complete - using 'normal' way."; + } Project *project = SessionManager::startupProject(); if (!project) return; @@ -90,7 +145,7 @@ void TestConfiguration::completeTestInformation(TestRunMode runMode) const QSet buildSystemTargets = m_buildTargets; qCDebug(LOG) << "BuildSystemTargets\n " << buildSystemTargets; - const BuildTargetInfo targetInfo + BuildTargetInfo targetInfo = Utils::findOrDefault(target->applicationTargets().list, [&buildSystemTargets] (const BuildTargetInfo &bti) { return Utils::anyOf(buildSystemTargets, [&bti](const QString &b) { @@ -101,12 +156,22 @@ void TestConfiguration::completeTestInformation(TestRunMode runMode) && targWithProjectFile.at(1).startsWith(bti.projectFilePath.toString()); }); }); - if (!QTC_GUARD(!targetInfo.targetFilePath.isEmpty())) { // empty if BTI default created + // we might end up with an empty targetFilePath - e.g. when having a library we just link to + // there would be no BuildTargetInfo that could match + if (targetInfo.targetFilePath.isEmpty()) { qCDebug(LOG) << "BuildTargetInfos"; - for (const BuildTargetInfo &bti : target->applicationTargets().list) - qCDebug(LOG) << " " << bti.targetName << bti.projectFilePath << bti.targetFilePath; + const QList buildTargets = target->applicationTargets().list; + // if there is only one build target just use it (but be honest that we're guessing) + if (buildTargets.size() == 1) { + targetInfo = buildTargets.first(); + m_guessedConfiguration = true; + m_guessedFrom = targetInfo.targetName; + } } + const QString localExecutable = ensureExeEnding(targetInfo.targetFilePath.toString()); + if (localExecutable.isEmpty()) + return; QString buildBase; if (auto buildConfig = target->activeBuildConfiguration()) { @@ -153,6 +218,7 @@ void TestConfiguration::completeTestInformation(TestRunMode runMode) return b.startsWith(currentBST); }))) { qCDebug(LOG) << " Using this RunConfig."; + m_origRunConfig = runConfig; m_runnable = stdRunnable; m_runnable.executable = currentExecutable; m_displayName = runConfig->displayName(); @@ -167,9 +233,9 @@ void TestConfiguration::completeTestInformation(TestRunMode runMode) // or we might have end up using the (wrong) path of a locally installed executable // for this case try the original executable path of the BuildTargetInfo (the executable // before installation) to have at least something to execute - if (m_runnable.executable.isEmpty() && !localExecutable.isEmpty()) + if (!hasExecutable() && !localExecutable.isEmpty()) m_runnable.executable = localExecutable; - if (m_displayName.isEmpty() && !m_runnable.executable.isEmpty()) { + if (m_displayName.isEmpty() && hasExecutable()) { qCDebug(LOG) << " Fallback"; // we failed to find a valid runconfiguration - but we've got the executable already if (auto rc = target->activeRunConfiguration()) { @@ -255,9 +321,14 @@ void TestConfiguration::setInternalTargets(const QSet &targets) m_buildTargets = targets; } +void TestConfiguration::setOriginalRunConfiguration(RunConfiguration *runConfig) +{ + m_origRunConfig = runConfig; +} + QString TestConfiguration::executableFilePath() const { - if (m_runnable.executable.isEmpty()) + if (!hasExecutable()) return QString(); QFileInfo commandFileInfo(m_runnable.executable); @@ -295,5 +366,10 @@ bool DebuggableTestConfiguration::isDebugRunMode() const return m_runMode == TestRunMode::Debug || m_runMode == TestRunMode::DebugWithoutDeploy; } +bool TestConfiguration::hasExecutable() const +{ + return !m_runnable.executable.isEmpty(); +} + } // namespace Internal } // namespace Autotest diff --git a/src/plugins/autotest/testconfiguration.h b/src/plugins/autotest/testconfiguration.h index 7ec208af2a9..e35b0f0dd21 100644 --- a/src/plugins/autotest/testconfiguration.h +++ b/src/plugins/autotest/testconfiguration.h @@ -56,6 +56,7 @@ public: virtual ~TestConfiguration(); void completeTestInformation(TestRunMode runMode); + void completeTestInformation(ProjectExplorer::RunConfiguration *rc, TestRunMode runMode); void setTestCases(const QStringList &testCases); void setTestCaseCount(int count); @@ -67,6 +68,7 @@ public: void setEnvironment(const Utils::Environment &env); void setProject(ProjectExplorer::Project *project); void setInternalTargets(const QSet &targets); + void setOriginalRunConfiguration(ProjectExplorer::RunConfiguration *runConfig); QStringList testCases() const { return m_testCases; } int testCaseCount() const { return m_testCaseCount; } @@ -77,7 +79,10 @@ public: QString displayName() const { return m_displayName; } Utils::Environment environment() const { return m_runnable.environment; } ProjectExplorer::Project *project() const { return m_project.data(); } + QSet internalTargets() const { return m_buildTargets; } + ProjectExplorer::RunConfiguration *originalRunConfiguration() const { return m_origRunConfig; } TestRunConfiguration *runConfiguration() const { return m_runConfig; } + bool hasExecutable() const; bool isGuessed() const { return m_guessedConfiguration; } QString runConfigDisplayName() const { return m_guessedConfiguration ? m_guessedFrom : m_displayName; } @@ -96,8 +101,9 @@ private: QString m_guessedFrom; QPointer m_project; bool m_guessedConfiguration = false; - TestRunConfiguration *m_runConfig = 0; + TestRunConfiguration *m_runConfig = nullptr; QSet m_buildTargets; + ProjectExplorer::RunConfiguration *m_origRunConfig = nullptr; ProjectExplorer::StandardRunnable m_runnable; }; diff --git a/src/plugins/autotest/testrunner.cpp b/src/plugins/autotest/testrunner.cpp index 4c9ba7f645d..b263f44e557 100644 --- a/src/plugins/autotest/testrunner.cpp +++ b/src/plugins/autotest/testrunner.cpp @@ -32,6 +32,7 @@ #include "testsettings.h" #include "testoutputreader.h" +#include #include #include @@ -39,19 +40,28 @@ #include #include #include +#include +#include #include #include #include #include +#include +#include +#include #include #include +#include +#include #include #include #include +#include + namespace Autotest { namespace Internal { @@ -284,8 +294,57 @@ void TestRunner::prepareToRunTests(TestRunMode mode) } } +static QString firstTestCaseTarget(const TestConfiguration *config) +{ + const QSet &internalTargets = config->internalTargets(); + int size = internalTargets.size(); + if (size) + return (*internalTargets.begin()).split('|').first(); + return TestRunner::tr(""); +} + +static bool askUserForRunConfiguration(TestConfiguration *config) +{ + using namespace ProjectExplorer; + RunConfigurationSelectionDialog dialog(firstTestCaseTarget(config), + Core::ICore::dialogParent()); + if (dialog.exec() == QDialog::Accepted) { + const QString dName = dialog.displayName(); + if (dName.isEmpty()) + return false; + // run configuration has been selected - fill config based on this one.. + const QString exe = dialog.executable(); + // paranoia... can the current startup project have changed meanwhile? + if (auto project = SessionManager::startupProject()) { + if (auto target = project->activeTarget()) { + RunConfiguration *runConfig + = Utils::findOr(target->runConfigurations(), nullptr, + [&dName, &exe] (const RunConfiguration *rc) { + if (rc->displayName() != dName) + return false; + if (!rc->runnable().is()) + return false; + StandardRunnable runnable = rc->runnable().as(); + return runnable.executable == exe; + }); + if (runConfig) { + config->setOriginalRunConfiguration(runConfig); + return true; + } + } + } + } + return false; +} + void TestRunner::runTests() { + for (TestConfiguration *config : m_selectedTests) { + config->completeTestInformation(TestRunMode::Run); + if (!config->hasExecutable()) + if (askUserForRunConfiguration(config)) + config->completeTestInformation(config->originalRunConfiguration(), TestRunMode::Run); + } QFuture future = Utils::runAsync(&performTestRun, m_selectedTests, *AutotestPlugin::instance()->settings()); m_futureWatcher.setFuture(future); @@ -327,6 +386,11 @@ void TestRunner::debugTests() TestConfiguration *config = m_selectedTests.first(); config->completeTestInformation(TestRunMode::Debug); + if (!config->hasExecutable()) { + if (askUserForRunConfiguration(config)) + config->completeTestInformation(config->originalRunConfiguration(), TestRunMode::Debug); + } + if (!config->runConfiguration()) { emit testResultReady(TestResultPtr(new FaultyTestResult(Result::MessageFatal, TestRunner::tr("Failed to get run configuration.")))); @@ -453,5 +517,90 @@ void TestRunner::onFinished() emit testRunFinished(); } +/*************************************************************************************************/ + +RunConfigurationSelectionDialog::RunConfigurationSelectionDialog(const QString &testsInfo, + QWidget *parent) + : QDialog(parent) +{ + setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); + setWindowTitle(tr("Select Run Configuration")); + + m_details = new QLabel(tr("Could not determine which run configuration to choose for running" + " tests (%1)").arg(testsInfo), this); + m_rcCombo = new QComboBox(this); + m_executable = new QLabel(this); + m_arguments = new QLabel(this); + m_workingDir = new QLabel(this); + m_buttonBox = new QDialogButtonBox(this); + m_buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok); + m_buttonBox->button(QDialogButtonBox::Ok)->setDefault(true); + + auto line = new QFrame(this); + line->setFrameShape(QFrame::HLine); + line->setFrameShadow(QFrame::Sunken); + + auto formLayout = new QFormLayout; + formLayout->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow); + formLayout->addRow(m_details); + formLayout->addRow(tr("Run Configuration:"), m_rcCombo); + formLayout->addRow(line); + formLayout->addRow(tr("Executable:"), m_executable); + formLayout->addRow(tr("Arguments:"), m_arguments); + formLayout->addRow(tr("Working Directory:"), m_workingDir); + // TODO Device support + auto vboxLayout = new QVBoxLayout(this); + vboxLayout->addLayout(formLayout); + vboxLayout->addStretch(); + vboxLayout->addWidget(line); + vboxLayout->addWidget(m_buttonBox); + + connect(m_rcCombo, &QComboBox::currentTextChanged, + this, &RunConfigurationSelectionDialog::updateLabels); + connect(m_buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept); + connect(m_buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); + + populate(); +} + +QString RunConfigurationSelectionDialog::displayName() const +{ + return m_rcCombo ? m_rcCombo->currentText() : QString(); +} + +QString RunConfigurationSelectionDialog::executable() const +{ + return m_executable ? m_executable->text() : QString(); +} + +void RunConfigurationSelectionDialog::populate() +{ + m_rcCombo->addItem(QString(), QStringList({QString(), QString(), QString()})); // empty default + + if (auto project = ProjectExplorer::SessionManager::startupProject()) { + if (auto target = project->activeTarget()) { + for (ProjectExplorer::RunConfiguration *rc : target->runConfigurations()) { + if (rc->runnable().is()) { + auto runnable = rc->runnable().as(); + const QStringList rcDetails = { runnable.executable, + runnable.commandLineArguments, + runnable.workingDirectory }; + m_rcCombo->addItem(rc->displayName(), rcDetails); + } + } + } + } +} + +void RunConfigurationSelectionDialog::updateLabels() +{ + int i = m_rcCombo->currentIndex(); + const QStringList values = m_rcCombo->itemData(i).toStringList(); + QTC_ASSERT(values.size() == 3, return); + m_executable->setText(values.at(0)); + m_arguments->setText(values.at(1)); + m_workingDir->setText(values.at(2)); +} + } // namespace Internal } // namespace Autotest diff --git a/src/plugins/autotest/testrunner.h b/src/plugins/autotest/testrunner.h index b146d7fb95e..004c4f48313 100644 --- a/src/plugins/autotest/testrunner.h +++ b/src/plugins/autotest/testrunner.h @@ -28,10 +28,17 @@ #include "testconfiguration.h" #include "testresult.h" +#include #include #include #include +QT_BEGIN_NAMESPACE +class QComboBox; +class QDialogButtonBox; +class QLabel; +QT_END_NAMESPACE + namespace ProjectExplorer { class Project; } @@ -77,5 +84,23 @@ private: QMetaObject::Connection m_buildConnect; }; +class RunConfigurationSelectionDialog : public QDialog +{ + Q_OBJECT +public: + explicit RunConfigurationSelectionDialog(const QString &testsInfo, QWidget *parent = nullptr); + QString displayName() const; + QString executable() const; +private: + void populate(); + void updateLabels(); + QLabel *m_details; + QLabel *m_executable; + QLabel *m_arguments; + QLabel *m_workingDir; + QComboBox *m_rcCombo; + QDialogButtonBox *m_buttonBox; +}; + } // namespace Internal } // namespace Autotest diff --git a/src/plugins/autotest/testtreeitem.cpp b/src/plugins/autotest/testtreeitem.cpp index 626fda93d3b..d27c689e5b0 100644 --- a/src/plugins/autotest/testtreeitem.cpp +++ b/src/plugins/autotest/testtreeitem.cpp @@ -30,6 +30,7 @@ #include #include +#include #include #include @@ -286,12 +287,12 @@ bool TestTreeItem::lessThan(const TestTreeItem *other, SortMode mode) const QSet TestTreeItem::internalTargets() const { auto cppMM = CppTools::CppModelManager::instance(); - const QList projectParts = cppMM->projectPart(filePath()); + const QList projectParts = cppMM->projectPart(m_filePath); QSet targets; for (const CppTools::ProjectPart::Ptr part : projectParts) { - if (part->buildTargetType != CppTools::ProjectPart::Executable) - continue; targets.insert(part->buildSystemTarget + '|' + part->projectFile); + if (part->buildTargetType != CppTools::ProjectPart::Executable) + targets.unite(TestTreeItem::dependingInternalTargets(cppMM, m_filePath)); } return targets; } @@ -359,5 +360,28 @@ TestTreeItem *TestTreeItem::findChildBy(CompareFunction compare) const return nullptr; } +/* + * try to find build system target that depends on the given file - if the file is no header + * try to find the corresponding header and use this instead to find the respective target + */ +QSet TestTreeItem::dependingInternalTargets(CppTools::CppModelManager *cppMM, + const QString &file) +{ + QSet result; + QTC_ASSERT(cppMM, return result); + const CPlusPlus::Snapshot snapshot = cppMM->snapshot(); + QTC_ASSERT(snapshot.contains(file), return result); + bool wasHeader; + const QString correspondingFile + = CppTools::correspondingHeaderOrSource(file, &wasHeader, CppTools::CacheUsage::ReadOnly); + const Utils::FileNameList dependingFiles = snapshot.filesDependingOn( + wasHeader ? file : correspondingFile); + for (const Utils::FileName &fn : dependingFiles) { + for (const CppTools::ProjectPart::Ptr part : cppMM->projectPart(fn)) + result.insert(part->buildSystemTarget + '|' + part->projectFile); + } + return result; +} + } // namespace Internal } // namespace Autotest diff --git a/src/plugins/autotest/testtreeitem.h b/src/plugins/autotest/testtreeitem.h index 2c2c728a2c7..f4a7d735db5 100644 --- a/src/plugins/autotest/testtreeitem.h +++ b/src/plugins/autotest/testtreeitem.h @@ -28,6 +28,7 @@ #include #include +#include #include #include @@ -40,6 +41,8 @@ namespace { }; } +namespace CppTools { class CppModelManager; } + namespace Autotest { namespace Internal { @@ -114,6 +117,8 @@ public: protected: typedef std::function CompareFunction; TestTreeItem *findChildBy(CompareFunction compare) const; + static QSet dependingInternalTargets(CppTools::CppModelManager *cppMM, + const QString &file); private: void revalidateCheckState(); diff --git a/src/plugins/coreplugin/documentmanager.cpp b/src/plugins/coreplugin/documentmanager.cpp index c4744e75931..afbc8da18a0 100644 --- a/src/plugins/coreplugin/documentmanager.cpp +++ b/src/plugins/coreplugin/documentmanager.cpp @@ -1365,7 +1365,10 @@ FileName DocumentManager::projectsDirectory() void DocumentManager::setProjectsDirectory(const FileName &directory) { - d->m_projectsDirectory = directory; + if (d->m_projectsDirectory != directory) { + d->m_projectsDirectory = directory; + emit m_instance->projectsDirectoryChanged(d->m_projectsDirectory); + } } /*! diff --git a/src/plugins/coreplugin/documentmanager.h b/src/plugins/coreplugin/documentmanager.h index d8a243ea6f6..052a7ee7bd4 100644 --- a/src/plugins/coreplugin/documentmanager.h +++ b/src/plugins/coreplugin/documentmanager.h @@ -146,6 +146,7 @@ signals: void allDocumentsRenamed(const QString &from, const QString &to); /// emitted if one document changed its name e.g. due to save as void documentRenamed(Core::IDocument *document, const QString &from, const QString &to); + void projectsDirectoryChanged(const Utils::FileName &directory); protected: bool eventFilter(QObject *obj, QEvent *e); diff --git a/src/plugins/cpptools/cpptoolsplugin.cpp b/src/plugins/cpptools/cpptoolsplugin.cpp index d0dfec3a56d..af192cb0828 100644 --- a/src/plugins/cpptools/cpptoolsplugin.cpp +++ b/src/plugins/cpptools/cpptoolsplugin.cpp @@ -357,7 +357,8 @@ static int commonFilePathLength(const QString &s1, const QString &s2) static QString correspondingHeaderOrSourceInProject(const QFileInfo &fileInfo, const QStringList &candidateFileNames, - const ProjectExplorer::Project *project) + const ProjectExplorer::Project *project, + CacheUsage cacheUsage) { QString bestFileName; int compareValue = 0; @@ -376,8 +377,10 @@ static QString correspondingHeaderOrSourceInProject(const QFileInfo &fileInfo, if (!bestFileName.isEmpty()) { const QFileInfo candidateFi(bestFileName); QTC_ASSERT(candidateFi.isFile(), return QString()); - m_headerSourceMapping[fileInfo.absoluteFilePath()] = candidateFi.absoluteFilePath(); - m_headerSourceMapping[candidateFi.absoluteFilePath()] = fileInfo.absoluteFilePath(); + if (cacheUsage == CacheUsage::ReadWrite) { + m_headerSourceMapping[fileInfo.absoluteFilePath()] = candidateFi.absoluteFilePath(); + m_headerSourceMapping[candidateFi.absoluteFilePath()] = fileInfo.absoluteFilePath(); + } return candidateFi.absoluteFilePath(); } @@ -386,7 +389,7 @@ static QString correspondingHeaderOrSourceInProject(const QFileInfo &fileInfo, } // namespace Internal -QString correspondingHeaderOrSource(const QString &fileName, bool *wasHeader) +QString correspondingHeaderOrSource(const QString &fileName, bool *wasHeader, CacheUsage cacheUsage) { using namespace Internal; @@ -437,9 +440,11 @@ QString correspondingHeaderOrSource(const QString &fileName, bool *wasHeader) const QString normalized = Utils::FileUtils::normalizePathName(candidateFilePath); const QFileInfo candidateFi(normalized); if (candidateFi.isFile()) { - m_headerSourceMapping[fi.absoluteFilePath()] = candidateFi.absoluteFilePath(); - if (!isHeader || !baseName.endsWith(privateHeaderSuffix)) - m_headerSourceMapping[candidateFi.absoluteFilePath()] = fi.absoluteFilePath(); + if (cacheUsage == CacheUsage::ReadWrite) { + m_headerSourceMapping[fi.absoluteFilePath()] = candidateFi.absoluteFilePath(); + if (!isHeader || !baseName.endsWith(privateHeaderSuffix)) + m_headerSourceMapping[candidateFi.absoluteFilePath()] = fi.absoluteFilePath(); + } return candidateFi.absoluteFilePath(); } } @@ -449,7 +454,7 @@ QString correspondingHeaderOrSource(const QString &fileName, bool *wasHeader) ProjectExplorer::Project *currentProject = ProjectExplorer::ProjectTree::currentProject(); if (currentProject) { const QString path = correspondingHeaderOrSourceInProject(fi, candidateFileNames, - currentProject); + currentProject, cacheUsage); if (!path.isEmpty()) return path; @@ -462,7 +467,8 @@ QString correspondingHeaderOrSource(const QString &fileName, bool *wasHeader) if (project == currentProject) continue; // We have already checked the current project. - const QString path = correspondingHeaderOrSourceInProject(fi, candidateFileNames, project); + const QString path = correspondingHeaderOrSourceInProject(fi, candidateFileNames, + project, cacheUsage); if (!path.isEmpty()) return path; } diff --git a/src/plugins/cpptools/cpptoolsreuse.h b/src/plugins/cpptools/cpptoolsreuse.h index 46ef50d7b16..89183bb0b81 100644 --- a/src/plugins/cpptools/cpptoolsreuse.h +++ b/src/plugins/cpptools/cpptoolsreuse.h @@ -68,7 +68,10 @@ bool CPPTOOLS_EXPORT isOwnershipRAIIType(CPlusPlus::Symbol *symbol, const CPlusPlus::Macro CPPTOOLS_EXPORT *findCanonicalMacro(const QTextCursor &cursor, CPlusPlus::Document::Ptr document); -QString CPPTOOLS_EXPORT correspondingHeaderOrSource(const QString &fileName, bool *wasHeader = 0); +enum class CacheUsage { ReadWrite, ReadOnly }; + +QString CPPTOOLS_EXPORT correspondingHeaderOrSource(const QString &fileName, bool *wasHeader = 0, + CacheUsage cacheUsage = CacheUsage::ReadWrite); void CPPTOOLS_EXPORT switchHeaderSource(); class CppCodeModelSettings; diff --git a/src/plugins/projectexplorer/foldernavigationwidget.cpp b/src/plugins/projectexplorer/foldernavigationwidget.cpp index 797c0c2b15b..10ed90d4e0a 100644 --- a/src/plugins/projectexplorer/foldernavigationwidget.cpp +++ b/src/plugins/projectexplorer/foldernavigationwidget.cpp @@ -27,6 +27,7 @@ #include "projectexplorer.h" #include +#include #include #include #include @@ -53,12 +54,17 @@ #include #include +const int PATH_ROLE = Qt::UserRole; +const int ID_ROLE = Qt::UserRole + 1; + +const char PROJECTSDIRECTORYROOT_ID[] = "A.Projects"; + namespace ProjectExplorer { namespace Internal { static FolderNavigationWidgetFactory *m_instance = nullptr; -QVector +QVector FolderNavigationWidgetFactory::m_rootDirectories; // FolderNavigationModel: Shows path as tooltip. @@ -164,21 +170,29 @@ void FolderNavigationWidget::toggleAutoSynchronization() setAutoSynchronization(!m_autoSync); } -void FolderNavigationWidget::addRootDirectory(const QString &displayName, - const Utils::FileName &directory) +void FolderNavigationWidget::insertRootDirectory( + const FolderNavigationWidgetFactory::RootDirectory &directory) { - m_rootSelector->addItem(displayName, qVariantFromValue(directory)); - m_rootSelector->setItemData(m_rootSelector->count() - 1, - directory.toUserOutput(), - Qt::ToolTipRole); + // insert sorted + int index = 0; + while (index < m_rootSelector->count() + && m_rootSelector->itemData(index, ID_ROLE).toString() < directory.id) + ++index; + if (m_rootSelector->itemData(index, ID_ROLE).toString() != directory.id) + m_rootSelector->insertItem(index, directory.displayName); + m_rootSelector->setItemData(index, qVariantFromValue(directory.path), PATH_ROLE); + m_rootSelector->setItemData(index, directory.id, ID_ROLE); + m_rootSelector->setItemData(index, directory.path.toUserOutput(), Qt::ToolTipRole); + if (m_rootSelector->currentIndex() == index) + setRootDirectory(directory.path); if (m_autoSync) // we might find a better root for current selection now setCurrentEditor(Core::EditorManager::currentEditor()); } -void FolderNavigationWidget::removeRootDirectory(const Utils::FileName &directory) +void FolderNavigationWidget::removeRootDirectory(const QString &id) { for (int i = 0; i < m_rootSelector->count(); ++i) { - if (m_rootSelector->itemData(i).value() == directory) { + if (m_rootSelector->itemData(i, ID_ROLE).toString() == id) { m_rootSelector->removeItem(i); break; } @@ -343,18 +357,27 @@ FolderNavigationWidgetFactory::FolderNavigationWidgetFactory() setPriority(400); setId("File System"); setActivationSequence(QKeySequence(Core::UseMacShortcuts ? tr("Meta+Y") : tr("Alt+Y"))); - addRootDirectory(FolderNavigationWidget::tr("Computer"), Utils::FileName()); + insertRootDirectory( + {QLatin1String("A.Computer"), FolderNavigationWidget::tr("Computer"), Utils::FileName()}); + insertRootDirectory({QLatin1String("A.Home"), + FolderNavigationWidget::tr("Home"), + Utils::FileName::fromString(QDir::homePath())}); + updateProjectsDirectoryRoot(); + connect(Core::DocumentManager::instance(), + &Core::DocumentManager::projectsDirectoryChanged, + this, + &FolderNavigationWidgetFactory::updateProjectsDirectoryRoot); } Core::NavigationView FolderNavigationWidgetFactory::createWidget() { auto fnw = new FolderNavigationWidget; - for (const DirectoryEntry &root : m_rootDirectories) - fnw->addRootDirectory(root.first, root.second); + for (const RootDirectory &root : m_rootDirectories) + fnw->insertRootDirectory(root); connect(this, &FolderNavigationWidgetFactory::rootDirectoryAdded, fnw, - &FolderNavigationWidget::addRootDirectory); + &FolderNavigationWidget::insertRootDirectory); connect(this, &FolderNavigationWidgetFactory::rootDirectoryRemoved, fnw, @@ -392,21 +415,33 @@ void FolderNavigationWidgetFactory::restoreSettings(QSettings *settings, int pos fnw->setAutoSynchronization(settings->value(baseKey + QLatin1String(".SyncWithEditor"), true).toBool()); } -void FolderNavigationWidgetFactory::addRootDirectory(const QString &displayName, - const Utils::FileName &directory) +void FolderNavigationWidgetFactory::insertRootDirectory(const RootDirectory &directory) { - m_rootDirectories.append(DirectoryEntry(displayName, directory)); - emit m_instance->rootDirectoryAdded(displayName, directory); + const int index = rootIndex(directory.id); + if (index < 0) + m_rootDirectories.append(directory); + emit m_instance->rootDirectoryAdded(directory); } -void FolderNavigationWidgetFactory::removeRootDirectory(const Utils::FileName &directory) +void FolderNavigationWidgetFactory::removeRootDirectory(const QString &id) { - const int index = Utils::indexOf(m_rootDirectories, [directory](const DirectoryEntry &entry) { - return entry.second == directory; - }); - QTC_ASSERT(index >= 0, return); + const int index = rootIndex(id); + QTC_ASSERT(index >= 0, return ); m_rootDirectories.removeAt(index); - emit m_instance->rootDirectoryRemoved(directory); + emit m_instance->rootDirectoryRemoved(id); +} + +int FolderNavigationWidgetFactory::rootIndex(const QString &id) +{ + return Utils::indexOf(m_rootDirectories, + [id](const RootDirectory &entry) { return entry.id == id; }); +} + +void FolderNavigationWidgetFactory::updateProjectsDirectoryRoot() +{ + insertRootDirectory({QLatin1String(PROJECTSDIRECTORYROOT_ID), + FolderNavigationWidget::tr("Projects"), + Core::DocumentManager::projectsDirectory()}); } } // namespace Internal diff --git a/src/plugins/projectexplorer/foldernavigationwidget.h b/src/plugins/projectexplorer/foldernavigationwidget.h index 22f88f43485..06c91c17185 100644 --- a/src/plugins/projectexplorer/foldernavigationwidget.h +++ b/src/plugins/projectexplorer/foldernavigationwidget.h @@ -26,13 +26,13 @@ #pragma once #include +#include #include namespace Core { class IEditor; } namespace Utils { -class FileName; class NavigationTreeView; } @@ -46,6 +46,36 @@ QT_END_NAMESPACE namespace ProjectExplorer { namespace Internal { +class FolderNavigationWidgetFactory : public Core::INavigationWidgetFactory +{ + Q_OBJECT + +public: + struct RootDirectory { + QString id; + QString displayName; + Utils::FileName path; + }; + + FolderNavigationWidgetFactory(); + + Core::NavigationView createWidget() override; + void saveSettings(QSettings *settings, int position, QWidget *widget) override; + void restoreSettings(QSettings *settings, int position, QWidget *widget) override; + + static void insertRootDirectory(const RootDirectory &directory); + static void removeRootDirectory(const QString &id); + +signals: + void rootDirectoryAdded(const RootDirectory &directory); + void rootDirectoryRemoved(const QString &id); + +private: + static int rootIndex(const QString &id); + void updateProjectsDirectoryRoot(); + static QVector m_rootDirectories; +}; + class FolderNavigationWidget : public QWidget { Q_OBJECT @@ -61,8 +91,8 @@ public: void setAutoSynchronization(bool sync); void toggleAutoSynchronization(); - void addRootDirectory(const QString &displayName, const Utils::FileName &directory); - void removeRootDirectory(const Utils::FileName &directory); + void insertRootDirectory(const FolderNavigationWidgetFactory::RootDirectory &directory); + void removeRootDirectory(const QString &id); protected: void contextMenuEvent(QContextMenuEvent *ev) override; @@ -86,28 +116,5 @@ private: friend class FolderNavigationWidgetFactory; }; -class FolderNavigationWidgetFactory : public Core::INavigationWidgetFactory -{ - Q_OBJECT - -public: - FolderNavigationWidgetFactory(); - - Core::NavigationView createWidget() override; - void saveSettings(QSettings *settings, int position, QWidget *widget) override; - void restoreSettings(QSettings *settings, int position, QWidget *widget) override; - - static void addRootDirectory(const QString &displayName, const Utils::FileName &directory); - static void removeRootDirectory(const Utils::FileName &directory); - -signals: - void rootDirectoryAdded(const QString &displayName, const Utils::FileName &directory); - void rootDirectoryRemoved(const Utils::FileName &directory); - -private: - using DirectoryEntry = std::pair; - static QVector m_rootDirectories; -}; - } // namespace Internal } // namespace ProjectExplorer diff --git a/src/plugins/projectexplorer/session.cpp b/src/plugins/projectexplorer/session.cpp index 458bc525469..cd66c88caea 100644 --- a/src/plugins/projectexplorer/session.cpp +++ b/src/plugins/projectexplorer/session.cpp @@ -118,6 +118,11 @@ private: static SessionManager *m_instance = nullptr; static SessionManagerPrivate *d = nullptr; +static QString projectFolderId(Project *pro) +{ + return "P." + pro->displayName() + "." + pro->projectFilePath().toString(); +} + SessionManager::SessionManager(QObject *parent) : QObject(parent) { m_instance = this; @@ -386,10 +391,14 @@ void SessionManager::addProject(Project *pro) m_instance, [pro]() { m_instance->projectDisplayNameChanged(pro); }); emit m_instance->projectAdded(pro); - FolderNavigationWidgetFactory::addRootDirectory(pro->displayName(), - pro->projectFilePath().parentDir()); + const auto updateFolderNavigation = [pro] { + FolderNavigationWidgetFactory::insertRootDirectory( + {projectFolderId(pro), pro->displayName(), pro->projectFilePath().parentDir()}); + }; + updateFolderNavigation(); configureEditors(pro); connect(pro, &Project::fileListChanged, [pro](){ configureEditors(pro); }); + connect(pro, &Project::displayNameChanged, pro, updateFolderNavigation); } void SessionManager::removeProject(Project *project) @@ -742,7 +751,7 @@ void SessionManager::removeProjects(QList remove) m_instance, &SessionManager::clearProjectFileCache); d->m_projectFileCache.remove(pro); emit m_instance->projectRemoved(pro); - FolderNavigationWidgetFactory::removeRootDirectory(pro->projectFilePath().parentDir()); + FolderNavigationWidgetFactory::removeRootDirectory(projectFolderId(pro)); delete pro; } diff --git a/src/plugins/qmldesigner/components/navigator/navigatormodelinterface.h b/src/plugins/qmldesigner/components/navigator/navigatormodelinterface.h index 243aa489cf0..bedcc2f561a 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatormodelinterface.h +++ b/src/plugins/qmldesigner/components/navigator/navigatormodelinterface.h @@ -43,6 +43,8 @@ public: virtual void notifyModelNodesRemoved(const QList &modelNodes) = 0; virtual void notifyModelNodesInserted(const QList &modelNodes) = 0; virtual void notifyModelNodesMoved(const QList &modelNodes) = 0; + virtual void setFilter(bool showObjects) = 0; + virtual void resetModel() = 0; }; } //QmlDesigner diff --git a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp index 0b6c3cc6ae8..3b78b09de1f 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp +++ b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp @@ -246,6 +246,16 @@ Qt::ItemFlags NavigatorTreeModel::flags(const QModelIndex &index) const | Qt::ItemNeverHasChildren; } +QList filteredList(const NodeListProperty &property, bool filter) +{ + if (!filter) + return property.toModelNodeList(); + + return Utils::filtered(property.toModelNodeList(), [] (const ModelNode &arg) { + return QmlItemNode::isValidQmlItemNode(arg); + }); +} + QModelIndex NavigatorTreeModel::index(int row, int column, const QModelIndex &parent) const { @@ -262,7 +272,7 @@ QModelIndex NavigatorTreeModel::index(int row, int column, ModelNode modelNode; if (parentModelNode.defaultNodeListProperty().isValid()) - modelNode = parentModelNode.defaultNodeListProperty().at(row); + modelNode = filteredList(parentModelNode.defaultNodeListProperty(), m_showOnlyVisibleItems).at(row); if (!modelNode.isValid()) return QModelIndex(); @@ -293,7 +303,7 @@ QModelIndex NavigatorTreeModel::parent(const QModelIndex &index) const int row = 0; if (!parentModelNode.isRootNode() && parentModelNode.parentProperty().isNodeListProperty()) - row = parentModelNode.parentProperty().toNodeListProperty().indexOf(parentModelNode); + row = filteredList(parentModelNode.parentProperty().toNodeListProperty(), m_showOnlyVisibleItems).indexOf(parentModelNode); return createIndexFromModelNode(row, 0, parentModelNode); } @@ -313,7 +323,7 @@ int NavigatorTreeModel::rowCount(const QModelIndex &parent) const int rows = 0; if (modelNode.defaultNodeListProperty().isValid()) - rows = modelNode.defaultNodeListProperty().count(); + rows = filteredList(modelNode.defaultNodeListProperty(), m_showOnlyVisibleItems).count(); return rows; } @@ -628,4 +638,17 @@ void NavigatorTreeModel::notifyModelNodesMoved(const QList &modelNode layoutChanged(indexes); } +void NavigatorTreeModel::setFilter(bool showOnlyVisibleItems) +{ + m_showOnlyVisibleItems = showOnlyVisibleItems; + resetModel(); +} + +void NavigatorTreeModel::resetModel() +{ + beginResetModel(); + m_nodeIndexHash.clear(); + endResetModel(); +} + } // QmlDesigner diff --git a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.h b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.h index 9b6e22b114a..92b352fce50 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.h +++ b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.h @@ -87,6 +87,8 @@ public: void notifyModelNodesRemoved(const QList &modelNodes) override; void notifyModelNodesInserted(const QList &modelNodes) override; void notifyModelNodesMoved(const QList &modelNodes) override; + void setFilter(bool showOnlyVisibleItems) override; + void resetModel() override; private: void moveNodesInteractive(NodeAbstractProperty &parentProperty, const QList &modelNodes, int targetIndex); @@ -97,6 +99,7 @@ private: QPointer m_view; mutable QHash m_nodeIndexHash; + bool m_showOnlyVisibleItems = true; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/navigator/navigatorview.cpp b/src/plugins/qmldesigner/components/navigator/navigatorview.cpp index 4bf00a00e7b..48531cf82eb 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatorview.cpp +++ b/src/plugins/qmldesigner/components/navigator/navigatorview.cpp @@ -34,6 +34,7 @@ #include #include +#include #include #include #include @@ -88,6 +89,7 @@ NavigatorView::NavigatorView(QObject* parent) : connect(m_widget.data(), &NavigatorWidget::rightButtonClicked, this, &NavigatorView::rightButtonClicked); connect(m_widget.data(), &NavigatorWidget::downButtonClicked, this, &NavigatorView::downButtonClicked); connect(m_widget.data(), &NavigatorWidget::upButtonClicked, this, &NavigatorView::upButtonClicked); + connect(m_widget.data(), &NavigatorWidget::filterToggled, this, &NavigatorView::filterToggled); #ifndef QMLDESIGNER_TEST NameItemDelegate *idDelegate = new NameItemDelegate(this); @@ -145,6 +147,9 @@ void NavigatorView::modelAttached(Model *model) { AbstractView::modelAttached(model); + m_currentModelInterface->setFilter( + DesignerSettings::getValue(DesignerSettingsKey::NAVIGATOR_SHOW_ONLY_VISIBLE_ITEMS).toBool()); + QTreeView *treeView = treeWidget(); treeView->expandAll(); @@ -400,6 +405,13 @@ void NavigatorView::downButtonClicked() blockSelectionChangedSignal(blocked); } +void NavigatorView::filterToggled(bool flag) +{ + m_currentModelInterface->setFilter(flag); + treeWidget()->expandAll(); + DesignerSettings::setValue(DesignerSettingsKey::NAVIGATOR_SHOW_ONLY_VISIBLE_ITEMS, flag); +} + void NavigatorView::changeSelection(const QItemSelection & /*newSelection*/, const QItemSelection &/*deselected*/) { if (m_blockSelectionChangedSignal) diff --git a/src/plugins/qmldesigner/components/navigator/navigatorview.h b/src/plugins/qmldesigner/components/navigator/navigatorview.h index 24c65f2eeb8..d02a0d38fe0 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatorview.h +++ b/src/plugins/qmldesigner/components/navigator/navigatorview.h @@ -99,6 +99,7 @@ private: void rightButtonClicked(); void upButtonClicked(); void downButtonClicked(); + void filterToggled(bool); protected: //functions QTreeView *treeWidget() const; diff --git a/src/plugins/qmldesigner/components/navigator/navigatorwidget.cpp b/src/plugins/qmldesigner/components/navigator/navigatorwidget.cpp index d9794f6388e..0785e704df2 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatorwidget.cpp +++ b/src/plugins/qmldesigner/components/navigator/navigatorwidget.cpp @@ -27,14 +27,17 @@ #include "navigatorview.h" #include "qmldesignerconstants.h" #include "qmldesignericons.h" +#include #include #include #include #include +#include #include #include #include +#include namespace QmlDesigner { @@ -80,29 +83,49 @@ QList NavigatorWidget::createToolBarWidgets() { QList buttons; - buttons.append(new QToolButton()); - buttons.last()->setIcon(Icons::ARROW_LEFT.icon()); - buttons.last()->setToolTip(tr("Become last sibling of parent (CTRL + Left).")); - buttons.last()->setShortcut(QKeySequence(Qt::Key_Left | Qt::CTRL)); - connect(buttons.last(), &QAbstractButton::clicked, this, &NavigatorWidget::leftButtonClicked); - buttons.append(new QToolButton()); - buttons.last()->setIcon(Icons::ARROW_RIGHT.icon()); - buttons.last()->setToolTip(tr("Become child of last sibling (CTRL + Right).")); - buttons.last()->setShortcut(QKeySequence(Qt::Key_Right | Qt::CTRL)); - connect(buttons.last(), &QAbstractButton::clicked, this, &NavigatorWidget::rightButtonClicked); + auto button = new QToolButton(); + button->setIcon(Icons::ARROW_LEFT.icon()); + button->setToolTip(tr("Become last sibling of parent (CTRL + Left).")); + button->setShortcut(QKeySequence(Qt::Key_Left | Qt::CTRL)); + connect(button, &QAbstractButton::clicked, this, &NavigatorWidget::leftButtonClicked); + buttons.append(button); - buttons.append(new QToolButton()); - buttons.last()->setIcon(Icons::ARROW_DOWN.icon()); - buttons.last()->setToolTip(tr("Move down (CTRL + Down).")); - buttons.last()->setShortcut(QKeySequence(Qt::Key_Down | Qt::CTRL)); - connect(buttons.last(), &QAbstractButton::clicked, this, &NavigatorWidget::downButtonClicked); + button = new QToolButton(); + button->setIcon(Icons::ARROW_RIGHT.icon()); + button->setToolTip(tr("Become child of last sibling (CTRL + Right).")); + button->setShortcut(QKeySequence(Qt::Key_Right | Qt::CTRL)); + connect(button, &QAbstractButton::clicked, this, &NavigatorWidget::rightButtonClicked); + buttons.append(button); - buttons.append(new QToolButton()); - buttons.last()->setIcon(Icons::ARROW_UP.icon()); - buttons.last()->setToolTip(tr("Move up (CTRL + Up).")); - buttons.last()->setShortcut(QKeySequence(Qt::Key_Up | Qt::CTRL)); - connect(buttons.last(), &QAbstractButton::clicked, this, &NavigatorWidget::upButtonClicked); + button = new QToolButton(); + button->setIcon(Icons::ARROW_DOWN.icon()); + button->setToolTip(tr("Move down (CTRL + Down).")); + button->setShortcut(QKeySequence(Qt::Key_Down | Qt::CTRL)); + connect(button, &QAbstractButton::clicked, this, &NavigatorWidget::downButtonClicked); + buttons.append(button); + + button = new QToolButton(); + button->setIcon(Icons::ARROW_UP.icon()); + button->setToolTip(tr("Move up (CTRL + Up).")); + button->setShortcut(QKeySequence(Qt::Key_Up | Qt::CTRL)); + connect(button, &QAbstractButton::clicked, this, &NavigatorWidget::upButtonClicked); + buttons.append(button); + + auto filter = new QToolButton; + filter->setIcon(Utils::Icons::FILTER.icon()); + filter->setToolTip(tr("Filter Tree")); + filter->setPopupMode(QToolButton::InstantPopup); + filter->setProperty("noArrow", true); + auto filterMenu = new QMenu(filter); + auto objectAction = new QAction(tr("Show only visible itmes.")); + objectAction->setCheckable(true); + objectAction->setChecked( + DesignerSettings::getValue(DesignerSettingsKey::NAVIGATOR_SHOW_ONLY_VISIBLE_ITEMS).toBool()); + connect(objectAction, &QAction::toggled, this, &NavigatorWidget::filterToggled); + filterMenu->addAction(objectAction); + filter->setMenu(filterMenu); + buttons.append(filter); return buttons; } diff --git a/src/plugins/qmldesigner/components/navigator/navigatorwidget.h b/src/plugins/qmldesigner/components/navigator/navigatorwidget.h index 526004cf840..45e8b19c9b5 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatorwidget.h +++ b/src/plugins/qmldesigner/components/navigator/navigatorwidget.h @@ -53,6 +53,7 @@ signals: void rightButtonClicked(); void upButtonClicked(); void downButtonClicked(); + void filterToggled(bool); private: // functions NavigatorView *navigatorView() const; diff --git a/src/plugins/qmldesigner/designersettings.cpp b/src/plugins/qmldesigner/designersettings.cpp index c75c98c80bc..ec7d1397283 100644 --- a/src/plugins/qmldesigner/designersettings.cpp +++ b/src/plugins/qmldesigner/designersettings.cpp @@ -74,6 +74,8 @@ void DesignerSettings::fromSettings(QSettings *settings) restoreValue(settings, DesignerSettingsKey::FORWARD_PUPPET_OUTPUT, QString()); restoreValue(settings, DesignerSettingsKey::REFORMAT_UI_QML_FILES, true); restoreValue(settings, DesignerSettingsKey::IGNORE_DEVICE_PIXEL_RATIO, false); + restoreValue(settings, DesignerSettingsKey::STATESEDITOR_EXPANDED, false); + restoreValue(settings, DesignerSettingsKey::NAVIGATOR_SHOW_ONLY_VISIBLE_ITEMS, true); settings->endGroup(); settings->endGroup(); diff --git a/src/plugins/qmldesigner/designersettings.h b/src/plugins/qmldesigner/designersettings.h index a3710d278dc..7172c10491e 100644 --- a/src/plugins/qmldesigner/designersettings.h +++ b/src/plugins/qmldesigner/designersettings.h @@ -60,6 +60,7 @@ const char PUPPET_KILL_TIMEOUT[] = "PuppetKillTimeout"; const char DEBUG_PUPPET[] = "DebugPuppet"; const char FORWARD_PUPPET_OUTPUT[] = "ForwardPuppetOutput"; const char STATESEDITOR_EXPANDED[] = "StatesEditorExpanded"; +const char NAVIGATOR_SHOW_ONLY_VISIBLE_ITEMS[] = "NavigatorShowOnlyVisibleItems"; const char REFORMAT_UI_QML_FILES[] = "ReformatUiQmlFiles"; /* These settings are not exposed in ui. */ const char IGNORE_DEVICE_PIXEL_RATIO[] = "IgnoreDevicePixelRaio"; /* The settings can be used to turn off the feature, if there are serious issues */ } diff --git a/src/plugins/qmlprofiler/tests/localqmlprofilerrunner_test.cpp b/src/plugins/qmlprofiler/tests/localqmlprofilerrunner_test.cpp index 754455c86b4..3bf680be5ba 100644 --- a/src/plugins/qmlprofiler/tests/localqmlprofilerrunner_test.cpp +++ b/src/plugins/qmlprofiler/tests/localqmlprofilerrunner_test.cpp @@ -93,8 +93,8 @@ void LocalQmlProfilerRunnerTest::testRunner() runControl->initiateStart(); - QTRY_COMPARE_WITH_TIMEOUT(startCount, 1, 20000); - QTRY_VERIFY_WITH_TIMEOUT(!started, 20000); + QTRY_COMPARE_WITH_TIMEOUT(startCount, 1, 30000); + QTRY_VERIFY_WITH_TIMEOUT(!started, 30000); QCOMPARE(stopCount, 1); QCOMPARE(runCount, 0); @@ -114,8 +114,8 @@ void LocalQmlProfilerRunnerTest::testRunner() connectRunner(); runControl->initiateStart(); - QTRY_VERIFY_WITH_TIMEOUT(running, 20000); - QTRY_VERIFY_WITH_TIMEOUT(!running, 20000); + QTRY_VERIFY_WITH_TIMEOUT(running, 30000); + QTRY_VERIFY_WITH_TIMEOUT(!running, 30000); QCOMPARE(startCount, 2); QCOMPARE(stopCount, 2); QCOMPARE(runCount, 1); @@ -134,9 +134,9 @@ void LocalQmlProfilerRunnerTest::testRunner() connectRunner(); runControl->initiateStart(); - QTRY_VERIFY_WITH_TIMEOUT(running, 20000); + QTRY_VERIFY_WITH_TIMEOUT(running, 30000); runControl->initiateStop(); - QTRY_VERIFY_WITH_TIMEOUT(!running, 20000); + QTRY_VERIFY_WITH_TIMEOUT(!running, 30000); QCOMPARE(startCount, 3); QCOMPARE(stopCount, 3); QCOMPARE(runCount, 2); diff --git a/tests/system/suite_debugger/tst_simple_analyze/test.py b/tests/system/suite_debugger/tst_simple_analyze/test.py index 89c5fe30919..d01d5cbc966 100644 --- a/tests/system/suite_debugger/tst_simple_analyze/test.py +++ b/tests/system/suite_debugger/tst_simple_analyze/test.py @@ -35,7 +35,9 @@ def main(): analyzerTargets = Targets.desktopTargetClasses() checkedTargets, projectName = createNewQtQuickApplication(workingDir, targets=analyzerTargets) editor = waitForObject(":Qt Creator_QmlJSEditor::QmlJSTextEditorWidget") - if placeCursorToLine(editor, "MouseArea.*", True): + if placeCursorToLine(editor, "}"): + type(editor, '') + type(editor, '') type(editor, '') type(editor, '') typeLines(editor, ['Timer {', diff --git a/tests/system/suite_debugger/tst_simple_analyze/testdata/events_qt5.tsv b/tests/system/suite_debugger/tst_simple_analyze/testdata/events_qt5.tsv index 7e1b41e3422..cd25a9eb10b 100644 --- a/tests/system/suite_debugger/tst_simple_analyze/testdata/events_qt5.tsv +++ b/tests/system/suite_debugger/tst_simple_analyze/testdata/events_qt5.tsv @@ -3,18 +3,7 @@ "main.qml:15" "Handling Signal" "2" "onTriggered: { runCount += 1; var i; for (i = 1; i < 2500; ++i) { var j = i * i; console.log(j); } }" "main.qml:15" "JavaScript" "2" "onTriggered" "main.qml:4" "Creating" "2" "QtQuick.Window/Window" -"main.qml:33" "Creating" "2" "QtQuick/TextEdit" "main.qml:1" "Compiling" "1" "main.qml" "main.qml:10" "Creating" "2" "QtQuick/Timer" -"main.qml:37" "Binding" "1" "anchors.top: parent.top" -"main.qml:40" "Creating" "2" "QtQuick/Rectangle" -"main.qml:37" "JavaScript" "1" "expression for top" "main.qml:14" "Binding" "3" "running: runCount < 2" -"main.qml:26" "Creating" "2" "QtQuick/MouseArea" -"main.qml:38" "Binding" "1" "anchors.horizontalCenter: parent.horizontalCenter" -"main.qml:38" "JavaScript" "1" "expression for horizontalCenter" -"main.qml:41" "Binding" "1" "anchors.fill: parent" -"main.qml:27" "Binding" "1" "anchors.fill: parent" "main.qml:14" "JavaScript" "3" "expression for running" -"main.qml:41" "JavaScript" "1" "expression for fill" -"main.qml:27" "JavaScript" "1" "expression for fill" diff --git a/tests/system/suite_debugger/tst_simple_debug/test.py b/tests/system/suite_debugger/tst_simple_debug/test.py index 54b0d652ee5..c726d6468bb 100644 --- a/tests/system/suite_debugger/tst_simple_debug/test.py +++ b/tests/system/suite_debugger/tst_simple_debug/test.py @@ -35,7 +35,9 @@ def main(): workingDir = tempDir() checkedTargets, projectName = createNewQtQuickApplication(workingDir, targets=targets) editor = waitForObject(":Qt Creator_QmlJSEditor::QmlJSTextEditorWidget") - if placeCursorToLine(editor, "MouseArea.*", True): + if placeCursorToLine(editor, "}"): + type(editor, '') + type(editor, '') type(editor, '') type(editor, '') typeLines(editor, ['Timer {', @@ -50,7 +52,7 @@ def main(): test.log("Setting breakpoints") result = setBreakpointsForCurrentProject(filesAndLines) if result: - expectedBreakpointsOrder = [{os.path.join(workingDir, projectName, "main.cpp"):8}, + expectedBreakpointsOrder = [{os.path.join(workingDir, projectName, "main.cpp"):10}, {os.path.join(workingDir, projectName, "main.qml"):13}] availableConfigs = iterateBuildConfigs(len(checkedTargets), "Debug") progressBarWait()