genericproject.cpp 19.7 KB
Newer Older
Roberto Raggi's avatar
Roberto Raggi committed
1
2
3
4
/**************************************************************************
**
** This file is part of Qt Creator
**
con's avatar
con committed
5
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
Roberto Raggi's avatar
Roberto Raggi committed
6
**
7
** Contact: Nokia Corporation (qt-info@nokia.com)
Roberto Raggi's avatar
Roberto Raggi committed
8
9
10
11
**
**
** GNU Lesser General Public License Usage
**
hjk's avatar
hjk committed
12
13
14
15
16
17
** 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.
Roberto Raggi's avatar
Roberto Raggi committed
18
**
con's avatar
con committed
19
** In addition, as a special exception, Nokia gives you certain additional
hjk's avatar
hjk committed
20
** rights. These rights are described in the Nokia Qt LGPL Exception
con's avatar
con committed
21
22
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
hjk's avatar
hjk committed
23
24
25
26
27
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
con's avatar
con committed
28
** If you have questions regarding the use of this file, please contact
29
** Nokia at qt-info@nokia.com.
Roberto Raggi's avatar
Roberto Raggi committed
30
31
32
33
**
**************************************************************************/

#include "genericproject.h"
Tobias Hunger's avatar
Tobias Hunger committed
34

dt's avatar
dt committed
35
#include "genericbuildconfiguration.h"
Tobias Hunger's avatar
Tobias Hunger committed
36
37
#include "genericprojectconstants.h"
#include "generictarget.h"
Roberto Raggi's avatar
Roberto Raggi committed
38

39
#include <projectexplorer/abi.h>
40
#include <projectexplorer/buildenvironmentwidget.h>
41
#include <projectexplorer/headerpath.h>
42
#include <projectexplorer/customexecutablerunconfiguration.h>
43
#include <projectexplorer/toolchainmanager.h>
Roberto Raggi's avatar
Roberto Raggi committed
44
#include <projectexplorer/projectexplorerconstants.h>
45
#include <cplusplus/ModelManagerInterface.h>
Roberto Raggi's avatar
Roberto Raggi committed
46
#include <extensionsystem/pluginmanager.h>
47
#include <utils/pathchooser.h>
hjk's avatar
hjk committed
48
#include <utils/qtcassert.h>
49
#include <utils/fileutils.h>
Roberto Raggi's avatar
Roberto Raggi committed
50
#include <coreplugin/icore.h>
51
#include <coreplugin/icontext.h>
52
#include <coreplugin/filemanager.h>
Roberto Raggi's avatar
Roberto Raggi committed
53

54
#include <QtCore/QDir>
55
#include <QtCore/QProcessEnvironment>
Roberto Raggi's avatar
Roberto Raggi committed
56

57
58
59
#include <QtGui/QFormLayout>
#include <QtGui/QMainWindow>
#include <QtGui/QComboBox>
Roberto Raggi's avatar
Roberto Raggi committed
60
61
62

using namespace GenericProjectManager;
using namespace GenericProjectManager::Internal;
63
using namespace ProjectExplorer;
Roberto Raggi's avatar
Roberto Raggi committed
64

65
namespace {
66
const char * const TOOLCHAIN_KEY("GenericProjectManager.GenericProject.Toolchain");
67
68
} // end of anonymous namespace

69
70
71
72
////////////////////////////////////////////////////////////////////////////////////
// GenericProject
////////////////////////////////////////////////////////////////////////////////////

Roberto Raggi's avatar
Roberto Raggi committed
73
GenericProject::GenericProject(Manager *manager, const QString &fileName)
74
75
76
    : m_manager(manager),
      m_fileName(fileName),
      m_toolChain(0)
Roberto Raggi's avatar
Roberto Raggi committed
77
{
78
79
80
    setProjectContext(Core::Context(GenericProjectManager::Constants::PROJECTCONTEXT));
    setProjectLanguage(Core::Context(ProjectExplorer::Constants::LANG_CXX));

81
    QFileInfo fileInfo(m_fileName);
82
83
    QDir dir = fileInfo.dir();

84
    m_projectName      = fileInfo.completeBaseName();
85
86
87
    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();
88

89
90
91
92
93
    m_creatorIFile  = new GenericProjectFile(this, m_fileName, GenericProject::Everything);
    m_filesIFile    = new GenericProjectFile(this, m_filesFileName, GenericProject::Files);
    m_includesIFile = new GenericProjectFile(this, m_includesFileName, GenericProject::Configuration);
    m_configIFile   = new GenericProjectFile(this, m_configFileName, GenericProject::Configuration);

94
95
96
97
    Core::FileManager::addFile(m_creatorIFile);
    Core::FileManager::addFile(m_filesIFile);
    Core::FileManager::addFile(m_includesIFile);
    Core::FileManager::addFile(m_configIFile);
98
99

    m_rootNode = new GenericProjectNode(this, m_creatorIFile);
100

101
    m_manager->registerProject(this);
Roberto Raggi's avatar
Roberto Raggi committed
102
103
104
105
}

GenericProject::~GenericProject()
{
106
    m_codeModelFuture.cancel();
107
    m_manager->unregisterProject(this);
108

109
    delete m_rootNode;
110
    // do not delete m_toolChain
Roberto Raggi's avatar
Roberto Raggi committed
111
112
}

Tobias Hunger's avatar
Tobias Hunger committed
113
GenericTarget *GenericProject::activeTarget() const
114
{
Tobias Hunger's avatar
Tobias Hunger committed
115
    return static_cast<GenericTarget *>(Project::activeTarget());
116
117
}

118
QString GenericProject::filesFileName() const
hjk's avatar
hjk committed
119
120
121
{
    return m_filesFileName;
}
122
123

QString GenericProject::includesFileName() const
hjk's avatar
hjk committed
124
125
126
{
    return m_includesFileName;
}
127
128

QString GenericProject::configFileName() const
hjk's avatar
hjk committed
129
130
131
{
    return m_configFileName;
}
132

133
static QStringList readLines(const QString &absoluteFileName)
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
{
    QStringList lines;

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

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

            lines.append(line);
        }
    }

    return lines;
}

153
bool GenericProject::saveRawFileList(const QStringList &rawFileList)
154
{
155
    // Make sure we can open the file for writing
156
157
158
159
160
161
162
    Utils::FileSaver saver(filesFileName(), QIODevice::Text);
    if (!saver.hasError()) {
        QTextStream stream(saver.file());
        foreach (const QString &filePath, rawFileList)
            stream << filePath << QLatin1Char('\n');
        saver.setResult(&stream);
    }
hjk's avatar
hjk committed
163
    if (!saver.finalize(Core::ICore::mainWindow()))
164
165
166
        return false;
    refresh(GenericProject::Files);
    return true;
167
}
168

169
170
bool GenericProject::addFiles(const QStringList &filePaths)
{
171
172
173
174
175
    QStringList newList = m_rawFileList;

    QDir baseDir(QFileInfo(m_fileName).dir());
    foreach (const QString &filePath, filePaths)
        newList.append(baseDir.relativeFilePath(filePath));
176

177
    return saveRawFileList(newList);
178
179
180
181
}

bool GenericProject::removeFiles(const QStringList &filePaths)
{
182
    QStringList newList = m_rawFileList;
183

184
185
186
187
    foreach (const QString &filePath, filePaths) {
        QHash<QString, QString>::iterator i = m_rawListEntries.find(filePath);
        if (i != m_rawListEntries.end())
            newList.removeOne(i.value());
188
    }
189

190
    return saveRawFileList(newList);
191
192
}

193
194
195
196
197
198
199
200
201
202
bool GenericProject::setFiles(const QStringList &filePaths)
{
    QStringList newList;
    QDir baseDir(QFileInfo(m_fileName).dir());
    foreach (const QString &filePath, filePaths)
        newList.append(baseDir.relativeFilePath(filePath));

    return saveRawFileList(newList);
}

203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
bool GenericProject::renameFile(const QString &filePath, const QString &newFilePath)
{
    QStringList newList = m_rawFileList;

    QHash<QString, QString>::iterator i = m_rawListEntries.find(filePath);
    if (i != m_rawListEntries.end()) {
        int index = newList.indexOf(i.value());
        if (index != -1) {
            QDir baseDir(QFileInfo(m_fileName).dir());
            newList.replace(index, baseDir.relativeFilePath(newFilePath));
        }
    }

    return saveRawFileList(newList);
}

219
void GenericProject::parseProject(RefreshOptions options)
Roberto Raggi's avatar
Roberto Raggi committed
220
{
221
222
223
    if (options & Files) {
        m_rawListEntries.clear();
        m_rawFileList = readLines(filesFileName());
224
        m_files = processEntries(m_rawFileList, &m_rawListEntries);
225
    }
226

227
    if (options & Configuration) {
228
        m_projectIncludePaths = processEntries(readLines(includesFileName()));
229

230
231
        // TODO: Possibly load some configuration from the project file
        //QSettings projectInfo(m_fileName, QSettings::IniFormat);
Roberto Raggi's avatar
Roberto Raggi committed
232

233
        m_defines.clear();
Roberto Raggi's avatar
Roberto Raggi committed
234

235
236
237
238
        QFile configFile(configFileName());
        if (configFile.open(QFile::ReadOnly))
            m_defines = configFile.readAll();
    }
239

240
241
    if (options & Files)
        emit fileListChanged();
Roberto Raggi's avatar
Roberto Raggi committed
242
243
}

244
void GenericProject::refresh(RefreshOptions options)
Roberto Raggi's avatar
Roberto Raggi committed
245
{
246
247
248
    QSet<QString> oldFileList;
    if (!(options & Configuration))
        oldFileList = m_files.toSet();
249

250
251
252
253
    parseProject(options);

    if (options & Files)
        m_rootNode->refresh();
Roberto Raggi's avatar
Roberto Raggi committed
254

255
    CPlusPlus::CppModelManagerInterface *modelManager =
256
        CPlusPlus::CppModelManagerInterface::instance();
Roberto Raggi's avatar
Roberto Raggi committed
257

258
    if (modelManager) {
259
        CPlusPlus::CppModelManagerInterface::ProjectInfo pinfo = modelManager->projectInfo(this);
Roberto Raggi's avatar
Roberto Raggi committed
260

261
262
263
        if (m_toolChain) {
            pinfo.defines = m_toolChain->predefinedMacros();
            pinfo.defines += '\n';
Roberto Raggi's avatar
Roberto Raggi committed
264

265
266
267
268
269
270
            foreach (const HeaderPath &headerPath, m_toolChain->systemHeaderPaths()) {
                if (headerPath.kind() == HeaderPath::FrameworkHeaderPath)
                    pinfo.frameworkPaths.append(headerPath.path());
                else
                    pinfo.includePaths.append(headerPath.path());
            }
Roberto Raggi's avatar
Roberto Raggi committed
271
272
        }

273
274
        pinfo.includePaths += allIncludePaths();
        pinfo.defines += m_defines;
Roberto Raggi's avatar
Roberto Raggi committed
275
276

        // ### add _defines.
Roberto Raggi's avatar
Roberto Raggi committed
277
278
        pinfo.sourceFiles = files();
        pinfo.sourceFiles += generated();
Roberto Raggi's avatar
Roberto Raggi committed
279

280
281
282
283
284
        QStringList filesToUpdate;

        if (options & Configuration) {
            filesToUpdate = pinfo.sourceFiles;
            filesToUpdate.append(QLatin1String("<configuration>")); // XXX don't hardcode configuration file name
285
286
            // Full update, if there's a code model update, cancel it
            m_codeModelFuture.cancel();
287
288
289
290
291
292
        } 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());
        }
293

Roberto Raggi's avatar
Roberto Raggi committed
294
        modelManager->updateProjectInfo(pinfo);
295
        m_codeModelFuture = modelManager->updateSourceFiles(filesToUpdate);
Roberto Raggi's avatar
Roberto Raggi committed
296
297
298
    }
}

299
/**
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
 * Expands environment variables in the given \a string when they are written
 * like $$(VARIABLE).
 */
static void expandEnvironmentVariables(const QProcessEnvironment &env, QString &string)
{
    const static QRegExp candidate(QLatin1String("\\$\\$\\((.+)\\)"));

    int index = candidate.indexIn(string);
    while (index != -1) {
        const QString value = env.value(candidate.cap(1));

        string.replace(index, candidate.matchedLength(), value);
        index += value.length();

        index = candidate.indexIn(string, index);
    }
}

/**
 * Expands environment variables and converts the path from relative to the
 * project to an absolute path.
 *
322
 * The \a map variable is an optional argument that will map the returned
323
 * absolute paths back to their original \a entries.
324
 */
325
326
QStringList GenericProject::processEntries(const QStringList &paths,
                                           QHash<QString, QString> *map) const
Roberto Raggi's avatar
Roberto Raggi committed
327
{
328
    const QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
329
    const QDir projectDir(QFileInfo(m_fileName).dir());
330

Roberto Raggi's avatar
Roberto Raggi committed
331
    QStringList absolutePaths;
332
    foreach (const QString &path, paths) {
333
334
        QString trimmedPath = path.trimmed();
        if (trimmedPath.isEmpty())
335
336
            continue;

337
338
339
        expandEnvironmentVariables(env, trimmedPath);

        const QString absPath = QFileInfo(projectDir, trimmedPath).absoluteFilePath();
340
341
        absolutePaths.append(absPath);
        if (map)
342
            map->insert(absPath, trimmedPath);
Roberto Raggi's avatar
Roberto Raggi committed
343
344
345
346
347
    }
    absolutePaths.removeDuplicates();
    return absolutePaths;
}

Roberto Raggi's avatar
Roberto Raggi committed
348
349
350
QStringList GenericProject::allIncludePaths() const
{
    QStringList paths;
351
352
    paths += m_includePaths;
    paths += m_projectIncludePaths;
Roberto Raggi's avatar
Roberto Raggi committed
353
354
355
356
357
    paths.removeDuplicates();
    return paths;
}

QStringList GenericProject::projectIncludePaths() const
hjk's avatar
hjk committed
358
359
360
{
    return m_projectIncludePaths;
}
Roberto Raggi's avatar
Roberto Raggi committed
361

Roberto Raggi's avatar
Roberto Raggi committed
362
QStringList GenericProject::files() const
hjk's avatar
hjk committed
363
364
365
{
    return m_files;
}
Roberto Raggi's avatar
Roberto Raggi committed
366
367

QStringList GenericProject::generated() const
hjk's avatar
hjk committed
368
369
370
{
    return m_generated;
}
Roberto Raggi's avatar
Roberto Raggi committed
371
372

QStringList GenericProject::includePaths() const
hjk's avatar
hjk committed
373
374
375
{
    return m_includePaths;
}
Roberto Raggi's avatar
Roberto Raggi committed
376
377

void GenericProject::setIncludePaths(const QStringList &includePaths)
hjk's avatar
hjk committed
378
379
380
{
    m_includePaths = includePaths;
}
Roberto Raggi's avatar
Roberto Raggi committed
381

Roberto Raggi's avatar
Roberto Raggi committed
382
QByteArray GenericProject::defines() const
hjk's avatar
hjk committed
383
384
385
{
    return m_defines;
}
Roberto Raggi's avatar
Roberto Raggi committed
386

387
void GenericProject::setToolChain(ToolChain *tc)
Roberto Raggi's avatar
Roberto Raggi committed
388
{
389
390
    if (m_toolChain == tc)
        return;
Roberto Raggi's avatar
Roberto Raggi committed
391

392
    m_toolChain = tc;
393
394
    refresh(Configuration);

395
396
397
398
399
    foreach (Target *t, targets()) {
        foreach (BuildConfiguration *bc, t->buildConfigurations())
            bc->setToolChain(tc);
    }

400
    emit toolChainChanged(m_toolChain);
Roberto Raggi's avatar
Roberto Raggi committed
401
402
}

403
ToolChain *GenericProject::toolChain() const
404
405
406
407
{
    return m_toolChain;
}

408
QString GenericProject::displayName() const
Roberto Raggi's avatar
Roberto Raggi committed
409
{
410
    return m_projectName;
Roberto Raggi's avatar
Roberto Raggi committed
411
412
}

Tobias Hunger's avatar
Tobias Hunger committed
413
414
QString GenericProject::id() const
{
Tobias Hunger's avatar
Tobias Hunger committed
415
    return QLatin1String(Constants::GENERICPROJECT_ID);
Tobias Hunger's avatar
Tobias Hunger committed
416
417
}

Roberto Raggi's avatar
Roberto Raggi committed
418
419
Core::IFile *GenericProject::file() const
{
420
    return m_creatorIFile;
Roberto Raggi's avatar
Roberto Raggi committed
421
422
}

423
IProjectManager *GenericProject::projectManager() const
Roberto Raggi's avatar
Roberto Raggi committed
424
{
425
    return m_manager;
Roberto Raggi's avatar
Roberto Raggi committed
426
427
}

428
QList<Project *> GenericProject::dependsOn()
Roberto Raggi's avatar
Roberto Raggi committed
429
430
431
432
{
    return QList<Project *>();
}

433
QList<BuildConfigWidget*> GenericProject::subConfigWidgets()
Roberto Raggi's avatar
Roberto Raggi committed
434
{
435
    QList<BuildConfigWidget*> list;
436
437
    list << new BuildEnvironmentWidget;
    return list;
Roberto Raggi's avatar
Roberto Raggi committed
438
439
}

440
GenericProjectNode *GenericProject::rootProjectNode() const
Roberto Raggi's avatar
Roberto Raggi committed
441
{
442
    return m_rootNode;
Roberto Raggi's avatar
Roberto Raggi committed
443
444
445
446
}

QStringList GenericProject::files(FilesMode fileMode) const
{
447
    Q_UNUSED(fileMode)
448
    return m_files; // ### TODO: handle generated files here.
Roberto Raggi's avatar
Roberto Raggi committed
449
450
}

Tobias Hunger's avatar
Tobias Hunger committed
451
QStringList GenericProject::buildTargets() const
Roberto Raggi's avatar
Roberto Raggi committed
452
453
454
455
456
457
458
{
    QStringList targets;
    targets.append(QLatin1String("all"));
    targets.append(QLatin1String("clean"));
    return targets;
}

459
QVariantMap GenericProject::toMap() const
Roberto Raggi's avatar
Roberto Raggi committed
460
{
461
    QVariantMap map(Project::toMap());
462
    map.insert(QLatin1String(TOOLCHAIN_KEY), m_toolChain ? m_toolChain->id() : QString());
463
464
465
466
467
468
469
    return map;
}

bool GenericProject::fromMap(const QVariantMap &map)
{
    if (!Project::fromMap(map))
        return false;
Roberto Raggi's avatar
Roberto Raggi committed
470

471
472
473
474
475
476
477
478
479
    // Sanity check: We need both a buildconfiguration and a runconfiguration!
    QList<Target *> targetList = targets();
    foreach (Target *t, targetList) {
        if (!t->activeBuildConfiguration()) {
            removeTarget(t);
            delete t;
            continue;
        }
        if (!t->activeRunConfiguration())
480
            t->addRunConfiguration(new CustomExecutableRunConfiguration(t));
481
482
483
    }

    // Add default setup:
484
485
486
487
488
    if (targets().isEmpty()) {
        GenericTargetFactory *factory =
                ExtensionSystem::PluginManager::instance()->getObject<GenericTargetFactory>();
        addTarget(factory->create(this, QLatin1String(GENERIC_DESKTOP_TARGET_ID)));
    }
489

490
    QString id = map.value(QLatin1String(TOOLCHAIN_KEY)).toString();
491
492
    const ToolChainManager *toolChainManager = ToolChainManager::instance();

493
    if (!id.isNull()) {
494
        setToolChain(toolChainManager->findToolChain(id));
495
    } else {
496
497
498
499
        ProjectExplorer::Abi abi = ProjectExplorer::Abi::hostAbi();
        abi = ProjectExplorer::Abi(abi.architecture(), abi.os(),  ProjectExplorer::Abi::UnknownFlavor,
                                   abi.binaryFormat(), abi.wordWidth() == 32 ? 32 : 0);
        QList<ToolChain *> tcs = toolChainManager->findToolChains(abi);
500
        if (tcs.isEmpty())
501
            tcs = toolChainManager->toolChains();
502
503
504
        if (!tcs.isEmpty())
            setToolChain(tcs.at(0));
    }
Roberto Raggi's avatar
Roberto Raggi committed
505
506

    setIncludePaths(allIncludePaths());
507

508
    refresh(Everything);
dt's avatar
dt committed
509
    return true;
510
511
}

Roberto Raggi's avatar
Roberto Raggi committed
512
513
514
////////////////////////////////////////////////////////////////////////////////////
// GenericBuildSettingsWidget
////////////////////////////////////////////////////////////////////////////////////
515

516
GenericBuildSettingsWidget::GenericBuildSettingsWidget(GenericTarget *target)
517
    : m_target(target), m_toolChainChooser(0), m_buildConfiguration(0)
Roberto Raggi's avatar
Roberto Raggi committed
518
519
{
    QFormLayout *fl = new QFormLayout(this);
520
521
    fl->setContentsMargins(0, -1, 0, -1);
    fl->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow);
522
523

    // build directory
524
    m_pathChooser = new Utils::PathChooser(this);
525
    m_pathChooser->setEnabled(true);
526
    m_pathChooser->setBaseDirectory(m_target->genericProject()->projectDirectory());
527
    fl->addRow(tr("Build directory:"), m_pathChooser);
con's avatar
con committed
528
    connect(m_pathChooser, SIGNAL(changed(QString)), this, SLOT(buildDirectoryChanged()));
529

530
    // tool chain
531
532
533
534
535
536
537
538
    m_toolChainChooser = new QComboBox;
    m_toolChainChooser->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
    updateToolChainList();

    fl->addRow(tr("Tool chain:"), m_toolChainChooser);
    connect(m_toolChainChooser, SIGNAL(activated(int)), this, SLOT(toolChainSelected(int)));
    connect(m_target->genericProject(), SIGNAL(toolChainChanged(ProjectExplorer::ToolChain*)),
            this, SLOT(toolChainChanged(ProjectExplorer::ToolChain*)));
539
    connect(ProjectExplorer::ToolChainManager::instance(), SIGNAL(toolChainAdded(ProjectExplorer::ToolChain*)),
540
            this, SLOT(updateToolChainList()));
541
    connect(ProjectExplorer::ToolChainManager::instance(), SIGNAL(toolChainRemoved(ProjectExplorer::ToolChain*)),
542
            this, SLOT(updateToolChainList()));
Roberto Raggi's avatar
Roberto Raggi committed
543
544
545
546
547
548
549
550
}

GenericBuildSettingsWidget::~GenericBuildSettingsWidget()
{ }

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

dt's avatar
dt committed
551
void GenericBuildSettingsWidget::init(BuildConfiguration *bc)
Roberto Raggi's avatar
Roberto Raggi committed
552
{
553
    m_buildConfiguration = static_cast<GenericBuildConfiguration *>(bc);
554
    m_pathChooser->setPath(m_buildConfiguration->rawBuildDirectory());
Roberto Raggi's avatar
Roberto Raggi committed
555
556
557
558
}

void GenericBuildSettingsWidget::buildDirectoryChanged()
{
559
    m_buildConfiguration->setBuildDirectory(m_pathChooser->rawPath());
Roberto Raggi's avatar
Roberto Raggi committed
560
561
}

562
563
564
565
void GenericBuildSettingsWidget::toolChainSelected(int index)
{
    using namespace ProjectExplorer;

566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
    ToolChain *tc = static_cast<ToolChain *>(m_toolChainChooser->itemData(index).value<void *>());
    m_target->genericProject()->setToolChain(tc);
}

void GenericBuildSettingsWidget::toolChainChanged(ProjectExplorer::ToolChain *tc)
{
    for (int i = 0; i < m_toolChainChooser->count(); ++i) {
        ToolChain * currentTc = static_cast<ToolChain *>(m_toolChainChooser->itemData(i).value<void *>());
        if (currentTc != tc)
            continue;
        m_toolChainChooser->setCurrentIndex(i);
        return;
    }
}

void GenericBuildSettingsWidget::updateToolChainList()
{
    m_toolChainChooser->clear();

    QList<ToolChain *> tcs = ToolChainManager::instance()->toolChains();
    if (!m_target->genericProject()->toolChain()) {
587
        m_toolChainChooser->addItem(tr("<Invalid tool chain>"), qVariantFromValue(static_cast<void *>(0)));
588
589
590
591
592
593
594
595
        m_toolChainChooser->setCurrentIndex(0);
    }
    foreach (ToolChain *tc, tcs) {
        m_toolChainChooser->addItem(tc->displayName(), qVariantFromValue(static_cast<void *>(tc)));
        if (m_target->genericProject()->toolChain()
                && m_target->genericProject()->toolChain()->id() == tc->id())
            m_toolChainChooser->setCurrentIndex(m_toolChainChooser->count() - 1);
    }
596
597
}

Roberto Raggi's avatar
Roberto Raggi committed
598
599
600
////////////////////////////////////////////////////////////////////////////////////
// GenericProjectFile
////////////////////////////////////////////////////////////////////////////////////
601

602
GenericProjectFile::GenericProjectFile(GenericProject *parent, QString fileName, GenericProject::RefreshOptions options)
Roberto Raggi's avatar
Roberto Raggi committed
603
    : Core::IFile(parent),
604
      m_project(parent),
605
606
      m_fileName(fileName),
      m_options(options)
Roberto Raggi's avatar
Roberto Raggi committed
607
608
609
610
611
{ }

GenericProjectFile::~GenericProjectFile()
{ }

612
bool GenericProjectFile::save(QString *, const QString &, bool)
Roberto Raggi's avatar
Roberto Raggi committed
613
614
615
616
617
618
{
    return false;
}

QString GenericProjectFile::fileName() const
{
619
    return m_fileName;
Roberto Raggi's avatar
Roberto Raggi committed
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
}

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

dt's avatar
dt committed
652
653
654
655
void GenericProjectFile::rename(const QString &newName)
{
    // Can't happen
    Q_UNUSED(newName);
656
    QTC_CHECK(false);
dt's avatar
dt committed
657
658
}

659
Core::IFile::ReloadBehavior GenericProjectFile::reloadBehavior(ChangeTrigger state, ChangeType type) const
Roberto Raggi's avatar
Roberto Raggi committed
660
{
661
662
663
664
665
    Q_UNUSED(state)
    Q_UNUSED(type)
    return BehaviorSilent;
}

666
bool GenericProjectFile::reload(QString *errorString, ReloadFlag flag, ChangeType type)
667
{
668
    Q_UNUSED(errorString)
669
    Q_UNUSED(flag)
670
671
672
    if (type == TypePermissions)
        return true;
    m_project->refresh(m_options);
673
    return true;
Roberto Raggi's avatar
Roberto Raggi committed
674
}