Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

othemebase.cpp

Go to the documentation of this file.
00001 /* This file is part of the KDE libraries
00002   Copyright (C) 1999 Daniel M. Duley <mosfet@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 version 2 as published by the Free Software Foundation.
00007 
00008   This library is distributed in the hope that it will be useful,
00009   but WITHOUT ANY WARRANTY; without even the implied warranty of
00010   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011   Library General Public License for more details.
00012 
00013   You should have received a copy of the GNU Library General Public License
00014   along with this library; see the file COPYING.LIB.  If not, write to
00015   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00016   Boston, MA 02111-1307, USA.
00017 */
00018 
00019 #include "othemebase.h"
00020 #include "ogfxeffect.h"
00021 
00022 /* OPIE */
00023 #include <opie2/odebug.h>
00024 #include <qpe/qpeapplication.h>
00025 #include <qpe/config.h>
00026 using namespace Opie::Core;
00027 
00028 /* QT */
00029 #include <qfile.h>
00030 #include <qtextstream.h>
00031 #include <qdir.h>
00032 #include <qpainter.h>
00033 #include <qbitmap.h>
00034 #include <qstringlist.h>
00035 
00036 /* STD */
00037 #include <stdlib.h>
00038 
00039 
00040 template class QIntCache<OThemePixmap>
00041 ;
00042 
00043 static const char *widgetEntries[] =
00044     { // unsunken widgets (see header)
00045         "PushButton", "ComboBox", "HSBarSlider", "VSBarSlider", "Bevel", "ToolButton",
00046         "ScrollButton", "HScrollDeco", "VScrollDeco", "ComboDeco", "MenuItem", "Tab",
00047         "ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight",
00048         // sunken widgets
00049         "PushButtonDown", "ComboBoxDown", "HSBarSliderDown", "VSBarSliderDown",
00050         "BevelDown", "ToolButtonDown", "ScrollButtonDown", "HScrollDecoDown",
00051         "VScrollDecoDown", "ComboDecoDown", "MenuItemDown", "TabDown", "SunkenArrowUp",
00052         "SunkenArrowDown", "SunkenArrowLeft", "SunkenArrowRight",
00053         // everything else
00054         "HScrollGroove", "VScrollGroove", "Slider", "SliderGroove", "CheckBoxDown",
00055         "CheckBox", "RadioDown", "Radio", "HBarHandle", "VBarHandle",
00056         "ToolBar", "Splitter", "CheckMark", "MenuBar", "DisableArrowUp",
00057         "DisableArrowDown", "DisableArrowLeft", "DisableArrowRight", "ProgressBar",
00058         "ProgressBackground", "MenuBarItem", "Background"
00059     };
00060 
00061 #define INHERIT_ITEMS 16
00062 
00063 
00064 // This is used to encode the keys. I used to use masks but I think this
00065 // bitfield is nicer :) I don't know why C++ coders don't use these more..
00066 // (mosfet)
00067 struct kthemeKeyData
00068 {
00069 unsigned int id :
00070     6;
00071 unsigned int width :
00072     12;
00073 unsigned int height :
00074     12;
00075 unsigned int border :
00076     1;
00077 unsigned int mask :
00078     1;
00079 };
00080 
00081 union kthemeKey{
00082     kthemeKeyData data;
00083     unsigned int cacheKey;
00084 };
00085 
00086 
00087 void OThemeBase::generateBorderPix( int i )
00088 {
00089     // separate pixmap into separate components
00090     if ( pbPixmaps[ i ] ) {
00091         // evidently I have to do masks manually...
00092         const QBitmap * srcMask = pbPixmaps[ i ] ->mask();
00093         QBitmap destMask( pbWidth[ i ], pbWidth[ i ] );
00094         QPixmap tmp( pbWidth[ i ], pbWidth[ i ] );
00095 
00096         bitBlt( &tmp, 0, 0, pbPixmaps[ i ], 0, 0, pbWidth[ i ], pbWidth[ i ],
00097                 Qt::CopyROP, false );
00098         if ( srcMask ) {
00099             bitBlt( &destMask, 0, 0, srcMask, 0, 0, pbWidth[ i ], pbWidth[ i ],
00100                     Qt::CopyROP, false );
00101             tmp.setMask( destMask );
00102         }
00103         pbPixmaps[ i ] ->setBorder( OThemePixmap::TopLeft, tmp );
00104 
00105         bitBlt( &tmp, 0, 0, pbPixmaps[ i ], pbPixmaps[ i ] ->width() - pbWidth[ i ], 0,
00106                 pbWidth[ i ], pbWidth[ i ], Qt::CopyROP, false );
00107         if ( srcMask ) {
00108             bitBlt( &destMask, 0, 0, srcMask, pbPixmaps[ i ] ->width() - pbWidth[ i ],
00109                     0, pbWidth[ i ], pbWidth[ i ], Qt::CopyROP, false );
00110             tmp.setMask( destMask );
00111         }
00112         pbPixmaps[ i ] ->setBorder( OThemePixmap::TopRight, tmp );
00113 
00114         bitBlt( &tmp, 0, 0, pbPixmaps[ i ], 0, pbPixmaps[ i ] ->height() - pbWidth[ i ],
00115                 pbWidth[ i ], pbWidth[ i ], Qt::CopyROP, false );
00116         if ( srcMask ) {
00117             bitBlt( &destMask, 0, 0, srcMask, 0, pbPixmaps[ i ] ->height() - pbWidth[ i ],
00118                     pbWidth[ i ], pbWidth[ i ], Qt::CopyROP, false );
00119             tmp.setMask( destMask );
00120         }
00121         pbPixmaps[ i ] ->setBorder( OThemePixmap::BottomLeft, tmp );
00122 
00123         bitBlt( &tmp, 0, 0, pbPixmaps[ i ], pbPixmaps[ i ] ->width() - pbWidth[ i ],
00124                 pbPixmaps[ i ] ->height() - pbWidth[ i ], pbWidth[ i ], pbWidth[ i ],
00125                 Qt::CopyROP, false );
00126         if ( srcMask ) {
00127             bitBlt( &destMask, 0, 0, srcMask, pbPixmaps[ i ] ->width() - pbWidth[ i ],
00128                     pbPixmaps[ i ] ->height() - pbWidth[ i ], pbWidth[ i ], pbWidth[ i ],
00129                     Qt::CopyROP, false );
00130             tmp.setMask( destMask );
00131         }
00132         pbPixmaps[ i ] ->setBorder( OThemePixmap::BottomRight, tmp );
00133 
00134         tmp.resize( pbPixmaps[ i ] ->width() - pbWidth[ i ] * 2, pbWidth[ i ] );
00135         destMask.resize( pbPixmaps[ i ] ->width() - pbWidth[ i ] * 2, pbWidth[ i ] );
00136         bitBlt( &tmp, 0, 0, pbPixmaps[ i ], pbWidth[ i ], 0,
00137                 pbPixmaps[ i ] ->width() - pbWidth[ i ] * 2, pbWidth[ i ], Qt::CopyROP, false );
00138         if ( srcMask ) {
00139             bitBlt( &destMask, 0, 0, srcMask, pbWidth[ i ], 0,
00140                     pbPixmaps[ i ] ->width() - pbWidth[ i ] * 2, pbWidth[ i ],
00141                     Qt::CopyROP, false );
00142             tmp.setMask( destMask );
00143         }
00144         pbPixmaps[ i ] ->setBorder( OThemePixmap::Top, tmp );
00145 
00146         bitBlt( &tmp, 0, 0, pbPixmaps[ i ], pbWidth[ i ],
00147                 pbPixmaps[ i ] ->height() - pbWidth[ i ],
00148                 pbPixmaps[ i ] ->width() - pbWidth[ i ] * 2, pbWidth[ i ], Qt::CopyROP, false );
00149         if ( srcMask ) {
00150             bitBlt( &destMask, 0, 0, srcMask, pbWidth[ i ],
00151                     pbPixmaps[ i ] ->height() - pbWidth[ i ],
00152                     pbPixmaps[ i ] ->width() - pbWidth[ i ] * 2, pbWidth[ i ], Qt::CopyROP, false );
00153             tmp.setMask( destMask );
00154         }
00155         pbPixmaps[ i ] ->setBorder( OThemePixmap::Bottom, tmp );
00156 
00157         tmp.resize( pbWidth[ i ], pbPixmaps[ i ] ->height() - pbWidth[ i ] * 2 );
00158         destMask.resize( pbWidth[ i ], pbPixmaps[ i ] ->height() - pbWidth[ i ] * 2 );
00159         bitBlt( &tmp, 0, 0, pbPixmaps[ i ], 0, pbWidth[ i ], pbWidth[ i ],
00160                 pbPixmaps[ i ] ->height() - pbWidth[ i ] * 2, Qt::CopyROP, false );
00161         if ( srcMask ) {
00162             bitBlt( &destMask, 0, 0, srcMask, 0, pbWidth[ i ], pbWidth[ i ],
00163                     pbPixmaps[ i ] ->height() - pbWidth[ i ] * 2, Qt::CopyROP, false );
00164             tmp.setMask( destMask );
00165         }
00166 
00167         pbPixmaps[ i ] ->setBorder( OThemePixmap::Left, tmp );
00168 
00169         bitBlt( &tmp, 0, 0, pbPixmaps[ i ], pbPixmaps[ i ] ->width() - pbWidth[ i ],
00170                 pbWidth[ i ], pbWidth[ i ], pbPixmaps[ i ] ->height() - pbWidth[ i ] * 2,
00171                 Qt::CopyROP, false );
00172         if ( srcMask ) {
00173             bitBlt( &destMask, 0, 0, srcMask, pbPixmaps[ i ] ->width() - pbWidth[ i ],
00174                     pbWidth[ i ], pbWidth[ i ], pbPixmaps[ i ] ->height() - pbWidth[ i ] * 2,
00175                     Qt::CopyROP, false );
00176             tmp.setMask( destMask );
00177         }
00178         pbPixmaps[ i ] ->setBorder( OThemePixmap::Right, tmp );
00179     }
00180     else
00181         odebug << "OThemeBase: Tried making border from empty pixmap" << oendl;
00182 }
00183 
00184 
00185 void OThemeBase::copyWidgetConfig( int sourceID, int destID, QString *pixnames,
00186                                    QString *brdnames )
00187 {
00188     scaleHints[ destID ] = scaleHints[ sourceID ];
00189     gradients[ destID ] = gradients[ sourceID ];
00190     blends[ destID ] = blends[ sourceID ];
00191     bContrasts[ destID ] = bContrasts[ sourceID ];
00192     borders[ destID ] = borders[ sourceID ];
00193     highlights[ destID ] = highlights[ sourceID ];
00194 
00195     if ( grLowColors[ sourceID ] )
00196         grLowColors[ destID ] = new QColor( *grLowColors[ sourceID ] );
00197     else
00198         grLowColors[ destID ] = NULL;
00199 
00200     if ( grHighColors[ sourceID ] )
00201         grHighColors[ destID ] = new QColor( *grHighColors[ sourceID ] );
00202     else
00203         grHighColors[ destID ] = NULL;
00204 
00205     if ( colors[ sourceID ] )
00206         colors[ destID ] = new QColorGroup( *colors[ sourceID ] );
00207     else
00208         colors[ destID ] = NULL;
00209 
00210     // pixmap
00211     pixnames[ destID ] = pixnames[ sourceID ];
00212     duplicate[ destID ] = false;
00213     pixmaps[ destID ] = NULL;
00214     images[ destID ] = NULL;
00215     if ( !pixnames[ destID ].isEmpty() ) {
00216         if ( scaleHints[ sourceID ] == TileScale && blends[ sourceID ] == 0.0 ) {
00217             pixmaps[ destID ] = pixmaps[ sourceID ];
00218             duplicate[ destID ] = true;
00219         }
00220         if ( !duplicate[ destID ] ) {
00221             pixmaps[ destID ] = loadPixmap( pixnames[ destID ] );
00222             if ( scaleHints[ destID ] == TileScale && blends[ destID ] == 0.0 )
00223                 images[ destID ] = NULL;
00224             else
00225                 images[ destID ] = loadImage( pixnames[ destID ] );
00226         }
00227     }
00228 
00229     // border pixmap
00230     pbDuplicate[ destID ] = false;
00231     pbPixmaps[ destID ] = NULL;
00232     pbWidth[ destID ] = pbWidth[ sourceID ];
00233     brdnames[ destID ] = brdnames[ sourceID ];
00234     if ( !brdnames[ destID ].isEmpty() ) {
00235         pbPixmaps[ destID ] = pbPixmaps[ sourceID ];
00236         pbDuplicate[ destID ] = true;
00237     }
00238 
00239     if ( sourceID == ActiveTab && destID == InactiveTab )
00240         aTabLine = iTabLine;
00241     else if ( sourceID == InactiveTab && destID == ActiveTab )
00242         iTabLine = aTabLine;
00243 }
00244 
00245 void OThemeBase::readConfig( Qt::GUIStyle /*style*/ )
00246 {
00247 #define PREBLEND_ITEMS 12
00248     static WidgetType preBlend[] = {Slider, IndicatorOn, IndicatorOff,
00249                                     ExIndicatorOn, ExIndicatorOff, HScrollDeco, VScrollDeco, HScrollDecoDown,
00250                                     VScrollDecoDown, ComboDeco, ComboDecoDown, CheckMark};
00251 
00252     int i;
00253     QString tmpStr;
00254     QString copyfrom[ WIDGETS ];
00255     QString pixnames[ WIDGETS ]; // used for duplicate check
00256     QString brdnames[ WIDGETS ];
00257     bool loaded[ WIDGETS ]; // used for preloading for CopyWidget
00258 
00259     if ( configFileName.isEmpty() ) {
00260         Config cfg ( "qpe" );
00261         cfg. setGroup ( "Appearance" );
00262 
00263         configFileName = cfg. readEntry ( "Theme", "default" );
00264     }
00265     Config config( configFilePath + "/themes/" + configFileName + ".themerc" , Config::File );
00266 
00267     // Are we initalized?
00268     applyMiscResourceGroup( &config );
00269     for ( i = 0; i < INHERIT_ITEMS; ++i ) {
00270         applyResourceGroup( &config, i, copyfrom, pixnames, brdnames );
00271     }
00272     for ( ; i < INHERIT_ITEMS*2; ++i ) {
00273         if ( config.hasGroup( QString( widgetEntries[ i ] ) ) ) {
00274             applyResourceGroup( &config, i, copyfrom, pixnames, brdnames );
00275         }
00276         else {
00277             copyfrom [ i ] = widgetEntries[ i - INHERIT_ITEMS ];
00278         }
00279     }
00280     for ( ; i < WIDGETS; ++i ) {
00281         applyResourceGroup( &config, i, copyfrom, pixnames, brdnames );
00282     }
00283 
00284     // initalize defaults that may not be read
00285     for ( i = 0; i < WIDGETS; ++i )
00286         loaded[ i ] = false;
00287     btnXShift = btnYShift = focus3DOffset = 0;
00288     aTabLine = iTabLine = true;
00289     roundedButton = roundedCombo = roundedSlider = focus3D = false;
00290     splitterWidth = 10;
00291 
00292     for ( i = 0; i < WIDGETS; ++i ) {
00293         readResourceGroup( i, copyfrom, pixnames, brdnames, loaded );
00294     }
00295 
00296     // misc items
00297     readMiscResourceGroup();
00298 
00299     // Handle preblend items
00300     for ( i = 0; i < PREBLEND_ITEMS; ++i ) {
00301         if ( pixmaps[ preBlend[ i ] ] != NULL && blends[ preBlend[ i ] ] != 0.0 )
00302             blend( preBlend[ i ] );
00303     }
00304 }
00305 
00306 OThemeBase::OThemeBase( const QString & configFile )
00307         : QWindowsStyle()
00308 {
00309     configFilePath = QPEApplication::qpeDir ( ) + "plugins/styles/";
00310     configFileName = configFile;
00311 
00312     readConfig( Qt::WindowsStyle );
00313     cache = new OThemeCache( cacheSize );
00314 }
00315 
00316 void OThemeBase::applyConfigFile( const QString &/*file*/ )
00317 {
00318 #if 0
00319     // handle std color scheme
00320     Config inConfig( file, Config::File );
00321     Config globalConfig ( "qpe" );
00322 
00323     globalConfig. setGroup ( "Apperance" );
00324     inConfig. setGroup( "General" );
00325 
00326     if ( inConfig.hasKey( "foreground" ) )
00327         globalConfig.writeEntry( "Text",                    inConfig.readEntry( "foreground", " " ) );
00328     if ( inConfig.hasKey( "background" ) )
00329         globalConfig.writeEntry( "Background",                    inConfig.readEntry( "background", " " ) );
00330     if ( inConfig.hasKey( "selectForeground" ) )
00331         globalConfig.writeEntry( "HighlightedText",              inConfig.readEntry( "selectForeground", " " ) );
00332     if ( inConfig.hasKey( "selectBackground" ) )
00333         globalConfig.writeEntry( "Highlight",                     inConfig.readEntry( "selectBackground", " " ) );
00334     if ( inConfig.hasKey( "windowForeground" ) )
00335         globalConfig.writeEntry( "Text",              inConfig.readEntry( "windowForeground", " " ) );
00336     if ( inConfig.hasKey( "windowBackground" ) )
00337         globalConfig.writeEntry( "Base",              inConfig.readEntry( "windowBackground", " " ) );
00338 
00339     // Keep track of the current theme so that we can select the right one
00340     // in the KControl module.
00341     globalConfig.writeEntry ( "CurrentTheme", file );
00342 
00343     globalConfig.write();
00344 #endif
00345 }
00346 
00347 OThemeBase::~OThemeBase()
00348 {
00349     int i;
00350     for ( i = 0; i < WIDGETS; ++i ) {
00351         if ( !duplicate[ i ] ) {
00352             if ( images[ i ] )
00353                 delete images[ i ];
00354             if ( pixmaps[ i ] )
00355                 delete pixmaps[ i ];
00356         }
00357         if ( !pbDuplicate[ i ] && pbPixmaps[ i ] )
00358             delete pbPixmaps[ i ];
00359         if ( colors[ i ] )
00360             delete( colors[ i ] );
00361         if ( grLowColors[ i ] )
00362             delete( grLowColors[ i ] );
00363         if ( grHighColors[ i ] )
00364             delete( grHighColors[ i ] );
00365     }
00366     delete cache;
00367 }
00368 
00369 QImage* OThemeBase::loadImage( QString &name )
00370 {
00371     QImage * image = new QImage;
00372     QString path = configFilePath + "/pixmaps/" + name;
00373     image->load( path );
00374     if ( !image->isNull() )
00375         return ( image );
00376     odebug << "OThemeBase: Unable to load image " << name.ascii ( ) << oendl;
00377     delete image;
00378     return ( NULL );
00379 }
00380 
00381 OThemePixmap* OThemeBase::loadPixmap( QString &name )
00382 {
00383     OThemePixmap * pixmap = new OThemePixmap( false );
00384     QString path = configFilePath + "/pixmaps/" + name;
00385     pixmap->load( path );
00386     if ( !pixmap->isNull() )
00387         return pixmap;
00388     odebug << "OThemeBase: Unable to load pixmap " << name.ascii() << oendl;
00389     delete pixmap;
00390     return ( NULL );
00391 }
00392 
00393 OThemePixmap* OThemeBase::scale( int w, int h, WidgetType widget )
00394 {
00395     if ( scaleHints[ widget ] == FullScale ) {
00396         if ( !pixmaps[ widget ] || pixmaps[ widget ] ->width() != w ||
00397                 pixmaps[ widget ] ->height() != h ) {
00398             OThemePixmap * cachePix = cache->pixmap( w, h, widget );
00399             if ( cachePix ) {
00400                 cachePix = new OThemePixmap( *cachePix );
00401                 if ( pixmaps[ widget ] )
00402                     cache->insert( pixmaps[ widget ], OThemeCache::FullScale,
00403                                    widget );
00404                 else
00405                     odebug << "We would have inserted a null pixmap!\n" << oendl;
00406                 pixmaps[ widget ] = cachePix;
00407             }
00408             else {
00409                 cache->insert( pixmaps[ widget ], OThemeCache::FullScale, widget );
00410                 QImage tmpImg = images[ widget ] ->smoothScale( w, h );
00411                 pixmaps[ widget ] = new OThemePixmap;
00412                 pixmaps[ widget ] ->convertFromImage( tmpImg );
00413                 if ( blends[ widget ] != 0.0 )
00414                     blend( widget );
00415             }
00416         }
00417     }
00418     else if ( scaleHints[ widget ] == HorizontalScale ) {
00419         if ( pixmaps[ widget ] ->width() != w ) {
00420             OThemePixmap * cachePix = cache->horizontalPixmap( w, widget );
00421             if ( cachePix ) {
00422                 cachePix = new OThemePixmap( *cachePix );
00423                 if ( pixmaps[ widget ] )
00424                     cache->insert( pixmaps[ widget ], OThemeCache::HorizontalScale, widget );
00425                 else
00426                     odebug << "We would have inserted a null pixmap!" << oendl;
00427                 pixmaps[ widget ] = cachePix;
00428             }
00429             else {
00430                 cache->insert( pixmaps[ widget ], OThemeCache::HorizontalScale, widget );
00431                 QImage tmpImg = images[ widget ] ->
00432                                 smoothScale( w, images[ widget ] ->height() );
00433                 pixmaps[ widget ] = new OThemePixmap;
00434                 pixmaps[ widget ] ->convertFromImage( tmpImg );
00435                 if ( blends[ widget ] != 0.0 )
00436                     blend( widget );
00437             }
00438         }
00439     }
00440     else if ( scaleHints[ widget ] == VerticalScale ) {
00441         if ( pixmaps[ widget ] ->height() != h ) {
00442             OThemePixmap * cachePix = cache->verticalPixmap( w, widget );
00443             if ( cachePix ) {
00444                 cachePix = new OThemePixmap( *cachePix );
00445                 if ( pixmaps[ widget ] )
00446                     cache->insert( pixmaps[ widget ], OThemeCache::VerticalScale, widget );
00447                 else
00448                     odebug << "We would have inserted a null pixmap!" << oendl;
00449                 pixmaps[ widget ] = cachePix;
00450             }
00451             else {
00452                 cache->insert( pixmaps[ widget ], OThemeCache::VerticalScale, widget );
00453                 QImage tmpImg =
00454                     images[ widget ] ->smoothScale( images[ widget ] ->width(), h );
00455                 pixmaps[ widget ] = new OThemePixmap;
00456                 pixmaps[ widget ] ->convertFromImage( tmpImg );
00457                 if ( blends[ widget ] != 0.0 )
00458                     blend( widget );
00459             }
00460         }
00461     }
00462     // If blended tile here so the blend is scaled properly
00463     else if ( scaleHints[ widget ] == TileScale && blends[ widget ] != 0.0 ) {
00464         if ( !pixmaps[ widget ] || pixmaps[ widget ] ->width() != w ||
00465                 pixmaps[ widget ] ->height() != h ) {
00466             OThemePixmap * cachePix = cache->pixmap( w, h, widget );
00467             if ( cachePix ) {
00468                 cachePix = new OThemePixmap( *cachePix );
00469                 cache->insert( pixmaps[ widget ], OThemeCache::FullScale, widget );
00470                 pixmaps[ widget ] = cachePix;
00471             }
00472             else {
00473                 cache->insert( pixmaps[ widget ], OThemeCache::FullScale, widget );
00474                 QPixmap tile;
00475                 tile.convertFromImage( *images[ widget ] );
00476                 pixmaps[ widget ] = new OThemePixmap;
00477                 pixmaps[ widget ] ->resize( w, h );
00478                 QPainter p( pixmaps[ widget ] );
00479                 p.drawTiledPixmap( 0, 0, w, h, tile );
00480                 if ( blends[ widget ] != 0.0 )
00481                     blend( widget );
00482             }
00483         }
00484     }
00485     return ( pixmaps[ widget ] );
00486 }
00487 
00488 OThemePixmap* OThemeBase::scaleBorder( int w, int h, WidgetType widget )
00489 {
00490     OThemePixmap * pixmap = NULL;
00491     if ( !pbPixmaps[ widget ] && !pbWidth[ widget ] )
00492         return ( NULL );
00493     pixmap = cache->pixmap( w, h, widget, true );
00494     if ( pixmap ) {
00495         pixmap = new OThemePixmap( *pixmap );
00496     }
00497     else {
00498         pixmap = new OThemePixmap();
00499         pixmap->resize( w, h );
00500         QBitmap mask;
00501         mask.resize( w, h );
00502         mask.fill( color0 );
00503         QPainter mPainter;
00504         mPainter.begin( &mask );
00505 
00506         QPixmap *tmp = borderPixmap( widget ) ->border( OThemePixmap::TopLeft );
00507         const QBitmap *srcMask = tmp->mask();
00508         int bdWidth = tmp->width();
00509 
00510         bitBlt( pixmap, 0, 0, tmp, 0, 0, bdWidth, bdWidth,
00511                 Qt::CopyROP, false );
00512         if ( srcMask )
00513             bitBlt( &mask, 0, 0, srcMask, 0, 0, bdWidth, bdWidth,
00514                     Qt::CopyROP, false );
00515         else
00516             mPainter.fillRect( 0, 0, bdWidth, bdWidth, color1 );
00517 
00518 
00519         tmp = borderPixmap( widget ) ->border( OThemePixmap::TopRight );
00520         srcMask = tmp->mask();
00521         bitBlt( pixmap, w - bdWidth, 0, tmp, 0, 0, bdWidth,
00522                 bdWidth, Qt::CopyROP, false );
00523         if ( srcMask )
00524             bitBlt( &mask, w - bdWidth, 0, srcMask, 0, 0, bdWidth,
00525                     bdWidth, Qt::CopyROP, false );
00526         else
00527             mPainter.fillRect( w - bdWidth, 0, bdWidth, bdWidth, color1 );
00528 
00529         tmp = borderPixmap( widget ) ->border( OThemePixmap::BottomLeft );
00530         srcMask = tmp->mask();
00531         bitBlt( pixmap, 0, h - bdWidth, tmp, 0, 0, bdWidth,
00532                 bdWidth, Qt::CopyROP, false );
00533         if ( srcMask )
00534             bitBlt( &mask, 0, h - bdWidth, srcMask, 0, 0, bdWidth,
00535                     bdWidth, Qt::CopyROP, false );
00536         else
00537             mPainter.fillRect( 0, h - bdWidth, bdWidth, bdWidth, color1 );
00538 
00539         tmp = borderPixmap( widget ) ->border( OThemePixmap::BottomRight );
00540         srcMask = tmp->mask();
00541         bitBlt( pixmap, w - bdWidth, h - bdWidth, tmp, 0, 0,
00542                 bdWidth, bdWidth, Qt::CopyROP, false );
00543         if ( srcMask )
00544             bitBlt( &mask, w - bdWidth, h - bdWidth, srcMask, 0, 0,
00545                     bdWidth, bdWidth, Qt::CopyROP, false );
00546         else
00547             mPainter.fillRect( w - bdWidth, h - bdWidth, bdWidth, bdWidth, color1 );
00548 
00549         QPainter p;
00550         p.begin( pixmap );
00551         if ( w - bdWidth * 2 > 0 ) {
00552             tmp = borderPixmap( widget ) ->border( OThemePixmap::Top );
00553             srcMask = tmp->mask();
00554             p.drawTiledPixmap( bdWidth, 0, w - bdWidth * 2, bdWidth, *tmp );
00555             if ( srcMask )
00556                 mPainter.drawTiledPixmap( bdWidth, 0, w - bdWidth * 2, bdWidth, *srcMask );
00557             else
00558                 mPainter.fillRect( bdWidth, 0, w - bdWidth * 2, bdWidth, color1 );
00559 
00560             tmp = borderPixmap( widget ) ->border( OThemePixmap::Bottom );
00561             srcMask = tmp->mask();
00562             p.drawTiledPixmap( bdWidth, h - bdWidth, w - bdWidth * 2, bdWidth,
00563                                *tmp );
00564             if ( srcMask )
00565                 mPainter.drawTiledPixmap( bdWidth, h - bdWidth, w - bdWidth * 2, bdWidth, *srcMask );
00566             else
00567                 mPainter.fillRect( bdWidth, h - bdWidth, w - bdWidth * 2, bdWidth,
00568                                    color1 );
00569         }
00570         if ( h - bdWidth * 2 > 0 ) {
00571             tmp = borderPixmap( widget ) ->border( OThemePixmap::Left );
00572             srcMask = tmp->mask();
00573             p.drawTiledPixmap( 0, bdWidth, bdWidth, h - bdWidth * 2, *tmp );
00574             if ( srcMask )
00575                 mPainter.drawTiledPixmap( 0, bdWidth, bdWidth, h - bdWidth * 2, *srcMask );
00576             else
00577                 mPainter.fillRect( 0, bdWidth, bdWidth, h - bdWidth * 2, color1 );
00578 
00579             tmp = borderPixmap( widget ) ->border( OThemePixmap::Right );
00580             srcMask = tmp->mask();
00581             p.drawTiledPixmap( w - bdWidth, bdWidth, bdWidth, h - bdWidth * 2,
00582                                *tmp );
00583             if ( srcMask )
00584                 mPainter.drawTiledPixmap(  w - bdWidth, bdWidth,  bdWidth, h - bdWidth * 2, *srcMask );
00585             else
00586                 mPainter.fillRect( w - bdWidth, bdWidth, bdWidth, h - bdWidth * 2, color1 );
00587         }
00588         p.end();
00589         mPainter.end();
00590         pixmap->setMask( mask );
00591         cache->insert( pixmap, OThemeCache::FullScale, widget, true );
00592         if ( !pixmap->mask() )
00593             odebug << "No mask for border pixmap!" << oendl;
00594     }
00595     return ( pixmap );
00596 }
00597 
00598 
00599 OThemePixmap* OThemeBase::blend( WidgetType widget )
00600 {
00601     OGfxEffect::GradientType g;
00602     switch ( gradients[ widget ] ) {
00603         case GrHorizontal:
00604             g = OGfxEffect::HorizontalGradient;
00605             break;
00606         case GrVertical:
00607             g = OGfxEffect::VerticalGradient;
00608             break;
00609         case GrPyramid:
00610             g = OGfxEffect::PyramidGradient;
00611             break;
00612         case GrRectangle:
00613             g = OGfxEffect::RectangleGradient;
00614             break;
00615         case GrElliptic:
00616             g = OGfxEffect::EllipticGradient;
00617             break;
00618         default:
00619             g = OGfxEffect::DiagonalGradient;
00620             break;
00621     }
00622     OGfxEffect::blend( *pixmaps[ widget ], blends[ widget ], *grLowColors[ widget ],
00623                        g, false );
00624     return ( pixmaps[ widget ] );
00625 }
00626 
00627 OThemePixmap* OThemeBase::gradient( int w, int h, WidgetType widget )
00628 {
00629     if ( gradients[ widget ] == GrVertical ) {
00630         if ( !pixmaps[ widget ] || pixmaps[ widget ] ->height() != h ) {
00631             OThemePixmap * cachePix = cache->verticalPixmap( h, widget );
00632             if ( cachePix ) {
00633                 cachePix = new OThemePixmap( *cachePix );
00634                 if ( pixmaps[ widget ] )
00635                     cache->insert( pixmaps[ widget ], OThemeCache::VerticalScale,
00636                                    widget );
00637                 pixmaps[ widget ] = cachePix;
00638             }
00639             else {
00640                 if ( pixmaps[ widget ] )
00641                     cache->insert( pixmaps[ widget ], OThemeCache::VerticalScale,
00642                                    widget );
00643                 pixmaps[ widget ] = new OThemePixmap;
00644                 pixmaps[ widget ] ->resize( w, h );
00645                 OGfxEffect::gradient( *pixmaps[ widget ], *grHighColors[ widget ],
00646                                       *grLowColors[ widget ],
00647                                       OGfxEffect::VerticalGradient );
00648             }
00649         }
00650     }
00651     else if ( gradients[ widget ] == GrHorizontal ) {
00652         if ( !pixmaps[ widget ] || pixmaps[ widget ] ->width() != w ) {
00653             OThemePixmap * cachePix = cache->horizontalPixmap( w, widget );
00654             if ( cachePix ) {
00655                 cachePix = new OThemePixmap( *cachePix );
00656                 if ( pixmaps[ widget ] )
00657                     cache->insert( pixmaps[ widget ],
00658                                    OThemeCache::HorizontalScale, widget );
00659                 pixmaps[ widget ] = cachePix;
00660             }
00661             else {
00662                 if ( pixmaps[ widget ] )
00663                     cache->insert( pixmaps[ widget ],
00664                                    OThemeCache::HorizontalScale, widget );
00665                 pixmaps[ widget ] = new OThemePixmap;
00666                 pixmaps[ widget ] ->resize( w, h );
00667                 OGfxEffect::gradient( *pixmaps[ widget ], *grHighColors[ widget ],
00668                                       *grLowColors[ widget ],
00669                                       OGfxEffect::HorizontalGradient );
00670             }
00671         }
00672     }
00673     else if ( gradients[ widget ] == GrReverseBevel ) {
00674         if ( !pixmaps[ widget ] || pixmaps[ widget ] ->width() != w ||
00675                 pixmaps[ widget ] ->height() != h ) {
00676             OThemePixmap * cachePix = cache->pixmap( w, h, widget );
00677             if ( cachePix ) {
00678                 cachePix = new OThemePixmap( *cachePix );
00679                 if ( pixmaps[ widget ] )
00680                     cache->insert( pixmaps[ widget ], OThemeCache::FullScale,
00681                                    widget );
00682                 pixmaps[ widget ] = cachePix;
00683             }
00684             else {
00685                 if ( pixmaps[ widget ] )
00686                     cache->insert( pixmaps[ widget ], OThemeCache::FullScale,
00687                                    widget );
00688                 pixmaps[ widget ] = new OThemePixmap;
00689                 pixmaps[ widget ] ->resize( w, h );
00690 
00691                 QPixmap s;
00692                 int offset = decoWidth( widget );
00693                 s.resize( w - offset * 2, h - offset * 2 );
00694                 QColor lc( *grLowColors[ widget ] );
00695                 QColor hc( *grHighColors[ widget ] );
00696                 if ( bevelContrast( widget ) ) {
00697                     int bc = bevelContrast( widget );
00698                     // want single increments, not factors like light()/dark()
00699                     lc.setRgb( lc.red() - bc, lc.green() - bc, lc.blue() - bc );
00700                     hc.setRgb( hc.red() + bc, hc.green() + bc, hc.blue() + bc );
00701                 }
00702                 OGfxEffect::gradient( *pixmaps[ widget ],
00703                                       lc, hc,
00704                                       OGfxEffect::DiagonalGradient );
00705                 OGfxEffect::gradient( s, *grHighColors[ widget ],
00706                                       *grLowColors[ widget ],
00707                                       OGfxEffect::DiagonalGradient );
00708                 bitBlt( pixmaps[ widget ], offset, offset, &s, 0, 0, w - offset * 2,
00709                         h - offset * 2, Qt::CopyROP );
00710             }
00711         }
00712     }
00713     else {
00714         OGfxEffect::GradientType g;
00715         switch ( gradients[ widget ] ) {
00716             case GrPyramid:
00717                 g = OGfxEffect::PyramidGradient;
00718                 break;
00719             case GrRectangle:
00720                 g = OGfxEffect::RectangleGradient;
00721                 break;
00722             case GrElliptic:
00723                 g = OGfxEffect::EllipticGradient;
00724                 break;
00725             default:
00726                 g = OGfxEffect::DiagonalGradient;
00727                 break;
00728         }
00729         if ( !pixmaps[ widget ] || pixmaps[ widget ] ->width() != w ||
00730                 pixmaps[ widget ] ->height() != h ) {
00731             OThemePixmap * cachePix = cache->pixmap( w, h, widget );
00732             if ( cachePix ) {
00733                 cachePix = new OThemePixmap( *cachePix );
00734                 if ( pixmaps[ widget ] )
00735                     cache->insert( pixmaps[ widget ], OThemeCache::FullScale,
00736                                    widget );
00737                 pixmaps[ widget ] = cachePix;
00738             }
00739             else {
00740                 if ( pixmaps[ widget ] )
00741                     cache->insert( pixmaps[ widget ], OThemeCache::FullScale,
00742                                    widget );
00743                 pixmaps[ widget ] = new OThemePixmap;
00744                 pixmaps[ widget ] ->resize( w, h );
00745                 OGfxEffect::gradient( *pixmaps[ widget ], *grHighColors[ widget ],
00746                                       *grLowColors[ widget ], g );
00747             }
00748         }
00749     }
00750     return ( pixmaps[ widget ] );
00751 }
00752 
00753 OThemePixmap* OThemeBase::scalePixmap( int w, int h, WidgetType widget )
00754 {
00755 
00756     if ( gradients[ widget ] && blends[ widget ] == 0.0 )
00757         return ( gradient( w, h, widget ) );
00758 
00759     return ( scale( w, h, widget ) );
00760 }
00761 
00762 QColorGroup* OThemeBase::makeColorGroup( QColor &fg, QColor &bg,
00763         Qt::GUIStyle )
00764 {
00765     if ( shading == Motif ) {
00766         int highlightVal, lowlightVal;
00767         highlightVal = 100 + ( 2* /*KGlobalSettings::contrast()*/ 3 + 4 ) * 16 / 10;
00768         lowlightVal = 100 + ( ( 2* /*KGlobalSettings::contrast()*/ 3 + 4 ) * 10 );
00769         return ( new QColorGroup( fg, bg, bg.light( highlightVal ),
00770                                   bg.dark( lowlightVal ), bg.dark( 120 ),
00771                                   fg, qApp->palette().normal().base() ) );
00772     }
00773     else
00774         return ( new QColorGroup( fg, bg, bg.light( 150 ), bg.dark(),
00775                                   bg.dark( 120 ), fg,
00776                                   qApp->palette().normal().base() ) );
00777 }
00778 
00779 static QColor strToColor ( const QString &str )
00780 {
00781     QString str2 = str. stripWhiteSpace ( );
00782 
00783     if ( str2 [0] == '#' )
00784         return QColor ( str2 );
00785     else {
00786         QStringList sl = QStringList::split ( ',', str2 );
00787 
00788         if ( sl. count ( ) >= 3 )
00789             return QColor ( sl [0]. toInt ( ), sl [1]. toInt ( ), sl [2]. toInt ( ));
00790     }
00791     return QColor ( 0, 0, 0 );
00792 }
00793 
00794 
00795 
00796 void OThemeBase::applyMiscResourceGroup( Config *config )
00797 {
00798     config-> setGroup ( "Misc" );
00799     QString tmpStr;
00800 
00801     tmpStr = config->readEntry( "SButtonPosition" );
00802     if ( tmpStr == "BottomLeft" )
00803         sbPlacement = SBBottomLeft;
00804     else if ( tmpStr == "BottomRight" )
00805         sbPlacement = SBBottomRight;
00806     else {
00807         if ( tmpStr != "Opposite" && !tmpStr.isEmpty() )
00808             odebug << "OThemeBase: Unrecognized sb button option " << tmpStr.ascii()
00809                    << ", using Opposite." << oendl;
00810         sbPlacement = SBOpposite;
00811     }
00812     tmpStr = config->readEntry( "ArrowType" );
00813     if ( tmpStr == "Small" )
00814         arrowStyle = SmallArrow;
00815     else if ( tmpStr == "3D" )
00816         arrowStyle = MotifArrow;
00817     else {
00818         if ( tmpStr != "Normal" && !tmpStr.isEmpty() )
00819             odebug << "OThemeBase: Unrecognized arrow option " << tmpStr.ascii()
00820                    << ", using Normal." << oendl;
00821         arrowStyle = LargeArrow;
00822     }
00823     tmpStr = config->readEntry( "ShadeStyle" );
00824     if ( tmpStr == "Motif" )
00825         shading = Motif;
00826     else if ( tmpStr == "Next" )
00827         shading = Next;
00828     else if ( tmpStr == "KDE" )
00829         shading = KDE;
00830     else
00831         shading = Windows;
00832 
00833     defaultFrame = config->readNumEntry( "FrameWidth", 2 );
00834     cacheSize = config->readNumEntry( "Cache", 1024 );
00835     sbExtent = config->readNumEntry( "ScrollBarExtent", 16 );
00836 
00837     config-> setGroup ( "General" );
00838 
00839     if ( config-> hasKey ( "foreground" ))        fgcolor    = strToColor ( config-> readEntry ( "foreground" ));
00840     if ( config-> hasKey ( "background" ))        bgcolor    = strToColor ( config-> readEntry ( "background" ));
00841     if ( config-> hasKey ( "selectForeground" ))  selfgcolor = strToColor ( config-> readEntry ( "selectForeground" ));
00842     if ( config-> hasKey ( "selectBackground" ))  selbgcolor = strToColor ( config-> readEntry ( "selectBackground" ));
00843     if ( config-> hasKey ( "windowForeground" ))  winfgcolor = strToColor ( config-> readEntry ( "windowForeground" ));
00844     if ( config-> hasKey ( "windowBackground" ))  winbgcolor = strToColor ( config-> readEntry ( "windowBackground" ));
00845 }
00846 
00847 void OThemeBase::readMiscResourceGroup()
00848 {}
00849 
00850 void OThemeBase::applyResourceGroup( Config *config, int i, QString *copyfrom, QString *pixnames, QString *brdnames )
00851 {
00852     QString tmpStr;
00853 
00854     config-> setGroup ( widgetEntries [ i ] );
00855 
00856     tmpStr = config->readEntry( "CopyWidget", "" );
00857     copyfrom [ i ] = tmpStr;
00858     if ( !tmpStr.isEmpty() )
00859         return ;
00860 
00861     // Scale hint
00862     tmpStr = config->readEntry( "Scale" );
00863     if ( tmpStr == "Full" )
00864         scaleHints [ i ] = FullScale;
00865     else if ( tmpStr == "Horizontal" )
00866         scaleHints [ i ] = HorizontalScale;
00867     else if ( tmpStr == "Vertical" )
00868         scaleHints [ i ] = VerticalScale;
00869     else {
00870         if ( tmpStr != "Tile" && !tmpStr.isEmpty() )
00871             odebug << "OThemeBase: Unrecognized scale option " << tmpStr.ascii()
00872                    << ", using Tile." << oendl;
00873         scaleHints [ i ] = TileScale;
00874     }
00875 
00876 
00877     // Gradient type
00878     tmpStr = config->readEntry( "Gradient" );
00879     if ( tmpStr == "Diagonal" )
00880         gradients [ i ] = GrDiagonal;
00881     else if ( tmpStr == "Horizontal" )
00882         gradients [ i ] = GrHorizontal;
00883     else if ( tmpStr == "Vertical" )
00884         gradients [ i ] = GrVertical;
00885     else if ( tmpStr == "Pyramid" )
00886         gradients [ i ] = GrPyramid;
00887     else if ( tmpStr == "Rectangle" )
00888         gradients [ i ] = GrRectangle;
00889     else if ( tmpStr == "Elliptic" )
00890         gradients [ i ] = GrElliptic;
00891     else if ( tmpStr == "ReverseBevel" )
00892         gradients [ i ] = GrReverseBevel;
00893     else {
00894         if ( tmpStr != "None" && !tmpStr.isEmpty() )
00895             odebug << "OThemeBase: Unrecognized gradient option " << tmpStr.ascii()
00896                    << ", using None." << oendl;
00897         gradients [ i ] = GrNone;
00898     }
00899 
00900     // Blend intensity
00901     blends[ i ] = config->readEntry( "BlendIntensity", "0.0" ).toDouble();
00902 
00903     // Bevel contrast
00904     bContrasts[ i ] = config->readNumEntry( "BevelContrast", 0 );
00905 
00906     // Border width
00907     borders [ i ] = config->readNumEntry( "Border", 1 );
00908 
00909     // Highlight width
00910     highlights [ i ] = config->readNumEntry( "Highlight", 1 );
00911 
00912     // Gradient low color or blend background
00913     if ( config->hasKey( "GradientLow" ) && ( gradients[ i ] != GrNone || blends[ i ] != 0.0 ))
00914         grLowColors[ i ] = new QColor( strToColor ( config->readEntry( "GradientLow", qApp->palette().normal().background().name() )));
00915     else
00916         grLowColors[ i ] = NULL;
00917 
00918 
00919     // Gradient high color
00920     if ( config->hasKey( "GradientHigh" ) && ( gradients[ i ] != GrNone ))
00921         grHighColors[ i ] = new QColor( strToColor ( config->readEntry( "GradientHigh", qApp->palette().normal().background().name() )));
00922     else
00923         grHighColors[ i ] = NULL;
00924 
00925     // Extended color attributes
00926     if ( config->hasKey( "Foreground" ) || config->hasKey( "Background" ) ) {
00927         QColor bg = strToColor( config->readEntry( "Background", qApp->palette().normal().background().name() ));
00928         QColor fg = strToColor( config->readEntry( "Foreground", qApp->palette().normal().foreground().name() ));
00929 
00930         colors[ i ] = makeColorGroup( fg, bg, Qt::WindowsStyle );
00931     }
00932     else
00933         colors[ i ] = NULL;
00934 
00935     // Pixmap
00936     tmpStr = config->readEntry( "Pixmap", "" );
00937     pixnames[ i ] = tmpStr;
00938     duplicate[ i ] = false;
00939     pixmaps[ i ] = NULL;
00940     images[ i ] = NULL;
00941 
00942 
00943     // Pixmap border
00944     tmpStr = config->readEntry( "PixmapBorder", "" );
00945     brdnames[ i ] = tmpStr;
00946     pbDuplicate[ i ] = false;
00947     pbPixmaps[ i ] = NULL;
00948     pbWidth[ i ] = 0;
00949     if ( !tmpStr.isEmpty() ) {
00950         pbWidth[ i ] = config->readNumEntry( "PixmapBWidth", 0 );
00951         if ( pbWidth[ i ] == 0 ) {
00952             odebug << "OThemeBase: No border width specified for pixmapped border widget "
00953                    << widgetEntries[ i ] << oendl;
00954             odebug << "OThemeBase: Using default of 2." << oendl;
00955             pbWidth[ i ] = 2;
00956         }
00957     }
00958 
00959 
00960     // Various widget specific settings. This was more efficent when bunched
00961     // together in the misc group, but this makes an easier to read config.
00962     if ( i == SliderGroove )
00963         roundedSlider = config->readBoolEntry( "SmallGroove", false );
00964     else if ( i == ActiveTab ) {
00965         aTabLine = config->readBoolEntry( "BottomLine", true );
00966     }
00967     else if ( i == InactiveTab ) {
00968         iTabLine = config->readBoolEntry( "BottomLine", true );
00969     }
00970     else if ( i == Splitter )
00971         splitterWidth = config->readNumEntry( "Width", 10 );
00972     else if ( i == ComboBox || i == ComboBoxDown ) {
00973         roundedCombo = config->readBoolEntry( "Round", false );
00974     }
00975     else if ( i == PushButton || i == PushButtonDown ) {
00976         btnXShift = config->readNumEntry( "XShift", 0 );
00977         btnYShift = config->readNumEntry( "YShift", 0 );
00978         focus3D = config->readBoolEntry( "3DFocusRect", false );
00979         focus3DOffset = config->readBoolEntry( "3DFocusOffset", 0 );
00980         roundedButton = config->readBoolEntry( "Round", false );
00981     }
00982 }
00983 
00984 
00985 void OThemeBase::readResourceGroup( int i, QString *copyfrom, QString *pixnames, QString *brdnames,
00986                                     bool *loadArray )
00987 {
00988     if ( loadArray[ i ] == true ) {
00989         return ; // already been preloaded.
00990     }
00991 
00992     int tmpVal;
00993     QString tmpStr;
00994 
00995     tmpStr = copyfrom [ i ];
00996     if ( !tmpStr.isEmpty() ) { // Duplicate another widget's config
00997         int sIndex;
00998         loadArray[ i ] = true;
00999         for ( sIndex = 0; sIndex < WIDGETS; ++sIndex ) {
01000             if ( tmpStr == widgetEntries[ sIndex ] ) {
01001                 if ( !loadArray[ sIndex ] )  // hasn't been loaded yet
01002                     readResourceGroup( sIndex, copyfrom, pixnames, brdnames,
01003                                        loadArray );
01004                 break;
01005             }
01006         }
01007         if ( loadArray[ sIndex ] ) {
01008             copyWidgetConfig( sIndex, i, pixnames, brdnames );
01009         }
01010         else
01011             odebug << "OThemeBase: Unable to identify source widget for " << widgetEntries[ i ] << oendl;
01012         return ;
01013     }
01014     // special inheritance for disabled arrows (these are tri-state unlike
01015     // the rest of what we handle).
01016     for ( tmpVal = DisArrowUp; tmpVal <= DisArrowRight; ++tmpVal ) {
01017         if ( tmpVal == i ) {
01018             tmpStr = pixnames [ i ];
01019             if ( tmpStr.isEmpty() ) {
01020                 copyWidgetConfig( ArrowUp + ( tmpVal - DisArrowUp ), i, pixnames,
01021                                   brdnames );
01022                 return ;
01023             }
01024         }
01025     }
01026 
01027     // Pixmap
01028     int existing;
01029     // Scan for duplicate pixmaps(two identical pixmaps, tile scale, no blend,
01030     // no pixmapped border)
01031     if ( !pixnames [ i ].isEmpty() ) {
01032         for ( existing = 0; existing < i; ++existing ) {
01033             if ( pixnames[ i ] == pixnames[ existing ] && scaleHints[ i ] == TileScale &&
01034                     scaleHints[ existing ] == TileScale && blends[ existing ] == 0.0 &&
01035                     blends[ i ] == 0.0 ) {
01036                 pixmaps[ i ] = pixmaps[ existing ];
01037                 duplicate[ i ] = true;
01038                 break;
01039             }
01040         }
01041     }
01042     // load
01043     if ( !duplicate[ i ] && !pixnames[ i ].isEmpty() ) {
01044         pixmaps[ i ] = loadPixmap( pixnames[ i ] );
01045         // load and save images for scaled/blended widgets for speed.
01046         if ( scaleHints[ i ] == TileScale && blends[ i ] == 0.0 )
01047             images[ i ] = NULL;
01048         else
01049             images[ i ] = loadImage( pixnames[ i ] );
01050     }
01051 
01052     // Pixmap border
01053     if ( !brdnames [ i ]. isEmpty () ) {
01054         // duplicate check
01055         for ( existing = 0; existing < i; ++existing ) {
01056             if ( brdnames [i] == brdnames[ existing ] ) {
01057                 pbPixmaps[ i ] = pbPixmaps[ existing ];
01058                 pbDuplicate[ i ] = true;
01059                 break;
01060             }
01061         }
01062     }
01063     // load
01064     if ( !pbDuplicate[ i ] && !brdnames[ i ].isEmpty() )
01065         pbPixmaps[ i ] = loadPixmap( brdnames[ i ] );
01066 
01067     if ( pbPixmaps[ i ] && !pbDuplicate[ i ] )
01068         generateBorderPix( i );
01069 
01070     loadArray[ i ] = true;
01071 }
01072 
01073 
01074 OThemePixmap::OThemePixmap( bool timer )
01075         : QPixmap()
01076 {
01077     if(timer){
01078        t = new QTime;
01079         t->start();
01080     }
01081     else
01082         t = NULL;
01083     int i;
01084     for ( i = 0; i < 8; ++i )
01085         b[ i ] = NULL;
01086 }
01087 
01088 OThemePixmap::OThemePixmap( const OThemePixmap &p )
01089         : QPixmap( p )
01090 {
01091     if(p.t){
01092         t = new QTime;
01093         t->start();
01094     }
01095     else
01096         t = NULL;
01097     int i;
01098     for ( i = 0; i < 8; ++i )
01099         if ( p.b[ i ] )
01100             b[ i ] = new QPixmap( *p.b[ i ] );
01101         else
01102             b[ i ] = NULL;
01103 }
01104 
01105 
01106 
01107 OThemePixmap::~OThemePixmap()
01108 {
01109     if(t)
01110         delete t;
01111     int i;
01112     for ( i = 0; i < 8; ++i )
01113         if ( b[ i ] )
01114             delete b[ i ];
01115 }
01116 
01117 OThemeCache::OThemeCache( int maxSize, QObject *parent, const char *name )
01118         : QObject( parent, name )
01119 {
01120     cache.setMaxCost( maxSize * 1024 );
01121     cache.setAutoDelete( true );
01122     flushTimer.start(300000); // 5 minutes
01123     connect(&flushTimer, SIGNAL(timeout()), SLOT(flushTimeout()));
01124 }
01125 
01126 void OThemeCache::flushTimeout()
01127 {
01128     QIntCacheIterator<OThemePixmap> it( cache );
01129     while ( it.current() ) {
01130         if ( it.current() ->isOld() )
01131             cache.remove( it.currentKey() );
01132         else
01133             ++it;
01134     }
01135 }
01136 
01137 OThemePixmap* OThemeCache::pixmap( int w, int h, int widgetID, bool border,
01138                                    bool mask )
01139 {
01140 
01141     kthemeKey key;
01142     key.cacheKey = 0; // shut up, gcc
01143     key.data.id = widgetID;
01144     key.data.width = w;
01145     key.data.height = h;
01146     key.data.border = border;
01147     key.data.mask = mask;
01148 
01149     OThemePixmap *pix = cache.find( ( unsigned long ) key.cacheKey );
01150     if ( pix )
01151         pix->updateAccessed();
01152     return ( pix );
01153 }
01154 
01155 OThemePixmap* OThemeCache::horizontalPixmap( int w, int widgetID )
01156 {
01157     kthemeKey key;
01158     key.cacheKey = 0; // shut up, gcc
01159     key.data.id = widgetID;
01160     key.data.width = w;
01161     key.data.height = 0;
01162     key.data.border = false;
01163     key.data.mask = false;
01164     OThemePixmap *pix = cache.find( ( unsigned long ) key.cacheKey );
01165     if ( pix )
01166         pix->updateAccessed();
01167     return ( pix );
01168 }
01169 
01170 OThemePixmap* OThemeCache::verticalPixmap( int h, int widgetID )
01171 {
01172     kthemeKey key;
01173     key.cacheKey = 0; // shut up, gcc
01174     key.data.id = widgetID;
01175     key.data.width = 0;
01176     key.data.height = h;
01177     key.data.border = false;
01178     key.data.mask = false;
01179     OThemePixmap *pix = cache.find( ( unsigned long ) key.cacheKey );
01180     if ( pix )
01181         pix->updateAccessed();
01182     return ( pix );
01183 }
01184 
01185 bool OThemeCache::insert( OThemePixmap *pixmap, ScaleHint scale, int widgetID,
01186                           bool border, bool mask )
01187 {
01188     kthemeKey key;
01189     key.cacheKey = 0; // shut up, gcc
01190     key.data.id = widgetID;
01191     key.data.width = ( scale == FullScale || scale == HorizontalScale ) ?
01192                      pixmap->width() : 0;
01193     key.data.height = ( scale == FullScale || scale == VerticalScale ) ?
01194                       pixmap->height() : 0;
01195     key.data.border = border;
01196     key.data.mask = mask;
01197 
01198     if ( cache.find( ( unsigned long ) key.cacheKey, true ) != NULL ) {
01199         return ( true ); // a pixmap of this scale is already in there
01200     }
01201     return ( cache.insert( ( unsigned long ) key.cacheKey, pixmap,
01202                            pixmap->width() * pixmap->height() * pixmap->depth() / 8 ) );
01203 }
01204 
01205 //#include "kthemebase.moc"

Generated on Sat Nov 5 16:17:59 2005 for OPIE by  doxygen 1.4.2