summaryrefslogtreecommitdiff
path: root/noncore/styles/theme/othemebase.cpp
Unidiff
Diffstat (limited to 'noncore/styles/theme/othemebase.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/styles/theme/othemebase.cpp1212
1 files changed, 1212 insertions, 0 deletions
diff --git a/noncore/styles/theme/othemebase.cpp b/noncore/styles/theme/othemebase.cpp
new file mode 100644
index 0000000..00cea03
--- a/dev/null
+++ b/noncore/styles/theme/othemebase.cpp
@@ -0,0 +1,1212 @@
1/* This file is part of the KDE libraries
2 Copyright (C) 1999 Daniel M. Duley <mosfet@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 version 2 as published by the Free Software Foundation.
7
8 This library is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 Library General Public License for more details.
12
13 You should have received a copy of the GNU Library General Public License
14 along with this library; see the file COPYING.LIB. If not, write to
15 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16 Boston, MA 02111-1307, USA.
17*/
18#include "othemebase.h"
19#include "ogfxeffect.h"
20#include <qpe/qpeapplication.h>
21//#include <kdebug.h>
22//#include <klocale.h>
23#include <qpe/config.h>
24//#include <kglobal.h>
25//#include <kglobalsettings.h>
26//#include <kstddirs.h>
27#include <qfile.h>
28#include <qtextstream.h>
29#include <qdir.h>
30#include <qpainter.h>
31#include <qbitmap.h>
32#include <stdlib.h>
33#include <qstringlist.h>
34
35#include <stdio.h>
36
37template class QIntCache<OThemePixmap>
38;
39
40static const char *widgetEntries[] =
41 { // unsunken widgets (see header)
42 "PushButton", "ComboBox", "HSBarSlider", "VSBarSlider", "Bevel", "ToolButton",
43 "ScrollButton", "HScrollDeco", "VScrollDeco", "ComboDeco", "MenuItem", "Tab",
44 "ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight",
45 // sunken widgets
46 "PushButtonDown", "ComboBoxDown", "HSBarSliderDown", "VSBarSliderDown",
47 "BevelDown", "ToolButtonDown", "ScrollButtonDown", "HScrollDecoDown",
48 "VScrollDecoDown", "ComboDecoDown", "MenuItemDown", "TabDown", "SunkenArrowUp",
49 "SunkenArrowDown", "SunkenArrowLeft", "SunkenArrowRight",
50 // everything else
51 "HScrollGroove", "VScrollGroove", "Slider", "SliderGroove", "CheckBoxDown",
52 "CheckBox", "RadioDown", "Radio", "HBarHandle", "VBarHandle",
53 "ToolBar", "Splitter", "CheckMark", "MenuBar", "DisableArrowUp",
54 "DisableArrowDown", "DisableArrowLeft", "DisableArrowRight", "ProgressBar",
55 "ProgressBackground", "MenuBarItem", "Background"
56 };
57
58#define INHERIT_ITEMS 16
59
60
61// This is used to encode the keys. I used to use masks but I think this
62// bitfield is nicer :) I don't know why C++ coders don't use these more..
63// (mosfet)
64struct kthemeKeyData
65{
66unsigned int id :
67 6;
68unsigned int width :
69 12;
70unsigned int height :
71 12;
72unsigned int border :
73 1;
74unsigned int mask :
75 1;
76};
77
78union kthemeKey{
79 kthemeKeyData data;
80 unsigned int cacheKey;
81};
82
83class MyConfig : public Config
84{
85public:
86 MyConfig ( const QString &f, Domain d ) : Config ( f, d )
87 { }
88
89 bool hasGroup ( const QString &gname ) const
90 {
91 QMap< QString, ConfigGroup>::ConstIterator it = groups. find ( gname );
92 return ( it != groups.end() );
93 }
94};
95
96void OThemeBase::generateBorderPix( int i )
97{
98 // separate pixmap into separate components
99 if ( pbPixmaps[ i ] ) {
100 // evidently I have to do masks manually...
101 const QBitmap * srcMask = pbPixmaps[ i ] ->mask();
102 QBitmap destMask( pbWidth[ i ], pbWidth[ i ] );
103 QPixmap tmp( pbWidth[ i ], pbWidth[ i ] );
104
105 bitBlt( &tmp, 0, 0, pbPixmaps[ i ], 0, 0, pbWidth[ i ], pbWidth[ i ],
106 Qt::CopyROP, false );
107 if ( srcMask ) {
108 bitBlt( &destMask, 0, 0, srcMask, 0, 0, pbWidth[ i ], pbWidth[ i ],
109 Qt::CopyROP, false );
110 tmp.setMask( destMask );
111 }
112 pbPixmaps[ i ] ->setBorder( OThemePixmap::TopLeft, tmp );
113
114 bitBlt( &tmp, 0, 0, pbPixmaps[ i ], pbPixmaps[ i ] ->width() - pbWidth[ i ], 0,
115 pbWidth[ i ], pbWidth[ i ], Qt::CopyROP, false );
116 if ( srcMask ) {
117 bitBlt( &destMask, 0, 0, srcMask, pbPixmaps[ i ] ->width() - pbWidth[ i ],
118 0, pbWidth[ i ], pbWidth[ i ], Qt::CopyROP, false );
119 tmp.setMask( destMask );
120 }
121 pbPixmaps[ i ] ->setBorder( OThemePixmap::TopRight, tmp );
122
123 bitBlt( &tmp, 0, 0, pbPixmaps[ i ], 0, pbPixmaps[ i ] ->height() - pbWidth[ i ],
124 pbWidth[ i ], pbWidth[ i ], Qt::CopyROP, false );
125 if ( srcMask ) {
126 bitBlt( &destMask, 0, 0, srcMask, 0, pbPixmaps[ i ] ->height() - pbWidth[ i ],
127 pbWidth[ i ], pbWidth[ i ], Qt::CopyROP, false );
128 tmp.setMask( destMask );
129 }
130 pbPixmaps[ i ] ->setBorder( OThemePixmap::BottomLeft, tmp );
131
132 bitBlt( &tmp, 0, 0, pbPixmaps[ i ], pbPixmaps[ i ] ->width() - pbWidth[ i ],
133 pbPixmaps[ i ] ->height() - pbWidth[ i ], pbWidth[ i ], pbWidth[ i ],
134 Qt::CopyROP, false );
135 if ( srcMask ) {
136 bitBlt( &destMask, 0, 0, srcMask, pbPixmaps[ i ] ->width() - pbWidth[ i ],
137 pbPixmaps[ i ] ->height() - pbWidth[ i ], pbWidth[ i ], pbWidth[ i ],
138 Qt::CopyROP, false );
139 tmp.setMask( destMask );
140 }
141 pbPixmaps[ i ] ->setBorder( OThemePixmap::BottomRight, tmp );
142
143 tmp.resize( pbPixmaps[ i ] ->width() - pbWidth[ i ] * 2, pbWidth[ i ] );
144 destMask.resize( pbPixmaps[ i ] ->width() - pbWidth[ i ] * 2, pbWidth[ i ] );
145 bitBlt( &tmp, 0, 0, pbPixmaps[ i ], pbWidth[ i ], 0,
146 pbPixmaps[ i ] ->width() - pbWidth[ i ] * 2, pbWidth[ i ], Qt::CopyROP, false );
147 if ( srcMask ) {
148 bitBlt( &destMask, 0, 0, srcMask, pbWidth[ i ], 0,
149 pbPixmaps[ i ] ->width() - pbWidth[ i ] * 2, pbWidth[ i ],
150 Qt::CopyROP, false );
151 tmp.setMask( destMask );
152 }
153 pbPixmaps[ i ] ->setBorder( OThemePixmap::Top, tmp );
154
155 bitBlt( &tmp, 0, 0, pbPixmaps[ i ], pbWidth[ i ],
156 pbPixmaps[ i ] ->height() - pbWidth[ i ],
157 pbPixmaps[ i ] ->width() - pbWidth[ i ] * 2, pbWidth[ i ], Qt::CopyROP, false );
158 if ( srcMask ) {
159 bitBlt( &destMask, 0, 0, srcMask, pbWidth[ i ],
160 pbPixmaps[ i ] ->height() - pbWidth[ i ],
161 pbPixmaps[ i ] ->width() - pbWidth[ i ] * 2, pbWidth[ i ], Qt::CopyROP, false );
162 tmp.setMask( destMask );
163 }
164 pbPixmaps[ i ] ->setBorder( OThemePixmap::Bottom, tmp );
165
166 tmp.resize( pbWidth[ i ], pbPixmaps[ i ] ->height() - pbWidth[ i ] * 2 );
167 destMask.resize( pbWidth[ i ], pbPixmaps[ i ] ->height() - pbWidth[ i ] * 2 );
168 bitBlt( &tmp, 0, 0, pbPixmaps[ i ], 0, pbWidth[ i ], pbWidth[ i ],
169 pbPixmaps[ i ] ->height() - pbWidth[ i ] * 2, Qt::CopyROP, false );
170 if ( srcMask ) {
171 bitBlt( &destMask, 0, 0, srcMask, 0, pbWidth[ i ], pbWidth[ i ],
172 pbPixmaps[ i ] ->height() - pbWidth[ i ] * 2, Qt::CopyROP, false );
173 tmp.setMask( destMask );
174 }
175
176 pbPixmaps[ i ] ->setBorder( OThemePixmap::Left, tmp );
177
178 bitBlt( &tmp, 0, 0, pbPixmaps[ i ], pbPixmaps[ i ] ->width() - pbWidth[ i ],
179 pbWidth[ i ], pbWidth[ i ], pbPixmaps[ i ] ->height() - pbWidth[ i ] * 2,
180 Qt::CopyROP, false );
181 if ( srcMask ) {
182 bitBlt( &destMask, 0, 0, srcMask, pbPixmaps[ i ] ->width() - pbWidth[ i ],
183 pbWidth[ i ], pbWidth[ i ], pbPixmaps[ i ] ->height() - pbWidth[ i ] * 2,
184 Qt::CopyROP, false );
185 tmp.setMask( destMask );
186 }
187 pbPixmaps[ i ] ->setBorder( OThemePixmap::Right, tmp );
188 }
189 else
190 qDebug ( "OThemeBase: Tried making border from empty pixmap" );
191}
192
193
194void OThemeBase::copyWidgetConfig( int sourceID, int destID, QString *pixnames,
195 QString *brdnames )
196{
197 scaleHints[ destID ] = scaleHints[ sourceID ];
198 gradients[ destID ] = gradients[ sourceID ];
199 blends[ destID ] = blends[ sourceID ];
200 bContrasts[ destID ] = bContrasts[ sourceID ];
201 borders[ destID ] = borders[ sourceID ];
202 highlights[ destID ] = highlights[ sourceID ];
203
204 if ( grLowColors[ sourceID ] )
205 grLowColors[ destID ] = new QColor( *grLowColors[ sourceID ] );
206 else
207 grLowColors[ destID ] = NULL;
208
209 if ( grHighColors[ sourceID ] )
210 grHighColors[ destID ] = new QColor( *grHighColors[ sourceID ] );
211 else
212 grHighColors[ destID ] = NULL;
213
214 if ( colors[ sourceID ] )
215 colors[ destID ] = new QColorGroup( *colors[ sourceID ] );
216 else
217 colors[ destID ] = NULL;
218
219 // pixmap
220 pixnames[ destID ] = pixnames[ sourceID ];
221 duplicate[ destID ] = false;
222 pixmaps[ destID ] = NULL;
223 images[ destID ] = NULL;
224 if ( !pixnames[ destID ].isEmpty() ) {
225 if ( scaleHints[ sourceID ] == TileScale && blends[ sourceID ] == 0.0 ) {
226 pixmaps[ destID ] = pixmaps[ sourceID ];
227 duplicate[ destID ] = true;
228 }
229 if ( !duplicate[ destID ] ) {
230 pixmaps[ destID ] = loadPixmap( pixnames[ destID ] );
231 if ( scaleHints[ destID ] == TileScale && blends[ destID ] == 0.0 )
232 images[ destID ] = NULL;
233 else
234 images[ destID ] = loadImage( pixnames[ destID ] );
235 }
236 }
237
238 // border pixmap
239 pbDuplicate[ destID ] = false;
240 pbPixmaps[ destID ] = NULL;
241 pbWidth[ destID ] = pbWidth[ sourceID ];
242 brdnames[ destID ] = brdnames[ sourceID ];
243 if ( !brdnames[ destID ].isEmpty() ) {
244 pbPixmaps[ destID ] = pbPixmaps[ sourceID ];
245 pbDuplicate[ destID ] = true;
246 }
247
248 if ( sourceID == ActiveTab && destID == InactiveTab )
249 aTabLine = iTabLine;
250 else if ( sourceID == InactiveTab && destID == ActiveTab )
251 iTabLine = aTabLine;
252}
253
254void OThemeBase::readConfig( Qt::GUIStyle /*style*/ )
255{
256#define PREBLEND_ITEMS 12
257 static WidgetType preBlend[] = {Slider, IndicatorOn, IndicatorOff,
258 ExIndicatorOn, ExIndicatorOff, HScrollDeco, VScrollDeco, HScrollDecoDown,
259 VScrollDecoDown, ComboDeco, ComboDecoDown, CheckMark};
260
261 int i;
262 QString tmpStr;
263 QString copyfrom[ WIDGETS ];
264 QString pixnames[ WIDGETS ]; // used for duplicate check
265 QString brdnames[ WIDGETS ];
266 bool loaded[ WIDGETS ]; // used for preloading for CopyWidget
267
268 if ( configFileName.isEmpty() ) {
269 Config cfg ( "qpe" );
270 cfg. setGroup ( "Appearance" );
271
272 configFileName = cfg. readEntry ( "Theme", "default" );
273 }
274 MyConfig config( configFilePath + "/themes/" + configFileName + ".themerc" , Config::File );
275
276 printf ( "Opened config file: %s\n", ( configFilePath + "/themes/" + configFileName + ".themerc" ). ascii());
277
278 // Are we initalized?
279 for ( i = 0; i < INHERIT_ITEMS; ++i ) {
280 applyResourceGroup( &config, i, copyfrom, pixnames, brdnames );
281 printf ( "%d [%s]: copy=%s, pix=%s, brd=%s\n", i, widgetEntries [i], copyfrom [i].latin1(), pixnames[i].latin1(),brdnames[i].latin1() );
282 }
283 for ( ; i < INHERIT_ITEMS*2; ++i ) {
284 if ( config.hasGroup( QString( widgetEntries[ i ] ) ) ) {
285 applyResourceGroup( &config, i, copyfrom, pixnames, brdnames );
286 printf ( "%d [%s]: copy=%s, pix=%s, brd=%s\n", i, widgetEntries [i], copyfrom [i].latin1(), pixnames[i].latin1(),brdnames[i].latin1() );
287 }
288 else {
289 copyfrom [ i ] = widgetEntries[ i - INHERIT_ITEMS ];
290 printf ( "%d [%s]: copy=%s\n", i, widgetEntries [i], copyfrom [i].latin1());
291 }
292 }
293 for ( ; i < WIDGETS; ++i ) {
294 applyResourceGroup( &config, i, copyfrom, pixnames, brdnames );
295 printf ( "%d [%s]: copy=%s, pix=%s, brd=%s\n", i, widgetEntries [i], copyfrom [i].latin1(), pixnames[i].latin1(),brdnames[i].latin1() );
296 }
297 applyMiscResourceGroup( &config );
298
299 // initalize defaults that may not be read
300 for ( i = 0; i < WIDGETS; ++i )
301 loaded[ i ] = false;
302 btnXShift = btnYShift = focus3DOffset = 0;
303 aTabLine = iTabLine = true;
304 roundedButton = roundedCombo = roundedSlider = focus3D = false;
305 splitterWidth = 10;
306
307 for ( i = 0; i < WIDGETS; ++i ) {
308 readResourceGroup( i, copyfrom, pixnames, brdnames, loaded );
309 printf ( "%d [%s]: copy=%s, pix=%s, brd=%s, colors=%s\n", i, widgetEntries [i], copyfrom [i].latin1(), pixnames[i].latin1(),brdnames[i].latin1(), (colors[i]?colors[i]->background().name().latin1():"<none)" ));
310 }
311
312 // misc items
313 readMiscResourceGroup();
314
315 // Handle preblend items
316 for ( i = 0; i < PREBLEND_ITEMS; ++i ) {
317 if ( pixmaps[ preBlend[ i ] ] != NULL && blends[ preBlend[ i ] ] != 0.0 )
318 blend( preBlend[ i ] );
319 }
320}
321
322OThemeBase::OThemeBase( const QString & configFile )
323 : QWindowsStyle()
324{
325 configFilePath = QPEApplication::qpeDir ( ) + "/plugins/styles/";
326 configFileName = configFile;
327
328 readConfig( Qt::WindowsStyle );
329 cache = new OThemeCache( cacheSize );
330}
331
332void OThemeBase::applyConfigFile( const QString &/*file*/ )
333{
334#if 0
335 // handle std color scheme
336 Config inConfig( file, Config::File );
337 Config globalConfig ( "qpe" );
338
339 globalConfig. setGroup ( "Apperance" );
340 inConfig. setGroup( "General" );
341
342 if ( inConfig.hasKey( "foreground" ) )
343 globalConfig.writeEntry( "Text", inConfig.readEntry( "foreground", " " ) );
344 if ( inConfig.hasKey( "background" ) )
345 globalConfig.writeEntry( "Background", inConfig.readEntry( "background", " " ) );
346 if ( inConfig.hasKey( "selectForeground" ) )
347 globalConfig.writeEntry( "HighlightedText", inConfig.readEntry( "selectForeground", " " ) );
348 if ( inConfig.hasKey( "selectBackground" ) )
349 globalConfig.writeEntry( "Highlight", inConfig.readEntry( "selectBackground", " " ) );
350 if ( inConfig.hasKey( "windowForeground" ) )
351 globalConfig.writeEntry( "Text", inConfig.readEntry( "windowForeground", " " ) );
352 if ( inConfig.hasKey( "windowBackground" ) )
353 globalConfig.writeEntry( "Base", inConfig.readEntry( "windowBackground", " " ) );
354
355 // Keep track of the current theme so that we can select the right one
356 // in the KControl module.
357 globalConfig.writeEntry ( "CurrentTheme", file );
358
359 globalConfig.write();
360#endif
361}
362
363OThemeBase::~OThemeBase()
364{
365 int i;
366 for ( i = 0; i < WIDGETS; ++i ) {
367 if ( !duplicate[ i ] ) {
368 if ( images[ i ] )
369 delete images[ i ];
370 if ( pixmaps[ i ] )
371 delete pixmaps[ i ];
372 }
373 if ( !pbDuplicate[ i ] && pbPixmaps[ i ] )
374 delete pbPixmaps[ i ];
375 if ( colors[ i ] )
376 delete( colors[ i ] );
377 if ( grLowColors[ i ] )
378 delete( grLowColors[ i ] );
379 if ( grHighColors[ i ] )
380 delete( grHighColors[ i ] );
381 }
382 delete cache;
383}
384
385QImage* OThemeBase::loadImage( QString &name )
386{
387 QImage * image = new QImage;
388 QString path = configFilePath + "/pixmaps/" + name;
389 image->load( path );
390 if ( !image->isNull() )
391 return ( image );
392 qDebug ( "OThemeBase: Unable to load image %s\n", name.ascii ( ) );
393 delete image;
394 return ( NULL );
395}
396
397OThemePixmap* OThemeBase::loadPixmap( QString &name )
398{
399 OThemePixmap * pixmap = new OThemePixmap( false );
400 QString path = configFilePath + "/pixmaps/" + name;
401 pixmap->load( path );
402 if ( !pixmap->isNull() )
403 return pixmap;
404 qDebug ( "OThemeBase: Unable to load pixmap %s\n", name.ascii() );
405 delete pixmap;
406 return ( NULL );
407}
408
409OThemePixmap* OThemeBase::scale( int w, int h, WidgetType widget )
410{
411 if ( scaleHints[ widget ] == FullScale ) {
412 if ( !pixmaps[ widget ] || pixmaps[ widget ] ->width() != w ||
413 pixmaps[ widget ] ->height() != h ) {
414 OThemePixmap * cachePix = cache->pixmap( w, h, widget );
415 if ( cachePix ) {
416 cachePix = new OThemePixmap( *cachePix );
417 if ( pixmaps[ widget ] )
418 cache->insert( pixmaps[ widget ], OThemeCache::FullScale,
419 widget );
420 else
421 qDebug( "We would have inserted a null pixmap!\n" );
422 pixmaps[ widget ] = cachePix;
423 }
424 else {
425 cache->insert( pixmaps[ widget ], OThemeCache::FullScale, widget );
426 QImage tmpImg = images[ widget ] ->smoothScale( w, h );
427 pixmaps[ widget ] = new OThemePixmap;
428 pixmaps[ widget ] ->convertFromImage( tmpImg );
429 if ( blends[ widget ] != 0.0 )
430 blend( widget );
431 }
432 }
433 }
434 else if ( scaleHints[ widget ] == HorizontalScale ) {
435 if ( pixmaps[ widget ] ->width() != w ) {
436 OThemePixmap * cachePix = cache->horizontalPixmap( w, widget );
437 if ( cachePix ) {
438 cachePix = new OThemePixmap( *cachePix );
439 if ( pixmaps[ widget ] )
440 cache->insert( pixmaps[ widget ], OThemeCache::HorizontalScale, widget );
441 else
442 qDebug ( "We would have inserted a null pixmap!\n" );
443 pixmaps[ widget ] = cachePix;
444 }
445 else {
446 cache->insert( pixmaps[ widget ], OThemeCache::HorizontalScale, widget );
447 QImage tmpImg = images[ widget ] ->
448 smoothScale( w, images[ widget ] ->height() );
449 pixmaps[ widget ] = new OThemePixmap;
450 pixmaps[ widget ] ->convertFromImage( tmpImg );
451 if ( blends[ widget ] != 0.0 )
452 blend( widget );
453 }
454 }
455 }
456 else if ( scaleHints[ widget ] == VerticalScale ) {
457 if ( pixmaps[ widget ] ->height() != h ) {
458 OThemePixmap * cachePix = cache->verticalPixmap( w, widget );
459 if ( cachePix ) {
460 cachePix = new OThemePixmap( *cachePix );
461 if ( pixmaps[ widget ] )
462 cache->insert( pixmaps[ widget ], OThemeCache::VerticalScale, widget );
463 else
464 qDebug ( "We would have inserted a null pixmap!\n" );
465 pixmaps[ widget ] = cachePix;
466 }
467 else {
468 cache->insert( pixmaps[ widget ], OThemeCache::VerticalScale, widget );
469 QImage tmpImg =
470 images[ widget ] ->smoothScale( images[ widget ] ->width(), h );
471 pixmaps[ widget ] = new OThemePixmap;
472 pixmaps[ widget ] ->convertFromImage( tmpImg );
473 if ( blends[ widget ] != 0.0 )
474 blend( widget );
475 }
476 }
477 }
478 // If blended tile here so the blend is scaled properly
479 else if ( scaleHints[ widget ] == TileScale && blends[ widget ] != 0.0 ) {
480 if ( !pixmaps[ widget ] || pixmaps[ widget ] ->width() != w ||
481 pixmaps[ widget ] ->height() != h ) {
482 OThemePixmap * cachePix = cache->pixmap( w, h, widget );
483 if ( cachePix ) {
484 cachePix = new OThemePixmap( *cachePix );
485 cache->insert( pixmaps[ widget ], OThemeCache::FullScale, widget );
486 pixmaps[ widget ] = cachePix;
487 }
488 else {
489 cache->insert( pixmaps[ widget ], OThemeCache::FullScale, widget );
490 QPixmap tile;
491 tile.convertFromImage( *images[ widget ] );
492 pixmaps[ widget ] = new OThemePixmap;
493 pixmaps[ widget ] ->resize( w, h );
494 QPainter p( pixmaps[ widget ] );
495 p.drawTiledPixmap( 0, 0, w, h, tile );
496 if ( blends[ widget ] != 0.0 )
497 blend( widget );
498 }
499 }
500 }
501 return ( pixmaps[ widget ] );
502}
503
504OThemePixmap* OThemeBase::scaleBorder( int w, int h, WidgetType widget )
505{
506 OThemePixmap * pixmap = NULL;
507 if ( !pbPixmaps[ widget ] && !pbWidth[ widget ] )
508 return ( NULL );
509 pixmap = cache->pixmap( w, h, widget, true );
510 if ( pixmap ) {
511 pixmap = new OThemePixmap( *pixmap );
512 }
513 else {
514 pixmap = new OThemePixmap();
515 pixmap->resize( w, h );
516 QBitmap mask;
517 mask.resize( w, h );
518 mask.fill( color0 );
519 QPainter mPainter;
520 mPainter.begin( &mask );
521
522 QPixmap *tmp = borderPixmap( widget ) ->border( OThemePixmap::TopLeft );
523 const QBitmap *srcMask = tmp->mask();
524 int bdWidth = tmp->width();
525
526 bitBlt( pixmap, 0, 0, tmp, 0, 0, bdWidth, bdWidth,
527 Qt::CopyROP, false );
528 if ( srcMask )
529 bitBlt( &mask, 0, 0, srcMask, 0, 0, bdWidth, bdWidth,
530 Qt::CopyROP, false );
531 else
532 mPainter.fillRect( 0, 0, bdWidth, bdWidth, color1 );
533
534
535 tmp = borderPixmap( widget ) ->border( OThemePixmap::TopRight );
536 srcMask = tmp->mask();
537 bitBlt( pixmap, w - bdWidth, 0, tmp, 0, 0, bdWidth,
538 bdWidth, Qt::CopyROP, false );
539 if ( srcMask )
540 bitBlt( &mask, w - bdWidth, 0, srcMask, 0, 0, bdWidth,
541 bdWidth, Qt::CopyROP, false );
542 else
543 mPainter.fillRect( w - bdWidth, 0, bdWidth, bdWidth, color1 );
544
545 tmp = borderPixmap( widget ) ->border( OThemePixmap::BottomLeft );
546 srcMask = tmp->mask();
547 bitBlt( pixmap, 0, h - bdWidth, tmp, 0, 0, bdWidth,
548 bdWidth, Qt::CopyROP, false );
549 if ( srcMask )
550 bitBlt( &mask, 0, h - bdWidth, srcMask, 0, 0, bdWidth,
551 bdWidth, Qt::CopyROP, false );
552 else
553 mPainter.fillRect( 0, h - bdWidth, bdWidth, bdWidth, color1 );
554
555 tmp = borderPixmap( widget ) ->border( OThemePixmap::BottomRight );
556 srcMask = tmp->mask();
557 bitBlt( pixmap, w - bdWidth, h - bdWidth, tmp, 0, 0,
558 bdWidth, bdWidth, Qt::CopyROP, false );
559 if ( srcMask )
560 bitBlt( &mask, w - bdWidth, h - bdWidth, srcMask, 0, 0,
561 bdWidth, bdWidth, Qt::CopyROP, false );
562 else
563 mPainter.fillRect( w - bdWidth, h - bdWidth, bdWidth, bdWidth, color1 );
564
565 QPainter p;
566 p.begin( pixmap );
567 if ( w - bdWidth * 2 > 0 ) {
568 tmp = borderPixmap( widget ) ->border( OThemePixmap::Top );
569 srcMask = tmp->mask();
570 p.drawTiledPixmap( bdWidth, 0, w - bdWidth * 2, bdWidth, *tmp );
571 if ( srcMask )
572 mPainter.drawTiledPixmap( bdWidth, 0, w - bdWidth * 2, bdWidth, *srcMask );
573 else
574 mPainter.fillRect( bdWidth, 0, w - bdWidth * 2, bdWidth, color1 );
575
576 tmp = borderPixmap( widget ) ->border( OThemePixmap::Bottom );
577 srcMask = tmp->mask();
578 p.drawTiledPixmap( bdWidth, h - bdWidth, w - bdWidth * 2, bdWidth,
579 *tmp );
580 if ( srcMask )
581 mPainter.drawTiledPixmap( bdWidth, h - bdWidth, w - bdWidth * 2, bdWidth, *srcMask );
582 else
583 mPainter.fillRect( bdWidth, h - bdWidth, w - bdWidth * 2, bdWidth,
584 color1 );
585 }
586 if ( h - bdWidth * 2 > 0 ) {
587 tmp = borderPixmap( widget ) ->border( OThemePixmap::Left );
588 srcMask = tmp->mask();
589 p.drawTiledPixmap( 0, bdWidth, bdWidth, h - bdWidth * 2, *tmp );
590 if ( srcMask )
591 mPainter.drawTiledPixmap( 0, bdWidth, bdWidth, h - bdWidth * 2, *srcMask );
592 else
593 mPainter.fillRect( 0, bdWidth, bdWidth, h - bdWidth * 2, color1 );
594
595 tmp = borderPixmap( widget ) ->border( OThemePixmap::Right );
596 srcMask = tmp->mask();
597 p.drawTiledPixmap( w - bdWidth, bdWidth, bdWidth, h - bdWidth * 2,
598 *tmp );
599 if ( srcMask )
600 mPainter.drawTiledPixmap( w - bdWidth, bdWidth, bdWidth, h - bdWidth * 2, *srcMask );
601 else
602 mPainter.fillRect( w - bdWidth, bdWidth, bdWidth, h - bdWidth * 2, color1 );
603 }
604 p.end();
605 mPainter.end();
606 pixmap->setMask( mask );
607 cache->insert( pixmap, OThemeCache::FullScale, widget, true );
608 if ( !pixmap->mask() )
609 qDebug ( "No mask for border pixmap!\n" );
610 }
611 return ( pixmap );
612}
613
614
615OThemePixmap* OThemeBase::blend( WidgetType widget )
616{
617 OGfxEffect::GradientType g;
618 switch ( gradients[ widget ] ) {
619 case GrHorizontal:
620 g = OGfxEffect::HorizontalGradient;
621 break;
622 case GrVertical:
623 g = OGfxEffect::VerticalGradient;
624 break;
625 case GrPyramid:
626 g = OGfxEffect::PyramidGradient;
627 break;
628 case GrRectangle:
629 g = OGfxEffect::RectangleGradient;
630 break;
631 case GrElliptic:
632 g = OGfxEffect::EllipticGradient;
633 break;
634 default:
635 g = OGfxEffect::DiagonalGradient;
636 break;
637 }
638 OGfxEffect::blend( *pixmaps[ widget ], blends[ widget ], *grLowColors[ widget ],
639 g, false );
640 return ( pixmaps[ widget ] );
641}
642
643OThemePixmap* OThemeBase::gradient( int w, int h, WidgetType widget )
644{
645 if ( gradients[ widget ] == GrVertical ) {
646 if ( !pixmaps[ widget ] || pixmaps[ widget ] ->height() != h ) {
647 OThemePixmap * cachePix = cache->verticalPixmap( h, widget );
648 if ( cachePix ) {
649 cachePix = new OThemePixmap( *cachePix );
650 if ( pixmaps[ widget ] )
651 cache->insert( pixmaps[ widget ], OThemeCache::VerticalScale,
652 widget );
653 pixmaps[ widget ] = cachePix;
654 }
655 else {
656 if ( pixmaps[ widget ] )
657 cache->insert( pixmaps[ widget ], OThemeCache::VerticalScale,
658 widget );
659 pixmaps[ widget ] = new OThemePixmap;
660 pixmaps[ widget ] ->resize( w, h );
661 OGfxEffect::gradient( *pixmaps[ widget ], *grHighColors[ widget ],
662 *grLowColors[ widget ],
663 OGfxEffect::VerticalGradient );
664 }
665 }
666 }
667 else if ( gradients[ widget ] == GrHorizontal ) {
668 if ( !pixmaps[ widget ] || pixmaps[ widget ] ->width() != w ) {
669 OThemePixmap * cachePix = cache->horizontalPixmap( w, widget );
670 if ( cachePix ) {
671 cachePix = new OThemePixmap( *cachePix );
672 if ( pixmaps[ widget ] )
673 cache->insert( pixmaps[ widget ],
674 OThemeCache::HorizontalScale, widget );
675 pixmaps[ widget ] = cachePix;
676 }
677 else {
678 if ( pixmaps[ widget ] )
679 cache->insert( pixmaps[ widget ],
680 OThemeCache::HorizontalScale, widget );
681 pixmaps[ widget ] = new OThemePixmap;
682 pixmaps[ widget ] ->resize( w, h );
683 OGfxEffect::gradient( *pixmaps[ widget ], *grHighColors[ widget ],
684 *grLowColors[ widget ],
685 OGfxEffect::HorizontalGradient );
686 }
687 }
688 }
689 else if ( gradients[ widget ] == GrReverseBevel ) {
690 if ( !pixmaps[ widget ] || pixmaps[ widget ] ->width() != w ||
691 pixmaps[ widget ] ->height() != h ) {
692 OThemePixmap * cachePix = cache->pixmap( w, h, widget );
693 if ( cachePix ) {
694 cachePix = new OThemePixmap( *cachePix );
695 if ( pixmaps[ widget ] )
696 cache->insert( pixmaps[ widget ], OThemeCache::FullScale,
697 widget );
698 pixmaps[ widget ] = cachePix;
699 }
700 else {
701 if ( pixmaps[ widget ] )
702 cache->insert( pixmaps[ widget ], OThemeCache::FullScale,
703 widget );
704 pixmaps[ widget ] = new OThemePixmap;
705 pixmaps[ widget ] ->resize( w, h );
706
707 QPixmap s;
708 int offset = decoWidth( widget );
709 s.resize( w - offset * 2, h - offset * 2 );
710 QColor lc( *grLowColors[ widget ] );
711 QColor hc( *grHighColors[ widget ] );
712 if ( bevelContrast( widget ) ) {
713 int bc = bevelContrast( widget );
714 // want single increments, not factors like light()/dark()
715 lc.setRgb( lc.red() - bc, lc.green() - bc, lc.blue() - bc );
716 hc.setRgb( hc.red() + bc, hc.green() + bc, hc.blue() + bc );
717 }
718 OGfxEffect::gradient( *pixmaps[ widget ],
719 lc, hc,
720 OGfxEffect::DiagonalGradient );
721 OGfxEffect::gradient( s, *grHighColors[ widget ],
722 *grLowColors[ widget ],
723 OGfxEffect::DiagonalGradient );
724 bitBlt( pixmaps[ widget ], offset, offset, &s, 0, 0, w - offset * 2,
725 h - offset * 2, Qt::CopyROP );
726 }
727 }
728 }
729 else {
730 OGfxEffect::GradientType g;
731 switch ( gradients[ widget ] ) {
732 case GrPyramid:
733 g = OGfxEffect::PyramidGradient;
734 break;
735 case GrRectangle:
736 g = OGfxEffect::RectangleGradient;
737 break;
738 case GrElliptic:
739 g = OGfxEffect::EllipticGradient;
740 break;
741 default:
742 g = OGfxEffect::DiagonalGradient;
743 break;
744 }
745 if ( !pixmaps[ widget ] || pixmaps[ widget ] ->width() != w ||
746 pixmaps[ widget ] ->height() != h ) {
747 OThemePixmap * cachePix = cache->pixmap( w, h, widget );
748 if ( cachePix ) {
749 cachePix = new OThemePixmap( *cachePix );
750 if ( pixmaps[ widget ] )
751 cache->insert( pixmaps[ widget ], OThemeCache::FullScale,
752 widget );
753 pixmaps[ widget ] = cachePix;
754 }
755 else {
756 if ( pixmaps[ widget ] )
757 cache->insert( pixmaps[ widget ], OThemeCache::FullScale,
758 widget );
759 pixmaps[ widget ] = new OThemePixmap;
760 pixmaps[ widget ] ->resize( w, h );
761 OGfxEffect::gradient( *pixmaps[ widget ], *grHighColors[ widget ],
762 *grLowColors[ widget ], g );
763 }
764 }
765 }
766 return ( pixmaps[ widget ] );
767}
768
769OThemePixmap* OThemeBase::scalePixmap( int w, int h, WidgetType widget )
770{
771
772 if ( gradients[ widget ] && blends[ widget ] == 0.0 )
773 return ( gradient( w, h, widget ) );
774
775 return ( scale( w, h, widget ) );
776}
777
778QColorGroup* OThemeBase::makeColorGroup( QColor &fg, QColor &bg,
779 Qt::GUIStyle )
780{
781 if ( shading == Motif ) {
782 int highlightVal, lowlightVal;
783 highlightVal = 100 + ( 2* /*KGlobalSettings::contrast()*/ 3 + 4 ) * 16 / 10;
784 lowlightVal = 100 + ( ( 2* /*KGlobalSettings::contrast()*/ 3 + 4 ) * 10 );
785 return ( new QColorGroup( fg, bg, bg.light( highlightVal ),
786 bg.dark( lowlightVal ), bg.dark( 120 ),
787 fg, qApp->palette().normal().base() ) );
788 }
789 else
790 return ( new QColorGroup( fg, bg, bg.light( 150 ), bg.dark(),
791 bg.dark( 120 ), fg,
792 qApp->palette().normal().base() ) );
793}
794
795static QColor strToColor ( const QString &str )
796{
797 QString str2 = str. stripWhiteSpace ( );
798
799 if ( str2 [0] == '#' )
800 return QColor ( str2 );
801 else {
802 QStringList sl = QStringList::split ( ',', str2 );
803
804 if ( sl. count ( ) >= 3 )
805 return QColor ( sl [0]. toInt ( ), sl [1]. toInt ( ), sl [2]. toInt ( ));
806 }
807 return QColor ( 0, 0, 0 );
808}
809
810
811
812void OThemeBase::applyMiscResourceGroup( Config *config )
813{
814 config-> setGroup ( "Misc" );
815 QString tmpStr;
816
817 tmpStr = config->readEntry( "SButtonPosition" );
818 if ( tmpStr == "BottomLeft" )
819 sbPlacement = SBBottomLeft;
820 else if ( tmpStr == "BottomRight" )
821 sbPlacement = SBBottomRight;
822 else {
823 if ( tmpStr != "Opposite" && !tmpStr.isEmpty() )
824 qDebug ( "OThemeBase: Unrecognized sb button option %s, using Opposite.\n", tmpStr.ascii() );
825 sbPlacement = SBOpposite;
826 }
827 tmpStr = config->readEntry( "ArrowType" );
828 if ( tmpStr == "Small" )
829 arrowStyle = SmallArrow;
830 else if ( tmpStr == "3D" )
831 arrowStyle = MotifArrow;
832 else {
833 if ( tmpStr != "Normal" && !tmpStr.isEmpty() )
834 qDebug ( "OThemeBase: Unrecognized arrow option %s, using Normal.\n", tmpStr.ascii() );
835 arrowStyle = LargeArrow;
836 }
837 tmpStr = config->readEntry( "ShadeStyle" );
838 if ( tmpStr == "Motif" )
839 shading = Motif;
840 else if ( tmpStr == "Next" )
841 shading = Next;
842 else if ( tmpStr == "KDE" )
843 shading = KDE;
844 else
845 shading = Windows;
846
847 defaultFrame = config->readNumEntry( "FrameWidth", 2 );
848 cacheSize = config->readNumEntry( "Cache", 1024 );
849 sbExtent = config->readNumEntry( "ScrollBarExtent", 16 );
850
851 config-> setGroup ( "General" );
852
853 if ( config-> hasKey ( "foreground" )) fgcolor = strToColor ( config-> readEntry ( "foreground" ));
854 if ( config-> hasKey ( "background" )) bgcolor = strToColor ( config-> readEntry ( "background" ));
855 if ( config-> hasKey ( "selectForeground" )) selfgcolor = strToColor ( config-> readEntry ( "selectForeground" ));
856 if ( config-> hasKey ( "selectBackground" )) selbgcolor = strToColor ( config-> readEntry ( "selectBackground" ));
857 if ( config-> hasKey ( "windowForeground" )) winfgcolor = strToColor ( config-> readEntry ( "windowForeground" ));
858 if ( config-> hasKey ( "windowBackground" )) winbgcolor = strToColor ( config-> readEntry ( "windowBackground" ));
859}
860
861void OThemeBase::readMiscResourceGroup()
862{}
863
864void OThemeBase::applyResourceGroup( Config *config, int i, QString *copyfrom, QString *pixnames, QString *brdnames )
865{
866 QString tmpStr;
867
868 config-> setGroup ( widgetEntries [ i ] );
869
870 tmpStr = config->readEntry( "CopyWidget", "" );
871 copyfrom [ i ] = tmpStr;
872 if ( !tmpStr.isEmpty() )
873 return ;
874
875 // Scale hint
876 tmpStr = config->readEntry( "Scale" );
877 if ( tmpStr == "Full" )
878 scaleHints [ i ] = FullScale;
879 else if ( tmpStr == "Horizontal" )
880 scaleHints [ i ] = HorizontalScale;
881 else if ( tmpStr == "Vertical" )
882 scaleHints [ i ] = VerticalScale;
883 else {
884 if ( tmpStr != "Tile" && !tmpStr.isEmpty() )
885 qDebug ( "OThemeBase: Unrecognized scale option %s, using Tile.\n", tmpStr.ascii() );
886 scaleHints [ i ] = TileScale;
887 }
888
889
890 // Gradient type
891 tmpStr = config->readEntry( "Gradient" );
892 if ( tmpStr == "Diagonal" )
893 gradients [ i ] = GrDiagonal;
894 else if ( tmpStr == "Horizontal" )
895 gradients [ i ] = GrHorizontal;
896 else if ( tmpStr == "Vertical" )
897 gradients [ i ] = GrVertical;
898 else if ( tmpStr == "Pyramid" )
899 gradients [ i ] = GrPyramid;
900 else if ( tmpStr == "Rectangle" )
901 gradients [ i ] = GrRectangle;
902 else if ( tmpStr == "Elliptic" )
903 gradients [ i ] = GrElliptic;
904 else if ( tmpStr == "ReverseBevel" )
905 gradients [ i ] = GrReverseBevel;
906 else {
907 if ( tmpStr != "None" && !tmpStr.isEmpty() )
908 qDebug ( "OThemeBase: Unrecognized gradient option %s, using None.\n", tmpStr.ascii() );
909 gradients [ i ] = GrNone;
910 }
911
912 // Blend intensity
913 blends[ i ] = config->readEntry( "BlendIntensity", "0.0" ).toDouble();
914
915 // Bevel contrast
916 bContrasts[ i ] = config->readNumEntry( "BevelContrast", 0 );
917
918 // Border width
919 borders [ i ] = config->readNumEntry( "Border", 1 );
920
921 // Highlight width
922 highlights [ i ] = config->readNumEntry( "Highlight", 1 );
923
924 // Gradient low color or blend background
925 if ( config->hasKey( "GradientLow" ) && ( gradients[ i ] != GrNone || blends[ i ] != 0.0 ))
926 grLowColors[ i ] = new QColor( strToColor ( config->readEntry( "GradientLow", qApp->palette().normal().background().name() )));
927 else
928 grLowColors[ i ] = NULL;
929
930
931 // Gradient high color
932 if ( config->hasKey( "GradientHigh" ) && ( gradients[ i ] != GrNone ))
933 grHighColors[ i ] = new QColor( strToColor ( config->readEntry( "GradientHigh", qApp->palette().normal().background().name() )));
934 else
935 grHighColors[ i ] = NULL;
936
937 // Extended color attributes
938 if ( config->hasKey( "Foreground" ) || config->hasKey( "Background" ) ) {
939 QColor bg = strToColor( config->readEntry( "Background", qApp->palette().normal().background().name() ));
940 QColor fg = strToColor( config->readEntry( "Foreground", qApp->palette().normal().foreground().name() ));
941
942 colors[ i ] = makeColorGroup( fg, bg, Qt::WindowsStyle );
943 }
944 else
945 colors[ i ] = NULL;
946
947 // Pixmap
948 tmpStr = config->readEntry( "Pixmap", "" );
949 pixnames[ i ] = tmpStr;
950 duplicate[ i ] = false;
951 pixmaps[ i ] = NULL;
952 images[ i ] = NULL;
953
954
955 // Pixmap border
956 tmpStr = config->readEntry( "PixmapBorder", "" );
957 brdnames[ i ] = tmpStr;
958 pbDuplicate[ i ] = false;
959 pbPixmaps[ i ] = NULL;
960 pbWidth[ i ] = 0;
961 if ( !tmpStr.isEmpty() ) {
962 pbWidth[ i ] = config->readNumEntry( "PixmapBWidth", 0 );
963 if ( pbWidth[ i ] == 0 ) {
964 qDebug ( "OThemeBase: No border width specified for pixmapped border widget %s\n", widgetEntries[ i ] );
965 qDebug ( "OThemeBase: Using default of 2.\n" );
966 pbWidth[ i ] = 2;
967 }
968 }
969
970
971 // Various widget specific settings. This was more efficent when bunched
972 // together in the misc group, but this makes an easier to read config.
973 if ( i == SliderGroove )
974 roundedSlider = config->readBoolEntry( "SmallGroove", false );
975 else if ( i == ActiveTab || i == InactiveTab )
976 aTabLine = iTabLine = config->readBoolEntry( "BottomLine", true );
977 else if ( i == Splitter )
978 splitterWidth = config->readNumEntry( "Width", 10 );
979 else if ( i == ComboBox || i == ComboBoxDown ) {
980 roundedCombo = config->readBoolEntry( "Round", false );
981 }
982 else if ( i == PushButton || i == PushButtonDown ) {
983 btnXShift = config->readNumEntry( "XShift", 0 );
984 btnYShift = config->readNumEntry( "YShift", 0 );
985 focus3D = config->readBoolEntry( "3DFocusRect", false );
986 focus3DOffset = config->readBoolEntry( "3DFocusOffset", 0 );
987 roundedButton = config->readBoolEntry( "Round", false );
988 }
989}
990
991
992void OThemeBase::readResourceGroup( int i, QString *copyfrom, QString *pixnames, QString *brdnames,
993 bool *loadArray )
994{
995 if ( loadArray[ i ] == true ) {
996 return ; // already been preloaded.
997 }
998
999 int tmpVal;
1000 QString tmpStr;
1001
1002 tmpStr = copyfrom [ i ];
1003 if ( !tmpStr.isEmpty() ) { // Duplicate another widget's config
1004 int sIndex;
1005 loadArray[ i ] = true;
1006 for ( sIndex = 0; sIndex < WIDGETS; ++sIndex ) {
1007 if ( tmpStr == widgetEntries[ sIndex ] ) {
1008 if ( !loadArray[ sIndex ] ) // hasn't been loaded yet
1009 readResourceGroup( sIndex, copyfrom, pixnames, brdnames,
1010 loadArray );
1011 break;
1012 }
1013 }
1014 if ( loadArray[ sIndex ] ) {
1015 copyWidgetConfig( sIndex, i, pixnames, brdnames );
1016 }
1017 else
1018 qDebug ( "OThemeBase: Unable to identify source widget for %s\n", widgetEntries[ i ] );
1019 return ;
1020 }
1021 // special inheritance for disabled arrows (these are tri-state unlike
1022 // the rest of what we handle).
1023 for ( tmpVal = DisArrowUp; tmpVal <= DisArrowRight; ++tmpVal ) {
1024 if ( tmpVal == i ) {
1025 tmpStr = pixnames [ i ];
1026 if ( tmpStr.isEmpty() ) {
1027 copyWidgetConfig( ArrowUp + ( tmpVal - DisArrowUp ), i, pixnames,
1028 brdnames );
1029 return ;
1030 }
1031 }
1032 }
1033
1034 // Pixmap
1035 int existing;
1036 // Scan for duplicate pixmaps(two identical pixmaps, tile scale, no blend,
1037 // no pixmapped border)
1038 if ( !pixnames [ i ].isEmpty() ) {
1039 for ( existing = 0; existing < i; ++existing ) {
1040 if ( pixnames[ i ] == pixnames[ existing ] && scaleHints[ i ] == TileScale &&
1041 scaleHints[ existing ] == TileScale && blends[ existing ] == 0.0 &&
1042 blends[ i ] == 0.0 ) {
1043 pixmaps[ i ] = pixmaps[ existing ];
1044 duplicate[ i ] = true;
1045 break;
1046 }
1047 }
1048 }
1049 // load
1050 if ( !duplicate[ i ] && !pixnames[ i ].isEmpty() ) {
1051 pixmaps[ i ] = loadPixmap( pixnames[ i ] );
1052 // load and save images for scaled/blended widgets for speed.
1053 if ( scaleHints[ i ] == TileScale && blends[ i ] == 0.0 )
1054 images[ i ] = NULL;
1055 else
1056 images[ i ] = loadImage( pixnames[ i ] );
1057 }
1058
1059 // Pixmap border
1060 if ( !brdnames [ i ]. isEmpty () ) {
1061 // duplicate check
1062 for ( existing = 0; existing < i; ++existing ) {
1063 if ( brdnames [i] == brdnames[ existing ] ) {
1064 pbPixmaps[ i ] = pbPixmaps[ existing ];
1065 pbDuplicate[ i ] = true;
1066 break;
1067 }
1068 }
1069 }
1070 // load
1071 if ( !pbDuplicate[ i ] && !brdnames[ i ].isEmpty() )
1072 pbPixmaps[ i ] = loadPixmap( brdnames[ i ] );
1073
1074 if ( pbPixmaps[ i ] && !pbDuplicate[ i ] )
1075 generateBorderPix( i );
1076
1077 loadArray[ i ] = true;
1078}
1079
1080
1081OThemePixmap::OThemePixmap( bool timer )
1082 : QPixmap()
1083{
1084 if(timer){
1085 t = new QTime;
1086 t->start();
1087 }
1088 else
1089 t = NULL;
1090 int i;
1091 for ( i = 0; i < 8; ++i )
1092 b[ i ] = NULL;
1093}
1094
1095OThemePixmap::OThemePixmap( const OThemePixmap &p )
1096 : QPixmap( p )
1097{
1098 if(p.t){
1099 t = new QTime;
1100 t->start();
1101 }
1102 else
1103 t = NULL;
1104 int i;
1105 for ( i = 0; i < 8; ++i )
1106 if ( p.b[ i ] )
1107 b[ i ] = new QPixmap( *p.b[ i ] );
1108 else
1109 b[ i ] = NULL;
1110}
1111
1112
1113
1114OThemePixmap::~OThemePixmap()
1115{
1116 if(t)
1117 delete t;
1118 int i;
1119 for ( i = 0; i < 8; ++i )
1120 if ( b[ i ] )
1121 delete b[ i ];
1122}
1123
1124OThemeCache::OThemeCache( int maxSize, QObject *parent, const char *name )
1125 : QObject( parent, name )
1126{
1127 cache.setMaxCost( maxSize * 1024 );
1128 cache.setAutoDelete( true );
1129 flushTimer.start(300000); // 5 minutes
1130 connect(&flushTimer, SIGNAL(timeout()), SLOT(flushTimeout()));
1131}
1132
1133void OThemeCache::flushTimeout()
1134{
1135 QIntCacheIterator<OThemePixmap> it( cache );
1136 while ( it.current() ) {
1137 if ( it.current() ->isOld() )
1138 cache.remove( it.currentKey() );
1139 else
1140 ++it;
1141 }
1142}
1143
1144OThemePixmap* OThemeCache::pixmap( int w, int h, int widgetID, bool border,
1145 bool mask )
1146{
1147
1148 kthemeKey key;
1149 key.cacheKey = 0; // shut up, gcc
1150 key.data.id = widgetID;
1151 key.data.width = w;
1152 key.data.height = h;
1153 key.data.border = border;
1154 key.data.mask = mask;
1155
1156 OThemePixmap *pix = cache.find( ( unsigned long ) key.cacheKey );
1157 if ( pix )
1158 pix->updateAccessed();
1159 return ( pix );
1160}
1161
1162OThemePixmap* OThemeCache::horizontalPixmap( int w, int widgetID )
1163{
1164 kthemeKey key;
1165 key.cacheKey = 0; // shut up, gcc
1166 key.data.id = widgetID;
1167 key.data.width = w;
1168 key.data.height = 0;
1169 key.data.border = false;
1170 key.data.mask = false;
1171 OThemePixmap *pix = cache.find( ( unsigned long ) key.cacheKey );
1172 if ( pix )
1173 pix->updateAccessed();
1174 return ( pix );
1175}
1176
1177OThemePixmap* OThemeCache::verticalPixmap( int h, int widgetID )
1178{
1179 kthemeKey key;
1180 key.cacheKey = 0; // shut up, gcc
1181 key.data.id = widgetID;
1182 key.data.width = 0;
1183 key.data.height = h;
1184 key.data.border = false;
1185 key.data.mask = false;
1186 OThemePixmap *pix = cache.find( ( unsigned long ) key.cacheKey );
1187 if ( pix )
1188 pix->updateAccessed();
1189 return ( pix );
1190}
1191
1192bool OThemeCache::insert( OThemePixmap *pixmap, ScaleHint scale, int widgetID,
1193 bool border, bool mask )
1194{
1195 kthemeKey key;
1196 key.cacheKey = 0; // shut up, gcc
1197 key.data.id = widgetID;
1198 key.data.width = ( scale == FullScale || scale == HorizontalScale ) ?
1199 pixmap->width() : 0;
1200 key.data.height = ( scale == FullScale || scale == VerticalScale ) ?
1201 pixmap->height() : 0;
1202 key.data.border = border;
1203 key.data.mask = mask;
1204
1205 if ( cache.find( ( unsigned long ) key.cacheKey, true ) != NULL ) {
1206 return ( true ); // a pixmap of this scale is already in there
1207 }
1208 return ( cache.insert( ( unsigned long ) key.cacheKey, pixmap,
1209 pixmap->width() * pixmap->height() * pixmap->depth() / 8 ) );
1210}
1211
1212//#include "kthemebase.moc"