project.cpp 17.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
** Contact: Nokia Corporation (qt-info@nokia.com)
con's avatar
con committed
8
**
9
** Commercial Usage
10
**
11 12 13 14
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
15
**
16
** GNU Lesser General Public License Usage
17
**
18 19 20 21 22 23
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24
**
25
** If you are unsure which license is appropriate for your use, please
hjk's avatar
hjk committed
26
** contact the sales department at http://qt.nokia.com/contact.
con's avatar
con committed
27
**
28
**************************************************************************/
hjk's avatar
hjk committed
29

con's avatar
con committed
30
#include "project.h"
hjk's avatar
hjk committed
31

32 33 34 35
#include "persistentsettings.h"
#include "buildconfiguration.h"
#include "environment.h"
#include "projectnodes.h"
hjk's avatar
hjk committed
36
#include "buildstep.h"
con's avatar
con committed
37 38 39 40 41 42
#include "projectexplorer.h"
#include "runconfiguration.h"
#include "editorconfiguration.h"

#include <coreplugin/ifile.h>
#include <extensionsystem/pluginmanager.h>
hjk's avatar
hjk committed
43
#include <utils/qtcassert.h>
con's avatar
con committed
44 45

#include <QtCore/QDebug>
hjk's avatar
hjk committed
46
#include <QtCore/QTextCodec>
con's avatar
con committed
47 48

using namespace ProjectExplorer;
49
using namespace ProjectExplorer::Internal;
con's avatar
con committed
50 51 52 53 54 55 56

Project::Project()
    : m_activeRunConfiguration(0),
      m_editorConfiguration(new EditorConfiguration())
{
}

57 58 59
Project::~Project()
{
    qDeleteAll(m_buildConfigurationValues);
dt's avatar
dt committed
60
    qDeleteAll(m_runConfigurations);
61 62 63
    delete m_editorConfiguration;
}

dt's avatar
dt committed
64 65 66 67 68 69 70 71 72 73 74
QString Project::makeUnique(const QString &preferedName, const QStringList &usedNames)
{
    if (!usedNames.contains(preferedName))
        return preferedName;
    int i = 2;
    QString tryName = preferedName + QString::number(i);
    while (usedNames.contains(tryName))
        tryName = preferedName + QString::number(++i);
    return tryName;
}

75
void Project::addBuildConfiguration(BuildConfiguration *configuration)
con's avatar
con committed
76
{
77 78 79 80 81
    // Check that we don't have a configuration with the same displayName
    QString configurationDisplayName = configuration->displayName();
    QStringList displayNames;
    foreach (const BuildConfiguration *bc, m_buildConfigurationValues)
        displayNames << bc->displayName();
dt's avatar
dt committed
82
    configurationDisplayName = makeUnique(configurationDisplayName, displayNames);
83
    configuration->setDisplayName(configurationDisplayName);
con's avatar
con committed
84

85 86
    // add it
    m_buildConfigurationValues.push_back(configuration);
con's avatar
con committed
87

88
    emit addedBuildConfiguration(configuration);
con's avatar
con committed
89 90
}

91
void Project::removeBuildConfiguration(BuildConfiguration *configuration)
con's avatar
con committed
92
{
93
    //todo: this might be error prone
94
    if (!m_buildConfigurationValues.contains(configuration))
con's avatar
con committed
95 96
        return;

97
    m_buildConfigurationValues.removeOne(configuration);
con's avatar
con committed
98

99
    emit removedBuildConfiguration(configuration);
100
    delete configuration;
con's avatar
con committed
101 102
}

103
QList<BuildConfiguration *> Project::buildConfigurations() const
con's avatar
con committed
104
{
105
    return m_buildConfigurationValues;
con's avatar
con committed
106 107
}

108 109 110 111 112
bool Project::hasBuildSettings() const
{
    return true;
}

con's avatar
con committed
113 114 115 116 117 118 119
void Project::saveSettings()
{
    PersistentSettingsWriter writer;
    saveSettingsImpl(writer);
    writer.save(file()->fileName() + QLatin1String(".user"), "QtCreatorProject");
}

dt's avatar
dt committed
120
bool Project::restoreSettings()
con's avatar
con committed
121 122 123
{
    PersistentSettingsReader reader;
    reader.load(file()->fileName() + QLatin1String(".user"));
dt's avatar
dt committed
124 125
    if (!restoreSettingsImpl(reader))
        return false;
con's avatar
con committed
126

dt's avatar
dt committed
127
    if (m_activeBuildConfiguration && !m_buildConfigurationValues.isEmpty())
128
        setActiveBuildConfiguration(m_buildConfigurationValues.at(0));
con's avatar
con committed
129 130 131

    if (!m_activeRunConfiguration && !m_runConfigurations.isEmpty())
        setActiveRunConfiguration(m_runConfigurations.at(0));
dt's avatar
dt committed
132
    return true;
con's avatar
con committed
133 134
}

dt's avatar
dt committed
135
QList<BuildConfigWidget*> Project::subConfigWidgets()
con's avatar
con committed
136
{
dt's avatar
dt committed
137
    return QList<BuildConfigWidget*>();
con's avatar
con committed
138 139 140 141
}

void Project::saveSettingsImpl(PersistentSettingsWriter &writer)
{
dt's avatar
dt committed
142 143 144 145
    const QList<BuildConfiguration *> bcs = buildConfigurations();

    // For compability with older versions the "name" is saved as a string instead of a number
    writer.saveValue("activebuildconfiguration", QString::number(bcs.indexOf(m_activeBuildConfiguration)));
con's avatar
con committed
146 147

    //save buildsettings
148
    QStringList buildConfigurationNames;
dt's avatar
dt committed
149
    for(int i=0; i < bcs.size(); ++i) {
dt's avatar
dt committed
150 151
        QMap<QString, QVariant> temp;
        bcs.at(i)->toMap(temp);
dt's avatar
dt committed
152 153
        writer.saveValue("buildConfiguration-" + QString::number(i), temp);
        buildConfigurationNames << QString::number(i);
con's avatar
con committed
154
    }
155
    writer.saveValue("buildconfigurations", buildConfigurationNames);
con's avatar
con committed
156 157

    // save each buildstep/buildConfiguration combination
dt's avatar
dt committed
158
    for(int i=0; i < bcs.size(); ++i) {
159
        QStringList buildStepNames;
dt's avatar
dt committed
160
        foreach (BuildStep *buildStep, bcs.at(i)->buildSteps())
161
            buildStepNames << buildStep->displayName();
dt's avatar
dt committed
162
        writer.saveValue("buildconfiguration-" + QString::number(i) + "-buildsteps", buildStepNames);
163 164

        int buildstepnr = 0;
dt's avatar
dt committed
165
        foreach (BuildStep *buildStep, bcs.at(i)->buildSteps()) {
166
            QMap<QString, QVariant> temp;
167
            buildStep->storeIntoLocalMap(temp);
dt's avatar
dt committed
168
            writer.saveValue("buildconfiguration-" + QString::number(i) + "-buildstep" + QString().setNum(buildstepnr), temp);
con's avatar
con committed
169 170 171 172 173
            ++buildstepnr;
        }
    }

    // save each cleanstep/buildConfiguration combination
dt's avatar
dt committed
174
    for(int i=0; i < bcs.size(); ++i) {
175
        QStringList cleanStepNames;
dt's avatar
dt committed
176
        foreach (BuildStep *cleanStep, bcs.at(i)->cleanSteps())
177
            cleanStepNames << cleanStep->displayName();
dt's avatar
dt committed
178
        writer.saveValue("buildconfiguration-" + QString::number(i) + "-cleansteps", cleanStepNames);
179 180

        int cleanstepnr = 0;
dt's avatar
dt committed
181
        foreach (BuildStep *cleanStep, bcs.at(i)->cleanSteps()) {
182
            QMap<QString, QVariant> temp;
183
            cleanStep->storeIntoLocalMap(temp);
dt's avatar
dt committed
184
            writer.saveValue("buildconfiguration-" + QString::number(i) + "-cleanstep" + QString().setNum(cleanstepnr), temp);
con's avatar
con committed
185 186 187 188 189 190 191
            ++cleanstepnr;
        }
    }

    // Running
    int i = 0;
    int activeId = 0;
192
    foreach (RunConfiguration* rc, m_runConfigurations) {
con's avatar
con committed
193
        writer.setPrefix("RunConfiguration" + QString().setNum(i) + "-");
194
        writer.saveValue("Id", rc->id());
con's avatar
con committed
195 196 197 198 199 200 201 202 203 204 205
        rc->save(writer);
        if (rc == m_activeRunConfiguration)
            activeId = i;
        ++i;
    }
    writer.setPrefix(QString::null);
    writer.saveValue("activeRunConfiguration", activeId);

    writer.saveValue("defaultFileEncoding", m_editorConfiguration->defaultTextCodec()->name());
}

dt's avatar
dt committed
206
bool Project::restoreSettingsImpl(PersistentSettingsReader &reader)
con's avatar
con committed
207
{
208 209 210
    const QList<IBuildStepFactory *> buildStepFactories =
          ExtensionSystem::PluginManager::instance()->getObjects<IBuildStepFactory>();

211
    // restoring BuldConfigurations from settings
con's avatar
con committed
212
    const QStringList buildConfigurationNames = reader.restoreValue("buildconfigurations").toStringList();
dt's avatar
dt committed
213

hjk's avatar
hjk committed
214
    foreach (const QString &buildConfigurationName, buildConfigurationNames) {
con's avatar
con committed
215 216
        QMap<QString, QVariant> temp =
            reader.restoreValue("buildConfiguration-" + buildConfigurationName).toMap();
217

dt's avatar
dt committed
218
        BuildConfiguration *bc = buildConfigurationFactory()->restore(temp);
219
        // Restore build steps
dt's avatar
dt committed
220
        QVariant buildStepsValueVariant = reader.restoreValue("buildconfiguration-" + buildConfigurationName + "-buildsteps");
221 222 223 224 225 226 227 228
        if(buildStepsValueVariant.isValid()) {
            int pos = 0;
            QStringList buildStepNames = buildStepsValueVariant.toStringList();
            for (int buildstepnr = 0; buildstepnr < buildStepNames.size(); ++buildstepnr) {
                const QString &buildStepName = buildStepNames.at(buildstepnr);
                BuildStep *buildStep  = 0;
                foreach (IBuildStepFactory *factory, buildStepFactories) {
                    if (factory->canCreate(buildStepName)) {
dt's avatar
dt committed
229
                        buildStep = factory->create(bc, buildStepName);
230 231 232 233 234 235 236 237 238
                        break;
                    }
                }
                // Restoring settings
                if (buildStep) {
                    // TODO remove restoreFromGlobalMap after 2.0
                    QMap<QString, QVariant> buildStepValues = reader.restoreValue("buildstep" + QString().setNum(buildstepnr)).toMap();
                    buildStep->restoreFromGlobalMap(buildStepValues);
                    buildStepValues =
dt's avatar
dt committed
239
                            reader.restoreValue("buildconfiguration-" + buildConfigurationName + "-buildstep" + QString().setNum(buildstepnr)).toMap();
240 241 242 243 244 245 246
                    buildStep->restoreFromLocalMap(buildStepValues);
                    bc->insertBuildStep(pos, buildStep);
                    ++pos;
                }
            }
        }
        // Restore clean steps
dt's avatar
dt committed
247
        QVariant cleanStepsValueVariant = reader.restoreValue("buildconfiguration-" + buildConfigurationName + "-cleansteps");
248 249 250 251 252 253 254 255
        if(cleanStepsValueVariant.isValid()) {
            int pos = 0;
            QStringList cleanStepNames = cleanStepsValueVariant.toStringList();
            for (int cleanstepnr = 0; cleanstepnr < cleanStepNames.size(); ++cleanstepnr) {
                const QString &cleanStepName = cleanStepNames.at(cleanstepnr);
                BuildStep *cleanStep = 0;
                foreach (IBuildStepFactory *factory, buildStepFactories) {
                    if (factory->canCreate(cleanStepName)) {
dt's avatar
dt committed
256
                        cleanStep = factory->create(bc, cleanStepName);
257 258 259 260 261 262 263 264 265
                        break;
                    }
                }
                // Restoring settings
                if (cleanStep) {
                    // TODO remove restoreFromGlobalMap after 2.0
                    QMap<QString, QVariant> buildStepValues = reader.restoreValue("cleanstep" + QString().setNum(cleanstepnr)).toMap();
                    cleanStep->restoreFromGlobalMap(buildStepValues);
                    buildStepValues =
dt's avatar
dt committed
266
                            reader.restoreValue("buildconfiguration-" + buildConfigurationName + "-cleanstep" + QString().setNum(cleanstepnr)).toMap();
267 268 269 270 271 272
                    cleanStep->restoreFromLocalMap(buildStepValues);
                    bc->insertCleanStep(pos, cleanStep);
                    ++pos;
                }
            }
        }
dt's avatar
dt committed
273
        addBuildConfiguration(bc);
con's avatar
con committed
274 275
    }

dt's avatar
dt committed
276
    // Set Active Configuration
dt's avatar
dt committed
277 278 279 280 281 282 283 284 285 286
    { // Try restoring the active configuration
        QString activeConfigurationName = reader.restoreValue("activebuildconfiguration").toString();
        int index = buildConfigurationNames.indexOf(activeConfigurationName);
        if (index != -1)
            m_activeBuildConfiguration = buildConfigurations().at(index);
        else if (!buildConfigurations().isEmpty())
            m_activeBuildConfiguration = buildConfigurations().at(0);
        else
            m_activeBuildConfiguration = 0;
    }
dt's avatar
dt committed
287

288
    //Build Settings
con's avatar
con committed
289
    QVariant buildStepsVariant = reader.restoreValue("buildsteps");
hjk's avatar
hjk committed
290
    if (buildStepsVariant.isValid()) {
291
        // Old code path for 1.3 compability
con's avatar
con committed
292 293 294
        // restoring BuildSteps from settings
        int pos = 0;
        QStringList buildStepNames = buildStepsVariant.toStringList();
295 296 297
        for (int buildstepnr = 0; buildstepnr < buildStepNames.size(); ++buildstepnr) {
            const QString &buildStepName = buildStepNames.at(buildstepnr);
            BuildStep *buildStep  = 0;
298 299 300 301
            IBuildStepFactory *factory = 0;
            foreach (IBuildStepFactory *fac, buildStepFactories) {
                if (fac->canCreate(buildStepName)) {
                    factory = fac;
con's avatar
con committed
302 303 304
                    break;
                }
            }
305
            if (factory) {
dt's avatar
dt committed
306 307 308 309
                const QList<BuildConfiguration *> &bcs = buildConfigurations();
                for(int i = 0; i < bcs.size(); ++i) {
                    buildStep = factory->create(bcs.at(i), buildStepName);
                    bcs.at(i)->insertBuildStep(pos, buildStep);
310 311 312
                    QMap<QString, QVariant> buildStepValues = reader.restoreValue("buildstep" + QString().setNum(buildstepnr)).toMap();
                    buildStep->restoreFromGlobalMap(buildStepValues);
                    buildStepValues =
dt's avatar
dt committed
313
                            reader.restoreValue("buildconfiguration-" + QString::number(i) + "-buildstep" + QString().setNum(buildstepnr)).toMap();
314
                    buildStep->restoreFromLocalMap(buildStepValues);
315
                }
316
                ++pos;
317
            }
con's avatar
con committed
318
        }
319
    }
con's avatar
con committed
320

321 322
    QVariant cleanStepsVariant = reader.restoreValue("cleansteps");
    if (cleanStepsVariant.isValid()) {
323
        // Old code path for 1.3 compability
324
        QStringList cleanStepNames = cleanStepsVariant.toStringList();
con's avatar
con committed
325
        // restoring BuildSteps from settings
326 327 328 329
        int pos = 0;
        for (int cleanstepnr = 0; cleanstepnr < cleanStepNames.size(); ++cleanstepnr) {
            const QString &cleanStepName = cleanStepNames.at(cleanstepnr);
            BuildStep *cleanStep = 0;
330 331 332 333
            IBuildStepFactory *factory = 0;
            foreach (IBuildStepFactory *fac, buildStepFactories) {
                if (fac->canCreate(cleanStepName)) {
                    factory = fac;
con's avatar
con committed
334 335 336
                    break;
                }
            }
337 338

            if (factory) {
dt's avatar
dt committed
339 340 341 342
                const QList<BuildConfiguration *> &bcs = buildConfigurations();
                for (int i = 0; i < bcs.size(); ++i) {
                    cleanStep = factory->create(bcs.at(i), cleanStepName);
                    bcs.at(i)->insertCleanStep(pos, cleanStep);
343 344
                    QMap<QString, QVariant> cleanStepValues = reader.restoreValue("cleanstep" + QString().setNum(cleanstepnr)).toMap();
                    cleanStep->restoreFromGlobalMap(cleanStepValues);
345
                    QMap<QString, QVariant> buildStepValues =
dt's avatar
dt committed
346
                            reader.restoreValue("buildconfiguration-" + QString::number(i) + "-cleanstep" + QString().setNum(cleanstepnr)).toMap();
347
                    cleanStep->restoreFromLocalMap(buildStepValues);
348
                }
349
                ++pos;
con's avatar
con committed
350 351 352 353 354 355 356 357 358 359 360
            }
        }
    }

    // Running
    const int activeId = reader.restoreValue("activeRunConfiguration").toInt();
    int i = 0;
    const QList<IRunConfigurationFactory *> factories =
        ExtensionSystem::PluginManager::instance()->getObjects<IRunConfigurationFactory>();
    forever {
        reader.setPrefix("RunConfiguration" + QString().setNum(i) + "-");
361 362
        const QVariant &idVariant = reader.restoreValue("Id");
        if (!idVariant.isValid())
con's avatar
con committed
363
            break;
364
        const QString &id = idVariant.toString();
hjk's avatar
hjk committed
365
        foreach (IRunConfigurationFactory *factory, factories) {
366 367
            if (factory->canRestore(id)) {
                RunConfiguration* rc = factory->create(this, id);
con's avatar
con committed
368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383
                rc->restore(reader);
                addRunConfiguration(rc);
                if (i == activeId)
                    setActiveRunConfiguration(rc);
            }
        }
        ++i;
    }
    reader.setPrefix(QString::null);

    QTextCodec *codec = QTextCodec::codecForName(reader.restoreValue("defaultFileEncoding").toByteArray());
    if (codec)
        m_editorConfiguration->setDefaultTextCodec(codec);

    if (!m_activeRunConfiguration && !m_runConfigurations.isEmpty())
        setActiveRunConfiguration(m_runConfigurations.at(0));
dt's avatar
dt committed
384
    return true;
con's avatar
con committed
385 386
}

387
BuildConfiguration *Project::activeBuildConfiguration() const
con's avatar
con committed
388
{
389
    return m_activeBuildConfiguration;
con's avatar
con committed
390 391
}

392
void Project::setActiveBuildConfiguration(BuildConfiguration *configuration)
con's avatar
con committed
393
{
dt's avatar
dt committed
394 395
    if (m_activeBuildConfiguration != configuration && m_buildConfigurationValues.contains(configuration)) {
        m_activeBuildConfiguration = configuration;
con's avatar
con committed
396 397 398 399
        emit activeBuildConfigurationChanged();
    }
}

400
QList<RunConfiguration *> Project::runConfigurations() const
con's avatar
con committed
401 402 403 404
{
    return m_runConfigurations;
}

405
void Project::addRunConfiguration(RunConfiguration* runConfiguration)
con's avatar
con committed
406
{
dt's avatar
dt committed
407
    if (m_runConfigurations.contains(runConfiguration)) {
408
        qWarning()<<"Not adding already existing runConfiguration"<<runConfiguration->displayName();
dt's avatar
dt committed
409 410
        return;
    }
con's avatar
con committed
411
    m_runConfigurations.push_back(runConfiguration);
412
    emit addedRunConfiguration(this, runConfiguration->displayName());
con's avatar
con committed
413 414
}

415
void Project::removeRunConfiguration(RunConfiguration* runConfiguration)
con's avatar
con committed
416
{
dt's avatar
dt committed
417
    if(!m_runConfigurations.contains(runConfiguration)) {
418
        qWarning()<<"Not removing runConfiguration"<<runConfiguration->displayName()<<"becasue it doesn't exist";
dt's avatar
dt committed
419
        return;
420
    }
421

con's avatar
con committed
422
    if (m_activeRunConfiguration == runConfiguration) {
423
        if (m_runConfigurations.size() <= 1)
424
            setActiveRunConfiguration(0);
425 426
        else if (m_runConfigurations.at(0) == m_activeRunConfiguration)
            setActiveRunConfiguration(m_runConfigurations.at(1));
con's avatar
con committed
427 428 429
        else
            setActiveRunConfiguration(m_runConfigurations.at(0));
    }
430 431

    m_runConfigurations.removeOne(runConfiguration);
432
    emit removedRunConfiguration(this, runConfiguration->displayName());
dt's avatar
dt committed
433
    delete runConfiguration;
con's avatar
con committed
434 435
}

436
RunConfiguration* Project::activeRunConfiguration() const
con's avatar
con committed
437 438 439 440
{
    return m_activeRunConfiguration;
}

441
void Project::setActiveRunConfiguration(RunConfiguration* runConfiguration)
con's avatar
con committed
442 443 444
{
    if (runConfiguration == m_activeRunConfiguration)
        return;
dt's avatar
dt committed
445
    Q_ASSERT(m_runConfigurations.contains(runConfiguration) || runConfiguration == 0);
con's avatar
con committed
446 447 448 449 450 451 452 453 454
    m_activeRunConfiguration = runConfiguration;
    emit activeRunConfigurationChanged();
}

EditorConfiguration *Project::editorConfiguration() const
{
    return m_editorConfiguration;
}

455
QByteArray Project::predefinedMacros(const QString &) const
456 457 458 459
{
    return QByteArray();
}

460
QStringList Project::includePaths(const QString &) const
461 462 463 464
{
    return QStringList();
}

465
QStringList Project::frameworkPaths(const QString &) const
466 467 468
{
    return QStringList();
}
469 470 471 472 473 474

QString Project::generatedUiHeader(const QString & /* formFile */) const
{
    return QString();
}