From dfec256dfff5af3fcd0ee47c8832d7ae600fd6c2 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Thu, 14 Sep 2017 13:16:10 +0200 Subject: [PATCH] CMake: Allow CMake configuration to be forced to string type This allows editing values with misidentified types in Project Mode. Change-Id: Ic74da2ca71cc9046cbbeb1202075976c9edd28b7 Reviewed-by: Tim Jenssen --- .../cmakebuildsettingswidget.cpp | 30 +++++++++++++++++++ .../cmakebuildsettingswidget.h | 2 ++ .../cmakeprojectmanager/configmodel.cpp | 20 +++++++++++++ src/plugins/cmakeprojectmanager/configmodel.h | 3 ++ 4 files changed, 55 insertions(+) diff --git a/src/plugins/cmakeprojectmanager/cmakebuildsettingswidget.cpp b/src/plugins/cmakeprojectmanager/cmakebuildsettingswidget.cpp index fe4f1be9df7..c2a236136e9 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildsettingswidget.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildsettingswidget.cpp @@ -140,6 +140,8 @@ CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeBuildConfiguration *bc) tree, [tree](const QModelIndex &idx) { tree->edit(idx); }); m_configView = tree; + m_configView->viewport()->installEventFilter(this); + m_configFilterModel->setSourceModel(m_configModel); m_configFilterModel->setFilterKeyColumn(0); m_configFilterModel->setFilterRole(ConfigModel::ItemIsAdvancedRole); @@ -339,6 +341,9 @@ void CMakeBuildSettingsWidget::updateFromKit() static QModelIndex mapToSource(const QAbstractItemView *view, const QModelIndex &idx) { + if (!idx.isValid()) + return idx; + QAbstractItemModel *model = view->model(); QModelIndex result = idx; while (QSortFilterProxyModel *proxy = qobject_cast(model)) { @@ -356,5 +361,30 @@ void CMakeBuildSettingsWidget::updateSelection(const QModelIndex ¤t, const m_editButton->setEnabled(currentModelIndex.flags().testFlag(Qt::ItemIsEditable)); } +bool CMakeBuildSettingsWidget::eventFilter(QObject *target, QEvent *event) +{ + // handle context menu events: + if (target != m_configView->viewport() || event->type() != QEvent::ContextMenu) + return false; + + auto e = static_cast(event); + const QModelIndex idx = mapToSource(m_configView, m_configView->indexAt(e->pos())); + if (!idx.isValid()) + return false; + + QMenu *menu = new QMenu(this); + connect(menu, &QMenu::triggered, menu, &QMenu::deleteLater); + + QAction *forceToStringAction = new QAction(tr("Force to String")); + forceToStringAction->setEnabled(m_configModel->canForceToString(idx)); + menu->addAction(forceToStringAction); + connect(forceToStringAction, &QAction::triggered, this, [this, idx]() { m_configModel->forceToString(idx); }); + + menu->move(e->globalPos()); + menu->show(); + + return true; +} + } // namespace Internal } // namespace CMakeProjectManager diff --git a/src/plugins/cmakeprojectmanager/cmakebuildsettingswidget.h b/src/plugins/cmakeprojectmanager/cmakebuildsettingswidget.h index 27ddb792474..a15cfe6e0aa 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildsettingswidget.h +++ b/src/plugins/cmakeprojectmanager/cmakebuildsettingswidget.h @@ -66,6 +66,8 @@ private: void updateSelection(const QModelIndex ¤t, const QModelIndex &previous); + bool eventFilter(QObject *target, QEvent *event); + CMakeBuildConfiguration *m_buildConfiguration; QTreeView *m_configView; ConfigModel *m_configModel; diff --git a/src/plugins/cmakeprojectmanager/configmodel.cpp b/src/plugins/cmakeprojectmanager/configmodel.cpp index 256bb624fd9..0ab1b6c25ba 100644 --- a/src/plugins/cmakeprojectmanager/configmodel.cpp +++ b/src/plugins/cmakeprojectmanager/configmodel.cpp @@ -134,6 +134,26 @@ bool ConfigModel::hasCMakeChanges() const return Utils::contains(m_configuration, [](const InternalDataItem &i) { return i.isCMakeChanged; }); } +bool ConfigModel::canForceToString(const QModelIndex &idx) const +{ + if (idx.model() != const_cast(this) || idx.column() != 1) + return false; + Utils::TreeItem *item = itemForIndex(idx); + auto cmti = dynamic_cast(item); + return cmti && (cmti->dataItem->type != DataItem::STRING); +} + +void ConfigModel::forceToString(const QModelIndex &idx) +{ + QTC_ASSERT(canForceToString(idx), return); + Utils::TreeItem *item = itemForIndex(idx); + auto cmti = dynamic_cast(item); + + cmti->dataItem->type = DataItem::STRING; + const QModelIndex valueIdx = idx.sibling(1, idx.column()); + emit dataChanged(valueIdx, valueIdx); +} + QList ConfigModel::configurationChanges() const { const QList tmp diff --git a/src/plugins/cmakeprojectmanager/configmodel.h b/src/plugins/cmakeprojectmanager/configmodel.h index f9b5b67ae69..0bb06f59b50 100644 --- a/src/plugins/cmakeprojectmanager/configmodel.h +++ b/src/plugins/cmakeprojectmanager/configmodel.h @@ -75,6 +75,9 @@ public: bool hasChanges() const; bool hasCMakeChanges() const; + bool canForceToString(const QModelIndex &idx) const; + void forceToString(const QModelIndex &idx); + QList configurationChanges() const; private: