File indexing completed on 2024-04-14 04:36:14

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 
0021 #include "KPropertyFactory.h"
0022 
0023 //---------------
0024 
0025 //! @internal
0026 class Q_DECL_HIDDEN KPropertyFactoryManager::Private
0027 {
0028 public:
0029     Private()
0030     {
0031     }
0032     ~Private()
0033     {
0034         qDeleteAll(factories);
0035     }
0036 
0037     QSet<KPropertyFactory*> factories;
0038     QHash<int, KComposedPropertyCreatorInterface*> composedPropertyCreators;
0039     QHash<int, KPropertyValueDisplayInterface*> valueDisplays;
0040 };
0041 
0042 Q_GLOBAL_STATIC(KPropertyFactoryManager, _self)
0043 
0044 //! @internal
0045 class Q_DECL_HIDDEN KPropertyFactory::Private
0046 {
0047 public:
0048     Private()
0049     {
0050     }
0051     ~Private()
0052     {
0053         qDeleteAll(valueDisplaysSet);
0054     }
0055 
0056     QHash<int, KComposedPropertyCreatorInterface*> composedPropertyCreators;
0057     QSet<KComposedPropertyCreatorInterface*> composedPropertyCreatorsSet;
0058     QHash<int, KPropertyValueDisplayInterface*> valueDisplays;
0059     QSet<KPropertyValueDisplayInterface*> valueDisplaysSet;
0060 };
0061 
0062 typedef QList<void (*)()> InitFunctions;
0063 //! @internal Used by KPropertyFactoryManager::addInitFunction()
0064 Q_GLOBAL_STATIC(InitFunctions, _initFunctions)
0065 
0066 KPropertyFactory::KPropertyFactory()
0067     : d( new Private )
0068 {
0069 }
0070 
0071 KPropertyFactory::~KPropertyFactory()
0072 {
0073     delete d;
0074 }
0075 
0076 QHash<int, KComposedPropertyCreatorInterface*> KPropertyFactory::composedPropertyCreators() const
0077 {
0078     return d->composedPropertyCreators;
0079 }
0080 
0081 QHash<int, KPropertyValueDisplayInterface*> KPropertyFactory::valueDisplays() const
0082 {
0083     return d->valueDisplays;
0084 }
0085 
0086 void KPropertyFactory::addComposedPropertyCreator( int type, KComposedPropertyCreatorInterface* creator )
0087 {
0088     addComposedPropertyCreatorInternal( type, creator, true );
0089 }
0090 
0091 void KPropertyFactory::addComposedPropertyCreatorInternal(int type, KComposedPropertyCreatorInterface* creator, bool own)
0092 {
0093     if (own)
0094         d->composedPropertyCreatorsSet.insert(creator);
0095     d->composedPropertyCreators.insert(type, creator);
0096 }
0097 
0098 void KPropertyFactory::addDisplay(int type, KPropertyValueDisplayInterface *display)
0099 {
0100     addDisplayInternal(type, display, true);
0101     if (dynamic_cast<KComposedPropertyCreatorInterface*>(display)) {
0102         addComposedPropertyCreatorInternal( type,
0103         dynamic_cast<KComposedPropertyCreatorInterface*>(display), false/* !own*/ );
0104     }
0105     if (dynamic_cast<KPropertyValueDisplayInterface*>(display)) {
0106         addDisplayInternal( type, dynamic_cast<KPropertyValueDisplayInterface*>(display), false/* !own*/ );
0107     }
0108 }
0109 
0110 void KPropertyFactory::addDisplayInternal(int type, KPropertyValueDisplayInterface *display, bool own)
0111 {
0112     if (own) {
0113         d->valueDisplaysSet.insert(display);
0114     }
0115     d->valueDisplays.insert(type, display);
0116 }
0117 
0118 //------------
0119 
0120 class Q_DECL_HIDDEN KPropertyValueDisplayInterface::Private
0121 {
0122 public:
0123     Private() {}
0124 };
0125 
0126 KPropertyValueDisplayInterface::KPropertyValueDisplayInterface()
0127     : d(new Private)
0128 {
0129 }
0130 
0131 KPropertyValueDisplayInterface::~KPropertyValueDisplayInterface()
0132 {
0133     delete d;
0134 }
0135 
0136 //static
0137 int KPropertyValueDisplayInterface::maxStringValueLength()
0138 {
0139     return 250;
0140 }
0141 
0142 //static
0143 QString KPropertyValueDisplayInterface::valueToLocalizedString(const QVariant& value)
0144 {
0145     QString s(value.toString());
0146     if (KPropertyValueDisplayInterface::maxStringValueLength() < s.length()) {
0147         s.truncate(KPropertyValueDisplayInterface::maxStringValueLength());
0148         return QObject::tr("%1...", "Truncated string").arg(s);
0149     }
0150     return s;
0151 }
0152 
0153 //------------
0154 
0155 KPropertyFactoryManager::KPropertyFactoryManager()
0156         : QObject(nullptr)
0157         , d(new Private)
0158 {
0159     setObjectName(QLatin1String("KPropertyFactoryManager"));
0160 }
0161 
0162 KPropertyFactoryManager::~KPropertyFactoryManager()
0163 {
0164     delete d;
0165 }
0166 
0167 KPropertyFactoryManager* KPropertyFactoryManager::self()
0168 {
0169     if (_self.exists()) { // avoid recursion: initFunctions below may call self()
0170         return _self;
0171     }
0172     _self(); // KPropertyFactoryManager should exist as initFunctions may need it
0173     foreach(void (*initFunction)(), *_initFunctions) {
0174         initFunction();
0175     }
0176     _initFunctions->clear();
0177     return _self;
0178 }
0179 
0180 void KPropertyFactoryManager::registerFactory(KPropertyFactory *factory)
0181 {
0182     d->factories.insert(factory);
0183     QHash<int, KComposedPropertyCreatorInterface*>::ConstIterator composedPropertyCreatorsItEnd
0184         = factory->composedPropertyCreators().constEnd();
0185     for (QHash<int, KComposedPropertyCreatorInterface*>::ConstIterator it( factory->composedPropertyCreators().constBegin() );
0186         it != composedPropertyCreatorsItEnd; ++it)
0187     {
0188         d->composedPropertyCreators.insert(it.key(), it.value());
0189     }
0190     QHash<int, KPropertyValueDisplayInterface*>::ConstIterator valueDisplaysItEnd
0191         = factory->valueDisplays().constEnd();
0192     for (QHash<int, KPropertyValueDisplayInterface*>::ConstIterator it( factory->valueDisplays().constBegin() );
0193         it != valueDisplaysItEnd; ++it)
0194     {
0195         d->valueDisplays.insert(it.key(), it.value());
0196     }
0197 }
0198 
0199 KComposedPropertyInterface* KPropertyFactoryManager::createComposedProperty(KProperty *parent)
0200 {
0201     const KComposedPropertyCreatorInterface *creator = d->composedPropertyCreators.value( parent->type() );
0202     return creator ? creator->createComposedProperty(parent) : nullptr;
0203 }
0204 
0205 //static
0206 void KPropertyFactoryManager::addInitFunction(void (*initFunction)())
0207 {
0208     _initFunctions->append(initFunction);
0209 }
0210 
0211 bool KPropertyFactoryManager::canConvertValueToText(int type) const
0212 {
0213     return d->valueDisplays.value(type) != nullptr;
0214 }
0215 
0216 bool KPropertyFactoryManager::canConvertValueToText(const KProperty* property) const
0217 {
0218     return canConvertValueToText(property->type());
0219 }
0220 
0221 QString KPropertyFactoryManager::propertyValueToString(const KProperty* property) const
0222 {
0223     const KPropertyValueDisplayInterface *display = d->valueDisplays.value(property->type());
0224     return display ? display->propertyValueToString(property, QLocale::c()) : property->value().toString();
0225 }
0226 
0227 QString KPropertyFactoryManager::valueToString(int type, const QVariant &value) const
0228 {
0229     const KPropertyValueDisplayInterface *display = d->valueDisplays.value(type);
0230     return display ? display->valueToString(value, QLocale::c()) : value.toString();
0231 }
0232 
0233 QString KPropertyFactoryManager::propertyValueToLocalizedString(const KProperty* property) const
0234 {
0235     const KPropertyValueDisplayInterface *display = d->valueDisplays.value(property->type());
0236     return display ? display->propertyValueToString(property, QLocale()) : KPropertyValueDisplayInterface::valueToLocalizedString(property->value());
0237 }
0238 
0239 QString KPropertyFactoryManager::valueToLocalizedString(int type, const QVariant &value) const
0240 {
0241     const KPropertyValueDisplayInterface *display = d->valueDisplays.value(type);
0242     return display ? display->valueToString(value, QLocale()) : KPropertyValueDisplayInterface::valueToLocalizedString(value.toString());
0243 }
0244 
0245 //! @todo
0246 #if 0
0247     const int type = parent->type();
0248 /*
0249     CustomPropertyFactory *factory = d->registeredWidgets[type];
0250     if (factory)
0251         return factory->createCustomProperty(parent);
0252 */
0253     switch (type) {
0254     case Size:
0255     case Size_Width:
0256     case Size_Height:
0257         return new SizeCustomProperty(parent);
0258     case Point:
0259     case Point_X:
0260     case Point_Y:
0261         return new PointCustomProperty(parent);
0262     case Rect:
0263     case Rect_X:
0264     case Rect_Y:
0265     case Rect_Width:
0266     case Rect_Height:
0267         return new RectCustomProperty(parent);
0268     case SizePolicy:
0269 /*    case SizePolicy_HorizontalStretch:
0270     case SizePolicy_VerticalStretch:
0271     case SizePolicy_HorizontalPolicy:
0272     case SizePolicy_VerticalPolicy:*/
0273         return new SizePolicyCustomProperty(parent);
0274     default:;
0275     }
0276     return 0;
0277 #endif
0278 
0279 class Q_DECL_HIDDEN KComposedPropertyInterface::Private
0280 {
0281 public:
0282     Private() {}
0283     bool childValueChangedEnabled = true;
0284 };
0285 
0286 KComposedPropertyInterface::KComposedPropertyInterface(KProperty *parent)
0287  : d(new Private)
0288 {
0289     Q_UNUSED(parent)
0290 }
0291 
0292 KComposedPropertyInterface::~KComposedPropertyInterface()
0293 {
0294     delete d;
0295 }
0296 
0297 void KComposedPropertyInterface::childValueChangedInternal(KProperty *child, const QVariant &value,
0298                                                            KProperty::ValueOptions valueOptions)
0299 {
0300     if (d->childValueChangedEnabled) {
0301         childValueChanged(child, value, valueOptions);
0302     }
0303 }
0304 
0305 void KComposedPropertyInterface::setChildValueChangedEnabled(bool set)
0306 {
0307     d->childValueChangedEnabled = set;
0308 }
0309 
0310 bool KComposedPropertyInterface::childValueChangedEnabled() const
0311 {
0312     return d->childValueChangedEnabled;
0313 }
0314 
0315 //---------------
0316 
0317 class Q_DECL_HIDDEN KComposedPropertyCreatorInterface::Private
0318 {
0319 public:
0320     Private() {}
0321 };
0322 
0323 KComposedPropertyCreatorInterface::KComposedPropertyCreatorInterface()
0324     : d(new Private)
0325 {
0326 }
0327 
0328 KComposedPropertyCreatorInterface::~KComposedPropertyCreatorInterface()
0329 {
0330     delete d;
0331 }