aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/projectexplorer/projectexplorer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/projectexplorer/projectexplorer.cpp')
-rw-r--r--src/plugins/projectexplorer/projectexplorer.cpp245
1 files changed, 154 insertions, 91 deletions
diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp
index c4a15ec526..8a7d3238ef 100644
--- a/src/plugins/projectexplorer/projectexplorer.cpp
+++ b/src/plugins/projectexplorer/projectexplorer.cpp
@@ -33,6 +33,7 @@
#include "compileoutputwindow.h"
#include "configtaskhandler.h"
#include "customexecutablerunconfiguration.h"
+#include "customparserssettingspage.h"
#include "customwizard/customwizard.h"
#include "deployablefile.h"
#include "deployconfiguration.h"
@@ -118,7 +119,6 @@
#include <coreplugin/fileutils.h>
#include <coreplugin/findplaceholder.h>
#include <coreplugin/icore.h>
-#include <coreplugin/id.h>
#include <coreplugin/idocument.h>
#include <coreplugin/idocumentfactory.h>
#include <coreplugin/imode.h>
@@ -146,16 +146,17 @@
#include <utils/stringutils.h>
#include <utils/utilsicons.h>
-#include <QFileInfo>
-#include <QSettings>
-
#include <QAction>
+#include <QActionGroup>
#include <QApplication>
#include <QDir>
#include <QFileDialog>
+#include <QFileInfo>
#include <QInputDialog>
#include <QMenu>
#include <QMessageBox>
+#include <QPair>
+#include <QSettings>
#include <QThreadPool>
#include <QTimer>
@@ -182,6 +183,7 @@
using namespace Core;
using namespace ProjectExplorer::Internal;
+using namespace Utils;
namespace ProjectExplorer {
@@ -282,6 +284,9 @@ const char SEPARATE_DEBUG_INFO_SETTINGS_KEY[] = "ProjectExplorer/Settings/Separa
const char QML_DEBUGGING_SETTINGS_KEY[] = "ProjectExplorer/Settings/QmlDebugging";
const char QT_QUICK_COMPILER_SETTINGS_KEY[] = "ProjectExplorer/Settings/QtQuickCompiler";
+const char CUSTOM_PARSER_COUNT_KEY[] = "ProjectExplorer/Settings/CustomParserCount";
+const char CUSTOM_PARSER_PREFIX_KEY[] = "ProjectExplorer/Settings/CustomParser";
+
} // namespace Constants
@@ -390,7 +395,7 @@ public:
void updateContextMenuActions();
void updateLocationSubMenus();
- void executeRunConfiguration(RunConfiguration *, Core::Id mode);
+ void executeRunConfiguration(RunConfiguration *, Utils::Id mode);
QPair<bool, QString> buildSettingsEnabledForSession();
QPair<bool, QString> buildSettingsEnabled(const Project *pro);
@@ -452,7 +457,7 @@ public:
void doUpdateRunActions();
- void currentModeChanged(Core::Id mode, Core::Id oldMode);
+ void currentModeChanged(Utils::Id mode, Utils::Id oldMode);
void updateWelcomePage();
@@ -519,6 +524,7 @@ public:
QAction *m_openFileAction;
QAction *m_projectTreeCollapseAllAction;
QAction *m_projectTreeExpandAllAction;
+ QAction *m_projectTreeExpandNodeAction = nullptr;
Utils::ParameterAction *m_closeProjectFilesActionFileMenu;
Utils::ParameterAction *m_closeProjectFilesActionContextMenu;
QAction *m_searchOnFileSystem;
@@ -549,9 +555,10 @@ public:
MiniProjectTargetSelector * m_targetSelector;
ProjectExplorerSettings m_projectExplorerSettings;
BuildPropertiesSettings m_buildPropertiesSettings;
+ QList<Internal::CustomParserSettings> m_customParsers;
bool m_shouldHaveRunConfiguration = false;
bool m_shuttingDown = false;
- Core::Id m_runMode = Constants::NO_RUN_MODE;
+ Utils::Id m_runMode = Constants::NO_RUN_MODE;
ToolChainManager *m_toolChainManager = nullptr;
QStringList m_arguments;
@@ -617,7 +624,7 @@ public:
RunWorkerFactory m_customExecutableRunWorkerFactory{
RunWorkerFactory::make<SimpleTargetRunner>(),
{Constants::NORMAL_RUN_MODE},
- {m_customExecutableRunConfigFactory.id()}
+ {m_customExecutableRunConfigFactory.runConfigurationId()}
};
ProjectFileWizardExtension m_projectFileWizardExtension;
@@ -629,6 +636,7 @@ public:
CompileOutputSettingsPage m_compileOutputSettingsPage;
DeviceSettingsPage m_deviceSettingsPage;
SshSettingsPage m_sshSettingsPage;
+ CustomParsersSettingsPage m_customParsersSettingsPage;
ProjectTreeWidgetFactory m_projectTreeFactory;
FolderNavigationWidgetFactory m_folderNavigationWidgetFactory;
@@ -649,7 +657,9 @@ public:
RunWorkerFactory desktopRunWorkerFactory{
RunWorkerFactory::make<SimpleTargetRunner>(),
{ProjectExplorer::Constants::NORMAL_RUN_MODE},
- {qmakeRunConfigFactory.id(), qbsRunConfigFactory.id(), cmakeRunConfigFactory.id()}
+ {qmakeRunConfigFactory.runConfigurationId(),
+ qbsRunConfigFactory.runConfigurationId(),
+ cmakeRunConfigFactory.runConfigurationId()}
};
};
@@ -752,6 +762,8 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
ProjectTree *tree = &dd->m_projectTree;
connect(tree, &ProjectTree::currentProjectChanged,
dd, &ProjectExplorerPluginPrivate::updateContextMenuActions);
+ connect(tree, &ProjectTree::nodeActionsChanged,
+ dd, &ProjectExplorerPluginPrivate::updateContextMenuActions);
connect(tree, &ProjectTree::currentNodeChanged,
dd, &ProjectExplorerPluginPrivate::updateContextMenuActions);
connect(tree, &ProjectTree::currentProjectChanged,
@@ -813,6 +825,8 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
});
ProjectPanelFactory::registerFactory(panelFactory);
+ RunConfiguration::registerAspect<CustomParsersAspect>();
+
// context menus
ActionContainer *msessionContextMenu =
ActionManager::createMenu(Constants::M_SESSIONCONTEXT);
@@ -926,7 +940,7 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
ActionManager::createMenu(ProjectExplorer::Constants::M_OPENTERMINALCONTEXT);
openTerminal->setOnAllDisabledBehavior(ActionContainer::Show);
dd->m_openTerminalMenu = openTerminal->menu();
- dd->m_openTerminalMenu->setTitle(FileUtils::msgTerminalWithAction());
+ dd->m_openTerminalMenu->setTitle(Core::FileUtils::msgTerminalWithAction());
// "open with" submenu
ActionContainer * const openWith =
@@ -980,7 +994,7 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
projectTreeContext);
mfileContextMenu->addAction(cmd, Constants::G_FILE_OPEN);
- dd->m_searchOnFileSystem = new QAction(FileUtils::msgFindInDirectory(), this);
+ dd->m_searchOnFileSystem = new QAction(Core::FileUtils::msgFindInDirectory(), this);
cmd = ActionManager::registerAction(dd->m_searchOnFileSystem, Constants::SEARCHONFILESYSTEM, projectTreeContext);
mfileContextMenu->addAction(cmd, Constants::G_FILE_OTHER);
@@ -988,14 +1002,14 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
msubProjectContextMenu->addAction(cmd, Constants::G_PROJECT_LAST);
mprojectContextMenu->addAction(cmd, Constants::G_PROJECT_LAST);
- dd->m_showInGraphicalShell = new QAction(FileUtils::msgGraphicalShellAction(), this);
+ dd->m_showInGraphicalShell = new QAction(Core::FileUtils::msgGraphicalShellAction(), this);
cmd = ActionManager::registerAction(dd->m_showInGraphicalShell, Constants::SHOWINGRAPHICALSHELL,
projectTreeContext);
mfileContextMenu->addAction(cmd, Constants::G_FILE_OPEN);
mfolderContextMenu->addAction(cmd, Constants::G_FOLDER_FILES);
// Open Terminal Here menu
- dd->m_openTerminalHere = new QAction(FileUtils::msgTerminalHereAction(), this);
+ dd->m_openTerminalHere = new QAction(Core::FileUtils::msgTerminalHereAction(), this);
cmd = ActionManager::registerAction(dd->m_openTerminalHere, Constants::OPENTERMINALHERE,
projectTreeContext);
@@ -1361,7 +1375,7 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
dd->m_removeFileAction = new QAction(this);
cmd = ActionManager::registerAction(dd->m_removeFileAction, Constants::REMOVEFILE,
projectTreeContext);
- cmd->setDefaultKeySequence(QKeySequence::Delete);
+ cmd->setDefaultKeySequences({QKeySequence::Delete, QKeySequence::Backspace});
mfileContextMenu->addAction(cmd, Constants::G_FILE_OTHER);
// duplicate file action
@@ -1380,7 +1394,7 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
dd->m_deleteFileAction = new QAction(tr("Delete File..."), this);
cmd = ActionManager::registerAction(dd->m_deleteFileAction, Constants::DELETEFILE,
projectTreeContext);
- cmd->setDefaultKeySequence(QKeySequence::Delete);
+ cmd->setDefaultKeySequences({QKeySequence::Delete, QKeySequence::Backspace});
mfileContextMenu->addAction(cmd, Constants::G_FILE_OTHER);
// renamefile action
@@ -1412,6 +1426,13 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
// Collapse & Expand.
const Id treeGroup = Constants::G_PROJECT_TREE;
+
+ dd->m_projectTreeExpandNodeAction = new QAction(tr("Expand"), this);
+ connect(dd->m_projectTreeExpandNodeAction, &QAction::triggered,
+ ProjectTree::instance(), &ProjectTree::expandCurrentNodeRecursively);
+ Command * const expandNodeCmd = ActionManager::registerAction(
+ dd->m_projectTreeExpandNodeAction, "ProjectExplorer.ExpandNode",
+ projectTreeContext);
dd->m_projectTreeCollapseAllAction = new QAction(tr("Collapse All"), this);
Command * const collapseCmd = ActionManager::registerAction(
dd->m_projectTreeCollapseAllAction, Constants::PROJECTTREE_COLLAPSE_ALL,
@@ -1423,6 +1444,7 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
for (Core::ActionContainer * const ac : {mfileContextMenu, msubProjectContextMenu,
mfolderContextMenu, mprojectContextMenu, msessionContextMenu}) {
ac->addSeparator(treeGroup);
+ ac->addAction(expandNodeCmd, treeGroup);
ac->addAction(collapseCmd, treeGroup);
ac->addAction(expandCmd, treeGroup);
}
@@ -1432,8 +1454,7 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
dd->m_projectSelectorAction->setObjectName("KitSelector"); // used for UI introduction
dd->m_projectSelectorAction->setCheckable(true);
dd->m_projectSelectorAction->setEnabled(false);
- QWidget *mainWindow = ICore::mainWindow();
- dd->m_targetSelector = new MiniProjectTargetSelector(dd->m_projectSelectorAction, mainWindow);
+ dd->m_targetSelector = new MiniProjectTargetSelector(dd->m_projectSelectorAction, ICore::dialogParent());
connect(dd->m_projectSelectorAction, &QAction::triggered,
dd->m_targetSelector, &QWidget::show);
ModeManager::addProjectSelector(dd->m_projectSelectorAction);
@@ -1511,7 +1532,7 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
tmp = Utils::HostOsInfo::isWindowsHost() ? 1 : 0;
dd->m_projectExplorerSettings.stopBeforeBuild = StopBeforeBuild(tmp);
dd->m_projectExplorerSettings.terminalMode = static_cast<TerminalMode>(s->value(
- Constants::TERMINAL_MODE_SETTINGS_KEY, int(TerminalMode::Smart)).toInt());
+ Constants::TERMINAL_MODE_SETTINGS_KEY, int(TerminalMode::Off)).toInt());
dd->m_projectExplorerSettings.closeSourceFilesWithProject
= s->value(Constants::CLOSE_FILES_WITH_PROJECT_SETTINGS_KEY, true).toBool();
dd->m_projectExplorerSettings.clearIssuesOnRebuild
@@ -1535,6 +1556,14 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
dd->m_buildPropertiesSettings.qtQuickCompiler
= loadTriStateValue(Constants::QT_QUICK_COMPILER_SETTINGS_KEY);
+ const int customParserCount = s->value(Constants::CUSTOM_PARSER_COUNT_KEY).toInt();
+ for (int i = 0; i < customParserCount; ++i) {
+ CustomParserSettings settings;
+ settings.fromMap(s->value(Constants::CUSTOM_PARSER_PREFIX_KEY
+ + QString::number(i)).toMap());
+ dd->m_customParsers << settings;
+ }
+
auto buildManager = new BuildManager(this, dd->m_cancelBuildAction);
connect(buildManager, &BuildManager::buildStateChanged,
dd, &ProjectExplorerPluginPrivate::updateActions);
@@ -1985,7 +2014,7 @@ void ProjectExplorerPlugin::extensionsInitialized()
const QString gitBinary = Core::ICore::settings()->value("Git/BinaryPath", "git")
.toString();
const QStringList rawGitSearchPaths = Core::ICore::settings()->value("Git/Path")
- .toString().split(':', QString::SkipEmptyParts);
+ .toString().split(':', Utils::SkipEmptyParts);
const Utils::FilePaths gitSearchPaths = Utils::transform(rawGitSearchPaths,
[](const QString &rawPath) { return Utils::FilePath::fromString(rawPath); });
const Utils::FilePath fullGitPath = Utils::Environment::systemEnvironment()
@@ -2004,7 +2033,7 @@ void ProjectExplorerPlugin::extensionsInitialized()
Command * const cmd = ActionManager::registerAction(parseIssuesAction,
"ProjectExplorer.ParseIssuesAction");
connect(parseIssuesAction, &QAction::triggered, this, [] {
- ParseIssuesDialog dlg(ICore::mainWindow());
+ ParseIssuesDialog dlg(ICore::dialogParent());
dlg.exec();
});
mtools->addAction(cmd);
@@ -2068,7 +2097,7 @@ void ProjectExplorerPlugin::openNewProjectDialog()
void ProjectExplorerPluginPrivate::showSessionManager()
{
SessionManager::save();
- SessionDialog sessionDialog(ICore::mainWindow());
+ SessionDialog sessionDialog(ICore::dialogParent());
sessionDialog.setAutoLoadSession(dd->m_projectExplorerSettings.autorestoreLastSession);
sessionDialog.exec();
dd->m_projectExplorerSettings.autorestoreLastSession = sessionDialog.autoLoadSession();
@@ -2169,6 +2198,12 @@ void ProjectExplorerPluginPrivate::savePersistentSettings()
dd->m_buildPropertiesSettings.qmlDebugging.toVariant());
s->setValue(Constants::QT_QUICK_COMPILER_SETTINGS_KEY,
dd->m_buildPropertiesSettings.qtQuickCompiler.toVariant());
+
+ s->setValue(Constants::CUSTOM_PARSER_COUNT_KEY, dd->m_customParsers.count());
+ for (int i = 0; i < dd->m_customParsers.count(); ++i) {
+ s->setValue(Constants::CUSTOM_PARSER_PREFIX_KEY + QString::number(i),
+ dd->m_customParsers.at(i).toMap());
+ }
}
void ProjectExplorerPlugin::openProjectWelcomePage(const QString &fileName)
@@ -2209,7 +2244,7 @@ void ProjectExplorerPlugin::showOpenProjectError(const OpenProjectResult &result
QString errorMessage = result.errorMessage();
if (!errorMessage.isEmpty()) {
// ignore alreadyOpen
- QMessageBox::critical(ICore::mainWindow(), tr("Failed to Open Project"), errorMessage);
+ QMessageBox::critical(ICore::dialogParent(), tr("Failed to Open Project"), errorMessage);
} else {
// ignore multiple alreadyOpen
Project *alreadyOpen = result.alreadyOpen().constFirst();
@@ -2351,6 +2386,11 @@ QThreadPool *ProjectExplorerPlugin::sharedThreadPool()
return &(dd->m_threadPool);
}
+MiniProjectTargetSelector *ProjectExplorerPlugin::targetSelector()
+{
+ return dd->m_targetSelector;
+}
+
/*!
This function is connected to the ICore::coreOpened signal. If
there was no session explicitly loaded, it creates an empty new
@@ -2414,7 +2454,7 @@ void ProjectExplorerPluginPrivate::restoreSession()
updateActions();
}
-void ProjectExplorerPluginPrivate::executeRunConfiguration(RunConfiguration *runConfiguration, Core::Id runMode)
+void ProjectExplorerPluginPrivate::executeRunConfiguration(RunConfiguration *runConfiguration, Utils::Id runMode)
{
const Tasks runConfigIssues = runConfiguration->checkForIssues();
if (!runConfigIssues.isEmpty()) {
@@ -2453,7 +2493,7 @@ void ProjectExplorerPluginPrivate::startRunControl(RunControl *runControl)
m_outputPane.createNewOutputWindow(runControl);
m_outputPane.flash(); // one flash for starting
m_outputPane.showTabFor(runControl);
- Core::Id runMode = runControl->runMode();
+ Utils::Id runMode = runControl->runMode();
const auto popupMode = runMode == Constants::NORMAL_RUN_MODE
? m_outputPane.settings().runOutputMode
: runMode == Constants::DEBUG_RUN_MODE
@@ -2696,17 +2736,6 @@ ProjectExplorerPluginPrivate::ProjectExplorerPluginPrivate()
m_allProjectDirectoriesFilter.setIsCustomFilter(false);
}
-QString ProjectExplorerPlugin::displayNameForStepId(Id stepId)
-{
- if (stepId == Constants::BUILDSTEPS_CLEAN)
- return tr("Clean");
- if (stepId == Constants::BUILDSTEPS_BUILD)
- return tr("Build", "Build step");
- if (stepId == Constants::BUILDSTEPS_DEPLOY)
- return tr("Deploy");
- return tr("Build", "Build step");
-}
-
void ProjectExplorerPluginPrivate::runProjectContextMenu()
{
const Node *node = ProjectTree::currentNode();
@@ -2844,7 +2873,7 @@ static bool hasDeploySettings(Project *pro)
});
}
-void ProjectExplorerPlugin::runProject(Project *pro, Core::Id mode, const bool forceSkipDeploy)
+void ProjectExplorerPlugin::runProject(Project *pro, Utils::Id mode, const bool forceSkipDeploy)
{
if (!pro)
return;
@@ -2854,13 +2883,13 @@ void ProjectExplorerPlugin::runProject(Project *pro, Core::Id mode, const bool f
runRunConfiguration(rc, mode, forceSkipDeploy);
}
-void ProjectExplorerPlugin::runStartupProject(Core::Id runMode, bool forceSkipDeploy)
+void ProjectExplorerPlugin::runStartupProject(Utils::Id runMode, bool forceSkipDeploy)
{
runProject(SessionManager::startupProject(), runMode, forceSkipDeploy);
}
void ProjectExplorerPlugin::runRunConfiguration(RunConfiguration *rc,
- Core::Id runMode,
+ Utils::Id runMode,
const bool forceSkipDeploy)
{
if (!rc->isEnabled())
@@ -2970,7 +2999,7 @@ void ProjectExplorerPluginPrivate::updateDeployActions()
doUpdateRunActions();
}
-bool ProjectExplorerPlugin::canRunStartupProject(Core::Id runMode, QString *whyNot)
+bool ProjectExplorerPlugin::canRunStartupProject(Utils::Id runMode, QString *whyNot)
{
Project *project = SessionManager::startupProject();
if (!project) {
@@ -3236,20 +3265,28 @@ void ProjectExplorerPluginPrivate::updateContextMenuActions()
return currentNode->supportsAction(action, currentNode);
};
+ bool canEditProject = true;
+ if (project && project->activeTarget()) {
+ const BuildSystem * const bs = project->activeTarget()->buildSystem();
+ if (bs->isParsing() || bs->isWaitingForParse())
+ canEditProject = false;
+ }
if (currentNode->asFolderNode()) {
// Also handles ProjectNode
- m_addNewFileAction->setEnabled(supports(AddNewFile)
+ m_addNewFileAction->setEnabled(canEditProject && supports(AddNewFile)
&& !ICore::isNewItemDialogRunning());
- m_addNewSubprojectAction->setEnabled(currentNode->isProjectNodeType()
+ m_addNewSubprojectAction->setEnabled(canEditProject && currentNode->isProjectNodeType()
&& supports(AddSubProject)
&& !ICore::isNewItemDialogRunning());
- m_addExistingProjectsAction->setEnabled(currentNode->isProjectNodeType()
+ m_addExistingProjectsAction->setEnabled(canEditProject
+ && currentNode->isProjectNodeType()
&& supports(AddExistingProject));
- m_removeProjectAction->setEnabled(currentNode->isProjectNodeType()
+ m_removeProjectAction->setEnabled(canEditProject && currentNode->isProjectNodeType()
&& supports(RemoveSubProject));
- m_addExistingFilesAction->setEnabled(supports(AddExistingFile));
- m_addExistingDirectoryAction->setEnabled(supports(AddExistingDirectory));
- m_renameFileAction->setEnabled(supports(Rename));
+ m_addExistingFilesAction->setEnabled(canEditProject && supports(AddExistingFile));
+ m_addExistingDirectoryAction->setEnabled(canEditProject
+ && supports(AddExistingDirectory));
+ m_renameFileAction->setEnabled(canEditProject && supports(Rename));
} else if (auto fileNode = currentNode->asFileNode()) {
// Enable and show remove / delete in magic ways:
// If both are disabled show Remove
@@ -3257,20 +3294,20 @@ void ProjectExplorerPluginPrivate::updateContextMenuActions()
// If only removeFile is enabled only show it
// If only deleteFile is enable only show it
bool isTypeProject = fileNode->fileType() == FileType::Project;
- bool enableRemove = !isTypeProject && supports(RemoveFile);
+ bool enableRemove = canEditProject && !isTypeProject && supports(RemoveFile);
m_removeFileAction->setEnabled(enableRemove);
- bool enableDelete = !isTypeProject && supports(EraseFile);
+ bool enableDelete = canEditProject && !isTypeProject && supports(EraseFile);
m_deleteFileAction->setEnabled(enableDelete);
m_deleteFileAction->setVisible(enableDelete);
m_removeFileAction->setVisible(!enableDelete || enableRemove);
- m_renameFileAction->setEnabled(!isTypeProject && supports(Rename));
+ m_renameFileAction->setEnabled(canEditProject && !isTypeProject && supports(Rename));
const bool currentNodeIsTextFile = isTextFile(
currentNode->filePath().toString());
m_diffFileAction->setEnabled(DiffService::instance()
&& currentNodeIsTextFile && TextEditor::TextDocument::currentTextDocument());
- const bool canDuplicate = supports(AddNewFile)
+ const bool canDuplicate = canEditProject && supports(AddNewFile)
&& currentNode->asFileNode()->fileType() != FileType::Project;
m_duplicateFileAction->setVisible(canDuplicate);
m_duplicateFileAction->setEnabled(canDuplicate);
@@ -3390,7 +3427,7 @@ void ProjectExplorerPluginPrivate::addNewSubproject()
QVariantMap map;
map.insert(QLatin1String(Constants::PREFERRED_PROJECT_NODE), QVariant::fromValue(currentNode));
Project *project = ProjectTree::currentProject();
- Core::Id projectType;
+ Utils::Id projectType;
if (project) {
const QStringList profileIds = Utils::transform(ProjectTree::currentProject()->targets(),
[](const Target *t) {
@@ -3420,7 +3457,7 @@ void ProjectExplorerPluginPrivate::addExistingProjects()
QTC_ASSERT(projectNode, return);
const QString dir = currentNode->directory();
QStringList subProjectFilePaths = QFileDialog::getOpenFileNames(
- ICore::mainWindow(), tr("Choose Project File"), dir,
+ ICore::dialogParent(), tr("Choose Project File"), dir,
projectNode->subProjectFileNamePatterns().join(";;"));
if (!ProjectTree::hasNode(projectNode))
return;
@@ -3443,7 +3480,7 @@ void ProjectExplorerPluginPrivate::addExistingProjects()
if (!failedProjects.empty()) {
const QString message = tr("The following subprojects could not be added to project "
"\"%1\":").arg(projectNode->managingProject()->displayName());
- QMessageBox::warning(ICore::mainWindow(), tr("Adding Subproject Failed"),
+ QMessageBox::warning(ICore::dialogParent(), tr("Adding Subproject Failed"),
message + "\n " + failedProjects.join("\n "));
return;
}
@@ -3457,7 +3494,7 @@ void ProjectExplorerPluginPrivate::handleAddExistingFiles()
QTC_ASSERT(folderNode, return);
- QStringList fileNames = QFileDialog::getOpenFileNames(ICore::mainWindow(),
+ QStringList fileNames = QFileDialog::getOpenFileNames(ICore::dialogParent(),
tr("Add Existing Files"), node->directory());
if (fileNames.isEmpty())
return;
@@ -3473,7 +3510,7 @@ void ProjectExplorerPluginPrivate::addExistingDirectory()
QTC_ASSERT(folderNode, return);
SelectableFilesDialogAddDirectory dialog(Utils::FilePath::fromString(node->directory()),
- Utils::FilePaths(), ICore::mainWindow());
+ Utils::FilePaths(), ICore::dialogParent());
dialog.setAddFileFilter({});
if (dialog.exec() == QDialog::Accepted)
@@ -3496,7 +3533,7 @@ void ProjectExplorerPlugin::addExistingFiles(FolderNode *folderNode, const QStri
.arg(folderNode->managingProject()->displayName()) + QLatin1Char('\n');
const QStringList nativeFiles
= Utils::transform(notAdded, &QDir::toNativeSeparators);
- QMessageBox::warning(ICore::mainWindow(), tr("Adding Files to Project Failed"),
+ QMessageBox::warning(ICore::dialogParent(), tr("Adding Files to Project Failed"),
message + nativeFiles.join(QLatin1Char('\n')));
fileNames = Utils::filtered(fileNames,
[&notAdded](const QString &f) { return !notAdded.contains(f); });
@@ -3512,7 +3549,7 @@ void ProjectExplorerPluginPrivate::removeProject()
return;
ProjectNode *projectNode = node->managingProject();
if (projectNode) {
- Utils::RemoveFileDialog removeFileDialog(node->filePath().toString(), ICore::mainWindow());
+ Utils::RemoveFileDialog removeFileDialog(node->filePath().toString(), ICore::dialogParent());
removeFileDialog.setDeleteFileVisible(false);
if (removeFileDialog.exec() == QDialog::Accepted)
projectNode->removeSubProject(node->filePath().toString());
@@ -3537,7 +3574,7 @@ void ProjectExplorerPluginPrivate::showInGraphicalShell()
{
Node *currentNode = ProjectTree::currentNode();
QTC_ASSERT(currentNode, return);
- FileUtils::showInGraphicalShell(ICore::mainWindow(), currentNode->path());
+ Core::FileUtils::showInGraphicalShell(ICore::dialogParent(), currentNode->path());
}
void ProjectExplorerPluginPrivate::openTerminalHere(const EnvironmentGetter &env)
@@ -3549,7 +3586,7 @@ void ProjectExplorerPluginPrivate::openTerminalHere(const EnvironmentGetter &env
if (!environment)
return;
- FileUtils::openTerminal(currentNode->directory(), environment.value());
+ Core::FileUtils::openTerminal(currentNode->directory(), environment.value());
}
void ProjectExplorerPluginPrivate::openTerminalHereWithRunEnv()
@@ -3580,40 +3617,56 @@ void ProjectExplorerPluginPrivate::removeFile()
QTC_ASSERT(currentNode && currentNode->asFileNode(), return);
const Utils::FilePath filePath = currentNode->filePath();
- Utils::RemoveFileDialog removeFileDialog(filePath.toString(), ICore::mainWindow());
-
- if (removeFileDialog.exec() == QDialog::Accepted) {
- const bool deleteFile = removeFileDialog.isDeleteFileChecked();
+ using NodeAndPath = QPair<const Node *, Utils::FilePath>;
+ QList<NodeAndPath> filesToRemove{qMakePair(currentNode, currentNode->filePath())};
+ QList<NodeAndPath> siblings;
+ for (const Node * const n : ProjectTree::siblingsWithSameBaseName(currentNode))
+ siblings << qMakePair(n, n->filePath());
+
+ Utils::RemoveFileDialog removeFileDialog(filePath.toString(), ICore::dialogParent());
+ if (removeFileDialog.exec() != QDialog::Accepted)
+ return;
- // Re-read the current node, in case the project is re-parsed while the dialog is open
- if (!ProjectTree::hasNode(currentNode)) {
- QMessageBox::warning(ICore::mainWindow(), tr("Removing File Failed"),
- tr("File %1 was not removed, because the project has changed "
+ const bool deleteFile = removeFileDialog.isDeleteFileChecked();
+
+ const QMessageBox::StandardButton reply = QMessageBox::question(
+ Core::ICore::dialogParent(), tr("Remove More Files?"),
+ tr("Remove these files as well?\n %1")
+ .arg(Utils::transform<QStringList>(siblings, [](const NodeAndPath &np) {
+ return np.second.toFileInfo().fileName();
+ }).join("\n ")));
+ if (reply == QMessageBox::Yes)
+ filesToRemove << siblings;
+
+ for (const NodeAndPath &file : filesToRemove) {
+ // Nodes can become invalid if the project was re-parsed while the dialog was open
+ if (!ProjectTree::hasNode(file.first)) {
+ QMessageBox::warning(ICore::dialogParent(), tr("Removing File Failed"),
+ tr("File \"%1\" was not removed, because the project has changed "
"in the meantime.\nPlease try again.")
- .arg(filePath.toUserOutput()));
+ .arg(file.second.toUserOutput()));
return;
}
// remove from project
- FolderNode *folderNode = currentNode->asFileNode()->parentFolderNode();
+ FolderNode *folderNode = file.first->asFileNode()->parentFolderNode();
QTC_ASSERT(folderNode, return);
const RemovedFilesFromProject status
- = folderNode->removeFiles(QStringList(filePath.toString()));
+ = folderNode->removeFiles(QStringList(file.second.toString()));
const bool success = status == RemovedFilesFromProject::Ok
|| (status == RemovedFilesFromProject::Wildcard
&& removeFileDialog.isDeleteFileChecked());
if (!success) {
- QMessageBox::warning(ICore::mainWindow(), tr("Removing File Failed"),
- tr("Could not remove file %1 from project %2.")
- .arg(filePath.toUserOutput())
- .arg(folderNode->managingProject()->displayName()));
+ TaskHub::addTask(BuildSystemTask(Task::Error,
+ tr("Could not remove file \"%1\" from project \"%2\".")
+ .arg(filePath.toUserOutput(), folderNode->managingProject()->displayName()),
+ folderNode->managingProject()->filePath()));
if (!deleteFile)
- return;
+ continue;
}
-
FileChangeBlocker changeGuard(filePath.toString());
- FileUtils::removeFile(filePath.toString(), deleteFile);
+ Core::FileUtils::removeFile(filePath.toString(), deleteFile);
}
}
@@ -3632,7 +3685,7 @@ void ProjectExplorerPluginPrivate::duplicateFile()
newFileName.insert(copyTokenIndex, tr("_copy"));
bool okPressed;
- newFileName = QInputDialog::getText(ICore::mainWindow(), tr("Choose File Name"),
+ newFileName = QInputDialog::getText(ICore::dialogParent(), tr("Choose File Name"),
tr("New file name:"), QLineEdit::Normal, newFileName, &okPressed);
if (!okPressed)
return;
@@ -3644,14 +3697,14 @@ void ProjectExplorerPluginPrivate::duplicateFile()
QTC_ASSERT(folderNode, return);
QFile sourceFile(filePath);
if (!sourceFile.copy(newFilePath)) {
- QMessageBox::critical(ICore::mainWindow(), tr("Duplicating File Failed"),
+ QMessageBox::critical(ICore::dialogParent(), tr("Duplicating File Failed"),
tr("Failed to copy file \"%1\" to \"%2\": %3.")
.arg(QDir::toNativeSeparators(filePath),
QDir::toNativeSeparators(newFilePath), sourceFile.errorString()));
return;
}
if (!folderNode->addFiles(QStringList(newFilePath))) {
- QMessageBox::critical(ICore::mainWindow(), tr("Duplicating File Failed"),
+ QMessageBox::critical(ICore::dialogParent(), tr("Duplicating File Failed"),
tr("Failed to add new file \"%1\" to the project.")
.arg(QDir::toNativeSeparators(newFilePath)));
}
@@ -3666,7 +3719,7 @@ void ProjectExplorerPluginPrivate::deleteFile()
QString filePath = currentNode->filePath().toString();
QMessageBox::StandardButton button =
- QMessageBox::question(ICore::mainWindow(),
+ QMessageBox::question(ICore::dialogParent(),
tr("Delete File"),
tr("Delete %1 from file system?")
.arg(QDir::toNativeSeparators(filePath)),
@@ -3687,7 +3740,7 @@ void ProjectExplorerPluginPrivate::deleteFile()
QFile file(filePath);
if (file.exists()) {
if (!file.remove())
- QMessageBox::warning(ICore::mainWindow(), tr("Deleting File Failed"),
+ QMessageBox::warning(ICore::dialogParent(), tr("Deleting File Failed"),
tr("Could not delete file %1.")
.arg(QDir::toNativeSeparators(filePath)));
}
@@ -3718,7 +3771,7 @@ void ProjectExplorerPlugin::renameFile(Node *node, const QString &newFilePath)
if (!folderNode->canRenameFile(oldFilePath, newFilePath)) {
QTimer::singleShot(0, [oldFilePath, newFilePath, projectFileName] {
- int res = QMessageBox::question(ICore::mainWindow(),
+ int res = QMessageBox::question(ICore::dialogParent(),
tr("Project Editing Failed"),
tr("The project file %1 cannot be automatically changed.\n\n"
"Rename %2 to %3 anyway?")
@@ -3726,14 +3779,13 @@ void ProjectExplorerPlugin::renameFile(Node *node, const QString &newFilePath)
.arg(QDir::toNativeSeparators(oldFilePath))
.arg(QDir::toNativeSeparators(newFilePath)));
if (res == QMessageBox::Yes) {
- QTC_CHECK(FileUtils::renameFile(oldFilePath, newFilePath));
+ QTC_CHECK(Core::FileUtils::renameFile(oldFilePath, newFilePath));
}
-
});
return;
}
- if (FileUtils::renameFile(oldFilePath, newFilePath)) {
+ if (Core::FileUtils::renameFile(oldFilePath, newFilePath)) {
// Tell the project plugin about rename
if (!folderNode->renameFile(oldFilePath, newFilePath)) {
const QString renameFileError
@@ -3743,7 +3795,7 @@ void ProjectExplorerPlugin::renameFile(Node *node, const QString &newFilePath)
.arg(projectFileName);
QTimer::singleShot(0, [renameFileError]() {
- QMessageBox::warning(ICore::mainWindow(),
+ QMessageBox::warning(ICore::dialogParent(),
tr("Project Editing Failed"),
renameFileError);
});
@@ -3754,9 +3806,7 @@ void ProjectExplorerPlugin::renameFile(Node *node, const QString &newFilePath)
.arg(QDir::toNativeSeparators(newFilePath));
QTimer::singleShot(0, [renameFileError]() {
- QMessageBox::warning(ICore::mainWindow(),
- tr("Cannot Rename File"),
- renameFileError);
+ QMessageBox::warning(ICore::dialogParent(), tr("Cannot Rename File"), renameFileError);
});
}
}
@@ -3839,6 +3889,19 @@ void ProjectExplorerPlugin::showQtSettings()
dd->m_buildPropertiesSettings.showQtSettings = true;
}
+void ProjectExplorerPlugin::setCustomParsers(const QList<CustomParserSettings> &settings)
+{
+ if (dd->m_customParsers != settings) {
+ dd->m_customParsers = settings;
+ emit m_instance->customParsersChanged();
+ }
+}
+
+const QList<CustomParserSettings> ProjectExplorerPlugin::customParsers()
+{
+ return dd->m_customParsers;
+}
+
QStringList ProjectExplorerPlugin::projectFilePatterns()
{
QStringList patterns;
@@ -3890,7 +3953,7 @@ void ProjectExplorerPlugin::updateActions()
dd->updateActions();
}
-void ProjectExplorerPlugin::activateProjectPanel(Core::Id panelId)
+void ProjectExplorerPlugin::activateProjectPanel(Utils::Id panelId)
{
Core::ModeManager::activateMode(Constants::MODE_SESSION);
dd->m_proWindow->activateProjectPanel(panelId);