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

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 "KPropertyWidgetsPluginManager.h"
0022 #include "KDefaultPropertyFactory.h"
0023 #include "KPropertyEditorView.h"
0024 #include "KPropertyUtils.h"
0025 
0026 //! Class for access to KPropertyWidgetsPluginManager constructor
0027 class KPropertyWidgetsPluginManagerSingleton
0028 {
0029 public:
0030     KPropertyWidgetsPluginManager object;
0031 };
0032 
0033 //! @internal
0034 class Q_DECL_HIDDEN KPropertyWidgetsPluginManager::Private
0035 {
0036 public:
0037     Private()
0038     {
0039     }
0040     ~Private()
0041     {
0042     }
0043 
0044     QHash<int, KPropertyEditorCreatorInterface*> editorCreators;
0045     QHash<int, KPropertyValuePainterInterface*> valuePainters;
0046 };
0047 
0048 Q_GLOBAL_STATIC(KPropertyWidgetsPluginManagerSingleton, _self)
0049 
0050 //! @internal Make sure sure the KPropertyWidgetsPluginManager is created after
0051 //! KPropertyFactoryManager (delayed). Unless KPropertyFactoryManager is created,
0052 //! KPropertyWidgetsPluginManager isn't created.
0053 //! @todo is this worth putting in a reusable macro?
0054 struct KPropertyWidgetsPluginManagerInitializer {
0055     KPropertyWidgetsPluginManagerInitializer() {
0056         KPropertyFactoryManager::addInitFunction(&initMe);
0057     }
0058     static void initMe() { KPropertyWidgetsPluginManager::self(); }
0059 };
0060 namespace {
0061 KPropertyWidgetsPluginManagerInitializer init;
0062 }
0063 
0064 //------------
0065 
0066 KPropertyWidgetsPluginManager::KPropertyWidgetsPluginManager()
0067         : d(new Private)
0068 {
0069     registerFactory(new KDefaultPropertyFactory);
0070 }
0071 
0072 KPropertyWidgetsPluginManager::~KPropertyWidgetsPluginManager()
0073 {
0074     delete d;
0075 }
0076 
0077 KPropertyWidgetsPluginManager* KPropertyWidgetsPluginManager::self()
0078 {
0079     KPropertyFactoryManager::self(); // make sure KPropertyFactoryManager instance exists
0080                                      // before KPropertyWidgetsPluginManager ctor is called
0081     return &_self->object;
0082 }
0083 
0084 void KPropertyWidgetsPluginManager::registerFactory(KPropertyWidgetsFactory *factory)
0085 {
0086     KPropertyFactoryManager::self()->registerFactory(factory);
0087 
0088     QHash<int, KPropertyEditorCreatorInterface*>::ConstIterator editorCreatorsItEnd
0089         = factory->editorCreators().constEnd();
0090     for (QHash<int, KPropertyEditorCreatorInterface*>::ConstIterator it( factory->editorCreators().constBegin() );
0091         it != editorCreatorsItEnd; ++it)
0092     {
0093         d->editorCreators.insert(it.key(), it.value());
0094     }
0095     QHash<int, KPropertyValuePainterInterface*>::ConstIterator valuePaintersItEnd
0096         = factory->valuePainters().constEnd();
0097     for (QHash<int, KPropertyValuePainterInterface*>::ConstIterator it( factory->valuePainters().constBegin() );
0098         it != valuePaintersItEnd; ++it)
0099     {
0100         d->valuePainters.insert(it.key(), it.value());
0101     }
0102 }
0103 
0104 bool KPropertyWidgetsPluginManager::isEditorForTypeAvailable( int type ) const
0105 {
0106     return d->editorCreators.value(type);
0107 }
0108 
0109 QWidget * KPropertyWidgetsPluginManager::createEditor(
0110     int type, QWidget *parent,
0111     const QStyleOptionViewItem & option, const QModelIndex & index ) const
0112 {
0113     const KPropertyEditorCreatorInterface *creator = d->editorCreators.value(type);
0114     if (!creator)
0115         return nullptr;
0116     QWidget *w = creator->createEditor(type, parent, option, index);
0117     KProperty *property = KPropertyUtils::propertyForIndex(index);
0118     if (w && property) {
0119        w->setObjectName(QLatin1String(property->name()));
0120        if (!creator->options()->bordersVisible()) {
0121 //! @todo get real border color from the palette
0122             QColor gridLineColor(qobject_cast<KPropertyEditorView*>(parent->parentWidget()) ?
0123                 qobject_cast<KPropertyEditorView*>(parent->parentWidget())->gridLineColor()
0124                 : KPropertyEditorView::defaultGridLineColor());
0125             QString cssClassName = QLatin1String(w->metaObject()->className());
0126             cssClassName.replace(QLatin1String("KProperty"), QString()); //!< @todo
0127             QString css =
0128                 QString::fromLatin1("%1 { border-top: 1px solid %2; } ")
0129                 .arg(cssClassName).arg(gridLineColor.name());
0130 //            kprDebug() << css;
0131             w->setStyleSheet(css);
0132         }
0133     }
0134     return w;
0135 }
0136 
0137 bool KPropertyWidgetsPluginManager::paint( int type, QPainter * painter,
0138     const QStyleOptionViewItem & option, const QModelIndex & index ) const
0139 {
0140     const KPropertyValuePainterInterface *_painter = d->valuePainters.value(type);
0141     if (!_painter)
0142         return false;
0143     QStyleOptionViewItem realOption(option);
0144     if (option.state & QStyle::State_Selected) {
0145         // paint background because there may be editor widget with no autoFillBackground set
0146         realOption.palette.setBrush(QPalette::Text, realOption.palette.highlightedText());
0147         painter->fillRect(realOption.rect, realOption.palette.highlight());
0148     }
0149     painter->setPen(realOption.palette.text().color());
0150     _painter->paint(painter, realOption, index);
0151     return true;
0152 }
0153 
0154 //! @todo
0155 #if 0
0156     const int type = parent->type();
0157 /*
0158     CustomPropertyFactory *factory = d->registeredWidgets[type];
0159     if (factory)
0160         return factory->createCustomProperty(parent);
0161 */
0162     switch (type) {
0163     case Size:
0164     case Size_Width:
0165     case Size_Height:
0166         return new SizeCustomProperty(parent);
0167     case Point:
0168     case Point_X:
0169     case Point_Y:
0170         return new PointCustomProperty(parent);
0171     case Rect:
0172     case Rect_X:
0173     case Rect_Y:
0174     case Rect_Width:
0175     case Rect_Height:
0176         return new RectCustomProperty(parent);
0177     case SizePolicy:
0178 /*    case SizePolicy_HorizontalStretch:
0179     case SizePolicy_VerticalStretch:
0180     case SizePolicy_HorizontalPolicy:
0181     case SizePolicy_VerticalPolicy:*/
0182         return new SizePolicyCustomProperty(parent);
0183     default:;
0184     }
0185     return 0;
0186 #endif