From bd0f3345a938b35ce6a12f6150373b0955b8dd12 Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Sun, 10 Jul 2011 15:24:15 -0500 Subject: Add Qt3 development HEAD version --- src/styles/qcdestyle.cpp | 367 ++++++ src/styles/qcdestyle.h | 86 ++ src/styles/qcommonstyle.cpp | 2726 ++++++++++++++++++++++++++++++++++++++++ src/styles/qcommonstyle.h | 137 ++ src/styles/qcompactstyle.cpp | 321 +++++ src/styles/qcompactstyle.h | 75 ++ src/styles/qinterlacestyle.cpp | 805 ++++++++++++ src/styles/qinterlacestyle.h | 107 ++ src/styles/qmotifplusstyle.cpp | 1584 +++++++++++++++++++++++ src/styles/qmotifplusstyle.h | 124 ++ src/styles/qmotifstyle.cpp | 2359 ++++++++++++++++++++++++++++++++++ src/styles/qmotifstyle.h | 136 ++ src/styles/qplatinumstyle.cpp | 1557 +++++++++++++++++++++++ src/styles/qplatinumstyle.h | 117 ++ src/styles/qsgistyle.cpp | 1468 ++++++++++++++++++++++ src/styles/qsgistyle.h | 133 ++ src/styles/qstylefactory.cpp | 268 ++++ src/styles/qstylefactory.h | 62 + src/styles/qstyleinterface_p.h | 76 ++ src/styles/qstyleplugin.cpp | 185 +++ src/styles/qstyleplugin.h | 72 ++ src/styles/qt_styles.pri | 140 +++ src/styles/qwindowsstyle.cpp | 2161 +++++++++++++++++++++++++++++++ src/styles/qwindowsstyle.h | 135 ++ 24 files changed, 15201 insertions(+) create mode 100644 src/styles/qcdestyle.cpp create mode 100644 src/styles/qcdestyle.h create mode 100644 src/styles/qcommonstyle.cpp create mode 100644 src/styles/qcommonstyle.h create mode 100644 src/styles/qcompactstyle.cpp create mode 100644 src/styles/qcompactstyle.h create mode 100644 src/styles/qinterlacestyle.cpp create mode 100644 src/styles/qinterlacestyle.h create mode 100644 src/styles/qmotifplusstyle.cpp create mode 100644 src/styles/qmotifplusstyle.h create mode 100644 src/styles/qmotifstyle.cpp create mode 100644 src/styles/qmotifstyle.h create mode 100644 src/styles/qplatinumstyle.cpp create mode 100644 src/styles/qplatinumstyle.h create mode 100644 src/styles/qsgistyle.cpp create mode 100644 src/styles/qsgistyle.h create mode 100644 src/styles/qstylefactory.cpp create mode 100644 src/styles/qstylefactory.h create mode 100644 src/styles/qstyleinterface_p.h create mode 100644 src/styles/qstyleplugin.cpp create mode 100644 src/styles/qstyleplugin.h create mode 100644 src/styles/qt_styles.pri create mode 100644 src/styles/qwindowsstyle.cpp create mode 100644 src/styles/qwindowsstyle.h (limited to 'src/styles') diff --git a/src/styles/qcdestyle.cpp b/src/styles/qcdestyle.cpp new file mode 100644 index 0000000..d6621c0 --- /dev/null +++ b/src/styles/qcdestyle.cpp @@ -0,0 +1,367 @@ +/**************************************************************************** +** +** Implementation of CDE-like style class +** +** Created : 981231 +** +** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the widgets module of the Qt GUI Toolkit. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** This file may be used under the terms of the Q Public License as +** defined by Trolltech ASA and appearing in the file LICENSE.QPL +** included in the packaging of this file. Licensees holding valid Qt +** Commercial licenses may use this file in accordance with the Qt +** Commercial License Agreement provided with the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "qcdestyle.h" + +#if !defined(QT_NO_STYLE_CDE) || defined(QT_PLUGIN) + +#include "qpainter.h" +#include "qdrawutil.h" +#include "qbutton.h" +#include + +/*! + \class QCDEStyle qcdestyle.h + \brief The QCDEStyle class provides a CDE look and feel. + + \ingroup appearance + + This style provides a slightly improved Motif look similar to some + versions of the Common Desktop Environment (CDE). The main + differences are thinner frames and more modern radio buttons and + checkboxes. Together with a dark background and a bright + text/foreground color, the style looks quite attractive (at least + for Motif fans). + + Note that the functions provided by QCDEStyle are + reimplementations of QStyle functions; see QStyle for their + documentation. +*/ + +/*! + Constructs a QCDEStyle. + + If \a useHighlightCols is FALSE (the default), then the style will + polish the application's color palette to emulate the Motif way of + highlighting, which is a simple inversion between the base and the + text color. +*/ +QCDEStyle::QCDEStyle( bool useHighlightCols ) : QMotifStyle( useHighlightCols ) +{ +} + +/*! + Destroys the style. +*/ +QCDEStyle::~QCDEStyle() +{ +} + + +/*!\reimp +*/ +int QCDEStyle::pixelMetric( PixelMetric metric, const QWidget *widget ) const +{ + int ret; + + switch( metric ) { + case PM_DefaultFrameWidth: + ret = 1; + break ; + case PM_MenuBarFrameWidth: + ret = 1; + break; + case PM_ScrollBarExtent: + ret = 13; + break; + default: + ret = QMotifStyle::pixelMetric( metric, widget ); + break; + } + return ret; +} + +/*! \reimp +*/ +void QCDEStyle::drawControl( ControlElement element, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QColorGroup &cg, + SFlags how, + const QStyleOption& opt ) const +{ + + switch( element ) { + case CE_MenuBarItem: + { + if ( how & Style_Active ) // active item + qDrawShadePanel( p, r, cg, TRUE, 1, + &cg.brush( QColorGroup::Button ) ); + else // other item + p->fillRect( r, cg.brush( QColorGroup::Button ) ); + QCommonStyle::drawControl( element, p, widget, r, cg, how, opt ); + break; + } + default: + QMotifStyle::drawControl( element, p, widget, r, cg, how, opt ); + break; + } + + +} + +/*! \reimp +*/ +void QCDEStyle::drawPrimitive( PrimitiveElement pe, + QPainter *p, + const QRect &r, + const QColorGroup &cg, + SFlags flags, + const QStyleOption& opt ) const +{ + switch( pe ) { + case PE_Indicator: { +#ifndef QT_NO_BUTTON + bool down = flags & Style_Down; + bool on = flags & Style_On; + bool showUp = !( down ^ on ); + QBrush fill = showUp || flags & Style_NoChange ? cg.brush( QColorGroup::Button ) : cg.brush( QColorGroup::Mid ); + qDrawShadePanel( p, r, cg, !showUp, pixelMetric( PM_DefaultFrameWidth ), &cg.brush( QColorGroup::Button ) ); + + if ( !( flags & Style_Off ) ) { + QPointArray a( 7 * 2 ); + int i, xx, yy; + xx = r.x() + 3; + yy = r.y() + 5; + for ( i = 0; i < 3; i++ ) { + a.setPoint( 2 * i, xx, yy ); + a.setPoint( 2 * i + 1, xx, yy + 2 ); + xx++; yy++; + } + yy -= 2; + for ( i = 3; i < 7; i++ ) { + a.setPoint( 2 * i, xx, yy ); + a.setPoint( 2 * i + 1, xx, yy + 2 ); + xx++; yy--; + } + if ( flags & Style_NoChange ) + p->setPen( cg.dark() ); + else + p->setPen( cg.foreground() ); + p->drawLineSegments( a ); + } +#endif + } + break; + case PE_ExclusiveIndicator: + { +#define QCOORDARRLEN(x) sizeof(x)/(sizeof(QCOORD)*2) + static const QCOORD pts1[] = { // up left lines + 1,9, 1,8, 0,7, 0,4, 1,3, 1,2, 2,1, 3,1, 4,0, 7,0, 8,1, 9,1 }; + static const QCOORD pts4[] = { // bottom right lines + 2,10, 3,10, 4,11, 7,11, 8,10, 9,10, 10,9, 10,8, 11,7, + 11,4, 10,3, 10,2 }; + static const QCOORD pts5[] = { // inner fill + 4,2, 7,2, 9,4, 9,7, 7,9, 4,9, 2,7, 2,4 }; + bool down = flags & Style_Down; + bool on = flags & Style_On; + p->eraseRect( r ); + QPointArray a( QCOORDARRLEN(pts1), pts1 ); + a.translate( r.x(), r.y() ); + p->setPen( ( down || on ) ? cg.dark() : cg.light() ); + p->drawPolyline( a ); + a.setPoints( QCOORDARRLEN(pts4), pts4 ); + a.translate( r.x(), r.y() ); + p->setPen( ( down || on ) ? cg.light() : cg.dark() ); + p->drawPolyline( a ); + a.setPoints( QCOORDARRLEN(pts5), pts5 ); + a.translate( r.x(), r.y() ); + QColor fillColor = on ? cg.dark() : cg.background(); + p->setPen( fillColor ); + p->setBrush( on ? cg.brush( QColorGroup::Dark ) : + cg.brush( QColorGroup::Background ) ); + p->drawPolygon( a ); + break; + } + + case PE_ExclusiveIndicatorMask: + { + static const QCOORD pts1[] = { + // up left lines + 1,9, 1,8, 0,7, 0,4, 1,3, 1,2, 2,1, 3,1, 4,0, 7,0, 8,1, 9,1, + // bottom right lines + 10,2, 10,3, 11,4, 11,7, 10,8, 10,9, 9,10, 8,10, 7,11, 4,11, 3,10, 2,10 + }; + QPointArray a(QCOORDARRLEN(pts1), pts1); + a.translate(r.x(), r.y()); + p->setPen(color1); + p->setBrush(color1); + p->drawPolygon(a); + break; + } + case PE_ArrowUp: + case PE_ArrowDown: + case PE_ArrowRight: + case PE_ArrowLeft: { + QRect rect = r; + QPointArray bFill; // fill polygon + QPointArray bTop; // top shadow. + QPointArray bBot; // bottom shadow. + QPointArray bLeft; // left shadow. + QWMatrix matrix; // xform matrix + bool vertical = pe == PE_ArrowUp || pe == PE_ArrowDown; + bool horizontal = !vertical; + int dim = rect.width() < rect.height() ? rect.width() : rect.height(); + int colspec = 0x0000; // color specification array + + if ( dim < 2 ) // too small arrow + return; + + // adjust size and center (to fix rotation below) + if ( rect.width() > dim ) { + rect.setX( rect.x() + ( ( rect.width() - dim ) / 2 ) ); + rect.setWidth( dim ); + } + if ( rect.height() > dim ) { + rect.setY( rect.y() + ( ( rect.height() - dim ) / 2 ) ); + rect.setHeight( dim ); + } + + if ( dim > 3 ) { + bFill.resize( dim & 1 ? 3 : 4 ); + bTop.resize( 2 ); + bBot.resize( 2 ); + bLeft.resize( 2 ); + bLeft.putPoints( 0, 2, 0, 0, 0, dim-1 ); + bTop.putPoints( 0, 2, 1, 0, dim-1, dim/2 ); + bBot.putPoints( 0, 2, 1, dim-1, dim-1, dim/2 ); + + if ( dim > 6 ) { // dim>6: must fill interior + bFill.putPoints( 0, 2, 1, dim-1, 1, 1 ); + if ( dim & 1 ) // if size is an odd number + bFill.setPoint( 2, dim - 2, dim / 2 ); + else + bFill.putPoints( 2, 2, dim-2, dim/2-1, dim-2, dim/2 ); + } + } else { + if ( dim == 3 ) { // 3x3 arrow pattern + bLeft.setPoints( 4, 0,0, 0,2, 1,1, 1,1 ); + bTop .setPoints( 2, 1,0, 1,0 ); + bBot .setPoints( 2, 1,2, 2,1 ); + } else { // 2x2 arrow pattern + bLeft.setPoints( 2, 0,0, 0,1 ); + bTop .setPoints( 2, 1,0, 1,0 ); + bBot .setPoints( 2, 1,1, 1,1 ); + } + } + + if ( pe == PE_ArrowUp || pe == PE_ArrowLeft ) { + matrix.translate( rect.x(), rect.y() ); + if ( vertical ) { + matrix.translate( 0, rect.height() - 1 ); + matrix.rotate( -90 ); + } else { + matrix.translate( rect.width() - 1, rect.height() - 1 ); + matrix.rotate( 180 ); + } + if ( flags & Style_Down ) + colspec = horizontal ? 0x2334 : 0x2343; + else + colspec = horizontal ? 0x1443 : 0x1434; + } else if ( pe == PE_ArrowDown || pe == PE_ArrowRight ) { + matrix.translate( rect.x(), rect.y() ); + if ( vertical ) { + matrix.translate( rect.width()-1, 0 ); + matrix.rotate( 90 ); + } + if ( flags & Style_Down ) + colspec = horizontal ? 0x2443 : 0x2434; + else + colspec = horizontal ? 0x1334 : 0x1343; + } + + QColor *cols[5]; + if ( flags & Style_Enabled ) { + cols[0] = 0; + cols[1] = (QColor *)&cg.button(); + cols[2] = (QColor *)&cg.mid(); + cols[3] = (QColor *)&cg.light(); + cols[4] = (QColor *)&cg.dark(); + } else { + cols[0] = 0; + cols[1] = (QColor *)&cg.button(); + cols[2] = (QColor *)&cg.button(); + cols[3] = (QColor *)&cg.button(); + cols[4] = (QColor *)&cg.button(); + } + +#define CMID *cols[ (colspec>>12) & 0xf ] +#define CLEFT *cols[ (colspec>>8) & 0xf ] +#define CTOP *cols[ (colspec>>4) & 0xf ] +#define CBOT *cols[ colspec & 0xf ] + + QPen savePen = p->pen(); // save current pen + QBrush saveBrush = p->brush(); // save current brush + QWMatrix wxm = p->worldMatrix(); + QPen pen( NoPen ); + QBrush brush = cg.brush( flags & Style_Enabled ? QColorGroup::Button : + QColorGroup::Mid ); + + p->setPen( pen ); + p->setBrush( brush ); + p->setWorldMatrix( matrix, TRUE ); // set transformation matrix + p->drawPolygon( bFill ); // fill arrow + p->setBrush( NoBrush ); // don't fill + + p->setPen( CLEFT ); + p->drawLineSegments( bLeft ); + p->setPen( CBOT ); + p->drawLineSegments( bBot ); + p->setPen( CTOP ); + p->drawLineSegments( bTop ); + + p->setWorldMatrix( wxm ); + p->setBrush( saveBrush ); // restore brush + p->setPen( savePen ); // restore pen + +#undef CMID +#undef CLEFT +#undef CTOP +#undef CBOT + + } + break; + default: + QMotifStyle::drawPrimitive( pe, p, r, cg, flags, opt ); + } +} + +#endif diff --git a/src/styles/qcdestyle.h b/src/styles/qcdestyle.h new file mode 100644 index 0000000..a94f620 --- /dev/null +++ b/src/styles/qcdestyle.h @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Definition of the CDE-like style class +** +** Created : 990513 +** +** Copyright (C) 1999-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the widgets module of the Qt GUI Toolkit. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** This file may be used under the terms of the Q Public License as +** defined by Trolltech ASA and appearing in the file LICENSE.QPL +** included in the packaging of this file. Licensees holding valid Qt +** Commercial licenses may use this file in accordance with the Qt +** Commercial License Agreement provided with the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + + +#ifndef QCDESTYLE_H +#define QCDESTYLE_H + +#ifndef QT_H +#include "qmotifstyle.h" +#endif // QT_H + +#if !defined(QT_NO_STYLE_CDE) || defined(QT_PLUGIN) + +#if defined(QT_PLUGIN) +#define Q_EXPORT_STYLE_CDE +#else +#define Q_EXPORT_STYLE_CDE Q_EXPORT +#endif + +class Q_EXPORT_STYLE_CDE QCDEStyle : public QMotifStyle +{ + Q_OBJECT +public: + + QCDEStyle( bool useHighlightCols = FALSE ); + virtual ~QCDEStyle(); + + int pixelMetric( PixelMetric metric, const QWidget *widget = 0 ) const; + + void drawControl( ControlElement element, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QColorGroup &cg, + SFlags how = Style_Default, + const QStyleOption& = QStyleOption::Default ) const; + + void drawPrimitive( PrimitiveElement pe, + QPainter *p, + const QRect &r, + const QColorGroup &cg, + SFlags flags = Style_Default, + const QStyleOption& = QStyleOption::Default ) const; + +}; + +#endif // QT_NO_STYLE_CDE + +#endif // QCDESTYLE_H diff --git a/src/styles/qcommonstyle.cpp b/src/styles/qcommonstyle.cpp new file mode 100644 index 0000000..0f9dddb --- /dev/null +++ b/src/styles/qcommonstyle.cpp @@ -0,0 +1,2726 @@ +/**************************************************************************** +** +** Implementation of the QCommonStyle class +** +** Created : 981231 +** +** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the widgets module of the Qt GUI Toolkit. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** This file may be used under the terms of the Q Public License as +** defined by Trolltech ASA and appearing in the file LICENSE.QPL +** included in the packaging of this file. Licensees holding valid Qt +** Commercial licenses may use this file in accordance with the Qt +** Commercial License Agreement provided with the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "qcommonstyle.h" + +#ifndef QT_NO_STYLE + +#include "qmenubar.h" +#include "qapplication.h" +#include "qpainter.h" +#include "qdrawutil.h" +#include "qpixmap.h" +#include "qpushbutton.h" +#include "qtabbar.h" +#include "qscrollbar.h" +#include "qtoolbutton.h" +#include "qtoolbar.h" +#include "qdockarea.h" +#include "qheader.h" +#include "qspinbox.h" +#include "qrangecontrol.h" +#include "qgroupbox.h" +#include "qslider.h" +#include "qlistview.h" +#include "qcheckbox.h" +#include "qradiobutton.h" +#include "qbitmap.h" +#include "qprogressbar.h" +#include "private/qdialogbuttons_p.h" +#include +#include +#include "../widgets/qtitlebar_p.h" +#include + +/*! + \class QCommonStyle qcommonstyle.h + \brief The QCommonStyle class encapsulates the common Look and Feel of a GUI. + + \ingroup appearance + + This abstract class implements some of the widget's look and feel + that is common to all GUI styles provided and shipped as part of + Qt. + + All the functions are documented in \l QStyle. +*/ + +/*! + \enum Qt::ArrowType + + \value UpArrow + \value DownArrow + \value LeftArrow + \value RightArrow + +*/ + +// the active painter, if any... this is used as an optimzation to +// avoid creating a painter if we have an active one (since +// QStyle::itemRect() needs a painter to operate correctly +static QPainter *activePainter = 0; + +/*! + Constructs a QCommonStyle. +*/ +QCommonStyle::QCommonStyle() : QStyle() +{ + activePainter = 0; +} + +/*! \reimp */ +QCommonStyle::~QCommonStyle() +{ + activePainter = 0; +} + + +static const char * const check_list_controller_xpm[] = { +"16 16 4 1", +" c None", +". c #000000000000", +"X c #FFFFFFFF0000", +"o c #C71BC30BC71B", +" ", +" ", +" .......... ", +" .XXXXXXXX. ", +" .XXXXXXXX.oo ", +" .XXXXXXXX.oo ", +" .XXXXXXXX.oo ", +" .XXXXXXXX.oo ", +" .XXXXXXXX.oo ", +" .XXXXXXXX.oo ", +" .XXXXXXXX.oo ", +" ..........oo ", +" oooooooooo ", +" oooooooooo ", +" ", +" "}; + +/*! \reimp */ +void QCommonStyle::drawPrimitive( PrimitiveElement pe, + QPainter *p, + const QRect &r, + const QColorGroup &cg, + SFlags flags, + const QStyleOption& opt ) const +{ + activePainter = p; + + switch (pe) { +#ifndef QT_NO_LISTVIEW + case PE_CheckListController: { + p->drawPixmap(r, QPixmap((const char **)check_list_controller_xpm)); + break; } + case PE_CheckListExclusiveIndicator: { + QCheckListItem *item = opt.checkListItem(); + QListView *lv = item->listView(); + if(!item) + return; + int x = r.x(), y = r.y(); +#define QCOORDARRLEN(x) sizeof(x)/(sizeof(QCOORD)*2) + static const QCOORD pts1[] = { // dark lines + 1,9, 1,8, 0,7, 0,4, 1,3, 1,2, 2,1, 3,1, 4,0, 7,0, 8,1, 9,1 }; + static const QCOORD pts2[] = { // black lines + 2,8, 1,7, 1,4, 2,3, 2,2, 3,2, 4,1, 7,1, 8,2, 9,2 }; + static const QCOORD pts3[] = { // background lines + 2,9, 3,9, 4,10, 7,10, 8,9, 9,9, 9,8, 10,7, 10,4, 9,3 }; + static const QCOORD pts4[] = { // white lines + 2,10, 3,10, 4,11, 7,11, 8,10, 9,10, 10,9, 10,8, 11,7, + 11,4, 10,3, 10,2 }; + // static const QCOORD pts5[] = { // inner fill + // 4,2, 7,2, 9,4, 9,7, 7,9, 4,9, 2,7, 2,4 }; + //QPointArray a; + // p->eraseRect( x, y, w, h ); + + if ( flags & Style_Enabled ) + p->setPen( cg.text() ); + else + p->setPen( QPen( lv->palette().color( QPalette::Disabled, QColorGroup::Text ) ) ); + QPointArray a( QCOORDARRLEN(pts1), pts1 ); + a.translate( x, y ); + //p->setPen( cg.dark() ); + p->drawPolyline( a ); + a.setPoints( QCOORDARRLEN(pts2), pts2 ); + a.translate( x, y ); + p->drawPolyline( a ); + a.setPoints( QCOORDARRLEN(pts3), pts3 ); + a.translate( x, y ); + // p->setPen( black ); + p->drawPolyline( a ); + a.setPoints( QCOORDARRLEN(pts4), pts4 ); + a.translate( x, y ); + // p->setPen( blue ); + p->drawPolyline( a ); + // a.setPoints( QCOORDARRLEN(pts5), pts5 ); + // a.translate( x, y ); + // QColor fillColor = isDown() ? g.background() : g.base(); + // p->setPen( fillColor ); + // p->setBrush( fillColor ); + // p->drawPolygon( a ); + if ( flags & Style_On ) { + p->setPen( NoPen ); + p->setBrush( cg.text() ); + p->drawRect( x+5, y+4, 2, 4 ); + p->drawRect( x+4, y+5, 4, 2 ); + } + break; } + case PE_CheckListIndicator: { + QCheckListItem *item = opt.checkListItem(); + QListView *lv = item->listView(); + if(!item) + return; + int x = r.x(), y = r.y(), w = r.width(), h = r.width(), marg = lv->itemMargin(); + + if ( flags & Style_Enabled ) + p->setPen( QPen( cg.text(), 2 ) ); + else + p->setPen( QPen( lv->palette().color( QPalette::Disabled, QColorGroup::Text ), + 2 ) ); + bool parentControl = FALSE; + if ( item->parent() && item->parent()->rtti() == 1 && + ((QCheckListItem*) item->parent())->type() == QCheckListItem::Controller ) + parentControl = TRUE; + if ( flags & Style_Selected && !lv->rootIsDecorated() && !parentControl ) { + p->fillRect( 0, 0, x + marg + w + 4, item->height(), + cg.brush( QColorGroup::Highlight ) ); + if ( item->isEnabled() ) + p->setPen( QPen( cg.highlightedText(), 2 ) ); + } + + if ( flags & Style_NoChange ) + p->setBrush( cg.brush( QColorGroup::Button ) ); + p->drawRect( x+marg, y+2, w-4, h-4 ); + ///////////////////// + x++; + y++; + if ( ( flags & Style_On) || ( flags & Style_NoChange ) ) { + QPointArray a( 7*2 ); + int i, xx = x+1+marg, yy=y+5; + for ( i=0; i<3; i++ ) { + a.setPoint( 2*i, xx, yy ); + a.setPoint( 2*i+1, xx, yy+2 ); + xx++; yy++; + } + yy -= 2; + for ( i=3; i<7; i++ ) { + a.setPoint( 2*i, xx, yy ); + a.setPoint( 2*i+1, xx, yy+2 ); + xx++; yy--; + } + p->drawLineSegments( a ); + } + break; } +#endif + case PE_HeaderArrow: + p->save(); + if ( flags & Style_Down ) { + QPointArray pa( 3 ); + p->setPen( cg.light() ); + p->drawLine( r.x() + r.width(), r.y(), r.x() + r.width() / 2, r.height() ); + p->setPen( cg.dark() ); + pa.setPoint( 0, r.x() + r.width() / 2, r.height() ); + pa.setPoint( 1, r.x(), r.y() ); + pa.setPoint( 2, r.x() + r.width(), r.y() ); + p->drawPolyline( pa ); + } else { + QPointArray pa( 3 ); + p->setPen( cg.light() ); + pa.setPoint( 0, r.x(), r.height() ); + pa.setPoint( 1, r.x() + r.width(), r.height() ); + pa.setPoint( 2, r.x() + r.width() / 2, r.y() ); + p->drawPolyline( pa ); + p->setPen( cg.dark() ); + p->drawLine( r.x(), r.height(), r.x() + r.width() / 2, r.y() ); + } + p->restore(); + break; + + case PE_StatusBarSection: + qDrawShadeRect( p, r, cg, TRUE, 1, 0, 0 ); + break; + + case PE_ButtonCommand: + case PE_ButtonBevel: + case PE_ButtonTool: + case PE_ButtonDropDown: + case PE_HeaderSection: + qDrawShadePanel(p, r, cg, flags & (Style_Sunken | Style_Down | Style_On) , 1, + &cg.brush(QColorGroup::Button)); + break; + + case PE_Separator: + qDrawShadeLine( p, r.left(), r.top(), r.right(), r.bottom(), cg, + flags & Style_Sunken, 1, 0); + break; + + case PE_FocusRect: { + const QColor *bg = 0; + + if (!opt.isDefault()) + bg = &opt.color(); + + QPen oldPen = p->pen(); + + if (bg) { + int h, s, v; + bg->hsv(&h, &s, &v); + if (v >= 128) + p->setPen(Qt::black); + else + p->setPen(Qt::white); + } else + p->setPen(cg.foreground()); + + if (flags & Style_FocusAtBorder) + p->drawRect(QRect(r.x() + 1, r.y() + 1, r.width() - 2, r.height() - 2)); + else + p->drawRect(r); + + p->setPen(oldPen); + break; } + + case PE_SpinWidgetPlus: + case PE_SpinWidgetMinus: { + p->save(); + int fw = pixelMetric( PM_DefaultFrameWidth, 0 ); + QRect br; + br.setRect( r.x() + fw, r.y() + fw, r.width() - fw*2, + r.height() - fw*2 ); + + p->fillRect( br, cg.brush( QColorGroup::Button ) ); + p->setPen( cg.buttonText() ); + p->setBrush( cg.buttonText() ); + + int length; + int x = r.x(), y = r.y(), w = r.width(), h = r.height(); + if ( w <= 8 || h <= 6 ) + length = QMIN( w-2, h-2 ); + else + length = QMIN( 2*w / 3, 2*h / 3 ); + + if ( !(length & 1) ) + length -=1; + int xmarg = ( w - length ) / 2; + int ymarg = ( h - length ) / 2; + + p->drawLine( x + xmarg, ( y + h / 2 - 1 ), + x + xmarg + length - 1, ( y + h / 2 - 1 ) ); + if ( pe == PE_SpinWidgetPlus ) + p->drawLine( ( x+w / 2 ) - 1, y + ymarg, + ( x+w / 2 ) - 1, y + ymarg + length - 1 ); + p->restore(); + break; } + + case PE_SpinWidgetUp: + case PE_SpinWidgetDown: { + int fw = pixelMetric( PM_DefaultFrameWidth, 0 ); + QRect br; + br.setRect( r.x() + fw, r.y() + fw, r.width() - fw*2, + r.height() - fw*2 ); + p->fillRect( br, cg.brush( QColorGroup::Button ) ); + int x = r.x(), y = r.y(), w = r.width(), h = r.height(); + int sw = w-4; + if ( sw < 3 ) + break; + else if ( !(sw & 1) ) + sw--; + sw -= ( sw / 7 ) * 2; // Empty border + int sh = sw/2 + 2; // Must have empty row at foot of arrow + + int sx = x + w / 2 - sw / 2 - 1; + int sy = y + h / 2 - sh / 2 - 1; + + QPointArray a; + if ( pe == PE_SpinWidgetDown ) + a.setPoints( 3, 0, 1, sw-1, 1, sh-2, sh-1 ); + else + a.setPoints( 3, 0, sh-1, sw-1, sh-1, sh-2, 1 ); + int bsx = 0; + int bsy = 0; + if ( flags & Style_Sunken ) { + bsx = pixelMetric(PM_ButtonShiftHorizontal); + bsy = pixelMetric(PM_ButtonShiftVertical); + } + p->save(); + p->translate( sx + bsx, sy + bsy ); + p->setPen( cg.buttonText() ); + p->setBrush( cg.buttonText() ); + p->drawPolygon( a ); + p->restore(); + break; } + + case PE_Indicator: { + if (flags & Style_NoChange) { + p->setPen(cg.foreground()); + p->fillRect(r, cg.brush(QColorGroup::Button)); + p->drawRect(r); + p->drawLine(r.topLeft(), r.bottomRight()); + } else + qDrawShadePanel(p, r.x(), r.y(), r.width(), r.height(), + cg, flags & (Style_Sunken | Style_On), 1, + &cg.brush(QColorGroup::Button)); + break; } + + case PE_IndicatorMask: { + p->fillRect(r, color1); + break; } + + case PE_ExclusiveIndicator: { + QRect ir = r; + p->setPen(cg.dark()); + p->drawArc(r, 0, 5760); + + if (flags & (Style_Sunken | Style_On)) { + ir.addCoords(2, 2, -2, -2); + p->setBrush(cg.foreground()); + p->drawEllipse(ir); + } + + break; } + + case PE_ExclusiveIndicatorMask: { + p->setPen(color1); + p->setBrush(color1); + p->drawEllipse(r); + break; } + + case PE_DockWindowHandle: { + bool highlight = flags & Style_On; + + p->save(); + p->translate( r.x(), r.y() ); + if ( flags & Style_Horizontal ) { + int x = r.width() / 3; + if ( r.height() > 4 ) { + qDrawShadePanel( p, x, 2, 3, r.height() - 4, + cg, highlight, 1, 0 ); + qDrawShadePanel( p, x+3, 2, 3, r.height() - 4, + cg, highlight, 1, 0 ); + } + } else { + if ( r.width() > 4 ) { + int y = r.height() / 3; + qDrawShadePanel( p, 2, y, r.width() - 4, 3, + cg, highlight, 1, 0 ); + qDrawShadePanel( p, 2, y+3, r.width() - 4, 3, + cg, highlight, 1, 0 ); + } + } + p->restore(); + break; + } + + case PE_DockWindowSeparator: { + QPoint p1, p2; + if ( flags & Style_Horizontal ) { + p1 = QPoint( r.width()/2, 0 ); + p2 = QPoint( p1.x(), r.height() ); + } else { + p1 = QPoint( 0, r.height()/2 ); + p2 = QPoint( r.width(), p1.y() ); + } + qDrawShadeLine( p, p1, p2, cg, 1, 1, 0 ); + break; } + + case PE_Panel: + case PE_PanelPopup: { + int lw = opt.isDefault() ? pixelMetric(PM_DefaultFrameWidth) + : opt.lineWidth(); + + qDrawShadePanel(p, r, cg, (flags & Style_Sunken), lw); + break; } + + case PE_PanelDockWindow: { + int lw = opt.isDefault() ? pixelMetric(PM_DockWindowFrameWidth) + : opt.lineWidth(); + + qDrawShadePanel(p, r, cg, FALSE, lw); + break; } + + case PE_PanelMenuBar: { + int lw = opt.isDefault() ? pixelMetric(PM_MenuBarFrameWidth) + : opt.lineWidth(); + + qDrawShadePanel(p, r, cg, FALSE, lw, &cg.brush(QColorGroup::Button)); + break; } + + case PE_SizeGrip: { + p->save(); + + int x, y, w, h; + r.rect(&x, &y, &w, &h); + + int sw = QMIN( h,w ); + if ( h > w ) + p->translate( 0, h - w ); + else + p->translate( w - h, 0 ); + + int sx = x; + int sy = y; + int s = sw / 3; + + if ( QApplication::reverseLayout() ) { + sx = x + sw; + for ( int i = 0; i < 4; ++i ) { + p->setPen( QPen( cg.light(), 1 ) ); + p->drawLine( x, sy - 1 , sx + 1, sw ); + p->setPen( QPen( cg.dark(), 1 ) ); + p->drawLine( x, sy, sx, sw ); + p->setPen( QPen( cg.dark(), 1 ) ); + p->drawLine( x, sy + 1, sx - 1, sw ); + sx -= s; + sy += s; + } + } else { + for ( int i = 0; i < 4; ++i ) { + p->setPen( QPen( cg.light(), 1 ) ); + p->drawLine( sx-1, sw, sw, sy-1 ); + p->setPen( QPen( cg.dark(), 1 ) ); + p->drawLine( sx, sw, sw, sy ); + p->setPen( QPen( cg.dark(), 1 ) ); + p->drawLine( sx+1, sw, sw, sy+1 ); + sx += s; + sy += s; + } + } + + p->restore(); + break; } + + case PE_CheckMark: { + const int markW = r.width() > 7 ? 7 : r.width(); + const int markH = markW; + int posX = r.x() + ( r.width() - markW )/2 + 1; + int posY = r.y() + ( r.height() - markH )/2; + + // Could do with some optimizing/caching... + QPointArray a( markH*2 ); + int i, xx, yy; + xx = posX; + yy = 3 + posY; + for ( i=0; isetPen( cg.highlightedText() ); + QPoint offset(1,1); + for ( pnt = 0; pnt < (int)a.size(); pnt++ ) + a[pnt] += offset; + p->drawLineSegments( a ); + for ( pnt = 0; pnt < (int)a.size(); pnt++ ) + a[pnt] -= offset; + } + p->setPen( cg.text() ); + p->drawLineSegments( a ); + break; } + + case PE_PanelGroupBox: //We really do not need PE_GroupBoxFrame anymore, nasty holdover ### + drawPrimitive( PE_GroupBoxFrame, p, r, cg, flags, opt ); + break; + case PE_GroupBoxFrame: { +#ifndef QT_NO_FRAME + if ( opt.isDefault() ) + break; + int lwidth = opt.lineWidth(), mlwidth = opt.midLineWidth(); + if ( flags & (Style_Sunken|Style_Raised)) + qDrawShadeRect( p, r.x(), r.y(), r.width(), r.height(), cg, flags & Style_Sunken, lwidth, mlwidth ); + else + qDrawPlainRect( p, r.x(), r.y(), r.width(), r.height(), cg.foreground(), lwidth ); +#endif + break; } + + case PE_ProgressBarChunk: + p->fillRect( r.x(), r.y() + 3, r.width() -2, r.height() - 6, + cg.brush(QColorGroup::Highlight)); + break; + + case PE_PanelLineEdit: + case PE_PanelTabWidget: + case PE_WindowFrame: + drawPrimitive( PE_Panel, p, r, cg, flags, opt ); + break; + + case PE_RubberBand: + drawPrimitive(PE_FocusRect, p, r, cg, flags, opt); + break; + default: + break; + } + + activePainter = 0; +} + +/*! \reimp */ +void QCommonStyle::drawControl( ControlElement element, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QColorGroup &cg, + SFlags flags, + const QStyleOption& opt ) const +{ +#if defined(QT_CHECK_STATE) + if (! widget) { + qWarning("QCommonStyle::drawControl: widget parameter cannot be zero!"); + return; + } +#endif + + activePainter = p; + + switch (element) { + case CE_MenuBarEmptyArea: { + QRegion reg; + if(p->hasClipping()) //ick + reg = p->clipRegion(); + else + reg = r; + ((QWidget *)widget)->erase( reg ); + break; } + case CE_PushButton: + { +#ifndef QT_NO_PUSHBUTTON + const QPushButton *button = (const QPushButton *) widget; + QRect br = r; + int dbi = pixelMetric(PM_ButtonDefaultIndicator, widget); + + if (button->isDefault() || button->autoDefault()) { + if ( button->isDefault()) + drawPrimitive(PE_ButtonDefault, p, br, cg, flags); + + br.setCoords(br.left() + dbi, + br.top() + dbi, + br.right() - dbi, + br.bottom() - dbi); + } + + p->save(); + p->setBrushOrigin( -widget->backgroundOffset().x(), + -widget->backgroundOffset().y() ); + drawPrimitive(PE_ButtonCommand, p, br, cg, flags); + p->restore(); +#endif + break; + } + + case CE_PushButtonLabel: + { +#ifndef QT_NO_PUSHBUTTON + const QPushButton *button = (const QPushButton *) widget; + QRect ir = r; + + if (button->isDown() || button->isOn()) { + flags |= Style_Sunken; + ir.moveBy(pixelMetric(PM_ButtonShiftHorizontal, widget), + pixelMetric(PM_ButtonShiftVertical, widget)); + } + + if (button->isMenuButton()) { + int mbi = pixelMetric(PM_MenuButtonIndicator, widget); + QRect ar(ir.right() - mbi, ir.y() + 2, mbi - 4, ir.height() - 4); + drawPrimitive(PE_ArrowDown, p, ar, cg, flags, opt); + ir.setWidth(ir.width() - mbi); + } + + int tf=AlignVCenter | ShowPrefix; + if (!styleHint(SH_UnderlineAccelerator, widget, QStyleOption::Default, 0)) + tf |= NoAccel; + +#ifndef QT_NO_ICONSET + if ( button->iconSet() && ! button->iconSet()->isNull() ) { + QIconSet::Mode mode = + button->isEnabled() ? QIconSet::Normal : QIconSet::Disabled; + if ( mode == QIconSet::Normal && button->hasFocus() ) + mode = QIconSet::Active; + + QIconSet::State state = QIconSet::Off; + if ( button->isToggleButton() && button->isOn() ) + state = QIconSet::On; + + QPixmap pixmap = button->iconSet()->pixmap( QIconSet::Small, mode, state ); + int pixw = pixmap.width(); + int pixh = pixmap.height(); + + //Center the icon if there is neither text nor pixmap + if ( button->text().isEmpty() && !button->pixmap() ) + p->drawPixmap( ir.x() + ir.width() / 2 - pixw / 2, ir.y() + ir.height() / 2 - pixh / 2, pixmap ); + else + p->drawPixmap( ir.x() + 2, ir.y() + ir.height() / 2 - pixh / 2, pixmap ); + + ir.moveBy(pixw + 4, 0); + ir.setWidth(ir.width() - (pixw + 4)); + // left-align text if there is + if (!button->text().isEmpty()) + tf |= AlignLeft; + else if (button->pixmap()) + tf |= AlignHCenter; + } else +#endif //QT_NO_ICONSET + tf |= AlignHCenter; + drawItem(p, ir, tf, cg, + flags & Style_Enabled, button->pixmap(), button->text(), + button->text().length(), &(cg.buttonText()) ); + + if (flags & Style_HasFocus) + drawPrimitive(PE_FocusRect, p, subRect(SR_PushButtonFocusRect, widget), + cg, flags); +#endif + break; + } + + case CE_CheckBox: + drawPrimitive(PE_Indicator, p, r, cg, flags, opt); + break; + + case CE_CheckBoxLabel: + { +#ifndef QT_NO_CHECKBOX + const QCheckBox *checkbox = (const QCheckBox *) widget; + + int alignment = QApplication::reverseLayout() ? AlignRight : AlignLeft; + if (!styleHint(SH_UnderlineAccelerator, widget, QStyleOption::Default, 0)) + alignment |= NoAccel; + + drawItem(p, r, alignment | AlignVCenter | ShowPrefix, cg, + flags & Style_Enabled, checkbox->pixmap(), checkbox->text()); + + if (flags & Style_HasFocus) { + QRect fr = visualRect(subRect(SR_CheckBoxFocusRect, widget), widget); + drawPrimitive(PE_FocusRect, p, fr, cg, flags); + } +#endif + break; + } + + case CE_RadioButton: + drawPrimitive(PE_ExclusiveIndicator, p, r, cg, flags, opt); + break; + + case CE_RadioButtonLabel: + { +#ifndef QT_NO_RADIOBUTTON + const QRadioButton *radiobutton = (const QRadioButton *) widget; + + int alignment = QApplication::reverseLayout() ? AlignRight : AlignLeft; + if (!styleHint(SH_UnderlineAccelerator, widget, QStyleOption::Default, 0)) + alignment |= NoAccel; + drawItem(p, r, alignment | AlignVCenter | ShowPrefix, cg, + flags & Style_Enabled, radiobutton->pixmap(), radiobutton->text()); + + if (flags & Style_HasFocus) { + QRect fr = visualRect(subRect(SR_RadioButtonFocusRect, widget), widget); + drawPrimitive(PE_FocusRect, p, fr, cg, flags); + } +#endif + break; + } + +#ifndef QT_NO_TABBAR + case CE_TabBarTab: + { + const QTabBar * tb = (const QTabBar *) widget; + + if ( tb->shape() == QTabBar::TriangularAbove || + tb->shape() == QTabBar::TriangularBelow ) { + // triangular, above or below + int y; + int x; + QPointArray a( 10 ); + a.setPoint( 0, 0, -1 ); + a.setPoint( 1, 0, 0 ); + y = r.height()-2; + x = y/3; + a.setPoint( 2, x++, y-1 ); + a.setPoint( 3, x++, y ); + a.setPoint( 3, x++, y++ ); + a.setPoint( 4, x, y ); + + int i; + int right = r.width() - 1; + for ( i = 0; i < 5; i++ ) + a.setPoint( 9-i, right - a.point( i ).x(), a.point( i ).y() ); + + if ( tb->shape() == QTabBar::TriangularAbove ) + for ( i = 0; i < 10; i++ ) + a.setPoint( i, a.point(i).x(), + r.height() - 1 - a.point( i ).y() ); + + a.translate( r.left(), r.top() ); + + if ( flags & Style_Selected ) + p->setBrush( cg.base() ); + else + p->setBrush( cg.background() ); + p->setPen( cg.foreground() ); + p->drawPolygon( a ); + p->setBrush( NoBrush ); + } + break; + } + + case CE_TabBarLabel: + { + if ( opt.isDefault() ) + break; + + const QTabBar * tb = (const QTabBar *) widget; + QTab * t = opt.tab(); + + QRect tr = r; + if ( t->identifier() == tb->currentTab() ) + tr.setBottom( tr.bottom() - + pixelMetric( QStyle::PM_DefaultFrameWidth, tb ) ); + + int alignment = AlignCenter | ShowPrefix; + if (!styleHint(SH_UnderlineAccelerator, widget, QStyleOption::Default, 0)) + alignment |= NoAccel; + drawItem( p, tr, alignment, cg, + flags & Style_Enabled, 0, t->text() ); + + if ( (flags & Style_HasFocus) && !t->text().isEmpty() ) + drawPrimitive( PE_FocusRect, p, r, cg ); + break; + } +#endif // QT_NO_TABBAR +#ifndef QT_NO_TOOLBOX + case CE_ToolBoxTab: + { + int d = 20 + r.height() - 3; + QPointArray a( 7 ); + a.setPoint( 0, -1, r.height() + 1 ); + a.setPoint( 1, -1, 1 ); + a.setPoint( 2, r.width() - d, 1 ); + a.setPoint( 3, r.width() - 20, r.height() - 2 ); + a.setPoint( 4, r.width() - 1, r.height() - 2 ); + a.setPoint( 5, r.width() - 1, r.height() + 1 ); + a.setPoint( 6, -1, r.height() + 1 ); + + const QToolBox *tb = (const QToolBox*)widget; + + if ( flags & Style_Selected && tb->currentItem() ) + p->setBrush( tb->currentItem()->paletteBackgroundColor() ); + else + p->setBrush( cg.brush(QColorGroup::Background) ); + + p->setPen( cg.mid().dark( 150 ) ); + p->drawPolygon( a ); + p->setPen( cg.light() ); + p->drawLine( 0, 2, r.width() - d, 2 ); + p->drawLine( r.width() - d - 1, 2, r.width() - 21, r.height() - 1 ); + p->drawLine( r.width() - 20, r.height() - 1, r.width(), r.height() - 1 ); + p->setBrush( NoBrush ); + break; + } +#endif // QT_NO_TOOLBOX + case CE_ProgressBarGroove: + qDrawShadePanel(p, r, cg, TRUE, 1, &cg.brush(QColorGroup::Background)); + break; + +#ifndef QT_NO_PROGRESSBAR + case CE_ProgressBarContents: + { + const QProgressBar *progressbar = (const QProgressBar *) widget; + // Correct the highlight color if same as background, + // or else we cannot see the progress... + QColorGroup cgh = cg; + if ( cgh.highlight() == cgh.background() ) + cgh.setColor( QColorGroup::Highlight, progressbar->palette().active().highlight() ); + bool reverse = QApplication::reverseLayout(); + int fw = 2; + int w = r.width() - 2*fw; + if ( !progressbar->totalSteps() ) { + // draw busy indicator + int x = progressbar->progress() % (w * 2); + if (x > w) + x = 2 * w - x; + x = reverse ? r.right() - x : x + r.x(); + p->setPen( QPen(cgh.highlight(), 4) ); + p->drawLine(x, r.y() + 1, x, r.height() - fw); + } else { + const int unit_width = pixelMetric(PM_ProgressBarChunkWidth, widget); + int u; + if ( unit_width > 1 ) + u = (r.width()+unit_width/3) / unit_width; + else + u = w / unit_width; + int p_v = progressbar->progress(); + int t_s = progressbar->totalSteps() ? progressbar->totalSteps() : 1; + + if ( u > 0 && p_v >= INT_MAX / u && t_s >= u ) { + // scale down to something usable. + p_v /= u; + t_s /= u; + } + + // nu < tnu, if last chunk is only a partial chunk + int tnu, nu; + tnu = nu = p_v * u / t_s; + + if (nu * unit_width > w) + nu--; + + // Draw nu units out of a possible u of unit_width + // width, each a rectangle bordered by background + // color, all in a sunken panel with a percentage text + // display at the end. + int x = 0; + int x0 = reverse ? r.right() - ((unit_width > 1) ? + unit_width : fw) : r.x() + fw; + for (int i=0; icenterIndicator() && !progressbar->indicatorFollowsStyle() && + progressbar->progress()*2 >= progressbar->totalSteps() ) + pcolor = &penColor; + drawItem(p, r, AlignCenter | SingleLine, cg, flags & Style_Enabled, 0, + progressbar->progressString(), -1, pcolor ); + } + break; +#endif // QT_NO_PROGRESSBAR + + case CE_MenuBarItem: + { +#ifndef QT_NO_MENUDATA + if (opt.isDefault()) + break; + + QMenuItem *mi = opt.menuItem(); + int alignment = AlignCenter|ShowPrefix|DontClip|SingleLine; + if (!styleHint(SH_UnderlineAccelerator, widget, QStyleOption::Default, 0)) + alignment |= NoAccel; + drawItem( p, r, alignment, cg, + flags & Style_Enabled, mi->pixmap(), mi->text(), -1, + &cg.buttonText() ); +#endif + break; + } + +#ifndef QT_NO_TOOLBUTTON + case CE_ToolButtonLabel: + { + const QToolButton *toolbutton = (const QToolButton *) widget; + QRect rect = r; + Qt::ArrowType arrowType = opt.isDefault() + ? Qt::DownArrow : opt.arrowType(); + + int shiftX = 0; + int shiftY = 0; + if (flags & (Style_Down | Style_On)) { + shiftX = pixelMetric(PM_ButtonShiftHorizontal, widget); + shiftY = pixelMetric(PM_ButtonShiftVertical, widget); + } + + if (!opt.isDefault()) { + PrimitiveElement pe; + switch (arrowType) { + case Qt::LeftArrow: pe = PE_ArrowLeft; break; + case Qt::RightArrow: pe = PE_ArrowRight; break; + case Qt::UpArrow: pe = PE_ArrowUp; break; + default: + case Qt::DownArrow: pe = PE_ArrowDown; break; + } + + rect.moveBy(shiftX, shiftY); + drawPrimitive(pe, p, rect, cg, flags, opt); + } else { + QColor btext = toolbutton->paletteForegroundColor(); + + if (toolbutton->iconSet().isNull() && + ! toolbutton->text().isNull() && + ! toolbutton->usesTextLabel()) { + int alignment = AlignCenter | ShowPrefix; + if (!styleHint(SH_UnderlineAccelerator, widget, QStyleOption::Default, 0)) + alignment |= NoAccel; + + rect.moveBy(shiftX, shiftY); + drawItem(p, rect, alignment, cg, + flags & Style_Enabled, 0, toolbutton->text(), + toolbutton->text().length(), &btext); + } else { + QPixmap pm; + QIconSet::Size size = + toolbutton->usesBigPixmap() ? QIconSet::Large : QIconSet::Small; + QIconSet::State state = + toolbutton->isOn() ? QIconSet::On : QIconSet::Off; + QIconSet::Mode mode; + if (! toolbutton->isEnabled()) + mode = QIconSet::Disabled; + else if (flags & (Style_Down | Style_On) || + (flags & Style_Raised) && (flags & Style_AutoRaise)) + mode = QIconSet::Active; + else + mode = QIconSet::Normal; + pm = toolbutton->iconSet().pixmap( size, mode, state ); + + if ( toolbutton->usesTextLabel() ) { + p->setFont( toolbutton->font() ); + QRect pr = rect, tr = rect; + int alignment = ShowPrefix; + if (!styleHint(SH_UnderlineAccelerator, widget, QStyleOption::Default, 0)) + alignment |= NoAccel; + + if ( toolbutton->textPosition() == QToolButton::Under ) { + int fh = p->fontMetrics().height(); + pr.addCoords( 0, 1, 0, -fh-3 ); + tr.addCoords( 0, pr.bottom(), 0, -3 ); + pr.moveBy(shiftX, shiftY); + drawItem( p, pr, AlignCenter, cg, TRUE, &pm, QString::null ); + alignment |= AlignCenter; + } else { + pr.setWidth( pm.width() + 8 ); + tr.addCoords( pr.right(), 0, 0, 0 ); + pr.moveBy(shiftX, shiftY); + + drawItem( p, pr, AlignCenter, cg, TRUE, &pm, QString::null ); + alignment |= AlignLeft | AlignVCenter; + } + + tr.moveBy(shiftX, shiftY); + drawItem( p, tr, alignment, cg, + flags & Style_Enabled, 0, toolbutton->textLabel(), + toolbutton->textLabel().length(), &btext); + } else { + rect.moveBy(shiftX, shiftY); + drawItem( p, rect, AlignCenter, cg, TRUE, &pm, QString::null ); + } + } + } + + break; + } +#endif // QT_NO_TOOLBUTTON +#ifndef QT_NO_HEADER + case CE_HeaderLabel: + { + QRect rect = r; + const QHeader* header = (const QHeader *) widget; + int section = opt.headerSection(); + + QIconSet* icon = header->iconSet( section ); + if ( icon ) { + QPixmap pixmap = icon->pixmap( QIconSet::Small, + flags & Style_Enabled ? + QIconSet::Normal : QIconSet::Disabled ); + int pixw = pixmap.width(); + int pixh = pixmap.height(); + // "pixh - 1" because of tricky integer division + + QRect pixRect = rect; + pixRect.setY( rect.center().y() - (pixh - 1) / 2 ); + drawItem ( p, pixRect, AlignVCenter, cg, flags & Style_Enabled, + &pixmap, QString::null ); + if (QApplication::reverseLayout()) + rect.setRight(rect.right() - pixw - 2); + else + rect.setLeft(rect.left() + pixw + 2); + } + + if (rect.isValid()) + drawItem ( p, rect, AlignVCenter, cg, flags & Style_Enabled, + 0, header->label( section ), -1, &(cg.buttonText()) ); + } +#endif // QT_NO_HEADER + default: + break; + } + + activePainter = 0; +} + +/*! \reimp */ +void QCommonStyle::drawControlMask( ControlElement control, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QStyleOption& opt ) const +{ + Q_UNUSED(widget); + + activePainter = p; + + QColorGroup cg(color1,color1,color1,color1,color1,color1,color1,color1,color0); + + switch (control) { + case CE_PushButton: + drawPrimitive(PE_ButtonCommand, p, r, cg, Style_Default, opt); + break; + + case CE_CheckBox: + drawPrimitive(PE_IndicatorMask, p, r, cg, Style_Default, opt); + break; + + case CE_RadioButton: + drawPrimitive(PE_ExclusiveIndicatorMask, p, r, cg, Style_Default, opt); + break; + + default: + p->fillRect(r, color1); + break; + } + + activePainter = 0; +} + +/*! \reimp */ +QRect QCommonStyle::subRect(SubRect r, const QWidget *widget) const +{ +#if defined(QT_CHECK_STATE) + if (! widget) { + qWarning("QCommonStyle::subRect: widget parameter cannot be zero!"); + return QRect(); + } +#endif + + QRect rect, wrect(widget->rect()); + + switch (r) { +#ifndef QT_NO_DIALOGBUTTONS + case SR_DialogButtonAbort: + case SR_DialogButtonRetry: + case SR_DialogButtonIgnore: + case SR_DialogButtonAccept: + case SR_DialogButtonReject: + case SR_DialogButtonApply: + case SR_DialogButtonHelp: + case SR_DialogButtonAll: + case SR_DialogButtonCustom: { + QDialogButtons::Button srch = QDialogButtons::None; + if(r == SR_DialogButtonAccept) + srch = QDialogButtons::Accept; + else if(r == SR_DialogButtonReject) + srch = QDialogButtons::Reject; + else if(r == SR_DialogButtonAll) + srch = QDialogButtons::All; + else if(r == SR_DialogButtonApply) + srch = QDialogButtons::Apply; + else if(r == SR_DialogButtonHelp) + srch = QDialogButtons::Help; + else if(r == SR_DialogButtonRetry) + srch = QDialogButtons::Retry; + else if(r == SR_DialogButtonIgnore) + srch = QDialogButtons::Ignore; + else if(r == SR_DialogButtonAbort) + srch = QDialogButtons::Abort; + + const int bwidth = pixelMetric(PM_DialogButtonsButtonWidth, widget), + bheight = pixelMetric(PM_DialogButtonsButtonHeight, widget), + bspace = pixelMetric(PM_DialogButtonsSeparator, widget), + fw = pixelMetric(PM_DefaultFrameWidth, widget); + const QDialogButtons *dbtns = (const QDialogButtons *) widget; + int start = fw; + if(dbtns->orientation() == Horizontal) + start = wrect.right() - fw; + QDialogButtons::Button btns[] = { QDialogButtons::All, QDialogButtons::Reject, QDialogButtons::Accept, //reverse order (right to left) + QDialogButtons::Apply, QDialogButtons::Retry, QDialogButtons::Ignore, QDialogButtons::Abort, + QDialogButtons::Help }; + for(unsigned int i = 0, cnt = 0; i < (sizeof(btns)/sizeof(btns[0])); i++) { + if(dbtns->isButtonVisible(btns[i])) { + QSize szH = dbtns->sizeHint(btns[i]); + int mwidth = QMAX(bwidth, szH.width()), mheight = QMAX(bheight, szH.height()); + if(dbtns->orientation() == Horizontal) { + start -= mwidth; + if(cnt) + start -= bspace; + } else if(cnt) { + start += mheight; + start += bspace; + } + cnt++; + if(btns[i] == srch) { + if(dbtns->orientation() == Horizontal) + return QRect(start, wrect.bottom() - fw - mheight, mwidth, mheight); + else + return QRect(fw, start, mwidth, mheight); + } + } + } + if(r == SR_DialogButtonCustom) { + if(dbtns->orientation() == Horizontal) + return QRect(fw, fw, start - fw - bspace, wrect.height() - (fw*2)); + else + return QRect(fw, start, wrect.width() - (fw*2), wrect.height() - start - (fw*2)); + } + return QRect(); } +#endif //QT_NO_DIALOGBUTTONS + case SR_PushButtonContents: + { +#ifndef QT_NO_PUSHBUTTON + const QPushButton *button = (const QPushButton *) widget; + int dx1, dx2; + + dx1 = pixelMetric(PM_DefaultFrameWidth, widget); + if (button->isDefault() || button->autoDefault()) + dx1 += pixelMetric(PM_ButtonDefaultIndicator, widget); + dx2 = dx1 * 2; + + rect.setRect(wrect.x() + dx1, + wrect.y() + dx1, + wrect.width() - dx2, + wrect.height() - dx2); +#endif + break; + } + + case SR_PushButtonFocusRect: + { +#ifndef QT_NO_PUSHBUTTON + const QPushButton *button = (const QPushButton *) widget; + int dbw1 = 0, dbw2 = 0; + if (button->isDefault() || button->autoDefault()) { + dbw1 = pixelMetric(PM_ButtonDefaultIndicator, widget); + dbw2 = dbw1 * 2; + } + + int dfw1 = pixelMetric(PM_DefaultFrameWidth, widget) * 2, + dfw2 = dfw1 * 2; + + rect.setRect(wrect.x() + dfw1 + dbw1, + wrect.y() + dfw1 + dbw1, + wrect.width() - dfw2 - dbw2, + wrect.height() - dfw2 - dbw2); +#endif + break; + } + + case SR_CheckBoxIndicator: + { + int h = pixelMetric( PM_IndicatorHeight, widget ); + rect.setRect(0, ( wrect.height() - h ) / 2, + pixelMetric( PM_IndicatorWidth, widget ), h ); + break; + } + + case SR_CheckBoxContents: + { +#ifndef QT_NO_CHECKBOX + QRect ir = subRect(SR_CheckBoxIndicator, widget); + rect.setRect(ir.right() + 6, wrect.y(), + wrect.width() - ir.width() - 6, wrect.height()); +#endif + break; + } + + case SR_CheckBoxFocusRect: + { +#ifndef QT_NO_CHECKBOX + const QCheckBox *checkbox = (const QCheckBox *) widget; + if ( !checkbox->pixmap() && checkbox->text().isEmpty() ) { + rect = subRect( SR_CheckBoxIndicator, widget ); + rect.addCoords( 1, 1, -1, -1 ); + break; + } + QRect cr = subRect(SR_CheckBoxContents, widget); + + // don't create a painter if we have an active one + QPainter *p = 0; + if (! activePainter) + p = new QPainter(checkbox); + rect = itemRect((activePainter ? activePainter : p), + cr, AlignLeft | AlignVCenter | ShowPrefix, + checkbox->isEnabled(), + checkbox->pixmap(), + checkbox->text()); + + delete p; + + rect.addCoords( -3, -2, 3, 2 ); + rect = rect.intersect(wrect); +#endif + break; + } + + case SR_RadioButtonIndicator: + { + int h = pixelMetric( PM_ExclusiveIndicatorHeight, widget ); + rect.setRect(0, ( wrect.height() - h ) / 2, + pixelMetric( PM_ExclusiveIndicatorWidth, widget ), h ); + break; + } + + case SR_RadioButtonContents: + { + QRect ir = subRect(SR_RadioButtonIndicator, widget); + rect.setRect(ir.right() + 6, wrect.y(), + wrect.width() - ir.width() - 6, wrect.height()); + break; + } + + case SR_RadioButtonFocusRect: + { +#ifndef QT_NO_RADIOBUTTON + const QRadioButton *radiobutton = (const QRadioButton *) widget; + if ( !radiobutton->pixmap() && radiobutton->text().isEmpty() ) { + rect = subRect( SR_RadioButtonIndicator, widget ); + rect.addCoords( 1, 1, -1, -1 ); + break; + } + QRect cr = subRect(SR_RadioButtonContents, widget); + + // don't create a painter if we have an active one + QPainter *p = 0; + if (! activePainter) + p = new QPainter(radiobutton); + rect = itemRect((activePainter ? activePainter : p), + cr, AlignLeft | AlignVCenter | ShowPrefix, + radiobutton->isEnabled(), + radiobutton->pixmap(), + radiobutton->text()); + delete p; + + rect.addCoords( -3, -2, 3, 2 ); + rect = rect.intersect(wrect); +#endif + break; + } + + case SR_ComboBoxFocusRect: + rect.setRect(3, 3, widget->width()-6-16, widget->height()-6); + break; + +#ifndef QT_NO_SLIDER + case SR_SliderFocusRect: + { + const QSlider * sl = (const QSlider *) widget; + int tickOffset = pixelMetric( PM_SliderTickmarkOffset, sl ); + int thickness = pixelMetric( PM_SliderControlThickness, sl ); + + if ( sl->orientation() == Horizontal ) + rect.setRect( 0, tickOffset-1, sl->width(), thickness+2 ); + else + rect.setRect( tickOffset-1, 0, thickness+2, sl->height() ); + rect = rect.intersect( sl->rect() ); // ## is this really necessary? + break; + } +#endif // QT_NO_SLIDER + +#ifndef QT_NO_MAINWINDOW + case SR_DockWindowHandleRect: + { + if (! widget->parentWidget()) + break; + + const QDockWindow * dw = (const QDockWindow *) widget->parentWidget(); + + if ( !dw->area() || !dw->isCloseEnabled() ) + rect.setRect( 0, 0, widget->width(), widget->height() ); + else { + if ( dw->area()->orientation() == Horizontal ) + rect.setRect(0, 15, widget->width(), widget->height() - 15); + else + rect.setRect(0, 1, widget->width() - 15, widget->height() - 1); + } + break; + } +#endif // QT_NO_MAINWINDOW + + case SR_ProgressBarGroove: + case SR_ProgressBarContents: + { +#ifndef QT_NO_PROGRESSBAR + QFontMetrics fm( ( widget ? widget->fontMetrics() : + QApplication::fontMetrics() ) ); + const QProgressBar *progressbar = (const QProgressBar *) widget; + int textw = 0; + if (progressbar->percentageVisible()) + textw = fm.width("100%") + 6; + + if (progressbar->indicatorFollowsStyle() || + ! progressbar->centerIndicator()) + rect.setCoords(wrect.left(), wrect.top(), + wrect.right() - textw, wrect.bottom()); + else + rect = wrect; +#endif + break; + } + + case SR_ProgressBarLabel: + { +#ifndef QT_NO_PROGRESSBAR + QFontMetrics fm( ( widget ? widget->fontMetrics() : + QApplication::fontMetrics() ) ); + const QProgressBar *progressbar = (const QProgressBar *) widget; + int textw = 0; + if (progressbar->percentageVisible()) + textw = fm.width("100%") + 6; + + if (progressbar->indicatorFollowsStyle() || + ! progressbar->centerIndicator()) + rect.setCoords(wrect.right() - textw, wrect.top(), + wrect.right(), wrect.bottom()); + else + rect = wrect; +#endif + break; + } + + case SR_ToolButtonContents: + rect = querySubControlMetrics(CC_ToolButton, widget, SC_ToolButton); + break; + + case SR_ToolBoxTabContents: + rect = wrect; + rect.addCoords( 0, 0, -30, 0 ); + break; + + default: + rect = wrect; + break; + } + + return rect; +} + +#ifndef QT_NO_RANGECONTROL +/* + I really need this and I don't want to expose it in QRangeControl.. +*/ +static int qPositionFromValue( const QRangeControl * rc, int logical_val, + int span ) +{ + if ( span <= 0 || logical_val < rc->minValue() || + rc->maxValue() <= rc->minValue() ) + return 0; + if ( logical_val > rc->maxValue() ) + return span; + + uint range = rc->maxValue() - rc->minValue(); + uint p = logical_val - rc->minValue(); + + if ( range > (uint)INT_MAX/4096 ) { + const int scale = 4096*2; + return ( (p/scale) * span ) / (range/scale); + // ### the above line is probably not 100% correct + // ### but fixing it isn't worth the extreme pain... + } else if ( range > (uint)span ) { + return (2*p*span + range) / (2*range); + } else { + uint div = span / range; + uint mod = span % range; + return p*div + (2*p*mod + range) / (2*range); + } + //equiv. to (p*span)/range + 0.5 + // no overflow because of this implicit assumption: + // span <= 4096 +} +#endif // QT_NO_RANGECONTROL + +/*! \reimp */ +void QCommonStyle::drawComplexControl( ComplexControl control, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QColorGroup &cg, + SFlags flags, + SCFlags controls, + SCFlags active, + const QStyleOption& opt ) const +{ +#if defined(QT_CHECK_STATE) + if (! widget) { + qWarning("QCommonStyle::drawComplexControl: widget parameter cannot be zero!"); + return; + } +#endif + + activePainter = p; + + switch (control) { +#ifndef QT_NO_SCROLLBAR + case CC_ScrollBar: + { + const QScrollBar *scrollbar = (const QScrollBar *) widget; + QRect addline, subline, addpage, subpage, slider, first, last; + bool maxedOut = (scrollbar->minValue() == scrollbar->maxValue()); + + subline = querySubControlMetrics(control, widget, SC_ScrollBarSubLine, opt); + addline = querySubControlMetrics(control, widget, SC_ScrollBarAddLine, opt); + subpage = querySubControlMetrics(control, widget, SC_ScrollBarSubPage, opt); + addpage = querySubControlMetrics(control, widget, SC_ScrollBarAddPage, opt); + slider = querySubControlMetrics(control, widget, SC_ScrollBarSlider, opt); + first = querySubControlMetrics(control, widget, SC_ScrollBarFirst, opt); + last = querySubControlMetrics(control, widget, SC_ScrollBarLast, opt); + + if ((controls & SC_ScrollBarSubLine) && subline.isValid()) + drawPrimitive(PE_ScrollBarSubLine, p, subline, cg, + ((maxedOut) ? Style_Default : Style_Enabled) | + ((active == SC_ScrollBarSubLine) ? + Style_Down : Style_Default) | + ((scrollbar->orientation() == Qt::Horizontal) ? + Style_Horizontal : 0)); + if ((controls & SC_ScrollBarAddLine) && addline.isValid()) + drawPrimitive(PE_ScrollBarAddLine, p, addline, cg, + ((maxedOut) ? Style_Default : Style_Enabled) | + ((active == SC_ScrollBarAddLine) ? + Style_Down : Style_Default) | + ((scrollbar->orientation() == Qt::Horizontal) ? + Style_Horizontal : 0)); + if ((controls & SC_ScrollBarSubPage) && subpage.isValid()) + drawPrimitive(PE_ScrollBarSubPage, p, subpage, cg, + ((maxedOut) ? Style_Default : Style_Enabled) | + ((active == SC_ScrollBarSubPage) ? + Style_Down : Style_Default) | + ((scrollbar->orientation() == Qt::Horizontal) ? + Style_Horizontal : 0)); + if ((controls & SC_ScrollBarAddPage) && addpage.isValid()) + drawPrimitive(PE_ScrollBarAddPage, p, addpage, cg, + ((maxedOut) ? Style_Default : Style_Enabled) | + ((active == SC_ScrollBarAddPage) ? + Style_Down : Style_Default) | + ((scrollbar->orientation() == Qt::Horizontal) ? + Style_Horizontal : 0)); + if ((controls & SC_ScrollBarFirst) && first.isValid()) + drawPrimitive(PE_ScrollBarFirst, p, first, cg, + ((maxedOut) ? Style_Default : Style_Enabled) | + ((active == SC_ScrollBarFirst) ? + Style_Down : Style_Default) | + ((scrollbar->orientation() == Qt::Horizontal) ? + Style_Horizontal : 0)); + if ((controls & SC_ScrollBarLast) && last.isValid()) + drawPrimitive(PE_ScrollBarLast, p, last, cg, + ((maxedOut) ? Style_Default : Style_Enabled) | + ((active == SC_ScrollBarLast) ? + Style_Down : Style_Default) | + ((scrollbar->orientation() == Qt::Horizontal) ? + Style_Horizontal : 0)); + if ((controls & SC_ScrollBarSlider) && slider.isValid()) { + drawPrimitive(PE_ScrollBarSlider, p, slider, cg, + ((maxedOut) ? Style_Default : Style_Enabled) | + ((active == SC_ScrollBarSlider) ? + Style_Down : Style_Default) | + ((scrollbar->orientation() == Qt::Horizontal) ? + Style_Horizontal : 0)); + + // ### perhaps this should not be able to accept focus if maxedOut? + if (scrollbar->hasFocus()) { + QRect fr(slider.x() + 2, slider.y() + 2, + slider.width() - 5, slider.height() - 5); + drawPrimitive(PE_FocusRect, p, fr, cg, Style_Default); + } + } + + break; + } +#endif // QT_NO_SCROLLBAR + +#ifndef QT_NO_TOOLBUTTON + case CC_ToolButton: + { + const QToolButton *toolbutton = (const QToolButton *) widget; + + QColorGroup c = cg; + if ( toolbutton->backgroundMode() != PaletteButton ) + c.setBrush( QColorGroup::Button, + toolbutton->paletteBackgroundColor() ); + QRect button, menuarea; + button = visualRect( querySubControlMetrics(control, widget, SC_ToolButton, opt), widget ); + menuarea = visualRect( querySubControlMetrics(control, widget, SC_ToolButtonMenu, opt), widget ); + + SFlags bflags = flags, + mflags = flags; + + if (active & SC_ToolButton) + bflags |= Style_Down; + if (active & SC_ToolButtonMenu) + mflags |= Style_Down; + + if (controls & SC_ToolButton) { + if (bflags & (Style_Down | Style_On | Style_Raised)) { + drawPrimitive(PE_ButtonTool, p, button, c, bflags, opt); + } else if ( toolbutton->parentWidget() && + toolbutton->parentWidget()->backgroundPixmap() && + ! toolbutton->parentWidget()->backgroundPixmap()->isNull() ) { + QPixmap pixmap = + *(toolbutton->parentWidget()->backgroundPixmap()); + + p->drawTiledPixmap( r, pixmap, toolbutton->pos() ); + } + } + + if (controls & SC_ToolButtonMenu) { + if (mflags & (Style_Down | Style_On | Style_Raised)) + drawPrimitive(PE_ButtonDropDown, p, menuarea, c, mflags, opt); + drawPrimitive(PE_ArrowDown, p, menuarea, c, mflags, opt); + } + + if (toolbutton->hasFocus() && !toolbutton->focusProxy()) { + QRect fr = toolbutton->rect(); + fr.addCoords(3, 3, -3, -3); + drawPrimitive(PE_FocusRect, p, fr, c); + } + + break; + } +#endif // QT_NO_TOOLBUTTON + +#ifndef QT_NO_TITLEBAR + case CC_TitleBar: + { + const QTitleBar *titlebar = (const QTitleBar *) widget; + if ( controls & SC_TitleBarLabel ) { + QColorGroup cgroup = titlebar->usesActiveColor() ? + titlebar->palette().active() : titlebar->palette().inactive(); + + QColor left = cgroup.highlight(); + QColor right = cgroup.base(); + + if ( left != right ) { + double rS = left.red(); + double gS = left.green(); + double bS = left.blue(); + + const double rD = double(right.red() - rS) / titlebar->width(); + const double gD = double(right.green() - gS) / titlebar->width(); + const double bD = double(right.blue() - bS) / titlebar->width(); + + const int w = titlebar->width(); + for ( int sx = 0; sx < w; sx++ ) { + rS+=rD; + gS+=gD; + bS+=bD; + p->setPen( QColor( (int)rS, (int)gS, (int)bS ) ); + p->drawLine( sx, 0, sx, titlebar->height() ); + } + } else { + p->fillRect( titlebar->rect(), left ); + } + + QRect ir = visualRect( querySubControlMetrics( CC_TitleBar, widget, SC_TitleBarLabel ), widget ); + + p->setPen( cgroup.highlightedText() ); + p->drawText(ir.x()+2, ir.y(), ir.width()-2, ir.height(), + AlignAuto | AlignVCenter | SingleLine, titlebar->visibleText() ); + } + + QRect ir; + bool down = FALSE; + QPixmap pm; + + if ( controls & SC_TitleBarCloseButton ) { + ir = visualRect( querySubControlMetrics( CC_TitleBar, widget, SC_TitleBarCloseButton ), widget ); + down = active & SC_TitleBarCloseButton; + if ( widget->testWFlags( WStyle_Tool ) +#ifndef QT_NO_MAINWINDOW + || ::qt_cast(widget) +#endif + ) + pm = stylePixmap(SP_DockWindowCloseButton, widget); + else + pm = stylePixmap(SP_TitleBarCloseButton, widget); + drawPrimitive(PE_ButtonTool, p, ir, titlebar->colorGroup(), + down ? Style_Down : Style_Raised); + + p->save(); + if( down ) + p->translate( pixelMetric(PM_ButtonShiftHorizontal, widget), + pixelMetric(PM_ButtonShiftVertical, widget) ); + drawItem( p, ir, AlignCenter, titlebar->colorGroup(), TRUE, &pm, QString::null ); + p->restore(); + } + + if ( titlebar->window() ) { + if ( controls & SC_TitleBarMaxButton ) { + ir = visualRect( querySubControlMetrics( CC_TitleBar, widget, SC_TitleBarMaxButton ), widget ); + + down = active & SC_TitleBarMaxButton; + pm = QPixmap(stylePixmap(SP_TitleBarMaxButton, widget)); + drawPrimitive(PE_ButtonTool, p, ir, titlebar->colorGroup(), + down ? Style_Down : Style_Raised); + + p->save(); + if( down ) + p->translate( pixelMetric(PM_ButtonShiftHorizontal, widget), + pixelMetric(PM_ButtonShiftVertical, widget) ); + drawItem( p, ir, AlignCenter, titlebar->colorGroup(), TRUE, &pm, QString::null ); + p->restore(); + } + + if ( controls & SC_TitleBarNormalButton || controls & SC_TitleBarMinButton ) { + ir = visualRect( querySubControlMetrics( CC_TitleBar, widget, SC_TitleBarMinButton ), widget ); + QStyle::SubControl ctrl = (controls & SC_TitleBarNormalButton ? + SC_TitleBarNormalButton : + SC_TitleBarMinButton); + QStyle::StylePixmap spixmap = (controls & SC_TitleBarNormalButton ? + SP_TitleBarNormalButton : + SP_TitleBarMinButton); + down = active & ctrl; + pm = QPixmap(stylePixmap(spixmap, widget)); + drawPrimitive(PE_ButtonTool, p, ir, titlebar->colorGroup(), + down ? Style_Down : Style_Raised); + + p->save(); + if( down ) + p->translate( pixelMetric(PM_ButtonShiftHorizontal, widget), + pixelMetric(PM_ButtonShiftVertical, widget) ); + drawItem( p, ir, AlignCenter, titlebar->colorGroup(), TRUE, &pm, QString::null ); + p->restore(); + } + + if ( controls & SC_TitleBarShadeButton ) { + ir = visualRect( querySubControlMetrics( CC_TitleBar, widget, SC_TitleBarShadeButton ), widget ); + + down = active & SC_TitleBarShadeButton; + pm = QPixmap(stylePixmap(SP_TitleBarShadeButton, widget)); + drawPrimitive(PE_ButtonTool, p, ir, titlebar->colorGroup(), + down ? Style_Down : Style_Raised); + p->save(); + if( down ) + p->translate( pixelMetric(PM_ButtonShiftHorizontal, widget), + pixelMetric(PM_ButtonShiftVertical, widget) ); + drawItem( p, ir, AlignCenter, titlebar->colorGroup(), TRUE, &pm, QString::null ); + p->restore(); + } + + if ( controls & SC_TitleBarUnshadeButton ) { + ir = visualRect( querySubControlMetrics( CC_TitleBar, widget, SC_TitleBarUnshadeButton ), widget ); + + down = active & SC_TitleBarUnshadeButton; + pm = QPixmap(stylePixmap(SP_TitleBarUnshadeButton, widget)); + drawPrimitive(PE_ButtonTool, p, ir, titlebar->colorGroup(), + down ? Style_Down : Style_Raised); + p->save(); + if( down ) + p->translate( pixelMetric(PM_ButtonShiftHorizontal, widget), + pixelMetric(PM_ButtonShiftVertical, widget) ); + drawItem( p, ir, AlignCenter, titlebar->colorGroup(), TRUE, &pm, QString::null ); + p->restore(); + } + } +#ifndef QT_NO_WIDGET_TOPEXTRA + if ( controls & SC_TitleBarSysMenu ) { + if ( titlebar->icon() ) { + ir = visualRect( querySubControlMetrics( CC_TitleBar, widget, SC_TitleBarSysMenu ), widget ); + drawItem( p, ir, AlignCenter, titlebar->colorGroup(), TRUE, titlebar->icon(), QString::null ); + } + } +#endif + break; + } +#endif //QT_NO_TITLEBAR + + case CC_SpinWidget: { +#ifndef QT_NO_SPINWIDGET + const QSpinWidget * sw = (const QSpinWidget *) widget; + SFlags flags; + PrimitiveElement pe; + + if ( controls & SC_SpinWidgetFrame ) + qDrawWinPanel( p, r, cg, TRUE ); //cstyle == Sunken ); + + if ( controls & SC_SpinWidgetUp ) { + flags = Style_Default | Style_Enabled; + if (active == SC_SpinWidgetUp ) { + flags |= Style_On; + flags |= Style_Sunken; + } else + flags |= Style_Raised; + if ( sw->buttonSymbols() == QSpinWidget::PlusMinus ) + pe = PE_SpinWidgetPlus; + else + pe = PE_SpinWidgetUp; + + QRect re = sw->upRect(); + QColorGroup ucg = sw->isUpEnabled() ? cg : sw->palette().disabled(); + drawPrimitive(PE_ButtonBevel, p, re, ucg, flags); + drawPrimitive(pe, p, re, ucg, flags); + } + + if ( controls & SC_SpinWidgetDown ) { + flags = Style_Default | Style_Enabled; + if (active == SC_SpinWidgetDown ) { + flags |= Style_On; + flags |= Style_Sunken; + } else + flags |= Style_Raised; + if ( sw->buttonSymbols() == QSpinWidget::PlusMinus ) + pe = PE_SpinWidgetMinus; + else + pe = PE_SpinWidgetDown; + + QRect re = sw->downRect(); + QColorGroup dcg = sw->isDownEnabled() ? cg : sw->palette().disabled(); + drawPrimitive(PE_ButtonBevel, p, re, dcg, flags); + drawPrimitive(pe, p, re, dcg, flags); + } +#endif + break; } + +#ifndef QT_NO_SLIDER + case CC_Slider: + switch ( controls ) { + case SC_SliderTickmarks: { + const QSlider * sl = (const QSlider *) widget; + int tickOffset = pixelMetric( PM_SliderTickmarkOffset, sl ); + int ticks = sl->tickmarks(); + int thickness = pixelMetric( PM_SliderControlThickness, sl ); + int len = pixelMetric( PM_SliderLength, sl ); + int available = pixelMetric( PM_SliderSpaceAvailable, sl ); + int interval = sl->tickInterval(); + + if ( interval <= 0 ) { + interval = sl->lineStep(); + if ( qPositionFromValue( sl, interval, available ) - + qPositionFromValue( sl, 0, available ) < 3 ) + interval = sl->pageStep(); + } + + int fudge = len / 2; + int pos; + + if ( ticks & QSlider::Above ) { + p->setPen( cg.foreground() ); + int v = sl->minValue(); + if ( !interval ) + interval = 1; + while ( v <= sl->maxValue() + 1 ) { + pos = qPositionFromValue( sl, v, available ) + fudge; + if ( sl->orientation() == Horizontal ) + p->drawLine( pos, 0, pos, tickOffset-2 ); + else + p->drawLine( 0, pos, tickOffset-2, pos ); + v += interval; + } + } + + if ( ticks & QSlider::Below ) { + p->setPen( cg.foreground() ); + int v = sl->minValue(); + if ( !interval ) + interval = 1; + while ( v <= sl->maxValue() + 1 ) { + pos = qPositionFromValue( sl, v, available ) + fudge; + if ( sl->orientation() == Horizontal ) + p->drawLine( pos, tickOffset+thickness+1, pos, + tickOffset+thickness+1 + available-2 ); + else + p->drawLine( tickOffset+thickness+1, pos, + tickOffset+thickness+1 + available-2, + pos ); + v += interval; + } + + } + + break; } + } + break; +#endif // QT_NO_SLIDER +#ifndef QT_NO_LISTVIEW + case CC_ListView: + if ( controls & SC_ListView ) { + QListView *listview = (QListView*)widget; + p->fillRect( r, listview->viewport()->backgroundBrush() ); + } + break; +#endif //QT_NO_LISTVIEW + default: + break; + } + + activePainter = 0; +} + + +/*! \reimp */ +void QCommonStyle::drawComplexControlMask( ComplexControl control, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QStyleOption& opt ) const +{ + Q_UNUSED(control); + Q_UNUSED(widget); + Q_UNUSED(opt); + + p->fillRect(r, color1); +} + + +/*! \reimp */ +QRect QCommonStyle::querySubControlMetrics( ComplexControl control, + const QWidget *widget, + SubControl sc, + const QStyleOption &opt ) const +{ +#if defined(QT_CHECK_STATE) + if (! widget) { + qWarning("QCommonStyle::querySubControlMetrics: widget parameter cannot be zero!"); + return QRect(); + } +#endif + + switch ( control ) { + case CC_SpinWidget: { + int fw = pixelMetric( PM_SpinBoxFrameWidth, widget); + QSize bs; + bs.setHeight( widget->height()/2 - fw ); + if ( bs.height() < 8 ) + bs.setHeight( 8 ); + bs.setWidth( QMIN( bs.height() * 8 / 5, widget->width() / 4 ) ); // 1.6 -approximate golden mean + bs = bs.expandedTo( QApplication::globalStrut() ); + int y = fw; + int x, lx, rx; + x = widget->width() - y - bs.width(); + lx = fw; + rx = x - fw; + switch ( sc ) { + case SC_SpinWidgetUp: + return QRect(x, y, bs.width(), bs.height()); + case SC_SpinWidgetDown: + return QRect(x, y + bs.height(), bs.width(), bs.height()); + case SC_SpinWidgetButtonField: + return QRect(x, y, bs.width(), widget->height() - 2*fw); + case SC_SpinWidgetEditField: + return QRect(lx, fw, rx, widget->height() - 2*fw); + case SC_SpinWidgetFrame: + return widget->rect(); + default: + break; + } + break; } + + case CC_ComboBox: { + int x = 0, y = 0, wi = widget->width(), he = widget->height(); + int xpos = x; + xpos += wi - 2 - 16; + + switch ( sc ) { + case SC_ComboBoxFrame: + return widget->rect(); + case SC_ComboBoxArrow: + return QRect(xpos, y+2, 16, he-4); + case SC_ComboBoxEditField: + return QRect(x+3, y+3, wi-6-16, he-6); + case SC_ComboBoxListBoxPopup: + return opt.rect(); + default: + break; + } + break; } + +#ifndef QT_NO_SCROLLBAR + case CC_ScrollBar: { + const QScrollBar *scrollbar = (const QScrollBar *) widget; + int sliderstart = 0; + int sbextent = pixelMetric(PM_ScrollBarExtent, widget); + int maxlen = ((scrollbar->orientation() == Qt::Horizontal) ? + scrollbar->width() : scrollbar->height()) - (sbextent * 2); + int sliderlen; + + sliderstart = scrollbar->sliderStart(); + + // calculate slider length + if (scrollbar->maxValue() != scrollbar->minValue()) { + uint range = scrollbar->maxValue() - scrollbar->minValue(); + sliderlen = (Q_LLONG(scrollbar->pageStep()) * maxlen) / (range + scrollbar->pageStep()); + + int slidermin = pixelMetric( PM_ScrollBarSliderMin, widget ); + if ( sliderlen < slidermin || range > INT_MAX / 2 ) + sliderlen = slidermin; + if ( sliderlen > maxlen ) + sliderlen = maxlen; + } else + sliderlen = maxlen; + + switch (sc) { + case SC_ScrollBarSubLine: // top/left button + if (scrollbar->orientation() == Qt::Horizontal) { + int buttonWidth = QMIN(scrollbar->width()/2, sbextent); + return QRect( 0, 0, buttonWidth, sbextent ); + } else { + int buttonHeight = QMIN(scrollbar->height()/2, sbextent); + return QRect( 0, 0, sbextent, buttonHeight ); + } + + case SC_ScrollBarAddLine: // bottom/right button + if (scrollbar->orientation() == Qt::Horizontal) { + int buttonWidth = QMIN(scrollbar->width()/2, sbextent); + return QRect( scrollbar->width() - buttonWidth, 0, buttonWidth, sbextent ); + } else { + int buttonHeight = QMIN(scrollbar->height()/2, sbextent); + return QRect( 0, scrollbar->height() - buttonHeight, sbextent, buttonHeight ); + } + + case SC_ScrollBarSubPage: // between top/left button and slider + if (scrollbar->orientation() == Qt::Horizontal) + return QRect(sbextent, 0, sliderstart - sbextent, sbextent); + return QRect(0, sbextent, sbextent, sliderstart - sbextent); + + case SC_ScrollBarAddPage: // between bottom/right button and slider + if (scrollbar->orientation() == Qt::Horizontal) + return QRect(sliderstart + sliderlen, 0, + maxlen - sliderstart - sliderlen + sbextent, sbextent); + return QRect(0, sliderstart + sliderlen, + sbextent, maxlen - sliderstart - sliderlen + sbextent); + + case SC_ScrollBarGroove: + if (scrollbar->orientation() == Qt::Horizontal) + return QRect(sbextent, 0, scrollbar->width() - sbextent * 2, + scrollbar->height()); + return QRect(0, sbextent, scrollbar->width(), + scrollbar->height() - sbextent * 2); + + case SC_ScrollBarSlider: + if (scrollbar->orientation() == Qt::Horizontal) + return QRect(sliderstart, 0, sliderlen, sbextent); + return QRect(0, sliderstart, sbextent, sliderlen); + + default: break; + } + + break; } +#endif // QT_NO_SCROLLBAR + +#ifndef QT_NO_SLIDER + case CC_Slider: { + const QSlider * sl = (const QSlider *) widget; + int tickOffset = pixelMetric( PM_SliderTickmarkOffset, sl ); + int thickness = pixelMetric( PM_SliderControlThickness, sl ); + + switch ( sc ) { + case SC_SliderHandle: { + int sliderPos = 0; + int len = pixelMetric( PM_SliderLength, sl ); + + sliderPos = sl->sliderStart(); + + if ( sl->orientation() == Horizontal ) + return QRect( sliderPos, tickOffset, len, thickness ); + return QRect( tickOffset, sliderPos, thickness, len ); } + case SC_SliderGroove: { + if ( sl->orientation() == Horizontal ) + return QRect( 0, tickOffset, sl->width(), thickness ); + return QRect( tickOffset, 0, thickness, sl->height() ); } + + default: + break; + } + break; } +#endif // QT_NO_SLIDER + +#if !defined(QT_NO_TOOLBUTTON) && !defined(QT_NO_POPUPMENU) + case CC_ToolButton: { + const QToolButton *toolbutton = (const QToolButton *) widget; + int mbi = pixelMetric(PM_MenuButtonIndicator, widget); + + QRect rect = toolbutton->rect(); + switch (sc) { + case SC_ToolButton: + if (toolbutton->popup() && ! toolbutton->popupDelay()) + rect.addCoords(0, 0, -mbi, 0); + return rect; + + case SC_ToolButtonMenu: + if (toolbutton->popup() && ! toolbutton->popupDelay()) + rect.addCoords(rect.width() - mbi, 0, 0, 0); + return rect; + + default: break; + } + break; + } +#endif // QT_NO_TOOLBUTTON && QT_NO_POPUPMENU + +#ifndef QT_NO_TITLEBAR + case CC_TitleBar: { + const QTitleBar *titlebar = (const QTitleBar *) widget; + const int controlTop = 2; + const int controlHeight = widget->height() - controlTop * 2; + + switch (sc) { + case SC_TitleBarLabel: { + const QTitleBar *titlebar = (QTitleBar*)widget; + QRect ir( 0, 0, titlebar->width(), titlebar->height() ); + if ( titlebar->testWFlags( WStyle_Tool ) ) { + if ( titlebar->testWFlags( WStyle_SysMenu ) ) + ir.addCoords( 0, 0, -controlHeight-3, 0 ); + if ( titlebar->testWFlags( WStyle_MinMax ) ) + ir.addCoords( 0, 0, -controlHeight-2, 0 ); + } else { + if ( titlebar->testWFlags( WStyle_SysMenu ) ) + ir.addCoords( controlHeight+3, 0, -controlHeight-3, 0 ); + if ( titlebar->testWFlags( WStyle_Minimize ) ) + ir.addCoords( 0, 0, -controlHeight-2, 0 ); + if ( titlebar->testWFlags( WStyle_Maximize ) ) + ir.addCoords( 0, 0, -controlHeight-2, 0 ); + } + return ir; } + + case SC_TitleBarCloseButton: + return QRect( titlebar->width() - ( controlHeight + controlTop ), + controlTop, controlHeight, controlHeight ); + + case SC_TitleBarMaxButton: + case SC_TitleBarShadeButton: + case SC_TitleBarUnshadeButton: + return QRect( titlebar->width() - ( ( controlHeight + controlTop ) * 2 ), + controlTop, controlHeight, controlHeight ); + + case SC_TitleBarMinButton: + case SC_TitleBarNormalButton: { + int offset = controlHeight + controlTop; + if ( !titlebar->testWFlags( WStyle_Maximize ) ) + offset *= 2; + else + offset *= 3; + return QRect( titlebar->width() - offset, controlTop, controlHeight, controlHeight ); + } + + case SC_TitleBarSysMenu: + return QRect( 3, controlTop, controlHeight, controlHeight); + + default: break; + } + break; } +#endif //QT_NO_TITLEBAR + + default: + break; + } + return QRect(); +} + + +/*! \reimp */ +QStyle::SubControl QCommonStyle::querySubControl(ComplexControl control, + const QWidget *widget, + const QPoint &pos, + const QStyleOption& opt ) const +{ + SubControl ret = SC_None; + + switch (control) { +#ifndef QT_NO_LISTVIEW + case CC_ListView: + { + if(pos.x() >= 0 && pos.x() < + opt.listViewItem()->listView()->treeStepSize()) + ret = SC_ListViewExpand; + break; + } +#endif +#ifndef QT_NO_SCROLLBAR + case CC_ScrollBar: + { + QRect r; + uint ctrl = SC_ScrollBarAddLine; + + // we can do this because subcontrols were designed to be masks as well... + while (ret == SC_None && ctrl <= SC_ScrollBarGroove) { + r = querySubControlMetrics(control, widget, + (QStyle::SubControl) ctrl, opt); + if (r.isValid() && r.contains(pos)) + ret = (QStyle::SubControl) ctrl; + + ctrl <<= 1; + } + + break; + } +#endif + case CC_TitleBar: + { +#ifndef QT_NO_TITLEBAR + const QTitleBar *titlebar = (QTitleBar*)widget; + QRect r; + uint ctrl = SC_TitleBarLabel; + + // we can do this because subcontrols were designed to be masks as well... + while (ret == SC_None && ctrl <= SC_TitleBarUnshadeButton) { + r = visualRect( querySubControlMetrics( control, widget, (QStyle::SubControl) ctrl, opt ), widget ); + if (r.isValid() && r.contains(pos)) + ret = (QStyle::SubControl) ctrl; + + ctrl <<= 1; + } + if ( titlebar->window() ) { + if (titlebar->testWFlags( WStyle_Tool )) { + if ( ret == SC_TitleBarMinButton || ret == SC_TitleBarMaxButton ) { + if ( titlebar->window()->isMinimized() ) + ret = SC_TitleBarUnshadeButton; + else + ret = SC_TitleBarShadeButton; + } + } else if ( ret == SC_TitleBarMinButton && titlebar->window()->isMinimized() ) { + ret = QStyle::SC_TitleBarNormalButton; + } + } +#endif + break; + } + + default: + break; + } + + return ret; +} + + +/*! \reimp */ +int QCommonStyle::pixelMetric(PixelMetric m, const QWidget *widget) const +{ + int ret; + + switch (m) { + case PM_DialogButtonsSeparator: + ret = 5; + break; + case PM_DialogButtonsButtonWidth: + ret = 70; + break; + case PM_DialogButtonsButtonHeight: + ret = 30; + break; + case PM_CheckListControllerSize: + case PM_CheckListButtonSize: + ret = 16; + break; + case PM_TitleBarHeight: { + if ( widget ) { + if ( widget->testWFlags( WStyle_Tool ) ) { + ret = QMAX( widget->fontMetrics().lineSpacing(), 16 ); +#ifndef QT_NO_MAINWINDOW + } else if ( ::qt_cast(widget) ) { + ret = QMAX( widget->fontMetrics().lineSpacing(), 13 ); +#endif + } else { + ret = QMAX( widget->fontMetrics().lineSpacing(), 18 ); + } + } else { + ret = 0; + } + + break; } + case PM_ScrollBarSliderMin: + ret = 9; + break; + + case PM_ButtonMargin: + ret = 6; + break; + + case PM_ButtonDefaultIndicator: + ret = 0; + break; + + case PM_MenuButtonIndicator: + if (! widget) + ret = 12; + else + ret = QMAX(12, (widget->height() - 4) / 3); + break; + + case PM_ButtonShiftHorizontal: + case PM_ButtonShiftVertical: + ret = 0; + break; + + case PM_SpinBoxFrameWidth: + case PM_DefaultFrameWidth: + ret = 2; + break; + + case PM_MDIFrameWidth: + ret = 2; + break; + + case PM_MDIMinimizedWidth: + ret = 196; + break; + +#ifndef QT_NO_SCROLLBAR + case PM_ScrollBarExtent: + if ( !widget ) { + ret = 16; + } else { + const QScrollBar *bar = (const QScrollBar*)widget; + int s = bar->orientation() == Qt::Horizontal ? + QApplication::globalStrut().height() + : QApplication::globalStrut().width(); + ret = QMAX( 16, s ); + } + break; +#endif + case PM_MaximumDragDistance: + ret = -1; + break; + +#ifndef QT_NO_SLIDER + case PM_SliderThickness: + ret = 16; + break; + + case PM_SliderTickmarkOffset: + { + if (! widget) { + ret = 0; + break; + } + + const QSlider * sl = (const QSlider *) widget; + int space = (sl->orientation() == Horizontal) ? sl->height() : + sl->width(); + int thickness = pixelMetric( PM_SliderControlThickness, sl ); + int ticks = sl->tickmarks(); + + if ( ticks == QSlider::Both ) + ret = (space - thickness) / 2; + else if ( ticks == QSlider::Above ) + ret = space - thickness; + else + ret = 0; + break; + } + + case PM_SliderSpaceAvailable: + { + const QSlider * sl = (const QSlider *) widget; + if ( sl->orientation() == Horizontal ) + ret = sl->width() - pixelMetric( PM_SliderLength, sl ); + else + ret = sl->height() - pixelMetric( PM_SliderLength, sl ); + break; + } +#endif // QT_NO_SLIDER + + case PM_DockWindowSeparatorExtent: + ret = 6; + break; + + case PM_DockWindowHandleExtent: + ret = 8; + break; + + case PM_DockWindowFrameWidth: + ret = 1; + break; + + case PM_MenuBarFrameWidth: + ret = 2; + break; + + case PM_MenuBarItemSpacing: + case PM_ToolBarItemSpacing: + ret = 0; + break; + + case PM_TabBarTabOverlap: + ret = 3; + break; + + case PM_TabBarBaseHeight: + ret = 0; + break; + + case PM_TabBarBaseOverlap: + ret = 0; + break; + + case PM_TabBarTabHSpace: + ret = 24; + break; + + case PM_TabBarTabShiftHorizontal: + case PM_TabBarTabShiftVertical: + ret = 2; + break; + +#ifndef QT_NO_TABBAR + case PM_TabBarTabVSpace: + { + const QTabBar * tb = (const QTabBar *) widget; + if ( tb && ( tb->shape() == QTabBar::RoundedAbove || + tb->shape() == QTabBar::RoundedBelow ) ) + ret = 10; + else + ret = 0; + break; + } +#endif + + case PM_ProgressBarChunkWidth: + ret = 9; + break; + + case PM_IndicatorWidth: + ret = 13; + break; + + case PM_IndicatorHeight: + ret = 13; + break; + + case PM_ExclusiveIndicatorWidth: + ret = 12; + break; + + case PM_ExclusiveIndicatorHeight: + ret = 12; + break; + + case PM_PopupMenuFrameHorizontalExtra: + case PM_PopupMenuFrameVerticalExtra: + ret = 0; + break; + + case PM_HeaderMargin: + ret = 4; + break; + case PM_HeaderMarkSize: + ret = 32; + break; + case PM_HeaderGripMargin: + ret = 4; + break; + case PM_TabBarScrollButtonWidth: + ret = 16; + break; + default: + ret = 0; + break; + } + + return ret; +} + + +/*! \reimp */ +QSize QCommonStyle::sizeFromContents(ContentsType contents, + const QWidget *widget, + const QSize &contentsSize, + const QStyleOption& opt ) const +{ + QSize sz(contentsSize); + +#if defined(QT_CHECK_STATE) + if (! widget) { + qWarning("QCommonStyle::sizeFromContents: widget parameter cannot be zero!"); + return sz; + } +#endif + + switch (contents) { +#ifndef QT_NO_DIALOGBUTTONS + case CT_DialogButtons: { + const QDialogButtons *dbtns = (const QDialogButtons *)widget; + int w = contentsSize.width(), h = contentsSize.height(); + const int bwidth = pixelMetric(PM_DialogButtonsButtonWidth, widget), + bspace = pixelMetric(PM_DialogButtonsSeparator, widget), + bheight = pixelMetric(PM_DialogButtonsButtonHeight, widget); + if(dbtns->orientation() == Horizontal) { + if(!w) + w = bwidth; + } else { + if(!h) + h = bheight; + } + QDialogButtons::Button btns[] = { QDialogButtons::All, QDialogButtons::Reject, QDialogButtons::Accept, //reverse order (right to left) + QDialogButtons::Apply, QDialogButtons::Retry, QDialogButtons::Ignore, QDialogButtons::Abort, + QDialogButtons::Help }; + for(unsigned int i = 0, cnt = 0; i < (sizeof(btns)/sizeof(btns[0])); i++) { + if(dbtns->isButtonVisible(btns[i])) { + QSize szH = dbtns->sizeHint(btns[i]); + int mwidth = QMAX(bwidth, szH.width()), mheight = QMAX(bheight, szH.height()); + if(dbtns->orientation() == Horizontal) + h = QMAX(h, mheight); + else + w = QMAX(w, mwidth); + + if(cnt) + w += bspace; + cnt++; + if(dbtns->orientation() == Horizontal) + w += mwidth; + else + h += mheight; + } + } + const int fw = pixelMetric(PM_DefaultFrameWidth, widget) * 2; + sz = QSize(w + fw, h + fw); + break; } +#endif //QT_NO_DIALOGBUTTONS + case CT_PushButton: + { +#ifndef QT_NO_PUSHBUTTON + const QPushButton *button = (const QPushButton *) widget; + int w = contentsSize.width(), + h = contentsSize.height(), + bm = pixelMetric(PM_ButtonMargin, widget), + fw = pixelMetric(PM_DefaultFrameWidth, widget) * 2; + + w += bm + fw; + h += bm + fw; + + if (button->isDefault() || button->autoDefault()) { + int dbw = pixelMetric(PM_ButtonDefaultIndicator, widget) * 2; + w += dbw; + h += dbw; + } + + sz = QSize(w, h); +#endif + break; + } + + case CT_CheckBox: + { +#ifndef QT_NO_CHECKBOX + const QCheckBox *checkbox = (const QCheckBox *) widget; + QRect irect = subRect(SR_CheckBoxIndicator, widget); + int h = pixelMetric( PM_IndicatorHeight, widget ); + int margins = (!checkbox->pixmap() && checkbox->text().isEmpty()) ? 0 : 10; + sz += QSize(irect.right() + margins, 4 ); + sz.setHeight( QMAX( sz.height(), h ) ); +#endif + break; + } + + case CT_RadioButton: + { +#ifndef QT_NO_RADIOBUTTON + const QRadioButton *radiobutton = (const QRadioButton *) widget; + QRect irect = subRect(SR_RadioButtonIndicator, widget); + int h = pixelMetric( PM_ExclusiveIndicatorHeight, widget ); + int margins = (!radiobutton->pixmap() && radiobutton->text().isEmpty()) ? 0 : 10; + sz += QSize(irect.right() + margins, 4 ); + sz.setHeight( QMAX( sz.height(), h ) ); +#endif + break; + } + + case CT_ToolButton: + { + sz = QSize(sz.width() + 6, sz.height() + 5); + break; + } + + case CT_ComboBox: + { + int dfw = pixelMetric(PM_DefaultFrameWidth, widget) * 2; + sz = QSize(sz.width() + dfw + 21, sz.height() + dfw ); + break; + } + + case CT_PopupMenuItem: + { +#ifndef QT_NO_POPUPMENU + if (opt.isDefault()) + break; + + const QPopupMenu *popup = (const QPopupMenu *) widget; + bool checkable = popup->isCheckable(); + QMenuItem *mi = opt.menuItem(); + int maxpmw = opt.maxIconWidth(); + int w = sz.width(), h = sz.height(); + + if (mi->custom()) { + w = mi->custom()->sizeHint().width(); + h = mi->custom()->sizeHint().height(); + if (! mi->custom()->fullSpan()) + h += 8; + } else if ( mi->widget() ) { + } else if (mi->isSeparator()) { + w = 10; + h = 2; + } else { + if (mi->pixmap()) + h = QMAX(h, mi->pixmap()->height() + 4); + else + h = QMAX(h, popup->fontMetrics().height() + 8); + + if (mi->iconSet() != 0) + h = QMAX(h, mi->iconSet()->pixmap(QIconSet::Small, + QIconSet::Normal).height() + 4); + } + + if (! mi->text().isNull()) { + if (mi->text().find('\t') >= 0) + w += 12; + } + + if (maxpmw) + w += maxpmw + 6; + if (checkable && maxpmw < 20) + w += 20 - maxpmw; + if (checkable || maxpmw > 0) + w += 2; + w += 12; + + sz = QSize(w, h); +#endif + break; + } + + case CT_LineEdit: + case CT_Header: + case CT_Slider: + case CT_ProgressBar: + // just return the contentsSize for now + // fall through intended + + default: + break; + } + + return sz; +} + + +/*! \reimp */ +int QCommonStyle::styleHint(StyleHint sh, const QWidget * w, const QStyleOption &, QStyleHintReturn *) const +{ + int ret; + + switch (sh) { +#ifndef QT_NO_DIALOGBUTTONS + case SH_DialogButtons_DefaultButton: + ret = QDialogButtons::Accept; + break; +#endif + case SH_GroupBox_TextLabelVerticalAlignment: + ret = Qt::AlignVCenter; + break; + + case SH_GroupBox_TextLabelColor: + ret = (int) ( w ? w->paletteForegroundColor().rgb() : 0 ); + break; + + case SH_ListViewExpand_SelectMouseType: + case SH_TabBar_SelectMouseType: + ret = QEvent::MouseButtonPress; + break; + + case SH_GUIStyle: + ret = WindowsStyle; + break; + + case SH_ScrollBar_BackgroundMode: + ret = QWidget::PaletteBackground; + break; + + case SH_TabBar_Alignment: + case SH_Header_ArrowAlignment: + ret = Qt::AlignLeft; + break; + + case SH_PopupMenu_SubMenuPopupDelay: + ret = 256; + break; + + case SH_ProgressDialog_TextLabelAlignment: + ret = Qt::AlignCenter; + break; + + case SH_BlinkCursorWhenTextSelected: + ret = 1; + break; + + case SH_Table_GridLineColor: + ret = -1; + break; + + case SH_LineEdit_PasswordCharacter: + ret = '*'; + break; + + case SH_ToolBox_SelectedPageTitleBold: + ret = 1; + break; + + case SH_UnderlineAccelerator: + ret = 1; + break; + + case SH_ToolButton_Uses3D: + ret = 1; + break; + + default: + ret = 0; + break; + } + + return ret; +} + +/*! \reimp */ +QPixmap QCommonStyle::stylePixmap(StylePixmap, const QWidget *, const QStyleOption&) const +{ + return QPixmap(); +} + + +#endif // QT_NO_STYLE diff --git a/src/styles/qcommonstyle.h b/src/styles/qcommonstyle.h new file mode 100644 index 0000000..3bed7b0 --- /dev/null +++ b/src/styles/qcommonstyle.h @@ -0,0 +1,137 @@ +/**************************************************************************** +** +** Definition of QCommonStyle class +** +** Created : 980616 +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the widgets module of the Qt GUI Toolkit. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** This file may be used under the terms of the Q Public License as +** defined by Trolltech ASA and appearing in the file LICENSE.QPL +** included in the packaging of this file. Licensees holding valid Qt +** Commercial licenses may use this file in accordance with the Qt +** Commercial License Agreement provided with the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef QCOMMONSTYLE_H +#define QCOMMONSTYLE_H + +#ifndef QT_H +#include "qstyle.h" +#endif // QT_H + +#ifndef QT_NO_STYLE + +class Q_EXPORT QCommonStyle: public QStyle +{ + Q_OBJECT + +public: + QCommonStyle(); + ~QCommonStyle(); + + void drawPrimitive( PrimitiveElement pe, + QPainter *p, + const QRect &r, + const QColorGroup &cg, + SFlags flags = Style_Default, + const QStyleOption& = QStyleOption::Default ) const; + + void drawControl( ControlElement element, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QColorGroup &cg, + SFlags how = Style_Default, + const QStyleOption& = QStyleOption::Default ) const; + + void drawControlMask( ControlElement element, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QStyleOption& = QStyleOption::Default ) const; + + QRect subRect( SubRect r, const QWidget *widget ) const; + + void drawComplexControl( ComplexControl control, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QColorGroup &cg, + SFlags how = Style_Default, +#ifdef Q_QDOC + SCFlags sub = SC_All, +#else + SCFlags sub = (uint)SC_All, +#endif + SCFlags subActive = SC_None, + const QStyleOption& = QStyleOption::Default ) const; + + void drawComplexControlMask( ComplexControl control, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QStyleOption& = QStyleOption::Default ) const; + + QRect querySubControlMetrics( ComplexControl control, + const QWidget *widget, + SubControl sc, + const QStyleOption& = QStyleOption::Default ) const; + + SubControl querySubControl( ComplexControl control, + const QWidget *widget, + const QPoint &pos, + const QStyleOption& = QStyleOption::Default ) const; + + int pixelMetric( PixelMetric m, const QWidget *widget = 0 ) const; + + QSize sizeFromContents( ContentsType s, + const QWidget *widget, + const QSize &contentsSize, + const QStyleOption& = QStyleOption::Default ) const; + + int styleHint(StyleHint sh, const QWidget *, const QStyleOption &, QStyleHintReturn *) const; + + QPixmap stylePixmap( StylePixmap sp, + const QWidget *widget = 0, + const QStyleOption& = QStyleOption::Default ) const; + + +private: + // Disabled copy constructor and operator= +#if defined(Q_DISABLE_COPY) + QCommonStyle( const QCommonStyle & ); + QCommonStyle &operator=( const QCommonStyle & ); +#endif +}; + + + +#endif // QT_NO_STYLE + +#endif // QCOMMONSTYLE_H diff --git a/src/styles/qcompactstyle.cpp b/src/styles/qcompactstyle.cpp new file mode 100644 index 0000000..46b4df3 --- /dev/null +++ b/src/styles/qcompactstyle.cpp @@ -0,0 +1,321 @@ +/**************************************************************************** +** +** Implementation of compact style class +** +** Created : 006231 +** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the widgets module of the Qt GUI Toolkit. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** This file may be used under the terms of the Q Public License as +** defined by Trolltech ASA and appearing in the file LICENSE.QPL +** included in the packaging of this file. Licensees holding valid Qt +** Commercial licenses may use this file in accordance with the Qt +** Commercial License Agreement provided with the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "qcompactstyle.h" + +#if !defined(QT_NO_STYLE_COMPACT) || defined(QT_PLUGIN) + +#include "qfontmetrics.h" +#include "qpalette.h" +#include "qpainter.h" +#include "qdrawutil.h" +#include "qmenudata.h" +#include "qpopupmenu.h" + +QCompactStyle::QCompactStyle() +: QWindowsStyle() +{ +} + +/*! \reimp */ +int QCompactStyle::pixelMetric( PixelMetric metric, const QWidget *widget ) +{ + int ret; + switch ( metric ) { + case PM_ButtonMargin: + ret = 2; + break; + // tws - I added this in to stop this "Windows Scroll behaivor." Remove it + // if you don't want it. + case PM_MaximumDragDistance: + ret = -1; + break; + default: + ret = QWindowsStyle::pixelMetric( metric, widget ); + break; + } + return ret; +} + +static const int motifItemFrame = 0; // menu item frame width +static const int motifSepHeight = 2; // separator item height +static const int motifItemHMargin = 1; // menu item hor text margin +static const int motifItemVMargin = 2; // menu item ver text margin +static const int motifArrowHMargin = 0; // arrow horizontal margin +static const int motifTabSpacing = 4; // space between text and tab +static const int motifCheckMarkHMargin = 1; // horiz. margins of check mark +static const int windowsRightBorder = 8; // right border on windows +static const int windowsCheckMarkWidth = 2; // checkmarks width on windows + +static int extraPopupMenuItemWidth( bool checkable, int maxpmw, QMenuItem* mi, const QFontMetrics& /*fm*/ ) +{ + int w = 2*motifItemHMargin + 2*motifItemFrame; // a little bit of border can never harm + + if ( mi->isSeparator() ) + return 10; // arbitrary + else if ( mi->pixmap() ) + w += mi->pixmap()->width(); // pixmap only + + if ( !mi->text().isNull() ) { + if ( mi->text().find('\t') >= 0 ) // string contains tab + w += motifTabSpacing; + } + + if ( maxpmw ) { // we have iconsets + w += maxpmw; + w += 6; // add a little extra border around the iconset + } + + if ( checkable && maxpmw < windowsCheckMarkWidth ) { + w += windowsCheckMarkWidth - maxpmw; // space for the checkmarks + } + + if ( maxpmw > 0 || checkable ) // we have a check-column ( iconsets or checkmarks) + w += motifCheckMarkHMargin; // add space to separate the columns + + w += windowsRightBorder; // windows has a strange wide border on the right side + + return w; +} + +static int popupMenuItemHeight( bool /*checkable*/, QMenuItem* mi, const QFontMetrics& fm ) +{ + int h = 0; + if ( mi->isSeparator() ) // separator height + h = motifSepHeight; + else if ( mi->pixmap() ) // pixmap height + h = mi->pixmap()->height() + 2*motifItemFrame; + else // text height + h = fm.height() + 2*motifItemVMargin + 2*motifItemFrame - 1; + + if ( !mi->isSeparator() && mi->iconSet() != 0 ) { + h = QMAX( h, mi->iconSet()->pixmap( QIconSet::Small, QIconSet::Normal ).height() + 2*motifItemFrame ); + } + if ( mi->custom() ) + h = QMAX( h, mi->custom()->sizeHint().height() + 2*motifItemVMargin + 2*motifItemFrame ) - 1; + return h; +} + +void drawPopupMenuItem( QPainter* p, bool checkable, + int maxpmw, int tab, QMenuItem* mi, + const QPalette& pal, bool act, + bool enabled, + int x, int y, int w, int h) +{ + +} + +/*! \reimp */ +void QCompactStyle::drawControl( ControlElement element, QPainter *p, const QWidget *widget, const QRect &r, + const QColorGroup &g, SFlags flags, const QStyleOption& opt ) +{ + switch ( element ) { + case CE_PopupMenuItem: + { + if (! widget || opt.isDefault()) + break; + + const QPopupMenu *popupmenu = (const QPopupMenu *) widget; + QMenuItem *mi = opt.menuItem(); + if ( !mi ) + break; + + int tab = opt.tabWidth(); + int maxpmw = opt.maxIconWidth(); + bool dis = !(flags & Style_Enabled); + bool checkable = popupmenu->isCheckable(); + bool act = flags & Style_Active; + int x, y, w, h; + r.rect( &x, &y, &w, &h ); + + QColorGroup itemg = g; + + if ( checkable ) + maxpmw = QMAX( maxpmw, 8 ); // space for the checkmarks + + int checkcol = maxpmw; + + if ( mi && mi->isSeparator() ) { // draw separator + p->setPen( g.dark() ); + p->drawLine( x, y, x+w, y ); + p->setPen( g.light() ); + p->drawLine( x, y+1, x+w, y+1 ); + return; + } + + QBrush fill = act? g.brush( QColorGroup::Highlight ) : + g.brush( QColorGroup::Button ); + p->fillRect( x, y, w, h, fill); + + if ( !mi ) + return; + + if ( mi->isChecked() ) { + if ( act && !dis ) { + qDrawShadePanel( p, x, y, checkcol, h, + g, TRUE, 1, &g.brush( QColorGroup::Button ) ); + } else { + qDrawShadePanel( p, x, y, checkcol, h, + g, TRUE, 1, &g.brush( QColorGroup::Midlight ) ); + } + } else if ( !act ) { + p->fillRect(x, y, checkcol , h, + g.brush( QColorGroup::Button )); + } + + if ( mi->iconSet() ) { // draw iconset + QIconSet::Mode mode = dis ? QIconSet::Disabled : QIconSet::Normal; + if (act && !dis ) + mode = QIconSet::Active; + QPixmap pixmap; + if ( checkable && mi->isChecked() ) + pixmap = mi->iconSet()->pixmap( QIconSet::Small, mode, QIconSet::On ); + else + pixmap = mi->iconSet()->pixmap( QIconSet::Small, mode ); + int pixw = pixmap.width(); + int pixh = pixmap.height(); + if ( act && !dis ) { + if ( !mi->isChecked() ) + qDrawShadePanel( p, x, y, checkcol, h, g, FALSE, 1, &g.brush( QColorGroup::Button ) ); + } + QRect cr( x, y, checkcol, h ); + QRect pmr( 0, 0, pixw, pixh ); + pmr.moveCenter( cr.center() ); + p->setPen( itemg.text() ); + p->drawPixmap( pmr.topLeft(), pixmap ); + + QBrush fill = act? g.brush( QColorGroup::Highlight ) : + g.brush( QColorGroup::Button ); + p->fillRect( x+checkcol + 1, y, w - checkcol - 1, h, fill); + } else if ( checkable ) { // just "checking"... + int mw = checkcol + motifItemFrame; + int mh = h - 2*motifItemFrame; + if ( mi->isChecked() ) { + + SFlags cflags = Style_Default; + if (! dis) + cflags |= Style_Enabled; + if (act) + cflags |= Style_On; + + drawPrimitive( PE_CheckMark, p, QRect(x + motifItemFrame + 2, y + motifItemFrame, + mw, mh), itemg, cflags, opt ); + } + } + + p->setPen( act ? g.highlightedText() : g.buttonText() ); + + QColor discol; + if ( dis ) { + discol = itemg.text(); + p->setPen( discol ); + } + + int xm = motifItemFrame + checkcol + motifItemHMargin; + + if ( mi->custom() ) { + int m = motifItemVMargin; + p->save(); + if ( dis && !act ) { + p->setPen( g.light() ); + mi->custom()->paint( p, itemg, act, !dis, + x+xm+1, y+m+1, w-xm-tab+1, h-2*m ); + p->setPen( discol ); + } + mi->custom()->paint( p, itemg, act, !dis, + x+xm, y+m, w-xm-tab+1, h-2*m ); + p->restore(); + } + QString s = mi->text(); + if ( !s.isNull() ) { // draw text + int t = s.find( '\t' ); + int m = motifItemVMargin; + const int text_flags = AlignVCenter|ShowPrefix | DontClip | SingleLine; + if ( t >= 0 ) { // draw tab text + if ( dis && !act ) { + p->setPen( g.light() ); + p->drawText( x+w-tab-windowsRightBorder-motifItemHMargin-motifItemFrame+1, + y+m+1, tab, h-2*m, text_flags, s.mid( t+1 )); + p->setPen( discol ); + } + p->drawText( x+w-tab-windowsRightBorder-motifItemHMargin-motifItemFrame, + y+m, tab, h-2*m, text_flags, s.mid( t+1 ) ); + s = s.left( t ); + } + if ( dis && !act ) { + p->setPen( g.light() ); + p->drawText( x+xm+1, y+m+1, w-xm+1, h-2*m, text_flags, s, t ); + p->setPen( discol ); + } + p->drawText( x+xm, y+m, w-xm-tab+1, h-2*m, text_flags, s, t ); + } else if ( mi->pixmap() ) { // draw pixmap + QPixmap *pixmap = mi->pixmap(); + if ( pixmap->depth() == 1 ) + p->setBackgroundMode( OpaqueMode ); + p->drawPixmap( x+xm, y+motifItemFrame, *pixmap ); + if ( pixmap->depth() == 1 ) + p->setBackgroundMode( TransparentMode ); + } + if ( mi->popup() ) { // draw sub menu arrow + int dim = (h-2*motifItemFrame) / 2; + if ( act ) { + if ( !dis ) + discol = white; + QColorGroup g2( discol, g.highlight(), + white, white, + dis ? discol : white, + discol, white ); + drawPrimitive(PE_ArrowRight, p, QRect(x+w - motifArrowHMargin - motifItemFrame - dim, y + h / 2 - dim / 2, dim, dim), + g2, Style_Enabled); + } else { + drawPrimitive(PE_ArrowRight, p, QRect(x+w - motifArrowHMargin - motifItemFrame - dim, y + h / 2 - dim / 2, dim, dim), + g, !dis ? Style_Enabled : Style_Default); + } + } + } + break; + + default: + QWindowsStyle::drawControl( element, p, widget, r, g, flags, opt ); + break; + } +} + +#endif diff --git a/src/styles/qcompactstyle.h b/src/styles/qcompactstyle.h new file mode 100644 index 0000000..ea27cb4 --- /dev/null +++ b/src/styles/qcompactstyle.h @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Definition of compact style class, good for small displays +** +** Created : 000623 +** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the widgets module of the Qt GUI Toolkit. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** This file may be used under the terms of the Q Public License as +** defined by Trolltech ASA and appearing in the file LICENSE.QPL +** included in the packaging of this file. Licensees holding valid Qt +** Commercial licenses may use this file in accordance with the Qt +** Commercial License Agreement provided with the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef QCOMPACTSTYLE_H +#define QCOMPACTSTYLE_H + +#ifndef QT_H +#include "qwindowsstyle.h" +#endif // QT_H + +#if !defined(QT_NO_STYLE_COMPACT) || defined(QT_PLUGIN) + +#if defined(QT_PLUGIN) +#define Q_EXPORT_STYLE_COMPACT +#else +#define Q_EXPORT_STYLE_COMPACT Q_EXPORT +#endif + +class Q_EXPORT_STYLE_COMPACT QCompactStyle : public QWindowsStyle +{ +public: + QCompactStyle(); + + int pixelMetric( PixelMetric metric, const QWidget *widget = 0 ); + + void drawControl( ControlElement element, QPainter *p, const QWidget *w, const QRect &r, + const QColorGroup &cg, SFlags how = Style_Default, const QStyleOption& = QStyleOption::Default ); + +private: // Disabled copy constructor and operator= +#if defined(Q_DISABLE_COPY) + QCompactStyle( const QCompactStyle & ); + QCompactStyle& operator=( const QCompactStyle & ); +#endif +}; + +#endif // QT_NO_STYLE_WINDOWS + +#endif // QCOMPACTSTYLE_H diff --git a/src/styles/qinterlacestyle.cpp b/src/styles/qinterlacestyle.cpp new file mode 100644 index 0000000..d95d1b4 --- /dev/null +++ b/src/styles/qinterlacestyle.cpp @@ -0,0 +1,805 @@ +/**************************************************************************** +** +** Implementation of QInterlaceStyle class +** +** Created : 010122 +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the widgets module of the Qt GUI Toolkit. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** This file may be used under the terms of the Q Public License as +** defined by Trolltech ASA and appearing in the file LICENSE.QPL +** included in the packaging of this file. Licensees holding valid Qt +** Commercial licenses may use this file in accordance with the Qt +** Commercial License Agreement provided with the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#if 0 // ###### not ported to new API yet + +#include "qinterlacestyle.h" + +#if !defined(QT_NO_STYLE_INTERLACE) || defined(QT_PLUGIN) + +#include "qapplication.h" +#include "qpainter.h" +#include "qdrawutil.h" // for now +#include "qpalette.h" // for now +#include "qwidget.h" +#include "qlabel.h" +#include "qpushbutton.h" +#include "qwidget.h" +#include "qrangecontrol.h" +#include "qscrollbar.h" +#include "qlistbox.h" + +#include + +/*! + \class QInterlaceStyle qinterlacestyle.h + \brief The QInterlaceStyle class provides a Look and Feel suitable for interlaced displays. + \ingroup appearance + + This class implements a look and feel that reduces flicker as much as + possible on interlaced displays (i.e. television). It is an experimental + style. In addition to using this style you will need to select a font + that does not flicker. +*/ + +/*! + Constructs a QInterlaceStyle +*/ +QInterlaceStyle::QInterlaceStyle() : QMotifStyle() +{ + setUseHighlightColors( TRUE ); +} + +/*! \reimp +*/ +int QInterlaceStyle::buttonDefaultIndicatorWidth() const +{ + return 0; +} + +/*! \reimp +*/ +int QInterlaceStyle::setSliderThickness() const +{ + return 18; +} + +/*! \reimp +*/ +QSize QInterlaceStyle::scrollBarExtent() const +{ + return QSize( 18, 18 ); +} + +/*! \reimp +*/ +int QInterlaceStyle::defaultFrameWidth() const +{ + return 2; +} + +/*! + \reimp + */ +void QInterlaceStyle::polish( QApplication *app) +{ + oldPalette = app->palette(); +#if 0 + QColor bg( 128, 64, 128 ); + QColor btn( 255, 145, 0 ); + QColor mid = bg.dark( 120 ); + QColor low = mid.dark( 120 ); + QColor fg( white ); +#else + QColor bg( 224, 224, 224 ); + QColor btn = bg.dark( 105 ); + QColor mid = bg.dark( 120 ); + QColor low = mid.dark( 120 ); + QColor fg( black ); +#endif + + QColorGroup cg( fg, btn, low, low, mid, black, black, white, bg ); + cg.setColor( QColorGroup::Highlight, QColor( 255, 255, 192 ) ); + cg.setColor( QColorGroup::HighlightedText, black ); + + QColorGroup dcg( cg ); + dcg.setColor( QColorGroup::ButtonText, low ); + dcg.setColor( QColorGroup::Text, low ); + + app->setPalette( QPalette( cg, dcg, cg ), TRUE ); +} + +/*! + \reimp + */ +void QInterlaceStyle::unPolish( QApplication *app) +{ + app->setPalette(oldPalette, TRUE); +} + +/*! + \reimp + */ +void QInterlaceStyle::polish( QWidget* w) +{ + + // the polish function sets some widgets to transparent mode and + // some to translate background mode in order to get the full + // benefit from the nice pixmaps in the color group. + + if ( w->inherits("QLCDNumber") ){ + return; + } + + if ( !w->isTopLevel() ) { + if ( w->inherits("QGroupBox") + || w->inherits("QTabWidget") + || w->inherits("QPushButton") ) { + w->setAutoMask( TRUE ); + return; + } + if (w->inherits("QLabel") + || w->inherits("QSlider") + || w->inherits("QButton") + || w->inherits("QProgressBar") + ){ + w->setBackgroundOrigin( QWidget::ParentOrigin ); + } + } + + if ( w->inherits( "QFrame" ) ) { + QFrame *f = (QFrame *)w; + switch ( f->frameShape() ) { + case QFrame::WinPanel: + f->setFrameShape( QFrame::StyledPanel ); + + case QFrame::Panel: + case QFrame::Box: + case QFrame::StyledPanel: + case QFrame::PopupPanel: + if ( f->frameWidth() == 1 ) + f->setLineWidth( 2 ); + break; + default: + break; + } + } + + if ( w->inherits( "QListBox" ) ) { + // the list box in combos has an ugly border otherwise + QFrame *f = (QFrame *)w; + if ( f->frameShadow() == QFrame::Plain ) { + f->setFrameShadow( QFrame::Raised ); + f->setLineWidth( 1 ); + } + } +} + +/*! + \reimp +*/ +void QInterlaceStyle::unPolish( QWidget* w) +{ + + // the polish function sets some widgets to transparent mode and + // some to translate background mode in order to get the full + // benefit from the nice pixmaps in the color group. + + if ( w->inherits("QLCDNumber") ){ + return; + } + + if ( !w->isTopLevel() ) { + if ( w->inherits("QGroupBox") + || w->inherits("QTabWidget") + || w->inherits("QPushButton" ) ) { + w->setAutoMask( FALSE ); + return; + } + if (w->inherits("QLabel") + || w->inherits("QSlider") + || w->inherits("QButton") + || w->inherits("QProgressBar") + ){ + w->setBackgroundOrigin( QWidget::WidgetOrigin ); + } + } + +} + +/*! + \reimp +*/ +QRect QInterlaceStyle::pushButtonContentsRect( QPushButton *btn ) +{ + int fw = 0; + if ( btn->isDefault() || btn->autoDefault() ) + fw = buttonDefaultIndicatorWidth(); + + return buttonRect( fw+5, fw, btn->width()-2*fw-10, btn->height()-2*fw ); +} + +/*! + \reimp +*/ +void QInterlaceStyle::drawFocusRect ( QPainter *p, const QRect &/*r*/, const QColorGroup &g, const QColor * bg, bool /*atBorder*/ ) +{ + if (bg ) { + int h,s,v; + bg->hsv(&h,&s,&v); + if (v >= 128) + p->setPen( Qt::black ); + else + p->setPen( Qt::white ); + } + else + p->setPen( g.foreground() ); +/* + p->setBrush( NoBrush ); + if ( atBorder ) { + p->drawRect( QRect( r.x()+1, r.y()+2, r.width()-2, r.height()-4 ) ); + p->drawRect( QRect( r.x()+2, r.y()+1, r.width()-4, r.height()-2 ) ); + } else { + p->drawRect( QRect( r.x(), r.y()+1, r.width(), r.height()-2 ) ); + p->drawRect( QRect( r.x()+1, r.y(), r.width()-2, r.height() ) ); + } +*/ +} + +/*! + \reimp +*/ +void QInterlaceStyle::drawButton( QPainter *p, int x, int y, int w, int h, + const QColorGroup &g, bool /* sunken */, + const QBrush *fill ) +{ + const int lineWidth = 2; + + p->setBrush( g.brush( QColorGroup::Dark ) ); + p->setPen( NoPen ); + p->drawRect( x+1, y+1, 2, 2 ); + p->drawRect( x+w-3, y+1, 2, 2 ); + p->drawRect( x+1, y+h-3, 2, 2 ); + p->drawRect( x+w-3, y+h-3, 2, 2 ); + + p->drawRect( x+2, y, w-4, 2 ); + p->drawRect( x+2, y+h-lineWidth, w-4, lineWidth ); + p->drawRect( x, y+2, lineWidth, h-4 ); + p->drawRect( x+w-lineWidth, y+2, lineWidth, h-4 ); + + if ( fill ) { + x += 2; + y += 2; + w -= 4; + h -= 4; + p->setBrush( *fill ); + p->setPen( NoPen ); + p->drawRect( x+1, y, w-2, 1 ); + p->drawRect( x, y+1, w, h-2 ); + p->drawRect( x+1, y+h-1, w-2, 1 ); + } +} + +/*! \reimp */ +void QInterlaceStyle::drawButtonMask( QPainter * p, int x, int y, int w, int h ) +{ + QBrush fill( color1 ); + QColorGroup cg; + cg.setBrush( QColorGroup::Dark, color1 ); + drawButton( p, x, y, w, h, cg, FALSE, &fill ); +} + +/*! + \reimp +*/ +void QInterlaceStyle::drawBevelButton( QPainter *p, int x, int y, int w, int h, + const QColorGroup &g, bool sunken, const QBrush* fill ) +{ + QInterlaceStyle::drawButton(p, x, y, w, h, g, sunken, fill); +} + +/*! + \reimp +*/ +void QInterlaceStyle::drawPushButton( QPushButton* btn, QPainter *p) +{ + QColorGroup g = btn->colorGroup(); + int x1, y1, x2, y2; + + btn->rect().coords( &x1, &y1, &x2, &y2 ); // get coordinates + + QBrush fill( g.button() ); + if ( btn->isDown() || btn->isOn() ) + fill = g.mid(); + + if ( btn->hasFocus() ) + g.setBrush( QColorGroup::Dark, black ); + drawButton( p, x1, y1, x2-x1+1, y2-y1+1, g, FALSE, &fill ); + + if ( btn->isMenuButton() ) { + int dx = (y1-y2-4)/3; + drawArrow( p, DownArrow, FALSE, + x2 - dx, dx, y1, y2 - y1, + g, btn->isEnabled() ); + } + + if ( p->brush().style() != NoBrush ) + p->setBrush( NoBrush ); +} + +/*! + \reimp +*/ +QSize QInterlaceStyle::indicatorSize () const +{ + return QSize(13,13); +} + +/*! + \reimp +*/ +void QInterlaceStyle::drawIndicator( QPainter * p, int x, int y, int w, int h, const QColorGroup &g, int s, bool down, bool enabled ) +{ + p->fillRect( x, y, w, h, g.brush( QColorGroup::Background ) ); + QBrush fill; + if ( s == QButton::NoChange ) { + QBrush b = p->brush(); + QColor c = p->backgroundColor(); + p->setBackgroundMode( TransparentMode ); + p->setBackgroundColor( green ); + fill = QBrush(g.base(), Dense4Pattern); + p->setBackgroundColor( c ); + p->setBrush( b ); + } else if ( down ) + fill = g.brush( QColorGroup::Button ); + else + fill = g.brush( enabled ? QColorGroup::Base : QColorGroup::Background ); + + drawButton( p, x, y, w, h, g, FALSE, &fill ); + + if ( s != QButton::Off ) { + QPointArray a( 7*2 ); + int i, xx, yy; + xx = x+3; + yy = y+5; + for ( i=0; i<3; i++ ) { + a.setPoint( 2*i, xx, yy ); + a.setPoint( 2*i+1, xx, yy+2 ); + xx++; yy++; + } + yy -= 2; + for ( i=3; i<7; i++ ) { + a.setPoint( 2*i, xx, yy ); + a.setPoint( 2*i+1, xx, yy+2 ); + xx++; yy--; + } + if ( s == QButton::NoChange ) { + p->setPen( g.dark() ); + } else { + p->setPen( g.text() ); + } + p->drawLineSegments( a ); + } +} + +/*! + \reimp +*/ +void QInterlaceStyle::drawIndicatorMask( QPainter *p, int x, int y, int w, int h, int ) +{ + drawButtonMask( p, x, y, w, h ); +} + +/*! + \reimp +*/ +QSize QInterlaceStyle::exclusiveIndicatorSize() const +{ + return QSize(13,13); +} + +/*! + \reimp +*/ +void QInterlaceStyle::drawExclusiveIndicator( QPainter *p, int x, int y, int w, int h, const QColorGroup &g, bool on, bool down, bool enabled ) +{ + p->fillRect( x, y, w, h, g.brush( QColorGroup::Background ) ); + p->setBrush( g.dark() ); + p->setPen( QPen( NoPen ) ); + p->drawEllipse( x, y, w, h ); + + x += 2; + y += 2; + w -= 4; + h -= 4; + QColor fillColor = ( down || !enabled ) ? g.button() : g.base(); + p->setBrush( fillColor ); + p->drawEllipse( x, y, w, h ); + + if ( on ) { + p->setBrush( g.text() ); + p->drawEllipse( x+2, y+2, w-4, h-4 ); + } +} + +/*! + \reimp +*/ +void QInterlaceStyle::drawExclusiveIndicatorMask( QPainter *p, int x, int y, int w, int h, bool ) +{ + p->setBrush( color1 ); + p->setPen( QPen( NoPen ) ); + p->drawEllipse( x, y, w, h ); +} + +static int get_combo_extra_width( int h, int *return_awh=0 ) +{ + int awh; + if ( h < 8 ) { + awh = 6; + } else if ( h < 14 ) { + awh = h - 2; + } else { + awh = h/2; + } + if ( return_awh ) + *return_awh = awh; + return awh*3/2; +} + +/*! + \reimp +*/ +QRect QInterlaceStyle::comboButtonRect ( int x, int y, int w, int h ) +{ + QRect r = buttonRect( x, y, w, h ); + int ew = get_combo_extra_width( r.height() ); + return QRect(r.x(), r.y(), r.width()-ew, r.height()); +} + +static void get_combo_parameters( const QRect &r, + int &ew, int &awh, int &ax, + int &ay, int &sh, int &dh, + int &sy ) +{ + ew = get_combo_extra_width( r.height(), &awh ); + + sh = (awh+3)/4; + if ( sh < 3 ) + sh = 3; + dh = sh/2 + 1; + + ay = r.y() + (r.height()-awh-sh-dh)/2; + if ( ay < 0 ) { + //panic mode + ay = 0; + sy = r.height(); + } else { + sy = ay+awh+dh; + } + ax = r.x() + r.width() - ew +(ew-awh)/2; +} + +/*! + \reimp +*/ +void QInterlaceStyle::drawComboButton( QPainter *p, int x, int y, int w, int h, + const QColorGroup &g, + bool /* sunken */, + bool /*editable*/, + bool /*enabled */, + const QBrush *fb ) +{ + QBrush fill = fb ? *fb : g.brush( QColorGroup::Button ); + + int awh, ax, ay, sh, sy, dh, ew; + get_combo_parameters( buttonRect(x,y,w,h), ew, awh, ax, ay, sh, dh, sy ); + + drawButton( p, x, y, w, h, g, FALSE, &fill ); + + qDrawArrow( p, DownArrow, MotifStyle, FALSE, ax, ay, awh, awh, g, TRUE ); + + p->setPen( g.dark() ); + p->drawRect( ax+1, sy+1, awh-1, sh-1 ); +} + +/*! + \reimp +*/ +void QInterlaceStyle::drawPushButtonLabel( QPushButton* btn, QPainter *p) +{ + QRect r = btn->rect(); + int x, y, w, h; + r.rect( &x, &y, &w, &h ); + + int x1, y1, x2, y2; + btn->rect().coords( &x1, &y1, &x2, &y2 ); // get coordinates + int dx = 0; + int dy = 0; + if ( btn->isMenuButton() ) + dx = (y2-y1) / 3; + if ( btn->isOn() || btn->isDown() ) { +// dx--; +// dy--; + } + if ( dx || dy ) + p->translate( dx, dy ); + + x += 2; y += 2; w -= 4; h -= 4; + QColorGroup g = btn->colorGroup(); + const QColor *col = &btn->colorGroup().buttonText(); + if ( (btn->isDown() || btn->isOn()) ) + col = &btn->colorGroup().brightText(); + else if ( !btn->isEnabled() ) + col = &btn->colorGroup().dark(); + drawItem( p, x, y, w, h, + AlignCenter|ShowPrefix, + g, btn->isEnabled(), + btn->pixmap(), btn->text(), -1, col ); + + if ( dx || dy ) + p->translate( -dx, -dy ); +} + +#define HORIZONTAL (sb->orientation() == QScrollBar::Horizontal) +#define VERTICAL !HORIZONTAL +#define MOTIF_BORDER defaultFrameWidth() +#define SLIDER_MIN 9 // ### motif says 6 but that's too small + + +/*! \reimp */ + +void QInterlaceStyle::scrollBarMetrics( const QScrollBar* sb, int &sliderMin, int &sliderMax, int &sliderLength, int &buttonDim ) +{ + int maxLength; + int b = MOTIF_BORDER; + int length = HORIZONTAL ? sb->width() : sb->height(); + int extent = HORIZONTAL ? sb->height() : sb->width(); + + if ( length > ( extent - b*2 - 1 )*2 + b*2 ) + buttonDim = extent - b*2; + else + buttonDim = ( length - b*2 )/2 - 1; + + sliderMin = b + buttonDim; + maxLength = length - b*2 - buttonDim*2; + + if ( sb->maxValue() == sb->minValue() ) { + sliderLength = maxLength; + } else { + uint range = sb->maxValue()-sb->minValue(); + sliderLength = (sb->pageStep()*maxLength)/ + (range + sb->pageStep()); + if ( sliderLength < SLIDER_MIN || range > INT_MAX/2 ) + sliderLength = SLIDER_MIN; + if ( sliderLength > maxLength ) + sliderLength = maxLength; + } + sliderMax = sliderMin + maxLength - sliderLength; + +} + + +/*! \reimp */ + +void QInterlaceStyle::drawScrollBarControls( QPainter* p, const QScrollBar* sb, + int sliderStart, uint controls, + uint activeControl ) +{ +#define ADD_LINE_ACTIVE ( activeControl == AddLine ) +#define SUB_LINE_ACTIVE ( activeControl == SubLine ) + QColorGroup g = sb->colorGroup(); + + int sliderMin, sliderMax, sliderLength, buttonDim; + scrollBarMetrics( sb, sliderMin, sliderMax, sliderLength, buttonDim ); + + QBrush fill = g.brush( QColorGroup::Mid ); + if (sb->backgroundPixmap() ){ + fill = QBrush( g.mid(), *sb->backgroundPixmap() ); + } + + if ( controls == (AddLine | SubLine | AddPage | SubPage | Slider | First | Last ) ) + drawPanel( p, 0, 0, sb->width(), sb->height(), g, FALSE, 2, &fill ); + + if (sliderStart > sliderMax) { // sanity check + sliderStart = sliderMax; + } + + int b = MOTIF_BORDER; + int dimB = buttonDim; + QRect addB; + QRect subB; + QRect addPageR; + QRect subPageR; + QRect sliderR; + int addX, addY, subX, subY; + int length = HORIZONTAL ? sb->width() : sb->height(); + int extent = HORIZONTAL ? sb->height() : sb->width(); + + if ( HORIZONTAL ) { + subY = addY = ( extent - dimB ) / 2; + subX = b; + addX = length - dimB - b; + } else { + subX = addX = ( extent - dimB ) / 2; + subY = b; + addY = length - dimB - b; + } + + subB.setRect( subX,subY,dimB,dimB ); + addB.setRect( addX,addY,dimB,dimB ); + + int sliderEnd = sliderStart + sliderLength; + int sliderW = extent - b*2; + if ( HORIZONTAL ) { + subPageR.setRect( subB.right() + 1, b, + sliderStart - subB.right() , sliderW ); + addPageR.setRect( sliderEnd-1, b, addX - sliderEnd+1, sliderW ); + sliderR .setRect( sliderStart, b, sliderLength, sliderW ); + } else { + subPageR.setRect( b, subB.bottom()+1, sliderW, + sliderStart - subB.bottom() ); + addPageR.setRect( b, sliderEnd-1, sliderW, addY - sliderEnd + 1); + sliderR .setRect( b, sliderStart, sliderW, sliderLength ); + } + + if ( controls & AddLine ) + drawArrow( p, VERTICAL ? DownArrow : RightArrow, + ADD_LINE_ACTIVE, addB.x(), addB.y(), + addB.width(), addB.height(), g, TRUE ); + if ( controls & SubLine ) + drawArrow( p, VERTICAL ? UpArrow : LeftArrow, + SUB_LINE_ACTIVE, subB.x(), subB.y(), + subB.width(), subB.height(), g, TRUE ); + + if ( controls & SubPage ) + p->fillRect( subPageR, fill ); + + if ( controls & AddPage ) + p->fillRect( addPageR, fill ); + + if ( controls & Slider ) { + QPoint bo = p->brushOrigin(); + p->setBrushOrigin(sliderR.topLeft()); + if ( sliderR.isValid() ) + drawButton( p, sliderR.x(), sliderR.y(), + sliderR.width(), sliderR.height(), g, + FALSE, &g.brush( QColorGroup::Button ) ); + p->setBrushOrigin(bo); + } + +} + +/*! + \reimp +*/ +void QInterlaceStyle::drawSlider ( QPainter * p, int x, int y, int w, int h, const QColorGroup & g, Orientation orient, bool, bool) +{ + p->fillRect( x, y, w, h, g.brush( QColorGroup::Background ) ); + drawButton( p, x, y, w, h, g, FALSE, &g.brush( QColorGroup::Button ) ); + if ( orient == Horizontal ) { + QCOORD mid = x + w / 2; + qDrawShadeLine( p, mid, y , mid, y + h - 2, g, TRUE, 1); + } else { + QCOORD mid = y +h / 2; + qDrawShadeLine( p, x, mid, x + w - 2, mid, g, TRUE, 1); + } +} + + +/*! + \reimp +*/ +void QInterlaceStyle::drawSliderGroove ( QPainter * p, int x, int y, int w, int h, const QColorGroup & g, QCOORD , Orientation o) +{ + p->setBrush( g.brush( QColorGroup::Dark ) ); + p->setPen( NoPen ); + + if ( o == Horizontal ) + drawButton( p, x, y+h/2-3, w, 6, g, FALSE, &g.brush( QColorGroup::Mid ) ); + else + drawButton( p, x+w/2-3, y, 6, h, g, FALSE, &g.brush( QColorGroup::Mid ) ); +} + + +/*! + \reimp +*/ +int QInterlaceStyle::splitterWidth() const +{ + return QMAX( 12, QApplication::globalStrut().width() ); +} + +/*! + \reimp +*/ +void QInterlaceStyle::drawSplitter( QPainter *p, int x, int y, int w, int h, + const QColorGroup &g, Orientation orient) +{ + const int motifOffset = 12; + int sw = splitterWidth(); + if ( orient == Horizontal ) { + QCOORD xPos = x + w/2; + QCOORD kPos = motifOffset; + QCOORD kSize = sw - 4; + + qDrawShadeLine( p, xPos, kPos + kSize - 1 , + xPos, h, g ); + drawPanel( p, xPos-sw/2+2, kPos, + kSize, kSize, g, FALSE, 2, + &g.brush( QColorGroup::Button )); + qDrawShadeLine( p, xPos, 0, xPos, kPos, g ); + } else { + QCOORD yPos = y + h/2; + QCOORD kPos = w - motifOffset - sw; + QCOORD kSize = sw - 4; + + qDrawShadeLine( p, 0, yPos, kPos, yPos, g ); + drawPanel( p, kPos, yPos-sw/2+2, + kSize, kSize, g, FALSE, 2, + &g.brush( QColorGroup::Button )); + qDrawShadeLine( p, kPos + kSize -1, yPos, + w, yPos, g ); + } + +} + +/*! + \reimp +*/ +void QInterlaceStyle::drawPanel( QPainter *p, int x, int y, int w, int h, + const QColorGroup &g, bool /*sunken*/, + int lineWidth, const QBrush *fill ) +{ + if ( lineWidth < 2 ) + lineWidth = 2; + + p->setBrush( g.brush( QColorGroup::Dark ) ); + p->setPen( NoPen ); + + p->drawRect( x, y, w, lineWidth ); + p->drawRect( x, y+h-lineWidth, w, lineWidth ); + p->drawRect( x, y, lineWidth, h ); + p->drawRect( x+w-lineWidth, y, lineWidth, h ); + + if ( fill ) { + x += lineWidth; + y += lineWidth; + w -= 2*lineWidth; + h -= 2*lineWidth; + p->setBrush( *fill ); + p->setPen( NoPen ); + p->drawRect( x, y, w, h ); + } +} + +#endif // QT_NO_STYLE_INTERLACE + +#endif diff --git a/src/styles/qinterlacestyle.h b/src/styles/qinterlacestyle.h new file mode 100644 index 0000000..c139281 --- /dev/null +++ b/src/styles/qinterlacestyle.h @@ -0,0 +1,107 @@ +/**************************************************************************** +** +** Implementation of QInterlaceStyle widget class +** +** Created : 010122 +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the widgets module of the Qt GUI Toolkit. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** This file may be used under the terms of the Q Public License as +** defined by Trolltech ASA and appearing in the file LICENSE.QPL +** included in the packaging of this file. Licensees holding valid Qt +** Commercial licenses may use this file in accordance with the Qt +** Commercial License Agreement provided with the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#if 0 // ###### not ported to new API yet +#ifndef QINTERLACESTYLE_H +#define QINTERLACESTYLE_H + +#ifndef QT_H +#include "qmotifstyle.h" +#endif // QT_H + +#if !defined(QT_NO_STYLE_INTERLACE) || defined(QT_PLUGIN) + +#include "qpalette.h" + +class Q_EXPORT QInterlaceStyle : public QMotifStyle +{ +public: + QInterlaceStyle(); + void polish( QApplication*); + void unPolish( QApplication*); + void polish( QWidget* ); + void unPolish( QWidget* ); + + int defaultFrameWidth() const; + QRect pushButtonContentsRect( QPushButton *btn ); + + void drawFocusRect ( QPainter *, const QRect &, const QColorGroup &, const QColor * bg = 0, bool = FALSE ); + void drawButton( QPainter *p, int x, int y, int w, int h, + const QColorGroup &g, bool sunken = FALSE, + const QBrush *fill = 0 ); + void drawButtonMask ( QPainter * p, int x, int y, int w, int h ); + void drawBevelButton( QPainter *p, int x, int y, int w, int h, + const QColorGroup &g, bool sunken = FALSE, + const QBrush *fill = 0 ); + + void drawPushButton( QPushButton* btn, QPainter *p); + QSize indicatorSize () const; + void drawIndicator ( QPainter * p, int x, int y, int w, int h, const QColorGroup & g, int state, bool down = FALSE, bool enabled = TRUE ); + void drawIndicatorMask( QPainter *p, int x, int y, int w, int h, int ); + QSize exclusiveIndicatorSize () const; + void drawExclusiveIndicator( QPainter * p, int x, int y, int w, int h, const QColorGroup & g, bool on, bool down = FALSE, bool enabled = TRUE ); + void drawExclusiveIndicatorMask( QPainter * p, int x, int y, int w, int h, bool ); + QRect comboButtonRect ( int x, int y, int w, int h ); + void drawComboButton( QPainter *p, int x, int y, int w, int h, const QColorGroup &g, bool sunken, bool editable, bool enabled, const QBrush *fb ); + void drawPushButtonLabel( QPushButton* btn, QPainter *p); + void drawPanel( QPainter *p, int x, int y, int w, int h, + const QColorGroup &, bool sunken, + int lineWidth, const QBrush *fill ); + + void scrollBarMetrics( const QScrollBar* sb, int &sliderMin, int &sliderMax, int &sliderLength, int &buttonDim ); + void drawScrollBarControls( QPainter* p, const QScrollBar* sb, int sliderStart, uint controls, uint activeControl ); + void drawSlider( QPainter * p, int x, int y, int w, int h, const QColorGroup & g, Orientation, bool tickAbove, bool tickBelow ); + void drawSliderGroove( QPainter * p, int x, int y, int w, int h, const QColorGroup & g, QCOORD c, Orientation ); + int splitterWidth() const; + void drawSplitter( QPainter *p, int x, int y, int w, int h, + const QColorGroup &g, Orientation orient); + + int buttonDefaultIndicatorWidth() const; + int setSliderThickness() const; + QSize scrollBarExtent() const; + +private: + QPalette oldPalette; +}; + +#endif // QT_NO_STYLE_INTERLACE + +#endif +#endif diff --git a/src/styles/qmotifplusstyle.cpp b/src/styles/qmotifplusstyle.cpp new file mode 100644 index 0000000..6cf56f3 --- /dev/null +++ b/src/styles/qmotifplusstyle.cpp @@ -0,0 +1,1584 @@ +/**************************************************************************** +** +** Implementation of QMotifPlusStyle class +** +** Created : 000727 +** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the widgets module of the Qt GUI Toolkit. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** This file may be used under the terms of the Q Public License as +** defined by Trolltech ASA and appearing in the file LICENSE.QPL +** included in the packaging of this file. Licensees holding valid Qt +** Commercial licenses may use this file in accordance with the Qt +** Commercial License Agreement provided with the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "qmotifplusstyle.h" + +#if !defined(QT_NO_STYLE_MOTIFPLUS) || defined(QT_PLUGIN) + +#include "qmenubar.h" +#include "qapplication.h" +#include "qpainter.h" +#include "qpalette.h" +#include "qframe.h" +#include "qpushbutton.h" +#include "qcheckbox.h" +#include "qradiobutton.h" +#include "qcombobox.h" +#include "qlineedit.h" +#include "qspinbox.h" +#include "qslider.h" +#include "qdrawutil.h" +#include "qscrollbar.h" +#include "qtabbar.h" +#include "qtoolbar.h" +#include "qguardedptr.h" +#include "qlayout.h" + + +struct QMotifPlusStylePrivate +{ + QMotifPlusStylePrivate() + : hoverWidget(0), hovering(FALSE), sliderActive(FALSE), mousePressed(FALSE), + scrollbarElement(0), lastElement(0), ref(1) + { ; } + + QGuardedPtr hoverWidget; + bool hovering, sliderActive, mousePressed; + int scrollbarElement, lastElement, ref; + QPoint mousePos; +}; + +static QMotifPlusStylePrivate * singleton = 0; + + +static void drawMotifPlusShade(QPainter *p, + const QRect &r, + const QColorGroup &g, + bool sunken, bool mouseover, + const QBrush *fill = 0) +{ + QPen oldpen = p->pen(); + QPointArray a(4); + QColor button = + mouseover ? g.midlight() : g.button(); + QBrush brush = + mouseover ? g.brush(QColorGroup::Midlight) : g.brush(QColorGroup::Button); + int x, y, w, h; + + r.rect(&x, &y, &w, &h); + + if (sunken) p->setPen(g.dark()); else p->setPen(g.light()); + a.setPoint(0, x, y + h - 1); + a.setPoint(1, x, y); + a.setPoint(2, x, y); + a.setPoint(3, x + w - 1, y); + p->drawLineSegments(a); + + if (sunken) p->setPen(Qt::black); else p->setPen(button); + a.setPoint(0, x + 1, y + h - 2); + a.setPoint(1, x + 1, y + 1); + a.setPoint(2, x + 1, y + 1); + a.setPoint(3, x + w - 2, y + 1); + p->drawLineSegments(a); + + if (sunken) p->setPen(button); else p->setPen(g.dark()); + a.setPoint(0, x + 2, y + h - 2); + a.setPoint(1, x + w - 2, y + h - 2); + a.setPoint(2, x + w - 2, y + h - 2); + a.setPoint(3, x + w - 2, y + 2); + p->drawLineSegments(a); + + if (sunken) p->setPen(g.light()); else p->setPen(Qt::black); + a.setPoint(0, x + 1, y + h - 1); + a.setPoint(1, x + w - 1, y + h - 1); + a.setPoint(2, x + w - 1, y + h - 1); + a.setPoint(3, x + w - 1, y); + p->drawLineSegments(a); + + if (fill) + p->fillRect(x + 2, y + 2, w - 4, h - 4, *fill); + else + p->fillRect(x + 2, y + 2, w - 4, h - 4, brush); + + p->setPen(oldpen); +} + + +/*! + \class QMotifPlusStyle qmotifplusstyle.h + \brief The QMotifPlusStyle class provides a more sophisticated Motif-ish look and feel. + + \ingroup appearance + + This class implements a Motif-ish look and feel with the more + sophisticated bevelling as used by the GIMP Toolkit (GTK+) for + Unix/X11. +*/ + +/*! + Constructs a QMotifPlusStyle + + If \a hoveringHighlight is TRUE (the default), then the style will + not highlight push buttons, checkboxes, radiobuttons, comboboxes, + scrollbars or sliders. +*/ +QMotifPlusStyle::QMotifPlusStyle(bool hoveringHighlight) : QMotifStyle(TRUE) +{ + if ( !singleton ) + singleton = new QMotifPlusStylePrivate; + else + singleton->ref++; + + useHoveringHighlight = hoveringHighlight; +} + +/*! \reimp */ +QMotifPlusStyle::~QMotifPlusStyle() +{ + if ( singleton && singleton->ref-- <= 0) { + delete singleton; + singleton = 0; + } +} + + +/*! \reimp */ +void QMotifPlusStyle::polish(QPalette &) +{ +} + + +/*! \reimp */ +void QMotifPlusStyle::polish(QWidget *widget) +{ +#ifndef QT_NO_FRAME + if (::qt_cast(widget) && ((QFrame *) widget)->frameStyle() == QFrame::Panel) + ((QFrame *) widget)->setFrameStyle(QFrame::WinPanel); +#endif + +#ifndef QT_NO_MENUBAR + if (::qt_cast(widget) && ((QMenuBar *) widget)->frameStyle() != QFrame::NoFrame) + ((QMenuBar *) widget)->setFrameStyle(QFrame::StyledPanel | QFrame::Raised); +#endif + +#ifndef QT_NO_TOOLBAR + if (::qt_cast(widget)) + widget->layout()->setMargin(2); +#endif + if (useHoveringHighlight) { + if (::qt_cast(widget) || ::qt_cast(widget)) + widget->installEventFilter(this); + + if (::qt_cast(widget) || ::qt_cast(widget)) { + widget->setMouseTracking(TRUE); + widget->installEventFilter(this); + } + } + + QMotifStyle::polish(widget); +} + + +/*! \reimp */ +void QMotifPlusStyle::unPolish(QWidget *widget) +{ + widget->removeEventFilter(this); + QMotifStyle::unPolish(widget); +} + + +/*! \reimp */ +void QMotifPlusStyle::polish(QApplication *) +{ +} + + +/*! \reimp */ +void QMotifPlusStyle::unPolish(QApplication *) +{ +} + + +/*! \reimp */ +int QMotifPlusStyle::pixelMetric(PixelMetric metric, const QWidget *widget) const +{ + int ret; + + switch (metric) { + case PM_ScrollBarExtent: + ret = 15; + break; + + case PM_ButtonDefaultIndicator: + ret = 5; + break; + + case PM_ButtonMargin: + ret = 4; + break; + + case PM_SliderThickness: + ret = 15; + break; + + case PM_IndicatorWidth: + case PM_IndicatorHeight: + ret = 10; + break; + + case PM_ExclusiveIndicatorWidth: + case PM_ExclusiveIndicatorHeight: + ret = 11; + break; + + default: + ret = QMotifStyle::pixelMetric(metric, widget); + break; + } + + return ret; +} + + +/*! \reimp */ +void QMotifPlusStyle::drawPrimitive( PrimitiveElement pe, + QPainter *p, + const QRect &r, + const QColorGroup &cg, + SFlags flags, + const QStyleOption& opt ) const +{ + switch (pe) { + case PE_HeaderSection: + + case PE_ButtonCommand: + case PE_ButtonBevel: + case PE_ButtonTool: + if (flags & (Style_Down | Style_On | Style_Raised | Style_Sunken)) + drawMotifPlusShade( p, r, cg, bool(flags & (Style_Down | Style_On)), + bool(flags & Style_MouseOver)); + else if (flags & Style_MouseOver) + p->fillRect(r, cg.brush(QColorGroup::Midlight)); + else + p->fillRect(r, cg.brush(QColorGroup::Button)); + break; + + case PE_Panel: + case PE_PanelPopup: + case PE_PanelMenuBar: + case PE_PanelDockWindow: + if ( opt.lineWidth() ) + drawMotifPlusShade( p, r, cg, (flags & Style_Sunken), (flags & Style_MouseOver)); + else if ( flags & Style_MouseOver ) + p->fillRect(r, cg.brush(QColorGroup::Midlight)); + else + p->fillRect(r, cg.brush(QColorGroup::Button)); + break; + + case PE_SpinWidgetUp: + drawPrimitive(PE_ArrowUp, p, r, cg, flags, opt); + break; + + case PE_SpinWidgetDown: + drawPrimitive(PE_ArrowDown, p, r, cg, flags, opt); + break; + + case PE_Indicator: + { + QBrush fill; + if (flags & Style_On) + fill = cg.brush(QColorGroup::Mid); + else if (flags & Style_MouseOver) + fill = cg.brush(QColorGroup::Midlight); + else + fill = cg.brush(QColorGroup::Button); + + if (flags & Style_NoChange) { + qDrawPlainRect(p, r, cg.text(), 1, &fill); + p->drawLine(r.topRight(), r.bottomLeft()); + } else + drawMotifPlusShade(p, r, cg, (flags & Style_On), + (flags & Style_MouseOver), &fill); + break; + } + + case PE_ExclusiveIndicator: + { + QPen oldpen = p->pen(); + QPointArray thick(8); + QPointArray thin(4); + QColor button = ((flags & Style_MouseOver) ? cg.midlight() : cg.button()); + QBrush brush = ((flags & Style_MouseOver) ? + cg.brush(QColorGroup::Midlight) : + cg.brush(QColorGroup::Button)); + int x, y, w, h; + r.rect(&x, &y, &w, &h); + + p->fillRect(x, y, w, h, brush); + + + if (flags & Style_On) { + thick.setPoint(0, x, y + (h / 2)); + thick.setPoint(1, x + (w / 2), y); + thick.setPoint(2, x + 1, y + (h / 2)); + thick.setPoint(3, x + (w / 2), y + 1); + thick.setPoint(4, x + (w / 2), y); + thick.setPoint(5, x + w - 1, y + (h / 2)); + thick.setPoint(6, x + (w / 2), y + 1); + thick.setPoint(7, x + w - 2, y + (h / 2)); + p->setPen(cg.dark()); + p->drawLineSegments(thick); + + thick.setPoint(0, x + 1, y + (h / 2) + 1); + thick.setPoint(1, x + (w / 2), y + h - 1); + thick.setPoint(2, x + 2, y + (h / 2) + 1); + thick.setPoint(3, x + (w / 2), y + h - 2); + thick.setPoint(4, x + (w / 2), y + h - 1); + thick.setPoint(5, x + w - 2, y + (h / 2) + 1); + thick.setPoint(6, x + (w / 2), y + h - 2); + thick.setPoint(7, x + w - 3, y + (h / 2) + 1); + p->setPen(cg.light()); + p->drawLineSegments(thick); + + thin.setPoint(0, x + 2, y + (h / 2)); + thin.setPoint(1, x + (w / 2), y + 2); + thin.setPoint(2, x + (w / 2), y + 2); + thin.setPoint(3, x + w - 3, y + (h / 2)); + p->setPen(Qt::black); + p->drawLineSegments(thin); + + thin.setPoint(0, x + 3, y + (h / 2) + 1); + thin.setPoint(1, x + (w / 2), y + h - 3); + thin.setPoint(2, x + (w / 2), y + h - 3); + thin.setPoint(3, x + w - 4, y + (h / 2) + 1); + p->setPen(cg.mid()); + p->drawLineSegments(thin); + } else { + thick.setPoint(0, x, y + (h / 2)); + thick.setPoint(1, x + (w / 2), y); + thick.setPoint(2, x + 1, y + (h / 2)); + thick.setPoint(3, x + (w / 2), y + 1); + thick.setPoint(4, x + (w / 2), y); + thick.setPoint(5, x + w - 1, y + (h / 2)); + thick.setPoint(6, x + (w / 2), y + 1); + thick.setPoint(7, x + w - 2, y + (h / 2)); + p->setPen(cg.light()); + p->drawLineSegments(thick); + + thick.setPoint(0, x + 2, y + (h / 2) + 1); + thick.setPoint(1, x + (w / 2), y + h - 2); + thick.setPoint(2, x + 3, y + (h / 2) + 1); + thick.setPoint(3, x + (w / 2), y + h - 3); + thick.setPoint(4, x + (w / 2), y + h - 2); + thick.setPoint(5, x + w - 3, y + (h / 2) + 1); + thick.setPoint(6, x + (w / 2), y + h - 3); + thick.setPoint(7, x + w - 4, y + (h / 2) + 1); + p->setPen(cg.dark()); + p->drawLineSegments(thick); + + thin.setPoint(0, x + 2, y + (h / 2)); + thin.setPoint(1, x + (w / 2), y + 2); + thin.setPoint(2, x + (w / 2), y + 2); + thin.setPoint(3, x + w - 3, y + (h / 2)); + p->setPen(button); + p->drawLineSegments(thin); + + thin.setPoint(0, x + 1, y + (h / 2) + 1); + thin.setPoint(1, x + (w / 2), y + h - 1); + thin.setPoint(2, x + (w / 2), y + h - 1); + thin.setPoint(3, x + w - 2, y + (h / 2) + 1); + p->setPen(Qt::black); + p->drawLineSegments(thin); + } + + p->setPen(oldpen); + break; + } + + + + case PE_ArrowDown: + case PE_ArrowLeft: + case PE_ArrowRight: + case PE_ArrowUp: + { + QPen oldpen = p->pen(); + QBrush oldbrush = p->brush(); + QPointArray poly(3); + QColor button = (flags & Style_MouseOver) ? cg.midlight() : cg.button(); + bool down = (flags & Style_Down); + int x, y, w, h; + r.rect(&x, &y, &w, &h); + + p->save(); + p->setBrush(button); + + switch (pe) { + case PE_ArrowUp: + { + poly.setPoint(0, x + (w / 2), y ); + poly.setPoint(1, x, y + h - 1); + poly.setPoint(2, x + w - 1, y + h - 1); + p->drawPolygon(poly); + + if (down) + p->setPen(button); + else + p->setPen(cg.dark()); + p->drawLine(x + 1, y + h - 2, x + w - 2, y + h - 2); + + if (down) + p->setPen(cg.light()); + else + p->setPen(black); + p->drawLine(x, y + h - 1, x + w - 1, y + h - 1); + + if (down) + p->setPen(button); + else + p->setPen(cg.dark()); + p->drawLine(x + w - 2, y + h - 1, x + (w / 2), y + 1); + + if (down) + p->setPen(cg.light()); + else + p->setPen(black); + p->drawLine(x + w - 1, y + h - 1, x + (w / 2), y); + + if (down) + p->setPen(black); + else + p->setPen(button); + p->drawLine(x + (w / 2), y + 1, x + 1, y + h - 1); + + if (down) + p->setPen(cg.dark()); + else + p->setPen(cg.light()); + p->drawLine(x + (w / 2), y, x, y + h - 1); + break; + } + + case PE_ArrowDown: + { + poly.setPoint(0, x + w - 1, y); + poly.setPoint(1, x, y); + poly.setPoint(2, x + (w / 2), y + h - 1); + p->drawPolygon(poly); + + if (down) + p->setPen(black); + else + p->setPen(button); + p->drawLine(x + w - 2, y + 1, x + 1, y + 1); + + if (down) + p->setPen(cg.dark()); + else + p->setPen(cg.light()); + p->drawLine(x + w - 1, y, x, y); + + if (down) + p->setPen(black); + else + p->setPen(button); + p->drawLine(x + 1, y, x + (w / 2), y + h - 2); + + if (down) + p->setPen(cg.dark()); + else + p->setPen(cg.light()); + p->drawLine(x, y, x + (w / 2), y + h - 1); + + if (down) + p->setPen(button); + else + p->setPen(cg.dark()); + p->drawLine(x + (w / 2), y + h - 2, x + w - 2, y); + + if (down) + p->setPen(cg.light()); + else + p->setPen(black); + p->drawLine(x + (w / 2), y + h - 1, x + w - 1, y); + break; + } + + case PE_ArrowLeft: + { + poly.setPoint(0, x, y + (h / 2)); + poly.setPoint(1, x + w - 1, y + h - 1); + poly.setPoint(2, x + w - 1, y); + p->drawPolygon(poly); + + if (down) + p->setPen(button); + else + p->setPen(cg.dark()); + p->drawLine(x + 1, y + (h / 2), x + w - 1, y + h - 1); + + if (down) + p->setPen(cg.light()); + else + p->setPen(black); + p->drawLine(x, y + (h / 2), x + w - 1, y + h - 1); + + if (down) + p->setPen(button); + else + p->setPen(cg.dark()); + p->drawLine(x + w - 2, y + h - 1, x + w - 2, y + 1); + + if (down) + p->setPen(cg.light()); + else + p->setPen(black); + p->drawLine(x + w - 1, y + h - 1, x + w - 1, y); + + if (down) + p->setPen(black); + else + p->setPen(button); + p->drawLine(x + w - 1, y + 1, x + 1, y + (h / 2)); + + if (down) + p->setPen(cg.dark()); + else + p->setPen(cg.light()); + p->drawLine(x + w - 1, y, x, y + (h / 2)); + break; + } + + case PE_ArrowRight: + { + poly.setPoint(0, x + w - 1, y + (h / 2)); + poly.setPoint(1, x, y); + poly.setPoint(2, x, y + h - 1); + p->drawPolygon(poly); + + if (down) + p->setPen(black); + else + p->setPen(button); + p->drawLine( x + w - 1, y + (h / 2), x + 1, y + 1); + + if (down) + p->setPen(cg.dark()); + else + p->setPen(cg.light()); + p->drawLine(x + w - 1, y + (h / 2), x, y); + + if (down) + p->setPen(black); + else + p->setPen(button); + p->drawLine(x + 1, y + 1, x + 1, y + h - 2); + + if (down) + p->setPen(cg.dark()); + else + p->setPen(cg.light()); + p->drawLine(x, y, x, y + h - 1); + + if (down) + p->setPen(button); + else + p->setPen(cg.dark()); + p->drawLine(x + 1, y + h - 2, x + w - 1, y + (h / 2)); + + if (down) + p->setPen(cg.light()); + else + p->setPen(black); + p->drawLine(x, y + h - 1, x + w - 1, y + (h / 2)); + break; + } + + default: + break; + } + + p->restore(); + p->setBrush(oldbrush); + p->setPen(oldpen); + break; + } + + default: + QMotifStyle::drawPrimitive(pe, p, r, cg, flags, opt); + break; + } +} + + +/*! \reimp +*/ +void QMotifPlusStyle::drawControl( ControlElement element, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QColorGroup &cg, + SFlags flags, + const QStyleOption& opt ) const +{ + if (widget == singleton->hoverWidget) + flags |= Style_MouseOver; + + switch (element) { + case CE_PushButton: + { +#ifndef QT_NO_PUSHBUTTON + const QPushButton *button = (const QPushButton *) widget; + QRect br = r; + int dbi = pixelMetric(PM_ButtonDefaultIndicator, widget); + + if (button->isDefault() || button->autoDefault()) { + if (button->isDefault()) + drawMotifPlusShade(p, br, cg, TRUE, FALSE, + &cg.brush(QColorGroup::Background)); + + br.setCoords(br.left() + dbi, + br.top() + dbi, + br.right() - dbi, + br.bottom() - dbi); + } + + if (flags & Style_HasFocus) + br.addCoords(1, 1, -1, -1); + p->save(); + p->setBrushOrigin( -button->backgroundOffset().x(), + -button->backgroundOffset().y() ); + drawPrimitive(PE_ButtonCommand, p, br, cg, flags); + p->restore(); +#endif + break; + } + + case CE_CheckBoxLabel: + { +#ifndef QT_NO_CHECKBOX + const QCheckBox *checkbox = (const QCheckBox *) widget; + + if (flags & Style_MouseOver) { + QRegion r(checkbox->rect()); + r -= visualRect(subRect(SR_CheckBoxIndicator, widget), widget); + p->setClipRegion(r); + p->fillRect(checkbox->rect(), cg.brush(QColorGroup::Midlight)); + p->setClipping(FALSE); + } + + int alignment = QApplication::reverseLayout() ? AlignRight : AlignLeft; + drawItem(p, r, alignment | AlignVCenter | ShowPrefix, cg, + flags & Style_Enabled, checkbox->pixmap(), checkbox->text()); + + if (checkbox->hasFocus()) { + QRect fr = visualRect(subRect(SR_CheckBoxFocusRect, widget), widget); + drawPrimitive(PE_FocusRect, p, fr, cg, flags); + } +#endif + break; + } + + case CE_RadioButtonLabel: + { +#ifndef QT_NO_RADIOBUTTON + const QRadioButton *radiobutton = (const QRadioButton *) widget; + + if (flags & Style_MouseOver) { + QRegion r(radiobutton->rect()); + r -= visualRect(subRect(SR_RadioButtonIndicator, widget), widget); + p->setClipRegion(r); + p->fillRect(radiobutton->rect(), cg.brush(QColorGroup::Midlight)); + p->setClipping(FALSE); + } + + int alignment = QApplication::reverseLayout() ? AlignRight : AlignLeft; + drawItem(p, r, alignment | AlignVCenter | ShowPrefix, cg, + flags & Style_Enabled, radiobutton->pixmap(), radiobutton->text()); + + if (radiobutton->hasFocus()) { + QRect fr = visualRect(subRect(SR_RadioButtonFocusRect, widget), widget); + drawPrimitive(PE_FocusRect, p, fr, cg, flags); + } +#endif + break; + } + + case CE_MenuBarItem: + { +#ifndef QT_NO_MENUDATA + if (opt.isDefault()) + break; + + QMenuItem *mi = opt.menuItem(); + if ((flags & Style_Enabled) && (flags & Style_Active)) + drawMotifPlusShade(p, r, cg, FALSE, TRUE); + else + p->fillRect(r, cg.button()); + + drawItem(p, r, AlignCenter | ShowPrefix | DontClip | SingleLine, + cg, flags & Style_Enabled, mi->pixmap(), mi->text(), -1, + &cg.buttonText()); +#endif + break; + } + + +#ifndef QT_NO_POPUPMENU + case CE_PopupMenuItem: + { + if (! widget || opt.isDefault()) + break; + + QPopupMenu *popupmenu = (QPopupMenu *) widget; + QMenuItem *mi = opt.menuItem(); + if ( !mi ) + break; + + int tab = opt.tabWidth(); + int maxpmw = opt.maxIconWidth(); + bool dis = ! (flags & Style_Enabled); + bool checkable = popupmenu->isCheckable(); + bool act = flags & Style_Active; + int x, y, w, h; + + r.rect(&x, &y, &w, &h); + + if (checkable) + maxpmw = QMAX(maxpmw, 15); + + int checkcol = maxpmw; + + if (mi && mi->isSeparator()) { + p->setPen( cg.dark() ); + p->drawLine( x, y, x+w, y ); + p->setPen( cg.light() ); + p->drawLine( x, y+1, x+w, y+1 ); + return; + } + + if ( act && !dis ) + drawMotifPlusShade(p, QRect(x, y, w, h), cg, FALSE, TRUE); + else + p->fillRect(x, y, w, h, cg.brush( QColorGroup::Button )); + + if ( !mi ) + return; + + QRect vrect = visualRect( QRect( x+2, y+2, checkcol, h-2 ), r ); + if ( mi->isChecked() ) { + if ( mi->iconSet() ) { + qDrawShadePanel( p, vrect.x(), y+2, checkcol, h-2*2, + cg, TRUE, 1, &cg.brush( QColorGroup::Midlight ) ); + } + } else if ( !act ) { + p->fillRect(vrect, + cg.brush( QColorGroup::Button )); + } + + if ( mi->iconSet() ) { // draw iconset + QIconSet::Mode mode = (!dis) ? QIconSet::Normal : QIconSet::Disabled; + + if (act && !dis) + mode = QIconSet::Active; + + QPixmap pixmap; + if ( checkable && mi->isChecked() ) + pixmap = mi->iconSet()->pixmap( QIconSet::Small, mode, + QIconSet::On ); + else + pixmap = mi->iconSet()->pixmap( QIconSet::Small, mode ); + + int pixw = pixmap.width(); + int pixh = pixmap.height(); + + QRect pmr( 0, 0, pixw, pixh ); + + pmr.moveCenter(vrect.center()); + + p->setPen( cg.text() ); + p->drawPixmap( pmr.topLeft(), pixmap ); + + } else if (checkable) { + if (mi->isChecked()) { + SFlags cflags = Style_Default; + if (! dis) + cflags |= Style_Enabled; + if (act) + cflags |= Style_On; + + drawPrimitive(PE_CheckMark, p, vrect, cg, cflags); + } + } + + p->setPen( cg.buttonText() ); + + QColor discol; + if (dis) { + discol = cg.text(); + p->setPen( discol ); + } + + vrect = visualRect( QRect(x + checkcol + 4, y + 2, + w - checkcol - tab - 3, h - 4), r ); + if (mi->custom()) { + p->save(); + mi->custom()->paint(p, cg, act, !dis, vrect.x(), y + 2, + w - checkcol - tab - 3, h - 4); + p->restore(); + } + + QString s = mi->text(); + if ( !s.isNull() ) { // draw text + int t = s.find( '\t' ); + int m = 2; + int text_flags = AlignVCenter|ShowPrefix | DontClip | SingleLine; + text_flags |= (QApplication::reverseLayout() ? AlignRight : AlignLeft ); + if ( t >= 0 ) { // draw tab text + QRect vr = visualRect( QRect(x+w-tab-2-2, + y+m, tab, h-2*m), r ); + p->drawText( vr.x(), + y+m, tab, h-2*m, text_flags, s.mid( t+1 ) ); + } + p->drawText(vrect.x(), y + 2, w - checkcol -tab - 3, h - 4, + text_flags, s, t); + } else if (mi->pixmap()) { + QPixmap *pixmap = mi->pixmap(); + + if (pixmap->depth() == 1) p->setBackgroundMode(OpaqueMode); + QRect vr = visualRect( QRect( x + checkcol + 2, y + 2, w - checkcol - 1, h - 4 ), r ); + p->drawPixmap(vr.x(), y + 2, *pixmap); + if (pixmap->depth() == 1) p->setBackgroundMode(TransparentMode); + } + + if (mi->popup()) { + int hh = h / 2; + QStyle::PrimitiveElement arrow = (QApplication::reverseLayout() ? PE_ArrowLeft : PE_ArrowRight); + vrect = visualRect( QRect(x + w - hh - 6, y + (hh / 2), hh, hh), r ); + drawPrimitive(arrow, p, + vrect, cg, + ((act && !dis) ? + Style_Down : Style_Default) | + ((!dis) ? Style_Enabled : Style_Default)); + } + break; + } +#endif // QT_NO_POPUPMENU + + case CE_TabBarTab: + { +#ifndef QT_NO_TABBAR + const QTabBar *tabbar = (const QTabBar *) widget; + bool selected = flags & Style_Selected; + + QColorGroup g = tabbar->colorGroup(); + QPen oldpen = p->pen(); + QRect fr(r); + + if (! selected) { + if (tabbar->shape() == QTabBar::RoundedAbove || + tabbar->shape() == QTabBar::TriangularAbove) { + fr.setTop(fr.top() + 2); + } else { + fr.setBottom(fr.bottom() - 2); + } + } + + fr.setWidth(fr.width() - 3); + + p->fillRect(fr.left() + 1, fr.top() + 1, fr.width() - 2, fr.height() - 2, + (selected) ? cg.brush(QColorGroup::Button) + : cg.brush(QColorGroup::Mid)); + + if (tabbar->shape() == QTabBar::RoundedAbove) { + // "rounded" tabs on top + fr.setBottom(fr.bottom() - 1); + + p->setPen(g.light()); + p->drawLine(fr.left(), fr.top() + 1, + fr.left(), fr.bottom() - 1); + p->drawLine(fr.left() + 1, fr.top(), + fr.right() - 1, fr.top()); + if (! selected) + p->drawLine(fr.left(), fr.bottom(), + fr.right() + 3, fr.bottom()); + + if (fr.left() == 0) + p->drawLine(fr.left(), fr.bottom(), + fr.left(), fr.bottom() + 1); + + p->setPen(g.dark()); + p->drawLine(fr.right() - 1, fr.top() + 2, + fr.right() - 1, fr.bottom() - 1); + + p->setPen(black); + p->drawLine(fr.right(), fr.top() + 1, + fr.right(), fr.bottom() - 1); + } else if (tabbar->shape() == QTabBar::RoundedBelow) { + // "rounded" tabs on bottom + fr.setTop(fr.top() + 1); + + p->setPen(g.dark()); + p->drawLine(fr.right() + 3, fr.top() - 1, + fr.right() - 1, fr.top() - 1); + p->drawLine(fr.right() - 1, fr.top(), + fr.right() - 1, fr.bottom() - 2); + p->drawLine(fr.right() - 1, fr.bottom() - 2, + fr.left() + 2, fr.bottom() - 2); + if (! selected) { + p->drawLine(fr.right(), fr.top() - 1, + fr.left() + 1, fr.top() - 1); + + if (fr.left() != 0) + p->drawPoint(fr.left(), fr.top() - 1); + } + + p->setPen(black); + p->drawLine(fr.right(), fr.top(), + fr.right(), fr.bottom() - 2); + p->drawLine(fr.right() - 1, fr.bottom() - 1, + fr.left(), fr.bottom() - 1); + if (! selected) + p->drawLine(fr.right() + 3, fr.top(), + fr.left(), fr.top()); + else + p->drawLine(fr.right() + 3, fr.top(), + fr.right(), fr.top()); + + p->setPen(g.light()); + p->drawLine(fr.left(), fr.top() + 1, + fr.left(), fr.bottom() - 2); + + if (selected) { + p->drawPoint(fr.left(), fr.top()); + if (fr.left() == 0) + p->drawPoint(fr.left(), fr.top() - 1); + + p->setPen(g.button()); + p->drawLine(fr.left() + 2, fr.top() - 1, + fr.left() + 1, fr.top() - 1); + } + } else + // triangular drawing code + QMotifStyle::drawControl(element, p, widget, r, cg, flags, opt); + + p->setPen(oldpen); +#endif + break; + } + + default: + QMotifStyle::drawControl(element, p, widget, r, cg, flags, opt); + break; + } +} + + +/*! \reimp +*/ +QRect QMotifPlusStyle::subRect(SubRect r, const QWidget *widget) const +{ + QRect rect; + + switch (r) { + case SR_PushButtonFocusRect: + { +#ifndef QT_NO_PUSHBUTTON + const QPushButton *button = (const QPushButton *) widget; + int dfi = pixelMetric(PM_ButtonDefaultIndicator, widget); + + rect = button->rect(); + if (button->isDefault() || button->autoDefault()) + rect.addCoords(dfi, dfi, -dfi, -dfi); +#endif + break; + } + + case SR_CheckBoxIndicator: + { + int h = pixelMetric( PM_IndicatorHeight ); + rect.setRect(( widget->rect().height() - h ) / 2, + ( widget->rect().height() - h ) / 2, + pixelMetric( PM_IndicatorWidth ), h ); + break; + } + + case SR_RadioButtonIndicator: + { + int h = pixelMetric( PM_ExclusiveIndicatorHeight ); + rect.setRect( ( widget->rect().height() - h ) / 2, + ( widget->rect().height() - h ) / 2, + pixelMetric( PM_ExclusiveIndicatorWidth ), h ); + break; + } + + case SR_CheckBoxFocusRect: + case SR_RadioButtonFocusRect: + rect = widget->rect(); + break; + + case SR_ComboBoxFocusRect: + { +#ifndef QT_NO_COMBOBOX + const QComboBox *combobox = (const QComboBox *) widget; + + if (combobox->editable()) { + rect = querySubControlMetrics(CC_ComboBox, widget, + SC_ComboBoxEditField); + rect.addCoords(-3, -3, 3, 3); + } else + rect = combobox->rect(); +#endif + break; + } + + case SR_SliderFocusRect: + { +#ifndef QT_NO_SLIDER + const QSlider *slider = (const QSlider *) widget; + int tickOffset = pixelMetric( PM_SliderTickmarkOffset, widget ); + int thickness = pixelMetric( PM_SliderControlThickness, widget ); + int x, y, wi, he; + + if ( slider->orientation() == Horizontal ) { + x = 0; + y = tickOffset; + wi = slider->width(); + he = thickness; + } else { + x = tickOffset; + y = 0; + wi = thickness; + he = slider->height(); + } + + rect.setRect(x, y, wi, he); +#endif + break; + } + + default: + rect = QMotifStyle::subRect(r, widget); + break; + } + + return rect; +} + + +/*! \reimp */ +void QMotifPlusStyle::drawComplexControl(ComplexControl control, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QColorGroup &cg, + SFlags flags, + SCFlags controls, + SCFlags active, + const QStyleOption& opt ) const +{ + if (widget == singleton->hoverWidget) + flags |= Style_MouseOver; + + switch (control) { + case CC_ScrollBar: + { +#ifndef QT_NO_SCROLLBAR + const QScrollBar *scrollbar = (const QScrollBar *) widget; + QRect addline, subline, addpage, subpage, slider, first, last; + bool maxedOut = (scrollbar->minValue() == scrollbar->maxValue()); + + subline = querySubControlMetrics(control, widget, SC_ScrollBarSubLine, opt); + addline = querySubControlMetrics(control, widget, SC_ScrollBarAddLine, opt); + subpage = querySubControlMetrics(control, widget, SC_ScrollBarSubPage, opt); + addpage = querySubControlMetrics(control, widget, SC_ScrollBarAddPage, opt); + slider = querySubControlMetrics(control, widget, SC_ScrollBarSlider, opt); + first = querySubControlMetrics(control, widget, SC_ScrollBarFirst, opt); + last = querySubControlMetrics(control, widget, SC_ScrollBarLast, opt); + + bool skipUpdate = FALSE; + if (singleton->hovering) { + if (addline.contains(singleton->mousePos)) { + skipUpdate = + (singleton->scrollbarElement == SC_ScrollBarAddLine); + singleton->scrollbarElement = SC_ScrollBarAddLine; + } else if (subline.contains(singleton->mousePos)) { + skipUpdate = + (singleton->scrollbarElement == SC_ScrollBarSubLine); + singleton->scrollbarElement = SC_ScrollBarSubLine; + } else if (slider.contains(singleton->mousePos)) { + skipUpdate = + (singleton->scrollbarElement == SC_ScrollBarSlider); + singleton->scrollbarElement = SC_ScrollBarSlider; + } else { + skipUpdate = + (singleton->scrollbarElement == 0); + singleton->scrollbarElement = 0; + } + } else + singleton->scrollbarElement = 0; + + if (skipUpdate && singleton->scrollbarElement == singleton->lastElement) + break; + + singleton->lastElement = singleton->scrollbarElement; + + if (controls == (SC_ScrollBarAddLine | SC_ScrollBarSubLine | + SC_ScrollBarAddPage | SC_ScrollBarSubPage | + SC_ScrollBarFirst | SC_ScrollBarLast | SC_ScrollBarSlider)) + drawMotifPlusShade(p, widget->rect(), cg, TRUE, FALSE, + &cg.brush(QColorGroup::Mid)); + + if ((controls & SC_ScrollBarSubLine) && subline.isValid()) + drawPrimitive(PE_ScrollBarSubLine, p, subline, cg, + ((active == SC_ScrollBarSubLine || + singleton->scrollbarElement == SC_ScrollBarSubLine) ? + Style_MouseOver: Style_Default) | + ((maxedOut) ? Style_Default : Style_Enabled) | + ((active == SC_ScrollBarSubLine) ? + Style_Down : Style_Default) | + ((scrollbar->orientation() == Qt::Horizontal) ? + Style_Horizontal : Style_Default)); + if ((controls & SC_ScrollBarAddLine) && addline.isValid()) + drawPrimitive(PE_ScrollBarAddLine, p, addline, cg, + ((active == SC_ScrollBarAddLine || + singleton->scrollbarElement == SC_ScrollBarAddLine) ? + Style_MouseOver: Style_Default) | + ((maxedOut) ? Style_Default : Style_Enabled) | + ((active == SC_ScrollBarAddLine) ? + Style_Down : Style_Default) | + ((scrollbar->orientation() == Qt::Horizontal) ? + Style_Horizontal : Style_Default)); + if ((controls & SC_ScrollBarSubPage) && subpage.isValid()) + drawPrimitive(PE_ScrollBarSubPage, p, subpage, cg, + ((maxedOut) ? Style_Default : Style_Enabled) | + ((active == SC_ScrollBarSubPage) ? + Style_Down : Style_Default) | + ((scrollbar->orientation() == Qt::Horizontal) ? + Style_Horizontal : Style_Default)); + if ((controls & SC_ScrollBarAddPage) && addpage.isValid()) + drawPrimitive(PE_ScrollBarAddPage, p, addpage, cg, + ((maxedOut) ? Style_Default : Style_Enabled) | + ((active == SC_ScrollBarAddPage) ? + Style_Down : Style_Default) | + ((scrollbar->orientation() == Qt::Horizontal) ? + Style_Horizontal : Style_Default)); + if ((controls & SC_ScrollBarFirst) && first.isValid()) + drawPrimitive(PE_ScrollBarFirst, p, first, cg, + ((maxedOut) ? Style_Default : Style_Enabled) | + ((active == SC_ScrollBarFirst) ? + Style_Down : Style_Default) | + ((scrollbar->orientation() == Qt::Horizontal) ? + Style_Horizontal : Style_Default)); + if ((controls & SC_ScrollBarLast) && last.isValid()) + drawPrimitive(PE_ScrollBarLast, p, last, cg, + ((maxedOut) ? Style_Default : Style_Enabled) | + ((active == SC_ScrollBarLast) ? + Style_Down : Style_Default) | + ((scrollbar->orientation() == Qt::Horizontal) ? + Style_Horizontal : Style_Default)); + if ((controls & SC_ScrollBarSlider) && slider.isValid()) { + drawPrimitive(PE_ScrollBarSlider, p, slider, cg, + ((active == SC_ScrollBarSlider || + singleton->scrollbarElement == SC_ScrollBarSlider) ? + Style_MouseOver: Style_Default) | + ((maxedOut) ? Style_Default : Style_Enabled) | + ((scrollbar->orientation() == Qt::Horizontal) ? + Style_Horizontal : Style_Default)); + + // ### perhaps this should not be able to accept focus if maxedOut? + if (scrollbar->hasFocus()) { + QRect fr(slider.x() + 2, slider.y() + 2, + slider.width() - 5, slider.height() - 5); + drawPrimitive(PE_FocusRect, p, fr, cg, Style_Default); + } + } +#endif + break; + } + + case CC_ComboBox: + { +#ifndef QT_NO_COMBOBOX + const QComboBox *combobox = (const QComboBox *) widget; + + QRect editfield, arrow; + editfield = + visualRect(querySubControlMetrics(CC_ComboBox, + combobox, + SC_ComboBoxEditField, + opt), widget); + arrow = + visualRect(querySubControlMetrics(CC_ComboBox, + combobox, + SC_ComboBoxArrow, + opt), widget); + + if (combobox->editable()) { + if (controls & SC_ComboBoxEditField && editfield.isValid()) { + editfield.addCoords(-3, -3, 3, 3); + if (combobox->hasFocus()) + editfield.addCoords(1, 1, -1, -1); + drawMotifPlusShade(p, editfield, cg, TRUE, FALSE, + (widget->isEnabled() ? + &cg.brush(QColorGroup::Base) : + &cg.brush(QColorGroup::Background))); + } + + if (controls & SC_ComboBoxArrow && arrow.isValid()) { + drawMotifPlusShade(p, arrow, cg, (active == SC_ComboBoxArrow), + (flags & Style_MouseOver)); + + int space = (r.height() - 13) / 2; + arrow.addCoords(space, space, -space, -space); + + if (active == SC_ComboBoxArrow) + flags |= Style_Sunken; + drawPrimitive(PE_ArrowDown, p, arrow, cg, flags); + } + } else { + if (controls & SC_ComboBoxEditField && editfield.isValid()) { + editfield.addCoords(-3, -3, 3, 3); + if (combobox->hasFocus()) + editfield.addCoords(1, 1, -1, -1); + drawMotifPlusShade(p, editfield, cg, FALSE, + (flags & Style_MouseOver)); + } + + if (controls & SC_ComboBoxArrow && arrow.isValid()) + drawMotifPlusShade(p, arrow, cg, FALSE, (flags & Style_MouseOver)); + } + + if (combobox->hasFocus() || + (combobox->editable() && combobox->lineEdit()->hasFocus())) { + QRect fr = visualRect(subRect(SR_ComboBoxFocusRect, widget), widget); + drawPrimitive(PE_FocusRect, p, fr, cg, flags); + } +#endif + break; + } + + case CC_SpinWidget: + { +#ifndef QT_NO_SPINWIDGET + const QSpinWidget * sw = (const QSpinWidget *) widget; + SFlags flags = Style_Default; + + if (controls & SC_SpinWidgetFrame) + drawMotifPlusShade(p, r, cg, TRUE, FALSE, &cg.brush(QColorGroup::Base)); + + if (controls & SC_SpinWidgetUp) { + flags = Style_Enabled; + if (active == SC_SpinWidgetUp ) + flags |= Style_Down; + + PrimitiveElement pe; + if ( sw->buttonSymbols() == QSpinWidget::PlusMinus ) + pe = PE_SpinWidgetPlus; + else + pe = PE_SpinWidgetUp; + + QRect re = sw->upRect(); + QColorGroup ucg = sw->isUpEnabled() ? cg : sw->palette().disabled(); + drawPrimitive(pe, p, re, ucg, flags); + } + + if (controls & SC_SpinWidgetDown) { + flags = Style_Enabled; + if (active == SC_SpinWidgetDown ) + flags |= Style_Down; + + PrimitiveElement pe; + if ( sw->buttonSymbols() == QSpinWidget::PlusMinus ) + pe = PE_SpinWidgetMinus; + else + pe = PE_SpinWidgetDown; + + QRect re = sw->downRect(); + QColorGroup dcg = sw->isDownEnabled() ? cg : sw->palette().disabled(); + drawPrimitive(pe, p, re, dcg, flags); + } +#endif + break; + } + + case CC_Slider: + { +#ifndef QT_NO_SLIDER + const QSlider *slider = (const QSlider *) widget; + bool mouseover = (flags & Style_MouseOver); + + QRect groove = querySubControlMetrics(CC_Slider, widget, SC_SliderGroove, + opt), + handle = querySubControlMetrics(CC_Slider, widget, SC_SliderHandle, + opt); + + if ((controls & SC_SliderGroove) && groove.isValid()) { + drawMotifPlusShade(p, groove, cg, TRUE, FALSE, + &cg.brush(QColorGroup::Mid)); + + if ( flags & Style_HasFocus ) { + QRect fr = subRect( SR_SliderFocusRect, widget ); + drawPrimitive( PE_FocusRect, p, fr, cg, flags ); + } + } + + if ((controls & SC_SliderHandle) && handle.isValid()) { + if ((mouseover && handle.contains(singleton->mousePos)) || + singleton->sliderActive) + flags |= Style_MouseOver; + else + flags &= ~Style_MouseOver; + drawPrimitive(PE_ButtonBevel, p, handle, cg, flags | Style_Raised); + + if ( slider->orientation() == Horizontal ) { + QCOORD mid = handle.x() + handle.width() / 2; + qDrawShadeLine( p, mid, handle.y() + 1, mid , + handle.y() + handle.height() - 3, + cg, TRUE, 1); + } else { + QCOORD mid = handle.y() + handle.height() / 2; + qDrawShadeLine( p, handle.x() + 1, mid, + handle.x() + handle.width() - 3, mid, + cg, TRUE, 1); + } + } + + if (controls & SC_SliderTickmarks) + QMotifStyle::drawComplexControl(control, p, widget, r, cg, flags, + SC_SliderTickmarks, active, opt); +#endif + break; + } + + default: + QMotifStyle::drawComplexControl(control, p, widget, r, cg, flags, + controls, active, opt); + } +} + + +/*! \reimp +*/ +QRect QMotifPlusStyle::querySubControlMetrics(ComplexControl control, + const QWidget *widget, + SubControl subcontrol, + const QStyleOption& opt) const +{ + switch (control) { + case CC_SpinWidget: { + int fw = pixelMetric( PM_SpinBoxFrameWidth, 0 ); + QSize bs; + bs.setHeight( (widget->height() + 1)/2 ); + if ( bs.height() < 10 ) + bs.setHeight( 10 ); + bs.setWidth( bs.height() ); // 1.6 -approximate golden mean + bs = bs.expandedTo( QApplication::globalStrut() ); + int y = 0; + int x, lx, rx, h; + x = widget->width() - y - bs.width(); + lx = fw; + rx = x - fw * 2; + h = bs.height() * 2; + + switch ( subcontrol ) { + case SC_SpinWidgetUp: + return QRect(x + 1, y, bs.width(), bs.height() - 1); + case SC_SpinWidgetDown: + return QRect(x + 1, y + bs.height() + 1, bs.width(), bs.height()); + case SC_SpinWidgetButtonField: + return QRect(x, y, bs.width(), h - 2*fw); + case SC_SpinWidgetEditField: + return QRect(lx, fw, rx, h - 2*fw); + case SC_SpinWidgetFrame: + return QRect( 0, 0, widget->width() - bs.width(), h); + default: + break; + } + break; } + +#ifndef QT_NO_COMBOBOX + case CC_ComboBox: { + const QComboBox *combobox = (const QComboBox *) widget; + if (combobox->editable()) { + int space = (combobox->height() - 13) / 2; + switch (subcontrol) { + case SC_ComboBoxFrame: + return QRect(); + case SC_ComboBoxEditField: { + QRect rect = widget->rect(); + rect.setWidth(rect.width() - 13 - space * 2); + rect.addCoords(3, 3, -3, -3); + return rect; } + case SC_ComboBoxArrow: + return QRect(combobox->width() - 13 - space * 2, 0, + 13 + space * 2, combobox->height()); + default: break; // shouldn't get here + } + + } else { + int space = (combobox->height() - 7) / 2; + switch (subcontrol) { + case SC_ComboBoxFrame: + return QRect(); + case SC_ComboBoxEditField: { + QRect rect = widget->rect(); + rect.addCoords(3, 3, -3, -3); + return rect; } + case SC_ComboBoxArrow: // 12 wide, 7 tall + return QRect(combobox->width() - 12 - space, space, 12, 7); + default: break; // shouldn't get here + } + } + break; } +#endif + +#ifndef QT_NO_SLIDER + case CC_Slider: { + + if (subcontrol == SC_SliderHandle) { + const QSlider *slider = (const QSlider *) widget; + int tickOffset = pixelMetric( PM_SliderTickmarkOffset, widget ); + int thickness = pixelMetric( PM_SliderControlThickness, widget ); + int len = pixelMetric( PM_SliderLength, widget ) + 2; + int sliderPos = slider->sliderStart(); + int motifBorder = 2; + + if ( slider->orientation() == Horizontal ) + return QRect( sliderPos + motifBorder, tickOffset + motifBorder, len, + thickness - 2*motifBorder ); + return QRect( tickOffset + motifBorder, sliderPos + motifBorder, + thickness - 2*motifBorder, len); + } + break; } +#endif + default: break; + } + return QMotifStyle::querySubControlMetrics(control, widget, subcontrol, opt); +} + + +/*! \reimp */ +bool QMotifPlusStyle::eventFilter(QObject *object, QEvent *event) +{ + switch(event->type()) { + case QEvent::MouseButtonPress: + { + singleton->mousePressed = TRUE; + + if (!::qt_cast(object)) + break; + + singleton->sliderActive = TRUE; + break; + } + + case QEvent::MouseButtonRelease: + { + singleton->mousePressed = FALSE; + + if (!::qt_cast(object)) + break; + + singleton->sliderActive = FALSE; + ((QWidget *) object)->repaint(FALSE); + break; + } + + case QEvent::Enter: + { + if (! object->isWidgetType()) + break; + + singleton->hoverWidget = (QWidget *) object; + if (! singleton->hoverWidget->isEnabled()) { + singleton->hoverWidget = 0; + break; + } + singleton->hoverWidget->repaint(FALSE); + break; + } + + case QEvent::Leave: + { + if (object != singleton->hoverWidget) + break; + QWidget *w = singleton->hoverWidget; + singleton->hoverWidget = 0; + w->repaint(FALSE); + break; + } + + case QEvent::MouseMove: + { + if (! object->isWidgetType() || object != singleton->hoverWidget) + break; + + if (!::qt_cast(object) && ! ::qt_cast(object)) + break; + + singleton->mousePos = ((QMouseEvent *) event)->pos(); + if (! singleton->mousePressed) { + singleton->hovering = TRUE; + singleton->hoverWidget->repaint(FALSE); + singleton->hovering = FALSE; + } + + break; + } + + default: + break; + } + + return QMotifStyle::eventFilter(object, event); +} + + +/*! \reimp */ +int QMotifPlusStyle::styleHint(StyleHint hint, + const QWidget *widget, + const QStyleOption &opt, + QStyleHintReturn *returnData) const +{ + int ret; + switch (hint) { + case SH_PopupMenu_MouseTracking: + ret = 1; + break; + default: + ret = QMotifStyle::styleHint(hint, widget, opt, returnData); + break; + } + return ret; +} + + +#endif // QT_NO_STYLE_MOTIFPLUS diff --git a/src/styles/qmotifplusstyle.h b/src/styles/qmotifplusstyle.h new file mode 100644 index 0000000..b1908de --- /dev/null +++ b/src/styles/qmotifplusstyle.h @@ -0,0 +1,124 @@ +/**************************************************************************** +** +** Definition of QMotifPlusStyle class +** +** Created : 000727 +** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the widgets module of the Qt GUI Toolkit. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** This file may be used under the terms of the Q Public License as +** defined by Trolltech ASA and appearing in the file LICENSE.QPL +** included in the packaging of this file. Licensees holding valid Qt +** Commercial licenses may use this file in accordance with the Qt +** Commercial License Agreement provided with the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef QMOTIFPLUSSTYLE_H +#define QMOTIFPLUSSTYLE_H + + +#ifndef QT_H +#include "qmotifstyle.h" +#endif // QT_H + +#if !defined(QT_NO_STYLE_MOTIFPLUS) || defined(QT_PLUGIN) + +#if defined(QT_PLUGIN) +#define Q_EXPORT_STYLE_MOTIFPLUS +#else +#define Q_EXPORT_STYLE_MOTIFPLUS Q_EXPORT +#endif + +class Q_EXPORT_STYLE_MOTIFPLUS QMotifPlusStyle : public QMotifStyle +{ + Q_OBJECT + +public: + QMotifPlusStyle(bool hoveringHighlight = TRUE); + virtual ~QMotifPlusStyle(); + + void polish(QPalette &pal); + void polish(QWidget *widget); + void unPolish(QWidget*widget); + + void polish(QApplication *app); + void unPolish(QApplication *app); + + void drawPrimitive( PrimitiveElement pe, + QPainter *p, + const QRect &r, + const QColorGroup &cg, + SFlags flags = Style_Default, + const QStyleOption& = QStyleOption::Default ) const; + + void drawControl( ControlElement element, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QColorGroup &cg, + SFlags how = Style_Default, + const QStyleOption& = QStyleOption::Default ) const; + + QRect subRect(SubRect r, const QWidget *widget) const; + + void drawComplexControl(ComplexControl control, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QColorGroup &cg, + SFlags how = Style_Default, +#ifdef Q_QDOC + SCFlags controls = SC_All, +#else + SCFlags controls = (uint)SC_All, +#endif + SCFlags active = SC_None, + const QStyleOption& = QStyleOption::Default ) const; + + QRect querySubControlMetrics(ComplexControl control, + const QWidget *widget, + SubControl subcontrol, + const QStyleOption& = QStyleOption::Default) const; + + int pixelMetric(PixelMetric metric, const QWidget *widget = 0) const; + + int styleHint(StyleHint sh, const QWidget *, const QStyleOption & = QStyleOption::Default, + QStyleHintReturn* = 0) const; + +protected: + bool eventFilter(QObject *, QEvent *); + + +private: + bool useHoveringHighlight; +}; + + +#endif // QT_NO_STYLE_MOTIFPLUS + +#endif // QMOTIFPLUSSTYLE_H diff --git a/src/styles/qmotifstyle.cpp b/src/styles/qmotifstyle.cpp new file mode 100644 index 0000000..d6a1644 --- /dev/null +++ b/src/styles/qmotifstyle.cpp @@ -0,0 +1,2359 @@ +/**************************************************************************** +** +** Implementation of Motif-like style class +** +** Created : 981231 +** +** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the widgets module of the Qt GUI Toolkit. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** This file may be used under the terms of the Q Public License as +** defined by Trolltech ASA and appearing in the file LICENSE.QPL +** included in the packaging of this file. Licensees holding valid Qt +** Commercial licenses may use this file in accordance with the Qt +** Commercial License Agreement provided with the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "qmotifstyle.h" + +#if !defined(QT_NO_STYLE_MOTIF) || defined(QT_PLUGIN) + +#include "qpopupmenu.h" +#include "qapplication.h" +#include "qpainter.h" +#include "qdrawutil.h" +#include "qpixmap.h" +#include "qpalette.h" +#include "qwidget.h" +#include "qpushbutton.h" +#include "qscrollbar.h" +#include "qtabbar.h" +#include "qtabwidget.h" +#include "qlistview.h" +#include "qsplitter.h" +#include "qslider.h" +#include "qcombobox.h" +#include "qdockwindow.h" +#include "qdockarea.h" +#include "qprogressbar.h" +#include "qimage.h" +#include + + + +// old constants that might still be useful... +static const int motifItemFrame = 2; // menu item frame width +static const int motifSepHeight = 2; // separator item height +static const int motifItemHMargin = 3; // menu item hor text margin +static const int motifItemVMargin = 2; // menu item ver text margin +static const int motifArrowHMargin = 6; // arrow horizontal margin +static const int motifTabSpacing = 12; // space between text and tab +static const int motifCheckMarkHMargin = 2; // horiz. margins of check mark +static const int motifCheckMarkSpace = 12; + + +/*! + \class QMotifStyle qmotifstyle.h + \brief The QMotifStyle class provides Motif look and feel. + + \ingroup appearance + + This class implements the Motif look and feel. It closely + resembles the original Motif look as defined by the Open Group, + but with some minor improvements. The Motif style is Qt's default + GUI style on UNIX platforms. +*/ + +/*! + Constructs a QMotifStyle. + + If \a useHighlightCols is FALSE (the default), the style will + polish the application's color palette to emulate the Motif way of + highlighting, which is a simple inversion between the base and the + text color. +*/ +QMotifStyle::QMotifStyle( bool useHighlightCols ) : QCommonStyle() +{ + highlightCols = useHighlightCols; +} + +/*!\reimp +*/ +QMotifStyle::~QMotifStyle() +{ +} + +/*! + If \a arg is FALSE, the style will polish the application's color + palette to emulate the Motif way of highlighting, which is a + simple inversion between the base and the text color. + + The effect will show up the next time an application palette is + set via QApplication::setPalette(). The current color palette of + the application remains unchanged. + + \sa QStyle::polish() +*/ +void QMotifStyle::setUseHighlightColors( bool arg ) +{ + highlightCols = arg; +} + +/*! + Returns TRUE if the style treats the highlight colors of the + palette in a Motif-like manner, which is a simple inversion + between the base and the text color; otherwise returns FALSE. The + default is FALSE. +*/ +bool QMotifStyle::useHighlightColors() const +{ + return highlightCols; +} + +/*! \reimp */ + +void QMotifStyle::polish( QPalette& pal ) +{ + if ( pal.active().light() == pal.active().base() ) { + QColor nlight = pal.active().light().dark(108 ); + pal.setColor( QPalette::Active, QColorGroup::Light, nlight ) ; + pal.setColor( QPalette::Disabled, QColorGroup::Light, nlight ) ; + pal.setColor( QPalette::Inactive, QColorGroup::Light, nlight ) ; + } + + if ( highlightCols ) + return; + + // force the ugly motif way of highlighting *sigh* + QColorGroup disabled = pal.disabled(); + QColorGroup active = pal.active(); + + pal.setColor( QPalette::Active, QColorGroup::Highlight, + active.text() ); + pal.setColor( QPalette::Active, QColorGroup::HighlightedText, + active.base()); + pal.setColor( QPalette::Disabled, QColorGroup::Highlight, + disabled.text() ); + pal.setColor( QPalette::Disabled, QColorGroup::HighlightedText, + disabled.base() ); + pal.setColor( QPalette::Inactive, QColorGroup::Highlight, + active.text() ); + pal.setColor( QPalette::Inactive, QColorGroup::HighlightedText, + active.base() ); +} + +/*! + \reimp + \internal + Keep QStyle::polish() visible. +*/ +void QMotifStyle::polish( QWidget* w ) +{ + QStyle::polish(w); +} + +/*! + \reimp + \internal + Keep QStyle::polish() visible. +*/ +void QMotifStyle::polish( QApplication* a ) +{ + QStyle::polish(a); +} + +static void rot(QPointArray& a, int n) +{ + QPointArray r(a.size()); + for (int i = 0; i < (int)a.size(); i++) { + switch (n) { + case 1: r.setPoint(i,-a[i].y(),a[i].x()); break; + case 2: r.setPoint(i,-a[i].x(),-a[i].y()); break; + case 3: r.setPoint(i,a[i].y(),-a[i].x()); break; + } + } + a = r; +} + + +/*!\reimp +*/ +void QMotifStyle::drawPrimitive( PrimitiveElement pe, + QPainter *p, + const QRect &r, + const QColorGroup &cg, + SFlags flags, + const QStyleOption& opt ) const +{ + switch( pe ) { +#ifndef QT_NO_LISTVIEW + case PE_CheckListExclusiveIndicator: { + QCheckListItem *item = opt.checkListItem(); + QListView *lv = item->listView(); + if(!item) + return; + + if ( item->isEnabled() ) + p->setPen( QPen( cg.text() ) ); + else + p->setPen( QPen( lv->palette().color( QPalette::Disabled, QColorGroup::Text ) ) ); + QPointArray a; + + int cx = r.width()/2 - 1; + int cy = r.height()/2; + int e = r.width()/2 - 1; + for ( int i = 0; i < 3; i++ ) { //penWidth 2 doesn't quite work + a.setPoints( 4, cx-e, cy, cx, cy-e, cx+e, cy, cx, cy+e ); + p->drawPolygon( a ); + e--; + } + if ( item->isOn() ) { + if ( item->isEnabled() ) + p->setPen( QPen( cg.text()) ); + else + p->setPen( QPen( item->listView()->palette().color( QPalette::Disabled, + QColorGroup::Text ) ) ); + QBrush saveBrush = p->brush(); + p->setBrush( cg.text() ); + e = e - 2; + a.setPoints( 4, cx-e, cy, cx, cy-e, cx+e, cy, cx, cy+e ); + p->drawPolygon( a ); + p->setBrush( saveBrush ); + } + break; } +#endif + case PE_ButtonCommand: + case PE_ButtonBevel: + case PE_ButtonTool: + case PE_HeaderSection: + qDrawShadePanel( p, r, cg, bool(flags & (Style_Down | Style_On )), + pixelMetric(PM_DefaultFrameWidth), + &cg.brush(QColorGroup::Button) ); + break; + + case PE_Indicator: { +#ifndef QT_NO_BUTTON + bool on = flags & Style_On; + bool down = flags & Style_Down; + bool showUp = !( down ^ on ); + QBrush fill = showUp || flags & Style_NoChange ? cg.brush( QColorGroup::Button ) : cg.brush(QColorGroup::Mid ); + if ( flags & Style_NoChange ) { + qDrawPlainRect( p, r, cg.text(), + 1, &fill ); + p->drawLine( r.x() + r.width() - 1, r.y(), + r.x(), r.y() + r.height() - 1); + } else + qDrawShadePanel( p, r, cg, !showUp, + pixelMetric(PM_DefaultFrameWidth), &fill ); +#endif + break; + } + + case PE_ExclusiveIndicator: + { +#define QCOORDARRLEN(x) sizeof(x)/(sizeof(QCOORD)*2) + QCOORD inner_pts[] = { // used for filling diamond + 2,r.height()/2, + r.width()/2,2, + r.width()-3,r.height()/2, + r.width()/2,r.height()-3 + }; + QCOORD top_pts[] = { // top (^) of diamond + 0,r.height()/2, + r.width()/2,0, + r.width()-2,r.height()/2-1, + r.width()-3,r.height()/2-1, + r.width()/2,1, + 1,r.height()/2, + 2,r.height()/2, + r.width()/2,2, + r.width()-4,r.height()/2-1 + }; + QCOORD bottom_pts[] = { // bottom (v) of diamond + 1,r.height()/2+1, + r.width()/2,r.height()-1, + r.width()-1,r.height()/2, + r.width()-2,r.height()/2, + r.width()/2,r.height()-2, + 2,r.height()/2+1, + 3,r.height()/2+1, + r.width()/2,r.height()-3, + r.width()-3,r.height()/2 + }; + bool on = flags & Style_On; + bool down = flags & Style_Down; + bool showUp = !(down ^ on ); + QPointArray a( QCOORDARRLEN(inner_pts), inner_pts ); + p->eraseRect( r ); + p->setPen( NoPen ); + p->setBrush( showUp ? cg.brush( QColorGroup::Button ) : + cg.brush( QColorGroup::Mid ) ); + a.translate( r.x(), r.y() ); + p->drawPolygon( a ); + p->setPen( showUp ? cg.light() : cg.dark() ); + p->setBrush( NoBrush ); + a.setPoints( QCOORDARRLEN(top_pts), top_pts ); + a.translate( r.x(), r.y() ); + p->drawPolyline( a ); + p->setPen( showUp ? cg.dark() : cg.light() ); + a.setPoints( QCOORDARRLEN(bottom_pts), bottom_pts ); + a.translate( r.x(), r.y() ); + p->drawPolyline( a ); + + break; + } + + case PE_ExclusiveIndicatorMask: + { + static QCOORD inner_pts[] = { // used for filling diamond + 0,r.height()/2, + r.width()/2,0, + r.width()-1,r.height()/2, + r.width()/2,r.height()-1 + }; + QPointArray a(QCOORDARRLEN(inner_pts), inner_pts); + p->setPen(color1); + p->setBrush(color1); + a.translate(r.x(), r.y()); + p->drawPolygon(a); + break; + } + + case PE_ArrowUp: + case PE_ArrowDown: + case PE_ArrowRight: + case PE_ArrowLeft: + { + QRect rect = r; + QPointArray bFill; + QPointArray bTop; + QPointArray bBot; + QPointArray bLeft; + bool vertical = pe == PE_ArrowUp || pe == PE_ArrowDown; + bool horizontal = !vertical; + int dim = rect.width() < rect.height() ? rect.width() : rect.height(); + int colspec = 0x0000; + + if ( dim < 2 ) + break; + + // adjust size and center (to fix rotation below) + if ( rect.width() > dim ) { + rect.setX( rect.x() + ((rect.width() - dim ) / 2) ); + rect.setWidth( dim ); + } + if ( rect.height() > dim ) { + rect.setY( rect.y() + ((rect.height() - dim ) / 2 )); + rect.setHeight( dim ); + } + + if ( dim > 3 ) { + if ( dim > 6 ) + bFill.resize( dim & 1 ? 3 : 4 ); + bTop.resize( (dim/2)*2 ); + bBot.resize( dim & 1 ? dim + 1 : dim ); + bLeft.resize( dim > 4 ? 4 : 2 ); + bLeft.putPoints( 0, 2, 0,0, 0,dim-1 ); + if ( dim > 4 ) + bLeft.putPoints( 2, 2, 1,2, 1,dim-3 ); + bTop.putPoints( 0, 4, 1,0, 1,1, 2,1, 3,1 ); + bBot.putPoints( 0, 4, 1,dim-1, 1,dim-2, 2,dim-2, 3,dim-2 ); + + for( int i=0; i 6 ) { // dim>6: must fill interior + bFill.putPoints( 0, 2, 1,dim-3, 1,2 ); + if ( dim & 1 ) // if size is an odd number + bFill.setPoint( 2, dim - 3, dim / 2 ); + else + bFill.putPoints( 2, 2, dim-4,dim/2-1, dim-4,dim/2 ); + } + } + else { + if ( dim == 3 ) { // 3x3 arrow pattern + bLeft.setPoints( 4, 0,0, 0,2, 1,1, 1,1 ); + bTop .setPoints( 2, 1,0, 1,0 ); + bBot .setPoints( 2, 1,2, 2,1 ); + } + else { // 2x2 arrow pattern + bLeft.setPoints( 2, 0,0, 0,1 ); + bTop .setPoints( 2, 1,0, 1,0 ); + bBot .setPoints( 2, 1,1, 1,1 ); + } + } + + // We use rot() and translate() as it is more efficient that + // matrix transformations on the painter, and because it still + // works with QT_NO_TRANSFORMATIONS defined. + + if ( pe == PE_ArrowUp || pe == PE_ArrowLeft ) { + if ( vertical ) { + rot(bFill,3); + rot(bLeft,3); + rot(bTop,3); + rot(bBot,3); + bFill.translate( 0, rect.height() - 1 ); + bLeft.translate( 0, rect.height() - 1 ); + bTop.translate( 0, rect.height() - 1 ); + bBot.translate( 0, rect.height() - 1 ); + } else { + rot(bFill,2); + rot(bLeft,2); + rot(bTop,2); + rot(bBot,2); + bFill.translate( rect.width() - 1, rect.height() - 1 ); + bLeft.translate( rect.width() - 1, rect.height() - 1 ); + bTop.translate( rect.width() - 1, rect.height() - 1 ); + bBot.translate( rect.width() - 1, rect.height() - 1 ); + } + if ( flags & Style_Down ) + colspec = horizontal ? 0x2334 : 0x2343; + else + colspec = horizontal ? 0x1443 : 0x1434; + } else { + if ( vertical ) { + rot(bFill,1); + rot(bLeft,1); + rot(bTop,1); + rot(bBot,1); + bFill.translate( rect.width() - 1, 0 ); + bLeft.translate( rect.width() - 1, 0 ); + bTop.translate( rect.width() - 1, 0 ); + bBot.translate( rect.width() - 1, 0 ); + } + if ( flags & Style_Down ) + colspec = horizontal ? 0x2443 : 0x2434; + else + colspec = horizontal ? 0x1334 : 0x1343; + } + bFill.translate( rect.x(), rect.y() ); + bLeft.translate( rect.x(), rect.y() ); + bTop.translate( rect.x(), rect.y() ); + bBot.translate( rect.x(), rect.y() ); + + QColor *cols[5]; + if ( flags & Style_Enabled ) { + cols[0] = 0; + cols[1] = (QColor *)&cg.button(); + cols[2] = (QColor *)&cg.mid(); + cols[3] = (QColor *)&cg.light(); + cols[4] = (QColor *)&cg.dark(); + } else { + cols[0] = 0; + cols[1] = (QColor *)&cg.button(); + cols[2] = (QColor *)&cg.button(); + cols[3] = (QColor *)&cg.button(); + cols[4] = (QColor *)&cg.button(); + } + +#define CMID *cols[ (colspec>>12) & 0xf ] +#define CLEFT *cols[ (colspec>>8) & 0xf ] +#define CTOP *cols[ (colspec>>4) & 0xf ] +#define CBOT *cols[ colspec & 0xf ] + + QPen savePen = p->pen(); + QBrush saveBrush = p->brush(); + QPen pen( NoPen ); + QBrush brush = cg.brush( flags & Style_Enabled ? QColorGroup::Button : + QColorGroup::Mid ); + p->setPen( pen ); + p->setBrush( brush ); + p->drawPolygon( bFill ); + p->setBrush( NoBrush ); + + p->setPen( CLEFT ); + p->drawLineSegments( bLeft ); + p->setPen( CTOP ); + p->drawLineSegments( bTop ); + p->setPen( CBOT ); + p->drawLineSegments( bBot ); + + p->setBrush( saveBrush ); + p->setPen( savePen ); +#undef CMID +#undef CLEFT +#undef CTOP +#undef CBOT + break; + } + + case PE_SpinWidgetPlus: + case PE_SpinWidgetMinus: + { + p->save(); + int fw = pixelMetric( PM_DefaultFrameWidth ); + QRect br; + br.setRect( r.x() + fw, r.y() + fw, r.width() - fw*2, + r.height() - fw*2 ); + + if ( flags & Style_Sunken ) + p->fillRect( r, cg.brush( QColorGroup::Dark ) ); + else + p->fillRect( r, cg.brush( QColorGroup::Button ) ); + + p->setPen( cg.buttonText() ); + p->setBrush( cg.buttonText() ); + + int length; + int x = r.x(), y = r.y(), w = r.width(), h = r.height(); + if ( w <= 8 || h <= 6 ) + length = QMIN( w-2, h-2 ); + else + length = QMIN( 2*w / 3, 2*h / 3 ); + + if ( !(length & 1) ) + length -=1; + int xmarg = ( w - length ) / 2; + int ymarg = ( h - length ) / 2; + + p->drawLine( x + xmarg, ( y + h / 2 - 1 ), + x + xmarg + length - 1, ( y + h / 2 - 1 ) ); + if ( pe == PE_SpinWidgetPlus ) + p->drawLine( ( x+w / 2 ) - 1, y + ymarg, + ( x+w / 2 ) - 1, y + ymarg + length - 1 ); + p->restore(); + break; + } + + case PE_SpinWidgetUp: + case PE_SpinWidgetDown: + { + p->save(); + int fw = pixelMetric( PM_DefaultFrameWidth ); + QRect br; + br.setRect( r.x() + fw, r.y() + fw, r.width() - fw*2, + r.height() - fw*2 ); + if ( flags & Style_Sunken ) + p->fillRect( br, cg.brush( QColorGroup::Mid ) ); + else + p->fillRect( br, cg.brush( QColorGroup::Button ) ); + + int x = r.x(), y = r.y(), w = r.width(), h = r.height(); + int sw = w-4; + if ( sw < 3 ) + return; + else if ( !(sw & 1) ) + sw--; + sw -= ( sw / 7 ) * 2; // Empty border + int sh = sw/2 + 2; // Must have empty row at foot of arrow + + int sx = x + w / 2 - sw / 2 - 1; + int sy = y + h / 2 - sh / 2 - 1; + + QPointArray a; + if ( pe == PE_SpinWidgetDown ) + a.setPoints( 3, 0, 1, sw-1, 1, sh-2, sh-1 ); + else + a.setPoints( 3, 0, sh-1, sw-1, sh-1, sh-2, 1 ); + int bsx = 0; + int bsy = 0; + if ( flags & Style_Sunken ) { + bsx = pixelMetric(PM_ButtonShiftHorizontal); + bsy = pixelMetric(PM_ButtonShiftVertical); + } + p->translate( sx + bsx, sy + bsy ); + p->setPen( cg.buttonText() ); + p->setBrush( cg.buttonText() ); + p->drawPolygon( a ); + p->restore(); + break; + } + + case PE_DockWindowHandle: + { + p->save(); + p->translate( r.x(), r.y() ); + + QColor dark( cg.dark() ); + QColor light( cg.light() ); + unsigned int i; + if ( flags & Style_Horizontal ) { + int h = r.height(); + if ( h > 6 ) { + if ( flags & Style_On ) + p->fillRect( 1, 1, 8, h - 2, cg.highlight() ); + QPointArray a( 2 * ((h-6)/3) ); + int y = 3 + (h%3)/2; + p->setPen( dark ); + p->drawLine( 8, 1, 8, h-2 ); + for( i=0; 2*i < a.size(); i ++ ) { + a.setPoint( 2*i, 5, y+1+3*i ); + a.setPoint( 2*i+1, 2, y+2+3*i ); + } + p->drawPoints( a ); + p->setPen( light ); + p->drawLine( 9, 1, 9, h-2 ); + for( i=0; 2*i < a.size(); i++ ) { + a.setPoint( 2*i, 4, y+3*i ); + a.setPoint( 2*i+1, 1, y+1+3*i ); + } + p->drawPoints( a ); + // if ( drawBorder ) { + // p->setPen( QPen( Qt::darkGray ) ); + // p->drawLine( 0, r.height() - 1, + // tbExtent, r.height() - 1 ); + // } + } + } else { + int w = r.width(); + if ( w > 6 ) { + if ( flags & Style_On ) + p->fillRect( 1, 1, w - 2, 9, cg.highlight() ); + QPointArray a( 2 * ((w-6)/3) ); + + int x = 3 + (w%3)/2; + p->setPen( dark ); + p->drawLine( 1, 8, w-2, 8 ); + for( i=0; 2*i < a.size(); i ++ ) { + a.setPoint( 2*i, x+1+3*i, 6 ); + a.setPoint( 2*i+1, x+2+3*i, 3 ); + } + p->drawPoints( a ); + p->setPen( light ); + p->drawLine( 1, 9, w-2, 9 ); + for( i=0; 2*i < a.size(); i++ ) { + a.setPoint( 2*i, x+3*i, 5 ); + a.setPoint( 2*i+1, x+1+3*i, 2 ); + } + p->drawPoints( a ); + // if ( drawBorder ) { + // p->setPen( QPen( Qt::darkGray ) ); + // p->drawLine( r.width() - 1, 0, + // r.width() - 1, tbExtent ); + // } + } + } + p->restore(); + break; + } + + case PE_Splitter: + if (flags & Style_Horizontal) + flags &= ~Style_Horizontal; + else + flags |= Style_Horizontal; + // fall through intended + + case PE_DockWindowResizeHandle: + { + const int motifOffset = 10; + int sw = pixelMetric( PM_SplitterWidth ); + if ( flags & Style_Horizontal ) { + QCOORD yPos = r.y() + r.height() / 2; + QCOORD kPos = r.width() - motifOffset - sw; + QCOORD kSize = sw - 2; + + qDrawShadeLine( p, 0, yPos, kPos, yPos, cg ); + qDrawShadePanel( p, kPos, yPos - sw / 2 + 1, kSize, kSize, + cg, FALSE, 1, &cg.brush( QColorGroup::Button ) ); + qDrawShadeLine( p, kPos + kSize - 1, yPos, r.width(), yPos, cg ); + } else { + QCOORD xPos = r.x() + r.width() / 2; + QCOORD kPos = motifOffset; + QCOORD kSize = sw - 2; + + qDrawShadeLine( p, xPos, kPos + kSize - 1, xPos, r.height(), cg ); + qDrawShadePanel( p, xPos - sw / 2 + 1, kPos, kSize, kSize, cg, + FALSE, 1, &cg.brush( QColorGroup::Button ) ); + qDrawShadeLine( p, xPos, 0, xPos, kPos, cg ); + } + break; + } + + case PE_CheckMark: + { + const int markW = 6; + const int markH = 6; + int posX = r.x() + ( r.width() - markW ) / 2 - 1; + int posY = r.y() + ( r.height() - markH ) / 2; + int dfw = pixelMetric(PM_DefaultFrameWidth); + + if (dfw < 2) { + // Could do with some optimizing/caching... + QPointArray a( 7*2 ); + int i, xx, yy; + xx = posX; + yy = 3 + posY; + for ( i=0; i<3; i++ ) { + a.setPoint( 2*i, xx, yy ); + a.setPoint( 2*i+1, xx, yy+2 ); + xx++; yy++; + } + yy -= 2; + for ( i=3; i<7; i++ ) { + a.setPoint( 2*i, xx, yy ); + a.setPoint( 2*i+1, xx, yy+2 ); + xx++; yy--; + } + if ( ! (flags & Style_Enabled) && ! (flags & Style_On) ) { + int pnt; + p->setPen( cg.highlightedText() ); + QPoint offset(1,1); + for ( pnt = 0; pnt < (int)a.size(); pnt++ ) + a[pnt] += offset; + p->drawLineSegments( a ); + for ( pnt = 0; pnt < (int)a.size(); pnt++ ) + a[pnt] -= offset; + } + p->setPen( cg.text() ); + p->drawLineSegments( a ); + + qDrawShadePanel( p, posX-2, posY-2, markW+4, markH+6, cg, TRUE, dfw); + } else + qDrawShadePanel( p, posX, posY, markW, markH, cg, TRUE, dfw, + &cg.brush( QColorGroup::Mid ) ); + + break; + } + + case PE_ScrollBarSubLine: + drawPrimitive(((flags & Style_Horizontal) ? PE_ArrowLeft : PE_ArrowUp), + p, r, cg, Style_Enabled | flags); + break; + + case PE_ScrollBarAddLine: + drawPrimitive(((flags & Style_Horizontal) ? PE_ArrowRight : PE_ArrowDown), + p, r, cg, Style_Enabled | flags); + break; + + case PE_ScrollBarSubPage: + case PE_ScrollBarAddPage: + p->fillRect(r, cg.brush(QColorGroup::Mid)); + break; + + case PE_ScrollBarSlider: + drawPrimitive(PE_ButtonBevel, p, r, cg, + (flags | Style_Raised) & ~Style_Down); + break; + + case PE_ProgressBarChunk: + p->fillRect( r.x(), r.y() + 2, r.width() - 2, + r.height() - 4, cg.brush(QColorGroup::Highlight)); + break; + + default: + QCommonStyle::drawPrimitive( pe, p, r, cg, flags, opt ); + break; + } +} + + +/*!\reimp +*/ +void QMotifStyle::drawControl( ControlElement element, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QColorGroup &cg, + SFlags flags, + const QStyleOption& opt ) const +{ + switch( element ) { + case CE_PushButton: + { +#ifndef QT_NO_PUSHBUTTON + int diw, x1, y1, x2, y2; + const QPushButton *btn; + QColorGroup newCg = cg; + btn = ( const QPushButton * )widget; + p->setPen( cg.foreground() ); + p->setBrush( QBrush( cg.button(), NoBrush ) ); + diw = pixelMetric( PM_ButtonDefaultIndicator ); + r.coords( &x1, &y1, &x2, &y2 ); + if ( btn->isDefault() || btn->autoDefault() ) { + x1 += diw; + y1 += diw; + x2 -= diw; + y2 -= diw; + } + QBrush fill; + if ( btn->isDown() ) + fill = newCg.brush( QColorGroup::Mid ); + else if ( btn->isOn() ) + fill = QBrush( newCg.mid(), Dense4Pattern ); + else + fill = newCg.brush( QColorGroup::Button ); + + newCg.setBrush( QColorGroup::Button, fill ); + if ( btn->isDefault() ) { + if ( diw == 0 ) { + QPointArray a; + a.setPoints( 9, + x1, y1, x2, y1, x2, y2, x1, y2, x1, y1+1, + x2-1, y1+1, x2-1, y2-1, x1+1, y2-1, x1+1, y1+1 ); + p->setPen( newCg.shadow() ); + p->drawPolygon( a ); + x1 += 2; + y1 += 2; + x2 -= 2; + y2 -= 2; + } else { + qDrawShadePanel( p, r, newCg, TRUE ); + } + } + if ( !btn->isFlat() || btn->isOn() || btn->isDown() ) { + QRect tmp( x1, y1, x2 - x1 + 1, y2 - y1 + 1 ); + SFlags flags = Style_Default; + if ( btn->isOn()) + flags |= Style_On; + if (btn->isDown()) + flags |= Style_Down; + p->save(); + p->setBrushOrigin( -widget->backgroundOffset().x(), + -widget->backgroundOffset().y() ); + drawPrimitive( PE_ButtonCommand, p, + tmp, newCg, + flags ); + p->restore(); + } + if ( p->brush().style() != NoBrush ) + p->setBrush( NoBrush ); +#endif + break; + } + + case CE_TabBarTab: + { +#ifndef QT_NO_TABBAR + if ( !widget || !widget->parentWidget() || !opt.tab() ) + break; + + const QTabBar * tb = (const QTabBar *) widget; + const QTab * t = opt.tab(); + + int dfw = pixelMetric( PM_DefaultFrameWidth, tb ); + bool selected = flags & Style_Selected; + int o = dfw > 1 ? 1 : 0; + bool lastTab = FALSE; + + QRect r2( r ); + if ( tb->shape() == QTabBar::RoundedAbove ) { + if ( styleHint( SH_TabBar_Alignment, tb ) == AlignRight && + tb->indexOf( t->identifier() ) == tb->count()-1 ) + lastTab = TRUE; + + if ( o ) { + p->setPen( tb->colorGroup().light() ); + p->drawLine( r2.left(), r2.bottom(), r2.right(), r2.bottom() ); + p->setPen( tb->colorGroup().light() ); + p->drawLine( r2.left(), r2.bottom()-1, r2.right(), r2.bottom()-1 ); + if ( r2.left() == 0 ) + p->drawPoint( tb->rect().bottomLeft() ); + } + else { + p->setPen( tb->colorGroup().light() ); + p->drawLine( r2.left(), r2.bottom(), r2.right(), r2.bottom() ); + } + + if ( selected ) { + p->fillRect( QRect( r2.left()+1, r2.bottom()-o, r2.width()-3, 2), + tb->palette().active().brush( QColorGroup::Background )); + p->setPen( tb->colorGroup().background() ); + // p->drawLine( r2.left()+1, r2.bottom(), r2.right()-2, r2.bottom() ); + // if (o) + // p->drawLine( r2.left()+1, r2.bottom()-1, r2.right()-2, r2.bottom()-1 ); + p->drawLine( r2.left()+1, r2.bottom(), r2.left()+1, r2.top()+2 ); + p->setPen( tb->colorGroup().light() ); + } else { + p->setPen( tb->colorGroup().light() ); + r2.setRect( r2.left() + 2, r2.top() + 2, + r2.width() - 4, r2.height() - 2 ); + } + + p->drawLine( r2.left(), r2.bottom()-1, r2.left(), r2.top() + 2 ); + p->drawPoint( r2.left()+1, r2.top() + 1 ); + p->drawLine( r2.left()+2, r2.top(), + r2.right() - 2, r2.top() ); + p->drawPoint( r2.left(), r2.bottom()); + + if ( o ) { + p->drawLine( r2.left()+1, r2.bottom(), r2.left()+1, r2.top() + 2 ); + p->drawLine( r2.left()+2, r2.top()+1, + r2.right() - 2, r2.top()+1 ); + } + + p->setPen( tb->colorGroup().dark() ); + p->drawLine( r2.right() - 1, r2.top() + 2, + r2.right() - 1, r2.bottom() - 1 + (selected ? o : -o)); + if ( o ) { + p->drawPoint( r2.right() - 1, r2.top() + 1 ); + p->drawLine( r2.right(), r2.top() + 2, r2.right(), + r2.bottom() - + (selected ? (lastTab ? 0:1):1+o)); + p->drawPoint( r2.right() - 1, r2.top() + 1 ); + } + } else if ( tb->shape() == QTabBar::RoundedBelow ) { + if ( styleHint( SH_TabBar_Alignment, tb ) == AlignLeft && + tb->indexOf( t->identifier() ) == tb->count()-1 ) + lastTab = TRUE; + if ( selected ) { + p->fillRect( QRect( r2.left()+1, r2.top(), r2.width()-3, 1), + tb->palette().active().brush( QColorGroup::Background )); + p->setPen( tb->colorGroup().background() ); + // p->drawLine( r2.left()+1, r2.top(), r2.right()-2, r2.top() ); + p->drawLine( r2.left()+1, r2.top(), r2.left()+1, r2.bottom()-2 ); + p->setPen( tb->colorGroup().dark() ); + } else { + p->setPen( tb->colorGroup().dark() ); + p->drawLine( r2.left(), r2.top(), r2.right(), r2.top() ); + p->drawLine( r2.left() + 1, r2.top() + 1, + r2.right() - (lastTab ? 0 : 2), + r2.top() + 1 ); + r2.setRect( r2.left() + 2, r2.top(), + r2.width() - 4, r2.height() - 2 ); + } + + p->drawLine( r2.right() - 1, r2.top(), + r2.right() - 1, r2.bottom() - 2 ); + p->drawPoint( r2.right() - 2, r2.bottom() - 2 ); + p->drawLine( r2.right() - 2, r2.bottom() - 1, + r2.left() + 1, r2.bottom() - 1 ); + p->drawPoint( r2.left() + 1, r2.bottom() - 2 ); + + if (dfw > 1) { + p->drawLine( r2.right(), r2.top(), + r2.right(), r2.bottom() - 1 ); + p->drawPoint( r2.right() - 1, r2.bottom() - 1 ); + p->drawLine( r2.right() - 1, r2.bottom(), + r2.left() + 2, r2.bottom() ); + } + + p->setPen( tb->colorGroup().light() ); + p->drawLine( r2.left(), r2.top() + (selected ? 0 : 2), + r2.left(), r2.bottom() - 2 ); + p->drawLine( r2.left() + 1, r2.top() + (selected ? 0 : 2), + r2.left() + 1, r2.bottom() - 3 ); + + } else { + QCommonStyle::drawControl( element, p, widget, r, cg, flags, opt ); + } +#endif + break; + } + + case CE_ProgressBarGroove: + qDrawShadePanel(p, r, cg, TRUE, 2); + break; + + case CE_ProgressBarLabel: + { +#ifndef QT_NO_PROGRESSBAR + const QProgressBar * pb = (const QProgressBar *) widget; + const int unit_width = pixelMetric( PM_ProgressBarChunkWidth, pb ); + int u = r.width() / unit_width; + int p_v = pb->progress(); + int t_s = pb->totalSteps(); + if ( u > 0 && pb->progress() >= INT_MAX / u && t_s >= u ) { + // scale down to something usable. + p_v /= u; + t_s /= u; + } + if ( pb->percentageVisible() && pb->totalSteps() ) { + int nu = ( u * p_v + t_s/2 ) / t_s; + int x = unit_width * nu; + if (pb->indicatorFollowsStyle() || pb->centerIndicator()) { + p->setPen( cg.highlightedText() ); + p->setClipRect( r.x(), r.y(), x, r.height() ); + p->drawText( r, AlignCenter | SingleLine, pb->progressString() ); + + if ( pb->progress() != pb->totalSteps() ) { + p->setClipRect( r.x() + x, r.y(), r.width() - x, r.height() ); + p->setPen( cg.highlight() ); + p->drawText( r, AlignCenter | SingleLine, pb->progressString() ); + } + } else { + p->setPen( cg.text() ); + p->drawText( r, AlignCenter | SingleLine, pb->progressString() ); + } + } +#endif + break; + } + +#ifndef QT_NO_POPUPMENU + case CE_PopupMenuItem: + { + if (! widget || opt.isDefault()) + break; + + const QPopupMenu *popupmenu = (const QPopupMenu *) widget; + QMenuItem *mi = opt.menuItem(); + if ( !mi ) + break; + + int tab = opt.tabWidth(); + int maxpmw = opt.maxIconWidth(); + bool dis = ! (flags & Style_Enabled); + bool checkable = popupmenu->isCheckable(); + bool act = flags & Style_Active; + int x, y, w, h; + + r.rect(&x, &y, &w, &h); + + if ( checkable ) + maxpmw = QMAX( maxpmw, motifCheckMarkSpace ); + + int checkcol = maxpmw; + + if ( mi && mi->isSeparator() ) { // draw separator + p->setPen( cg.dark() ); + p->drawLine( x, y, x+w, y ); + p->setPen( cg.light() ); + p->drawLine( x, y+1, x+w, y+1 ); + return; + } + + int pw = motifItemFrame; + + if ( act && !dis ) { // active item frame + if (pixelMetric( PM_DefaultFrameWidth ) > 1) + qDrawShadePanel( p, x, y, w, h, cg, FALSE, pw, + &cg.brush( QColorGroup::Button ) ); + else + qDrawShadePanel( p, x+1, y+1, w-2, h-2, cg, TRUE, 1, + &cg.brush( QColorGroup::Button ) ); + } + else // incognito frame + p->fillRect(x, y, w, h, cg.brush( QColorGroup::Button )); + + if ( !mi ) + return; + + QRect vrect = visualRect( QRect( x+motifItemFrame, y+motifItemFrame, checkcol, h-2*motifItemFrame ), r ); + int xvis = vrect.x(); + if ( mi->isChecked() ) { + if ( mi->iconSet() ) { + qDrawShadePanel( p, xvis, y+motifItemFrame, checkcol, h-2*motifItemFrame, + cg, TRUE, 1, &cg.brush( QColorGroup::Midlight ) ); + } + } else if ( !act ) { + p->fillRect(xvis, y+motifItemFrame, checkcol, h-2*motifItemFrame, + cg.brush( QColorGroup::Button )); + } + + if ( mi->iconSet() ) { // draw iconset + QIconSet::Mode mode = QIconSet::Normal; // no disabled icons in Motif + if (act && !dis ) + mode = QIconSet::Active; + QPixmap pixmap; + if ( checkable && mi->isChecked() ) + pixmap = mi->iconSet()->pixmap( QIconSet::Small, mode, QIconSet::On ); + else + pixmap = mi->iconSet()->pixmap( QIconSet::Small, mode ); + + int pixw = pixmap.width(); + int pixh = pixmap.height(); + QRect pmr( 0, 0, pixw, pixh ); + pmr.moveCenter( vrect.center() ); + p->setPen( cg.text() ); + p->drawPixmap( pmr.topLeft(), pixmap ); + + } else if ( checkable ) { // just "checking"... + int mw = checkcol; + int mh = h - 2*motifItemFrame; + if ( mi->isChecked() ) { + SFlags cflags = Style_Default; + if (! dis) + cflags |= Style_Enabled; + if (act) + cflags |= Style_On; + + drawPrimitive(PE_CheckMark, p, + QRect(xvis, y+motifItemFrame, mw, mh), + cg, cflags); + } + } + + + p->setPen( cg.buttonText() ); + + QColor discol; + if ( dis ) { + discol = cg.text(); + p->setPen( discol ); + } + + int xm = motifItemFrame + checkcol + motifItemHMargin; + + vrect = visualRect( QRect( x+xm, y+motifItemVMargin, w-xm-tab, h-2*motifItemVMargin ), r ); + xvis = vrect.x(); + if ( mi->custom() ) { + int m = motifItemVMargin; + p->save(); + mi->custom()->paint( p, cg, act, !dis, + xvis, y+m, w-xm-tab+1, h-2*m ); + p->restore(); + } + QString s = mi->text(); + if ( !s.isNull() ) { // draw text + int t = s.find( '\t' ); + int m = motifItemVMargin; + int text_flags = AlignVCenter|ShowPrefix | DontClip | SingleLine; + text_flags |= (QApplication::reverseLayout() ? AlignRight : AlignLeft ); + if ( t >= 0 ) { // draw tab text + QRect vr = visualRect( QRect( x+w-tab-motifItemHMargin-motifItemFrame, + y+motifItemVMargin, tab, h-2*motifItemVMargin ), r ); + int xv = vr.x(); + p->drawText( xv, y+m, tab, h-2*m, text_flags, s.mid( t+1 ) ); + s = s.left( t ); + } + p->drawText( xvis, y+m, w-xm-tab+1, h-2*m, text_flags, s, t ); + } else if ( mi->pixmap() ) { // draw pixmap + QPixmap *pixmap = mi->pixmap(); + if ( pixmap->depth() == 1 ) + p->setBackgroundMode( OpaqueMode ); + p->drawPixmap( xvis, y+motifItemFrame, *pixmap ); + if ( pixmap->depth() == 1 ) + p->setBackgroundMode( TransparentMode ); + } + if ( mi->popup() ) { // draw sub menu arrow + int dim = (h-2*motifItemFrame) / 2; + QStyle::PrimitiveElement arrow = (QApplication::reverseLayout() ? PE_ArrowLeft : PE_ArrowRight); + QRect vr = visualRect( QRect(x+w - motifArrowHMargin - motifItemFrame - dim, + y+h/2-dim/2, dim, dim), r ); + if ( act ) + drawPrimitive(arrow, p, vr, cg, + (Style_Down | + (dis ? Style_Default : Style_Enabled)) ); + else + drawPrimitive(arrow, p, vr, cg, + (dis ? Style_Default : Style_Enabled)); + } + + break; + } +#endif // QT_NO_POPUPMENU + + case CE_MenuBarItem: + { + if ( flags & Style_Active ) // active item + qDrawShadePanel( p, r, cg, FALSE, motifItemFrame, + &cg.brush(QColorGroup::Button) ); + else // other item + p->fillRect( r, cg.brush(QColorGroup::Button) ); + QCommonStyle::drawControl( element, p, widget, r, cg, flags, opt ); + break; + } + + default: + QCommonStyle::drawControl( element, p, widget, r, cg, flags, opt ); + break; + } +} + +static int get_combo_extra_width( int h, int w, int *return_awh=0 ) +{ + int awh, + tmp; + if ( h < 8 ) { + awh = 6; + } else if ( h < 14 ) { + awh = h - 2; + } else { + awh = h/2; + } + tmp = (awh * 3) / 2; + if ( tmp > w / 2 ) { + awh = w / 2 - 3; + tmp = w / 2 + 3; + } + + if ( return_awh ) + *return_awh = awh; + + return tmp; +} + +static void get_combo_parameters( const QRect &r, + int &ew, int &awh, int &ax, + int &ay, int &sh, int &dh, + int &sy ) +{ + ew = get_combo_extra_width( r.height(), r.width(), &awh ); + + sh = (awh+3)/4; + if ( sh < 3 ) + sh = 3; + dh = sh/2 + 1; + + ay = r.y() + (r.height()-awh-sh-dh)/2; + if ( ay < 0 ) { + //panic mode + ay = 0; + sy = r.height(); + } else { + sy = ay+awh+dh; + } + ax = r.x() + r.width() - ew; + ax += (ew-awh)/2; +} + +/*!\reimp +*/ +void QMotifStyle::drawComplexControl( ComplexControl control, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QColorGroup &cg, + SFlags flags, + SCFlags sub, + SCFlags subActive, + const QStyleOption& opt ) const +{ + switch ( control ) { + case CC_SpinWidget: { + SCFlags drawSub = SC_None; + if ( sub & SC_SpinWidgetFrame ) + qDrawShadePanel( p, r, cg, TRUE, + pixelMetric( PM_DefaultFrameWidth) ); + + if ( sub & SC_SpinWidgetUp || sub & SC_SpinWidgetDown ) { + if ( sub & SC_SpinWidgetUp ) + drawSub |= SC_SpinWidgetUp; + if ( sub & SC_SpinWidgetDown ) + drawSub |= SC_SpinWidgetDown; + + QCommonStyle::drawComplexControl( control, p, widget, r, cg, flags, + drawSub, subActive, opt ); + } + break; } + + case CC_Slider: + { +#ifndef QT_NO_SLIDER + const QSlider * slider = (const QSlider *) widget; + + QRect groove = querySubControlMetrics(CC_Slider, widget, SC_SliderGroove, + opt), + handle = querySubControlMetrics(CC_Slider, widget, SC_SliderHandle, + opt); + + if ((sub & SC_SliderGroove) && groove.isValid()) { + qDrawShadePanel( p, groove, cg, TRUE, 2, + &cg.brush( QColorGroup::Mid ) ); + + + if ( flags & Style_HasFocus ) { + QRect fr = subRect( SR_SliderFocusRect, widget ); + drawPrimitive( PE_FocusRect, p, fr, cg ); + } + } + + if (( sub & SC_SliderHandle ) && handle.isValid()) { + drawPrimitive( PE_ButtonBevel, p, handle, cg ); + + if ( slider->orientation() == Horizontal ) { + QCOORD mid = handle.x() + handle.width() / 2; + qDrawShadeLine( p, mid, handle.y(), mid, + handle.y() + handle.height() - 2, + cg, TRUE, 1); + } else { + QCOORD mid = handle.y() + handle.height() / 2; + qDrawShadeLine( p, handle.x(), mid, + handle.x() + handle.width() - 2, mid, + cg, TRUE, 1); + } + } + + if ( sub & SC_SliderTickmarks ) + QCommonStyle::drawComplexControl( control, p, widget, r, cg, flags, + SC_SliderTickmarks, subActive, + opt ); +#endif + break; + } + + case CC_ComboBox: +#ifndef QT_NO_COMBOBOX + if ( sub & SC_ComboBoxArrow ) { + const QComboBox * cb = (const QComboBox *) widget; + int awh, ax, ay, sh, sy, dh, ew; + int fw = pixelMetric( PM_DefaultFrameWidth, cb); + + drawPrimitive( PE_ButtonCommand, p, r, cg, flags ); + QRect ar = QStyle::visualRect( querySubControlMetrics( CC_ComboBox, cb, SC_ComboBoxArrow, + opt ), cb ); + drawPrimitive( PE_ArrowDown, p, ar, cg, flags | Style_Enabled ); + + QRect tr = r; + tr.addCoords( fw, fw, -fw, -fw ); + get_combo_parameters( tr, ew, awh, ax, ay, sh, dh, sy ); + + // draws the shaded line under the arrow + p->setPen( cg.light() ); + p->drawLine( ar.x(), sy, ar.x()+awh-1, sy ); + p->drawLine( ar.x(), sy, ar.x(), sy+sh-1 ); + p->setPen( cg.dark() ); + p->drawLine( ar.x()+1, sy+sh-1, ar.x()+awh-1, sy+sh-1 ); + p->drawLine( ar.x()+awh-1, sy+1, ar.x()+awh-1, sy+sh-1 ); + + if ( cb->hasFocus() ) { + QRect re = QStyle::visualRect( subRect( SR_ComboBoxFocusRect, cb ), cb ); + drawPrimitive( PE_FocusRect, p, re, cg ); + } + } + + if ( sub & SC_ComboBoxEditField ) { + QComboBox * cb = (QComboBox *) widget; + if ( cb->editable() ) { + QRect er = QStyle::visualRect( querySubControlMetrics( CC_ComboBox, cb, + SC_ComboBoxEditField ), cb ); + er.addCoords( -1, -1, 1, 1); + qDrawShadePanel( p, er, cg, TRUE, 1, + &cg.brush( QColorGroup::Button )); + } + } +#endif + p->setPen(cg.buttonText()); + break; + + case CC_ScrollBar: + { + if (sub == (SC_ScrollBarAddLine | SC_ScrollBarSubLine | SC_ScrollBarAddPage | + SC_ScrollBarSubPage | SC_ScrollBarFirst | SC_ScrollBarLast | + SC_ScrollBarSlider)) + qDrawShadePanel(p, widget->rect(), cg, TRUE, + pixelMetric(PM_DefaultFrameWidth, widget), + &cg.brush(QColorGroup::Mid)); + QCommonStyle::drawComplexControl(control, p, widget, r, cg, flags, sub, + subActive, opt); + break; + } + +#ifndef QT_NO_LISTVIEW + case CC_ListView: + { + if ( sub & SC_ListView ) { + QCommonStyle::drawComplexControl( control, p, widget, r, cg, flags, sub, subActive, opt ); + } + if ( sub & ( SC_ListViewBranch | SC_ListViewExpand ) ) { + if (opt.isDefault()) + break; + + QListViewItem *item = opt.listViewItem(); + QListViewItem *child = item->firstChild(); + + int y = r.y(); + int c; + QPointArray dotlines; + if ( subActive == (uint)SC_All && sub == SC_ListViewExpand ) { + c = 2; + dotlines.resize(2); + dotlines[0] = QPoint( r.right(), r.top() ); + dotlines[1] = QPoint( r.right(), r.bottom() ); + } else { + int linetop = 0, linebot = 0; + // each branch needs at most two lines, ie. four end points + dotlines.resize( item->childCount() * 4 ); + c = 0; + + // skip the stuff above the exposed rectangle + while ( child && y + child->height() <= 0 ) { + y += child->totalHeight(); + child = child->nextSibling(); + } + + int bx = r.width() / 2; + + // paint stuff in the magical area + QListView* v = item->listView(); + while ( child && y < r.height() ) { + if (child->isVisible()) { + int lh; + if ( !item->multiLinesEnabled() ) + lh = child->height(); + else + lh = p->fontMetrics().height() + 2 * v->itemMargin(); + lh = QMAX( lh, QApplication::globalStrut().height() ); + if ( lh % 2 > 0 ) + lh++; + linebot = y + lh/2; + if ( (child->isExpandable() || child->childCount()) && + (child->height() > 0) ) { + // needs a box + p->setPen( cg.text() ); + p->drawRect( bx-4, linebot-4, 9, 9 ); + QPointArray a; + if ( child->isOpen() ) + a.setPoints( 3, bx-2, linebot-2, + bx, linebot+2, + bx+2, linebot-2 ); //RightArrow + else + a.setPoints( 3, bx-2, linebot-2, + bx+2, linebot, + bx-2, linebot+2 ); //DownArrow + p->setBrush( cg.text() ); + p->drawPolygon( a ); + p->setBrush( NoBrush ); + // dotlinery + dotlines[c++] = QPoint( bx, linetop ); + dotlines[c++] = QPoint( bx, linebot - 5 ); + dotlines[c++] = QPoint( bx + 5, linebot ); + dotlines[c++] = QPoint( r.width(), linebot ); + linetop = linebot + 5; + } else { + // just dotlinery + dotlines[c++] = QPoint( bx+1, linebot ); + dotlines[c++] = QPoint( r.width(), linebot ); + } + y += child->totalHeight(); + } + child = child->nextSibling(); + } + + // Expand line height to edge of rectangle if there's any + // visible child below + while ( child && child->height() <= 0) + child = child->nextSibling(); + if ( child ) + linebot = r.height(); + + if ( linetop < linebot ) { + dotlines[c++] = QPoint( bx, linetop ); + dotlines[c++] = QPoint( bx, linebot ); + } + } + + int line; // index into dotlines + p->setPen( cg.text() ); + if ( sub & SC_ListViewBranch ) for( line = 0; line < c; line += 2 ) { + p->drawLine( dotlines[line].x(), dotlines[line].y(), + dotlines[line+1].x(), dotlines[line+1].y() ); + } + } + + break; + } +#endif // QT_NO_LISTVIEW + + default: + QCommonStyle::drawComplexControl( control, p, widget, r, cg, flags, + sub, subActive, opt ); + } +} + + +/*! \reimp */ +int QMotifStyle::pixelMetric( PixelMetric metric, const QWidget *widget ) const +{ + int ret; + + switch( metric ) { + case PM_ButtonDefaultIndicator: + ret = 3; + break; + + case PM_ButtonShiftHorizontal: + case PM_ButtonShiftVertical: + ret = 0; + break; + + case PM_SplitterWidth: + ret = QMAX( 10, QApplication::globalStrut().width() ); + break; + + case PM_SliderLength: + ret = 30; + break; + + case PM_SliderThickness: + ret = 24; + break; + + case PM_SliderControlThickness: + { +#ifndef QT_NO_SLIDER + const QSlider * sl = (const QSlider *) widget; + int space = (sl->orientation() == Horizontal) ? sl->height() + : sl->width(); + int ticks = sl->tickmarks(); + int n = 0; + if ( ticks & QSlider::Above ) n++; + if ( ticks & QSlider::Below ) n++; + if ( !n ) { + ret = space; + break; + } + + int thick = 6; // Magic constant to get 5 + 16 + 5 + + space -= thick; + //### the two sides may be unequal in size + if ( space > 0 ) + thick += (space * 2) / (n + 2); + ret = thick; +#endif + break; + } + + case PM_SliderSpaceAvailable: + { +#ifndef QT_NO_SLIDER + const QSlider * sl = (const QSlider *) widget; + if ( sl->orientation() == Horizontal ) + ret = sl->width() - pixelMetric( PM_SliderLength, sl ) - 6; + else + ret = sl->height() - pixelMetric( PM_SliderLength, sl ) - 6; +#endif + break; + } + + case PM_DockWindowHandleExtent: + ret = 9; + break; + + case PM_ProgressBarChunkWidth: + ret = 1; + break; + + case PM_ExclusiveIndicatorWidth: + case PM_ExclusiveIndicatorHeight: + ret = 13; + break; + + default: + ret = QCommonStyle::pixelMetric( metric, widget ); + break; + } + return ret; +} + + +/*!\reimp +*/ +QRect QMotifStyle::querySubControlMetrics( ComplexControl control, + const QWidget *widget, + SubControl sc, + const QStyleOption& opt ) const +{ + switch ( control ) { + case CC_SpinWidget: { + if ( !widget ) + return QRect(); + int fw = pixelMetric( PM_SpinBoxFrameWidth, 0 ); + QSize bs; + bs.setHeight( widget->height()/2 ); + if ( bs.height() < 8 ) + bs.setHeight( 8 ); + bs.setWidth( QMIN( bs.height() * 8 / 5, widget->width() / 4 ) ); // 1.6 -approximate golden mean + bs = bs.expandedTo( QApplication::globalStrut() ); + int y = 0; + int x, lx, rx; + x = widget->width() - y - bs.width(); + lx = fw; + rx = x - fw * 2; + switch ( sc ) { + case SC_SpinWidgetUp: + return QRect(x, y, bs.width(), bs.height()); + case SC_SpinWidgetDown: + return QRect(x, y + bs.height(), bs.width(), bs.height()); + case SC_SpinWidgetButtonField: + return QRect(x, y, bs.width(), widget->height() - 2*fw); + case SC_SpinWidgetEditField: + return QRect(lx, fw, rx, widget->height() - 2*fw); + case SC_SpinWidgetFrame: + return QRect( 0, 0, + widget->width() - bs.width(), widget->height() ); + default: + break; + } + break; } + +#ifndef QT_NO_SLIDER + case CC_Slider: { + if (sc == SC_SliderHandle) { + const QSlider * sl = (const QSlider *) widget; + int tickOffset = pixelMetric( PM_SliderTickmarkOffset, sl ); + int thickness = pixelMetric( PM_SliderControlThickness, sl ); + int sliderPos = sl->sliderStart(); + int len = pixelMetric( PM_SliderLength, sl ); + int motifBorder = 3; + + if ( sl->orientation() == Horizontal ) + return QRect( sliderPos + motifBorder, tickOffset + motifBorder, len, + thickness - 2*motifBorder ); + return QRect( tickOffset + motifBorder, sliderPos + motifBorder, + thickness - 2*motifBorder, len ); + } + break; } +#endif + +#ifndef QT_NO_SCROLLBAR + case CC_ScrollBar: { + if (! widget) + return QRect(); + + const QScrollBar *scrollbar = (const QScrollBar *) widget; + int sliderstart = scrollbar->sliderStart(); + int sbextent = pixelMetric(PM_ScrollBarExtent, widget); + int fw = pixelMetric(PM_DefaultFrameWidth, widget); + int buttonw = sbextent - (fw * 2); + int buttonh = sbextent - (fw * 2); + int maxlen = ((scrollbar->orientation() == Qt::Horizontal) ? + scrollbar->width() : scrollbar->height()) - + (buttonw * 2) - (fw * 2); + int sliderlen; + + // calculate slider length + if (scrollbar->maxValue() != scrollbar->minValue()) { + uint range = scrollbar->maxValue() - scrollbar->minValue(); + sliderlen = (scrollbar->pageStep() * maxlen) / + (range + scrollbar->pageStep()); + + if ( sliderlen < 9 || range > INT_MAX/2 ) + sliderlen = 9; + if ( sliderlen > maxlen ) + sliderlen = maxlen; + } else + sliderlen = maxlen; + + switch (sc) { + case SC_ScrollBarSubLine: + // top/left button + if (scrollbar->orientation() == Qt::Horizontal) { + if ( scrollbar->width()/2 < sbextent ) + buttonw = scrollbar->width()/2 - (fw*2); + return QRect(fw, fw, buttonw, buttonh); + } else { + if ( scrollbar->height()/2 < sbextent ) + buttonh = scrollbar->height()/2 - (fw*2); + return QRect(fw, fw, buttonw, buttonh); + } + case SC_ScrollBarAddLine: + // bottom/right button + if (scrollbar->orientation() == Qt::Horizontal) { + if ( scrollbar->width()/2 < sbextent ) + buttonw = scrollbar->width()/2 - (fw*2); + return QRect(scrollbar->width() - buttonw - fw, fw, + buttonw, buttonh); + } else { + if ( scrollbar->height()/2 < sbextent ) + buttonh = scrollbar->height()/2 - (fw*2); + return QRect(fw, scrollbar->height() - buttonh - fw, + buttonw, buttonh); + } + case SC_ScrollBarSubPage: + if (scrollbar->orientation() == Qt::Horizontal) + return QRect(buttonw + fw, fw, sliderstart - buttonw - fw, buttonw); + return QRect(fw, buttonw + fw, buttonw, sliderstart - buttonw - fw); + + case SC_ScrollBarAddPage: + if (scrollbar->orientation() == Qt::Horizontal) + return QRect(sliderstart + sliderlen, fw, + maxlen - sliderstart - sliderlen + buttonw + fw, buttonw); + return QRect(fw, sliderstart + sliderlen, buttonw, + maxlen - sliderstart - sliderlen + buttonw + fw); + + case SC_ScrollBarGroove: + if (scrollbar->orientation() == Qt::Horizontal) + return QRect(buttonw + fw, fw, maxlen, buttonw); + return QRect(fw, buttonw + fw, buttonw, maxlen); + + case SC_ScrollBarSlider: + if (scrollbar->orientation() == Qt::Horizontal) + return QRect(sliderstart, fw, sliderlen, buttonw); + return QRect(fw, sliderstart, buttonw, sliderlen); + + default: + break; + } + break; } +#endif + +#ifndef QT_NO_COMBOBOX + case CC_ComboBox: + + switch ( sc ) { + case SC_ComboBoxArrow: { + const QComboBox * cb = (const QComboBox *) widget; + int ew, awh, sh, dh, ax, ay, sy; + int fw = pixelMetric( PM_DefaultFrameWidth, cb ); + QRect cr = cb->rect(); + cr.addCoords( fw, fw, -fw, -fw ); + get_combo_parameters( cr, ew, awh, ax, ay, sh, dh, sy ); + return QRect( ax, ay, awh, awh ); } + + case SC_ComboBoxEditField: { + const QComboBox * cb = (const QComboBox *) widget; + int fw = pixelMetric( PM_DefaultFrameWidth, cb ); + QRect rect = cb->rect(); + rect.addCoords( fw, fw, -fw, -fw ); + int ew = get_combo_extra_width( rect.height(), rect.width() ); + rect.addCoords( 1, 1, -1-ew, -1 ); + return rect; } + + default: + break; + } + break; +#endif + default: break; + } + return QCommonStyle::querySubControlMetrics( control, widget, sc, opt ); +} + +/*!\reimp +*/ +QSize QMotifStyle::sizeFromContents( ContentsType contents, + const QWidget *widget, + const QSize &contentsSize, + const QStyleOption& opt ) const +{ + QSize sz(contentsSize); + + switch(contents) { + case CT_PushButton: + { +#ifndef QT_NO_PUSHBUTTON + const QPushButton *button = (const QPushButton *) widget; + sz = QCommonStyle::sizeFromContents(contents, widget, contentsSize, opt); + if ((button->isDefault() || button->autoDefault()) && + sz.width() < 80 && ! button->pixmap()) + sz.setWidth(80); +#endif + break; + } + + case CT_PopupMenuItem: + { +#ifndef QT_NO_POPUPMENU + if (! widget || opt.isDefault()) + break; + + const QPopupMenu *popup = (QPopupMenu *) widget; + bool checkable = popup->isCheckable(); + QMenuItem *mi = opt.menuItem(); + int maxpmw = opt.maxIconWidth(); + int w = sz.width(), h = sz.height(); + + if (mi->custom()) { + w = mi->custom()->sizeHint().width(); + h = mi->custom()->sizeHint().height(); + if (! mi->custom()->fullSpan()) + h += 2*motifItemVMargin + 2*motifItemFrame; + } else if ( mi->widget() ) { + } else if ( mi->isSeparator() ) { + w = 10; + h = motifSepHeight; + } else if (mi->pixmap() || ! mi->text().isNull()) + h += 2*motifItemVMargin + 2*motifItemFrame; + + // a little bit of border can never harm + w += 2*motifItemHMargin + 2*motifItemFrame; + + if ( !mi->text().isNull() && mi->text().find('\t') >= 0 ) + // string contains tab + w += motifTabSpacing; + else if (mi->popup()) + // submenu indicator needs some room if we don't have a tab column + w += motifArrowHMargin + 4*motifItemFrame; + + if ( checkable && maxpmw <= 0) + // if we are checkable and have no iconsets, add space for a checkmark + w += motifCheckMarkSpace; + else if (checkable && maxpmw < motifCheckMarkSpace) + // make sure the check-column is wide enough if we have iconsets + w += (motifCheckMarkSpace - maxpmw); + + // if we have a check-column ( iconsets of checkmarks), add space + // to separate the columns + if ( maxpmw > 0 || checkable ) + w += motifCheckMarkHMargin; + + sz = QSize(w, h); +#endif + break; + } + + default: + sz = QCommonStyle::sizeFromContents( contents, widget, contentsSize, opt ); + break; + } + + return sz; +} + +/*!\reimp +*/ +QRect QMotifStyle::subRect( SubRect r, const QWidget *widget ) const +{ + QRect rect; + QRect wrect = widget->rect(); + + switch ( r ) { + case SR_SliderFocusRect: + rect = QCommonStyle::subRect( r, widget ); + rect.addCoords( 2, 2, -2, -2 ); + break; + + case SR_ComboBoxFocusRect: + { + int awh, ax, ay, sh, sy, dh, ew; + int fw = pixelMetric( PM_DefaultFrameWidth, widget ); + QRect tr = wrect; + + tr.addCoords( fw, fw, -fw, -fw ); + get_combo_parameters( tr, ew, awh, ax, ay, sh, dh, sy ); + rect.setRect(ax-2, ay-2, awh+4, awh+sh+dh+4); + break; + } + + case SR_DockWindowHandleRect: + { +#ifndef QT_NO_MAINWINDOW + if ( !widget || !widget->parent() ) + break; + + const QDockWindow * dw = (const QDockWindow *) widget->parent(); + if ( !dw->area() || !dw->isCloseEnabled() ) + rect.setRect( 0, 0, widget->width(), widget->height() ); + else { + if ( dw->area()->orientation() == Horizontal ) + rect.setRect(2, 15, widget->width()-2, widget->height() - 15); + else + rect.setRect(0, 2, widget->width() - 15, widget->height() - 2); + } +#endif + break; + } + + case SR_ProgressBarGroove: + case SR_ProgressBarContents: + { +#ifndef QT_NO_PROGRESSBAR + QFontMetrics fm( ( widget ? widget->fontMetrics() : + QApplication::fontMetrics() ) ); + const QProgressBar *progressbar = (const QProgressBar *) widget; + int textw = 0; + if (progressbar->percentageVisible()) + textw = fm.width("100%") + 6; + + if (progressbar->indicatorFollowsStyle() || + progressbar->centerIndicator()) + rect = wrect; + else + rect.setCoords(wrect.left(), wrect.top(), + wrect.right() - textw, wrect.bottom()); +#endif + break; + } + + case SR_ProgressBarLabel: + { +#ifndef QT_NO_PROGRESSBAR + QFontMetrics fm( ( widget ? widget->fontMetrics() : + QApplication::fontMetrics() ) ); + const QProgressBar *progressbar = (const QProgressBar *) widget; + int textw = 0; + if (progressbar->percentageVisible()) + textw = fm.width("100%") + 6; + + if (progressbar->indicatorFollowsStyle() || + progressbar->centerIndicator()) + rect = wrect; + else + rect.setCoords(wrect.right() - textw, wrect.top(), + wrect.right(), wrect.bottom()); +#endif + break; + } + + case SR_CheckBoxContents: + { +#ifndef QT_NO_CHECKBOX + QRect ir = subRect(SR_CheckBoxIndicator, widget); + rect.setRect(ir.right() + 10, wrect.y(), + wrect.width() - ir.width() - 10, wrect.height()); +#endif + break; + } + + case SR_RadioButtonContents: + { + QRect ir = subRect(SR_RadioButtonIndicator, widget); + rect.setRect(ir.right() + 10, wrect.y(), + wrect.width() - ir.width() - 10, wrect.height()); + break; + } + + default: + rect = QCommonStyle::subRect( r, widget ); + } + + return rect; +} + +/*! \reimp +*/ +void QMotifStyle::polishPopupMenu( QPopupMenu* p) +{ +#ifndef QT_NO_POPUPMENU + if ( !p->testWState( WState_Polished ) ) + p->setCheckable( FALSE ); +#endif +} + + +#ifndef QT_NO_IMAGEIO_XPM +static const char * const qt_close_xpm[] = { +"12 12 2 1", +" s None c None", +". c black", +" ", +" ", +" . . ", +" ... ... ", +" ...... ", +" .... ", +" .... ", +" ...... ", +" ... ... ", +" . . ", +" ", +" "}; + +static const char * const qt_maximize_xpm[] = { +"12 12 2 1", +" s None c None", +". c black", +" ", +" ", +" ", +" . ", +" ... ", +" ..... ", +" ....... ", +" ......... ", +" ", +" ", +" ", +" "}; + +static const char * const qt_minimize_xpm[] = { +"12 12 2 1", +" s None c None", +". c black", +" ", +" ", +" ", +" ", +" ......... ", +" ....... ", +" ..... ", +" ... ", +" . ", +" ", +" ", +" "}; + +#if 0 // ### not used??? +static const char * const qt_normalize_xpm[] = { +"12 12 2 1", +" s None c None", +". c black", +" ", +" ", +" . ", +" .. ", +" ... ", +" .... ", +" ..... ", +" ...... ", +" ....... ", +" ", +" ", +" "}; +#endif + +static const char * const qt_normalizeup_xpm[] = { +"12 12 2 1", +" s None c None", +". c black", +" ", +" ", +" ", +" ....... ", +" ...... ", +" ..... ", +" .... ", +" ... ", +" .. ", +" . ", +" ", +" "}; + +static const char * const qt_shade_xpm[] = { +"12 12 2 1", "# c #000000", +". c None", +"............", +"............", +".#########..", +".#########..", +"............", +"............", +"............", +"............", +"............", +"............", +"............", +"............"}; + + +static const char * const qt_unshade_xpm[] = { +"12 12 2 1", +"# c #000000", +". c None", +"............", +"............", +".#########..", +".#########..", +".#.......#..", +".#.......#..", +".#.......#..", +".#.......#..", +".#.......#..", +".#########..", +"............", +"............"}; + + +static const char * dock_window_close_xpm[] = { +"8 8 2 1", +"# c #000000", +". c None", +"##....##", +".##..##.", +"..####..", +"...##...", +"..####..", +".##..##.", +"##....##", +"........"}; + +// Message box icons, from page 210 of the Windows style guide. + +// Hand-drawn to resemble Microsoft's icons, but in the Mac/Netscape palette. +// Thanks to TrueColor displays, it is slightly more efficient to have +// them duplicated. +/* XPM */ +static const char * const information_xpm[]={ +"32 32 5 1", +". c None", +"c c #000000", +"* c #999999", +"a c #ffffff", +"b c #0000ff", +"...........********.............", +"........***aaaaaaaa***..........", +"......**aaaaaaaaaaaaaa**........", +".....*aaaaaaaaaaaaaaaaaa*.......", +"....*aaaaaaaabbbbaaaaaaaac......", +"...*aaaaaaaabbbbbbaaaaaaaac.....", +"..*aaaaaaaaabbbbbbaaaaaaaaac....", +".*aaaaaaaaaaabbbbaaaaaaaaaaac...", +".*aaaaaaaaaaaaaaaaaaaaaaaaaac*..", +"*aaaaaaaaaaaaaaaaaaaaaaaaaaaac*.", +"*aaaaaaaaaabbbbbbbaaaaaaaaaaac*.", +"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**", +"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**", +"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**", +"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**", +"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**", +".*aaaaaaaaaaabbbbbaaaaaaaaaac***", +".*aaaaaaaaaaabbbbbaaaaaaaaaac***", +"..*aaaaaaaaaabbbbbaaaaaaaaac***.", +"...caaaaaaabbbbbbbbbaaaaaac****.", +"....caaaaaaaaaaaaaaaaaaaac****..", +".....caaaaaaaaaaaaaaaaaac****...", +"......ccaaaaaaaaaaaaaacc****....", +".......*cccaaaaaaaaccc*****.....", +"........***cccaaaac*******......", +"..........****caaac*****........", +".............*caaac**...........", +"...............caac**...........", +"................cac**...........", +".................cc**...........", +"..................***...........", +"...................**..........."}; +/* XPM */ +static const char* const warning_xpm[]={ +"32 32 4 1", +". c None", +"a c #ffff00", +"* c #000000", +"b c #999999", +".............***................", +"............*aaa*...............", +"...........*aaaaa*b.............", +"...........*aaaaa*bb............", +"..........*aaaaaaa*bb...........", +"..........*aaaaaaa*bb...........", +".........*aaaaaaaaa*bb..........", +".........*aaaaaaaaa*bb..........", +"........*aaaaaaaaaaa*bb.........", +"........*aaaa***aaaa*bb.........", +".......*aaaa*****aaaa*bb........", +".......*aaaa*****aaaa*bb........", +"......*aaaaa*****aaaaa*bb.......", +"......*aaaaa*****aaaaa*bb.......", +".....*aaaaaa*****aaaaaa*bb......", +".....*aaaaaa*****aaaaaa*bb......", +"....*aaaaaaaa***aaaaaaaa*bb.....", +"....*aaaaaaaa***aaaaaaaa*bb.....", +"...*aaaaaaaaa***aaaaaaaaa*bb....", +"...*aaaaaaaaaa*aaaaaaaaaa*bb....", +"..*aaaaaaaaaaa*aaaaaaaaaaa*bb...", +"..*aaaaaaaaaaaaaaaaaaaaaaa*bb...", +".*aaaaaaaaaaaa**aaaaaaaaaaa*bb..", +".*aaaaaaaaaaa****aaaaaaaaaa*bb..", +"*aaaaaaaaaaaa****aaaaaaaaaaa*bb.", +"*aaaaaaaaaaaaa**aaaaaaaaaaaa*bb.", +"*aaaaaaaaaaaaaaaaaaaaaaaaaaa*bbb", +"*aaaaaaaaaaaaaaaaaaaaaaaaaaa*bbb", +".*aaaaaaaaaaaaaaaaaaaaaaaaa*bbbb", +"..*************************bbbbb", +"....bbbbbbbbbbbbbbbbbbbbbbbbbbb.", +".....bbbbbbbbbbbbbbbbbbbbbbbbb.."}; +/* XPM */ +static const char* const critical_xpm[]={ +"32 32 4 1", +". c None", +"a c #999999", +"* c #ff0000", +"b c #ffffff", +"...........********.............", +".........************...........", +".......****************.........", +"......******************........", +".....********************a......", +"....**********************a.....", +"...************************a....", +"..*******b**********b*******a...", +"..******bbb********bbb******a...", +".******bbbbb******bbbbb******a..", +".*******bbbbb****bbbbb*******a..", +"*********bbbbb**bbbbb*********a.", +"**********bbbbbbbbbb**********a.", +"***********bbbbbbbb***********aa", +"************bbbbbb************aa", +"************bbbbbb************aa", +"***********bbbbbbbb***********aa", +"**********bbbbbbbbbb**********aa", +"*********bbbbb**bbbbb*********aa", +".*******bbbbb****bbbbb*******aa.", +".******bbbbb******bbbbb******aa.", +"..******bbb********bbb******aaa.", +"..*******b**********b*******aa..", +"...************************aaa..", +"....**********************aaa...", +"....a********************aaa....", +".....a******************aaa.....", +"......a****************aaa......", +".......aa************aaaa.......", +".........aa********aaaaa........", +"...........aaaaaaaaaaa..........", +".............aaaaaaa............"}; +/* XPM */ +static const char *const question_xpm[] = { +"32 32 5 1", +". c None", +"c c #000000", +"* c #999999", +"a c #ffffff", +"b c #0000ff", +"...........********.............", +"........***aaaaaaaa***..........", +"......**aaaaaaaaaaaaaa**........", +".....*aaaaaaaaaaaaaaaaaa*.......", +"....*aaaaaaaaaaaaaaaaaaaac......", +"...*aaaaaaaabbbbbbaaaaaaaac.....", +"..*aaaaaaaabaaabbbbaaaaaaaac....", +".*aaaaaaaabbaaaabbbbaaaaaaaac...", +".*aaaaaaaabbbbaabbbbaaaaaaaac*..", +"*aaaaaaaaabbbbaabbbbaaaaaaaaac*.", +"*aaaaaaaaaabbaabbbbaaaaaaaaaac*.", +"*aaaaaaaaaaaaabbbbaaaaaaaaaaac**", +"*aaaaaaaaaaaaabbbaaaaaaaaaaaac**", +"*aaaaaaaaaaaaabbaaaaaaaaaaaaac**", +"*aaaaaaaaaaaaabbaaaaaaaaaaaaac**", +"*aaaaaaaaaaaaaaaaaaaaaaaaaaaac**", +".*aaaaaaaaaaaabbaaaaaaaaaaaac***", +".*aaaaaaaaaaabbbbaaaaaaaaaaac***", +"..*aaaaaaaaaabbbbaaaaaaaaaac***.", +"...caaaaaaaaaabbaaaaaaaaaac****.", +"....caaaaaaaaaaaaaaaaaaaac****..", +".....caaaaaaaaaaaaaaaaaac****...", +"......ccaaaaaaaaaaaaaacc****....", +".......*cccaaaaaaaaccc*****.....", +"........***cccaaaac*******......", +"..........****caaac*****........", +".............*caaac**...........", +"...............caac**...........", +"................cac**...........", +".................cc**...........", +"..................***...........", +"...................**...........", +}; +#endif + +/*! + \reimp + */ +QPixmap QMotifStyle::stylePixmap(StylePixmap sp, + const QWidget *widget, + const QStyleOption& opt) const +{ +#ifndef QT_NO_IMAGEIO_XPM + switch (sp) { + case SP_TitleBarShadeButton: + return QPixmap((const char **)qt_shade_xpm); + case SP_TitleBarUnshadeButton: + return QPixmap((const char **)qt_unshade_xpm); + case SP_TitleBarNormalButton: + return QPixmap((const char **)qt_normalizeup_xpm); + case SP_TitleBarMinButton: + return QPixmap((const char **)qt_minimize_xpm); + case SP_TitleBarMaxButton: + return QPixmap((const char **)qt_maximize_xpm); + case SP_TitleBarCloseButton: + return QPixmap((const char **)qt_close_xpm); + case SP_DockWindowCloseButton: + return QPixmap((const char **)dock_window_close_xpm ); + + case SP_MessageBoxInformation: + case SP_MessageBoxWarning: + case SP_MessageBoxCritical: + case SP_MessageBoxQuestion: + { + const char * const * xpm_data; + switch ( sp ) { + case SP_MessageBoxInformation: + xpm_data = information_xpm; + break; + case SP_MessageBoxWarning: + xpm_data = warning_xpm; + break; + case SP_MessageBoxCritical: + xpm_data = critical_xpm; + break; + case SP_MessageBoxQuestion: + xpm_data = question_xpm; + break; + default: + xpm_data = 0; + break; + } + QPixmap pm; + if ( xpm_data ) { + QImage image( (const char **) xpm_data); + // All that color looks ugly in Motif + QColorGroup g = QApplication::palette().active(); + switch ( sp ) { + case SP_MessageBoxInformation: + case SP_MessageBoxQuestion: + image.setColor( 2, 0xff000000 | g.dark().rgb() ); + image.setColor( 3, 0xff000000 | g.base().rgb() ); + image.setColor( 4, 0xff000000 | g.text().rgb() ); + break; + case SP_MessageBoxWarning: + image.setColor( 1, 0xff000000 | g.base().rgb() ); + image.setColor( 2, 0xff000000 | g.text().rgb() ); + image.setColor( 3, 0xff000000 | g.dark().rgb() ); + break; + case SP_MessageBoxCritical: + image.setColor( 1, 0xff000000 | g.dark().rgb() ); + image.setColor( 2, 0xff000000 | g.text().rgb() ); + image.setColor( 3, 0xff000000 | g.base().rgb() ); + break; + default: + break; + } + pm.convertFromImage(image); + } + return pm; + } + + default: + break; + } +#endif + + return QCommonStyle::stylePixmap(sp, widget, opt); +} + + +/*! \reimp */ +int QMotifStyle::styleHint(StyleHint hint, + const QWidget *widget, + const QStyleOption &opt, + QStyleHintReturn *returnData) const +{ + int ret; + + switch (hint) { + case SH_GUIStyle: + ret = MotifStyle; + break; + + case SH_ScrollBar_BackgroundMode: + ret = QWidget::PaletteMid; + break; + + case SH_ScrollBar_MiddleClickAbsolutePosition: + case SH_Slider_SloppyKeyEvents: + case SH_ProgressDialog_CenterCancelButton: + case SH_PopupMenu_SpaceActivatesItem: + case SH_ScrollView_FrameOnlyAroundContents: + ret = 1; + break; + + case SH_PopupMenu_SubMenuPopupDelay: + ret = 96; + break; + + case SH_ProgressDialog_TextLabelAlignment: + ret = AlignAuto | AlignVCenter; + break; + + case SH_ItemView_ChangeHighlightOnFocus: + ret = 0; + break; + + default: + ret = QCommonStyle::styleHint(hint, widget, opt, returnData); + break; + } + + return ret; +} + + +#endif diff --git a/src/styles/qmotifstyle.h b/src/styles/qmotifstyle.h new file mode 100644 index 0000000..c26337c --- /dev/null +++ b/src/styles/qmotifstyle.h @@ -0,0 +1,136 @@ +/**************************************************************************** +** +** Definition of Motif-like style class +** +** Created : 981231 +** +** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the widgets module of the Qt GUI Toolkit. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** This file may be used under the terms of the Q Public License as +** defined by Trolltech ASA and appearing in the file LICENSE.QPL +** included in the packaging of this file. Licensees holding valid Qt +** Commercial licenses may use this file in accordance with the Qt +** Commercial License Agreement provided with the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef QMOTIFSTYLE_H +#define QMOTIFSTYLE_H + +#ifndef QT_H +#include "qcommonstyle.h" +#endif // QT_H + +#if !defined(QT_NO_STYLE_MOTIF) || defined(QT_PLUGIN) + +class QPalette; + +#if defined(QT_PLUGIN) +#define Q_EXPORT_STYLE_MOTIF +#else +#define Q_EXPORT_STYLE_MOTIF Q_EXPORT +#endif + + +class Q_EXPORT_STYLE_MOTIF QMotifStyle : public QCommonStyle +{ + Q_OBJECT +public: + QMotifStyle( bool useHighlightCols=FALSE ); + virtual ~QMotifStyle(); + + void setUseHighlightColors( bool ); + bool useHighlightColors() const; + + void polish( QPalette& ); + void polish( QWidget* ); + void polish( QApplication* ); + + void polishPopupMenu( QPopupMenu* ); + + // new style API + void drawPrimitive( PrimitiveElement pe, + QPainter *p, + const QRect &r, + const QColorGroup &cg, + SFlags flags = Style_Default, + const QStyleOption& = QStyleOption::Default ) const; + + void drawControl( ControlElement element, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QColorGroup &cg, + SFlags how = Style_Default, + const QStyleOption& = QStyleOption::Default ) const; + + void drawComplexControl( ComplexControl control, + QPainter *p, + const QWidget* widget, + const QRect& r, + const QColorGroup& cg, + SFlags how = Style_Default, +#ifdef Q_QDOC + SCFlags sub = SC_All, +#else + SCFlags sub = (uint)SC_All, +#endif + SCFlags subActive = SC_None, + const QStyleOption& = QStyleOption::Default ) const; + + QRect querySubControlMetrics( ComplexControl control, + const QWidget *widget, + SubControl sc, + const QStyleOption& = QStyleOption::Default ) const; + + int pixelMetric( PixelMetric metric, const QWidget *widget = 0 ) const; + + QSize sizeFromContents( ContentsType contents, + const QWidget *widget, + const QSize &contentsSize, + const QStyleOption& = QStyleOption::Default ) const; + + QRect subRect( SubRect r, const QWidget *widget ) const; + + QPixmap stylePixmap(StylePixmap, const QWidget * = 0, const QStyleOption& = QStyleOption::Default) const; + + int styleHint(StyleHint sh, const QWidget *, const QStyleOption & = QStyleOption::Default, + QStyleHintReturn* = 0) const; + +private: + bool highlightCols; + + // Disabled copy constructor and operator= +#if defined(Q_DISABLE_COPY) + QMotifStyle( const QMotifStyle & ); + QMotifStyle& operator=( const QMotifStyle & ); +#endif +}; + +#endif // QT_NO_STYLE_MOTIF + +#endif // QMOTIFSTYLE_H diff --git a/src/styles/qplatinumstyle.cpp b/src/styles/qplatinumstyle.cpp new file mode 100644 index 0000000..19c12a7 --- /dev/null +++ b/src/styles/qplatinumstyle.cpp @@ -0,0 +1,1557 @@ +/**************************************************************************** +** +** Implementation of Platinum-like style class +** +** Created : 981231 +** +** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the widgets module of the Qt GUI Toolkit. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** This file may be used under the terms of the Q Public License as +** defined by Trolltech ASA and appearing in the file LICENSE.QPL +** included in the packaging of this file. Licensees holding valid Qt +** Commercial licenses may use this file in accordance with the Qt +** Commercial License Agreement provided with the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "qplatinumstyle.h" + +#if !defined(QT_NO_STYLE_PLATINUM) || defined(QT_PLUGIN) + +#include "qapplication.h" +#include "qcombobox.h" +#include "qdrawutil.h" +#include "qpainter.h" +#include "qpalette.h" +#include "qpixmap.h" +#include "qpushbutton.h" +#include "qscrollbar.h" +#include "qslider.h" +#include + +/*! + \class QPlatinumStyle qplatinumstyle.h + \brief The QPlatinumStyle class provides Mac/Platinum look and feel. + + \ingroup appearance + + This class implements the Platinum look and feel. It's an + experimental class that tries to resemble a Macinosh-like GUI + style with the QStyle system. The emulation is currently far from + perfect. + + \sa QAquaStyle +*/ + + +/*! + Constructs a QPlatinumStyle +*/ +QPlatinumStyle::QPlatinumStyle() +{ +} + +/*!\reimp +*/ +QPlatinumStyle::~QPlatinumStyle() +{ +} + + +/*!\reimp + */ +void QPlatinumStyle::drawPrimitive( PrimitiveElement pe, + QPainter *p, + const QRect &r, + const QColorGroup &cg, + SFlags flags, + const QStyleOption& opt ) const +{ + switch (pe) { + case PE_HeaderSection: + { + // adjust the sunken flag, otherwise headers are drawn + // sunken... + if ( flags & Style_Sunken ) + flags ^= Style_Sunken; + drawPrimitive( PE_ButtonBevel, p, r, cg, flags, opt ); + break; + } + case PE_ButtonTool: + { + // tool buttons don't change color when pushed in platinum, + // so we need to make the mid and button color the same + QColorGroup myCG = cg; + QBrush fill; + + // quick trick to make sure toolbuttons drawn sunken + // when they are activated... + if ( flags & Style_On ) + flags |= Style_Sunken; + + fill = myCG.brush( QColorGroup::Button ); + myCG.setBrush( QColorGroup::Mid, fill ); + drawPrimitive( PE_ButtonBevel, p, r, myCG, flags, opt ); + break; + } + case PE_ButtonBevel: + { + int x, + y, + w, + h; + r.rect( &x, &y, &w, &h ); + + QPen oldPen = p->pen(); + if ( w * h < 1600 || + QABS(w - h) > 10 ) { + // small buttons + + if ( !(flags & (Style_Sunken | Style_Down)) ) { + p->fillRect( x + 2, y + 2, w - 4, h - 4, + cg.brush(QColorGroup::Button) ); + // the bright side + p->setPen( cg.dark() ); + // the bright side + p->setPen( cg.dark() ); + p->drawLine( x, y, x + w - 1, y ); + p->drawLine( x, y, x, y + h - 1 ); + + p->setPen( cg.light() ); + p->drawLine( x + 1, y + 1, x + w - 2, y + 1 ); + p->drawLine( x + 1, y + 1, x + 1, y + h - 2 ); + + // the dark side + p->setPen( cg.mid() ); + p->drawLine( x + 2, y + h - 2, x + w - 2, y + h - 2 ); + p->drawLine( x + w - 2, y + 2, x + w - 2, y + h - 3 ); + + p->setPen( cg.dark().dark() ); + p->drawLine( x + 1, y + h - 1, x + w - 1, + y + h - 1 ); + p->drawLine( x + w - 1, y + 1, + x + w - 1, + y + h - 2 ); + } else { + p->fillRect(x + 2, y + 2, + w - 4, h - 4, + cg.brush( QColorGroup::Mid )); + + // the dark side + p->setPen( cg.dark().dark() ); + p->drawLine( x, y, x + w - 1, y ); + p->drawLine( x, y, x, y + h - 1 ); + + p->setPen( cg.mid().dark()); + p->drawLine( x + 1, y + 1, + x + w-2, y + 1); + p->drawLine( x + 1, y + 1, + x + 1, y + h - 2 ); + + + // the bright side! + + p->setPen(cg.button()); + p->drawLine( x + 1, y + h - 2, + x + w - 2, + y + h - 2 ); + p->drawLine( x + w - 2, y + 1, + x + w - 2, + y + h - 2 ); + p->setPen(cg.dark()); + p->drawLine(x, y + h - 1, + x + w - 1, + y + h - 1 ); + p->drawLine(x + w - 1, y, + x + w - 1, + y + h - 1 ); + } + } else { + // big ones + if ( !(flags & (Style_Sunken | Style_Down)) ) { + p->fillRect( x + 3, y + 3, w - 6, + h - 6, + cg.brush(QColorGroup::Button) ); + + // the bright side + p->setPen( cg.button().dark() ); + p->drawLine( x, y, x + w - 1, y ); + p->drawLine( x, y, x, y + h - 1 ); + + p->setPen( cg.button() ); + p->drawLine( x + 1, y + 1, + x + w - 2, y + 1 ); + p->drawLine( x + 1, y + 1, + x + 1, y + h - 2 ); + + p->setPen( cg.light() ); + p->drawLine( x + 2, y + 2, + x + 2, y + h - 2 ); + p->drawLine( x + 2, y + 2, + x + w - 2, y + 2 ); + // the dark side! + + p->setPen( cg.mid() ); + p->drawLine( x + 3, y + h - 3, + x + w - 3, + y + h - 3 ); + p->drawLine( x + w - 3, y + 3, + x + w - 3, + y + h - 3 ); + p->setPen( cg.dark() ); + p->drawLine( x + 2, y + h - 2, + x + w - 2, + y + h - 2 ); + p->drawLine( x + w - 2, y + 2, + x + w - 2, + y + h - 2 ); + + p->setPen( cg.dark().dark() ); + p->drawLine( x + 1, y + h - 1, + x + w - 1, + y + h - 1 ); + p->drawLine( x + w - 1, y + 1, + x + w - 1, + y + h - 1 ); + } else { + p->fillRect( x + 3, y + 3, w - 6, + h - 6, + cg.brush( QColorGroup::Mid ) ); + + // the dark side + p->setPen( cg.dark().dark().dark() ); + p->drawLine( x, y, x + w - 1, y ); + p->drawLine( x, y, x, y + h - 1 ); + + p->setPen( cg.dark().dark() ); + p->drawLine( x + 1, y + 1, + x + w - 2, y + 1 ); + p->drawLine( x + 1, y + 1, + x + 1, y + h - 2 ); + + p->setPen( cg.mid().dark() ); + p->drawLine( x + 2, y + 2, + x + 2, y + w - 2 ); + p->drawLine( x + 2, y + 2, + x + w - 2, y + 2 ); + + + // the bright side! + + p->setPen( cg.button() ); + p->drawLine( x + 2, y + h - 3, + x + w - 3, + y + h - 3 ); + p->drawLine( x + w - 3, y + 3, + x + w - 3, + y + h - 3 ); + + p->setPen( cg.midlight() ); + p->drawLine( x + 1, y + h - 2, + x + w - 2, + y + h - 2 ); + p->drawLine( x + w - 2, y + 1, + x + w - 2, + y + h - 2 ); + + p->setPen( cg.dark() ); + p->drawLine( x, y + h - 1, + x + w - 1, + y + h - 1 ); + p->drawLine( x + w - 1, y, + x + w - 1, + y + h - 1 ); + + + // corners + p->setPen( mixedColor(cg.dark().dark().dark(), + cg.dark()) ); + p->drawPoint( x, y + h - 1 ); + p->drawPoint( x + w - 1, y ); + + p->setPen( mixedColor(cg.dark().dark(), cg.midlight()) ); + p->drawPoint( x + 1, y + h - 2 ); + p->drawPoint( x + w - 2, y + 1 ); + + p->setPen( mixedColor(cg.mid().dark(), cg.button() ) ); + p->drawPoint( x + 2, y + h - 3 ); + p->drawPoint( x + w - 3, y + 2 ); + } + } + p->setPen( oldPen ); + break; + } + case PE_ButtonCommand: + { + QPen oldPen = p->pen(); + int x, + y, + w, + h; + r.rect( &x, &y, &w, &h); + + if ( !(flags & (Style_Down | Style_On)) ) { + p->fillRect( x+3, y+3, w-6, h-6, + cg.brush( QColorGroup::Button )); + // the bright side + p->setPen( cg.shadow() ); + p->drawLine( x, y, x+w-1, y ); + p->drawLine( x, y, x, y + h - 1 ); + + p->setPen( cg.button() ); + p->drawLine( x + 1, y + 1, x + w - 2, y + 1 ); + p->drawLine( x + 1, y + 1, x + 1, y + h - 2 ); + + p->setPen( cg.light() ); + p->drawLine( x + 2, y + 2, x + 2, y + h - 2 ); + p->drawLine( x + 2, y + 2, x + w - 2, y + 2 ); + + + // the dark side! + + p->setPen( cg.mid() ); + p->drawLine( x + 3, y + h - 3 ,x + w - 3, y + h - 3 ); + p->drawLine( x + w - 3, y + 3, x + w - 3, y + h - 3 ); + + p->setPen( cg.dark() ); + p->drawLine( x + 2, y + h - 2, x + w - 2, y + h - 2 ); + p->drawLine( x + w - 2, y + 2, x + w - 2, y + h - 2 ); + + p->setPen( cg.shadow() ); + p->drawLine( x + 1, y + h - 1, x + w - 1, y + h - 1 ); + p->drawLine( x + w - 1, y, x + w - 1, y + h - 1 ); + + + // top left corner: + p->setPen( cg.background() ); + p->drawPoint( x, y ); + p->drawPoint( x + 1, y ); + p->drawPoint( x, y+1 ); + p->setPen( cg.shadow() ); + p->drawPoint( x + 1, y + 1 ); + p->setPen( cg.button() ); + p->drawPoint( x + 2, y + 2 ); + p->setPen( white ); + p->drawPoint( x + 3, y + 3 ); + // bottom left corner: + p->setPen( cg.background() ); + p->drawPoint( x, y + h - 1 ); + p->drawPoint( x + 1, y + h - 1 ); + p->drawPoint( x, y + h - 2 ); + p->setPen( cg.shadow() ); + p->drawPoint( x + 1, y + h - 2 ); + p->setPen( cg.dark() ); + p->drawPoint( x + 2, y + h - 3 ); + // top right corner: + p->setPen( cg.background() ); + p->drawPoint( x + w -1, y ); + p->drawPoint( x + w - 2, y ); + p->drawPoint( x + w - 1, y + 1 ); + p->setPen( cg.shadow() ); + p->drawPoint( x + w - 2, y + 1 ); + p->setPen( cg.dark() ); + p->drawPoint( x + w - 3, y + 2 ); + // bottom right corner: + p->setPen( cg.background() ); + p->drawPoint( x + w - 1, y + h - 1 ); + p->drawPoint( x + w - 2, y + h - 1 ); + p->drawPoint( x + w - 1, y + h - 2 ); + p->setPen( cg.shadow() ); + p->drawPoint( x + w - 2, y + h - 2 ); + p->setPen( cg.dark() ); + p->drawPoint( x + w - 3, y + h - 3 ); + p->setPen( cg.mid() ); + p->drawPoint( x + w - 4, y + h - 4 ); + + } else { + p->fillRect( x + 2, y + 2, w - 4, h - 4, + cg.brush(QColorGroup::Dark) ); + + // the dark side + p->setPen( cg.shadow() ); + p->drawLine( x, y, x + w - 1, y ); + p->drawLine( x, y, x, y + h - 1 ); + + p->setPen( cg.dark().dark() ); + p->drawLine( x + 1, y + 1, x + w - 2, y + 1 ); + p->drawLine( x + 1, y + 1, x + 1, y + h - 2 ); + + // the bright side! + + p->setPen( cg.button() ); + p->drawLine( x + 1, y + h - 2, x + w - 2, y + h - 2 ); + p->drawLine( x + w - 2, y + 1, x + w - 2, y + h - 2 ); + + p->setPen( cg.dark() ); + p->drawLine( x, y + h - 1, x + w - 1, y + h - 1 ); + p->drawLine( x + w - 1, y, x + w - 1, y + h - 1 ); + + // top left corner: + p->setPen( cg.background() ); + p->drawPoint( x, y ); + p->drawPoint( x + 1, y ); + p->drawPoint( x, y + 1 ); + p->setPen( cg.shadow() ); + p->drawPoint( x + 1, y + 1 ); + p->setPen( cg.dark().dark() ); + p->drawPoint( x + 3, y + 3 ); + // bottom left corner: + p->setPen( cg.background() ); + p->drawPoint( x, y + h - 1 ); + p->drawPoint( x + 1, y + h - 1 ); + p->drawPoint( x, y + h - 2 ); + p->setPen( cg.shadow() ); + p->drawPoint( x + 1, y + h - 2 ); + // top right corner: + p->setPen( cg.background() ); + p->drawPoint( x + w - 1, y ); + p->drawPoint( x + w - 2, y ); + p->drawPoint( x + w - 1, y + 1 ); + p->setPen( cg.shadow() ); + p->drawPoint( x + w - 2, y + 1 ); + // bottom right corner: + p->setPen( cg.background() ); + p->drawPoint( x + w - 1, y + h - 1 ); + p->drawPoint( x + w - 2, y + h - 1 ); + p->drawPoint( x + w - 1, y + h - 2 ); + p->setPen( cg.shadow() ); + p->drawPoint( x + w - 2, y + h - 2 ); + p->setPen( cg.dark() ); + p->drawPoint( x + w - 3, y + h - 3 ); + p->setPen( cg.mid() ); + p->drawPoint( x + w - 4, y + h - 4 ); + } + p->setPen( oldPen ); + break; + } + case PE_Indicator: + { + drawPrimitive( PE_ButtonBevel, p, QRect(r.x(), r.y(), + r.width() - 2, r.height()), + cg, flags ); + p->fillRect( r.x() + r.width() - 2, r.y(), 2, r.height(), + cg.brush( QColorGroup::Background ) ); + p->setPen( cg.shadow() ); + p->drawRect( r.x(), r.y(), r.width() - 2, r.height() ); + + static const QCOORD nochange_mark[] = { 3,5, 9,5, 3,6, 9,6 }; + static const QCOORD check_mark[] = { + 3,5, 5,5, 4,6, 5,6, 5,7, 6,7, 5,8, 6,8, 6,9, 9,9, + 6,10, 8,10, 7,11, 8,11, 7,12, 7,12, 8,8, 9,8, 8,7, 10,7, + 9,6, 10,6, 9,5, 11,5, 10,4, 11,4, 10,3, 12,3, + 11,2, 12,2, 11,1, 13,1, 12,0, 13,0 }; + if ( !(flags & Style_Off) ) { + QPen oldPen = p->pen(); + int x1 = r.x(); + int y1 = r.y(); + if ( flags & Style_Down ) { + x1++; + y1++; + } + QPointArray amark; + if ( flags & Style_On ) { + amark = QPointArray( sizeof(check_mark)/(sizeof(QCOORD)*2), + check_mark ); + // ### KLUDGE!! + flags ^= Style_On; + flags ^= Style_Down; + } else if ( flags & Style_NoChange ) { + amark = QPointArray( sizeof(nochange_mark) + / (sizeof(QCOORD) * 2), + nochange_mark ); + } + + amark.translate( x1 + 1, y1 + 1 ); + p->setPen( cg.dark() ); + p->drawLineSegments( amark ); + amark.translate( -1, -1 ); + p->setPen( cg.foreground() ); + p->drawLineSegments( amark ); + p->setPen( oldPen ); + } + break; + } + case PE_IndicatorMask: + { + int x, + y, + w, + h; + r.rect( &x, &y, &w, &h ); + p->fillRect( x, y, w - 2, h, color1); + if ( flags & Style_Off ) { + QPen oldPen = p->pen(); + p->setPen ( QPen(color1, 2)); + p->drawLine( x + 2, y + h / 2 - 1, + x + w / 2 - 1, y + h - 4 ); + p->drawLine( x + w / 2 - 1, y + h - 4, + x + w, 0); + p->setPen( oldPen ); + } + break; + } + case PE_ExclusiveIndicator: + { +#define QCOORDARRLEN(x) sizeof(x) / (sizeof(QCOORD) * 2 ) + bool down = flags & Style_Down; + bool on = flags & Style_On; + + static const QCOORD pts1[] = { // normal circle + 5,0, 8,0, 9,1, 10,1, 11,2, 12,3, 12,4, 13,5, + 13,8, 12,9, 12,10, 11,11, 10,12, 9,12, 8,13, + 5,13, 4,12, 3,12, 2,11, 1,10, 1,9, 0,8, 0,5, + 1,4, 1,3, 2,2, 3,1, 4,1 }; + static const QCOORD pts2[] = { // top left shadow + 5,1, 8,1, 3,2, 7,2, 2,3, 5,3, 2,4, 4,4, + 1,5, 3,5, 1,6, 1,8, 2,6, 2,7 }; + static const QCOORD pts3[] = { // bottom right, dark + 5,12, 8,12, 7,11, 10,11, 8,10, 11,10, + 9,9, 11,9, 10,8, 12,8, 11,7, 11,7, + 12,5, 12,7 }; + static const QCOORD pts4[] = { // bottom right, light + 5,12, 8,12, 7,11, 10,11, 9,10, 11,10, + 10,9, 11,9, 11,7, 11,8, 12,5, 12,8 }; + static const QCOORD pts5[] = { // check mark + 6,4, 8,4, 10,6, 10,8, 8,10, 6,10, 4,8, 4,6 }; + static const QCOORD pts6[] = { // check mark extras + 4,5, 5,4, 9,4, 10,5, 10,9, 9,10, 5,10, 4,9 }; + int x, y; + x = r.x(); + y = r.y(); + p->eraseRect( r ); + p->setBrush( (down||on) ? cg.brush( QColorGroup::Dark ) + : cg.brush( QColorGroup::Button) ); + p->setPen( NoPen ); + p->drawEllipse( x, y, 13, 13 ); + p->setPen( cg.shadow() ); + QPointArray a( QCOORDARRLEN(pts1), pts1 ); + a.translate( x, y ); + p->drawPolyline( a ); // draw normal circle + QColor tc, bc; + const QCOORD *bp; + int bl; + if ( down || on ) { // pressed down or on + tc = cg.dark().dark(); + bc = cg.light(); + bp = pts4; + bl = QCOORDARRLEN(pts4); + } else { // released + tc = cg.light(); + bc = cg.dark(); + bp = pts3; + bl = QCOORDARRLEN(pts3); + } + p->setPen( tc ); + a.setPoints( QCOORDARRLEN(pts2), pts2 ); + a.translate( x, y ); + p->drawLineSegments( a ); // draw top shadow + p->setPen( bc ); + a.setPoints( bl, bp ); + a.translate( x, y ); + p->drawLineSegments( a ); + if ( on ) { // draw check mark + int x1 = x, + y1 = y; + p->setBrush( cg.foreground() ); + p->setPen( cg.foreground() ); + a.setPoints( QCOORDARRLEN(pts5), pts5 ); + a.translate( x1, y1 ); + p->drawPolygon( a ); + p->setBrush( NoBrush ); + p->setPen( cg.dark() ); + a.setPoints( QCOORDARRLEN(pts6), pts6 ); + a.translate( x1, y1 ); + p->drawLineSegments( a ); + } + break; + } + + case PE_ExclusiveIndicatorMask: + { + static const QCOORD pts1[] = { // normal circle + 5,0, 8,0, 9,1, 10,1, 11,2, 12,3, 12,4, 13,5, + 13,8, 12,9, 12,10, 11,11, 10,12, 9,12, 8,13, + 5,13, 4,12, 3,12, 2,11, 1,10, 1,9, 0,8, 0,5, + 1,4, 1,3, 2,2, 3,1, 4,1 }; + QPointArray a(QCOORDARRLEN(pts1), pts1); + a.translate(r.x(), r.y()); + p->setPen(color1); + p->setBrush(color1); + p->drawPolygon(a); + break; + } + case PE_ScrollBarAddLine: + { + drawPrimitive( PE_ButtonBevel, p, r, cg, + (flags & Style_Enabled) | ((flags & Style_Down) + ? Style_Sunken + : Style_Raised) ); + p->setPen( cg.shadow() ); + p->drawRect( r ); + drawPrimitive( ((flags & Style_Horizontal) ? PE_ArrowRight + : PE_ArrowDown), p, QRect(r.x() + 2, + r.y() + 2, + r.width() - 4, + r.height() - 4), + cg, flags ); + break; + } + case PE_ScrollBarSubLine: + { + drawPrimitive( PE_ButtonBevel, p, r, cg, + (flags & Style_Enabled) | ((flags & Style_Down) + ? Style_Sunken + : Style_Raised) ); + p->setPen( cg.shadow() ); + p->drawRect( r ); + drawPrimitive( ((flags & Style_Horizontal) ? PE_ArrowLeft + : PE_ArrowUp ), p, QRect(r.x() + 2, + r.y() + 2, + r.width() - 4, + r.height() - 4), + cg, flags ); + break; + } + case PE_ScrollBarAddPage: + case PE_ScrollBarSubPage: + { + QPen oldPen = p->pen(); + if ( r.width() < 3 || r.height() < 3 ) { + p->fillRect( r, cg.brush(QColorGroup::Mid) ); + p->setPen( cg.shadow() ); + p->drawRect( r ); + p->setPen( oldPen ); + } else { + int x, + y, + w, + h; + r.rect( &x, &y, &w, &h ); + if ( flags & Style_Horizontal ) { + p->fillRect( x + 2, y + 2, w - 2, + h - 4, + cg.brush(QColorGroup::Mid) ); + // the dark side + p->setPen( cg.dark().dark() ); + p->drawLine( x, y, x + w - 1, y ); + p->setPen( cg.shadow()); + p->drawLine( x, y, x, y + h - 1 ); + + p->setPen( cg.mid().dark()); + p->drawLine( x + 1, y + 1, x + w - 1, + y + 1 ); + p->drawLine( x + 1, y + 1, x + 1, + y + h - 2 ); + + // the bright side! + + p->setPen( cg.button()); + p->drawLine( x + 1, y + h - 2, + x + w - 1, + y + h - 2 ); + p->setPen( cg.shadow()); + p->drawLine( x, y + h - 1, + x + w - 1, + y + h - 1 ); + + } else { + p->fillRect( x + 2, y + 2, w - 4, + h - 2, + cg.brush(QColorGroup::Mid) ); + + // the dark side + p->setPen( cg.dark().dark() ); + p->drawLine( x, y, x + w - 1, y ); + p->setPen( cg.shadow() ); + p->drawLine( x, y, x, y + h - 1 ); + + p->setPen( cg.mid().dark() ); + p->drawLine( x + 1, y + 1, x + w - 2, + y + 1 ); + p->drawLine( x + 1, y + 1, x + 1, + y + h - 1 ); + + // the bright side! + p->setPen( cg.button() ); + p->drawLine( x + w - 2, y + 1, + x + w - 2, + y + h - 1 ); + + p->setPen( cg.shadow() ); + p->drawLine( x + w - 1, y, + x + w - 1, + y + h - 1 ); + + } + } + p->setPen( oldPen ); + break; + } + case PE_ScrollBarSlider: + { + QPoint bo = p->brushOrigin(); + p->setBrushOrigin( r.topLeft() ); + drawPrimitive( PE_ButtonBevel, p, r, cg, Style_Raised ); + p->setBrushOrigin( bo ); + drawRiffles( p, r.x(), r.y(), r.width(), r.height(), cg, + flags & Style_Horizontal ); + p->setPen( cg.shadow() ); + p->drawRect( r ); + if ( flags & Style_HasFocus ) { + drawPrimitive( PE_FocusRect, p, QRect(r.x() + 2, r.y() + 2, + r.width() - 5, + r.height() - 5 ), + cg, flags ); + } + break; + } + default: + QWindowsStyle::drawPrimitive( pe, p, r, cg, flags, opt ); + break; + } + +} + +/*!\reimp + */ +void QPlatinumStyle::drawControl( ControlElement element, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QColorGroup &cg, + SFlags how, + const QStyleOption& opt ) const +{ + switch( element ) { + case CE_PushButton: + { +#ifndef QT_NO_PUSHBUTTON + QColorGroup myCg( cg ); + const QPushButton *btn; + int x1, y1, x2, y2; + bool useBevelButton; + SFlags flags; + flags = Style_Default; + btn = (const QPushButton*)widget; + p->setBrushOrigin( -widget->backgroundOffset().x(), + -widget->backgroundOffset().y() ); + + // take care of the flags based on what we know... + if ( btn->isDown() ) + flags |= Style_Down; + if ( btn->isOn() ) + flags |= Style_On; + if ( btn->isEnabled() ) + flags |= Style_Enabled; + if ( btn->isDefault() ) + flags |= Style_Default; + if (! btn->isFlat() && !(flags & Style_Down)) + flags |= Style_Raised; + + r.coords( &x1, &y1, &x2, &y2 ); + + p->setPen( cg.foreground() ); + p->setBrush( QBrush(cg.button(), NoBrush) ); + + QBrush fill; + if ( btn->isDown() ) { + fill = cg.brush( QColorGroup::Dark ); + // this could be done differently, but this + // makes a down Bezel drawn correctly... + myCg.setBrush( QColorGroup::Mid, fill ); + } else if ( btn->isOn() ) { + fill = QBrush( cg.mid(), Dense4Pattern ); + myCg.setBrush( QColorGroup::Mid, fill ); + } + // to quote the old QPlatinumStlye drawPushButton... + // small or square image buttons as well as toggle buttons are + // bevel buttons (what a heuristic....) + if ( btn->isToggleButton() + || ( btn->pixmap() && + (btn->width() * btn->height() < 1600 || + QABS( btn->width() - btn->height()) < 10 )) ) + useBevelButton = TRUE; + else + useBevelButton = FALSE; + + int diw = pixelMetric( PM_ButtonDefaultIndicator, widget ); + if ( btn->isDefault() ) { + x1 += 1; + y1 += 1; + x2 -= 1; + y2 -= 1; + QColorGroup cg2( myCg ); + SFlags myFlags = flags; + // don't draw the default button sunken, unless it's necessary. + if ( myFlags & Style_Down ) + myFlags ^= Style_Down; + if ( myFlags & Style_Sunken ) + myFlags ^= Style_Sunken; + + cg2.setColor( QColorGroup::Button, cg.mid() ); + if ( useBevelButton ) { + drawPrimitive( PE_ButtonBevel, p, QRect( x1, y1, + x2 - x1 + 1, + y2 - y1 + 1 ), + myCg, myFlags, opt ); + } else { + drawPrimitive( PE_ButtonCommand, p, QRect( x1, y1, + x2 - x1 + 1, + y2 - y1 + 1 ), + cg2, myFlags, opt ); + } + } + + if ( btn->isDefault() || btn->autoDefault() ) { + x1 += diw; + y1 += diw; + x2 -= diw; + y2 -= diw; + } + + if ( !btn->isFlat() || btn->isOn() || btn->isDown() ) { + if ( useBevelButton ) { + // fix for toggle buttons... + if ( flags & (Style_Down | Style_On) ) + flags |= Style_Sunken; + drawPrimitive( PE_ButtonBevel, p, QRect( x1, y1, + x2 - x1 + 1, + y2 - y1 + 1 ), + myCg, flags, opt ); + } else { + + drawPrimitive( PE_ButtonCommand, p, QRect( x1, y1, + x2 - x1 + 1, + y2 - y1 + 1 ), + myCg, flags, opt ); + } + } + + + if ( p->brush().style() != NoBrush ) + p->setBrush( NoBrush ); + break; +#endif + } + case CE_PushButtonLabel: + { +#ifndef QT_NO_PUSHBUTTON + const QPushButton *btn; + bool on; + int x, y, w, h; + SFlags flags; + flags = Style_Default; + btn = (const QPushButton*)widget; + on = btn->isDown() || btn->isOn(); + r.rect( &x, &y, &w, &h ); + if ( btn->isMenuButton() ) { + int dx = pixelMetric( PM_MenuButtonIndicator, widget ); + + QColorGroup g = cg; + int xx = x + w - dx - 4; + int yy = y - 3; + int hh = h + 6; + + if ( !on ) { + p->setPen( g.mid() ); + p->drawLine( xx, yy + 2, xx, yy + hh - 3 ); + p->setPen( g.button() ); + p->drawLine( xx + 1, yy + 1, xx + 1, yy + hh - 2 ); + p->setPen( g.light() ); + p->drawLine( xx + 2, yy + 2, xx + 2, yy + hh - 2 ); + } + if ( btn->isEnabled() ) + flags |= Style_Enabled; + drawPrimitive( PE_ArrowDown, p, QRect(x + w - dx - 1, y + 2, + dx, h - 4), + g, flags, opt ); + w -= dx; + } +#ifndef QT_NO_ICONSET + if ( btn->iconSet() && !btn->iconSet()->isNull() ) { + QIconSet::Mode mode = btn->isEnabled() + ? QIconSet::Normal : QIconSet::Disabled; + if ( mode == QIconSet::Normal && btn->hasFocus() ) + mode = QIconSet::Active; + QIconSet::State state = QIconSet::Off; + if ( btn->isToggleButton() && btn->isOn() ) + state = QIconSet::On; + QPixmap pixmap = btn->iconSet()->pixmap( QIconSet::Small, + mode, state ); + int pixw = pixmap.width(); + int pixh = pixmap.height(); + p->drawPixmap( x + 2, y + h / 2 - pixh / 2, pixmap ); + x += pixw + 4; + w -= pixw + 4; + } +#endif + drawItem( p, QRect( x, y, w, h ), + AlignCenter | ShowPrefix, + btn->colorGroup(), btn->isEnabled(), + btn->pixmap(), btn->text(), -1, + on ? &btn->colorGroup().brightText() + : &btn->colorGroup().buttonText() ); + if ( btn->hasFocus() ) + drawPrimitive( PE_FocusRect, p, + subRect(SR_PushButtonFocusRect, widget), + cg, flags ); + break; +#endif + } + default: + QWindowsStyle::drawControl( element, p, widget, r, cg, how, opt ); + break; + } +} + +/*!\reimp + */ +void QPlatinumStyle::drawComplexControl( ComplexControl control, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QColorGroup &cg, + SFlags how, + SCFlags sub, + SCFlags subActive, + const QStyleOption& opt ) const +{ + switch ( control ) { + case CC_ComboBox: + { + int x, + y, + w, + h; + r.rect( &x, &y, &w, &h ); + p->fillRect( x + 2, y + 2, w - 4, + h - 4, cg.brush(QColorGroup::Button) ); + // the bright side + p->setPen(cg.shadow()); + p->drawLine( x, y, x + w - 1, y ); + p->drawLine( x, y, x, y + h - 1 ); + + p->setPen( cg.light() ); + p->drawLine( x + 1, y + 1, + x + w - 2, y + 1 ); + p->drawLine( x + 1, y + 1, + x + 1, y + h - 2 ); + + // the dark side! + + + p->setPen( cg.mid() ); + p->drawLine( x + 2, y + h - 2, + x + w - 2, y + h - 2 ); + p->drawLine( x + w - 2, y + 2, + x + w - 2, y + h - 2 ); + + p->setPen (cg.shadow() ); + p->drawLine( x + 1, y + h - 1, + x + w - 1, y + h - 1 ); + p->drawLine( x + w - 1, y, + x + w - 1, y + h - 1 ); + + // top left corner: + p->setPen( cg.background() ); + p->drawPoint( x, y ); + p->drawPoint( x + 1, y ); + p->drawPoint( x, y + 1 ); + p->setPen( cg.shadow() ); + p->drawPoint( x + 1, y + 1 ); + p->setPen( white ); + p->drawPoint( x + 3, y + 3 ); + // bottom left corner: + p->setPen( cg.background() ); + p->drawPoint( x, y + h - 1 ); + p->drawPoint( x + 1, y + h - 1 ); + p->drawPoint( x, y + h - 2 ); + p->setPen( cg.shadow() ); + p->drawPoint( x + 1, y + h - 2 ); + // top right corner: + p->setPen( cg.background() ); + p->drawPoint( x + w - 1, y ); + p->drawPoint( x + w - 2, y ); + p->drawPoint( x + w - 1, y + 1 ); + p->setPen( cg.shadow() ); + p->drawPoint( x + w - 2, y + 1 ); + // bottom right corner: + p->setPen( cg.background() ); + p->drawPoint( x + w - 1, y + h - 1 ); + p->drawPoint( x + w - 2, y + h - 1 ); + p->drawPoint( x + w - 1, y + h - 2 ); + p->setPen( cg.shadow() ); + p->drawPoint( x + w - 2, y + h - 2 ); + p->setPen( cg.dark() ); + p->drawPoint( x + w - 3, y + h - 3 ); + + if ( sub & SC_ComboBoxArrow ) { + QRect rTmp = querySubControlMetrics( CC_ComboBox, widget, + SC_ComboBoxArrow, opt ); + int xx = rTmp.x(), + yy = rTmp.y(), + ww = rTmp.width(), + hh = rTmp.height(); + // the bright side + + p->setPen( cg.mid() ); + p->drawLine( xx, yy+2, xx, yy+hh-3 ); + + p->setPen( cg.button() ); + p->drawLine( xx+1, yy+1, xx+ww-2, yy+1 ); + p->drawLine( xx+1, yy+1, xx+1, yy+hh-2 ); + + p->setPen( cg.light() ); + p->drawLine( xx+2, yy+2, xx+2, yy+hh-2 ); + p->drawLine( xx+2, yy+2, xx+ww-2, yy+2 ); + + + // the dark side! + + p->setPen( cg.mid() ); + p->drawLine( xx+3, yy+hh-3 ,xx+ww-3, yy+hh-3 ); + p->drawLine( xx+ww-3, yy+3, xx+ww-3, yy+hh-3 ); + + p->setPen( cg.dark() ); + p->drawLine( xx+2, yy+hh-2 ,xx+ww-2, yy+hh-2 ); + p->drawLine( xx+ww-2, yy+2, xx+ww-2, yy+hh-2 ); + + p->setPen( cg.shadow() ); + p->drawLine( xx+1, yy+hh-1,xx+ww-1, yy+hh-1 ); + p->drawLine( xx+ww-1, yy, xx+ww-1, yy+hh-1 ); + + // top right corner: + p->setPen( cg.background() ); + p->drawPoint( xx + ww - 1, yy ); + p->drawPoint( xx + ww - 2, yy ); + p->drawPoint( xx + ww - 1, yy + 1 ); + p->setPen( cg.shadow() ); + p->drawPoint( xx + ww - 2, yy + 1 ); + // bottom right corner: + p->setPen( cg.background() ); + p->drawPoint( xx + ww - 1, yy + hh - 1 ); + p->drawPoint( xx + ww - 2, yy + hh - 1 ); + p->drawPoint( xx + ww - 1, yy + hh - 2 ); + p->setPen( cg.shadow() ); + p->drawPoint( xx + ww - 2, yy + hh - 2 ); + p->setPen( cg.dark() ); + p->drawPoint( xx + ww - 3, yy + hh - 3 ); + p->setPen( cg.mid() ); + p->drawPoint( xx + ww - 4, yy + hh - 4 ); + + // and the arrows + p->setPen( cg.foreground() ); + QPointArray a ; + a.setPoints( 7, -3,1, 3,1, -2,0, 2,0, -1,-1, 1,-1, 0,-2 ); + a.translate( xx + ww / 2, yy + hh / 2 - 3 ); + p->drawLineSegments( a, 0, 3 ); // draw arrow + p->drawPoint( a[6] ); + a.setPoints( 7, -3,-1, 3,-1, -2,0, 2,0, -1,1, 1,1, 0,2 ); + a.translate( xx + ww / 2, yy + hh / 2 + 2 ); + p->drawLineSegments( a, 0, 3 ); // draw arrow + p->drawPoint( a[6] ); + + } +#ifndef QT_NO_COMBOBOX + if ( sub & SC_ComboBoxEditField ) { + const QComboBox *cmb; + cmb = (const QComboBox*)widget; + // sadly this is pretty much the windows code, except + // for the first fillRect call... + QRect re = + QStyle::visualRect( querySubControlMetrics( CC_ComboBox, + widget, + SC_ComboBoxEditField ), + widget ); + if ( cmb->hasFocus() && !cmb->editable() ) + p->fillRect( re.x() + 1, re.y() + 1, + re.width() - 2, re.height() - 2, + cg.brush( QColorGroup::Highlight ) ); + + if ( cmb->hasFocus() ) { + p->setPen( cg.highlightedText() ); + p->setBackgroundColor( cg.highlight() ); + } else { + p->setPen( cg.text() ); + p->setBackgroundColor( cg.background() ); + } + + if ( cmb->hasFocus() && !cmb->editable() ) { + QRect re = + QStyle::visualRect( subRect( SR_ComboBoxFocusRect, + cmb ), + widget ); + drawPrimitive( PE_FocusRect, p, re, cg, + Style_FocusAtBorder, + QStyleOption(cg.highlight())); + } + if ( cmb->editable() ) { + // need this for the moment... + // was the code in comboButton rect + QRect ir( x + 3, y + 3, + w - 6 - 16, h - 6 ); + if ( QApplication::reverseLayout() ) + ir.moveBy( 16, 0 ); + // end comboButtonRect... + ir.setRect( ir.left() - 1, ir.top() - 1, ir.width() + 2, + ir.height() + 2 ); + qDrawShadePanel( p, ir, cg, TRUE, 2, 0 ); + } + } +#endif + break; + } + case CC_Slider: + { +#ifndef QT_NO_SLIDER + const QSlider *slider = (const QSlider *) widget; + int thickness = pixelMetric( PM_SliderControlThickness, widget ); + int len = pixelMetric( PM_SliderLength, widget ); + int ticks = slider->tickmarks(); + + QRect groove = querySubControlMetrics(CC_Slider, widget, SC_SliderGroove, + opt), + handle = querySubControlMetrics(CC_Slider, widget, SC_SliderHandle, + opt); + + if ((sub & SC_SliderGroove) && groove.isValid()) { + p->fillRect( groove, cg.brush(QColorGroup::Background) ); + + int x, y, w, h; + int mid = thickness / 2; + + if ( ticks & QSlider::Above ) + mid += len / 8; + if ( ticks & QSlider::Below ) + mid -= len / 8; + + if ( slider->orientation() == Horizontal ) { + x = 0; + y = groove.y() + mid - 3; + w = slider->width(); + h = 7; + } else { + x = groove.x() + mid - 3; + y = 0; + w = 7; + h = slider->height(); + } + + p->fillRect( x, y, w, h, cg.brush( QColorGroup::Dark )); + // the dark side + p->setPen( cg.dark() ); + p->drawLine( x, y, x + w - 1, y ); + p->drawLine( x, y, x, y + h - 1); + p->setPen( cg.shadow() ); + p->drawLine( x + 1, y + 1, x + w - 2, y + 1 ); + p->drawLine( x + 1, y + 1, x + 1, y + h - 2 ); + // the bright side! + p->setPen(cg.shadow()); + p->drawLine( x + 1, y + h - 2, x + w - 2, y + h - 2 ); + p->drawLine( x + w - 2, y + 1, x + w - 2, y + h - 2 ); + p->setPen( cg.light() ); + p->drawLine( x, y + h - 1, x + w - 1, y + h - 1 ); + p->drawLine( x + w - 1, y, x + w - 1, y + h - 1 ); + // top left corner: + p->setPen(cg.background()); + p->drawPoint( x, y ); + p->drawPoint( x + 1, y ); + p->drawPoint( x, y + 1 ); + p->setPen(cg.shadow()); + p->drawPoint( x + 1, y + 1 ); + // bottom left corner: + p->setPen( cg.background() ); + p->drawPoint( x, y + h - 1 ); + p->drawPoint( x + 1, y + h - 1 ); + p->drawPoint( x, y + h - 2 ); + p->setPen( cg.light() ); + p->drawPoint( x + 1, y + h - 2 ); + // top right corner: + p->setPen( cg.background() ); + p->drawPoint( x + w - 1, y ); + p->drawPoint( x + w - 2, y ); + p->drawPoint( x + w - 1, y + 1 ); + p->setPen( cg.dark() ); + p->drawPoint( x + w - 2, y + 1 ); + // bottom right corner: + p->setPen( cg.background() ); + p->drawPoint( x + w - 1, y + h - 1 ); + p->drawPoint( x + w - 2, y + h - 1 ); + p->drawPoint( x + w - 1, y + h - 2 ); + p->setPen( cg.light() ); + p->drawPoint( x + w - 2, y + h - 2 ); + p->setPen( cg.dark() ); + p->drawPoint( x + w - 3, y + h - 3 ); + // ### end slider groove + + if ( how & Style_HasFocus ) + drawPrimitive( PE_FocusRect, p, groove, cg ); + } + + if ((sub & SC_SliderHandle) && handle.isValid()) { + const QColor c0 = cg.shadow(); + const QColor c1 = cg.dark(); + const QColor c3 = cg.light(); + + int x1 = handle.x(); + int x2 = handle.x() + handle.width() - 1; + int y1 = handle.y(); + int y2 = handle.y() + handle.height() - 1; + int mx = handle.width() / 2; + int my = handle.height() / 2; + + if ( slider->orientation() == Vertical ) { + // Background + QBrush oldBrush = p->brush(); + p->setBrush( cg.brush( QColorGroup::Button ) ); + p->setPen( NoPen ); + QPointArray a(6); + a.setPoint( 0, x1 + 1, y1 + 1 ); + a.setPoint( 1, x2 - my + 2, y1 + 1 ); + a.setPoint( 2, x2 - 1, y1 + my - 1 ); + a.setPoint( 3, x2 - 1, y2 - my + 1 ); + a.setPoint( 4, x2 - my + 2, y2 - 1 ); + a.setPoint( 5, x1 + 1, y2 - 1 ); + p->drawPolygon( a ); + p->setBrush( oldBrush ); + + // shadow border + p->setPen( c0 ); + p->drawLine( x1, y1 + 1, x1,y2 - 1 ); + p->drawLine( x2 - my + 2, y1, x2, y1 + my - 2 ); + p->drawLine( x2 - my + 2, y2, x2, y1 + my + 2 ); + p->drawLine( x2, y1 + my - 2, x2, y1 + my + 2 ); + p->drawLine( x1 + 1, y1, x2 - my + 2, y1 ); + p->drawLine( x1 + 1, y2, x2 - my + 2, y2 ); + + // light shadow + p->setPen( c3 ); + p->drawLine( x1 + 1, y1 + 2, x1 + 1, y2 - 2 ); + p->drawLine( x1 + 1, y1 + 1, x2 - my + 2, y1 + 1 ); + p->drawLine( x2 - my + 2, y1 + 1, x2 - 1, y1 + my - 2 ); + + // dark shadow + p->setPen(c1); + p->drawLine( x2 - 1, y1 + my - 2, x2 - 1, y1 + my + 2 ); + p->drawLine( x2 - my + 2, y2 - 1, x2 - 1, y1 + my + 2 ); + p->drawLine( x1 + 1, y2 - 1, x2 -my + 2, y2 - 1 ); + + drawRiffles( p, handle.x(), handle.y() + 2, handle.width() - 3, + handle.height() - 4, cg, TRUE ); + } else { // Horizontal + QBrush oldBrush = p->brush(); + p->setBrush( cg.brush( QColorGroup::Button ) ); + p->setPen( NoPen ); + QPointArray a(6); + a.setPoint( 0, x2 - 1, y1 + 1 ); + a.setPoint( 1, x2 - 1, y2 - mx + 2 ); + a.setPoint( 2, x2 - mx + 1, y2 - 1 ); + a.setPoint( 3, x1 + mx - 1, y2 - 1 ); + a.setPoint( 4, x1 + 1, y2 - mx + 2 ); + a.setPoint( 5, x1 + 1, y1 + 1 ); + p->drawPolygon( a ); + p->setBrush( oldBrush ); + + // shadow border + p->setPen( c0 ); + p->drawLine( x1 + 1, y1, x2 - 1, y1 ); + p->drawLine( x1, y2 - mx + 2, x1 + mx - 2, y2 ); + p->drawLine( x2, y2 - mx + 2, x1 + mx + 2, y2 ); + p->drawLine( x1 + mx - 2, y2, x1 + mx + 2, y2 ); + p->drawLine( x1, y1 + 1, x1, y2 - mx + 2 ); + p->drawLine( x2, y1 + 1, x2, y2 - mx + 2 ); + + // light shadow + p->setPen(c3); + p->drawLine( x1 + 1, y1 + 1, x2 - 1, y1 + 1 ); + p->drawLine( x1 + 1, y1 + 1, x1 + 1, y2 - mx + 2 ); + + // dark shadow + p->setPen(c1); + p->drawLine( x2 - 1, y1 + 1, x2 - 1, y2 - mx + 2 ); + p->drawLine( x1 + 1, y2 - mx + 2, x1 + mx - 2, y2 - 1 ); + p->drawLine( x2 - 1, y2 - mx + 2, x1 + mx + 2, y2 - 1 ); + p->drawLine( x1 + mx - 2, y2 - 1, x1 + mx + 2, y2 - 1 ); + + drawRiffles( p, handle.x() + 2, handle.y(), handle.width() - 4, + handle.height() - 5, cg, FALSE ); + } + } + + if ( sub & SC_SliderTickmarks ) + QCommonStyle::drawComplexControl( control, p, widget, r, + cg, how, SC_SliderTickmarks, + subActive, opt ); +#endif + break; + } + default: + QWindowsStyle::drawComplexControl( control, p, widget, r, cg, + how, sub, subActive, opt ); + break; + } +} + + + +/*!\reimp + */ +QRect QPlatinumStyle::querySubControlMetrics( ComplexControl control, + const QWidget *widget, + SubControl sc, + const QStyleOption& opt ) const +{ + switch( control ) { +#ifndef QT_NO_COMBOBOX + case CC_ComboBox: + const QComboBox *cb; + cb = (const QComboBox *)widget; + switch( sc ) { + case SC_ComboBoxArrow: { + QRect ir = cb->rect(); + int xx; + if( QApplication::reverseLayout() ) + xx = ir.x(); + else + xx = ir.x() + ir.width() - 20; + return QRect( xx, ir.y(), 20, ir.height()); } + default: + break; + } + break; +#endif +#ifndef QT_NO_SCROLLBAR + case CC_ScrollBar: { + const QScrollBar *sb; + sb = (const QScrollBar *)widget; + int sliderStart = sb->sliderStart(); + int sbextent = pixelMetric( PM_ScrollBarExtent, widget ); + int maxlen = ((sb->orientation() == Qt::Horizontal) ? + sb->width() : sb->height()) - ( sbextent * 2 ); + + int sliderlen; + + // calculate length + if ( sb->maxValue() != sb->minValue() ) { + uint range = sb->maxValue() - sb->minValue(); + sliderlen = ( sb->pageStep() * maxlen ) / + ( range + sb->pageStep() ); + + int slidermin = pixelMetric( PM_ScrollBarSliderMin, widget ); + if ( sliderlen < slidermin || range > INT_MAX / 2 ) + sliderlen = slidermin; + if ( sliderlen > maxlen ) + sliderlen = maxlen; + } else { + sliderlen = maxlen; + } + + switch ( sc ) { + case SC_ScrollBarSubLine: + if ( sb->orientation() == Qt::Horizontal ) { + int buttonw = QMIN( sb->width() / 2, sbextent ); + return QRect( sb->width() - 2 * buttonw, 0, buttonw, sbextent ); + } else { + int buttonh = QMIN( sb->height() / 2, sbextent ); + return QRect( 0, sb->height() - 2 * buttonh, sbextent, buttonh ); + } + case SC_ScrollBarAddLine: + if ( sb->orientation() == Qt::Horizontal ) { + int buttonw = QMIN( sb->width() / 2, sbextent ); + return QRect( sb->width() - buttonw, 0, sbextent, buttonw ); + } else { + int buttonh = QMIN( sb->height() / 2, sbextent ); + return QRect(0, sb->height() - buttonh, sbextent, buttonh ); + } + case SC_ScrollBarSubPage: + if ( sb->orientation() == Qt::Horizontal ) + return QRect( 1, 0, sliderStart, sbextent ); + return QRect( 0, 1, sbextent, sliderStart ); + case SC_ScrollBarAddPage: + if ( sb->orientation() == Qt::Horizontal ) + return QRect( sliderStart + sliderlen, 0, maxlen - sliderStart - sliderlen, sbextent ); + return QRect( 0, sliderStart + sliderlen, sbextent, maxlen - sliderStart - sliderlen ); + case SC_ScrollBarGroove: + if ( sb->orientation() == Qt::Horizontal ) + return QRect( 1, 0, sb->width() - sbextent * 2, sb->height() ); + return QRect( 0, 1, sb->width(), sb->height() - sbextent * 2 ); + default: + break; + } + break; } +#endif +#ifndef QT_NO_SLIDER + case CC_Slider: { + + const QSlider *slider = (const QSlider *) widget; + int tickOffset = pixelMetric( PM_SliderTickmarkOffset, widget); + int thickness = pixelMetric( PM_SliderControlThickness, widget); + int mid = thickness / 2; + int ticks = slider->tickmarks(); + int len = pixelMetric( PM_SliderLength, widget ); + + switch ( sc ) { + case SC_SliderGroove: + if ( ticks & QSlider::Above ) + mid += len / 8; + if ( ticks & QSlider::Below ) + mid -= len / 8; + if ( slider->orientation() == QSlider::Horizontal ) + return QRect( 0, tickOffset, slider->width(), thickness ); + return QRect( tickOffset, 0, thickness, slider->height() ); + default: + break; + } + break; } +#endif + default: + break; + } + return QWindowsStyle::querySubControlMetrics( control, widget, sc, opt ); +} + + +/*!\reimp + */ +int QPlatinumStyle::pixelMetric( PixelMetric metric, + const QWidget *widget ) const +{ + int ret; + switch( metric ) { + case PM_ButtonDefaultIndicator: + ret = 3; + break; + case PM_ButtonShiftHorizontal: + case PM_ButtonShiftVertical: + ret = 0; + break; + case PM_IndicatorWidth: + ret = 15; + break; + case PM_IndicatorHeight: + ret = 13; + break; + case PM_ExclusiveIndicatorHeight: + case PM_ExclusiveIndicatorWidth: + ret = 15; + break; + case PM_SliderLength: + ret = 17; + break; + case PM_MaximumDragDistance: + ret = -1; + break; + default: + ret = QWindowsStyle::pixelMetric( metric, widget ); + break; + } + return ret; +} + +/*!\reimp + */ +QRect QPlatinumStyle::subRect( SubRect r, const QWidget *widget ) const +{ + QRect rect; + switch ( r ) { + case SR_ComboBoxFocusRect: + { + QRect tmpR = widget->rect(); + rect = QRect( tmpR.x() + 4, tmpR.y() + 4, tmpR.width() - 8 - 16, + tmpR.height() - 8 ); + break; + } + default: + rect = QWindowsStyle::subRect( r, widget ); + break; + } + return rect; +} + +/*! + Mixes two colors \a c1 and \a c2 to a new color. +*/ +QColor QPlatinumStyle::mixedColor(const QColor &c1, const QColor &c2) const +{ + int h1,s1,v1,h2,s2,v2; + c1.hsv(&h1,&s1,&v1); + c2.hsv(&h2,&s2,&v2); + return QColor( (h1+h2)/2, (s1+s2)/2, (v1+v2)/2, QColor::Hsv ); +} + +/*! + Draws the nifty Macintosh decoration used on sliders using painter + \a p and colorgroup \a g. \a x, \a y, \a w, \a h and \a horizontal + specify the geometry and orientation of the riffles. +*/ +void QPlatinumStyle::drawRiffles( QPainter* p, int x, int y, int w, int h, + const QColorGroup &g, bool horizontal ) const +{ + if (!horizontal) { + if (h > 20) { + y += (h-20)/2 ; + h = 20; + } + if (h > 8) { + int n = h / 4; + int my = y+h/2-n; + int i ; + p->setPen(g.light()); + for (i=0; idrawLine(x+3, my+2*i, x+w-5, my+2*i); + } + p->setPen(g.dark()); + my++; + for (i=0; idrawLine(x+4, my+2*i, x+w-4, my+2*i); + } + } + } + else { + if (w > 20) { + x += (w-20)/2 ; + w = 20; + } + if (w > 8) { + int n = w / 4; + int mx = x+w/2-n; + int i ; + p->setPen(g.light()); + for (i=0; idrawLine(mx+2*i, y+3, mx + 2*i, y+h-5); + } + p->setPen(g.dark()); + mx++; + for (i=0; idrawLine(mx+2*i, y+4, mx + 2*i, y+h-4); + } + } + } +} + + +#endif diff --git a/src/styles/qplatinumstyle.h b/src/styles/qplatinumstyle.h new file mode 100644 index 0000000..8c83aea --- /dev/null +++ b/src/styles/qplatinumstyle.h @@ -0,0 +1,117 @@ +/**************************************************************************** +** +** Definition of Platinum-like style class +** +** Created : 981231 +** +** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the widgets module of the Qt GUI Toolkit. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** This file may be used under the terms of the Q Public License as +** defined by Trolltech ASA and appearing in the file LICENSE.QPL +** included in the packaging of this file. Licensees holding valid Qt +** Commercial licenses may use this file in accordance with the Qt +** Commercial License Agreement provided with the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef QPLATINUMSTYLE_H +#define QPLATINUMSTYLE_H + +#ifndef QT_H +#include "qwindowsstyle.h" +#endif // QT_H + +#if !defined(QT_NO_STYLE_PLATINUM) || defined(QT_PLUGIN) + +class QPalette; + +#if defined(QT_PLUGIN) +#define Q_EXPORT_STYLE_PLATINUM +#else +#define Q_EXPORT_STYLE_PLATINUM Q_EXPORT +#endif + +class Q_EXPORT_STYLE_PLATINUM QPlatinumStyle : public QWindowsStyle +{ + Q_OBJECT +public: + QPlatinumStyle(); + virtual ~QPlatinumStyle(); + + // new Style Stuff + void drawPrimitive( PrimitiveElement pe, + QPainter *p, + const QRect &r, + const QColorGroup &cg, + SFlags flags = Style_Default, + const QStyleOption& = QStyleOption::Default ) const; + + void drawControl( ControlElement element, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QColorGroup &cg, + SFlags how = Style_Default, + const QStyleOption& = QStyleOption::Default ) const; + + void drawComplexControl( ComplexControl control, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QColorGroup &cg, + SFlags how = Style_Default, +#ifdef Q_QDOC + SCFlags sub = SC_All, +#else + SCFlags sub = (uint)SC_All, +#endif + SCFlags subActive = SC_None, + const QStyleOption& = QStyleOption::Default ) const; + + QRect querySubControlMetrics( ComplexControl control, + const QWidget *widget, + SubControl sc, + const QStyleOption& = QStyleOption::Default ) const; + + int pixelMetric( PixelMetric metric, const QWidget *widget = 0 ) const; + + QRect subRect( SubRect r, const QWidget *widget ) const; + +protected: + QColor mixedColor(const QColor &, const QColor &) const; + void drawRiffles( QPainter* p, int x, int y, int w, int h, + const QColorGroup &g, bool horizontal ) const; +private: // Disabled copy constructor and operator= +#if defined(Q_DISABLE_COPY) + QPlatinumStyle( const QPlatinumStyle & ); + QPlatinumStyle& operator=( const QPlatinumStyle & ); +#endif +}; + +#endif // QT_NO_STYLE_PLATINUM + +#endif // QPLATINUMSTYLE_H diff --git a/src/styles/qsgistyle.cpp b/src/styles/qsgistyle.cpp new file mode 100644 index 0000000..1bfc113 --- /dev/null +++ b/src/styles/qsgistyle.cpp @@ -0,0 +1,1468 @@ +/**************************************************************************** +** +** Implementation of Motif-like style class +** +** Created : 981231 +** +** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the widgets module of the Qt GUI Toolkit. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** This file may be used under the terms of the Q Public License as +** defined by Trolltech ASA and appearing in the file LICENSE.QPL +** included in the packaging of this file. Licensees holding valid Qt +** Commercial licenses may use this file in accordance with the Qt +** Commercial License Agreement provided with the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "qsgistyle.h" + +#if !defined(QT_NO_STYLE_SGI) || defined(QT_PLUGIN) + +#include "qpopupmenu.h" +#include "qapplication.h" +#include "qbutton.h" +#include "qpainter.h" +#include "qdrawutil.h" +#include "qpixmap.h" +#include "qpalette.h" +#include "qwidget.h" +#include "qpushbutton.h" +#include "qscrollbar.h" +#include "qcombobox.h" +#include "qslider.h" +#include "qtextedit.h" +#include "qtoolbar.h" +#include "qlineedit.h" +#include "qmenubar.h" +#include + +#ifndef QT_NO_SLIDER +struct SliderLastPosition +{ + SliderLastPosition() : rect(0,-1,0,-1), slider(0) {} + QRect rect; + const QSlider* slider; +}; +#endif + +#ifndef QT_NO_SCROLLBAR +struct ScrollbarLastPosition +{ + ScrollbarLastPosition() : rect( 0,-1, 0,-1 ), scrollbar(0) {} + QRect rect; + const QScrollBar *scrollbar; +}; +#endif + +class QSGIStylePrivate +{ +public: + QSGIStylePrivate() + : hotWidget( 0 ), mousePos( -1, -1 ) + { + } + + const QWidget *hotWidget; + QPoint mousePos; +#ifndef QT_NO_SCROLLBAR + ScrollbarLastPosition lastScrollbarRect; +#endif +#ifndef QT_NO_SLIDER + SliderLastPosition lastSliderRect; +#endif +}; + +/*! + \class QSGIStyle qsgistyle.h + \brief The QSGIStyle class provides SGI/Irix look and feel. + + \ingroup appearance + + This class implements the SGI look and feel. It resembles the + SGI/Irix Motif GUI style as closely as QStyle allows. +*/ + +/*! + Constructs a QSGIStyle. + + If \a useHighlightCols is FALSE (default value), the style will + polish the application's color palette to emulate the Motif way of + highlighting, which is a simple inversion between the base and the + text color. + + \sa QMotifStyle::useHighlightColors() +*/ +QSGIStyle::QSGIStyle( bool useHighlightCols ) : QMotifStyle( useHighlightCols ), isApplicationStyle( 0 ) +{ + d = new QSGIStylePrivate; +} + +/*! + Destroys the style. +*/ +QSGIStyle::~QSGIStyle() +{ + delete d; +} + +/*! + \reimp + + Changes some application-wide settings to be SGI-like, e.g. sets a + bold italic font for menu options. +*/ +void +QSGIStyle::polish( QApplication* app) +{ + isApplicationStyle = 1; + QMotifStyle::polish( app ); + + QPalette pal = QApplication::palette(); + // check this on SGI-Boxes + //pal.setColor( QColorGroup::Background, pal.active().midlight() ); + if (pal.active().button() == pal.active().background()) + pal.setColor( QColorGroup::Button, pal.active().button().dark(120) ); + // darker basecolor in list-widgets + pal.setColor( QColorGroup::Base, pal.active().base().dark(130) ); + if (! useHighlightColors() ) { + pal.setColor( QPalette::Active, QColorGroup::Highlight, pal.active().text() ); + pal.setColor( QPalette::Active, QColorGroup::HighlightedText, pal.active().base() ); + pal.setColor( QPalette::Inactive, QColorGroup::Highlight, pal.inactive().text() ); + pal.setColor( QPalette::Inactive, QColorGroup::HighlightedText, pal.inactive().base() ); + pal.setColor( QPalette::Disabled, QColorGroup::Highlight, pal.disabled().text() ); + pal.setColor( QPalette::Disabled, QColorGroup::HighlightedText, pal.disabled().base() ); + } + QApplication::setPalette( pal, TRUE ); + + // different basecolor and highlighting in Q(Multi)LineEdit + pal.setColor( QColorGroup::Base, QColor(211,181,181) ); + pal.setColor( QPalette::Active, QColorGroup::Highlight, pal.active().midlight() ); + pal.setColor( QPalette::Active, QColorGroup::HighlightedText, pal.active().text() ); + pal.setColor( QPalette::Inactive, QColorGroup::Highlight, pal.inactive().midlight() ); + pal.setColor( QPalette::Inactive, QColorGroup::HighlightedText, pal.inactive().text() ); + pal.setColor( QPalette::Disabled, QColorGroup::Highlight, pal.disabled().midlight() ); + pal.setColor( QPalette::Disabled, QColorGroup::HighlightedText, pal.disabled().text() ); + + QApplication::setPalette( pal, TRUE, "QLineEdit" ); + QApplication::setPalette( pal, TRUE, "QTextEdit" ); + QApplication::setPalette( pal, TRUE, "QDateTimeEditBase" ); + + pal = QApplication::palette(); + pal.setColor( QColorGroup::Button, pal.active().background() ); + QApplication::setPalette( pal, TRUE, "QMenuBar" ); + QApplication::setPalette( pal, TRUE, "QToolBar" ); + QApplication::setPalette( pal, TRUE, "QPopupMenu" ); +} + +/*! \reimp +*/ +void +QSGIStyle::unPolish( QApplication* /* app */ ) +{ + QFont f = QApplication::font(); + QApplication::setFont( f, TRUE ); // get rid of the special fonts for special widget classes +} + +/*! + \reimp + + Installs an event filter for several widget classes to enable + hovering. +*/ +void +QSGIStyle::polish( QWidget* w ) +{ + QMotifStyle::polish(w); + + if ( !isApplicationStyle ) { + QPalette sgiPal = QApplication::palette(); + + sgiPal.setColor( QColorGroup::Background, sgiPal.active().midlight() ); + if (sgiPal.active().button() == sgiPal.active().background()) + sgiPal.setColor( QColorGroup::Button, sgiPal.active().button().dark(110) ); + sgiPal.setColor( QColorGroup::Base, sgiPal.active().base().dark(130) ); + if (! useHighlightColors() ) { + sgiPal.setColor( QPalette::Active, QColorGroup::Highlight, sgiPal.active().text() ); + sgiPal.setColor( QPalette::Active, QColorGroup::HighlightedText, sgiPal.active().base() ); + sgiPal.setColor( QPalette::Inactive, QColorGroup::Highlight, sgiPal.inactive().text() ); + sgiPal.setColor( QPalette::Inactive, QColorGroup::HighlightedText, sgiPal.inactive().base() ); + sgiPal.setColor( QPalette::Disabled, QColorGroup::Highlight, sgiPal.disabled().text() ); + sgiPal.setColor( QPalette::Disabled, QColorGroup::HighlightedText, sgiPal.disabled().base() ); + } + + if ( ::qt_cast(w) || ::qt_cast(w) ) { + // different basecolor and highlighting in Q(Multi)LineEdit + sgiPal.setColor( QColorGroup::Base, QColor(211,181,181) ); + sgiPal.setColor( QPalette::Active, QColorGroup::Highlight, sgiPal.active().midlight() ); + sgiPal.setColor( QPalette::Active, QColorGroup::HighlightedText, sgiPal.active().text() ); + sgiPal.setColor( QPalette::Inactive, QColorGroup::Highlight, sgiPal.inactive().midlight() ); + sgiPal.setColor( QPalette::Inactive, QColorGroup::HighlightedText, sgiPal.inactive().text() ); + sgiPal.setColor( QPalette::Disabled, QColorGroup::Highlight, sgiPal.disabled().midlight() ); + sgiPal.setColor( QPalette::Disabled, QColorGroup::HighlightedText, sgiPal.disabled().text() ); + + } else if ( ::qt_cast(w) || ::qt_cast(w) ) { + sgiPal.setColor( QColorGroup::Button, sgiPal.active().midlight() ); + } + + w->setPalette( sgiPal ); + } + + if ( ::qt_cast(w) || ::qt_cast(w) || ::qt_cast(w) ) { + w->installEventFilter( this ); + w->setMouseTracking( TRUE ); +#ifndef QT_NO_SCROLLBAR + if ( ::qt_cast(w) ) + w->setBackgroundMode( QWidget::NoBackground ); +#endif + } else if ( ::qt_cast(w) ) { + QFont f = QApplication::font(); + f.setBold( TRUE ); + f.setItalic( TRUE ); + w->setFont( f ); +#ifndef QT_NO_MENUBAR + } else if ( ::qt_cast(w) ) { + ((QFrame*) w)->setFrameStyle(QFrame::StyledPanel | QFrame::Raised); + w->setBackgroundMode( QWidget::PaletteBackground ); + QFont f = QApplication::font(); + f.setBold( TRUE ); + f.setItalic( TRUE ); + w->setFont( f ); +#endif +#ifndef QT_NO_POPUPMENU + } else if ( ::qt_cast(w) ) { + ((QFrame*) w)->setLineWidth( pixelMetric( PM_DefaultFrameWidth ) + 1 ); + QFont f = QApplication::font(); + f.setBold( TRUE ); + f.setItalic( TRUE ); + w->setFont( f ); +#endif + } else if ( ::qt_cast(w) || w->inherits("QToolBarSeparator") ) { + w->setBackgroundMode( QWidget::PaletteBackground ); + } +} + +/*! \reimp */ +void +QSGIStyle::unPolish( QWidget* w ) +{ + if ( ::qt_cast(w) || ::qt_cast(w) || ::qt_cast(w) ) { + w->removeEventFilter( this ); +#ifndef QT_NO_POPUPMENU + } else if ( ::qt_cast(w) ) { + ((QFrame*)w)->setLineWidth( pixelMetric( PM_DefaultFrameWidth ) ); + w->setFont( QApplication::font() ); +#endif +#if !defined(QT_NO_MENUBAR) || !defined(QT_NO_COMBOBOX) + } else if ( ::qt_cast(w) || ::qt_cast(w) ) { + w->setFont( QApplication::font() ); +#endif + } +} + +/*! \reimp */ +bool QSGIStyle::eventFilter( QObject* o, QEvent* e ) +{ + if ( !o->isWidgetType() || e->type() == QEvent::Paint ) + return QMotifStyle::eventFilter( o, e ); + + QWidget *widget = (QWidget*)o; + + switch ( e->type() ) { + case QEvent::MouseButtonPress: + { +#ifndef QT_NO_SCROLLBAR + if ( ::qt_cast(widget) ) { + d->lastScrollbarRect.rect = ((QScrollBar*)widget)->sliderRect(); + d->lastScrollbarRect.scrollbar = ((QScrollBar*)widget); + widget->repaint( FALSE ); + } else +#endif + { +#ifndef QT_NO_SLIDER + if ( ::qt_cast(widget) ) { + d->lastSliderRect.rect = ((QSlider*)widget)->sliderRect(); + d->lastSliderRect.slider = ((QSlider*)widget); + widget->repaint( FALSE ); + } +#endif + } + } + break; + + case QEvent::MouseButtonRelease: + { + if ( 0 ) { +#ifndef QT_NO_SCROLLBAR + } else if ( ::qt_cast(widget) ) { + QRect oldRect = d->lastScrollbarRect.rect; + d->lastScrollbarRect.rect = QRect( 0, -1, 0, -1 ); + widget->repaint( oldRect, FALSE ); +#endif +#ifndef QT_NO_SLIDER + } else if ( ::qt_cast(widget) ) { + QRect oldRect = d->lastSliderRect.rect; + d->lastSliderRect.rect = QRect( 0, -1, 0, -1 ); + widget->repaint( oldRect, FALSE ); +#endif + } + } + break; + + case QEvent::MouseMove: + if ( !widget->isActiveWindow() ) + break; + if ( ((QMouseEvent*)e)->button() ) + break; + + d->hotWidget = widget; + d->mousePos = ((QMouseEvent*)e)->pos(); + widget->repaint( FALSE ); + break; + + case QEvent::Enter: + if ( !widget->isActiveWindow() ) + break; + d->hotWidget = widget; + widget->repaint( FALSE ); + break; + + case QEvent::Leave: + if ( !widget->isActiveWindow() ) + break; + if ( widget == d->hotWidget) { + d->hotWidget = 0; + widget->repaint( FALSE ); + } + break; + + default: + break; + } + return QMotifStyle::eventFilter( o, e ); +} + +static const int sgiItemFrame = 2; // menu item frame width +// static const int sgiSepHeight = 1; // separator item height +static const int sgiItemHMargin = 3; // menu item hor text margin +static const int sgiItemVMargin = 2; // menu item ver text margin +static const int sgiArrowHMargin = 6; // arrow horizontal margin +static const int sgiTabSpacing = 12; // space between text and tab +// static const int sgiCheckMarkHMargin = 2; // horiz. margins of check mark ### not used?!? +static const int sgiCheckMarkSpace = 20; + +/*! \reimp */ +int QSGIStyle::pixelMetric( PixelMetric metric, const QWidget *widget ) const +{ + switch ( metric ) { + case PM_DefaultFrameWidth: + return 2; + + case PM_ButtonDefaultIndicator: + return 4; + + case PM_ScrollBarExtent: + return 21; + + case PM_IndicatorWidth: + case PM_IndicatorHeight: + return 14; + + case PM_ExclusiveIndicatorWidth: + case PM_ExclusiveIndicatorHeight: + return 12; + + case PM_SplitterWidth: + return QMAX( 10, QApplication::globalStrut().width() ); + + default: + break; + } + return QMotifStyle::pixelMetric( metric, widget ); +} + +static void drawPanel( QPainter *p, int x, int y, int w, int h, + const QColorGroup &g, bool sunken, + int lineWidth, const QBrush* fill) +{ + if ( w == 0 || h == 0 ) + return; +#if defined(CHECK_RANGE) + ASSERT( w > 0 && h > 0 && lineWidth >= 0 ); +#endif + QPen oldPen = p->pen(); // save pen + QPointArray a( 4*lineWidth ); + if ( sunken ) + p->setPen( g.dark() ); + else + p->setPen( g.light() ); + int x1, y1, x2, y2; + int i; + int n = 0; + x1 = x; + y1 = y2 = y; + x2 = x+w-2; + for ( i=0; idrawLineSegments( a ); + n = 0; + if ( sunken ) + p->setPen( g.light() ); + else + p->setPen( g.dark() ); + x1 = x; + y1 = y2 = y+h-1; + x2 = x+w-1; + for ( i=0; idrawLineSegments( a ); + if ( fill ) { // fill with fill color + QBrush oldBrush = p->brush(); + p->setPen( Qt::NoPen ); + p->setBrush( *fill ); + p->drawRect( x+lineWidth, y+lineWidth, w-lineWidth*2, h-lineWidth*2 ); + p->setBrush( oldBrush ); + } + p->setPen( oldPen ); // restore pen +} + +static void drawSeparator( QPainter *p, int x1, int y1, int x2, int y2, + const QColorGroup &g ) +{ + QPen oldPen = p->pen(); + + p->setPen( g.midlight() ); + p->drawLine( x1, y1, x2, y2 ); + p->setPen( g.shadow() ); + if ( y2-y1 < x2-x1 ) + p->drawLine( x1, y1+1, x2, y2+1 ); + else + p->drawLine( x1+1, y1, x2+1, y2 ); + + p->setPen( oldPen ); +} + +static void drawSGIPrefix( QPainter *p, int x, int y, QString* miText ) +{ + if ( miText && (!!(*miText)) ) { + int amp = 0; + bool nextAmp = FALSE; + while ( ( amp = miText->find( '&', amp ) ) != -1 ) { + if ( (uint)amp == miText->length()-1 ) + return; + miText->remove( amp,1 ); + nextAmp = (*miText)[amp] == '&'; // next time if && + + if ( !nextAmp ) { // draw special underlining + uint ulx = p->fontMetrics().width(*miText, amp); + + uint ulw = p->fontMetrics().width(*miText, amp+1) - ulx; + + p->drawLine( x+ulx, y, x+ulx+ulw, y ); + p->drawLine( x+ulx, y+1, x+ulx+ulw/2, y+1 ); + p->drawLine( x+ulx, y+2, x+ulx+ulw/4, y+2 ); + } + amp++; + } + } +} + +static int get_combo_extra_width( int h, int *return_awh=0 ) +{ + int awh; + if ( h < 8 ) { + awh = 6; + } else if ( h < 14 ) { + awh = h - 2; + } else { + awh = h/2; + } + if ( return_awh ) + *return_awh = awh; + return awh*2; +} + +static void get_combo_parameters( const QRect &r, + int &ew, int &awh, int &ax, + int &ay, int &sh, int &dh, + int &sy ) +{ + ew = get_combo_extra_width( r.height(), &awh ); + + sh = (awh+3)/4; + if ( sh < 3 ) + sh = 3; + dh = sh/2 + 1; + + ay = r.y() + (r.height()-awh-sh-dh)/2; + if ( ay < 0 ) { + //panic mode + ay = 0; + sy = r.height(); + } else { + sy = ay+awh+dh; + } + if( QApplication::reverseLayout() ) + ax = r.x(); + else + ax = r.x() + r.width() - ew; + ax += (ew-awh)/2; +} + +/*! \reimp */ +void QSGIStyle::drawPrimitive( PrimitiveElement pe, + QPainter *p, + const QRect &r, + const QColorGroup &cg, + SFlags flags, + const QStyleOption& opt ) const +{ + const int x = r.x(); + const int y = r.y(); + const int w = r.width(); + const int h = r.height(); + const bool sunken = flags & ( Style_Sunken | Style_Down | Style_On ); + const int defaultFrameWidth = pixelMetric( PM_DefaultFrameWidth ); + bool hot = ( flags & Style_MouseOver ) && ( flags & Style_Enabled ); + + switch ( pe ) { + case PE_ButtonCommand: + { + QBrush fill; + if ( hot ) { + if ( sunken ) + fill = cg.brush( QColorGroup::Dark ); + else + fill = cg.brush( QColorGroup::Midlight ); + } else if ( sunken ) { + fill = cg.brush( QColorGroup::Mid ); + } else { + fill = cg.brush( QColorGroup::Button ); + } + + drawPanel( p, x, y, w, h, cg, sunken, defaultFrameWidth, &fill ); + } + break; + + case PE_PanelPopup: + case PE_ButtonBevel: + case PE_ButtonTool: + { + drawPrimitive( PE_ButtonCommand, p, QRect( x+1, y+1, w-2, h-2 ), cg, flags, opt ); + + QPen oldPen = p->pen(); + QPointArray a; + + // draw twocolored rectangle + p->setPen( sunken ? cg.light() : cg.dark().dark(200) ); + a.setPoints( 3, x, y+h-1, x+w-1, y+h-1, x+w-1, y ); + p->drawPolyline( a ); + p->setPen( cg.dark() ); + a.setPoints( 3, x, y+h-2, x, y, x+w-2, y ); + p->drawPolyline( a ); + + p->setPen( oldPen ); + } + break; + + case PE_ArrowUp: + case PE_ArrowDown: + case PE_ArrowLeft: + case PE_ArrowRight: + { + QPointArray a; // arrow polygon + switch ( pe ) { + case PE_ArrowUp: + a.setPoints( 3, 0,-5, -5,4, 4,4 ); + break; + case PE_ArrowDown: + a.setPoints( 3, 0,4, -4,-4, 4,-4 ); + break; + case PE_ArrowLeft: + a.setPoints( 3, -4,0, 4,-5, 4,4 ); + break; + case PE_ArrowRight: + a.setPoints( 3, 4,0, -4,-5, -4,4 ); + break; + default: + return; + } + + p->save(); + p->setPen( Qt::NoPen ); + a.translate( x+w/2, y+h/2 ); + p->setBrush( flags & Style_Enabled ? cg.dark() : cg.light() ); + p->drawPolygon( a ); // draw arrow + p->restore(); + } + break; + + case PE_Indicator: + { + QRect er = r; + er.addCoords( 1, 1, -1, -1 ); + int iflags = flags & ~Style_On; + drawPrimitive( PE_ButtonBevel, p, er, cg, iflags, opt ); + if ( !(flags & QStyle::Style_Off) ) { + er = r; + er.addCoords( 1, 2, 1, 1 ); + drawPrimitive( PE_CheckMark, p, er, cg, flags, opt ); + } + } + break; + + case PE_IndicatorMask: + { + QPen oldPen = p->pen(); + QBrush oldBrush = p->brush(); + + p->setPen( Qt::color1 ); + p->setBrush( Qt::color1 ); + p->fillRect( x, y, w, h, QBrush( Qt::color0 ) ); + QRect er = r; + er.addCoords( 1, 1, -1, -1 ); + p->fillRect(er, QBrush(Qt::color1)); + + if ( !(flags & QStyle::Style_Off) ) { + er = r; + er.addCoords( 1, 2, 1, 1 ); + static const QCOORD check_mark[] = { + 14,0, 10,0, 11,1, 8,1, 9,2, 7,2, 8,3, 6,3, + 7,4, 1,4, 6,5, 1,5, 6,6, 3,6, 5,7, 4,7, + 5,8, 5,8, 4,3, 2,3, 3,2, 3,2 }; + + QPointArray amark; + amark = QPointArray( sizeof(check_mark)/(sizeof(QCOORD)*2), check_mark ); + amark.translate( er.x()+1, er.y()+1 ); + p->drawLineSegments( amark ); + amark.translate( -1, -1 ); + p->drawLineSegments( amark ); + } + + p->setBrush( oldBrush ); + p->setPen( oldPen ); + } + break; + + case PE_CheckMark: + { + static const QCOORD check_mark[] = { + 14,0, 10,0, 11,1, 8,1, 9,2, 7,2, 8,3, 6,3, + 7,4, 1,4, 6,5, 1,5, 6,6, 3,6, 5,7, 4,7, + 5,8, 5,8, 4,3, 2,3, 3,2, 3,2 }; + + QPen oldPen = p->pen(); + + QPointArray amark; + amark = QPointArray( sizeof(check_mark)/(sizeof(QCOORD)*2), check_mark ); + amark.translate( x+1, y+1 ); + + if ( flags & Style_On ) { + p->setPen( flags & Style_Enabled ? cg.shadow() : cg.dark() ); + p->drawLineSegments( amark ); + amark.translate( -1, -1 ); + p->setPen( flags & Style_Enabled ? QColor(255,0,0) : cg.dark() ); + p->drawLineSegments( amark ); + p->setPen( oldPen ); + } else { + p->setPen( flags & Style_Enabled ? cg.dark() : cg.mid() ); + p->drawLineSegments( amark ); + amark.translate( -1, -1 ); + p->setPen( flags & Style_Enabled ? QColor(230,120,120) : cg.dark() ); + p->drawLineSegments( amark ); + p->setPen( oldPen ); + } + } + break; + + case PE_ExclusiveIndicator: + { + p->save(); + p->eraseRect( x, y, w, h ); + p->translate( x, y ); + + p->setPen( cg.button() ); + p->setBrush( hot ? cg.midlight() : cg.button() ); + QPointArray a; + a.setPoints( 4, 5,0, 11,6, 6,11, 0,5); + p->drawPolygon( a ); + + p->setPen( cg.dark() ); + p->drawLine( 0,5, 5,0 ); + p->drawLine( 6,0, 11,5 ); + p->setPen( flags & Style_Down ? cg.light() : cg.dark() ); + p->drawLine( 11,6, 6,11 ); + p->drawLine( 5,11, 0,6 ); + p->drawLine( 2,7, 5,10 ); + p->drawLine( 6,10, 9,7 ); + p->setPen( cg.light() ); + p->drawLine( 2,5, 5,2 ); + + if ( flags & Style_On ) { + p->setPen( flags & Style_Enabled ? Qt::blue : Qt::darkGray ); + p->setBrush( flags & Style_Enabled ? Qt::blue : Qt::darkGray ); + a.setPoints(3, 6,2, 8,4, 6,6 ); + p->drawPolygon( a ); + p->setBrush( Qt::NoBrush ); + + p->setPen( cg.shadow() ); + p->drawLine( 7,7, 9,5 ); + } else { + p->drawLine( 6,2, 9,5 ); + } + p->restore(); + } + break; + + case PE_ExclusiveIndicatorMask: + { + p->save(); + QPen oldPen = p->pen(); + QBrush oldBrush = p->brush(); + + p->setPen( Qt::color1 ); + p->setBrush( Qt::color1 ); + QPointArray a; + a.setPoints( 8, 0,5, 5,0, 6,0, 11,5, 11,6, 6,11, 5,11, 0,6 ); + a.translate( x, y ); + p->drawPolygon( a ); + + p->setBrush( oldBrush ); + p->setPen( oldPen ); + p->restore(); + } + break; + + case PE_Panel: + { + const int lineWidth = opt.isDefault() ? defaultFrameWidth : opt.lineWidth(); + drawPanel( p, x, y, w, h, cg, flags & (Style_Sunken | Style_Down | Style_On), lineWidth, 0 ); + if ( lineWidth <= 1 ) + return; + + // draw extra shadinglines + QPen oldPen = p->pen(); + p->setPen( cg.midlight() ); + p->drawLine( x+1, y+h-3, x+1, y+1 ); + p->drawLine( x+1, y+1, x+w-3, y+1 ); + p->setPen( cg.mid() ); + p->drawLine( x+1, y+h-2, x+w-2, y+h-2 ); + p->drawLine( x+w-2, y+h-2, x+w-2, y+1 ); + p->setPen(oldPen); + } + break; + + case PE_ScrollBarSubLine: + if ( !r.contains( d->mousePos ) && !(flags & Style_Active) ) + flags &= ~Style_MouseOver; + drawPrimitive( PE_ButtonCommand, p, r, cg, flags, opt ); + drawPrimitive(((flags & Style_Horizontal) ? PE_ArrowLeft : PE_ArrowUp), + p, r, cg, Style_Enabled | flags); + break; + + case PE_ScrollBarAddLine: + if ( !r.contains( d->mousePos ) ) + flags &= ~Style_MouseOver; + drawPrimitive( PE_ButtonCommand, p, r, cg, flags, opt ); + drawPrimitive(((flags & Style_Horizontal) ? PE_ArrowRight : PE_ArrowDown), + p, r, cg, Style_Enabled | flags); + break; + + case PE_ScrollBarSubPage: + case PE_ScrollBarAddPage: + if ( !r.contains( d->mousePos ) ) + flags &= ~Style_MouseOver; + if ( r.isValid() ) + qDrawShadePanel( p, x, y, w, h, cg, FALSE, 1, hot ? &cg.brush( QColorGroup::Midlight ) : &cg.brush( QColorGroup::Button ) ); + break; + + case PE_ScrollBarSlider: + { + if ( !r.isValid() ) + break; + if ( !(r.contains( d->mousePos ) || flags & Style_Active) || !(flags & Style_Enabled ) ) + flags &= ~Style_MouseOver; + + QPixmap pm( r.width(), r.height() ); + QPainter bp( &pm ); + drawPrimitive(PE_ButtonBevel, &bp, QRect(0,0,r.width(),r.height()), cg, flags | Style_Enabled | Style_Raised); + if ( flags & Style_Horizontal ) { + const int sliderM = r.width() / 2; + if ( r.width() > 20 ) { + drawSeparator( &bp, sliderM-5, 2, sliderM-5, r.height()-3, cg ); + drawSeparator( &bp, sliderM+3, 2, sliderM+3, r.height()-3, cg ); + } + if ( r.width() > 10 ) + drawSeparator( &bp, sliderM-1, 2, sliderM-1, r.height()-3, cg ); + + } else { + const int sliderM = r.height() / 2; + if ( r.height() > 20 ) { + drawSeparator( &bp, 2, sliderM-5, r.width()-3, sliderM-5, cg ); + drawSeparator( &bp, 2, sliderM+3, r.width()-3, sliderM+3, cg ); + } + if ( r.height() > 10 ) + drawSeparator( &bp, 2, sliderM-1, r.width()-3, sliderM-1, cg ); + } + bp.end(); + p->drawPixmap( r.x(), r.y(), pm ); + } + + break; + + case PE_Splitter: + { + const int motifOffset = 10; + int sw = pixelMetric( PM_SplitterWidth ); + if ( flags & Style_Horizontal ) { + int xPos = x + w/2; + int kPos = motifOffset; + int kSize = sw - 2; + + qDrawShadeLine( p, xPos, kPos + kSize - 1 , + xPos, h, cg ); + + drawPrimitive( PE_ButtonBevel, p, QRect(xPos-sw/2+1, kPos, kSize, kSize+1), cg, flags, opt ); + qDrawShadeLine( p, xPos+2, 0, xPos, kPos, cg ); + } else { + int yPos = y + h/2; + int kPos = w - motifOffset - sw; + int kSize = sw - 2; + + qDrawShadeLine( p, 0, yPos, kPos, yPos, cg ); + drawPrimitive( PE_ButtonBevel, p, QRect( kPos, yPos-sw/2+1, kSize+1, kSize ), cg, flags, opt ); + qDrawShadeLine( p, kPos + kSize+1, yPos, w, yPos, cg ); + } + } + break; + + default: + QMotifStyle::drawPrimitive( pe, p, r, cg, flags, opt ); + break; + } +} + +/*! \reimp */ +void QSGIStyle::drawControl( ControlElement element, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QColorGroup &cg, + SFlags flags, + const QStyleOption& opt ) const +{ + if ( widget == d->hotWidget ) + flags |= Style_MouseOver; + + switch ( element ) { + case CE_PushButton: + { +#ifndef QT_NO_PUSHBUTTON + const QPushButton *btn = (QPushButton*)widget; + int x1, y1, x2, y2; + r.coords( &x1, &y1, &x2, &y2 ); + + p->setPen( cg.foreground() ); + p->setBrush( QBrush( cg.button(),Qt::NoBrush ) ); + p->setBrushOrigin( -widget->backgroundOffset().x(), + -widget->backgroundOffset().y() ); + + int diw = pixelMetric( QStyle::PM_ButtonDefaultIndicator ); + if ( btn->isDefault() || btn->autoDefault() ) { + x1 += diw; + y1 += diw; + x2 -= diw; + y2 -= diw; + } + + QPointArray a; + if ( btn->isDefault() ) { + if ( diw == 0 ) { + a.setPoints( 9, + x1, y1, x2, y1, x2, y2, x1, y2, x1, y1+1, + x2-1, y1+1, x2-1, y2-1, x1+1, y2-1, x1+1, y1+1 ); + p->setPen( cg.shadow() ); + p->drawPolyline( a ); + x1 += 2; + y1 += 2; + x2 -= 2; + y2 -= 2; + } else { + qDrawShadePanel( p, btn->rect(), cg, TRUE ); + } + } + + QBrush fill = cg.brush( QColorGroup::Button ); + if ( !btn->isFlat() || btn->isOn() || btn->isDown() ) + drawPrimitive( PE_ButtonBevel, p, QRect( x1, y1, x2-x1+1, y2-y1+1 ), cg, flags, opt ); + + if ( p->brush().style() != Qt::NoBrush ) + p->setBrush( Qt::NoBrush ); +#endif + } + break; + + case CE_PopupMenuItem: + { +#ifndef QT_NO_POPUPMENU + if (! widget || opt.isDefault()) + break; + QMenuItem *mi = opt.menuItem(); + if ( !mi ) + break; + const QPopupMenu *popupmenu = (const QPopupMenu *) widget; + int tab = opt.tabWidth(); + int maxpmw = opt.maxIconWidth(); + bool dis = ! (flags & Style_Enabled); + bool checkable = popupmenu->isCheckable(); + bool act = flags & Style_Active; + int x, y, w, h; + + r.rect(&x, &y, &w, &h); + + if ( checkable ) + maxpmw = QMAX( maxpmw, sgiCheckMarkSpace ); + int checkcol = maxpmw; + + if (mi && mi->isSeparator() ) { + p->setPen( cg.mid() ); + p->drawLine(x, y, x+w, y ); + return; + } + + int pw = sgiItemFrame; + + if ( act && !dis ) { + if ( pixelMetric( PM_DefaultFrameWidth ) > 1 ) + drawPanel( p, x, y, w, h, cg, FALSE, pw, + &cg.brush( QColorGroup::Light ) ); + else + drawPanel( p, x+1, y+1, w-2, h-2, cg, FALSE, 1, + &cg.brush( QColorGroup::Light ) ); + } else { + p->fillRect( x, y, w, h, cg.brush( QColorGroup::Button ) ); + } + + if ( !mi ) + return; + + if ( mi->isChecked() ) { + if ( mi->iconSet() ) { + drawPanel( p, x+sgiItemFrame, y+sgiItemFrame, checkcol, h-2*sgiItemFrame, + cg, TRUE, 1, &cg.brush( QColorGroup::Light ) ); + } + } else { + if ( !act ) + p->fillRect( x+sgiItemFrame, y+sgiItemFrame, checkcol, h-2*sgiItemFrame, + cg.brush( QColorGroup::Button ) ); + } + + if ( mi->iconSet() ) { + QIconSet::Mode mode = QIconSet::Normal; + if ( act && !dis ) + mode = QIconSet::Active; + QPixmap pixmap; + if ( checkable && mi->isChecked() ) + pixmap = mi->iconSet()->pixmap( QIconSet::Small, mode, QIconSet::On ); + else + pixmap = mi->iconSet()->pixmap( QIconSet::Small, mode ); + + int pixw = pixmap.width(); + int pixh = pixmap.height(); + QRect cr( x+sgiItemFrame, y+sgiItemFrame, checkcol, h-2*sgiItemFrame ); + QRect pmr( 0, 0, pixw, pixh ); + pmr.moveCenter( cr.center() ); + p->setPen( cg.text() ); + p->drawPixmap( pmr.topLeft(), pixmap ); + } else { + if ( checkable ) { + SFlags cflags = Style_Default; + if (! dis) + cflags |= Style_Enabled; + if (act) + cflags |= Style_On; + + if ( mi->isChecked() ) { + QRect er( x+sgiItemFrame+1, y+sgiItemFrame+3, + pixelMetric(PM_IndicatorWidth), + pixelMetric(PM_IndicatorHeight) ); + er.addCoords( 1, 1, -1, -1 ); + drawPrimitive( PE_ButtonBevel, p, er, cg, cflags, opt ); + er.addCoords( 0, 1, 1, 1 ); + drawPrimitive( PE_CheckMark, p, er, cg, cflags | Style_On, opt ); + } + } + } + + p->setPen( cg.buttonText() ); + + QColor discol; + if ( dis ) { + discol = cg.text(); + p->setPen( discol ); + } + + int xm = sgiItemFrame + checkcol + sgiItemHMargin; + + if ( mi->custom() ) { + int m = sgiItemVMargin; + p->save(); + mi->custom()->paint( p, cg, act, !dis, + x+xm, y+m, w-xm-tab+1, h-2*m ); + p->restore(); + } + + QString s = mi->text(); + if ( !!s ) { + int t = s.find( '\t' ); + int m = sgiItemVMargin; + const int text_flags = AlignVCenter | DontClip | SingleLine; //special underline for &x + + QString miText = s; + if ( t>=0 ) { + p->drawText(x+w-tab-sgiItemHMargin-sgiItemFrame, + y+m, tab, h-2*m, text_flags, miText.mid( t+1 ) ); + miText = s.mid( 0, t ); + } + QRect br = p->fontMetrics().boundingRect( x+xm, y+m, w-xm-tab+1, h-2*m, + text_flags, mi->text() ); + + drawSGIPrefix( p, br.x()+p->fontMetrics().leftBearing(miText[0]), + br.y()+br.height()+p->fontMetrics().underlinePos()-2, &miText ); + p->drawText( x+xm, y+m, w-xm-tab+1, h-2*m, text_flags, miText, miText.length() ); + } else { + if ( mi->pixmap() ) { + QPixmap *pixmap = mi->pixmap(); + if ( pixmap->depth() == 1 ) + p->setBackgroundMode( OpaqueMode ); + p->drawPixmap( x+xm, y+sgiItemFrame, *pixmap ); + if ( pixmap->depth() == 1 ) + p->setBackgroundMode( TransparentMode ); + } + } + if ( mi->popup() ) { + int dim = (h-2*sgiItemFrame) / 2; + drawPrimitive( PE_ArrowRight, p, QRect( x+w-sgiArrowHMargin-sgiItemFrame-dim, y+h/2-dim/2, dim, dim ), cg, flags ); + } +#endif + } + break; + + case CE_MenuBarItem: + { +#ifndef QT_NO_MENUDATA + if (opt.isDefault()) + break; + + QMenuItem *mi = opt.menuItem(); + + bool active = flags & Style_Active; + int x, y, w, h; + r.rect( &x, &y, &w, &h ); + + if ( active ) { + p->setPen( QPen( cg.shadow(), 1) ); + p->drawRect( x, y, w, h ); + qDrawShadePanel( p, QRect(x+1,y+1,w-2,h-2), cg, FALSE, 2, + &cg.brush( QColorGroup::Light )); + } else { + p->fillRect( x, y, w, h, cg.brush( QColorGroup::Button )); + } + + if ( mi->pixmap() ) + drawItem( p, r, AlignCenter|DontClip|SingleLine, + cg, mi->isEnabled(), mi->pixmap(), "", -1, &cg.buttonText() ); + + if ( !!mi->text() ) { + QString* text = new QString(mi->text()); + QRect br = p->fontMetrics().boundingRect( x, y-2, w+1, h, + AlignCenter|DontClip|SingleLine|ShowPrefix, mi->text() ); + + drawSGIPrefix( p, br.x()+p->fontMetrics().leftBearing((*text)[0]), + br.y()+br.height()+p->fontMetrics().underlinePos()-2, text ); + p->drawText( x, y-2, w+1, h, AlignCenter|DontClip|SingleLine, *text, text->length() ); + delete text; + } +#endif + } + break; + + case CE_CheckBox: + QMotifStyle::drawControl( element, p, widget, r, cg, flags, opt ); + break; + + default: + QMotifStyle::drawControl( element, p, widget, r, cg, flags, opt ); + break; + } +} + +/*! \reimp */ +void QSGIStyle::drawComplexControl( ComplexControl control, + QPainter *p, + const QWidget* widget, + const QRect& r, + const QColorGroup& cg, + SFlags flags, + SCFlags sub, + SCFlags subActive, + const QStyleOption& opt ) const +{ + if ( widget == d->hotWidget ) + flags |= Style_MouseOver; + + switch ( control ) { + case CC_Slider: + { +#ifndef QT_NO_SLIDER + const QSlider * slider = (const QSlider *) widget; + + QRect groove = querySubControlMetrics(CC_Slider, widget, SC_SliderGroove, + opt), + handle = querySubControlMetrics(CC_Slider, widget, SC_SliderHandle, + opt); + + if ((sub & SC_SliderGroove) && groove.isValid()) { + QRegion region( groove ); + if ( ( sub & SC_SliderHandle ) && handle.isValid() ) + region = region.subtract( handle ); + if ( d->lastSliderRect.slider == slider && d->lastSliderRect.rect.isValid() ) + region = region.subtract( d->lastSliderRect.rect ); + p->setClipRegion( region ); + + QRect grooveTop = groove; + grooveTop.addCoords( 1, 1, -1, -1 ); + drawPrimitive( PE_ButtonBevel, p, grooveTop, cg, flags & ~Style_MouseOver, opt ); + + if ( flags & Style_HasFocus ) { + QRect fr = subRect( SR_SliderFocusRect, widget ); + drawPrimitive( PE_FocusRect, p, fr, cg, flags & ~Style_MouseOver ); + } + + if ( d->lastSliderRect.slider == slider && d->lastSliderRect.rect.isValid() ) { + if ( ( sub & SC_SliderHandle ) && handle.isValid() ) { + region = widget->rect(); + region = region.subtract( handle ); + p->setClipRegion( region ); + } else { + p->setClipping( FALSE ); + } + qDrawShadePanel( p, d->lastSliderRect.rect, cg, TRUE, 1, &cg.brush( QColorGroup::Dark ) ); + } + p->setClipping( FALSE ); + } + + if (( sub & SC_SliderHandle ) && handle.isValid()) { + if ( flags & Style_MouseOver && !handle.contains( d->mousePos ) && subActive != SC_SliderHandle ) + flags &= ~Style_MouseOver; + drawPrimitive( PE_ButtonBevel, p, handle, cg, flags ); + + if ( slider->orientation() == Horizontal ) { + QCOORD mid = handle.x() + handle.width() / 2; + qDrawShadeLine( p, mid, handle.y(), mid, + handle.y() + handle.height() - 2, + cg, TRUE, 1); + } else { + QCOORD mid = handle.y() + handle.height() / 2; + qDrawShadeLine( p, handle.x(), mid, + handle.x() + handle.width() - 2, mid, + cg, TRUE, 1); + } + } + + if ( sub & SC_SliderTickmarks ) + QMotifStyle::drawComplexControl( control, p, widget, r, cg, flags, + SC_SliderTickmarks, subActive, + opt ); +#endif + break; + } + case CC_ComboBox: + { +#ifndef QT_NO_COMBOBOX + const QComboBox * cb = (QComboBox *) widget; + + if (sub & SC_ComboBoxFrame) { + QRect fr = + QStyle::visualRect( querySubControlMetrics( CC_ComboBox, cb, + SC_ComboBoxFrame ), cb ); + drawPrimitive( PE_ButtonBevel, p, fr, cg, flags ); + } + + if ( sub & SC_ComboBoxArrow ) { + p->save(); + QRect er = + QStyle::visualRect( querySubControlMetrics( CC_ComboBox, cb, SC_ComboBoxArrow ), cb ); + + er.addCoords( 0, 3, 0, 0 ); + + drawPrimitive( PE_ArrowDown, p, er, cg, flags | Style_Enabled, opt ); + + int awh, ax, ay, sh, sy, dh, ew; + get_combo_parameters( widget->rect(), ew, awh, ax, ay, sh, dh, sy ); + + QBrush arrow = cg.brush( QColorGroup::Dark ); + p->fillRect( ax, sy-1, awh, sh, arrow ); + + p->restore(); + if ( cb->hasFocus() ) { + QRect re = QStyle::visualRect( subRect( SR_ComboBoxFocusRect, cb ), cb ); + drawPrimitive( PE_FocusRect, p, re, cg ); + } + } + if ( sub & SC_ComboBoxEditField ) { + if ( cb->editable() ) { + QRect er = + QStyle::visualRect( querySubControlMetrics( CC_ComboBox, cb, + SC_ComboBoxEditField ), cb ); + er.addCoords( -1, -1, 1, 1); + qDrawShadePanel( p, QRect( er.x()-1, er.y()-1, + er.width()+2, er.height()+2 ), + cg, TRUE, 1, &cg.brush( QColorGroup::Button ) ); + } + } +#endif + p->setPen(cg.buttonText()); + break; + } + + case CC_ScrollBar: + { +#ifndef QT_NO_SCROLLBAR + QScrollBar *scrollbar = (QScrollBar*)widget; + bool maxedOut = (scrollbar->minValue() == scrollbar->maxValue()); + if ( maxedOut ) + flags &= ~Style_Enabled; + + QRect handle = QStyle::visualRect( querySubControlMetrics( CC_ScrollBar, widget, SC_ScrollBarSlider, opt ), widget ); + + if ( sub & SC_ScrollBarGroove ) { + } + if ( sub & SC_ScrollBarAddLine ) { + QRect er = QStyle::visualRect( querySubControlMetrics( CC_ScrollBar, widget, SC_ScrollBarAddLine, opt ), widget ); + drawPrimitive( PE_ScrollBarAddLine, p, er, cg, flags, opt ); + } + if ( sub & SC_ScrollBarSubLine ) { + QRect er = QStyle::visualRect( querySubControlMetrics( CC_ScrollBar, widget, SC_ScrollBarSubLine, opt ), widget ); + drawPrimitive( PE_ScrollBarSubLine, p, er, cg, flags, opt ); + } + if ( sub & SC_ScrollBarAddPage ) { + QRect er = QStyle::visualRect( querySubControlMetrics( CC_ScrollBar, widget, SC_ScrollBarAddPage, opt ), widget ); + QRegion region( er ); + if ( d->lastScrollbarRect.scrollbar == scrollbar && + d->lastScrollbarRect.rect.isValid() && + er.intersects( d->lastScrollbarRect.rect ) ) { + region = region.subtract( d->lastScrollbarRect.rect ); + p->setClipRegion( region ); + } + if ( sub & SC_ScrollBarSlider && er.intersects( handle ) ) { + region = region.subtract( handle ); + p->setClipRegion( region ); + } + + drawPrimitive( PE_ScrollBarAddPage, p, er, cg, flags & ~Style_MouseOver, opt ); + + if ( d->lastScrollbarRect.scrollbar == scrollbar && + d->lastScrollbarRect.rect.isValid() && + er.intersects( d->lastScrollbarRect.rect ) ) { + if ( sub & SC_ScrollBarSlider && handle.isValid() ) { + region = er; + region.subtract( handle ); + p->setClipRegion( region ); + } else { + p->setClipping( FALSE ); + } + qDrawShadePanel( p, d->lastScrollbarRect.rect, cg, TRUE, 1, &cg.brush( QColorGroup::Dark ) ); + } + p->setClipping( FALSE ); + } + if ( sub & SC_ScrollBarSubPage ) { + QRect er = QStyle::visualRect( querySubControlMetrics( CC_ScrollBar, widget, SC_ScrollBarSubPage, opt ), widget ); + QRegion region( er ); + if ( d->lastScrollbarRect.scrollbar == scrollbar && + d->lastScrollbarRect.rect.isValid() && + er.intersects( d->lastScrollbarRect.rect ) ) { + region = region.subtract( d->lastScrollbarRect.rect ); + p->setClipRegion( region ); + } + if ( sub & SC_ScrollBarSlider && er.intersects( handle ) ) { + region = region.subtract( handle ); + p->setClipRegion( region ); + } + drawPrimitive( PE_ScrollBarSubPage, p, er, cg, flags & ~Style_MouseOver, opt ); + if ( d->lastScrollbarRect.scrollbar == scrollbar && + d->lastScrollbarRect.rect.isValid() && + er.intersects( d->lastScrollbarRect.rect ) ) { + if ( sub & SC_ScrollBarSlider && handle.isValid() ) { + region = er; + region.subtract( handle ); + p->setClipRegion( region ); + } else { + p->setClipping( FALSE ); + } + qDrawShadePanel( p, d->lastScrollbarRect.rect, cg, TRUE, 1, &cg.brush( QColorGroup::Dark ) ); + } + p->setClipping( FALSE ); + } + if ( sub & SC_ScrollBarSlider ) { + p->setClipping( FALSE ); + if ( subActive == SC_ScrollBarSlider ) + flags |= Style_Active; + + drawPrimitive( PE_ScrollBarSlider, p, handle, cg, flags, opt ); + } +#endif + } + break; + + default: + QMotifStyle::drawComplexControl( control, p, widget, r, cg, flags, sub, subActive, opt ); + break; + } +} + +/*!\reimp +*/ +QSize QSGIStyle::sizeFromContents( ContentsType contents, + const QWidget *widget, + const QSize &contentsSize, + const QStyleOption& opt ) const +{ + QSize sz(contentsSize); + + switch(contents) { + case CT_PopupMenuItem: + { +#ifndef QT_NO_POPUPMENU + if (! widget || opt.isDefault()) + break; + + QMenuItem *mi = opt.menuItem(); + sz = QMotifStyle::sizeFromContents( contents, widget, contentsSize, + opt ); + // SGI checkmark items needs a bit more room + const QPopupMenu *popup = (QPopupMenu *) widget; + if ( popup && popup->isCheckable() ) + sz.setWidth( sz.width() + 8 ); + // submenu indicator needs a bit more room + if (mi->popup()) + sz.setWidth( sz.width() + sgiTabSpacing ); +#endif + break; + } + case CT_ComboBox: + sz.rwidth() += 30; + break; + + default: + sz = QMotifStyle::sizeFromContents( contents, widget, contentsSize, opt ); + break; + } + + return sz; +} + +/*! \reimp */ +QRect QSGIStyle::subRect( SubRect r, const QWidget *widget ) const +{ + QRect rect; + + switch ( r ) { + case SR_ComboBoxFocusRect: + { + int awh, ax, ay, sh, sy, dh, ew; + int fw = pixelMetric( PM_DefaultFrameWidth, widget ); + QRect tr = widget->rect(); + + tr.addCoords( fw, fw, -fw, -fw ); + get_combo_parameters( tr, ew, awh, ax, ay, sh, dh, sy ); + rect.setRect(ax-2, ay-2, awh+4, awh+sh+dh+4); + } + break; + default: + return QMotifStyle::subRect( r, widget ); + } + + return rect; +} + +/*! \reimp */ +QRect QSGIStyle::querySubControlMetrics( ComplexControl control, + const QWidget *widget, + SubControl sub, + const QStyleOption& opt ) const +{ + switch ( control ) { + case CC_ComboBox: + switch ( sub ) { + case SC_ComboBoxFrame: + return widget->rect(); + + case SC_ComboBoxArrow: { + int ew, awh, sh, dh, ax, ay, sy; + int fw = pixelMetric( PM_DefaultFrameWidth, widget ); + QRect cr = widget->rect(); + cr.addCoords( fw, fw, -fw, -fw ); + get_combo_parameters( cr, ew, awh, ax, ay, sh, dh, sy ); + return QRect( ax, ay, awh, awh ); } + + case SC_ComboBoxEditField: { + int fw = pixelMetric( PM_DefaultFrameWidth, widget ); + QRect rect = widget->rect(); + rect.addCoords( fw, fw, -fw, -fw ); + int ew = get_combo_extra_width( rect.height() ); + rect.addCoords( 1, 1, -1-ew, -1 ); + return rect; } + + default: + break; + } + break; + case CC_ScrollBar: + return QCommonStyle::querySubControlMetrics( control, widget, sub, opt ); + default: break; + } + return QMotifStyle::querySubControlMetrics( control, widget, sub, opt ); +} + +#endif // QT_NO_STYLE_SGI diff --git a/src/styles/qsgistyle.h b/src/styles/qsgistyle.h new file mode 100644 index 0000000..addb7d7 --- /dev/null +++ b/src/styles/qsgistyle.h @@ -0,0 +1,133 @@ +/**************************************************************************** +** +** Definition of SGI-like style class +** +** Created : 981231 +** +** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the widgets module of the Qt GUI Toolkit. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** This file may be used under the terms of the Q Public License as +** defined by Trolltech ASA and appearing in the file LICENSE.QPL +** included in the packaging of this file. Licensees holding valid Qt +** Commercial licenses may use this file in accordance with the Qt +** Commercial License Agreement provided with the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef QSGISTYLE_H +#define QSGISTYLE_H + +#ifndef QT_H +#include "qmotifstyle.h" +#include "qguardedptr.h" +#include "qwidget.h" +#endif // QT_H + +#if !defined(QT_NO_STYLE_SGI) || defined(QT_PLUGIN) + +#if defined(QT_PLUGIN) +#define Q_EXPORT_STYLE_SGI +#else +#define Q_EXPORT_STYLE_SGI Q_EXPORT +#endif + +class QSGIStylePrivate; + +class Q_EXPORT_STYLE_SGI QSGIStyle: public QMotifStyle +{ + Q_OBJECT +public: + QSGIStyle( bool useHighlightCols = FALSE ); + virtual ~QSGIStyle(); + +#if !defined(Q_NO_USING_KEYWORD) + using QMotifStyle::polish; +#endif + void polish( QWidget* ); + void unPolish( QWidget* ); + void polish( QApplication* ); + void unPolish( QApplication* ); + + void drawPrimitive( PrimitiveElement pe, + QPainter *p, + const QRect &r, + const QColorGroup &cg, + SFlags flags = Style_Default, + const QStyleOption& = QStyleOption::Default ) const; + + void drawControl( ControlElement element, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QColorGroup &cg, + SFlags how = Style_Default, + const QStyleOption& = QStyleOption::Default ) const; + + void drawComplexControl( ComplexControl control, + QPainter *p, + const QWidget* widget, + const QRect& r, + const QColorGroup& cg, + SFlags how = Style_Default, +#ifdef Q_QDOC + SCFlags sub = SC_All, +#else + SCFlags sub = (uint)SC_All, +#endif + SCFlags subActive = SC_None, + const QStyleOption& = QStyleOption::Default ) const; + + int pixelMetric( PixelMetric metric, const QWidget *widget = 0 ) const; + + QSize sizeFromContents( ContentsType contents, + const QWidget *widget, + const QSize &contentsSize, + const QStyleOption& = QStyleOption::Default ) const; + + QRect subRect( SubRect r, const QWidget *widget ) const; + QRect querySubControlMetrics( ComplexControl control, + const QWidget *widget, + SubControl sc, + const QStyleOption& = QStyleOption::Default ) const; + +protected: + bool eventFilter( QObject*, QEvent*); + +private: + QSGIStylePrivate *d; + + uint isApplicationStyle :1; +#if defined(Q_DISABLE_COPY) + QSGIStyle( const QSGIStyle & ); + QSGIStyle& operator=( const QSGIStyle & ); +#endif + +}; + +#endif // QT_NO_STYLE_SGI + +#endif // QSGISTYLE_H diff --git a/src/styles/qstylefactory.cpp b/src/styles/qstylefactory.cpp new file mode 100644 index 0000000..dab4c99 --- /dev/null +++ b/src/styles/qstylefactory.cpp @@ -0,0 +1,268 @@ +/**************************************************************************** +** +** Implementation of QStyleFactory class +** +** Created : 001103 +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the widgets module of the Qt GUI Toolkit. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** This file may be used under the terms of the Q Public License as +** defined by Trolltech ASA and appearing in the file LICENSE.QPL +** included in the packaging of this file. Licensees holding valid Qt +** Commercial licenses may use this file in accordance with the Qt +** Commercial License Agreement provided with the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "qstyleinterface_p.h" // up here for GCC 2.7.* compatibility +#include "qstylefactory.h" + +#ifndef QT_NO_STYLE + +#include "qapplication.h" +#include "qwindowsstyle.h" +#include "qmotifstyle.h" +#include "qcdestyle.h" +#include "qmotifplusstyle.h" +#include "qplatinumstyle.h" +#include "qsgistyle.h" +#include "qcompactstyle.h" +#ifndef QT_NO_STYLE_WINDOWSXP +#include "qwindowsxpstyle.h" +#endif +#ifndef QT_NO_STYLE_AQUA +#include "qaquastyle.h" +#endif +#ifndef QT_NO_STYLE_POCKETPC +#include "qpocketpcstyle_wce.h" +#endif + +#if !defined( QT_NO_STYLE_MAC ) && defined( Q_WS_MAC ) +QString p2qstring(const unsigned char *c); //qglobal.cpp +#include "qt_mac.h" +#include "qmacstyle_mac.h" +#endif +#include + +#include +#ifndef QT_NO_COMPONENT +class QStyleFactoryPrivate : public QObject +{ +public: + QStyleFactoryPrivate(); + ~QStyleFactoryPrivate(); + + static QPluginManager *manager; +}; + +static QStyleFactoryPrivate *instance = 0; +QPluginManager *QStyleFactoryPrivate::manager = 0; + +QStyleFactoryPrivate::QStyleFactoryPrivate() +: QObject( qApp ) +{ + manager = new QPluginManager( IID_QStyleFactory, QApplication::libraryPaths(), "/styles", FALSE ); +} + +QStyleFactoryPrivate::~QStyleFactoryPrivate() +{ + delete manager; + manager = 0; + + instance = 0; +} + +#endif //QT_NO_COMPONENT + +/*! + \class QStyleFactory qstylefactory.h + \brief The QStyleFactory class creates QStyle objects. + + The style factory creates a QStyle object for a given key with + QStyleFactory::create(key). + + The styles are either built-in or dynamically loaded from a style + plugin (see \l QStylePlugin). + + QStyleFactory::keys() returns a list of valid keys, typically + including "Windows", "Motif", "CDE", "MotifPlus", "Platinum", + "SGI" and "Compact". Depending on the platform, "WindowsXP", + "Aqua" or "Macintosh" may be available. +*/ + +/*! + Creates a QStyle object that matches \a key case-insensitively. + This is either a built-in style, or a style from a style plugin. + + \sa keys() +*/ +QStyle *QStyleFactory::create( const QString& key ) +{ + QStyle *ret = 0; + QString style = key.lower(); +#ifndef QT_NO_STYLE_WINDOWS + if ( style == "windows" ) + ret = new QWindowsStyle; + else +#endif +#ifndef QT_NO_STYLE_WINDOWSXP + if ( style == "windowsxp" ) + ret = new QWindowsXPStyle; + else +#endif +#ifndef QT_NO_STYLE_MOTIF + if ( style == "motif" ) + ret = new QMotifStyle; + else +#endif +#ifndef QT_NO_STYLE_CDE + if ( style == "cde" ) + ret = new QCDEStyle; + else +#endif +#ifndef QT_NO_STYLE_MOTIFPLUS + if ( style == "motifplus" ) + ret = new QMotifPlusStyle; + else +#endif +#ifndef QT_NO_STYLE_PLATINUM + if ( style == "platinum" ) + ret = new QPlatinumStyle; + else +#endif +#ifndef QT_NO_STYLE_SGI + if ( style == "sgi") + ret = new QSGIStyle; + else +#endif +#ifndef QT_NO_STYLE_COMPACT + if ( style == "compact" ) + ret = new QCompactStyle; + else +#endif +#ifndef QT_NO_STYLE_AQUA + if ( style == "aqua" ) + ret = new QAquaStyle; +#endif +#ifndef QT_NO_STYLE_POCKETPC + if ( style == "pocketpc" ) + ret = new QPocketPCStyle; +#endif +#if !defined( QT_NO_STYLE_MAC ) && defined( Q_WS_MAC ) + if( style.left(9) == "macintosh" ) + ret = new QMacStyle; +#endif + { } // Keep these here - they make the #ifdefery above work + +#ifndef QT_NO_COMPONENT + if(!ret) { + if ( !instance ) + instance = new QStyleFactoryPrivate; + + QInterfacePtr iface; + QStyleFactoryPrivate::manager->queryInterface( style, &iface ); + + if ( iface ) + ret = iface->create( style ); + } + if(ret) + ret->setName(key); +#endif + return ret; +} + +#ifndef QT_NO_STRINGLIST +/*! + Returns the list of keys this factory can create styles for. + + \sa create() +*/ +QStringList QStyleFactory::keys() +{ + QStringList list; +#ifndef QT_NO_COMPONENT + if ( !instance ) + instance = new QStyleFactoryPrivate; + + list = QStyleFactoryPrivate::manager->featureList(); +#endif //QT_NO_COMPONENT + +#ifndef QT_NO_STYLE_WINDOWS + if ( !list.contains( "Windows" ) ) + list << "Windows"; +#endif +#ifndef QT_NO_STYLE_WINDOWSXP + if ( !list.contains( "WindowsXP" ) && QWindowsXPStyle::resolveSymbols() ) + list << "WindowsXP"; +#endif +#ifndef QT_NO_STYLE_MOTIF + if ( !list.contains( "Motif" ) ) + list << "Motif"; +#endif +#ifndef QT_NO_STYLE_CDE + if ( !list.contains( "CDE" ) ) + list << "CDE"; +#endif +#ifndef QT_NO_STYLE_MOTIFPLUS + if ( !list.contains( "MotifPlus" ) ) + list << "MotifPlus"; +#endif +#ifndef QT_NO_STYLE_PLATINUM + if ( !list.contains( "Platinum" ) ) + list << "Platinum"; +#endif +#ifndef QT_NO_STYLE_SGI + if ( !list.contains( "SGI" ) ) + list << "SGI"; +#endif +#ifndef QT_NO_STYLE_COMPACT + if ( !list.contains( "Compact" ) ) + list << "Compact"; +#endif +#ifndef QT_NO_STYLE_AQUA + if ( !list.contains( "Aqua" ) ) + list << "Aqua"; +#endif +#if !defined( QT_NO_STYLE_MAC ) && defined( Q_WS_MAC ) + QString mstyle = "Macintosh"; + Collection c = NewCollection(); + if (c) { + GetTheme(c); + Str255 str; + long int s = 256; + if(!GetCollectionItem(c, kThemeNameTag, 0, &s, &str)) + mstyle += " (" + p2qstring(str) + ")"; + } + if (!list.contains(mstyle)) + list << mstyle; + DisposeCollection(c); +#endif + + return list; +} +#endif +#endif // QT_NO_STYLE diff --git a/src/styles/qstylefactory.h b/src/styles/qstylefactory.h new file mode 100644 index 0000000..232cea5 --- /dev/null +++ b/src/styles/qstylefactory.h @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** ... +** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the widgets module of the Qt GUI Toolkit. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** This file may be used under the terms of the Q Public License as +** defined by Trolltech ASA and appearing in the file LICENSE.QPL +** included in the packaging of this file. Licensees holding valid Qt +** Commercial licenses may use this file in accordance with the Qt +** Commercial License Agreement provided with the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef QSTYLEFACTORY_H +#define QSTYLEFACTORY_H + +#ifndef QT_H +#include "qstringlist.h" +#endif // QT_H + +#ifndef QT_NO_STYLE + +class QString; +class QStyle; + +class Q_EXPORT QStyleFactory +{ +public: +#ifndef QT_NO_STRINGLIST + static QStringList keys(); +#endif + static QStyle *create( const QString& ); +}; + +#endif //QT_NO_STYLE + +#endif //QSTYLEFACTORY_H diff --git a/src/styles/qstyleinterface_p.h b/src/styles/qstyleinterface_p.h new file mode 100644 index 0000000..833b08a --- /dev/null +++ b/src/styles/qstyleinterface_p.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** ... +** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the widgets module of the Qt GUI Toolkit. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** This file may be used under the terms of the Q Public License as +** defined by Trolltech ASA and appearing in the file LICENSE.QPL +** included in the packaging of this file. Licensees holding valid Qt +** Commercial licenses may use this file in accordance with the Qt +** Commercial License Agreement provided with the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef QSTYLEINTERFACE_P_H +#define QSTYLEINTERFACE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. This header file may +// change from version to version without notice, or even be +// removed. +// +// We mean it. +// +// + +#ifndef QT_H +#include +#endif // QT_H + +#ifndef QT_NO_STYLE +#ifndef QT_NO_COMPONENT + +class QStyle; + +// {FC1B6EBE-053C-49c1-A483-C377739AB9A5} +#ifndef IID_QStyleFactory +#define IID_QStyleFactory QUuid(0xfc1b6ebe, 0x53c, 0x49c1, 0xa4, 0x83, 0xc3, 0x77, 0x73, 0x9a, 0xb9, 0xa5) +#endif + +struct Q_EXPORT QStyleFactoryInterface : public QFeatureListInterface +{ + virtual QStyle* create( const QString& style ) = 0; +}; + +#endif //QT_NO_COMPONENT +#endif //QT_NO_STYLE + +#endif //QSTYLEINTERFACE_P_H diff --git a/src/styles/qstyleplugin.cpp b/src/styles/qstyleplugin.cpp new file mode 100644 index 0000000..99364ee --- /dev/null +++ b/src/styles/qstyleplugin.cpp @@ -0,0 +1,185 @@ +/**************************************************************************** +** +** Implementation of QSqlDriverPlugin class +** +** Created : 010920 +** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the widgets module of the Qt GUI Toolkit. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** This file may be used under the terms of the Q Public License as +** defined by Trolltech ASA and appearing in the file LICENSE.QPL +** included in the packaging of this file. Licensees holding valid Qt +** Commercial licenses may use this file in accordance with the Qt +** Commercial License Agreement provided with the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "qstyleplugin.h" + +#ifndef QT_NO_STYLE +#ifndef QT_NO_COMPONENT + +#include "qstyleinterface_p.h" +#include "qobjectcleanuphandler.h" +#include "qstyle.h" + +/*! + \class QStylePlugin qstyleplugin.h + \brief The QStylePlugin class provides an abstract base for custom QStyle plugins. + + \ingroup plugins + + The style plugin is a simple plugin interface that makes it easy + to create custom styles that can be loaded dynamically into + applications with a QStyleFactory. + + Writing a style plugin is achieved by subclassing this base class, + reimplementing the pure virtual functions keys() and create(), and + exporting the class with the \c Q_EXPORT_PLUGIN macro. See the + \link plugins-howto.html plugins documentation\endlink for an + example. +*/ + +/*! + \fn QStringList QStylePlugin::keys() const + + Returns the list of style keys this plugin supports. + + These keys are usually the class names of the custom styles that + are implemented in the plugin. + + \sa create() +*/ + +/*! + \fn QStyle* QStylePlugin::create( const QString& key ) + + Creates and returns a QStyle object for the style key \a key. The + style key is usually the class name of the required style. + + \sa keys() +*/ + +class QStylePluginPrivate : public QStyleFactoryInterface, public QLibraryInterface +{ +public: + QStylePluginPrivate( QStylePlugin *p ) + : plugin( p ) + { + } + + virtual ~QStylePluginPrivate(); + + QRESULT queryInterface( const QUuid &iid, QUnknownInterface **iface ); + Q_REFCOUNT; + + QStringList featureList() const; + QStyle *create( const QString &key ); + + bool init(); + void cleanup(); + bool canUnload() const; + +private: + QStylePlugin *plugin; + QObjectCleanupHandler styles; +}; + +QRESULT QStylePluginPrivate::queryInterface( const QUuid &iid, QUnknownInterface **iface ) +{ + *iface = 0; + + if ( iid == IID_QUnknown ) + *iface = (QStyleFactoryInterface*)this; + else if ( iid == IID_QFeatureList ) + *iface = (QFeatureListInterface*)this; + else if ( iid == IID_QStyleFactory ) + *iface = (QStyleFactoryInterface*)this; + else if ( iid == IID_QLibrary ) + *iface = (QLibraryInterface*) this; + else + return QE_NOINTERFACE; + + (*iface)->addRef(); + return QS_OK; +} + +QStylePluginPrivate::~QStylePluginPrivate() +{ + delete plugin; +} + +QStringList QStylePluginPrivate::featureList() const +{ + return plugin->keys(); +} + +QStyle *QStylePluginPrivate::create( const QString &key ) +{ + QStyle *st = plugin->create( key ); + styles.add( st ); + return st; +} + +bool QStylePluginPrivate::init() +{ + return TRUE; +} + +void QStylePluginPrivate::cleanup() +{ + styles.clear(); +} + +bool QStylePluginPrivate::canUnload() const +{ + return styles.isEmpty(); +} + + +/*! + Constructs a style plugin. This is invoked automatically by the + \c Q_EXPORT_PLUGIN macro. +*/ +QStylePlugin::QStylePlugin() + : QGPlugin( (QStyleFactoryInterface*)(d = new QStylePluginPrivate( this )) ) +{ +} + +/*! + Destroys the style plugin. + + You never have to call this explicitly. Qt destroys a plugin + automatically when it is no longer used. +*/ +QStylePlugin::~QStylePlugin() +{ + // don't delete d, as this is deleted by d +} + +#endif // QT_NO_COMPONENT +#endif // QT_NO_STYLE diff --git a/src/styles/qstyleplugin.h b/src/styles/qstyleplugin.h new file mode 100644 index 0000000..673047b --- /dev/null +++ b/src/styles/qstyleplugin.h @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Definition of QStylePlugin class +** +** Created : 010920 +** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the widgets module of the Qt GUI Toolkit. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** This file may be used under the terms of the Q Public License as +** defined by Trolltech ASA and appearing in the file LICENSE.QPL +** included in the packaging of this file. Licensees holding valid Qt +** Commercial licenses may use this file in accordance with the Qt +** Commercial License Agreement provided with the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef QSTYLEPLUGIN_H +#define QSTYLEPLUGIN_H + +#ifndef QT_H +#include "qgplugin.h" +#include "qstringlist.h" +#endif // QT_H + +#ifndef QT_NO_STYLE +#ifndef QT_NO_COMPONENT + +class QStyle; +class QStylePluginPrivate; + +class Q_EXPORT QStylePlugin : public QGPlugin +{ + Q_OBJECT +public: + QStylePlugin(); + ~QStylePlugin(); + + virtual QStringList keys() const = 0; + virtual QStyle *create( const QString &key ) = 0; + +private: + QStylePluginPrivate *d; +}; + +#endif // QT_NO_COMPONENT +#endif // QT_NO_STYLE + +#endif // QSTYLEPLUGIN_H diff --git a/src/styles/qt_styles.pri b/src/styles/qt_styles.pri new file mode 100644 index 0000000..913828e --- /dev/null +++ b/src/styles/qt_styles.pri @@ -0,0 +1,140 @@ +# Qt styles module + +styles { + STYLES_P = styles + HEADERS +=$$STYLES_H/qstylefactory.h \ + $$STYLES_P/qstyleinterface_p.h \ + $$STYLES_H/qstyleplugin.h \ + $$STYLES_H/qcommonstyle.h + SOURCES +=$$STYLES_CPP/qstylefactory.cpp \ + $$STYLES_CPP/qstyleplugin.cpp \ + $$STYLES_CPP/qcommonstyle.cpp + + contains( styles, all ) { + styles += mac cde motifplus sgi platinum compact interlace windows motif + } + + x11|embedded|!macx-*:styles -= mac + contains( styles, mac ) { + HEADERS +=$$STYLES_H/qmacstyle_mac.h \ + $$STYLES_H/qmacstylepixmaps_mac_p.h + SOURCES +=$$STYLES_CPP/qmacstyle_mac.cpp + HEADERS *= $$STYLES_CPP/qaquastyle_p.h + SOURCES *= $$STYLES_CPP/qaquastyle_p.cpp + + !contains( styles, windows ) { + message( mac requires windows ) + styles += windows + } + } + else:DEFINES += QT_NO_STYLE_MAC + + #embedded|!macx-*:styles -= aqua + contains( styles, aqua ) { + HEADERS += $$STYLES_H/qaquastyle.h + SOURCES += $$STYLES_CPP/qaquastyle.cpp + HEADERS *= $$STYLES_CPP/qaquastyle_p.h + SOURCES *= $$STYLES_CPP/qaquastyle_p.cpp + + !contains( styles, windows ) { + message( aqua requires windows ) + styles += windows + } + } + else:DEFINES += QT_NO_STYLE_AQUA + + contains( styles, cde ) { + HEADERS +=$$STYLES_H/qcdestyle.h + SOURCES +=$$STYLES_CPP/qcdestyle.cpp + + !contains( styles, motif ) { + message( cde requires motif ) + styles += motif + } + } + else:DEFINES += QT_NO_STYLE_CDE + + contains( styles, motifplus ) { + HEADERS +=$$STYLES_H/qmotifplusstyle.h + SOURCES +=$$STYLES_CPP/qmotifplusstyle.cpp + !contains( styles, motif ) { + message( motifplus requires motif ) + styles += motif + } + } + else:DEFINES += QT_NO_STYLE_MOTIFPLUS + + contains( styles, interlace ) { + HEADERS +=$$STYLES_H/qinterlacestyle.h + SOURCES +=$$STYLES_CPP/qinterlacestyle.cpp + !contains( styles, windows ) { + message( interlace requires windows ) + styles += windows + } + } + else:DEFINES += QT_NO_STYLE_INTERLACE + + contains( styles, platinum ) { + HEADERS +=$$STYLES_H/qplatinumstyle.h + SOURCES +=$$STYLES_CPP/qplatinumstyle.cpp + !contains( styles, windows ) { + message( platinum requires windows ) + styles += windows + } + } + else:DEFINES += QT_NO_STYLE_PLATINUM + + contains( styles, windowsxp ) { + HEADERS +=$$STYLES_H/qwindowsxpstyle.h + SOURCES +=$$STYLES_CPP/qwindowsxpstyle.cpp + !contains( styles, windowsxp ) { + message( windowsxp requires windows ) + styles += windows + } + } + else:DEFINES += QT_NO_STYLE_WINDOWSXP + + contains( styles, sgi ) { + HEADERS +=$$STYLES_H/qsgistyle.h + SOURCES +=$$STYLES_CPP/qsgistyle.cpp + !contains( styles, motif ) { + message( sgi requires motif ) + styles += motif + } + } + else:DEFINES += QT_NO_STYLE_SGI + + contains( styles, compact ) { + HEADERS +=$$STYLES_H/qcompactstyle.h + SOURCES +=$$STYLES_CPP/qcompactstyle.cpp + !contains( styles, windows ) { + message( compact requires windows ) + styles += windows + } + } + else:DEFINES += QT_NO_STYLE_COMPACT + + wince-*:styles += pocketpc + contains( styles, pocketpc ) { + HEADERS +=$$STYLES_H/qpocketpcstyle_wce.h + SOURCES +=$$STYLES_CPP/qpocketpcstyle_wce.cpp + + !contains( styles, windows ) { + message( pocketpc requires windows ) + styles += windows + } + } + else:DEFINES += QT_NO_STYLE_POCKETPC + + contains( styles, windows ) { + HEADERS +=$$STYLES_H/qwindowsstyle.h + SOURCES +=$$STYLES_CPP/qwindowsstyle.cpp + } + else:DEFINES += QT_NO_STYLE_WINDOWS + + contains( styles, motif ) { + HEADERS +=$$STYLES_H/qmotifstyle.h + SOURCES +=$$STYLES_CPP/qmotifstyle.cpp + } + else:DEFINES += QT_NO_STYLE_MOTIF +} diff --git a/src/styles/qwindowsstyle.cpp b/src/styles/qwindowsstyle.cpp new file mode 100644 index 0000000..4e6e586 --- /dev/null +++ b/src/styles/qwindowsstyle.cpp @@ -0,0 +1,2161 @@ +/**************************************************************************** +** +** Implementation of Windows-like style class +** +** Created : 981231 +** +** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the widgets module of the Qt GUI Toolkit. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** This file may be used under the terms of the Q Public License as +** defined by Trolltech ASA and appearing in the file LICENSE.QPL +** included in the packaging of this file. Licensees holding valid Qt +** Commercial licenses may use this file in accordance with the Qt +** Commercial License Agreement provided with the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "qwindowsstyle.h" + +#if !defined(QT_NO_STYLE_WINDOWS) || defined(QT_PLUGIN) + +#include "qpopupmenu.h" +#include "qapplication.h" +#include "qpainter.h" +#include "qdrawutil.h" // for now +#include "qpixmap.h" // for now +#include "qwidget.h" +#include "qlabel.h" +#include "qimage.h" +#include "qpushbutton.h" +#include "qcombobox.h" +#include "qlistbox.h" +#include "qwidget.h" +#include "qrangecontrol.h" +#include "qscrollbar.h" +#include "qslider.h" +#include "qtabwidget.h" +#include "qtabbar.h" +#include "qlistview.h" +#include "qbitmap.h" +#include "qcleanuphandler.h" +#include "qdockwindow.h" +#include "qobjectlist.h" +#include "qmenubar.h" + +#if defined(Q_WS_WIN) +#include "qt_windows.h" +#endif + +#include + + +static const int windowsItemFrame = 2; // menu item frame width +static const int windowsSepHeight = 2; // separator item height +static const int windowsItemHMargin = 3; // menu item hor text margin +static const int windowsItemVMargin = 2; // menu item ver text margin +static const int windowsArrowHMargin = 6; // arrow horizontal margin +static const int windowsTabSpacing = 12; // space between text and tab +static const int windowsCheckMarkHMargin = 2; // horiz. margins of check mark +static const int windowsRightBorder = 12; // right border on windows +static const int windowsCheckMarkWidth = 12; // checkmarks width on windows + +static bool use2000style = TRUE; + +enum QSliderDirection { SlUp, SlDown, SlLeft, SlRight }; + +// A friendly class providing access to QMenuData's protected member. +class FriendlyMenuData : public QMenuData +{ + friend class QWindowsStyle; +}; + +// Private class +class QWindowsStyle::Private : public QObject +{ +public: + Private(QWindowsStyle *parent); + + bool hasSeenAlt(const QWidget *widget) const; + bool altDown() const { return alt_down; } + +protected: + bool eventFilter(QObject *o, QEvent *e); + +private: + QPtrList seenAlt; + bool alt_down; + int menuBarTimer; +}; + +QWindowsStyle::Private::Private(QWindowsStyle *parent) +: QObject(parent, "QWindowsStylePrivate"), alt_down(FALSE), menuBarTimer(0) +{ +} + +// Returns true if the toplevel parent of \a widget has seen the Alt-key +bool QWindowsStyle::Private::hasSeenAlt(const QWidget *widget) const +{ + widget = widget->topLevelWidget(); + return seenAlt.contains(widget); +} + +// Records Alt- and Focus events +bool QWindowsStyle::Private::eventFilter(QObject *o, QEvent *e) +{ + if (!o->isWidgetType()) + return QObject::eventFilter(o, e); + + QWidget *widget = ::qt_cast(o); + + switch(e->type()) { + case QEvent::KeyPress: + if (((QKeyEvent*)e)->key() == Key_Alt) { + widget = widget->topLevelWidget(); + + // Alt has been pressed - find all widgets that care + QObjectList *l = widget->queryList("QWidget"); + QObjectListIt it( *l ); + QWidget *w; + while ( (w = (QWidget*)it.current()) != 0 ) { + ++it; + if (w->isTopLevel() || !w->isVisible() || + w->style().styleHint(SH_UnderlineAccelerator, w)) + l->removeRef(w); + } + // Update states before repainting + seenAlt.append(widget); + alt_down = TRUE; + + // Repaint all relevant widgets + it.toFirst(); + while ( (w = (QWidget*)it.current()) != 0 ) { + ++it; + w->repaint(FALSE); + } + delete l; + } + break; + case QEvent::KeyRelease: + if (((QKeyEvent*)e)->key() == Key_Alt) { + widget = widget->topLevelWidget(); + + // Update state + alt_down = FALSE; + // Repaint only menubars + QObjectList *l = widget->queryList("QMenuBar"); + QObjectListIt it( *l ); + QMenuBar *menuBar; + while ( (menuBar = (QMenuBar*)it.current()) != 0) { + ++it; + menuBar->repaint(FALSE); + } + } + break; + case QEvent::FocusIn: + case QEvent::FocusOut: + { + // Menubars toggle based on focus + QMenuBar *menuBar = ::qt_cast(o); + if (menuBar && !menuBarTimer) // delayed repaint to avoid flicker + menuBarTimer = menuBar->startTimer(0); + } + break; + case QEvent::Close: + // Reset widget when closing + seenAlt.removeRef(widget); + seenAlt.removeRef(widget->topLevelWidget()); + break; + case QEvent::Timer: + { + QMenuBar *menuBar = ::qt_cast(o); + QTimerEvent *te = (QTimerEvent*)e; + if (menuBar && te->timerId() == menuBarTimer) { + menuBar->killTimer(te->timerId()); + menuBarTimer = 0; + menuBar->repaint(FALSE); + return TRUE; + } + } + break; + default: + break; + } + + return QObject::eventFilter(o, e); +} + +/*! + \class QWindowsStyle qwindowsstyle.h + \brief The QWindowsStyle class provides a Microsoft Windows-like look and feel. + + \ingroup appearance + + This style is Qt's default GUI style on Windows. +*/ + +/*! + Constructs a QWindowsStyle +*/ +QWindowsStyle::QWindowsStyle() : QCommonStyle(), d(0) +{ +#if defined(Q_OS_WIN32) + use2000style = qWinVersion() != Qt::WV_NT && qWinVersion() != Qt::WV_95; +#endif +} + +/*! \reimp */ +QWindowsStyle::~QWindowsStyle() +{ + delete d; +} + +/*! \reimp */ +void QWindowsStyle::polish(QApplication *app) +{ + // We only need the overhead when shortcuts are sometimes hidden + if (!styleHint(SH_UnderlineAccelerator, 0)) { + d = new Private(this); + app->installEventFilter(d); + } +} + +/*! \reimp */ +void QWindowsStyle::unPolish(QApplication *) +{ + delete d; + d = 0; +} + +/*! \reimp */ +void QWindowsStyle::polish(QWidget *widget) +{ + QCommonStyle::polish(widget); +} + +/*! \reimp */ +void QWindowsStyle::unPolish(QWidget *widget) +{ + QCommonStyle::polish(widget); +} + +/*! \reimp */ +void QWindowsStyle::polish( QPalette &pal ) +{ + QCommonStyle::polish(pal); +} + +/*! \reimp */ +void QWindowsStyle::drawPrimitive( PrimitiveElement pe, + QPainter *p, + const QRect &r, + const QColorGroup &cg, + SFlags flags, + const QStyleOption& opt ) const +{ + QRect rr( r ); + switch (pe) { + case PE_ButtonCommand: + { + QBrush fill; + + if (! (flags & Style_Down) && (flags & Style_On)) + fill = QBrush(cg.light(), Dense4Pattern); + else + fill = cg.brush(QColorGroup::Button); + + if (flags & Style_ButtonDefault && flags & Style_Down) { + p->setPen(cg.dark()); + p->setBrush(fill); + p->drawRect(r); + } else if (flags & (Style_Raised | Style_Down | Style_On | Style_Sunken)) + qDrawWinButton(p, r, cg, flags & (Style_Sunken | Style_Down | + Style_On), &fill); + else + p->fillRect(r, fill); + break; + } + + case PE_ButtonBevel: + case PE_HeaderSection: + { + QBrush fill; + + if (! (flags & Style_Down) && (flags & Style_On)) + fill = QBrush(cg.light(), Dense4Pattern); + else + fill = cg.brush(QColorGroup::Button); + + if (flags & (Style_Raised | Style_Down | Style_On | Style_Sunken)) + qDrawWinButton(p, r, cg, flags & (Style_Down | Style_On), &fill); + else + p->fillRect(r, fill); + break; + } +#if defined(Q_WS_WIN) + case PE_HeaderArrow: + p->save(); + if ( flags & Style_Up ) { // invert logic to follow Windows style guide + QPointArray pa( 3 ); + p->setPen( cg.light() ); + p->drawLine( r.x() + r.width(), r.y(), r.x() + r.width() / 2, r.height() ); + p->setPen( cg.dark() ); + pa.setPoint( 0, r.x() + r.width() / 2, r.height() ); + pa.setPoint( 1, r.x(), r.y() ); + pa.setPoint( 2, r.x() + r.width(), r.y() ); + p->drawPolyline( pa ); + } else { + QPointArray pa( 3 ); + p->setPen( cg.light() ); + pa.setPoint( 0, r.x(), r.height() ); + pa.setPoint( 1, r.x() + r.width(), r.height() ); + pa.setPoint( 2, r.x() + r.width() / 2, r.y() ); + p->drawPolyline( pa ); + p->setPen( cg.dark() ); + p->drawLine( r.x(), r.height(), r.x() + r.width() / 2, r.y() ); + } + p->restore(); + break; +#endif + + case PE_ButtonDefault: + p->setPen(cg.shadow()); + p->drawRect(r); + break; + + case PE_ButtonTool: + { + QBrush fill; + bool stippled = FALSE; + + if (! (flags & (Style_Down | Style_MouseOver)) && + (flags & Style_On) && + use2000style) { + fill = QBrush(cg.light(), Dense4Pattern); + stippled = TRUE; + } else + fill = cg.brush(QColorGroup::Button); + + if (flags & (Style_Raised | Style_Down | Style_On)) { + if (flags & Style_AutoRaise) { + qDrawShadePanel(p, r, cg, flags & (Style_Down | Style_On), + 1, &fill); + + if (stippled) { + p->setPen(cg.button()); + p->drawRect(r.x() + 1, r.y() + 1, r.width() - 2, r.height() - 2); + } + } else + qDrawWinButton(p, r, cg, flags & (Style_Down | Style_On), + &fill); + } else + p->fillRect(r, fill); + + break; + } + + case PE_FocusRect: + if (opt.isDefault()) + p->drawWinFocusRect(r); + else + p->drawWinFocusRect(r, opt.color()); + break; + + case PE_Indicator: + { + QBrush fill; + if (flags & Style_NoChange) { + QBrush b = p->brush(); + QColor c = p->backgroundColor(); + p->setBackgroundMode( TransparentMode ); + p->setBackgroundColor( green ); + fill = QBrush(cg.base(), Dense4Pattern); + p->setBackgroundColor( c ); + p->setBrush( b ); + } else if (flags & Style_Down) + fill = cg.brush( QColorGroup::Button ); + else if (flags & Style_Enabled) + fill = cg.brush( QColorGroup::Base ); + else + fill = cg.brush( QColorGroup::Background ); + + qDrawWinPanel( p, r, cg, TRUE, &fill ); + + if (flags & Style_NoChange ) + p->setPen( cg.dark() ); + else + p->setPen( cg.text() ); + } // FALLTHROUGH + case PE_CheckListIndicator: + if ( pe == PE_CheckListIndicator ) { //since we fall through from PE_Indicator + if ( flags & Style_Enabled ) + p->setPen( QPen( cg.text(), 1 ) ); + else + p->setPen( QPen( cg.dark(), 1 ) ); + if ( flags & Style_NoChange ) + p->setBrush( cg.brush( QColorGroup::Button ) ); + p->drawRect( r.x()+1, r.y()+1, 11, 11 ); + } + if (! (flags & Style_Off)) { + QPointArray a( 7*2 ); + int i, xx, yy; + xx = rr.x() + 3; + yy = rr.y() + 5; + + for ( i=0; i<3; i++ ) { + a.setPoint( 2*i, xx, yy ); + a.setPoint( 2*i+1, xx, yy+2 ); + xx++; yy++; + } + + yy -= 2; + for ( i=3; i<7; i++ ) { + a.setPoint( 2*i, xx, yy ); + a.setPoint( 2*i+1, xx, yy+2 ); + xx++; yy--; + } + + p->drawLineSegments( a ); + } + break; + + case PE_ExclusiveIndicator: + { +#define QCOORDARRLEN(x) sizeof(x)/(sizeof(QCOORD)*2) + static const QCOORD pts1[] = { // dark lines + 1,9, 1,8, 0,7, 0,4, 1,3, 1,2, 2,1, 3,1, 4,0, 7,0, 8,1, 9,1 }; + static const QCOORD pts2[] = { // black lines + 2,8, 1,7, 1,4, 2,3, 2,2, 3,2, 4,1, 7,1, 8,2, 9,2 }; + static const QCOORD pts3[] = { // background lines + 2,9, 3,9, 4,10, 7,10, 8,9, 9,9, 9,8, 10,7, 10,4, 9,3 }; + static const QCOORD pts4[] = { // white lines + 2,10, 3,10, 4,11, 7,11, 8,10, 9,10, 10,9, 10,8, 11,7, + 11,4, 10,3, 10,2 }; + static const QCOORD pts5[] = { // inner fill + 4,2, 7,2, 9,4, 9,7, 7,9, 4,9, 2,7, 2,4 }; + + // make sure the indicator is square + QRect ir = r; + + if (r.width() < r.height()) { + ir.setTop(r.top() + (r.height() - r.width()) / 2); + ir.setHeight(r.width()); + } else if (r.height() < r.width()) { + ir.setLeft(r.left() + (r.width() - r.height()) / 2); + ir.setWidth(r.height()); + } + + p->eraseRect(ir); + bool down = flags & Style_Down; + bool enabled = flags & Style_Enabled; + bool on = flags & Style_On; + QPointArray a; + a.setPoints( QCOORDARRLEN(pts1), pts1 ); + a.translate( ir.x(), ir.y() ); + p->setPen( cg.dark() ); + p->drawPolyline( a ); + a.setPoints( QCOORDARRLEN(pts2), pts2 ); + a.translate( ir.x(), ir.y() ); + p->setPen( cg.shadow() ); + p->drawPolyline( a ); + a.setPoints( QCOORDARRLEN(pts3), pts3 ); + a.translate( ir.x(), ir.y() ); + p->setPen( cg.midlight() ); + p->drawPolyline( a ); + a.setPoints( QCOORDARRLEN(pts4), pts4 ); + a.translate( ir.x(), ir.y() ); + p->setPen( cg.light() ); + p->drawPolyline( a ); + a.setPoints( QCOORDARRLEN(pts5), pts5 ); + a.translate( ir.x(), ir.y() ); + QColor fillColor = ( down || !enabled ) ? cg.button() : cg.base(); + p->setPen( fillColor ); + p->setBrush( fillColor ) ; + p->drawPolygon( a ); + if ( on ) { + p->setPen( NoPen ); + p->setBrush( cg.text() ); + p->drawRect( ir.x() + 5, ir.y() + 4, 2, 4 ); + p->drawRect( ir.x() + 4, ir.y() + 5, 4, 2 ); + } + break; + } + + case PE_Panel: + case PE_PanelPopup: + { + int lw = opt.isDefault() ? pixelMetric(PM_DefaultFrameWidth) + : opt.lineWidth(); + + if (lw == 2) { + QColorGroup popupCG = cg; + if ( pe == PE_PanelPopup ) { + popupCG.setColor( QColorGroup::Light, cg.background() ); + popupCG.setColor( QColorGroup::Midlight, cg.light() ); + } + qDrawWinPanel(p, r, popupCG, flags & Style_Sunken); + } else { + QCommonStyle::drawPrimitive(pe, p, r, cg, flags, opt); + } + break; + } + + case PE_Splitter: + { + QPen oldPen = p->pen(); + p->setPen( cg.light() ); + if ( flags & Style_Horizontal ) { + p->drawLine( r.x() + 1, r.y(), r.x() + 1, r.height() ); + p->setPen( cg.dark() ); + p->drawLine( r.x(), r.y(), r.x(), r.height() ); + p->drawLine( r.right()-1, r.y(), r.right()-1, r.height() ); + p->setPen( cg.shadow() ); + p->drawLine( r.right(), r.y(), r.right(), r.height() ); + } else { + p->drawLine( r.x(), r.y() + 1, r.width(), r.y() + 1 ); + p->setPen( cg.dark() ); + p->drawLine( r.x(), r.bottom() - 1, r.width(), r.bottom() - 1 ); + p->setPen( cg.shadow() ); + p->drawLine( r.x(), r.bottom(), r.width(), r.bottom() ); + } + p->setPen( oldPen ); + break; + } + case PE_DockWindowResizeHandle: + { + QPen oldPen = p->pen(); + p->setPen( cg.light() ); + if ( flags & Style_Horizontal ) { + p->drawLine( r.x(), r.y(), r.width(), r.y() ); + p->setPen( cg.dark() ); + p->drawLine( r.x(), r.bottom() - 1, r.width(), r.bottom() - 1 ); + p->setPen( cg.shadow() ); + p->drawLine( r.x(), r.bottom(), r.width(), r.bottom() ); + } else { + p->drawLine( r.x(), r.y(), r.x(), r.height() ); + p->setPen( cg.dark() ); + p->drawLine( r.right()-1, r.y(), r.right()-1, r.height() ); + p->setPen( cg.shadow() ); + p->drawLine( r.right(), r.y(), r.right(), r.height() ); + } + p->setPen( oldPen ); + break; + } + + case PE_ScrollBarSubLine: + if (use2000style) { + if (flags & Style_Down) { + p->setPen( cg.dark() ); + p->setBrush( cg.brush( QColorGroup::Button ) ); + p->drawRect( r ); + } else + drawPrimitive(PE_ButtonBevel, p, r, cg, flags | Style_Raised); + } else + drawPrimitive(PE_ButtonBevel, p, r, cg, (flags & Style_Enabled) | + ((flags & Style_Down) ? Style_Down : Style_Raised)); + + drawPrimitive(((flags & Style_Horizontal) ? PE_ArrowLeft : PE_ArrowUp), + p, r, cg, flags); + break; + + case PE_ScrollBarAddLine: + if (use2000style) { + if (flags & Style_Down) { + p->setPen( cg.dark() ); + p->setBrush( cg.brush( QColorGroup::Button ) ); + p->drawRect( r ); + } else + drawPrimitive(PE_ButtonBevel, p, r, cg, flags | Style_Raised); + } else + drawPrimitive(PE_ButtonBevel, p, r, cg, (flags & Style_Enabled) | + ((flags & Style_Down) ? Style_Down : Style_Raised)); + + drawPrimitive(((flags & Style_Horizontal) ? PE_ArrowRight : PE_ArrowDown), + p, r, cg, flags); + break; + + case PE_ScrollBarAddPage: + case PE_ScrollBarSubPage: + { + QBrush br; + QColor c = p->backgroundColor(); + + p->setPen(NoPen); + p->setBackgroundMode(OpaqueMode); + + if (flags & Style_Down) { + br = QBrush(cg.shadow(), Dense4Pattern); + p->setBackgroundColor( cg.dark() ); + p->setBrush( QBrush(cg.shadow(), Dense4Pattern) ); + } else { + br = (cg.brush(QColorGroup::Light).pixmap() ? + cg.brush(QColorGroup::Light) : + QBrush(cg.light(), Dense4Pattern)); + p->setBrush(br); + } + + p->drawRect(r); + p->setBackgroundColor(c); + break; + } + + case PE_ScrollBarSlider: + if (! (flags & Style_Enabled)) { + QBrush br = (cg.brush(QColorGroup::Light).pixmap() ? + cg.brush(QColorGroup::Light) : + QBrush(cg.light(), Dense4Pattern)); + p->setPen(NoPen); + p->setBrush(br); + p->setBackgroundMode(OpaqueMode); + p->drawRect(r); + } else + drawPrimitive(PE_ButtonBevel, p, r, cg, Style_Enabled | Style_Raised); + break; + + case PE_WindowFrame: + { + QColorGroup popupCG = cg; + popupCG.setColor( QColorGroup::Light, cg.background() ); + popupCG.setColor( QColorGroup::Midlight, cg.light() ); + qDrawWinPanel(p, r, popupCG, flags & Style_Sunken); + } + break; + + default: + if (pe >= PE_ArrowUp && pe <= PE_ArrowLeft) { + QPointArray a; + + switch ( pe ) { + case PE_ArrowUp: + a.setPoints( 7, -4,1, 2,1, -3,0, 1,0, -2,-1, 0,-1, -1,-2 ); + break; + + case PE_ArrowDown: + a.setPoints( 7, -4,-2, 2,-2, -3,-1, 1,-1, -2,0, 0,0, -1,1 ); + break; + + case PE_ArrowRight: + a.setPoints( 7, -2,-3, -2,3, -1,-2, -1,2, 0,-1, 0,1, 1,0 ); + break; + + case PE_ArrowLeft: + a.setPoints( 7, 0,-3, 0,3, -1,-2, -1,2, -2,-1, -2,1, -3,0 ); + break; + + default: + break; + } + + if (a.isNull()) + return; + + 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, 0, 3 ); // draw arrow + p->drawPoint( a[6] ); + } else { + a.translate( r.x() + r.width() / 2 + 1, r.y() + r.height() / 2 + 1 ); + p->setPen( cg.light() ); + p->drawLineSegments( a, 0, 3 ); // draw arrow + p->drawPoint( a[6] ); + a.translate( -1, -1 ); + p->setPen( cg.mid() ); + p->drawLineSegments( a, 0, 3 ); // draw arrow + p->drawPoint( a[6] ); + } + p->restore(); + } else + QCommonStyle::drawPrimitive(pe, p, r, cg, flags, opt); + } +} + + +/*! + \reimp +*/ +void QWindowsStyle::drawControl( ControlElement element, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QColorGroup &cg, + SFlags flags, + const QStyleOption& opt ) const +{ + switch (element) { +#ifndef QT_NO_TABBAR + case CE_TabBarTab: + { + if ( !widget || !widget->parentWidget() || !opt.tab() ) + break; + + const QTabBar * tb = (const QTabBar *) widget; + const QTab * t = opt.tab(); + bool selected = flags & Style_Selected; + bool lastTab = (tb->indexOf( t->identifier() ) == tb->count()-1) ? + TRUE : FALSE; + QRect r2( r ); + if ( tb->shape() == QTabBar::RoundedAbove ) { + p->setPen( cg.midlight() ); + + p->drawLine( r2.left(), r2.bottom(), r2.right(), r2.bottom() ); + p->setPen( cg.light() ); + p->drawLine( r2.left(), r2.bottom()-1, r2.right(), r2.bottom()-1 ); + if ( r2.left() == 0 ) + p->drawPoint( tb->rect().bottomLeft() ); + + if ( selected ) { + p->fillRect( QRect( r2.left()+1, r2.bottom()-1, r2.width()-3, 2), + cg.brush( QColorGroup::Background )); + p->setPen( cg.background() ); + p->drawLine( r2.left()+1, r2.bottom(), r2.left()+1, r2.top()+2 ); + p->setPen( cg.light() ); + } else { + p->setPen( cg.light() ); + r2.setRect( r2.left() + 2, r2.top() + 2, + r2.width() - 4, r2.height() - 2 ); + } + + int x1, x2; + x1 = r2.left(); + x2 = r2.right() - 2; + p->drawLine( x1, r2.bottom()-1, x1, r2.top() + 2 ); + x1++; + p->drawPoint( x1, r2.top() + 1 ); + x1++; + p->drawLine( x1, r2.top(), x2, r2.top() ); + if ( r2.left() > 0 ) { + p->setPen( cg.midlight() ); + } + x1 = r2.left(); + p->drawPoint( x1, r2.bottom()); + + p->setPen( cg.midlight() ); + x1++; + p->drawLine( x1, r2.bottom(), x1, r2.top() + 2 ); + x1++; + p->drawLine( x1, r2.top()+1, x2, r2.top()+1 ); + + p->setPen( cg.dark() ); + x2 = r2.right() - 1; + p->drawLine( x2, r2.top() + 2, x2, r2.bottom() - 1 + + (selected ? 1:-1) ); + p->setPen( cg.shadow() ); + p->drawPoint( x2, r2.top() + 1 ); + p->drawPoint( x2, r2.top() + 1 ); + x2++; + p->drawLine( x2, r2.top() + 2, x2, r2.bottom() - + (selected ? (lastTab ? 0:1) :2)); + } else if ( tb->shape() == QTabBar::RoundedBelow ) { + bool rightAligned = styleHint( SH_TabBar_Alignment, tb ) == AlignRight; + bool firstTab = tb->indexOf( t->identifier() ) == 0; + if ( selected ) { + p->fillRect( QRect( r2.left()+1, r2.top(), r2.width()-3, 1), + cg.brush( QColorGroup::Background )); + p->setPen( cg.background() ); + p->drawLine( r2.left()+1, r2.top(), r2.left()+1, r2.bottom()-2 ); + p->setPen( cg.dark() ); + } else { + p->setPen( cg.shadow() ); + p->drawLine( r2.left() + + (rightAligned && firstTab ? 0 : 1), + r2.top() + 1, + r2.right() - (lastTab ? 0 : 2), + r2.top() + 1 ); + + if ( rightAligned && lastTab ) + p->drawPoint( r2.right(), r2.top() ); + p->setPen( cg.dark() ); + p->drawLine( r2.left(), r2.top(), r2.right() - 1, + r2.top() ); + r2.setRect( r2.left() + 2, r2.top(), + r2.width() - 4, r2.height() - 2 ); + } + + p->drawLine( r2.right() - 1, r2.top() + (selected ? 0: 2), + r2.right() - 1, r2.bottom() - 2 ); + p->drawPoint( r2.right() - 2, r2.bottom() - 2 ); + p->drawLine( r2.right() - 2, r2.bottom() - 1, + r2.left() + 1, r2.bottom() - 1 ); + + p->setPen( cg.midlight() ); + p->drawLine( r2.left() + 1, r2.bottom() - 2, + r2.left() + 1, r2.top() + (selected ? 0 : 2) ); + + p->setPen( cg.shadow() ); + p->drawLine( r2.right(), + r2.top() + (lastTab && rightAligned && + selected) ? 0 : 1, + r2.right(), r2.bottom() - 1 ); + p->drawPoint( r2.right() - 1, r2.bottom() - 1 ); + p->drawLine( r2.right() - 1, r2.bottom(), + r2.left() + 2, r2.bottom() ); + + p->setPen( cg.light() ); + p->drawLine( r2.left(), r2.top() + (selected ? 0 : 2), + r2.left(), r2.bottom() - 2 ); + } else { + QCommonStyle::drawControl(element, p, widget, r, cg, flags, opt); + } + break; + } +#endif // QT_NO_TABBAR + case CE_ToolBoxTab: + { + qDrawShadePanel( p, r, cg, flags & (Style_Sunken | Style_Down | Style_On) , 1, + &cg.brush(QColorGroup::Button)); + break; + } + +#ifndef QT_NO_POPUPMENU + case CE_PopupMenuItem: + { + if (! widget || opt.isDefault()) + break; + + const QPopupMenu *popupmenu = (const QPopupMenu *) widget; + QMenuItem *mi = opt.menuItem(); + if ( !mi ) + break; + + int tab = opt.tabWidth(); + int maxpmw = opt.maxIconWidth(); + bool dis = !(flags&Style_Enabled); + bool checkable = popupmenu->isCheckable(); + bool act = flags & Style_Active; + int x, y, w, h; + + r.rect(&x, &y, &w, &h); + + if ( checkable ) { + // space for the checkmarks + if (use2000style) + maxpmw = QMAX( maxpmw, 20 ); + else + maxpmw = QMAX( maxpmw, 12 ); + } + + int checkcol = maxpmw; + + if ( mi && mi->isSeparator() ) { // draw separator + p->setPen( cg.dark() ); + p->drawLine( x, y, x+w, y ); + p->setPen( cg.light() ); + p->drawLine( x, y+1, x+w, y+1 ); + return; + } + + QBrush fill = (act ? + cg.brush( QColorGroup::Highlight ) : + cg.brush( QColorGroup::Button )); + p->fillRect( x, y, w, h, fill); + + if ( !mi ) + return; + + int xpos = x; + QRect vrect = visualRect( QRect( xpos, y, checkcol, h ), r ); + int xvis = vrect.x(); + if ( mi->isChecked() ) { + if ( act && !dis ) + qDrawShadePanel( p, xvis, y, checkcol, h, + cg, TRUE, 1, &cg.brush( QColorGroup::Button ) ); + else { + QBrush fill( cg.light(), Dense4Pattern ); + // set the brush origin for the hash pattern to the x/y coordinate + // of the menu item's checkmark... this way, the check marks have + // a consistent look + QPoint origin = p->brushOrigin(); + p->setBrushOrigin( xvis, y ); + qDrawShadePanel( p, xvis, y, checkcol, h, cg, TRUE, 1, + &fill ); + // restore the previous brush origin + p->setBrushOrigin( origin ); + } + } else if (! act) + p->fillRect(xvis, y, checkcol , h, cg.brush( QColorGroup::Button )); + + if ( mi->iconSet() ) { // draw iconset + QIconSet::Mode mode = dis ? QIconSet::Disabled : QIconSet::Normal; + if (act && !dis ) + mode = QIconSet::Active; + QPixmap pixmap; + if ( checkable && mi->isChecked() ) + pixmap = mi->iconSet()->pixmap( QIconSet::Small, mode, QIconSet::On ); + else + pixmap = mi->iconSet()->pixmap( QIconSet::Small, mode ); + int pixw = pixmap.width(); + int pixh = pixmap.height(); + if ( act && !dis && !mi->isChecked() ) + qDrawShadePanel( p, xvis, y, checkcol, h, cg, FALSE, 1, + &cg.brush( QColorGroup::Button ) ); + QRect pmr( 0, 0, pixw, pixh ); + pmr.moveCenter( vrect.center() ); + p->setPen( cg.text() ); + p->drawPixmap( pmr.topLeft(), pixmap ); + + fill = (act ? + cg.brush( QColorGroup::Highlight ) : + cg.brush( QColorGroup::Button )); + int xp = xpos + checkcol + 1; + p->fillRect( visualRect( QRect( xp, y, w - checkcol - 1, h ), r ), fill); + } else if ( checkable ) { // just "checking"... + if ( mi->isChecked() ) { + int xp = xpos + windowsItemFrame; + + SFlags cflags = Style_Default; + if (! dis) + cflags |= Style_Enabled; + if (act) + cflags |= Style_On; + + drawPrimitive(PE_CheckMark, p, + visualRect( QRect(xp, y + windowsItemFrame, + checkcol - 2*windowsItemFrame, + h - 2*windowsItemFrame), r ), cg, cflags); + } + } + + p->setPen( act ? cg.highlightedText() : cg.buttonText() ); + + QColor discol; + if ( dis ) { + discol = cg.text(); + p->setPen( discol ); + } + + int xm = windowsItemFrame + checkcol + windowsItemHMargin; + xpos += xm; + + vrect = visualRect( QRect( xpos, y+windowsItemVMargin, w-xm-tab+1, h-2*windowsItemVMargin ), r ); + xvis = vrect.x(); + if ( mi->custom() ) { + p->save(); + if ( dis && !act ) { + p->setPen( cg.light() ); + mi->custom()->paint( p, cg, act, !dis, + xvis+1, y+windowsItemVMargin+1, w-xm-tab+1, h-2*windowsItemVMargin ); + p->setPen( discol ); + } + mi->custom()->paint( p, cg, act, !dis, + xvis, y+windowsItemVMargin, w-xm-tab+1, h-2*windowsItemVMargin ); + p->restore(); + } + QString s = mi->text(); + if ( !s.isNull() ) { // draw text + int t = s.find( '\t' ); + int text_flags = AlignVCenter|ShowPrefix | DontClip | SingleLine; + if (!styleHint(SH_UnderlineAccelerator, widget)) + text_flags |= NoAccel; + text_flags |= (QApplication::reverseLayout() ? AlignRight : AlignLeft ); + if ( t >= 0 ) { // draw tab text + int xp = x + w - tab - windowsItemHMargin - windowsItemFrame + 1; + if ( use2000style ) + xp -= 20; + else + xp -= windowsRightBorder; + int xoff = visualRect( QRect( xp, y+windowsItemVMargin, tab, h-2*windowsItemVMargin ), r ).x(); + if ( dis && !act ) { + p->setPen( cg.light() ); + p->drawText( xoff+1, y+windowsItemVMargin+1, tab, h-2*windowsItemVMargin, text_flags, s.mid( t+1 )); + p->setPen( discol ); + } + p->drawText( xoff, y+windowsItemVMargin, tab, h-2*windowsItemVMargin, text_flags, s.mid( t+1 ) ); + s = s.left( t ); + } + if ( dis && !act ) { + p->setPen( cg.light() ); + p->drawText( xvis+1, y+windowsItemVMargin+1, w-xm-tab+1, h-2*windowsItemVMargin, text_flags, s, t ); + p->setPen( discol ); + } + p->drawText( xvis, y+windowsItemVMargin, w-xm-tab+1, h-2*windowsItemVMargin, text_flags, s, t ); + } else if ( mi->pixmap() ) { // draw pixmap + QPixmap *pixmap = mi->pixmap(); + if ( pixmap->depth() == 1 ) + p->setBackgroundMode( OpaqueMode ); + p->drawPixmap( xvis, y+windowsItemFrame, *pixmap ); + if ( pixmap->depth() == 1 ) + p->setBackgroundMode( TransparentMode ); + } + if ( mi->popup() ) { // draw sub menu arrow + int dim = (h-2*windowsItemFrame) / 2; + PrimitiveElement arrow; + arrow = ( QApplication::reverseLayout() ? PE_ArrowLeft : PE_ArrowRight ); + xpos = x+w - windowsArrowHMargin - windowsItemFrame - dim; + vrect = visualRect( QRect(xpos, y + h / 2 - dim / 2, dim, dim), r ); + if ( act ) { + QColorGroup g2 = cg; + g2.setColor( QColorGroup::ButtonText, g2.highlightedText() ); + drawPrimitive(arrow, p, vrect, + g2, dis ? Style_Default : Style_Enabled); + } else { + drawPrimitive(arrow, p, vrect, + cg, dis ? Style_Default : Style_Enabled ); + } + } + + break; + } +#endif + + case CE_MenuBarItem: + { + bool active = flags & Style_Active; + bool hasFocus = flags & Style_HasFocus; + bool down = flags & Style_Down; + QRect pr = r; + + p->fillRect( r, cg.brush( QColorGroup::Button ) ); + if ( active || hasFocus ) { + QBrush b = cg.brush( QColorGroup::Button ); + if ( active && down ) + p->setBrushOrigin(p->brushOrigin() + QPoint(1,1)); + if ( active && hasFocus ) + qDrawShadeRect( p, r.x(), r.y(), r.width(), r.height(), + cg, active && down, 1, 0, &b ); + if ( active && down ) { + pr.moveBy( pixelMetric(PM_ButtonShiftHorizontal, widget), + pixelMetric(PM_ButtonShiftVertical, widget) ); + p->setBrushOrigin(p->brushOrigin() - QPoint(1,1)); + } + } + QCommonStyle::drawControl(element, p, widget, pr, cg, flags, opt); + break; + } + + default: + QCommonStyle::drawControl(element, p, widget, r, cg, flags, opt); + } +} + + +/*! + \reimp +*/ +int QWindowsStyle::pixelMetric(PixelMetric metric, const QWidget *widget) const +{ + int ret; + + switch (metric) { + case PM_ButtonDefaultIndicator: + case PM_ButtonShiftHorizontal: + case PM_ButtonShiftVertical: + ret = 1; + break; + + case PM_MaximumDragDistance: + ret = 60; + break; + +#ifndef QT_NO_SLIDER + case PM_SliderLength: + ret = 11; + break; + + // Returns the number of pixels to use for the business part of the + // slider (i.e., the non-tickmark portion). The remaining space is shared + // equally between the tickmark regions. + case PM_SliderControlThickness: + { + const QSlider * sl = (const QSlider *) widget; + int space = (sl->orientation() == Horizontal) ? sl->height() + : sl->width(); + int ticks = sl->tickmarks(); + int n = 0; + if ( ticks & QSlider::Above ) n++; + if ( ticks & QSlider::Below ) n++; + if ( !n ) { + ret = space; + break; + } + + int thick = 6; // Magic constant to get 5 + 16 + 5 + if ( ticks != QSlider::Both && ticks != QSlider::NoMarks ) + thick += pixelMetric( PM_SliderLength, sl ) / 4; + + space -= thick; + //### the two sides may be unequal in size + if ( space > 0 ) + thick += (space * 2) / (n + 2); + ret = thick; + break; + } +#endif // QT_NO_SLIDER + + case PM_MenuBarFrameWidth: + ret = 0; + break; + +#if defined(Q_WS_WIN) + case PM_TitleBarHeight: + if ( widget && ( widget->testWFlags( WStyle_Tool ) || ::qt_cast(widget) ) ) { + // MS always use one less than they say +#if defined(Q_OS_TEMP) + ret = GetSystemMetrics( SM_CYCAPTION ) - 1; +#else + ret = GetSystemMetrics( SM_CYSMCAPTION ) - 1; +#endif + } else { + ret = GetSystemMetrics( SM_CYCAPTION ) - 1; + } + break; + + case PM_ScrollBarExtent: + { +#ifndef Q_OS_TEMP + NONCLIENTMETRICS ncm; + ncm.cbSize = sizeof(NONCLIENTMETRICS); + if ( SystemParametersInfo( SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0 ) ) + ret = QMAX( ncm.iScrollHeight, ncm.iScrollWidth ); + else +#endif + ret = QCommonStyle::pixelMetric( metric, widget ); + } + break; +#endif + + case PM_SplitterWidth: + ret = QMAX( 6, QApplication::globalStrut().width() ); + break; + +#if defined(Q_WS_WIN) + case PM_MDIFrameWidth: + ret = GetSystemMetrics(SM_CYFRAME); + break; +#endif + + default: + ret = QCommonStyle::pixelMetric(metric, widget); + break; + } + + return ret; +} + + +/*! + \reimp +*/ +QSize QWindowsStyle::sizeFromContents( ContentsType contents, + const QWidget *widget, + const QSize &contentsSize, + const QStyleOption& opt ) const +{ + QSize sz(contentsSize); + + switch (contents) { + case CT_PushButton: + { +#ifndef QT_NO_PUSHBUTTON + const QPushButton *button = (const QPushButton *) widget; + sz = QCommonStyle::sizeFromContents(contents, widget, contentsSize, opt); + int w = sz.width(), h = sz.height(); + + int defwidth = 0; + if (button->isDefault() || button->autoDefault()) + defwidth = 2*pixelMetric( PM_ButtonDefaultIndicator, widget ); + + if (w < 80+defwidth && !button->pixmap()) + w = 80+defwidth; + if (h < 23+defwidth) + h = 23+defwidth; + + sz = QSize(w, h); +#endif + break; + } + + case CT_PopupMenuItem: + { +#ifndef QT_NO_POPUPMENU + if (! widget || opt.isDefault()) + break; + + const QPopupMenu *popup = (const QPopupMenu *) widget; + bool checkable = popup->isCheckable(); + QMenuItem *mi = opt.menuItem(); + int maxpmw = opt.maxIconWidth(); + int w = sz.width(), h = sz.height(); + + if (mi->custom()) { + w = mi->custom()->sizeHint().width(); + h = mi->custom()->sizeHint().height(); + if (! mi->custom()->fullSpan()) + h += 2*windowsItemVMargin + 2*windowsItemFrame; + } else if ( mi->widget() ) { + } else if (mi->isSeparator()) { + w = 10; // arbitrary + h = windowsSepHeight; + } else { + if (mi->pixmap()) + h = QMAX(h, mi->pixmap()->height() + 2*windowsItemFrame); + else if (! mi->text().isNull()) + h = QMAX(h, popup->fontMetrics().height() + 2*windowsItemVMargin + + 2*windowsItemFrame); + + if (mi->iconSet() != 0) + h = QMAX(h, mi->iconSet()->pixmap(QIconSet::Small, + QIconSet::Normal).height() + + 2*windowsItemFrame); + } + + if (! mi->text().isNull() && mi->text().find('\t') >= 0) { + if ( use2000style ) + w += 20; + else + w += windowsTabSpacing; + } else if (mi->popup()) { + w += 2*windowsArrowHMargin; + } + + if (use2000style) { + if (checkable && maxpmw < 20) + w += 20 - maxpmw; + } else { + if (checkable && maxpmw < windowsCheckMarkWidth) + w += windowsCheckMarkWidth - maxpmw; + } + if (checkable || maxpmw > 0) + w += windowsCheckMarkHMargin; + if (use2000style) + w += 20; + else + w += windowsRightBorder; + + sz = QSize(w, h); +#endif + break; + } + + default: + sz = QCommonStyle::sizeFromContents(contents, widget, sz, opt); + break; + } + + return sz; +} + +/*! \reimp +*/ +void QWindowsStyle::polishPopupMenu( QPopupMenu* p) +{ +#ifndef QT_NO_POPUPMENU + if ( !p->testWState( WState_Polished ) ) + p->setCheckable( TRUE ); +#endif +} + +#ifndef QT_NO_IMAGEIO_XPM +static const char * const qt_close_xpm[] = { +"12 12 2 1", +"# c #000000", +". c None", +"............", +"............", +"..##....##..", +"...##..##...", +"....####....", +".....##.....", +"....####....", +"...##..##...", +"..##....##..", +"............", +"............", +"............"}; + +static const char * const qt_maximize_xpm[]={ +"12 12 2 1", +"# c #000000", +". c None", +"............", +".#########..", +".#########..", +".#.......#..", +".#.......#..", +".#.......#..", +".#.......#..", +".#.......#..", +".#.......#..", +".#########..", +"............", +"............"}; + + +static const char * const qt_minimize_xpm[] = { +"12 12 2 1", +"# c #000000", +". c None", +"............", +"............", +"............", +"............", +"............", +"............", +"............", +"............", +"..######....", +"..######....", +"............", +"............"}; + +static const char * const qt_normalizeup_xpm[] = { +"12 12 2 1", +"# c #000000", +". c None", +"............", +"....######..", +"....######..", +"....#....#..", +"..######.#..", +"..######.#..", +"..#....###..", +"..#....#....", +"..#....#....", +"..######....", +"............", +"............"}; + + +static const char * const qt_shade_xpm[] = { +"12 12 2 1", +"# c #000000", +". c None", +"............", +"............", +"............", +"............", +"............", +".....#......", +"....###.....", +"...#####....", +"..#######...", +"............", +"............", +"............"}; + +static const char * const qt_unshade_xpm[] = { +"12 12 2 1", +"# c #000000", +". c None", +"............", +"............", +"............", +"............", +"..#######...", +"...#####....", +"....###.....", +".....#......", +"............", +"............", +"............", +"............"}; + +static const char * dock_window_close_xpm[] = { +"8 8 2 1", +"# c #000000", +". c None", +"........", +".##..##.", +"..####..", +"...##...", +"..####..", +".##..##.", +"........", +"........"}; + +/* XPM */ +static const char * const information_xpm[]={ +"32 32 5 1", +". c None", +"c c #000000", +"* c #999999", +"a c #ffffff", +"b c #0000ff", +"...........********.............", +"........***aaaaaaaa***..........", +"......**aaaaaaaaaaaaaa**........", +".....*aaaaaaaaaaaaaaaaaa*.......", +"....*aaaaaaaabbbbaaaaaaaac......", +"...*aaaaaaaabbbbbbaaaaaaaac.....", +"..*aaaaaaaaabbbbbbaaaaaaaaac....", +".*aaaaaaaaaaabbbbaaaaaaaaaaac...", +".*aaaaaaaaaaaaaaaaaaaaaaaaaac*..", +"*aaaaaaaaaaaaaaaaaaaaaaaaaaaac*.", +"*aaaaaaaaaabbbbbbbaaaaaaaaaaac*.", +"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**", +"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**", +"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**", +"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**", +"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**", +".*aaaaaaaaaaabbbbbaaaaaaaaaac***", +".*aaaaaaaaaaabbbbbaaaaaaaaaac***", +"..*aaaaaaaaaabbbbbaaaaaaaaac***.", +"...caaaaaaabbbbbbbbbaaaaaac****.", +"....caaaaaaaaaaaaaaaaaaaac****..", +".....caaaaaaaaaaaaaaaaaac****...", +"......ccaaaaaaaaaaaaaacc****....", +".......*cccaaaaaaaaccc*****.....", +"........***cccaaaac*******......", +"..........****caaac*****........", +".............*caaac**...........", +"...............caac**...........", +"................cac**...........", +".................cc**...........", +"..................***...........", +"...................**..........."}; +/* XPM */ +static const char* const warning_xpm[]={ +"32 32 4 1", +". c None", +"a c #ffff00", +"* c #000000", +"b c #999999", +".............***................", +"............*aaa*...............", +"...........*aaaaa*b.............", +"...........*aaaaa*bb............", +"..........*aaaaaaa*bb...........", +"..........*aaaaaaa*bb...........", +".........*aaaaaaaaa*bb..........", +".........*aaaaaaaaa*bb..........", +"........*aaaaaaaaaaa*bb.........", +"........*aaaa***aaaa*bb.........", +".......*aaaa*****aaaa*bb........", +".......*aaaa*****aaaa*bb........", +"......*aaaaa*****aaaaa*bb.......", +"......*aaaaa*****aaaaa*bb.......", +".....*aaaaaa*****aaaaaa*bb......", +".....*aaaaaa*****aaaaaa*bb......", +"....*aaaaaaaa***aaaaaaaa*bb.....", +"....*aaaaaaaa***aaaaaaaa*bb.....", +"...*aaaaaaaaa***aaaaaaaaa*bb....", +"...*aaaaaaaaaa*aaaaaaaaaa*bb....", +"..*aaaaaaaaaaa*aaaaaaaaaaa*bb...", +"..*aaaaaaaaaaaaaaaaaaaaaaa*bb...", +".*aaaaaaaaaaaa**aaaaaaaaaaa*bb..", +".*aaaaaaaaaaa****aaaaaaaaaa*bb..", +"*aaaaaaaaaaaa****aaaaaaaaaaa*bb.", +"*aaaaaaaaaaaaa**aaaaaaaaaaaa*bb.", +"*aaaaaaaaaaaaaaaaaaaaaaaaaaa*bbb", +"*aaaaaaaaaaaaaaaaaaaaaaaaaaa*bbb", +".*aaaaaaaaaaaaaaaaaaaaaaaaa*bbbb", +"..*************************bbbbb", +"....bbbbbbbbbbbbbbbbbbbbbbbbbbb.", +".....bbbbbbbbbbbbbbbbbbbbbbbbb.."}; +/* XPM */ +static const char* const critical_xpm[]={ +"32 32 4 1", +". c None", +"a c #999999", +"* c #ff0000", +"b c #ffffff", +"...........********.............", +".........************...........", +".......****************.........", +"......******************........", +".....********************a......", +"....**********************a.....", +"...************************a....", +"..*******b**********b*******a...", +"..******bbb********bbb******a...", +".******bbbbb******bbbbb******a..", +".*******bbbbb****bbbbb*******a..", +"*********bbbbb**bbbbb*********a.", +"**********bbbbbbbbbb**********a.", +"***********bbbbbbbb***********aa", +"************bbbbbb************aa", +"************bbbbbb************aa", +"***********bbbbbbbb***********aa", +"**********bbbbbbbbbb**********aa", +"*********bbbbb**bbbbb*********aa", +".*******bbbbb****bbbbb*******aa.", +".******bbbbb******bbbbb******aa.", +"..******bbb********bbb******aaa.", +"..*******b**********b*******aa..", +"...************************aaa..", +"....**********************aaa...", +"....a********************aaa....", +".....a******************aaa.....", +"......a****************aaa......", +".......aa************aaaa.......", +".........aa********aaaaa........", +"...........aaaaaaaaaaa..........", +".............aaaaaaa............"}; +/* XPM */ +static const char *const question_xpm[] = { +"32 32 5 1", +". c None", +"c c #000000", +"* c #999999", +"a c #ffffff", +"b c #0000ff", +"...........********.............", +"........***aaaaaaaa***..........", +"......**aaaaaaaaaaaaaa**........", +".....*aaaaaaaaaaaaaaaaaa*.......", +"....*aaaaaaaaaaaaaaaaaaaac......", +"...*aaaaaaaabbbbbbaaaaaaaac.....", +"..*aaaaaaaabaaabbbbaaaaaaaac....", +".*aaaaaaaabbaaaabbbbaaaaaaaac...", +".*aaaaaaaabbbbaabbbbaaaaaaaac*..", +"*aaaaaaaaabbbbaabbbbaaaaaaaaac*.", +"*aaaaaaaaaabbaabbbbaaaaaaaaaac*.", +"*aaaaaaaaaaaaabbbbaaaaaaaaaaac**", +"*aaaaaaaaaaaaabbbaaaaaaaaaaaac**", +"*aaaaaaaaaaaaabbaaaaaaaaaaaaac**", +"*aaaaaaaaaaaaabbaaaaaaaaaaaaac**", +"*aaaaaaaaaaaaaaaaaaaaaaaaaaaac**", +".*aaaaaaaaaaaabbaaaaaaaaaaaac***", +".*aaaaaaaaaaabbbbaaaaaaaaaaac***", +"..*aaaaaaaaaabbbbaaaaaaaaaac***.", +"...caaaaaaaaaabbaaaaaaaaaac****.", +"....caaaaaaaaaaaaaaaaaaaac****..", +".....caaaaaaaaaaaaaaaaaac****...", +"......ccaaaaaaaaaaaaaacc****....", +".......*cccaaaaaaaaccc*****.....", +"........***cccaaaac*******......", +"..........****caaac*****........", +".............*caaac**...........", +"...............caac**...........", +"................cac**...........", +".................cc**...........", +"..................***...........", +"...................**...........", +}; +#endif //QT_NO_IMAGEIO_XPM + +/*! + \reimp + */ +QPixmap QWindowsStyle::stylePixmap(StylePixmap stylepixmap, + const QWidget *widget, + const QStyleOption& opt) const +{ +#ifndef QT_NO_IMAGEIO_XPM + switch (stylepixmap) { + case SP_TitleBarShadeButton: + return QPixmap( (const char **)qt_shade_xpm ); + case SP_TitleBarUnshadeButton: + return QPixmap( (const char **)qt_unshade_xpm ); + case SP_TitleBarNormalButton: + return QPixmap( (const char **)qt_normalizeup_xpm ); + case SP_TitleBarMinButton: + return QPixmap( (const char **)qt_minimize_xpm ); + case SP_TitleBarMaxButton: + return QPixmap( (const char **)qt_maximize_xpm ); + case SP_TitleBarCloseButton: + return QPixmap( (const char **)qt_close_xpm ); + case SP_DockWindowCloseButton: + return QPixmap( (const char **)dock_window_close_xpm ); + case SP_MessageBoxInformation: + return QPixmap( (const char **)information_xpm); + case SP_MessageBoxWarning: + return QPixmap( (const char **)warning_xpm ); + case SP_MessageBoxCritical: + return QPixmap( (const char **)critical_xpm ); + case SP_MessageBoxQuestion: + return QPixmap( (const char **)question_xpm ); + default: + break; + } +#endif //QT_NO_IMAGEIO_XPM + return QCommonStyle::stylePixmap(stylepixmap, widget, opt); +} + +/*!\reimp +*/ +void QWindowsStyle::drawComplexControl( ComplexControl ctrl, QPainter *p, + const QWidget *widget, + const QRect &r, + const QColorGroup &cg, + SFlags flags, + SCFlags sub, + SCFlags subActive, + const QStyleOption& opt ) const +{ + switch (ctrl) { +#ifndef QT_NO_LISTVIEW + case CC_ListView: + { + if ( sub & SC_ListView ) { + QCommonStyle::drawComplexControl( ctrl, p, widget, r, cg, flags, sub, subActive, opt ); + } + if ( sub & ( SC_ListViewBranch | SC_ListViewExpand ) ) { + if (opt.isDefault()) + break; + + QListViewItem *item = opt.listViewItem(), + *child = item->firstChild(); + + int y = r.y(); + int c; + int dotoffset = 0; + QPointArray dotlines; + if ( subActive == (uint)SC_All && sub == SC_ListViewExpand ) { + c = 2; + dotlines.resize(2); + dotlines[0] = QPoint( r.right(), r.top() ); + dotlines[1] = QPoint( r.right(), r.bottom() ); + } else { + int linetop = 0, linebot = 0; + // each branch needs at most two lines, ie. four end points + dotoffset = (item->itemPos() + item->height() - y) %2; + dotlines.resize( item->childCount() * 4 ); + c = 0; + + // skip the stuff above the exposed rectangle + while ( child && y + child->height() <= 0 ) { + y += child->totalHeight(); + child = child->nextSibling(); + } + + int bx = r.width() / 2; + + // paint stuff in the magical area + QListView* v = item->listView(); + while ( child && y < r.height() ) { + if (child->isVisible()) { + int lh; + if ( !item->multiLinesEnabled() ) + lh = child->height(); + else + lh = p->fontMetrics().height() + 2 * v->itemMargin(); + lh = QMAX( lh, QApplication::globalStrut().height() ); + if ( lh % 2 > 0 ) + lh++; + linebot = y + lh/2; + if ( (child->isExpandable() || child->childCount()) && + (child->height() > 0) ) { + // needs a box + p->setPen( cg.mid() ); + p->drawRect( bx-4, linebot-4, 9, 9 ); + // plus or minus + p->setPen( cg.text() ); + p->drawLine( bx - 2, linebot, bx + 2, linebot ); + if ( !child->isOpen() ) + p->drawLine( bx, linebot - 2, bx, linebot + 2 ); + // dotlinery + p->setPen( cg.mid() ); + dotlines[c++] = QPoint( bx, linetop ); + dotlines[c++] = QPoint( bx, linebot - 4 ); + dotlines[c++] = QPoint( bx + 5, linebot ); + dotlines[c++] = QPoint( r.width(), linebot ); + linetop = linebot + 5; + } else { + // just dotlinery + dotlines[c++] = QPoint( bx+1, linebot -1); + dotlines[c++] = QPoint( r.width(), linebot -1); + } + y += child->totalHeight(); + } + child = child->nextSibling(); + } + + // Expand line height to edge of rectangle if there's any + // visible child below + while ( child && child->height() <= 0) + child = child->nextSibling(); + if ( child ) + linebot = r.height(); + + if ( linetop < linebot ) { + dotlines[c++] = QPoint( bx, linetop ); + dotlines[c++] = QPoint( bx, linebot ); + } + } + p->setPen( cg.text() ); + + static QBitmap *verticalLine = 0, *horizontalLine = 0; + static QCleanupHandler qlv_cleanup_bitmap; + if ( !verticalLine ) { + // make 128*1 and 1*128 bitmaps that can be used for + // drawing the right sort of lines. + verticalLine = new QBitmap( 1, 129, TRUE ); + horizontalLine = new QBitmap( 128, 1, TRUE ); + QPointArray a( 64 ); + QPainter p; + p.begin( verticalLine ); + int i; + for( i=0; i<64; i++ ) + a.setPoint( i, 0, i*2+1 ); + p.setPen( color1 ); + p.drawPoints( a ); + p.end(); + QApplication::flushX(); + verticalLine->setMask( *verticalLine ); + p.begin( horizontalLine ); + for( i=0; i<64; i++ ) + a.setPoint( i, i*2+1, 0 ); + p.setPen( color1 ); + p.drawPoints( a ); + p.end(); + QApplication::flushX(); + horizontalLine->setMask( *horizontalLine ); + qlv_cleanup_bitmap.add( &verticalLine ); + qlv_cleanup_bitmap.add( &horizontalLine ); + } + + int line; // index into dotlines + if ( sub & SC_ListViewBranch ) for( line = 0; line < c; line += 2 ) { + // assumptions here: lines are horizontal or vertical. + // lines always start with the numerically lowest + // coordinate. + + // point ... relevant coordinate of current point + // end ..... same coordinate of the end of the current line + // other ... the other coordinate of the current point/line + if ( dotlines[line].y() == dotlines[line+1].y() ) { + int end = dotlines[line+1].x(); + int point = dotlines[line].x(); + int other = dotlines[line].y(); + while( point < end ) { + int i = 128; + if ( i+point > end ) + i = end-point; + p->drawPixmap( point, other, *horizontalLine, + 0, 0, i, 1 ); + point += i; + } + } else { + int end = dotlines[line+1].y(); + int point = dotlines[line].y(); + int other = dotlines[line].x(); + int pixmapoffset = ((point & 1) != dotoffset ) ? 1 : 0; + while( point < end ) { + int i = 128; + if ( i+point > end ) + i = end-point; + p->drawPixmap( other, point, *verticalLine, + 0, pixmapoffset, 1, i ); + point += i; + } + } + } + } + } + break; +#endif //QT_NO_LISTVIEW + +#ifndef QT_NO_COMBOBOX + case CC_ComboBox: + if ( sub & SC_ComboBoxArrow ) { + SFlags flags = Style_Default; + + qDrawWinPanel( p, r, cg, TRUE, widget->isEnabled() ? + &cg.brush( QColorGroup::Base ): + &cg.brush( QColorGroup::Background ) ); + + QRect ar = + QStyle::visualRect( querySubControlMetrics( CC_ComboBox, widget, + SC_ComboBoxArrow ), widget ); + if ( subActive == SC_ComboBoxArrow ) { + p->setPen( cg.dark() ); + p->setBrush( cg.brush( QColorGroup::Button ) ); + p->drawRect( ar ); + } else + qDrawWinPanel( p, ar, cg, FALSE, + &cg.brush( QColorGroup::Button ) ); + + ar.addCoords( 2, 2, -2, -2 ); + if ( widget->isEnabled() ) + flags |= Style_Enabled; + + if ( subActive == SC_ComboBoxArrow ) { + flags |= Style_Sunken; + } + drawPrimitive( PE_ArrowDown, p, ar, cg, flags ); + } + + if ( sub & SC_ComboBoxEditField ) { + const QComboBox * cb = (const QComboBox *) widget; + QRect re = + QStyle::visualRect( querySubControlMetrics( CC_ComboBox, widget, + SC_ComboBoxEditField ), widget ); + if ( cb->hasFocus() && !cb->editable() ) + p->fillRect( re.x(), re.y(), re.width(), re.height(), + cg.brush( QColorGroup::Highlight ) ); + + if ( cb->hasFocus() ) { + p->setPen( cg.highlightedText() ); + p->setBackgroundColor( cg.highlight() ); + + } else { + p->setPen( cg.text() ); + p->setBackgroundColor( cg.background() ); + } + + if ( cb->hasFocus() && !cb->editable() ) { + QRect re = + QStyle::visualRect( subRect( SR_ComboBoxFocusRect, cb ), widget ); + drawPrimitive( PE_FocusRect, p, re, cg, Style_FocusAtBorder, QStyleOption(cg.highlight())); + } + } + + break; +#endif // QT_NO_COMBOBOX + +#ifndef QT_NO_SLIDER + case CC_Slider: + { + const QSlider *sl = (const QSlider *) widget; + int thickness = pixelMetric( PM_SliderControlThickness, widget ); + int len = pixelMetric( PM_SliderLength, widget ); + int ticks = sl->tickmarks(); + + QRect groove = querySubControlMetrics(CC_Slider, widget, SC_SliderGroove, + opt), + handle = querySubControlMetrics(CC_Slider, widget, SC_SliderHandle, + opt); + + if ((sub & SC_SliderGroove) && groove.isValid()) { + int mid = thickness / 2; + + if ( ticks & QSlider::Above ) + mid += len / 8; + if ( ticks & QSlider::Below ) + mid -= len / 8; + + p->setPen( cg.shadow() ); + if ( sl->orientation() == Horizontal ) { + qDrawWinPanel( p, groove.x(), groove.y() + mid - 2, + groove.width(), 4, cg, TRUE ); + p->drawLine( groove.x() + 1, groove.y() + mid - 1, + groove.x() + groove.width() - 3, groove.y() + mid - 1 ); + } else { + qDrawWinPanel( p, groove.x() + mid - 2, groove.y(), + 4, groove.height(), cg, TRUE ); + p->drawLine( groove.x() + mid - 1, groove.y() + 1, + groove.x() + mid - 1, + groove.y() + groove.height() - 3 ); + } + } + + if (sub & SC_SliderTickmarks) + QCommonStyle::drawComplexControl(ctrl, p, widget, r, cg, flags, + SC_SliderTickmarks, subActive, + opt ); + + if ( sub & SC_SliderHandle ) { + // 4444440 + // 4333310 + // 4322210 + // 4322210 + // 4322210 + // 4322210 + // *43210* + // **410** + // ***0*** + const QColor c0 = cg.shadow(); + const QColor c1 = cg.dark(); + // const QColor c2 = g.button(); + const QColor c3 = cg.midlight(); + const QColor c4 = cg.light(); + + int x = handle.x(), y = handle.y(), + wi = handle.width(), he = handle.height(); + + int x1 = x; + int x2 = x+wi-1; + int y1 = y; + int y2 = y+he-1; + + Orientation orient = sl->orientation(); + bool tickAbove = sl->tickmarks() == QSlider::Above; + bool tickBelow = sl->tickmarks() == QSlider::Below; + + p->fillRect( x, y, wi, he, cg.brush( QColorGroup::Background ) ); + + if ( flags & Style_HasFocus ) { + QRect re = subRect( SR_SliderFocusRect, sl ); + drawPrimitive( PE_FocusRect, p, re, cg ); + } + + if ( (tickAbove && tickBelow) || (!tickAbove && !tickBelow) ) { + qDrawWinButton( p, QRect(x,y,wi,he), cg, FALSE, + &cg.brush( QColorGroup::Button ) ); + return; + } + + QSliderDirection dir; + + if ( orient == Horizontal ) + if ( tickAbove ) + dir = SlUp; + else + dir = SlDown; + else + if ( tickAbove ) + dir = SlLeft; + else + dir = SlRight; + + QPointArray a; + + int d = 0; + switch ( dir ) { + case SlUp: + y1 = y1 + wi/2; + d = (wi + 1) / 2 - 1; + a.setPoints(5, x1,y1, x1,y2, x2,y2, x2,y1, x1+d,y1-d ); + break; + case SlDown: + y2 = y2 - wi/2; + d = (wi + 1) / 2 - 1; + a.setPoints(5, x1,y1, x1,y2, x1+d,y2+d, x2,y2, x2,y1 ); + break; + case SlLeft: + d = (he + 1) / 2 - 1; + x1 = x1 + he/2; + a.setPoints(5, x1,y1, x1-d,y1+d, x1,y2, x2,y2, x2,y1); + break; + case SlRight: + d = (he + 1) / 2 - 1; + x2 = x2 - he/2; + a.setPoints(5, x1,y1, x1,y2, x2,y2, x2+d,y1+d, x2,y1 ); + break; + } + + QBrush oldBrush = p->brush(); + p->setBrush( cg.brush( QColorGroup::Button ) ); + p->setPen( NoPen ); + p->drawRect( x1, y1, x2-x1+1, y2-y1+1 ); + p->drawPolygon( a ); + p->setBrush( oldBrush ); + + if ( dir != SlUp ) { + p->setPen( c4 ); + p->drawLine( x1, y1, x2, y1 ); + p->setPen( c3 ); + p->drawLine( x1, y1+1, x2, y1+1 ); + } + if ( dir != SlLeft ) { + p->setPen( c3 ); + p->drawLine( x1+1, y1+1, x1+1, y2 ); + p->setPen( c4 ); + p->drawLine( x1, y1, x1, y2 ); + } + if ( dir != SlRight ) { + p->setPen( c0 ); + p->drawLine( x2, y1, x2, y2 ); + p->setPen( c1 ); + p->drawLine( x2-1, y1+1, x2-1, y2-1 ); + } + if ( dir != SlDown ) { + p->setPen( c0 ); + p->drawLine( x1, y2, x2, y2 ); + p->setPen( c1 ); + p->drawLine( x1+1, y2-1, x2-1, y2-1 ); + } + + switch ( dir ) { + case SlUp: + p->setPen( c4 ); + p->drawLine( x1, y1, x1+d, y1-d); + p->setPen( c0 ); + d = wi - d - 1; + p->drawLine( x2, y1, x2-d, y1-d); + d--; + p->setPen( c3 ); + p->drawLine( x1+1, y1, x1+1+d, y1-d ); + p->setPen( c1 ); + p->drawLine( x2-1, y1, x2-1-d, y1-d); + break; + case SlDown: + p->setPen( c4 ); + p->drawLine( x1, y2, x1+d, y2+d); + p->setPen( c0 ); + d = wi - d - 1; + p->drawLine( x2, y2, x2-d, y2+d); + d--; + p->setPen( c3 ); + p->drawLine( x1+1, y2, x1+1+d, y2+d ); + p->setPen( c1 ); + p->drawLine( x2-1, y2, x2-1-d, y2+d); + break; + case SlLeft: + p->setPen( c4 ); + p->drawLine( x1, y1, x1-d, y1+d); + p->setPen( c0 ); + d = he - d - 1; + p->drawLine( x1, y2, x1-d, y2-d); + d--; + p->setPen( c3 ); + p->drawLine( x1, y1+1, x1-d, y1+1+d ); + p->setPen( c1 ); + p->drawLine( x1, y2-1, x1-d, y2-1-d); + break; + case SlRight: + p->setPen( c4 ); + p->drawLine( x2, y1, x2+d, y1+d); + p->setPen( c0 ); + d = he - d - 1; + p->drawLine( x2, y2, x2+d, y2-d); + d--; + p->setPen( c3 ); + p->drawLine( x2, y1+1, x2+d, y1+1+d ); + p->setPen( c1 ); + p->drawLine( x2, y2-1, x2+d, y2-1-d); + break; + } + } + + break; + } +#endif // QT_NO_SLIDER + + default: + QCommonStyle::drawComplexControl( ctrl, p, widget, r, cg, flags, sub, + subActive, opt ); + break; + } +} + + +/*! \reimp */ +int QWindowsStyle::styleHint( StyleHint hint, + const QWidget *widget, + const QStyleOption &opt, + QStyleHintReturn *returnData ) const +{ + int ret; + + switch (hint) { + case SH_EtchDisabledText: + case SH_Slider_SnapToValue: + case SH_PrintDialog_RightAlignButtons: + case SH_MainWindow_SpaceBelowMenuBar: + case SH_FontDialog_SelectAssociatedText: + case SH_PopupMenu_AllowActiveAndDisabled: + case SH_MenuBar_AltKeyNavigation: + case SH_MenuBar_MouseTracking: + case SH_PopupMenu_MouseTracking: + case SH_ComboBox_ListMouseTracking: + case SH_ScrollBar_StopMouseOverSlider: + ret = 1; + break; + + case SH_ItemView_ChangeHighlightOnFocus: +#if defined(Q_WS_WIN) + if ( qWinVersion() != WV_95 && qWinVersion() != WV_NT ) + ret = 1; + else +#endif + ret = 0; + break; + + case SH_ToolBox_SelectedPageTitleBold: + ret = 0; + break; + +#if defined(Q_WS_WIN) + case SH_UnderlineAccelerator: + ret = 1; + if ( qWinVersion() != WV_95 && qWinVersion() != WV_98 && qWinVersion() != WV_NT ) { + BOOL cues; + SystemParametersInfo(SPI_GETKEYBOARDCUES, 0, &cues, 0); + ret = cues ? 1 : 0; + // Do nothing if we always paint underlines + if (!ret && widget && d) { + QMenuBar *menuBar = ::qt_cast(widget); + QPopupMenu *popupMenu = 0; + if (!menuBar) + popupMenu = ::qt_cast(widget); + + // If we paint a menubar draw underlines if it has focus, or if alt is down, + // or if a popup menu belonging to the menubar is active and paints underlines + if (menuBar) { + if (menuBar->hasFocus()) { + ret = 1; + } else if (d->altDown()) { + ret = 1; + } else if (qApp->focusWidget() && qApp->focusWidget()->isPopup()) { + popupMenu = ::qt_cast(qApp->focusWidget()); + QMenuData *pm = popupMenu ? (QMenuData*)popupMenu->qt_cast("QMenuData") : 0; + if (pm && ((FriendlyMenuData*)pm)->parentMenu == menuBar) { + if (d->hasSeenAlt(menuBar)) + ret = 1; + } + } + // If we paint a popup menu draw underlines if the respective menubar does + } else if (popupMenu) { + QMenuData *pm = (QMenuData*)popupMenu->qt_cast("QMenuData"); + while (pm) { + if (((FriendlyMenuData*)pm)->isMenuBar) { + menuBar = (QMenuBar*)pm; + if (d->hasSeenAlt(menuBar)) + ret = 1; + break; + } + pm = ((FriendlyMenuData*)pm)->parentMenu; + } + // Otherwise draw underlines if the toplevel widget has seen an alt-press + } else if (d->hasSeenAlt(widget)) { + ret = 1; + } + } + + } + break; +#endif + + default: + ret = QCommonStyle::styleHint(hint, widget, opt, returnData); + break; + } + + return ret; +} + +/*! \reimp */ +QRect QWindowsStyle::subRect(SubRect r, const QWidget *widget) const +{ + QRect rect; + + switch (r) { +#ifndef QT_NO_SLIDER + case SR_SliderFocusRect: + { + rect = widget->rect(); + break; + } +#endif // QT_NO_SLIDER + case SR_ToolBoxTabContents: + rect = widget->rect(); + break; + default: + rect = QCommonStyle::subRect( r, widget ); + break; + } + + return rect; +} + +#endif diff --git a/src/styles/qwindowsstyle.h b/src/styles/qwindowsstyle.h new file mode 100644 index 0000000..5ad82b0 --- /dev/null +++ b/src/styles/qwindowsstyle.h @@ -0,0 +1,135 @@ +/**************************************************************************** +** +** Definition of Windows-like style class +** +** Created : 981231 +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the widgets module of the Qt GUI Toolkit. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** This file may be used under the terms of the Q Public License as +** defined by Trolltech ASA and appearing in the file LICENSE.QPL +** included in the packaging of this file. Licensees holding valid Qt +** Commercial licenses may use this file in accordance with the Qt +** Commercial License Agreement provided with the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef QWINDOWSSTYLE_H +#define QWINDOWSSTYLE_H + +#ifndef QT_H +#include "qcommonstyle.h" +#endif // QT_H + +#if !defined(QT_NO_STYLE_WINDOWS) || defined(QT_PLUGIN) + +#if defined(QT_PLUGIN) +#define Q_EXPORT_STYLE_WINDOWS +#else +#define Q_EXPORT_STYLE_WINDOWS Q_EXPORT +#endif + + +class Q_EXPORT_STYLE_WINDOWS QWindowsStyle : public QCommonStyle +{ + Q_OBJECT +public: + QWindowsStyle(); + ~QWindowsStyle(); + + void polish(QApplication*); + void unPolish(QApplication*); + + void polish(QWidget*); + void unPolish(QWidget*); + + void polish( QPalette & ); + + virtual void polishPopupMenu( QPopupMenu* ); + + // new stuff + void drawPrimitive( PrimitiveElement pe, + QPainter *p, + const QRect &r, + const QColorGroup &cg, + SFlags flags = Style_Default, + const QStyleOption& = QStyleOption::Default ) const; + + void drawControl( ControlElement element, + QPainter *p, + const QWidget *widget, + const QRect &r, + const QColorGroup &cg, + SFlags flags = Style_Default, + const QStyleOption& = QStyleOption::Default ) const; + + void drawComplexControl( ComplexControl control, + QPainter* p, + const QWidget* widget, + const QRect& r, + const QColorGroup& cg, + SFlags flags = Style_Default, +#ifdef Q_QDOC + SCFlags sub = SC_All, +#else + SCFlags sub = (uint)SC_All, +#endif + SCFlags subActive = SC_None, + const QStyleOption& = QStyleOption::Default ) const; + + int pixelMetric( PixelMetric metric, + const QWidget *widget = 0 ) const; + + QSize sizeFromContents( ContentsType contents, + const QWidget *widget, + const QSize &contentsSize, + const QStyleOption& = QStyleOption::Default ) const; + + int styleHint(StyleHint sh, const QWidget *, const QStyleOption & = QStyleOption::Default, + QStyleHintReturn* = 0) const; + + QPixmap stylePixmap( StylePixmap stylepixmap, + const QWidget *widget = 0, + const QStyleOption& = QStyleOption::Default ) const; + + QRect subRect( SubRect r, const QWidget *widget ) const; + + +private: + class Private; + Private *d; + + // Disabled copy constructor and operator= +#if defined(Q_DISABLE_COPY) + QWindowsStyle( const QWindowsStyle & ); + QWindowsStyle& operator=( const QWindowsStyle & ); +#endif +}; + +#endif // QT_NO_STYLE_WINDOWS + +#endif // QWINDOWSSTYLE_H -- cgit v1.2.1