Commit 4a52d821 authored by Tobias Hunger's avatar Tobias Hunger Committed by hjk

Kit: Introduce variables for Kit display names

This change also adds a AbstractMacroExpander for the QtKitInformation.

It supports the following variables in the Kit display name:

 %{Qt:version} - Qt version number
 %{Qt:type}    - Qt type
 %{Qt:name}    - Qt version name
 %{Qt:mkspec}  - mkspec used by the Qt version

Task-number: QTCREATORBUG-11118
Change-Id: I7263781336ab561c34880b187ebd55e81e6ca215
Reviewed-by: default avatarDaniel Teske <daniel.teske@digia.com>
Reviewed-by: default avatarhjk <hjk121@nokiamail.com>
parent 351abd03
...@@ -1147,7 +1147,7 @@ void AndroidConfigurations::updateAutomaticKitList() ...@@ -1147,7 +1147,7 @@ void AndroidConfigurations::updateAutomaticKitList()
foreach (Kit *kit, newKits) { foreach (Kit *kit, newKits) {
AndroidToolChain *tc = static_cast<AndroidToolChain *>(ToolChainKitInformation::toolChain(kit)); AndroidToolChain *tc = static_cast<AndroidToolChain *>(ToolChainKitInformation::toolChain(kit));
AndroidQtVersion *qt = static_cast<AndroidQtVersion *>(QtSupport::QtKitInformation::qtVersion(kit)); AndroidQtVersion *qt = static_cast<AndroidQtVersion *>(QtSupport::QtKitInformation::qtVersion(kit));
kit->setDisplayName(tr("Android for %1 (GCC %2, Qt %3)") kit->setUnexpandedDisplayName(tr("Android for %1 (GCC %2, Qt %3)")
.arg(qt->targetArch()) .arg(qt->targetArch())
.arg(tc->ndkToolChainVersion()) .arg(tc->ndkToolChainVersion())
.arg(qt->qtVersionString())); .arg(qt->qtVersionString()));
......
...@@ -308,7 +308,7 @@ void IosConfigurations::updateAutomaticKitList() ...@@ -308,7 +308,7 @@ void IosConfigurations::updateAutomaticKitList()
if (unique) break; if (unique) break;
displayName = baseDisplayName + QLatin1String("-") + QString::number(iVers); displayName = baseDisplayName + QLatin1String("-") + QString::number(iVers);
} }
kitAtt->setDisplayName(displayName); kitAtt->setUnexpandedDisplayName(displayName);
} }
kitAtt->setIconPath(Utils::FileName::fromString( kitAtt->setIconPath(Utils::FileName::fromString(
QLatin1String(Constants::IOS_SETTINGS_CATEGORY_ICON))); QLatin1String(Constants::IOS_SETTINGS_CATEGORY_ICON)));
......
...@@ -35,6 +35,8 @@ ...@@ -35,6 +35,8 @@
#include <utils/algorithm.h> #include <utils/algorithm.h>
#include <utils/fileutils.h> #include <utils/fileutils.h>
#include <utils/qtcassert.h>
#include <utils/stringutils.h>
#include <QApplication> #include <QApplication>
#include <QFileInfo> #include <QFileInfo>
...@@ -62,6 +64,33 @@ const char STICKY_INFO_KEY[] = "PE.Profile.StickyInfo"; ...@@ -62,6 +64,33 @@ const char STICKY_INFO_KEY[] = "PE.Profile.StickyInfo";
namespace ProjectExplorer { namespace ProjectExplorer {
// --------------------------------------------------------------------
// KitMacroExpander:
// --------------------------------------------------------------------
class KitMacroExpander : public Utils::AbstractMacroExpander
{
public:
KitMacroExpander(const QList<Utils::AbstractMacroExpander *> &children) :
m_childExpanders(children)
{ }
~KitMacroExpander() { qDeleteAll(m_childExpanders); }
bool resolveMacro(const QString &name, QString *ret);
private:
QList<Utils::AbstractMacroExpander *> m_childExpanders;
};
bool KitMacroExpander::resolveMacro(const QString &name, QString *ret)
{
foreach (Utils::AbstractMacroExpander *expander, m_childExpanders) {
if (expander->resolveMacro(name, ret))
return true;
}
return false;
}
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
// KitPrivate // KitPrivate
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
...@@ -71,7 +100,7 @@ namespace Internal { ...@@ -71,7 +100,7 @@ namespace Internal {
class KitPrivate class KitPrivate
{ {
public: public:
KitPrivate(Id id) : KitPrivate(Id id, Kit *k) :
m_id(id), m_id(id),
m_nestedBlockingLevel(0), m_nestedBlockingLevel(0),
m_autodetected(false), m_autodetected(false),
...@@ -81,16 +110,37 @@ public: ...@@ -81,16 +110,37 @@ public:
m_hasWarning(false), m_hasWarning(false),
m_hasValidityInfo(false), m_hasValidityInfo(false),
m_mustNotify(false), m_mustNotify(false),
m_mustNotifyAboutDisplayName(false) m_mustNotifyAboutDisplayName(false),
m_macroExpander(0)
{ {
if (!id.isValid()) if (!id.isValid())
m_id = Id::fromString(QUuid::createUuid().toString()); m_id = Id::fromString(QUuid::createUuid().toString());
m_displayName = QCoreApplication::translate("ProjectExplorer::Kit", "Unnamed"); m_displayName = QCoreApplication::translate("ProjectExplorer::Kit", "Unnamed");
m_previousDisplayName = m_displayName;
m_iconPath = Utils::FileName::fromLatin1(":///DESKTOP///"); m_iconPath = Utils::FileName::fromLatin1(":///DESKTOP///");
QList<Utils::AbstractMacroExpander *> expanders;
foreach (const KitInformation *ki, KitManager::kitInformation()) {
Utils::AbstractMacroExpander *tmp = ki->createMacroExpander(k);
if (tmp)
expanders.append(tmp);
}
m_macroExpander = new KitMacroExpander(expanders);
}
~KitPrivate()
{ delete m_macroExpander; }
void updatePreviousDisplayName()
{
QTC_ASSERT(m_macroExpander, return);
m_previousDisplayName = Utils::expandMacros(m_displayName, m_macroExpander);
} }
QString m_displayName; QString m_displayName;
QString m_previousDisplayName;
QString m_fileSystemFriendlyName; QString m_fileSystemFriendlyName;
Id m_id; Id m_id;
int m_nestedBlockingLevel; int m_nestedBlockingLevel;
...@@ -108,6 +158,7 @@ public: ...@@ -108,6 +158,7 @@ public:
QHash<Core::Id, QVariant> m_data; QHash<Core::Id, QVariant> m_data;
QSet<Core::Id> m_sticky; QSet<Core::Id> m_sticky;
QSet<Core::Id> m_mutable; QSet<Core::Id> m_mutable;
Utils::AbstractMacroExpander *m_macroExpander;
}; };
} // namespace Internal } // namespace Internal
...@@ -117,16 +168,17 @@ public: ...@@ -117,16 +168,17 @@ public:
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
Kit::Kit(Core::Id id) : Kit::Kit(Core::Id id) :
d(new Internal::KitPrivate(id)) d(new Internal::KitPrivate(id, this))
{ {
foreach (KitInformation *sti, KitManager::kitInformation()) foreach (KitInformation *sti, KitManager::kitInformation())
d->m_data.insert(sti->id(), sti->defaultValue(this)); d->m_data.insert(sti->id(), sti->defaultValue(this));
d->m_icon = icon(d->m_iconPath); d->m_icon = icon(d->m_iconPath);
d->updatePreviousDisplayName();
} }
Kit::Kit(const QVariantMap &data) : Kit::Kit(const QVariantMap &data) :
d(new Internal::KitPrivate(Core::Id())) d(new Internal::KitPrivate(Core::Id(), this))
{ {
d->m_id = Id::fromSetting(data.value(QLatin1String(ID_KEY))); d->m_id = Id::fromSetting(data.value(QLatin1String(ID_KEY)));
...@@ -160,6 +212,8 @@ Kit::Kit(const QVariantMap &data) : ...@@ -160,6 +212,8 @@ Kit::Kit(const QVariantMap &data) :
QStringList stickyInfoList = data.value(QLatin1String(STICKY_INFO_KEY)).toStringList(); QStringList stickyInfoList = data.value(QLatin1String(STICKY_INFO_KEY)).toStringList();
foreach (const QString &stickyInfo, stickyInfoList) foreach (const QString &stickyInfo, stickyInfoList)
d->m_sticky.insert(Core::Id::fromString(stickyInfo)); d->m_sticky.insert(Core::Id::fromString(stickyInfo));
d->updatePreviousDisplayName();
} }
Kit::~Kit() Kit::~Kit()
...@@ -201,6 +255,7 @@ Kit *Kit::clone(bool keepName) const ...@@ -201,6 +255,7 @@ Kit *Kit::clone(bool keepName) const
k->d->m_iconPath = d->m_iconPath; k->d->m_iconPath = d->m_iconPath;
k->d->m_sticky = d->m_sticky; k->d->m_sticky = d->m_sticky;
k->d->m_mutable = d->m_mutable; k->d->m_mutable = d->m_mutable;
k->d->updatePreviousDisplayName();
return k; return k;
} }
...@@ -215,9 +270,10 @@ void Kit::copyFrom(const Kit *k) ...@@ -215,9 +270,10 @@ void Kit::copyFrom(const Kit *k)
d->m_displayName = k->d->m_displayName; d->m_displayName = k->d->m_displayName;
d->m_fileSystemFriendlyName = k->d->m_fileSystemFriendlyName; d->m_fileSystemFriendlyName = k->d->m_fileSystemFriendlyName;
d->m_mustNotify = true; d->m_mustNotify = true;
d->m_mustNotifyAboutDisplayName = true; d->m_mustNotifyAboutDisplayName = false;
d->m_sticky = k->d->m_sticky; d->m_sticky = k->d->m_sticky;
d->m_mutable = k->d->m_mutable; d->m_mutable = k->d->m_mutable;
d->updatePreviousDisplayName();
} }
bool Kit::isValid() const bool Kit::isValid() const
...@@ -277,11 +333,16 @@ void Kit::setup() ...@@ -277,11 +333,16 @@ void Kit::setup()
info.at(i)->setup(this); info.at(i)->setup(this);
} }
QString Kit::displayName() const QString Kit::unexpandedDisplayName() const
{ {
return d->m_displayName; return d->m_displayName;
} }
QString Kit::displayName() const
{
return Utils::expandMacros(unexpandedDisplayName(), macroExpander());
}
static QString candidateName(const QString &name, const QString &postfix) static QString candidateName(const QString &name, const QString &postfix)
{ {
if (name.contains(postfix)) if (name.contains(postfix))
...@@ -293,11 +354,13 @@ static QString candidateName(const QString &name, const QString &postfix) ...@@ -293,11 +354,13 @@ static QString candidateName(const QString &name, const QString &postfix)
return candidate; return candidate;
} }
void Kit::setDisplayName(const QString &name) void Kit::setUnexpandedDisplayName(const QString &name)
{ {
if (d->m_displayName == name) if (d->m_displayName == name)
return; return;
d->m_displayName = name; d->m_displayName = name;
d->updatePreviousDisplayName();
kitDisplayNameChanged(); kitDisplayNameChanged();
} }
...@@ -310,7 +373,7 @@ QStringList Kit::candidateNameList(const QString &base) const ...@@ -310,7 +373,7 @@ QStringList Kit::candidateNameList(const QString &base) const
if (!postfix.isEmpty()) { if (!postfix.isEmpty()) {
QString tmp = candidateName(base, postfix); QString tmp = candidateName(base, postfix);
if (!tmp.isEmpty()) if (!tmp.isEmpty())
result << candidateName(base, postfix); result << tmp;
} }
} }
return result; return result;
...@@ -621,14 +684,26 @@ bool Kit::hasFeatures(const FeatureSet &features) const ...@@ -621,14 +684,26 @@ bool Kit::hasFeatures(const FeatureSet &features) const
return availableFeatures().contains(features); return availableFeatures().contains(features);
} }
Utils::AbstractMacroExpander *Kit::macroExpander() const
{
QTC_CHECK(d->m_macroExpander);
return d->m_macroExpander;
}
void Kit::kitUpdated() void Kit::kitUpdated()
{ {
if (d->m_nestedBlockingLevel > 0 && !d->m_mustNotifyAboutDisplayName) { if (d->m_nestedBlockingLevel > 0) {
d->m_mustNotify = true; if (!d->m_mustNotifyAboutDisplayName)
d->m_mustNotify = true;
return; return;
} }
d->m_hasValidityInfo = false; d->m_hasValidityInfo = false;
KitManager::notifyAboutUpdate(this); if (displayName() != d->m_previousDisplayName) {
d->updatePreviousDisplayName();
KitManager::notifyAboutDisplayNameChange(this);
} else {
KitManager::notifyAboutUpdate(this);
}
} }
void Kit::kitDisplayNameChanged() void Kit::kitDisplayNameChanged()
......
...@@ -38,7 +38,10 @@ ...@@ -38,7 +38,10 @@
#include <QSet> #include <QSet>
#include <QVariant> #include <QVariant>
namespace Utils { class Environment; } namespace Utils {
class AbstractMacroExpander;
class Environment;
} // namespace Utils
namespace ProjectExplorer { namespace ProjectExplorer {
class IOutputParser; class IOutputParser;
...@@ -71,8 +74,9 @@ public: ...@@ -71,8 +74,9 @@ public:
// Fix will not look at other information in the kit! // Fix will not look at other information in the kit!
void setup(); // Apply advanced magic(TM). Used only once on each kit during initial setup. void setup(); // Apply advanced magic(TM). Used only once on each kit during initial setup.
QString unexpandedDisplayName() const;
QString displayName() const; QString displayName() const;
void setDisplayName(const QString &name); void setUnexpandedDisplayName(const QString &name);
QStringList candidateNameList(const QString &base) const; QStringList candidateNameList(const QString &base) const;
...@@ -122,6 +126,8 @@ public: ...@@ -122,6 +126,8 @@ public:
Core::FeatureSet availableFeatures() const; Core::FeatureSet availableFeatures() const;
bool hasFeatures(const Core::FeatureSet &features) const; bool hasFeatures(const Core::FeatureSet &features) const;
Utils::AbstractMacroExpander *macroExpander() const;
private: private:
void setSdkProvided(bool sdkProvided); void setSdkProvided(bool sdkProvided);
......
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#include "kitinformationmacroexpander.h"
#include <utils/qtcassert.h>
namespace ProjectExplorer {
KitInformationMacroExpander::KitInformationMacroExpander(const Kit *k) :
m_kit(k)
{
QTC_CHECK(k);
}
const Kit *KitInformationMacroExpander::kit() const
{
return m_kit;
}
// --------------------------------------------------------------------------
// KitInformationMacroExpander:
// --------------------------------------------------------------------------
} // namespace ProjectExplorer
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#ifndef KITINFORMATIONMACROEXPANDER_H
#define KITINFORMATIONMACROEXPANDER_H
#include "projectexplorer_export.h"
#include <utils/stringutils.h>
namespace ProjectExplorer {
class Kit;
// --------------------------------------------------------------------------
// KitInformationMacroExpander:
// --------------------------------------------------------------------------
class PROJECTEXPLORER_EXPORT KitInformationMacroExpander : public Utils::AbstractMacroExpander
{
public:
KitInformationMacroExpander(const Kit *k);
const Kit *kit() const;
private:
const Kit *m_kit;
};
} // namespace ProjectExplorer
#endif // KITINFORMATIONMACROEXPANDER_H
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
#include <utils/persistentsettings.h> #include <utils/persistentsettings.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/stringutils.h>
#include <utils/environment.h> #include <utils/environment.h>
#include <utils/algorithm.h> #include <utils/algorithm.h>
...@@ -243,7 +244,7 @@ void KitManager::restoreKits() ...@@ -243,7 +244,7 @@ void KitManager::restoreKits()
if (kits().isEmpty()) { if (kits().isEmpty()) {
Kit *defaultKit = new Kit; // One kit using default values Kit *defaultKit = new Kit; // One kit using default values
defaultKit->setDisplayName(tr("Desktop")); defaultKit->setUnexpandedDisplayName(tr("Desktop"));
defaultKit->setSdkProvided(false); defaultKit->setSdkProvided(false);
defaultKit->setAutoDetected(false); defaultKit->setAutoDetected(false);
defaultKit->setIconPath(Utils::FileName::fromLatin1(":///DESKTOP///")); defaultKit->setIconPath(Utils::FileName::fromLatin1(":///DESKTOP///"));
...@@ -476,7 +477,7 @@ void KitManager::deleteKit(Kit *k) ...@@ -476,7 +477,7 @@ void KitManager::deleteKit(Kit *k)
delete k; delete k;
} }
QString KitManager::uniqueKitName(const Kit *k, const QString &name, const QList<Kit *> &allKits) QString KitManager::uniqueKitName(const Kit *k, const QList<Kit *> &allKits)
{ {
QStringList nameList; QStringList nameList;
nameList << QString(); // Disallow empty kit names! nameList << QString(); // Disallow empty kit names!
...@@ -486,20 +487,21 @@ QString KitManager::uniqueKitName(const Kit *k, const QString &name, const QList ...@@ -486,20 +487,21 @@ QString KitManager::uniqueKitName(const Kit *k, const QString &name, const QList
nameList.append(tmp->candidateNameList(tmp->displayName())); nameList.append(tmp->candidateNameList(tmp->displayName()));
} }
QStringList candidateNames = k->candidateNameList(name); const QString dn = k->displayName();
const QString udn = k->unexpandedDisplayName();
QString uniqueName = Project::makeUnique(name, nameList); QString uniqueName = Project::makeUnique(dn, nameList);
if (uniqueName != name) { if (uniqueName == dn)
foreach (const QString &candidate, candidateNames) { return udn;
const QString tmp = Project::makeUnique(candidate, nameList);
if (tmp == candidate) { QStringList candidateNames = k->candidateNameList(udn);
uniqueName = tmp; foreach (const QString &candidate, candidateNames) {
break; QString expandedCandidate = Utils::expandMacros(candidate, k->macroExpander());
} if (!nameList.contains(expandedCandidate))
} return candidate;
} }
return uniqueName; return udn + uniqueName.mid(dn.count());
} }
void KitManager::notifyAboutDisplayNameChange(Kit *k) void KitManager::notifyAboutDisplayNameChange(Kit *k)
...@@ -507,7 +509,7 @@ void KitManager::notifyAboutDisplayNameChange(Kit *k) ...@@ -507,7 +509,7 @@ void KitManager::notifyAboutDisplayNameChange(Kit *k)
if (!k) if (!k)
return; return;
if (d->m_kitList.contains(k) && d->m_keepDisplayNameUnique) if (d->m_kitList.contains(k) && d->m_keepDisplayNameUnique)
k->setDisplayName(uniqueKitName(k, k->displayName(), kits())); k->setUnexpandedDisplayName(uniqueKitName(k, kits()));
int pos = d->m_kitList.indexOf(k); int pos = d->m_kitList.indexOf(k);
if (pos >= 0 && d->m_initialized) if (pos >= 0 && d->m_initialized)
d->moveKit(pos); d->moveKit(pos);
...@@ -537,7 +539,7 @@ bool KitManager::registerKit(ProjectExplorer::Kit *k) ...@@ -537,7 +539,7 @@ bool KitManager::registerKit(ProjectExplorer::Kit *k)
if (kits().contains(k)) if (kits().contains(k))
return false; return false;
k->setDisplayName(uniqueKitName(k, k->displayName(), kits())); k->setUnexpandedDisplayName(uniqueKitName(k, kits()));
// make sure we have all the information in our kits: // make sure we have all the information in our kits:
m_instance->addKit(k); m_instance->addKit(k);
......
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
#include <functional> #include <functional>
namespace Utils { namespace Utils {
class AbstractMacroExpander;
class FileName; class FileName;
class Environment; class Environment;
} }
...@@ -97,6 +98,9 @@ public: ...@@ -97,6 +98,9 @@ public:
virtual QString displayNameForPlatform(const ProjectExplorer::Kit *k, const QString &platform) const; virtual QString displayNameForPlatform(const ProjectExplorer::Kit *k, const QString &platform) const;
virtual Core::FeatureSet availableFeatures(const Kit *k) const; virtual Core::FeatureSet availableFeatures(const Kit *k) const;
virtual Utils::AbstractMacroExpander *createMacroExpander(const Kit *k) const
{ Q_UNUSED(k); return 0; }
protected: protected:
void setId(Core::Id id) { m_id = id; } void setId(Core::Id id) { m_id = id; }
void setPriority(int priority) { m_priority = priority; } void setPriority(int priority) { m_priority = priority; }
...@@ -140,7 +144,7 @@ public: ...@@ -140,7 +144,7 @@ public:
static void deleteKit(Kit *k); static void deleteKit(Kit *k);