Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qcolordialog.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5#include "qcolordialog.h"
6
7#if QT_CONFIG(accessibility)
8#include "qaccessible.h"
9#endif
10#include "qapplication.h"
11#include "qdrawutil.h"
12#include "qevent.h"
13#include "qimage.h"
14#if QT_CONFIG(draganddrop)
15#include <qdrag.h>
16#endif
17#include "qlabel.h"
18#include "qlayout.h"
19#include "qlineedit.h"
20#if QT_CONFIG(menu)
21#include "qmenu.h"
22#endif
23#include "qpainter.h"
24#include "qpixmap.h"
25#include "qpushbutton.h"
26#if QT_CONFIG(regularexpression)
27#include <qregularexpression.h>
28#endif
29#if QT_CONFIG(settings)
30#include "qsettings.h"
31#endif
32#include "qsharedpointer.h"
33#include "qstyle.h"
34#include "qstyleoption.h"
35#include "qvalidator.h"
36#include "qmimedata.h"
37#include "qspinbox.h"
39#include "qscreen.h"
40#include "qcursor.h"
41#include "qtimer.h"
42#include "qwindow.h"
43
44#include "private/qdialog_p.h"
45#include "private/qcolorwell_p.h"
46
47#include <qpa/qplatformintegration.h>
48#include <qpa/qplatformservices.h>
49#include <private/qguiapplication_p.h>
50
51#include <QtCore/qpointer.h>
52
53#include <algorithm>
54
55QT_BEGIN_NAMESPACE
56
57using namespace Qt::StringLiterals;
58
59namespace QtPrivate {
61class QColorPicker;
62class QColorShower;
64} // namespace QtPrivate
65
70
72{
73 Q_DECLARE_PUBLIC(QColorDialog)
74
75public:
81
83#ifdef Q_OS_WIN32
84 , updateTimer(0)
85#endif
86 {}
87
89 { return static_cast<QPlatformColorDialogHelper *>(platformHelper()); }
90
91 void init(const QColor &initial);
94 QColor currentQColor() const;
95 void setCurrentColor(const QColor &color, SetColorMode setColorMode = SetColorAll);
96 void setCurrentRgbColor(QRgb rgb);
97 void setCurrentQColor(const QColor &color);
98 bool selectColor(const QColor &color);
99 QColor grabScreenColor(const QPoint &p);
100
101 int currentAlpha() const;
102 void setCurrentAlpha(int a);
103 void showAlpha(bool b);
104 bool isAlphaVisible() const;
107
108 void addCustom();
109 void _q_setCustom(int index, QRgb color);
110
111 void newHsv(int h, int s, int v);
112 void newColorTypedIn(QRgb rgb);
113 void nextCustom(int, int);
114 void newCustom(int, int);
115 void newStandard(int, int);
119 void updateColorPicking(const QPoint &pos);
121 bool handleColorPickingMouseMove(QMouseEvent *e);
123 bool handleColorPickingKeyPress(QKeyEvent *e);
124
126 void setVisible(bool visible) override;
127
130
139 QPushButton *ok;
140 QPushButton *cancel;
141 QPushButton *addCusBt;
142 QPushButton *eyeDropperButton = nullptr;
150
154#ifdef Q_OS_WIN32
157#endif
158
159private:
160 virtual void initHelper(QPlatformDialogHelper *h) override;
161 virtual void helperPrepareShow(QPlatformDialogHelper *h) override;
162};
163
164//////////// QWellArray BEGIN
165
166void QWellArray::paintEvent(QPaintEvent *e)
167{
168 QRect r = e->rect();
169 int cx = r.x();
170 int cy = r.y();
171 int ch = r.height();
172 int cw = r.width();
173 int colfirst = columnAt(cx);
174 int collast = columnAt(cx + cw);
175 int rowfirst = rowAt(cy);
176 int rowlast = rowAt(cy + ch);
177
178 if (isRightToLeft()) {
179 int t = colfirst;
180 colfirst = collast;
181 collast = t;
182 }
183
184 QPainter painter(this);
185 QPainter *p = &painter;
186 QRect rect(0, 0, cellWidth(), cellHeight());
187
188
189 if (collast < 0 || collast >= ncols)
190 collast = ncols-1;
191 if (rowlast < 0 || rowlast >= nrows)
192 rowlast = nrows-1;
193
194 // Go through the rows
195 for (int r = rowfirst; r <= rowlast; ++r) {
196 // get row position and height
197 int rowp = rowY(r);
198
199 // Go through the columns in the row r
200 // if we know from where to where, go through [colfirst, collast],
201 // else go through all of them
202 for (int c = colfirst; c <= collast; ++c) {
203 // get position and width of column c
204 int colp = columnX(c);
205 // Translate painter and draw the cell
206 rect.translate(colp, rowp);
207 paintCell(p, r, c, rect);
208 rect.translate(-colp, -rowp);
209 }
210 }
211}
212
213QWellArray::QWellArray(int rows, int cols, QWidget *parent)
214 : QWidget(parent)
215 ,nrows(rows), ncols(cols)
216{
217 setFocusPolicy(Qt::StrongFocus);
218 cellw = 28;
219 cellh = 24;
220 curCol = 0;
221 curRow = 0;
222 selCol = -1;
223 selRow = -1;
224}
225
226QSize QWellArray::sizeHint() const
227{
228 ensurePolished();
229 return gridSize().boundedTo(QSize(640, 480));
230}
231
232
233void QWellArray::paintCell(QPainter* p, int row, int col, const QRect &rect)
234{
235 int b = 3; //margin
236
237 const QPalette & g = palette();
238 QStyleOptionFrame opt;
239 opt.initFrom(this);
240 int dfw = style()->pixelMetric(QStyle::PM_DefaultFrameWidth, &opt, this);
241 opt.lineWidth = dfw;
242 opt.midLineWidth = 1;
243 opt.rect = rect.adjusted(b, b, -b, -b);
244 opt.palette = g;
245 opt.state = QStyle::State_Enabled | QStyle::State_Sunken;
246 style()->drawPrimitive(QStyle::PE_Frame, &opt, p, this);
247 b += dfw;
248
249 if ((row == curRow) && (col == curCol)) {
250 if (hasFocus()) {
251 QStyleOptionFocusRect opt;
252 opt.palette = g;
253 opt.rect = rect;
254 opt.state = QStyle::State_None | QStyle::State_KeyboardFocusChange;
255 style()->drawPrimitive(QStyle::PE_FrameFocusRect, &opt, p, this);
256 }
257 }
258 paintCellContents(p, row, col, opt.rect.adjusted(dfw, dfw, -dfw, -dfw));
259}
260
261/*
262 Reimplement this function to change the contents of the well array.
263 */
264void QWellArray::paintCellContents(QPainter *p, int row, int col, const QRect &r)
265{
266 Q_UNUSED(row);
267 Q_UNUSED(col);
268 p->fillRect(r, Qt::white);
269 p->setPen(Qt::black);
270 p->drawLine(r.topLeft(), r.bottomRight());
271 p->drawLine(r.topRight(), r.bottomLeft());
272}
273
274void QWellArray::mousePressEvent(QMouseEvent *e)
275{
276 // The current cell marker is set to the cell the mouse is pressed in
277 QPoint pos = e->position().toPoint();
278 setCurrent(rowAt(pos.y()), columnAt(pos.x()));
279}
280
281void QWellArray::mouseReleaseEvent(QMouseEvent * /* event */)
282{
283 // The current cell marker is set to the cell the mouse is clicked in
284 setSelected(curRow, curCol);
285}
286
287
288/*
289 Sets the cell currently having the focus. This is not necessarily
290 the same as the currently selected cell.
291*/
292
293void QWellArray::setCurrent(int row, int col)
294{
295 if ((curRow == row) && (curCol == col))
296 return;
297
298 if (row < 0 || col < 0 || row >= nrows || col >= ncols)
299 row = col = -1;
300
301 int oldRow = curRow;
302 int oldCol = curCol;
303
304 curRow = row;
305 curCol = col;
306
307 updateCell(oldRow, oldCol);
308 updateCell(curRow, curCol);
309
310 emit currentChanged(curRow, curCol);
311 sendAccessibleChildFocusEvent();
312}
313
314/*
315 Sets the currently selected cell to \a row, \a column. If \a row or
316 \a column are less than zero, the current cell is unselected.
317
318 Does not set the position of the focus indicator.
319*/
320void QWellArray::setSelected(int row, int col)
321{
322 int oldRow = selRow;
323 int oldCol = selCol;
324
325 if (row < 0 || col < 0)
326 row = col = -1;
327
328 selCol = col;
329 selRow = row;
330
331 updateCell(oldRow, oldCol);
332 updateCell(selRow, selCol);
333 if (row >= 0)
334 emit selected(row, col);
335
336#if QT_CONFIG(menu)
337 if (isVisible() && qobject_cast<QMenu*>(parentWidget()))
338 parentWidget()->close();
339#endif
340}
341
342void QWellArray::focusInEvent(QFocusEvent*)
343{
344 updateCell(curRow, curCol);
345 emit currentChanged(curRow, curCol);
346 sendAccessibleChildFocusEvent();
347}
348
349
350void QWellArray::focusOutEvent(QFocusEvent*)
351{
352 updateCell(curRow, curCol);
353}
354
355void QWellArray::keyPressEvent(QKeyEvent* e)
356{
357 switch(e->key()) { // Look at the key code
358 case Qt::Key_Left: // If 'left arrow'-key,
359 if (curCol > 0) // and cr't not in leftmost col
360 setCurrent(curRow, curCol - 1); // set cr't to next left column
361 break;
362 case Qt::Key_Right: // Correspondingly...
363 if (curCol < numCols()-1)
364 setCurrent(curRow, curCol + 1);
365 break;
366 case Qt::Key_Up:
367 if (curRow > 0)
368 setCurrent(curRow - 1, curCol);
369 break;
370 case Qt::Key_Down:
371 if (curRow < numRows()-1)
372 setCurrent(curRow + 1, curCol);
373 break;
374 case Qt::Key_Space:
375 setSelected(curRow, curCol);
376 break;
377 default: // If not an interesting key,
378 e->ignore(); // we don't accept the event
379 return;
380 }
381}
382
383void QWellArray::sendAccessibleChildFocusEvent()
384{
385#if QT_CONFIG(accessibility)
386 if (!QAccessible::isActive())
387 return;
388
389 if (hasFocus() && curRow >= 0 && curCol >= 0) {
390 const int itemIndex = index(curRow, curCol);
391 QAccessibleEvent event(this, QAccessible::Focus);
392 event.setChild(itemIndex);
393 QAccessible::updateAccessibility(&event);
394 }
395#endif
396}
397
398//////////// QWellArray END
399
400namespace QtPrivate {
401
402// Event filter to be installed on the dialog while in color-picking mode.
404public:
405 explicit QColorPickingEventFilter(QColorDialogPrivate *dp, QObject *parent) : QObject(parent), m_dp(dp) {}
406
407 bool eventFilter(QObject *, QEvent *event) override
408 {
409 switch (event->type()) {
410 case QEvent::MouseMove:
411 return m_dp->handleColorPickingMouseMove(static_cast<QMouseEvent *>(event));
412 case QEvent::MouseButtonRelease:
413 return m_dp->handleColorPickingMouseButtonRelease(static_cast<QMouseEvent *>(event));
414 case QEvent::KeyPress:
415 return m_dp->handleColorPickingKeyPress(static_cast<QKeyEvent *>(event));
416 default:
417 break;
418 }
419 return false;
420 }
421
422 void applicationStateChanged(Qt::ApplicationState state)
423 {
424 if (state != Qt::ApplicationActive)
426 }
427
428private:
430};
431
432} // namespace QtPrivate
433
434/*
435 Internal event filter used to adjust dialog options during widget polish.
436
437 Enables DontUseNativeDialog automatically when QColorDialog is subclassed
438 and no explicit options were set by the user.
439*/
441{
442public:
443 explicit QColorPolishFilter(QColorDialog *cd) : QObject(cd)
444 {
445 cd->installEventFilter(this);
446 }
447
448 bool eventFilter(QObject *obj, QEvent *event) override
449 {
450 if (event->type() == QEvent::Polish ) {
451 Q_ASSERT(qobject_cast<QColorDialog *>(obj));
452 auto *cd = static_cast<QColorDialog *>(obj);
453 auto *d = static_cast<QColorDialogPrivate *>(QObjectPrivate::get(cd));
454
455 if (cd->metaObject() != &QColorDialog::staticMetaObject && !d->optionsExplicitlySet)
456 cd->setOption(QColorDialog::DontUseNativeDialog);
457
458 deleteLater(); // no longer needed after first polish
459 }
460 return false;
461 }
462};
463
464/*!
465 Returns the number of custom colors supported by QColorDialog. All
466 color dialogs share the same custom colors.
467*/
468int QColorDialog::customCount()
469{
470 return QColorDialogOptions::customColorCount();
471}
472
473/*!
474 Returns the custom color at the given \a index as a QColor value.
475*/
476QColor QColorDialog::customColor(int index)
477{
478 return QColor(QColorDialogOptions::customColor(index));
479}
480
481/*!
482 Sets the custom color at \a index to the QColor \a color value.
483
484 \note This function does not apply to the Native Color Dialog on the
485 \macos platform. If you still require this function, use the
486 QColorDialog::DontUseNativeDialog option.
487*/
488void QColorDialog::setCustomColor(int index, QColor color)
489{
490 QColorDialogOptions::setCustomColor(index, color.rgba());
491}
492
493/*!
494 \since 5.0
495
496 Returns the standard color at the given \a index as a QColor value.
497*/
498QColor QColorDialog::standardColor(int index)
499{
500 return QColor(QColorDialogOptions::standardColor(index));
501}
502
503/*!
504 Sets the standard color at \a index to the QColor \a color value.
505
506 \note This function does not apply to the Native Color Dialog on the
507 \macos platform. If you still require this function, use the
508 QColorDialog::DontUseNativeDialog option.
509*/
510void QColorDialog::setStandardColor(int index, QColor color)
511{
512 QColorDialogOptions::setStandardColor(index, color.rgba());
513}
514
515static inline void rgb2hsv(QRgb rgb, int &h, int &s, int &v)
516{
517 QColor c;
518 c.setRgb(rgb);
519 c.getHsv(&h, &s, &v);
520}
521
522void QColorWell::paintCellContents(QPainter *p, int row, int col, const QRect &r)
523{
524 int i = row + col*numRows();
525 p->fillRect(r, QColor(values[i]));
526}
527
528void QColorWell::mousePressEvent(QMouseEvent *e)
529{
530 oldCurrent = QPoint(selectedRow(), selectedColumn());
531 QWellArray::mousePressEvent(e);
532 mousePressed = true;
533 pressPos = e->position().toPoint();
534}
535
536void QColorWell::mouseMoveEvent(QMouseEvent *e)
537{
538 QWellArray::mouseMoveEvent(e);
539#if QT_CONFIG(draganddrop)
540 if (!mousePressed)
541 return;
542 if ((pressPos - e->position().toPoint()).manhattanLength() > QApplication::startDragDistance()) {
543 setCurrent(oldCurrent.x(), oldCurrent.y());
544 int i = rowAt(pressPos.y()) + columnAt(pressPos.x()) * numRows();
545 QColor col(values[i]);
546 QMimeData *mime = new QMimeData;
547 mime->setColorData(col);
548 QPixmap pix(cellWidth(), cellHeight());
549 pix.fill(col);
550 QPainter p(&pix);
551 p.drawRect(0, 0, pix.width() - 1, pix.height() - 1);
552 p.end();
553 QDrag *drg = new QDrag(this);
554 drg->setMimeData(mime);
555 drg->setPixmap(pix);
556 mousePressed = false;
557 drg->exec(Qt::CopyAction);
558 }
559#endif
560}
561
562#if QT_CONFIG(draganddrop)
563void QColorWell::dragEnterEvent(QDragEnterEvent *e)
564{
565 if (qvariant_cast<QColor>(e->mimeData()->colorData()).isValid())
566 e->accept();
567 else
568 e->ignore();
569}
570
571void QColorWell::dragLeaveEvent(QDragLeaveEvent *)
572{
573 if (hasFocus())
574 parentWidget()->setFocus();
575}
576
577void QColorWell::dragMoveEvent(QDragMoveEvent *e)
578{
579 if (qvariant_cast<QColor>(e->mimeData()->colorData()).isValid()) {
580 setCurrent(rowAt(e->position().toPoint().y()), columnAt(e->position().toPoint().x()));
581 e->accept();
582 } else {
583 e->ignore();
584 }
585}
586
587void QColorWell::dropEvent(QDropEvent *e)
588{
589 QColor col = qvariant_cast<QColor>(e->mimeData()->colorData());
590 if (col.isValid()) {
591 int i = rowAt(e->position().toPoint().y()) + columnAt(e->position().toPoint().x()) * numRows();
592 emit colorChanged(i, col.rgb());
593 e->accept();
594 } else {
595 e->ignore();
596 }
597}
598
599#endif // QT_CONFIG(draganddrop)
600
601void QColorWell::mouseReleaseEvent(QMouseEvent *e)
602{
603 if (!mousePressed)
604 return;
605 QWellArray::mouseReleaseEvent(e);
606 mousePressed = false;
607}
608
609namespace QtPrivate {
610
611class QColorPicker : public QFrame
612{
614public:
617
618 void setCrossVisible(bool visible);
619public slots:
620 void setCol(int h, int s);
621
622signals:
623 void newCol(int h, int s);
624
625protected:
626 QSize sizeHint() const override;
627 void paintEvent(QPaintEvent*) override;
628 void keyPressEvent(QKeyEvent *event) override;
629 void mouseMoveEvent(QMouseEvent *) override;
630 void mousePressEvent(QMouseEvent *) override;
631 void resizeEvent(QResizeEvent *) override;
632
633private:
634 QPoint m_pos;
635
636 QPixmap createColorsPixmap();
637 QPoint colPt(int hue, int sat);
638 int huePt(const QPoint &pt, const QSize &widgetSize);
639 int huePt(const QPoint &pt) { return huePt(pt, size()); }
640 int satPt(const QPoint &pt, const QSize &widgetSize);
641 int satPt(const QPoint &pt) { return satPt(pt, size()); }
642 void setCol(const QPoint &pt, bool notify = true);
643
644 QPixmap pix;
645 bool crossVisible;
646};
647
648} // namespace QtPrivate
649
650static int pWidth = 220;
651static int pHeight = 200;
652
653namespace QtPrivate {
654
656{
658public:
661
662public slots:
663 void setCol(int h, int s, int v);
664 void setCol(int h, int s);
665
666signals:
667 void newHsv(int h, int s, int v);
668
669protected:
670 void paintEvent(QPaintEvent*) override;
671 void keyPressEvent(QKeyEvent *event) override;
672 void mouseMoveEvent(QMouseEvent *) override;
673 void mousePressEvent(QMouseEvent *) override;
674
675private:
676 enum { foff = 3, coff = 4 }; //frame and contents offset
677 int val;
678 int hue;
679 int sat;
680
681 int y2val(int y);
682 int val2y(int val);
683 void setVal(int v);
684
685 QPixmap pix;
686};
687
688
689int QColorLuminancePicker::y2val(int y)
690{
691 int d = height() - 2*coff - 1;
692 return 255 - (y - coff)*255/d;
693}
694
695int QColorLuminancePicker::val2y(int v)
696{
697 int d = height() - 2*coff - 1;
698 return coff + (255-v)*d/255;
699}
700
701QColorLuminancePicker::QColorLuminancePicker(QWidget* parent)
702 :QWidget(parent)
703{
704 hue = 100; val = 100; sat = 100;
705 // setAttribute(WA_NoErase, true);
706 setFocusPolicy(Qt::StrongFocus);
707}
708
712
714{
715 switch (event->key()) {
716 case Qt::Key_Down:
717 setVal(std::clamp(val - 1, 0, 255));
718 break;
719 case Qt::Key_Up:
720 setVal(std::clamp(val + 1, 0, 255));
721 break;
722 default:
723 QWidget::keyPressEvent(event);
724 break;
725 }
726}
727
729{
730 if (m->buttons() == Qt::NoButton) {
731 m->ignore();
732 return;
733 }
734 setVal(y2val(m->position().toPoint().y()));
735}
737{
738 setVal(y2val(m->position().toPoint().y()));
739}
740
741void QColorLuminancePicker::setVal(int v)
742{
743 if (val == v)
744 return;
745 val = qMax(0, qMin(v,255));
746 pix = QPixmap();
747 repaint();
748 emit newHsv(hue, sat, val);
749}
750
751//receives from a hue,sat chooser and relays.
752void QColorLuminancePicker::setCol(int h, int s)
753{
754 setCol(h, s, val);
755 emit newHsv(h, s, val);
756}
757
759{
760 int w = width() - 5;
761
762 QRect r(0, foff, w, height() - 2*foff);
763 int wi = r.width() - 2;
764 int hi = r.height() - 2;
765 if (pix.isNull() || pix.height() != hi || pix.width() != wi) {
766 QImage img(wi, hi, QImage::Format_RGB32);
767 int y;
768 uint *pixel = (uint *) img.scanLine(0);
769 for (y = 0; y < hi; y++) {
770 uint *end = pixel + wi;
771 std::fill(pixel, end, QColor::fromHsv(hue, sat, y2val(y + coff)).rgb());
772 pixel = end;
773 }
774 pix = QPixmap::fromImage(img);
775 }
776 QPainter p(this);
777 p.drawPixmap(1, coff, pix);
778 const QPalette &g = palette();
779 qDrawShadePanel(&p, r, g, true);
780 p.setPen(g.windowText().color());
781 p.setBrush(g.windowText());
782 p.eraseRect(w, 0, 5, height());
783 const int y = val2y(val);
784 const std::array<QPoint, 3> points = {QPoint(w, y), QPoint(w + 5, y + 5), QPoint(w + 5, y - 5)};
785 p.drawPolygon(points.data(), static_cast<int>(points.size()));
786}
787
788void QColorLuminancePicker::setCol(int h, int s , int v)
789{
790 val = v;
791 hue = h;
792 sat = s;
793 pix = QPixmap();
794 repaint();
795}
796
797QPoint QColorPicker::colPt(int hue, int sat)
798{
799 QRect r = contentsRect();
800 return QPoint((360 - hue) * (r.width() - 1) / 360, (255 - sat) * (r.height() - 1) / 255);
801}
802
803int QColorPicker::huePt(const QPoint &pt, const QSize &widgetSize)
804{
805 QRect r = QRect(QPoint(0, 0), widgetSize) - contentsMargins();
806 return std::clamp(360 - pt.x() * 360 / (r.width() - 1), 0, 359);
807}
808
809int QColorPicker::satPt(const QPoint &pt, const QSize &widgetSize)
810{
811 QRect r = QRect(QPoint(0, 0), widgetSize) - contentsMargins();
812 return std::clamp(255 - pt.y() * 255 / (r.height() - 1), 0, 255);
813}
814
815void QColorPicker::setCol(const QPoint &pt, bool notify)
816{
817 if (pt == m_pos || pix.isNull())
818 return;
819
820 Q_ASSERT(pix.height());
821 Q_ASSERT(pix.width());
822
823 QRect r(m_pos, QSize(20, 20));
824 m_pos.setX(std::clamp(pt.x(), 0, pix.width() - 1));
825 m_pos.setY(std::clamp(pt.y(), 0, pix.height() - 1));
826 r = r.united(QRect(m_pos, QSize(20, 20)));
827 r.translate(contentsRect().x() - 9, contentsRect().y() - 9);
828 // update(r);
829 repaint(r);
830
831 if (notify)
832 emit newCol(huePt(m_pos), satPt(m_pos));
833}
834
835QColorPicker::QColorPicker(QWidget* parent)
836 : QFrame(parent)
837 , crossVisible(true)
838{
839 setAttribute(Qt::WA_NoSystemBackground);
840 setFocusPolicy(Qt::StrongFocus);
841 setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed) );
842 adjustSize();
843
844 pix = createColorsPixmap();
845
846 setCol(150, 255);
847}
848
852
853void QColorPicker::setCrossVisible(bool visible)
854{
855 if (crossVisible != visible) {
856 crossVisible = visible;
857 update();
858 }
859}
860
862{
863 return QSize(pWidth + 2*frameWidth(), pHeight + 2*frameWidth());
864}
865
866void QColorPicker::setCol(int h, int s)
867{
868 int nhue = qMin(qMax(0,h), 359);
869 int nsat = qMin(qMax(0,s), 255);
870 if (nhue == huePt(m_pos) && nsat == satPt(m_pos))
871 return;
872
873 setCol(colPt(nhue, nsat), false);
874}
875
876void QColorPicker::keyPressEvent(QKeyEvent *event)
877{
878 switch (event->key()) {
879 case Qt::Key_Down:
880 setCol(m_pos + QPoint(0, 1));
881 break;
882 case Qt::Key_Left:
883 setCol(m_pos + QPoint(-1, 0));
884 break;
885 case Qt::Key_Right:
886 setCol(m_pos + QPoint(1, 0));
887 break;
888 case Qt::Key_Up:
889 setCol(m_pos + QPoint(0, -1));
890 break;
891 default:
892 QFrame::keyPressEvent(event);
893 break;
894 }
895}
896
897void QColorPicker::mouseMoveEvent(QMouseEvent *m)
898{
899 QPoint p = m->position().toPoint() - contentsRect().topLeft();
900 if (m->buttons() == Qt::NoButton) {
901 m->ignore();
902 return;
903 }
904 setCol(p);
905}
906
907void QColorPicker::mousePressEvent(QMouseEvent *m)
908{
909 QPoint p = m->position().toPoint() - contentsRect().topLeft();
910 setCol(p);
911}
912
913void QColorPicker::paintEvent(QPaintEvent* )
914{
915 QPainter p(this);
916 drawFrame(&p);
917 QRect r = contentsRect();
918
919 p.drawPixmap(r.topLeft(), pix);
920
921 if (crossVisible) {
922 QPoint pt = m_pos + r.topLeft();
923 p.setPen(Qt::black);
924 p.fillRect(pt.x()-9, pt.y(), 20, 2, Qt::black);
925 p.fillRect(pt.x(), pt.y()-9, 2, 20, Qt::black);
926 }
927}
928
929void QColorPicker::resizeEvent(QResizeEvent *ev)
930{
931 QFrame::resizeEvent(ev);
932
933 pix = createColorsPixmap();
934
935 const QSize &oldSize = ev->oldSize();
936 if (!oldSize.isValid())
937 return;
938
939 // calculate hue/saturation based on previous widget size
940 // and update position accordingly
941 const int hue = huePt(m_pos, oldSize);
942 const int sat = satPt(m_pos, oldSize);
943 setCol(hue, sat);
944}
945
946QPixmap QColorPicker::createColorsPixmap()
947{
948 int w = width() - frameWidth() * 2;
949 int h = height() - frameWidth() * 2;
950 QImage img(w, h, QImage::Format_RGB32);
951 int x, y;
952 uint *pixel = (uint *) img.scanLine(0);
953 for (y = 0; y < h; y++) {
954 const uint *end = pixel + w;
955 x = 0;
956 while (pixel < end) {
957 QPoint p(x, y);
958 QColor c;
959 c.setHsv(huePt(p), satPt(p), 200);
960 *pixel = c.rgb();
961 ++pixel;
962 ++x;
963 }
964 }
965 return QPixmap::fromImage(img);
966}
967
968class QColSpinBox : public QSpinBox
969{
970public:
971 QColSpinBox(QWidget *parent)
972 : QSpinBox(parent) { setRange(0, 255); }
973 void setValue(int i) {
974 const QSignalBlocker blocker(this);
975 QSpinBox::setValue(i);
976 }
977};
978
979class QColorShowLabel;
980
981class QColorShower : public QWidget
982{
984public:
986
987 //things that don't emit signals
988 void setHsv(int h, int s, int v);
989
990 int currentAlpha() const
991 { return (colorDialog->options() & QColorDialog::ShowAlphaChannel) ? alphaEd->value() : 255; }
992 void setCurrentAlpha(int a) { alphaEd->setValue(a); rgbEd(); }
993 void showAlpha(bool b);
994 bool isAlphaVisible() const;
995
996 QRgb currentColor() const { return curCol; }
997 QColor currentQColor() const { return curQColor; }
1000
1001public slots:
1003
1004signals:
1006 void currentColorChanged(const QColor &color);
1007
1008private slots:
1009 void rgbEd();
1010 void hsvEd();
1011 void htmlEd();
1012
1013private:
1014 void showCurrentColor();
1015 int hue, sat, val;
1016 QRgb curCol;
1017 QColor curQColor;
1018 QLabel *lblHue;
1019 QLabel *lblSat;
1020 QLabel *lblVal;
1021 QLabel *lblRed;
1022 QLabel *lblGreen;
1023 QLabel *lblBlue;
1024 QLabel *lblHtml;
1025 QColSpinBox *hEd;
1026 QColSpinBox *sEd;
1027 QColSpinBox *vEd;
1028 QColSpinBox *rEd;
1029 QColSpinBox *gEd;
1030 QColSpinBox *bEd;
1031 QColSpinBox *alphaEd;
1032 QLabel *alphaLab;
1033 QLineEdit *htEd;
1034 QColorShowLabel *lab;
1035 bool rgbOriginal;
1036 QColorDialog *colorDialog;
1037 QGridLayout *gl;
1038
1041};
1042
1044{
1045 Q_OBJECT
1046
1047public:
1053 void setColor(QColor c) { col = c; }
1054
1055signals:
1057
1058protected:
1059 void paintEvent(QPaintEvent *) override;
1060 void mousePressEvent(QMouseEvent *e) override;
1061 void mouseMoveEvent(QMouseEvent *e) override;
1062 void mouseReleaseEvent(QMouseEvent *e) override;
1063#if QT_CONFIG(draganddrop)
1067#endif
1068
1069private:
1070 QColor col;
1071 bool mousePressed;
1072 QPoint pressPos;
1073};
1074
1075void QColorShowLabel::paintEvent(QPaintEvent *e)
1076{
1077 QPainter p(this);
1078 drawFrame(&p);
1079 p.fillRect(contentsRect()&e->rect(), col);
1080}
1081
1083{
1084 alphaLab->setVisible(b);
1085 alphaEd->setVisible(b);
1086}
1087
1088inline bool QColorShower::isAlphaVisible() const
1089{
1090 return alphaLab->isVisible();
1091}
1092
1094{
1095 mousePressed = true;
1096 pressPos = e->position().toPoint();
1097}
1098
1099void QColorShowLabel::mouseMoveEvent(QMouseEvent *e)
1100{
1101#if !QT_CONFIG(draganddrop)
1102 Q_UNUSED(e);
1103#else
1104 if (!mousePressed)
1105 return;
1106 if ((pressPos - e->position().toPoint()).manhattanLength() > QApplication::startDragDistance()) {
1107 QMimeData *mime = new QMimeData;
1108 mime->setColorData(col);
1109 QPixmap pix(30, 20);
1110 pix.fill(col);
1111 QPainter p(&pix);
1112 p.drawRect(0, 0, pix.width() - 1, pix.height() - 1);
1113 p.end();
1114 QDrag *drg = new QDrag(this);
1115 drg->setMimeData(mime);
1116 drg->setPixmap(pix);
1117 mousePressed = false;
1118 drg->exec(Qt::CopyAction);
1119 }
1120#endif
1121}
1122
1123#if QT_CONFIG(draganddrop)
1125{
1127 e->accept();
1128 else
1129 e->ignore();
1130}
1131
1133{
1134}
1135
1137{
1139 if (color.isValid()) {
1140 col = color;
1141 repaint();
1143 e->accept();
1144 } else {
1145 e->ignore();
1146 }
1147}
1148#endif // QT_CONFIG(draganddrop)
1149
1151{
1152 if (!mousePressed)
1153 return;
1154 mousePressed = false;
1155}
1156
1157QColorShower::QColorShower(QColorDialog *parent)
1158 : QWidget(parent)
1159{
1160 colorDialog = parent;
1161
1162 curCol = qRgb(255, 255, 255);
1163 curQColor = Qt::white;
1164
1165 gl = new QGridLayout(this);
1166 const int s = gl->spacing();
1167 gl->setContentsMargins(s, s, s, s);
1168 lab = new QColorShowLabel(this);
1169
1170#ifdef QT_SMALL_COLORDIALOG
1171 lab->setMinimumHeight(60);
1172#endif
1173 lab->setMinimumWidth(60);
1174
1175// For QVGA screens only the comboboxes and color label are visible.
1176// For nHD screens only color and luminence pickers and color label are visible.
1177#if !defined(QT_SMALL_COLORDIALOG)
1178 gl->addWidget(lab, 0, 0, -1, 1);
1179#else
1180 gl->addWidget(lab, 0, 0, 1, -1);
1181#endif
1182 connect(lab, &QColorShowLabel::colorDropped, this, &QColorShower::newCol);
1183 connect(lab, &QColorShowLabel::colorDropped, this, &QColorShower::setRgb);
1184
1185 hEd = new QColSpinBox(this);
1186 hEd->setRange(0, 359);
1187 lblHue = new QLabel(this);
1188#ifndef QT_NO_SHORTCUT
1189 lblHue->setBuddy(hEd);
1190#endif
1191 lblHue->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
1192#if !defined(QT_SMALL_COLORDIALOG)
1193 gl->addWidget(lblHue, 0, 1);
1194 gl->addWidget(hEd, 0, 2);
1195#else
1196 gl->addWidget(lblHue, 1, 0);
1197 gl->addWidget(hEd, 2, 0);
1198#endif
1199
1200 sEd = new QColSpinBox(this);
1201 lblSat = new QLabel(this);
1202#ifndef QT_NO_SHORTCUT
1203 lblSat->setBuddy(sEd);
1204#endif
1205 lblSat->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
1206#if !defined(QT_SMALL_COLORDIALOG)
1207 gl->addWidget(lblSat, 1, 1);
1208 gl->addWidget(sEd, 1, 2);
1209#else
1210 gl->addWidget(lblSat, 1, 1);
1211 gl->addWidget(sEd, 2, 1);
1212#endif
1213
1214 vEd = new QColSpinBox(this);
1215 lblVal = new QLabel(this);
1216#ifndef QT_NO_SHORTCUT
1217 lblVal->setBuddy(vEd);
1218#endif
1219 lblVal->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
1220#if !defined(QT_SMALL_COLORDIALOG)
1221 gl->addWidget(lblVal, 2, 1);
1222 gl->addWidget(vEd, 2, 2);
1223#else
1224 gl->addWidget(lblVal, 1, 2);
1225 gl->addWidget(vEd, 2, 2);
1226#endif
1227
1228 rEd = new QColSpinBox(this);
1229 lblRed = new QLabel(this);
1230#ifndef QT_NO_SHORTCUT
1231 lblRed->setBuddy(rEd);
1232#endif
1233 lblRed->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
1234#if !defined(QT_SMALL_COLORDIALOG)
1235 gl->addWidget(lblRed, 0, 3);
1236 gl->addWidget(rEd, 0, 4);
1237#else
1238 gl->addWidget(lblRed, 3, 0);
1239 gl->addWidget(rEd, 4, 0);
1240#endif
1241
1242 gEd = new QColSpinBox(this);
1243 lblGreen = new QLabel(this);
1244#ifndef QT_NO_SHORTCUT
1245 lblGreen->setBuddy(gEd);
1246#endif
1247 lblGreen->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
1248#if !defined(QT_SMALL_COLORDIALOG)
1249 gl->addWidget(lblGreen, 1, 3);
1250 gl->addWidget(gEd, 1, 4);
1251#else
1252 gl->addWidget(lblGreen, 3, 1);
1253 gl->addWidget(gEd, 4, 1);
1254#endif
1255
1256 bEd = new QColSpinBox(this);
1257 lblBlue = new QLabel(this);
1258#ifndef QT_NO_SHORTCUT
1259 lblBlue->setBuddy(bEd);
1260#endif
1261 lblBlue->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
1262#if !defined(QT_SMALL_COLORDIALOG)
1263 gl->addWidget(lblBlue, 2, 3);
1264 gl->addWidget(bEd, 2, 4);
1265#else
1266 gl->addWidget(lblBlue, 3, 2);
1267 gl->addWidget(bEd, 4, 2);
1268#endif
1269
1270 alphaEd = new QColSpinBox(this);
1271 alphaLab = new QLabel(this);
1272#ifndef QT_NO_SHORTCUT
1273 alphaLab->setBuddy(alphaEd);
1274#endif
1275 alphaLab->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
1276#if !defined(QT_SMALL_COLORDIALOG)
1277 gl->addWidget(alphaLab, 3, 1, 1, 3);
1278 gl->addWidget(alphaEd, 3, 4);
1279#else
1280 gl->addWidget(alphaLab, 1, 3, 3, 1);
1281 gl->addWidget(alphaEd, 4, 3);
1282#endif
1283 alphaEd->hide();
1284 alphaLab->hide();
1285 lblHtml = new QLabel(this);
1286 htEd = new QLineEdit(this);
1287 htEd->setObjectName("qt_colorname_lineedit");
1288#ifndef QT_NO_SHORTCUT
1289 lblHtml->setBuddy(htEd);
1290#endif
1291
1292#if QT_CONFIG(regularexpression)
1293 QRegularExpression regExp(QStringLiteral("#?([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})"));
1294 QRegularExpressionValidator *validator = new QRegularExpressionValidator(regExp, this);
1295 htEd->setValidator(validator);
1296#else
1297 htEd->setReadOnly(true);
1298#endif
1299 htEd->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed);
1300
1301 lblHtml->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
1302#if defined(QT_SMALL_COLORDIALOG)
1303 gl->addWidget(lblHtml, 5, 0);
1304 gl->addWidget(htEd, 5, 1, 1, /*colspan=*/ 2);
1305#else
1306 gl->addWidget(lblHtml, 5, 1);
1307 gl->addWidget(htEd, 5, 2, 1, /*colspan=*/ 3);
1308#endif
1309
1310 connect(hEd, &QSpinBox::valueChanged, this, &QColorShower::hsvEd);
1311 connect(sEd, &QSpinBox::valueChanged, this, &QColorShower::hsvEd);
1312 connect(vEd, &QSpinBox::valueChanged, this, &QColorShower::hsvEd);
1313
1314 connect(rEd, &QSpinBox::valueChanged, this, &QColorShower::rgbEd);
1315 connect(gEd, &QSpinBox::valueChanged, this, &QColorShower::rgbEd);
1316 connect(bEd, &QSpinBox::valueChanged, this, &QColorShower::rgbEd);
1317 connect(alphaEd, &QSpinBox::valueChanged, this, &QColorShower::rgbEd);
1318 connect(htEd, &QLineEdit::textEdited, this, &QColorShower::htmlEd);
1319
1321}
1322
1323} // namespace QtPrivate
1324
1325inline QRgb QColorDialogPrivate::currentColor() const { return cs->currentColor(); }
1330
1332{
1333 if (nativeDialogInUse)
1334 return platformColorDialogHelper()->currentColor();
1335 return cs->currentQColor();
1336}
1337
1338void QColorShower::showCurrentColor()
1339{
1340 lab->setColor(currentColor());
1341 lab->repaint();
1342}
1343
1344void QColorShower::rgbEd()
1345{
1346 rgbOriginal = true;
1347 curCol = qRgba(rEd->value(), gEd->value(), bEd->value(), currentAlpha());
1348
1349 rgb2hsv(currentColor(), hue, sat, val);
1350
1351 hEd->setValue(hue);
1352 sEd->setValue(sat);
1353 vEd->setValue(val);
1354
1355 htEd->setText(QColor(curCol).name());
1356
1357 showCurrentColor();
1358 emit newCol(currentColor());
1360}
1361
1362void QColorShower::hsvEd()
1363{
1364 rgbOriginal = false;
1365 hue = hEd->value();
1366 sat = sEd->value();
1367 val = vEd->value();
1368
1369 QColor c;
1370 c.setHsv(hue, sat, val);
1371 curCol = c.rgb();
1372
1373 rEd->setValue(qRed(currentColor()));
1374 gEd->setValue(qGreen(currentColor()));
1375 bEd->setValue(qBlue(currentColor()));
1376
1377 htEd->setText(c.name());
1378
1379 showCurrentColor();
1380 emit newCol(currentColor());
1382}
1383
1384void QColorShower::htmlEd()
1385{
1386 QString t = htEd->text();
1387 if (t.isEmpty())
1388 return;
1389
1390 if (!t.startsWith(u"#")) {
1391 t.prepend(u"#");
1392 QSignalBlocker blocker(htEd);
1393 htEd->setText(t);
1394 }
1395
1396 QColor c = QColor::fromString(t);
1397 if (!c.isValid())
1398 return;
1399
1400 curCol = qRgba(c.red(), c.green(), c.blue(), currentAlpha());
1401 rgb2hsv(curCol, hue, sat, val);
1402
1403 hEd->setValue(hue);
1404 sEd->setValue(sat);
1405 vEd->setValue(val);
1406
1407 rEd->setValue(qRed(currentColor()));
1408 gEd->setValue(qGreen(currentColor()));
1409 bEd->setValue(qBlue(currentColor()));
1410
1411 showCurrentColor();
1412 emit newCol(currentColor());
1414}
1415
1416void QColorShower::setRgb(QRgb rgb)
1417{
1418 rgbOriginal = true;
1419 curCol = rgb;
1420
1421 rgb2hsv(currentColor(), hue, sat, val);
1422
1423 hEd->setValue(hue);
1424 sEd->setValue(sat);
1425 vEd->setValue(val);
1426
1427 rEd->setValue(qRed(currentColor()));
1428 gEd->setValue(qGreen(currentColor()));
1429 bEd->setValue(qBlue(currentColor()));
1430
1431 htEd->setText(QColor(rgb).name());
1432
1433 showCurrentColor();
1435}
1436
1437void QColorShower::setHsv(int h, int s, int v)
1438{
1439 if (h < -1 || (uint)s > 255 || (uint)v > 255)
1440 return;
1441
1442 rgbOriginal = false;
1443 hue = h; val = v; sat = s;
1444 QColor c;
1445 c.setHsv(hue, sat, val);
1446 curCol = c.rgb();
1447
1448 hEd->setValue(hue);
1449 sEd->setValue(sat);
1450 vEd->setValue(val);
1451
1452 rEd->setValue(qRed(currentColor()));
1453 gEd->setValue(qGreen(currentColor()));
1454 bEd->setValue(qBlue(currentColor()));
1455
1456 htEd->setText(c.name());
1457
1458 showCurrentColor();
1460}
1461
1463{
1464 lblHue->setText(QColorDialog::tr("Hu&e:"));
1465 lblSat->setText(QColorDialog::tr("&Sat:"));
1466 lblVal->setText(QColorDialog::tr("&Val:"));
1467 lblRed->setText(QColorDialog::tr("&Red:"));
1468 lblGreen->setText(QColorDialog::tr("&Green:"));
1469 lblBlue->setText(QColorDialog::tr("Bl&ue:"));
1470 alphaLab->setText(QColorDialog::tr("A&lpha channel:"));
1471 lblHtml->setText(QColorDialog::tr("&HTML:"));
1472}
1473
1475{
1476 QColor oldQColor(curQColor);
1477 curQColor.setRgba(qRgba(qRed(curCol), qGreen(curCol), qBlue(curCol), currentAlpha()));
1478 if (curQColor != oldQColor)
1479 emit currentColorChanged(curQColor);
1480}
1481
1482//sets all widgets to display h,s,v
1483void QColorDialogPrivate::newHsv(int h, int s, int v)
1484{
1485 if (!nativeDialogInUse) {
1486 cs->setHsv(h, s, v);
1487 cp->setCol(h, s);
1488 lp->setCol(h, s, v);
1489 }
1490}
1491
1492//sets all widgets to display rgb
1494{
1495 if (!nativeDialogInUse) {
1496 cs->setRgb(rgb);
1497 newColorTypedIn(rgb);
1498 }
1499}
1500
1501// hack; doesn't keep curCol in sync, so use with care
1502void QColorDialogPrivate::setCurrentQColor(const QColor &color)
1503{
1504 Q_Q(QColorDialog);
1505 if (cs->curQColor != color) {
1506 cs->curQColor = color;
1507 emit q->currentColorChanged(color);
1508 }
1509}
1510
1511// size of standard and custom color selector
1512enum {
1516};
1517
1518bool QColorDialogPrivate::selectColor(const QColor &col)
1519{
1520 QRgb color = col.rgb();
1521 // Check standard colors
1522 if (standard) {
1523 const QRgb *standardColors = QColorDialogOptions::standardColors();
1524 const QRgb *standardColorsEnd = standardColors + standardColorRows * colorColumns;
1525 const QRgb *match = std::find(standardColors, standardColorsEnd, color);
1526 if (match != standardColorsEnd) {
1527 const int index = int(match - standardColors);
1528 const int column = index / standardColorRows;
1529 const int row = index % standardColorRows;
1530 newStandard(row, column);
1531 standard->setCurrent(row, column);
1532 standard->setSelected(row, column);
1533 standard->setFocus();
1534 return true;
1535 }
1536 }
1537 // Check custom colors
1538 if (custom) {
1539 const QRgb *customColors = QColorDialogOptions::customColors();
1540 const QRgb *customColorsEnd = customColors + customColorRows * colorColumns;
1541 const QRgb *match = std::find(customColors, customColorsEnd, color);
1542 if (match != customColorsEnd) {
1543 const int index = int(match - customColors);
1544 const int column = index / customColorRows;
1545 const int row = index % customColorRows;
1546 newCustom(row, column);
1547 custom->setCurrent(row, column);
1548 custom->setSelected(row, column);
1549 custom->setFocus();
1550 return true;
1551 }
1552 }
1553 return false;
1554}
1555
1557{
1558 QScreen *screen = QGuiApplication::screenAt(p);
1559 if (!screen)
1560 screen = QGuiApplication::primaryScreen();
1561 const QRect screenRect = screen->geometry();
1562 const QPixmap pixmap =
1563 screen->grabWindow(0, p.x() - screenRect.x(), p.y() - screenRect.y(), 1, 1);
1564 const QImage i = pixmap.toImage();
1565 return i.pixel(0, 0);
1566}
1567
1568//sets all widgets except cs to display rgb
1570{
1571 if (!nativeDialogInUse) {
1572 int h, s, v;
1573 rgb2hsv(rgb, h, s, v);
1574 cp->setCol(h, s);
1575 lp->setCol(h, s, v);
1576 }
1577}
1578
1580{
1581 nextCust = r + customColorRows * c;
1582}
1583
1585{
1586 const int i = r + customColorRows * c;
1587 setCurrentRgbColor(QColorDialogOptions::customColor(i));
1588 if (standard)
1589 standard->setSelected(-1,-1);
1590}
1591
1593{
1594 setCurrentRgbColor(QColorDialogOptions::standardColor(r + c * 6));
1595 if (custom)
1596 custom->setSelected(-1,-1);
1597}
1598
1600{
1601 Q_Q(QColorDialog);
1602
1603 auto *platformServices = QGuiApplicationPrivate::platformIntegration()->services();
1604 if (platformServices && platformServices->hasCapability(QPlatformServices::Capability::ColorPicking)) {
1605 if (auto *colorPicker = platformServices->colorPicker(q->windowHandle())) {
1606 q->connect(colorPicker, &QPlatformServiceColorPicker::colorPicked, q,
1607 [q, colorPicker](const QColor &color) {
1608 colorPicker->deleteLater();
1609 q->setCurrentColor(color);
1610 });
1611 colorPicker->pickColor();
1612 return;
1613 }
1614 }
1615
1616 if (!colorPickingEventFilter)
1617 colorPickingEventFilter = new QColorPickingEventFilter(this, q);
1618 q->installEventFilter(colorPickingEventFilter);
1619 QObject::connect(qApp, &QGuiApplication::applicationStateChanged,
1620 colorPickingEventFilter, &QColorPickingEventFilter::applicationStateChanged);
1621 // If user pushes Escape, the last color before picking will be restored.
1622 beforeScreenColorPicking = cs->currentColor();
1623#ifndef QT_NO_CURSOR
1624 q->grabMouse(Qt::CrossCursor);
1625#else
1626 q->grabMouse();
1627#endif
1628
1629#ifdef Q_OS_WIN32
1630 // On Windows mouse tracking doesn't work over other processes's windows
1631 updateTimer->start(30);
1632
1633 // HACK: Because mouse grabbing doesn't work across processes, we have to have a dummy,
1634 // invisible window to catch the mouse click, otherwise we will click whatever we clicked
1635 // and loose focus.
1636 dummyTransparentWindow.show();
1637#endif
1638 q->grabKeyboard();
1639 /* With setMouseTracking(true) the desired color can be more precisely picked up,
1640 * and continuously pushing the mouse button is not necessary.
1641 */
1642 q->setMouseTracking(true);
1643
1644 addCusBt->setDisabled(true);
1645 buttons->setDisabled(true);
1646 if (eyeDropperButton) {
1647 eyeDropperButton->setDisabled(true);
1648 const QPoint globalPos = QCursor::pos();
1649 q->setCurrentColor(grabScreenColor(globalPos));
1650 updateColorLabelText(globalPos);
1651 }
1652}
1653
1655{
1656 if (!lblScreenColorInfo)
1657 return;
1658#ifdef Q_OS_OHOS
1659 Q_UNUSED(globalPos)
1660 lblScreenColorInfo->setText(QColorDialog::tr("Cursor at %1, %2\nPress ESC to cancel")
1661 .arg(QStringLiteral("-"))
1662 .arg(QStringLiteral("-")));
1663#else
1664 lblScreenColorInfo->setText(QColorDialog::tr("Cursor at %1, %2\nPress ESC to cancel")
1665 .arg(globalPos.x())
1666 .arg(globalPos.y()));
1667#endif
1668}
1669
1671{
1672 Q_Q(QColorDialog);
1674 q->removeEventFilter(colorPickingEventFilter);
1675 QObject::disconnect(qApp, &QGuiApplication::applicationStateChanged,
1676 colorPickingEventFilter, &QColorPickingEventFilter::applicationStateChanged);
1677 q->releaseMouse();
1678#ifdef Q_OS_WIN32
1679 updateTimer->stop();
1680 dummyTransparentWindow.setVisible(false);
1681#endif
1682 q->releaseKeyboard();
1683 q->setMouseTracking(false);
1684 lblScreenColorInfo->setText("\n"_L1);
1685 addCusBt->setDisabled(false);
1686 buttons->setDisabled(false);
1687 eyeDropperButton->setDisabled(false);
1688}
1689
1690void QColorDialogPrivate::init(const QColor &initial)
1691{
1692 Q_Q(QColorDialog);
1693
1694 q->setSizeGripEnabled(false);
1695 q->setWindowTitle(QColorDialog::tr("Select Color"));
1696
1697 // default: use the native dialog if possible. Can be overridden in setOptions()
1698 nativeDialogInUse = (platformColorDialogHelper() != nullptr);
1699 colorPickingEventFilter = nullptr;
1700 nextCust = 0;
1701
1702 if (!nativeDialogInUse)
1704
1705#ifdef Q_OS_WIN32
1706 dummyTransparentWindow.resize(1, 1);
1707 dummyTransparentWindow.setFlags(Qt::Tool | Qt::FramelessWindowHint);
1708#endif
1709
1710 q->setCurrentColor(initial);
1711}
1712
1714{
1715 Q_Q(QColorDialog);
1716 QVBoxLayout *mainLay = new QVBoxLayout(q);
1717 // there's nothing in this dialog that benefits from sizing up
1718 mainLay->setSizeConstraint(QLayout::SetFixedSize);
1719
1720 QHBoxLayout *topLay = new QHBoxLayout();
1721 mainLay->addLayout(topLay);
1722
1723 leftLay = nullptr;
1724
1725#if defined(QT_SMALL_COLORDIALOG)
1726 smallDisplay = true;
1727 const int lumSpace = 20;
1728#else
1729 // small displays (e.g. PDAs) cannot fit the full color dialog,
1730 // so just use the color picker.
1731 smallDisplay = (QGuiApplication::primaryScreen()->virtualGeometry().width() < 480 || QGuiApplication::primaryScreen()->virtualGeometry().height() < 350);
1732 const int lumSpace = topLay->spacing() / 2;
1733#endif
1734
1735 if (!smallDisplay) {
1736 leftLay = new QVBoxLayout;
1737 topLay->addLayout(leftLay);
1738
1739 standard = new QColorWell(q, standardColorRows, colorColumns, QColorDialogOptions::standardColors());
1740 lblBasicColors = new QLabel(q);
1741#ifndef QT_NO_SHORTCUT
1742 lblBasicColors->setBuddy(standard);
1743#endif
1744 QObjectPrivate::connect(standard, &QColorWell::selected,
1745 this, &QColorDialogPrivate::newStandard);
1746 leftLay->addWidget(lblBasicColors);
1747 leftLay->addWidget(standard);
1748
1749#if !defined(QT_SMALL_COLORDIALOG)
1751 eyeDropperButton = new QPushButton();
1752 leftLay->addWidget(eyeDropperButton);
1753 lblScreenColorInfo = new QLabel("\n"_L1);
1754 leftLay->addWidget(lblScreenColorInfo);
1755 QObjectPrivate::connect(eyeDropperButton, &QPushButton::clicked,
1756 this, &QColorDialogPrivate::pickScreenColor);
1757 } else {
1758 eyeDropperButton = nullptr;
1759 lblScreenColorInfo = nullptr;
1760 }
1761#endif
1762
1763 leftLay->addStretch();
1764
1765 custom = new QColorWell(q, customColorRows, colorColumns, QColorDialogOptions::customColors());
1766 custom->setAcceptDrops(true);
1767
1768 QObjectPrivate::connect(custom, &QColorWell::selected, this, &QColorDialogPrivate::newCustom);
1769 QObjectPrivate::connect(custom, &QColorWell::currentChanged, this, &QColorDialogPrivate::nextCustom);
1770
1771 QObject::connect(custom, &QWellArray::colorChanged, q, [this] (int index, QRgb color) {
1772 QColorDialogOptions::setCustomColor(index, color);
1773 if (custom)
1774 custom->update();
1775 });
1776
1777 lblCustomColors = new QLabel(q);
1778#ifndef QT_NO_SHORTCUT
1779 lblCustomColors->setBuddy(custom);
1780#endif
1781 leftLay->addWidget(lblCustomColors);
1782 leftLay->addWidget(custom);
1783
1784 addCusBt = new QPushButton(q);
1785 QObjectPrivate::connect(addCusBt, &QPushButton::clicked, this, &QColorDialogPrivate::addCustom);
1786 leftLay->addWidget(addCusBt);
1787 } else {
1788 // better color picker size for small displays
1789#if defined(QT_SMALL_COLORDIALOG)
1790 QSize screenSize = QGuiApplication::screenAt(QCursor::pos())->availableGeometry().size();
1791 pWidth = pHeight = qMin(screenSize.width(), screenSize.height());
1792 pHeight -= 20;
1793 if (screenSize.height() > screenSize.width())
1794 pWidth -= 20;
1795#else
1796 pWidth = 150;
1797 pHeight = 100;
1798#endif
1799 custom = nullptr;
1800 standard = nullptr;
1801 }
1802
1803 QVBoxLayout *rightLay = new QVBoxLayout;
1804 topLay->addLayout(rightLay);
1805
1806 QHBoxLayout *pickLay = new QHBoxLayout;
1807 rightLay->addLayout(pickLay);
1808
1809 QVBoxLayout *cLay = new QVBoxLayout;
1810 pickLay->addLayout(cLay);
1811 cp = new QColorPicker(q);
1812
1813 cp->setFrameStyle(QFrame::Panel | QFrame::Sunken);
1814
1815#if defined(QT_SMALL_COLORDIALOG)
1816 cp->hide();
1817#else
1818 cLay->addSpacing(lumSpace);
1819 cLay->addWidget(cp);
1820#endif
1821 cLay->addSpacing(lumSpace);
1822
1823 lp = new QColorLuminancePicker(q);
1824#if defined(QT_SMALL_COLORDIALOG)
1825 lp->hide();
1826#else
1827 lp->setFixedWidth(20);
1828 pickLay->addSpacing(10);
1829 pickLay->addWidget(lp);
1830 pickLay->addStretch();
1831#endif
1832
1833 QObject::connect(cp, &QColorPicker::newCol, lp, qOverload<int, int>(&QColorLuminancePicker::setCol));
1834 QObjectPrivate::connect(lp, &QColorLuminancePicker::newHsv, this, &QColorDialogPrivate::newHsv);
1835
1836 rightLay->addStretch();
1837
1838 cs = new QColorShower(q);
1839 pickLay->setContentsMargins(cs->gl->contentsMargins());
1840 QObjectPrivate::connect(cs, &QColorShower::newCol,
1841 this, &QColorDialogPrivate::newColorTypedIn);
1842 QObject::connect(cs, &QColorShower::currentColorChanged,
1843 q, &QColorDialog::currentColorChanged);
1844#if defined(QT_SMALL_COLORDIALOG)
1845 topLay->addWidget(cs);
1846#else
1847 rightLay->addWidget(cs);
1848 if (leftLay)
1849 leftLay->addSpacing(cs->gl->contentsMargins().right());
1850#endif
1851
1852 buttons = new QDialogButtonBox(q);
1853 mainLay->addWidget(buttons);
1854
1855 ok = buttons->addButton(QDialogButtonBox::Ok);
1856 QObject::connect(ok, &QPushButton::clicked, q, &QColorDialog::accept);
1857 ok->setDefault(true);
1858 cancel = buttons->addButton(QDialogButtonBox::Cancel);
1859 QObject::connect(cancel, &QPushButton::clicked, q, &QColorDialog::reject);
1860
1861#ifdef Q_OS_WIN32
1862 updateTimer = new QTimer(q);
1863 QObjectPrivate::connect(updateTimer, &QTimer::timeout,
1864 this, qOverload<>(&QColorDialogPrivate::updateColorPicking));
1865#endif
1867}
1868
1869void QColorDialogPrivate::initHelper(QPlatformDialogHelper *h)
1870{
1871 QColorDialog *d = q_func();
1872 auto *colorDialogHelper = static_cast<QPlatformColorDialogHelper*>(h);
1873 QObject::connect(colorDialogHelper, &QPlatformColorDialogHelper::currentColorChanged,
1874 d, &QColorDialog::currentColorChanged);
1875 QObject::connect(colorDialogHelper, &QPlatformColorDialogHelper::colorSelected,
1876 d, &QColorDialog::colorSelected);
1877 colorDialogHelper->setOptions(options);
1878}
1879
1880void QColorDialogPrivate::helperPrepareShow(QPlatformDialogHelper *)
1881{
1882 options->setWindowTitle(q_func()->windowTitle());
1883}
1884
1886{
1887 QColorDialogOptions::setCustomColor(nextCust, cs->currentColor());
1888 if (custom)
1889 custom->update();
1890 nextCust = (nextCust+1) % QColorDialogOptions::customColorCount();
1891}
1892
1894{
1895 if (nativeDialogInUse)
1896 return;
1897
1898 if (!smallDisplay) {
1899 lblBasicColors->setText(QColorDialog::tr("&Basic colors"));
1900 lblCustomColors->setText(QColorDialog::tr("&Custom colors"));
1901 addCusBt->setText(QColorDialog::tr("&Add to Custom Colors"));
1902#if !defined(QT_SMALL_COLORDIALOG)
1903 if (eyeDropperButton)
1904 eyeDropperButton->setText(QColorDialog::tr("&Pick Screen Color"));
1905#endif
1906 }
1907
1909}
1910
1912{
1913 const auto integration = QGuiApplicationPrivate::platformIntegration();
1914 return integration->hasCapability(QPlatformIntegration::ScreenWindowGrabbing)
1915 || integration->services()->hasCapability(QPlatformServices::Capability::ColorPicking);
1916}
1917
1919{
1920 // Don't use Q_Q here! This function is called from ~QDialog,
1921 // so Q_Q calling q_func() invokes undefined behavior (invalid cast in q_func()).
1922 const QDialog * const q = static_cast<const QDialog*>(q_ptr);
1923 if (nativeDialogInUse)
1924 return true;
1925 if (QCoreApplication::testAttribute(Qt::AA_DontUseNativeDialogs)
1926 || q->testAttribute(Qt::WA_DontShowOnScreen)
1927 || (options->options() & QColorDialog::DontUseNativeDialog)) {
1928 return false;
1929 }
1930
1931 return strcmp(QColorDialog::staticMetaObject.className(), q->metaObject()->className()) == 0;
1932}
1933
1935 Qt::Dialog | Qt::WindowTitleHint
1936 | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint;
1937
1938/*!
1939 \class QColorDialog
1940 \brief The QColorDialog class provides a dialog widget for specifying colors.
1941
1942 \ingroup standard-dialogs
1943 \inmodule QtWidgets
1944
1945 The color dialog's function is to allow users to choose colors.
1946 For example, you might use this in a drawing program to allow the
1947 user to set the brush color.
1948
1949 The static functions provide modal color dialogs.
1950 \omit
1951 If you require a modeless dialog, use the QColorDialog constructor.
1952 \endomit
1953
1954 The static getColor() function shows the dialog, and allows the user to
1955 specify a color. This function can also be used to let users choose a
1956 color with a level of transparency: pass the ShowAlphaChannel option as
1957 an additional argument.
1958
1959 The user can store customCount() different custom colors. The
1960 custom colors are shared by all color dialogs, and remembered
1961 during the execution of the program. Use setCustomColor() to set
1962 the custom colors, and use customColor() to get them.
1963
1964 When pressing the "Pick Screen Color" button, the cursor changes to a haircross
1965 and the colors on the screen are scanned. The user can pick up one by clicking
1966 the mouse or the Enter button. Pressing Escape restores the last color selected
1967 before entering this mode.
1968
1969 The \l{dialogs/standarddialogs}{Standard Dialogs} example shows
1970 how to use QColorDialog as well as other built-in Qt dialogs.
1971
1972 \image fusion-colordialog.png A color dialog in the Fusion widget style.
1973
1974 \sa QColor, QFileDialog, QFontDialog, {Standard Dialogs Example}
1975*/
1976
1977/*!
1978 Constructs a color dialog with the given \a parent.
1979*/
1980QColorDialog::QColorDialog(QWidget *parent)
1981 : QColorDialog(QColor(Qt::white), parent)
1982{
1983 new QColorPolishFilter(this);
1984}
1985
1986/*!
1987 Constructs a color dialog with the given \a parent and specified
1988 \a initial color.
1989*/
1990QColorDialog::QColorDialog(const QColor &initial, QWidget *parent)
1991 : QDialog(*new QColorDialogPrivate, parent, qcd_DefaultWindowFlags)
1992{
1993 Q_D(QColorDialog);
1994 new QColorPolishFilter(this);
1995 d->init(initial);
1996}
1997
1998void QColorDialogPrivate::setCurrentColor(const QColor &color, SetColorMode setColorMode)
1999{
2000 if (nativeDialogInUse) {
2001 platformColorDialogHelper()->setCurrentColor(color);
2002 return;
2003 }
2004
2005 if (setColorMode & ShowColor) {
2006 setCurrentRgbColor(color.rgb());
2007 setCurrentAlpha(color.alpha());
2008 }
2009 if (setColorMode & SelectColor)
2010 selectColor(color);
2011}
2012
2013/*!
2014 \property QColorDialog::currentColor
2015 \brief the currently selected color in the dialog
2016*/
2017
2018void QColorDialog::setCurrentColor(const QColor &color)
2019{
2020 Q_D(QColorDialog);
2021 d->setCurrentColor(color);
2022}
2023
2024QColor QColorDialog::currentColor() const
2025{
2026 Q_D(const QColorDialog);
2027 return d->currentQColor();
2028}
2029
2030/*!
2031 Returns the color that the user selected by clicking the \uicontrol{OK}
2032 or equivalent button.
2033
2034 \note This color is not always the same as the color held by the
2035 \l currentColor property since the user can choose different colors
2036 before finally selecting the one to use.
2037*/
2038QColor QColorDialog::selectedColor() const
2039{
2040 Q_D(const QColorDialog);
2041 return d->selectedQColor;
2042}
2043
2044/*!
2045 Sets the given \a option to be enabled if \a on is true;
2046 otherwise, clears the given \a option.
2047
2048 \sa options, testOption()
2049*/
2050void QColorDialog::setOption(ColorDialogOption option, bool on)
2051{
2052 Q_D(QColorDialog);
2053 d->optionsExplicitlySet = true;
2054
2055 const QColorDialog::ColorDialogOptions previousOptions = options();
2056 if (!(previousOptions & option) != !on)
2057 setOptions(previousOptions ^ option);
2058}
2059
2060/*!
2061 Returns \c true if the given \a option is enabled; otherwise, returns
2062 false.
2063
2064 \sa options, setOption()
2065*/
2066bool QColorDialog::testOption(ColorDialogOption option) const
2067{
2068 Q_D(const QColorDialog);
2069 return d->options->testOption(static_cast<QColorDialogOptions::ColorDialogOption>(option));
2070}
2071
2072/*!
2073 \property QColorDialog::options
2074 \brief the various options that affect the look and feel of the dialog
2075
2076 By default, all options are disabled.
2077
2078 Options should be set before showing the dialog. Setting them while the
2079 dialog is visible is not guaranteed to have an immediate effect on the
2080 dialog (depending on the option and on the platform).
2081
2082 \sa setOption(), testOption()
2083*/
2084void QColorDialog::setOptions(ColorDialogOptions options)
2085{
2086 Q_D(QColorDialog);
2087 d->optionsExplicitlySet = true;
2088
2089 if (QColorDialog::options() == options)
2090 return;
2091
2092 d->options->setOptions(QColorDialogOptions::ColorDialogOptions(int(options)));
2093 if ((options & DontUseNativeDialog) && d->nativeDialogInUse) {
2094 d->nativeDialogInUse = false;
2095 d->initWidgets();
2096 }
2097 if (!d->nativeDialogInUse) {
2098 d->buttons->setVisible(!(options & NoButtons));
2099 d->showAlpha(options & ShowAlphaChannel);
2100 if (d->eyeDropperButton)
2101 d->eyeDropperButton->setVisible(!(options & NoEyeDropperButton));
2102 }
2103}
2104
2105QColorDialog::ColorDialogOptions QColorDialog::options() const
2106{
2107 Q_D(const QColorDialog);
2108 return QColorDialog::ColorDialogOptions(int(d->options->options()));
2109}
2110
2111/*!
2112 \enum QColorDialog::ColorDialogOption
2113
2114 This enum specifies various options that affect the look and feel
2115 of a color dialog.
2116
2117 \value ShowAlphaChannel Allow the user to select the alpha component of a color.
2118 \value NoButtons Don't display \uicontrol{OK} and \uicontrol{Cancel} buttons. (Useful for "live dialogs".)
2119 \value NoEyeDropperButton Hide the \uicontrol{Eye Dropper} button. This value was added in Qt 6.6.
2120 \value DontUseNativeDialog Use Qt's standard color dialog instead of the operating system
2121 native color dialog.
2122
2123 \sa options, setOption(), testOption(), windowModality()
2124*/
2125
2126/*!
2127 \fn void QColorDialog::currentColorChanged(const QColor &color)
2128
2129 This signal is emitted whenever the current color changes in the dialog.
2130 The current color is specified by \a color.
2131
2132 \sa color, colorSelected()
2133*/
2134
2135/*!
2136 \fn void QColorDialog::colorSelected(const QColor &color);
2137
2138 This signal is emitted just after the user has clicked \uicontrol{OK} to
2139 select a color to use. The chosen color is specified by \a color.
2140
2141 \sa color, currentColorChanged()
2142*/
2143
2144/*!
2145 Changes the visibility of the dialog. If \a visible is true, the dialog
2146 is shown; otherwise, it is hidden.
2147*/
2148void QColorDialog::setVisible(bool visible)
2149{
2150 // will call QColorDialogPrivate::setVisible override
2151 QDialog::setVisible(visible);
2152}
2153
2154/*!
2155 \internal
2156
2157 The implementation of QColorDialog::setVisible() has to live here so that the call
2158 to hide() in ~QDialog calls this function; it wouldn't call the override of
2159 QDialog::setVisible().
2160*/
2162{
2163 // Don't use Q_Q here! This function is called from ~QDialog,
2164 // so Q_Q calling q_func() invokes undefined behavior (invalid cast in q_func()).
2165 const auto q = static_cast<QDialog *>(q_ptr);
2166
2167 if (visible)
2168 selectedQColor = QColor();
2169
2170 if (nativeDialogInUse) {
2171 if (setNativeDialogVisible(visible)) {
2172 // Set WA_DontShowOnScreen so that QDialog::setVisible(visible) below
2173 // updates the state correctly, but skips showing the non-native version:
2174 q->setAttribute(Qt::WA_DontShowOnScreen);
2175 } else if (visible) {
2177 }
2178 } else {
2179 q->setAttribute(Qt::WA_DontShowOnScreen, false);
2180 }
2181
2182 QDialogPrivate::setVisible(visible);
2183}
2184
2185/*!
2186 Opens the dialog and connects its colorSelected() signal to the slot specified
2187 by \a receiver and \a member.
2188
2189 The signal will be disconnected from the slot when the dialog is closed.
2190*/
2191void QColorDialog::open(QObject *receiver, const char *member)
2192{
2193 Q_D(QColorDialog);
2194 connect(this, SIGNAL(colorSelected(QColor)), receiver, member);
2195 d->receiverToDisconnectOnClose = receiver;
2196 d->memberToDisconnectOnClose = member;
2197 QDialog::open();
2198}
2199
2200/*!
2201 Pops up a modal color dialog with the given window \a title (or "Select Color" if none is
2202 specified), lets the user choose a color, and returns that color. The color is initially set
2203 to \a initial. The dialog is a child of \a parent. It returns an invalid (see
2204 QColor::isValid()) color if the user cancels the dialog.
2205
2206 The \a options argument allows you to customize the dialog.
2207*/
2208QColor QColorDialog::getColor(const QColor &initial, QWidget *parent, const QString &title,
2209 ColorDialogOptions options)
2210{
2211 QAutoPointer<QColorDialog> dlg(new QColorDialog(parent));
2212 if (!title.isEmpty())
2213 dlg->setWindowTitle(title);
2214 dlg->setOptions(options);
2215 dlg->setCurrentColor(initial);
2216
2217 // If the dlg was deleted with a parent window,
2218 // dlg == nullptr after leaving the exec().
2219 dlg->exec();
2220 if (bool(dlg))
2221 return dlg->selectedColor();
2222 else
2223 return QColor();
2224}
2225
2226/*!
2227 Destroys the color dialog.
2228*/
2229
2230QColorDialog::~QColorDialog()
2231{
2232}
2233
2234/*!
2235 \reimp
2236*/
2237void QColorDialog::changeEvent(QEvent *e)
2238{
2239 Q_D(QColorDialog);
2240 if (e->type() == QEvent::LanguageChange)
2241 d->retranslateStrings();
2242 QDialog::changeEvent(e);
2243}
2244
2246{
2247#ifndef QT_NO_CURSOR
2248 Q_Q(QColorDialog);
2249 static QPoint lastGlobalPos;
2250 QPoint newGlobalPos = QCursor::pos();
2251 if (lastGlobalPos == newGlobalPos)
2252 return;
2253 lastGlobalPos = newGlobalPos;
2254
2255 if (!q->rect().contains(q->mapFromGlobal(newGlobalPos))) { // Inside the dialog mouse tracking works, handleColorPickingMouseMove will be called
2256 updateColorPicking(newGlobalPos);
2257#ifdef Q_OS_WIN32
2258 dummyTransparentWindow.setPosition(newGlobalPos);
2259#endif
2260 }
2261#endif // ! QT_NO_CURSOR
2262}
2263
2265{
2266 const QColor color = grabScreenColor(globalPos);
2267 // QTBUG-39792, do not change standard, custom color selectors while moving as
2268 // otherwise it is not possible to pre-select a custom cell for assignment.
2269 setCurrentColor(color, ShowColor);
2270 updateColorLabelText(globalPos);
2271}
2272
2274{
2275 // If the cross is visible the grabbed color will be black most of the times
2276 cp->setCrossVisible(!cp->geometry().contains(e->position().toPoint()));
2277
2278 updateColorPicking(e->globalPosition().toPoint());
2279 return true;
2280}
2281
2283{
2284 setCurrentColor(grabScreenColor(e->globalPosition().toPoint()), SetColorAll);
2286 return true;
2287}
2288
2290{
2291 Q_Q(QColorDialog);
2292#if QT_CONFIG(shortcut)
2293 if (e->matches(QKeySequence::Cancel)) {
2294 releaseColorPicking();
2295 q->setCurrentColor(beforeScreenColorPicking);
2296 } else
2297#endif
2298 if (e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter) {
2299 q->setCurrentColor(grabScreenColor(QCursor::pos()));
2301 }
2302 e->accept();
2303 return true;
2304}
2305
2306/*!
2307 Closes the dialog and sets its result code to \a result. If this dialog
2308 is shown with exec(), done() causes the local event loop to finish,
2309 and exec() to return \a result.
2310
2311 \sa QDialog::done()
2312*/
2313void QColorDialog::done(int result)
2314{
2315 Q_D(QColorDialog);
2316 if (result == Accepted) {
2317 d->selectedQColor = d->currentQColor();
2318 emit colorSelected(d->selectedQColor);
2319 } else {
2320 d->selectedQColor = QColor();
2321 }
2322 QDialog::done(result);
2323 if (d->receiverToDisconnectOnClose) {
2324 disconnect(this, SIGNAL(colorSelected(QColor)),
2325 d->receiverToDisconnectOnClose, d->memberToDisconnectOnClose);
2326 d->receiverToDisconnectOnClose = nullptr;
2327 }
2328 d->memberToDisconnectOnClose.clear();
2329}
2330
2331QT_END_NAMESPACE
2332
2333#include "qcolordialog.moc"
2334#include "moc_qcolordialog.cpp"
QColor grabScreenColor(const QPoint &p)
bool selectColor(const QColor &color)
void init(const QColor &initial)
void setCurrentAlpha(int a)
QColorPickingEventFilter * colorPickingEventFilter
bool handleColorPickingMouseButtonRelease(QMouseEvent *e)
QColor currentQColor() const
bool handleColorPickingMouseMove(QMouseEvent *e)
void _q_setCustom(int index, QRgb color)
QPushButton * eyeDropperButton
void updateColorLabelText(const QPoint &)
void setCurrentColor(const QColor &color, SetColorMode setColorMode=SetColorAll)
bool isAlphaVisible() const
QVBoxLayout * leftLay
void setCurrentQColor(const QColor &color)
bool canBeNativeDialog() const override
void setCurrentRgbColor(QRgb rgb)
QRgb currentColor() const
void newColorTypedIn(QRgb rgb)
bool handleColorPickingKeyPress(QKeyEvent *e)
void updateColorPicking(const QPoint &pos)
QSharedPointer< QColorDialogOptions > options
void newStandard(int, int)
void setVisible(bool visible) override
QDialogButtonBox * buttons
bool supportsColorPicking() const
QPointer< QObject > receiverToDisconnectOnClose
virtual void initHelper(QPlatformDialogHelper *h) override
QByteArray memberToDisconnectOnClose
QPushButton * addCusBt
void newHsv(int h, int s, int v)
virtual void helperPrepareShow(QPlatformDialogHelper *h) override
QColorLuminancePicker * lp
void newCustom(int, int)
QPlatformColorDialogHelper * platformColorDialogHelper() const
void nextCustom(int, int)
bool eventFilter(QObject *obj, QEvent *event) override
Filters events if this object has been installed as an event filter for the watched object.
QColorPolishFilter(QColorDialog *cd)
friend class QPainter
\inmodule QtCore\reentrant
Definition qpoint.h:30
QColSpinBox(QWidget *parent)
void paintEvent(QPaintEvent *) override
This event handler can be reimplemented in a subclass to receive paint events passed in event.
void keyPressEvent(QKeyEvent *event) override
This event handler, for event event, can be reimplemented in a subclass to receive key press events f...
void mouseMoveEvent(QMouseEvent *) override
This event handler, for event event, can be reimplemented in a subclass to receive mouse move events ...
void mousePressEvent(QMouseEvent *) override
This event handler, for event event, can be reimplemented in a subclass to receive mouse press events...
void paintEvent(QPaintEvent *) override
This event handler can be reimplemented in a subclass to receive paint events passed in event.
void mouseMoveEvent(QMouseEvent *) override
This event handler, for event event, can be reimplemented in a subclass to receive mouse move events ...
QSize sizeHint() const override
void setCrossVisible(bool visible)
void resizeEvent(QResizeEvent *) override
This event handler can be reimplemented in a subclass to receive widget resize events which are passe...
void mousePressEvent(QMouseEvent *) override
This event handler, for event event, can be reimplemented in a subclass to receive mouse press events...
void keyPressEvent(QKeyEvent *event) override
This event handler, for event event, can be reimplemented in a subclass to receive key press events f...
bool eventFilter(QObject *, QEvent *event) override
Filters events if this object has been installed as an event filter for the watched object.
void applicationStateChanged(Qt::ApplicationState state)
QColorPickingEventFilter(QColorDialogPrivate *dp, QObject *parent)
void mouseReleaseEvent(QMouseEvent *e) override
This event handler, for event event, can be reimplemented in a subclass to receive mouse release even...
void mousePressEvent(QMouseEvent *e) override
This event handler, for event event, can be reimplemented in a subclass to receive mouse press events...
void mouseMoveEvent(QMouseEvent *e) override
This event handler, for event event, can be reimplemented in a subclass to receive mouse move events ...
void paintEvent(QPaintEvent *) override
This event handler can be reimplemented in a subclass to receive paint events passed in event.
QColor currentQColor() const
void setHsv(int h, int s, int v)
void currentColorChanged(const QColor &color)
friend class QT_PREPEND_NAMESPACE(QUntypedBindable)
QtPrivate::QColorShower QColorShower
static void rgb2hsv(QRgb rgb, int &h, int &s, int &v)
static int pHeight
static int pWidth
QtPrivate::QColorPickingEventFilter QColorPickingEventFilter
QtPrivate::QColorLuminancePicker QColorLuminancePicker
QtPrivate::QColorPicker QColorPicker
static const Qt::WindowFlags qcd_DefaultWindowFlags
@ colorColumns
@ standardColorRows
@ customColorRows
#define qApp