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

0001 /* This file is part of the KDE project
0002    Copyright (C) 2010-2016 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 #include "coloredit.h"
0021 #include "combobox.h"
0022 #include "KPropertyUtils_p.h"
0023 
0024 #include <QEvent>
0025 #include <QHBoxLayout>
0026 
0027 #include <KColorCombo>
0028 #include <KColorCollection>
0029 
0030 Q_GLOBAL_STATIC_WITH_ARGS(KColorCollection, g_oxygenColors, (QLatin1String("Oxygen.colors")))
0031 
0032 static QString colorToName(const QColor &color, const QLocale &locale)
0033 {
0034     if (!color.isValid()) {
0035         return locale.language() == QLocale::C ? QString::fromLatin1("#invalid")
0036                                      : QObject::tr("#invalid", "Invalid color");
0037     }
0038     return color.alpha() == 255 ? color.name(QColor::HexRgb) : color.name(QColor::HexArgb);
0039 }
0040 
0041 //! @brief Paints color code
0042 //! Useful for caching the font.
0043 //! @internal
0044 class ColorCodePainter
0045 {
0046 public:
0047     explicit ColorCodePainter(const QFont &font)
0048         : m_font(font)
0049     {
0050         m_font.setFamily(QLatin1String("courier"));
0051     }
0052     void paint(QPainter *painter, const QRect &rect, const QColor &color) {
0053         painter->setPen(KPropertyUtilsPrivate::contrastColor(color));
0054         painter->setFont(m_font);
0055         painter->drawText(rect, Qt::AlignCenter, colorToName(color, QLocale()));
0056     }
0057 
0058 private:
0059     QFont m_font;
0060 };
0061 
0062 // -------------------
0063 
0064 class Q_DECL_HIDDEN KPropertyColorComboEditor::Private
0065 {
0066 public:
0067     Private() {}
0068     KColorCombo *combo;
0069     QWidget *colorCodeOverlay;
0070     QScopedPointer<ColorCodePainter> colorCodePainter;
0071 };
0072 
0073 KPropertyColorComboEditor::KPropertyColorComboEditor(QWidget *parent)
0074         : QWidget(parent)
0075         , d(new Private)
0076 {
0077     installEventFilter(this); // handle size of the combo
0078     d->colorCodePainter.reset(new ColorCodePainter(font()));
0079     d->combo = new KColorCombo(this);
0080     connect(d->combo, SIGNAL(activated(QColor)), this, SLOT(slotValueChanged(QColor)));
0081     d->combo->installEventFilter(this); // handle size of the overlay
0082     d->colorCodeOverlay = new QWidget(d->combo, Qt::CustomizeWindowHint | Qt::WindowTransparentForInput);
0083     d->colorCodeOverlay->raise();
0084     d->colorCodeOverlay->installEventFilter(this); // handle painting of the overlay
0085     QList< QColor > colors;
0086     const int oxygenColorsCount = g_oxygenColors->count();
0087     for (int i = 0; i < oxygenColorsCount; i++) {
0088         colors += g_oxygenColors->color(i);
0089     }
0090     d->combo->setColors(colors);
0091     setFocusProxy(d->combo);
0092 
0093     int paddingTop = 1;
0094     if (!KPropertyUtilsPrivate::gridLineColor(this).isValid()) {
0095         d->combo->setFrame(false);
0096         paddingTop = 0;
0097     }
0098     QString styleSheet = QString::fromLatin1("KPropertyColorComboEditor { \
0099         %1; \
0100         padding-top: %2px; padding-left: 1px; }")
0101         .arg(KPropertyComboBoxEditor::borderSheet(this))
0102         .arg(paddingTop);
0103     setStyleSheet(styleSheet);
0104 }
0105 
0106 KPropertyColorComboEditor::~KPropertyColorComboEditor()
0107 {
0108     delete d;
0109 }
0110 
0111 QVariant KPropertyColorComboEditor::value() const
0112 {
0113     return d->combo->color();
0114 }
0115 
0116 void KPropertyColorComboEditor::setValue(const QVariant &value)
0117 {
0118     d->combo->setColor(value.value<QColor>());
0119 }
0120 
0121 void KPropertyColorComboEditor::slotValueChanged(const QColor&)
0122 {
0123     emit commitData(this);
0124 }
0125 
0126 bool KPropertyColorComboEditor::eventFilter(QObject *o, QEvent *e)
0127 {
0128     const bool result = QWidget::eventFilter(o, e);
0129     if (o == d->colorCodeOverlay) {
0130         if (e->type() == QEvent::Paint) {
0131             QPainter painter(d->colorCodeOverlay);
0132              d->colorCodePainter->paint(&painter, d->colorCodeOverlay->rect(), d->combo->color());
0133         }
0134     } else if (o == d->combo) {
0135         if (e->type() == QEvent::Resize) {
0136             d->colorCodeOverlay->setGeometry(0, 0, d->combo->width(), d->combo->height());
0137         }
0138     } else if (o == this) {
0139         if (e->type() == QEvent::Resize) {
0140             d->combo->setGeometry(0, 0, width(), height()+1);
0141         }
0142     }
0143     return result;
0144 }
0145 
0146 // -------------------
0147 
0148 class Q_DECL_HIDDEN KPropertyColorComboDelegate::Private
0149 {
0150 public:
0151     Private() {}
0152     QScopedPointer<ColorCodePainter> colorCodePainter;
0153 };
0154 
0155 KPropertyColorComboDelegate::KPropertyColorComboDelegate()
0156     : d(new Private)
0157 {
0158 }
0159 
0160 KPropertyColorComboDelegate::~KPropertyColorComboDelegate()
0161 {
0162     delete d;
0163 }
0164 
0165 QWidget * KPropertyColorComboDelegate::createEditor(int type, QWidget *parent,
0166     const QStyleOptionViewItem &option, const QModelIndex &index) const
0167 {
0168     Q_UNUSED(type)
0169     Q_UNUSED(option)
0170     Q_UNUSED(index)
0171     return new KPropertyColorComboEditor(parent);
0172 }
0173 
0174 void KPropertyColorComboDelegate::paint( QPainter * painter,
0175     const QStyleOptionViewItem & option, const QModelIndex & index ) const
0176 {
0177     const KPropertyUtilsPrivate::PainterSaver saver(painter);
0178     const QBrush b(index.data(Qt::EditRole).value<QColor>());
0179     painter->setBrush(b);
0180     painter->setPen(QPen(Qt::NoPen));
0181     painter->drawRect(option.rect);
0182     if (!d->colorCodePainter) {
0183         d->colorCodePainter.reset(new ColorCodePainter(option.font));
0184     }
0185     d->colorCodePainter->paint(painter, option.rect, b.color());
0186 }
0187 
0188 QString KPropertyColorComboDelegate::valueToString(const QVariant& value, const QLocale &locale) const
0189 {
0190     return colorToName(value.value<QColor>(), locale);
0191 }