KoTooluButton.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2002 Werner Trobin <trobin@kde.org>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18*/
19
20#include <tqapplication.h>
21#include <tqtooltip.h>
22#include <tqpainter.h>
23#include <tqdrawutil.h>
24#include <tqpixmap.h>
25#include <tqstyle.h>
26#include <tqpopupmenu.h>
27
28#include <tdeglobalsettings.h>
29#include <tdetoolbar.h>
30#include <KoTooluButton.h>
31#include <kcolordrag.h>
32#include <tdelocale.h>
33#include <kcolordialog.h>
34#include <kdebug.h>
35
36namespace {
37 // For the KoColorPanel
38 const int COLS = 15;
39 const int TILESIZE = 16;
40 // For the KoToolButton
41 int ARROW_WIDTH = 12;
42}
43
44KoColorPanel::KoColorPanel( TQWidget* parent, const char* name ) :
45 TQWidget( parent, name, WStaticContents | WRepaintNoErase | WResizeNoErase )
46{
47 setMouseTracking( true );
48 setAcceptDrops( true );
49 init();
50}
51
52KoColorPanel::~KoColorPanel()
53{
54}
55
56TQSize KoColorPanel::sizeHint() const
57{
58 return minimumSizeHint();
59}
60
61TQSize KoColorPanel::minimumSizeHint() const
62{
63 return TQSize( COLS << 4, lines() << 4 );
64}
65
66TQPopupMenu* KoColorPanel::createColorPopup( KoColorPanel::MenuStyle style, const TQColor& defaultColor,
67 const TQObject* receiver, const char* slot,
68 TQWidget* parent, const char* name )
69{
70 TQPopupMenu* menu = new TQPopupMenu( parent, name );
71 KoColorPopupProxy* proxy = 0;
72
73 if ( defaultColor.isValid() ) {
74 TQPixmap pixmap( 12, 12 );
75 TQPainter p( &pixmap );
76 p.fillRect( 0, 0, 12, 12, defaultColor );
77 p.end();
78 proxy = new KoColorPopupProxy( defaultColor, 0, menu, "color proxy" );
79 connect( proxy, TQ_SIGNAL( colorSelected( const TQColor& ) ), receiver, slot );
80 menu->insertItem( TQIconSet( pixmap ), i18n( "Default Color" ), proxy, TQ_SLOT( slotDefaultColor() ) );
81 menu->insertSeparator();
82 }
83
84 KoColorPanel* panel = new KoColorPanel( menu, "default colors" );
85 panel->insertDefaultColors();
86 connect( panel, TQ_SIGNAL( colorSelected( const TQColor& ) ), receiver, slot );
87 menu->insertItem( panel );
88
89 if ( style == CustomColors ) {
90 menu->insertSeparator();
91 panel = new KoColorPanel( menu, "custom panel" );
92 connect( panel, TQ_SIGNAL( colorSelected( const TQColor& ) ), receiver, slot );
93 menu->insertItem( panel );
94 if ( !proxy ) {
95 proxy = new KoColorPopupProxy( TQColor(), panel, menu, "color proxy" );
96 connect( proxy, TQ_SIGNAL( colorSelected( const TQColor& ) ), receiver, slot );
97 }
98 else
99 proxy->setRecentColorPanel( panel );
100 menu->insertSeparator();
101 menu->insertItem( i18n( "More Colors..." ), proxy, TQ_SLOT( slotMoreColors() ) );
102 }
103
104 return menu;
105}
106
107void KoColorPanel::clear()
108{
109 if ( m_colorMap.isEmpty() )
110 return;
111
112 TQSize area( minimumSizeHint() );
113 m_colorMap.clear();
114 init();
115 updateGeometry();
116 erase( 0, 0, area.width(), area.height() );
117}
118
119void KoColorPanel::insertColor( const TQColor& color )
120{
121 Position pos = m_nextPosition;
122 if ( insertColor( color, true ) ) // we want checking for external users
123 finalizeInsertion( pos );
124}
125
126void KoColorPanel::insertColor( const TQColor& color, const TQString& toolTip )
127{
128 Position pos = m_nextPosition;
129 if ( insertColor( color, toolTip, true ) ) // we want checking for external users
130 finalizeInsertion( pos );
131}
132
133void KoColorPanel::insertDefaultColors()
134{
135 if ( m_defaultsAdded )
136 return;
137 m_defaultsAdded = true;
138
139 int currentRow = m_nextPosition.y; // we have to repaint this row below
140
141 // Note: No checking for duplicates, so take care when you modify that list
142 insertColor(TQColor( 255 , 0 , 0 ), i18n( "color", "Red" ), false);
143 insertColor(TQColor( 255 , 165 , 0 ), i18n( "color", "Orange" ), false);
144 insertColor(TQColor( 255 , 0 , 255 ), i18n( "color", "Magenta" ), false);
145 insertColor(TQColor( 0 , 0 , 255 ), i18n( "color", "Blue" ), false);
146 insertColor(TQColor( 0 , 255 , 255 ), i18n( "color", "Cyan" ), false);
147 insertColor(TQColor( 0 , 255 , 0 ), i18n( "color", "Green" ), false);
148 insertColor(TQColor( 255 , 255 , 0 ), i18n( "color", "Yellow" ), false);
149 insertColor(TQColor( 165 , 42 , 42 ), i18n( "color", "Brown" ), false);
150 insertColor(TQColor( 139 , 0 , 0 ), i18n( "color", "DarkRed" ), false);
151 insertColor(TQColor( 255 , 140 , 0 ), i18n( "color", "DarkOrange" ), false);
152 insertColor(TQColor( 139 , 0 , 139 ), i18n( "color", "DarkMagenta" ), false);
153 insertColor(TQColor( 0 , 0 , 139 ), i18n( "color", "DarkBlue" ), false);
154 insertColor(TQColor( 0 , 139 , 139 ), i18n( "color", "DarkCyan" ), false);
155 insertColor(TQColor( 0 , 100 , 0 ), i18n( "color", "DarkGreen" ), false);
156 insertColor(TQColor( 130 , 127 , 0 ), i18n( "color", "DarkYellow" ), false);
157 insertColor(TQColor( 255 , 255 , 255 ), i18n( "color", "White" ), false);
158 // xgettext:no-c-format
159 insertColor(TQColor( 229 , 229 , 229 ), i18n( "color", "Gray 90%" ), false);
160 // xgettext:no-c-format
161 insertColor(TQColor( 204 , 204 , 204 ), i18n( "color", "Gray 80%" ), false);
162 // xgettext:no-c-format
163 insertColor(TQColor( 178 , 178 , 178 ), i18n( "color", "Gray 70%" ), false);
164 // xgettext:no-c-format
165 insertColor(TQColor( 153 , 153 , 153 ), i18n( "color", "Gray 60%" ), false);
166 // xgettext:no-c-format
167 insertColor(TQColor( 127 , 127 , 127 ), i18n( "color", "Gray 50%" ), false);
168 // xgettext:no-c-format
169 insertColor(TQColor( 102 , 102 , 102 ), i18n( "color", "Gray 40%" ), false);
170 // xgettext:no-c-format
171 insertColor(TQColor( 76 , 76 , 76 ), i18n( "color", "Gray 30%" ), false);
172 // xgettext:no-c-format
173 insertColor(TQColor( 51 , 51 , 51 ), i18n( "color", "Gray 20%" ), false);
174 // xgettext:no-c-format
175 insertColor(TQColor( 25 , 25 , 25 ), i18n( "color", "Gray 10%" ), false);
176 insertColor(TQColor( 0 , 0 , 0 ), i18n( "color", "Black" ), false);
177 insertColor(TQColor( 255 , 255 , 240 ), i18n( "color", "Ivory" ), false);
178 insertColor(TQColor( 255 , 250 , 250 ), i18n( "color", "Snow" ), false);
179 insertColor(TQColor( 245 , 255 , 250 ), i18n( "color", "MintCream" ), false);
180 insertColor(TQColor( 255 , 250 , 240 ), i18n( "color", "FloralWhite" ), false);
181 insertColor(TQColor( 255 , 255 , 224 ), i18n( "color", "LightYellow" ), false);
182 insertColor(TQColor( 240 , 255 , 255 ), i18n( "color", "Azure" ), false);
183 insertColor(TQColor( 248 , 248 , 255 ), i18n( "color", "GhostWhite" ), false);
184 insertColor(TQColor( 240 , 255 , 240 ), i18n( "color", "Honeydew" ), false);
185 insertColor(TQColor( 255 , 245 , 238 ), i18n( "color", "Seashell" ), false);
186 insertColor(TQColor( 240 , 248 , 255 ), i18n( "color", "AliceBlue" ), false);
187 insertColor(TQColor( 255 , 248 , 220 ), i18n( "color", "Cornsilk" ), false);
188 insertColor(TQColor( 255 , 240 , 245 ), i18n( "color", "LavenderBlush" ), false);
189 insertColor(TQColor( 253 , 245 , 230 ), i18n( "color", "OldLace" ), false);
190 insertColor(TQColor( 245 , 245 , 245 ), i18n( "color", "WhiteSmoke" ), false);
191 insertColor(TQColor( 255 , 250 , 205 ), i18n( "color", "LemonChiffon" ), false);
192 insertColor(TQColor( 224 , 255 , 255 ), i18n( "color", "LightCyan" ), false);
193 insertColor(TQColor( 250 , 250 , 210 ), i18n( "color", "LightGoldenrodYellow" ), false);
194 insertColor(TQColor( 250 , 240 , 230 ), i18n( "color", "Linen" ), false);
195 insertColor(TQColor( 245 , 245 , 220 ), i18n( "color", "Beige" ), false);
196 insertColor(TQColor( 255 , 239 , 213 ), i18n( "color", "PapayaWhip" ), false);
197 insertColor(TQColor( 255 , 235 , 205 ), i18n( "color", "BlanchedAlmond" ), false);
198 insertColor(TQColor( 250 , 235 , 215 ), i18n( "color", "AntiqueWhite" ), false);
199 insertColor(TQColor( 255 , 228 , 225 ), i18n( "color", "MistyRose" ), false);
200 insertColor(TQColor( 230 , 230 , 250 ), i18n( "color", "Lavender" ), false);
201 insertColor(TQColor( 255 , 228 , 196 ), i18n( "color", "Bisque" ), false);
202 insertColor(TQColor( 255 , 228 , 181 ), i18n( "color", "Moccasin" ), false);
203 insertColor(TQColor( 255 , 222 , 173 ), i18n( "color", "NavajoWhite" ), false);
204 insertColor(TQColor( 255 , 218 , 185 ), i18n( "color", "PeachPuff" ), false);
205 insertColor(TQColor( 238 , 232 , 170 ), i18n( "color", "PaleGoldenrod" ), false);
206 insertColor(TQColor( 245 , 222 , 179 ), i18n( "color", "Wheat" ), false);
207 insertColor(TQColor( 220 , 220 , 220 ), i18n( "color", "Gainsboro" ), false);
208 insertColor(TQColor( 240 , 230 , 140 ), i18n( "color", "Khaki" ), false);
209 insertColor(TQColor( 175 , 238 , 238 ), i18n( "color", "PaleTurquoise" ), false);
210 insertColor(TQColor( 255 , 192 , 203 ), i18n( "color", "Pink" ), false);
211 insertColor(TQColor( 238 , 221 , 130 ), i18n( "color", "LightGoldenrod" ), false);
212 insertColor(TQColor( 211 , 211 , 211 ), i18n( "color", "LightGray" ), false);
213 insertColor(TQColor( 255 , 182 , 193 ), i18n( "color", "LightPink" ), false);
214 insertColor(TQColor( 176 , 224 , 230 ), i18n( "color", "PowderBlue" ), false);
215 insertColor(TQColor( 127 , 255 , 212 ), i18n( "color", "Aquamarine" ), false);
216 insertColor(TQColor( 216 , 191 , 216 ), i18n( "color", "Thistle" ), false);
217 insertColor(TQColor( 173 , 216 , 230 ), i18n( "color", "LightBlue" ), false);
218 insertColor(TQColor( 152 , 251 , 152 ), i18n( "color", "PaleGreen" ), false);
219 insertColor(TQColor( 255 , 215 , 0 ), i18n( "color", "Gold" ), false);
220 insertColor(TQColor( 173 , 255 , 47 ), i18n( "color", "GreenYellow" ), false);
221 insertColor(TQColor( 176 , 196 , 222 ), i18n( "color", "LightSteelBlue" ), false);
222 insertColor(TQColor( 144 , 238 , 144 ), i18n( "color", "LightGreen" ), false);
223 insertColor(TQColor( 221 , 160 , 221 ), i18n( "color", "Plum" ), false);
224 insertColor(TQColor( 190 , 190 , 190 ), i18n( "color", "Gray" ), false);
225 insertColor(TQColor( 222 , 184 , 135 ), i18n( "color", "BurlyWood" ), false);
226 insertColor(TQColor( 135 , 206 , 250 ), i18n( "color", "LightSkyBlue" ), false);
227 insertColor(TQColor( 255 , 160 , 122 ), i18n( "color", "LightSalmon" ), false);
228 insertColor(TQColor( 135 , 206 , 235 ), i18n( "color", "SkyBlue" ), false);
229 insertColor(TQColor( 210 , 180 , 140 ), i18n( "color", "Tan" ), false);
230 insertColor(TQColor( 238 , 130 , 238 ), i18n( "color", "Violet" ), false);
231 insertColor(TQColor( 244 , 164 , 96 ), i18n( "color", "SandyBrown" ), false);
232 insertColor(TQColor( 233 , 150 , 122 ), i18n( "color", "DarkSalmon" ), false);
233 insertColor(TQColor( 189 , 183 , 107 ), i18n( "color", "DarkKhaki" ), false);
234 insertColor(TQColor( 127 , 255 , 0 ), i18n( "color", "Chartreuse" ), false);
235 insertColor(TQColor( 169 , 169 , 169 ), i18n( "color", "DarkGray" ), false);
236 insertColor(TQColor( 124 , 252 , 0 ), i18n( "color", "LawnGreen" ), false);
237 insertColor(TQColor( 255 , 105 , 180 ), i18n( "color", "HotPink" ), false);
238 insertColor(TQColor( 250 , 128 , 114 ), i18n( "color", "Salmon" ), false);
239 insertColor(TQColor( 240 , 128 , 128 ), i18n( "color", "LightCoral" ), false);
240 insertColor(TQColor( 64 , 224 , 208 ), i18n( "color", "Turquoise" ), false);
241 insertColor(TQColor( 143 , 188 , 143 ), i18n( "color", "DarkSeaGreen" ), false);
242 insertColor(TQColor( 218 , 112 , 214 ), i18n( "color", "Orchid" ), false);
243 insertColor(TQColor( 102 , 205 , 170 ), i18n( "color", "MediumAquamarine" ), false);
244 insertColor(TQColor( 255 , 127 , 80 ), i18n( "color", "Coral" ), false);
245 insertColor(TQColor( 154 , 205 , 50 ), i18n( "color", "YellowGreen" ), false);
246 insertColor(TQColor( 218 , 165 , 32 ), i18n( "color", "Goldenrod" ), false);
247 insertColor(TQColor( 72 , 209 , 204 ), i18n( "color", "MediumTurquoise" ), false);
248 insertColor(TQColor( 188 , 143 , 143 ), i18n( "color", "RosyBrown" ), false);
249 insertColor(TQColor( 219 , 112 , 147 ), i18n( "color", "PaleVioletRed" ), false);
250 insertColor(TQColor( 0 , 250 , 154 ), i18n( "color", "MediumSpringGreen" ), false);
251 insertColor(TQColor( 255 , 99 , 71 ), i18n( "color", "Tomato" ), false);
252 insertColor(TQColor( 0 , 255 , 127 ), i18n( "color", "SpringGreen" ), false);
253 insertColor(TQColor( 205 , 133 , 63 ), i18n( "color", "Peru" ), false);
254 insertColor(TQColor( 100 , 149 , 237 ), i18n( "color", "CornflowerBlue" ), false);
255 insertColor(TQColor( 132 , 112 , 255 ), i18n( "color", "LightSlateBlue" ), false);
256 insertColor(TQColor( 147 , 112 , 219 ), i18n( "color", "MediumPurple" ), false);
257 insertColor(TQColor( 186 , 85 , 211 ), i18n( "color", "MediumOrchid" ), false);
258 insertColor(TQColor( 95 , 158 , 160 ), i18n( "color", "CadetBlue" ), false);
259 insertColor(TQColor( 0 , 206 , 209 ), i18n( "color", "DarkTurquoise" ), false);
260 insertColor(TQColor( 0 , 191 , 255 ), i18n( "color", "DeepSkyBlue" ), false);
261 insertColor(TQColor( 119 , 136 , 153 ), i18n( "color", "LightSlateGray" ), false);
262 insertColor(TQColor( 184 , 134 , 11 ), i18n( "color", "DarkGoldenrod" ), false);
263 insertColor(TQColor( 123 , 104 , 238 ), i18n( "color", "MediumSlateBlue" ), false);
264 insertColor(TQColor( 205 , 92 , 92 ), i18n( "color", "IndianRed" ), false);
265 insertColor(TQColor( 210 , 105 , 30 ), i18n( "color", "Chocolate" ), false);
266 insertColor(TQColor( 60 , 179 , 113 ), i18n( "color", "MediumSeaGreen" ), false);
267 insertColor(TQColor( 50 , 205 , 50 ), i18n( "color", "LimeGreen" ), false);
268 insertColor(TQColor( 32 , 178 , 170 ), i18n( "color", "LightSeaGreen" ), false);
269 insertColor(TQColor( 112 , 128 , 144 ), i18n( "color", "SlateGray" ), false);
270 insertColor(TQColor( 30 , 144 , 255 ), i18n( "color", "DodgerBlue" ), false);
271 insertColor(TQColor( 255 , 69 , 0 ), i18n( "color", "OrangeRed" ), false);
272 insertColor(TQColor( 255 , 20 , 147 ), i18n( "color", "DeepPink" ), false);
273 insertColor(TQColor( 70 , 130 , 180 ), i18n( "color", "SteelBlue" ), false);
274 insertColor(TQColor( 106 , 90 , 205 ), i18n( "color", "SlateBlue" ), false);
275 insertColor(TQColor( 107 , 142 , 35 ), i18n( "color", "OliveDrab" ), false);
276 insertColor(TQColor( 65 , 105 , 225 ), i18n( "color", "RoyalBlue" ), false);
277 insertColor(TQColor( 208 , 32 , 144 ), i18n( "color", "VioletRed" ), false);
278 insertColor(TQColor( 153 , 50 , 204 ), i18n( "color", "DarkOrchid" ), false);
279 insertColor(TQColor( 160 , 32 , 240 ), i18n( "color", "Purple" ), false);
280 insertColor(TQColor( 105 , 105 , 105 ), i18n( "color", "DimGray" ), false);
281 insertColor(TQColor( 138 , 43 , 226 ), i18n( "color", "BlueViolet" ), false);
282 insertColor(TQColor( 160 , 82 , 45 ), i18n( "color", "Sienna" ), false);
283 insertColor(TQColor( 199 , 21 , 133 ), i18n( "color", "MediumVioletRed" ), false);
284 insertColor(TQColor( 176 , 48 , 96 ), i18n( "color", "Maroon" ), false);
285 insertColor(TQColor( 46 , 139 , 87 ), i18n( "color", "SeaGreen" ), false);
286 insertColor(TQColor( 85 , 107 , 47 ), i18n( "color", "DarkOliveGreen" ), false);
287 insertColor(TQColor( 34 , 139 , 34 ), i18n( "color", "ForestGreen" ), false);
288 insertColor(TQColor( 139 , 69 , 19 ), i18n( "color", "SaddleBrown" ), false);
289 insertColor(TQColor( 148 , 0 , 211 ), i18n( "color", "DarkViolet" ), false);
290 insertColor(TQColor( 178 , 34 , 34 ), i18n( "color", "FireBrick" ), false);
291 insertColor(TQColor( 72 , 61 , 139 ), i18n( "color", "DarkSlateBlue" ), false);
292 insertColor(TQColor( 47 , 79 , 79 ), i18n( "color", "DarkSlateGray" ), false);
293 insertColor(TQColor( 25 , 25 , 112 ), i18n( "color", "MidnightBlue" ), false);
294 insertColor(TQColor( 0 , 0 , 205 ), i18n( "color", "MediumBlue" ), false);
295 insertColor(TQColor( 0 , 0 , 128 ), i18n( "color", "Navy" ), false);
296
297 finalizeInsertion( m_nextPosition ); // with a no-op paint() call as we repaint anyway
298 updateGeometry();
299 // we have to repaint the "old" current row explicitly due
300 // to WStaticContents
301 update( 0, currentRow << 4, COLS << 4, 16 );
302}
303
304void KoColorPanel::mousePressEvent( TQMouseEvent* e )
305{
306 if ( e->button() == TQt::LeftButton )
307 m_pressedPos = e->pos();
308}
309
310void KoColorPanel::mouseReleaseEvent( TQMouseEvent* )
311{
312 if ( isVisible() && parentWidget() && parentWidget()->inherits( "TQPopupMenu" ) )
313 parentWidget()->close();
314 emit colorSelected( mapToColor( m_pressedPos ) );
315}
316
317void KoColorPanel::mouseMoveEvent( TQMouseEvent* e )
318{
319 if ( e->state() & TQt::LeftButton ) {
320 TQPoint p = m_pressedPos - e->pos();
321 if ( p.manhattanLength() > TQApplication::startDragDistance() ) {
322 TQColor color( mapToColor( m_pressedPos ) );
323 if ( color.isValid() ) {
324 KColorDrag *drag = new KColorDrag( color, this, name() );
325 drag->dragCopy();
326 }
327 }
328 }
329 else
330 updateFocusPosition( mapToPosition( e->pos() ) );
331}
332
333void KoColorPanel::paintEvent( TQPaintEvent* e )
334{
335 int lns = lines();
336 int startRow, endRow, startCol, endCol;
337 paintArea( e->rect(), startRow, endRow, startCol, endCol );
338
339 TQPainter p( this );
340
341 // First clear all the areas we won't paint on later (only if the widget isn't erased)
342 if ( !e->erased() ) {
343 // vertical rects
344 int tmp = TILESIZE * lns;
345 if ( startCol == 0 )
346 erase( 0, 0, 2, tmp );
347 if ( endCol == COLS )
348 erase( width() - 2, 0, 2, tmp );
349 else
350 erase( ( endCol << 4 ) - 2, 0, 2, tmp );
351 int i = startCol == 0 ? 1 : startCol;
352 for ( ; i < endCol; ++i )
353 erase( ( i << 4 ) - 2, 0, 4, tmp );
354
355 // horizontal rects
356 tmp = TILESIZE * COLS;
357 if ( startRow == 0 )
358 erase( 0, 0, tmp, 2 );
359 if ( endRow == lns )
360 erase( 0, height() - 2, tmp, 2 );
361 else
362 erase( 0, ( endRow << 4 ) - 2, tmp, 2 );
363 i = startRow == 0 ? 1 : startRow;
364 for ( ; i < endRow; ++i )
365 erase( 0, ( i << 4 ) - 2, tmp, 4 );
366 }
367
368 // The "active" element (if there is one)
369 if ( hasFocus() && m_focusPosition.x != -1 && m_focusPosition.y != -1 &&
370 mapFromPosition( m_focusPosition ).intersects( e->rect() ) )
371 style().drawPrimitive( TQStyle::PE_Panel, &p, TQRect( m_focusPosition.x << 4, m_focusPosition.y << 4, TILESIZE, TILESIZE ),
372 colorGroup(), TQStyle::Style_Sunken | TQStyle::Style_Enabled );
373
374 --lns; // Attention: We just avoid some lns - 1 statements
375
376 // ...all color tiles
377 if ( !m_colorMap.isEmpty() ) {
378 int currentRow = startRow, currentCol = startCol;
379 while ( currentRow < endRow && currentCol < endCol ) {
380 TQMap<Position, TQColor>::ConstIterator it = m_colorMap.find( Position( currentCol, currentRow ) );
381 if( it != m_colorMap.end() )
382 p.fillRect( ( currentCol << 4 ) + 2, ( currentRow << 4 ) + 2, 12, 12, it.data() );
383
384 // position of the next cell
385 ++currentCol;
386 if ( currentCol == endCol ) {
387 ++currentRow;
388 currentCol = startCol;
389 }
390 }
391 }
392
393 // clean up the last line (it's most likely that it's not totally filled)
394 if ( !e->erased() && endRow > lns ) {
395 int fields = m_colorMap.count() % COLS;
396 erase( fields << 4, lns * TILESIZE, ( COLS - fields ) << 4, 16 );
397 }
398}
399
400void KoColorPanel::keyPressEvent( TQKeyEvent* e )
401{
402 Position newPos( validPosition( m_focusPosition ) );
403 if ( e->key() == TQt::Key_Up ) {
404 if ( newPos.y == 0 )
405 e->ignore();
406 else
407 --newPos.y;
408 }
409 else if ( e->key() == TQt::Key_Down ) {
410 if ( newPos < Position( m_colorMap.count() % COLS, lines() - 2 ) )
411 ++newPos.y;
412 else
413 e->ignore();
414 }
415 else if ( e->key() == TQt::Key_Left ) {
416 if ( newPos.x == 0 )
417 e->ignore();
418 else
419 --newPos.x;
420 }
421 else if ( e->key() == TQt::Key_Right ) {
422 if ( newPos.x < COLS - 1 && newPos < Position( m_colorMap.count() % COLS - 1, lines() - 1 ) )
423 ++newPos.x;
424 else
425 e->ignore();
426 }
427 else if ( e->key() == TQt::Key_Return ) {
428 if ( isVisible() && parentWidget() && parentWidget()->inherits( "TQPopupMenu" ) )
429 parentWidget()->close();
430 emit colorSelected( mapToColor( m_focusPosition ) );
431 }
432 updateFocusPosition( newPos );
433}
434
435void KoColorPanel::focusInEvent( TQFocusEvent* e )
436{
437 if ( !m_colorMap.isEmpty() && m_focusPosition.x == -1 && m_focusPosition.y == -1 ) {
438 m_focusPosition.x = 0;
439 m_focusPosition.y = 0;
440 }
441 TQWidget::focusInEvent( e );
442}
443
444void KoColorPanel::dragEnterEvent( TQDragEnterEvent* e )
445{
446 e->accept( KColorDrag::canDecode( e ) );
447}
448
449void KoColorPanel::dropEvent( TQDropEvent* e )
450{
451 TQColor color;
452 if ( KColorDrag::decode( e, color ) )
453 insertColor( color );
454}
455
456void KoColorPanel::finalizeInsertion( const Position& pos )
457{
458 paint( pos );
459
460 if ( !isFocusEnabled() )
461 setFocusPolicy( TQWidget::StrongFocus );
462 // Did we start a new row?
463 if ( m_nextPosition.x == 1 )
464 updateGeometry();
465}
466
467bool KoColorPanel::insertColor( const TQColor& color, bool checking )
468{
469 if ( checking && isAvailable( color ) )
470 return false;
471
472 m_colorMap.insert( m_nextPosition, color );
473
474 ++m_nextPosition.x;
475 if ( m_nextPosition.x == COLS ) {
476 m_nextPosition.x = 0;
477 ++m_nextPosition.y;
478 }
479 return true;
480}
481
482bool KoColorPanel::insertColor( const TQColor& color, const TQString& toolTip, bool checking )
483{
484 if ( checking && isAvailable( color ) )
485 return false;
486
487 // Remember the "old" m_nextPosition -- this is the place where the newly
488 // inserted color will be located
489 TQRect rect( mapFromPosition( m_nextPosition ) );
490 insertColor( color, false ); // check only once ;)
491 TQToolTip::add( this, rect, toolTip );
492 return true;
493}
494
495bool KoColorPanel::isAvailable( const TQColor& color )
496{
497 // O(n) checking on insert, but this is better than O(n) checking
498 // on every mouse move...
499 TQMap<Position, TQColor>::ConstIterator it = m_colorMap.begin();
500 TQMap<Position, TQColor>::ConstIterator end = m_colorMap.end();
501 for ( ; it != end; ++it )
502 if ( it.data() == color )
503 return true;
504 return false;
505}
506
507KoColorPanel::Position KoColorPanel::mapToPosition( const TQPoint& point ) const
508{
509 return Position( point.x() >> 4, point.y() >> 4 );
510}
511
512TQColor KoColorPanel::mapToColor( const TQPoint& point ) const
513{
514 return mapToColor( mapToPosition( point ) );
515}
516
517TQColor KoColorPanel::mapToColor( const KoColorPanel::Position& position ) const
518{
519 TQMap<Position, TQColor>::ConstIterator it = m_colorMap.find( position );
520 if ( it != m_colorMap.end() )
521 return it.data();
522 return TQColor();
523}
524
525TQRect KoColorPanel::mapFromPosition( const KoColorPanel::Position& position ) const
526{
527 return TQRect( position.x << 4, position.y << 4, TILESIZE, TILESIZE );
528}
529
530KoColorPanel::Position KoColorPanel::validPosition( const Position& position )
531{
532 Position pos( position );
533 int lns = lines() - 1;
534 int lastLineLen = m_colorMap.count() % COLS - 1;
535
536 // ensure the position is within the valid grid area
537 // note: special handling of the last line
538 if ( pos.x < 0 )
539 pos.x = 0;
540 else if ( pos.y == lns && pos.x > lastLineLen )
541 pos.x = lastLineLen;
542 else if ( pos.x >= COLS )
543 pos.x = COLS - 1;
544
545 if ( pos.y < 0 )
546 pos.y = 0;
547 else if ( pos.x > lastLineLen && pos.y > lns - 1 )
548 pos.y = lns - 1;
549 else if ( pos.y > lns )
550 pos.y = lns;
551 return pos;
552}
553
554int KoColorPanel::lines() const
555{
556 if ( m_colorMap.isEmpty() )
557 return 1;
558 return ( m_colorMap.count() - 1 ) / COLS + 1;
559}
560
561void KoColorPanel::paintArea( const TQRect& rect, int& startRow, int& endRow, int& startCol, int& endCol ) const
562{
563 startRow = rect.top() >> 4;
564 endRow = ( rect.bottom() >> 4 ) + 1;
565 startCol = rect.left() >> 4;
566 endCol = ( rect.right() >> 4 ) + 1;
567}
568
569void KoColorPanel::updateFocusPosition( const Position& newPosition )
570{
571 TQPainter p( this );
572
573 // restore the old tile where we had the focus before
574 if ( m_focusPosition.x != -1 && m_focusPosition.y != -1 )
575 paint( m_focusPosition );
576
577 m_focusPosition = newPosition;
578
579 TQMap<Position, TQColor>::ConstIterator it = m_colorMap.find( m_focusPosition );
580 if ( it != m_colorMap.end() ) {
581 // draw at the new focus position
582 style().drawPrimitive( TQStyle::PE_Panel, &p, TQRect( m_focusPosition.x << 4, m_focusPosition.y << 4, TILESIZE, TILESIZE ),
583 colorGroup(), TQStyle::Style_Sunken | TQStyle::Style_Enabled );
584 p.fillRect( ( m_focusPosition.x << 4 ) + 2, ( m_focusPosition.y << 4 ) + 2, 12, 12, it.data() );
585 }
586
587}
588
589void KoColorPanel::paint( const Position& position )
590{
591 TQMap<Position, TQColor>::ConstIterator it = m_colorMap.find( position );
592 if ( it == m_colorMap.end() )
593 return;
594
595 erase( mapFromPosition( position ) );
596 TQPainter p( this );
597 p.fillRect( ( position.x << 4 ) + 2, ( position.y << 4 ) + 2, 12, 12, it.data() );
598}
599
600void KoColorPanel::init()
601{
602 setFocusPolicy( TQWidget::NoFocus ); // it's empty
603 m_nextPosition.x = 0;
604 m_nextPosition.y = 0;
605 m_focusPosition.x = -1;
606 m_focusPosition.y = -1;
607 m_defaultsAdded = false;
608}
609
610bool operator<( const KoColorPanel::Position& lhs, const KoColorPanel::Position& rhs )
611{
612 return ( lhs.y * COLS + lhs.x ) < ( rhs.y * COLS + rhs.x );
613}
614
615
616KoColorPopupProxy::KoColorPopupProxy( const TQColor& defaultColor, KoColorPanel* recentColors, TQObject* parent, const char* name ) :
617 TQObject( parent, name ), m_defaultColor( defaultColor ), m_recentColors( recentColors )
618{
619}
620
621void KoColorPopupProxy::setRecentColorPanel( KoColorPanel* recentColors )
622{
623 m_recentColors = recentColors;
624}
625
626void KoColorPopupProxy::slotDefaultColor()
627{
628 emit colorSelected( m_defaultColor );
629}
630
631void KoColorPopupProxy::slotMoreColors()
632{
633 if ( !m_recentColors )
634 return;
635
636 TQColor newColor;
637 TQWidget* p = 0;
638 if ( parent() && parent()->isWidgetType() )
639 p = static_cast<TQWidget*>( parent() );
640
641 if ( KColorDialog::getColor( newColor, p ) == TQDialog::Accepted ) {
642 m_recentColors->insertColor( newColor );
643 emit colorSelected( newColor );
644 }
645}
646
647
648KoToolButton::KoToolButton( const TQString& icon, int id, TQWidget* parent,
649 const char* name, const TQString& txt, TDEInstance* _instance ) :
650 TDEToolBarButton( icon, id, parent, name, txt, _instance ), m_arrowPressed( false )
651{
652 init();
653}
654
655KoToolButton::KoToolButton( const TQPixmap& pixmap, int id, TQWidget* parent,
656 const char* name, const TQString& txt ) :
657 TDEToolBarButton( pixmap, id, parent, name, txt ), m_arrowPressed( false )
658{
659 init();
660}
661
662KoToolButton::~KoToolButton()
663{
664}
665
666TQSize KoToolButton::sizeHint() const
667{
668 return minimumSizeHint();
669}
670
671TQSize KoToolButton::minimumSizeHint() const
672{
673 TQSize size = TDEToolBarButton::minimumSizeHint();
674 size.setWidth( size.width() + ARROW_WIDTH );
675 return size;
676}
677
678TQSize KoToolButton::minimumSize() const
679{
680 return minimumSizeHint();
681}
682
683void KoToolButton::colorSelected( const TQColor& color )
684{
685 kdDebug() << "selected::: " << TQString(color.name()) << endl;
686}
687
688void KoToolButton::drawButton(TQPainter *_painter)
689{
690 TQStyle::SFlags flags = TQStyle::Style_Default;
691 TQStyle::SCFlags active = TQStyle::SC_None;
692 TQStyle::SCFlags arrowActive = TQStyle::SC_None;
693 TQStyleOption opt;
694 TQColorGroup cg( colorGroup() );
695
696 if ( isEnabled() ) {
697 flags |= TQStyle::Style_Enabled;
698 if ( TDEToolBarButton::isRaised() || m_arrowPressed )
699 flags |= TQStyle::Style_Raised;
700 }
701 if ( isOn() )
702 flags |= TQStyle::Style_On;
703
704 TQStyle::SFlags arrowFlags = flags;
705
706 if ( isDown() && !m_arrowPressed ) {
707 flags |= TQStyle::Style_Down;
708 active |= TQStyle::SC_ToolButton;
709 }
710 if ( m_arrowPressed )
711 arrowActive |= TQStyle::SC_ToolButton;
712
713 // Draw styled toolbuttons
714 _painter->setClipRect( 0, 0, width() - ARROW_WIDTH, height() );
715 style().drawComplexControl( TQStyle::CC_ToolButton, _painter, this, TQRect( 0, 0, width() - ARROW_WIDTH, height() ), cg,
716 flags, TQStyle::SC_ToolButton, active, opt );
717 _painter->setClipRect( width() - ARROW_WIDTH, 0, ARROW_WIDTH, height() );
718 style().drawComplexControl( TQStyle::CC_ToolButton, _painter, this, TQRect( width(), 0, ARROW_WIDTH, height() ), cg,
719 arrowFlags, TQStyle::SC_ToolButton, arrowActive, opt );
720 _painter->setClipping( false );
721
722 // ...and the arrow indicating the popup
723 style().drawPrimitive( TQStyle::PE_ArrowDown, _painter, TQRect( width() - ARROW_WIDTH - 1, 0, ARROW_WIDTH, height() ),
724 cg, flags, opt );
725
726 if ( TDEToolBarButton::isRaised() || m_arrowPressed )
727 qDrawShadeLine( _painter, width() - ARROW_WIDTH - 1, 0, width() - ARROW_WIDTH - 1, height() - 1, colorGroup(), true );
728
729 int dx, dy;
730 TQFont tmp_font( TDEGlobalSettings::toolBarFont() );
731 TQFontMetrics fm( tmp_font );
732 TQRect textRect;
733 int textFlags = 0;
734
735 if ( static_cast<TDEToolBar::IconText>( iconTextMode() ) == TDEToolBar::IconOnly ) { // icon only
736 TQPixmap pixmap = iconSet().pixmap( TQIconSet::Automatic,
737 isEnabled() ? ( TDEToolBarButton::isActive() ? TQIconSet::Active : TQIconSet::Normal ) :
738 TQIconSet::Disabled, isOn() ? TQIconSet::On : TQIconSet::Off );
739 if ( !pixmap.isNull() ) {
740 dx = ( width() - ARROW_WIDTH - pixmap.width() ) / 2;
741 dy = ( height() - pixmap.height() ) / 2;
742 buttonShift( dx, dy );
743 _painter->drawPixmap( dx, dy, pixmap );
744 }
745 }
746 else if ( static_cast<TDEToolBar::IconText>( iconTextMode() ) == TDEToolBar::IconTextRight ) { // icon and text (if any)
747 TQPixmap pixmap = iconSet().pixmap( TQIconSet::Automatic,
748 isEnabled() ? ( TDEToolBarButton::isActive() ? TQIconSet::Active : TQIconSet::Normal ) :
749 TQIconSet::Disabled, isOn() ? TQIconSet::On : TQIconSet::Off );
750 if( !pixmap.isNull()) {
751 dx = 4;
752 dy = ( height() - pixmap.height() ) / 2;
753 buttonShift( dx, dy );
754 _painter->drawPixmap( dx, dy, pixmap );
755 }
756
757 if (!textLabel().isNull()) {
758 textFlags = AlignVCenter | AlignLeft;
759 if ( !pixmap.isNull() )
760 dx = 4 + pixmap.width() + 2;
761 else
762 dx = 4;
763 dy = 0;
764 buttonShift( dx, dy );
765 textRect = TQRect( dx, dy, width() - dx, height() );
766 }
767 }
768 else if ( static_cast<TDEToolBar::IconText>( iconTextMode() ) == TDEToolBar::TextOnly ) {
769 if ( !textLabel().isNull() ) {
770 textFlags = AlignTop | AlignLeft;
771 dx = ( width() - ARROW_WIDTH - fm.width( textLabel() ) ) / 2;
772 dy = ( height() - fm.lineSpacing() ) / 2;
773 buttonShift( dx, dy );
774 textRect = TQRect( dx, dy, fm.width(textLabel()), fm.lineSpacing() );
775 }
776 }
777 else if ( static_cast<TDEToolBar::IconText>( iconTextMode() ) == TDEToolBar::IconTextBottom ) {
778 TQPixmap pixmap = iconSet().pixmap( TQIconSet::Automatic,
779 isEnabled() ? ( TDEToolBarButton::isActive() ? TQIconSet::Active : TQIconSet::Normal ) :
780 TQIconSet::Disabled, isOn() ? TQIconSet::On : TQIconSet::Off );
781 if( !pixmap.isNull()) {
782 dx = ( width() - ARROW_WIDTH - pixmap.width() ) / 2;
783 dy = ( height() - fm.lineSpacing() - pixmap.height() ) / 2;
784 buttonShift( dx, dy );
785 _painter->drawPixmap( dx, dy, pixmap );
786 }
787
788 if ( !textLabel().isNull() ) {
789 textFlags = AlignBottom | AlignHCenter;
790 dx = ( width() - ARROW_WIDTH - fm.width( textLabel() ) ) / 2;
791 dy = height() - fm.lineSpacing() - 4;
792 buttonShift( dx, dy );
793 textRect = TQRect( dx, dy, fm.width( textLabel() ), fm.lineSpacing() );
794 }
795 }
796
797 // Draw the text at the position given by textRect, and using textFlags
798 if (!textLabel().isNull() && !textRect.isNull()) {
799 _painter->setFont( TDEGlobalSettings::toolBarFont() );
800 if ( !isEnabled() )
801 _painter->setPen( palette().disabled().dark() );
802 else if( TDEToolBarButton::isRaised() )
803 _painter->setPen( TDEGlobalSettings::toolBarHighlightColor() );
804 else
805 _painter->setPen( colorGroup().buttonText() );
806 _painter->drawText( textRect, textFlags, textLabel() );
807 }
808}
809
810bool KoToolButton::eventFilter( TQObject* o, TQEvent* e )
811{
812 if ( o == m_popup ) {
813 if ( e->type() == TQEvent::MouseButtonPress )
814 if ( hitArrow( mapFromGlobal( static_cast<TQMouseEvent*>( e )->globalPos() ) ) ) {
815 kdDebug() << "KoToolButton::eventFilter-------------->" << endl;
816 m_popup->close();
817 m_arrowPressed = false;
818 return true;
819 }
820 return false;
821 }
822
823 if ( e->type() == TQEvent::MouseButtonPress ) {
824 m_arrowPressed = hitArrow( static_cast<TQMouseEvent*>( e )->pos() );
825 if ( m_arrowPressed )
826 m_popup->popup( mapToGlobal( TQPoint( 0, height() ) ) );
827 }
828 else if ( e->type() == TQEvent::MouseButtonRelease )
829 m_arrowPressed = false;
830 return TDEToolBarButton::eventFilter( o, e );
831}
832
833void KoToolButton::init()
834{
835 m_popup = KoColorPanel::createColorPopup( KoColorPanel::CustomColors, TQt::yellow, this,
836 TQ_SLOT( colorSelected( const TQColor& ) ),
837 this, "no-name" );
838 // We are interested in the mouse clicks on the arrow button
839 m_popup->installEventFilter( this );
840
841 ARROW_WIDTH = style().pixelMetric(TQStyle::PM_MenuButtonIndicator) + 4;
842 kdDebug() << "##################### Arrow: " << ARROW_WIDTH << endl;
843}
844
845void KoToolButton::buttonShift( int& dx, int& dy )
846{
847 if ( isDown() && !m_arrowPressed ) {
848 dx += style().pixelMetric( TQStyle::PM_ButtonShiftHorizontal );
849 dy += style().pixelMetric( TQStyle::PM_ButtonShiftVertical );
850 }
851}
852
853bool KoToolButton::hitArrow( const TQPoint& pos )
854{
855 return TQRect( width() - ARROW_WIDTH, 0, ARROW_WIDTH, height() ).contains( pos );
856}
857
858#include <KoTooluButton.moc>
static int getColor(TQColor &theColor, TQWidget *parent=0L)
static bool decode(TQMimeSource *e, TQColor &col)
static bool canDecode(TQMimeSource *e)
bool isActive() const
bool isRaised() const
const char * name(StdAction id)