File indexing completed on 2024-12-08 12:45:15
0001 /* This file is part of the KDE project 0002 Copyright (C) 2004 Cedric Pasteur <cedric.pasteur@free.fr> 0003 Copyright (C) 2004 Alexander Dymo <cloudtemple@mskat.net> 0004 Copyright (C) 2004-2017 Jarosław Staniek <staniek@kde.org> 0005 0006 This library is free software; you can redistribute it and/or 0007 modify it under the terms of the GNU Library General Public 0008 License as published by the Free Software Foundation; either 0009 version 2 of the License, or (at your option) any later version. 0010 0011 This library is distributed in the hope that it will be useful, 0012 but WITHOUT ANY WARRANTY; without even the implied warranty of 0013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0014 Library General Public License for more details. 0015 0016 You should have received a copy of the GNU Library General Public License 0017 along with this library; see the file COPYING.LIB. If not, write to 0018 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0019 * Boston, MA 02110-1301, USA. 0020 */ 0021 0022 #ifndef KPROPERTY_PROPERTY_H 0023 #define KPROPERTY_PROPERTY_H 0024 0025 #include <QVariant> 0026 #include <QStringList> 0027 #include <QByteArray> 0028 #include <QDebug> 0029 0030 #include <cmath> 0031 #include <limits> 0032 0033 #include "kpropertycore_export.h" 0034 0035 class KComposedPropertyInterface; 0036 class KPropertyListData; 0037 class KPropertySet; 0038 class KPropertySetPrivate; 0039 0040 /** 0041 * @brief Minimum double value working precisely. 0042 * 0043 * @since 3.1 0044 */ 0045 #define KPROPERTY_MIN_PRECISE_DOUBLE (-pow(2, std::numeric_limits<double>::digits)) 0046 0047 /** 0048 * @brief Minimum double value working precisely 0049 * 0050 * Editor for double values (spin box) has localized contents and its code supports just this maximum. 0051 * For a 64-bit machine it's 2**53. 0052 * See also https://phabricator.kde.org/D5419#inline-22329 0053 * 0054 * @since 3.1 0055 */ 0056 #define KPROPERTY_MAX_PRECISE_DOUBLE (pow(2, std::numeric_limits<double>::digits)) 0057 0058 /*! \brief The base class representing a single property 0059 0060 KProperty object can hold a property of given type supported by QVariant. Properties of custom types 0061 can be also created, see using KPropertyFactory. Composed or custom properties 0062 are not created using subclassing of KProperty but using @ref KComposedPropertyInterface. 0063 0064 Each property stores old value to allows undoing that reverts the value to the old one. 0065 Property has a non-empty name (a QByteArray), a caption that is user-visible translated string 0066 displayed in property editor. Description is a translatable string that can be specified too 0067 in order to further explain meaning of the property. 0068 0069 Propery also supports setting arbitrary number of options using KProperty::setOption() that allow 0070 to customize look or behavior of the property in the editor. 0071 0072 @code 0073 // Creating a simple property: 0074 KProperty *property = new KProperty(name, value, caption, description); 0075 // name is a QByteArray, value is whatever type QVariant supports 0076 0077 // Creating a property of type ValueFromList matching keys with names: 0078 QStringList keys({"one", "two", "three"}); // possible values of the property 0079 QStringList names({tr("One"), tr("Two"), tr("Three")}); // Names (possibly translated) shown in 0080 // the editor instead of the keys 0081 property = new KProperty(name, new KPropertyListData(keys, names), "two", caption); 0082 0083 // Creating a property of type ValueFromList matching variant keys with names: 0084 KPropertyListData *listData = new KPropertyListData({1.1, tr("One")}, {2.5, tr("Two")}, {3., tr("Three")}}); 0085 propertySet->addProperty(new KProperty("List", listData, "otheritem", "List")); 0086 @endcode 0087 0088 @note Sometimes it makes sense to split property captions that have with more words to multiple lines 0089 using a newline character, e.g. "Allow Zero Size" to "Allow Zero\nSize". 0090 This is suitable especially for the needs of property editor which can offer only limited area. 0091 The text of property caption containing newline characters is available in its original form using 0092 KProperty::captionForDisplaying(). KProperty::caption() returns modified caption text in which 0093 the newline characters are substituted with spaces and any trailing and leading whitespace is removed. 0094 */ 0095 class KPROPERTYCORE_EXPORT KProperty 0096 { 0097 public: 0098 /*! Defines types of properties. 0099 Properties defined by plugins should have a type number >= UserDefined .*/ 0100 enum Type { 0101 //standard supported QVariant types 0102 Auto = 0x00ffffff, 0103 Invalid = QVariant::Invalid, 0104 BitArray = QVariant::BitArray, 0105 Bitmap = QVariant::Bitmap, 0106 Bool = QVariant::Bool, 0107 Brush = QVariant::Brush, 0108 ByteArray = QVariant::ByteArray, 0109 Char = QVariant::Char, 0110 Color = QVariant::Color, 0111 Cursor = QVariant::Cursor, 0112 Date = QVariant::Date, 0113 DateTime = QVariant::DateTime, 0114 Double = QVariant::Double, 0115 Font = QVariant::Font, 0116 Icon = QVariant::Icon, 0117 Image = QVariant::Image, 0118 Int = QVariant::Int, 0119 KeySequence = QVariant::KeySequence, 0120 Line = QVariant::Line, 0121 LineF = QVariant::LineF, 0122 List = QVariant::List, 0123 Locale = QVariant::Locale, 0124 LongLong = QVariant::LongLong, 0125 Map = QVariant::Map, 0126 Matrix = QVariant::Matrix, 0127 Transform = QVariant::Transform, 0128 Palette = QVariant::Palette, 0129 Pen = QVariant::Pen, 0130 Pixmap = QVariant::Pixmap, 0131 Point = QVariant::Point, 0132 PointF = QVariant::PointF, 0133 Polygon = QVariant::Polygon, 0134 Rect = QVariant::Rect, 0135 RectF = QVariant::RectF, 0136 RegExp = QVariant::RegExp, 0137 Region = QVariant::Region, 0138 Size = QVariant::Size, 0139 SizeF = QVariant::SizeF, 0140 SizePolicy = QVariant::SizePolicy, 0141 String = QVariant::String, 0142 StringList = QVariant::StringList, 0143 TextFormat = QVariant::TextFormat, 0144 TextLength = QVariant::TextLength, 0145 Time = QVariant::Time, 0146 UInt = QVariant::UInt, 0147 ULongLong = QVariant::ULongLong, 0148 Url = QVariant::Url, 0149 0150 //predefined custom types 0151 ValueFromList = 1000, /**<string value from a list*/ 0152 Symbol, /**<unicode symbol code*/ 0153 FontName, /**<font name, e.g. "times new roman"*/ 0154 LineStyle, /**<line style*/ 0155 ComposedUrl /**<composed URL @since 3.2 */, 0156 0157 UserDefined = 4000 /**<plugin defined properties should start here*/ 0158 }; 0159 0160 /** 0161 * Constructs a null property. 0162 * Null properties have empty names and captions and Invalid types. 0163 */ 0164 KProperty(); 0165 0166 /*! Constructs property of a simple type. */ 0167 explicit KProperty(const QByteArray &name, const QVariant &value = QVariant(), 0168 const QString &caption = QString(), const QString &description = QString(), 0169 int type = Auto, KProperty* parent = nullptr); 0170 0171 /** 0172 * @brief Constructs property of ValueFromList type 0173 * 0174 * Ownership of @a listData is passed to the property object. 0175 */ 0176 KProperty(const QByteArray &name, KPropertyListData *listData, 0177 const QVariant &value = QVariant(), 0178 const QString &caption = QString(), const QString &description = QString(), 0179 int type = ValueFromList, KProperty* parent = nullptr); 0180 0181 /*! Constructs a deep copy of \a prop property. */ 0182 KProperty(const KProperty &prop); 0183 0184 ~KProperty(); 0185 0186 /** 0187 * @return name of the property 0188 * @note empty name means a null property 0189 */ 0190 QByteArray name() const; 0191 0192 /** 0193 * Sets name of the property 0194 * @note empty name means a null property 0195 */ 0196 void setName(const QByteArray &name); 0197 0198 /*! \return the caption of the property. Does not contain newline characters. Can be empty. */ 0199 QString caption() const; 0200 0201 /*! \return the caption of the property or name() if the caption is empty. */ 0202 inline QString captionOrName() const 0203 { 0204 return caption().isEmpty() ? QString::fromLatin1(name()) : caption(); 0205 } 0206 0207 /*! \return the caption text of the property for displaying. 0208 It is similar to caption() but if the property caption contains newline characters, 0209 these are not substituted with spaces. */ 0210 QString captionForDisplaying() const; 0211 0212 /*! Sets the name of the property. If the caption contains newline characters, 0213 these are substituted with spaces. 0214 @see captionForDisplaying 0215 */ 0216 void setCaption(const QString &caption); 0217 0218 /*! \return the description of the property.*/ 0219 QString description() const; 0220 0221 /*! Sets the description of the property.*/ 0222 void setDescription(const QString &description); 0223 0224 /*! \return the type of the property.*/ 0225 int type() const; 0226 0227 /*! Sets the type of the property.*/ 0228 void setType(int type); 0229 0230 /*! \return the value of the property.*/ 0231 QVariant value() const; 0232 0233 /*! Returns the previous property value if it was set in setValue(). */ 0234 QVariant oldValue() const; 0235 0236 //! Options that influence how values are handled in setValue() and valueEqualsTo() 0237 //! @since 3.1 0238 enum class ValueOption { 0239 None = 0, //!< No options, that is 1. old value is remembered before setting a new one; 0240 //!< 2. composed properties are considered while comparing old and new value 0241 IgnoreOld = 1, //!< Do not remember the old value before setting a new one 0242 IgnoreComposedProperty = 2 //!< Do not use composed property when comparing values 0243 }; 0244 Q_DECLARE_FLAGS(ValueOptions, ValueOption) 0245 0246 /** 0247 * @brief Sets value of the property. 0248 * @param value New value 0249 * @param options Options for the value setting. 0250 * @return @c true if the value has been changed and @c false if the @a value was the same 0251 * as previous one so it was not changed of if this property is null. 0252 */ 0253 bool setValue(const QVariant &value, ValueOptions options = ValueOptions()); 0254 0255 /** 0256 * @return true if value of this property is equal to specified value 0257 * 0258 * Takes type into account. 0259 * @param value Value to compare. 0260 * @param valueOptions Options to use when comparing. 0261 * Only the @c None and IgnoreComposedProperties are supported. 0262 * @since 3.1 0263 */ 0264 bool valueEqualsTo(const QVariant &value, ValueOptions valueOptions = ValueOptions()) const; 0265 0266 /*! Resets the value of the property to the old value. 0267 @see oldValue() */ 0268 void resetValue(); 0269 0270 /*! \return the qstring-to-value correspondence list of the property. 0271 used to create comboboxes-like property editors.*/ 0272 KPropertyListData* listData() const; 0273 0274 /*! Sets the qstring-to-value correspondence list of the property. 0275 This is used to create comboboxes-like property editors.*/ 0276 void setListData(KPropertyListData* list); 0277 0278 /*! Sets the string-to-value correspondence list of the property. 0279 This is used to create comboboxes-like property editors. 0280 This is overload of the above ctor added for convenience. */ 0281 void setListData(const QStringList &keys, const QStringList &names); 0282 0283 /*! Sets icon name to \a name for this property. Icons are optional and are used e.g. 0284 in property editor - displayed at the left hand. */ 0285 void setIconName(const QString &name); 0286 0287 /*! \return property icon's name. Can be empty. */ 0288 QString iconName() const; 0289 0290 /*! \return a list of all children for this property, or NULL of there 0291 is no children for this property */ 0292 const QList<KProperty*>* children() const; 0293 0294 /*! \return a child property for \a name, or NULL if there is no property with that name. */ 0295 KProperty* child(const QByteArray &name); 0296 0297 /*! \return parent property for this property, or NULL if there is no parent property. */ 0298 KProperty* parent() const; 0299 0300 /*! \return the composed property for this property, or NULL if there was 0301 no composed property defined. */ 0302 KComposedPropertyInterface* composedProperty() const; 0303 0304 /*! Sets composed property \a prop for this property. */ 0305 void setComposedProperty(KComposedPropertyInterface *prop); 0306 0307 /*! \return true if this property is null. Property is null if it has empty name. */ 0308 bool isNull() const; 0309 0310 /** 0311 * @brief Return @c true if value of this property or value of any child property is modified. 0312 * 0313 * @see clearModifiedFlag() 0314 */ 0315 bool isModified() const; 0316 0317 /** 0318 * @brief Clears the "modified" flag for this property and all its child properties. 0319 * 0320 * After calling this method isModified() returs false for the property and all child 0321 * properties. 0322 * 0323 * @see isModified() 0324 */ 0325 void clearModifiedFlag(); 0326 0327 /*! \return true if the property is read-only when used in a property editor. 0328 @c false by default. 0329 The property can be read-write but still not editable for the user if the parent property set's 0330 read-only flag is set. 0331 @see KPropertySet::isReadOnly() */ 0332 bool isReadOnly() const; 0333 0334 /*! Sets this property to be read-only. 0335 @see isReadOnly() */ 0336 void setReadOnly(bool readOnly); 0337 0338 /*! \return true if the property is visible. 0339 Only visible properties are displayed by the property editor view. */ 0340 bool isVisible() const; 0341 0342 /*! Sets the visibility flag.*/ 0343 void setVisible(bool visible); 0344 0345 /*! \return true if the property can be saved to a stream, xml, etc. 0346 There is a possibility to use "GUI" properties that aren't 0347 stored but used only in a GUI.*/ 0348 bool isStorable() const; 0349 0350 /*! Sets "storable" flag for this property. @see isStorable() */ 0351 void setStorable(bool storable); 0352 0353 //! Synchronization policy for property values 0354 //! @since 3.1 0355 enum class ValueSyncPolicy { 0356 Editor, //!< Allow to synchronize by the property editor using its valueSync setting (default) 0357 FocusOut, //!< Synchronize the value when focus is out of the editor widget for this property 0358 //!< or when the user presses the Enter key 0359 Auto //!< Synchronize automatically as soon as the editor widget for this property signals 0360 //! (using commitData) that the value has been changed, e.g. when the user types 0361 //! another letter in a text box 0362 }; 0363 0364 //! @return synchronization policy for property values of this property 0365 //! @since 3.1 0366 ValueSyncPolicy valueSyncPolicy() const; 0367 0368 //! Sets synchronization policy for property values of this property 0369 //! See ValueSyncPolicy for details. 0370 //! @since 3.1 0371 void setValueSyncPolicy(ValueSyncPolicy policy); 0372 0373 /*! Sets value \a val for option \a name. 0374 Options are used to override default settings of individual properties. 0375 They are most visible in property editor widgets. Option is set if it is not null. 0376 This means that empty string can be still a valid value. 0377 To unset given option, call setOption() with a null QVariant value. 0378 0379 Currently supported options are: 0380 <ul> 0381 <li> min: value describing minimum value for properties of integer, double, 0382 date, date/time and time types. Default is 0 for double and unsigned integer types, 0383 -INT_MAX for signed integer type. 0384 Defaults for date, date/time and time types are specified in documentation 0385 of QDateEdit::minimumDate, QDateTimeEdit::minimumDateTime and QTime::minimumTime, respectively. 0386 The value specified for this option is accepted if: 0387 - it is not larger than the value of the "max" option 0388 - it is not smaller than KPROPERTY_MIN_PRECISE_DOUBLE (for double type) 0389 - it is not smaller than -INT_MAX (for integer type) 0390 - it is not smaller than 0 (for unsigned integer type). 0391 </li> 0392 <li> minValueText: user-visible translated string to be displayed in editor for integer, 0393 double, date, date/time and time types when the value is equal to the value of 0394 "min" option. 0395 The value specified for this option is accepted if min option is supported for given type 0396 and is specified. 0397 @see QAbstractSpinBox::specialValueText</li> 0398 <li> max: value describing minimum value for properties of integer type. 0399 Default is KPROPERTY_MAX_PRECISE_DOUBLE for double type (maximum precise value) 0400 and INT_MAX for integer type. 0401 Defaults for date, date/time and time types are specified in documentation 0402 of QDateEdit::maximumDate, QDateTimeEdit::maximumDateTime and QTime::maximumTime, respectively. 0403 The value is ignored if it is smaller than the value of "min" option. </li> 0404 The value specified for this option is accepted if: 0405 - it is not smaller than the value of the "min" option 0406 - it is not larger than KPROPERTY_MAX_PRECISE_DOUBLE (for double type) 0407 - it is not larger than INT_MAX (for integer and unsigned integer type). 0408 </li> 0409 <li> precision: integer value >= 0 describing the number of decimals after the decimal 0410 point for double type. Default value is 2. 0411 @see QDoubleSpinBox::decimals</li> 0412 <li> step: double value > 0.0 describing the size of the step that is taken when 0413 the user hits the up or down button of editor for double type. Default value is 0.01. 0414 @see QDoubleSpinBox::singleStep</li> 0415 <li> 3State: boolean value used for boolean type; if @c true, the editor becomes a combobox 0416 (instead of checkable button) and accepts the third "null" state. Otherwise the boolean 0417 type only accepts @c true and @c false values, anything other, including invalid and null 0418 values, is converted to @c false.</li> 0419 <li> yesName: user-visible translated string used for boolean type (both 2- and 3-state) 0420 to visually represent the "true" value. If not present, tr("Yes") is used.</li> 0421 <li> noName: user-visible translated string used for boolean type (both 2- and 3-state) 0422 to visually represent the "false" value. If not present, tr("No") is used.</li> 0423 <li> 3rdStateName: user-visible translated string used for boolean type (both 2- and 3-state) 0424 to visually represent the third "null" value. If not present, tr("None") is used.</li> 0425 <li> nullName: user-visible translated string used for boolean type to display the "null" 0426 value, if and only if the property accepts two states (i.e. when "3State" option 0427 is @c false). If the "nullName" option is not set, null values are displayed as 0428 @c false.</li> 0429 <li> extraValueAllowed: boolean value, if @c true the user is able to manually add extra 0430 values to a combobox.</li> 0431 <li> fileMode: string value that describes types of objects that can be selected by the url 0432 editor: 0433 <ul> 0434 <li>"dirsOnly": only display and allow to select existing directories; 0435 @see QFileDialog::getExistingDirectoryUrl()</li> 0436 <li>"existingFile": only allow to select one existing file for opening, i.e. confirmation 0437 of overwriting is not performed; 0438 @see QFileDialog::getOpenFileUrl()</li> 0439 <li>Any other value: any file is supported, whether it exists or not; if the file exists, 0440 "confirmOverwrites" option is honored; this mode is the only one supporting non-file 0441 protocols such as ftp or http; to use them user has to enter them explicitly, 0442 file protocol is still the default 0443 @see QFileDialog::getSaveFileUrl()</li> 0444 </ul> 0445 @note Empty URLs are always allowed. 0446 </li> 0447 <li> confirmOverwrites: boolean value supported by the url editor; if @c true and the "fileMode" 0448 option is not equal to "existingFile" nor "dirsOnly" user will be asked for confirmation 0449 of file overwriting if selected file exists. @c false by default. 0450 @note The line edit does not validate the content.</li> 0451 <li> multiLine: boolean value used for string type. If @c true, a multi-line 0452 QPlainTextEdit-based widget is used for editor; otherwise a single-line QLineEdit 0453 widget is used. @c false by default. Added in version 3.1.</li> 0454 <li>prefix: string to display before the value, e.g. '$'. Supported for double and integer 0455 types and composed types based on double and integer types (Point*, Size*, Rect*). 0456 @see QDoubleSpinBox::prefix QSpinBox::prefix</li> 0457 <li>suffix: string to display after the value, e.g. unit such as 'mm'. 0458 Supported for double and integer types and composed types based on double and 0459 integer types (Point*, Size*, Rect*). Note that only display is affected, value 0460 is not converted to any unit. 0461 @see QDoubleSpinBox::suffix QSpinBox::suffix</li> 0462 </ul>*/ 0463 void setOption(const char* name, const QVariant& val); 0464 0465 /*! @brief Returns value of given option 0466 * Option is set if returned value is not null. 0467 * If there is no option for @a name in given property and parent property is present (see parent()), 0468 * parent property is checked. If the parent property offers the option, the value 0469 * is returned. If it is not present there, @a defaultValue value is returned. 0470 * Looking at parent property is available since 3.1. 0471 * @note The lookup is performed recursively, first in parent, then grand parent, etc. 0472 * @see setOption 0473 */ 0474 QVariant option(const char* name, const QVariant& defaultValue = QVariant()) const; 0475 0476 /*! @brief Returns @c true if at least one option is specified for this property 0477 * If there are no options defined @c true can be still returned if parent property 0478 * is present and it has at least one option specified. 0479 * Looking at parent property is available since 3.1. 0480 * @note The lookup is performed recursively, first in parent, then grand parent, etc. 0481 */ 0482 bool hasOptions() const; 0483 0484 /*! Equivalent to setValue(const QVariant &) */ 0485 KProperty& operator= (const QVariant& val); 0486 0487 /*! Assigns a deep copy of all attributes of \a property to this property. */ 0488 KProperty& operator= (const KProperty &property); 0489 0490 /** 0491 * @return @c true if the property is equal to @a prop; otherwise returns @c false. 0492 * Two properties are equal if they have the same name and type. 0493 * @note All null properties are equal 0494 * @todo Compare properties deeper? 0495 */ 0496 bool operator==(const KProperty &prop) const; 0497 0498 /** 0499 * @return @c true if the property is different from @a prop; otherwise returns @c false. 0500 * Two properties are different if they have different names or types. 0501 * @since 3.1 0502 */ 0503 bool operator!=(const KProperty &prop) const; 0504 0505 #if 0 0506 /*! \return a key used for sorting. 0507 Usually its set by KPropertySet::addProperty() and KProperty::addChild() to a unique value, 0508 so that this property can be sorted in a property editor in original order. 0509 \see EditorItem::compare() */ 0510 int sortingKey() const; 0511 #endif 0512 0513 private: 0514 //! Added only to help porting old code. Use public setValue() methods. 0515 void setValue(const QVariant &value, bool a1, bool a2 = true); 0516 0517 class Private; 0518 Private * const d; 0519 0520 friend class KPropertySet; 0521 friend class KPropertySetPrivate; 0522 friend class KPropertySetBuffer; 0523 friend KPROPERTYCORE_EXPORT QDebug operator<<(QDebug dbg, const KProperty &p); 0524 }; 0525 0526 //! qDebug() stream operator. Writes property @a p to the debug output in a nicely formatted way. 0527 KPROPERTYCORE_EXPORT QDebug operator<<(QDebug dbg, const KProperty &p); 0528 0529 Q_DECLARE_OPERATORS_FOR_FLAGS(KProperty::ValueOptions) 0530 0531 #endif