genericproject.cpp 20.5 KB
Newer Older
Roberto Raggi's avatar
Roberto Raggi committed
1
2
3
4
5
6
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
7
** Contact: Nokia Corporation (qt-info@nokia.com)
Roberto Raggi's avatar
Roberto Raggi committed
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
**
** Commercial Usage
**
** 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.
**
** GNU Lesser General Public License Usage
**
** 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.
**
** 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.
Roberto Raggi's avatar
Roberto Raggi committed
27
28
29
30
31
**
**************************************************************************/

#include "genericproject.h"
#include "genericprojectconstants.h"
32
#include "genericmakestep.h"
dt's avatar
dt committed
33
#include "genericbuildconfiguration.h"
Roberto Raggi's avatar
Roberto Raggi committed
34

35
#include <projectexplorer/toolchain.h>
Roberto Raggi's avatar
Roberto Raggi committed
36
#include <projectexplorer/projectexplorerconstants.h>
37
#include <projectexplorer/persistentsettings.h>
Roberto Raggi's avatar
Roberto Raggi committed
38
39
#include <cpptools/cppmodelmanagerinterface.h>
#include <extensionsystem/pluginmanager.h>
40
#include <utils/pathchooser.h>
Roberto Raggi's avatar
Roberto Raggi committed
41
42
43
#include <utils/qtcassert.h>
#include <coreplugin/icore.h>

44
45
46
47
#include <QtCore/QtDebug>
#include <QtCore/QDir>
#include <QtCore/QSettings>
#include <QtCore/QProcess>
48
#include <QtCore/QCoreApplication>
Roberto Raggi's avatar
Roberto Raggi committed
49

50
51
#include <QtGui/QFormLayout>
#include <QtGui/QMainWindow>
52
#include <QtGui/QInputDialog>
53
#include <QtGui/QComboBox>
54
55
#include <QtGui/QStringListModel>
#include <QtGui/QListWidget>
56
#include <QtGui/QPushButton>
Roberto Raggi's avatar
Roberto Raggi committed
57
58
59

using namespace GenericProjectManager;
using namespace GenericProjectManager::Internal;
60
using namespace ProjectExplorer;
Roberto Raggi's avatar
Roberto Raggi committed
61

62
63
namespace {

64
65
66
67
/**
 * An editable string list model. New strings can be added by editing the entry
 * called "<new>", displayed at the end.
 */
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
class ListModel: public QStringListModel
{
public:
    ListModel(QObject *parent)
        : QStringListModel(parent) {}

    virtual ~ListModel() {}

    virtual int rowCount(const QModelIndex &parent) const
    { return 1 + QStringListModel::rowCount(parent); }

    virtual Qt::ItemFlags flags(const QModelIndex &index) const
    { return QStringListModel::flags(index) | Qt::ItemIsEditable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled; }

    virtual QModelIndex index(int row, int column, const QModelIndex &parent) const
    {
        if (row == stringList().size())
            return createIndex(row, column);

        return QStringListModel::index(row, column, parent);
    }

    virtual QVariant data(const QModelIndex &index, int role) const
    {
        if (role == Qt::DisplayRole || role == Qt::EditRole) {
            if (index.row() == stringList().size())
94
                return QCoreApplication::translate("GenericProject", "<new>");
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
        }

        return QStringListModel::data(index, role);
    }

    virtual bool setData(const QModelIndex &index, const QVariant &value, int role)
    {
        if (role == Qt::EditRole && index.row() == stringList().size())
            insertRow(index.row(), QModelIndex());

        return QStringListModel::setData(index, value, role);
    }
};

} // end of anonymous namespace

111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/*!
  \class GenericBuildConfigurationFactory
*/

GenericBuildConfigurationFactory::GenericBuildConfigurationFactory(GenericProject *project)
    : IBuildConfigurationFactory(project),
    m_project(project)
{
}

GenericBuildConfigurationFactory::~GenericBuildConfigurationFactory()
{
}

QStringList GenericBuildConfigurationFactory::availableCreationTypes() const
{
    return QStringList() << "Create";
}

Friedemann Kleint's avatar
Friedemann Kleint committed
130
QString GenericBuildConfigurationFactory::displayNameForType(const QString & /* type */) const
131
132
133
134
{
    return tr("Create");
}

135
bool GenericBuildConfigurationFactory::create(const QString &type) const
136
{
137
138
139
140
141
142
143
144
145
146
147
148
    QTC_ASSERT(type == "Create", return false);
    //TODO asking for name is duplicated everywhere, but maybe more
    // wizards will show up, that incorporate choosing the name
    bool ok;
    QString buildConfigurationName = QInputDialog::getText(0,
                          tr("New configuration"),
                          tr("New Configuration Name:"),
                          QLineEdit::Normal,
                          QString(),
                          &ok);
    if (!ok || buildConfigurationName.isEmpty())
        return false;
dt's avatar
dt committed
149
    GenericBuildConfiguration *bc = new GenericBuildConfiguration(buildConfigurationName);
150
    m_project->addBuildConfiguration(bc); // also makes the name unique...
151
152
153
154

    GenericMakeStep *makeStep = new GenericMakeStep(m_project, bc);
    bc->insertBuildStep(0, makeStep);
    makeStep->setBuildTarget("all", /* on = */ true);
dt's avatar
dt committed
155
    return true;
156
157
}

dt's avatar
dt committed
158
159
160
161
162
163
164
165
bool GenericBuildConfigurationFactory::clone(const QString &name, BuildConfiguration *source) const
{
    // TODO
    GenericBuildConfiguration *bc = new GenericBuildConfiguration(name, static_cast<GenericBuildConfiguration *>(source));
    m_project->addBuildConfiguration(bc);
    return true;
}

166
167
168
169
////////////////////////////////////////////////////////////////////////////////////
// GenericProject
////////////////////////////////////////////////////////////////////////////////////

Roberto Raggi's avatar
Roberto Raggi committed
170
GenericProject::GenericProject(Manager *manager, const QString &fileName)
171
172
    : m_manager(manager),
      m_fileName(fileName),
173
      m_buildConfigurationFactory(new GenericBuildConfigurationFactory(this)),
174
      m_toolChain(0)
Roberto Raggi's avatar
Roberto Raggi committed
175
{
176
    QFileInfo fileInfo(m_fileName);
177
178
    QDir dir = fileInfo.dir();

179
    m_projectName      = fileInfo.completeBaseName();
180
181
182
    m_filesFileName    = QFileInfo(dir, m_projectName + QLatin1String(".files")).absoluteFilePath();
    m_includesFileName = QFileInfo(dir, m_projectName + QLatin1String(".includes")).absoluteFilePath();
    m_configFileName   = QFileInfo(dir, m_projectName + QLatin1String(".config")).absoluteFilePath();
183

184
185
    m_file = new GenericProjectFile(this, fileName);
    m_rootNode = new GenericProjectNode(this, m_file);
186

187
    m_manager->registerProject(this);
Roberto Raggi's avatar
Roberto Raggi committed
188
189
190
191
}

GenericProject::~GenericProject()
{
192
    m_manager->unregisterProject(this);
193

194
195
    delete m_rootNode;
    delete m_toolChain;
Roberto Raggi's avatar
Roberto Raggi committed
196
197
}

198
199
200
201
202
IBuildConfigurationFactory *GenericProject::buildConfigurationFactory() const
{
    return m_buildConfigurationFactory;
}

203
QString GenericProject::filesFileName() const
204
{ return m_filesFileName; }
205
206

QString GenericProject::includesFileName() const
207
{ return m_includesFileName; }
208
209

QString GenericProject::configFileName() const
210
{ return m_configFileName; }
211

212
static QStringList readLines(const QString &absoluteFileName)
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
{
    QStringList lines;

    QFile file(absoluteFileName);
    if (file.open(QFile::ReadOnly)) {
        QTextStream stream(&file);

        forever {
            QString line = stream.readLine();
            if (line.isNull())
                break;

            line = line.trimmed();
            if (line.isEmpty())
                continue;

            lines.append(line);
        }
    }

    return lines;
}

236
bool GenericProject::setFiles(const QStringList &filePaths)
237
{
238
    // Make sure we can open the file for writing
239
    QFile file(filesFileName());
240
241
242
243
244
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
        return false;

    QTextStream stream(&file);
    QDir baseDir(QFileInfo(m_fileName).dir());
245
    foreach (const QString &filePath, filePaths)
246
247
248
249
250
        stream << baseDir.relativeFilePath(filePath) << QLatin1Char('\n');

    file.close();
    refresh(GenericProject::Files);
    return true;
251
}
252

253
254
255
256
257
258
259
260
261
262
bool GenericProject::addFiles(const QStringList &filePaths)
{
    QStringList newFileList = m_files;
    newFileList.append(filePaths);

    return setFiles(newFileList);
}

bool GenericProject::removeFiles(const QStringList &filePaths)
{
263
264
265
266
267
268
269
    QStringList newFileList;
    QSet<QString> filesToRemove = filePaths.toSet();

    foreach (const QString &file, m_files) {
        if (!filesToRemove.contains(file))
            newFileList.append(file);
    }
270
271
272
273

    return setFiles(newFileList);
}

274
void GenericProject::parseProject(RefreshOptions options)
Roberto Raggi's avatar
Roberto Raggi committed
275
{
276
    if (options & Files)
277
        m_files = convertToAbsoluteFiles(readLines(filesFileName()));
278

279
    if (options & Configuration) {
280
        m_projectIncludePaths = convertToAbsoluteFiles(readLines(includesFileName()));
281

282
283
        QSettings projectInfo(m_fileName, QSettings::IniFormat);
        m_generated = convertToAbsoluteFiles(projectInfo.value(QLatin1String("generated")).toStringList());
Roberto Raggi's avatar
Roberto Raggi committed
284

285
        m_defines.clear();
Roberto Raggi's avatar
Roberto Raggi committed
286

287
288
289
290
        QFile configFile(configFileName());
        if (configFile.open(QFile::ReadOnly))
            m_defines = configFile.readAll();
    }
291

292
293
    if (options & Files)
        emit fileListChanged();
Roberto Raggi's avatar
Roberto Raggi committed
294
295
}

296
void GenericProject::refresh(RefreshOptions options)
Roberto Raggi's avatar
Roberto Raggi committed
297
{
298
299
300
    QSet<QString> oldFileList;
    if (!(options & Configuration))
        oldFileList = m_files.toSet();
301

302
303
304
305
    parseProject(options);

    if (options & Files)
        m_rootNode->refresh();
Roberto Raggi's avatar
Roberto Raggi committed
306
307
308
309

    CppTools::CppModelManagerInterface *modelManager =
        ExtensionSystem::PluginManager::instance()->getObject<CppTools::CppModelManagerInterface>();

310
311
312
    if (m_toolChain && modelManager) {
        const QByteArray predefinedMacros = m_toolChain->predefinedMacros();
        const QList<ProjectExplorer::HeaderPath> systemHeaderPaths = m_toolChain->systemHeaderPaths();
Roberto Raggi's avatar
Roberto Raggi committed
313
314
315

        CppTools::CppModelManagerInterface::ProjectInfo pinfo = modelManager->projectInfo(this);
        pinfo.defines = predefinedMacros;
Roberto Raggi's avatar
Roberto Raggi committed
316
        pinfo.defines += '\n';
317
        pinfo.defines += m_defines;
Roberto Raggi's avatar
Roberto Raggi committed
318
319
320

        QStringList allIncludePaths, allFrameworkPaths;

321
        foreach (const ProjectExplorer::HeaderPath &headerPath, m_toolChain->systemHeaderPaths()) {
Roberto Raggi's avatar
Roberto Raggi committed
322
323
324
325
326
327
            if (headerPath.kind() == ProjectExplorer::HeaderPath::FrameworkHeaderPath)
                allFrameworkPaths.append(headerPath.path());
            else
                allIncludePaths.append(headerPath.path());
        }

Roberto Raggi's avatar
Roberto Raggi committed
328
        allIncludePaths += this->allIncludePaths();
Roberto Raggi's avatar
Roberto Raggi committed
329
330
331
332
333

        pinfo.frameworkPaths = allFrameworkPaths;
        pinfo.includePaths = allIncludePaths;

        // ### add _defines.
Roberto Raggi's avatar
Roberto Raggi committed
334
335
        pinfo.sourceFiles = files();
        pinfo.sourceFiles += generated();
Roberto Raggi's avatar
Roberto Raggi committed
336

337
338
339
340
341
342
343
344
345
346
347
        QStringList filesToUpdate;

        if (options & Configuration) {
            filesToUpdate = pinfo.sourceFiles;
            filesToUpdate.append(QLatin1String("<configuration>")); // XXX don't hardcode configuration file name
        } else if (options & Files) {
            // Only update files that got added to the list
            QSet<QString> newFileList = m_files.toSet();
            newFileList.subtract(oldFileList);
            filesToUpdate.append(newFileList.toList());
        }
348

Roberto Raggi's avatar
Roberto Raggi committed
349
        modelManager->updateProjectInfo(pinfo);
350
        modelManager->updateSourceFiles(filesToUpdate);
Roberto Raggi's avatar
Roberto Raggi committed
351
352
353
    }
}

Roberto Raggi's avatar
Roberto Raggi committed
354
355
QStringList GenericProject::convertToAbsoluteFiles(const QStringList &paths) const
{
356
    const QDir projectDir(QFileInfo(m_fileName).dir());
Roberto Raggi's avatar
Roberto Raggi committed
357
358
359
360
361
362
363
364
365
    QStringList absolutePaths;
    foreach (const QString &file, paths) {
        QFileInfo fileInfo(projectDir, file);
        absolutePaths.append(fileInfo.absoluteFilePath());
    }
    absolutePaths.removeDuplicates();
    return absolutePaths;
}

Roberto Raggi's avatar
Roberto Raggi committed
366
367
368
QStringList GenericProject::allIncludePaths() const
{
    QStringList paths;
369
370
    paths += m_includePaths;
    paths += m_projectIncludePaths;
Roberto Raggi's avatar
Roberto Raggi committed
371
372
373
374
375
    paths.removeDuplicates();
    return paths;
}

QStringList GenericProject::projectIncludePaths() const
376
{ return m_projectIncludePaths; }
Roberto Raggi's avatar
Roberto Raggi committed
377

Roberto Raggi's avatar
Roberto Raggi committed
378
QStringList GenericProject::files() const
379
{ return m_files; }
Roberto Raggi's avatar
Roberto Raggi committed
380
381

QStringList GenericProject::generated() const
382
{ return m_generated; }
Roberto Raggi's avatar
Roberto Raggi committed
383
384

QStringList GenericProject::includePaths() const
385
{ return m_includePaths; }
Roberto Raggi's avatar
Roberto Raggi committed
386
387

void GenericProject::setIncludePaths(const QStringList &includePaths)
388
{ m_includePaths = includePaths; }
Roberto Raggi's avatar
Roberto Raggi committed
389

Roberto Raggi's avatar
Roberto Raggi committed
390
QByteArray GenericProject::defines() const
391
{ return m_defines; }
Roberto Raggi's avatar
Roberto Raggi committed
392

393
void GenericProject::setToolChainType(ProjectExplorer::ToolChain::ToolChainType type)
Roberto Raggi's avatar
Roberto Raggi committed
394
395
396
{
    using namespace ProjectExplorer;

397
    m_toolChainType = type;
398

399
400
    delete m_toolChain;
    m_toolChain = 0;
Roberto Raggi's avatar
Roberto Raggi committed
401

402
    if (type == ToolChain::MinGW) {
Roberto Raggi's avatar
Roberto Raggi committed
403
404
405
        const QLatin1String qmake_cxx("g++"); // ### FIXME
        const QString mingwDirectory; // ### FIXME

406
        m_toolChain = ToolChain::createMinGWToolChain(qmake_cxx, mingwDirectory);
Roberto Raggi's avatar
Roberto Raggi committed
407

408
    } else if (type == ToolChain::MSVC) {
Roberto Raggi's avatar
Roberto Raggi committed
409
        const QString msvcVersion; // ### FIXME
410
        m_toolChain = ToolChain::createMSVCToolChain(msvcVersion, false);
Roberto Raggi's avatar
Roberto Raggi committed
411

412
    } else if (type == ToolChain::WINCE) {
Roberto Raggi's avatar
Roberto Raggi committed
413
        const QString msvcVersion, wincePlatform; // ### FIXME
414
        m_toolChain = ToolChain::createWinCEToolChain(msvcVersion, wincePlatform);
Roberto Raggi's avatar
Roberto Raggi committed
415

416
    } else if (type == ToolChain::GCC || type == ToolChain::GCC) {
Roberto Raggi's avatar
Roberto Raggi committed
417
        const QLatin1String qmake_cxx("g++"); // ### FIXME
418
        m_toolChain = ToolChain::createGccToolChain(qmake_cxx);
Roberto Raggi's avatar
Roberto Raggi committed
419
420
421
    }
}

422
QString GenericProject::buildParser(BuildConfiguration *configuration) const
Roberto Raggi's avatar
Roberto Raggi committed
423
{
424
    Q_UNUSED(configuration)
425
426
    if (m_toolChain) {
        switch (m_toolChain->type()) {
Roberto Raggi's avatar
Roberto Raggi committed
427
        case ProjectExplorer::ToolChain::GCC:
428
        //case ProjectExplorer::ToolChain::LinuxICC:
Roberto Raggi's avatar
Roberto Raggi committed
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
        case ProjectExplorer::ToolChain::MinGW:
            return QLatin1String(ProjectExplorer::Constants::BUILD_PARSER_GCC);

        case ProjectExplorer::ToolChain::MSVC:
        case ProjectExplorer::ToolChain::WINCE:
            return ProjectExplorer::Constants::BUILD_PARSER_MSVC;

        default:
            break;
        } // switch
    }

    return QString();
}

444
445
446
447
448
ProjectExplorer::ToolChain *GenericProject::toolChain() const
{
    return m_toolChain;
}

449
450
ProjectExplorer::ToolChain::ToolChainType GenericProject::toolChainType() const
{ return m_toolChainType; }
451

Roberto Raggi's avatar
Roberto Raggi committed
452
453
QString GenericProject::name() const
{
454
    return m_projectName;
Roberto Raggi's avatar
Roberto Raggi committed
455
456
457
458
}

Core::IFile *GenericProject::file() const
{
459
    return m_file;
Roberto Raggi's avatar
Roberto Raggi committed
460
461
462
463
}

ProjectExplorer::IProjectManager *GenericProject::projectManager() const
{
464
    return m_manager;
Roberto Raggi's avatar
Roberto Raggi committed
465
466
467
468
469
470
471
472
473
474
475
476
}

QList<ProjectExplorer::Project *> GenericProject::dependsOn()
{
    return QList<Project *>();
}

bool GenericProject::isApplication() const
{
    return true;
}

477
ProjectExplorer::Environment GenericProject::environment(BuildConfiguration *configuration) const
Roberto Raggi's avatar
Roberto Raggi committed
478
{
479
    Q_UNUSED(configuration)
Roberto Raggi's avatar
Roberto Raggi committed
480
481
482
    return ProjectExplorer::Environment::systemEnvironment();
}

483
QString GenericProject::buildDirectory(BuildConfiguration *configuration) const
Roberto Raggi's avatar
Roberto Raggi committed
484
{
485
    QString buildDirectory = configuration->value("buildDirectory").toString();
Roberto Raggi's avatar
Roberto Raggi committed
486
487

    if (buildDirectory.isEmpty()) {
488
        QFileInfo fileInfo(m_fileName);
Roberto Raggi's avatar
Roberto Raggi committed
489
490
491
492
493
494
495

        buildDirectory = fileInfo.absolutePath();
    }

    return buildDirectory;
}

dt's avatar
dt committed
496
ProjectExplorer::BuildConfigWidget *GenericProject::createConfigWidget()
Roberto Raggi's avatar
Roberto Raggi committed
497
498
499
500
{
    return new GenericBuildSettingsWidget(this);
}

dt's avatar
dt committed
501
QList<ProjectExplorer::BuildConfigWidget*> GenericProject::subConfigWidgets()
Roberto Raggi's avatar
Roberto Raggi committed
502
{
dt's avatar
dt committed
503
    return QList<ProjectExplorer::BuildConfigWidget*>();
Roberto Raggi's avatar
Roberto Raggi committed
504
505
}

506
GenericProjectNode *GenericProject::rootProjectNode() const
Roberto Raggi's avatar
Roberto Raggi committed
507
{
508
    return m_rootNode;
Roberto Raggi's avatar
Roberto Raggi committed
509
510
511
512
}

QStringList GenericProject::files(FilesMode fileMode) const
{
513
    Q_UNUSED(fileMode)
514
    return m_files; // ### TODO: handle generated files here.
Roberto Raggi's avatar
Roberto Raggi committed
515
516
517
518
519
520
521
522
523
524
}

QStringList GenericProject::targets() const
{
    QStringList targets;
    targets.append(QLatin1String("all"));
    targets.append(QLatin1String("clean"));
    return targets;
}

dt's avatar
dt committed
525
bool GenericProject::restoreSettingsImpl(ProjectExplorer::PersistentSettingsReader &reader)
Roberto Raggi's avatar
Roberto Raggi committed
526
527
528
529
{
    Project::restoreSettingsImpl(reader);

    if (buildConfigurations().isEmpty()) {
dt's avatar
dt committed
530
        GenericBuildConfiguration *bc = new GenericBuildConfiguration("all");
531
        addBuildConfiguration(bc);
Roberto Raggi's avatar
Roberto Raggi committed
532

533
534
        GenericMakeStep *makeStep = new GenericMakeStep(this, bc);
        bc->insertBuildStep(0, makeStep);
Roberto Raggi's avatar
Roberto Raggi committed
535

536
        makeStep->setBuildTarget("all", /* on = */ true);
Roberto Raggi's avatar
Roberto Raggi committed
537
538
539
540

        const QLatin1String buildDirectory("buildDirectory");

        const QFileInfo fileInfo(file()->fileName());
541
        bc->setValue(buildDirectory, fileInfo.absolutePath());
542
543

        setActiveBuildConfiguration(bc);
Roberto Raggi's avatar
Roberto Raggi committed
544
    }
545

546
547
548
    using namespace ProjectExplorer;
    QString toolChainName = reader.restoreValue(QLatin1String("toolChain")).toString();
    bool convertible = false;
549
    ToolChain::ToolChainType type = ToolChain::ToolChainType(toolChainName.toInt(&convertible));
550
551
552
    if (!convertible) {
        // legacy string values
        if (toolChainName == QLatin1String("gcc"))
553
            type = ToolChain::GCC;
554
        else if (toolChainName == QLatin1String("mingw"))
555
            type = ToolChain::MinGW;
556
        else if (toolChainName == QLatin1String("msvc"))
557
            type = ToolChain::MSVC;
558
        else if (toolChainName == QLatin1String("wince"))
559
            type = ToolChain::WINCE;
560
    }
561

562
    setToolChainType(type); // ### move
Roberto Raggi's avatar
Roberto Raggi committed
563
564
565
566
567

    const QStringList userIncludePaths =
            reader.restoreValue(QLatin1String("includePaths")).toStringList();

    setIncludePaths(allIncludePaths());
568

569
    refresh(Everything);
dt's avatar
dt committed
570
    return true;
571
572
573
574
575
576
}

void GenericProject::saveSettingsImpl(ProjectExplorer::PersistentSettingsWriter &writer)
{
    Project::saveSettingsImpl(writer);

577
    writer.saveValue(QLatin1String("toolChain"), m_toolChainType);
578
    writer.saveValue(QLatin1String("includePaths"), m_includePaths);
Roberto Raggi's avatar
Roberto Raggi committed
579
580
581
582
583
}

////////////////////////////////////////////////////////////////////////////////////
// GenericBuildSettingsWidget
////////////////////////////////////////////////////////////////////////////////////
584

Roberto Raggi's avatar
Roberto Raggi committed
585
GenericBuildSettingsWidget::GenericBuildSettingsWidget(GenericProject *project)
586
    : m_project(project)
Roberto Raggi's avatar
Roberto Raggi committed
587
588
{
    QFormLayout *fl = new QFormLayout(this);
589
590
    fl->setContentsMargins(0, -1, 0, -1);
    fl->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow);
591
592

    // build directory
593
    m_pathChooser = new Utils::PathChooser(this);
594
595
    m_pathChooser->setEnabled(true);
    fl->addRow(tr("Build directory:"), m_pathChooser);
con's avatar
con committed
596
    connect(m_pathChooser, SIGNAL(changed(QString)), this, SLOT(buildDirectoryChanged()));
597

598
    // tool chain
599
    QComboBox *toolChainChooser = new QComboBox;
600
    toolChainChooser->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
601
    using namespace ProjectExplorer;
602
603
    int index = 0;
    int selectedIndex = -1;
604
    foreach (ToolChain::ToolChainType tc, ToolChain::supportedToolChains()) {
605
606
607
608
        toolChainChooser->addItem(ToolChain::toolChainName(tc), QVariant::fromValue<ToolChain::ToolChainType>(tc));
        if (m_project->toolChainType() == tc)
            selectedIndex = index;
        ++index;
609
610
    }

611
    toolChainChooser->setCurrentIndex(selectedIndex);
612
    fl->addRow(tr("Tool Chain:"), toolChainChooser);
613
    connect(toolChainChooser, SIGNAL(activated(int)), this, SLOT(toolChainSelected(int)));
Roberto Raggi's avatar
Roberto Raggi committed
614
615
616
617
618
619
620
621
}

GenericBuildSettingsWidget::~GenericBuildSettingsWidget()
{ }

QString GenericBuildSettingsWidget::displayName() const
{ return tr("Generic Manager"); }

622
void GenericBuildSettingsWidget::init(const QString &buildConfigurationName)
Roberto Raggi's avatar
Roberto Raggi committed
623
{
624
625
    m_buildConfiguration = buildConfigurationName;
    m_pathChooser->setPath(m_project->buildDirectory(m_project->buildConfiguration(buildConfigurationName)));
Roberto Raggi's avatar
Roberto Raggi committed
626
627
628
629
}

void GenericBuildSettingsWidget::buildDirectoryChanged()
{
630
    m_project->buildConfiguration(m_buildConfiguration)->setValue("buildDirectory", m_pathChooser->path());
Roberto Raggi's avatar
Roberto Raggi committed
631
632
}

633
634
635
636
637
638
639
640
641
void GenericBuildSettingsWidget::toolChainSelected(int index)
{
    using namespace ProjectExplorer;

    QComboBox *toolChainChooser = qobject_cast<QComboBox*>(sender());
    ToolChain::ToolChainType type = toolChainChooser->itemData(index).value<ToolChain::ToolChainType>();
    m_project->setToolChainType(type);
}

Roberto Raggi's avatar
Roberto Raggi committed
642
643
644
////////////////////////////////////////////////////////////////////////////////////
// GenericProjectFile
////////////////////////////////////////////////////////////////////////////////////
645

Roberto Raggi's avatar
Roberto Raggi committed
646
647
GenericProjectFile::GenericProjectFile(GenericProject *parent, QString fileName)
    : Core::IFile(parent),
648
649
      m_project(parent),
      m_fileName(fileName)
Roberto Raggi's avatar
Roberto Raggi committed
650
651
652
653
654
655
656
657
658
659
660
661
{ }

GenericProjectFile::~GenericProjectFile()
{ }

bool GenericProjectFile::save(const QString &)
{
    return false;
}

QString GenericProjectFile::fileName() const
{
662
    return m_fileName;
Roberto Raggi's avatar
Roberto Raggi committed
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
}

QString GenericProjectFile::defaultPath() const
{
    return QString();
}

QString GenericProjectFile::suggestedFileName() const
{
    return QString();
}

QString GenericProjectFile::mimeType() const
{
    return Constants::GENERICMIMETYPE;
}

bool GenericProjectFile::isModified() const
{
    return false;
}

bool GenericProjectFile::isReadOnly() const
{
    return true;
}

bool GenericProjectFile::isSaveAsAllowed() const
{
    return false;
}

void GenericProjectFile::modified(ReloadBehavior *)
{
}