aboutsummaryrefslogtreecommitdiffstats
path: root/src/libs/utils
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/utils')
-rw-r--r--src/libs/utils/aspects.cpp556
-rw-r--r--src/libs/utils/aspects.h259
2 files changed, 342 insertions, 473 deletions
diff --git a/src/libs/utils/aspects.cpp b/src/libs/utils/aspects.cpp
index d8fdd9f6f3..5c1fd5cdb2 100644
--- a/src/libs/utils/aspects.cpp
+++ b/src/libs/utils/aspects.cpp
@@ -40,8 +40,6 @@ class BaseAspectPrivate
{
public:
Id m_id;
- QVariant m_value;
- QVariant m_defaultValue;
std::function<QVariant(const QVariant &)> m_toSettings;
std::function<QVariant(const QVariant &)> m_fromSettings;
@@ -99,7 +97,7 @@ BaseAspect::BaseAspect(AspectContainer *container)
{
if (container)
container->registerAspect(this);
- addDataExtractor(this, &BaseAspect::value, &Data::value);
+ addDataExtractor(this, &BaseAspect::variantValue, &Data::value);
}
/*!
@@ -120,43 +118,49 @@ void BaseAspect::setId(Id id)
d->m_id = id;
}
-QVariant BaseAspect::value() const
+QVariant BaseAspect::variantValue() const
{
- return d->m_value;
+ return {};
}
/*!
Sets \a value.
- Emits \c changed() if the value changed.
+ Prefer the typed setValue() of derived classes.
*/
-void BaseAspect::setValue(const QVariant &value)
+void BaseAspect::setVariantValue(const QVariant &value)
{
- if (setValueQuietly(value)) {
- emit changed();
- emitChangedValue();
- }
+ Q_UNUSED(value)
+ QTC_CHECK(false);
+}
+
+void BaseAspect::setDefaultVariantValue(const QVariant &value)
+{
+ Q_UNUSED(value)
+ QTC_CHECK(false);
}
/*!
- Sets \a value without emitting \c changed().
+ \internal
+
+ Sets \a value without emitting signals.
- Returns whether the value changed.
+ Prefer the typed setValueQuietly() of derived classes.
*/
-bool BaseAspect::setValueQuietly(const QVariant &value)
+void BaseAspect::setVariantValueQuietly(const QVariant &value)
{
- if (d->m_value == value)
- return false;
- d->m_value = value;
- return true;
+ Q_UNUSED(value)
+ QTC_CHECK(false);
}
-QVariant BaseAspect::defaultValue() const
+QVariant BaseAspect::defaultVariantValue() const
{
- return d->m_defaultValue;
+ return {};
}
/*!
+ \fn TypedAspect::setDefaultValue(const ValueType &value)
+
Sets a default \a value and the current value for this aspect.
\note The current value will be set silently to the same value.
@@ -165,11 +169,6 @@ QVariant BaseAspect::defaultValue() const
Default values will not be stored in settings.
*/
-void BaseAspect::setDefaultValue(const QVariant &value)
-{
- d->m_defaultValue = value;
- d->m_value = value;
-}
void BaseAspect::setDisplayName(const QString &displayName)
{
@@ -308,8 +307,12 @@ void BaseAspect::setEnabler(BoolAspect *checker)
{
QTC_ASSERT(checker, return);
setEnabled(checker->value());
- connect(checker, &BoolAspect::volatileValueChanged, this, &BaseAspect::setEnabled);
- connect(checker, &BoolAspect::valueChanged, this, &BaseAspect::setEnabled);
+ connect(checker, &BoolAspect::volatileValueChanged, this, [this, checker] {
+ BaseAspect::setEnabled(checker->volatileValue());
+ });
+ connect(checker, &BoolAspect::changed, this, [this, checker] {
+ BaseAspect::setEnabled(checker->volatileValue());
+ });
}
bool BaseAspect::isReadOnly() const
@@ -442,16 +445,29 @@ void createItem(Layouting::LayoutItem *item, const BaseAspect *aspect)
/*!
Updates this aspect's value from user-initiated changes in the widget.
- This has only an effect if \c isAutoApply is false.
+ Emits changed() if the value changed.
*/
void BaseAspect::apply()
{
- QTC_CHECK(!d->m_autoApply);
- if (isDirty())
- setValue(volatileValue());
+ if (silentApply()) {
+ if (hasAction())
+ emit action()->triggered(variantValue().toBool());
+ emit changed();
+ }
}
/*!
+ Updates this aspect's value from user-initiated changes in the widget.
+
+ \returns whether the value changed. Does not emit signals.
+*/
+
+bool BaseAspect::silentApply()
+{
+ guiToInternal();
+ return internalToExternal();
+}
+/*!
Discard user changes in the widget and restore widget contents from
aspect's value.
@@ -459,9 +475,8 @@ void BaseAspect::apply()
*/
void BaseAspect::cancel()
{
- QTC_CHECK(!d->m_autoApply);
- if (!d->m_subWidgets.isEmpty())
- setVolatileValue(d->m_value);
+ externalToInternal();
+ internalToGui();
}
void BaseAspect::finish()
@@ -476,24 +491,9 @@ bool BaseAspect::hasAction() const
return d->m_action != nullptr;
}
-bool BaseAspect::isDirty() const
+bool BaseAspect::isDirty()
{
- QTC_CHECK(!isAutoApply());
- // Aspects that were never shown cannot contain unsaved user changes.
- if (d->m_subWidgets.isEmpty())
- return false;
- return volatileValue() != d->m_value;
-}
-
-QVariant BaseAspect::volatileValue() const
-{
- QTC_CHECK(!isAutoApply());
- return {};
-}
-
-void BaseAspect::setVolatileValue(const QVariant &val)
-{
- Q_UNUSED(val);
+ return false;
}
void BaseAspect::registerSubWidget(QWidget *widget)
@@ -534,8 +534,10 @@ void BaseAspect::saveToMap(QVariantMap &data, const QVariant &value,
*/
void BaseAspect::fromMap(const QVariantMap &map)
{
- const QVariant val = map.value(settingsKey(), toSettingsValue(defaultValue()));
- setValue(fromSettingsValue(val));
+ if (settingsKey().isEmpty())
+ return;
+ const QVariant val = map.value(settingsKey(), toSettingsValue(defaultVariantValue()));
+ setVariantValue(fromSettingsValue(val));
}
/*!
@@ -543,7 +545,9 @@ void BaseAspect::fromMap(const QVariantMap &map)
*/
void BaseAspect::toMap(QVariantMap &map) const
{
- saveToMap(map, toSettingsValue(d->m_value), toSettingsValue(d->m_defaultValue), settingsKey());
+ if (settingsKey().isEmpty())
+ return;
+ saveToMap(map, toSettingsValue(variantValue()), toSettingsValue(defaultVariantValue()), settingsKey());
}
void BaseAspect::readSettings(const QSettings *settings)
@@ -551,7 +555,7 @@ void BaseAspect::readSettings(const QSettings *settings)
if (settingsKey().isEmpty())
return;
const QVariant &val = settings->value(settingsKey());
- setValue(val.isValid() ? fromSettingsValue(val) : defaultValue());
+ setVariantValue(val.isValid() ? fromSettingsValue(val) : defaultVariantValue());
}
void BaseAspect::writeSettings(QSettings *settings) const
@@ -560,8 +564,8 @@ void BaseAspect::writeSettings(QSettings *settings) const
return;
QtcSettings::setValueWithDefault(settings,
settingsKey(),
- toSettingsValue(value()),
- toSettingsValue(defaultValue()));
+ toSettingsValue(variantValue()),
+ toSettingsValue(defaultVariantValue()));
}
void BaseAspect::setFromSettingsTransformation(const SavedValueTransformation &transform)
@@ -773,9 +777,8 @@ public:
*/
StringAspect::StringAspect(AspectContainer *container)
- : BaseAspect(container), d(new Internal::StringAspectPrivate)
+ : TypedAspect(container), d(new Internal::StringAspectPrivate)
{
- setDefaultValue(QString());
setSpan(2, 1); // Default: Label + something
addDataExtractor(this, &StringAspect::value, &Data::value);
@@ -800,7 +803,7 @@ void StringAspect::setValueAcceptor(StringAspect::ValueAcceptor &&acceptor)
*/
QString StringAspect::value() const
{
- return BaseAspect::value().toString();
+ return TypedAspect::value();
}
/*!
@@ -816,27 +819,13 @@ void StringAspect::setValue(const QString &val)
if (d->m_valueAcceptor) {
const std::optional<QString> tmp = d->m_valueAcceptor(value(), val);
if (!tmp) {
- update(); // Make sure the original value is retained in the UI
+ internalToGui(); // Make sure the original value is retained in the UI
return;
}
processedValue = tmp.value();
}
- if (BaseAspect::setValueQuietly(QVariant(processedValue))) {
- update();
- emit changed();
- emit valueChanged(processedValue);
- }
-}
-
-QString StringAspect::defaultValue() const
-{
- return BaseAspect::defaultValue().toString();
-}
-
-void StringAspect::setDefaultValue(const QString &val)
-{
- BaseAspect::setDefaultValue(val);
+ TypedAspect::setValue(processedValue);
}
/*!
@@ -845,7 +834,7 @@ void StringAspect::setDefaultValue(const QString &val)
void StringAspect::fromMap(const QVariantMap &map)
{
if (!settingsKey().isEmpty())
- BaseAspect::setValueQuietly(map.value(settingsKey(), defaultValue()));
+ setValueQuietly(map.value(settingsKey(), defaultValue()).toString());
if (d->m_checker)
d->m_checker->fromMap(map);
}
@@ -900,7 +889,7 @@ PathChooser *StringAspect::pathChooser() const
void StringAspect::setShowToolTipOnLabel(bool show)
{
d->m_showToolTipOnLabel = show;
- update();
+ internalToGui();
}
/*!
@@ -1246,79 +1235,48 @@ void StringAspect::addToLayout(LayoutItem &parent)
d->m_checker->addToLayout(parent);
}
-QVariant StringAspect::volatileValue() const
-{
- switch (d->m_displayStyle) {
- case PathChooserDisplay:
- QTC_ASSERT(d->m_pathChooserDisplay, return {});
- if (d->m_pathChooserDisplay->filePath().isEmpty())
- return defaultValue();
- return d->m_pathChooserDisplay->filePath().toString();
- case LineEditDisplay:
- QTC_ASSERT(d->m_lineEditDisplay, return {});
- if (d->m_lineEditDisplay->text().isEmpty())
- return defaultValue();
- return d->m_lineEditDisplay->text();
- case TextEditDisplay:
- QTC_ASSERT(d->m_textEditDisplay, return {});
- if (d->m_textEditDisplay->document()->isEmpty())
- return defaultValue();
- return d->m_textEditDisplay->document()->toPlainText();
- case LabelDisplay:
- break;
- }
- return {};
-}
-
-void StringAspect::setVolatileValue(const QVariant &val)
+void StringAspect::guiToInternal()
{
switch (d->m_displayStyle) {
case PathChooserDisplay:
if (d->m_pathChooserDisplay)
- d->m_pathChooserDisplay->setFilePath(FilePath::fromVariant(val));
+ m_internal = d->m_pathChooserDisplay->lineEdit()->text();
break;
case LineEditDisplay:
if (d->m_lineEditDisplay)
- d->m_lineEditDisplay->setText(val.toString());
+ m_internal = d->m_lineEditDisplay->text();
break;
case TextEditDisplay:
if (d->m_textEditDisplay)
- d->m_textEditDisplay->document()->setPlainText(val.toString());
- break;
+ m_internal = d->m_textEditDisplay->document()->toPlainText();
case LabelDisplay:
break;
}
}
-void StringAspect::emitChangedValue()
-{
- emit valueChanged(value());
-}
-
-void StringAspect::update()
+void StringAspect::internalToGui()
{
- const QString displayedString = d->m_displayFilter ? d->m_displayFilter(value()) : value();
-
+ const QString displayed = d->m_displayFilter ? d->m_displayFilter(m_internal) : m_internal;
if (d->m_pathChooserDisplay) {
- d->m_pathChooserDisplay->setFilePath(FilePath::fromUserInput(displayedString));
+ d->m_pathChooserDisplay->lineEdit()->setText(displayed);
d->updateWidgetFromCheckStatus(this, d->m_pathChooserDisplay.data());
}
if (d->m_lineEditDisplay) {
- d->m_lineEditDisplay->setTextKeepingActiveCursor(displayedString);
+ d->m_lineEditDisplay->setTextKeepingActiveCursor(displayed);
d->updateWidgetFromCheckStatus(this, d->m_lineEditDisplay.data());
}
if (d->m_textEditDisplay) {
const QString old = d->m_textEditDisplay->document()->toPlainText();
- if (displayedString != old)
- d->m_textEditDisplay->setText(displayedString);
+ if (displayed != old)
+ d->m_textEditDisplay->setText(displayed);
d->updateWidgetFromCheckStatus(this, d->m_textEditDisplay.data());
}
if (d->m_labelDisplay) {
- d->m_labelDisplay->setText(displayedString);
- d->m_labelDisplay->setToolTip(d->m_showToolTipOnLabel ? displayedString : toolTip());
+ d->m_labelDisplay->setText(displayed);
+ d->m_labelDisplay->setToolTip(d->m_showToolTipOnLabel ? displayed : toolTip());
}
validateInput();
@@ -1342,11 +1300,11 @@ void StringAspect::makeCheckable(CheckBoxPlacement checkBoxPlacement,
: BoolAspect::LabelPlacement::AtCheckBox);
d->m_checker->setSettingsKey(checkerKey);
- connect(d->m_checker.get(), &BoolAspect::changed, this, &StringAspect::update);
+ connect(d->m_checker.get(), &BoolAspect::changed, this, &StringAspect::internalToGui);
connect(d->m_checker.get(), &BoolAspect::changed, this, &StringAspect::changed);
connect(d->m_checker.get(), &BoolAspect::changed, this, &StringAspect::checkedChanged);
- update();
+ internalToGui();
}
@@ -1384,12 +1342,10 @@ FilePathAspect::FilePathAspect(AspectContainer *container)
*/
ColorAspect::ColorAspect(AspectContainer *container)
- : BaseAspect(container), d(new Internal::ColorAspectPrivate)
+ : TypedAspect(container), d(new Internal::ColorAspectPrivate)
{
setDefaultValue(QColor::fromRgb(0, 0, 0));
setSpan(1, 1);
-
- addDataExtractor(this, &ColorAspect::value, &Data::value);
}
ColorAspect::~ColorAspect() = default;
@@ -1408,31 +1364,16 @@ void ColorAspect::addToLayout(Layouting::LayoutItem &parent)
}
}
-QColor ColorAspect::value() const
-{
- return BaseAspect::value().value<QColor>();
-}
-
-void ColorAspect::setValue(const QColor &value)
-{
- if (BaseAspect::setValueQuietly(value))
- emit changed();
-}
-
-QVariant ColorAspect::volatileValue() const
+void ColorAspect::internalToGui()
{
- QTC_CHECK(!isAutoApply());
if (d->m_colorButton)
- return d->m_colorButton->color();
- QTC_CHECK(false);
- return {};
+ m_internal = d->m_colorButton->color();
}
-void ColorAspect::setVolatileValue(const QVariant &val)
+void ColorAspect::guiToInternal()
{
- QTC_CHECK(!isAutoApply());
if (d->m_colorButton)
- d->m_colorButton->setColor(val.value<QColor>());
+ d->m_colorButton->setColor(m_internal);
}
/*!
@@ -1451,12 +1392,10 @@ void ColorAspect::setVolatileValue(const QVariant &val)
BoolAspect::BoolAspect(AspectContainer *container)
- : BaseAspect(container), d(new Internal::BoolAspectPrivate)
+ : TypedAspect(container), d(new Internal::BoolAspectPrivate)
{
setDefaultValue(false);
setSpan(2, 1);
-
- addDataExtractor(this, &BoolAspect::value, &Data::value);
}
/*!
@@ -1520,8 +1459,8 @@ std::function<void (QObject *)> BoolAspect::groupChecker()
QAction *BoolAspect::action()
{
if (hasAction())
- return BaseAspect::action();
- auto act = BaseAspect::action(); // Creates it.
+ return TypedAspect::action();
+ auto act = TypedAspect::action(); // Creates it.
act->setCheckable(true);
act->setChecked(value());
act->setToolTip(toolTip());
@@ -1531,74 +1470,32 @@ QAction *BoolAspect::action()
// in a menu like "Use FakeVim", isAutoApply() is false, and yet this
// here can trigger.
//QTC_CHECK(isAutoApply());
- setValue(newValue);
+ m_external = newValue;
+ externalToInternal();
+ internalToGui();
});
return act;
}
-QVariant BoolAspect::volatileValue() const
+void BoolAspect::guiToInternal()
{
if (d->m_button)
- return d->m_button->isChecked();
- if (d->m_groupBox)
- return d->m_groupBox->isChecked();
- QTC_CHECK(false);
- return {};
+ m_internal = d->m_button->isChecked();
+ else if (d->m_groupBox)
+ m_internal = d->m_groupBox->isChecked();
}
-void BoolAspect::setVolatileValue(const QVariant &val)
+void BoolAspect::internalToGui()
{
if (d->m_button)
- d->m_button->setChecked(val.toBool());
+ d->m_button->setChecked(m_internal);
else if (d->m_groupBox)
- d->m_groupBox->setChecked(val.toBool());
-}
-
-void BoolAspect::emitChangedValue()
-{
- emit valueChanged(value());
-}
-
-
-/*!
- Returns the value of the boolean aspect as a boolean value.
-*/
-
-bool BoolAspect::value() const
-{
- return BaseAspect::value().toBool();
-}
-
-void BoolAspect::setValue(bool value)
-{
- if (BaseAspect::setValueQuietly(value)) {
- if (d->m_button)
- d->m_button->setChecked(value);
- //qDebug() << "SetValue: Changing" << labelText() << " to " << value;
- emit changed();
- //QTC_CHECK(!labelText().isEmpty());
- emit valueChanged(value);
- //qDebug() << "SetValue: Changed" << labelText() << " to " << value;
- if (hasAction()) {
- //qDebug() << "SetValue: Triggering " << labelText() << "with" << value;
- emit action()->triggered(value);
- }
- }
-}
-
-bool BoolAspect::defaultValue() const
-{
- return BaseAspect::defaultValue().toBool();
-}
-
-void BoolAspect::setDefaultValue(bool val)
-{
- BaseAspect::setDefaultValue(val);
+ d->m_groupBox->setChecked(m_internal);
}
void BoolAspect::setLabel(const QString &labelText, LabelPlacement labelPlacement)
{
- BaseAspect::setLabelText(labelText);
+ TypedAspect::setLabelText(labelText);
d->m_labelPlacement = labelPlacement;
}
@@ -1627,7 +1524,7 @@ CheckableDecider BoolAspect::checkableDecider()
*/
SelectionAspect::SelectionAspect(AspectContainer *container)
- : BaseAspect(container), d(new Internal::SelectionAspectPrivate)
+ : TypedAspect(container), d(new Internal::SelectionAspectPrivate)
{
setSpan(2, 1);
}
@@ -1683,25 +1580,26 @@ void SelectionAspect::addToLayout(Layouting::LayoutItem &parent)
}
}
-QVariant SelectionAspect::volatileValue() const
+void SelectionAspect::guiToInternal()
{
switch (d->m_displayStyle) {
case DisplayStyle::RadioButtons:
- QTC_ASSERT(d->m_buttonGroup, return {});
- return d->m_buttonGroup->checkedId();
+ if (d->m_buttonGroup)
+ m_internal = d->m_buttonGroup->checkedId();
+ break;
case DisplayStyle::ComboBox:
- QTC_ASSERT(d->m_comboBox, return {});
- return d->m_comboBox->currentIndex();
+ if (d->m_comboBox)
+ m_internal = d->m_comboBox->currentIndex();
+ break;
}
- return {};
}
-void SelectionAspect::setVolatileValue(const QVariant &val)
+void SelectionAspect::internalToGui()
{
switch (d->m_displayStyle) {
case DisplayStyle::RadioButtons: {
if (d->m_buttonGroup) {
- QAbstractButton *button = d->m_buttonGroup->button(val.toInt());
+ QAbstractButton *button = d->m_buttonGroup->button(m_internal);
QTC_ASSERT(button, return);
button->setChecked(true);
}
@@ -1709,7 +1607,7 @@ void SelectionAspect::setVolatileValue(const QVariant &val)
}
case DisplayStyle::ComboBox:
if (d->m_comboBox)
- d->m_comboBox->setCurrentIndex(val.toInt());
+ d->m_comboBox->setCurrentIndex(m_internal);
break;
}
}
@@ -1727,22 +1625,6 @@ void SelectionAspect::setDisplayStyle(SelectionAspect::DisplayStyle style)
d->m_displayStyle = style;
}
-int SelectionAspect::value() const
-{
- return BaseAspect::value().toInt();
-}
-
-void SelectionAspect::setValue(int value)
-{
- if (BaseAspect::setValueQuietly(value)) {
- if (d->m_buttonGroup && 0 <= value && value < d->m_buttons.size())
- d->m_buttons.at(value)->setChecked(true);
- else if (d->m_comboBox)
- d->m_comboBox->setCurrentIndex(value);
- emit changed();
- }
-}
-
void SelectionAspect::setStringValue(const QString &val)
{
const int index = indexForDisplay(val);
@@ -1750,20 +1632,15 @@ void SelectionAspect::setStringValue(const QString &val)
setValue(index);
}
-int SelectionAspect::defaultValue() const
-{
- return BaseAspect::defaultValue().toInt();
-}
-
void SelectionAspect::setDefaultValue(int val)
{
- BaseAspect::setDefaultValue(val);
+ TypedAspect::setDefaultValue(val);
}
// Note: This needs to be set after all options are added.
void SelectionAspect::setDefaultValue(const QString &val)
{
- BaseAspect::setDefaultValue(indexForDisplay(val));
+ TypedAspect::setDefaultValue(indexForDisplay(val));
}
QString SelectionAspect::stringValue() const
@@ -1830,7 +1707,7 @@ QVariant SelectionAspect::itemValueForIndex(int index) const
*/
MultiSelectionAspect::MultiSelectionAspect(AspectContainer *container)
- : BaseAspect(container), d(new Internal::MultiSelectionAspectPrivate(this))
+ : TypedAspect(container), d(new Internal::MultiSelectionAspectPrivate(this))
{
setDefaultValue(QStringList());
setSpan(2, 1);
@@ -1898,23 +1775,27 @@ void MultiSelectionAspect::setDisplayStyle(MultiSelectionAspect::DisplayStyle st
d->m_displayStyle = style;
}
-QStringList MultiSelectionAspect::value() const
+void MultiSelectionAspect::internalToGui()
{
- return BaseAspect::value().toStringList();
+ if (d->m_listView) {
+ const int n = d->m_listView->count();
+ QTC_CHECK(n == d->m_allValues.size());
+ for (int i = 0; i != n; ++i) {
+ auto item = d->m_listView->item(i);
+ item->setCheckState(m_internal.contains(item->text()) ? Qt::Checked : Qt::Unchecked);
+ }
+ }
}
-void MultiSelectionAspect::setValue(const QStringList &value)
+void MultiSelectionAspect::guiToInternal()
{
- if (BaseAspect::setValueQuietly(value)) {
- if (d->m_listView) {
- const int n = d->m_listView->count();
- QTC_CHECK(n == d->m_allValues.size());
- for (int i = 0; i != n; ++i) {
- auto item = d->m_listView->item(i);
- item->setCheckState(value.contains(item->text()) ? Qt::Checked : Qt::Unchecked);
- }
- } else {
- emit changed();
+ if (d->m_listView) {
+ m_internal.clear();
+ for (const QString &val : std::as_const(d->m_allValues)) {
+ auto item = new QListWidgetItem(val, d->m_listView);
+ item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
+ if (item->checkState() == Qt::Checked)
+ m_internal.append(item->text());
}
}
}
@@ -1937,12 +1818,9 @@ void MultiSelectionAspect::setValue(const QStringList &value)
// IntegerAspect
IntegerAspect::IntegerAspect(AspectContainer *container)
- : BaseAspect(container), d(new Internal::IntegerAspectPrivate)
+ : TypedAspect(container), d(new Internal::IntegerAspectPrivate)
{
- setDefaultValue(qint64(0));
setSpan(2, 1);
-
- addDataExtractor(this, &IntegerAspect::value, &Data::value);
}
/*!
@@ -1974,41 +1852,16 @@ void IntegerAspect::addToLayout(Layouting::LayoutItem &parent)
}
}
-QVariant IntegerAspect::volatileValue() const
-{
- QTC_CHECK(!isAutoApply());
- QTC_ASSERT(d->m_spinBox, return {});
- return d->m_spinBox->value() * d->m_displayScaleFactor;
-}
-
-void IntegerAspect::setVolatileValue(const QVariant &val)
+void IntegerAspect::guiToInternal()
{
- QTC_CHECK(!isAutoApply());
if (d->m_spinBox)
- d->m_spinBox->setValue(int(val.toLongLong() / d->m_displayScaleFactor));
-}
-
-qint64 IntegerAspect::value() const
-{
- return BaseAspect::value().toLongLong();
-}
-
-void IntegerAspect::setValue(qint64 value)
-{
- if (BaseAspect::setValueQuietly(value)) {
- if (d->m_spinBox)
- d->m_spinBox->setValue(value / d->m_displayScaleFactor);
- //qDebug() << "SetValue: Changing" << labelText() << " to " << value;
- emit changed();
- //QTC_CHECK(!labelText().isEmpty());
- emit valueChanged(value);
- //qDebug() << "SetValue: Changed" << labelText() << " to " << value;
- }
+ m_internal = d->m_spinBox->value() * d->m_displayScaleFactor;
}
-qint64 IntegerAspect::defaultValue() const
+void IntegerAspect::internalToGui()
{
- return BaseAspect::defaultValue().toLongLong();
+ if (d->m_spinBox)
+ d->m_spinBox->setValue(m_internal / d->m_displayScaleFactor);
}
void IntegerAspect::setRange(qint64 min, qint64 max)
@@ -2042,11 +1895,6 @@ void IntegerAspect::setDisplayScaleFactor(qint64 factor)
d->m_displayScaleFactor = factor;
}
-void IntegerAspect::setDefaultValue(qint64 defaultValue)
-{
- BaseAspect::setDefaultValue(defaultValue);
-}
-
void IntegerAspect::setSpecialValueText(const QString &specialText)
{
d->m_specialValueText = specialText;
@@ -2073,7 +1921,7 @@ void IntegerAspect::setSingleStep(qint64 step)
*/
DoubleAspect::DoubleAspect(AspectContainer *container)
- : BaseAspect(container), d(new Internal::DoubleAspectPrivate)
+ : TypedAspect(container), d(new Internal::DoubleAspectPrivate)
{
setDefaultValue(double(0));
setSpan(2, 1);
@@ -2097,7 +1945,7 @@ void DoubleAspect::addToLayout(LayoutItem &builder)
d->m_spinBox->setSpecialValueText(d->m_specialValueText);
if (d->m_maximumValue && d->m_maximumValue)
d->m_spinBox->setRange(d->m_minimumValue.value(), d->m_maximumValue.value());
- d->m_spinBox->setValue(value()); // Must happen after setRange()!
+ internalToGui(); // Must happen after setRange()!
addLabeledItem(builder, d->m_spinBox);
if (isAutoApply()) {
@@ -2106,33 +1954,16 @@ void DoubleAspect::addToLayout(LayoutItem &builder)
}
}
-QVariant DoubleAspect::volatileValue() const
-{
- QTC_CHECK(!isAutoApply());
- QTC_ASSERT(d->m_spinBox, return {});
- return d->m_spinBox->value();
-}
-
-void DoubleAspect::setVolatileValue(const QVariant &val)
+void DoubleAspect::guiToInternal()
{
- QTC_CHECK(!isAutoApply());
if (d->m_spinBox)
- d->m_spinBox->setValue(val.toDouble());
-}
-
-double DoubleAspect::value() const
-{
- return BaseAspect::value().toDouble();
-}
-
-void DoubleAspect::setValue(double value)
-{
- BaseAspect::setValue(value);
+ m_internal = d->m_spinBox->value();
}
-double DoubleAspect::defaultValue() const
+void DoubleAspect::internalToGui()
{
- return BaseAspect::defaultValue().toDouble();
+ if (d->m_spinBox)
+ d->m_spinBox->setValue(m_internal);
}
void DoubleAspect::setRange(double min, double max)
@@ -2151,11 +1982,6 @@ void DoubleAspect::setSuffix(const QString &suffix)
d->m_suffix = suffix;
}
-void DoubleAspect::setDefaultValue(double defaultValue)
-{
- BaseAspect::setDefaultValue(defaultValue);
-}
-
void DoubleAspect::setSpecialValueText(const QString &specialText)
{
d->m_specialValueText = specialText;
@@ -2192,7 +2018,7 @@ TriStateAspect::TriStateAspect(AspectContainer *container,
TriState TriStateAspect::value() const
{
- return TriState::fromVariant(BaseAspect::value());
+ return TriState::fromInt(SelectionAspect::value());
}
void TriStateAspect::setValue(TriState value)
@@ -2202,12 +2028,12 @@ void TriStateAspect::setValue(TriState value)
TriState TriStateAspect::defaultValue() const
{
- return TriState::fromVariant(BaseAspect::defaultValue());
+ return TriState::fromInt(SelectionAspect::defaultValue());
}
void TriStateAspect::setDefaultValue(TriState value)
{
- BaseAspect::setDefaultValue(value.toVariant());
+ SelectionAspect::setDefaultValue(value.toInt());
}
const TriState TriState::Enabled{TriState::EnabledValue};
@@ -2216,7 +2042,11 @@ const TriState TriState::Default{TriState::DefaultValue};
TriState TriState::fromVariant(const QVariant &variant)
{
- int v = variant.toInt();
+ return fromInt(variant.toInt());
+}
+
+TriState TriState::fromInt(int v)
+{
QTC_ASSERT(v == EnabledValue || v == DisabledValue || v == DefaultValue, v = DefaultValue);
return TriState(Value(v));
}
@@ -2231,7 +2061,7 @@ TriState TriState::fromVariant(const QVariant &variant)
*/
StringListAspect::StringListAspect(AspectContainer *container)
- : BaseAspect(container), d(new Internal::StringListAspectPrivate)
+ : TypedAspect(container), d(new Internal::StringListAspectPrivate)
{
setDefaultValue(QStringList());
}
@@ -2250,16 +2080,6 @@ void StringListAspect::addToLayout(LayoutItem &parent)
// TODO - when needed.
}
-QStringList StringListAspect::value() const
-{
- return BaseAspect::value().toStringList();
-}
-
-void StringListAspect::setValue(const QStringList &value)
-{
- BaseAspect::setValue(value);
-}
-
void StringListAspect::appendValue(const QString &s, bool allowDuplicates)
{
QStringList val = value();
@@ -2303,10 +2123,8 @@ void StringListAspect::removeValues(const QStringList &values)
*/
IntegersAspect::IntegersAspect(AspectContainer *container)
- : BaseAspect(container)
-{
- setDefaultValue({});
-}
+ : TypedAspect(container)
+{}
/*!
\internal
@@ -2322,33 +2140,6 @@ void IntegersAspect::addToLayout(Layouting::LayoutItem &parent)
// TODO - when needed.
}
-void IntegersAspect::emitChangedValue()
-{
- emit valueChanged(value());
-}
-
-QList<int> IntegersAspect::value() const
-{
- return transform(BaseAspect::value().toList(),
- [](QVariant v) { return v.toInt(); });
-}
-
-void IntegersAspect::setValue(const QList<int> &value)
-{
- BaseAspect::setValue(transform(value, [](int i) { return QVariant::fromValue<int>(i); }));
-}
-
-QList<int> IntegersAspect::defaultValue() const
-{
- return transform(BaseAspect::defaultValue().toList(),
- [](QVariant v) { return v.toInt(); });
-}
-
-void IntegersAspect::setDefaultValue(const QList<int> &value)
-{
- BaseAspect::setDefaultValue(transform(value, [](int i) { return QVariant::fromValue<int>(i); }));
-}
-
/*!
\class Utils::TextDisplay
@@ -2576,7 +2367,7 @@ void AspectContainer::finish()
void AspectContainer::reset()
{
for (BaseAspect *aspect : std::as_const(d->m_items))
- aspect->setValueQuietly(aspect->defaultValue());
+ aspect->setVariantValueQuietly(aspect->defaultVariantValue());
}
void AspectContainer::setAutoApply(bool on)
@@ -2633,6 +2424,41 @@ BaseAspect::Data::Ptr BaseAspect::extractData() const
return Data::Ptr(data);
}
+/*
+ Mirrors the internal volatile value to the GUI element if they are already
+ created.
+
+ No-op otherwise.
+*/
+void BaseAspect::internalToGui()
+{}
+
+/*
+ Mirrors the data stored in GUI element if they are already created to
+ the internal volatile value.
+
+ No-op otherwise.
+*/
+void BaseAspect::guiToInternal()
+{}
+
+/*
+ Mirrors internal volatile value to the externally visible value.
+ This function is used for \c apply().
+
+ \returns whether the value changes.
+*/
+bool BaseAspect::internalToExternal()
+{
+ return false;
+}
+
+/*
+ Mirrors externally visible value to internal volatile value.
+*/
+void BaseAspect::externalToInternal()
+{}
+
void BaseAspect::addDataExtractorHelper(const DataExtractor &extractor) const
{
d->m_dataExtractors.append(extractor);
diff --git a/src/libs/utils/aspects.h b/src/libs/utils/aspects.h
index 3c69306214..cc603edf54 100644
--- a/src/libs/utils/aspects.h
+++ b/src/libs/utils/aspects.h
@@ -51,12 +51,12 @@ public:
Id id() const;
void setId(Id id);
- QVariant value() const;
- void setValue(const QVariant &value);
- bool setValueQuietly(const QVariant &value);
+ virtual QVariant variantValue() const;
+ virtual void setVariantValue(const QVariant &value);
+ virtual void setVariantValueQuietly(const QVariant &value);
- QVariant defaultValue() const;
- void setDefaultValue(const QVariant &value);
+ virtual QVariant defaultVariantValue() const;
+ virtual void setDefaultVariantValue(const QVariant &value);
QString settingsKey() const;
void setSettingsKey(const QString &settingsKey);
@@ -100,10 +100,6 @@ public:
virtual void addToLayout(Layouting::LayoutItem &parent);
- virtual QVariant volatileValue() const;
- virtual void setVolatileValue(const QVariant &val);
- virtual void emitChangedValue() {}
-
virtual void readSettings(const QSettings *settings);
virtual void writeSettings(QSettings *settings) const;
@@ -114,9 +110,10 @@ public:
QVariant fromSettingsValue(const QVariant &val) const;
virtual void apply();
+ virtual bool silentApply();
virtual void cancel();
virtual void finish();
- virtual bool isDirty() const;
+ virtual bool isDirty();
bool hasAction() const;
class QTCREATOR_UTILS_EXPORT Data
@@ -164,9 +161,15 @@ public:
signals:
void changed();
+ void volatileValueChanged();
void labelLinkActivated(const QString &link);
protected:
+ virtual void internalToGui();
+ virtual void guiToInternal();
+ virtual bool internalToExternal();
+ virtual void externalToInternal();
+
QLabel *label() const;
void setupLabel();
void addLabeledItem(Layouting::LayoutItem &parent, QWidget *widget);
@@ -208,35 +211,125 @@ private:
QTCREATOR_UTILS_EXPORT void createItem(Layouting::LayoutItem *item, const BaseAspect &aspect);
QTCREATOR_UTILS_EXPORT void createItem(Layouting::LayoutItem *item, const BaseAspect *aspect);
-class QTCREATOR_UTILS_EXPORT BoolAspect : public BaseAspect
+template <typename ValueType>
+class TypedAspect : public BaseAspect
{
- Q_OBJECT
-
public:
- BoolAspect(AspectContainer *container = nullptr);
- ~BoolAspect() override;
+ TypedAspect(AspectContainer *container = nullptr)
+ : BaseAspect(container)
+ {
+ addDataExtractor(this, &TypedAspect::value, &Data::value);
+ }
struct Data : BaseAspect::Data
{
- bool value;
+ ValueType value;
};
+ ValueType operator()() const { return m_external; }
+ ValueType value() const { return m_external; }
+ ValueType defaultValue() const { return m_default; }
+
+ void setDefaultValue(const ValueType &value)
+ {
+ m_default = value;
+ setValue(value);
+ }
+
+ void setValue(const ValueType &value)
+ {
+ m_external = value;
+ if (isDirty()) {
+ externalToInternal();
+ internalToGui();
+ }
+ }
+
+ void setValueQuietly(const ValueType &value)
+ {
+ m_external = value;
+ if (isDirty()) {
+ externalToInternal();
+ internalToGui();
+ }
+ }
+
+ void setVolatileValue(const ValueType &value)
+ {
+ m_internal = value;
+ internalToGui();
+ }
+
+ ValueType volatileValue() const
+ {
+ const_cast<TypedAspect *>(this)->guiToInternal();
+ return m_internal;
+ }
+
+protected:
+ bool isDirty() override
+ {
+ guiToInternal();
+ return m_internal != m_external;
+ }
+
+ bool internalToExternal() override
+ {
+ if (m_external == m_internal)
+ return false;
+ m_external = m_internal;
+ return true;
+ }
+
+ void externalToInternal() override
+ {
+ m_internal = m_external;
+ }
+
+ QVariant variantValue() const override
+ {
+ return QVariant::fromValue<ValueType>(m_external);
+ }
+
+ void setVariantValue(const QVariant &value) override
+ {
+ setValue(value.value<ValueType>());
+ }
+
+ void setVariantValueQuietly(const QVariant &value) override
+ {
+ setValueQuietly(value.value<ValueType>());
+ }
+
+ QVariant defaultVariantValue() const override
+ {
+ return QVariant::fromValue<ValueType>(m_default);
+ }
+
+ void setDefaultVariantValue(const QVariant &value) override
+ {
+ m_default = value.value<ValueType>();
+ }
+
+ ValueType m_default{};
+ ValueType m_external{};
+ ValueType m_internal{};
+};
+
+class QTCREATOR_UTILS_EXPORT BoolAspect : public TypedAspect<bool>
+{
+ Q_OBJECT
+
+public:
+ BoolAspect(AspectContainer *container = nullptr);
+ ~BoolAspect() override;
+
void addToLayout(Layouting::LayoutItem &parent) override;
std::function<void(QObject *)> groupChecker();
Utils::CheckableDecider checkableDecider();
QAction *action() override;
- QVariant volatileValue() const override;
- void setVolatileValue(const QVariant &val) override;
- void emitChangedValue() override;
-
- bool operator()() const { return value(); }
- bool value() const;
- void setValue(bool val);
- bool defaultValue() const;
- void setDefaultValue(bool val);
-
enum class LabelPlacement { AtCheckBox, AtCheckBoxWithoutDummyLabel, InExtraLabel };
void setLabel(const QString &labelText,
LabelPlacement labelPlacement = LabelPlacement::InExtraLabel);
@@ -244,15 +337,14 @@ public:
void adoptButton(QAbstractButton *button);
-signals:
- void valueChanged(bool newValue);
- void volatileValueChanged(bool newValue);
-
private:
+ void internalToGui() override;
+ void guiToInternal() override;
+
std::unique_ptr<Internal::BoolAspectPrivate> d;
};
-class QTCREATOR_UTILS_EXPORT ColorAspect : public BaseAspect
+class QTCREATOR_UTILS_EXPORT ColorAspect : public TypedAspect<QColor>
{
Q_OBJECT
@@ -260,24 +352,16 @@ public:
ColorAspect(AspectContainer *container = nullptr);
~ColorAspect() override;
- struct Data : BaseAspect::Data
- {
- QColor value;
- };
-
void addToLayout(Layouting::LayoutItem &parent) override;
- QColor value() const;
- void setValue(const QColor &val);
-
- QVariant volatileValue() const override;
- void setVolatileValue(const QVariant &val) override;
-
private:
+ void internalToGui() override;
+ void guiToInternal() override;
+
std::unique_ptr<Internal::ColorAspectPrivate> d;
};
-class QTCREATOR_UTILS_EXPORT SelectionAspect : public BaseAspect
+class QTCREATOR_UTILS_EXPORT SelectionAspect : public TypedAspect<int>
{
Q_OBJECT
@@ -286,20 +370,13 @@ public:
~SelectionAspect() override;
void addToLayout(Layouting::LayoutItem &parent) override;
- QVariant volatileValue() const override;
- void setVolatileValue(const QVariant &val) override;
void finish() override;
- int operator()() const { return value(); }
- int value() const;
- void setValue(int val);
-
QString stringValue() const;
void setStringValue(const QString &val);
- int defaultValue() const;
- void setDefaultValue(int val);
void setDefaultValue(const QString &val);
+ void setDefaultValue(int val);
QVariant itemValue() const;
@@ -325,14 +402,15 @@ public:
int indexForItemValue(const QVariant &value) const;
QVariant itemValueForIndex(int index) const;
-signals:
- void volatileValueChanged(int newValue);
+protected:
+ void internalToGui() override;
+ void guiToInternal() override;
private:
std::unique_ptr<Internal::SelectionAspectPrivate> d;
};
-class QTCREATOR_UTILS_EXPORT MultiSelectionAspect : public BaseAspect
+class QTCREATOR_UTILS_EXPORT MultiSelectionAspect : public TypedAspect<QStringList>
{
Q_OBJECT
@@ -345,17 +423,18 @@ public:
enum class DisplayStyle { ListView };
void setDisplayStyle(DisplayStyle style);
- QStringList value() const;
- void setValue(const QStringList &val);
-
QStringList allValues() const;
void setAllValues(const QStringList &val);
+protected:
+ void internalToGui() override;
+ void guiToInternal() override;
+
private:
std::unique_ptr<Internal::MultiSelectionAspectPrivate> d;
};
-class QTCREATOR_UTILS_EXPORT StringAspect : public BaseAspect
+class QTCREATOR_UTILS_EXPORT StringAspect : public TypedAspect<QString>
{
Q_OBJECT
@@ -371,21 +450,13 @@ public:
void addToLayout(Layouting::LayoutItem &parent) override;
- QVariant volatileValue() const override;
- void setVolatileValue(const QVariant &val) override;
- void emitChangedValue() override;
-
// Hook between UI and StringAspect:
using ValueAcceptor = std::function<std::optional<QString>(const QString &, const QString &)>;
void setValueAcceptor(ValueAcceptor &&acceptor);
- QString operator()() const { return value(); }
QString value() const;
void setValue(const QString &val);
- QString defaultValue() const;
- void setDefaultValue(const QString &val);
-
void setShowToolTipOnLabel(bool show);
void setDisplayFilter(const std::function<QString (const QString &)> &displayFilter);
@@ -438,10 +509,10 @@ public:
signals:
void checkedChanged();
- void valueChanged(const QString &newValue);
protected:
- void update();
+ void internalToGui() override;
+ void guiToInternal() override;
std::unique_ptr<Internal::StringAspectPrivate> d;
};
@@ -454,7 +525,7 @@ public:
FilePath operator()() const { return filePath(); }
};
-class QTCREATOR_UTILS_EXPORT IntegerAspect : public BaseAspect
+class QTCREATOR_UTILS_EXPORT IntegerAspect : public TypedAspect<qint64>
{
Q_OBJECT
@@ -464,16 +535,6 @@ public:
void addToLayout(Layouting::LayoutItem &parent) override;
- QVariant volatileValue() const override;
- void setVolatileValue(const QVariant &val) override;
-
- qint64 operator()() const { return value(); }
- qint64 value() const;
- void setValue(qint64 val);
-
- qint64 defaultValue() const;
- void setDefaultValue(qint64 defaultValue);
-
void setRange(qint64 min, qint64 max);
void setLabel(const QString &label); // FIXME: Use setLabelText
void setPrefix(const QString &prefix);
@@ -485,14 +546,15 @@ public:
struct Data : BaseAspect::Data { qint64 value = 0; };
-signals:
- void valueChanged(int newValue);
+protected:
+ void internalToGui() override;
+ void guiToInternal() override;
private:
std::unique_ptr<Internal::IntegerAspectPrivate> d;
};
-class QTCREATOR_UTILS_EXPORT DoubleAspect : public BaseAspect
+class QTCREATOR_UTILS_EXPORT DoubleAspect : public TypedAspect<double>
{
Q_OBJECT
@@ -502,22 +564,16 @@ public:
void addToLayout(Layouting::LayoutItem &parent) override;
- QVariant volatileValue() const override;
- void setVolatileValue(const QVariant &val) override;
-
- double operator()() const { return value(); }
- double value() const;
- void setValue(double val);
-
- double defaultValue() const;
- void setDefaultValue(double defaultValue);
-
void setRange(double min, double max);
void setPrefix(const QString &prefix);
void setSuffix(const QString &suffix);
void setSpecialValueText(const QString &specialText);
void setSingleStep(double step);
+protected:
+ void internalToGui() override;
+ void guiToInternal() override;
+
private:
std::unique_ptr<Internal::DoubleAspectPrivate> d;
};
@@ -532,6 +588,7 @@ public:
int toInt() const { return int(m_value); }
QVariant toVariant() const { return int(m_value); }
+ static TriState fromInt(int value);
static TriState fromVariant(const QVariant &variant);
static const TriState Enabled;
@@ -562,7 +619,7 @@ public:
void setDefaultValue(TriState setting);
};
-class QTCREATOR_UTILS_EXPORT StringListAspect : public BaseAspect
+class QTCREATOR_UTILS_EXPORT StringListAspect : public TypedAspect<QStringList>
{
Q_OBJECT
@@ -572,9 +629,6 @@ public:
void addToLayout(Layouting::LayoutItem &parent) override;
- QStringList value() const;
- void setValue(const QStringList &val);
-
void appendValue(const QString &value, bool allowDuplicates = true);
void removeValue(const QString &value);
void appendValues(const QStringList &values, bool allowDuplicates = true);
@@ -584,7 +638,7 @@ private:
std::unique_ptr<Internal::StringListAspectPrivate> d;
};
-class QTCREATOR_UTILS_EXPORT IntegersAspect : public BaseAspect
+class QTCREATOR_UTILS_EXPORT IntegersAspect : public TypedAspect<QList<int>>
{
Q_OBJECT
@@ -593,17 +647,6 @@ public:
~IntegersAspect() override;
void addToLayout(Layouting::LayoutItem &parent) override;
- void emitChangedValue() override;
-
- QList<int> operator()() const { return value(); }
- QList<int> value() const;
- void setValue(const QList<int> &value);
-
- QList<int> defaultValue() const;
- void setDefaultValue(const QList<int> &value);
-
-signals:
- void valueChanged(const QList<int> &values);
};
class QTCREATOR_UTILS_EXPORT TextDisplay : public BaseAspect