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

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
  • Kross
  • KUtils
  • Nepomuk
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.5.4
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