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