Files
qt-creator/src/libs/utils/aspects.h
Christian Stenger 4d63206d95 Utils: Add helper methods for SelectionAspect
Change-Id: Idda6ac0846549f37e934d3e856c453ed314c7880
Reviewed-by: hjk <hjk@qt.io>
2021-04-19 06:20:03 +00:00

576 lines
16 KiB
C++

/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include "fileutils.h"
#include "id.h"
#include "infolabel.h"
#include "macroexpander.h"
#include "optional.h"
#include "pathchooser.h"
#include <functional>
#include <memory>
QT_BEGIN_NAMESPACE
class QAction;
class QGroupBox;
class QSettings;
QT_END_NAMESPACE
namespace Utils {
class AspectContainer;
class BoolAspect;
class LayoutBuilder;
namespace Internal {
class AspectContainerPrivate;
class BaseAspectPrivate;
class BoolAspectPrivate;
class DoubleAspectPrivate;
class IntegerAspectPrivate;
class MultiSelectionAspectPrivate;
class SelectionAspectPrivate;
class StringAspectPrivate;
class StringListAspectPrivate;
class TextDisplayPrivate;
} // Internal
class QTCREATOR_UTILS_EXPORT BaseAspect : public QObject
{
Q_OBJECT
public:
BaseAspect();
~BaseAspect() override;
Utils::Id id() const;
void setId(Utils::Id id);
QVariant value() const;
void setValue(const QVariant &value);
bool setValueQuietly(const QVariant &value);
QVariant defaultValue() const;
void setDefaultValue(const QVariant &value);
QString settingsKey() const;
void setSettingsKey(const QString &settingsKey);
void setSettingsKey(const QString &group, const QString &key);
QString displayName() const;
void setDisplayName(const QString &displayName);
QString toolTip() const;
void setToolTip(const QString &tooltip);
bool isVisible() const;
void setVisible(bool visible);
bool isAutoApply() const;
void setAutoApply(bool on);
bool isEnabled() const;
void setEnabled(bool enabled);
void setEnabler(BoolAspect *checker);
bool isReadOnly() const;
void setReadOnly(bool enabled);
void setSpan(int x, int y = 1);
QString labelText() const;
void setLabelText(const QString &labelText);
void setLabelPixmap(const QPixmap &labelPixmap);
void setIcon(const QIcon &labelIcon);
using ConfigWidgetCreator = std::function<QWidget *()>;
void setConfigWidgetCreator(const ConfigWidgetCreator &configWidgetCreator);
QWidget *createConfigWidget() const;
virtual QAction *action();
virtual void fromMap(const QVariantMap &map);
virtual void toMap(QVariantMap &map) const;
virtual void toActiveMap(QVariantMap &map) const { toMap(map); }
virtual void acquaintSiblings(const AspectContainer &);
virtual void addToLayout(LayoutBuilder &builder);
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;
using SavedValueTransformation = std::function<QVariant(const QVariant &)>;
void setFromSettingsTransformation(const SavedValueTransformation &transform);
void setToSettingsTransformation(const SavedValueTransformation &transform);
QVariant toSettingsValue(const QVariant &val) const;
QVariant fromSettingsValue(const QVariant &val) const;
virtual void apply();
virtual void cancel();
virtual void finish();
bool isDirty() const;
bool hasAction() const;
signals:
void changed();
protected:
QLabel *label() const;
void setupLabel();
void addLabeledItem(LayoutBuilder &builder, QWidget *widget);
template <class Widget, typename ...Args>
Widget *createSubWidget(Args && ...args) {
auto w = new Widget(args...);
registerSubWidget(w);
return w;
}
void registerSubWidget(QWidget *widget);
static void saveToMap(QVariantMap &data, const QVariant &value,
const QVariant &defaultValue, const QString &key);
private:
std::unique_ptr<Internal::BaseAspectPrivate> d;
};
class QTCREATOR_UTILS_EXPORT BoolAspect : public BaseAspect
{
Q_OBJECT
public:
explicit BoolAspect(const QString &settingsKey = QString());
~BoolAspect() override;
void addToLayout(LayoutBuilder &builder) override;
QAction *action() override;
QVariant volatileValue() const override;
void setVolatileValue(const QVariant &val) override;
void emitChangedValue() override;
bool value() const;
void setValue(bool val);
void setDefaultValue(bool val);
enum class LabelPlacement { AtCheckBox, AtCheckBoxWithoutDummyLabel, InExtraLabel };
void setLabel(const QString &labelText,
LabelPlacement labelPlacement = LabelPlacement::InExtraLabel);
void setLabelPlacement(LabelPlacement labelPlacement);
void setHandlesGroup(QGroupBox *box);
signals:
void valueChanged(bool newValue);
void volatileValueChanged(bool newValue);
private:
std::unique_ptr<Internal::BoolAspectPrivate> d;
};
class QTCREATOR_UTILS_EXPORT SelectionAspect : public BaseAspect
{
Q_OBJECT
public:
SelectionAspect();
~SelectionAspect() override;
void addToLayout(LayoutBuilder &builder) override;
QVariant volatileValue() const override;
void setVolatileValue(const QVariant &val) override;
void finish() override;
int value() const;
void setValue(int val);
void setStringValue(const QString &val);
void setDefaultValue(int val);
void setDefaultValue(const QString &val);
QString stringValue() const;
QVariant itemValue() const;
enum class DisplayStyle { RadioButtons, ComboBox };
void setDisplayStyle(DisplayStyle style);
class Option
{
public:
Option(const QString &displayName, const QString &toolTip, const QVariant &itemData)
: displayName(displayName), tooltip(toolTip), itemData(itemData)
{}
QString displayName;
QString tooltip;
QVariant itemData;
bool enabled = true;
};
void addOption(const QString &displayName, const QString &toolTip = {});
void addOption(const Option &option);
int indexForDisplay(const QString &displayName) const;
QString displayForIndex(int index) const;
int indexForItemValue(const QVariant &value) const;
QVariant itemValueForIndex(int index) const;
signals:
void volatileValueChanged(int newValue);
private:
std::unique_ptr<Internal::SelectionAspectPrivate> d;
};
class QTCREATOR_UTILS_EXPORT MultiSelectionAspect : public BaseAspect
{
Q_OBJECT
public:
MultiSelectionAspect();
~MultiSelectionAspect() override;
void addToLayout(LayoutBuilder &builder) override;
enum class DisplayStyle { ListView };
void setDisplayStyle(DisplayStyle style);
QStringList value() const;
void setValue(const QStringList &val);
QStringList allValues() const;
void setAllValues(const QStringList &val);
private:
std::unique_ptr<Internal::MultiSelectionAspectPrivate> d;
};
class QTCREATOR_UTILS_EXPORT StringAspect : public BaseAspect
{
Q_OBJECT
public:
StringAspect();
~StringAspect() override;
void addToLayout(LayoutBuilder &builder) override;
QVariant volatileValue() const override;
void setVolatileValue(const QVariant &val) override;
void emitChangedValue() override;
// Hook between UI and StringAspect:
using ValueAcceptor = std::function<Utils::optional<QString>(const QString &, const QString &)>;
void setValueAcceptor(ValueAcceptor &&acceptor);
QString value() const;
void setValue(const QString &val);
void setDefaultValue(const QString &val);
void setShowToolTipOnLabel(bool show);
void setDisplayFilter(const std::function<QString (const QString &)> &displayFilter);
void setPlaceHolderText(const QString &placeHolderText);
void setHistoryCompleter(const QString &historyCompleterKey);
void setExpectedKind(const Utils::PathChooser::Kind expectedKind);
void setFileDialogOnly(bool requireFileDialog);
void setEnvironment(const Utils::Environment &env);
void setBaseFileName(const Utils::FilePath &baseFileName);
void setUndoRedoEnabled(bool readOnly);
void setAcceptRichText(bool acceptRichText);
void setMacroExpanderProvider(const Utils::MacroExpanderProvider &expanderProvider);
void setUseGlobalMacroExpander();
void setUseResetButton();
void setValidationFunction(const Utils::FancyLineEdit::ValidationFunction &validator);
void setOpenTerminalHandler(const std::function<void()> &openTerminal);
void validateInput();
enum class UncheckedSemantics { Disabled, ReadOnly };
enum class CheckBoxPlacement { Top, Right };
void setUncheckedSemantics(UncheckedSemantics semantics);
bool isChecked() const;
void setChecked(bool checked);
void makeCheckable(CheckBoxPlacement checkBoxPlacement, const QString &optionalLabel,
const QString &optionalBaseKey);
enum DisplayStyle {
LabelDisplay,
LineEditDisplay,
TextEditDisplay,
PathChooserDisplay
};
void setDisplayStyle(DisplayStyle style);
void fromMap(const QVariantMap &map) override;
void toMap(QVariantMap &map) const override;
Utils::FilePath filePath() const;
void setFilePath(const Utils::FilePath &value);
PathChooser *pathChooser() const; // Avoid to use.
signals:
void checkedChanged();
void valueChanged(const QString &newValue);
protected:
void update();
std::unique_ptr<Internal::StringAspectPrivate> d;
};
class QTCREATOR_UTILS_EXPORT IntegerAspect : public BaseAspect
{
Q_OBJECT
public:
IntegerAspect();
~IntegerAspect() override;
void addToLayout(LayoutBuilder &builder) override;
QVariant volatileValue() const override;
void setVolatileValue(const QVariant &val) override;
qint64 value() const;
void setValue(qint64 val);
void setDefaultValue(qint64 defaultValue);
void setRange(qint64 min, qint64 max);
void setLabel(const QString &label); // FIXME: Use setLabelText
void setPrefix(const QString &prefix);
void setSuffix(const QString &suffix);
void setDisplayIntegerBase(int base);
void setDisplayScaleFactor(qint64 factor);
void setSpecialValueText(const QString &specialText);
void setSingleStep(qint64 step);
private:
std::unique_ptr<Internal::IntegerAspectPrivate> d;
};
class QTCREATOR_UTILS_EXPORT DoubleAspect : public BaseAspect
{
Q_OBJECT
public:
DoubleAspect();
~DoubleAspect() override;
void addToLayout(LayoutBuilder &builder) override;
QVariant volatileValue() const override;
void setVolatileValue(const QVariant &val) override;
double value() const;
void setValue(double val);
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);
private:
std::unique_ptr<Internal::DoubleAspectPrivate> d;
};
class QTCREATOR_UTILS_EXPORT TriState
{
enum Value { EnabledValue, DisabledValue, DefaultValue };
explicit TriState(Value v) : m_value(v) {}
public:
TriState() = default;
QVariant toVariant() const { return int(m_value); }
static TriState fromVariant(const QVariant &variant);
static const TriState Enabled;
static const TriState Disabled;
static const TriState Default;
friend bool operator==(TriState a, TriState b) { return a.m_value == b.m_value; }
friend bool operator!=(TriState a, TriState b) { return a.m_value != b.m_value; }
private:
Value m_value = DefaultValue;
};
class QTCREATOR_UTILS_EXPORT TriStateAspect : public SelectionAspect
{
Q_OBJECT
public:
TriStateAspect(
const QString onString = tr("Enable"),
const QString &offString = tr("Disable"),
const QString &defaultString = tr("Leave at Default"));
TriState value() const;
void setValue(TriState setting);
void setDefaultValue(TriState setting);
};
class QTCREATOR_UTILS_EXPORT StringListAspect : public BaseAspect
{
Q_OBJECT
public:
StringListAspect();
~StringListAspect() override;
void addToLayout(LayoutBuilder &builder) 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);
void removeValues(const QStringList &values);
private:
std::unique_ptr<Internal::StringListAspectPrivate> d;
};
class QTCREATOR_UTILS_EXPORT IntegersAspect : public BaseAspect
{
Q_OBJECT
public:
IntegersAspect();
~IntegersAspect() override;
void addToLayout(LayoutBuilder &builder) override;
void emitChangedValue() override;
QList<int> value() const;
void setValue(const QList<int> &value);
void setDefaultValue(const QList<int> &value);
signals:
void valueChanged(const QList<int> &values);
};
class QTCREATOR_UTILS_EXPORT TextDisplay : public BaseAspect
{
Q_OBJECT
public:
TextDisplay(const QString &message = {},
Utils::InfoLabel::InfoType type = Utils::InfoLabel::None);
~TextDisplay() override;
void addToLayout(LayoutBuilder &builder) override;
void setIconType(Utils::InfoLabel::InfoType t);
void setText(const QString &message);
private:
std::unique_ptr<Internal::TextDisplayPrivate> d;
};
class QTCREATOR_UTILS_EXPORT AspectContainer : public QObject
{
Q_OBJECT
public:
AspectContainer(QObject *parent = nullptr);
~AspectContainer();
AspectContainer(const AspectContainer &) = delete;
AspectContainer &operator=(const AspectContainer &) = delete;
void registerAspect(BaseAspect *aspect);
void registerAspects(const AspectContainer &aspects);
template <class Aspect, typename ...Args>
Aspect *addAspect(Args && ...args)
{
auto aspect = new Aspect(args...);
registerAspect(aspect);
return aspect;
}
void fromMap(const QVariantMap &map);
void toMap(QVariantMap &map) const;
void readSettings(QSettings *settings);
void writeSettings(QSettings *settings) const;
void setSettingsGroup(const QString &groupKey);
void setSettingsGroups(const QString &groupKey, const QString &subGroupKey);
void apply();
void cancel();
void finish();
void reset();
bool equals(const AspectContainer &other) const;
void copyFrom(const AspectContainer &other);
void setAutoApply(bool on);
void setOwnsSubAspects(bool on);
bool isDirty() const;
template <typename T> T *aspect() const
{
for (BaseAspect *aspect : aspects())
if (T *result = qobject_cast<T *>(aspect))
return result;
return nullptr;
}
BaseAspect *aspect(Utils::Id id) const;
template <typename T> T *aspect(Utils::Id id) const
{
return qobject_cast<T*>(aspect(id));
}
void forEachAspect(const std::function<void(BaseAspect *)> &run) const;
const QList<BaseAspect *> &aspects() const;
using const_iterator = QList<BaseAspect *>::const_iterator;
using value_type = QList<BaseAspect *>::value_type;
const_iterator begin() const;
const_iterator end() const;
signals:
void applied();
void fromMapFinished();
private:
std::unique_ptr<Internal::AspectContainerPrivate> d;
};
} // namespace Utils