Skip to content
Snippets Groups Projects
qt4nodes.h 10.2 KiB
Newer Older
/**************************************************************************
con's avatar
con committed
**
** This file is part of Qt Creator
**
hjk's avatar
hjk committed
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
con's avatar
con committed
**
** Contact: Nokia Corporation (qt-info@nokia.com)
con's avatar
con committed
**
** 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
** contact the sales department at http://qt.nokia.com/contact.
con's avatar
con committed
**
**************************************************************************/
hjk's avatar
hjk committed

con's avatar
con committed
#ifndef QT4NODES_H
#define QT4NODES_H

#include <coreplugin/ifile.h>
con's avatar
con committed
#include <projectexplorer/projectnodes.h>
#include <projectexplorer/project.h>
con's avatar
con committed

#include <QtCore/QHash>
#include <QtCore/QStringList>
#include <QtCore/QDateTime>
#include <QtCore/QMap>
#include <QtCore/QFutureWatcher>
#include <QtCore/QFileSystemWatcher>
con's avatar
con committed

// defined in proitems.h
QT_BEGIN_NAMESPACE
class ProFile;
QT_END_NAMESPACE

namespace Core {
class ICore;
}

namespace Qt4ProjectManager {

// Import base classes into namespace
using ProjectExplorer::Node;
using ProjectExplorer::FileNode;
using ProjectExplorer::FolderNode;
using ProjectExplorer::ProjectNode;
using ProjectExplorer::NodesWatcher;

// Import enums into namespace
using ProjectExplorer::NodeType;
using ProjectExplorer::FileNodeType;
using ProjectExplorer::FolderNodeType;
using ProjectExplorer::ProjectNodeType;

using ProjectExplorer::UnknownFileType;
using ProjectExplorer::ProjectFileType;

class Qt4Project;

namespace Internal {

using ProjectExplorer::FileType;
class ProFileReader;
dt's avatar
dt committed
class Qt4UiCodeModelSupport;
con's avatar
con committed

//  Type of projects
enum Qt4ProjectType {
    InvalidProject = 0,
    ApplicationTemplate,
    LibraryTemplate,
    ScriptTemplate,
    SubDirsTemplate
};

// Other variables of interest
enum Qt4Variable {
    DefinesVar = 1,
    IncludePathVar,
    UiDirVar,
    PkgConfigVar,
    PrecompiledHeaderVar,
    LibDirectoriesVar,
con's avatar
con committed
};

class Qt4PriFileNode;
class Qt4ProFileNode;

class Qt4PriFile : public Core::IFile
{
    Q_OBJECT
public:
    Qt4PriFile(Qt4PriFileNode *qt4PriFile);
    virtual bool save(const QString &fileName = QString());
    virtual QString fileName() const;
dt's avatar
dt committed
    virtual void rename(const QString &newName);

    virtual QString defaultPath() const;
    virtual QString suggestedFileName() const;
    virtual QString mimeType() const;

    virtual bool isModified() const;
    virtual bool isReadOnly() const;
    virtual bool isSaveAsAllowed() const;

    ReloadBehavior reloadBehavior(ChangeTrigger state, ChangeType type) const;
    void reload(ReloadFlag flag, ChangeType type);
con's avatar
con committed
// Implements ProjectNode for qt4 pro files
class Qt4PriFileNode : public ProjectExplorer::ProjectNode
{
con's avatar
con committed
    Q_OBJECT
    Q_DISABLE_COPY(Qt4PriFileNode)
public:
    Qt4PriFileNode(Qt4Project *project, Qt4ProFileNode* qt4ProFileNode, const QString &filePath);
con's avatar
con committed

    void update(ProFile *includeFileExact, ProFileReader *readerExact, ProFile *includeFileCumlative, ProFileReader *readerCumalative);

con's avatar
con committed

// ProjectNode interface
dt's avatar
dt committed
    QList<ProjectAction> supportedActions(Node *node) const;
con's avatar
con committed

    bool hasBuildTargets() const { return false; }
con's avatar
con committed

    bool canAddSubProject(const QString &proFilePath) const;

con's avatar
con committed
    bool addSubProjects(const QStringList &proFilePaths);
    bool removeSubProjects(const QStringList &proFilePaths);

    bool addFiles(const FileType fileType, const QStringList &filePaths,
                  QStringList *notAdded = 0);
    bool removeFiles(const FileType fileType, const QStringList &filePaths,
                     QStringList *notRemoved = 0);
    bool deleteFiles(const FileType fileType,
                     const QStringList &filePaths);
con's avatar
con committed
    bool renameFile(const FileType fileType,
                    const QString &filePath, const QString &newFilePath);

    void folderChanged(const QString &folder);

    bool deploysFolder(const QString &folder) const;

con's avatar
con committed
protected:
    void clear();
    static QStringList varNames(FileType type);
    static QStringList dynamicVarNames(ProFileReader *readerExact, ProFileReader *readerCumulative);
    static QSet<QString> filterFiles(ProjectExplorer::FileType fileType, const QSet<QString> &files);
con's avatar
con committed

    enum ChangeType {
        AddToProFile,
        RemoveFromProFile
    };

    bool changeIncludes(ProFile *includeFile,
                       const QStringList &proFilePaths,
                       ChangeType change);

    void changeFiles(const FileType fileType,
                     const QStringList &filePaths,
                     QStringList *notChanged,
                     ChangeType change);
private slots:
    void scheduleUpdate();

con's avatar
con committed
private:
    void save(const QStringList &lines);
con's avatar
con committed
    bool priFileWritable(const QString &path);
    bool saveModifiedEditors();
    QStringList formResources(const QString &formFile) const;
    QStringList baseVPaths(ProFileReader *reader, const QString &projectDir);
    QStringList fullVPaths(const QStringList &baseVPaths, ProFileReader *reader, FileType type, const QString &qmakeVariable, const QString &projectDir);
    void watchFolders(const QSet<QString> &folders);
con's avatar
con committed

    Qt4Project *m_project;
    Qt4ProFileNode *m_qt4ProFileNode;
con's avatar
con committed
    QString m_projectFilePath;
    QString m_projectDir;
dt's avatar
dt committed
    QMap<QString, Qt4UiCodeModelSupport *> m_uiCodeModelSupport;
    // Memory is cheap...
    // TODO (really that cheap?)
    QMap<ProjectExplorer::FileType, QSet<QString> > m_files;
    QSet<QString> m_recursiveEnumerateFiles;
    QSet<QString> m_watchedFolders;

con's avatar
con committed
    // managed by Qt4ProFileNode
    friend class Qt4ProFileNode;
    friend class Qt4PriFile; // for scheduling updates on modified
    // internal temporary subtree representation
    friend struct InternalNode;
con's avatar
con committed
};

struct TargetInformation
{
    bool valid;
    QString workingDir;
    QString target;
    QString executable;
    QString buildDir;
    bool operator==(const TargetInformation &other) const
    {
        return workingDir == other.workingDir
                && target == other.target
                && executable == other.executable
                && valid == valid
                && buildDir == buildDir;
    }
    bool operator!=(const TargetInformation &other) const
    {
        return !(*this == other);
    }

    TargetInformation()
        : valid(false)
    {}

    TargetInformation(const TargetInformation &other)
        : valid(other.valid),
          workingDir(other.workingDir),
          target(other.target),
          executable(other.executable),
          buildDir(other.buildDir)
con's avatar
con committed
// Implements ProjectNode for qt4 pro files
class Qt4ProFileNode : public Qt4PriFileNode
{
con's avatar
con committed
    Q_OBJECT
    Q_DISABLE_COPY(Qt4ProFileNode)
public:
    Qt4ProFileNode(Qt4Project *project,
                   const QString &filePath,
                   QObject *parent = 0);
    ~Qt4ProFileNode();
con's avatar
con committed

    bool isParent(Qt4ProFileNode *node);

    bool hasBuildTargets() const;
con's avatar
con committed

    Qt4ProjectType projectType() const;

    QStringList variableValue(const Qt4Variable var) const;

dt's avatar
dt committed
    void updateCodeModelSupportFromBuild(const QStringList &files);
    void updateCodeModelSupportFromEditor(const QString &uiFileName, const QString &contents);
    QString uiDirectory() const;
    static QString uiHeaderFile(const QString &uiDir, const QString &formFile);

    const Qt4ProFileNode *findProFileFor(const QString &string) const;
    TargetInformation targetInformation(const QString &fileName) const;
    TargetInformation targetInformation() const;
con's avatar
con committed
    void update();
    void scheduleUpdate();

public slots:
    void asyncUpdate();

con's avatar
con committed
private slots:
    void buildStateChanged(ProjectExplorer::Project*);
    void applyAsyncEvaluate();
con's avatar
con committed

    void setupReader();
    bool evaluate();
    void applyEvaluate(bool parseResult, bool async);

    void asyncEvaluate(QFutureInterface<bool> &fi);

    typedef QHash<Qt4Variable, QStringList> Qt4VariablesHash;

dt's avatar
dt committed
    void createUiCodeModelSupport();
    QStringList updateUiFiles();
con's avatar
con committed

dt's avatar
dt committed
    QString uiDirPath(ProFileReader *reader) const;
    QString mocDirPath(ProFileReader *reader) const;
con's avatar
con committed
    QStringList includePaths(ProFileReader *reader) const;
    QStringList libDirectories(ProFileReader *reader) const;
con's avatar
con committed
    QStringList subDirsPaths(ProFileReader *reader) const;
    TargetInformation targetInformation(ProFileReader *reader) const;
con's avatar
con committed

    void invalidate();

    Qt4ProjectType m_projectType;
    Qt4VariablesHash m_varValues;
con's avatar
con committed

    QMap<QString, QDateTime> m_uitimestamps;
    TargetInformation m_qt4targetInformation;
con's avatar
con committed
    friend class Qt4NodeHierarchy;

    // Async stuff
    QFutureWatcher<bool> m_parseFutureWatcher;
    ProFileReader *m_readerExact;
    ProFileReader *m_readerCumulative;
con's avatar
con committed
};

class Qt4NodesWatcher : public ProjectExplorer::NodesWatcher
{
con's avatar
con committed
    Q_OBJECT
    Q_DISABLE_COPY(Qt4NodesWatcher)
public:
    Qt4NodesWatcher(QObject *parent = 0);

signals:
    void projectTypeChanged(Qt4ProjectManager::Internal::Qt4ProFileNode *projectNode,
                            const Qt4ProjectManager::Internal::Qt4ProjectType oldType,
                            const Qt4ProjectManager::Internal::Qt4ProjectType newType);

    void variablesChanged(Qt4ProFileNode *projectNode,
                          const QHash<Qt4Variable, QStringList> &oldValues,
                          const QHash<Qt4Variable, QStringList> &newValues);

    void proFileUpdated(Qt4ProjectManager::Internal::Qt4ProFileNode *projectNode);

private:
    // let them emit signals
    friend class Qt4ProFileNode;
    friend class Qt4PriFileNode;
};

} // namespace Internal
} // namespace Qt4ProjectManager

#endif // QT4NODES_H