File indexing completed on 2024-12-08 10:15:37

0001 /* This file is part of the KDE project
0002    Copyright (C) 2008-2015 Jarosław Staniek <staniek@kde.org>
0003 
0004    This library is free software; you can redistribute it and/or
0005    modify it under the terms of the GNU Library General Public
0006    License as published by the Free Software Foundation; either
0007    version 2 of the License, or (at your option) any later version.
0008 
0009    This library is distributed in the hope that it will be useful,
0010    but WITHOUT ANY WARRANTY; without even the implied warranty of
0011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0012    Library General Public License for more details.
0013 
0014    You should have received a copy of the GNU Library General Public License
0015    along with this library; see the file COPYING.LIB.  If not, write to
0016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0017  * Boston, MA 02110-1301, USA.
0018 */
0019 
0020 #ifndef KPROPERTY_FACTORY_H
0021 #define KPROPERTY_FACTORY_H
0022 
0023 #include "KProperty.h"
0024 
0025 //! An interface for for composed property handlers
0026 /*! KComposedPropertyInterface should be subclassed to override the behaviour of a property type.
0027   In the constructor child property objects should be created if there are any.
0028   Then functions handling values should be implemented.
0029 
0030   Example implementation of composed properties can be found in editors/ directory.
0031 */
0032 class KPROPERTYCORE_EXPORT KComposedPropertyInterface
0033 {
0034 public:
0035     explicit KComposedPropertyInterface(KProperty *parent);
0036     virtual ~KComposedPropertyInterface();
0037 
0038     /*! This function modifies the child properties for parent value @a value.
0039      It is called by @ref KProperty::setValue() when
0040      the property is composed.
0041     It is not necessary to modify the property value, it is done by KProperty.
0042     @note When this method is called valueOptions should have
0043           the KProperty::ValueOption::IgnoreComposedProperty flag set or else there will be infinite
0044           recursion. The KProperty class makes sure this is the case but developers of custom
0045           properties should take special care about this.
0046     */
0047     virtual void setValue(KProperty *property, const QVariant &value, KProperty::ValueOptions valueOptions) = 0;
0048 
0049     void childValueChangedInternal(KProperty *child, const QVariant &value, KProperty::ValueOptions valueOptions);
0050 
0051     bool childValueChangedEnabled() const;
0052 
0053     void setChildValueChangedEnabled(bool set);
0054 
0055     /*! @return true if values @a first and @a second are equal. Used in KProperty::setValue()
0056      to check if value has been changed before setting value.
0057      Default implementation uses operator==. */
0058     inline virtual bool valuesEqual(const QVariant &first, const QVariant &second) { return first == second; }
0059 
0060 protected:
0061     virtual void childValueChanged(KProperty *child, const QVariant &value, KProperty::ValueOptions valueOptions) = 0;
0062 
0063     /*! This method emits the \a KPropertySet::propertyChanged() signal for all
0064     sets our parent-property is registered in. */
0065     void emitPropertyChanged();
0066 
0067 private:
0068     Q_DISABLE_COPY(KComposedPropertyInterface)
0069     class Private;
0070     Private * const d;
0071 };
0072 
0073 class KPROPERTYCORE_EXPORT KComposedPropertyCreatorInterface
0074 {
0075 public:
0076     KComposedPropertyCreatorInterface();
0077 
0078     virtual ~KComposedPropertyCreatorInterface();
0079 
0080     virtual KComposedPropertyInterface* createComposedProperty(KProperty *parent) const = 0;
0081 
0082 private:
0083     Q_DISABLE_COPY(KComposedPropertyCreatorInterface)
0084     class Private;
0085     Private * const d;
0086 };
0087 
0088 //! Creator returning composed property object
0089 template<class ComposedProperty>
0090 class KComposedPropertyCreator : public KComposedPropertyCreatorInterface
0091 {
0092 public:
0093     KComposedPropertyCreator() : KComposedPropertyCreatorInterface() {}
0094 
0095     ~KComposedPropertyCreator() override {}
0096 
0097     ComposedProperty* createComposedProperty(KProperty *parent) const override {
0098         return new ComposedProperty(parent);
0099     }
0100 
0101     Q_DISABLE_COPY(KComposedPropertyCreator)
0102 };
0103 
0104 //! Provides a specialized conversion of value to string depending on type
0105 class KPROPERTYCORE_EXPORT KPropertyValueDisplayInterface
0106 {
0107 public:
0108     KPropertyValueDisplayInterface();
0109 
0110     virtual ~KPropertyValueDisplayInterface();
0111 
0112     virtual QString propertyValueToString(const KProperty* property, const QLocale &locale) const
0113         { return valueToString(property->value(), locale); }
0114 
0115     virtual QString valueToString(const QVariant& value, const QLocale &locale) const = 0;
0116 
0117     //! Maximum length of strings to display in valueToString(), propertyValueToString()
0118     //! and KPropertyValuePainterInterface::paint().
0119     //! Used to avoid inefficiences. Equal to 250.
0120     //! @todo Make configurable?
0121     static int maxStringValueLength();
0122 
0123     //! @return @a value converted to string using QVariant::toString(), truncated if it's longer than @ref maxStringValueLength()
0124     //! @see maxStringValueLength();
0125     static QString valueToLocalizedString(const QVariant& value);
0126 
0127 private:
0128     Q_DISABLE_COPY(KPropertyValueDisplayInterface)
0129     class Private;
0130     Private * const d;
0131 };
0132 
0133 class KPROPERTYCORE_EXPORT KPropertyFactory
0134 {
0135 public:
0136     KPropertyFactory();
0137 
0138     virtual ~KPropertyFactory();
0139 
0140     QHash<int, KComposedPropertyCreatorInterface*> composedPropertyCreators() const;
0141     QHash<int, KPropertyValueDisplayInterface*> valueDisplays() const;
0142 
0143     void addComposedPropertyCreator(int type, KComposedPropertyCreatorInterface* creator);
0144 
0145     void addDisplay(int type, KPropertyValueDisplayInterface *display);
0146 
0147 protected:
0148     void addComposedPropertyCreatorInternal(int type,
0149         KComposedPropertyCreatorInterface* creator, bool own = true);
0150 
0151     //! Adds value-to-text converted @a painter for type @a type.
0152     //! The converter becomes owned by the factory.
0153     void addDisplayInternal(int type, KPropertyValueDisplayInterface *display, bool own = true);
0154 
0155     Q_DISABLE_COPY(KPropertyFactory)
0156     class Private;
0157     Private * const d;
0158 };
0159 
0160 class KPROPERTYCORE_EXPORT KPropertyFactoryManager : public QObject
0161 {
0162     Q_OBJECT
0163 public:
0164     KComposedPropertyInterface* createComposedProperty(KProperty *parent);
0165 
0166     //! Registers factory @a factory. It becomes owned by the manager.
0167     void registerFactory(KPropertyFactory *factory);
0168 
0169     /*! \return a pointer to a factory manager instance.*/
0170     static KPropertyFactoryManager* self();
0171 
0172     bool canConvertValueToText(int type) const;
0173 
0174     bool canConvertValueToText(const KProperty* property) const;
0175 
0176     QString propertyValueToString(const KProperty* property) const;
0177 
0178     QString valueToString(int type, const QVariant &value) const;
0179 
0180     QString propertyValueToLocalizedString(const KProperty* property) const;
0181 
0182     QString valueToLocalizedString(int type, const QVariant &value) const;
0183 
0184     KPropertyFactoryManager();
0185     ~KPropertyFactoryManager() override;
0186 
0187     //! Adds function @a initFunction that will be called after the manager is created.
0188     //! Useful for creation custom factories.
0189     static void addInitFunction(void (*initFunction)());
0190 
0191 private:
0192     Q_DISABLE_COPY(KPropertyFactoryManager)
0193     class Private;
0194     Private * const d;
0195 };
0196 
0197 #endif