OSDN Git Service

Merge remote branch 'origin/2.0'
[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) 2010 Nokia Corporation and/or its subsidiary(-ies).
6 **
7 ** Contact: Nokia Corporation (qt-info@nokia.com)
8 **
9 ** Commercial Usage
10 **
11 ** Licensees holding valid Qt Commercial licenses may use this file in
12 ** accordance with the Qt Commercial License Agreement provided with the
13 ** Software or, alternatively, in accordance with the terms contained in
14 ** a written agreement between you and Nokia.
15 **
16 ** GNU Lesser General Public License Usage
17 **
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file.  Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** If you are unsure which license is appropriate for your use, please
26 ** contact the sales department at http://qt.nokia.com/contact.
27 **
28 **************************************************************************/
29
30 #include "projectexplorer.h"
31
32 #include "project.h"
33 #include "projectexplorersettings.h"
34 #include "target.h"
35 #include "targetsettingspanel.h"
36 #include "copytaskhandler.h"
37 #include "showineditortaskhandler.h"
38 #include "vcsannotatetaskhandler.h"
39 #include "applicationrunconfiguration.h"
40 #include "allprojectsfilter.h"
41 #include "allprojectsfind.h"
42 #include "buildmanager.h"
43 #include "buildsettingspropertiespage.h"
44 #include "currentprojectfind.h"
45 #include "currentprojectfilter.h"
46 #include "customexecutablerunconfiguration.h"
47 #include "editorsettingspropertiespage.h"
48 #include "dependenciespanel.h"
49 #include "foldernavigationwidget.h"
50 #include "iprojectmanager.h"
51 #include "metatypedeclarations.h"
52 #include "nodesvisitor.h"
53 #include "outputwindow.h"
54 #include "persistentsettings.h"
55 #include "pluginfilefactory.h"
56 #include "processstep.h"
57 #include "projectexplorerconstants.h"
58 #include "customwizard.h"
59 #include "projectfilewizardextension.h"
60 #include "projecttreewidget.h"
61 #include "projectwindow.h"
62 #include "removefiledialog.h"
63 #include "runsettingspropertiespage.h"
64 #include "scriptwrappers.h"
65 #include "session.h"
66 #include "sessiondialog.h"
67 #include "target.h"
68 #include "projectexplorersettingspage.h"
69 #include "projectwelcomepage.h"
70 #include "projectwelcomepagewidget.h"
71 #include "corelistenercheckingforrunningbuild.h"
72 #include "buildconfiguration.h"
73 #include "buildconfigdialog.h"
74 #include "miniprojecttargetselector.h"
75
76 #include <coreplugin/basemode.h>
77 #include <coreplugin/coreconstants.h>
78 #include <coreplugin/filemanager.h>
79 #include <coreplugin/icore.h>
80 #include <coreplugin/mainwindow.h>
81 #include <coreplugin/mimedatabase.h>
82 #include <coreplugin/modemanager.h>
83 #include <coreplugin/actionmanager/actionmanager.h>
84 #include <coreplugin/actionmanager/actioncontainer.h>
85 #include <coreplugin/actionmanager/command.h>
86 #include <coreplugin/editormanager/editormanager.h>
87 #include <coreplugin/editormanager/ieditor.h>
88 #include <coreplugin/editormanager/ieditorfactory.h>
89 #include <coreplugin/editormanager/iexternaleditor.h>
90 #include <coreplugin/findplaceholder.h>
91 #include <coreplugin/basefilewizard.h>
92 #include <coreplugin/vcsmanager.h>
93 #include <coreplugin/iversioncontrol.h>
94 #include <welcome/welcomemode.h>
95 #include <extensionsystem/pluginmanager.h>
96 #include <utils/consoleprocess.h>
97 #include <utils/qtcassert.h>
98 #include <utils/parameteraction.h>
99
100 #include <QtCore/QtPlugin>
101 #include <QtCore/QDateTime>
102 #include <QtCore/QDebug>
103 #include <QtCore/QSettings>
104
105 #include <QtGui/QAction>
106 #include <QtGui/QApplication>
107 #include <QtGui/QFileDialog>
108 #include <QtGui/QMenu>
109 #include <QtGui/QMessageBox>
110
111 Q_DECLARE_METATYPE(Core::IEditorFactory*);
112 Q_DECLARE_METATYPE(Core::IExternalEditor*);
113
114 namespace {
115 bool debug = false;
116 }
117
118 namespace ProjectExplorer {
119
120 struct ProjectExplorerPluginPrivate {
121     ProjectExplorerPluginPrivate();
122
123     QMenu *m_sessionContextMenu;
124     QMenu *m_sessionMenu;
125     QMenu *m_projectMenu;
126     QMenu *m_subProjectMenu;
127     QMenu *m_folderMenu;
128     QMenu *m_fileMenu;
129     QMenu *m_openWithMenu;
130
131     QMultiMap<int, QObject*> m_actionMap;
132     QAction *m_sessionManagerAction;
133     QAction *m_newAction;
134 #if 0
135     QAction *m_loadAction;
136 #endif
137     Utils::ParameterAction *m_unloadAction;
138     QAction *m_clearSession;
139     QAction *m_buildProjectOnlyAction;
140     Utils::ParameterAction *m_buildAction;
141     Utils::ParameterAction *m_buildActionContextMenu;
142     QAction *m_buildSessionAction;
143     QAction *m_rebuildProjectOnlyAction;
144     Utils::ParameterAction *m_rebuildAction;
145     Utils::ParameterAction *m_rebuildActionContextMenu;
146     QAction *m_rebuildSessionAction;
147     QAction *m_cleanProjectOnlyAction;
148     Utils::ParameterAction *m_cleanAction;
149     Utils::ParameterAction *m_cleanActionContextMenu;
150     QAction *m_cleanSessionAction;
151     QAction *m_runAction;
152     QAction *m_runActionContextMenu;
153     QAction *m_cancelBuildAction;
154     QAction *m_debugAction;
155     QAction *m_addNewFileAction;
156     QAction *m_addExistingFilesAction;
157     QAction *m_openFileAction;
158     QAction *m_showInGraphicalShell;
159     QAction *m_openTerminalHere;
160     QAction *m_removeFileAction;
161     QAction *m_renameFileAction;
162     QAction *m_projectSelectorAction;
163     QAction *m_projectSelectorActionMenu;
164
165     Internal::ProjectWindow *m_proWindow;
166     SessionManager *m_session;
167     QString m_sessionToRestoreAtStartup;
168
169     Project *m_currentProject;
170     Node *m_currentNode;
171
172     BuildManager *m_buildManager;
173
174     QList<Internal::ProjectFileFactory*> m_fileFactories;
175     QStringList m_profileMimeTypes;
176     Internal::OutputPane *m_outputPane;
177
178     QList<QPair<QString, QString> > m_recentProjects; // pair of filename, displayname
179     static const int m_maxRecentProjects = 7;
180
181     QString m_lastOpenDirectory;
182     RunConfiguration *m_delayedRunConfiguration; // TODO this is not right
183     RunControl *m_debuggingRunControl;
184     QString m_runMode;
185     QString m_projectFilterString;
186     Internal::MiniProjectTargetSelector * m_targetSelector;
187     Internal::ProjectExplorerSettings m_projectExplorerSettings;
188     Internal::ProjectWelcomePage *m_welcomePage;
189
190     Core::BaseMode * m_projectsMode;
191 };
192
193 ProjectExplorerPluginPrivate::ProjectExplorerPluginPrivate() :
194     m_currentProject(0),
195     m_currentNode(0),
196     m_delayedRunConfiguration(0),
197     m_debuggingRunControl(0),
198     m_projectsMode(0)
199 {
200 }
201
202 }  // namespace ProjectExplorer
203
204 using namespace ProjectExplorer;
205 using namespace ProjectExplorer::Internal;
206
207
208 ProjectExplorerPlugin *ProjectExplorerPlugin::m_instance = 0;
209
210 ProjectExplorerPlugin::ProjectExplorerPlugin()
211     : d(new ProjectExplorerPluginPrivate)
212 {
213     m_instance = this;
214 }
215
216 ProjectExplorerPlugin::~ProjectExplorerPlugin()
217 {
218     removeObject(d->m_welcomePage);
219     delete d->m_welcomePage;
220     removeObject(this);
221     delete d;
222 }
223
224 ProjectExplorerPlugin *ProjectExplorerPlugin::instance()
225 {
226     return m_instance;
227 }
228
229 bool ProjectExplorerPlugin::parseArguments(const QStringList &arguments, QString * /* error */)
230 {
231     CustomWizard::setVerbose(arguments.count(QLatin1String("-customwizard-verbose")));
232     return true;
233 }
234
235 bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *error)
236 {
237     if (!parseArguments(arguments, error))
238         return false;
239
240     Core::ICore *core = Core::ICore::instance();
241     Core::ActionManager *am = core->actionManager();
242
243     d->m_welcomePage = new ProjectWelcomePage;
244     connect(d->m_welcomePage, SIGNAL(manageSessions()), this, SLOT(showSessionManager()));
245     addObject(d->m_welcomePage);
246     addObject(this);
247
248     connect(core->fileManager(), SIGNAL(currentFileChanged(QString)),
249             this, SLOT(setCurrentFile(QString)));
250
251     d->m_session = new SessionManager(this);
252
253     connect(d->m_session, SIGNAL(projectAdded(ProjectExplorer::Project *)),
254             this, SIGNAL(fileListChanged()));
255     connect(d->m_session, SIGNAL(aboutToRemoveProject(ProjectExplorer::Project *)),
256             this, SLOT(invalidateProject(ProjectExplorer::Project *)));
257     connect(d->m_session, SIGNAL(projectRemoved(ProjectExplorer::Project *)),
258             this, SIGNAL(fileListChanged()));
259     connect(d->m_session, SIGNAL(startupProjectChanged(ProjectExplorer::Project *)),
260             this, SLOT(startupProjectChanged()));
261     connect(d->m_session, SIGNAL(dependencyChanged(ProjectExplorer::Project*,ProjectExplorer::Project*)),
262             this, SLOT(updateActions()));
263
264     d->m_proWindow = new ProjectWindow;
265
266     Core::Context globalcontext(Core::Constants::C_GLOBAL);
267     Core::Context pecontext(Constants::C_PROJECTEXPLORER);
268
269     d->m_projectsMode = new Core::BaseMode;
270     d->m_projectsMode->setDisplayName(tr("Projects"));
271     d->m_projectsMode->setId(QLatin1String(Constants::MODE_SESSION));
272     d->m_projectsMode->setIcon(QIcon(QLatin1String(":/fancyactionbar/images/mode_Project.png")));
273     d->m_projectsMode->setPriority(Constants::P_MODE_SESSION);
274     d->m_projectsMode->setWidget(d->m_proWindow);
275     d->m_projectsMode->setContext(pecontext);
276     d->m_projectsMode->setEnabled(session()->startupProject());
277     d->m_projectsMode->setContextHelpId(QLatin1String("Managing Projects"));
278     addAutoReleasedObject(d->m_projectsMode);
279     d->m_proWindow->layout()->addWidget(new Core::FindToolBarPlaceHolder(d->m_proWindow));
280
281     addAutoReleasedObject(new CopyTaskHandler);
282     addAutoReleasedObject(new ShowInEditorTaskHandler);
283     addAutoReleasedObject(new VcsAnnotateTaskHandler);
284
285     d->m_buildManager = new BuildManager(this);
286     connect(d->m_buildManager, SIGNAL(buildStateChanged(ProjectExplorer::Project *)),
287             this, SLOT(buildStateChanged(ProjectExplorer::Project *)));
288     connect(d->m_buildManager, SIGNAL(buildQueueFinished(bool)),
289             this, SLOT(buildQueueFinished(bool)));
290
291     addAutoReleasedObject(new CoreListenerCheckingForRunningBuild(d->m_buildManager));
292
293     d->m_outputPane = new OutputPane;
294     addAutoReleasedObject(d->m_outputPane);
295     connect(d->m_session, SIGNAL(projectRemoved(ProjectExplorer::Project *)),
296             d->m_outputPane, SLOT(projectRemoved()));
297
298     AllProjectsFilter *allProjectsFilter = new AllProjectsFilter(this);
299     addAutoReleasedObject(allProjectsFilter);
300
301     CurrentProjectFilter *currentProjectFilter = new CurrentProjectFilter(this);
302     addAutoReleasedObject(currentProjectFilter);
303
304     addAutoReleasedObject(new BuildSettingsPanelFactory);
305     addAutoReleasedObject(new RunSettingsPanelFactory);
306     addAutoReleasedObject(new EditorSettingsPanelFactory);
307     addAutoReleasedObject(new DependenciesPanelFactory(d->m_session));
308
309     ProcessStepFactory *processStepFactory = new ProcessStepFactory;
310     addAutoReleasedObject(processStepFactory);
311
312     ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
313     AllProjectsFind *allProjectsFind = new AllProjectsFind(this,
314         pm->getObject<Find::SearchResultWindow>());
315     addAutoReleasedObject(allProjectsFind);
316
317     CurrentProjectFind *currentProjectFind = new CurrentProjectFind(this,
318         pm->getObject<Find::SearchResultWindow>());
319     addAutoReleasedObject(currentProjectFind);
320
321     addAutoReleasedObject(new LocalApplicationRunControlFactory);
322     addAutoReleasedObject(new CustomExecutableRunConfigurationFactory);
323
324     addAutoReleasedObject(new ProjectFileWizardExtension);
325
326     // Settings page
327     addAutoReleasedObject(new ProjectExplorerSettingsPage);
328
329     // context menus
330     Core::ActionContainer *msessionContextMenu =
331         am->createMenu(Constants::M_SESSIONCONTEXT);
332     Core::ActionContainer *mproject =
333         am->createMenu(Constants::M_PROJECTCONTEXT);
334     Core::ActionContainer *msubProject =
335         am->createMenu(Constants::M_SUBPROJECTCONTEXT);
336     Core::ActionContainer *mfolder =
337         am->createMenu(Constants::M_FOLDERCONTEXT);
338     Core::ActionContainer *mfilec =
339         am->createMenu(Constants::M_FILECONTEXT);
340
341     d->m_sessionContextMenu = msessionContextMenu->menu();
342     d->m_projectMenu = mproject->menu();
343     d->m_subProjectMenu = msubProject->menu();
344     d->m_folderMenu = mfolder->menu();
345     d->m_fileMenu = mfilec->menu();
346
347     Core::ActionContainer *mfile =
348         am->actionContainer(Core::Constants::M_FILE);
349     Core::ActionContainer *menubar =
350         am->actionContainer(Core::Constants::MENU_BAR);
351
352     // mode manager (for fancy actions)
353     Core::ModeManager *modeManager = core->modeManager();
354
355     // build menu
356     Core::ActionContainer *mbuild =
357         am->createMenu(Constants::M_BUILDPROJECT);
358     mbuild->menu()->setTitle(tr("&Build"));
359     menubar->addMenu(mbuild, Core::Constants::G_VIEW);
360
361     // debug menu
362     Core::ActionContainer *mdebug =
363         am->createMenu(Constants::M_DEBUG);
364     mdebug->menu()->setTitle(tr("&Debug"));
365     menubar->addMenu(mdebug, Core::Constants::G_VIEW);
366
367     Core::ActionContainer *mstartdebugging =
368         am->createMenu(Constants::M_DEBUG_STARTDEBUGGING);
369     mstartdebugging->menu()->setTitle(tr("&Start Debugging"));
370     mdebug->addMenu(mstartdebugging, Core::Constants::G_DEFAULT_ONE);
371
372     //
373     // Groups
374     //
375
376     mbuild->appendGroup(Constants::G_BUILD_SESSION);
377     mbuild->appendGroup(Constants::G_BUILD_PROJECT);
378     mbuild->appendGroup(Constants::G_BUILD_OTHER);
379     mbuild->appendGroup(Constants::G_BUILD_CANCEL);
380     mbuild->appendGroup(Constants::G_BUILD_RUN);
381
382     msessionContextMenu->appendGroup(Constants::G_SESSION_BUILD);
383     msessionContextMenu->appendGroup(Constants::G_SESSION_FILES);
384     msessionContextMenu->appendGroup(Constants::G_SESSION_OTHER);
385     msessionContextMenu->appendGroup(Constants::G_SESSION_CONFIG);
386
387     mproject->appendGroup(Constants::G_PROJECT_OPEN);
388     mproject->appendGroup(Constants::G_PROJECT_NEW);
389     mproject->appendGroup(Constants::G_PROJECT_BUILD);
390     mproject->appendGroup(Constants::G_PROJECT_RUN);
391     mproject->appendGroup(Constants::G_PROJECT_FILES);
392     mproject->appendGroup(Constants::G_PROJECT_OTHER);
393     mproject->appendGroup(Constants::G_PROJECT_CONFIG);
394
395     msubProject->appendGroup(Constants::G_PROJECT_OPEN);
396     msubProject->appendGroup(Constants::G_PROJECT_BUILD);
397     msubProject->appendGroup(Constants::G_PROJECT_FILES);
398     msubProject->appendGroup(Constants::G_PROJECT_OTHER);
399     msubProject->appendGroup(Constants::G_PROJECT_CONFIG);
400
401     mfolder->appendGroup(Constants::G_FOLDER_FILES);
402     mfolder->appendGroup(Constants::G_FOLDER_OTHER);
403     mfolder->appendGroup(Constants::G_FOLDER_CONFIG);
404
405     mfilec->appendGroup(Constants::G_FILE_OPEN);
406     mfilec->appendGroup(Constants::G_FILE_OTHER);
407     mfilec->appendGroup(Constants::G_FILE_CONFIG);
408
409     // "open with" submenu
410     Core::ActionContainer * const openWith =
411             am->createMenu(ProjectExplorer::Constants::M_OPENFILEWITHCONTEXT);
412     openWith->setEmptyAction(Core::ActionContainer::EA_None);
413     d->m_openWithMenu = openWith->menu();
414     d->m_openWithMenu->setTitle(tr("Open With"));
415
416     connect(d->m_openWithMenu, SIGNAL(triggered(QAction *)),
417             this, SLOT(openWithMenuTriggered(QAction *)));
418
419     //
420     // Separators
421     //
422
423     Core::Command *cmd;
424     QAction *sep;
425
426     sep = new QAction(this);
427     sep->setSeparator(true);
428     cmd = am->registerAction(sep, QLatin1String("ProjectExplorer.Build.Sep"), globalcontext);
429     mbuild->addAction(cmd, Constants::G_BUILD_PROJECT);
430
431     sep = new QAction(this);
432     sep->setSeparator(true);
433     cmd = am->registerAction(sep, QLatin1String("ProjectExplorer.Files.Sep"), globalcontext);
434     msessionContextMenu->addAction(cmd, Constants::G_SESSION_FILES);
435     mproject->addAction(cmd, Constants::G_PROJECT_FILES);
436     msubProject->addAction(cmd, Constants::G_PROJECT_FILES);
437
438     sep = new QAction(this);
439     sep->setSeparator(true);
440     cmd = am->registerAction(sep, QLatin1String("ProjectExplorer.New.Sep"), globalcontext);
441     mproject->addAction(cmd, Constants::G_PROJECT_NEW);
442
443     sep = new QAction(this);
444     sep->setSeparator(true);
445     cmd = am->registerAction(sep, QLatin1String("ProjectExplorer.Config.Sep"), globalcontext);
446     msessionContextMenu->addAction(cmd, Constants::G_SESSION_CONFIG);
447     mproject->addAction(cmd, Constants::G_PROJECT_CONFIG);
448     msubProject->addAction(cmd, Constants::G_PROJECT_CONFIG);
449
450     sep = new QAction(this);
451     sep->setSeparator(true);
452     cmd = am->registerAction(sep, QLatin1String("ProjectExplorer.Projects.Sep"), globalcontext);
453     mfile->addAction(cmd, Core::Constants::G_FILE_PROJECT);
454
455     sep = new QAction(this);
456     sep->setSeparator(true);
457     cmd = am->registerAction(sep, QLatin1String("ProjectExplorer.Other.Sep"), globalcontext);
458     mbuild->addAction(cmd, Constants::G_BUILD_OTHER);
459     msessionContextMenu->addAction(cmd, Constants::G_SESSION_OTHER);
460     mproject->addAction(cmd, Constants::G_PROJECT_OTHER);
461     msubProject->addAction(cmd, Constants::G_PROJECT_OTHER);
462
463     sep = new QAction(this);
464     sep->setSeparator(true);
465     cmd = am->registerAction(sep, QLatin1String("ProjectExplorer.Run.Sep"), globalcontext);
466     mbuild->addAction(cmd, Constants::G_BUILD_RUN);
467     mproject->addAction(cmd, Constants::G_PROJECT_RUN);
468
469     sep = new QAction(this);
470     sep->setSeparator(true);
471     cmd = am->registerAction(sep, QLatin1String("ProjectExplorer.CancelBuild.Sep"), globalcontext);
472     mbuild->addAction(cmd, Constants::G_BUILD_CANCEL);
473
474     //
475     // Actions
476     //
477
478     // new session action
479     d->m_sessionManagerAction = new QAction(tr("Session Manager..."), this);
480     cmd = am->registerAction(d->m_sessionManagerAction, Constants::NEWSESSION, globalcontext);
481     cmd->setDefaultKeySequence(QKeySequence());
482
483     // new action
484     d->m_newAction = new QAction(tr("New Project..."), this);
485     cmd = am->registerAction(d->m_newAction, Constants::NEWPROJECT, globalcontext);
486     cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+N")));
487     msessionContextMenu->addAction(cmd, Constants::G_SESSION_FILES);
488
489 #if 0
490     // open action
491     d->m_loadAction = new QAction(tr("Load Project..."), this);
492     cmd = am->registerAction(d->m_loadAction, Constants::LOAD, globalcontext);
493     cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+O")));
494     mfile->addAction(cmd, Core::Constants::G_FILE_PROJECT);
495     msessionContextMenu->addAction(cmd, Constants::G_SESSION_FILES);
496 #endif
497
498     // Default open action
499     d->m_openFileAction = new QAction(tr("Open File"), this);
500     cmd = am->registerAction(d->m_openFileAction, ProjectExplorer::Constants::OPENFILE,
501                        globalcontext);
502     mfilec->addAction(cmd, Constants::G_FILE_OPEN);
503
504     d->m_showInGraphicalShell = new QAction(FolderNavigationWidget::msgGraphicalShellAction(), this);
505     cmd = am->registerAction(d->m_showInGraphicalShell, ProjectExplorer::Constants::SHOWINGRAPHICALSHELL,
506                        globalcontext);
507     mfilec->addAction(cmd, Constants::G_FILE_OPEN);
508     mfolder->addAction(cmd, Constants::G_FOLDER_FILES);
509
510     d->m_openTerminalHere = new QAction(FolderNavigationWidget::msgTerminalAction(), this);
511     cmd = am->registerAction(d->m_openTerminalHere, ProjectExplorer::Constants::OPENTERMIANLHERE,
512                        globalcontext);
513     mfilec->addAction(cmd, Constants::G_FILE_OPEN);
514     mfolder->addAction(cmd, Constants::G_FOLDER_FILES);
515
516     // Open With menu
517     mfilec->addMenu(openWith, ProjectExplorer::Constants::G_FILE_OPEN);
518
519     // recent projects menu
520     Core::ActionContainer *mrecent =
521         am->createMenu(Constants::M_RECENTPROJECTS);
522     mrecent->menu()->setTitle(tr("Recent P&rojects"));
523     mfile->addMenu(mrecent, Core::Constants::G_FILE_OPEN);
524     connect(mfile->menu(), SIGNAL(aboutToShow()),
525         this, SLOT(updateRecentProjectMenu()));
526
527     // unload action
528     d->m_unloadAction = new Utils::ParameterAction(tr("Close Project"), tr("Close Project \"%1\""),
529                                                       Utils::ParameterAction::EnabledWithParameter, this);
530     cmd = am->registerAction(d->m_unloadAction, Constants::UNLOAD, globalcontext);
531     cmd->setAttribute(Core::Command::CA_UpdateText);
532     cmd->setDefaultText(d->m_unloadAction->text());
533     mfile->addAction(cmd, Core::Constants::G_FILE_PROJECT);
534     mproject->addAction(cmd, Constants::G_PROJECT_FILES);
535
536     // unload session action
537     d->m_clearSession = new QAction(tr("Close All Projects"), this);
538     cmd = am->registerAction(d->m_clearSession, Constants::CLEARSESSION, globalcontext);
539     mfile->addAction(cmd, Core::Constants::G_FILE_PROJECT);
540     msessionContextMenu->addAction(cmd, Constants::G_SESSION_FILES);
541
542     // session menu
543     Core::ActionContainer *msession = am->createMenu(Constants::M_SESSION);
544     msession->menu()->setTitle(tr("Session"));
545     mfile->addMenu(msession, Core::Constants::G_FILE_PROJECT);
546     d->m_sessionMenu = msession->menu();
547     connect(mfile->menu(), SIGNAL(aboutToShow()),
548             this, SLOT(updateSessionMenu()));
549
550     // build session action
551     QIcon buildIcon(Constants::ICON_BUILD);
552     buildIcon.addFile(Constants::ICON_BUILD_SMALL);
553     d->m_buildSessionAction = new QAction(buildIcon, tr("Build All"), this);
554     cmd = am->registerAction(d->m_buildSessionAction, Constants::BUILDSESSION, globalcontext);
555     cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+B")));
556     mbuild->addAction(cmd, Constants::G_BUILD_SESSION);
557     msessionContextMenu->addAction(cmd, Constants::G_SESSION_BUILD);
558     // Add to mode bar
559     modeManager->addAction(cmd, Constants::P_ACTION_BUILDSESSION);
560
561     // rebuild session action
562     QIcon rebuildIcon(Constants::ICON_REBUILD);
563     rebuildIcon.addFile(Constants::ICON_REBUILD_SMALL);
564     d->m_rebuildSessionAction = new QAction(rebuildIcon, tr("Rebuild All"), this);
565     cmd = am->registerAction(d->m_rebuildSessionAction, Constants::REBUILDSESSION, globalcontext);
566     mbuild->addAction(cmd, Constants::G_BUILD_SESSION);
567     msessionContextMenu->addAction(cmd, Constants::G_SESSION_BUILD);
568
569     // clean session
570     QIcon cleanIcon(Constants::ICON_CLEAN);
571     cleanIcon.addFile(Constants::ICON_CLEAN_SMALL);
572     d->m_cleanSessionAction = new QAction(cleanIcon, tr("Clean All"), this);
573     cmd = am->registerAction(d->m_cleanSessionAction, Constants::CLEANSESSION, globalcontext);
574     mbuild->addAction(cmd, Constants::G_BUILD_SESSION);
575     msessionContextMenu->addAction(cmd, Constants::G_SESSION_BUILD);
576
577     // build action
578     d->m_buildAction = new Utils::ParameterAction(tr("Build Project"), tr("Build Project \"%1\""),
579                                                      Utils::ParameterAction::AlwaysEnabled, this);
580     cmd = am->registerAction(d->m_buildAction, Constants::BUILD, globalcontext);
581     cmd->setAttribute(Core::Command::CA_UpdateText);
582     cmd->setDefaultText(d->m_buildAction->text());
583     cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+B")));
584     mbuild->addAction(cmd, Constants::G_BUILD_PROJECT);
585
586     // rebuild action
587     d->m_rebuildAction = new Utils::ParameterAction(tr("Rebuild Project"), tr("Rebuild Project \"%1\""),
588                                                        Utils::ParameterAction::AlwaysEnabled, this);
589     cmd = am->registerAction(d->m_rebuildAction, Constants::REBUILD, globalcontext);
590     cmd->setAttribute(Core::Command::CA_UpdateText);
591     cmd->setDefaultText(d->m_rebuildAction->text());
592     mbuild->addAction(cmd, Constants::G_BUILD_PROJECT);
593
594     // clean action
595     d->m_cleanAction = new Utils::ParameterAction(tr("Clean Project"), tr("Clean Project \"%1\""),
596                                                      Utils::ParameterAction::AlwaysEnabled, this);
597     cmd = am->registerAction(d->m_cleanAction, Constants::CLEAN, globalcontext);
598     cmd->setAttribute(Core::Command::CA_UpdateText);
599     cmd->setDefaultText(d->m_cleanAction->text());
600     mbuild->addAction(cmd, Constants::G_BUILD_PROJECT);
601
602     // build action (context menu)
603     d->m_buildActionContextMenu = new Utils::ParameterAction(tr("Build Project"), tr("Build Project \"%1\""),
604                                                              Utils::ParameterAction::AlwaysEnabled, this);
605     cmd = am->registerAction(d->m_buildActionContextMenu, Constants::BUILDCM, globalcontext);
606     cmd->setAttribute(Core::Command::CA_UpdateText);
607     cmd->setDefaultText(d->m_buildActionContextMenu->text());
608     mproject->addAction(cmd, Constants::G_PROJECT_BUILD);
609
610     // rebuild action (context menu)
611     d->m_rebuildActionContextMenu = new Utils::ParameterAction(tr("Rebuild Project"), tr("Rebuild Project \"%1\""),
612                                                                Utils::ParameterAction::AlwaysEnabled, this);
613     cmd = am->registerAction(d->m_rebuildActionContextMenu, Constants::REBUILDCM, globalcontext);
614     cmd->setAttribute(Core::Command::CA_UpdateText);
615     cmd->setDefaultText(d->m_rebuildActionContextMenu->text());
616     mproject->addAction(cmd, Constants::G_PROJECT_BUILD);
617
618     // clean action (context menu)
619     d->m_cleanActionContextMenu = new Utils::ParameterAction(tr("Clean Project"), tr("Clean Project \"%1\""),
620                                                              Utils::ParameterAction::AlwaysEnabled, this);
621     cmd = am->registerAction(d->m_cleanActionContextMenu, Constants::CLEANCM, globalcontext);
622     cmd->setAttribute(Core::Command::CA_UpdateText);
623     cmd->setDefaultText(d->m_cleanActionContextMenu->text());
624     mproject->addAction(cmd, Constants::G_PROJECT_BUILD);
625
626     // build without dependencies action
627     d->m_buildProjectOnlyAction = new QAction(tr("Build Without Dependencies"), this);
628     cmd = am->registerAction(d->m_buildProjectOnlyAction, Constants::BUILDPROJECTONLY, globalcontext);
629
630     // rebuild without dependencies action
631     d->m_rebuildProjectOnlyAction = new QAction(tr("Rebuild Without Dependencies"), this);
632     cmd = am->registerAction(d->m_rebuildProjectOnlyAction, Constants::REBUILDPROJECTONLY, globalcontext);
633
634     // clean without dependencies action
635     d->m_cleanProjectOnlyAction = new QAction(tr("Clean Without Dependencies"), this);
636     cmd = am->registerAction(d->m_cleanProjectOnlyAction, Constants::CLEANPROJECTONLY, globalcontext);
637
638     // run action
639     QIcon runIcon(Constants::ICON_RUN);
640     runIcon.addFile(Constants::ICON_RUN_SMALL);
641     d->m_runAction = new QAction(runIcon, tr("Run"), this);
642     cmd = am->registerAction(d->m_runAction, Constants::RUN, globalcontext);
643     cmd->setAttribute(Core::Command::CA_UpdateText);
644
645     cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+R")));
646     mbuild->addAction(cmd, Constants::G_BUILD_RUN);
647
648     modeManager->addAction(cmd, Constants::P_ACTION_RUN);
649
650     d->m_runActionContextMenu = new QAction(runIcon, tr("Run"), this);
651     cmd = am->registerAction(d->m_runActionContextMenu, Constants::RUNCONTEXTMENU, globalcontext);
652     mproject->addAction(cmd, Constants::G_PROJECT_RUN);
653
654     // cancel build action
655     d->m_cancelBuildAction = new QAction(tr("Cancel Build"), this);
656     cmd = am->registerAction(d->m_cancelBuildAction, Constants::CANCELBUILD, globalcontext);
657     mbuild->addAction(cmd, Constants::G_BUILD_CANCEL);
658
659     // debug action
660     QIcon debuggerIcon(":/projectexplorer/images/debugger_start_small.png");
661     debuggerIcon.addFile(":/projectexplorer/images/debugger_start.png");
662     d->m_debugAction = new QAction(debuggerIcon, tr("Start Debugging"), this);
663     cmd = am->registerAction(d->m_debugAction, Constants::DEBUG, globalcontext);
664     cmd->setAttribute(Core::Command::CA_UpdateText);
665     cmd->setAttribute(Core::Command::CA_UpdateIcon);
666     cmd->setDefaultText(tr("Start Debugging"));
667     cmd->setDefaultKeySequence(QKeySequence(tr("F5")));
668     mstartdebugging->addAction(cmd, Core::Constants::G_DEFAULT_ONE);
669     modeManager->addAction(cmd, Constants::P_ACTION_DEBUG);
670
671     // add new file action
672     d->m_addNewFileAction = new QAction(tr("Add New..."), this);
673     cmd = am->registerAction(d->m_addNewFileAction, ProjectExplorer::Constants::ADDNEWFILE,
674                        globalcontext);
675     mproject->addAction(cmd, Constants::G_PROJECT_FILES);
676     msubProject->addAction(cmd, Constants::G_PROJECT_FILES);
677     mfolder->addAction(cmd, Constants::G_FOLDER_FILES);
678
679     // add existing file action
680     d->m_addExistingFilesAction = new QAction(tr("Add Existing Files..."), this);
681     cmd = am->registerAction(d->m_addExistingFilesAction, ProjectExplorer::Constants::ADDEXISTINGFILES,
682                        globalcontext);
683     mproject->addAction(cmd, Constants::G_PROJECT_FILES);
684     msubProject->addAction(cmd, Constants::G_PROJECT_FILES);
685     mfolder->addAction(cmd, Constants::G_FOLDER_FILES);
686
687     // remove file action
688     d->m_removeFileAction = new QAction(tr("Remove File..."), this);
689     cmd = am->registerAction(d->m_removeFileAction, ProjectExplorer::Constants::REMOVEFILE,
690                        globalcontext);
691     mfilec->addAction(cmd, Constants::G_FILE_OTHER);
692
693     // renamefile action
694     d->m_renameFileAction = new QAction(tr("Rename"), this);
695     cmd = am->registerAction(d->m_renameFileAction, ProjectExplorer::Constants::RENAMEFILE,
696                        globalcontext);
697     mfilec->addAction(cmd, Constants::G_FILE_OTHER);
698     // Not yet used by anyone, so hide for now
699 //    mfolder->addAction(cmd, Constants::G_FOLDER_FILES);
700 //    msubProject->addAction(cmd, Constants::G_FOLDER_FILES);
701 //    mproject->addAction(cmd, Constants::G_FOLDER_FILES);
702
703     // target selector
704     d->m_projectSelectorAction = new QAction(this);
705     d->m_projectSelectorAction->setCheckable(true);
706     d->m_projectSelectorAction->setEnabled(false);
707     QWidget *mainWindow = Core::ICore::instance()->mainWindow();
708     d->m_targetSelector = new Internal::MiniProjectTargetSelector(d->m_projectSelectorAction, mainWindow);
709     connect(d->m_projectSelectorAction, SIGNAL(triggered()), d->m_targetSelector, SLOT(show()));
710     modeManager->addProjectSelector(d->m_projectSelectorAction);
711
712     d->m_projectSelectorActionMenu = new QAction(this);
713     d->m_projectSelectorActionMenu->setEnabled(false);
714     d->m_projectSelectorActionMenu->setText(tr("Open Build/Run Target Selector..."));
715     connect(d->m_projectSelectorActionMenu, SIGNAL(triggered()), d->m_targetSelector, SLOT(show()));
716     cmd = am->registerAction(d->m_projectSelectorActionMenu, ProjectExplorer::Constants::SELECTTARGET,
717                        globalcontext);
718     cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+T")));
719     mbuild->addAction(cmd, Constants::G_BUILD_RUN);
720
721     connect(d->m_session, SIGNAL(projectAdded(ProjectExplorer::Project*)),
722             d->m_targetSelector, SLOT(addProject(ProjectExplorer::Project*)));
723     connect(d->m_session, SIGNAL(projectRemoved(ProjectExplorer::Project*)),
724             d->m_targetSelector, SLOT(removeProject(ProjectExplorer::Project*)));
725     connect(d->m_targetSelector, SIGNAL(startupProjectChanged(ProjectExplorer::Project*)),
726             this, SLOT(setStartupProject(ProjectExplorer::Project*)));
727     connect(d->m_session, SIGNAL(startupProjectChanged(ProjectExplorer::Project*)),
728             d->m_targetSelector, SLOT(changeStartupProject(ProjectExplorer::Project*)));
729
730     connect(core, SIGNAL(saveSettingsRequested()),
731         this, SLOT(savePersistentSettings()));
732
733     addAutoReleasedObject(new ProjectTreeWidgetFactory);
734     addAutoReleasedObject(new FolderNavigationWidgetFactory);
735
736     if (QSettings *s = core->settings()) {
737         const QStringList fileNames = s->value("ProjectExplorer/RecentProjects/FileNames").toStringList();
738         const QStringList displayNames = s->value("ProjectExplorer/RecentProjects/DisplayNames").toStringList();
739         if (fileNames.size() == displayNames.size()) {
740             for (int i = 0; i < fileNames.size(); ++i) {
741                 if (QFileInfo(fileNames.at(i)).isFile())
742                     d->m_recentProjects.append(qMakePair(fileNames.at(i), displayNames.at(i)));
743             }
744         }
745     }
746
747     if (QSettings *s = core->settings()) {
748         d->m_projectExplorerSettings.buildBeforeRun = s->value("ProjectExplorer/Settings/BuildBeforeRun", true).toBool();
749         d->m_projectExplorerSettings.saveBeforeBuild = s->value("ProjectExplorer/Settings/SaveBeforeBuild", false).toBool();
750         d->m_projectExplorerSettings.showCompilerOutput = s->value("ProjectExplorer/Settings/ShowCompilerOutput", false).toBool();
751         d->m_projectExplorerSettings.cleanOldAppOutput = s->value("ProjectExplorer/Settings/CleanOldAppOutput", false).toBool();
752         d->m_projectExplorerSettings.useJom = s->value("ProjectExplorer/Settings/UseJom", true).toBool();
753     }
754
755     connect(d->m_sessionManagerAction, SIGNAL(triggered()), this, SLOT(showSessionManager()));
756     connect(d->m_newAction, SIGNAL(triggered()), this, SLOT(newProject()));
757 #if 0
758     connect(d->m_loadAction, SIGNAL(triggered()), this, SLOT(loadAction()));
759 #endif
760     connect(d->m_buildProjectOnlyAction, SIGNAL(triggered()), this, SLOT(buildProjectOnly()));
761     connect(d->m_buildAction, SIGNAL(triggered()), this, SLOT(buildProject()));
762     connect(d->m_buildActionContextMenu, SIGNAL(triggered()), this, SLOT(buildProjectContextMenu()));
763     connect(d->m_buildSessionAction, SIGNAL(triggered()), this, SLOT(buildSession()));
764     connect(d->m_rebuildProjectOnlyAction, SIGNAL(triggered()), this, SLOT(rebuildProjectOnly()));
765     connect(d->m_rebuildAction, SIGNAL(triggered()), this, SLOT(rebuildProject()));
766     connect(d->m_rebuildActionContextMenu, SIGNAL(triggered()), this, SLOT(rebuildProjectContextMenu()));
767     connect(d->m_rebuildSessionAction, SIGNAL(triggered()), this, SLOT(rebuildSession()));
768     connect(d->m_cleanProjectOnlyAction, SIGNAL(triggered()), this, SLOT(cleanProjectOnly()));
769     connect(d->m_cleanAction, SIGNAL(triggered()), this, SLOT(cleanProject()));
770     connect(d->m_cleanActionContextMenu, SIGNAL(triggered()), this, SLOT(cleanProjectContextMenu()));
771     connect(d->m_cleanSessionAction, SIGNAL(triggered()), this, SLOT(cleanSession()));
772     connect(d->m_runAction, SIGNAL(triggered()), this, SLOT(runProject()));
773     connect(d->m_runActionContextMenu, SIGNAL(triggered()), this, SLOT(runProjectContextMenu()));
774     connect(d->m_cancelBuildAction, SIGNAL(triggered()), this, SLOT(cancelBuild()));
775     connect(d->m_debugAction, SIGNAL(triggered()), this, SLOT(debugProject()));
776     connect(d->m_unloadAction, SIGNAL(triggered()), this, SLOT(unloadProject()));
777     connect(d->m_clearSession, SIGNAL(triggered()), this, SLOT(clearSession()));
778     connect(d->m_addNewFileAction, SIGNAL(triggered()), this, SLOT(addNewFile()));
779     connect(d->m_addExistingFilesAction, SIGNAL(triggered()), this, SLOT(addExistingFiles()));
780     connect(d->m_openFileAction, SIGNAL(triggered()), this, SLOT(openFile()));
781     connect(d->m_showInGraphicalShell, SIGNAL(triggered()), this, SLOT(showInGraphicalShell()));
782     connect(d->m_openTerminalHere, SIGNAL(triggered()), this, SLOT(openTerminalHere()));
783     connect(d->m_removeFileAction, SIGNAL(triggered()), this, SLOT(removeFile()));
784     connect(d->m_renameFileAction, SIGNAL(triggered()), this, SLOT(renameFile()));
785
786     updateActions();
787
788     connect(Core::ICore::instance(), SIGNAL(coreAboutToOpen()),
789             this, SLOT(determineSessionToRestoreAtStartup()));
790     connect(Core::ICore::instance(), SIGNAL(coreOpened()), this, SLOT(restoreSession()));
791
792     updateWelcomePage();
793
794     return true;
795 }
796
797 // Find a factory by file mime type in a sequence of factories
798 template <class Factory, class Iterator>
799     Factory *findFactory(const QString &mimeType, Iterator i1, Iterator i2)
800 {
801     for ( ; i1 != i2; ++i2) {
802         Factory *f = *i1;
803         if (f->mimeTypes().contains(mimeType))
804             return f;
805     }
806     return 0;
807 }
808
809 ProjectFileFactory * ProjectExplorerPlugin::findProjectFileFactory(const QString &filename) const
810 {
811     // Find factory
812     if (const Core::MimeType mt = Core::ICore::instance()->mimeDatabase()->findByFile(QFileInfo(filename)))
813         if (ProjectFileFactory *pf = findFactory<ProjectFileFactory>(mt.type(), d->m_fileFactories.constBegin(), d->m_fileFactories.constEnd()))
814             return pf;
815     qWarning("Unable to find project file factory for '%s'", filename.toUtf8().constData());
816     return 0;
817 }
818
819 void ProjectExplorerPlugin::loadAction()
820 {
821     if (debug)
822         qDebug() << "ProjectExplorerPlugin::loadAction";
823
824
825     QString dir = d->m_lastOpenDirectory;
826
827     // for your special convenience, we preselect a pro file if it is
828     // the current file
829     if (Core::IEditor *editor = Core::EditorManager::instance()->currentEditor()) {
830         if (const Core::IFile *file = editor->file()) {
831             const QString fn = file->fileName();
832             const bool isProject = d->m_profileMimeTypes.contains(file->mimeType());
833             dir = isProject ? fn : QFileInfo(fn).absolutePath();
834         }
835     }
836
837     QString filename = QFileDialog::getOpenFileName(0, tr("Load Project"),
838                                                     dir,
839                                                     d->m_projectFilterString);
840     if (filename.isEmpty())
841         return;
842     if (ProjectFileFactory *pf = findProjectFileFactory(filename))
843         pf->open(filename);
844     updateActions();
845 }
846
847 void ProjectExplorerPlugin::unloadProject()
848 {
849     if (debug)
850         qDebug() << "ProjectExplorerPlugin::unloadProject";
851
852     Core::IFile *fi = d->m_currentProject->file();
853
854     if (!fi || fi->fileName().isEmpty()) //nothing to save?
855         return;
856
857     QList<Core::IFile*> filesToSave;
858     filesToSave << fi;
859
860     // check the number of modified files
861     int readonlycount = 0;
862     foreach (const Core::IFile *file, filesToSave) {
863         if (file->isReadOnly())
864             ++readonlycount;
865     }
866
867     bool success = false;
868     if (readonlycount > 0)
869         success = Core::ICore::instance()->fileManager()->saveModifiedFiles(filesToSave).isEmpty();
870     else
871         success = Core::ICore::instance()->fileManager()->saveModifiedFilesSilently(filesToSave).isEmpty();
872
873     if (!success)
874         return;
875
876     addToRecentProjects(fi->fileName(), d->m_currentProject->displayName());
877     d->m_session->removeProject(d->m_currentProject);
878     updateActions();
879 }
880
881 void ProjectExplorerPlugin::clearSession()
882 {
883     if (debug)
884         qDebug() << "ProjectExplorerPlugin::clearSession";
885
886     if (!d->m_session->clear())
887         return; // Action has been cancelled
888     updateActions();
889 }
890
891 void ProjectExplorerPlugin::extensionsInitialized()
892 {
893     d->m_fileFactories = ProjectFileFactory::createFactories(&d->m_projectFilterString);
894     foreach (ProjectFileFactory *pf, d->m_fileFactories) {
895         d->m_profileMimeTypes += pf->mimeTypes();
896         addAutoReleasedObject(pf);
897     }
898     // Add custom wizards, for which other plugins might have registered
899     // class factories
900     foreach(Core::IWizard *cpw, ProjectExplorer::CustomWizard::createWizards())
901         addAutoReleasedObject(cpw);
902 }
903
904 void ProjectExplorerPlugin::aboutToShutdown()
905 {
906     d->m_proWindow->aboutToShutdown(); // disconnect from session
907     d->m_session->clear();
908     d->m_projectsMode = 0;
909 //    d->m_proWindow->saveConfigChanges();
910 }
911
912 void ProjectExplorerPlugin::newProject()
913 {
914     if (debug)
915         qDebug() << "ProjectExplorerPlugin::newProject";
916
917     QString defaultLocation;
918     if (currentProject()) {
919         QDir dir(currentProject()->projectDirectory());
920         dir.cdUp();
921         defaultLocation = dir.absolutePath();
922     }
923
924     Core::ICore::instance()->showNewItemDialog(tr("New Project", "Title of dialog"),
925                               Core::IWizard::wizardsOfKind(Core::IWizard::ProjectWizard),
926                               defaultLocation);
927     updateActions();
928 }
929
930 void ProjectExplorerPlugin::showSessionManager()
931 {
932     if (debug)
933         qDebug() << "ProjectExplorerPlugin::showSessionManager";
934
935     if (d->m_session->isDefaultVirgin()) {
936         // do not save new virgin default sessions
937     } else {
938         d->m_session->save();
939     }
940     SessionDialog sessionDialog(d->m_session);
941     sessionDialog.exec();
942
943     updateActions();
944
945     Core::ModeManager *modeManager = Core::ModeManager::instance();
946     Core::IMode *welcomeMode = modeManager->mode(Core::Constants::MODE_WELCOME);
947     if (modeManager->currentMode() == welcomeMode)
948         updateWelcomePage();
949 }
950
951 void ProjectExplorerPlugin::setStartupProject(Project *project)
952 {
953     if (debug)
954         qDebug() << "ProjectExplorerPlugin::setStartupProject";
955
956     if (!project)
957         return;
958     d->m_session->setStartupProject(project);
959     updateActions();
960 }
961
962 void ProjectExplorerPlugin::savePersistentSettings()
963 {
964     if (debug)
965         qDebug()<<"ProjectExplorerPlugin::savePersistentSettings()";
966
967     foreach (Project *pro, d->m_session->projects())
968         pro->saveSettings();
969
970     if (d->m_session->isDefaultVirgin()) {
971         // do not save new virgin default sessions
972     } else {
973         d->m_session->save();
974     }
975
976     QSettings *s = Core::ICore::instance()->settings();
977     if (s) {
978         s->setValue("ProjectExplorer/StartupSession", d->m_session->currentSession());
979         s->remove("ProjectExplorer/RecentProjects/Files");
980
981         QStringList fileNames;
982         QStringList displayNames;
983         QList<QPair<QString, QString> >::const_iterator it, end;
984         end = d->m_recentProjects.constEnd();
985         for (it = d->m_recentProjects.constBegin(); it != end; ++it) {
986             fileNames << (*it).first;
987             displayNames << (*it).second;
988         }
989
990         s->setValue("ProjectExplorer/RecentProjects/FileNames", fileNames);
991         s->setValue("ProjectExplorer/RecentProjects/DisplayNames", displayNames);
992
993         s->setValue("ProjectExplorer/Settings/BuildBeforeRun", d->m_projectExplorerSettings.buildBeforeRun);
994         s->setValue("ProjectExplorer/Settings/SaveBeforeBuild", d->m_projectExplorerSettings.saveBeforeBuild);
995         s->setValue("ProjectExplorer/Settings/ShowCompilerOutput", d->m_projectExplorerSettings.showCompilerOutput);
996         s->setValue("ProjectExplorer/Settings/CleanOldAppOutput", d->m_projectExplorerSettings.cleanOldAppOutput);
997         s->setValue("ProjectExplorer/Settings/UseJom", d->m_projectExplorerSettings.useJom);
998     }
999 }
1000
1001 bool ProjectExplorerPlugin::openProject(const QString &fileName)
1002 {
1003     if (debug)
1004         qDebug() << "ProjectExplorerPlugin::openProject";
1005
1006     QList<Project *> list = openProjects(QStringList() << fileName);
1007     if (!list.isEmpty()) {
1008         addToRecentProjects(fileName, list.first()->displayName());
1009         return true;
1010     }
1011     return false;
1012 }
1013
1014 static inline QList<IProjectManager*> allProjectManagers()
1015 {
1016     ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
1017     return pm->getObjects<IProjectManager>();
1018 }
1019
1020 QList<Project *> ProjectExplorerPlugin::openProjects(const QStringList &fileNames)
1021 {
1022     if (debug)
1023         qDebug() << "ProjectExplorerPlugin - opening projects " << fileNames;
1024
1025     const QList<IProjectManager*> projectManagers = allProjectManagers();
1026
1027     QList<Project*> openedPro;
1028     foreach (const QString &fileName, fileNames) {
1029         if (const Core::MimeType mt = Core::ICore::instance()->mimeDatabase()->findByFile(QFileInfo(fileName))) {
1030             foreach (IProjectManager *manager, projectManagers) {
1031                 if (manager->mimeType() == mt.type()) {
1032                     if (Project *pro = manager->openProject(fileName)) {
1033                         if (pro->restoreSettings()) {
1034                             connect(pro, SIGNAL(fileListChanged()), this, SIGNAL(fileListChanged()));
1035                             d->m_session->addProject(pro);
1036                             // Make sure we always have a current project / node
1037                             if (!d->m_currentProject && !openedPro.isEmpty())
1038                                 setCurrentNode(pro->rootProjectNode());
1039                             openedPro += pro;
1040                         } else {
1041                             delete pro;
1042                         }
1043                     }
1044                     d->m_session->reportProjectLoadingProgress();
1045                     break;
1046                 }
1047             }
1048         }
1049     }
1050     updateActions();
1051
1052     if (openedPro.isEmpty()) {
1053         qDebug() << "ProjectExplorerPlugin - Could not open any projects!";
1054     } else {
1055         Core::ModeManager::instance()->activateMode(Core::Constants::MODE_EDIT);
1056     }
1057
1058     return openedPro;
1059 }
1060
1061 Project *ProjectExplorerPlugin::currentProject() const
1062 {
1063     if (debug) {
1064         if (d->m_currentProject)
1065             qDebug() << "ProjectExplorerPlugin::currentProject returns " << d->m_currentProject->displayName();
1066         else
1067             qDebug() << "ProjectExplorerPlugin::currentProject returns 0";
1068     }
1069     return d->m_currentProject;
1070 }
1071
1072 Node *ProjectExplorerPlugin::currentNode() const
1073 {
1074     return d->m_currentNode;
1075 }
1076
1077 void ProjectExplorerPlugin::setCurrentFile(Project *project, const QString &filePath)
1078 {
1079     setCurrent(project, filePath, 0);
1080 }
1081
1082 void ProjectExplorerPlugin::setCurrentFile(const QString &filePath)
1083 {
1084     Project *project = d->m_session->projectForFile(filePath);
1085     // If the file is not in any project, stay with the current project
1086     // e.g. on opening a git diff buffer, git log buffer, we don't change the project
1087     // I'm not 100% sure this is correct
1088     if (!project)
1089         project = d->m_currentProject;
1090     setCurrent(project, filePath, 0);
1091 }
1092
1093 void ProjectExplorerPlugin::setCurrentNode(Node *node)
1094 {
1095     setCurrent(d->m_session->projectForNode(node), QString(), node);
1096 }
1097
1098 SessionManager *ProjectExplorerPlugin::session() const
1099 {
1100     return d->m_session;
1101 }
1102
1103 Project *ProjectExplorerPlugin::startupProject() const
1104 {
1105     if (debug)
1106         qDebug() << "ProjectExplorerPlugin::startupProject";
1107
1108     return d->m_session->startupProject();
1109 }
1110
1111 void ProjectExplorerPlugin::updateWelcomePage()
1112 {
1113     ProjectWelcomePageWidget::WelcomePageData welcomePageData;
1114     welcomePageData.sessionList =  d->m_session->sessions();
1115     welcomePageData.activeSession = d->m_session->activeSession();
1116     welcomePageData.previousSession = d->m_session->lastSession();
1117     welcomePageData.projectList = d->m_recentProjects;
1118     d->m_welcomePage->setWelcomePageData(welcomePageData);
1119 }
1120
1121 void ProjectExplorerPlugin::currentModeChanged(Core::IMode *mode, Core::IMode *oldMode)
1122 {
1123     if (mode && mode->id() == QLatin1String(Core::Constants::MODE_WELCOME))
1124         updateWelcomePage();
1125     if (oldMode == d->m_projectsMode)
1126         savePersistentSettings();
1127 }
1128
1129 void ProjectExplorerPlugin::determineSessionToRestoreAtStartup()
1130 {
1131     QStringList sessions = d->m_session->sessions();
1132     // We have command line arguments, try to find a session in them
1133     QStringList arguments = ExtensionSystem::PluginManager::instance()->arguments();
1134     // Default to no session loading
1135     d->m_sessionToRestoreAtStartup.clear();
1136     foreach (const QString &arg, arguments) {
1137         if (sessions.contains(arg)) {
1138             // Session argument
1139             d->m_sessionToRestoreAtStartup = arg;
1140             break;
1141         }
1142     }
1143     if (!d->m_sessionToRestoreAtStartup.isNull())
1144         Core::ICore::instance()->modeManager()->activateMode(Core::Constants::MODE_EDIT);
1145 }
1146
1147 /*!
1148     \fn void ProjectExplorerPlugin::restoreSession()
1149
1150     This method is connected to the ICore::coreOpened signal.  If
1151     there was no session explicitly loaded, it creates an empty new
1152     default session and puts the list of recent projects and sessions
1153     onto the welcome page.
1154 */
1155 void ProjectExplorerPlugin::restoreSession()
1156 {
1157     if (debug)
1158         qDebug() << "ProjectExplorerPlugin::restoreSession";
1159
1160     // We have command line arguments, try to find a session in them
1161     QStringList arguments = ExtensionSystem::PluginManager::instance()->arguments();
1162     arguments.removeOne(d->m_sessionToRestoreAtStartup);
1163
1164     // Restore latest session or what was passed on the command line
1165     if (d->m_sessionToRestoreAtStartup.isEmpty()) {
1166         d->m_session->createAndLoadNewDefaultSession();
1167     } else {
1168         d->m_session->loadSession(d->m_sessionToRestoreAtStartup);
1169     }
1170
1171     // update welcome page
1172     Core::ModeManager *modeManager = Core::ModeManager::instance();
1173     connect(modeManager, SIGNAL(currentModeChanged(Core::IMode*, Core::IMode*)),
1174             this, SLOT(currentModeChanged(Core::IMode*, Core::IMode*)));
1175     connect(d->m_welcomePage, SIGNAL(requestSession(QString)), this, SLOT(loadSession(QString)));
1176     connect(d->m_welcomePage, SIGNAL(requestProject(QString)), this, SLOT(loadProject(QString)));
1177
1178     Core::ICore::instance()->openFiles(arguments);
1179     updateActions();
1180
1181 }
1182
1183 void ProjectExplorerPlugin::loadSession(const QString &session)
1184 {
1185     if (debug)
1186         qDebug() << "ProjectExplorerPlugin::loadSession" << session;
1187     d->m_session->loadSession(session);
1188 }
1189
1190
1191 void ProjectExplorerPlugin::showContextMenu(const QPoint &globalPos, Node *node)
1192 {
1193     QMenu *contextMenu = 0;
1194
1195     if (!node)
1196         node = d->m_session->sessionNode();
1197
1198     if (node->nodeType() != SessionNodeType) {
1199         Project *project = d->m_session->projectForNode(node);
1200         setCurrentNode(node);
1201
1202         emit aboutToShowContextMenu(project, node);
1203         switch (node->nodeType()) {
1204         case ProjectNodeType:
1205             if (node->parentFolderNode() == d->m_session->sessionNode())
1206                 contextMenu = d->m_projectMenu;
1207             else
1208                 contextMenu = d->m_subProjectMenu;
1209             break;
1210         case FolderNodeType:
1211             contextMenu = d->m_folderMenu;
1212             break;
1213         case FileNodeType:
1214             populateOpenWithMenu();
1215             contextMenu = d->m_fileMenu;
1216             break;
1217         default:
1218             qWarning("ProjectExplorerPlugin::showContextMenu - Missing handler for node type");
1219         }
1220     } else { // session item
1221         emit aboutToShowContextMenu(0, node);
1222
1223         contextMenu = d->m_sessionContextMenu;
1224     }
1225
1226     updateContextMenuActions(d->m_currentNode);
1227     if (contextMenu && contextMenu->actions().count() > 0) {
1228         contextMenu->popup(globalPos);
1229     }
1230 }
1231
1232 BuildManager *ProjectExplorerPlugin::buildManager() const
1233 {
1234     return d->m_buildManager;
1235 }
1236
1237 void ProjectExplorerPlugin::buildStateChanged(Project * pro)
1238 {
1239     if (debug) {
1240         qDebug() << "buildStateChanged";
1241         qDebug() << pro->file()->fileName() << "isBuilding()" << d->m_buildManager->isBuilding(pro);
1242     }
1243     Q_UNUSED(pro)
1244     updateActions();
1245 }
1246
1247 void ProjectExplorerPlugin::executeRunConfiguration(RunConfiguration *runConfiguration, const QString &runMode)
1248 {
1249     if (IRunControlFactory *runControlFactory = findRunControlFactory(runConfiguration, runMode)) {
1250         emit aboutToExecuteProject(runConfiguration->target()->project(), runMode);
1251
1252         RunControl *control = runControlFactory->create(runConfiguration, runMode);
1253         startRunControl(control, runMode);
1254     }
1255
1256 }
1257
1258 void ProjectExplorerPlugin::startRunControl(RunControl *runControl, const QString &runMode)
1259 {
1260     d->m_outputPane->createNewOutputWindow(runControl);
1261     if (runMode == ProjectExplorer::Constants::RUNMODE)
1262         d->m_outputPane->popup(false);
1263     d->m_outputPane->showTabFor(runControl);
1264     if (projectExplorerSettings().cleanOldAppOutput)
1265         d->m_outputPane->clearContents();
1266
1267     connect(runControl, SIGNAL(addToOutputWindow(RunControl *, const QString &, bool)),
1268             d->m_outputPane, SLOT(appendApplicationOutput(RunControl*,const QString &, bool)));
1269     connect(runControl, SIGNAL(addToOutputWindowInline(RunControl *, const QString &, bool)),
1270             d->m_outputPane, SLOT(appendApplicationOutputInline(RunControl*,const QString &, bool)));
1271     connect(runControl, SIGNAL(appendMessage(RunControl*,QString,bool)),
1272             d->m_outputPane, SLOT(appendMessage(RunControl *, const QString &, bool)));
1273
1274     connect(runControl, SIGNAL(finished()),
1275             this, SLOT(runControlFinished()));
1276
1277     if (runMode == ProjectExplorer::Constants::DEBUGMODE)
1278         d->m_debuggingRunControl = runControl;
1279
1280     runControl->start();
1281     updateRunActions();
1282 }
1283
1284 void ProjectExplorerPlugin::buildQueueFinished(bool success)
1285 {
1286     if (debug)
1287         qDebug() << "buildQueueFinished()" << success;
1288
1289     updateActions();
1290
1291     if (success && d->m_delayedRunConfiguration) {
1292         executeRunConfiguration(d->m_delayedRunConfiguration, d->m_runMode);
1293     } else {
1294         if (d->m_buildManager->tasksAvailable())
1295             d->m_buildManager->showTaskWindow();
1296     }
1297     d->m_delayedRunConfiguration = 0;
1298     d->m_runMode.clear();
1299 }
1300
1301 void ProjectExplorerPlugin::setCurrent(Project *project, QString filePath, Node *node)
1302 {
1303     if (debug)
1304         qDebug() << "ProjectExplorer - setting path to " << (node ? node->path() : filePath)
1305                 << " and project to " << (project ? project->displayName() : "0");
1306
1307     if (node)
1308         filePath = node->path();
1309     else
1310         node = d->m_session->nodeForFile(filePath, project);
1311
1312     Core::ICore *core = Core::ICore::instance();
1313
1314     bool projectChanged = false;
1315     if (d->m_currentProject != project) {
1316         Core::Context oldContext;
1317         Core::Context newContext;
1318
1319         if (d->m_currentProject) {
1320             oldContext.add(d->m_currentProject->projectManager()->projectContext());
1321             oldContext.add(d->m_currentProject->projectManager()->projectLanguage());
1322         }
1323         if (project) {
1324             newContext.add(project->projectManager()->projectContext());
1325             newContext.add(project->projectManager()->projectLanguage());
1326         }
1327
1328         core->updateAdditionalContexts(oldContext, newContext);
1329
1330         d->m_currentProject = project;
1331
1332         projectChanged = true;
1333     }
1334
1335     if (projectChanged || d->m_currentNode != node) {
1336         d->m_currentNode = node;
1337         if (debug)
1338             qDebug() << "ProjectExplorer - currentNodeChanged(" << (node ? node->path() : "0") << ", " << (project ? project->displayName() : "0") << ")";
1339         emit currentNodeChanged(d->m_currentNode, project);
1340     }
1341     if (projectChanged) {
1342         if (debug)
1343             qDebug() << "ProjectExplorer - currentProjectChanged(" << (project ? project->displayName() : "0") << ")";
1344         emit currentProjectChanged(project);
1345         updateActions();
1346     }
1347
1348     core->fileManager()->setCurrentFile(filePath);
1349 }
1350
1351 void ProjectExplorerPlugin::updateActions()
1352 {
1353     if (debug)
1354         qDebug() << "ProjectExplorerPlugin::updateActions";
1355
1356     Project *startupProject = session()->startupProject();
1357     bool enableBuildActions = startupProject
1358                               && ! (d->m_buildManager->isBuilding(startupProject))
1359                               && hasBuildSettings(startupProject);
1360
1361     bool enableBuildActionsContextMenu = d->m_currentProject
1362                               && ! (d->m_buildManager->isBuilding(d->m_currentProject))
1363                               && hasBuildSettings(d->m_currentProject);
1364
1365
1366     bool hasProjects = !d->m_session->projects().isEmpty();
1367     bool building = d->m_buildManager->isBuilding();
1368     QString projectName = startupProject ? startupProject->displayName() : QString();
1369     QString projectNameContextMenu = d->m_currentProject ? d->m_currentProject->displayName() : QString();
1370
1371     if (debug)
1372         qDebug() << "BuildManager::isBuilding()" << building;
1373
1374     d->m_unloadAction->setParameter(projectNameContextMenu);
1375
1376     d->m_buildAction->setParameter(projectName);
1377     d->m_rebuildAction->setParameter(projectName);
1378     d->m_cleanAction->setParameter(projectName);
1379
1380     d->m_buildAction->setEnabled(enableBuildActions);
1381     d->m_rebuildAction->setEnabled(enableBuildActions);
1382     d->m_cleanAction->setEnabled(enableBuildActions);
1383
1384     d->m_buildActionContextMenu->setParameter(projectNameContextMenu);
1385     d->m_rebuildActionContextMenu->setParameter(projectNameContextMenu);
1386     d->m_cleanActionContextMenu->setParameter(projectNameContextMenu);
1387
1388     d->m_buildActionContextMenu->setEnabled(enableBuildActionsContextMenu);
1389     d->m_rebuildActionContextMenu->setEnabled(enableBuildActionsContextMenu);
1390     d->m_cleanActionContextMenu->setEnabled(enableBuildActionsContextMenu);
1391
1392     d->m_buildProjectOnlyAction->setEnabled(enableBuildActions);
1393     d->m_rebuildProjectOnlyAction->setEnabled(enableBuildActions);
1394     d->m_cleanProjectOnlyAction->setEnabled(enableBuildActions);
1395
1396     d->m_clearSession->setEnabled(hasProjects && !building);
1397     d->m_buildSessionAction->setEnabled(hasProjects && !building);
1398     d->m_rebuildSessionAction->setEnabled(hasProjects && !building);
1399     d->m_cleanSessionAction->setEnabled(hasProjects && !building);
1400     d->m_cancelBuildAction->setEnabled(building);
1401
1402     d->m_projectSelectorAction->setEnabled(!session()->projects().isEmpty());
1403     d->m_projectSelectorActionMenu->setEnabled(!session()->projects().isEmpty());
1404
1405     updateRunActions();
1406 }
1407
1408 // NBS TODO check projectOrder()
1409 // what we want here is all the projects pro depends on
1410 QStringList ProjectExplorerPlugin::allFilesWithDependencies(Project *pro)
1411 {
1412     if (debug)
1413         qDebug() << "ProjectExplorerPlugin::allFilesWithDependencies(" << pro->file()->fileName() << ")";
1414
1415     QStringList filesToSave;
1416     foreach (Project *p, d->m_session->projectOrder(pro)) {
1417         FindAllFilesVisitor filesVisitor;
1418         p->rootProjectNode()->accept(&filesVisitor);
1419         filesToSave << filesVisitor.filePaths();
1420     }
1421     qSort(filesToSave);
1422     return filesToSave;
1423 }
1424
1425 bool ProjectExplorerPlugin::saveModifiedFiles()
1426 {
1427     if (debug)
1428         qDebug() << "ProjectExplorerPlugin::saveModifiedFiles";
1429
1430     QList<Core::IFile *> filesToSave = Core::ICore::instance()->fileManager()->modifiedFiles();
1431     if (!filesToSave.isEmpty()) {
1432         if (d->m_projectExplorerSettings.saveBeforeBuild) {
1433             Core::ICore::instance()->fileManager()->saveModifiedFilesSilently(filesToSave);
1434         } else {
1435             bool cancelled = false;
1436             bool alwaysSave = false;
1437
1438             Core::FileManager *fm = Core::ICore::instance()->fileManager();
1439             fm->saveModifiedFiles(filesToSave, &cancelled, QString(),
1440                                   tr("Always save files before build"), &alwaysSave);
1441
1442             if (cancelled)
1443                 return false;
1444             if (alwaysSave)
1445                 d->m_projectExplorerSettings.saveBeforeBuild = true;
1446         }
1447     }
1448     return true;
1449 }
1450
1451 //NBS handle case where there is no activeBuildConfiguration
1452 // because someone delete all build configurations
1453
1454 void ProjectExplorerPlugin::buildProjectOnly()
1455 {
1456     if (debug)
1457         qDebug() << "ProjectExplorerPlugin::buildProjectOnly";
1458
1459     if (saveModifiedFiles())
1460         buildManager()->buildProject(session()->startupProject()->activeTarget()->activeBuildConfiguration());
1461 }
1462
1463 void ProjectExplorerPlugin::buildProject()
1464 {
1465     if (debug)
1466         qDebug() << "ProjectExplorerPlugin::buildProject";
1467
1468     if (saveModifiedFiles()) {
1469         QList<BuildConfiguration *> configurations;
1470         foreach (Project *pro, d->m_session->projectOrder(session()->startupProject()))
1471             if (pro->activeTarget()->activeBuildConfiguration())
1472                 configurations << pro->activeTarget()->activeBuildConfiguration();
1473
1474         d->m_buildManager->buildProjects(configurations);
1475     }
1476 }
1477
1478 void ProjectExplorerPlugin::buildProjectContextMenu()
1479 {
1480     if (debug)
1481         qDebug() << "ProjectExplorerPlugin::buildProjectContextMenu";
1482
1483     if (saveModifiedFiles()) {
1484         QList<BuildConfiguration *> configurations;
1485         foreach (Project *pro, d->m_session->projectOrder(d->m_currentProject))
1486             if (pro->activeTarget()->activeBuildConfiguration())
1487                 configurations << pro->activeTarget()->activeBuildConfiguration();
1488
1489         d->m_buildManager->buildProjects(configurations);
1490     }
1491 }
1492
1493 void ProjectExplorerPlugin::buildSession()
1494 {
1495     if (debug)
1496         qDebug() << "ProjectExplorerPlugin::buildSession";
1497
1498     if (saveModifiedFiles()) {
1499         QList<BuildConfiguration *> configurations;
1500         foreach (Project *pro, d->m_session->projectOrder())
1501             if (pro->activeTarget()->activeBuildConfiguration())
1502                 configurations << pro->activeTarget()->activeBuildConfiguration();
1503         d->m_buildManager->buildProjects(configurations);
1504     }
1505 }
1506
1507 void ProjectExplorerPlugin::rebuildProjectOnly()
1508 {
1509     if (debug)
1510         qDebug() << "ProjectExplorerPlugin::rebuildProjectOnly";
1511
1512     if (saveModifiedFiles()) {
1513         d->m_buildManager->cleanProject(session()->startupProject()->activeTarget()->activeBuildConfiguration());
1514         d->m_buildManager->buildProject(session()->startupProject()->activeTarget()->activeBuildConfiguration());
1515     }
1516 }
1517
1518 void ProjectExplorerPlugin::rebuildProject()
1519 {
1520     if (debug)
1521         qDebug() << "ProjectExplorerPlugin::rebuildProject";
1522
1523     if (saveModifiedFiles()) {
1524         const QList<Project *> &projects = d->m_session->projectOrder(session()->startupProject());
1525         QList<BuildConfiguration *> configurations;
1526         foreach (Project *pro, projects)
1527             if (pro->activeTarget()->activeBuildConfiguration())
1528                 configurations << pro->activeTarget()->activeBuildConfiguration();
1529
1530         d->m_buildManager->cleanProjects(configurations);
1531         d->m_buildManager->buildProjects(configurations);
1532     }
1533 }
1534
1535 void ProjectExplorerPlugin::rebuildProjectContextMenu()
1536 {
1537     if (debug)
1538         qDebug() << "ProjectExplorerPlugin::rebuildProjectContextMenu";
1539
1540     if (saveModifiedFiles()) {
1541         const QList<Project *> &projects = d->m_session->projectOrder(d->m_currentProject);
1542         QList<BuildConfiguration *> configurations;
1543         foreach (Project *pro, projects)
1544             if (pro->activeTarget()->activeBuildConfiguration())
1545                 configurations << pro->activeTarget()->activeBuildConfiguration();
1546
1547         d->m_buildManager->cleanProjects(configurations);
1548         d->m_buildManager->buildProjects(configurations);
1549     }
1550 }
1551
1552 void ProjectExplorerPlugin::rebuildSession()
1553 {
1554     if (debug)
1555         qDebug() << "ProjectExplorerPlugin::rebuildSession";
1556
1557     if (saveModifiedFiles()) {
1558         const QList<Project *> & projects = d->m_session->projectOrder();
1559         QList<BuildConfiguration *> configurations;
1560         foreach (Project *pro, projects)
1561             if (pro->activeTarget()->activeBuildConfiguration())
1562                 configurations << pro->activeTarget()->activeBuildConfiguration();
1563
1564         d->m_buildManager->cleanProjects(configurations);
1565         d->m_buildManager->buildProjects(configurations);
1566     }
1567 }
1568
1569 void ProjectExplorerPlugin::cleanProjectOnly()
1570 {
1571     if (debug)
1572         qDebug() << "ProjectExplorerPlugin::cleanProjectOnly";
1573
1574     if (saveModifiedFiles())
1575         d->m_buildManager->cleanProject(session()->startupProject()->activeTarget()->activeBuildConfiguration());
1576 }
1577
1578 void ProjectExplorerPlugin::cleanProject()
1579 {
1580     if (debug)
1581         qDebug() << "ProjectExplorerPlugin::cleanProject";
1582
1583     if (saveModifiedFiles()) {
1584         const QList<Project *> & projects = d->m_session->projectOrder(session()->startupProject());
1585         QList<BuildConfiguration *> configurations;
1586         foreach (Project *pro, projects)
1587             if (pro->activeTarget()->activeBuildConfiguration())
1588                 configurations << pro->activeTarget()->activeBuildConfiguration();
1589         d->m_buildManager->cleanProjects(configurations);
1590     }
1591 }
1592
1593 void ProjectExplorerPlugin::cleanProjectContextMenu()
1594 {
1595     if (debug)
1596         qDebug() << "ProjectExplorerPlugin::cleanProjectContextMenu";
1597
1598     if (saveModifiedFiles()) {
1599         const QList<Project *> & projects = d->m_session->projectOrder(d->m_currentProject);
1600         QList<BuildConfiguration *> configurations;
1601         foreach (Project *pro, projects)
1602             if (pro->activeTarget()->activeBuildConfiguration())
1603                 configurations << pro->activeTarget()->activeBuildConfiguration();
1604         d->m_buildManager->cleanProjects(configurations);
1605     }
1606 }
1607
1608 void ProjectExplorerPlugin::cleanSession()
1609 {
1610     if (debug)
1611         qDebug() << "ProjectExplorerPlugin::cleanSession";
1612
1613     if (saveModifiedFiles()) {
1614         const QList<Project *> & projects = d->m_session->projectOrder();
1615         QList<BuildConfiguration *> configurations;
1616         foreach (Project *pro, projects)
1617             if (pro->activeTarget()->activeBuildConfiguration())
1618                 configurations << pro->activeTarget()->activeBuildConfiguration();
1619         d->m_buildManager->cleanProjects(configurations);
1620     }
1621 }
1622
1623 void ProjectExplorerPlugin::runProject()
1624 {
1625     runProjectImpl(startupProject(), ProjectExplorer::Constants::RUNMODE);
1626 }
1627
1628 void ProjectExplorerPlugin::runProjectContextMenu()
1629 {
1630     runProjectImpl(d->m_currentProject, ProjectExplorer::Constants::RUNMODE);
1631 }
1632
1633 bool ProjectExplorerPlugin::hasBuildSettings(Project *pro)
1634 {
1635     const QList<Project *> & projects = d->m_session->projectOrder(pro);
1636     foreach(Project *project, projects)
1637         if (project->activeTarget()->activeBuildConfiguration())
1638             return true;
1639     return false;
1640 }
1641
1642 void ProjectExplorerPlugin::runProjectImpl(Project *pro, QString mode)
1643 {
1644     if (!pro)
1645         return;
1646
1647     if (d->m_projectExplorerSettings.buildBeforeRun && hasBuildSettings(pro)) {
1648         if (!pro->activeTarget()->activeRunConfiguration()->isEnabled()) {
1649             if (!showBuildConfigDialog())
1650                 return;
1651         }
1652         if (saveModifiedFiles()) {
1653             d->m_runMode = mode;
1654             d->m_delayedRunConfiguration = pro->activeTarget()->activeRunConfiguration();
1655
1656             const QList<Project *> & projects = d->m_session->projectOrder(pro);
1657             QList<BuildConfiguration *> configurations;
1658             foreach(Project *project, projects)
1659                 if (project->activeTarget()->activeBuildConfiguration())
1660                     configurations << project->activeTarget()->activeBuildConfiguration();
1661             d->m_buildManager->buildProjects(configurations);
1662
1663             updateRunActions();
1664         }
1665     } else {
1666         // TODO this ignores RunConfiguration::isEnabled()
1667         if (saveModifiedFiles())
1668             executeRunConfiguration(pro->activeTarget()->activeRunConfiguration(), mode);
1669     }
1670 }
1671
1672 void ProjectExplorerPlugin::debugProject()
1673 {
1674     Project *pro = startupProject();
1675     if (!pro || d->m_debuggingRunControl )
1676         return;
1677
1678     runProjectImpl(pro, ProjectExplorer::Constants::DEBUGMODE);
1679 }
1680
1681 bool ProjectExplorerPlugin::showBuildConfigDialog()
1682 {
1683     Project *pro = startupProject();
1684     BuildConfigDialog *dialog = new BuildConfigDialog(pro,
1685                                                       Core::ICore::instance()->mainWindow());
1686     dialog->exec();
1687     BuildConfiguration *otherConfig = dialog->selectedBuildConfiguration();
1688     int result = dialog->result();
1689     dialog->deleteLater();
1690     switch (result) {
1691     case BuildConfigDialog::ChangeBuild:
1692         if (otherConfig) {
1693             pro->activeTarget()->setActiveBuildConfiguration(otherConfig);
1694             return true;
1695         }
1696         return false;
1697     case BuildConfigDialog::Cancel:
1698         return false;
1699     case BuildConfigDialog::Continue:
1700         return true;
1701     default:
1702         return false;
1703     }
1704 }
1705
1706 void ProjectExplorerPlugin::runControlFinished()
1707 {
1708     if (sender() == d->m_debuggingRunControl)
1709         d->m_debuggingRunControl = 0;
1710
1711     updateRunActions();
1712 }
1713
1714 void ProjectExplorerPlugin::startupProjectChanged()
1715 {
1716     static QPointer<Project> previousStartupProject = 0;
1717     Project *project = startupProject();
1718     if (project == previousStartupProject)
1719         return;
1720
1721     if (d->m_projectsMode)
1722         d->m_projectsMode->setEnabled(project);
1723
1724     if (previousStartupProject) {
1725         disconnect(previousStartupProject->activeTarget(), SIGNAL(activeRunConfigurationChanged(ProjectExplorer::RunConfiguration*)),
1726                 this, SLOT(updateRunActions()));
1727
1728         disconnect(previousStartupProject, SIGNAL(activeTargetChanged(ProjectExplorer::Target*)),
1729                    this, SLOT(updateRunActions()));
1730         disconnect(previousStartupProject->activeTarget()->activeRunConfiguration(),
1731                    SIGNAL(isEnabledChanged(bool)), this, SLOT(updateRunActions()));
1732
1733         foreach (Target *t, previousStartupProject->targets())
1734             disconnect(t, SIGNAL(activeRunConfigurationChanged(ProjectExplorer::RunConfiguration*)),
1735                        this, SLOT(updateActions()));
1736     }
1737
1738     previousStartupProject = project;
1739
1740     if (project) {
1741         connect(project, SIGNAL(activeTargetChanged(ProjectExplorer::Target*)),
1742                 this, SLOT(updateRunActions()));
1743
1744         connect(project->activeTarget(), SIGNAL(activeRunConfigurationChanged(ProjectExplorer::RunConfiguration*)),
1745                 this, SLOT(updateRunActions()));
1746
1747         if (project->activeTarget()->activeRunConfiguration()) {
1748             connect(project->activeTarget()->activeRunConfiguration(), SIGNAL(isEnabledChanged(bool)),
1749                     this, SLOT(updateRunActions()));
1750             foreach (Target *t, project->targets())
1751                 connect(t, SIGNAL(activeRunConfigurationChanged(ProjectExplorer::RunConfiguration*)),
1752                     this, SLOT(updateActions()));
1753         }
1754     }
1755
1756     updateRunActions();
1757 }
1758
1759 // NBS TODO implement more than one runner
1760 IRunControlFactory *ProjectExplorerPlugin::findRunControlFactory(RunConfiguration *config, const QString &mode)
1761 {
1762     ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
1763     const QList<IRunControlFactory *> factories = pm->getObjects<IRunControlFactory>();
1764     foreach (IRunControlFactory *f, factories)
1765         if (f->canRun(config, mode))
1766             return f;
1767     return 0;
1768 }
1769
1770 void ProjectExplorerPlugin::updateRunActions()
1771 {
1772     const Project *project = startupProject();
1773
1774     if (!project ||
1775         !project->activeTarget() ||
1776         !project->activeTarget()->activeRunConfiguration()) {
1777
1778         d->m_runAction->setToolTip(tr("Cannot run without a project."));
1779         d->m_debugAction->setToolTip(tr("Cannot debug without a project."));
1780
1781         d->m_runAction->setEnabled(false);
1782         d->m_debugAction->setEnabled(false);
1783         return;
1784     }
1785     d->m_runAction->setToolTip(QString());
1786     d->m_debugAction->setToolTip(QString());
1787
1788     RunConfiguration *activeRC = project->activeTarget()->activeRunConfiguration();
1789
1790     bool canRun = findRunControlFactory(activeRC, ProjectExplorer::Constants::RUNMODE)
1791                   && activeRC->isEnabled();
1792     const bool canDebug = !d->m_debuggingRunControl && findRunControlFactory(activeRC, ProjectExplorer::Constants::DEBUGMODE)
1793                           && activeRC->isEnabled();
1794     const bool building = d->m_buildManager->isBuilding();
1795
1796     d->m_runAction->setEnabled(canRun && !building);
1797
1798     canRun = session()->startupProject() && findRunControlFactory(activeRC, ProjectExplorer::Constants::RUNMODE);
1799
1800     d->m_runActionContextMenu->setEnabled(canRun && !building);
1801
1802     d->m_debugAction->setEnabled(canDebug && !building);
1803
1804 }
1805
1806 void ProjectExplorerPlugin::cancelBuild()
1807 {
1808     if (debug)
1809         qDebug() << "ProjectExplorerPlugin::cancelBuild";
1810
1811     if (d->m_buildManager->isBuilding())
1812         d->m_buildManager->cancel();
1813 }
1814
1815 void ProjectExplorerPlugin::addToRecentProjects(const QString &fileName, const QString &displayName)
1816 {
1817     if (debug)
1818         qDebug() << "ProjectExplorerPlugin::addToRecentProjects(" << fileName << ")";
1819
1820     if (fileName.isEmpty())
1821         return;
1822     QString prettyFileName(QDir::toNativeSeparators(fileName));
1823
1824     QList<QPair<QString, QString> >::iterator it;
1825     for(it = d->m_recentProjects.begin(); it != d->m_recentProjects.end();)
1826         if ((*it).first == prettyFileName)
1827             it = d->m_recentProjects.erase(it);
1828         else
1829             ++it;
1830
1831     if (d->m_recentProjects.count() > d->m_maxRecentProjects)
1832         d->m_recentProjects.removeLast();
1833     d->m_recentProjects.prepend(qMakePair(prettyFileName, displayName));
1834     QFileInfo fi(prettyFileName);
1835     d->m_lastOpenDirectory = fi.absolutePath();
1836 }
1837
1838 void ProjectExplorerPlugin::updateRecentProjectMenu()
1839 {
1840     typedef QList<QPair<QString, QString> >::const_iterator StringPairListConstIterator;
1841     if (debug)
1842         qDebug() << "ProjectExplorerPlugin::updateRecentProjectMenu";
1843
1844     Core::ActionContainer *aci =
1845         Core::ICore::instance()->actionManager()->actionContainer(Constants::M_RECENTPROJECTS);
1846     QMenu *menu = aci->menu();
1847     menu->clear();
1848
1849     menu->setEnabled(!d->m_recentProjects.isEmpty());
1850
1851     //projects (ignore sessions, they used to be in this list)
1852     const StringPairListConstIterator end = d->m_recentProjects.constEnd();
1853     for (StringPairListConstIterator it = d->m_recentProjects.constBegin(); it != end; ++it) {
1854         const QPair<QString, QString> &s = *it;
1855         if (s.first.endsWith(QLatin1String(".qws")))
1856             continue;
1857         QAction *action = menu->addAction(s.first);
1858         action->setData(s.first);
1859         connect(action, SIGNAL(triggered()), this, SLOT(openRecentProject()));
1860     }
1861 }
1862
1863 void ProjectExplorerPlugin::openRecentProject()
1864 {
1865     if (debug)
1866         qDebug() << "ProjectExplorerPlugin::openRecentProject()";
1867
1868     QAction *a = qobject_cast<QAction*>(sender());
1869     if (!a)
1870         return;
1871     QString fileName = a->data().toString();
1872     if (!fileName.isEmpty())
1873         openProject(fileName);
1874 }
1875
1876 void ProjectExplorerPlugin::invalidateProject(Project *project)
1877 {
1878     if (debug)
1879         qDebug() << "ProjectExplorerPlugin::invalidateProject" << project->displayName();
1880     if (d->m_currentProject == project) {
1881         //
1882         // Workaround for a bug in QItemSelectionModel
1883         // - currentChanged etc are not emitted if the
1884         // item is removed from the underlying data model
1885         //
1886         setCurrent(0, QString(), 0);
1887     }
1888
1889     disconnect(project, SIGNAL(fileListChanged()), this, SIGNAL(fileListChanged()));
1890     updateActions();
1891 }
1892
1893 void ProjectExplorerPlugin::goToTaskWindow()
1894 {
1895     d->m_buildManager->gotoTaskWindow();
1896 }
1897
1898 void ProjectExplorerPlugin::updateContextMenuActions(Node *node)
1899 {
1900     d->m_addExistingFilesAction->setEnabled(false);
1901     d->m_addNewFileAction->setEnabled(false);
1902     d->m_removeFileAction->setEnabled(false);
1903
1904     if (node->projectNode()) {
1905         QList<ProjectNode::ProjectAction> actions =
1906                 d->m_currentNode->projectNode()->supportedActions(node);
1907
1908         if (qobject_cast<FolderNode*>(d->m_currentNode)) {
1909             bool addFilesEnabled = actions.contains(ProjectNode::AddFile);
1910             d->m_addExistingFilesAction->setEnabled(addFilesEnabled);
1911             d->m_addNewFileAction->setEnabled(addFilesEnabled);
1912             d->m_renameFileAction->setEnabled(actions.contains(ProjectNode::Rename));
1913         } else if (qobject_cast<FileNode*>(d->m_currentNode)) {
1914             bool removeFileEnabled = actions.contains(ProjectNode::RemoveFile);
1915             d->m_removeFileAction->setEnabled(removeFileEnabled);
1916             d->m_renameFileAction->setEnabled(actions.contains(ProjectNode::Rename));
1917         }
1918     }
1919 }
1920
1921 void ProjectExplorerPlugin::addNewFile()
1922 {
1923     QTC_ASSERT(d->m_currentNode, return)
1924     QFileInfo fi(d->m_currentNode->path());
1925     const QString location = (fi.isDir() ? fi.absoluteFilePath() : fi.absolutePath());
1926     Core::ICore::instance()->showNewItemDialog(tr("New File", "Title of dialog"),
1927                               Core::IWizard::wizardsOfKind(Core::IWizard::FileWizard)
1928                               + Core::IWizard::wizardsOfKind(Core::IWizard::ClassWizard),
1929                               location);
1930 }
1931
1932 void ProjectExplorerPlugin::addExistingFiles()
1933 {
1934     QTC_ASSERT(d->m_currentNode, return)
1935
1936     ProjectNode *projectNode = qobject_cast<ProjectNode*>(d->m_currentNode->projectNode());
1937     Core::ICore *core = Core::ICore::instance();
1938     QFileInfo fi(d->m_currentNode->path());
1939     const QString dir = (fi.isDir() ? fi.absoluteFilePath() : fi.absolutePath());
1940     QStringList fileNames = QFileDialog::getOpenFileNames(core->mainWindow(), tr("Add Existing Files"), dir);
1941     if (fileNames.isEmpty())
1942         return;
1943
1944     QHash<FileType, QString> fileTypeToFiles;
1945     foreach (const QString &fileName, fileNames) {
1946         FileType fileType = typeForFileName(core->mimeDatabase(), QFileInfo(fileName));
1947         fileTypeToFiles.insertMulti(fileType, fileName);
1948     }
1949
1950     QStringList notAdded;
1951     foreach (const FileType type, fileTypeToFiles.uniqueKeys()) {
1952         projectNode->addFiles(type, fileTypeToFiles.values(type), &notAdded);
1953     }
1954     if (!notAdded.isEmpty()) {
1955         QString message = tr("Could not add following files to project %1:\n").arg(projectNode->displayName());
1956         QString files = notAdded.join("\n");
1957         QMessageBox::warning(core->mainWindow(), tr("Add files to project failed"),
1958                              message + files);
1959         foreach (const QString &file, notAdded)
1960             fileNames.removeOne(file);
1961     }
1962
1963     if (Core::IVersionControl *vcManager = core->vcsManager()->findVersionControlForDirectory(dir))
1964         if (vcManager->supportsOperation(Core::IVersionControl::AddOperation)) {
1965             const QString files = fileNames.join(QString(QLatin1Char('\n')));
1966             QMessageBox::StandardButton button =
1967                 QMessageBox::question(core->mainWindow(), tr("Add to Version Control"),
1968                                       tr("Add files\n%1\nto version control (%2)?").arg(files, vcManager->displayName()),
1969                                       QMessageBox::Yes | QMessageBox::No);
1970             if (button == QMessageBox::Yes) {
1971                 QStringList notAddedToVc;
1972                 foreach (const QString &file, fileNames) {
1973                     if (!vcManager->vcsAdd(file))
1974                         notAddedToVc << file;
1975                 }
1976
1977                 if (!notAddedToVc.isEmpty()) {
1978                     const QString message = tr("Could not add following files to version control (%1)\n").arg(vcManager->displayName());
1979                     const QString filesNotAdded = notAddedToVc.join(QString(QLatin1Char('\n')));
1980                     QMessageBox::warning(core->mainWindow(), tr("Add files to version control failed"),
1981                                          message + filesNotAdded);
1982                 }
1983             }
1984         }
1985 }
1986
1987 void ProjectExplorerPlugin::openFile()
1988 {
1989     QTC_ASSERT(d->m_currentNode, return)
1990     Core::EditorManager *em = Core::EditorManager::instance();
1991     em->openEditor(d->m_currentNode->path());
1992     em->ensureEditorManagerVisible();
1993 }
1994
1995 void ProjectExplorerPlugin::showInGraphicalShell()
1996 {
1997     QTC_ASSERT(d->m_currentNode, return)
1998     FolderNavigationWidget::showInGraphicalShell(Core::ICore::instance()->mainWindow(),
1999                                                  d->m_currentNode->path());
2000 }
2001
2002 void ProjectExplorerPlugin::openTerminalHere()
2003 {
2004     QTC_ASSERT(d->m_currentNode, return)
2005     FolderNavigationWidget::openTerminal(d->m_currentNode->path());
2006 }
2007
2008 void ProjectExplorerPlugin::removeFile()
2009 {
2010     QTC_ASSERT(d->m_currentNode && d->m_currentNode->nodeType() == FileNodeType, return)
2011
2012     FileNode *fileNode = qobject_cast<FileNode*>(d->m_currentNode);
2013     Core::ICore *core = Core::ICore::instance();
2014
2015     QString filePath = d->m_currentNode->path();
2016     RemoveFileDialog removeFileDialog(filePath, core->mainWindow());
2017
2018     if (removeFileDialog.exec() == QDialog::Accepted) {
2019         const bool deleteFile = removeFileDialog.isDeleteFileChecked();
2020
2021         // remove from project
2022         ProjectNode *projectNode = fileNode->projectNode();
2023         Q_ASSERT(projectNode);
2024
2025         if (!projectNode->removeFiles(fileNode->fileType(), QStringList(filePath))) {
2026             QMessageBox::warning(core->mainWindow(), tr("Remove file failed"),
2027                                  tr("Could not remove file %1 from project %2.").arg(filePath).arg(projectNode->displayName()));
2028             return;
2029         }
2030
2031         // remove from version control
2032         core->vcsManager()->promptToDelete(filePath);
2033
2034         // remove from file system
2035         if (deleteFile) {
2036             QFile file(filePath);
2037
2038             if (file.exists()) {
2039                 // could have been deleted by vc
2040                 if (!file.remove())
2041                     QMessageBox::warning(core->mainWindow(), tr("Delete file failed"),
2042                                          tr("Could not delete file %1.").arg(filePath));
2043             }
2044         }
2045     }
2046 }
2047
2048 void ProjectExplorerPlugin::renameFile()
2049 {
2050     QWidget *focusWidget = QApplication::focusWidget();
2051     while (focusWidget) {
2052         ProjectTreeWidget *treeWidget = qobject_cast<ProjectTreeWidget*>(focusWidget);
2053         if (treeWidget) {
2054             treeWidget->editCurrentItem();
2055             break;
2056         }
2057         focusWidget = focusWidget->parentWidget();
2058     }
2059 }
2060
2061 void ProjectExplorerPlugin::renameFile(Node *node, const QString &to)
2062 {
2063     FileNode *fileNode = qobject_cast<FileNode *>(node);
2064     if (!fileNode)
2065         return;
2066     QString orgFilePath = node->path();
2067     QString dir = QFileInfo(orgFilePath).absolutePath();
2068     QString newFilePath = dir + "/" + to;
2069     Core::ICore *core = Core::ICore::instance();
2070     Core::IVersionControl *vc = core->vcsManager()->findVersionControlForDirectory(dir);
2071     bool result = false;
2072     if (vc && vc->supportsOperation(Core::IVersionControl::MoveOperation))
2073         result = vc->vcsMove(orgFilePath, newFilePath);
2074     if (!result) // The moving via vcs failed or the vcs does not support moving, fall back
2075         result = QFile::rename(orgFilePath, newFilePath);
2076     if (result) {
2077         // yeah we moved, tell the filemanager about it
2078         Core::ICore::instance()->fileManager()->renamedFile(orgFilePath, newFilePath);
2079         // Tell the project plugin about it
2080         ProjectNode *projectNode = fileNode->projectNode();
2081         projectNode->renameFile(fileNode->fileType(), orgFilePath, newFilePath);
2082         // TODO emit a signal?
2083     }
2084 }
2085
2086 void ProjectExplorerPlugin::populateOpenWithMenu(QMenu *menu, const QString &fileName)
2087 {
2088     typedef QList<Core::IEditorFactory*> EditorFactoryList;
2089     typedef QList<Core::IExternalEditor*> ExternalEditorList;
2090
2091     menu->clear();
2092
2093     bool anyMatches = false;
2094
2095     Core::ICore *core = Core::ICore::instance();
2096     if (const Core::MimeType mt = core->mimeDatabase()->findByFile(QFileInfo(fileName))) {
2097         const EditorFactoryList factories = core->editorManager()->editorFactories(mt, false);
2098         const ExternalEditorList externalEditors = core->editorManager()->externalEditors(mt, false);
2099         anyMatches = !factories.empty() || !externalEditors.empty();
2100         if (anyMatches) {
2101             const QList<Core::IEditor *> editorsOpenForFile = core->editorManager()->editorsForFileName(fileName);
2102             // Add all suitable editors
2103             foreach (Core::IEditorFactory *editorFactory, factories) {
2104                 // Add action to open with this very editor factory
2105                 QString const actionTitle = editorFactory->displayName();
2106                 QAction * const action = menu->addAction(actionTitle);
2107                 action->setData(qVariantFromValue(editorFactory));
2108                 // File already open in an editor -> only enable that entry since
2109                 // we currently do not support opening a file in two editors at once
2110                 if (!editorsOpenForFile.isEmpty()) {
2111                     bool enabled = false;
2112                     foreach (Core::IEditor * const openEditor, editorsOpenForFile) {
2113                         if (editorFactory->id() == openEditor->id())
2114                             enabled = true;
2115                         break;
2116                     }
2117                     action->setEnabled(enabled);
2118                 }
2119             } // for editor factories
2120             // Add all suitable external editors
2121             foreach (Core::IExternalEditor *externalEditor, externalEditors) {
2122                 QAction * const action = menu->addAction(externalEditor->displayName());
2123                 action->setData(qVariantFromValue(externalEditor));
2124             }
2125         } // matches
2126     }
2127     menu->setEnabled(anyMatches);
2128 }
2129
2130 void ProjectExplorerPlugin::populateOpenWithMenu()
2131 {
2132     populateOpenWithMenu(d->m_openWithMenu, currentNode()->path());
2133 }
2134
2135 void ProjectExplorerPlugin::openWithMenuTriggered(QAction *action)
2136 {
2137     if (!action)
2138         qWarning() << "ProjectExplorerPlugin::openWithMenuTriggered no action, can't happen.";
2139     else
2140         openEditorFromAction(action, currentNode()->path());
2141 }
2142
2143 void ProjectExplorerPlugin::openEditorFromAction(QAction *action, const QString &fileName)
2144 {
2145     Core::EditorManager *em = Core::EditorManager::instance();
2146     const QVariant data = action->data();
2147     if (qVariantCanConvert<Core::IEditorFactory *>(data)) {
2148         Core::IEditorFactory *factory = qVariantValue<Core::IEditorFactory *>(data);
2149         em->openEditor(fileName, factory->id());
2150         em->ensureEditorManagerVisible();
2151         return;
2152     }
2153     if (qVariantCanConvert<Core::IExternalEditor *>(data)) {
2154         Core::IExternalEditor *externalEditor = qVariantValue<Core::IExternalEditor *>(data);
2155         em->openExternalEditor(fileName, externalEditor->id());
2156     }
2157 }
2158
2159 void ProjectExplorerPlugin::updateSessionMenu()
2160 {
2161     d->m_sessionMenu->clear();
2162     QActionGroup *ag = new QActionGroup(d->m_sessionMenu);
2163     connect(ag, SIGNAL(triggered(QAction *)), this, SLOT(setSession(QAction *)));
2164     const QString &activeSession = d->m_session->activeSession();
2165     foreach (const QString &session, d->m_session->sessions()) {
2166         QAction *act = ag->addAction(session);
2167         act->setCheckable(true);
2168         if (session == activeSession)
2169             act->setChecked(true);
2170     }
2171     d->m_sessionMenu->addActions(ag->actions());
2172     d->m_sessionMenu->addSeparator();
2173     d->m_sessionMenu->addAction(d->m_sessionManagerAction);
2174
2175     d->m_sessionMenu->setEnabled(true);
2176 }
2177
2178 void ProjectExplorerPlugin::setSession(QAction *action)
2179 {
2180     QString session = action->text();
2181     if (session != d->m_session->activeSession())
2182         d->m_session->loadSession(session);
2183 }
2184
2185
2186 void ProjectExplorerPlugin::setProjectExplorerSettings(const Internal::ProjectExplorerSettings &pes)
2187 {
2188     if (d->m_projectExplorerSettings == pes)
2189         return;
2190     d->m_projectExplorerSettings = pes;
2191     emit settingsChanged();
2192 }
2193
2194 Internal::ProjectExplorerSettings ProjectExplorerPlugin::projectExplorerSettings() const
2195 {
2196     return d->m_projectExplorerSettings;
2197 }
2198
2199 QStringList ProjectExplorerPlugin::projectFilePatterns()
2200 {
2201     QStringList patterns;
2202     const Core::MimeDatabase *mdb = Core::ICore::instance()->mimeDatabase();
2203     foreach(const IProjectManager *pm, allProjectManagers())
2204         if (const Core::MimeType mt = mdb->findByType(pm->mimeType()))
2205             foreach(const QRegExp &re, mt.globPatterns())
2206                 patterns += re.pattern();
2207     return patterns;
2208 }
2209
2210 void ProjectExplorerPlugin::openOpenProjectDialog()
2211 {
2212     Core::FileManager *fileMananger = Core::ICore::instance()->fileManager();
2213     const QString projectPatterns = ProjectExplorerPlugin::projectFilePatterns().join(QString(QLatin1Char(' ')));
2214     QString projectFilesFilter = tr("Projects (%1)").arg(projectPatterns);
2215     const QString allFilesFilter = tr("All Files (*)");
2216     const QString filters = allFilesFilter + QLatin1String(";;") + projectFilesFilter;
2217     const QString path = fileMananger->useProjectsDirectory() ? fileMananger->projectsDirectory() : QString();
2218     const QStringList files = fileMananger->getOpenFileNames(filters, path, &projectFilesFilter);
2219     if (!files.isEmpty())
2220         Core::ICore::instance()->openFiles(files);
2221 }
2222
2223 Q_EXPORT_PLUGIN(ProjectExplorerPlugin)