From f05fcdcdd582a55db4e89afffcefc9da516b4d39 Mon Sep 17 00:00:00 2001
From: Tobias Hunger <tobias.hunger@digia.com>
Date: Mon, 9 Sep 2013 17:11:59 +0200
Subject: [PATCH] Kits: Allow for mutable KitInformation

Mutable KitInformation are those that are supposed to be editable in more
user-accessible places (e.g. like the Mini Target Selector or similar)
than the normal kit options page.

The functionality to display these settings is not part of this patch.

Change-Id: I13446c49abf89eaf739a60dbcd01c97e2144de45
Reviewed-by: Tobias Hunger <tobias.hunger@digia.com>
---
 src/plugins/projectexplorer/kit.cpp           | 32 ++++++++++++++++++-
 src/plugins/projectexplorer/kit.h             |  4 +++
 .../projectexplorer/kitconfigwidget.cpp       | 10 ++++++
 src/plugins/projectexplorer/kitconfigwidget.h |  2 ++
 src/plugins/projectexplorer/kitmanager.h      |  1 -
 .../kitmanagerconfigwidget.cpp                | 25 +++++++++++++++
 .../projectexplorer/kitmanagerconfigwidget.h  |  2 ++
 7 files changed, 74 insertions(+), 2 deletions(-)

diff --git a/src/plugins/projectexplorer/kit.cpp b/src/plugins/projectexplorer/kit.cpp
index f02eae4f474..23bdd24292e 100644
--- a/src/plugins/projectexplorer/kit.cpp
+++ b/src/plugins/projectexplorer/kit.cpp
@@ -52,6 +52,7 @@ const char AUTODETECTED_KEY[] = "PE.Profile.AutoDetected";
 const char SDK_PROVIDED_KEY[] = "PE.Profile.SDK";
 const char DATA_KEY[] = "PE.Profile.Data";
 const char ICON_KEY[] = "PE.Profile.Icon";
+const char MUTABLE_INFO_KEY[] = "PE.Profile.MutableInfo";
 
 } // namespace
 
@@ -94,6 +95,7 @@ public:
 
     QHash<Core::Id, QVariant> m_data;
     QSet<Core::Id> m_sticky;
+    QSet<Core::Id> m_mutable;
 };
 
 } // namespace Internal
@@ -150,6 +152,7 @@ Kit *Kit::clone(bool keepName) const
     k->d->m_icon = d->m_icon;
     k->d->m_iconPath = d->m_iconPath;
     k->d->m_sticky = d->m_sticky;
+    k->d->m_mutable = d->m_mutable;
     return k;
 }
 
@@ -164,6 +167,7 @@ void Kit::copyFrom(const Kit *k)
     d->m_mustNotify = true;
     d->m_mustNotifyAboutDisplayName = true;
     d->m_sticky = k->d->m_sticky;
+    d->m_mutable = k->d->m_mutable;
 }
 
 bool Kit::isValid() const
@@ -336,6 +340,7 @@ void Kit::removeKey(Id key)
         return;
     d->m_data.remove(key);
     d->m_sticky.remove(key);
+    d->m_mutable.remove(key);
     kitUpdated();
 }
 
@@ -353,7 +358,9 @@ bool Kit::isEqual(const Kit *other) const
 {
     return isDataEqual(other)
             && d->m_iconPath == other->d->m_iconPath
-            && d->m_displayName == other->d->m_displayName;
+            && d->m_displayName == other->d->m_displayName
+            && d->m_mutable == other->d->m_mutable;
+
 }
 
 QVariantMap Kit::toMap() const
@@ -367,6 +374,11 @@ QVariantMap Kit::toMap() const
     data.insert(QLatin1String(SDK_PROVIDED_KEY), d->m_sdkProvided);
     data.insert(QLatin1String(ICON_KEY), d->m_iconPath.toString());
 
+    QStringList mutableInfo;
+    foreach (const Core::Id &id, d->m_mutable.values())
+        mutableInfo << id.toString();
+    data.insert(QLatin1String(MUTABLE_INFO_KEY), mutableInfo);
+
     QVariantMap extra;
 
     const IdVariantConstIt cend = d->m_data.constEnd();
@@ -455,6 +467,11 @@ bool Kit::fromMap(const QVariantMap &data)
     for (QVariantMap::ConstIterator it = extra.constBegin(); it != cend; ++it)
         setValue(Id::fromString(it.key()), it.value());
 
+    QStringList mutableInfoList = data.value(QLatin1String(MUTABLE_INFO_KEY)).toStringList();
+    foreach (const QString &mutableInfo, mutableInfoList) {
+        d->m_mutable.insert(Core::Id::fromString(mutableInfo));
+    }
+
     return true;
 }
 
@@ -489,6 +506,19 @@ void Kit::makeUnSticky()
     d->m_sticky.clear();
 }
 
+void Kit::setMutable(Id id, bool b)
+{
+    if (b)
+        d->m_mutable.insert(id);
+    else
+        d->m_mutable.remove(id);
+}
+
+bool Kit::isMutable(Id id) const
+{
+    return d->m_mutable.contains(id);
+}
+
 void Kit::kitUpdated()
 {
     if (d->m_nestedBlockingLevel > 0 && !d->m_mustNotifyAboutDisplayName) {
diff --git a/src/plugins/projectexplorer/kit.h b/src/plugins/projectexplorer/kit.h
index b8495cb770b..72deab3edd5 100644
--- a/src/plugins/projectexplorer/kit.h
+++ b/src/plugins/projectexplorer/kit.h
@@ -100,11 +100,15 @@ public:
     Kit *clone(bool keepName = false) const;
     void copyFrom(const Kit *k);
 
+    // Note: Stickyness is *not* saved!
     void setAutoDetected(bool detected);
     void makeSticky();
     void setSticky(Core::Id id, bool b);
     void makeUnSticky();
 
+    void setMutable(Core::Id id, bool b);
+    bool isMutable(Core::Id id) const;
+
 private:
     void setSdkProvided(bool sdkProvided);
 
diff --git a/src/plugins/projectexplorer/kitconfigwidget.cpp b/src/plugins/projectexplorer/kitconfigwidget.cpp
index 189553c6a43..2504cf682c5 100644
--- a/src/plugins/projectexplorer/kitconfigwidget.cpp
+++ b/src/plugins/projectexplorer/kitconfigwidget.cpp
@@ -43,4 +43,14 @@ Core::Id KitConfigWidget::kitInformationId() const
     return m_kitInformation->id();
 }
 
+bool KitConfigWidget::isMutable() const
+{
+    return m_kit->isMutable(m_kitInformation->id());
+}
+
+void KitConfigWidget::setMutable(bool b)
+{
+    m_kit->setMutable(m_kitInformation->id(), b);
+}
+
 } // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/kitconfigwidget.h b/src/plugins/projectexplorer/kitconfigwidget.h
index 04ddb969416..fbb4b745f8b 100644
--- a/src/plugins/projectexplorer/kitconfigwidget.h
+++ b/src/plugins/projectexplorer/kitconfigwidget.h
@@ -64,6 +64,8 @@ public:
     virtual QWidget *buttonWidget() const { return 0; }
 
     bool isSticky() const { return m_isSticky; }
+    bool isMutable() const;
+    void setMutable(bool b);
 
 signals:
     void dirty();
diff --git a/src/plugins/projectexplorer/kitmanager.h b/src/plugins/projectexplorer/kitmanager.h
index 449921dd98a..5c201aa14f3 100644
--- a/src/plugins/projectexplorer/kitmanager.h
+++ b/src/plugins/projectexplorer/kitmanager.h
@@ -90,7 +90,6 @@ public:
 
     virtual QString displayNamePostfix(const Kit *k) const;
 
-
 protected:
     void setId(Core::Id id) { m_id = id; }
     void setPriority(int priority) { m_priority = priority; }
diff --git a/src/plugins/projectexplorer/kitmanagerconfigwidget.cpp b/src/plugins/projectexplorer/kitmanagerconfigwidget.cpp
index 4f70c7fd252..8c586ef6a24 100644
--- a/src/plugins/projectexplorer/kitmanagerconfigwidget.cpp
+++ b/src/plugins/projectexplorer/kitmanagerconfigwidget.cpp
@@ -35,6 +35,7 @@
 #include <utils/detailswidget.h>
 #include <utils/qtcassert.h>
 
+#include <QAction>
 #include <QFileDialog>
 #include <QGridLayout>
 #include <QLabel>
@@ -98,6 +99,8 @@ KitManagerConfigWidget::~KitManagerConfigWidget()
 {
     qDeleteAll(m_widgets);
     m_widgets.clear();
+    qDeleteAll(m_actions);
+    m_actions.clear();
 
     KitManager::deleteKit(m_modifiedKit);
     // Make sure our workingCopy did not get registered somehow:
@@ -174,6 +177,16 @@ void KitManagerConfigWidget::addConfigWidget(ProjectExplorer::KitConfigWidget *w
     QString name = widget->displayName();
     QString toolTip = widget->toolTip();
 
+    QAction *action = new QAction(tr("Mark as Mutable"), 0);
+    action->setCheckable(true);
+    action->setData(QVariant::fromValue(widget));
+    action->setChecked(widget->isMutable());
+    action->setEnabled(!widget->isSticky());
+    widget->mainWidget()->addAction(action);
+    widget->mainWidget()->setContextMenuPolicy(Qt::ActionsContextMenu);
+    connect(action, SIGNAL(toggled(bool)), this, SLOT(updateMutableState()));
+    m_actions << action;
+
     int row = m_layout->rowCount();
     m_layout->addWidget(widget->mainWidget(), row, WidgetColumn);
     if (QWidget *button = widget->buttonWidget())
@@ -287,6 +300,18 @@ void KitManagerConfigWidget::kitWasUpdated(Kit *k)
     updateVisibility();
 }
 
+void KitManagerConfigWidget::updateMutableState()
+{
+    QAction *action = qobject_cast<QAction *>(sender());
+    if (!action)
+        return;
+    KitConfigWidget *widget = qobject_cast<KitConfigWidget *>(action->data().value<QObject *>());
+    if (!widget)
+        return;
+    widget->setMutable(action->isChecked());
+    emit dirty();
+}
+
 QLabel *KitManagerConfigWidget::createLabel(const QString &name, const QString &toolTip)
 {
     QLabel *label = new QLabel(name);
diff --git a/src/plugins/projectexplorer/kitmanagerconfigwidget.h b/src/plugins/projectexplorer/kitmanagerconfigwidget.h
index 1fcf346dc0c..13aac9977ca 100644
--- a/src/plugins/projectexplorer/kitmanagerconfigwidget.h
+++ b/src/plugins/projectexplorer/kitmanagerconfigwidget.h
@@ -80,6 +80,7 @@ private slots:
     void setDisplayName();
     void workingCopyWasUpdated(ProjectExplorer::Kit *k);
     void kitWasUpdated(ProjectExplorer::Kit *k);
+    void updateMutableState();
 
 private:
     enum LayoutColumns {
@@ -101,6 +102,7 @@ private:
     bool m_isDefaultKit;
     bool m_fixingKit;
     QPixmap m_background;
+    QList<QAction *> m_actions;
 };
 
 } // namespace Internal
-- 
GitLab