forked from qt-creator/qt-creator
CMakeProjectManager: Support drop down selector for options
CMake provides "hack" for cmake-gui, that allows set options variants and select then from drop down list. Allows Qt Creator re-use this solution. See: - https://blog.kitware.com/constraining-values-with-comboboxes-in-cmake-cmake-gui/ - http://blog.bethcodes.com/cmake-tips-tricks-drop-down-list Drop down values can be added to option via: SET_PROPERTY(CACHE OptionName PROPERTY STRINGS Option1 Option2 Option3) This solution should not restrict to provide any other value, it provides only suggestion for user to select one of prdefined values. Change-Id: I8fc52155775f1e04979db8206bb42363df9359e8 Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
This commit is contained in:
@@ -794,6 +794,7 @@ CMakeConfig BuildDirManager::parseConfiguration(const Utils::FileName &cacheFile
|
|||||||
}
|
}
|
||||||
|
|
||||||
QSet<QByteArray> advancedSet;
|
QSet<QByteArray> advancedSet;
|
||||||
|
QMap<QByteArray, QByteArray> valuesMap;
|
||||||
QByteArray documentation;
|
QByteArray documentation;
|
||||||
while (!cache.atEnd()) {
|
while (!cache.atEnd()) {
|
||||||
const QByteArray line = trimCMakeCacheLine(cache.readLine());
|
const QByteArray line = trimCMakeCacheLine(cache.readLine());
|
||||||
@@ -817,6 +818,8 @@ CMakeConfig BuildDirManager::parseConfiguration(const Utils::FileName &cacheFile
|
|||||||
|
|
||||||
if (key.endsWith("-ADVANCED") && value == "1") {
|
if (key.endsWith("-ADVANCED") && value == "1") {
|
||||||
advancedSet.insert(key.left(key.count() - 9 /* "-ADVANCED" */));
|
advancedSet.insert(key.left(key.count() - 9 /* "-ADVANCED" */));
|
||||||
|
} else if (key.endsWith("-STRINGS") && fromByteArray(type) == CMakeConfigItem::INTERNAL) {
|
||||||
|
valuesMap[key.left(key.count() - 8) /* "-STRINGS" */] = value;
|
||||||
} else {
|
} else {
|
||||||
CMakeConfigItem::Type t = fromByteArray(type);
|
CMakeConfigItem::Type t = fromByteArray(type);
|
||||||
result << CMakeConfigItem(key, t, documentation, value);
|
result << CMakeConfigItem(key, t, documentation, value);
|
||||||
@@ -827,6 +830,13 @@ CMakeConfig BuildDirManager::parseConfiguration(const Utils::FileName &cacheFile
|
|||||||
for (int i = 0; i < result.count(); ++i) {
|
for (int i = 0; i < result.count(); ++i) {
|
||||||
CMakeConfigItem &item = result[i];
|
CMakeConfigItem &item = result[i];
|
||||||
item.isAdvanced = advancedSet.contains(item.key);
|
item.isAdvanced = advancedSet.contains(item.key);
|
||||||
|
|
||||||
|
if (valuesMap.contains(item.key)) {
|
||||||
|
item.values = CMakeConfigItem::cmakeSplitValue(QString::fromUtf8(valuesMap[item.key]));
|
||||||
|
} else if (item.key == "CMAKE_BUILD_TYPE") {
|
||||||
|
// WA for known options
|
||||||
|
item.values << "" << "Debug" << "Release" << "MinSizeRel" << "RelWithDebInfo";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Utils::sort(result, CMakeConfigItem::sortOperator());
|
Utils::sort(result, CMakeConfigItem::sortOperator());
|
||||||
|
|||||||
@@ -245,6 +245,7 @@ QList<ConfigModel::DataItem> CMakeBuildConfiguration::completeCMakeConfiguration
|
|||||||
j.key = QString::fromUtf8(i.key);
|
j.key = QString::fromUtf8(i.key);
|
||||||
j.value = QString::fromUtf8(i.value);
|
j.value = QString::fromUtf8(i.value);
|
||||||
j.description = QString::fromUtf8(i.documentation);
|
j.description = QString::fromUtf8(i.documentation);
|
||||||
|
j.values = i.values;
|
||||||
|
|
||||||
j.isAdvanced = i.isAdvanced || i.type == CMakeConfigItem::INTERNAL;
|
j.isAdvanced = i.isAdvanced || i.type == CMakeConfigItem::INTERNAL;
|
||||||
switch (i.type) {
|
switch (i.type) {
|
||||||
@@ -280,6 +281,7 @@ void CMakeBuildConfiguration::setCurrentCMakeConfiguration(const QList<ConfigMod
|
|||||||
ni.value = i.value.toUtf8();
|
ni.value = i.value.toUtf8();
|
||||||
ni.documentation = i.description.toUtf8();
|
ni.documentation = i.description.toUtf8();
|
||||||
ni.isAdvanced = i.isAdvanced;
|
ni.isAdvanced = i.isAdvanced;
|
||||||
|
ni.values = i.values;
|
||||||
switch (i.type) {
|
switch (i.type) {
|
||||||
case CMakeProjectManager::ConfigModel::DataItem::BOOLEAN:
|
case CMakeProjectManager::ConfigModel::DataItem::BOOLEAN:
|
||||||
ni.type = CMakeConfigItem::BOOL;
|
ni.type = CMakeConfigItem::BOOL;
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
#include "cmakebuildsettingswidget.h"
|
#include "cmakebuildsettingswidget.h"
|
||||||
|
|
||||||
#include "configmodel.h"
|
#include "configmodel.h"
|
||||||
|
#include "configmodelitemdelegate.h"
|
||||||
#include "cmakeproject.h"
|
#include "cmakeproject.h"
|
||||||
#include "cmakebuildconfiguration.h"
|
#include "cmakebuildconfiguration.h"
|
||||||
|
|
||||||
@@ -140,6 +141,7 @@ CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeBuildConfiguration *bc)
|
|||||||
m_configView->setSelectionBehavior(QAbstractItemView::SelectItems);
|
m_configView->setSelectionBehavior(QAbstractItemView::SelectItems);
|
||||||
m_configView->setFrameShape(QFrame::NoFrame);
|
m_configView->setFrameShape(QFrame::NoFrame);
|
||||||
m_configView->hideColumn(2); // Hide isAdvanced column
|
m_configView->hideColumn(2); // Hide isAdvanced column
|
||||||
|
m_configView->setItemDelegate(new ConfigModelItemDelegate(m_configView));
|
||||||
QFrame *findWrapper = Core::ItemViewFind::createSearchableWrapper(m_configView, Core::ItemViewFind::LightColored);
|
QFrame *findWrapper = Core::ItemViewFind::createSearchableWrapper(m_configView, Core::ItemViewFind::LightColored);
|
||||||
findWrapper->setFrameStyle(QFrame::StyledPanel);
|
findWrapper->setFrameStyle(QFrame::StyledPanel);
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ CMakeConfigItem::CMakeConfigItem() = default;
|
|||||||
|
|
||||||
CMakeConfigItem::CMakeConfigItem(const CMakeConfigItem &other) :
|
CMakeConfigItem::CMakeConfigItem(const CMakeConfigItem &other) :
|
||||||
key(other.key), type(other.type), isAdvanced(other.isAdvanced),
|
key(other.key), type(other.type), isAdvanced(other.isAdvanced),
|
||||||
value(other.value), documentation(other.documentation)
|
value(other.value), documentation(other.documentation), values(other.values)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
CMakeConfigItem::CMakeConfigItem(const QByteArray &k, Type t,
|
CMakeConfigItem::CMakeConfigItem(const QByteArray &k, Type t,
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ public:
|
|||||||
bool isAdvanced = false;
|
bool isAdvanced = false;
|
||||||
QByteArray value; // converted to string as needed
|
QByteArray value; // converted to string as needed
|
||||||
QByteArray documentation;
|
QByteArray documentation;
|
||||||
|
QStringList values;
|
||||||
};
|
};
|
||||||
using CMakeConfig = QList<CMakeConfigItem>;
|
using CMakeConfig = QList<CMakeConfigItem>;
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,8 @@ HEADERS = builddirmanager.h \
|
|||||||
cmakebuildsettingswidget.h \
|
cmakebuildsettingswidget.h \
|
||||||
cmakeindenter.h \
|
cmakeindenter.h \
|
||||||
cmakeautocompleter.h \
|
cmakeautocompleter.h \
|
||||||
configmodel.h
|
configmodel.h \
|
||||||
|
configmodelitemdelegate.h
|
||||||
|
|
||||||
SOURCES = builddirmanager.cpp \
|
SOURCES = builddirmanager.cpp \
|
||||||
cmakebuildstep.cpp \
|
cmakebuildstep.cpp \
|
||||||
@@ -54,6 +55,7 @@ SOURCES = builddirmanager.cpp \
|
|||||||
cmakebuildsettingswidget.cpp \
|
cmakebuildsettingswidget.cpp \
|
||||||
cmakeindenter.cpp \
|
cmakeindenter.cpp \
|
||||||
cmakeautocompleter.cpp \
|
cmakeautocompleter.cpp \
|
||||||
configmodel.cpp
|
configmodel.cpp \
|
||||||
|
configmodelitemdelegate.cpp
|
||||||
|
|
||||||
RESOURCES += cmakeproject.qrc
|
RESOURCES += cmakeproject.qrc
|
||||||
|
|||||||
@@ -71,6 +71,8 @@ QtcPlugin {
|
|||||||
"cmakeautocompleter.h",
|
"cmakeautocompleter.h",
|
||||||
"cmakeautocompleter.cpp",
|
"cmakeautocompleter.cpp",
|
||||||
"configmodel.cpp",
|
"configmodel.cpp",
|
||||||
"configmodel.h"
|
"configmodel.h",
|
||||||
|
"configmodelitemdelegate.cpp",
|
||||||
|
"configmodelitemdelegate.h"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -88,6 +88,15 @@ QVariant ConfigModel::data(const QModelIndex &index, int role) const
|
|||||||
|
|
||||||
const InternalDataItem &item = m_configuration[index.row()];
|
const InternalDataItem &item = m_configuration[index.row()];
|
||||||
|
|
||||||
|
if (index.column() < 2) {
|
||||||
|
switch (role) {
|
||||||
|
case ItemTypeRole:
|
||||||
|
return item.type;
|
||||||
|
case ItemValuesRole:
|
||||||
|
return item.values;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (index.column()) {
|
switch (index.column()) {
|
||||||
case 0:
|
case 0:
|
||||||
switch (role) {
|
switch (role) {
|
||||||
@@ -97,8 +106,6 @@ QVariant ConfigModel::data(const QModelIndex &index, int role) const
|
|||||||
return item.key;
|
return item.key;
|
||||||
case Qt::ToolTipRole:
|
case Qt::ToolTipRole:
|
||||||
return item.description;
|
return item.description;
|
||||||
case Qt::UserRole:
|
|
||||||
return item.type;
|
|
||||||
case Qt::FontRole: {
|
case Qt::FontRole: {
|
||||||
QFont font;
|
QFont font;
|
||||||
font.setItalic(item.isCMakeChanged);
|
font.setItalic(item.isCMakeChanged);
|
||||||
@@ -126,8 +133,6 @@ QVariant ConfigModel::data(const QModelIndex &index, int role) const
|
|||||||
}
|
}
|
||||||
case Qt::ToolTipRole:
|
case Qt::ToolTipRole:
|
||||||
return item.description;
|
return item.description;
|
||||||
case Qt::UserRole:
|
|
||||||
return item.type;
|
|
||||||
default:
|
default:
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
@@ -209,13 +214,15 @@ QVariant ConfigModel::headerData(int section, Qt::Orientation orientation, int r
|
|||||||
void ConfigModel::appendConfiguration(const QString &key,
|
void ConfigModel::appendConfiguration(const QString &key,
|
||||||
const QString &value,
|
const QString &value,
|
||||||
const ConfigModel::DataItem::Type type,
|
const ConfigModel::DataItem::Type type,
|
||||||
const QString &description)
|
const QString &description,
|
||||||
|
const QStringList &values)
|
||||||
{
|
{
|
||||||
DataItem item;
|
DataItem item;
|
||||||
item.key = key;
|
item.key = key;
|
||||||
item.type = type;
|
item.type = type;
|
||||||
item.value = value;
|
item.value = value;
|
||||||
item.description = description;
|
item.description = description;
|
||||||
|
item.values = values;
|
||||||
|
|
||||||
InternalDataItem internalItem(item);
|
InternalDataItem internalItem(item);
|
||||||
internalItem.isUserNew = true;
|
internalItem.isUserNew = true;
|
||||||
|
|||||||
@@ -34,6 +34,11 @@ class ConfigModel : public QAbstractTableModel
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
enum Roles {
|
||||||
|
ItemTypeRole = Qt::UserRole,
|
||||||
|
ItemValuesRole
|
||||||
|
};
|
||||||
|
|
||||||
class DataItem {
|
class DataItem {
|
||||||
public:
|
public:
|
||||||
enum Type { BOOLEAN, FILE, DIRECTORY, STRING, UNKNOWN};
|
enum Type { BOOLEAN, FILE, DIRECTORY, STRING, UNKNOWN};
|
||||||
@@ -43,6 +48,7 @@ public:
|
|||||||
bool isAdvanced = false;
|
bool isAdvanced = false;
|
||||||
QString value;
|
QString value;
|
||||||
QString description;
|
QString description;
|
||||||
|
QStringList values;
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit ConfigModel(QObject *parent = nullptr);
|
explicit ConfigModel(QObject *parent = nullptr);
|
||||||
@@ -58,7 +64,8 @@ public:
|
|||||||
void appendConfiguration(const QString &key,
|
void appendConfiguration(const QString &key,
|
||||||
const QString &value = QString(),
|
const QString &value = QString(),
|
||||||
const DataItem::Type type = DataItem::UNKNOWN,
|
const DataItem::Type type = DataItem::UNKNOWN,
|
||||||
const QString &description = QString());
|
const QString &description = QString(),
|
||||||
|
const QStringList &values = QStringList());
|
||||||
void setConfiguration(const QList<DataItem> &config);
|
void setConfiguration(const QList<DataItem> &config);
|
||||||
void flush();
|
void flush();
|
||||||
void resetAllChanges();
|
void resetAllChanges();
|
||||||
|
|||||||
78
src/plugins/cmakeprojectmanager/configmodelitemdelegate.cpp
Normal file
78
src/plugins/cmakeprojectmanager/configmodelitemdelegate.cpp
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2016 Alexander Drozdov.
|
||||||
|
** Contact: adrozdoff@gmail.com
|
||||||
|
**
|
||||||
|
** This file is part of CMakeProjectManager2 plugin.
|
||||||
|
**
|
||||||
|
** 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 or version 3 as published by the Free
|
||||||
|
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||||
|
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||||
|
** following information to ensure the GNU Lesser General Public License
|
||||||
|
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||||
|
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "configmodelitemdelegate.h"
|
||||||
|
#include "configmodel.h"
|
||||||
|
|
||||||
|
#include <QComboBox>
|
||||||
|
|
||||||
|
namespace CMakeProjectManager {
|
||||||
|
|
||||||
|
ConfigModelItemDelegate::ConfigModelItemDelegate(QObject* parent)
|
||||||
|
: QStyledItemDelegate(parent)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
ConfigModelItemDelegate::~ConfigModelItemDelegate()
|
||||||
|
{ }
|
||||||
|
|
||||||
|
QWidget* ConfigModelItemDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const
|
||||||
|
{
|
||||||
|
// ComboBox ony in column 2
|
||||||
|
if (index.column() != 1)
|
||||||
|
return QStyledItemDelegate::createEditor(parent, option, index);
|
||||||
|
|
||||||
|
auto model = index.model();
|
||||||
|
auto values = model->data(index, ConfigModel::ItemValuesRole).toStringList();
|
||||||
|
if (values.isEmpty())
|
||||||
|
return QStyledItemDelegate::createEditor(parent, option, index);
|
||||||
|
|
||||||
|
// Create the combobox and populate it
|
||||||
|
auto cb = new QComboBox(parent);
|
||||||
|
cb->addItems(values);
|
||||||
|
cb->setEditable(true);
|
||||||
|
|
||||||
|
return cb;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigModelItemDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const
|
||||||
|
{
|
||||||
|
if (QComboBox* cb = qobject_cast<QComboBox*>(editor)) {
|
||||||
|
// get the index of the text in the combobox that matches the current value of the itenm
|
||||||
|
QString currentText = index.data(Qt::EditRole).toString();
|
||||||
|
int cbIndex = cb->findText(currentText);
|
||||||
|
// if it is valid, adjust the combobox
|
||||||
|
if (cbIndex >= 0)
|
||||||
|
cb->setCurrentIndex(cbIndex);
|
||||||
|
else
|
||||||
|
cb->setEditText(currentText);
|
||||||
|
} else {
|
||||||
|
QStyledItemDelegate::setEditorData(editor, index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigModelItemDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const
|
||||||
|
{
|
||||||
|
if (QComboBox* cb = qobject_cast<QComboBox*>(editor))
|
||||||
|
// save the current text of the combo box as the current value of the item
|
||||||
|
model->setData(index, cb->currentText(), Qt::EditRole);
|
||||||
|
else
|
||||||
|
QStyledItemDelegate::setModelData(editor, model, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace CMakeProjectManager
|
||||||
|
|
||||||
37
src/plugins/cmakeprojectmanager/configmodelitemdelegate.h
Normal file
37
src/plugins/cmakeprojectmanager/configmodelitemdelegate.h
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2016 Alexander Drozdov.
|
||||||
|
** Contact: adrozdoff@gmail.com
|
||||||
|
**
|
||||||
|
** This file is part of CMakeProjectManager2 plugin.
|
||||||
|
**
|
||||||
|
** 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 or version 3 as published by the Free
|
||||||
|
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||||
|
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||||
|
** following information to ensure the GNU Lesser General Public License
|
||||||
|
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||||
|
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QStyledItemDelegate>
|
||||||
|
|
||||||
|
namespace CMakeProjectManager {
|
||||||
|
|
||||||
|
class ConfigModelItemDelegate : public QStyledItemDelegate
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
ConfigModelItemDelegate(QObject* parent=0);
|
||||||
|
~ConfigModelItemDelegate();
|
||||||
|
|
||||||
|
QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const override;
|
||||||
|
void setEditorData(QWidget* editor, const QModelIndex& index) const override;
|
||||||
|
void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace CMakeProjectManager
|
||||||
Reference in New Issue
Block a user