summaryrefslogtreecommitdiffstats
path: root/kstyles/kthemestyle/kthemebase.cpp
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commitce4a32fe52ef09d8f5ff1dd22c001110902b60a2 (patch)
tree5ac38a06f3dde268dc7927dc155896926aaf7012 /kstyles/kthemestyle/kthemebase.cpp
downloadtdelibs-ce4a32fe52ef09d8f5ff1dd22c001110902b60a2.tar.gz
tdelibs-ce4a32fe52ef09d8f5ff1dd22c001110902b60a2.zip
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdelibs@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kstyles/kthemestyle/kthemebase.cpp')
-rw-r--r--kstyles/kthemestyle/kthemebase.cpp1826
1 files changed, 1826 insertions, 0 deletions
diff --git a/kstyles/kthemestyle/kthemebase.cpp b/kstyles/kthemestyle/kthemebase.cpp
new file mode 100644
index 000000000..bd463e28e
--- /dev/null
+++ b/kstyles/kthemestyle/kthemebase.cpp
@@ -0,0 +1,1826 @@
+/*
+ $Id$
+
+ This file is part of the KDE libraries
+ Copyright (C) 1999 Daniel M. Duley <mosfet@kde.org>
+
+ KDE3 port (C) 2001-2002 Maksim Orlovich <mo002j@mail.rochester.edu>
+ Port version 0.9.7
+
+ Palette setup code is from KApplication,
+ Copyright (C) 1997 Matthias Kalle Dalheimer (kalle@kde.org)
+ Copyright (C) 1998, 1999, 2000 KDE Team
+
+ Includes code portions from the KDE HighColor style.
+
+ KDE3 HighColor Style
+ Copyright (C) 2001 Karol Szwed <gallium@kde.org>
+ (C) 2001 Fredrik Höglund <fredrik@kde.org>
+
+ Drawing routines adapted from the KDE2 HCStyle,
+ Copyright (C) 2000 Daniel M. Duley <mosfet@kde.org>
+ (C) 2000 Dirk Mueller <mueller@kde.org>
+ (C) 2001 Martijn Klingens <klingens@kde.org>
+
+
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "kthemebase.h"
+#include <kpixmapeffect.h>
+#include <qimage.h>
+#include <qpainter.h>
+#include <qbitmap.h>
+#include <stdlib.h>
+
+#include <qsettings.h>
+#include <qapplication.h>
+#include <qscrollbar.h>
+
+typedef QMap<QString, QString> Prop;
+
+template class QIntCache<KThemePixmap>
+;
+
+/*
+Bugs:
+Can't delete old slider image when calculating the rotated one for some reason.
+*/
+
+//Shamelessly stolen from KConfigBase
+static QColor readColorEntry( QSettings* s, const char *pKey,
+ const QColor* pDefault )
+{
+ QColor aRetColor;
+ int nRed = 0, nGreen = 0, nBlue = 0;
+
+ QString aValue = s->readEntry( pKey );
+ if ( !aValue.isEmpty() )
+ {
+ if ( aValue.at( 0 ) == '#' )
+ {
+ aRetColor.setNamedColor( aValue );
+ }
+ else
+ {
+ bool bOK;
+ // find first part (red)
+ int nIndex = aValue.find( ',' );
+ if ( nIndex == -1 )
+ {
+ // return a sensible default -- Bernd
+ if ( pDefault )
+ aRetColor = *pDefault;
+ return aRetColor;
+ }
+
+ nRed = aValue.left( nIndex ).toInt( &bOK );
+
+ // find second part (green)
+ int nOldIndex = nIndex;
+ nIndex = aValue.find( ',', nOldIndex + 1 );
+
+ if ( nIndex == -1 )
+ {
+ // return a sensible default -- Bernd
+ if ( pDefault )
+ aRetColor = *pDefault;
+ return aRetColor;
+ }
+ nGreen = aValue.mid( nOldIndex + 1,
+ nIndex - nOldIndex - 1 ).toInt( &bOK );
+
+ // find third part (blue)
+ nBlue = aValue.right( aValue.length() - nIndex - 1 ).toInt( &bOK );
+
+ aRetColor.setRgb( nRed, nGreen, nBlue );
+ }
+ }
+ else
+ {
+
+ if ( pDefault )
+ aRetColor = *pDefault;
+ }
+
+ return aRetColor;
+}
+
+
+static const char * const widgetEntries[] =
+ { // unsunken widgets (see header)
+ "PushButton", "ComboBox", "HSBarSlider", "VSBarSlider", "Bevel", "ToolButton",
+ "ScrollButton", "HScrollDeco", "VScrollDeco", "ComboDeco", "MenuItem", "Tab",
+ "ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight",
+ // sunken widgets
+ "PushButtonDown", "ComboBoxDown", "HSBarSliderDown", "VSBarSliderDown",
+ "BevelDown", "ToolButtonDown", "ScrollButtonDown", "HScrollDecoDown",
+ "VScrollDecoDown", "ComboDecoDown", "MenuItemDown", "TabDown", "SunkenArrowUp",
+ "SunkenArrowDown", "SunkenArrowLeft", "SunkenArrowRight",
+ // everything else
+ "HScrollGroove", "VScrollGroove", "Slider", "SliderGroove", "CheckBoxDown",
+ "CheckBox", "CheckBoxTri", "RadioDown", "Radio", "HBarHandle", "VBarHandle",
+ "ToolBar", "Splitter", "CheckMark", "MenuBar", "DisableArrowUp",
+ "DisableArrowDown", "DisableArrowLeft", "DisableArrowRight", "ProgressBar",
+ "ProgressBackground", "MenuBarItem", "Background", "RotSlider",
+ "RotInactiveTab", "RotActiveTab",
+ };
+
+#define INHERIT_ITEMS 16
+
+
+class KThemeBasePrivate
+{
+public:
+ /** Color overrides flags..*/
+ bool overrideForeground;
+ bool overrideBackground;
+ bool overrideSelectForeground;
+ bool overrideSelectBackground;
+ bool overrideWindowForeground;
+ bool overrideWindowBackground;
+
+ /**
+ * Colors to override defaults with..
+ */
+ QColor overrideForegroundCol;
+ QColor overrideBackgroundCol;
+ QColor overrideSelectForegroundCol;
+ QColor overrideSelectBackgroundCol;
+ QColor overrideWindowForegroundCol;
+ QColor overrideWindowBackgroundCol;
+
+ int contrast;
+
+
+ QMap <QString, QMap<QString, QString> > props;
+
+ QMap<const QPixmap*, QColor> colorCache;
+
+ /*
+ A heuristic routine that tries to determine the avergae color of the image
+ Wouldn't work for things like sliders, etc.
+ */
+ QColor pixmapAveColor( const QPixmap* p )
+ {
+ if ( colorCache.contains( p ) )
+ return colorCache[ p ];
+
+ QImage to_ave = p->convertToImage();
+ double h = 0, s = 0, v = 0;
+ int count = 0;
+ int dh, ds, dv;
+ for ( int x = 0; x < p->width(); x++ )
+ {
+ QColor pix( to_ave.pixel( x, p->height() / 2 ) );
+ pix.hsv( &dh, &ds, &dv );
+ h += dh;
+ s += ds;
+ v += dv;
+ count++;
+ }
+
+ for ( int y = 0; y < p->height(); y++ )
+ {
+ QColor pix( to_ave.pixel( p->width() / 2, y ) );
+ pix.hsv( &dh, &ds, &dv );
+ h += dh;
+ s += ds;
+ v += dv;
+ count++;
+ }
+ colorCache[ p ] = QColor( int( h / count + 0.5 ), int( s / count + 0.5 ), int( v / count + 0.5 ), QColor::Hsv );
+ return colorCache[ p ];
+ }
+};
+
+
+
+// This is used to encode the keys. I used to use masks but I think this
+// bitfield is nicer :) I don't know why C++ coders don't use these more..
+// (mosfet)
+struct kthemeKeyData
+{
+unsigned int id :
+ 6;
+unsigned int width :
+ 12;
+unsigned int height :
+ 12;
+unsigned int border :
+ 1;
+unsigned int mask :
+ 1;
+};
+
+union kthemeKey{
+ kthemeKeyData data;
+ unsigned int cacheKey;
+};
+
+void KThemeBase::generateBorderPix( int i )
+{
+ // separate pixmap into separate components
+ if ( pbPixmaps[ i ] )
+ {
+ // evidently I have to do masks manually...
+ const QBitmap * srcMask = pbPixmaps[ i ] ->mask();
+ QBitmap destMask( pbWidth[ i ], pbWidth[ i ] );
+ QPixmap tmp( pbWidth[ i ], pbWidth[ i ] );
+
+ bitBlt( &tmp, 0, 0, pbPixmaps[ i ], 0, 0, pbWidth[ i ], pbWidth[ i ],
+ Qt::CopyROP, false );
+ if ( srcMask )
+ {
+ bitBlt( &destMask, 0, 0, srcMask, 0, 0, pbWidth[ i ], pbWidth[ i ],
+ Qt::CopyROP, false );
+ tmp.setMask( destMask );
+ }
+ pbPixmaps[ i ] ->setBorder( KThemePixmap::TopLeft, tmp );
+
+ bitBlt( &tmp, 0, 0, pbPixmaps[ i ], pbPixmaps[ i ] ->width() - pbWidth[ i ], 0,
+ pbWidth[ i ], pbWidth[ i ], Qt::CopyROP, false );
+ if ( srcMask )
+ {
+ bitBlt( &destMask, 0, 0, srcMask, pbPixmaps[ i ] ->width() - pbWidth[ i ],
+ 0, pbWidth[ i ], pbWidth[ i ], Qt::CopyROP, false );
+ tmp.setMask( destMask );
+ }
+ pbPixmaps[ i ] ->setBorder( KThemePixmap::TopRight, tmp );
+
+ bitBlt( &tmp, 0, 0, pbPixmaps[ i ], 0, pbPixmaps[ i ] ->height() - pbWidth[ i ],
+ pbWidth[ i ], pbWidth[ i ], Qt::CopyROP, false );
+ if ( srcMask )
+ {
+ bitBlt( &destMask, 0, 0, srcMask, 0, pbPixmaps[ i ] ->height() - pbWidth[ i ],
+ pbWidth[ i ], pbWidth[ i ], Qt::CopyROP, false );
+ tmp.setMask( destMask );
+ }
+ pbPixmaps[ i ] ->setBorder( KThemePixmap::BottomLeft, tmp );
+
+ bitBlt( &tmp, 0, 0, pbPixmaps[ i ], pbPixmaps[ i ] ->width() - pbWidth[ i ],
+ pbPixmaps[ i ] ->height() - pbWidth[ i ], pbWidth[ i ], pbWidth[ i ],
+ Qt::CopyROP, false );
+ if ( srcMask )
+ {
+ bitBlt( &destMask, 0, 0, srcMask, pbPixmaps[ i ] ->width() - pbWidth[ i ],
+ pbPixmaps[ i ] ->height() - pbWidth[ i ], pbWidth[ i ], pbWidth[ i ],
+ Qt::CopyROP, false );
+ tmp.setMask( destMask );
+ }
+ pbPixmaps[ i ] ->setBorder( KThemePixmap::BottomRight, tmp );
+
+ tmp.resize( pbPixmaps[ i ] ->width() - pbWidth[ i ] * 2, pbWidth[ i ] );
+ destMask.resize( pbPixmaps[ i ] ->width() - pbWidth[ i ] * 2, pbWidth[ i ] );
+ bitBlt( &tmp, 0, 0, pbPixmaps[ i ], pbWidth[ i ], 0,
+ pbPixmaps[ i ] ->width() - pbWidth[ i ] * 2, pbWidth[ i ], Qt::CopyROP, false );
+ if ( srcMask )
+ {
+ bitBlt( &destMask, 0, 0, srcMask, pbWidth[ i ], 0,
+ pbPixmaps[ i ] ->width() - pbWidth[ i ] * 2, pbWidth[ i ],
+ Qt::CopyROP, false );
+ tmp.setMask( destMask );
+ }
+ pbPixmaps[ i ] ->setBorder( KThemePixmap::Top, tmp );
+
+ bitBlt( &tmp, 0, 0, pbPixmaps[ i ], pbWidth[ i ],
+ pbPixmaps[ i ] ->height() - pbWidth[ i ],
+ pbPixmaps[ i ] ->width() - pbWidth[ i ] * 2, pbWidth[ i ], Qt::CopyROP, false );
+ if ( srcMask )
+ {
+ bitBlt( &destMask, 0, 0, srcMask, pbWidth[ i ],
+ pbPixmaps[ i ] ->height() - pbWidth[ i ],
+ pbPixmaps[ i ] ->width() - pbWidth[ i ] * 2, pbWidth[ i ], Qt::CopyROP, false );
+ tmp.setMask( destMask );
+ }
+ pbPixmaps[ i ] ->setBorder( KThemePixmap::Bottom, tmp );
+
+ tmp.resize( pbWidth[ i ], pbPixmaps[ i ] ->height() - pbWidth[ i ] * 2 );
+ destMask.resize( pbWidth[ i ], pbPixmaps[ i ] ->height() - pbWidth[ i ] * 2 );
+ bitBlt( &tmp, 0, 0, pbPixmaps[ i ], 0, pbWidth[ i ], pbWidth[ i ],
+ pbPixmaps[ i ] ->height() - pbWidth[ i ] * 2, Qt::CopyROP, false );
+ if ( srcMask )
+ {
+ bitBlt( &destMask, 0, 0, srcMask, 0, pbWidth[ i ], pbWidth[ i ],
+ pbPixmaps[ i ] ->height() - pbWidth[ i ] * 2, Qt::CopyROP, false );
+ tmp.setMask( destMask );
+ }
+
+ pbPixmaps[ i ] ->setBorder( KThemePixmap::Left, tmp );
+
+ bitBlt( &tmp, 0, 0, pbPixmaps[ i ], pbPixmaps[ i ] ->width() - pbWidth[ i ],
+ pbWidth[ i ], pbWidth[ i ], pbPixmaps[ i ] ->height() - pbWidth[ i ] * 2,
+ Qt::CopyROP, false );
+ if ( srcMask )
+ {
+ bitBlt( &destMask, 0, 0, srcMask, pbPixmaps[ i ] ->width() - pbWidth[ i ],
+ pbWidth[ i ], pbWidth[ i ], pbPixmaps[ i ] ->height() - pbWidth[ i ] * 2,
+ Qt::CopyROP, false );
+ tmp.setMask( destMask );
+ }
+ pbPixmaps[ i ] ->setBorder( KThemePixmap::Right, tmp );
+ }
+ else
+ qWarning( "KThemeBase: Tried making border from empty pixmap\n" );
+}
+
+
+void KThemeBase::copyWidgetConfig( int sourceID, int destID, QString *pixnames,
+ QString *brdnames )
+{
+ scaleHints[ destID ] = scaleHints[ sourceID ];
+ gradients[ destID ] = gradients[ sourceID ];
+ blends[ destID ] = blends[ sourceID ];
+ bContrasts[ destID ] = bContrasts[ sourceID ];
+ borders[ destID ] = borders[ sourceID ];
+ highlights[ destID ] = highlights[ sourceID ];
+
+ if ( grLowColors[ sourceID ] )
+ grLowColors[ destID ] = new QColor( *grLowColors[ sourceID ] );
+ else
+ grLowColors[ destID ] = NULL;
+
+ if ( grHighColors[ sourceID ] )
+ grHighColors[ destID ] = new QColor( *grHighColors[ sourceID ] );
+ else
+ grHighColors[ destID ] = NULL;
+
+ if ( colors[ sourceID ] )
+ colors[ destID ] = new QColorGroup( *colors[ sourceID ] );
+ else
+ colors[ destID ] = NULL;
+
+ // pixmap
+ pixnames[ destID ] = pixnames[ sourceID ];
+ duplicate[ destID ] = false;
+ pixmaps[ destID ] = NULL;
+ images[ destID ] = NULL;
+ if ( !pixnames[ destID ].isEmpty() )
+ {
+ if ( scaleHints[ sourceID ] == TileScale && blends[ sourceID ] == 0.0 )
+ {
+ pixmaps[ destID ] = pixmaps[ sourceID ];
+ duplicate[ destID ] = true;
+ }
+ if ( !duplicate[ destID ] )
+ {
+ pixmaps[ destID ] = loadPixmap( pixnames[ destID ] );
+ if ( scaleHints[ destID ] == TileScale && blends[ destID ] == 0.0 )
+ images[ destID ] = NULL;
+ else
+ images[ destID ] = loadImage( pixnames[ destID ] );
+ }
+ }
+
+ // border pixmap
+ pbDuplicate[ destID ] = false;
+ pbPixmaps[ destID ] = NULL;
+ pbWidth[ destID ] = pbWidth[ sourceID ];
+ brdnames[ destID ] = brdnames[ sourceID ];
+ if ( !brdnames[ destID ].isEmpty() )
+ {
+ pbPixmaps[ destID ] = pbPixmaps[ sourceID ];
+ pbDuplicate[ destID ] = true;
+ }
+
+ if ( sourceID == ActiveTab && destID == InactiveTab )
+ aTabLine = iTabLine;
+ else if ( sourceID == InactiveTab && destID == ActiveTab )
+ iTabLine = aTabLine;
+}
+
+void KThemeBase::readConfig( Qt::GUIStyle /*style*/ )
+{
+#define PREBLEND_ITEMS 12
+ static const WidgetType preBlend[] =
+ {
+ Slider, IndicatorOn, IndicatorOff,
+ ExIndicatorOn, ExIndicatorOff, HScrollDeco, VScrollDeco, HScrollDecoDown,
+ VScrollDecoDown, ComboDeco, ComboDecoDown, CheckMark
+ };
+
+ int i;
+ QString tmpStr;
+ QString pixnames[ WIDGETS ]; // used for duplicate check
+ QString brdnames[ WIDGETS ];
+ bool loaded[ WIDGETS ]; // used for preloading for CopyWidget
+
+ QSettings config;
+ if (configDirName.isEmpty() || configDirName == ".")
+ {
+ KStyleDirs::dirs()->addToSearch( "themerc", config );
+ }
+ else config.insertSearchPath( QSettings::Unix, configDirName );
+
+ applyConfigFile( config );
+
+ d->contrast = config.readNumEntry( configFileName + "KDE/contrast", 7 );
+
+
+
+ for ( i = 0; i < INHERIT_ITEMS; ++i )
+ applyResourceGroup( &config, i );
+ for ( ; i < INHERIT_ITEMS*2; ++i )
+ {
+ if ( config.entryList( configFileName + widgetEntries[ i ] ).size() )
+ applyResourceGroup( &config, i );
+#ifndef Q_WS_QWS //FIXME
+
+ else
+ {
+ Prop& copyProp = d->props[ widgetEntries[ i ] ];
+ copyProp[ "CopyWidget" ] = QString( widgetEntries[ i - INHERIT_ITEMS ] );
+ }
+#endif
+
+ }
+ for ( ; i < WIDGETS; ++i )
+ applyResourceGroup( &config, i );
+ applyMiscResourceGroup( &config );
+
+ // initialize defaults that may not be read
+ for ( i = 0; i < WIDGETS; ++i )
+ loaded[ i ] = false;
+ btnXShift = btnYShift = focus3DOffset = 0;
+ aTabLine = iTabLine = true;
+ roundedButton = roundedCombo = roundedSlider = focus3D = false;
+ splitterWidth = 10;
+
+ //Handle the rotated background separately..
+ d->props[ widgetEntries[ RotSliderGroove ] ] = d->props[ widgetEntries[ SliderGroove ] ];
+ d->props[ widgetEntries[ RotInactiveTab ] ] = d->props[ widgetEntries[ InactiveTab ] ];
+ d->props[ widgetEntries[ RotActiveTab ] ] = d->props[ widgetEntries[ ActiveTab ] ];
+
+ // misc items
+ readMiscResourceGroup();
+
+
+ for ( i = 0; i < WIDGETS; ++i )
+ readResourceGroup( i, pixnames, brdnames, loaded );
+
+ if ( pixmaps[ RotSliderGroove ] )
+ {
+ QWMatrix r270; //TODO: 90 if reverse?
+ r270.rotate( 270 );
+ KThemePixmap* bf = new KThemePixmap( pixmaps[ RotSliderGroove ], pixmaps[ RotSliderGroove ] ->xForm( r270 ) ); //
+ pixmaps[ RotSliderGroove ] = bf;
+ if ( images[ RotSliderGroove ] )
+ {
+ delete images[ RotSliderGroove ];
+ images[ RotSliderGroove ] = new QImage( bf->convertToImage() );
+ }
+ }
+
+ if ( pixmaps[ RotActiveTab ] )
+ {
+ QWMatrix r180;
+ r180.rotate( 180 );
+ KThemePixmap* bf = new KThemePixmap( pixmaps[ RotActiveTab ], pixmaps[ RotActiveTab ] ->xForm( r180 ) );
+
+ pixmaps[ RotActiveTab ] = bf;
+ if ( images[ RotActiveTab ] )
+ {
+ delete images[ RotActiveTab ];
+ images[ RotActiveTab ] = new QImage( bf->convertToImage() );
+ }
+ }
+
+ if ( pixmaps[ RotInactiveTab ] )
+ {
+ QWMatrix r180;
+ r180.rotate( 180 );
+ KThemePixmap* bf = new KThemePixmap( pixmaps[ RotInactiveTab ], pixmaps[ RotInactiveTab ] ->xForm( r180 ) );
+
+ pixmaps[ RotInactiveTab ] = bf;
+ if ( images[ RotInactiveTab ] )
+ {
+ delete images[ RotInactiveTab ];
+ images[ RotInactiveTab ] = new QImage( bf->convertToImage() );
+ }
+ }
+
+ // Handle preblend items
+ for ( i = 0; i < PREBLEND_ITEMS; ++i )
+ {
+ if ( pixmaps[ preBlend[ i ] ] != NULL && blends[ preBlend[ i ] ] != 0.0 )
+ blend( preBlend[ i ] );
+ }
+
+ d->props.clear();
+}
+
+KThemeBase::KThemeBase( const QString& dir, const QString & configFile )
+ : KStyle( FilledFrameWorkaround ), configFileName( configFile )
+{
+ d = new KThemeBasePrivate;
+ if ( configFileName.isEmpty() )
+ configFileName = "kstylerc";
+
+
+ configDirName = dir;
+ //Strip of rc from the configFileName
+ if ( configFileName.endsWith( "rc" ) )
+ {
+ configFileName.truncate( configFileName.length() - 2 ); //Get rid of rc..
+ }
+ //else SCREAM!!
+
+
+ configFileName = "/" + configFileName + "/";
+
+ readConfig( Qt::WindowsStyle );
+ cache = new KThemeCache( cacheSize );
+
+ switch ( scrollBarLayout() )
+ {
+ case SBBottomLeft:
+ setScrollBarType( NextStyleScrollBar );
+ break;
+ case SBBottomRight:
+ setScrollBarType( PlatinumStyleScrollBar );
+ break;
+ case SBOpposite:
+ break;
+ //Do nothing, this type already set..
+ }
+ ;
+}
+
+void KThemeBase::applyConfigFile( QSettings& config )
+{
+ QStringList keys = config.entryList( configFileName );
+
+ if ( keys.contains( "foreground" ) )
+ {
+ d->overrideForeground = true;
+ d->overrideForegroundCol = readColorEntry( &config, ( configFileName + "foreground" ).latin1(), 0 );
+ }
+ else
+ d->overrideForeground = false;
+
+ if ( keys.contains( "background" ) )
+ {
+ d->overrideBackground = true;
+ d->overrideBackgroundCol = readColorEntry( &config, ( configFileName + "background" ).latin1(), 0 );
+ }
+ else
+ d->overrideBackground = false;
+
+
+
+ if ( keys.contains( "selectForeground" ) )
+ {
+ d->overrideSelectForeground = true;
+ d->overrideSelectForegroundCol = readColorEntry( &config, ( configFileName + "selectForeground" ).latin1(), 0 );
+ }
+ else
+ d->overrideSelectForeground = false;
+
+ if ( keys.contains( "selectBackground" ) )
+ {
+ d->overrideSelectBackground = true;
+ d->overrideSelectBackgroundCol = readColorEntry( &config, ( configFileName + "selectBackground" ).latin1(), 0 );
+ }
+ else
+ d->overrideSelectBackground = false;
+
+ if ( keys.contains( "windowBackground" ) )
+ {
+ d->overrideWindowBackground = true;
+ d->overrideWindowBackgroundCol = readColorEntry( &config, ( configFileName + "windowBackground" ).latin1(), 0 );
+ }
+ else
+ d->overrideWindowBackground = false;
+
+
+ if ( keys.contains( "windowForeground" ) )
+ {
+ d->overrideWindowForeground = true;
+ d->overrideWindowForegroundCol = readColorEntry( &config, ( configFileName + "windowForeground" ).latin1(), 0 );
+ }
+ else
+ d->overrideWindowForeground = false;
+
+
+#ifndef Q_WS_QWS //FIXME
+
+ for ( int input = 0; input < WIDGETS; ++input )
+ {
+ d->props.erase( widgetEntries[ input ] );
+ }
+ d->props.erase( "Misc" );
+#endif
+}
+
+KThemeBase::~KThemeBase()
+{
+ int i;
+ for ( i = 0; i < WIDGETS; ++i )
+ {
+ if ( !duplicate[ i ] )
+ {
+ if ( images[ i ] )
+ delete images[ i ];
+ if ( pixmaps[ i ] )
+ delete pixmaps[ i ];
+ }
+ if ( !pbDuplicate[ i ] && pbPixmaps[ i ] )
+ delete pbPixmaps[ i ];
+ if ( colors[ i ] )
+ delete( colors[ i ] );
+ if ( grLowColors[ i ] )
+ delete( grLowColors[ i ] );
+ if ( grHighColors[ i ] )
+ delete( grHighColors[ i ] );
+ }
+ KStyleDirs::release();
+ delete cache;
+ delete d;
+}
+
+QImage* KThemeBase::loadImage( const QString &name )
+{
+ QImage * image = new QImage;
+ QString path = KStyleDirs::dirs()->findResource( "themepixmap",name );
+ image->load( path );
+ if ( !image->isNull() )
+ return ( image );
+ qWarning( "KThemeBase: Unable to load image %s\n", name.latin1() );
+ delete image;
+ return ( NULL );
+}
+
+KThemePixmap* KThemeBase::loadPixmap( const QString &name )
+{
+ KThemePixmap * pixmap = new KThemePixmap( false );
+ QString path = KStyleDirs::dirs()->findResource( "themepixmap", name );
+ pixmap->load( path );
+ if ( !pixmap->isNull() )
+ return pixmap;
+ qWarning( "KThemeBase: Unable to load pixmap %s\n", name.latin1() );
+ delete pixmap;
+ return ( NULL );
+}
+
+
+KThemePixmap* KThemeBase::scale( int w, int h, WidgetType widget ) const
+{
+ if ( scaleHints[ widget ] == FullScale )
+ {
+ if ( !pixmaps[ widget ] || pixmaps[ widget ] ->width() != w ||
+ pixmaps[ widget ] ->height() != h )
+ {
+ KThemePixmap * cachePix = cache->pixmap( w, h, widget );
+ if ( cachePix )
+ {
+ cachePix = new KThemePixmap( *cachePix );
+ if ( pixmaps[ widget ] )
+ cache->insert( pixmaps[ widget ], KThemeCache::FullScale,
+ widget );
+ else
+ qWarning( "We would have inserted a null pixmap!\n" );
+ pixmaps[ widget ] = cachePix;
+ }
+ else
+ {
+ cache->insert( pixmaps[ widget ], KThemeCache::FullScale, widget );
+ QImage tmpImg = images[ widget ] ->smoothScale( w, h );
+ pixmaps[ widget ] = new KThemePixmap;
+ pixmaps[ widget ] ->convertFromImage( tmpImg );
+ if ( blends[ widget ] != 0.0 )
+ blend( widget );
+ }
+ }
+ }
+ else if ( scaleHints[ widget ] == HorizontalScale )
+ {
+ if ( pixmaps[ widget ] ->width() != w )
+ {
+ KThemePixmap * cachePix = cache->horizontalPixmap( w, widget );
+ if ( cachePix )
+ {
+ cachePix = new KThemePixmap( *cachePix );
+ if ( pixmaps[ widget ] )
+ cache->insert( pixmaps[ widget ], KThemeCache::HorizontalScale, widget );
+ else
+ qWarning( "We would have inserted a null pixmap!\n" );
+ pixmaps[ widget ] = cachePix;
+ }
+ else
+ {
+ cache->insert( pixmaps[ widget ], KThemeCache::HorizontalScale, widget );
+ QImage tmpImg = images[ widget ] ->
+ smoothScale( w, images[ widget ] ->height() );
+ pixmaps[ widget ] = new KThemePixmap;
+ pixmaps[ widget ] ->convertFromImage( tmpImg );
+ if ( blends[ widget ] != 0.0 )
+ blend( widget );
+ }
+ }
+ }
+ else if ( scaleHints[ widget ] == VerticalScale )
+ {
+ if ( pixmaps[ widget ] ->height() != h )
+ {
+ KThemePixmap * cachePix = cache->verticalPixmap( w, widget );
+ if ( cachePix )
+ {
+ cachePix = new KThemePixmap( *cachePix );
+ if ( pixmaps[ widget ] )
+ cache->insert( pixmaps[ widget ], KThemeCache::VerticalScale, widget );
+ else
+ qWarning( "We would have inserted a null pixmap!\n" );
+ pixmaps[ widget ] = cachePix;
+ }
+ else
+ {
+ cache->insert( pixmaps[ widget ], KThemeCache::VerticalScale, widget );
+ QImage tmpImg =
+ images[ widget ] ->smoothScale( images[ widget ] ->width(), h );
+ pixmaps[ widget ] = new KThemePixmap;
+ pixmaps[ widget ] ->convertFromImage( tmpImg );
+ if ( blends[ widget ] != 0.0 )
+ blend( widget );
+ }
+ }
+ }
+ // If blended tile here so the blend is scaled properly
+ else if ( scaleHints[ widget ] == TileScale && blends[ widget ] != 0.0 )
+ {
+ if ( !pixmaps[ widget ] || pixmaps[ widget ] ->width() != w ||
+ pixmaps[ widget ] ->height() != h )
+ {
+ KThemePixmap * cachePix = cache->pixmap( w, h, widget );
+ if ( cachePix )
+ {
+ cachePix = new KThemePixmap( *cachePix );
+ cache->insert( pixmaps[ widget ], KThemeCache::FullScale, widget );
+ pixmaps[ widget ] = cachePix;
+ }
+ else
+ {
+ cache->insert( pixmaps[ widget ], KThemeCache::FullScale, widget );
+ QPixmap tile;
+ tile.convertFromImage( *images[ widget ] );
+ pixmaps[ widget ] = new KThemePixmap;
+ pixmaps[ widget ] ->resize( w, h );
+ QPainter p( pixmaps[ widget ] );
+ p.drawTiledPixmap( 0, 0, w, h, tile );
+ if ( blends[ widget ] != 0.0 )
+ blend( widget );
+ }
+ }
+ }
+ return ( pixmaps[ widget ] );
+}
+
+KThemePixmap* KThemeBase::scaleBorder( int w, int h, WidgetType widget ) const
+{
+ KThemePixmap * pixmap = NULL;
+ if ( !pbPixmaps[ widget ] && !pbWidth[ widget ] )
+ return ( NULL );
+ pixmap = cache->pixmap( w, h, widget, true );
+ if ( pixmap )
+ {
+ pixmap = new KThemePixmap( *pixmap );
+ }
+ else
+ {
+ pixmap = new KThemePixmap();
+ pixmap->resize( w, h );
+ QBitmap mask;
+ mask.resize( w, h );
+ mask.fill( color0 );
+ QPainter mPainter;
+ mPainter.begin( &mask );
+
+ QPixmap *tmp = borderPixmap( widget ) ->border( KThemePixmap::TopLeft );
+ const QBitmap *srcMask = tmp->mask();
+ int bdWidth = tmp->width();
+
+ bitBlt( pixmap, 0, 0, tmp, 0, 0, bdWidth, bdWidth,
+ Qt::CopyROP, false );
+ if ( srcMask )
+ bitBlt( &mask, 0, 0, srcMask, 0, 0, bdWidth, bdWidth,
+ Qt::CopyROP, false );
+ else
+ mPainter.fillRect( 0, 0, bdWidth, bdWidth, color1 );
+
+
+ tmp = borderPixmap( widget ) ->border( KThemePixmap::TopRight );
+ srcMask = tmp->mask();
+ bitBlt( pixmap, w - bdWidth, 0, tmp, 0, 0, bdWidth,
+ bdWidth, Qt::CopyROP, false );
+ if ( srcMask )
+ bitBlt( &mask, w - bdWidth, 0, srcMask, 0, 0, bdWidth,
+ bdWidth, Qt::CopyROP, false );
+ else
+ mPainter.fillRect( w - bdWidth, 0, bdWidth, bdWidth, color1 );
+
+ tmp = borderPixmap( widget ) ->border( KThemePixmap::BottomLeft );
+ srcMask = tmp->mask();
+ bitBlt( pixmap, 0, h - bdWidth, tmp, 0, 0, bdWidth,
+ bdWidth, Qt::CopyROP, false );
+ if ( srcMask )
+ bitBlt( &mask, 0, h - bdWidth, srcMask, 0, 0, bdWidth,
+ bdWidth, Qt::CopyROP, false );
+ else
+ mPainter.fillRect( 0, h - bdWidth, bdWidth, bdWidth, color1 );
+
+ tmp = borderPixmap( widget ) ->border( KThemePixmap::BottomRight );
+ srcMask = tmp->mask();
+ bitBlt( pixmap, w - bdWidth, h - bdWidth, tmp, 0, 0,
+ bdWidth, bdWidth, Qt::CopyROP, false );
+ if ( srcMask )
+ bitBlt( &mask, w - bdWidth, h - bdWidth, srcMask, 0, 0,
+ bdWidth, bdWidth, Qt::CopyROP, false );
+ else
+ mPainter.fillRect( w - bdWidth, h - bdWidth, bdWidth, bdWidth, color1 );
+
+ QPainter p;
+ p.begin( pixmap );
+ if ( w - bdWidth * 2 > 0 )
+ {
+ tmp = borderPixmap( widget ) ->border( KThemePixmap::Top );
+ srcMask = tmp->mask();
+ p.drawTiledPixmap( bdWidth, 0, w - bdWidth * 2, bdWidth, *tmp );
+ if ( srcMask )
+ bitBlt( &mask, bdWidth, 0, srcMask, 0, 0,
+ w - bdWidth * 2, bdWidth, Qt::CopyROP, false );
+ else
+ mPainter.fillRect( bdWidth, 0, w - bdWidth * 2, bdWidth, color1 );
+
+ tmp = borderPixmap( widget ) ->border( KThemePixmap::Bottom );
+ srcMask = tmp->mask();
+ p.drawTiledPixmap( bdWidth, h - bdWidth, w - bdWidth * 2, bdWidth,
+ *tmp );
+ if ( srcMask )
+ bitBlt( &mask, bdWidth, h - bdWidth, srcMask, 0, 0,
+ w - bdWidth * 2, bdWidth, Qt::CopyROP, false );
+ else
+ mPainter.fillRect( bdWidth, h - bdWidth, w - bdWidth * 2, bdWidth,
+ color1 );
+ }
+ if ( h - bdWidth * 2 > 0 )
+ {
+ tmp = borderPixmap( widget ) ->border( KThemePixmap::Left );
+ srcMask = tmp->mask();
+ p.drawTiledPixmap( 0, bdWidth, bdWidth, h - bdWidth * 2, *tmp );
+ if ( srcMask )
+ bitBlt( &mask, 0, bdWidth, srcMask, 0, 0,
+ bdWidth, h - bdWidth * 2, Qt::CopyROP, false );
+ else
+ mPainter.fillRect( 0, bdWidth, bdWidth, h - bdWidth * 2, color1 );
+
+ tmp = borderPixmap( widget ) ->border( KThemePixmap::Right );
+ srcMask = tmp->mask();
+ p.drawTiledPixmap( w - bdWidth, bdWidth, bdWidth, h - bdWidth * 2,
+ *tmp );
+ if ( srcMask )
+ bitBlt( &mask, w - bdWidth, bdWidth, srcMask, 0, 0,
+ bdWidth, h - bdWidth * 2, Qt::CopyROP, false );
+ else
+ mPainter.fillRect( w - bdWidth, bdWidth, bdWidth, h - bdWidth * 2, color1 );
+ }
+ p.end();
+ mPainter.end();
+ pixmap->setMask( mask );
+ cache->insert( pixmap, KThemeCache::FullScale, widget, true );
+ if ( !pixmap->mask() )
+ qWarning( "No mask for border pixmap!\n" );
+ }
+ return ( pixmap );
+}
+
+
+KThemePixmap* KThemeBase::blend( WidgetType widget ) const
+{
+ KPixmapEffect::GradientType g;
+ switch ( gradients[ widget ] )
+ {
+ case GrHorizontal:
+ g = KPixmapEffect::HorizontalGradient;
+ break;
+ case GrVertical:
+ g = KPixmapEffect::VerticalGradient;
+ break;
+ case GrPyramid:
+ g = KPixmapEffect::PyramidGradient;
+ break;
+ case GrRectangle:
+ g = KPixmapEffect::RectangleGradient;
+ break;
+ case GrElliptic:
+ g = KPixmapEffect::EllipticGradient;
+ break;
+ default:
+ g = KPixmapEffect::DiagonalGradient;
+ break;
+ }
+ KPixmapEffect::blend( *pixmaps[ widget ], blends[ widget ], *grLowColors[ widget ],
+ g, false );
+ return ( pixmaps[ widget ] );
+}
+
+KThemePixmap* KThemeBase::gradient( int w, int h, WidgetType widget ) const
+{
+ if ( gradients[ widget ] == GrVertical )
+ {
+ if ( !pixmaps[ widget ] || pixmaps[ widget ] ->height() != h )
+ {
+ KThemePixmap * cachePix = cache->verticalPixmap( h, widget );
+ if ( cachePix )
+ {
+ cachePix = new KThemePixmap( *cachePix );
+ if ( pixmaps[ widget ] )
+ cache->insert( pixmaps[ widget ], KThemeCache::VerticalScale,
+ widget );
+ pixmaps[ widget ] = cachePix;
+ }
+ else
+ {
+ if ( pixmaps[ widget ] )
+ cache->insert( pixmaps[ widget ], KThemeCache::VerticalScale,
+ widget );
+ pixmaps[ widget ] = new KThemePixmap;
+ pixmaps[ widget ] ->resize( w, h );
+ KPixmapEffect::gradient( *pixmaps[ widget ], *grHighColors[ widget ],
+ *grLowColors[ widget ],
+ KPixmapEffect::VerticalGradient );
+ }
+ }
+ }
+ else if ( gradients[ widget ] == GrHorizontal )
+ {
+ if ( !pixmaps[ widget ] || pixmaps[ widget ] ->width() != w )
+ {
+ KThemePixmap * cachePix = cache->horizontalPixmap( w, widget );
+ if ( cachePix )
+ {
+ cachePix = new KThemePixmap( *cachePix );
+ if ( pixmaps[ widget ] )
+ cache->insert( pixmaps[ widget ],
+ KThemeCache::HorizontalScale, widget );
+ pixmaps[ widget ] = cachePix;
+ }
+ else
+ {
+ if ( pixmaps[ widget ] )
+ cache->insert( pixmaps[ widget ],
+ KThemeCache::HorizontalScale, widget );
+ pixmaps[ widget ] = new KThemePixmap;
+ pixmaps[ widget ] ->resize( w, h );
+ KPixmapEffect::gradient( *pixmaps[ widget ], *grHighColors[ widget ],
+ *grLowColors[ widget ],
+ KPixmapEffect::HorizontalGradient );
+ }
+ }
+ }
+ else if ( gradients[ widget ] == GrReverseBevel )
+ {
+ if ( !pixmaps[ widget ] || pixmaps[ widget ] ->width() != w ||
+ pixmaps[ widget ] ->height() != h )
+ {
+ KThemePixmap * cachePix = cache->pixmap( w, h, widget );
+ if ( cachePix )
+ {
+ cachePix = new KThemePixmap( *cachePix );
+ if ( pixmaps[ widget ] )
+ cache->insert( pixmaps[ widget ], KThemeCache::FullScale,
+ widget );
+ pixmaps[ widget ] = cachePix;
+ }
+ else
+ {
+ if ( pixmaps[ widget ] )
+ cache->insert( pixmaps[ widget ], KThemeCache::FullScale,
+ widget );
+ pixmaps[ widget ] = new KThemePixmap;
+ pixmaps[ widget ] ->resize( w, h );
+
+ KPixmap s;
+ int offset = decoWidth( widget );
+ s.resize( w - offset * 2, h - offset * 2 );
+ QColor lc( *grLowColors[ widget ] );
+ QColor hc( *grHighColors[ widget ] );
+ if ( bevelContrast( widget ) )
+ {
+ int bc = bevelContrast( widget );
+ // want single increments, not factors like light()/dark()
+ lc.setRgb( lc.red() - bc, lc.green() - bc, lc.blue() - bc );
+ hc.setRgb( hc.red() + bc, hc.green() + bc, hc.blue() + bc );
+ }
+ KPixmapEffect::gradient( *pixmaps[ widget ],
+ lc, hc,
+ KPixmapEffect::DiagonalGradient );
+ KPixmapEffect::gradient( s, *grHighColors[ widget ],
+ *grLowColors[ widget ],
+ KPixmapEffect::DiagonalGradient );
+ bitBlt( pixmaps[ widget ], offset, offset, &s, 0, 0, w - offset * 2,
+ h - offset * 2, Qt::CopyROP );
+ }
+ }
+ }
+ else
+ {
+ KPixmapEffect::GradientType g;
+ switch ( gradients[ widget ] )
+ {
+ case GrPyramid:
+ g = KPixmapEffect::PyramidGradient;
+ break;
+ case GrRectangle:
+ g = KPixmapEffect::RectangleGradient;
+ break;
+ case GrElliptic:
+ g = KPixmapEffect::EllipticGradient;
+ break;
+ default:
+ g = KPixmapEffect::DiagonalGradient;
+ break;
+ }
+ if ( !pixmaps[ widget ] || pixmaps[ widget ] ->width() != w ||
+ pixmaps[ widget ] ->height() != h )
+ {
+ KThemePixmap * cachePix = cache->pixmap( w, h, widget );
+ if ( cachePix )
+ {
+ cachePix = new KThemePixmap( *cachePix );
+ if ( pixmaps[ widget ] )
+ cache->insert( pixmaps[ widget ], KThemeCache::FullScale,
+ widget );
+ pixmaps[ widget ] = cachePix;
+ }
+ else
+ {
+ if ( pixmaps[ widget ] )
+ cache->insert( pixmaps[ widget ], KThemeCache::FullScale,
+ widget );
+ pixmaps[ widget ] = new KThemePixmap;
+ pixmaps[ widget ] ->resize( w, h );
+ KPixmapEffect::gradient( *pixmaps[ widget ], *grHighColors[ widget ],
+ *grLowColors[ widget ], g );
+ }
+ }
+ }
+ return ( pixmaps[ widget ] );
+}
+
+KThemePixmap* KThemeBase::scalePixmap( int w, int h, WidgetType widget ) const
+{
+
+ if ( gradients[ widget ] && blends[ widget ] == 0.0 )
+ return ( gradient( w, h, widget ) );
+
+ return ( scale( w, h, widget ) );
+}
+
+QColorGroup* KThemeBase::makeColorGroup( const QColor &fg, const QColor &bg,
+ Qt::GUIStyle )
+{
+ if ( shading == Motif )
+ {
+ int highlightVal, lowlightVal;
+ highlightVal = 100 + ( 2 * d->contrast + 4 ) * 16 / 10;
+ lowlightVal = 100 + ( ( 2 * d->contrast + 4 ) * 10 );
+ return ( new QColorGroup( fg, bg, bg.light( highlightVal ),
+ bg.dark( lowlightVal ), bg.dark( 120 ),
+ fg, QApplication::palette().active().base() ) );
+ }
+ else
+ return ( new QColorGroup( fg, bg, bg.light( 150 ), bg.dark(),
+ bg.dark( 120 ), fg,
+ QApplication::palette().active().base() ) );
+}
+
+
+void KThemeBase::applyMiscResourceGroup( QSettings *config )
+{
+#ifndef Q_WS_QWS //FIXME
+ d->props.erase( "Misc" ); // clear the old property
+
+ QString base = configFileName + "Misc/";
+
+ Prop& prop = d->props[ "Misc" ];
+ QString tmpStr;
+
+ tmpStr = config->readEntry( base + "SButtonPosition" );
+ if ( tmpStr == "BottomLeft" )
+ prop[ "SButtonPosition" ] = QString::number( ( int ) SBBottomLeft );
+ else if ( tmpStr == "BottomRight" )
+ prop[ "SButtonPosition" ] = QString::number( ( int ) SBBottomRight );
+ else
+ {
+ if ( tmpStr != "Opposite" && !tmpStr.isEmpty() )
+ qWarning( "KThemeBase: Unrecognized sb button option %s, using Opposite.\n", tmpStr.latin1() );
+ ;
+ prop[ "SButtonPosition" ] = QString::number( ( int ) SBOpposite );
+ }
+ tmpStr = config->readEntry( base + "ArrowType" );
+ if ( tmpStr == "Small" )
+ prop[ "ArrowType" ] = QString::number( ( int ) SmallArrow );
+ else if ( tmpStr == "3D" )
+ prop[ "ArrowType" ] = QString::number( ( int ) MotifArrow );
+ else
+ {
+ if ( tmpStr != "Normal" && !tmpStr.isEmpty() )
+ qWarning( "KThemeBase: Unrecognized arrow option %s, using Normal.\n", tmpStr.latin1() );
+ prop[ "ArrowType" ] = QString::number( ( int ) LargeArrow );
+ }
+ tmpStr = config->readEntry( base + "ShadeStyle" );
+ if ( tmpStr == "Motif" )
+ prop[ "ShadeStyle" ] = QString::number( ( int ) Motif );
+ else if ( tmpStr == "Next" )
+ prop[ "ShadeStyle" ] = QString::number( ( int ) Next );
+ else if ( tmpStr == "KDE" )
+ prop[ "ShadeStyle" ] = QString::number( ( int ) KDE );
+ else
+ prop[ "ShadeStyle" ] = QString::number( ( int ) Windows );
+
+ prop[ "FrameWidth" ] = QString::number( config->readNumEntry( base + "FrameWidth", 2 ) );
+ prop[ "Cache" ] = QString::number( config->readNumEntry( base + "Cache", 1024 ) );
+ prop[ "ScrollBarExtent" ] = QString::number( config->readNumEntry( base + "ScrollBarExtent", 16 ) );
+#endif
+}
+
+static int readNumEntry( Prop& prop, QString setting, int def )
+{
+ bool ok;
+ QString s_val = prop[ setting ];
+ int val = s_val.toInt( &ok );
+ if ( ok )
+ return val;
+ return def;
+}
+
+static QColor readColorEntry( Prop& prop, QString setting, const QColor& def )
+{
+ QString s_val = prop[ setting ];
+ if ( !s_val.isEmpty() )
+ {
+ QColor c( s_val );
+ return c;
+ }
+ return def;
+}
+
+void KThemeBase::readMiscResourceGroup()
+{
+#ifndef Q_WS_QWS //FIXME
+ Prop & prop = d->props[ "Misc" ];
+
+ sbPlacement = ( SButton ) readNumEntry( prop, "SButtonPosition",
+ ( int ) SBOpposite );
+ arrowStyle = ( ArrowStyle ) readNumEntry( prop, "ArrowType",
+ ( int ) LargeArrow );
+ shading = ( ShadeStyle ) readNumEntry( prop, "ShadeStyle", ( int ) Windows );
+ defaultFrame = readNumEntry( prop, "FrameWidth", 2 );
+ cacheSize = readNumEntry( prop, "Cache", 1024 );
+ sbExtent = readNumEntry( prop, "ScrollBarExtent", 16 );
+#endif
+}
+
+
+void KThemeBase::applyResourceGroup( QSettings *config, int i )
+{
+#ifndef Q_WS_QWS //FIXME
+ QString tmpStr;
+ int tmpVal;
+
+ // clear the old property
+ d->props.erase( widgetEntries[ i ] );
+
+ QString base = configFileName + widgetEntries[ i ] + "/";
+
+ Prop& prop = d->props[ widgetEntries[ i ] ];
+
+ tmpStr = config->readEntry( base + "CopyWidget", "" );
+ prop[ "CopyWidget" ] = tmpStr;
+ if ( !tmpStr.isEmpty() )
+ {
+ return ;
+ }
+
+ tmpStr = config->readEntry( base + "Scale" );
+ if ( tmpStr == "Full" )
+ tmpVal = ( int ) FullScale;
+ else if ( tmpStr == "Horizontal" )
+ tmpVal = ( int ) HorizontalScale;
+ else if ( tmpStr == "Vertical" )
+ tmpVal = ( int ) VerticalScale;
+ else
+ {
+ if ( tmpStr != "Tile" && !tmpStr.isEmpty() )
+ qWarning( "KThemeBase: Unrecognized scale option %s, using Tile.\n", tmpStr.latin1() );
+ tmpVal = ( int ) TileScale;
+ }
+ prop[ "ScaleHint" ] = QString::number( tmpVal );
+
+ // Gradient type
+ tmpStr = config->readEntry( base + "Gradient" );
+ if ( tmpStr == "Diagonal" )
+ tmpVal = ( int ) GrDiagonal;
+ else if ( tmpStr == "Horizontal" )
+ tmpVal = ( int ) GrHorizontal;
+ else if ( tmpStr == "Vertical" )
+ tmpVal = ( int ) GrVertical;
+ else if ( tmpStr == "Pyramid" )
+ tmpVal = ( int ) GrPyramid;
+ else if ( tmpStr == "Rectangle" )
+ tmpVal = ( int ) GrRectangle;
+ else if ( tmpStr == "Elliptic" )
+ tmpVal = ( int ) GrElliptic;
+ else if ( tmpStr == "ReverseBevel" )
+ tmpVal = ( int ) GrReverseBevel;
+ else
+ {
+ if ( tmpStr != "None" && !tmpStr.isEmpty() )
+ qWarning( "KThemeBase: Unrecognized gradient option %s, using None.\n", tmpStr.latin1() );
+ tmpVal = ( int ) GrNone;
+ }
+ prop[ "Gradient" ] = QString::number( tmpVal );
+
+ // Blend intensity
+ tmpStr.setNum( config->readDoubleEntry( base + "BlendIntensity", 0.0 ) );
+ prop[ "Blend" ] = tmpStr;
+
+ // Bevel contrast
+ prop[ "BContrast" ] = QString::number( config->readNumEntry( base + "BevelContrast", 0 ) );
+
+ // Border width
+ prop[ "Border" ] = QString::number( config->readNumEntry( base + "Border", 1 ) );
+
+ // Highlight width
+ prop[ "Highlight" ] = QString::number( config->readNumEntry( base + "Highlight", 1 ) );
+
+ QStringList keys = config->entryList( base );
+
+ // Gradient low color or blend background
+ if ( keys.contains( "GradientLow" ) )
+ prop[ "GrLow" ] = readColorEntry( config, QString( base + "GradientLow" ).latin1(),
+ &QApplication::palette().active().background() ).name();
+
+ // Gradient high color
+ if ( keys.contains( "GradientHigh" ) )
+ prop[ "GrHigh" ] = readColorEntry( config, QString( base + "GradientHigh" ).latin1(),
+ &QApplication::palette().active().foreground() ).name();
+
+ // Extended color attributes
+ if ( keys.contains( "Foreground" ) || keys.contains( "Background" ) )
+ {
+ QColor fg, bg;
+ if ( keys.contains( "Background" ) )
+ bg = readColorEntry( config, QString( base + "Background" ).latin1(), &bg );
+ if ( keys.contains( "Foreground" ) )
+ fg = readColorEntry( config, QString( base + "Foreground" ).latin1(), &fg );
+ prop[ "Foreground" ] = fg.name();
+ prop[ "Background" ] = bg.name();
+
+ }
+ else
+ colors[ i ] = NULL;
+
+ // Pixmap
+ tmpStr = config->readEntry( base + "Pixmap", "" );
+ if ( !tmpStr.isEmpty() )
+ prop[ "Pixmap" ] = tmpStr;
+ // Pixmap border
+ tmpStr = config->readEntry( base + "PixmapBorder", "" );
+ if ( !tmpStr.isEmpty() )
+ {
+ prop[ "PixmapBorder" ] = tmpStr;
+ prop[ "PixmapBWidth" ] = QString::number(
+ config->readNumEntry( base + "PixmapBWidth", 0 ) );
+ }
+
+ // Various widget specific settings. This was more efficient when bunched
+ // together in the misc group, but this makes an easier to read config.
+ if ( i == SliderGroove )
+ prop[ "SmallGroove" ] = QString::number(
+ config->readBoolEntry( base + "SmallGroove", false ) );
+ else if ( i == ActiveTab || i == InactiveTab )
+ prop[ "BottomLine" ] = QString::number(
+ config->readBoolEntry( base + "BottomLine", true ) );
+ else if ( i == Splitter )
+ prop[ "Width" ] = QString::number( config->readNumEntry( base + "Width", 10 ) );
+ else if ( i == ComboBox || i == ComboBoxDown )
+ {
+ if ( keys.contains( "Round" ) )
+ prop[ "Round" ] = QString::number( config->readBoolEntry( base + "Round", false ) );
+ else
+ prop[ "Round" ] = "5000"; // invalid, used w/multiple groups
+
+ }
+ else if ( i == PushButton || i == PushButtonDown )
+ {
+ if ( keys.contains( "XShift" ) )
+ prop[ "XShift" ] = QString::number( config->readNumEntry( base + "XShift", 0 ) );
+ else
+ prop[ "XShift" ] = "5000";
+ if ( keys.contains( "YShift" ) )
+ prop[ "YShift" ] = QString::number( config->readNumEntry( base + "YShift", 0 ) );
+ else
+ prop[ "YShift" ] = "5000";
+ if ( keys.contains( "3DFocusRect" ) )
+ prop[ "3DFRect" ] = QString::number( config->
+ readBoolEntry( base + "3DFocusRect", false ) );
+ else
+ prop[ "3DFRect" ] = "5000";
+ if ( keys.contains( "3DFocusOffset" ) )
+ prop[ "3DFOffset" ] = QString::number( config->
+ readBoolEntry( base + "3DFocusOffset", 0 ) );
+ else
+ prop[ "3DFOffset" ] = "5000";
+ if ( keys.contains( "Round" ) )
+ prop[ "Round" ] = QString::number( config->readBoolEntry( base + "Round", false ) );
+ else
+ prop[ "Round" ] = "5000";
+ }
+#endif
+}
+
+void KThemeBase::readResourceGroup( int i, QString *pixnames, QString *brdnames,
+ bool *loadArray )
+{
+#ifndef Q_WS_QWS //FIXME
+ if ( loadArray[ i ] == true )
+ {
+ return ; // already been preloaded.
+ }
+
+ int tmpVal;
+ Prop prop = d->props[ widgetEntries[ i ] ];
+ QString tmpStr;
+
+ tmpStr = prop[ "CopyWidget" ];
+ if ( !tmpStr.isEmpty() )
+ { // Duplicate another widget's config
+ int sIndex;
+ loadArray[ i ] = true;
+ for ( sIndex = 0; sIndex < WIDGETS; ++sIndex )
+ {
+ if ( tmpStr == widgetEntries[ sIndex ] )
+ {
+ if ( !loadArray[ sIndex ] ) // hasn't been loaded yet
+ readResourceGroup( sIndex, pixnames, brdnames,
+ loadArray );
+ break;
+ }
+ }
+ if ( loadArray[ sIndex ] )
+ {
+ copyWidgetConfig( sIndex, i, pixnames, brdnames );
+ }
+ else
+ qWarning( "KThemeBase: Unable to identify source widget for %s\n", widgetEntries[ i ] );
+ return ;
+ }
+ // special inheritance for disabled arrows (these are tri-state unlike
+ // the rest of what we handle).
+ for ( tmpVal = DisArrowUp; tmpVal <= DisArrowRight; ++tmpVal )
+ {
+ if ( tmpVal == i )
+ {
+ tmpStr = prop[ "Pixmap" ];
+ if ( tmpStr.isEmpty() )
+ {
+ copyWidgetConfig( ArrowUp + ( tmpVal - DisArrowUp ), i, pixnames,
+ brdnames );
+ return ;
+ }
+ }
+ }
+
+ // Scale hint
+ scaleHints[ i ] = ( ScaleHint ) readNumEntry( prop, "ScaleHint", ( int ) TileScale );
+ gradients[ i ] = ( Gradient ) readNumEntry( prop, "Gradient", ( int ) GrNone );
+
+ // Blend intensity
+ tmpStr = prop[ "Blend" ];
+ if ( tmpStr.isEmpty() )
+ tmpStr = QString::fromLatin1( "0.0" );
+ blends[ i ] = tmpStr.toFloat();
+
+ // Bevel contrast
+ bContrasts[ i ] = readNumEntry( prop, "BContrast", 0 );
+
+ // Border width
+ borders[ i ] = readNumEntry( prop, "Border", 1 );
+
+ // Highlight width
+ highlights[ i ] = readNumEntry( prop, "Highlight", 1 );
+
+ // Gradient low color or blend background
+ if ( gradients[ i ] != GrNone || blends[ i ] != 0.0 )
+ grLowColors[ i ] =
+ new QColor( readColorEntry( prop, "GrLow",
+ QApplication::palette().active().
+ background() ) );
+ else
+ grLowColors[ i ] = NULL;
+
+ // Gradient high color
+ if ( gradients[ i ] != GrNone )
+ grHighColors[ i ] =
+ new QColor( readColorEntry( prop, "GrHigh",
+ QApplication::palette().active().
+ background() ) );
+ else
+ grHighColors[ i ] = NULL;
+
+ // Extended color attributes
+ QColor fg, bg;
+ fg = readColorEntry( prop, "Foreground", fg );
+ bg = readColorEntry( prop, "Background", bg );
+ if ( fg.isValid() || bg.isValid() )
+ {
+ if ( !fg.isValid() )
+ fg = QApplication::palette().active().foreground();
+ if ( !bg.isValid() )
+ bg = QApplication::palette().active().background();
+ colors[ i ] = makeColorGroup( fg, bg, Qt::WindowsStyle );
+ }
+ else
+ colors[ i ] = NULL;
+
+ // Pixmap
+ int existing;
+ tmpStr = prop[ "Pixmap" ];
+ pixnames[ i ] = tmpStr;
+ duplicate[ i ] = false;
+ pixmaps[ i ] = NULL;
+ images[ i ] = NULL;
+ // Scan for duplicate pixmaps(two identical pixmaps, tile scale, no blend,
+ // no pixmapped border)
+ if ( !tmpStr.isEmpty() )
+ {
+ for ( existing = 0; existing < i; ++existing )
+ {
+ if ( tmpStr == pixnames[ existing ] && scaleHints[ i ] == TileScale &&
+ scaleHints[ existing ] == TileScale && blends[ existing ] == 0.0 &&
+ blends[ i ] == 0.0 )
+ {
+ pixmaps[ i ] = pixmaps[ existing ];
+ duplicate[ i ] = true;
+ break;
+ }
+ }
+ }
+ // load
+ if ( !duplicate[ i ] && !tmpStr.isEmpty() )
+ {
+ pixmaps[ i ] = loadPixmap( tmpStr );
+ // load and save images for scaled/blended widgets for speed.
+ if ( scaleHints[ i ] == TileScale && blends[ i ] == 0.0 )
+ images[ i ] = NULL;
+ else
+ images[ i ] = loadImage( tmpStr );
+ }
+
+ // Pixmap border
+ tmpStr = prop[ "PixmapBorder" ];
+ brdnames[ i ] = tmpStr;
+ pbDuplicate[ i ] = false;
+ pbPixmaps[ i ] = NULL;
+ pbWidth[ i ] = 0;
+ if ( !tmpStr.isEmpty() )
+ {
+ pbWidth[ i ] = readNumEntry( prop, "PixmapBWidth", 0 );
+ if ( pbWidth[ i ] == 0 )
+ {
+ qWarning( "KThemeBase: No border width specified for pixmapped border widget %s\n",
+ widgetEntries[ i ] );
+ qWarning( "KThemeBase: Using default of 2.\n" );
+ pbWidth[ i ] = 2;
+ }
+ // duplicate check
+ for ( existing = 0; existing < i; ++existing )
+ {
+ if ( tmpStr == brdnames[ existing ] )
+ {
+ pbPixmaps[ i ] = pbPixmaps[ existing ];
+ pbDuplicate[ i ] = true;
+ break;
+ }
+ }
+ }
+ // load
+ if ( !pbDuplicate[ i ] && !tmpStr.isEmpty() )
+ pbPixmaps[ i ] = loadPixmap( tmpStr );
+
+ if ( pbPixmaps[ i ] && !pbDuplicate[ i ] )
+ generateBorderPix( i );
+
+ // Various widget specific settings. This was more efficient when bunched
+ // together in the misc group, but this makes an easier to read config.
+ if ( i == SliderGroove )
+ roundedSlider = readNumEntry( prop, "SmallGroove", false );
+ else if ( i == ActiveTab )
+ aTabLine = readNumEntry( prop, "BottomLine", true );
+ else if ( i == InactiveTab )
+ iTabLine = readNumEntry( prop, "BottomLine", true );
+ else if ( i == Splitter )
+ splitterWidth = readNumEntry( prop, "Width", 10 );
+ else if ( i == ComboBox || i == ComboBoxDown )
+ {
+ tmpVal = readNumEntry( prop, "Round", 5000 );
+ if ( tmpVal != 5000 )
+ roundedCombo = tmpVal;
+ }
+ else if ( i == PushButton || i == PushButtonDown )
+ {
+ tmpVal = readNumEntry( prop, "XShift", 0 );
+ if ( tmpVal != 5000 )
+ btnXShift = tmpVal;
+ tmpVal = readNumEntry( prop, "YShift", 0 );
+ if ( tmpVal != 5000 )
+ btnYShift = tmpVal;
+ tmpVal = readNumEntry( prop, "3DFRect", false );
+ if ( tmpVal != 5000 )
+ focus3D = tmpVal;
+ tmpVal = readNumEntry( prop, "3DFOffset", 0 );
+ if ( tmpVal != 5000 )
+ focus3DOffset = tmpVal;
+ tmpVal = readNumEntry( prop, "Round", false );
+ if ( tmpVal != 5000 )
+ roundedButton = tmpVal;
+ }
+ loadArray[ i ] = true;
+#endif
+}
+
+
+QPalette KThemeBase::overridePalette( const QPalette& pal )
+{
+
+ //Read current settings for colors..
+ QColor background = pal.active().background();
+ QColor foreground = pal.active().foreground();
+ QColor button = background; //CHECKME
+ QColor highlight = pal.active().highlight();
+ QColor highlightedText = pal.active().highlightedText(); //CHECKME
+ QColor base = pal.active().base(); //config->readColorEntry( "windowBackground", &white );
+ QColor baseText = pal.active().text(); //CHECKME
+
+ //See whether there are any immediate overrides.
+ if ( d->overrideBackground )
+ background = d->overrideBackgroundCol;
+
+ if ( d->overrideForeground )
+ foreground = d->overrideForegroundCol;
+
+ if ( d->overrideSelectBackground )
+ highlight = d->overrideSelectBackgroundCol;
+ if ( d->overrideSelectForeground )
+ highlightedText = d->overrideSelectForegroundCol;
+
+ if ( d->overrideWindowBackground )
+ base = d->overrideWindowBackgroundCol;
+ if ( d->overrideWindowForeground )
+ baseText = d->overrideWindowForegroundCol;
+
+ //Now, try to get the button color from the pixmap
+ if ( uncached( Bevel ) )
+ button = d->pixmapAveColor( uncached( Bevel ) );
+
+ QColor buttonText = foreground;
+
+ int highlightVal, lowlightVal;
+ highlightVal = 100 + ( 2 * d->contrast + 4 ) * 16 / 10;
+ lowlightVal = 100 + ( 2 * d->contrast + 4 ) * 10;
+
+
+ if ( isPixmap( Background ) || isColor( Background ) )
+ {
+ if ( isColor( Background ) )
+ {
+ background = colorGroup( pal.active(), Background )
+ ->background();
+ }
+ if ( isPixmap( Background ) )
+ {
+ background = d->pixmapAveColor( uncached( Background ) );
+ }
+
+
+ QColorGroup pre( foreground, button, background.light( highlightVal ),
+ background.dark( lowlightVal ), background.dark( 120 ),
+ baseText, buttonText /*CHECKME: BrightText*/, base, background );
+
+ buttonText = colorGroup( pre, PushButton ) ->foreground();
+ }
+
+ QColor disfg = foreground;
+ int h, s, v;
+ disfg.hsv( &h, &s, &v );
+ if ( v > 128 )
+ // dark bg, light fg - need a darker disabled fg
+ disfg = disfg.dark( lowlightVal );
+ else if ( disfg != black )
+ // light bg, dark fg - need a lighter disabled fg - but only if !black
+ disfg = disfg.light( highlightVal );
+ else
+ // black fg - use darkgray disabled fg
+ disfg = Qt::darkGray;
+
+
+ QColorGroup disabledgrp( disfg, background, //TODO:Convert this to the new ctor.
+ background.light( highlightVal ),
+ background.dark( lowlightVal ),
+ background.dark( 120 ),
+ background.dark( 120 ), base );
+
+
+ QColorGroup colgrp( foreground, button, background.light( highlightVal ),
+ background.dark( lowlightVal ), background.dark( 120 ),
+ baseText, buttonText /*CHECKME: BrightText*/, base, background );
+
+
+
+ colgrp.setColor( QColorGroup::Highlight, highlight );
+ colgrp.setColor( QColorGroup::HighlightedText, highlightedText );
+ colgrp.setColor( QColorGroup::ButtonText, buttonText );
+ colgrp.setColor( QColorGroup::Midlight, button.light( 110 ) );
+
+
+ disabledgrp.setColor( QColorGroup::Base, base );
+ disabledgrp.setColor( QColorGroup::Button, button );
+ disabledgrp.setColor( QColorGroup::ButtonText, buttonText );
+ disabledgrp.setColor( QColorGroup::Midlight, button.light( 110 ) );
+
+ QPalette newPal( colgrp, disabledgrp, colgrp );
+
+ return newPal;
+
+}
+
+KThemePixmap::KThemePixmap( bool timer )
+ : KPixmap()
+{
+ if ( timer )
+ {
+ t = new QTime;
+ t->start();
+ }
+ else
+ t = NULL;
+ int i;
+ for ( i = 0; i < 8; ++i )
+ b[ i ] = NULL;
+}
+
+KThemePixmap::KThemePixmap( const KThemePixmap &p )
+ : KPixmap( p )
+{
+ if ( p.t )
+ {
+ t = new QTime;
+ t->start();
+ }
+ else
+ t = NULL;
+ int i;
+ for ( i = 0; i < 8; ++i )
+ if ( p.b[ i ] )
+ b[ i ] = new QPixmap( *p.b[ i ] );
+ else
+ b[ i ] = NULL;
+}
+
+KThemePixmap::KThemePixmap( const KThemePixmap &p, const QPixmap &p2 )
+ : KPixmap( p2 )
+{
+ if ( p.t )
+ {
+ t = new QTime;
+ t->start();
+ }
+ else
+ t = NULL;
+ int i;
+ for ( i = 0; i < 8; ++i )
+ if ( p.b[ i ] )
+ b[ i ] = new QPixmap( *p.b[ i ] );
+ else
+ b[ i ] = NULL;
+}
+
+
+
+KThemePixmap::~KThemePixmap()
+{
+ if ( t )
+ delete t;
+ int i;
+ for ( i = 0; i < 8; ++i )
+ if ( b[ i ] )
+ delete b[ i ];
+}
+
+KThemeCache::KThemeCache( int maxSize, QObject *parent, const char *name )
+ : QObject( parent, name )
+{
+ cache.setMaxCost( maxSize * 1024 );
+ cache.setAutoDelete( true );
+ flushTimer.start( 300000 ); // 5 minutes
+ connect( &flushTimer, SIGNAL( timeout() ), SLOT( flushTimeout() ) );
+}
+
+void KThemeCache::flushTimeout()
+{
+ QIntCacheIterator<KThemePixmap> it( cache );
+ while ( it.current() )
+ {
+ if ( it.current() ->isOld() )
+ cache.remove( it.currentKey() );
+ else
+ ++it;
+ }
+}
+
+KThemePixmap* KThemeCache::pixmap( int w, int h, int widgetID, bool border,
+ bool mask )
+{
+
+ kthemeKey key;
+ key.cacheKey = 0; // shut up, gcc
+ key.data.id = widgetID;
+ key.data.width = w;
+ key.data.height = h;
+ key.data.border = border;
+ key.data.mask = mask;
+
+ KThemePixmap *pix = cache.find( ( unsigned long ) key.cacheKey );
+ if ( pix )
+ pix->updateAccessed();
+ return ( pix );
+}
+
+KThemePixmap* KThemeCache::horizontalPixmap( int w, int widgetID )
+{
+ kthemeKey key;
+ key.cacheKey = 0; // shut up, gcc
+ key.data.id = widgetID;
+ key.data.width = w;
+ key.data.height = 0;
+ key.data.border = false;
+ key.data.mask = false;
+ KThemePixmap *pix = cache.find( ( unsigned long ) key.cacheKey );
+ if ( pix )
+ pix->updateAccessed();
+ return ( pix );
+}
+
+KThemePixmap* KThemeCache::verticalPixmap( int h, int widgetID )
+{
+ kthemeKey key;
+ key.cacheKey = 0; // shut up, gcc
+ key.data.id = widgetID;
+ key.data.width = 0;
+ key.data.height = h;
+ key.data.border = false;
+ key.data.mask = false;
+ KThemePixmap *pix = cache.find( ( unsigned long ) key.cacheKey );
+ if ( pix )
+ pix->updateAccessed();
+ return ( pix );
+}
+
+bool KThemeCache::insert( KThemePixmap *pixmap, ScaleHint scale, int widgetID,
+ bool border, bool mask )
+{
+ kthemeKey key;
+ key.cacheKey = 0; // shut up, gcc
+ key.data.id = widgetID;
+ key.data.width = ( scale == FullScale || scale == HorizontalScale ) ?
+ pixmap->width() : 0;
+ key.data.height = ( scale == FullScale || scale == VerticalScale ) ?
+ pixmap->height() : 0;
+ key.data.border = border;
+ key.data.mask = mask;
+
+ if ( cache.find( ( unsigned long ) key.cacheKey, true ) != NULL )
+ {
+ return ( true ); // a pixmap of this scale is already in there
+ }
+ return ( cache.insert( ( unsigned long ) key.cacheKey, pixmap,
+ pixmap->width() * pixmap->height() * pixmap->depth() / 8 ) );
+}
+
+
+
+
+#include "kthemebase.moc"