projectexplorer.cpp 74.2 KB
Newer Older
1
/**************************************************************************
con's avatar
con committed
2
3
4
**
** This file is part of Qt Creator
**
5
** Copyright (c) 2009 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
26
** contact the sales department at http://www.qtsoftware.com/contact.
con's avatar
con committed
27
**
28
**************************************************************************/
hjk's avatar
hjk committed
29

con's avatar
con committed
30
31
32
33
34
#include "applicationrunconfiguration.h"
#include "allprojectsfilter.h"
#include "allprojectsfind.h"
#include "buildmanager.h"
#include "buildsettingspropertiespage.h"
35
#include "currentprojectfind.h"
con's avatar
con committed
36
37
#include "currentprojectfilter.h"
#include "customexecutablerunconfiguration.h"
38
39
#include "editorsettingspropertiespage.h"
#include "dependenciespanel.h"
con's avatar
con committed
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#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 "projectexplorer.h"
#include "projectexplorerconstants.h"
#include "projectfilewizardextension.h"
#include "projecttreewidget.h"
#include "projectwindow.h"
#include "removefiledialog.h"
#include "runsettingspropertiespage.h"
#include "scriptwrappers.h"
#include "session.h"
#include "sessiondialog.h"
58
#include "buildparserfactory.h"
59
#include "projectexplorersettingspage.h"
con's avatar
con committed
60
61
62

#include <coreplugin/basemode.h>
#include <coreplugin/coreconstants.h>
63
64
#include <coreplugin/filemanager.h>
#include <coreplugin/icore.h>
con's avatar
con committed
65
66
67
68
#include <coreplugin/mainwindow.h>
#include <coreplugin/mimedatabase.h>
#include <coreplugin/modemanager.h>
#include <coreplugin/uniqueidmanager.h>
69
#include <coreplugin/actionmanager/actionmanager.h>
con's avatar
con committed
70
71
72
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/editormanager/ieditor.h>
#include <coreplugin/editormanager/ieditorfactory.h>
73
#include <coreplugin/editormanager/iexternaleditor.h>
con's avatar
con committed
74
75
76
77
78
79
#include <coreplugin/findplaceholder.h>
#include <coreplugin/basefilewizard.h>
#include <coreplugin/mainwindow.h>
#include <coreplugin/welcomemode.h>
#include <coreplugin/vcsmanager.h>
#include <coreplugin/iversioncontrol.h>
80
#include <coreplugin/vcsmanager.h>
81
#include <coreplugin/welcomemode.h>
82
#include <extensionsystem/pluginmanager.h>
hjk's avatar
hjk committed
83
#include <utils/qtcassert.h>
84
#include <utils/parameteraction.h>
con's avatar
con committed
85

86
#include <QtCore/QtPlugin>
hjk's avatar
hjk committed
87
#include <QtCore/QDateTime>
con's avatar
con committed
88
89
#include <QtCore/QDebug>
#include <QtCore/QSettings>
hjk's avatar
hjk committed
90

con's avatar
con committed
91
92
#include <QtGui/QAction>
#include <QtGui/QApplication>
hjk's avatar
hjk committed
93
94
95
#include <QtGui/QFileDialog>
#include <QtGui/QMenu>
#include <QtGui/QMessageBox>
con's avatar
con committed
96
97

Q_DECLARE_METATYPE(QSharedPointer<ProjectExplorer::RunConfiguration>);
98
99
Q_DECLARE_METATYPE(Core::IEditorFactory*);
Q_DECLARE_METATYPE(Core::IExternalEditor*);
con's avatar
con committed
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119

namespace {
bool debug = false;
}

using namespace ProjectExplorer;
using namespace ProjectExplorer::Internal;

CoreListenerCheckingForRunningBuild::CoreListenerCheckingForRunningBuild(BuildManager *manager)
    : Core::ICoreListener(0), m_manager(manager)
{
}

bool CoreListenerCheckingForRunningBuild::coreAboutToClose()
{
    if (m_manager->isBuilding()) {
        QMessageBox box;
        QPushButton *closeAnyway = box.addButton(tr("Cancel Build && Close"), QMessageBox::AcceptRole);
        QPushButton *cancelClose = box.addButton(tr("Don't Close"), QMessageBox::RejectRole);
        box.setDefaultButton(cancelClose);
120
        box.setWindowTitle(tr("Close Qt Creator?"));
con's avatar
con committed
121
        box.setText(tr("A project is currently being built."));
122
        box.setInformativeText(tr("Do you want to cancel the build process and close Qt Creator anyway?"));
con's avatar
con committed
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
        box.exec();
        return (box.clickedButton() == closeAnyway);
    }
    return true;
}

ProjectExplorerPlugin *ProjectExplorerPlugin::m_instance = 0;

ProjectExplorerPlugin::ProjectExplorerPlugin()
    : m_buildConfigurationActionGroup(0),
      m_runConfigurationActionGroup(0),
      m_currentProject(0),
      m_currentNode(0),
      m_delayedRunConfiguration(0),
      m_debuggingRunControl(0)
{
    m_instance = this;
}

ProjectExplorerPlugin::~ProjectExplorerPlugin()
{
    removeObject(this);
}

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

152
bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *error)
con's avatar
con committed
153
{
154
155
156
    Q_UNUSED(arguments);
    Q_UNUSED(error);

157
158
    Core::ICore *core = Core::ICore::instance();
    Core::ActionManager *am = core->actionManager();
con's avatar
con committed
159
160
161

    addObject(this);

hjk's avatar
hjk committed
162
163
    connect(core->fileManager(), SIGNAL(currentFileChanged(QString)),
            this, SLOT(setCurrentFile(QString)));
con's avatar
con committed
164

hjk's avatar
hjk committed
165
    m_session = new SessionManager(this);
con's avatar
con committed
166
167
168
169
170
171
172
173
174
175

    connect(m_session, SIGNAL(projectAdded(ProjectExplorer::Project *)),
            this, SIGNAL(fileListChanged()));
    connect(m_session, SIGNAL(aboutToRemoveProject(ProjectExplorer::Project *)),
            this, SLOT(invalidateProject(ProjectExplorer::Project *)));
    connect(m_session, SIGNAL(projectRemoved(ProjectExplorer::Project *)),
            this, SIGNAL(fileListChanged()));
    connect(m_session, SIGNAL(startupProjectChanged(ProjectExplorer::Project *)),
            this, SLOT(startupProjectChanged()));

176
    m_proWindow = new ProjectWindow;
con's avatar
con committed
177
178
179
180
181

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

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

hjk's avatar
hjk committed
184
185
186
187
188
189
    Core::BaseMode *mode = new Core::BaseMode;
    mode->setName(tr("Projects"));
    mode->setUniqueModeName(Constants::MODE_SESSION);
    mode->setIcon(QIcon(QLatin1String(":/fancyactionbar/images/mode_Project.png")));
    mode->setPriority(Constants::P_MODE_SESSION);
    mode->setWidget(m_proWindow);
con's avatar
con committed
190
191
192
193
194
195
196
197
198
199
200
201
    mode->setContext(QList<int>() << pecontext);
    addAutoReleasedObject(mode);
    m_proWindow->layout()->addWidget(new Core::FindToolBarPlaceHolder(mode));

    m_buildManager = new BuildManager(this);
    connect(m_buildManager, SIGNAL(buildStateChanged(ProjectExplorer::Project *)),
            this, SLOT(buildStateChanged(ProjectExplorer::Project *)));
    connect(m_buildManager, SIGNAL(buildQueueFinished(bool)),
            this, SLOT(buildQueueFinished(bool)));

    addAutoReleasedObject(new CoreListenerCheckingForRunningBuild(m_buildManager));

hjk's avatar
hjk committed
202
    m_outputPane = new OutputPane;
con's avatar
con committed
203
204
205
206
    addAutoReleasedObject(m_outputPane);
    connect(m_session, SIGNAL(projectRemoved(ProjectExplorer::Project *)),
            m_outputPane, SLOT(projectRemoved()));

207
    AllProjectsFilter *allProjectsFilter = new AllProjectsFilter(this);
con's avatar
con committed
208
209
    addAutoReleasedObject(allProjectsFilter);

210
    CurrentProjectFilter *currentProjectFilter = new CurrentProjectFilter(this);
con's avatar
con committed
211
212
213
214
215
    addAutoReleasedObject(currentProjectFilter);

    addAutoReleasedObject(new BuildSettingsPanelFactory);
    addAutoReleasedObject(new RunSettingsPanelFactory);
    addAutoReleasedObject(new EditorSettingsPanelFactory);
216
    addAutoReleasedObject(new DependenciesPanelFactory(m_session));
con's avatar
con committed
217
218
219
220

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

221
222
223
    ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
    AllProjectsFind *allProjectsFind = new AllProjectsFind(this,
        pm->getObject<Find::SearchResultWindow>());
con's avatar
con committed
224
225
    addAutoReleasedObject(allProjectsFind);

226
227
    CurrentProjectFind *currentProjectFind = new CurrentProjectFind(this,
        pm->getObject<Find::SearchResultWindow>());
con's avatar
con committed
228
229
230
231
232
    addAutoReleasedObject(currentProjectFind);

    addAutoReleasedObject(new ApplicationRunConfigurationRunner);
    addAutoReleasedObject(new CustomExecutableRunConfigurationFactory);

233
    addAutoReleasedObject(new ProjectFileWizardExtension);
con's avatar
con committed
234

235
236
237
238
    // Build parsers
    addAutoReleasedObject(new GccParserFactory);
    addAutoReleasedObject(new MsvcParserFactory);

239
240
241
    // Settings page
    addAutoReleasedObject(new ProjectExplorerSettingsPage);

con's avatar
con committed
242
    // context menus
243
    Core::ActionContainer *msessionContextMenu =
con's avatar
con committed
244
        am->createMenu(Constants::M_SESSIONCONTEXT);
245
    Core::ActionContainer *mproject =
con's avatar
con committed
246
        am->createMenu(Constants::M_PROJECTCONTEXT);
247
    Core::ActionContainer *msubProject =
con's avatar
con committed
248
        am->createMenu(Constants::M_SUBPROJECTCONTEXT);
249
    Core::ActionContainer *mfolder =
con's avatar
con committed
250
        am->createMenu(Constants::M_FOLDERCONTEXT);
251
    Core::ActionContainer *mfilec =
con's avatar
con committed
252
253
254
255
256
257
258
259
        am->createMenu(Constants::M_FILECONTEXT);

    m_sessionContextMenu = msessionContextMenu->menu();
    m_projectMenu = mproject->menu();
    m_subProjectMenu = msubProject->menu();
    m_folderMenu = mfolder->menu();
    m_fileMenu = mfilec->menu();

260
    Core::ActionContainer *mfile =
con's avatar
con committed
261
        am->actionContainer(Core::Constants::M_FILE);
262
    Core::ActionContainer *menubar =
con's avatar
con committed
263
264
265
        am->actionContainer(Core::Constants::MENU_BAR);

    // mode manager (for fancy actions)
266
    Core::ModeManager *modeManager = core->modeManager();
con's avatar
con committed
267
268

    // build menu
269
    Core::ActionContainer *mbuild =
con's avatar
con committed
270
        am->createMenu(Constants::M_BUILDPROJECT);
271
    mbuild->menu()->setTitle(tr("&Build"));
con's avatar
con committed
272
273
274
    menubar->addMenu(mbuild, Core::Constants::G_VIEW);

    // debug menu
275
    Core::ActionContainer *mdebug =
con's avatar
con committed
276
        am->createMenu(Constants::M_DEBUG);
277
    mdebug->menu()->setTitle(tr("&Debug"));
con's avatar
con committed
278
279
    menubar->addMenu(mdebug, Core::Constants::G_VIEW);

280
281
282
283
    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
284
285
286
287
288
289
290
291
292

    //
    // 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
293
    mbuild->appendGroup(Constants::G_BUILD_RUN);
con's avatar
con committed
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321

    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);
    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
322
    Core::ActionContainer * const openWith =
con's avatar
con committed
323
324
325
326
327
328
329
330
331
332
333
334
            am->createMenu(ProjectExplorer::Constants::M_OPENFILEWITHCONTEXT);
    m_openWithMenu = openWith->menu();
    m_openWithMenu->setTitle(tr("Open With"));

    connect(mfilec->menu(), SIGNAL(aboutToShow()), this, SLOT(populateOpenWithMenu()));
    connect(m_openWithMenu, SIGNAL(triggered(QAction *)),
            this, SLOT(openWithMenuTriggered(QAction *)));

    //
    // Separators
    //

con's avatar
con committed
335
    Core::Command *cmd;
con's avatar
con committed
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
    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.Close.Sep"), globalcontext);
    mfile->addAction(cmd, Core::Constants::G_FILE_CLOSE);

    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
    m_sessionManagerAction = new QAction(tr("Session Manager..."), this);
    cmd = am->registerAction(m_sessionManagerAction, Constants::NEWSESSION, globalcontext);
    cmd->setDefaultKeySequence(QKeySequence());

    // new action
    m_newAction = new QAction(tr("New Project..."), this);
    cmd = am->registerAction(m_newAction, Constants::NEWPROJECT, globalcontext);
    cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+N")));
    msessionContextMenu->addAction(cmd, Constants::G_SESSION_FILES);

#if 0
    // open action
    m_loadAction = new QAction(tr("Load Project..."), this);
    cmd = am->registerAction(m_loadAction, Constants::LOAD, globalcontext);
    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
    m_openFileAction = new QAction(tr("Open File"), this);
    cmd = am->registerAction(m_openFileAction, ProjectExplorer::Constants::OPENFILE,
                       globalcontext);
    mfilec->addAction(cmd, Constants::G_FILE_OPEN);

con's avatar
con committed
421
422
423
424
425
426
427
428
#ifdef Q_OS_MAC
    // Show in Finder action
    m_showInFinder = new QAction(tr("Show in Finder..."), this);
    cmd = am->registerAction(m_showInFinder, ProjectExplorer::Constants::SHOWINFINDER,
                       globalcontext);
    mfilec->addAction(cmd, Constants::G_FILE_OPEN);
#endif

con's avatar
con committed
429
430
431
    // Open With menu
    mfilec->addMenu(openWith, ProjectExplorer::Constants::G_FILE_OPEN);

mae's avatar
mae committed
432
    // recent projects menu
433
    Core::ActionContainer *mrecent =
mae's avatar
mae committed
434
        am->createMenu(Constants::M_RECENTPROJECTS);
435
    mrecent->menu()->setTitle(tr("Recent Projects"));
mae's avatar
mae committed
436
437
438
439
    mfile->addMenu(mrecent, Core::Constants::G_FILE_OPEN);
    connect(mfile->menu(), SIGNAL(aboutToShow()),
        this, SLOT(updateRecentProjectMenu()));

con's avatar
con committed
440
    // unload action
441
442
    m_unloadAction = new Core::Utils::ParameterAction(tr("Close Project"), tr("Close Project \"%1\""),
                                                      Core::Utils::ParameterAction::EnabledWithParameter, this);
con's avatar
con committed
443
    cmd = am->registerAction(m_unloadAction, Constants::UNLOAD, globalcontext);
con's avatar
con committed
444
    cmd->setAttribute(Core::Command::CA_UpdateText);
con's avatar
con committed
445
446
447
448
449
    cmd->setDefaultText(m_unloadAction->text());
    mfile->addAction(cmd, Core::Constants::G_FILE_PROJECT);
    mproject->addAction(cmd, Constants::G_PROJECT_FILES);

    // unload session action
Oswald Buddenhagen's avatar
Oswald Buddenhagen committed
450
    m_clearSession = new QAction(tr("Close All Projects"), this);
con's avatar
con committed
451
452
453
454
455
    cmd = am->registerAction(m_clearSession, Constants::CLEARSESSION, globalcontext);
    mfile->addAction(cmd, Core::Constants::G_FILE_PROJECT);
    msessionContextMenu->addAction(cmd, Constants::G_SESSION_FILES);

    // session menu
456
    Core::ActionContainer *msession = am->createMenu(Constants::M_SESSION);
457
    msession->menu()->setTitle(tr("Session"));
con's avatar
con committed
458
459
460
461
462
463
    mfile->addMenu(msession, Core::Constants::G_FILE_PROJECT);
    m_sessionMenu = msession->menu();
    connect(mfile->menu(), SIGNAL(aboutToShow()),
            this, SLOT(updateSessionMenu()));

    // build menu
464
    Core::ActionContainer *mbc =
con's avatar
con committed
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
        am->createMenu(Constants::BUILDCONFIGURATIONMENU);
    m_buildConfigurationMenu = mbc->menu();
    m_buildConfigurationMenu->setTitle(tr("Set Build Configuration"));
    //TODO this means it is build twice, rrr
    connect(mproject->menu(), SIGNAL(aboutToShow()), this, SLOT(populateBuildConfigurationMenu()));
    connect(mbuild->menu(), SIGNAL(aboutToShow()), this, SLOT(populateBuildConfigurationMenu()));
    connect(m_buildConfigurationMenu, SIGNAL(aboutToShow()), this, SLOT(populateBuildConfigurationMenu()));
    connect(m_buildConfigurationMenu, SIGNAL(triggered(QAction *)), this, SLOT(buildConfigurationMenuTriggered(QAction *)));

    // build session action
    QIcon buildIcon(Constants::ICON_BUILD);
    buildIcon.addFile(Constants::ICON_BUILD_SMALL);
    m_buildSessionAction = new QAction(buildIcon, tr("Build All"), this);
    cmd = am->registerAction(m_buildSessionAction, Constants::BUILDSESSION, globalcontext);
    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
    modeManager->addAction(cmd, Constants::P_ACTION_BUILDSESSION, m_buildConfigurationMenu);

    // rebuild session action
    QIcon rebuildIcon(Constants::ICON_REBUILD);
    rebuildIcon.addFile(Constants::ICON_REBUILD_SMALL);
    m_rebuildSessionAction = new QAction(rebuildIcon, tr("Rebuild All"), this);
    cmd = am->registerAction(m_rebuildSessionAction, Constants::REBUILDSESSION, globalcontext);
    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);
    m_cleanSessionAction = new QAction(cleanIcon, tr("Clean All"), this);
    cmd = am->registerAction(m_cleanSessionAction, Constants::CLEANSESSION, globalcontext);
    mbuild->addAction(cmd, Constants::G_BUILD_SESSION);
    msessionContextMenu->addAction(cmd, Constants::G_SESSION_BUILD);

    // build action
502
503
    m_buildAction = new Core::Utils::ParameterAction(tr("Build Project"), tr("Build Project \"%1\""),
                                                     Core::Utils::ParameterAction::EnabledWithParameter, this);
con's avatar
con committed
504
    cmd = am->registerAction(m_buildAction, Constants::BUILD, globalcontext);
505
506
    cmd->setAttribute(Core::Command::CA_UpdateText);
    cmd->setDefaultText(m_buildAction->text());
con's avatar
con committed
507
508
509
510
511
    cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+B")));
    mbuild->addAction(cmd, Constants::G_BUILD_PROJECT);
    mproject->addAction(cmd, Constants::G_PROJECT_BUILD);

    // rebuild action
512
513
    m_rebuildAction = new Core::Utils::ParameterAction(tr("Rebuild Project"), tr("Rebuild Project \"%1\""),
                                                       Core::Utils::ParameterAction::EnabledWithParameter, this);
con's avatar
con committed
514
    cmd = am->registerAction(m_rebuildAction, Constants::REBUILD, globalcontext);
515
516
    cmd->setAttribute(Core::Command::CA_UpdateText);
    cmd->setDefaultText(m_rebuildAction->text());
con's avatar
con committed
517
518
519
520
    mbuild->addAction(cmd, Constants::G_BUILD_PROJECT);
    mproject->addAction(cmd, Constants::G_PROJECT_BUILD);

    // clean action
521
522
    m_cleanAction = new Core::Utils::ParameterAction(tr("Clean Project"), tr("Clean Project \"%1\""),
                                                     Core::Utils::ParameterAction::EnabledWithParameter, this);
con's avatar
con committed
523
    cmd = am->registerAction(m_cleanAction, Constants::CLEAN, globalcontext);
524
525
    cmd->setAttribute(Core::Command::CA_UpdateText);
    cmd->setDefaultText(m_cleanAction->text());
con's avatar
con committed
526
527
528
    mbuild->addAction(cmd, Constants::G_BUILD_PROJECT);
    mproject->addAction(cmd, Constants::G_PROJECT_BUILD);

529
530
    // build without dependencies action
    m_buildProjectOnlyAction = new QAction(tr("Build Without Dependencies"), this);
531
    cmd = am->registerAction(m_buildProjectOnlyAction, Constants::BUILDPROJECTONLY, globalcontext);
532

533
534
    // rebuild without dependencies action
    m_rebuildProjectOnlyAction = new QAction(tr("Rebuild Without Dependencies"), this);
535
    cmd = am->registerAction(m_rebuildProjectOnlyAction, Constants::REBUILDPROJECTONLY, globalcontext);
536

537
538
    // clean without dependencies action
    m_cleanProjectOnlyAction = new QAction(tr("Clean Without Dependencies"), this);
539
    cmd = am->registerAction(m_cleanProjectOnlyAction, Constants::CLEANPROJECTONLY, globalcontext);
540

con's avatar
con committed
541
    // Add Set Build Configuration to menu
dt's avatar
dt committed
542
    mbuild->addMenu(mbc, Constants::G_BUILD_OTHER);
con's avatar
con committed
543
544
545
546
547
548
549
550
551
    mproject->addMenu(mbc, Constants::G_PROJECT_CONFIG);

    // run action
    QIcon runIcon(Constants::ICON_RUN);
    runIcon.addFile(Constants::ICON_RUN_SMALL);
    m_runAction = new QAction(runIcon, tr("Run"), this);
    cmd = am->registerAction(m_runAction, Constants::RUN, globalcontext);
    cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+R")));
    mbuild->addAction(cmd, Constants::G_BUILD_RUN);
552

553
    Core::ActionContainer *mrc = am->createMenu(Constants::RUNCONFIGURATIONMENU);
con's avatar
con committed
554
555
556
557
558
559
560
561
562
563
564
565
    m_runConfigurationMenu = mrc->menu();
    m_runConfigurationMenu->setTitle(tr("Set Run Configuration"));
    mbuild->addMenu(mrc, Constants::G_BUILD_RUN);
    mproject->addMenu(mrc, Constants::G_PROJECT_CONFIG);
    // TODO this recreates the menu twice if shown in the Build or context menu
    connect(m_runConfigurationMenu, SIGNAL(aboutToShow()), this, SLOT(populateRunConfigurationMenu()));
    connect(mproject->menu(), SIGNAL(aboutToShow()), this, SLOT(populateRunConfigurationMenu()));
    connect(mbuild->menu(), SIGNAL(aboutToShow()), this, SLOT(populateRunConfigurationMenu()));
    connect(m_runConfigurationMenu, SIGNAL(triggered(QAction *)), this, SLOT(runConfigurationMenuTriggered(QAction *)));

    modeManager->addAction(cmd, Constants::P_ACTION_RUN, m_runConfigurationMenu);

566
567
568
569
    m_runActionContextMenu = new QAction(runIcon, tr("Run"), this);
    cmd = am->registerAction(m_runActionContextMenu, Constants::RUNCONTEXTMENU, globalcontext);
    mproject->addAction(cmd, Constants::G_PROJECT_RUN);

con's avatar
con committed
570
571
572
573
574
575
576
    // cancel build action
    m_cancelBuildAction = new QAction(tr("Cancel Build"), this);
    cmd = am->registerAction(m_cancelBuildAction, Constants::CANCELBUILD, globalcontext);
    mbuild->addAction(cmd, Constants::G_BUILD_CANCEL);

    // debug action
    QIcon debuggerIcon(":/projectexplorer/images/debugger_start_small.png");
577
    debuggerIcon.addFile(":/projectexplorer/images/debugger_start.png");
con's avatar
con committed
578
579
    m_debugAction = new QAction(debuggerIcon, tr("Start Debugging"), this);
    cmd = am->registerAction(m_debugAction, Constants::DEBUG, globalcontext);
con's avatar
con committed
580
581
    cmd->setAttribute(Core::Command::CA_UpdateText);
    cmd->setAttribute(Core::Command::CA_UpdateIcon);
con's avatar
con committed
582
583
    cmd->setDefaultText(tr("Start Debugging"));
    cmd->setDefaultKeySequence(QKeySequence(tr("F5")));
584
    mstartdebugging->addAction(cmd, Core::Constants::G_DEFAULT_ONE);
con's avatar
con committed
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
    modeManager->addAction(cmd, Constants::P_ACTION_DEBUG, m_runConfigurationMenu);

    // add new file action
    m_addNewFileAction = new QAction(tr("Add New..."), this);
    cmd = am->registerAction(m_addNewFileAction, ProjectExplorer::Constants::ADDNEWFILE,
                       globalcontext);
    mproject->addAction(cmd, Constants::G_PROJECT_FILES);
    msubProject->addAction(cmd, Constants::G_PROJECT_FILES);

    // add existing file action
    m_addExistingFilesAction = new QAction(tr("Add Existing Files..."), this);
    cmd = am->registerAction(m_addExistingFilesAction, ProjectExplorer::Constants::ADDEXISTINGFILES,
                       globalcontext);
    mproject->addAction(cmd, Constants::G_PROJECT_FILES);
    msubProject->addAction(cmd, Constants::G_PROJECT_FILES);

    // remove file action
    m_removeFileAction = new QAction(tr("Remove File..."), this);
    cmd = am->registerAction(m_removeFileAction, ProjectExplorer::Constants::REMOVEFILE,
                       globalcontext);
    mfilec->addAction(cmd, Constants::G_FILE_OTHER);

    // renamefile action (TODO: Not supported yet)
    m_renameFileAction = new QAction(tr("Rename"), this);
    cmd = am->registerAction(m_renameFileAction, ProjectExplorer::Constants::RENAMEFILE,
                       globalcontext);
    mfilec->addAction(cmd, Constants::G_FILE_OTHER);
    m_renameFileAction->setEnabled(false);
    m_renameFileAction->setVisible(false);

615
    connect(core, SIGNAL(saveSettingsRequested()),
con's avatar
con committed
616
617
        this, SLOT(savePersistentSettings()));

hjk's avatar
hjk committed
618
619
    addAutoReleasedObject(new ProjectTreeWidgetFactory);
    addAutoReleasedObject(new FolderNavigationWidgetFactory);
con's avatar
con committed
620

621
    // > -- Creator 1.0 compatibility code
622
    QStringList oldRecentProjects;
623
    if (QSettings *s = core->settings())
624
625
        oldRecentProjects = s->value("ProjectExplorer/RecentProjects/Files", QStringList()).toStringList();
    for (QStringList::iterator it = oldRecentProjects.begin(); it != oldRecentProjects.end(); ) {
con's avatar
con committed
626
627
628
        if (QFileInfo(*it).isFile()) {
            ++it;
        } else {
629
            it = oldRecentProjects.erase(it);
con's avatar
con committed
630
631
632
        }
    }

633
634
635
    foreach(const QString &s, oldRecentProjects) {
        m_recentProjects.append(qMakePair(s, QFileInfo(s).fileName()));
    }
636
    // < -- Creator 1.0 compatibility code
637
638
639
640
641
642

    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) {
643
644
                if (QFileInfo(fileNames.at(i)).isFile())
                    m_recentProjects.append(qMakePair(fileNames.at(i), displayNames.at(i)));
645
646
647
648
            }
        }
    }

649
650
651
652
    if (QSettings *s = core->settings()) {
        m_projectExplorerSettings.buildBeforeRun = s->value("ProjectExplorer/Settings/BuildBeforeRun", true).toBool();
        m_projectExplorerSettings.saveBeforeBuild = s->value("ProjectExplorer/Settings/SaveBeforeBuild", false).toBool();
    }
653

654
655
656
657
    if (Core::Internal::WelcomeMode *welcomeMode = qobject_cast<Core::Internal::WelcomeMode*>
        (Core::ICore::instance()->modeManager()->mode(Core::Constants::MODE_WELCOME))) {
        connect(welcomeMode, SIGNAL(manageSessions()), this, SLOT(showSessionManager()));
    }
658
    connect(m_sessionManagerAction, SIGNAL(triggered()), this, SLOT(showSessionManager()));
con's avatar
con committed
659
660
661
662
    connect(m_newAction, SIGNAL(triggered()), this, SLOT(newProject()));
#if 0
    connect(m_loadAction, SIGNAL(triggered()), this, SLOT(loadAction()));
#endif
663
    connect(m_buildProjectOnlyAction, SIGNAL(triggered()), this, SLOT(buildProjectOnly()));
con's avatar
con committed
664
665
    connect(m_buildAction, SIGNAL(triggered()), this, SLOT(buildProject()));
    connect(m_buildSessionAction, SIGNAL(triggered()), this, SLOT(buildSession()));
666
    connect(m_rebuildProjectOnlyAction, SIGNAL(triggered()), this, SLOT(rebuildProjectOnly()));
con's avatar
con committed
667
668
    connect(m_rebuildAction, SIGNAL(triggered()), this, SLOT(rebuildProject()));
    connect(m_rebuildSessionAction, SIGNAL(triggered()), this, SLOT(rebuildSession()));
669
    connect(m_cleanProjectOnlyAction, SIGNAL(triggered()), this, SLOT(cleanProjectOnly()));
con's avatar
con committed
670
671
672
    connect(m_cleanAction, SIGNAL(triggered()), this, SLOT(cleanProject()));
    connect(m_cleanSessionAction, SIGNAL(triggered()), this, SLOT(cleanSession()));
    connect(m_runAction, SIGNAL(triggered()), this, SLOT(runProject()));
673
    connect(m_runActionContextMenu, SIGNAL(triggered()), this, SLOT(runProjectContextMenu()));
con's avatar
con committed
674
675
676
677
678
679
680
    connect(m_cancelBuildAction, SIGNAL(triggered()), this, SLOT(cancelBuild()));
    connect(m_debugAction, SIGNAL(triggered()), this, SLOT(debugProject()));
    connect(m_unloadAction, SIGNAL(triggered()), this, SLOT(unloadProject()));
    connect(m_clearSession, SIGNAL(triggered()), this, SLOT(clearSession()));
    connect(m_addNewFileAction, SIGNAL(triggered()), this, SLOT(addNewFile()));
    connect(m_addExistingFilesAction, SIGNAL(triggered()), this, SLOT(addExistingFiles()));
    connect(m_openFileAction, SIGNAL(triggered()), this, SLOT(openFile()));
con's avatar
con committed
681
682
683
#ifdef Q_OS_MAC
    connect(m_showInFinder, SIGNAL(triggered()), this, SLOT(showInFinder()));
#endif
con's avatar
con committed
684
685
686
687
688
    connect(m_removeFileAction, SIGNAL(triggered()), this, SLOT(removeFile()));
    connect(m_renameFileAction, SIGNAL(triggered()), this, SLOT(renameFile()));

    updateActions();

689
690
    connect(Core::ICore::instance(), SIGNAL(coreAboutToOpen()),
            this, SLOT(determineSessionToRestoreAtStartup()));
691
    connect(Core::ICore::instance(), SIGNAL(coreOpened()), this, SLOT(restoreSession()));
con's avatar
con committed
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710

    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
711
    if (const Core::MimeType mt = Core::ICore::instance()->mimeDatabase()->findByFile(QFileInfo(filename)))
con's avatar
con committed
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
        if (ProjectFileFactory *pf = findFactory<ProjectFileFactory>(mt.type(), m_fileFactories.constBegin(), m_fileFactories.constEnd()))
            return pf;
    qWarning("Unable to find project file factory for '%s'", filename.toUtf8().constData());
    return 0;
}

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


    QString dir = m_lastOpenDirectory;

    // 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();
            const bool isProject = m_profileMimeTypes.contains(file->mimeType());
            dir = isProject ? fn : QFileInfo(fn).absolutePath();
        }
    }

    QString filename = QFileDialog::getOpenFileName(0, tr("Load Project"),
                                                    dir,
                                                    m_projectFilterString);
    if (filename.isEmpty())
        return;
    if (ProjectFileFactory *pf = findProjectFileFactory(filename))
        pf->open(filename);
    updateActions();
}

746
void ProjectExplorerPlugin::unloadProject()
con's avatar
con committed
747
748
{
    if (debug)
749
        qDebug() << "ProjectExplorerPlugin::unloadProject";
con's avatar
con committed
750

751
    Core::IFile *fi = m_currentProject->file();
con's avatar
con committed
752
753

    if (!fi || fi->fileName().isEmpty()) //nothing to save?
754
        return;
con's avatar
con committed
755
756
757

    QList<Core::IFile*> filesToSave;
    filesToSave << fi;
758
    // FIXME: What we want here is to check whether we need to safe any of the pro/pri files in this project
con's avatar
con committed
759
760
761
762
763
764
765
766
767
768

    // 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)
769
        success = Core::ICore::instance()->fileManager()->saveModifiedFiles(filesToSave).isEmpty();
con's avatar
con committed
770
    else
771
        success = Core::ICore::instance()->fileManager()->saveModifiedFilesSilently(filesToSave).isEmpty();
con's avatar
con committed
772

773
    if (!success)
con's avatar
con committed
774
775
        return;

776
    addToRecentProjects(fi->fileName(), m_currentProject->name());
con's avatar
con committed
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
    m_session->removeProject(m_currentProject);
    updateActions();
}

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

    if (!m_session->clear())
        return; // Action has been cancelled
    updateActions();
}

void ProjectExplorerPlugin::extensionsInitialized()
{
793
    m_fileFactories = ProjectFileFactory::createFactories(&m_projectFilterString);
hjk's avatar
hjk committed
794
    foreach (ProjectFileFactory *pf, m_fileFactories) {
con's avatar
con committed
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
        m_profileMimeTypes += pf->mimeTypes();
        addAutoReleasedObject(pf);
    }
}

void ProjectExplorerPlugin::shutdown()
{
    m_session->clear();
//    m_proWindow->saveConfigChanges();
}

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

    QString defaultLocation;
    if (currentProject()) {
        const QFileInfo file(currentProject()->file()->fileName());
        QDir dir = file.dir();
        dir.cdUp();
        defaultLocation = dir.absolutePath();
    }

819
    Core::ICore::instance()->showNewItemDialog(tr("New Project", "Title of dialog"),
820
                              Core::IWizard::wizardsOfKind(Core::IWizard::ProjectWizard),
con's avatar
con committed
821
822
823
824
                              defaultLocation);
    updateActions();
}

825
void ProjectExplorerPlugin::showSessionManager()
con's avatar
con committed
826
827
{
    if (debug)
828
        qDebug() << "ProjectExplorerPlugin::showSessionManager";
con's avatar
con committed
829
830
831
832
833
834
835
836
837
838

    if (m_session->isDefaultVirgin()) {
        // do not save new virgin default sessions
    } else {
        m_session->save();
    }
    SessionDialog sessionDialog(m_session, m_session->activeSession(), false);
    sessionDialog.exec();

    updateActions();
839
840
841
842
843
844
845

    Core::ModeManager *modeManager = Core::ModeManager::instance();
    Core::IMode *welcomeMode = modeManager->mode(Core::Constants::MODE_WELCOME);
    if (modeManager->currentMode() == welcomeMode)
    {
        updateWelcomePage(qobject_cast<Core::Internal::WelcomeMode*>(welcomeMode));
    }
con's avatar
con committed
846
847
848
849
850
851
852
853
854
}

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

    if (!project)
        project = m_currentProject;
dt's avatar
dt committed
855
856
    if (!project)
        return;
con's avatar
con committed
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
    m_session->setStartupProject(project);
    // NPE: Visually mark startup project
    updateActions();
}

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

    foreach (Project *pro, m_session->projects())
        pro->saveSettings();

    if (m_session->isDefaultVirgin()) {
        // do not save new virgin default sessions
    } else {
        m_session->save();
    }

876
    QSettings *s = Core::ICore::instance()->settings();
con's avatar
con committed
877
878
    if (s) {
        s->setValue("ProjectExplorer/StartupSession", m_session->file()->fileName());
879
880
881
882
883
884
885
886
887
888
889
890
891
        s->remove("ProjectExplorer/RecentProjects/Files");

        QStringList fileNames;
        QStringList displayNames;
        QList<QPair<QString, QString> >::const_iterator it, end;
        end = m_recentProjects.constEnd();
        for (it = m_recentProjects.constBegin(); it != end; ++it) {
            fileNames << (*it).first;
            displayNames << (*it).second;
        }

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

        s->setValue("ProjectExplorer/Settings/BuildBeforeRun", m_projectExplorerSettings.buildBeforeRun);
        s->setValue("ProjectExplorer/Settings/SaveBeforeBuild", m_projectExplorerSettings.saveBeforeBuild);
con's avatar
con committed
895
896
897
898
899
900
901
902
    }
}

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

903
904
905
    QList<Project *> list = openProjects(QStringList() << fileName);
    if (!list.isEmpty()) {
        addToRecentProjects(fileName, list.first()->name());
con's avatar
con committed
906
907
908
909
910
        return true;
    }
    return false;
}

911
QList<Project *> ProjectExplorerPlugin::openProjects(const QStringList &fileNames)
con's avatar
con committed
912
913
914
915
{
    if (debug)
        qDebug() << "ProjectExplorerPlugin - opening projects " << fileNames;

916
917
    ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
    QList<IProjectManager*> projectManagers = pm->getObjects<IProjectManager>();
con's avatar
con committed
918
919
920
921

    //QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
   // bool blocked = blockSignals(true);
    QList<Project*> openedPro;
922
923
    foreach (const QString &fileName, fileNames) {
        if (const Core::MimeType mt = Core::ICore::instance()->mimeDatabase()->findByFile(QFileInfo(fileName))) {
con's avatar
con committed
924
925
926
927
928
929
930
931
            foreach (IProjectManager *manager, projectManagers)
                if (manager->mimeType() == mt.type()) {
                    if (Project *pro = manager->openProject(fileName))
                        openedPro += pro;
                    m_session->reportProjectLoadingProgress();
                    break;
                }
        }
932
    }
con's avatar
con committed
933
934
935
936
937
938
    //blockSignals(blocked);

    if (openedPro.isEmpty()) {
        if (debug)
            qDebug() << "ProjectExplorerPlugin - Could not open any projects!";
        QApplication::restoreOverrideCursor();
939
        return QList<Project *>();
con's avatar
con committed
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
    }

    foreach (Project *pro, openedPro) {
        if (debug)
            qDebug()<<"restoring settings for "<<pro->file()->fileName();
        pro->restoreSettings();
        connect(pro, SIGNAL(fileListChanged()), this, SIGNAL(fileListChanged()));
    }
    m_session->addProjects(openedPro);

    // Make sure we always have a current project / node
    if (!m_currentProject)
        setCurrentNode(openedPro.first()->rootProjectNode());

    updateActions();

956
    Core::ModeManager::instance()->activateMode(Core::Constants::MODE_EDIT);
con's avatar
con committed
957
958
    QApplication::restoreOverrideCursor();

959
    return openedPro;
con's avatar
con committed
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
}

Project *ProjectExplorerPlugin::currentProject() const
{
    if (debug) {
        if (m_currentProject)
            qDebug() << "ProjectExplorerPlugin::currentProject returns " << m_currentProject->name();
        else
            qDebug() << "ProjectExplorerPlugin::currentProject returns 0";
    }
    return m_currentProject;
}

Node *ProjectExplorerPlugin::currentNode() const
{
    return m_currentNode;
}

void ProjectExplorerPlugin::setCurrentFile(Project *project, const QString &filePath)
{
    setCurrent(project, filePath, 0);
}

void ProjectExplorerPlugin::setCurrentFile(const QString &filePath)
{
    Project *project = m_session->projectForFile(filePath);
986
987
988
989
990
    // If the file is not in any project, stay with the current project
    // e.g. on opening a git diff buffer, git log buffer, we don't change the project
    // I'm not 100% sure this is correct
    if (!project)
        project = m_currentProject;
con's avatar
con committed
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
    setCurrent(project, filePath, 0);
}

void ProjectExplorerPlugin::setCurrentNode(Node *node)
{
    setCurrent(m_session->projectForNode(node), QString(), node);
}

SessionManager *ProjectExplorerPlugin::session() const
{
    return m_session;
}

Project *ProjectExplorerPlugin::startupProject() const
{
    if (debug)
        qDebug() << "ProjectExplorerPlugin::startupProject";

    Project *pro = m_session->startupProject();

    if (!pro)
        pro = m_currentProject;

    return pro;
}

// update welcome page
void ProjectExplorerPlugin::updateWelcomePage(Core::Internal::WelcomeMode *welcomeMode)
{
    Core::Internal::WelcomeMode::WelcomePageData welcomePageData;
    welcomePageData.sessionList =  m_session->sessions();
    welcomePageData.activeSession = m_session->activeSession();
    welcomePageData.previousSession = m_session->lastSession();
    welcomePageData.projectList = m_recentProjects;
    welcomeMode->updateWelcomePage(welcomePageData);
}

void ProjectExplorerPlugin::currentModeChanged(Core::IMode *mode)
{
    if (Core::Internal::WelcomeMode *welcomeMode = qobject_cast<Core::Internal::WelcomeMode*>(mode))
        updateWelcomePage(welcomeMode);
}

1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
void ProjectExplorerPlugin::determineSessionToRestoreAtStartup()
{
    QStringList sessions = m_session->sessions();
    // We have command line arguments, try to find a session in them
    QStringList arguments = ExtensionSystem::PluginManager::instance()->arguments();
    // Default to no session loading
    m_sessionToRestoreAtStartup = QString::null;
    foreach (const QString &arg, arguments) {
        if (sessions.contains(arg)) {
            // Session argument
            m_sessionToRestoreAtStartup = arg;
            break;
        }
    }
    if (!m_sessionToRestoreAtStartup.isNull())
        Core::ICore::instance()->modeManager()->activateMode(Core::Constants::MODE_EDIT);
}

con's avatar
con committed
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
/*!
    \fn void ProjectExplorerPlugin::restoreSession()

    This method is connected to the ICore::coreOpened signal.  If
    there was no session explicitly loaded, it creates an empty new
    default session and puts the list of recent projects and sessions
    onto the welcome page.
*/
void ProjectExplorerPlugin::restoreSession()
{
    if (debug)
        qDebug() << "ProjectExplorerPlugin::restoreSession";

    // We have command line arguments, try to find a session in them
    QStringList arguments = ExtensionSystem::PluginManager::instance()->arguments();
1067
    arguments.removeOne(m_sessionToRestoreAtStartup);
con's avatar
con committed
1068
1069

    // Restore latest session or what was passed on the command line
1070
    if (m_sessionToRestoreAtStartup == QString::null) {
con's avatar
con committed
1071
1072
        m_session->createAndLoadNewDefaultSession();
    } else {
1073
        m_session->loadSession(m_sessionToRestoreAtStartup);
con's avatar
con committed
1074
1075
1076
    }

    // update welcome page
1077
    Core::ModeManager *modeManager = Core::ModeManager::instance();
con's avatar
con committed
1078
1079
1080
1081
1082
1083
1084
    connect(modeManager, SIGNAL(currentModeChanged(Core::IMode*)), this, SLOT(currentModeChanged(Core::IMode*)));
    if (Core::Internal::WelcomeMode *welcomeMode = qobject_cast<Core::Internal::WelcomeMode*>(modeManager->mode(Core::Constants::MODE_WELCOME))) {
        updateWelcomePage(welcomeMode);
        connect(welcomeMode, SIGNAL(requestSession(QString)), this, SLOT(loadSession(QString)));
        connect(welcomeMode, SIGNAL(requestProject(QString)), this, SLOT(loadProject(QString)));
    }

1085
    Core::ICore::instance()->openFiles(arguments);
con's avatar
con committed
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
    updateActions();

}

void ProjectExplorerPlugin::loadSession(const QString &session)
{
    if (debug)
        qDebug() << "ProjectExplorerPlugin::loadSession" << session;
    m_session->loadSession(session);
}


void ProjectExplorerPlugin::showContextMenu(const QPoint &globalPos, Node *node)
{
    QMenu *contextMenu = 0;

    if (!node)
        node = m_session->sessionNode();

    if (node->nodeType() != SessionNodeType) {
        Project *project = m_session->projectForNode(node);
        setCurrentNode(node);

        emit aboutToShowContextMenu(project, node);
        switch (node->nodeType()) {
        case ProjectNodeType:
            if (node->parentFolderNode() == m_session->sessionNode())
                contextMenu = m_projectMenu;
            else
                contextMenu = m_subProjectMenu;
            break;
        case FolderNodeType:
            contextMenu = m_folderMenu;
            break;
        case FileNodeType:
            contextMenu = m_fileMenu;
            break;
        default:
            qWarning("ProjectExplorerPlugin::showContextMenu - Missing handler for node type");
        }
    } else { // session item
        emit aboutToShowContextMenu(0, node);

        contextMenu = m_sessionContextMenu;
    }

1132
    updateContextMenuActions();
con's avatar
con committed
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
    if (contextMenu && contextMenu->actions().count() > 0) {
        contextMenu->popup(globalPos);
    }
}

BuildManager *ProjectExplorerPlugin::buildManager() const
{
    return m_buildManager;
}

void ProjectExplorerPlugin::buildStateChanged(Project * pro)
{
    if (debug) {
        qDebug() << "buildStateChanged";
        qDebug() << pro->file()->fileName() << "isBuilding()" << m_buildManager->isBuilding(pro);
    }
    Q_UNUSED(pro);
    updateActions();
}

1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
void ProjectExplorerPlugin::executeRunConfiguration(QSharedPointer<RunConfiguration> runConfiguration, const QString &runMode)
{
    IRunConfigurationRunner *runner = findRunner(runConfiguration, runMode);
    if (runner) {
        emit aboutToExecuteProject(runConfiguration->project());

        RunControl *control = runner->run(runConfiguration, runMode);
        m_outputPane->createNewOutputWindow(control);
        if (runMode == ProjectExplorer::Constants::RUNMODE)
            m_outputPane->popup(false);
        m_outputPane->showTabFor(control);

        connect(control, SIGNAL(addToOutputWindow(RunControl *, const QString &)),
                this, SLOT(addToApplicationOutputWindow(RunControl *, const QString &)));
        connect(control, SIGNAL(addToOutputWindowInline(RunControl *, const QString &)),
                this, SLOT(addToApplicationOutputWindowInline(RunControl *, const QString &)));
        connect(control, SIGNAL(error(RunControl *, const QString &)),
                this, SLOT(addErrorToApplicationOutputWindow(RunControl *, const QString &)));
        connect(control, SIGNAL(finished()),
                this, SLOT(runControlFinished()));

        if (runMode == ProjectExplorer::Constants::DEBUGMODE)
            m_debuggingRunControl = control;

        control->start();
        updateRunAction();
    }

}

con's avatar
con committed
1183
1184
1185
1186
1187
1188
1189
1190
void ProjectExplorerPlugin::buildQueueFinished(bool success)
{
    if (debug)
        qDebug() << "buildQueueFinished()" << success;

    updateActions();

    if (success && m_delayedRunConfiguration) {
1191
        executeRunConfiguration(m_delayedRunConfiguration, m_runMode);
con's avatar
con committed
1192
1193
1194
1195
    } else {
        if (m_buildManager->tasksAvailable())
            m_buildManager->showTaskWindow();
    }
1196
1197
    m_delayedRunConfiguration = QSharedPointer<RunConfiguration>(0);
    m_runMode = QString::null;
con's avatar
con committed
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
}

void ProjectExplorerPlugin::setCurrent(Project *project, QString filePath, Node *node)
{
    if (debug)
        qDebug() << "ProjectExplorer - setting path to " << (node ? node->path() : filePath)
                << " and project to " << (project ? project->name() : "0");

    if (node)
        filePath = node->path();
    else
dt's avatar
dt committed
1209
        node = m_session->nodeForFile(filePath, project);
con's avatar
con committed
1210

1211
1212
    Core::ICore *core = Core::ICore::instance();

con's avatar
con committed
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
    bool projectChanged = false;
    if (m_currentProject != project) {
        int oldContext = -1;
        int newContext = -1;
        int oldLanguageID = -1;
        int newLanguageID = -1;
        if (m_currentProject) {
            oldContext = m_currentProject->projectManager()->projectContext();
            oldLanguageID = m_currentProject->projectManager()->projectLanguage();
        }
        if (project) {
            newContext = project->projectManager()->projectContext();
            newLanguageID = project->projectManager()->projectLanguage();
        }
1227
1228
1229
1230
1231
        core->removeAdditionalContext(oldContext);
        core->removeAdditionalContext(oldLanguageID);
        core->addAdditionalContext(newContext);
        core->addAdditionalContext(newLanguageID);
        core->updateContext();
con's avatar
con committed
1232
1233
1234
1235
1236
1237
1238
1239
1240

        m_currentProject = project;

        projectChanged = true;
    }

    if (projectChanged || m_currentNode != node) {
        m_currentNode = node;
        if (debug)
1241
            qDebug() << "ProjectExplorer - currentNodeChanged(" << (node ? node->path() : "0") << ", " << (project ? project->name() : "0") << ")";
con's avatar
con committed
1242
1243
1244
1245
1246
        emit currentNodeChanged(m_currentNode, project);
    }
    if (projectChanged) {
        if (debug)
            qDebug() << "ProjectExplorer - currentProjectChanged(" << (project ? project->name() : "0") << ")";
1247
1248
        // Enable the right VCS
        if (const Core::IFile *projectFile = project ? project->file() : static_cast<const Core::IFile *>(0)) {
1249
            core->vcsManager()->setVCSEnabled(QFileInfo(projectFile->fileName()).absolutePath());
1250
        } else {
1251
            core->vcsManager()->setAllVCSEnabled();
1252
1253
        }

con's avatar
con committed
1254
1255
1256
1257
        emit currentProjectChanged(project);
        updateActions();
    }

1258
    core->fileManager()->setCurrentFile(filePath);
con's avatar
con committed
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
}

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

    bool enableBuildActions = m_currentProject && ! (m_buildManager->isBuilding(m_currentProject));
    bool hasProjects = !m_session->projects().isEmpty();
    bool building = m_buildManager->isBuilding();
1269
    QString projectName = m_currentProject ? m_currentProject->name() : QString();
con's avatar
con committed
1270
1271

    if (debug)
1272
        qDebug() << "BuildManager::isBuilding()" << building;
con's avatar
con committed
1273

1274
    m_unloadAction->setParameter(projectName);
con's avatar
con committed
1275

1276
1277
1278
    m_buildAction->setParameter(projectName);
    m_rebuildAction->setParameter(projectName);
    m_cleanAction->setParameter(projectName);
1279

1280
1281
1282
    m_buildProjectOnlyAction->setEnabled(enableBuildActions);
    m_rebuildProjectOnlyAction->setEnabled(enableBuildActions);
    m_cleanProjectOnlyAction->setEnabled(enableBuildActions);
1283

con's avatar
con committed
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
    m_clearSession->setEnabled(hasProjects && !building);
    m_buildSessionAction->setEnabled(hasProjects && !building);
    m_rebuildSessionAction->setEnabled(hasProjects && !building);
    m_cleanSessionAction->setEnabled(hasProjects && !building);
    m_cancelBuildAction->setEnabled(building);

    updateRunAction();
}

// NBS TODO check projectOrder()
// what we want here is all the projects pro depends on
QStringList ProjectExplorerPlugin::allFilesWithDependencies(Project *pro)
{
    if (debug)
        qDebug() << "ProjectExplorerPlugin::allFilesWithDependencies(" << pro->file()->fileName() << ")";

    QStringList filesToSave;
hjk's avatar
hjk committed
1301
    foreach (Project *p, m_session->projectOrder(pro)) {
con's avatar
con committed
1302
1303
1304
1305
1306
1307
1308
1309
        FindAllFilesVisitor filesVisitor;
        p->rootProjectNode()->accept(&filesVisitor);
        filesToSave << filesVisitor.filePaths();
    }
    qSort(filesToSave);
    return filesToSave;
}

1310
bool ProjectExplorerPlugin::saveModifiedFiles()
con's avatar
con committed
1311
1312
1313
1314
{
    if (debug)
        qDebug() << "ProjectExplorerPlugin::saveModifiedFiles";

1315
    QList<Core::IFile *> filesToSave = Core::ICore::instance()->fileManager()->modifiedFiles();
con's avatar
con committed
1316
    if (!filesToSave.isEmpty()) {
1317
1318
1319
1320
        if (m_projectExplorerSettings.saveBeforeBuild) {
            Core::ICore::instance()->fileManager()->saveModifiedFilesSilently(filesToSave);
        } else {
            bool cancelled = false;
1321
            bool alwaysSave = false;
1322
1323
1324
1325
1326
1327

            Core::FileManager *fm = Core::ICore::instance()->fileManager();
            fm->saveModifiedFiles(filesToSave, &cancelled, QString::null,
                                  "Always save files before build", &alwaysSave);

            if (cancelled)
1328
                return false;
1329
            if (alwaysSave)
1330
                m_projectExplorerSettings.saveBeforeBuild = true;
con's avatar
con committed
1331
1332
1333
1334
1335
1336
1337
1338
        }
    }
    return true;
}

//NBS handle case where there is no activeBuildConfiguration
// because someone delete all build configurations

1339
void ProjectExplorerPlugin::buildProjectOnly()
con's avatar
con committed
1340
1341
{
    if (debug)
1342
        qDebug() << "ProjectExplorerPlugin::buildProjectOnly";
con's avatar
con committed
1343

1344
    if (saveModifiedFiles())
con's avatar
con committed
1345
1346
1347
        buildManager()->buildProject(m_currentProject, m_currentProject->activeBuildConfiguration());
}

1348
1349
1350
1351
1352
1353
1354
1355
static QStringList configurations(const QList<Project *> &projects)
{
    QStringList result;
    foreach (const Project * pro, projects)
        result << pro->activeBuildConfiguration();
    return result;
}

1356
1357
1358
1359
1360
void ProjectExplorerPlugin::buildProject()
{
    if (debug)
        qDebug() << "ProjectExplorerPlugin::buildProject";

1361
1362
    if (saveModifiedFiles()) {
        const QList<Project *> & projects = m_session->projectOrder(m_currentProject);
1363
        m_buildManager->buildProjects(projects, configurations(projects));
1364
1365
1366
    }
}

con's avatar
con committed
1367
1368
1369
1370
1371
void ProjectExplorerPlugin::buildSession()
{
    if (debug)
        qDebug() << "ProjectExplorerPlugin::buildSession";

1372
1373
    if (saveModifie