kcolordialog.cpp

00001 /* This file is part of the KDE libraries
00002     Copyright (C) 1997 Martin Jones (mjones@kde.org)
00003 
00004     This library is free software; you can redistribute it and/or
00005     modify it under the terms of the GNU Library General Public
00006     License as published by the Free Software Foundation; either
00007     version 2 of the License, or (at your option) any later version.
00008 
00009     This library is distributed in the hope that it will be useful,
00010     but WITHOUT ANY WARRANTY; without even the implied warranty of
00011     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012     Library General Public License for more details.
00013 
00014     You should have received a copy of the GNU Library General Public License
00015     along with this library; see the file COPYING.LIB.  If not, write to
00016     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017     Boston, MA 02110-1301, USA.
00018 */
00019 //-----------------------------------------------------------------------------
00020 // KDE color selection dialog.
00021 //
00022 // 1999-09-27 Espen Sand <espensa@online.no>
00023 // KColorDialog is now subclassed from KDialogBase. I have also extended
00024 // KColorDialog::getColor() so that it contains a parent argument. This
00025 // improves centering capability.
00026 //
00027 // layout management added Oct 1997 by Mario Weilguni
00028 // <mweilguni@sime.com>
00029 //
00030 
00031 #include <stdio.h>
00032 #include <stdlib.h>
00033 
00034 #include <qcheckbox.h>
00035 #include <qcombobox.h>
00036 #include <qdrawutil.h>
00037 #include <qevent.h>
00038 #include <qfile.h>
00039 #include <qimage.h>
00040 #include <qlabel.h>
00041 #include <qlayout.h>
00042 #include <qlineedit.h>
00043 #include <qvalidator.h>
00044 #include <qpainter.h>
00045 #include <qpushbutton.h>
00046 #include <qspinbox.h>
00047 #include <qtimer.h>
00048 
00049 #include <kapplication.h>
00050 #include <kconfig.h>
00051 #include <kglobal.h>
00052 #include <kglobalsettings.h>
00053 #include <kiconloader.h>
00054 #include <klistbox.h>
00055 #include <klocale.h>
00056 #include <kmessagebox.h>
00057 #include <kseparator.h>
00058 #include <kpalette.h>
00059 #include <kimageeffect.h>
00060 
00061 #include "kcolordialog.h"
00062 #include "kcolordrag.h"
00063 #include "kstaticdeleter.h"
00064 #include <config.h>
00065 #include <kdebug.h>
00066 
00067 #include "config.h"
00068 #ifdef Q_WS_X11
00069 #include <X11/Xlib.h> 
00070 
00071 // defined in qapplication_x11.cpp
00072 typedef int (*QX11EventFilter) (XEvent*);
00073 extern QX11EventFilter qt_set_x11_event_filter (QX11EventFilter filter);
00074 #endif
00075 
00076 struct ColorPaletteNameType
00077 {
00078     const char* m_fileName;
00079     const char* m_displayName;
00080 };
00081 
00082 const ColorPaletteNameType colorPaletteName[]=
00083 {
00084     { "Recent_Colors", I18N_NOOP2( "palette name", "* Recent Colors *" ) },
00085     { "Custom_Colors", I18N_NOOP2( "palette name", "* Custom Colors *" ) },
00086     { "40.colors",     I18N_NOOP2( "palette name", "Forty Colors" ) },
00087     { "Rainbow.colors",I18N_NOOP2( "palette name", "Rainbow Colors" ) },
00088     { "Royal.colors",  I18N_NOOP2( "palette name", "Royal Colors" ) },
00089     { "Web.colors",    I18N_NOOP2( "palette name", "Web Colors" ) },
00090     { 0, 0 } // end of data
00091 };
00092 
00093 const int recentColorIndex = 0;
00094 
00095 class KColorSpinBox : public QSpinBox
00096 {
00097 public:
00098   KColorSpinBox(int minValue, int maxValue, int step, QWidget* parent)
00099    : QSpinBox(minValue, maxValue, step, parent, "kcolorspinbox")
00100   { }
00101 
00102   // Override Qt's braindead auto-selection.
00103   virtual void valueChange()
00104   {
00105       updateDisplay();
00106       emit valueChanged( value() );
00107       emit valueChanged( currentValueText() );
00108   }
00109 
00110 };
00111 
00112 
00113 #define STANDARD_PAL_SIZE 17
00114 
00115 KColor::KColor()
00116 : QColor()
00117 {
00118   r = 0; g = 0; b = 0; h = 0; s = 0; v = 0;
00119 }
00120 
00121 KColor::KColor( const KColor &col)
00122 : QColor( col )
00123 {
00124   h = col.h; s = col.s; v = col.v;
00125   r = col.r; g = col.g; b = col.b;
00126 }
00127 
00128 KColor::KColor( const QColor &col)
00129 : QColor( col )
00130 {
00131   QColor::getRgb(&r, &g, &b);
00132   QColor::getHsv(&h, &s, &v);
00133 }
00134 
00135 bool KColor::operator==(const KColor& col) const
00136 {
00137   return (h == col.h) && (s == col.s) && (v == col.v) &&
00138          (r == col.r) && (g == col.g) && (b == col.b);
00139 }
00140 
00141 KColor& KColor::operator=(const KColor& col)
00142 {
00143   *(QColor *)this = col;
00144   h = col.h; s = col.s; v = col.v;
00145   r = col.r; g = col.g; b = col.b;
00146   return *this;
00147 }
00148 
00149 void
00150 KColor::setHsv(int _h, int _s, int _v)
00151 {
00152   h = _h; s = _s; v = _v;
00153   QColor::setHsv(h, s, v);
00154   QColor::rgb(&r, &g, &b);
00155 }
00156 
00157 void
00158 KColor::setRgb(int _r, int _g, int _b)
00159 {
00160   r = _r; g = _g; b = _b;
00161   QColor::setRgb(r, g, b);
00162   QColor::hsv(&h, &s, &v);
00163 }
00164 
00165 void
00166 KColor::rgb(int *_r, int *_g, int *_b) const
00167 {
00168   *_r = r; *_g = g; *_b = b;
00169 }
00170 
00171 void
00172 KColor::hsv(int *_h, int *_s, int *_v) const
00173 {
00174   *_h = h; *_s = s; *_v = v;
00175 }
00176 
00177 
00178 static QColor *standardPalette = 0;
00179 static KStaticDeleter<QColor> spd;
00180 
00181 static void createStandardPalette()
00182 {
00183     if ( standardPalette )
00184     return;
00185 
00186     spd.setObject(standardPalette, new QColor [STANDARD_PAL_SIZE], true/*array*/);
00187 
00188     int i = 0;
00189 
00190     standardPalette[i++] = Qt::red;
00191     standardPalette[i++] = Qt::green;
00192     standardPalette[i++] = Qt::blue;
00193     standardPalette[i++] = Qt::cyan;
00194     standardPalette[i++] = Qt::magenta;
00195     standardPalette[i++] = Qt::yellow;
00196     standardPalette[i++] = Qt::darkRed;
00197     standardPalette[i++] = Qt::darkGreen;
00198     standardPalette[i++] = Qt::darkBlue;
00199     standardPalette[i++] = Qt::darkCyan;
00200     standardPalette[i++] = Qt::darkMagenta;
00201     standardPalette[i++] = Qt::darkYellow;
00202     standardPalette[i++] = Qt::white;
00203     standardPalette[i++] = Qt::lightGray;
00204     standardPalette[i++] = Qt::gray;
00205     standardPalette[i++] = Qt::darkGray;
00206     standardPalette[i++] = Qt::black;
00207 }
00208 
00209 
00210 KHSSelector::KHSSelector( QWidget *parent, const char *name )
00211     : KXYSelector( parent, name )
00212 {
00213     setRange( 0, 0, 359, 255 );
00214 }
00215 
00216 void KHSSelector::updateContents()
00217 {
00218     drawPalette(&pixmap);
00219 }
00220 
00221 void KHSSelector::resizeEvent( QResizeEvent * )
00222 {
00223     updateContents();
00224 }
00225 
00226 void KHSSelector::drawContents( QPainter *painter )
00227 {
00228     painter->drawPixmap( contentsRect().x(), contentsRect().y(), pixmap );
00229 }
00230 
00231 void KHSSelector::drawPalette( QPixmap *pixmap )
00232 {
00233     int xSize = contentsRect().width(), ySize = contentsRect().height();
00234     QImage image( xSize, ySize, 32 );
00235     QColor col;
00236     int h, s;
00237     uint *p;
00238 
00239     for ( s = ySize-1; s >= 0; s-- )
00240     {
00241         p = (uint *) image.scanLine( ySize - s - 1 );
00242         for( h = 0; h < xSize; h++ )
00243         {
00244             col.setHsv( 359*h/(xSize-1), 255*s/(ySize-1), 192 );
00245             *p = col.rgb();
00246             p++;
00247         }
00248     }
00249 
00250     if ( QColor::numBitPlanes() <= 8 )
00251     {
00252         createStandardPalette();
00253         KImageEffect::dither( image, standardPalette, STANDARD_PAL_SIZE );
00254     }
00255     pixmap->convertFromImage( image );
00256 }
00257 
00258 
00259 //-----------------------------------------------------------------------------
00260 
00261 KValueSelector::KValueSelector( QWidget *parent, const char *name )
00262     : KSelector( KSelector::Vertical, parent, name ), _hue(0), _sat(0)
00263 {
00264     setRange( 0, 255 );
00265     pixmap.setOptimization( QPixmap::BestOptim );
00266 }
00267 
00268 KValueSelector::KValueSelector(Orientation o, QWidget *parent, const char *name
00269  )
00270     : KSelector( o, parent, name), _hue(0), _sat(0)
00271 {
00272     setRange( 0, 255 );
00273     pixmap.setOptimization( QPixmap::BestOptim );
00274 }
00275 
00276 void KValueSelector::updateContents()
00277 {
00278     drawPalette(&pixmap);
00279 }
00280 
00281 void KValueSelector::resizeEvent( QResizeEvent * )
00282 {
00283     updateContents();
00284 }
00285 
00286 void KValueSelector::drawContents( QPainter *painter )
00287 {
00288     painter->drawPixmap( contentsRect().x(), contentsRect().y(), pixmap );
00289 }
00290 
00291 void KValueSelector::drawPalette( QPixmap *pixmap )
00292 {
00293     int xSize = contentsRect().width(), ySize = contentsRect().height();
00294     QImage image( xSize, ySize, 32 );
00295     QColor col;
00296     uint *p;
00297     QRgb rgb;
00298 
00299     if ( orientation() == KSelector::Horizontal )
00300     {
00301         for ( int v = 0; v < ySize; v++ )
00302         {
00303             p = (uint *) image.scanLine( ySize - v - 1 );
00304 
00305             for( int x = 0; x < xSize; x++ )
00306             {
00307                 col.setHsv( _hue, _sat, 255*x/(xSize-1) );
00308                 rgb = col.rgb();
00309                 *p++ = rgb;
00310             }
00311         }
00312     }
00313 
00314     if( orientation() == KSelector::Vertical )
00315     {
00316         for ( int v = 0; v < ySize; v++ )
00317         {
00318             p = (uint *) image.scanLine( ySize - v - 1 );
00319             col.setHsv( _hue, _sat, 255*v/(ySize-1) );
00320             rgb = col.rgb();
00321             for ( int i = 0; i < xSize; i++ )
00322                 *p++ = rgb;
00323         }
00324     }
00325 
00326     if ( QColor::numBitPlanes() <= 8 )
00327     {
00328         createStandardPalette();
00329         KImageEffect::dither( image, standardPalette, STANDARD_PAL_SIZE );
00330     }
00331     pixmap->convertFromImage( image );
00332 }
00333 
00334 //-----------------------------------------------------------------------------
00335 
00336 KColorCells::KColorCells( QWidget *parent, int rows, int cols )
00337     : QGridView( parent )
00338 {
00339     shade = true;
00340     setNumRows( rows );
00341     setNumCols( cols );
00342     colors = new QColor [ rows * cols ];
00343 
00344     for ( int i = 0; i < rows * cols; i++ )
00345         colors[i] = QColor();
00346 
00347     selected = 0;
00348         inMouse = false;
00349 
00350     // Drag'n'Drop
00351     setAcceptDrops( true);
00352 
00353     setHScrollBarMode( AlwaysOff );
00354     setVScrollBarMode( AlwaysOff );
00355     viewport()->setBackgroundMode( PaletteBackground );
00356     setBackgroundMode( PaletteBackground );
00357 }
00358 
00359 KColorCells::~KColorCells()
00360 {
00361     delete [] colors;
00362 }
00363 
00364 void KColorCells::setColor( int colNum, const QColor &col )
00365 {
00366     colors[colNum] = col;
00367     updateCell( colNum/numCols(), colNum%numCols() );
00368 }
00369 
00370 void KColorCells::paintCell( QPainter *painter, int row, int col )
00371 {
00372     QBrush brush;
00373         int w = 1;
00374 
00375     if (shade)
00376         {
00377         qDrawShadePanel( painter, 1, 1, cellWidth()-2,
00378             cellHeight()-2, colorGroup(), true, 1, &brush );
00379         w = 2;
00380         }
00381         QColor color = colors[ row * numCols() + col ];
00382         if (!color.isValid())
00383     {
00384         if (!shade) return;
00385         color = backgroundColor();
00386     }
00387 
00388     painter->setPen( color );
00389     painter->setBrush( QBrush( color ) );
00390     painter->drawRect( w, w, cellWidth()-w*2, cellHeight()-w*2 );
00391 
00392     if ( row * numCols() + col == selected )
00393         painter->drawWinFocusRect( w, w, cellWidth()-w*2, cellHeight()-w*2 );
00394 }
00395 
00396 void KColorCells::resizeEvent( QResizeEvent * )
00397 {
00398     setCellWidth( width() / numCols() );
00399     setCellHeight( height() / numRows() );
00400 }
00401 
00402 void KColorCells::mousePressEvent( QMouseEvent *e )
00403 {
00404     inMouse = true;
00405     mPos = e->pos();
00406 }
00407 
00408 int KColorCells::posToCell(const QPoint &pos, bool ignoreBorders)
00409 {
00410    int row = pos.y() / cellHeight();
00411    int col = pos.x() / cellWidth();
00412    int cell = row * numCols() + col;
00413 
00414    if (!ignoreBorders)
00415    {
00416       int border = 2;
00417       int x = pos.x() - col * cellWidth();
00418       int y = pos.y() - row * cellHeight();
00419       if ( (x < border) || (x > cellWidth()-border) ||
00420            (y < border) || (y > cellHeight()-border))
00421          return -1;
00422    }
00423    return cell;
00424 }
00425 
00426 void KColorCells::mouseMoveEvent( QMouseEvent *e )
00427 {
00428     if( !(e->state() && LeftButton)) return;
00429 
00430     if(inMouse) {
00431         int delay = KGlobalSettings::dndEventDelay();
00432         if(e->x() > mPos.x()+delay || e->x() < mPos.x()-delay ||
00433            e->y() > mPos.y()+delay || e->y() < mPos.y()-delay){
00434             // Drag color object
00435             int cell = posToCell(mPos);
00436             if ((cell != -1) && colors[cell].isValid())
00437             {
00438                KColorDrag *d = new KColorDrag( colors[cell], this);
00439                d->dragCopy();
00440             }
00441         }
00442     }
00443 }
00444 
00445 void KColorCells::dragEnterEvent( QDragEnterEvent *event)
00446 {
00447      event->accept( acceptDrags && KColorDrag::canDecode( event));
00448 }
00449 
00450 void KColorCells::dropEvent( QDropEvent *event)
00451 {
00452      QColor c;
00453      if( KColorDrag::decode( event, c)) {
00454           int cell = posToCell(event->pos(), true);
00455       setColor(cell,c);
00456      }
00457 }
00458 
00459 void KColorCells::mouseReleaseEvent( QMouseEvent *e )
00460 {
00461     int cell = posToCell(mPos);
00462         int currentCell = posToCell(e->pos());
00463 
00464         // If we release the mouse in another cell and we don't have
00465         // a drag we should ignore this event.
00466         if (currentCell != cell)
00467            cell = -1;
00468 
00469     if ( (cell != -1) && (selected != cell) )
00470     {
00471         int prevSel = selected;
00472         selected = cell;
00473         updateCell( prevSel/numCols(), prevSel%numCols() );
00474         updateCell( cell/numCols(), cell%numCols() );
00475         }
00476 
00477         inMouse = false;
00478         if (cell != -1)
00479         emit colorSelected( cell );
00480 }
00481 
00482 void KColorCells::mouseDoubleClickEvent( QMouseEvent * /*e*/ )
00483 {
00484   int cell = posToCell(mPos);
00485 
00486   if (cell != -1)
00487     emit colorDoubleClicked( cell );
00488 }
00489 
00490 
00491 //-----------------------------------------------------------------------------
00492 
00493 KColorPatch::KColorPatch( QWidget *parent ) : QFrame( parent )
00494 {
00495     setFrameStyle( QFrame::Panel | QFrame::Sunken );
00496     colContext = 0;
00497     setAcceptDrops( true);
00498 }
00499 
00500 KColorPatch::~KColorPatch()
00501 {
00502   if ( colContext )
00503     QColor::destroyAllocContext( colContext );
00504 }
00505 
00506 void KColorPatch::setColor( const QColor &col )
00507 {
00508     if ( colContext )
00509         QColor::destroyAllocContext( colContext );
00510     colContext = QColor::enterAllocContext();
00511     color.setRgb( col.rgb() );
00512     color.alloc();
00513     QColor::leaveAllocContext();
00514 
00515     QPainter painter;
00516 
00517     painter.begin( this );
00518     drawContents( &painter );
00519     painter.end();
00520 }
00521 
00522 void KColorPatch::drawContents( QPainter *painter )
00523 {
00524     painter->setPen( color );
00525     painter->setBrush( QBrush( color ) );
00526     painter->drawRect( contentsRect() );
00527 }
00528 
00529 void KColorPatch::mouseMoveEvent( QMouseEvent *e )
00530 {
00531         // Drag color object
00532         if( !(e->state() && LeftButton)) return;
00533     KColorDrag *d = new KColorDrag( color, this);
00534     d->dragCopy();
00535 }
00536 
00537 void KColorPatch::dragEnterEvent( QDragEnterEvent *event)
00538 {
00539      event->accept( KColorDrag::canDecode( event));
00540 }
00541 
00542 void KColorPatch::dropEvent( QDropEvent *event)
00543 {
00544      QColor c;
00545      if( KColorDrag::decode( event, c)) {
00546       setColor( c);
00547       emit colorChanged( c);
00548      }
00549 }
00550 
00551 class KPaletteTable::KPaletteTablePrivate
00552 {
00553 public:
00554     QMap<QString,QColor> m_namedColorMap;
00555 };
00556 
00557 KPaletteTable::KPaletteTable( QWidget *parent, int minWidth, int cols)
00558     : QWidget( parent ), cells(0), mPalette(0), mMinWidth(minWidth), mCols(cols)
00559 {
00560   d = new KPaletteTablePrivate;
00561   
00562   i18n_namedColors  = i18n("Named Colors");
00563 
00564   QStringList diskPaletteList = KPalette::getPaletteList();
00565   QStringList paletteList;
00566 
00567   // We must replace the untranslated file names by translate names (of course only for KDE's standard palettes)
00568   for ( int i = 0; colorPaletteName[i].m_fileName; ++i )
00569   {
00570       diskPaletteList.remove( colorPaletteName[i].m_fileName );
00571       paletteList.append( i18n( "palette name", colorPaletteName[i].m_displayName ) );
00572   }
00573   paletteList += diskPaletteList;
00574   paletteList.append( i18n_namedColors );
00575 
00576   QVBoxLayout *layout = new QVBoxLayout( this );
00577 
00578   combo = new QComboBox( false, this );
00579   combo->insertStringList( paletteList );
00580   layout->addWidget(combo);
00581 
00582   sv = new QScrollView( this );
00583   QSize cellSize = QSize( mMinWidth, 120);
00584   sv->setHScrollBarMode( QScrollView::AlwaysOff);
00585   sv->setVScrollBarMode( QScrollView::AlwaysOn);
00586   QSize minSize = QSize(sv->verticalScrollBar()->width(), 0);
00587   minSize += QSize(sv->frameWidth(), 0);
00588   minSize += QSize(cellSize);
00589   sv->setFixedSize(minSize);
00590   layout->addWidget(sv);
00591 
00592   mNamedColorList = new KListBox( this, "namedColorList", 0 );
00593   mNamedColorList->setFixedSize(minSize);
00594   mNamedColorList->hide();
00595   layout->addWidget(mNamedColorList);
00596   connect( mNamedColorList, SIGNAL(highlighted( const QString & )),
00597        this, SLOT( slotColorTextSelected( const QString & )) );
00598 
00599   setFixedSize( sizeHint());
00600   connect( combo, SIGNAL(activated(const QString &)),
00601     this, SLOT(slotSetPalette( const QString &)));
00602 }
00603 
00604 KPaletteTable::~KPaletteTable()
00605 {
00606    delete mPalette;
00607    delete d;
00608 }
00609 
00610 QString
00611 KPaletteTable::palette() const
00612 {
00613   return combo->currentText();
00614 }
00615 
00616 
00617 static const char * const *namedColorFilePath( void )
00618 {
00619   //
00620   // 2000-02-05 Espen Sand.
00621   // Add missing filepaths here. Make sure the last entry is 0!
00622   //
00623   static const char * const path[] =
00624   {
00625 #ifdef X11_RGBFILE
00626     X11_RGBFILE,
00627 #endif
00628     "/usr/X11R6/lib/X11/rgb.txt",
00629     "/usr/openwin/lib/X11/rgb.txt", // for Solaris.
00630     0
00631   };
00632   return path;
00633 }
00634 
00635 
00636 
00637 
00638 void
00639 KPaletteTable::readNamedColor( void )
00640 {
00641   if( mNamedColorList->count() != 0 )
00642   {
00643     return; // Strings already present
00644   }
00645 
00646   KGlobal::locale()->insertCatalogue("kdelibs_colors");
00647 
00648   //
00649   // Code somewhat inspired by KPalette.
00650   //
00651 
00652   const char * const *path = namedColorFilePath();
00653   for( int i=0; path[i]; ++i )
00654   {
00655     QFile paletteFile( path[i] );
00656     if( !paletteFile.open( IO_ReadOnly ) )
00657     {
00658       continue;
00659     }
00660 
00661     QString line;
00662     QStringList list;
00663     while( paletteFile.readLine( line, 100 ) != -1 )
00664     {
00665       int red, green, blue;
00666       int pos = 0;
00667 
00668       if( sscanf(line.ascii(), "%d %d %d%n", &red, &green, &blue, &pos ) == 3 )
00669       {
00670     //
00671     // Remove duplicates. Every name with a space and every name
00672     // that start with "gray".
00673     //
00674     QString name = line.mid(pos).stripWhiteSpace();
00675     if( name.isNull() || name.find(' ') != -1 ||
00676         name.find( "gray" ) != -1 ||  name.find( "grey" ) != -1 )
00677     {
00678       continue;
00679     }
00680 
00681         const QColor color ( red, green, blue );
00682         if ( color.isValid() )
00683         {
00684             const QString colorName( i18n("color", name.latin1() ) );
00685             list.append( colorName );
00686             d->m_namedColorMap[ colorName ] = color;
00687         }
00688       }
00689     }
00690 
00691     list.sort();
00692     mNamedColorList->insertStringList( list );
00693     break;
00694   }
00695 
00696   if( mNamedColorList->count() == 0 )
00697   {
00698     //
00699     // Give the error dialog box a chance to center above the
00700     // widget (or dialog). If we had displayed it now we could get a
00701     // situation where the (modal) error dialog box pops up first
00702     // preventing the real dialog to become visible until the
00703     // error dialog box is removed (== bad UI).
00704     //
00705     QTimer::singleShot( 10, this, SLOT(slotShowNamedColorReadError()) );
00706   }
00707 }
00708 
00709 
00710 void
00711 KPaletteTable::slotShowNamedColorReadError( void )
00712 {
00713   if( mNamedColorList->count() == 0 )
00714   {
00715     QString msg = i18n(""
00716       "Unable to read X11 RGB color strings. The following "
00717       "file location(s) were examined:\n");
00718 
00719     const char * const *path = namedColorFilePath();
00720     for( int i=0; path[i]; ++i )
00721     {
00722       msg += path[i];
00723       msg += "\n";
00724     }
00725     KMessageBox::sorry( this, msg );
00726   }
00727 }
00728 
00729 
00730 //
00731 // 2000-02-12 Espen Sand
00732 // Set the color in two steps. The setPalette() slot will not emit a signal
00733 // with the current color setting. The reason is that setPalette() is used
00734 // by the color selector dialog on startup. In the color selector dialog
00735 // we normally want to display a startup color which we specify
00736 // when the dialog is started. The slotSetPalette() slot below will
00737 // set the palette and then use the information to emit a signal with the
00738 // new color setting. It is only used by the combobox widget.
00739 //
00740 void
00741 KPaletteTable::slotSetPalette( const QString &_paletteName )
00742 {
00743   setPalette( _paletteName );
00744   if( mNamedColorList->isVisible() )
00745   {
00746     int item = mNamedColorList->currentItem();
00747     mNamedColorList->setCurrentItem( item < 0 ? 0 : item );
00748     slotColorTextSelected( mNamedColorList->currentText() );
00749   }
00750   else
00751   {
00752     slotColorCellSelected(0); // FIXME: We need to save the current value!!
00753   }
00754 }
00755 
00756 
00757 void
00758 KPaletteTable::setPalette( const QString &_paletteName )
00759 {
00760   QString paletteName( _paletteName);
00761   if (paletteName.isEmpty())
00762      paletteName = i18n_recentColors;
00763 
00764   if (combo->currentText() != paletteName)
00765   {
00766      bool found = false;
00767      for(int i = 0; i < combo->count(); i++)
00768      {
00769         if (combo->text(i) == paletteName)
00770         {
00771            combo->setCurrentItem(i);
00772            found = true;
00773            break;
00774         }
00775      }
00776      if (!found)
00777      {
00778         combo->insertItem(paletteName);
00779         combo->setCurrentItem(combo->count()-1);
00780      }
00781   }
00782 
00783   // We must again find the file name of the palette from the eventual translation
00784   for ( int i = 0; colorPaletteName[i].m_fileName; ++i )
00785   {
00786       if ( paletteName == i18n( "palette name", colorPaletteName[i].m_displayName ) )
00787       {
00788           paletteName = colorPaletteName[i].m_fileName;
00789           break;
00790       }
00791   }
00792 
00793 
00794   //
00795   // 2000-02-12 Espen Sand
00796   // The palette mode "i18n_namedColors" does not use the KPalette class.
00797   // In fact, 'mPalette' and 'cells' are 0 when in this mode. The reason
00798   // for this is maninly that KPalette reads from and writes to files using
00799   // "locate()". The colors used in "i18n_namedColors" mode comes from the
00800   // X11 diretory and is not writable. I don't think this fit in KPalette.
00801   //
00802   if( !mPalette || mPalette->name() != paletteName )
00803   {
00804     if( paletteName == i18n_namedColors )
00805     {
00806       sv->hide();
00807       mNamedColorList->show();
00808       readNamedColor();
00809 
00810       delete cells; cells = 0;
00811       delete mPalette; mPalette = 0;
00812     }
00813     else
00814     {
00815       mNamedColorList->hide();
00816       sv->show();
00817 
00818       delete cells;
00819       delete mPalette;
00820       mPalette = new KPalette(paletteName);
00821       int rows = (mPalette->nrColors()+mCols-1) / mCols;
00822       if (rows < 1) rows = 1;
00823       cells = new KColorCells( sv->viewport(), rows, mCols);
00824       cells->setShading(false);
00825       cells->setAcceptDrags(false);
00826       QSize cellSize = QSize( mMinWidth, mMinWidth * rows / mCols);
00827       cells->setFixedSize( cellSize );
00828       for( int i = 0; i < mPalette->nrColors(); i++)
00829       {
00830         cells->setColor( i, mPalette->color(i) );
00831       }
00832       connect( cells, SIGNAL( colorSelected( int ) ),
00833            SLOT( slotColorCellSelected( int ) ) );
00834       connect( cells, SIGNAL( colorDoubleClicked( int ) ),
00835            SLOT( slotColorCellDoubleClicked( int ) ) );
00836       sv->addChild( cells );
00837       cells->show();
00838       sv->updateScrollBars();
00839     }
00840   }
00841 }
00842 
00843 
00844 
00845 void
00846 KPaletteTable::slotColorCellSelected( int col )
00847 {
00848   if (!mPalette || (col >= mPalette->nrColors()))
00849      return;
00850   emit colorSelected( mPalette->color(col), mPalette->colorName(col) );
00851 }
00852 
00853 void
00854 KPaletteTable::slotColorCellDoubleClicked( int col )
00855 {
00856   if (!mPalette || (col >= mPalette->nrColors()))
00857      return;
00858   emit colorDoubleClicked( mPalette->color(col), mPalette->colorName(col) );
00859 }
00860 
00861 
00862 void
00863 KPaletteTable::slotColorTextSelected( const QString &colorText )
00864 {
00865   emit colorSelected( d->m_namedColorMap[ colorText ], colorText );
00866 }
00867 
00868 
00869 void
00870 KPaletteTable::addToCustomColors( const QColor &color)
00871 {
00872   setPalette(i18n_customColors);
00873   mPalette->addColor( color );
00874   mPalette->save();
00875   delete mPalette;
00876   mPalette = 0;
00877   setPalette(i18n_customColors);
00878 }
00879 
00880 void
00881 KPaletteTable::addToRecentColors( const QColor &color)
00882 {
00883   //
00884   // 2000-02-12 Espen Sand.
00885   // The 'mPalette' is always 0 when current mode is i18n_namedColors
00886   //
00887   bool recentIsSelected = false;
00888   if ( mPalette && mPalette->name() == colorPaletteName[ recentColorIndex ].m_fileName )
00889   {
00890      delete mPalette;
00891      mPalette = 0;
00892      recentIsSelected = true;
00893   }
00894   KPalette *recentPal = new KPalette( colorPaletteName[ recentColorIndex ].m_fileName );
00895   if (recentPal->findColor(color) == -1)
00896   {
00897      recentPal->addColor( color );
00898      recentPal->save();
00899   }
00900   delete recentPal;
00901   if (recentIsSelected)
00902       setPalette( i18n( "palette name", colorPaletteName[ recentColorIndex ].m_displayName ) );
00903 }
00904 
00905 class KColorDialog::KColorDialogPrivate {
00906 public:
00907     KPaletteTable *table;
00908     QString originalPalette;
00909     bool bRecursion;
00910     bool bEditRgb;
00911     bool bEditHsv;
00912     bool bEditHtml;
00913     bool bColorPicking;
00914     QLabel *colorName;
00915     QLineEdit *htmlName;
00916     KColorSpinBox *hedit;
00917     KColorSpinBox *sedit;
00918     KColorSpinBox *vedit;
00919     KColorSpinBox *redit;
00920     KColorSpinBox *gedit;
00921     KColorSpinBox *bedit;
00922     KColorPatch *patch;
00923     KHSSelector *hsSelector;
00924     KPalette *palette;
00925     KValueSelector *valuePal;
00926     QVBoxLayout* l_right;
00927     QGridLayout* tl_layout;
00928     QCheckBox *cbDefaultColor;
00929     KColor defaultColor;
00930     KColor selColor;
00931 #ifdef Q_WS_X11
00932     QX11EventFilter oldfilter;
00933 #endif
00934 };
00935 
00936 
00937 KColorDialog::KColorDialog( QWidget *parent, const char *name, bool modal )
00938   :KDialogBase( parent, name, modal, i18n("Select Color"),
00939         modal ? Ok|Cancel : Close,
00940         Ok, true )
00941 {
00942   d = new KColorDialogPrivate;
00943   d->bRecursion = true;
00944   d->bColorPicking = false;
00945 #ifdef Q_WS_X11
00946   d->oldfilter = 0;
00947 #endif
00948   d->cbDefaultColor = 0L;
00949   connect( this, SIGNAL(okClicked(void)),this,SLOT(slotWriteSettings(void)));
00950   connect( this, SIGNAL(closeClicked(void)),this,SLOT(slotWriteSettings(void)));
00951 
00952   QLabel *label;
00953 
00954   //
00955   // Create the top level page and its layout
00956   //
00957   QWidget *page = new QWidget( this );
00958   setMainWidget( page );
00959 
00960   QGridLayout *tl_layout = new QGridLayout( page, 3, 3, 0, spacingHint() );
00961   d->tl_layout = tl_layout;
00962   tl_layout->addColSpacing( 1, spacingHint() * 2 );
00963 
00964   //
00965   // the more complicated part: the left side
00966   // add a V-box
00967   //
00968   QVBoxLayout *l_left = new QVBoxLayout();
00969   tl_layout->addLayout(l_left, 0, 0);
00970 
00971   //
00972   // add a H-Box for the XY-Selector and a grid for the
00973   // entry fields
00974   //
00975   QHBoxLayout *l_ltop = new QHBoxLayout();
00976   l_left->addLayout(l_ltop);
00977 
00978   // a little space between
00979   l_left->addSpacing(10);
00980 
00981   QGridLayout *l_lbot = new QGridLayout(3, 6);
00982   l_left->addLayout(l_lbot);
00983 
00984   //
00985   // the palette and value selector go into the H-box
00986   //
00987   d->hsSelector = new KHSSelector( page );
00988   d->hsSelector->setMinimumSize(140, 70);
00989   l_ltop->addWidget(d->hsSelector, 8);
00990   connect( d->hsSelector, SIGNAL( valueChanged( int, int ) ),
00991        SLOT( slotHSChanged( int, int ) ) );
00992 
00993   d->valuePal = new KValueSelector( page );
00994   d->valuePal->setMinimumSize(26, 70);
00995   l_ltop->addWidget(d->valuePal, 1);
00996   connect( d->valuePal, SIGNAL( valueChanged( int ) ),
00997        SLOT( slotVChanged( int ) ) );
00998 
00999 
01000   //
01001   // add the HSV fields
01002   //
01003   label = new QLabel( i18n("H:"), page );
01004   label->setAlignment(AlignRight | AlignVCenter);
01005   l_lbot->addWidget(label, 0, 2);
01006   d->hedit = new KColorSpinBox( 0, 359, 1, page );
01007   d->hedit->setValidator( new QIntValidator( d->hedit ) );
01008   l_lbot->addWidget(d->hedit, 0, 3);
01009   connect( d->hedit, SIGNAL( valueChanged(int) ),
01010     SLOT( slotHSVChanged() ) );
01011 
01012   label = new QLabel( i18n("S:"), page );
01013   label->setAlignment(AlignRight | AlignVCenter);
01014   l_lbot->addWidget(label, 1, 2);
01015   d->sedit = new KColorSpinBox( 0, 255, 1, page );
01016   d->sedit->setValidator( new QIntValidator( d->sedit ) );
01017   l_lbot->addWidget(d->sedit, 1, 3);
01018   connect( d->sedit, SIGNAL( valueChanged(int) ),
01019     SLOT( slotHSVChanged() ) );
01020 
01021   label = new QLabel( i18n("V:"), page );
01022   label->setAlignment(AlignRight | AlignVCenter);
01023   l_lbot->addWidget(label, 2, 2);
01024   d->vedit = new KColorSpinBox( 0, 255, 1, page );
01025   d->vedit->setValidator( new QIntValidator( d->vedit ) );
01026   l_lbot->addWidget(d->vedit, 2, 3);
01027   connect( d->vedit, SIGNAL( valueChanged(int) ),
01028     SLOT( slotHSVChanged() ) );
01029 
01030   //
01031   // add the RGB fields
01032   //
01033   label = new QLabel( i18n("R:"), page );
01034   label->setAlignment(AlignRight | AlignVCenter);
01035   l_lbot->addWidget(label, 0, 4);
01036   d->redit = new KColorSpinBox( 0, 255, 1, page );
01037   d->redit->setValidator( new QIntValidator( d->redit ) );
01038   l_lbot->addWidget(d->redit, 0, 5);
01039   connect( d->redit, SIGNAL( valueChanged(int) ),
01040     SLOT( slotRGBChanged() ) );
01041 
01042   label = new QLabel( i18n("G:"), page );
01043   label->setAlignment(AlignRight | AlignVCenter);
01044   l_lbot->addWidget( label, 1, 4);
01045   d->gedit = new KColorSpinBox( 0, 255,1, page );
01046   d->gedit->setValidator( new QIntValidator( d->gedit ) );
01047   l_lbot->addWidget(d->gedit, 1, 5);
01048   connect( d->gedit, SIGNAL( valueChanged(int) ),
01049     SLOT( slotRGBChanged() ) );
01050 
01051   label = new QLabel( i18n("B:"), page );
01052   label->setAlignment(AlignRight | AlignVCenter);
01053   l_lbot->addWidget(label, 2, 4);
01054   d->bedit = new KColorSpinBox( 0, 255, 1, page );
01055   d->bedit->setValidator( new QIntValidator( d->bedit ) );
01056   l_lbot->addWidget(d->bedit, 2, 5);
01057   connect( d->bedit, SIGNAL( valueChanged(int) ),
01058     SLOT( slotRGBChanged() ) );
01059 
01060   //
01061   // the entry fields should be wide enough to hold 8888888
01062   //
01063   int w = d->hedit->fontMetrics().width("8888888");
01064   d->hedit->setFixedWidth(w);
01065   d->sedit->setFixedWidth(w);
01066   d->vedit->setFixedWidth(w);
01067 
01068   d->redit->setFixedWidth(w);
01069   d->gedit->setFixedWidth(w);
01070   d->bedit->setFixedWidth(w);
01071 
01072   //
01073   // add a layout for the right side
01074   //
01075   d->l_right = new QVBoxLayout;
01076   tl_layout->addLayout(d->l_right, 0, 2);
01077 
01078   //
01079   // Add the palette table
01080   //
01081   d->table = new KPaletteTable( page );
01082   d->l_right->addWidget(d->table, 10);
01083 
01084   connect( d->table, SIGNAL( colorSelected( const QColor &, const QString & ) ),
01085        SLOT( slotColorSelected( const QColor &, const QString & ) ) );
01086 
01087   connect(
01088     d->table,
01089     SIGNAL( colorDoubleClicked( const QColor &, const QString & ) ),
01090     SLOT( slotColorDoubleClicked( const QColor &, const QString & ) )
01091   );
01092   // Store the default value for saving time.
01093   d->originalPalette = d->table->palette();
01094 
01095   //
01096   // a little space between
01097   //
01098   d->l_right->addSpacing(10);
01099 
01100   QHBoxLayout *l_hbox = new QHBoxLayout( d->l_right );
01101 
01102   //
01103   // The add to custom colors button
01104   //
01105   QPushButton *button = new QPushButton( page );
01106   button->setText(i18n("&Add to Custom Colors"));
01107   l_hbox->addWidget(button, 0, AlignLeft);
01108   connect( button, SIGNAL( clicked()), SLOT( slotAddToCustomColors()));
01109 
01110   //
01111   // The color picker button
01112   //
01113   button = new QPushButton( page );
01114   button->setPixmap( BarIcon("colorpicker"));
01115   l_hbox->addWidget(button, 0, AlignHCenter );
01116   connect( button, SIGNAL( clicked()), SLOT( slotColorPicker()));
01117 
01118   //
01119   // a little space between
01120   //
01121   d->l_right->addSpacing(10);
01122 
01123   //
01124   // and now the entry fields and the patch (=colored box)
01125   //
01126   QGridLayout *l_grid = new QGridLayout( d->l_right, 2, 3);
01127 
01128   l_grid->setColStretch(2, 1);
01129 
01130   label = new QLabel( page );
01131   label->setText(i18n("Name:"));
01132   l_grid->addWidget(label, 0, 1, AlignLeft);
01133 
01134   d->colorName = new QLabel( page );
01135   l_grid->addWidget(d->colorName, 0, 2, AlignLeft);
01136 
01137   label = new QLabel( page );
01138   label->setText(i18n("HTML:"));
01139   l_grid->addWidget(label, 1, 1, AlignLeft);
01140 
01141   d->htmlName = new QLineEdit( page );
01142   d->htmlName->setMaxLength( 13 ); // Qt's QColor allows 12 hexa-digits
01143   d->htmlName->setText("#FFFFFF"); // But HTML uses only 6, so do not worry about the size
01144   w = d->htmlName->fontMetrics().width(QString::fromLatin1("#DDDDDDD"));
01145   d->htmlName->setFixedWidth(w);
01146   l_grid->addWidget(d->htmlName, 1, 2, AlignLeft);
01147 
01148   connect( d->htmlName, SIGNAL( textChanged(const QString &) ),
01149       SLOT( slotHtmlChanged() ) );
01150 
01151   d->patch = new KColorPatch( page );
01152   d->patch->setFixedSize(48, 48);
01153   l_grid->addMultiCellWidget(d->patch, 0, 1, 0, 0, AlignHCenter | AlignVCenter);
01154   connect( d->patch, SIGNAL( colorChanged( const QColor&)),
01155        SLOT( setColor( const QColor&)));
01156 
01157   tl_layout->activate();
01158   page->setMinimumSize( page->sizeHint() );
01159 
01160   readSettings();
01161   d->bRecursion = false;
01162   d->bEditHsv = false;
01163   d->bEditRgb = false;
01164   d->bEditHtml = false;
01165 
01166   disableResize();
01167   KColor col;
01168   col.setHsv( 0, 0, 255 );
01169   _setColor( col );
01170 
01171   d->htmlName->installEventFilter(this);
01172   d->hsSelector->installEventFilter(this);
01173   d->hsSelector->setAcceptDrops(true);
01174 }
01175 
01176 KColorDialog::~KColorDialog()
01177 {
01178 #ifdef Q_WS_X11
01179     if (d->bColorPicking)
01180         qt_set_x11_event_filter(d->oldfilter);
01181 #endif
01182     delete d;
01183 }
01184 
01185 bool
01186 KColorDialog::eventFilter( QObject *obj, QEvent *ev )
01187 {
01188     if ((obj == d->htmlName) || (obj == d->hsSelector))
01189     switch(ev->type())
01190     {
01191       case QEvent::DragEnter:
01192       case QEvent::DragMove:
01193       case QEvent::DragLeave:
01194       case QEvent::Drop:
01195       case QEvent::DragResponse:
01196             qApp->sendEvent(d->patch, ev);
01197             return true;
01198       default:
01199             break;
01200     }
01201     return KDialogBase::eventFilter(obj, ev);
01202 }
01203 
01204 void
01205 KColorDialog::setDefaultColor( const QColor& col )
01206 {
01207     if ( !d->cbDefaultColor )
01208     {
01209         //
01210         // a little space between
01211         //
01212         d->l_right->addSpacing(10);
01213 
01214         //
01215         // and the "default color" checkbox, under all items on the right side
01216         //
01217         d->cbDefaultColor = new QCheckBox( i18n( "Default color" ), mainWidget() );
01218         d->cbDefaultColor->setChecked(true);
01219 
01220         d->l_right->addWidget( d->cbDefaultColor );
01221 
01222         mainWidget()->setMaximumSize( QWIDGETSIZE_MAX, QWIDGETSIZE_MAX ); // cancel setFixedSize()
01223         d->tl_layout->activate();
01224         mainWidget()->setMinimumSize( mainWidget()->sizeHint() );
01225         disableResize();
01226 
01227         connect( d->cbDefaultColor, SIGNAL( clicked() ), SLOT( slotDefaultColorClicked() ) );
01228     }
01229 
01230     d->defaultColor = col;
01231 
01232     slotDefaultColorClicked();
01233 }
01234 
01235 QColor KColorDialog::defaultColor() const
01236 {
01237     return d->defaultColor;
01238 }
01239 
01240 void KColorDialog::slotDefaultColorClicked()
01241 {
01242     if ( d->cbDefaultColor->isChecked() )
01243     {
01244         d->selColor = d->defaultColor;
01245         showColor( d->selColor, i18n( "-default-" ) );
01246     } else
01247     {
01248         showColor( d->selColor, QString::null );
01249     }
01250 }
01251 
01252 void
01253 KColorDialog::readSettings()
01254 {
01255   KConfig* config = KGlobal::config();
01256 
01257   QString oldgroup = config->group();
01258 
01259   config->setGroup("Colors");
01260   QString palette = config->readEntry("CurrentPalette");
01261   d->table->setPalette(palette);
01262   config->setGroup( oldgroup );
01263 }
01264 
01265 void
01266 KColorDialog::slotWriteSettings()
01267 {
01268   KConfig* config = KGlobal::config();
01269   config->setGroup("Colors");
01270   QString palette = d->table->palette();
01271   if (!config->hasDefault("CurrentPalette") &&
01272       (d->table->palette() == d->originalPalette))
01273   {
01274      config->revertToDefault("CurrentPalette");
01275   }
01276   else
01277   {
01278      config->writeEntry("CurrentPalette", d->table->palette());
01279   }
01280 }
01281 
01282 QColor
01283 KColorDialog::color() const
01284 {
01285   if ( d->cbDefaultColor && d->cbDefaultColor->isChecked() )
01286      return QColor();
01287   if ( d->selColor.isValid() )
01288     d->table->addToRecentColors( d->selColor );
01289   return d->selColor;
01290 }
01291 
01292 void KColorDialog::setColor( const QColor &col )
01293 {
01294   _setColor( col );
01295 }
01296 
01297 //
01298 // static function to display dialog and return color
01299 //
01300 int KColorDialog::getColor( QColor &theColor, QWidget *parent )
01301 {
01302   KColorDialog dlg( parent, "Color Selector", true );
01303   if ( theColor.isValid() )
01304     dlg.setColor( theColor );
01305   int result = dlg.exec();
01306 
01307   if ( result == Accepted )
01308   {
01309     theColor = dlg.color();
01310   }
01311 
01312   return result;
01313 }
01314 
01315 //
01316 // static function to display dialog and return color
01317 //
01318 int KColorDialog::getColor( QColor &theColor, const QColor& defaultCol, QWidget *parent )
01319 {
01320   KColorDialog dlg( parent, "Color Selector", true );
01321   dlg.setDefaultColor( defaultCol );
01322   dlg.setColor( theColor );
01323   int result = dlg.exec();
01324 
01325   if ( result == Accepted )
01326     theColor = dlg.color();
01327 
01328   return result;
01329 }
01330 
01331 void KColorDialog::slotRGBChanged( void )
01332 {
01333   if (d->bRecursion) return;
01334   int red = d->redit->value();
01335   int grn = d->gedit->value();
01336   int blu = d->bedit->value();
01337 
01338   if ( red > 255 || red < 0 ) return;
01339   if ( grn > 255 || grn < 0 ) return;
01340   if ( blu > 255 || blu < 0 ) return;
01341 
01342   KColor col;
01343   col.setRgb( red, grn, blu );
01344   d->bEditRgb = true;
01345   _setColor( col );
01346   d->bEditRgb = false;
01347 }
01348 
01349 void KColorDialog::slotHtmlChanged( void )
01350 {
01351   if (d->bRecursion || d->htmlName->text().isEmpty()) return;
01352 
01353   QString strColor( d->htmlName->text() );
01354 
01355   // Assume that a user does not want to type the # all the time
01356   if ( strColor[0] != '#' )
01357   {
01358     bool signalsblocked = d->htmlName->signalsBlocked();
01359     d->htmlName->blockSignals(true);
01360     strColor.prepend("#");
01361     d->htmlName->setText(strColor);
01362     d->htmlName->blockSignals(signalsblocked);
01363   }
01364 
01365   const QColor color( strColor );
01366 
01367   if ( color.isValid() )
01368   {
01369     KColor col( color );
01370     d->bEditHtml = true;
01371     _setColor( col );
01372     d->bEditHtml = false;
01373   }
01374 }
01375 
01376 void KColorDialog::slotHSVChanged( void )
01377 {
01378   if (d->bRecursion) return;
01379   int hue = d->hedit->value();
01380   int sat = d->sedit->value();
01381   int val = d->vedit->value();
01382 
01383   if ( hue > 359 || hue < 0 ) return;
01384   if ( sat > 255 || sat < 0 ) return;
01385   if ( val > 255 || val < 0 ) return;
01386 
01387   KColor col;
01388   col.setHsv( hue, sat, val );
01389   d->bEditHsv = true;
01390   _setColor( col );
01391   d->bEditHsv = false;
01392 }
01393 
01394 void KColorDialog::slotHSChanged( int h, int s )
01395 {
01396   int _h, _s, v;
01397   d->selColor.hsv(&_h, &_s, &v);
01398   if (v < 0)
01399      v = 0;
01400   KColor col;
01401   col.setHsv( h, s, v );
01402   _setColor( col );
01403 }
01404 
01405 void KColorDialog::slotVChanged( int v )
01406 {
01407   int h, s, _v;
01408   d->selColor.hsv(&h, &s, &_v);
01409   KColor col;
01410   col.setHsv( h, s, v );
01411   _setColor( col );
01412 }
01413 
01414 void KColorDialog::slotColorSelected( const QColor &color )
01415 {
01416   _setColor( color );
01417 }
01418 
01419 void KColorDialog::slotAddToCustomColors( )
01420 {
01421   d->table->addToCustomColors( d->selColor );
01422 }
01423 
01424 void KColorDialog::slotColorSelected( const QColor &color, const QString &name )
01425 {
01426   _setColor( color, name);
01427 }
01428 
01429 void KColorDialog::slotColorDoubleClicked
01430 (
01431   const QColor  & color,
01432   const QString & name
01433 )
01434 {
01435   _setColor(color, name);
01436   accept();
01437 }
01438 
01439 void KColorDialog::_setColor(const KColor &color, const QString &name)
01440 {
01441   if (color.isValid())
01442   {
01443      if (d->cbDefaultColor && d->cbDefaultColor->isChecked())
01444         d->cbDefaultColor->setChecked(false);
01445      d->selColor = color;
01446   }
01447   else
01448   {
01449      if (d->cbDefaultColor && d->cbDefaultColor->isChecked())
01450         d->cbDefaultColor->setChecked(true);
01451      d->selColor = d->defaultColor;
01452   }
01453 
01454   showColor( d->selColor, name );
01455 
01456   emit colorSelected( d->selColor );
01457 }
01458 
01459 // show but don't set into selColor, nor emit colorSelected
01460 void KColorDialog::showColor( const KColor &color, const QString &name )
01461 {
01462   d->bRecursion = true;
01463 
01464   if (name.isEmpty())
01465      d->colorName->setText( i18n("-unnamed-"));
01466   else
01467      d->colorName->setText( name );
01468 
01469   d->patch->setColor( color );
01470 
01471   setRgbEdit( color );
01472   setHsvEdit( color );
01473   setHtmlEdit( color );
01474 
01475   int h, s, v;
01476   color.hsv( &h, &s, &v );
01477   d->hsSelector->setValues( h, s );
01478   d->valuePal->blockSignals(true);
01479   d->valuePal->setHue( h );
01480   d->valuePal->setSaturation( s );
01481   d->valuePal->setValue( v );
01482   d->valuePal->updateContents();
01483   d->valuePal->blockSignals(false);
01484   d->valuePal->repaint( false );
01485   d->bRecursion = false;
01486 }
01487 
01488 
01489 static QWidget *kde_color_dlg_widget = 0;
01490 
01491 #ifdef Q_WS_X11
01492 static int kde_color_dlg_handler(XEvent *event)
01493 {
01494     if (event->type == ButtonRelease)
01495     {
01496         QMouseEvent e( QEvent::MouseButtonRelease, QPoint(),
01497                        QPoint(event->xmotion.x_root, event->xmotion.y_root) , 0, 0 );
01498         QApplication::sendEvent( kde_color_dlg_widget, &e );
01499         return true;
01500     }
01501     return false;
01502 }
01503 #endif
01504 void
01505 KColorDialog::slotColorPicker()
01506 {
01507     d->bColorPicking = true;
01508 #ifdef Q_WS_X11
01509     d->oldfilter = qt_set_x11_event_filter(kde_color_dlg_handler);
01510 #endif
01511     kde_color_dlg_widget = this;
01512     grabMouse( crossCursor );
01513     grabKeyboard();
01514 }
01515 
01516 void
01517 KColorDialog::mouseReleaseEvent( QMouseEvent *e )
01518 {
01519   if (d->bColorPicking)
01520   {
01521      d->bColorPicking = false;
01522 #ifdef Q_WS_X11
01523      qt_set_x11_event_filter(d->oldfilter);
01524      d->oldfilter = 0;
01525 #endif
01526      releaseMouse();
01527      releaseKeyboard();
01528      _setColor( grabColor( e->globalPos() ) );
01529      return;
01530   }
01531   KDialogBase::mouseReleaseEvent( e );
01532 }
01533 
01534 QColor
01535 KColorDialog::grabColor(const QPoint &p)
01536 {
01537     QWidget *desktop = QApplication::desktop();
01538     QPixmap pm = QPixmap::grabWindow( desktop->winId(), p.x(), p.y(), 1, 1);
01539     QImage i = pm.convertToImage();
01540     return i.pixel(0,0);
01541 }
01542 
01543 void
01544 KColorDialog::keyPressEvent( QKeyEvent *e )
01545 {
01546   if (d->bColorPicking)
01547   {
01548      if (e->key() == Key_Escape)
01549      {
01550         d->bColorPicking = false;
01551 #ifdef Q_WS_X11
01552         qt_set_x11_event_filter(d->oldfilter);
01553         d->oldfilter = 0;
01554 #endif
01555         releaseMouse();
01556         releaseKeyboard();
01557      }
01558      e->accept();
01559      return;
01560   }
01561   KDialogBase::keyPressEvent( e );
01562 }
01563 
01564 void KColorDialog::setRgbEdit( const KColor &col )
01565 {
01566   if (d->bEditRgb) return;
01567   int r, g, b;
01568   col.rgb( &r, &g, &b );
01569 
01570   d->redit->setValue( r );
01571   d->gedit->setValue( g );
01572   d->bedit->setValue( b );
01573 }
01574 
01575 void KColorDialog::setHtmlEdit( const KColor &col )
01576 {
01577   if (d->bEditHtml) return;
01578   int r, g, b;
01579   col.rgb( &r, &g, &b );
01580   QString num;
01581 
01582   num.sprintf("#%02X%02X%02X", r,g,b);
01583   d->htmlName->setText( num );
01584 }
01585 
01586 
01587 void KColorDialog::setHsvEdit( const KColor &col )
01588 {
01589   if (d->bEditHsv) return;
01590   int h, s, v;
01591   col.hsv( &h, &s, &v );
01592 
01593   d->hedit->setValue( h );
01594   d->sedit->setValue( s );
01595   d->vedit->setValue( v );
01596 }
01597 
01598 void KHSSelector::virtual_hook( int id, void* data )
01599 { KXYSelector::virtual_hook( id, data ); }
01600 
01601 void KValueSelector::virtual_hook( int id, void* data )
01602 { KSelector::virtual_hook( id, data ); }
01603 
01604 void KPaletteTable::virtual_hook( int, void* )
01605 { /*BASE::virtual_hook( id, data );*/ }
01606 
01607 void KColorCells::virtual_hook( int, void* )
01608 { /*BASE::virtual_hook( id, data );*/ }
01609 
01610 void KColorPatch::virtual_hook( int, void* )
01611 { /*BASE::virtual_hook( id, data );*/ }
01612 
01613 void KColorDialog::virtual_hook( int id, void* data )
01614 { KDialogBase::virtual_hook( id, data ); }
01615 
01616 
01617 #include "kcolordialog.moc"
01618 //#endif
KDE Home | KDE Accessibility Home | Description of Access Keys