Ran am2cmake.
[basket4.git] / src / kcolorcombo2.cpp
blob2800e8b1dc6e2e9cb417f985bb28bbb3d59800cf
1 /***************************************************************************
2 * Copyright (C) 2005 by S�astien Laot *
3 * slaout@linux62.org *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
21 #include <qapplication.h>
22 #include <qpixmap.h>
23 #include <qbitmap.h>
24 #include <qpainter.h>
25 #include <q3listbox.h>
26 //Added by qt3to4:
27 #include <QDropEvent>
28 #include <QPaintEvent>
29 #include <QMouseEvent>
30 #include <QKeyEvent>
31 #include <QEvent>
32 #include <QDragEnterEvent>
33 #include <kglobalsettings.h>
34 #include <klocale.h>
35 #include <kcolordialog.h>
36 #include <qclipboard.h>
37 #include <kstdaccel.h>
38 #include <kcolordrag.h>
40 #include "kcolorcombo2.h"
42 //#include "qeffects.h"
44 //#define DEBUG_COLOR_ARRAY
45 //#define OUTPUT_GIMP_PALETTE
47 #ifdef DEBUG_COLOR_ARRAY
48 #include <iostream>
49 #include <iomanip>
50 #endif
51 #ifdef OUTPUT_GIMP_PALETTE
52 #include <iostream>
53 #include <iomanip>
54 #endif
56 /** class KColorPopup: */
58 const int KColorPopup::MARGIN = 1;
59 const int KColorPopup::FRAME_WIDTH = 1;
62 KColorPopup::KColorPopup(KColorCombo2 *parent)
63 : QWidget(/*parent=*/0, /*name=*/0, WType_Popup | WNoAutoErase),
64 m_selector(parent)
66 hide();
67 setMouseTracking(true);
68 //resize(20, 20);
69 //setWFlags(Qt::WNoAutoErase);
72 KColorPopup::~KColorPopup()
76 #include <qcursor.h>
78 void KColorPopup::relayout() // FIXME: relayout should NOT redraw the pixmap!
80 int columnCount = m_selector->columnCount();
81 int rowCount = m_selector->rowCount();
82 int colorHeight = m_selector->colorRectHeight();
83 int colorWidth = m_selector->colorRectWidthForHeight(colorHeight);
84 bool haveDefault = m_selector->defaultColor().isValid();
86 int width = 2 + MARGIN + (colorWidth + MARGIN) * columnCount;
87 int height = 2 + MARGIN + (colorHeight + MARGIN) * rowCount + (colorHeight + MARGIN);
89 resize(width, height);
91 // Initialize the pixmap:
92 m_pixmap.resize(width, height);
93 QPainter painter(&m_pixmap);
94 painter.fillRect(0, 0, width, height, KGlobalSettings::baseColor());
95 painter.setPen(KGlobalSettings::textColor());
96 painter.drawRect(0, 0, width, height);
98 // Needed to draw:
99 int x, y;
100 QRect selectionRect;
102 // Draw the color array:
103 for (int i = 0; i < columnCount; ++i) {
104 for (int j = 0; j < rowCount; ++j) {
105 x = 1 + MARGIN + (colorWidth + MARGIN) * i;
106 y = 1 + MARGIN + (colorHeight + MARGIN) * j;
107 if (i == m_selectedColumn && j == m_selectedRow) {
108 selectionRect = QRect(x - 2, y - 2, colorWidth + 4, colorHeight + 4);
109 painter.fillRect(selectionRect, KGlobalSettings::highlightColor());
111 m_selector->drawColorRect(painter, x, y, m_selector->colorAt(i, j), /*isDefault=*/false, colorWidth, colorHeight);
115 m_columnOther = (haveDefault ? columnCount / 2 : 0); // "(Default)" is allowed, paint "Other..." on the right
116 int defaultCellWidth = (colorWidth + MARGIN) * m_columnOther;
117 int otherCellWidth = (colorWidth + MARGIN) * (columnCount - m_columnOther);
119 // Draw the "(Default)" and "Other..." colors:
120 y = height - (colorHeight + MARGIN) - 1;
121 QColor textColor;
122 if (m_selector->defaultColor().isValid()) {
123 x = 1 + MARGIN;
124 if (m_selectedColumn < m_columnOther && rowCount == m_selectedRow) {
125 selectionRect = QRect(x - 2, y - 2, defaultCellWidth, colorHeight + 4);
126 painter.fillRect(selectionRect, KGlobalSettings::highlightColor());
127 textColor = KGlobalSettings::highlightedTextColor();
128 } else
129 textColor = KGlobalSettings::textColor();
130 m_selector->drawColorRect(painter, x, y, m_selector->defaultColor(), /*isDefault=*/true, colorWidth, colorHeight);
131 painter.setFont(m_selector->font());
132 painter.setPen(textColor);
133 painter.drawText(x + 2 + colorWidth, y, /*width=*/5000, colorHeight, AlignLeft | AlignVCenter | DontClip, i18n("(Default)"));
135 x = 1 + MARGIN + m_columnOther * (colorWidth + MARGIN);
136 if (m_selectedColumn >= m_columnOther && rowCount == m_selectedRow) {
137 selectionRect = QRect(x - 2, y - 2, otherCellWidth, colorHeight + 4);
138 painter.fillRect(selectionRect, KGlobalSettings::highlightColor());
139 textColor = KGlobalSettings::highlightedTextColor();
140 } else
141 textColor = KGlobalSettings::textColor();
142 m_selector->drawColorRect(painter, x, y, m_otherColor, /*isDefault=*/false, colorWidth, colorHeight);
143 painter.setFont(m_selector->font());
144 painter.setPen(textColor);
145 painter.drawText(x + 2 + colorWidth, y, /*width=*/5000, colorHeight, AlignLeft | AlignVCenter | DontClip, i18n("Other..."));
147 // QPoint pos = mapFromGlobal(QCursor::pos());
148 // painter.drawRect(pos.x(), pos.y(), 5000, 5000);
151 void KColorPopup::updateCell(int column, int row)
153 int colorHeight = m_selector->colorRectHeight();
154 int colorWidth = m_selector->colorRectWidthForHeight(colorHeight);
156 int x = 1 + MARGIN + - 2 + column * (colorWidth + MARGIN);
157 int y = 1 + MARGIN + - 2 + row * (colorHeight + MARGIN);
158 int width = colorWidth + MARGIN;
159 int height = colorHeight + MARGIN;
161 if (row == m_selector->rowCount()) {
162 if (m_selectedColumn < m_columnOther) // The "(Default)" cell:
163 width = (colorWidth + MARGIN) * m_columnOther;
164 else // The "Other..." cell:
165 width = (colorWidth + MARGIN) * (m_selector->columnCount() - m_columnOther);
168 update(x, y, width, height);
171 void KColorPopup::doSelection()
173 m_otherColor = QColor();
175 // If the selected color is not the default one, try to find it in the array:
176 if (m_selector->color().isValid()) {
177 bool isInArray = false;
178 for (int column = 0; column < m_selector->columnCount(); ++column)
179 for (int row = 0; row < m_selector->rowCount(); ++row)
180 if (m_selector->color() == m_selector->colorAt(column, row)) {
181 m_selectedColumn = column;
182 m_selectedRow = row;
183 isInArray = true;
185 // If not found in array, it's another one:
186 if (!isInArray) {
187 m_selectedColumn = m_columnOther;
188 m_selectedRow = m_selector->rowCount();
189 m_otherColor = m_selector->color();
191 // If it's the default one:
192 } else {
193 m_selectedColumn = 0;
194 m_selectedRow = m_selector->rowCount();
198 void KColorPopup::validate()
200 hide();
201 close();
203 if (m_selectedRow != m_selector->rowCount()) // A normal row:
204 m_selector->setColor(m_selector->colorAt(m_selectedColumn, m_selectedRow));
205 else if (m_selectedColumn < m_columnOther) // The default color:
206 m_selector->setColor(QColor());
207 else { // The user want to choose one:
208 QColor color = m_selector->effectiveColor();
209 if (KColorDialog::getColor(color, this) == QDialog::Accepted)
210 m_selector->setColor(color);
214 void KColorPopup::mousePressEvent(QMouseEvent *event)
216 int x = event->pos().x();
217 int y = event->pos().y();
218 if (x < 0 || y < 0 || x >= width() || y >= height()) {
219 hide();
220 close();
221 } else
222 validate();
224 event->accept();
227 void KColorPopup::paintEvent(QPaintEvent *event)
229 QPainter painter(this);
230 painter.drawPixmap(0, 0, m_pixmap);
231 painter.setPen(Qt::black);
232 painter.drawRect(event->rect());
235 void KColorPopup::mouseMoveEvent(QMouseEvent *event)
237 int x = event->pos().x();
238 int y = event->pos().y();
239 if (x < FRAME_WIDTH + 2 || y < FRAME_WIDTH + 2 || x > width() - 2 - 2*FRAME_WIDTH || y > height() - 2 - 2*FRAME_WIDTH)
240 return;
242 int colorHeight = m_selector->colorRectHeight();
243 int colorWidth = m_selector->colorRectWidthForHeight(colorHeight);
245 // int oldSelectedColumn = m_selectedColumn;
246 // int oldSelectedRow = m_selectedRow;
247 m_selectedColumn = (x - FRAME_WIDTH - MARGIN + 2) / (colorWidth + MARGIN);
248 m_selectedRow = (y - FRAME_WIDTH - MARGIN + 2) / (colorHeight + MARGIN);
250 relayout();
251 update();
254 void KColorPopup::keyPressEvent(QKeyEvent *event)
256 int column = m_selectedColumn;
257 int row = m_selectedRow;
258 int columnCount = m_selector->columnCount();
259 int rowCount = m_selector->rowCount();
261 switch (event->key()) {
262 case Qt::Key_Right:
263 if (m_selectedRow != rowCount) // A normal row:
264 column = (column + 1) % columnCount;
265 else {
266 // The last row, if there are two choices, switch. Else, do nothing:
267 if (m_selector->defaultColor().isValid())
268 column = (m_selectedColumn < m_columnOther ? m_columnOther : 0);
270 break;
271 case Qt::Key_Left:
272 if (m_selectedRow != rowCount) { // A normal row:
273 column = (column - 1);
274 if (column < 0)
275 column = columnCount - 1;
276 } else {
277 // The last row, if there are two choices, switch. Else, do nothing:
278 if (m_selector->defaultColor().isValid())
279 column = (m_selectedColumn < m_columnOther ? m_columnOther : 0);
281 break;
282 case Qt::Key_Up: row = (row - 1); if (row < 0) row = rowCount; break;
283 case Qt::Key_Down: row = (row + 1) % (rowCount+1); break;
284 case Qt::Key_PageDown: row += 10; if (row > rowCount) row = rowCount; break;
285 case Qt::Key_PageUp: row -= 10; if (row < 0) row = 0; break;
286 case Qt::Key_Home: row = 0; column = 0; break;
287 case Qt::Key_End: row = rowCount; column = columnCount - 1; break;
288 case Qt::Key_Return:
289 validate();
290 break;
291 default:
292 QWidget::keyPressEvent(event);
295 if (row != m_selectedRow || column != m_selectedColumn) {
296 m_selectedRow = row;
297 m_selectedColumn = column;
298 relayout();
299 update();
303 /** Helper function: */
305 QColor Tool_mixColors(const QColor &color1, const QColor &color2)
307 QColor mixedColor;
308 mixedColor.setRgb( (color1.red() + color2.red()) / 2,
309 (color1.green() + color2.green()) / 2,
310 (color1.blue() + color2.blue()) / 2 );
311 return mixedColor;
314 /** class KColorCombo2Private */
316 class KColorCombo2::KColorCombo2Private
320 /** class KColorCombo2: */
322 /* All code for the popup management (including the constructor, popup() and eventFilter())
323 * has been copied from the KDateEdit widget (in libkdepim).
325 * Some other piece of code comes from KColorButton (in libkdeui) to enable color drag, drop, copy and paste.
328 KColorCombo2::KColorCombo2(const QColor &color, const QColor &defaultColor, QWidget *parent, const char *name)
329 : QComboBox(/*editable=*/false, parent, name),
330 m_color(color), m_defaultColor(defaultColor)
332 init();
335 KColorCombo2::KColorCombo2(const QColor &color, QWidget *parent, const char *name)
336 : QComboBox(/*editable=*/false, parent, name),
337 m_color(color), m_defaultColor()
339 init();
342 void KColorCombo2::init()
344 m_discardNextMousePress = false;
345 m_colorArray = 0;
346 d = new KColorCombo2Private();
348 setDefaultColor(m_defaultColor);
349 insertItem("", /*index=*/0);
350 updateComboBox(); // It need an item of index 0 to exists, so we created it.
351 setAcceptDrops(true);
353 m_popup = new KColorPopup(this);
354 m_popup->installEventFilter(this);
356 // By default, the array is filled with setRainbowPreset().
357 // But we allocate it on demand (the later as possible) to avoid performances issues if the developer set another array.
358 // However, to keep columnCount() rowCount() const, we define theme here:
359 m_columnCount = 13;
360 m_rowCount = 9;
363 KColorCombo2::~KColorCombo2()
365 deleteColorArray();
368 void KColorCombo2::setColor(const QColor &color)
370 // Do nothing if the color should be set to the default one and there is no such default color allowed:
371 if (!color.isValid() && !m_defaultColor.isValid()) {
372 // kdebug << this::FUNCTION << "Trying to assign the default color (an invalid one) whereas no such default color is allowed";
373 return;
376 if (m_color != color) {
377 m_color = color;
378 updateComboBox();
379 emit changed(color);
383 QColor KColorCombo2::color() const
385 return m_color;
388 QColor KColorCombo2::effectiveColor() const
390 if (m_color.isValid())
391 return m_color;
392 else
393 return m_defaultColor;
396 void KColorCombo2::setRainbowPreset(int colorColumnCount, int lightRowCount, int darkRowCount, bool withGray)
398 // At least one row and one column:
399 if (colorColumnCount < 1 - (withGray ? 1 : 0))
400 colorColumnCount = 1 - (withGray ? 1 : 0);
401 if (lightRowCount < 0)
402 lightRowCount = 0;
403 if (darkRowCount < 0)
404 darkRowCount = 0;
406 // Create the array:
407 int columnCount = colorColumnCount + (withGray ? 1 : 0);
408 int rowCount = lightRowCount + 1 + darkRowCount;
409 newColorArray(columnCount, rowCount);
411 // Fill the array:
412 for (int i = 0; i < colorColumnCount; ++i) {
413 int hue = i * 360 / colorColumnCount;
414 // With light colors:
415 for (int j = 1; j <= lightRowCount; ++j) { // Start to 1 because we don't want a row full of white!
416 int saturation = j * 255 / (lightRowCount + 1);
417 setColorAt(i, j - 1, QColor(hue, saturation, 255, QColor::Hsv));
419 // With pure colors:
420 setColorAt(i, lightRowCount, QColor(hue, 255, 255, QColor::Hsv));
421 // With dark colors:
422 for (int j = 1; j <= darkRowCount; ++j) {
423 int value = 255 - j * 255 / (darkRowCount + 1);
424 setColorAt(i, lightRowCount + j, QColor(hue, 255, value, QColor::Hsv));
428 // Fill the gray column:
429 if (withGray) {
430 for (int i = 0; i < rowCount; ++i) {
431 int gray = ( rowCount == 1 ? 128 : 255 - (i * 255 / (rowCount - 1)) );
432 setColorAt(columnCount-1, i, QColor(gray, gray, gray));
436 #ifdef DEBUG_COLOR_ARRAY
437 std::cout << "KColorCombo2::setColorPreset" << std::endl;
438 for (int j = 0; j < rowCount; ++j) {
439 for (int i = 0; i < columnCount; ++i) {
440 int h, s, v;
441 m_colorArray[i][j].getHsv(h, s, v);
442 std::cout << "(" << std::setw(3) << h << "," << std::setw(3) << s << "," << std::setw(3) << v << ") ";
443 //std::cout << colorArray[i][j].name() << " ";
445 std::cout << std::endl;
447 #endif
448 #ifdef OUTPUT_GIMP_PALETTE
449 std::cout << "GIMP Palette" << std::endl;
450 for (int j = 0; j < rowCount; ++j) {
451 for (int i = 0; i < columnCount; ++i) {
452 std::cout << std::setw(3) << m_colorArray[i][j].red() << ", " << std::setw(3) << m_colorArray[i][j].green() << ", " << std::setw(3) << m_colorArray[i][j].blue() << std::endl;
455 #endif
458 int KColorCombo2::columnCount() const
460 return m_columnCount;
463 int KColorCombo2::rowCount() const
465 return m_rowCount;
468 QColor KColorCombo2::colorAt(int column, int row)/* const*/
470 if (!m_colorArray)
471 setRainbowPreset();
473 if (column < 0 || row < 0 || column >= m_columnCount || row >= m_rowCount)
474 return QColor();
476 return m_colorArray[column][row];
479 QColor KColorCombo2::defaultColor() const
481 return m_defaultColor;
484 void KColorCombo2::newColorArray(int columnCount, int rowCount)
486 if (columnCount <= 0 || rowCount <= 0) {
487 // kdebug << this::FUNCTION << "Trying to create an empty new color array (with %d columns and %d rows)";
488 return;
491 // Delete any previous array (if any):
492 deleteColorArray();
494 // Create a new array of the wanted dimentions:
495 m_columnCount = columnCount;
496 m_rowCount = rowCount;
497 m_colorArray = new QColor* [columnCount];
498 for (int i = 0; i < columnCount; ++i)
499 m_colorArray[i] = new QColor[rowCount];
501 m_popup->relayout();
504 void KColorCombo2::setColorAt(int column, int row, const QColor &color)
506 if (!m_colorArray)
507 setRainbowPreset();
509 if (column < 0 || row < 0 || column >= m_columnCount || row >= m_rowCount) {
510 // kdebug << this::FUNCTION << "Trying to set a color at an invalid index (at column %d and row %d, whereas the array have %d columns and %d rows)";
511 return;
514 m_colorArray[column][row] = color;
517 void KColorCombo2::setDefaultColor(const QColor &color)
519 m_defaultColor = color;
520 if (!m_defaultColor.isValid() && !m_color.isValid())
521 m_color = Qt::white; // FIXME: Use the first one.
524 QPixmap KColorCombo2::colorRectPixmap(const QColor &color, bool isDefault, int width, int height)
526 // Prepare to draw:
527 QPixmap pixmap(width, height);
528 QBitmap mask(width, height);
529 QPainter painter(&pixmap);
530 QPainter maskPainter(&mask);
532 // Draw pixmap:
533 drawColorRect(painter, 0, 0, color, isDefault, width, height);
535 // Draw mask (make the four corners transparent):
536 maskPainter.fillRect(0, 0, width, height, Qt::color1); // opaque
537 maskPainter.setPen(Qt::color0); // transparent
538 maskPainter.drawPoint(0, 0);
539 maskPainter.drawPoint(0, height - 1);
540 maskPainter.drawPoint(width - 1, height - 1);
541 maskPainter.drawPoint(width - 1, 0);
543 // Finish:
544 painter.end();
545 maskPainter.end();
546 pixmap.setMask(mask);
547 return pixmap;
550 void KColorCombo2::drawColorRect(QPainter &painter, int x, int y, const QColor &color, bool isDefault, int width, int height)
552 // Fill:
553 if (color.isValid())
554 painter.fillRect(x /*+ 1*/, y /*+ 1*/, width /*- 2*/, height /*- 2*/, color);
555 else {
556 // If it's an invalid color, it's for the "Other..." entry: draw a rainbow.
557 // If it wasn't for the "Other..." entry, the programmer made a fault, so (s)he will be informed about that visually.
558 for (int i = 0; i < width-2; ++i) {
559 int hue = i * 360 / (width-2);
560 for (int j = 0; j < height-2; ++j) {
561 int saturation = 255 - (j * 255 / (height-2));
562 painter.setPen( QColor(hue, saturation, /*value=*/255, QColor::Hsv) );
563 painter.drawPoint(x + i + 1, y + j + 1);
568 // Stroke:
569 int dontCare, value;
570 color.getHsv(/*hue:*/dontCare, /*saturation:*/dontCare, value);
571 QColor stroke = (color.isValid() ? color.dark(125) : KGlobalSettings::textColor());
572 painter.setPen(/*color);//*/stroke);
573 painter.drawLine(x + 1, y, x + width - 2, y);
574 painter.drawLine(x, y + 1, x, y + height - 2);
575 painter.drawLine(x + 1, y + height - 1, x + width - 2, y + height - 1);
576 painter.drawLine(x + width - 1, y + 1, x + width - 1, y + height - 2);
578 // Round corners:
579 QColor antialiasing;
580 if (color.isValid()) {
581 antialiasing = Tool_mixColors(color, stroke);
582 painter.setPen(antialiasing);
583 painter.drawPoint(x + 1, y + 1);
584 painter.drawPoint(x + 1, y + height - 2);
585 painter.drawPoint(x + width - 2, y + height - 2);
586 painter.drawPoint(x + width - 2, y + 1);
587 } else {
588 // The two top corners:
589 antialiasing = Tool_mixColors(Qt::red, stroke);
590 painter.setPen(antialiasing);
591 painter.drawPoint(x + 1, y + 1);
592 painter.drawPoint(x + width - 2, y + 1);
593 // The two bottom ones:
594 antialiasing = Tool_mixColors(Qt::white, stroke);
595 painter.setPen(antialiasing);
596 painter.drawPoint(x + 1, y + height - 2);
597 painter.drawPoint(x + width - 2, y + height - 2);
600 // Mark default color:
601 if (isDefault) {
602 painter.setPen(stroke);
603 painter.drawLine(x + 1, y + height - 2, x + width - 2, y + 1);
607 int KColorCombo2::colorRectHeight() const
609 return (fontMetrics().boundingRect(i18n("(Default)")).height() + 2)*3/2;
612 int KColorCombo2::colorRectWidthForHeight(int height) const
614 return height * 14 / 10; // 1.4 times the height, like A4 papers.
617 void KColorCombo2::deleteColorArray()
619 if (m_colorArray) {
620 for (int i = 0; i < m_columnCount; ++i)
621 delete[] m_colorArray[i];
622 delete[] m_colorArray;
623 m_colorArray = 0;
627 void KColorCombo2::updateComboBox()
629 int height = colorRectHeight()*2/3; // fontMetrics().boundingRect(i18n("(Default)")).height() + 2
630 QPixmap pixmap = colorRectPixmap(effectiveColor(), !m_color.isValid(), colorRectWidthForHeight(height), height); // TODO: isDefaultColorSelected()
631 changeItem(pixmap, (m_color.isValid() ? "" : i18n("(Default)")), /*index=*/0);
634 void KColorCombo2::popup()
636 if (!m_colorArray)
637 setRainbowPreset();
639 // Compute where to show the popup:
640 QRect desk = KGlobalSettings::desktopGeometry(this);
642 QPoint popupPoint = mapToGlobal(QPoint(0, 0));
644 int popupHeight = m_popup->sizeHint().height();
645 if (popupPoint.y() + height() + popupHeight > desk.bottom())
646 popupPoint.setY(popupPoint.y() - popupHeight);
647 else
648 popupPoint.setY(popupPoint.y() + height());
650 int popupWidth = m_popup->sizeHint().width();
651 if (popupPoint.x() + popupWidth > desk.right())
652 popupPoint.setX(desk.right() - popupWidth);
654 if (popupPoint.x() < desk.left())
655 popupPoint.setX(desk.left());
657 if (popupPoint.y() < desk.top())
658 popupPoint.setY(desk.top());
660 // Configure the popup:
661 m_popup->move(popupPoint);
662 //m_popup->setColor(m_color);
663 m_popup->doSelection();
664 m_popup->relayout(); // FIXME: In aboutToShow() ?
665 #if 0
666 //#ifndef QT_NO_EFFECTS
667 if (QApplication::isEffectEnabled(UI_AnimateCombo)) {
668 if (m_popup->y() < mapToGlobal(QPoint(0,0)).y())
669 qScrollEffect(m_popup, QEffects::UpScroll);
670 else
671 qScrollEffect(m_popup);
672 } else
673 #endif
674 m_popup->show();
676 // The combo box is now shown pressed. Make it show not pressed again
677 // by causing its (invisible) list box to emit a 'selected' signal.
678 // Simulate an Enter to unpress it:
679 Q3ListBox *lb = listBox();
680 if (lb) {
681 lb->setCurrentItem(0);
682 QKeyEvent* keyEvent = new QKeyEvent(QEvent::KeyPress, Qt::Key_Enter, 0, 0);
683 QApplication::postEvent(lb, keyEvent);
687 bool KColorCombo2::eventFilter(QObject */*object*/, QEvent *event)
689 QMouseEvent *mouseEvent;
691 switch (event->type()) {
692 case QEvent::MouseButtonDblClick:
693 case QEvent::MouseButtonPress:
694 mouseEvent = (QMouseEvent*)event;
695 if ( !m_popup->rect().contains(mouseEvent->pos()) ) {
696 QPoint globalPos = m_popup->mapToGlobal(mouseEvent->pos());
697 if (QApplication::widgetAt(globalPos, /*child=*/true) == this) {
698 // The popup is being closed by a click on the KColorCombo2 widget.
699 // Avoid popping it up again immediately:
700 m_discardNextMousePress = true;
703 break;
704 default:
705 break;
708 // Don't stop the event being handled further:
709 return false;
712 void KColorCombo2::mousePressEvent(QMouseEvent *event)
714 m_dragStartPos = event->pos();
716 if (event->button() == Qt::LeftButton && m_discardNextMousePress)
717 m_discardNextMousePress = false;
718 else
719 QComboBox::mousePressEvent(event);
722 void KColorCombo2::mouseMoveEvent(QMouseEvent *event)
724 if( (event->state() & Qt::LeftButton) &&
725 (event->pos() - m_dragStartPos).manhattanLength() > KGlobalSettings::dndEventDelay() ) {
726 // Drag color object:
727 KColorDrag *colorDrag = new KColorDrag(effectiveColor(), this);
728 // Replace the drag pixmap with our own rounded one, at the same position and dimetions:
729 QPixmap pixmap = colorDrag->pixmap();
730 pixmap = colorRectPixmap(effectiveColor(), /*isDefault=*/false, pixmap.width(), pixmap.height());
731 colorDrag->setPixmap(pixmap, colorDrag->pixmapHotSpot());
732 colorDrag->dragCopy();
733 //setDown(false);
737 void KColorCombo2::dragEnterEvent(QDragEnterEvent *event)
739 event->accept(isEnabled() && KColorDrag::canDecode(event));
742 void KColorCombo2::dropEvent(QDropEvent *event)
744 QColor color;
745 if (KColorDrag::decode(event, color))
746 setColor(color);
749 void KColorCombo2::keyPressEvent(QKeyEvent *event)
751 KKey key(event);
753 if (KStdAccel::copy().contains(key)) {
754 QMimeSource *mime = new KColorDrag(effectiveColor());
755 QApplication::clipboard()->setData(mime, QClipboard::Clipboard);
756 } else if (KStdAccel::paste().contains(key)) {
757 QColor color;
758 KColorDrag::decode(QApplication::clipboard()->data(QClipboard::Clipboard), color);
759 setColor(color);
760 } else
761 QComboBox::keyPressEvent(event);
764 void KColorCombo2::fontChange(const QFont &oldFont)
766 // Since the color-rectangle is the same height of the text, we should resize it if the font change:
767 updateComboBox();
768 QComboBox::fontChange(oldFont); // To update geometry.
771 void KColorCombo2::virtual_hook(int /*id*/, void */*data*/)
773 /* KBASE::virtual_hook(id, data); */
776 #include "kcolorcombo2.moc"