File indexing completed on 2024-04-21 04:41:05

0001 /* This file is part of the KDE project
0002    Copyright (C) 2008-2017 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 #include "KDefaultPropertyFactory.h"
0024 #include "KPropertyEditorView.h"
0025 #include "KPropertyStringEditor.h"
0026 #include "KPropertyUtils.h"
0027 #include "KPropertyUtils_p.h"
0028 
0029 class Q_DECL_HIDDEN KPropertyLabel::Private
0030 {
0031 public:
0032     Private()
0033     {
0034     }
0035     ~Private()
0036     {
0037     }
0038 
0039     const KProperty *property;
0040     const KPropertyValueDisplayInterface *iface;
0041     QVariant value;
0042 };
0043 
0044 KPropertyLabel::KPropertyLabel(QWidget *parent, const KProperty *property,
0045                                const KPropertyValueDisplayInterface *iface)
0046     : QLabel(parent), d(new Private)
0047 {
0048     d->property = property;
0049     d->iface = iface;
0050     setAutoFillBackground(true);
0051 
0052     KPropertyEditorView* view = nullptr;
0053     if (parent) {
0054         view = qobject_cast<KPropertyEditorView *>(parent->parentWidget());
0055     }
0056     const QColor gridLineColor(view ? view->gridLineColor()
0057                                     : KPropertyEditorView::defaultGridLineColor());
0058     const int top = 1 + (gridLineColor.isValid() ? 1 : 0);
0059 
0060     setContentsMargins(0, top, 0, 0);
0061     setIndent(1);
0062 }
0063 
0064 KPropertyLabel::~KPropertyLabel()
0065 {
0066     delete d;
0067 }
0068 
0069 QVariant KPropertyLabel::value() const
0070 {
0071     return d->value;
0072 }
0073 
0074 void KPropertyLabel::setValue(const QVariant& value)
0075 {
0076     d->value = value;
0077     setText(d->iface->propertyValueToString(d->property, QLocale()));
0078 }
0079 
0080 void KPropertyLabel::paintEvent( QPaintEvent * event )
0081 {
0082     QLabel::paintEvent(event);
0083     KPropertyWidgetsFactory::paintTopGridLine(this);
0084 }
0085 
0086 //---------------
0087 
0088 //! @internal
0089 class Q_DECL_HIDDEN KPropertyWidgetsFactory::Private
0090 {
0091 public:
0092     Private()
0093     {
0094     }
0095     ~Private()
0096     {
0097         qDeleteAll(editorCreatorsSet);
0098         qDeleteAll(valuePaintersSet);
0099     }
0100 
0101     QHash<int, KPropertyEditorCreatorInterface*> editorCreators;
0102     QHash<int, KPropertyValuePainterInterface*> valuePainters;
0103 
0104     QSet<KPropertyEditorCreatorInterface*> editorCreatorsSet;
0105     QSet<KPropertyValuePainterInterface*> valuePaintersSet;
0106 };
0107 
0108 KPropertyWidgetsFactory::KPropertyWidgetsFactory()
0109     : d( new Private )
0110 {
0111 }
0112 
0113 KPropertyWidgetsFactory::~KPropertyWidgetsFactory()
0114 {
0115     delete d;
0116 }
0117 
0118 QHash<int, KPropertyEditorCreatorInterface*> KPropertyWidgetsFactory::editorCreators() const
0119 {
0120     return d->editorCreators;
0121 }
0122 
0123 QHash<int, KPropertyValuePainterInterface*> KPropertyWidgetsFactory::valuePainters() const
0124 {
0125     return d->valuePainters;
0126 }
0127 
0128 void KPropertyWidgetsFactory::addEditor(int type, KPropertyEditorCreatorInterface *creator)
0129 {
0130     addEditorInternal( type, creator, true );
0131     if (dynamic_cast<KComposedPropertyCreatorInterface*>(creator)) {
0132         addComposedPropertyCreatorInternal( type,
0133             dynamic_cast<KComposedPropertyCreatorInterface*>(creator), false/* !own*/ );
0134     }
0135     if (dynamic_cast<KPropertyValuePainterInterface*>(creator)) {
0136         addPainterInternal( type, dynamic_cast<KPropertyValuePainterInterface*>(creator), false/* !own*/ );
0137     }
0138     if (dynamic_cast<KPropertyValueDisplayInterface*>(creator)) {
0139         addDisplayInternal( type, dynamic_cast<KPropertyValueDisplayInterface*>(creator), false/* !own*/ );
0140     }
0141 }
0142 
0143 void KPropertyWidgetsFactory::addPainter(int type, KPropertyValuePainterInterface *painter)
0144 {
0145     addPainterInternal(type, painter, true);
0146     if (dynamic_cast<KComposedPropertyCreatorInterface*>(painter)) {
0147         addComposedPropertyCreatorInternal( type,
0148         dynamic_cast<KComposedPropertyCreatorInterface*>(painter), false/* !own*/ );
0149     }
0150     if (dynamic_cast<KPropertyEditorCreatorInterface*>(painter)) {
0151         addEditorInternal( type, dynamic_cast<KPropertyEditorCreatorInterface*>(painter), false/* !own*/ );
0152     }
0153     if (dynamic_cast<KPropertyValueDisplayInterface*>(painter)) {
0154         addDisplayInternal( type, dynamic_cast<KPropertyValueDisplayInterface*>(painter), false/* !own*/ );
0155     }
0156 }
0157 
0158 void KPropertyWidgetsFactory::addEditorInternal(int type, KPropertyEditorCreatorInterface *editor, bool own)
0159 {
0160     if (own)
0161         d->editorCreatorsSet.insert(editor);
0162     d->editorCreators.insert(type, editor);
0163 }
0164 
0165 void KPropertyWidgetsFactory::addPainterInternal(int type, KPropertyValuePainterInterface *painter, bool own)
0166 {
0167     if (own)
0168         d->valuePaintersSet.insert(painter);
0169     d->valuePainters.insert(type, painter);
0170 }
0171 
0172 //static
0173 void KPropertyWidgetsFactory::paintTopGridLine(QWidget *widget)
0174 {
0175     // paint top grid line
0176     KPropertyEditorView* view = nullptr;
0177     if (widget->parentWidget()) {
0178         view = qobject_cast<KPropertyEditorView*>(widget->parentWidget()->parentWidget());
0179     }
0180     const QColor gridLineColor(view ? view->gridLineColor() : KPropertyEditorView::defaultGridLineColor());
0181     if (gridLineColor.isValid()) {
0182         const QAbstractScrollArea *area = qobject_cast<const QAbstractScrollArea*>(widget);
0183         QWidget *widgetToPaint;
0184         if (area && area->viewport()) {
0185             widgetToPaint = area->viewport();
0186         } else {
0187             widgetToPaint = widget;
0188         }
0189         QPainter p(widgetToPaint);
0190         p.setPen(QPen( QBrush(gridLineColor), 1));
0191         p.drawLine(0, 0, widget->width()-1, 0);
0192     }
0193 }
0194 
0195 //static
0196 void KPropertyWidgetsFactory::setTopAndBottomBordersUsingStyleSheet(QWidget *widget,
0197                                                                     const QString& extraStyleSheet)
0198 {
0199     KPropertyEditorView* view = nullptr;
0200     if (widget->parentWidget()) {
0201         view = qobject_cast<KPropertyEditorView*>(widget->parentWidget()->parentWidget());
0202     }
0203     const QColor gridLineColor(view ? view->gridLineColor() : KPropertyEditorView::defaultGridLineColor());
0204     widget->setStyleSheet(
0205         QString::fromLatin1("%1 { border-top: 1px solid %2;border-bottom: 1px solid %2; } %3")
0206         .arg(QLatin1String(widget->metaObject()->className()))
0207         .arg(gridLineColor.name()).arg(extraStyleSheet));
0208 }
0209 
0210 //------------
0211 
0212 class Q_DECL_HIDDEN KPropertyEditorCreatorOptions::Private
0213 {
0214 public:
0215     Private() : bordersVisible(false)
0216     {
0217     }
0218     Private(const Private &other) {
0219         copy(other);
0220     }
0221 #define KPropertyEditorCreatorOptionsPrivateArgs(o) std::tie(o.bordersVisible)
0222     void copy(const Private &other) {
0223         KPropertyEditorCreatorOptionsPrivateArgs((*this)) = KPropertyEditorCreatorOptionsPrivateArgs(other);
0224     }
0225     bool operator==(const Private &other) const {
0226         return KPropertyEditorCreatorOptionsPrivateArgs((*this)) == KPropertyEditorCreatorOptionsPrivateArgs(other);
0227     }
0228     bool bordersVisible;
0229 };
0230 
0231 KPropertyEditorCreatorOptions::KPropertyEditorCreatorOptions()
0232     : d(new Private)
0233 {
0234 }
0235 
0236 KPropertyEditorCreatorOptions::KPropertyEditorCreatorOptions(const KPropertyEditorCreatorOptions &other)
0237     : d(new Private(*other.d))
0238 {
0239 }
0240 
0241 KPropertyEditorCreatorOptions::~KPropertyEditorCreatorOptions()
0242 {
0243     delete d;
0244 }
0245 
0246 bool KPropertyEditorCreatorOptions::bordersVisible() const
0247 {
0248     return d->bordersVisible;
0249 }
0250 
0251 void KPropertyEditorCreatorOptions::setBordersVisible(bool visible)
0252 {
0253     d->bordersVisible = visible;
0254 }
0255 
0256 KPropertyEditorCreatorOptions& KPropertyEditorCreatorOptions::operator=(const KPropertyEditorCreatorOptions &other)
0257 {
0258     if (this != &other) {
0259         d->copy(*other.d);
0260     }
0261     return *this;
0262 }
0263 
0264 bool KPropertyEditorCreatorOptions::operator==(const KPropertyEditorCreatorOptions &other) const
0265 {
0266     return *d == *other.d;
0267 }
0268 
0269 //------------
0270 
0271 class Q_DECL_HIDDEN KPropertyEditorCreatorInterface::Private
0272 {
0273 public:
0274     Private()
0275     {
0276     }
0277 
0278     //! Options for altering the editor widget creation process
0279     KPropertyEditorCreatorOptions options;
0280 };
0281 
0282 KPropertyEditorCreatorInterface::KPropertyEditorCreatorInterface()
0283     : d(new Private)
0284 {
0285 }
0286 
0287 KPropertyEditorCreatorInterface::~KPropertyEditorCreatorInterface()
0288 {
0289     delete d;
0290 }
0291 
0292 QWidget* KPropertyEditorCreatorInterface::createEditor(int type, QWidget *parent,
0293                                                        const QStyleOptionViewItem & option,
0294                                                        const QModelIndex & index) const
0295 {
0296     Q_UNUSED(type);
0297     Q_UNUSED(option);
0298     Q_UNUSED(index);
0299     return new KPropertyStringEditor(parent);
0300 }
0301 
0302 const KPropertyEditorCreatorOptions* KPropertyEditorCreatorInterface::options() const
0303 {
0304     return &d->options;
0305 }
0306 
0307 KPropertyEditorCreatorOptions* KPropertyEditorCreatorInterface::options()
0308 {
0309     return &d->options;
0310 }
0311 
0312 //------------
0313 
0314 KPropertyValuePainterInterface::KPropertyValuePainterInterface()
0315 {
0316 }
0317 
0318 KPropertyValuePainterInterface::~KPropertyValuePainterInterface()
0319 {
0320 }
0321 
0322 //static
0323 void KPropertyValuePainterInterface::paint(const KPropertyValueDisplayInterface *iface,
0324                                            QPainter *painter, const QStyleOptionViewItem &option,
0325                                            const QModelIndex &index)
0326 {
0327     const KPropertyUtilsPrivate::PainterSaver saver(painter);
0328     QRect r(option.rect);
0329     r.setLeft(r.left() + 1);
0330     KProperty *prop = KPropertyUtils::propertyForIndex(index);
0331     painter->drawText(r, Qt::AlignLeft | Qt::AlignVCenter,
0332         iface->propertyValueToString(prop, QLocale()));
0333 }