2012-10-02 09:12:39 +02:00
|
|
|
/****************************************************************************
|
2008-12-02 12:01:29 +01:00
|
|
|
**
|
2013-01-28 17:12:19 +01:00
|
|
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
2012-10-02 09:12:39 +02:00
|
|
|
** Contact: http://www.qt-project.org/legal
|
2008-12-02 12:01:29 +01:00
|
|
|
**
|
2012-10-02 09:12:39 +02:00
|
|
|
** This file is part of Qt Creator.
|
2008-12-02 12:01:29 +01:00
|
|
|
**
|
2012-10-02 09:12:39 +02:00
|
|
|
** Commercial License Usage
|
|
|
|
|
** Licensees holding valid commercial Qt licenses may use this file in
|
|
|
|
|
** accordance with the commercial license agreement provided with the
|
|
|
|
|
** Software or, alternatively, in accordance with the terms contained in
|
|
|
|
|
** a written agreement between you and Digia. For licensing terms and
|
|
|
|
|
** conditions see http://qt.digia.com/licensing. For further information
|
|
|
|
|
** use the contact form at http://qt.digia.com/contact-us.
|
2008-12-02 14:17:16 +01:00
|
|
|
**
|
2009-02-25 09:02:17 +01:00
|
|
|
** GNU Lesser General Public License Usage
|
2012-10-02 09:12:39 +02:00
|
|
|
** 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.
|
|
|
|
|
**
|
|
|
|
|
** In addition, as a special exception, Digia gives you certain additional
|
|
|
|
|
** rights. These rights are described in the Digia Qt LGPL Exception
|
2010-12-17 16:01:08 +01:00
|
|
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
|
|
|
**
|
2012-10-02 09:12:39 +02:00
|
|
|
****************************************************************************/
|
2008-12-02 16:19:05 +01:00
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
#include "qt4nodes.h"
|
|
|
|
|
#include "qt4project.h"
|
|
|
|
|
#include "qt4projectmanager.h"
|
2010-01-20 14:47:08 +01:00
|
|
|
#include "qt4projectmanagerconstants.h"
|
2011-08-18 16:46:44 +02:00
|
|
|
#include "qt4buildconfiguration.h"
|
2012-04-24 15:49:09 +02:00
|
|
|
#include "qmakerunconfigurationfactory.h"
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
|
#include <projectexplorer/nodesvisitor.h>
|
|
|
|
|
#include <coreplugin/editormanager/editormanager.h>
|
2009-10-01 16:38:08 +02:00
|
|
|
#include <coreplugin/editormanager/ieditor.h>
|
2009-01-27 12:40:49 +01:00
|
|
|
#include <coreplugin/fileiconprovider.h>
|
2012-02-14 16:43:51 +01:00
|
|
|
#include <coreplugin/documentmanager.h>
|
2008-12-02 12:01:29 +01:00
|
|
|
#include <coreplugin/icore.h>
|
|
|
|
|
#include <coreplugin/iversioncontrol.h>
|
|
|
|
|
#include <coreplugin/vcsmanager.h>
|
2012-10-15 11:53:22 +02:00
|
|
|
#include <coreplugin/dialogs/readonlyfilesdialog.h>
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2009-04-28 14:30:17 +02:00
|
|
|
#include <projectexplorer/buildmanager.h>
|
2012-04-24 15:49:09 +02:00
|
|
|
#include <projectexplorer/projectexplorer.h>
|
|
|
|
|
#include <projectexplorer/target.h>
|
2011-05-20 21:40:53 +02:00
|
|
|
#include <qtsupport/profilereader.h>
|
2012-09-03 18:31:44 +02:00
|
|
|
#include <qtsupport/qtkitinformation.h>
|
2013-07-09 16:41:57 +02:00
|
|
|
#include <qtsupport/uicodemodelsupport.h>
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2013-04-02 11:52:31 +02:00
|
|
|
#include <cpptools/cppmodelmanagerinterface.h>
|
2013-07-01 16:13:48 +02:00
|
|
|
#include <cpptools/cpptoolsconstants.h>
|
2013-04-09 10:40:18 +02:00
|
|
|
|
2012-08-23 15:53:58 +02:00
|
|
|
#include <utils/hostosinfo.h>
|
2010-08-24 18:22:57 +02:00
|
|
|
#include <utils/stringutils.h>
|
2011-05-20 21:40:53 +02:00
|
|
|
#include <proparser/prowriter.h>
|
2013-05-29 20:18:51 +02:00
|
|
|
#include <proparser/qmakevfs.h>
|
2010-08-10 16:27:35 +02:00
|
|
|
#include <algorithm>
|
2008-12-09 15:25:01 +01:00
|
|
|
|
2012-02-15 10:42:41 +01:00
|
|
|
#include <QDebug>
|
|
|
|
|
#include <QDir>
|
|
|
|
|
#include <QFile>
|
|
|
|
|
#include <QFileInfo>
|
|
|
|
|
#include <QXmlStreamReader>
|
2008-12-09 15:25:01 +01:00
|
|
|
|
2012-02-15 10:42:41 +01:00
|
|
|
#include <QMessageBox>
|
2012-02-09 09:35:03 +01:00
|
|
|
#include <utils/QtConcurrentTools>
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2010-02-12 12:40:32 +01:00
|
|
|
// Static cached data in struct Qt4NodeStaticData providing information and icons
|
|
|
|
|
// for file types and the project. Do some magic via qAddPostRoutine()
|
|
|
|
|
// to make sure the icons do not outlive QApplication, triggering warnings on X11.
|
|
|
|
|
|
|
|
|
|
struct FileTypeDataStorage {
|
|
|
|
|
ProjectExplorer::FileType type;
|
|
|
|
|
const char *typeName;
|
|
|
|
|
const char *icon;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const FileTypeDataStorage fileTypeDataStorage[] = {
|
|
|
|
|
{ ProjectExplorer::HeaderType,
|
2011-09-07 11:52:04 +02:00
|
|
|
QT_TRANSLATE_NOOP("Qt4ProjectManager::Qt4PriFileNode", "Headers"),
|
2010-02-12 12:40:32 +01:00
|
|
|
":/qt4projectmanager/images/headers.png" },
|
|
|
|
|
{ ProjectExplorer::SourceType,
|
2011-09-07 11:52:04 +02:00
|
|
|
QT_TRANSLATE_NOOP("Qt4ProjectManager::Qt4PriFileNode", "Sources"),
|
2010-02-12 12:40:32 +01:00
|
|
|
":/qt4projectmanager/images/sources.png" },
|
|
|
|
|
{ ProjectExplorer::FormType,
|
2011-09-07 11:52:04 +02:00
|
|
|
QT_TRANSLATE_NOOP("Qt4ProjectManager::Qt4PriFileNode", "Forms"),
|
2013-04-16 17:39:03 +02:00
|
|
|
":/qtsupport/images/forms.png" },
|
2010-02-12 12:40:32 +01:00
|
|
|
{ ProjectExplorer::ResourceType,
|
2011-09-07 11:52:04 +02:00
|
|
|
QT_TRANSLATE_NOOP("Qt4ProjectManager::Qt4PriFileNode", "Resources"),
|
2013-04-16 17:39:03 +02:00
|
|
|
":/qtsupport/images/qt_qrc.png" },
|
2010-08-10 16:27:35 +02:00
|
|
|
{ ProjectExplorer::QMLType,
|
2011-09-07 11:52:04 +02:00
|
|
|
QT_TRANSLATE_NOOP("Qt4ProjectManager::Qt4PriFileNode", "QML"),
|
2013-04-16 17:39:03 +02:00
|
|
|
":/qtsupport/images/qml.png" },
|
2010-02-12 12:40:32 +01:00
|
|
|
{ ProjectExplorer::UnknownFileType,
|
2011-09-07 11:52:04 +02:00
|
|
|
QT_TRANSLATE_NOOP("Qt4ProjectManager::Qt4PriFileNode", "Other files"),
|
2010-02-12 12:40:32 +01:00
|
|
|
":/qt4projectmanager/images/unknown.png" }
|
|
|
|
|
};
|
|
|
|
|
|
2012-05-04 11:49:37 +02:00
|
|
|
bool sortNodesByPath(ProjectExplorer::Node *a, ProjectExplorer::Node *b)
|
|
|
|
|
{
|
|
|
|
|
return a->path() < b->path();
|
|
|
|
|
}
|
|
|
|
|
|
2012-03-27 16:37:33 +02:00
|
|
|
class Qt4NodeStaticData {
|
|
|
|
|
public:
|
|
|
|
|
class FileTypeData {
|
|
|
|
|
public:
|
2010-02-12 12:40:32 +01:00
|
|
|
FileTypeData(ProjectExplorer::FileType t = ProjectExplorer::UnknownFileType,
|
|
|
|
|
const QString &tN = QString(),
|
|
|
|
|
const QIcon &i = QIcon()) :
|
|
|
|
|
type(t), typeName(tN), icon(i) { }
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2010-02-12 12:40:32 +01:00
|
|
|
ProjectExplorer::FileType type;
|
|
|
|
|
QString typeName;
|
|
|
|
|
QIcon icon;
|
|
|
|
|
};
|
|
|
|
|
|
2012-03-27 16:37:33 +02:00
|
|
|
Qt4NodeStaticData();
|
|
|
|
|
|
2010-02-12 12:40:32 +01:00
|
|
|
QVector<FileTypeData> fileTypeData;
|
|
|
|
|
QIcon projectIcon;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static void clearQt4NodeStaticData();
|
|
|
|
|
|
2012-03-27 16:37:33 +02:00
|
|
|
Qt4NodeStaticData::Qt4NodeStaticData()
|
|
|
|
|
{
|
2010-02-12 12:40:32 +01:00
|
|
|
// File type data
|
|
|
|
|
const unsigned count = sizeof(fileTypeDataStorage)/sizeof(FileTypeDataStorage);
|
2012-03-27 16:37:33 +02:00
|
|
|
fileTypeData.reserve(count);
|
2010-02-12 12:40:32 +01:00
|
|
|
|
|
|
|
|
// Overlay the SP_DirIcon with the custom icons
|
|
|
|
|
const QSize desiredSize = QSize(16, 16);
|
|
|
|
|
|
2011-04-19 15:42:14 +02:00
|
|
|
for (unsigned i = 0 ; i < count; ++i) {
|
2010-02-12 12:40:32 +01:00
|
|
|
const QIcon overlayIcon = QIcon(QLatin1String(fileTypeDataStorage[i].icon));
|
|
|
|
|
const QPixmap folderPixmap =
|
|
|
|
|
Core::FileIconProvider::overlayIcon(QStyle::SP_DirIcon,
|
|
|
|
|
overlayIcon, desiredSize);
|
|
|
|
|
QIcon folderIcon;
|
|
|
|
|
folderIcon.addPixmap(folderPixmap);
|
2011-09-07 11:52:04 +02:00
|
|
|
const QString desc = Qt4ProjectManager::Qt4PriFileNode::tr(fileTypeDataStorage[i].typeName);
|
2012-03-27 16:37:33 +02:00
|
|
|
fileTypeData.push_back(Qt4NodeStaticData::FileTypeData(fileTypeDataStorage[i].type,
|
|
|
|
|
desc, folderIcon));
|
2010-02-12 12:40:32 +01:00
|
|
|
}
|
|
|
|
|
// Project icon
|
2013-04-16 17:39:03 +02:00
|
|
|
const QIcon projectBaseIcon(QLatin1String(":/qtsupport/images/qt_project.png"));
|
2010-02-12 12:40:32 +01:00
|
|
|
const QPixmap projectPixmap = Core::FileIconProvider::overlayIcon(QStyle::SP_DirIcon,
|
|
|
|
|
projectBaseIcon,
|
|
|
|
|
desiredSize);
|
2012-03-27 16:37:33 +02:00
|
|
|
projectIcon.addPixmap(projectPixmap);
|
2010-02-12 12:40:32 +01:00
|
|
|
|
|
|
|
|
qAddPostRoutine(clearQt4NodeStaticData);
|
2012-03-27 16:37:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Q_GLOBAL_STATIC(Qt4NodeStaticData, qt4NodeStaticData)
|
2010-02-12 12:40:32 +01:00
|
|
|
|
|
|
|
|
static void clearQt4NodeStaticData()
|
|
|
|
|
{
|
|
|
|
|
qt4NodeStaticData()->fileTypeData.clear();
|
|
|
|
|
qt4NodeStaticData()->projectIcon = QIcon();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2010-02-12 12:40:32 +01:00
|
|
|
enum { debug = 0 };
|
|
|
|
|
|
2011-09-07 11:52:04 +02:00
|
|
|
using namespace Qt4ProjectManager;
|
|
|
|
|
using namespace Qt4ProjectManager::Internal;
|
2010-01-20 14:47:08 +01:00
|
|
|
|
2011-11-22 13:10:10 +01:00
|
|
|
Qt4PriFile::Qt4PriFile(Qt4ProjectManager::Qt4PriFileNode *qt4PriFile)
|
2012-02-14 16:43:51 +01:00
|
|
|
: IDocument(qt4PriFile), m_priFile(qt4PriFile)
|
2010-01-20 14:47:08 +01:00
|
|
|
{
|
2013-07-04 13:30:26 +02:00
|
|
|
setFilePath(m_priFile->path());
|
2010-01-20 14:47:08 +01:00
|
|
|
}
|
|
|
|
|
|
2011-05-10 20:43:03 +02:00
|
|
|
bool Qt4PriFile::save(QString *errorString, const QString &fileName, bool autoSave)
|
2010-01-20 14:47:08 +01:00
|
|
|
{
|
2011-03-30 13:45:16 +02:00
|
|
|
Q_UNUSED(errorString);
|
2010-01-20 14:47:08 +01:00
|
|
|
Q_UNUSED(fileName);
|
2011-05-10 20:43:03 +02:00
|
|
|
Q_UNUSED(autoSave);
|
2010-01-20 14:47:08 +01:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString Qt4PriFile::defaultPath() const
|
|
|
|
|
{
|
2010-02-02 17:09:41 +01:00
|
|
|
return QString();
|
2010-01-20 14:47:08 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString Qt4PriFile::suggestedFileName() const
|
|
|
|
|
{
|
2010-02-02 17:09:41 +01:00
|
|
|
return QString();
|
2010-01-20 14:47:08 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString Qt4PriFile::mimeType() const
|
|
|
|
|
{
|
2012-01-13 14:20:45 +01:00
|
|
|
return QLatin1String(Qt4ProjectManager::Constants::PROFILE_MIMETYPE);
|
2010-01-20 14:47:08 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool Qt4PriFile::isModified() const
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool Qt4PriFile::isSaveAsAllowed() const
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2012-02-14 16:43:51 +01:00
|
|
|
Core::IDocument::ReloadBehavior Qt4PriFile::reloadBehavior(ChangeTrigger state, ChangeType type) const
|
2010-01-20 14:47:08 +01:00
|
|
|
{
|
2010-03-19 10:28:05 +01:00
|
|
|
Q_UNUSED(state)
|
|
|
|
|
Q_UNUSED(type)
|
|
|
|
|
return BehaviorSilent;
|
2010-01-20 14:47:08 +01:00
|
|
|
}
|
|
|
|
|
|
2011-04-04 15:24:13 +02:00
|
|
|
bool Qt4PriFile::reload(QString *errorString, ReloadFlag flag, ChangeType type)
|
2010-03-19 10:28:05 +01:00
|
|
|
{
|
2011-04-04 15:24:13 +02:00
|
|
|
Q_UNUSED(errorString)
|
2010-03-19 10:28:05 +01:00
|
|
|
Q_UNUSED(flag)
|
|
|
|
|
if (type == TypePermissions)
|
2011-04-04 15:24:13 +02:00
|
|
|
return true;
|
2010-03-19 10:28:05 +01:00
|
|
|
m_priFile->scheduleUpdate();
|
2011-04-04 15:24:13 +02:00
|
|
|
return true;
|
2010-03-19 10:28:05 +01:00
|
|
|
}
|
2010-01-20 14:47:08 +01:00
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
/*!
|
|
|
|
|
\class Qt4PriFileNode
|
|
|
|
|
Implements abstract ProjectNode class
|
|
|
|
|
*/
|
|
|
|
|
|
2011-11-22 13:10:10 +01:00
|
|
|
namespace Qt4ProjectManager {
|
|
|
|
|
|
2008-12-05 14:29:18 +01:00
|
|
|
Qt4PriFileNode::Qt4PriFileNode(Qt4Project *project, Qt4ProFileNode* qt4ProFileNode, const QString &filePath)
|
2008-12-02 12:01:29 +01:00
|
|
|
: ProjectNode(filePath),
|
|
|
|
|
m_project(project),
|
2008-12-05 14:29:18 +01:00
|
|
|
m_qt4ProFileNode(qt4ProFileNode),
|
2008-12-04 11:10:56 +01:00
|
|
|
m_projectFilePath(QDir::fromNativeSeparators(filePath)),
|
2011-09-06 17:21:51 +02:00
|
|
|
m_projectDir(QFileInfo(filePath).absolutePath()),
|
|
|
|
|
m_includedInExactParse(true)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2008-12-17 15:51:48 +01:00
|
|
|
Q_ASSERT(project);
|
2010-01-22 16:49:57 +01:00
|
|
|
m_qt4PriFile = new Qt4PriFile(this);
|
2012-02-14 16:43:51 +01:00
|
|
|
Core::DocumentManager::addDocument(m_qt4PriFile);
|
2010-01-20 14:47:08 +01:00
|
|
|
|
2010-02-24 15:03:54 +01:00
|
|
|
setDisplayName(QFileInfo(filePath).completeBaseName());
|
2009-01-27 12:40:49 +01:00
|
|
|
|
2010-02-12 12:40:32 +01:00
|
|
|
setIcon(qt4NodeStaticData()->projectIcon);
|
2008-12-09 17:17:12 +01:00
|
|
|
}
|
|
|
|
|
|
2012-03-13 15:44:59 +01:00
|
|
|
Qt4PriFileNode::~Qt4PriFileNode()
|
|
|
|
|
{
|
|
|
|
|
watchFolders(QSet<QString>());
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-09 17:17:12 +01:00
|
|
|
void Qt4PriFileNode::scheduleUpdate()
|
|
|
|
|
{
|
2011-05-20 21:40:53 +02:00
|
|
|
QtSupport::ProFileCacheManager::instance()->discardFile(m_projectFilePath);
|
2008-12-09 17:17:12 +01:00
|
|
|
m_qt4ProFileNode->scheduleUpdate();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2011-09-07 11:52:04 +02:00
|
|
|
namespace Internal {
|
2010-02-12 12:40:32 +01:00
|
|
|
struct InternalNode
|
2010-02-26 12:55:17 +01:00
|
|
|
{
|
2012-05-04 11:49:37 +02:00
|
|
|
QList<InternalNode *> virtualfolders;
|
|
|
|
|
QMap<QString, InternalNode *> subnodes;
|
2010-02-26 12:55:17 +01:00
|
|
|
QStringList files;
|
|
|
|
|
ProjectExplorer::FileType type;
|
2013-02-18 18:47:54 +01:00
|
|
|
int priority;
|
2010-08-10 16:27:35 +02:00
|
|
|
QString displayName;
|
2012-05-04 11:49:37 +02:00
|
|
|
QString typeName;
|
2010-02-26 12:55:17 +01:00
|
|
|
QString fullPath;
|
|
|
|
|
QIcon icon;
|
2009-08-17 17:59:57 +02:00
|
|
|
|
2010-02-26 12:55:17 +01:00
|
|
|
InternalNode()
|
|
|
|
|
{
|
|
|
|
|
type = ProjectExplorer::UnknownFileType;
|
2012-05-04 11:49:37 +02:00
|
|
|
priority = 0;
|
2010-02-26 12:55:17 +01:00
|
|
|
}
|
2009-08-25 15:39:31 +02:00
|
|
|
|
2010-02-26 12:55:17 +01:00
|
|
|
~InternalNode()
|
|
|
|
|
{
|
2012-05-04 11:49:37 +02:00
|
|
|
qDeleteAll(virtualfolders);
|
2010-02-26 12:55:17 +01:00
|
|
|
qDeleteAll(subnodes);
|
|
|
|
|
}
|
2009-08-17 17:59:57 +02:00
|
|
|
|
2013-02-18 18:47:54 +01:00
|
|
|
// Creates: a tree structure from a list of absolute file paths.
|
2010-02-26 12:55:17 +01:00
|
|
|
// Empty directories are compressed into a single entry with a longer path.
|
|
|
|
|
// * project
|
|
|
|
|
// * /absolute/path
|
|
|
|
|
// * file1
|
|
|
|
|
// * relative
|
|
|
|
|
// * path1
|
|
|
|
|
// * file1
|
|
|
|
|
// * file2
|
|
|
|
|
// * path2
|
|
|
|
|
// * file1
|
|
|
|
|
// The method first creates a tree that looks like the directory structure, i.e.
|
|
|
|
|
// * /
|
|
|
|
|
// * absolute
|
|
|
|
|
// * path
|
|
|
|
|
// ...
|
|
|
|
|
// and afterwards calls compress() which merges directory nodes with single children, i.e. to
|
|
|
|
|
// * /absolute/path
|
2011-11-08 18:53:51 +01:00
|
|
|
void create(const QString &projectDir, const QSet<Utils::FileName> &newFilePaths, ProjectExplorer::FileType type)
|
2010-02-26 12:55:17 +01:00
|
|
|
{
|
2012-01-13 14:20:45 +01:00
|
|
|
static const QChar separator = QLatin1Char('/');
|
2011-11-25 13:17:52 +01:00
|
|
|
const Utils::FileName projectDirFileName = Utils::FileName::fromString(projectDir);
|
2011-11-08 18:53:51 +01:00
|
|
|
foreach (const Utils::FileName &file, newFilePaths) {
|
|
|
|
|
Utils::FileName fileWithoutPrefix;
|
2010-02-26 12:55:17 +01:00
|
|
|
bool isRelative;
|
2011-11-25 13:17:52 +01:00
|
|
|
if (file.isChildOf(projectDirFileName)) {
|
2010-02-26 12:55:17 +01:00
|
|
|
isRelative = true;
|
2011-11-25 13:17:52 +01:00
|
|
|
fileWithoutPrefix = file.relativeChildPath(projectDirFileName);
|
2010-02-26 12:55:17 +01:00
|
|
|
} else {
|
|
|
|
|
isRelative = false;
|
|
|
|
|
fileWithoutPrefix = file;
|
|
|
|
|
}
|
2011-11-08 18:53:51 +01:00
|
|
|
QStringList parts = fileWithoutPrefix.toString().split(separator, QString::SkipEmptyParts);
|
2012-08-23 15:53:58 +02:00
|
|
|
if (!Utils::HostOsInfo::isWindowsHost() && !isRelative && parts.count() > 0)
|
2010-02-26 12:55:17 +01:00
|
|
|
parts[0].prepend(separator);
|
|
|
|
|
QStringListIterator it(parts);
|
|
|
|
|
InternalNode *currentNode = this;
|
2012-01-13 14:20:45 +01:00
|
|
|
QString path = (isRelative ? (projectDirFileName.toString() + QLatin1Char('/')) : QString());
|
2010-02-26 12:55:17 +01:00
|
|
|
while (it.hasNext()) {
|
|
|
|
|
const QString &key = it.next();
|
|
|
|
|
if (it.hasNext()) { // key is directory
|
|
|
|
|
path += key;
|
2010-08-10 16:27:35 +02:00
|
|
|
if (!currentNode->subnodes.contains(path)) {
|
2010-02-26 12:55:17 +01:00
|
|
|
InternalNode *val = new InternalNode;
|
|
|
|
|
val->type = type;
|
|
|
|
|
val->fullPath = path;
|
2010-08-10 16:27:35 +02:00
|
|
|
val->displayName = key;
|
|
|
|
|
currentNode->subnodes.insert(path, val);
|
2010-02-26 12:55:17 +01:00
|
|
|
currentNode = val;
|
|
|
|
|
} else {
|
2010-08-10 16:27:35 +02:00
|
|
|
currentNode = currentNode->subnodes.value(path);
|
2009-08-17 17:59:57 +02:00
|
|
|
}
|
2010-02-26 12:55:17 +01:00
|
|
|
path += separator;
|
|
|
|
|
} else { // key is filename
|
2011-11-08 18:53:51 +01:00
|
|
|
currentNode->files.append(file.toString());
|
2009-08-17 17:59:57 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2010-02-26 12:55:17 +01:00
|
|
|
this->compress();
|
|
|
|
|
}
|
2009-08-17 17:59:57 +02:00
|
|
|
|
2010-02-26 12:55:17 +01:00
|
|
|
// Removes folder nodes with only a single sub folder in it
|
|
|
|
|
void compress()
|
|
|
|
|
{
|
|
|
|
|
QMap<QString, InternalNode*> newSubnodes;
|
|
|
|
|
QMapIterator<QString, InternalNode*> i(subnodes);
|
|
|
|
|
while (i.hasNext()) {
|
|
|
|
|
i.next();
|
|
|
|
|
i.value()->compress();
|
|
|
|
|
if (i.value()->files.isEmpty() && i.value()->subnodes.size() == 1) {
|
2010-08-10 16:27:35 +02:00
|
|
|
// replace i.value() by i.value()->subnodes.begin()
|
2010-02-26 12:55:17 +01:00
|
|
|
QString key = i.value()->subnodes.begin().key();
|
2010-08-10 16:27:35 +02:00
|
|
|
InternalNode *keep = i.value()->subnodes.value(key);
|
2012-01-13 14:20:45 +01:00
|
|
|
keep->displayName = i.value()->displayName + QLatin1Char('/') + keep->displayName;
|
2010-08-10 16:27:35 +02:00
|
|
|
newSubnodes.insert(key, keep);
|
2010-02-26 12:55:17 +01:00
|
|
|
i.value()->subnodes.clear();
|
|
|
|
|
delete i.value();
|
|
|
|
|
} else {
|
|
|
|
|
newSubnodes.insert(i.key(), i.value());
|
2009-08-17 17:59:57 +02:00
|
|
|
}
|
|
|
|
|
}
|
2010-02-26 12:55:17 +01:00
|
|
|
subnodes = newSubnodes;
|
|
|
|
|
}
|
2009-08-17 17:59:57 +02:00
|
|
|
|
2012-05-04 11:49:37 +02:00
|
|
|
FolderNode *createFolderNode(InternalNode *node)
|
|
|
|
|
{
|
|
|
|
|
FolderNode *newNode = 0;
|
|
|
|
|
if (node->typeName.isEmpty())
|
|
|
|
|
newNode = new FolderNode(node->fullPath);
|
|
|
|
|
else
|
|
|
|
|
newNode = new ProVirtualFolderNode(node->fullPath, node->priority, node->typeName);
|
|
|
|
|
|
|
|
|
|
newNode->setDisplayName(node->displayName);
|
|
|
|
|
if (!node->icon.isNull())
|
|
|
|
|
newNode->setIcon(node->icon);
|
|
|
|
|
return newNode;
|
|
|
|
|
}
|
|
|
|
|
|
2010-02-26 12:55:17 +01:00
|
|
|
// Makes the projectNode's subtree below the given folder match this internal node's subtree
|
2011-11-22 13:10:10 +01:00
|
|
|
void updateSubFolders(Qt4ProjectManager::Qt4PriFileNode *projectNode, ProjectExplorer::FolderNode *folder)
|
2010-02-26 12:55:17 +01:00
|
|
|
{
|
|
|
|
|
updateFiles(projectNode, folder, type);
|
2009-08-17 17:59:57 +02:00
|
|
|
|
2012-05-04 11:49:37 +02:00
|
|
|
// updateFolders
|
|
|
|
|
QMultiMap<QString, FolderNode *> existingFolderNodes;
|
|
|
|
|
foreach (FolderNode *node, folder->subFolderNodes())
|
2010-02-26 12:55:17 +01:00
|
|
|
if (node->nodeType() != ProjectNodeType)
|
2012-05-04 11:49:37 +02:00
|
|
|
existingFolderNodes.insert(node->path(), node);
|
2010-08-10 16:27:35 +02:00
|
|
|
|
2010-02-26 12:55:17 +01:00
|
|
|
QList<FolderNode *> foldersToRemove;
|
|
|
|
|
QList<FolderNode *> foldersToAdd;
|
|
|
|
|
typedef QPair<InternalNode *, FolderNode *> NodePair;
|
|
|
|
|
QList<NodePair> nodesToUpdate;
|
|
|
|
|
|
2012-05-04 11:49:37 +02:00
|
|
|
// Check virtual
|
|
|
|
|
{
|
|
|
|
|
QList<InternalNode *>::const_iterator it = virtualfolders.constBegin();
|
|
|
|
|
QList<InternalNode *>::const_iterator end = virtualfolders.constEnd();
|
|
|
|
|
for ( ; it != end; ++it) {
|
|
|
|
|
bool found = false;
|
|
|
|
|
QString path = (*it)->fullPath;
|
|
|
|
|
QMultiMap<QString, FolderNode *>::const_iterator oldit
|
|
|
|
|
= existingFolderNodes.constFind(path);
|
2012-05-08 14:38:20 +02:00
|
|
|
while (oldit != existingFolderNodes.constEnd() && oldit.key() == path) {
|
2012-05-04 11:49:37 +02:00
|
|
|
if (oldit.value()->nodeType() == ProjectExplorer::VirtualFolderNodeType) {
|
|
|
|
|
ProjectExplorer::VirtualFolderNode *vfn
|
|
|
|
|
= qobject_cast<ProjectExplorer::VirtualFolderNode *>(oldit.value());
|
|
|
|
|
if (vfn->priority() == (*it)->priority) {
|
|
|
|
|
found = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
++oldit;
|
|
|
|
|
}
|
|
|
|
|
if (found) {
|
|
|
|
|
nodesToUpdate << NodePair(*it, *oldit);
|
|
|
|
|
} else {
|
|
|
|
|
FolderNode *newNode = createFolderNode(*it);
|
|
|
|
|
foldersToAdd << newNode;
|
|
|
|
|
nodesToUpdate << NodePair(*it, newNode);
|
|
|
|
|
}
|
2009-08-17 17:59:57 +02:00
|
|
|
}
|
2010-02-26 12:55:17 +01:00
|
|
|
}
|
2012-05-04 11:49:37 +02:00
|
|
|
// Check subnodes
|
|
|
|
|
{
|
|
|
|
|
QMap<QString, InternalNode *>::const_iterator it = subnodes.constBegin();
|
|
|
|
|
QMap<QString, InternalNode *>::const_iterator end = subnodes.constEnd();
|
|
|
|
|
|
|
|
|
|
for ( ; it != end; ++it) {
|
|
|
|
|
bool found = false;
|
|
|
|
|
QString path = it.value()->fullPath;
|
|
|
|
|
QMultiMap<QString, FolderNode *>::const_iterator oldit
|
|
|
|
|
= existingFolderNodes.constFind(path);
|
2012-05-08 14:38:20 +02:00
|
|
|
while (oldit != existingFolderNodes.constEnd() && oldit.key() == path) {
|
2012-05-04 11:49:37 +02:00
|
|
|
if (oldit.value()->nodeType() == ProjectExplorer::FolderNodeType) {
|
|
|
|
|
found = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
++oldit;
|
|
|
|
|
}
|
|
|
|
|
if (found) {
|
|
|
|
|
nodesToUpdate << NodePair(it.value(), *oldit);
|
|
|
|
|
} else {
|
|
|
|
|
FolderNode *newNode = createFolderNode(it.value());
|
|
|
|
|
foldersToAdd << newNode;
|
|
|
|
|
nodesToUpdate << NodePair(it.value(), newNode);
|
|
|
|
|
}
|
|
|
|
|
}
|
2010-02-26 12:55:17 +01:00
|
|
|
}
|
2009-08-17 17:59:57 +02:00
|
|
|
|
2012-05-04 11:49:37 +02:00
|
|
|
QSet<FolderNode *> toKeep;
|
|
|
|
|
foreach (const NodePair &np, nodesToUpdate)
|
|
|
|
|
toKeep << np.second;
|
|
|
|
|
|
|
|
|
|
QMultiMap<QString, FolderNode *>::const_iterator jit = existingFolderNodes.constBegin();
|
|
|
|
|
QMultiMap<QString, FolderNode *>::const_iterator jend = existingFolderNodes.constEnd();
|
|
|
|
|
for ( ; jit != jend; ++jit)
|
|
|
|
|
if (!toKeep.contains(jit.value()))
|
|
|
|
|
foldersToRemove << jit.value();
|
|
|
|
|
|
2010-02-26 12:55:17 +01:00
|
|
|
if (!foldersToRemove.isEmpty())
|
|
|
|
|
projectNode->removeFolderNodes(foldersToRemove, folder);
|
|
|
|
|
if (!foldersToAdd.isEmpty())
|
|
|
|
|
projectNode->addFolderNodes(foldersToAdd, folder);
|
2009-08-17 17:59:57 +02:00
|
|
|
|
2010-02-26 12:55:17 +01:00
|
|
|
foreach (const NodePair &np, nodesToUpdate)
|
|
|
|
|
np.first->updateSubFolders(projectNode, np.second);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Makes the folder's files match this internal node's file list
|
2011-11-22 13:10:10 +01:00
|
|
|
void updateFiles(Qt4ProjectManager::Qt4PriFileNode *projectNode, FolderNode *folder, FileType type)
|
2010-02-26 12:55:17 +01:00
|
|
|
{
|
|
|
|
|
QList<FileNode*> existingFileNodes;
|
|
|
|
|
foreach (FileNode *fileNode, folder->fileNodes()) {
|
|
|
|
|
if (fileNode->fileType() == type && !fileNode->isGenerated())
|
|
|
|
|
existingFileNodes << fileNode;
|
2009-08-17 17:59:57 +02:00
|
|
|
}
|
|
|
|
|
|
2010-02-26 12:55:17 +01:00
|
|
|
QList<FileNode*> filesToRemove;
|
|
|
|
|
QList<FileNode*> filesToAdd;
|
2009-08-17 17:59:57 +02:00
|
|
|
|
2010-02-26 12:55:17 +01:00
|
|
|
qSort(files);
|
2012-05-04 11:49:37 +02:00
|
|
|
qSort(existingFileNodes.begin(), existingFileNodes.end(), sortNodesByPath);
|
2010-02-26 12:55:17 +01:00
|
|
|
|
|
|
|
|
QList<FileNode*>::const_iterator existingNodeIter = existingFileNodes.constBegin();
|
|
|
|
|
QList<QString>::const_iterator newPathIter = files.constBegin();
|
|
|
|
|
while (existingNodeIter != existingFileNodes.constEnd()
|
|
|
|
|
&& newPathIter != files.constEnd()) {
|
|
|
|
|
if ((*existingNodeIter)->path() < *newPathIter) {
|
2009-08-17 17:59:57 +02:00
|
|
|
filesToRemove << *existingNodeIter;
|
|
|
|
|
++existingNodeIter;
|
2010-02-26 12:55:17 +01:00
|
|
|
} else if ((*existingNodeIter)->path() > *newPathIter) {
|
2011-05-25 11:23:25 +02:00
|
|
|
filesToAdd << new ProjectExplorer::FileNode(*newPathIter, type, false);
|
2009-08-17 17:59:57 +02:00
|
|
|
++newPathIter;
|
2010-02-26 12:55:17 +01:00
|
|
|
} else { // *existingNodeIter->path() == *newPathIter
|
|
|
|
|
++existingNodeIter;
|
|
|
|
|
++newPathIter;
|
2009-08-17 17:59:57 +02:00
|
|
|
}
|
|
|
|
|
}
|
2010-02-26 12:55:17 +01:00
|
|
|
while (existingNodeIter != existingFileNodes.constEnd()) {
|
|
|
|
|
filesToRemove << *existingNodeIter;
|
|
|
|
|
++existingNodeIter;
|
|
|
|
|
}
|
|
|
|
|
while (newPathIter != files.constEnd()) {
|
2011-05-25 11:23:25 +02:00
|
|
|
filesToAdd << new ProjectExplorer::FileNode(*newPathIter, type, false);
|
2010-02-26 12:55:17 +01:00
|
|
|
++newPathIter;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!filesToRemove.isEmpty())
|
|
|
|
|
projectNode->removeFileNodes(filesToRemove, folder);
|
|
|
|
|
if (!filesToAdd.isEmpty())
|
|
|
|
|
projectNode->addFileNodes(filesToAdd, folder);
|
|
|
|
|
}
|
|
|
|
|
};
|
2011-09-07 11:52:04 +02:00
|
|
|
}
|
2010-03-10 16:55:37 +01:00
|
|
|
|
2012-11-28 13:46:49 +01:00
|
|
|
QStringList Qt4PriFileNode::baseVPaths(QtSupport::ProFileReader *reader, const QString &projectDir, const QString &buildDir) const
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2010-03-10 16:55:37 +01:00
|
|
|
QStringList result;
|
|
|
|
|
if (!reader)
|
|
|
|
|
return result;
|
2012-01-13 14:20:45 +01:00
|
|
|
result += reader->absolutePathValues(QLatin1String("VPATH"), projectDir);
|
2010-03-10 16:55:37 +01:00
|
|
|
result << projectDir; // QMAKE_ABSOLUTE_SOURCE_PATH
|
2012-11-28 13:46:49 +01:00
|
|
|
result << buildDir;
|
2010-03-10 16:55:37 +01:00
|
|
|
result.removeDuplicates();
|
|
|
|
|
return result;
|
|
|
|
|
}
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2012-06-05 17:27:10 +02:00
|
|
|
QStringList Qt4PriFileNode::fullVPaths(const QStringList &baseVPaths, QtSupport::ProFileReader *reader,
|
2012-11-28 13:46:49 +01:00
|
|
|
const QString &qmakeVariable, const QString &projectDir) const
|
2010-03-10 16:55:37 +01:00
|
|
|
{
|
|
|
|
|
QStringList vPaths;
|
|
|
|
|
if (!reader)
|
|
|
|
|
return vPaths;
|
2012-11-28 13:46:49 +01:00
|
|
|
vPaths = reader->absolutePathValues(QLatin1String("VPATH_") + qmakeVariable, projectDir);
|
2010-03-10 16:55:37 +01:00
|
|
|
vPaths += baseVPaths;
|
|
|
|
|
vPaths.removeDuplicates();
|
|
|
|
|
return vPaths;
|
|
|
|
|
}
|
|
|
|
|
|
2013-07-01 11:35:38 +02:00
|
|
|
QSet<Utils::FileName> Qt4PriFileNode::recursiveEnumerate(const QString &folder)
|
2010-08-10 16:27:35 +02:00
|
|
|
{
|
2011-11-08 18:53:51 +01:00
|
|
|
QSet<Utils::FileName> result;
|
2010-08-10 16:27:35 +02:00
|
|
|
QFileInfo fi(folder);
|
|
|
|
|
if (fi.isDir()) {
|
|
|
|
|
QDir dir(folder);
|
|
|
|
|
dir.setFilter(dir.filter() | QDir::NoDotAndDotDot);
|
|
|
|
|
|
|
|
|
|
foreach (const QFileInfo &file, dir.entryInfoList()) {
|
2012-01-05 15:16:26 +01:00
|
|
|
if (file.isDir() && !file.isSymLink())
|
2010-08-10 16:27:35 +02:00
|
|
|
result += recursiveEnumerate(file.absoluteFilePath());
|
|
|
|
|
else
|
2011-11-08 18:53:51 +01:00
|
|
|
result += Utils::FileName(file);
|
2010-08-10 16:27:35 +02:00
|
|
|
}
|
|
|
|
|
} else if (fi.exists()) {
|
2011-11-08 18:53:51 +01:00
|
|
|
result << Utils::FileName(fi);
|
2010-08-10 16:27:35 +02:00
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
2010-03-10 16:55:37 +01:00
|
|
|
|
2011-05-20 21:40:53 +02:00
|
|
|
void Qt4PriFileNode::update(ProFile *includeFileExact, QtSupport::ProFileReader *readerExact, ProFile *includeFileCumlative, QtSupport::ProFileReader *readerCumulative)
|
2010-03-10 16:55:37 +01:00
|
|
|
{
|
2008-12-02 12:01:29 +01:00
|
|
|
// add project file node
|
|
|
|
|
if (m_fileNodes.isEmpty())
|
2011-05-25 11:23:25 +02:00
|
|
|
addFileNodes(QList<FileNode*>() << new ProjectExplorer::FileNode(m_projectFilePath, ProjectExplorer::ProjectFileType, false), this);
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2009-07-10 13:37:02 +02:00
|
|
|
const QString &projectDir = m_qt4ProFileNode->m_projectDir;
|
|
|
|
|
|
2009-08-17 17:59:57 +02:00
|
|
|
InternalNode contents;
|
|
|
|
|
|
2012-09-07 12:35:18 +02:00
|
|
|
ProjectExplorer::Target *t = m_project->activeTarget();
|
|
|
|
|
ProjectExplorer::Kit *k = t ? t->kit() : ProjectExplorer::KitManager::instance()->defaultKit();
|
|
|
|
|
QtSupport::BaseQtVersion *qtVersion = QtSupport::QtKitInformation::qtVersion(k);
|
|
|
|
|
|
2010-08-10 16:27:35 +02:00
|
|
|
// Figure out DEPLOYMENT and INSTALL folders
|
|
|
|
|
QStringList folders;
|
2012-09-07 12:35:18 +02:00
|
|
|
QStringList dynamicVariables = dynamicVarNames(readerExact, readerCumulative, qtVersion);
|
2011-02-09 14:59:07 +01:00
|
|
|
if (includeFileExact)
|
|
|
|
|
foreach (const QString &dynamicVar, dynamicVariables) {
|
|
|
|
|
folders += readerExact->values(dynamicVar, includeFileExact);
|
|
|
|
|
// Ignore stuff from cumulative parse
|
|
|
|
|
// we are recursively enumerating all the files from those folders
|
|
|
|
|
// and add watchers for them, that's too dangerous if we get the foldrs
|
|
|
|
|
// wrong and enumerate the whole project tree multiple times
|
|
|
|
|
}
|
2010-08-10 16:27:35 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
for (int i=0; i < folders.size(); ++i) {
|
2011-02-25 15:27:13 +01:00
|
|
|
const QFileInfo fi(folders.at(i));
|
2010-08-10 16:27:35 +02:00
|
|
|
if (fi.isRelative())
|
2012-01-13 14:20:45 +01:00
|
|
|
folders[i] = QDir::cleanPath(projectDir + QLatin1Char('/') + folders.at(i));
|
2010-08-10 16:27:35 +02:00
|
|
|
}
|
|
|
|
|
|
2010-08-12 15:04:24 +02:00
|
|
|
|
|
|
|
|
m_recursiveEnumerateFiles.clear();
|
2010-08-12 13:38:21 +02:00
|
|
|
// Remove non existing items and non folders
|
2010-08-11 15:25:56 +02:00
|
|
|
QStringList::iterator it = folders.begin();
|
|
|
|
|
while (it != folders.end()) {
|
|
|
|
|
QFileInfo fi(*it);
|
2010-08-12 15:04:24 +02:00
|
|
|
if (fi.exists()) {
|
|
|
|
|
if (fi.isDir()) {
|
|
|
|
|
// keep directories
|
|
|
|
|
++it;
|
|
|
|
|
} else {
|
|
|
|
|
// move files directly to m_recursiveEnumerateFiles
|
2011-11-08 18:53:51 +01:00
|
|
|
m_recursiveEnumerateFiles << Utils::FileName::fromString(*it);
|
2010-08-12 15:04:24 +02:00
|
|
|
it = folders.erase(it);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// do remove non exsting stuff
|
2010-08-11 15:25:56 +02:00
|
|
|
it = folders.erase(it);
|
2010-08-12 15:04:24 +02:00
|
|
|
}
|
2010-08-11 15:25:56 +02:00
|
|
|
}
|
|
|
|
|
|
2010-08-10 16:27:35 +02:00
|
|
|
folders.removeDuplicates();
|
|
|
|
|
watchFolders(folders.toSet());
|
|
|
|
|
|
|
|
|
|
foreach (const QString &folder, folders) {
|
|
|
|
|
m_recursiveEnumerateFiles += recursiveEnumerate(folder);
|
|
|
|
|
}
|
2011-11-08 18:53:51 +01:00
|
|
|
QMap<FileType, QSet<Utils::FileName> > foundFiles;
|
2010-10-25 13:57:45 +02:00
|
|
|
|
2011-02-09 14:59:07 +01:00
|
|
|
QStringList baseVPathsExact;
|
|
|
|
|
if (includeFileExact)
|
2012-11-28 13:46:49 +01:00
|
|
|
baseVPathsExact = baseVPaths(readerExact, projectDir, m_qt4ProFileNode->buildDir());
|
2011-02-09 14:59:07 +01:00
|
|
|
QStringList baseVPathsCumulative;
|
|
|
|
|
if (includeFileCumlative)
|
2012-11-28 13:46:49 +01:00
|
|
|
baseVPathsCumulative = baseVPaths(readerCumulative, projectDir, m_qt4ProFileNode->buildDir());
|
2011-02-09 14:59:07 +01:00
|
|
|
|
|
|
|
|
const QVector<Qt4NodeStaticData::FileTypeData> &fileTypes = qt4NodeStaticData()->fileTypeData;
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
// update files
|
2009-08-17 17:59:57 +02:00
|
|
|
for (int i = 0; i < fileTypes.size(); ++i) {
|
2010-02-12 12:40:32 +01:00
|
|
|
FileType type = fileTypes.at(i).type;
|
2010-08-10 16:27:35 +02:00
|
|
|
QStringList qmakeVariables = varNames(type);
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2011-11-08 18:53:51 +01:00
|
|
|
QSet<Utils::FileName> newFilePaths;
|
2009-07-10 13:37:02 +02:00
|
|
|
foreach (const QString &qmakeVariable, qmakeVariables) {
|
2011-02-09 14:59:07 +01:00
|
|
|
if (includeFileExact) {
|
2012-11-28 13:46:49 +01:00
|
|
|
QStringList vPathsExact = fullVPaths(baseVPathsExact, readerExact, qmakeVariable, projectDir);
|
2011-11-08 18:53:51 +01:00
|
|
|
QStringList tmp = readerExact->absoluteFileValues(qmakeVariable, projectDir, vPathsExact, includeFileExact);
|
|
|
|
|
foreach (const QString &t, tmp)
|
|
|
|
|
newFilePaths += Utils::FileName::fromString(t);
|
2011-02-09 14:59:07 +01:00
|
|
|
}
|
|
|
|
|
if (includeFileCumlative) {
|
2012-11-28 13:46:49 +01:00
|
|
|
QStringList vPathsCumulative = fullVPaths(baseVPathsCumulative, readerCumulative, qmakeVariable, projectDir);
|
2011-11-08 18:53:51 +01:00
|
|
|
QStringList tmp = readerCumulative->absoluteFileValues(qmakeVariable, projectDir, vPathsCumulative, includeFileCumlative);
|
|
|
|
|
foreach (const QString &t, tmp)
|
|
|
|
|
newFilePaths += Utils::FileName::fromString(t);
|
2011-02-09 14:59:07 +01:00
|
|
|
}
|
2009-07-10 13:37:02 +02:00
|
|
|
}
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2010-10-25 13:57:45 +02:00
|
|
|
foundFiles[type] = newFilePaths;
|
|
|
|
|
m_recursiveEnumerateFiles.subtract(newFilePaths);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < fileTypes.size(); ++i) {
|
|
|
|
|
FileType type = fileTypes.at(i).type;
|
2011-11-08 18:53:51 +01:00
|
|
|
QSet<Utils::FileName> newFilePaths = filterFilesProVariables(type, foundFiles[type]);
|
2011-06-30 17:57:52 +02:00
|
|
|
newFilePaths += filterFilesRecursiveEnumerata(type, m_recursiveEnumerateFiles);
|
2010-08-10 16:27:35 +02:00
|
|
|
|
|
|
|
|
// We only need to save this information if
|
|
|
|
|
// we are watching folders
|
|
|
|
|
if (!folders.isEmpty())
|
|
|
|
|
m_files[type] = newFilePaths;
|
|
|
|
|
else
|
|
|
|
|
m_files[type].clear();
|
|
|
|
|
|
2009-08-17 17:59:57 +02:00
|
|
|
if (!newFilePaths.isEmpty()) {
|
|
|
|
|
InternalNode *subfolder = new InternalNode;
|
|
|
|
|
subfolder->type = type;
|
2010-02-12 12:40:32 +01:00
|
|
|
subfolder->icon = fileTypes.at(i).icon;
|
2012-05-04 11:49:37 +02:00
|
|
|
subfolder->fullPath = m_projectDir;
|
|
|
|
|
subfolder->typeName = fileTypes.at(i).typeName;
|
|
|
|
|
subfolder->priority = -i;
|
2010-08-10 16:27:35 +02:00
|
|
|
subfolder->displayName = fileTypes.at(i).typeName;
|
2012-05-04 11:49:37 +02:00
|
|
|
contents.virtualfolders.append(subfolder);
|
2009-08-17 17:59:57 +02:00
|
|
|
// create the hierarchy with subdirectories
|
2011-11-08 18:53:51 +01:00
|
|
|
subfolder->create(m_projectDir, newFilePaths, type);
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
}
|
2010-08-10 16:27:35 +02:00
|
|
|
|
|
|
|
|
contents.updateSubFolders(this, this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Qt4PriFileNode::watchFolders(const QSet<QString> &folders)
|
|
|
|
|
{
|
|
|
|
|
QSet<QString> toUnwatch = m_watchedFolders;
|
|
|
|
|
toUnwatch.subtract(folders);
|
|
|
|
|
|
|
|
|
|
QSet<QString> toWatch = folders;
|
|
|
|
|
toWatch.subtract(m_watchedFolders);
|
|
|
|
|
|
|
|
|
|
if (!toUnwatch.isEmpty())
|
2011-08-18 16:46:44 +02:00
|
|
|
m_project->unwatchFolders(toUnwatch.toList(), this);
|
2010-08-10 16:27:35 +02:00
|
|
|
if (!toWatch.isEmpty())
|
2011-08-18 16:46:44 +02:00
|
|
|
m_project->watchFolders(toWatch.toList(), this);
|
2010-08-10 16:27:35 +02:00
|
|
|
|
|
|
|
|
m_watchedFolders = folders;
|
|
|
|
|
}
|
|
|
|
|
|
2013-07-01 11:35:38 +02:00
|
|
|
bool Qt4PriFileNode::folderChanged(const QString &changedFolder, const QSet<Utils::FileName> &newFiles)
|
2010-08-10 16:27:35 +02:00
|
|
|
{
|
2013-07-01 11:35:38 +02:00
|
|
|
//qDebug()<<"########## Qt4PriFileNode::folderChanged";
|
|
|
|
|
// So, we need to figure out which files changed.
|
|
|
|
|
|
|
|
|
|
QSet<Utils::FileName> addedFiles = newFiles;
|
|
|
|
|
addedFiles.subtract(m_recursiveEnumerateFiles);
|
|
|
|
|
|
|
|
|
|
QSet<Utils::FileName> removedFiles = m_recursiveEnumerateFiles;
|
|
|
|
|
removedFiles.subtract(newFiles);
|
|
|
|
|
|
|
|
|
|
foreach (const Utils::FileName &file, removedFiles) {
|
|
|
|
|
if (!file.isChildOf(Utils::FileName::fromString(changedFolder)))
|
|
|
|
|
removedFiles.remove(file);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (addedFiles.isEmpty() && removedFiles.isEmpty())
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
m_recursiveEnumerateFiles = newFiles;
|
|
|
|
|
|
|
|
|
|
// Apply the differences
|
|
|
|
|
// per file type
|
|
|
|
|
const QVector<Qt4NodeStaticData::FileTypeData> &fileTypes = qt4NodeStaticData()->fileTypeData;
|
|
|
|
|
for (int i = 0; i < fileTypes.size(); ++i) {
|
|
|
|
|
FileType type = fileTypes.at(i).type;
|
|
|
|
|
QSet<Utils::FileName> add = filterFilesRecursiveEnumerata(type, addedFiles);
|
|
|
|
|
QSet<Utils::FileName> remove = filterFilesRecursiveEnumerata(type, removedFiles);
|
|
|
|
|
|
|
|
|
|
if (!add.isEmpty() || !remove.isEmpty()) {
|
|
|
|
|
// Scream :)
|
|
|
|
|
// qDebug()<<"For type"<<fileTypes.at(i).typeName<<"\n"
|
|
|
|
|
// <<"added files"<<add<<"\n"
|
|
|
|
|
// <<"removed files"<<remove;
|
|
|
|
|
|
|
|
|
|
m_files[type].unite(add);
|
|
|
|
|
m_files[type].subtract(remove);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Now apply stuff
|
|
|
|
|
InternalNode contents;
|
|
|
|
|
for (int i = 0; i < fileTypes.size(); ++i) {
|
|
|
|
|
FileType type = fileTypes.at(i).type;
|
|
|
|
|
if (!m_files[type].isEmpty()) {
|
|
|
|
|
InternalNode *subfolder = new InternalNode;
|
|
|
|
|
subfolder->type = type;
|
|
|
|
|
subfolder->icon = fileTypes.at(i).icon;
|
|
|
|
|
subfolder->fullPath = m_projectDir;
|
|
|
|
|
subfolder->typeName = fileTypes.at(i).typeName;
|
|
|
|
|
subfolder->priority = -i;
|
|
|
|
|
subfolder->displayName = fileTypes.at(i).typeName;
|
|
|
|
|
contents.virtualfolders.append(subfolder);
|
|
|
|
|
// create the hierarchy with subdirectories
|
|
|
|
|
subfolder->create(m_projectDir, m_files[type], type);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
contents.updateSubFolders(this, this);
|
|
|
|
|
return true;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2010-08-24 17:17:11 +02:00
|
|
|
bool Qt4PriFileNode::deploysFolder(const QString &folder) const
|
|
|
|
|
{
|
|
|
|
|
QString f = folder;
|
2012-01-13 14:20:45 +01:00
|
|
|
const QChar slash = QLatin1Char('/');
|
|
|
|
|
if (!f.endsWith(slash))
|
|
|
|
|
f.append(slash);
|
2010-08-24 17:17:11 +02:00
|
|
|
foreach (const QString &wf, m_watchedFolders) {
|
|
|
|
|
if (f.startsWith(wf)
|
2012-01-13 14:20:45 +01:00
|
|
|
&& (wf.endsWith(slash)
|
|
|
|
|
|| (wf.length() < f.length() && f.at(wf.length()) == slash)))
|
2010-08-24 17:17:11 +02:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2011-01-20 18:05:58 +01:00
|
|
|
QList<ProjectExplorer::RunConfiguration *> Qt4PriFileNode::runConfigurationsFor(Node *node)
|
|
|
|
|
{
|
2012-04-24 15:49:09 +02:00
|
|
|
QmakeRunConfigurationFactory *factory = QmakeRunConfigurationFactory::find(m_project->activeTarget());
|
|
|
|
|
if (factory)
|
|
|
|
|
return factory->runConfigurationsForNode(m_project->activeTarget(), node);
|
2011-10-28 10:15:04 +00:00
|
|
|
return QList<ProjectExplorer::RunConfiguration *>();
|
2011-01-20 18:05:58 +01:00
|
|
|
}
|
|
|
|
|
|
2011-09-06 17:21:51 +02:00
|
|
|
QList<Qt4PriFileNode *> Qt4PriFileNode::subProjectNodesExact() const
|
|
|
|
|
{
|
|
|
|
|
QList<Qt4PriFileNode *> nodes;
|
|
|
|
|
foreach (ProjectNode *node, subProjectNodes()) {
|
|
|
|
|
Qt4PriFileNode *n = qobject_cast<Qt4PriFileNode *>(node);
|
|
|
|
|
if (n && n->includedInExactParse())
|
|
|
|
|
nodes << n;
|
|
|
|
|
}
|
|
|
|
|
return nodes;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool Qt4PriFileNode::includedInExactParse() const
|
|
|
|
|
{
|
|
|
|
|
return m_includedInExactParse;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Qt4PriFileNode::setIncludedInExactParse(bool b)
|
|
|
|
|
{
|
|
|
|
|
m_includedInExactParse = b;
|
|
|
|
|
}
|
|
|
|
|
|
2010-05-11 14:13:38 +02:00
|
|
|
QList<ProjectNode::ProjectAction> Qt4PriFileNode::supportedActions(Node *node) const
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
|
|
|
|
QList<ProjectAction> actions;
|
2008-12-05 14:29:18 +01:00
|
|
|
|
|
|
|
|
const FolderNode *folderNode = this;
|
|
|
|
|
const Qt4ProFileNode *proFileNode;
|
|
|
|
|
while (!(proFileNode = qobject_cast<const Qt4ProFileNode*>(folderNode)))
|
|
|
|
|
folderNode = folderNode->parentFolderNode();
|
2008-12-17 15:51:48 +01:00
|
|
|
Q_ASSERT(proFileNode);
|
2008-12-05 14:29:18 +01:00
|
|
|
|
|
|
|
|
switch (proFileNode->projectType()) {
|
|
|
|
|
case ApplicationTemplate:
|
2011-05-05 17:42:35 +02:00
|
|
|
case LibraryTemplate:
|
|
|
|
|
case AuxTemplate: {
|
|
|
|
|
// TODO: Some of the file types don't make much sense for aux
|
|
|
|
|
// projects (e.g. cpp). It'd be nice if the "add" action could
|
|
|
|
|
// work on a subset of the file types according to project type.
|
|
|
|
|
|
2010-08-24 17:17:11 +02:00
|
|
|
actions << AddNewFile;
|
Remove braces for single lines of conditions
#!/usr/bin/env ruby
Dir.glob('**/*.cpp') { |file|
# skip ast (excluding paste, astpath, and canv'ast'imer)
next if file =~ /ast[^eip]|keywords\.|qualifiers|preprocessor|names.cpp/i
s = File.read(file)
next if s.include?('qlalr')
orig = s.dup
s.gsub!(/\n *if [^\n]*{\n[^\n]*\n\s+}(\s+else if [^\n]* {\n[^\n]*\n\s+})*(\s+else {\n[^\n]*\n\s+})?\n/m) { |m|
res = $&
if res =~ /^\s*(\/\/|[A-Z_]{3,})/ # C++ comment or macro (Q_UNUSED, SDEBUG), do not touch braces
res
else
res.gsub!('} else', 'else')
res.gsub!(/\n +} *\n/m, "\n")
res.gsub(/ *{$/, '')
end
}
s.gsub!(/ *$/, '')
File.open(file, 'wb').write(s) if s != orig
}
Change-Id: I3b30ee60df0986f66c02132c65fc38a3fbb6bbdc
Reviewed-by: hjk <qthjk@ovi.com>
2013-01-08 03:32:53 +02:00
|
|
|
if (m_recursiveEnumerateFiles.contains(Utils::FileName::fromString(node->path())))
|
2010-08-11 14:49:42 +02:00
|
|
|
actions << EraseFile;
|
Remove braces for single lines of conditions
#!/usr/bin/env ruby
Dir.glob('**/*.cpp') { |file|
# skip ast (excluding paste, astpath, and canv'ast'imer)
next if file =~ /ast[^eip]|keywords\.|qualifiers|preprocessor|names.cpp/i
s = File.read(file)
next if s.include?('qlalr')
orig = s.dup
s.gsub!(/\n *if [^\n]*{\n[^\n]*\n\s+}(\s+else if [^\n]* {\n[^\n]*\n\s+})*(\s+else {\n[^\n]*\n\s+})?\n/m) { |m|
res = $&
if res =~ /^\s*(\/\/|[A-Z_]{3,})/ # C++ comment or macro (Q_UNUSED, SDEBUG), do not touch braces
res
else
res.gsub!('} else', 'else')
res.gsub!(/\n +} *\n/m, "\n")
res.gsub(/ *{$/, '')
end
}
s.gsub!(/ *$/, '')
File.open(file, 'wb').write(s) if s != orig
}
Change-Id: I3b30ee60df0986f66c02132c65fc38a3fbb6bbdc
Reviewed-by: hjk <qthjk@ovi.com>
2013-01-08 03:32:53 +02:00
|
|
|
else
|
2010-08-10 16:27:35 +02:00
|
|
|
actions << RemoveFile;
|
2010-08-24 17:17:11 +02:00
|
|
|
|
2010-08-24 18:22:57 +02:00
|
|
|
bool addExistingFiles = true;
|
2012-05-04 11:49:37 +02:00
|
|
|
if (node->nodeType() == ProjectExplorer::VirtualFolderNodeType) {
|
2010-08-24 18:22:57 +02:00
|
|
|
// A virtual folder, we do what the projectexplorer does
|
|
|
|
|
FolderNode *folder = qobject_cast<FolderNode *>(node);
|
|
|
|
|
if (folder) {
|
|
|
|
|
QStringList list;
|
|
|
|
|
foreach (FolderNode *f, folder->subFolderNodes())
|
2012-01-13 14:20:45 +01:00
|
|
|
list << f->path() + QLatin1Char('/');
|
2010-08-24 18:22:57 +02:00
|
|
|
if (deploysFolder(Utils::commonPath(list)))
|
|
|
|
|
addExistingFiles = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2010-08-27 13:32:32 +02:00
|
|
|
addExistingFiles = addExistingFiles && !deploysFolder(node->path());
|
2010-08-24 18:22:57 +02:00
|
|
|
|
|
|
|
|
if (addExistingFiles)
|
2010-08-24 17:17:11 +02:00
|
|
|
actions << AddExistingFile;
|
|
|
|
|
|
2008-12-05 14:29:18 +01:00
|
|
|
break;
|
2010-08-24 18:22:57 +02:00
|
|
|
}
|
2008-12-05 14:29:18 +01:00
|
|
|
case SubDirsTemplate:
|
|
|
|
|
actions << AddSubProject << RemoveSubProject;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
2010-05-11 14:13:38 +02:00
|
|
|
|
2011-05-25 11:23:25 +02:00
|
|
|
ProjectExplorer::FileNode *fileNode = qobject_cast<FileNode *>(node);
|
2010-05-11 14:13:38 +02:00
|
|
|
if (fileNode && fileNode->fileType() != ProjectExplorer::ProjectFileType)
|
|
|
|
|
actions << Rename;
|
|
|
|
|
|
2011-10-28 10:15:04 +00:00
|
|
|
|
2012-04-24 15:49:09 +02:00
|
|
|
ProjectExplorer::Target *target = m_project->activeTarget();
|
|
|
|
|
QmakeRunConfigurationFactory *factory = QmakeRunConfigurationFactory::find(target);
|
|
|
|
|
if (factory && !factory->runConfigurationsForNode(target, node).isEmpty())
|
2011-01-20 18:05:58 +01:00
|
|
|
actions << HasSubProjectRunConfigurations;
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
return actions;
|
|
|
|
|
}
|
|
|
|
|
|
2010-08-26 18:33:16 +02:00
|
|
|
bool Qt4PriFileNode::canAddSubProject(const QString &proFilePath) const
|
|
|
|
|
{
|
|
|
|
|
QFileInfo fi(proFilePath);
|
|
|
|
|
if (fi.suffix() == QLatin1String("pro")
|
|
|
|
|
|| fi.suffix() == QLatin1String("pri"))
|
|
|
|
|
return true;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2010-08-27 15:44:15 +02:00
|
|
|
static QString simplifyProFilePath(const QString &proFilePath)
|
|
|
|
|
{
|
|
|
|
|
// if proFilePath is like: _path_/projectName/projectName.pro
|
|
|
|
|
// we simplify it to: _path_/projectName
|
|
|
|
|
QFileInfo fi(proFilePath);
|
|
|
|
|
const QString parentPath = fi.absolutePath();
|
|
|
|
|
QFileInfo parentFi(parentPath);
|
|
|
|
|
if (parentFi.fileName() == fi.completeBaseName())
|
|
|
|
|
return parentPath;
|
|
|
|
|
return proFilePath;
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
bool Qt4PriFileNode::addSubProjects(const QStringList &proFilePaths)
|
|
|
|
|
{
|
2010-08-26 18:33:16 +02:00
|
|
|
ProjectExplorer::FindAllFilesVisitor visitor;
|
|
|
|
|
accept(&visitor);
|
|
|
|
|
const QStringList &allFiles = visitor.filePaths();
|
|
|
|
|
|
|
|
|
|
QStringList uniqueProFilePaths;
|
2010-08-27 15:44:15 +02:00
|
|
|
foreach (const QString &proFile, proFilePaths)
|
|
|
|
|
if (!allFiles.contains(proFile))
|
|
|
|
|
uniqueProFilePaths.append(simplifyProFilePath(proFile));
|
2010-08-26 18:33:16 +02:00
|
|
|
|
|
|
|
|
QStringList failedFiles;
|
2013-07-01 16:13:48 +02:00
|
|
|
changeFiles(QLatin1String(Constants::PROFILE_MIMETYPE), uniqueProFilePaths, &failedFiles, AddToProFile);
|
2010-08-26 18:33:16 +02:00
|
|
|
|
|
|
|
|
return failedFiles.isEmpty();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool Qt4PriFileNode::removeSubProjects(const QStringList &proFilePaths)
|
|
|
|
|
{
|
2010-08-27 15:44:15 +02:00
|
|
|
QStringList failedOriginalFiles;
|
2013-07-01 16:13:48 +02:00
|
|
|
changeFiles(QLatin1String(Constants::PROFILE_MIMETYPE), proFilePaths, &failedOriginalFiles, RemoveFromProFile);
|
2010-08-27 15:44:15 +02:00
|
|
|
|
|
|
|
|
QStringList simplifiedProFiles;
|
|
|
|
|
foreach (const QString &proFile, failedOriginalFiles)
|
|
|
|
|
simplifiedProFiles.append(simplifyProFilePath(proFile));
|
|
|
|
|
|
|
|
|
|
QStringList failedSimplifiedFiles;
|
2013-07-01 16:13:48 +02:00
|
|
|
changeFiles(QLatin1String(Constants::PROFILE_MIMETYPE), simplifiedProFiles, &failedSimplifiedFiles, RemoveFromProFile);
|
2010-08-27 15:44:15 +02:00
|
|
|
|
|
|
|
|
return failedSimplifiedFiles.isEmpty();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2013-07-01 16:13:48 +02:00
|
|
|
bool Qt4PriFileNode::addFiles(const QStringList &filePaths, QStringList *notAdded)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2010-05-18 16:29:41 +02:00
|
|
|
// If a file is already referenced in the .pro file then we don't add them.
|
|
|
|
|
// That ignores scopes and which variable was used to reference the file
|
|
|
|
|
// So it's obviously a bit limited, but in those cases you need to edit the
|
|
|
|
|
// project files manually anyway.
|
|
|
|
|
|
|
|
|
|
ProjectExplorer::FindAllFilesVisitor visitor;
|
|
|
|
|
accept(&visitor);
|
|
|
|
|
const QStringList &allFiles = visitor.filePaths();
|
|
|
|
|
|
2013-07-01 16:13:48 +02:00
|
|
|
typedef QMap<QString, QStringList> TypeFileMap;
|
|
|
|
|
// Split into lists by file type and bulk-add them.
|
|
|
|
|
TypeFileMap typeFileMap;
|
|
|
|
|
const Core::MimeDatabase *mdb = Core::ICore::mimeDatabase();
|
|
|
|
|
foreach (const QString file, filePaths) {
|
|
|
|
|
const Core::MimeType mt = mdb->findByFile(file);
|
|
|
|
|
typeFileMap[mt.type()] << file;
|
2010-06-08 12:15:43 +02:00
|
|
|
}
|
|
|
|
|
|
2013-07-01 16:13:48 +02:00
|
|
|
QStringList failedFiles;
|
|
|
|
|
foreach (const QString &type, typeFileMap.keys()) {
|
|
|
|
|
const QStringList typeFiles = typeFileMap.value(type);
|
|
|
|
|
QStringList qrcFiles; // the list of qrc files referenced from ui files
|
|
|
|
|
if (type == QLatin1String(ProjectExplorer::Constants::RESOURCE_MIMETYPE)) {
|
|
|
|
|
foreach (const QString &formFile, typeFiles) {
|
|
|
|
|
QStringList resourceFiles = formResources(formFile);
|
|
|
|
|
foreach (const QString &resourceFile, resourceFiles)
|
|
|
|
|
if (!qrcFiles.contains(resourceFile))
|
|
|
|
|
qrcFiles.append(resourceFile);
|
|
|
|
|
}
|
|
|
|
|
}
|
2010-06-08 12:15:43 +02:00
|
|
|
|
2013-07-01 16:13:48 +02:00
|
|
|
QStringList uniqueQrcFiles;
|
|
|
|
|
foreach (const QString &file, qrcFiles) {
|
|
|
|
|
if (!allFiles.contains(file))
|
|
|
|
|
uniqueQrcFiles.append(file);
|
|
|
|
|
}
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2013-07-01 16:13:48 +02:00
|
|
|
QStringList uniqueFilePaths;
|
|
|
|
|
foreach (const QString &file, typeFiles) {
|
|
|
|
|
if (!allFiles.contains(file))
|
|
|
|
|
uniqueFilePaths.append(file);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
changeFiles(type, uniqueFilePaths, &failedFiles, AddToProFile);
|
|
|
|
|
if (notAdded)
|
|
|
|
|
*notAdded += failedFiles;
|
|
|
|
|
changeFiles(QLatin1String(ProjectExplorer::Constants::RESOURCE_MIMETYPE), uniqueQrcFiles, &failedFiles, AddToProFile);
|
|
|
|
|
if (notAdded)
|
|
|
|
|
*notAdded += failedFiles;
|
|
|
|
|
}
|
2008-12-02 12:01:29 +01:00
|
|
|
return failedFiles.isEmpty();
|
|
|
|
|
}
|
|
|
|
|
|
2013-07-01 16:13:48 +02:00
|
|
|
bool Qt4PriFileNode::removeFiles(const QStringList &filePaths,
|
2008-12-02 12:01:29 +01:00
|
|
|
QStringList *notRemoved)
|
|
|
|
|
{
|
|
|
|
|
QStringList failedFiles;
|
2013-07-01 16:13:48 +02:00
|
|
|
typedef QMap<QString, QStringList> TypeFileMap;
|
|
|
|
|
// Split into lists by file type and bulk-add them.
|
|
|
|
|
TypeFileMap typeFileMap;
|
|
|
|
|
const Core::MimeDatabase *mdb = Core::ICore::mimeDatabase();
|
|
|
|
|
foreach (const QString file, filePaths) {
|
|
|
|
|
const Core::MimeType mt = mdb->findByFile(file);
|
|
|
|
|
typeFileMap[mt.type()] << file;
|
|
|
|
|
}
|
|
|
|
|
foreach (const QString &type, typeFileMap.keys()) {
|
|
|
|
|
const QStringList typeFiles = typeFileMap.value(type);
|
|
|
|
|
changeFiles(type, typeFiles, &failedFiles, RemoveFromProFile);
|
|
|
|
|
if (notRemoved)
|
|
|
|
|
*notRemoved = failedFiles;
|
|
|
|
|
}
|
2008-12-02 12:01:29 +01:00
|
|
|
return failedFiles.isEmpty();
|
|
|
|
|
}
|
|
|
|
|
|
2013-07-01 16:13:48 +02:00
|
|
|
bool Qt4PriFileNode::deleteFiles(const QStringList &filePaths)
|
2010-08-10 16:27:35 +02:00
|
|
|
{
|
|
|
|
|
QStringList failedFiles;
|
2013-07-01 16:13:48 +02:00
|
|
|
typedef QMap<QString, QStringList> TypeFileMap;
|
|
|
|
|
// Split into lists by file type and bulk-add them.
|
|
|
|
|
TypeFileMap typeFileMap;
|
|
|
|
|
const Core::MimeDatabase *mdb = Core::ICore::mimeDatabase();
|
|
|
|
|
foreach (const QString file, filePaths) {
|
|
|
|
|
const Core::MimeType mt = mdb->findByFile(file);
|
|
|
|
|
typeFileMap[mt.type()] << file;
|
|
|
|
|
}
|
|
|
|
|
foreach (const QString &type, typeFileMap.keys()) {
|
|
|
|
|
const QStringList typeFiles = typeFileMap.value(type);
|
|
|
|
|
changeFiles(type, typeFiles, &failedFiles, RemoveFromProFile);
|
|
|
|
|
}
|
2010-08-10 16:27:35 +02:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2013-07-01 16:13:48 +02:00
|
|
|
bool Qt4PriFileNode::renameFile(const QString &filePath, const QString &newFilePath)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2008-12-05 14:29:18 +01:00
|
|
|
if (newFilePath.isEmpty())
|
2008-12-02 12:01:29 +01:00
|
|
|
return false;
|
|
|
|
|
|
2012-04-18 11:50:32 +02:00
|
|
|
bool changeProFileOptional = deploysFolder(QFileInfo(filePath).absolutePath());
|
2013-07-01 16:13:48 +02:00
|
|
|
const Core::MimeDatabase *mdb = Core::ICore::mimeDatabase();
|
2013-08-08 19:32:33 +02:00
|
|
|
const Core::MimeType mt = mdb->findByFile(newFilePath);
|
2008-12-02 12:01:29 +01:00
|
|
|
QStringList dummy;
|
2013-07-01 16:13:48 +02:00
|
|
|
|
|
|
|
|
changeFiles(mt.type(), QStringList() << filePath, &dummy, RemoveFromProFile);
|
2012-04-18 11:50:32 +02:00
|
|
|
if (!dummy.isEmpty() && !changeProFileOptional)
|
2008-12-02 12:01:29 +01:00
|
|
|
return false;
|
2013-07-01 16:13:48 +02:00
|
|
|
changeFiles(mt.type(), QStringList() << newFilePath, &dummy, AddToProFile);
|
2012-04-18 11:50:32 +02:00
|
|
|
if (!dummy.isEmpty() && !changeProFileOptional)
|
2008-12-02 12:01:29 +01:00
|
|
|
return false;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool Qt4PriFileNode::priFileWritable(const QString &path)
|
|
|
|
|
{
|
2012-10-15 11:53:22 +02:00
|
|
|
Core::Internal::ReadOnlyFilesDialog roDialog(path, Core::ICore::mainWindow());
|
|
|
|
|
roDialog.setShowFailWarning(true);
|
|
|
|
|
return roDialog.exec() != Core::Internal::ReadOnlyFilesDialog::RO_Cancel;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2010-01-22 16:49:57 +01:00
|
|
|
bool Qt4PriFileNode::saveModifiedEditors()
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2013-07-18 12:26:23 +02:00
|
|
|
Core::IDocument *document
|
|
|
|
|
= Core::EditorManager::documentModel()->documentForFilePath(m_projectFilePath);
|
|
|
|
|
if (!document || !document->isModified())
|
|
|
|
|
return true;
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2013-07-18 12:26:23 +02:00
|
|
|
bool cancelled;
|
|
|
|
|
Core::DocumentManager::saveModifiedDocuments(QList<Core::IDocument *>() << document, &cancelled,
|
|
|
|
|
tr("There are unsaved changes for project file %1.").arg(m_projectFilePath));
|
|
|
|
|
if (cancelled)
|
|
|
|
|
return false;
|
|
|
|
|
// force instant reload of ourselves
|
|
|
|
|
QtSupport::ProFileCacheManager::instance()->discardFile(m_projectFilePath);
|
|
|
|
|
m_project->qt4ProjectManager()->notifyChanged(m_projectFilePath);
|
2008-12-02 12:01:29 +01:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2010-06-08 12:15:43 +02:00
|
|
|
QStringList Qt4PriFileNode::formResources(const QString &formFile) const
|
|
|
|
|
{
|
|
|
|
|
QStringList resourceFiles;
|
|
|
|
|
QFile file(formFile);
|
2013-02-12 10:13:43 +01:00
|
|
|
if (!file.open(QIODevice::ReadOnly))
|
|
|
|
|
return resourceFiles;
|
|
|
|
|
|
2010-06-08 12:15:43 +02:00
|
|
|
QXmlStreamReader reader(&file);
|
|
|
|
|
|
|
|
|
|
QFileInfo fi(formFile);
|
|
|
|
|
QDir formDir = fi.absoluteDir();
|
|
|
|
|
while (!reader.atEnd()) {
|
|
|
|
|
reader.readNext();
|
|
|
|
|
if (reader.isStartElement()) {
|
|
|
|
|
if (reader.name() == QLatin1String("iconset")) {
|
|
|
|
|
const QXmlStreamAttributes attributes = reader.attributes();
|
|
|
|
|
if (attributes.hasAttribute(QLatin1String("resource")))
|
|
|
|
|
resourceFiles.append(QDir::cleanPath(formDir.absoluteFilePath(
|
|
|
|
|
attributes.value(QLatin1String("resource")).toString())));
|
|
|
|
|
} else if (reader.name() == QLatin1String("include")) {
|
|
|
|
|
const QXmlStreamAttributes attributes = reader.attributes();
|
|
|
|
|
if (attributes.hasAttribute(QLatin1String("location")))
|
|
|
|
|
resourceFiles.append(QDir::cleanPath(formDir.absoluteFilePath(
|
|
|
|
|
attributes.value(QLatin1String("location")).toString())));
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (reader.hasError())
|
|
|
|
|
qWarning() << "Could not read form file:" << formFile;
|
|
|
|
|
|
|
|
|
|
return resourceFiles;
|
|
|
|
|
}
|
|
|
|
|
|
2013-07-01 16:13:48 +02:00
|
|
|
void Qt4PriFileNode::changeFiles(const QString &mimeType,
|
2008-12-02 12:01:29 +01:00
|
|
|
const QStringList &filePaths,
|
|
|
|
|
QStringList *notChanged,
|
|
|
|
|
ChangeType change)
|
|
|
|
|
{
|
|
|
|
|
if (filePaths.isEmpty())
|
|
|
|
|
return;
|
|
|
|
|
|
2010-01-14 21:39:31 +01:00
|
|
|
*notChanged = filePaths;
|
|
|
|
|
|
|
|
|
|
// Check for modified editors
|
2010-01-22 16:49:57 +01:00
|
|
|
if (!saveModifiedEditors())
|
2010-01-14 21:39:31 +01:00
|
|
|
return;
|
|
|
|
|
|
2010-05-18 13:48:57 +02:00
|
|
|
// Ensure that the file is not read only
|
|
|
|
|
QFileInfo fi(m_projectFilePath);
|
|
|
|
|
if (!fi.isWritable()) {
|
|
|
|
|
// Try via vcs manager
|
2012-01-24 15:36:40 +01:00
|
|
|
Core::VcsManager *vcsManager = Core::ICore::vcsManager();
|
2010-05-18 13:48:57 +02:00
|
|
|
Core::IVersionControl *versionControl = vcsManager->findVersionControlForDirectory(fi.absolutePath());
|
|
|
|
|
if (!versionControl || versionControl->vcsOpen(m_projectFilePath)) {
|
|
|
|
|
bool makeWritable = QFile::setPermissions(m_projectFilePath, fi.permissions() | QFile::WriteUser);
|
|
|
|
|
if (!makeWritable) {
|
2012-01-24 15:36:40 +01:00
|
|
|
QMessageBox::warning(Core::ICore::mainWindow(),
|
2010-05-18 13:48:57 +02:00
|
|
|
tr("Failed!"),
|
|
|
|
|
tr("Could not write project file %1.").arg(m_projectFilePath));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2010-01-14 22:58:55 +01:00
|
|
|
QStringList lines;
|
|
|
|
|
ProFile *includeFile;
|
|
|
|
|
{
|
|
|
|
|
QString contents;
|
|
|
|
|
{
|
2011-03-30 15:15:15 +02:00
|
|
|
Utils::FileReader reader;
|
|
|
|
|
if (!reader.fetch(m_projectFilePath, QIODevice::Text)) {
|
|
|
|
|
m_project->proFileParseError(reader.errorString());
|
2010-01-14 22:58:55 +01:00
|
|
|
return;
|
|
|
|
|
}
|
2011-03-30 15:15:15 +02:00
|
|
|
contents = QString::fromLocal8Bit(reader.data());
|
|
|
|
|
lines = contents.split(QLatin1Char('\n'));
|
2010-01-14 22:58:55 +01:00
|
|
|
}
|
|
|
|
|
|
2013-05-29 20:18:51 +02:00
|
|
|
QMakeVfs vfs;
|
2011-05-20 21:40:53 +02:00
|
|
|
QtSupport::ProMessageHandler handler;
|
2013-05-29 20:18:51 +02:00
|
|
|
QMakeParser parser(0, &vfs, &handler);
|
2013-02-08 14:31:44 +01:00
|
|
|
includeFile = parser.parsedProBlock(contents, m_projectFilePath, 1);
|
2008-12-05 14:29:18 +01:00
|
|
|
}
|
|
|
|
|
|
2010-01-15 21:52:44 +01:00
|
|
|
QDir priFileDir = QDir(m_qt4ProFileNode->m_projectDir);
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
|
if (change == AddToProFile) {
|
2010-05-18 14:59:51 +02:00
|
|
|
// Use the first variable for adding.
|
2013-08-08 19:32:33 +02:00
|
|
|
ProWriter::addFiles(includeFile, &lines, priFileDir, filePaths, varNameForAdding(mimeType));
|
2010-01-14 22:58:55 +01:00
|
|
|
notChanged->clear();
|
2008-12-02 12:01:29 +01:00
|
|
|
} else { // RemoveFromProFile
|
2013-08-08 19:32:33 +02:00
|
|
|
*notChanged = ProWriter::removeFiles(includeFile, &lines, priFileDir, filePaths, varNamesForRemoving());
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// save file
|
2012-02-14 16:43:51 +01:00
|
|
|
Core::DocumentManager::expectFileChange(m_projectFilePath);
|
2010-01-14 22:58:55 +01:00
|
|
|
save(lines);
|
2012-02-14 16:43:51 +01:00
|
|
|
Core::DocumentManager::unexpectFileChange(m_projectFilePath);
|
2010-01-14 21:51:34 +01:00
|
|
|
|
2010-05-18 15:02:53 +02:00
|
|
|
// This is a hack.
|
|
|
|
|
// We are saving twice in a very short timeframe, once the editor and once the ProFile.
|
|
|
|
|
// So the modification time might not change between those two saves.
|
|
|
|
|
// We manually tell each editor to reload it's file.
|
|
|
|
|
// (The .pro files are notified by the file system watcher.)
|
2011-04-04 15:24:13 +02:00
|
|
|
QStringList errorStrings;
|
2013-07-18 12:26:23 +02:00
|
|
|
Core::IDocument *document = Core::EditorManager::documentModel()->documentForFilePath(m_projectFilePath);
|
|
|
|
|
if (document) {
|
|
|
|
|
QString errorString;
|
|
|
|
|
if (!document->reload(&errorString, Core::IDocument::FlagReload, Core::IDocument::TypeContents))
|
|
|
|
|
errorStrings << errorString;
|
2010-01-22 16:49:57 +01:00
|
|
|
}
|
2011-04-04 15:24:13 +02:00
|
|
|
if (!errorStrings.isEmpty())
|
2012-01-24 15:36:40 +01:00
|
|
|
QMessageBox::warning(Core::ICore::mainWindow(), tr("File Error"),
|
2011-04-04 15:24:13 +02:00
|
|
|
errorStrings.join(QLatin1String("\n")));
|
2010-01-22 16:49:57 +01:00
|
|
|
|
2010-01-14 21:51:34 +01:00
|
|
|
includeFile->deref();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2010-01-14 22:58:55 +01:00
|
|
|
void Qt4PriFileNode::save(const QStringList &lines)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2011-03-30 15:15:15 +02:00
|
|
|
Utils::FileSaver saver(m_projectFilePath, QIODevice::Text);
|
2011-11-03 12:05:15 -04:00
|
|
|
saver.write(lines.join(QLatin1String("\n")).toLocal8Bit());
|
2012-01-24 15:36:40 +01:00
|
|
|
saver.finalize(Core::ICore::mainWindow());
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2010-01-22 16:49:57 +01:00
|
|
|
m_project->qt4ProjectManager()->notifyChanged(m_projectFilePath);
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2010-08-10 16:27:35 +02:00
|
|
|
QStringList Qt4PriFileNode::varNames(ProjectExplorer::FileType type)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
|
|
|
|
QStringList vars;
|
|
|
|
|
switch (type) {
|
|
|
|
|
case ProjectExplorer::HeaderType:
|
|
|
|
|
vars << QLatin1String("HEADERS");
|
2009-11-24 19:13:37 +01:00
|
|
|
vars << QLatin1String("OBJECTIVE_HEADERS");
|
2008-12-02 12:01:29 +01:00
|
|
|
break;
|
|
|
|
|
case ProjectExplorer::SourceType:
|
|
|
|
|
vars << QLatin1String("SOURCES");
|
|
|
|
|
vars << QLatin1String("OBJECTIVE_SOURCES");
|
2009-06-16 14:41:25 +02:00
|
|
|
vars << QLatin1String("LEXSOURCES");
|
|
|
|
|
vars << QLatin1String("YACCSOURCES");
|
2008-12-02 12:01:29 +01:00
|
|
|
break;
|
|
|
|
|
case ProjectExplorer::ResourceType:
|
|
|
|
|
vars << QLatin1String("RESOURCES");
|
|
|
|
|
break;
|
|
|
|
|
case ProjectExplorer::FormType:
|
|
|
|
|
vars << QLatin1String("FORMS");
|
|
|
|
|
break;
|
2010-08-26 18:33:16 +02:00
|
|
|
case ProjectExplorer::ProjectFileType:
|
|
|
|
|
vars << QLatin1String("SUBDIRS");
|
|
|
|
|
break;
|
2010-08-10 16:27:35 +02:00
|
|
|
case ProjectExplorer::QMLType:
|
2011-06-20 16:10:42 +02:00
|
|
|
vars << QLatin1String("OTHER_FILES");
|
2010-08-10 16:27:35 +02:00
|
|
|
break;
|
2008-12-02 12:01:29 +01:00
|
|
|
default:
|
|
|
|
|
vars << QLatin1String("OTHER_FILES");
|
2010-11-22 15:10:20 +01:00
|
|
|
vars << QLatin1String("ICON");
|
2008-12-02 12:01:29 +01:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return vars;
|
|
|
|
|
}
|
|
|
|
|
|
2013-07-01 16:13:48 +02:00
|
|
|
//!
|
|
|
|
|
//! \brief Qt4PriFileNode::varNames
|
|
|
|
|
//! \param mimeType
|
|
|
|
|
//! \return the qmake variable name for the mime type
|
2013-08-08 19:32:33 +02:00
|
|
|
//! Note: Only used for adding.
|
2013-07-01 16:13:48 +02:00
|
|
|
//!
|
2013-08-08 19:32:33 +02:00
|
|
|
QString Qt4PriFileNode::varNameForAdding(const QString &mimeType)
|
2013-07-01 16:13:48 +02:00
|
|
|
{
|
|
|
|
|
if (mimeType == QLatin1String(ProjectExplorer::Constants::CPP_HEADER_MIMETYPE)
|
|
|
|
|
|| mimeType == QLatin1String(ProjectExplorer::Constants::C_HEADER_MIMETYPE)) {
|
2013-08-08 19:32:33 +02:00
|
|
|
return QLatin1String("HEADERS");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mimeType == QLatin1String(ProjectExplorer::Constants::CPP_SOURCE_MIMETYPE)
|
2013-07-01 16:13:48 +02:00
|
|
|
|| mimeType == QLatin1String(ProjectExplorer::Constants::C_SOURCE_MIMETYPE)) {
|
2013-08-08 19:32:33 +02:00
|
|
|
return QLatin1String("SOURCES");
|
2013-07-01 16:13:48 +02:00
|
|
|
}
|
2013-08-08 19:32:33 +02:00
|
|
|
|
|
|
|
|
if (mimeType == QLatin1String(CppTools::Constants::OBJECTIVE_CPP_SOURCE_MIMETYPE))
|
|
|
|
|
return QLatin1String("OBJECTIVE_SOURCES");
|
|
|
|
|
|
|
|
|
|
if (mimeType == QLatin1String(ProjectExplorer::Constants::RESOURCE_MIMETYPE))
|
|
|
|
|
return QLatin1String("RESOURCES");
|
|
|
|
|
|
|
|
|
|
if (mimeType == QLatin1String(ProjectExplorer::Constants::FORM_MIMETYPE))
|
|
|
|
|
return QLatin1String("FORMS");
|
|
|
|
|
|
|
|
|
|
if (mimeType == QLatin1String(ProjectExplorer::Constants::QML_MIMETYPE))
|
|
|
|
|
return QLatin1String("OTHER_FILES");
|
|
|
|
|
|
|
|
|
|
if (mimeType == QLatin1String(Constants::PROFILE_MIMETYPE))
|
|
|
|
|
return QLatin1String("SUBDIRS");
|
|
|
|
|
|
|
|
|
|
return QLatin1String("OTHER_FILES");
|
2013-07-01 16:13:48 +02:00
|
|
|
}
|
|
|
|
|
|
2013-08-08 19:32:33 +02:00
|
|
|
//!
|
|
|
|
|
//! \brief Qt4PriFileNode::varNamesForRemoving
|
|
|
|
|
//! \return all qmake variables which are displayed in the project tree
|
|
|
|
|
//! Note: Only used for removing.
|
|
|
|
|
//!
|
|
|
|
|
QStringList Qt4PriFileNode::varNamesForRemoving()
|
|
|
|
|
{
|
|
|
|
|
QStringList vars;
|
|
|
|
|
vars << QLatin1String("HEADERS");
|
|
|
|
|
vars << QLatin1String("OBJECTIVE_HEADERS");
|
|
|
|
|
vars << QLatin1String("SOURCES");
|
|
|
|
|
vars << QLatin1String("OBJECTIVE_SOURCES");
|
|
|
|
|
vars << QLatin1String("RESOURCES");
|
|
|
|
|
vars << QLatin1String("FORMS");
|
|
|
|
|
vars << QLatin1String("OTHER_FILES");
|
|
|
|
|
vars << QLatin1String("SUBDIRS");
|
|
|
|
|
vars << QLatin1String("OTHER_FILES");
|
|
|
|
|
vars << QLatin1String("ICON");
|
|
|
|
|
return vars;
|
|
|
|
|
}
|
2010-08-10 16:27:35 +02:00
|
|
|
|
2012-09-07 12:35:18 +02:00
|
|
|
QStringList Qt4PriFileNode::dynamicVarNames(QtSupport::ProFileReader *readerExact, QtSupport::ProFileReader *readerCumulative,
|
|
|
|
|
QtSupport::BaseQtVersion *qtVersion)
|
2010-08-10 16:27:35 +02:00
|
|
|
{
|
|
|
|
|
QStringList result;
|
2012-09-07 12:35:18 +02:00
|
|
|
|
2010-08-10 16:27:35 +02:00
|
|
|
// Figure out DEPLOYMENT and INSTALLS
|
2012-01-13 14:20:45 +01:00
|
|
|
const QString deployment = QLatin1String("DEPLOYMENT");
|
2012-09-07 12:35:18 +02:00
|
|
|
const QString sources = QLatin1String(qtVersion && qtVersion->qtVersion() < QtSupport::QtVersionNumber(5,0,0) ? ".sources" : ".files");
|
2012-01-13 14:20:45 +01:00
|
|
|
QStringList listOfVars = readerExact->values(deployment);
|
2010-08-10 16:27:35 +02:00
|
|
|
foreach (const QString &var, listOfVars) {
|
2012-01-13 14:20:45 +01:00
|
|
|
result << (var + sources);
|
2010-08-10 16:27:35 +02:00
|
|
|
}
|
|
|
|
|
if (readerCumulative) {
|
2012-01-13 14:20:45 +01:00
|
|
|
QStringList listOfVars = readerCumulative->values(deployment);
|
2010-08-10 16:27:35 +02:00
|
|
|
foreach (const QString &var, listOfVars) {
|
2012-01-13 14:20:45 +01:00
|
|
|
result << (var + sources);
|
2010-08-10 16:27:35 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-01-13 14:20:45 +01:00
|
|
|
const QString installs = QLatin1String("INSTALLS");
|
|
|
|
|
const QString files = QLatin1String(".files");
|
|
|
|
|
listOfVars = readerExact->values(installs);
|
2010-08-10 16:27:35 +02:00
|
|
|
foreach (const QString &var, listOfVars) {
|
2012-01-13 14:20:45 +01:00
|
|
|
result << (var + files);
|
2010-08-10 16:27:35 +02:00
|
|
|
}
|
|
|
|
|
if (readerCumulative) {
|
2012-01-13 14:20:45 +01:00
|
|
|
QStringList listOfVars = readerCumulative->values(installs);
|
2010-08-10 16:27:35 +02:00
|
|
|
foreach (const QString &var, listOfVars) {
|
2012-01-13 14:20:45 +01:00
|
|
|
result << (var + files);
|
2010-08-10 16:27:35 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2011-11-08 18:53:51 +01:00
|
|
|
QSet<Utils::FileName> Qt4PriFileNode::filterFilesProVariables(ProjectExplorer::FileType fileType, const QSet<Utils::FileName> &files)
|
2011-06-30 17:57:52 +02:00
|
|
|
{
|
|
|
|
|
if (fileType != ProjectExplorer::QMLType && fileType != ProjectExplorer::UnknownFileType)
|
|
|
|
|
return files;
|
2011-11-08 18:53:51 +01:00
|
|
|
QSet<Utils::FileName> result;
|
2011-06-30 17:57:52 +02:00
|
|
|
if (fileType == ProjectExplorer::QMLType) {
|
2011-11-08 18:53:51 +01:00
|
|
|
foreach (const Utils::FileName &file, files)
|
2013-04-23 12:36:44 +02:00
|
|
|
if (file.toString().endsWith(QLatin1String(".qml")))
|
2011-06-30 17:57:52 +02:00
|
|
|
result << file;
|
|
|
|
|
} else {
|
2011-11-08 18:53:51 +01:00
|
|
|
foreach (const Utils::FileName &file, files)
|
2013-04-23 12:36:44 +02:00
|
|
|
if (!file.toString().endsWith(QLatin1String(".qml")))
|
2011-06-30 17:57:52 +02:00
|
|
|
result << file;
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2011-11-08 18:53:51 +01:00
|
|
|
QSet<Utils::FileName> Qt4PriFileNode::filterFilesRecursiveEnumerata(ProjectExplorer::FileType fileType, const QSet<Utils::FileName> &files)
|
2010-08-10 16:27:35 +02:00
|
|
|
{
|
2011-11-08 18:53:51 +01:00
|
|
|
QSet<Utils::FileName> result;
|
2010-08-10 16:27:35 +02:00
|
|
|
if (fileType != ProjectExplorer::QMLType && fileType != ProjectExplorer::UnknownFileType)
|
|
|
|
|
return result;
|
2012-11-28 20:44:03 +02:00
|
|
|
if (fileType == ProjectExplorer::QMLType) {
|
2011-11-08 18:53:51 +01:00
|
|
|
foreach (const Utils::FileName &file, files)
|
2013-04-23 12:36:44 +02:00
|
|
|
if (file.toString().endsWith(QLatin1String(".qml")))
|
2010-08-10 16:27:35 +02:00
|
|
|
result << file;
|
|
|
|
|
} else {
|
2011-11-08 18:53:51 +01:00
|
|
|
foreach (const Utils::FileName &file, files)
|
2013-04-23 12:36:44 +02:00
|
|
|
if (!file.toString().endsWith(QLatin1String(".qml")))
|
2010-08-10 16:27:35 +02:00
|
|
|
result << file;
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2011-11-22 13:10:10 +01:00
|
|
|
} // namespace Qt4ProjectManager
|
|
|
|
|
|
2011-05-25 11:23:25 +02:00
|
|
|
static Qt4ProjectType proFileTemplateTypeToProjectType(ProFileEvaluator::TemplateType type)
|
|
|
|
|
{
|
|
|
|
|
switch (type) {
|
|
|
|
|
case ProFileEvaluator::TT_Unknown:
|
|
|
|
|
case ProFileEvaluator::TT_Application:
|
|
|
|
|
return ApplicationTemplate;
|
|
|
|
|
case ProFileEvaluator::TT_Library:
|
|
|
|
|
return LibraryTemplate;
|
|
|
|
|
case ProFileEvaluator::TT_Script:
|
|
|
|
|
return ScriptTemplate;
|
|
|
|
|
case ProFileEvaluator::TT_Aux:
|
|
|
|
|
return AuxTemplate;
|
|
|
|
|
case ProFileEvaluator::TT_Subdirs:
|
|
|
|
|
return SubDirsTemplate;
|
|
|
|
|
default:
|
|
|
|
|
return InvalidProject;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Qt4NodesWatcher::Qt4NodesWatcher(QObject *parent)
|
|
|
|
|
: NodesWatcher(parent)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2010-07-06 14:32:33 +02:00
|
|
|
const Qt4ProFileNode *Qt4ProFileNode::findProFileFor(const QString &fileName) const
|
2009-04-28 14:30:17 +02:00
|
|
|
{
|
|
|
|
|
if (fileName == path())
|
|
|
|
|
return this;
|
|
|
|
|
foreach (ProjectNode *pn, subProjectNodes())
|
2009-12-04 19:22:12 +01:00
|
|
|
if (Qt4ProFileNode *qt4ProFileNode = qobject_cast<Qt4ProFileNode *>(pn))
|
2010-07-06 14:32:33 +02:00
|
|
|
if (const Qt4ProFileNode *result = qt4ProFileNode->findProFileFor(fileName))
|
2009-04-28 14:30:17 +02:00
|
|
|
return result;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2009-01-14 17:13:17 +01:00
|
|
|
|
2010-10-05 17:38:45 +02:00
|
|
|
QString Qt4ProFileNode::makefile() const
|
|
|
|
|
{
|
2012-09-05 13:08:40 +02:00
|
|
|
return singleVariableValue(Makefile);
|
2010-10-05 17:38:45 +02:00
|
|
|
}
|
|
|
|
|
|
2012-04-28 22:24:33 +03:00
|
|
|
QString Qt4ProFileNode::objectExtension() const
|
|
|
|
|
{
|
2012-08-23 15:53:58 +02:00
|
|
|
if (m_varValues[ObjectExt].isEmpty())
|
|
|
|
|
return Utils::HostOsInfo::isWindowsHost() ? QLatin1String(".obj") : QLatin1String(".o");
|
2012-04-28 22:24:33 +03:00
|
|
|
return m_varValues[ObjectExt].first();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString Qt4ProFileNode::objectsDirectory() const
|
|
|
|
|
{
|
2012-09-05 13:08:40 +02:00
|
|
|
return singleVariableValue(ObjectsDir);
|
2012-04-28 22:24:33 +03:00
|
|
|
}
|
|
|
|
|
|
2012-02-16 15:09:56 +01:00
|
|
|
QByteArray Qt4ProFileNode::cxxDefines() const
|
|
|
|
|
{
|
|
|
|
|
QByteArray result;
|
|
|
|
|
foreach (const QString &def, variableValue(DefinesVar)) {
|
|
|
|
|
result += "#define ";
|
|
|
|
|
const int index = def.indexOf(QLatin1Char('='));
|
|
|
|
|
if (index == -1) {
|
|
|
|
|
result += def.toLatin1();
|
|
|
|
|
result += " 1\n";
|
|
|
|
|
} else {
|
|
|
|
|
const QString name = def.left(index);
|
|
|
|
|
const QString value = def.mid(index + 1);
|
|
|
|
|
result += name.toLatin1();
|
|
|
|
|
result += ' ';
|
|
|
|
|
result += value.toLocal8Bit();
|
|
|
|
|
result += '\n';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2011-05-10 16:18:04 +02:00
|
|
|
bool Qt4ProFileNode::isDeployable() const
|
|
|
|
|
{
|
|
|
|
|
return m_isDeployable;
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
/*!
|
|
|
|
|
\class Qt4ProFileNode
|
|
|
|
|
Implements abstract ProjectNode class
|
|
|
|
|
*/
|
|
|
|
|
Qt4ProFileNode::Qt4ProFileNode(Qt4Project *project,
|
|
|
|
|
const QString &filePath,
|
|
|
|
|
QObject *parent)
|
2008-12-05 14:29:18 +01:00
|
|
|
: Qt4PriFileNode(project, this, filePath),
|
2010-10-27 16:27:22 +02:00
|
|
|
m_validParse(false),
|
2012-05-08 12:53:24 +02:00
|
|
|
m_parseInProgress(true),
|
2013-02-18 18:47:54 +01:00
|
|
|
m_projectType(InvalidProject),
|
2010-03-10 16:55:37 +01:00
|
|
|
m_readerExact(0),
|
|
|
|
|
m_readerCumulative(0)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
|
|
|
|
if (parent)
|
|
|
|
|
setParent(parent);
|
|
|
|
|
|
2010-03-10 16:55:37 +01:00
|
|
|
connect(&m_parseFutureWatcher, SIGNAL(finished()),
|
|
|
|
|
this, SLOT(applyAsyncEvaluate()));
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2008-12-02 18:14:06 +01:00
|
|
|
Qt4ProFileNode::~Qt4ProFileNode()
|
|
|
|
|
{
|
2010-03-10 16:55:37 +01:00
|
|
|
m_parseFutureWatcher.waitForFinished();
|
2010-03-11 17:01:06 +01:00
|
|
|
if (m_readerExact) {
|
|
|
|
|
// Oh we need to clean up
|
2012-06-28 12:18:49 +02:00
|
|
|
applyEvaluate(EvalAbort, true);
|
2010-03-11 17:01:06 +01:00
|
|
|
m_project->decrementPendingEvaluateFutures();
|
|
|
|
|
}
|
2010-03-10 16:55:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool Qt4ProFileNode::isParent(Qt4ProFileNode *node)
|
|
|
|
|
{
|
2010-03-12 14:58:42 +01:00
|
|
|
while ((node = qobject_cast<Qt4ProFileNode *>(node->parentFolderNode()))) {
|
2010-03-10 16:55:37 +01:00
|
|
|
if (node == this)
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
2008-12-02 18:14:06 +01:00
|
|
|
}
|
|
|
|
|
|
2010-02-02 11:59:24 +01:00
|
|
|
bool Qt4ProFileNode::hasBuildTargets() const
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2010-11-18 17:31:30 +01:00
|
|
|
return hasBuildTargets(projectType());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool Qt4ProFileNode::hasBuildTargets(Qt4ProjectType projectType) const
|
|
|
|
|
{
|
|
|
|
|
return (projectType == ApplicationTemplate || projectType == LibraryTemplate);
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2012-05-04 16:25:41 +03:00
|
|
|
bool Qt4ProFileNode::isDebugAndRelease() const
|
|
|
|
|
{
|
|
|
|
|
const QStringList configValues = m_varValues.value(ConfigVar);
|
2012-05-14 22:58:34 +03:00
|
|
|
return configValues.contains(QLatin1String("debug_and_release"));
|
2012-05-04 16:25:41 +03:00
|
|
|
}
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
Qt4ProjectType Qt4ProFileNode::projectType() const
|
|
|
|
|
{
|
|
|
|
|
return m_projectType;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QStringList Qt4ProFileNode::variableValue(const Qt4Variable var) const
|
|
|
|
|
{
|
|
|
|
|
return m_varValues.value(var);
|
|
|
|
|
}
|
|
|
|
|
|
2012-08-20 12:41:52 +02:00
|
|
|
QString Qt4ProFileNode::singleVariableValue(const Qt4Variable var) const
|
|
|
|
|
{
|
|
|
|
|
const QStringList &values = variableValue(var);
|
|
|
|
|
return values.isEmpty() ? QString() : values.first();
|
|
|
|
|
}
|
|
|
|
|
|
2013-07-11 16:24:51 +02:00
|
|
|
QHash<QString, QString> Qt4ProFileNode::uiFiles() const
|
2012-10-08 14:33:33 +02:00
|
|
|
{
|
2013-07-11 16:24:51 +02:00
|
|
|
return m_uiFiles;
|
2012-10-08 14:33:33 +02:00
|
|
|
}
|
|
|
|
|
|
2011-09-12 12:40:53 +02:00
|
|
|
void Qt4ProFileNode::emitProFileUpdatedRecursive()
|
2010-11-02 16:39:45 +01:00
|
|
|
{
|
2011-05-25 11:23:25 +02:00
|
|
|
foreach (ProjectExplorer::NodesWatcher *watcher, watchers())
|
|
|
|
|
if (Internal::Qt4NodesWatcher *qt4Watcher = qobject_cast<Internal::Qt4NodesWatcher*>(watcher))
|
2012-10-16 15:56:24 +02:00
|
|
|
emit qt4Watcher->proFileUpdated(this, m_validParse, m_parseInProgress);
|
2010-11-02 16:39:45 +01:00
|
|
|
|
|
|
|
|
foreach (ProjectNode *subNode, subProjectNodes()) {
|
Remove braces for single lines of conditions
#!/usr/bin/env ruby
Dir.glob('**/*.cpp') { |file|
# skip ast (excluding paste, astpath, and canv'ast'imer)
next if file =~ /ast[^eip]|keywords\.|qualifiers|preprocessor|names.cpp/i
s = File.read(file)
next if s.include?('qlalr')
orig = s.dup
s.gsub!(/\n *if [^\n]*{\n[^\n]*\n\s+}(\s+else if [^\n]* {\n[^\n]*\n\s+})*(\s+else {\n[^\n]*\n\s+})?\n/m) { |m|
res = $&
if res =~ /^\s*(\/\/|[A-Z_]{3,})/ # C++ comment or macro (Q_UNUSED, SDEBUG), do not touch braces
res
else
res.gsub!('} else', 'else')
res.gsub!(/\n +} *\n/m, "\n")
res.gsub(/ *{$/, '')
end
}
s.gsub!(/ *$/, '')
File.open(file, 'wb').write(s) if s != orig
}
Change-Id: I3b30ee60df0986f66c02132c65fc38a3fbb6bbdc
Reviewed-by: hjk <qthjk@ovi.com>
2013-01-08 03:32:53 +02:00
|
|
|
if (Qt4ProFileNode *node = qobject_cast<Qt4ProFileNode *>(subNode))
|
2011-09-12 12:40:53 +02:00
|
|
|
node->emitProFileUpdatedRecursive();
|
2010-11-02 16:39:45 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-09-12 12:40:53 +02:00
|
|
|
void Qt4ProFileNode::setParseInProgressRecursive(bool b)
|
2010-10-27 16:27:22 +02:00
|
|
|
{
|
2011-09-12 12:40:53 +02:00
|
|
|
setParseInProgress(b);
|
2011-06-22 12:53:49 +02:00
|
|
|
foreach (ProjectNode *subNode, subProjectNodes()) {
|
Remove braces for single lines of conditions
#!/usr/bin/env ruby
Dir.glob('**/*.cpp') { |file|
# skip ast (excluding paste, astpath, and canv'ast'imer)
next if file =~ /ast[^eip]|keywords\.|qualifiers|preprocessor|names.cpp/i
s = File.read(file)
next if s.include?('qlalr')
orig = s.dup
s.gsub!(/\n *if [^\n]*{\n[^\n]*\n\s+}(\s+else if [^\n]* {\n[^\n]*\n\s+})*(\s+else {\n[^\n]*\n\s+})?\n/m) { |m|
res = $&
if res =~ /^\s*(\/\/|[A-Z_]{3,})/ # C++ comment or macro (Q_UNUSED, SDEBUG), do not touch braces
res
else
res.gsub!('} else', 'else')
res.gsub!(/\n +} *\n/m, "\n")
res.gsub(/ *{$/, '')
end
}
s.gsub!(/ *$/, '')
File.open(file, 'wb').write(s) if s != orig
}
Change-Id: I3b30ee60df0986f66c02132c65fc38a3fbb6bbdc
Reviewed-by: hjk <qthjk@ovi.com>
2013-01-08 03:32:53 +02:00
|
|
|
if (Qt4ProFileNode *node = qobject_cast<Qt4ProFileNode *>(subNode))
|
2011-09-12 12:40:53 +02:00
|
|
|
node->setParseInProgressRecursive(b);
|
2011-06-22 12:53:49 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-09-12 12:40:53 +02:00
|
|
|
void Qt4ProFileNode::setParseInProgress(bool b)
|
|
|
|
|
{
|
|
|
|
|
if (m_parseInProgress == b)
|
|
|
|
|
return;
|
|
|
|
|
m_parseInProgress = b;
|
|
|
|
|
foreach (ProjectExplorer::NodesWatcher *watcher, watchers())
|
|
|
|
|
if (Internal::Qt4NodesWatcher *qt4Watcher = qobject_cast<Internal::Qt4NodesWatcher*>(watcher))
|
2012-10-16 15:56:24 +02:00
|
|
|
emit qt4Watcher->proFileUpdated(this, m_validParse, m_parseInProgress);
|
2011-09-12 12:40:53 +02:00
|
|
|
}
|
|
|
|
|
|
2012-05-08 12:53:24 +02:00
|
|
|
void Qt4ProFileNode::setValidParseRecursive(bool b)
|
|
|
|
|
{
|
|
|
|
|
setValidParse(b);
|
|
|
|
|
foreach (ProjectNode *subNode, subProjectNodes()) {
|
Remove braces for single lines of conditions
#!/usr/bin/env ruby
Dir.glob('**/*.cpp') { |file|
# skip ast (excluding paste, astpath, and canv'ast'imer)
next if file =~ /ast[^eip]|keywords\.|qualifiers|preprocessor|names.cpp/i
s = File.read(file)
next if s.include?('qlalr')
orig = s.dup
s.gsub!(/\n *if [^\n]*{\n[^\n]*\n\s+}(\s+else if [^\n]* {\n[^\n]*\n\s+})*(\s+else {\n[^\n]*\n\s+})?\n/m) { |m|
res = $&
if res =~ /^\s*(\/\/|[A-Z_]{3,})/ # C++ comment or macro (Q_UNUSED, SDEBUG), do not touch braces
res
else
res.gsub!('} else', 'else')
res.gsub!(/\n +} *\n/m, "\n")
res.gsub(/ *{$/, '')
end
}
s.gsub!(/ *$/, '')
File.open(file, 'wb').write(s) if s != orig
}
Change-Id: I3b30ee60df0986f66c02132c65fc38a3fbb6bbdc
Reviewed-by: hjk <qthjk@ovi.com>
2013-01-08 03:32:53 +02:00
|
|
|
if (Qt4ProFileNode *node = qobject_cast<Qt4ProFileNode *>(subNode))
|
2012-05-08 12:53:24 +02:00
|
|
|
node->setValidParseRecursive(b);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Do note the absence of signal emission, always set validParse
|
|
|
|
|
// before setParseInProgress, as that will emit the signals
|
|
|
|
|
void Qt4ProFileNode::setValidParse(bool b)
|
|
|
|
|
{
|
|
|
|
|
if (m_validParse == b)
|
|
|
|
|
return;
|
|
|
|
|
m_validParse = b;
|
|
|
|
|
}
|
|
|
|
|
|
2011-09-12 12:40:53 +02:00
|
|
|
bool Qt4ProFileNode::validParse() const
|
|
|
|
|
{
|
|
|
|
|
return m_validParse;
|
|
|
|
|
}
|
|
|
|
|
|
2011-06-10 15:37:10 +02:00
|
|
|
bool Qt4ProFileNode::parseInProgress() const
|
2010-10-27 16:27:22 +02:00
|
|
|
{
|
2011-06-10 15:37:10 +02:00
|
|
|
return m_parseInProgress;
|
2010-10-27 16:27:22 +02:00
|
|
|
}
|
|
|
|
|
|
2008-12-09 17:17:12 +01:00
|
|
|
void Qt4ProFileNode::scheduleUpdate()
|
|
|
|
|
{
|
2011-09-12 12:40:53 +02:00
|
|
|
setParseInProgressRecursive(true);
|
2010-03-10 16:55:37 +01:00
|
|
|
m_project->scheduleAsyncUpdate(this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Qt4ProFileNode::asyncUpdate()
|
|
|
|
|
{
|
|
|
|
|
m_project->incrementPendingEvaluateFutures();
|
|
|
|
|
setupReader();
|
2010-10-25 17:26:41 +02:00
|
|
|
m_parseFutureWatcher.waitForFinished();
|
2011-02-09 20:03:04 +01:00
|
|
|
QFuture<EvalResult> future = QtConcurrent::run(&Qt4ProFileNode::asyncEvaluate, this);
|
2010-03-10 16:55:37 +01:00
|
|
|
m_parseFutureWatcher.setFuture(future);
|
2008-12-09 17:17:12 +01:00
|
|
|
}
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
void Qt4ProFileNode::update()
|
|
|
|
|
{
|
2011-09-12 12:40:53 +02:00
|
|
|
setParseInProgressRecursive(true);
|
2010-03-10 16:55:37 +01:00
|
|
|
setupReader();
|
2011-02-09 20:03:04 +01:00
|
|
|
EvalResult evalResult = evaluate();
|
|
|
|
|
applyEvaluate(evalResult, false);
|
2010-03-10 16:55:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Qt4ProFileNode::setupReader()
|
|
|
|
|
{
|
|
|
|
|
Q_ASSERT(!m_readerExact);
|
|
|
|
|
Q_ASSERT(!m_readerCumulative);
|
|
|
|
|
|
|
|
|
|
m_readerExact = m_project->createProFileReader(this);
|
|
|
|
|
|
|
|
|
|
m_readerCumulative = m_project->createProFileReader(this);
|
2012-06-18 10:03:45 +02:00
|
|
|
m_readerCumulative->setCumulative(true);
|
2010-03-10 16:55:37 +01:00
|
|
|
}
|
|
|
|
|
|
2011-02-09 20:03:04 +01:00
|
|
|
Qt4ProFileNode::EvalResult Qt4ProFileNode::evaluate()
|
2010-03-10 16:55:37 +01:00
|
|
|
{
|
2011-02-09 20:03:04 +01:00
|
|
|
EvalResult evalResult = EvalOk;
|
2010-06-18 21:15:14 +02:00
|
|
|
if (ProFile *pro = m_readerExact->parsedProFile(m_projectFilePath)) {
|
2012-06-11 20:56:24 +02:00
|
|
|
if (!m_readerExact->accept(pro, QMakeEvaluator::LoadAll))
|
2011-02-09 20:03:04 +01:00
|
|
|
evalResult = EvalPartial;
|
2012-06-11 20:56:24 +02:00
|
|
|
if (!m_readerCumulative->accept(pro, QMakeEvaluator::LoadPreFiles))
|
2011-02-09 20:03:04 +01:00
|
|
|
evalResult = EvalFail;
|
2010-06-18 21:15:14 +02:00
|
|
|
pro->deref();
|
|
|
|
|
} else {
|
2011-02-09 20:03:04 +01:00
|
|
|
evalResult = EvalFail;
|
2010-06-18 21:15:14 +02:00
|
|
|
}
|
2011-02-09 20:03:04 +01:00
|
|
|
return evalResult;
|
2010-03-10 16:55:37 +01:00
|
|
|
}
|
|
|
|
|
|
2011-02-09 20:03:04 +01:00
|
|
|
void Qt4ProFileNode::asyncEvaluate(QFutureInterface<EvalResult> &fi)
|
2010-03-10 16:55:37 +01:00
|
|
|
{
|
2011-02-09 20:03:04 +01:00
|
|
|
EvalResult evalResult = evaluate();
|
|
|
|
|
fi.reportResult(evalResult);
|
2010-03-10 16:55:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Qt4ProFileNode::applyAsyncEvaluate()
|
|
|
|
|
{
|
|
|
|
|
applyEvaluate(m_parseFutureWatcher.result(), true);
|
|
|
|
|
m_project->decrementPendingEvaluateFutures();
|
|
|
|
|
}
|
|
|
|
|
|
2012-05-04 11:49:37 +02:00
|
|
|
bool sortByNodes(Node *a, Node *b)
|
|
|
|
|
{
|
|
|
|
|
return a->path() < b->path();
|
|
|
|
|
}
|
|
|
|
|
|
2011-02-09 20:03:04 +01:00
|
|
|
void Qt4ProFileNode::applyEvaluate(EvalResult evalResult, bool async)
|
2010-03-10 16:55:37 +01:00
|
|
|
{
|
2010-03-11 17:01:06 +01:00
|
|
|
if (!m_readerExact)
|
|
|
|
|
return;
|
2011-02-09 20:03:04 +01:00
|
|
|
if (evalResult == EvalFail || m_project->wasEvaluateCanceled()) {
|
2011-12-07 17:52:59 +01:00
|
|
|
m_validParse = false;
|
2010-03-11 17:01:06 +01:00
|
|
|
m_project->destroyProFileReader(m_readerExact);
|
2011-02-08 12:46:25 +01:00
|
|
|
m_project->destroyProFileReader(m_readerCumulative);
|
2010-03-10 16:55:37 +01:00
|
|
|
m_readerExact = m_readerCumulative = 0;
|
2012-05-08 12:53:24 +02:00
|
|
|
setValidParseRecursive(false);
|
|
|
|
|
setParseInProgressRecursive(false);
|
|
|
|
|
|
2011-02-09 20:03:04 +01:00
|
|
|
if (evalResult == EvalFail) {
|
2010-06-15 16:34:03 +02:00
|
|
|
m_project->proFileParseError(tr("Error while parsing file %1. Giving up.").arg(m_projectFilePath));
|
2012-05-08 12:53:24 +02:00
|
|
|
if (m_projectType == InvalidProject)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
// delete files && folders && projects
|
|
|
|
|
removeFileNodes(fileNodes(), this);
|
|
|
|
|
removeProjectNodes(subProjectNodes());
|
|
|
|
|
removeFolderNodes(subFolderNodes(), this);
|
|
|
|
|
|
|
|
|
|
// change project type
|
|
|
|
|
Qt4ProjectType oldType = m_projectType;
|
|
|
|
|
m_projectType = InvalidProject;
|
|
|
|
|
|
|
|
|
|
foreach (ProjectExplorer::NodesWatcher *watcher, watchers())
|
|
|
|
|
if (Internal::Qt4NodesWatcher *qt4Watcher = qobject_cast<Internal::Qt4NodesWatcher*>(watcher))
|
|
|
|
|
emit qt4Watcher->projectTypeChanged(this, oldType, InvalidProject);
|
2010-06-15 16:34:03 +02:00
|
|
|
}
|
2008-12-02 12:01:29 +01:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (debug)
|
|
|
|
|
qDebug() << "Qt4ProFileNode - updating files for file " << m_projectFilePath;
|
|
|
|
|
|
2011-09-07 11:52:04 +02:00
|
|
|
Qt4ProjectType projectType = proFileTemplateTypeToProjectType(
|
2011-02-09 20:03:04 +01:00
|
|
|
(evalResult == EvalOk ? m_readerExact : m_readerCumulative)->templateType());
|
2008-12-02 12:01:29 +01:00
|
|
|
if (projectType != m_projectType) {
|
|
|
|
|
Qt4ProjectType oldType = m_projectType;
|
2012-05-08 12:53:24 +02:00
|
|
|
// probably all subfiles/projects have changed anyway
|
|
|
|
|
// delete files && folders && projects
|
|
|
|
|
foreach (ProjectNode *projectNode, subProjectNodes()) {
|
|
|
|
|
if (Qt4ProFileNode *qt4ProFileNode = qobject_cast<Qt4ProFileNode *>(projectNode)) {
|
|
|
|
|
qt4ProFileNode->setValidParseRecursive(false);
|
|
|
|
|
qt4ProFileNode->setParseInProgressRecursive(false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
removeFileNodes(fileNodes(), this);
|
|
|
|
|
removeProjectNodes(subProjectNodes());
|
|
|
|
|
removeFolderNodes(subFolderNodes(), this);
|
|
|
|
|
|
2010-11-18 18:18:54 +01:00
|
|
|
bool changesHasBuildTargets = hasBuildTargets() ^ hasBuildTargets(projectType);
|
2010-11-18 17:31:30 +01:00
|
|
|
|
|
|
|
|
if (changesHasBuildTargets)
|
|
|
|
|
aboutToChangeHasBuildTargets();
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
m_projectType = projectType;
|
2010-11-18 17:31:30 +01:00
|
|
|
|
|
|
|
|
if (changesHasBuildTargets)
|
|
|
|
|
hasBuildTargetsChanged();
|
|
|
|
|
|
2010-10-30 21:54:23 +02:00
|
|
|
// really emit here? or at the end? Nobody is connected to this signal at the moment
|
2010-03-10 16:55:37 +01:00
|
|
|
// so we kind of can ignore that question for now
|
2011-05-25 11:23:25 +02:00
|
|
|
foreach (ProjectExplorer::NodesWatcher *watcher, watchers())
|
|
|
|
|
if (Internal::Qt4NodesWatcher *qt4Watcher = qobject_cast<Internal::Qt4NodesWatcher*>(watcher))
|
2008-12-02 12:01:29 +01:00
|
|
|
emit qt4Watcher->projectTypeChanged(this, oldType, projectType);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Add/Remove pri files, sub projects
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
QList<ProjectNode*> existingProjectNodes = subProjectNodes();
|
|
|
|
|
|
2010-03-10 16:55:37 +01:00
|
|
|
QStringList newProjectFilesExact;
|
|
|
|
|
QHash<QString, ProFile*> includeFilesExact;
|
2011-09-06 17:21:51 +02:00
|
|
|
QSet<QString> exactSubdirs;
|
2010-03-10 16:55:37 +01:00
|
|
|
ProFile *fileForCurrentProjectExact = 0;
|
2012-06-01 09:50:32 +02:00
|
|
|
QStringList subProjectsNotToDeploy;
|
2011-02-09 20:03:04 +01:00
|
|
|
if (evalResult == EvalOk) {
|
2011-09-06 17:21:51 +02:00
|
|
|
if (m_projectType == SubDirsTemplate) {
|
2013-08-09 12:26:32 +02:00
|
|
|
newProjectFilesExact = subDirsPaths(m_readerExact, &subProjectsNotToDeploy, false);
|
2011-09-06 17:21:51 +02:00
|
|
|
exactSubdirs = newProjectFilesExact.toSet();
|
|
|
|
|
}
|
2011-02-09 20:03:04 +01:00
|
|
|
foreach (ProFile *includeFile, m_readerExact->includeFiles()) {
|
|
|
|
|
if (includeFile->fileName() == m_projectFilePath) { // this file
|
|
|
|
|
fileForCurrentProjectExact = includeFile;
|
|
|
|
|
} else {
|
|
|
|
|
newProjectFilesExact << includeFile->fileName();
|
|
|
|
|
includeFilesExact.insert(includeFile->fileName(), includeFile);
|
|
|
|
|
}
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
2010-03-10 16:55:37 +01:00
|
|
|
}
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2010-03-10 16:55:37 +01:00
|
|
|
QStringList newProjectFilesCumlative;
|
|
|
|
|
QHash<QString, ProFile*> includeFilesCumlative;
|
|
|
|
|
ProFile *fileForCurrentProjectCumlative = 0;
|
2011-02-08 12:46:25 +01:00
|
|
|
if (m_projectType == SubDirsTemplate)
|
2013-08-09 12:26:32 +02:00
|
|
|
newProjectFilesCumlative = subDirsPaths(m_readerCumulative, 0, true);
|
2011-02-08 12:46:25 +01:00
|
|
|
foreach (ProFile *includeFile, m_readerCumulative->includeFiles()) {
|
|
|
|
|
if (includeFile->fileName() == m_projectFilePath) {
|
|
|
|
|
fileForCurrentProjectCumlative = includeFile;
|
|
|
|
|
} else {
|
|
|
|
|
newProjectFilesCumlative << includeFile->fileName();
|
|
|
|
|
includeFilesCumlative.insert(includeFile->fileName(), includeFile);
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
qSort(existingProjectNodes.begin(), existingProjectNodes.end(),
|
|
|
|
|
sortNodesByPath);
|
2010-03-10 16:55:37 +01:00
|
|
|
qSort(newProjectFilesExact);
|
|
|
|
|
qSort(newProjectFilesCumlative);
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
|
QList<ProjectNode*> toAdd;
|
|
|
|
|
QList<ProjectNode*> toRemove;
|
|
|
|
|
|
2010-03-10 16:55:37 +01:00
|
|
|
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!
|
|
|
|
|
|
2010-10-30 21:54:23 +02:00
|
|
|
// So this is one giant loop comparing 3 lists at once and sorting the comparison
|
2010-03-10 16:55:37 +01:00
|
|
|
// 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;
|
2012-11-28 20:44:03 +02:00
|
|
|
} else if (! newExactAtEnd
|
2010-03-10 16:55:37 +01:00
|
|
|
&& (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;
|
2012-11-28 20:44:03 +02:00
|
|
|
} else if (*newExactIt < *newCumlativeIt) {
|
2010-03-10 16:55:37 +01:00
|
|
|
++newExactIt;
|
|
|
|
|
} else if (*newCumlativeIt < *newExactIt) {
|
|
|
|
|
++newCumlativeIt;
|
2008-12-02 12:01:29 +01:00
|
|
|
} else {
|
2010-03-10 16:55:37 +01:00
|
|
|
++newExactIt;
|
|
|
|
|
++newCumlativeIt;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
2010-03-10 16:55:37 +01:00
|
|
|
// Update existingNodeIte
|
2011-02-08 21:15:05 +01:00
|
|
|
ProFile *fileExact = includeFilesExact.value((*existingIt)->path());
|
2010-03-10 16:55:37 +01:00
|
|
|
ProFile *fileCumlative = includeFilesCumlative.value((*existingIt)->path());
|
|
|
|
|
if (fileExact || fileCumlative) {
|
2011-09-06 17:21:51 +02:00
|
|
|
Qt4PriFileNode *priFileNode = static_cast<Qt4PriFileNode *>(*existingIt);
|
|
|
|
|
priFileNode->update(fileExact, m_readerExact, fileCumlative, m_readerCumulative);
|
|
|
|
|
priFileNode->setIncludedInExactParse(fileExact != 0 && includedInExactParse());
|
2010-03-10 16:55:37 +01:00
|
|
|
} 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
|
2011-09-06 17:21:51 +02:00
|
|
|
Qt4ProFileNode *proFileNode = static_cast<Qt4ProFileNode *>(*existingIt);
|
|
|
|
|
proFileNode->setIncludedInExactParse(exactSubdirs.contains(proFileNode->path()) && includedInExactParse());
|
2010-03-10 16:55:37 +01:00
|
|
|
if (async)
|
2011-09-06 17:21:51 +02:00
|
|
|
proFileNode->asyncUpdate();
|
2010-03-10 16:55:37 +01:00
|
|
|
else
|
2011-09-06 17:21:51 +02:00
|
|
|
proFileNode->update();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
2010-03-10 16:55:37 +01:00
|
|
|
++existingIt;
|
|
|
|
|
// newCumalativeIt and newExactIt are already incremented
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
|
}
|
2010-05-20 16:02:24 +02:00
|
|
|
// If we found something to add, do it
|
2010-03-10 16:55:37 +01:00
|
|
|
if (!nodeToAdd.isEmpty()) {
|
2011-02-08 21:15:05 +01:00
|
|
|
ProFile *fileExact = includeFilesExact.value(nodeToAdd);
|
2010-03-10 16:55:37 +01:00
|
|
|
ProFile *fileCumlative = includeFilesCumlative.value(nodeToAdd);
|
2010-05-20 16:02:24 +02:00
|
|
|
|
|
|
|
|
// Loop preventation, make sure that exact same node is not in our parent chain
|
|
|
|
|
bool loop = false;
|
|
|
|
|
ProjectExplorer::Node *n = this;
|
|
|
|
|
while ((n = n->parentFolderNode())) {
|
|
|
|
|
if (qobject_cast<Qt4PriFileNode *>(n) && n->path() == nodeToAdd) {
|
|
|
|
|
loop = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (loop) {
|
|
|
|
|
// Do nothing
|
|
|
|
|
} else if (fileExact || fileCumlative) {
|
2010-03-10 16:55:37 +01:00
|
|
|
Qt4PriFileNode *qt4PriFileNode = new Qt4PriFileNode(m_project, this, nodeToAdd);
|
2010-05-20 16:02:24 +02:00
|
|
|
qt4PriFileNode->setParentFolderNode(this); // Needed for loop detection
|
2011-09-06 17:21:51 +02:00
|
|
|
qt4PriFileNode->setIncludedInExactParse(fileExact != 0 && includedInExactParse());
|
2010-03-10 16:55:37 +01:00
|
|
|
qt4PriFileNode->update(fileExact, m_readerExact, fileCumlative, m_readerCumulative);
|
|
|
|
|
toAdd << qt4PriFileNode;
|
|
|
|
|
} else {
|
|
|
|
|
Qt4ProFileNode *qt4ProFileNode = new Qt4ProFileNode(m_project, nodeToAdd);
|
2010-05-20 16:02:24 +02:00
|
|
|
qt4ProFileNode->setParentFolderNode(this); // Needed for loop detection
|
2011-09-06 17:21:51 +02:00
|
|
|
qt4ProFileNode->setIncludedInExactParse(exactSubdirs.contains(qt4ProFileNode->path()) && includedInExactParse());
|
2010-03-10 16:55:37 +01:00
|
|
|
if (async)
|
|
|
|
|
qt4ProFileNode->asyncUpdate();
|
|
|
|
|
else
|
|
|
|
|
qt4ProFileNode->update();
|
|
|
|
|
toAdd << qt4ProFileNode;
|
|
|
|
|
}
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
2010-03-10 16:55:37 +01:00
|
|
|
} // for
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2012-05-08 12:53:24 +02:00
|
|
|
foreach (ProjectNode *node, toRemove) {
|
|
|
|
|
if (Qt4ProFileNode *qt4ProFileNode = qobject_cast<Qt4ProFileNode *>(node)) {
|
|
|
|
|
qt4ProFileNode->setValidParseRecursive(false);
|
|
|
|
|
qt4ProFileNode->setParseInProgressRecursive(false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
if (!toRemove.isEmpty())
|
|
|
|
|
removeProjectNodes(toRemove);
|
|
|
|
|
if (!toAdd.isEmpty())
|
|
|
|
|
addProjectNodes(toAdd);
|
|
|
|
|
|
2010-03-10 16:55:37 +01:00
|
|
|
Qt4PriFileNode::update(fileForCurrentProjectExact, m_readerExact, fileForCurrentProjectCumlative, m_readerCumulative);
|
|
|
|
|
|
2011-06-10 15:37:10 +02:00
|
|
|
m_validParse = (evalResult == EvalOk);
|
|
|
|
|
if (m_validParse) {
|
2011-02-09 20:03:04 +01:00
|
|
|
|
|
|
|
|
// update TargetInformation
|
|
|
|
|
m_qt4targetInformation = targetInformation(m_readerExact);
|
2012-09-04 11:41:32 +02:00
|
|
|
m_resolvedMkspecPath = m_readerExact->resolvedMkSpec();
|
2011-02-09 20:03:04 +01:00
|
|
|
|
2012-06-01 09:50:32 +02:00
|
|
|
m_subProjectsNotToDeploy = subProjectsNotToDeploy;
|
2011-02-09 20:03:04 +01:00
|
|
|
setupInstallsList(m_readerExact);
|
|
|
|
|
|
2012-11-28 13:46:49 +01:00
|
|
|
QString buildDirectory = buildDir();
|
2011-02-09 20:03:04 +01:00
|
|
|
// update other variables
|
|
|
|
|
QHash<Qt4Variable, QStringList> newVarValues;
|
|
|
|
|
|
|
|
|
|
newVarValues[DefinesVar] = m_readerExact->values(QLatin1String("DEFINES"));
|
|
|
|
|
newVarValues[IncludePathVar] = includePaths(m_readerExact);
|
2012-11-26 15:09:56 +02:00
|
|
|
newVarValues[CppFlagsVar] = m_readerExact->values(QLatin1String("QMAKE_CXXFLAGS"));
|
2012-06-05 17:32:30 +02:00
|
|
|
newVarValues[CppHeaderVar] = fileListForVar(m_readerExact, m_readerCumulative,
|
2012-11-28 13:46:49 +01:00
|
|
|
QLatin1String("HEADERS"), m_projectDir, buildDirectory);
|
2012-06-05 17:32:30 +02:00
|
|
|
newVarValues[CppSourceVar] = fileListForVar(m_readerExact, m_readerCumulative,
|
2012-11-28 13:46:49 +01:00
|
|
|
QLatin1String("SOURCES"), m_projectDir, buildDirectory);
|
2012-06-05 17:32:30 +02:00
|
|
|
newVarValues[ObjCSourceVar] = fileListForVar(m_readerExact, m_readerCumulative,
|
2012-11-28 13:46:49 +01:00
|
|
|
QLatin1String("OBJECTIVE_SOURCES"), m_projectDir, buildDirectory);
|
2013-03-21 22:10:38 +04:00
|
|
|
newVarValues[ObjCHeaderVar] = fileListForVar(m_readerExact, m_readerCumulative,
|
|
|
|
|
QLatin1String("OBJECTIVE_HEADERS"), m_projectDir, buildDirectory);
|
2011-02-09 20:03:04 +01:00
|
|
|
newVarValues[UiDirVar] = QStringList() << uiDirPath(m_readerExact);
|
|
|
|
|
newVarValues[MocDirVar] = QStringList() << mocDirPath(m_readerExact);
|
2013-05-21 11:35:15 +02:00
|
|
|
newVarValues[ResourceVar] = fileListForVar(m_readerExact, m_readerCumulative,
|
|
|
|
|
QLatin1String("RESOURCES"), m_projectDir, buildDirectory);
|
|
|
|
|
newVarValues[ExactResourceVar] = fileListForVar(m_readerExact, 0,
|
|
|
|
|
QLatin1String("RESOURCES"), m_projectDir, buildDirectory);
|
2011-02-09 20:03:04 +01:00
|
|
|
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);
|
|
|
|
|
newVarValues[ConfigVar] = m_readerExact->values(QLatin1String("CONFIG"));
|
|
|
|
|
newVarValues[QmlImportPathVar] = m_readerExact->absolutePathValues(
|
|
|
|
|
QLatin1String("QML_IMPORT_PATH"), m_projectDir);
|
2012-01-13 14:20:45 +01:00
|
|
|
newVarValues[Makefile] = m_readerExact->values(QLatin1String("MAKEFILE"));
|
2011-09-15 13:30:54 +02:00
|
|
|
newVarValues[QtVar] = m_readerExact->values(QLatin1String("QT"));
|
2012-04-28 22:24:33 +03:00
|
|
|
newVarValues[ObjectExt] = m_readerExact->values(QLatin1String("QMAKE_EXT_OBJ"));
|
|
|
|
|
newVarValues[ObjectsDir] = m_readerExact->values(QLatin1String("OBJECTS_DIR"));
|
2012-08-20 12:41:52 +02:00
|
|
|
newVarValues[VersionVar] = m_readerExact->values(QLatin1String("VERSION"));
|
2013-03-12 14:09:18 +01:00
|
|
|
newVarValues[TargetExtVar] = m_readerExact->values(QLatin1String("TARGET_EXT"));
|
2012-08-20 12:41:52 +02:00
|
|
|
newVarValues[TargetVersionExtVar]
|
|
|
|
|
= m_readerExact->values(QLatin1String("TARGET_VERSION_EXT"));
|
2012-11-26 15:09:56 +02:00
|
|
|
newVarValues[StaticLibExtensionVar] = m_readerExact->values(QLatin1String("QMAKE_EXTENSION_STATICLIB"));
|
|
|
|
|
newVarValues[ShLibExtensionVar] = m_readerExact->values(QLatin1String("QMAKE_EXTENSION_SHLIB"));
|
2013-02-27 16:29:32 +01:00
|
|
|
newVarValues[AndroidArchVar] = m_readerExact->values(QLatin1String("ANDROID_TARGET_ARCH"));
|
2011-05-10 16:18:04 +02:00
|
|
|
|
|
|
|
|
m_isDeployable = false;
|
|
|
|
|
if (m_projectType == ApplicationTemplate) {
|
|
|
|
|
m_isDeployable = true;
|
|
|
|
|
} else {
|
2012-01-13 14:20:45 +01:00
|
|
|
foreach (const QString &item, m_readerExact->values(QLatin1String("DEPLOYMENT"))) {
|
|
|
|
|
if (!m_readerExact->values(item + QLatin1String(".sources")).isEmpty()) {
|
2011-05-10 16:18:04 +02:00
|
|
|
m_isDeployable = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2011-02-09 20:03:04 +01:00
|
|
|
|
|
|
|
|
if (m_varValues != newVarValues) {
|
|
|
|
|
Qt4VariablesHash oldValues = m_varValues;
|
|
|
|
|
m_varValues = newVarValues;
|
|
|
|
|
|
2011-05-25 11:23:25 +02:00
|
|
|
foreach (ProjectExplorer::NodesWatcher *watcher, watchers())
|
|
|
|
|
if (Internal::Qt4NodesWatcher *qt4Watcher = qobject_cast<Internal::Qt4NodesWatcher*>(watcher))
|
2011-02-09 20:03:04 +01:00
|
|
|
emit qt4Watcher->variablesChanged(this, oldValues, m_varValues);
|
|
|
|
|
}
|
|
|
|
|
} // evalResult == EvalOk
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2011-09-12 12:40:53 +02:00
|
|
|
setParseInProgress(false);
|
2011-06-10 15:37:10 +02:00
|
|
|
|
2013-07-11 16:24:51 +02:00
|
|
|
updateUiFiles();
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2010-03-10 16:55:37 +01:00
|
|
|
m_project->destroyProFileReader(m_readerExact);
|
2011-02-08 12:46:25 +01:00
|
|
|
m_project->destroyProFileReader(m_readerCumulative);
|
2010-03-10 16:55:37 +01:00
|
|
|
|
|
|
|
|
m_readerExact = 0;
|
|
|
|
|
m_readerCumulative = 0;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2012-04-19 13:43:51 +02:00
|
|
|
QStringList Qt4ProFileNode::fileListForVar(QtSupport::ProFileReader *readerExact, QtSupport::ProFileReader *readerCumulative,
|
2012-11-28 13:46:49 +01:00
|
|
|
const QString &varName, const QString &projectDir, const QString &buildDir) const
|
2012-04-19 13:43:51 +02:00
|
|
|
{
|
2012-11-28 13:46:49 +01:00
|
|
|
QStringList baseVPathsExact = baseVPaths(readerExact, projectDir, buildDir);
|
|
|
|
|
QStringList vPathsExact = fullVPaths(baseVPathsExact, readerExact, varName, projectDir);
|
2012-06-05 17:32:30 +02:00
|
|
|
|
2012-04-19 13:43:51 +02:00
|
|
|
QStringList result;
|
|
|
|
|
result = readerExact->absoluteFileValues(varName,
|
|
|
|
|
projectDir,
|
2012-06-05 17:32:30 +02:00
|
|
|
vPathsExact,
|
2012-04-19 13:43:51 +02:00
|
|
|
0);
|
2012-06-05 17:32:30 +02:00
|
|
|
if (readerCumulative) {
|
2012-11-28 13:46:49 +01:00
|
|
|
QStringList baseVPathsCumulative = baseVPaths(readerCumulative, projectDir, buildDir);
|
|
|
|
|
QStringList vPathsCumulative = fullVPaths(baseVPathsCumulative, readerCumulative, varName, projectDir);
|
2012-04-19 13:43:51 +02:00
|
|
|
result += readerCumulative->absoluteFileValues(varName,
|
|
|
|
|
projectDir,
|
2012-06-05 17:32:30 +02:00
|
|
|
vPathsCumulative,
|
2012-04-19 13:43:51 +02:00
|
|
|
0);
|
2012-06-05 17:32:30 +02:00
|
|
|
}
|
2012-04-19 13:43:51 +02:00
|
|
|
result.removeDuplicates();
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2011-05-20 21:40:53 +02:00
|
|
|
QString Qt4ProFileNode::uiDirPath(QtSupport::ProFileReader *reader) const
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2012-01-13 14:20:45 +01:00
|
|
|
QString path = reader->value(QLatin1String("UI_DIR"));
|
2010-04-13 16:34:51 +02:00
|
|
|
if (QFileInfo(path).isRelative())
|
2012-01-13 14:20:45 +01:00
|
|
|
path = QDir::cleanPath(buildDir() + QLatin1Char('/') + path);
|
2010-04-13 16:34:51 +02:00
|
|
|
return path;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2011-05-20 21:40:53 +02:00
|
|
|
QString Qt4ProFileNode::mocDirPath(QtSupport::ProFileReader *reader) const
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2012-01-13 14:20:45 +01:00
|
|
|
QString path = reader->value(QLatin1String("MOC_DIR"));
|
2010-04-13 16:34:51 +02:00
|
|
|
if (QFileInfo(path).isRelative())
|
2012-01-13 14:20:45 +01:00
|
|
|
path = QDir::cleanPath(buildDir() + QLatin1Char('/') + path);
|
2010-04-13 16:34:51 +02:00
|
|
|
return path;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2011-05-20 21:40:53 +02:00
|
|
|
QStringList Qt4ProFileNode::includePaths(QtSupport::ProFileReader *reader) const
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
|
|
|
|
QStringList paths;
|
2012-01-13 14:20:45 +01:00
|
|
|
foreach (const QString &cxxflags, m_readerExact->values(QLatin1String("QMAKE_CXXFLAGS"))) {
|
|
|
|
|
if (cxxflags.startsWith(QLatin1String("-I")))
|
2010-03-29 17:11:26 +02:00
|
|
|
paths.append(cxxflags.mid(2));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
paths.append(reader->absolutePathValues(QLatin1String("INCLUDEPATH"), m_projectDir));
|
2012-12-07 19:53:38 +02:00
|
|
|
paths.append(reader->absolutePathValues(QLatin1String("QMAKE_INCDIR"), m_projectDir));
|
2010-04-13 16:34:51 +02:00
|
|
|
// 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
|
2010-10-30 21:54:23 +02:00
|
|
|
// thus we add those directories manually (without checking for existence)
|
2010-04-13 16:34:51 +02:00
|
|
|
paths << mocDirPath(reader) << uiDirPath(reader);
|
2011-11-29 16:47:57 +01:00
|
|
|
// qmake always adds "."
|
|
|
|
|
paths << m_projectDir;
|
2008-12-02 12:01:29 +01:00
|
|
|
paths.removeDuplicates();
|
|
|
|
|
return paths;
|
|
|
|
|
}
|
|
|
|
|
|
2011-05-20 21:40:53 +02:00
|
|
|
QStringList Qt4ProFileNode::libDirectories(QtSupport::ProFileReader *reader) const
|
2010-03-29 15:17:04 +02:00
|
|
|
{
|
|
|
|
|
QStringList result;
|
|
|
|
|
foreach (const QString &str, reader->values(QLatin1String("LIBS"))) {
|
Remove braces for single lines of conditions
#!/usr/bin/env ruby
Dir.glob('**/*.cpp') { |file|
# skip ast (excluding paste, astpath, and canv'ast'imer)
next if file =~ /ast[^eip]|keywords\.|qualifiers|preprocessor|names.cpp/i
s = File.read(file)
next if s.include?('qlalr')
orig = s.dup
s.gsub!(/\n *if [^\n]*{\n[^\n]*\n\s+}(\s+else if [^\n]* {\n[^\n]*\n\s+})*(\s+else {\n[^\n]*\n\s+})?\n/m) { |m|
res = $&
if res =~ /^\s*(\/\/|[A-Z_]{3,})/ # C++ comment or macro (Q_UNUSED, SDEBUG), do not touch braces
res
else
res.gsub!('} else', 'else')
res.gsub!(/\n +} *\n/m, "\n")
res.gsub(/ *{$/, '')
end
}
s.gsub!(/ *$/, '')
File.open(file, 'wb').write(s) if s != orig
}
Change-Id: I3b30ee60df0986f66c02132c65fc38a3fbb6bbdc
Reviewed-by: hjk <qthjk@ovi.com>
2013-01-08 03:32:53 +02:00
|
|
|
if (str.startsWith(QLatin1String("-L")))
|
2010-03-29 15:17:04 +02:00
|
|
|
result.append(str.mid(2));
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2013-08-09 12:26:32 +02:00
|
|
|
QStringList Qt4ProFileNode::subDirsPaths(QtSupport::ProFileReader *reader, QStringList *subProjectsNotToDeploy,
|
|
|
|
|
bool silent) const
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
|
|
|
|
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"
|
2009-03-12 14:57:37 +01:00
|
|
|
// or
|
|
|
|
|
// "SUBDIR = subid
|
|
|
|
|
// subid.file = realdir/realfile.pro"
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
|
QString realDir;
|
|
|
|
|
const QString subDirKey = subDirVar + QLatin1String(".subdir");
|
2009-03-12 14:57:37 +01:00
|
|
|
const QString subDirFileKey = subDirVar + QLatin1String(".file");
|
2008-12-02 12:01:29 +01:00
|
|
|
if (reader->contains(subDirKey))
|
2010-06-08 14:02:15 +02:00
|
|
|
realDir = reader->value(subDirKey);
|
2009-03-12 14:57:37 +01:00
|
|
|
else if (reader->contains(subDirFileKey))
|
2010-06-08 14:02:15 +02:00
|
|
|
realDir = reader->value(subDirFileKey);
|
2009-03-12 14:57:37 +01:00
|
|
|
else
|
2008-12-02 12:01:29 +01:00
|
|
|
realDir = subDirVar;
|
|
|
|
|
QFileInfo info(realDir);
|
2010-06-08 14:02:15 +02:00
|
|
|
if (!info.isAbsolute())
|
2010-02-01 12:43:56 +01:00
|
|
|
info.setFile(m_projectDir + QLatin1Char('/') + realDir);
|
2010-06-08 14:02:15 +02:00
|
|
|
realDir = info.filePath();
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2009-07-27 12:50:42 +02:00
|
|
|
QString realFile;
|
Remove braces for single lines of conditions
#!/usr/bin/env ruby
Dir.glob('**/*.cpp') { |file|
# skip ast (excluding paste, astpath, and canv'ast'imer)
next if file =~ /ast[^eip]|keywords\.|qualifiers|preprocessor|names.cpp/i
s = File.read(file)
next if s.include?('qlalr')
orig = s.dup
s.gsub!(/\n *if [^\n]*{\n[^\n]*\n\s+}(\s+else if [^\n]* {\n[^\n]*\n\s+})*(\s+else {\n[^\n]*\n\s+})?\n/m) { |m|
res = $&
if res =~ /^\s*(\/\/|[A-Z_]{3,})/ # C++ comment or macro (Q_UNUSED, SDEBUG), do not touch braces
res
else
res.gsub!('} else', 'else')
res.gsub!(/\n +} *\n/m, "\n")
res.gsub(/ *{$/, '')
end
}
s.gsub!(/ *$/, '')
File.open(file, 'wb').write(s) if s != orig
}
Change-Id: I3b30ee60df0986f66c02132c65fc38a3fbb6bbdc
Reviewed-by: hjk <qthjk@ovi.com>
2013-01-08 03:32:53 +02:00
|
|
|
if (info.isDir())
|
2010-02-01 12:43:56 +01:00
|
|
|
realFile = QString::fromLatin1("%1/%2.pro").arg(realDir, info.fileName());
|
Remove braces for single lines of conditions
#!/usr/bin/env ruby
Dir.glob('**/*.cpp') { |file|
# skip ast (excluding paste, astpath, and canv'ast'imer)
next if file =~ /ast[^eip]|keywords\.|qualifiers|preprocessor|names.cpp/i
s = File.read(file)
next if s.include?('qlalr')
orig = s.dup
s.gsub!(/\n *if [^\n]*{\n[^\n]*\n\s+}(\s+else if [^\n]* {\n[^\n]*\n\s+})*(\s+else {\n[^\n]*\n\s+})?\n/m) { |m|
res = $&
if res =~ /^\s*(\/\/|[A-Z_]{3,})/ # C++ comment or macro (Q_UNUSED, SDEBUG), do not touch braces
res
else
res.gsub!('} else', 'else')
res.gsub!(/\n +} *\n/m, "\n")
res.gsub(/ *{$/, '')
end
}
s.gsub!(/ *$/, '')
File.open(file, 'wb').write(s) if s != orig
}
Change-Id: I3b30ee60df0986f66c02132c65fc38a3fbb6bbdc
Reviewed-by: hjk <qthjk@ovi.com>
2013-01-08 03:32:53 +02:00
|
|
|
else
|
2008-12-02 12:01:29 +01:00
|
|
|
realFile = realDir;
|
|
|
|
|
|
2010-01-19 15:59:36 +01:00
|
|
|
if (QFile::exists(realFile)) {
|
2012-06-01 09:50:32 +02:00
|
|
|
realFile = QDir::cleanPath(realFile);
|
|
|
|
|
subProjectPaths << realFile;
|
|
|
|
|
if (subProjectsNotToDeploy && !subProjectsNotToDeploy->contains(realFile)
|
|
|
|
|
&& reader->values(subDirVar + QLatin1String(".CONFIG"))
|
|
|
|
|
.contains(QLatin1String("no_default_target"))) {
|
|
|
|
|
subProjectsNotToDeploy->append(realFile);
|
|
|
|
|
}
|
2010-01-19 15:59:36 +01:00
|
|
|
} else {
|
2013-08-09 12:26:32 +02:00
|
|
|
if (!silent)
|
|
|
|
|
m_project->proFileParseError(tr("Could not find .pro file for sub dir '%1' in '%2'")
|
|
|
|
|
.arg(subDirVar).arg(realDir));
|
2010-01-19 15:59:36 +01:00
|
|
|
}
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2010-06-08 13:57:23 +02:00
|
|
|
subProjectPaths.removeDuplicates();
|
2008-12-02 12:01:29 +01:00
|
|
|
return subProjectPaths;
|
|
|
|
|
}
|
|
|
|
|
|
2011-05-20 21:40:53 +02:00
|
|
|
TargetInformation Qt4ProFileNode::targetInformation(QtSupport::ProFileReader *reader) const
|
2010-03-10 16:55:37 +01:00
|
|
|
{
|
|
|
|
|
TargetInformation result;
|
|
|
|
|
if (!reader)
|
|
|
|
|
return result;
|
|
|
|
|
|
2012-10-23 17:40:10 +02:00
|
|
|
QtSupport::ProFileReader *readerBP = 0;
|
2012-11-26 15:09:56 +02:00
|
|
|
QStringList builds = reader->values(QLatin1String("BUILDS"));
|
2012-10-23 17:40:10 +02:00
|
|
|
if (!builds.isEmpty()) {
|
|
|
|
|
QString build = builds.first();
|
2013-03-12 14:09:18 +01:00
|
|
|
result.buildTarget = reader->value(build + QLatin1String(".target"));
|
2012-10-23 17:40:10 +02:00
|
|
|
|
|
|
|
|
QHash<QString, QStringList> basevars;
|
|
|
|
|
QStringList basecfgs = reader->values(build + QLatin1String(".CONFIG"));
|
|
|
|
|
basecfgs += build;
|
2012-11-26 15:09:56 +02:00
|
|
|
basecfgs += QLatin1String("build_pass");
|
|
|
|
|
basevars[QLatin1String("BUILD_PASS")] = QStringList(build);
|
2012-10-23 17:40:10 +02:00
|
|
|
QStringList buildname = reader->values(build + QLatin1String(".name"));
|
2012-11-26 15:09:56 +02:00
|
|
|
basevars[QLatin1String("BUILD_NAME")] = (buildname.isEmpty() ? QStringList(build) : buildname);
|
2012-10-23 17:40:10 +02:00
|
|
|
|
|
|
|
|
readerBP = m_project->createProFileReader(this);
|
|
|
|
|
readerBP->setExtraVars(basevars);
|
|
|
|
|
readerBP->setExtraConfigs(basecfgs);
|
|
|
|
|
|
|
|
|
|
EvalResult evalResult = EvalOk;
|
|
|
|
|
if (ProFile *pro = readerBP->parsedProFile(m_projectFilePath)) {
|
|
|
|
|
if (!readerBP->accept(pro, QMakeEvaluator::LoadAll))
|
|
|
|
|
evalResult = EvalPartial;
|
|
|
|
|
pro->deref();
|
|
|
|
|
} else {
|
|
|
|
|
evalResult = EvalFail;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (evalResult != EvalOk)
|
|
|
|
|
return result;
|
|
|
|
|
|
|
|
|
|
reader = readerBP;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// BUILD DIR
|
2010-05-07 10:41:34 +02:00
|
|
|
result.buildDir = buildDir();
|
2010-03-10 16:55:37 +01:00
|
|
|
|
2013-03-12 14:09:18 +01:00
|
|
|
if (reader->contains(QLatin1String("DESTDIR")))
|
|
|
|
|
result.destDir = reader->value(QLatin1String("DESTDIR"));
|
2010-03-10 16:55:37 +01:00
|
|
|
|
2012-10-23 17:40:10 +02:00
|
|
|
// Target
|
2012-01-13 14:20:45 +01:00
|
|
|
result.target = reader->value(QLatin1String("TARGET"));
|
2010-03-10 16:55:37 +01:00
|
|
|
if (result.target.isEmpty())
|
|
|
|
|
result.target = QFileInfo(m_projectFilePath).baseName();
|
|
|
|
|
|
|
|
|
|
result.valid = true;
|
2012-10-23 17:40:10 +02:00
|
|
|
|
|
|
|
|
if (readerBP)
|
|
|
|
|
m_project->destroyProFileReader(readerBP);
|
|
|
|
|
|
2010-03-10 16:55:37 +01:00
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2010-07-06 14:32:33 +02:00
|
|
|
TargetInformation Qt4ProFileNode::targetInformation() const
|
2010-03-10 16:55:37 +01:00
|
|
|
{
|
|
|
|
|
return m_qt4targetInformation;
|
|
|
|
|
}
|
|
|
|
|
|
2011-10-07 15:40:38 +02:00
|
|
|
QString Qt4ProFileNode::resolvedMkspecPath() const
|
|
|
|
|
{
|
|
|
|
|
return m_resolvedMkspecPath;
|
|
|
|
|
}
|
|
|
|
|
|
2011-05-20 21:40:53 +02:00
|
|
|
void Qt4ProFileNode::setupInstallsList(const QtSupport::ProFileReader *reader)
|
2010-10-27 17:19:52 +02:00
|
|
|
{
|
|
|
|
|
m_installsList.clear();
|
|
|
|
|
if (!reader)
|
|
|
|
|
return;
|
|
|
|
|
const QStringList &itemList = reader->values(QLatin1String("INSTALLS"));
|
|
|
|
|
foreach (const QString &item, itemList) {
|
2012-06-01 17:09:58 +02:00
|
|
|
if (reader->values(item + QLatin1String(".CONFIG")).contains(QLatin1String("no_default_install")))
|
|
|
|
|
continue;
|
2010-10-27 17:19:52 +02:00
|
|
|
QString itemPath;
|
2010-10-28 09:22:19 +02:00
|
|
|
const QString pathVar = item + QLatin1String(".path");
|
2010-10-27 17:19:52 +02:00
|
|
|
const QStringList &itemPaths = reader->values(pathVar);
|
|
|
|
|
if (itemPaths.count() != 1) {
|
|
|
|
|
qDebug("Invalid RHS: Variable '%s' has %d values.",
|
|
|
|
|
qPrintable(pathVar), itemPaths.count());
|
|
|
|
|
if (itemPaths.isEmpty()) {
|
2010-12-02 16:50:15 +01:00
|
|
|
qDebug("%s: Ignoring INSTALLS item '%s', because it has no path.",
|
|
|
|
|
qPrintable(m_projectFilePath), qPrintable(item));
|
2010-10-27 17:19:52 +02:00
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
2010-10-28 09:22:19 +02:00
|
|
|
itemPath = itemPaths.last();
|
2010-10-27 17:19:52 +02:00
|
|
|
|
|
|
|
|
const QStringList &itemFiles
|
|
|
|
|
= reader->absoluteFileValues(item + QLatin1String(".files"),
|
|
|
|
|
m_projectDir, QStringList() << m_projectDir, 0);
|
|
|
|
|
if (item == QLatin1String("target")) {
|
|
|
|
|
m_installsList.targetPath = itemPath;
|
|
|
|
|
} else {
|
|
|
|
|
if (itemFiles.isEmpty()) {
|
2010-12-16 14:46:24 +01:00
|
|
|
// TODO: Fix QMAKE_SUBSTITUTES handling in pro file reader, then uncomment again
|
|
|
|
|
// if (!reader->values(item + QLatin1String(".CONFIG"))
|
|
|
|
|
// .contains(QLatin1String("no_check_exist"))) {
|
|
|
|
|
// qDebug("%s: Ignoring INSTALLS item '%s', because it has no files.",
|
|
|
|
|
// qPrintable(m_projectFilePath), qPrintable(item));
|
|
|
|
|
// }
|
2010-10-27 17:19:52 +02:00
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
m_installsList.items << InstallsItem(itemPath, itemFiles);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
InstallsList Qt4ProFileNode::installsList() const
|
|
|
|
|
{
|
|
|
|
|
return m_installsList;
|
|
|
|
|
}
|
|
|
|
|
|
2012-05-03 12:42:05 +02:00
|
|
|
QString Qt4ProFileNode::sourceDir() const
|
|
|
|
|
{
|
|
|
|
|
return m_projectDir;
|
|
|
|
|
}
|
|
|
|
|
|
2011-01-21 15:37:05 +01:00
|
|
|
QString Qt4ProFileNode::buildDir(Qt4BuildConfiguration *bc) const
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2012-05-03 12:42:05 +02:00
|
|
|
const QDir srcDirRoot = m_project->rootQt4ProjectNode()->sourceDir();
|
2008-12-02 12:01:29 +01:00
|
|
|
const QString relativeDir = srcDirRoot.relativeFilePath(m_projectDir);
|
2011-01-21 15:37:05 +01:00
|
|
|
if (!bc && m_project->activeTarget())
|
2012-07-04 15:43:39 +02:00
|
|
|
bc = static_cast<Qt4BuildConfiguration *>(m_project->activeTarget()->activeBuildConfiguration());
|
2011-01-21 15:37:05 +01:00
|
|
|
if (!bc)
|
|
|
|
|
return QString();
|
2013-04-10 16:22:15 +02:00
|
|
|
return QDir::cleanPath(QDir(bc->buildDirectory()).absoluteFilePath(relativeDir));
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2009-12-03 16:23:15 +01:00
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2013-07-11 16:24:51 +02:00
|
|
|
void Qt4ProFileNode::updateUiFiles()
|
2009-05-12 14:12:20 +02:00
|
|
|
{
|
2013-07-11 16:24:51 +02:00
|
|
|
m_uiFiles.clear();
|
2012-10-08 14:33:33 +02:00
|
|
|
|
2009-05-12 14:12:20 +02:00
|
|
|
// Only those two project types can have ui files for us
|
|
|
|
|
if (m_projectType == ApplicationTemplate || m_projectType == LibraryTemplate) {
|
|
|
|
|
// Find all ui files
|
2011-09-07 11:52:04 +02:00
|
|
|
FindUiFileNodesVisitor uiFilesVisitor;
|
2009-05-12 14:12:20 +02:00
|
|
|
this->accept(&uiFilesVisitor);
|
2011-05-25 11:23:25 +02:00
|
|
|
const QList<ProjectExplorer::FileNode*> uiFiles = uiFilesVisitor.uiFileNodes;
|
2009-05-12 14:12:20 +02:00
|
|
|
|
|
|
|
|
// Find the UiDir, there can only ever be one
|
2009-12-03 16:23:15 +01:00
|
|
|
const QString uiDir = uiDirectory();
|
2013-07-11 16:24:51 +02:00
|
|
|
foreach (const ProjectExplorer::FileNode *uiFile, uiFiles)
|
|
|
|
|
m_uiFiles.insert(uiFile->path(), uiHeaderFile(uiDir, uiFile->path()));
|
2009-05-12 14:12:20 +02:00
|
|
|
}
|
|
|
|
|
}
|