If the file is open, there must be an engine.
[qt-netbsd.git] / src / gui / dialogs / qcolordialog.cpp
blobe9031acf7a88273cb4201430baf9a3267b11686e
1 /****************************************************************************
2 **
3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the QtGui module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
14 ** this package.
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file. Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights. These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
38 ** $QT_END_LICENSE$
40 ****************************************************************************/
42 #include "qcolordialog_p.h"
44 #ifndef QT_NO_COLORDIALOG
46 #include "qapplication.h"
47 #include "qdesktopwidget.h"
48 #include "qdrawutil.h"
49 #include "qevent.h"
50 #include "qimage.h"
51 #include "qlabel.h"
52 #include "qlayout.h"
53 #include "qlineedit.h"
54 #include "qmenu.h"
55 #include "qpainter.h"
56 #include "qpixmap.h"
57 #include "qpushbutton.h"
58 #include "qsettings.h"
59 #include "qstyle.h"
60 #include "qstyleoption.h"
61 #include "qvalidator.h"
62 #include "qmime.h"
63 #include "qspinbox.h"
64 #include "qdialogbuttonbox.h"
65 #include "private/qguiplatformplugin_p.h"
67 #ifdef Q_WS_S60
68 #include "private/qt_s60_p.h"
69 #endif
71 QT_BEGIN_NAMESPACE
73 //////////// QWellArray BEGIN
75 struct QWellArrayData;
77 class QWellArray : public QWidget
79 Q_OBJECT
80 Q_PROPERTY(int selectedColumn READ selectedColumn)
81 Q_PROPERTY(int selectedRow READ selectedRow)
83 public:
84 QWellArray(int rows, int cols, QWidget* parent=0);
85 ~QWellArray() {}
86 QString cellContent(int row, int col) const;
88 int selectedColumn() const { return selCol; }
89 int selectedRow() const { return selRow; }
91 virtual void setCurrent(int row, int col);
92 virtual void setSelected(int row, int col);
94 QSize sizeHint() const;
96 virtual void setCellBrush(int row, int col, const QBrush &);
97 QBrush cellBrush(int row, int col);
99 inline int cellWidth() const
100 { return cellw; }
102 inline int cellHeight() const
103 { return cellh; }
105 inline int rowAt(int y) const
106 { return y / cellh; }
108 inline int columnAt(int x) const
109 { if (isRightToLeft()) return ncols - (x / cellw) - 1; return x / cellw; }
111 inline int rowY(int row) const
112 { return cellh * row; }
114 inline int columnX(int column) const
115 { if (isRightToLeft()) return cellw * (ncols - column - 1); return cellw * column; }
117 inline int numRows() const
118 { return nrows; }
120 inline int numCols() const
121 {return ncols; }
123 inline QRect cellRect() const
124 { return QRect(0, 0, cellw, cellh); }
126 inline QSize gridSize() const
127 { return QSize(ncols * cellw, nrows * cellh); }
129 QRect cellGeometry(int row, int column)
131 QRect r;
132 if (row >= 0 && row < nrows && column >= 0 && column < ncols)
133 r.setRect(columnX(column), rowY(row), cellw, cellh);
134 return r;
137 inline void updateCell(int row, int column) { update(cellGeometry(row, column)); }
139 signals:
140 void selected(int row, int col);
142 protected:
143 virtual void paintCell(QPainter *, int row, int col, const QRect&);
144 virtual void paintCellContents(QPainter *, int row, int col, const QRect&);
146 void mousePressEvent(QMouseEvent*);
147 void mouseReleaseEvent(QMouseEvent*);
148 void keyPressEvent(QKeyEvent*);
149 void focusInEvent(QFocusEvent*);
150 void focusOutEvent(QFocusEvent*);
151 void paintEvent(QPaintEvent *);
153 private:
154 Q_DISABLE_COPY(QWellArray)
156 int nrows;
157 int ncols;
158 int cellw;
159 int cellh;
160 int curRow;
161 int curCol;
162 int selRow;
163 int selCol;
164 QWellArrayData *d;
167 void QWellArray::paintEvent(QPaintEvent *e)
169 QRect r = e->rect();
170 int cx = r.x();
171 int cy = r.y();
172 int ch = r.height();
173 int cw = r.width();
174 int colfirst = columnAt(cx);
175 int collast = columnAt(cx + cw);
176 int rowfirst = rowAt(cy);
177 int rowlast = rowAt(cy + ch);
179 if (isRightToLeft()) {
180 int t = colfirst;
181 colfirst = collast;
182 collast = t;
185 QPainter painter(this);
186 QPainter *p = &painter;
187 QRect rect(0, 0, cellWidth(), cellHeight());
190 if (collast < 0 || collast >= ncols)
191 collast = ncols-1;
192 if (rowlast < 0 || rowlast >= nrows)
193 rowlast = nrows-1;
195 // Go through the rows
196 for (int r = rowfirst; r <= rowlast; ++r) {
197 // get row position and height
198 int rowp = rowY(r);
200 // Go through the columns in the row r
201 // if we know from where to where, go through [colfirst, collast],
202 // else go through all of them
203 for (int c = colfirst; c <= collast; ++c) {
204 // get position and width of column c
205 int colp = columnX(c);
206 // Translate painter and draw the cell
207 rect.translate(colp, rowp);
208 paintCell(p, r, c, rect);
209 rect.translate(-colp, -rowp);
214 struct QWellArrayData {
215 QBrush *brush;
218 QWellArray::QWellArray(int rows, int cols, QWidget *parent)
219 : QWidget(parent)
220 ,nrows(rows), ncols(cols)
222 d = 0;
223 setFocusPolicy(Qt::StrongFocus);
224 cellw = 28;
225 cellh = 24;
226 curCol = 0;
227 curRow = 0;
228 selCol = -1;
229 selRow = -1;
232 QSize QWellArray::sizeHint() const
234 ensurePolished();
235 return gridSize().boundedTo(QSize(640, 480));
239 void QWellArray::paintCell(QPainter* p, int row, int col, const QRect &rect)
241 int b = 3; //margin
243 const QPalette & g = palette();
244 QStyleOptionFrame opt;
245 int dfw = style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
246 opt.lineWidth = dfw;
247 opt.midLineWidth = 1;
248 opt.rect = rect.adjusted(b, b, -b, -b);
249 opt.palette = g;
250 opt.state = QStyle::State_Enabled | QStyle::State_Sunken;
251 style()->drawPrimitive(QStyle::PE_Frame, &opt, p, this);
252 b += dfw;
254 if ((row == curRow) && (col == curCol)) {
255 if (hasFocus()) {
256 QStyleOptionFocusRect opt;
257 opt.palette = g;
258 opt.rect = rect;
259 opt.state = QStyle::State_None | QStyle::State_KeyboardFocusChange;
260 style()->drawPrimitive(QStyle::PE_FrameFocusRect, &opt, p, this);
263 paintCellContents(p, row, col, opt.rect.adjusted(dfw, dfw, -dfw, -dfw));
267 Reimplement this function to change the contents of the well array.
269 void QWellArray::paintCellContents(QPainter *p, int row, int col, const QRect &r)
271 if (d) {
272 p->fillRect(r, d->brush[row*numCols()+col]);
273 } else {
274 p->fillRect(r, Qt::white);
275 p->setPen(Qt::black);
276 p->drawLine(r.topLeft(), r.bottomRight());
277 p->drawLine(r.topRight(), r.bottomLeft());
281 void QWellArray::mousePressEvent(QMouseEvent *e)
283 // The current cell marker is set to the cell the mouse is pressed in
284 QPoint pos = e->pos();
285 setCurrent(rowAt(pos.y()), columnAt(pos.x()));
288 void QWellArray::mouseReleaseEvent(QMouseEvent * /* event */)
290 // The current cell marker is set to the cell the mouse is clicked in
291 setSelected(curRow, curCol);
296 Sets the cell currently having the focus. This is not necessarily
297 the same as the currently selected cell.
300 void QWellArray::setCurrent(int row, int col)
302 if ((curRow == row) && (curCol == col))
303 return;
305 if (row < 0 || col < 0)
306 row = col = -1;
308 int oldRow = curRow;
309 int oldCol = curCol;
311 curRow = row;
312 curCol = col;
314 updateCell(oldRow, oldCol);
315 updateCell(curRow, curCol);
319 Sets the currently selected cell to \a row, \a column. If \a row or
320 \a column are less than zero, the current cell is unselected.
322 Does not set the position of the focus indicator.
324 void QWellArray::setSelected(int row, int col)
326 int oldRow = selRow;
327 int oldCol = selCol;
329 if (row < 0 || col < 0)
330 row = col = -1;
332 selCol = col;
333 selRow = row;
335 updateCell(oldRow, oldCol);
336 updateCell(selRow, selCol);
337 if (row >= 0)
338 emit selected(row, col);
340 #ifndef QT_NO_MENU
341 if (isVisible() && qobject_cast<QMenu*>(parentWidget()))
342 parentWidget()->close();
343 #endif
346 void QWellArray::focusInEvent(QFocusEvent*)
348 updateCell(curRow, curCol);
351 void QWellArray::setCellBrush(int row, int col, const QBrush &b)
353 if (!d) {
354 d = new QWellArrayData;
355 int i = numRows()*numCols();
356 d->brush = new QBrush[i];
358 if (row >= 0 && row < numRows() && col >= 0 && col < numCols())
359 d->brush[row*numCols()+col] = b;
363 Returns the brush set for the cell at \a row, \a column. If no brush is
364 set, Qt::NoBrush is returned.
367 QBrush QWellArray::cellBrush(int row, int col)
369 if (d && row >= 0 && row < numRows() && col >= 0 && col < numCols())
370 return d->brush[row*numCols()+col];
371 return Qt::NoBrush;
376 /*!\reimp
379 void QWellArray::focusOutEvent(QFocusEvent*)
381 updateCell(curRow, curCol);
384 /*\reimp
386 void QWellArray::keyPressEvent(QKeyEvent* e)
388 switch(e->key()) { // Look at the key code
389 case Qt::Key_Left: // If 'left arrow'-key,
390 if(curCol > 0) // and cr't not in leftmost col
391 setCurrent(curRow, curCol - 1); // set cr't to next left column
392 break;
393 case Qt::Key_Right: // Correspondingly...
394 if(curCol < numCols()-1)
395 setCurrent(curRow, curCol + 1);
396 break;
397 case Qt::Key_Up:
398 if(curRow > 0)
399 setCurrent(curRow - 1, curCol);
400 break;
401 case Qt::Key_Down:
402 if(curRow < numRows()-1)
403 setCurrent(curRow + 1, curCol);
404 break;
405 #if 0
406 // bad idea that shouldn't have been implemented; very counterintuitive
407 case Qt::Key_Return:
408 case Qt::Key_Enter:
410 ignore the key, so that the dialog get it, but still select
411 the current row/col
413 e->ignore();
414 // fallthrough intended
415 #endif
416 case Qt::Key_Space:
417 setSelected(curRow, curCol);
418 break;
419 default: // If not an interesting key,
420 e->ignore(); // we don't accept the event
421 return;
426 //////////// QWellArray END
428 static bool initrgb = false;
429 static QRgb stdrgb[6*8];
430 static QRgb cusrgb[2*8];
431 static bool customSet = false;
434 static void initRGB()
436 if (initrgb)
437 return;
438 initrgb = true;
439 int i = 0;
440 for (int g = 0; g < 4; g++)
441 for (int r = 0; r < 4; r++)
442 for (int b = 0; b < 3; b++)
443 stdrgb[i++] = qRgb(r * 255 / 3, g * 255 / 3, b * 255 / 2);
445 for (i = 0; i < 2*8; i++)
446 cusrgb[i] = 0xffffffff;
450 Returns the number of custom colors supported by QColorDialog. All
451 color dialogs share the same custom colors.
453 int QColorDialog::customCount()
455 return 2 * 8;
459 \since 4.5
461 Returns the custom color at the given \a index as a QRgb value.
463 QRgb QColorDialog::customColor(int index)
465 if (uint(index) >= uint(customCount()))
466 return qRgb(255, 255, 255);
467 initRGB();
468 return cusrgb[index];
472 Sets the custom color at \a index to the QRgb \a color value.
474 \note This function does not apply to the Native Color Dialog on the Mac
475 OS X platform. If you still require this function, use the
476 QColorDialog::DontUseNativeDialog option.
478 void QColorDialog::setCustomColor(int index, QRgb color)
480 if (uint(index) >= uint(customCount()))
481 return;
482 initRGB();
483 customSet = true;
484 cusrgb[index] = color;
488 Sets the standard color at \a index to the QRgb \a color value.
490 \note This function does not apply to the Native Color Dialog on the Mac
491 OS X platform. If you still require this function, use the
492 QColorDialog::DontUseNativeDialog option.
495 void QColorDialog::setStandardColor(int index, QRgb color)
497 if (uint(index) >= uint(6 * 8))
498 return;
499 initRGB();
500 stdrgb[index] = color;
503 static inline void rgb2hsv(QRgb rgb, int &h, int &s, int &v)
505 QColor c;
506 c.setRgb(rgb);
507 c.getHsv(&h, &s, &v);
510 class QColorWell : public QWellArray
512 public:
513 QColorWell(QWidget *parent, int r, int c, QRgb *vals)
514 :QWellArray(r, c, parent), values(vals), mousePressed(false), oldCurrent(-1, -1)
515 { setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum)); }
517 protected:
518 void paintCellContents(QPainter *, int row, int col, const QRect&);
519 void mousePressEvent(QMouseEvent *e);
520 void mouseMoveEvent(QMouseEvent *e);
521 void mouseReleaseEvent(QMouseEvent *e);
522 #ifndef QT_NO_DRAGANDDROP
523 void dragEnterEvent(QDragEnterEvent *e);
524 void dragLeaveEvent(QDragLeaveEvent *e);
525 void dragMoveEvent(QDragMoveEvent *e);
526 void dropEvent(QDropEvent *e);
527 #endif
529 private:
530 QRgb *values;
531 bool mousePressed;
532 QPoint pressPos;
533 QPoint oldCurrent;
537 void QColorWell::paintCellContents(QPainter *p, int row, int col, const QRect &r)
539 int i = row + col*numRows();
540 p->fillRect(r, QColor(values[i]));
543 void QColorWell::mousePressEvent(QMouseEvent *e)
545 oldCurrent = QPoint(selectedRow(), selectedColumn());
546 QWellArray::mousePressEvent(e);
547 mousePressed = true;
548 pressPos = e->pos();
551 void QColorWell::mouseMoveEvent(QMouseEvent *e)
553 QWellArray::mouseMoveEvent(e);
554 #ifndef QT_NO_DRAGANDDROP
555 if (!mousePressed)
556 return;
557 if ((pressPos - e->pos()).manhattanLength() > QApplication::startDragDistance()) {
558 setCurrent(oldCurrent.x(), oldCurrent.y());
559 int i = rowAt(pressPos.y()) + columnAt(pressPos.x()) * numRows();
560 QColor col(values[i]);
561 QMimeData *mime = new QMimeData;
562 mime->setColorData(col);
563 QPixmap pix(cellWidth(), cellHeight());
564 pix.fill(col);
565 QPainter p(&pix);
566 p.drawRect(0, 0, pix.width() - 1, pix.height() - 1);
567 p.end();
568 QDrag *drg = new QDrag(this);
569 drg->setMimeData(mime);
570 drg->setPixmap(pix);
571 mousePressed = false;
572 drg->start();
574 #endif
577 #ifndef QT_NO_DRAGANDDROP
578 void QColorWell::dragEnterEvent(QDragEnterEvent *e)
580 if (qvariant_cast<QColor>(e->mimeData()->colorData()).isValid())
581 e->accept();
582 else
583 e->ignore();
586 void QColorWell::dragLeaveEvent(QDragLeaveEvent *)
588 if (hasFocus())
589 parentWidget()->setFocus();
592 void QColorWell::dragMoveEvent(QDragMoveEvent *e)
594 if (qvariant_cast<QColor>(e->mimeData()->colorData()).isValid()) {
595 setCurrent(rowAt(e->pos().y()), columnAt(e->pos().x()));
596 e->accept();
597 } else {
598 e->ignore();
602 void QColorWell::dropEvent(QDropEvent *e)
604 QColor col = qvariant_cast<QColor>(e->mimeData()->colorData());
605 if (col.isValid()) {
606 int i = rowAt(e->pos().y()) + columnAt(e->pos().x()) * numRows();
607 values[i] = col.rgb();
608 update();
609 e->accept();
610 } else {
611 e->ignore();
615 #endif // QT_NO_DRAGANDDROP
617 void QColorWell::mouseReleaseEvent(QMouseEvent *e)
619 if (!mousePressed)
620 return;
621 QWellArray::mouseReleaseEvent(e);
622 mousePressed = false;
625 class QColorPicker : public QFrame
627 Q_OBJECT
628 public:
629 QColorPicker(QWidget* parent);
630 ~QColorPicker();
632 public slots:
633 void setCol(int h, int s);
635 signals:
636 void newCol(int h, int s);
638 protected:
639 QSize sizeHint() const;
640 void paintEvent(QPaintEvent*);
641 void mouseMoveEvent(QMouseEvent *);
642 void mousePressEvent(QMouseEvent *);
644 private:
645 int hue;
646 int sat;
648 QPoint colPt();
649 int huePt(const QPoint &pt);
650 int satPt(const QPoint &pt);
651 void setCol(const QPoint &pt);
653 QPixmap *pix;
656 static int pWidth = 220;
657 static int pHeight = 200;
659 class QColorLuminancePicker : public QWidget
661 Q_OBJECT
662 public:
663 QColorLuminancePicker(QWidget* parent=0);
664 ~QColorLuminancePicker();
666 public slots:
667 void setCol(int h, int s, int v);
668 void setCol(int h, int s);
670 signals:
671 void newHsv(int h, int s, int v);
673 protected:
674 void paintEvent(QPaintEvent*);
675 void mouseMoveEvent(QMouseEvent *);
676 void mousePressEvent(QMouseEvent *);
678 private:
679 enum { foff = 3, coff = 4 }; //frame and contents offset
680 int val;
681 int hue;
682 int sat;
684 int y2val(int y);
685 int val2y(int val);
686 void setVal(int v);
688 QPixmap *pix;
692 int QColorLuminancePicker::y2val(int y)
694 int d = height() - 2*coff - 1;
695 return 255 - (y - coff)*255/d;
698 int QColorLuminancePicker::val2y(int v)
700 int d = height() - 2*coff - 1;
701 return coff + (255-v)*d/255;
704 QColorLuminancePicker::QColorLuminancePicker(QWidget* parent)
705 :QWidget(parent)
707 hue = 100; val = 100; sat = 100;
708 pix = 0;
709 // setAttribute(WA_NoErase, true);
712 QColorLuminancePicker::~QColorLuminancePicker()
714 delete pix;
717 void QColorLuminancePicker::mouseMoveEvent(QMouseEvent *m)
719 setVal(y2val(m->y()));
721 void QColorLuminancePicker::mousePressEvent(QMouseEvent *m)
723 setVal(y2val(m->y()));
726 void QColorLuminancePicker::setVal(int v)
728 if (val == v)
729 return;
730 val = qMax(0, qMin(v,255));
731 delete pix; pix=0;
732 repaint();
733 emit newHsv(hue, sat, val);
736 //receives from a hue,sat chooser and relays.
737 void QColorLuminancePicker::setCol(int h, int s)
739 setCol(h, s, val);
740 emit newHsv(h, s, val);
743 void QColorLuminancePicker::paintEvent(QPaintEvent *)
745 int w = width() - 5;
747 QRect r(0, foff, w, height() - 2*foff);
748 int wi = r.width() - 2;
749 int hi = r.height() - 2;
750 if (!pix || pix->height() != hi || pix->width() != wi) {
751 delete pix;
752 QImage img(wi, hi, QImage::Format_RGB32);
753 int y;
754 uint *pixel = (uint *) img.scanLine(0);
755 for (y = 0; y < hi; y++) {
756 const uint *end = pixel + wi;
757 while (pixel < end) {
758 QColor c;
759 c.setHsv(hue, sat, y2val(y+coff));
760 *pixel = c.rgb();
761 ++pixel;
764 pix = new QPixmap(QPixmap::fromImage(img));
766 QPainter p(this);
767 p.drawPixmap(1, coff, *pix);
768 const QPalette &g = palette();
769 qDrawShadePanel(&p, r, g, true);
770 p.setPen(g.foreground().color());
771 p.setBrush(g.foreground());
772 QPolygon a;
773 int y = val2y(val);
774 a.setPoints(3, w, y, w+5, y+5, w+5, y-5);
775 p.eraseRect(w, 0, 5, height());
776 p.drawPolygon(a);
779 void QColorLuminancePicker::setCol(int h, int s , int v)
781 val = v;
782 hue = h;
783 sat = s;
784 delete pix; pix=0;
785 repaint();
788 QPoint QColorPicker::colPt()
789 { return QPoint((360-hue)*(pWidth-1)/360, (255-sat)*(pHeight-1)/255); }
790 int QColorPicker::huePt(const QPoint &pt)
791 { return 360 - pt.x()*360/(pWidth-1); }
792 int QColorPicker::satPt(const QPoint &pt)
793 { return 255 - pt.y()*255/(pHeight-1) ; }
794 void QColorPicker::setCol(const QPoint &pt)
795 { setCol(huePt(pt), satPt(pt)); }
797 QColorPicker::QColorPicker(QWidget* parent)
798 : QFrame(parent)
800 hue = 0; sat = 0;
801 setCol(150, 255);
803 QImage img(pWidth, pHeight, QImage::Format_RGB32);
804 int x, y;
805 uint *pixel = (uint *) img.scanLine(0);
806 for (y = 0; y < pHeight; y++) {
807 const uint *end = pixel + pWidth;
808 x = 0;
809 while (pixel < end) {
810 QPoint p(x, y);
811 QColor c;
812 c.setHsv(huePt(p), satPt(p), 200);
813 *pixel = c.rgb();
814 ++pixel;
815 ++x;
818 pix = new QPixmap(QPixmap::fromImage(img));
819 setAttribute(Qt::WA_NoSystemBackground);
820 setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed) );
823 QColorPicker::~QColorPicker()
825 delete pix;
828 QSize QColorPicker::sizeHint() const
830 return QSize(pWidth + 2*frameWidth(), pHeight + 2*frameWidth());
833 void QColorPicker::setCol(int h, int s)
835 int nhue = qMin(qMax(0,h), 359);
836 int nsat = qMin(qMax(0,s), 255);
837 if (nhue == hue && nsat == sat)
838 return;
840 QRect r(colPt(), QSize(20,20));
841 hue = nhue; sat = nsat;
842 r = r.united(QRect(colPt(), QSize(20,20)));
843 r.translate(contentsRect().x()-9, contentsRect().y()-9);
844 // update(r);
845 repaint(r);
848 void QColorPicker::mouseMoveEvent(QMouseEvent *m)
850 QPoint p = m->pos() - contentsRect().topLeft();
851 setCol(p);
852 emit newCol(hue, sat);
855 void QColorPicker::mousePressEvent(QMouseEvent *m)
857 QPoint p = m->pos() - contentsRect().topLeft();
858 setCol(p);
859 emit newCol(hue, sat);
862 void QColorPicker::paintEvent(QPaintEvent* )
864 QPainter p(this);
865 drawFrame(&p);
866 QRect r = contentsRect();
868 p.drawPixmap(r.topLeft(), *pix);
869 QPoint pt = colPt() + r.topLeft();
870 p.setPen(Qt::black);
872 p.fillRect(pt.x()-9, pt.y(), 20, 2, Qt::black);
873 p.fillRect(pt.x(), pt.y()-9, 2, 20, Qt::black);
877 class QColSpinBox : public QSpinBox
879 public:
880 QColSpinBox(QWidget *parent)
881 : QSpinBox(parent) { setRange(0, 255); }
882 void setValue(int i) {
883 bool block = signalsBlocked();
884 blockSignals(true);
885 QSpinBox::setValue(i);
886 blockSignals(block);
890 class QColorShowLabel;
892 class QColorShower : public QWidget
894 Q_OBJECT
895 public:
896 QColorShower(QColorDialog *parent);
898 //things that don't emit signals
899 void setHsv(int h, int s, int v);
901 int currentAlpha() const
902 { return (colorDialog->options() & QColorDialog::ShowAlphaChannel) ? alphaEd->value() : 255; }
903 void setCurrentAlpha(int a) { alphaEd->setValue(a); rgbEd(); }
904 void showAlpha(bool b);
905 bool isAlphaVisible() const;
907 QRgb currentColor() const { return curCol; }
908 QColor currentQColor() const { return curQColor; }
909 void retranslateStrings();
910 void updateQColor();
912 public slots:
913 void setRgb(QRgb rgb);
915 signals:
916 void newCol(QRgb rgb);
917 void currentColorChanged(const QColor &color);
919 private slots:
920 void rgbEd();
921 void hsvEd();
922 private:
923 void showCurrentColor();
924 int hue, sat, val;
925 QRgb curCol;
926 QColor curQColor;
927 QLabel *lblHue;
928 QLabel *lblSat;
929 QLabel *lblVal;
930 QLabel *lblRed;
931 QLabel *lblGreen;
932 QLabel *lblBlue;
933 QColSpinBox *hEd;
934 QColSpinBox *sEd;
935 QColSpinBox *vEd;
936 QColSpinBox *rEd;
937 QColSpinBox *gEd;
938 QColSpinBox *bEd;
939 QColSpinBox *alphaEd;
940 QLabel *alphaLab;
941 QColorShowLabel *lab;
942 bool rgbOriginal;
943 QColorDialog *colorDialog;
945 friend class QColorDialog;
946 friend class QColorDialogPrivate;
949 class QColorShowLabel : public QFrame
951 Q_OBJECT
953 public:
954 QColorShowLabel(QWidget *parent) : QFrame(parent) {
955 setFrameStyle(QFrame::Panel|QFrame::Sunken);
956 setAcceptDrops(true);
957 mousePressed = false;
959 void setColor(QColor c) { col = c; }
961 signals:
962 void colorDropped(QRgb);
964 protected:
965 void paintEvent(QPaintEvent *);
966 void mousePressEvent(QMouseEvent *e);
967 void mouseMoveEvent(QMouseEvent *e);
968 void mouseReleaseEvent(QMouseEvent *e);
969 #ifndef QT_NO_DRAGANDDROP
970 void dragEnterEvent(QDragEnterEvent *e);
971 void dragLeaveEvent(QDragLeaveEvent *e);
972 void dropEvent(QDropEvent *e);
973 #endif
975 private:
976 QColor col;
977 bool mousePressed;
978 QPoint pressPos;
981 void QColorShowLabel::paintEvent(QPaintEvent *e)
983 QPainter p(this);
984 drawFrame(&p);
985 p.fillRect(contentsRect()&e->rect(), col);
988 void QColorShower::showAlpha(bool b)
990 alphaLab->setVisible(b);
991 alphaEd->setVisible(b);
994 inline bool QColorShower::isAlphaVisible() const
996 return alphaLab->isVisible();
999 void QColorShowLabel::mousePressEvent(QMouseEvent *e)
1001 mousePressed = true;
1002 pressPos = e->pos();
1005 void QColorShowLabel::mouseMoveEvent(QMouseEvent *e)
1007 #ifdef QT_NO_DRAGANDDROP
1008 Q_UNUSED(e);
1009 #else
1010 if (!mousePressed)
1011 return;
1012 if ((pressPos - e->pos()).manhattanLength() > QApplication::startDragDistance()) {
1013 QMimeData *mime = new QMimeData;
1014 mime->setColorData(col);
1015 QPixmap pix(30, 20);
1016 pix.fill(col);
1017 QPainter p(&pix);
1018 p.drawRect(0, 0, pix.width() - 1, pix.height() - 1);
1019 p.end();
1020 QDrag *drg = new QDrag(this);
1021 drg->setMimeData(mime);
1022 drg->setPixmap(pix);
1023 mousePressed = false;
1024 drg->start();
1026 #endif
1029 #ifndef QT_NO_DRAGANDDROP
1030 void QColorShowLabel::dragEnterEvent(QDragEnterEvent *e)
1032 if (qvariant_cast<QColor>(e->mimeData()->colorData()).isValid())
1033 e->accept();
1034 else
1035 e->ignore();
1038 void QColorShowLabel::dragLeaveEvent(QDragLeaveEvent *)
1042 void QColorShowLabel::dropEvent(QDropEvent *e)
1044 QColor color = qvariant_cast<QColor>(e->mimeData()->colorData());
1045 if (color.isValid()) {
1046 col = color;
1047 repaint();
1048 emit colorDropped(col.rgb());
1049 e->accept();
1050 } else {
1051 e->ignore();
1054 #endif // QT_NO_DRAGANDDROP
1056 void QColorShowLabel::mouseReleaseEvent(QMouseEvent *)
1058 if (!mousePressed)
1059 return;
1060 mousePressed = false;
1063 QColorShower::QColorShower(QColorDialog *parent)
1064 : QWidget(parent)
1066 colorDialog = parent;
1068 curCol = qRgb(255, 255, 255);
1069 curQColor = Qt::white;
1071 QGridLayout *gl = new QGridLayout(this);
1072 gl->setMargin(gl->spacing());
1073 lab = new QColorShowLabel(this);
1075 #ifdef Q_WS_S60
1076 QS60Data s60Data = QS60Data();
1077 const bool nonTouchUI = !s60Data.hasTouchscreen;
1078 #endif
1081 #ifndef Q_WS_WINCE
1082 #ifdef Q_WS_S60
1083 lab->setMinimumHeight(60);
1084 #endif
1085 lab->setMinimumWidth(60);
1086 #else
1087 lab->setMinimumWidth(20);
1088 #endif
1090 // In S60, due to small screen and different screen layouts need to re-arrange the widgets.
1091 // For QVGA screens only the comboboxes and color label are visible.
1092 // For nHD screens only color and luminence pickers and color label are visible.
1093 #ifndef Q_WS_S60
1094 gl->addWidget(lab, 0, 0, -1, 1);
1095 #else
1096 if (nonTouchUI)
1097 gl->addWidget(lab, 0, 0, 1, -1);
1098 else
1099 gl->addWidget(lab, 0, 0, -1, 1);
1100 #endif
1101 connect(lab, SIGNAL(colorDropped(QRgb)), this, SIGNAL(newCol(QRgb)));
1102 connect(lab, SIGNAL(colorDropped(QRgb)), this, SLOT(setRgb(QRgb)));
1104 hEd = new QColSpinBox(this);
1105 hEd->setRange(0, 359);
1106 lblHue = new QLabel(this);
1107 #ifndef QT_NO_SHORTCUT
1108 lblHue->setBuddy(hEd);
1109 #endif
1110 lblHue->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
1111 #ifndef Q_WS_S60
1112 gl->addWidget(lblHue, 0, 1);
1113 gl->addWidget(hEd, 0, 2);
1114 #else
1115 if (nonTouchUI) {
1116 gl->addWidget(lblHue, 1, 0);
1117 gl->addWidget(hEd, 2, 0);
1118 } else {
1119 lblHue->hide();
1120 hEd->hide();
1122 #endif
1124 sEd = new QColSpinBox(this);
1125 lblSat = new QLabel(this);
1126 #ifndef QT_NO_SHORTCUT
1127 lblSat->setBuddy(sEd);
1128 #endif
1129 lblSat->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
1130 #ifndef Q_WS_S60
1131 gl->addWidget(lblSat, 1, 1);
1132 gl->addWidget(sEd, 1, 2);
1133 #else
1134 if (nonTouchUI) {
1135 gl->addWidget(lblSat, 1, 1);
1136 gl->addWidget(sEd, 2, 1);
1137 } else {
1138 lblSat->hide();
1139 sEd->hide();
1141 #endif
1143 vEd = new QColSpinBox(this);
1144 lblVal = new QLabel(this);
1145 #ifndef QT_NO_SHORTCUT
1146 lblVal->setBuddy(vEd);
1147 #endif
1148 lblVal->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
1149 #ifndef Q_WS_S60
1150 gl->addWidget(lblVal, 2, 1);
1151 gl->addWidget(vEd, 2, 2);
1152 #else
1153 if (nonTouchUI) {
1154 gl->addWidget(lblVal, 1, 2);
1155 gl->addWidget(vEd, 2, 2);
1156 } else {
1157 lblVal->hide();
1158 vEd->hide();
1160 #endif
1162 rEd = new QColSpinBox(this);
1163 lblRed = new QLabel(this);
1164 #ifndef QT_NO_SHORTCUT
1165 lblRed->setBuddy(rEd);
1166 #endif
1167 lblRed->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
1168 #ifndef Q_WS_S60
1169 gl->addWidget(lblRed, 0, 3);
1170 gl->addWidget(rEd, 0, 4);
1171 #else
1172 if (nonTouchUI) {
1173 gl->addWidget(lblRed, 3, 0);
1174 gl->addWidget(rEd, 4, 0);
1175 } else {
1176 lblRed->hide();
1177 rEd->hide();
1179 #endif
1181 gEd = new QColSpinBox(this);
1182 lblGreen = new QLabel(this);
1183 #ifndef QT_NO_SHORTCUT
1184 lblGreen->setBuddy(gEd);
1185 #endif
1186 lblGreen->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
1187 #ifndef Q_WS_S60
1188 gl->addWidget(lblGreen, 1, 3);
1189 gl->addWidget(gEd, 1, 4);
1190 #else
1191 if (nonTouchUI) {
1192 gl->addWidget(lblGreen, 3, 1);
1193 gl->addWidget(gEd, 4, 1);
1194 } else {
1195 lblGreen->hide();
1196 gEd->hide();
1198 #endif
1200 bEd = new QColSpinBox(this);
1201 lblBlue = new QLabel(this);
1202 #ifndef QT_NO_SHORTCUT
1203 lblBlue->setBuddy(bEd);
1204 #endif
1205 lblBlue->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
1206 #ifndef Q_WS_S60
1207 gl->addWidget(lblBlue, 2, 3);
1208 gl->addWidget(bEd, 2, 4);
1209 #else
1210 if (nonTouchUI) {
1211 gl->addWidget(lblBlue, 3, 2);
1212 gl->addWidget(bEd, 4, 2);
1213 } else {
1214 lblBlue->hide();
1215 bEd->hide();
1217 #endif
1219 alphaEd = new QColSpinBox(this);
1220 alphaLab = new QLabel(this);
1221 #ifndef QT_NO_SHORTCUT
1222 alphaLab->setBuddy(alphaEd);
1223 #endif
1224 alphaLab->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
1225 #ifndef Q_WS_S60
1226 gl->addWidget(alphaLab, 3, 1, 1, 3);
1227 gl->addWidget(alphaEd, 3, 4);
1228 #else
1229 if (nonTouchUI) {
1230 gl->addWidget(alphaLab, 1, 3, 3, 1);
1231 gl->addWidget(alphaEd, 4, 3);
1232 } else {
1233 alphaLab->hide();
1234 alphaEd->hide();
1236 #endif
1237 alphaEd->hide();
1238 alphaLab->hide();
1240 connect(hEd, SIGNAL(valueChanged(int)), this, SLOT(hsvEd()));
1241 connect(sEd, SIGNAL(valueChanged(int)), this, SLOT(hsvEd()));
1242 connect(vEd, SIGNAL(valueChanged(int)), this, SLOT(hsvEd()));
1244 connect(rEd, SIGNAL(valueChanged(int)), this, SLOT(rgbEd()));
1245 connect(gEd, SIGNAL(valueChanged(int)), this, SLOT(rgbEd()));
1246 connect(bEd, SIGNAL(valueChanged(int)), this, SLOT(rgbEd()));
1247 connect(alphaEd, SIGNAL(valueChanged(int)), this, SLOT(rgbEd()));
1249 retranslateStrings();
1252 inline QRgb QColorDialogPrivate::currentColor() const { return cs->currentColor(); }
1253 inline int QColorDialogPrivate::currentAlpha() const { return cs->currentAlpha(); }
1254 inline void QColorDialogPrivate::setCurrentAlpha(int a) { cs->setCurrentAlpha(a); }
1255 inline void QColorDialogPrivate::showAlpha(bool b) { cs->showAlpha(b); }
1256 inline bool QColorDialogPrivate::isAlphaVisible() const { return cs->isAlphaVisible(); }
1258 QColor QColorDialogPrivate::currentQColor() const
1260 return cs->currentQColor();
1263 void QColorShower::showCurrentColor()
1265 lab->setColor(currentColor());
1266 lab->repaint();
1269 void QColorShower::rgbEd()
1271 rgbOriginal = true;
1272 curCol = qRgba(rEd->value(), gEd->value(), bEd->value(), currentAlpha());
1274 rgb2hsv(currentColor(), hue, sat, val);
1276 hEd->setValue(hue);
1277 sEd->setValue(sat);
1278 vEd->setValue(val);
1280 showCurrentColor();
1281 emit newCol(currentColor());
1282 updateQColor();
1285 void QColorShower::hsvEd()
1287 rgbOriginal = false;
1288 hue = hEd->value();
1289 sat = sEd->value();
1290 val = vEd->value();
1292 QColor c;
1293 c.setHsv(hue, sat, val);
1294 curCol = c.rgb();
1296 rEd->setValue(qRed(currentColor()));
1297 gEd->setValue(qGreen(currentColor()));
1298 bEd->setValue(qBlue(currentColor()));
1300 showCurrentColor();
1301 emit newCol(currentColor());
1302 updateQColor();
1305 void QColorShower::setRgb(QRgb rgb)
1307 rgbOriginal = true;
1308 curCol = rgb;
1310 rgb2hsv(currentColor(), hue, sat, val);
1312 hEd->setValue(hue);
1313 sEd->setValue(sat);
1314 vEd->setValue(val);
1316 rEd->setValue(qRed(currentColor()));
1317 gEd->setValue(qGreen(currentColor()));
1318 bEd->setValue(qBlue(currentColor()));
1320 showCurrentColor();
1321 updateQColor();
1324 void QColorShower::setHsv(int h, int s, int v)
1326 if (h < -1 || (uint)s > 255 || (uint)v > 255)
1327 return;
1329 rgbOriginal = false;
1330 hue = h; val = v; sat = s;
1331 QColor c;
1332 c.setHsv(hue, sat, val);
1333 curCol = c.rgb();
1335 hEd->setValue(hue);
1336 sEd->setValue(sat);
1337 vEd->setValue(val);
1339 rEd->setValue(qRed(currentColor()));
1340 gEd->setValue(qGreen(currentColor()));
1341 bEd->setValue(qBlue(currentColor()));
1343 showCurrentColor();
1344 updateQColor();
1347 void QColorShower::retranslateStrings()
1349 lblHue->setText(QColorDialog::tr("Hu&e:"));
1350 lblSat->setText(QColorDialog::tr("&Sat:"));
1351 lblVal->setText(QColorDialog::tr("&Val:"));
1352 lblRed->setText(QColorDialog::tr("&Red:"));
1353 lblGreen->setText(QColorDialog::tr("&Green:"));
1354 lblBlue->setText(QColorDialog::tr("Bl&ue:"));
1355 alphaLab->setText(QColorDialog::tr("A&lpha channel:"));
1358 void QColorShower::updateQColor()
1360 QColor oldQColor(curQColor);
1361 curQColor.setRgba(qRgba(qRed(curCol), qGreen(curCol), qBlue(curCol), currentAlpha()));
1362 if (curQColor != oldQColor)
1363 emit currentColorChanged(curQColor);
1366 //sets all widgets to display h,s,v
1367 void QColorDialogPrivate::_q_newHsv(int h, int s, int v)
1369 cs->setHsv(h, s, v);
1370 cp->setCol(h, s);
1371 lp->setCol(h, s, v);
1374 //sets all widgets to display rgb
1375 void QColorDialogPrivate::setCurrentColor(QRgb rgb)
1377 cs->setRgb(rgb);
1378 _q_newColorTypedIn(rgb);
1381 // hack; doesn't keep curCol in sync, so use with care
1382 void QColorDialogPrivate::setCurrentQColor(const QColor &color)
1384 Q_Q(QColorDialog);
1385 if (cs->curQColor != color) {
1386 cs->curQColor = color;
1387 emit q->currentColorChanged(color);
1391 bool QColorDialogPrivate::selectColor(const QColor &col)
1393 QRgb color = col.rgb();
1394 int i = 0, j = 0;
1395 // Check standard colors
1396 if (standard) {
1397 for (i = 0; i < 6; i++) {
1398 for (j = 0; j < 8; j++) {
1399 if (color == stdrgb[i + j*6]) {
1400 _q_newStandard(i, j);
1401 standard->setCurrent(i, j);
1402 standard->setSelected(i, j);
1403 standard->setFocus();
1404 return true;
1409 // Check custom colors
1410 if (custom) {
1411 for (i = 0; i < 2; i++) {
1412 for (j = 0; j < 8; j++) {
1413 if (color == cusrgb[i + j*2]) {
1414 _q_newCustom(i, j);
1415 custom->setCurrent(i, j);
1416 custom->setSelected(i, j);
1417 custom->setFocus();
1418 return true;
1423 return false;
1426 //sets all widgets except cs to display rgb
1427 void QColorDialogPrivate::_q_newColorTypedIn(QRgb rgb)
1429 int h, s, v;
1430 rgb2hsv(rgb, h, s, v);
1431 cp->setCol(h, s);
1432 lp->setCol(h, s, v);
1435 void QColorDialogPrivate::_q_newCustom(int r, int c)
1437 int i = r+2*c;
1438 setCurrentColor(cusrgb[i]);
1439 nextCust = i;
1440 if (standard)
1441 standard->setSelected(-1,-1);
1444 void QColorDialogPrivate::_q_newStandard(int r, int c)
1446 setCurrentColor(stdrgb[r+c*6]);
1447 if (custom)
1448 custom->setSelected(-1,-1);
1451 void QColorDialogPrivate::init(const QColor &initial)
1453 Q_Q(QColorDialog);
1455 q->setSizeGripEnabled(false);
1456 q->setWindowTitle(QColorDialog::tr("Select Color"));
1458 nativeDialogInUse = false;
1460 nextCust = 0;
1461 QVBoxLayout *mainLay = new QVBoxLayout(q);
1462 // there's nothing in this dialog that benefits from sizing up
1463 mainLay->setSizeConstraint(QLayout::SetFixedSize);
1465 QHBoxLayout *topLay = new QHBoxLayout();
1466 mainLay->addLayout(topLay);
1468 leftLay = 0;
1470 #if (defined(Q_WS_WINCE) || defined(Q_WS_S60))
1471 smallDisplay = true;
1472 const int lumSpace = 20;
1473 #else
1474 // small displays (e.g. PDAs) cannot fit the full color dialog,
1475 // so just use the color picker.
1476 smallDisplay = (QApplication::desktop()->width() < 480 || QApplication::desktop()->height() < 350);
1477 const int lumSpace = topLay->spacing() / 2;
1478 #endif
1480 if (!smallDisplay) {
1481 leftLay = new QVBoxLayout;
1482 topLay->addLayout(leftLay);
1485 initRGB();
1487 #ifndef QT_NO_SETTINGS
1488 if (!customSet) {
1489 QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
1490 for (int i = 0; i < 2*8; ++i) {
1491 QVariant v = settings.value(QLatin1String("Qt/customColors/") + QString::number(i));
1492 if (v.isValid()) {
1493 QRgb rgb = v.toUInt();
1494 cusrgb[i] = rgb;
1498 #endif
1500 #if defined(Q_WS_S60)
1501 QS60Data s60Data = QS60Data();
1502 const bool nonTouchUI = !s60Data.hasTouchscreen;
1503 #endif
1505 if (!smallDisplay) {
1506 standard = new QColorWell(q, 6, 8, stdrgb);
1507 lblBasicColors = new QLabel(q);
1508 #ifndef QT_NO_SHORTCUT
1509 lblBasicColors->setBuddy(standard);
1510 #endif
1511 q->connect(standard, SIGNAL(selected(int,int)), SLOT(_q_newStandard(int,int)));
1512 leftLay->addWidget(lblBasicColors);
1513 leftLay->addWidget(standard);
1515 #if !defined(Q_WS_WINCE)
1516 leftLay->addStretch();
1517 #endif
1519 custom = new QColorWell(q, 2, 8, cusrgb);
1520 custom->setAcceptDrops(true);
1522 q->connect(custom, SIGNAL(selected(int,int)), SLOT(_q_newCustom(int,int)));
1523 lblCustomColors = new QLabel(q);
1524 #ifndef QT_NO_SHORTCUT
1525 lblCustomColors->setBuddy(custom);
1526 #endif
1527 leftLay->addWidget(lblCustomColors);
1528 leftLay->addWidget(custom);
1530 addCusBt = new QPushButton(q);
1531 QObject::connect(addCusBt, SIGNAL(clicked()), q, SLOT(_q_addCustom()));
1532 leftLay->addWidget(addCusBt);
1533 } else {
1534 // better color picker size for small displays
1535 #ifdef Q_WS_S60
1536 QSize screenSize = QApplication::desktop()->availableGeometry(QCursor::pos()).size();
1537 pWidth = pHeight = qMin(screenSize.width(), screenSize.height());
1538 pHeight -= 20;
1539 if(screenSize.height() > screenSize.width())
1540 pWidth -= 20;
1541 #else
1542 pWidth = 150;
1543 pHeight = 100;
1544 #endif
1545 custom = 0;
1546 standard = 0;
1549 QVBoxLayout *rightLay = new QVBoxLayout;
1550 topLay->addLayout(rightLay);
1552 QHBoxLayout *pickLay = new QHBoxLayout;
1553 rightLay->addLayout(pickLay);
1555 QVBoxLayout *cLay = new QVBoxLayout;
1556 pickLay->addLayout(cLay);
1557 cp = new QColorPicker(q);
1559 cp->setFrameStyle(QFrame::Panel + QFrame::Sunken);
1561 #if defined(Q_WS_S60)
1562 if (!nonTouchUI) {
1563 pickLay->addWidget(cp);
1564 cLay->addSpacing(lumSpace);
1565 } else {
1566 cp->hide();
1568 #else
1569 cLay->addSpacing(lumSpace);
1570 cLay->addWidget(cp);
1571 #endif
1572 cLay->addSpacing(lumSpace);
1574 lp = new QColorLuminancePicker(q);
1575 #if defined(Q_WS_S60)
1576 QSize screenSize = QApplication::desktop()->availableGeometry(QCursor::pos()).size();
1577 const int minDimension = qMin(screenSize.height(), screenSize.width());
1578 //set picker to be finger-usable
1579 int pickerWidth = !nonTouchUI ? minDimension/9 : minDimension/12;
1580 lp->setFixedWidth(pickerWidth);
1581 if (!nonTouchUI)
1582 pickLay->addWidget(lp);
1583 else
1584 lp->hide();
1585 #else
1586 lp->setFixedWidth(20);
1587 pickLay->addWidget(lp);
1588 #endif
1590 QObject::connect(cp, SIGNAL(newCol(int,int)), lp, SLOT(setCol(int,int)));
1591 QObject::connect(lp, SIGNAL(newHsv(int,int,int)), q, SLOT(_q_newHsv(int,int,int)));
1593 rightLay->addStretch();
1595 cs = new QColorShower(q);
1596 QObject::connect(cs, SIGNAL(newCol(QRgb)), q, SLOT(_q_newColorTypedIn(QRgb)));
1597 QObject::connect(cs, SIGNAL(currentColorChanged(QColor)),
1598 q, SIGNAL(currentColorChanged(QColor)));
1599 #if defined(Q_WS_S60)
1600 if (!nonTouchUI)
1601 pWidth -= cp->size().width();
1602 topLay->addWidget(cs);
1603 #else
1604 rightLay->addWidget(cs);
1605 #endif
1607 buttons = new QDialogButtonBox(q);
1608 mainLay->addWidget(buttons);
1610 ok = buttons->addButton(QDialogButtonBox::Ok);
1611 QObject::connect(ok, SIGNAL(clicked()), q, SLOT(accept()));
1612 ok->setDefault(true);
1613 cancel = buttons->addButton(QDialogButtonBox::Cancel);
1614 QObject::connect(cancel, SIGNAL(clicked()), q, SLOT(reject()));
1616 retranslateStrings();
1618 #ifdef Q_WS_MAC
1619 delegate = 0;
1620 #endif
1622 q->setCurrentColor(initial);
1625 void QColorDialogPrivate::_q_addCustom()
1627 cusrgb[nextCust] = cs->currentColor();
1628 if (custom)
1629 custom->update();
1630 nextCust = (nextCust+1) % 16;
1633 void QColorDialogPrivate::retranslateStrings()
1635 if (!smallDisplay) {
1636 lblBasicColors->setText(QColorDialog::tr("&Basic colors"));
1637 lblCustomColors->setText(QColorDialog::tr("&Custom colors"));
1638 addCusBt->setText(QColorDialog::tr("&Add to Custom Colors"));
1641 cs->retranslateStrings();
1644 static const Qt::WindowFlags DefaultWindowFlags =
1645 Qt::Dialog | Qt::WindowTitleHint | Qt::MSWindowsFixedSizeDialogHint
1646 | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint;
1649 \class QColorDialog
1650 \brief The QColorDialog class provides a dialog widget for specifying colors.
1652 \ingroup standard-dialogs
1654 The color dialog's function is to allow users to choose colors.
1655 For example, you might use this in a drawing program to allow the
1656 user to set the brush color.
1658 The static functions provide modal color dialogs.
1659 \omit
1660 If you require a modeless dialog, use the QColorDialog constructor.
1661 \endomit
1663 The static getColor() function shows the dialog, and allows the user to
1664 specify a color. This function can also be used to let users choose a
1665 color with a level of transparency: pass the ShowAlphaChannel option as
1666 an additional argument.
1668 The user can store customCount() different custom colors. The
1669 custom colors are shared by all color dialogs, and remembered
1670 during the execution of the program. Use setCustomColor() to set
1671 the custom colors, and use customColor() to get them.
1673 Additional widgets that allow users to pick colors are available
1674 as \l{Qt Solutions}.
1676 The \l{dialogs/standarddialogs}{Standard Dialogs} example shows
1677 how to use QColorDialog as well as other built-in Qt dialogs.
1679 \image plastique-colordialog.png A color dialog in the Plastique widget style.
1681 \sa QColor, QFileDialog, QPrintDialog, QFontDialog, {Standard Dialogs Example}
1685 \since 4.5
1687 Constructs a color dialog with the given \a parent.
1689 QColorDialog::QColorDialog(QWidget *parent)
1690 : QDialog(*new QColorDialogPrivate, parent, DefaultWindowFlags)
1692 Q_D(QColorDialog);
1693 d->init(Qt::white);
1697 \since 4.5
1699 Constructs a color dialog with the given \a parent and specified
1700 \a initial color.
1702 QColorDialog::QColorDialog(const QColor &initial, QWidget *parent)
1703 : QDialog(*new QColorDialogPrivate, parent, DefaultWindowFlags)
1705 Q_D(QColorDialog);
1706 d->init(initial);
1710 \property QColorDialog::currentColor
1711 \brief the currently selected color in the dialog
1714 void QColorDialog::setCurrentColor(const QColor &color)
1716 Q_D(QColorDialog);
1717 d->setCurrentColor(color.rgb());
1718 d->selectColor(color);
1719 d->setCurrentAlpha(color.alpha());
1721 #ifdef Q_WS_MAC
1722 d->setCurrentQColor(color);
1723 d->setCocoaPanelColor(color);
1724 #endif
1725 if (d->nativeDialogInUse)
1726 qt_guiPlatformPlugin()->colorDialogSetCurrentColor(this, color);
1729 QColor QColorDialog::currentColor() const
1731 Q_D(const QColorDialog);
1732 return d->currentQColor();
1737 Returns the color that the user selected by clicking the \gui{OK}
1738 or equivalent button.
1740 \note This color is not always the same as the color held by the
1741 \l currentColor property since the user can choose different colors
1742 before finally selecting the one to use.
1744 QColor QColorDialog::selectedColor() const
1746 Q_D(const QColorDialog);
1747 return d->selectedQColor;
1751 Sets the given \a option to be enabled if \a on is true;
1752 otherwise, clears the given \a option.
1754 \sa options, testOption()
1756 void QColorDialog::setOption(ColorDialogOption option, bool on)
1758 Q_D(QColorDialog);
1759 if (!(d->opts & option) != !on)
1760 setOptions(d->opts ^ option);
1764 \since 4.5
1766 Returns true if the given \a option is enabled; otherwise, returns
1767 false.
1769 \sa options, setOption()
1771 bool QColorDialog::testOption(ColorDialogOption option) const
1773 Q_D(const QColorDialog);
1774 return (d->opts & option) != 0;
1778 \property QColorDialog::options
1779 \brief the various options that affect the look and feel of the dialog
1781 By default, all options are disabled.
1783 Options should be set before showing the dialog. Setting them while the
1784 dialog is visible is not guaranteed to have an immediate effect on the
1785 dialog (depending on the option and on the platform).
1787 \sa setOption(), testOption()
1789 void QColorDialog::setOptions(ColorDialogOptions options)
1791 Q_D(QColorDialog);
1793 ColorDialogOptions changed = (options ^ d->opts);
1794 if (!changed)
1795 return;
1797 d->opts = options;
1798 d->buttons->setVisible(!(options & NoButtons));
1799 d->showAlpha(options & ShowAlphaChannel);
1802 QColorDialog::ColorDialogOptions QColorDialog::options() const
1804 Q_D(const QColorDialog);
1805 return d->opts;
1809 \enum QColorDialog::ColorDialogOption
1811 \since 4.5
1813 This enum specifies various options that affect the look and feel
1814 of a color dialog.
1816 \value ShowAlphaChannel Allow the user to select the alpha component of a color.
1817 \value NoButtons Don't display \gui{OK} and \gui{Cancel} buttons. (Useful for "live dialogs".)
1818 \value DontUseNativeDialog Use Qt's standard color dialog on the Mac instead of Apple's
1819 native color panel.
1821 \sa options, setOption(), testOption(), windowModality()
1825 \fn void QColorDialog::currentColorChanged(const QColor &color)
1827 This signal is emitted whenever the current color changes in the dialog.
1828 The current color is specified by \a color.
1830 \sa color, colorSelected()
1833 #ifdef Q_WS_MAC
1834 // can only have one Cocoa color panel active
1835 bool QColorDialogPrivate::sharedColorPanelAvailable = true;
1836 #endif
1839 \fn void QColorDialog::colorSelected(const QColor &color);
1841 This signal is emitted just after the user has clicked \gui{OK} to
1842 select a color to use. The chosen color is specified by \a color.
1844 \sa color, currentColorChanged()
1848 Changes the visibility of the dialog. If \a visible is true, the dialog
1849 is shown; otherwise, it is hidden.
1851 void QColorDialog::setVisible(bool visible)
1853 Q_D(QColorDialog);
1855 if (visible){
1856 if (testAttribute(Qt::WA_WState_ExplicitShowHide) && !testAttribute(Qt::WA_WState_Hidden))
1857 return;
1858 } else if (testAttribute(Qt::WA_WState_ExplicitShowHide) && testAttribute(Qt::WA_WState_Hidden))
1859 return;
1861 if (visible)
1862 d->selectedQColor = QColor();
1864 #if defined(Q_WS_MAC)
1865 if (visible) {
1866 if (d->delegate || (QColorDialogPrivate::sharedColorPanelAvailable &&
1867 !(testAttribute(Qt::WA_DontShowOnScreen) || (d->opts & DontUseNativeDialog)))){
1868 d->openCocoaColorPanel(currentColor(), parentWidget(), windowTitle(), options());
1869 QColorDialogPrivate::sharedColorPanelAvailable = false;
1870 setAttribute(Qt::WA_DontShowOnScreen);
1872 setWindowFlags(windowModality() == Qt::WindowModal ? Qt::Sheet : DefaultWindowFlags);
1873 } else {
1874 if (d->delegate) {
1875 d->closeCocoaColorPanel();
1876 setAttribute(Qt::WA_DontShowOnScreen, false);
1879 #else
1881 if (!(d->opts & DontUseNativeDialog) && qt_guiPlatformPlugin()->colorDialogSetVisible(this, visible)) {
1882 d->nativeDialogInUse = true;
1883 // Set WA_DontShowOnScreen so that QDialog::setVisible(visible) below
1884 // updates the state correctly, but skips showing the non-native version:
1885 setAttribute(Qt::WA_DontShowOnScreen);
1886 } else {
1887 d->nativeDialogInUse = false;
1888 setAttribute(Qt::WA_DontShowOnScreen, false);
1890 #endif
1892 QDialog::setVisible(visible);
1896 \overload
1897 \since 4.5
1899 Opens the dialog and connects its colorSelected() signal to the slot specified
1900 by \a receiver and \a member.
1902 The signal will be disconnected from the slot when the dialog is closed.
1904 void QColorDialog::open(QObject *receiver, const char *member)
1906 Q_D(QColorDialog);
1907 connect(this, SIGNAL(colorSelected(QColor)), receiver, member);
1908 d->receiverToDisconnectOnClose = receiver;
1909 d->memberToDisconnectOnClose = member;
1910 QDialog::open();
1914 \fn QColorDialog::open()
1916 \since 4.5
1917 Shows the dialog as a \l{QDialog#Modal Dialogs}{window modal dialog},
1918 returning immediately.
1920 \sa QDialog::open()
1924 \since 4.5
1926 Pops up a modal color dialog with the given window \a title (or "Select Color" if none is
1927 specified), lets the user choose a color, and returns that color. The color is initially set
1928 to \a initial. The dialog is a child of \a parent. It returns an invalid (see
1929 QColor::isValid()) color if the user cancels the dialog.
1931 The \a options argument allows you to customize the dialog.
1933 QColor QColorDialog::getColor(const QColor &initial, QWidget *parent, const QString &title,
1934 ColorDialogOptions options)
1936 QColorDialog dlg(parent);
1937 if (!title.isEmpty())
1938 dlg.setWindowTitle(title);
1939 dlg.setOptions(options);
1940 dlg.setCurrentColor(initial);
1941 dlg.exec();
1942 return dlg.selectedColor();
1946 Pops up a modal color dialog, lets the user choose a color, and
1947 returns that color. The color is initially set to \a initial. The
1948 dialog is a child of \a parent. It returns an invalid (see
1949 QColor::isValid()) color if the user cancels the dialog.
1952 QColor QColorDialog::getColor(const QColor &initial, QWidget *parent)
1954 return getColor(initial, parent, QString(), ColorDialogOptions(0));
1959 \obsolete
1961 Pops up a modal color dialog to allow the user to choose a color
1962 and an alpha channel (transparency) value. The color+alpha is
1963 initially set to \a initial. The dialog is a child of \a parent.
1965 If \a ok is non-null, \e *\a ok is set to true if the user clicked
1966 \gui{OK}, and to false if the user clicked Cancel.
1968 If the user clicks Cancel, the \a initial value is returned.
1970 Use QColorDialog::getColor() instead, passing the
1971 QColorDialog::ShowAlphaChannel option.
1974 QRgb QColorDialog::getRgba(QRgb initial, bool *ok, QWidget *parent)
1976 QColor color(getColor(QColor(initial), parent, QString(), ShowAlphaChannel));
1977 QRgb result = color.isValid() ? color.rgba() : initial;
1978 if (ok)
1979 *ok = color.isValid();
1980 return result;
1984 Destroys the color dialog.
1987 QColorDialog::~QColorDialog()
1989 Q_D(QColorDialog);
1990 #if defined(Q_WS_MAC)
1991 if (d->delegate) {
1992 d->releaseCocoaColorPanelDelegate();
1993 QColorDialogPrivate::sharedColorPanelAvailable = true;
1995 #endif
1997 #ifndef QT_NO_SETTINGS
1998 if (!customSet) {
1999 QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
2000 for (int i = 0; i < 2*8; ++i)
2001 settings.setValue(QLatin1String("Qt/customColors/") + QString::number(i), cusrgb[i]);
2003 #endif
2004 if (d->nativeDialogInUse)
2005 qt_guiPlatformPlugin()->colorDialogDelete(this);
2011 \reimp
2013 void QColorDialog::changeEvent(QEvent *e)
2015 Q_D(QColorDialog);
2016 if (e->type() == QEvent::LanguageChange)
2017 d->retranslateStrings();
2018 QDialog::changeEvent(e);
2022 Closes the dialog and sets its result code to \a result. If this dialog
2023 is shown with exec(), done() causes the local event loop to finish,
2024 and exec() to return \a result.
2026 \sa QDialog::done()
2028 void QColorDialog::done(int result)
2030 Q_D(QColorDialog);
2031 QDialog::done(result);
2032 if (result == Accepted) {
2033 d->selectedQColor = d->currentQColor();
2034 emit colorSelected(d->selectedQColor);
2035 } else {
2036 d->selectedQColor = QColor();
2038 if (d->receiverToDisconnectOnClose) {
2039 disconnect(this, SIGNAL(colorSelected(QColor)),
2040 d->receiverToDisconnectOnClose, d->memberToDisconnectOnClose);
2041 d->receiverToDisconnectOnClose = 0;
2043 d->memberToDisconnectOnClose.clear();
2046 QT_END_NAMESPACE
2048 #include "qcolordialog.moc"
2049 #include "moc_qcolordialog.cpp"
2051 #endif // QT_NO_COLORDIALOG
2054 \fn QColor QColorDialog::getColor(const QColor &init, QWidget *parent, const char *name)
2055 \compat
2059 \fn QRgb QColorDialog::getRgba(QRgb rgba, bool *ok, QWidget *parent, const char *name)
2060 \compat