lib Library API Documentation

kotoolbutton.cc

00001 /* This file is part of the KDE project
00002    Copyright (C) 2002 Werner Trobin <trobin@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., 59 Temple Place - Suite 330,
00017    Boston, MA 02111-1307, USA.
00018 */
00019 
00020 #include <qapplication.h>
00021 #include <qtooltip.h>
00022 #include <qpainter.h>
00023 #include <qdrawutil.h>
00024 #include <qpixmap.h>
00025 #include <qstyle.h>
00026 #include <qpopupmenu.h>
00027 
00028 #include <kglobalsettings.h>
00029 #include <ktoolbar.h>
00030 #include <kotoolbutton.h>
00031 #include <kcolordrag.h>
00032 #include <klocale.h>
00033 #include <kcolordialog.h>
00034 #include <kdebug.h>
00035 
00036 namespace {
00037     // For the KoColorPanel
00038     const int COLS = 15;
00039     const int TILESIZE = 16;
00040     // For the KoToolButton
00041     int ARROW_WIDTH = 12;
00042 }
00043 
00044 KoColorPanel::KoColorPanel( QWidget* parent, const char* name ) :
00045     QWidget( parent, name, WStaticContents | WRepaintNoErase | WResizeNoErase )
00046 {
00047     setMouseTracking( true );
00048     setAcceptDrops( true );
00049     init();
00050 }
00051 
00052 KoColorPanel::~KoColorPanel()
00053 {
00054 }
00055 
00056 QSize KoColorPanel::sizeHint() const
00057 {
00058     return minimumSizeHint();
00059 }
00060 
00061 QSize KoColorPanel::minimumSizeHint() const
00062 {
00063     return QSize( COLS << 4, lines() << 4 );
00064 }
00065 
00066 QPopupMenu* KoColorPanel::createColorPopup( KoColorPanel::MenuStyle style, const QColor& defaultColor,
00067                                             const QObject* receiver, const char* slot,
00068                                             QWidget* parent, const char* name )
00069 {
00070     QPopupMenu* menu = new QPopupMenu( parent, name );
00071     KoColorPopupProxy* proxy = 0;
00072 
00073     if ( defaultColor.isValid() ) {
00074         QPixmap pixmap( 12, 12 );
00075         QPainter p( &pixmap );
00076         p.fillRect( 0, 0, 12, 12, defaultColor );
00077         p.end();
00078         proxy = new KoColorPopupProxy( defaultColor, 0, menu, "color proxy" );
00079         connect( proxy, SIGNAL( colorSelected( const QColor& ) ), receiver, slot );
00080         menu->insertItem( QIconSet( pixmap ), i18n( "Default Color" ), proxy, SLOT( slotDefaultColor() ) );
00081         menu->insertSeparator();
00082     }
00083 
00084     KoColorPanel* panel = new KoColorPanel( menu, "default colors" );
00085     panel->insertDefaultColors();
00086     connect( panel, SIGNAL( colorSelected( const QColor& ) ), receiver, slot );
00087     menu->insertItem( panel );
00088 
00089     if ( style == CustomColors ) {
00090         menu->insertSeparator();
00091         panel = new KoColorPanel( menu, "custom panel" );
00092         connect( panel, SIGNAL( colorSelected( const QColor& ) ), receiver, slot );
00093         menu->insertItem( panel );
00094         if ( !proxy ) {
00095             proxy = new KoColorPopupProxy( QColor(), panel, menu, "color proxy" );
00096             connect( proxy, SIGNAL( colorSelected( const QColor& ) ), receiver, slot );
00097         }
00098         else
00099             proxy->setRecentColorPanel( panel );
00100         menu->insertSeparator();
00101         menu->insertItem( i18n( "More Colors..." ), proxy, SLOT( slotMoreColors() ) );
00102     }
00103 
00104     return menu;
00105 }
00106 
00107 void KoColorPanel::clear()
00108 {
00109     if ( m_colorMap.isEmpty() )
00110         return;
00111 
00112     QSize area( minimumSizeHint() );
00113     m_colorMap.clear();
00114     init();
00115     updateGeometry();
00116     erase( 0, 0, area.width(), area.height() );
00117 }
00118 
00119 void KoColorPanel::insertColor( const QColor& color )
00120 {
00121     Position pos = m_nextPosition;
00122     if ( insertColor( color, true ) ) // we want checking for external users
00123         finalizeInsertion( pos );
00124 }
00125 
00126 void KoColorPanel::insertColor( const QColor& color, const QString& toolTip )
00127 {
00128     Position pos = m_nextPosition;
00129     if ( insertColor( color, toolTip, true ) ) // we want checking for external users
00130         finalizeInsertion( pos );
00131 }
00132 
00133 void KoColorPanel::insertDefaultColors()
00134 {
00135     if ( m_defaultsAdded )
00136         return;
00137     m_defaultsAdded = true;
00138 
00139     int currentRow = m_nextPosition.y; // we have to repaint this row below
00140 
00141     // Note: No checking for duplicates, so take care when you modify that list
00142     insertColor(qRgb( 255 ,     0 ,     0 ), i18n( "Color", "Red" ), false);
00143     insertColor(qRgb( 255 ,   165 ,     0 ), i18n( "Color", "Orange" ), false);
00144     insertColor(qRgb( 255 ,     0 ,   255 ), i18n( "Color", "Magenta" ), false);
00145     insertColor(qRgb(   0 ,     0 ,   255 ), i18n( "Color", "Blue" ), false);
00146     insertColor(qRgb(   0 ,   255 ,   255 ), i18n( "Color", "Cyan" ), false);
00147     insertColor(qRgb(   0 ,   255 ,     0 ), i18n( "Color", "Green" ), false);
00148     insertColor(qRgb( 255 ,   255 ,     0 ), i18n( "Color", "Yellow" ), false);
00149     insertColor(qRgb( 165 ,    42 ,    42 ), i18n( "Color", "Brown" ), false);
00150     insertColor(qRgb( 139 ,     0 ,     0 ), i18n( "Color", "Dark Red" ), false);
00151     insertColor(qRgb( 255 ,   140 ,     0 ), i18n( "Color", "Dark Orange" ), false);
00152     insertColor(qRgb( 139 ,     0 ,   139 ), i18n( "Color", "Dark Magenta" ), false);
00153     insertColor(qRgb(   0 ,     0 ,   139 ), i18n( "Color", "Dark Blue" ), false);
00154     insertColor(qRgb(   0 ,   139 ,   139 ), i18n( "Color", "Dark Cyan" ), false);
00155     insertColor(qRgb(   0 ,   100 ,     0 ), i18n( "Color", "Dark Green" ), false);
00156     insertColor(qRgb( 130 ,   127 ,     0 ), i18n( "Color", "Dark Yellow" ), false);
00157     insertColor(qRgb( 255 ,   255 ,   255 ), i18n( "Color", "White" ), false);
00158     // xgettext:no-c-format
00159     insertColor(qRgb( 229 ,   229 ,   229 ), i18n( "Color", "Gray 90%" ), false);
00160     // xgettext:no-c-format
00161     insertColor(qRgb( 204 ,   204 ,   204 ), i18n( "Color", "Gray 80%" ), false);
00162     // xgettext:no-c-format
00163     insertColor(qRgb( 178 ,   178 ,   178 ), i18n( "Color", "Gray 70%" ), false);
00164     // xgettext:no-c-format
00165     insertColor(qRgb( 153 ,   153 ,   153 ), i18n( "Color", "Gray 60%" ), false);
00166     // xgettext:no-c-format
00167     insertColor(qRgb( 127 ,   127 ,   127 ), i18n( "Color", "Gray 50%" ), false);
00168     // xgettext:no-c-format
00169     insertColor(qRgb( 102 ,   102 ,   102 ), i18n( "Color", "Gray 40%" ), false);
00170     // xgettext:no-c-format
00171     insertColor(qRgb(  76 ,    76 ,    76 ), i18n( "Color", "Gray 30%" ), false);
00172     // xgettext:no-c-format
00173     insertColor(qRgb(  51 ,    51 ,    51 ), i18n( "Color", "Gray 20%" ), false);
00174     // xgettext:no-c-format
00175     insertColor(qRgb(  25 ,    25 ,    25 ), i18n( "Color", "Gray 10%" ), false);
00176     insertColor(qRgb(   0 ,     0 ,     0 ), i18n( "Color", "Black" ), false);
00177     insertColor(qRgb( 255 ,   255 ,   240 ), i18n( "Color", "Ivory" ), false);
00178     insertColor(qRgb( 255 ,   250 ,   250 ), i18n( "Color", "Snow" ), false);
00179     insertColor(qRgb( 245 ,   255 ,   250 ), i18n( "Color", "Mint Cream" ), false);
00180     insertColor(qRgb( 255 ,   250 ,   240 ), i18n( "Color", "Floral White" ), false);
00181     insertColor(qRgb( 255 ,   255 ,   224 ), i18n( "Color", "Light Yellow" ), false);
00182     insertColor(qRgb( 240 ,   255 ,   255 ), i18n( "Color", "Azure" ), false);
00183     insertColor(qRgb( 248 ,   248 ,   255 ), i18n( "Color", "Ghost White" ), false);
00184     insertColor(qRgb( 240 ,   255 ,   240 ), i18n( "Color", "Honeydew" ), false);
00185     insertColor(qRgb( 255 ,   245 ,   238 ), i18n( "Color", "Seashell" ), false);
00186     insertColor(qRgb( 240 ,   248 ,   255 ), i18n( "Color", "Alice Blue" ), false);
00187     insertColor(qRgb( 255 ,   248 ,   220 ), i18n( "Color", "Cornsilk" ), false);
00188     insertColor(qRgb( 255 ,   240 ,   245 ), i18n( "Color", "Lavender Blush" ), false);
00189     insertColor(qRgb( 253 ,   245 ,   230 ), i18n( "Color", "Old Lace" ), false);
00190     insertColor(qRgb( 245 ,   245 ,   245 ), i18n( "Color", "White Smoke" ), false);
00191     insertColor(qRgb( 255 ,   250 ,   205 ), i18n( "Color", "Lemon Chiffon" ), false);
00192     insertColor(qRgb( 224 ,   255 ,   255 ), i18n( "Color", "Light Cyan" ), false);
00193     insertColor(qRgb( 250 ,   250 ,   210 ), i18n( "Color", "Light Goldenrod Yellow" ), false);
00194     insertColor(qRgb( 250 ,   240 ,   230 ), i18n( "Color", "Linen" ), false);
00195     insertColor(qRgb( 245 ,   245 ,   220 ), i18n( "Color", "Beige" ), false);
00196     insertColor(qRgb( 255 ,   239 ,   213 ), i18n( "Color", "Papaya Whip" ), false);
00197     insertColor(qRgb( 255 ,   235 ,   205 ), i18n( "Color", "Blanched Almond" ), false);
00198     insertColor(qRgb( 250 ,   235 ,   215 ), i18n( "Color", "Antique White" ), false);
00199     insertColor(qRgb( 255 ,   228 ,   225 ), i18n( "Color", "Misty Rose" ), false);
00200     insertColor(qRgb( 230 ,   230 ,   250 ), i18n( "Color", "Lavender" ), false);
00201     insertColor(qRgb( 255 ,   228 ,   196 ), i18n( "Color", "Bisque" ), false);
00202     insertColor(qRgb( 255 ,   228 ,   181 ), i18n( "Color", "Moccasin" ), false);
00203     insertColor(qRgb( 255 ,   222 ,   173 ), i18n( "Color", "Navajo White" ), false);
00204     insertColor(qRgb( 255 ,   218 ,   185 ), i18n( "Color", "Peach Puff" ), false);
00205     insertColor(qRgb( 238 ,   232 ,   170 ), i18n( "Color", "Pale Goldenrod" ), false);
00206     insertColor(qRgb( 245 ,   222 ,   179 ), i18n( "Color", "Wheat" ), false);
00207     insertColor(qRgb( 220 ,   220 ,   220 ), i18n( "Color", "Gainsboro" ), false);
00208     insertColor(qRgb( 240 ,   230 ,   140 ), i18n( "Color", "Khaki" ), false);
00209     insertColor(qRgb( 175 ,   238 ,   238 ), i18n( "Color", "Pale Turquoise" ), false);
00210     insertColor(qRgb( 255 ,   192 ,   203 ), i18n( "Color", "Pink" ), false);
00211     insertColor(qRgb( 238 ,   221 ,   130 ), i18n( "Color", "Light Goldenrod" ), false);
00212     insertColor(qRgb( 211 ,   211 ,   211 ), i18n( "Color", "Light Gray" ), false);
00213     insertColor(qRgb( 255 ,   182 ,   193 ), i18n( "Color", "Light Pink" ), false);
00214     insertColor(qRgb( 176 ,   224 ,   230 ), i18n( "Color", "Powder Blue" ), false);
00215     insertColor(qRgb( 127 ,   255 ,   212 ), i18n( "Color", "Aquamarine" ), false);
00216     insertColor(qRgb( 216 ,   191 ,   216 ), i18n( "Color", "Thistle" ), false);
00217     insertColor(qRgb( 173 ,   216 ,   230 ), i18n( "Color", "Light Blue" ), false);
00218     insertColor(qRgb( 152 ,   251 ,   152 ), i18n( "Color", "Pale Green" ), false);
00219     insertColor(qRgb( 255 ,   215 ,     0 ), i18n( "Color", "Gold" ), false);
00220     insertColor(qRgb( 173 ,   255 ,    47 ), i18n( "Color", "Green Yellow" ), false);
00221     insertColor(qRgb( 176 ,   196 ,   222 ), i18n( "Color", "Light Steel Blue" ), false);
00222     insertColor(qRgb( 144 ,   238 ,   144 ), i18n( "Color", "Light Green" ), false);
00223     insertColor(qRgb( 221 ,   160 ,   221 ), i18n( "Color", "Plum" ), false);
00224     insertColor(qRgb( 190 ,   190 ,   190 ), i18n( "Color", "Gray" ), false);
00225     insertColor(qRgb( 222 ,   184 ,   135 ), i18n( "Color", "Burly Wood" ), false);
00226     insertColor(qRgb( 135 ,   206 ,   250 ), i18n( "Color", "Light Sky Blue" ), false);
00227     insertColor(qRgb( 255 ,   160 ,   122 ), i18n( "Color", "Light Salmon" ), false);
00228     insertColor(qRgb( 135 ,   206 ,   235 ), i18n( "Color", "Sky Blue" ), false);
00229     insertColor(qRgb( 210 ,   180 ,   140 ), i18n( "Color", "Tan" ), false);
00230     insertColor(qRgb( 238 ,   130 ,   238 ), i18n( "Color", "Violet" ), false);
00231     insertColor(qRgb( 244 ,   164 ,    96 ), i18n( "Color", "Sandy Brown" ), false);
00232     insertColor(qRgb( 233 ,   150 ,   122 ), i18n( "Color", "Dark Salmon" ), false);
00233     insertColor(qRgb( 189 ,   183 ,   107 ), i18n( "Color", "Dark Khaki" ), false);
00234     insertColor(qRgb( 127 ,   255 ,     0 ), i18n( "Color", "Chartreuse" ), false);
00235     insertColor(qRgb( 169 ,   169 ,   169 ), i18n( "Color", "Dark Gray" ), false);
00236     insertColor(qRgb( 124 ,   252 ,     0 ), i18n( "Color", "Lawn Green" ), false);
00237     insertColor(qRgb( 255 ,   105 ,   180 ), i18n( "Color", "Hot Pink" ), false);
00238     insertColor(qRgb( 250 ,   128 ,   114 ), i18n( "Color", "Salmon" ), false);
00239     insertColor(qRgb( 240 ,   128 ,   128 ), i18n( "Color", "Light Coral" ), false);
00240     insertColor(qRgb(  64 ,   224 ,   208 ), i18n( "Color", "Turquoise" ), false);
00241     insertColor(qRgb( 143 ,   188 ,   143 ), i18n( "Color", "Dark Sea Green" ), false);
00242     insertColor(qRgb( 218 ,   112 ,   214 ), i18n( "Color", "Orchid" ), false);
00243     insertColor(qRgb( 102 ,   205 ,   170 ), i18n( "Color", "Medium Aquamarine" ), false);
00244     insertColor(qRgb( 255 ,   127 ,    80 ), i18n( "Color", "Coral" ), false);
00245     insertColor(qRgb( 154 ,   205 ,    50 ), i18n( "Color", "Yellow Green" ), false);
00246     insertColor(qRgb( 218 ,   165 ,    32 ), i18n( "Color", "Goldenrod" ), false);
00247     insertColor(qRgb(  72 ,   209 ,   204 ), i18n( "Color", "Medium Turquoise" ), false);
00248     insertColor(qRgb( 188 ,   143 ,   143 ), i18n( "Color", "Rosy Brown" ), false);
00249     insertColor(qRgb( 219 ,   112 ,   147 ), i18n( "Color", "Pale Violet Red" ), false);
00250     insertColor(qRgb(   0 ,   250 ,   154 ), i18n( "Color", "Medium Spring Green" ), false);
00251     insertColor(qRgb( 255 ,    99 ,    71 ), i18n( "Color", "Tomato" ), false);
00252     insertColor(qRgb( 0   ,   255 ,   127 ), i18n( "Color", "Spring Green" ), false);
00253     insertColor(qRgb( 205 ,   133 ,    63 ), i18n( "Color", "Peru" ), false);
00254     insertColor(qRgb( 100 ,   149 ,   237 ), i18n( "Color", "Cornflower Blue" ), false);
00255     insertColor(qRgb( 132 ,   112 ,   255 ), i18n( "Color", "Light Slate Blue" ), false);
00256     insertColor(qRgb( 147 ,   112 ,   219 ), i18n( "Color", "Medium Purple" ), false);
00257     insertColor(qRgb( 186 ,    85 ,   211 ), i18n( "Color", "Medium Orchid" ), false);
00258     insertColor(qRgb(  95 ,   158 ,   160 ), i18n( "Color", "Cadet Blue" ), false);
00259     insertColor(qRgb(   0 ,   206 ,   209 ), i18n( "Color", "Dark Turquoise" ), false);
00260     insertColor(qRgb(   0 ,   191 ,   255 ), i18n( "Color", "Deep Sky Blue" ), false);
00261     insertColor(qRgb( 119 ,   136 ,   153 ), i18n( "Color", "Light Slate Gray" ), false);
00262     insertColor(qRgb( 184 ,   134 ,    11 ), i18n( "Color", "Dark Goldenrod" ), false);
00263     insertColor(qRgb( 123 ,   104 ,   238 ), i18n( "Color", "Medium Slate Blue" ), false);
00264     insertColor(qRgb( 205 ,    92 ,    92 ), i18n( "Color", "Indian Red" ), false);
00265     insertColor(qRgb( 210 ,   105 ,    30 ), i18n( "Color", "Chocolate" ), false);
00266     insertColor(qRgb(  60 ,   179 ,   113 ), i18n( "Color", "Medium Sea Green" ), false);
00267     insertColor(qRgb(  50 ,   205 ,    50 ), i18n( "Color", "Lime Green" ), false);
00268     insertColor(qRgb(  32 ,   178 ,   170 ), i18n( "Color", "Light Sea Green" ), false);
00269     insertColor(qRgb( 112 ,   128 ,   144 ), i18n( "Color", "Slate Gray" ), false);
00270     insertColor(qRgb(  30 ,   144 ,   255 ), i18n( "Color", "Dodger Blue" ), false);
00271     insertColor(qRgb( 255 ,    69 ,     0 ), i18n( "Color", "Orange Red" ), false);
00272     insertColor(qRgb( 255 ,    20 ,   147 ), i18n( "Color", "Deep Pink" ), false);
00273     insertColor(qRgb(  70 ,   130 ,   180 ), i18n( "Color", "Steel Blue" ), false);
00274     insertColor(qRgb( 106 ,    90 ,   205 ), i18n( "Color", "Slate Blue" ), false);
00275     insertColor(qRgb( 107 ,   142 ,    35 ), i18n( "Color", "Olive Drab" ), false);
00276     insertColor(qRgb(  65 ,   105 ,   225 ), i18n( "Color", "Royal Blue" ), false);
00277     insertColor(qRgb( 208 ,    32 ,   144 ), i18n( "Color", "Violet Red" ), false);
00278     insertColor(qRgb( 153 ,    50 ,   204 ), i18n( "Color", "Dark Orchid" ), false);
00279     insertColor(qRgb( 160 ,    32 ,   240 ), i18n( "Color", "Purple" ), false);
00280     insertColor(qRgb( 105 ,   105 ,   105 ), i18n( "Color", "Dim Gray" ), false);
00281     insertColor(qRgb( 138 ,    43 ,   226 ), i18n( "Color", "Blue Violet" ), false);
00282     insertColor(qRgb( 160 ,    82 ,    45 ), i18n( "Color", "Sienna" ), false);
00283     insertColor(qRgb( 199 ,    21 ,   133 ), i18n( "Color", "Medium Violet Red" ), false);
00284     insertColor(qRgb( 176 ,    48 ,    96 ), i18n( "Color", "Maroon" ), false);
00285     insertColor(qRgb(  46 ,   139 ,    87 ), i18n( "Color", "Sea Green" ), false);
00286     insertColor(qRgb(  85 ,   107 ,    47 ), i18n( "Color", "Dark Olive Green" ), false);
00287     insertColor(qRgb(  34 ,   139 ,    34 ), i18n( "Color", "Forest Green" ), false);
00288     insertColor(qRgb( 139 ,    69 ,    19 ), i18n( "Color", "Saddle Brown" ), false);
00289     insertColor(qRgb( 148 ,     0 ,   211 ), i18n( "Color", "Dark Violet" ), false);
00290     insertColor(qRgb( 178 ,    34 ,    34 ), i18n( "Color", "Fire Brick" ), false);
00291     insertColor(qRgb(  72 ,    61 ,   139 ), i18n( "Color", "Dark Slate Blue" ), false);
00292     insertColor(qRgb(  47 ,    79 ,    79 ), i18n( "Color", "Dark Slate Gray" ), false);
00293     insertColor(qRgb(  25 ,    25 ,   112 ), i18n( "Color", "Midnight Blue" ), false);
00294     insertColor(qRgb(   0 ,     0 ,   205 ), i18n( "Color", "Medium Blue" ), false);
00295     insertColor(qRgb(   0 ,     0 ,   128 ), i18n( "Color", "Navy" ), false);
00296 
00297     finalizeInsertion( m_nextPosition );  // with a no-op paint() call as we repaint anyway
00298     updateGeometry();
00299     // we have to repaint the "old" current row explicitly due
00300     // to WStaticContents
00301     update( 0, currentRow << 4, COLS << 4, 16 );
00302 }
00303 
00304 void KoColorPanel::mousePressEvent( QMouseEvent* e )
00305 {
00306     if ( e->button() == Qt::LeftButton )
00307         m_pressedPos = e->pos();
00308 }
00309 
00310 void KoColorPanel::mouseReleaseEvent( QMouseEvent* )
00311 {
00312     if ( isVisible() && parentWidget() && parentWidget()->inherits( "QPopupMenu" ) )
00313         parentWidget()->close();
00314     emit colorSelected( mapToColor( m_pressedPos ) );
00315 }
00316 
00317 void KoColorPanel::mouseMoveEvent( QMouseEvent* e )
00318 {
00319     if ( e->state() & Qt::LeftButton ) {
00320         QPoint p = m_pressedPos - e->pos();
00321         if ( p.manhattanLength() > QApplication::startDragDistance() ) {
00322             QColor color( mapToColor( m_pressedPos ) );
00323             if ( color.isValid() ) {
00324                 KColorDrag *drag = new KColorDrag( color, this, name() );
00325                 drag->dragCopy();
00326             }
00327         }
00328     }
00329     else
00330         updateFocusPosition( mapToPosition( e->pos() ) );
00331 }
00332 
00333 void KoColorPanel::paintEvent( QPaintEvent* e )
00334 {
00335     int lns = lines();
00336     int startRow, endRow, startCol, endCol;
00337     paintArea( e->rect(), startRow, endRow, startCol, endCol );
00338 
00339     QPainter p( this );
00340 
00341     // First clear all the areas we won't paint on later (only if the widget isn't erased)
00342     if ( !e->erased() ) {
00343         // vertical rects
00344         int tmp = TILESIZE * lns;
00345         if ( startCol == 0 )
00346             erase( 0, 0, 2, tmp );
00347         if ( endCol == COLS )
00348             erase( width() - 2, 0, 2, tmp );
00349         else
00350             erase( ( endCol << 4 ) - 2, 0, 2, tmp );
00351         int i = startCol == 0 ? 1 : startCol;
00352         for ( ; i < endCol; ++i )
00353             erase( ( i << 4 ) - 2, 0, 4, tmp );
00354 
00355         // horizontal rects
00356         tmp = TILESIZE * COLS;
00357         if ( startRow == 0 )
00358             erase( 0, 0, tmp, 2 );
00359         if ( endRow == lns )
00360             erase( 0, height() - 2, tmp, 2 );
00361         else
00362             erase( 0, ( endRow << 4 ) - 2, tmp, 2 );
00363         i = startRow == 0 ? 1 : startRow;
00364         for ( ; i < endRow; ++i )
00365             erase( 0, ( i << 4 ) - 2, tmp, 4 );
00366     }
00367 
00368     // The "active" element (if there is one)
00369     if ( hasFocus() && m_focusPosition.x != -1 && m_focusPosition.y != -1 &&
00370          mapFromPosition( m_focusPosition ).intersects( e->rect() ) )
00371         style().drawPrimitive( QStyle::PE_Panel, &p, QRect( m_focusPosition.x << 4, m_focusPosition.y << 4, TILESIZE, TILESIZE ),
00372                                colorGroup(), QStyle::Style_Sunken | QStyle::Style_Enabled );
00373 
00374     --lns;  // Attention: We just avoid some lns - 1 statements
00375 
00376     // ...all color tiles
00377     if ( !m_colorMap.isEmpty() ) {
00378         int currentRow = startRow, currentCol = startCol;
00379         while ( currentRow < endRow && currentCol < endCol ) {
00380             QMap<Position, QColor>::ConstIterator it = m_colorMap.find( Position( currentCol, currentRow ) );
00381             if( it != m_colorMap.end() )
00382                 p.fillRect( ( currentCol << 4 ) + 2, ( currentRow << 4 ) + 2, 12, 12, it.data() );
00383 
00384             // position of the next cell
00385             ++currentCol;
00386             if ( currentCol == endCol ) {
00387                 ++currentRow;
00388                 currentCol = startCol;
00389             }
00390         }
00391     }
00392 
00393     // clean up the last line (it's most likely that it's not totally filled)
00394     if ( !e->erased() && endRow > lns ) {
00395         int fields = m_colorMap.count() % COLS;
00396         erase( fields << 4, lns * TILESIZE, ( COLS - fields ) << 4, 16 );
00397     }
00398 }
00399 
00400 void KoColorPanel::keyPressEvent( QKeyEvent* e )
00401 {
00402     Position newPos( validPosition( m_focusPosition ) );
00403     if ( e->key() == Qt::Key_Up ) {
00404         if ( newPos.y == 0 )
00405             e->ignore();
00406         else
00407             --newPos.y;
00408     }
00409     else if ( e->key() == Qt::Key_Down ) {
00410         if ( newPos < Position( m_colorMap.count() % COLS, lines() - 2 ) )
00411             ++newPos.y;
00412         else
00413             e->ignore();
00414     }
00415     else if ( e->key() == Qt::Key_Left ) {
00416         if ( newPos.x == 0 )
00417             e->ignore();
00418         else
00419             --newPos.x;
00420     }
00421     else if ( e->key() == Qt::Key_Right ) {
00422         if ( newPos.x < COLS - 1 && newPos < Position( m_colorMap.count() % COLS - 1, lines() - 1 ) )
00423             ++newPos.x;
00424         else
00425             e->ignore();
00426     }
00427     else if ( e->key() == Qt::Key_Return ) {
00428         if ( isVisible() && parentWidget() && parentWidget()->inherits( "QPopupMenu" ) )
00429             parentWidget()->close();
00430         emit colorSelected( mapToColor( m_focusPosition ) );
00431     }
00432     updateFocusPosition( newPos );
00433 }
00434 
00435 void KoColorPanel::focusInEvent( QFocusEvent* e )
00436 {
00437     if ( !m_colorMap.isEmpty() && m_focusPosition.x == -1 && m_focusPosition.y == -1 ) {
00438         m_focusPosition.x = 0;
00439         m_focusPosition.y = 0;
00440     }
00441     QWidget::focusInEvent( e );
00442 }
00443 
00444 void KoColorPanel::dragEnterEvent( QDragEnterEvent* e )
00445 {
00446     e->accept( KColorDrag::canDecode( e ) );
00447 }
00448 
00449 void KoColorPanel::dropEvent( QDropEvent* e )
00450 {
00451     QColor color;
00452     if ( KColorDrag::decode( e, color ) )
00453         insertColor( color );
00454 }
00455 
00456 void KoColorPanel::finalizeInsertion( const Position& pos )
00457 {
00458     paint( pos );
00459 
00460     if ( !isFocusEnabled() )
00461         setFocusPolicy( QWidget::StrongFocus );
00462     // Did we start a new row?
00463     if ( m_nextPosition.x == 1 )
00464         updateGeometry();
00465 }
00466 
00467 bool KoColorPanel::insertColor( const QColor& color, bool checking )
00468 {
00469     if ( checking && isAvailable( color ) )
00470         return false;
00471 
00472     m_colorMap.insert( m_nextPosition, color );
00473 
00474     ++m_nextPosition.x;
00475     if ( m_nextPosition.x == COLS ) {
00476         m_nextPosition.x = 0;
00477         ++m_nextPosition.y;
00478     }
00479     return true;
00480 }
00481 
00482 bool KoColorPanel::insertColor( const QColor& color, const QString& toolTip, bool checking )
00483 {
00484     if ( checking && isAvailable( color ) )
00485         return false;
00486 
00487     // Remember the "old" m_nextPosition -- this is the place where the newly
00488     // inserted color will be located
00489     QRect rect( mapFromPosition( m_nextPosition ) );
00490     insertColor( color, false ); // check only once ;)
00491     QToolTip::add( this, rect, toolTip );
00492     return true;
00493 }
00494 
00495 bool KoColorPanel::isAvailable( const QColor& color )
00496 {
00497     // O(n) checking on insert, but this is better than O(n) checking
00498     // on every mouse move...
00499     QMap<Position, QColor>::ConstIterator it = m_colorMap.begin();
00500     QMap<Position, QColor>::ConstIterator end = m_colorMap.end();
00501     for ( ; it != end; ++it )
00502         if ( it.data() == color )
00503             return true;
00504     return false;
00505 }
00506 
00507 KoColorPanel::Position KoColorPanel::mapToPosition( const QPoint& point ) const
00508 {
00509     return Position( point.x() >> 4, point.y() >> 4 );
00510 }
00511 
00512 QColor KoColorPanel::mapToColor( const QPoint& point ) const
00513 {
00514     return mapToColor( mapToPosition( point ) );
00515 }
00516 
00517 QColor KoColorPanel::mapToColor( const KoColorPanel::Position& position ) const
00518 {
00519     QMap<Position, QColor>::ConstIterator it = m_colorMap.find( position );
00520     if ( it != m_colorMap.end() )
00521         return it.data();
00522     return QColor();
00523 }
00524 
00525 QRect KoColorPanel::mapFromPosition( const KoColorPanel::Position& position ) const
00526 {
00527     return QRect( position.x << 4, position.y << 4, TILESIZE, TILESIZE );
00528 }
00529 
00530 KoColorPanel::Position KoColorPanel::validPosition( const Position& position )
00531 {
00532     Position pos( position );
00533     int lns = lines() - 1;
00534     int lastLineLen = m_colorMap.count() % COLS - 1;
00535 
00536     // ensure the position is within the valid grid area
00537     // note: special handling of the last line
00538     if ( pos.x < 0 )
00539         pos.x = 0;
00540     else if ( pos.y == lns && pos.x > lastLineLen )
00541         pos.x = lastLineLen;
00542     else if ( pos.x >= COLS )
00543         pos.x = COLS - 1;
00544 
00545     if ( pos.y < 0 )
00546         pos.y = 0;
00547     else if ( pos.x > lastLineLen && pos.y > lns - 1 )
00548         pos.y = lns - 1;
00549     else if ( pos.y > lns )
00550         pos.y = lns;
00551     return pos;
00552 }
00553 
00554 int KoColorPanel::lines() const
00555 {
00556     if ( m_colorMap.isEmpty() )
00557         return 1;
00558     return ( m_colorMap.count() - 1 ) / COLS + 1;
00559 }
00560 
00561 void KoColorPanel::paintArea( const QRect& rect, int& startRow, int& endRow, int& startCol, int& endCol ) const
00562 {
00563     startRow = rect.top() >> 4;
00564     endRow = ( rect.bottom() >> 4 ) + 1;
00565     startCol = rect.left() >> 4;
00566     endCol = ( rect.right() >> 4 ) + 1;
00567 }
00568 
00569 void KoColorPanel::updateFocusPosition( const Position& newPosition )
00570 {
00571     QPainter p( this );
00572 
00573     // restore the old tile where we had the focus before
00574     if ( m_focusPosition.x != -1 && m_focusPosition.y != -1 )
00575         paint( m_focusPosition );
00576 
00577     m_focusPosition = newPosition;
00578 
00579     QMap<Position, QColor>::ConstIterator it = m_colorMap.find( m_focusPosition );
00580     if ( it != m_colorMap.end() ) {
00581         // draw at the new focus position
00582         style().drawPrimitive( QStyle::PE_Panel, &p, QRect( m_focusPosition.x << 4, m_focusPosition.y << 4, TILESIZE, TILESIZE ),
00583                                colorGroup(), QStyle::Style_Sunken | QStyle::Style_Enabled );
00584         p.fillRect( ( m_focusPosition.x << 4 ) + 2, ( m_focusPosition.y << 4 ) + 2, 12, 12, it.data() );
00585     }
00586 
00587 }
00588 
00589 void KoColorPanel::paint( const Position& position )
00590 {
00591     QMap<Position, QColor>::ConstIterator it = m_colorMap.find( position );
00592     if ( it == m_colorMap.end() )
00593         return;
00594 
00595     erase( mapFromPosition( position ) );
00596     QPainter p( this );
00597     p.fillRect( ( position.x << 4 ) + 2, ( position.y << 4 ) + 2, 12, 12, it.data() );
00598 }
00599 
00600 void KoColorPanel::init()
00601 {
00602     setFocusPolicy( QWidget::NoFocus ); // it's empty
00603     m_nextPosition.x = 0;
00604     m_nextPosition.y = 0;
00605     m_focusPosition.x = -1;
00606     m_focusPosition.y = -1;
00607     m_defaultsAdded = false;
00608 }
00609 
00610 bool operator<( const KoColorPanel::Position& lhs, const KoColorPanel::Position& rhs )
00611 {
00612     return ( lhs.y * COLS + lhs.x ) < ( rhs.y * COLS + rhs.x );
00613 }
00614 
00615 
00616 KoColorPopupProxy::KoColorPopupProxy( const QColor& defaultColor, KoColorPanel* recentColors, QObject* parent, const char* name ) :
00617     QObject( parent, name ), m_defaultColor( defaultColor ), m_recentColors( recentColors )
00618 {
00619 }
00620 
00621 void KoColorPopupProxy::setRecentColorPanel( KoColorPanel* recentColors )
00622 {
00623     m_recentColors = recentColors;
00624 }
00625 
00626 void KoColorPopupProxy::slotDefaultColor()
00627 {
00628     emit colorSelected( m_defaultColor );
00629 }
00630 
00631 void KoColorPopupProxy::slotMoreColors()
00632 {
00633     if ( !m_recentColors )
00634         return;
00635 
00636     QColor newColor;
00637     QWidget* p = 0;
00638     if ( parent() && parent()->isWidgetType() )
00639         p = static_cast<QWidget*>( parent() );
00640 
00641     if ( KColorDialog::getColor( newColor, p ) == QDialog::Accepted ) {
00642         m_recentColors->insertColor( newColor );
00643         emit colorSelected( newColor );
00644     }
00645 }
00646 
00647 
00648 KoToolButton::KoToolButton( const QString& icon, int id, QWidget* parent,
00649                             const char* name, const QString& txt, KInstance* _instance ) :
00650     KToolBarButton( icon, id, parent, name, txt, _instance ), m_arrowPressed( false )
00651 {
00652     init();
00653 }
00654 
00655 KoToolButton::KoToolButton( const QPixmap& pixmap, int id, QWidget* parent,
00656                             const char* name, const QString& txt ) :
00657     KToolBarButton( pixmap, id, parent, name, txt ), m_arrowPressed( false )
00658 {
00659     init();
00660 }
00661 
00662 KoToolButton::~KoToolButton()
00663 {
00664 }
00665 
00666 QSize KoToolButton::sizeHint() const
00667 {
00668     return minimumSizeHint();
00669 }
00670 
00671 QSize KoToolButton::minimumSizeHint() const
00672 {
00673     QSize size = KToolBarButton::minimumSizeHint();
00674     size.setWidth( size.width() + ARROW_WIDTH );
00675     return size;
00676 }
00677 
00678 QSize KoToolButton::minimumSize() const
00679 {
00680     return minimumSizeHint();
00681 }
00682 
00683 void KoToolButton::colorSelected( const QColor& color )
00684 {
00685     kdDebug() << "selected::: " << color.name() << endl;
00686 }
00687 
00688 void KoToolButton::drawButton(QPainter *_painter)
00689 {
00690     QStyle::SFlags flags = QStyle::Style_Default;
00691     QStyle::SCFlags active = QStyle::SC_None;
00692     QStyle::SCFlags arrowActive = QStyle::SC_None;
00693     QStyleOption opt;
00694     QColorGroup cg( colorGroup() );
00695 
00696     if ( isEnabled() ) {
00697     flags |= QStyle::Style_Enabled;
00698         if ( KToolBarButton::isRaised() || m_arrowPressed )
00699             flags |= QStyle::Style_Raised;
00700     }
00701     if ( isOn() )
00702         flags |= QStyle::Style_On;
00703 
00704     QStyle::SFlags arrowFlags = flags;
00705 
00706     if ( isDown() && !m_arrowPressed ) {
00707         flags  |= QStyle::Style_Down;
00708         active |= QStyle::SC_ToolButton;
00709     }
00710     if ( m_arrowPressed )
00711         arrowActive |= QStyle::SC_ToolButton;
00712 
00713     // Draw styled toolbuttons
00714     _painter->setClipRect( 0, 0, width() - ARROW_WIDTH, height() );
00715     style().drawComplexControl( QStyle::CC_ToolButton, _painter, this, QRect( 0, 0, width() - ARROW_WIDTH, height() ), cg,
00716                                 flags, QStyle::SC_ToolButton, active, opt );
00717     _painter->setClipRect( width() - ARROW_WIDTH, 0, ARROW_WIDTH, height() );
00718     style().drawComplexControl( QStyle::CC_ToolButton, _painter, this, QRect( width(), 0, ARROW_WIDTH, height() ), cg,
00719                                 arrowFlags, QStyle::SC_ToolButton, arrowActive, opt );
00720     _painter->setClipping( false );
00721 
00722     // ...and the arrow indicating the popup
00723     style().drawPrimitive( QStyle::PE_ArrowDown, _painter, QRect( width() - ARROW_WIDTH - 1, 0, ARROW_WIDTH, height() ),
00724                            cg, flags, opt );
00725 
00726     if ( KToolBarButton::isRaised() || m_arrowPressed )
00727         qDrawShadeLine( _painter, width() - ARROW_WIDTH - 1, 0, width() - ARROW_WIDTH - 1, height() - 1, colorGroup(), true );
00728 
00729     int dx, dy;
00730     QFont tmp_font( KGlobalSettings::toolBarFont() );
00731     QFontMetrics fm( tmp_font );
00732     QRect textRect;
00733     int textFlags = 0;
00734 
00735     if ( static_cast<KToolBar::IconText>( iconTextMode() ) == KToolBar::IconOnly ) { // icon only
00736         QPixmap pixmap = iconSet().pixmap( QIconSet::Automatic,
00737                                            isEnabled() ? ( KToolBarButton::isActive() ? QIconSet::Active : QIconSet::Normal ) :
00738                                            QIconSet::Disabled, isOn() ? QIconSet::On : QIconSet::Off );
00739         if ( !pixmap.isNull() ) {
00740             dx = ( width() - ARROW_WIDTH - pixmap.width() ) / 2;
00741             dy = ( height() - pixmap.height() ) / 2;
00742             buttonShift( dx, dy );
00743             _painter->drawPixmap( dx, dy, pixmap );
00744         }
00745     }
00746     else if ( static_cast<KToolBar::IconText>( iconTextMode() ) == KToolBar::IconTextRight ) { // icon and text (if any)
00747         QPixmap pixmap = iconSet().pixmap( QIconSet::Automatic,
00748                                            isEnabled() ? ( KToolBarButton::isActive() ? QIconSet::Active : QIconSet::Normal ) :
00749                                            QIconSet::Disabled, isOn() ? QIconSet::On : QIconSet::Off );
00750         if( !pixmap.isNull()) {
00751             dx = 4;
00752             dy = ( height() - pixmap.height() ) / 2;
00753             buttonShift( dx, dy );
00754             _painter->drawPixmap( dx, dy, pixmap );
00755         }
00756 
00757         if (!textLabel().isNull()) {
00758             textFlags = AlignVCenter | AlignLeft;
00759             if ( !pixmap.isNull() )
00760                 dx = 4 + pixmap.width() + 2;
00761             else
00762                 dx = 4;
00763             dy = 0;
00764             buttonShift( dx, dy );
00765             textRect = QRect( dx, dy, width() - dx, height() );
00766         }
00767     }
00768     else if ( static_cast<KToolBar::IconText>( iconTextMode() ) == KToolBar::TextOnly ) {
00769         if ( !textLabel().isNull() ) {
00770             textFlags = AlignTop | AlignLeft;
00771             dx = ( width() - ARROW_WIDTH - fm.width( textLabel() ) ) / 2;
00772             dy = ( height() - fm.lineSpacing() ) / 2;
00773             buttonShift( dx, dy );
00774             textRect = QRect( dx, dy, fm.width(textLabel()), fm.lineSpacing() );
00775         }
00776     }
00777     else if ( static_cast<KToolBar::IconText>( iconTextMode() ) == KToolBar::IconTextBottom ) {
00778         QPixmap pixmap = iconSet().pixmap( QIconSet::Automatic,
00779                                            isEnabled() ? ( KToolBarButton::isActive() ? QIconSet::Active : QIconSet::Normal ) :
00780                                            QIconSet::Disabled, isOn() ? QIconSet::On : QIconSet::Off );
00781         if( !pixmap.isNull()) {
00782             dx = ( width() - ARROW_WIDTH - pixmap.width() ) / 2;
00783             dy = ( height() - fm.lineSpacing() - pixmap.height() ) / 2;
00784             buttonShift( dx, dy );
00785             _painter->drawPixmap( dx, dy, pixmap );
00786         }
00787 
00788         if ( !textLabel().isNull() ) {
00789             textFlags = AlignBottom | AlignHCenter;
00790             dx = ( width() - ARROW_WIDTH - fm.width( textLabel() ) ) / 2;
00791             dy = height() - fm.lineSpacing() - 4;
00792             buttonShift( dx, dy );
00793             textRect = QRect( dx, dy, fm.width( textLabel() ), fm.lineSpacing() );
00794         }
00795     }
00796 
00797     // Draw the text at the position given by textRect, and using textFlags
00798     if (!textLabel().isNull() && !textRect.isNull()) {
00799         _painter->setFont( KGlobalSettings::toolBarFont() );
00800         if ( !isEnabled() )
00801             _painter->setPen( palette().disabled().dark() );
00802         else if( KToolBarButton::isRaised() )
00803             _painter->setPen( KGlobalSettings::toolBarHighlightColor() );
00804         else
00805             _painter->setPen( colorGroup().buttonText() );
00806         _painter->drawText( textRect, textFlags, textLabel() );
00807     }
00808 }
00809 
00810 bool KoToolButton::eventFilter( QObject* o, QEvent* e )
00811 {
00812     if ( o == m_popup ) {
00813         if ( e->type() == QEvent::MouseButtonPress )
00814             if ( hitArrow( mapFromGlobal( static_cast<QMouseEvent*>( e )->globalPos() ) ) ) {
00815                 kdDebug() << "KoToolButton::eventFilter-------------->" << endl;
00816                 m_popup->close();
00817                 m_arrowPressed = false;
00818                 return true;
00819             }
00820         return false;
00821     }
00822 
00823     if ( e->type() == QEvent::MouseButtonPress ) {
00824         m_arrowPressed = hitArrow( static_cast<QMouseEvent*>( e )->pos() );
00825         if ( m_arrowPressed )
00826             m_popup->popup( mapToGlobal( QPoint( 0, height() ) ) );
00827     }
00828     else if ( e->type() == QEvent::MouseButtonRelease )
00829         m_arrowPressed = false;
00830     return KToolBarButton::eventFilter( o, e );
00831 }
00832 
00833 void KoToolButton::init()
00834 {
00835     m_popup = KoColorPanel::createColorPopup( KoColorPanel::CustomColors, Qt::yellow, this,
00836                                               SLOT( colorSelected( const QColor& ) ),
00837                                               this, "no-name" );
00838     // We are interested in the mouse clicks on the arrow button
00839     m_popup->installEventFilter( this );
00840 
00841     ARROW_WIDTH = style().pixelMetric(QStyle::PM_MenuButtonIndicator) + 4;
00842     kdDebug() << "##################### Arrow: " << ARROW_WIDTH << endl;
00843 }
00844 
00845 void KoToolButton::buttonShift( int& dx, int& dy )
00846 {
00847     if ( isDown() && !m_arrowPressed ) {
00848         dx += style().pixelMetric( QStyle::PM_ButtonShiftHorizontal );
00849         dy += style().pixelMetric( QStyle::PM_ButtonShiftVertical );
00850     }
00851 }
00852 
00853 bool KoToolButton::hitArrow( const QPoint& pos )
00854 {
00855     return QRect( width() - ARROW_WIDTH, 0, ARROW_WIDTH, height() ).contains( pos );
00856 }
00857 
00858 #include <kotoolbutton.moc>
KDE Logo
This file is part of the documentation for lib Library Version 1.3.5.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sun Mar 20 14:25:28 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003