forked from qt-creator/qt-creator
CMake: Improve delegates for CMake configuration
Change-Id: Ib1d2bfca1b2faafd36c53f24c6649e73ee0af190 Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
This commit is contained in:
@@ -34,9 +34,11 @@
|
||||
#include <coreplugin/icore.h>
|
||||
#include <coreplugin/find/itemviewfind.h>
|
||||
#include <projectexplorer/kitmanager.h>
|
||||
#include <projectexplorer/project.h>
|
||||
#include <projectexplorer/projectexplorer.h>
|
||||
#include <projectexplorer/target.h>
|
||||
|
||||
#include <utils/asconst.h>
|
||||
#include <utils/detailswidget.h>
|
||||
#include <utils/fancylineedit.h>
|
||||
#include <utils/headerviewstretcher.h>
|
||||
@@ -46,12 +48,14 @@
|
||||
|
||||
#include <QBoxLayout>
|
||||
#include <QCheckBox>
|
||||
#include <QComboBox>
|
||||
#include <QFrame>
|
||||
#include <QGridLayout>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <QSortFilterProxyModel>
|
||||
#include <QSpacerItem>
|
||||
#include <QStyledItemDelegate>
|
||||
#include <QMenu>
|
||||
|
||||
namespace CMakeProjectManager {
|
||||
@@ -161,7 +165,8 @@ CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeBuildConfiguration *bc)
|
||||
m_configView->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
m_configView->setSelectionBehavior(QAbstractItemView::SelectItems);
|
||||
m_configView->setFrameShape(QFrame::NoFrame);
|
||||
m_configView->setItemDelegate(new ConfigModelItemDelegate(m_configView));
|
||||
m_configView->setItemDelegate(new ConfigModelItemDelegate(m_buildConfiguration->project()->projectDirectory(),
|
||||
m_configView));
|
||||
QFrame *findWrapper = Core::ItemViewFind::createSearchableWrapper(m_configView, Core::ItemViewFind::LightColored);
|
||||
findWrapper->setFrameStyle(QFrame::StyledPanel);
|
||||
|
||||
@@ -221,14 +226,17 @@ CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeBuildConfiguration *bc)
|
||||
|
||||
if (m_buildConfiguration->isParsing())
|
||||
m_showProgressTimer.start();
|
||||
else
|
||||
else {
|
||||
m_configModel->setConfiguration(m_buildConfiguration->completeCMakeConfiguration());
|
||||
m_configView->expandAll();
|
||||
}
|
||||
|
||||
connect(m_buildConfiguration->target()->project(), &ProjectExplorer::Project::parsingFinished,
|
||||
this, [this, buildDirChooser, stretcher]() {
|
||||
updateButtonState();
|
||||
m_configModel->setConfiguration(m_buildConfiguration->completeCMakeConfiguration());
|
||||
m_configView->expandAll();
|
||||
stretcher->stretch();
|
||||
updateButtonState();
|
||||
buildDirChooser->triggerChanged(); // refresh valid state...
|
||||
m_showProgressTimer.stop();
|
||||
m_progressIndicator->hide();
|
||||
@@ -238,6 +246,10 @@ CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeBuildConfiguration *bc)
|
||||
m_showProgressTimer.stop();
|
||||
m_progressIndicator->hide();
|
||||
});
|
||||
connect(m_configTextFilterModel, &QAbstractItemModel::modelReset, this, [this, stretcher]() {
|
||||
m_configView->expandAll();
|
||||
stretcher->stretch();
|
||||
});
|
||||
|
||||
connect(m_configModel, &QAbstractItemModel::dataChanged,
|
||||
this, &CMakeBuildSettingsWidget::updateButtonState);
|
||||
@@ -321,10 +333,15 @@ void CMakeBuildSettingsWidget::updateButtonState()
|
||||
|
||||
void CMakeBuildSettingsWidget::updateAdvancedCheckBox()
|
||||
{
|
||||
if (m_showAdvancedCheckBox->isChecked())
|
||||
if (m_showAdvancedCheckBox->isChecked()) {
|
||||
m_configFilterModel->setSourceModel(nullptr);
|
||||
m_configTextFilterModel->setSourceModel(m_configModel);
|
||||
else
|
||||
|
||||
} else {
|
||||
m_configTextFilterModel->setSourceModel(nullptr);
|
||||
m_configFilterModel->setSourceModel(m_configModel);
|
||||
m_configTextFilterModel->setSourceModel(m_configFilterModel);
|
||||
}
|
||||
}
|
||||
|
||||
void CMakeBuildSettingsWidget::updateFromKit()
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <QCoreApplication>
|
||||
#include <QFont>
|
||||
#include <QString>
|
||||
#include <QSortFilterProxyModel>
|
||||
|
||||
namespace CMakeProjectManager {
|
||||
|
||||
@@ -154,6 +155,37 @@ void ConfigModel::forceToString(const QModelIndex &idx)
|
||||
emit dataChanged(valueIdx, valueIdx);
|
||||
}
|
||||
|
||||
ConfigModel::DataItem ConfigModel::dataItemFromIndex(const QModelIndex &idx)
|
||||
{
|
||||
const QAbstractItemModel *m = idx.model();
|
||||
QModelIndex mIdx = idx;
|
||||
while (auto sfpm = qobject_cast<const QSortFilterProxyModel *>(m)) {
|
||||
m = sfpm->sourceModel();
|
||||
mIdx = sfpm->mapToSource(mIdx);
|
||||
}
|
||||
auto model = qobject_cast<const ConfigModel *>(m);
|
||||
QTC_ASSERT(model, return DataItem());
|
||||
const QModelIndex modelIdx = mIdx;
|
||||
|
||||
Utils::TreeItem *item = model->itemForIndex(modelIdx);
|
||||
auto cmti = dynamic_cast<Internal::ConfigModelTreeItem *>(item);
|
||||
|
||||
if (cmti && cmti->dataItem) {
|
||||
DataItem di;
|
||||
di.key = cmti->dataItem->key;
|
||||
di.type = cmti->dataItem->type;
|
||||
di.isHidden = cmti->dataItem->isHidden;
|
||||
di.isAdvanced = cmti->dataItem->isAdvanced;
|
||||
di.inCMakeCache = cmti->dataItem->inCMakeCache;
|
||||
di.value = cmti->dataItem->currentValue();
|
||||
di.description = cmti->dataItem->description;
|
||||
di.values = cmti->dataItem->values;
|
||||
|
||||
return di;
|
||||
}
|
||||
return DataItem();
|
||||
}
|
||||
|
||||
QList<ConfigModel::DataItem> ConfigModel::configurationChanges() const
|
||||
{
|
||||
const QList<InternalDataItem> tmp
|
||||
@@ -303,10 +335,6 @@ QVariant ConfigModelTreeItem::data(int column, int role) const
|
||||
}
|
||||
|
||||
// Leaf node:
|
||||
if (role == ConfigModel::ItemTypeRole)
|
||||
return dataItem->type;
|
||||
if (role == ConfigModel::ItemValuesRole)
|
||||
return dataItem->values;
|
||||
if (role == ConfigModel::ItemIsAdvancedRole)
|
||||
return dataItem->isAdvanced ? "1" : "0";
|
||||
|
||||
|
||||
@@ -38,9 +38,7 @@ class ConfigModel : public Utils::TreeModel<>
|
||||
|
||||
public:
|
||||
enum Roles {
|
||||
ItemTypeRole = Qt::UserRole,
|
||||
ItemValuesRole,
|
||||
ItemIsAdvancedRole
|
||||
ItemIsAdvancedRole = Qt::UserRole,
|
||||
};
|
||||
|
||||
class DataItem {
|
||||
@@ -78,6 +76,8 @@ public:
|
||||
bool canForceToString(const QModelIndex &idx) const;
|
||||
void forceToString(const QModelIndex &idx);
|
||||
|
||||
static DataItem dataItemFromIndex(const QModelIndex &idx);
|
||||
|
||||
QList<DataItem> configurationChanges() const;
|
||||
|
||||
private:
|
||||
|
||||
@@ -19,59 +19,117 @@
|
||||
#include "configmodelitemdelegate.h"
|
||||
#include "configmodel.h"
|
||||
|
||||
#include <utils/asconst.h>
|
||||
#include <utils/pathchooser.h>
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QCheckBox>
|
||||
#include <QLineEdit>
|
||||
#include <QPainter>
|
||||
|
||||
namespace CMakeProjectManager {
|
||||
|
||||
ConfigModelItemDelegate::ConfigModelItemDelegate(QObject* parent)
|
||||
ConfigModelItemDelegate::ConfigModelItemDelegate(const Utils::FileName &base, QObject* parent)
|
||||
: QStyledItemDelegate(parent)
|
||||
, m_base(base)
|
||||
{ }
|
||||
|
||||
ConfigModelItemDelegate::~ConfigModelItemDelegate()
|
||||
{ }
|
||||
QWidget *ConfigModelItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const
|
||||
|
||||
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);
|
||||
if (index.column() == 1) {
|
||||
ConfigModel::DataItem data = ConfigModel::dataItemFromIndex(index);
|
||||
if (data.type == ConfigModel::DataItem::FILE || data.type == ConfigModel::DataItem::DIRECTORY) {
|
||||
auto edit = new Utils::PathChooser(parent);
|
||||
edit->setFocusPolicy(Qt::StrongFocus);
|
||||
edit->setBaseFileName(m_base);
|
||||
edit->setAutoFillBackground(true);
|
||||
if (data.type == ConfigModel::DataItem::FILE) {
|
||||
edit->setExpectedKind(Utils::PathChooser::File);
|
||||
edit->setPromptDialogTitle(tr("Select a file for %1").arg(data.key));
|
||||
} else {
|
||||
edit->setExpectedKind(Utils::PathChooser::Directory);
|
||||
edit->setPromptDialogTitle(tr("Select a directory for %1").arg(data.key));
|
||||
}
|
||||
return edit;
|
||||
} else if (!data.values.isEmpty()) {
|
||||
auto edit = new QComboBox(parent);
|
||||
edit->setFocusPolicy(Qt::StrongFocus);
|
||||
for (const QString &s : Utils::asConst(data.values))
|
||||
edit->addItem(s);
|
||||
return edit;
|
||||
} else if (data.type == ConfigModel::DataItem::BOOLEAN) {
|
||||
auto edit = new QCheckBox(parent);
|
||||
edit->setFocusPolicy(Qt::StrongFocus);
|
||||
return edit;
|
||||
} else if (data.type == ConfigModel::DataItem::STRING) {
|
||||
auto edit = new QLineEdit(parent);
|
||||
edit->setFocusPolicy(Qt::StrongFocus);
|
||||
return edit;
|
||||
}
|
||||
}
|
||||
|
||||
return QStyledItemDelegate::createEditor(parent, option, index);
|
||||
}
|
||||
|
||||
void ConfigModelItemDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const
|
||||
void ConfigModelItemDelegate::setEditorData(QWidget *editor, 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);
|
||||
if (index.column() == 1) {
|
||||
ConfigModel::DataItem data = ConfigModel::dataItemFromIndex(index);
|
||||
if (data.type == ConfigModel::DataItem::FILE || data.type == ConfigModel::DataItem::DIRECTORY) {
|
||||
auto edit = static_cast<Utils::PathChooser *>(editor);
|
||||
edit->setFileName(Utils::FileName::fromUserInput(data.value));
|
||||
return;
|
||||
} else if (!data.values.isEmpty()) {
|
||||
auto edit = static_cast<QComboBox *>(editor);
|
||||
edit->setCurrentText(data.value);
|
||||
return;
|
||||
} else if (data.type == ConfigModel::DataItem::BOOLEAN) {
|
||||
auto edit = static_cast<QCheckBox *>(editor);
|
||||
edit->setChecked(index.data(Qt::CheckStateRole).toBool());
|
||||
edit->setText(data.value);
|
||||
return;
|
||||
} else if (data.type == ConfigModel::DataItem::STRING) {
|
||||
auto edit = static_cast<QLineEdit *>(editor);
|
||||
edit->setText(data.value);
|
||||
return;
|
||||
}
|
||||
}
|
||||
QStyledItemDelegate::setEditorData(editor, index);
|
||||
}
|
||||
|
||||
void ConfigModelItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
|
||||
const QModelIndex &index) const
|
||||
{
|
||||
if (index.column() == 1) {
|
||||
ConfigModel::DataItem data = ConfigModel::dataItemFromIndex(index);
|
||||
if (data.type == ConfigModel::DataItem::FILE || data.type == ConfigModel::DataItem::DIRECTORY) {
|
||||
auto edit = static_cast<Utils::PathChooser *>(editor);
|
||||
if (edit->rawPath() != data.value)
|
||||
model->setData(index, edit->fileName().toUserOutput(), Qt::EditRole);
|
||||
return;
|
||||
} else if (!data.values.isEmpty()) {
|
||||
auto edit = static_cast<QComboBox *>(editor);
|
||||
model->setData(index, edit->currentText(), Qt::EditRole);
|
||||
return;
|
||||
} else if (data.type == ConfigModel::DataItem::BOOLEAN) {
|
||||
auto edit = static_cast<QCheckBox *>(editor);
|
||||
model->setData(index, edit->text(), Qt::EditRole);
|
||||
} else if (data.type == ConfigModel::DataItem::STRING) {
|
||||
auto edit = static_cast<QLineEdit *>(editor);
|
||||
model->setData(index, edit->text(), Qt::EditRole);
|
||||
}
|
||||
}
|
||||
QStyledItemDelegate::setModelData(editor, model, index);
|
||||
}
|
||||
|
||||
QSize CMakeProjectManager::ConfigModelItemDelegate::sizeHint(const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const
|
||||
{
|
||||
Q_UNUSED(option);
|
||||
Q_UNUSED(index);
|
||||
return QSize(100, m_measurement.sizeHint().height());
|
||||
}
|
||||
|
||||
} // namespace CMakeProjectManager
|
||||
|
||||
@@ -18,20 +18,30 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QStyledItemDelegate>
|
||||
|
||||
#include <utils/fileutils.h>
|
||||
|
||||
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;
|
||||
public:
|
||||
ConfigModelItemDelegate(const Utils::FileName &base, QObject *parent = nullptr);
|
||||
|
||||
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const final;
|
||||
void setEditorData(QWidget *editor, const QModelIndex &index) const final;
|
||||
void setModelData(QWidget *editor, QAbstractItemModel *model,
|
||||
const QModelIndex &index) const final;
|
||||
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const final;
|
||||
|
||||
private:
|
||||
Utils::FileName m_base;
|
||||
QComboBox m_measurement;
|
||||
};
|
||||
|
||||
} // namespace CMakeProjectManager
|
||||
|
||||
Reference in New Issue
Block a user