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"
39 #include "projectexplorersettings.h"
41 #include "targetsettingspanel.h"
42 #include "copytaskhandler.h"
43 #include "showineditortaskhandler.h"
44 #include "vcsannotatetaskhandler.h"
45 #include "localapplicationruncontrol.h"
46 #include "allprojectsfilter.h"
47 #include "allprojectsfind.h"
48 #include "buildmanager.h"
49 #include "buildsettingspropertiespage.h"
50 #include "currentprojectfind.h"
51 #include "currentprojectfilter.h"
52 #include "customexecutablerunconfiguration.h"
53 #include "editorsettingspropertiespage.h"
54 #include "dependenciespanel.h"
55 #include "foldernavigationwidget.h"
56 #include "iprojectmanager.h"
57 #include "metatypedeclarations.h"
58 #include "nodesvisitor.h"
59 #include "outputwindow.h"
60 #include "persistentsettings.h"
61 #include "pluginfilefactory.h"
62 #include "processstep.h"
63 #include "projectexplorerconstants.h"
64 #include "customwizard.h"
65 #include "projectfilewizardextension.h"
66 #include "projecttreewidget.h"
67 #include "projectwindow.h"
68 #include "removefiledialog.h"
69 #include "runsettingspropertiespage.h"
70 #include "scriptwrappers.h"
72 #include "projectnodes.h"
73 #include "sessiondialog.h"
75 #include "projectexplorersettingspage.h"
76 #include "projectwelcomepage.h"
77 #include "projectwelcomepagewidget.h"
78 #include "corelistenercheckingforrunningbuild.h"
79 #include "buildconfiguration.h"
80 #include "miniprojecttargetselector.h"
82 #include "publishing/ipublishingwizardfactory.h"
83 #include "publishing/publishingwizardselectiondialog.h"
85 #include <coreplugin/coreconstants.h>
86 #include <coreplugin/filemanager.h>
87 #include <coreplugin/icore.h>
88 #include <coreplugin/imode.h>
89 #include <coreplugin/mimedatabase.h>
90 #include <coreplugin/modemanager.h>
91 #include <coreplugin/actionmanager/actionmanager.h>
92 #include <coreplugin/actionmanager/actioncontainer.h>
93 #include <coreplugin/actionmanager/command.h>
94 #include <coreplugin/uniqueidmanager.h>
95 #include <coreplugin/editormanager/editormanager.h>
96 #include <coreplugin/editormanager/ieditor.h>
97 #include <coreplugin/editormanager/ieditorfactory.h>
98 #include <coreplugin/editormanager/iexternaleditor.h>
99 #include <coreplugin/findplaceholder.h>
100 #include <coreplugin/basefilewizard.h>
101 #include <coreplugin/vcsmanager.h>
102 #include <coreplugin/iversioncontrol.h>
103 #include <welcome/welcomemode.h>
104 #include <extensionsystem/pluginmanager.h>
105 #include <find/searchresultwindow.h>
106 #include <utils/consoleprocess.h>
107 #include <utils/qtcassert.h>
108 #include <utils/parameteraction.h>
109 #include <utils/stringutils.h>
111 #include <QtCore/QtPlugin>
112 #include <QtCore/QDateTime>
113 #include <QtCore/QDebug>
114 #include <QtCore/QSettings>
116 #include <QtGui/QAction>
117 #include <QtGui/QApplication>
118 #include <QtGui/QFileDialog>
119 #include <QtGui/QMenu>
120 #include <QtGui/QMessageBox>
121 #include <QtGui/QMainWindow>
122 #include <QtGui/QWizard>
124 Q_DECLARE_METATYPE(Core::IEditorFactory*)
125 Q_DECLARE_METATYPE(Core::IExternalEditor*)
131 namespace ProjectExplorer {
133 struct ProjectExplorerPluginPrivate {
134 ProjectExplorerPluginPrivate();
136 QMenu *m_sessionContextMenu;
137 QMenu *m_sessionMenu;
138 QMenu *m_projectMenu;
139 QMenu *m_subProjectMenu;
142 QMenu *m_openWithMenu;
144 QMultiMap<int, QObject*> m_actionMap;
145 QAction *m_sessionManagerAction;
146 QAction *m_newAction;
147 QAction *m_loadAction;
148 Utils::ParameterAction *m_unloadAction;
149 QAction *m_clearSession;
150 QAction *m_buildProjectOnlyAction;
151 Utils::ParameterAction *m_buildAction;
152 Utils::ParameterAction *m_buildActionContextMenu;
153 QAction *m_buildSessionAction;
154 QAction *m_rebuildProjectOnlyAction;
155 Utils::ParameterAction *m_rebuildAction;
156 Utils::ParameterAction *m_rebuildActionContextMenu;
157 QAction *m_rebuildSessionAction;
158 QAction *m_cleanProjectOnlyAction;
159 QAction *m_deployProjectOnlyAction;
160 Utils::ParameterAction *m_deployAction;
161 Utils::ParameterAction *m_deployActionContextMenu;
162 QAction *m_deploySessionAction;
163 Utils::ParameterAction *m_publishAction;
164 Utils::ParameterAction *m_cleanAction;
165 Utils::ParameterAction *m_cleanActionContextMenu;
166 QAction *m_cleanSessionAction;
167 QAction *m_runAction;
168 QAction *m_runActionContextMenu;
169 QAction *m_cancelBuildAction;
170 QAction *m_addNewFileAction;
171 QAction *m_addExistingFilesAction;
172 QAction *m_addNewSubprojectAction;
173 QAction *m_removeFileAction;
174 QAction *m_removeProjectAction;
175 QAction *m_deleteFileAction;
176 QAction *m_renameFileAction;
177 QAction *m_openFileAction;
178 QAction *m_showInGraphicalShell;
179 QAction *m_openTerminalHere;
180 QAction *m_setStartupProjectAction;
181 QAction *m_projectSelectorAction;
182 QAction *m_projectSelectorActionMenu;
184 Internal::ProjectWindow *m_proWindow;
185 SessionManager *m_session;
186 QString m_sessionToRestoreAtStartup;
188 Project *m_currentProject;
191 BuildManager *m_buildManager;
193 QList<Internal::ProjectFileFactory*> m_fileFactories;
194 QStringList m_profileMimeTypes;
195 Internal::OutputPane *m_outputPane;
197 QList<QPair<QString, QString> > m_recentProjects; // pair of filename, displayname
198 static const int m_maxRecentProjects = 7;
200 QString m_lastOpenDirectory;
201 RunConfiguration *m_delayedRunConfiguration; // TODO this is not right
203 QString m_projectFilterString;
204 Internal::MiniProjectTargetSelector * m_targetSelector;
205 Internal::ProjectExplorerSettings m_projectExplorerSettings;
206 Internal::ProjectWelcomePage *m_welcomePage;
208 Core::IMode *m_projectsMode;
211 ProjectExplorerPluginPrivate::ProjectExplorerPluginPrivate() :
214 m_delayedRunConfiguration(0),
219 class ProjectsMode : public Core::IMode
222 ProjectsMode(QWidget *proWindow) : m_widget(proWindow) {}
224 QString displayName() const { return tr("Projects"); }
225 QIcon icon() const { return QIcon(QLatin1String(":/fancyactionbar/images/mode_Project.png")); }
226 int priority() const { return Constants::P_MODE_SESSION; }
227 QWidget *widget() { return m_widget; }
228 QString id() const { return QLatin1String(Constants::MODE_SESSION); }
229 QString type() const { return QString(); }
230 Core::Context context() const { return Core::Context(Constants::C_PROJECTEXPLORER); }
231 QString contextHelpId() const { return QLatin1String("Managing Projects"); }
238 } // namespace ProjectExplorer
240 using namespace ProjectExplorer;
241 using namespace ProjectExplorer::Internal;
244 ProjectExplorerPlugin *ProjectExplorerPlugin::m_instance = 0;
246 ProjectExplorerPlugin::ProjectExplorerPlugin()
247 : d(new ProjectExplorerPluginPrivate)
252 ProjectExplorerPlugin::~ProjectExplorerPlugin()
254 removeObject(d->m_welcomePage);
255 delete d->m_welcomePage;
260 ProjectExplorerPlugin *ProjectExplorerPlugin::instance()
265 bool ProjectExplorerPlugin::parseArguments(const QStringList &arguments, QString * /* error */)
267 CustomWizard::setVerbose(arguments.count(QLatin1String("-customwizard-verbose")));
271 bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *error)
273 if (!parseArguments(arguments, error))
277 addAutoReleasedObject(new TaskHub);
279 Core::ICore *core = Core::ICore::instance();
280 Core::ActionManager *am = core->actionManager();
281 connect(core, SIGNAL(newItemsDialogRequested()), this, SLOT(loadCustomWizards()));
283 d->m_welcomePage = new ProjectWelcomePage;
284 connect(d->m_welcomePage, SIGNAL(manageSessions()), this, SLOT(showSessionManager()));
285 addObject(d->m_welcomePage);
287 connect(core->fileManager(), SIGNAL(currentFileChanged(QString)),
288 this, SLOT(setCurrentFile(QString)));
290 d->m_session = new SessionManager(this);
292 connect(d->m_session, SIGNAL(projectAdded(ProjectExplorer::Project *)),
293 this, SIGNAL(fileListChanged()));
294 connect(d->m_session, SIGNAL(aboutToRemoveProject(ProjectExplorer::Project *)),
295 this, SLOT(invalidateProject(ProjectExplorer::Project *)));
296 connect(d->m_session, SIGNAL(projectRemoved(ProjectExplorer::Project *)),
297 this, SIGNAL(fileListChanged()));
298 connect(d->m_session, SIGNAL(startupProjectChanged(ProjectExplorer::Project *)),
299 this, SLOT(startupProjectChanged()));
300 connect(d->m_session, SIGNAL(dependencyChanged(ProjectExplorer::Project*,ProjectExplorer::Project*)),
301 this, SLOT(updateActions()));
303 d->m_proWindow = new ProjectWindow;
305 Core::Context globalcontext(Core::Constants::C_GLOBAL);
306 Core::Context projecTreeContext(Constants::C_PROJECT_TREE);
308 d->m_projectsMode = new ProjectsMode(d->m_proWindow);
309 d->m_projectsMode->setEnabled(session()->startupProject());
310 addAutoReleasedObject(d->m_projectsMode);
311 d->m_proWindow->layout()->addWidget(new Core::FindToolBarPlaceHolder(d->m_proWindow));
313 addAutoReleasedObject(new CopyTaskHandler);
314 addAutoReleasedObject(new ShowInEditorTaskHandler);
315 addAutoReleasedObject(new VcsAnnotateTaskHandler);
317 d->m_buildManager = new BuildManager(this);
318 connect(d->m_buildManager, SIGNAL(buildStateChanged(ProjectExplorer::Project *)),
319 this, SLOT(buildStateChanged(ProjectExplorer::Project *)));
320 connect(d->m_buildManager, SIGNAL(buildQueueFinished(bool)),
321 this, SLOT(buildQueueFinished(bool)));
323 addAutoReleasedObject(new CoreListener);
325 d->m_outputPane = new OutputPane;
326 addAutoReleasedObject(d->m_outputPane);
327 connect(d->m_session, SIGNAL(projectRemoved(ProjectExplorer::Project *)),
328 d->m_outputPane, SLOT(projectRemoved()));
330 AllProjectsFilter *allProjectsFilter = new AllProjectsFilter(this);
331 addAutoReleasedObject(allProjectsFilter);
333 CurrentProjectFilter *currentProjectFilter = new CurrentProjectFilter(this);
334 addAutoReleasedObject(currentProjectFilter);
336 addAutoReleasedObject(new BuildSettingsPanelFactory);
337 addAutoReleasedObject(new RunSettingsPanelFactory);
338 addAutoReleasedObject(new EditorSettingsPanelFactory);
339 addAutoReleasedObject(new DependenciesPanelFactory(d->m_session));
341 ProcessStepFactory *processStepFactory = new ProcessStepFactory;
342 addAutoReleasedObject(processStepFactory);
344 AllProjectsFind *allProjectsFind = new AllProjectsFind(this,
345 Find::SearchResultWindow::instance());
346 addAutoReleasedObject(allProjectsFind);
348 CurrentProjectFind *currentProjectFind = new CurrentProjectFind(this,
349 Find::SearchResultWindow::instance());
350 addAutoReleasedObject(currentProjectFind);
352 addAutoReleasedObject(new LocalApplicationRunControlFactory);
353 addAutoReleasedObject(new CustomExecutableRunConfigurationFactory);
355 addAutoReleasedObject(new ProjectFileWizardExtension);
358 addAutoReleasedObject(new ProjectExplorerSettingsPage);
361 Core::ActionContainer *msessionContextMenu =
362 am->createMenu(Constants::M_SESSIONCONTEXT);
363 Core::ActionContainer *mprojectContextMenu =
364 am->createMenu(Constants::M_PROJECTCONTEXT);
365 Core::ActionContainer *msubProjectContextMenu =
366 am->createMenu(Constants::M_SUBPROJECTCONTEXT);
367 Core::ActionContainer *mfolderContextMenu =
368 am->createMenu(Constants::M_FOLDERCONTEXT);
369 Core::ActionContainer *mfileContextMenu =
370 am->createMenu(Constants::M_FILECONTEXT);
372 d->m_sessionContextMenu = msessionContextMenu->menu();
373 d->m_projectMenu = mprojectContextMenu->menu();
374 d->m_subProjectMenu = msubProjectContextMenu->menu();
375 d->m_folderMenu = mfolderContextMenu->menu();
376 d->m_fileMenu = mfileContextMenu->menu();
378 Core::ActionContainer *mfile =
379 am->actionContainer(Core::Constants::M_FILE);
380 Core::ActionContainer *menubar =
381 am->actionContainer(Core::Constants::MENU_BAR);
383 // mode manager (for fancy actions)
384 Core::ModeManager *modeManager = core->modeManager();
387 Core::ActionContainer *mbuild =
388 am->createMenu(Constants::M_BUILDPROJECT);
389 mbuild->menu()->setTitle(tr("&Build"));
390 menubar->addMenu(mbuild, Core::Constants::G_VIEW);
393 Core::ActionContainer *mdebug =
394 am->createMenu(Constants::M_DEBUG);
395 mdebug->menu()->setTitle(tr("&Debug"));
396 menubar->addMenu(mdebug, Core::Constants::G_VIEW);
398 Core::ActionContainer *mstartdebugging =
399 am->createMenu(Constants::M_DEBUG_STARTDEBUGGING);
400 mstartdebugging->menu()->setTitle(tr("&Start Debugging"));
401 mdebug->addMenu(mstartdebugging, Core::Constants::G_DEFAULT_ONE);
407 mbuild->appendGroup(Constants::G_BUILD_SESSION);
408 mbuild->appendGroup(Constants::G_BUILD_PROJECT);
409 mbuild->appendGroup(Constants::G_BUILD_OTHER);
410 mbuild->appendGroup(Constants::G_BUILD_CANCEL);
411 mbuild->appendGroup(Constants::G_BUILD_RUN);
413 msessionContextMenu->appendGroup(Constants::G_SESSION_BUILD);
414 msessionContextMenu->appendGroup(Constants::G_SESSION_FILES);
415 msessionContextMenu->appendGroup(Constants::G_SESSION_OTHER);
416 msessionContextMenu->appendGroup(Constants::G_SESSION_CONFIG);
418 mprojectContextMenu->appendGroup(Constants::G_PROJECT_FIRST);
419 mprojectContextMenu->appendGroup(Constants::G_PROJECT_BUILD);
420 mprojectContextMenu->appendGroup(Constants::G_PROJECT_RUN);
421 mprojectContextMenu->appendGroup(Constants::G_PROJECT_FILES);
422 mprojectContextMenu->appendGroup(Constants::G_PROJECT_OTHER);
423 mprojectContextMenu->appendGroup(Constants::G_PROJECT_CONFIG);
425 msubProjectContextMenu->appendGroup(Constants::G_PROJECT_FIRST);
426 msubProjectContextMenu->appendGroup(Constants::G_PROJECT_BUILD);
427 msubProjectContextMenu->appendGroup(Constants::G_PROJECT_FILES);
428 msubProjectContextMenu->appendGroup(Constants::G_PROJECT_OTHER);
429 msubProjectContextMenu->appendGroup(Constants::G_PROJECT_CONFIG);
431 mfolderContextMenu->appendGroup(Constants::G_FOLDER_FILES);
432 mfolderContextMenu->appendGroup(Constants::G_FOLDER_OTHER);
433 mfolderContextMenu->appendGroup(Constants::G_FOLDER_CONFIG);
435 mfileContextMenu->appendGroup(Constants::G_FILE_OPEN);
436 mfileContextMenu->appendGroup(Constants::G_FILE_OTHER);
437 mfileContextMenu->appendGroup(Constants::G_FILE_CONFIG);
439 // "open with" submenu
440 Core::ActionContainer * const openWith =
441 am->createMenu(ProjectExplorer::Constants::M_OPENFILEWITHCONTEXT);
442 openWith->setOnAllDisabledBehavior(Core::ActionContainer::Show);
443 d->m_openWithMenu = openWith->menu();
444 d->m_openWithMenu->setTitle(tr("Open With"));
446 connect(d->m_openWithMenu, SIGNAL(triggered(QAction *)),
447 this, SLOT(openWithMenuTriggered(QAction *)));
456 sep = new QAction(this);
457 sep->setSeparator(true);
458 cmd = am->registerAction(sep, Core::Id("ProjectExplorer.Build.Sep"), globalcontext);
459 mbuild->addAction(cmd, Constants::G_BUILD_PROJECT);
461 sep = new QAction(this);
462 sep->setSeparator(true);
463 cmd = am->registerAction(sep, Core::Id("ProjectExplorer.Files.Sep"), projecTreeContext);
464 msessionContextMenu->addAction(cmd, Constants::G_SESSION_FILES);
465 mprojectContextMenu->addAction(cmd, Constants::G_PROJECT_FILES);
466 msubProjectContextMenu->addAction(cmd, Constants::G_PROJECT_FILES);
468 sep = new QAction(this);
469 sep->setSeparator(true);
470 cmd = am->registerAction(sep, Core::Id("ProjectExplorer.Config.Sep"), projecTreeContext);
471 msessionContextMenu->addAction(cmd, Constants::G_SESSION_CONFIG);
472 mprojectContextMenu->addAction(cmd, Constants::G_PROJECT_CONFIG);
473 msubProjectContextMenu->addAction(cmd, Constants::G_PROJECT_CONFIG);
475 sep = new QAction(this);
476 sep->setSeparator(true);
477 cmd = am->registerAction(sep, Core::Id("ProjectExplorer.Projects.Sep"), globalcontext);
478 mfile->addAction(cmd, Core::Constants::G_FILE_PROJECT);
480 sep = new QAction(this);
481 sep->setSeparator(true);
482 cmd = am->registerAction(sep, Core::Id("ProjectExplorer.Other.Sep"), globalcontext);
483 mbuild->addAction(cmd, Constants::G_BUILD_OTHER);
484 msessionContextMenu->addAction(cmd, Constants::G_SESSION_OTHER);
485 mprojectContextMenu->addAction(cmd, Constants::G_PROJECT_OTHER);
486 msubProjectContextMenu->addAction(cmd, Constants::G_PROJECT_OTHER);
488 sep = new QAction(this);
489 sep->setSeparator(true);
490 cmd = am->registerAction(sep, Core::Id("ProjectExplorer.Run.Sep"), globalcontext);
491 mbuild->addAction(cmd, Constants::G_BUILD_RUN);
492 mprojectContextMenu->addAction(cmd, Constants::G_PROJECT_RUN);
494 sep = new QAction(this);
495 sep->setSeparator(true);
496 cmd = am->registerAction(sep, Core::Id("ProjectExplorer.CancelBuild.Sep"), globalcontext);
497 mbuild->addAction(cmd, Constants::G_BUILD_CANCEL);
503 // new session action
504 d->m_sessionManagerAction = new QAction(tr("Session Manager..."), this);
505 cmd = am->registerAction(d->m_sessionManagerAction, Constants::NEWSESSION, globalcontext);
506 cmd->setDefaultKeySequence(QKeySequence());
509 d->m_newAction = new QAction(tr("New Project..."), this);
510 cmd = am->registerAction(d->m_newAction, Constants::NEWPROJECT, globalcontext);
511 cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+N")));
512 msessionContextMenu->addAction(cmd, Constants::G_SESSION_FILES);
515 d->m_loadAction = new QAction(tr("Load Project..."), this);
516 cmd = am->registerAction(d->m_loadAction, Constants::LOAD, globalcontext);
518 cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+O")));
520 msessionContextMenu->addAction(cmd, Constants::G_SESSION_FILES);
522 // Default open action
523 d->m_openFileAction = new QAction(tr("Open File"), this);
524 cmd = am->registerAction(d->m_openFileAction, ProjectExplorer::Constants::OPENFILE,
526 mfileContextMenu->addAction(cmd, Constants::G_FILE_OPEN);
528 d->m_showInGraphicalShell = new QAction(FolderNavigationWidget::msgGraphicalShellAction(), this);
529 cmd = am->registerAction(d->m_showInGraphicalShell, ProjectExplorer::Constants::SHOWINGRAPHICALSHELL,
531 mfileContextMenu->addAction(cmd, Constants::G_FILE_OPEN);
532 mfolderContextMenu->addAction(cmd, Constants::G_FOLDER_FILES);
534 d->m_openTerminalHere = new QAction(FolderNavigationWidget::msgTerminalAction(), this);
535 cmd = am->registerAction(d->m_openTerminalHere, ProjectExplorer::Constants::OPENTERMIANLHERE,
537 mfileContextMenu->addAction(cmd, Constants::G_FILE_OPEN);
538 mfolderContextMenu->addAction(cmd, Constants::G_FOLDER_FILES);
541 mfileContextMenu->addMenu(openWith, ProjectExplorer::Constants::G_FILE_OPEN);
543 // recent projects menu
544 Core::ActionContainer *mrecent =
545 am->createMenu(Constants::M_RECENTPROJECTS);
546 mrecent->menu()->setTitle(tr("Recent P&rojects"));
547 mrecent->setOnAllDisabledBehavior(Core::ActionContainer::Show);
548 mfile->addMenu(mrecent, Core::Constants::G_FILE_OPEN);
549 connect(mfile->menu(), SIGNAL(aboutToShow()),
550 this, SLOT(updateRecentProjectMenu()));
554 d->m_unloadAction = new Utils::ParameterAction(tr("Close Project"), tr("Close Project \"%1\""),
555 Utils::ParameterAction::EnabledWithParameter, this);
556 cmd = am->registerAction(d->m_unloadAction, Constants::UNLOAD, globalcontext);
557 cmd->setAttribute(Core::Command::CA_UpdateText);
558 cmd->setDefaultText(d->m_unloadAction->text());
559 mfile->addAction(cmd, Core::Constants::G_FILE_PROJECT);
561 // unload session action
562 d->m_clearSession = new QAction(tr("Close All Projects"), this);
563 cmd = am->registerAction(d->m_clearSession, Constants::CLEARSESSION, globalcontext);
564 mfile->addAction(cmd, Core::Constants::G_FILE_PROJECT);
565 msessionContextMenu->addAction(cmd, Constants::G_SESSION_FILES);
568 Core::ActionContainer *msession = am->createMenu(Constants::M_SESSION);
569 msession->menu()->setTitle(tr("Session"));
570 msession->setOnAllDisabledBehavior(Core::ActionContainer::Show);
571 mfile->addMenu(msession, Core::Constants::G_FILE_PROJECT);
572 d->m_sessionMenu = msession->menu();
573 connect(mfile->menu(), SIGNAL(aboutToShow()),
574 this, SLOT(updateSessionMenu()));
576 // build session action
577 QIcon buildIcon(Constants::ICON_BUILD);
578 buildIcon.addFile(Constants::ICON_BUILD_SMALL);
579 d->m_buildSessionAction = new QAction(buildIcon, tr("Build All"), this);
580 cmd = am->registerAction(d->m_buildSessionAction, Constants::BUILDSESSION, globalcontext);
581 cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+B")));
582 mbuild->addAction(cmd, Constants::G_BUILD_SESSION);
583 msessionContextMenu->addAction(cmd, Constants::G_SESSION_BUILD);
585 modeManager->addAction(cmd, Constants::P_ACTION_BUILDSESSION);
587 // rebuild session action
588 QIcon rebuildIcon(Constants::ICON_REBUILD);
589 rebuildIcon.addFile(Constants::ICON_REBUILD_SMALL);
590 d->m_rebuildSessionAction = new QAction(rebuildIcon, tr("Rebuild All"), this);
591 cmd = am->registerAction(d->m_rebuildSessionAction, Constants::REBUILDSESSION, globalcontext);
592 mbuild->addAction(cmd, Constants::G_BUILD_SESSION);
593 msessionContextMenu->addAction(cmd, Constants::G_SESSION_BUILD);
596 d->m_deploySessionAction = new QAction(tr("Deploy All"), this);
597 cmd = am->registerAction(d->m_deploySessionAction, Constants::DEPLOYSESSION, globalcontext);
598 mbuild->addAction(cmd, Constants::G_BUILD_SESSION);
599 msessionContextMenu->addAction(cmd, Constants::G_SESSION_BUILD);
602 QIcon cleanIcon(Constants::ICON_CLEAN);
603 cleanIcon.addFile(Constants::ICON_CLEAN_SMALL);
604 d->m_cleanSessionAction = new QAction(cleanIcon, tr("Clean All"), this);
605 cmd = am->registerAction(d->m_cleanSessionAction, Constants::CLEANSESSION, globalcontext);
606 mbuild->addAction(cmd, Constants::G_BUILD_SESSION);
607 msessionContextMenu->addAction(cmd, Constants::G_SESSION_BUILD);
610 d->m_buildAction = new Utils::ParameterAction(tr("Build Project"), tr("Build Project \"%1\""),
611 Utils::ParameterAction::AlwaysEnabled, this);
612 cmd = am->registerAction(d->m_buildAction, Constants::BUILD, globalcontext);
613 cmd->setAttribute(Core::Command::CA_UpdateText);
614 cmd->setDefaultText(d->m_buildAction->text());
615 cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+B")));
616 mbuild->addAction(cmd, Constants::G_BUILD_PROJECT);
619 d->m_rebuildAction = new Utils::ParameterAction(tr("Rebuild Project"), tr("Rebuild Project \"%1\""),
620 Utils::ParameterAction::AlwaysEnabled, this);
621 cmd = am->registerAction(d->m_rebuildAction, Constants::REBUILD, globalcontext);
622 cmd->setAttribute(Core::Command::CA_UpdateText);
623 cmd->setDefaultText(d->m_rebuildAction->text());
624 mbuild->addAction(cmd, Constants::G_BUILD_PROJECT);
627 d->m_deployAction = new Utils::ParameterAction(tr("Deploy Project"), tr("Deploy Project \"%1\""),
628 Utils::ParameterAction::AlwaysEnabled, this);
629 cmd = am->registerAction(d->m_deployAction, Constants::DEPLOY, globalcontext);
630 cmd->setAttribute(Core::Command::CA_UpdateText);
631 cmd->setDefaultText(d->m_deployAction->text());
632 mbuild->addAction(cmd, Constants::G_BUILD_PROJECT);
635 d->m_publishAction = new Utils::ParameterAction(tr("Publish Project..."), tr("Publish Project \"%1\"..."),
636 Utils::ParameterAction::AlwaysEnabled, this);
637 cmd = am->registerAction(d->m_publishAction, Constants::PUBLISH, globalcontext);
638 cmd->setAttribute(Core::Command::CA_UpdateText);
639 cmd->setDefaultText(d->m_publishAction->text());
640 mbuild->addAction(cmd, Constants::G_BUILD_PROJECT);
643 d->m_cleanAction = new Utils::ParameterAction(tr("Clean Project"), tr("Clean Project \"%1\""),
644 Utils::ParameterAction::AlwaysEnabled, this);
645 cmd = am->registerAction(d->m_cleanAction, Constants::CLEAN, globalcontext);
646 cmd->setAttribute(Core::Command::CA_UpdateText);
647 cmd->setDefaultText(d->m_cleanAction->text());
648 mbuild->addAction(cmd, Constants::G_BUILD_PROJECT);
650 // build action (context menu)
651 d->m_buildActionContextMenu = new Utils::ParameterAction(tr("Build Project"), tr("Build Project \"%1\""),
652 Utils::ParameterAction::AlwaysEnabled, this);
653 cmd = am->registerAction(d->m_buildActionContextMenu, Constants::BUILDCM, projecTreeContext);
654 cmd->setAttribute(Core::Command::CA_UpdateText);
655 cmd->setDefaultText(d->m_buildActionContextMenu->text());
656 mprojectContextMenu->addAction(cmd, Constants::G_PROJECT_BUILD);
658 // rebuild action (context menu)
659 d->m_rebuildActionContextMenu = new Utils::ParameterAction(tr("Rebuild Project"), tr("Rebuild Project \"%1\""),
660 Utils::ParameterAction::AlwaysEnabled, this);
661 cmd = am->registerAction(d->m_rebuildActionContextMenu, Constants::REBUILDCM, projecTreeContext);
662 cmd->setAttribute(Core::Command::CA_UpdateText);
663 cmd->setDefaultText(d->m_rebuildActionContextMenu->text());
664 mprojectContextMenu->addAction(cmd, Constants::G_PROJECT_BUILD);
666 // deploy action (context menu)
667 d->m_deployActionContextMenu = new Utils::ParameterAction(tr("Deploy Project"), tr("Deploy Project \"%1\""),
668 Utils::ParameterAction::AlwaysEnabled, this);
669 cmd = am->registerAction(d->m_deployActionContextMenu, Constants::DEPLOYCM, projecTreeContext);
670 cmd->setAttribute(Core::Command::CA_UpdateText);
671 cmd->setDefaultText(d->m_deployActionContextMenu->text());
672 mprojectContextMenu->addAction(cmd, Constants::G_PROJECT_BUILD);
674 // clean action (context menu)
675 d->m_cleanActionContextMenu = new Utils::ParameterAction(tr("Clean Project"), tr("Clean Project \"%1\""),
676 Utils::ParameterAction::AlwaysEnabled, this);
677 cmd = am->registerAction(d->m_cleanActionContextMenu, Constants::CLEANCM, projecTreeContext);
678 cmd->setAttribute(Core::Command::CA_UpdateText);
679 cmd->setDefaultText(d->m_cleanActionContextMenu->text());
680 mprojectContextMenu->addAction(cmd, Constants::G_PROJECT_BUILD);
682 // build without dependencies action
683 d->m_buildProjectOnlyAction = new QAction(tr("Build Without Dependencies"), this);
684 cmd = am->registerAction(d->m_buildProjectOnlyAction, Constants::BUILDPROJECTONLY, globalcontext);
686 // rebuild without dependencies action
687 d->m_rebuildProjectOnlyAction = new QAction(tr("Rebuild Without Dependencies"), this);
688 cmd = am->registerAction(d->m_rebuildProjectOnlyAction, Constants::REBUILDPROJECTONLY, globalcontext);
690 // deploy without dependencies action
691 d->m_deployProjectOnlyAction = new QAction(tr("Deploy Without Dependencies"), this);
692 cmd = am->registerAction(d->m_deployProjectOnlyAction, Constants::DEPLOYPROJECTONLY, globalcontext);
694 // clean without dependencies action
695 d->m_cleanProjectOnlyAction = new QAction(tr("Clean Without Dependencies"), this);
696 cmd = am->registerAction(d->m_cleanProjectOnlyAction, Constants::CLEANPROJECTONLY, globalcontext);
699 QIcon runIcon(Constants::ICON_RUN);
700 runIcon.addFile(Constants::ICON_RUN_SMALL);
701 d->m_runAction = new QAction(runIcon, tr("Run"), this);
702 cmd = am->registerAction(d->m_runAction, Constants::RUN, globalcontext);
703 cmd->setAttribute(Core::Command::CA_UpdateText);
705 cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+R")));
706 mbuild->addAction(cmd, Constants::G_BUILD_RUN);
708 modeManager->addAction(cmd, Constants::P_ACTION_RUN);
710 d->m_runActionContextMenu = new QAction(runIcon, tr("Run"), this);
711 cmd = am->registerAction(d->m_runActionContextMenu, Constants::RUNCONTEXTMENU, projecTreeContext);
712 mprojectContextMenu->addAction(cmd, Constants::G_PROJECT_RUN);
714 // cancel build action
715 d->m_cancelBuildAction = new QAction(tr("Cancel Build"), this);
716 cmd = am->registerAction(d->m_cancelBuildAction, Constants::CANCELBUILD, globalcontext);
717 mbuild->addAction(cmd, Constants::G_BUILD_CANCEL);
719 // add new file action
720 d->m_addNewFileAction = new QAction(tr("Add New..."), this);
721 cmd = am->registerAction(d->m_addNewFileAction, ProjectExplorer::Constants::ADDNEWFILE,
723 mprojectContextMenu->addAction(cmd, Constants::G_PROJECT_FILES);
724 msubProjectContextMenu->addAction(cmd, Constants::G_PROJECT_FILES);
725 mfolderContextMenu->addAction(cmd, Constants::G_FOLDER_FILES);
727 // add existing file action
728 d->m_addExistingFilesAction = new QAction(tr("Add Existing Files..."), this);
729 cmd = am->registerAction(d->m_addExistingFilesAction, ProjectExplorer::Constants::ADDEXISTINGFILES,
731 mprojectContextMenu->addAction(cmd, Constants::G_PROJECT_FILES);
732 msubProjectContextMenu->addAction(cmd, Constants::G_PROJECT_FILES);
733 mfolderContextMenu->addAction(cmd, Constants::G_FOLDER_FILES);
735 // new subproject action
736 d->m_addNewSubprojectAction = new QAction(tr("New Subproject..."), this);
737 cmd = am->registerAction(d->m_addNewSubprojectAction, ProjectExplorer::Constants::ADDNEWSUBPROJECT,
739 mprojectContextMenu->addAction(cmd, Constants::G_PROJECT_FILES);
740 msubProjectContextMenu->addAction(cmd, Constants::G_PROJECT_FILES);
742 // unload project again, in right position
743 mprojectContextMenu->addAction(am->command(Constants::UNLOAD), Constants::G_PROJECT_FILES);
745 // remove file action
746 d->m_removeFileAction = new QAction(tr("Remove File..."), this);
747 cmd = am->registerAction(d->m_removeFileAction, ProjectExplorer::Constants::REMOVEFILE,
749 cmd->setDefaultKeySequence(QKeySequence::Delete);
750 mfileContextMenu->addAction(cmd, Constants::G_FILE_OTHER);
752 //: Remove project from parent profile (Project explorer view); will not physically delete any files.
753 d->m_removeProjectAction = new QAction(tr("Remove Project..."), this);
754 cmd = am->registerAction(d->m_removeProjectAction, ProjectExplorer::Constants::REMOVEPROJECT,
756 msubProjectContextMenu->addAction(cmd, Constants::G_PROJECT_FILES);
758 // delete file action
759 d->m_deleteFileAction = new QAction(tr("Delete File..."), this);
760 cmd = am->registerAction(d->m_deleteFileAction, ProjectExplorer::Constants::DELETEFILE,
762 cmd->setDefaultKeySequence(QKeySequence::Delete);
763 mfileContextMenu->addAction(cmd, Constants::G_FILE_OTHER);
766 d->m_renameFileAction = new QAction(tr("Rename"), this);
767 cmd = am->registerAction(d->m_renameFileAction, ProjectExplorer::Constants::RENAMEFILE,
769 mfileContextMenu->addAction(cmd, Constants::G_FILE_OTHER);
770 // Not yet used by anyone, so hide for now
771 // mfolder->addAction(cmd, Constants::G_FOLDER_FILES);
772 // msubProject->addAction(cmd, Constants::G_FOLDER_FILES);
773 // mproject->addAction(cmd, Constants::G_FOLDER_FILES);
775 // set startup project action
776 d->m_setStartupProjectAction = new QAction(tr("Set as Startup Project"), this);
777 cmd = am->registerAction(d->m_setStartupProjectAction, ProjectExplorer::Constants::SETSTARTUP,
779 mprojectContextMenu->addAction(cmd, Constants::G_PROJECT_FIRST);
782 d->m_projectSelectorAction = new QAction(this);
783 d->m_projectSelectorAction->setCheckable(true);
784 d->m_projectSelectorAction->setEnabled(false);
785 QWidget *mainWindow = Core::ICore::instance()->mainWindow();
786 d->m_targetSelector = new Internal::MiniProjectTargetSelector(d->m_projectSelectorAction, mainWindow);
787 connect(d->m_projectSelectorAction, SIGNAL(triggered()), d->m_targetSelector, SLOT(show()));
788 modeManager->addProjectSelector(d->m_projectSelectorAction);
790 d->m_projectSelectorActionMenu = new QAction(this);
791 d->m_projectSelectorActionMenu->setEnabled(false);
792 d->m_projectSelectorActionMenu->setText(tr("Open Build/Run Target Selector..."));
793 connect(d->m_projectSelectorActionMenu, SIGNAL(triggered()), d->m_targetSelector, SLOT(show()));
794 cmd = am->registerAction(d->m_projectSelectorActionMenu, ProjectExplorer::Constants::SELECTTARGET,
796 cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+T")));
797 mbuild->addAction(cmd, Constants::G_BUILD_RUN);
799 connect(d->m_session, SIGNAL(projectAdded(ProjectExplorer::Project*)),
800 d->m_targetSelector, SLOT(addProject(ProjectExplorer::Project*)));
801 connect(d->m_session, SIGNAL(projectRemoved(ProjectExplorer::Project*)),
802 d->m_targetSelector, SLOT(removeProject(ProjectExplorer::Project*)));
803 connect(d->m_targetSelector, SIGNAL(startupProjectChanged(ProjectExplorer::Project*)),
804 this, SLOT(setStartupProject(ProjectExplorer::Project*)));
805 connect(d->m_session, SIGNAL(startupProjectChanged(ProjectExplorer::Project*)),
806 d->m_targetSelector, SLOT(changeStartupProject(ProjectExplorer::Project*)));
808 connect(core, SIGNAL(saveSettingsRequested()),
809 this, SLOT(savePersistentSettings()));
811 addAutoReleasedObject(new ProjectTreeWidgetFactory);
812 addAutoReleasedObject(new FolderNavigationWidgetFactory);
814 if (QSettings *s = core->settings()) {
815 const QStringList fileNames = s->value("ProjectExplorer/RecentProjects/FileNames").toStringList();
816 const QStringList displayNames = s->value("ProjectExplorer/RecentProjects/DisplayNames").toStringList();
817 if (fileNames.size() == displayNames.size()) {
818 for (int i = 0; i < fileNames.size(); ++i) {
819 if (QFileInfo(fileNames.at(i)).isFile())
820 d->m_recentProjects.append(qMakePair(fileNames.at(i), displayNames.at(i)));
825 if (QSettings *s = core->settings()) {
826 d->m_projectExplorerSettings.buildBeforeDeploy = s->value("ProjectExplorer/Settings/BuildBeforeDeploy", true).toBool();
827 d->m_projectExplorerSettings.deployBeforeRun = s->value("ProjectExplorer/Settings/DeployBeforeRun", true).toBool();
828 d->m_projectExplorerSettings.saveBeforeBuild = s->value("ProjectExplorer/Settings/SaveBeforeBuild", false).toBool();
829 d->m_projectExplorerSettings.showCompilerOutput = s->value("ProjectExplorer/Settings/ShowCompilerOutput", false).toBool();
830 d->m_projectExplorerSettings.showRunOutput = s->value("ProjectExplorer/Settings/ShowRunOutput", true).toBool();
831 d->m_projectExplorerSettings.cleanOldAppOutput = s->value("ProjectExplorer/Settings/CleanOldAppOutput", false).toBool();
832 d->m_projectExplorerSettings.wrapAppOutput = s->value("ProjectExplorer/Settings/WrapAppOutput", true).toBool();
833 d->m_projectExplorerSettings.useJom = s->value("ProjectExplorer/Settings/UseJom", true).toBool();
834 d->m_projectExplorerSettings.autorestoreLastSession = s->value("ProjectExplorer/Settings/AutoRestoreLastSession", false).toBool();
835 d->m_projectExplorerSettings.environmentId = QUuid(s->value("ProjectExplorer/Settings/EnvironmentId").toString());
836 if (d->m_projectExplorerSettings.environmentId.isNull())
837 d->m_projectExplorerSettings.environmentId = QUuid::createUuid();
840 connect(d->m_sessionManagerAction, SIGNAL(triggered()), this, SLOT(showSessionManager()));
841 connect(d->m_newAction, SIGNAL(triggered()), this, SLOT(newProject()));
842 connect(d->m_loadAction, SIGNAL(triggered()), this, SLOT(loadAction()));
843 connect(d->m_buildProjectOnlyAction, SIGNAL(triggered()), this, SLOT(buildProjectOnly()));
844 connect(d->m_buildAction, SIGNAL(triggered()), this, SLOT(buildProject()));
845 connect(d->m_buildActionContextMenu, SIGNAL(triggered()), this, SLOT(buildProjectContextMenu()));
846 connect(d->m_buildSessionAction, SIGNAL(triggered()), this, SLOT(buildSession()));
847 connect(d->m_rebuildProjectOnlyAction, SIGNAL(triggered()), this, SLOT(rebuildProjectOnly()));
848 connect(d->m_rebuildAction, SIGNAL(triggered()), this, SLOT(rebuildProject()));
849 connect(d->m_rebuildActionContextMenu, SIGNAL(triggered()), this, SLOT(rebuildProjectContextMenu()));
850 connect(d->m_rebuildSessionAction, SIGNAL(triggered()), this, SLOT(rebuildSession()));
851 connect(d->m_deployProjectOnlyAction, SIGNAL(triggered()), this, SLOT(deployProjectOnly()));
852 connect(d->m_deployAction, SIGNAL(triggered()), this, SLOT(deployProject()));
853 connect(d->m_deployActionContextMenu, SIGNAL(triggered()), this, SLOT(deployProjectContextMenu()));
854 connect(d->m_deploySessionAction, SIGNAL(triggered()), this, SLOT(deploySession()));
855 connect(d->m_publishAction, SIGNAL(triggered()), this, SLOT(publishProject()));
856 connect(d->m_cleanProjectOnlyAction, SIGNAL(triggered()), this, SLOT(cleanProjectOnly()));
857 connect(d->m_cleanAction, SIGNAL(triggered()), this, SLOT(cleanProject()));
858 connect(d->m_cleanActionContextMenu, SIGNAL(triggered()), this, SLOT(cleanProjectContextMenu()));
859 connect(d->m_cleanSessionAction, SIGNAL(triggered()), this, SLOT(cleanSession()));
860 connect(d->m_runAction, SIGNAL(triggered()), this, SLOT(runProject()));
861 connect(d->m_runActionContextMenu, SIGNAL(triggered()), this, SLOT(runProjectContextMenu()));
862 connect(d->m_cancelBuildAction, SIGNAL(triggered()), this, SLOT(cancelBuild()));
863 connect(d->m_unloadAction, SIGNAL(triggered()), this, SLOT(unloadProject()));
864 connect(d->m_clearSession, SIGNAL(triggered()), this, SLOT(clearSession()));
865 connect(d->m_addNewFileAction, SIGNAL(triggered()), this, SLOT(addNewFile()));
866 connect(d->m_addExistingFilesAction, SIGNAL(triggered()), this, SLOT(addExistingFiles()));
867 connect(d->m_addNewSubprojectAction, SIGNAL(triggered()), this, SLOT(addNewSubproject()));
868 connect(d->m_removeProjectAction, SIGNAL(triggered()), this, SLOT(removeProject()));
869 connect(d->m_openFileAction, SIGNAL(triggered()), this, SLOT(openFile()));
870 connect(d->m_showInGraphicalShell, SIGNAL(triggered()), this, SLOT(showInGraphicalShell()));
871 connect(d->m_openTerminalHere, SIGNAL(triggered()), this, SLOT(openTerminalHere()));
872 connect(d->m_removeFileAction, SIGNAL(triggered()), this, SLOT(removeFile()));
873 connect(d->m_deleteFileAction, SIGNAL(triggered()), this, SLOT(deleteFile()));
874 connect(d->m_renameFileAction, SIGNAL(triggered()), this, SLOT(renameFile()));
875 connect(d->m_setStartupProjectAction, SIGNAL(triggered()), this, SLOT(setStartupProject()));
877 connect(this, SIGNAL(updateRunActions()), this, SLOT(slotUpdateRunActions()));
881 connect(Core::ICore::instance(), SIGNAL(coreAboutToOpen()),
882 this, SLOT(determineSessionToRestoreAtStartup()));
883 connect(Core::ICore::instance(), SIGNAL(coreOpened()), this, SLOT(restoreSession()));
890 ProjectFileFactory *ProjectExplorerPlugin::findProjectFileFactory(const QString &filename) const
893 if (const Core::MimeType mt = Core::ICore::instance()->mimeDatabase()->findByFile(QFileInfo(filename))) {
894 const QString mimeType = mt.type();
895 foreach (ProjectFileFactory *f, d->m_fileFactories)
896 if (f->mimeTypes().contains(mimeType))
899 qWarning("Unable to find project file factory for '%s'", filename.toUtf8().constData());
903 void ProjectExplorerPlugin::loadAction()
906 qDebug() << "ProjectExplorerPlugin::loadAction";
909 QString dir = d->m_lastOpenDirectory;
911 // for your special convenience, we preselect a pro file if it is
913 if (Core::IEditor *editor = Core::EditorManager::instance()->currentEditor()) {
914 if (const Core::IFile *file = editor->file()) {
915 const QString fn = file->fileName();
916 const bool isProject = d->m_profileMimeTypes.contains(file->mimeType());
917 dir = isProject ? fn : QFileInfo(fn).absolutePath();
921 QString filename = QFileDialog::getOpenFileName(0, tr("Load Project"),
923 d->m_projectFilterString);
924 if (filename.isEmpty())
926 if (ProjectFileFactory *pf = findProjectFileFactory(filename))
931 void ProjectExplorerPlugin::unloadProject()
934 qDebug() << "ProjectExplorerPlugin::unloadProject";
936 Core::IFile *fi = d->m_currentProject->file();
938 if (!fi || fi->fileName().isEmpty()) //nothing to save?
941 QList<Core::IFile*> filesToSave;
944 // check the number of modified files
945 int readonlycount = 0;
946 foreach (const Core::IFile *file, filesToSave) {
947 if (file->isReadOnly())
951 bool success = false;
952 if (readonlycount > 0)
953 success = Core::ICore::instance()->fileManager()->saveModifiedFiles(filesToSave).isEmpty();
955 success = Core::ICore::instance()->fileManager()->saveModifiedFilesSilently(filesToSave).isEmpty();
960 addToRecentProjects(fi->fileName(), d->m_currentProject->displayName());
961 d->m_session->removeProject(d->m_currentProject);
965 void ProjectExplorerPlugin::clearSession()
968 qDebug() << "ProjectExplorerPlugin::clearSession";
970 if (!d->m_session->clear())
971 return; // Action has been cancelled
975 void ProjectExplorerPlugin::extensionsInitialized()
977 d->m_fileFactories = ProjectFileFactory::createFactories(&d->m_projectFilterString);
978 foreach (ProjectFileFactory *pf, d->m_fileFactories) {
979 d->m_profileMimeTypes += pf->mimeTypes();
980 addAutoReleasedObject(pf);
982 d->m_buildManager->extensionsInitialized();
985 void ProjectExplorerPlugin::loadCustomWizards()
987 // Add custom wizards, for which other plugins might have registered
989 static bool firstTime = true;
992 foreach(Core::IWizard *cpw, ProjectExplorer::CustomWizard::createWizards())
993 addAutoReleasedObject(cpw);
997 ExtensionSystem::IPlugin::ShutdownFlag ProjectExplorerPlugin::aboutToShutdown()
999 d->m_proWindow->aboutToShutdown(); // disconnect from session
1000 d->m_session->clear();
1001 d->m_projectsMode = 0;
1002 // Attempt to synchronously shutdown all run controls.
1003 // If that fails, fall back to asynchronous shutdown (Debugger run controls
1004 // might shutdown asynchronously).
1005 if (d->m_outputPane->closeTabs(false /* No prompt any more */))
1006 return SynchronousShutdown;
1007 connect(d->m_outputPane, SIGNAL(allRunControlsFinished()),
1008 this, SIGNAL(asynchronousShutdownFinished()));
1009 return AsynchronousShutdown;
1012 void ProjectExplorerPlugin::newProject()
1015 qDebug() << "ProjectExplorerPlugin::newProject";
1017 Core::ICore::instance()->showNewItemDialog(tr("New Project", "Title of dialog"),
1018 Core::IWizard::wizardsOfKind(Core::IWizard::ProjectWizard));
1022 void ProjectExplorerPlugin::showSessionManager()
1025 qDebug() << "ProjectExplorerPlugin::showSessionManager";
1027 if (d->m_session->isDefaultVirgin()) {
1028 // do not save new virgin default sessions
1030 d->m_session->save();
1032 SessionDialog sessionDialog(d->m_session);
1033 sessionDialog.setAutoLoadSession(d->m_projectExplorerSettings.autorestoreLastSession);
1034 sessionDialog.exec();
1035 d->m_projectExplorerSettings.autorestoreLastSession = sessionDialog.autoLoadSession();
1039 Core::ModeManager *modeManager = Core::ModeManager::instance();
1040 Core::IMode *welcomeMode = modeManager->mode(Core::Constants::MODE_WELCOME);
1041 if (modeManager->currentMode() == welcomeMode)
1042 updateWelcomePage();
1045 void ProjectExplorerPlugin::setStartupProject(Project *project)
1048 qDebug() << "ProjectExplorerPlugin::setStartupProject";
1052 d->m_session->setStartupProject(project);
1056 void ProjectExplorerPlugin::publishProject()
1058 const Project * const project = d->m_session->startupProject();
1059 QTC_ASSERT(project, return);
1060 PublishingWizardSelectionDialog selectionDialog(project);
1061 if (selectionDialog.exec() == QDialog::Accepted) {
1062 QWizard * const publishingWizard
1063 = selectionDialog.createSelectedWizard();
1064 publishingWizard->exec();
1065 delete publishingWizard;
1069 void ProjectExplorerPlugin::savePersistentSettings()
1072 qDebug()<<"ProjectExplorerPlugin::savePersistentSettings()";
1074 foreach (Project *pro, d->m_session->projects())
1075 pro->saveSettings();
1077 if (d->m_session->isDefaultVirgin()) {
1078 // do not save new virgin default sessions
1080 d->m_session->save();
1083 QSettings *s = Core::ICore::instance()->settings();
1085 s->setValue("ProjectExplorer/StartupSession", d->m_session->currentSession());
1086 s->remove("ProjectExplorer/RecentProjects/Files");
1088 QStringList fileNames;
1089 QStringList displayNames;
1090 QList<QPair<QString, QString> >::const_iterator it, end;
1091 end = d->m_recentProjects.constEnd();
1092 for (it = d->m_recentProjects.constBegin(); it != end; ++it) {
1093 fileNames << (*it).first;
1094 displayNames << (*it).second;
1097 s->setValue("ProjectExplorer/RecentProjects/FileNames", fileNames);
1098 s->setValue("ProjectExplorer/RecentProjects/DisplayNames", displayNames);
1100 s->setValue("ProjectExplorer/Settings/BuildBeforeDeploy", d->m_projectExplorerSettings.buildBeforeDeploy);
1101 s->setValue("ProjectExplorer/Settings/DeployBeforeRun", d->m_projectExplorerSettings.deployBeforeRun);
1102 s->setValue("ProjectExplorer/Settings/SaveBeforeBuild", d->m_projectExplorerSettings.saveBeforeBuild);
1103 s->setValue("ProjectExplorer/Settings/ShowCompilerOutput", d->m_projectExplorerSettings.showCompilerOutput);
1104 s->setValue("ProjectExplorer/Settings/ShowRunOutput", d->m_projectExplorerSettings.showRunOutput);
1105 s->setValue("ProjectExplorer/Settings/CleanOldAppOutput", d->m_projectExplorerSettings.cleanOldAppOutput);
1106 s->setValue("ProjectExplorer/Settings/WrapAppOutput", d->m_projectExplorerSettings.wrapAppOutput);
1107 s->setValue("ProjectExplorer/Settings/UseJom", d->m_projectExplorerSettings.useJom);
1108 s->setValue("ProjectExplorer/Settings/AutoRestoreLastSession", d->m_projectExplorerSettings.autorestoreLastSession);
1109 s->setValue("ProjectExplorer/Settings/EnvironmentId", d->m_projectExplorerSettings.environmentId.toString());
1113 bool ProjectExplorerPlugin::openProject(const QString &fileName)
1116 qDebug() << "ProjectExplorerPlugin::openProject";
1118 QList<Project *> list = openProjects(QStringList() << fileName);
1119 if (!list.isEmpty()) {
1120 addToRecentProjects(fileName, list.first()->displayName());
1126 static inline QList<IProjectManager*> allProjectManagers()
1128 ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
1129 return pm->getObjects<IProjectManager>();
1132 QList<Project *> ProjectExplorerPlugin::openProjects(const QStringList &fileNames)
1135 qDebug() << "ProjectExplorerPlugin - opening projects " << fileNames;
1137 const QList<IProjectManager*> projectManagers = allProjectManagers();
1139 QList<Project*> openedPro;
1140 foreach (const QString &fileName, fileNames) {
1141 if (const Core::MimeType mt = Core::ICore::instance()->mimeDatabase()->findByFile(QFileInfo(fileName))) {
1142 foreach (IProjectManager *manager, projectManagers) {
1143 if (manager->mimeType() == mt.type()) {
1144 if (Project *pro = manager->openProject(fileName)) {
1145 if (pro->restoreSettings()) {
1146 connect(pro, SIGNAL(fileListChanged()), this, SIGNAL(fileListChanged()));
1147 d->m_session->addProject(pro);
1148 // Make sure we always have a current project / node
1149 if (!d->m_currentProject && !openedPro.isEmpty())
1150 setCurrentNode(pro->rootProjectNode());
1156 d->m_session->reportProjectLoadingProgress();
1164 if (openedPro.isEmpty()) {
1165 qDebug() << "ProjectExplorerPlugin - Could not open any projects!";
1167 Core::ModeManager::instance()->activateMode(Core::Constants::MODE_EDIT);
1173 Project *ProjectExplorerPlugin::currentProject() const
1176 if (d->m_currentProject)
1177 qDebug() << "ProjectExplorerPlugin::currentProject returns " << d->m_currentProject->displayName();
1179 qDebug() << "ProjectExplorerPlugin::currentProject returns 0";
1181 return d->m_currentProject;
1184 Node *ProjectExplorerPlugin::currentNode() const
1186 return d->m_currentNode;
1189 void ProjectExplorerPlugin::setCurrentFile(Project *project, const QString &filePath)
1191 setCurrent(project, filePath, 0);
1194 void ProjectExplorerPlugin::setCurrentFile(const QString &filePath)
1196 Project *project = d->m_session->projectForFile(filePath);
1197 // If the file is not in any project, stay with the current project
1198 // e.g. on opening a git diff buffer, git log buffer, we don't change the project
1199 // I'm not 100% sure this is correct
1201 project = d->m_currentProject;
1202 setCurrent(project, filePath, 0);
1205 void ProjectExplorerPlugin::setCurrentNode(Node *node)
1207 setCurrent(d->m_session->projectForNode(node), QString(), node);
1210 SessionManager *ProjectExplorerPlugin::session() const
1212 return d->m_session;
1215 Project *ProjectExplorerPlugin::startupProject() const
1218 qDebug() << "ProjectExplorerPlugin::startupProject";
1220 return d->m_session->startupProject();
1223 void ProjectExplorerPlugin::updateWelcomePage()
1225 ProjectWelcomePageWidget::WelcomePageData welcomePageData;
1226 welcomePageData.sessionList = d->m_session->sessions();
1227 welcomePageData.activeSession = d->m_session->activeSession();
1228 welcomePageData.previousSession = d->m_session->lastSession();
1229 welcomePageData.projectList = d->m_recentProjects;
1230 d->m_welcomePage->setWelcomePageData(welcomePageData);
1233 void ProjectExplorerPlugin::currentModeChanged(Core::IMode *mode, Core::IMode *oldMode)
1235 if (mode && mode->id() == Core::Id(Core::Constants::MODE_WELCOME))
1236 updateWelcomePage();
1237 if (oldMode == d->m_projectsMode)
1238 savePersistentSettings();
1241 void ProjectExplorerPlugin::determineSessionToRestoreAtStartup()
1243 QStringList arguments = ExtensionSystem::PluginManager::instance()->arguments();
1244 if (arguments.contains("-lastsession")
1245 || d->m_projectExplorerSettings.autorestoreLastSession) {
1246 d->m_sessionToRestoreAtStartup = d->m_session->lastSession();
1248 QStringList sessions = d->m_session->sessions();
1249 // We have command line arguments, try to find a session in them
1250 // Default to no session loading
1251 foreach (const QString &arg, arguments) {
1252 if (sessions.contains(arg)) {
1254 d->m_sessionToRestoreAtStartup = arg;
1260 if (!d->m_sessionToRestoreAtStartup.isNull())
1261 Core::ICore::instance()->modeManager()->activateMode(Core::Constants::MODE_EDIT);
1265 \fn void ProjectExplorerPlugin::restoreSession()
1267 This method is connected to the ICore::coreOpened signal. If
1268 there was no session explicitly loaded, it creates an empty new
1269 default session and puts the list of recent projects and sessions
1270 onto the welcome page.
1272 void ProjectExplorerPlugin::restoreSession()
1275 qDebug() << "ProjectExplorerPlugin::restoreSession";
1277 // We have command line arguments, try to find a session in them
1278 QStringList arguments = ExtensionSystem::PluginManager::instance()->arguments();
1279 arguments.removeOne(d->m_sessionToRestoreAtStartup);
1281 // Restore latest session or what was passed on the command line
1282 if (d->m_sessionToRestoreAtStartup.isEmpty()) {
1283 d->m_session->createAndLoadNewDefaultSession();
1285 d->m_session->loadSession(d->m_sessionToRestoreAtStartup);
1288 // update welcome page
1289 Core::ModeManager *modeManager = Core::ModeManager::instance();
1290 connect(modeManager, SIGNAL(currentModeChanged(Core::IMode*, Core::IMode*)),
1291 this, SLOT(currentModeChanged(Core::IMode*, Core::IMode*)));
1292 connect(d->m_welcomePage, SIGNAL(requestSession(QString)), this, SLOT(loadSession(QString)));
1293 connect(d->m_welcomePage, SIGNAL(requestProject(QString)), this, SLOT(loadProject(QString)));
1295 QStringList combinedList;
1296 // Converts "filename" "+45" or "filename" ":23"
1297 // into "filename+45" and "filename:23"
1298 foreach (const QString &str, arguments) {
1299 if (!combinedList.isEmpty() && (str.startsWith("+") || str.startsWith(":"))) {
1300 combinedList.last().append(str);
1302 combinedList << str;
1306 Core::ICore::instance()->openFiles(combinedList, Core::ICore::OpenFilesFlags(Core::ICore::CanContainLineNumbers | Core::ICore::SwitchMode));
1311 void ProjectExplorerPlugin::loadSession(const QString &session)
1314 qDebug() << "ProjectExplorerPlugin::loadSession" << session;
1315 d->m_session->loadSession(session);
1319 void ProjectExplorerPlugin::showContextMenu(const QPoint &globalPos, Node *node)
1321 QMenu *contextMenu = 0;
1324 node = d->m_session->sessionNode();
1326 if (node->nodeType() != SessionNodeType) {
1327 Project *project = d->m_session->projectForNode(node);
1328 setCurrentNode(node);
1330 emit aboutToShowContextMenu(project, node);
1331 switch (node->nodeType()) {
1332 case ProjectNodeType:
1333 if (node->parentFolderNode() == d->m_session->sessionNode())
1334 contextMenu = d->m_projectMenu;
1336 contextMenu = d->m_subProjectMenu;
1338 case FolderNodeType:
1339 contextMenu = d->m_folderMenu;
1342 populateOpenWithMenu();
1343 contextMenu = d->m_fileMenu;
1346 qWarning("ProjectExplorerPlugin::showContextMenu - Missing handler for node type");
1348 } else { // session item
1349 emit aboutToShowContextMenu(0, node);
1351 contextMenu = d->m_sessionContextMenu;
1354 updateContextMenuActions();
1355 if (contextMenu && contextMenu->actions().count() > 0) {
1356 contextMenu->popup(globalPos);
1360 BuildManager *ProjectExplorerPlugin::buildManager() const
1362 return d->m_buildManager;
1365 void ProjectExplorerPlugin::buildStateChanged(Project * pro)
1368 qDebug() << "buildStateChanged";
1369 qDebug() << pro->file()->fileName() << "isBuilding()" << d->m_buildManager->isBuilding(pro);
1375 void ProjectExplorerPlugin::executeRunConfiguration(RunConfiguration *runConfiguration, const QString &runMode)
1377 if (IRunControlFactory *runControlFactory = findRunControlFactory(runConfiguration, runMode)) {
1378 emit aboutToExecuteProject(runConfiguration->target()->project(), runMode);
1380 RunControl *control = runControlFactory->create(runConfiguration, runMode);
1383 startRunControl(control, runMode);
1387 void ProjectExplorerPlugin::startRunControl(RunControl *runControl, const QString &runMode)
1389 d->m_outputPane->createNewOutputWindow(runControl);
1390 if (runMode == ProjectExplorer::Constants::RUNMODE && d->m_projectExplorerSettings.showRunOutput)
1391 d->m_outputPane->popup(false);
1392 d->m_outputPane->showTabFor(runControl);
1393 connect(runControl, SIGNAL(finished()), this, SLOT(runControlFinished()));
1394 runControl->start();
1395 emit updateRunActions();
1398 void ProjectExplorerPlugin::buildQueueFinished(bool success)
1401 qDebug() << "buildQueueFinished()" << success;
1405 if (success && d->m_delayedRunConfiguration) {
1406 executeRunConfiguration(d->m_delayedRunConfiguration, d->m_runMode);
1408 if (d->m_buildManager->tasksAvailable())
1409 d->m_buildManager->showTaskWindow();
1411 d->m_delayedRunConfiguration = 0;
1412 d->m_runMode.clear();
1415 void ProjectExplorerPlugin::setCurrent(Project *project, QString filePath, Node *node)
1418 qDebug() << "ProjectExplorer - setting path to " << (node ? node->path() : filePath)
1419 << " and project to " << (project ? project->displayName() : "0");
1422 filePath = node->path();
1424 node = d->m_session->nodeForFile(filePath, project);
1426 Core::ICore *core = Core::ICore::instance();
1428 bool projectChanged = false;
1429 if (d->m_currentProject != project) {
1430 Core::Context oldContext;
1431 Core::Context newContext;
1433 if (d->m_currentProject) {
1434 oldContext.add(d->m_currentProject->projectManager()->projectContext());
1435 oldContext.add(d->m_currentProject->projectManager()->projectLanguage());
1438 newContext.add(project->projectManager()->projectContext());
1439 newContext.add(project->projectManager()->projectLanguage());
1442 core->updateAdditionalContexts(oldContext, newContext);
1444 d->m_currentProject = project;
1446 projectChanged = true;
1449 if (projectChanged || d->m_currentNode != node) {
1450 d->m_currentNode = node;
1452 qDebug() << "ProjectExplorer - currentNodeChanged(" << (node ? node->path() : "0") << ", " << (project ? project->displayName() : "0") << ")";
1453 emit currentNodeChanged(d->m_currentNode, project);
1454 updateContextMenuActions();
1456 if (projectChanged) {
1458 qDebug() << "ProjectExplorer - currentProjectChanged(" << (project ? project->displayName() : "0") << ")";
1459 emit currentProjectChanged(project);
1463 core->fileManager()->setCurrentFile(filePath);
1466 void ProjectExplorerPlugin::updateActions()
1469 qDebug() << "ProjectExplorerPlugin::updateActions";
1471 Project *project = startupProject();
1472 bool enableBuildActions = project
1473 && ! (d->m_buildManager->isBuilding(project))
1474 && hasBuildSettings(project);
1476 bool enableBuildActionsContextMenu = d->m_currentProject
1477 && ! (d->m_buildManager->isBuilding(d->m_currentProject))
1478 && hasBuildSettings(d->m_currentProject);
1480 bool hasProjects = !d->m_session->projects().isEmpty();
1481 bool building = d->m_buildManager->isBuilding();
1482 QString projectName = project ? project->displayName() : QString();
1483 QString projectNameContextMenu = d->m_currentProject ? d->m_currentProject->displayName() : QString();
1486 qDebug() << "BuildManager::isBuilding()" << building;
1488 d->m_unloadAction->setParameter(projectNameContextMenu);
1490 d->m_buildAction->setParameter(projectName);
1491 d->m_rebuildAction->setParameter(projectName);
1492 d->m_cleanAction->setParameter(projectName);
1494 d->m_buildAction->setEnabled(enableBuildActions);
1495 d->m_rebuildAction->setEnabled(enableBuildActions);
1496 d->m_cleanAction->setEnabled(enableBuildActions);
1498 d->m_buildActionContextMenu->setParameter(projectNameContextMenu);
1499 d->m_rebuildActionContextMenu->setParameter(projectNameContextMenu);
1500 d->m_cleanActionContextMenu->setParameter(projectNameContextMenu);
1502 d->m_buildActionContextMenu->setEnabled(enableBuildActionsContextMenu);
1503 d->m_rebuildActionContextMenu->setEnabled(enableBuildActionsContextMenu);
1504 d->m_cleanActionContextMenu->setEnabled(enableBuildActionsContextMenu);
1506 d->m_buildProjectOnlyAction->setEnabled(enableBuildActions);
1507 d->m_rebuildProjectOnlyAction->setEnabled(enableBuildActions);
1508 d->m_cleanProjectOnlyAction->setEnabled(enableBuildActions);
1510 d->m_clearSession->setEnabled(hasProjects && !building);
1511 d->m_buildSessionAction->setEnabled(hasProjects && !building);
1512 d->m_rebuildSessionAction->setEnabled(hasProjects && !building);
1513 d->m_cleanSessionAction->setEnabled(hasProjects && !building);
1514 d->m_cancelBuildAction->setEnabled(building);
1516 d->m_publishAction->setEnabled(hasProjects);
1518 d->m_projectSelectorAction->setEnabled(!session()->projects().isEmpty());
1519 d->m_projectSelectorActionMenu->setEnabled(!session()->projects().isEmpty());
1521 updateDeployActions();
1524 // NBS TODO check projectOrder()
1525 // what we want here is all the projects pro depends on
1526 QStringList ProjectExplorerPlugin::allFilesWithDependencies(Project *pro)
1529 qDebug() << "ProjectExplorerPlugin::allFilesWithDependencies(" << pro->file()->fileName() << ")";
1531 QStringList filesToSave;
1532 foreach (Project *p, d->m_session->projectOrder(pro)) {
1533 FindAllFilesVisitor filesVisitor;
1534 p->rootProjectNode()->accept(&filesVisitor);
1535 filesToSave << filesVisitor.filePaths();
1541 bool ProjectExplorerPlugin::saveModifiedFiles()
1544 qDebug() << "ProjectExplorerPlugin::saveModifiedFiles";
1546 QList<Core::IFile *> filesToSave = Core::ICore::instance()->fileManager()->modifiedFiles();
1547 if (!filesToSave.isEmpty()) {
1548 if (d->m_projectExplorerSettings.saveBeforeBuild) {
1549 Core::ICore::instance()->fileManager()->saveModifiedFilesSilently(filesToSave);
1551 bool cancelled = false;
1552 bool alwaysSave = false;
1554 Core::FileManager *fm = Core::ICore::instance()->fileManager();
1555 fm->saveModifiedFiles(filesToSave, &cancelled, QString(),
1556 tr("Always save files before build"), &alwaysSave);
1561 d->m_projectExplorerSettings.saveBeforeBuild = true;
1567 //NBS handle case where there is no activeBuildConfiguration
1568 // because someone delete all build configurations
1570 void ProjectExplorerPlugin::deploy(QList<Project *> projects)
1573 if (d->m_projectExplorerSettings.buildBeforeDeploy)
1574 steps << Constants::BUILDSTEPS_BUILD;
1575 steps << Constants::BUILDSTEPS_DEPLOY;
1576 queue(projects, steps);
1579 int ProjectExplorerPlugin::queue(QList<Project *> projects, QStringList stepIds)
1582 QStringList projectNames;
1583 foreach (Project *p, projects)
1584 projectNames << p->displayName();
1585 qDebug() << "Building" << stepIds << "for projects" << projectNames;
1588 if (!saveModifiedFiles())
1591 QList<BuildStepList *> stepLists;
1592 foreach (Project *pro, projects) {
1593 if (!pro || !pro->activeTarget())
1595 foreach (const QString id, stepIds) {
1596 BuildStepList *bsl = 0;
1597 if (id == Core::Id(Constants::BUILDSTEPS_DEPLOY)
1598 && pro->activeTarget()->activeDeployConfiguration())
1599 bsl = pro->activeTarget()->activeDeployConfiguration()->stepList();
1600 else if (pro->activeTarget()->activeBuildConfiguration())
1601 bsl = pro->activeTarget()->activeBuildConfiguration()->stepList(id);
1603 if (!bsl || bsl->isEmpty())
1609 if (stepLists.isEmpty())
1611 if (!d->m_buildManager->buildLists(stepLists))
1613 return stepLists.count();
1616 void ProjectExplorerPlugin::buildProjectOnly()
1618 queue(QList<Project *>() << session()->startupProject(), QStringList() << Constants::BUILDSTEPS_BUILD);
1621 void ProjectExplorerPlugin::buildProject()
1623 queue(d->m_session->projectOrder(session()->startupProject()),
1624 QStringList() << Constants::BUILDSTEPS_BUILD);
1627 void ProjectExplorerPlugin::buildProjectContextMenu()
1629 queue(d->m_session->projectOrder(d->m_currentProject),
1630 QStringList() << Constants::BUILDSTEPS_BUILD);
1633 void ProjectExplorerPlugin::buildSession()
1635 queue(d->m_session->projectOrder(),
1636 QStringList() << Constants::BUILDSTEPS_BUILD);
1639 void ProjectExplorerPlugin::rebuildProjectOnly()
1641 queue(QList<Project *>() << session()->startupProject(),
1642 QStringList() << Constants::BUILDSTEPS_CLEAN << Constants::BUILDSTEPS_BUILD);
1645 void ProjectExplorerPlugin::rebuildProject()
1647 queue(d->m_session->projectOrder(session()->startupProject()),
1648 QStringList() << Constants::BUILDSTEPS_CLEAN << Constants::BUILDSTEPS_BUILD);
1651 void ProjectExplorerPlugin::rebuildProjectContextMenu()
1653 queue(d->m_session->projectOrder(d->m_currentProject),
1654 QStringList() << Constants::BUILDSTEPS_CLEAN << Constants::BUILDSTEPS_BUILD);
1657 void ProjectExplorerPlugin::rebuildSession()
1659 queue(d->m_session->projectOrder(),
1660 QStringList() << Constants::BUILDSTEPS_CLEAN << Constants::BUILDSTEPS_BUILD);
1663 void ProjectExplorerPlugin::deployProjectOnly()
1665 deploy(QList<Project *>() << session()->startupProject());
1668 void ProjectExplorerPlugin::deployProject()
1670 deploy(d->m_session->projectOrder(session()->startupProject()));
1673 void ProjectExplorerPlugin::deployProjectContextMenu()
1675 deploy(d->m_session->projectOrder(d->m_currentProject));
1678 void ProjectExplorerPlugin::deploySession()
1680 deploy(d->m_session->projectOrder());
1683 void ProjectExplorerPlugin::cleanProjectOnly()
1685 queue(QList<Project *>() << session()->startupProject(),
1686 QStringList() << Constants::BUILDSTEPS_CLEAN << Constants::BUILDSTEPS_CLEAN);
1689 void ProjectExplorerPlugin::cleanProject()
1691 queue(d->m_session->projectOrder(session()->startupProject()),
1692 QStringList() << Constants::BUILDSTEPS_CLEAN << Constants::BUILDSTEPS_CLEAN);
1695 void ProjectExplorerPlugin::cleanProjectContextMenu()
1697 queue(d->m_session->projectOrder(d->m_currentProject),
1698 QStringList() << Constants::BUILDSTEPS_CLEAN << Constants::BUILDSTEPS_CLEAN);
1701 void ProjectExplorerPlugin::cleanSession()
1703 queue(d->m_session->projectOrder(),
1704 QStringList() << Constants::BUILDSTEPS_CLEAN << Constants::BUILDSTEPS_CLEAN);
1707 void ProjectExplorerPlugin::runProject()
1709 runProject(startupProject(), ProjectExplorer::Constants::RUNMODE);
1712 void ProjectExplorerPlugin::runProjectContextMenu()
1714 runProject(d->m_currentProject, ProjectExplorer::Constants::RUNMODE);
1717 bool ProjectExplorerPlugin::hasBuildSettings(Project *pro)
1719 const QList<Project *> & projects = d->m_session->projectOrder(pro);
1720 foreach(Project *project, projects)
1721 if (project->activeTarget()->activeBuildConfiguration())
1726 bool ProjectExplorerPlugin::coreAboutToClose()
1728 if (d->m_buildManager->isBuilding()) {
1730 QPushButton *closeAnyway = box.addButton(tr("Cancel Build && Close"), QMessageBox::AcceptRole);
1731 QPushButton *cancelClose = box.addButton(tr("Do Not Close"), QMessageBox::RejectRole);
1732 box.setDefaultButton(cancelClose);
1733 box.setWindowTitle(tr("Close Qt Creator?"));
1734 box.setText(tr("A project is currently being built."));
1735 box.setInformativeText(tr("Do you want to cancel the build process and close Qt Creator anyway?"));
1737 if (box.clickedButton() != closeAnyway)
1740 if (!d->m_outputPane->aboutToClose())
1745 bool ProjectExplorerPlugin::hasDeploySettings(Project *pro)
1747 const QList<Project *> & projects = d->m_session->projectOrder(pro);
1748 foreach(Project *project, projects)
1749 if (project->activeTarget()->activeDeployConfiguration() &&
1750 !project->activeTarget()->activeDeployConfiguration()->stepList()->isEmpty())
1755 void ProjectExplorerPlugin::runProject(Project *pro, QString mode)
1760 if (!pro->activeTarget()->activeRunConfiguration()->isEnabled())
1763 QStringList stepIds;
1764 if (d->m_projectExplorerSettings.deployBeforeRun) {
1765 if (d->m_projectExplorerSettings.buildBeforeDeploy)
1766 stepIds << Constants::BUILDSTEPS_BUILD;
1767 stepIds << Constants::BUILDSTEPS_DEPLOY;
1769 const QList<Project *> &projects = d->m_session->projectOrder(pro);
1770 int queueCount = queue(projects, stepIds);
1772 if (queueCount < 0) // something went wrong
1775 if (queueCount > 0) {
1776 // delay running till after our queued steps were processed
1777 d->m_runMode = mode;
1778 d->m_delayedRunConfiguration = pro->activeTarget()->activeRunConfiguration();
1780 executeRunConfiguration(pro->activeTarget()->activeRunConfiguration(), mode);
1782 emit updateRunActions();
1785 void ProjectExplorerPlugin::runControlFinished()
1787 emit updateRunActions();
1790 void ProjectExplorerPlugin::startupProjectChanged()
1792 static QPointer<Project> previousStartupProject = 0;
1793 Project *project = startupProject();
1794 if (project == previousStartupProject)
1797 if (d->m_projectsMode)
1798 d->m_projectsMode->setEnabled(project);
1800 if (previousStartupProject) {
1801 disconnect(previousStartupProject, SIGNAL(activeTargetChanged(ProjectExplorer::Target*)),
1802 this, SLOT(activeTargetChanged()));
1805 previousStartupProject = project;
1808 connect(project, SIGNAL(activeTargetChanged(ProjectExplorer::Target*)),
1809 this, SLOT(activeTargetChanged()));
1812 activeTargetChanged();
1814 emit updateRunActions();
1817 void ProjectExplorerPlugin::activeTargetChanged()
1819 static QPointer<Target> previousTarget = 0;
1821 if (startupProject())
1822 target = startupProject()->activeTarget();
1823 if (target == previousTarget)
1826 if (previousTarget) {
1827 disconnect(previousTarget, SIGNAL(activeRunConfigurationChanged(ProjectExplorer::RunConfiguration*)),
1828 this, SLOT(activeRunConfigurationChanged()));
1830 previousTarget = target;
1832 connect(target, SIGNAL(activeRunConfigurationChanged(ProjectExplorer::RunConfiguration*)),
1833 this, SLOT(activeRunConfigurationChanged()));
1836 updateDeployActions();
1837 activeRunConfigurationChanged();
1840 void ProjectExplorerPlugin::activeRunConfigurationChanged()
1842 static QPointer<RunConfiguration> previousRunConfiguration = 0;
1843 RunConfiguration *rc = 0;
1844 if (startupProject() && startupProject()->activeTarget())
1845 rc = startupProject()->activeTarget()->activeRunConfiguration();
1846 if (rc == previousRunConfiguration)
1848 if (previousRunConfiguration) {
1849 disconnect(previousRunConfiguration, SIGNAL(isEnabledChanged(bool)),
1850 this, SIGNAL(updateRunActions()));
1852 previousRunConfiguration = rc;
1854 connect(rc, SIGNAL(isEnabledChanged(bool)),
1855 this, SIGNAL(updateRunActions()));
1857 emit updateRunActions();
1860 // NBS TODO implement more than one runner
1861 IRunControlFactory *ProjectExplorerPlugin::findRunControlFactory(RunConfiguration *config, const QString &mode)
1863 ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
1864 const QList<IRunControlFactory *> factories = pm->getObjects<IRunControlFactory>();
1865 foreach (IRunControlFactory *f, factories)
1866 if (f->canRun(config, mode))
1871 void ProjectExplorerPlugin::updateDeployActions()
1873 Project *project = startupProject();
1875 bool enableDeployActions = project
1876 && ! (d->m_buildManager->isBuilding(project))
1877 && hasDeploySettings(project);
1878 bool enableDeployActionsContextMenu = d->m_currentProject
1879 && ! (d->m_buildManager->isBuilding(d->m_currentProject))
1880 && hasDeploySettings(d->m_currentProject);
1882 const QString projectName = project ? project->displayName() : QString();
1883 const QString projectNameContextMenu = d->m_currentProject ? d->m_currentProject->displayName() : QString();
1884 bool hasProjects = !d->m_session->projects().isEmpty();
1885 bool building = d->m_buildManager->isBuilding();
1887 d->m_deployAction->setParameter(projectName);
1888 d->m_deployAction->setEnabled(enableDeployActions);
1890 d->m_deployActionContextMenu->setParameter(projectNameContextMenu);
1891 d->m_deployActionContextMenu->setEnabled(enableDeployActionsContextMenu);
1893 d->m_deployProjectOnlyAction->setEnabled(enableDeployActions);
1895 d->m_deploySessionAction->setEnabled(hasProjects && !building);
1897 emit updateRunActions();
1900 bool ProjectExplorerPlugin::canRun(Project *project, const QString &runMode)
1903 !project->activeTarget() ||
1904 !project->activeTarget()->activeRunConfiguration()) {
1907 RunConfiguration *activeRC = project->activeTarget()->activeRunConfiguration();
1909 bool canRun = findRunControlFactory(activeRC, runMode)
1910 && activeRC->isEnabled();
1911 const bool building = d->m_buildManager->isBuilding();
1912 return (canRun && !building);
1915 void ProjectExplorerPlugin::slotUpdateRunActions()
1917 Project *project = startupProject();
1918 d->m_runAction->setEnabled(canRun(project, ProjectExplorer::Constants::RUNMODE));
1921 void ProjectExplorerPlugin::cancelBuild()
1924 qDebug() << "ProjectExplorerPlugin::cancelBuild";
1926 if (d->m_buildManager->isBuilding())
1927 d->m_buildManager->cancel();
1930 void ProjectExplorerPlugin::addToRecentProjects(const QString &fileName, const QString &displayName)
1933 qDebug() << "ProjectExplorerPlugin::addToRecentProjects(" << fileName << ")";
1935 if (fileName.isEmpty())
1937 QString prettyFileName(QDir::toNativeSeparators(fileName));
1939 QList<QPair<QString, QString> >::iterator it;
1940 for(it = d->m_recentProjects.begin(); it != d->m_recentProjects.end();)
1941 if ((*it).first == prettyFileName)
1942 it = d->m_recentProjects.erase(it);
1946 if (d->m_recentProjects.count() > d->m_maxRecentProjects)
1947 d->m_recentProjects.removeLast();
1948 d->m_recentProjects.prepend(qMakePair(prettyFileName, displayName));
1949 QFileInfo fi(prettyFileName);
1950 d->m_lastOpenDirectory = fi.absolutePath();
1953 void ProjectExplorerPlugin::updateRecentProjectMenu()
1955 typedef QList<QPair<QString, QString> >::const_iterator StringPairListConstIterator;
1957 qDebug() << "ProjectExplorerPlugin::updateRecentProjectMenu";
1959 Core::ActionContainer *aci =
1960 Core::ICore::instance()->actionManager()->actionContainer(Constants::M_RECENTPROJECTS);
1961 QMenu *menu = aci->menu();
1964 menu->setEnabled(!d->m_recentProjects.isEmpty());
1966 //projects (ignore sessions, they used to be in this list)
1967 const StringPairListConstIterator end = d->m_recentProjects.constEnd();
1968 for (StringPairListConstIterator it = d->m_recentProjects.constBegin(); it != end; ++it) {
1969 const QPair<QString, QString> &s = *it;
1970 if (s.first.endsWith(QLatin1String(".qws")))
1972 QAction *action = menu->addAction(Utils::withTildeHomePath(s.first));
1973 action->setData(s.first);
1974 connect(action, SIGNAL(triggered()), this, SLOT(openRecentProject()));
1978 void ProjectExplorerPlugin::openRecentProject()
1981 qDebug() << "ProjectExplorerPlugin::openRecentProject()";
1983 QAction *a = qobject_cast<QAction*>(sender());
1986 QString fileName = a->data().toString();
1987 if (!fileName.isEmpty())
1988 openProject(fileName);
1991 void ProjectExplorerPlugin::invalidateProject(Project *project)
1994 qDebug() << "ProjectExplorerPlugin::invalidateProject" << project->displayName();
1995 if (d->m_currentProject == project) {
1997 // Workaround for a bug in QItemSelectionModel
1998 // - currentChanged etc are not emitted if the
1999 // item is removed from the underlying data model
2001 setCurrent(0, QString(), 0);
2004 disconnect(project, SIGNAL(fileListChanged()), this, SIGNAL(fileListChanged()));
2008 void ProjectExplorerPlugin::updateContextMenuActions()
2010 d->m_addExistingFilesAction->setEnabled(false);
2011 d->m_addNewFileAction->setEnabled(false);
2012 d->m_addNewSubprojectAction->setEnabled(false);
2013 d->m_removeFileAction->setEnabled(false);
2014 d->m_deleteFileAction->setEnabled(false);
2015 d->m_renameFileAction->setEnabled(false);
2017 d->m_addExistingFilesAction->setVisible(true);
2018 d->m_removeFileAction->setVisible(true);
2019 d->m_deleteFileAction->setVisible(true);
2021 if (d->m_currentNode && d->m_currentNode->projectNode()) {
2022 QList<ProjectNode::ProjectAction> actions =
2023 d->m_currentNode->projectNode()->supportedActions(d->m_currentNode);
2025 if (qobject_cast<FolderNode*>(d->m_currentNode)) {
2026 d->m_addNewFileAction->setEnabled(actions.contains(ProjectNode::AddNewFile));
2027 d->m_addNewSubprojectAction->setEnabled(d->m_currentNode->nodeType() == ProjectNodeType
2028 && actions.contains(ProjectNode::AddSubProject));
2029 d->m_addExistingFilesAction->setEnabled(actions.contains(ProjectNode::AddExistingFile));
2030 d->m_renameFileAction->setEnabled(actions.contains(ProjectNode::Rename));
2031 } else if (qobject_cast<FileNode*>(d->m_currentNode)) {
2032 // Enable and show remove / delete in magic ways:
2033 // If both are disabled show Remove
2034 // If both are enabled show both (can't happen atm)
2035 // If only removeFile is enabled only show it
2036 // If only deleteFile is enable only show it
2037 bool enableRemove = actions.contains(ProjectNode::RemoveFile);
2038 d->m_removeFileAction->setEnabled(enableRemove);
2039 bool enableDelete = actions.contains(ProjectNode::EraseFile);
2040 d->m_deleteFileAction->setEnabled(enableDelete);
2041 d->m_deleteFileAction->setVisible(enableDelete);
2043 d->m_removeFileAction->setVisible(!enableDelete || enableRemove);
2044 d->m_renameFileAction->setEnabled(actions.contains(ProjectNode::Rename));
2049 QString ProjectExplorerPlugin::directoryFor(Node *node)
2051 QString path = node->path();
2053 FolderNode *folder = qobject_cast<FolderNode *>(node);
2054 if (path.contains("#") && folder) {
2055 // Virtual Folder case
2056 // We figure out a commonPath from the subfolders
2058 foreach (FolderNode *f, folder->subFolderNodes())
2059 list << f->path() + "/";
2061 location = path.left(path.indexOf('#'));
2063 location = Utils::commonPath(list);
2066 location = (fi.isDir() ? fi.absoluteFilePath() : fi.absolutePath());
2071 void ProjectExplorerPlugin::addNewFile()
2073 QTC_ASSERT(d->m_currentNode, return)
2074 QString location = directoryFor(d->m_currentNode);
2076 Core::ICore::instance()->showNewItemDialog(tr("New File", "Title of dialog"),
2077 Core::IWizard::wizardsOfKind(Core::IWizard::FileWizard)
2078 + Core::IWizard::wizardsOfKind(Core::IWizard::ClassWizard),
2082 void ProjectExplorerPlugin::addNewSubproject()
2084 QTC_ASSERT(d->m_currentNode, return)
2085 QString location = directoryFor(d->m_currentNode);
2087 if (d->m_currentNode->nodeType() == ProjectNodeType
2088 && d->m_currentNode->projectNode()->supportedActions(
2089 d->m_currentNode->projectNode()).contains(ProjectNode::AddSubProject)) {
2090 Core::ICore::instance()->showNewItemDialog(tr("New Subproject", "Title of dialog"),
2091 Core::IWizard::wizardsOfKind(Core::IWizard::ProjectWizard),
2096 void ProjectExplorerPlugin::addExistingFiles()
2098 QTC_ASSERT(d->m_currentNode, return)
2100 ProjectNode *projectNode = qobject_cast<ProjectNode*>(d->m_currentNode->projectNode());
2101 Core::ICore *core = Core::ICore::instance();
2102 const QString dir = directoryFor(d->m_currentNode);
2103 QStringList fileNames = QFileDialog::getOpenFileNames(core->mainWindow(), tr("Add Existing Files"), dir);
2104 if (fileNames.isEmpty())
2107 QHash<FileType, QString> fileTypeToFiles;
2108 foreach (const QString &fileName, fileNames) {
2109 FileType fileType = typeForFileName(core->mimeDatabase(), QFileInfo(fileName));
2110 fileTypeToFiles.insertMulti(fileType, fileName);
2113 QStringList notAdded;
2114 foreach (const FileType type, fileTypeToFiles.uniqueKeys()) {
2115 projectNode->addFiles(type, fileTypeToFiles.values(type), ¬Added);
2117 if (!notAdded.isEmpty()) {
2118 QString message = tr("Could not add following files to project %1:\n").arg(projectNode->displayName());
2119 QString files = notAdded.join("\n");
2120 QMessageBox::warning(core->mainWindow(), tr("Adding Files to Project Failed"),
2122 foreach (const QString &file, notAdded)
2123 fileNames.removeOne(file);
2126 if (Core::IVersionControl *vcManager = core->vcsManager()->findVersionControlForDirectory(dir))
2127 if (vcManager->supportsOperation(Core::IVersionControl::AddOperation)) {
2128 const QString files = fileNames.join(QString(QLatin1Char('\n')));
2129 QMessageBox::StandardButton button =
2130 QMessageBox::question(core->mainWindow(), tr("Add to Version Control"),
2131 tr("Add files\n%1\nto version control (%2)?").arg(files, vcManager->displayName()),
2132 QMessageBox::Yes | QMessageBox::No);
2133 if (button == QMessageBox::Yes) {
2134 QStringList notAddedToVc;
2135 foreach (const QString &file, fileNames) {
2136 if (!vcManager->vcsAdd(file))
2137 notAddedToVc << file;
2140 if (!notAddedToVc.isEmpty()) {
2141 const QString message = tr("Could not add following files to version control (%1)\n").arg(vcManager->displayName());
2142 const QString filesNotAdded = notAddedToVc.join(QString(QLatin1Char('\n')));
2143 QMessageBox::warning(core->mainWindow(), tr("Adding to Version Control Failed"),
2144 message + filesNotAdded);
2150 void ProjectExplorerPlugin::removeProject()
2152 ProjectNode *subProjectNode = qobject_cast<ProjectNode*>(d->m_currentNode->projectNode());
2153 ProjectNode *projectNode = qobject_cast<ProjectNode *>(subProjectNode->parentFolderNode());
2155 Core::ICore *core = Core::ICore::instance();
2156 RemoveFileDialog removeFileDialog(subProjectNode->path(), core->mainWindow());
2157 removeFileDialog.setDeleteFileVisible(false);
2158 if (removeFileDialog.exec() == QDialog::Accepted)
2159 projectNode->removeSubProjects(QStringList() << subProjectNode->path());
2163 void ProjectExplorerPlugin::openFile()
2165 QTC_ASSERT(d->m_currentNode, return)
2166 Core::EditorManager *em = Core::EditorManager::instance();
2167 em->openEditor(d->m_currentNode->path(), QString(), Core::EditorManager::ModeSwitch);
2170 void ProjectExplorerPlugin::showInGraphicalShell()
2172 QTC_ASSERT(d->m_currentNode, return)
2173 FolderNavigationWidget::showInGraphicalShell(Core::ICore::instance()->mainWindow(),
2174 directoryFor(d->m_currentNode));
2177 void ProjectExplorerPlugin::openTerminalHere()
2179 QTC_ASSERT(d->m_currentNode, return)
2180 FolderNavigationWidget::openTerminal(directoryFor(d->m_currentNode));
2183 void ProjectExplorerPlugin::removeFile()
2185 QTC_ASSERT(d->m_currentNode && d->m_currentNode->nodeType() == FileNodeType, return)
2187 FileNode *fileNode = qobject_cast<FileNode*>(d->m_currentNode);
2188 Core::ICore *core = Core::ICore::instance();
2190 QString filePath = d->m_currentNode->path();
2191 RemoveFileDialog removeFileDialog(filePath, core->mainWindow());
2193 if (removeFileDialog.exec() == QDialog::Accepted) {
2194 const bool deleteFile = removeFileDialog.isDeleteFileChecked();
2196 // remove from project
2197 ProjectNode *projectNode = fileNode->projectNode();
2198 Q_ASSERT(projectNode);
2200 if (!projectNode->removeFiles(fileNode->fileType(), QStringList(filePath))) {
2201 QMessageBox::warning(core->mainWindow(), tr("Removing File Failed"),
2202 tr("Could not remove file %1 from project %2.").arg(filePath).arg(projectNode->displayName()));
2206 // remove from version control
2207 core->vcsManager()->promptToDelete(filePath);
2209 // remove from file system
2211 QFile file(filePath);
2213 if (file.exists()) {
2214 // could have been deleted by vc
2216 QMessageBox::warning(core->mainWindow(), tr("Deleting File Failed"),
2217 tr("Could not delete file %1.").arg(filePath));
2223 void ProjectExplorerPlugin::deleteFile()
2225 QTC_ASSERT(d->m_currentNode && d->m_currentNode->nodeType() == FileNodeType, return)
2227 FileNode *fileNode = qobject_cast<FileNode*>(d->m_currentNode);
2228 Core::ICore *core = Core::ICore::instance();
2230 QString filePath = d->m_currentNode->path();
2231 QMessageBox::StandardButton button =
2232 QMessageBox::question(core->mainWindow(),
2234 tr("Delete %1 from file system?").arg(filePath),
2235 QMessageBox::Yes | QMessageBox::No);
2236 if (button != QMessageBox::Yes)
2239 ProjectNode *projectNode = fileNode->projectNode();
2240 Q_ASSERT(projectNode);
2242 projectNode->deleteFiles(fileNode->fileType(), QStringList(filePath));
2244 if (Core::IVersionControl *vc =
2245 core->vcsManager()->findVersionControlForDirectory(QFileInfo(filePath).absolutePath())) {
2246 vc->vcsDelete(filePath);
2248 QFile file(filePath);
2249 if (file.exists()) {
2251 QMessageBox::warning(core->mainWindow(), tr("Deleting File Failed"),
2252 tr("Could not delete file %1.").arg(filePath));
2256 void ProjectExplorerPlugin::renameFile()
2258 QWidget *focusWidget = QApplication::focusWidget();
2259 while (focusWidget) {
2260 ProjectTreeWidget *treeWidget = qobject_cast<ProjectTreeWidget*>(focusWidget);
2262 treeWidget->editCurrentItem();
2265 focusWidget = focusWidget->parentWidget();
2269 void ProjectExplorerPlugin::renameFile(Node *node, const QString &to)
2271 FileNode *fileNode = qobject_cast<FileNode *>(node);
2274 QString orgFilePath = QFileInfo(node->path()).absoluteFilePath();
2275 QString dir = QFileInfo(orgFilePath).absolutePath();
2276 QString newFilePath = dir + "/" + to;
2277 Core::ICore *core = Core::ICore::instance();
2278 Core::IVersionControl *vc = core->vcsManager()->findVersionControlForDirectory(dir);
2279 bool result = false;
2280 if (vc && vc->supportsOperation(Core::IVersionControl::MoveOperation))
2281 result = vc->vcsMove(orgFilePath, newFilePath);
2282 if (!result) // The moving via vcs failed or the vcs does not support moving, fall back
2283 result = QFile::rename(orgFilePath, newFilePath);
2285 // yeah we moved, tell the filemanager about it
2286 Core::ICore::instance()->fileManager()->renamedFile(orgFilePath, newFilePath);
2287 // Tell the project plugin about it
2288 ProjectNode *projectNode = fileNode->projectNode();
2289 projectNode->renameFile(fileNode->fileType(), orgFilePath, newFilePath);
2290 // TODO emit a signal?
2294 void ProjectExplorerPlugin::setStartupProject()
2296 setStartupProject(d->m_currentProject);
2299 void ProjectExplorerPlugin::populateOpenWithMenu(QMenu *menu, const QString &fileName)
2301 typedef QList<Core::IEditorFactory*> EditorFactoryList;
2302 typedef QList<Core::IExternalEditor*> ExternalEditorList;
2306 bool anyMatches = false;
2308 Core::ICore *core = Core::ICore::instance();
2309 if (const Core::MimeType mt = core->mimeDatabase()->findByFile(QFileInfo(fileName))) {
2310 const EditorFactoryList factories = core->editorManager()->editorFactories(mt, false);
2311 const ExternalEditorList externalEditors = core->editorManager()->externalEditors(mt, false);
2312 anyMatches = !factories.empty() || !externalEditors.empty();
2314 // Add all suitable editors
2315 foreach (Core::IEditorFactory *editorFactory, factories) {
2316 // Add action to open with this very editor factory
2317 QString const actionTitle = editorFactory->displayName();
2318 QAction * const action = menu->addAction(actionTitle);
2319 action->setData(qVariantFromValue(editorFactory));
2321 // Add all suitable external editors
2322 foreach (Core::IExternalEditor *externalEditor, externalEditors) {
2323 QAction * const action = menu->addAction(externalEditor->displayName());
2324 action->setData(qVariantFromValue(externalEditor));
2328 menu->setEnabled(anyMatches);
2331 void ProjectExplorerPlugin::populateOpenWithMenu()
2333 populateOpenWithMenu(d->m_openWithMenu, currentNode()->path());
2336 void ProjectExplorerPlugin::openWithMenuTriggered(QAction *action)
2339 qWarning() << "ProjectExplorerPlugin::openWithMenuTriggered no action, can't happen.";
2341 openEditorFromAction(action, currentNode()->path());
2344 void ProjectExplorerPlugin::openEditorFromAction(QAction *action, const QString &fileName)
2346 Core::EditorManager *em = Core::EditorManager::instance();
2347 const QVariant data = action->data();
2348 if (qVariantCanConvert<Core::IEditorFactory *>(data)) {
2349 Core::IEditorFactory *factory = qVariantValue<Core::IEditorFactory *>(data);
2351 // close any open editors that have this file open, but have a different type.
2352 QList<Core::IEditor *> editorsOpenForFile = em->editorsForFileName(fileName);
2353 if (!editorsOpenForFile.isEmpty()) {
2354 foreach (Core::IEditor *openEditor, editorsOpenForFile) {
2355 if (factory->id() == openEditor->id())
2356 editorsOpenForFile.removeAll(openEditor);
2358 if (!em->closeEditors(editorsOpenForFile)) // don't open if cancel was pressed
2362 em->openEditor(fileName, factory->id(), Core::EditorManager::ModeSwitch);
2365 if (qVariantCanConvert<Core::IExternalEditor *>(data)) {
2366 Core::IExternalEditor *externalEditor = qVariantValue<Core::IExternalEditor *>(data);
2367 em->openExternalEditor(fileName, externalEditor->id());
2371 void ProjectExplorerPlugin::updateSessionMenu()
2373 d->m_sessionMenu->clear();
2374 QActionGroup *ag = new QActionGroup(d->m_sessionMenu);
2375 connect(ag, SIGNAL(triggered(QAction *)), this, SLOT(setSession(QAction *)));
2376 const QString &activeSession = d->m_session->activeSession();
2377 foreach (const QString &session, d->m_session->sessions()) {
2378 QAction *act = ag->addAction(session);
2379 act->setCheckable(true);
2380 if (session == activeSession)
2381 act->setChecked(true);
2383 d->m_sessionMenu->addActions(ag->actions());
2384 d->m_sessionMenu->addSeparator();
2385 d->m_sessionMenu->addAction(d->m_sessionManagerAction);
2387 d->m_sessionMenu->setEnabled(true);
2390 void ProjectExplorerPlugin::setSession(QAction *action)
2392 QString session = action->text();
2393 if (session != d->m_session->activeSession())
2394 d->m_session->loadSession(session);
2398 void ProjectExplorerPlugin::setProjectExplorerSettings(const Internal::ProjectExplorerSettings &pes)
2400 if (d->m_projectExplorerSettings == pes)
2402 d->m_projectExplorerSettings = pes;
2403 emit settingsChanged();
2406 Internal::ProjectExplorerSettings ProjectExplorerPlugin::projectExplorerSettings() const
2408 return d->m_projectExplorerSettings;
2411 QStringList ProjectExplorerPlugin::projectFilePatterns()
2413 QStringList patterns;
2414 const Core::MimeDatabase *mdb = Core::ICore::instance()->mimeDatabase();
2415 foreach(const IProjectManager *pm, allProjectManagers())
2416 if (const Core::MimeType mt = mdb->findByType(pm->mimeType()))
2417 foreach(const Core::MimeGlobPattern &gp, mt.globPatterns())
2418 patterns += gp.regExp().pattern();
2422 void ProjectExplorerPlugin::openOpenProjectDialog()
2424 Core::FileManager *fileMananger = Core::ICore::instance()->fileManager();
2425 const QString projectPatterns = ProjectExplorerPlugin::projectFilePatterns().join(QString(QLatin1Char(' ')));
2426 QString projectFilesFilter = tr("Projects (%1)").arg(projectPatterns);
2427 const QString allFilesFilter = tr("All Files (*)");
2428 const QString filters = allFilesFilter + QLatin1String(";;") + projectFilesFilter;
2429 const QString path = fileMananger->useProjectsDirectory() ? fileMananger->projectsDirectory() : QString();
2430 const QStringList files = fileMananger->getOpenFileNames(filters, path, &projectFilesFilter);
2431 if (!files.isEmpty())
2432 Core::ICore::instance()->openFiles(files, Core::ICore::SwitchMode);
2435 Q_EXPORT_PLUGIN(ProjectExplorerPlugin)