/**************************************************************************** ** ** Copyright (C) 2018 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. ** ****************************************************************************/ #include "aspects.h" #include "algorithm.h" #include "fancylineedit.h" #include "layoutbuilder.h" #include "pathchooser.h" #include "qtcassert.h" #include "qtcprocess.h" #include "utilsicons.h" #include "variablechooser.h" #include #include #include #include #include #include #include #include #include #include #include #include namespace Utils { namespace Internal { class BaseAspectPrivate { public: Utils::Id m_id; QString m_displayName; QString m_settingsKey; // Name of data in settings. QString m_tooltip; bool m_visible = true; bool m_enabled = true; bool m_readOnly = true; BaseAspect::ConfigWidgetCreator m_configWidgetCreator; QList> m_subWidgets; }; } // Internal /*! \class Utils::BaseAspect \inmodule QtCreator \brief The \c BaseAspect class provides a common base for classes implementing aspects. An aspect is a hunk of data like a property or collection of related properties of some object, together with a description of its behavior for common operations like visualizing or persisting. Simple aspects are for example a boolean property represented by a QCheckBox in the user interface, or a string property represented by a PathChooser, selecting directories in the filesystem. While aspects implementations usually have the ability to visualize and to persist their data, or use an ID, neither of these is mandatory. */ /*! Constructs a BaseAspect. */ BaseAspect::BaseAspect() : d(new Internal::BaseAspectPrivate) {} /*! Destructs a BaseAspect. */ BaseAspect::~BaseAspect() = default; Id BaseAspect::id() const { return d->m_id; } void BaseAspect::setId(Id id) { d->m_id = id; } void BaseAspect::setDisplayName(const QString &displayName) { d->m_displayName = displayName; } bool BaseAspect::isVisible() const { return d->m_visible; } /*! Shows or hides the visual representation of this aspect depending on the value of \a visible. By default, it is visible. */ void BaseAspect::setVisible(bool visible) { d->m_visible = visible; for (QWidget *w : qAsConst(d->m_subWidgets)) { QTC_ASSERT(w, continue); w->setVisible(visible); } } QString BaseAspect::toolTip() const { return d->m_tooltip; } /*! Sets \a tooltip as tool tip for the visual representation of this aspect. */ void BaseAspect::setToolTip(const QString &tooltip) { d->m_tooltip = tooltip; for (QWidget *w : qAsConst(d->m_subWidgets)) { QTC_ASSERT(w, continue); w->setToolTip(tooltip); } } void BaseAspect::setEnabled(bool enabled) { d->m_enabled = enabled; for (QWidget *w : qAsConst(d->m_subWidgets)) { QTC_ASSERT(w, continue); w->setEnabled(enabled); } } void BaseAspect::setReadOnly(bool readOnly) { d->m_readOnly = readOnly; for (QWidget *w : qAsConst(d->m_subWidgets)) { QTC_ASSERT(w, continue); if (auto lineEdit = qobject_cast(w)) lineEdit->setReadOnly(readOnly); else if (auto textEdit = qobject_cast(w)) textEdit->setReadOnly(readOnly); } } /*! \internal */ void BaseAspect::setConfigWidgetCreator(const ConfigWidgetCreator &configWidgetCreator) { d->m_configWidgetCreator = configWidgetCreator; } /*! Returns the key to be used when accessing the settings. \sa setSettingsKey() */ QString BaseAspect::settingsKey() const { return d->m_settingsKey; } /*! Sets the key to be used when accessing the settings. \sa settingsKey() */ void BaseAspect::setSettingsKey(const QString &key) { d->m_settingsKey = key; } /*! Sets the key and group to be used when accessing the settings. \sa settingsKey() */ void BaseAspect::setSettingsKey(const QString &group, const QString &key) { d->m_settingsKey = group + "/" + key; } QString BaseAspect::displayName() const { return d->m_displayName; } /*! \internal */ QWidget *BaseAspect::createConfigWidget() const { return d->m_configWidgetCreator ? d->m_configWidgetCreator() : nullptr; } /*! Adds the visual representation of this aspect to a layout using a layout builder. */ void BaseAspect::addToLayout(LayoutBuilder &) { } void BaseAspect::registerSubWidget(QWidget *widget) { d->m_subWidgets.append(widget); connect(widget, &QObject::destroyed, this, [this, widget] { d->m_subWidgets.removeAll(widget); }); widget->setEnabled(d->m_enabled); widget->setToolTip(d->m_tooltip); // Visible is on by default. Not setting it explicitly avoid popping // it up when the parent is not set yet, the normal case. if (!d->m_visible) widget->setVisible(d->m_visible); } void BaseAspect::saveToMap(QVariantMap &data, const QVariant &value, const QVariant &defaultValue, const QString &keyExtension) const { if (settingsKey().isEmpty()) return; const QString key = settingsKey() + keyExtension; if (value == defaultValue) data.remove(key); else data.insert(key, value); } /*! Retrieves the internal value of this BaseAspect from a \c QVariantMap. This base implementation does nothing. */ void BaseAspect::fromMap(const QVariantMap &) {} /*! Stores the internal value of this BaseAspect into a \c QVariantMap. This base implementation does nothing. */ void BaseAspect::toMap(QVariantMap &) const {} /*! \internal */ void BaseAspect::acquaintSiblings(const BaseAspects &) {} // BaseAspects /*! \class BaseAspects \inmodule QtCreator \brief This class represent a collection of one or more aspects. A BaseAspects object assumes ownership on its aspects. */ /*! Constructs a BaseAspects object. */ BaseAspects::BaseAspects() = default; /*! Destructs a BaseAspects object. */ BaseAspects::~BaseAspects() { qDeleteAll(m_aspects); } /*! Retrieves a BaseAspect with a given \a id, or nullptr if no such aspect is contained. \sa BaseAspect. */ BaseAspect *BaseAspects::aspect(Utils::Id id) const { return Utils::findOrDefault(m_aspects, Utils::equal(&BaseAspect::id, id)); } /*! \internal */ void BaseAspects::fromMap(const QVariantMap &map) const { for (BaseAspect *aspect : m_aspects) aspect->fromMap(map); } /*! \internal */ void BaseAspects::toMap(QVariantMap &map) const { for (BaseAspect *aspect : m_aspects) aspect->toMap(map); } namespace Internal { class BoolAspectPrivate { public: BoolAspect::LabelPlacement m_labelPlacement = BoolAspect::LabelPlacement::AtCheckBox; bool m_value = false; bool m_defaultValue = false; QString m_labelText; QPointer m_checkBox; // Owned by configuration widget QPointer m_label; // Owned by configuration widget }; class SelectionAspectPrivate { public: int m_value = 0; int m_defaultValue = 0; SelectionAspect::DisplayStyle m_displayStyle = SelectionAspect::DisplayStyle::RadioButtons; struct Option { QString displayName; QString tooltip; }; QVector