summaryrefslogtreecommitdiffstats
path: root/kstyles/kthemestyle
diff options
context:
space:
mode:
Diffstat (limited to 'kstyles/kthemestyle')
-rw-r--r--kstyles/kthemestyle/Makefile.am29
-rw-r--r--kstyles/kthemestyle/kstyledirs.cpp48
-rw-r--r--kstyles/kthemestyle/kstyledirs.h82
-rw-r--r--kstyles/kthemestyle/kthemebase.cpp1826
-rw-r--r--kstyles/kthemestyle/kthemebase.h853
-rw-r--r--kstyles/kthemestyle/kthemestyle.cpp2384
-rw-r--r--kstyles/kthemestyle/kthemestyle.h230
7 files changed, 5452 insertions, 0 deletions
diff --git a/kstyles/kthemestyle/Makefile.am b/kstyles/kthemestyle/Makefile.am
new file mode 100644
index 000000000..0edb271b4
--- /dev/null
+++ b/kstyles/kthemestyle/Makefile.am
@@ -0,0 +1,29 @@
+
+# This file is part of the KDE libraries
+# Copyright (C) 1997 Matthias Kalle Dalheimer (kalle@kde.org)
+# (C) 1997 Stephan Kulow (coolo@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 as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+
+# 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 General Public License
+# along with this library; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+
+AM_CPPFLAGS = -DQT_PLUGIN
+
+INCLUDES = -I$(top_srcdir)/kdefx $(all_includes)
+noinst_HEADERS = kthemestyle.h kthemebase.h kstyledirs.h
+kde_style_LTLIBRARIES = kthemestyle.la
+kthemestyle_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) -module
+kthemestyle_la_LIBADD = ../../kdefx/libkdefx.la ../../kdecore/libkdecore.la
+kthemestyle_la_SOURCES = kthemebase.cpp kthemestyle.cpp kstyledirs.cpp
+kthemestyle_la_METASOURCES = AUTO
diff --git a/kstyles/kthemestyle/kstyledirs.cpp b/kstyles/kthemestyle/kstyledirs.cpp
new file mode 100644
index 000000000..b77d4d56b
--- /dev/null
+++ b/kstyles/kthemestyle/kstyledirs.cpp
@@ -0,0 +1,48 @@
+/*
+ $Id$
+
+ Simple helper routines for style's use of KStandardDirs with QSettings, etc.
+
+ 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.
+
+
+ This file is part of the KDE libraries
+*/
+
+#include <qfile.h>
+#include <kstandarddirs.h>
+#include "kstyledirs.h"
+
+KStyleDirs* KStyleDirs::instance = 0;
+
+KStyleDirs::KStyleDirs()
+{
+ addResourceType( "themepixmap", KStandardDirs::kde_default( "data" ) + "kstyle/pixmaps/" );
+ addResourceType( "themerc", KStandardDirs::kde_default( "data" ) + "kstyle/themes/" );
+}
+
+KStyleDirs::~KStyleDirs()
+{
+}
+
+void KStyleDirs::addToSearch( const char* type, QSettings& s ) const
+{
+ const QStringList & dirs = resourceDirs(type);
+ for ( int c = dirs.size()-1; c >= 0 ; c-- )
+ {
+ s.insertSearchPath( QSettings::Unix, dirs[ c ]);
+ }
+}
+
diff --git a/kstyles/kthemestyle/kstyledirs.h b/kstyles/kthemestyle/kstyledirs.h
new file mode 100644
index 000000000..b23457a07
--- /dev/null
+++ b/kstyles/kthemestyle/kstyledirs.h
@@ -0,0 +1,82 @@
+/*
+ $Id$
+
+ This file is part of the KDE libraries
+ (c) 2002 Maksim Orlovich <mo002j@mail.rochester.edu>,
+
+ 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.
+*/
+
+#ifndef KSTYLE_DIRS_H
+#define KSTYLE_DIRS_H
+
+
+#include <qsettings.h>
+#include <qstringlist.h>
+#include <kstandarddirs.h>
+
+/**
+* @short Access to the standard KDE directories for the pixmap style
+* @author Maksim Orlovich<mo002j@mail.rochester.edu> is responsible for this file,
+ but all the interesting work is done by KStandardDirs
+* @version $Id$
+*
+* This class provides a this wrapper for styles around KStandardDirs,
+* permitting integration with QSettings and easy loading of pixmaps
+*
+* It add share/apps/kstyle/themes as "themerc",
+* share/apps/kstyle/pixmaps "themepixmap"
+*/
+class KStyleDirs: public KStandardDirs
+{
+public:
+ static KStyleDirs* dirs()
+ {
+ if ( !instance)
+ instance = new KStyleDirs;
+ return instance;
+ }
+
+ static void release()
+ {
+ delete instance;
+ instance = 0;
+ }
+
+ /**
+ Adds all of KDE directories of type type to the seach path of q.
+
+ For example, when one does the following:
+ QSettings settings;
+ KStyleDirs dirs;
+ dirs.addToSearch("config",settings);
+
+ The one can do settings.readEntry("kstyle/KDE/WidgetStyle") to access a settings in kstylerc.
+ */
+ void addToSearch( const char* type, QSettings& q) const; //Better name?
+
+protected:
+ static KStyleDirs* instance;
+ /**
+ Creates an instance of the class, and calculates the path information.
+ */
+ KStyleDirs();
+ KStyleDirs(const KStyleDirs&);
+ KStyleDirs& operator= (const KStyleDirs&);
+
+ virtual ~KStyleDirs();
+};
+
+#endif
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"
diff --git a/kstyles/kthemestyle/kthemebase.h b/kstyles/kthemestyle/kthemebase.h
new file mode 100644
index 000000000..8f8041464
--- /dev/null
+++ b/kstyles/kthemestyle/kthemebase.h
@@ -0,0 +1,853 @@
+/*
+ $Id$
+
+ This file is part of the KDE libraries
+ Copyright (C) 1999 Daniel M. Duley <mosfet@kde.org>
+
+ KDE3 port (C) 2001 Maksim Orlovich <mo002j@mail.rochester.edu>
+
+ Palette setup code is from KApplication,
+Copyright (C) 1997 Matthias Kalle Dalheimer (kalle@kde.org)
+Copyright (C) 1998, 1999, 2000 KDE Team
+
+
+ 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.
+*/
+
+#ifndef KTHEMEBASE_H
+#define KTHEMEBASE_H
+
+#include <qtimer.h>
+#include <qdatetime.h>
+#include <kpixmap.h>
+#include <qintcache.h>
+#include <qstring.h>
+#include <kstyle.h>
+#include <qsettings.h>
+#include <qpalette.h> // for QColorGroup
+#include "kstyledirs.h"
+#include <qmap.h>
+
+class QImage;
+
+
+
+/**
+ * This class adds simple time management to KPixmap for use in flushing
+ * KThemeCache.
+ *
+ * @author Daniel M. Duley <mosfet@kde.org>
+ */
+class KThemePixmap : public KPixmap
+{
+public:
+ enum BorderType{Top = 0, Bottom, Left, Right, TopLeft, TopRight, BottomLeft,
+ BottomRight};
+
+ KThemePixmap( bool timer = true );
+ KThemePixmap( const KThemePixmap &p );
+ KThemePixmap( const KThemePixmap &p, const QPixmap& rp );
+ ~KThemePixmap();
+ QPixmap* border( BorderType type );
+ void setBorder( BorderType type, const QPixmap &p );
+ void updateAccessed();
+ bool isOld();
+protected:
+ QTime *t;
+ QPixmap *b[ 8 ];
+
+private:
+ class KThemePixmapPrivate;
+ KThemePixmapPrivate *d;
+};
+
+inline QPixmap* KThemePixmap::border( BorderType type )
+{
+ return ( b[ type ] );
+}
+
+inline void KThemePixmap::setBorder( BorderType type, const QPixmap &p )
+{
+ if ( b[ type ] )
+ {
+ qWarning( "KThemePixmap: Overwriting existing border!" );
+ delete( b[ type ] );
+ }
+ b[ type ] = new QPixmap( p );
+}
+
+inline void KThemePixmap::updateAccessed()
+{
+ if ( t )
+ t->start();
+}
+
+inline bool KThemePixmap::isOld()
+{
+ return ( t ? t->elapsed() >= 300000 : false );
+}
+
+/**
+ * A very simple pixmap cache for theme plugins. QPixmapCache is not used
+ * since it uses QString keys which are not needed. All the information we
+ * need can be encoded in a numeric key. Using QIntCache instead allows us to
+ * skip the string operations.
+ *
+ * This class is mostly just inline methods that do bit operations on a key
+ * composed of the widget ID, width and/or height, and then calls
+ * QIntCache::find().
+ *
+ * One other thing to note is that full, horizontal, and vertically scaled
+ * pixmaps are not used interchangeably. For example, if you insert a fully
+ * scaled pixmap that is 32x32 then request a horizontally scaled pixmap with
+ * a width of 32, they will not match. This is because a pixmap that has been
+ * inserted into the cache has already been scaled at some point and it is
+ * very likely the vertical height was not originally 32. Thus the pixmap
+ * will be wrong when drawn, even though the horizontal width matches.
+ *
+ * @author Daniel M. Duley <mosfet@kde.org>
+ *
+ */
+class KThemeCache : public QObject
+{
+ Q_OBJECT
+public:
+ /**
+ * The scale hints supported by the cache. Note that Tiled is not here
+ * since tiled pixmaps are kept only once in KThemeBase.
+ */
+ enum ScaleHint{FullScale, HorizontalScale, VerticalScale};
+ /**
+ * The constructor.
+ *
+ * @param maxSize The maximum size of the cache in kilobytes.
+ * @param parent The parent object.
+ * @param name The name of the object.
+ */
+ KThemeCache( int maxSize, QObject *parent = 0, const char *name = 0 );
+ /**
+ * Inserts a new pixmap into the cache.
+ *
+ * @param pixmap The pixmap to insert.
+ * @param scale The scaling type of the pixmap.
+ * @param widgetID The widget ID of the pixmap, usually from KThemeBase's
+ * WidgetType enum.
+ * @param border True if the pixmap has a border.
+ * @param mask True if the pixmap has a mask.
+ *
+ * @return True if the insert was successful, false otherwise.
+ */
+ bool insert( KThemePixmap *pixmap, ScaleHint scale, int widgetID,
+ bool border = false, bool mask = false );
+ /**
+ * Returns a fully scaled pixmap.
+ *
+ * @param w The pixmap width to search for.
+ * @param h The pixmap height to search for.
+ * @param widgetID The widget ID to search for.
+ * @param border True if the pixmap has a border.
+ * @param mask True if the pixmap has a mask.
+ *
+ * @return True if a pixmap matching the width, height, and widget ID of
+ * the pixmap exists, NULL otherwise.
+ */
+ KThemePixmap* pixmap( int w, int h, int widgetID, bool border = false,
+ bool mask = false );
+ /**
+ * Returns a horizontally scaled pixmap.
+ *
+ * @param w The pixmap width to search for.
+ * @param widgetID The widget ID to search for.
+ *
+ * @return True if a pixmap matching the width and widget ID of
+ * the pixmap exists, NULL otherwise.
+ */
+ KThemePixmap* horizontalPixmap( int w, int widgetID );
+ /**
+ * Returns a vertically scaled pixmap.
+ *
+ * @param h The pixmap height to search for.
+ * @param widgetID The widget ID to search for.
+ *
+ * @return True if a pixmap matching the height and widget ID of
+ * the pixmap exists, NULL otherwise.
+ */
+ KThemePixmap* verticalPixmap( int h, int widgetID );
+protected slots:
+ void flushTimeout();
+protected:
+ QIntCache<KThemePixmap> cache;
+ QTimer flushTimer;
+
+private:
+ class KThemeCachePrivate;
+ KThemeCachePrivate *d;
+};
+
+
+
+class KThemeBasePrivate;
+/**
+ * This is a base class for KDE themed styles. It implements a cache,
+ * configuration file parsing, pixmap scaling, gradients, and a lot
+ * of inline methods for accessing user specified parameters.
+ *
+ * Note that this class *does not* actually implement any themes. It just
+ * provides the groundwork for doing so. The only reason to use this class
+ * directly is if you plan to reimplement all of the widgets. Otherwise,
+ * refer to KThemeStyle for a fully themed style you can derive from.
+ *
+ * @author Daniel M. Duley <mosfet@kde.org>
+ */
+class KThemeBase: public KStyle
+{
+ Q_OBJECT
+public:
+ /**
+ * Constructs a new KThemeBase object.
+ */
+ KThemeBase( const QString &dirs, const QString &configFile );
+ ~KThemeBase();
+ /**
+ * Describes if a pixmap should be scaled fully, horizontally, vertically,
+ * or not at all and tiled.
+ */
+ enum ScaleHint{FullScale, HorizontalScale, VerticalScale, TileScale};
+ /**
+ * The default arrow types.
+ */
+ enum ArrowStyle{MotifArrow, LargeArrow, SmallArrow};
+ /**
+ * The default frame shading styles.
+ */
+ enum ShadeStyle{Motif, Windows, Next, KDE};
+ /**
+ * The default scrollbar button layout. BottomLeft is like what Next
+ * uses, BottomRight is like Platinum, and Opposite it like Windows and
+ * Motif.
+ */
+ enum SButton{SBBottomLeft, SBBottomRight, SBOpposite};
+ /**
+ * The gradient types. Horizontal is left to right, Vertical is top to
+ * bottom, and diagonal is upper-left to bottom-right.
+ */
+ enum Gradient{GrNone, GrHorizontal, GrVertical, GrDiagonal, GrPyramid,
+ GrRectangle, GrElliptic, GrReverseBevel};
+ /**
+ * This provides a list of widget types that KThemeBase recognizes.
+ */
+ /* Internal note: The order here is important. Some widgets inherit
+ * properties. This is usually for when you have two settings for the
+ * same widget, ie: on(sunken), and off. The on settings will inherit
+ * the properties of the off one when nothing is specified in the config.
+ *
+ * In order to be able to handle this while still having everything in
+ * one group that is easy to loop from we have the following order:
+ * unsunked(off) items, sunken(on)items, and then the ones that don't
+ * matter. INHERIT_ITEMS define the number of widgets that have inheritence
+ * so if 0 == PushButtonOff then INHERIT_ITEMS should == PushButtonOn
+ * and so on. WIDGETS define the total number of widgets.
+ */
+ enum WidgetType{
+ // Off (unsunken widgets)
+ PushButton = 0, ComboBox, HScrollBarSlider, VScrollBarSlider, Bevel,
+ ToolButton, ScrollButton, HScrollDeco, VScrollDeco,
+ ComboDeco, MenuItem, InactiveTab, ArrowUp, ArrowDown, ArrowLeft,
+ ArrowRight,
+ // On (sunken widgets)
+ PushButtonDown, ComboBoxDown, HScrollBarSliderDown,
+ VScrollBarSliderDown, BevelDown, ToolButtonDown, ScrollButtonDown,
+ HScrollDecoDown, VScrollDecoDown, ComboDecoDown, MenuItemDown,
+ ActiveTab, SunkenArrowUp, SunkenArrowDown, SunkenArrowLeft,
+ SunkenArrowRight,
+ // Everything else (indicators must have separate settings)
+ HScrollGroove, VScrollGroove, Slider, SliderGroove, IndicatorOn,
+ IndicatorOff, IndicatorTri, ExIndicatorOn, ExIndicatorOff, HBarHandle, VBarHandle,
+ ToolBar, Splitter, CheckMark, MenuBar, DisArrowUp, DisArrowDown,
+ DisArrowLeft, DisArrowRight, ProgressBar, ProgressBg, MenuBarItem,
+ Background, RotSliderGroove, RotInactiveTab, RotActiveTab, WIDGETS};
+
+ /**
+ * The scaling type specified by the KConfig file.
+ *
+ * @param widget A Widgets enum value.
+ *
+ * @return A ScaleHint enum value.
+ */
+ ScaleHint scaleHint( WidgetType widget ) const;
+ /**
+ * The gradient type specified by the KConfig file.
+ *
+ * @param widget A Widgets enum value.
+ *
+ * @return A Gradient enum value.
+ */
+ Gradient gradientHint( WidgetType widget ) const;
+ /**
+ * The color group specified for a given widget.
+ * If a color group is set in the theme configuration
+ * that is used, otherwise defaultColor is returned.
+ *
+ * @param defaultGroup The colorGroup to set if one is available.
+ *
+ * @param widget The widget whose color group to retrieve.
+ *
+ */
+ const QColorGroup* colorGroup( const QColorGroup &defaultGroup,
+ WidgetType widget ) const;
+
+ QBrush pixmapBrush( const QColorGroup &group, QColorGroup::ColorRole role,
+ int w, int h, WidgetType widget );
+ /**
+ * True if the widget has a pixmap or gradient specified.
+ */
+ bool isPixmap( WidgetType widget ) const;
+ /**
+ * True if the widget has a color group specified.
+ */
+ bool isColor( WidgetType widget ) const;
+ /**
+ * True if the user specified a 3D focus rectangle
+ */
+ bool is3DFocus() const;
+ /**
+ * If the user specified a 3D focus rectangle, they may also specify an
+ * offset from the default rectangle to use when drawing it. This returns
+ * the specified offset.
+ */
+ int focusOffset() const;
+ /**
+ * The border width of the specified widget.
+ */
+ int borderWidth( WidgetType widget ) const;
+ /**
+ * Pixmap border width of the specified widget.
+ */
+ int pixBorderWidth( WidgetType widget ) const;
+ /**
+ * Returns the border pixmap if enabled for the specified widget. This
+ * will contain the originial pixmap, plus the edges separated in
+ * KThemePixmap::border() if valid. If invalid it will return NULL.
+ */
+ KThemePixmap* borderPixmap( WidgetType widget ) const;
+ /**
+ * The highlight width of the specified widget.
+ */
+ int highlightWidth( WidgetType widget ) const;
+ /**
+ * The border plus highlight width of the widget.
+ */
+ int decoWidth( WidgetType widget ) const;
+ /**
+ * The extent (width for vertical, height for horizontal) requested
+ * for the scrollbars.
+ */
+ int getSBExtent() const;
+ /**
+ * The scrollbar button layout.
+ */
+ SButton scrollBarLayout() const;
+ /**
+ * The arrow type.
+ */
+ ArrowStyle arrowType() const;
+ /**
+ * The shading type.
+ */
+ ShadeStyle shade() const;
+ /**
+ * The frame width.
+ */
+ int frameWidth() const;
+ /**
+ * The splitter width.
+ */
+ int splitWidth() const;
+ /**
+ * The contrast for some bevel effects such as reverse gradient.
+ */
+ int bevelContrast( WidgetType widget ) const;
+ /**
+ * The button text X shift.
+ */
+ int buttonXShift() const;
+ /**
+ * The button text Y shift.
+ */
+ int buttonYShift() const;
+ /**
+ * Returns either the slider length of the slider pixmap if available,
+ * otherwise the length specified in the config file.
+ */
+ int sliderButtonLength() const;
+ /**
+ * True if rounded buttons are requested.
+ */
+ bool roundButton() const;
+ /**
+ * True if rounded comboboxes are requested.
+ */
+ bool roundComboBox() const;
+ /**
+ * True if rounded slider grooves are requested.
+ */
+ bool roundSlider() const;
+ /**
+ * True if a line should be drawn on the bottom of active tabs.
+ */
+ bool activeTabLine() const;
+ /**
+ * True if a line should be drawn on the bottom of inactive tabs.
+ */
+ bool inactiveTabLine() const;
+ /**
+ * Returns the current uncached pixmap for the given widget. This will
+ * usually be either the last scaled or gradient pixmap if those have
+ * been specified in the config file, the original pixmap if not, or NULL
+ * if no pixmap has been specified.
+ */
+ KThemePixmap* uncached( WidgetType widget ) const;
+ /**
+ * Returns the pixmap for the given widget at the specified width and
+ * height. This will return NULL if no pixmap or gradient is specified.
+ * It may also return a different sized pixmap if the scaling
+ * is set to Tiled. When using this method, you should call it using
+ * the needed width and height then use QPainter::drawTiledPixmap to
+ * paint it. Doing this, if the pixmap is scaled it will be the proper
+ * size, otherwise it will be tiled.
+ *
+ * @param w Requested width.
+ * @param h Requested height.
+ * @param widget Widget type.
+ * @return The pixmap or NULL if one is not specified.
+ */
+ virtual KThemePixmap *scalePixmap( int w, int h, WidgetType widget ) const;
+protected:
+ /**
+ * This method reads a configuration file and sets things up so
+ * overrideColorGroup works. Modiying user's config files within
+ * a style is evil, IMHO (SadEagle). On the other hand, this will
+ * make it simply ignore settings.
+ *
+ * @param config The configuration file to apply.
+ */
+ void applyConfigFile( QSettings & config );
+
+ /*
+ * Generates a new palette based on the values for which have been specified explicitly
+ * in the .themerc file.
+ */
+ QPalette overridePalette( const QPalette& pal );
+
+ /**
+ * Returns a QImage for the given widget if the widget is scaled, NULL
+ * otherwise. QImages of the original pixmap are stored for scaled
+ * widgets in order to facilitate fast and accurate smooth-scaling. This
+ * also saves us a conversion from a pixmap to an image then back again.
+ */
+ QImage* image( WidgetType widget ) const;
+ /**
+ * Returns the gradient high color if one is specified, NULL otherwise.
+ */
+ QColor* gradientHigh( WidgetType widget ) const;
+ /**
+ * Returns the gradient low color if one is specified, NULL otherwise.
+ */
+ QColor* gradientLow( WidgetType widget ) const;
+ /**
+ * Reads in all the configuration file entries supported.
+ *
+ * @param colorStyle The style for the color groups. In KDE, colors were
+ * calculated a little differently for Motif vs Windows styles. This
+ * is obsolete.
+ */
+ void readConfig( Qt::GUIStyle colorStyle = Qt::WindowsStyle );
+ void readWidgetConfig( int i, QSettings *config, QString *pixnames,
+ QString *brdnames, bool *loadArray );
+ void copyWidgetConfig( int sourceID, int destID, QString *pixnames,
+ QString *brdnames );
+ /**
+ * Makes a full color group based on the given foreground and background
+ * colors. This is the same code used by KDE (kapp.cpp) in previous
+ * versions.
+ */
+ QColorGroup* makeColorGroup( const QColor &fg, const QColor &bg,
+ Qt::GUIStyle style = Qt::WindowsStyle );
+ KThemePixmap* scale( int w, int h, WidgetType widget ) const;
+ KThemePixmap* scaleBorder( int w, int h, WidgetType type ) const;
+ KThemePixmap* gradient( int w, int h, WidgetType widget ) const ;
+ KThemePixmap* blend( WidgetType widget ) const;
+ void generateBorderPix( int i );
+ void applyResourceGroup( QSettings *config, int i );
+ void applyMiscResourceGroup( QSettings *config );
+ void readResourceGroup( int i, QString *pixnames, QString *brdnames,
+ bool *loadArray );
+ void readMiscResourceGroup();
+ /**
+ * Attempts to load a pixmap from the default KThemeBase locations.
+ */
+ KThemePixmap* loadPixmap( const QString &name );
+ /**
+ * Attempts to load a image from the default KThemeBase locations.
+ */
+ QImage* loadImage( const QString &name );
+
+
+ /**
+ These are included for fuuture extension purposes..
+ */
+ virtual int pixelMetric ( PixelMetric metric, const QWidget * widget = 0 ) const
+ {
+ return KStyle::pixelMetric( metric, widget );
+ }
+
+ virtual void drawPrimitive ( PrimitiveElement pe, QPainter * p, const QRect & r, const QColorGroup & cg,
+ SFlags flags = Style_Default,
+ const QStyleOption& option = QStyleOption::Default ) const
+ {
+ KStyle::drawPrimitive ( pe, p, r, cg,
+ flags, option );
+ }
+
+
+ virtual void drawControl( ControlElement element,
+ QPainter *p,
+ const QWidget *widget,
+ const QRect &r,
+ const QColorGroup &cg,
+ SFlags how = Style_Default,
+ const QStyleOption& opt = QStyleOption::Default ) const
+ {
+ KStyle::drawControl( element, p, widget,
+ r, cg, how, opt );
+ }
+
+ virtual void drawControlMask( ControlElement element,
+ QPainter *p,
+ const QWidget *widget,
+ const QRect &r,
+ const QStyleOption& opt = QStyleOption::Default ) const
+ {
+ KStyle::drawControlMask( element, p, widget, r, opt );
+ }
+
+
+ virtual void drawComplexControl( ComplexControl control,
+ QPainter *p,
+ const QWidget* widget,
+ const QRect &r,
+ const QColorGroup &cg,
+ SFlags flags = Style_Default,
+ SCFlags controls = SC_All,
+ SCFlags active = SC_None,
+ const QStyleOption& opt = QStyleOption::Default ) const
+ {
+ KStyle::drawComplexControl( control, p, widget, r, cg, flags, controls, active, opt );
+ }
+
+
+ virtual void drawKStylePrimitive( KStylePrimitive kpe,
+ QPainter* p,
+ const QWidget* widget,
+ const QRect &r,
+ const QColorGroup &cg,
+ SFlags flags = Style_Default,
+ const QStyleOption& opt = QStyleOption::Default ) const
+ {
+ KStyle::drawKStylePrimitive( kpe,
+ p, widget, r,
+ cg, flags, opt );
+ }
+
+
+ virtual int styleHint( StyleHint sh,
+ const QWidget *widget = 0,
+ const QStyleOption& opt = QStyleOption::Default,
+ QStyleHintReturn* returnData = 0 ) const
+ {
+ return KStyle::styleHint( sh,
+ widget,
+ opt,
+ returnData );
+ }
+
+ virtual QSize sizeFromContents( ContentsType contents,
+ const QWidget *widget,
+ const QSize &contentsSize,
+ const QStyleOption& opt = QStyleOption::Default ) const
+ {
+ return KStyle::sizeFromContents( contents,
+ widget, contentsSize, opt );
+ }
+
+private:
+ KThemeBasePrivate *d;
+
+ SButton sbPlacement;
+ ArrowStyle arrowStyle;
+ ShadeStyle shading;
+ int defaultFrame;
+ int btnXShift, btnYShift;
+ int sliderLen;
+ int splitterWidth;
+ int focus3DOffset;
+ int sbExtent;
+ bool smallGroove;
+ bool roundedButton, roundedCombo, roundedSlider;
+ bool aTabLine, iTabLine;
+ bool focus3D;
+ KThemeCache *cache;
+ int cacheSize;
+ QString configFileName;
+ QString configDirName;
+
+ /**
+ * The theme pixmaps. Many of these may be NULL if no pixmap is specified.
+ * There may also be duplicate pixmap pointers if more than one widget
+ * uses the same tiled pixmap. If a pixmap is tiled, it is kept here and
+ * this acts as a cache. Otherwise this will hold whatever the last scaled
+ * pixmap was.
+ */
+ mutable KThemePixmap *pixmaps[ WIDGETS ];
+ /**
+ * The theme images. These are for scaled images and are kept in order
+ * to maintain fast smoothscaling.
+ */
+ mutable QImage *images[ WIDGETS ];
+ /**
+ * The border widths
+ */
+ mutable unsigned char borders[ WIDGETS ];
+ /**
+ * The highlight widths
+ */
+ mutable unsigned char highlights[ WIDGETS ];
+ /**
+ * The scale hints for pixmaps and gradients.
+ */
+ mutable ScaleHint scaleHints[ WIDGETS ];
+ /**
+ * All the color groups.
+ */
+ mutable QColorGroup *colors[ WIDGETS ];
+ /**
+ * Gradient low colors (or blend background).
+ */
+ mutable QColor *grLowColors[ WIDGETS ];
+ /**
+ * Gradient high colors.
+ */
+ mutable QColor *grHighColors[ WIDGETS ];
+ /**
+ * Gradient types.
+ */
+ mutable Gradient gradients[ WIDGETS ];
+ /**
+ * Blend intensity factors
+ */
+ mutable float blends[ WIDGETS ];
+ /**
+ * Bevel contrasts
+ */
+ mutable unsigned char bContrasts[ WIDGETS ];
+ /**
+ * Duplicate pixmap entries (used during destruction).
+ */
+ mutable bool duplicate[ WIDGETS ];
+ /**
+ * Pixmapped border widths
+ */
+ mutable int pbWidth[ WIDGETS ];
+ /**
+ * Pixmapped borders
+ */
+ mutable KThemePixmap *pbPixmaps[ WIDGETS ];
+ /**
+ * Duplicate border pixmapped border entries
+ */
+ mutable bool pbDuplicate[ WIDGETS ];
+
+};
+
+inline bool KThemeBase::isPixmap( WidgetType widget ) const
+{
+ return ( pixmaps[ widget ] != NULL || gradients[ widget ] != GrNone );
+}
+
+inline bool KThemeBase::isColor( WidgetType widget ) const
+{
+ return ( colors[ widget ] != NULL );
+}
+
+inline bool KThemeBase::is3DFocus() const
+{
+ return ( focus3D );
+}
+
+inline int KThemeBase::focusOffset() const
+{
+ return ( focus3DOffset );
+}
+
+inline int KThemeBase::bevelContrast( WidgetType widget ) const
+{
+ return ( bContrasts[ widget ] );
+}
+
+inline KThemeBase::ScaleHint KThemeBase::scaleHint( WidgetType widget ) const
+{
+ return ( ( widget < WIDGETS ) ? scaleHints[ widget ] : TileScale );
+}
+
+inline KThemeBase::Gradient KThemeBase::gradientHint( WidgetType widget ) const
+{
+ return ( ( widget < WIDGETS ) ? gradients[ widget ] : GrNone );
+}
+
+inline KThemePixmap* KThemeBase::uncached( WidgetType widget ) const
+{
+ return ( pixmaps[ widget ] );
+}
+
+inline QBrush KThemeBase::pixmapBrush( const QColorGroup &group,
+ QColorGroup::ColorRole role,
+ int w, int h, WidgetType widget )
+{
+ if ( pixmaps[ widget ] || images[ widget ] )
+ return ( QBrush( group.color( role ), *scalePixmap( w, h, widget ) ) );
+ else
+ return ( group.color( role ) );
+}
+
+inline const QColorGroup* KThemeBase::colorGroup( const QColorGroup &defaultGroup,
+ WidgetType widget ) const
+{
+ return ( ( colors[ widget ] ) ? colors[ widget ] : &defaultGroup );
+}
+
+inline int KThemeBase::borderWidth( WidgetType widget ) const
+{
+ return ( pbWidth[ widget ] ? pbWidth[ widget ] : borders[ widget ] );
+}
+
+inline int KThemeBase::pixBorderWidth( WidgetType widget ) const
+{
+ return ( pbWidth[ widget ] );
+}
+
+inline int KThemeBase::highlightWidth( WidgetType widget ) const
+{
+ return ( pbWidth[ widget ] ? 0 : highlights[ widget ] );
+}
+
+inline int KThemeBase::decoWidth( WidgetType widget ) const
+{
+ return ( pbWidth[ widget ] ? pbWidth[ widget ] : borders[ widget ] + highlights[ widget ] );
+}
+
+inline QColor* KThemeBase::gradientHigh( WidgetType widget ) const
+{
+ return ( grHighColors[ widget ] );
+}
+
+inline QColor* KThemeBase::gradientLow( WidgetType widget ) const
+{
+ return ( grLowColors[ widget ] );
+}
+
+inline QImage* KThemeBase::image( WidgetType widget ) const
+{
+ return ( images[ widget ] );
+}
+
+inline KThemeBase::SButton KThemeBase::scrollBarLayout() const
+{
+ return ( sbPlacement );
+}
+
+inline KThemeBase::ArrowStyle KThemeBase::arrowType() const
+{
+ return ( arrowStyle );
+}
+
+inline KThemeBase::ShadeStyle KThemeBase::shade() const
+{
+ return ( shading );
+}
+
+inline int KThemeBase::frameWidth() const
+{
+ return ( defaultFrame );
+}
+
+inline int KThemeBase::buttonXShift() const
+{
+ return ( btnXShift );
+}
+
+inline int KThemeBase::splitWidth() const
+{
+ return ( splitterWidth );
+}
+
+inline int KThemeBase::buttonYShift() const
+{
+ return ( btnYShift );
+}
+
+inline int KThemeBase::sliderButtonLength() const
+{
+ if ( isPixmap( Slider ) )
+ return ( uncached( Slider ) ->width() );
+ else
+ return ( sliderLen );
+}
+
+inline bool KThemeBase::roundButton() const
+{
+ return ( roundedButton );
+}
+
+inline bool KThemeBase::roundComboBox() const
+{
+ return ( roundedCombo );
+}
+
+inline bool KThemeBase::roundSlider() const
+{
+ return ( roundedSlider );
+}
+
+inline bool KThemeBase::activeTabLine() const
+{
+ return ( aTabLine );
+}
+
+inline bool KThemeBase::inactiveTabLine() const
+{
+ return ( iTabLine );
+}
+
+inline int KThemeBase::getSBExtent() const
+{
+ return ( sbExtent );
+}
+
+inline KThemePixmap* KThemeBase::borderPixmap( WidgetType widget ) const
+{
+ return ( pbPixmaps[ widget ] );
+}
+
+#endif
diff --git a/kstyles/kthemestyle/kthemestyle.cpp b/kstyles/kthemestyle/kthemestyle.cpp
new file mode 100644
index 000000000..cdb419772
--- /dev/null
+++ b/kstyles/kthemestyle/kthemestyle.cpp
@@ -0,0 +1,2384 @@
+/*
+ $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
+
+ Includes code portions from the dotNET style, and the KDE HighColor style.
+
+ dotNET Style
+ Copyright (C) 2001, Chris Lee <lee@azsites.com>
+ Carsten Pfeiffer <pfeiffer@kde.org>
+
+ 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 "kthemestyle.h"
+#include "kthemebase.h"
+#include <qstyleplugin.h>
+#include <qstylefactory.h>
+#include <kimageeffect.h>
+
+#include <qbitmap.h>
+#include <qcheckbox.h>
+#include <qlabel.h>
+#define INCLUDE_MENUITEM_DEF
+#include <qmenudata.h>
+#include <qpopupmenu.h>
+#include <qpalette.h>
+#include <qtabbar.h>
+#include <qtoolbutton.h>
+#include <kglobalsettings.h>
+#include <kdrawutil.h>
+#include <qdrawutil.h>
+#include <qprogressbar.h>
+#include <qdir.h>
+#include <qapplication.h>
+#include <qmenubar.h>
+#include <qrangecontrol.h>
+#include <qslider.h>
+#include <qtooltip.h>
+#include <qobjectlist.h>
+#include <qradiobutton.h>
+#include <qstatusbar.h>
+#include "kstyledirs.h"
+
+#include <qimage.h>
+
+#include <limits.h>
+
+#ifdef __GLIBC__
+#include <dlfcn.h>
+#endif
+
+static const QCOORD u_arrow[] = { -1, -3, 0, -3, -2, -2, 1, -2, -3, -1, 2, -1, -4, 0, 3, 0, -4, 1, 3, 1};
+static const QCOORD d_arrow[] = { -4, -2, 3, -2, -4, -1, 3, -1, -3, 0, 2, 0, -2, 1, 1, 1, -1, 2, 0, 2};
+static const QCOORD l_arrow[] = { -3, -1, -3, 0, -2, -2, -2, 1, -1, -3, -1, 2, 0, -4, 0, 3, 1, -4, 1, 3};
+static const QCOORD r_arrow[] = { -2, -4, -2, 3, -1, -4, -1, 3, 0, -3, 0, 2, 1, -2, 1, 1, 2, -1, 2, 0};
+
+const QCOORD win_style_u_arrow[] = { 0, -2, 0, -2, -1, -1, 1, -1, -2, 0, 2, 0, -3, 1, 3, 1 };
+const QCOORD win_style_d_arrow[] = { -3, -2, 3, -2, -2, -1, 2, -1, -1, 0, 1, 0, 0, 1, 0, 1 };
+const QCOORD win_style_l_arrow[] = { 1, -3, 1, -3, 0, -2, 1, -2, -1, -1, 1, -1, -2, 0, 1, 0, -1, 1, 1, 1, 0, 2, 1, 2, 1, 3, 1, 3 };
+const QCOORD win_style_r_arrow[] = { -2, -3, -2, -3, -2, -2, -1, -2, -2, -1, 0, -1, -2, 0, 1, 0, -2, 1, 0, 1, -2, 2, -1, 2, -2, 3, -2, 3 };
+
+
+#define QCOORDARRLEN(x) sizeof(x)/(sizeof(QCOORD)*2)
+
+
+static const int itemFrame = 2;
+static const int itemHMargin = 3;
+static const int itemVMargin = 1;
+static const int arrowHMargin = 6;
+static const int rightBorder = 12;
+
+
+/*
+BUGS:
+Sliders flash a bit -- anything else?
+
+TODO:
+Nicer disabled buttons.
+Sliders are not disabled properly
+*/
+
+
+class KThemeStylePlugin : public QStylePlugin
+{
+public:
+
+ KThemeStylePlugin()
+ {
+#ifdef __GLIBC__
+ dlopen("kthemestyle.so",RTLD_LAZY);
+ //####### Keep reference count up so kdecore w. fast-malloc doesn't get unloaded
+ //####### (Fixes exit crashes with qt-only apps that occur on Linux)
+ //####### This should be rethought after 3.0,
+ //####### as it relies on the implementation-specific behavior
+ //####### of the glibc libdl (finding already loaded libraries based on the
+ //####### soname)
+#endif
+ }
+
+ ~KThemeStylePlugin()
+ {}
+
+ QStringList keys() const
+ {
+ QSettings cfg;
+ KStyleDirs::dirs()->addToSearch( "config", cfg );
+
+ QStringList keys;
+ bool ok;
+
+ keys = cfg.readListEntry( "/kthemestyle/themes", &ok);
+ if ( !ok )
+ qWarning( "KThemeStyle cache seems corrupt!\n" ); //Too bad one can't i18n this :-(
+
+ return keys;
+ }
+
+ QStyle* create( const QString& key )
+ {
+ QSettings cfg;
+ KStyleDirs::dirs()->addToSearch( "config", cfg );
+
+ QString file = cfg.readEntry( "/kthemestyle/" + key + "/file" );
+ if ( !key.isEmpty() )
+ {
+ QFileInfo fi( file );
+ return new KThemeStyle( fi.dirPath(), fi.fileName() );
+ }
+
+ return 0;
+ }
+};
+
+KDE_Q_EXPORT_PLUGIN( KThemeStylePlugin )
+
+
+void kDrawWindowsArrow ( QPainter *p, const QStyle* style, QStyle::PrimitiveElement pe, bool down,
+ int x, int y, int w, int h,
+ const QColorGroup &cg, bool enabled )
+{
+ QPointArray a;
+ switch ( pe )
+ {
+ case QStyle::PE_ArrowUp:
+ a.setPoints( QCOORDARRLEN( win_style_u_arrow ), win_style_u_arrow );
+ break;
+
+ case QStyle::PE_ArrowDown:
+ a.setPoints( QCOORDARRLEN( win_style_d_arrow ), win_style_d_arrow );
+ break;
+
+ case QStyle::PE_ArrowLeft:
+ a.setPoints( QCOORDARRLEN( win_style_l_arrow ), win_style_l_arrow );
+ break;
+ default:
+ a.setPoints( QCOORDARRLEN( win_style_r_arrow ), win_style_r_arrow );
+ }
+
+ p->save();
+ if ( down )
+ {
+ p->translate( style->pixelMetric( QStyle::PM_ButtonShiftHorizontal ),
+ style->pixelMetric( QStyle::PM_ButtonShiftVertical ) );
+ }
+
+ if ( enabled )
+ {
+ a.translate( x + w / 2, y + h / 2 );
+ p->setPen( cg.buttonText() );
+ p->drawLineSegments( a );
+ }
+ else
+ {
+ a.translate( x + w / 2 + 1, y + h / 2 + 1 );
+ p->setPen( cg.light() );
+ p->drawLineSegments( a );
+ a.translate( -1, -1 );
+ p->setPen( cg.mid() );
+ p->drawLineSegments( a );
+ }
+
+ p->restore();
+
+}
+
+
+
+QSize KThemeStyle::sizeFromContents( ContentsType contents,
+ const QWidget* widget,
+ const QSize &contentSize,
+ const QStyleOption& opt ) const
+{
+ switch ( contents )
+ {
+ // PUSHBUTTON SIZE
+ // ------------------------------------------------------------------
+ case CT_PushButton:
+ {
+ const QPushButton * button = ( const QPushButton* ) widget;
+ int w = contentSize.width();
+ int h = contentSize.height();
+ int bm = pixelMetric( PM_ButtonMargin, widget );
+ int fw = pixelMetric( PM_DefaultFrameWidth, widget ) * 2;
+
+ w += bm + fw + 6; // ### Add 6 to make way for bold font.
+ h += bm + fw;
+
+ // Ensure we stick to standard width and heights.
+ if ( button->isDefault() || button->autoDefault() )
+ {
+ if ( w < 80 && !button->text().isEmpty() )
+ w = 80;
+ }
+
+ if ( h < 22 )
+ h = 22;
+
+ return QSize( w, h );
+ }
+
+ // POPUPMENU ITEM SIZE
+ // -----------------------------------------------------------------
+ case CT_PopupMenuItem:
+ {
+ if ( ! widget || opt.isDefault() )
+ return contentSize;
+
+ const QPopupMenu *popup = ( const QPopupMenu * ) widget;
+ bool checkable = popup->isCheckable();
+ QMenuItem *mi = opt.menuItem();
+ int maxpmw = opt.maxIconWidth();
+ int w = contentSize.width(), h = contentSize.height();
+
+ if ( mi->custom() )
+ {
+ w = mi->custom() ->sizeHint().width();
+ h = mi->custom() ->sizeHint().height();
+ if ( ! mi->custom() ->fullSpan() )
+ h += 2 * itemVMargin + 2 * itemFrame;
+ }
+ else if ( mi->widget() )
+ {}
+ else if ( mi->isSeparator() )
+ {
+ w = 10; // Arbitrary
+ h = 2;
+ }
+ else
+ {
+ if ( mi->pixmap() )
+ h = QMAX( h, mi->pixmap() ->height() + 2 * itemFrame );
+ else
+ h = QMAX( h, popup->fontMetrics().height()
+ + 2 * itemVMargin + 2 * itemFrame );
+
+ if ( mi->iconSet() )
+ h = QMAX( h, mi->iconSet() ->pixmap(
+ QIconSet::Small, QIconSet::Normal ).height() +
+ 2 * itemFrame );
+ }
+
+ if ( ! mi->text().isNull() && mi->text().find( '\t' ) >= 0 )
+ w += 12;
+ else if ( mi->popup() )
+ w += 2 * arrowHMargin;
+
+ if ( maxpmw )
+ w += maxpmw + 6;
+ if ( checkable && maxpmw < 20 )
+ w += 20 - maxpmw;
+ if ( checkable || maxpmw > 0 )
+ w += 12;
+
+ w += rightBorder;
+
+ return QSize( w, h );
+ }
+
+ default:
+ return KThemeBase::sizeFromContents( contents, widget, contentSize, opt );
+ }
+}
+
+
+QRect KThemeStyle::subRect(SubRect sr, const QWidget* widget) const
+{
+ if (sr == SR_CheckBoxFocusRect)
+ {
+ const QCheckBox* cb = static_cast<const QCheckBox*>(widget);
+
+ //Only checkbox, no label
+ if (cb->text().isEmpty() && (cb->pixmap() == 0) )
+ {
+ QRect bounding = cb->rect();
+
+ int cw = pixelMetric(PM_IndicatorWidth, widget);
+ int ch = pixelMetric(PM_IndicatorHeight, widget);
+
+ QRect checkbox(bounding.x() + 2, bounding.y() + 2 + (bounding.height() - ch)/2, cw - 4, ch - 4);
+
+ return checkbox;
+ }
+ }
+ return KStyle::subRect(sr, widget);
+}
+
+int KThemeStyle::pixelMetric ( PixelMetric metric, const QWidget * widget ) const
+{
+ switch ( metric )
+ {
+ case PM_MenuBarFrameWidth:
+ return 1;
+ case PM_DefaultFrameWidth:
+ return ( frameWidth() );
+
+ case PM_ButtonMargin:
+ return decoWidth( PushButton ) > decoWidth( PushButtonDown ) ?
+ 3 + decoWidth( PushButton ) : 3 + decoWidth( PushButtonDown );
+
+ case PM_ScrollBarExtent:
+ case PM_SliderThickness: //Should this be 16 always?
+ return getSBExtent();
+
+ case PM_ButtonDefaultIndicator:
+ return 0;
+
+ case PM_ButtonShiftHorizontal:
+ return buttonXShift();
+
+ case PM_ButtonShiftVertical:
+ return buttonYShift();
+
+ case PM_ExclusiveIndicatorWidth:
+ if ( isPixmap( ExIndicatorOn ) )
+ return ( uncached( ExIndicatorOn ) ->size().width() );
+ else
+ return KThemeBase::pixelMetric ( metric, widget );
+
+ case PM_ExclusiveIndicatorHeight:
+ if ( isPixmap( ExIndicatorOn ) )
+ return ( uncached( ExIndicatorOn ) ->size().height() );
+ else
+ return KThemeBase::pixelMetric ( metric, widget );
+
+
+ case PM_IndicatorWidth:
+ if ( isPixmap( IndicatorOn ) )
+ return ( uncached( IndicatorOn ) ->size().width() );
+ else
+ return KThemeBase::pixelMetric ( metric, widget );
+
+ case PM_IndicatorHeight:
+ if ( isPixmap( IndicatorOn ) )
+ return ( uncached( IndicatorOn ) ->size().height() );
+ else
+ return KThemeBase::pixelMetric ( metric, widget );
+
+ case PM_SliderLength:
+ return ( sliderButtonLength() );
+
+ case PM_SplitterWidth:
+ return ( splitWidth() );
+
+ default:
+ return KThemeBase::pixelMetric ( metric, widget );
+ }
+}
+
+
+
+KThemeStyle::KThemeStyle( const QString& configDir, const QString &configFile )
+ : KThemeBase( configDir, configFile ), paletteSaved( false ), polishLock( false ), menuCache( 0 ), vsliderCache( 0 ),
+ brushHandle( 0 ), brushHandleSet( false ), kickerMode( false )
+{
+ mtfstyle = QStyleFactory::create( "Motif" );
+ if ( !mtfstyle )
+ mtfstyle = QStyleFactory::create( *( QStyleFactory::keys().begin() ) );
+}
+
+KThemeStyle::~KThemeStyle()
+{
+ delete vsliderCache;
+ delete menuCache;
+
+}
+
+
+void KThemeStyle::polish( QApplication * app )
+{
+ if (!qstrcmp(app->argv()[0], "kicker"))
+ kickerMode = true;
+}
+
+
+void KThemeStyle::polish( QPalette &p )
+{
+ if ( polishLock )
+ {
+ return ; //Palette polishing disabled ...
+ }
+
+
+
+ if ( !paletteSaved )
+ {
+ oldPalette = p;
+ paletteSaved = true;
+ }
+
+ p = overridePalette( p );
+
+ if ( isPixmap( Background ) )
+ {
+ QBrush bgBrush( p.color( QPalette::Normal,
+ QColorGroup::Background ),
+ *uncached( Background ) );
+ brushHandle = uncached( Background )->handle();
+ brushHandleSet = true;
+ p.setBrush( QColorGroup::Background, bgBrush );
+ }
+
+}
+
+void KThemeStyle::paletteChanged()
+{
+ QPalette p = QApplication::palette();
+ polish( p );
+ QApplication::setPalette( p );
+}
+
+
+void KThemeStyle::unPolish( QApplication *app )
+{
+ app->setPalette( oldPalette, true );
+}
+
+bool KThemeStyle::eventFilter( QObject* object, QEvent* event )
+{
+ if( object->inherits("KActiveLabel"))
+ {
+ if(event->type() == QEvent::Move || event->type() == QEvent::Resize ||
+ event->type() == QEvent::Show)
+ {
+ QWidget *w = static_cast<QWidget*>(object);
+ QPoint pos(0, 0);
+ pos = w->mapTo(w->topLevelWidget(), pos);
+ QPixmap pix(uncached( Background )->size());
+ QPainter p;
+ p.begin(&pix);
+ p.drawTiledPixmap(0, 0,
+ uncached( Background )->width(),
+ uncached( Background )->height() ,
+ *uncached( Background ),
+ pos.x(), pos.y());
+ p.end();
+ QPalette pal(w->palette());
+ QBrush brush( pal.color( QPalette::Normal,
+ QColorGroup::Background),
+ pix );
+ pal.setBrush(QColorGroup::Base, brush);
+ w->setPalette(pal);
+ }
+ }
+ if (!qstrcmp(object->name(), "kde toolbar widget") && object->inherits("QLabel"))
+ {
+ QWidget* lb = static_cast<QWidget*>(object);
+ if (lb->backgroundMode() == Qt::PaletteButton)
+ lb->setBackgroundMode(Qt::PaletteBackground);
+ lb->removeEventFilter(this);
+ }
+
+ return KStyle::eventFilter(object, event);
+}
+
+void KThemeStyle::polish( QWidget *w )
+{
+ if (::qt_cast<QStatusBar*>(w))
+ w->setPaletteBackgroundColor(QApplication::palette().color(QPalette::Normal, QColorGroup::Background));
+
+ if (::qt_cast<QLabel*>(w) && !qstrcmp(w->name(), "kde toolbar widget"))
+ w->installEventFilter(this);
+
+ if (w->backgroundPixmap() && !w->isTopLevel() &&
+ (!kickerMode ||
+ (!w->inherits("TaskBar") && !w->inherits("TaskBarContainer") && !w->inherits("TaskbarApplet") && !w->inherits("ContainerArea") && !w->inherits("AppletHandle"))))
+ {
+ //The brushHandle check verifies that the bg pixmap is actually the brush..
+ if (!brushHandleSet || brushHandle == w->backgroundPixmap()->handle())
+ {
+ w->setBackgroundOrigin( QWidget::WindowOrigin );
+ }
+ }
+
+ if (w->inherits("KActiveLabel"))
+ {
+ if (uncached( Background ))
+ w->installEventFilter(this);
+ }
+
+ if ( w->inherits( "QTipLabel" ) )
+ {
+ polishLock = true;
+
+ QColorGroup clrGroup( Qt::black, QColor( 255, 255, 220 ),
+ QColor( 96, 96, 96 ), Qt::black, Qt::black,
+ Qt::black, QColor( 255, 255, 220 ) );
+ QPalette toolTip ( clrGroup, clrGroup, clrGroup );
+
+ QToolTip::setPalette( toolTip );
+ polishLock = false;
+ }
+
+ if ( w->inherits( "KonqIconViewWidget" ) ) //Konqueror background hack/workaround
+ {
+ w->setPalette( oldPalette );
+ return ;
+ }
+
+ if ( ::qt_cast<QMenuBar*>(w) )
+ {
+ w->setBackgroundMode( QWidget::NoBackground );
+ }
+ else if ( w->inherits( "KToolBarSeparator" ) || w->inherits( "QToolBarSeparator" ) )
+ {
+ w->setBackgroundMode( QWidget::PaletteBackground );
+ }
+ else if ( ::qt_cast<QPopupMenu*>(w) )
+ {
+ popupPalette = w->palette();
+ if ( isColor( MenuItem ) || isColor( MenuItemDown ) )
+ {
+ QPalette newPal( w->palette() );
+ if ( isColor( MenuItem ) )
+ {
+ newPal.setActive( *colorGroup( newPal.active(), MenuItem ) );
+ newPal.setDisabled( *colorGroup( newPal.active(), MenuItem ) );
+ }
+ if ( isColor( MenuItemDown ) )
+ {
+ newPal.setActive( *colorGroup( newPal.active(), MenuItemDown ) );
+ }
+ w->setPalette( newPal );
+ }
+
+ w->setBackgroundMode( QWidget::NoBackground );
+ }
+ else if ( ::qt_cast<QCheckBox*>(w) )
+ {
+ if ( isColor( IndicatorOff ) || isColor( IndicatorOn ) )
+ {
+ QPalette newPal( w->palette() );
+ if ( isColor( IndicatorOff ) )
+ {
+ newPal.setActive( *colorGroup( newPal.active(), IndicatorOff ) );
+ newPal.setDisabled( *colorGroup( newPal.active(), IndicatorOff ) );
+ }
+ if ( isColor( IndicatorOn ) )
+ newPal.setActive( *colorGroup( newPal.active(), IndicatorOn ) );
+ w->setPalette( newPal );
+ }
+ }
+ else if ( ::qt_cast<QRadioButton*>(w) )
+ {
+ if ( isColor( ExIndicatorOff ) || isColor( ExIndicatorOn ) )
+ {
+ QPalette newPal( w->palette() );
+ if ( isColor( ExIndicatorOff ) )
+ {
+ newPal.setActive( *colorGroup( newPal.active(), ExIndicatorOff ) );
+ newPal.setDisabled( *colorGroup( newPal.active(),
+ ExIndicatorOff ) );
+ }
+ if ( isColor( ExIndicatorOn ) )
+ newPal.setActive( *colorGroup( newPal.active(), ExIndicatorOn ) );
+ w->setPalette( newPal );
+ }
+ }
+
+ KStyle::polish( w );
+}
+
+void KThemeStyle::unPolish( QWidget* w )
+{
+ if (w->backgroundPixmap() && !w->isTopLevel())
+ {
+ //The brushHandle check verifies that the bg pixmap is actually the brush..
+ if (!brushHandleSet || brushHandle ==w->backgroundPixmap()->handle())
+ {
+ w->setBackgroundOrigin( QWidget::WidgetOrigin );
+ }
+ }
+
+ //Toolbar labels should nornally be PaletteButton
+ if ( ::qt_cast<QLabel*>(w) && !qstrcmp(w->name(), "kde toolbar widget"))
+ w->setBackgroundMode( QWidget::PaletteButton );
+
+ //The same for menu bars, popup menus
+ else if ( ::qt_cast<QMenuBar*>(w) || ::qt_cast<QPopupMenu*>(w) )
+ w->setBackgroundMode( QWidget::PaletteButton );
+
+ //For toolbar internal separators, return to button, too (can't use qt_cast here since don't have access to the class)
+ else if ( w->inherits( "KToolBarSeparator" ) || w->inherits( "QToolBarSeparator" ) )
+ w->setBackgroundMode( QWidget::PaletteButton );
+
+ //For scrollbars, we don't do much, since the widget queries the style on the switch
+
+ //Drop some custom palettes. ### this really should check the serial number to be 100% correct.
+ if ( ::qt_cast<QPopupMenu*>(w) || ::qt_cast<QCheckBox*>(w) || ::qt_cast<QRadioButton*>(w) || ::qt_cast<QStatusBar*>(w) )
+ w->unsetPalette();
+
+ KStyle::unPolish( w );
+}
+
+
+void KThemeStyle::drawBaseButton( QPainter *p, int x, int y, int w, int h,
+ const QColorGroup &g, bool sunken, bool
+ rounded, WidgetType type ) const
+{
+ int offset = borderPixmap( type ) ? 0 : decoWidth( type ) ; //##### This is wrong, but the code relies on it..
+ QPen oldPen = p->pen();
+
+ // handle reverse bevel here since it uses decowidth differently
+ if ( gradientHint( type ) == GrReverseBevel )
+ {
+ int i;
+ bitBlt( p->device(), x, y, scalePixmap( w, h, type ), 0, 0, w, h,
+ Qt::CopyROP, true );
+ p->setPen( g.text() );
+ for ( i = 0; i < borderWidth( type ); ++i, ++x, ++y, w -= 2, h -= 2 )
+ p->drawRect( x, y, w, h );
+ }
+ // same with KDE style borders
+ else if ( !borderPixmap( type ) && shade() == KDE )
+ {
+ kDrawBeButton( p, x, y, w, h, g, sunken );
+ if ( isPixmap( type ) )
+ p->drawTiledPixmap( x + 4, y + 4, w - 6, h - 6,
+ *scalePixmap( w - 6, h - 6,
+ type ) );
+ else
+ p->fillRect( x + 4, y + 4, w - 6, h - offset * 6,
+ g.brush( QColorGroup::Button ) );
+
+ }
+ else
+ {
+ if ( ( w - offset * 2 ) > 0 && ( h - offset * 2 ) > 0 )
+ {
+ if ( isPixmap( type ) )
+ if ( rounded )
+ p->drawTiledPixmap( x, y, w, h, *scalePixmap( w, h, type ) );
+ else
+ p->drawTiledPixmap( x + offset, y + offset, w - offset * 2,
+ h - offset * 2,
+ *scalePixmap( w - offset * 2, h - offset * 2,
+ type ) );
+ else if ( 1 ) //##### TODO - Get this optimization working... !borderPixmap( type ) || (( w - decoWidth(type) * 2 ) > 0 && ( h - decoWidth(type) * 2 ) > 0) )
+ //Sometimes border covers the whole thing - in that case, avoid drawing the base.
+ {
+ p->fillRect( x + offset, y + offset, w - offset * 2, h - offset * 2,
+ g.brush( QColorGroup::Button ) );
+ }
+ }
+ if ( borderPixmap( type ) )
+ {
+ bitBlt( p->device(), x, y, scaleBorder( w, h, type ), 0, 0, w, h,
+ Qt::CopyROP, false );
+ }
+ else
+ drawShade( p, x, y, w, h, g, sunken, rounded,
+ highlightWidth( type ), borderWidth( type ), shade() );
+ }
+ p->setPen( oldPen );
+}
+
+void KThemeStyle::drawPrimitive ( PrimitiveElement pe, QPainter * p, const QRect & r, const QColorGroup & g_base,
+ SFlags flags, const QStyleOption & opt ) const
+{
+ bool handled = false;
+ int x, y, w, h;
+ r.rect( &x, &y, &w, &h );
+
+ bool sunken = ( flags & Style_Sunken );
+ bool enabled = ( flags & Style_Enabled );
+ bool down = ( flags & Style_Down );
+ bool on = flags & Style_On;
+ QColorGroup g = g_base;
+
+ switch ( pe )
+ {
+ case PE_ArrowUp:
+ case PE_ArrowDown:
+ case PE_ArrowRight:
+ case PE_ArrowLeft:
+ {
+ QRect r( x, y, w, h );
+ if ( r.width() > 12 )
+ {
+ r.setRect( r.x() + ( r.width() - 12 ) / 2, r.y(), 12, r.height() );
+ }
+ if ( r.height() > 12 )
+ {
+ r.setRect( r.x(), r.y() + ( r.height() - 12 ) / 2, r.width(), 12 );
+ }
+ r.rect( &x, &y, &w, &h );
+ // Handles pixmapped arrows. A little inefficient because you can specify
+ // some as pixmaps and some as default types.
+ WidgetType widget;
+ switch ( pe )
+ {
+ case PE_ArrowUp:
+ widget = enabled ? down ? SunkenArrowUp : ArrowUp : DisArrowUp;
+ break;
+ case PE_ArrowDown:
+ widget = enabled ? down ? SunkenArrowDown : ArrowDown : DisArrowDown;
+ break;
+ case PE_ArrowLeft:
+ widget = enabled ? down ? SunkenArrowLeft : ArrowLeft : DisArrowLeft;
+ break;
+ case PE_ArrowRight:
+ default:
+ widget = enabled ? down ? SunkenArrowRight : ArrowRight : DisArrowRight;
+ break;
+ }
+ if ( isPixmap( widget ) )
+ {
+ bitBlt( p->device(), x + ( w - uncached( widget ) ->width() ) / 2,
+ y + ( h - uncached( widget ) ->height() ) / 2,
+ uncached( widget ) );
+
+ return ;
+ }
+ const QColorGroup *cg = colorGroup( g, widget );
+ // Standard arrow types
+ if ( arrowType() == MotifArrow )
+ {
+ mtfstyle->drawPrimitive( pe, p, r, g, flags, opt );
+
+ handled = true;
+ }
+ else if ( arrowType() == SmallArrow )
+ {
+ // #### FIXME: This should be like the Platinum style - uses HighColor look for now
+ QPointArray a;
+
+ switch ( pe )
+ {
+ case PE_ArrowUp:
+ a.setPoints( QCOORDARRLEN( u_arrow ), u_arrow );
+ break;
+
+ case PE_ArrowDown:
+ a.setPoints( QCOORDARRLEN( d_arrow ), d_arrow );
+ break;
+
+ case PE_ArrowLeft:
+ a.setPoints( QCOORDARRLEN( l_arrow ), l_arrow );
+ break;
+
+ default:
+ a.setPoints( QCOORDARRLEN( r_arrow ), r_arrow );
+ }
+
+ p->save();
+
+ if ( flags & Style_Down )
+ p->translate( pixelMetric( PM_ButtonShiftHorizontal ),
+ pixelMetric( PM_ButtonShiftVertical ) );
+
+ if ( flags & Style_Enabled )
+ {
+ a.translate( r.x() + r.width() / 2, r.y() + r.height() / 2 );
+ p->setPen( cg->buttonText() );
+ p->drawLineSegments( a );
+ }
+ else
+ {
+ a.translate( r.x() + r.width() / 2 + 1, r.y() + r.height() / 2 + 1 );
+ p->setPen( cg->mid() );
+ p->drawLineSegments( a );
+ }
+ p->restore();
+ }
+ else
+ {
+ QPointArray a;
+ int x2 = x + w - 1, y2 = y + h - 1;
+ switch ( pe )
+ {
+ case PE_ArrowUp:
+ a.setPoints( 4, x, y2, x2, y2, x + w / 2, y, x, y2 );
+ break;
+ case PE_ArrowDown:
+ a.setPoints( 4, x, y, x2, y, x + w / 2, y2, x, y );
+ break;
+ case PE_ArrowLeft:
+ a.setPoints( 4, x2, y, x2, y2, x, y + h / 2, x2, y );
+ break;
+ default:
+ a.setPoints( 4, x, y, x, y2, x2, y + h / 2, x, y );
+ break;
+ }
+ QBrush oldBrush = p->brush();
+ QPen oldPen = p->pen();
+ p->setBrush( cg->brush( QColorGroup::Shadow ) );
+ p->setPen( cg->shadow() );
+ p->drawPolygon( a );
+ p->setBrush( oldBrush );
+ p->setPen( oldPen );
+ handled = true;
+ }
+ break;
+
+ }
+ case PE_HeaderSection:
+ {
+ sunken = false; //Never mind this one
+ }
+ case PE_ButtonBevel:
+ {
+ WidgetType type = ( sunken || on || down ) ? BevelDown : Bevel;
+ drawBaseButton( p, x, y, w, h, *colorGroup( g, type ), ( sunken || on || down ), false, type );
+ handled = true;
+ break;
+ }
+ case PE_ButtonCommand:
+ {
+ drawBaseButton( p, x, y, w, h, g, ( sunken || on || down ), roundButton(), ( sunken || on || down ) ?
+ PushButtonDown : PushButton );
+ handled = true;
+ break;
+ }
+ case PE_PanelDockWindow:
+ {
+ drawBaseButton( p, x, y, w, h, *colorGroup( g, ToolBar ), false, false,
+ ToolBar );
+ handled = true;
+ break;
+ }
+ case PE_CheckMark:
+ {
+ if ( isPixmap( CheckMark ) )
+ {
+ if ( flags & Style_Enabled || flags & Style_On )
+ bitBlt( p->device(), x + ( w - uncached( CheckMark ) ->width() ) / 2,
+ y + ( h - uncached( CheckMark ) ->height() ) / 2,
+ uncached( CheckMark ) );
+ handled = true;
+ }
+ else //Small hack to ensure the checkmark gets painter proper color..
+ {
+ g.setColor( QColorGroup::Text, g.buttonText() );
+ }
+ break;
+ }
+ case PE_ExclusiveIndicator:
+ {
+ if ( isPixmap( ( flags & Style_On || flags & Style_Down ) ? ExIndicatorOn : ExIndicatorOff ) )
+ {
+ p->drawPixmap( x, y, *uncached( ( flags & Style_On || flags & Style_Down ) ? ExIndicatorOn :
+ ExIndicatorOff ) );
+ handled = true;
+ }
+
+ break;
+ }
+ case PE_ExclusiveIndicatorMask:
+ {
+ if ( isPixmap( ( flags & Style_On || flags & Style_Down ) ? ExIndicatorOn : ExIndicatorOff ) )
+ {
+ const QBitmap * mask = uncached( ( flags & Style_On || flags & Style_Down ) ? ExIndicatorOn : ExIndicatorOff ) ->mask();
+ if ( mask )
+ {
+ p->setPen( Qt::color1 );
+ p->drawPixmap( x, y, *mask );
+ }
+ else
+ p->fillRect( x, y, w, h, QBrush( color1, SolidPattern ) );
+ handled = true;
+ }
+ break;
+ }
+
+ case PE_IndicatorMask:
+ {
+ if ( isPixmap( ( flags & Style_On ) ? IndicatorOn : IndicatorOff ) )
+ {
+ const QBitmap * mask = uncached( ( flags & Style_On ) ? IndicatorOn :
+ IndicatorOff ) ->mask();
+ if ( mask )
+ {
+ p->setPen( Qt::color1 );
+ p->drawPixmap( x, y, *mask );
+ }
+ else
+ p->fillRect( x, y, w, h, QBrush( color1, SolidPattern ) );
+ handled = true;
+ }
+ break;
+ }
+ case PE_Indicator:
+ {
+ if ( isPixmap( ( flags & Style_On || flags & Style_Down ) ?
+ IndicatorOn : IndicatorOff ) )
+ {
+ p->drawPixmap( x, y, *uncached( ( flags & Style_On || flags & Style_Down ) ?
+ IndicatorOn : IndicatorOff ) );
+ handled = true;
+ }
+ break;
+ }
+ case PE_Splitter:
+ {
+ drawBaseButton( p, x, y, w, h, *colorGroup( g, Splitter ), false, false,
+ Splitter );
+ handled = true;
+ break;
+ }
+ case PE_FocusRect:
+ {
+ if ( is3DFocus() )
+ {
+ p->setPen( g.dark() );
+ int i = focusOffset();
+ p->drawLine( r.x() + i, r.y() + 1 + i, r.x() + i, r.bottom() - 1 - i );
+ p->drawLine( r.x() + 1 + i, r.y() + i, r.right() - 1 - i, r.y() + i );
+ p->setPen( g.light() );
+ p->drawLine( r.right() - i, r.y() + 1 + i, r.right() - i, r.bottom() - 1 - i );
+ p->drawLine( r.x() + 1 + i, r.bottom() - i, r.right() - 1 - i, r.bottom() - i );
+ handled = true;
+ }
+ else
+ {
+ handled = true;
+ p->drawWinFocusRect(r);
+ }
+ break;
+ }
+ case PE_PanelMenuBar:
+ {
+ QPixmap* cache = makeMenuBarCache(w, h);
+ p->drawPixmap( x, y, *cache);
+ handled = true;
+ break;
+ }
+ case PE_ScrollBarAddPage:
+ case PE_ScrollBarSubPage:
+ {
+ WidgetType widget = ( flags & Style_Horizontal ) ? HScrollGroove : VScrollGroove;
+
+ if ( !isPixmap( widget ) )
+ {
+ p->fillRect( r, colorGroup( g, widget ) ->brush( QColorGroup::Background ) );
+ // Do the borders and frame
+ drawShade( p, r.x(), r.y(), r.width(),
+ r.height(), *colorGroup( g, widget ), true, false,
+ highlightWidth( widget ), borderWidth( widget ), shade() );
+ }
+ else
+ {
+ // If the groove is pixmapped we make a full-sized image (it gets
+ // cached) then bitBlt it to the appropriate rect.
+ p->drawTiledPixmap( r.x(), r.y(), r.width(), r.height(),
+ *scalePixmap( r.width(), r.height(),
+ widget ) );
+ drawShade( p, r.x(), r.y(), r.width(),
+ r.height(), *colorGroup( g, widget ), true, false,
+ highlightWidth( widget ), borderWidth( widget ), shade() );
+ }
+
+ handled = true;
+ break;
+ }
+ case PE_ScrollBarAddLine:
+ {
+ bool horizontal = ( flags & Style_Horizontal );
+ drawBaseButton( p, r.x(), r.y(), r.width(), r.height(),
+ *colorGroup( g, down ? ScrollButtonDown : ScrollButton ),
+ down, false, down ? ScrollButtonDown : ScrollButton );
+
+ drawPrimitive( ( horizontal ) ? PE_ArrowRight : PE_ArrowDown, p ,
+ QRect( r.x() + 3, r.y() + 3, r.width() - 6, r.height() - 6 ),
+ *colorGroup( g, down ? ScrollButtonDown : ScrollButton ),
+ flags );
+
+ handled = true;
+ break;
+ }
+ case PE_ScrollBarSubLine:
+ {
+ bool horizontal = ( flags & Style_Horizontal );
+ drawBaseButton( p, r.x(), r.y(), r.width(), r.height(),
+ *colorGroup( g, down ? ScrollButtonDown : ScrollButton ),
+ down, false, down ? ScrollButtonDown : ScrollButton );
+
+ drawPrimitive( ( horizontal ) ? PE_ArrowLeft : PE_ArrowUp, p ,
+ QRect( r.x() + 3, r.y() + 3, r.width() - 6, r.height() - 6 ),
+ *colorGroup( g, down ? ScrollButtonDown : ScrollButton ),
+ flags );
+ handled = true;
+ break;
+ }
+ case PE_ScrollBarSlider:
+ {
+ bool active = ( flags & Style_Active ) || ( flags & Style_Down ); //activeControl == QStyle::AddLine;
+ bool horizontal = ( flags & Style_Horizontal );
+ int offsetH = horizontal ? 0: decoWidth(VScrollGroove) ;
+ int offsetV = horizontal ? decoWidth(HScrollGroove):0;
+
+ WidgetType widget = horizontal ?
+ active ? HScrollBarSliderDown : HScrollBarSlider :
+ active ? VScrollBarSliderDown : VScrollBarSlider;
+ drawBaseButton( p, r.x()+offsetH, r.y()+offsetV, r.width()-2*offsetH,
+ r.height()-2*offsetV, *colorGroup( g, widget ), active, false,
+ widget );
+
+ int spaceW = horizontal ? r.width() - decoWidth( widget ) - 4 :
+ r.width();
+ int spaceH = horizontal ? r.height() :
+ r.height() - decoWidth( widget ) - 4;
+
+ widget = active ? horizontal ? HScrollDecoDown : VScrollDecoDown :
+ horizontal ? HScrollDeco : VScrollDeco;
+ if ( isPixmap( widget ) )
+ {
+ if ( spaceW >= uncached( widget ) ->width() &&
+ spaceH >= uncached( widget ) ->height() )
+ {
+ bitBlt( p->device(),
+ r.x() + ( r.width() - uncached( widget ) ->width() ) / 2,
+ r.y() + ( r.height() - uncached( widget ) ->height() ) / 2,
+ uncached( widget ) );
+ }
+ }
+ handled = true;
+ break;
+
+ }
+ default:
+ handled = false;
+ }
+
+ if ( !handled )
+ KThemeBase::drawPrimitive ( pe, p, r, g,
+ flags, opt );
+}
+
+
+
+QPixmap* KThemeStyle::makeMenuBarCache(int w, int h) const
+{
+ if (menuCache)
+ {
+ if (menuCache->width() != w || menuCache->height() != h )
+ {
+ delete menuCache;
+ }
+ else
+ return menuCache;
+ }
+
+ const QColorGroup *g = colorGroup( QApplication::palette().active(), MenuBar);
+
+ menuCache = new QPixmap ( w, h );
+ QPainter p(menuCache);
+ drawBaseButton( &p, 0, 0, w, h, *g, false, false, MenuBar );
+ p.end();
+ return menuCache;
+}
+
+
+void KThemeStyle::drawControl( ControlElement element,
+ QPainter *p,
+ const QWidget *widget,
+ const QRect &r,
+ const QColorGroup &cg,
+ SFlags how ,
+ const QStyleOption& opt ) const
+{
+ bool handled = false;
+ int x, y, w, h;
+ r.rect( &x, &y, &w, &h );
+
+
+ switch ( element )
+ {
+ case CE_PushButton:
+ {
+ const QPushButton * btn = ( const QPushButton* ) widget;
+ bool sunken = btn->isOn() || btn->isDown();
+ int diw = pixelMetric( PM_ButtonDefaultIndicator, btn );
+ drawBaseButton( p, diw, diw, w - 2 * diw, h - 2 * diw,
+ *colorGroup( btn->colorGroup(), sunken ? PushButtonDown :
+ PushButton ), sunken, roundButton(),
+ sunken ? PushButtonDown : PushButton );
+ // TODO if diw, draw fancy default button indicator
+ handled = true;
+ break;
+ }
+ case CE_PushButtonLabel:
+ {
+ const QPushButton* button = ( const QPushButton* ) widget;
+ bool active = button->isOn() || button->isDown();
+ int x, y, w, h;
+ r.rect( &x, &y, &w, &h );
+
+ // Shift button contents if pushed.
+ if ( active )
+ {
+ x += pixelMetric( PM_ButtonShiftHorizontal, widget );
+ y += pixelMetric( PM_ButtonShiftVertical, widget );
+ how |= Style_Sunken;
+ }
+
+ // Does the button have a popup menu?
+ if ( button->isMenuButton() )
+ {
+ int dx = pixelMetric( PM_MenuButtonIndicator, widget );
+ drawPrimitive( PE_ArrowDown, p, QRect( x + w - dx - 2, y + 2, dx, h - 4 ),
+ cg, how, opt );
+ w -= dx;
+ }
+
+ // Draw the icon if there is one
+ if ( button->iconSet() && !button->iconSet() ->isNull() )
+ {
+ QIconSet::Mode mode = QIconSet::Disabled;
+ QIconSet::State state = QIconSet::Off;
+
+ if ( button->isEnabled() )
+ mode = button->hasFocus() ? QIconSet::Active : QIconSet::Normal;
+ if ( button->isToggleButton() && button->isOn() )
+ state = QIconSet::On;
+
+ QPixmap pixmap = button->iconSet() ->pixmap( QIconSet::Small, mode, state );
+
+ // Center the iconset if there's no text or pixmap
+ if (button->text().isEmpty() && !button->pixmap())
+ p->drawPixmap( x + (w - pixmap.width()) / 2,
+ y + (h - pixmap.height()) / 2, pixmap );
+ else
+ p->drawPixmap( x + 4, y + (h - pixmap.height()) / 2, pixmap );
+
+ int pw = pixmap.width();
+ x += pw + 4;
+ w -= pw + 4;
+ }
+
+ // Make the label indicate if the button is a default button or not
+ if ( active || button->isDefault() && button->isEnabled() )
+ {
+ // Draw "fake" bold text - this enables the font metrics to remain
+ // the same as computed in QPushButton::sizeHint(), but gives
+ // a reasonable bold effect.
+ int i;
+
+ // Text shadow
+ for ( i = 0; i < 2; i++ )
+ drawItem( p, QRect( x + i + 1, y + 1, w, h ), AlignCenter | ShowPrefix,
+ button->colorGroup(), button->isEnabled(), NULL,
+ button->text(), -1,
+ active ? &button->colorGroup().dark() : &button->colorGroup().mid() );
+
+ // Normal Text
+ for ( i = 0; i < 2; i++ )
+ drawItem( p, QRect( x + i, y, w, h ), AlignCenter | ShowPrefix,
+ button->colorGroup(), true, i == 0 ? button->pixmap() : NULL,
+ button->text(), -1,
+ active ? &button->colorGroup().light() : &button->colorGroup().buttonText() );
+ }
+ else
+ {
+ if ( button->isEnabled() )
+ {
+ drawItem( p, QRect( x, y, w, h ), AlignCenter | ShowPrefix, button->colorGroup(),
+ true, button->pixmap(), button->text(), -1,
+ active ? &button->colorGroup().light() : &button->colorGroup().buttonText() );
+ }
+ else
+ {
+ //TODO: Handle reversed
+ drawItem( p, QRect( x + 1, y + 1, w, h ), AlignCenter | ShowPrefix, button->colorGroup(),
+ true, button->pixmap(), button->text(), -1,
+ &button->colorGroup().light() );
+
+ drawItem( p, QRect( x, y, w, h ), AlignCenter | ShowPrefix, button->colorGroup(),
+ true, button->pixmap(), button->text(), -1,
+ &button->colorGroup().buttonText() );
+ }
+ }
+
+ // Draw a focus rect if the button has focus
+ if ( how & Style_HasFocus )
+ drawPrimitive( PE_FocusRect, p,
+ QStyle::visualRect( subRect( SR_PushButtonFocusRect, widget ), widget ),
+ cg, how );
+ handled = true;
+ break;
+ }
+
+ case CE_MenuBarEmptyArea:
+ {
+ //Expand to cover entire region
+ drawPrimitive(PE_PanelMenuBar, p,
+ QRect(0,0,r.width()+r.x()*2, r.height()+r.y()*2),
+ cg, Style_Default);
+ handled = true;
+ break;
+ }
+
+ case CE_TabBarTab:
+ {
+ const QTabBar* tb = ( const QTabBar* ) widget;
+ QTabBar::Shape tbs = tb->shape();
+ bool selected = how & Style_Selected;
+ WidgetType widget = selected ? ActiveTab : InactiveTab;
+ const QColorGroup *cg = colorGroup( tb->colorGroup(), widget );
+ int i;
+ int x2 = x + w - 1, y2 = y + h - 1;
+ int bWidth = borderWidth( widget );
+ int hWidth = highlightWidth( widget );
+ handled = true;
+ if ( tbs == QTabBar::RoundedAbove || tbs == QTabBar::TriangularAbove )
+ {
+ if ( !selected )
+ {
+ p->fillRect( x, y, x2 - x + 1, 2,
+ tb->palette().active().brush( QColorGroup::Background ) );
+ y += 2;
+ }
+ p->setPen( cg->text() );
+ i = 0;
+ if ( i < bWidth )
+ {
+ p->drawLine( x, y + 1, x, y2 );
+ p->drawLine( x2, y + 1, x2, y2 );
+ p->drawLine( x + 1, y, x2 - 1, y );
+ if ( selected ? activeTabLine() : inactiveTabLine() )
+ {
+ p->drawLine( x, y2, x2, y2 );
+ --y2;
+ }
+ ++i, ++x, ++y, --x2;
+ }
+ for ( ; i < bWidth; ++i, ++x, ++y, --x2 )
+ {
+ p->drawLine( x, y, x, y2 );
+ p->drawLine( x2, y, x2, y2 );
+ p->drawLine( x, y, x2, y );
+ if ( selected ? activeTabLine() : inactiveTabLine() )
+ {
+ p->drawLine( x, y2, x2, y2 );
+ --y2;
+ }
+ }
+ i = 0;
+ if ( i < hWidth && bWidth == 0 )
+ {
+ p->setPen( cg->light() );
+ p->drawLine( x, y + 1, x, y2 );
+ p->drawLine( x + 1, y, x2 - 1, y );
+ p->setPen( cg->dark() );
+ p->drawLine( x2, y + 1, x2, y2 );
+ if ( selected ? activeTabLine() : inactiveTabLine() )
+ {
+ p->drawLine( x, y2, x2, y2 );
+ --y2;
+ }
+ ++i, ++x, ++y, --x2;
+ }
+ for ( ; i < hWidth; ++i, ++x, ++y, --x2 )
+ {
+ p->setPen( cg->light() );
+ p->drawLine( x, y, x, y2 );
+ p->drawLine( x, y, x2, y );
+ p->setPen( cg->dark() );
+ p->drawLine( x2, y + 1, x2, y2 );
+ if ( selected ? activeTabLine() : inactiveTabLine() )
+ {
+ p->drawLine( x, y2, x2, y2 );
+ --y2;
+ }
+ }
+ if ( isPixmap( widget ) )
+ p->drawTiledPixmap( x, y, x2 - x + 1, y2 - y + 1,
+ *scalePixmap( x2 - x + 1, y2 - y + 1, widget ) );
+ else
+ p->fillRect( x, y, x2 - x + 1, y2 - y + 1, cg->background() );
+ }
+ else if ( tb->shape() == QTabBar::RoundedBelow ||
+ tb->shape() == QTabBar::TriangularBelow )
+ {
+ if ( widget == ActiveTab )
+ widget = RotActiveTab;
+ else
+ widget = RotInactiveTab;
+
+ if ( !selected )
+ {
+ p->fillRect( x, y2 - 2, x2 - x + 1, 2,
+ tb->palette().active().brush( QColorGroup::Background ) );
+ y2 -= 2;
+ }
+ p->setPen( cg->text() );
+ i = 0;
+ if ( i < bWidth )
+ {
+ p->drawLine( x, y, x, y2 - 1 );
+ p->drawLine( x2, y, x2, y2 - 1 );
+ p->drawLine( x + 1, y2, x2 - 1, y2 );
+ if ( selected ? activeTabLine() : inactiveTabLine() )
+ {
+ p->drawLine( x, y, x2, y );
+ ++y;
+ }
+ }
+ for ( ; i < bWidth; ++i, ++x, --x2, --y2 )
+ {
+ p->drawLine( x, y, x, y2 );
+ p->drawLine( x2, y, x2, y2 );
+ p->drawLine( x, y2, x2, y2 );
+ if ( selected ? activeTabLine() : inactiveTabLine() )
+ {
+ p->drawLine( x, y, x2, y );
+ ++y;
+ }
+ }
+ i = 0;
+ if ( i < hWidth && bWidth == 0 )
+ {
+ p->setPen( cg->dark() );
+ p->drawLine( x + 1, y2, x2 - 1, y2 );
+ p->drawLine( x2, y, x2, y2 - 1 );
+ p->setPen( cg->light() );
+ p->drawLine( x, y, x, y2 - 1 );
+ if ( selected ? activeTabLine() : inactiveTabLine() )
+ {
+ p->drawLine( x, y, x2, y );
+ ++y;
+ }
+ ++i, ++x, --x2, --y2;
+ }
+ for ( ; i < hWidth; ++i, ++x, --x2, --y2 )
+ {
+ p->setPen( cg->dark() );
+ p->drawLine( x, y2, x2, y2 );
+ p->drawLine( x2, y, x2, y2 );
+ p->setPen( cg->light() );
+ p->drawLine( x, y, x, y2 );
+ if ( selected ? activeTabLine() : inactiveTabLine() )
+ {
+ p->drawLine( x, y, x2, y );
+ ++y;
+ }
+ }
+ if ( isPixmap( widget ) )
+ p->drawTiledPixmap( x, y, x2 - x + 1, y2 - y + 1,
+ *scalePixmap( x2 - x + 1, y2 - y + 1, widget ) );
+ else
+ p->fillRect( x, y, x2 - x + 1, y2 - y + 1, cg->background() );
+ }
+ break;
+ }
+ case CE_MenuBarItem:
+ {
+
+ r.rect( &x, &y, &w, &h );
+ QMenuItem *mi = opt.menuItem();
+ QMenuBar *mb = ( QMenuBar* ) widget;
+ QRect pr = mb->rect();
+ bool active = how & Style_Active;
+ //bool focused = how & Style_HasFocus;
+ const QColorGroup *g = colorGroup( cg, active ? MenuBarItem : MenuBar );
+ QColor btext = g->buttonText();
+
+ QPixmap* cache = makeMenuBarCache(pr.width(), pr.height());
+
+ QPixmap buf( w, pr.height() );
+
+ bitBlt(&buf, 0, 0, cache, x, y, w, pr.height());
+ QPainter p2( &buf );
+
+ if ( active )
+ {
+ drawBaseButton( &p2, 0, 0, w, h, *g, false, false, MenuBarItem );
+ }
+
+ p2.end();
+ p->drawPixmap( x, y, buf, 0, 0, w, h );
+
+ drawItem( p, QRect(x,y,w,h), AlignCenter | AlignVCenter | ShowPrefix | DontClip | SingleLine,
+ *g, mi->isEnabled(), mi->pixmap(), mi->text(),
+ -1, &btext );
+ handled = true;
+ break;
+ }
+ case CE_PopupMenuItem:
+ {
+ bool separator = false;
+ int x, y, w, h;
+ r.rect( &x, &y, &w, &h );
+
+ const QPopupMenu *popupmenu = ( const QPopupMenu * ) widget;
+ QMenuItem *mi = opt.menuItem();
+ if ( mi )
+ {
+ separator = mi->isSeparator();
+ }
+
+ int tab = opt.tabWidth();
+ int checkcol = opt.maxIconWidth();
+ bool enabled = (mi? mi->isEnabled():true);
+ bool checkable = popupmenu->isCheckable();
+ bool active = how & Style_Active;
+ bool etchtext = styleHint( SH_EtchDisabledText, 0 );
+ bool reverse = QApplication::reverseLayout();
+
+ const QColorGroup& cg_ours = *colorGroup( cg, active ? MenuItemDown : MenuItem );
+ //QColor btext = cg_ours.buttonText();
+
+
+ if ( checkable )
+ checkcol = QMAX( checkcol, 20 );
+
+ // Are we a menu item separator?
+ if ( separator )
+ {
+ p->setPen( cg_ours.dark() );
+ p->drawLine( x, y, x + w, y );
+ p->setPen( cg_ours.light() );
+ p->drawLine( x, y + 1, x + w, y + 1 );
+ break;
+ }
+
+ // Draw the menu item background
+ if ( active )
+ drawBaseButton( p, x, y, w, h, cg_ours, true, false, MenuItemDown );
+ else
+ {
+ drawShade( p, x, y, w, h, *colorGroup( cg_ours, MenuItem ), false, false,
+ highlightWidth( MenuItem ), borderWidth( MenuItem ),
+ shade() );
+ int dw = decoWidth( MenuItem );
+ if ( !isPixmap( MenuItem ) )
+ {
+ p->fillRect(
+ x + dw, y + dw, w - dw * 2, h - dw * 2,
+ cg_ours.brush( QColorGroup::Background ) );
+ //cg.brush( QColorGroup::Background ));
+ //colorGroup( cg_ours, MenuItem ) ->brush( QColorGroup::Background ) );
+ }
+ else
+ {
+ // process inactive item pixmaps as one large item
+ p->drawTiledPixmap( x + dw, y + dw, w - dw * 2, h - dw * 2, *scalePixmap
+ ( w, p->window().height(), MenuItem ),
+ x, y );
+ }
+ }
+
+ if (!mi)
+ break;
+
+ // Do we have an icon?
+ if ( mi->iconSet() )
+ {
+ QIconSet::Mode mode;
+ QRect cr = visualRect( QRect( x, y, checkcol, h ), r );
+
+ // Select the correct icon from the iconset
+ if ( active )
+ mode = enabled ? QIconSet::Active : QIconSet::Disabled;
+ else
+ mode = enabled ? QIconSet::Normal : QIconSet::Disabled;
+
+ // Do we have an icon and are checked at the same time?
+ // Then draw a "pressed" background behind the icon
+ if ( checkable && mi->isChecked() ) //!active && -- ??
+ drawBaseButton( p, cr.x(), cr.y(), cr.width(), cr.height(), *colorGroup( cg_ours, BevelDown ), true, false, BevelDown );
+
+ // Draw the icon
+ QPixmap pixmap = mi->iconSet() ->pixmap( QIconSet::Small, mode );
+ int pixw = pixmap.width();
+ int pixh = pixmap.height();
+ QRect pmr( 0, 0, pixw, pixh );
+ pmr.moveCenter( cr.center() );
+ p->setPen( cg_ours.highlightedText() );
+ p->drawPixmap( pmr.topLeft(), pixmap );
+ }
+
+ // Are we checked? (This time without an icon)
+ else if ( checkable && mi->isChecked() )
+ {
+ int cx = reverse ? x + w - checkcol : x;
+
+ // We only have to draw the background if the menu item is inactive -
+ // if it's active the "pressed" background is already drawn
+ //if ( ! active )
+ // qDrawShadePanel( p, cx, y, checkcol, h, cg_ours, true, 1,
+ // &cg_ours.brush(QColorGroup::Midlight) );
+
+ // Draw the checkmark
+ SFlags cflags = Style_Default;
+ cflags |= active ? Style_Enabled : Style_On;
+
+ drawPrimitive( PE_CheckMark, p, QRect( cx + itemFrame, y + itemFrame,
+ checkcol - itemFrame * 2, h - itemFrame * 2 ), cg_ours, cflags );
+ }
+
+ // Time to draw the menu item label...
+ int xm = itemFrame + checkcol + itemHMargin; // X position margin
+
+ int xp = reverse ? // X position
+ x + tab + rightBorder + itemHMargin + itemFrame - 1 :
+ x + xm;
+
+ int offset = reverse ? -1 : 1; // Shadow offset for etched text
+
+ // Label width (minus the width of the accelerator portion)
+ int tw = w - xm - tab - arrowHMargin - itemHMargin * 3 - itemFrame + 1;
+
+ // Set the color for enabled and disabled text
+ // (used for both active and inactive menu items)
+ p->setPen( enabled ? cg_ours.buttonText() : cg_ours.mid() );
+
+ // This color will be used instead of the above if the menu item
+ // is active and disabled at the same time. (etched text)
+ QColor discol = cg_ours.mid();
+
+ // Does the menu item draw it's own label?
+ if ( mi->custom() )
+ {
+ int m = itemVMargin;
+ // Save the painter state in case the custom
+ // paint method changes it in some way
+ p->save();
+
+ // Draw etched text if we're inactive and the menu item is disabled
+ if ( etchtext && !enabled && !active )
+ {
+ p->setPen( cg_ours.light() );
+ mi->custom() ->paint( p, cg_ours, active, enabled, xp + offset, y + m + 1, tw, h - 2 * m );
+ p->setPen( discol );
+ }
+ mi->custom() ->paint( p, cg_ours, active, enabled, xp, y + m, tw, h - 2 * m );
+ p->restore();
+ }
+ else
+ {
+ // The menu item doesn't draw it's own label
+ QString s = mi->text();
+
+ // Does the menu item have a text label?
+ if ( !s.isNull() )
+ {
+ int t = s.find( '\t' );
+ int m = itemVMargin;
+ int text_flags = AlignVCenter | ShowPrefix | DontClip | SingleLine;
+ text_flags |= reverse ? AlignRight : AlignLeft;
+
+ // Does the menu item have a tabstop? (for the accelerator text)
+ if ( t >= 0 )
+ {
+ int tabx = reverse ? x + rightBorder + itemHMargin + itemFrame :
+ x + w - tab - rightBorder - itemHMargin - itemFrame;
+
+
+ // Draw the right part of the label (accelerator text)
+ if ( etchtext && !enabled && !active )
+ {
+ // Draw etched text if we're inactive and the menu item is disabled
+ p->setPen( cg_ours.light() );
+ p->drawText( tabx + offset, y + m + 1, tab, h - 2 * m, text_flags, s.mid( t + 1 ) );
+ p->setPen( discol );
+ }
+ p->drawText( tabx, y + m, tab, h - 2 * m, text_flags, s.mid( t + 1 ) );
+ s = s.left( t );
+ }
+
+
+ // Draw the left part of the label (or the whole label
+ // if there's no accelerator)
+ if ( etchtext && !enabled && !active )
+ {
+ // Etched text again for inactive disabled menu items...
+ p->setPen( cg_ours.light() );
+ p->drawText( xp + offset, y + m + 1, tw, h - 2 * m, text_flags, s, t );
+ p->setPen( discol );
+ }
+
+ p->drawText( xp, y + m, tw, h - 2 * m, text_flags, s, t );
+
+ }
+
+ // The menu item doesn't have a text label
+ // Check if it has a pixmap instead
+ else if ( mi->pixmap() )
+ {
+ QPixmap * pixmap = mi->pixmap();
+
+ // Draw the pixmap
+ if ( pixmap->depth() == 1 )
+ p->setBackgroundMode( OpaqueMode );
+
+ int diffw = ( ( w - pixmap->width() ) / 2 )
+ + ( ( w - pixmap->width() ) % 2 );
+ p->drawPixmap( x + diffw, y + itemFrame, *pixmap );
+
+ if ( pixmap->depth() == 1 )
+ p->setBackgroundMode( TransparentMode );
+ }
+ }
+
+ // Does the menu item have a submenu?
+ if ( mi->popup() )
+ {
+ PrimitiveElement arrow = reverse ? PE_ArrowLeft : PE_ArrowRight;
+ int dim = 10 - itemFrame; //We're not very useful to inherit off, so just hardcode..
+ QRect vr = visualRect( QRect( x + w - arrowHMargin - itemFrame - dim,
+ y + h / 2 - dim / 2, dim, dim ), r );
+
+ // Draw an arrow at the far end of the menu item
+ if ( active )
+ {
+ if ( enabled )
+ discol = cg_ours.buttonText();
+
+ QColorGroup g2( discol, cg_ours.highlight(), white, white,
+ enabled ? white : discol, discol, white );
+
+ drawPrimitive( arrow, p, vr, g2, Style_Enabled | Style_Down );
+ }
+ else
+ drawPrimitive( arrow, p, vr, cg_ours,
+ enabled ? Style_Enabled : Style_Default );
+ }
+ handled = true;
+ break;
+ }
+ case CE_ProgressBarGroove:
+ {
+ QBrush bg;
+ const QColorGroup * cg2 = colorGroup( cg, ProgressBg );
+ qDrawWinPanel( p, r, *cg2, true );
+ bg.setColor( cg2->color( QColorGroup::Background ) );
+ if ( isPixmap( ProgressBg ) )
+ bg.setPixmap( *uncached( ProgressBg ) );
+ p->fillRect( x + 2, y + 2, w - 4, h - 4, bg );
+
+ handled = true;
+ break;
+ }
+ case CE_ProgressBarContents:
+ {
+ const QProgressBar* pb = (const QProgressBar*)widget;
+ QRect cr = subRect(SR_ProgressBarContents, widget);
+ double progress = pb->progress();
+ bool reverse = QApplication::reverseLayout();
+ int steps = pb->totalSteps();
+
+ int pstep = 0;
+
+ if (!cr.isValid())
+ return;
+
+ // Draw progress bar
+ if (progress > 0 || steps == 0)
+ {
+ double pg = (steps == 0) ? 0.1 : progress / steps;
+ int width = QMIN(cr.width(), (int)(pg * cr.width()));
+ if (steps == 0)
+ { //Busy indicator
+
+ if (width < 1) width = 1; //A busy indicator with width 0 is kind of useless
+
+ int remWidth = cr.width() - width; //Never disappear completely
+ if (remWidth <= 0) remWidth = 1; //Do something non-crashy when too small...
+
+ pstep = int(progress) % ( 2 * remWidth );
+
+ if ( pstep > remWidth )
+ {
+ //Bounce about.. We're remWidth + some delta, we want to be remWidth - delta...
+ // - ( (remWidth + some delta) - 2* remWidth ) = - (some deleta - remWidth) = remWidth - some delta..
+ pstep = - (pstep - 2 * remWidth );
+ }
+ }
+
+ if ( !reverse )
+ drawBaseButton( p, x + pstep, y, width, h, *colorGroup( cg, ProgressBar ), false, false, ProgressBar );
+ else
+ {
+ //TODO:Optimize
+ QPixmap buf( width, h );
+ QPainter p2( &buf );
+ drawBaseButton( &p2, 0, 0, width, h, *colorGroup( cg, ProgressBar ), false, false, ProgressBar );
+ p2.end();
+ QPixmap mirroredPix = QPixmap( buf.convertToImage().mirror( true, false ) );
+ bitBlt( p->device(), x + w - width - pstep, y, &mirroredPix );
+ }
+ }
+
+ handled = true;
+ break;
+ }
+ default:
+ handled = false;
+ };
+
+ if ( !handled )
+ KThemeBase::drawControl( element,
+ p, widget, r, cg, how, opt );
+}
+
+
+void KThemeStyle::drawControlMask( ControlElement element,
+ QPainter *p,
+ const QWidget *widget,
+ const QRect &r,
+ const QStyleOption& opt ) const
+{
+ bool handled = false;
+ int x, y, w, h;
+ r.rect( &x, &y, &w, &h );
+
+ switch ( element )
+ {
+ case CE_PushButton:
+ {
+ //Is this correct?
+ drawBaseMask( p, x, y, w, h, roundButton() );
+ handled = true;
+ break;
+ }
+ default:
+ handled = false;
+ };
+
+ if ( !handled )
+ KThemeBase::drawControlMask( element,
+ p, widget, r, opt );
+
+}
+
+
+void KThemeStyle::drawKStylePrimitive( KStylePrimitive kpe,
+ QPainter* p,
+ const QWidget* widget,
+ const QRect &r,
+ const QColorGroup &cg,
+ SFlags flags,
+ const QStyleOption& opt ) const
+{
+ bool handled = false;
+ int x, y, w, h;
+ r.rect( &x, &y, &w, &h );
+ switch ( kpe )
+ {
+ case KPE_SliderGroove:
+ {
+ if ( !roundSlider() )
+ {
+ const QSlider * slider = ( const QSlider* ) widget;
+ bool horizontal = slider->orientation() == Horizontal;
+ if ( horizontal )
+ {
+ drawBaseButton( p, x, y, w, h, *colorGroup( cg, SliderGroove ), true,
+ false, SliderGroove );
+ }
+ else
+ {
+ drawBaseButton( p, x, y, w, h, *colorGroup( cg, RotSliderGroove ), true,
+ false, RotSliderGroove );
+ }
+ }
+ else
+ {
+ //This code is from HighColorDefault..
+ const QSlider* slider = ( const QSlider* ) widget;
+ bool horizontal = slider->orientation() == Horizontal;
+ int gcenter = ( horizontal ? r.height() : r.width() ) / 2;
+
+ QRect gr;
+ if ( horizontal )
+ gr = QRect( r.x(), r.y() + gcenter - 3, r.width(), 7 );
+ else
+ gr = QRect( r.x() + gcenter - 3, r.y(), 7, r.height() );
+
+ int x, y, w, h;
+ gr.rect( &x, &y, &w, &h );
+ int x2 = x + w - 1;
+ int y2 = y + h - 1;
+
+ // Draw the slider groove.
+ p->setPen( cg.dark() );
+ p->drawLine( x + 2, y, x2 - 2, y );
+ p->drawLine( x, y + 2, x, y2 - 2 );
+ p->fillRect( x + 2, y + 2, w - 4, h - 4,
+ slider->isEnabled() ? cg.dark() : cg.mid() );
+ p->setPen( cg.shadow() );
+ p->drawRect( x + 1, y + 1, w - 2, h - 2 );
+ p->setPen( cg.light() );
+ p->drawPoint( x + 1, y2 - 1 );
+ p->drawPoint( x2 - 1, y2 - 1 );
+ p->drawLine( x2, y + 2, x2, y2 - 2 );
+ p->drawLine( x + 2, y2, x2 - 2, y2 );
+ }
+ handled = true;
+ break;
+ }
+ case KPE_SliderHandle:
+ {
+ if ( isPixmap( Slider ) )
+ {
+ const QSlider * slider = ( const QSlider* ) widget;
+ bool horizontal = slider->orientation() == Horizontal;
+ if ( horizontal )
+ {
+ bitBlt( p->device(), x, y + ( h - uncached( Slider ) ->height() ) / 2,
+ uncached( Slider ) );
+ }
+ else
+ {
+ if ( !vsliderCache )
+ {
+ QWMatrix r270;
+ r270.rotate( 270 );
+ vsliderCache = new QPixmap( uncached( Slider ) ->xForm( r270 ) );
+ if ( uncached( Slider ) ->mask() )
+ vsliderCache->setMask( uncached( Slider ) ->mask() ->xForm( r270 ) );
+ }
+ bitBlt( p->device(), x + ( w - vsliderCache->width() ) / 2, y,
+ vsliderCache );
+ }
+ }
+ else
+ {
+ //This code again from HighColor..
+ //...except sans the gradient..
+ const QSlider* slider = ( const QSlider* ) widget;
+ bool horizontal = slider->orientation() == Horizontal;
+ int x, y, w, h;
+ r.rect( &x, &y, &w, &h );
+ int x2 = x + w - 1;
+ int y2 = y + h - 1;
+
+ p->setPen( cg.mid() );
+ p->drawLine( x + 1, y, x2 - 1, y );
+ p->drawLine( x, y + 1, x, y2 - 1 );
+ p->setPen( cg.shadow() );
+ p->drawLine( x + 1, y2, x2 - 1, y2 );
+ p->drawLine( x2, y + 1, x2, y2 - 1 );
+
+ p->setPen( cg.light() );
+ p->drawLine( x + 1, y + 1, x2 - 1, y + 1 );
+ p->drawLine( x + 1, y + 1, x + 1, y2 - 1 );
+ p->setPen( cg.dark() );
+ p->drawLine( x + 2, y2 - 1, x2 - 1, y2 - 1 );
+ p->drawLine( x2 - 1, y + 2, x2 - 1, y2 - 1 );
+ p->setPen( cg.midlight() );
+ p->drawLine( x + 2, y + 2, x2 - 2, y + 2 );
+ p->drawLine( x + 2, y + 2, x + 2, y2 - 2 );
+ p->setPen( cg.mid() );
+ p->drawLine( x + 3, y2 - 2, x2 - 2, y2 - 2 );
+ p->drawLine( x2 - 2, y + 3, x2 - 2, y2 - 2 );
+ p->fillRect( QRect( x + 3, y + 3, w - 6, h - 6 ),
+ cg.button() );
+
+ // Paint riffles
+ if ( horizontal )
+ {
+ p->setPen( cg.light() );
+ p->drawLine( x + 5, y + 4, x + 5, y2 - 4 );
+ p->drawLine( x + 8, y + 4, x + 8, y2 - 4 );
+ p->drawLine( x + 11, y + 4, x + 11, y2 - 4 );
+ p->setPen( slider->isEnabled() ? cg.shadow() : cg.mid() );
+ p->drawLine( x + 6, y + 4, x + 6, y2 - 4 );
+ p->drawLine( x + 9, y + 4, x + 9, y2 - 4 );
+ p->drawLine( x + 12, y + 4, x + 12, y2 - 4 );
+ }
+ else
+ {
+ p->setPen( cg.light() );
+ p->drawLine( x + 4, y + 5, x2 - 4, y + 5 );
+ p->drawLine( x + 4, y + 8, x2 - 4, y + 8 );
+ p->drawLine( x + 4, y + 11, x2 - 4, y + 11 );
+ p->setPen( slider->isEnabled() ? cg.shadow() : cg.mid() );
+ p->drawLine( x + 4, y + 6, x2 - 4, y + 6 );
+ p->drawLine( x + 4, y + 9, x2 - 4, y + 9 );
+ p->drawLine( x + 4, y + 12, x2 - 4, y + 12 );
+ }
+ }
+ handled = true;
+ break;
+ }
+ //case KPE_DockWindowHandle:
+ case KPE_ToolBarHandle:
+ case KPE_GeneralHandle:
+ {
+ if ( w > h )
+ drawBaseButton( p, x, y, w, h, *colorGroup( cg, HBarHandle ), false, false,
+ HBarHandle );
+ else
+ drawBaseButton( p, x, y, w, h, *colorGroup( cg, VBarHandle ), false, false,
+ VBarHandle );
+
+ handled = true;
+ break;
+ }
+ default:
+ handled = false;
+
+ }
+
+ if ( !handled )
+ {
+ KThemeBase::drawKStylePrimitive( kpe, p, widget,
+ r, cg, flags, opt );
+ }
+
+}
+
+
+
+
+void KThemeStyle::drawComplexControl ( ComplexControl control, QPainter * p, const QWidget * widget,
+ const QRect & r, const QColorGroup & g, SFlags how ,
+ SCFlags controls, SCFlags active,
+ const QStyleOption & opt ) const
+{
+ bool handled = false;
+ int x, y, w, h;
+ r.rect( &x, &y, &w, &h );
+ bool down = how & Style_Down;
+ bool on = how & Style_On;
+
+ // bool enabled = ( how & Style_Enabled );
+
+ switch ( control )
+ {
+ case CC_ToolButton:
+ {
+ const QToolButton * toolbutton = ( const QToolButton * ) widget;
+ QRect button, menu;
+ button = querySubControlMetrics( control, widget, SC_ToolButton, opt );
+ menu = querySubControlMetrics( control, widget, SC_ToolButtonMenu, opt );
+
+
+ if ( controls & SC_ToolButton )
+ {
+ WidgetType widget = ( down || on ) ? ToolButtonDown : ToolButton;
+
+ drawBaseButton( p, button.x(), button.y(), button.width(), button.height(), *colorGroup( g, widget ), down || on, false,
+ widget );
+
+ // int m = decoWidth( widget );
+ }
+
+ if ( controls & SC_ToolButtonMenu )
+ {
+ drawPrimitive( PE_ArrowDown, p, menu, g, how );
+ /* if ( enabled )
+ kDrawWindowsArrow(p, this, PE_ArrowDown, false, menu.x(), menu.y(), menu.width(), menu.height(),
+ g, true );
+ else
+ kDrawWindowsArrow(p, this, PE_ArrowDown, false, menu.x(), menu.y(), menu.width(), menu.height(),
+ g, false );*/
+ }
+
+ if ( toolbutton->hasFocus() && !toolbutton->focusProxy() )
+ {
+ QRect fr = toolbutton->rect();
+ fr.addCoords( 3, 3, -3, -3 );
+ drawPrimitive( PE_FocusRect, p, fr, g );
+ }
+
+ handled = true;
+ break;
+ }
+
+ case CC_ComboBox:
+ {
+ if ( controls & SC_ComboBoxFrame )
+ {
+ //TODO: Anyway of detecting when the popup is there -- would look nicer if sunken then too..
+ bool sunken = ( active == SC_ComboBoxArrow );
+ //No frame, edit box and button for now?
+ WidgetType widget = sunken ? ComboBoxDown : ComboBox;
+ drawBaseButton( p, x, y, w, h, *colorGroup( g, widget ), sunken,
+ roundComboBox(), widget );
+
+ controls ^= SC_ComboBoxFrame;
+ }
+
+ if ( controls & SC_ComboBoxArrow )
+ {
+ bool sunken = ( active == SC_ComboBoxArrow );
+ QRect ar = QStyle::visualRect(
+ querySubControlMetrics( CC_ComboBox, widget, SC_ComboBoxArrow ),
+ widget );
+ ar.rect( &x, &y, &w, &h );
+ WidgetType widget = sunken ? ComboBoxDown : ComboBox;
+
+ if ( !sunken && isPixmap( ComboDeco ) )
+ bitBlt( p->device(),
+ x + ( w - uncached( ComboDeco ) ->width() - decoWidth( ComboBox ) / 2 ),
+ y + ( h - uncached( ComboDeco ) ->height() ) / 2,
+ uncached( ComboDeco ) );
+ else if ( sunken && isPixmap( ComboDecoDown ) )
+ bitBlt( p->device(),
+ x + ( w - uncached( ComboDecoDown ) ->width() - decoWidth( ComboBoxDown ) ) / 2,
+ y + ( h - uncached( ComboDecoDown ) ->height() ) / 2,
+ uncached( ComboDecoDown ) );
+ else
+ {
+
+ mtfstyle->drawPrimitive( PE_ArrowDown, p, QRect( x, y, w, h ), *colorGroup( g, widget ), sunken ? ( how | Style_Sunken ) : how, opt );
+ qDrawShadeRect( p, x, y, w, h, *colorGroup( g, widget ) ); //w-14, y+7+(h-15), 10, 3,
+ }
+ controls ^= SC_ComboBoxArrow;
+ }
+ break;
+ }
+ case CC_ScrollBar:
+ {
+ const QScrollBar *sb = ( const QScrollBar* ) widget;
+ bool maxedOut = ( sb->minValue() == sb->maxValue() );
+ bool horizontal = ( sb->orientation() == Qt::Horizontal );
+ SFlags sflags = ( ( horizontal ? Style_Horizontal : Style_Default ) |
+ ( maxedOut ? Style_Default : Style_Enabled ) );
+
+ //Here, we don't do add page, subpage, etc.,
+ QRect addline, subline, subline2, groove, slider;
+ subline = querySubControlMetrics( control, widget, SC_ScrollBarSubLine, opt );
+ addline = querySubControlMetrics( control, widget, SC_ScrollBarAddLine, opt );
+ groove = querySubControlMetrics( control, widget, SC_ScrollBarGroove, opt );
+
+ slider = querySubControlMetrics( control, widget, SC_ScrollBarSlider, opt );
+ subline2 = addline;
+
+ QPixmap buf( sb->width(), sb->height() );
+ QPainter p2( &buf );
+
+ if ( groove.isValid() )
+ {
+ p2.fillRect( groove, QColor( 255, 0, 0 ) );
+ drawPrimitive( PE_ScrollBarSubPage, &p2, groove, g,
+ sflags | ( ( active == SC_ScrollBarSubPage ) ?
+ Style_Down : Style_Default ) );
+ }
+
+
+ // Draw the up/left button set
+ if ( subline.isValid() )
+ {
+ drawPrimitive( PE_ScrollBarSubLine, &p2, subline, g,
+ sflags | ( active == SC_ScrollBarSubLine ?
+ Style_Down : Style_Default ) );
+ }
+
+ if ( addline.isValid() )
+ drawPrimitive( PE_ScrollBarAddLine, &p2, addline, g,
+ sflags | ( ( active == SC_ScrollBarAddLine ) ?
+ Style_Down : Style_Default ) );
+
+ if ( slider.isValid() )
+ { //(controls & SC_ScrollBarSlider) &&
+ drawPrimitive( PE_ScrollBarSlider, &p2, slider, g,
+ sflags | ( ( active == SC_ScrollBarSlider ) ?
+ Style_Down : Style_Default ) );
+ // Draw focus rect
+ if ( sb->hasFocus() )
+ {
+ QRect fr( slider.x() + 2, slider.y() + 2,
+ slider.width() - 5, slider.height() - 5 );
+ drawPrimitive( PE_FocusRect, &p2, fr, g, Style_Default );
+ }
+ p2.end();
+ bitBlt( p->device(), x, y, &buf );
+ handled = true;
+
+ }
+ break;
+ }
+ default:
+ handled = false;
+ }
+
+ if ( !handled )
+ {
+ KThemeBase::drawComplexControl ( control, p, widget,
+ r, g, how ,
+ controls, active,
+ opt );
+ }
+
+}
+
+
+void KThemeStyle::drawBaseMask( QPainter *p, int x, int y, int w, int h,
+ bool round ) const
+{
+ // round edge fills
+ static const QCOORD btm_left_fill[] =
+ {
+ 0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 0, 1, 1, 1, 2, 1, 3, 1, 4, 1,
+ 1, 2, 2, 2, 3, 2, 4, 2, 2, 3, 3, 3, 4, 3, 3, 4, 4, 4
+ };
+
+ static const QCOORD btm_right_fill[] =
+ {
+ 0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 0, 1, 1, 1, 2, 1, 3, 1, 4,
+ 1, 0, 2, 1, 2, 2, 2, 3, 2, 0, 3, 1, 3, 2, 3, 0, 4, 1, 4
+ };
+
+ static const QCOORD top_left_fill[] =
+ {
+ 3, 0, 4, 0, 2, 1, 3, 1, 4, 1, 1, 2, 2, 2, 3, 2, 4, 2, 0, 3,
+ 1, 3, 2, 3, 3, 3, 4, 3, 0, 4, 1, 4, 2, 4, 3, 4, 4, 4
+ };
+
+ static const QCOORD top_right_fill[] =
+ {
+ 0, 0, 1, 0, 0, 1, 1, 1, 2, 1, 0, 2, 1, 2, 2, 2, 3, 2, 0,
+ 3, 1, 3, 2, 3, 3, 3, 4, 3, 0, 4, 1, 4, 2, 4, 3, 4, 4, 4
+ };
+
+ QBrush fillBrush( color1, SolidPattern );
+ p->setPen( color1 );
+ if ( round && w > 19 && h > 19 )
+ {
+ int x2 = x + w - 1;
+ int y2 = y + h - 1;
+ QPointArray a( QCOORDARRLEN( top_left_fill ), top_left_fill );
+ a.translate( 1, 1 );
+ p->drawPoints( a );
+ a.setPoints( QCOORDARRLEN( btm_left_fill ), btm_left_fill );
+ a.translate( 1, h - 6 );
+ p->drawPoints( a );
+ a.setPoints( QCOORDARRLEN( top_right_fill ), top_right_fill );
+ a.translate( w - 6, 1 );
+ p->drawPoints( a );
+ a.setPoints( QCOORDARRLEN( btm_right_fill ), btm_right_fill );
+ a.translate( w - 6, h - 6 );
+ p->drawPoints( a );
+
+ p->fillRect( x + 6, y, w - 12, h, fillBrush );
+ p->fillRect( x, y + 6, x + 6, h - 12, fillBrush );
+ p->fillRect( x2 - 6, y + 6, x2, h - 12, fillBrush );
+ p->drawLine( x + 6, y, x2 - 6, y );
+ p->drawLine( x + 6, y2, x2 - 6, y2 );
+ p->drawLine( x, y + 6, x, y2 - 6 );
+ p->drawLine( x2, y + 6, x2, y2 - 6 );
+
+ }
+ else
+ p->fillRect( x, y, w, h, fillBrush );
+}
+
+int KThemeStyle::styleHint( StyleHint sh, const QWidget *w, const QStyleOption &opt, QStyleHintReturn *shr ) const
+{
+ switch ( sh )
+ {
+ case SH_EtchDisabledText:
+ case SH_Slider_SnapToValue:
+ case SH_PrintDialog_RightAlignButtons:
+ case SH_FontDialog_SelectAssociatedText:
+ case SH_PopupMenu_AllowActiveAndDisabled:
+ case SH_MenuBar_AltKeyNavigation:
+ case SH_MenuBar_MouseTracking:
+ case SH_PopupMenu_MouseTracking:
+ case SH_ComboBox_ListMouseTracking:
+ return 1;
+
+ case SH_GUIStyle:
+ return WindowsStyle;
+
+ case SH_ScrollBar_BackgroundMode:
+ return NoBackground;
+
+ default:
+ return KThemeBase::styleHint( sh, w, opt, shr );
+ };
+}
+
+
+
+/* This is where we draw the borders and highlights. The new round button
+ * code is a pain in the arse. We don't want to be calculating arcs so
+ * use a whole lotta QPointArray's ;-) The code is made a lot more complex
+ * because you can have variable width border and highlights...
+ * I may want to cache this if round buttons are used, but am concerned
+ * about excessive cache misses. This is a memory/speed tradeoff that I
+ * have to test.
+ */
+void KThemeStyle::drawShade( QPainter *p, int x, int y, int w, int h,
+ const QColorGroup &g, bool sunken, bool rounded,
+ int hWidth, int bWidth, ShadeStyle style ) const
+{
+ int i, sc, bc, x2, y2;
+ QPen highPen, lowPen;
+
+ if ( style == Motif )
+ {
+ highPen.setColor( sunken ? g.dark() : g.light() );
+ lowPen.setColor( sunken ? g.light() : g.dark() );
+ }
+ else
+ {
+ highPen.setColor( sunken ? g.shadow() : g.light() );
+ lowPen.setColor( sunken ? g.light() : g.shadow() );
+ }
+
+ // Advanced round buttons
+ if ( rounded && w > 19 && h > 19 )
+ {
+ x2 = x + w - 1, y2 = y + h - 1;
+ QPointArray bPntArray, hPntArray, lPntArray;
+ QPointArray bLineArray, hLineArray, lLineArray;
+ // borders
+ for ( i = 0, bc = 0; i < bWidth; ++i )
+ {
+ bPntArray.putPoints( bc, 24, x + 4, y + 1, x + 5, y + 1, x + 3, y + 2, x + 2, y + 3,
+ x + 1, y + 4, x + 1, y + 5, x + 1, y2 - 5, x + 1, y2 - 4, x + 2, y2 - 3,
+ x2 - 5, y + 1, x2 - 4, y + 1, x2 - 3, y + 2, x2 - 5, y2 - 1,
+ x2 - 4, y2 - 1, x2 - 3, y2 - 2, x2 - 2, y2 - 3, x2 - 1, y2 - 5,
+ x2 - 1, y2 - 4, x + 3, y2 - 2, x + 4, y2 - 1, x + 5, y2 - 1,
+ x2 - 2, y + 3, x2 - 1, y + 4, x2 - 1, y + 5 );
+ bc += 24;
+ // ellispe edges don't match exactly, so fill in blanks
+ if ( i < bWidth - 1 || hWidth != 0 )
+ {
+ bPntArray.putPoints( bc, 20, x + 6, y + 1, x + 4, y + 2, x + 3, y + 3,
+ x + 2, y + 4, x + 1, y + 6, x2 - 6, y + 1, x2 - 4, y + 2,
+ x2 - 3, y + 3, x + 2, y2 - 4, x + 1, y2 - 6, x2 - 6, y2 - 1,
+ x2 - 4, y2 - 2, x2 - 3, y2 - 3, x2 - 2, y2 - 4, x2 - 1, y2 - 6,
+ x + 6, y2 - 1, x + 4, y2 - 2, x + 3, y2 - 3, x2 - 1, y + 6,
+ x2 - 2, y + 4 );
+ bc += 20;
+ }
+ bLineArray.putPoints( i * 8, 8, x + 6, y, x2 - 6, y, x, y + 6, x, y2 - 6,
+ x + 6, y2, x2 - 6, y2, x2, y + 6, x2, y2 - 6 );
+ ++x, ++y;
+ --x2, --y2;
+ }
+ // highlights
+ for ( i = 0, sc = 0; i < hWidth; ++i )
+ {
+ hPntArray.putPoints( sc, 12, x + 4, y + 1, x + 5, y + 1, // top left
+ x + 3, y + 2, x + 2, y + 3, x + 1, y + 4, x + 1, y + 5,
+ x + 1, y2 - 5, x + 1, y2 - 4, x + 2, y2 - 3, // half corners
+ x2 - 5, y + 1, x2 - 4, y + 1, x2 - 3, y + 2 );
+ lPntArray.putPoints( sc, 12, x2 - 5, y2 - 1, x2 - 4, y2 - 1, // btm right
+ x2 - 3, y2 - 2, x2 - 2, y2 - 3, x2 - 1, y2 - 5, x2 - 1, y2 - 4,
+ x + 3, y2 - 2, x + 4, y2 - 1, x + 5, y2 - 1, //half corners
+ x2 - 2, y + 3, x2 - 1, y + 4, x2 - 1, y + 5 );
+ sc += 12;
+ if ( i < hWidth - 1 )
+ {
+ hPntArray.putPoints( sc, 10, x + 6, y + 1, x + 4, y + 2, // top left
+ x + 3, y + 3, x + 2, y + 4, x + 1, y + 6,
+ x2 - 6, y + 1, x2 - 4, y + 2, // half corners
+ x2 - 3, y + 3, x + 2, y2 - 4, x + 1, y2 - 6 );
+ lPntArray.putPoints( sc, 10, x2 - 6, y2 - 1, x2 - 4, y2 - 2, // btm right
+ x2 - 3, y2 - 3, x2 - 2, y2 - 4, x2 - 1, y2 - 6,
+ x + 6, y2 - 1, x + 4, y2 - 2, // half corners
+ x + 3, y2 - 3, x2 - 1, y + 6, x2 - 2, y + 4 );
+ sc += 10;
+ }
+ hLineArray.putPoints( i * 4, 4, x + 6, y, x2 - 6, y, x, y + 6, x, y2 - 6 );
+ lLineArray.putPoints( i * 4, 4, x + 6, y2, x2 - 6, y2, x2, y + 6, x2, y2 - 6 );
+ ++x, ++y;
+ --x2, --y2;
+ }
+ p->setPen( Qt::black );
+ p->drawPoints( bPntArray );
+ p->drawLineSegments( bLineArray );
+ p->setPen( highPen );
+ p->drawPoints( hPntArray );
+ p->drawLineSegments( hLineArray );
+ p->setPen( lowPen );
+ p->drawPoints( lPntArray );
+ p->drawLineSegments( lLineArray );
+ }
+ // Rectangular buttons
+ else
+ {
+ QPointArray highShade( hWidth * 4 );
+ QPointArray lowShade( hWidth * 4 );
+
+ p->setPen( g.shadow() );
+ for ( i = 0; i < bWidth && w > 2 && h > 2; ++i, ++x, ++y, w -= 2, h -= 2 )
+ p->drawRect( x, y , w, h );
+
+ if ( !hWidth )
+ return ;
+
+ x2 = x + w - 1, y2 = y + h - 1;
+ for ( i = 0; i < hWidth; ++i, ++x, ++y, --x2, --y2 )
+ {
+ highShade.putPoints( i * 4, 4, x, y, x2, y, x, y, x, y2 );
+ lowShade.putPoints( i * 4, 4, x, y2, x2, y2, x2, y, x2, y2 );
+ }
+ if ( style == Windows && hWidth > 1 )
+ {
+ p->setPen( highPen );
+ p->drawLineSegments( highShade, 0, 2 );
+ p->setPen( lowPen );
+ p->drawLineSegments( lowShade, 0, 2 );
+
+ p->setPen( ( sunken ) ? g.dark() : g.mid() );
+ p->drawLineSegments( highShade, 4 );
+ p->setPen( ( sunken ) ? g.mid() : g.dark() );
+ p->drawLineSegments( lowShade, 4 );
+ }
+ else
+ {
+ p->setPen( ( sunken ) ? g.dark() : g.light() );
+ p->drawLineSegments( highShade );
+ p->setPen( ( sunken ) ? g.light() : g.dark() );
+ p->drawLineSegments( lowShade );
+ }
+ }
+}
+
+
+
+
+int KThemeStyle::popupMenuItemHeight( bool /*checkable*/, QMenuItem *mi,
+ const QFontMetrics &fm )
+{
+ int h2, h = 0;
+ int offset = QMAX( decoWidth( MenuItemDown ), decoWidth( MenuItem ) ) + 4;
+
+ if ( mi->isSeparator() )
+ return ( 2 );
+ if ( mi->isChecked() )
+ h = isPixmap( CheckMark ) ? uncached( CheckMark ) ->height() + offset :
+ offset + 16;
+ if ( mi->pixmap() )
+ {
+ h2 = mi->pixmap() ->height() + offset;
+ h = h2 > h ? h2 : h;
+ }
+ if ( mi->iconSet() )
+ {
+ h2 = mi->iconSet() ->
+ pixmap( QIconSet::Small, QIconSet::Normal ).height() + offset;
+ h = h2 > h ? h2 : h;
+ }
+ h2 = fm.height() + offset;
+ h = h2 > h ? h2 : h;
+ return ( h );
+}
+
+#include "kthemestyle.moc"
+// kate: indent-width 4; replace-tabs off; tab-width 4; space-indent on;
diff --git a/kstyles/kthemestyle/kthemestyle.h b/kstyles/kthemestyle/kthemestyle.h
new file mode 100644
index 000000000..9b7d54b60
--- /dev/null
+++ b/kstyles/kthemestyle/kthemestyle.h
@@ -0,0 +1,230 @@
+/*
+$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
+
+Includes code portions from the dotNET style, and the KDE HighColor style.
+
+dotNET Style
+ Copyright (C) 2001, Chris Lee <lee@azsites.com>
+ Carsten Pfeiffer <pfeiffer@kde.org>
+
+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.
+*/
+#ifndef KTHEMESTYLE_H
+#define KTHEMESTYLE_H
+
+#include <qglobal.h>
+
+#include "kthemebase.h"
+#include <qwindowdefs.h>
+#include <qobject.h>
+#include <qbutton.h>
+#include <qpushbutton.h>
+#include <qscrollbar.h>
+#include <qtabbar.h>
+#include <qstring.h>
+#include <qintdict.h>
+#include <qmap.h>
+
+
+/**
+ * KDE themed styles.
+ *
+ * It provides methods for
+ * drawing most widgets with user-specified borders, highlights, pixmaps,
+ * etc. It also handles various other settings such as scrollbar types,
+ * rounded buttons, and shading types. For a full list of parameters this
+ * class handles refer to the KDE theme configuration documentation.
+ *
+ */
+
+class KThemeStyle: public KThemeBase
+{
+ Q_OBJECT
+public:
+ /**
+ * Constructs a new KThemeStyle object.
+ *
+ * @param configDir The directory which has the KConfig file.
+ * @param configFile A KConfig file to use as the theme configuration.
+ * Defaults to ~/.kderc.
+ */
+ KThemeStyle( const QString& configDir, const QString &configFile = QString::null );
+ ~KThemeStyle();
+
+ virtual int pixelMetric ( PixelMetric metric, const QWidget * widget = 0 ) const;
+
+ virtual void drawPrimitive ( PrimitiveElement pe, QPainter * p, const QRect & r, const QColorGroup & cg,
+ SFlags flags = Style_Default,
+ const QStyleOption& = QStyleOption::Default ) const;
+
+ virtual void drawControl( ControlElement element,
+ QPainter *p,
+ const QWidget *widget,
+ const QRect &r,
+ const QColorGroup &cg,
+ SFlags how = Style_Default,
+ const QStyleOption& = QStyleOption::Default ) const;
+
+ virtual void drawControlMask( ControlElement element,
+ QPainter *p,
+ const QWidget *widget,
+ const QRect &r,
+ const QStyleOption& = QStyleOption::Default ) const;
+
+
+ virtual void drawComplexControl( ComplexControl control,
+ QPainter *p,
+ const QWidget* widget,
+ const QRect &r,
+ const QColorGroup &cg,
+ SFlags flags = Style_Default,
+ SCFlags controls = SC_All,
+ SCFlags active = SC_None,
+ const QStyleOption& = QStyleOption::Default ) const;
+
+ virtual void drawKStylePrimitive( KStylePrimitive kpe,
+ QPainter* p,
+ const QWidget* widget,
+ const QRect &r,
+ const QColorGroup &cg,
+ SFlags flags = Style_Default,
+ const QStyleOption& = QStyleOption::Default ) const;
+
+
+ virtual int styleHint( StyleHint sh,
+ const QWidget *widget = 0,
+ const QStyleOption& = QStyleOption::Default,
+ QStyleHintReturn* returnData = 0 ) const;
+
+ virtual QSize sizeFromContents( ContentsType contents,
+ const QWidget *widget,
+ const QSize &contentsSize,
+ const QStyleOption& = QStyleOption::Default ) const;
+
+ virtual QRect subRect(SubRect, const QWidget *) const;
+
+ virtual void polish( QWidget* );
+ virtual void unPolish( QWidget* );
+ virtual bool eventFilter( QObject* object, QEvent* event );
+ /**
+ * By default this just sets the background brushes to the pixmapped
+ * background.
+ */
+ virtual void polish( QApplication *app );
+ virtual void unPolish( QApplication* );
+
+ /** \internal */
+ // to make it possible for derived classes to overload this function
+ virtual void polish( QPalette& pal );
+
+ /**
+ * This is a convenience method for drawing widgets with
+ * borders, highlights, pixmaps, colors, etc...
+ * You specify the widget type and it will draw it according to the
+ * config file settings.
+ *
+ * @param x The x coordinate of the button's upper left hand corner.
+ * @param y The y coordinate of the buttons' upper left hand corner.
+ * @param w The button width.
+ * @param h The button height.
+ * @param p The QPainter to draw on.
+ * @param g The color group to use.
+ * @param sunken The button is drawn with a sunken style if @p true
+ * @param rounded @p true if the widget is rounded, @p false if rectangular.
+ * @param type The widget type to paint.
+ */
+ virtual void drawBaseButton( QPainter *p, int x, int y, int w, int h,
+ const QColorGroup &g, bool sunken = false,
+ bool rounded = false, WidgetType type = Bevel ) const;
+ /**
+ * Draw a mask with for widgets that may be rounded.
+ *
+ *Currently used
+ * by pushbuttons and comboboxes.
+ *
+ * @param p The QPainter to draw on.
+ * @param x The x coordinate of the widget's upper left hand corner.
+ * @param y The y coordinate of the widget's upper left hand corner.
+ * @param w The widget width.
+ * @param h The widget height.
+ * @param rounded @p true if the widget is rounded, @p false if rectangular.
+ */
+ virtual void drawBaseMask( QPainter *p, int x, int y, int w, int h,
+ bool rounded ) const;
+
+
+
+ /**
+ * Draw a shaded rectangle using the given style.
+ *
+ * @param p The painter to draw on.
+ * @param g The color group to use.
+ * @param x The x coordinate of the rectangle's upper left hand corner.
+ * @param y The y coordinate of the rectangle's upper left hand corner.
+ * @param w The rectangle width.
+ * @param h The rectangle height.
+ * @param sunken Draws a sunken style if @p true.
+ * @param rounded Draws a rounded shape if @p true. Requires bWidth to be
+ * at least 1.
+ * @param hWidth The highlight width.
+ * @param bWidth The border width.
+ * @param style The shading style to use.
+ */
+ virtual void drawShade( QPainter *p, int x, int y, int w, int h,
+ const QColorGroup &g, bool sunken, bool rounded,
+ int hWidth, int bWidth, ShadeStyle style ) const;
+ int popupMenuItemHeight( bool checkable, QMenuItem *mi,
+ const QFontMetrics &fm );
+
+protected:
+ QPalette oldPalette, popupPalette, indiPalette, exIndiPalette;
+ bool paletteSaved;
+ bool polishLock;
+ QStyle *mtfstyle;
+
+ QPixmap* makeMenuBarCache(int w, int h) const;
+
+ mutable QPixmap* menuCache;
+ mutable QPixmap* vsliderCache;
+
+ Qt::HANDLE brushHandle;
+ bool brushHandleSet;
+ bool kickerMode;
+
+protected slots:
+ void paletteChanged();
+
+
+
+};
+
+
+#endif