OSDN Git Service

d5b489b40f6967ee825be78fe00cfe5918a9c9ce
[qt-creator-jp/qt-creator-jp.git] / src / plugins / projectexplorer / projectexplorer.cpp
1 /**************************************************************************
2 **
3 ** This file is part of Qt Creator
4 **
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
6 **
7 ** Contact: Nokia Corporation (info@qt.nokia.com)
8 **
9 **
10 ** GNU Lesser General Public License Usage
11 **
12 ** This file may be used under the terms of the GNU Lesser General Public
13 ** License version 2.1 as published by the Free Software Foundation and
14 ** appearing in the file LICENSE.LGPL included in the packaging of this file.
15 ** Please review the following information to ensure the GNU Lesser General
16 ** Public License version 2.1 requirements will be met:
17 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 **
19 ** In addition, as a special exception, Nokia gives you certain additional
20 ** rights. These rights are described in the Nokia Qt LGPL Exception
21 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 **
23 ** Other Usage
24 **
25 ** Alternatively, this file may be used in accordance with the terms and
26 ** conditions contained in a signed written agreement between you and Nokia.
27 **
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at info@qt.nokia.com.
30 **
31 **************************************************************************/
32
33 #include "projectexplorer.h"
34
35 #include "buildsteplist.h"
36 #include "deployconfiguration.h"
37 #include "gcctoolchainfactories.h"
38 #include "project.h"
39 #include "projectexplorersettings.h"
40 #include "target.h"
41 #include "targetsettingspanel.h"
42 #include "toolchainmanager.h"
43 #include "toolchainoptionspage.h"
44 #include "copytaskhandler.h"
45 #include "showineditortaskhandler.h"
46 #include "vcsannotatetaskhandler.h"
47 #include "localapplicationruncontrol.h"
48 #include "allprojectsfilter.h"
49 #include "allprojectsfind.h"
50 #include "buildmanager.h"
51 #include "buildsettingspropertiespage.h"
52 #include "currentprojectfind.h"
53 #include "currentprojectfilter.h"
54 #include "customexecutablerunconfiguration.h"
55 #include "editorsettingspropertiespage.h"
56 #include "codestylesettingspropertiespage.h"
57 #include "dependenciespanel.h"
58 #include "foldernavigationwidget.h"
59 #include "iprojectmanager.h"
60 #include "metatypedeclarations.h"
61 #include "nodesvisitor.h"
62 #include "appoutputpane.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 "session.h"
74 #include "projectnodes.h"
75 #include "sessiondialog.h"
76 #include "target.h"
77 #include "projectexplorersettingspage.h"
78 #include "projectwelcomepage.h"
79 #include "corelistenercheckingforrunningbuild.h"
80 #include "buildconfiguration.h"
81 #include "miniprojecttargetselector.h"
82 #include "taskhub.h"
83 #include "publishing/ipublishingwizardfactory.h"
84 #include "publishing/publishingwizardselectiondialog.h"
85
86 #ifdef Q_OS_WIN
87 #    include "windebuginterface.h"
88 #    include "msvctoolchain.h"
89 #endif
90
91 #include <coreplugin/coreconstants.h>
92 #include <coreplugin/filemanager.h>
93 #include <coreplugin/icore.h>
94 #include <coreplugin/imode.h>
95 #include <coreplugin/mimedatabase.h>
96 #include <coreplugin/modemanager.h>
97 #include <coreplugin/actionmanager/actionmanager.h>
98 #include <coreplugin/actionmanager/actioncontainer.h>
99 #include <coreplugin/actionmanager/command.h>
100 #include <coreplugin/uniqueidmanager.h>
101 #include <coreplugin/editormanager/editormanager.h>
102 #include <coreplugin/editormanager/ieditor.h>
103 #include <coreplugin/editormanager/ieditorfactory.h>
104 #include <coreplugin/editormanager/iexternaleditor.h>
105 #include <coreplugin/findplaceholder.h>
106 #include <coreplugin/basefilewizard.h>
107 #include <coreplugin/vcsmanager.h>
108 #include <coreplugin/iversioncontrol.h>
109 #include <coreplugin/variablemanager.h>
110 #include <coreplugin/fileutils.h>
111 #include <extensionsystem/pluginmanager.h>
112 #include <find/searchresultwindow.h>
113 #include <utils/consoleprocess.h>
114 #include <utils/qtcassert.h>
115 #include <utils/parameteraction.h>
116 #include <utils/stringutils.h>
117
118 #include <QtCore/QtPlugin>
119 #include <QtCore/QDateTime>
120 #include <QtCore/QDebug>
121 #include <QtCore/QSettings>
122 #include <QtCore/QAbstractFileEngine>
123
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>
131
132 /*!
133     \namespace ProjectExplorer
134     ProjectExplorer plugin namespace
135 */
136
137 /*!
138     \namespace ProjectExplorer::Internal
139     Internal namespace of the ProjectExplorer plugin
140     \internal
141 */
142
143 /*!
144     \class ProjectExplorer::ProjectExplorerPlugin
145
146     \brief ProjectExplorerPlugin with static accessor and utility functions to obtain
147     current project, open projects, etc.
148 */
149
150 Q_DECLARE_METATYPE(Core::IEditorFactory*)
151 Q_DECLARE_METATYPE(Core::IExternalEditor*)
152
153 namespace {
154 bool debug = false;
155 }
156
157 static const char kCurrentProjectPath[] = "CurrentProject:Path";
158 static const char kCurrentProjectFilePath[] = "CurrentProject:FilePath";
159
160 namespace ProjectExplorer {
161
162 struct ProjectExplorerPluginPrivate {
163     ProjectExplorerPluginPrivate();
164
165     QMenu *m_sessionContextMenu;
166     QMenu *m_sessionMenu;
167     QMenu *m_projectMenu;
168     QMenu *m_subProjectMenu;
169     QMenu *m_folderMenu;
170     QMenu *m_fileMenu;
171     QMenu *m_openWithMenu;
172
173     QMultiMap<int, QObject*> m_actionMap;
174     QAction *m_sessionManagerAction;
175     QAction *m_newAction;
176     QAction *m_loadAction;
177     Utils::ParameterAction *m_unloadAction;
178     QAction *m_clearSession;
179     QAction *m_buildProjectOnlyAction;
180     Utils::ParameterAction *m_buildAction;
181     Utils::ParameterAction *m_buildActionContextMenu;
182     QAction *m_buildSessionAction;
183     QAction *m_rebuildProjectOnlyAction;
184     Utils::ParameterAction *m_rebuildAction;
185     Utils::ParameterAction *m_rebuildActionContextMenu;
186     QAction *m_rebuildSessionAction;
187     QAction *m_cleanProjectOnlyAction;
188     QAction *m_deployProjectOnlyAction;
189     Utils::ParameterAction *m_deployAction;
190     Utils::ParameterAction *m_deployActionContextMenu;
191     QAction *m_deploySessionAction;
192     Utils::ParameterAction *m_publishAction;
193     Utils::ParameterAction *m_cleanAction;
194     Utils::ParameterAction *m_cleanActionContextMenu;
195     QAction *m_cleanSessionAction;
196     QAction *m_runAction;
197     QAction *m_runActionContextMenu;
198     QAction *m_cancelBuildAction;
199     QAction *m_addNewFileAction;
200     QAction *m_addExistingFilesAction;
201     QAction *m_addNewSubprojectAction;
202     QAction *m_removeFileAction;
203     QAction *m_removeProjectAction;
204     QAction *m_deleteFileAction;
205     QAction *m_renameFileAction;
206     QAction *m_openFileAction;
207     QAction *m_projectTreeCollapseAllAction;
208     QAction *m_showInGraphicalShell;
209     QAction *m_openTerminalHere;
210     QAction *m_setStartupProjectAction;
211     QAction *m_projectSelectorAction;
212     QAction *m_projectSelectorActionMenu;
213     QAction *m_runSubProject;
214
215     Internal::ProjectWindow *m_proWindow;
216     SessionManager *m_session;
217     QString m_sessionToRestoreAtStartup;
218
219     Project *m_currentProject;
220     Node *m_currentNode;
221
222     BuildManager *m_buildManager;
223
224     QList<Internal::ProjectFileFactory*> m_fileFactories;
225     QStringList m_profileMimeTypes;
226     Internal::AppOutputPane *m_outputPane;
227
228     QList<QPair<QString, QString> > m_recentProjects; // pair of filename, displayname
229     static const int m_maxRecentProjects = 7;
230
231     QString m_lastOpenDirectory;
232     RunConfiguration *m_delayedRunConfiguration; // TODO this is not right
233     QString m_runMode;
234     QString m_projectFilterString;
235     Internal::MiniProjectTargetSelector * m_targetSelector;
236     Internal::ProjectExplorerSettings m_projectExplorerSettings;
237     Internal::ProjectWelcomePage *m_welcomePage;
238
239     Core::IMode *m_projectsMode;
240
241     ToolChainManager *m_toolChainManager;
242 };
243
244 ProjectExplorerPluginPrivate::ProjectExplorerPluginPrivate() :
245     m_currentProject(0),
246     m_currentNode(0),
247     m_delayedRunConfiguration(0),
248     m_projectsMode(0),
249     m_toolChainManager(0)
250 {
251 }
252
253 class ProjectsMode : public Core::IMode
254 {
255 public:
256     ProjectsMode(QWidget *proWindow)
257     {
258         setWidget(proWindow);
259         setContext(Core::Context(Constants::C_PROJECTEXPLORER));
260         setDisplayName(QCoreApplication::translate("ProjectExplorer::ProjectsMode", "Projects"));
261         setIcon(QIcon(QLatin1String(":/fancyactionbar/images/mode_Project.png")));
262         setPriority(Constants::P_MODE_SESSION);
263         setId(QLatin1String(Constants::MODE_SESSION));
264         setType(QString());
265         setContextHelpId(QLatin1String("Managing Projects"));
266     }
267 };
268
269 }  // namespace ProjectExplorer
270
271 using namespace ProjectExplorer;
272 using namespace ProjectExplorer::Internal;
273
274
275 ProjectExplorerPlugin *ProjectExplorerPlugin::m_instance = 0;
276
277 ProjectExplorerPlugin::ProjectExplorerPlugin()
278     : d(new ProjectExplorerPluginPrivate)
279 {
280     m_instance = this;
281 }
282
283 ProjectExplorerPlugin::~ProjectExplorerPlugin()
284 {
285     removeObject(d->m_welcomePage);
286     delete d->m_welcomePage;
287     delete d->m_toolChainManager;
288     removeObject(this);
289     delete d;
290 }
291
292 ProjectExplorerPlugin *ProjectExplorerPlugin::instance()
293 {
294     return m_instance;
295 }
296
297 bool ProjectExplorerPlugin::parseArguments(const QStringList &arguments, QString * /* error */)
298 {
299     CustomWizard::setVerbose(arguments.count(QLatin1String("-customwizard-verbose")));
300     return true;
301 }
302
303 bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *error)
304 {
305     if (!parseArguments(arguments, error))
306         return false;
307     addObject(this);
308
309     // Add ToolChainFactories:
310 #ifdef Q_OS_WIN
311     addAutoReleasedObject(new WinDebugInterface);
312
313     addAutoReleasedObject(new Internal::MingwToolChainFactory);
314     addAutoReleasedObject(new Internal::MsvcToolChainFactory);
315 #else
316     addAutoReleasedObject(new Internal::GccToolChainFactory);
317     addAutoReleasedObject(new Internal::LinuxIccToolChainFactory);
318 #endif
319     addAutoReleasedObject(new Internal::ClangToolChainFactory);
320
321     d->m_toolChainManager = new ToolChainManager(this);
322
323     addAutoReleasedObject(new Internal::ToolChainOptionsPage);
324
325     addAutoReleasedObject(new TaskHub);
326
327     Core::ICore *core = Core::ICore::instance();
328     Core::ActionManager *am = core->actionManager();
329     connect(core, SIGNAL(newItemsDialogRequested()), this, SLOT(loadCustomWizards()));
330
331     d->m_welcomePage = new ProjectWelcomePage;
332     connect(d->m_welcomePage, SIGNAL(manageSessions()), this, SLOT(showSessionManager()));
333     addObject(d->m_welcomePage);
334
335     connect(core->fileManager(), SIGNAL(currentFileChanged(QString)),
336             this, SLOT(setCurrentFile(QString)));
337
338     d->m_session = new SessionManager(this);
339
340     connect(d->m_session, SIGNAL(projectAdded(ProjectExplorer::Project *)),
341             this, SIGNAL(fileListChanged()));
342     connect(d->m_session, SIGNAL(aboutToRemoveProject(ProjectExplorer::Project *)),
343             this, SLOT(invalidateProject(ProjectExplorer::Project *)));
344     connect(d->m_session, SIGNAL(projectRemoved(ProjectExplorer::Project *)),
345             this, SIGNAL(fileListChanged()));
346     connect(d->m_session, SIGNAL(projectAdded(ProjectExplorer::Project*)),
347             this, SLOT(projectAdded(ProjectExplorer::Project*)));
348     connect(d->m_session, SIGNAL(projectRemoved(ProjectExplorer::Project*)),
349             this, SLOT(projectRemoved(ProjectExplorer::Project*)));
350     connect(d->m_session, SIGNAL(startupProjectChanged(ProjectExplorer::Project *)),
351             this, SLOT(startupProjectChanged()));
352     connect(d->m_session, SIGNAL(dependencyChanged(ProjectExplorer::Project*,ProjectExplorer::Project*)),
353             this, SLOT(updateActions()));
354     connect(d->m_session, SIGNAL(sessionLoaded()),
355             this, SLOT(updateActions()));
356     connect(d->m_session, SIGNAL(sessionLoaded()),
357             this, SLOT(updateWelcomePage()));
358
359     d->m_proWindow = new ProjectWindow;
360
361     Core::Context globalcontext(Core::Constants::C_GLOBAL);
362     Core::Context projecTreeContext(Constants::C_PROJECT_TREE);
363
364     d->m_projectsMode = new ProjectsMode(d->m_proWindow);
365     d->m_projectsMode->setEnabled(session()->startupProject());
366     addAutoReleasedObject(d->m_projectsMode);
367     d->m_proWindow->layout()->addWidget(new Core::FindToolBarPlaceHolder(d->m_proWindow));
368
369     addAutoReleasedObject(new CopyTaskHandler);
370     addAutoReleasedObject(new ShowInEditorTaskHandler);
371     addAutoReleasedObject(new VcsAnnotateTaskHandler);
372
373     d->m_buildManager = new BuildManager(this);
374     connect(d->m_buildManager, SIGNAL(buildStateChanged(ProjectExplorer::Project *)),
375             this, SLOT(buildStateChanged(ProjectExplorer::Project *)));
376     connect(d->m_buildManager, SIGNAL(buildQueueFinished(bool)),
377             this, SLOT(buildQueueFinished(bool)));
378
379     addAutoReleasedObject(new CoreListener);
380
381     d->m_outputPane = new AppOutputPane;
382     addAutoReleasedObject(d->m_outputPane);
383     connect(d->m_session, SIGNAL(projectRemoved(ProjectExplorer::Project *)),
384             d->m_outputPane, SLOT(projectRemoved()));
385
386     AllProjectsFilter *allProjectsFilter = new AllProjectsFilter(this);
387     addAutoReleasedObject(allProjectsFilter);
388
389     CurrentProjectFilter *currentProjectFilter = new CurrentProjectFilter(this);
390     addAutoReleasedObject(currentProjectFilter);
391
392     addAutoReleasedObject(new BuildSettingsPanelFactory);
393     addAutoReleasedObject(new RunSettingsPanelFactory);
394     addAutoReleasedObject(new EditorSettingsPanelFactory);
395     addAutoReleasedObject(new CodeStyleSettingsPanelFactory);
396     addAutoReleasedObject(new DependenciesPanelFactory(d->m_session));
397
398     ProcessStepFactory *processStepFactory = new ProcessStepFactory;
399     addAutoReleasedObject(processStepFactory);
400
401     AllProjectsFind *allProjectsFind = new AllProjectsFind(this,
402         Find::SearchResultWindow::instance());
403     addAutoReleasedObject(allProjectsFind);
404
405     CurrentProjectFind *currentProjectFind = new CurrentProjectFind(this,
406         Find::SearchResultWindow::instance());
407     addAutoReleasedObject(currentProjectFind);
408
409     addAutoReleasedObject(new LocalApplicationRunControlFactory);
410     addAutoReleasedObject(new CustomExecutableRunConfigurationFactory);
411
412     addAutoReleasedObject(new ProjectFileWizardExtension);
413
414     // Settings page
415     addAutoReleasedObject(new ProjectExplorerSettingsPage);
416
417     // context menus
418     Core::ActionContainer *msessionContextMenu =
419         am->createMenu(Constants::M_SESSIONCONTEXT);
420     Core::ActionContainer *mprojectContextMenu =
421         am->createMenu(Constants::M_PROJECTCONTEXT);
422     Core::ActionContainer *msubProjectContextMenu =
423         am->createMenu(Constants::M_SUBPROJECTCONTEXT);
424     Core::ActionContainer *mfolderContextMenu =
425         am->createMenu(Constants::M_FOLDERCONTEXT);
426     Core::ActionContainer *mfileContextMenu =
427         am->createMenu(Constants::M_FILECONTEXT);
428
429     d->m_sessionContextMenu = msessionContextMenu->menu();
430     d->m_projectMenu = mprojectContextMenu->menu();
431     d->m_subProjectMenu = msubProjectContextMenu->menu();
432     d->m_folderMenu = mfolderContextMenu->menu();
433     d->m_fileMenu = mfileContextMenu->menu();
434
435     Core::ActionContainer *mfile =
436         am->actionContainer(Core::Constants::M_FILE);
437     Core::ActionContainer *menubar =
438         am->actionContainer(Core::Constants::MENU_BAR);
439
440     // mode manager (for fancy actions)
441     Core::ModeManager *modeManager = core->modeManager();
442
443     // build menu
444     Core::ActionContainer *mbuild =
445         am->createMenu(Constants::M_BUILDPROJECT);
446     mbuild->menu()->setTitle(tr("&Build"));
447     menubar->addMenu(mbuild, Core::Constants::G_VIEW);
448
449     // debug menu
450     Core::ActionContainer *mdebug =
451         am->createMenu(Constants::M_DEBUG);
452     mdebug->menu()->setTitle(tr("&Debug"));
453     menubar->addMenu(mdebug, Core::Constants::G_VIEW);
454
455     Core::ActionContainer *mstartdebugging =
456         am->createMenu(Constants::M_DEBUG_STARTDEBUGGING);
457     mstartdebugging->menu()->setTitle(tr("&Start Debugging"));
458     mdebug->addMenu(mstartdebugging, Core::Constants::G_DEFAULT_ONE);
459
460     //
461     // Groups
462     //
463
464     mbuild->appendGroup(Constants::G_BUILD_SESSION);
465     mbuild->appendGroup(Constants::G_BUILD_PROJECT);
466     mbuild->appendGroup(Constants::G_BUILD_OTHER);
467     mbuild->appendGroup(Constants::G_BUILD_CANCEL);
468     mbuild->appendGroup(Constants::G_BUILD_RUN);
469
470     msessionContextMenu->appendGroup(Constants::G_SESSION_BUILD);
471     msessionContextMenu->appendGroup(Constants::G_SESSION_FILES);
472     msessionContextMenu->appendGroup(Constants::G_SESSION_OTHER);
473     msessionContextMenu->appendGroup(Constants::G_SESSION_CONFIG);
474     msessionContextMenu->appendGroup(Constants::G_PROJECT_TREE);
475
476     mprojectContextMenu->appendGroup(Constants::G_PROJECT_FIRST);
477     mprojectContextMenu->appendGroup(Constants::G_PROJECT_BUILD);
478     mprojectContextMenu->appendGroup(Constants::G_PROJECT_RUN);
479     mprojectContextMenu->appendGroup(Constants::G_PROJECT_FILES);
480     mprojectContextMenu->appendGroup(Constants::G_PROJECT_LAST);
481     mprojectContextMenu->appendGroup(Constants::G_PROJECT_TREE);
482
483     msubProjectContextMenu->appendGroup(Constants::G_PROJECT_FIRST);
484     msubProjectContextMenu->appendGroup(Constants::G_PROJECT_BUILD);
485     msubProjectContextMenu->appendGroup(Constants::G_PROJECT_RUN);
486     msubProjectContextMenu->appendGroup(Constants::G_PROJECT_FILES);
487     msubProjectContextMenu->appendGroup(Constants::G_PROJECT_LAST);
488     msubProjectContextMenu->appendGroup(Constants::G_PROJECT_TREE);
489
490     Core::ActionContainer *runMenu = Core::ICore::instance()->actionManager()->createMenu(Constants::RUNMENUCONTEXTMENU);
491     runMenu->setOnAllDisabledBehavior(Core::ActionContainer::Hide);
492     QIcon runIcon(Constants::ICON_RUN);
493     runIcon.addFile(Constants::ICON_RUN_SMALL);
494     runMenu->menu()->setIcon(runIcon);
495     runMenu->menu()->setTitle("Run");
496     msubProjectContextMenu->addMenu(runMenu, ProjectExplorer::Constants::G_PROJECT_RUN);
497
498     mfolderContextMenu->appendGroup(Constants::G_FOLDER_FILES);
499     mfolderContextMenu->appendGroup(Constants::G_FOLDER_OTHER);
500     mfolderContextMenu->appendGroup(Constants::G_FOLDER_CONFIG);
501     mfolderContextMenu->appendGroup(Constants::G_PROJECT_TREE);
502
503     mfileContextMenu->appendGroup(Constants::G_FILE_OPEN);
504     mfileContextMenu->appendGroup(Constants::G_FILE_OTHER);
505     mfileContextMenu->appendGroup(Constants::G_FILE_CONFIG);
506     mfileContextMenu->appendGroup(Constants::G_PROJECT_TREE);
507     // "open with" submenu
508     Core::ActionContainer * const openWith =
509             am->createMenu(ProjectExplorer::Constants::M_OPENFILEWITHCONTEXT);
510     openWith->setOnAllDisabledBehavior(Core::ActionContainer::Show);
511     d->m_openWithMenu = openWith->menu();
512     d->m_openWithMenu->setTitle(tr("Open With"));
513
514     connect(d->m_openWithMenu, SIGNAL(triggered(QAction *)),
515             this, SLOT(openWithMenuTriggered(QAction *)));
516
517     //
518     // Separators
519     //
520
521     Core::Command *cmd;
522     QAction *sep;
523
524     sep = new QAction(this);
525     sep->setSeparator(true);
526     cmd = am->registerAction(sep, Core::Id("ProjectExplorer.Build.Sep"), globalcontext);
527     mbuild->addAction(cmd, Constants::G_BUILD_PROJECT);
528
529     sep = new QAction(this);
530     sep->setSeparator(true);
531     cmd = am->registerAction(sep, Core::Id("ProjectExplorer.Files.Sep"), projecTreeContext);
532     msessionContextMenu->addAction(cmd, Constants::G_SESSION_FILES);
533     mprojectContextMenu->addAction(cmd, Constants::G_PROJECT_FILES);
534     msubProjectContextMenu->addAction(cmd, Constants::G_PROJECT_FILES);
535
536     sep = new QAction(this);
537     sep->setSeparator(true);
538     cmd = am->registerAction(sep, Core::Id("ProjectExplorer.Config.Sep"), projecTreeContext);
539     msessionContextMenu->addAction(cmd, Constants::G_SESSION_CONFIG);
540
541     sep = new QAction(this);
542     sep->setSeparator(true);
543     cmd = am->registerAction(sep, Core::Id("ProjectExplorer.Projects.Sep"), globalcontext);
544     mfile->addAction(cmd, Core::Constants::G_FILE_PROJECT);
545
546     sep = new QAction(this);
547     sep->setSeparator(true);
548     cmd = am->registerAction(sep, Core::Id("ProjectExplorer.Other.Sep"), globalcontext);
549     mbuild->addAction(cmd, Constants::G_BUILD_OTHER);
550     msessionContextMenu->addAction(cmd, Constants::G_SESSION_OTHER);
551
552     sep = new QAction(this);
553     sep->setSeparator(true);
554     cmd = am->registerAction(sep, Core::Id("ProjectExplorer.Run.Sep"), globalcontext);
555     mbuild->addAction(cmd, Constants::G_BUILD_RUN);
556     mprojectContextMenu->addAction(cmd, Constants::G_PROJECT_RUN);
557
558     sep = new QAction(this);
559     sep->setSeparator(true);
560     cmd = am->registerAction(sep, Core::Id("ProjectExplorer.CancelBuild.Sep"), globalcontext);
561     mbuild->addAction(cmd, Constants::G_BUILD_CANCEL);
562
563     //
564     // Actions
565     //
566
567     // new action
568     d->m_newAction = new QAction(tr("New Project..."), this);
569     cmd = am->registerAction(d->m_newAction, Constants::NEWPROJECT, globalcontext);
570     cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+N")));
571     msessionContextMenu->addAction(cmd, Constants::G_SESSION_FILES);
572
573     // open action
574     d->m_loadAction = new QAction(tr("Load Project..."), this);
575     cmd = am->registerAction(d->m_loadAction, Constants::LOAD, globalcontext);
576 #ifndef Q_WS_MAC
577     cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+O")));
578 #endif
579     msessionContextMenu->addAction(cmd, Constants::G_SESSION_FILES);
580
581     // Default open action
582     d->m_openFileAction = new QAction(tr("Open File"), this);
583     cmd = am->registerAction(d->m_openFileAction, ProjectExplorer::Constants::OPENFILE,
584                        projecTreeContext);
585     mfileContextMenu->addAction(cmd, Constants::G_FILE_OPEN);
586
587     d->m_showInGraphicalShell = new QAction(Core::Internal::FileUtils::msgGraphicalShellAction(), this);
588     cmd = am->registerAction(d->m_showInGraphicalShell, ProjectExplorer::Constants::SHOWINGRAPHICALSHELL,
589                        projecTreeContext);
590     mfileContextMenu->addAction(cmd, Constants::G_FILE_OPEN);
591     mfolderContextMenu->addAction(cmd, Constants::G_FOLDER_FILES);
592
593     d->m_openTerminalHere = new QAction(Core::Internal::FileUtils::msgTerminalAction(), this);
594     cmd = am->registerAction(d->m_openTerminalHere, ProjectExplorer::Constants::OPENTERMIANLHERE,
595                        projecTreeContext);
596     mfileContextMenu->addAction(cmd, Constants::G_FILE_OPEN);
597     mfolderContextMenu->addAction(cmd, Constants::G_FOLDER_FILES);
598
599     // Open With menu
600     mfileContextMenu->addMenu(openWith, ProjectExplorer::Constants::G_FILE_OPEN);
601
602     // recent projects menu
603     Core::ActionContainer *mrecent =
604         am->createMenu(Constants::M_RECENTPROJECTS);
605     mrecent->menu()->setTitle(tr("Recent P&rojects"));
606     mrecent->setOnAllDisabledBehavior(Core::ActionContainer::Show);
607     mfile->addMenu(mrecent, Core::Constants::G_FILE_OPEN);
608     connect(mfile->menu(), SIGNAL(aboutToShow()),
609         this, SLOT(updateRecentProjectMenu()));
610
611     // recent session menu
612     Core::ActionContainer *msession = am->createMenu(Constants::M_SESSION);
613     msession->menu()->setTitle(tr("Recent Sessions"));
614     msession->setOnAllDisabledBehavior(Core::ActionContainer::Show);
615     mfile->addMenu(msession, Core::Constants::G_FILE_OPEN);
616     d->m_sessionMenu = msession->menu();
617     connect(mfile->menu(), SIGNAL(aboutToShow()),
618             this, SLOT(updateSessionMenu()));
619
620     // session manager action
621     d->m_sessionManagerAction = new QAction(tr("Session Manager..."), this);
622     cmd = am->registerAction(d->m_sessionManagerAction, Constants::NEWSESSION, globalcontext);
623     mfile->addAction(cmd, Core::Constants::G_FILE_OPEN);
624     cmd->setDefaultKeySequence(QKeySequence());
625
626
627     // XXX same action?
628     // unload action
629     d->m_unloadAction = new Utils::ParameterAction(tr("Close Project"), tr("Close Project \"%1\""),
630                                                       Utils::ParameterAction::EnabledWithParameter, this);
631     cmd = am->registerAction(d->m_unloadAction, Constants::UNLOAD, globalcontext);
632     cmd->setAttribute(Core::Command::CA_UpdateText);
633     cmd->setDefaultText(d->m_unloadAction->text());
634     mfile->addAction(cmd, Core::Constants::G_FILE_PROJECT);
635
636     // unload session action
637     d->m_clearSession = new QAction(tr("Close All Projects"), this);
638     cmd = am->registerAction(d->m_clearSession, Constants::CLEARSESSION, globalcontext);
639     mfile->addAction(cmd, Core::Constants::G_FILE_PROJECT);
640     msessionContextMenu->addAction(cmd, Constants::G_SESSION_FILES);
641
642     // build session action
643     QIcon buildIcon(Constants::ICON_BUILD);
644     buildIcon.addFile(Constants::ICON_BUILD_SMALL);
645     d->m_buildSessionAction = new QAction(buildIcon, tr("Build All"), this);
646     cmd = am->registerAction(d->m_buildSessionAction, Constants::BUILDSESSION, globalcontext);
647     cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+B")));
648     mbuild->addAction(cmd, Constants::G_BUILD_SESSION);
649     msessionContextMenu->addAction(cmd, Constants::G_SESSION_BUILD);
650
651     // rebuild session action
652     QIcon rebuildIcon(Constants::ICON_REBUILD);
653     rebuildIcon.addFile(Constants::ICON_REBUILD_SMALL);
654     d->m_rebuildSessionAction = new QAction(rebuildIcon, tr("Rebuild All"), this);
655     cmd = am->registerAction(d->m_rebuildSessionAction, Constants::REBUILDSESSION, globalcontext);
656     mbuild->addAction(cmd, Constants::G_BUILD_SESSION);
657     msessionContextMenu->addAction(cmd, Constants::G_SESSION_BUILD);
658
659     // deploy session
660     d->m_deploySessionAction = new QAction(tr("Deploy All"), this);
661     cmd = am->registerAction(d->m_deploySessionAction, Constants::DEPLOYSESSION, globalcontext);
662     mbuild->addAction(cmd, Constants::G_BUILD_SESSION);
663     msessionContextMenu->addAction(cmd, Constants::G_SESSION_BUILD);
664
665     // clean session
666     QIcon cleanIcon(Constants::ICON_CLEAN);
667     cleanIcon.addFile(Constants::ICON_CLEAN_SMALL);
668     d->m_cleanSessionAction = new QAction(cleanIcon, tr("Clean All"), this);
669     cmd = am->registerAction(d->m_cleanSessionAction, Constants::CLEANSESSION, globalcontext);
670     mbuild->addAction(cmd, Constants::G_BUILD_SESSION);
671     msessionContextMenu->addAction(cmd, Constants::G_SESSION_BUILD);
672
673     // build action
674     d->m_buildAction = new Utils::ParameterAction(tr("Build Project"), tr("Build Project \"%1\""),
675                                                      Utils::ParameterAction::AlwaysEnabled, this);
676     d->m_buildAction->setIcon(buildIcon);
677     cmd = am->registerAction(d->m_buildAction, Constants::BUILD, globalcontext);
678     cmd->setAttribute(Core::Command::CA_UpdateText);
679     cmd->setDefaultText(d->m_buildAction->text());
680     cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+B")));
681     mbuild->addAction(cmd, Constants::G_BUILD_PROJECT);
682
683     // Add to mode bar
684     modeManager->addAction(cmd->action(), Constants::P_ACTION_BUILDPROJECT);
685
686     // rebuild action
687     d->m_rebuildAction = new Utils::ParameterAction(tr("Rebuild Project"), tr("Rebuild Project \"%1\""),
688                                                        Utils::ParameterAction::AlwaysEnabled, this);
689     cmd = am->registerAction(d->m_rebuildAction, Constants::REBUILD, globalcontext);
690     cmd->setAttribute(Core::Command::CA_UpdateText);
691     cmd->setDefaultText(d->m_rebuildAction->text());
692     mbuild->addAction(cmd, Constants::G_BUILD_PROJECT);
693
694     // deploy action
695     d->m_deployAction = new Utils::ParameterAction(tr("Deploy Project"), tr("Deploy Project \"%1\""),
696                                                      Utils::ParameterAction::AlwaysEnabled, this);
697     cmd = am->registerAction(d->m_deployAction, Constants::DEPLOY, globalcontext);
698     cmd->setAttribute(Core::Command::CA_UpdateText);
699     cmd->setDefaultText(d->m_deployAction->text());
700     mbuild->addAction(cmd, Constants::G_BUILD_PROJECT);
701
702     // Publish action
703     d->m_publishAction = new Utils::ParameterAction(tr("Publish Project..."), tr("Publish Project \"%1\"..."),
704                                                     Utils::ParameterAction::AlwaysEnabled, this);
705     cmd = am->registerAction(d->m_publishAction, Constants::PUBLISH, globalcontext);
706     cmd->setAttribute(Core::Command::CA_UpdateText);
707     cmd->setDefaultText(d->m_publishAction->text());
708     mbuild->addAction(cmd, Constants::G_BUILD_PROJECT);
709
710     // clean action
711     d->m_cleanAction = new Utils::ParameterAction(tr("Clean Project"), tr("Clean Project \"%1\""),
712                                                      Utils::ParameterAction::AlwaysEnabled, this);
713     cmd = am->registerAction(d->m_cleanAction, Constants::CLEAN, globalcontext);
714     cmd->setAttribute(Core::Command::CA_UpdateText);
715     cmd->setDefaultText(d->m_cleanAction->text());
716     mbuild->addAction(cmd, Constants::G_BUILD_PROJECT);
717
718     // build action (context menu)
719     d->m_buildActionContextMenu = new Utils::ParameterAction(tr("Build Project"), tr("Build Project \"%1\""),
720                                                              Utils::ParameterAction::AlwaysEnabled, this);
721     cmd = am->registerAction(d->m_buildActionContextMenu, Constants::BUILDCM, projecTreeContext);
722     cmd->setAttribute(Core::Command::CA_UpdateText);
723     cmd->setDefaultText(d->m_buildActionContextMenu->text());
724     mprojectContextMenu->addAction(cmd, Constants::G_PROJECT_BUILD);
725
726     // rebuild action (context menu)
727     d->m_rebuildActionContextMenu = new Utils::ParameterAction(tr("Rebuild Project"), tr("Rebuild Project \"%1\""),
728                                                                Utils::ParameterAction::AlwaysEnabled, this);
729     cmd = am->registerAction(d->m_rebuildActionContextMenu, Constants::REBUILDCM, projecTreeContext);
730     cmd->setAttribute(Core::Command::CA_UpdateText);
731     cmd->setDefaultText(d->m_rebuildActionContextMenu->text());
732     mprojectContextMenu->addAction(cmd, Constants::G_PROJECT_BUILD);
733
734     // deploy action (context menu)
735     d->m_deployActionContextMenu = new Utils::ParameterAction(tr("Deploy Project"), tr("Deploy Project \"%1\""),
736                                                               Utils::ParameterAction::AlwaysEnabled, this);
737     cmd = am->registerAction(d->m_deployActionContextMenu, Constants::DEPLOYCM, projecTreeContext);
738     cmd->setAttribute(Core::Command::CA_UpdateText);
739     cmd->setDefaultText(d->m_deployActionContextMenu->text());
740     mprojectContextMenu->addAction(cmd, Constants::G_PROJECT_BUILD);
741
742     // clean action (context menu)
743     d->m_cleanActionContextMenu = new Utils::ParameterAction(tr("Clean Project"), tr("Clean Project \"%1\""),
744                                                              Utils::ParameterAction::AlwaysEnabled, this);
745     cmd = am->registerAction(d->m_cleanActionContextMenu, Constants::CLEANCM, projecTreeContext);
746     cmd->setAttribute(Core::Command::CA_UpdateText);
747     cmd->setDefaultText(d->m_cleanActionContextMenu->text());
748     mprojectContextMenu->addAction(cmd, Constants::G_PROJECT_BUILD);
749
750     // build without dependencies action
751     d->m_buildProjectOnlyAction = new QAction(tr("Build Without Dependencies"), this);
752     cmd = am->registerAction(d->m_buildProjectOnlyAction, Constants::BUILDPROJECTONLY, globalcontext);
753
754     // rebuild without dependencies action
755     d->m_rebuildProjectOnlyAction = new QAction(tr("Rebuild Without Dependencies"), this);
756     cmd = am->registerAction(d->m_rebuildProjectOnlyAction, Constants::REBUILDPROJECTONLY, globalcontext);
757
758     // deploy without dependencies action
759     d->m_deployProjectOnlyAction = new QAction(tr("Deploy Without Dependencies"), this);
760     cmd = am->registerAction(d->m_deployProjectOnlyAction, Constants::DEPLOYPROJECTONLY, globalcontext);
761
762     // clean without dependencies action
763     d->m_cleanProjectOnlyAction = new QAction(tr("Clean Without Dependencies"), this);
764     cmd = am->registerAction(d->m_cleanProjectOnlyAction, Constants::CLEANPROJECTONLY, globalcontext);
765
766     // run action
767     d->m_runAction = new QAction(runIcon, tr("Run"), this);
768     cmd = am->registerAction(d->m_runAction, Constants::RUN, globalcontext);
769     cmd->setAttribute(Core::Command::CA_UpdateText);
770
771     cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+R")));
772     mbuild->addAction(cmd, Constants::G_BUILD_RUN);
773
774     modeManager->addAction(cmd->action(), Constants::P_ACTION_RUN);
775
776     d->m_runActionContextMenu = new QAction(runIcon, tr("Run"), this);
777     cmd = am->registerAction(d->m_runActionContextMenu, Constants::RUNCONTEXTMENU, projecTreeContext);
778     mprojectContextMenu->addAction(cmd, Constants::G_PROJECT_RUN);
779     msubProjectContextMenu->addAction(cmd, Constants::G_PROJECT_RUN);
780
781     // cancel build action
782     d->m_cancelBuildAction = new QAction(tr("Cancel Build"), this);
783     cmd = am->registerAction(d->m_cancelBuildAction, Constants::CANCELBUILD, globalcontext);
784     mbuild->addAction(cmd, Constants::G_BUILD_CANCEL);
785
786     // add new file action
787     d->m_addNewFileAction = new QAction(tr("Add New..."), this);
788     cmd = am->registerAction(d->m_addNewFileAction, ProjectExplorer::Constants::ADDNEWFILE,
789                        projecTreeContext);
790     mprojectContextMenu->addAction(cmd, Constants::G_PROJECT_FILES);
791     msubProjectContextMenu->addAction(cmd, Constants::G_PROJECT_FILES);
792     mfolderContextMenu->addAction(cmd, Constants::G_FOLDER_FILES);
793
794     // add existing file action
795     d->m_addExistingFilesAction = new QAction(tr("Add Existing Files..."), this);
796     cmd = am->registerAction(d->m_addExistingFilesAction, ProjectExplorer::Constants::ADDEXISTINGFILES,
797                        projecTreeContext);
798     mprojectContextMenu->addAction(cmd, Constants::G_PROJECT_FILES);
799     msubProjectContextMenu->addAction(cmd, Constants::G_PROJECT_FILES);
800     mfolderContextMenu->addAction(cmd, Constants::G_FOLDER_FILES);
801
802     // new subproject action
803     d->m_addNewSubprojectAction = new QAction(tr("New Subproject..."), this);
804     cmd = am->registerAction(d->m_addNewSubprojectAction, ProjectExplorer::Constants::ADDNEWSUBPROJECT,
805                        projecTreeContext);
806     mprojectContextMenu->addAction(cmd, Constants::G_PROJECT_FILES);
807     msubProjectContextMenu->addAction(cmd, Constants::G_PROJECT_FILES);
808
809     // unload project again, in right position
810     mprojectContextMenu->addAction(am->command(Constants::UNLOAD), Constants::G_PROJECT_LAST);
811
812     // remove file action
813     d->m_removeFileAction = new QAction(tr("Remove File..."), this);
814     cmd = am->registerAction(d->m_removeFileAction, ProjectExplorer::Constants::REMOVEFILE,
815                        projecTreeContext);
816     cmd->setDefaultKeySequence(QKeySequence::Delete);
817     mfileContextMenu->addAction(cmd, Constants::G_FILE_OTHER);
818
819     //: Remove project from parent profile (Project explorer view); will not physically delete any files.
820     d->m_removeProjectAction = new QAction(tr("Remove Project..."), this);
821     cmd = am->registerAction(d->m_removeProjectAction, ProjectExplorer::Constants::REMOVEPROJECT,
822                        projecTreeContext);
823     msubProjectContextMenu->addAction(cmd, Constants::G_PROJECT_FILES);
824
825     // delete file action
826     d->m_deleteFileAction = new QAction(tr("Delete File..."), this);
827     cmd = am->registerAction(d->m_deleteFileAction, ProjectExplorer::Constants::DELETEFILE,
828                              projecTreeContext);
829     cmd->setDefaultKeySequence(QKeySequence::Delete);
830     mfileContextMenu->addAction(cmd, Constants::G_FILE_OTHER);
831
832     // renamefile action
833     d->m_renameFileAction = new QAction(tr("Rename"), this);
834     cmd = am->registerAction(d->m_renameFileAction, ProjectExplorer::Constants::RENAMEFILE,
835                        projecTreeContext);
836     mfileContextMenu->addAction(cmd, Constants::G_FILE_OTHER);
837     // Not yet used by anyone, so hide for now
838 //    mfolder->addAction(cmd, Constants::G_FOLDER_FILES);
839 //    msubProject->addAction(cmd, Constants::G_FOLDER_FILES);
840 //    mproject->addAction(cmd, Constants::G_FOLDER_FILES);
841
842     // set startup project action
843     d->m_setStartupProjectAction = new QAction(tr("Set as Active Project"), this);
844     cmd = am->registerAction(d->m_setStartupProjectAction, ProjectExplorer::Constants::SETSTARTUP,
845                              projecTreeContext);
846     mprojectContextMenu->addAction(cmd, Constants::G_PROJECT_FIRST);
847
848     // Collapse All.
849     sep = new QAction(this);
850     sep->setSeparator(true);
851     Core::Command *treeSpacer = am->registerAction(sep, Core::Id("ProjectExplorer.Tree.Sep"), globalcontext);
852
853     d->m_projectTreeCollapseAllAction = new QAction(tr("Collapse All"), this);
854     cmd = am->registerAction(d->m_projectTreeCollapseAllAction, Constants::PROJECTTREE_COLLAPSE_ALL,
855                              projecTreeContext);
856     const QString treeGroup = QLatin1String(Constants::G_PROJECT_TREE);
857     mfileContextMenu->addAction(treeSpacer, treeGroup);
858     mfileContextMenu->addAction(cmd, treeGroup);
859     msubProjectContextMenu->addAction(treeSpacer, treeGroup);
860     msubProjectContextMenu->addAction(cmd, treeGroup);
861     mfolderContextMenu->addAction(treeSpacer, treeGroup);
862     mfolderContextMenu->addAction(cmd, treeGroup);
863     mprojectContextMenu->addAction(treeSpacer, treeGroup);
864     mprojectContextMenu->addAction(cmd, treeGroup);
865     msessionContextMenu->addAction(treeSpacer, treeGroup);
866     msessionContextMenu->addAction(cmd, treeGroup);
867
868     // target selector
869     d->m_projectSelectorAction = new QAction(this);
870     d->m_projectSelectorAction->setCheckable(true);
871     d->m_projectSelectorAction->setEnabled(false);
872     QWidget *mainWindow = Core::ICore::instance()->mainWindow();
873     d->m_targetSelector = new Internal::MiniProjectTargetSelector(d->m_projectSelectorAction, mainWindow);
874     connect(d->m_projectSelectorAction, SIGNAL(triggered()), d->m_targetSelector, SLOT(show()));
875     modeManager->addProjectSelector(d->m_projectSelectorAction);
876
877     d->m_projectSelectorActionMenu = new QAction(this);
878     d->m_projectSelectorActionMenu->setEnabled(false);
879     d->m_projectSelectorActionMenu->setText(tr("Open Build/Run Target Selector..."));
880     connect(d->m_projectSelectorActionMenu, SIGNAL(triggered()), d->m_targetSelector, SLOT(show()));
881     cmd = am->registerAction(d->m_projectSelectorActionMenu, ProjectExplorer::Constants::SELECTTARGET,
882                        globalcontext);
883     cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+T")));
884     mbuild->addAction(cmd, Constants::G_BUILD_RUN);
885
886     connect(d->m_session, SIGNAL(projectAdded(ProjectExplorer::Project*)),
887             d->m_targetSelector, SLOT(addProject(ProjectExplorer::Project*)));
888     connect(d->m_session, SIGNAL(aboutToRemoveProject(ProjectExplorer::Project*)),
889             d->m_targetSelector, SLOT(removeProject(ProjectExplorer::Project*)));
890     connect(d->m_targetSelector, SIGNAL(startupProjectChanged(ProjectExplorer::Project*)),
891             this, SLOT(setStartupProject(ProjectExplorer::Project*)));
892     connect(d->m_session, SIGNAL(startupProjectChanged(ProjectExplorer::Project*)),
893             d->m_targetSelector, SLOT(changeStartupProject(ProjectExplorer::Project*)));
894
895     connect(core, SIGNAL(saveSettingsRequested()),
896         this, SLOT(savePersistentSettings()));
897
898     addAutoReleasedObject(new ProjectTreeWidgetFactory);
899     addAutoReleasedObject(new FolderNavigationWidgetFactory);
900     addAutoReleasedObject(new DeployConfigurationFactory);
901
902     if (QSettings *s = core->settings()) {
903         const QStringList fileNames = s->value("ProjectExplorer/RecentProjects/FileNames").toStringList();
904         const QStringList displayNames = s->value("ProjectExplorer/RecentProjects/DisplayNames").toStringList();
905         if (fileNames.size() == displayNames.size()) {
906             for (int i = 0; i < fileNames.size(); ++i) {
907                 if (QFileInfo(fileNames.at(i)).isFile())
908                     d->m_recentProjects.append(qMakePair(fileNames.at(i), displayNames.at(i)));
909             }
910         }
911     }
912
913     if (QSettings *s = core->settings()) {
914         d->m_projectExplorerSettings.buildBeforeDeploy = s->value("ProjectExplorer/Settings/BuildBeforeDeploy", true).toBool();
915         d->m_projectExplorerSettings.deployBeforeRun = s->value("ProjectExplorer/Settings/DeployBeforeRun", true).toBool();
916         d->m_projectExplorerSettings.saveBeforeBuild = s->value("ProjectExplorer/Settings/SaveBeforeBuild", false).toBool();
917         d->m_projectExplorerSettings.showCompilerOutput = s->value("ProjectExplorer/Settings/ShowCompilerOutput", false).toBool();
918         d->m_projectExplorerSettings.showRunOutput = s->value("ProjectExplorer/Settings/ShowRunOutput", true).toBool();
919         d->m_projectExplorerSettings.cleanOldAppOutput = s->value("ProjectExplorer/Settings/CleanOldAppOutput", false).toBool();
920         d->m_projectExplorerSettings.mergeStdErrAndStdOut = s->value("ProjectExplorer/Settings/MergeStdErrAndStdOut", false).toBool();
921         d->m_projectExplorerSettings.wrapAppOutput = s->value("ProjectExplorer/Settings/WrapAppOutput", true).toBool();
922         d->m_projectExplorerSettings.useJom = s->value("ProjectExplorer/Settings/UseJom", true).toBool();
923         d->m_projectExplorerSettings.autorestoreLastSession = s->value("ProjectExplorer/Settings/AutoRestoreLastSession", false).toBool();
924         d->m_projectExplorerSettings.prompToStopRunControl = s->value("ProjectExplorer/Settings/PromptToStopRunControl", false).toBool();
925         d->m_projectExplorerSettings.maxAppOutputLines = s->value("ProjectExplorer/Settings/MaxAppOutputLines", 100000).toInt();
926         d->m_projectExplorerSettings.environmentId = QUuid(s->value("ProjectExplorer/Settings/EnvironmentId").toString());
927         if (d->m_projectExplorerSettings.environmentId.isNull())
928             d->m_projectExplorerSettings.environmentId = QUuid::createUuid();
929     }
930
931     connect(d->m_sessionManagerAction, SIGNAL(triggered()), this, SLOT(showSessionManager()));
932     connect(d->m_newAction, SIGNAL(triggered()), this, SLOT(newProject()));
933     connect(d->m_loadAction, SIGNAL(triggered()), this, SLOT(loadAction()));
934     connect(d->m_buildProjectOnlyAction, SIGNAL(triggered()), this, SLOT(buildProjectOnly()));
935     connect(d->m_buildAction, SIGNAL(triggered()), this, SLOT(buildProject()));
936     connect(d->m_buildActionContextMenu, SIGNAL(triggered()), this, SLOT(buildProjectContextMenu()));
937     connect(d->m_buildSessionAction, SIGNAL(triggered()), this, SLOT(buildSession()));
938     connect(d->m_rebuildProjectOnlyAction, SIGNAL(triggered()), this, SLOT(rebuildProjectOnly()));
939     connect(d->m_rebuildAction, SIGNAL(triggered()), this, SLOT(rebuildProject()));
940     connect(d->m_rebuildActionContextMenu, SIGNAL(triggered()), this, SLOT(rebuildProjectContextMenu()));
941     connect(d->m_rebuildSessionAction, SIGNAL(triggered()), this, SLOT(rebuildSession()));
942     connect(d->m_deployProjectOnlyAction, SIGNAL(triggered()), this, SLOT(deployProjectOnly()));
943     connect(d->m_deployAction, SIGNAL(triggered()), this, SLOT(deployProject()));
944     connect(d->m_deployActionContextMenu, SIGNAL(triggered()), this, SLOT(deployProjectContextMenu()));
945     connect(d->m_deploySessionAction, SIGNAL(triggered()), this, SLOT(deploySession()));
946     connect(d->m_publishAction, SIGNAL(triggered()), this, SLOT(publishProject()));
947     connect(d->m_cleanProjectOnlyAction, SIGNAL(triggered()), this, SLOT(cleanProjectOnly()));
948     connect(d->m_cleanAction, SIGNAL(triggered()), this, SLOT(cleanProject()));
949     connect(d->m_cleanActionContextMenu, SIGNAL(triggered()), this, SLOT(cleanProjectContextMenu()));
950     connect(d->m_cleanSessionAction, SIGNAL(triggered()), this, SLOT(cleanSession()));
951     connect(d->m_runAction, SIGNAL(triggered()), this, SLOT(runProject()));
952     connect(d->m_runActionContextMenu, SIGNAL(triggered()), this, SLOT(runProjectContextMenu()));
953     connect(d->m_cancelBuildAction, SIGNAL(triggered()), this, SLOT(cancelBuild()));
954     connect(d->m_unloadAction, SIGNAL(triggered()), this, SLOT(unloadProject()));
955     connect(d->m_clearSession, SIGNAL(triggered()), this, SLOT(clearSession()));
956     connect(d->m_addNewFileAction, SIGNAL(triggered()), this, SLOT(addNewFile()));
957     connect(d->m_addExistingFilesAction, SIGNAL(triggered()), this, SLOT(addExistingFiles()));
958     connect(d->m_addNewSubprojectAction, SIGNAL(triggered()), this, SLOT(addNewSubproject()));
959     connect(d->m_removeProjectAction, SIGNAL(triggered()), this, SLOT(removeProject()));
960     connect(d->m_openFileAction, SIGNAL(triggered()), this, SLOT(openFile()));
961     connect(d->m_showInGraphicalShell, SIGNAL(triggered()), this, SLOT(showInGraphicalShell()));
962     connect(d->m_openTerminalHere, SIGNAL(triggered()), this, SLOT(openTerminalHere()));
963     connect(d->m_removeFileAction, SIGNAL(triggered()), this, SLOT(removeFile()));
964     connect(d->m_deleteFileAction, SIGNAL(triggered()), this, SLOT(deleteFile()));
965     connect(d->m_renameFileAction, SIGNAL(triggered()), this, SLOT(renameFile()));
966     connect(d->m_setStartupProjectAction, SIGNAL(triggered()), this, SLOT(setStartupProject()));
967
968     connect(this, SIGNAL(updateRunActions()), this, SLOT(slotUpdateRunActions()));
969
970     updateActions();
971
972     connect(Core::ICore::instance(), SIGNAL(coreAboutToOpen()),
973             this, SLOT(determineSessionToRestoreAtStartup()));
974     connect(Core::ICore::instance(), SIGNAL(coreOpened()), this, SLOT(restoreSession()));
975
976     updateWelcomePage();
977
978     Core::VariableManager *vm = Core::VariableManager::instance();
979     vm->registerVariable(QLatin1String(kCurrentProjectFilePath),
980         tr("Full path of the current project's main file, including file name."));
981     vm->registerVariable(QLatin1String(kCurrentProjectPath),
982         tr("Full path of the current project's main file, excluding file name."));
983     connect(vm, SIGNAL(variableUpdateRequested(QString)),
984             this, SLOT(updateVariable(QString)));
985
986     return true;
987 }
988
989 void ProjectExplorerPlugin::loadAction()
990 {
991     if (debug)
992         qDebug() << "ProjectExplorerPlugin::loadAction";
993
994
995     QString dir = d->m_lastOpenDirectory;
996
997     // for your special convenience, we preselect a pro file if it is
998     // the current file
999     if (Core::IEditor *editor = Core::EditorManager::instance()->currentEditor()) {
1000         if (const Core::IFile *file = editor->file()) {
1001             const QString fn = file->fileName();
1002             const bool isProject = d->m_profileMimeTypes.contains(file->mimeType());
1003             dir = isProject ? fn : QFileInfo(fn).absolutePath();
1004         }
1005     }
1006
1007     QString filename = QFileDialog::getOpenFileName(0, tr("Load Project"),
1008                                                     dir,
1009                                                     d->m_projectFilterString);
1010     if (filename.isEmpty())
1011         return;
1012     openProject(filename);
1013     updateActions();
1014 }
1015
1016 void ProjectExplorerPlugin::unloadProject()
1017 {
1018     if (debug)
1019         qDebug() << "ProjectExplorerPlugin::unloadProject";
1020
1021     Core::IFile *fi = d->m_currentProject->file();
1022
1023     if (!fi || fi->fileName().isEmpty()) //nothing to save?
1024         return;
1025
1026     QList<Core::IFile*> filesToSave;
1027     filesToSave << fi;
1028
1029     // check the number of modified files
1030     int readonlycount = 0;
1031     foreach (const Core::IFile *file, filesToSave) {
1032         if (file->isReadOnly())
1033             ++readonlycount;
1034     }
1035
1036     bool success = false;
1037     if (readonlycount > 0)
1038         success = Core::ICore::instance()->fileManager()->saveModifiedFiles(filesToSave).isEmpty();
1039     else
1040         success = Core::ICore::instance()->fileManager()->saveModifiedFilesSilently(filesToSave).isEmpty();
1041
1042     if (!success)
1043         return;
1044
1045     addToRecentProjects(fi->fileName(), d->m_currentProject->displayName());
1046     d->m_session->removeProject(d->m_currentProject);
1047     updateActions();
1048 }
1049
1050 void ProjectExplorerPlugin::clearSession()
1051 {
1052     if (debug)
1053         qDebug() << "ProjectExplorerPlugin::clearSession";
1054
1055     if (!d->m_session->clear())
1056         return; // Action has been cancelled
1057     updateActions();
1058 }
1059
1060 void ProjectExplorerPlugin::extensionsInitialized()
1061 {
1062     d->m_toolChainManager->restoreToolChains();
1063
1064     d->m_proWindow->extensionsInitialized();
1065     d->m_fileFactories = ProjectFileFactory::createFactories(&d->m_projectFilterString);
1066     foreach (ProjectFileFactory *pf, d->m_fileFactories) {
1067         d->m_profileMimeTypes += pf->mimeTypes();
1068         addAutoReleasedObject(pf);
1069     }
1070     d->m_buildManager->extensionsInitialized();
1071 }
1072
1073 void ProjectExplorerPlugin::loadCustomWizards()
1074 {
1075     // Add custom wizards, for which other plugins might have registered
1076     // class factories
1077     static bool firstTime = true;
1078     if (firstTime) {
1079         firstTime = false;
1080         foreach(Core::IWizard *cpw, ProjectExplorer::CustomWizard::createWizards())
1081             addAutoReleasedObject(cpw);
1082     }
1083 }
1084
1085 void ProjectExplorerPlugin::updateVariable(const QString &variable)
1086 {
1087     if (variable == QLatin1String(kCurrentProjectFilePath)) {
1088         if (currentProject() && currentProject()->file()) {
1089             Core::VariableManager::instance()->insert(variable,
1090                                                       currentProject()->file()->fileName());
1091         } else {
1092             Core::VariableManager::instance()->remove(variable);
1093         }
1094     } else if (variable == QLatin1String(kCurrentProjectPath)) {
1095         if (currentProject() && currentProject()->file()) {
1096             Core::VariableManager::instance()->insert(variable,
1097                                                       QFileInfo(currentProject()->file()->fileName()).path());
1098         } else {
1099             Core::VariableManager::instance()->remove(variable);
1100         }
1101     }
1102 }
1103
1104 ExtensionSystem::IPlugin::ShutdownFlag ProjectExplorerPlugin::aboutToShutdown()
1105 {
1106     d->m_proWindow->aboutToShutdown(); // disconnect from session
1107     d->m_session->clear();
1108     d->m_projectsMode = 0;
1109     // Attempt to synchronously shutdown all run controls.
1110     // If that fails, fall back to asynchronous shutdown (Debugger run controls
1111     // might shutdown asynchronously).
1112     if (d->m_outputPane->closeTabs(AppOutputPane::CloseTabNoPrompt /* No prompt any more */))
1113         return SynchronousShutdown;
1114     connect(d->m_outputPane, SIGNAL(allRunControlsFinished()),
1115             this, SIGNAL(asynchronousShutdownFinished()));
1116     return AsynchronousShutdown;
1117 }
1118
1119 void ProjectExplorerPlugin::newProject()
1120 {
1121     if (debug)
1122         qDebug() << "ProjectExplorerPlugin::newProject";
1123
1124     Core::ICore::instance()->showNewItemDialog(tr("New Project", "Title of dialog"),
1125                               Core::IWizard::wizardsOfKind(Core::IWizard::ProjectWizard));
1126     updateActions();
1127 }
1128
1129 void ProjectExplorerPlugin::showSessionManager()
1130 {
1131     if (debug)
1132         qDebug() << "ProjectExplorerPlugin::showSessionManager";
1133
1134     if (d->m_session->isDefaultVirgin()) {
1135         // do not save new virgin default sessions
1136     } else {
1137         d->m_session->save();
1138     }
1139     SessionDialog sessionDialog(d->m_session);
1140     sessionDialog.setAutoLoadSession(d->m_projectExplorerSettings.autorestoreLastSession);
1141     sessionDialog.exec();
1142     d->m_projectExplorerSettings.autorestoreLastSession = sessionDialog.autoLoadSession();
1143
1144     updateActions();
1145
1146     Core::ModeManager *modeManager = Core::ModeManager::instance();
1147     Core::IMode *welcomeMode = modeManager->mode(Core::Constants::MODE_WELCOME);
1148     if (modeManager->currentMode() == welcomeMode)
1149         updateWelcomePage();
1150 }
1151
1152 void ProjectExplorerPlugin::setStartupProject(Project *project)
1153 {
1154     if (debug)
1155         qDebug() << "ProjectExplorerPlugin::setStartupProject";
1156
1157     if (!project)
1158         return;
1159     d->m_session->setStartupProject(project);
1160     updateActions();
1161 }
1162
1163 void ProjectExplorerPlugin::publishProject()
1164 {
1165     const Project * const project = d->m_session->startupProject();
1166     QTC_ASSERT(project, return);
1167     PublishingWizardSelectionDialog selectionDialog(project);
1168     if (selectionDialog.exec() == QDialog::Accepted) {
1169         QWizard * const publishingWizard
1170             = selectionDialog.createSelectedWizard();
1171         publishingWizard->exec();
1172         delete publishingWizard;
1173     }
1174 }
1175
1176 void ProjectExplorerPlugin::savePersistentSettings()
1177 {
1178     if (debug)
1179         qDebug()<<"ProjectExplorerPlugin::savePersistentSettings()";
1180
1181     foreach (Project *pro, d->m_session->projects())
1182         pro->saveSettings();
1183
1184     if (d->m_session->isDefaultVirgin()) {
1185         // do not save new virgin default sessions
1186     } else {
1187         d->m_session->save();
1188     }
1189
1190     QSettings *s = Core::ICore::instance()->settings();
1191     if (s) {
1192         s->setValue("ProjectExplorer/StartupSession", d->m_session->currentSession());
1193         s->remove("ProjectExplorer/RecentProjects/Files");
1194
1195         QStringList fileNames;
1196         QStringList displayNames;
1197         QList<QPair<QString, QString> >::const_iterator it, end;
1198         end = d->m_recentProjects.constEnd();
1199         for (it = d->m_recentProjects.constBegin(); it != end; ++it) {
1200             fileNames << (*it).first;
1201             displayNames << (*it).second;
1202         }
1203
1204         s->setValue("ProjectExplorer/RecentProjects/FileNames", fileNames);
1205         s->setValue("ProjectExplorer/RecentProjects/DisplayNames", displayNames);
1206
1207         s->setValue("ProjectExplorer/Settings/BuildBeforeDeploy", d->m_projectExplorerSettings.buildBeforeDeploy);
1208         s->setValue("ProjectExplorer/Settings/DeployBeforeRun", d->m_projectExplorerSettings.deployBeforeRun);
1209         s->setValue("ProjectExplorer/Settings/SaveBeforeBuild", d->m_projectExplorerSettings.saveBeforeBuild);
1210         s->setValue("ProjectExplorer/Settings/ShowCompilerOutput", d->m_projectExplorerSettings.showCompilerOutput);
1211         s->setValue("ProjectExplorer/Settings/ShowRunOutput", d->m_projectExplorerSettings.showRunOutput);
1212         s->setValue("ProjectExplorer/Settings/CleanOldAppOutput", d->m_projectExplorerSettings.cleanOldAppOutput);
1213         s->setValue("ProjectExplorer/Settings/MergeStdErrAndStdOut", d->m_projectExplorerSettings.mergeStdErrAndStdOut);
1214         s->setValue("ProjectExplorer/Settings/WrapAppOutput", d->m_projectExplorerSettings.wrapAppOutput);
1215         s->setValue("ProjectExplorer/Settings/UseJom", d->m_projectExplorerSettings.useJom);
1216         s->setValue("ProjectExplorer/Settings/AutoRestoreLastSession", d->m_projectExplorerSettings.autorestoreLastSession);
1217         s->setValue("ProjectExplorer/Settings/PromptToStopRunControl", d->m_projectExplorerSettings.prompToStopRunControl);
1218         s->setValue("ProjectExplorer/Settings/MaxAppOutputLines", d->m_projectExplorerSettings.maxAppOutputLines);
1219         s->setValue("ProjectExplorer/Settings/EnvironmentId", d->m_projectExplorerSettings.environmentId.toString());
1220     }
1221 }
1222
1223 bool ProjectExplorerPlugin::openProject(const QString &fileName)
1224 {
1225     if (debug)
1226         qDebug() << "ProjectExplorerPlugin::openProject";
1227
1228     QList<Project *> list = openProjects(QStringList() << fileName);
1229     if (!list.isEmpty()) {
1230         addToRecentProjects(fileName, list.first()->displayName());
1231         d->m_session->setStartupProject(list.first());
1232         return true;
1233     }
1234     return false;
1235 }
1236
1237 static inline QList<IProjectManager*> allProjectManagers()
1238 {
1239     ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
1240     return pm->getObjects<IProjectManager>();
1241 }
1242
1243 QList<Project *> ProjectExplorerPlugin::openProjects(const QStringList &fileNames)
1244 {
1245     if (debug)
1246         qDebug() << "ProjectExplorerPlugin - opening projects " << fileNames;
1247
1248     const QList<IProjectManager*> projectManagers = allProjectManagers();
1249
1250     QList<Project*> openedPro;
1251     foreach (const QString &fileName, fileNames) {
1252         if (const Core::MimeType mt = Core::ICore::instance()->mimeDatabase()->findByFile(QFileInfo(fileName))) {
1253             foreach (IProjectManager *manager, projectManagers) {
1254                 if (manager->mimeType() == mt.type()) {
1255                     if (Project *pro = manager->openProject(fileName)) {
1256                         if (pro->restoreSettings()) {
1257                             connect(pro, SIGNAL(fileListChanged()), this, SIGNAL(fileListChanged()));
1258                             d->m_session->addProject(pro);
1259                             // Make sure we always have a current project / node
1260                             if (!d->m_currentProject && !openedPro.isEmpty())
1261                                 setCurrentNode(pro->rootProjectNode());
1262                             openedPro += pro;
1263                         } else {
1264                             delete pro;
1265                         }
1266                     }
1267                     d->m_session->reportProjectLoadingProgress();
1268                     break;
1269                 }
1270             }
1271         }
1272     }
1273     updateActions();
1274
1275     if (!openedPro.isEmpty())
1276         Core::ModeManager::instance()->activateMode(Core::Constants::MODE_EDIT);
1277
1278     return openedPro;
1279 }
1280
1281 Project *ProjectExplorerPlugin::currentProject() const
1282 {
1283     if (debug) {
1284         if (d->m_currentProject)
1285             qDebug() << "ProjectExplorerPlugin::currentProject returns " << d->m_currentProject->displayName();
1286         else
1287             qDebug() << "ProjectExplorerPlugin::currentProject returns 0";
1288     }
1289     return d->m_currentProject;
1290 }
1291
1292 Node *ProjectExplorerPlugin::currentNode() const
1293 {
1294     return d->m_currentNode;
1295 }
1296
1297 void ProjectExplorerPlugin::setCurrentFile(Project *project, const QString &filePath)
1298 {
1299     setCurrent(project, filePath, 0);
1300 }
1301
1302 void ProjectExplorerPlugin::setCurrentFile(const QString &filePath)
1303 {
1304     Project *project = d->m_session->projectForFile(filePath);
1305     // If the file is not in any project, stay with the current project
1306     // e.g. on opening a git diff buffer, git log buffer, we don't change the project
1307     // I'm not 100% sure this is correct
1308     if (!project)
1309         project = d->m_currentProject;
1310     setCurrent(project, filePath, 0);
1311 }
1312
1313 void ProjectExplorerPlugin::setCurrentNode(Node *node)
1314 {
1315     setCurrent(d->m_session->projectForNode(node), QString(), node);
1316 }
1317
1318 SessionManager *ProjectExplorerPlugin::session() const
1319 {
1320     return d->m_session;
1321 }
1322
1323 Project *ProjectExplorerPlugin::startupProject() const
1324 {
1325     if (debug)
1326         qDebug() << "ProjectExplorerPlugin::startupProject";
1327
1328     return d->m_session->startupProject();
1329 }
1330
1331 void ProjectExplorerPlugin::updateWelcomePage()
1332 {
1333     d->m_welcomePage->reloadWelcomeScreenData();
1334 }
1335
1336 void ProjectExplorerPlugin::currentModeChanged(Core::IMode *mode, Core::IMode *oldMode)
1337 {
1338     if (mode && mode->id() == Core::Id(Core::Constants::MODE_WELCOME))
1339         updateWelcomePage();
1340     if (oldMode == d->m_projectsMode)
1341         savePersistentSettings();
1342 }
1343
1344 void ProjectExplorerPlugin::determineSessionToRestoreAtStartup()
1345 {
1346     QStringList arguments = ExtensionSystem::PluginManager::instance()->arguments();
1347     // Process command line arguments first:
1348     if (arguments.contains("-lastsession"))
1349         d->m_sessionToRestoreAtStartup = d->m_session->lastSession();
1350     if (d->m_sessionToRestoreAtStartup.isNull()) {
1351         QStringList sessions = d->m_session->sessions();
1352         // We have command line arguments, try to find a session in them
1353         // Default to no session loading
1354         foreach (const QString &arg, arguments) {
1355             if (sessions.contains(arg)) {
1356                 // Session argument
1357                 d->m_sessionToRestoreAtStartup = arg;
1358                 break;
1359             }
1360         }
1361     }
1362     // Handle settings only after command line arguments:
1363     if (d->m_sessionToRestoreAtStartup.isNull()
1364         && d->m_projectExplorerSettings.autorestoreLastSession)
1365         d->m_sessionToRestoreAtStartup = d->m_session->lastSession();
1366
1367     if (!d->m_sessionToRestoreAtStartup.isNull())
1368         Core::ICore::instance()->modeManager()->activateMode(Core::Constants::MODE_EDIT);
1369 }
1370
1371 /*!
1372     \fn void ProjectExplorerPlugin::restoreSession()
1373
1374     This method is connected to the ICore::coreOpened signal.  If
1375     there was no session explicitly loaded, it creates an empty new
1376     default session and puts the list of recent projects and sessions
1377     onto the welcome page.
1378 */
1379 void ProjectExplorerPlugin::restoreSession()
1380 {
1381     if (debug)
1382         qDebug() << "ProjectExplorerPlugin::restoreSession";
1383
1384     // We have command line arguments, try to find a session in them
1385     QStringList arguments = ExtensionSystem::PluginManager::instance()->arguments();
1386     arguments.removeOne(d->m_sessionToRestoreAtStartup);
1387
1388     // Restore latest session or what was passed on the command line
1389     if (d->m_sessionToRestoreAtStartup.isEmpty()) {
1390         d->m_session->createAndLoadNewDefaultSession();
1391     } else {
1392         d->m_session->loadSession(d->m_sessionToRestoreAtStartup);
1393     }
1394
1395     // update welcome page
1396     Core::ModeManager *modeManager = Core::ModeManager::instance();
1397     connect(modeManager, SIGNAL(currentModeChanged(Core::IMode*, Core::IMode*)),
1398             this, SLOT(currentModeChanged(Core::IMode*, Core::IMode*)));
1399     connect(d->m_welcomePage, SIGNAL(requestSession(QString)), this, SLOT(loadSession(QString)));
1400     connect(d->m_welcomePage, SIGNAL(requestProject(QString)), this, SLOT(openProject(QString)));
1401
1402     QStringList combinedList;
1403     // Converts "filename" "+45" or "filename" ":23"
1404     // into     "filename+45"   and "filename:23"
1405     foreach (const QString &str, arguments) {
1406         if (!combinedList.isEmpty() && (str.startsWith(QLatin1Char('+'))
1407                                         || str.startsWith(QLatin1Char(':')))) {
1408             combinedList.last().append(str);
1409         } else {
1410             combinedList << str;
1411         }
1412     }
1413
1414     Core::ICore::instance()->openFiles(combinedList, Core::ICore::OpenFilesFlags(Core::ICore::CanContainLineNumbers | Core::ICore::SwitchMode));
1415     updateActions();
1416
1417 }
1418
1419 void ProjectExplorerPlugin::loadSession(const QString &session)
1420 {
1421     if (debug)
1422         qDebug() << "ProjectExplorerPlugin::loadSession" << session;
1423     d->m_session->loadSession(session);
1424 }
1425
1426
1427 void ProjectExplorerPlugin::showContextMenu(QWidget *view, const QPoint &globalPos, Node *node)
1428 {
1429     QMenu *contextMenu = 0;
1430
1431     if (!node)
1432         node = d->m_session->sessionNode();
1433
1434     if (node->nodeType() != SessionNodeType) {
1435         Project *project = d->m_session->projectForNode(node);
1436         setCurrentNode(node);
1437
1438         emit aboutToShowContextMenu(project, node);
1439         switch (node->nodeType()) {
1440         case ProjectNodeType:
1441             if (node->parentFolderNode() == d->m_session->sessionNode())
1442                 contextMenu = d->m_projectMenu;
1443             else
1444                 contextMenu = d->m_subProjectMenu;
1445             break;
1446         case FolderNodeType:
1447             contextMenu = d->m_folderMenu;
1448             break;
1449         case FileNodeType:
1450             populateOpenWithMenu();
1451             contextMenu = d->m_fileMenu;
1452             break;
1453         default:
1454             qWarning("ProjectExplorerPlugin::showContextMenu - Missing handler for node type");
1455         }
1456     } else { // session item
1457         emit aboutToShowContextMenu(0, node);
1458
1459         contextMenu = d->m_sessionContextMenu;
1460     }
1461
1462     updateContextMenuActions();
1463     d->m_projectTreeCollapseAllAction->disconnect(SIGNAL(triggered()));
1464     connect(d->m_projectTreeCollapseAllAction, SIGNAL(triggered()), view, SLOT(collapseAll()));
1465     if (contextMenu && contextMenu->actions().count() > 0) {
1466         contextMenu->popup(globalPos);
1467     }
1468 }
1469
1470 BuildManager *ProjectExplorerPlugin::buildManager() const
1471 {
1472     return d->m_buildManager;
1473 }
1474
1475 void ProjectExplorerPlugin::buildStateChanged(Project * pro)
1476 {
1477     if (debug) {
1478         qDebug() << "buildStateChanged";
1479         qDebug() << pro->file()->fileName() << "isBuilding()" << d->m_buildManager->isBuilding(pro);
1480     }
1481     Q_UNUSED(pro)
1482     updateActions();
1483 }
1484
1485 void ProjectExplorerPlugin::executeRunConfiguration(RunConfiguration *runConfiguration, const QString &runMode)
1486 {
1487     if (IRunControlFactory *runControlFactory = findRunControlFactory(runConfiguration, runMode)) {
1488         emit aboutToExecuteProject(runConfiguration->target()->project(), runMode);
1489
1490         RunControl *control = runControlFactory->create(runConfiguration, runMode);
1491         if (!control)
1492             return;
1493         startRunControl(control, runMode);
1494     }
1495 }
1496
1497 void ProjectExplorerPlugin::startRunControl(RunControl *runControl, const QString &runMode)
1498 {
1499     d->m_outputPane->createNewOutputWindow(runControl);
1500     if (runMode == ProjectExplorer::Constants::RUNMODE && d->m_projectExplorerSettings.showRunOutput)
1501         d->m_outputPane->popup(false);
1502     d->m_outputPane->showTabFor(runControl);
1503     connect(runControl, SIGNAL(finished()), this, SLOT(runControlFinished()));
1504     runControl->start();
1505     emit updateRunActions();
1506 }
1507
1508 QList<RunControl *> ProjectExplorerPlugin::runControls() const
1509 {
1510     return d->m_outputPane->runControls();
1511 }
1512
1513 void ProjectExplorerPlugin::buildQueueFinished(bool success)
1514 {
1515     if (debug)
1516         qDebug() << "buildQueueFinished()" << success;
1517
1518     updateActions();
1519
1520     if (success && d->m_delayedRunConfiguration) {
1521         executeRunConfiguration(d->m_delayedRunConfiguration, d->m_runMode);
1522     } else {
1523         if (d->m_buildManager->tasksAvailable())
1524             d->m_buildManager->showTaskWindow();
1525     }
1526     d->m_delayedRunConfiguration = 0;
1527     d->m_runMode.clear();
1528 }
1529
1530 void ProjectExplorerPlugin::setCurrent(Project *project, QString filePath, Node *node)
1531 {
1532     if (debug)
1533         qDebug() << "ProjectExplorer - setting path to " << (node ? node->path() : filePath)
1534                 << " and project to " << (project ? project->displayName() : "0");
1535
1536     if (node)
1537         filePath = node->path();
1538     else
1539         node = d->m_session->nodeForFile(filePath, project);
1540
1541     Core::ICore *core = Core::ICore::instance();
1542
1543     bool projectChanged = false;
1544     if (d->m_currentProject != project) {
1545         Core::Context oldContext;
1546         Core::Context newContext;
1547
1548         if (d->m_currentProject) {
1549             oldContext.add(d->m_currentProject->projectContext());
1550             oldContext.add(d->m_currentProject->projectLanguage());
1551         }
1552         if (project) {
1553             newContext.add(project->projectContext());
1554             newContext.add(project->projectLanguage());
1555         }
1556
1557         core->updateAdditionalContexts(oldContext, newContext);
1558
1559         d->m_currentProject = project;
1560
1561         projectChanged = true;
1562     }
1563
1564     if (projectChanged || d->m_currentNode != node) {
1565         d->m_currentNode = node;
1566         if (debug)
1567             qDebug() << "ProjectExplorer - currentNodeChanged(" << (node ? node->path() : "0") << ", " << (project ? project->displayName() : "0") << ")";
1568         emit currentNodeChanged(d->m_currentNode, project);
1569         updateContextMenuActions();
1570     }
1571     if (projectChanged) {
1572         if (debug)
1573             qDebug() << "ProjectExplorer - currentProjectChanged(" << (project ? project->displayName() : "0") << ")";
1574         emit currentProjectChanged(project);
1575         updateActions();
1576     }
1577
1578     core->fileManager()->setCurrentFile(filePath);
1579 }
1580
1581 void ProjectExplorerPlugin::updateActions()
1582 {
1583     if (debug)
1584         qDebug() << "ProjectExplorerPlugin::updateActions";
1585
1586     QPair<bool, QString> buildActionState = buildSettingsEnabled(startupProject());
1587     QPair<bool, QString> buildActionContextState = buildSettingsEnabled(d->m_currentProject);
1588     QPair<bool, QString> buildSessionState = buildSettingsEnabledForSession();
1589
1590     Project *project = startupProject();
1591     QString projectName = project ? project->displayName() : QString();
1592     QString projectNameContextMenu = d->m_currentProject ? d->m_currentProject->displayName() : QString();
1593
1594     d->m_unloadAction->setParameter(projectNameContextMenu);
1595
1596     // Normal actions
1597     d->m_buildAction->setParameter(projectName);
1598     d->m_rebuildAction->setParameter(projectName);
1599     d->m_cleanAction->setParameter(projectName);
1600
1601     d->m_buildAction->setEnabled(buildActionState.first);
1602     d->m_rebuildAction->setEnabled(buildActionState.first);
1603     d->m_cleanAction->setEnabled(buildActionState.first);
1604
1605     d->m_buildAction->setToolTip(buildActionState.second);
1606     d->m_rebuildAction->setToolTip(buildActionState.second);
1607     d->m_cleanAction->setToolTip(buildActionState.second);
1608
1609     // Context menu actions
1610     d->m_buildActionContextMenu->setParameter(projectNameContextMenu);
1611     d->m_rebuildActionContextMenu->setParameter(projectNameContextMenu);
1612     d->m_cleanActionContextMenu->setParameter(projectNameContextMenu);
1613
1614     d->m_buildActionContextMenu->setEnabled(buildActionContextState.first);
1615     d->m_rebuildActionContextMenu->setEnabled(buildActionContextState.first);
1616     d->m_cleanActionContextMenu->setEnabled(buildActionContextState.first);
1617
1618     d->m_buildActionContextMenu->setToolTip(buildActionState.second);
1619     d->m_rebuildActionContextMenu->setToolTip(buildActionState.second);
1620     d->m_cleanActionContextMenu->setToolTip(buildActionState.second);
1621
1622     // build project only
1623     d->m_buildProjectOnlyAction->setEnabled(buildActionState.first);
1624     d->m_rebuildProjectOnlyAction->setEnabled(buildActionState.first);
1625     d->m_cleanProjectOnlyAction->setEnabled(buildActionState.first);
1626
1627     d->m_buildProjectOnlyAction->setToolTip(buildActionState.second);
1628     d->m_rebuildProjectOnlyAction->setToolTip(buildActionState.second);
1629     d->m_cleanProjectOnlyAction->setToolTip(buildActionState.second);
1630
1631     // Session actions
1632     d->m_clearSession->setEnabled(!d->m_session->projects().isEmpty());
1633
1634     d->m_buildSessionAction->setEnabled(buildSessionState.first);
1635     d->m_rebuildSessionAction->setEnabled(buildSessionState.first);
1636     d->m_cleanSessionAction->setEnabled(buildSessionState.first);
1637
1638     d->m_buildSessionAction->setToolTip(buildSessionState.second);
1639     d->m_rebuildSessionAction->setToolTip(buildSessionState.second);
1640     d->m_cleanSessionAction->setToolTip(buildSessionState.second);
1641
1642     d->m_cancelBuildAction->setEnabled(d->m_buildManager->isBuilding());
1643
1644     d->m_publishAction->setEnabled(!d->m_session->projects().isEmpty());
1645
1646     d->m_projectSelectorAction->setEnabled(!session()->projects().isEmpty());
1647     d->m_projectSelectorActionMenu->setEnabled(!session()->projects().isEmpty());
1648
1649     updateDeployActions();
1650 }
1651
1652 // NBS TODO check projectOrder()
1653 // what we want here is all the projects pro depends on
1654 QStringList ProjectExplorerPlugin::allFilesWithDependencies(Project *pro)
1655 {
1656     if (debug)
1657         qDebug() << "ProjectExplorerPlugin::allFilesWithDependencies(" << pro->file()->fileName() << ")";
1658
1659     QStringList filesToSave;
1660     foreach (Project *p, d->m_session->projectOrder(pro)) {
1661         FindAllFilesVisitor filesVisitor;
1662         p->rootProjectNode()->accept(&filesVisitor);
1663         filesToSave << filesVisitor.filePaths();
1664     }
1665     qSort(filesToSave);
1666     return filesToSave;
1667 }
1668
1669 bool ProjectExplorerPlugin::saveModifiedFiles()
1670 {
1671     if (debug)
1672         qDebug() << "ProjectExplorerPlugin::saveModifiedFiles";
1673
1674     QList<Core::IFile *> filesToSave = Core::ICore::instance()->fileManager()->modifiedFiles();
1675     if (!filesToSave.isEmpty()) {
1676         if (d->m_projectExplorerSettings.saveBeforeBuild) {
1677             Core::ICore::instance()->fileManager()->saveModifiedFilesSilently(filesToSave);
1678         } else {
1679             bool cancelled = false;
1680             bool alwaysSave = false;
1681
1682             Core::FileManager *fm = Core::ICore::instance()->fileManager();
1683             fm->saveModifiedFiles(filesToSave, &cancelled, QString(),
1684                                   tr("Always save files before build"), &alwaysSave);
1685
1686             if (cancelled)
1687                 return false;
1688             if (alwaysSave)
1689                 d->m_projectExplorerSettings.saveBeforeBuild = true;
1690         }
1691     }
1692     return true;
1693 }
1694
1695 //NBS handle case where there is no activeBuildConfiguration
1696 // because someone delete all build configurations
1697
1698 void ProjectExplorerPlugin::deploy(QList<Project *> projects)
1699 {
1700     QStringList steps;
1701     if (d->m_projectExplorerSettings.buildBeforeDeploy)
1702         steps << Constants::BUILDSTEPS_BUILD;
1703     steps << Constants::BUILDSTEPS_DEPLOY;
1704     queue(projects, steps);
1705 }
1706
1707 int ProjectExplorerPlugin::queue(QList<Project *> projects, QStringList stepIds)
1708 {
1709     if (debug) {
1710         QStringList projectNames;
1711         foreach (const Project *p, projects)
1712             projectNames << p->displayName();
1713         qDebug() << "Building" << stepIds << "for projects" << projectNames;
1714     }
1715
1716     if (!saveModifiedFiles())
1717         return -1;
1718
1719     QList<BuildStepList *> stepLists;
1720     foreach (const QString id, stepIds) {
1721         foreach (Project *pro, projects) {
1722             if (!pro || !pro->activeTarget())
1723                 continue;
1724             BuildStepList *bsl = 0;
1725             if (id == Core::Id(Constants::BUILDSTEPS_DEPLOY)
1726                 && pro->activeTarget()->activeDeployConfiguration())
1727                 bsl = pro->activeTarget()->activeDeployConfiguration()->stepList();
1728             else if (pro->activeTarget()->activeBuildConfiguration())
1729                 bsl = pro->activeTarget()->activeBuildConfiguration()->stepList(id);
1730
1731             if (!bsl || bsl->isEmpty())
1732                 continue;
1733             stepLists << bsl;
1734         }
1735     }
1736
1737     if (stepLists.isEmpty())
1738         return 0;
1739     if (!d->m_buildManager->buildLists(stepLists))
1740         return -1;
1741     return stepLists.count();
1742 }
1743
1744 void ProjectExplorerPlugin::buildProjectOnly()
1745 {
1746     queue(QList<Project *>() << session()->startupProject(), QStringList() << Constants::BUILDSTEPS_BUILD);
1747 }
1748
1749 void ProjectExplorerPlugin::buildProject(ProjectExplorer::Project *p)
1750 {
1751     queue(d->m_session->projectOrder(p),
1752           QStringList() << Constants::BUILDSTEPS_BUILD);
1753 }
1754
1755 void ProjectExplorerPlugin::buildProject()
1756 {
1757     queue(d->m_session->projectOrder(session()->startupProject()),
1758           QStringList() << Constants::BUILDSTEPS_BUILD);
1759 }
1760
1761 void ProjectExplorerPlugin::buildProjectContextMenu()
1762 {
1763     queue(d->m_session->projectOrder(d->m_currentProject),
1764           QStringList() << Constants::BUILDSTEPS_BUILD);
1765 }
1766
1767 void ProjectExplorerPlugin::buildSession()
1768 {
1769     queue(d->m_session->projectOrder(),
1770           QStringList() << Constants::BUILDSTEPS_BUILD);
1771 }
1772
1773 void ProjectExplorerPlugin::rebuildProjectOnly()
1774 {
1775     queue(QList<Project *>() << session()->startupProject(),
1776           QStringList() << Constants::BUILDSTEPS_CLEAN << Constants::BUILDSTEPS_BUILD);
1777 }
1778
1779 void ProjectExplorerPlugin::rebuildProject()
1780 {
1781     queue(d->m_session->projectOrder(session()->startupProject()),
1782           QStringList() << Constants::BUILDSTEPS_CLEAN << Constants::BUILDSTEPS_BUILD);
1783 }
1784
1785 void ProjectExplorerPlugin::rebuildProjectContextMenu()
1786 {
1787     queue(d->m_session->projectOrder(d->m_currentProject),
1788           QStringList() << Constants::BUILDSTEPS_CLEAN << Constants::BUILDSTEPS_BUILD);
1789 }
1790
1791 void ProjectExplorerPlugin::rebuildSession()
1792 {
1793     queue(d->m_session->projectOrder(),
1794           QStringList() << Constants::BUILDSTEPS_CLEAN << Constants::BUILDSTEPS_BUILD);
1795 }
1796
1797 void ProjectExplorerPlugin::deployProjectOnly()
1798 {
1799     deploy(QList<Project *>() << session()->startupProject());
1800 }
1801
1802 void ProjectExplorerPlugin::deployProject()
1803 {
1804     deploy(d->m_session->projectOrder(session()->startupProject()));
1805 }
1806
1807 void ProjectExplorerPlugin::deployProjectContextMenu()
1808 {
1809     deploy(d->m_session->projectOrder(d->m_currentProject));
1810 }
1811
1812 void ProjectExplorerPlugin::deploySession()
1813 {
1814     deploy(d->m_session->projectOrder());
1815 }
1816
1817 void ProjectExplorerPlugin::cleanProjectOnly()
1818 {
1819     queue(QList<Project *>() << session()->startupProject(),
1820           QStringList() << Constants::BUILDSTEPS_CLEAN);
1821 }
1822
1823 void ProjectExplorerPlugin::cleanProject()
1824 {
1825     queue(d->m_session->projectOrder(session()->startupProject()),
1826           QStringList() << Constants::BUILDSTEPS_CLEAN);
1827 }
1828
1829 void ProjectExplorerPlugin::cleanProjectContextMenu()
1830 {
1831     queue(d->m_session->projectOrder(d->m_currentProject),
1832           QStringList() << Constants::BUILDSTEPS_CLEAN);
1833 }
1834
1835 void ProjectExplorerPlugin::cleanSession()
1836 {
1837     queue(d->m_session->projectOrder(),
1838           QStringList() << Constants::BUILDSTEPS_CLEAN);
1839 }
1840
1841 void ProjectExplorerPlugin::runProject()
1842 {
1843     runProject(startupProject(), ProjectExplorer::Constants::RUNMODE);
1844 }
1845
1846 void ProjectExplorerPlugin::runProjectContextMenu()
1847 {
1848     ProjectNode *projectNode = qobject_cast<ProjectNode*>(d->m_currentNode);
1849     if (projectNode == d->m_currentProject->rootProjectNode() || !projectNode) {
1850         runProject(d->m_currentProject, ProjectExplorer::Constants::RUNMODE);
1851     } else {
1852         QAction *act = qobject_cast<QAction *>(sender());
1853         if (!act)
1854             return;
1855         RunConfiguration *rc = act->data().value<RunConfiguration *>();
1856         if (!rc)
1857             return;
1858         runRunConfiguration(rc, ProjectExplorer::Constants::RUNMODE);
1859     }
1860 }
1861
1862 bool ProjectExplorerPlugin::hasBuildSettings(Project *pro)
1863 {
1864     const QList<Project *> & projects = d->m_session->projectOrder(pro);
1865     foreach(Project *project, projects)
1866         if (project
1867                 && project->activeTarget()
1868                 && project->activeTarget()->activeBuildConfiguration())
1869             return true;
1870     return false;
1871 }
1872
1873 QPair<bool, QString> ProjectExplorerPlugin::buildSettingsEnabled(Project *pro)
1874 {
1875     QPair<bool, QString> result;
1876     result.first = true;
1877     if (!pro) {
1878         result.first = false;
1879         result.second = tr("No project loaded");
1880     } else if (d->m_buildManager->isBuilding(pro)) {
1881         result.first = false;
1882         result.second = tr("Currently building the active project");
1883     } else if (!hasBuildSettings(pro)) {
1884         result.first = false;
1885         result.second = tr("Project has no build settings");
1886     } else {
1887         const QList<Project *> & projects = d->m_session->projectOrder(pro);
1888         foreach(Project *project, projects) {
1889             if (project
1890                     && project->activeTarget()
1891                     && project->activeTarget()->activeBuildConfiguration()
1892                     && !project->activeTarget()->activeBuildConfiguration()->isEnabled()) {
1893                 result.first = false;
1894                 result.second += tr("Building '%1' is disabled: %2<br>")
1895                         .arg(project->displayName(),
1896                              project->activeTarget()->activeBuildConfiguration()->disabledReason());
1897             }
1898         }
1899     }
1900     return result;
1901 }
1902
1903 QPair<bool, QString> ProjectExplorerPlugin::buildSettingsEnabledForSession()
1904 {
1905     QPair<bool, QString> result;
1906     result.first = true;
1907     if (d->m_session->projects().isEmpty()) {
1908         result.first = false;
1909         result.second = tr("No project loaded");
1910     } else if (d->m_buildManager->isBuilding()) {
1911         result.first = false;
1912         result.second = tr("A build is in progress");
1913     } else if (!hasBuildSettings(0)) {
1914         result.first = false;
1915         result.second = tr("Project has no build settings");
1916     } else {
1917         const QList<Project *> & projects = d->m_session->projectOrder(0);
1918         foreach(Project *project, projects) {
1919             if (project
1920                     && project->activeTarget()
1921                     && project->activeTarget()->activeBuildConfiguration()
1922                     && !project->activeTarget()->activeBuildConfiguration()->isEnabled()) {
1923                 result.first = false;
1924                 result.second += tr("Building '%1' is disabled: %2\n")
1925                         .arg(project->displayName(),
1926                              project->activeTarget()->activeBuildConfiguration()->disabledReason());
1927             }
1928         }
1929     }
1930     return result;
1931 }
1932
1933 bool ProjectExplorerPlugin::coreAboutToClose()
1934 {
1935     if (d->m_buildManager->isBuilding()) {
1936         QMessageBox box;
1937         QPushButton *closeAnyway = box.addButton(tr("Cancel Build && Close"), QMessageBox::AcceptRole);
1938         QPushButton *cancelClose = box.addButton(tr("Do Not Close"), QMessageBox::RejectRole);
1939         box.setDefaultButton(cancelClose);
1940         box.setWindowTitle(tr("Close Qt Creator?"));
1941         box.setText(tr("A project is currently being built."));
1942         box.setInformativeText(tr("Do you want to cancel the build process and close Qt Creator anyway?"));
1943         box.exec();
1944         if (box.clickedButton() != closeAnyway)
1945             return false;
1946     }
1947     if (!d->m_outputPane->aboutToClose())
1948         return false;
1949     return true;
1950 }
1951
1952 bool ProjectExplorerPlugin::hasDeploySettings(Project *pro)
1953 {
1954     const QList<Project *> & projects = d->m_session->projectOrder(pro);
1955     foreach(Project *project, projects)
1956         if (project->activeTarget()->activeDeployConfiguration() &&
1957                 !project->activeTarget()->activeDeployConfiguration()->stepList()->isEmpty())
1958             return true;
1959     return false;
1960 }
1961
1962 void ProjectExplorerPlugin::runProject(Project *pro, const QString &mode)
1963 {
1964     if (!pro)
1965         return;
1966
1967     runRunConfiguration(pro->activeTarget()->activeRunConfiguration(), mode);
1968 }
1969
1970 void ProjectExplorerPlugin::runRunConfiguration(ProjectExplorer::RunConfiguration *rc, const QString &mode)
1971 {
1972     if (!rc->isEnabled())
1973         return;
1974
1975     QStringList stepIds;
1976     if (d->m_projectExplorerSettings.deployBeforeRun) {
1977         if (d->m_projectExplorerSettings.buildBeforeDeploy)
1978             stepIds << Constants::BUILDSTEPS_BUILD;
1979         stepIds << Constants::BUILDSTEPS_DEPLOY;
1980     }
1981
1982     Project *pro = rc->target()->project();
1983     const QList<Project *> &projects = d->m_session->projectOrder(pro);
1984     int queueCount = queue(projects, stepIds);
1985
1986     if (queueCount < 0) // something went wrong
1987         return;
1988
1989     if (queueCount > 0) {
1990         // delay running till after our queued steps were processed
1991         d->m_runMode = mode;
1992         d->m_delayedRunConfiguration = rc;
1993     } else {
1994         executeRunConfiguration(rc, mode);
1995     }
1996     emit updateRunActions();
1997 }
1998
1999 void ProjectExplorerPlugin::runControlFinished()
2000 {
2001     emit updateRunActions();
2002 }
2003
2004 void ProjectExplorerPlugin::projectAdded(ProjectExplorer::Project *pro)
2005 {
2006     // more specific action en and disabling ?
2007     connect(pro, SIGNAL(buildConfigurationEnabledChanged()),
2008             this, SLOT(updateActions()));
2009 }
2010
2011 void ProjectExplorerPlugin::projectRemoved(ProjectExplorer::Project * pro)
2012 {
2013     // more specific action en and disabling ?
2014     disconnect(pro, SIGNAL(buildConfigurationEnabledChanged()),
2015                this, SLOT(updateActions()));
2016 }
2017
2018 void ProjectExplorerPlugin::startupProjectChanged()
2019 {
2020     static QPointer<Project> previousStartupProject = 0;
2021     Project *project = startupProject();
2022     if (project == previousStartupProject)
2023         return;
2024
2025     if (d->m_projectsMode)
2026         d->m_projectsMode->setEnabled(project);
2027
2028     if (previousStartupProject) {
2029         disconnect(previousStartupProject, SIGNAL(activeTargetChanged(ProjectExplorer::Target*)),
2030                    this, SLOT(activeTargetChanged()));
2031     }
2032
2033     previousStartupProject = project;
2034
2035     if (project) {
2036         connect(project, SIGNAL(activeTargetChanged(ProjectExplorer::Target*)),
2037                 this, SLOT(activeTargetChanged()));
2038     }
2039
2040     activeTargetChanged();
2041 }
2042
2043 void ProjectExplorerPlugin::activeTargetChanged()
2044 {
2045     static QPointer<Target> previousTarget = 0;
2046     Target *target = 0;
2047     if (startupProject())
2048         target = startupProject()->activeTarget();
2049     if (target == previousTarget)
2050         return;
2051
2052     if (previousTarget) {
2053         disconnect(previousTarget, SIGNAL(activeRunConfigurationChanged(ProjectExplorer::RunConfiguration*)),
2054                    this, SLOT(activeRunConfigurationChanged()));
2055     }
2056     previousTarget = target;
2057     if (target) {
2058         connect(target, SIGNAL(activeRunConfigurationChanged(ProjectExplorer::RunConfiguration*)),
2059                 this, SLOT(activeRunConfigurationChanged()));
2060     }
2061
2062     updateDeployActions();
2063     activeRunConfigurationChanged();
2064 }
2065
2066 void ProjectExplorerPlugin::activeRunConfigurationChanged()
2067 {
2068     static QPointer<RunConfiguration> previousRunConfiguration = 0;
2069     RunConfiguration *rc = 0;
2070     if (startupProject() && startupProject()->activeTarget())
2071         rc = startupProject()->activeTarget()->activeRunConfiguration();
2072     if (rc == previousRunConfiguration)
2073         return;
2074     if (previousRunConfiguration) {
2075         disconnect(previousRunConfiguration, SIGNAL(isEnabledChanged(bool)),
2076                    this, SIGNAL(updateRunActions()));
2077         disconnect(previousRunConfiguration, SIGNAL(debuggersChanged()),
2078                    this, SIGNAL(updateRunActions()));
2079     }
2080     previousRunConfiguration = rc;
2081     if (rc) {
2082         connect(rc, SIGNAL(isEnabledChanged(bool)),
2083                 this, SIGNAL(updateRunActions()));
2084         connect(rc, SIGNAL(debuggersChanged()),
2085                 this, SIGNAL(updateRunActions()));
2086     }
2087     emit updateRunActions();
2088 }
2089
2090 // NBS TODO implement more than one runner
2091 IRunControlFactory *ProjectExplorerPlugin::findRunControlFactory(RunConfiguration *config, const QString &mode)
2092 {
2093     ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
2094     const QList<IRunControlFactory *> factories = pm->getObjects<IRunControlFactory>();
2095     foreach (IRunControlFactory *f, factories)
2096         if (f->canRun(config, mode))
2097             return f;
2098     return 0;
2099 }
2100
2101 void ProjectExplorerPlugin::updateDeployActions()
2102 {
2103     Project *project = startupProject();
2104
2105     bool enableDeployActions = project
2106             && ! (d->m_buildManager->isBuilding(project))
2107             && hasDeploySettings(project);
2108     bool enableDeployActionsContextMenu = d->m_currentProject
2109                               && ! (d->m_buildManager->isBuilding(d->m_currentProject))
2110                               && hasDeploySettings(d->m_currentProject);
2111
2112     if (d->m_projectExplorerSettings.buildBeforeDeploy) {
2113         if (hasBuildSettings(project)
2114                 && !buildSettingsEnabled(project).first)
2115             enableDeployActions = false;
2116         if (hasBuildSettings(d->m_currentProject)
2117                 && !buildSettingsEnabled(d->m_currentProject).first)
2118             enableDeployActionsContextMenu = false;
2119     }
2120
2121     const QString projectName = project ? project->displayName() : QString();
2122     const QString projectNameContextMenu = d->m_currentProject ? d->m_currentProject->displayName() : QString();
2123     bool hasProjects = !d->m_session->projects().isEmpty();
2124     bool building = d->m_buildManager->isBuilding();
2125
2126     d->m_deployAction->setParameter(projectName);
2127     d->m_deployAction->setEnabled(enableDeployActions);
2128
2129     d->m_deployActionContextMenu->setParameter(projectNameContextMenu);
2130     d->m_deployActionContextMenu->setEnabled(enableDeployActionsContextMenu);
2131
2132     d->m_deployProjectOnlyAction->setEnabled(enableDeployActions);
2133
2134     d->m_deploySessionAction->setEnabled(hasProjects && !building);
2135
2136     emit updateRunActions();
2137 }
2138
2139 bool ProjectExplorerPlugin::canRun(Project *project, const QString &runMode)
2140 {
2141     if (!project ||
2142         !project->activeTarget() ||
2143         !project->activeTarget()->activeRunConfiguration()) {
2144         return false;
2145     }
2146
2147     if (d->m_projectExplorerSettings.buildBeforeDeploy
2148             && d->m_projectExplorerSettings.deployBeforeRun
2149             && hasBuildSettings(project)
2150             && !buildSettingsEnabled(project).first)
2151         return false;
2152
2153
2154     RunConfiguration *activeRC = project->activeTarget()->activeRunConfiguration();
2155
2156     bool canRun = findRunControlFactory(activeRC, runMode)
2157                   && activeRC->isEnabled();
2158     const bool building = d->m_buildManager->isBuilding();
2159     return (canRun && !building);
2160 }
2161
2162 QString ProjectExplorerPlugin::cannotRunReason(Project *project, const QString &runMode)
2163 {
2164     if (!project)
2165         return tr("No active project");
2166
2167     if (!project->activeTarget())
2168         return tr("The project '%1' has no active target").arg(project->displayName());
2169
2170     if (!project->activeTarget()->activeRunConfiguration())
2171         return tr("The target '%1' for project '%2' has no active run configuration")
2172                 .arg(project->activeTarget()->displayName(), project->displayName());
2173
2174
2175     if (d->m_projectExplorerSettings.buildBeforeDeploy
2176             && d->m_projectExplorerSettings.deployBeforeRun
2177             && hasBuildSettings(project)) {
2178         QPair<bool, QString> buildState = buildSettingsEnabled(project);
2179         if (!buildState.first)
2180             return buildState.second;
2181     }
2182
2183
2184     RunConfiguration *activeRC = project->activeTarget()->activeRunConfiguration();
2185     if (!activeRC->isEnabled())
2186         return activeRC->disabledReason();
2187
2188     // shouldn't actually be shown to the user...
2189     if (!findRunControlFactory(activeRC, runMode))
2190         return tr("Cannot run '%1' in mode '%2'.")
2191                 .arg(activeRC->displayName(), runMode);
2192
2193
2194     if (d->m_buildManager->isBuilding())
2195         return tr("A build is still in progress.");
2196     return QString();
2197 }
2198
2199 void ProjectExplorerPlugin::slotUpdateRunActions()
2200 {
2201     Project *project = startupProject();
2202     d->m_runAction->setEnabled(canRun(project, ProjectExplorer::Constants::RUNMODE));
2203     d->m_runAction->setToolTip(cannotRunReason(project, ProjectExplorer::Constants::RUNMODE));
2204 }
2205
2206 void ProjectExplorerPlugin::cancelBuild()
2207 {
2208     if (debug)
2209         qDebug() << "ProjectExplorerPlugin::cancelBuild";
2210
2211     if (d->m_buildManager->isBuilding())
2212         d->m_buildManager->cancel();
2213 }
2214
2215 void ProjectExplorerPlugin::addToRecentProjects(const QString &fileName, const QString &displayName)
2216 {
2217     if (debug)
2218         qDebug() << "ProjectExplorerPlugin::addToRecentProjects(" << fileName << ")";
2219
2220     if (fileName.isEmpty())
2221         return;
2222     QString prettyFileName(QDir::toNativeSeparators(fileName));
2223
2224     QList<QPair<QString, QString> >::iterator it;
2225     for(it = d->m_recentProjects.begin(); it != d->m_recentProjects.end();)
2226         if ((*it).first == prettyFileName)
2227             it = d->m_recentProjects.erase(it);
2228         else
2229             ++it;
2230
2231     if (d->m_recentProjects.count() > d->m_maxRecentProjects)
2232         d->m_recentProjects.removeLast();
2233     d->m_recentProjects.prepend(qMakePair(prettyFileName, displayName));
2234     QFileInfo fi(prettyFileName);
2235     d->m_lastOpenDirectory = fi.absolutePath();
2236     emit recentProjectsChanged();
2237 }
2238
2239 void ProjectExplorerPlugin::updateRecentProjectMenu()
2240 {
2241     typedef QList<QPair<QString, QString> >::const_iterator StringPairListConstIterator;
2242     if (debug)
2243         qDebug() << "ProjectExplorerPlugin::updateRecentProjectMenu";
2244
2245     Core::ActionContainer *aci =
2246         Core::ICore::instance()->actionManager()->actionContainer(Constants::M_RECENTPROJECTS);
2247     QMenu *menu = aci->menu();
2248     menu->clear();
2249
2250     bool hasRecentProjects = false;
2251     //projects (ignore sessions, they used to be in this list)
2252     const StringPairListConstIterator end = d->m_recentProjects.constEnd();
2253     for (StringPairListConstIterator it = d->m_recentProjects.constBegin(); it != end; ++it) {
2254         const QPair<QString, QString> &s = *it;
2255         if (s.first.endsWith(QLatin1String(".qws")))
2256             continue;
2257         QAction *action = menu->addAction(Utils::withTildeHomePath(s.first));
2258         action->setData(s.first);
2259         connect(action, SIGNAL(triggered()), this, SLOT(openRecentProject()));
2260         hasRecentProjects = true;
2261     }
2262     menu->setEnabled(hasRecentProjects);
2263
2264     // add the Clear Menu item
2265     if (hasRecentProjects) {
2266         menu->addSeparator();
2267         QAction *action = menu->addAction(QCoreApplication::translate(
2268                                           "Core", Core::Constants::TR_CLEAR_MENU));
2269         connect(action, SIGNAL(triggered()), this, SLOT(clearRecentProjects()));
2270     }
2271     emit recentProjectsChanged();
2272 }
2273
2274 void ProjectExplorerPlugin::clearRecentProjects()
2275 {
2276     d->m_recentProjects.clear();
2277     updateWelcomePage();
2278 }
2279
2280 void ProjectExplorerPlugin::openRecentProject()
2281 {
2282     if (debug)
2283         qDebug() << "ProjectExplorerPlugin::openRecentProject()";
2284
2285     QAction *a = qobject_cast<QAction*>(sender());
2286     if (!a)
2287         return;
2288     QString fileName = a->data().toString();
2289     if (!fileName.isEmpty()) {
2290         openProject(fileName);
2291     }
2292 }
2293
2294 void ProjectExplorerPlugin::invalidateProject(Project *project)
2295 {
2296     if (debug)
2297         qDebug() << "ProjectExplorerPlugin::invalidateProject" << project->displayName();
2298     if (d->m_currentProject == project) {
2299         //
2300         // Workaround for a bug in QItemSelectionModel
2301         // - currentChanged etc are not emitted if the
2302         // item is removed from the underlying data model
2303         //
2304         setCurrent(0, QString(), 0);
2305     }
2306
2307     disconnect(project, SIGNAL(fileListChanged()), this, SIGNAL(fileListChanged()));
2308     updateActions();
2309 }
2310
2311 void ProjectExplorerPlugin::updateContextMenuActions()
2312 {
2313     d->m_addExistingFilesAction->setEnabled(false);
2314     d->m_addNewFileAction->setEnabled(false);
2315     d->m_addNewSubprojectAction->setEnabled(false);
2316     d->m_removeFileAction->setEnabled(false);
2317     d->m_deleteFileAction->setEnabled(false);
2318     d->m_renameFileAction->setEnabled(false);
2319
2320     d->m_addExistingFilesAction->setVisible(true);
2321     d->m_removeFileAction->setVisible(true);
2322     d->m_deleteFileAction->setVisible(true);
2323     d->m_runActionContextMenu->setVisible(false);
2324
2325     Core::ActionContainer *runMenu = Core::ICore::instance()->actionManager()->actionContainer(Constants::RUNMENUCONTEXTMENU);
2326     runMenu->menu()->clear();
2327
2328     if (d->m_currentNode && d->m_currentNode->projectNode()) {
2329         QList<ProjectNode::ProjectAction> actions =
2330                 d->m_currentNode->projectNode()->supportedActions(d->m_currentNode);
2331
2332         if (ProjectNode *pn = qobject_cast<ProjectNode *>(d->m_currentNode)) {
2333             if (pn == d->m_currentProject->rootProjectNode()) {
2334                 d->m_runActionContextMenu->setVisible(true);
2335             } else {
2336                 QList<RunConfiguration *> runConfigs = pn->runConfigurationsFor(pn);
2337                 if (runConfigs.count() == 1) {
2338                     d->m_runActionContextMenu->setVisible(true);
2339                     d->m_runActionContextMenu->setData(QVariant::fromValue(runConfigs.first()));
2340                 } else if (runConfigs.count() > 1) {
2341                     foreach (RunConfiguration *rc, runConfigs) {
2342                         QAction *act = new QAction(runMenu->menu());
2343                         act->setData(QVariant::fromValue(rc));
2344                         act->setText(QString("Run %1").arg(rc->displayName()));
2345                         runMenu->menu()->addAction(act);
2346                         connect(act, SIGNAL(triggered()),
2347                                 this, SLOT(runProjectContextMenu()));
2348                     }
2349                 }
2350             }
2351         }
2352         if (qobject_cast<FolderNode*>(d->m_currentNode)) {
2353             // Also handles ProjectNode
2354             d->m_addNewFileAction->setEnabled(actions.contains(ProjectNode::AddNewFile));
2355             d->m_addNewSubprojectAction->setEnabled(d->m_currentNode->nodeType() == ProjectNodeType
2356                                                     && actions.contains(ProjectNode::AddSubProject));
2357             d->m_addExistingFilesAction->setEnabled(actions.contains(ProjectNode::AddExistingFile));
2358             d->m_renameFileAction->setEnabled(actions.contains(ProjectNode::Rename));
2359         } else if (qobject_cast<FileNode*>(d->m_currentNode)) {
2360             // Enable and show remove / delete in magic ways:
2361             // If both are disabled show Remove
2362             // If both are enabled show both (can't happen atm)
2363             // If only removeFile is enabled only show it
2364             // If only deleteFile is enable only show it
2365             bool enableRemove = actions.contains(ProjectNode::RemoveFile);
2366             d->m_removeFileAction->setEnabled(enableRemove);
2367             bool enableDelete = actions.contains(ProjectNode::EraseFile);
2368             d->m_deleteFileAction->setEnabled(enableDelete);
2369             d->m_deleteFileAction->setVisible(enableDelete);
2370
2371             d->m_removeFileAction->setVisible(!enableDelete || enableRemove);
2372             d->m_renameFileAction->setEnabled(actions.contains(ProjectNode::Rename));
2373         }
2374     }
2375 }
2376
2377 QString pathOrDirectoryFor(Node *node, bool dir)
2378 {
2379     QString path = node->path();
2380     QString location;
2381     FolderNode *folder = qobject_cast<FolderNode *>(node);
2382     if (path.contains("#") && folder) {
2383         // Virtual Folder case
2384         // If there are files directly below or no subfolders, take the folder path
2385         if (!folder->fileNodes().isEmpty() || folder->subFolderNodes().isEmpty()) {
2386             location = path.left(path.indexOf('#'));;
2387         } else {
2388             // Otherwise we figure out a commonPath from the subfolders
2389             QStringList list;
2390             foreach (FolderNode *f, folder->subFolderNodes())
2391                 list << f->path() + QLatin1Char('/');
2392             location = Utils::commonPath(list);
2393         }
2394     } else {
2395         QFileInfo fi(path);
2396         if (dir) {
2397             location = fi.isDir() ? fi.absoluteFilePath() : fi.absolutePath();
2398         } else {
2399             location = fi.absoluteFilePath();
2400         }
2401     }
2402     return location;
2403 }
2404
2405 QString ProjectExplorerPlugin::pathFor(Node *node)
2406 {
2407     return pathOrDirectoryFor(node, false);
2408 }
2409
2410 QString ProjectExplorerPlugin::directoryFor(Node *node)
2411 {
2412     return pathOrDirectoryFor(node, true);
2413 }
2414
2415 void ProjectExplorerPlugin::addNewFile()
2416 {
2417     QTC_ASSERT(d->m_currentNode, return)
2418     QString location = directoryFor(d->m_currentNode);
2419
2420     Core::ICore::instance()->showNewItemDialog(tr("New File", "Title of dialog"),
2421                                Core::IWizard::wizardsOfKind(Core::IWizard::FileWizard)
2422                                + Core::IWizard::wizardsOfKind(Core::IWizard::ClassWizard),
2423                                location);
2424 }
2425
2426 void ProjectExplorerPlugin::addNewSubproject()
2427 {
2428     QTC_ASSERT(d->m_currentNode, return)
2429     QString location = directoryFor(d->m_currentNode);
2430
2431     if (d->m_currentNode->nodeType() == ProjectNodeType
2432             && d->m_currentNode->projectNode()->supportedActions(
2433                 d->m_currentNode->projectNode()).contains(ProjectNode::AddSubProject)) {
2434         Core::ICore::instance()->showNewItemDialog(tr("New Subproject", "Title of dialog"),
2435                               Core::IWizard::wizardsOfKind(Core::IWizard::ProjectWizard),
2436                               location);
2437     }
2438 }
2439
2440 void ProjectExplorerPlugin::addExistingFiles()
2441 {
2442     QTC_ASSERT(d->m_currentNode, return)
2443
2444     QStringList fileNames = QFileDialog::getOpenFileNames(Core::ICore::instance()->mainWindow(),
2445         tr("Add Existing Files"), directoryFor(d->m_currentNode));
2446     if (fileNames.isEmpty())
2447         return;
2448     addExistingFiles(fileNames);
2449 }
2450
2451 void ProjectExplorerPlugin::addExistingFiles(const QStringList &filePaths)
2452 {
2453     ProjectNode *projectNode = qobject_cast<ProjectNode*>(d->m_currentNode->projectNode());
2454     addExistingFiles(projectNode, filePaths);
2455 }
2456
2457 void ProjectExplorerPlugin::addExistingFiles(ProjectNode *projectNode, const QStringList &filePaths)
2458 {
2459     Core::ICore *core = Core::ICore::instance();
2460     const QString dir = directoryFor(projectNode);
2461     QStringList fileNames = filePaths;
2462     QHash<FileType, QString> fileTypeToFiles;
2463     foreach (const QString &fileName, fileNames) {
2464         FileType fileType = typeForFileName(core->mimeDatabase(), QFileInfo(fileName));
2465         fileTypeToFiles.insertMulti(fileType, fileName);
2466     }
2467
2468     QStringList notAdded;
2469     foreach (const FileType type, fileTypeToFiles.uniqueKeys()) {
2470         projectNode->addFiles(type, fileTypeToFiles.values(type), &notAdded);
2471     }
2472     if (!notAdded.isEmpty()) {
2473         QString message = tr("Could not add following files to project %1:\n").arg(projectNode->displayName());
2474         QString files = notAdded.join("\n");
2475         QMessageBox::warning(core->mainWindow(), tr("Adding Files to Project Failed"),
2476                              message + files);
2477         foreach (const QString &file, notAdded)
2478             fileNames.removeOne(file);
2479     }
2480
2481     if (Core::IVersionControl *vcManager = core->vcsManager()->findVersionControlForDirectory(dir))
2482         if (vcManager->supportsOperation(Core::IVersionControl::AddOperation)) {
2483             const QString files = fileNames.join(QString(QLatin1Char('\n')));
2484             QMessageBox::StandardButton button =
2485                 QMessageBox::question(core->mainWindow(), tr("Add to Version Control"),
2486                                       tr("Add files\n%1\nto version control (%2)?").arg(files, vcManager->displayName()),
2487                                       QMessageBox::Yes | QMessageBox::No);
2488             if (button == QMessageBox::Yes) {
2489                 QStringList notAddedToVc;
2490                 foreach (const QString &file, fileNames) {
2491                     if (!vcManager->vcsAdd(file))
2492                         notAddedToVc << file;
2493                 }
2494
2495                 if (!notAddedToVc.isEmpty()) {
2496                     const QString message = tr("Could not add following files to version control (%1)\n").arg(vcManager->displayName());
2497                     const QString filesNotAdded = notAddedToVc.join(QString(QLatin1Char('\n')));
2498                     QMessageBox::warning(core->mainWindow(), tr("Adding to Version Control Failed"),
2499                                          message + filesNotAdded);
2500                 }
2501             }
2502         }
2503 }
2504
2505 void ProjectExplorerPlugin::removeProject()
2506 {
2507     ProjectNode *subProjectNode = qobject_cast<ProjectNode*>(d->m_currentNode->projectNode());
2508     ProjectNode *projectNode = qobject_cast<ProjectNode *>(subProjectNode->parentFolderNode());
2509     if (projectNode) {
2510         Core::ICore *core = Core::ICore::instance();
2511         RemoveFileDialog removeFileDialog(subProjectNode->path(), core->mainWindow());
2512         removeFileDialog.setDeleteFileVisible(false);
2513         if (removeFileDialog.exec() == QDialog::Accepted)
2514             projectNode->removeSubProjects(QStringList() << subProjectNode->path());
2515     }
2516 }
2517
2518 void ProjectExplorerPlugin::openFile()
2519 {
2520     QTC_ASSERT(d->m_currentNode, return)
2521     Core::EditorManager *em = Core::EditorManager::instance();
2522     em->openEditor(d->m_currentNode->path(), QString(), Core::EditorManager::ModeSwitch);
2523 }
2524
2525 void ProjectExplorerPlugin::showInGraphicalShell()
2526 {
2527     QTC_ASSERT(d->m_currentNode, return)
2528     Core::Internal::FileUtils::showInGraphicalShell(Core::ICore::instance()->mainWindow(),
2529                                                     pathFor(d->m_currentNode));
2530 }
2531
2532 void ProjectExplorerPlugin::openTerminalHere()
2533 {
2534     QTC_ASSERT(d->m_currentNode, return)
2535     Core::Internal::FileUtils::openTerminal(directoryFor(d->m_currentNode));
2536 }
2537
2538 void ProjectExplorerPlugin::removeFile()
2539 {
2540     QTC_ASSERT(d->m_currentNode && d->m_currentNode->nodeType() == FileNodeType, return)
2541
2542     FileNode *fileNode = qobject_cast<FileNode*>(d->m_currentNode);
2543     Core::ICore *core = Core::ICore::instance();
2544
2545     QString filePath = d->m_currentNode->path();
2546     RemoveFileDialog removeFileDialog(filePath, core->mainWindow());
2547
2548     if (removeFileDialog.exec() == QDialog::Accepted) {
2549         const bool deleteFile = removeFileDialog.isDeleteFileChecked();
2550
2551         // remove from project
2552         ProjectNode *projectNode = fileNode->projectNode();
2553         Q_ASSERT(projectNode);
2554
2555         if (!projectNode->removeFiles(fileNode->fileType(), QStringList(filePath))) {
2556             QMessageBox::warning(core->mainWindow(), tr("Removing File Failed"),
2557                                  tr("Could not remove file %1 from project %2.").arg(filePath).arg(projectNode->displayName()));
2558             return;
2559         }
2560
2561         // remove from version control
2562         core->vcsManager()->promptToDelete(filePath);
2563
2564         // remove from file system
2565         if (deleteFile) {
2566             QFile file(filePath);
2567
2568             if (file.exists()) {
2569                 // could have been deleted by vc
2570                 if (!file.remove())
2571                     QMessageBox::warning(core->mainWindow(), tr("Deleting File Failed"),
2572                                          tr("Could not delete file %1.").arg(filePath));
2573             }
2574         }
2575     }
2576 }
2577
2578 void ProjectExplorerPlugin::deleteFile()
2579 {
2580     QTC_ASSERT(d->m_currentNode && d->m_currentNode->nodeType() == FileNodeType, return)
2581
2582     FileNode *fileNode = qobject_cast<FileNode*>(d->m_currentNode);
2583     Core::ICore *core = Core::ICore::instance();
2584
2585     QString filePath = d->m_currentNode->path();
2586     QMessageBox::StandardButton button =
2587             QMessageBox::question(core->mainWindow(),
2588                                   tr("Delete File"),
2589                                   tr("Delete %1 from file system?").arg(filePath),
2590                                   QMessageBox::Yes | QMessageBox::No);
2591     if (button != QMessageBox::Yes)
2592         return;
2593
2594     ProjectNode *projectNode = fileNode->projectNode();
2595     Q_ASSERT(projectNode);
2596
2597     projectNode->deleteFiles(fileNode->fileType(), QStringList(filePath));
2598
2599     core->fileManager()->expectFileChange(fileNode->path());
2600     if (Core::IVersionControl *vc =
2601             core->vcsManager()->findVersionControlForDirectory(QFileInfo(filePath).absolutePath())) {
2602         vc->vcsDelete(filePath);
2603     }
2604     QFile file(filePath);
2605     if (file.exists()) {
2606         if (!file.remove())
2607             QMessageBox::warning(core->mainWindow(), tr("Deleting File Failed"),
2608                                  tr("Could not delete file %1.").arg(filePath));
2609     }
2610     core->fileManager()->unexpectFileChange(fileNode->path());
2611 }
2612
2613 void ProjectExplorerPlugin::renameFile()
2614 {
2615     QWidget *focusWidget = QApplication::focusWidget();
2616     while (focusWidget) {
2617         ProjectTreeWidget *treeWidget = qobject_cast<ProjectTreeWidget*>(focusWidget);
2618         if (treeWidget) {
2619             treeWidget->editCurrentItem();
2620             return;
2621         }
2622         focusWidget = focusWidget->parentWidget();
2623     }
2624 }
2625
2626 void ProjectExplorerPlugin::renameFile(Node *node, const QString &to)
2627 {
2628     FileNode *fileNode = qobject_cast<FileNode *>(node);
2629     if (!fileNode)
2630         return;
2631     QString orgFilePath = QFileInfo(node->path()).absoluteFilePath();
2632     QString dir = QFileInfo(orgFilePath).absolutePath();
2633     QString newFilePath = dir + QLatin1Char('/') + to;
2634
2635     if (orgFilePath == newFilePath)
2636         return;
2637
2638     Core::ICore *core = Core::ICore::instance();
2639     Core::IVersionControl *vc = core->vcsManager()->findVersionControlForDirectory(dir);
2640
2641     bool result = false;
2642     if (vc && vc->supportsOperation(Core::IVersionControl::MoveOperation))
2643         result = vc->vcsMove(orgFilePath, newFilePath);
2644     if (!result) { // The moving via vcs failed or the vcs does not support moving, fall back
2645         QFile f(orgFilePath);
2646         if (!f.fileEngine()->caseSensitive()
2647                 && orgFilePath.compare(newFilePath, Qt::CaseInsensitive) == 0) {
2648             // Due to QTBUG-3570
2649             result = f.fileEngine()->rename(newFilePath);
2650         } else {
2651             result = QFile::rename(orgFilePath, newFilePath);
2652         }
2653     }
2654     if (result) {
2655         // yeah we moved, tell the filemanager about it
2656         Core::ICore::instance()->fileManager()->renamedFile(orgFilePath, newFilePath);
2657         // Tell the project plugin about it
2658         ProjectNode *projectNode = fileNode->projectNode();
2659         projectNode->renameFile(fileNode->fileType(), orgFilePath, newFilePath);
2660         // TODO emit a signal?
2661     }
2662 }
2663
2664 void ProjectExplorerPlugin::setStartupProject()
2665 {
2666     setStartupProject(d->m_currentProject);
2667 }
2668
2669 void ProjectExplorerPlugin::populateOpenWithMenu(QMenu *menu, const QString &fileName)
2670 {
2671     typedef QList<Core::IEditorFactory*> EditorFactoryList;
2672     typedef QList<Core::IExternalEditor*> ExternalEditorList;
2673
2674     menu->clear();
2675
2676     bool anyMatches = false;
2677
2678     Core::ICore *core = Core::ICore::instance();
2679     if (const Core::MimeType mt = core->mimeDatabase()->findByFile(QFileInfo(fileName))) {
2680         const EditorFactoryList factories = core->editorManager()->editorFactories(mt, false);
2681         const ExternalEditorList externalEditors = core->editorManager()->externalEditors(mt, false);
2682         anyMatches = !factories.empty() || !externalEditors.empty();
2683         if (anyMatches) {
2684             // Add all suitable editors
2685             foreach (Core::IEditorFactory *editorFactory, factories) {
2686                 // Add action to open with this very editor factory
2687                 QString const actionTitle = editorFactory->displayName();
2688                 QAction * const action = menu->addAction(actionTitle);
2689                 action->setData(qVariantFromValue(editorFactory));
2690             }
2691             // Add all suitable external editors
2692             foreach (Core::IExternalEditor *externalEditor, externalEditors) {
2693                 QAction * const action = menu->addAction(externalEditor->displayName());
2694                 action->setData(qVariantFromValue(externalEditor));
2695             }
2696         }
2697     }
2698     menu->setEnabled(anyMatches);
2699 }
2700
2701 void ProjectExplorerPlugin::populateOpenWithMenu()
2702 {
2703     populateOpenWithMenu(d->m_openWithMenu, currentNode()->path());
2704 }
2705
2706 void ProjectExplorerPlugin::openWithMenuTriggered(QAction *action)
2707 {
2708     if (!action)
2709         qWarning() << "ProjectExplorerPlugin::openWithMenuTriggered no action, can't happen.";
2710     else
2711         openEditorFromAction(action, currentNode()->path());
2712 }
2713
2714 void ProjectExplorerPlugin::openEditorFromAction(QAction *action, const QString &fileName)
2715 {
2716     Core::EditorManager *em = Core::EditorManager::instance();
2717     const QVariant data = action->data();
2718     if (qVariantCanConvert<Core::IEditorFactory *>(data)) {
2719         Core::IEditorFactory *factory = qVariantValue<Core::IEditorFactory *>(data);
2720
2721         // close any open editors that have this file open, but have a different type.
2722         QList<Core::IEditor *> editorsOpenForFile = em->editorsForFileName(fileName);
2723         if (!editorsOpenForFile.isEmpty()) {
2724             foreach (Core::IEditor *openEditor, editorsOpenForFile) {
2725                 if (factory->id() == openEditor->id())
2726                     editorsOpenForFile.removeAll(openEditor);
2727             }
2728             if (!em->closeEditors(editorsOpenForFile)) // don't open if cancel was pressed
2729                 return;
2730         }
2731
2732         em->openEditor(fileName, factory->id(), Core::EditorManager::ModeSwitch);
2733         return;
2734     }
2735     if (qVariantCanConvert<Core::IExternalEditor *>(data)) {
2736         Core::IExternalEditor *externalEditor = qVariantValue<Core::IExternalEditor *>(data);
2737         em->openExternalEditor(fileName, externalEditor->id());
2738     }
2739 }
2740
2741 void ProjectExplorerPlugin::updateSessionMenu()
2742 {
2743     d->m_sessionMenu->clear();
2744     QActionGroup *ag = new QActionGroup(d->m_sessionMenu);
2745     connect(ag, SIGNAL(triggered(QAction *)), this, SLOT(setSession(QAction *)));
2746     const QString &activeSession = d->m_session->activeSession();
2747     foreach (const QString &session, d->m_session->sessions()) {
2748         QAction *act = ag->addAction(session);
2749         act->setCheckable(true);
2750         if (session == activeSession)
2751             act->setChecked(true);
2752     }
2753     d->m_sessionMenu->addActions(ag->actions());
2754     d->m_sessionMenu->setEnabled(true);
2755 }
2756
2757 void ProjectExplorerPlugin::setSession(QAction *action)
2758 {
2759     QString session = action->text();
2760     if (session != d->m_session->activeSession())
2761         d->m_session->loadSession(session);
2762 }
2763
2764
2765 void ProjectExplorerPlugin::setProjectExplorerSettings(const Internal::ProjectExplorerSettings &pes)
2766 {
2767     if (d->m_projectExplorerSettings == pes)
2768         return;
2769     d->m_projectExplorerSettings = pes;
2770     emit settingsChanged();
2771 }
2772
2773 Internal::ProjectExplorerSettings ProjectExplorerPlugin::projectExplorerSettings() const
2774 {
2775     return d->m_projectExplorerSettings;
2776 }
2777
2778 QStringList ProjectExplorerPlugin::projectFilePatterns()
2779 {
2780     QStringList patterns;
2781     const Core::MimeDatabase *mdb = Core::ICore::instance()->mimeDatabase();
2782     foreach(const IProjectManager *pm, allProjectManagers())
2783         if (const Core::MimeType mt = mdb->findByType(pm->mimeType()))
2784             foreach(const Core::MimeGlobPattern &gp, mt.globPatterns())
2785                 patterns += gp.regExp().pattern();
2786     return patterns;
2787 }
2788
2789 void ProjectExplorerPlugin::openOpenProjectDialog()
2790 {
2791     Core::FileManager *fileMananger = Core::ICore::instance()->fileManager();
2792     const QString path = fileMananger->useProjectsDirectory() ? fileMananger->projectsDirectory() : QString();
2793     const QStringList files = fileMananger->getOpenFileNames(d->m_projectFilterString, path);
2794     if (!files.isEmpty())
2795         Core::ICore::instance()->openFiles(files, Core::ICore::SwitchMode);
2796 }
2797
2798 QList<QPair<QString, QString> > ProjectExplorerPlugin::recentProjects()
2799 {
2800     return d->m_recentProjects;
2801 }
2802
2803 Q_EXPORT_PLUGIN(ProjectExplorerPlugin)