00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include "kcolorcombo.h"
00034
00035 #include <QtCore/QVector>
00036 #include <QtGui/QAbstractItemDelegate>
00037 #include <QtGui/QStylePainter>
00038
00039 #include <kglobal.h>
00040 #include <klocale.h>
00041
00042 #include "kcolordialog.h"
00043
00044
00045
00046
00047
00048
00049 class KColorComboDelegate : public QAbstractItemDelegate
00050 {
00051 public:
00052 static const int ColorRole = Qt::UserRole + 1;
00053
00054 KColorComboDelegate(QObject *parent = 0);
00055 virtual ~KColorComboDelegate();
00056
00057 virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
00058 virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
00059 };
00060
00061 static const int colorframe_delta = 3;
00062
00063 static QBrush k_colorcombodelegate_brush(const QModelIndex &index, int role)
00064 {
00065 QBrush brush;
00066 QVariant v = index.data(role);
00067 if (v.type() == QVariant::Brush) {
00068 brush = v.value<QBrush>();
00069 } else if (v.type() == QVariant::Color) {
00070 brush = QBrush(v.value<QColor>());
00071 }
00072 return brush;
00073 }
00074
00075 KColorComboDelegate::KColorComboDelegate(QObject *parent)
00076 : QAbstractItemDelegate(parent)
00077 {
00078 }
00079
00080 KColorComboDelegate::~KColorComboDelegate()
00081 {
00082 }
00083
00084 void KColorComboDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
00085 {
00086
00087 QBrush backbrush = k_colorcombodelegate_brush(index, Qt::BackgroundRole);
00088 QColor innercolor(Qt::white);
00089 bool isSelected = (option.state & QStyle::State_Selected);
00090 bool paletteBrush = false;
00091 if (backbrush.style() == Qt::NoBrush) {
00092 paletteBrush = true;
00093 if (isSelected) {
00094 backbrush = option.palette.brush(QPalette::Highlight);
00095 } else {
00096 backbrush = option.palette.brush(QPalette::Base);
00097 }
00098 }
00099 if (isSelected) {
00100 innercolor = option.palette.color(QPalette::Highlight);
00101 } else {
00102 innercolor = option.palette.color(QPalette::Base);
00103 }
00104 painter->fillRect(option.rect, backbrush);
00105 QRect innerrect = option.rect.adjusted(colorframe_delta, colorframe_delta, -colorframe_delta, -colorframe_delta);
00106
00107 QVariant cv = index.data(ColorRole);
00108 if (cv.type() == QVariant::Color) {
00109 QColor tmpcolor = cv.value<QColor>();
00110 if (tmpcolor.isValid()) {
00111 innercolor = tmpcolor;
00112 paletteBrush = false;
00113 painter->setPen(Qt::black);
00114 painter->setBrush(innercolor);
00115 painter->drawRect(innerrect);
00116 painter->setBrush(Qt::NoBrush);
00117 }
00118 }
00119
00120 QVariant tv = index.data(Qt::DisplayRole);
00121 if (tv.type() == QVariant::String) {
00122 QString text = tv.toString();
00123 QColor textColor;
00124 if (paletteBrush) {
00125 if (isSelected) {
00126 textColor = option.palette.color(QPalette::HighlightedText);
00127 } else {
00128 textColor = option.palette.color(QPalette::Text);
00129 }
00130 } else {
00131 int unused, v;
00132 innercolor.getHsv(&unused, &unused, &v);
00133 if (v > 128) {
00134 textColor = Qt::black;
00135 } else {
00136 textColor = Qt::white;
00137 }
00138 }
00139 painter->setPen(textColor);
00140 painter->drawText(innerrect.adjusted(1, 1, -1, -1), text);
00141 }
00142 }
00143
00144 QSize KColorComboDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
00145 {
00146 Q_UNUSED(index)
00147
00148
00149 return QSize(100, option.fontMetrics.height() + 2 * colorframe_delta);
00150 }
00151
00152
00153 #define STANDARD_PAL_SIZE 17
00154
00155 K_GLOBAL_STATIC_WITH_ARGS(QVector<QColor>, standardPalette, (STANDARD_PAL_SIZE))
00156 static void createStandardPalette()
00157 {
00158 if ( standardPalette->isEmpty() )
00159 return;
00160
00161 int i = 0;
00162
00163 (*standardPalette)[i++] = Qt::red;
00164 (*standardPalette)[i++] = Qt::green;
00165 (*standardPalette)[i++] = Qt::blue;
00166 (*standardPalette)[i++] = Qt::cyan;
00167 (*standardPalette)[i++] = Qt::magenta;
00168 (*standardPalette)[i++] = Qt::yellow;
00169 (*standardPalette)[i++] = Qt::darkRed;
00170 (*standardPalette)[i++] = Qt::darkGreen;
00171 (*standardPalette)[i++] = Qt::darkBlue;
00172 (*standardPalette)[i++] = Qt::darkCyan;
00173 (*standardPalette)[i++] = Qt::darkMagenta;
00174 (*standardPalette)[i++] = Qt::darkYellow;
00175 (*standardPalette)[i++] = Qt::white;
00176 (*standardPalette)[i++] = Qt::lightGray;
00177 (*standardPalette)[i++] = Qt::gray;
00178 (*standardPalette)[i++] = Qt::darkGray;
00179 (*standardPalette)[i++] = Qt::black;
00180 }
00181
00182 class KColorComboPrivate
00183 {
00184 public:
00185 KColorComboPrivate(KColorCombo *qq);
00186
00187 void addColors();
00188 void setCustomColor(const QColor &color, bool lookupInPresets = true);
00189
00190
00191 void _k_slotActivated(int index);
00192 void _k_slotHighlighted(int index);
00193
00194 KColorCombo *q;
00195 QList<QColor> colorList;
00196 QColor customColor;
00197 QColor internalcolor;
00198 };
00199
00200 KColorComboPrivate::KColorComboPrivate(KColorCombo *qq)
00201 : q(qq), customColor(Qt::white)
00202 {
00203 }
00204
00205 void KColorComboPrivate::setCustomColor(const QColor &color, bool lookupInPresets)
00206 {
00207 if (lookupInPresets) {
00208 if (colorList.isEmpty()) {
00209 for (int i = 0; i < STANDARD_PAL_SIZE; ++i) {
00210 if (standardPalette->at(i) == color) {
00211 q->setCurrentIndex(i + 1);
00212 internalcolor = color;
00213 return;
00214 }
00215 }
00216 } else {
00217 int i = colorList.indexOf(color);
00218 if (i >= 0) {
00219 q->setCurrentIndex(i + 1);
00220 internalcolor = color;
00221 return;
00222 }
00223 }
00224 }
00225
00226 internalcolor = color;
00227 customColor = color;
00228 q->setItemData(0, customColor, KColorComboDelegate::ColorRole);
00229 }
00230
00231
00232 KColorCombo::KColorCombo( QWidget *parent )
00233 : QComboBox(parent), d(new KColorComboPrivate(this))
00234 {
00235 createStandardPalette();
00236
00237 setItemDelegate(new KColorComboDelegate(this));
00238 d->addColors();
00239
00240 connect(this, SIGNAL(activated(int)), SLOT(_k_slotActivated(int)));
00241 connect(this, SIGNAL(highlighted(int)), SLOT(_k_slotHighlighted(int)));
00242
00243
00244 setCurrentIndex(13);
00245 d->_k_slotActivated(13);
00246 }
00247
00248
00249 KColorCombo::~KColorCombo()
00250 {
00251 delete d;
00252 }
00253
00254 void KColorCombo::setColors( const QList<QColor> &colors )
00255 {
00256 clear();
00257 d->colorList = colors;
00258 d->addColors();
00259 }
00260
00261 QList<QColor> KColorCombo::colors() const
00262 {
00263 if (d->colorList.isEmpty()) {
00264 QList<QColor> list;
00265 for (int i = 0; i < STANDARD_PAL_SIZE; ++i) {
00266 list += standardPalette->at(i);
00267 }
00268 return list;
00269 } else {
00270 return d->colorList;
00271 }
00272 }
00273
00277 void KColorCombo::setColor( const QColor &col )
00278 {
00279 if (!col.isValid()) {
00280 return;
00281 }
00282
00283 if (count() == 0) {
00284 d->addColors();
00285 }
00286
00287 d->setCustomColor(col, true);
00288 }
00289
00290
00294 QColor KColorCombo::color() const {
00295 return d->internalcolor;
00296 }
00297
00298 bool KColorCombo::isCustomColor() const
00299 {
00300 return d->internalcolor == d->customColor;
00301 }
00302
00303 void KColorCombo::paintEvent(QPaintEvent *event)
00304 {
00305 Q_UNUSED(event)
00306 QStylePainter painter(this);
00307 painter.setPen(palette().color(QPalette::Text));
00308
00309 QStyleOptionComboBox opt;
00310 initStyleOption(&opt);
00311 painter.drawComplexControl(QStyle::CC_ComboBox, opt);
00312
00313 QRect frame = style()->subControlRect(QStyle::CC_ComboBox, &opt, QStyle::SC_ComboBoxEditField, this);
00314 painter.fillRect(frame.adjusted(1, 1, -1, -1), QBrush(d->internalcolor));
00315 }
00316
00320 void KColorCombo::showEmptyList()
00321 {
00322 clear();
00323 }
00324
00325 void KColorComboPrivate::_k_slotActivated(int index)
00326 {
00327 if (index == 0) {
00328 if (KColorDialog::getColor(customColor, q) == QDialog::Accepted) {
00329 setCustomColor(customColor, false);
00330 }
00331 } else if (colorList.isEmpty()) {
00332 internalcolor = standardPalette->at(index - 1);
00333 } else {
00334 internalcolor = colorList[index - 1];
00335 }
00336
00337 emit q->activated(internalcolor);
00338 }
00339
00340 void KColorComboPrivate::_k_slotHighlighted(int index)
00341 {
00342 if (index == 0) {
00343 internalcolor = customColor;
00344 } else if (colorList.isEmpty()) {
00345 internalcolor = standardPalette->at(index - 1);
00346 } else {
00347 internalcolor = colorList[index - 1];
00348 }
00349
00350 emit q->highlighted(internalcolor);
00351 }
00352
00353 void KColorComboPrivate::addColors()
00354 {
00355 q->addItem(i18nc("Custom color", "Custom..."));
00356
00357 if (colorList.isEmpty()) {
00358 for (int i = 0; i < STANDARD_PAL_SIZE; ++i) {
00359 q->addItem(QString());
00360 q->setItemData(i + 1, standardPalette->at(i), KColorComboDelegate::ColorRole);
00361 }
00362 } else {
00363 for (int i = 0, count = colorList.count(); i < count; ++i) {
00364 q->addItem(QString());
00365 q->setItemData(i + 1, colorList[i], KColorComboDelegate::ColorRole);
00366 }
00367 }
00368 }
00369
00370 #include "kcolorcombo.moc"