1 /**************************************************************************
3 ** This file is part of Qt Creator
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
7 ** Contact: Nokia Corporation (qt-info@nokia.com)
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 ** In addition, as a special exception, Nokia gives you certain additional
26 ** rights. These rights are described in the Nokia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 ** If you have questions regarding the use of this file, please contact
30 ** Nokia at qt-info@nokia.com.
32 **************************************************************************/
34 #include "projectexplorer.h"
36 #include "buildsteplist.h"
37 #include "deployconfiguration.h"
38 #include "gcctoolchainfactories.h"
40 #include "projectexplorersettings.h"
42 #include "targetsettingspanel.h"
43 #include "toolchainmanager.h"
44 #include "toolchainoptionspage.h"
45 #include "copytaskhandler.h"
46 #include "showineditortaskhandler.h"
47 #include "vcsannotatetaskhandler.h"
48 #include "localapplicationruncontrol.h"
49 #include "allprojectsfilter.h"
50 #include "allprojectsfind.h"
51 #include "buildmanager.h"
52 #include "buildsettingspropertiespage.h"
53 #include "currentprojectfind.h"
54 #include "currentprojectfilter.h"
55 #include "customexecutablerunconfiguration.h"
56 #include "editorsettingspropertiespage.h"
57 #include "dependenciespanel.h"
58 #include "foldernavigationwidget.h"
59 #include "iprojectmanager.h"
60 #include "metatypedeclarations.h"
61 #include "nodesvisitor.h"
62 #include "outputwindow.h"
63 #include "persistentsettings.h"
64 #include "pluginfilefactory.h"
65 #include "processstep.h"
66 #include "projectexplorerconstants.h"
67 #include "customwizard.h"
68 #include "projectfilewizardextension.h"
69 #include "projecttreewidget.h"
70 #include "projectwindow.h"
71 #include "removefiledialog.h"
72 #include "runsettingspropertiespage.h"
73 #include "scriptwrappers.h"
75 #include "projectnodes.h"
76 #include "sessiondialog.h"
78 #include "projectexplorersettingspage.h"
79 #include "projectwelcomepage.h"
80 #include "projectwelcomepagewidget.h"
81 #include "corelistenercheckingforrunningbuild.h"
82 #include "buildconfiguration.h"
83 #include "miniprojecttargetselector.h"
85 #include "publishing/ipublishingwizardfactory.h"
86 #include "publishing/publishingwizardselectiondialog.h"
89 # include "msvctoolchain.h"
92 #include <coreplugin/coreconstants.h>
93 #include <coreplugin/filemanager.h>
94 #include <coreplugin/icore.h>
95 #include <coreplugin/imode.h>
96 #include <coreplugin/mimedatabase.h>
97 #include <coreplugin/modemanager.h>
98 #include <coreplugin/actionmanager/actionmanager.h>
99 #include <coreplugin/actionmanager/actioncontainer.h>
100 #include <coreplugin/actionmanager/command.h>
101 #include <coreplugin/uniqueidmanager.h>
102 #include <coreplugin/editormanager/editormanager.h>
103 #include <coreplugin/editormanager/ieditor.h>
104 #include <coreplugin/editormanager/ieditorfactory.h>
105 #include <coreplugin/editormanager/iexternaleditor.h>
106 #include <coreplugin/findplaceholder.h>
107 #include <coreplugin/basefilewizard.h>
108 #include <coreplugin/vcsmanager.h>
109 #include <coreplugin/iversioncontrol.h>
110 #include <coreplugin/variablemanager.h>
111 #include <welcome/welcomemode.h>
112 #include <extensionsystem/pluginmanager.h>
113 #include <find/searchresultwindow.h>
114 #include <utils/consoleprocess.h>
115 #include <utils/qtcassert.h>
116 #include <utils/parameteraction.h>
117 #include <utils/stringutils.h>
119 #include <QtCore/QtPlugin>
120 #include <QtCore/QDateTime>
121 #include <QtCore/QDebug>
122 #include <QtCore/QSettings>
124 #include <QtGui/QAction>
125 #include <QtGui/QApplication>
126 #include <QtGui/QFileDialog>
127 #include <QtGui/QMenu>
128 #include <QtGui/QMessageBox>
129 #include <QtGui/QMainWindow>
130 #include <QtGui/QWizard>
132 Q_DECLARE_METATYPE(Core::IEditorFactory*)
133 Q_DECLARE_METATYPE(Core::IExternalEditor*)
139 static const char * const kCurrentProjectPath = "CurrentProject:Path";
140 static const char * const kCurrentProjectFilePath = "CurrentProject:FilePath";
142 namespace ProjectExplorer {
144 struct ProjectExplorerPluginPrivate {
145 ProjectExplorerPluginPrivate();
147 QMenu *m_sessionContextMenu;
148 QMenu *m_sessionMenu;
149 QMenu *m_projectMenu;
150 QMenu *m_subProjectMenu;
153 QMenu *m_openWithMenu;
155 QMultiMap<int, QObject*> m_actionMap;
156 QAction *m_sessionManagerAction;
157 QAction *m_newAction;
158 QAction *m_loadAction;
159 Utils::ParameterAction *m_unloadAction;
160 QAction *m_clearSession;
161 QAction *m_buildProjectOnlyAction;
162 Utils::ParameterAction *m_buildAction;
163 Utils::ParameterAction *m_buildActionContextMenu;
164 QAction *m_buildSessionAction;
165 QAction *m_rebuildProjectOnlyAction;
166 Utils::ParameterAction *m_rebuildAction;
167 Utils::ParameterAction *m_rebuildActionContextMenu;
168 QAction *m_rebuildSessionAction;
169 QAction *m_cleanProjectOnlyAction;
170 QAction *m_deployProjectOnlyAction;
171 Utils::ParameterAction *m_deployAction;
172 Utils::ParameterAction *m_deployActionContextMenu;
173 QAction *m_deploySessionAction;
174 Utils::ParameterAction *m_publishAction;
175 Utils::ParameterAction *m_cleanAction;
176 Utils::ParameterAction *m_cleanActionContextMenu;
177 QAction *m_cleanSessionAction;
178 QAction *m_runAction;
179 QAction *m_runActionContextMenu;
180 QAction *m_cancelBuildAction;
181 QAction *m_addNewFileAction;
182 QAction *m_addExistingFilesAction;
183 QAction *m_addNewSubprojectAction;
184 QAction *m_removeFileAction;
185 QAction *m_removeProjectAction;
186 QAction *m_deleteFileAction;
187 QAction *m_renameFileAction;
188 QAction *m_openFileAction;
189 QAction *m_showInGraphicalShell;
190 QAction *m_openTerminalHere;
191 QAction *m_setStartupProjectAction;
192 QAction *m_projectSelectorAction;
193 QAction *m_projectSelectorActionMenu;
194 QAction *m_runSubProject;
196 Internal::ProjectWindow *m_proWindow;
197 SessionManager *m_session;
198 QString m_sessionToRestoreAtStartup;
200 Project *m_currentProject;
203 BuildManager *m_buildManager;
205 QList<Internal::ProjectFileFactory*> m_fileFactories;
206 QStringList m_profileMimeTypes;
207 Internal::OutputPane *m_outputPane;
209 QList<QPair<QString, QString> > m_recentProjects; // pair of filename, displayname
210 static const int m_maxRecentProjects = 7;
212 QString m_lastOpenDirectory;
213 RunConfiguration *m_delayedRunConfiguration; // TODO this is not right
215 QString m_projectFilterString;
216 Internal::MiniProjectTargetSelector * m_targetSelector;
217 Internal::ProjectExplorerSettings m_projectExplorerSettings;
218 Internal::ProjectWelcomePage *m_welcomePage;
220 Core::IMode *m_projectsMode;
222 ToolChainManager *m_toolChainManager;
225 ProjectExplorerPluginPrivate::ProjectExplorerPluginPrivate() :
228 m_delayedRunConfiguration(0),
230 m_toolChainManager(0)
234 class ProjectsMode : public Core::IMode
237 ProjectsMode(QWidget *proWindow) : m_widget(proWindow) {}
239 QString displayName() const { return QCoreApplication::translate("ProjectExplorer::ProjectsMode", "Projects"); }
240 QIcon icon() const { return QIcon(QLatin1String(":/fancyactionbar/images/mode_Project.png")); }
241 int priority() const { return Constants::P_MODE_SESSION; }
242 QWidget *widget() { return m_widget; }
243 QString id() const { return QLatin1String(Constants::MODE_SESSION); }
244 QString type() const { return QString(); }
245 Core::Context context() const { return Core::Context(Constants::C_PROJECTEXPLORER); }
246 QString contextHelpId() const { return QLatin1String("Managing Projects"); }
253 } // namespace ProjectExplorer
255 using namespace ProjectExplorer;
256 using namespace ProjectExplorer::Internal;
259 ProjectExplorerPlugin *ProjectExplorerPlugin::m_instance = 0;
261 ProjectExplorerPlugin::ProjectExplorerPlugin()
262 : d(new ProjectExplorerPluginPrivate)
267 ProjectExplorerPlugin::~ProjectExplorerPlugin()
269 removeObject(d->m_welcomePage);
270 delete d->m_welcomePage;
271 delete d->m_toolChainManager;
276 ProjectExplorerPlugin *ProjectExplorerPlugin::instance()
281 bool ProjectExplorerPlugin::parseArguments(const QStringList &arguments, QString * /* error */)
283 CustomWizard::setVerbose(arguments.count(QLatin1String("-customwizard-verbose")));
287 bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *error)
289 if (!parseArguments(arguments, error))
293 // Add ToolChainFactories:
295 addAutoReleasedObject(new Internal::MingwToolChainFactory);
296 addAutoReleasedObject(new Internal::MsvcToolChainFactory);
298 addAutoReleasedObject(new Internal::GccToolChainFactory);
299 addAutoReleasedObject(new Internal::LinuxIccToolChainFactory);
302 d->m_toolChainManager = new ToolChainManager(this);
304 addAutoReleasedObject(new Internal::ToolChainOptionsPage);
306 addAutoReleasedObject(new TaskHub);
308 Core::ICore *core = Core::ICore::instance();
309 Core::ActionManager *am = core->actionManager();
310 connect(core, SIGNAL(newItemsDialogRequested()), this, SLOT(loadCustomWizards()));
312 d->m_welcomePage = new ProjectWelcomePage;
313 connect(d->m_welcomePage, SIGNAL(manageSessions()), this, SLOT(showSessionManager()));
314 addObject(d->m_welcomePage);
316 connect(core->fileManager(), SIGNAL(currentFileChanged(QString)),
317 this, SLOT(setCurrentFile(QString)));
319 d->m_session = new SessionManager(this);
321 connect(d->m_session, SIGNAL(projectAdded(ProjectExplorer::Project *)),
322 this, SIGNAL(fileListChanged()));
323 connect(d->m_session, SIGNAL(aboutToRemoveProject(ProjectExplorer::Project *)),
324 this, SLOT(invalidateProject(ProjectExplorer::Project *)));
325 connect(d->m_session, SIGNAL(projectRemoved(ProjectExplorer::Project *)),
326 this, SIGNAL(fileListChanged()));
327 connect(d->m_session, SIGNAL(projectAdded(ProjectExplorer::Project*)),
328 this, SLOT(projectAdded(ProjectExplorer::Project*)));
329 connect(d->m_session, SIGNAL(projectRemoved(ProjectExplorer::Project*)),
330 this, SLOT(projectRemoved(ProjectExplorer::Project*)));
331 connect(d->m_session, SIGNAL(startupProjectChanged(ProjectExplorer::Project *)),
332 this, SLOT(startupProjectChanged()));
333 connect(d->m_session, SIGNAL(dependencyChanged(ProjectExplorer::Project*,ProjectExplorer::Project*)),
334 this, SLOT(updateActions()));
335 connect(d->m_session, SIGNAL(sessionLoaded()),
336 this, SLOT(updateActions()));
337 connect(d->m_session, SIGNAL(sessionLoaded()),
338 this, SLOT(updateWelcomePage()));
340 d->m_proWindow = new ProjectWindow;
342 Core::Context globalcontext(Core::Constants::C_GLOBAL);
343 Core::Context projecTreeContext(Constants::C_PROJECT_TREE);
345 d->m_projectsMode = new ProjectsMode(d->m_proWindow);
346 d->m_projectsMode->setEnabled(session()->startupProject());
347 addAutoReleasedObject(d->m_projectsMode);
348 d->m_proWindow->layout()->addWidget(new Core::FindToolBarPlaceHolder(d->m_proWindow));
350 addAutoReleasedObject(new CopyTaskHandler);
351 addAutoReleasedObject(new ShowInEditorTaskHandler);
352 addAutoReleasedObject(new VcsAnnotateTaskHandler);
354 d->m_buildManager = new BuildManager(this);
355 connect(d->m_buildManager, SIGNAL(buildStateChanged(ProjectExplorer::Project *)),
356 this, SLOT(buildStateChanged(ProjectExplorer::Project *)));
357 connect(d->m_buildManager, SIGNAL(buildQueueFinished(bool)),
358 this, SLOT(buildQueueFinished(bool)));
360 addAutoReleasedObject(new CoreListener);
362 d->m_outputPane = new OutputPane;
363 addAutoReleasedObject(d->m_outputPane);
364 connect(d->m_session, SIGNAL(projectRemoved(ProjectExplorer::Project *)),
365 d->m_outputPane, SLOT(projectRemoved()));
367 AllProjectsFilter *allProjectsFilter = new AllProjectsFilter(this);
368 addAutoReleasedObject(allProjectsFilter);
370 CurrentProjectFilter *currentProjectFilter = new CurrentProjectFilter(this);
371 addAutoReleasedObject(currentProjectFilter);
373 addAutoReleasedObject(new BuildSettingsPanelFactory);
374 addAutoReleasedObject(new RunSettingsPanelFactory);
375 addAutoReleasedObject(new EditorSettingsPanelFactory);
376 addAutoReleasedObject(new DependenciesPanelFactory(d->m_session));
378 ProcessStepFactory *processStepFactory = new ProcessStepFactory;
379 addAutoReleasedObject(processStepFactory);
381 AllProjectsFind *allProjectsFind = new AllProjectsFind(this,
382 Find::SearchResultWindow::instance());
383 addAutoReleasedObject(allProjectsFind);
385 CurrentProjectFind *currentProjectFind = new CurrentProjectFind(this,
386 Find::SearchResultWindow::instance());
387 addAutoReleasedObject(currentProjectFind);
389 addAutoReleasedObject(new LocalApplicationRunControlFactory);
390 addAutoReleasedObject(new CustomExecutableRunConfigurationFactory);
392 addAutoReleasedObject(new ProjectFileWizardExtension);
395 addAutoReleasedObject(new ProjectExplorerSettingsPage);
398 Core::ActionContainer *msessionContextMenu =
399 am->createMenu(Constants::M_SESSIONCONTEXT);
400 Core::ActionContainer *mprojectContextMenu =
401 am->createMenu(Constants::M_PROJECTCONTEXT);
402 Core::ActionContainer *msubProjectContextMenu =
403 am->createMenu(Constants::M_SUBPROJECTCONTEXT);
404 Core::ActionContainer *mfolderContextMenu =
405 am->createMenu(Constants::M_FOLDERCONTEXT);
406 Core::ActionContainer *mfileContextMenu =
407 am->createMenu(Constants::M_FILECONTEXT);
409 d->m_sessionContextMenu = msessionContextMenu->menu();
410 d->m_projectMenu = mprojectContextMenu->menu();
411 d->m_subProjectMenu = msubProjectContextMenu->menu();
412 d->m_folderMenu = mfolderContextMenu->menu();
413 d->m_fileMenu = mfileContextMenu->menu();
415 Core::ActionContainer *mfile =
416 am->actionContainer(Core::Constants::M_FILE);
417 Core::ActionContainer *menubar =
418 am->actionContainer(Core::Constants::MENU_BAR);
420 // mode manager (for fancy actions)
421 Core::ModeManager *modeManager = core->modeManager();
424 Core::ActionContainer *mbuild =
425 am->createMenu(Constants::M_BUILDPROJECT);
426 mbuild->menu()->setTitle(tr("&Build"));
427 menubar->addMenu(mbuild, Core::Constants::G_VIEW);
430 Core::ActionContainer *mdebug =
431 am->createMenu(Constants::M_DEBUG);
432 mdebug->menu()->setTitle(tr("&Debug"));
433 menubar->addMenu(mdebug, Core::Constants::G_VIEW);
435 Core::ActionContainer *mstartdebugging =
436 am->createMenu(Constants::M_DEBUG_STARTDEBUGGING);
437 mstartdebugging->menu()->setTitle(tr("&Start Debugging"));
438 mdebug->addMenu(mstartdebugging, Core::Constants::G_DEFAULT_ONE);
444 mbuild->appendGroup(Constants::G_BUILD_SESSION);
445 mbuild->appendGroup(Constants::G_BUILD_PROJECT);
446 mbuild->appendGroup(Constants::G_BUILD_OTHER);
447 mbuild->appendGroup(Constants::G_BUILD_CANCEL);
448 mbuild->appendGroup(Constants::G_BUILD_RUN);
450 msessionContextMenu->appendGroup(Constants::G_SESSION_BUILD);
451 msessionContextMenu->appendGroup(Constants::G_SESSION_FILES);
452 msessionContextMenu->appendGroup(Constants::G_SESSION_OTHER);
453 msessionContextMenu->appendGroup(Constants::G_SESSION_CONFIG);
455 mprojectContextMenu->appendGroup(Constants::G_PROJECT_FIRST);
456 mprojectContextMenu->appendGroup(Constants::G_PROJECT_BUILD);
457 mprojectContextMenu->appendGroup(Constants::G_PROJECT_RUN);
458 mprojectContextMenu->appendGroup(Constants::G_PROJECT_FILES);
459 mprojectContextMenu->appendGroup(Constants::G_PROJECT_OTHER);
460 mprojectContextMenu->appendGroup(Constants::G_PROJECT_CONFIG);
462 msubProjectContextMenu->appendGroup(Constants::G_PROJECT_FIRST);
463 msubProjectContextMenu->appendGroup(Constants::G_PROJECT_BUILD);
464 msubProjectContextMenu->appendGroup(Constants::G_PROJECT_RUN);
465 msubProjectContextMenu->appendGroup(Constants::G_PROJECT_FILES);
466 msubProjectContextMenu->appendGroup(Constants::G_PROJECT_OTHER);
467 msubProjectContextMenu->appendGroup(Constants::G_PROJECT_CONFIG);
469 Core::ActionContainer *runMenu = Core::ICore::instance()->actionManager()->createMenu(Constants::RUNMENUCONTEXTMENU);
470 runMenu->setOnAllDisabledBehavior(Core::ActionContainer::Hide);
471 QIcon runIcon(Constants::ICON_RUN);
472 runIcon.addFile(Constants::ICON_RUN_SMALL);
473 runMenu->menu()->setIcon(runIcon);
474 runMenu->menu()->setTitle("Run");
475 msubProjectContextMenu->addMenu(runMenu, ProjectExplorer::Constants::G_PROJECT_RUN);
477 mfolderContextMenu->appendGroup(Constants::G_FOLDER_FILES);
478 mfolderContextMenu->appendGroup(Constants::G_FOLDER_OTHER);
479 mfolderContextMenu->appendGroup(Constants::G_FOLDER_CONFIG);
481 mfileContextMenu->appendGroup(Constants::G_FILE_OPEN);
482 mfileContextMenu->appendGroup(Constants::G_FILE_OTHER);
483 mfileContextMenu->appendGroup(Constants::G_FILE_CONFIG);
485 // "open with" submenu
486 Core::ActionContainer * const openWith =
487 am->createMenu(ProjectExplorer::Constants::M_OPENFILEWITHCONTEXT);
488 openWith->setOnAllDisabledBehavior(Core::ActionContainer::Show);
489 d->m_openWithMenu = openWith->menu();
490 d->m_openWithMenu->setTitle(tr("Open With"));
492 connect(d->m_openWithMenu, SIGNAL(triggered(QAction *)),
493 this, SLOT(openWithMenuTriggered(QAction *)));
502 sep = new QAction(this);
503 sep->setSeparator(true);
504 cmd = am->registerAction(sep, Core::Id("ProjectExplorer.Build.Sep"), globalcontext);
505 mbuild->addAction(cmd, Constants::G_BUILD_PROJECT);
507 sep = new QAction(this);
508 sep->setSeparator(true);
509 cmd = am->registerAction(sep, Core::Id("ProjectExplorer.Files.Sep"), projecTreeContext);
510 msessionContextMenu->addAction(cmd, Constants::G_SESSION_FILES);
511 mprojectContextMenu->addAction(cmd, Constants::G_PROJECT_FILES);
512 msubProjectContextMenu->addAction(cmd, Constants::G_PROJECT_FILES);
514 sep = new QAction(this);
515 sep->setSeparator(true);
516 cmd = am->registerAction(sep, Core::Id("ProjectExplorer.Config.Sep"), projecTreeContext);
517 msessionContextMenu->addAction(cmd, Constants::G_SESSION_CONFIG);
518 mprojectContextMenu->addAction(cmd, Constants::G_PROJECT_CONFIG);
519 msubProjectContextMenu->addAction(cmd, Constants::G_PROJECT_CONFIG);
521 sep = new QAction(this);
522 sep->setSeparator(true);
523 cmd = am->registerAction(sep, Core::Id("ProjectExplorer.Projects.Sep"), globalcontext);
524 mfile->addAction(cmd, Core::Constants::G_FILE_PROJECT);
526 sep = new QAction(this);
527 sep->setSeparator(true);
528 cmd = am->registerAction(sep, Core::Id("ProjectExplorer.Other.Sep"), globalcontext);
529 mbuild->addAction(cmd, Constants::G_BUILD_OTHER);
530 msessionContextMenu->addAction(cmd, Constants::G_SESSION_OTHER);
531 mprojectContextMenu->addAction(cmd, Constants::G_PROJECT_OTHER);
532 msubProjectContextMenu->addAction(cmd, Constants::G_PROJECT_OTHER);
534 sep = new QAction(this);
535 sep->setSeparator(true);
536 cmd = am->registerAction(sep, Core::Id("ProjectExplorer.Run.Sep"), globalcontext);
537 mbuild->addAction(cmd, Constants::G_BUILD_RUN);
538 mprojectContextMenu->addAction(cmd, Constants::G_PROJECT_RUN);
540 sep = new QAction(this);
541 sep->setSeparator(true);
542 cmd = am->registerAction(sep, Core::Id("ProjectExplorer.CancelBuild.Sep"), globalcontext);
543 mbuild->addAction(cmd, Constants::G_BUILD_CANCEL);
550 d->m_newAction = new QAction(tr("New Project..."), this);
551 cmd = am->registerAction(d->m_newAction, Constants::NEWPROJECT, globalcontext);
552 cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+N")));
553 msessionContextMenu->addAction(cmd, Constants::G_SESSION_FILES);
556 d->m_loadAction = new QAction(tr("Load Project..."), this);
557 cmd = am->registerAction(d->m_loadAction, Constants::LOAD, globalcontext);
559 cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+O")));
561 msessionContextMenu->addAction(cmd, Constants::G_SESSION_FILES);
563 // Default open action
564 d->m_openFileAction = new QAction(tr("Open File"), this);
565 cmd = am->registerAction(d->m_openFileAction, ProjectExplorer::Constants::OPENFILE,
567 mfileContextMenu->addAction(cmd, Constants::G_FILE_OPEN);
569 d->m_showInGraphicalShell = new QAction(FolderNavigationWidget::msgGraphicalShellAction(), this);
570 cmd = am->registerAction(d->m_showInGraphicalShell, ProjectExplorer::Constants::SHOWINGRAPHICALSHELL,
572 mfileContextMenu->addAction(cmd, Constants::G_FILE_OPEN);
573 mfolderContextMenu->addAction(cmd, Constants::G_FOLDER_FILES);
575 d->m_openTerminalHere = new QAction(FolderNavigationWidget::msgTerminalAction(), this);
576 cmd = am->registerAction(d->m_openTerminalHere, ProjectExplorer::Constants::OPENTERMIANLHERE,
578 mfileContextMenu->addAction(cmd, Constants::G_FILE_OPEN);
579 mfolderContextMenu->addAction(cmd, Constants::G_FOLDER_FILES);
582 mfileContextMenu->addMenu(openWith, ProjectExplorer::Constants::G_FILE_OPEN);
584 // recent projects menu
585 Core::ActionContainer *mrecent =
586 am->createMenu(Constants::M_RECENTPROJECTS);
587 mrecent->menu()->setTitle(tr("Recent P&rojects"));
588 mrecent->setOnAllDisabledBehavior(Core::ActionContainer::Show);
589 mfile->addMenu(mrecent, Core::Constants::G_FILE_OPEN);
590 connect(mfile->menu(), SIGNAL(aboutToShow()),
591 this, SLOT(updateRecentProjectMenu()));
593 // recent session menu
594 Core::ActionContainer *msession = am->createMenu(Constants::M_SESSION);
595 msession->menu()->setTitle(tr("Recent Sessions"));
596 msession->setOnAllDisabledBehavior(Core::ActionContainer::Show);
597 mfile->addMenu(msession, Core::Constants::G_FILE_OPEN);
598 d->m_sessionMenu = msession->menu();
599 connect(mfile->menu(), SIGNAL(aboutToShow()),
600 this, SLOT(updateSessionMenu()));
602 // session manager action
603 d->m_sessionManagerAction = new QAction(tr("Session Manager..."), this);
604 cmd = am->registerAction(d->m_sessionManagerAction, Constants::NEWSESSION, globalcontext);
605 mfile->addAction(cmd, Core::Constants::G_FILE_OPEN);
606 cmd->setDefaultKeySequence(QKeySequence());
611 d->m_unloadAction = new Utils::ParameterAction(tr("Close Project"), tr("Close Project \"%1\""),
612 Utils::ParameterAction::EnabledWithParameter, this);
613 cmd = am->registerAction(d->m_unloadAction, Constants::UNLOAD, globalcontext);
614 cmd->setAttribute(Core::Command::CA_UpdateText);
615 cmd->setDefaultText(d->m_unloadAction->text());
616 mfile->addAction(cmd, Core::Constants::G_FILE_PROJECT);
618 // unload session action
619 d->m_clearSession = new QAction(tr("Close All Projects"), this);
620 cmd = am->registerAction(d->m_clearSession, Constants::CLEARSESSION, globalcontext);
621 mfile->addAction(cmd, Core::Constants::G_FILE_PROJECT);
622 msessionContextMenu->addAction(cmd, Constants::G_SESSION_FILES);
624 // build session action
625 QIcon buildIcon(Constants::ICON_BUILD);
626 buildIcon.addFile(Constants::ICON_BUILD_SMALL);
627 d->m_buildSessionAction = new QAction(buildIcon, tr("Build All"), this);
628 cmd = am->registerAction(d->m_buildSessionAction, Constants::BUILDSESSION, globalcontext);
629 cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+B")));
630 mbuild->addAction(cmd, Constants::G_BUILD_SESSION);
631 msessionContextMenu->addAction(cmd, Constants::G_SESSION_BUILD);
633 modeManager->addAction(cmd->action(), Constants::P_ACTION_BUILDSESSION);
635 // rebuild session action
636 QIcon rebuildIcon(Constants::ICON_REBUILD);
637 rebuildIcon.addFile(Constants::ICON_REBUILD_SMALL);
638 d->m_rebuildSessionAction = new QAction(rebuildIcon, tr("Rebuild All"), this);
639 cmd = am->registerAction(d->m_rebuildSessionAction, Constants::REBUILDSESSION, globalcontext);
640 mbuild->addAction(cmd, Constants::G_BUILD_SESSION);
641 msessionContextMenu->addAction(cmd, Constants::G_SESSION_BUILD);
644 d->m_deploySessionAction = new QAction(tr("Deploy All"), this);
645 cmd = am->registerAction(d->m_deploySessionAction, Constants::DEPLOYSESSION, globalcontext);
646 mbuild->addAction(cmd, Constants::G_BUILD_SESSION);
647 msessionContextMenu->addAction(cmd, Constants::G_SESSION_BUILD);
650 QIcon cleanIcon(Constants::ICON_CLEAN);
651 cleanIcon.addFile(Constants::ICON_CLEAN_SMALL);
652 d->m_cleanSessionAction = new QAction(cleanIcon, tr("Clean All"), this);
653 cmd = am->registerAction(d->m_cleanSessionAction, Constants::CLEANSESSION, globalcontext);
654 mbuild->addAction(cmd, Constants::G_BUILD_SESSION);
655 msessionContextMenu->addAction(cmd, Constants::G_SESSION_BUILD);
658 d->m_buildAction = new Utils::ParameterAction(tr("Build Project"), tr("Build Project \"%1\""),
659 Utils::ParameterAction::AlwaysEnabled, this);
660 cmd = am->registerAction(d->m_buildAction, Constants::BUILD, globalcontext);
661 cmd->setAttribute(Core::Command::CA_UpdateText);
662 cmd->setDefaultText(d->m_buildAction->text());
663 cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+B")));
664 mbuild->addAction(cmd, Constants::G_BUILD_PROJECT);
667 d->m_rebuildAction = new Utils::ParameterAction(tr("Rebuild Project"), tr("Rebuild Project \"%1\""),
668 Utils::ParameterAction::AlwaysEnabled, this);
669 cmd = am->registerAction(d->m_rebuildAction, Constants::REBUILD, globalcontext);
670 cmd->setAttribute(Core::Command::CA_UpdateText);
671 cmd->setDefaultText(d->m_rebuildAction->text());
672 mbuild->addAction(cmd, Constants::G_BUILD_PROJECT);
675 d->m_deployAction = new Utils::ParameterAction(tr("Deploy Project"), tr("Deploy Project \"%1\""),
676 Utils::ParameterAction::AlwaysEnabled, this);
677 cmd = am->registerAction(d->m_deployAction, Constants::DEPLOY, globalcontext);
678 cmd->setAttribute(Core::Command::CA_UpdateText);
679 cmd->setDefaultText(d->m_deployAction->text());
680 mbuild->addAction(cmd, Constants::G_BUILD_PROJECT);
683 d->m_publishAction = new Utils::ParameterAction(tr("Publish Project..."), tr("Publish Project \"%1\"..."),
684 Utils::ParameterAction::AlwaysEnabled, this);
685 cmd = am->registerAction(d->m_publishAction, Constants::PUBLISH, globalcontext);
686 cmd->setAttribute(Core::Command::CA_UpdateText);
687 cmd->setDefaultText(d->m_publishAction->text());
688 mbuild->addAction(cmd, Constants::G_BUILD_PROJECT);
691 d->m_cleanAction = new Utils::ParameterAction(tr("Clean Project"), tr("Clean Project \"%1\""),
692 Utils::ParameterAction::AlwaysEnabled, this);
693 cmd = am->registerAction(d->m_cleanAction, Constants::CLEAN, globalcontext);
694 cmd->setAttribute(Core::Command::CA_UpdateText);
695 cmd->setDefaultText(d->m_cleanAction->text());
696 mbuild->addAction(cmd, Constants::G_BUILD_PROJECT);
698 // build action (context menu)
699 d->m_buildActionContextMenu = new Utils::ParameterAction(tr("Build Project"), tr("Build Project \"%1\""),
700 Utils::ParameterAction::AlwaysEnabled, this);
701 cmd = am->registerAction(d->m_buildActionContextMenu, Constants::BUILDCM, projecTreeContext);
702 cmd->setAttribute(Core::Command::CA_UpdateText);
703 cmd->setDefaultText(d->m_buildActionContextMenu->text());
704 mprojectContextMenu->addAction(cmd, Constants::G_PROJECT_BUILD);
706 // rebuild action (context menu)
707 d->m_rebuildActionContextMenu = new Utils::ParameterAction(tr("Rebuild Project"), tr("Rebuild Project \"%1\""),
708 Utils::ParameterAction::AlwaysEnabled, this);
709 cmd = am->registerAction(d->m_rebuildActionContextMenu, Constants::REBUILDCM, projecTreeContext);
710 cmd->setAttribute(Core::Command::CA_UpdateText);
711 cmd->setDefaultText(d->m_rebuildActionContextMenu->text());
712 mprojectContextMenu->addAction(cmd, Constants::G_PROJECT_BUILD);
714 // deploy action (context menu)
715 d->m_deployActionContextMenu = new Utils::ParameterAction(tr("Deploy Project"), tr("Deploy Project \"%1\""),
716 Utils::ParameterAction::AlwaysEnabled, this);
717 cmd = am->registerAction(d->m_deployActionContextMenu, Constants::DEPLOYCM, projecTreeContext);
718 cmd->setAttribute(Core::Command::CA_UpdateText);
719 cmd->setDefaultText(d->m_deployActionContextMenu->text());
720 mprojectContextMenu->addAction(cmd, Constants::G_PROJECT_BUILD);
722 // clean action (context menu)
723 d->m_cleanActionContextMenu = new Utils::ParameterAction(tr("Clean Project"), tr("Clean Project \"%1\""),
724 Utils::ParameterAction::AlwaysEnabled, this);
725 cmd = am->registerAction(d->m_cleanActionContextMenu, Constants::CLEANCM, projecTreeContext);
726 cmd->setAttribute(Core::Command::CA_UpdateText);
727 cmd->setDefaultText(d->m_cleanActionContextMenu->text());
728 mprojectContextMenu->addAction(cmd, Constants::G_PROJECT_BUILD);
730 // build without dependencies action
731 d->m_buildProjectOnlyAction = new QAction(tr("Build Without Dependencies"), this);
732 cmd = am->registerAction(d->m_buildProjectOnlyAction, Constants::BUILDPROJECTONLY, globalcontext);
734 // rebuild without dependencies action
735 d->m_rebuildProjectOnlyAction = new QAction(tr("Rebuild Without Dependencies"), this);
736 cmd = am->registerAction(d->m_rebuildProjectOnlyAction, Constants::REBUILDPROJECTONLY, globalcontext);
738 // deploy without dependencies action
739 d->m_deployProjectOnlyAction = new QAction(tr("Deploy Without Dependencies"), this);
740 cmd = am->registerAction(d->m_deployProjectOnlyAction, Constants::DEPLOYPROJECTONLY, globalcontext);
742 // clean without dependencies action
743 d->m_cleanProjectOnlyAction = new QAction(tr("Clean Without Dependencies"), this);
744 cmd = am->registerAction(d->m_cleanProjectOnlyAction, Constants::CLEANPROJECTONLY, globalcontext);
747 d->m_runAction = new QAction(runIcon, tr("Run"), this);
748 cmd = am->registerAction(d->m_runAction, Constants::RUN, globalcontext);
749 cmd->setAttribute(Core::Command::CA_UpdateText);
751 cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+R")));
752 mbuild->addAction(cmd, Constants::G_BUILD_RUN);
754 modeManager->addAction(cmd->action(), Constants::P_ACTION_RUN);
756 d->m_runActionContextMenu = new QAction(runIcon, tr("Run"), this);
757 cmd = am->registerAction(d->m_runActionContextMenu, Constants::RUNCONTEXTMENU, projecTreeContext);
758 mprojectContextMenu->addAction(cmd, Constants::G_PROJECT_RUN);
759 msubProjectContextMenu->addAction(cmd, Constants::G_PROJECT_RUN);
761 // cancel build action
762 d->m_cancelBuildAction = new QAction(tr("Cancel Build"), this);
763 cmd = am->registerAction(d->m_cancelBuildAction, Constants::CANCELBUILD, globalcontext);
764 mbuild->addAction(cmd, Constants::G_BUILD_CANCEL);
766 // add new file action
767 d->m_addNewFileAction = new QAction(tr("Add New..."), this);
768 cmd = am->registerAction(d->m_addNewFileAction, ProjectExplorer::Constants::ADDNEWFILE,
770 mprojectContextMenu->addAction(cmd, Constants::G_PROJECT_FILES);
771 msubProjectContextMenu->addAction(cmd, Constants::G_PROJECT_FILES);
772 mfolderContextMenu->addAction(cmd, Constants::G_FOLDER_FILES);
774 // add existing file action
775 d->m_addExistingFilesAction = new QAction(tr("Add Existing Files..."), this);
776 cmd = am->registerAction(d->m_addExistingFilesAction, ProjectExplorer::Constants::ADDEXISTINGFILES,
778 mprojectContextMenu->addAction(cmd, Constants::G_PROJECT_FILES);
779 msubProjectContextMenu->addAction(cmd, Constants::G_PROJECT_FILES);
780 mfolderContextMenu->addAction(cmd, Constants::G_FOLDER_FILES);
782 // new subproject action
783 d->m_addNewSubprojectAction = new QAction(tr("New Subproject..."), this);
784 cmd = am->registerAction(d->m_addNewSubprojectAction, ProjectExplorer::Constants::ADDNEWSUBPROJECT,
786 mprojectContextMenu->addAction(cmd, Constants::G_PROJECT_FILES);
787 msubProjectContextMenu->addAction(cmd, Constants::G_PROJECT_FILES);
789 // unload project again, in right position
790 mprojectContextMenu->addAction(am->command(Constants::UNLOAD), Constants::G_PROJECT_FILES);
792 // remove file action
793 d->m_removeFileAction = new QAction(tr("Remove File..."), this);
794 cmd = am->registerAction(d->m_removeFileAction, ProjectExplorer::Constants::REMOVEFILE,
796 cmd->setDefaultKeySequence(QKeySequence::Delete);
797 mfileContextMenu->addAction(cmd, Constants::G_FILE_OTHER);
799 //: Remove project from parent profile (Project explorer view); will not physically delete any files.
800 d->m_removeProjectAction = new QAction(tr("Remove Project..."), this);
801 cmd = am->registerAction(d->m_removeProjectAction, ProjectExplorer::Constants::REMOVEPROJECT,
803 msubProjectContextMenu->addAction(cmd, Constants::G_PROJECT_FILES);
805 // delete file action
806 d->m_deleteFileAction = new QAction(tr("Delete File..."), this);
807 cmd = am->registerAction(d->m_deleteFileAction, ProjectExplorer::Constants::DELETEFILE,
809 cmd->setDefaultKeySequence(QKeySequence::Delete);
810 mfileContextMenu->addAction(cmd, Constants::G_FILE_OTHER);
813 d->m_renameFileAction = new QAction(tr("Rename"), this);
814 cmd = am->registerAction(d->m_renameFileAction, ProjectExplorer::Constants::RENAMEFILE,
816 mfileContextMenu->addAction(cmd, Constants::G_FILE_OTHER);
817 // Not yet used by anyone, so hide for now
818 // mfolder->addAction(cmd, Constants::G_FOLDER_FILES);
819 // msubProject->addAction(cmd, Constants::G_FOLDER_FILES);
820 // mproject->addAction(cmd, Constants::G_FOLDER_FILES);
822 // set startup project action
823 d->m_setStartupProjectAction = new QAction(tr("Set as Startup Project"), this);
824 cmd = am->registerAction(d->m_setStartupProjectAction, ProjectExplorer::Constants::SETSTARTUP,
826 mprojectContextMenu->addAction(cmd, Constants::G_PROJECT_FIRST);
829 d->m_projectSelectorAction = new QAction(this);
830 d->m_projectSelectorAction->setCheckable(true);
831 d->m_projectSelectorAction->setEnabled(false);
832 QWidget *mainWindow = Core::ICore::instance()->mainWindow();
833 d->m_targetSelector = new Internal::MiniProjectTargetSelector(d->m_projectSelectorAction, mainWindow);
834 connect(d->m_projectSelectorAction, SIGNAL(triggered()), d->m_targetSelector, SLOT(show()));
835 modeManager->addProjectSelector(d->m_projectSelectorAction);
837 d->m_projectSelectorActionMenu = new QAction(this);
838 d->m_projectSelectorActionMenu->setEnabled(false);
839 d->m_projectSelectorActionMenu->setText(tr("Open Build/Run Target Selector..."));
840 connect(d->m_projectSelectorActionMenu, SIGNAL(triggered()), d->m_targetSelector, SLOT(show()));
841 cmd = am->registerAction(d->m_projectSelectorActionMenu, ProjectExplorer::Constants::SELECTTARGET,
843 cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+T")));
844 mbuild->addAction(cmd, Constants::G_BUILD_RUN);
846 connect(d->m_session, SIGNAL(projectAdded(ProjectExplorer::Project*)),
847 d->m_targetSelector, SLOT(addProject(ProjectExplorer::Project*)));
848 connect(d->m_session, SIGNAL(projectRemoved(ProjectExplorer::Project*)),
849 d->m_targetSelector, SLOT(removeProject(ProjectExplorer::Project*)));
850 connect(d->m_targetSelector, SIGNAL(startupProjectChanged(ProjectExplorer::Project*)),
851 this, SLOT(setStartupProject(ProjectExplorer::Project*)));
852 connect(d->m_session, SIGNAL(startupProjectChanged(ProjectExplorer::Project*)),
853 d->m_targetSelector, SLOT(changeStartupProject(ProjectExplorer::Project*)));
855 connect(core, SIGNAL(saveSettingsRequested()),
856 this, SLOT(savePersistentSettings()));
858 addAutoReleasedObject(new ProjectTreeWidgetFactory);
859 addAutoReleasedObject(new FolderNavigationWidgetFactory);
861 if (QSettings *s = core->settings()) {
862 const QStringList fileNames = s->value("ProjectExplorer/RecentProjects/FileNames").toStringList();
863 const QStringList displayNames = s->value("ProjectExplorer/RecentProjects/DisplayNames").toStringList();
864 if (fileNames.size() == displayNames.size()) {
865 for (int i = 0; i < fileNames.size(); ++i) {
866 if (QFileInfo(fileNames.at(i)).isFile())
867 d->m_recentProjects.append(qMakePair(fileNames.at(i), displayNames.at(i)));
872 if (QSettings *s = core->settings()) {
873 d->m_projectExplorerSettings.buildBeforeDeploy = s->value("ProjectExplorer/Settings/BuildBeforeDeploy", true).toBool();
874 d->m_projectExplorerSettings.deployBeforeRun = s->value("ProjectExplorer/Settings/DeployBeforeRun", true).toBool();
875 d->m_projectExplorerSettings.saveBeforeBuild = s->value("ProjectExplorer/Settings/SaveBeforeBuild", false).toBool();
876 d->m_projectExplorerSettings.showCompilerOutput = s->value("ProjectExplorer/Settings/ShowCompilerOutput", false).toBool();
877 d->m_projectExplorerSettings.showRunOutput = s->value("ProjectExplorer/Settings/ShowRunOutput", true).toBool();
878 d->m_projectExplorerSettings.cleanOldAppOutput = s->value("ProjectExplorer/Settings/CleanOldAppOutput", false).toBool();
879 d->m_projectExplorerSettings.wrapAppOutput = s->value("ProjectExplorer/Settings/WrapAppOutput", true).toBool();
880 d->m_projectExplorerSettings.useJom = s->value("ProjectExplorer/Settings/UseJom", true).toBool();
881 d->m_projectExplorerSettings.autorestoreLastSession = s->value("ProjectExplorer/Settings/AutoRestoreLastSession", false).toBool();
882 d->m_projectExplorerSettings.prompToStopRunControl = s->value("ProjectExplorer/Settings/PromptToStopRunControl", false).toBool();
883 d->m_projectExplorerSettings.environmentId = QUuid(s->value("ProjectExplorer/Settings/EnvironmentId").toString());
884 if (d->m_projectExplorerSettings.environmentId.isNull())
885 d->m_projectExplorerSettings.environmentId = QUuid::createUuid();
888 connect(d->m_sessionManagerAction, SIGNAL(triggered()), this, SLOT(showSessionManager()));
889 connect(d->m_newAction, SIGNAL(triggered()), this, SLOT(newProject()));
890 connect(d->m_loadAction, SIGNAL(triggered()), this, SLOT(loadAction()));
891 connect(d->m_buildProjectOnlyAction, SIGNAL(triggered()), this, SLOT(buildProjectOnly()));
892 connect(d->m_buildAction, SIGNAL(triggered()), this, SLOT(buildProject()));
893 connect(d->m_buildActionContextMenu, SIGNAL(triggered()), this, SLOT(buildProjectContextMenu()));
894 connect(d->m_buildSessionAction, SIGNAL(triggered()), this, SLOT(buildSession()));
895 connect(d->m_rebuildProjectOnlyAction, SIGNAL(triggered()), this, SLOT(rebuildProjectOnly()));
896 connect(d->m_rebuildAction, SIGNAL(triggered()), this, SLOT(rebuildProject()));
897 connect(d->m_rebuildActionContextMenu, SIGNAL(triggered()), this, SLOT(rebuildProjectContextMenu()));
898 connect(d->m_rebuildSessionAction, SIGNAL(triggered()), this, SLOT(rebuildSession()));
899 connect(d->m_deployProjectOnlyAction, SIGNAL(triggered()), this, SLOT(deployProjectOnly()));
900 connect(d->m_deployAction, SIGNAL(triggered()), this, SLOT(deployProject()));
901 connect(d->m_deployActionContextMenu, SIGNAL(triggered()), this, SLOT(deployProjectContextMenu()));
902 connect(d->m_deploySessionAction, SIGNAL(triggered()), this, SLOT(deploySession()));
903 connect(d->m_publishAction, SIGNAL(triggered()), this, SLOT(publishProject()));
904 connect(d->m_cleanProjectOnlyAction, SIGNAL(triggered()), this, SLOT(cleanProjectOnly()));
905 connect(d->m_cleanAction, SIGNAL(triggered()), this, SLOT(cleanProject()));
906 connect(d->m_cleanActionContextMenu, SIGNAL(triggered()), this, SLOT(cleanProjectContextMenu()));
907 connect(d->m_cleanSessionAction, SIGNAL(triggered()), this, SLOT(cleanSession()));
908 connect(d->m_runAction, SIGNAL(triggered()), this, SLOT(runProject()));
909 connect(d->m_runActionContextMenu, SIGNAL(triggered()), this, SLOT(runProjectContextMenu()));
910 connect(d->m_cancelBuildAction, SIGNAL(triggered()), this, SLOT(cancelBuild()));
911 connect(d->m_unloadAction, SIGNAL(triggered()), this, SLOT(unloadProject()));
912 connect(d->m_clearSession, SIGNAL(triggered()), this, SLOT(clearSession()));
913 connect(d->m_addNewFileAction, SIGNAL(triggered()), this, SLOT(addNewFile()));
914 connect(d->m_addExistingFilesAction, SIGNAL(triggered()), this, SLOT(addExistingFiles()));
915 connect(d->m_addNewSubprojectAction, SIGNAL(triggered()), this, SLOT(addNewSubproject()));
916 connect(d->m_removeProjectAction, SIGNAL(triggered()), this, SLOT(removeProject()));
917 connect(d->m_openFileAction, SIGNAL(triggered()), this, SLOT(openFile()));
918 connect(d->m_showInGraphicalShell, SIGNAL(triggered()), this, SLOT(showInGraphicalShell()));
919 connect(d->m_openTerminalHere, SIGNAL(triggered()), this, SLOT(openTerminalHere()));
920 connect(d->m_removeFileAction, SIGNAL(triggered()), this, SLOT(removeFile()));
921 connect(d->m_deleteFileAction, SIGNAL(triggered()), this, SLOT(deleteFile()));
922 connect(d->m_renameFileAction, SIGNAL(triggered()), this, SLOT(renameFile()));
923 connect(d->m_setStartupProjectAction, SIGNAL(triggered()), this, SLOT(setStartupProject()));
925 connect(this, SIGNAL(updateRunActions()), this, SLOT(slotUpdateRunActions()));
929 connect(Core::ICore::instance(), SIGNAL(coreAboutToOpen()),
930 this, SLOT(determineSessionToRestoreAtStartup()));
931 connect(Core::ICore::instance(), SIGNAL(coreOpened()), this, SLOT(restoreSession()));
935 Core::VariableManager *vm = Core::VariableManager::instance();
936 vm->registerVariable(QLatin1String(kCurrentProjectFilePath),
937 tr("Full path of the current project's main file, including file name."));
938 vm->registerVariable(QLatin1String(kCurrentProjectPath),
939 tr("Full path of the current project's main file, excluding file name."));
940 connect(vm, SIGNAL(variableUpdateRequested(QString)),
941 this, SLOT(updateVariable(QString)));
946 void ProjectExplorerPlugin::loadAction()
949 qDebug() << "ProjectExplorerPlugin::loadAction";
952 QString dir = d->m_lastOpenDirectory;
954 // for your special convenience, we preselect a pro file if it is
956 if (Core::IEditor *editor = Core::EditorManager::instance()->currentEditor()) {
957 if (const Core::IFile *file = editor->file()) {
958 const QString fn = file->fileName();
959 const bool isProject = d->m_profileMimeTypes.contains(file->mimeType());
960 dir = isProject ? fn : QFileInfo(fn).absolutePath();
964 QString filename = QFileDialog::getOpenFileName(0, tr("Load Project"),
966 d->m_projectFilterString);
967 if (filename.isEmpty())
969 openProject(filename);
973 void ProjectExplorerPlugin::unloadProject()
976 qDebug() << "ProjectExplorerPlugin::unloadProject";
978 Core::IFile *fi = d->m_currentProject->file();
980 if (!fi || fi->fileName().isEmpty()) //nothing to save?
983 QList<Core::IFile*> filesToSave;
986 // check the number of modified files
987 int readonlycount = 0;
988 foreach (const Core::IFile *file, filesToSave) {
989 if (file->isReadOnly())
993 bool success = false;
994 if (readonlycount > 0)
995 success = Core::ICore::instance()->fileManager()->saveModifiedFiles(filesToSave).isEmpty();
997 success = Core::ICore::instance()->fileManager()->saveModifiedFilesSilently(filesToSave).isEmpty();
1002 addToRecentProjects(fi->fileName(), d->m_currentProject->displayName());
1003 d->m_session->removeProject(d->m_currentProject);
1007 void ProjectExplorerPlugin::clearSession()
1010 qDebug() << "ProjectExplorerPlugin::clearSession";
1012 if (!d->m_session->clear())
1013 return; // Action has been cancelled
1017 void ProjectExplorerPlugin::extensionsInitialized()
1019 d->m_toolChainManager->restoreToolChains();
1021 d->m_proWindow->extensionsInitialized();
1022 d->m_fileFactories = ProjectFileFactory::createFactories(&d->m_projectFilterString);
1023 foreach (ProjectFileFactory *pf, d->m_fileFactories) {
1024 d->m_profileMimeTypes += pf->mimeTypes();
1025 addAutoReleasedObject(pf);
1027 d->m_buildManager->extensionsInitialized();
1030 void ProjectExplorerPlugin::loadCustomWizards()
1032 // Add custom wizards, for which other plugins might have registered
1034 static bool firstTime = true;
1037 foreach(Core::IWizard *cpw, ProjectExplorer::CustomWizard::createWizards())
1038 addAutoReleasedObject(cpw);
1042 void ProjectExplorerPlugin::updateVariable(const QString &variable)
1044 if (variable == QLatin1String(kCurrentProjectFilePath)) {
1045 if (currentProject() && currentProject()->file()) {
1046 Core::VariableManager::instance()->insert(variable,
1047 currentProject()->file()->fileName());
1049 Core::VariableManager::instance()->remove(variable);
1051 } else if (variable == QLatin1String(kCurrentProjectPath)) {
1052 if (currentProject() && currentProject()->file()) {
1053 Core::VariableManager::instance()->insert(variable,
1054 QFileInfo(currentProject()->file()->fileName()).filePath());
1056 Core::VariableManager::instance()->remove(variable);
1061 ExtensionSystem::IPlugin::ShutdownFlag ProjectExplorerPlugin::aboutToShutdown()
1063 d->m_proWindow->aboutToShutdown(); // disconnect from session
1064 d->m_session->clear();
1065 d->m_projectsMode = 0;
1066 // Attempt to synchronously shutdown all run controls.
1067 // If that fails, fall back to asynchronous shutdown (Debugger run controls
1068 // might shutdown asynchronously).
1069 if (d->m_outputPane->closeTabs(OutputPane::CloseTabNoPrompt /* No prompt any more */))
1070 return SynchronousShutdown;
1071 connect(d->m_outputPane, SIGNAL(allRunControlsFinished()),
1072 this, SIGNAL(asynchronousShutdownFinished()));
1073 return AsynchronousShutdown;
1076 void ProjectExplorerPlugin::newProject()
1079 qDebug() << "ProjectExplorerPlugin::newProject";
1081 Core::ICore::instance()->showNewItemDialog(tr("New Project", "Title of dialog"),
1082 Core::IWizard::wizardsOfKind(Core::IWizard::ProjectWizard));
1086 void ProjectExplorerPlugin::showSessionManager()
1089 qDebug() << "ProjectExplorerPlugin::showSessionManager";
1091 if (d->m_session->isDefaultVirgin()) {
1092 // do not save new virgin default sessions
1094 d->m_session->save();
1096 SessionDialog sessionDialog(d->m_session);
1097 sessionDialog.setAutoLoadSession(d->m_projectExplorerSettings.autorestoreLastSession);
1098 sessionDialog.exec();
1099 d->m_projectExplorerSettings.autorestoreLastSession = sessionDialog.autoLoadSession();
1103 Core::ModeManager *modeManager = Core::ModeManager::instance();
1104 Core::IMode *welcomeMode = modeManager->mode(Core::Constants::MODE_WELCOME);
1105 if (modeManager->currentMode() == welcomeMode)
1106 updateWelcomePage();
1109 void ProjectExplorerPlugin::setStartupProject(Project *project)
1112 qDebug() << "ProjectExplorerPlugin::setStartupProject";
1116 d->m_session->setStartupProject(project);
1120 void ProjectExplorerPlugin::publishProject()
1122 const Project * const project = d->m_session->startupProject();
1123 QTC_ASSERT(project, return);
1124 PublishingWizardSelectionDialog selectionDialog(project);
1125 if (selectionDialog.exec() == QDialog::Accepted) {
1126 QWizard * const publishingWizard
1127 = selectionDialog.createSelectedWizard();
1128 publishingWizard->exec();
1129 delete publishingWizard;
1133 void ProjectExplorerPlugin::savePersistentSettings()
1136 qDebug()<<"ProjectExplorerPlugin::savePersistentSettings()";
1138 foreach (Project *pro, d->m_session->projects())
1139 pro->saveSettings();
1141 if (d->m_session->isDefaultVirgin()) {
1142 // do not save new virgin default sessions
1144 d->m_session->save();
1147 QSettings *s = Core::ICore::instance()->settings();
1149 s->setValue("ProjectExplorer/StartupSession", d->m_session->currentSession());
1150 s->remove("ProjectExplorer/RecentProjects/Files");
1152 QStringList fileNames;
1153 QStringList displayNames;
1154 QList<QPair<QString, QString> >::const_iterator it, end;
1155 end = d->m_recentProjects.constEnd();
1156 for (it = d->m_recentProjects.constBegin(); it != end; ++it) {
1157 fileNames << (*it).first;
1158 displayNames << (*it).second;
1161 s->setValue("ProjectExplorer/RecentProjects/FileNames", fileNames);
1162 s->setValue("ProjectExplorer/RecentProjects/DisplayNames", displayNames);
1164 s->setValue("ProjectExplorer/Settings/BuildBeforeDeploy", d->m_projectExplorerSettings.buildBeforeDeploy);
1165 s->setValue("ProjectExplorer/Settings/DeployBeforeRun", d->m_projectExplorerSettings.deployBeforeRun);
1166 s->setValue("ProjectExplorer/Settings/SaveBeforeBuild", d->m_projectExplorerSettings.saveBeforeBuild);
1167 s->setValue("ProjectExplorer/Settings/ShowCompilerOutput", d->m_projectExplorerSettings.showCompilerOutput);
1168 s->setValue("ProjectExplorer/Settings/ShowRunOutput", d->m_projectExplorerSettings.showRunOutput);
1169 s->setValue("ProjectExplorer/Settings/CleanOldAppOutput", d->m_projectExplorerSettings.cleanOldAppOutput);
1170 s->setValue("ProjectExplorer/Settings/WrapAppOutput", d->m_projectExplorerSettings.wrapAppOutput);
1171 s->setValue("ProjectExplorer/Settings/UseJom", d->m_projectExplorerSettings.useJom);
1172 s->setValue("ProjectExplorer/Settings/AutoRestoreLastSession", d->m_projectExplorerSettings.autorestoreLastSession);
1173 s->setValue("ProjectExplorer/Settings/PromptToStopRunControl", d->m_projectExplorerSettings.prompToStopRunControl);
1174 s->setValue("ProjectExplorer/Settings/EnvironmentId", d->m_projectExplorerSettings.environmentId.toString());
1178 bool ProjectExplorerPlugin::openProject(const QString &fileName)
1181 qDebug() << "ProjectExplorerPlugin::openProject";
1183 QList<Project *> list = openProjects(QStringList() << fileName);
1184 if (!list.isEmpty()) {
1185 addToRecentProjects(fileName, list.first()->displayName());
1191 static inline QList<IProjectManager*> allProjectManagers()
1193 ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
1194 return pm->getObjects<IProjectManager>();
1197 QList<Project *> ProjectExplorerPlugin::openProjects(const QStringList &fileNames)
1200 qDebug() << "ProjectExplorerPlugin - opening projects " << fileNames;
1202 const QList<IProjectManager*> projectManagers = allProjectManagers();
1204 QList<Project*> openedPro;
1205 foreach (const QString &fileName, fileNames) {
1206 if (const Core::MimeType mt = Core::ICore::instance()->mimeDatabase()->findByFile(QFileInfo(fileName))) {
1207 foreach (IProjectManager *manager, projectManagers) {
1208 if (manager->mimeType() == mt.type()) {
1209 if (Project *pro = manager->openProject(fileName)) {
1210 if (pro->restoreSettings()) {
1211 connect(pro, SIGNAL(fileListChanged()), this, SIGNAL(fileListChanged()));
1212 d->m_session->addProject(pro);
1213 // Make sure we always have a current project / node
1214 if (!d->m_currentProject && !openedPro.isEmpty())
1215 setCurrentNode(pro->rootProjectNode());
1221 d->m_session->reportProjectLoadingProgress();
1229 if (!openedPro.isEmpty())
1230 Core::ModeManager::instance()->activateMode(Core::Constants::MODE_EDIT);
1235 Project *ProjectExplorerPlugin::currentProject() const
1238 if (d->m_currentProject)
1239 qDebug() << "ProjectExplorerPlugin::currentProject returns " << d->m_currentProject->displayName();
1241 qDebug() << "ProjectExplorerPlugin::currentProject returns 0";
1243 return d->m_currentProject;
1246 Node *ProjectExplorerPlugin::currentNode() const
1248 return d->m_currentNode;
1251 void ProjectExplorerPlugin::setCurrentFile(Project *project, const QString &filePath)
1253 setCurrent(project, filePath, 0);
1256 void ProjectExplorerPlugin::setCurrentFile(const QString &filePath)
1258 Project *project = d->m_session->projectForFile(filePath);
1259 // If the file is not in any project, stay with the current project
1260 // e.g. on opening a git diff buffer, git log buffer, we don't change the project
1261 // I'm not 100% sure this is correct
1263 project = d->m_currentProject;
1264 setCurrent(project, filePath, 0);
1267 void ProjectExplorerPlugin::setCurrentNode(Node *node)
1269 setCurrent(d->m_session->projectForNode(node), QString(), node);
1272 SessionManager *ProjectExplorerPlugin::session() const
1274 return d->m_session;
1277 Project *ProjectExplorerPlugin::startupProject() const
1280 qDebug() << "ProjectExplorerPlugin::startupProject";
1282 return d->m_session->startupProject();
1285 void ProjectExplorerPlugin::updateWelcomePage()
1287 ProjectWelcomePageWidget::WelcomePageData welcomePageData;
1288 welcomePageData.sessionList = d->m_session->sessions();
1289 welcomePageData.activeSession = d->m_session->activeSession();
1290 welcomePageData.previousSession = d->m_session->lastSession();
1291 welcomePageData.projectList = d->m_recentProjects;
1292 d->m_welcomePage->setWelcomePageData(welcomePageData);
1295 void ProjectExplorerPlugin::currentModeChanged(Core::IMode *mode, Core::IMode *oldMode)
1297 if (mode && mode->id() == Core::Id(Core::Constants::MODE_WELCOME))
1298 updateWelcomePage();
1299 if (oldMode == d->m_projectsMode)
1300 savePersistentSettings();
1303 void ProjectExplorerPlugin::determineSessionToRestoreAtStartup()
1305 QStringList arguments = ExtensionSystem::PluginManager::instance()->arguments();
1306 // Process command line arguments first:
1307 if (arguments.contains("-lastsession"))
1308 d->m_sessionToRestoreAtStartup = d->m_session->lastSession();
1309 if (d->m_sessionToRestoreAtStartup.isNull()) {
1310 QStringList sessions = d->m_session->sessions();
1311 // We have command line arguments, try to find a session in them
1312 // Default to no session loading
1313 foreach (const QString &arg, arguments) {
1314 if (sessions.contains(arg)) {
1316 d->m_sessionToRestoreAtStartup = arg;
1321 // Handle settings only after command line arguments:
1322 if (d->m_sessionToRestoreAtStartup.isNull()
1323 && d->m_projectExplorerSettings.autorestoreLastSession)
1324 d->m_sessionToRestoreAtStartup = d->m_session->lastSession();
1326 if (!d->m_sessionToRestoreAtStartup.isNull())
1327 Core::ICore::instance()->modeManager()->activateMode(Core::Constants::MODE_EDIT);
1331 \fn void ProjectExplorerPlugin::restoreSession()
1333 This method is connected to the ICore::coreOpened signal. If
1334 there was no session explicitly loaded, it creates an empty new
1335 default session and puts the list of recent projects and sessions
1336 onto the welcome page.
1338 void ProjectExplorerPlugin::restoreSession()
1341 qDebug() << "ProjectExplorerPlugin::restoreSession";
1343 // We have command line arguments, try to find a session in them
1344 QStringList arguments = ExtensionSystem::PluginManager::instance()->arguments();
1345 arguments.removeOne(d->m_sessionToRestoreAtStartup);
1347 // Restore latest session or what was passed on the command line
1348 if (d->m_sessionToRestoreAtStartup.isEmpty()) {
1349 d->m_session->createAndLoadNewDefaultSession();
1351 d->m_session->loadSession(d->m_sessionToRestoreAtStartup);
1354 // update welcome page
1355 Core::ModeManager *modeManager = Core::ModeManager::instance();
1356 connect(modeManager, SIGNAL(currentModeChanged(Core::IMode*, Core::IMode*)),
1357 this, SLOT(currentModeChanged(Core::IMode*, Core::IMode*)));
1358 connect(d->m_welcomePage, SIGNAL(requestSession(QString)), this, SLOT(loadSession(QString)));
1359 connect(d->m_welcomePage, SIGNAL(requestProject(QString)), this, SLOT(openProject(QString)));
1361 QStringList combinedList;
1362 // Converts "filename" "+45" or "filename" ":23"
1363 // into "filename+45" and "filename:23"
1364 foreach (const QString &str, arguments) {
1365 if (!combinedList.isEmpty() && (str.startsWith(QLatin1Char('+'))
1366 || str.startsWith(QLatin1Char(':')))) {
1367 combinedList.last().append(str);
1369 combinedList << str;
1373 Core::ICore::instance()->openFiles(combinedList, Core::ICore::OpenFilesFlags(Core::ICore::CanContainLineNumbers | Core::ICore::SwitchMode));
1378 void ProjectExplorerPlugin::loadSession(const QString &session)
1381 qDebug() << "ProjectExplorerPlugin::loadSession" << session;
1382 d->m_session->loadSession(session);
1386 void ProjectExplorerPlugin::showContextMenu(const QPoint &globalPos, Node *node)
1388 QMenu *contextMenu = 0;
1391 node = d->m_session->sessionNode();
1393 if (node->nodeType() != SessionNodeType) {
1394 Project *project = d->m_session->projectForNode(node);
1395 setCurrentNode(node);
1397 emit aboutToShowContextMenu(project, node);
1398 switch (node->nodeType()) {
1399 case ProjectNodeType:
1400 if (node->parentFolderNode() == d->m_session->sessionNode())
1401 contextMenu = d->m_projectMenu;
1403 contextMenu = d->m_subProjectMenu;
1405 case FolderNodeType:
1406 contextMenu = d->m_folderMenu;
1409 populateOpenWithMenu();
1410 contextMenu = d->m_fileMenu;
1413 qWarning("ProjectExplorerPlugin::showContextMenu - Missing handler for node type");
1415 } else { // session item
1416 emit aboutToShowContextMenu(0, node);
1418 contextMenu = d->m_sessionContextMenu;
1421 updateContextMenuActions();
1422 if (contextMenu && contextMenu->actions().count() > 0) {
1423 contextMenu->popup(globalPos);
1427 BuildManager *ProjectExplorerPlugin::buildManager() const
1429 return d->m_buildManager;
1432 void ProjectExplorerPlugin::buildStateChanged(Project * pro)
1435 qDebug() << "buildStateChanged";
1436 qDebug() << pro->file()->fileName() << "isBuilding()" << d->m_buildManager->isBuilding(pro);
1442 void ProjectExplorerPlugin::executeRunConfiguration(RunConfiguration *runConfiguration, const QString &runMode)
1444 if (IRunControlFactory *runControlFactory = findRunControlFactory(runConfiguration, runMode)) {
1445 emit aboutToExecuteProject(runConfiguration->target()->project(), runMode);
1447 RunControl *control = runControlFactory->create(runConfiguration, runMode);
1450 startRunControl(control, runMode);
1454 void ProjectExplorerPlugin::startRunControl(RunControl *runControl, const QString &runMode)
1456 d->m_outputPane->createNewOutputWindow(runControl);
1457 if (runMode == ProjectExplorer::Constants::RUNMODE && d->m_projectExplorerSettings.showRunOutput)
1458 d->m_outputPane->popup(false);
1459 d->m_outputPane->showTabFor(runControl);
1460 connect(runControl, SIGNAL(finished()), this, SLOT(runControlFinished()));
1461 runControl->start();
1462 emit updateRunActions();
1465 void ProjectExplorerPlugin::buildQueueFinished(bool success)
1468 qDebug() << "buildQueueFinished()" << success;
1472 if (success && d->m_delayedRunConfiguration) {
1473 executeRunConfiguration(d->m_delayedRunConfiguration, d->m_runMode);
1475 if (d->m_buildManager->tasksAvailable())
1476 d->m_buildManager->showTaskWindow();
1478 d->m_delayedRunConfiguration = 0;
1479 d->m_runMode.clear();
1482 void ProjectExplorerPlugin::setCurrent(Project *project, QString filePath, Node *node)
1485 qDebug() << "ProjectExplorer - setting path to " << (node ? node->path() : filePath)
1486 << " and project to " << (project ? project->displayName() : "0");
1489 filePath = node->path();
1491 node = d->m_session->nodeForFile(filePath, project);
1493 Core::ICore *core = Core::ICore::instance();
1495 bool projectChanged = false;
1496 if (d->m_currentProject != project) {
1497 Core::Context oldContext;
1498 Core::Context newContext;
1500 if (d->m_currentProject) {
1501 oldContext.add(d->m_currentProject->projectManager()->projectContext());
1502 oldContext.add(d->m_currentProject->projectManager()->projectLanguage());
1505 newContext.add(project->projectManager()->projectContext());
1506 newContext.add(project->projectManager()->projectLanguage());
1509 core->updateAdditionalContexts(oldContext, newContext);
1511 d->m_currentProject = project;
1513 projectChanged = true;
1516 if (projectChanged || d->m_currentNode != node) {
1517 d->m_currentNode = node;
1519 qDebug() << "ProjectExplorer - currentNodeChanged(" << (node ? node->path() : "0") << ", " << (project ? project->displayName() : "0") << ")";
1520 emit currentNodeChanged(d->m_currentNode, project);
1521 updateContextMenuActions();
1523 if (projectChanged) {
1525 qDebug() << "ProjectExplorer - currentProjectChanged(" << (project ? project->displayName() : "0") << ")";
1526 emit currentProjectChanged(project);
1530 core->fileManager()->setCurrentFile(filePath);
1533 void ProjectExplorerPlugin::updateActions()
1536 qDebug() << "ProjectExplorerPlugin::updateActions";
1538 Project *project = startupProject();
1539 bool enableBuildActions = project
1540 && ! (d->m_buildManager->isBuilding(project))
1541 && hasBuildSettings(project)
1542 && buildSettingsEnabled(project);
1544 bool enableBuildActionsContextMenu = d->m_currentProject
1545 && ! (d->m_buildManager->isBuilding(d->m_currentProject))
1546 && hasBuildSettings(d->m_currentProject)
1547 && buildSettingsEnabled(d->m_currentProject);
1549 bool hasProjects = !d->m_session->projects().isEmpty();
1550 bool enabledSessionBuildActions = !d->m_buildManager->isBuilding()
1551 && hasBuildSettings(0)
1552 && buildSettingsEnabled(0);
1553 QString projectName = project ? project->displayName() : QString();
1554 QString projectNameContextMenu = d->m_currentProject ? d->m_currentProject->displayName() : QString();
1556 d->m_unloadAction->setParameter(projectNameContextMenu);
1558 d->m_buildAction->setParameter(projectName);
1559 d->m_rebuildAction->setParameter(projectName);
1560 d->m_cleanAction->setParameter(projectName);
1562 d->m_buildAction->setEnabled(enableBuildActions);
1563 d->m_rebuildAction->setEnabled(enableBuildActions);
1564 d->m_cleanAction->setEnabled(enableBuildActions);
1566 d->m_buildActionContextMenu->setParameter(projectNameContextMenu);
1567 d->m_rebuildActionContextMenu->setParameter(projectNameContextMenu);
1568 d->m_cleanActionContextMenu->setParameter(projectNameContextMenu);
1570 d->m_buildActionContextMenu->setEnabled(enableBuildActionsContextMenu);
1571 d->m_rebuildActionContextMenu->setEnabled(enableBuildActionsContextMenu);
1572 d->m_cleanActionContextMenu->setEnabled(enableBuildActionsContextMenu);
1574 d->m_buildProjectOnlyAction->setEnabled(enableBuildActions);
1575 d->m_rebuildProjectOnlyAction->setEnabled(enableBuildActions);
1576 d->m_cleanProjectOnlyAction->setEnabled(enableBuildActions);
1578 d->m_clearSession->setEnabled(hasProjects);
1580 d->m_buildSessionAction->setEnabled(hasProjects && enabledSessionBuildActions);
1581 d->m_rebuildSessionAction->setEnabled(hasProjects && enabledSessionBuildActions);
1582 d->m_cleanSessionAction->setEnabled(hasProjects && enabledSessionBuildActions);
1583 d->m_cancelBuildAction->setEnabled(d->m_buildManager->isBuilding());
1585 d->m_publishAction->setEnabled(hasProjects);
1587 d->m_projectSelectorAction->setEnabled(!session()->projects().isEmpty());
1588 d->m_projectSelectorActionMenu->setEnabled(!session()->projects().isEmpty());
1590 updateDeployActions();
1593 // NBS TODO check projectOrder()
1594 // what we want here is all the projects pro depends on
1595 QStringList ProjectExplorerPlugin::allFilesWithDependencies(Project *pro)
1598 qDebug() << "ProjectExplorerPlugin::allFilesWithDependencies(" << pro->file()->fileName() << ")";
1600 QStringList filesToSave;
1601 foreach (Project *p, d->m_session->projectOrder(pro)) {
1602 FindAllFilesVisitor filesVisitor;
1603 p->rootProjectNode()->accept(&filesVisitor);
1604 filesToSave << filesVisitor.filePaths();
1610 bool ProjectExplorerPlugin::saveModifiedFiles()
1613 qDebug() << "ProjectExplorerPlugin::saveModifiedFiles";
1615 QList<Core::IFile *> filesToSave = Core::ICore::instance()->fileManager()->modifiedFiles();
1616 if (!filesToSave.isEmpty()) {
1617 if (d->m_projectExplorerSettings.saveBeforeBuild) {
1618 Core::ICore::instance()->fileManager()->saveModifiedFilesSilently(filesToSave);
1620 bool cancelled = false;
1621 bool alwaysSave = false;
1623 Core::FileManager *fm = Core::ICore::instance()->fileManager();
1624 fm->saveModifiedFiles(filesToSave, &cancelled, QString(),
1625 tr("Always save files before build"), &alwaysSave);
1630 d->m_projectExplorerSettings.saveBeforeBuild = true;
1636 //NBS handle case where there is no activeBuildConfiguration
1637 // because someone delete all build configurations
1639 void ProjectExplorerPlugin::deploy(QList<Project *> projects)
1642 if (d->m_projectExplorerSettings.buildBeforeDeploy)
1643 steps << Constants::BUILDSTEPS_BUILD;
1644 steps << Constants::BUILDSTEPS_DEPLOY;
1645 queue(projects, steps);
1648 int ProjectExplorerPlugin::queue(QList<Project *> projects, QStringList stepIds)
1651 QStringList projectNames;
1652 foreach (Project *p, projects)
1653 projectNames << p->displayName();
1654 qDebug() << "Building" << stepIds << "for projects" << projectNames;
1657 if (!saveModifiedFiles())
1660 QList<BuildStepList *> stepLists;
1661 foreach (Project *pro, projects) {
1662 if (!pro || !pro->activeTarget())
1664 foreach (const QString id, stepIds) {
1665 BuildStepList *bsl = 0;
1666 if (id == Core::Id(Constants::BUILDSTEPS_DEPLOY)
1667 && pro->activeTarget()->activeDeployConfiguration())
1668 bsl = pro->activeTarget()->activeDeployConfiguration()->stepList();
1669 else if (pro->activeTarget()->activeBuildConfiguration())
1670 bsl = pro->activeTarget()->activeBuildConfiguration()->stepList(id);
1672 if (!bsl || bsl->isEmpty())
1678 if (stepLists.isEmpty())
1680 if (!d->m_buildManager->buildLists(stepLists))
1682 return stepLists.count();
1685 void ProjectExplorerPlugin::buildProjectOnly()
1687 queue(QList<Project *>() << session()->startupProject(), QStringList() << Constants::BUILDSTEPS_BUILD);
1690 void ProjectExplorerPlugin::buildProject()
1692 queue(d->m_session->projectOrder(session()->startupProject()),
1693 QStringList() << Constants::BUILDSTEPS_BUILD);
1696 void ProjectExplorerPlugin::buildProjectContextMenu()
1698 queue(d->m_session->projectOrder(d->m_currentProject),
1699 QStringList() << Constants::BUILDSTEPS_BUILD);
1702 void ProjectExplorerPlugin::buildSession()
1704 queue(d->m_session->projectOrder(),
1705 QStringList() << Constants::BUILDSTEPS_BUILD);
1708 void ProjectExplorerPlugin::rebuildProjectOnly()
1710 queue(QList<Project *>() << session()->startupProject(),
1711 QStringList() << Constants::BUILDSTEPS_CLEAN << Constants::BUILDSTEPS_BUILD);
1714 void ProjectExplorerPlugin::rebuildProject()
1716 queue(d->m_session->projectOrder(session()->startupProject()),
1717 QStringList() << Constants::BUILDSTEPS_CLEAN << Constants::BUILDSTEPS_BUILD);
1720 void ProjectExplorerPlugin::rebuildProjectContextMenu()
1722 queue(d->m_session->projectOrder(d->m_currentProject),
1723 QStringList() << Constants::BUILDSTEPS_CLEAN << Constants::BUILDSTEPS_BUILD);
1726 void ProjectExplorerPlugin::rebuildSession()
1728 queue(d->m_session->projectOrder(),
1729 QStringList() << Constants::BUILDSTEPS_CLEAN << Constants::BUILDSTEPS_BUILD);
1732 void ProjectExplorerPlugin::deployProjectOnly()
1734 deploy(QList<Project *>() << session()->startupProject());
1737 void ProjectExplorerPlugin::deployProject()
1739 deploy(d->m_session->projectOrder(session()->startupProject()));
1742 void ProjectExplorerPlugin::deployProjectContextMenu()
1744 deploy(d->m_session->projectOrder(d->m_currentProject));
1747 void ProjectExplorerPlugin::deploySession()
1749 deploy(d->m_session->projectOrder());
1752 void ProjectExplorerPlugin::cleanProjectOnly()
1754 queue(QList<Project *>() << session()->startupProject(),
1755 QStringList() << Constants::BUILDSTEPS_CLEAN);
1758 void ProjectExplorerPlugin::cleanProject()
1760 queue(d->m_session->projectOrder(session()->startupProject()),
1761 QStringList() << Constants::BUILDSTEPS_CLEAN);
1764 void ProjectExplorerPlugin::cleanProjectContextMenu()
1766 queue(d->m_session->projectOrder(d->m_currentProject),
1767 QStringList() << Constants::BUILDSTEPS_CLEAN);
1770 void ProjectExplorerPlugin::cleanSession()
1772 queue(d->m_session->projectOrder(),
1773 QStringList() << Constants::BUILDSTEPS_CLEAN);
1776 void ProjectExplorerPlugin::runProject()
1778 runProject(startupProject(), ProjectExplorer::Constants::RUNMODE);
1781 void ProjectExplorerPlugin::runProjectContextMenu()
1783 ProjectNode *projectNode = qobject_cast<ProjectNode*>(d->m_currentNode);
1784 if (projectNode == d->m_currentProject->rootProjectNode() || !projectNode) {
1785 runProject(d->m_currentProject, ProjectExplorer::Constants::RUNMODE);
1787 QAction *act = qobject_cast<QAction *>(sender());
1790 RunConfiguration *rc = act->data().value<RunConfiguration *>();
1793 runRunConfiguration(rc, ProjectExplorer::Constants::RUNMODE);
1797 bool ProjectExplorerPlugin::hasBuildSettings(Project *pro)
1799 const QList<Project *> & projects = d->m_session->projectOrder(pro);
1800 foreach(Project *project, projects)
1802 && project->activeTarget()
1803 && project->activeTarget()->activeBuildConfiguration())
1808 bool ProjectExplorerPlugin::buildSettingsEnabled(Project *pro)
1810 const QList<Project *> & projects = d->m_session->projectOrder(pro);
1812 foreach(Project *project, projects)
1814 && project->activeTarget()
1815 && project->activeTarget()->activeBuildConfiguration()
1816 && !project->activeTarget()->activeBuildConfiguration()->isEnabled())
1821 bool ProjectExplorerPlugin::coreAboutToClose()
1823 if (d->m_buildManager->isBuilding()) {
1825 QPushButton *closeAnyway = box.addButton(tr("Cancel Build && Close"), QMessageBox::AcceptRole);
1826 QPushButton *cancelClose = box.addButton(tr("Do Not Close"), QMessageBox::RejectRole);
1827 box.setDefaultButton(cancelClose);
1828 box.setWindowTitle(tr("Close Qt Creator?"));
1829 box.setText(tr("A project is currently being built."));
1830 box.setInformativeText(tr("Do you want to cancel the build process and close Qt Creator anyway?"));
1832 if (box.clickedButton() != closeAnyway)
1835 if (!d->m_outputPane->aboutToClose())
1840 bool ProjectExplorerPlugin::hasDeploySettings(Project *pro)
1842 const QList<Project *> & projects = d->m_session->projectOrder(pro);
1843 foreach(Project *project, projects)
1844 if (project->activeTarget()->activeDeployConfiguration() &&
1845 !project->activeTarget()->activeDeployConfiguration()->stepList()->isEmpty())
1850 void ProjectExplorerPlugin::runProject(Project *pro, const QString &mode)
1855 runRunConfiguration(pro->activeTarget()->activeRunConfiguration(), mode);
1858 void ProjectExplorerPlugin::runRunConfiguration(ProjectExplorer::RunConfiguration *rc, const QString &mode)
1860 if (!rc->isEnabled())
1863 QStringList stepIds;
1864 if (d->m_projectExplorerSettings.deployBeforeRun) {
1865 if (d->m_projectExplorerSettings.buildBeforeDeploy)
1866 stepIds << Constants::BUILDSTEPS_BUILD;
1867 stepIds << Constants::BUILDSTEPS_DEPLOY;
1870 Project *pro = rc->target()->project();
1871 const QList<Project *> &projects = d->m_session->projectOrder(pro);
1872 int queueCount = queue(projects, stepIds);
1874 if (queueCount < 0) // something went wrong
1877 if (queueCount > 0) {
1878 // delay running till after our queued steps were processed
1879 d->m_runMode = mode;
1880 d->m_delayedRunConfiguration = rc;
1882 executeRunConfiguration(rc, mode);
1884 emit updateRunActions();
1887 void ProjectExplorerPlugin::runControlFinished()
1889 emit updateRunActions();
1892 void ProjectExplorerPlugin::projectAdded(ProjectExplorer::Project *pro)
1894 // more specific action en and disabling ?
1895 connect(pro, SIGNAL(buildConfigurationEnabledChanged()),
1896 this, SLOT(updateActions()));
1899 void ProjectExplorerPlugin::projectRemoved(ProjectExplorer::Project * pro)
1901 // more specific action en and disabling ?
1902 disconnect(pro, SIGNAL(buildConfigurationEnabledChanged()),
1903 this, SLOT(updateActions()));
1906 void ProjectExplorerPlugin::startupProjectChanged()
1908 static QPointer<Project> previousStartupProject = 0;
1909 Project *project = startupProject();
1910 if (project == previousStartupProject)
1913 if (d->m_projectsMode)
1914 d->m_projectsMode->setEnabled(project);
1916 if (previousStartupProject) {
1917 disconnect(previousStartupProject, SIGNAL(activeTargetChanged(ProjectExplorer::Target*)),
1918 this, SLOT(activeTargetChanged()));
1921 previousStartupProject = project;
1924 connect(project, SIGNAL(activeTargetChanged(ProjectExplorer::Target*)),
1925 this, SLOT(activeTargetChanged()));
1928 activeTargetChanged();
1931 void ProjectExplorerPlugin::activeTargetChanged()
1933 static QPointer<Target> previousTarget = 0;
1935 if (startupProject())
1936 target = startupProject()->activeTarget();
1937 if (target == previousTarget)
1940 if (previousTarget) {
1941 disconnect(previousTarget, SIGNAL(activeRunConfigurationChanged(ProjectExplorer::RunConfiguration*)),
1942 this, SLOT(activeRunConfigurationChanged()));
1944 previousTarget = target;
1946 connect(target, SIGNAL(activeRunConfigurationChanged(ProjectExplorer::RunConfiguration*)),
1947 this, SLOT(activeRunConfigurationChanged()));
1950 updateDeployActions();
1951 activeRunConfigurationChanged();
1954 void ProjectExplorerPlugin::activeRunConfigurationChanged()
1956 static QPointer<RunConfiguration> previousRunConfiguration = 0;
1957 RunConfiguration *rc = 0;
1958 if (startupProject() && startupProject()->activeTarget())
1959 rc = startupProject()->activeTarget()->activeRunConfiguration();
1960 if (rc == previousRunConfiguration)
1962 if (previousRunConfiguration) {
1963 disconnect(previousRunConfiguration, SIGNAL(isEnabledChanged(bool)),
1964 this, SIGNAL(updateRunActions()));
1966 previousRunConfiguration = rc;
1968 connect(rc, SIGNAL(isEnabledChanged(bool)),
1969 this, SIGNAL(updateRunActions()));
1971 emit updateRunActions();
1974 // NBS TODO implement more than one runner
1975 IRunControlFactory *ProjectExplorerPlugin::findRunControlFactory(RunConfiguration *config, const QString &mode)
1977 ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
1978 const QList<IRunControlFactory *> factories = pm->getObjects<IRunControlFactory>();
1979 foreach (IRunControlFactory *f, factories)
1980 if (f->canRun(config, mode))
1985 void ProjectExplorerPlugin::updateDeployActions()
1987 Project *project = startupProject();
1989 bool enableDeployActions = project
1990 && ! (d->m_buildManager->isBuilding(project))
1991 && hasDeploySettings(project);
1992 bool enableDeployActionsContextMenu = d->m_currentProject
1993 && ! (d->m_buildManager->isBuilding(d->m_currentProject))
1994 && hasDeploySettings(d->m_currentProject);
1996 if (d->m_projectExplorerSettings.buildBeforeDeploy) {
1997 if (hasBuildSettings(project)
1998 && !buildSettingsEnabled(project))
1999 enableDeployActions = false;
2000 if (hasBuildSettings(d->m_currentProject)
2001 && !buildSettingsEnabled(d->m_currentProject))
2002 enableDeployActionsContextMenu = false;
2005 const QString projectName = project ? project->displayName() : QString();
2006 const QString projectNameContextMenu = d->m_currentProject ? d->m_currentProject->displayName() : QString();
2007 bool hasProjects = !d->m_session->projects().isEmpty();
2008 bool building = d->m_buildManager->isBuilding();
2010 d->m_deployAction->setParameter(projectName);
2011 d->m_deployAction->setEnabled(enableDeployActions);
2013 d->m_deployActionContextMenu->setParameter(projectNameContextMenu);
2014 d->m_deployActionContextMenu->setEnabled(enableDeployActionsContextMenu);
2016 d->m_deployProjectOnlyAction->setEnabled(enableDeployActions);
2018 d->m_deploySessionAction->setEnabled(hasProjects && !building);
2020 emit updateRunActions();
2023 bool ProjectExplorerPlugin::canRun(Project *project, const QString &runMode)
2026 !project->activeTarget() ||
2027 !project->activeTarget()->activeRunConfiguration()) {
2031 if (d->m_projectExplorerSettings.buildBeforeDeploy
2032 && d->m_projectExplorerSettings.deployBeforeRun
2033 && hasBuildSettings(project)
2034 && !buildSettingsEnabled(project))
2038 RunConfiguration *activeRC = project->activeTarget()->activeRunConfiguration();
2040 bool canRun = findRunControlFactory(activeRC, runMode)
2041 && activeRC->isEnabled();
2042 const bool building = d->m_buildManager->isBuilding();
2043 return (canRun && !building);
2046 void ProjectExplorerPlugin::slotUpdateRunActions()
2048 Project *project = startupProject();
2049 d->m_runAction->setEnabled(canRun(project, ProjectExplorer::Constants::RUNMODE));
2052 void ProjectExplorerPlugin::cancelBuild()
2055 qDebug() << "ProjectExplorerPlugin::cancelBuild";
2057 if (d->m_buildManager->isBuilding())
2058 d->m_buildManager->cancel();
2061 void ProjectExplorerPlugin::addToRecentProjects(const QString &fileName, const QString &displayName)
2064 qDebug() << "ProjectExplorerPlugin::addToRecentProjects(" << fileName << ")";
2066 if (fileName.isEmpty())
2068 QString prettyFileName(QDir::toNativeSeparators(fileName));
2070 QList<QPair<QString, QString> >::iterator it;
2071 for(it = d->m_recentProjects.begin(); it != d->m_recentProjects.end();)
2072 if ((*it).first == prettyFileName)
2073 it = d->m_recentProjects.erase(it);
2077 if (d->m_recentProjects.count() > d->m_maxRecentProjects)
2078 d->m_recentProjects.removeLast();
2079 d->m_recentProjects.prepend(qMakePair(prettyFileName, displayName));
2080 QFileInfo fi(prettyFileName);
2081 d->m_lastOpenDirectory = fi.absolutePath();
2084 void ProjectExplorerPlugin::updateRecentProjectMenu()
2086 typedef QList<QPair<QString, QString> >::const_iterator StringPairListConstIterator;
2088 qDebug() << "ProjectExplorerPlugin::updateRecentProjectMenu";
2090 Core::ActionContainer *aci =
2091 Core::ICore::instance()->actionManager()->actionContainer(Constants::M_RECENTPROJECTS);
2092 QMenu *menu = aci->menu();
2095 menu->setEnabled(!d->m_recentProjects.isEmpty());
2097 //projects (ignore sessions, they used to be in this list)
2098 const StringPairListConstIterator end = d->m_recentProjects.constEnd();
2099 for (StringPairListConstIterator it = d->m_recentProjects.constBegin(); it != end; ++it) {
2100 const QPair<QString, QString> &s = *it;
2101 if (s.first.endsWith(QLatin1String(".qws")))
2103 QAction *action = menu->addAction(Utils::withTildeHomePath(s.first));
2104 action->setData(s.first);
2105 connect(action, SIGNAL(triggered()), this, SLOT(openRecentProject()));
2109 void ProjectExplorerPlugin::openRecentProject()
2112 qDebug() << "ProjectExplorerPlugin::openRecentProject()";
2114 QAction *a = qobject_cast<QAction*>(sender());
2117 QString fileName = a->data().toString();
2118 if (!fileName.isEmpty()) {
2119 openProject(fileName);
2123 void ProjectExplorerPlugin::invalidateProject(Project *project)
2126 qDebug() << "ProjectExplorerPlugin::invalidateProject" << project->displayName();
2127 if (d->m_currentProject == project) {
2129 // Workaround for a bug in QItemSelectionModel
2130 // - currentChanged etc are not emitted if the
2131 // item is removed from the underlying data model
2133 setCurrent(0, QString(), 0);
2136 disconnect(project, SIGNAL(fileListChanged()), this, SIGNAL(fileListChanged()));
2140 void ProjectExplorerPlugin::updateContextMenuActions()
2142 d->m_addExistingFilesAction->setEnabled(false);
2143 d->m_addNewFileAction->setEnabled(false);
2144 d->m_addNewSubprojectAction->setEnabled(false);
2145 d->m_removeFileAction->setEnabled(false);
2146 d->m_deleteFileAction->setEnabled(false);
2147 d->m_renameFileAction->setEnabled(false);
2149 d->m_addExistingFilesAction->setVisible(true);
2150 d->m_removeFileAction->setVisible(true);
2151 d->m_deleteFileAction->setVisible(true);
2152 d->m_runActionContextMenu->setVisible(false);
2154 Core::ActionContainer *runMenu = Core::ICore::instance()->actionManager()->actionContainer(Constants::RUNMENUCONTEXTMENU);
2155 runMenu->menu()->clear();
2157 if (d->m_currentNode && d->m_currentNode->projectNode()) {
2158 QList<ProjectNode::ProjectAction> actions =
2159 d->m_currentNode->projectNode()->supportedActions(d->m_currentNode);
2161 if (ProjectNode *pn = qobject_cast<ProjectNode *>(d->m_currentNode)) {
2162 if (pn == d->m_currentProject->rootProjectNode()) {
2163 d->m_runActionContextMenu->setVisible(true);
2165 QList<RunConfiguration *> runConfigs = pn->runConfigurationsFor(pn);
2166 if (runConfigs.count() == 1) {
2167 d->m_runActionContextMenu->setVisible(true);
2168 d->m_runActionContextMenu->setData(QVariant::fromValue(runConfigs.first()));
2169 } else if (runConfigs.count() > 1) {
2170 foreach (RunConfiguration *rc, runConfigs) {
2171 QAction *act = new QAction(runMenu->menu());
2172 act->setData(QVariant::fromValue(rc));
2173 act->setText(QString("Run %1").arg(rc->displayName()));
2174 runMenu->menu()->addAction(act);
2175 connect(act, SIGNAL(triggered()),
2176 this, SLOT(runProjectContextMenu()));
2181 if (qobject_cast<FolderNode*>(d->m_currentNode)) {
2182 // Also handles ProjectNode
2183 d->m_addNewFileAction->setEnabled(actions.contains(ProjectNode::AddNewFile));
2184 d->m_addNewSubprojectAction->setEnabled(d->m_currentNode->nodeType() == ProjectNodeType
2185 && actions.contains(ProjectNode::AddSubProject));
2186 d->m_addExistingFilesAction->setEnabled(actions.contains(ProjectNode::AddExistingFile));
2187 d->m_renameFileAction->setEnabled(actions.contains(ProjectNode::Rename));
2188 } else if (qobject_cast<FileNode*>(d->m_currentNode)) {
2189 // Enable and show remove / delete in magic ways:
2190 // If both are disabled show Remove
2191 // If both are enabled show both (can't happen atm)
2192 // If only removeFile is enabled only show it
2193 // If only deleteFile is enable only show it
2194 bool enableRemove = actions.contains(ProjectNode::RemoveFile);
2195 d->m_removeFileAction->setEnabled(enableRemove);
2196 bool enableDelete = actions.contains(ProjectNode::EraseFile);
2197 d->m_deleteFileAction->setEnabled(enableDelete);
2198 d->m_deleteFileAction->setVisible(enableDelete);
2200 d->m_removeFileAction->setVisible(!enableDelete || enableRemove);
2201 d->m_renameFileAction->setEnabled(actions.contains(ProjectNode::Rename));
2206 QString ProjectExplorerPlugin::directoryFor(Node *node)
2208 QString path = node->path();
2210 FolderNode *folder = qobject_cast<FolderNode *>(node);
2211 if (path.contains("#") && folder) {
2212 // Virtual Folder case
2213 // We figure out a commonPath from the subfolders
2215 foreach (FolderNode *f, folder->subFolderNodes())
2216 list << f->path() + QLatin1Char('/');
2218 location = path.left(path.indexOf('#'));
2220 location = Utils::commonPath(list);
2223 location = (fi.isDir() ? fi.absoluteFilePath() : fi.absolutePath());
2228 void ProjectExplorerPlugin::addNewFile()
2230 QTC_ASSERT(d->m_currentNode, return)
2231 QString location = directoryFor(d->m_currentNode);
2233 Core::ICore::instance()->showNewItemDialog(tr("New File", "Title of dialog"),
2234 Core::IWizard::wizardsOfKind(Core::IWizard::FileWizard)
2235 + Core::IWizard::wizardsOfKind(Core::IWizard::ClassWizard),
2239 void ProjectExplorerPlugin::addNewSubproject()
2241 QTC_ASSERT(d->m_currentNode, return)
2242 QString location = directoryFor(d->m_currentNode);
2244 if (d->m_currentNode->nodeType() == ProjectNodeType
2245 && d->m_currentNode->projectNode()->supportedActions(
2246 d->m_currentNode->projectNode()).contains(ProjectNode::AddSubProject)) {
2247 Core::ICore::instance()->showNewItemDialog(tr("New Subproject", "Title of dialog"),
2248 Core::IWizard::wizardsOfKind(Core::IWizard::ProjectWizard),
2253 void ProjectExplorerPlugin::addExistingFiles()
2255 QTC_ASSERT(d->m_currentNode, return)
2257 QStringList fileNames = QFileDialog::getOpenFileNames(Core::ICore::instance()->mainWindow(),
2258 tr("Add Existing Files"), directoryFor(d->m_currentNode));
2259 if (fileNames.isEmpty())
2261 addExistingFiles(fileNames);
2264 void ProjectExplorerPlugin::addExistingFiles(const QStringList &filePaths)
2266 ProjectNode *projectNode = qobject_cast<ProjectNode*>(d->m_currentNode->projectNode());
2267 addExistingFiles(projectNode, filePaths);
2270 void ProjectExplorerPlugin::addExistingFiles(ProjectNode *projectNode, const QStringList &filePaths)
2272 Core::ICore *core = Core::ICore::instance();
2273 const QString dir = directoryFor(projectNode);
2274 QStringList fileNames = filePaths;
2275 QHash<FileType, QString> fileTypeToFiles;
2276 foreach (const QString &fileName, fileNames) {
2277 FileType fileType = typeForFileName(core->mimeDatabase(), QFileInfo(fileName));
2278 fileTypeToFiles.insertMulti(fileType, fileName);
2281 QStringList notAdded;
2282 foreach (const FileType type, fileTypeToFiles.uniqueKeys()) {
2283 projectNode->addFiles(type, fileTypeToFiles.values(type), ¬Added);
2285 if (!notAdded.isEmpty()) {
2286 QString message = tr("Could not add following files to project %1:\n").arg(projectNode->displayName());
2287 QString files = notAdded.join("\n");
2288 QMessageBox::warning(core->mainWindow(), tr("Adding Files to Project Failed"),
2290 foreach (const QString &file, notAdded)
2291 fileNames.removeOne(file);
2294 if (Core::IVersionControl *vcManager = core->vcsManager()->findVersionControlForDirectory(dir))
2295 if (vcManager->supportsOperation(Core::IVersionControl::AddOperation)) {
2296 const QString files = fileNames.join(QString(QLatin1Char('\n')));
2297 QMessageBox::StandardButton button =
2298 QMessageBox::question(core->mainWindow(), tr("Add to Version Control"),
2299 tr("Add files\n%1\nto version control (%2)?").arg(files, vcManager->displayName()),
2300 QMessageBox::Yes | QMessageBox::No);
2301 if (button == QMessageBox::Yes) {
2302 QStringList notAddedToVc;
2303 foreach (const QString &file, fileNames) {
2304 if (!vcManager->vcsAdd(file))
2305 notAddedToVc << file;
2308 if (!notAddedToVc.isEmpty()) {
2309 const QString message = tr("Could not add following files to version control (%1)\n").arg(vcManager->displayName());
2310 const QString filesNotAdded = notAddedToVc.join(QString(QLatin1Char('\n')));
2311 QMessageBox::warning(core->mainWindow(), tr("Adding to Version Control Failed"),
2312 message + filesNotAdded);
2318 void ProjectExplorerPlugin::removeProject()
2320 ProjectNode *subProjectNode = qobject_cast<ProjectNode*>(d->m_currentNode->projectNode());
2321 ProjectNode *projectNode = qobject_cast<ProjectNode *>(subProjectNode->parentFolderNode());
2323 Core::ICore *core = Core::ICore::instance();
2324 RemoveFileDialog removeFileDialog(subProjectNode->path(), core->mainWindow());
2325 removeFileDialog.setDeleteFileVisible(false);
2326 if (removeFileDialog.exec() == QDialog::Accepted)
2327 projectNode->removeSubProjects(QStringList() << subProjectNode->path());
2331 void ProjectExplorerPlugin::openFile()
2333 QTC_ASSERT(d->m_currentNode, return)
2334 Core::EditorManager *em = Core::EditorManager::instance();
2335 em->openEditor(d->m_currentNode->path(), QString(), Core::EditorManager::ModeSwitch);
2338 void ProjectExplorerPlugin::showInGraphicalShell()
2340 QTC_ASSERT(d->m_currentNode, return)
2341 FolderNavigationWidget::showInGraphicalShell(Core::ICore::instance()->mainWindow(),
2342 directoryFor(d->m_currentNode));
2345 void ProjectExplorerPlugin::openTerminalHere()
2347 QTC_ASSERT(d->m_currentNode, return)
2348 FolderNavigationWidget::openTerminal(directoryFor(d->m_currentNode));
2351 void ProjectExplorerPlugin::removeFile()
2353 QTC_ASSERT(d->m_currentNode && d->m_currentNode->nodeType() == FileNodeType, return)
2355 FileNode *fileNode = qobject_cast<FileNode*>(d->m_currentNode);
2356 Core::ICore *core = Core::ICore::instance();
2358 QString filePath = d->m_currentNode->path();
2359 RemoveFileDialog removeFileDialog(filePath, core->mainWindow());
2361 if (removeFileDialog.exec() == QDialog::Accepted) {
2362 const bool deleteFile = removeFileDialog.isDeleteFileChecked();
2364 // remove from project
2365 ProjectNode *projectNode = fileNode->projectNode();
2366 Q_ASSERT(projectNode);
2368 if (!projectNode->removeFiles(fileNode->fileType(), QStringList(filePath))) {
2369 QMessageBox::warning(core->mainWindow(), tr("Removing File Failed"),
2370 tr("Could not remove file %1 from project %2.").arg(filePath).arg(projectNode->displayName()));
2374 // remove from version control
2375 core->vcsManager()->promptToDelete(filePath);
2377 // remove from file system
2379 QFile file(filePath);
2381 if (file.exists()) {
2382 // could have been deleted by vc
2384 QMessageBox::warning(core->mainWindow(), tr("Deleting File Failed"),
2385 tr("Could not delete file %1.").arg(filePath));
2391 void ProjectExplorerPlugin::deleteFile()
2393 QTC_ASSERT(d->m_currentNode && d->m_currentNode->nodeType() == FileNodeType, return)
2395 FileNode *fileNode = qobject_cast<FileNode*>(d->m_currentNode);
2396 Core::ICore *core = Core::ICore::instance();
2398 QString filePath = d->m_currentNode->path();
2399 QMessageBox::StandardButton button =
2400 QMessageBox::question(core->mainWindow(),
2402 tr("Delete %1 from file system?").arg(filePath),
2403 QMessageBox::Yes | QMessageBox::No);
2404 if (button != QMessageBox::Yes)
2407 ProjectNode *projectNode = fileNode->projectNode();
2408 Q_ASSERT(projectNode);
2410 projectNode->deleteFiles(fileNode->fileType(), QStringList(filePath));
2412 if (Core::IVersionControl *vc =
2413 core->vcsManager()->findVersionControlForDirectory(QFileInfo(filePath).absolutePath())) {
2414 vc->vcsDelete(filePath);
2416 QFile file(filePath);
2417 if (file.exists()) {
2419 QMessageBox::warning(core->mainWindow(), tr("Deleting File Failed"),
2420 tr("Could not delete file %1.").arg(filePath));
2424 void ProjectExplorerPlugin::renameFile()
2426 QWidget *focusWidget = QApplication::focusWidget();
2427 while (focusWidget) {
2428 ProjectTreeWidget *treeWidget = qobject_cast<ProjectTreeWidget*>(focusWidget);
2430 treeWidget->editCurrentItem();
2433 focusWidget = focusWidget->parentWidget();
2437 void ProjectExplorerPlugin::renameFile(Node *node, const QString &to)
2439 FileNode *fileNode = qobject_cast<FileNode *>(node);
2442 QString orgFilePath = QFileInfo(node->path()).absoluteFilePath();
2443 QString dir = QFileInfo(orgFilePath).absolutePath();
2444 QString newFilePath = dir + QLatin1Char('/') + to;
2445 Core::ICore *core = Core::ICore::instance();
2446 Core::IVersionControl *vc = core->vcsManager()->findVersionControlForDirectory(dir);
2447 bool result = false;
2448 if (vc && vc->supportsOperation(Core::IVersionControl::MoveOperation))
2449 result = vc->vcsMove(orgFilePath, newFilePath);
2450 if (!result) // The moving via vcs failed or the vcs does not support moving, fall back
2451 result = QFile::rename(orgFilePath, newFilePath);
2453 // yeah we moved, tell the filemanager about it
2454 Core::ICore::instance()->fileManager()->renamedFile(orgFilePath, newFilePath);
2455 // Tell the project plugin about it
2456 ProjectNode *projectNode = fileNode->projectNode();
2457 projectNode->renameFile(fileNode->fileType(), orgFilePath, newFilePath);
2458 // TODO emit a signal?
2462 void ProjectExplorerPlugin::setStartupProject()
2464 setStartupProject(d->m_currentProject);
2467 void ProjectExplorerPlugin::populateOpenWithMenu(QMenu *menu, const QString &fileName)
2469 typedef QList<Core::IEditorFactory*> EditorFactoryList;
2470 typedef QList<Core::IExternalEditor*> ExternalEditorList;
2474 bool anyMatches = false;
2476 Core::ICore *core = Core::ICore::instance();
2477 if (const Core::MimeType mt = core->mimeDatabase()->findByFile(QFileInfo(fileName))) {
2478 const EditorFactoryList factories = core->editorManager()->editorFactories(mt, false);
2479 const ExternalEditorList externalEditors = core->editorManager()->externalEditors(mt, false);
2480 anyMatches = !factories.empty() || !externalEditors.empty();
2482 // Add all suitable editors
2483 foreach (Core::IEditorFactory *editorFactory, factories) {
2484 // Add action to open with this very editor factory
2485 QString const actionTitle = editorFactory->displayName();
2486 QAction * const action = menu->addAction(actionTitle);
2487 action->setData(qVariantFromValue(editorFactory));
2489 // Add all suitable external editors
2490 foreach (Core::IExternalEditor *externalEditor, externalEditors) {
2491 QAction * const action = menu->addAction(externalEditor->displayName());
2492 action->setData(qVariantFromValue(externalEditor));
2496 menu->setEnabled(anyMatches);
2499 void ProjectExplorerPlugin::populateOpenWithMenu()
2501 populateOpenWithMenu(d->m_openWithMenu, currentNode()->path());
2504 void ProjectExplorerPlugin::openWithMenuTriggered(QAction *action)
2507 qWarning() << "ProjectExplorerPlugin::openWithMenuTriggered no action, can't happen.";
2509 openEditorFromAction(action, currentNode()->path());
2512 void ProjectExplorerPlugin::openEditorFromAction(QAction *action, const QString &fileName)
2514 Core::EditorManager *em = Core::EditorManager::instance();
2515 const QVariant data = action->data();
2516 if (qVariantCanConvert<Core::IEditorFactory *>(data)) {
2517 Core::IEditorFactory *factory = qVariantValue<Core::IEditorFactory *>(data);
2519 // close any open editors that have this file open, but have a different type.
2520 QList<Core::IEditor *> editorsOpenForFile = em->editorsForFileName(fileName);
2521 if (!editorsOpenForFile.isEmpty()) {
2522 foreach (Core::IEditor *openEditor, editorsOpenForFile) {
2523 if (factory->id() == openEditor->id())
2524 editorsOpenForFile.removeAll(openEditor);
2526 if (!em->closeEditors(editorsOpenForFile)) // don't open if cancel was pressed
2530 em->openEditor(fileName, factory->id(), Core::EditorManager::ModeSwitch);
2533 if (qVariantCanConvert<Core::IExternalEditor *>(data)) {
2534 Core::IExternalEditor *externalEditor = qVariantValue<Core::IExternalEditor *>(data);
2535 em->openExternalEditor(fileName, externalEditor->id());
2539 void ProjectExplorerPlugin::updateSessionMenu()
2541 d->m_sessionMenu->clear();
2542 QActionGroup *ag = new QActionGroup(d->m_sessionMenu);
2543 connect(ag, SIGNAL(triggered(QAction *)), this, SLOT(setSession(QAction *)));
2544 const QString &activeSession = d->m_session->activeSession();
2545 foreach (const QString &session, d->m_session->sessions()) {
2546 QAction *act = ag->addAction(session);
2547 act->setCheckable(true);
2548 if (session == activeSession)
2549 act->setChecked(true);
2551 d->m_sessionMenu->addActions(ag->actions());
2552 d->m_sessionMenu->setEnabled(true);
2555 void ProjectExplorerPlugin::setSession(QAction *action)
2557 QString session = action->text();
2558 if (session != d->m_session->activeSession())
2559 d->m_session->loadSession(session);
2563 void ProjectExplorerPlugin::setProjectExplorerSettings(const Internal::ProjectExplorerSettings &pes)
2565 if (d->m_projectExplorerSettings == pes)
2567 d->m_projectExplorerSettings = pes;
2568 emit settingsChanged();
2571 Internal::ProjectExplorerSettings ProjectExplorerPlugin::projectExplorerSettings() const
2573 return d->m_projectExplorerSettings;
2576 QStringList ProjectExplorerPlugin::projectFilePatterns()
2578 QStringList patterns;
2579 const Core::MimeDatabase *mdb = Core::ICore::instance()->mimeDatabase();
2580 foreach(const IProjectManager *pm, allProjectManagers())
2581 if (const Core::MimeType mt = mdb->findByType(pm->mimeType()))
2582 foreach(const Core::MimeGlobPattern &gp, mt.globPatterns())
2583 patterns += gp.regExp().pattern();
2587 void ProjectExplorerPlugin::openOpenProjectDialog()
2589 Core::FileManager *fileMananger = Core::ICore::instance()->fileManager();
2590 const QString projectPatterns = ProjectExplorerPlugin::projectFilePatterns().join(QString(QLatin1Char(' ')));
2591 QString projectFilesFilter = tr("Projects (%1)").arg(projectPatterns);
2592 const QString allFilesFilter = tr("All Files (*)");
2593 const QString filters = allFilesFilter + QLatin1String(";;") + projectFilesFilter;
2594 const QString path = fileMananger->useProjectsDirectory() ? fileMananger->projectsDirectory() : QString();
2595 const QStringList files = fileMananger->getOpenFileNames(filters, path, &projectFilesFilter);
2596 if (!files.isEmpty())
2597 Core::ICore::instance()->openFiles(files, Core::ICore::SwitchMode);
2600 Q_EXPORT_PLUGIN(ProjectExplorerPlugin)