File indexing completed on 2024-04-14 14:53:45

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_SET_H
0023 #define KPROPERTY_SET_H
0024 
0025 #include <QObject>
0026 #include <QHash>
0027 #include <QDebug>
0028 
0029 #include "KProperty.h"
0030 
0031 class KPropertySetPrivate;
0032 
0033 //! An interface for functor selecting properties.
0034 /*! Used in Iterator. */
0035 class KPROPERTYCORE_EXPORT KPropertySelector
0036 {
0037 public:
0038     KPropertySelector();
0039     virtual ~KPropertySelector();
0040 
0041     //! An operator implementing the functor.
0042     virtual bool operator()(const KProperty& prop) const = 0;
0043 
0044     //! Creates a deep copy of the selector.
0045     //! Required for proper usage of the selector.
0046     virtual KPropertySelector* clone() const = 0;
0047 };
0048 
0049 //! A class to iterate over a KPropertySet.
0050 /*! It behaves like a QList::ConstIterator.
0051  Usage:
0052  @code  for (KPropertySetIterator it(set); it.current(); ++it) { .... }
0053  @endcode
0054  Usage with selector:
0055  @code  for (KPropertySetIterator it(set, MySelector()); it.current(); ++it) { .... }
0056  @endcode */
0057 class KPROPERTYCORE_EXPORT KPropertySetIterator
0058 {
0059 public:
0060     //! Creates iterator for @a set set of properties.
0061     /*!             The properties are sorted by insertion order by default.
0062         Use setOrder(Iterator::Alphabetical) to have alphabetical order. */
0063     explicit KPropertySetIterator(const KPropertySet &set);
0064 
0065     //! Creates iterator for @a set set of properties.
0066     /*! @a selector functor is used to iterate only
0067         over specified properties.
0068         The properties are sorted by insertion order by default.
0069         Use setOrder(Iterator::Alphabetical) to have alphabetical order. */
0070     KPropertySetIterator(const KPropertySet &set, const KPropertySelector& selector);
0071 
0072     //! Copy constructor
0073     //! @since 3.1
0074     KPropertySetIterator(const KPropertySetIterator &set);
0075 
0076     ~KPropertySetIterator();
0077 
0078     //! Assigns @a other to this KPropertySetIterator
0079     //! @since 3.1
0080     KPropertySetIterator& operator=(const KPropertySetIterator &other);
0081 
0082     //! @return true if this iterator equals to @a other
0083     //! @since 3.1
0084     bool operator==(const KPropertySetIterator &other) const;
0085 
0086     //! @return true if this iterator does not equal to @a other
0087     //! @since 3.1
0088     inline bool operator!=(const KPropertySetIterator &other) const { return !operator==(other); }
0089 
0090     //! Ordering options for properties
0091     /*! @see setOrder() */
0092     enum class Order {
0093         Insertion,    //!< insertion order
0094         Alphabetical, //!< alphabetical order (case-insensitively by captions)
0095         AlphabeticalByName //!< alphabetical order (case-insensitively by name)
0096     };
0097 
0098     //! Sets order for properties. Restarts the iterator.
0099     void setOrder(Order order);
0100 
0101     //! @return order for properties.
0102     Order order() const;
0103 
0104     void operator++();
0105 
0106     inline KProperty* operator*() const { return current(); }
0107 
0108     KProperty* current() const;
0109 
0110     friend class KPropertySet;
0111 
0112 private:
0113     class Private;
0114     Private * const d;
0115 };
0116 
0117 /*! \brief Set of properties
0118  */
0119 class KPROPERTYCORE_EXPORT KPropertySet : public QObject
0120 {
0121     Q_OBJECT
0122 public:
0123     //! Constructs a new property set object.
0124     explicit KPropertySet(QObject *parent = nullptr);
0125 
0126     /*! Constructs a deep copy of \a set.
0127      The new object will not have a QObject parent even if \a set has such parent. */
0128     explicit KPropertySet(const KPropertySet& set);
0129 
0130     ~KPropertySet() override;
0131 
0132     /*! @return the number of top-level properties in the set. */
0133     int count() const;
0134 
0135     /*! @return the number of top-level properties in the set
0136                 matching criteria defined by @a selector. */
0137     int count(const KPropertySelector& selector) const;
0138 
0139     /*! @return true if the set is empty, i.e. count() is 0; otherwise returns false. */
0140     bool isEmpty() const;
0141 
0142     /*! @return true if the set is contains visible properties. */
0143     bool hasVisibleProperties() const;
0144 
0145     /*! @return true if the set is contains properties
0146                 matching criteria defined by @a selector. */
0147     bool hasProperties(const KPropertySelector& selector) const;
0148 
0149     /*! \return true if the set is read-only when used in a property editor.
0150      @c false by default.
0151      In a read-only property set no property can be modified by the user regardless of read-only flag
0152      of any property (KProperty::isReadOnly()). On the other hand if KProperty::isReadOnly() is @c true
0153      and KPropertySet::isReadOnly() is @c false, the property is still read-only.
0154      Read-only property set prevents editing in the property editor but it is still possible to change
0155      value or other parameters of property programatically using KProperty::setValue(),
0156      KProperty::resetValue(), etc. */
0157     bool isReadOnly() const;
0158 
0159     /*! \return true if the set contains property names \a name. */
0160     bool contains(const QByteArray &name) const;
0161 
0162     /*! \return property named with \a name. If no such property is found,
0163      null property (KProperty()) is returned. */
0164     KProperty& property(const QByteArray &name) const;
0165 
0166     /*! Accesses a property by name.
0167     A property reference is returned, so all property modifications are allowed.
0168     If there is no such property, null property (KProperty()) is returned,
0169     so it's good practice to use contains() if it's not known if the property exists.
0170     For example to set a value of a property, use:
0171     @code
0172     KPropertySet set;
0173     ...
0174     if (!set.contains("myProperty")) {
0175       dosomething;
0176     }
0177     set["myProperty"].setValue("My Value");
0178     @endcode
0179     @return \ref Property with given name.
0180     @see changeProperty(const QByteArray &, const QVariant &)
0181     @see changePropertyIfExists(const QByteArray &, const QVariant &)
0182     */
0183     KProperty& operator[](const QByteArray &name) const;
0184 
0185     /*! @return value for property named with @a name.
0186      If no such property is found, default value @a defaultValue is returned. */
0187     QVariant propertyValue(const QByteArray &name, const QVariant& defaultValue = QVariant()) const;
0188 
0189     /*! Creates a deep copy of \a set and assigns it to this property set. */
0190     KPropertySet& operator= (const KPropertySet &set);
0191 
0192     /*! \return the user-visible translated caption string for \a group that will
0193      be shown in property editor to represent \a group. If there is no special
0194      caption set for the group, \a group is just returned. */
0195     QString groupCaption(const QByteArray &group) const;
0196 
0197     /*! \return icon name for \a group. */
0198     QString groupIconName(const QByteArray &group) const;
0199 
0200     /**
0201      * @return group name for property @a propertyName
0202      * Empty value is returned if there is no such property.
0203      * @since 3.1
0204      */
0205     QByteArray groupNameForProperty(const QByteArray &propertyName) const;
0206 
0207     /**
0208      * @overload QByteArray groupNameForProperty(const QByteArray &propertyName) const
0209      * @since 3.1
0210      */
0211     QByteArray groupNameForProperty(const KProperty &property) const;
0212 
0213     /*! \return a list of all group names. The order of items is undefined. */
0214     QList<QByteArray> groupNames() const;
0215 
0216     /*! \return a list of all property names for group @a group.
0217      The order of items is undefined. */
0218     QList<QByteArray> propertyNamesForGroup(const QByteArray &group) const;
0219 
0220     /*! Used by property editor to preserve previous selection when this set
0221      is assigned again. */
0222     QByteArray previousSelection() const;
0223 
0224     /*! Prints debug output for this set. */
0225     void debug() const;
0226 
0227     //! @return property values for this set
0228     QMap<QByteArray, QVariant> propertyValues() const;
0229 
0230     /**
0231      * @brief Clears "modified" flag of all properties in this set, i.e. calls clearModifiedFlag() for each property.
0232      * @since 3.1
0233      * @see KProperty::clearModifiedFlag()
0234      */
0235     void clearModifiedFlags();
0236 
0237     /**
0238      * Returns @c true if at least one property in this set is modified, i.e. returns @c true for isModified()
0239      * @since 3.1
0240      * @see clearModifiedFlags() KProperty::isModified()
0241      */
0242     bool isModified() const;
0243 
0244 public Q_SLOTS:
0245     /*! Adds the property to the set, in the group.
0246      The property becomes owned by the set.
0247      Any name can be used for the @a group. "common" is the default for a basic top-level group. */
0248     void addProperty(KProperty *property, const QByteArray &group = "common");
0249 
0250     /*! Removes property from the set and deletes the object.
0251      Emits aboutToDeleteProperty before removing. */
0252     void removeProperty(KProperty *property);
0253 
0254     /*! Removes property with the given name from the set and deletes the object.
0255     Emits aboutToDeleteProperty() before removing.*/
0256     void removeProperty(const QByteArray &name);
0257 
0258     /*! Removes all property objects from the property set and deletes them. */
0259     void clear();
0260 
0261     /*! Change the value of property whose key is \a property to \a value.
0262     @see void changePropertyIfExists(const QByteArray &, const QVariant &) */
0263     void changeProperty(const QByteArray &property, const QVariant &value);
0264 
0265     /*! Change the value of property whose key is \a property to \a value
0266      only if it exists in the set.
0267      @see void changeProperty(const QByteArray &, const QVariant &) */
0268     void changePropertyIfExists(const QByteArray &property, const QVariant &value);
0269 
0270     /*! Sets @a caption as a user-visible translated string that will be shown in editor to represent
0271      \a group. */
0272     void setGroupCaption(const QByteArray &group, const QString &caption);
0273 
0274     /*! Sets the icon name \a icon to be displayed for \a group. */
0275     void setGroupIconName(const QByteArray &group, const QString& iconName);
0276 
0277     //! Sets previous section.
0278     //! @see previousSelection()
0279     void setPreviousSelection(const QByteArray &prevSelection);
0280 
0281     /*! Sets this set to be read-only.
0282      @see isReadOnly */
0283     void setReadOnly(bool readOnly);
0284 
0285 Q_SIGNALS:
0286     /*! Emitted when the value of the property is changed.*/
0287     void propertyChanged(KPropertySet& set, KProperty& property);
0288 
0289     /*! @internal Exists to be sure that we emitted it before propertyChanged(),
0290      so editor object can handle this. */
0291     void propertyChangedInternal(KPropertySet& set, KProperty& property);
0292 
0293     /*! Emitted when the value of the property is reset.*/
0294     void propertyReset(KPropertySet& set, KProperty& property);
0295 
0296     /*! Emitted when property is about to be deleted.*/
0297     void aboutToDeleteProperty(KPropertySet& set, KProperty& property);
0298 
0299     /*! Emitted when property set object is about to be cleared (using clear()).
0300      This signal is also emitted from destructor before emitting aboutToBeDeleted(). */
0301     void aboutToBeCleared();
0302 
0303     /*! Emitted when property set object is about to be deleted.*/
0304     void aboutToBeDeleted();
0305 
0306     /*! Emitted when property set object's read-only flag has changed.*/
0307     void readOnlyFlagChanged();
0308 
0309 protected:
0310     /*! Constructs a set which owns or does not own it's properties.*/
0311     explicit KPropertySet(bool propertyOwner);
0312 
0313 private:
0314     KPropertySetPrivate * const d;
0315     friend class KPropertySetPrivate;
0316 };
0317 
0318 //! qDebug() stream operator. Writes this set to the debug output in a nicely formatted way.
0319 KPROPERTYCORE_EXPORT QDebug operator<<(QDebug dbg, const KPropertySet &set);
0320 
0321 #endif