genericproject.cpp 17 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
**
**************************************************************************/

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

dt's avatar
dt committed
32
#include "genericbuildconfiguration.h"
Tobias Hunger's avatar
Tobias Hunger committed
33 34
#include "genericprojectconstants.h"
#include "generictarget.h"
Roberto Raggi's avatar
Roberto Raggi committed
35

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

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

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

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

63
namespace {
64
const char * const TOOLCHAIN_KEY("GenericProjectManager.GenericProject.Toolchain");
65

66 67 68 69
/**
 * An editable string list model. New strings can be added by editing the entry
 * called "<new>", displayed at the end.
 */
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
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())
96
                return QCoreApplication::translate("GenericProject", "<new>");
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
        }

        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

113 114 115 116
////////////////////////////////////////////////////////////////////////////////////
// GenericProject
////////////////////////////////////////////////////////////////////////////////////

Roberto Raggi's avatar
Roberto Raggi committed
117
GenericProject::GenericProject(Manager *manager, const QString &fileName)
118 119
    : m_manager(manager),
      m_fileName(fileName),
Tobias Hunger's avatar
Tobias Hunger committed
120
      m_targetFactory(new GenericTargetFactory(this)),
121
      m_toolChain(0)
Roberto Raggi's avatar
Roberto Raggi committed
122
{
123
    QFileInfo fileInfo(m_fileName);
124 125
    QDir dir = fileInfo.dir();

126
    m_projectName      = fileInfo.completeBaseName();
127 128 129
    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();
130

131 132
    m_file = new GenericProjectFile(this, fileName);
    m_rootNode = new GenericProjectNode(this, m_file);
133

134
    m_manager->registerProject(this);
Roberto Raggi's avatar
Roberto Raggi committed
135 136 137 138
}

GenericProject::~GenericProject()
{
139
    m_manager->unregisterProject(this);
140

141 142
    delete m_rootNode;
    delete m_toolChain;
Roberto Raggi's avatar
Roberto Raggi committed
143 144
}

Tobias Hunger's avatar
Tobias Hunger committed
145 146 147 148 149 150
GenericTargetFactory *GenericProject::targetFactory() const
{
    return m_targetFactory;
}

GenericTarget *GenericProject::activeTarget() const
151
{
Tobias Hunger's avatar
Tobias Hunger committed
152
    return static_cast<GenericTarget *>(Project::activeTarget());
153 154
}

155
QString GenericProject::filesFileName() const
156
{ return m_filesFileName; }
157 158

QString GenericProject::includesFileName() const
159
{ return m_includesFileName; }
160 161

QString GenericProject::configFileName() const
162
{ return m_configFileName; }
163

164
static QStringList readLines(const QString &absoluteFileName)
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183
{
    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;
}

184
bool GenericProject::saveRawFileList(const QStringList &rawFileList)
185
{
186
    // Make sure we can open the file for writing
187
    QFile file(filesFileName());
188 189 190 191
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
        return false;

    QTextStream stream(&file);
192 193
    foreach (const QString &filePath, rawFileList)
        stream << filePath << QLatin1Char('\n');
194 195 196 197

    file.close();
    refresh(GenericProject::Files);
    return true;
198
}
199

200 201
bool GenericProject::addFiles(const QStringList &filePaths)
{
202 203 204 205 206
    QStringList newList = m_rawFileList;

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

208
    return saveRawFileList(newList);
209 210 211 212
}

bool GenericProject::removeFiles(const QStringList &filePaths)
{
213
    QStringList newList = m_rawFileList;
214

215 216 217 218
    foreach (const QString &filePath, filePaths) {
        QHash<QString, QString>::iterator i = m_rawListEntries.find(filePath);
        if (i != m_rawListEntries.end())
            newList.removeOne(i.value());
219
    }
220

221
    return saveRawFileList(newList);
222 223
}

224
void GenericProject::parseProject(RefreshOptions options)
Roberto Raggi's avatar
Roberto Raggi committed
225
{
226 227 228 229 230
    if (options & Files) {
        m_rawListEntries.clear();
        m_rawFileList = readLines(filesFileName());
        m_files = convertToAbsoluteFiles(m_rawFileList, &m_rawListEntries);
    }
231

232
    if (options & Configuration) {
233
        m_projectIncludePaths = convertToAbsoluteFiles(readLines(includesFileName()));
234

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

238
        m_defines.clear();
Roberto Raggi's avatar
Roberto Raggi committed
239

240 241 242 243
        QFile configFile(configFileName());
        if (configFile.open(QFile::ReadOnly))
            m_defines = configFile.readAll();
    }
244

245 246
    if (options & Files)
        emit fileListChanged();
Roberto Raggi's avatar
Roberto Raggi committed
247 248
}

249
void GenericProject::refresh(RefreshOptions options)
Roberto Raggi's avatar
Roberto Raggi committed
250
{
251 252 253
    QSet<QString> oldFileList;
    if (!(options & Configuration))
        oldFileList = m_files.toSet();
254

255 256 257 258
    parseProject(options);

    if (options & Files)
        m_rootNode->refresh();
Roberto Raggi's avatar
Roberto Raggi committed
259 260 261 262

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

263 264
    if (m_toolChain && modelManager) {
        const QByteArray predefinedMacros = m_toolChain->predefinedMacros();
Roberto Raggi's avatar
Roberto Raggi committed
265 266 267

        CppTools::CppModelManagerInterface::ProjectInfo pinfo = modelManager->projectInfo(this);
        pinfo.defines = predefinedMacros;
Roberto Raggi's avatar
Roberto Raggi committed
268
        pinfo.defines += '\n';
269
        pinfo.defines += m_defines;
Roberto Raggi's avatar
Roberto Raggi committed
270

271 272
        QStringList allIncludePaths;
        QStringList allFrameworkPaths;
Roberto Raggi's avatar
Roberto Raggi committed
273

274
        foreach (const ProjectExplorer::HeaderPath &headerPath, m_toolChain->systemHeaderPaths()) {
Roberto Raggi's avatar
Roberto Raggi committed
275 276 277 278 279 280
            if (headerPath.kind() == ProjectExplorer::HeaderPath::FrameworkHeaderPath)
                allFrameworkPaths.append(headerPath.path());
            else
                allIncludePaths.append(headerPath.path());
        }

Roberto Raggi's avatar
Roberto Raggi committed
281
        allIncludePaths += this->allIncludePaths();
Roberto Raggi's avatar
Roberto Raggi committed
282 283 284 285 286

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

        // ### add _defines.
Roberto Raggi's avatar
Roberto Raggi committed
287 288
        pinfo.sourceFiles = files();
        pinfo.sourceFiles += generated();
Roberto Raggi's avatar
Roberto Raggi committed
289

290 291 292 293 294 295 296 297 298 299 300
        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());
        }
301

Roberto Raggi's avatar
Roberto Raggi committed
302
        modelManager->updateProjectInfo(pinfo);
303
        modelManager->updateSourceFiles(filesToUpdate);
Roberto Raggi's avatar
Roberto Raggi committed
304 305 306
    }
}

307 308 309 310 311 312
/**
 * The \a map variable is an optional argument that will map the returned
 * absolute paths back to their original \a paths.
 */
QStringList GenericProject::convertToAbsoluteFiles(const QStringList &paths,
                                                   QHash<QString, QString> *map) const
Roberto Raggi's avatar
Roberto Raggi committed
313
{
314
    const QDir projectDir(QFileInfo(m_fileName).dir());
Roberto Raggi's avatar
Roberto Raggi committed
315
    QStringList absolutePaths;
316 317 318 319 320 321 322 323
    foreach (const QString &path, paths) {
        if (path.trimmed().isEmpty())
            continue;

        const QString absPath = QFileInfo(projectDir, path).absoluteFilePath();
        absolutePaths.append(absPath);
        if (map)
            map->insert(absPath, path);
Roberto Raggi's avatar
Roberto Raggi committed
324 325 326 327 328
    }
    absolutePaths.removeDuplicates();
    return absolutePaths;
}

Roberto Raggi's avatar
Roberto Raggi committed
329 330 331
QStringList GenericProject::allIncludePaths() const
{
    QStringList paths;
332 333
    paths += m_includePaths;
    paths += m_projectIncludePaths;
Roberto Raggi's avatar
Roberto Raggi committed
334 335 336 337 338
    paths.removeDuplicates();
    return paths;
}

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

Roberto Raggi's avatar
Roberto Raggi committed
341
QStringList GenericProject::files() const
342
{ return m_files; }
Roberto Raggi's avatar
Roberto Raggi committed
343 344

QStringList GenericProject::generated() const
345
{ return m_generated; }
Roberto Raggi's avatar
Roberto Raggi committed
346 347

QStringList GenericProject::includePaths() const
348
{ return m_includePaths; }
Roberto Raggi's avatar
Roberto Raggi committed
349 350

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

Roberto Raggi's avatar
Roberto Raggi committed
353
QByteArray GenericProject::defines() const
354
{ return m_defines; }
Roberto Raggi's avatar
Roberto Raggi committed
355

356
void GenericProject::setToolChainType(ProjectExplorer::ToolChain::ToolChainType type)
Roberto Raggi's avatar
Roberto Raggi committed
357 358 359
{
    using namespace ProjectExplorer;

360
    m_toolChainType = type;
361

362 363
    delete m_toolChain;
    m_toolChain = 0;
Roberto Raggi's avatar
Roberto Raggi committed
364

365
    if (type == ToolChain::MinGW) {
Roberto Raggi's avatar
Roberto Raggi committed
366 367 368
        const QLatin1String qmake_cxx("g++"); // ### FIXME
        const QString mingwDirectory; // ### FIXME

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

371
    } else if (type == ToolChain::MSVC) {
Roberto Raggi's avatar
Roberto Raggi committed
372
        const QString msvcVersion; // ### FIXME
373
        m_toolChain = ToolChain::createMSVCToolChain(msvcVersion, false);
Roberto Raggi's avatar
Roberto Raggi committed
374

375
    } else if (type == ToolChain::WINCE) {
Roberto Raggi's avatar
Roberto Raggi committed
376
        const QString msvcVersion, wincePlatform; // ### FIXME
377
        m_toolChain = ToolChain::createWinCEToolChain(msvcVersion, wincePlatform);
Roberto Raggi's avatar
Roberto Raggi committed
378

379
    } else if (type == ToolChain::GCC || type == ToolChain::GCC) {
Roberto Raggi's avatar
Roberto Raggi committed
380
        const QLatin1String qmake_cxx("g++"); // ### FIXME
381
        m_toolChain = ToolChain::createGccToolChain(qmake_cxx);
Roberto Raggi's avatar
Roberto Raggi committed
382 383 384
    }
}

385 386 387 388 389
ProjectExplorer::ToolChain *GenericProject::toolChain() const
{
    return m_toolChain;
}

390 391
ProjectExplorer::ToolChain::ToolChainType GenericProject::toolChainType() const
{ return m_toolChainType; }
392

393
QString GenericProject::displayName() const
Roberto Raggi's avatar
Roberto Raggi committed
394
{
395
    return m_projectName;
Roberto Raggi's avatar
Roberto Raggi committed
396 397
}

Tobias Hunger's avatar
Tobias Hunger committed
398 399 400 401 402
QString GenericProject::id() const
{
    return QLatin1String("GenericProjectManager.GenericProject");
}

Roberto Raggi's avatar
Roberto Raggi committed
403 404
Core::IFile *GenericProject::file() const
{
405
    return m_file;
Roberto Raggi's avatar
Roberto Raggi committed
406 407 408 409
}

ProjectExplorer::IProjectManager *GenericProject::projectManager() const
{
410
    return m_manager;
Roberto Raggi's avatar
Roberto Raggi committed
411 412 413 414 415 416 417 418 419 420 421 422
}

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

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

dt's avatar
dt committed
423
ProjectExplorer::BuildConfigWidget *GenericProject::createConfigWidget()
Roberto Raggi's avatar
Roberto Raggi committed
424 425 426 427
{
    return new GenericBuildSettingsWidget(this);
}

dt's avatar
dt committed
428
QList<ProjectExplorer::BuildConfigWidget*> GenericProject::subConfigWidgets()
Roberto Raggi's avatar
Roberto Raggi committed
429
{
dt's avatar
dt committed
430
    return QList<ProjectExplorer::BuildConfigWidget*>();
Roberto Raggi's avatar
Roberto Raggi committed
431 432
}

433
GenericProjectNode *GenericProject::rootProjectNode() const
Roberto Raggi's avatar
Roberto Raggi committed
434
{
435
    return m_rootNode;
Roberto Raggi's avatar
Roberto Raggi committed
436 437 438 439
}

QStringList GenericProject::files(FilesMode fileMode) const
{
440
    Q_UNUSED(fileMode)
441
    return m_files; // ### TODO: handle generated files here.
Roberto Raggi's avatar
Roberto Raggi committed
442 443
}

Tobias Hunger's avatar
Tobias Hunger committed
444
QStringList GenericProject::buildTargets() const
Roberto Raggi's avatar
Roberto Raggi committed
445 446 447 448 449 450 451
{
    QStringList targets;
    targets.append(QLatin1String("all"));
    targets.append(QLatin1String("clean"));
    return targets;
}

452
QVariantMap GenericProject::toMap() const
Roberto Raggi's avatar
Roberto Raggi committed
453
{
454 455 456 457 458 459 460 461 462
    QVariantMap map(Project::toMap());
    map.insert(QLatin1String(TOOLCHAIN_KEY), static_cast<int>(m_toolChainType));
    return map;
}

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

464
    // Add default BC:
Tobias Hunger's avatar
Tobias Hunger committed
465 466
    if (targets().isEmpty())
        addTarget(targetFactory()->create(this, QLatin1String(GENERIC_DESKTOP_TARGET_ID)));
467

468 469 470
    ToolChain::ToolChainType type =
            static_cast<ProjectExplorer::ToolChain::ToolChainType>
            (map.value(QLatin1String(TOOLCHAIN_KEY), 0).toInt());
Roberto Raggi's avatar
Roberto Raggi committed
471

472
    setToolChainType(type);
Roberto Raggi's avatar
Roberto Raggi committed
473 474

    setIncludePaths(allIncludePaths());
475

476
    refresh(Everything);
dt's avatar
dt committed
477
    return true;
478 479
}

Roberto Raggi's avatar
Roberto Raggi committed
480 481 482
////////////////////////////////////////////////////////////////////////////////////
// GenericBuildSettingsWidget
////////////////////////////////////////////////////////////////////////////////////
483

Roberto Raggi's avatar
Roberto Raggi committed
484
GenericBuildSettingsWidget::GenericBuildSettingsWidget(GenericProject *project)
dt's avatar
dt committed
485
    : m_project(project), m_buildConfiguration(0)
Roberto Raggi's avatar
Roberto Raggi committed
486 487
{
    QFormLayout *fl = new QFormLayout(this);
488 489
    fl->setContentsMargins(0, -1, 0, -1);
    fl->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow);
490 491

    // build directory
492
    m_pathChooser = new Utils::PathChooser(this);
493 494
    m_pathChooser->setEnabled(true);
    fl->addRow(tr("Build directory:"), m_pathChooser);
con's avatar
con committed
495
    connect(m_pathChooser, SIGNAL(changed(QString)), this, SLOT(buildDirectoryChanged()));
496

497
    // tool chain
498
    QComboBox *toolChainChooser = new QComboBox;
499
    toolChainChooser->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
500
    using namespace ProjectExplorer;
501 502
    int index = 0;
    int selectedIndex = -1;
503
    foreach (ToolChain::ToolChainType tc, ToolChain::supportedToolChains()) {
504 505 506 507
        toolChainChooser->addItem(ToolChain::toolChainName(tc), QVariant::fromValue<ToolChain::ToolChainType>(tc));
        if (m_project->toolChainType() == tc)
            selectedIndex = index;
        ++index;
508 509
    }

510
    toolChainChooser->setCurrentIndex(selectedIndex);
511
    fl->addRow(tr("Tool Chain:"), toolChainChooser);
512
    connect(toolChainChooser, SIGNAL(activated(int)), this, SLOT(toolChainSelected(int)));
Roberto Raggi's avatar
Roberto Raggi committed
513 514 515 516 517 518 519 520
}

GenericBuildSettingsWidget::~GenericBuildSettingsWidget()
{ }

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

dt's avatar
dt committed
521
void GenericBuildSettingsWidget::init(BuildConfiguration *bc)
Roberto Raggi's avatar
Roberto Raggi committed
522
{
523 524
    m_buildConfiguration = static_cast<GenericBuildConfiguration *>(bc);
    m_pathChooser->setPath(m_buildConfiguration->buildDirectory());
Roberto Raggi's avatar
Roberto Raggi committed
525 526 527 528
}

void GenericBuildSettingsWidget::buildDirectoryChanged()
{
529
    m_buildConfiguration->setBuildDirectory(m_pathChooser->path());
Roberto Raggi's avatar
Roberto Raggi committed
530 531
}

532 533 534 535 536 537 538 539 540
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
541 542 543
////////////////////////////////////////////////////////////////////////////////////
// GenericProjectFile
////////////////////////////////////////////////////////////////////////////////////
544

Roberto Raggi's avatar
Roberto Raggi committed
545 546
GenericProjectFile::GenericProjectFile(GenericProject *parent, QString fileName)
    : Core::IFile(parent),
547 548
      m_project(parent),
      m_fileName(fileName)
Roberto Raggi's avatar
Roberto Raggi committed
549 550 551 552 553 554 555 556 557 558 559 560
{ }

GenericProjectFile::~GenericProjectFile()
{ }

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

QString GenericProjectFile::fileName() const
{
561
    return m_fileName;
Roberto Raggi's avatar
Roberto Raggi committed
562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596
}

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 *)
{
}