Skip to content
Snippets Groups Projects
qt4nodes.cpp 48.3 KiB
Newer Older
/**************************************************************************
con's avatar
con committed
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 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
#include "proeditormodel.h"
hjk's avatar
hjk committed

con's avatar
con committed
#include "profilereader.h"
#include "prowriter.h"
con's avatar
con committed
#include "qt4nodes.h"
#include "qt4project.h"
#include "qt4projectmanager.h"
dt's avatar
dt committed
#include "qtuicodemodelsupport.h"
con's avatar
con committed

#include <projectexplorer/nodesvisitor.h>
#include <projectexplorer/filewatcher.h>
con's avatar
con committed

#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/fileiconprovider.h>
con's avatar
con committed
#include <coreplugin/filemanager.h>
#include <coreplugin/icore.h>
#include <coreplugin/iversioncontrol.h>
#include <coreplugin/vcsmanager.h>

#include <cpptools/cppmodelmanagerinterface.h>
#include <cplusplus/CppDocument.h>
#include <extensionsystem/pluginmanager.h>
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/buildmanager.h>
con's avatar
con committed

hjk's avatar
hjk committed
#include <utils/qtcassert.h>

con's avatar
con committed
#include <QtCore/QDebug>
#include <QtCore/QDir>
#include <QtCore/QFile>
#include <QtCore/QFileInfo>
#include <QtCore/QTimer>
#include <QtGui/QPainter>
con's avatar
con committed
#include <QtGui/QMainWindow>
#include <QtGui/QMessageBox>
#include <QtGui/QPushButton>

using namespace Qt4ProjectManager;
using namespace Qt4ProjectManager::Internal;

namespace {
    bool debug = false;
}

namespace {
    // sorting helper function
    bool sortProjectFilesByPath(ProFile *f1, ProFile *f2)
    {
        return f1->fileName() < f2->fileName();
    }
}

/*!
  \class Qt4PriFileNode
  Implements abstract ProjectNode class
  */

Qt4PriFileNode::Qt4PriFileNode(Qt4Project *project, Qt4ProFileNode* qt4ProFileNode, const QString &filePath)
con's avatar
con committed
        : ProjectNode(filePath),
          m_project(project),
          m_qt4ProFileNode(qt4ProFileNode),
          m_projectFilePath(QDir::fromNativeSeparators(filePath)),
          m_projectDir(QFileInfo(filePath).absolutePath()),
          m_fileWatcher(new ProjectExplorer::FileWatcher(this))
con's avatar
con committed
{
    Q_ASSERT(project);
    setFolderName(QFileInfo(filePath).completeBaseName());

    static QIcon dirIcon;
    if (dirIcon.isNull()) {
        // Create a custom Qt dir icon based on the system icon
        Core::FileIconProvider *iconProvider = Core::FileIconProvider::instance();
        QPixmap dirIconPixmap = iconProvider->overlayIcon(QStyle::SP_DirIcon,
                                                          QIcon(":/qt4projectmanager/images/qt_project.png"),
                                                          QSize(16, 16));
        dirIcon.addPixmap(dirIconPixmap);
    }
    setIcon(dirIcon);
    m_fileWatcher->addFile(filePath);
    connect(m_fileWatcher, SIGNAL(fileChanged(QString)),
            this, SLOT(scheduleUpdate()));
}

void Qt4PriFileNode::scheduleUpdate()
{
    m_qt4ProFileNode->scheduleUpdate();
con's avatar
con committed
}

namespace Qt4ProjectManager {
namespace Internal {
    struct InternalNode
    {
        QMap<QString, InternalNode*> subnodes;
        QStringList files;
        ProjectExplorer::FileType type;
        QString fullName;
        QIcon icon;

        InternalNode()
        {
            type = ProjectExplorer::UnknownFileType;
        }

        ~InternalNode()
        {
            qDeleteAll(subnodes);
        }

        // Creates a tree structure from a list of absolute file paths.
        // Empty directories are compressed into a single entry with a longer path.
        // * project
        //    * /absolute/path
        //       * file1
        //    * relative
        //       * path1
        //          * file1
        //          * file2
        //       * path2
        //          * file1
        void create(const QString &projectDir, const QStringList &newFilePaths, ProjectExplorer::FileType type)
        {
            static const QChar separator = QChar('/');
            const QString projectDirWithSeparator = projectDir + separator;
            int projectDirWithSeparatorLength = projectDirWithSeparator.length();
            foreach (const QString &file, newFilePaths) {
                QString fileWithoutPrefix;
                bool isRelative;
                if (file.startsWith(projectDirWithSeparator)) {
                    isRelative = true;
                    fileWithoutPrefix = file.mid(projectDirWithSeparatorLength);
                } else {
                    isRelative = false;
                    fileWithoutPrefix = file;
                }
                QStringList parts = fileWithoutPrefix.split(separator, QString::SkipEmptyParts);
                if (!isRelative && parts.count() > 0)
                    parts[0].prepend(separator);
                QStringListIterator it(parts);
                InternalNode *currentNode = this;
                QString path = (isRelative ? projectDir : "");
                while (it.hasNext()) {
                    const QString &key = it.next();
                    path += separator + key;
                    if (it.hasNext()) { // key is directory
                        if (!currentNode->subnodes.contains(key)) {
                            InternalNode *val = new InternalNode;
                            val->type = type;
                            val->fullName = path;
                            currentNode->subnodes.insert(key, val);
                            currentNode = val;
                        } else {
                            currentNode = currentNode->subnodes.value(key);
                        }
                    } else { // key is filename
                        currentNode->files.append(file);
                    }
                }
            }
            this->compress();
        }

        // Removes folder nodes with only a single sub folder in it
        void compress()
        {
            static const QChar separator = QChar('/');
            QMap<QString, InternalNode*> newSubnodes;
            QMapIterator<QString, InternalNode*> i(subnodes);
            while (i.hasNext()) {
                i.next();
                i.value()->compress();
Loading
Loading full blame...