Skip to content
Snippets Groups Projects
qt4project.cpp 41.9 KiB
Newer Older
con's avatar
con committed
    }

    if (runConfigurations().isEmpty()) {
        QSharedPointer<RunConfiguration> rc(new ProjectExplorer::CustomExecutableRunConfiguration(this));
        addRunConfiguration(rc);
        setActiveRunConfiguration(rc);
        m_isApplication = false;
    } else if (resetActiveRunConfiguration) {
        setActiveRunConfiguration(runConfigurations().first());
    }
}

QList<Qt4ProFileNode *> Qt4Project::applicationProFiles() const
{
    QList<Qt4ProFileNode *> list;
    collectApplicationProFiles(list, rootProjectNode());
    return list;
}

void Qt4Project::projectTypeChanged(Qt4ProFileNode *node, const Qt4ProjectType oldType, const Qt4ProjectType newType)
{
    if (oldType == Internal::ApplicationTemplate
        || oldType == Internal::ScriptTemplate) {
        // check wheter we need to delete a Run Configuration
        checkForDeletedApplicationProjects();
    }

    if (newType == Internal::ApplicationTemplate
        || newType == Internal::ScriptTemplate) {
        // add a new Run Configuration
        m_applicationProFileChange.clear();
        m_applicationProFileChange.append(node);
        checkForNewApplicationProjects();
    }
}

void Qt4Project::proFileUpdated(Qt4ProjectManager::Internal::Qt4ProFileNode *node)
{
    foreach (QSharedPointer<RunConfiguration> rc, runConfigurations()) {
        if (QSharedPointer<Qt4RunConfiguration> qt4rc = rc.dynamicCast<Qt4RunConfiguration>()) {
            if (qt4rc->proFilePath() == node->path()) {
                qt4rc->invalidateCachedTargetInformation();
QMakeStep *Qt4Project::qmakeStep() const
{
    QMakeStep *qs = 0;
    foreach(BuildStep *bs, buildSteps())
        if ((qs = qobject_cast<QMakeStep *>(bs)) != 0)
            return qs;
    return 0;
}

con's avatar
con committed
MakeStep *Qt4Project::makeStep() const
{
    MakeStep *qs = 0;
    foreach(BuildStep *bs, buildSteps())
        if ((qs = qobject_cast<MakeStep *>(bs)) != 0)
            return qs;
    return 0;
}
bool Qt4Project::hasSubNode(Qt4PriFileNode *root, const QString &path)
    if (root->path() == path)
        return true;
    foreach (FolderNode *fn, root->subFolderNodes()) {
        if (qobject_cast<Qt4ProFileNode *>(fn)) {
            // we aren't interested in pro file nodes
hjk's avatar
hjk committed
        } else if (Qt4PriFileNode *qt4prifilenode = qobject_cast<Qt4PriFileNode *>(fn)) {
            if (hasSubNode(qt4prifilenode, path))
                return true;
        }
    }
    return false;
}

void Qt4Project::findProFile(const QString& fileName, Qt4ProFileNode *root, QList<Qt4ProFileNode *> &list)
{
    if (hasSubNode(root, fileName))
        list.append(root);

    foreach (FolderNode *fn, root->subFolderNodes())
        if (Qt4ProFileNode *qt4proFileNode =  qobject_cast<Qt4ProFileNode *>(fn))
            findProFile(fileName, qt4proFileNode, list);
}

void Qt4Project::notifyChanged(const QString &name)
{
    if (files(Qt4Project::ExcludeGeneratedFiles).contains(name)) {
        QList<Qt4ProFileNode *> list;
        findProFile(name, rootProjectNode(), list);
        foreach(Qt4ProFileNode *node, list)
            node->update();
    }

void Qt4Project::invalidateCachedTargetInformation()
{
    emit targetInformationChanged();
// We match -spec and -platfrom separetly
// We ignore -cache, because qmake contained a bug that it didn't
// mention the -cache in the Makefile
// That means changing the -cache option in the additional arguments
// does not automatically rerun qmake. Alas, we could try more
// intelligent matching for -cache, but i guess people rarely
// do use that.

dt's avatar
dt committed
QStringList Qt4Project::removeSpecFromArgumentList(const QStringList &old)
{
    if (!old.contains("-spec") && !old.contains("-platform") && !old.contains("-cache"))
        return old;
    QStringList newList;
    bool ignoreNext = false;
    foreach(const QString &item, old) {
        if (ignoreNext) {
            ignoreNext = false;
        } else if (item == "-spec" || item == "-platform" || item == "-cache") {
            ignoreNext = true;
        } else {
            newList << item;
        }
    }
    return newList;
}

dt's avatar
dt committed
QString Qt4Project::extractSpecFromArgumentList(const QStringList &list)
{
    int index = list.indexOf("-spec");
    if (index == -1)
        index = list.indexOf("-platform");
    if (index == -1)
        return QString();
    if (index + 1 < list.length())
        return list.at(index +1);
    else
        return QString();
}

// returns true if both are equal
bool Qt4Project::compareBuildConfigurationToImportFrom(const QString &buildConfiguration, const QString &workingDirectory)
{
    QMakeStep *qs = qmakeStep();
    if (QDir(workingDirectory).exists(QLatin1String("Makefile")) && qs) {
        QString qtPath = QtVersionManager::findQtVersionFromMakefile(workingDirectory);
        QtVersion *version = qtVersion(buildConfiguration);
        if (version->path() == qtPath) {
            // same qtversion
            QPair<QtVersion::QmakeBuildConfig, QStringList> result =
                    QtVersionManager::scanMakeFile(workingDirectory, version->defaultBuildConfig());
            if (QtVersion::QmakeBuildConfig(value(buildConfiguration, "buildConfiguration").toInt()) == result.first) {
                // The QMake Build Configuration are the same,
                // now compare arguments lists
                // we have to compare without the spec/platform cmd argument
                // and compare that on its own
                QString actualSpec = extractSpecFromArgumentList(qs->value(buildConfiguration, "qmakeArgs").toStringList());
                if (actualSpec.isEmpty())
dt's avatar
dt committed
                    actualSpec = version->mkspec();

                // Now to convert the actualSpec to a absolute path, we go through a few hops
                if (QFileInfo(actualSpec).isRelative()) {
                    QString path = version->sourcePath() + "/mkspecs/" + actualSpec;
                    if (QFileInfo(path).exists()) {
                        actualSpec = QDir::cleanPath(path);
                    } else {
                        path = version->versionInfo().value("QMAKE_MKSPECS") + "/" + actualSpec;
                        if (QFileInfo(path).exists()) {
                            actualSpec = QDir::cleanPath(path);
                        } else {
                            path = workingDirectory + "/" + actualSpec;
                            if (QFileInfo(path).exists())
                                actualSpec = QDir::cleanPath(path);
                        }
                    }
                }


                QString parsedSpec = extractSpecFromArgumentList(result.second);
                // if the MakeFile did not contain a mkspec, then it is the default for that qmake
                if (parsedSpec.isEmpty())
                    parsedSpec = version->sourcePath() + "/mkspecs/" + version->mkspec();
                if (QFileInfo(parsedSpec).isRelative())
                    parsedSpec = QDir::cleanPath(workingDirectory + "/" + parsedSpec);

                QStringList actualArgs = removeSpecFromArgumentList(qs->value(buildConfiguration, "qmakeArgs").toStringList());
                QStringList parsedArgs = removeSpecFromArgumentList(result.second);

#ifdef Q_OS_WIN
                actualSpec = actualSpec.toLower();
                parsedSpec = parsedSpec.toLower();
#endif

                qDebug()<<"Actual args:"<<actualArgs;
                qDebug()<<"Parsed args:"<<parsedArgs;
                qDebug()<<"Actual spec:"<<actualSpec;
                qDebug()<<"Parsed spec:"<<parsedSpec;

                if (actualArgs == parsedArgs && actualSpec == parsedSpec)

/*!
  Handle special case were a subproject of the qt directory is opened, and
  qt was configured to be built as a shadow build -> also build in the sub-
  project in the correct shadow build directory.
  */

// TODO this function should be called on project first load
// and it should check against all configured qt versions ?
//void Qt4Project::detectQtShadowBuild(const QString &buildConfiguration) const
//{
//    if (project()->activeBuildConfiguration() == buildConfiguration)
//        return;
//
//    const QString currentQtDir = static_cast<Qt4Project *>(project())->qtDir(buildConfiguration);
//    const QString qtSourceDir = static_cast<Qt4Project *>(project())->qtVersion(buildConfiguration)->sourcePath();
//
//    // if the project is a sub-project of Qt and Qt was shadow-built then automatically
//    // adjust the build directory of the sub-project.
//    if (project()->file()->fileName().startsWith(qtSourceDir) && qtSourceDir != currentQtDir) {
//        project()->setValue(buildConfiguration, "useShadowBuild", true);
//        QString buildDir = QFileInfo(project()->file()->fileName()).absolutePath();
//        buildDir.replace(qtSourceDir, currentQtDir);
//        project()->setValue(buildConfiguration, "buildDirectory", buildDir);
//        project()->setValue(buildConfiguration, "autoShadowBuild", true);
//    }
//}