00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
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 #ifdef Q_WS_X11
00068 #include <X11/Xlib.h>
00069
00070
00071 typedef int (*QX11EventFilter) (XEvent*);
00072 extern QX11EventFilter qt_set_x11_event_filter (QX11EventFilter filter);
00073
00074 #define HSV_X 305
00075 #define RGB_X 385
00076
00077 static const char * const recentColors = "Recent_Colors";
00078 static const char * const customColors = "Custom_Colors";
00079
00080 class KColorSpinBox : public QSpinBox
00081 {
00082 public:
00083 KColorSpinBox(int minValue, int maxValue, int step, QWidget* parent)
00084 : QSpinBox(minValue, maxValue, step, parent, "kcolorspinbox")
00085 { }
00086
00087
00088 virtual void valueChange()
00089 {
00090 updateDisplay();
00091 emit valueChanged( value() );
00092 emit valueChanged( currentValueText() );
00093 }
00094
00095 };
00096
00097
00098 #define STANDARD_PAL_SIZE 17
00099
00100 KColor::KColor()
00101 : QColor()
00102 {
00103 r = 0; g = 0; b = 0; h = 0; s = 0; v = 0;
00104 };
00105
00106 KColor::KColor( const KColor &col)
00107 : QColor( col )
00108 {
00109 h = col.h; s = col.s; v = col.v;
00110 r = col.r; g = col.g; b = col.b;
00111 };
00112
00113 KColor::KColor( const QColor &col)
00114 : QColor( col )
00115 {
00116 QColor::rgb(&r, &g, &b);
00117 QColor::hsv(&h, &s, &v);
00118 };
00119
00120 bool KColor::operator==(const KColor& col) const
00121 {
00122 return (h == col.h) && (s == col.s) && (v == col.v) &&
00123 (r == col.r) && (g == col.g) && (b == col.b);
00124 }
00125
00126 KColor& KColor::operator=(const KColor& col)
00127 {
00128 *(QColor *)this = col;
00129 h = col.h; s = col.s; v = col.v;
00130 r = col.r; g = col.g; b = col.b;
00131 return *this;
00132 }
00133
00134 void
00135 KColor::setHsv(int _h, int _s, int _v)
00136 {
00137 h = _h; s = _s; v = _v;
00138 QColor::setHsv(h, s, v);
00139 QColor::rgb(&r, &g, &b);
00140 };
00141
00142 void
00143 KColor::setRgb(int _r, int _g, int _b)
00144 {
00145 r = _r; g = _g; b = _b;
00146 QColor::setRgb(r, g, b);
00147 QColor::hsv(&h, &s, &v);
00148 }
00149
00150 void
00151 KColor::rgb(int *_r, int *_g, int *_b) const
00152 {
00153 *_r = r; *_g = g; *_b = b;
00154 }
00155
00156 void
00157 KColor::hsv(int *_h, int *_s, int *_v) const
00158 {
00159 *_h = h; *_s = s; *_v = v;
00160 }
00161
00162
00163 static QColor *standardPalette = 0;
00164 static KStaticDeleter<QColor> spd;
00165
00166 static void createStandardPalette()
00167 {
00168 if ( standardPalette )
00169 return;
00170
00171 standardPalette = spd.setObject(new QColor [STANDARD_PAL_SIZE], true);
00172
00173 int i = 0;
00174
00175 standardPalette[i++] = Qt::red;
00176 standardPalette[i++] = Qt::green;
00177 standardPalette[i++] = Qt::blue;
00178 standardPalette[i++] = Qt::cyan;
00179 standardPalette[i++] = Qt::magenta;
00180 standardPalette[i++] = Qt::yellow;
00181 standardPalette[i++] = Qt::darkRed;
00182 standardPalette[i++] = Qt::darkGreen;
00183 standardPalette[i++] = Qt::darkBlue;
00184 standardPalette[i++] = Qt::darkCyan;
00185 standardPalette[i++] = Qt::darkMagenta;
00186 standardPalette[i++] = Qt::darkYellow;
00187 standardPalette[i++] = Qt::white;
00188 standardPalette[i++] = Qt::lightGray;
00189 standardPalette[i++] = Qt::gray;
00190 standardPalette[i++] = Qt::darkGray;
00191 standardPalette[i++] = Qt::black;
00192 }
00193
00194
00195 KHSSelector::KHSSelector( QWidget *parent, const char *name )
00196 : KXYSelector( parent, name )
00197 {
00198 setRange( 0, 0, 359, 255 );
00199 }
00200
00201 void KHSSelector::updateContents()
00202 {
00203 drawPalette(&pixmap);
00204 }
00205
00206 void KHSSelector::resizeEvent( QResizeEvent * )
00207 {
00208 updateContents();
00209 }
00210
00211 void KHSSelector::drawContents( QPainter *painter )
00212 {
00213 painter->drawPixmap( contentsRect().x(), contentsRect().y(), pixmap );
00214 }
00215
00216 void KHSSelector::drawPalette( QPixmap *pixmap )
00217 {
00218 int xSize = contentsRect().width(), ySize = contentsRect().height();
00219 QImage image( xSize, ySize, 32 );
00220 QColor col;
00221 int h, s;
00222 uint *p;
00223
00224 for ( s = ySize-1; s >= 0; s-- )
00225 {
00226 p = (uint *) image.scanLine( ySize - s - 1 );
00227 for( h = 0; h < xSize; h++ )
00228 {
00229 col.setHsv( 359*h/(xSize-1), 255*s/(ySize-1), 192 );
00230 *p = col.rgb();
00231 p++;
00232 }
00233 }
00234
00235 if ( QColor::numBitPlanes() <= 8 )
00236 {
00237 createStandardPalette();
00238 KImageEffect::dither( image, standardPalette, STANDARD_PAL_SIZE );
00239 }
00240 pixmap->convertFromImage( image );
00241 }
00242
00243
00244
00245
00246 KValueSelector::KValueSelector( QWidget *parent, const char *name )
00247 : KSelector( KSelector::Vertical, parent, name ), _hue(0), _sat(0)
00248 {
00249 setRange( 0, 255 );
00250 pixmap.setOptimization( QPixmap::BestOptim );
00251 }
00252
00253 KValueSelector::KValueSelector(Orientation o, QWidget *parent, const char *name
00254 )
00255 : KSelector( o, parent, name), _hue(0), _sat(0)
00256 {
00257 setRange( 0, 255 );
00258 pixmap.setOptimization( QPixmap::BestOptim );
00259 }
00260
00261 void KValueSelector::updateContents()
00262 {
00263 drawPalette(&pixmap);
00264 }
00265
00266 void KValueSelector::resizeEvent( QResizeEvent * )
00267 {
00268 updateContents();
00269 }
00270
00271 void KValueSelector::drawContents( QPainter *painter )
00272 {
00273 painter->drawPixmap( contentsRect().x(), contentsRect().y(), pixmap );
00274 }
00275
00276 void KValueSelector::drawPalette( QPixmap *pixmap )
00277 {
00278 int xSize = contentsRect().width(), ySize = contentsRect().height();
00279 QImage image( xSize, ySize, 32 );
00280 QColor col;
00281 uint *p;
00282 QRgb rgb;
00283
00284 if ( orientation() == KSelector::Horizontal )
00285 {
00286 for ( int v = 0; v < ySize; v++ )
00287 {
00288 p = (uint *) image.scanLine( ySize - v - 1 );
00289
00290 for( int x = 0; x < xSize; x++ )
00291 {
00292 col.setHsv( _hue, _sat, 255*x/(xSize-1) );
00293 rgb = col.rgb();
00294 *p++ = rgb;
00295 }
00296 }
00297 }
00298
00299 if( orientation() == KSelector::Vertical )
00300 {
00301 for ( int v = 0; v < ySize; v++ )
00302 {
00303 p = (uint *) image.scanLine( ySize - v - 1 );
00304 col.setHsv( _hue, _sat, 255*v/(ySize-1) );
00305 rgb = col.rgb();
00306 for ( int i = 0; i < xSize; i++ )
00307 *p++ = rgb;
00308 }
00309 }
00310
00311 if ( QColor::numBitPlanes() <= 8 )
00312 {
00313 createStandardPalette();
00314 KImageEffect::dither( image, standardPalette, STANDARD_PAL_SIZE );
00315 }
00316 pixmap->convertFromImage( image );
00317 }
00318
00319
00320
00321 KColorCells::KColorCells( QWidget *parent, int rows, int cols )
00322 : QGridView( parent )
00323 {
00324 shade = true;
00325 setNumRows( rows );
00326 setNumCols( cols );
00327 colors = new QColor [ rows * cols ];
00328
00329 for ( int i = 0; i < rows * cols; i++ )
00330 colors[i] = QColor();
00331
00332 selected = 0;
00333 inMouse = false;
00334
00335
00336 setAcceptDrops( true);
00337
00338 setHScrollBarMode( AlwaysOff );
00339 setVScrollBarMode( AlwaysOff );
00340 viewport()->setBackgroundMode( PaletteBackground );
00341 setBackgroundMode( PaletteBackground );
00342 }
00343
00344 KColorCells::~KColorCells()
00345 {
00346 delete [] colors;
00347 }
00348
00349 void KColorCells::setColor( int colNum, const QColor &col )
00350 {
00351 colors[colNum] = col;
00352 updateCell( colNum/numCols(), colNum%numCols() );
00353 }
00354
00355 void KColorCells::paintCell( QPainter *painter, int row, int col )
00356 {
00357 QBrush brush;
00358 int w = 1;
00359
00360 if (shade)
00361 {
00362 qDrawShadePanel( painter, 1, 1, cellWidth()-2,
00363 cellHeight()-2, colorGroup(), TRUE, 1, &brush );
00364 w = 2;
00365 }
00366 QColor color = colors[ row * numCols() + col ];
00367 if (!color.isValid())
00368 {
00369 if (!shade) return;
00370 color = backgroundColor();
00371 }
00372
00373 painter->setPen( color );
00374 painter->setBrush( QBrush( color ) );
00375 painter->drawRect( w, w, cellWidth()-w*2, cellHeight()-w*2 );
00376
00377 if ( row * numCols() + col == selected )
00378 painter->drawWinFocusRect( w, w, cellWidth()-w*2, cellHeight()-w*2 );
00379 }
00380
00381 void KColorCells::resizeEvent( QResizeEvent * )
00382 {
00383 setCellWidth( width() / numCols() );
00384 setCellHeight( height() / numRows() );
00385 }
00386
00387 void KColorCells::mousePressEvent( QMouseEvent *e )
00388 {
00389 inMouse = true;
00390 mPos = e->pos();
00391 }
00392
00393 int KColorCells::posToCell(const QPoint &pos, bool ignoreBorders)
00394 {
00395 int row = pos.y() / cellHeight();
00396 int col = pos.x() / cellWidth();
00397 int cell = row * numCols() + col;
00398
00399 if (!ignoreBorders)
00400 {
00401 int border = 2;
00402 int x = pos.x() - col * cellWidth();
00403 int y = pos.y() - row * cellHeight();
00404 if ( (x < border) || (x > cellWidth()-border) ||
00405 (y < border) || (y > cellHeight()-border))
00406 return -1;
00407 }
00408 return cell;
00409 }
00410
00411 void KColorCells::mouseMoveEvent( QMouseEvent *e )
00412 {
00413 if( !(e->state() && LeftButton)) return;
00414
00415 if(inMouse) {
00416 int delay = KGlobalSettings::dndEventDelay();
00417 if(e->x() > mPos.x()+delay || e->x() < mPos.x()-delay ||
00418 e->y() > mPos.y()+delay || e->y() < mPos.y()-delay){
00419
00420 int cell = posToCell(mPos);
00421 if ((cell != -1) && colors[cell].isValid())
00422 {
00423 KColorDrag *d = KColorDrag::makeDrag( colors[cell], this);
00424 d->dragCopy();
00425 }
00426 }
00427 }
00428 }
00429
00430 void KColorCells::dragEnterEvent( QDragEnterEvent *event)
00431 {
00432 event->accept( acceptDrags && KColorDrag::canDecode( event));
00433 }
00434
00435 void KColorCells::dropEvent( QDropEvent *event)
00436 {
00437 QColor c;
00438 if( KColorDrag::decode( event, c)) {
00439 int cell = posToCell(event->pos(), true);
00440 setColor(cell,c);
00441 }
00442 }
00443
00444 void KColorCells::mouseReleaseEvent( QMouseEvent *e )
00445 {
00446 int cell = posToCell(mPos);
00447 int currentCell = posToCell(e->pos());
00448
00449
00450
00451 if (currentCell != cell)
00452 cell = -1;
00453
00454 if ( (cell != -1) && (selected != cell) )
00455 {
00456 int prevSel = selected;
00457 selected = cell;
00458 updateCell( prevSel/numCols(), prevSel%numCols() );
00459 updateCell( cell/numCols(), cell%numCols() );
00460 }
00461
00462 inMouse = false;
00463 if (cell != -1)
00464 emit colorSelected( cell );
00465 }
00466
00467 void KColorCells::mouseDoubleClickEvent( QMouseEvent * )
00468 {
00469 int cell = posToCell(mPos);
00470
00471 if (cell != -1)
00472 emit colorDoubleClicked( cell );
00473 }
00474
00475
00476
00477
00478 KColorPatch::KColorPatch( QWidget *parent ) : QFrame( parent )
00479 {
00480 setFrameStyle( QFrame::Panel | QFrame::Sunken );
00481 colContext = 0;
00482 setAcceptDrops( true);
00483 }
00484
00485 KColorPatch::~KColorPatch()
00486 {
00487 if ( colContext )
00488 QColor::destroyAllocContext( colContext );
00489 }
00490
00491 void KColorPatch::setColor( const QColor &col )
00492 {
00493 if ( colContext )
00494 QColor::destroyAllocContext( colContext );
00495 colContext = QColor::enterAllocContext();
00496 color.setRgb( col.rgb() );
00497 color.alloc();
00498 QColor::leaveAllocContext();
00499
00500 QPainter painter;
00501
00502 painter.begin( this );
00503 drawContents( &painter );
00504 painter.end();
00505 }
00506
00507 void KColorPatch::drawContents( QPainter *painter )
00508 {
00509 painter->setPen( color );
00510 painter->setBrush( QBrush( color ) );
00511 painter->drawRect( contentsRect() );
00512 }
00513
00514 void KColorPatch::mouseMoveEvent( QMouseEvent *e )
00515 {
00516
00517 if( !(e->state() && LeftButton)) return;
00518 KColorDrag *d = KColorDrag::makeDrag( color, this);
00519 d->dragCopy();
00520 }
00521
00522 void KColorPatch::dragEnterEvent( QDragEnterEvent *event)
00523 {
00524 event->accept( KColorDrag::canDecode( event));
00525 }
00526
00527 void KColorPatch::dropEvent( QDropEvent *event)
00528 {
00529 QColor c;
00530 if( KColorDrag::decode( event, c)) {
00531 setColor( c);
00532 emit colorChanged( c);
00533 }
00534 }
00535
00536
00537 KPaletteTable::KPaletteTable( QWidget *parent, int minWidth, int cols)
00538 : QWidget( parent ), mMinWidth(minWidth), mCols(cols)
00539 {
00540 cells = 0;
00541 mPalette = 0;
00542 i18n_customColors = i18n("* Custom Colors *");
00543 i18n_recentColors = i18n("* Recent Colors *");
00544 i18n_namedColors = i18n("Named Colors");
00545
00546 QStringList paletteList = KPalette::getPaletteList();
00547 paletteList.remove(customColors);
00548 paletteList.remove(recentColors);
00549 paletteList.prepend(i18n_customColors);
00550 paletteList.prepend(i18n_recentColors);
00551 paletteList.append( i18n_namedColors );
00552
00553 QVBoxLayout *layout = new QVBoxLayout( this );
00554
00555 combo = new QComboBox( false, this );
00556 combo->insertStringList( paletteList );
00557 layout->addWidget(combo);
00558
00559 sv = new QScrollView( this );
00560 QSize cellSize = QSize( mMinWidth, 120);
00561 sv->setHScrollBarMode( QScrollView::AlwaysOff);
00562 sv->setVScrollBarMode( QScrollView::AlwaysOn);
00563 QSize minSize = QSize(sv->verticalScrollBar()->width(), 0);
00564 minSize += QSize(sv->frameWidth(), 0);
00565 minSize += QSize(cellSize);
00566 sv->setFixedSize(minSize);
00567 layout->addWidget(sv);
00568
00569 mNamedColorList = new KListBox( this, "namedColorList", 0 );
00570 mNamedColorList->setFixedSize(minSize);
00571 mNamedColorList->hide();
00572 layout->addWidget(mNamedColorList);
00573 connect( mNamedColorList, SIGNAL(highlighted( const QString & )),
00574 this, SLOT( slotColorTextSelected( const QString & )) );
00575
00576 setFixedSize( sizeHint());
00577 connect( combo, SIGNAL(activated(const QString &)),
00578 this, SLOT(slotSetPalette( const QString &)));
00579 }
00580
00581 KPaletteTable::~KPaletteTable()
00582 {
00583 delete mPalette;
00584 }
00585
00586 QString
00587 KPaletteTable::palette() const
00588 {
00589 return combo->currentText();
00590 }
00591
00592
00593 static const char * const *namedColorFilePath( void )
00594 {
00595
00596
00597
00598
00599 static const char * const path[] =
00600 {
00601 #ifdef X11_RGBFILE
00602 X11_RGBFILE,
00603 #endif
00604 "/usr/X11R6/lib/X11/rgb.txt",
00605 "/usr/openwin/lib/X11/rgb.txt",
00606 0
00607 };
00608 return( path );
00609 }
00610
00611
00612
00613
00614 void
00615 KPaletteTable::readNamedColor( void )
00616 {
00617 if( mNamedColorList->count() != 0 )
00618 {
00619 return;
00620 }
00621
00622
00623
00624
00625
00626 const char * const *path = namedColorFilePath();
00627 for( int i=0; path[i] != 0; i++ )
00628 {
00629 QFile paletteFile( path[i] );
00630 if( paletteFile.open( IO_ReadOnly ) == false )
00631 {
00632 continue;
00633 }
00634
00635 QString line;
00636 QStringList list;
00637 while( paletteFile.readLine( line, 100 ) != -1 )
00638 {
00639 int red, green, blue;
00640 int pos = 0;
00641
00642 if( sscanf(line.ascii(), "%d %d %d%n", &red, &green, &blue, &pos ) == 3 )
00643 {
00644
00645
00646
00647
00648 QString name = line.mid(pos).stripWhiteSpace();
00649 if( name.isNull() == true || name.find(' ') != -1 ||
00650 name.find( "gray" ) != -1 )
00651 {
00652 continue;
00653 }
00654 list.append( name );
00655 }
00656 }
00657
00658 list.sort();
00659 mNamedColorList->insertStringList( list );
00660 break;
00661 }
00662
00663 if( mNamedColorList->count() == 0 )
00664 {
00665
00666
00667
00668
00669
00670
00671
00672 QTimer::singleShot( 10, this, SLOT(slotShowNamedColorReadError()) );
00673 }
00674 }
00675
00676
00677 void
00678 KPaletteTable::slotShowNamedColorReadError( void )
00679 {
00680 if( mNamedColorList->count() == 0 )
00681 {
00682 QString msg = i18n(""
00683 "Unable to read X11 RGB color strings. The following "
00684 "file location(s) were examined:\n");
00685
00686 const char * const *path = namedColorFilePath();
00687 for( int i=0; path[i] != 0; i++ )
00688 {
00689 msg += path[i];
00690 msg += "\n";
00691 }
00692 KMessageBox::sorry( this, msg );
00693 }
00694 }
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707 void
00708 KPaletteTable::slotSetPalette( const QString &_paletteName )
00709 {
00710 setPalette( _paletteName );
00711 if( mNamedColorList->isVisible() == true )
00712 {
00713 int item = mNamedColorList->currentItem();
00714 mNamedColorList->setCurrentItem( item < 0 ? 0 : item );
00715 slotColorTextSelected( mNamedColorList->currentText() );
00716 }
00717 else
00718 {
00719 slotColorCellSelected(0);
00720 }
00721 }
00722
00723
00724 void
00725 KPaletteTable::setPalette( const QString &_paletteName )
00726 {
00727 QString paletteName( _paletteName);
00728 if (paletteName.isEmpty())
00729 paletteName = i18n_recentColors;
00730
00731 if (combo->currentText() != paletteName)
00732 {
00733 bool found = false;
00734 for(int i = 0; i < combo->count(); i++)
00735 {
00736 if (combo->text(i) == paletteName)
00737 {
00738 combo->setCurrentItem(i);
00739 found = true;
00740 break;
00741 }
00742 }
00743 if (!found)
00744 {
00745 combo->insertItem(paletteName);
00746 combo->setCurrentItem(combo->count()-1);
00747 }
00748 }
00749
00750 if (paletteName == i18n_customColors)
00751 paletteName = customColors;
00752 else if (paletteName == i18n_recentColors)
00753 paletteName = recentColors;
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764 if( mPalette == 0 || mPalette->name() != paletteName )
00765 {
00766 if( paletteName == i18n_namedColors )
00767 {
00768 sv->hide();
00769 mNamedColorList->show();
00770 readNamedColor();
00771
00772 delete cells; cells = 0;
00773 delete mPalette; mPalette = 0;
00774 }
00775 else
00776 {
00777 mNamedColorList->hide();
00778 sv->show();
00779
00780 delete cells;
00781 delete mPalette;
00782 mPalette = new KPalette(paletteName);
00783 int rows = (mPalette->nrColors()+mCols-1) / mCols;
00784 if (rows < 1) rows = 1;
00785 cells = new KColorCells( sv->viewport(), rows, mCols);
00786 cells->setShading(false);
00787 cells->setAcceptDrags(false);
00788 QSize cellSize = QSize( mMinWidth, mMinWidth * rows / mCols);
00789 cells->setFixedSize( cellSize );
00790 for( int i = 0; i < mPalette->nrColors(); i++)
00791 {
00792 cells->setColor( i, mPalette->color(i) );
00793 }
00794 connect( cells, SIGNAL( colorSelected( int ) ),
00795 SLOT( slotColorCellSelected( int ) ) );
00796 connect( cells, SIGNAL( colorDoubleClicked( int ) ),
00797 SLOT( slotColorCellDoubleClicked( int ) ) );
00798 sv->addChild( cells );
00799 cells->show();
00800 sv->updateScrollBars();
00801 }
00802 }
00803 }
00804
00805
00806
00807 void
00808 KPaletteTable::slotColorCellSelected( int col )
00809 {
00810 if (!mPalette || (col >= mPalette->nrColors()))
00811 return;
00812 emit colorSelected( mPalette->color(col), mPalette->colorName(col) );
00813 }
00814
00815 void
00816 KPaletteTable::slotColorCellDoubleClicked( int col )
00817 {
00818 if (!mPalette || (col >= mPalette->nrColors()))
00819 return;
00820 emit colorDoubleClicked( mPalette->color(col), mPalette->colorName(col) );
00821 }
00822
00823
00824 void
00825 KPaletteTable::slotColorTextSelected( const QString &colorText )
00826 {
00827 emit colorSelected( QColor (colorText), colorText );
00828 }
00829
00830
00831 void
00832 KPaletteTable::addToCustomColors( const QColor &color)
00833 {
00834 setPalette(i18n_customColors);
00835 mPalette->addColor( color );
00836 mPalette->save();
00837 delete mPalette;
00838 mPalette = 0;
00839 setPalette(i18n_customColors);
00840 }
00841
00842 void
00843 KPaletteTable::addToRecentColors( const QColor &color)
00844 {
00845
00846
00847
00848
00849 bool recentIsSelected = false;
00850 if ( mPalette != 0 && mPalette->name() == recentColors)
00851 {
00852 delete mPalette;
00853 mPalette = 0;
00854 recentIsSelected = true;
00855 }
00856 KPalette *recentPal = new KPalette(recentColors);
00857 if (recentPal->findColor(color) == -1)
00858 {
00859 recentPal->addColor( color );
00860 recentPal->save();
00861 }
00862 delete recentPal;
00863 if (recentIsSelected)
00864 setPalette(i18n_recentColors);
00865 }
00866
00867 class KColorDialog::KColorDialogPrivate {
00868 public:
00869 KPaletteTable *table;
00870 bool bRecursion;
00871 bool bEditRgb;
00872 bool bEditHsv;
00873 bool bEditHtml;
00874 bool bColorPicking;
00875 QLabel *colorName;
00876 QLineEdit *htmlName;
00877 KColorSpinBox *hedit;
00878 KColorSpinBox *sedit;
00879 KColorSpinBox *vedit;
00880 KColorSpinBox *redit;
00881 KColorSpinBox *gedit;
00882 KColorSpinBox *bedit;
00883 KColorPatch *patch;
00884 KHSSelector *hsSelector;
00885 KPalette *palette;
00886 KValueSelector *valuePal;
00887 QVBoxLayout* l_right;
00888 QGridLayout* tl_layout;
00889 QCheckBox *cbDefaultColor;
00890 KColor defaultColor;
00891 KColor selColor;
00892 QX11EventFilter oldfilter;
00893 };
00894
00895
00896 KColorDialog::KColorDialog( QWidget *parent, const char *name, bool modal )
00897 :KDialogBase( parent, name, modal, i18n("Select Color"),
00898 modal ? Help|Ok|Cancel : Help|Close,
00899 Ok, true )
00900 {
00901 d = new KColorDialogPrivate;
00902 d->bRecursion = true;
00903 d->bColorPicking = false;
00904 d->oldfilter = 0;
00905 d->cbDefaultColor = 0L;
00906 setHelp( QString::fromLatin1("kcolordialog.html"), QString::null );
00907 connect( this, SIGNAL(okClicked(void)),this,SLOT(slotWriteSettings(void)));
00908 connect( this, SIGNAL(closeClicked(void)),this,SLOT(slotWriteSettings(void)));
00909
00910 QLabel *label;
00911
00912
00913
00914
00915 QWidget *page = new QWidget( this );
00916 setMainWidget( page );
00917
00918 QGridLayout *tl_layout = new QGridLayout( page, 3, 3, 0, spacingHint() );
00919 d->tl_layout = tl_layout;
00920 tl_layout->addColSpacing( 1, spacingHint() * 2 );
00921
00922
00923
00924
00925
00926 QVBoxLayout *l_left = new QVBoxLayout();
00927 tl_layout->addLayout(l_left, 0, 0);
00928
00929
00930
00931
00932
00933 QHBoxLayout *l_ltop = new QHBoxLayout();
00934 l_left->addLayout(l_ltop);
00935
00936
00937 l_left->addSpacing(10);
00938
00939 QGridLayout *l_lbot = new QGridLayout(3, 6);
00940 l_left->addLayout(l_lbot);
00941
00942
00943
00944
00945 d->hsSelector = new KHSSelector( page );
00946 d->hsSelector->setMinimumSize(140, 70);
00947 l_ltop->addWidget(d->hsSelector, 8);
00948 connect( d->hsSelector, SIGNAL( valueChanged( int, int ) ),
00949 SLOT( slotHSChanged( int, int ) ) );
00950
00951 d->valuePal = new KValueSelector( page );
00952 d->valuePal->setMinimumSize(26, 70);
00953 l_ltop->addWidget(d->valuePal, 1);
00954 connect( d->valuePal, SIGNAL( valueChanged( int ) ),
00955 SLOT( slotVChanged( int ) ) );
00956
00957
00958
00959
00960
00961 label = new QLabel( i18n("H:"), page );
00962 label->setAlignment(AlignRight | AlignVCenter);
00963 l_lbot->addWidget(label, 0, 2);
00964 d->hedit = new KColorSpinBox( 0, 359, 1, page );
00965 d->hedit->setValidator( new QIntValidator( d->hedit ) );
00966 l_lbot->addWidget(d->hedit, 0, 3);
00967 connect( d->hedit, SIGNAL( valueChanged(int) ),
00968 SLOT( slotHSVChanged() ) );
00969
00970 label = new QLabel( i18n("S:"), page );
00971 label->setAlignment(AlignRight | AlignVCenter);
00972 l_lbot->addWidget(label, 1, 2);
00973 d->sedit = new KColorSpinBox( 0, 255, 1, page );
00974 d->sedit->setValidator( new QIntValidator( d->sedit ) );
00975 l_lbot->addWidget(d->sedit, 1, 3);
00976 connect( d->sedit, SIGNAL( valueChanged(int) ),
00977 SLOT( slotHSVChanged() ) );
00978
00979 label = new QLabel( i18n("V:"), page );
00980 label->setAlignment(AlignRight | AlignVCenter);
00981 l_lbot->addWidget(label, 2, 2);
00982 d->vedit = new KColorSpinBox( 0, 255, 1, page );
00983 d->vedit->setValidator( new QIntValidator( d->vedit ) );
00984 l_lbot->addWidget(d->vedit, 2, 3);
00985 connect( d->vedit, SIGNAL( valueChanged(int) ),
00986 SLOT( slotHSVChanged() ) );
00987
00988
00989
00990
00991 label = new QLabel( i18n("R:"), page );
00992 label->setAlignment(AlignRight | AlignVCenter);
00993 l_lbot->addWidget(label, 0, 4);
00994 d->redit = new KColorSpinBox( 0, 255, 1, page );
00995 d->redit->setValidator( new QIntValidator( d->redit ) );
00996 l_lbot->addWidget(d->redit, 0, 5);
00997 connect( d->redit, SIGNAL( valueChanged(int) ),
00998 SLOT( slotRGBChanged() ) );
00999
01000 label = new QLabel( i18n("G:"), page );
01001 label->setAlignment(AlignRight | AlignVCenter);
01002 l_lbot->addWidget( label, 1, 4);
01003 d->gedit = new KColorSpinBox( 0, 255,1, page );
01004 d->gedit->setValidator( new QIntValidator( d->gedit ) );
01005 l_lbot->addWidget(d->gedit, 1, 5);
01006 connect( d->gedit, SIGNAL( valueChanged(int) ),
01007 SLOT( slotRGBChanged() ) );
01008
01009 label = new QLabel( i18n("B:"), page );
01010 label->setAlignment(AlignRight | AlignVCenter);
01011 l_lbot->addWidget(label, 2, 4);
01012 d->bedit = new KColorSpinBox( 0, 255, 1, page );
01013 d->bedit->setValidator( new QIntValidator( d->bedit ) );
01014 l_lbot->addWidget(d->bedit, 2, 5);
01015 connect( d->bedit, SIGNAL( valueChanged(int) ),
01016 SLOT( slotRGBChanged() ) );
01017
01018
01019
01020
01021 int w = d->hedit->fontMetrics().width("8888888");
01022 d->hedit->setFixedWidth(w);
01023 d->sedit->setFixedWidth(w);
01024 d->vedit->setFixedWidth(w);
01025
01026 d->redit->setFixedWidth(w);
01027 d->gedit->setFixedWidth(w);
01028 d->bedit->setFixedWidth(w);
01029
01030
01031
01032
01033 d->l_right = new QVBoxLayout;
01034 tl_layout->addLayout(d->l_right, 0, 2);
01035
01036
01037
01038
01039 d->table = new KPaletteTable( page );
01040 d->l_right->addWidget(d->table, 10);
01041
01042 connect( d->table, SIGNAL( colorSelected( const QColor &, const QString & ) ),
01043 SLOT( slotColorSelected( const QColor &, const QString & ) ) );
01044
01045 connect(
01046 d->table,
01047 SIGNAL( colorDoubleClicked( const QColor &, const QString & ) ),
01048 SLOT( slotColorDoubleClicked( const QColor &, const QString & ) )
01049 );
01050
01051
01052
01053
01054 d->l_right->addSpacing(10);
01055
01056 QHBoxLayout *l_hbox = new QHBoxLayout( d->l_right );
01057
01058
01059
01060
01061 QPushButton *button = new QPushButton( page );
01062 button->setText(i18n("&Add to Custom Colors"));
01063 l_hbox->addWidget(button, 0, AlignLeft);
01064 connect( button, SIGNAL( clicked()), SLOT( slotAddToCustomColors()));
01065
01066
01067
01068
01069 button = new QPushButton( page );
01070 button->setPixmap( BarIcon("colorpicker"));
01071 l_hbox->addWidget(button, 0, AlignHCenter );
01072 connect( button, SIGNAL( clicked()), SLOT( slotColorPicker()));
01073
01074
01075
01076
01077 d->l_right->addSpacing(10);
01078
01079
01080
01081
01082 QGridLayout *l_grid = new QGridLayout( d->l_right, 2, 3);
01083
01084 l_grid->setColStretch(2, 1);
01085
01086 label = new QLabel( page );
01087 label->setText(i18n("Name:"));
01088 l_grid->addWidget(label, 0, 1, AlignLeft);
01089
01090 d->colorName = new QLabel( page );
01091 l_grid->addWidget(d->colorName, 0, 2, AlignLeft);
01092
01093 label = new QLabel( page );
01094 label->setText(i18n("HTML:"));
01095 l_grid->addWidget(label, 1, 1, AlignLeft);
01096
01097 d->htmlName = new QLineEdit( page );
01098 d->htmlName->setMaxLength( 7 );
01099 d->htmlName->setText("#FFFFFF");
01100 w = d->htmlName->fontMetrics().width(QString::fromLatin1("#DDDDDDD"));
01101 d->htmlName->setFixedWidth(w);
01102 l_grid->addWidget(d->htmlName, 1, 2, AlignLeft);
01103
01104 connect( d->htmlName, SIGNAL( textChanged(const QString &) ),
01105 SLOT( slotHtmlChanged() ) );
01106
01107 d->patch = new KColorPatch( page );
01108 d->patch->setFixedSize(48, 48);
01109 l_grid->addMultiCellWidget(d->patch, 0, 1, 0, 0, AlignHCenter | AlignVCenter);
01110 connect( d->patch, SIGNAL( colorChanged( const QColor&)),
01111 SLOT( setColor( const QColor&)));
01112
01113 tl_layout->activate();
01114 page->setMinimumSize( page->sizeHint() );
01115
01116 readSettings();
01117 d->bRecursion = false;
01118 d->bEditHsv = false;
01119 d->bEditRgb = false;
01120 d->bEditHtml = false;
01121
01122 disableResize();
01123 }
01124
01125 KColorDialog::~KColorDialog()
01126 {
01127 if (d->bColorPicking)
01128 qt_set_x11_event_filter(d->oldfilter);
01129 delete d;
01130 }
01131
01132 void
01133 KColorDialog::setDefaultColor( const QColor& col )
01134 {
01135 if ( !d->cbDefaultColor )
01136 {
01137
01138
01139
01140 d->l_right->addSpacing(10);
01141
01142
01143
01144
01145 d->cbDefaultColor = new QCheckBox( i18n( "Default color" ), mainWidget() );
01146 d->l_right->addWidget( d->cbDefaultColor );
01147
01148 mainWidget()->setMaximumSize( QWIDGETSIZE_MAX, QWIDGETSIZE_MAX );
01149 d->tl_layout->activate();
01150 mainWidget()->setMinimumSize( mainWidget()->sizeHint() );
01151 disableResize();
01152
01153 connect( d->cbDefaultColor, SIGNAL( clicked() ), SLOT( slotDefaultColorClicked() ) );
01154 }
01155
01156 d->defaultColor = col;
01157
01158 slotDefaultColorClicked();
01159 }
01160
01161 QColor KColorDialog::defaultColor() const
01162 {
01163 return d->defaultColor;
01164 }
01165
01166 void KColorDialog::slotDefaultColorClicked()
01167 {
01168 bool enable;
01169 if ( d->cbDefaultColor->isChecked() )
01170 {
01171 d->selColor = QColor();
01172 showColor( d->defaultColor, i18n( "-default-" ) );
01173 enable = false;
01174 } else
01175 {
01176 d->selColor = d->defaultColor;
01177 enable = true;
01178 }
01179 d->hedit->setEnabled( enable );
01180 d->sedit->setEnabled( enable );
01181 d->vedit->setEnabled( enable );
01182 d->redit->setEnabled( enable );
01183 d->gedit->setEnabled( enable );
01184 d->bedit->setEnabled( enable );
01185 d->valuePal->setEnabled( enable );
01186 d->hsSelector->setEnabled( enable );
01187 }
01188
01189 void
01190 KColorDialog::readSettings()
01191 {
01192 KConfig* config = KGlobal::config();
01193
01194 QString oldgroup = config->group();
01195
01196 config->setGroup("Colors");
01197 QString palette = config->readEntry("CurrentPalette");
01198 d->table->setPalette(palette);
01199
01200 config->setGroup( oldgroup );
01201 }
01202
01203 void
01204 KColorDialog::slotWriteSettings()
01205 {
01206 KConfig* config = KGlobal::config();
01207
01208 QString oldgroup = config->group();
01209
01210 config->setGroup("Colors");
01211 config->writeEntry("CurrentPalette", d->table->palette() );
01212
01213 config->setGroup( oldgroup );
01214 }
01215
01216 QColor
01217 KColorDialog::color() const
01218 {
01219 if ( d->selColor.isValid() )
01220 d->table->addToRecentColors( d->selColor );
01221 return d->selColor;
01222 }
01223
01224 void KColorDialog::setColor( const QColor &col )
01225 {
01226 _setColor( col );
01227 }
01228
01229
01230
01231
01232 int KColorDialog::getColor( QColor &theColor, QWidget *parent )
01233 {
01234 KColorDialog dlg( parent, "Color Selector", TRUE );
01235 if ( theColor.isValid() )
01236 dlg.setColor( theColor );
01237 int result = dlg.exec();
01238
01239 if ( result == Accepted )
01240 {
01241 theColor = dlg.color();
01242 }
01243
01244 return result;
01245 }
01246
01247
01248
01249
01250 int KColorDialog::getColor( QColor &theColor, const QColor& defaultCol, QWidget *parent )
01251 {
01252 KColorDialog dlg( parent, "Color Selector", TRUE );
01253 dlg.setDefaultColor( defaultCol );
01254 dlg.setColor( theColor );
01255 int result = dlg.exec();
01256
01257 if ( result == Accepted )
01258 theColor = dlg.color();
01259
01260 return result;
01261 }
01262
01263 void KColorDialog::slotRGBChanged( void )
01264 {
01265 if (d->bRecursion) return;
01266 int red = d->redit->value();
01267 int grn = d->gedit->value();
01268 int blu = d->bedit->value();
01269
01270 if ( red > 255 || red < 0 ) return;
01271 if ( grn > 255 || grn < 0 ) return;
01272 if ( blu > 255 || blu < 0 ) return;
01273
01274 KColor col;
01275 col.setRgb( red, grn, blu );
01276 d->bEditRgb = true;
01277 _setColor( col );
01278 d->bEditRgb = false;
01279 }
01280
01281 void KColorDialog::slotHtmlChanged( void )
01282 {
01283 if (d->bRecursion || d->htmlName->text().isEmpty()) return;
01284
01285 unsigned int red = 256;
01286 unsigned int grn = 256;
01287 unsigned int blu = 256;
01288
01289 if (sscanf(d->htmlName->text().latin1(), "#%02x%02x%02x", &red, &grn, &blu)!=3)
01290 return;
01291
01292 if ( red > 255 || grn > 255 || blu > 255) return;
01293
01294 KColor col;
01295 col.setRgb( red, grn, blu );
01296 d->bEditHtml = true;
01297 _setColor( col );
01298 d->bEditHtml = false;
01299 }
01300
01301 void KColorDialog::slotHSVChanged( void )
01302 {
01303 if (d->bRecursion) return;
01304 int hue = d->hedit->value();
01305 int sat = d->sedit->value();
01306 int val = d->vedit->value();
01307
01308 if ( hue > 359 || hue < 0 ) return;
01309 if ( sat > 255 || sat < 0 ) return;
01310 if ( val > 255 || val < 0 ) return;
01311
01312 KColor col;
01313 col.setHsv( hue, sat, val );
01314 d->bEditHsv = true;
01315 _setColor( col );
01316 d->bEditHsv = false;
01317 }
01318
01319 void KColorDialog::slotHSChanged( int h, int s )
01320 {
01321 int _h, _s, v;
01322 d->selColor.hsv(&_h, &_s, &v);
01323 if (v < 1)
01324 v = 1;
01325 KColor col;
01326 col.setHsv( h, s, v );
01327 _setColor( col );
01328 }
01329
01330 void KColorDialog::slotVChanged( int v )
01331 {
01332 int h, s, _v;
01333 d->selColor.hsv(&h, &s, &_v);
01334 KColor col;
01335 col.setHsv( h, s, v );
01336 _setColor( col );
01337 }
01338
01339 void KColorDialog::slotColorSelected( const QColor &color )
01340 {
01341 _setColor( color );
01342 }
01343
01344 void KColorDialog::slotAddToCustomColors( )
01345 {
01346 d->table->addToCustomColors( d->selColor );
01347 }
01348
01349 void KColorDialog::slotColorSelected( const QColor &color, const QString &name )
01350 {
01351 _setColor( color, name);
01352 }
01353
01354 void KColorDialog::slotColorDoubleClicked
01355 (
01356 const QColor & color,
01357 const QString & name
01358 )
01359 {
01360 _setColor(color, name);
01361 accept();
01362 }
01363
01364 void KColorDialog::_setColor(const KColor &color, const QString &name)
01365 {
01366 if (color == d->selColor) return;
01367
01368 d->selColor = color;
01369
01370 showColor( color, name );
01371
01372 emit colorSelected( d->selColor );
01373 }
01374
01375
01376 void KColorDialog::showColor( const KColor &color, const QString &name )
01377 {
01378 d->bRecursion = true;
01379
01380 if (name.isEmpty())
01381 d->colorName->setText( i18n("-unnamed-"));
01382 else
01383 d->colorName->setText( name );
01384
01385 d->patch->setColor( color );
01386
01387 setRgbEdit( color );
01388 setHsvEdit( color );
01389 setHtmlEdit( color );
01390
01391 int h, s, v;
01392 color.hsv( &h, &s, &v );
01393 d->hsSelector->setValues( h, s );
01394 d->valuePal->setHue( h );
01395 d->valuePal->setSaturation( s );
01396 d->valuePal->setValue( v );
01397 d->valuePal->updateContents();
01398 d->valuePal->repaint( FALSE );
01399 d->bRecursion = false;
01400 }
01401
01402
01403 static QWidget *kde_color_dlg_widget = 0;
01404
01405 int kde_color_dlg_handler(XEvent *event)
01406 {
01407 if (event->type == ButtonRelease)
01408 {
01409 QMouseEvent e( QEvent::MouseButtonRelease, QPoint(),
01410 QPoint(event->xmotion.x_root, event->xmotion.y_root) , 0, 0 );
01411 QApplication::sendEvent( kde_color_dlg_widget, &e );
01412 return TRUE;
01413 }
01414 return FALSE;
01415 }
01416
01417 void
01418 KColorDialog::slotColorPicker()
01419 {
01420 d->bColorPicking = true;
01421 d->oldfilter = qt_set_x11_event_filter(kde_color_dlg_handler);
01422 kde_color_dlg_widget = this;
01423 grabMouse( crossCursor );
01424 grabKeyboard();
01425 }
01426
01427 void
01428 KColorDialog::mouseReleaseEvent( QMouseEvent *e )
01429 {
01430 if (d->bColorPicking)
01431 {
01432 d->bColorPicking = false;
01433 qt_set_x11_event_filter(d->oldfilter);
01434 d->oldfilter = 0;
01435 releaseMouse();
01436 releaseKeyboard();
01437 _setColor( grabColor( e->globalPos() ) );
01438 return;
01439 }
01440 KDialogBase::mouseReleaseEvent( e );
01441 }
01442
01443 QColor
01444 KColorDialog::grabColor(const QPoint &p)
01445 {
01446 QWidget *desktop = QApplication::desktop();
01447 QPixmap pm = QPixmap::grabWindow( desktop->winId(), p.x(), p.y(), 1, 1);
01448 QImage i = pm.convertToImage();
01449 return i.pixel(0,0);
01450 }
01451
01452 void
01453 KColorDialog::keyPressEvent( QKeyEvent *e )
01454 {
01455 if (d->bColorPicking)
01456 {
01457 if (e->key() == Key_Escape)
01458 {
01459 d->bColorPicking = false;
01460 qt_set_x11_event_filter(d->oldfilter);
01461 d->oldfilter = 0;
01462 releaseMouse();
01463 releaseKeyboard();
01464 }
01465 e->accept();
01466 return;
01467 }
01468 KDialogBase::keyPressEvent( e );
01469 }
01470
01471 void KColorDialog::setRgbEdit( const KColor &col )
01472 {
01473 if (d->bEditRgb) return;
01474 int r, g, b;
01475 col.rgb( &r, &g, &b );
01476
01477 d->redit->setValue( r );
01478 d->gedit->setValue( g );
01479 d->bedit->setValue( b );
01480 }
01481
01482 void KColorDialog::setHtmlEdit( const KColor &col )
01483 {
01484 if (d->bEditHtml) return;
01485 int r, g, b;
01486 col.rgb( &r, &g, &b );
01487 QString num;
01488
01489 num.sprintf("#%02X%02X%02X", r,g,b);
01490 d->htmlName->setText( num );
01491 }
01492
01493
01494 void KColorDialog::setHsvEdit( const KColor &col )
01495 {
01496 if (d->bEditHsv) return;
01497 int h, s, v;
01498 col.hsv( &h, &s, &v );
01499
01500 d->hedit->setValue( h );
01501 d->sedit->setValue( s );
01502 d->vedit->setValue( v );
01503 }
01504
01505 void KHSSelector::virtual_hook( int id, void* data )
01506 { KXYSelector::virtual_hook( id, data ); }
01507
01508 void KValueSelector::virtual_hook( int id, void* data )
01509 { KSelector::virtual_hook( id, data ); }
01510
01511 void KPaletteTable::virtual_hook( int, void* )
01512 { }
01513
01514 void KColorCells::virtual_hook( int, void* )
01515 { }
01516
01517 void KColorPatch::virtual_hook( int, void* )
01518 { }
01519
01520 void KColorDialog::virtual_hook( int id, void* data )
01521 { KDialogBase::virtual_hook( id, data ); }
01522
01523
01524 #include "kcolordialog.moc"
01525 #endif