forked from qt-creator/qt-creator
Wizards: add IconListField
- reuse some code from ComboBoxField throw an abstract ListField class - ListField can handle more data like: icon, trToolTip - fix disabledIndex in ComboBoxField - adjust documentation Change-Id: I00b6ab787fb2fad97dafff32786cf73c636c772d Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
This commit is contained in:
@@ -730,7 +730,10 @@
|
|||||||
|
|
||||||
\endlist
|
\endlist
|
||||||
|
|
||||||
\section2 Combo Box
|
\section2 List
|
||||||
|
|
||||||
|
\note The Combo Box and Icon List types are both variations of the List type,
|
||||||
|
and therefore they can have the same properties.
|
||||||
|
|
||||||
\code
|
\code
|
||||||
{
|
{
|
||||||
@@ -744,19 +747,36 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
\endcode
|
\endcode
|
||||||
|
or
|
||||||
|
\code
|
||||||
|
{
|
||||||
|
"name": "ChosenBuildSystem",
|
||||||
|
"trDisplayName": "Choose your build system:",
|
||||||
|
"type": "IconList",
|
||||||
|
"data":
|
||||||
|
{
|
||||||
|
"items": [
|
||||||
|
{ "trKey": "Qbs", "value": "qbs", "icon": "qbs_icon.png", "trToolTip": "Building with Qbs." },
|
||||||
|
{ "trKey": "QMake", "value": "qmake", "icon": "qmake_icon.png", "trToolTip": "Building with QMake." }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
\endcode
|
||||||
|
|
||||||
\list
|
\list
|
||||||
|
|
||||||
\li \c items specifies a list of items to put into the combo box. The
|
\li \c items specifies a list of items to put into the list type. The
|
||||||
list can contain both JSON objects and plain strings. For JSON
|
list can contain both JSON objects and plain strings.
|
||||||
objects, define \c trKey and \c value pairs, where the \c trKey is
|
For JSON objects, define \c trKey and \c value pairs, where the
|
||||||
the list item visible to users and \c value contains the data
|
\c trKey is the list item visible to users and \c value contains
|
||||||
associated with the item.
|
the data associated with the item.
|
||||||
|
In addition, you can use \c icon to specify an icon for the list
|
||||||
|
item and \c trToolTip to specify a tooltip for it.
|
||||||
|
|
||||||
\li \c index specifies the index to select when the combo box is
|
\li \c index specifies the index to select when the list type is
|
||||||
enabled. By default, it is set to \c 0.
|
enabled. By default, it is set to \c 0.
|
||||||
|
|
||||||
\li \c disabledIndex specifies the index to show if the combo box is
|
\li \c disabledIndex specifies the index to show if the list type is
|
||||||
disabled.
|
disabled.
|
||||||
|
|
||||||
\endlist
|
\endlist
|
||||||
|
|||||||
@@ -33,9 +33,9 @@
|
|||||||
#include <utils/fancylineedit.h>
|
#include <utils/fancylineedit.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
#include <utils/stringutils.h>
|
#include <utils/stringutils.h>
|
||||||
#include <utils/textfieldcombobox.h>
|
|
||||||
#include <utils/theme/theme.h>
|
#include <utils/theme/theme.h>
|
||||||
|
|
||||||
|
#include <QComboBox>
|
||||||
#include <QCheckBox>
|
#include <QCheckBox>
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
@@ -46,6 +46,10 @@
|
|||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
#include <QVariantMap>
|
#include <QVariantMap>
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
|
#include <QListView>
|
||||||
|
#include <QStandardItem>
|
||||||
|
#include <QItemSelectionModel>
|
||||||
|
#include <QDir>
|
||||||
|
|
||||||
using namespace Utils;
|
using namespace Utils;
|
||||||
|
|
||||||
@@ -792,49 +796,52 @@ void CheckBoxField::initializeData(MacroExpander *expander)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
||||||
// ComboBoxFieldData:
|
// ListFieldData:
|
||||||
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
||||||
|
|
||||||
struct ComboBoxItem {
|
std::unique_ptr<QStandardItem> createStandardItemFromListItem(const QVariant &item, QString *errorMessage)
|
||||||
ComboBoxItem(const QString &k = QString(), const QString &v = QString(), const QVariant &c = true) :
|
|
||||||
key(k), value(v), condition(c)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
QString key;
|
|
||||||
QString value;
|
|
||||||
QVariant condition;
|
|
||||||
};
|
|
||||||
|
|
||||||
ComboBoxItem parseComboBoxItem(const QVariant &item, QString *errorMessage)
|
|
||||||
{
|
{
|
||||||
if (item.type() == QVariant::List) {
|
if (item.type() == QVariant::List) {
|
||||||
*errorMessage = QCoreApplication::translate("ProjectExplorer::JsonFieldPage",
|
*errorMessage = QCoreApplication::translate("ProjectExplorer::JsonFieldPage",
|
||||||
"No lists allowed inside ComboBox items list.");
|
"No JSON lists allowed inside List items.");
|
||||||
return ComboBoxItem();
|
return {};
|
||||||
} else if (item.type() == QVariant::Map) {
|
}
|
||||||
|
auto standardItem = std::make_unique<QStandardItem>();
|
||||||
|
if (item.type() == QVariant::Map) {
|
||||||
QVariantMap tmp = item.toMap();
|
QVariantMap tmp = item.toMap();
|
||||||
QString key = JsonWizardFactory::localizedString(consumeValue(tmp, QLatin1String("trKey"), QString()).toString());
|
const QString key = JsonWizardFactory::localizedString(consumeValue(tmp, "trKey", QString()).toString());
|
||||||
QString value = consumeValue(tmp, QLatin1String("value"), QString()).toString();
|
const QString value = consumeValue(tmp, "value", key).toString();
|
||||||
QVariant condition = consumeValue(tmp, QLatin1String("condition"), true);
|
|
||||||
if (key.isNull() || key.isEmpty()) {
|
if (key.isNull() || key.isEmpty()) {
|
||||||
*errorMessage = QCoreApplication::translate("ProjectExplorer::JsonFieldPage",
|
*errorMessage = QCoreApplication::translate("ProjectExplorer::JsonFieldPage",
|
||||||
"No \"key\" found in ComboBox items.");
|
"No \"key\" found in List items.");
|
||||||
return ComboBoxItem();
|
return {};
|
||||||
}
|
}
|
||||||
if (value.isNull())
|
standardItem->setText(key);
|
||||||
value = key;
|
standardItem->setData(value, ListField::ValueRole);
|
||||||
return ComboBoxItem(key, value, condition);
|
standardItem->setData(consumeValue(tmp, "condition", true), ListField::ConditionRole);
|
||||||
|
standardItem->setData(consumeValue(tmp, "icon"), ListField::IconStringRole);
|
||||||
|
standardItem->setToolTip(JsonWizardFactory::localizedString(consumeValue(tmp, "trToolTip", QString()).toString()));
|
||||||
|
warnAboutUnsupportedKeys(tmp, QString(), "List");
|
||||||
} else {
|
} else {
|
||||||
QString keyvalue = item.toString();
|
const QString keyvalue = item.toString();
|
||||||
return ComboBoxItem(keyvalue, keyvalue);
|
standardItem->setText(keyvalue);
|
||||||
|
standardItem->setData(keyvalue, ListField::ValueRole);
|
||||||
|
standardItem->setData(true, ListField::ConditionRole);
|
||||||
}
|
}
|
||||||
|
return standardItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ComboBoxField::parseData(const QVariant &data, QString *errorMessage)
|
ListField::ListField() = default;
|
||||||
|
|
||||||
|
ListField::~ListField() = default;
|
||||||
|
|
||||||
|
bool ListField::parseData(const QVariant &data, QString *errorMessage)
|
||||||
{
|
{
|
||||||
if (data.type() != QVariant::Map) {
|
if (data.type() != QVariant::Map) {
|
||||||
*errorMessage = QCoreApplication::translate("ProjectExplorer::JsonFieldPage",
|
*errorMessage = QCoreApplication::translate("ProjectExplorer::JsonFieldPage",
|
||||||
"ComboBox data is not an object.");
|
"%1(\"%2\") data is not an object.")
|
||||||
|
.arg(type(), name());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -844,118 +851,235 @@ bool ComboBoxField::parseData(const QVariant &data, QString *errorMessage)
|
|||||||
m_index = consumeValue(tmp, "index", 0).toInt(&ok);
|
m_index = consumeValue(tmp, "index", 0).toInt(&ok);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
*errorMessage = QCoreApplication::translate("ProjectExplorer::JsonFieldPage",
|
*errorMessage = QCoreApplication::translate("ProjectExplorer::JsonFieldPage",
|
||||||
"ComboBox(\"%1\") \"index\" is not an integer value.")
|
"%1(\"%2\") \"index\" is not an integer value.")
|
||||||
.arg(name());
|
.arg(type(), name());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
m_disabledIndex = consumeValue(tmp, "disabledIndex", -1).toInt(&ok);
|
m_disabledIndex = consumeValue(tmp, "disabledIndex", -1).toInt(&ok);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
*errorMessage = QCoreApplication::translate("ProjectExplorer::JsonFieldPage",
|
*errorMessage = QCoreApplication::translate("ProjectExplorer::JsonFieldPage",
|
||||||
"ComboBox(\"%1\") \"disabledIndex\" is not an integer value.")
|
"%1(\"%2\") \"disabledIndex\" is not an integer value.")
|
||||||
.arg(name());
|
.arg(type(), name());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant value = consumeValue(tmp, "items");
|
const QVariant value = consumeValue(tmp, "items");
|
||||||
if (value.isNull()) {
|
if (value.isNull()) {
|
||||||
*errorMessage = QCoreApplication::translate("ProjectExplorer::JsonFieldPage",
|
*errorMessage = QCoreApplication::translate("ProjectExplorer::JsonFieldPage",
|
||||||
"ComboBox(\"%1\") \"items\" missing.")
|
"%1(\"%2\") \"items\" missing.")
|
||||||
.arg(name());
|
.arg(type(), name());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (value.type() != QVariant::List) {
|
if (value.type() != QVariant::List) {
|
||||||
*errorMessage = QCoreApplication::translate("ProjectExplorer::JsonFieldPage",
|
*errorMessage = QCoreApplication::translate("ProjectExplorer::JsonFieldPage",
|
||||||
"ComboBox(\"%1\") \"items\" is not a list.")
|
"%1(\"%2\") \"items\" is not a JSON list.")
|
||||||
.arg(name());
|
.arg(type(), name());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (const QVariant &i, value.toList()) {
|
for (const QVariant &i : value.toList()) {
|
||||||
ComboBoxItem keyValue = parseComboBoxItem(i, errorMessage);
|
std::unique_ptr<QStandardItem> item = createStandardItemFromListItem(i, errorMessage);
|
||||||
if (keyValue.key.isNull())
|
QString test = item->text();
|
||||||
return false; // an error happened...
|
QTC_ASSERT(!item || !item->text().isEmpty(), continue);
|
||||||
m_itemList.append(keyValue.key);
|
m_itemList.emplace_back(std::move(item));
|
||||||
m_itemDataList.append(keyValue.value);
|
|
||||||
m_itemConditionList.append(keyValue.condition);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_itemConditionList.count() != m_itemDataList.count()
|
|
||||||
|| m_itemConditionList.count() != m_itemList.count()) {
|
|
||||||
m_itemConditionList.clear();
|
|
||||||
m_itemDataList.clear();
|
|
||||||
m_itemList.clear();
|
|
||||||
*errorMessage = QCoreApplication::translate("ProjectExplorer::JsonFieldPage",
|
|
||||||
"Internal Error: ComboBox(\"%1\") items lists got mixed up.")
|
|
||||||
.arg(name());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
warnAboutUnsupportedKeys(tmp, name(), type());
|
warnAboutUnsupportedKeys(tmp, name(), type());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QWidget *ComboBoxField::createWidget(const QString &displayName, JsonFieldPage *page)
|
|
||||||
{
|
|
||||||
Q_UNUSED(displayName);
|
|
||||||
Q_UNUSED(page);
|
|
||||||
return new TextFieldComboBox;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ComboBoxField::setup(JsonFieldPage *page, const QString &name)
|
bool ListField::validate(MacroExpander *expander, QString *message)
|
||||||
{
|
|
||||||
auto w = qobject_cast<TextFieldComboBox *>(widget());
|
|
||||||
QTC_ASSERT(w, return);
|
|
||||||
page->registerFieldWithName(name, w, "indexText", SIGNAL(text4Changed(QString)));
|
|
||||||
QObject::connect(w, &TextFieldComboBox::text4Changed,
|
|
||||||
page, [page](QString) { page->completeChanged(); });
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ComboBoxField::validate(MacroExpander *expander, QString *message)
|
|
||||||
{
|
{
|
||||||
if (!JsonFieldPage::Field::validate(expander, message))
|
if (!JsonFieldPage::Field::validate(expander, message))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
auto w = qobject_cast<TextFieldComboBox *>(widget());
|
updateIndex();
|
||||||
QTC_ASSERT(w, return false);
|
if (selectionModel()->hasSelection())
|
||||||
if (!w->isEnabled() && m_disabledIndex >= 0 && m_savedIndex < 0) {
|
return true;
|
||||||
m_savedIndex = w->currentIndex();
|
return false;
|
||||||
w->setCurrentIndex(m_disabledIndex);
|
|
||||||
} else if (w->isEnabled() && m_savedIndex >= 0) {
|
|
||||||
w->setCurrentIndex(m_savedIndex);
|
|
||||||
m_savedIndex = -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
void ListField::initializeData(MacroExpander *expander)
|
||||||
|
{
|
||||||
|
QTC_ASSERT(widget(), return);
|
||||||
|
|
||||||
|
QStandardItem *currentItem = m_index >= 0 ? m_itemList[uint(m_index)].get() : nullptr;
|
||||||
|
QList<QStandardItem*> expandedValuesItems;
|
||||||
|
expandedValuesItems.reserve(int(m_itemList.size()));
|
||||||
|
|
||||||
|
QSize maxIconSize;
|
||||||
|
|
||||||
|
for (const std::unique_ptr<QStandardItem> &item : m_itemList) {
|
||||||
|
bool condition = JsonWizard::boolFromVariant(item->data(ConditionRole), expander);
|
||||||
|
if (!condition)
|
||||||
|
continue;
|
||||||
|
QStandardItem *expandedValuesItem = item->clone();
|
||||||
|
if (item.get() == currentItem)
|
||||||
|
currentItem = expandedValuesItem;
|
||||||
|
expandedValuesItem->setText(expander->expand(item->text()));
|
||||||
|
expandedValuesItem->setData(expander->expand(item->data(ValueRole).toString()), ValueRole);
|
||||||
|
expandedValuesItem->setData(expander->expand(item->data(IconStringRole).toString()), IconStringRole);
|
||||||
|
expandedValuesItem->setData(condition, ConditionRole);
|
||||||
|
|
||||||
|
QString iconPath = expandedValuesItem->data(IconStringRole).toString();
|
||||||
|
if (!iconPath.isEmpty()) {
|
||||||
|
if (JsonFieldPage *page = qobject_cast<JsonFieldPage*>(widget()->parentWidget())) {
|
||||||
|
const QString wizardDirectory = page->value("WizardDir").toString();
|
||||||
|
iconPath = QDir::cleanPath(QDir(wizardDirectory).absoluteFilePath(iconPath));
|
||||||
|
if (QFileInfo::exists(iconPath)) {
|
||||||
|
QIcon icon(iconPath);
|
||||||
|
expandedValuesItem->setIcon(icon);
|
||||||
|
addPossibleIconSize(icon);
|
||||||
|
} else {
|
||||||
|
qWarning().noquote() << QString("Icon file \"%1\" not found.").arg(QDir::toNativeSeparators(iconPath));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
qWarning().noquote() << QString("%1(\"%2\") has no parentWidget JsonFieldPage to get the icon path.").arg(type(), name());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expandedValuesItems.append(expandedValuesItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
itemModel()->clear();
|
||||||
|
itemModel()->appendColumn(expandedValuesItems); // inserts the first column
|
||||||
|
|
||||||
|
selectionModel()->setCurrentIndex(itemModel()->indexFromItem(currentItem), QItemSelectionModel::ClearAndSelect);
|
||||||
|
|
||||||
|
updateIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
QStandardItemModel *ListField::itemModel()
|
||||||
|
{
|
||||||
|
if (!m_itemModel)
|
||||||
|
m_itemModel = new QStandardItemModel(widget());
|
||||||
|
return m_itemModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
QItemSelectionModel *ListField::selectionModel()
|
||||||
|
{
|
||||||
|
return m_selectionModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListField::setSelectionModel(QItemSelectionModel *selectionModel)
|
||||||
|
{
|
||||||
|
m_selectionModel = selectionModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize ListField::maxIconSize()
|
||||||
|
{
|
||||||
|
return m_maxIconSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListField::addPossibleIconSize(const QIcon &icon)
|
||||||
|
{
|
||||||
|
const QSize iconSize = icon.availableSizes().value(0);
|
||||||
|
if (iconSize.height() > m_maxIconSize.height())
|
||||||
|
m_maxIconSize = iconSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListField::updateIndex()
|
||||||
|
{
|
||||||
|
if (!widget()->isEnabled() && m_disabledIndex >= 0 && m_savedIndex < 0) {
|
||||||
|
m_savedIndex = selectionModel()->currentIndex().row();
|
||||||
|
selectionModel()->setCurrentIndex(itemModel()->index(m_disabledIndex, 0), QItemSelectionModel::ClearAndSelect);
|
||||||
|
} else if (widget()->isEnabled() && m_savedIndex >= 0) {
|
||||||
|
selectionModel()->setCurrentIndex(itemModel()->index(m_savedIndex, 0), QItemSelectionModel::ClearAndSelect);
|
||||||
|
m_savedIndex = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComboBoxField::setup(JsonFieldPage *page, const QString &name)
|
||||||
|
{
|
||||||
|
auto w = qobject_cast<QComboBox*>(widget());
|
||||||
|
QTC_ASSERT(w, return);
|
||||||
|
w->setModel(itemModel());
|
||||||
|
w->setInsertPolicy(QComboBox::NoInsert);
|
||||||
|
|
||||||
|
QSizePolicy s = w->sizePolicy();
|
||||||
|
s.setHorizontalPolicy(QSizePolicy::Expanding);
|
||||||
|
w->setSizePolicy(s);
|
||||||
|
|
||||||
|
setSelectionModel(w->view()->selectionModel());
|
||||||
|
|
||||||
|
// the selectionModel does not behave like expected and wanted - so we block signals here
|
||||||
|
// (for example there was some losing focus thing when hovering over items, ...)
|
||||||
|
selectionModel()->blockSignals(true);
|
||||||
|
QObject::connect(w, static_cast<void(QComboBox::*)(int)>(&QComboBox::activated), [w, this](int index) {
|
||||||
|
w->blockSignals(true);
|
||||||
|
selectionModel()->clearSelection();
|
||||||
|
|
||||||
|
selectionModel()->blockSignals(false);
|
||||||
|
selectionModel()->setCurrentIndex(w->model()->index(index, 0),
|
||||||
|
QItemSelectionModel::ClearAndSelect);
|
||||||
|
selectionModel()->blockSignals(true);
|
||||||
|
w->blockSignals(false);
|
||||||
|
});
|
||||||
|
page->registerObjectAsFieldWithName<QItemSelectionModel>(name, selectionModel(), &QItemSelectionModel::selectionChanged, [this]() {
|
||||||
|
const QModelIndex i = selectionModel()->currentIndex();
|
||||||
|
if (i.isValid())
|
||||||
|
return i.data(ValueRole).toString();
|
||||||
|
return QString();
|
||||||
|
});
|
||||||
|
QObject::connect(selectionModel(), &QItemSelectionModel::selectionChanged, page, [page]() {
|
||||||
|
emit page->completeChanged();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget *ComboBoxField::createWidget(const QString & /*displayName*/, JsonFieldPage * /*page*/)
|
||||||
|
{
|
||||||
|
return new QComboBox;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ComboBoxField::initializeData(MacroExpander *expander)
|
void ComboBoxField::initializeData(MacroExpander *expander)
|
||||||
{
|
{
|
||||||
auto w = qobject_cast<TextFieldComboBox *>(widget());
|
ListField::initializeData(expander);
|
||||||
QTC_ASSERT(widget(), return);
|
// refresh also the current text of the combobox
|
||||||
QStringList tmpItems
|
auto w = qobject_cast<QComboBox*>(widget());
|
||||||
= Utils::transform(m_itemList,
|
w->setCurrentIndex(selectionModel()->currentIndex().row());
|
||||||
[expander](const QString &i) { return expander->expand(i); });
|
|
||||||
QStringList tmpData
|
|
||||||
= Utils::transform(m_itemDataList,
|
|
||||||
[expander](const QString &i) { return expander->expand(i); });
|
|
||||||
QList<bool> tmpConditions
|
|
||||||
= Utils::transform(m_itemConditionList,
|
|
||||||
[expander](const QVariant &v) { return JsonWizard::boolFromVariant(v, expander); });
|
|
||||||
|
|
||||||
int index = m_index;
|
|
||||||
for (int i = tmpConditions.count() - 1; i >= 0; --i) {
|
|
||||||
if (!tmpConditions.at(i)) {
|
|
||||||
tmpItems.removeAt(i);
|
|
||||||
tmpData.removeAt(i);
|
|
||||||
if (i < index && index > 0)
|
|
||||||
--index;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (index < 0 || index >= tmpData.count())
|
void IconListField::setup(JsonFieldPage *page, const QString &name)
|
||||||
index = 0;
|
{
|
||||||
w->setItems(tmpItems, tmpData);
|
auto w = qobject_cast<QListView*>(widget());
|
||||||
w->setInsertPolicy(QComboBox::NoInsert);
|
QTC_ASSERT(w, return);
|
||||||
w->setCurrentIndex(index);
|
|
||||||
|
w->setViewMode(QListView::IconMode);
|
||||||
|
w->setMovement(QListView::Static);
|
||||||
|
w->setResizeMode(QListView::Adjust);
|
||||||
|
w->setSelectionRectVisible(false);
|
||||||
|
w->setWrapping(true);
|
||||||
|
w->setWordWrap(true);
|
||||||
|
|
||||||
|
w->setModel(itemModel());
|
||||||
|
setSelectionModel(w->selectionModel());
|
||||||
|
page->registerObjectAsFieldWithName<QItemSelectionModel>(name, selectionModel(), &QItemSelectionModel::selectionChanged, [this]() {
|
||||||
|
const QModelIndex i = selectionModel()->currentIndex();
|
||||||
|
if (i.isValid())
|
||||||
|
return i.data(ValueRole).toString();
|
||||||
|
return QString();
|
||||||
|
});
|
||||||
|
QObject::connect(selectionModel(), &QItemSelectionModel::selectionChanged, page, [page]() {
|
||||||
|
page->completeChanged();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget *IconListField::createWidget(const QString & /*displayName*/, JsonFieldPage * /*page*/)
|
||||||
|
{
|
||||||
|
return new QListView;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IconListField::initializeData(MacroExpander *expander)
|
||||||
|
{
|
||||||
|
ListField::initializeData(expander);
|
||||||
|
auto w = qobject_cast<QListView*>(widget());
|
||||||
|
const int spacing = 4;
|
||||||
|
w->setSpacing(spacing);
|
||||||
|
w->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||||
|
|
||||||
|
// adding a third hight of the icon to see following items if there are some
|
||||||
|
w->setMinimumHeight(maxIconSize().height() + maxIconSize().height() / 3);
|
||||||
|
w->setIconSize(maxIconSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
||||||
|
|||||||
@@ -42,7 +42,6 @@ QT_END_NAMESPACE
|
|||||||
|
|
||||||
namespace Utils {
|
namespace Utils {
|
||||||
class MacroExpander;
|
class MacroExpander;
|
||||||
class TextFieldComboBox;
|
|
||||||
} // namespace Utils
|
} // namespace Utils
|
||||||
|
|
||||||
namespace ProjectExplorer {
|
namespace ProjectExplorer {
|
||||||
|
|||||||
@@ -32,6 +32,16 @@
|
|||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
|
#include <QDir>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
class QStandardItem;
|
||||||
|
class QStandardItemModel;
|
||||||
|
class QItemSelectionModel;
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
namespace ProjectExplorer {
|
namespace ProjectExplorer {
|
||||||
|
|
||||||
@@ -170,25 +180,58 @@ private:
|
|||||||
bool m_isModified = false;
|
bool m_isModified = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ComboBoxField : public JsonFieldPage::Field
|
class ListField : public JsonFieldPage::Field
|
||||||
{
|
{
|
||||||
private:
|
public:
|
||||||
|
enum SpecialRoles {
|
||||||
|
ValueRole = Qt::UserRole,
|
||||||
|
ConditionRole = Qt::UserRole + 1,
|
||||||
|
IconStringRole = Qt::UserRole + 2
|
||||||
|
};
|
||||||
|
ListField();
|
||||||
|
virtual ~ListField() override;
|
||||||
|
|
||||||
|
protected:
|
||||||
bool parseData(const QVariant &data, QString *errorMessage) override;
|
bool parseData(const QVariant &data, QString *errorMessage) override;
|
||||||
|
|
||||||
QWidget *createWidget(const QString &displayName, JsonFieldPage *page) override;
|
QWidget *createWidget(const QString &displayName, JsonFieldPage *page) override = 0;
|
||||||
|
void setup(JsonFieldPage *page, const QString &name) override = 0;
|
||||||
void setup(JsonFieldPage *page, const QString &name) override;
|
|
||||||
|
|
||||||
bool validate(Utils::MacroExpander *expander, QString *message) override;
|
bool validate(Utils::MacroExpander *expander, QString *message) override;
|
||||||
void initializeData(Utils::MacroExpander *expander) override;
|
void initializeData(Utils::MacroExpander *expander) override;
|
||||||
|
QStandardItemModel *itemModel();
|
||||||
|
QItemSelectionModel *selectionModel();
|
||||||
|
void setSelectionModel(QItemSelectionModel *selectionModel);
|
||||||
|
QSize maxIconSize();
|
||||||
|
|
||||||
QStringList m_itemList;
|
private:
|
||||||
QStringList m_itemDataList;
|
void addPossibleIconSize(const QIcon &icon);
|
||||||
QVariantList m_itemConditionList;
|
void updateIndex();
|
||||||
|
|
||||||
|
std::vector<std::unique_ptr<QStandardItem>> m_itemList;
|
||||||
|
QStandardItemModel *m_itemModel = nullptr;
|
||||||
|
QItemSelectionModel *m_selectionModel = nullptr;
|
||||||
int m_index = -1;
|
int m_index = -1;
|
||||||
int m_disabledIndex = -1;
|
int m_disabledIndex = -1;
|
||||||
|
QSize m_maxIconSize;
|
||||||
|
|
||||||
mutable int m_savedIndex = -1;
|
mutable int m_savedIndex = -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ComboBoxField : public ListField
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void setup(JsonFieldPage *page, const QString &name) override;
|
||||||
|
QWidget *createWidget(const QString &displayName, JsonFieldPage *page) override;
|
||||||
|
void initializeData(Utils::MacroExpander *expander) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IconListField : public ListField
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void setup(JsonFieldPage *page, const QString &name) override;
|
||||||
|
QWidget *createWidget(const QString &displayName, JsonFieldPage *page) override;
|
||||||
|
void initializeData(Utils::MacroExpander *expander) override;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace ProjectExplorer
|
} // namespace ProjectExplorer
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
#include <QCheckBox>
|
#include <QCheckBox>
|
||||||
#include <QLineEdit>
|
#include <QLineEdit>
|
||||||
#include <QComboBox>
|
#include <QComboBox>
|
||||||
|
#include <QListView>
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
namespace {
|
namespace {
|
||||||
@@ -209,8 +210,8 @@ void ProjectExplorer::ProjectExplorerPlugin::testJsonWizardsLineEdit()
|
|||||||
void ProjectExplorer::ProjectExplorerPlugin::testJsonWizardsComboBox()
|
void ProjectExplorer::ProjectExplorerPlugin::testJsonWizardsComboBox()
|
||||||
{
|
{
|
||||||
QString errorMessage;
|
QString errorMessage;
|
||||||
|
|
||||||
QWidget parent;
|
QWidget parent;
|
||||||
|
|
||||||
const QJsonArray items({"abc", "cde", "fgh"});
|
const QJsonArray items({"abc", "cde", "fgh"});
|
||||||
QJsonObject disabledComboBoxObject = createWidget("ComboBox", "Disabled", QJsonObject({ {{"disabledIndex", 2}, {"items", items}} }));
|
QJsonObject disabledComboBoxObject = createWidget("ComboBox", "Disabled", QJsonObject({ {{"disabledIndex", 2}, {"items", items}} }));
|
||||||
disabledComboBoxObject.insert("enabled", false);
|
disabledComboBoxObject.insert("enabled", false);
|
||||||
@@ -228,6 +229,8 @@ void ProjectExplorer::ProjectExplorerPlugin::testJsonWizardsComboBox()
|
|||||||
|
|
||||||
QComboBox *defaultComboBox = findComboBox(wizard, "Default");
|
QComboBox *defaultComboBox = findComboBox(wizard, "Default");
|
||||||
QVERIFY(defaultComboBox);
|
QVERIFY(defaultComboBox);
|
||||||
|
QCOMPARE(defaultComboBox->count(), items.count());
|
||||||
|
QCOMPARE(qPrintable(defaultComboBox->currentText()), "abc");
|
||||||
|
|
||||||
defaultComboBox->setCurrentIndex(2);
|
defaultComboBox->setCurrentIndex(2);
|
||||||
QCOMPARE(qPrintable(defaultComboBox->currentText()), "fgh");
|
QCOMPARE(qPrintable(defaultComboBox->currentText()), "fgh");
|
||||||
@@ -238,7 +241,49 @@ void ProjectExplorer::ProjectExplorerPlugin::testJsonWizardsComboBox()
|
|||||||
|
|
||||||
QComboBox *disabledComboBox = findComboBox(wizard, "Disabled");
|
QComboBox *disabledComboBox = findComboBox(wizard, "Disabled");
|
||||||
QVERIFY(disabledComboBox);
|
QVERIFY(disabledComboBox);
|
||||||
QEXPECT_FAIL("", "This is wrong, since ComboBox got condition items", Continue);
|
|
||||||
QCOMPARE(qPrintable(disabledComboBox->currentText()), "fgh");
|
QCOMPARE(qPrintable(disabledComboBox->currentText()), "fgh");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProjectExplorer::ProjectExplorerPlugin::testJsonWizardsIconList()
|
||||||
|
{
|
||||||
|
QString errorMessage;
|
||||||
|
QWidget parent;
|
||||||
|
|
||||||
|
const QJsonArray items({
|
||||||
|
QJsonObject{
|
||||||
|
{"trKey", "item no1"},
|
||||||
|
{"condition", true},
|
||||||
|
{"icon", "../share/qtcreator/templates/wizards/qtquickstyleicons/default.png"}
|
||||||
|
|
||||||
|
},
|
||||||
|
QJsonObject{
|
||||||
|
{"trKey", "item no2"},
|
||||||
|
{"condition", false},
|
||||||
|
{"icon", "not_existing_path"}
|
||||||
|
|
||||||
|
},
|
||||||
|
QJsonObject{
|
||||||
|
{"trKey", "item no3"},
|
||||||
|
{"condition", true},
|
||||||
|
{"trToolTip", "MyToolTip"},
|
||||||
|
{"icon", "../share/qtcreator/templates/wizards/qtquickstyleicons/default.png"}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const QJsonArray widgets({
|
||||||
|
createWidget("IconList", "Fancy", QJsonObject{{"index", -1}, {"items", items}})
|
||||||
|
});
|
||||||
|
|
||||||
|
const QJsonObject pages = createFieldPageJsonObject(widgets);
|
||||||
|
const QJsonObject wizardObject = createGeneralWizard(pages);
|
||||||
|
JsonWizardFactory *factory = ProjectExplorer::JsonWizardFactory::createWizardFactory(wizardObject.toVariantMap(), QDir(), &errorMessage);
|
||||||
|
QVERIFY2(factory, qPrintable(errorMessage));
|
||||||
|
Utils::Wizard *wizard = factory->runWizard(QString(), &parent, Core::Id(), QVariantMap());
|
||||||
|
|
||||||
|
auto view = wizard->findChild<QListView *>("FancyIconList");
|
||||||
|
QCOMPARE(view->model()->rowCount(), 2);
|
||||||
|
QVERIFY(view->model()->index(0,0).data(Qt::DecorationRole).canConvert<QIcon>());
|
||||||
|
QIcon icon = view->model()->index(0,0).data(Qt::DecorationRole).value<QIcon>();
|
||||||
|
QVERIFY(!icon.isNull());
|
||||||
|
QVERIFY(!wizard->page(0)->isComplete());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ FieldPageFactory::FieldPageFactory()
|
|||||||
JsonFieldPage::registerFieldFactory(QLatin1String("PathChooser"), []() { return new PathChooserField; });
|
JsonFieldPage::registerFieldFactory(QLatin1String("PathChooser"), []() { return new PathChooserField; });
|
||||||
JsonFieldPage::registerFieldFactory(QLatin1String("CheckBox"), []() { return new CheckBoxField; });
|
JsonFieldPage::registerFieldFactory(QLatin1String("CheckBox"), []() { return new CheckBoxField; });
|
||||||
JsonFieldPage::registerFieldFactory(QLatin1String("ComboBox"), []() { return new ComboBoxField; });
|
JsonFieldPage::registerFieldFactory(QLatin1String("ComboBox"), []() { return new ComboBoxField; });
|
||||||
|
JsonFieldPage::registerFieldFactory(QLatin1String("IconList"), []() { return new IconListField; });
|
||||||
}
|
}
|
||||||
|
|
||||||
Utils::WizardPage *FieldPageFactory::create(JsonWizard *wizard, Core::Id typeId, const QVariant &data)
|
Utils::WizardPage *FieldPageFactory::create(JsonWizard *wizard, Core::Id typeId, const QVariant &data)
|
||||||
|
|||||||
@@ -189,6 +189,7 @@ private slots:
|
|||||||
void testJsonWizardsCheckBox();
|
void testJsonWizardsCheckBox();
|
||||||
void testJsonWizardsLineEdit();
|
void testJsonWizardsLineEdit();
|
||||||
void testJsonWizardsComboBox();
|
void testJsonWizardsComboBox();
|
||||||
|
void testJsonWizardsIconList();
|
||||||
|
|
||||||
void testAnsiFilterOutputParser_data();
|
void testAnsiFilterOutputParser_data();
|
||||||
void testAnsiFilterOutputParser();
|
void testAnsiFilterOutputParser();
|
||||||
|
|||||||
Reference in New Issue
Block a user