forked from qt-creator/qt-creator
Use exact and aysnc .pro file evaluate
This is a big change touching almost all of our .pro file parsing. With this patch we only evaluate once exact for all needs and once greedy for the filelist. That is the qt runconfigurations don't have own evaluaters but reuse the project wide exact evaluation. We reevaluate if the user changes the build directory, the qmake buildconfiguration or the qmake arguments. That is if you open src.pro (or projects.pro) of qt with a shadow build you still don't get all the files, but after correcting the build directory, we reevaluate the .pro files and find all files. So for a suitable definition of fixed, that bug is now fixed. We now get the exact defines of all .pro files instead of all defines for all buildconfigurations. We still don't distinguish in which .pro file a DEFINE is set. So the code model now knows about all the defines set for the given configuration but not for which files it is actually set. Also that includes all DEFINES set in .qmake.cache or the mkspecs. This means all defines from .pro files should now work. The intial loading is still synchronous. I haven't looked into it to deeply, but it seems possible to make it also async.There are probably a few issues which need to be solved fist. Also due to the asynchronous nature of the code, the executable is updated a few seconds after actually changing the build configuration
This commit is contained in:
@@ -61,6 +61,7 @@ Node::Node(NodeType nodeType,
|
|||||||
m_folderNode(0),
|
m_folderNode(0),
|
||||||
m_path(filePath)
|
m_path(filePath)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeType Node::nodeType() const
|
NodeType Node::nodeType() const
|
||||||
|
@@ -116,12 +116,27 @@ ProFileCacheManager *ProFileCacheManager::s_instance = 0;
|
|||||||
|
|
||||||
ProFileCacheManager::ProFileCacheManager(QObject *parent) :
|
ProFileCacheManager::ProFileCacheManager(QObject *parent) :
|
||||||
QObject(parent),
|
QObject(parent),
|
||||||
m_cache(0)
|
m_cache(0),
|
||||||
|
m_refCount(0)
|
||||||
{
|
{
|
||||||
s_instance = this;
|
s_instance = this;
|
||||||
m_timer.setSingleShot(true);
|
|
||||||
m_timer.setInterval(5000);
|
m_timer.setInterval(5000);
|
||||||
connect(&m_timer, SIGNAL(timeout()), SLOT(clear()));
|
m_timer.setSingleShot(true);
|
||||||
|
connect(&m_timer, SIGNAL(timeout()),
|
||||||
|
this, SLOT(clear()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProFileCacheManager::incRefCount()
|
||||||
|
{
|
||||||
|
++m_refCount;
|
||||||
|
m_timer.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProFileCacheManager::decRefCount()
|
||||||
|
{
|
||||||
|
--m_refCount;
|
||||||
|
if (!m_refCount)
|
||||||
|
m_timer.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
ProFileCacheManager::~ProFileCacheManager()
|
ProFileCacheManager::~ProFileCacheManager()
|
||||||
@@ -132,7 +147,6 @@ ProFileCacheManager::~ProFileCacheManager()
|
|||||||
|
|
||||||
ProFileCache *ProFileCacheManager::cache()
|
ProFileCache *ProFileCacheManager::cache()
|
||||||
{
|
{
|
||||||
m_timer.start();
|
|
||||||
if (!m_cache)
|
if (!m_cache)
|
||||||
m_cache = new ProFileCache;
|
m_cache = new ProFileCache;
|
||||||
return m_cache;
|
return m_cache;
|
||||||
@@ -140,6 +154,7 @@ ProFileCache *ProFileCacheManager::cache()
|
|||||||
|
|
||||||
void ProFileCacheManager::clear()
|
void ProFileCacheManager::clear()
|
||||||
{
|
{
|
||||||
|
Q_ASSERT(m_refCount == 0);
|
||||||
// Just deleting the cache will be safe as long as the sequence of
|
// Just deleting the cache will be safe as long as the sequence of
|
||||||
// obtaining a cache pointer and using it is atomic as far as the main
|
// obtaining a cache pointer and using it is atomic as far as the main
|
||||||
// loop is concerned. Use a shared pointer once this is not true anymore.
|
// loop is concerned. Use a shared pointer once this is not true anymore.
|
||||||
|
@@ -77,13 +77,16 @@ public:
|
|||||||
ProFileCache *cache();
|
ProFileCache *cache();
|
||||||
void discardFiles(const QString &prefix);
|
void discardFiles(const QString &prefix);
|
||||||
void discardFile(const QString &fileName);
|
void discardFile(const QString &fileName);
|
||||||
|
void incRefCount();
|
||||||
|
void decRefCount();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ProFileCacheManager(QObject *parent);
|
ProFileCacheManager(QObject *parent);
|
||||||
~ProFileCacheManager();
|
~ProFileCacheManager();
|
||||||
Q_SLOT void clear();
|
Q_SLOT void clear();
|
||||||
QTimer m_timer;
|
|
||||||
ProFileCache *m_cache;
|
ProFileCache *m_cache;
|
||||||
|
int m_refCount;
|
||||||
|
QTimer m_timer;
|
||||||
|
|
||||||
static ProFileCacheManager *s_instance;
|
static ProFileCacheManager *s_instance;
|
||||||
|
|
||||||
|
@@ -52,7 +52,6 @@ MaemoRunConfiguration::MaemoRunConfiguration(Qt4Target *parent,
|
|||||||
const QString &proFilePath)
|
const QString &proFilePath)
|
||||||
: RunConfiguration(parent, QLatin1String(MAEMO_RC_ID))
|
: RunConfiguration(parent, QLatin1String(MAEMO_RC_ID))
|
||||||
, m_proFilePath(proFilePath)
|
, m_proFilePath(proFilePath)
|
||||||
, m_cachedTargetInformationValid(false)
|
|
||||||
, m_cachedSimulatorInformationValid(false)
|
, m_cachedSimulatorInformationValid(false)
|
||||||
, qemu(0)
|
, qemu(0)
|
||||||
{
|
{
|
||||||
@@ -62,9 +61,7 @@ MaemoRunConfiguration::MaemoRunConfiguration(Qt4Target *parent,
|
|||||||
MaemoRunConfiguration::MaemoRunConfiguration(Qt4Target *parent,
|
MaemoRunConfiguration::MaemoRunConfiguration(Qt4Target *parent,
|
||||||
MaemoRunConfiguration *source)
|
MaemoRunConfiguration *source)
|
||||||
: RunConfiguration(parent, source)
|
: RunConfiguration(parent, source)
|
||||||
, m_executable(source->m_executable)
|
|
||||||
, m_proFilePath(source->m_proFilePath)
|
, m_proFilePath(source->m_proFilePath)
|
||||||
, m_cachedTargetInformationValid(false)
|
|
||||||
, m_simulator(source->m_simulator)
|
, m_simulator(source->m_simulator)
|
||||||
, m_simulatorArgs(source->m_simulatorArgs)
|
, m_simulatorArgs(source->m_simulatorArgs)
|
||||||
, m_simulatorPath(source->m_simulatorPath)
|
, m_simulatorPath(source->m_simulatorPath)
|
||||||
@@ -95,8 +92,8 @@ void MaemoRunConfiguration::init()
|
|||||||
connect(&MaemoDeviceConfigurations::instance(), SIGNAL(updated()), this,
|
connect(&MaemoDeviceConfigurations::instance(), SIGNAL(updated()), this,
|
||||||
SLOT(updateDeviceConfigurations()));
|
SLOT(updateDeviceConfigurations()));
|
||||||
|
|
||||||
connect(qt4Target(), SIGNAL(targetInformationChanged()), this,
|
connect(qt4Target()->qt4Project(), SIGNAL(proFileUpdated(Qt4ProjectManager::Internal::Qt4ProFileNode*)),
|
||||||
SLOT(invalidateCachedTargetInformation()));
|
this, SLOT(proFileUpdate(Qt4ProjectManager::Internal::Qt4ProFileNode*)));
|
||||||
|
|
||||||
connect(qt4Target()->qt4Project(),
|
connect(qt4Target()->qt4Project(),
|
||||||
SIGNAL(proFileUpdated(Qt4ProjectManager::Internal::Qt4ProFileNode*)),
|
SIGNAL(proFileUpdated(Qt4ProjectManager::Internal::Qt4ProFileNode*)),
|
||||||
@@ -148,7 +145,7 @@ QWidget *MaemoRunConfiguration::configurationWidget()
|
|||||||
void MaemoRunConfiguration::proFileUpdate(Qt4ProjectManager::Internal::Qt4ProFileNode *pro)
|
void MaemoRunConfiguration::proFileUpdate(Qt4ProjectManager::Internal::Qt4ProFileNode *pro)
|
||||||
{
|
{
|
||||||
if (m_proFilePath == pro->path())
|
if (m_proFilePath == pro->path())
|
||||||
invalidateCachedTargetInformation();
|
emit targetInformationChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariantMap MaemoRunConfiguration::toMap() const
|
QVariantMap MaemoRunConfiguration::toMap() const
|
||||||
@@ -329,8 +326,11 @@ const QString MaemoRunConfiguration::dumperLib() const
|
|||||||
|
|
||||||
QString MaemoRunConfiguration::executable() const
|
QString MaemoRunConfiguration::executable() const
|
||||||
{
|
{
|
||||||
updateTarget();
|
TargetInformation ti = qt4Target()->qt4Project()->rootProjectNode()->targetInformation(m_proFilePath);
|
||||||
return m_executable;
|
if (!ti.valid)
|
||||||
|
return QString();
|
||||||
|
|
||||||
|
return QDir::cleanPath(ti.workingDir + QLatin1Char('/') + ti.target);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString MaemoRunConfiguration::simulatorSshPort() const
|
QString MaemoRunConfiguration::simulatorSshPort() const
|
||||||
@@ -379,39 +379,6 @@ bool MaemoRunConfiguration::isQemuRunning() const
|
|||||||
return (qemu && qemu->state() != QProcess::NotRunning);
|
return (qemu && qemu->state() != QProcess::NotRunning);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MaemoRunConfiguration::invalidateCachedTargetInformation()
|
|
||||||
{
|
|
||||||
m_cachedTargetInformationValid = false;
|
|
||||||
emit targetInformationChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MaemoRunConfiguration::updateTarget() const
|
|
||||||
{
|
|
||||||
if (m_cachedTargetInformationValid)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_executable.clear();
|
|
||||||
m_cachedTargetInformationValid = true;
|
|
||||||
|
|
||||||
Qt4TargetInformation info =
|
|
||||||
qt4Target()->targetInformation(activeQt4BuildConfiguration(),
|
|
||||||
m_proFilePath);
|
|
||||||
if (info.error != Qt4TargetInformation::NoError) {
|
|
||||||
if (info.error == Qt4TargetInformation::ProParserError) {
|
|
||||||
Core::ICore::instance()->messageManager()->printToOutputPane(tr(
|
|
||||||
"Could not parse %1. The Maemo run configuration %2 "
|
|
||||||
"can not be started.").arg(m_proFilePath).arg(displayName()));
|
|
||||||
}
|
|
||||||
emit targetInformationChanged();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_executable
|
|
||||||
= QDir::cleanPath(info.workingDir % QLatin1Char('/') % info.target);
|
|
||||||
|
|
||||||
emit targetInformationChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MaemoRunConfiguration::updateSimulatorInformation() const
|
void MaemoRunConfiguration::updateSimulatorInformation() const
|
||||||
{
|
{
|
||||||
if (m_cachedSimulatorInformationValid)
|
if (m_cachedSimulatorInformationValid)
|
||||||
|
@@ -114,14 +114,12 @@ protected:
|
|||||||
private slots:
|
private slots:
|
||||||
void proFileUpdate(Qt4ProjectManager::Internal::Qt4ProFileNode *pro);
|
void proFileUpdate(Qt4ProjectManager::Internal::Qt4ProFileNode *pro);
|
||||||
void updateDeviceConfigurations();
|
void updateDeviceConfigurations();
|
||||||
void invalidateCachedTargetInformation();
|
|
||||||
|
|
||||||
void startStopQemu();
|
void startStopQemu();
|
||||||
void qemuProcessFinished();
|
void qemuProcessFinished();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void init();
|
void init();
|
||||||
void updateTarget() const;
|
|
||||||
void updateSimulatorInformation() const;
|
void updateSimulatorInformation() const;
|
||||||
const QString cmd(const QString &cmdName) const;
|
const QString cmd(const QString &cmdName) const;
|
||||||
const MaemoToolChain *toolchain() const;
|
const MaemoToolChain *toolchain() const;
|
||||||
@@ -133,9 +131,7 @@ private:
|
|||||||
QMap<QString, QDateTime> &deployTimes,
|
QMap<QString, QDateTime> &deployTimes,
|
||||||
const QVariantMap &map);
|
const QVariantMap &map);
|
||||||
|
|
||||||
mutable QString m_executable;
|
|
||||||
QString m_proFilePath;
|
QString m_proFilePath;
|
||||||
mutable bool m_cachedTargetInformationValid;
|
|
||||||
|
|
||||||
mutable QString m_simulator;
|
mutable QString m_simulator;
|
||||||
mutable QString m_simulatorArgs;
|
mutable QString m_simulatorArgs;
|
||||||
|
@@ -112,7 +112,6 @@ QString pathToId(const QString &path)
|
|||||||
S60DeviceRunConfiguration::S60DeviceRunConfiguration(Target *parent, const QString &proFilePath) :
|
S60DeviceRunConfiguration::S60DeviceRunConfiguration(Target *parent, const QString &proFilePath) :
|
||||||
RunConfiguration(parent, QLatin1String(S60_DEVICE_RC_ID)),
|
RunConfiguration(parent, QLatin1String(S60_DEVICE_RC_ID)),
|
||||||
m_proFilePath(proFilePath),
|
m_proFilePath(proFilePath),
|
||||||
m_cachedTargetInformationValid(false),
|
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
m_serialPortName(QLatin1String("COM5")),
|
m_serialPortName(QLatin1String("COM5")),
|
||||||
#else
|
#else
|
||||||
@@ -126,7 +125,6 @@ S60DeviceRunConfiguration::S60DeviceRunConfiguration(Target *parent, const QStri
|
|||||||
S60DeviceRunConfiguration::S60DeviceRunConfiguration(Target *target, S60DeviceRunConfiguration *source) :
|
S60DeviceRunConfiguration::S60DeviceRunConfiguration(Target *target, S60DeviceRunConfiguration *source) :
|
||||||
RunConfiguration(target, source),
|
RunConfiguration(target, source),
|
||||||
m_proFilePath(source->m_proFilePath),
|
m_proFilePath(source->m_proFilePath),
|
||||||
m_cachedTargetInformationValid(false),
|
|
||||||
m_serialPortName(source->m_serialPortName),
|
m_serialPortName(source->m_serialPortName),
|
||||||
m_signingMode(source->m_signingMode),
|
m_signingMode(source->m_signingMode),
|
||||||
m_customSignaturePath(source->m_customSignaturePath),
|
m_customSignaturePath(source->m_customSignaturePath),
|
||||||
@@ -135,12 +133,6 @@ S60DeviceRunConfiguration::S60DeviceRunConfiguration(Target *target, S60DeviceRu
|
|||||||
ctor();
|
ctor();
|
||||||
}
|
}
|
||||||
|
|
||||||
void S60DeviceRunConfiguration::proFileUpdate(Qt4ProjectManager::Internal::Qt4ProFileNode *pro)
|
|
||||||
{
|
|
||||||
if (m_proFilePath == pro->path())
|
|
||||||
invalidateCachedTargetInformation();
|
|
||||||
}
|
|
||||||
|
|
||||||
void S60DeviceRunConfiguration::ctor()
|
void S60DeviceRunConfiguration::ctor()
|
||||||
{
|
{
|
||||||
if (!m_proFilePath.isEmpty())
|
if (!m_proFilePath.isEmpty())
|
||||||
@@ -148,11 +140,17 @@ void S60DeviceRunConfiguration::ctor()
|
|||||||
else
|
else
|
||||||
setDisplayName(tr("QtS60DeviceRunConfiguration"));
|
setDisplayName(tr("QtS60DeviceRunConfiguration"));
|
||||||
|
|
||||||
connect(target(), SIGNAL(targetInformationChanged()),
|
|
||||||
this, SLOT(invalidateCachedTargetInformation()));
|
|
||||||
|
|
||||||
connect(qt4Target()->qt4Project(), SIGNAL(proFileUpdated(Qt4ProjectManager::Internal::Qt4ProFileNode*)),
|
connect(qt4Target()->qt4Project(), SIGNAL(proFileUpdated(Qt4ProjectManager::Internal::Qt4ProFileNode*)),
|
||||||
this, SLOT(proFileUpdate(Qt4ProjectManager::Internal::Qt4ProFileNode*)));
|
this, SLOT(proFileUpdate(Qt4ProjectManager::Internal::Qt4ProFileNode*)));
|
||||||
|
|
||||||
|
connect(qt4Target()->qt4Project(), SIGNAL(targetInformationChanged(Qt4ProjectManager::Internal::Qt4ProFileNode*)),
|
||||||
|
this, SLOT(proFileUpdate(Qt4ProjectManager::Internal::Qt4ProFileNode*)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void S60DeviceRunConfiguration::proFileUpdate(Qt4ProjectManager::Internal::Qt4ProFileNode *pro)
|
||||||
|
{
|
||||||
|
if (m_proFilePath == pro->path())
|
||||||
|
emit targetInformationChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -246,32 +244,60 @@ void S60DeviceRunConfiguration::setSerialPortName(const QString &name)
|
|||||||
|
|
||||||
QString S60DeviceRunConfiguration::targetName() const
|
QString S60DeviceRunConfiguration::targetName() const
|
||||||
{
|
{
|
||||||
const_cast<S60DeviceRunConfiguration *>(this)->updateTarget();
|
TargetInformation ti = qt4Target()->qt4Project()->rootProjectNode()->targetInformation(m_proFilePath);
|
||||||
return m_targetName;
|
if (!ti.valid)
|
||||||
|
return QString();
|
||||||
|
return ti.target;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline QString fixBaseNameTarget(const QString &in)
|
||||||
|
{
|
||||||
|
if (in == QLatin1String("udeb"))
|
||||||
|
return QLatin1String("debug");
|
||||||
|
if (in == QLatin1String("urel"))
|
||||||
|
return QLatin1String("release");
|
||||||
|
return in;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString S60DeviceRunConfiguration::basePackageFilePath() const
|
QString S60DeviceRunConfiguration::basePackageFilePath() const
|
||||||
{
|
{
|
||||||
const_cast<S60DeviceRunConfiguration *>(this)->updateTarget();
|
TargetInformation ti = qt4Target()->qt4Project()->rootProjectNode()->targetInformation(m_proFilePath);
|
||||||
return m_baseFileName;
|
if (!ti.valid)
|
||||||
|
return QString();
|
||||||
|
QString baseFileName = ti.workingDir + QLatin1Char('/') + ti.target;
|
||||||
|
baseFileName += QLatin1Char('_') + fixBaseNameTarget(symbianPlatform()) + QLatin1Char('_') + symbianTarget();
|
||||||
|
return baseFileName;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString S60DeviceRunConfiguration::symbianPlatform() const
|
QString S60DeviceRunConfiguration::symbianPlatform() const
|
||||||
{
|
{
|
||||||
const_cast<S60DeviceRunConfiguration *>(this)->updateTarget();
|
Qt4BuildConfiguration *qt4bc = qt4Target()->qt4Project()->activeTarget()->activeBuildConfiguration();
|
||||||
return m_platform;
|
switch (qt4bc->toolChainType()) {
|
||||||
|
case ToolChain::GCCE:
|
||||||
|
case ToolChain::GCCE_GNUPOC:
|
||||||
|
return QLatin1String("gcce");
|
||||||
|
case ToolChain::RVCT_ARMV5:
|
||||||
|
return QLatin1String("armv5");
|
||||||
|
default: // including ToolChain::RVCT_ARMV6_GNUPOC:
|
||||||
|
return QLatin1String("armv6");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString S60DeviceRunConfiguration::symbianTarget() const
|
QString S60DeviceRunConfiguration::symbianTarget() const
|
||||||
{
|
{
|
||||||
const_cast<S60DeviceRunConfiguration *>(this)->updateTarget();
|
Qt4BuildConfiguration *qt4bc = qt4Target()->qt4Project()->activeTarget()->activeBuildConfiguration();
|
||||||
return m_target;
|
if (qt4bc->qmakeBuildConfiguration() & QtVersion::DebugBuild)
|
||||||
|
return QString("udeb");
|
||||||
|
else
|
||||||
|
return QString("urel");
|
||||||
}
|
}
|
||||||
|
|
||||||
QString S60DeviceRunConfiguration::packageTemplateFileName() const
|
QString S60DeviceRunConfiguration::packageTemplateFileName() const
|
||||||
{
|
{
|
||||||
const_cast<S60DeviceRunConfiguration *>(this)->updateTarget();
|
TargetInformation ti = qt4Target()->qt4Project()->rootProjectNode()->targetInformation(m_proFilePath);
|
||||||
return m_packageTemplateFileName;
|
if (!ti.valid)
|
||||||
|
return QString();
|
||||||
|
return ti.workingDir + QLatin1Char('/') + ti.target + QLatin1String("_template.pkg");
|
||||||
}
|
}
|
||||||
|
|
||||||
S60DeviceRunConfiguration::SigningMode S60DeviceRunConfiguration::signingMode() const
|
S60DeviceRunConfiguration::SigningMode S60DeviceRunConfiguration::signingMode() const
|
||||||
@@ -373,8 +399,7 @@ QString S60DeviceRunConfiguration::localExecutableFileName() const
|
|||||||
|
|
||||||
QString S60DeviceRunConfiguration::signedPackage() const
|
QString S60DeviceRunConfiguration::signedPackage() const
|
||||||
{
|
{
|
||||||
const_cast<S60DeviceRunConfiguration *>(this)->updateTarget();
|
return QDir::toNativeSeparators(basePackageFilePath() + QLatin1String(".sis"));
|
||||||
return QDir::toNativeSeparators(m_baseFileName + QLatin1String(".sis"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList S60DeviceRunConfiguration::commandLineArguments() const
|
QStringList S60DeviceRunConfiguration::commandLineArguments() const
|
||||||
@@ -387,74 +412,6 @@ void S60DeviceRunConfiguration::setCommandLineArguments(const QStringList &args)
|
|||||||
m_commandLineArguments = args;
|
m_commandLineArguments = args;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fix up target specification for "make sis":
|
|
||||||
// "udeb"-> "debug", "urel" -> "release"
|
|
||||||
static inline QString fixBaseNameTarget(const QString &in)
|
|
||||||
{
|
|
||||||
if (in == QLatin1String("udeb"))
|
|
||||||
return QLatin1String("debug");
|
|
||||||
if (in == QLatin1String("urel"))
|
|
||||||
return QLatin1String("release");
|
|
||||||
return in;
|
|
||||||
}
|
|
||||||
|
|
||||||
void S60DeviceRunConfiguration::updateTarget()
|
|
||||||
{
|
|
||||||
if (m_cachedTargetInformationValid)
|
|
||||||
return;
|
|
||||||
Qt4TargetInformation info = qt4Target()->targetInformation(qt4Target()->activeBuildConfiguration(),
|
|
||||||
m_proFilePath);
|
|
||||||
if (info.error != Qt4TargetInformation::NoError) {
|
|
||||||
if (info.error == Qt4TargetInformation::ProParserError) {
|
|
||||||
Core::ICore::instance()->messageManager()->printToOutputPane(
|
|
||||||
tr("Could not parse %1. The Qt Symbian Device run configuration %2 can not be started.")
|
|
||||||
.arg(m_proFilePath).arg(displayName()));
|
|
||||||
}
|
|
||||||
m_targetName.clear();
|
|
||||||
m_baseFileName.clear();
|
|
||||||
m_packageTemplateFileName.clear();
|
|
||||||
m_platform.clear();
|
|
||||||
m_cachedTargetInformationValid = true;
|
|
||||||
emit targetInformationChanged();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_targetName = info.target;
|
|
||||||
|
|
||||||
m_baseFileName = info.workingDir + QLatin1Char('/') + m_targetName;
|
|
||||||
m_packageTemplateFileName = m_baseFileName + QLatin1String("_template.pkg");
|
|
||||||
|
|
||||||
Qt4BuildConfiguration *qt4bc = qt4Target()->activeBuildConfiguration();
|
|
||||||
switch (qt4bc->toolChainType()) {
|
|
||||||
case ToolChain::GCCE:
|
|
||||||
case ToolChain::GCCE_GNUPOC:
|
|
||||||
m_platform = QLatin1String("gcce");
|
|
||||||
break;
|
|
||||||
case ToolChain::RVCT_ARMV5:
|
|
||||||
case ToolChain::RVCT_ARMV5_GNUPOC:
|
|
||||||
m_platform = QLatin1String("armv5");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
m_platform = QLatin1String("armv6");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (qt4bc->qmakeBuildConfiguration() & QtVersion::DebugBuild)
|
|
||||||
m_target = QLatin1String("udeb");
|
|
||||||
else
|
|
||||||
m_target = QLatin1String("urel");
|
|
||||||
m_baseFileName += QLatin1Char('_') + fixBaseNameTarget(m_target)
|
|
||||||
+ QLatin1Char('-') + m_platform;
|
|
||||||
m_cachedTargetInformationValid = true;
|
|
||||||
emit targetInformationChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
void S60DeviceRunConfiguration::invalidateCachedTargetInformation()
|
|
||||||
{
|
|
||||||
m_cachedTargetInformationValid = false;
|
|
||||||
emit targetInformationChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ======== S60DeviceRunConfigurationFactory
|
// ======== S60DeviceRunConfigurationFactory
|
||||||
|
|
||||||
S60DeviceRunConfigurationFactory::S60DeviceRunConfigurationFactory(QObject *parent) :
|
S60DeviceRunConfigurationFactory::S60DeviceRunConfigurationFactory(QObject *parent) :
|
||||||
|
@@ -110,7 +110,6 @@ signals:
|
|||||||
void serialPortNameChanged();
|
void serialPortNameChanged();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void invalidateCachedTargetInformation();
|
|
||||||
void proFileUpdate(Qt4ProjectManager::Internal::Qt4ProFileNode *pro);
|
void proFileUpdate(Qt4ProjectManager::Internal::Qt4ProFileNode *pro);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -119,16 +118,9 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
ProjectExplorer::ToolChain::ToolChainType toolChainType(ProjectExplorer::BuildConfiguration *configuration) const;
|
ProjectExplorer::ToolChain::ToolChainType toolChainType(ProjectExplorer::BuildConfiguration *configuration) const;
|
||||||
void updateTarget();
|
|
||||||
void ctor();
|
void ctor();
|
||||||
|
|
||||||
QString m_proFilePath;
|
QString m_proFilePath;
|
||||||
QString m_targetName;
|
|
||||||
QString m_platform;
|
|
||||||
QString m_target;
|
|
||||||
QString m_baseFileName;
|
|
||||||
QString m_packageTemplateFileName;
|
|
||||||
bool m_cachedTargetInformationValid;
|
|
||||||
QString m_serialPortName;
|
QString m_serialPortName;
|
||||||
SigningMode m_signingMode;
|
SigningMode m_signingMode;
|
||||||
QString m_customSignaturePath;
|
QString m_customSignaturePath;
|
||||||
|
@@ -76,16 +76,14 @@ QString pathToId(const QString &path)
|
|||||||
|
|
||||||
S60EmulatorRunConfiguration::S60EmulatorRunConfiguration(Target *parent, const QString &proFilePath) :
|
S60EmulatorRunConfiguration::S60EmulatorRunConfiguration(Target *parent, const QString &proFilePath) :
|
||||||
RunConfiguration(parent, QLatin1String(S60_EMULATOR_RC_ID)),
|
RunConfiguration(parent, QLatin1String(S60_EMULATOR_RC_ID)),
|
||||||
m_proFilePath(proFilePath),
|
m_proFilePath(proFilePath)
|
||||||
m_cachedTargetInformationValid(false)
|
|
||||||
{
|
{
|
||||||
ctor();
|
ctor();
|
||||||
}
|
}
|
||||||
|
|
||||||
S60EmulatorRunConfiguration::S60EmulatorRunConfiguration(Target *parent, S60EmulatorRunConfiguration *source) :
|
S60EmulatorRunConfiguration::S60EmulatorRunConfiguration(Target *parent, S60EmulatorRunConfiguration *source) :
|
||||||
RunConfiguration(parent, source),
|
RunConfiguration(parent, source),
|
||||||
m_proFilePath(source->m_proFilePath),
|
m_proFilePath(source->m_proFilePath)
|
||||||
m_cachedTargetInformationValid(false)
|
|
||||||
{
|
{
|
||||||
ctor();
|
ctor();
|
||||||
}
|
}
|
||||||
@@ -97,11 +95,11 @@ void S60EmulatorRunConfiguration::ctor()
|
|||||||
else
|
else
|
||||||
setDisplayName(tr("Qt Symbian Emulator RunConfiguration"));
|
setDisplayName(tr("Qt Symbian Emulator RunConfiguration"));
|
||||||
|
|
||||||
connect(qt4Target(), SIGNAL(targetInformationChanged()),
|
|
||||||
this, SLOT(invalidateCachedTargetInformation()));
|
|
||||||
|
|
||||||
connect(qt4Target()->qt4Project(), SIGNAL(proFileUpdated(Qt4ProjectManager::Internal::Qt4ProFileNode*)),
|
connect(qt4Target()->qt4Project(), SIGNAL(proFileUpdated(Qt4ProjectManager::Internal::Qt4ProFileNode*)),
|
||||||
this, SLOT(proFileUpdate(Qt4ProjectManager::Internal::Qt4ProFileNode*)));
|
this, SLOT(proFileUpdate(Qt4ProjectManager::Internal::Qt4ProFileNode*)));
|
||||||
|
|
||||||
|
connect(qt4Target()->qt4Project(), SIGNAL(targetInformationChanged(Qt4ProjectManager::Internal::Qt4ProFileNode*)),
|
||||||
|
this, SLOT(proFileUpdate(Qt4ProjectManager::Internal::Qt4ProFileNode*)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -112,10 +110,9 @@ S60EmulatorRunConfiguration::~S60EmulatorRunConfiguration()
|
|||||||
void S60EmulatorRunConfiguration::proFileUpdate(Qt4ProjectManager::Internal::Qt4ProFileNode *pro)
|
void S60EmulatorRunConfiguration::proFileUpdate(Qt4ProjectManager::Internal::Qt4ProFileNode *pro)
|
||||||
{
|
{
|
||||||
if (m_proFilePath == pro->path())
|
if (m_proFilePath == pro->path())
|
||||||
invalidateCachedTargetInformation();
|
emit targetInformationChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Qt4Target *S60EmulatorRunConfiguration::qt4Target() const
|
Qt4Target *S60EmulatorRunConfiguration::qt4Target() const
|
||||||
{
|
{
|
||||||
return static_cast<Qt4Target *>(target());
|
return static_cast<Qt4Target *>(target());
|
||||||
@@ -152,28 +149,6 @@ bool S60EmulatorRunConfiguration::fromMap(const QVariantMap &map)
|
|||||||
|
|
||||||
QString S60EmulatorRunConfiguration::executable() const
|
QString S60EmulatorRunConfiguration::executable() const
|
||||||
{
|
{
|
||||||
const_cast<S60EmulatorRunConfiguration *>(this)->updateTarget();
|
|
||||||
return m_executable;
|
|
||||||
}
|
|
||||||
|
|
||||||
void S60EmulatorRunConfiguration::updateTarget()
|
|
||||||
{
|
|
||||||
if (m_cachedTargetInformationValid)
|
|
||||||
return;
|
|
||||||
Qt4TargetInformation info = qt4Target()->targetInformation(qt4Target()->activeBuildConfiguration(),
|
|
||||||
m_proFilePath);
|
|
||||||
if (info.error != Qt4TargetInformation::NoError) {
|
|
||||||
if (info.error == Qt4TargetInformation::ProParserError) {
|
|
||||||
Core::ICore::instance()->messageManager()->printToOutputPane(
|
|
||||||
tr("Could not parse %1. The Qt for Symbian emulator run configuration %2 can not be started.")
|
|
||||||
.arg(m_proFilePath).arg(displayName()));
|
|
||||||
}
|
|
||||||
m_executable.clear();
|
|
||||||
m_cachedTargetInformationValid = true;
|
|
||||||
emit targetInformationChanged();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Qt4BuildConfiguration *qt4bc = qt4Target()->activeBuildConfiguration();
|
Qt4BuildConfiguration *qt4bc = qt4Target()->activeBuildConfiguration();
|
||||||
QtVersion *qtVersion = qt4bc->qtVersion();
|
QtVersion *qtVersion = qt4bc->qtVersion();
|
||||||
QString baseDir = S60Manager::instance()->deviceForQtVersion(qtVersion).epocRoot;
|
QString baseDir = S60Manager::instance()->deviceForQtVersion(qtVersion).epocRoot;
|
||||||
@@ -182,18 +157,13 @@ void S60EmulatorRunConfiguration::updateTarget()
|
|||||||
qmakeBuildConfig = "udeb";
|
qmakeBuildConfig = "udeb";
|
||||||
baseDir += "/epoc32/release/winscw/" + qmakeBuildConfig;
|
baseDir += "/epoc32/release/winscw/" + qmakeBuildConfig;
|
||||||
|
|
||||||
m_executable = QDir::toNativeSeparators(
|
TargetInformation ti = qt4Target()->qt4Project()->rootProjectNode()->targetInformation(m_proFilePath);
|
||||||
QDir::cleanPath(baseDir + QLatin1Char('/') + info.target));
|
if (!ti.valid)
|
||||||
m_executable += QLatin1String(".exe");
|
return QString();
|
||||||
|
QString executable = QDir::toNativeSeparators(QDir::cleanPath(baseDir + QLatin1Char('/') + ti.target));
|
||||||
|
executable += QLatin1String(".exe");
|
||||||
|
|
||||||
m_cachedTargetInformationValid = true;
|
return executable;
|
||||||
emit targetInformationChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
void S60EmulatorRunConfiguration::invalidateCachedTargetInformation()
|
|
||||||
{
|
|
||||||
m_cachedTargetInformationValid = false;
|
|
||||||
emit targetInformationChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ======== S60EmulatorRunConfigurationWidget
|
// ======== S60EmulatorRunConfigurationWidget
|
||||||
|
@@ -75,7 +75,6 @@ signals:
|
|||||||
void targetInformationChanged();
|
void targetInformationChanged();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void invalidateCachedTargetInformation();
|
|
||||||
void proFileUpdate(Qt4ProjectManager::Internal::Qt4ProFileNode *pro);
|
void proFileUpdate(Qt4ProjectManager::Internal::Qt4ProFileNode *pro);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -87,8 +86,6 @@ private:
|
|||||||
void updateTarget();
|
void updateTarget();
|
||||||
|
|
||||||
QString m_proFilePath;
|
QString m_proFilePath;
|
||||||
QString m_executable;
|
|
||||||
bool m_cachedTargetInformationValid;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class S60EmulatorRunConfigurationWidget : public QWidget
|
class S60EmulatorRunConfigurationWidget : public QWidget
|
||||||
|
@@ -277,10 +277,11 @@ void Qt4BuildConfiguration::setShadowBuildAndDirectory(bool shadowBuild, const Q
|
|||||||
{
|
{
|
||||||
if (m_shadowBuild == shadowBuild && m_buildDirectory == buildDirectory)
|
if (m_shadowBuild == shadowBuild && m_buildDirectory == buildDirectory)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_shadowBuild = shadowBuild;
|
m_shadowBuild = shadowBuild;
|
||||||
m_buildDirectory = buildDirectory;
|
m_buildDirectory = buildDirectory;
|
||||||
emit buildDirectoryChanged();
|
emit buildDirectoryChanged();
|
||||||
emit targetInformationChanged();
|
emit proFileEvaluateNeeded(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
ProjectExplorer::ToolChain *Qt4BuildConfiguration::toolChain() const
|
ProjectExplorer::ToolChain *Qt4BuildConfiguration::toolChain() const
|
||||||
@@ -340,8 +341,9 @@ void Qt4BuildConfiguration::setQtVersion(QtVersion *version)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
m_qtVersionId = version->uniqueId();
|
m_qtVersionId = version->uniqueId();
|
||||||
|
|
||||||
|
emit proFileEvaluateNeeded(this);
|
||||||
emit qtVersionChanged();
|
emit qtVersionChanged();
|
||||||
emit targetInformationChanged();
|
|
||||||
emit environmentChanged();
|
emit environmentChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -351,8 +353,9 @@ void Qt4BuildConfiguration::setToolChainType(ProjectExplorer::ToolChain::ToolCha
|
|||||||
m_toolChainType == type)
|
m_toolChainType == type)
|
||||||
return;
|
return;
|
||||||
m_toolChainType = type;
|
m_toolChainType = type;
|
||||||
|
|
||||||
|
emit proFileEvaluateNeeded(this);
|
||||||
emit toolChainTypeChanged();
|
emit toolChainTypeChanged();
|
||||||
emit targetInformationChanged();
|
|
||||||
emit environmentChanged();
|
emit environmentChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -371,8 +374,9 @@ void Qt4BuildConfiguration::setQMakeBuildConfiguration(QtVersion::QmakeBuildConf
|
|||||||
if (m_qmakeBuildConfiguration == config)
|
if (m_qmakeBuildConfiguration == config)
|
||||||
return;
|
return;
|
||||||
m_qmakeBuildConfiguration = config;
|
m_qmakeBuildConfiguration = config;
|
||||||
|
|
||||||
|
emit proFileEvaluateNeeded(this);
|
||||||
emit qmakeBuildConfigurationChanged();
|
emit qmakeBuildConfigurationChanged();
|
||||||
emit targetInformationChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Qt4BuildConfiguration::emitQMakeBuildConfigurationChanged()
|
void Qt4BuildConfiguration::emitQMakeBuildConfigurationChanged()
|
||||||
|
@@ -84,7 +84,8 @@ public:
|
|||||||
QtVersion::QmakeBuildConfigs qmakeBuildConfiguration() const;
|
QtVersion::QmakeBuildConfigs qmakeBuildConfiguration() const;
|
||||||
void setQMakeBuildConfiguration(QtVersion::QmakeBuildConfigs config);
|
void setQMakeBuildConfiguration(QtVersion::QmakeBuildConfigs config);
|
||||||
// used by qmake step to notify that the qmake args have changed
|
// used by qmake step to notify that the qmake args have changed
|
||||||
// not really nice
|
// not really nice, the build configuration should save the arguments
|
||||||
|
// since they are needed for reevaluation
|
||||||
void emitQMakeBuildConfigurationChanged();
|
void emitQMakeBuildConfigurationChanged();
|
||||||
// used by qmake step to notify that the build directory was initialized
|
// used by qmake step to notify that the build directory was initialized
|
||||||
// not really nice
|
// not really nice
|
||||||
@@ -119,9 +120,9 @@ signals:
|
|||||||
/// if those change the qmakebuildconfig
|
/// if those change the qmakebuildconfig
|
||||||
void qmakeBuildConfigurationChanged();
|
void qmakeBuildConfigurationChanged();
|
||||||
|
|
||||||
/// a covenience signal, emitted if either the qtversion, the toolchainType or the qmake build
|
/// emitted if the build configuration changed in a way that
|
||||||
/// configuration changed
|
/// should trigger a reevaluation of all .pro files
|
||||||
void targetInformationChanged();
|
void proFileEvaluateNeeded(Qt4ProjectManager::Internal::Qt4BuildConfiguration *);
|
||||||
|
|
||||||
void buildDirectoryInitialized();
|
void buildDirectoryInitialized();
|
||||||
|
|
||||||
|
@@ -58,12 +58,12 @@
|
|||||||
#include <QtCore/QDir>
|
#include <QtCore/QDir>
|
||||||
#include <QtCore/QFile>
|
#include <QtCore/QFile>
|
||||||
#include <QtCore/QFileInfo>
|
#include <QtCore/QFileInfo>
|
||||||
#include <QtCore/QTimer>
|
|
||||||
|
|
||||||
#include <QtGui/QPainter>
|
#include <QtGui/QPainter>
|
||||||
#include <QtGui/QMainWindow>
|
#include <QtGui/QMainWindow>
|
||||||
#include <QtGui/QMessageBox>
|
#include <QtGui/QMessageBox>
|
||||||
#include <QtGui/QPushButton>
|
#include <QtGui/QPushButton>
|
||||||
|
#include <qtconcurrent/QtConcurrentTools>
|
||||||
|
|
||||||
// Static cached data in struct Qt4NodeStaticData providing information and icons
|
// Static cached data in struct Qt4NodeStaticData providing information and icons
|
||||||
// for file types and the project. Do some magic via qAddPostRoutine()
|
// for file types and the project. Do some magic via qAddPostRoutine()
|
||||||
@@ -453,22 +453,44 @@ struct InternalNode
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void Qt4PriFileNode::update(ProFile *includeFile, ProFileReader *reader)
|
|
||||||
{
|
|
||||||
Q_ASSERT(includeFile);
|
|
||||||
Q_ASSERT(reader);
|
|
||||||
|
|
||||||
|
QStringList Qt4PriFileNode::baseVPaths(ProFileReader *reader, const QString &projectDir)
|
||||||
|
{
|
||||||
|
QStringList result;
|
||||||
|
if (!reader)
|
||||||
|
return result;
|
||||||
|
result += reader->absolutePathValues("VPATH", projectDir);
|
||||||
|
result << projectDir; // QMAKE_ABSOLUTE_SOURCE_PATH
|
||||||
|
result += reader->absolutePathValues("DEPENDPATH", projectDir);
|
||||||
|
result.removeDuplicates();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList Qt4PriFileNode::fullVPaths(const QStringList &baseVPaths, ProFileReader *reader, FileType type, const QString &qmakeVariable, const QString &projectDir)
|
||||||
|
{
|
||||||
|
QStringList vPaths;
|
||||||
|
if (!reader)
|
||||||
|
return vPaths;
|
||||||
|
if (type == ProjectExplorer::SourceType)
|
||||||
|
vPaths = reader->absolutePathValues("VPATH_" + qmakeVariable, projectDir);
|
||||||
|
vPaths += baseVPaths;
|
||||||
|
if (type == ProjectExplorer::HeaderType)
|
||||||
|
vPaths += reader->absolutePathValues("INCLUDEPATH", projectDir);
|
||||||
|
vPaths.removeDuplicates();
|
||||||
|
return vPaths;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Qt4PriFileNode::update(ProFile *includeFileExact, ProFileReader *readerExact, ProFile *includeFileCumlative, ProFileReader *readerCumulative)
|
||||||
|
{
|
||||||
// add project file node
|
// add project file node
|
||||||
if (m_fileNodes.isEmpty())
|
if (m_fileNodes.isEmpty())
|
||||||
addFileNodes(QList<FileNode*>() << new FileNode(m_projectFilePath, ProjectFileType, false), this);
|
addFileNodes(QList<FileNode*>() << new FileNode(m_projectFilePath, ProjectFileType, false), this);
|
||||||
|
|
||||||
const QString &projectDir = m_qt4ProFileNode->m_projectDir;
|
const QString &projectDir = m_qt4ProFileNode->m_projectDir;
|
||||||
|
|
||||||
QStringList baseVPaths;
|
QStringList baseVPathsExact = baseVPaths(readerExact, projectDir);
|
||||||
baseVPaths += reader->absolutePathValues("VPATH", projectDir);
|
QStringList baseVPathsCumulative = baseVPaths(readerCumulative, projectDir);
|
||||||
baseVPaths << projectDir; // QMAKE_ABSOLUTE_SOURCE_PATH
|
|
||||||
baseVPaths += reader->absolutePathValues("DEPENDPATH", projectDir);
|
|
||||||
baseVPaths.removeDuplicates();
|
|
||||||
|
|
||||||
const QVector<Qt4NodeStaticData::FileTypeData> &fileTypes = qt4NodeStaticData()->fileTypeData;
|
const QVector<Qt4NodeStaticData::FileTypeData> &fileTypes = qt4NodeStaticData()->fileTypeData;
|
||||||
|
|
||||||
@@ -481,14 +503,14 @@ void Qt4PriFileNode::update(ProFile *includeFile, ProFileReader *reader)
|
|||||||
|
|
||||||
QStringList newFilePaths;
|
QStringList newFilePaths;
|
||||||
foreach (const QString &qmakeVariable, qmakeVariables) {
|
foreach (const QString &qmakeVariable, qmakeVariables) {
|
||||||
QStringList vPaths;
|
QStringList vPathsExact = fullVPaths(baseVPathsExact, readerExact, type, qmakeVariable, projectDir);
|
||||||
if (type == ProjectExplorer::SourceType)
|
QStringList vPathsCumulative = fullVPaths(baseVPathsCumulative, readerCumulative, type, qmakeVariable, projectDir);
|
||||||
vPaths = reader->absolutePathValues("VPATH_" + qmakeVariable, projectDir);
|
|
||||||
vPaths += baseVPaths;
|
|
||||||
if (type == ProjectExplorer::HeaderType)
|
newFilePaths += readerExact->absoluteFileValues(qmakeVariable, projectDir, vPathsExact, includeFileExact);
|
||||||
vPaths += reader->absolutePathValues("INCLUDEPATH", projectDir);
|
if (readerCumulative)
|
||||||
vPaths.removeDuplicates();
|
newFilePaths += readerCumulative->absoluteFileValues(qmakeVariable, projectDir, vPathsCumulative, includeFileCumlative);
|
||||||
newFilePaths += reader->absoluteFileValues(qmakeVariable, projectDir, vPaths, includeFile);
|
|
||||||
}
|
}
|
||||||
newFilePaths.removeDuplicates();
|
newFilePaths.removeDuplicates();
|
||||||
|
|
||||||
@@ -773,6 +795,16 @@ Qt4ProFileNode *Qt4ProFileNode::findProFileFor(const QString &fileName)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TargetInformation Qt4ProFileNode::targetInformation(const QString &fileName)
|
||||||
|
{
|
||||||
|
TargetInformation result;
|
||||||
|
Qt4ProFileNode *qt4ProFileNode = findProFileFor(fileName);
|
||||||
|
if (!qt4ProFileNode)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
return qt4ProFileNode->targetInformation();
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\class Qt4ProFileNode
|
\class Qt4ProFileNode
|
||||||
Implements abstract ProjectNode class
|
Implements abstract ProjectNode class
|
||||||
@@ -781,20 +813,19 @@ Qt4ProFileNode::Qt4ProFileNode(Qt4Project *project,
|
|||||||
const QString &filePath,
|
const QString &filePath,
|
||||||
QObject *parent)
|
QObject *parent)
|
||||||
: Qt4PriFileNode(project, this, filePath),
|
: Qt4PriFileNode(project, this, filePath),
|
||||||
// own stuff
|
m_projectType(InvalidProject),
|
||||||
m_projectType(InvalidProject)
|
m_readerExact(0),
|
||||||
|
m_readerCumulative(0)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (parent)
|
if (parent)
|
||||||
setParent(parent);
|
setParent(parent);
|
||||||
|
|
||||||
m_updateTimer.setInterval(100);
|
|
||||||
m_updateTimer.setSingleShot(true);
|
|
||||||
|
|
||||||
connect(&m_updateTimer, SIGNAL(timeout()),
|
|
||||||
this, SLOT(update()));
|
|
||||||
|
|
||||||
connect(ProjectExplorer::ProjectExplorerPlugin::instance()->buildManager(), SIGNAL(buildStateChanged(ProjectExplorer::Project*)),
|
connect(ProjectExplorer::ProjectExplorerPlugin::instance()->buildManager(), SIGNAL(buildStateChanged(ProjectExplorer::Project*)),
|
||||||
this, SLOT(buildStateChanged(ProjectExplorer::Project*)));
|
this, SLOT(buildStateChanged(ProjectExplorer::Project*)));
|
||||||
|
|
||||||
|
connect(&m_parseFutureWatcher, SIGNAL(finished()),
|
||||||
|
this, SLOT(applyAsyncEvaluate()));
|
||||||
}
|
}
|
||||||
|
|
||||||
Qt4ProFileNode::~Qt4ProFileNode()
|
Qt4ProFileNode::~Qt4ProFileNode()
|
||||||
@@ -807,6 +838,16 @@ Qt4ProFileNode::~Qt4ProFileNode()
|
|||||||
modelManager->removeEditorSupport(it.value());
|
modelManager->removeEditorSupport(it.value());
|
||||||
delete it.value();
|
delete it.value();
|
||||||
}
|
}
|
||||||
|
m_parseFutureWatcher.waitForFinished();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Qt4ProFileNode::isParent(Qt4ProFileNode *node)
|
||||||
|
{
|
||||||
|
while (node = qobject_cast<Qt4ProFileNode *>(node->parentFolderNode())) {
|
||||||
|
if (node == this)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Qt4ProFileNode::buildStateChanged(ProjectExplorer::Project *project)
|
void Qt4ProFileNode::buildStateChanged(ProjectExplorer::Project *project)
|
||||||
@@ -834,17 +875,97 @@ QStringList Qt4ProFileNode::variableValue(const Qt4Variable var) const
|
|||||||
|
|
||||||
void Qt4ProFileNode::scheduleUpdate()
|
void Qt4ProFileNode::scheduleUpdate()
|
||||||
{
|
{
|
||||||
m_updateTimer.start();
|
m_project->scheduleAsyncUpdate(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Qt4ProFileNode::asyncUpdate()
|
||||||
|
{
|
||||||
|
m_project->incrementPendingEvaluateFutures();
|
||||||
|
setupReader();
|
||||||
|
QFuture<bool> future = QtConcurrent::run(&Qt4ProFileNode::asyncEvaluate, this);
|
||||||
|
m_parseFutureWatcher.setFuture(future);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Qt4ProFileNode::update()
|
void Qt4ProFileNode::update()
|
||||||
{
|
{
|
||||||
ProFileReader *reader = m_project->createProFileReader(this);
|
setupReader();
|
||||||
Q_ASSERT(reader);
|
bool parserError = evaluate();
|
||||||
if (!reader->readProFile(m_projectFilePath)) {
|
applyEvaluate(!parserError, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Qt4ProFileNode::setupReader()
|
||||||
|
{
|
||||||
|
Q_ASSERT(!m_readerExact);
|
||||||
|
Q_ASSERT(!m_readerCumulative);
|
||||||
|
|
||||||
|
m_readerExact = m_project->createProFileReader(this);
|
||||||
|
m_readerExact->setCumulative(false);
|
||||||
|
|
||||||
|
m_readerCumulative = m_project->createProFileReader(this);
|
||||||
|
|
||||||
|
// Find out what flags we pass on to qmake
|
||||||
|
QStringList addedUserConfigArguments;
|
||||||
|
QStringList removedUserConfigArguments;
|
||||||
|
m_project->activeTarget()->activeBuildConfiguration()->getConfigCommandLineArguments(&addedUserConfigArguments, &removedUserConfigArguments);
|
||||||
|
|
||||||
|
m_readerExact->setConfigCommandLineArguments(addedUserConfigArguments, removedUserConfigArguments);
|
||||||
|
m_readerCumulative->setConfigCommandLineArguments(addedUserConfigArguments, removedUserConfigArguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Qt4ProFileNode::evaluate()
|
||||||
|
{
|
||||||
|
bool parserError = false;
|
||||||
|
if (!m_readerExact->readProFile(m_projectFilePath)) {
|
||||||
m_project->proFileParseError(tr("Error while parsing file %1. Giving up.").arg(m_projectFilePath));
|
m_project->proFileParseError(tr("Error while parsing file %1. Giving up.").arg(m_projectFilePath));
|
||||||
m_project->destroyProFileReader(reader);
|
parserError = true;
|
||||||
invalidate();
|
}
|
||||||
|
|
||||||
|
if (!m_readerCumulative->readProFile(m_projectFilePath)) {
|
||||||
|
m_project->proFileParseError(tr("Error while parsing file %1. Giving up.").arg(m_projectFilePath));
|
||||||
|
parserError = true;
|
||||||
|
}
|
||||||
|
return parserError;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Qt4ProFileNode::asyncEvaluate(QFutureInterface<bool> &fi)
|
||||||
|
{
|
||||||
|
bool parserError = evaluate();
|
||||||
|
fi.reportResult(!parserError);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Qt4ProFileNode::applyAsyncEvaluate()
|
||||||
|
{
|
||||||
|
applyEvaluate(m_parseFutureWatcher.result(), true);
|
||||||
|
m_project->decrementPendingEvaluateFutures();
|
||||||
|
}
|
||||||
|
|
||||||
|
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_Subdirs:
|
||||||
|
return SubDirsTemplate;
|
||||||
|
default:
|
||||||
|
return InvalidProject;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Qt4ProFileNode::applyEvaluate(bool parseResult, bool async)
|
||||||
|
{
|
||||||
|
if (!parseResult || m_project->wasEvaluateCanceled()) {
|
||||||
|
if (m_readerExact)
|
||||||
|
m_project->destroyProFileReader(m_readerExact);
|
||||||
|
if (m_readerCumulative)
|
||||||
|
m_project->destroyProFileReader(m_readerCumulative);
|
||||||
|
m_readerExact = m_readerCumulative = 0;
|
||||||
|
if (!parseResult) // Invalidate
|
||||||
|
invalidate();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -852,29 +973,25 @@ void Qt4ProFileNode::update()
|
|||||||
qDebug() << "Qt4ProFileNode - updating files for file " << m_projectFilePath;
|
qDebug() << "Qt4ProFileNode - updating files for file " << m_projectFilePath;
|
||||||
|
|
||||||
Qt4ProjectType projectType = InvalidProject;
|
Qt4ProjectType projectType = InvalidProject;
|
||||||
switch (reader->templateType()) {
|
// Check that both are the same if we have both
|
||||||
case ProFileEvaluator::TT_Unknown:
|
if (m_readerExact->templateType() != m_readerCumulative->templateType()) {
|
||||||
case ProFileEvaluator::TT_Application: {
|
// Now what. The only thing which could be reasonable is that someone
|
||||||
projectType = ApplicationTemplate;
|
// changes between template app and library.
|
||||||
break;
|
// Well, we are conservative here for now.
|
||||||
}
|
// Let's wait until someone complains and look at what they are doing.
|
||||||
case ProFileEvaluator::TT_Library: {
|
m_project->destroyProFileReader(m_readerCumulative);
|
||||||
projectType = LibraryTemplate;
|
m_readerCumulative = 0;
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ProFileEvaluator::TT_Script: {
|
|
||||||
projectType = ScriptTemplate;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ProFileEvaluator::TT_Subdirs:
|
|
||||||
projectType = SubDirsTemplate;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
projectType = proFileTemplateTypeToProjectType(m_readerExact->templateType());
|
||||||
|
|
||||||
if (projectType != m_projectType) {
|
if (projectType != m_projectType) {
|
||||||
Qt4ProjectType oldType = m_projectType;
|
Qt4ProjectType oldType = m_projectType;
|
||||||
// probably all subfiles/projects have changed anyway ...
|
// probably all subfiles/projects have changed anyway ...
|
||||||
clear();
|
clear();
|
||||||
m_projectType = projectType;
|
m_projectType = projectType;
|
||||||
|
// really emit here? or at the end? Noone is connected to this signal at the moment
|
||||||
|
// so we kind of can ignore that question for now
|
||||||
foreach (NodesWatcher *watcher, watchers())
|
foreach (NodesWatcher *watcher, watchers())
|
||||||
if (Qt4NodesWatcher *qt4Watcher = qobject_cast<Qt4NodesWatcher*>(watcher))
|
if (Qt4NodesWatcher *qt4Watcher = qobject_cast<Qt4NodesWatcher*>(watcher))
|
||||||
emit qt4Watcher->projectTypeChanged(this, oldType, projectType);
|
emit qt4Watcher->projectTypeChanged(this, oldType, projectType);
|
||||||
@@ -886,97 +1003,165 @@ void Qt4ProFileNode::update()
|
|||||||
|
|
||||||
QList<ProjectNode*> existingProjectNodes = subProjectNodes();
|
QList<ProjectNode*> existingProjectNodes = subProjectNodes();
|
||||||
|
|
||||||
QList<QString> newProjectFiles;
|
QStringList newProjectFilesExact;
|
||||||
QHash<QString, ProFile*> includeFiles;
|
QHash<QString, ProFile*> includeFilesExact;
|
||||||
ProFile *fileForCurrentProject = 0;
|
ProFile *fileForCurrentProjectExact = 0;
|
||||||
{
|
if (m_projectType == SubDirsTemplate)
|
||||||
if (projectType == SubDirsTemplate) {
|
newProjectFilesExact = subDirsPaths(m_readerExact);
|
||||||
foreach (const QString &subDirProject, subDirsPaths(reader))
|
foreach (ProFile *includeFile, m_readerExact->includeFiles()) {
|
||||||
newProjectFiles << subDirProject;
|
if (includeFile->fileName() == m_projectFilePath) { // this file
|
||||||
|
fileForCurrentProjectExact = includeFile;
|
||||||
|
} else {
|
||||||
|
newProjectFilesExact << includeFile->fileName();
|
||||||
|
includeFilesExact.insert(includeFile->fileName(), includeFile);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
foreach (ProFile *includeFile, reader->includeFiles()) {
|
|
||||||
if (includeFile->fileName() == m_projectFilePath) { // this file
|
QStringList newProjectFilesCumlative;
|
||||||
fileForCurrentProject = includeFile;
|
QHash<QString, ProFile*> includeFilesCumlative;
|
||||||
|
ProFile *fileForCurrentProjectCumlative = 0;
|
||||||
|
if (m_readerCumulative) {
|
||||||
|
if (m_projectType == SubDirsTemplate)
|
||||||
|
newProjectFilesCumlative = subDirsPaths(m_readerCumulative);
|
||||||
|
foreach (ProFile *includeFile, m_readerCumulative->includeFiles()) {
|
||||||
|
if (includeFile->fileName() == m_projectFilePath) {
|
||||||
|
fileForCurrentProjectCumlative = includeFile;
|
||||||
} else {
|
} else {
|
||||||
newProjectFiles << includeFile->fileName();
|
newProjectFilesCumlative << includeFile->fileName();
|
||||||
includeFiles.insert(includeFile->fileName(), includeFile);
|
includeFilesCumlative.insert(includeFile->fileName(), includeFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
qSort(existingProjectNodes.begin(), existingProjectNodes.end(),
|
qSort(existingProjectNodes.begin(), existingProjectNodes.end(),
|
||||||
sortNodesByPath);
|
sortNodesByPath);
|
||||||
qSort(newProjectFiles.begin(), newProjectFiles.end());
|
qSort(newProjectFilesExact);
|
||||||
|
qSort(newProjectFilesCumlative);
|
||||||
|
|
||||||
QList<ProjectNode*> toAdd;
|
QList<ProjectNode*> toAdd;
|
||||||
QList<ProjectNode*> toRemove;
|
QList<ProjectNode*> toRemove;
|
||||||
|
|
||||||
QList<ProjectNode*>::const_iterator existingNodeIter = existingProjectNodes.constBegin();
|
QList<ProjectNode*>::const_iterator existingIt = existingProjectNodes.constBegin();
|
||||||
QList<QString>::const_iterator newProjectFileIter = newProjectFiles.constBegin();
|
QStringList::const_iterator newExactIt = newProjectFilesExact.constBegin();
|
||||||
while (existingNodeIter != existingProjectNodes.constEnd()
|
QStringList::const_iterator newCumlativeIt = newProjectFilesCumlative.constBegin();
|
||||||
&& newProjectFileIter != newProjectFiles.constEnd()) {
|
|
||||||
if ((*existingNodeIter)->path() < *newProjectFileIter) {
|
|
||||||
toRemove << *existingNodeIter;
|
|
||||||
++existingNodeIter;
|
|
||||||
} else if ((*existingNodeIter)->path() > *newProjectFileIter) {
|
|
||||||
if (ProFile *file = includeFiles.value(*newProjectFileIter)) {
|
|
||||||
Qt4PriFileNode *priFileNode
|
|
||||||
= new Qt4PriFileNode(m_project, this,
|
|
||||||
*newProjectFileIter);
|
|
||||||
priFileNode->update(file, reader);
|
|
||||||
toAdd << priFileNode;
|
|
||||||
} else {
|
|
||||||
toAdd << createSubProFileNode(*newProjectFileIter);
|
|
||||||
}
|
|
||||||
++newProjectFileIter;
|
|
||||||
} else { // *existingNodeIter->path() == *newProjectFileIter
|
|
||||||
if (ProFile *file = includeFiles.value(*newProjectFileIter)) {
|
|
||||||
Qt4PriFileNode *priFileNode = static_cast<Qt4PriFileNode*>(*existingNodeIter);
|
|
||||||
priFileNode->update(file, reader);
|
|
||||||
}
|
|
||||||
|
|
||||||
++existingNodeIter;
|
forever {
|
||||||
++newProjectFileIter;
|
bool existingAtEnd = (existingIt == existingProjectNodes.constEnd());
|
||||||
}
|
bool newExactAtEnd = (newExactIt == newProjectFilesExact.constEnd());
|
||||||
}
|
bool newCumlativeAtEnd = (newCumlativeIt == newProjectFilesCumlative.constEnd());
|
||||||
while (existingNodeIter != existingProjectNodes.constEnd()) {
|
|
||||||
toRemove << *existingNodeIter;
|
if (existingAtEnd && newExactAtEnd && newCumlativeAtEnd)
|
||||||
++existingNodeIter;
|
break; // we are done, hurray!
|
||||||
}
|
|
||||||
while (newProjectFileIter != newProjectFiles.constEnd()) {
|
// So this is one giant loop comparing 3 lists at once and sorting the comparision
|
||||||
if (ProFile *file = includeFiles.value(*newProjectFileIter)) {
|
// into mainly 2 buckets: toAdd and toRemove
|
||||||
Qt4PriFileNode *priFileNode
|
// We need to distinguish between nodes that came from exact and cumalative
|
||||||
= new Qt4PriFileNode(m_project, this,
|
// parsing, since the update call is diffrent for them
|
||||||
*newProjectFileIter);
|
// I believe this code to be correct, be careful in changing it
|
||||||
priFileNode->update(file, reader);
|
|
||||||
toAdd << priFileNode;
|
QString nodeToAdd;
|
||||||
|
if (! existingAtEnd
|
||||||
|
&& (newExactAtEnd || (*existingIt)->path() < *newExactIt)
|
||||||
|
&& (newCumlativeAtEnd || (*existingIt)->path() < *newCumlativeIt)) {
|
||||||
|
// Remove case
|
||||||
|
toRemove << *existingIt;
|
||||||
|
++existingIt;
|
||||||
|
} else if(! newExactAtEnd
|
||||||
|
&& (existingAtEnd || *newExactIt < (*existingIt)->path())
|
||||||
|
&& (newCumlativeAtEnd || *newExactIt < *newCumlativeIt)) {
|
||||||
|
// Mark node from exact for adding
|
||||||
|
nodeToAdd = *newExactIt;
|
||||||
|
++newExactIt;
|
||||||
|
} else if (! newCumlativeAtEnd
|
||||||
|
&& (existingAtEnd || *newCumlativeIt < (*existingIt)->path())
|
||||||
|
&& (newExactAtEnd || *newCumlativeIt < *newExactIt)) {
|
||||||
|
// Mark node from cumalative for adding
|
||||||
|
nodeToAdd = *newCumlativeIt;
|
||||||
|
++newCumlativeIt;
|
||||||
|
} else if (!newExactAtEnd
|
||||||
|
&& !newCumlativeAtEnd
|
||||||
|
&& (existingAtEnd || *newExactIt < (*existingIt)->path())
|
||||||
|
&& (existingAtEnd || *newCumlativeIt < (*existingIt)->path())) {
|
||||||
|
// Mark node from both for adding
|
||||||
|
nodeToAdd = *newExactIt;
|
||||||
|
++newExactIt;
|
||||||
|
++newCumlativeIt;
|
||||||
} else {
|
} else {
|
||||||
toAdd << createSubProFileNode(*newProjectFileIter);
|
Q_ASSERT(!newExactAtEnd || !newCumlativeAtEnd);
|
||||||
|
// update case, figure out which case exactly
|
||||||
|
if (newExactAtEnd) {
|
||||||
|
++newCumlativeIt;
|
||||||
|
} else if (newCumlativeAtEnd) {
|
||||||
|
++newExactIt;
|
||||||
|
} else if(*newExactIt < *newCumlativeIt) {
|
||||||
|
++newExactIt;
|
||||||
|
} else if (*newCumlativeIt < *newExactIt) {
|
||||||
|
++newCumlativeIt;
|
||||||
|
} else {
|
||||||
|
++newExactIt;
|
||||||
|
++newCumlativeIt;
|
||||||
|
}
|
||||||
|
// Update existingNodeIte
|
||||||
|
ProFile *fileExact = includeFilesCumlative.value((*existingIt)->path());
|
||||||
|
ProFile *fileCumlative = includeFilesCumlative.value((*existingIt)->path());
|
||||||
|
if (fileExact || fileCumlative) {
|
||||||
|
static_cast<Qt4PriFileNode *>(*existingIt)->update(fileExact, m_readerExact, fileCumlative, m_readerCumulative);
|
||||||
|
} else {
|
||||||
|
// We always parse exactly, because we later when async parsing don't know whether
|
||||||
|
// the .pro file is included in this .pro file
|
||||||
|
// So to compare that later parse with the sync one
|
||||||
|
if (async)
|
||||||
|
static_cast<Qt4ProFileNode *>(*existingIt)->asyncUpdate();
|
||||||
|
else
|
||||||
|
static_cast<Qt4ProFileNode *>(*existingIt)->update();
|
||||||
|
}
|
||||||
|
++existingIt;
|
||||||
|
// newCumalativeIt and newExactIt are already incremented
|
||||||
|
|
||||||
}
|
}
|
||||||
++newProjectFileIter;
|
// If we found something to add do it
|
||||||
}
|
if (!nodeToAdd.isEmpty()) {
|
||||||
|
ProFile *fileExact = includeFilesCumlative.value(nodeToAdd);
|
||||||
|
ProFile *fileCumlative = includeFilesCumlative.value(nodeToAdd);
|
||||||
|
if (fileExact || fileCumlative) {
|
||||||
|
Qt4PriFileNode *qt4PriFileNode = new Qt4PriFileNode(m_project, this, nodeToAdd);
|
||||||
|
qt4PriFileNode->update(fileExact, m_readerExact, fileCumlative, m_readerCumulative);
|
||||||
|
toAdd << qt4PriFileNode;
|
||||||
|
} else {
|
||||||
|
Qt4ProFileNode *qt4ProFileNode = new Qt4ProFileNode(m_project, nodeToAdd);
|
||||||
|
if (async)
|
||||||
|
qt4ProFileNode->asyncUpdate();
|
||||||
|
else
|
||||||
|
qt4ProFileNode->update();
|
||||||
|
toAdd << qt4ProFileNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // for
|
||||||
|
|
||||||
if (!toRemove.isEmpty())
|
if (!toRemove.isEmpty())
|
||||||
removeProjectNodes(toRemove);
|
removeProjectNodes(toRemove);
|
||||||
if (!toAdd.isEmpty())
|
if (!toAdd.isEmpty())
|
||||||
addProjectNodes(toAdd);
|
addProjectNodes(toAdd);
|
||||||
|
|
||||||
Qt4PriFileNode::update(fileForCurrentProject, reader);
|
Qt4PriFileNode::update(fileForCurrentProjectExact, m_readerExact, fileForCurrentProjectCumlative, m_readerCumulative);
|
||||||
|
|
||||||
|
// update TargetInformation
|
||||||
|
m_qt4targetInformation = targetInformation(m_readerExact);
|
||||||
|
|
||||||
// update other variables
|
// update other variables
|
||||||
QHash<Qt4Variable, QStringList> newVarValues;
|
QHash<Qt4Variable, QStringList> newVarValues;
|
||||||
|
|
||||||
newVarValues[DefinesVar] = reader->values(QLatin1String("DEFINES"));
|
newVarValues[DefinesVar] = m_readerExact->values(QLatin1String("DEFINES"));
|
||||||
newVarValues[IncludePathVar] = includePaths(reader);
|
newVarValues[IncludePathVar] = includePaths(m_readerExact);
|
||||||
newVarValues[UiDirVar] = uiDirPaths(reader);
|
newVarValues[UiDirVar] = uiDirPaths(m_readerExact);
|
||||||
newVarValues[MocDirVar] = mocDirPaths(reader);
|
newVarValues[MocDirVar] = mocDirPaths(m_readerExact);
|
||||||
newVarValues[PkgConfigVar] = reader->values(QLatin1String("PKGCONFIG"));
|
newVarValues[PkgConfigVar] = m_readerExact->values(QLatin1String("PKGCONFIG"));
|
||||||
newVarValues[PrecompiledHeaderVar] =
|
newVarValues[PrecompiledHeaderVar] =
|
||||||
reader->absoluteFileValues(QLatin1String("PRECOMPILED_HEADER"),
|
m_readerExact->absoluteFileValues(QLatin1String("PRECOMPILED_HEADER"),
|
||||||
m_projectDir,
|
m_projectDir,
|
||||||
QStringList() << m_projectDir,
|
QStringList() << m_projectDir,
|
||||||
0);
|
0);
|
||||||
|
|
||||||
if (m_varValues != newVarValues) {
|
if (m_varValues != newVarValues) {
|
||||||
m_varValues = newVarValues;
|
m_varValues = newVarValues;
|
||||||
@@ -992,7 +1177,12 @@ void Qt4ProFileNode::update()
|
|||||||
if (Qt4NodesWatcher *qt4Watcher = qobject_cast<Qt4NodesWatcher*>(watcher))
|
if (Qt4NodesWatcher *qt4Watcher = qobject_cast<Qt4NodesWatcher*>(watcher))
|
||||||
emit qt4Watcher->proFileUpdated(this);
|
emit qt4Watcher->proFileUpdated(this);
|
||||||
|
|
||||||
m_project->destroyProFileReader(reader);
|
m_project->destroyProFileReader(m_readerExact);
|
||||||
|
if (m_readerCumulative)
|
||||||
|
m_project->destroyProFileReader(m_readerCumulative);
|
||||||
|
|
||||||
|
m_readerExact = 0;
|
||||||
|
m_readerCumulative = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@@ -1124,13 +1314,6 @@ QStringList Qt4ProFileNode::updateUiFiles()
|
|||||||
return toUpdate;
|
return toUpdate;
|
||||||
}
|
}
|
||||||
|
|
||||||
Qt4ProFileNode *Qt4ProFileNode::createSubProFileNode(const QString &path)
|
|
||||||
{
|
|
||||||
Qt4ProFileNode *subProFileNode = new Qt4ProFileNode(m_project, path);
|
|
||||||
subProFileNode->update();
|
|
||||||
return subProFileNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList Qt4ProFileNode::uiDirPaths(ProFileReader *reader) const
|
QStringList Qt4ProFileNode::uiDirPaths(ProFileReader *reader) const
|
||||||
{
|
{
|
||||||
QStringList candidates = reader->absolutePathValues(QLatin1String("UI_DIR"),
|
QStringList candidates = reader->absolutePathValues(QLatin1String("UI_DIR"),
|
||||||
@@ -1205,6 +1388,73 @@ QStringList Qt4ProFileNode::subDirsPaths(ProFileReader *reader) const
|
|||||||
return subProjectPaths;
|
return subProjectPaths;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TargetInformation Qt4ProFileNode::targetInformation(ProFileReader *reader) const
|
||||||
|
{
|
||||||
|
TargetInformation result;
|
||||||
|
if (!reader)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
const QString baseDir = buildDir();
|
||||||
|
// qDebug() << "base build dir is:"<<baseDir;
|
||||||
|
|
||||||
|
// Working Directory
|
||||||
|
if (reader->contains("DESTDIR")) {
|
||||||
|
//qDebug() << "reader contains destdir:" << reader->value("DESTDIR");
|
||||||
|
result.workingDir = reader->value("DESTDIR");
|
||||||
|
if (QDir::isRelativePath(result.workingDir)) {
|
||||||
|
result.workingDir = baseDir + QLatin1Char('/') + result.workingDir;
|
||||||
|
//qDebug() << "was relative and expanded to" << result.workingDir;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//qDebug() << "reader didn't contain DESTDIR, setting to " << baseDir;
|
||||||
|
result.workingDir = baseDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
result.target = reader->value("TARGET");
|
||||||
|
if (result.target.isEmpty())
|
||||||
|
result.target = QFileInfo(m_projectFilePath).baseName();
|
||||||
|
|
||||||
|
#if defined (Q_OS_MAC)
|
||||||
|
if (reader->values("CONFIG").contains("app_bundle")) {
|
||||||
|
result.workingDir += QLatin1Char('/')
|
||||||
|
+ result.target
|
||||||
|
+ QLatin1String(".app/Contents/MacOS");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
result.workingDir = QDir::cleanPath(result.workingDir);
|
||||||
|
|
||||||
|
QString wd = result.workingDir;
|
||||||
|
if (!reader->contains("DESTDIR")
|
||||||
|
&& reader->values("CONFIG").contains("debug_and_release")
|
||||||
|
&& reader->values("CONFIG").contains("debug_and_release_target")) {
|
||||||
|
// If we don't have a destdir and debug and release is set
|
||||||
|
// then the executable is in a debug/release folder
|
||||||
|
//qDebug() << "reader has debug_and_release_target";
|
||||||
|
|
||||||
|
// Hmm can we find out whether it's debug or release in a saner way?
|
||||||
|
// Theoretically it's in CONFIG
|
||||||
|
QString qmakeBuildConfig = "release";
|
||||||
|
if (m_project->activeTarget()->activeBuildConfiguration()->qmakeBuildConfiguration() & QtVersion::DebugBuild)
|
||||||
|
qmakeBuildConfig = "debug";
|
||||||
|
wd += QLatin1Char('/') + qmakeBuildConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
result.executable = QDir::cleanPath(wd + QLatin1Char('/') + result.target);
|
||||||
|
//qDebug() << "##### updateTarget sets:" << result.workingDir << result.executable;
|
||||||
|
|
||||||
|
#if defined (Q_OS_WIN)
|
||||||
|
result.executable += QLatin1String(".exe");
|
||||||
|
#endif
|
||||||
|
result.valid = true;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
TargetInformation Qt4ProFileNode::targetInformation()
|
||||||
|
{
|
||||||
|
return m_qt4targetInformation;
|
||||||
|
}
|
||||||
|
|
||||||
QString Qt4ProFileNode::buildDir() const
|
QString Qt4ProFileNode::buildDir() const
|
||||||
{
|
{
|
||||||
const QDir srcDirRoot = QFileInfo(m_project->rootProjectNode()->path()).absoluteDir();
|
const QDir srcDirRoot = QFileInfo(m_project->rootProjectNode()->path()).absoluteDir();
|
||||||
|
@@ -36,9 +36,9 @@
|
|||||||
|
|
||||||
#include <QtCore/QHash>
|
#include <QtCore/QHash>
|
||||||
#include <QtCore/QStringList>
|
#include <QtCore/QStringList>
|
||||||
#include <QtCore/QTimer>
|
|
||||||
#include <QtCore/QDateTime>
|
#include <QtCore/QDateTime>
|
||||||
#include <QtCore/QMap>
|
#include <QtCore/QMap>
|
||||||
|
#include <QtCore/QFutureWatcher>
|
||||||
|
|
||||||
// defined in proitems.h
|
// defined in proitems.h
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
@@ -127,7 +127,8 @@ class Qt4PriFileNode : public ProjectExplorer::ProjectNode
|
|||||||
public:
|
public:
|
||||||
Qt4PriFileNode(Qt4Project *project, Qt4ProFileNode* qt4ProFileNode, const QString &filePath);
|
Qt4PriFileNode(Qt4Project *project, Qt4ProFileNode* qt4ProFileNode, const QString &filePath);
|
||||||
|
|
||||||
void update(ProFile *includeFile, ProFileReader *reader);
|
void update(ProFile *includeFileExact, ProFileReader *readerExact, ProFile *includeFileCumlative, ProFileReader *readerCumalative);
|
||||||
|
|
||||||
|
|
||||||
// ProjectNode interface
|
// ProjectNode interface
|
||||||
QList<ProjectAction> supportedActions() const;
|
QList<ProjectAction> supportedActions() const;
|
||||||
@@ -169,6 +170,8 @@ private:
|
|||||||
void save(const QStringList &lines);
|
void save(const QStringList &lines);
|
||||||
bool priFileWritable(const QString &path);
|
bool priFileWritable(const QString &path);
|
||||||
bool saveModifiedEditors();
|
bool saveModifiedEditors();
|
||||||
|
QStringList baseVPaths(ProFileReader *reader, const QString &projectDir);
|
||||||
|
QStringList fullVPaths(const QStringList &baseVPaths, ProFileReader *reader, FileType type, const QString &qmakeVariable, const QString &projectDir);
|
||||||
|
|
||||||
Qt4Project *m_project;
|
Qt4Project *m_project;
|
||||||
Qt4ProFileNode *m_qt4ProFileNode;
|
Qt4ProFileNode *m_qt4ProFileNode;
|
||||||
@@ -185,6 +188,38 @@ private:
|
|||||||
friend struct InternalNode;
|
friend struct InternalNode;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct TargetInformation
|
||||||
|
{
|
||||||
|
bool valid;
|
||||||
|
QString workingDir;
|
||||||
|
QString target;
|
||||||
|
QString executable;
|
||||||
|
bool operator==(const TargetInformation &other) const
|
||||||
|
{
|
||||||
|
return workingDir == other.workingDir
|
||||||
|
&& target == other.target
|
||||||
|
&& executable == other.executable
|
||||||
|
&& valid == valid;
|
||||||
|
}
|
||||||
|
bool operator!=(const TargetInformation &other) const
|
||||||
|
{
|
||||||
|
return !(*this == other);
|
||||||
|
}
|
||||||
|
|
||||||
|
TargetInformation()
|
||||||
|
: valid(false)
|
||||||
|
{}
|
||||||
|
|
||||||
|
TargetInformation(const TargetInformation &other)
|
||||||
|
: valid(other.valid),
|
||||||
|
workingDir(other.workingDir),
|
||||||
|
target(other.target),
|
||||||
|
executable(other.executable)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
// Implements ProjectNode for qt4 pro files
|
// Implements ProjectNode for qt4 pro files
|
||||||
class Qt4ProFileNode : public Qt4PriFileNode
|
class Qt4ProFileNode : public Qt4PriFileNode
|
||||||
{
|
{
|
||||||
@@ -196,6 +231,8 @@ public:
|
|||||||
QObject *parent = 0);
|
QObject *parent = 0);
|
||||||
~Qt4ProFileNode();
|
~Qt4ProFileNode();
|
||||||
|
|
||||||
|
bool isParent(Qt4ProFileNode *node);
|
||||||
|
|
||||||
bool hasBuildTargets() const;
|
bool hasBuildTargets() const;
|
||||||
|
|
||||||
Qt4ProjectType projectType() const;
|
Qt4ProjectType projectType() const;
|
||||||
@@ -211,33 +248,50 @@ public:
|
|||||||
static QString uiHeaderFile(const QString &uiDir, const QString &formFile);
|
static QString uiHeaderFile(const QString &uiDir, const QString &formFile);
|
||||||
|
|
||||||
Qt4ProFileNode *findProFileFor(const QString &string);
|
Qt4ProFileNode *findProFileFor(const QString &string);
|
||||||
|
TargetInformation targetInformation(const QString &fileName);
|
||||||
|
TargetInformation targetInformation();
|
||||||
|
|
||||||
|
void update();
|
||||||
|
void scheduleUpdate();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void scheduleUpdate();
|
void asyncUpdate();
|
||||||
void update();
|
|
||||||
private slots:
|
private slots:
|
||||||
void buildStateChanged(ProjectExplorer::Project*);
|
void buildStateChanged(ProjectExplorer::Project*);
|
||||||
|
void applyAsyncEvaluate();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void setupReader();
|
||||||
|
bool evaluate();
|
||||||
|
void applyEvaluate(bool parseResult, bool async);
|
||||||
|
|
||||||
|
void asyncEvaluate(QFutureInterface<bool> &fi);
|
||||||
|
|
||||||
typedef QHash<Qt4Variable, QStringList> Qt4VariablesHash;
|
typedef QHash<Qt4Variable, QStringList> Qt4VariablesHash;
|
||||||
|
|
||||||
void createUiCodeModelSupport();
|
void createUiCodeModelSupport();
|
||||||
QStringList updateUiFiles();
|
QStringList updateUiFiles();
|
||||||
Qt4ProFileNode *createSubProFileNode(const QString &path);
|
|
||||||
|
|
||||||
QStringList uiDirPaths(ProFileReader *reader) const;
|
QStringList uiDirPaths(ProFileReader *reader) const;
|
||||||
QStringList mocDirPaths(ProFileReader *reader) const;
|
QStringList mocDirPaths(ProFileReader *reader) const;
|
||||||
QStringList includePaths(ProFileReader *reader) const;
|
QStringList includePaths(ProFileReader *reader) const;
|
||||||
QStringList subDirsPaths(ProFileReader *reader) const;
|
QStringList subDirsPaths(ProFileReader *reader) const;
|
||||||
|
TargetInformation targetInformation(ProFileReader *reader) const;
|
||||||
|
|
||||||
void invalidate();
|
void invalidate();
|
||||||
|
|
||||||
Qt4ProjectType m_projectType;
|
Qt4ProjectType m_projectType;
|
||||||
Qt4VariablesHash m_varValues;
|
Qt4VariablesHash m_varValues;
|
||||||
QTimer m_updateTimer;
|
|
||||||
|
|
||||||
QMap<QString, QDateTime> m_uitimestamps;
|
QMap<QString, QDateTime> m_uitimestamps;
|
||||||
|
TargetInformation m_qt4targetInformation;
|
||||||
friend class Qt4NodeHierarchy;
|
friend class Qt4NodeHierarchy;
|
||||||
|
|
||||||
|
// Async stuff
|
||||||
|
QFutureWatcher<bool> m_parseFutureWatcher;
|
||||||
|
ProFileReader *m_readerExact;
|
||||||
|
ProFileReader *m_readerCumulative;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Qt4NodesWatcher : public ProjectExplorer::NodesWatcher
|
class Qt4NodesWatcher : public ProjectExplorer::NodesWatcher
|
||||||
|
@@ -44,6 +44,7 @@
|
|||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
#include <coreplugin/messagemanager.h>
|
#include <coreplugin/messagemanager.h>
|
||||||
#include <coreplugin/coreconstants.h>
|
#include <coreplugin/coreconstants.h>
|
||||||
|
#include <coreplugin/progressmanager/progressmanager.h>
|
||||||
#include <extensionsystem/pluginmanager.h>
|
#include <extensionsystem/pluginmanager.h>
|
||||||
#include <projectexplorer/customexecutablerunconfiguration.h>
|
#include <projectexplorer/customexecutablerunconfiguration.h>
|
||||||
#include <projectexplorer/nodesvisitor.h>
|
#include <projectexplorer/nodesvisitor.h>
|
||||||
@@ -232,21 +233,16 @@ Qt4Project::Qt4Project(Qt4Manager *manager, const QString& fileName) :
|
|||||||
m_fileInfo(new Qt4ProjectFile(this, fileName, this)),
|
m_fileInfo(new Qt4ProjectFile(this, fileName, this)),
|
||||||
m_isApplication(true),
|
m_isApplication(true),
|
||||||
m_projectFiles(new Qt4ProjectFiles),
|
m_projectFiles(new Qt4ProjectFiles),
|
||||||
m_proFileOption(0)
|
m_proFileOption(0),
|
||||||
|
m_asyncUpdateFutureInterface(0),
|
||||||
|
m_pendingEvaluateFuturesCount(0),
|
||||||
|
m_asyncUpdateState(NoState),
|
||||||
|
m_cancelEvaluate(false)
|
||||||
{
|
{
|
||||||
m_updateCodeModelTimer.setSingleShot(true);
|
m_asyncUpdateTimer.setSingleShot(true);
|
||||||
m_updateCodeModelTimer.setInterval(20);
|
m_asyncUpdateTimer.setInterval(3000);
|
||||||
connect(&m_updateCodeModelTimer, SIGNAL(timeout()), this, SLOT(updateCodeModel()));
|
connect(&m_asyncUpdateTimer, SIGNAL(timeout()), this, SLOT(asyncUpdate()));
|
||||||
|
|
||||||
m_rootProjectNode = new Qt4ProFileNode(this, m_fileInfo->fileName(), this);
|
|
||||||
m_rootProjectNode->registerWatcher(m_nodesWatcher);
|
|
||||||
|
|
||||||
connect(this, SIGNAL(addedTarget(ProjectExplorer::Target*)),
|
|
||||||
this, SLOT(onAddedTarget(ProjectExplorer::Target*)));
|
|
||||||
|
|
||||||
// Setup Qt versions supported (== possible targets).
|
|
||||||
connect(QtVersionManager::instance(), SIGNAL(qtVersionsChanged(QList<int>)),
|
|
||||||
this, SLOT(qtVersionsChanged()));
|
|
||||||
setSupportedTargetIds(QtVersionManager::instance()->supportedTargetIds());
|
setSupportedTargetIds(QtVersionManager::instance()->supportedTargetIds());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -295,31 +291,30 @@ bool Qt4Project::fromMap(const QVariantMap &map)
|
|||||||
Q_ASSERT(activeTarget());
|
Q_ASSERT(activeTarget());
|
||||||
Q_ASSERT(activeTarget()->activeBuildConfiguration());
|
Q_ASSERT(activeTarget()->activeBuildConfiguration());
|
||||||
|
|
||||||
|
m_manager->registerProject(this);
|
||||||
|
|
||||||
|
m_rootProjectNode = new Qt4ProFileNode(this, m_fileInfo->fileName(), this);
|
||||||
|
m_rootProjectNode->registerWatcher(m_nodesWatcher);
|
||||||
|
|
||||||
update();
|
update();
|
||||||
updateFileList();
|
updateFileList();
|
||||||
// This might be incorrect, need a full update
|
// This might be incorrect, need a full update
|
||||||
scheduleUpdateCodeModel(rootProjectNode());
|
updateCodeModel();
|
||||||
|
|
||||||
// Now connect
|
checkForNewApplicationProjects();
|
||||||
connect(m_nodesWatcher, SIGNAL(foldersAdded()), this, SLOT(updateFileList()));
|
checkForDeletedApplicationProjects();
|
||||||
connect(m_nodesWatcher, SIGNAL(foldersRemoved()), this, SLOT(updateFileList()));
|
|
||||||
connect(m_nodesWatcher, SIGNAL(filesAdded()), this, SLOT(updateFileList()));
|
|
||||||
connect(m_nodesWatcher, SIGNAL(filesRemoved()), this, SLOT(updateFileList()));
|
|
||||||
connect(m_nodesWatcher, SIGNAL(proFileUpdated(Qt4ProjectManager::Internal::Qt4ProFileNode *)),
|
|
||||||
this, SLOT(scheduleUpdateCodeModel(Qt4ProjectManager::Internal::Qt4ProFileNode *)));
|
|
||||||
|
|
||||||
connect(m_nodesWatcher, SIGNAL(foldersAboutToBeAdded(FolderNode *, const QList<FolderNode*> &)),
|
foreach (Target *t, targets())
|
||||||
this, SLOT(foldersAboutToBeAdded(FolderNode *, const QList<FolderNode*> &)));
|
onAddedTarget(t);
|
||||||
connect(m_nodesWatcher, SIGNAL(foldersAdded()), this, SLOT(checkForNewApplicationProjects()));
|
|
||||||
|
|
||||||
connect(m_nodesWatcher, SIGNAL(foldersRemoved()), this, SLOT(checkForDeletedApplicationProjects()));
|
setSupportedTargetIds(QtVersionManager::instance()->supportedTargetIds());
|
||||||
|
|
||||||
connect(m_nodesWatcher, SIGNAL(projectTypeChanged(Qt4ProjectManager::Internal::Qt4ProFileNode *,
|
// Setup Qt versions supported (== possible targets).
|
||||||
const Qt4ProjectManager::Internal::Qt4ProjectType,
|
connect(this, SIGNAL(addedTarget(ProjectExplorer::Target*)),
|
||||||
const Qt4ProjectManager::Internal::Qt4ProjectType)),
|
this, SLOT(onAddedTarget(ProjectExplorer::Target*)));
|
||||||
this, SLOT(projectTypeChanged(Qt4ProjectManager::Internal::Qt4ProFileNode *,
|
|
||||||
const Qt4ProjectManager::Internal::Qt4ProjectType,
|
connect(QtVersionManager::instance(), SIGNAL(qtVersionsChanged(QList<int>)),
|
||||||
const Qt4ProjectManager::Internal::Qt4ProjectType)));
|
this, SLOT(qtVersionsChanged()));
|
||||||
|
|
||||||
connect(m_nodesWatcher, SIGNAL(proFileUpdated(Qt4ProjectManager::Internal::Qt4ProFileNode *)),
|
connect(m_nodesWatcher, SIGNAL(proFileUpdated(Qt4ProjectManager::Internal::Qt4ProFileNode *)),
|
||||||
this, SIGNAL(proFileUpdated(Qt4ProjectManager::Internal::Qt4ProFileNode *)));
|
this, SIGNAL(proFileUpdated(Qt4ProjectManager::Internal::Qt4ProFileNode *)));
|
||||||
@@ -327,22 +322,6 @@ bool Qt4Project::fromMap(const QVariantMap &map)
|
|||||||
connect(this, SIGNAL(activeTargetChanged(ProjectExplorer::Target*)),
|
connect(this, SIGNAL(activeTargetChanged(ProjectExplorer::Target*)),
|
||||||
this, SLOT(activeTargetWasChanged()));
|
this, SLOT(activeTargetWasChanged()));
|
||||||
|
|
||||||
// Add RunConfigurations to targets:
|
|
||||||
// If we have no application targets then add a empty CustomExecutableRC as
|
|
||||||
// it will ask the user for an executable to run.
|
|
||||||
QStringList pathes = applicationProFilePathes();
|
|
||||||
foreach (Target *t, targets()) {
|
|
||||||
Qt4Target * qt4target = static_cast<Qt4Target*>(t);
|
|
||||||
if (t->runConfigurations().isEmpty()) {
|
|
||||||
if (pathes.isEmpty()) {
|
|
||||||
t->addRunConfiguration(new ProjectExplorer::CustomExecutableRunConfiguration(t));
|
|
||||||
} else {
|
|
||||||
foreach (const QString &path, pathes)
|
|
||||||
qt4target->addRunConfigurationForPath(path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -377,28 +356,46 @@ namespace {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void Qt4Project::scheduleUpdateCodeModel(Qt4ProjectManager::Internal::Qt4ProFileNode *pro)
|
|
||||||
{
|
|
||||||
m_updateCodeModelTimer.start();
|
|
||||||
m_proFilesForCodeModelUpdate.append(pro);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Qt4Project::changeTargetInformation()
|
|
||||||
{
|
|
||||||
Qt4Target *t(qobject_cast<Qt4Target *>(sender()));
|
|
||||||
if (t && t == activeTarget())
|
|
||||||
emit targetInformationChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Qt4Project::onAddedTarget(ProjectExplorer::Target *t)
|
void Qt4Project::onAddedTarget(ProjectExplorer::Target *t)
|
||||||
{
|
{
|
||||||
Q_ASSERT(t);
|
Q_ASSERT(t);
|
||||||
connect(t, SIGNAL(targetInformationChanged()),
|
|
||||||
this, SLOT(changeTargetInformation()));
|
|
||||||
Qt4Target *qt4target = qobject_cast<Qt4Target *>(t);
|
Qt4Target *qt4target = qobject_cast<Qt4Target *>(t);
|
||||||
Q_ASSERT(qt4target);
|
Q_ASSERT(qt4target);
|
||||||
connect(qt4target, SIGNAL(buildDirectoryInitialized()),
|
connect(qt4target, SIGNAL(buildDirectoryInitialized()),
|
||||||
this, SIGNAL(buildDirectoryInitialized()));
|
this, SIGNAL(buildDirectoryInitialized()));
|
||||||
|
connect(qt4target, SIGNAL(proFileEvaluateNeeded(Qt4ProjectManager::Internal::Qt4Target*)),
|
||||||
|
this, SLOT(proFileEvaluateNeeded(Qt4ProjectManager::Internal::Qt4Target*)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Qt4Project::proFileEvaluateNeeded(Qt4ProjectManager::Internal::Qt4Target *target)
|
||||||
|
{
|
||||||
|
if (activeTarget() == target)
|
||||||
|
scheduleAsyncUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// equalFileList compares two file lists ignoring
|
||||||
|
/// <configuration> without generating temporary lists
|
||||||
|
|
||||||
|
bool Qt4Project::equalFileList(const QStringList &a, const QStringList &b)
|
||||||
|
{
|
||||||
|
if (abs(a.length() - b.length()) > 1)
|
||||||
|
return false;
|
||||||
|
QStringList::const_iterator ait = a.constBegin();
|
||||||
|
QStringList::const_iterator bit = b.constBegin();
|
||||||
|
QStringList::const_iterator aend = a.constEnd();
|
||||||
|
QStringList::const_iterator bend = b.constEnd();
|
||||||
|
|
||||||
|
while (ait != aend && bit != bend) {
|
||||||
|
if (*ait == QLatin1String("<configuration>"))
|
||||||
|
++ait;
|
||||||
|
else if (*bit == QLatin1String("<configuration>"))
|
||||||
|
++bit;
|
||||||
|
else if (*ait == *bit)
|
||||||
|
++ait, ++bit;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return (ait == aend && bit == bend);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Qt4Project::updateCodeModel()
|
void Qt4Project::updateCodeModel()
|
||||||
@@ -406,6 +403,8 @@ void Qt4Project::updateCodeModel()
|
|||||||
if (debug)
|
if (debug)
|
||||||
qDebug()<<"Qt4Project::updateCodeModel()";
|
qDebug()<<"Qt4Project::updateCodeModel()";
|
||||||
|
|
||||||
|
// TODO cancel still running indexing
|
||||||
|
|
||||||
if (!activeTarget() || !activeTarget()->activeBuildConfiguration())
|
if (!activeTarget() || !activeTarget()->activeBuildConfiguration())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -424,64 +423,35 @@ void Qt4Project::updateCodeModel()
|
|||||||
QByteArray predefinedMacros;
|
QByteArray predefinedMacros;
|
||||||
|
|
||||||
ToolChain *tc = activeBC->toolChain();
|
ToolChain *tc = activeBC->toolChain();
|
||||||
QList<HeaderPath> allHeaderPaths;
|
|
||||||
if (tc) {
|
if (tc) {
|
||||||
predefinedMacros = tc->predefinedMacros();
|
predefinedMacros = tc->predefinedMacros();
|
||||||
allHeaderPaths = tc->systemHeaderPaths();
|
|
||||||
//qDebug()<<"Predefined Macros";
|
//qDebug()<<"Predefined Macros";
|
||||||
//qDebug()<<tc->predefinedMacros();
|
//qDebug()<<tc->predefinedMacros();
|
||||||
//qDebug()<<"";
|
//qDebug()<<"";
|
||||||
//qDebug()<<"System Header Paths";
|
//qDebug()<<"System Header Paths";
|
||||||
//foreach(const HeaderPath &hp, tc->systemHeaderPaths())
|
//foreach(const HeaderPath &hp, tc->systemHeaderPaths())
|
||||||
// qDebug()<<hp.path();
|
// qDebug()<<hp.path();
|
||||||
}
|
|
||||||
foreach (const HeaderPath &headerPath, allHeaderPaths) {
|
|
||||||
if (headerPath.kind() == HeaderPath::FrameworkHeaderPath)
|
|
||||||
predefinedFrameworkPaths.append(headerPath.path());
|
|
||||||
else
|
|
||||||
predefinedIncludePaths.append(headerPath.path());
|
|
||||||
}
|
|
||||||
|
|
||||||
const QHash<QString, QString> versionInfo = activeBC->qtVersion()->versionInfo();
|
foreach (const HeaderPath &headerPath, tc->systemHeaderPaths()) {
|
||||||
const QString newQtIncludePath = versionInfo.value(QLatin1String("QT_INSTALL_HEADERS"));
|
if (headerPath.kind() == HeaderPath::FrameworkHeaderPath)
|
||||||
|
predefinedFrameworkPaths.append(headerPath.path());
|
||||||
predefinedIncludePaths.append(newQtIncludePath);
|
else
|
||||||
QDir dir(newQtIncludePath);
|
predefinedIncludePaths.append(headerPath.path());
|
||||||
foreach (QFileInfo info, dir.entryInfoList(QDir::Dirs)) {
|
}
|
||||||
const QString path = info.fileName();
|
|
||||||
|
|
||||||
if (path == QLatin1String("Qt"))
|
|
||||||
continue; // skip $QT_INSTALL_HEADERS/Qt. There's no need to include it.
|
|
||||||
else if (path.startsWith(QLatin1String("Qt")) || path == QLatin1String("phonon"))
|
|
||||||
predefinedIncludePaths.append(info.absoluteFilePath());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FindQt4ProFiles findQt4ProFiles;
|
FindQt4ProFiles findQt4ProFiles;
|
||||||
QList<Qt4ProFileNode *> proFiles = findQt4ProFiles(rootProjectNode());
|
QList<Qt4ProFileNode *> proFiles = findQt4ProFiles(rootProjectNode());
|
||||||
QByteArray definedMacros = predefinedMacros;
|
QByteArray allDefinedMacros = predefinedMacros;
|
||||||
QStringList allIncludePaths = predefinedIncludePaths;
|
QStringList allIncludePaths;
|
||||||
QStringList allFrameworkPaths = predefinedFrameworkPaths;
|
QStringList allFrameworkPaths = predefinedFrameworkPaths;
|
||||||
QStringList allPrecompileHeaders;
|
QStringList allPrecompileHeaders;
|
||||||
|
|
||||||
#ifdef Q_OS_MAC
|
|
||||||
const QString newQtLibsPath = versionInfo.value(QLatin1String("QT_INSTALL_LIBS"));
|
|
||||||
allFrameworkPaths.append(newQtLibsPath);
|
|
||||||
// put QtXXX.framework/Headers directories in include path since that qmake's behavior
|
|
||||||
QDir frameworkDir(newQtLibsPath);
|
|
||||||
foreach (QFileInfo info, frameworkDir.entryInfoList(QDir::Dirs)) {
|
|
||||||
if (! info.fileName().startsWith(QLatin1String("Qt")))
|
|
||||||
continue;
|
|
||||||
allIncludePaths.append(info.absoluteFilePath()+"/Headers");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
// Collect per .pro file information
|
// Collect per .pro file information
|
||||||
m_codeModelInfo.clear();
|
m_codeModelInfo.clear();
|
||||||
foreach (Qt4ProFileNode *pro, proFiles) {
|
foreach (Qt4ProFileNode *pro, proFiles) {
|
||||||
Internal::CodeModelInfo info;
|
Internal::CodeModelInfo info;
|
||||||
info.defines = predefinedMacros;
|
info.defines = predefinedMacros;
|
||||||
info.includes = predefinedIncludePaths;
|
|
||||||
info.frameworkPaths = predefinedFrameworkPaths;
|
info.frameworkPaths = predefinedFrameworkPaths;
|
||||||
|
|
||||||
info.precompiledHeader = pro->variableValue(PrecompiledHeaderVar);
|
info.precompiledHeader = pro->variableValue(PrecompiledHeaderVar);
|
||||||
@@ -489,22 +459,23 @@ void Qt4Project::updateCodeModel()
|
|||||||
allPrecompileHeaders.append(info.precompiledHeader);
|
allPrecompileHeaders.append(info.precompiledHeader);
|
||||||
|
|
||||||
// Add custom defines
|
// Add custom defines
|
||||||
|
|
||||||
foreach (const QString &def, pro->variableValue(DefinesVar)) {
|
foreach (const QString &def, pro->variableValue(DefinesVar)) {
|
||||||
definedMacros += "#define ";
|
allDefinedMacros += "#define ";
|
||||||
info.defines += "#define ";
|
info.defines += "#define ";
|
||||||
const int index = def.indexOf(QLatin1Char('='));
|
const int index = def.indexOf(QLatin1Char('='));
|
||||||
if (index == -1) {
|
if (index == -1) {
|
||||||
definedMacros += def.toLatin1();
|
allDefinedMacros += def.toLatin1();
|
||||||
definedMacros += " 1\n";
|
allDefinedMacros += " 1\n";
|
||||||
info.defines += def.toLatin1();
|
info.defines += def.toLatin1();
|
||||||
info.defines += " 1\n";
|
info.defines += " 1\n";
|
||||||
} else {
|
} else {
|
||||||
const QString name = def.left(index);
|
const QString name = def.left(index);
|
||||||
const QString value = def.mid(index + 1);
|
const QString value = def.mid(index + 1);
|
||||||
definedMacros += name.toLatin1();
|
allDefinedMacros += name.toLatin1();
|
||||||
definedMacros += ' ';
|
allDefinedMacros += ' ';
|
||||||
definedMacros += value.toLocal8Bit();
|
allDefinedMacros += value.toLocal8Bit();
|
||||||
definedMacros += '\n';
|
allDefinedMacros += '\n';
|
||||||
info.defines += name.toLatin1();
|
info.defines += name.toLatin1();
|
||||||
info.defines += ' ';
|
info.defines += ' ';
|
||||||
info.defines += value.toLocal8Bit();
|
info.defines += value.toLocal8Bit();
|
||||||
@@ -520,10 +491,7 @@ void Qt4Project::updateCodeModel()
|
|||||||
info.includes.append(includePath);
|
info.includes.append(includePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0 // Experimental PKGCONFIG support
|
||||||
// Disable for now, we need better .pro parsing first
|
|
||||||
// Also the information gathered here isn't used
|
|
||||||
// by the codemodel yet
|
|
||||||
{ // Pkg Config support
|
{ // Pkg Config support
|
||||||
QStringList pkgConfig = pro->variableValue(PkgConfigVar);
|
QStringList pkgConfig = pro->variableValue(PkgConfigVar);
|
||||||
if (!pkgConfig.isEmpty()) {
|
if (!pkgConfig.isEmpty()) {
|
||||||
@@ -541,8 +509,14 @@ void Qt4Project::updateCodeModel()
|
|||||||
|
|
||||||
// Add mkspec directory
|
// Add mkspec directory
|
||||||
info.includes.append(activeBC->qtVersion()->mkspecPath());
|
info.includes.append(activeBC->qtVersion()->mkspecPath());
|
||||||
|
info.includes.append(predefinedIncludePaths);
|
||||||
|
|
||||||
info.frameworkPaths = allFrameworkPaths;
|
// qDebug()<<"Dumping code model information";
|
||||||
|
// qDebug()<<"for .pro file"<< pro->path();
|
||||||
|
// qDebug()<<info.defines;
|
||||||
|
// qDebug()<<info.includes;
|
||||||
|
// qDebug()<<info.frameworkPaths;
|
||||||
|
// qDebug()<<"\n";
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
//Disable for now, we need better .pro file parsing first, and code model
|
//Disable for now, we need better .pro file parsing first, and code model
|
||||||
@@ -564,15 +538,7 @@ void Qt4Project::updateCodeModel()
|
|||||||
// Add mkspec directory
|
// Add mkspec directory
|
||||||
allIncludePaths.append(activeBC->qtVersion()->mkspecPath());
|
allIncludePaths.append(activeBC->qtVersion()->mkspecPath());
|
||||||
|
|
||||||
// Dump things out
|
allIncludePaths.append(predefinedIncludePaths);
|
||||||
// This is debugging output...
|
|
||||||
// qDebug()<<"CodeModel stuff:";
|
|
||||||
// QMap<QString, CodeModelInfo>::const_iterator it, end;
|
|
||||||
// end = m_codeModelInfo.constEnd();
|
|
||||||
// for(it = m_codeModelInfo.constBegin(); it != end; ++it) {
|
|
||||||
// qDebug()<<"File: "<<it.key()<<"\nIncludes:"<<it.value().includes<<"\nDefines"<<it.value().defines<<"\n";
|
|
||||||
// }
|
|
||||||
// qDebug()<<"----------------------------";
|
|
||||||
|
|
||||||
QStringList files;
|
QStringList files;
|
||||||
files += m_projectFiles->files[HeaderType];
|
files += m_projectFiles->files[HeaderType];
|
||||||
@@ -584,37 +550,34 @@ void Qt4Project::updateCodeModel()
|
|||||||
|
|
||||||
//qDebug()<<"Using precompiled header"<<allPrecompileHeaders;
|
//qDebug()<<"Using precompiled header"<<allPrecompileHeaders;
|
||||||
|
|
||||||
if (pinfo.defines == predefinedMacros
|
bool fileList = equalFileList(pinfo.sourceFiles, files);
|
||||||
|
|
||||||
|
if (pinfo.defines == allDefinedMacros
|
||||||
&& pinfo.includePaths == allIncludePaths
|
&& pinfo.includePaths == allIncludePaths
|
||||||
&& pinfo.frameworkPaths == allFrameworkPaths
|
&& pinfo.frameworkPaths == allFrameworkPaths
|
||||||
&& pinfo.sourceFiles == files
|
&& fileList
|
||||||
&& pinfo.precompiledHeaders == allPrecompileHeaders) {
|
&& pinfo.precompiledHeaders == allPrecompileHeaders) {
|
||||||
// Nothing to update...
|
// Nothing to update...
|
||||||
} else {
|
} else {
|
||||||
if (pinfo.defines != predefinedMacros ||
|
pinfo.sourceFiles.clear();
|
||||||
pinfo.includePaths != allIncludePaths ||
|
if (pinfo.defines != allDefinedMacros
|
||||||
pinfo.frameworkPaths != allFrameworkPaths) {
|
|| pinfo.includePaths != allIncludePaths
|
||||||
|
|| pinfo.frameworkPaths != allFrameworkPaths
|
||||||
|
|| pinfo.precompiledHeaders != allPrecompileHeaders)
|
||||||
|
{
|
||||||
pinfo.sourceFiles.append(QLatin1String("<configuration>"));
|
pinfo.sourceFiles.append(QLatin1String("<configuration>"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//pinfo.defines = predefinedMacros;
|
||||||
pinfo.defines = predefinedMacros;
|
pinfo.defines = allDefinedMacros;
|
||||||
// pinfo.defines += definedMacros; // ### FIXME: me
|
|
||||||
pinfo.includePaths = allIncludePaths;
|
pinfo.includePaths = allIncludePaths;
|
||||||
pinfo.frameworkPaths = allFrameworkPaths;
|
pinfo.frameworkPaths = allFrameworkPaths;
|
||||||
pinfo.sourceFiles = files;
|
pinfo.sourceFiles += files;
|
||||||
pinfo.precompiledHeaders = allPrecompileHeaders;
|
pinfo.precompiledHeaders = allPrecompileHeaders;
|
||||||
|
|
||||||
modelmanager->updateProjectInfo(pinfo);
|
modelmanager->updateProjectInfo(pinfo);
|
||||||
modelmanager->updateSourceFiles(pinfo.sourceFiles);
|
modelmanager->updateSourceFiles(pinfo.sourceFiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO use this information
|
|
||||||
// These are the pro files that were actually changed
|
|
||||||
// if the list is empty we are at the initial stage
|
|
||||||
// TODO check that this also works if pro files get added
|
|
||||||
// and removed
|
|
||||||
m_proFilesForCodeModelUpdate.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Qt4Project::qtVersionsChanged()
|
void Qt4Project::qtVersionsChanged()
|
||||||
@@ -654,8 +617,167 @@ QStringList Qt4Project::frameworkPaths(const QString &fileName) const
|
|||||||
// */
|
// */
|
||||||
void Qt4Project::update()
|
void Qt4Project::update()
|
||||||
{
|
{
|
||||||
|
qDebug()<<"Doing sync update";
|
||||||
m_rootProjectNode->update();
|
m_rootProjectNode->update();
|
||||||
//updateCodeModel();
|
qDebug()<<"State is now Base";
|
||||||
|
m_asyncUpdateState = Base;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Qt4Project::scheduleAsyncUpdate(Qt4ProFileNode *node)
|
||||||
|
{
|
||||||
|
qDebug()<<"schduleAsyncUpdate (node)";
|
||||||
|
Q_ASSERT(m_asyncUpdateState != NoState);
|
||||||
|
|
||||||
|
if (m_cancelEvaluate) {
|
||||||
|
qDebug()<<" Already canceling, nothing to do";
|
||||||
|
// A cancel is in progress
|
||||||
|
// That implies that a full update is going to happen afterwards
|
||||||
|
// So we don't need to do anything
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_asyncUpdateState == AsyncFullUpdatePending) {
|
||||||
|
// Just postpone
|
||||||
|
qDebug()<<" full update pending, restarting timer";
|
||||||
|
m_asyncUpdateTimer.start();
|
||||||
|
} else if (m_asyncUpdateState == AsyncPartialUpdatePending
|
||||||
|
|| m_asyncUpdateState == Base) {
|
||||||
|
qDebug()<<" adding node to async update list, setting state to AsyncPartialUpdatePending";
|
||||||
|
// Add the node
|
||||||
|
m_asyncUpdateState = AsyncPartialUpdatePending;
|
||||||
|
|
||||||
|
QList<Internal::Qt4ProFileNode *>::iterator it;
|
||||||
|
bool add = true;
|
||||||
|
qDebug()<<"scheduleAsyncUpdate();"<<m_partialEvaluate.size()<<"nodes";
|
||||||
|
int count = 0;
|
||||||
|
it = m_partialEvaluate.begin();
|
||||||
|
while (it != m_partialEvaluate.end()) {
|
||||||
|
if (*it == node) {
|
||||||
|
add = false;
|
||||||
|
break;
|
||||||
|
} else if (node->isParent(*it)) { // We already have the parent in the list, nothing to do
|
||||||
|
add = false;
|
||||||
|
break;
|
||||||
|
} else if ((*it)->isParent(node)) { // The node is the parent of a child already in the list
|
||||||
|
it = m_partialEvaluate.erase(it);
|
||||||
|
} else {
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (add)
|
||||||
|
m_partialEvaluate.append(node);
|
||||||
|
// and start the timer anew
|
||||||
|
m_asyncUpdateTimer.start();
|
||||||
|
} else if (m_asyncUpdateState == AsyncUpdateInProgress) {
|
||||||
|
// A update is in progress
|
||||||
|
// And this slot only gets called if a file changed on disc
|
||||||
|
// So we'll play it safe and schedule a complete evaluate
|
||||||
|
// This might trigger if due to version control a few files
|
||||||
|
// change a partial update gets in progress and then another
|
||||||
|
// batch of changes come in, which triggers a full update
|
||||||
|
// even if that's not really needed
|
||||||
|
qDebug()<<" Async update in progress, scheduling new one afterwards";
|
||||||
|
scheduleAsyncUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Qt4Project::scheduleAsyncUpdate()
|
||||||
|
{
|
||||||
|
qDebug()<<"scheduleAsyncUpdate";
|
||||||
|
Q_ASSERT(m_asyncUpdateState != NoState);
|
||||||
|
if (m_cancelEvaluate) { // we are in progress of canceling
|
||||||
|
// and will start the evaluation after that
|
||||||
|
qDebug()<<" canceling is in progress, doing nothing";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (m_asyncUpdateState == AsyncUpdateInProgress) {
|
||||||
|
qDebug()<<" update in progress, canceling and setting state to full update pending";
|
||||||
|
m_cancelEvaluate = true;
|
||||||
|
m_asyncUpdateState = AsyncFullUpdatePending;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug()<<" starting timer for full update, setting state to full update pending";
|
||||||
|
m_partialEvaluate.clear();
|
||||||
|
m_asyncUpdateState = AsyncFullUpdatePending;
|
||||||
|
m_asyncUpdateTimer.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Qt4Project::incrementPendingEvaluateFutures()
|
||||||
|
{
|
||||||
|
++m_pendingEvaluateFuturesCount;
|
||||||
|
qDebug()<<"incrementPendingEvaluateFutures to"<<m_pendingEvaluateFuturesCount;
|
||||||
|
|
||||||
|
m_asyncUpdateFutureInterface->setProgressRange(m_asyncUpdateFutureInterface->progressMinimum(),
|
||||||
|
m_asyncUpdateFutureInterface->progressMaximum() + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Qt4Project::decrementPendingEvaluateFutures()
|
||||||
|
{
|
||||||
|
--m_pendingEvaluateFuturesCount;
|
||||||
|
|
||||||
|
qDebug()<<"decrementPendingEvaluateFutures to"<<m_pendingEvaluateFuturesCount;
|
||||||
|
|
||||||
|
m_asyncUpdateFutureInterface->setProgressValue(m_asyncUpdateFutureInterface->progressValue() + 1);
|
||||||
|
if (m_pendingEvaluateFuturesCount == 0) {
|
||||||
|
qDebug()<<" WOHOO, no pending futures, cleaning up";
|
||||||
|
// We are done!
|
||||||
|
qDebug()<<" reporting finished";
|
||||||
|
m_asyncUpdateFutureInterface->reportFinished();
|
||||||
|
delete m_asyncUpdateFutureInterface;
|
||||||
|
m_asyncUpdateFutureInterface = 0;
|
||||||
|
m_cancelEvaluate = false;
|
||||||
|
|
||||||
|
// After beeing done, we need to call:
|
||||||
|
updateFileList();
|
||||||
|
updateCodeModel();
|
||||||
|
checkForNewApplicationProjects();
|
||||||
|
checkForDeletedApplicationProjects();
|
||||||
|
|
||||||
|
// TODO clear the profile cache ?
|
||||||
|
if (m_asyncUpdateState == AsyncFullUpdatePending || m_asyncUpdateState == AsyncPartialUpdatePending) {
|
||||||
|
qDebug()<<" Oh update is pending start the timer";
|
||||||
|
m_asyncUpdateTimer.start();
|
||||||
|
} else {
|
||||||
|
qDebug()<<" Setting state to Base";
|
||||||
|
m_asyncUpdateState = Base;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Qt4Project::wasEvaluateCanceled()
|
||||||
|
{
|
||||||
|
return m_cancelEvaluate;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Qt4Project::asyncUpdate()
|
||||||
|
{
|
||||||
|
qDebug()<<"async update, timer expired, doing now";
|
||||||
|
Q_ASSERT(!m_asyncUpdateFutureInterface);
|
||||||
|
m_asyncUpdateFutureInterface = new QFutureInterface<void>();
|
||||||
|
|
||||||
|
Core::ProgressManager *progressManager = Core::ICore::instance()->progressManager();
|
||||||
|
|
||||||
|
progressManager->addTask(m_asyncUpdateFutureInterface->future(), tr("Evaluate"), Constants::PROFILE_EVALUATE);
|
||||||
|
qDebug()<<" adding task";
|
||||||
|
|
||||||
|
m_asyncUpdateFutureInterface->setProgressRange(0, 0);
|
||||||
|
m_asyncUpdateFutureInterface->reportStarted();
|
||||||
|
|
||||||
|
if (m_asyncUpdateState == AsyncFullUpdatePending) {
|
||||||
|
qDebug()<<" full update, starting with root node";
|
||||||
|
m_rootProjectNode->asyncUpdate();
|
||||||
|
} else {
|
||||||
|
qDebug()<<" partial update,"<<m_partialEvaluate.size()<<"nodes to update";
|
||||||
|
foreach(Qt4ProFileNode *node, m_partialEvaluate)
|
||||||
|
node->asyncUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_partialEvaluate.clear();
|
||||||
|
qDebug()<<" Setting state to AsyncUpdateInProgress";
|
||||||
|
m_asyncUpdateState = AsyncUpdateInProgress;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -666,11 +788,6 @@ bool Qt4Project::isApplication() const
|
|||||||
return m_isApplication;
|
return m_isApplication;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProjectExplorer::ProjectExplorerPlugin *Qt4Project::projectExplorer() const
|
|
||||||
{
|
|
||||||
return m_manager->projectExplorer();
|
|
||||||
}
|
|
||||||
|
|
||||||
ProjectExplorer::IProjectManager *Qt4Project::projectManager() const
|
ProjectExplorer::IProjectManager *Qt4Project::projectManager() const
|
||||||
{
|
{
|
||||||
return m_manager;
|
return m_manager;
|
||||||
@@ -773,6 +890,7 @@ ProFileReader *Qt4Project::createProFileReader(Qt4ProFileNode *qt4ProFileNode)
|
|||||||
m_proFileOption->properties = version->versionInfo();
|
m_proFileOption->properties = version->versionInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ProFileCacheManager::instance()->incRefCount();
|
||||||
m_proFileOption->cache = ProFileCacheManager::instance()->cache();
|
m_proFileOption->cache = ProFileCacheManager::instance()->cache();
|
||||||
}
|
}
|
||||||
++m_proFileOptionRefCnt;
|
++m_proFileOptionRefCnt;
|
||||||
@@ -797,6 +915,7 @@ void Qt4Project::destroyProFileReader(ProFileReader *reader)
|
|||||||
|
|
||||||
delete m_proFileOption;
|
delete m_proFileOption;
|
||||||
m_proFileOption = 0;
|
m_proFileOption = 0;
|
||||||
|
ProFileCacheManager::instance()->decRefCount();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -830,23 +949,12 @@ void Qt4Project::collectApplicationProFiles(QList<Qt4ProFileNode *> &list, Qt4Pr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Qt4Project::foldersAboutToBeAdded(FolderNode *, const QList<FolderNode*> &nodes)
|
|
||||||
{
|
|
||||||
QList<Qt4ProFileNode *> list;
|
|
||||||
foreach (FolderNode *node, nodes) {
|
|
||||||
Qt4ProFileNode *qt4ProFileNode = qobject_cast<Qt4ProFileNode *>(node);
|
|
||||||
if (qt4ProFileNode)
|
|
||||||
collectApplicationProFiles(list, qt4ProFileNode);
|
|
||||||
}
|
|
||||||
m_applicationProFileChange = list;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Qt4Project::checkForNewApplicationProjects()
|
void Qt4Project::checkForNewApplicationProjects()
|
||||||
{
|
{
|
||||||
// Check all new project nodes
|
// Check all new project nodes
|
||||||
// against all runConfigurations in all targets.
|
// against all runConfigurations in all targets.
|
||||||
|
|
||||||
foreach (Qt4ProFileNode *qt4proFile, m_applicationProFileChange) {
|
foreach (Qt4ProFileNode *qt4proFile, applicationProFiles()) {
|
||||||
foreach (Target *target, targets()) {
|
foreach (Target *target, targets()) {
|
||||||
Qt4Target *qt4Target = static_cast<Qt4Target *>(target);
|
Qt4Target *qt4Target = static_cast<Qt4Target *>(target);
|
||||||
bool found = false;
|
bool found = false;
|
||||||
@@ -879,7 +987,6 @@ void Qt4Project::checkForDeletedApplicationProjects()
|
|||||||
if (Qt4RunConfiguration *qt4rc = qobject_cast<Qt4RunConfiguration *>(rc)) {
|
if (Qt4RunConfiguration *qt4rc = qobject_cast<Qt4RunConfiguration *>(rc)) {
|
||||||
if (!paths.contains(qt4rc->proFilePath())) {
|
if (!paths.contains(qt4rc->proFilePath())) {
|
||||||
removeList.append(qt4rc);
|
removeList.append(qt4rc);
|
||||||
// qDebug()<<"Removing runConfiguration for "<<qt4rc->proFilePath();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -922,31 +1029,12 @@ QStringList Qt4Project::applicationProFilePathes(const QString &prepend) const
|
|||||||
return proFiles;
|
return proFiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Qt4Project::projectTypeChanged(Qt4ProFileNode *node, const Qt4ProjectType oldType, const Qt4ProjectType newType)
|
|
||||||
{
|
|
||||||
if (oldType == Internal::ApplicationTemplate
|
|
||||||
|| oldType == Internal::ScriptTemplate) {
|
|
||||||
// check whether we need to delete a Run Configuration
|
|
||||||
checkForDeletedApplicationProjects();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (newType == Internal::ApplicationTemplate
|
|
||||||
|| newType == Internal::ScriptTemplate) {
|
|
||||||
// add a new Run Configuration
|
|
||||||
m_applicationProFileChange.clear();
|
|
||||||
m_applicationProFileChange.append(node);
|
|
||||||
checkForNewApplicationProjects();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Qt4Project::activeTargetWasChanged()
|
void Qt4Project::activeTargetWasChanged()
|
||||||
{
|
{
|
||||||
emit targetInformationChanged();
|
|
||||||
|
|
||||||
if (!activeTarget())
|
if (!activeTarget())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
update();
|
scheduleAsyncUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Qt4Project::hasSubNode(Qt4PriFileNode *root, const QString &path)
|
bool Qt4Project::hasSubNode(Qt4PriFileNode *root, const QString &path)
|
||||||
|
@@ -51,6 +51,7 @@
|
|||||||
#include <QtCore/QMap>
|
#include <QtCore/QMap>
|
||||||
#include <QtGui/QDirModel>
|
#include <QtGui/QDirModel>
|
||||||
#include <QtCore/QFutureInterface>
|
#include <QtCore/QFutureInterface>
|
||||||
|
#include <QtCore/QTimer>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
struct ProFileOption;
|
struct ProFileOption;
|
||||||
@@ -67,6 +68,7 @@ namespace Internal {
|
|||||||
class GCCPreprocessor;
|
class GCCPreprocessor;
|
||||||
struct Qt4ProjectFiles;
|
struct Qt4ProjectFiles;
|
||||||
class Qt4ProjectConfigWidget;
|
class Qt4ProjectConfigWidget;
|
||||||
|
class Qt4Target;
|
||||||
|
|
||||||
class CodeModelInfo
|
class CodeModelInfo
|
||||||
{
|
{
|
||||||
@@ -152,47 +154,54 @@ public:
|
|||||||
virtual QStringList includePaths(const QString &fileName) const;
|
virtual QStringList includePaths(const QString &fileName) const;
|
||||||
virtual QStringList frameworkPaths(const QString &fileName) const;
|
virtual QStringList frameworkPaths(const QString &fileName) const;
|
||||||
|
|
||||||
|
/// \internal
|
||||||
Internal::ProFileReader *createProFileReader(Internal::Qt4ProFileNode *qt4ProFileNode);
|
Internal::ProFileReader *createProFileReader(Internal::Qt4ProFileNode *qt4ProFileNode);
|
||||||
|
/// \internal
|
||||||
void destroyProFileReader(Internal::ProFileReader *reader);
|
void destroyProFileReader(Internal::ProFileReader *reader);
|
||||||
|
|
||||||
|
/// \internal
|
||||||
|
void scheduleAsyncUpdate(Qt4ProjectManager::Internal::Qt4ProFileNode *node);
|
||||||
|
/// \internal
|
||||||
|
void incrementPendingEvaluateFutures();
|
||||||
|
/// \internal
|
||||||
|
void decrementPendingEvaluateFutures();
|
||||||
|
/// \internal
|
||||||
|
bool wasEvaluateCanceled();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
/// convenience signal, emitted if either the active buildconfiguration emits
|
/// emitted after parse
|
||||||
/// targetInformationChanged() or if the active build configuration changes
|
|
||||||
/// (which can happen by the active target changing, too).
|
|
||||||
void targetInformationChanged();
|
|
||||||
void proFileUpdated(Qt4ProjectManager::Internal::Qt4ProFileNode *node);
|
void proFileUpdated(Qt4ProjectManager::Internal::Qt4ProFileNode *node);
|
||||||
void buildDirectoryInitialized();
|
void buildDirectoryInitialized();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void proFileParseError(const QString &errorMessage);
|
void proFileParseError(const QString &errorMessage);
|
||||||
void update();
|
void update();
|
||||||
void changeTargetInformation();
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void updateCodeModel();
|
|
||||||
void scheduleUpdateCodeModel(Qt4ProjectManager::Internal::Qt4ProFileNode *);
|
|
||||||
void qtVersionsChanged();
|
|
||||||
void updateFileList();
|
|
||||||
void onAddedTarget(ProjectExplorer::Target *t);
|
|
||||||
|
|
||||||
void foldersAboutToBeAdded(FolderNode *, const QList<FolderNode*> &);
|
|
||||||
void checkForNewApplicationProjects();
|
|
||||||
void checkForDeletedApplicationProjects();
|
|
||||||
void projectTypeChanged(Qt4ProjectManager::Internal::Qt4ProFileNode *node,
|
|
||||||
const Qt4ProjectManager::Internal::Qt4ProjectType oldType,
|
|
||||||
const Qt4ProjectManager::Internal::Qt4ProjectType newType);
|
|
||||||
void activeTargetWasChanged();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual bool fromMap(const QVariantMap &map);
|
virtual bool fromMap(const QVariantMap &map);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void proFileEvaluateNeeded(Qt4ProjectManager::Internal::Qt4Target *target);
|
||||||
|
|
||||||
|
void asyncUpdate();
|
||||||
|
|
||||||
|
void qtVersionsChanged();
|
||||||
|
void onAddedTarget(ProjectExplorer::Target *t);
|
||||||
|
void activeTargetWasChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void scheduleAsyncUpdate();
|
||||||
|
|
||||||
|
void checkForNewApplicationProjects();
|
||||||
|
void checkForDeletedApplicationProjects();
|
||||||
|
void updateCodeModel();
|
||||||
|
void updateFileList();
|
||||||
|
|
||||||
static void collectApplicationProFiles(QList<Internal::Qt4ProFileNode *> &list, Internal::Qt4ProFileNode *node);
|
static void collectApplicationProFiles(QList<Internal::Qt4ProFileNode *> &list, Internal::Qt4ProFileNode *node);
|
||||||
static void findProFile(const QString& fileName, Internal::Qt4ProFileNode *root, QList<Internal::Qt4ProFileNode *> &list);
|
static void findProFile(const QString& fileName, Internal::Qt4ProFileNode *root, QList<Internal::Qt4ProFileNode *> &list);
|
||||||
static bool hasSubNode(Internal::Qt4PriFileNode *root, const QString &path);
|
static bool hasSubNode(Internal::Qt4PriFileNode *root, const QString &path);
|
||||||
|
|
||||||
QList<Internal::Qt4ProFileNode *> m_applicationProFileChange;
|
static bool equalFileList(const QStringList &a, const QStringList &b);
|
||||||
ProjectExplorer::ProjectExplorerPlugin *projectExplorer() const;
|
|
||||||
|
|
||||||
void addDefaultBuild();
|
void addDefaultBuild();
|
||||||
|
|
||||||
@@ -213,17 +222,22 @@ private:
|
|||||||
// cached lists of all of files
|
// cached lists of all of files
|
||||||
Internal::Qt4ProjectFiles *m_projectFiles;
|
Internal::Qt4ProjectFiles *m_projectFiles;
|
||||||
|
|
||||||
QTimer m_updateCodeModelTimer;
|
// cached data during project rescan
|
||||||
QList<Qt4ProjectManager::Internal::Qt4ProFileNode *> m_proFilesForCodeModelUpdate;
|
ProFileOption *m_proFileOption;
|
||||||
|
int m_proFileOptionRefCnt;
|
||||||
|
|
||||||
|
QTimer m_asyncUpdateTimer;
|
||||||
|
QFutureInterface<void> *m_asyncUpdateFutureInterface;
|
||||||
|
int m_pendingEvaluateFuturesCount;
|
||||||
|
enum AsyncUpdateState { NoState, Base, AsyncFullUpdatePending, AsyncPartialUpdatePending, AsyncUpdateInProgress };
|
||||||
|
AsyncUpdateState m_asyncUpdateState;
|
||||||
|
bool m_cancelEvaluate;
|
||||||
|
QList<Internal::Qt4ProFileNode *> m_partialEvaluate;
|
||||||
|
|
||||||
QMap<QString, Internal::CodeModelInfo> m_codeModelInfo;
|
QMap<QString, Internal::CodeModelInfo> m_codeModelInfo;
|
||||||
|
|
||||||
friend class Qt4ProjectFile;
|
friend class Qt4ProjectFile;
|
||||||
friend class Internal::Qt4ProjectConfigWidget;
|
friend class Internal::Qt4ProjectConfigWidget;
|
||||||
|
|
||||||
// cached data during project rescan
|
|
||||||
ProFileOption *m_proFileOption;
|
|
||||||
int m_proFileOptionRefCnt;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Qt4ProjectManager
|
} // namespace Qt4ProjectManager
|
||||||
|
@@ -161,8 +161,6 @@ void Qt4ProjectConfigWidget::init(ProjectExplorer::BuildConfiguration *bc)
|
|||||||
qDebug() << "Qt4ProjectConfigWidget::init() for"<<bc->displayName();
|
qDebug() << "Qt4ProjectConfigWidget::init() for"<<bc->displayName();
|
||||||
|
|
||||||
if (m_buildConfiguration) {
|
if (m_buildConfiguration) {
|
||||||
disconnect(m_buildConfiguration, SIGNAL(buildDirectoryChanged()),
|
|
||||||
this, SLOT(buildDirectoryChanged()));
|
|
||||||
disconnect(m_buildConfiguration, SIGNAL(qtVersionChanged()),
|
disconnect(m_buildConfiguration, SIGNAL(qtVersionChanged()),
|
||||||
this, SLOT(qtVersionChanged()));
|
this, SLOT(qtVersionChanged()));
|
||||||
disconnect(m_buildConfiguration, SIGNAL(qmakeBuildConfigurationChanged()),
|
disconnect(m_buildConfiguration, SIGNAL(qmakeBuildConfigurationChanged()),
|
||||||
@@ -185,7 +183,7 @@ void Qt4ProjectConfigWidget::init(ProjectExplorer::BuildConfiguration *bc)
|
|||||||
m_ui->shadowBuildCheckBox->setChecked(shadowBuild);
|
m_ui->shadowBuildCheckBox->setChecked(shadowBuild);
|
||||||
m_ui->shadowBuildDirEdit->setEnabled(shadowBuild);
|
m_ui->shadowBuildDirEdit->setEnabled(shadowBuild);
|
||||||
m_browseButton->setEnabled(shadowBuild);
|
m_browseButton->setEnabled(shadowBuild);
|
||||||
m_ui->shadowBuildDirEdit->setPath(m_buildConfiguration->buildDirectory());
|
m_ui->shadowBuildDirEdit->setPath(m_buildConfiguration->shadowBuildDirectory());
|
||||||
updateImportLabel();
|
updateImportLabel();
|
||||||
updateToolChainCombo();
|
updateToolChainCombo();
|
||||||
updateDetails();
|
updateDetails();
|
||||||
|
@@ -203,7 +203,6 @@ ProjectExplorer::Project* Qt4Manager::openProject(const QString &fileName)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Qt4Project *pro = new Qt4Project(this, canonicalFilePath);
|
Qt4Project *pro = new Qt4Project(this, canonicalFilePath);
|
||||||
registerProject(pro);
|
|
||||||
return pro;
|
return pro;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -85,6 +85,9 @@ const char * const QT_APP_WIZARD_CATEGORY = "C.QtApplicationProjects";
|
|||||||
const char * const QT_APP_WIZARD_TR_SCOPE = "Qt4ProjectManager";
|
const char * const QT_APP_WIZARD_TR_SCOPE = "Qt4ProjectManager";
|
||||||
const char * const QT_APP_WIZARD_TR_CATEGORY = QT_TRANSLATE_NOOP("Qt4ProjectManager", "Qt Application Project");
|
const char * const QT_APP_WIZARD_TR_CATEGORY = QT_TRANSLATE_NOOP("Qt4ProjectManager", "Qt Application Project");
|
||||||
|
|
||||||
|
// Tasks
|
||||||
|
const char * const PROFILE_EVALUATE = "Qt4ProjectManager.ProFileEvaluate";
|
||||||
|
|
||||||
} // namespace Constants
|
} // namespace Constants
|
||||||
} // namespace Qt4ProjectManager
|
} // namespace Qt4ProjectManager
|
||||||
|
|
||||||
|
@@ -95,7 +95,6 @@ Qt4RunConfiguration::Qt4RunConfiguration(Qt4Target *parent, const QString &proFi
|
|||||||
m_proFilePath(proFilePath),
|
m_proFilePath(proFilePath),
|
||||||
m_runMode(Gui),
|
m_runMode(Gui),
|
||||||
m_userSetName(false),
|
m_userSetName(false),
|
||||||
m_cachedTargetInformationValid(false),
|
|
||||||
m_isUsingDyldImageSuffix(false),
|
m_isUsingDyldImageSuffix(false),
|
||||||
m_userSetWokingDirectory(false),
|
m_userSetWokingDirectory(false),
|
||||||
m_baseEnvironmentBase(Qt4RunConfiguration::BuildEnvironmentBase)
|
m_baseEnvironmentBase(Qt4RunConfiguration::BuildEnvironmentBase)
|
||||||
@@ -109,7 +108,6 @@ Qt4RunConfiguration::Qt4RunConfiguration(Qt4Target *parent, Qt4RunConfiguration
|
|||||||
m_proFilePath(source->m_proFilePath),
|
m_proFilePath(source->m_proFilePath),
|
||||||
m_runMode(source->m_runMode),
|
m_runMode(source->m_runMode),
|
||||||
m_userSetName(source->m_userSetName),
|
m_userSetName(source->m_userSetName),
|
||||||
m_cachedTargetInformationValid(false),
|
|
||||||
m_isUsingDyldImageSuffix(source->m_isUsingDyldImageSuffix),
|
m_isUsingDyldImageSuffix(source->m_isUsingDyldImageSuffix),
|
||||||
m_userSetWokingDirectory(source->m_userSetWokingDirectory),
|
m_userSetWokingDirectory(source->m_userSetWokingDirectory),
|
||||||
m_userWorkingDirectory(source->m_userWorkingDirectory),
|
m_userWorkingDirectory(source->m_userWorkingDirectory),
|
||||||
@@ -156,15 +154,12 @@ bool Qt4RunConfiguration::isEnabled(ProjectExplorer::BuildConfiguration *configu
|
|||||||
void Qt4RunConfiguration::proFileUpdate(Qt4ProjectManager::Internal::Qt4ProFileNode *pro)
|
void Qt4RunConfiguration::proFileUpdate(Qt4ProjectManager::Internal::Qt4ProFileNode *pro)
|
||||||
{
|
{
|
||||||
if (m_proFilePath == pro->path())
|
if (m_proFilePath == pro->path())
|
||||||
invalidateCachedTargetInformation();
|
emit effectiveTargetInformationChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Qt4RunConfiguration::ctor()
|
void Qt4RunConfiguration::ctor()
|
||||||
{
|
{
|
||||||
setDefaultDisplayName();
|
setDefaultDisplayName();
|
||||||
connect(qt4Target(), SIGNAL(targetInformationChanged()),
|
|
||||||
this, SLOT(invalidateCachedTargetInformation()));
|
|
||||||
|
|
||||||
connect(qt4Target(), SIGNAL(environmentChanged()),
|
connect(qt4Target(), SIGNAL(environmentChanged()),
|
||||||
this, SIGNAL(baseEnvironmentChanged()));
|
this, SIGNAL(baseEnvironmentChanged()));
|
||||||
|
|
||||||
@@ -475,7 +470,6 @@ bool Qt4RunConfiguration::fromMap(const QVariantMap &map)
|
|||||||
m_userWorkingDirectory = map.value(QLatin1String(USER_WORKING_DIRECTORY_KEY)).toString();
|
m_userWorkingDirectory = map.value(QLatin1String(USER_WORKING_DIRECTORY_KEY)).toString();
|
||||||
|
|
||||||
if (!m_proFilePath.isEmpty()) {
|
if (!m_proFilePath.isEmpty()) {
|
||||||
m_cachedTargetInformationValid = false;
|
|
||||||
if (!m_userSetName)
|
if (!m_userSetName)
|
||||||
setDefaultDisplayName();
|
setDefaultDisplayName();
|
||||||
}
|
}
|
||||||
@@ -487,8 +481,11 @@ bool Qt4RunConfiguration::fromMap(const QVariantMap &map)
|
|||||||
|
|
||||||
QString Qt4RunConfiguration::executable() const
|
QString Qt4RunConfiguration::executable() const
|
||||||
{
|
{
|
||||||
const_cast<Qt4RunConfiguration *>(this)->updateTarget();
|
Qt4Project *pro = qt4Target()->qt4Project();
|
||||||
return m_executable;
|
TargetInformation ti = pro->rootProjectNode()->targetInformation(m_proFilePath);
|
||||||
|
if (!ti.valid)
|
||||||
|
return QString();
|
||||||
|
return ti.executable;
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalApplicationRunConfiguration::RunMode Qt4RunConfiguration::runMode() const
|
LocalApplicationRunConfiguration::RunMode Qt4RunConfiguration::runMode() const
|
||||||
@@ -514,8 +511,11 @@ QString Qt4RunConfiguration::workingDirectory() const
|
|||||||
return m_userWorkingDirectory;
|
return m_userWorkingDirectory;
|
||||||
|
|
||||||
// else what the pro file reader tells us
|
// else what the pro file reader tells us
|
||||||
const_cast<Qt4RunConfiguration *>(this)->updateTarget();
|
Qt4Project *pro = qt4Target()->qt4Project();
|
||||||
return m_workingDir;
|
TargetInformation ti = pro->rootProjectNode()->targetInformation(m_proFilePath);
|
||||||
|
if(!ti.valid)
|
||||||
|
return QString();
|
||||||
|
return ti.workingDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList Qt4RunConfiguration::commandLineArguments() const
|
QStringList Qt4RunConfiguration::commandLineArguments() const
|
||||||
@@ -611,38 +611,6 @@ QString Qt4RunConfiguration::proFilePath() const
|
|||||||
return m_proFilePath;
|
return m_proFilePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Qt4RunConfiguration::updateTarget()
|
|
||||||
{
|
|
||||||
if (m_cachedTargetInformationValid)
|
|
||||||
return;
|
|
||||||
Qt4TargetInformation info = qt4Target()->targetInformation(qt4Target()->activeBuildConfiguration(),
|
|
||||||
m_proFilePath);
|
|
||||||
if (info.error != Qt4TargetInformation::NoError) {
|
|
||||||
if (info.error == Qt4TargetInformation::ProParserError) {
|
|
||||||
Core::ICore::instance()->messageManager()->printToOutputPane(
|
|
||||||
tr("Could not parse %1. The Qt4 run configuration %2 can not be started.")
|
|
||||||
.arg(m_proFilePath).arg(displayName()));
|
|
||||||
}
|
|
||||||
m_workingDir.clear();
|
|
||||||
m_executable.clear();
|
|
||||||
m_cachedTargetInformationValid = true;
|
|
||||||
emit effectiveTargetInformationChanged();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
m_workingDir = info.workingDir;
|
|
||||||
m_executable = info.executable;
|
|
||||||
|
|
||||||
m_cachedTargetInformationValid = true;
|
|
||||||
|
|
||||||
emit effectiveTargetInformationChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Qt4RunConfiguration::invalidateCachedTargetInformation()
|
|
||||||
{
|
|
||||||
m_cachedTargetInformationValid = false;
|
|
||||||
emit effectiveTargetInformationChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString Qt4RunConfiguration::dumperLibrary() const
|
QString Qt4RunConfiguration::dumperLibrary() const
|
||||||
{
|
{
|
||||||
QtVersion *version = qt4Target()->activeBuildConfiguration()->qtVersion();
|
QtVersion *version = qt4Target()->activeBuildConfiguration()->qtVersion();
|
||||||
|
@@ -91,12 +91,7 @@ public:
|
|||||||
QVariantMap toMap() const;
|
QVariantMap toMap() const;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
// This function is called if:
|
void targetInformationChanged();
|
||||||
// X the pro file changes
|
|
||||||
// X the active buildconfiguration changes
|
|
||||||
// X the qmake parameters change
|
|
||||||
// X the build directory changes
|
|
||||||
void invalidateCachedTargetInformation();
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void commandLineArgumentsChanged(const QString&);
|
void commandLineArgumentsChanged(const QString&);
|
||||||
@@ -140,11 +135,8 @@ private:
|
|||||||
QString m_proFilePath; // Full path to the Application Pro File
|
QString m_proFilePath; // Full path to the Application Pro File
|
||||||
|
|
||||||
// Cached startup sub project information
|
// Cached startup sub project information
|
||||||
QString m_executable;
|
|
||||||
QString m_workingDir;
|
|
||||||
ProjectExplorer::LocalApplicationRunConfiguration::RunMode m_runMode;
|
ProjectExplorer::LocalApplicationRunConfiguration::RunMode m_runMode;
|
||||||
bool m_userSetName;
|
bool m_userSetName;
|
||||||
bool m_cachedTargetInformationValid;
|
|
||||||
bool m_isUsingDyldImageSuffix;
|
bool m_isUsingDyldImageSuffix;
|
||||||
bool m_userSetWokingDirectory;
|
bool m_userSetWokingDirectory;
|
||||||
QString m_userWorkingDirectory;
|
QString m_userWorkingDirectory;
|
||||||
|
@@ -202,8 +202,9 @@ Qt4Target::Qt4Target(Qt4Project *parent, const QString &id) :
|
|||||||
{
|
{
|
||||||
connect(project(), SIGNAL(supportedTargetIdsChanged()),
|
connect(project(), SIGNAL(supportedTargetIdsChanged()),
|
||||||
this, SLOT(updateQtVersion()));
|
this, SLOT(updateQtVersion()));
|
||||||
|
|
||||||
connect(this, SIGNAL(activeBuildConfigurationChanged(ProjectExplorer::BuildConfiguration*)),
|
connect(this, SIGNAL(activeBuildConfigurationChanged(ProjectExplorer::BuildConfiguration*)),
|
||||||
this, SIGNAL(targetInformationChanged()));
|
this, SLOT(emitProFileEvaluateNeeded()));
|
||||||
connect(this, SIGNAL(activeBuildConfigurationChanged(ProjectExplorer::BuildConfiguration*)),
|
connect(this, SIGNAL(activeBuildConfigurationChanged(ProjectExplorer::BuildConfiguration*)),
|
||||||
this, SIGNAL(environmentChanged()));
|
this, SIGNAL(environmentChanged()));
|
||||||
connect(this, SIGNAL(addedRunConfiguration(ProjectExplorer::RunConfiguration*)),
|
connect(this, SIGNAL(addedRunConfiguration(ProjectExplorer::RunConfiguration*)),
|
||||||
@@ -231,89 +232,6 @@ Qt4Project *Qt4Target::qt4Project() const
|
|||||||
return static_cast<Qt4Project *>(project());
|
return static_cast<Qt4Project *>(project());
|
||||||
}
|
}
|
||||||
|
|
||||||
Qt4TargetInformation Qt4Target::targetInformation(Qt4BuildConfiguration *buildConfiguration,
|
|
||||||
const QString &proFilePath)
|
|
||||||
{
|
|
||||||
Qt4TargetInformation info;
|
|
||||||
Qt4ProFileNode *proFileNode = qt4Project()->rootProjectNode()->findProFileFor(proFilePath);
|
|
||||||
if (!proFileNode) {
|
|
||||||
info.error = Qt4TargetInformation::InvalidProjectError;
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
ProFileReader *reader = qt4Project()->createProFileReader(proFileNode);
|
|
||||||
reader->setCumulative(false);
|
|
||||||
|
|
||||||
// Find out what flags we pass on to qmake
|
|
||||||
QStringList addedUserConfigArguments;
|
|
||||||
QStringList removedUserConfigArguments;
|
|
||||||
buildConfiguration->getConfigCommandLineArguments(&addedUserConfigArguments, &removedUserConfigArguments);
|
|
||||||
reader->setConfigCommandLineArguments(addedUserConfigArguments, removedUserConfigArguments);
|
|
||||||
|
|
||||||
if (!reader->readProFile(proFilePath)) {
|
|
||||||
qt4Project()->destroyProFileReader(reader);
|
|
||||||
info.error = Qt4TargetInformation::ProParserError;
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extract data
|
|
||||||
const QDir baseProjectDirectory = QFileInfo(project()->file()->fileName()).absoluteDir();
|
|
||||||
const QString relSubDir = baseProjectDirectory.relativeFilePath(QFileInfo(proFilePath).path());
|
|
||||||
const QDir baseBuildDirectory = buildConfiguration->buildDirectory();
|
|
||||||
const QString baseDir = baseBuildDirectory.absoluteFilePath(relSubDir);
|
|
||||||
//qDebug()<<relSubDir<<baseDir;
|
|
||||||
|
|
||||||
// Working Directory
|
|
||||||
if (reader->contains("DESTDIR")) {
|
|
||||||
//qDebug() << "reader contains destdir:" << reader->value("DESTDIR");
|
|
||||||
info.workingDir = reader->value("DESTDIR");
|
|
||||||
if (QDir::isRelativePath(info.workingDir)) {
|
|
||||||
info.workingDir = baseDir + QLatin1Char('/') + info.workingDir;
|
|
||||||
//qDebug() << "was relative and expanded to" << info.workingDir;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//qDebug() << "reader didn't contain DESTDIR, setting to " << baseDir;
|
|
||||||
info.workingDir = baseDir;
|
|
||||||
}
|
|
||||||
|
|
||||||
info.target = reader->value("TARGET");
|
|
||||||
if (info.target.isEmpty())
|
|
||||||
info.target = QFileInfo(proFilePath).baseName();
|
|
||||||
|
|
||||||
#if defined (Q_OS_MAC)
|
|
||||||
if (reader->values("CONFIG").contains("app_bundle")) {
|
|
||||||
info.workingDir += QLatin1Char('/')
|
|
||||||
+ info.target
|
|
||||||
+ QLatin1String(".app/Contents/MacOS");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
info.workingDir = QDir::cleanPath(info.workingDir);
|
|
||||||
|
|
||||||
QString wd = info.workingDir;
|
|
||||||
if (!reader->contains("DESTDIR")
|
|
||||||
&& reader->values("CONFIG").contains("debug_and_release")
|
|
||||||
&& reader->values("CONFIG").contains("debug_and_release_target")) {
|
|
||||||
// If we don't have a destdir and debug and release is set
|
|
||||||
// then the executable is in a debug/release folder
|
|
||||||
//qDebug() << "reader has debug_and_release_target";
|
|
||||||
QString qmakeBuildConfig = "release";
|
|
||||||
if (buildConfiguration->qmakeBuildConfiguration() & QtVersion::DebugBuild)
|
|
||||||
qmakeBuildConfig = "debug";
|
|
||||||
wd += QLatin1Char('/') + qmakeBuildConfig;
|
|
||||||
}
|
|
||||||
|
|
||||||
info.executable = QDir::cleanPath(wd + QLatin1Char('/') + info.target);
|
|
||||||
//qDebug() << "##### updateTarget sets:" << info.workingDir << info.executable;
|
|
||||||
|
|
||||||
#if defined (Q_OS_WIN)
|
|
||||||
info.executable += QLatin1String(".exe");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
qt4Project()->destroyProFileReader(reader);
|
|
||||||
info.error = Qt4TargetInformation::NoError;
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
|
|
||||||
Qt4BuildConfiguration *Qt4Target::addQt4BuildConfiguration(QString displayName, QtVersion *qtversion,
|
Qt4BuildConfiguration *Qt4Target::addQt4BuildConfiguration(QString displayName, QtVersion *qtversion,
|
||||||
QtVersion::QmakeBuildConfigs qmakeBuildConfiguration,
|
QtVersion::QmakeBuildConfigs qmakeBuildConfiguration,
|
||||||
QStringList additionalArguments)
|
QStringList additionalArguments)
|
||||||
@@ -429,8 +347,8 @@ void Qt4Target::onAddedBuildConfiguration(ProjectExplorer::BuildConfiguration *b
|
|||||||
Q_ASSERT(qt4bc);
|
Q_ASSERT(qt4bc);
|
||||||
connect(qt4bc, SIGNAL(buildDirectoryInitialized()),
|
connect(qt4bc, SIGNAL(buildDirectoryInitialized()),
|
||||||
this, SIGNAL(buildDirectoryInitialized()));
|
this, SIGNAL(buildDirectoryInitialized()));
|
||||||
connect(qt4bc, SIGNAL(targetInformationChanged()),
|
connect(qt4bc, SIGNAL(proFileEvaluateNeeded(Qt4ProjectManager::Internal::Qt4BuildConfiguration *)),
|
||||||
this, SLOT(changeTargetInformation()));
|
this, SLOT(onProFileEvaluateNeeded(Qt4ProjectManager::Internal::Qt4BuildConfiguration *)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Qt4Target::slotUpdateDeviceInformation()
|
void Qt4Target::slotUpdateDeviceInformation()
|
||||||
@@ -441,11 +359,15 @@ void Qt4Target::slotUpdateDeviceInformation()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Qt4Target::changeTargetInformation()
|
void Qt4Target::onProFileEvaluateNeeded(Qt4ProjectManager::Internal::Qt4BuildConfiguration *bc)
|
||||||
{
|
{
|
||||||
Qt4BuildConfiguration * bc = qobject_cast<Qt4BuildConfiguration *>(sender());
|
|
||||||
if (bc && bc == activeBuildConfiguration())
|
if (bc && bc == activeBuildConfiguration())
|
||||||
emit targetInformationChanged();
|
emit proFileEvaluateNeeded(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Qt4Target::emitProFileEvaluateNeeded()
|
||||||
|
{
|
||||||
|
emit proFileEvaluateNeeded(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Qt4Target::updateToolTipAndIcon()
|
void Qt4Target::updateToolTipAndIcon()
|
||||||
|
@@ -53,20 +53,6 @@ class ProFileReader;
|
|||||||
class Qt4ProFileNode;
|
class Qt4ProFileNode;
|
||||||
class Qt4TargetFactory;
|
class Qt4TargetFactory;
|
||||||
|
|
||||||
struct Qt4TargetInformation
|
|
||||||
{
|
|
||||||
enum ErrorCode {
|
|
||||||
NoError,
|
|
||||||
InvalidProjectError,
|
|
||||||
ProParserError
|
|
||||||
};
|
|
||||||
|
|
||||||
ErrorCode error;
|
|
||||||
QString workingDir;
|
|
||||||
QString target;
|
|
||||||
QString executable;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Qt4Target : public ProjectExplorer::Target
|
class Qt4Target : public ProjectExplorer::Target
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -79,9 +65,6 @@ public:
|
|||||||
Qt4BuildConfiguration *activeBuildConfiguration() const;
|
Qt4BuildConfiguration *activeBuildConfiguration() const;
|
||||||
Qt4ProjectManager::Qt4Project *qt4Project() const;
|
Qt4ProjectManager::Qt4Project *qt4Project() const;
|
||||||
|
|
||||||
Qt4TargetInformation targetInformation(Internal::Qt4BuildConfiguration *buildConfiguration,
|
|
||||||
const QString &proFilePath);
|
|
||||||
|
|
||||||
Internal::Qt4BuildConfiguration *addQt4BuildConfiguration(QString displayName,
|
Internal::Qt4BuildConfiguration *addQt4BuildConfiguration(QString displayName,
|
||||||
QtVersion *qtversion,
|
QtVersion *qtversion,
|
||||||
QtVersion::QmakeBuildConfigs qmakeBuildConfiguration,
|
QtVersion::QmakeBuildConfigs qmakeBuildConfiguration,
|
||||||
@@ -94,11 +77,10 @@ public:
|
|||||||
ProjectExplorer::ToolChain::ToolChainType preferredToolChainType(const QList<ProjectExplorer::ToolChain::ToolChainType> &candidates) const;
|
ProjectExplorer::ToolChain::ToolChainType preferredToolChainType(const QList<ProjectExplorer::ToolChain::ToolChainType> &candidates) const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
/// convenience signal, emitted if either the active buildconfiguration emits
|
|
||||||
/// targetInformationChanged() or if the active build configuration changes
|
|
||||||
void targetInformationChanged();
|
|
||||||
|
|
||||||
void buildDirectoryInitialized();
|
void buildDirectoryInitialized();
|
||||||
|
/// emitted if the build configuration changed in a way that
|
||||||
|
/// should trigger a reevaluation of all .pro files
|
||||||
|
void proFileEvaluateNeeded(Qt4ProjectManager::Internal::Qt4Target *);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool fromMap(const QVariantMap &map);
|
bool fromMap(const QVariantMap &map);
|
||||||
@@ -108,7 +90,8 @@ private slots:
|
|||||||
void onAddedRunConfiguration(ProjectExplorer::RunConfiguration *rc);
|
void onAddedRunConfiguration(ProjectExplorer::RunConfiguration *rc);
|
||||||
void onAddedBuildConfiguration(ProjectExplorer::BuildConfiguration *bc);
|
void onAddedBuildConfiguration(ProjectExplorer::BuildConfiguration *bc);
|
||||||
void slotUpdateDeviceInformation();
|
void slotUpdateDeviceInformation();
|
||||||
void changeTargetInformation();
|
void onProFileEvaluateNeeded(Qt4ProjectManager::Internal::Qt4BuildConfiguration *bc);
|
||||||
|
void emitProFileEvaluateNeeded();
|
||||||
void updateToolTipAndIcon();
|
void updateToolTipAndIcon();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@@ -1221,6 +1221,7 @@ void QtVersion::updateToolChainAndMkspec() const
|
|||||||
ProFileOption option;
|
ProFileOption option;
|
||||||
option.properties = versionInfo();
|
option.properties = versionInfo();
|
||||||
option.cache = ProFileCacheManager::instance()->cache();
|
option.cache = ProFileCacheManager::instance()->cache();
|
||||||
|
ProFileCacheManager::instance()->incRefCount();
|
||||||
ProFileReader *reader = new ProFileReader(&option);
|
ProFileReader *reader = new ProFileReader(&option);
|
||||||
reader->setCumulative(false);
|
reader->setCumulative(false);
|
||||||
reader->setParsePreAndPostFiles(false);
|
reader->setParsePreAndPostFiles(false);
|
||||||
@@ -1302,6 +1303,7 @@ void QtVersion::updateToolChainAndMkspec() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
delete reader;
|
delete reader;
|
||||||
|
ProFileCacheManager::instance()->decRefCount();
|
||||||
m_toolChainUpToDate = true;
|
m_toolChainUpToDate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user