• Skip to content
  • Skip to link menu
KDE 4.3 API Reference
  • KDE API Reference
  • kdelibs
  • Sitemap
  • Contact Us
 

KDEUI

kcolordialog.cpp

Go to the documentation of this file.
00001 /* This file is part of the KDE libraries
00002     Copyright (C) 1997 Martin Jones (mjones@kde.org)
00003     Copyright (C) 2007 Roberto Raggi (roberto@kdevelop.org)
00004 
00005     This library is free software; you can redistribute it and/or
00006     modify it under the terms of the GNU Library General Public
00007     License as published by the Free Software Foundation; either
00008     version 2 of the License, or (at your option) any later version.
00009 
00010     This library is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013     Library General Public License for more details.
00014 
00015     You should have received a copy of the GNU Library General Public License
00016     along with this library; see the file COPYING.LIB.  If not, write to
00017     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018     Boston, MA 02110-1301, USA.
00019 */
00020 //-----------------------------------------------------------------------------
00021 // KDE color selection dialog.
00022 //
00023 // 1999-09-27 Espen Sand <espensa@online.no>
00024 // KColorDialog is now subclassed from KDialog. I have also extended
00025 // KColorDialog::getColor() so that it contains a parent argument. This
00026 // improves centering capability.
00027 //
00028 // layout management added Oct 1997 by Mario Weilguni
00029 // <mweilguni@sime.com>
00030 //
00031 
00032 #include "kcolordialog.h"
00033 #include "kcolordialog_p.h"
00034 
00035 
00036 #include <stdio.h>
00037 #include <stdlib.h>
00038 
00039 #include <QtGui/QCheckBox>
00040 #include <QtGui/QDesktopWidget>
00041 #include <QtGui/QRadioButton>
00042 #include <QtGui/qdrawutil.h>
00043 #include <QtGui/QActionEvent>
00044 #include <QtCore/QFile>
00045 #include <QtGui/QHeaderView>
00046 #include <QtGui/QImage>
00047 #include <QtGui/QItemDelegate>
00048 #include <QtGui/QLabel>
00049 #include <QtGui/QLayout>
00050 #include <QtGui/QPainter>
00051 #include <QtGui/QPushButton>
00052 #include <QtGui/QScrollBar>
00053 #include <QtGui/QDoubleSpinBox>
00054 #include <QtCore/QTimer>
00055 #include <QtGui/QDoubleValidator>
00056 
00057 #include <kapplication.h>
00058 #include <kcombobox.h>
00059 #include <kconfig.h>
00060 #include <kglobal.h>
00061 #include <kglobalsettings.h>
00062 #include <kiconloader.h>
00063 #include <klineedit.h>
00064 #include <klistwidget.h>
00065 #include <klocale.h>
00066 #include <kmessagebox.h>
00067 #include <kseparator.h>
00068 #include <kstandarddirs.h>
00069 #include <kcolorcollection.h>
00070 
00071 #include "kcolormimedata.h"
00072 #include <config.h>
00073 #include <kdebug.h>
00074 
00075 #include "kselector.h"
00076 #include "kcolorvalueselector.h"
00077 #include "khuesaturationselect.h"
00078 #include "kxyselector.h"
00079 #include <kconfiggroup.h>
00080 
00081 #include <iostream>
00082 
00083 #ifdef Q_WS_X11
00084 #include <X11/Xlib.h>
00085 #include <X11/Xutil.h>
00086 #include <QX11Info>
00087 #include <fixx11h.h>
00088 #endif
00089 
00090 using KDEPrivate::KColorTable;
00091 
00092 struct ColorCollectionNameType {
00093     const char* m_fileName;
00094     const char* m_displayName;
00095 };
00096 
00097 const ColorCollectionNameType colorCollectionName[] = {
00098     { "Recent_Colors", I18N_NOOP2("palette name", "* Recent Colors *") },
00099     { "Custom_Colors", I18N_NOOP2("palette name", "* Custom Colors *") },
00100     { "40.colors",     I18N_NOOP2("palette name", "Forty Colors") },
00101     { "Oxygen.colors", I18N_NOOP2("palette name", "Oxygen Colors") },
00102     { "Rainbow.colors", I18N_NOOP2("palette name", "Rainbow Colors") },
00103     { "Royal.colors",  I18N_NOOP2("palette name", "Royal Colors") },
00104     { "Web.colors",    I18N_NOOP2("palette name", "Web Colors") },
00105     { 0, 0 } // end of data
00106 };
00107 
00108 static const int recentColorIndex = 0;
00109 static const int customColorIndex = 1;
00110 static const int fortyColorIndex = 2;
00111 
00112 class KColorSpinBox : public QSpinBox
00113 {
00114 public:
00115     KColorSpinBox(int minValue, int maxValue, int step, QWidget* parent)
00116             : QSpinBox(parent) {
00117         setRange(minValue, maxValue); setSingleStep(step);
00118     }
00119 
00120 
00121     // Override Qt's braindead auto-selection.
00122     //XXX KDE4 : check this is no more necessary , was disabled to port to Qt4 //mikmak
00123     /*
00124     virtual void valueChange()
00125     {
00126         updateDisplay();
00127         emit valueChanged( value() );
00128         emit valueChanged( currentValueText() );
00129     }*/
00130 
00131 };
00132 
00133 //-----------------------------------------------------------------------------
00134 
00135 class KColorCells::KColorCellsPrivate
00136 {
00137 public:
00138     KColorCellsPrivate(KColorCells *q): q(q) {
00139         inMouse = false;
00140         selected = -1;
00141         shade = false;
00142     }
00143 
00144     KColorCells *q;
00145     QPoint mousePos;
00146     int selected;
00147     bool shade;
00148     bool inMouse;
00149 };
00150 
00151 KColorCells::KColorCells(QWidget *parent, int rows, int cols)
00152         : QTableWidget(parent), d(new KColorCellsPrivate(this))
00153 {
00154     setItemDelegate(new QItemDelegate(this));
00155 
00156     setFrameShape(QFrame::NoFrame);
00157     d->shade = true;
00158     setRowCount(rows);
00159     setColumnCount(cols);
00160 
00161     verticalHeader()->hide();
00162     horizontalHeader()->hide();
00163 
00164     d->selected = 0;
00165     d->inMouse = false;
00166 
00167     // Drag'n'Drop
00168     setAcceptDrops(true);
00169 
00170     setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
00171     setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
00172     viewport()->setBackgroundRole(QPalette::Background);
00173     setBackgroundRole(QPalette::Background);
00174 
00175 
00176     setSelectionMode(QAbstractItemView::SingleSelection);
00177     setDragEnabled(false);
00178 }
00179 
00180 KColorCells::~KColorCells()
00181 {
00182     delete d;
00183 }
00184 
00185 QColor KColorCells::color(int index) const
00186 {
00187     QTableWidgetItem * tmpItem = item(index / columnCount(), index % columnCount());
00188 
00189     if (tmpItem != 0)
00190         return tmpItem->data(Qt::BackgroundRole).value<QColor>();
00191 
00192     return QColor();
00193 }
00194 
00195 int KColorCells::count() const
00196 {
00197     return rowCount() * columnCount();
00198 }
00199 
00200 void KColorCells::setShading(bool _shade)
00201 {
00202     d->shade = _shade;
00203 }
00204 
00205 void KColorCells::setAcceptDrags(bool _acceptDrags)
00206 {
00207     this->setDragEnabled(_acceptDrags);
00208 }
00209 
00210 void KColorCells::setSelected(int index)
00211 {
00212     Q_ASSERT(index >= 0 && index < count());
00213 
00214     d->selected = index;
00215 }
00216 
00217 int KColorCells::selectedIndex() const
00218 {
00219     return d->selected;
00220 }
00221 
00222 void KColorCells::setColor(int column, const QColor &color)
00223 {
00224     const int tableRow = column / columnCount();
00225     const int tableColumn = column % columnCount();
00226 
00227     Q_ASSERT(tableRow >= 0 && tableRow < rowCount());
00228     Q_ASSERT(tableColumn >= 0 && tableColumn < columnCount());
00229 
00230     QTableWidgetItem * tableItem = item(tableRow, tableColumn);
00231 
00232     if (tableItem == 0) {
00233         tableItem = new QTableWidgetItem();
00234         setItem(tableRow, tableColumn, tableItem);
00235     }
00236 
00237     tableItem->setData(Qt::BackgroundRole , color);
00238 }
00239 
00240 /*void KColorCells::paintCell( QPainter *painter, int row, int col )
00241 {
00242     painter->setRenderHint( QPainter::Antialiasing , true );
00243 
00244  QBrush brush;
00245  int w = 1;
00246 
00247  if (shade)
00248  {
00249   qDrawShadePanel( painter, 1, 1, cellWidth()-2,
00250        cellHeight()-2, palette(), true, 1, &brush );
00251   w = 2;
00252  }
00253  QColor color = colors[ row * numCols() + col ];
00254  if (!color.isValid())
00255  {
00256   if (!shade) return;
00257   color = palette().color(backgroundRole());
00258  }
00259 
00260  const QRect colorRect( w, w, cellWidth()-w*2, cellHeight()-w*2 );
00261  painter->fillRect( colorRect, color );
00262 
00263  if ( row * numCols() + col == selected ) {
00264   painter->setPen( qGray(color.rgb())>=127 ? Qt::black : Qt::white );
00265   painter->drawLine( colorRect.topLeft(), colorRect.bottomRight() );
00266   painter->drawLine( colorRect.topRight(), colorRect.bottomLeft() );
00267  }
00268 }*/
00269 
00270 void KColorCells::resizeEvent(QResizeEvent*)
00271 {
00272     // According to the Qt doc:
00273     //   If you need to set the width of a given column to a fixed value, call
00274     //   QHeaderView::resizeSection() on the table's {horizontal,vertical}
00275     //   header.
00276     // Therefore we iterate over each row and column and set the header section
00277     // size, as the sizeHint does indeed appear to be ignored in favor of a
00278     // minimum size that is larger than what we want.
00279     for (int index = 0 ; index < columnCount() ; index++)
00280         horizontalHeader()->resizeSection(index, sizeHintForColumn(index));
00281     for (int index = 0 ; index < rowCount() ; index++)
00282         verticalHeader()->resizeSection(index, sizeHintForRow(index));
00283 }
00284 
00285 int KColorCells::sizeHintForColumn(int /*column*/) const
00286 {
00287     return width() / columnCount() ;
00288 }
00289 
00290 int KColorCells::sizeHintForRow(int /*row*/) const
00291 {
00292     return height() / rowCount() ;
00293 }
00294 
00295 void KColorCells::mousePressEvent(QMouseEvent *e)
00296 {
00297     d->inMouse = true;
00298     d->mousePos = e->pos();
00299 
00300     QTableWidget::mousePressEvent(e);
00301 }
00302 
00303 
00304 int KColorCells::positionToCell(const QPoint &pos, bool ignoreBorders) const
00305 {
00306     //TODO ignoreBorders not yet handled
00307     Q_UNUSED(ignoreBorders)
00308 
00309     QTableWidgetItem* tableItem = itemAt(pos);
00310 
00311     if (!tableItem)
00312         return -1;
00313 
00314     const int itemRow = row(tableItem);
00315     const int itemColumn = column(tableItem);
00316     int cell = itemRow * columnCount() + itemColumn;
00317 
00318     /*if (!ignoreBorders)
00319     {
00320        int border = 2;
00321        int x = pos.x() - col * cellWidth();
00322        int y = pos.y() - row * cellHeight();
00323        if ( (x < border) || (x > cellWidth()-border) ||
00324             (y < border) || (y > cellHeight()-border))
00325           return -1;
00326     }*/
00327 
00328     return cell;
00329 }
00330 
00331 void KColorCells::mouseMoveEvent(QMouseEvent *e)
00332 {
00333     if (this->dragEnabled() || this->acceptDrops()) {
00334         if (!(e->buttons() & Qt::LeftButton)) return;
00335 
00336         if (d->inMouse) {
00337             int delay = KGlobalSettings::dndEventDelay();
00338             if (e->x() > d->mousePos.x() + delay || e->x() < d->mousePos.x() - delay ||
00339                     e->y() > d->mousePos.y() + delay || e->y() < d->mousePos.y() - delay) {
00340                 // Drag color object
00341                 QTableWidgetItem * tableItem = itemAt(d->mousePos);
00342 
00343                 if (tableItem) {
00344                     QVariant var = tableItem->data(Qt::BackgroundRole);
00345                     QColor tmpCol = var.value<QColor>();
00346                     if (tmpCol.isValid())
00347                         KColorMimeData::createDrag(tmpCol, this)->start();
00348                 }
00349             }
00350         }
00351     } else
00352         QTableWidget::mouseMoveEvent(e);
00353 }
00354 
00355 void KColorCells::dragEnterEvent(QDragEnterEvent *event)
00356 {
00357     kDebug() << "KColorCells::dragEnterEvent() acceptDrags="
00358     << this->dragEnabled()
00359     << " canDecode=" << KColorMimeData::canDecode(event->mimeData())
00360     << endl;
00361     event->setAccepted(this->dragEnabled() && KColorMimeData::canDecode(event->mimeData()));
00362 }
00363 
00364 // Reimplemented to override QTableWidget's override.  Else dropping doesn't work.
00365 void KColorCells::dragMoveEvent(QDragMoveEvent *event)
00366 {
00367     kDebug() << "KColorCells::dragMoveEvent() acceptDrags="
00368     << this->dragEnabled()
00369     << " canDecode=" << KColorMimeData::canDecode(event->mimeData())
00370     << endl;
00371     event->setAccepted(this->dragEnabled() && KColorMimeData::canDecode(event->mimeData()));
00372 }
00373 
00374 void KColorCells::dropEvent(QDropEvent *event)
00375 {
00376     QColor c = KColorMimeData::fromMimeData(event->mimeData());
00377 
00378     kDebug() << "KColorCells::dropEvent() color.isValid=" << c.isValid();
00379     if (c.isValid()) {
00380         QTableWidgetItem * tableItem = itemAt(event->pos());
00381 
00382         if (tableItem)
00383             tableItem->setData(Qt::BackgroundRole , c);
00384     }
00385 }
00386 
00387 void KColorCells::mouseReleaseEvent(QMouseEvent *e)
00388 {
00389     if (selectionMode() != QAbstractItemView::NoSelection) {
00390         int cell = positionToCell(d->mousePos);
00391         int currentCell = positionToCell(e->pos());
00392 
00393         // If we release the mouse in another cell and we don't have
00394         // a drag we should ignore this event.
00395         if (currentCell != cell)
00396             cell = -1;
00397 
00398         if ((cell != -1) && (d->selected != cell)) {
00399             d->selected = cell;
00400 
00401             const int newRow = cell / columnCount();
00402             const int newColumn = cell % columnCount();
00403 
00404             clearSelection(); // we do not want old violet selected cells
00405 
00406             item(newRow, newColumn)->setSelected(true);
00407         }
00408 
00409         d->inMouse = false;
00410         if (cell != -1)
00411             emit colorSelected(cell , color(cell));
00412     }
00413 
00414     QTableWidget::mouseReleaseEvent(e);
00415 }
00416 
00417 void KColorCells::mouseDoubleClickEvent(QMouseEvent * /*e*/)
00418 {
00419     int cell = positionToCell(d->mousePos);
00420 
00421     if (cell != -1)
00422         emit colorDoubleClicked(cell , color(cell));
00423 }
00424 
00425 
00426 //-----------------------------------------------------------------------------
00427 
00428 class KColorPatch::KColorPatchPrivate
00429 {
00430 public:
00431     KColorPatchPrivate(KColorPatch *q): q(q) {}
00432 
00433     KColorPatch *q;
00434     QColor color;
00435 };
00436 
00437 KColorPatch::KColorPatch(QWidget *parent) : QFrame(parent), d(new KColorPatchPrivate(this))
00438 {
00439     setFrameStyle(QFrame::Panel | QFrame::Sunken);
00440     setAcceptDrops(true);
00441     setMinimumSize(12, 12);
00442 }
00443 
00444 KColorPatch::~KColorPatch()
00445 {
00446     delete d;
00447 }
00448 
00449 void KColorPatch::setColor(const QColor &col)
00450 {
00451     d->color.setRgb(col.rgb());
00452 
00453     update();
00454 }
00455 
00456 void KColorPatch::paintEvent(QPaintEvent* pe)
00457 {
00458     QFrame::paintEvent(pe);
00459     QPainter painter(this);
00460     painter.setPen(d->color);
00461     painter.setBrush(QBrush(d->color));
00462     painter.drawRect(contentsRect());
00463 }
00464 
00465 void KColorPatch::mouseMoveEvent(QMouseEvent *e)
00466 {
00467     // Drag color object
00468     if (!(e->buttons() & Qt::LeftButton))
00469         return;
00470     KColorMimeData::createDrag(d->color, this)->start();
00471 }
00472 
00473 void KColorPatch::dragEnterEvent(QDragEnterEvent *event)
00474 {
00475     event->setAccepted(KColorMimeData::canDecode(event->mimeData()));
00476 }
00477 
00478 void KColorPatch::dropEvent(QDropEvent *event)
00479 {
00480     QColor c = KColorMimeData::fromMimeData(event->mimeData());
00481     if (c.isValid()) {
00482         setColor(c);
00483         emit colorChanged(c);
00484     }
00485 }
00486 
00487 class KColorTable::KColorTablePrivate
00488 {
00489 public:
00490     KColorTablePrivate(KColorTable *q): q(q) {}
00491 
00492     void slotColorCellSelected(int index , const QColor&);
00493     void slotColorCellDoubleClicked(int index , const QColor&);
00494     void slotColorTextSelected(const QString &colorText);
00495     void slotSetColors(const QString &_collectionName);
00496     void slotShowNamedColorReadError(void);
00497 
00498     KColorTable *q;
00499     QString i18n_namedColors;
00500     KComboBox *combo;
00501     KColorCells *cells;
00502     QScrollArea *sv;
00503     KListWidget *mNamedColorList;
00504     KColorCollection *mPalette;
00505     int mMinWidth;
00506     int mCols;
00507     QMap<QString, QColor> m_namedColorMap;
00508 };
00509 
00510 KColorTable::KColorTable(QWidget *parent, int minWidth, int cols)
00511         : QWidget(parent), d(new KColorTablePrivate(this))
00512 {
00513     d->cells = 0;
00514     d->mPalette = 0;
00515     d->mMinWidth = minWidth;
00516     d->mCols = cols;
00517     d->i18n_namedColors  = i18n("Named Colors");
00518 
00519     QStringList diskPaletteList = KColorCollection::installedCollections();
00520     QStringList paletteList;
00521 
00522     // We must replace the untranslated file names by translate names (of course only for KDE's standard palettes)
00523     for (int i = 0; colorCollectionName[i].m_fileName; ++i) {
00524         diskPaletteList.removeAll(colorCollectionName[i].m_fileName);
00525         paletteList.append(i18nc("palette name", colorCollectionName[i].m_displayName));
00526     }
00527     paletteList += diskPaletteList;
00528     paletteList.append(d->i18n_namedColors);
00529 
00530     QVBoxLayout *layout = new QVBoxLayout(this);
00531 
00532     d->combo = new KComboBox(this);
00533     d->combo->setEditable(false);
00534     d->combo->addItems(paletteList);
00535     layout->addWidget(d->combo);
00536 
00537     d->sv = new QScrollArea(this);
00538     QSize cellSize = QSize(d->mMinWidth, 120);
00539     d->sv->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
00540     d->sv->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
00541     QSize minSize = QSize(d->sv->verticalScrollBar()->sizeHint().width(), 0);
00542     minSize += QSize(d->sv->frameWidth() * 2, 0);
00543     minSize += QSize(cellSize);
00544     d->sv->setFixedSize(minSize);
00545     layout->addWidget(d->sv);
00546 
00547     d->mNamedColorList = new KListWidget(this);
00548     d->mNamedColorList->setObjectName("namedColorList");
00549     d->mNamedColorList->setFixedSize(minSize);
00550     d->mNamedColorList->hide();
00551     layout->addWidget(d->mNamedColorList);
00552     connect(d->mNamedColorList, SIGNAL(currentTextChanged(const QString &)),
00553             this, SLOT(slotColorTextSelected(const QString &)));
00554 
00555     setFixedSize(sizeHint());
00556     connect(d->combo, SIGNAL(activated(const QString &)),
00557             this, SLOT(slotSetColors(const QString &)));
00558 }
00559 
00560 KColorTable::~KColorTable()
00561 {
00562     delete d->mPalette;
00563     delete d;
00564 }
00565 
00566 QString
00567 KColorTable::name() const
00568 {
00569     return d->combo->currentText();
00570 }
00571 
00572 
00573 static const char * const *namedColorFilePath(void)
00574 {
00575     //
00576     // 2000-02-05 Espen Sand.
00577     // Add missing filepaths here. Make sure the last entry is 0, 0!
00578     //
00579     // 2009-06-16 Pino Toscano
00580     //
00581     // You can specify either absolute paths or relative locations
00582     // wrt KStandardDirs resources. In either way, there should be two
00583     // "strings" for each path.
00584     // - absolute path: specify it directly, then add 0 as second item
00585     //   * example: "/usr/share/X11/rgb.txt", 0,
00586     // - KStandardDirs location: specify the filename as first item,
00587     //   then add the resource as second
00588     //   * example: "kdeui/rgb.txt", "data",
00589     //
00590     static const char * const path[] = {
00591 #ifdef Q_WS_X11
00592 #ifdef X11_RGBFILE
00593         X11_RGBFILE, 0,
00594 #endif
00595         "/usr/share/X11/rgb.txt", 0,
00596         "/usr/X11R6/lib/X11/rgb.txt", 0,
00597         "/usr/openwin/lib/X11/rgb.txt", 0, // for Solaris.
00598 #else /* systems without X11 */
00599         "kdeui/rgb.txt", "data",
00600 #endif
00601         0, 0
00602     };
00603     return path;
00604 }
00605 
00606 
00607 
00608 
00609 void
00610 KColorTable::readNamedColor(void)
00611 {
00612     if (d->mNamedColorList->count() != 0) {
00613         return; // Strings already present
00614     }
00615 
00616     KGlobal::locale()->insertCatalog("kdelibs_colors4");
00617 
00618     //
00619     // Code somewhat inspired by KColorCollection.
00620     //
00621 
00622     const char * const *path = namedColorFilePath();
00623     for (int i = 0; path[i]; i += 2) {
00624         QString file;
00625         if (path[i + 1]) {
00626             file = KStandardDirs::locate(path[i + 1], QString::fromLatin1(path[i]));
00627             if (file.isEmpty()) {
00628                 continue;
00629             }
00630         } else {
00631             file = QString::fromLatin1(path[i]);
00632         }
00633 
00634         QFile paletteFile(file);
00635         if (!paletteFile.open(QIODevice::ReadOnly)) {
00636             continue;
00637         }
00638 
00639         QByteArray line;
00640         QStringList list;
00641         while (!paletteFile.atEnd()) {
00642             line = paletteFile.readLine();
00643 
00644             int red, green, blue;
00645             int pos = 0;
00646 
00647             if (sscanf(line, "%d %d %d%n", &red, &green, &blue, &pos) == 3) {
00648                 //
00649                 // Remove duplicates. Every name with a space and every name
00650                 // that start with "gray".
00651                 //
00652                 QString name = line.mid(pos).trimmed();
00653                 QByteArray s1 = line.mid(pos);
00654                 if (name.isNull() || name.indexOf(' ') != -1 ||
00655                         name.indexOf("gray") != -1 ||  name.indexOf("grey") != -1) {
00656                     continue;
00657                 }
00658 
00659                 const QColor color(red, green, blue);
00660                 if (color.isValid()) {
00661                     const QString colorName(i18nc("color", name.toLatin1().data()));
00662                     list.append(colorName);
00663                     d->m_namedColorMap[ colorName ] = color;
00664                 }
00665             }
00666         }
00667 
00668         list.sort();
00669         d->mNamedColorList->addItems(list);
00670         break;
00671     }
00672 
00673     if (d->mNamedColorList->count() == 0) {
00674         //
00675         // Give the error dialog box a chance to center above the
00676         // widget (or dialog). If we had displayed it now we could get a
00677         // situation where the (modal) error dialog box pops up first
00678         // preventing the real dialog to become visible until the
00679         // error dialog box is removed (== bad UI).
00680         //
00681         QTimer::singleShot(10, this, SLOT(slotShowNamedColorReadError()));
00682     }
00683 }
00684 
00685 
00686 void
00687 KColorTable::KColorTablePrivate::slotShowNamedColorReadError(void)
00688 {
00689     if (mNamedColorList->count() == 0) {
00690         QString msg = i18n(""
00691                            "Unable to read X11 RGB color strings. The following "
00692                            "file location(s) were examined:\n");
00693 
00694         const char * const *path = namedColorFilePath();
00695         for (int i = 0; path[i]; i += 2) {
00696             if (path[i + 1]) {
00697                 msg += QLatin1String(path[i + 1]) + ", " + QString::fromLatin1(path[i]);
00698             } else {
00699                 msg += QLatin1String(path[i]);
00700             }
00701             msg += '\n';
00702         }
00703         KMessageBox::sorry(q, msg);
00704     }
00705 }
00706 
00707 
00708 //
00709 // 2000-02-12 Espen Sand
00710 // Set the color in two steps. The setColors() slot will not emit a signal
00711 // with the current color setting. The reason is that setColors() is used
00712 // by the color selector dialog on startup. In the color selector dialog
00713 // we normally want to display a startup color which we specify
00714 // when the dialog is started. The slotSetColors() slot below will
00715 // set the palette and then use the information to emit a signal with the
00716 // new color setting. It is only used by the combobox widget.
00717 //
00718 void
00719 KColorTable::KColorTablePrivate::slotSetColors(const QString &_collectionName)
00720 {
00721     q->setColors(_collectionName);
00722     if (mNamedColorList->count() && mNamedColorList->isVisible()) {
00723         int item = mNamedColorList->currentRow();
00724         mNamedColorList->setCurrentRow(item < 0 ? 0 : item);
00725         slotColorTextSelected(mNamedColorList->currentItem()->text());
00726     } else {
00727         slotColorCellSelected(0, QColor()); // FIXME: We need to save the current value!!
00728     }
00729 }
00730 
00731 
00732 void
00733 KColorTable::setColors(const QString &_collectionName)
00734 {
00735     QString collectionName(_collectionName);
00736 
00737     if (d->combo->currentText() != collectionName) {
00738         bool found = false;
00739         for (int i = 0; i < d->combo->count(); i++) {
00740             if (d->combo->itemText(i) == collectionName) {
00741                 d->combo->setCurrentIndex(i);
00742                 found = true;
00743                 break;
00744             }
00745         }
00746         if (!found) {
00747             d->combo->addItem(collectionName);
00748             d->combo->setCurrentIndex(d->combo->count() - 1);
00749         }
00750     }
00751 
00752     // We must again find the file name of the palette from the eventual translation
00753     for (int i = 0; colorCollectionName[i].m_fileName; ++i) {
00754         if (collectionName == i18nc("palette name", colorCollectionName[i].m_displayName)) {
00755             collectionName = colorCollectionName[i].m_fileName;
00756             break;
00757         }
00758     }
00759 
00760 
00761     //
00762     // 2000-02-12 Espen Sand
00763     // The palette mode "i18n_namedColors" does not use the KColorCollection
00764     // class. In fact, 'mPalette' and 'cells' are 0 when in this mode. The reason
00765     // for this is maninly that KColorCollection reads from and writes to files
00766     // using "locate()". The colors used in "i18n_namedColors" mode comes from
00767     // the X11 diretory and is not writable. I don't think this fit in
00768     // KColorCollection.
00769     //
00770     if (!d->mPalette || d->mPalette->name() != collectionName) {
00771         if (collectionName == d->i18n_namedColors) {
00772             d->sv->hide();
00773             d->mNamedColorList->show();
00774             readNamedColor();
00775 
00776             delete d->cells; d->cells = 0;
00777             delete d->mPalette; d->mPalette = 0;
00778         } else {
00779             d->mNamedColorList->hide();
00780             d->sv->show();
00781 
00782             delete d->cells;
00783             delete d->mPalette;
00784             d->mPalette = new KColorCollection(collectionName);
00785             int rows = (d->mPalette->count() + d->mCols - 1) / d->mCols;
00786             if (rows < 1) rows = 1;
00787             d->cells = new KColorCells(d->sv->viewport(), rows, d->mCols);
00788             d->cells->setShading(false);
00789             d->cells->setAcceptDrags(false);
00790             QSize cellSize = QSize(d->mMinWidth, d->mMinWidth * rows / d->mCols);
00791             d->cells->setFixedSize(cellSize);
00792             for (int i = 0; i < d->mPalette->count(); i++) {
00793                 d->cells->setColor(i, d->mPalette->color(i));
00794             }
00795             connect(d->cells, SIGNAL(colorSelected(int , const QColor&)),
00796                     SLOT(slotColorCellSelected(int , const QColor&)));
00797             connect(d->cells, SIGNAL(colorDoubleClicked(int , const QColor&)),
00798                     SLOT(slotColorCellDoubleClicked(int , const QColor&)));
00799             d->sv->setWidget(d->cells);
00800             d->cells->show();
00801 
00802             //d->sv->updateScrollBars();
00803         }
00804     }
00805 }
00806 
00807 
00808 
00809 void
00810 KColorTable::KColorTablePrivate::slotColorCellSelected(int index , const QColor& /*color*/)
00811 {
00812     if (!mPalette || (index >= mPalette->count()))
00813         return;
00814     emit q->colorSelected(mPalette->color(index), mPalette->name(index));
00815 }
00816 
00817 void
00818 KColorTable::KColorTablePrivate::slotColorCellDoubleClicked(int index , const QColor& /*color*/)
00819 {
00820     if (!mPalette || (index >= mPalette->count()))
00821         return;
00822     emit q->colorDoubleClicked(mPalette->color(index), mPalette->name(index));
00823 }
00824 
00825 
00826 void
00827 KColorTable::KColorTablePrivate::slotColorTextSelected(const QString &colorText)
00828 {
00829     emit q->colorSelected(m_namedColorMap[ colorText ], colorText);
00830 }
00831 
00832 
00833 void
00834 KColorTable::addToCustomColors(const QColor &color)
00835 {
00836     setColors(i18nc("palette name", colorCollectionName[customColorIndex].m_displayName));
00837     d->mPalette->addColor(color);
00838     d->mPalette->save();
00839     delete d->mPalette;
00840     d->mPalette = 0;
00841     setColors(i18nc("palette name", colorCollectionName[customColorIndex].m_displayName));
00842 }
00843 
00844 void
00845 KColorTable::addToRecentColors(const QColor &color)
00846 {
00847     //
00848     // 2000-02-12 Espen Sand.
00849     // The 'mPalette' is always 0 when current mode is i18n_namedColors
00850     //
00851     bool recentIsSelected = false;
00852     if (d->mPalette && d->mPalette->name() == colorCollectionName[ recentColorIndex ].m_fileName) {
00853         delete d->mPalette;
00854         d->mPalette = 0;
00855         recentIsSelected = true;
00856     }
00857     KColorCollection *recentPal = new KColorCollection(colorCollectionName[ recentColorIndex ].m_fileName);
00858     if (recentPal->findColor(color) == -1) {
00859         recentPal->addColor(color);
00860         recentPal->save();
00861     }
00862     delete recentPal;
00863     if (recentIsSelected)
00864         setColors(i18nc("palette name", colorCollectionName[ recentColorIndex ].m_displayName));
00865 }
00866 
00867 class KCDPickerFilter;
00868 
00869 class KColorDialog::KColorDialogPrivate
00870 {
00871 public:
00872     KColorDialogPrivate(KColorDialog *q): q(q) {}
00873 
00874     void setRgbEdit(const QColor &col);
00875     void setHsvEdit(const QColor &col);
00876     void setHtmlEdit(const QColor &col);
00877     void _setColor(const QColor &col, const QString &name = QString());
00878     void showColor(const QColor &color, const QString &name);
00879 
00880     void slotRGBChanged(void);
00881     void slotHSVChanged(void);
00882     void slotHtmlChanged(void);
00883     void slotHSChanged(int, int);
00884     void slotVChanged(int);
00885 
00886     void setHMode();
00887     void setSMode();
00888     void setVMode();
00889     void setRMode();
00890     void setGMode();
00891     void setBMode();
00892 
00893     void updateModeButtons();
00894 
00895     void slotColorSelected(const QColor &col);
00896     void slotColorSelected(const QColor &col, const QString &name);
00897     void slotColorDoubleClicked(const QColor &col, const QString &name);
00898     void slotColorPicker();
00899     void slotAddToCustomColors();
00900     void slotDefaultColorClicked();
00904     void slotWriteSettings();
00905 
00909     KColorChooserMode chooserMode();
00910 
00914     void setChooserMode(KColorChooserMode c);
00915 
00916     KColorDialog *q;
00917     KColorTable *table;
00918     QString originalPalette;
00919     bool bRecursion;
00920     bool bEditRgb;
00921     bool bEditHsv;
00922     bool bEditHtml;
00923     bool bColorPicking;
00924     QLabel *colorName;
00925     KLineEdit *htmlName;
00926     KColorSpinBox *hedit;
00927     KColorSpinBox *sedit;
00928     KColorSpinBox *vedit;
00929     KColorSpinBox *redit;
00930     KColorSpinBox *gedit;
00931     KColorSpinBox *bedit;
00932     QRadioButton *hmode;
00933     QRadioButton *smode;
00934     QRadioButton *vmode;
00935     QRadioButton *rmode;
00936     QRadioButton *gmode;
00937     QRadioButton *bmode;
00938 
00939     KColorPatch *patch;
00940     KColorPatch *comparePatch;
00941 
00942     KColorChooserMode _mode;
00943 
00944     KHueSaturationSelector *hsSelector;
00945     KColorCollection *palette;
00946     KColorValueSelector *valuePal;
00947     QVBoxLayout* l_right;
00948     QGridLayout* tl_layout;
00949     QCheckBox *cbDefaultColor;
00950     QColor defaultColor;
00951     QColor selColor;
00952 #ifdef Q_WS_X11
00953     KCDPickerFilter* filter;
00954 #endif
00955 };
00956 
00957 #ifdef Q_WS_X11
00958 class KCDPickerFilter: public QWidget
00959 {
00960 public:
00961     KCDPickerFilter(QWidget* parent): QWidget(parent) {}
00962 
00963     virtual bool x11Event(XEvent* event) {
00964         if (event->type == ButtonRelease) {
00965             QMouseEvent e(QEvent::MouseButtonRelease, QPoint(),
00966                           QPoint(event->xmotion.x_root, event->xmotion.y_root) , Qt::NoButton, Qt::NoButton, Qt::NoModifier);
00967             QApplication::sendEvent(parentWidget(), &e);
00968             return true;
00969         } else return false;
00970     }
00971 };
00972 
00973 #endif
00974 
00975 
00976 KColorDialog::KColorDialog(QWidget *parent, bool modal)
00977         : KDialog(parent), d(new KColorDialogPrivate(this))
00978 {
00979     setCaption(i18n("Select Color"));
00980     setButtons(modal ? Ok | Cancel : Close);
00981     showButtonSeparator(true);
00982     setModal(modal);
00983     d->bRecursion = true;
00984     d->bColorPicking = false;
00985 #ifdef Q_WS_X11
00986     d->filter = 0;
00987 #endif
00988     d->cbDefaultColor = 0L;
00989     d->_mode = ChooserClassic;
00990     connect(this, SIGNAL(okClicked(void)), this, SLOT(slotWriteSettings(void)));
00991     connect(this, SIGNAL(closeClicked(void)), this, SLOT(slotWriteSettings(void)));
00992 
00993     QLabel *label;
00994 
00995     //
00996     // Create the top level page and its layout
00997     //
00998     QWidget *page = new QWidget(this);
00999     setMainWidget(page);
01000 
01001     QGridLayout *tl_layout = new QGridLayout(page);
01002     tl_layout->setMargin(0);
01003     d->tl_layout = tl_layout;
01004     tl_layout->addItem(new QSpacerItem(spacingHint()*2, 0), 0, 1);
01005 
01006     //
01007     // the more complicated part: the left side
01008     // add a V-box
01009     //
01010     QVBoxLayout *l_left = new QVBoxLayout();
01011     tl_layout->addLayout(l_left, 0, 0);
01012 
01013     //
01014     // add a H-Box for the XY-Selector and a grid for the
01015     // entry fields
01016     //
01017     QHBoxLayout *l_ltop = new QHBoxLayout();
01018     l_left->addLayout(l_ltop);
01019 
01020     // a little space between
01021     l_left->addSpacing(10); // FIXME: remove hardcoded values
01022 
01023     QGridLayout *l_lbot = new QGridLayout();
01024     l_left->addLayout(l_lbot);
01025 
01026     //
01027     // the palette and value selector go into the H-box
01028     //
01029     d->hsSelector = new KHueSaturationSelector(page);
01030     d->hsSelector->setMinimumSize(256, 256);
01031     l_ltop->addWidget(d->hsSelector, 8);
01032     connect(d->hsSelector, SIGNAL(valueChanged(int, int)),
01033             SLOT(slotHSChanged(int, int)));
01034 
01035     d->valuePal = new KColorValueSelector(page);
01036     d->valuePal->setMinimumSize(26, 70);
01037     d->valuePal->setIndent(false);
01038     d->valuePal->setArrowDirection(Qt::RightArrow);
01039     l_ltop->addWidget(d->valuePal, 1);
01040     connect(d->valuePal, SIGNAL(valueChanged(int)),
01041             SLOT(slotVChanged(int)));
01042 
01043     //
01044     // add the HSV fields
01045     //
01046     l_lbot->setColumnStretch(2, 10);
01047 
01048     d->hmode = new QRadioButton(i18n("Hue:"), page);
01049     l_lbot->addWidget(d->hmode, 0, 0);
01050 
01051     d->hedit = new KColorSpinBox(0, 359, 1, page);
01052     l_lbot->addWidget(d->hedit, 0, 1);
01053     connect(d->hedit, SIGNAL(valueChanged(int)),
01054             SLOT(slotHSVChanged()));
01055     connect(d->hmode, SIGNAL(clicked()),
01056             SLOT(setHMode()));
01057 
01058     d->smode = new QRadioButton(i18n("Saturation:"), page);
01059     l_lbot->addWidget(d->smode, 1, 0);
01060 
01061     d->sedit = new KColorSpinBox(0, 255, 1, page);
01062     l_lbot->addWidget(d->sedit, 1, 1);
01063     connect(d->sedit, SIGNAL(valueChanged(int)),
01064             SLOT(slotHSVChanged()));
01065     connect(d->smode, SIGNAL(clicked()),
01066             SLOT(setSMode()));
01067 
01068     d->vmode = new QRadioButton(i18nc("This is the V of HSV", "Value:"), page);
01069     l_lbot->addWidget(d->vmode, 2, 0);
01070 
01071     d->vedit = new KColorSpinBox(0, 255, 1, page);
01072     l_lbot->addWidget(d->vedit, 2, 1);
01073     connect(d->vedit, SIGNAL(valueChanged(int)),
01074             SLOT(slotHSVChanged()));
01075     connect(d->vmode, SIGNAL(clicked()),
01076             SLOT(setVMode()));
01077 
01078 
01079     //
01080     // add the RGB fields
01081     //
01082     d->rmode = new QRadioButton(i18n("Red:"), page);
01083     l_lbot->addWidget(d->rmode, 0, 3);
01084     d->redit = new KColorSpinBox(0, 255, 1, page);
01085     l_lbot->addWidget(d->redit, 0, 4);
01086     connect(d->redit, SIGNAL(valueChanged(int)),
01087             SLOT(slotRGBChanged()));
01088     connect(d->rmode, SIGNAL(clicked()),
01089             SLOT(setRMode()));
01090 
01091     d->gmode = new QRadioButton(i18n("Green:"), page);
01092     l_lbot->addWidget(d->gmode, 1, 3);
01093 
01094     d->gedit = new KColorSpinBox(0, 255, 1, page);
01095     l_lbot->addWidget(d->gedit, 1, 4);
01096     connect(d->gedit, SIGNAL(valueChanged(int)),
01097             SLOT(slotRGBChanged()));
01098     connect(d->gmode, SIGNAL(clicked()),
01099             SLOT(setGMode()));
01100 
01101     d->bmode = new QRadioButton(i18n("Blue:"), page);
01102     l_lbot->addWidget(d->bmode, 2, 3);
01103 
01104     d->bedit = new KColorSpinBox(0, 255, 1, page);
01105     l_lbot->addWidget(d->bedit, 2, 4);
01106     connect(d->bedit, SIGNAL(valueChanged(int)),
01107             SLOT(slotRGBChanged()));
01108     connect(d->bmode, SIGNAL(clicked()),
01109             SLOT(setBMode()));
01110 
01111     //
01112     // add a layout for the right side
01113     //
01114     d->l_right = new QVBoxLayout;
01115     tl_layout->addLayout(d->l_right, 0, 2);
01116 
01117     //
01118     // Add the palette table
01119     //
01120     d->table = new KColorTable(page);
01121     d->l_right->addWidget(d->table, 10);
01122 
01123     connect(d->table, SIGNAL(colorSelected(const QColor &, const QString &)),
01124             SLOT(slotColorSelected(const QColor &, const QString &)));
01125 
01126     connect(
01127         d->table,
01128         SIGNAL(colorDoubleClicked(const QColor &, const QString &)),
01129         SLOT(slotColorDoubleClicked(const QColor &, const QString &))
01130     );
01131     // Store the default value for saving time.
01132     d->originalPalette = d->table->name();
01133 
01134     //
01135     // a little space between
01136     //
01137     d->l_right->addSpacing(10);
01138 
01139     QHBoxLayout *l_hbox = new QHBoxLayout();
01140     d->l_right->addItem(l_hbox);
01141 
01142     //
01143     // The add to custom colors button
01144     //
01145     QPushButton *addButton = new QPushButton(page);
01146     addButton->setText(i18n("&Add to Custom Colors"));
01147     l_hbox->addWidget(addButton, 0, Qt::AlignLeft);
01148     connect(addButton, SIGNAL(clicked()), SLOT(slotAddToCustomColors()));
01149 
01150     //
01151     // The color picker button
01152     //
01153     QPushButton* button = new QPushButton(page);
01154     button->setIcon(KIcon("color-picker"));
01155     int commonHeight = addButton->sizeHint().height();
01156     button->setFixedSize(commonHeight, commonHeight);
01157     l_hbox->addWidget(button, 0, Qt::AlignHCenter);
01158     connect(button, SIGNAL(clicked()), SLOT(slotColorPicker()));
01159 
01160     //
01161     // a little space between
01162     //
01163     d->l_right->addSpacing(10);
01164 
01165     //
01166     // and now the entry fields and the patch (=colored box)
01167     //
01168     QGridLayout *l_grid = new QGridLayout();
01169     d->l_right->addLayout(l_grid);
01170 
01171     l_grid->setColumnStretch(2, 1);
01172 
01173     label = new QLabel(page);
01174     label->setText(i18n("Name:"));
01175     l_grid->addWidget(label, 0, 1, Qt::AlignLeft);
01176 
01177     d->colorName = new QLabel(page);
01178     l_grid->addWidget(d->colorName, 0, 2, Qt::AlignLeft);
01179 
01180     label = new QLabel(page);
01181     label->setText(i18n("HTML:"));
01182     l_grid->addWidget(label, 1, 1, Qt::AlignLeft);
01183 
01184     d->htmlName = new KLineEdit(page);
01185     d->htmlName->setMaxLength(13);   // Qt's QColor allows 12 hexa-digits
01186     d->htmlName->setText("#FFFFFF"); // But HTML uses only 6, so do not worry about the size
01187     int w = d->htmlName->fontMetrics().width(QLatin1String("#DDDDDDD"));
01188     d->htmlName->setFixedWidth(w);
01189     l_grid->addWidget(d->htmlName, 1, 2, Qt::AlignLeft);
01190 
01191     connect(d->htmlName, SIGNAL(textChanged(const QString &)),
01192             SLOT(slotHtmlChanged()));
01193 
01194     d->patch = new KColorPatch(page);
01195     d->patch->setFixedSize(48, 48);
01196     l_grid->addWidget(d->patch, 0, 0, 2, 1, Qt::AlignHCenter | Qt::AlignVCenter);
01197     connect(d->patch, SIGNAL(colorChanged(const QColor&)),
01198             SLOT(setColor(const QColor&)));
01199 
01200     //
01201     // chain fields together
01202     //
01203     setTabOrder(d->hedit, d->sedit);
01204     setTabOrder(d->sedit, d->vedit);
01205     setTabOrder(d->vedit, d->redit);
01206     setTabOrder(d->redit, d->gedit);
01207     setTabOrder(d->gedit, d->bedit);
01208 
01209     tl_layout->activate();
01210     page->setMinimumSize(page->sizeHint());
01211 
01212     readSettings();
01213     d->bRecursion = false;
01214     d->bEditHsv = false;
01215     d->bEditRgb = false;
01216     d->bEditHtml = false;
01217 
01218     setFixedSize(sizeHint());
01219     QColor col;
01220     col.setHsv(0, 0, 255);
01221     d->_setColor(col);
01222 
01223 // FIXME: with enabled event filters, it crashes after ever enter of a drag.
01224 // better disable drag and drop than crashing it...
01225 //   d->htmlName->installEventFilter(this);
01226 //   d->hsSelector->installEventFilter(this);
01227     d->hsSelector->setAcceptDrops(true);
01228 
01229     d->setVMode();
01230 }
01231 
01232 KColorDialog::~KColorDialog()
01233 {
01234 #ifdef Q_WS_X11
01235     if (d->bColorPicking && kapp)
01236         kapp->removeX11EventFilter(d->filter);
01237 #endif
01238     delete d;
01239 }
01240 
01241 bool
01242 KColorDialog::eventFilter(QObject *obj, QEvent *ev)
01243 {
01244     if ((obj == d->htmlName) || (obj == d->hsSelector))
01245         switch (ev->type()) {
01246         case QEvent::DragEnter:
01247         case QEvent::DragMove:
01248         case QEvent::DragLeave:
01249         case QEvent::Drop:
01250         case QEvent::DragResponse:
01251             qApp->sendEvent(d->patch, ev);
01252             return true;
01253         default:
01254             break;
01255         }
01256     return KDialog::eventFilter(obj, ev);
01257 }
01258 
01259 void
01260 KColorDialog::setDefaultColor(const QColor& col)
01261 {
01262     if (!d->cbDefaultColor) {
01263         //
01264         // a little space between
01265         //
01266         d->l_right->addSpacing(10);
01267 
01268         //
01269         // and the "default color" checkbox, under all items on the right side
01270         //
01271         d->cbDefaultColor = new QCheckBox(i18n("Default color"), mainWidget());
01272 
01273         d->l_right->addWidget(d->cbDefaultColor);
01274 
01275         mainWidget()->setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);   // cancel setFixedSize()
01276         d->tl_layout->activate();
01277         mainWidget()->setMinimumSize(mainWidget()->sizeHint());
01278         setFixedSize(sizeHint());
01279 
01280         connect(d->cbDefaultColor, SIGNAL(clicked()), SLOT(slotDefaultColorClicked()));
01281     }
01282 
01283     d->defaultColor = col;
01284 
01285     d->slotDefaultColorClicked();
01286 }
01287 
01288 QColor KColorDialog::defaultColor() const
01289 {
01290     return d->defaultColor;
01291 }
01292 
01293 
01294 void KColorDialog::KColorDialogPrivate::setChooserMode(KColorChooserMode c)
01295 {
01296     _mode = c;
01297     hsSelector->setChooserMode(c);
01298     valuePal->setChooserMode(c);
01299 
01300     updateModeButtons();
01301     valuePal->updateContents();
01302     hsSelector->updateContents();
01303     valuePal->repaint();
01304     hsSelector->repaint();
01305     slotHSVChanged();
01306 }
01307 
01308 
01309 
01310 void
01311 KColorDialog::KColorDialogPrivate::updateModeButtons()
01312 {
01313     hmode->setChecked(false);
01314     smode->setChecked(false);
01315     vmode->setChecked(false);
01316     rmode->setChecked(false);
01317     gmode->setChecked(false);
01318     bmode->setChecked(false);
01319 
01320     switch (valuePal->chooserMode()) {
01321     case ChooserHue:
01322         hmode->setChecked(true);
01323         break;
01324     case ChooserSaturation:
01325         smode->setChecked(true);
01326         break;
01327     case ChooserRed:
01328         rmode->setChecked(true);
01329         break;
01330     case ChooserGreen:
01331         gmode->setChecked(true);
01332         break;
01333     case ChooserBlue:
01334         bmode->setChecked(true);
01335         break;
01336     case ChooserValue:
01337     default:
01338         vmode->setChecked(true);
01339         break;
01340     }
01341 }
01342 
01343 KColorChooserMode KColorDialog::KColorDialogPrivate::chooserMode()
01344 {
01345     return _mode;
01346 }
01347 
01348 void KColorDialog::KColorDialogPrivate::slotDefaultColorClicked()
01349 {
01350     if (cbDefaultColor->isChecked()) {
01351         selColor = defaultColor;
01352         showColor(selColor, i18n("-default-"));
01353     } else {
01354         showColor(selColor, QString());
01355     }
01356     emit q->colorSelected(selColor);
01357 }
01358 
01359 void
01360 KColorDialog::KColorDialogPrivate::setHMode()
01361 {
01362     setChooserMode(ChooserHue);
01363 }
01364 
01365 void
01366 KColorDialog::KColorDialogPrivate::setSMode()
01367 {
01368     setChooserMode(ChooserSaturation);
01369 }
01370 
01371 void
01372 KColorDialog::KColorDialogPrivate::setVMode()
01373 {
01374     setChooserMode(ChooserValue);
01375 }
01376 
01377 void
01378 KColorDialog::KColorDialogPrivate::setRMode()
01379 {
01380     setChooserMode(ChooserRed);
01381 }
01382 
01383 void
01384 KColorDialog::KColorDialogPrivate::setGMode()
01385 {
01386     setChooserMode(ChooserGreen);
01387 
01388 }
01389 
01390 void
01391 KColorDialog::KColorDialogPrivate::setBMode()
01392 {
01393     setChooserMode(ChooserBlue);
01394 }
01395 
01396 void
01397 KColorDialog::readSettings()
01398 {
01399     KConfigGroup group(KGlobal::config(), "Colors");
01400 
01401     QString collectionName = group.readEntry("CurrentPalette");
01402     if (collectionName.isEmpty()) {
01403         collectionName = i18nc("palette name", colorCollectionName[fortyColorIndex].m_displayName);
01404     } else {
01405         for (int i = 0; colorCollectionName[i].m_fileName; ++i) {
01406             if (collectionName == colorCollectionName[i].m_displayName) {
01407                 collectionName = i18nc("palette name", colorCollectionName[i].m_displayName);
01408                 break;
01409             }
01410         }
01411     }
01412 
01413     d->table->setColors(collectionName);
01414 }
01415 
01416 void
01417 KColorDialog::KColorDialogPrivate::slotWriteSettings()
01418 {
01419     KConfigGroup group(KGlobal::config(), "Colors");
01420 
01421     QString collectionName = table->name();
01422     if (!group.hasDefault("CurrentPalette") && table->name() == originalPalette) {
01423         group.revertToDefault("CurrentPalette");
01424     } else {
01425         QString collectionName(table->name());
01426         for (int i = 0; colorCollectionName[i].m_fileName; ++i) {
01427             if (collectionName == i18nc("palette name", colorCollectionName[i].m_displayName)) {
01428                 collectionName = colorCollectionName[i].m_displayName;
01429                 break;
01430             }
01431         }
01432         group.writeEntry("CurrentPalette", collectionName); //Make sure the untranslated name is saved, assuming there is one
01433     }
01434 }
01435 
01436 QColor
01437 KColorDialog::color() const
01438 {
01439     if (d->cbDefaultColor && d->cbDefaultColor->isChecked())
01440         return QColor();
01441     if (d->selColor.isValid())
01442         d->table->addToRecentColors(d->selColor);
01443     return d->selColor;
01444 }
01445 
01446 void KColorDialog::setColor(const QColor &col)
01447 {
01448     d->_setColor(col);
01449 }
01450 
01451 //
01452 // static function to display dialog and return color
01453 //
01454 int KColorDialog::getColor(QColor &theColor, QWidget *parent)
01455 {
01456     KColorDialog dlg(parent, true);
01457     dlg.setObjectName("Color Selector");
01458     if (theColor.isValid())
01459         dlg.setColor(theColor);
01460     int result = dlg.exec();
01461 
01462     if (result == Accepted) {
01463         theColor = dlg.color();
01464     }
01465 
01466     return result;
01467 }
01468 
01469 //
01470 // static function to display dialog and return color
01471 //
01472 int KColorDialog::getColor(QColor &theColor, const QColor& defaultCol, QWidget *parent)
01473 {
01474     KColorDialog dlg(parent, true);
01475     dlg.setObjectName("Color Selector");
01476     dlg.setDefaultColor(defaultCol);
01477     dlg.setColor(theColor);
01478     int result = dlg.exec();
01479 
01480     if (result == Accepted)
01481         theColor = dlg.color();
01482 
01483     return result;
01484 }
01485 
01486 void KColorDialog::KColorDialogPrivate::slotRGBChanged(void)
01487 {
01488     if (bRecursion) return;
01489     int red = redit->value();
01490     int grn = gedit->value();
01491     int blu = bedit->value();
01492 
01493     if (red > 255 || red < 0) return;
01494     if (grn > 255 || grn < 0) return;
01495     if (blu > 255 || blu < 0) return;
01496 
01497     QColor col;
01498     col.setRgb(red, grn, blu);
01499     bEditRgb = true;
01500     _setColor(col);
01501     bEditRgb = false;
01502 }
01503 
01504 void KColorDialog::KColorDialogPrivate::slotHtmlChanged(void)
01505 {
01506     if (bRecursion || htmlName->text().isEmpty()) return;
01507 
01508     QString strColor(htmlName->text());
01509 
01510     // Assume that a user does not want to type the # all the time
01511     if (strColor[0] != '#') {
01512         bool signalsblocked = htmlName->blockSignals(true);
01513         strColor.prepend("#");
01514         htmlName->setText(strColor);
01515         htmlName->blockSignals(signalsblocked);
01516     }
01517 
01518     const QColor color(strColor);
01519 
01520     if (color.isValid()) {
01521         QColor col(color);
01522         bEditHtml = true;
01523         _setColor(col);
01524         bEditHtml = false;
01525     }
01526 }
01527 
01528 void KColorDialog::KColorDialogPrivate::slotHSVChanged(void)
01529 {
01530     if (bRecursion) return;
01531     int hue = hedit->value();
01532     int sat = sedit->value();
01533     int val = vedit->value();
01534 
01535     if (hue > 359 || hue < 0) return;
01536     if (sat > 255 || sat < 0) return;
01537     if (val > 255 || val < 0) return;
01538 
01539     QColor col;
01540     col.setHsv(hue, sat, val);
01541     bEditHsv = true;
01542     _setColor(col);
01543     bEditHsv = false;
01544 }
01545 
01546 void KColorDialog::KColorDialogPrivate::slotHSChanged(int x, int y)
01547 {
01548     int _h, _s, _v, _r, _g, _b;
01549 
01550     _h = selColor.hue();
01551     _s = selColor.saturation();
01552     _v = selColor.value();
01553     _r = selColor.red();
01554     _g = selColor.green();
01555     _b = selColor.blue();
01556 
01557     QColor col;
01558 
01559     switch (chooserMode()) {
01560     case ChooserRed:
01561         col.setRgb(_r, x, y);
01562         break;
01563     case ChooserGreen:
01564         col.setRgb(x, _g, y);
01565         break;
01566     case ChooserBlue:
01567         col.setRgb(y, x, _b);
01568         break;
01569     case ChooserHue:
01570         col.setHsv(_h, x, y);
01571         break;
01572     case ChooserSaturation:
01573         col.setHsv(x, _s, y);
01574         break;
01575     case ChooserValue:
01576     default:
01577         col.setHsv(x, y, _v);
01578         break;
01579     }
01580     _setColor(col);
01581 }
01582 
01583 void KColorDialog::KColorDialogPrivate::slotVChanged(int v)
01584 {
01585     int _h, _s, _v, _r, _g, _b;
01586 
01587     _h = selColor.hue();
01588     _s = selColor.saturation();
01589     _v = selColor.value();
01590     _r = selColor.red();
01591     _g = selColor.green();
01592     _b = selColor.blue();
01593 
01594 
01595     QColor col;
01596 
01597     switch (chooserMode()) {
01598     case ChooserHue:
01599         col.setHsv(v, _s, _v);
01600         break;
01601     case ChooserSaturation:
01602         col.setHsv(_h, v, _v);
01603         break;
01604     case ChooserRed:
01605         col.setRgb(v, _g, _b);
01606         break;
01607     case ChooserGreen:
01608         col.setRgb(_r, v, _b);
01609         break;
01610     case ChooserBlue:
01611         col.setRgb(_r, _g, v);
01612         break;
01613     case ChooserValue:
01614     default:
01615         col.setHsv(_h, _s, v);
01616         break;
01617     }
01618 
01619     _setColor(col);
01620 }
01621 
01622 void KColorDialog::KColorDialogPrivate::slotColorSelected(const QColor &color)
01623 {
01624     _setColor(color);
01625 }
01626 
01627 void KColorDialog::KColorDialogPrivate::slotAddToCustomColors()
01628 {
01629     table->addToCustomColors(selColor);
01630 }
01631 
01632 void KColorDialog::KColorDialogPrivate::slotColorSelected(const QColor &color, const QString &name)
01633 {
01634     _setColor(color, name);
01635 }
01636 
01637 void KColorDialog::KColorDialogPrivate::slotColorDoubleClicked
01638 (
01639     const QColor  & color,
01640     const QString & name
01641 )
01642 {
01643     _setColor(color, name);
01644     q->accept();
01645 }
01646 
01647 void KColorDialog::KColorDialogPrivate::_setColor(const QColor &color, const QString &name)
01648 {
01649     if (color.isValid()) {
01650         if (cbDefaultColor && cbDefaultColor->isChecked())
01651             cbDefaultColor->setChecked(false);
01652         selColor = color;
01653     } else {
01654         if (cbDefaultColor && cbDefaultColor->isChecked())
01655             cbDefaultColor->setChecked(true);
01656         selColor = defaultColor;
01657     }
01658 
01659     showColor(selColor, name);
01660 
01661     emit q->colorSelected(selColor);
01662 }
01663 
01664 // show but don't set into selColor, nor emit colorSelected
01665 void KColorDialog::KColorDialogPrivate::showColor(const QColor &color, const QString &name)
01666 {
01667     bRecursion = true;
01668 
01669     if (name.isEmpty())
01670         colorName->setText(i18n("-unnamed-"));
01671     else
01672         colorName->setText(name);
01673 
01674     patch->setColor(color);
01675 
01676     setRgbEdit(color);
01677     setHsvEdit(color);
01678     setHtmlEdit(color);
01679 
01680 
01681     switch (chooserMode()) {
01682     case ChooserSaturation:
01683         hsSelector->setValues(color.hue(), color.value());
01684         valuePal->setValue(color.saturation());
01685         break;
01686     case ChooserValue:
01687         hsSelector->setValues(color.hue(), color.saturation());
01688         valuePal->setValue(color.value());
01689         break;
01690     case ChooserRed:
01691         hsSelector->setValues(color.green(), color.blue());
01692         valuePal->setValue(color.red());
01693         break;
01694     case ChooserGreen:
01695         hsSelector->setValues(color.red(), color.blue());
01696         valuePal->setValue(color.green());
01697         break;
01698     case ChooserBlue:
01699         hsSelector->setValues(color.green(), color.red());
01700         valuePal->setValue(color.blue());
01701         break;
01702     case ChooserHue:
01703     default:
01704         hsSelector->setValues(color.saturation(), color.value());
01705         valuePal->setValue(color.hue());
01706         break;
01707 
01708     }
01709 
01710     bool blocked = valuePal->blockSignals(true);
01711 
01712     valuePal->setHue(color.hue());
01713     valuePal->setSaturation(color.saturation());
01714     valuePal->setColorValue(color.value());
01715     valuePal->updateContents();
01716     valuePal->blockSignals(blocked);
01717     valuePal->repaint();
01718 
01719     blocked = hsSelector->blockSignals(true);
01720 
01721     hsSelector->setHue(color.hue());
01722     hsSelector->setSaturation(color.saturation());
01723     hsSelector->setColorValue(color.value());
01724     hsSelector->updateContents();
01725     hsSelector->blockSignals(blocked);
01726     hsSelector->repaint();
01727 
01728     bRecursion = false;
01729 }
01730 
01731 
01732 
01733 void
01734 KColorDialog::KColorDialogPrivate::slotColorPicker()
01735 {
01736     bColorPicking = true;
01737 #ifdef Q_WS_X11
01738     filter = new KCDPickerFilter(q);
01739     kapp->installX11EventFilter(filter);
01740 #endif
01741     q->grabMouse(Qt::CrossCursor);
01742     q->grabKeyboard();
01743 }
01744 
01745 void
01746 KColorDialog::mouseMoveEvent(QMouseEvent *e)
01747 {
01748     if (d->bColorPicking) {
01749         d->_setColor(grabColor(e->globalPos()));
01750         return;
01751     }
01752 
01753     KDialog::mouseMoveEvent(e);
01754 }
01755 
01756 void
01757 KColorDialog::mouseReleaseEvent(QMouseEvent *e)
01758 {
01759     if (d->bColorPicking) {
01760         d->bColorPicking = false;
01761 #ifdef Q_WS_X11
01762         kapp->removeX11EventFilter(d->filter);
01763         delete d->filter; d->filter = 0;
01764 #endif
01765         releaseMouse();
01766         releaseKeyboard();
01767         d->_setColor(grabColor(e->globalPos()));
01768         return;
01769     }
01770     KDialog::mouseReleaseEvent(e);
01771 }
01772 
01773 QColor
01774 KColorDialog::grabColor(const QPoint &p)
01775 {
01776 #ifdef Q_WS_X11
01777     // we use the X11 API directly in this case as we are not getting back a valid
01778     // return from QPixmap::grabWindow in the case where the application is using
01779     // an argb visual
01780     if( !qApp->desktop()->geometry().contains( p ))
01781         return QColor();
01782     Window root = RootWindow(QX11Info::display(), QX11Info::appScreen());
01783     XImage *ximg = XGetImage(QX11Info::display(), root, p.x(), p.y(), 1, 1, -1, ZPixmap);
01784     unsigned long xpixel = XGetPixel(ximg, 0, 0);
01785     XDestroyImage(ximg);
01786     XColor xcol;
01787     xcol.pixel = xpixel;
01788     xcol.flags = DoRed | DoGreen | DoBlue;
01789     XQueryColor(QX11Info::display(),
01790                 DefaultColormap(QX11Info::display(), QX11Info::appScreen()),
01791                 &xcol);
01792     return QColor::fromRgbF(xcol.red / 65535.0, xcol.green / 65535.0, xcol.blue / 65535.0);
01793 #else
01794     QWidget *desktop = QApplication::desktop();
01795     QPixmap pm = QPixmap::grabWindow(desktop->winId(), p.x(), p.y(), 1, 1);
01796     QImage i = pm.toImage();
01797     return i.pixel(0, 0);
01798 #endif
01799 }
01800 
01801 void
01802 KColorDialog::keyPressEvent(QKeyEvent *e)
01803 {
01804     if (d->bColorPicking) {
01805         if (e->key() == Qt::Key_Escape) {
01806             d->bColorPicking = false;
01807 #ifdef Q_WS_X11
01808             kapp->removeX11EventFilter(d->filter);
01809             delete d->filter; d->filter = 0;
01810 #endif
01811             releaseMouse();
01812             releaseKeyboard();
01813         }
01814         e->accept();
01815         return;
01816     }
01817     KDialog::keyPressEvent(e);
01818 }
01819 
01820 void KColorDialog::KColorDialogPrivate::setRgbEdit(const QColor &col)
01821 {
01822     if (bEditRgb) return;
01823     int r, g, b;
01824     col.getRgb(&r, &g, &b);
01825 
01826     redit->setValue(r);
01827     gedit->setValue(g);
01828     bedit->setValue(b);
01829 }
01830 
01831 void KColorDialog::KColorDialogPrivate::setHtmlEdit(const QColor &col)
01832 {
01833     if (bEditHtml) return;
01834     int r, g, b;
01835     col.getRgb(&r, &g, &b);
01836     QString num;
01837 
01838     num.sprintf("#%02X%02X%02X", r, g, b);
01839     htmlName->setText(num);
01840 }
01841 
01842 
01843 void KColorDialog::KColorDialogPrivate::setHsvEdit(const QColor &col)
01844 {
01845     if (bEditHsv) return;
01846     int h, s, v;
01847     col.getHsv(&h, &s, &v);
01848 
01849     hedit->setValue(h);
01850     sedit->setValue(s);
01851     vedit->setValue(v);
01852 }
01853 
01854 #include "kcolordialog.moc"
01855 #include "kcolordialog_p.moc"

KDEUI

Skip menu "KDEUI"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.6.1
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal