Skip to content
Snippets Groups Projects
qt4nodes.cpp 57 KiB
Newer Older
    projectType = proFileTemplateTypeToProjectType(m_readerExact->templateType());

con's avatar
con committed
    if (projectType != m_projectType) {
        Qt4ProjectType oldType = m_projectType;
        // probably all subfiles/projects have changed anyway ...
        clear();
        m_projectType = projectType;
        // really emit here? or at the end? Noone is connected to this signal at the moment
        // so we kind of can ignore that question for now
con's avatar
con committed
        foreach (NodesWatcher *watcher, watchers())
            if (Qt4NodesWatcher *qt4Watcher = qobject_cast<Qt4NodesWatcher*>(watcher))
                emit qt4Watcher->projectTypeChanged(this, oldType, projectType);
    }

    //
    // Add/Remove pri files, sub projects
    //

    QList<ProjectNode*> existingProjectNodes = subProjectNodes();

    QStringList newProjectFilesExact;
    QHash<QString, ProFile*> includeFilesExact;
    ProFile *fileForCurrentProjectExact = 0;
    if (m_projectType == SubDirsTemplate)
        newProjectFilesExact = subDirsPaths(m_readerExact);
    foreach (ProFile *includeFile, m_readerExact->includeFiles()) {
        if (includeFile->fileName() == m_projectFilePath) { // this file
            fileForCurrentProjectExact = includeFile;
        } else {
            newProjectFilesExact << includeFile->fileName();
            includeFilesExact.insert(includeFile->fileName(), includeFile);
con's avatar
con committed
        }
con's avatar
con committed


    QStringList newProjectFilesCumlative;
    QHash<QString, ProFile*> includeFilesCumlative;
    ProFile *fileForCurrentProjectCumlative = 0;
    if (m_readerCumulative) {
        if (m_projectType == SubDirsTemplate)
            newProjectFilesCumlative = subDirsPaths(m_readerCumulative);
        foreach (ProFile *includeFile, m_readerCumulative->includeFiles()) {
            if (includeFile->fileName() == m_projectFilePath) {
                fileForCurrentProjectCumlative = includeFile;
con's avatar
con committed
            } else {
                newProjectFilesCumlative << includeFile->fileName();
                includeFilesCumlative.insert(includeFile->fileName(), includeFile);
con's avatar
con committed
            }
        }
    }

    qSort(existingProjectNodes.begin(), existingProjectNodes.end(),
          sortNodesByPath);
    qSort(newProjectFilesExact);
    qSort(newProjectFilesCumlative);
con's avatar
con committed

    QList<ProjectNode*> toAdd;
    QList<ProjectNode*> toRemove;

    QList<ProjectNode*>::const_iterator existingIt = existingProjectNodes.constBegin();
    QStringList::const_iterator newExactIt = newProjectFilesExact.constBegin();
    QStringList::const_iterator newCumlativeIt = newProjectFilesCumlative.constBegin();

    forever {
        bool existingAtEnd = (existingIt == existingProjectNodes.constEnd());
        bool newExactAtEnd = (newExactIt == newProjectFilesExact.constEnd());
        bool newCumlativeAtEnd = (newCumlativeIt == newProjectFilesCumlative.constEnd());

        if (existingAtEnd && newExactAtEnd && newCumlativeAtEnd)
            break; // we are done, hurray!

        // So this is one giant loop comparing 3 lists at once and sorting the comparision
        // into mainly 2 buckets: toAdd and toRemove
        // We need to distinguish between nodes that came from exact and cumalative
        // parsing, since the update call is diffrent for them
        // I believe this code to be correct, be careful in changing it

        QString nodeToAdd;
        if (! existingAtEnd
            && (newExactAtEnd || (*existingIt)->path() < *newExactIt)
            && (newCumlativeAtEnd || (*existingIt)->path() < *newCumlativeIt)) {
            // Remove case
            toRemove << *existingIt;
            ++existingIt;
        } else if(! newExactAtEnd
                  && (existingAtEnd || *newExactIt < (*existingIt)->path())
                  && (newCumlativeAtEnd || *newExactIt < *newCumlativeIt)) {
            // Mark node from exact for adding
            nodeToAdd = *newExactIt;
            ++newExactIt;
        } else if (! newCumlativeAtEnd
                   && (existingAtEnd ||  *newCumlativeIt < (*existingIt)->path())
                   && (newExactAtEnd || *newCumlativeIt < *newExactIt)) {
            // Mark node from cumalative for adding
            nodeToAdd = *newCumlativeIt;
            ++newCumlativeIt;
        } else if (!newExactAtEnd
                   && !newCumlativeAtEnd
                   && (existingAtEnd || *newExactIt < (*existingIt)->path())
                   && (existingAtEnd || *newCumlativeIt < (*existingIt)->path())) {
            // Mark node from both for adding
            nodeToAdd = *newExactIt;
            ++newExactIt;
            ++newCumlativeIt;
        } else {
            Q_ASSERT(!newExactAtEnd || !newCumlativeAtEnd);
            // update case, figure out which case exactly
            if (newExactAtEnd) {
                ++newCumlativeIt;
            } else if (newCumlativeAtEnd) {
                ++newExactIt;
            } else if(*newExactIt < *newCumlativeIt) {
                ++newExactIt;
            } else if (*newCumlativeIt < *newExactIt) {
                ++newCumlativeIt;
con's avatar
con committed
            } else {
                ++newExactIt;
                ++newCumlativeIt;
con's avatar
con committed
            }
            // Update existingNodeIte
            ProFile *fileExact = includeFilesCumlative.value((*existingIt)->path());
            ProFile *fileCumlative = includeFilesCumlative.value((*existingIt)->path());
            if (fileExact || fileCumlative) {
                static_cast<Qt4PriFileNode *>(*existingIt)->update(fileExact, m_readerExact, fileCumlative, m_readerCumulative);
            } else {
                // We always parse exactly, because we later when async parsing don't know whether
                // the .pro file is included in this .pro file
                // So to compare that later parse with the sync one
                if (async)
                    static_cast<Qt4ProFileNode *>(*existingIt)->asyncUpdate();
                else
                    static_cast<Qt4ProFileNode *>(*existingIt)->update();
con's avatar
con committed
            }
            ++existingIt;
            // newCumalativeIt and newExactIt are already incremented
con's avatar
con committed

        }
        // If we found something to add do it
        if (!nodeToAdd.isEmpty()) {
            ProFile *fileExact = includeFilesCumlative.value(nodeToAdd);
            ProFile *fileCumlative = includeFilesCumlative.value(nodeToAdd);
            if (fileExact || fileCumlative) {
                Qt4PriFileNode *qt4PriFileNode = new Qt4PriFileNode(m_project, this, nodeToAdd);
                qt4PriFileNode->update(fileExact, m_readerExact, fileCumlative, m_readerCumulative);
                toAdd << qt4PriFileNode;
            } else {
                Qt4ProFileNode *qt4ProFileNode = new Qt4ProFileNode(m_project, nodeToAdd);
                if (async)
                    qt4ProFileNode->asyncUpdate();
                else
                    qt4ProFileNode->update();
                toAdd << qt4ProFileNode;
            }
con's avatar
con committed
        }
    } // for
con's avatar
con committed

    if (!toRemove.isEmpty())
        removeProjectNodes(toRemove);
    if (!toAdd.isEmpty())
        addProjectNodes(toAdd);

    Qt4PriFileNode::update(fileForCurrentProjectExact, m_readerExact, fileForCurrentProjectCumlative, m_readerCumulative);

    // update TargetInformation
    m_qt4targetInformation = targetInformation(m_readerExact);
con's avatar
con committed

    // update other variables
    QHash<Qt4Variable, QStringList> newVarValues;
    newVarValues[DefinesVar] = m_readerExact->values(QLatin1String("DEFINES"));
    newVarValues[IncludePathVar] = includePaths(m_readerExact);
dt's avatar
dt committed
    newVarValues[UiDirVar] = QStringList() << uiDirPath(m_readerExact);
    newVarValues[MocDirVar] = QStringList() << mocDirPath(m_readerExact);
    newVarValues[PkgConfigVar] = m_readerExact->values(QLatin1String("PKGCONFIG"));
    newVarValues[PrecompiledHeaderVar] =
            m_readerExact->absoluteFileValues(QLatin1String("PRECOMPILED_HEADER"),
                                              m_projectDir,
                                              QStringList() << m_projectDir,
                                              0);
    newVarValues[LibDirectoriesVar] = libDirectories(m_readerExact);
con's avatar
con committed

    if (m_varValues != newVarValues) {
        m_varValues = newVarValues;
        foreach (NodesWatcher *watcher, watchers())
            if (Qt4NodesWatcher *qt4Watcher = qobject_cast<Qt4NodesWatcher*>(watcher))
                emit qt4Watcher->variablesChanged(this, m_varValues, newVarValues);
    }

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

    foreach (NodesWatcher *watcher, watchers())
        if (Qt4NodesWatcher *qt4Watcher = qobject_cast<Qt4NodesWatcher*>(watcher))
            emit qt4Watcher->proFileUpdated(this);
    m_project->destroyProFileReader(m_readerExact);
    if (m_readerCumulative)
        m_project->destroyProFileReader(m_readerCumulative);

    m_readerExact = 0;
    m_readerCumulative = 0;
con's avatar
con committed
}

namespace {
    // find all ui files in project
    class FindUiFileNodesVisitor : public ProjectExplorer::NodesVisitor {
    public:
        void visitProjectNode(ProjectNode *projectNode)
        {
            visitFolderNode(projectNode);
        }
        void visitFolderNode(FolderNode *folderNode)
        {
            foreach (FileNode *fileNode, folderNode->fileNodes()) {
                if (fileNode->fileType() == ProjectExplorer::FormType)
                    uiFileNodes << fileNode;
            }
        }
        QList<FileNode*> uiFileNodes;
    };
}

// This function is triggered after a build, and updates the state ui files
// It does so by storing a modification time for each ui file we know about.

dt's avatar
dt committed
// TODO this function should also be called if the build directory is changed
dt's avatar
dt committed
QStringList Qt4ProFileNode::updateUiFiles()
con's avatar
con committed
{
dt's avatar
dt committed
//    qDebug()<<"Qt4ProFileNode::updateUiFiles()";
    // Only those two project types can have ui files for us
con's avatar
con committed
    if (m_projectType != ApplicationTemplate
        && m_projectType != LibraryTemplate)
dt's avatar
dt committed
        return QStringList();
con's avatar
con committed

    // Find all ui files
con's avatar
con committed
    FindUiFileNodesVisitor uiFilesVisitor;
    this->accept(&uiFilesVisitor);
    const QList<FileNode*> uiFiles = uiFilesVisitor.uiFileNodes;

    // Find the UiDir, there can only ever be one
    QString uiDir = buildDir();
    QStringList tmp = m_varValues[UiDirVar];
    if (tmp.size() != 0)
        uiDir = tmp.first();
con's avatar
con committed

    // Collect all existing generated files
con's avatar
con committed
    QList<FileNode*> existingFileNodes;
    foreach (FileNode *file, fileNodes()) {
        if (file->isGenerated())
            existingFileNodes << file;
    }

    // Convert uiFile to uiHeaderFilePath, find all headers that correspond
    // and try to find them in uiDir
con's avatar
con committed
    QStringList newFilePaths;
    foreach (FileNode *uiFile, uiFiles) {
        const QString uiHeaderFilePath
                = QString("%1/ui_%2.h").arg(uiDir, QFileInfo(uiFile->path()).completeBaseName());
        if (QFileInfo(uiHeaderFilePath).exists())
            newFilePaths << uiHeaderFilePath;
con's avatar
con committed
    }

    // Create a diff between those lists
con's avatar
con committed
    QList<FileNode*> toRemove;
    QList<FileNode*> toAdd;
    // The list of files for which we call updateSourceFile
    QStringList toUpdate;
con's avatar
con committed

    qSort(newFilePaths);
    qSort(existingFileNodes.begin(), existingFileNodes.end(), ProjectNode::sortNodesByPath);

    QList<FileNode*>::const_iterator existingNodeIter = existingFileNodes.constBegin();
    QList<QString>::const_iterator newPathIter = newFilePaths.constBegin();
    while (existingNodeIter != existingFileNodes.constEnd()
           && newPathIter != newFilePaths.constEnd()) {
        if ((*existingNodeIter)->path() < *newPathIter) {
            toRemove << *existingNodeIter;
            ++existingNodeIter;
        } else if ((*existingNodeIter)->path() > *newPathIter) {
            toAdd << new FileNode(*newPathIter, ProjectExplorer::HeaderType, true);
            ++newPathIter;
        } else { // *existingNodeIter->path() == *newPathIter
            QString fileName = (*existingNodeIter)->path();
            QMap<QString, QDateTime>::const_iterator it = m_uitimestamps.find(fileName);
            QDateTime lastModified = QFileInfo(fileName).lastModified();
            if (it == m_uitimestamps.constEnd() || it.value() < lastModified) {
                toUpdate << fileName;
                m_uitimestamps[fileName] = lastModified;
            }
con's avatar
con committed
            ++existingNodeIter;
            ++newPathIter;
        }
    }
    while (existingNodeIter != existingFileNodes.constEnd()) {
        toRemove << *existingNodeIter;
        ++existingNodeIter;
    }
    while (newPathIter != newFilePaths.constEnd()) {
        toAdd << new FileNode(*newPathIter, ProjectExplorer::HeaderType, true);
        ++newPathIter;
    }

    // Update project tree
con's avatar
con committed
    if (!toRemove.isEmpty()) {
        foreach (FileNode *file, toRemove)
            m_uitimestamps.remove(file->path());
con's avatar
con committed
        removeFileNodes(toRemove, this);
    }

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

con's avatar
con committed
    if (!toAdd.isEmpty()) {
        foreach (FileNode *file, toAdd) {
            m_uitimestamps.insert(file->path(), QFileInfo(file->path()).lastModified());
            toUpdate << file->path();

dt's avatar
dt committed
            // Also adding files depending on that
            // We only need to do that for files that were newly created
            QString fileName = QFileInfo(file->path()).fileName();
            foreach (CPlusPlus::Document::Ptr doc, modelManager->snapshot()) {
                if (doc->includedFiles().contains(fileName)) {
                    if (!toUpdate.contains(doc->fileName()))
                        toUpdate << doc->fileName();
                }
            }
        }
con's avatar
con committed
        addFileNodes(toAdd, this);
    }
dt's avatar
dt committed
    return toUpdate;
con's avatar
con committed
}

dt's avatar
dt committed
QString Qt4ProFileNode::uiDirPath(ProFileReader *reader) const
con's avatar
con committed
{
dt's avatar
dt committed
    QString path = reader->value("UI_DIR");
    if (QFileInfo(path).isRelative())
        path = QDir::cleanPath(buildDir() + "/" + path);
    return path;
con's avatar
con committed
}

dt's avatar
dt committed
QString Qt4ProFileNode::mocDirPath(ProFileReader *reader) const
con's avatar
con committed
{
dt's avatar
dt committed
    QString path = reader->value("MOC_DIR");
    if (QFileInfo(path).isRelative())
        path = QDir::cleanPath(buildDir() + "/" + path);
    return path;
con's avatar
con committed
}

QStringList Qt4ProFileNode::includePaths(ProFileReader *reader) const
{
    QStringList paths;
    foreach (const QString &cxxflags, m_readerExact->values("QMAKE_CXXFLAGS")) {
        if (cxxflags.startsWith("-I"))
            paths.append(cxxflags.mid(2));
    }

    paths.append(reader->absolutePathValues(QLatin1String("INCLUDEPATH"), m_projectDir));
dt's avatar
dt committed
    // paths already contains moc dir and ui dir, due to corrrectly parsing uic.prf and moc.prf
    // except if those directories don't exist at the time of parsing
    // thus we add those directories manually (without checking for existance)
    paths << mocDirPath(reader) << uiDirPath(reader);
con's avatar
con committed
    paths.removeDuplicates();
    return paths;
}

QStringList Qt4ProFileNode::libDirectories(ProFileReader *reader) const
{
    QStringList result;
    foreach (const QString &str, reader->values(QLatin1String("LIBS"))) {
        if (str.startsWith("-L")) {
            result.append(str.mid(2));
        }
    }
    return result;
}

con's avatar
con committed
QStringList Qt4ProFileNode::subDirsPaths(ProFileReader *reader) const
{
    QStringList subProjectPaths;

    const QStringList subDirVars = reader->values(QLatin1String("SUBDIRS"));

    foreach (const QString &subDirVar, subDirVars) {
        // Special case were subdir is just an identifier:
        //   "SUBDIR = subid
        //    subid.subdir = realdir"
con's avatar
con committed
        // or
        //   "SUBDIR = subid
        //    subid.file = realdir/realfile.pro"
con's avatar
con committed

        QString realDir;
        const QString subDirKey = subDirVar + QLatin1String(".subdir");
con's avatar
con committed
        const QString subDirFileKey = subDirVar + QLatin1String(".file");
con's avatar
con committed
        if (reader->contains(subDirKey))
            realDir = QFileInfo(reader->value(subDirKey)).filePath();
con's avatar
con committed
        else if (reader->contains(subDirFileKey))
            realDir = QFileInfo(reader->value(subDirFileKey)).filePath();
        else
con's avatar
con committed
            realDir = subDirVar;
        QFileInfo info(realDir);
        if (!info.isAbsolute()) {
            info.setFile(m_projectDir + QLatin1Char('/') + realDir);
            realDir = m_projectDir + QLatin1Char('/') + realDir;
con's avatar
con committed

        QString realFile;
        if (info.isDir()) {
            realFile = QString::fromLatin1("%1/%2.pro").arg(realDir, info.fileName());
con's avatar
con committed
        } else {
            realFile = realDir;
        }

        if (QFile::exists(realFile)) {
            if (!subProjectPaths.contains(realFile))
                subProjectPaths << realFile;
        } else {
            m_project->proFileParseError(tr("Could not find .pro file for sub dir '%1' in '%2'")
                                         .arg(subDirVar).arg(realDir));
        }
con's avatar
con committed
    }

    return subProjectPaths;
}

TargetInformation Qt4ProFileNode::targetInformation(ProFileReader *reader) const
{
    TargetInformation result;
    if (!reader)
        return result;

    result.buildDir = buildDir();
    const QString baseDir = result.buildDir;
    // qDebug() << "base build dir is:"<<baseDir;

    // Working Directory
    if (reader->contains("DESTDIR")) {
        //qDebug() << "reader contains destdir:" << reader->value("DESTDIR");
        result.workingDir = reader->value("DESTDIR");
        if (QDir::isRelativePath(result.workingDir)) {
            result.workingDir = baseDir + QLatin1Char('/') + result.workingDir;
            //qDebug() << "was relative and expanded to" << result.workingDir;
        }
    } else {
        //qDebug() << "reader didn't contain DESTDIR, setting to " << baseDir;
        result.workingDir = baseDir;
    }

    result.target = reader->value("TARGET");
    if (result.target.isEmpty())
        result.target = QFileInfo(m_projectFilePath).baseName();

#if defined (Q_OS_MAC)
    if (reader->values("CONFIG").contains("app_bundle")) {
        result.workingDir += QLatin1Char('/')
                           + result.target
                           + QLatin1String(".app/Contents/MacOS");
    }
#endif

    result.workingDir = QDir::cleanPath(result.workingDir);

    QString wd = result.workingDir;
    if (!reader->contains("DESTDIR")
        && reader->values("CONFIG").contains("debug_and_release")
        && reader->values("CONFIG").contains("debug_and_release_target")) {
        // If we don't have a destdir and debug and release is set
        // then the executable is in a debug/release folder
        //qDebug() << "reader has debug_and_release_target";

        // Hmm can we find out whether it's debug or release in a saner way?
        // Theoretically it's in CONFIG
        QString qmakeBuildConfig = "release";
        if (m_project->activeTarget()->activeBuildConfiguration()->qmakeBuildConfiguration() & QtVersion::DebugBuild)
            qmakeBuildConfig = "debug";
        wd += QLatin1Char('/') + qmakeBuildConfig;
    }

    result.executable = QDir::cleanPath(wd + QLatin1Char('/') + result.target);
    //qDebug() << "##### updateTarget sets:" << result.workingDir << result.executable;

#if defined (Q_OS_WIN)
    result.executable += QLatin1String(".exe");
#endif
    result.valid = true;
    return result;
}

TargetInformation Qt4ProFileNode::targetInformation()
{
    return m_qt4targetInformation;
}

QString Qt4ProFileNode::buildDir() const
con's avatar
con committed
{
    const QDir srcDirRoot = QFileInfo(m_project->rootProjectNode()->path()).absoluteDir();
    const QString relativeDir = srcDirRoot.relativeFilePath(m_projectDir);
Tobias Hunger's avatar
Tobias Hunger committed
    return QDir(m_project->activeTarget()->activeBuildConfiguration()->buildDirectory()).absoluteFilePath(relativeDir);
con's avatar
con committed
}

/*
  Sets project type to InvalidProject & deletes all subprojects/files/virtual folders
  */
void Qt4ProFileNode::invalidate()
{
    if (m_projectType == InvalidProject)
        return;

    clear();

    // change project type
    Qt4ProjectType oldType = m_projectType;
    m_projectType = InvalidProject;


    foreach (NodesWatcher *watcher, watchers())
        if (Qt4NodesWatcher *qt4Watcher = qobject_cast<Qt4NodesWatcher*>(watcher))
            emit qt4Watcher->projectTypeChanged(this, oldType, InvalidProject);
}

dt's avatar
dt committed
void Qt4ProFileNode::updateCodeModelSupportFromBuild(const QStringList &files)
{
    foreach (const QString &file, files) {
        QMap<QString, Qt4UiCodeModelSupport *>::const_iterator it, end;
        end = m_uiCodeModelSupport.constEnd();
        for (it = m_uiCodeModelSupport.constBegin(); it != end; ++it) {
            if (it.value()->fileName() == file)
                it.value()->updateFromBuild();
        }
    }
}

void Qt4ProFileNode::updateCodeModelSupportFromEditor(const QString &uiFileName,
                                                      const QString &contents)
    const QMap<QString, Qt4UiCodeModelSupport *>::const_iterator it =
            m_uiCodeModelSupport.constFind(uiFileName);
    if (it != m_uiCodeModelSupport.constEnd())
        it.value()->updateFromEditor(contents);
dt's avatar
dt committed
    foreach (ProjectExplorer::ProjectNode *pro, subProjectNodes())
        if (Qt4ProFileNode *qt4proFileNode = qobject_cast<Qt4ProFileNode *>(pro))
            qt4proFileNode->updateCodeModelSupportFromEditor(uiFileName, contents);
QString Qt4ProFileNode::uiDirectory() const
{
    const Qt4VariablesHash::const_iterator it = m_varValues.constFind(UiDirVar);
    if (it != m_varValues.constEnd() && !it.value().isEmpty())
        return it.value().front();
    return buildDir();
}

QString Qt4ProFileNode::uiHeaderFile(const QString &uiDir, const QString &formFile)
{
    QString uiHeaderFilePath = uiDir;
    uiHeaderFilePath += QLatin1String("/ui_");
    uiHeaderFilePath += QFileInfo(formFile).completeBaseName();
    uiHeaderFilePath += QLatin1String(".h");
    return QDir::cleanPath(uiHeaderFilePath);
}

dt's avatar
dt committed
void Qt4ProFileNode::createUiCodeModelSupport()
{
dt's avatar
dt committed
//    qDebug()<<"creatUiCodeModelSupport()";
dt's avatar
dt committed
    CppTools::CppModelManagerInterface *modelManager
            = ExtensionSystem::PluginManager::instance()->getObject<CppTools::CppModelManagerInterface>();

    // First move all to
    QMap<QString, Qt4UiCodeModelSupport *> oldCodeModelSupport;
    oldCodeModelSupport = m_uiCodeModelSupport;
    m_uiCodeModelSupport.clear();

    // Only those two project types can have ui files for us
    if (m_projectType == ApplicationTemplate || m_projectType == LibraryTemplate) {
        // Find all ui files
        FindUiFileNodesVisitor uiFilesVisitor;
        this->accept(&uiFilesVisitor);
        const QList<FileNode*> uiFiles = uiFilesVisitor.uiFileNodes;

        // Find the UiDir, there can only ever be one
        const  QString uiDir = uiDirectory();
        foreach (const FileNode *uiFile, uiFiles) {
            const QString uiHeaderFilePath = uiHeaderFile(uiDir, uiFile->path());
dt's avatar
dt committed
//            qDebug()<<"code model support for "<<uiFile->path()<<" "<<uiHeaderFilePath;
dt's avatar
dt committed
            QMap<QString, Qt4UiCodeModelSupport *>::iterator it = oldCodeModelSupport.find(uiFile->path());
            if (it != oldCodeModelSupport.end()) {
dt's avatar
dt committed
//                qDebug()<<"updated old codemodelsupport";
dt's avatar
dt committed
                Qt4UiCodeModelSupport *cms = it.value();
                cms->setFileName(uiHeaderFilePath);
                m_uiCodeModelSupport.insert(it.key(), cms);
                oldCodeModelSupport.erase(it);
            } else {
dt's avatar
dt committed
//                qDebug()<<"adding new codemodelsupport";
dt's avatar
dt committed
                Qt4UiCodeModelSupport *cms = new Qt4UiCodeModelSupport(modelManager, m_project, uiFile->path(), uiHeaderFilePath);
                m_uiCodeModelSupport.insert(uiFile->path(), cms);
                modelManager->addEditorSupport(cms);
            }
        }
    }
    // Remove old
    QMap<QString, Qt4UiCodeModelSupport *>::const_iterator it, end;
    end = oldCodeModelSupport.constEnd();
    for (it = oldCodeModelSupport.constBegin(); it!=end; ++it) {
        modelManager->removeEditorSupport(it.value());
        delete it.value();
    }
}
con's avatar
con committed
Qt4NodesWatcher::Qt4NodesWatcher(QObject *parent)
        : NodesWatcher(parent)
{
}
} // namespace Internal
} // namespace Qt4ProjectManager