1 /**************************************************************************** 2 ** 3 ** Copyright (C) 2020 The Qt Company Ltd. 4 ** Contact: https://www.qt.io/licensing/ 5 ** 6 ** This file is part of Qt Creator. 7 ** 8 ** Commercial License Usage 9 ** Licensees holding valid commercial Qt licenses may use this file in 10 ** accordance with the commercial license agreement provided with the 11 ** Software or, alternatively, in accordance with the terms contained in 12 ** a written agreement between you and The Qt Company. For licensing terms 13 ** and conditions see https://www.qt.io/terms-conditions. For further 14 ** information use the contact form at https://www.qt.io/contact-us. 15 ** 16 ** GNU General Public License Usage 17 ** Alternatively, this file may be used under the terms of the GNU 18 ** General Public License version 3 as published by the Free Software 19 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT 20 ** included in the packaging of this file. Please review the following 21 ** information to ensure the GNU General Public License requirements will 22 ** be met: https://www.gnu.org/licenses/gpl-3.0.html. 23 ** 24 ****************************************************************************/ 25 26 #pragma once 27 28 #include "fileutils.h" 29 #include "id.h" 30 #include "infolabel.h" 31 #include "macroexpander.h" 32 #include "optional.h" 33 #include "pathchooser.h" 34 35 #include <functional> 36 #include <memory> 37 38 QT_BEGIN_NAMESPACE 39 class QAction; 40 class QGroupBox; 41 class QSettings; 42 QT_END_NAMESPACE 43 44 namespace Utils { 45 46 class AspectContainer; 47 class BoolAspect; 48 class LayoutBuilder; 49 50 namespace Internal { 51 class AspectContainerPrivate; 52 class BaseAspectPrivate; 53 class BoolAspectPrivate; 54 class DoubleAspectPrivate; 55 class IntegerAspectPrivate; 56 class MultiSelectionAspectPrivate; 57 class SelectionAspectPrivate; 58 class StringAspectPrivate; 59 class StringListAspectPrivate; 60 class TextDisplayPrivate; 61 } // Internal 62 63 class QTCREATOR_UTILS_EXPORT BaseAspect : public QObject 64 { 65 Q_OBJECT 66 67 public: 68 BaseAspect(); 69 ~BaseAspect() override; 70 71 Utils::Id id() const; 72 void setId(Utils::Id id); 73 74 QVariant value() const; 75 void setValue(const QVariant &value); 76 bool setValueQuietly(const QVariant &value); 77 78 QVariant defaultValue() const; 79 void setDefaultValue(const QVariant &value); 80 81 QString settingsKey() const; 82 void setSettingsKey(const QString &settingsKey); 83 void setSettingsKey(const QString &group, const QString &key); 84 85 QString displayName() const; 86 void setDisplayName(const QString &displayName); 87 88 QString toolTip() const; 89 void setToolTip(const QString &tooltip); 90 91 bool isVisible() const; 92 void setVisible(bool visible); 93 94 bool isAutoApply() const; 95 void setAutoApply(bool on); 96 97 bool isEnabled() const; 98 void setEnabled(bool enabled); 99 void setEnabler(BoolAspect *checker); 100 101 bool isReadOnly() const; 102 void setReadOnly(bool enabled); 103 104 void setSpan(int x, int y = 1); 105 106 QString labelText() const; 107 void setLabelText(const QString &labelText); 108 void setLabelPixmap(const QPixmap &labelPixmap); 109 void setIcon(const QIcon &labelIcon); 110 111 using ConfigWidgetCreator = std::function<QWidget *()>; 112 void setConfigWidgetCreator(const ConfigWidgetCreator &configWidgetCreator); 113 QWidget *createConfigWidget() const; 114 115 virtual QAction *action(); 116 117 virtual void fromMap(const QVariantMap &map); 118 virtual void toMap(QVariantMap &map) const; toActiveMap(QVariantMap & map)119 virtual void toActiveMap(QVariantMap &map) const { toMap(map); } 120 virtual void acquaintSiblings(const AspectContainer &); 121 122 virtual void addToLayout(LayoutBuilder &builder); 123 124 virtual QVariant volatileValue() const; 125 virtual void setVolatileValue(const QVariant &val); emitChangedValue()126 virtual void emitChangedValue() {} 127 128 virtual void readSettings(const QSettings *settings); 129 virtual void writeSettings(QSettings *settings) const; 130 131 using SavedValueTransformation = std::function<QVariant(const QVariant &)>; 132 void setFromSettingsTransformation(const SavedValueTransformation &transform); 133 void setToSettingsTransformation(const SavedValueTransformation &transform); 134 QVariant toSettingsValue(const QVariant &val) const; 135 QVariant fromSettingsValue(const QVariant &val) const; 136 137 virtual void apply(); 138 virtual void cancel(); 139 virtual void finish(); 140 bool isDirty() const; 141 bool hasAction() const; 142 143 signals: 144 void changed(); 145 146 protected: 147 QLabel *label() const; 148 void setupLabel(); 149 void addLabeledItem(LayoutBuilder &builder, QWidget *widget); 150 151 template <class Widget, typename ...Args> createSubWidget(Args &&...args)152 Widget *createSubWidget(Args && ...args) { 153 auto w = new Widget(args...); 154 registerSubWidget(w); 155 return w; 156 } 157 158 void registerSubWidget(QWidget *widget); 159 static void saveToMap(QVariantMap &data, const QVariant &value, 160 const QVariant &defaultValue, const QString &key); 161 162 private: 163 std::unique_ptr<Internal::BaseAspectPrivate> d; 164 }; 165 166 class QTCREATOR_UTILS_EXPORT BoolAspect : public BaseAspect 167 { 168 Q_OBJECT 169 170 public: 171 explicit BoolAspect(const QString &settingsKey = QString()); 172 ~BoolAspect() override; 173 174 void addToLayout(LayoutBuilder &builder) override; 175 176 QAction *action() override; 177 178 QVariant volatileValue() const override; 179 void setVolatileValue(const QVariant &val) override; 180 void emitChangedValue() override; 181 182 bool value() const; 183 void setValue(bool val); 184 void setDefaultValue(bool val); 185 186 enum class LabelPlacement { AtCheckBox, AtCheckBoxWithoutDummyLabel, InExtraLabel }; 187 void setLabel(const QString &labelText, 188 LabelPlacement labelPlacement = LabelPlacement::InExtraLabel); 189 void setLabelPlacement(LabelPlacement labelPlacement); 190 void setHandlesGroup(QGroupBox *box); 191 192 signals: 193 void valueChanged(bool newValue); 194 void volatileValueChanged(bool newValue); 195 196 private: 197 std::unique_ptr<Internal::BoolAspectPrivate> d; 198 }; 199 200 class QTCREATOR_UTILS_EXPORT SelectionAspect : public BaseAspect 201 { 202 Q_OBJECT 203 204 public: 205 SelectionAspect(); 206 ~SelectionAspect() override; 207 208 void addToLayout(LayoutBuilder &builder) override; 209 QVariant volatileValue() const override; 210 void setVolatileValue(const QVariant &val) override; 211 void finish() override; 212 213 int value() const; 214 void setValue(int val); 215 void setStringValue(const QString &val); 216 void setDefaultValue(int val); 217 void setDefaultValue(const QString &val); 218 219 QString stringValue() const; 220 QVariant itemValue() const; 221 222 enum class DisplayStyle { RadioButtons, ComboBox }; 223 void setDisplayStyle(DisplayStyle style); 224 225 class Option 226 { 227 public: Option(const QString & displayName,const QString & toolTip,const QVariant & itemData)228 Option(const QString &displayName, const QString &toolTip, const QVariant &itemData) 229 : displayName(displayName), tooltip(toolTip), itemData(itemData) 230 {} 231 QString displayName; 232 QString tooltip; 233 QVariant itemData; 234 bool enabled = true; 235 }; 236 237 void addOption(const QString &displayName, const QString &toolTip = {}); 238 void addOption(const Option &option); 239 int indexForDisplay(const QString &displayName) const; 240 QString displayForIndex(int index) const; 241 int indexForItemValue(const QVariant &value) const; 242 QVariant itemValueForIndex(int index) const; 243 244 signals: 245 void volatileValueChanged(int newValue); 246 247 private: 248 std::unique_ptr<Internal::SelectionAspectPrivate> d; 249 }; 250 251 class QTCREATOR_UTILS_EXPORT MultiSelectionAspect : public BaseAspect 252 { 253 Q_OBJECT 254 255 public: 256 MultiSelectionAspect(); 257 ~MultiSelectionAspect() override; 258 259 void addToLayout(LayoutBuilder &builder) override; 260 261 enum class DisplayStyle { ListView }; 262 void setDisplayStyle(DisplayStyle style); 263 264 QStringList value() const; 265 void setValue(const QStringList &val); 266 267 QStringList allValues() const; 268 void setAllValues(const QStringList &val); 269 270 private: 271 std::unique_ptr<Internal::MultiSelectionAspectPrivate> d; 272 }; 273 274 class QTCREATOR_UTILS_EXPORT StringAspect : public BaseAspect 275 { 276 Q_OBJECT 277 278 public: 279 StringAspect(); 280 ~StringAspect() override; 281 282 void addToLayout(LayoutBuilder &builder) override; 283 284 QVariant volatileValue() const override; 285 void setVolatileValue(const QVariant &val) override; 286 void emitChangedValue() override; 287 288 // Hook between UI and StringAspect: 289 using ValueAcceptor = std::function<Utils::optional<QString>(const QString &, const QString &)>; 290 void setValueAcceptor(ValueAcceptor &&acceptor); 291 QString value() const; 292 void setValue(const QString &val); 293 void setDefaultValue(const QString &val); 294 295 void setShowToolTipOnLabel(bool show); 296 297 void setDisplayFilter(const std::function<QString (const QString &)> &displayFilter); 298 void setPlaceHolderText(const QString &placeHolderText); 299 void setHistoryCompleter(const QString &historyCompleterKey); 300 void setExpectedKind(const Utils::PathChooser::Kind expectedKind); 301 void setEnvironment(const Utils::Environment &env); 302 void setBaseFileName(const Utils::FilePath &baseFileName); 303 void setUndoRedoEnabled(bool readOnly); 304 void setAcceptRichText(bool acceptRichText); 305 void setMacroExpanderProvider(const Utils::MacroExpanderProvider &expanderProvider); 306 void setUseGlobalMacroExpander(); 307 void setUseResetButton(); 308 void setValidationFunction(const Utils::FancyLineEdit::ValidationFunction &validator); 309 void setOpenTerminalHandler(const std::function<void()> &openTerminal); 310 void setAutoApplyOnEditingFinished(bool applyOnEditingFinished); 311 312 void validateInput(); 313 314 enum class UncheckedSemantics { Disabled, ReadOnly }; 315 enum class CheckBoxPlacement { Top, Right }; 316 void setUncheckedSemantics(UncheckedSemantics semantics); 317 bool isChecked() const; 318 void setChecked(bool checked); 319 void makeCheckable(CheckBoxPlacement checkBoxPlacement, const QString &optionalLabel, 320 const QString &optionalBaseKey); 321 322 enum DisplayStyle { 323 LabelDisplay, 324 LineEditDisplay, 325 TextEditDisplay, 326 PathChooserDisplay 327 }; 328 void setDisplayStyle(DisplayStyle style); 329 330 void fromMap(const QVariantMap &map) override; 331 void toMap(QVariantMap &map) const override; 332 333 Utils::FilePath filePath() const; 334 void setFilePath(const Utils::FilePath &value); 335 336 PathChooser *pathChooser() const; // Avoid to use. 337 338 signals: 339 void checkedChanged(); 340 void valueChanged(const QString &newValue); 341 342 protected: 343 void update(); 344 345 std::unique_ptr<Internal::StringAspectPrivate> d; 346 }; 347 348 class QTCREATOR_UTILS_EXPORT IntegerAspect : public BaseAspect 349 { 350 Q_OBJECT 351 352 public: 353 IntegerAspect(); 354 ~IntegerAspect() override; 355 356 void addToLayout(LayoutBuilder &builder) override; 357 358 QVariant volatileValue() const override; 359 void setVolatileValue(const QVariant &val) override; 360 361 qint64 value() const; 362 void setValue(qint64 val); 363 void setDefaultValue(qint64 defaultValue); 364 365 void setRange(qint64 min, qint64 max); 366 void setLabel(const QString &label); // FIXME: Use setLabelText 367 void setPrefix(const QString &prefix); 368 void setSuffix(const QString &suffix); 369 void setDisplayIntegerBase(int base); 370 void setDisplayScaleFactor(qint64 factor); 371 void setSpecialValueText(const QString &specialText); 372 void setSingleStep(qint64 step); 373 374 private: 375 std::unique_ptr<Internal::IntegerAspectPrivate> d; 376 }; 377 378 class QTCREATOR_UTILS_EXPORT DoubleAspect : public BaseAspect 379 { 380 Q_OBJECT 381 382 public: 383 DoubleAspect(); 384 ~DoubleAspect() override; 385 386 void addToLayout(LayoutBuilder &builder) override; 387 388 QVariant volatileValue() const override; 389 void setVolatileValue(const QVariant &val) override; 390 391 double value() const; 392 void setValue(double val); 393 void setDefaultValue(double defaultValue); 394 395 void setRange(double min, double max); 396 void setPrefix(const QString &prefix); 397 void setSuffix(const QString &suffix); 398 void setSpecialValueText(const QString &specialText); 399 void setSingleStep(double step); 400 401 private: 402 std::unique_ptr<Internal::DoubleAspectPrivate> d; 403 }; 404 405 class QTCREATOR_UTILS_EXPORT TriState 406 { 407 enum Value { EnabledValue, DisabledValue, DefaultValue }; TriState(Value v)408 explicit TriState(Value v) : m_value(v) {} 409 410 public: 411 TriState() = default; 412 toVariant()413 QVariant toVariant() const { return int(m_value); } 414 static TriState fromVariant(const QVariant &variant); 415 416 static const TriState Enabled; 417 static const TriState Disabled; 418 static const TriState Default; 419 420 friend bool operator==(TriState a, TriState b) { return a.m_value == b.m_value; } 421 friend bool operator!=(TriState a, TriState b) { return a.m_value != b.m_value; } 422 423 private: 424 Value m_value = DefaultValue; 425 }; 426 427 class QTCREATOR_UTILS_EXPORT TriStateAspect : public SelectionAspect 428 { 429 Q_OBJECT 430 public: 431 TriStateAspect( 432 const QString onString = tr("Enable"), 433 const QString &offString = tr("Disable"), 434 const QString &defaultString = tr("Leave at Default")); 435 436 TriState value() const; 437 void setValue(TriState setting); 438 void setDefaultValue(TriState setting); 439 }; 440 441 class QTCREATOR_UTILS_EXPORT StringListAspect : public BaseAspect 442 { 443 Q_OBJECT 444 445 public: 446 StringListAspect(); 447 ~StringListAspect() override; 448 449 void addToLayout(LayoutBuilder &builder) override; 450 451 QStringList value() const; 452 void setValue(const QStringList &val); 453 454 void appendValue(const QString &value, bool allowDuplicates = true); 455 void removeValue(const QString &value); 456 void appendValues(const QStringList &values, bool allowDuplicates = true); 457 void removeValues(const QStringList &values); 458 459 private: 460 std::unique_ptr<Internal::StringListAspectPrivate> d; 461 }; 462 463 class QTCREATOR_UTILS_EXPORT IntegersAspect : public BaseAspect 464 { 465 Q_OBJECT 466 467 public: 468 IntegersAspect(); 469 ~IntegersAspect() override; 470 471 void addToLayout(LayoutBuilder &builder) override; 472 void emitChangedValue() override; 473 474 QList<int> value() const; 475 void setValue(const QList<int> &value); 476 void setDefaultValue(const QList<int> &value); 477 478 signals: 479 void valueChanged(const QList<int> &values); 480 }; 481 482 class QTCREATOR_UTILS_EXPORT TextDisplay : public BaseAspect 483 { 484 Q_OBJECT 485 486 public: 487 TextDisplay(const QString &message = {}, 488 Utils::InfoLabel::InfoType type = Utils::InfoLabel::None); 489 ~TextDisplay() override; 490 491 void addToLayout(LayoutBuilder &builder) override; 492 493 void setIconType(Utils::InfoLabel::InfoType t); 494 void setText(const QString &message); 495 496 private: 497 std::unique_ptr<Internal::TextDisplayPrivate> d; 498 }; 499 500 class QTCREATOR_UTILS_EXPORT AspectContainer : public QObject 501 { 502 Q_OBJECT 503 504 public: 505 AspectContainer(QObject *parent = nullptr); 506 ~AspectContainer(); 507 508 AspectContainer(const AspectContainer &) = delete; 509 AspectContainer &operator=(const AspectContainer &) = delete; 510 511 void registerAspect(BaseAspect *aspect); 512 void registerAspects(const AspectContainer &aspects); 513 514 template <class Aspect, typename ...Args> addAspect(Args &&...args)515 Aspect *addAspect(Args && ...args) 516 { 517 auto aspect = new Aspect(args...); 518 registerAspect(aspect); 519 return aspect; 520 } 521 522 void fromMap(const QVariantMap &map); 523 void toMap(QVariantMap &map) const; 524 525 void readSettings(QSettings *settings); 526 void writeSettings(QSettings *settings) const; 527 528 void setSettingsGroup(const QString &groupKey); 529 void setSettingsGroups(const QString &groupKey, const QString &subGroupKey); 530 531 void apply(); 532 void cancel(); 533 void finish(); 534 535 void reset(); 536 bool equals(const AspectContainer &other) const; 537 void copyFrom(const AspectContainer &other); 538 void setAutoApply(bool on); 539 void setOwnsSubAspects(bool on); 540 bool isDirty() const; 541 aspect()542 template <typename T> T *aspect() const 543 { 544 for (BaseAspect *aspect : aspects()) 545 if (T *result = qobject_cast<T *>(aspect)) 546 return result; 547 return nullptr; 548 } 549 550 BaseAspect *aspect(Utils::Id id) const; 551 aspect(Utils::Id id)552 template <typename T> T *aspect(Utils::Id id) const 553 { 554 return qobject_cast<T*>(aspect(id)); 555 } 556 557 void forEachAspect(const std::function<void(BaseAspect *)> &run) const; 558 559 const QList<BaseAspect *> &aspects() const; 560 561 using const_iterator = QList<BaseAspect *>::const_iterator; 562 using value_type = QList<BaseAspect *>::value_type; 563 564 const_iterator begin() const; 565 const_iterator end() const; 566 567 signals: 568 void applied(); 569 void fromMapFinished(); 570 571 private: 572 std::unique_ptr<Internal::AspectContainerPrivate> d; 573 }; 574 575 } // namespace Utils 576