forked from qt-creator/qt-creator
QmakeProjectImporter: Prepare for multiple concurrent imports
Fix logic around temporary qt versions. We want essentially shared ownership of kits on the temporary qt version. Change-Id: Ic8c748aa2b04afb5a30444563b3fc2f4272ca47c Reviewed-by: Tobias Hunger <tobias.hunger@digia.com>
This commit is contained in:
@@ -64,6 +64,12 @@ bool anyOf(const T &container, F predicate)
|
||||
return std::any_of(container.begin(), container.end(), predicate);
|
||||
}
|
||||
|
||||
template<typename T, typename F>
|
||||
int count(const T &container, F predicate)
|
||||
{
|
||||
return std::count_if(container.begin(), container.end(), predicate);
|
||||
}
|
||||
|
||||
//////////////////
|
||||
// allOf
|
||||
/////////////////
|
||||
|
||||
@@ -477,6 +477,25 @@ void Kit::setValue(Id key, const QVariant &value)
|
||||
kitUpdated();
|
||||
}
|
||||
|
||||
/// \internal
|
||||
void Kit::setValueSilently(Id key, const QVariant &value)
|
||||
{
|
||||
if (d->m_data.value(key) == value)
|
||||
return;
|
||||
d->m_data.insert(key, value);
|
||||
}
|
||||
|
||||
/// \internal
|
||||
void Kit::removeKeySilently(Id key)
|
||||
{
|
||||
if (!d->m_data.contains(key))
|
||||
return;
|
||||
d->m_data.remove(key);
|
||||
d->m_sticky.remove(key);
|
||||
d->m_mutable.remove(key);
|
||||
}
|
||||
|
||||
|
||||
void Kit::removeKey(Id key)
|
||||
{
|
||||
if (!d->m_data.contains(key))
|
||||
|
||||
@@ -97,7 +97,9 @@ public:
|
||||
QVariant value(Core::Id key, const QVariant &unset = QVariant()) const;
|
||||
bool hasValue(Core::Id key) const;
|
||||
void setValue(Core::Id key, const QVariant &value);
|
||||
void setValueSilently(Core::Id key, const QVariant &value);
|
||||
void removeKey(Core::Id key);
|
||||
void removeKeySilently(Core::Id key);
|
||||
bool isSticky(Core::Id id) const;
|
||||
|
||||
bool isDataEqual(const Kit *other) const;
|
||||
|
||||
@@ -57,7 +57,7 @@ void ProjectImporter::markTemporary(Kit *k)
|
||||
{
|
||||
QTC_ASSERT(!k->hasValue(KIT_IS_TEMPORARY), return);
|
||||
|
||||
setIsUpdating(true);
|
||||
bool oldIsUpdating = setIsUpdating(true);
|
||||
|
||||
const QString name = k->displayName();
|
||||
k->setUnexpandedDisplayName(QCoreApplication::translate("ProjectExplorer::ProjectImporter",
|
||||
@@ -67,7 +67,7 @@ void ProjectImporter::markTemporary(Kit *k)
|
||||
k->setValue(KIT_FINAL_NAME, name);
|
||||
k->setValue(KIT_IS_TEMPORARY, true);
|
||||
|
||||
setIsUpdating(false);
|
||||
setIsUpdating(oldIsUpdating);
|
||||
}
|
||||
|
||||
void ProjectImporter::makePermanent(Kit *k)
|
||||
@@ -75,7 +75,7 @@ void ProjectImporter::makePermanent(Kit *k)
|
||||
if (!k->hasValue(KIT_IS_TEMPORARY))
|
||||
return;
|
||||
|
||||
setIsUpdating(true);
|
||||
bool oldIsUpdating = setIsUpdating(true);
|
||||
|
||||
k->removeKey(KIT_IS_TEMPORARY);
|
||||
k->removeKey(TEMPORARY_OF_PROJECTS);
|
||||
@@ -85,7 +85,7 @@ void ProjectImporter::makePermanent(Kit *k)
|
||||
k->removeKey(KIT_TEMPORARY_NAME);
|
||||
k->removeKey(KIT_FINAL_NAME);
|
||||
|
||||
setIsUpdating(false);
|
||||
setIsUpdating(oldIsUpdating);
|
||||
}
|
||||
|
||||
void ProjectImporter::cleanupKit(Kit *k)
|
||||
@@ -102,11 +102,11 @@ void ProjectImporter::addProject(Kit *k)
|
||||
|
||||
projects.append(m_projectPath); // note: There can be more than one instance of the project added!
|
||||
|
||||
setIsUpdating(true);
|
||||
bool oldIsUpdating = setIsUpdating(true);
|
||||
|
||||
k->setValue(TEMPORARY_OF_PROJECTS, projects);
|
||||
k->setValueSilently(TEMPORARY_OF_PROJECTS, projects);
|
||||
|
||||
setIsUpdating(false);
|
||||
setIsUpdating(oldIsUpdating);
|
||||
}
|
||||
|
||||
void ProjectImporter::removeProject(Kit *k, const QString &path)
|
||||
@@ -117,14 +117,19 @@ void ProjectImporter::removeProject(Kit *k, const QString &path)
|
||||
QStringList projects = k->value(TEMPORARY_OF_PROJECTS, QStringList()).toStringList();
|
||||
projects.removeOne(path);
|
||||
|
||||
setIsUpdating(true);
|
||||
bool oldIsUpdating = setIsUpdating(true);
|
||||
|
||||
if (projects.isEmpty())
|
||||
ProjectExplorer::KitManager::deregisterKit(k);
|
||||
else
|
||||
k->setValue(TEMPORARY_OF_PROJECTS, projects);
|
||||
k->setValueSilently(TEMPORARY_OF_PROJECTS, projects);
|
||||
|
||||
setIsUpdating(false);
|
||||
setIsUpdating(oldIsUpdating);
|
||||
}
|
||||
|
||||
bool ProjectImporter::isTemporaryKit(Kit *k)
|
||||
{
|
||||
return k->hasValue(KIT_IS_TEMPORARY);
|
||||
}
|
||||
|
||||
} // namespace ProjectExplorer
|
||||
|
||||
@@ -65,8 +65,14 @@ public:
|
||||
void addProject(Kit *k);
|
||||
void removeProject(Kit *k, const QString &path);
|
||||
|
||||
bool isTemporaryKit(Kit *k);
|
||||
|
||||
protected:
|
||||
void setIsUpdating(bool b) { m_isUpdating = b; }
|
||||
bool setIsUpdating(bool b) {
|
||||
bool old = m_isUpdating;
|
||||
m_isUpdating = b;
|
||||
return old;
|
||||
}
|
||||
|
||||
private:
|
||||
const QString m_projectPath;
|
||||
|
||||
@@ -181,6 +181,8 @@ TargetSetupPage::TargetSetupPage(QWidget *parent) :
|
||||
setUseScrollArea(true);
|
||||
|
||||
QObject *km = KitManager::instance();
|
||||
// do note that those slots are triggered once *per* targetsetuppage
|
||||
// thus the same slot can be triggered multiple times on different instances!
|
||||
connect(km, SIGNAL(kitAdded(ProjectExplorer::Kit*)),
|
||||
this, SLOT(handleKitAddition(ProjectExplorer::Kit*)));
|
||||
connect(km, SIGNAL(kitRemoved(ProjectExplorer::Kit*)),
|
||||
|
||||
@@ -96,16 +96,22 @@ QList<ProjectExplorer::BuildInfo *> QmakeProjectImporter::import(const Utils::Fi
|
||||
}
|
||||
}
|
||||
|
||||
// Create a new version if not found:
|
||||
if (!version) {
|
||||
if (version) {
|
||||
// Check if version is a temporary qt
|
||||
int qtId = version->uniqueId();
|
||||
temporaryVersion = Utils::anyOf(ProjectExplorer::KitManager::kits(), [&qtId](ProjectExplorer::Kit *k){
|
||||
return k->value(QT_IS_TEMPORARY, -1).toInt() == qtId;
|
||||
});
|
||||
} else {
|
||||
// Create a new version if not found:
|
||||
// Do not use the canonical path here...
|
||||
version = QtSupport::QtVersionFactory::createQtVersionFromQMakePath(qmakeBinary);
|
||||
if (!version)
|
||||
continue;
|
||||
|
||||
setIsUpdating(true);
|
||||
bool oldIsUpdating = setIsUpdating(true);
|
||||
QtSupport::QtVersionManager::addVersion(version);
|
||||
setIsUpdating(false);
|
||||
setIsUpdating(oldIsUpdating);
|
||||
temporaryVersion = true;
|
||||
}
|
||||
|
||||
@@ -246,21 +252,39 @@ ProjectExplorer::Target *QmakeProjectImporter::preferredTarget(const QList<Proje
|
||||
void QmakeProjectImporter::cleanupKit(ProjectExplorer::Kit *k)
|
||||
{
|
||||
QtSupport::BaseQtVersion *version = QtSupport::QtVersionManager::version(k->value(QT_IS_TEMPORARY, -1).toInt());
|
||||
if (version)
|
||||
if (!version)
|
||||
return;
|
||||
|
||||
// count how many kits are using this version
|
||||
int qtId = version->uniqueId();
|
||||
int count = Utils::count(ProjectExplorer::KitManager::kits(), [qtId](ProjectExplorer::Kit *k) {
|
||||
return k->value(QT_IS_TEMPORARY, -1).toInt() == qtId;
|
||||
});
|
||||
|
||||
if (count == 0) // Remove if no other kit is using it. (The Kit k is not in KitManager::kits()
|
||||
QtSupport::QtVersionManager::removeVersion(version);
|
||||
}
|
||||
|
||||
void QmakeProjectImporter::makePermanent(ProjectExplorer::Kit *k)
|
||||
{
|
||||
if (!isTemporaryKit(k))
|
||||
return;
|
||||
setIsUpdating(true);
|
||||
int tempId = k->value(QT_IS_TEMPORARY, -1).toInt();
|
||||
int qtId = QtSupport::QtKitInformation::qtVersionId(k);
|
||||
if (tempId != qtId) {
|
||||
QtSupport::BaseQtVersion *version = QtSupport::QtVersionManager::version(tempId);
|
||||
if (version)
|
||||
int count = Utils::count(ProjectExplorer::KitManager::kits(), [tempId](ProjectExplorer::Kit *k) {
|
||||
return k->value(QT_IS_TEMPORARY, -1).toInt() == tempId;
|
||||
});
|
||||
if (count == 0)
|
||||
QtSupport::QtVersionManager::removeVersion(version);
|
||||
}
|
||||
|
||||
k->removeKey(QT_IS_TEMPORARY);
|
||||
foreach (ProjectExplorer::Kit *kit, ProjectExplorer::KitManager::kits())
|
||||
if (kit->value(QT_IS_TEMPORARY, -1).toInt() == tempId)
|
||||
kit->removeKeySilently(QT_IS_TEMPORARY);
|
||||
setIsUpdating(false);
|
||||
ProjectImporter::makePermanent(k);
|
||||
}
|
||||
|
||||
@@ -287,30 +311,30 @@ ProjectExplorer::Kit *QmakeProjectImporter::createTemporaryKit(QtSupport::BaseQt
|
||||
const QStringList &deducedQmakeArguments)
|
||||
{
|
||||
ProjectExplorer::Kit *k = new ProjectExplorer::Kit;
|
||||
bool oldIsUpdating = setIsUpdating(true);
|
||||
{
|
||||
ProjectExplorer::KitGuard guard(k);
|
||||
|
||||
ProjectExplorer::KitGuard guard(k);
|
||||
QtSupport::QtKitInformation::setQtVersion(k, version);
|
||||
ProjectExplorer::ToolChainKitInformation::setToolChain(k, preferredToolChain(version, parsedSpec, deducedQmakeArguments));
|
||||
QmakeKitInformation::setMkspec(k, parsedSpec);
|
||||
|
||||
QtSupport::QtKitInformation::setQtVersion(k, version);
|
||||
ProjectExplorer::ToolChainKitInformation::setToolChain(k, preferredToolChain(version, parsedSpec, deducedQmakeArguments));
|
||||
QmakeKitInformation::setMkspec(k, parsedSpec);
|
||||
markTemporary(k);
|
||||
if (temporaryVersion)
|
||||
k->setValue(QT_IS_TEMPORARY, version->uniqueId());
|
||||
|
||||
markTemporary(k);
|
||||
if (temporaryVersion)
|
||||
k->setValue(QT_IS_TEMPORARY, version->uniqueId());
|
||||
// Set up other values:
|
||||
foreach (ProjectExplorer::KitInformation *ki, ProjectExplorer::KitManager::kitInformation()) {
|
||||
if (ki->id() == ProjectExplorer::ToolChainKitInformation::id()
|
||||
|| ki->id() == QtSupport::QtKitInformation::id())
|
||||
continue;
|
||||
ki->setup(k);
|
||||
}
|
||||
k->setUnexpandedDisplayName(version->displayName());;
|
||||
} // ~KitGuard, sending kitUpdated
|
||||
|
||||
// Set up other values:
|
||||
foreach (ProjectExplorer::KitInformation *ki, ProjectExplorer::KitManager::kitInformation()) {
|
||||
if (ki->id() == ProjectExplorer::ToolChainKitInformation::id()
|
||||
|| ki->id() == QtSupport::QtKitInformation::id())
|
||||
continue;
|
||||
ki->setup(k);
|
||||
}
|
||||
|
||||
k->setUnexpandedDisplayName(version->displayName());
|
||||
|
||||
setIsUpdating(true);
|
||||
ProjectExplorer::KitManager::registerKit(k);
|
||||
setIsUpdating(false);
|
||||
ProjectExplorer::KitManager::registerKit(k); // potentially adds kits to other targetsetuppages
|
||||
setIsUpdating(oldIsUpdating);
|
||||
return k;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user