diff --git a/src/plugins/qmlprojectmanager/buildsystem/qmlbuildsystem.cpp b/src/plugins/qmlprojectmanager/buildsystem/qmlbuildsystem.cpp index d07df6b0fe3..6ecdeed638b 100644 --- a/src/plugins/qmlprojectmanager/buildsystem/qmlbuildsystem.cpp +++ b/src/plugins/qmlprojectmanager/buildsystem/qmlbuildsystem.cpp @@ -5,6 +5,7 @@ #include "../qmlprojectconstants.h" #include "../qmlprojectmanagertr.h" +#include "../qmlproject.h" #include #include @@ -155,6 +156,11 @@ bool QmlBuildSystem::updateProjectFile() return true; } +QmlProject *QmlBuildSystem::qmlProject() const +{ + return qobject_cast(project()); +} + void QmlBuildSystem::triggerParsing() { refresh(RefreshOptions::Project); @@ -315,6 +321,66 @@ void QmlBuildSystem::setBlockFilesUpdate(bool newBlockFilesUpdate) m_blockFilesUpdate = newBlockFilesUpdate; } +Utils::FilePath QmlBuildSystem::getStartupQmlFileWithFallback() const +{ + const auto currentProject = project(); + + if (!currentProject) + return {}; + + if (!target()) + return {}; + + const auto getFirstFittingFile = [](const Utils::FilePaths &files) -> Utils::FilePath { + for (const auto &file : files) { + if (file.exists()) + return file; + } + return {}; + }; + + const QStringView uiqmlstr = u"ui.qml"; + const QStringView qmlstr = u"qml"; + + //we will check mainUiFile twice: + //first priority if it's ui.qml file, second if it's just a qml file + const Utils::FilePath mainUiFile = mainUiFilePath(); + if (mainUiFile.exists() && mainUiFile.completeSuffix() == uiqmlstr) + return mainUiFile; + + const Utils::FilePaths uiFiles = currentProject->files([&](const ProjectExplorer::Node *node) { + return node->filePath().completeSuffix() == uiqmlstr; + }); + if (!uiFiles.isEmpty()) { + if (const auto file = getFirstFittingFile(uiFiles); !file.isEmpty()) + return file; + } + + //check the suffix of mainUiFile again, since there are no ui.qml files: + if (mainUiFile.exists() && mainUiFile.completeSuffix() == qmlstr) + return mainUiFile; + + const Utils::FilePath mainQmlFile = mainFilePath(); + if (mainQmlFile.exists() && mainQmlFile.completeSuffix() == qmlstr) + return mainQmlFile; + + //maybe it's also worth priotizing qml files containing common words like "Screen"? + const Utils::FilePaths qmlFiles = currentProject->files([&](const ProjectExplorer::Node *node) { + return node->filePath().completeSuffix() == qmlstr; + }); + if (!qmlFiles.isEmpty()) { + if (const auto file = getFirstFittingFile(qmlFiles); !file.isEmpty()) + return file; + } + + //if no source files exist in the project, lets try to open the .qmlproject file itself + const Utils::FilePath projectFile = projectFilePath(); + if (projectFile.exists()) + return projectFile; + + return {}; +} + Utils::FilePath QmlBuildSystem::mainFilePath() const { const QString fileName = mainFile(); diff --git a/src/plugins/qmlprojectmanager/buildsystem/qmlbuildsystem.h b/src/plugins/qmlprojectmanager/buildsystem/qmlbuildsystem.h index 0a0e9cfcbaf..2d689a19712 100644 --- a/src/plugins/qmlprojectmanager/buildsystem/qmlbuildsystem.h +++ b/src/plugins/qmlprojectmanager/buildsystem/qmlbuildsystem.h @@ -94,6 +94,8 @@ public: bool blockFilesUpdate() const; void setBlockFilesUpdate(bool newBlockFilesUpdate); + Utils::FilePath getStartupQmlFileWithFallback() const; + signals: void projectChanged(); diff --git a/src/plugins/qmlprojectmanager/qmlproject.cpp b/src/plugins/qmlprojectmanager/qmlproject.cpp index 45aedb0177f..12e1b9f7cbe 100644 --- a/src/plugins/qmlprojectmanager/qmlproject.cpp +++ b/src/plugins/qmlprojectmanager/qmlproject.cpp @@ -67,40 +67,24 @@ void QmlProject::parsingFinished(const Target *target, bool success) // trigger only once disconnect(this, &QmlProject::anyParsingFinished, this, &QmlProject::parsingFinished); - // FIXME: what to do in this case? if (!target || !success || !activeTarget()) return; - auto targetActive = activeTarget(); - auto qmlBuildSystem = qobject_cast( - targetActive->buildSystem()); - - const Utils::FilePath mainUiFile = qmlBuildSystem->mainUiFilePath(); - - if (mainUiFile.completeSuffix() == "ui.qml" && mainUiFile.exists()) { - QTimer::singleShot(1000, [mainUiFile]() { - Core::EditorManager::openEditor(mainUiFile, Utils::Id()); - }); + const auto qmlBuildSystem = qobject_cast( + activeTarget()->buildSystem()); + if (!qmlBuildSystem) return; - } - Utils::FilePaths uiFiles = collectUiQmlFilesForFolder( - projectDirectory().pathAppended("content")); - if (uiFiles.isEmpty()) { - uiFiles = collectUiQmlFilesForFolder(projectDirectory()); - if (uiFiles.isEmpty()) - return; - } - - Utils::FilePath currentFile; - if (auto cd = Core::EditorManager::currentDocument()) - currentFile = cd->filePath(); - - if (currentFile.isEmpty() || !isKnownFile(currentFile)) { - QTimer::singleShot(1000, [uiFiles]() { - Core::EditorManager::openEditor(uiFiles.first(), Utils::Id()); + const auto openFile = [&](const Utils::FilePath file) { + //why is this timer needed here? + QTimer::singleShot(1000, this, [file] { + Core::EditorManager::openEditor(file, Utils::Id()); }); - } + }; + + const Utils::FilePath fileToOpen = qmlBuildSystem->getStartupQmlFileWithFallback(); + if (!fileToOpen.isEmpty() && fileToOpen.exists() && !fileToOpen.isDir()) + openFile(fileToOpen); } Project::RestoreResult QmlProject::fromMap(const QVariantMap &map, QString *errorMessage) @@ -175,6 +159,14 @@ Utils::FilePaths QmlProject::collectUiQmlFilesForFolder(const Utils::FilePath &f return uiFiles; } +Utils::FilePaths QmlProject::collectQmlFiles() const +{ + const Utils::FilePaths qmlFiles = files([&](const Node *node) { + return node->filePath().completeSuffix() == "qml"; + }); + return qmlFiles; +} + Tasks QmlProject::projectIssues(const Kit *k) const { Tasks result = Project::projectIssues(k); diff --git a/src/plugins/studiowelcome/studiowelcomeplugin.cpp b/src/plugins/studiowelcome/studiowelcomeplugin.cpp index 5729b952e9e..7e9fce6f131 100644 --- a/src/plugins/studiowelcome/studiowelcomeplugin.cpp +++ b/src/plugins/studiowelcome/studiowelcomeplugin.cpp @@ -103,30 +103,20 @@ static StudioWelcomePlugin *s_pluginInstance = nullptr; static Utils::FilePath getMainUiFileWithFallback() { - auto project = ProjectExplorer::ProjectManager::startupProject(); + const auto project = ProjectExplorer::ProjectManager::startupProject(); if (!project) return {}; if (!project->activeTarget()) return {}; - auto qmlBuildSystem = qobject_cast( + const auto qmlBuildSystem = qobject_cast( project->activeTarget()->buildSystem()); if (!qmlBuildSystem) return {}; - auto mainUiFile = qmlBuildSystem->mainUiFilePath(); - if (mainUiFile.exists()) - return mainUiFile; - - const Utils::FilePaths uiFiles = project->files([&](const ProjectExplorer::Node *node) { - return node->filePath().completeSuffix() == "ui.qml"; - }); - if (!uiFiles.isEmpty()) - return uiFiles.first(); - - return {}; + return qmlBuildSystem->getStartupQmlFileWithFallback(); } std::unique_ptr makeUserFeedbackSettings() @@ -255,14 +245,16 @@ public: return; m_blockOpenRecent = true; - const FilePath projectFile = FilePath::fromVariant(data(index(row, 0), ProjectModel::FilePathRole)); + const FilePath projectFile = FilePath::fromVariant( + data(index(row, 0), ProjectModel::FilePathRole)); if (projectFile.exists()) { const ProjectExplorerPlugin::OpenProjectResult result = ProjectExplorer::ProjectExplorerPlugin::openProject(projectFile); if (!result && !result.alreadyOpen().isEmpty()) { - const auto mainUiFile = getMainUiFileWithFallback(); - if (mainUiFile.exists()) - Core::EditorManager::openEditor(mainUiFile, Utils::Id()); + const auto fileToOpen = getMainUiFileWithFallback(); + if (!fileToOpen.isEmpty() && fileToOpen.exists() && !fileToOpen.isDir()) { + Core::EditorManager::openEditor(fileToOpen, Utils::Id()); + } }; }