projectexplorer.cpp 69.8 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
8
**
** Contact:  Qt Software Information (qt-info@nokia.com)
**
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
26
** If you are unsure which license is appropriate for your use, please
** contact the sales department at qt-sales@nokia.com.
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 "qtversionmanager.h"
60
#include "qtoptionspage.h"
con's avatar
con committed
61
62
63

#include <coreplugin/basemode.h>
#include <coreplugin/coreconstants.h>
64
65
#include <coreplugin/filemanager.h>
#include <coreplugin/icore.h>
con's avatar
con committed
66
67
68
69
#include <coreplugin/mainwindow.h>
#include <coreplugin/mimedatabase.h>
#include <coreplugin/modemanager.h>
#include <coreplugin/uniqueidmanager.h>
70
#include <coreplugin/actionmanager/actionmanager.h>
con's avatar
con committed
71
72
73
74
75
76
77
78
79
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/editormanager/ieditor.h>
#include <coreplugin/editormanager/ieditorfactory.h>
#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 <extensionsystem/pluginmanager.h>
hjk's avatar
hjk committed
82
#include <utils/qtcassert.h>
con's avatar
con committed
83

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

con's avatar
con committed
89
90
#include <QtGui/QAction>
#include <QtGui/QApplication>
hjk's avatar
hjk committed
91
92
93
#include <QtGui/QFileDialog>
#include <QtGui/QMenu>
#include <QtGui/QMessageBox>
con's avatar
con committed
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116

Q_DECLARE_METATYPE(QSharedPointer<ProjectExplorer::RunConfiguration>);
Q_DECLARE_METATYPE(Core::IEditorFactory *);

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);
117
        box.setWindowTitle(tr("Close Qt Creator?"));
con's avatar
con committed
118
        box.setText(tr("A project is currently being built."));
119
        box.setInformativeText(tr("Do you want to cancel the build process and close Qt Creator anyway?"));
con's avatar
con committed
120
121
122
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
        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;
}

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

154
155
    Core::ICore *core = Core::ICore::instance();
    Core::ActionManager *am = core->actionManager();
con's avatar
con committed
156
157
158

    addObject(this);

hjk's avatar
hjk committed
159
160
    connect(core->fileManager(), SIGNAL(currentFileChanged(QString)),
            this, SLOT(setCurrentFile(QString)));
con's avatar
con committed
161

hjk's avatar
hjk committed
162
    m_session = new SessionManager(this);
con's avatar
con committed
163
164
165
166
167
168
169
170
171
172

    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()));

173
    m_proWindow = new ProjectWindow;
con's avatar
con committed
174
175
176
177
178

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

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

hjk's avatar
hjk committed
181
182
183
184
185
186
    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
187
188
189
190
191
192
193
194
195
196
197
198
    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)));
    connect(m_buildManager, SIGNAL(tasksChanged()),
            this, SLOT(updateTaskActions()));

199
200
201
    m_versionManager = new QtVersionManager();
    addAutoReleasedObject(m_versionManager);

202
203
    addAutoReleasedObject(new QtOptionsPage());

con's avatar
con committed
204
205
    addAutoReleasedObject(new CoreListenerCheckingForRunningBuild(m_buildManager));

hjk's avatar
hjk committed
206
    m_outputPane = new OutputPane;
con's avatar
con committed
207
208
209
210
    addAutoReleasedObject(m_outputPane);
    connect(m_session, SIGNAL(projectRemoved(ProjectExplorer::Project *)),
            m_outputPane, SLOT(projectRemoved()));

211
    AllProjectsFilter *allProjectsFilter = new AllProjectsFilter(this);
con's avatar
con committed
212
213
    addAutoReleasedObject(allProjectsFilter);

214
    CurrentProjectFilter *currentProjectFilter = new CurrentProjectFilter(this);
con's avatar
con committed
215
216
217
218
219
    addAutoReleasedObject(currentProjectFilter);

    addAutoReleasedObject(new BuildSettingsPanelFactory);
    addAutoReleasedObject(new RunSettingsPanelFactory);
    addAutoReleasedObject(new EditorSettingsPanelFactory);
220
    addAutoReleasedObject(new DependenciesPanelFactory(m_session));
con's avatar
con committed
221
222
223
224

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

225
226
227
    ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
    AllProjectsFind *allProjectsFind = new AllProjectsFind(this,
        pm->getObject<Find::SearchResultWindow>());
con's avatar
con committed
228
229
    addAutoReleasedObject(allProjectsFind);

230
231
    CurrentProjectFind *currentProjectFind = new CurrentProjectFind(this,
        pm->getObject<Find::SearchResultWindow>());
con's avatar
con committed
232
233
234
235
236
    addAutoReleasedObject(currentProjectFind);

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

237
    addAutoReleasedObject(new ProjectFileWizardExtension);
con's avatar
con committed
238

239
240
241
242
    // Build parsers
    addAutoReleasedObject(new GccParserFactory);
    addAutoReleasedObject(new MsvcParserFactory);

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

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

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

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

    // debug menu
276
    Core::ActionContainer *mdebug =
con's avatar
con committed
277
        am->createMenu(Constants::M_DEBUG);
278
    mdebug->menu()->setTitle(tr("&Debug"));
con's avatar
con committed
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
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
    menubar->addMenu(mdebug, Core::Constants::G_VIEW);


    //
    // Groups
    //

    mbuild->appendGroup(Constants::G_BUILD_SESSION);
    mbuild->appendGroup(Constants::G_BUILD_PROJECT);
    mbuild->appendGroup(Constants::G_BUILD_OTHER);
    mbuild->appendGroup(Constants::G_BUILD_RUN);
    mbuild->appendGroup(Constants::G_BUILD_TASK);
    mbuild->appendGroup(Constants::G_BUILD_CANCEL);

    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
320
    Core::ActionContainer * const openWith =
con's avatar
con committed
321
322
323
324
325
326
327
328
329
330
331
332
            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
333
    Core::Command *cmd;
con's avatar
con committed
334
335
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
421
422
423
    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.Task.Sep"), globalcontext);
    mbuild->addAction(cmd, Constants::G_BUILD_TASK);

    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
424
425
426
427
428
429
430
431
#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
432
433
434
    // Open With menu
    mfilec->addMenu(openWith, ProjectExplorer::Constants::G_FILE_OPEN);

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

con's avatar
con committed
443
444
445
    // unload action
    m_unloadAction = new QAction(tr("Unload Project"), this);
    cmd = am->registerAction(m_unloadAction, Constants::UNLOAD, globalcontext);
con's avatar
con committed
446
    cmd->setAttribute(Core::Command::CA_UpdateText);
con's avatar
con committed
447
448
449
450
451
452
453
454
455
456
457
    cmd->setDefaultText(m_unloadAction->text());
    mfile->addAction(cmd, Core::Constants::G_FILE_PROJECT);
    mproject->addAction(cmd, Constants::G_PROJECT_FILES);

    // unload session action
    m_clearSession = new QAction(tr("Unload All Projects"), this);
    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
458
    Core::ActionContainer *msession = am->createMenu(Constants::M_SESSION);
459
    msession->menu()->setTitle(tr("Session"));
con's avatar
con committed
460
461
462
463
464
465
    mfile->addMenu(msession, Core::Constants::G_FILE_PROJECT);
    m_sessionMenu = msession->menu();
    connect(mfile->menu(), SIGNAL(aboutToShow()),
            this, SLOT(updateSessionMenu()));

    // build menu
466
    Core::ActionContainer *mbc =
con's avatar
con committed
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
502
503
504
505
506
        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
    m_buildAction = new QAction(tr("Build Project"), this);
    cmd = am->registerAction(m_buildAction, Constants::BUILD, globalcontext);
507
    cmd->setAttribute(Core::Command::CA_UpdateText);
con's avatar
con committed
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
    cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+B")));
    mbuild->addAction(cmd, Constants::G_BUILD_PROJECT);
    mproject->addAction(cmd, Constants::G_PROJECT_BUILD);

    // rebuild action
    m_rebuildAction = new QAction(tr("Rebuild Project"), this);
    cmd = am->registerAction(m_rebuildAction, Constants::REBUILD, globalcontext);
    mbuild->addAction(cmd, Constants::G_BUILD_PROJECT);
    mproject->addAction(cmd, Constants::G_PROJECT_BUILD);

    // clean action
    m_cleanAction = new QAction(tr("Clean Project"), this);
    cmd = am->registerAction(m_cleanAction, Constants::CLEAN, globalcontext);
    mbuild->addAction(cmd, Constants::G_BUILD_PROJECT);
    mproject->addAction(cmd, Constants::G_PROJECT_BUILD);

    // Add Set Build Configuration to menu
    mbuild->addMenu(mbc, Constants::G_BUILD_PROJECT);
    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);
536

537
    Core::ActionContainer *mrc = am->createMenu(Constants::RUNCONFIGURATIONMENU);
con's avatar
con committed
538
539
540
541
542
543
544
545
546
547
548
549
    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);

550
551
552
553
    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
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
    // jump to next task
    m_taskAction = new QAction(tr("Go to Task Window"), this);
    m_taskAction->setIcon(QIcon(Core::Constants::ICON_NEXT));
    cmd = am->registerAction(m_taskAction, Constants::GOTOTASKWINDOW, globalcontext);
    // FIXME: Eike, look here! cmd->setDefaultKeySequence(QKeySequence(tr("F9")));
    mbuild->addAction(cmd, Constants::G_BUILD_TASK);

    // 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");
    debuggerIcon.addFile(":/gdbdebugger/images/debugger_start.png");
    m_debugAction = new QAction(debuggerIcon, tr("Start Debugging"), this);
    cmd = am->registerAction(m_debugAction, Constants::DEBUG, globalcontext);
con's avatar
con committed
571
572
    cmd->setAttribute(Core::Command::CA_UpdateText);
    cmd->setAttribute(Core::Command::CA_UpdateIcon);
con's avatar
con committed
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
    cmd->setDefaultText(tr("Start Debugging"));
    cmd->setDefaultKeySequence(QKeySequence(tr("F5")));
    mdebug->addAction(cmd, Core::Constants::G_DEFAULT_ONE);
    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);

606
    connect(core, SIGNAL(saveSettingsRequested()),
con's avatar
con committed
607
608
        this, SLOT(savePersistentSettings()));

hjk's avatar
hjk committed
609
610
    addAutoReleasedObject(new ProjectTreeWidgetFactory);
    addAutoReleasedObject(new FolderNavigationWidgetFactory);
con's avatar
con committed
611

612
    // > -- Creator 1.0 compatibility code
613
    QStringList oldRecentProjects;
614
    if (QSettings *s = core->settings())
615
616
        oldRecentProjects = s->value("ProjectExplorer/RecentProjects/Files", QStringList()).toStringList();
    for (QStringList::iterator it = oldRecentProjects.begin(); it != oldRecentProjects.end(); ) {
con's avatar
con committed
617
618
619
        if (QFileInfo(*it).isFile()) {
            ++it;
        } else {
620
            it = oldRecentProjects.erase(it);
con's avatar
con committed
621
622
623
        }
    }

624
625
626
    foreach(const QString &s, oldRecentProjects) {
        m_recentProjects.append(qMakePair(s, QFileInfo(s).fileName()));
    }
627
    // < -- Creator 1.0 compatibility code
628
629
630
631
632
633
634

    // TODO restore recentProjects
    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) {
635
636
                if (QFileInfo(fileNames.at(i)).isFile())
                    m_recentProjects.append(qMakePair(fileNames.at(i), displayNames.at(i)));
637
638
639
640
641
642
            }
        }
    }



643
    connect(m_sessionManagerAction, SIGNAL(triggered()), this, SLOT(showSessionManager()));
con's avatar
con committed
644
645
646
647
648
649
650
651
652
653
654
    connect(m_newAction, SIGNAL(triggered()), this, SLOT(newProject()));
#if 0
    connect(m_loadAction, SIGNAL(triggered()), this, SLOT(loadAction()));
#endif
    connect(m_buildAction, SIGNAL(triggered()), this, SLOT(buildProject()));
    connect(m_buildSessionAction, SIGNAL(triggered()), this, SLOT(buildSession()));
    connect(m_rebuildAction, SIGNAL(triggered()), this, SLOT(rebuildProject()));
    connect(m_rebuildSessionAction, SIGNAL(triggered()), this, SLOT(rebuildSession()));
    connect(m_cleanAction, SIGNAL(triggered()), this, SLOT(cleanProject()));
    connect(m_cleanSessionAction, SIGNAL(triggered()), this, SLOT(cleanSession()));
    connect(m_runAction, SIGNAL(triggered()), this, SLOT(runProject()));
655
    connect(m_runActionContextMenu, SIGNAL(triggered()), this, SLOT(runProjectContextMenu()));
con's avatar
con committed
656
657
658
659
660
661
662
663
    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_taskAction, SIGNAL(triggered()), this, SLOT(goToTaskWindow()));
    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
664
665
666
#ifdef Q_OS_MAC
    connect(m_showInFinder, SIGNAL(triggered()), this, SLOT(showInFinder()));
#endif
con's avatar
con committed
667
668
669
670
671
    connect(m_removeFileAction, SIGNAL(triggered()), this, SLOT(removeFile()));
    connect(m_renameFileAction, SIGNAL(triggered()), this, SLOT(renameFile()));

    updateActions();

672
    connect(Core::ICore::instance(), SIGNAL(coreOpened()), this, SLOT(restoreSession()));
con's avatar
con committed
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691

    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
692
    if (const Core::MimeType mt = Core::ICore::instance()->mimeDatabase()->findByFile(QFileInfo(filename)))
con's avatar
con committed
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
        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();
}

727
void ProjectExplorerPlugin::unloadProject()
con's avatar
con committed
728
729
{
    if (debug)
730
        qDebug() << "ProjectExplorerPlugin::unloadProject";
con's avatar
con committed
731

732
    Core::IFile *fi = m_currentProject->file();
con's avatar
con committed
733
734

    if (!fi || fi->fileName().isEmpty()) //nothing to save?
735
        return;
con's avatar
con committed
736
737
738

    QList<Core::IFile*> filesToSave;
    filesToSave << fi;
739
    // 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
740
741
742
743
744
745
746
747
748
749

    // 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)
750
        success = Core::ICore::instance()->fileManager()->saveModifiedFiles(filesToSave).isEmpty();
con's avatar
con committed
751
    else
752
        success = Core::ICore::instance()->fileManager()->saveModifiedFilesSilently(filesToSave).isEmpty();
con's avatar
con committed
753

754
    if (!success)
con's avatar
con committed
755
756
        return;

757
    addToRecentProjects(fi->fileName(), m_currentProject->name());
con's avatar
con committed
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
    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()
{
774
    m_fileFactories = ProjectFileFactory::createFactories(&m_projectFilterString);
hjk's avatar
hjk committed
775
    foreach (ProjectFileFactory *pf, m_fileFactories) {
con's avatar
con committed
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
        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();
    }

800
    Core::ICore::instance()->showNewItemDialog(tr("New Project", "Title of dialog"),
con's avatar
con committed
801
802
803
804
805
                              Core::BaseFileWizard::findWizardsOfKind(Core::IWizard::ProjectWizard),
                              defaultLocation);
    updateActions();
}

806
void ProjectExplorerPlugin::showSessionManager()
con's avatar
con committed
807
808
{
    if (debug)
809
        qDebug() << "ProjectExplorerPlugin::showSessionManager";
con's avatar
con committed
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828

    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();
}

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

    if (!project)
        project = m_currentProject;
dt's avatar
dt committed
829
830
    if (!project)
        return;
con's avatar
con committed
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
    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();
    }

850
    QSettings *s = Core::ICore::instance()->settings();
con's avatar
con committed
851
852
    if (s) {
        s->setValue("ProjectExplorer/StartupSession", m_session->file()->fileName());
853
854
855
856
857
858
859
860
861
862
863
864
865
        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);
con's avatar
con committed
866
867
868
869
870
871
872
873
    }
}

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

874
875
876
    QList<Project *> list = openProjects(QStringList() << fileName);
    if (!list.isEmpty()) {
        addToRecentProjects(fileName, list.first()->name());
con's avatar
con committed
877
878
879
880
881
        return true;
    }
    return false;
}

882
QList<Project *> ProjectExplorerPlugin::openProjects(const QStringList &fileNames)
con's avatar
con committed
883
884
885
886
{
    if (debug)
        qDebug() << "ProjectExplorerPlugin - opening projects " << fileNames;

887
888
    ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
    QList<IProjectManager*> projectManagers = pm->getObjects<IProjectManager>();
con's avatar
con committed
889
890
891
892

    //QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
   // bool blocked = blockSignals(true);
    QList<Project*> openedPro;
893
894
    foreach (const QString &fileName, fileNames) {
        if (const Core::MimeType mt = Core::ICore::instance()->mimeDatabase()->findByFile(QFileInfo(fileName))) {
con's avatar
con committed
895
896
897
898
899
900
901
902
            foreach (IProjectManager *manager, projectManagers)
                if (manager->mimeType() == mt.type()) {
                    if (Project *pro = manager->openProject(fileName))
                        openedPro += pro;
                    m_session->reportProjectLoadingProgress();
                    break;
                }
        }
903
    }
con's avatar
con committed
904
905
906
907
908
909
    //blockSignals(blocked);

    if (openedPro.isEmpty()) {
        if (debug)
            qDebug() << "ProjectExplorerPlugin - Could not open any projects!";
        QApplication::restoreOverrideCursor();
910
        return QList<Project *>();
con's avatar
con committed
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
    }

    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();

927
    Core::ModeManager::instance()->activateMode(Core::Constants::MODE_EDIT);
con's avatar
con committed
928
929
    QApplication::restoreOverrideCursor();

930
    return openedPro;
con's avatar
con committed
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
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
986
987
988
989
990
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
1034
1035
1036
1037
1038
1039
1040
1041
1042
}

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);
    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);
}

/*!
    \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";

    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
    QString sessionToLoad = QString::null;
    if (!arguments.isEmpty()) {
        foreach (const QString &arg, arguments) {
            if (sessions.contains(arg)) {
                // Session argument
                sessionToLoad = arg;
                arguments.removeOne(arg);
                if (debug)
                    qDebug()<< "Found session argument, loading session"<<sessionToLoad;
                break;
            }
        }
    }

    // Restore latest session or what was passed on the command line
    if (sessionToLoad == QString::null) {
        m_session->createAndLoadNewDefaultSession();
    } else {
        m_session->loadSession(sessionToLoad);
    }

    // update welcome page
1043
    Core::ModeManager *modeManager = Core::ModeManager::instance();
con's avatar
con committed
1044
1045
1046
1047
1048
1049
1050
    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)));
    }

1051
    Core::ICore::instance()->openFiles(arguments);
con's avatar
con committed
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
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
1132
1133
    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;

    updateContextMenuActions();

    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;
    }

    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();
}

void ProjectExplorerPlugin::buildQueueFinished(bool success)
{
    if (debug)
        qDebug() << "buildQueueFinished()" << success;

    updateActions();

    if (success && m_delayedRunConfiguration) {
        IRunConfigurationRunner *runner = findRunner(m_delayedRunConfiguration, m_runMode);
        if (runner) {
            emit aboutToExecuteProject(m_delayedRunConfiguration->project());

            RunControl *control = runner->run(m_delayedRunConfiguration, m_runMode);
            m_outputPane->createNewOutputWindow(control);
1134
1135
            if (m_runMode == ProjectExplorer::Constants::RUNMODE)
                m_outputPane->popup(false);
con's avatar
con committed
1136
1137
1138
1139
            m_outputPane->showTabFor(control);

            connect(control, SIGNAL(addToOutputWindow(RunControl *, const QString &)),
                    this, SLOT(addToApplicationOutputWindow(RunControl *, const QString &)));
Oswald Buddenhagen's avatar
Oswald Buddenhagen committed
1140
1141
            connect(control, SIGNAL(addToOutputWindowInline(RunControl *, const QString &)),
                    this, SLOT(addToApplicationOutputWindowInline(RunControl *, const QString &)));
con's avatar
con committed
1142
1143
1144
1145
1146
1147
1148
1149
            connect(control, SIGNAL(error(RunControl *, const QString &)),
                    this, SLOT(addErrorToApplicationOutputWindow(RunControl *, const QString &)));
            connect(control, SIGNAL(finished()),
                    this, SLOT(runControlFinished()));

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

dt's avatar
dt committed
1150
            control->start();
con's avatar
con committed
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
            updateRunAction();
        }
    } else {
        if (m_buildManager->tasksAvailable())
            m_buildManager->showTaskWindow();
    }

    m_delayedRunConfiguration = QSharedPointer<RunConfiguration>(0);
    m_runMode = QString::null;
}

void ProjectExplorerPlugin::updateTaskActions()
{
    m_taskAction->setEnabled(m_buildManager->tasksAvailable());
}

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
1176
        node = m_session->nodeForFile(filePath, project);
con's avatar
con committed
1177

1178
1179
    Core::ICore *core = Core::ICore::instance();

con's avatar
con committed
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
    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();
        }
1194
1195
1196
1197
1198
        core->removeAdditionalContext(oldContext);
        core->removeAdditionalContext(oldLanguageID);
        core->addAdditionalContext(newContext);
        core->addAdditionalContext(newLanguageID);
        core->updateContext();
con's avatar
con committed
1199
1200
1201
1202
1203
1204
1205
1206
1207

        m_currentProject = project;

        projectChanged = true;
    }

    if (projectChanged || m_currentNode != node) {
        m_currentNode = node;
        if (debug)
1208
            qDebug() << "ProjectExplorer - currentNodeChanged(" << (node ? node->path() : "0") << ", " << (project ? project->name() : "0") << ")";
con's avatar
con committed
1209
1210
1211
1212
1213
        emit currentNodeChanged(m_currentNode, project);
    }
    if (projectChanged) {
        if (debug)
            qDebug() << "ProjectExplorer - currentProjectChanged(" << (project ? project->name() : "0") << ")";
1214
1215
        // Enable the right VCS
        if (const Core::IFile *projectFile = project ? project->file() : static_cast<const Core::IFile *>(0)) {
1216
            core->vcsManager()->setVCSEnabled(QFileInfo(projectFile->fileName()).absolutePath());
1217
        } else {
1218
            core->vcsManager()->setAllVCSEnabled();
1219
1220
        }

con's avatar
con committed
1221
1222
1223
1224
        emit currentProjectChanged(project);
        updateActions();
    }

1225
    core->fileManager()->setCurrentFile(filePath);
con's avatar
con committed
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
}

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();

    if (debug)
        qDebug()<<"BuildManager::isBuilding()"<<building;

    m_unloadAction->setEnabled(m_currentProject != 0);
    if (m_currentProject == 0) {
        m_unloadAction->setText(tr("Unload Project"));
        m_buildAction->setText(tr("Build Project"));
    } else {
        m_unloadAction->setText(tr("Unload Project \"%1\"").arg(m_currentProject->name()));
        m_buildAction->setText(tr("Build Project \"%1\"").arg(m_currentProject->name()));
    }

    m_buildAction->setEnabled(enableBuildActions);
    m_rebuildAction->setEnabled(enableBuildActions);
    m_cleanAction->setEnabled(enableBuildActions);
    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();

    updateTaskActions();
}

1263

con's avatar
con committed
1264
1265
1266
1267
1268
1269
1270
1271
// 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
1272
    foreach (Project *p, m_session->projectOrder(pro)) {
con's avatar
con committed
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
        FindAllFilesVisitor filesVisitor;
        p->rootProjectNode()->accept(&filesVisitor);
        filesToSave << filesVisitor.filePaths();
    }
    qSort(filesToSave);
    return filesToSave;
}

bool ProjectExplorerPlugin::saveModifiedFiles(const QList<Project *> & projects)
{
    if (debug)
        qDebug() << "ProjectExplorerPlugin::saveModifiedFiles";

1286
    QList<Core::IFile *> modifiedFi = Core::ICore::instance()->fileManager()->modifiedFiles();
con's avatar
con committed
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
    QMap<QString, Core::IFile *> modified;

    QStringList allFiles;
    foreach (Project *pro, projects)
        allFiles << allFilesWithDependencies(pro);

    foreach (Core::IFile * fi, modifiedFi)
        modified.insert(fi->fileName(), fi);

    QList<Core::IFile *> filesToSave;

    QMap<QString, Core::IFile *>::const_iterator mit = modified.constBegin();
    QStringList::const_iterator ait = allFiles.constBegin();
    QMap<QString, Core::IFile *>::const_iterator mend = modified.constEnd();
    QStringList::const_iterator aend = allFiles.constEnd();

    while (mit != mend && ait != aend) {
        if (mit.key() < *ait)
            ++mit;
        else if (*ait < mit.key())
            ++ait;
        else {
            filesToSave.append(mit.value());
            ++ait;
            ++mit;
        }
    }

    if (!filesToSave.isEmpty()) {
        bool cancelled;
con's avatar
con committed
1317
        Core::ICore::instance()->fileManager()->saveModifiedFiles(filesToSave, &cancelled);
con's avatar
con committed
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
        if (cancelled) {
            return false;
        }
    }
    return true;
}

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

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

    if (saveModifiedFiles(QList<Project *>() << m_currentProject))
        buildManager()->buildProject(m_currentProject, m_currentProject->activeBuildConfiguration());
}

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

    const QList<Project *> & projects = m_session->projectOrder();
    if (saveModifiedFiles(projects)) {
        QStringList configurations;
        foreach (const Project * pro, projects)
            configurations << pro->activeBuildConfiguration();

        m_buildManager->buildProjects(projects, configurations);
    }
}

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

    if (saveModifiedFiles(QList<Project *>() << m_currentProject)) {
        m_buildManager->cleanProject(m_currentProject, m_currentProject->activeBuildConfiguration());
        m_buildManager->buildProject(m_currentProject, m_currentProject->activeBuildConfiguration());
    }
}

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

    const QList<Project *> & projects = m_session->projectOrder();
    if (saveModifiedFiles(projects)) {
        QStringList configurations;
        foreach (const Project * pro, projects)
            configurations << pro->activeBuildConfiguration();

        m_buildManager->cleanProjects(projects, configurations);
        m_buildManager->buildProjects(projects, configurations);
    }
}

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

    if (saveModifiedFiles(QList<Project *>() << m_currentProject))
        m_buildManager->cleanProject(m_currentProject, m_currentProject->activeBuildConfiguration());
}

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

    const QList<Project *> & projects = m_session->projectOrder();
    if (saveModifiedFiles(projects)) {
        QStringList configurations;
        foreach (const Project * pro, projects)
            configurations << pro->activeBuildConfiguration();

        m_buildManager->cleanProjects(projects, configurations);
    }
}

void ProjectExplorerPlugin::runProject()
{
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
    runProjectImpl(startupProject());
}

void ProjectExplorerPlugin::runProjectContextMenu()
{
    runProjectImpl(m_currentProject);
}

void ProjectExplorerPlugin::runProjectImpl(Project *pro)
{
con's avatar
con committed
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
    if (!pro)
        return;

    if (saveModifiedFiles(QList<Project *>() << pro)) {
        m_runMode = ProjectExplorer::Constants::RUNMODE;

        m_delayedRunConfiguration = pro->activeRunConfiguration();
        //NBS TODO make the build project step take into account project dependencies
        m_buildManager->buildProject(pro, pro->activeBuildConfiguration());
    }
}

void ProjectExplorerPlugin::debugProject()
{
    Project *pro = startupProject();
dt's avatar
dt committed
1430
    if (!pro || m_debuggingRunControl )
con's avatar
con committed
1431
1432
1433
1434
1435
1436
1437
        return;

    if (saveModifiedFiles(QList<Project *>() << pro)) {
        m_runMode = ProjectExplorer::Constants::DEBUGMODE;
        m_delayedRunConfiguration = pro->activeRunConfiguration();
        //NBS TODO make the build project step take into account project dependencies
        m_buildManager->buildProject(pro, pro->activeBuildConfiguration());
dt's avatar
dt committed
1438
        updateRunAction();
con's avatar
con committed
1439
1440
1441
1442
1443
1444
1445
1446
    }
}

void ProjectExplorerPlugin::addToApplicationOutputWindow(RunControl *rc, const QString &line)
{
    m_outputPane->appendOutput(rc, line);
}

Oswald Buddenhagen's avatar
Oswald Buddenhagen committed
1447
1448
1449
1450
1451
void ProjectExplorerPlugin::addToApplicationOutputWindowInline(RunControl *rc, const QString &line)
{
    m_outputPane->appendOutputInline(rc, line);
}

con's avatar
con committed
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
void ProjectExplorerPlugin::addErrorToApplicationOutputWindow(RunControl *rc, const QString &error)
{
    m_outputPane->appendOutput(rc, error);
}

void ProjectExplorerPlugin::runControlFinished()
{
    if (sender() == m_debuggingRunControl)
        m_debuggingRunControl = 0;

    updateRunAction();
}

void ProjectExplorerPlugin::startupProjectChanged()
{
    static QPointer<Project> previousStartupProject = 0;
    Project *project = startupProject();
    if (project == previousStartupProject)
        return;

    if (previousStartupProject) {
        disconnect(previousStartupProject, SIGNAL(activeRunConfigurationChanged()),
                   this, SLOT(updateRunAction()));
    }

    previousStartupProject = project;

    if (project) {
        connect(project, SIGNAL(activeRunConfigurationChanged()),
                this, SLOT(updateRunAction()));
    }

    updateRunAction();
}

// NBS TODO implement more than one runner
IRunConfigurationRunner *ProjectExplorerPlugin::findRunner(QSharedPointer<RunConfiguration> config, const QString &mode)
{
1490
1491
    ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
    const QList<IRunConfigurationRunner *> runners = pm->getObjects<IRunConfigurationRunner>();
con's avatar
con committed
1492
1493
1494
1495
1496
1497
1498
1499
1500
    foreach (IRunConfigurationRunner *runner, runners)
        if (runner->canRun(config, mode))
            return runner;
    return 0;
}

void ProjectExplorerPlugin::updateRunAction()
{
    const Project *project = startupProject();
1501
    bool canRun = project && findRunner(project->activeRunConfiguration(), ProjectExplorer::Constants::RUNMODE);
con's avatar
con committed
1502
1503
1504
    const bool canDebug = project && !m_debuggingRunControl && findRunner(project->activeRunConfiguration(), ProjectExplorer::Constants::DEBUGMODE);
    const bool building = m_buildManager->isBuilding();
    m_runAction->setEnabled(canRun && !building);
1505
1506
1507
1508

    canRun = m_currentProject && findRunner(m_currentProject->activeRunConfiguration(), ProjectExplorer::Constants::RUNMODE);
    m_runActionContextMenu->setEnabled(canRun && !building);

con's avatar
con committed
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
    m_debugAction->setEnabled(canDebug && !building);
}

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

    if (m_buildManager->isBuilding())
        m_buildManager->cancel();
}

1521
void ProjectExplorerPlugin::addToRecentProjects(const QString &fileName, const QString &displayName)
con's avatar
con committed
1522
1523
1524
1525
1526
1527
1528
{
    if (debug)
        qDebug() << "ProjectExplorerPlugin::addToRecentProjects(" << fileName << ")";

    if (fileName.isEmpty())
        return;
    QString prettyFileName(QDir::toNativeSeparators(fileName));
1529
1530
1531
1532
1533
1534
1535
1536

    QList<QPair<QString, QString> >::iterator it;
    for(it = m_recentProjects.begin(); it != m_recentProjects.end();)
        if ((*it).first == prettyFileName)
            it = m_recentProjects.erase(it);
        else
            ++it;

con's avatar
con committed
1537
1538
    if (m_recentProjects.count() > m_maxRecentProjects)
        m_recentProjects.removeLast();
1539
    m_recentProjects.prepend(qMakePair(prettyFileName, displayName));
con's avatar
con committed
1540
1541
1542
1543
1544
1545
1546
1547
1548
    QFileInfo fi(prettyFileName);
    m_lastOpenDirectory = fi.absolutePath();
}

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

1549
    Core::ActionContainer *aci =
1550
        Core::ICore::instance()->actionManager()->actionContainer(Constants::M_RECENTPROJECTS);
con's avatar
con committed
1551
1552
1553
1554
1555
1556
    QMenu *menu = aci->menu();
    menu->clear();

    menu->setEnabled(!m_recentProjects.isEmpty());

    //projects (ignore sessions, they used to be in this list)
1557
1558
1559
1560
1561
1562

    QList<QPair<QString, QString> >::const_iterator it, end;
    end = m_recentProjects.constEnd();
    for (it = m_recentProjects.constBegin(); it != end; ++it) {
        const QPair<QString, QString> &s = *it;
        if (s.first.endsWith(".qws"))
con's avatar
con committed
1563
            continue;
1564
        QAction *action = menu->addAction(s.first);
1565
        action->setData(s.first);
con's avatar
con committed
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
        connect(action, SIGNAL(triggered()), this, SLOT(openRecentProject()));
    }
}

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

    QAction *a = qobject_cast<QAction*>(sender());
1576
1577
1578
1579
    if (!a)
        return;
    QString fileName = a->data().toString();
    if (!fileName.isEmpty())
mae's avatar
mae committed
1580
        openProject(fileName);
con's avatar
con committed
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
}

void ProjectExplorerPlugin::invalidateProject(Project *project)
{
    if (debug)
        qDebug() << "ProjectExplorerPlugin::invalidateProject" << project->name();
    if (m_currentProject == project) {
        //
        // Workaround for a bug in QItemSelectionModel
        // - currentChanged etc are not emitted if the
        // item is removed from the underlying data model
        //
        setCurrent(0, QString(), 0);
    }

    disconnect(project, SIGNAL(fileListChanged()), this, SIGNAL(fileListChanged()));
}

void ProjectExplorerPlugin::goToTaskWindow()
{
    m_buildManager->gotoTaskWindow();
}

void ProjectExplorerPlugin::updateContextMenuActions()
{
    if (ProjectNode *projectNode = qobject_cast<ProjectNode*>(m_currentNode)) {
        const bool addFilesEnabled = projectNode->supportedActions().contains(ProjectNode::AddFile);
        m_addExistingFilesAction->setEnabled(addFilesEnabled);
        m_addNewFileAction->setEnabled(addFilesEnabled);
    } else if (FileNode *fileNode = qobject_cast<FileNode*>(m_currentNode)) {
        const bool removeFileEnabled = fileNode->projectNode()->supportedActions().contains(ProjectNode::RemoveFile);
        m_removeFileAction->setEnabled(removeFileEnabled);
    }
}

void ProjectExplorerPlugin::addNewFile()
{
dt's avatar
dt committed
1618
1619
    if (!m_currentNode && m_currentNode->nodeType() == ProjectNodeType)
        return;
con's avatar
con committed
1620
    const QString location = QFileInfo(m_currentNode->path()).dir().absolutePath();
1621
    Core::ICore::instance()->showNewItemDialog(tr("New File", "Title of dialog"),
con's avatar
con committed
1622
1623
1624
1625
1626
1627
1628
                              Core::BaseFileWizard::findWizardsOfKind(Core::IWizard::FileWizard)
                              + Core::BaseFileWizard::findWizardsOfKind(Core::IWizard::ClassWizard),
                              location);
}

void ProjectExplorerPlugin::addExistingFiles()
{
dt's avatar
dt committed
1629
1630
    if (!m_currentNode && m_currentNode->nodeType() == ProjectNodeType)
        return;
con's avatar
con committed