projectexplorer.cpp 83.7 KB
Newer Older
1
/**************************************************************************
con's avatar
con committed
2
3
4
**
** This file is part of Qt Creator
**
hjk's avatar
hjk committed
5
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
con's avatar
con committed
6
**
7
** Contact: Nokia Corporation (qt-info@nokia.com)
con's avatar
con committed
8
**
9
** Commercial Usage
10
**
11
12
13
14
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
15
**
16
** GNU Lesser General Public License Usage
17
**
18
19
20
21
22
23
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** 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
hjk's avatar
hjk committed
26
** contact the sales department at http://qt.nokia.com/contact.
con's avatar
con committed
27
**
28
**************************************************************************/
hjk's avatar
hjk committed
29

30
#include "projectexplorer.h"
Tobias Hunger's avatar
Tobias Hunger committed
31

32
#include "project.h"
33
#include "projectexplorersettings.h"
Tobias Hunger's avatar
Tobias Hunger committed
34
35
#include "target.h"
#include "targetsettingspanel.h"
con's avatar
con committed
36
37
38
39
40
#include "applicationrunconfiguration.h"
#include "allprojectsfilter.h"
#include "allprojectsfind.h"
#include "buildmanager.h"
#include "buildsettingspropertiespage.h"
41
#include "currentprojectfind.h"
con's avatar
con committed
42
43
#include "currentprojectfilter.h"
#include "customexecutablerunconfiguration.h"
44
45
#include "editorsettingspropertiespage.h"
#include "dependenciespanel.h"
con's avatar
con committed
46
47
48
49
50
51
52
53
54
#include "foldernavigationwidget.h"
#include "iprojectmanager.h"
#include "metatypedeclarations.h"
#include "nodesvisitor.h"
#include "outputwindow.h"
#include "persistentsettings.h"
#include "pluginfilefactory.h"
#include "processstep.h"
#include "projectexplorerconstants.h"
55
#include "customwizard.h"
con's avatar
con committed
56
57
58
59
60
61
62
63
#include "projectfilewizardextension.h"
#include "projecttreewidget.h"
#include "projectwindow.h"
#include "removefiledialog.h"
#include "runsettingspropertiespage.h"
#include "scriptwrappers.h"
#include "session.h"
#include "sessiondialog.h"
Tobias Hunger's avatar
Tobias Hunger committed
64
#include "target.h"
65
#include "projectexplorersettingspage.h"
66
67
#include "projectwelcomepage.h"
#include "projectwelcomepagewidget.h"
68
#include "corelistenercheckingforrunningbuild.h"
69
#include "buildconfiguration.h"
70
#include "buildconfigdialog.h"
71
#include "miniprojecttargetselector.h"
con's avatar
con committed
72
73
74

#include <coreplugin/basemode.h>
#include <coreplugin/coreconstants.h>
75
76
#include <coreplugin/filemanager.h>
#include <coreplugin/icore.h>
con's avatar
con committed
77
78
79
80
#include <coreplugin/mainwindow.h>
#include <coreplugin/mimedatabase.h>
#include <coreplugin/modemanager.h>
#include <coreplugin/uniqueidmanager.h>
81
#include <coreplugin/actionmanager/actionmanager.h>
82
83
#include <coreplugin/actionmanager/actioncontainer.h>
#include <coreplugin/actionmanager/command.h>
con's avatar
con committed
84
85
86
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/editormanager/ieditor.h>
#include <coreplugin/editormanager/ieditorfactory.h>
87
#include <coreplugin/editormanager/iexternaleditor.h>
con's avatar
con committed
88
89
90
91
#include <coreplugin/findplaceholder.h>
#include <coreplugin/basefilewizard.h>
#include <coreplugin/vcsmanager.h>
#include <coreplugin/iversioncontrol.h>
92
#include <welcome/welcomemode.h>
93
#include <extensionsystem/pluginmanager.h>
94
#include <utils/consoleprocess.h>
hjk's avatar
hjk committed
95
#include <utils/qtcassert.h>
96
#include <utils/parameteraction.h>
con's avatar
con committed
97

98
#include <QtCore/QtPlugin>
hjk's avatar
hjk committed
99
#include <QtCore/QDateTime>
con's avatar
con committed
100
101
#include <QtCore/QDebug>
#include <QtCore/QSettings>
hjk's avatar
hjk committed
102

con's avatar
con committed
103
104
#include <QtGui/QAction>
#include <QtGui/QApplication>
hjk's avatar
hjk committed
105
106
107
#include <QtGui/QFileDialog>
#include <QtGui/QMenu>
#include <QtGui/QMessageBox>
con's avatar
con committed
108

109
110
Q_DECLARE_METATYPE(Core::IEditorFactory*);
Q_DECLARE_METATYPE(Core::IExternalEditor*);
con's avatar
con committed
111
112
113
114
115

namespace {
bool debug = false;
}

116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
namespace ProjectExplorer {

struct ProjectExplorerPluginPrivate {
    ProjectExplorerPluginPrivate();

    QMenu *m_sessionContextMenu;
    QMenu *m_sessionMenu;
    QMenu *m_projectMenu;
    QMenu *m_subProjectMenu;
    QMenu *m_folderMenu;
    QMenu *m_fileMenu;
    QMenu *m_openWithMenu;

    QMultiMap<int, QObject*> m_actionMap;
    QAction *m_sessionManagerAction;
    QAction *m_newAction;
#if 0
    QAction *m_loadAction;
#endif
135
    Utils::ParameterAction *m_unloadAction;
136
137
    QAction *m_clearSession;
    QAction *m_buildProjectOnlyAction;
138
    Utils::ParameterAction *m_buildAction;
139
    Utils::ParameterAction *m_buildActionContextMenu;
140
141
    QAction *m_buildSessionAction;
    QAction *m_rebuildProjectOnlyAction;
142
    Utils::ParameterAction *m_rebuildAction;
143
    Utils::ParameterAction *m_rebuildActionContextMenu;
144
145
    QAction *m_rebuildSessionAction;
    QAction *m_cleanProjectOnlyAction;
146
    Utils::ParameterAction *m_cleanAction;
147
    Utils::ParameterAction *m_cleanActionContextMenu;
148
149
150
151
152
153
154
155
156
    QAction *m_cleanSessionAction;
    QAction *m_runAction;
    QAction *m_runActionContextMenu;
    QAction *m_cancelBuildAction;
    QAction *m_debugAction;
    QAction *m_addNewFileAction;
    QAction *m_addExistingFilesAction;
    QAction *m_openFileAction;
    QAction *m_showInGraphicalShell;
157
    QAction *m_openTerminalHere;
158
159
    QAction *m_removeFileAction;
    QAction *m_renameFileAction;
160
    QAction *m_projectSelectorAction;
161
    QAction *m_projectSelectorActionMenu;
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179

    Internal::ProjectWindow *m_proWindow;
    SessionManager *m_session;
    QString m_sessionToRestoreAtStartup;

    Project *m_currentProject;
    Node *m_currentNode;

    BuildManager *m_buildManager;

    QList<Internal::ProjectFileFactory*> m_fileFactories;
    QStringList m_profileMimeTypes;
    Internal::OutputPane *m_outputPane;

    QList<QPair<QString, QString> > m_recentProjects; // pair of filename, displayname
    static const int m_maxRecentProjects = 7;

    QString m_lastOpenDirectory;
180
    RunConfiguration *m_delayedRunConfiguration; // TODO this is not right
181
182
183
    RunControl *m_debuggingRunControl;
    QString m_runMode;
    QString m_projectFilterString;
184
    Internal::MiniProjectTargetSelector * m_targetSelector;
185
    Internal::ProjectExplorerSettings m_projectExplorerSettings;
186
    Internal::ProjectWelcomePage *m_welcomePage;
187
188

    Core::BaseMode * m_projectsMode;
189
190
191
192
193
194
};

ProjectExplorerPluginPrivate::ProjectExplorerPluginPrivate() :
    m_currentProject(0),
    m_currentNode(0),
    m_delayedRunConfiguration(0),
195
196
    m_debuggingRunControl(0),
    m_projectsMode(0)
197
198
199
200
201
{
}

}  // namespace ProjectExplorer

con's avatar
con committed
202
203
204
205
206
207
208
using namespace ProjectExplorer;
using namespace ProjectExplorer::Internal;


ProjectExplorerPlugin *ProjectExplorerPlugin::m_instance = 0;

ProjectExplorerPlugin::ProjectExplorerPlugin()
209
    : d(new ProjectExplorerPluginPrivate)
con's avatar
con committed
210
211
212
213
214
215
{
    m_instance = this;
}

ProjectExplorerPlugin::~ProjectExplorerPlugin()
{
216
217
    removeObject(d->m_welcomePage);
    delete d->m_welcomePage;
con's avatar
con committed
218
    removeObject(this);
219
    delete d;
con's avatar
con committed
220
221
222
223
224
225
226
}

ProjectExplorerPlugin *ProjectExplorerPlugin::instance()
{
    return m_instance;
}

227
228
229
230
231
232
bool ProjectExplorerPlugin::parseArguments(const QStringList &arguments, QString * /* error */)
{
    CustomWizard::setVerbose(arguments.count(QLatin1String("-customwizard-verbose")));
    return true;
}

233
bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *error)
con's avatar
con committed
234
{
235
236
    if (!parseArguments(arguments, error))
        return false;
237

238
239
    Core::ICore *core = Core::ICore::instance();
    Core::ActionManager *am = core->actionManager();
con's avatar
con committed
240

241
    d->m_welcomePage = new ProjectWelcomePage;
242
    connect(d->m_welcomePage, SIGNAL(manageSessions()), this, SLOT(showSessionManager()));
243
    addObject(d->m_welcomePage);
con's avatar
con committed
244
245
    addObject(this);

hjk's avatar
hjk committed
246
247
    connect(core->fileManager(), SIGNAL(currentFileChanged(QString)),
            this, SLOT(setCurrentFile(QString)));
con's avatar
con committed
248

249
    d->m_session = new SessionManager(this);
con's avatar
con committed
250

251
    connect(d->m_session, SIGNAL(projectAdded(ProjectExplorer::Project *)),
con's avatar
con committed
252
            this, SIGNAL(fileListChanged()));
253
    connect(d->m_session, SIGNAL(aboutToRemoveProject(ProjectExplorer::Project *)),
con's avatar
con committed
254
            this, SLOT(invalidateProject(ProjectExplorer::Project *)));
255
    connect(d->m_session, SIGNAL(projectRemoved(ProjectExplorer::Project *)),
con's avatar
con committed
256
            this, SIGNAL(fileListChanged()));
257
    connect(d->m_session, SIGNAL(startupProjectChanged(ProjectExplorer::Project *)),
con's avatar
con committed
258
            this, SLOT(startupProjectChanged()));
259
260
    connect(d->m_session, SIGNAL(dependencyChanged(ProjectExplorer::Project*,ProjectExplorer::Project*)),
            this, SLOT(updateActions()));
con's avatar
con committed
261

262
    d->m_proWindow = new ProjectWindow;
con's avatar
con committed
263
264
265
266
267

    QList<int> globalcontext;
    globalcontext.append(Core::Constants::C_GLOBAL_ID);

    QList<int> pecontext;
268
    pecontext << core->uniqueIDManager()->uniqueIdentifier(Constants::C_PROJECTEXPLORER);
con's avatar
con committed
269

270
271
272
273
274
275
276
277
    d->m_projectsMode = new Core::BaseMode;
    d->m_projectsMode->setDisplayName(tr("Projects"));
    d->m_projectsMode->setId(QLatin1String(Constants::MODE_SESSION));
    d->m_projectsMode->setIcon(QIcon(QLatin1String(":/fancyactionbar/images/mode_Project.png")));
    d->m_projectsMode->setPriority(Constants::P_MODE_SESSION);
    d->m_projectsMode->setWidget(d->m_proWindow);
    d->m_projectsMode->setContext(QList<int>() << pecontext);
    d->m_projectsMode->setEnabled(session()->startupProject());
Daniel Molkentin's avatar
Daniel Molkentin committed
278
    d->m_projectsMode->setContextHelpId(QLatin1String("Managing Projects"));
279
    addAutoReleasedObject(d->m_projectsMode);
280
    d->m_proWindow->layout()->addWidget(new Core::FindToolBarPlaceHolder(d->m_proWindow));
con's avatar
con committed
281

282
283
    d->m_buildManager = new BuildManager(this);
    connect(d->m_buildManager, SIGNAL(buildStateChanged(ProjectExplorer::Project *)),
con's avatar
con committed
284
            this, SLOT(buildStateChanged(ProjectExplorer::Project *)));
285
    connect(d->m_buildManager, SIGNAL(buildQueueFinished(bool)),
con's avatar
con committed
286
287
            this, SLOT(buildQueueFinished(bool)));

288
    addAutoReleasedObject(new CoreListenerCheckingForRunningBuild(d->m_buildManager));
con's avatar
con committed
289

290
291
292
293
    d->m_outputPane = new OutputPane;
    addAutoReleasedObject(d->m_outputPane);
    connect(d->m_session, SIGNAL(projectRemoved(ProjectExplorer::Project *)),
            d->m_outputPane, SLOT(projectRemoved()));
con's avatar
con committed
294

295
    AllProjectsFilter *allProjectsFilter = new AllProjectsFilter(this);
con's avatar
con committed
296
297
    addAutoReleasedObject(allProjectsFilter);

298
    CurrentProjectFilter *currentProjectFilter = new CurrentProjectFilter(this);
con's avatar
con committed
299
300
301
302
303
    addAutoReleasedObject(currentProjectFilter);

    addAutoReleasedObject(new BuildSettingsPanelFactory);
    addAutoReleasedObject(new RunSettingsPanelFactory);
    addAutoReleasedObject(new EditorSettingsPanelFactory);
304
    addAutoReleasedObject(new DependenciesPanelFactory(d->m_session));
con's avatar
con committed
305
306
307
308

    ProcessStepFactory *processStepFactory = new ProcessStepFactory;
    addAutoReleasedObject(processStepFactory);

309
310
311
    ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
    AllProjectsFind *allProjectsFind = new AllProjectsFind(this,
        pm->getObject<Find::SearchResultWindow>());
con's avatar
con committed
312
313
    addAutoReleasedObject(allProjectsFind);

314
315
    CurrentProjectFind *currentProjectFind = new CurrentProjectFind(this,
        pm->getObject<Find::SearchResultWindow>());
con's avatar
con committed
316
317
    addAutoReleasedObject(currentProjectFind);

318
    addAutoReleasedObject(new LocalApplicationRunControlFactory);
con's avatar
con committed
319
320
    addAutoReleasedObject(new CustomExecutableRunConfigurationFactory);

321
    addAutoReleasedObject(new ProjectFileWizardExtension);
con's avatar
con committed
322

323
324
325
    // Settings page
    addAutoReleasedObject(new ProjectExplorerSettingsPage);

con's avatar
con committed
326
    // context menus
327
    Core::ActionContainer *msessionContextMenu =
con's avatar
con committed
328
        am->createMenu(Constants::M_SESSIONCONTEXT);
329
    Core::ActionContainer *mproject =
con's avatar
con committed
330
        am->createMenu(Constants::M_PROJECTCONTEXT);
331
    Core::ActionContainer *msubProject =
con's avatar
con committed
332
        am->createMenu(Constants::M_SUBPROJECTCONTEXT);
333
    Core::ActionContainer *mfolder =
con's avatar
con committed
334
        am->createMenu(Constants::M_FOLDERCONTEXT);
335
    Core::ActionContainer *mfilec =
con's avatar
con committed
336
337
        am->createMenu(Constants::M_FILECONTEXT);

338
339
340
341
342
    d->m_sessionContextMenu = msessionContextMenu->menu();
    d->m_projectMenu = mproject->menu();
    d->m_subProjectMenu = msubProject->menu();
    d->m_folderMenu = mfolder->menu();
    d->m_fileMenu = mfilec->menu();
con's avatar
con committed
343

344
    Core::ActionContainer *mfile =
con's avatar
con committed
345
        am->actionContainer(Core::Constants::M_FILE);
346
    Core::ActionContainer *menubar =
con's avatar
con committed
347
348
349
        am->actionContainer(Core::Constants::MENU_BAR);

    // mode manager (for fancy actions)
350
    Core::ModeManager *modeManager = core->modeManager();
con's avatar
con committed
351
352

    // build menu
353
    Core::ActionContainer *mbuild =
con's avatar
con committed
354
        am->createMenu(Constants::M_BUILDPROJECT);
355
    mbuild->menu()->setTitle(tr("&Build"));
con's avatar
con committed
356
357
358
    menubar->addMenu(mbuild, Core::Constants::G_VIEW);

    // debug menu
359
    Core::ActionContainer *mdebug =
con's avatar
con committed
360
        am->createMenu(Constants::M_DEBUG);
361
    mdebug->menu()->setTitle(tr("&Debug"));
con's avatar
con committed
362
363
    menubar->addMenu(mdebug, Core::Constants::G_VIEW);

364
365
366
367
    Core::ActionContainer *mstartdebugging =
        am->createMenu(Constants::M_DEBUG_STARTDEBUGGING);
    mstartdebugging->menu()->setTitle(tr("&Start Debugging"));
    mdebug->addMenu(mstartdebugging, Core::Constants::G_DEFAULT_ONE);
con's avatar
con committed
368
369
370
371
372
373
374
375
376

    //
    // Groups
    //

    mbuild->appendGroup(Constants::G_BUILD_SESSION);
    mbuild->appendGroup(Constants::G_BUILD_PROJECT);
    mbuild->appendGroup(Constants::G_BUILD_OTHER);
    mbuild->appendGroup(Constants::G_BUILD_CANCEL);
dt's avatar
dt committed
377
    mbuild->appendGroup(Constants::G_BUILD_RUN);
con's avatar
con committed
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392

    msessionContextMenu->appendGroup(Constants::G_SESSION_BUILD);
    msessionContextMenu->appendGroup(Constants::G_SESSION_FILES);
    msessionContextMenu->appendGroup(Constants::G_SESSION_OTHER);
    msessionContextMenu->appendGroup(Constants::G_SESSION_CONFIG);

    mproject->appendGroup(Constants::G_PROJECT_OPEN);
    mproject->appendGroup(Constants::G_PROJECT_NEW);
    mproject->appendGroup(Constants::G_PROJECT_BUILD);
    mproject->appendGroup(Constants::G_PROJECT_RUN);
    mproject->appendGroup(Constants::G_PROJECT_FILES);
    mproject->appendGroup(Constants::G_PROJECT_OTHER);
    mproject->appendGroup(Constants::G_PROJECT_CONFIG);

    msubProject->appendGroup(Constants::G_PROJECT_OPEN);
393
    msubProject->appendGroup(Constants::G_PROJECT_BUILD);
con's avatar
con committed
394
395
396
397
398
399
400
401
402
403
404
405
406
    msubProject->appendGroup(Constants::G_PROJECT_FILES);
    msubProject->appendGroup(Constants::G_PROJECT_OTHER);
    msubProject->appendGroup(Constants::G_PROJECT_CONFIG);

    mfolder->appendGroup(Constants::G_FOLDER_FILES);
    mfolder->appendGroup(Constants::G_FOLDER_OTHER);
    mfolder->appendGroup(Constants::G_FOLDER_CONFIG);

    mfilec->appendGroup(Constants::G_FILE_OPEN);
    mfilec->appendGroup(Constants::G_FILE_OTHER);
    mfilec->appendGroup(Constants::G_FILE_CONFIG);

    // "open with" submenu
407
    Core::ActionContainer * const openWith =
con's avatar
con committed
408
            am->createMenu(ProjectExplorer::Constants::M_OPENFILEWITHCONTEXT);
409
    openWith->setEmptyAction(Core::ActionContainer::EA_None);
410
411
    d->m_openWithMenu = openWith->menu();
    d->m_openWithMenu->setTitle(tr("Open With"));
con's avatar
con committed
412

413
    connect(d->m_openWithMenu, SIGNAL(triggered(QAction *)),
con's avatar
con committed
414
415
416
417
418
419
            this, SLOT(openWithMenuTriggered(QAction *)));

    //
    // Separators
    //

con's avatar
con committed
420
    Core::Command *cmd;
con's avatar
con committed
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
    QAction *sep;

    sep = new QAction(this);
    sep->setSeparator(true);
    cmd = am->registerAction(sep, QLatin1String("ProjectExplorer.Build.Sep"), globalcontext);
    mbuild->addAction(cmd, Constants::G_BUILD_PROJECT);

    sep = new QAction(this);
    sep->setSeparator(true);
    cmd = am->registerAction(sep, QLatin1String("ProjectExplorer.Files.Sep"), globalcontext);
    msessionContextMenu->addAction(cmd, Constants::G_SESSION_FILES);
    mproject->addAction(cmd, Constants::G_PROJECT_FILES);
    msubProject->addAction(cmd, Constants::G_PROJECT_FILES);

    sep = new QAction(this);
    sep->setSeparator(true);
    cmd = am->registerAction(sep, QLatin1String("ProjectExplorer.New.Sep"), globalcontext);
    mproject->addAction(cmd, Constants::G_PROJECT_NEW);

    sep = new QAction(this);
    sep->setSeparator(true);
    cmd = am->registerAction(sep, QLatin1String("ProjectExplorer.Config.Sep"), globalcontext);
    msessionContextMenu->addAction(cmd, Constants::G_SESSION_CONFIG);
    mproject->addAction(cmd, Constants::G_PROJECT_CONFIG);
    msubProject->addAction(cmd, Constants::G_PROJECT_CONFIG);

    sep = new QAction(this);
    sep->setSeparator(true);
    cmd = am->registerAction(sep, QLatin1String("ProjectExplorer.Projects.Sep"), globalcontext);
    mfile->addAction(cmd, Core::Constants::G_FILE_PROJECT);

    sep = new QAction(this);
    sep->setSeparator(true);
    cmd = am->registerAction(sep, QLatin1String("ProjectExplorer.Other.Sep"), globalcontext);
    mbuild->addAction(cmd, Constants::G_BUILD_OTHER);
    msessionContextMenu->addAction(cmd, Constants::G_SESSION_OTHER);
    mproject->addAction(cmd, Constants::G_PROJECT_OTHER);
    msubProject->addAction(cmd, Constants::G_PROJECT_OTHER);

    sep = new QAction(this);
    sep->setSeparator(true);
    cmd = am->registerAction(sep, QLatin1String("ProjectExplorer.Run.Sep"), globalcontext);
    mbuild->addAction(cmd, Constants::G_BUILD_RUN);
    mproject->addAction(cmd, Constants::G_PROJECT_RUN);

    sep = new QAction(this);
    sep->setSeparator(true);
    cmd = am->registerAction(sep, QLatin1String("ProjectExplorer.CancelBuild.Sep"), globalcontext);
    mbuild->addAction(cmd, Constants::G_BUILD_CANCEL);

    //
    // Actions
    //

    // new session action
476
477
    d->m_sessionManagerAction = new QAction(tr("Session Manager..."), this);
    cmd = am->registerAction(d->m_sessionManagerAction, Constants::NEWSESSION, globalcontext);
con's avatar
con committed
478
479
480
    cmd->setDefaultKeySequence(QKeySequence());

    // new action
481
482
    d->m_newAction = new QAction(tr("New Project..."), this);
    cmd = am->registerAction(d->m_newAction, Constants::NEWPROJECT, globalcontext);
con's avatar
con committed
483
484
485
486
487
    cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+N")));
    msessionContextMenu->addAction(cmd, Constants::G_SESSION_FILES);

#if 0
    // open action
488
489
    d->m_loadAction = new QAction(tr("Load Project..."), this);
    cmd = am->registerAction(d->m_loadAction, Constants::LOAD, globalcontext);
con's avatar
con committed
490
491
492
493
494
495
    cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+O")));
    mfile->addAction(cmd, Core::Constants::G_FILE_PROJECT);
    msessionContextMenu->addAction(cmd, Constants::G_SESSION_FILES);
#endif

    // Default open action
496
497
    d->m_openFileAction = new QAction(tr("Open File"), this);
    cmd = am->registerAction(d->m_openFileAction, ProjectExplorer::Constants::OPENFILE,
con's avatar
con committed
498
499
500
                       globalcontext);
    mfilec->addAction(cmd, Constants::G_FILE_OPEN);

501
    d->m_showInGraphicalShell = new QAction(FolderNavigationWidget::msgGraphicalShellAction(), this);
502
    cmd = am->registerAction(d->m_showInGraphicalShell, ProjectExplorer::Constants::SHOWINGRAPHICALSHELL,
con's avatar
con committed
503
504
                       globalcontext);
    mfilec->addAction(cmd, Constants::G_FILE_OPEN);
505
    mfolder->addAction(cmd, Constants::G_FOLDER_FILES);
con's avatar
con committed
506

507
    d->m_openTerminalHere = new QAction(FolderNavigationWidget::msgTerminalAction(), this);
508
509
510
511
512
    cmd = am->registerAction(d->m_openTerminalHere, ProjectExplorer::Constants::OPENTERMIANLHERE,
                       globalcontext);
    mfilec->addAction(cmd, Constants::G_FILE_OPEN);
    mfolder->addAction(cmd, Constants::G_FOLDER_FILES);

con's avatar
con committed
513
514
515
    // Open With menu
    mfilec->addMenu(openWith, ProjectExplorer::Constants::G_FILE_OPEN);

mae's avatar
mae committed
516
    // recent projects menu
517
    Core::ActionContainer *mrecent =
mae's avatar
mae committed
518
        am->createMenu(Constants::M_RECENTPROJECTS);
519
    mrecent->menu()->setTitle(tr("Recent P&rojects"));
mae's avatar
mae committed
520
521
522
523
    mfile->addMenu(mrecent, Core::Constants::G_FILE_OPEN);
    connect(mfile->menu(), SIGNAL(aboutToShow()),
        this, SLOT(updateRecentProjectMenu()));

con's avatar
con committed
524
    // unload action
525
526
    d->m_unloadAction = new Utils::ParameterAction(tr("Close Project"), tr("Close Project \"%1\""),
                                                      Utils::ParameterAction::EnabledWithParameter, this);
527
    cmd = am->registerAction(d->m_unloadAction, Constants::UNLOAD, globalcontext);
con's avatar
con committed
528
    cmd->setAttribute(Core::Command::CA_UpdateText);
529
    cmd->setDefaultText(d->m_unloadAction->text());
con's avatar
con committed
530
531
532
533
    mfile->addAction(cmd, Core::Constants::G_FILE_PROJECT);
    mproject->addAction(cmd, Constants::G_PROJECT_FILES);

    // unload session action
534
535
    d->m_clearSession = new QAction(tr("Close All Projects"), this);
    cmd = am->registerAction(d->m_clearSession, Constants::CLEARSESSION, globalcontext);
con's avatar
con committed
536
537
538
539
    mfile->addAction(cmd, Core::Constants::G_FILE_PROJECT);
    msessionContextMenu->addAction(cmd, Constants::G_SESSION_FILES);

    // session menu
540
    Core::ActionContainer *msession = am->createMenu(Constants::M_SESSION);
541
    msession->menu()->setTitle(tr("Session"));
con's avatar
con committed
542
    mfile->addMenu(msession, Core::Constants::G_FILE_PROJECT);
543
    d->m_sessionMenu = msession->menu();
con's avatar
con committed
544
545
546
547
548
549
    connect(mfile->menu(), SIGNAL(aboutToShow()),
            this, SLOT(updateSessionMenu()));

    // build session action
    QIcon buildIcon(Constants::ICON_BUILD);
    buildIcon.addFile(Constants::ICON_BUILD_SMALL);
550
551
    d->m_buildSessionAction = new QAction(buildIcon, tr("Build All"), this);
    cmd = am->registerAction(d->m_buildSessionAction, Constants::BUILDSESSION, globalcontext);
con's avatar
con committed
552
553
554
555
    cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+B")));
    mbuild->addAction(cmd, Constants::G_BUILD_SESSION);
    msessionContextMenu->addAction(cmd, Constants::G_SESSION_BUILD);
    // Add to mode bar
556
    modeManager->addAction(cmd, Constants::P_ACTION_BUILDSESSION);
con's avatar
con committed
557
558
559
560

    // rebuild session action
    QIcon rebuildIcon(Constants::ICON_REBUILD);
    rebuildIcon.addFile(Constants::ICON_REBUILD_SMALL);
561
562
    d->m_rebuildSessionAction = new QAction(rebuildIcon, tr("Rebuild All"), this);
    cmd = am->registerAction(d->m_rebuildSessionAction, Constants::REBUILDSESSION, globalcontext);
con's avatar
con committed
563
564
565
566
567
568
    mbuild->addAction(cmd, Constants::G_BUILD_SESSION);
    msessionContextMenu->addAction(cmd, Constants::G_SESSION_BUILD);

    // clean session
    QIcon cleanIcon(Constants::ICON_CLEAN);
    cleanIcon.addFile(Constants::ICON_CLEAN_SMALL);
569
570
    d->m_cleanSessionAction = new QAction(cleanIcon, tr("Clean All"), this);
    cmd = am->registerAction(d->m_cleanSessionAction, Constants::CLEANSESSION, globalcontext);
con's avatar
con committed
571
572
573
574
    mbuild->addAction(cmd, Constants::G_BUILD_SESSION);
    msessionContextMenu->addAction(cmd, Constants::G_SESSION_BUILD);

    // build action
575
    d->m_buildAction = new Utils::ParameterAction(tr("Build Project"), tr("Build Project \"%1\""),
576
                                                     Utils::ParameterAction::AlwaysEnabled, this);
577
    cmd = am->registerAction(d->m_buildAction, Constants::BUILD, globalcontext);
578
    cmd->setAttribute(Core::Command::CA_UpdateText);
579
    cmd->setDefaultText(d->m_buildAction->text());
con's avatar
con committed
580
581
582
583
    cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+B")));
    mbuild->addAction(cmd, Constants::G_BUILD_PROJECT);

    // rebuild action
584
    d->m_rebuildAction = new Utils::ParameterAction(tr("Rebuild Project"), tr("Rebuild Project \"%1\""),
585
                                                       Utils::ParameterAction::AlwaysEnabled, this);
586
    cmd = am->registerAction(d->m_rebuildAction, Constants::REBUILD, globalcontext);
587
    cmd->setAttribute(Core::Command::CA_UpdateText);
588
    cmd->setDefaultText(d->m_rebuildAction->text());
con's avatar
con committed
589
590
591
    mbuild->addAction(cmd, Constants::G_BUILD_PROJECT);

    // clean action
592
    d->m_cleanAction = new Utils::ParameterAction(tr("Clean Project"), tr("Clean Project \"%1\""),
593
                                                     Utils::ParameterAction::AlwaysEnabled, this);
594
    cmd = am->registerAction(d->m_cleanAction, Constants::CLEAN, globalcontext);
595
    cmd->setAttribute(Core::Command::CA_UpdateText);
596
    cmd->setDefaultText(d->m_cleanAction->text());
con's avatar
con committed
597
    mbuild->addAction(cmd, Constants::G_BUILD_PROJECT);
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620

    // build action (context menu)
    d->m_buildActionContextMenu = new Utils::ParameterAction(tr("Build Project"), tr("Build Project \"%1\""),
                                                             Utils::ParameterAction::AlwaysEnabled, this);
    cmd = am->registerAction(d->m_buildActionContextMenu, Constants::BUILDCM, globalcontext);
    cmd->setAttribute(Core::Command::CA_UpdateText);
    cmd->setDefaultText(d->m_buildActionContextMenu->text());
    mproject->addAction(cmd, Constants::G_PROJECT_BUILD);

    // rebuild action (context menu)
    d->m_rebuildActionContextMenu = new Utils::ParameterAction(tr("Rebuild Project"), tr("Rebuild Project \"%1\""),
                                                               Utils::ParameterAction::AlwaysEnabled, this);
    cmd = am->registerAction(d->m_rebuildActionContextMenu, Constants::REBUILDCM, globalcontext);
    cmd->setAttribute(Core::Command::CA_UpdateText);
    cmd->setDefaultText(d->m_rebuildActionContextMenu->text());
    mproject->addAction(cmd, Constants::G_PROJECT_BUILD);

    // clean action (context menu)
    d->m_cleanActionContextMenu = new Utils::ParameterAction(tr("Clean Project"), tr("Clean Project \"%1\""),
                                                             Utils::ParameterAction::AlwaysEnabled, this);
    cmd = am->registerAction(d->m_cleanActionContextMenu, Constants::CLEANCM, globalcontext);
    cmd->setAttribute(Core::Command::CA_UpdateText);
    cmd->setDefaultText(d->m_cleanActionContextMenu->text());
con's avatar
con committed
621
622
    mproject->addAction(cmd, Constants::G_PROJECT_BUILD);

623
    // build without dependencies action
624
625
    d->m_buildProjectOnlyAction = new QAction(tr("Build Without Dependencies"), this);
    cmd = am->registerAction(d->m_buildProjectOnlyAction, Constants::BUILDPROJECTONLY, globalcontext);
626

627
    // rebuild without dependencies action
628
629
    d->m_rebuildProjectOnlyAction = new QAction(tr("Rebuild Without Dependencies"), this);
    cmd = am->registerAction(d->m_rebuildProjectOnlyAction, Constants::REBUILDPROJECTONLY, globalcontext);
630

631
    // clean without dependencies action
632
633
    d->m_cleanProjectOnlyAction = new QAction(tr("Clean Without Dependencies"), this);
    cmd = am->registerAction(d->m_cleanProjectOnlyAction, Constants::CLEANPROJECTONLY, globalcontext);
634

con's avatar
con committed
635
636
637
    // run action
    QIcon runIcon(Constants::ICON_RUN);
    runIcon.addFile(Constants::ICON_RUN_SMALL);
638
639
    d->m_runAction = new QAction(runIcon, tr("Run"), this);
    cmd = am->registerAction(d->m_runAction, Constants::RUN, globalcontext);
640
641
    cmd->setAttribute(Core::Command::CA_UpdateText);

con's avatar
con committed
642
643
    cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+R")));
    mbuild->addAction(cmd, Constants::G_BUILD_RUN);
644

645
    modeManager->addAction(cmd, Constants::P_ACTION_RUN);
con's avatar
con committed
646

647
648
    d->m_runActionContextMenu = new QAction(runIcon, tr("Run"), this);
    cmd = am->registerAction(d->m_runActionContextMenu, Constants::RUNCONTEXTMENU, globalcontext);
649
650
    mproject->addAction(cmd, Constants::G_PROJECT_RUN);

con's avatar
con committed
651
    // cancel build action
652
653
    d->m_cancelBuildAction = new QAction(tr("Cancel Build"), this);
    cmd = am->registerAction(d->m_cancelBuildAction, Constants::CANCELBUILD, globalcontext);
con's avatar
con committed
654
655
656
657
    mbuild->addAction(cmd, Constants::G_BUILD_CANCEL);

    // debug action
    QIcon debuggerIcon(":/projectexplorer/images/debugger_start_small.png");
658
    debuggerIcon.addFile(":/projectexplorer/images/debugger_start.png");
659
660
    d->m_debugAction = new QAction(debuggerIcon, tr("Start Debugging"), this);
    cmd = am->registerAction(d->m_debugAction, Constants::DEBUG, globalcontext);
con's avatar
con committed
661
662
    cmd->setAttribute(Core::Command::CA_UpdateText);
    cmd->setAttribute(Core::Command::CA_UpdateIcon);
con's avatar
con committed
663
664
    cmd->setDefaultText(tr("Start Debugging"));
    cmd->setDefaultKeySequence(QKeySequence(tr("F5")));
665
    mstartdebugging->addAction(cmd, Core::Constants::G_DEFAULT_ONE);
666
    modeManager->addAction(cmd, Constants::P_ACTION_DEBUG);
con's avatar
con committed
667
668

    // add new file action
669
670
    d->m_addNewFileAction = new QAction(tr("Add New..."), this);
    cmd = am->registerAction(d->m_addNewFileAction, ProjectExplorer::Constants::ADDNEWFILE,
con's avatar
con committed
671
672
673
                       globalcontext);
    mproject->addAction(cmd, Constants::G_PROJECT_FILES);
    msubProject->addAction(cmd, Constants::G_PROJECT_FILES);
674
    mfolder->addAction(cmd, Constants::G_FOLDER_FILES);
con's avatar
con committed
675
676

    // add existing file action
677
678
    d->m_addExistingFilesAction = new QAction(tr("Add Existing Files..."), this);
    cmd = am->registerAction(d->m_addExistingFilesAction, ProjectExplorer::Constants::ADDEXISTINGFILES,
con's avatar
con committed
679
680
681
                       globalcontext);
    mproject->addAction(cmd, Constants::G_PROJECT_FILES);
    msubProject->addAction(cmd, Constants::G_PROJECT_FILES);
682
    mfolder->addAction(cmd, Constants::G_FOLDER_FILES);
con's avatar
con committed
683
684

    // remove file action
685
686
    d->m_removeFileAction = new QAction(tr("Remove File..."), this);
    cmd = am->registerAction(d->m_removeFileAction, ProjectExplorer::Constants::REMOVEFILE,
con's avatar
con committed
687
688
689
690
                       globalcontext);
    mfilec->addAction(cmd, Constants::G_FILE_OTHER);

    // renamefile action (TODO: Not supported yet)
691
692
    d->m_renameFileAction = new QAction(tr("Rename"), this);
    cmd = am->registerAction(d->m_renameFileAction, ProjectExplorer::Constants::RENAMEFILE,
con's avatar
con committed
693
694
                       globalcontext);
    mfilec->addAction(cmd, Constants::G_FILE_OTHER);
695
696
    d->m_renameFileAction->setEnabled(false);
    d->m_renameFileAction->setVisible(false);
con's avatar
con committed
697

698
699
    // target selector
    d->m_projectSelectorAction = new QAction(this);
700
    d->m_projectSelectorAction->setCheckable(true);
701
702
703
    d->m_projectSelectorAction->setEnabled(false);
    QWidget *mainWindow = Core::ICore::instance()->mainWindow();
    d->m_targetSelector = new Internal::MiniProjectTargetSelector(d->m_projectSelectorAction, mainWindow);
704
    connect(d->m_projectSelectorAction, SIGNAL(triggered()), d->m_targetSelector, SLOT(show()));
705
    modeManager->addProjectSelector(d->m_projectSelectorAction);
706
707
708
709
710
711

    d->m_projectSelectorActionMenu = new QAction(this);
    d->m_projectSelectorActionMenu->setEnabled(false);
    d->m_projectSelectorActionMenu->setText(tr("Open Build/Run Target Selector..."));
    connect(d->m_projectSelectorActionMenu, SIGNAL(triggered()), d->m_targetSelector, SLOT(show()));
    cmd = am->registerAction(d->m_projectSelectorActionMenu, ProjectExplorer::Constants::SELECTTARGET,
Tobias Hunger's avatar
Tobias Hunger committed
712
713
                       globalcontext);
    cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+T")));
714
    mbuild->addAction(cmd, Constants::G_BUILD_RUN);
715
716
717
718
719
720
721
722
723
724

    connect(d->m_session, SIGNAL(projectAdded(ProjectExplorer::Project*)),
            d->m_targetSelector, SLOT(addProject(ProjectExplorer::Project*)));
    connect(d->m_session, SIGNAL(projectRemoved(ProjectExplorer::Project*)),
            d->m_targetSelector, SLOT(removeProject(ProjectExplorer::Project*)));
    connect(d->m_targetSelector, SIGNAL(startupProjectChanged(ProjectExplorer::Project*)),
            this, SLOT(setStartupProject(ProjectExplorer::Project*)));
    connect(d->m_session, SIGNAL(startupProjectChanged(ProjectExplorer::Project*)),
            d->m_targetSelector, SLOT(changeStartupProject(ProjectExplorer::Project*)));

725
    connect(core, SIGNAL(saveSettingsRequested()),
con's avatar
con committed
726
727
        this, SLOT(savePersistentSettings()));

hjk's avatar
hjk committed
728
729
    addAutoReleasedObject(new ProjectTreeWidgetFactory);
    addAutoReleasedObject(new FolderNavigationWidgetFactory);
con's avatar
con committed
730

731
732
733
734
735
    if (QSettings *s = core->settings()) {
        const QStringList fileNames = s->value("ProjectExplorer/RecentProjects/FileNames").toStringList();
        const QStringList displayNames = s->value("ProjectExplorer/RecentProjects/DisplayNames").toStringList();
        if (fileNames.size() == displayNames.size()) {
            for (int i = 0; i < fileNames.size(); ++i) {
736
                if (QFileInfo(fileNames.at(i)).isFile())
737
                    d->m_recentProjects.append(qMakePair(fileNames.at(i), displayNames.at(i)));
738
739
740
741
            }
        }
    }

742
    if (QSettings *s = core->settings()) {
743
744
745
        d->m_projectExplorerSettings.buildBeforeRun = s->value("ProjectExplorer/Settings/BuildBeforeRun", true).toBool();
        d->m_projectExplorerSettings.saveBeforeBuild = s->value("ProjectExplorer/Settings/SaveBeforeBuild", false).toBool();
        d->m_projectExplorerSettings.showCompilerOutput = s->value("ProjectExplorer/Settings/ShowCompilerOutput", false).toBool();
746
        d->m_projectExplorerSettings.cleanOldAppOutput = s->value("ProjectExplorer/Settings/CleanOldAppOutput", false).toBool();
747
        d->m_projectExplorerSettings.useJom = s->value("ProjectExplorer/Settings/UseJom", true).toBool();
748
    }
749

750
751
    connect(d->m_sessionManagerAction, SIGNAL(triggered()), this, SLOT(showSessionManager()));
    connect(d->m_newAction, SIGNAL(triggered()), this, SLOT(newProject()));
con's avatar
con committed
752
#if 0
753
    connect(d->m_loadAction, SIGNAL(triggered()), this, SLOT(loadAction()));
con's avatar
con committed
754
#endif
755
756
    connect(d->m_buildProjectOnlyAction, SIGNAL(triggered()), this, SLOT(buildProjectOnly()));
    connect(d->m_buildAction, SIGNAL(triggered()), this, SLOT(buildProject()));
757
    connect(d->m_buildActionContextMenu, SIGNAL(triggered()), this, SLOT(buildProjectContextMenu()));
758
759
760
    connect(d->m_buildSessionAction, SIGNAL(triggered()), this, SLOT(buildSession()));
    connect(d->m_rebuildProjectOnlyAction, SIGNAL(triggered()), this, SLOT(rebuildProjectOnly()));
    connect(d->m_rebuildAction, SIGNAL(triggered()), this, SLOT(rebuildProject()));
761
    connect(d->m_rebuildActionContextMenu, SIGNAL(triggered()), this, SLOT(rebuildProjectContextMenu()));
762
763
764
    connect(d->m_rebuildSessionAction, SIGNAL(triggered()), this, SLOT(rebuildSession()));
    connect(d->m_cleanProjectOnlyAction, SIGNAL(triggered()), this, SLOT(cleanProjectOnly()));
    connect(d->m_cleanAction, SIGNAL(triggered()), this, SLOT(cleanProject()));
765
    connect(d->m_cleanActionContextMenu, SIGNAL(triggered()), this, SLOT(cleanProjectContextMenu()));
766
767
768
769
770
771
772
773
774
775
776
    connect(d->m_cleanSessionAction, SIGNAL(triggered()), this, SLOT(cleanSession()));
    connect(d->m_runAction, SIGNAL(triggered()), this, SLOT(runProject()));
    connect(d->m_runActionContextMenu, SIGNAL(triggered()), this, SLOT(runProjectContextMenu()));
    connect(d->m_cancelBuildAction, SIGNAL(triggered()), this, SLOT(cancelBuild()));
    connect(d->m_debugAction, SIGNAL(triggered()), this, SLOT(debugProject()));
    connect(d->m_unloadAction, SIGNAL(triggered()), this, SLOT(unloadProject()));
    connect(d->m_clearSession, SIGNAL(triggered()), this, SLOT(clearSession()));
    connect(d->m_addNewFileAction, SIGNAL(triggered()), this, SLOT(addNewFile()));
    connect(d->m_addExistingFilesAction, SIGNAL(triggered()), this, SLOT(addExistingFiles()));
    connect(d->m_openFileAction, SIGNAL(triggered()), this, SLOT(openFile()));
    connect(d->m_showInGraphicalShell, SIGNAL(triggered()), this, SLOT(showInGraphicalShell()));
777
    connect(d->m_openTerminalHere, SIGNAL(triggered()), this, SLOT(openTerminalHere()));
778
779
    connect(d->m_removeFileAction, SIGNAL(triggered()), this, SLOT(removeFile()));
    connect(d->m_renameFileAction, SIGNAL(triggered()), this, SLOT(renameFile()));
con's avatar
con committed
780
781
782

    updateActions();

783
784
    connect(Core::ICore::instance(), SIGNAL(coreAboutToOpen()),
            this, SLOT(determineSessionToRestoreAtStartup()));
785
    connect(Core::ICore::instance(), SIGNAL(coreOpened()), this, SLOT(restoreSession()));
con's avatar
con committed
786

787
788
    updateWelcomePage();

con's avatar
con committed
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
    return true;
}

// Find a factory by file mime type in a sequence of factories
template <class Factory, class Iterator>
    Factory *findFactory(const QString &mimeType, Iterator i1, Iterator i2)
{
    for ( ; i1 != i2; ++i2) {
        Factory *f = *i1;
        if (f->mimeTypes().contains(mimeType))
            return f;
    }
    return 0;
}

ProjectFileFactory * ProjectExplorerPlugin::findProjectFileFactory(const QString &filename) const
{
    // Find factory
807
    if (const Core::MimeType mt = Core::ICore::instance()->mimeDatabase()->findByFile(QFileInfo(filename)))
808
        if (ProjectFileFactory *pf = findFactory<ProjectFileFactory>(mt.type(), d->m_fileFactories.constBegin(), d->m_fileFactories.constEnd()))
con's avatar
con committed
809
810
811
812
813
814
815
816
817
818
819
            return pf;
    qWarning("Unable to find project file factory for '%s'", filename.toUtf8().constData());
    return 0;
}

void ProjectExplorerPlugin::loadAction()
{
    if (debug)
        qDebug() << "ProjectExplorerPlugin::loadAction";


820
    QString dir = d->m_lastOpenDirectory;
con's avatar
con committed
821
822
823
824
825
826

    // for your special convenience, we preselect a pro file if it is
    // the current file
    if (Core::IEditor *editor = Core::EditorManager::instance()->currentEditor()) {
        if (const Core::IFile *file = editor->file()) {
            const QString fn = file->fileName();
827
            const bool isProject = d->m_profileMimeTypes.contains(file->mimeType());
con's avatar
con committed
828
829
830
831
832
833
            dir = isProject ? fn : QFileInfo(fn).absolutePath();
        }
    }

    QString filename = QFileDialog::getOpenFileName(0, tr("Load Project"),
                                                    dir,
834
                                                    d->m_projectFilterString);
con's avatar
con committed
835
836
837
838
839
840
841
    if (filename.isEmpty())
        return;
    if (ProjectFileFactory *pf = findProjectFileFactory(filename))
        pf->open(filename);
    updateActions();
}

842
void ProjectExplorerPlugin::unloadProject()
con's avatar
con committed
843
844
{
    if (debug)
845
        qDebug() << "ProjectExplorerPlugin::unloadProject";
con's avatar
con committed
846

847
    Core::IFile *fi = d->m_currentProject->file();
con's avatar
con committed
848
849

    if (!fi || fi->fileName().isEmpty()) //nothing to save?
850
        return;
con's avatar
con committed
851
852
853
854
855
856
857
858
859
860
861
862
863

    QList<Core::IFile*> filesToSave;
    filesToSave << fi;

    // check the number of modified files
    int readonlycount = 0;
    foreach (const Core::IFile *file, filesToSave) {
        if (file->isReadOnly())
            ++readonlycount;
    }

    bool success = false;
    if (readonlycount > 0)
864
        success = Core::ICore::instance()->fileManager()->saveModifiedFiles(filesToSave).isEmpty();
con's avatar
con committed
865
    else
866
        success = Core::ICore::instance()->fileManager()->saveModifiedFilesSilently(filesToSave).isEmpty();
con's avatar
con committed
867

868
    if (!success)
con's avatar
con committed
869
870
        return;

871
    addToRecentProjects(fi->fileName(), d->m_currentProject->displayName());
872
    d->m_session->removeProject(d->m_currentProject);
con's avatar
con committed
873
874
875
876
877
878
879
880
    updateActions();
}

void ProjectExplorerPlugin::clearSession()
{
    if (debug)
        qDebug() << "ProjectExplorerPlugin::clearSession";

881
    if (!d->m_session->clear())
con's avatar
con committed
882
883
884
885
886
887
        return; // Action has been cancelled
    updateActions();
}

void ProjectExplorerPlugin::extensionsInitialized()
{
888
889
890
    d->m_fileFactories = ProjectFileFactory::createFactories(&d->m_projectFilterString);
    foreach (ProjectFileFactory *pf, d->m_fileFactories) {
        d->m_profileMimeTypes += pf->mimeTypes();
con's avatar
con committed
891
892
        addAutoReleasedObject(pf);
    }
893
894
895
896
    // Add custom wizards, for which other plugins might have registered
    // class factories
    foreach(Core::IWizard *cpw, ProjectExplorer::CustomWizard::createWizards())
        addAutoReleasedObject(cpw);
con's avatar
con committed
897
898
}

899
void ProjectExplorerPlugin::aboutToShutdown()
con's avatar
con committed
900
{
901
    d->m_proWindow->aboutToShutdown(); // disconnect from session
902
    d->m_session->clear();
903
    d->m_projectsMode = 0;
904
//    d->m_proWindow->saveConfigChanges();
con's avatar
con committed
905
906
907
908
909
910
911
912
913
}

void ProjectExplorerPlugin::newProject()
{
    if (debug)
        qDebug() << "ProjectExplorerPlugin::newProject";

    QString defaultLocation;
    if (currentProject()) {
914
        QDir dir(currentProject()->projectDirectory());
con's avatar
con committed
915
916
917
918
        dir.cdUp();
        defaultLocation = dir.absolutePath();
    }

919
    Core::ICore::instance()->showNewItemDialog(tr("New Project", "Title of dialog"),
920
                              Core::IWizard::wizardsOfKind(Core::IWizard::ProjectWizard),
con's avatar
con committed
921
922
923
924
                              defaultLocation);
    updateActions();
}

925
void ProjectExplorerPlugin::showSessionManager()
con's avatar
con committed
926
927
{
    if (debug)
928
        qDebug() << "ProjectExplorerPlugin::showSessionManager";
con's avatar
con committed
929

930
    if (d->m_session->isDefaultVirgin()) {
con's avatar
con committed
931
932
        // do not save new virgin default sessions
    } else {
933
        d->m_session->save();
con's avatar
con committed
934
    }
935
    SessionDialog sessionDialog(d->m_session);
con's avatar
con committed
936
937
938
    sessionDialog.exec();

    updateActions();
939
940
941
942

    Core::ModeManager *modeManager = Core::ModeManager::instance();
    Core::IMode *welcomeMode = modeManager->mode(Core::Constants::MODE_WELCOME);
    if (modeManager->currentMode() == welcomeMode)
943
        updateWelcomePage();
con's avatar
con committed
944
945
946
947
948
949
950
}

void ProjectExplorerPlugin::setStartupProject(Project *project)
{
    if (debug)
        qDebug() << "ProjectExplorerPlugin::setStartupProject";

dt's avatar
dt committed
951
952
    if (!project)
        return;
953
    d->m_session->setStartupProject(project);
con's avatar
con committed
954
955
956
957
958
959
960
961
    updateActions();
}

void ProjectExplorerPlugin::savePersistentSettings()
{
    if (debug)
        qDebug()<<"ProjectExplorerPlugin::savePersistentSettings()";

962
    foreach (Project *pro, d->m_session->projects())
con's avatar
con committed
963
964
        pro->saveSettings();

965
    if (d->m_session->isDefaultVirgin()) {
con's avatar
con committed
966
967
        // do not save new virgin default sessions
    } else {
968
        d->m_session->save();
con's avatar
con committed
969
970
    }

971
    QSettings *s = Core::ICore::instance()->settings();
con's avatar
con committed
972
    if (s) {
973
        s->setValue("ProjectExplorer/StartupSession", d->m_session->file()->fileName());
974
975
976
977
978
        s->remove("ProjectExplorer/RecentProjects/Files");

        QStringList fileNames;
        QStringList displayNames;
        QList<QPair<QString, QString> >::const_iterator it, end;
979
980
        end = d->m_recentProjects.constEnd();
        for (it = d->m_recentProjects.constBegin(); it != end; ++it) {
981
982
983
984
985
986
            fileNames << (*it).first;
            displayNames << (*it).second;
        }

        s->setValue("ProjectExplorer/RecentProjects/FileNames", fileNames);
        s->setValue("ProjectExplorer/RecentProjects/DisplayNames", displayNames);
987

988
989
990
        s->setValue("ProjectExplorer/Settings/BuildBeforeRun", d->m_projectExplorerSettings.buildBeforeRun);
        s->setValue("ProjectExplorer/Settings/SaveBeforeBuild", d->m_projectExplorerSettings.saveBeforeBuild);
        s->setValue("ProjectExplorer/Settings/ShowCompilerOutput", d->m_projectExplorerSettings.showCompilerOutput);
991
        s->setValue("ProjectExplorer/Settings/CleanOldAppOutput", d->m_projectExplorerSettings.cleanOldAppOutput);
992
        s->setValue("ProjectExplorer/Settings/UseJom", d->m_projectExplorerSettings.useJom);
con's avatar
con committed
993
994
995
996
997
998
999
1000
    }
}

bool ProjectExplorerPlugin::openProject(const QString &fileName)
{
    if (debug)
        qDebug() << "ProjectExplorerPlugin::openProject";

dt's avatar