• Skip to content
  • Skip to link menu
KDE 4.1 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

KStyles

oxygen.cpp

Go to the documentation of this file.
00001 /* Oxygen widget style for KDE 4
00002    Copyright (C) 2007-2008 Casper Boemann <cbr@boemann.dk>
00003    Copyright (C) 2003-2005 Sandro Giessl <sandro@giessl.com>
00004    Copyright (C) 2001-2002 Chris Lee <clee@kde.org>
00005    Copyright (C) 2001-2002 Carsten Pfeiffer <pfeiffer@kde.org>
00006    Copyright (C) 2001-2002 Karol Szwed <gallium@kde.org>
00007    Copyright (c) 2002 Malte Starostik <malte@kde.org>
00008    Copyright (C) 2002,2003 Maksim Orlovich <mo002j@mail.rochester.edu>
00009    Copyright (C) 2001-2002 Karol Szwed      <gallium@kde.org>
00010    Copyright (C) 2001-2002 Fredrik Höglund  <fredrik@kde.org>
00011    Copyright (C) 2000 Daniel M. Duley       <mosfet@kde.org>
00012    Copyright (C) 2000 Dirk Mueller          <mueller@kde.org>
00013    Copyright (C) 2001 Martijn Klingens      <klingens@kde.org>
00014 
00015    This library is free software; you can redistribute it and/or
00016    modify it under the terms of the GNU Library General Public
00017    License version 2 as published by the Free Software Foundation.
00018 
00019    This library is distributed in the hope that it will be useful,
00020    but WITHOUT ANY WARRANTY; without even the implied warranty of
00021    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00022    Library General Public License for more details.
00023 
00024    You should have received a copy of the GNU Library General Public License
00025    along with this library; see the file COPYING.LIB.  If not, write to
00026    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00027    Boston, MA 02110-1301, USA.
00028  */
00029 
00030 #include "oxygen.h"
00031 #include "oxygen.moc"
00032 
00033 #include <QtGui/QPainter>
00034 #include <QtCore/QTimer>
00035 #include <QtCore/QEvent>
00036 #include <QtCore/QSettings>
00037 #include <QtGui/QStyleOption>
00038 #include <QtGui/QApplication>
00039 
00040 #include <QtGui/QCheckBox>
00041 #include <QtGui/QComboBox>
00042 #include <QtGui/QMenuBar>
00043 #include <QtGui/QProgressBar>
00044 #include <QtGui/QPushButton>
00045 #include <QtGui/QRadioButton>
00046 #include <QtGui/QToolButton>
00047 #include <QtGui/QToolBar>
00048 #include <QtGui/QToolBox>
00049 #include <QtGui/QScrollBar>
00050 #include <QtGui/QGroupBox>
00051 #include <QtGui/QLineEdit>
00052 #include <QtGui/QDockWidget>
00053 #include <QtGui/QMdiSubWindow>
00054 #include <QStyleOptionDockWidget>
00055 #include <QPaintEvent>
00056 #include <QToolBox>
00057 #include <QAbstractScrollArea>
00058 #include <QAbstractItemView>
00059 #include <KTitleWidget>
00060 
00061 #include <QtDBus/QtDBus>
00062 
00063 #include <KGlobal>
00064 #include <KGlobalSettings>
00065 #include <KConfigGroup>
00066 #include <KColorUtils>
00067 #include <KIconEffect>
00068 #include <kdebug.h>
00069 
00070 #include <math.h>
00071 
00072 #include "helper.h"
00073 #include "tileset.h"
00074 
00075 // We need better holes! Bevel color and shadow color are currently based on
00076 // only one color, even though they are different things; also, we don't really
00077 // know what bevel color should be based on... (and shadow color for white
00078 // views looks rather bad). For now at least, just using QPalette::Window
00079 // everywhere seems best...
00080 #define HOLE_COLOR_OUTSIDE
00081 
00082 K_EXPORT_STYLE("Oxygen", OxygenStyle)
00083 
00084 K_GLOBAL_STATIC_WITH_ARGS(OxygenStyleHelper, globalHelper, ("oxygen"))
00085 
00086 static const int gw = 2; // ie glowwidth which we want to un-reserve space for in the tabs
00087 
00088 OxygenStyle::OxygenStyle() :
00089     KStyle(),
00090 //     kickerMode(false),
00091 //     kornMode(false),
00092     flatMode(false),
00093     _helper(*globalHelper)
00094 {
00095     _config = _helper.config();
00096 
00097     // connect to KGlobalSettings signals so we will be notified when the
00098     // system palette (in particular, the contrast) is changed
00099     QDBusConnection::sessionBus().connect( QString(), "/KGlobalSettings",
00100                                            "org.kde.KGlobalSettings",
00101                                            "notifyChange", this,
00102                                            SLOT(globalSettingsChange(int,int))
00103                                          );
00104 
00105     // call the slot directly; this initial call will set up things that also
00106     // need to be reset when the system palette changes
00107     globalSettingsChange(KGlobalSettings::PaletteChanged, 0);
00108 
00109     setWidgetLayoutProp(WT_Generic, Generic::DefaultFrameWidth, 2);
00110 
00111     // TODO: change this when double buttons are implemented
00112     setWidgetLayoutProp(WT_ScrollBar, ScrollBar::DoubleBotButton, true);
00113     setWidgetLayoutProp(WT_ScrollBar, ScrollBar::MinimumSliderHeight, 21);
00114     setWidgetLayoutProp(WT_ScrollBar, ScrollBar::BarWidth, 15); // size*2+1
00115     setWidgetLayoutProp(WT_ScrollBar, ScrollBar::ArrowColor,QPalette::ButtonText);
00116     setWidgetLayoutProp(WT_ScrollBar, ScrollBar::ActiveArrowColor,QPalette::ButtonText);
00117     setWidgetLayoutProp(WT_ScrollBar, ScrollBar::SingleButtonHeight, 14);
00118     setWidgetLayoutProp(WT_ScrollBar, ScrollBar::DoubleButtonHeight, 28);
00119 
00120     setWidgetLayoutProp(WT_PushButton, PushButton::DefaultIndicatorMargin, 0);
00121     setWidgetLayoutProp(WT_PushButton, PushButton::ContentsMargin + Left, 16);
00122     setWidgetLayoutProp(WT_PushButton, PushButton::ContentsMargin + Right, 16);
00123     setWidgetLayoutProp(WT_PushButton, PushButton::ContentsMargin + Top, 1);
00124     setWidgetLayoutProp(WT_PushButton, PushButton::ContentsMargin + Bot, 0);
00125     setWidgetLayoutProp(WT_PushButton, PushButton::FocusMargin, 0);
00126     setWidgetLayoutProp(WT_PushButton, PushButton::FocusMargin + Left, 0);
00127     setWidgetLayoutProp(WT_PushButton, PushButton::FocusMargin + Right, 0);
00128     setWidgetLayoutProp(WT_PushButton, PushButton::FocusMargin + Top, 0);
00129     setWidgetLayoutProp(WT_PushButton, PushButton::FocusMargin + Bot, 0);
00130     setWidgetLayoutProp(WT_PushButton, PushButton::PressedShiftHorizontal, 0);
00131     setWidgetLayoutProp(WT_PushButton, PushButton::PressedShiftVertical,   0);
00132 
00133     setWidgetLayoutProp(WT_Splitter, Splitter::Width, 6);
00134 
00135     setWidgetLayoutProp(WT_CheckBox, CheckBox::Size, 23);
00136     setWidgetLayoutProp(WT_CheckBox, CheckBox::BoxTextSpace, 4);
00137     setWidgetLayoutProp(WT_RadioButton, RadioButton::Size, 25);
00138     setWidgetLayoutProp(WT_RadioButton, RadioButton::BoxTextSpace, 4);
00139 
00140     setWidgetLayoutProp(WT_DockWidget, DockWidget::TitleTextColor, QPalette::WindowText);
00141     setWidgetLayoutProp(WT_DockWidget, DockWidget::FrameWidth, 0);
00142     setWidgetLayoutProp(WT_DockWidget, DockWidget::TitleMargin, 3);
00143 
00144     setWidgetLayoutProp(WT_Menu, Menu::FrameWidth, 5);
00145 
00146     setWidgetLayoutProp(WT_MenuBar, MenuBar::ItemSpacing, 0);
00147     setWidgetLayoutProp(WT_MenuBar, MenuBar::Margin,        0);
00148     setWidgetLayoutProp(WT_MenuBar, MenuBar::Margin + Left,  0);
00149     setWidgetLayoutProp(WT_MenuBar, MenuBar::Margin + Right, 0);
00150     setWidgetLayoutProp(WT_MenuBar, MenuBar::Margin + Top, 0);
00151     setWidgetLayoutProp(WT_MenuBar, MenuBar::Margin + Bot, 2);
00152 
00153     setWidgetLayoutProp(WT_MenuBarItem, MenuBarItem::Margin, 3);
00154     setWidgetLayoutProp(WT_MenuBarItem, MenuBarItem::Margin+Left, 5);
00155     setWidgetLayoutProp(WT_MenuBarItem, MenuBarItem::Margin+Right, 5);
00156 
00157     setWidgetLayoutProp(WT_MenuItem, MenuItem::CheckAlongsideIcon, 1);
00158     setWidgetLayoutProp(WT_MenuItem, MenuItem::CheckWidth, 16);
00159     setWidgetLayoutProp(WT_MenuItem, MenuItem::MinHeight,  20);
00160 
00161     setWidgetLayoutProp(WT_ProgressBar, ProgressBar::BusyIndicatorSize, 10);
00162     setWidgetLayoutProp(WT_ProgressBar, ProgressBar::GrooveMargin, 2);
00163 
00164     setWidgetLayoutProp(WT_TabBar, TabBar::TabOverlap, 0);
00165     setWidgetLayoutProp(WT_TabBar, TabBar::BaseOverlap, 7);
00166     setWidgetLayoutProp(WT_TabBar, TabBar::TabContentsMargin, 4);
00167     setWidgetLayoutProp(WT_TabBar, TabBar::TabFocusMargin, 0);
00168     setWidgetLayoutProp(WT_TabBar, TabBar::TabContentsMargin + Left, 5);
00169     setWidgetLayoutProp(WT_TabBar, TabBar::TabContentsMargin + Right, 5);
00170     setWidgetLayoutProp(WT_TabBar, TabBar::TabContentsMargin + Top, 2);
00171     setWidgetLayoutProp(WT_TabBar, TabBar::TabContentsMargin + Bot, 4);
00172     setWidgetLayoutProp(WT_TabBar, TabBar::ScrollButtonWidth, 18);
00173 
00174     setWidgetLayoutProp(WT_TabWidget, TabWidget::ContentsMargin, 4);
00175 
00176     setWidgetLayoutProp(WT_Slider, Slider::HandleThickness, 25);
00177     setWidgetLayoutProp(WT_Slider, Slider::HandleLength, 19);
00178 
00179     setWidgetLayoutProp(WT_SpinBox, SpinBox::FrameWidth, 6);
00180     setWidgetLayoutProp(WT_SpinBox, SpinBox::ContentsMargin + Left, 3);
00181     setWidgetLayoutProp(WT_SpinBox, SpinBox::ContentsMargin + Top, -2);
00182     setWidgetLayoutProp(WT_SpinBox, SpinBox::ContentsMargin + Bot, -1);
00183     setWidgetLayoutProp(WT_SpinBox, SpinBox::ButtonWidth, 19);
00184     setWidgetLayoutProp(WT_SpinBox, SpinBox::ButtonSpacing, 0);
00185     setWidgetLayoutProp(WT_SpinBox, SpinBox::ButtonMargin+Left, 2);
00186     setWidgetLayoutProp(WT_SpinBox, SpinBox::ButtonMargin+Right, 8);
00187     setWidgetLayoutProp(WT_SpinBox, SpinBox::ButtonMargin+Top, 5);
00188     setWidgetLayoutProp(WT_SpinBox, SpinBox::ButtonMargin+Bot, 4);
00189 
00190     setWidgetLayoutProp(WT_ComboBox, ComboBox::FrameWidth, 6);
00191     setWidgetLayoutProp(WT_ComboBox, ComboBox::ContentsMargin + Left, 3);
00192     setWidgetLayoutProp(WT_ComboBox, ComboBox::ContentsMargin + Top, -1);
00193     setWidgetLayoutProp(WT_ComboBox, ComboBox::ContentsMargin + Bot, -1);
00194     setWidgetLayoutProp(WT_ComboBox, ComboBox::ButtonWidth, 19);
00195     setWidgetLayoutProp(WT_ComboBox, ComboBox::ButtonMargin, 0);
00196     setWidgetLayoutProp(WT_ComboBox, ComboBox::ButtonMargin+Left, 2);
00197     setWidgetLayoutProp(WT_ComboBox, ComboBox::ButtonMargin+Right, 9);
00198     setWidgetLayoutProp(WT_ComboBox, ComboBox::ButtonMargin+Top, 6);
00199     setWidgetLayoutProp(WT_ComboBox, ComboBox::ButtonMargin+Bot, 3);
00200     setWidgetLayoutProp(WT_ComboBox, ComboBox::FocusMargin, 0);
00201 
00202     setWidgetLayoutProp(WT_ToolBar, ToolBar::FrameWidth, 0);
00203     setWidgetLayoutProp(WT_ToolBar, ToolBar::ItemSpacing, 1);
00204     setWidgetLayoutProp(WT_ToolBar, ToolBar::ItemMargin, 2);
00205 
00206     setWidgetLayoutProp(WT_ToolButton, ToolButton::ContentsMargin, 4);
00207     setWidgetLayoutProp(WT_ToolButton, ToolButton::FocusMargin,    0);
00208     setWidgetLayoutProp(WT_ToolButton, ToolButton::InlineMenuIndicatorSize, 8);
00209     setWidgetLayoutProp(WT_ToolButton, ToolButton::InlineMenuIndicatorXOff, -11);
00210     setWidgetLayoutProp(WT_ToolButton, ToolButton::InlineMenuIndicatorYOff, -10);
00211 
00212     setWidgetLayoutProp(WT_GroupBox, GroupBox::FrameWidth, 5);
00213     setWidgetLayoutProp(WT_GroupBox, GroupBox::TitleTextColor, ColorMode(QPalette::WindowText));
00214 
00215     setWidgetLayoutProp(WT_ToolBoxTab, ToolBoxTab::Margin, 5);
00216 
00217     setWidgetLayoutProp(WT_Window, Window::TitleTextColor, QPalette::WindowText);
00218 
00219     KConfigGroup cfg(_config, "Style");
00220     switch (cfg.readEntry("MenuHighlight", (int)MM_DARK)) {
00221         case MM_STRONG:
00222             _menuHighlightMode = MM_STRONG;
00223             break;
00224         case MM_SUBTLE:
00225             _menuHighlightMode = MM_SUBTLE;
00226             break;
00227         default:
00228             _menuHighlightMode = MM_DARK;
00229     }
00230     _checkCheck = (cfg.readEntry("CheckStyle", 0) == 0);
00231     _animateProgressBar = cfg.readEntry("AnimateProgressBar", false);
00232     _drawToolBarItemSeparator = cfg.readEntry("DrawToolBarItemSeparator", true);
00233     _drawTriangularExpander = cfg.readEntry("DrawTriangularExpander", false);
00234 
00235     if ( _animateProgressBar )
00236     {
00237         animationTimer = new QTimer( this );
00238         connect( animationTimer, SIGNAL(timeout()), this, SLOT(updateProgressPos()) );
00239     }
00240 
00241 }
00242 
00243 
00244 void OxygenStyle::updateProgressPos()
00245 {
00246     QProgressBar* pb;
00247     //Update the registered progressbars.
00248     QMap<QWidget*, int>::iterator iter;
00249     bool visible = false;
00250     for (iter = progAnimWidgets.begin(); iter != progAnimWidgets.end(); ++iter)
00251     {
00252         pb = dynamic_cast<QProgressBar*>(iter.key());
00253 
00254         if ( !pb )
00255             continue;
00256 
00257         if ( iter.key() -> isEnabled() &&
00258              pb->value() != pb->maximum() )
00259         {
00260             // update animation Offset of the current Widget
00261             //iter.value() = (iter.value() + 1) % 32;
00262             // dont' update right now      iter.key()->update();
00263         }
00264         if (iter.key()->isVisible())
00265             visible = true;
00266     }
00267     if (!visible)
00268         animationTimer->stop();
00269 }
00270 
00271 
00272 OxygenStyle::~OxygenStyle()
00273 {
00274 }
00275 void OxygenStyle::drawComplexControl(ComplexControl control,const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget) const
00276 {
00277     switch (control)
00278     {
00279         case CC_GroupBox:
00280         {
00281             if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(option))
00282             {
00283                 bool isFlat = groupBox->features & QStyleOptionFrameV2::Flat;
00284 
00285                 if (isFlat)
00286                 {
00287                     QFont font = painter->font();
00288                     font.setBold(true);
00289                     painter->setFont(font);
00290                 }
00291             }
00292         }
00293         break;
00294         default:
00295             break;
00296     }
00297 
00298     return KStyle::drawComplexControl(control,option,painter,widget);
00299 }
00300 
00301 void OxygenStyle::drawControl(ControlElement element, const QStyleOption *option, QPainter *p, const QWidget *widget) const
00302 {
00303     switch (element)
00304     {
00305         case CE_RubberBand:
00306         {
00307             if (const QStyleOptionRubberBand *rbOpt = qstyleoption_cast<const QStyleOptionRubberBand *>(option))
00308             {
00309                 p->save();
00310                 QColor color = rbOpt->palette.color(QPalette::Highlight);
00311                 color.setAlpha(50);
00312                 p->setBrush(color);
00313                 color = KColorUtils::mix(color, rbOpt->palette.color(QPalette::Active, QPalette::WindowText));
00314                 p->setPen(color);
00315                 p->setClipRegion(rbOpt->rect);
00316                 p->drawRect(rbOpt->rect.adjusted(0,0,-1,-1));
00317                 p->restore();
00318             }
00319             break;
00320         }
00321         default:
00322             KStyle::drawControl(element, option, p, widget);
00323     }
00324 }
00325 
00326 void OxygenStyle::drawKStylePrimitive(WidgetType widgetType, int primitive,
00327                                        const QStyleOption* opt,
00328                                        const QRect &r, const QPalette &pal,
00329                                        State flags, QPainter* p,
00330                                        const QWidget* widget,
00331                                        KStyle::Option* kOpt) const
00332 {
00333     StyleOptions opts = 0;
00334     const bool reverseLayout = opt->direction == Qt::RightToLeft;
00335 
00336     const bool enabled = flags & State_Enabled;
00337     const bool mouseOver(enabled && (flags & State_MouseOver));
00338 
00339     switch (widgetType)
00340     {
00341         case WT_PushButton:
00342         {
00343             switch (primitive)
00344             {
00345                 case PushButton::Panel:
00346                 {
00347                     if ((flags & State_On) || (flags & State_Sunken))
00348                         opts |= Sunken;
00349                     if (flags & State_HasFocus)
00350                         opts |= Focus;
00351                     if (enabled && (flags & State_MouseOver))
00352                         opts |= Hover;
00353 
00354                     renderSlab(p, r, pal.color(QPalette::Button), opts);
00355                     return;
00356                 }
00357 
00358                 case PushButton::DefaultButtonFrame:
00359                 {
00360                     return;
00361                 }
00362             }
00363         }
00364         break;
00365 
00366         case WT_ToolBoxTab:
00367         {
00368             switch (primitive)
00369             {
00370                 case ToolBoxTab::Panel:
00371                 {
00372                     const QStyleOptionToolBox *option = qstyleoption_cast<const QStyleOptionToolBox *>(opt);
00373                     if(!(option && widget)) return;
00374 
00375                     const QStyleOptionToolBoxV2 *v2 = qstyleoption_cast<const QStyleOptionToolBoxV2 *>(opt);
00376 
00377                     p->save();
00378                     if (v2 && v2->position == QStyleOptionToolBoxV2::Beginning)
00379                     {
00380                         p->restore();
00381                         return;
00382                     }
00383 
00384                     QColor color = widget->palette().color(QPalette::Window); // option returns a wrong color
00385                     QColor light = _helper.calcLightColor(color);
00386                     QColor dark = _helper.calcDarkColor(color);
00387 
00388                     QPainterPath path;
00389                     int y = r.height()*15/100;
00390                     if (reverseLayout) {
00391                         path.moveTo(r.left()+52, r.top());
00392                         path.cubicTo(QPointF(r.left()+50-8, r.top()), QPointF(r.left()+50-10, r.top()+y), QPointF(r.left()+50-10, r.top()+y));
00393                         path.lineTo(r.left()+18+9, r.bottom()-y);
00394                         path.cubicTo(QPointF(r.left()+18+9, r.bottom()-y), QPointF(r.left()+19+6, r.bottom()-1-0.3), QPointF(r.left()+19, r.bottom()-1-0.3));
00395                     } else {
00396                         path.moveTo(r.right()-52, r.top());
00397                         path.cubicTo(QPointF(r.right()-50+8, r.top()), QPointF(r.right()-50+10, r.top()+y), QPointF(r.right()-50+10, r.top()+y));
00398                         path.lineTo(r.right()-18-9, r.bottom()-y);
00399                         path.cubicTo(QPointF(r.right()-18-9, r.bottom()-y), QPointF(r.right()-19-6, r.bottom()-1-0.3), QPointF(r.right()-19, r.bottom()-1-0.3));
00400                     }
00401 
00402                     p->setRenderHint(QPainter::Antialiasing, true);
00403                     p->translate(0,1);
00404                     p->setPen(light);
00405                     p->drawPath(path);
00406                     p->translate(0,-1);
00407                     p->setPen(dark);
00408                     p->drawPath(path);
00409 
00410                     p->setRenderHint(QPainter::Antialiasing, false);
00411                     if (reverseLayout) {
00412                         p->drawLine(r.left()+50-1, r.top(), r.right(), r.top());
00413                         p->drawLine(r.left()+20, r.bottom()-2, r.left(), r.bottom()-2);
00414                         p->setPen(light);
00415                         p->drawLine(r.left()+50, r.top()+1, r.right(), r.top()+1);
00416                         p->drawLine(r.left()+20, r.bottom()-1, r.left(), r.bottom()-1);
00417                     } else {
00418                         p->drawLine(r.left(), r.top(), r.right()-50+1, r.top());
00419                         p->drawLine(r.right()-20, r.bottom()-2, r.right(), r.bottom()-2);
00420                         p->setPen(light);
00421                         p->drawLine(r.left(), r.top()+1, r.right()-50, r.top()+1);
00422                         p->drawLine(r.right()-20, r.bottom()-1, r.right(), r.bottom()-1);
00423                     }
00424 
00425                     p->restore();
00426                     return;
00427                 }
00428             }
00429         }
00430         break;
00431 
00432         case WT_ProgressBar:
00433         {
00434 //             const Q3ProgressBar *pb = dynamic_cast<const Q3ProgressBar*>(widget);
00435 //             int steps = pb->totalSteps();
00436 
00437             QColor bg = enabled?pal.color(QPalette::Base):pal.color(QPalette::Background); // background
00438             QColor fg = enabled?pal.color(QPalette::Highlight):pal.color(QPalette::Background).dark(110); // foreground
00439             const QStyleOptionProgressBarV2 *pbOpt = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(opt);
00440             Qt::Orientation orientation = pbOpt? pbOpt->orientation : Qt::Horizontal;
00441 
00442             // we want small (16px) and centered progressbars
00443             QRect rect = r;
00444             /*if (orientation == Qt::Horizontal) {
00445                 if (r.height() > 17)
00446                     rect = QRect(r.x(), r.y() + (r.height()-17)/2, r.width(), 18);
00447             } else {
00448                 if (r.width() > 17)
00449                     rect = QRect(r.x() + (r.width()-17)/2, r.y(), 18, r.height());
00450             }*/
00451 
00452             switch (primitive)
00453             {
00454                 case ProgressBar::Groove:
00455                 {
00456                     QColor color = pal.color(QPalette::Window);
00457 
00458                     TileSet *tiles1 = _helper.progressBar(color, rect, orientation);
00459                     if (orientation == Qt::Horizontal)
00460                         tiles1->render(rect, p, TileSet::Left | TileSet::Vertical | TileSet::Right);
00461                     else
00462                         tiles1->render(rect, p, TileSet::Top | TileSet::Horizontal | TileSet::Bottom);
00463 
00464                     return;
00465                 }
00466 
00467                 case ProgressBar::BusyIndicator:
00468                 case ProgressBar::Indicator:
00469                 {
00470                     rect.adjust(-2,-2,2,2);
00471 
00472                     QColor color = pal.color(QPalette::Active, QPalette::Highlight);
00473 
00474                     if (rect.width() > 3) // doesn't look too good in a very small rect
00475                     {
00476                         // TODO: make kstyle make vertical progress bar grow from bottom to top
00477                         TileSet *tiles1 = _helper.progressBar(_helper.alphaColor(color,0.8), rect, orientation);
00478 
00479                         QPixmap pm(rect.width(),rect.height());
00480                         pm.fill(Qt::transparent);
00481                         QPainter pp(&pm);
00482                         pp.setRenderHints(QPainter::Antialiasing);
00483 
00484                         QLinearGradient lg(rect.topLeft(),rect.topRight());
00485                         lg.setColorAt(0.0, _helper.alphaColor(color,0.8));
00486                         lg.setColorAt(1.0, color);
00487                         pp.setPen(Qt::NoPen);
00488                         pp.setBrush(lg);
00489                         pp.drawRoundedRect(pm.rect().adjusted(2,2,-2,-3),3,3);
00490                         // only draw the inner part of the scrollbar
00491                         pp.setCompositionMode(QPainter::CompositionMode_SourceAtop);
00492 
00493                         if (orientation == Qt::Horizontal)
00494                             tiles1->render(pm.rect(), &pp, TileSet::Horizontal);
00495                         else
00496                             tiles1->render(pm.rect(), &pp, TileSet::Vertical);
00497 
00498                         pp.end();
00499                         p->drawPixmap(rect.topLeft(),pm);
00500                     }
00501                     return;
00502                 }
00503             }
00504         }
00505         break;
00506 
00507         case WT_MenuBar:
00508         {
00509             switch (primitive)
00510             {
00511                 case MenuBar::EmptyArea:
00512                 {
00513                     return;
00514                 }
00515             }
00516         }
00517         break;
00518 
00519         case WT_MenuBarItem:
00520         {
00521             switch (primitive)
00522             {
00523                 case MenuBarItem::Panel:
00524                 {
00525                     bool active  = flags & State_Selected;
00526 
00527                     if (active) {
00528                         QColor color = pal.color(QPalette::Window);
00529                         if (_menuHighlightMode != MM_DARK) {
00530                             if(flags & State_Sunken) {
00531                                 if (_menuHighlightMode == MM_STRONG)
00532                                     color = pal.color(QPalette::Highlight);
00533                                 else
00534                                     color = KColorUtils::mix(color, KColorUtils::tint(color, pal.color(QPalette::Highlight), 0.6));
00535                             }
00536                             else {
00537                                 if (_menuHighlightMode == MM_STRONG)
00538                                     color = KColorUtils::tint(color, _viewHoverBrush.brush(pal).color());
00539                                 else
00540                                     color = KColorUtils::mix(color, KColorUtils::tint(color, _viewHoverBrush.brush(pal).color()));
00541                             }
00542                         }
00543                         else {
00544                             color = _helper.calcMidColor(color);
00545                         }
00546 
00547                         _helper.holeFlat(color, 0.0)->render(r.adjusted(2,2,-2,-2), p, TileSet::Full);
00548                     }
00549 
00550                     return;
00551                 }
00552 
00553                 case Generic::Text:
00554                 {
00555                     KStyle::TextOption* textOpts = extractOption<KStyle::TextOption*>(kOpt);
00556 
00557                     QPen   old = p->pen();
00558                     if (_menuHighlightMode == MM_STRONG && flags & State_Sunken)
00559                         p->setPen(pal.color(QPalette::HighlightedText));
00560                     else
00561                         p->setPen(pal.color(QPalette::WindowText));
00562                     drawItemText(p, r, Qt::AlignVCenter | Qt::TextShowMnemonic | textOpts->hAlign, pal, flags & State_Enabled,
00563                                  textOpts->text);
00564                     p->setPen(old);
00565 
00566                     return;
00567                 }
00568             }
00569         }
00570         break;
00571 
00572         case WT_Menu:
00573         {
00574             switch (primitive)
00575             {
00576                 case Generic::Frame:
00577                 {
00578                     _helper.drawFloatFrame(p, r, pal.window().color());
00579                     return;
00580                 }
00581 
00582                 case Menu::Background:
00583                 {
00584                     // we paint in the eventFilter instead so we can paint in the border too
00585                     return;
00586                 }
00587 
00588                 case Menu::TearOff:
00589                 {
00590                     // TODO: See Keramik...
00591 
00592                     return;
00593                 }
00594 
00595                 case Menu::Scroller:
00596                 {
00597                     // TODO
00598                     return;
00599                 }
00600             }
00601         }
00602         break;
00603 
00604         case WT_MenuItem:
00605         {
00606             switch (primitive)
00607             {
00608                 case MenuItem::Separator:
00609                 {
00610                     renderSeparator(p,r,pal,Qt::Horizontal);
00611                     return;
00612                 }
00613 
00614                 case MenuItem::ItemIndicator:
00615                 {
00616                     if (enabled) {
00617                         QPixmap pm(r.size());
00618                         pm.fill(Qt::transparent);
00619                         QPainter pp(&pm);
00620                         QRect rr(QPoint(0,0), r.size());
00621 
00622                         QColor color = pal.color(QPalette::Window);
00623                         if (_menuHighlightMode == MM_STRONG)
00624                             color = pal.color(QPalette::Highlight);
00625                         else if (_menuHighlightMode == MM_SUBTLE)
00626                             color = KColorUtils::mix(color, KColorUtils::tint(color, pal.color(QPalette::Highlight), 0.6));
00627                         else
00628                             color = _helper.calcMidColor(color);
00629                         pp.setRenderHint(QPainter::Antialiasing);
00630                         pp.setPen(Qt::NoPen);
00631 
00632                         pp.setBrush(color);
00633                         _helper.fillHole(pp, rr);
00634 
00635                         _helper.holeFlat(color, 0.0)->render(rr.adjusted(2,2,-2,-2), &pp);
00636 
00637                         QRect maskr( visualRect(opt->direction, rr, QRect(rr.width()-40, 0, 40,rr.height())) );
00638                         QLinearGradient gradient(
00639                                 visualPos(opt->direction, maskr, QPoint(maskr.left(), 0)),
00640                                 visualPos(opt->direction, maskr, QPoint(maskr.right()-4, 0)));
00641                         gradient.setColorAt(0.0, QColor(0,0,0,255));
00642                         gradient.setColorAt(1.0, QColor(0,0,0,0));
00643                         pp.setBrush(gradient);
00644                         pp.setCompositionMode(QPainter::CompositionMode_DestinationIn);
00645                         pp.drawRect(maskr);
00646 
00647                         p->drawPixmap(handleRTL(opt, r), pm);
00648                     }
00649                     else {
00650                         drawKStylePrimitive(WT_Generic, Generic::FocusIndicator, opt, r, pal, flags, p, widget, kOpt);
00651                     }
00652 
00653                     return;
00654                 }
00655 
00656                 case Generic::Text:
00657                 {
00658                     KStyle::TextOption* textOpts = extractOption<KStyle::TextOption*>(kOpt);
00659 
00660                     QPen   old = p->pen();
00661                     if (_menuHighlightMode == MM_STRONG && flags & State_Selected)
00662                         p->setPen(pal.color(QPalette::HighlightedText));
00663                     else
00664                         p->setPen(pal.color(QPalette::WindowText));
00665                     drawItemText(p, r, Qt::AlignVCenter | Qt::TextShowMnemonic | textOpts->hAlign, pal, flags & State_Enabled,
00666                                  textOpts->text);
00667                     p->setPen(old);
00668 
00669                     return;
00670                 }
00671 
00672                 case Generic::ArrowRight:
00673                 case Generic::ArrowLeft:
00674                 {
00675                     // always draw in window text color due to fade-out
00676                     extractOption<KStyle::ColorOption*>(kOpt)->color = QPalette::WindowText;
00677                     // fall through to lower handler
00678                     break;
00679                 }
00680 
00681                 case MenuItem::CheckColumn:
00682                 {
00683                     // empty
00684                     return;
00685                 }
00686 
00687                 case MenuItem::CheckOn:
00688                 {
00689                     renderCheckBox(p, r.adjusted(2,-2,2,2), pal, enabled, false, mouseOver, CheckBox::CheckOn, true);
00690                     return;
00691                 }
00692 
00693                 case MenuItem::CheckOff:
00694                 {
00695                     renderCheckBox(p, r.adjusted(2,-2,2,2), pal, enabled, false, mouseOver, CheckBox::CheckOff, true);
00696                     return;
00697                 }
00698 
00699                 case MenuItem::RadioOn:
00700                 {
00701                     renderRadioButton(p, r, pal, enabled, false, mouseOver, RadioButton::RadioOn, true);
00702                     return;
00703                 }
00704 
00705                 case MenuItem::RadioOff:
00706                 {
00707                     renderRadioButton(p, r, pal, enabled, false, mouseOver, RadioButton::RadioOff, true);
00708                     return;
00709                 }
00710 
00711                 case MenuItem::CheckIcon:
00712                 {
00713                     // TODO
00714                     return;
00715                 }
00716 
00717                 case Generic::Icon:
00718                 {
00719                     p->save();
00720                     KStyle::IconOption* iconOpts = extractOption<KStyle::IconOption*>(kOpt);
00721                     QSize size = iconOpts->size;
00722                     if(!size.isValid()) {
00723                         size = QSize(pixelMetric(PM_SmallIconSize, opt, widget),
00724                                      pixelMetric(PM_SmallIconSize, opt, widget));
00725                     }
00726                     QImage icon;
00727                     if (flags & State_Enabled) {
00728                         if (iconOpts->active) {
00729                             icon = iconOpts->icon.pixmap(size, QIcon::Active).toImage();
00730                         } else {
00731                             icon = iconOpts->icon.pixmap(size, QIcon::Normal).toImage();
00732                         }
00733                     } else {
00734                         icon = iconOpts->icon.pixmap(size).toImage();
00735                         KIconEffect::deSaturate(icon, 0.8);
00736                         p->setOpacity(0.7);
00737                     }
00738                     p->drawImage(centerRect(r, icon.size()), icon);
00739                     p->restore();
00740                     return;
00741                 }
00742             }
00743         }
00744         break;
00745 
00746         case WT_DockWidget:
00747         {
00748             switch (primitive)
00749             {
00750                 case Generic::Text:
00751                 {
00752                     const QStyleOptionDockWidget* dwOpt = ::qstyleoption_cast<const QStyleOptionDockWidget*>(opt);
00753                     if (!dwOpt) return;
00754                     const QStyleOptionDockWidgetV2 *v2 = qstyleoption_cast<const QStyleOptionDockWidgetV2*>(opt);
00755                     bool verticalTitleBar = v2 ? v2->verticalTitleBar : false;
00756 
00757                     QRect btnr = subElementRect(dwOpt->floatable ? SE_DockWidgetFloatButton : SE_DockWidgetCloseButton, opt, widget);
00758                     int fw = widgetLayoutProp(WT_DockWidget, DockWidget::TitleMargin, opt, widget);
00759                     QRect r = dwOpt->rect.adjusted(fw, fw, -fw, -fw);
00760                     if (verticalTitleBar)
00761                         r.setY(btnr.y()+btnr.height());
00762                     else if(reverseLayout)
00763                     {
00764                         r.setLeft(btnr.x()+btnr.width());
00765                         r.adjust(0,0,-4,0);
00766                     }
00767                     else
00768                     {
00769                         r.setRight(btnr.x());
00770                         r.adjust(4,0,0,0);
00771                     }
00772 
00773                     QString title = dwOpt->title;
00774                     QString tmpTitle = title;
00775                     if(tmpTitle.contains("&"))
00776                     {
00777                         int pos = tmpTitle.indexOf("&");
00778                         if(!(tmpTitle.size()-1 > pos && tmpTitle.at(pos+1) == QChar('&')))
00779                             tmpTitle.remove(pos, 1);
00780                     }
00781                     int tw = dwOpt->fontMetrics.width(tmpTitle);
00782                     int th = dwOpt->fontMetrics.height();
00783                     int width = verticalTitleBar ? r.height() : r.width();
00784                     if (width < tw)
00785                         title = dwOpt->fontMetrics.elidedText(title, Qt::ElideRight, width, Qt::TextShowMnemonic);
00786 
00787                     if (verticalTitleBar)
00788                     {
00789                         QRect br(dwOpt->fontMetrics.boundingRect(title));
00790                         QImage textImage(br.size(), QImage::Format_ARGB32_Premultiplied);
00791                         textImage.fill(0x00000000);
00792                         QPainter painter(&textImage);
00793                         drawItemText(&painter, QRect(0, 0, br.width(), br.height()), Qt::AlignLeft|Qt::AlignTop|Qt::TextShowMnemonic, dwOpt->palette, dwOpt->state & State_Enabled, title, QPalette::WindowText);
00794                         painter.end();
00795                         textImage = textImage.transformed(QMatrix().rotate(-90));
00796 
00797                         p->drawPixmap(r.x()+(r.width()-th)/2, r.y()+r.height()-textImage.height(), QPixmap::fromImage(textImage));
00798                     }
00799                     else
00800                     {
00801                         drawItemText(p, r, (reverseLayout ? Qt::AlignRight : Qt::AlignLeft) | Qt::AlignVCenter
00802                         | Qt::TextShowMnemonic, dwOpt->palette, dwOpt->state & State_Enabled, title,
00803                         QPalette::WindowText);
00804                     }
00805                     return;
00806                 }
00807                 case Generic::Frame:
00808                 {
00809                     // Don't do anything here as it interferes with custom titlewidgets
00810                     return;
00811                 }
00812 
00813                 case DockWidget::TitlePanel:
00814                 {
00815                     // The frame is draw in the eventfilter
00816                     // This is because when a dockwidget has a titlebarwidget, then we can not
00817                     //  paint on the dockwidget prober here
00818                     return;
00819                 }
00820 
00821                 case DockWidget::SeparatorHandle:
00822                     if (flags&State_Horizontal)
00823                         drawKStylePrimitive(WT_Splitter, Splitter::HandleVert, opt, r, pal, flags, p, widget);
00824                     else
00825                         drawKStylePrimitive(WT_Splitter, Splitter::HandleHor, opt, r, pal, flags, p, widget);
00826                     return;
00827             }
00828         }
00829         break;
00830 
00831         case WT_StatusBar:
00832         {
00833             switch (primitive)
00834             {
00835                 case Generic::Frame:
00836                 {
00837                     return;
00838                 }
00839             }
00840         }
00841         break;
00842 
00843         case WT_CheckBox:
00844         {
00845             switch(primitive)
00846             {
00847                 case CheckBox::CheckOn:
00848                 case CheckBox::CheckOff:
00849                 case CheckBox::CheckTriState:
00850                 {
00851                     bool hasFocus = flags & State_HasFocus;
00852 
00853                     renderCheckBox(p, r, pal, enabled, hasFocus, mouseOver, primitive);
00854                     return;
00855                 }
00856                 case Generic::Text:
00857                 {
00858                     KStyle::TextOption* textOpts = extractOption<KStyle::TextOption*>(kOpt);
00859 
00860                     QPen old = p->pen();
00861                     p->setPen(pal.color(QPalette::WindowText));
00862                     drawItemText(p, r, Qt::AlignVCenter | Qt::TextShowMnemonic | textOpts->hAlign, pal, flags & State_Enabled,
00863                                  textOpts->text);
00864                     p->setPen(old);
00865                     return;
00866                 }
00867             }
00868         }
00869         break;
00870 
00871         case WT_RadioButton:
00872         {
00873             switch(primitive)
00874             {
00875                 case RadioButton::RadioOn:
00876                 case RadioButton::RadioOff:
00877                 {
00878                     bool hasFocus = flags & State_HasFocus;
00879 
00880                     renderRadioButton(p, r, pal, enabled, hasFocus, mouseOver, primitive);
00881                     return;
00882                 }
00883             }
00884 
00885         }
00886         break;
00887 
00888         case WT_ScrollBar:
00889         {
00890             switch (primitive)
00891             {
00892                 case ScrollBar::DoubleButtonHor:
00893                     if (reverseLayout)
00894                         renderHole(p, pal.color(QPalette::Window), QRect(r.right()+1, 0, 5, r.height()),
00895                                    false, false, TileSet::Top | TileSet::Bottom | TileSet::Left);
00896                     else
00897                         renderHole(p, pal.color(QPalette::Window), QRect(r.left()-5, 0, 5, r.height()),
00898                                    false, false, TileSet::Top | TileSet::Right | TileSet::Bottom);
00899                     break;
00900 
00901                 case ScrollBar::DoubleButtonVert:
00902                     renderHole(p, pal.color(QPalette::Window), QRect(0, r.top()-5, r.width(), 5),
00903                                false, false, TileSet::Left | TileSet::Bottom | TileSet::Right);
00904                     break;
00905 
00906                 case ScrollBar::SingleButtonHor:
00907                     if (reverseLayout)
00908                         renderHole(p, pal.color(QPalette::Window), QRect(r.left()-7, 0, 5, r.height()),
00909                                    false, false, TileSet::Top | TileSet::Right | TileSet::Bottom);
00910                     else
00911                         renderHole(p, pal.color(QPalette::Window), QRect(r.right()+3, 0, 5, r.height()),
00912                                    false, false, TileSet::Top | TileSet::Left | TileSet::Bottom);
00913                     break;
00914 
00915                 case ScrollBar::SingleButtonVert:
00916                     renderHole(p, pal.color(QPalette::Window), QRect(0, r.bottom()+3, r.width(), 5),
00917                                false, false, TileSet::Top | TileSet::Left | TileSet::Right);
00918                     break;
00919 
00920                 case ScrollBar::GrooveAreaVertTop:
00921                 {
00922                     renderHole(p, pal.color(QPalette::Window), r.adjusted(0,2,0,12),
00923                                false, false, TileSet::Left | TileSet::Right);
00924                     return;
00925                 }
00926 
00927                 case ScrollBar::GrooveAreaVertBottom:
00928                 {
00929                     renderHole(p, pal.color(QPalette::Window), r.adjusted(0,-10,0,0), false, false,
00930                                TileSet::Left | TileSet::Right);
00931                     return;
00932                 }
00933 
00934                 case ScrollBar::GrooveAreaHorLeft:
00935                 {
00936                     QRect rect = (reverseLayout) ? r.adjusted(0,0,10,0) : r.adjusted(2,0,12,0);
00937                     renderHole(p, pal.color(QPalette::Window), rect, false, false,
00938                                TileSet::Top | TileSet::Bottom);
00939                     return;
00940                 }
00941 
00942                 case ScrollBar::GrooveAreaHorRight:
00943                 {
00944                     QRect rect = (reverseLayout) ? r.adjusted(-12,0,-2,0) : r.adjusted(-10,0,0,0);
00945                     renderHole(p, pal.color(QPalette::Window), rect, false, false,
00946                                TileSet::Top | TileSet::Bottom);
00947                     return;
00948                 }
00949 
00950                 case ScrollBar::SliderVert:
00951                 {
00952                     QColor color = pal.color(QPalette::Button);
00953                     if (mouseOver || (flags & State_Sunken)) // TODO not when disabled ((flags & State_Enabled) doesn't work?)
00954                         color = _viewHoverBrush.brush(pal).color();
00955                     QRect rect = r.adjusted(1,3,-1,0);
00956 
00957                     renderHole(p, pal.color(QPalette::Window), rect.adjusted(-1,-1,1,0), false, false,
00958                                TileSet::Left | TileSet::Right);
00959 
00960                     int offset = rect.top()/2; // divide by 2 to make the "lightplay" move half speed of the handle
00961                     int remainder = qMin(12, rect.height()/2);
00962 
00963                     // Draw the handle in two parts, the top, and the bottom with calculated offset
00964                     TileSet *tiles1 = _helper.verticalScrollBar(color, rect.width(), offset);
00965                     TileSet *tiles2 = _helper.verticalScrollBar(color, rect.width(), offset+rect.height()+8);
00966 
00967                     p->save();
00968                     p->setClipRect(rect.adjusted(0,0,0,-remainder-1));
00969                     tiles1->render(rect, p, TileSet::Top | TileSet::Horizontal);
00970                     p->setClipRect( QRect(rect.left(), rect.bottom()-remainder, rect.width(), remainder));
00971                     tiles2->render( QRect(rect.left(), rect.bottom()-32, rect.width(),32),
00972                                     p, TileSet::Bottom | TileSet::Horizontal);
00973                     p->restore();
00974                     return;
00975                 }
00976 
00977                 case ScrollBar::SliderHor:
00978                 {
00979                     QColor color = pal.color(QPalette::Button);
00980                     if (mouseOver || (flags & State_Sunken)) // TODO not when disabled ((flags & State_Enabled) doesn't work?)
00981                         color = _viewHoverBrush.brush(pal).color();
00982                     QRect rect = (reverseLayout) ? r.adjusted(1,1,-2,-1) : r.adjusted(3,1,0,-1);
00983 
00984                     renderHole(p, pal.color(QPalette::Window), rect.adjusted(-1,-1,0,1), false, false,
00985                                TileSet::Top | TileSet::Bottom);
00986 
00987                     int offset = r.left()/2; // divide by 2 to make the "lightplay" move half speed of the handle
00988                     int remainder = qMin(12, rect.width()/2);
00989 
00990                     // Draw the handle in two parts, the top, and the bottom with calculated offset
00991                     TileSet *tiles1 = _helper.horizontalScrollBar(color, rect.height(), offset);
00992                     TileSet *tiles2 = _helper.horizontalScrollBar(color, rect.height(), offset+rect.width()+8);
00993 
00994                     p->save();
00995                     p->setClipRect(rect.adjusted(0,0,-remainder-1,0));
00996                     tiles1->render(rect, p, TileSet::Left | TileSet::Vertical);
00997                     p->setClipRect( QRect(rect.right()-remainder, rect.top(), remainder, rect.height()) );
00998                     tiles2->render( QRect(rect.right()-32, rect.top(), 32, rect.height()),
00999                                     p, TileSet::Right | TileSet::Vertical);
01000                     p->restore();
01001                     return;
01002                 }
01003 
01004             }
01005 
01006         }
01007         break;
01008 
01009         case WT_TabBar:
01010         {
01011             const QStyleOptionTabV2* tabOpt = qstyleoption_cast<const QStyleOptionTabV2*>(opt);
01012 
01013             switch (primitive)
01014             {
01015                 case TabBar::NorthTab:
01016                 case TabBar::SouthTab:
01017                 case TabBar::WestTab:
01018                 case TabBar::EastTab:
01019                 {
01020                     if (!tabOpt) break;
01021 
01022                     renderTab(p, r, pal, mouseOver, flags&State_Selected, tabOpt, reverseLayout);
01023 
01024                     return;
01025                 }
01026                 case TabBar::WestText:
01027                 case TabBar::EastText:
01028                 {
01029                     QImage img(r.height(), r.width(), QImage::Format_ARGB32_Premultiplied);
01030                     img.fill(0x00000000);
01031                     QPainter painter(&img);
01032                     drawItemText(&painter, img.rect(), (reverseLayout ? Qt::AlignRight : Qt::AlignLeft) | Qt::AlignVCenter | Qt::TextShowMnemonic, tabOpt->palette, tabOpt->state & State_Enabled, tabOpt->text, QPalette::WindowText);
01033                     painter.end();
01034                     img = img.transformed(QMatrix().rotate(primitive == TabBar::WestText ? -90 : 90));
01035                     p->drawImage(r.x(), r.y(), img);
01036                     return;
01037                 }
01038                 case TabBar::IndicatorTear:
01039                 {
01040                     const QStyleOptionTab* option = qstyleoption_cast<const QStyleOptionTab*>(opt);
01041                     if(!option) return;
01042 
01043                     TileSet::Tiles flag;
01044                     QRect rect;
01045                     QRect br = r;
01046                     bool vertical = false;
01047                     QPainter::CompositionMode slabCompMode = QPainter::CompositionMode_Source;
01048 
01049                     switch(option->shape) {
01050                     case QTabBar::RoundedNorth:
01051                     case QTabBar::TriangularNorth:
01052                         if(!option->cornerWidgets & QStyleOptionTab::LeftCornerWidget) {
01053                             flag = reverseLayout ? TileSet::Right : TileSet::Left;
01054                             rect = QRect(r.x(), r.y()+r.height()-4-7, 14+7, 4+14);
01055                         }
01056                         else {
01057                             flag = TileSet::Top;
01058                             rect = QRect(r.x()-7, r.y()+r.height()-7, 14+7, 7);
01059                             slabCompMode = QPainter::CompositionMode_SourceOver;
01060                         }
01061                         rect = visualRect(option->direction, r, rect);
01062                         break;
01063                     case QTabBar::RoundedSouth:
01064                     case QTabBar::TriangularSouth:
01065                         if(!option->cornerWidgets & QStyleOptionTab::LeftCornerWidget) {
01066                             flag = reverseLayout ? TileSet::Right : TileSet::Left;
01067                             rect = QRect(r.x(), r.y()-7, 14+7, 2+14);
01068                         }
01069                         else {
01070                             flag = TileSet::Bottom;
01071                             rect = reverseLayout ? QRect(r.x()-7+4, r.y(), 14+3, 6) : QRect(r.x()-7, r.y()-1, 14+6, 7);
01072                         }
01073                         break;
01074                     case QTabBar::RoundedWest:
01075                     case QTabBar::TriangularWest:
01076                         if(!option->cornerWidgets & QStyleOptionTab::LeftCornerWidget) {
01077                             flag = TileSet::Top;
01078                             rect = QRect(r.x()+r.width()-4-7, r.y(), 4+14, 7);
01079                         }
01080                         else {
01081                             flag = TileSet::Left;
01082                             rect = QRect(r.x()+r.width()-7, r.y()-7, 7, 4+14);
01083                             br.adjust(0,0,-5,0);
01084                         }
01085                         vertical = true;
01086                         break;
01087                     case QTabBar::RoundedEast:
01088                     case QTabBar::TriangularEast:
01089                         if(!option->cornerWidgets & QStyleOptionTab::LeftCornerWidget) {
01090                             flag = TileSet::Top;
01091                             rect = QRect(r.x()-7, r.y(), 4+14, 7);
01092                         }
01093                         else {
01094                             flag = TileSet::Right;
01095                             rect = QRect(r.x(), r.y()-7, 7, 4+14);
01096                             br.adjust(5,0,0,0);
01097                         }
01098                         vertical = true;
01099                         break;
01100                     default:
01101                         return;
01102                     }
01103 
01104                     QRect gr;
01105                     if(!vertical && !reverseLayout)
01106                         gr = QRect(0, 0, r.width(), r.height());
01107                     else if(!vertical && reverseLayout)
01108                         if(!option->cornerWidgets & QStyleOptionTab::LeftCornerWidget)
01109                             gr = QRect(r.x()-4, 0, r.x()-4+r.width(), r.height());
01110                         else
01111                             gr = QRect(r.x(), 0, r.x()+r.width(), r.height());
01112                     else
01113                         gr = QRect(0, 0, r.width(), r.height());
01114 
01115                     // fade tabbar
01116                     QPixmap pm(gr.width(),gr.height());
01117                     pm.fill(Qt::transparent);
01118                     QPainter pp(&pm);
01119 
01120                     int w = 0, h = 0;
01121                     if (vertical) {
01122                         h = gr.height();
01123                     } else {
01124                         w = gr.width();
01125                     }
01126                     QLinearGradient grad(w, h, 0, 0);
01127                     grad.setColorAt(0, Qt::transparent);
01128                     grad.setColorAt(0.2, Qt::transparent);
01129                     grad.setColorAt(1, Qt::black);
01130 
01131                     _helper.renderWindowBackground(&pp, pm.rect(), widget, pal);
01132                     pp.setCompositionMode(QPainter::CompositionMode_DestinationAtop);
01133                     pp.fillRect(pm.rect(), QBrush(grad));
01134                     p->setCompositionMode(QPainter::CompositionMode_SourceOver);
01135                     p->drawPixmap(gr.topLeft(),pm);
01136 
01137                     renderSlab(p, rect, opt->palette.color(QPalette::Window), NoFill, flag);
01138 
01139                     return;
01140                 }
01141                 case TabBar::BaseFrame:
01142                 {
01143                    const QStyleOptionTabBarBase* tabOpt = qstyleoption_cast<const QStyleOptionTabBarBase*>(opt);
01144 
01145                     switch(tabOpt->shape)
01146                     {
01147                         case QTabBar::RoundedNorth:
01148                         case QTabBar::TriangularNorth:
01149                         {
01150 
01151                             if (r.left() < tabOpt->tabBarRect.left())
01152                             {
01153                                 QRect fr = r;
01154                                 fr.setRight(tabOpt->tabBarRect.left());
01155                                 fr.adjust(-7,-gw,7,-1-gw);
01156                                 renderSlab(p, fr, pal.color(QPalette::Window), NoFill, TileSet::Top);
01157                             }
01158                             if (tabOpt->tabBarRect.right() < r.right())
01159                             {
01160                                 QRect fr = r;
01161                                 fr.setLeft(tabOpt->tabBarRect.right());
01162                                 fr.adjust(-7,-gw,7,-1-gw);
01163                                 renderSlab(p, fr, pal.color(QPalette::Window), NoFill, TileSet::Top);
01164                             }
01165                             return;
01166                         }
01167                         case QTabBar::RoundedSouth:
01168                         case QTabBar::TriangularSouth:
01169                         {
01170                             if (r.left() < tabOpt->tabBarRect.left())
01171                             {
01172                                 QRect fr = r;
01173                                 fr.setRight(tabOpt->tabBarRect.left());
01174                                 fr.adjust(-7,gw,7,-1+gw);
01175                                 renderSlab(p, fr, pal.color(QPalette::Window), NoFill, TileSet::Bottom);
01176                             }
01177                             if (tabOpt->tabBarRect.right() < r.right())
01178                             {
01179                                 QRect fr = r;
01180                                 fr.setLeft(tabOpt->tabBarRect.right());
01181                                 fr.adjust(-6,gw,7,-1+gw);
01182                                 renderSlab(p, fr, pal.color(QPalette::Window), NoFill, TileSet::Bottom);
01183                             }
01184                             return;
01185                         }
01186                         default:
01187                             break;
01188                     }
01189                     return;
01190                 }
01191                 case Generic::Text:
01192                 {
01193                     KStyle::TextOption* textOpts = extractOption<KStyle::TextOption*>(kOpt);
01194 
01195                     QPen old = p->pen();
01196                     p->setPen(pal.color(QPalette::WindowText));
01197                     drawItemText(p, r, Qt::AlignVCenter | Qt::TextShowMnemonic | textOpts->hAlign, pal, flags & State_Enabled,
01198                                  textOpts->text);
01199                     p->setPen(old);
01200                     return;
01201                 }
01202             }
01203 
01204         }
01205         break;
01206 
01207         case WT_TabWidget:
01208         {
01209             switch (primitive)
01210             {
01211                 case Generic::Frame:
01212                 {
01213                     const QStyleOptionTabWidgetFrame* tabOpt = qstyleoption_cast<const QStyleOptionTabWidgetFrame*>(opt);
01214                     // FIXME: tabOpt->tabBarSize may be bigger than the tab widget's size
01215                     int w = tabOpt->tabBarSize.width();
01216                     int h = tabOpt->tabBarSize.height();
01217                     int lw = tabOpt->leftCornerWidgetSize.width();
01218                     int lh = tabOpt->leftCornerWidgetSize.height();
01219 
01220                     switch(tabOpt->shape)
01221                     {
01222                         case QTabBar::RoundedNorth:
01223                         case QTabBar::TriangularNorth:
01224                             renderSlab(p, r.adjusted(-gw,-gw,gw,gw), pal.color(QPalette::Window), NoFill,
01225                                        TileSet::Left | TileSet::Bottom | TileSet::Right);
01226                             if(reverseLayout)
01227                             {
01228                                 // Left and right widgets are placed right and left when in reverse mode
01229 
01230                                 if (w+lw >0)
01231                                     renderSlab(p, QRect(-gw, r.y()-gw, r.width() - w - lw+7+gw, 7),
01232                                         pal.color(QPalette::Window), NoFill, TileSet::Left | TileSet::Top);
01233                                 else
01234                                     renderSlab(p, QRect(-gw, r.y()-gw, r.width()+2*gw, 7), pal.color(QPalette::Window), NoFill,
01235                                             TileSet::Left | TileSet::Top | TileSet::Right);
01236 
01237                                 if (lw > 0)
01238                                     renderSlab(p, QRect(r.right() - lw-7+gw, r.y()-gw, lw+7, 7),
01239                                              pal.color(QPalette::Window), NoFill, TileSet::Top | TileSet::Right);
01240                             }
01241                             else
01242                             {
01243                                 if (lw > 0)
01244                                     renderSlab(p, QRect(-gw, r.y()-gw, lw+7, 7), pal.color(QPalette::Window), NoFill,
01245                                         TileSet::Left | TileSet::Top);
01246 
01247                                 if (w+lw >0)
01248                                     renderSlab(p, QRect(w+lw-7, r.y()-gw, r.width() - w - lw+7+gw, 7), pal.color(QPalette::Window), NoFill,
01249                                             TileSet::Top | TileSet::Right);
01250                                 else
01251                                     renderSlab(p, QRect(-gw, r.y(), r.width()+2*gw, 7), pal.color(QPalette::Window), NoFill,
01252                                             TileSet::Left | TileSet::Top | TileSet::Right);
01253 
01254                             }
01255                             return;
01256 
01257                         case QTabBar::RoundedSouth:
01258                         case QTabBar::TriangularSouth:
01259                             renderSlab(p, r.adjusted(-gw,-gw,gw,gw), pal.color(QPalette::Window), NoFill,
01260                                        TileSet::Left | TileSet::Top | TileSet::Right);
01261                             if(reverseLayout)
01262                             {
01263                                 // Left and right widgets are placed right and left when in reverse mode
01264 
01265                                 if (w+lw >0)
01266                                     renderSlab(p, QRect(-gw, r.bottom()-7+gw, r.width() - w - lw + 7+gw, 7),
01267                                         pal.color(QPalette::Window), NoFill, TileSet::Left | TileSet::Bottom);
01268                                 else
01269                                     renderSlab(p, QRect(-gw, r.bottom()-7+gw, r.width()+2*gw, 7), pal.color(QPalette::Window),
01270                                         NoFill, TileSet::Left | TileSet::Bottom | TileSet::Right);
01271 
01272                                 if (lw > 0)
01273                                     renderSlab(p, QRect(r.right() - lw-7+gw, r.bottom()-7+gw, lw+7, 7),
01274                                         pal.color(QPalette::Window), NoFill, TileSet::Bottom | TileSet::Right);
01275                             }
01276                             else
01277                             {
01278                                 if (lw > 0)
01279                                     renderSlab(p, QRect(-gw, r.bottom()-7+gw, lw+7+gw, 7),
01280                                             pal.color(QPalette::Window), NoFill, TileSet::Left | TileSet::Bottom);
01281 
01282                                 if (w+lw >0)
01283                                     renderSlab(p, QRect(w+lw-7, r.bottom()-7+gw, r.width() - w - lw+7+gw, 7),
01284                                             pal.color(QPalette::Window), NoFill, TileSet::Bottom | TileSet::Right);
01285                                 else
01286                                     renderSlab(p, QRect(-gw, r.bottom()-7, r.width()+2*gw, 7), pal.color(QPalette::Window),
01287                                         NoFill, TileSet::Left | TileSet::Bottom | TileSet::Right);
01288 
01289                             }
01290                             return;
01291 
01292                         case QTabBar::RoundedWest:
01293                         case QTabBar::TriangularWest:
01294                             renderSlab(p, r.adjusted(-gw,-gw,gw,gw), pal.color(QPalette::Window), NoFill,
01295                                        TileSet::Top | TileSet::Right | TileSet::Bottom);
01296 
01297                             if(reverseLayout)
01298                             {
01299                                 // Left and right widgets are placed right and left when in reverse mode
01300                                 if (h+lh >0)
01301                                     renderSlab(p, QRect(r.x()-gw,  h + lh - 7, 7, r.height() - h - lh+7+gw),
01302                                                pal.color(QPalette::Window), NoFill, TileSet::Bottom | TileSet::Left);
01303                                 else
01304                                     renderSlab(p, QRect(r.x()-gw, r.y()-gw, r.width()+2*gw, 7), pal.color(QPalette::Window), NoFill,
01305                                                TileSet::Left | TileSet::Top | TileSet::Right);
01306 
01307                                 if (lh > 0)
01308                                     renderSlab(p, QRect(r.x()-gw, r.y()+gw , 7, lh+7),
01309                                                pal.color(QPalette::Window), NoFill, TileSet::Top | TileSet::Left);
01310                             }
01311                             else
01312                             {
01313                                 if (lh > 0)
01314                                     renderSlab(p, QRect(r.x()-gw, r.y()-gw, 7, lh+7), pal.color(QPalette::Window), NoFill,
01315                                                TileSet::Left | TileSet::Top);
01316 
01317                                 if (h+lh >0)
01318                                     renderSlab(p, QRect(r.x()-gw, r.y()+h+lh-7, 7, r.height() - h - lh+7+gw), pal.color(QPalette::Window), NoFill,
01319                                                TileSet::Left | TileSet::Bottom);
01320                                 else
01321                                     renderSlab(p, QRect(r.x()-gw, r.y()-gw, 7, r.height()+2*gw), pal.color(QPalette::Window), NoFill,
01322                                                TileSet::Top | TileSet::Left | TileSet::Bottom);
01323                             }
01324 
01325                             return;
01326 
01327                         case QTabBar::RoundedEast:
01328                         case QTabBar::TriangularEast:
01329                             renderSlab(p, r.adjusted(-gw,-gw,gw,gw), pal.color(QPalette::Window), NoFill,
01330                                        TileSet::Top | TileSet::Left | TileSet::Bottom);
01331                             if(reverseLayout)
01332                             {
01333                                 // Left and right widgets are placed right and left when in reverse mode
01334                                 if (h+lh >0)
01335                                     renderSlab(p, QRect(r.right()+1-7+gw,  h + lh - 7, 7, r.height() - h - lh+7+gw),
01336                                                pal.color(QPalette::Window), NoFill, TileSet::Bottom | TileSet::Right);
01337                                 else
01338                                     renderSlab(p, QRect(r.right()+1-7+gw, r.y()-gw, r.width()+2*gw, 7), pal.color(QPalette::Window), NoFill,
01339                                                TileSet::Left | TileSet::Top | TileSet::Right);
01340 
01341                                 if (lh > 0)
01342                                     renderSlab(p, QRect(r.right()+1-7+gw, r.y()+gw , 7, lh+7),
01343                                                pal.color(QPalette::Window), NoFill, TileSet::Top | TileSet::Right);
01344                             }
01345                             else
01346                             {
01347                                 if (lh > 0)
01348                                     renderSlab(p, QRect(r.right()+1-7+gw, r.y()-gw, 7, lh+7+gw), pal.color(QPalette::Window), NoFill,
01349                                                TileSet::Top | TileSet::Right);
01350 
01351                                 if (h+lh >0)
01352                                     renderSlab(p, QRect(r.right()+1-7+gw, r.y()+h+lh-7, 7, r.height() - h - lh+7+gw), pal.color(QPalette::Window), NoFill,
01353                                                TileSet::Bottom | TileSet::Right);
01354                                 else
01355                                     renderSlab(p, QRect(r.x()-gw, r.y()-gw, 7, r.height()+2*gw), pal.color(QPalette::Window), NoFill,
01356                                                TileSet::Top | TileSet::Right | TileSet::Bottom);
01357                             }
01358 
01359                             return;
01360                         default:
01361                             return;
01362                     }
01363                 }
01364 
01365             }
01366         }
01367         break;
01368 
01369         case WT_Window:
01370         {
01371             switch (primitive)
01372             {
01373                 case Generic::Frame:
01374                 {
01375                     _helper.drawFloatFrame(p, r, pal.window().color());
01376                     return;
01377                 }
01378 
01379                 case Window::TitlePanel:
01380                     return;
01381 
01382                 case Window::ButtonMin:
01383                 case Window::ButtonMax:
01384                 case Window::ButtonRestore:
01385                 case Window::ButtonClose:
01386                 case Window::ButtonShade:
01387                 case Window::ButtonUnshade:
01388                 case Window::ButtonHelp:
01389                 {
01390                     KStyle::TitleButtonOption* tbkOpts =
01391                             extractOption<KStyle::TitleButtonOption*>(kOpt);
01392                     State bflags = flags;
01393                     bflags &= ~State_Sunken;
01394                     if (tbkOpts->active)
01395                         bflags |= State_Sunken;
01396                     //drawKStylePrimitive(WT_ToolButton, ToolButton::Panel, opt, r, pal, bflags, p, widget);
01397                     p->drawPixmap(r.topLeft(), _helper.windecoButton(pal.button().color(), false,  r.height()));
01398                     p->setRenderHints(QPainter::Antialiasing);
01399                     p->setBrush(Qt::NoBrush);
01400                     QLinearGradient lg = _helper.decoGradient(QRect(3,3,11,11), QColor(0,0,0));
01401                     p->setPen(QPen(lg, 1.4));
01402                     renderWindowIcon(p, QRectF(r).adjusted(-2.5,-2.5,0,0), primitive);
01403 
01404                     return;
01405                 }
01406 
01407             }
01408         }
01409         break;
01410 
01411         case WT_Splitter:
01412         {
01413             switch (primitive)
01414             {
01415                 case Splitter::HandleHor:
01416                 {
01417                     int h = r.height();
01418                     QColor color = pal.color(QPalette::Background);
01419 
01420                     int ngroups = qMax(1,h / 250);
01421                     int center = (h - (ngroups-1) * 250) /2 + r.top();
01422                     for(int k = 0; k < ngroups; k++, center += 250) {
01423                         renderDot(p, QPointF(r.left()+3, center-3), color);
01424                         renderDot(p, QPointF(r.left()+3, center), color);
01425                         renderDot(p, QPointF(r.left()+3, center+3), color);
01426                     }
01427                     return;
01428                 }
01429                 case Splitter::HandleVert:
01430                 {
01431                     int w = r.width();
01432                     QColor color = pal.color(QPalette::Background);
01433 
01434                     int ngroups = qMax(1, w / 250);
01435                     int center = (w - (ngroups-1) * 250) /2 + r.left();
01436                     for(int k = 0; k < ngroups; k++, center += 250) {
01437                         renderDot(p, QPointF(center-3, r.top()+3), color);
01438                         renderDot(p, QPointF(center, r.top()+3), color);
01439                         renderDot(p, QPointF(center+3, r.top()+3), color);
01440                     }
01441                     return;
01442                 }
01443             }
01444         }
01445         break;
01446 
01447         case WT_Slider:
01448         {
01449             // TODO
01450             switch (primitive)
01451             {
01452                 case Slider::HandleHor:
01453                 case Slider::HandleVert:
01454                 {
01455                     StyleOptions opts = (flags & State_HasFocus ? Focus : StyleOption());
01456                     if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt))
01457                         if(slider->activeSubControls & SC_SliderHandle)
01458                             if (mouseOver) opts |= Hover;
01459 
01460                     renderSlab(p, r, pal.color(QPalette::Button), opts);
01461                     return;
01462                 }
01463 
01464                 case Slider::GrooveHor:
01465                 case Slider::GrooveVert:
01466                 {
01467 
01468                     bool horizontal = primitive == Slider::GrooveHor;
01469 
01470                     if (horizontal) {
01471                         int center = r.y()+r.height()/2;
01472                         _helper.groove(pal.color(QPalette::Window), 0.0)->render(
01473                                     QRect(r.left()+4, center-2, r.width()-8, 5), p);
01474                     } else {
01475                         int center = r.x()+r.width()/2;
01476                         _helper.groove(pal.color(QPalette::Window), 0.0)->render(
01477                                     QRect(center-2, r.top()+4, 5, r.height()-8), p);
01478 
01479                     }
01480 
01481                     return;
01482                 }
01483             }
01484 
01485         }
01486         break;
01487 
01488         case WT_SpinBox:
01489         {
01490             bool hasFocus = flags & State_HasFocus;
01491 
01492             const QColor inputColor = enabled?pal.color(QPalette::Base):pal.color(QPalette::Window);
01493 
01494             switch (primitive)
01495             {
01496                 case Generic::Frame:
01497                 {
01498                     QRect fr = r.adjusted(2,2,-2,-2);
01499                     p->save();
01500                     p->setRenderHint(QPainter::Antialiasing);
01501                     p->setPen(Qt::NoPen);
01502                     p->setBrush(inputColor);
01503 
01504 #ifdef HOLE_NO_EDGE_FILL
01505                     p->fillRect(fr.adjusted(3,3,-3,-3), inputColor);
01506 #else
01507                     _helper.fillHole(*p, r);
01508 #endif
01509 
01510                     p->restore();
01511                     // TODO use widget background role?
01512                     // We really need the color of the widget behind to be "right",
01513                     // but the shadow needs to be colored as the inner widget; needs
01514                     // changes in helper.
01515 #ifdef HOLE_COLOR_OUTSIDE
01516                     renderHole(p, pal.color(QPalette::Window), fr, hasFocus, mouseOver);
01517 #else
01518                     renderHole(p, inputColor, fr, hasFocus, mouseOver);
01519 #endif
01520                     return;
01521                 }
01522                 case SpinBox::EditField:
01523                 case SpinBox::ButtonArea:
01524                 case SpinBox::UpButton:
01525                 case SpinBox::DownButton:
01526                 {
01527                     return;
01528                 }
01529 
01530             }
01531 
01532         }
01533         break;
01534 
01535         case WT_ComboBox:
01536         {
01537             bool editable = false;
01538             if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(opt) )
01539                 editable = cb->editable;
01540 
01541             bool hasFocus = flags & State_HasFocus;
01542             StyleOptions opts = (flags & State_HasFocus ? Focus : StyleOption());
01543             if (mouseOver) opts |= Hover;
01544 
01545             const QColor buttonColor = enabled?pal.color(QPalette::Button):pal.color(QPalette::Window);
01546             const QColor inputColor = enabled ? pal.color(QPalette::Base) : pal.color(QPalette::Window);
01547             QRect editField = subControlRect(CC_ComboBox, qstyleoption_cast<const QStyleOptionComplex*>(opt), SC_ComboBoxEditField, widget);
01548 
01549             switch (primitive)
01550             {
01551                 case Generic::Frame:
01552                 {
01553                     // TODO: pressed state
01554                     if(!editable) {
01555                         renderSlab(p, r, pal.color(QPalette::Button), opts);
01556                     } else {
01557                         QRect fr = r.adjusted(2,2,-2,-2);
01558                         // input area
01559                         p->save();
01560                         p->setRenderHint(QPainter::Antialiasing);
01561                         p->setPen(Qt::NoPen);
01562                         p->setBrush(inputColor);
01563 
01564 #ifdef HOLE_NO_EDGE_FILL
01565                         p->fillRect(fr.adjusted(3,3,-3,-3), inputColor);
01566 #else
01567                         _helper.fillHole(*p, r.adjusted(0,0,0,-1));
01568 #endif
01569 
01570                         p->restore();
01571 
01572 #ifdef HOLE_COLOR_OUTSIDE
01573                         if (hasFocus && enabled)
01574                         {
01575                             renderHole(p, pal.color(QPalette::Window), fr, true, mouseOver);
01576                         }
01577                         else
01578                         {
01579                             renderHole(p, pal.color(QPalette::Window), fr, false, mouseOver);
01580                         }
01581 #else
01582                         if (hasFocus && enabled)
01583                         {
01584                             renderHole(p, inputColor, fr, true, mouseOver);
01585                         }
01586                         else
01587                         {
01588                             renderHole(p, inputColor, fr, false, mouseOver);
01589                         }
01590 #endif
01591                     }
01592 
01593                     return;
01594                 }
01595 
01596                 case ComboBox::EditField:
01597                 {
01598                     // empty
01599                     return;
01600                 }
01601 
01602                 case ComboBox::Button:
01603                 {
01604                     return;
01605                 }
01606             }
01607 
01608         }
01609         break;
01610 
01611         case WT_Header:
01612         {
01613             switch (primitive)
01614             {
01615                 case Header::SectionHor:
01616                 case Header::SectionVert:
01617                 {
01618                     if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
01619                         bool isFirst = (primitive==Header::SectionHor)&&(header->position == QStyleOptionHeader::Beginning);
01620 
01621                         p->setPen(pal.color(QPalette::Text));
01622 
01623                         QColor color = pal.color(QPalette::Button);
01624                         p->fillRect(r, color);
01625                         if(primitive == Header::SectionHor) {
01626                             if(header->section != 0 || isFirst) {
01627                                 int center = r.center().y();
01628                                 int pos = (reverseLayout)? r.left()+1 : r.right()-1;
01629                                 renderDot(p, QPointF(pos, center-3), color);
01630                                 renderDot(p, QPointF(pos, center), color);
01631                                 renderDot(p, QPointF(pos, center+3), color);
01632                             }
01633                         }
01634                         else
01635                             p->drawLine(r.bottomLeft(),r.bottomRight());
01636                     }
01637 
01638                     return;
01639                 }
01640             }
01641         }
01642         break;
01643 
01644         case WT_Tree:
01645         {
01646             switch (primitive)
01647             {
01648                 case Tree::VerticalBranch:
01649                 case Tree::HorizontalBranch:
01650                 {
01651                 //### FIXME: set sane color.
01652                     QBrush brush(Qt::Dense4Pattern);
01653                     brush.setColor(pal.mid().color() );
01654                     p->fillRect(r, brush);
01655                     return;
01656                 }
01657                 case Tree::ExpanderOpen:
01658                 case Tree::ExpanderClosed:
01659                 {
01660                     int radius = (r.width() - 4) / 2;
01661                     int centerx = r.x() + r.width()/2;
01662                     int centery = r.y() + r.height()/2;
01663 
01664                     p->setPen( pal.text().color() );
01665                     if(!_drawTriangularExpander)
01666                     {
01667                         // plus or minus
01668                         p->drawLine( centerx - radius, centery, centerx + radius, centery );
01669                         if (primitive == Tree::ExpanderClosed) // Collapsed = On
01670                             p->drawLine( centerx, centery - radius, centerx, centery + radius );
01671                     } else {
01672                         if(primitive == Tree::ExpanderClosed)
01673                             drawKStylePrimitive(WT_Generic, Generic::ArrowRight, opt, QRect(r.x()+1,r.y()+1,r.width(),r.height()), pal, flags, p, widget);
01674                         else
01675                             drawKStylePrimitive(WT_Generic, Generic::ArrowDown, opt, QRect(r.x()+1,r.y()+1,r.width(),r.height()), pal, flags, p, widget);
01676                     }
01677 
01678                     return;
01679                 }
01680                 default:
01681                     break;
01682             }
01683         }
01684         break;
01685 
01686         case WT_LineEdit:
01687         {
01688             switch (primitive)
01689             {
01690                 case Generic::Frame:
01691                 {
01692                     const bool isReadOnly = flags & State_ReadOnly;
01693                     const bool isEnabled = flags & State_Enabled;
01694                     const bool hasFocus = flags & State_HasFocus;
01695 #ifdef HOLE_COLOR_OUTSIDE
01696                     const QColor inputColor =  pal.color(QPalette::Window);
01697 #else
01698                     const QColor inputColor = enabled?pal.color(QPalette::Base):pal.color(QPalette::Window);
01699 #endif
01700                     if (hasFocus && !isReadOnly && isEnabled)
01701                     {
01702                         renderHole(p, inputColor, r.adjusted(2,2,-2,-3), true, mouseOver);
01703                     }
01704                     else
01705                     {
01706                         renderHole(p, inputColor, r.adjusted(2,2,-2,-3), false, mouseOver);
01707                     }
01708                     return;
01709                 }
01710 
01711                 case LineEdit::Panel:
01712                 {
01713                     const QColor inputColor = enabled?pal.color(QPalette::Base):pal.color(QPalette::Window);
01714 
01715                     if (const QStyleOptionFrame *panel = qstyleoption_cast<const QStyleOptionFrame*>(opt))
01716                     {
01717                         const int lineWidth(panel->lineWidth);
01718 
01719                         if (lineWidth > 0)
01720                         {
01721                             p->save();
01722                             p->setRenderHint(QPainter::Antialiasing);
01723                             p->setPen(Qt::NoPen);
01724                             p->setBrush(inputColor);
01725 
01726 #ifdef HOLE_NO_EDGE_FILL
01727                             p->fillRect(r.adjusted(5,5,-5,-5), inputColor);
01728 #else
01729                             _helper.fillHole(*p, r.adjusted(0,0,-0,-1));
01730 #endif
01731                             drawPrimitive(PE_FrameLineEdit, panel, p, widget);
01732 
01733                             p->restore();
01734                         }
01735                         else
01736                         {
01737                             p->fillRect(r.adjusted(2,2,-2,-1), inputColor);
01738                         }
01739                     }
01740                 }
01741             }
01742 
01743         }
01744         break;
01745 
01746         case WT_GroupBox:
01747         {
01748             switch (primitive)
01749             {
01750                 case Generic::Frame:
01751                 {
01752                     QColor color = pal.color(QPalette::Window);
01753 
01754                     p->save();
01755                     p->setRenderHint(QPainter::Antialiasing);
01756                     p->setPen(Qt::NoPen);
01757 
01758                     QLinearGradient innerGradient(0, r.top()-r.height()+12, 0, r.bottom()+r.height()-19);
01759                     QColor light = _helper.calcLightColor(color); //KColorUtils::shade(calcLightColor(color), shade));
01760                     light.setAlphaF(0.4);
01761                     innerGradient.setColorAt(0.0, light);
01762                     color.setAlphaF(0.4);
01763                     innerGradient.setColorAt(1.0, color);
01764                     p->setBrush(innerGradient);
01765                     p->setClipRect(r.adjusted(0, 0, 0, -19));
01766                     _helper.fillSlab(*p, r);
01767 
01768                     TileSet *slopeTileSet = _helper.slope(pal.color(QPalette::Window), 0.0);
01769                     p->setClipping(false);
01770                     slopeTileSet->render(r, p);
01771 
01772                     p->restore();
01773 
01774                     return;
01775                 }
01776                 case GroupBox::FlatFrame:
01777                 {
01778                     return;
01779                 }
01780             }
01781 
01782         }
01783         break;
01784 
01785         case WT_ToolBar:
01786         {
01787             switch (primitive)
01788             {
01789                 case ToolBar::HandleHor:
01790                 {
01791                     int counter = 1;
01792 
01793                         int center = r.left()+r.width()/2;
01794                         for(int j = r.top()+2; j <= r.bottom()-3; j+=3) {
01795                             if(counter%2 == 0) {
01796                                 renderDot(p, QPoint(center+1, j), pal.color(QPalette::Background));
01797                             } else {
01798                                 renderDot(p, QPoint(center-2, j), pal.color(QPalette::Background));
01799                             }
01800                             counter++;
01801                         }
01802                     return;
01803                 }
01804                 case ToolBar::HandleVert:
01805                 {
01806                     int counter = 1;
01807 
01808                         int center = r.top()+r.height()/2;
01809                         for(int j = r.left()+2; j <= r.right()-3; j+=3) {
01810                             if(counter%2 == 0) {
01811                                 renderDot(p, QPoint(j, center+1), pal.color(QPalette::Background));
01812                             } else {
01813                                 renderDot(p, QPoint(j, center-2), pal.color(QPalette::Background));
01814                             }
01815                             counter++;
01816                         }
01817 
01818                     return;
01819                 }
01820 
01821                 case ToolBar::Separator:
01822                 {
01823                     if(_drawToolBarItemSeparator) {
01824 
01825                         if(flags & State_Horizontal)
01826                             renderSeparator(p,r,pal,Qt::Vertical);
01827                         else
01828                             renderSeparator(p,r,pal,Qt::Horizontal);
01829                     }
01830 
01831                     return;
01832                 }
01833             }
01834         }
01835         break;
01836 
01837         case WT_ToolButton:
01838         {
01839             switch (primitive)
01840             {
01841                 case ToolButton::Panel:
01842                 {
01843                     QRect slitRect = r;
01844                     const QToolButton* t=dynamic_cast<const QToolButton*>(widget);
01845                     if (t && !t->autoRaise())
01846                     {
01847                         StyleOptions opts = 0;
01848 
01849                         if (const QTabBar *tb =  dynamic_cast<const QTabBar*>(t->parent()))
01850                         {
01851                             bool horizontal = true;
01852                             bool northOrEast = true;
01853                             switch(tb->shape())
01854                             {
01855                                 case QTabBar::RoundedNorth:
01856                                 case QTabBar::TriangularNorth:
01857                                     break;
01858                                 case QTabBar::RoundedSouth:
01859                                 case QTabBar::TriangularSouth:
01860                                     northOrEast = false;
01861                                     break;
01862                                 case QTabBar::RoundedEast:
01863                                 case QTabBar::TriangularEast:
01864                                     horizontal = false;
01865                                     break;
01866                                 case QTabBar::RoundedWest:
01867                                 case QTabBar::TriangularWest:
01868                                     northOrEast = false;
01869                                     horizontal = false;
01870                                     break;
01871                                 default:
01872                                     break;
01873                             }
01874                             int gw=2;
01875                             if (horizontal)
01876                             {
01877                                 slitRect.adjust(0,3,0,-3);
01878                                 _helper.renderWindowBackground(p, r.adjusted(0,2,0,-1), t, t->window()->palette());
01879                                 if (northOrEast)
01880                                     renderSlab(p, QRect(r.left()-7, r.bottom()-6-gw, r.width()+14, 2), pal.color(QPalette::Window), NoFill, TileSet::Top);
01881                                 else
01882                                     renderSlab(p, QRect(r.left()-7, r.top()+4+gw, r.width()+14, 2), pal.color(QPalette::Window), NoFill, TileSet::Bottom);
01883                             }
01884                             else
01885                             {
01886                                 slitRect.adjust(3,0,-3,0);
01887                                 _helper.renderWindowBackground(p, r.adjusted(2,0,-2,0), t, t->window()->palette());
01888                                 if (northOrEast)
01889                                     renderSlab(p, QRect(r.left()+5-gw, r.top()-7, 2, r.height()+14), pal.color(QPalette::Window), NoFill, TileSet::Right);
01890                                 else
01891                                     renderSlab(p, QRect(r.right()-6+gw, r.top()-7, 2, r.height()+14), pal.color(QPalette::Window), NoFill, TileSet::Left);
01892                             }
01893                             // continue drawing the slit
01894                         }
01895                         else
01896                         {
01897                             if ((flags & State_On) || (flags & State_Sunken))
01898                                 opts |= Sunken;
01899                             if (flags & State_HasFocus)
01900                                 opts |= Focus;
01901                             if (enabled && (flags & State_MouseOver))
01902                                 opts |= Hover;
01903                             
01904                             if (t->popupMode()==QToolButton::MenuButtonPopup) {
01905                                 renderSlab(p, r.adjusted(0,0,4,0), pal.color(QPalette::Button), opts, TileSet::Bottom | TileSet::Top | TileSet::Left);
01906                             } else
01907                                 renderSlab(p, r, pal.color(QPalette::Button), opts);
01908                             return;
01909                         }
01910                     }
01911 
01912                     bool hasFocus = flags & State_HasFocus;
01913 
01914                     if((flags & State_Sunken) || (flags & State_On) )
01915                     {
01916                         renderHole(p, pal.color(QPalette::Window), slitRect, hasFocus, mouseOver);
01917                     }
01918                     else if (hasFocus || mouseOver)
01919                     {
01920                         TileSet *tile;
01921                         tile = _helper.slitFocused(_viewFocusBrush.brush(QPalette::Active).color());
01922                         tile->render(slitRect, p);
01923                     }
01924                     return;
01925                 }
01926             }
01927 
01928         }
01929         break;
01930 
01931         case WT_Limit: //max value for the enum, only here to silence the compiler
01932         case WT_Generic: // handled below since the primitives arevalid for all WT_ types
01933             break;
01934     }
01935 
01936 
01937     // Arrows
01938     if (primitive >= Generic::ArrowUp && primitive <= Generic::ArrowLeft) {
01939         QPolygonF a;
01940         QPen oldPen(p->pen()); // important to save the pen as combobox assumes we don't touch
01941 
01942         switch (primitive) {
01943             case Generic::ArrowUp: {
01944                 a.clear();
01945                 a << QPointF( -3,2.5) << QPointF(0.5, -1.5) << QPointF(4,2.5);
01946                 break;
01947             }
01948             case Generic::ArrowDown: {
01949                 a.clear();
01950                 a << QPointF( -3,-2.5) << QPointF(0.5, 1.5) << QPointF(4,-2.5);
01951               break;
01952             }
01953             case Generic::ArrowLeft: {
01954                 a.clear();
01955                 a << QPointF(2.5,-3) << QPointF(-1.5, 0.5) << QPointF(2.5,4);
01956                 break;
01957             }
01958             case Generic::ArrowRight: {
01959                 a.clear();
01960                 a << QPointF(-2.5,-3) << QPointF(1.5, 0.5) << QPointF(-2.5,4);
01961                 break;
01962             }
01963         }
01964         qreal penThickness = 2.2;
01965 
01966         if (const QToolButton *tool = dynamic_cast<const QToolButton *>(widget)) {
01967             if (tool->popupMode()==QToolButton::MenuButtonPopup) {
01968                 if(!tool->autoRaise()) {
01969                     if ((flags & State_On) || (flags & State_Sunken))
01970                         opts |= Sunken;
01971                     if (flags & State_HasFocus)
01972                         opts |= Focus;
01973                     if (enabled && (flags & State_MouseOver))
01974                         opts |= Hover;
01975                     renderSlab(p, r.adjusted(-10,0,0,0), pal.color(QPalette::Button), opts, TileSet::Bottom | TileSet::Top | TileSet::Right);
01976 
01977                     a.translate(-3,1);
01978 
01979                     //Draw the dividing line
01980                     QColor color = pal.color(QPalette::Window);
01981                     QColor light = _helper.calcLightColor(color);
01982                     QColor dark = _helper.calcDarkColor(color);
01983                     dark.setAlpha(200);
01984                     light.setAlpha(150);
01985                     p->setPen(QPen(light,1));
01986                     p->drawLine(r.x()-5, r.y()+3, r.x()-5, r.bottom()-4);
01987                     p->drawLine(r.x()-3, r.y()+3, r.x()-3, r.bottom()-3);
01988                     p->setPen(QPen(dark,1));
01989                     p->drawLine(r.x()-4, r.y()+4, r.x()-4, r.bottom()-3);
01990                 }
01991             }
01992             else {
01993                 // smaller down arrow for menu indication on toolbuttons
01994                 penThickness = 1.7;
01995                 a.clear();
01996                 // NOTE: is there any smarter solution than this?
01997                 switch (primitive)
01998                 {
01999                     case Generic::ArrowUp: {
02000                         a << QPointF( -2,1.5) << QPointF(0.5, -1.5) << QPointF(3,1.5);
02001                         break;
02002                     }
02003                     case Generic::ArrowDown: {
02004                         a << QPointF( -2,-1.5) << QPointF(0.5, 1.5) << QPointF(3,-1.5);
02005                         break;
02006                     }
02007                     case Generic::ArrowLeft: {
02008                         a << QPointF(1.5,-2) << QPointF(-1.5, 0.5) << QPointF(1.5,3);
02009                         break;
02010                     }
02011                     case Generic::ArrowRight: {
02012                         a << QPointF(-1.5,-2) << QPointF(1.5, 0.5) << QPointF(-1.5,3);
02013                         break;
02014                     }
02015                 }
02016             }
02017         }
02018 
02019         a.translate(int(r.x()+r.width()/2), int(r.y()+r.height()/2));
02020 
02021         KStyle::ColorOption* colorOpt   = extractOption<KStyle::ColorOption*>(kOpt);
02022         QColor  arrowColor = colorOpt->color.color(pal);
02023 
02024         p->setPen(QPen(arrowColor, penThickness, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
02025         p->setRenderHint(QPainter::Antialiasing);
02026         p->drawPolyline(a);
02027         p->setRenderHint(QPainter::Antialiasing, false);
02028         p->setPen(oldPen);
02029         return;
02030     }
02031 
02032     switch (primitive)
02033     {
02034         case Generic::Frame:
02035         {
02036             // WT_Generic and other fallen-through frames...
02037             // QFrame, Qt item views, etc.: sunken..
02038             bool focusHighlight = flags&State_HasFocus/* && flags&State_Enabled*/;
02039             if (flags & State_Sunken) {
02040                 // TODO use widget background role? - probably not
02041                 //renderHole(p, pal.color(widget->backgroundRole()), r, focusHighlight);
02042                 renderHole(p, pal.color(QPalette::Window), r, focusHighlight);
02043             } else
02044                 if(widgetType == WT_Generic && (flags & State_Raised)) {
02045                     renderSlab(p, r.adjusted(-2, -2, 2, 2), pal.color(QPalette::Background), NoFill);
02046                 }
02047                 break; // do the default thing
02048         }
02049 
02050         case Generic::FocusIndicator:
02051         {
02052             const QAbstractItemView *aiv = qobject_cast<const QAbstractItemView*>(widget);
02053             if (aiv && opt && (opt->state & QStyle::State_Item)
02054                          && (aiv->selectionMode() != QAbstractItemView::SingleSelection))
02055             {
02056                 QPen pen(_viewFocusBrush.brush(QPalette::Active).color());
02057                 pen.setWidth(0);
02058                 pen.setStyle(Qt::DotLine);
02059                 p->setPen(pal.color(QPalette::Base));
02060                 p->drawRect(r.adjusted(0,0,-1,-1));
02061                 p->setPen(pen);
02062                 p->drawRect(r.adjusted(0,0,-1,-1));
02063             }
02064             // we don't want the stippled focus indicator in oxygen
02065             return;
02066         }
02067 
02068         default:
02069             break;
02070     }
02071 
02072     // default fallback
02073     KStyle::drawKStylePrimitive(widgetType, primitive, opt,
02074                                 r, pal, flags, p, widget, kOpt);
02075 }
02076 
02077 void OxygenStyle::polish(QWidget* widget)
02078 {
02079     if (!widget) return;
02080 
02081     switch (widget->windowFlags() & Qt::WindowType_Mask) {
02082         case Qt::Window:
02083         case Qt::Dialog:
02084             widget->installEventFilter(this);
02085             widget->setAttribute(Qt::WA_StyledBackground);
02086             break;
02087         case Qt::Popup: // we currently don't want that kind of gradient on menus etc
02088         case Qt::Tool: // this we exclude as it is used for dragging of icons etc
02089         default:
02090             break;
02091     }
02092 
02093     if( _animateProgressBar && qobject_cast<QProgressBar*>(widget) )
02094     {
02095         widget->installEventFilter(this);
02096         progAnimWidgets[widget] = 0;
02097         connect(widget, SIGNAL(destroyed(QObject*)), this, SLOT(progressBarDestroyed(QObject*)));
02098         if (!animationTimer->isActive()) {
02099             animationTimer->setSingleShot( false );
02100             animationTimer->start( 50 );
02101         }
02102     }
02103 
02104     if (qobject_cast<QPushButton*>(widget)
02105         || qobject_cast<QComboBox*>(widget)
02106         || qobject_cast<QAbstractSpinBox*>(widget)
02107         || qobject_cast<QCheckBox*>(widget)
02108         || qobject_cast<QRadioButton*>(widget)
02109         || qobject_cast<QTabBar*>(widget)
02110         || qobject_cast<QScrollBar*>(widget)
02111         || qobject_cast<QSlider*>(widget)
02112         || qobject_cast<QToolButton*>(widget)
02113         || qobject_cast<QLineEdit*>(widget)
02114         ) {
02115         widget->setAttribute(Qt::WA_Hover);
02116     }
02117 
02118     if (qobject_cast<QMenuBar*>(widget))
02119     {
02120         widget->setBackgroundRole(QPalette::NoRole);
02121     }
02122     else if (widget->inherits("Q3ToolBar")
02123         || qobject_cast<QToolBar*>(widget)
02124         || qobject_cast<QToolBar *>(widget->parent()))
02125     {
02126         widget->setBackgroundRole(QPalette::NoRole);
02127         widget->setContentsMargins(0,0,0,2);
02128         widget->installEventFilter(this);
02129     }
02130     else if (qobject_cast<QScrollBar*>(widget) )
02131     {
02132         widget->setAttribute(Qt::WA_OpaquePaintEvent, false);
02133     }
02134     else if (qobject_cast<QDockWidget*>(widget))
02135     {
02136         widget->setContentsMargins(4,3,4,4);
02137         widget->installEventFilter(this);
02138     }
02139     else if (qobject_cast<QToolBox*>(widget))
02140     {
02141         widget->setBackgroundRole(QPalette::NoRole);
02142         widget->setAutoFillBackground(false);
02143         widget->setContentsMargins(5,5,5,5);
02144         widget->installEventFilter(this);
02145     }
02146     else if (widget->parentWidget() && widget->parentWidget()->parentWidget() && qobject_cast<QToolBox*>(widget->parentWidget()->parentWidget()->parentWidget()))
02147     {
02148         widget->setBackgroundRole(QPalette::NoRole);
02149         widget->setAutoFillBackground(false);
02150         widget->parentWidget()->setAutoFillBackground(false);
02151     }
02152     else if (qobject_cast<QMenu*>(widget) 
02153             || qobject_cast<QFrame*>(widget) 
02154             || qobject_cast<QMdiSubWindow*>(widget))
02155     {
02156         widget->installEventFilter(this);
02157     }
02158     else if (widget->inherits("QComboBoxPrivateContainer"))
02159     {
02160         widget->installEventFilter(this);
02161         // note, it doesn't help to do a setContentsMargin()
02162     }
02163     KStyle::polish(widget);
02164 }
02165 
02166 void OxygenStyle::unpolish(QWidget* widget)
02167 {
02168     if ( qobject_cast<QProgressBar*>(widget) )
02169     {
02170         progAnimWidgets.remove(widget);
02171     }
02172 
02173     if (qobject_cast<QPushButton*>(widget)
02174         || qobject_cast<QComboBox*>(widget)
02175         || qobject_cast<QAbstractSpinBox*>(widget)
02176         || qobject_cast<QCheckBox*>(widget)
02177         || qobject_cast<QRadioButton*>(widget)
02178         || qobject_cast<QScrollBar*>(widget)
02179         || qobject_cast<QSlider*>(widget)
02180         || qobject_cast<QLineEdit*>(widget)
02181     ) {
02182         widget->setAttribute(Qt::WA_Hover, false);
02183     }
02184 
02185     if (qobject_cast<QMenuBar*>(widget)
02186         || (widget && widget->inherits("Q3ToolBar"))
02187         || qobject_cast<QToolBar*>(widget)
02188         || (widget && qobject_cast<QToolBar *>(widget->parent()))
02189         || qobject_cast<QToolBox*>(widget))
02190     {
02191         widget->setBackgroundRole(QPalette::Button);
02192     }
02193 
02194     if (qobject_cast<QScrollBar*>(widget))
02195     {
02196         widget->setAttribute(Qt::WA_OpaquePaintEvent);
02197     }
02198     else if (qobject_cast<QDockWidget*>(widget))
02199     {
02200         widget->setContentsMargins(0,0,0,0);
02201     }
02202     else if (qobject_cast<QToolBox*>(widget))
02203     {
02204         widget->setBackgroundRole(QPalette::Button);
02205         widget->setContentsMargins(0,0,0,0);
02206         widget->removeEventFilter(this);
02207     }
02208     else if (qobject_cast<QMenu*>(widget))
02209     {
02210         widget->setAttribute(Qt::WA_PaintOnScreen, false);
02211         widget->setAttribute(Qt::WA_NoSystemBackground, false);
02212         widget->removeEventFilter(this);
02213     }
02214     else if (qobject_cast<QFrame*>(widget)
02215             || qobject_cast<QMdiSubWindow*>(widget))
02216     {
02217         widget->removeEventFilter(this);
02218     }
02219     else if (widget->inherits("QComboBoxPrivateContainer"))
02220     {
02221         widget->removeEventFilter(this);
02222     }
02223     KStyle::unpolish(widget);
02224 }
02225 
02226 void OxygenStyle::progressBarDestroyed(QObject* obj)
02227 {
02228     progAnimWidgets.remove(static_cast<QWidget*>(obj));
02229     //the timer updates will stop next time if this was the last visible one
02230 }
02231 
02232 void OxygenStyle::globalSettingsChange(int type, int /*arg*/)
02233 {
02234     if (type == KGlobalSettings::PaletteChanged) {
02235         _helper.reloadConfig();
02236         _viewFocusBrush = KStatefulBrush( KColorScheme::View, KColorScheme::FocusColor, _config );
02237         _viewHoverBrush = KStatefulBrush( KColorScheme::View, KColorScheme::HoverColor, _config );
02238     }
02239 }
02240 
02241 void OxygenStyle::renderSlab(QPainter *p, QRect r, const QColor &color, StyleOptions opts, TileSet::Tiles tiles) const
02242 {
02243     if ((r.width() <= 0) || (r.height() <= 0))
02244         return;
02245 
02246     TileSet *tile;
02247 
02248     if (opts & Sunken)
02249         r.adjust(-1,0,1,2); // the tiles of sunken slabs look different so this is needed (also for the fill)
02250 
02251     // fill
02252     if (!(opts & NoFill))
02253     {
02254         p->save();
02255         p->setRenderHint(QPainter::Antialiasing);
02256         p->setPen(Qt::NoPen);
02257 
02258         QLinearGradient innerGradient(0, r.top() - r.height(), 0, r.bottom());
02259         innerGradient.setColorAt(0.0, _helper.calcLightColor(color)); //KColorUtils::shade(calcLightColor(color), shade));
02260         innerGradient.setColorAt(1.0, color);
02261         p->setBrush(innerGradient);
02262         _helper.fillSlab(*p, r);
02263 
02264         p->restore();
02265     }
02266 
02267     // edges
02268     // for slabs, hover takes precedence over focus (other way around for holes)
02269     // but in any case if the button is sunken we don't show focus nor hover
02270     if (opts & Sunken)
02271         tile = _helper.slabSunken(color, 0.0);
02272     else if (opts & Hover)
02273         tile = _helper.slabFocused(color, _viewHoverBrush.brush(QPalette::Active).color(), 0.0); // FIXME need state
02274     else if (opts & Focus)
02275         tile = _helper.slabFocused(color, _viewFocusBrush.brush(QPalette::Active).color(), 0.0); // FIXME need state
02276     else
02277     {
02278         tile = _helper.slab(color, 0.0);
02279         tile->render(r, p, tiles);
02280         return;
02281     }
02282     tile->render(r, p, tiles);
02283 }
02284 
02285 void OxygenStyle::renderHole(QPainter *p, const QColor &base, const QRect &r, bool focus, bool hover, TileSet::Tiles posFlags) const
02286 {
02287     if((r.width() <= 0)||(r.height() <= 0))
02288         return;
02289 
02290     TileSet *tile;
02291     // for holes, focus takes precedence over hover (other way around for buttons)
02292     if (focus)
02293         tile = _helper.holeFocused(base, _viewFocusBrush.brush(QPalette::Active).color(), 0.0); // FIXME need state
02294     else if (hover)
02295         tile = _helper.holeFocused(base, _viewHoverBrush.brush(QPalette::Active).color(), 0.0); // FIXME need state
02296     else
02297         tile = _helper.hole(base, 0.0);
02298     tile->render(r, p, posFlags);
02299 }
02300 
02301 // TODO take StyleOptions instead of ugly bools
02302 void OxygenStyle::renderCheckBox(QPainter *p, const QRect &rect, const QPalette &pal,
02303                                  bool enabled, bool hasFocus, bool mouseOver, int primitive,
02304                                  bool sunken) const
02305 {
02306     Q_UNUSED(enabled);
02307 
02308     int s = qMin(rect.width(), rect.height());
02309     QRect r = centerRect(rect, s, s);
02310 
02311     StyleOptions opts;
02312     if (hasFocus) opts |= Focus;
02313     if (mouseOver) opts |= Hover;
02314 
02315     if(sunken)
02316     {
02317         QColor color = pal.color(QPalette::Window);
02318         _helper.holeFlat(color, 0.0)->render(r, p, TileSet::Full);
02319     }
02320     else
02321     {
02322         renderSlab(p, r, pal.color(QPalette::Button), opts);
02323     }
02324 
02325     // check mark
02326     double x = r.center().x() - 3.5, y = r.center().y() - 2.5;
02327 
02328     if (primitive != CheckBox::CheckOff)
02329     {
02330         QBrush brush = _helper.decoGradient(rect.adjusted(2,2,-2,-2), pal.color(QPalette::ButtonText));
02331         QPen pen(brush, 2.2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
02332 
02333         pen.setCapStyle(Qt::RoundCap);
02334         if (primitive == CheckBox::CheckTriState) {
02335             QVector<qreal> dashes;
02336             if (_checkCheck) {
02337                 dashes << 1.0 << 2.0;
02338                 pen.setWidthF(1.3);
02339             }
02340             else {
02341                 dashes << 0.4 << 2.0;
02342             }
02343             pen.setDashPattern(dashes);
02344         }
02345 
02346         p->setRenderHint(QPainter::Antialiasing);
02347         p->setPen(pen);
02348         if (_checkCheck) {
02349             p->drawLine(QPointF(x+9, y), QPointF(x+3,y+7));
02350             p->drawLine(QPointF(x, y+4), QPointF(x+3,y+7));
02351         }
02352         else {
02353             if (sunken) {
02354                 p->drawLine(QPointF(x+8, y), QPointF(x+1,y+7));
02355                 p->drawLine(QPointF(x+8, y+7), QPointF(x+1,y));
02356             }
02357             else {
02358                 p->drawLine(QPointF(x+8, y-1), QPointF(x,y+7));
02359                 p->drawLine(QPointF(x+8, y+7), QPointF(x,y-1));
02360             }
02361         }
02362         p->setRenderHint(QPainter::Antialiasing, false);
02363     }
02364 }
02365 
02366 void OxygenStyle::renderRadioButton(QPainter *p, const QRect &r, const QPalette &pal,
02367                                         bool enabled, bool hasFocus, bool mouseOver, int prim,
02368                                    bool drawButton) const
02369 {
02370     Q_UNUSED(enabled);
02371 
02372     QRect r2(r.x() + (r.width()-21)/2, r.y() + (r.height()-21)/2, 21, 21);
02373     int x = r2.x();
02374     int y = r2.y();
02375 
02376     if(mouseOver || hasFocus)
02377     {
02378         QPixmap slabPixmap = _helper.roundSlabFocused(pal.color(QPalette::Button),
02379                     (mouseOver ? _viewHoverBrush : _viewFocusBrush).brush(QPalette::Active).color(), 0.0);
02380         if(drawButton)
02381             p->drawPixmap(x, y, slabPixmap);
02382     }
02383     else
02384     {
02385         QPixmap slabPixmap = _helper.roundSlab(pal.color(QPalette::Button), 0.0);
02386         if(drawButton)
02387             p->drawPixmap(x, y, slabPixmap);
02388     }
02389 
02390     // draw the radio mark
02391     switch (prim)
02392     {
02393         case RadioButton::RadioOn:
02394         {
02395             const double radius = 3.0;
02396             double dx = r2.width() * 0.5 - radius;
02397             double dy = r2.height() * 0.5 - radius;
02398             p->save();
02399             p->setRenderHints(QPainter::Antialiasing);
02400             p->setPen(Qt::NoPen);
02401             p->setBrush(_helper.decoGradient(r2.adjusted(2,2,-2,-2), pal.color(QPalette::ButtonText)));
02402             p->drawEllipse(QRectF(r2).adjusted(dx, dy, -dx, -dy));
02403             p->restore();
02404             return;
02405         }
02406         case RadioButton::RadioOff:
02407         {
02408             // empty
02409             return;
02410         }
02411 
02412         default:
02413             // StateTristate, shouldn't happen...
02414             return;
02415     }
02416 }
02417 
02418 void OxygenStyle::renderDot(QPainter *p, const QPointF &point, const QColor &baseColor) const
02419 {
02420     Q_UNUSED(baseColor)
02421     const qreal diameter = 1.8;
02422     p->setRenderHint(QPainter::Antialiasing);
02423     p->setPen(Qt::NoPen);
02424     p->setBrush(QColor(0, 0, 0, 66));
02425     p->drawEllipse(QRectF(point.x()-diameter/2+0.5, point.y()-diameter/2+0.5, diameter, diameter));
02426     p->setRenderHint(QPainter::Antialiasing, false);
02427 }
02428 
02429 void OxygenStyle::renderSeparator(QPainter *p, const QRect &rect,
02430 const QPalette &pal, Qt::Orientation orientation) const
02431 {
02432     QColor color = pal.color(QPalette::Window);
02433     QColor light = _helper.calcLightColor(color);
02434     QColor dark = _helper.calcDarkColor(color);
02435 
02436     bool antialias = p->testRenderHint(QPainter::Antialiasing);
02437     p->setRenderHint(QPainter::Antialiasing,false);
02438 
02439     QPoint start,end,offset;
02440 
02441     if (orientation == Qt::Horizontal) {
02442         start = QPoint(rect.x(),rect.y()+rect.height()/2-1);
02443         end = QPoint(rect.right(),rect.y()+rect.height()/2-1);
02444     offset = QPoint(0,1);
02445     } else {
02446     start = QPoint(rect.x()+rect.width()/2-1,rect.y());
02447     end = QPoint(rect.x()+rect.width()/2-1,rect.bottom());
02448     offset = QPoint(1,0);
02449     light.setAlpha(150);
02450     }
02451 
02452     QLinearGradient lg(start,end);
02453     lg.setColorAt(0.3, dark);
02454     lg.setColorAt(0.7, dark);
02455     dark.setAlpha(0);
02456     lg.setColorAt(0.0, dark);
02457     lg.setColorAt(1.0, dark);
02458     p->setPen(QPen(lg,1));
02459 
02460     if (orientation == Qt::Horizontal)
02461     p->drawLine(start,end);
02462     else
02463     p->drawLine(start+offset,end+offset);
02464 
02465     lg = QLinearGradient(start,end);
02466     lg.setColorAt(0.3, light);
02467     lg.setColorAt(0.7, light);
02468     light.setAlpha(0);
02469     lg.setColorAt(0.0, light);
02470     lg.setColorAt(1.0, light);
02471     p->setPen(QPen(lg,1));
02472 
02473 
02474     if (orientation == Qt::Horizontal)
02475     p->drawLine(start+offset,end+offset);
02476     else
02477     {
02478     p->drawLine(start,end);
02479     p->drawLine(start+offset*2,end+offset*2);
02480     }
02481 
02482     p->setRenderHint(QPainter::Antialiasing, antialias);
02483 }
02484 
02485 void OxygenStyle::renderTab(QPainter *p,
02486                             const QRect &r,
02487                             const QPalette &pal,
02488                             bool mouseOver,
02489                             const bool selected,
02490                             const QStyleOptionTabV2 *tabOpt,
02491                             const bool reverseLayout) const
02492 {
02493     const QStyleOptionTab::TabPosition pos = tabOpt->position;
02494     const bool northAlignment = tabOpt->shape == QTabBar::RoundedNorth || tabOpt->shape == QTabBar::TriangularNorth;
02495     const bool southAlignment = tabOpt->shape == QTabBar::RoundedSouth || tabOpt->shape == QTabBar::TriangularSouth;
02496     const bool westAlignment = tabOpt->shape == QTabBar::RoundedWest || tabOpt->shape == QTabBar::TriangularWest;
02497     const bool eastAlignment = tabOpt->shape == QTabBar::RoundedEast || tabOpt->shape == QTabBar::TriangularEast;
02498     const bool leftCornerWidget = reverseLayout ?
02499                             (tabOpt->cornerWidgets&QStyleOptionTab::RightCornerWidget) :
02500                             (tabOpt->cornerWidgets&QStyleOptionTab::LeftCornerWidget);
02501     const bool rightCornerWidget = reverseLayout ?
02502                             (tabOpt->cornerWidgets&QStyleOptionTab::LeftCornerWidget) :
02503                             (tabOpt->cornerWidgets&QStyleOptionTab::RightCornerWidget);
02504     const bool isFirst = pos == QStyleOptionTab::Beginning || pos == QStyleOptionTab::OnlyOneTab/* (pos == First) || (pos == Single)*/;
02505     const bool isLast = pos == QStyleOptionTab::End /*(pos == Last)*/;
02506     const bool isSingle = pos == QStyleOptionTab::OnlyOneTab /*(pos == Single)*/;
02507     const bool isLeftOfSelected =  reverseLayout ?
02508                             (tabOpt->selectedPosition == QStyleOptionTab::PreviousIsSelected) :
02509                             (tabOpt->selectedPosition == QStyleOptionTab::NextIsSelected);
02510     const bool isRightOfSelected =  reverseLayout ?
02511                             (tabOpt->selectedPosition == QStyleOptionTab::NextIsSelected) :
02512                             (tabOpt->selectedPosition == QStyleOptionTab::PreviousIsSelected);
02513     const bool isLeftMost =  (reverseLayout && !(westAlignment || eastAlignment) ?
02514                             (tabOpt->position == QStyleOptionTab::End) :
02515                             (tabOpt->position == QStyleOptionTab::Beginning)) ||
02516                                 tabOpt->position == QStyleOptionTab::OnlyOneTab;
02517     const bool isRightMost =  reverseLayout && !(westAlignment || eastAlignment) ?
02518                             (tabOpt->position == QStyleOptionTab::Beginning) :
02519                             (tabOpt->position == QStyleOptionTab::End) ||
02520                                 tabOpt->position == QStyleOptionTab::OnlyOneTab;
02521     const bool isFrameAligned =  reverseLayout && !(westAlignment || eastAlignment) ?
02522         (isRightMost && ! (tabOpt->cornerWidgets & QStyleOptionTab::LeftCornerWidget)) :
02523         (isLeftMost && ! (tabOpt->cornerWidgets & QStyleOptionTab::LeftCornerWidget));
02524     const QColor midColor = _helper.alphaColor(_helper.calcDarkColor(pal.color(QPalette::Window)), 0.4);
02525     const QColor darkColor = _helper.alphaColor(_helper.calcDarkColor(pal.color(QPalette::Window)), 0.6);
02526 
02527     if(northAlignment || southAlignment) {
02528         // the tab part of the tab - ie subtracted the fairing to the frame
02529         QRect Rc = southAlignment ? r.adjusted(-gw,6+gw,gw,gw) : r.adjusted(-gw,-gw,gw,-7-gw);
02530 
02531         // the area where the fairing should appear
02532         QRect Rb(Rc.x(), southAlignment?r.top()+gw:Rc.bottom()+1, Rc.width(), r.height()-Rc.height() );
02533 
02534 
02535         // FIXME - maybe going to redo tabs
02536         if (selected) {
02537             int x,y,w,h;
02538             r.getRect(&x, &y, &w, &h);
02539 
02540             if(southAlignment)
02541                 renderSlab(p, Rc.adjusted(0,-7,0,0), pal.color(QPalette::Window), NoFill, TileSet::Bottom | TileSet::Left | TileSet::Right);
02542             else
02543                 renderSlab(p, Rc.adjusted(0,0,0,7), pal.color(QPalette::Window), NoFill, TileSet::Top | TileSet::Left | TileSet::Right);
02544 
02545             // some "position specific" paintings...
02546             // First draw the left connection from the panel border to the tab
02547             if(isFirst && !reverseLayout && !leftCornerWidget) {
02548                 renderSlab(p, Rb.adjusted(0,-7,0,7), pal.color(QPalette::Window), NoFill, TileSet::Left);
02549             } else {
02550                 TileSet *tile = _helper.slabInverted(pal.color(QPalette::Window), 0.0);
02551                 if(southAlignment)
02552                     tile->render(QRect(Rb.left()-5, Rb.top()-1,12,13), p, TileSet::Right | TileSet::Top);
02553                 else
02554                     tile->render(QRect(Rb.left()-5, Rb.top()-5,12,12), p, TileSet::Right | TileSet::Bottom);
02555             }
02556 
02557             // Now draw the right connection from the panel border to the tab
02558             if(isFirst && reverseLayout && !rightCornerWidget) {
02559                 renderSlab(p, Rb.adjusted(0,-7,0,7), pal.color(QPalette::Window), NoFill, TileSet::Right);
02560             } else {
02561                 TileSet *tile = _helper.slabInverted(pal.color(QPalette::Window), 0.0);
02562                 //renderHole(p, QRect(Rb.right()-3, Rb.top(),3,5), false, false, TileSet::Left | TileSet::Bottom);
02563                 if(southAlignment)
02564                     tile->render(QRect(Rb.right()-6, Rb.top()-1,12,13), p, TileSet::Left | TileSet::Top);
02565                 else
02566                     tile->render(QRect(Rb.right()-6, Rb.top()-5,12,12), p, TileSet::Left | TileSet::Bottom);
02567             }
02568         } else {
02569             
02570             // inactive tabs
02571             int x,y,w,h;
02572             p->save(); // we only use the clipping and AA for inactive tabs
02573             p->setPen(darkColor);
02574             p->setBrush(midColor);
02575             p->setRenderHints(QPainter::Antialiasing);
02576 
02577             if (northAlignment) {
02578                 r.adjusted(0,5-gw,0,-gw).getRect(&x, &y, &w, &h);
02579                 p->setClipRect(x-4, y, w+8, h-5); // don't intersect the translucent border of the slab
02580                 p->setClipRect(x, y, w, h, Qt::UniteClip);
02581                 if(isLeftMost) {
02582                     QPainterPath path;
02583                     x-=gw;
02584                     w+=gw;
02585                     path.moveTo(x+2.5, y+h-2-(isFrameAligned ? 0 : 2));
02586                     path.lineTo(x+2.5, y+2.5); // left border
02587                     path.arcTo(QRectF(x+2.5, y+0.5, 9, 9), 180, -90); // top-left corner
02588                     path.lineTo(QPointF(x+w-0.5+(isLeftOfSelected?4-gw:0), y+0.5)); // top border
02589                     path.lineTo(QPointF(x+w-0.5+(isLeftOfSelected?4-gw:0), y+h-4)); // to complete the path.
02590                     p->drawPath(path);
02591                 } else if(isRightMost) {
02592                     QPainterPath path;
02593                     w+=gw;
02594                     path.moveTo(x+w-2.5, y+h-2-(isFrameAligned?0:2));
02595                     path.lineTo(x+w-2.5, y+2.5); // right border
02596                     path.arcTo(QRectF(x+w-9-2.5, y+0.5, 9, 9), 0, 90); // top-right corner
02597                     path.lineTo(QPointF(x+0.5-(isRightOfSelected?4-gw:0), y+0.5)); // top border
02598                     path.lineTo(QPointF(x+0.5-(isRightOfSelected?4-gw:0), y+h-4)); // to complete the path.
02599                     p->drawPath(path);
02600                 } else {
02601                     // top border
02602                     p->drawLine(QPointF(x-(isRightOfSelected?2:0), y+0.5), QPointF(x+w+(isRightOfSelected?2:0)+(isLeftOfSelected?2:0), y+0.5));
02603                     if(!isLeftOfSelected)
02604                         p->drawLine(QPointF(x+w+0.5, y+1.5), QPointF(x+w+0.5, y+h-4));
02605                     p->fillRect(x-(isRightOfSelected ? 2 : 0), y+1, w+(isLeftOfSelected||isRightOfSelected?3:0), h-5, midColor);
02606                 }
02607             }
02608             else { // southAlignment
02609                 r.adjusted(0,0+gw,0,-5+gw).getRect(&x, &y, &w, &h);
02610                 if(isLeftMost) {
02611                     QPainterPath path;
02612                     x-=gw;
02613                     w+=gw;
02614                     path.moveTo(x+2.5, y+2+(isFrameAligned ? 0 : 2));
02615                     path.lineTo(x+2.5, y+h-2.5); // left border
02616                     path.arcTo(QRectF(x+2.5, y+h-9.5, 9, 9), 180, 90); // bottom-left corner
02617                     path.lineTo(QPointF(x+w-0.5+(isLeftOfSelected?4-gw:0), y+h-0.5)); // bottom border
02618                     path.lineTo(QPointF(x+w-0.5+(isLeftOfSelected?4-gw:0), y+4)); // to complete the path.
02619                     p->drawPath(path);
02620                 } else if(isRightMost) {
02621                     QPainterPath path;
02622                     w+=gw;
02623                     path.moveTo(x+w-2.5, y+2+(isFrameAligned ?0:2));
02624                     path.lineTo(x+w-2.5, y+h-2.5); // right border
02625                     path.arcTo(QRectF(x+w-9-2.5, y+h-9.5, 9, 9), 0, -90); // bottom-right corner
02626                     path.lineTo(QPointF(x+0.5-(isRightOfSelected?4-gw:0), y+h-0.5)); // bottom border
02627                     path.lineTo(QPointF(x+0.5-(isRightOfSelected?4-gw:0), y+4)); // to complete the path.
02628                     p->drawPath(path);
02629                 } else {
02630                     // bottom border
02631                     p->drawLine(QPointF(x-(isRightOfSelected?2:0), y+h-0.5), QPointF(x+w+(isRightOfSelected ?2:0)+(isLeftOfSelected ?2:0), y+h-0.5));
02632                     if(!isLeftOfSelected)
02633                         p->drawLine(QPointF(x+w+0.5, y+1.5), QPointF(x+w+0.5, y+h-4));
02634                     p->fillRect(x-(isRightOfSelected ?2:0), y+1, w+(isLeftOfSelected || isRightOfSelected?3:0), h-2, midColor);
02635                 }
02636             }
02637             p->restore();
02638 
02639             TileSet::Tiles posFlag = southAlignment?TileSet::Bottom:TileSet::Top;
02640             QRect Ractual(Rb.left(), Rb.y(), Rb.width(), 6);
02641 
02642             if(isLeftMost) {
02643                 if(isFrameAligned)
02644                     posFlag |= TileSet::Left;
02645                 // fix, to keep the mouseover line within the tabs (drawn) boundary
02646                 if(reverseLayout || !isFrameAligned) {
02647                     renderSlab(p, QRect(Ractual.left()-7, Ractual.y(), 2+14, Ractual.height()), pal.color(QPalette::Window), NoFill, posFlag);
02648                     Ractual.adjust(-5,0,0,0);
02649                 }
02650             }
02651             else
02652                 Ractual.adjust(-7+gw,0,0,0);
02653 
02654             if(isRightMost) {
02655                 if(isFrameAligned)
02656                     posFlag |= TileSet::Right;
02657                 // fix, to keep the mouseover line within the tabs (drawn) boundary
02658                 if(reverseLayout && !isFrameAligned) {
02659                     renderSlab(p, QRect(Ractual.left()+Ractual.width()-2-7, Ractual.y(), 1+14, Ractual.height()), pal.color(QPalette::Window), NoFill, posFlag);
02660                     Ractual.adjust(0,0,5,0);
02661                 }
02662                 else if(!isFrameAligned) {
02663                     renderSlab(p, QRect(Ractual.left()+Ractual.width()-2-7, Ractual.y(), 2+14, Ractual.height()), pal.color(QPalette::Window), NoFill, posFlag);
02664                     Ractual.adjust(0,0,5,0);
02665                 }
02666             }
02667             else
02668                 Ractual.adjust(0,0,7-gw,0);
02669 
02670             if (mouseOver)
02671                 renderSlab(p, Ractual, pal.color(QPalette::Window), NoFill| Hover, posFlag);
02672             else
02673                 renderSlab(p, Ractual, pal.color(QPalette::Window), NoFill, posFlag);
02674 
02675 
02676             // TODO mouseover effects
02677         }
02678     }
02679      // westAlignment and eastAlignment
02680     else {
02681         // the tab part of the tab - ie subtracted the fairing to the frame
02682         QRect Rc = eastAlignment ? r.adjusted(7+gw,-gw,gw,gw) : r.adjusted(-gw,-gw,-7-gw,gw);
02683         // the area where the fairing should appear
02684         const QRect Rb(eastAlignment ? r.x()+gw: Rc.right()+1, Rc.top(), r.width()-Rc.width(), Rc.height() );
02685 
02686         if (selected) {
02687             int x,y,w,h;
02688             r.getRect(&x, &y, &w, &h);
02689 
02690             // parts of the adjacent tabs
02691             if(!isSingle && ((!reverseLayout && !isFirst) || (reverseLayout && !isFirst))) {
02692                 p->setPen(darkColor);
02693                 if(eastAlignment) {
02694                     p->fillRect(x+5, y, w-10, 2, midColor);
02695                     p->drawLine(QPointF(x+w-5-1, y), QPointF(x+w-5-1, y+2));
02696                 }
02697                 else {
02698                     p->fillRect(x+5, y, w-10, 2, midColor);
02699                     p->drawLine(QPointF(x+5, y), QPointF(x+5, y+2));
02700                 }
02701             }
02702             if(!isSingle && ((!reverseLayout && !isLast) || (reverseLayout && !isLast))) {
02703                 p->setPen(darkColor);
02704                 if(eastAlignment) {
02705                     p->fillRect(x+5, y+h-2, w-10, 2, midColor);
02706                     p->drawLine(QPointF(x+w-5-1, y+h-2), QPointF(x+w-5-1, y+h-1));
02707                 }
02708                 else {
02709                     p->fillRect(x+5, y+h-2, w-10, 2, midColor);
02710                     p->drawLine(QPointF(x+5, y+h-2-1), QPointF(x+5, y+h-1));
02711                 }
02712             }
02713 
02714             if(eastAlignment)
02715                 renderSlab(p, Rc.adjusted(-7,0,0,0), pal.color(QPalette::Window), NoFill, TileSet::Top | TileSet::Right | TileSet::Bottom);
02716             else
02717                 renderSlab(p, Rc.adjusted(0,0,7,0), pal.color(QPalette::Window), NoFill, TileSet::Top | TileSet::Left | TileSet::Bottom);
02718 
02719             // some "position specific" paintings...
02720             // First draw the top connection from the panel border to the tab
02721             if(isFirst && !leftCornerWidget) {
02722                 renderSlab(p, Rb.adjusted(-7,0,7,0), pal.color(QPalette::Window), NoFill, TileSet::Top);
02723             } else {
02724                 TileSet *tile = _helper.slabInverted(pal.color(QPalette::Window), 0.0);
02725                 if(eastAlignment)
02726                     tile->render(QRect(Rb.left(), Rb.top()-6,12,13), p, TileSet::Left | TileSet::Bottom);
02727                 else
02728                     tile->render(QRect(Rb.left()-5, Rb.top()-5,12,12), p, TileSet::Right | TileSet::Bottom);
02729             }
02730 
02731             // Now draw the bottom connection from the panel border to the tab
02732             TileSet *tile = _helper.slabInverted(pal.color(QPalette::Window), 0.0);
02733             if(eastAlignment)
02734                 tile->render(QRect(Rb.right()-6, Rb.bottom()-6,12,13), p, TileSet::Left | TileSet::Top);
02735             else
02736                 tile->render(QRect(Rb.right()-5-6, Rb.bottom()-6,12,12), p, TileSet::Right | TileSet::Top);
02737 
02738         }
02739         else {
02740             // inactive tabs
02741             int x,y,w,h;
02742             p->setPen(darkColor);
02743 
02744             if (westAlignment) {
02745                 r.adjusted(5-gw,0,-5-gw,0).getRect(&x, &y, &w, &h);
02746 
02747                 if(isLeftMost) { // at top
02748                     p->drawArc(QRectF(x+0.5, y+1.5, 9.5, 9.5),90*16, 90*16);
02749                     if(isFrameAligned)
02750                         p->drawLine(QPointF(x-3+9.5, y+1.5), QPointF(x+w+1.5, y+1.5));
02751                     else
02752                         p->drawLine(QPointF(x-3+9.5, y+1.5), QPointF(x+w-1, y+1.5));
02753                     // leftline
02754                     p->drawLine(QPointF(x, y-3+9.5), QPointF(x, y+h-1));
02755                     // separator
02756                     if((!reverseLayout && !isLeftOfSelected) || (reverseLayout && !isRightOfSelected))
02757                         p->drawLine(QPointF(x+1.5, y+h-1), QPointF(x+w-0.5, y+h-1));
02758                     p->fillRect(x, y+2, w, h-2, midColor);
02759                 } else  if(isRightMost) { // at bottom
02760                     p->drawArc(QRectF(x+0.5, y+h-0.5-9.5, 9.5, 9.5), 180*16, 90*16);
02761                     if(isFrameAligned)
02762                         p->drawLine(QPointF(x+9.5, y+h-1), QPointF(x+w, y+h-1));
02763                     else
02764                         p->drawLine(QPointF(x-4+9.5, y+h-1), QPointF(x+w-1, y+h-1));
02765                     // leftline
02766                     p->drawLine(QPointF(x, y), QPointF(x, y+h+3-9.5));
02767                     p->fillRect(x, y, w, h, midColor);
02768                 } else {
02769                     // leftline
02770                     p->drawLine(QPointF(x, y), QPointF(x, y+h-1));
02771                     if((!reverseLayout && !isLeftOfSelected) || (reverseLayout && !isRightOfSelected))
02772                         p->drawLine(QPointF(x+1.5, y+h-1), QPointF(x+w-0.5, y+h-1));
02773                     p->fillRect(x, y, w, h, midColor);
02774                 }
02775             }
02776             else { // eastAlignment
02777 
02778                 r.adjusted(5+gw,0,-5+gw,0).getRect(&x, &y, &w, &h);
02779 
02780                 if(isLeftMost) { // at top
02781                     p->drawArc(QRectF(x+w-0.5-9.5, y+1.5, 9.5, 9.5),0*16, 90*16);
02782                     if(isFrameAligned)
02783                         p->drawLine(QPointF(x-1.5, y+1.5), QPointF(x+w+3-9.5, y+1.5));
02784                     else
02785                         p->drawLine(QPointF(x, y+1.5), QPointF(x+w+3-9.5, y+1.5));
02786                     // rightline
02787                     p->drawLine(QPointF(x+w-1, y-3+9.5), QPointF(x+w-1, y+h-1));
02788                     // separator
02789                     if((!reverseLayout && !isLeftOfSelected) || (reverseLayout && !isRightOfSelected))
02790                         p->drawLine(QPointF(x+0.5, y+h-1), QPointF(x+w-1.5, y+h-1));
02791                     p->fillRect(x, y+2, w, h-2, midColor);
02792                 } else  if(isRightMost) { // at bottom
02793                     p->drawArc(QRectF(x+w-9.5-0.5, y+h-0.5-9.5, 9.5, 9.5), 270*16, 90*16);
02794                     if(isFrameAligned) // in reverseLayout mode
02795                         p->drawLine(QPointF(x-2.5, y+h-1), QPointF(x+w+3-9.5, y+h-1));
02796                     else
02797                         p->drawLine(QPointF(x+0.5, y+h-1), QPointF(x+w+4-9.5, y+h-1));
02798                     // rightline
02799                     p->drawLine(QPointF(x+w-1, y), QPointF(x+w-1, y+h+3-9.5));
02800                     p->fillRect(x, y, w, h, midColor);
02801                 } else {
02802                     // rightline
02803                     p->drawLine(QPointF(x+w-1, y), QPointF(x+w-1, y+h-1));
02804                     if((!reverseLayout && !isLeftOfSelected) || (reverseLayout && !isRightOfSelected))
02805                         p->drawLine(QPointF(x+0.5, y+h-1), QPointF(x+w-1.5, y+h-1));
02806                     p->fillRect(x, y, w, h, midColor);
02807                 }
02808 
02809             }
02810 
02811             TileSet::Tiles posFlag = eastAlignment ? TileSet::Right : TileSet::Left;
02812             QRect Ractual(Rb.left(), Rb.y(), 7, Rb.height());
02813 
02814             if(isLeftMost) { // at top
02815                 if(isFrameAligned)
02816                     posFlag |= TileSet::Top;
02817                 else {
02818                     renderSlab(p, QRect(Ractual.left(), Ractual.y()-7, Ractual.width(), 2+14), pal.color(QPalette::Window), NoFill, posFlag);
02819                     Ractual.adjust(0,-5,0,0);
02820                 }
02821             }
02822             else
02823                 Ractual.adjust(0,-7+gw,0,0);
02824 
02825             if(isRightMost) { // at bottom
02826                 if(isFrameAligned && !reverseLayout)
02827                     posFlag |= TileSet::Top;
02828                 Ractual.adjust(0,0,0,7);
02829             }
02830             else
02831                 Ractual.adjust(0,0,0,7-gw);
02832 
02833             if (mouseOver)
02834                 renderSlab(p, Ractual, pal.color(QPalette::Window), NoFill| Hover, posFlag);
02835             else
02836                 renderSlab(p, Ractual, pal.color(QPalette::Window), NoFill, posFlag);
02837 
02838         // TODO mouseover effects
02839         }
02840 
02841     }
02842 }
02843 
02844 int OxygenStyle::styleHint(StyleHint hint, const QStyleOption * option,
02845                             const QWidget * widget, QStyleHintReturn * returnData) const
02846 {
02847     switch (hint) {
02848         case SH_ComboBox_ListMouseTracking:
02849             return true;
02850         case SH_Menu_SubMenuPopupDelay:
02851             return 96; // Motif-like delay...
02852 
02853         case SH_ScrollView_FrameOnlyAroundContents:
02854             return true;
02855 
02856         case SH_ItemView_ShowDecorationSelected:
02857             return false;
02858 
02859         case SH_RubberBand_Mask:
02860         {
02861             const QStyleOptionRubberBand *opt = qstyleoption_cast<const QStyleOptionRubberBand *>(option);
02862             if (!opt)
02863                 return true;
02864             if (QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask*>(returnData))
02865                 mask->region = option->rect;
02866             return true;
02867         }
02868         default:
02869             return KStyle::styleHint(hint, option, widget, returnData);
02870     }
02871 }
02872 
02873 int OxygenStyle::pixelMetric(PixelMetric m, const QStyleOption *opt, const QWidget *widget) const
02874 {
02875     switch(m) {
02876         case PM_DefaultTopLevelMargin:
02877             return 11;
02878 
02879         case PM_DefaultChildMargin:
02880             return 4; // qcommon is 9;
02881 
02882         case PM_DefaultLayoutSpacing:
02883             return 4; // qcommon is 6
02884 
02885         case PM_DefaultFrameWidth:
02886             if (qobject_cast<const QLineEdit*>(widget))
02887                 return 5;
02888             if (qobject_cast<const QFrame*>(widget) ||  qobject_cast<const QComboBox*>(widget))
02889                 return 3;
02890             //else fall through
02891         default:
02892             return KStyle::pixelMetric(m,opt,widget);
02893     }
02894 }
02895 
02896 QSize OxygenStyle::sizeFromContents(ContentsType type, const QStyleOption* option, const QSize& contentsSize, const QWidget* widget) const
02897 {
02898     switch(type)
02899     {
02900         case CT_ToolButton:
02901         {
02902             QSize size = contentsSize;
02903 
02904             if (const QStyleOptionToolButton* tbOpt = qstyleoption_cast<const QStyleOptionToolButton*>(option)) {
02905                 if ((!tbOpt->icon.isNull()) && (!tbOpt->text.isEmpty()) && tbOpt->toolButtonStyle == Qt::ToolButtonTextUnderIcon)
02906                     size.setHeight(size.height()-9);
02907             }
02908 
02909             // We want to avoid super-skiny buttons, for things like "up" when icons + text
02910             // For this, we would like to make width >= height.
02911             // However, once we get here, QToolButton may have already put in the menu area
02912             // (PM_MenuButtonIndicator) into the width. So we may have to take it out, fix things
02913             // up, and add it back in. So much for class-independent rendering...
02914             int   menuAreaWidth = 0;
02915             if (const QStyleOptionToolButton* tbOpt = qstyleoption_cast<const QStyleOptionToolButton*>(option)) {
02916                 if (tbOpt->features & QStyleOptionToolButton::MenuButtonPopup)
02917                     menuAreaWidth = pixelMetric(QStyle::PM_MenuButtonIndicator, option, widget);
02918                 else if (tbOpt->features & QStyleOptionToolButton::HasMenu)
02919                     size.setWidth(size.width() + widgetLayoutProp(WT_ToolButton, ToolButton::InlineMenuIndicatorSize, tbOpt, widget));
02920             }
02921             size.setWidth(size.width() - menuAreaWidth);
02922             if (size.width() < size.height())
02923                 size.setWidth(size.height());
02924             size.setWidth(size.width() + menuAreaWidth);
02925 
02926             const QToolButton* t=dynamic_cast<const QToolButton*>(widget);
02927             if (t && t->autoRaise()==true)
02928             {
02929                 int width = size.width() +
02930                                     2*widgetLayoutProp(WT_ToolButton, ToolButton::ContentsMargin + MainMargin, option, widget) +
02931                                     widgetLayoutProp(WT_ToolButton, ToolButton::ContentsMargin + Left, option, widget) +
02932                                     widgetLayoutProp(WT_ToolButton, ToolButton::ContentsMargin + Right, option, widget);
02933 
02934                 int height = size.height() +
02935                                     2*widgetLayoutProp(WT_ToolButton, ToolButton::ContentsMargin + MainMargin, option, widget) +
02936                                     widgetLayoutProp(WT_ToolButton, ToolButton::ContentsMargin + Top, option, widget) +
02937                                     widgetLayoutProp(WT_ToolButton, ToolButton::ContentsMargin + Bot, option, widget);
02938 
02939                 return QSize(width, height);
02940             }
02941             else
02942             {
02943                 int width = size.width() +
02944                         2*widgetLayoutProp(WT_PushButton, PushButton::ContentsMargin + MainMargin, option, widget);
02945 
02946                 int height = size.height() +
02947                         2*widgetLayoutProp(WT_PushButton, PushButton::ContentsMargin + MainMargin, option, widget)
02948                         + widgetLayoutProp(WT_PushButton, PushButton::ContentsMargin + Top, option, widget)
02949                         + widgetLayoutProp(WT_PushButton, PushButton::ContentsMargin + Bot, option, widget);
02950 
02951                 return QSize(width, height);
02952             }
02953         }
02954         default:
02955             break;
02956     }
02957     return KStyle::sizeFromContents(type, option, contentsSize, widget);
02958 }
02959 
02960 
02961 QRect OxygenStyle::subControlRect(ComplexControl control, const QStyleOptionComplex* option,
02962                                 SubControl subControl, const QWidget* widget) const
02963 {
02964     QRect r = option->rect;
02965 
02966     switch (control)
02967     {
02968         case CC_GroupBox:
02969         {
02970             const QStyleOptionGroupBox *gbOpt = qstyleoption_cast<const QStyleOptionGroupBox *>(option);
02971             if (!gbOpt)
02972                 break;
02973 
02974             bool isFlat = gbOpt->features & QStyleOptionFrameV2::Flat;
02975 
02976             switch (subControl)
02977             {
02978                 case SC_GroupBoxFrame:
02979                     return r;
02980                 case SC_GroupBoxContents:
02981                 {
02982                     int th = gbOpt->fontMetrics.height() + 8;
02983                     QRect cr = subElementRect(SE_CheckBoxIndicator, option, widget);
02984                     int fw = widgetLayoutProp(WT_GroupBox, GroupBox::FrameWidth, option, widget);
02985 
02986                     bool checkable = gbOpt->subControls & QStyle::SC_GroupBoxCheckBox;
02987                     bool emptyText = gbOpt->text.isEmpty();
02988                     if (emptyText && !checkable) r.adjust(fw, fw, -fw, -fw);
02989                     else if (checkable) r.adjust(fw, fw + cr.height(), -fw, -fw);
02990                     else if (!emptyText) r.adjust(fw, fw + th, -fw, -fw);
02991                     else r.adjust(fw, fw + qMax(th, cr.height()), -fw, -fw);
02992 
02993                     // add additional indentation to flat group boxes
02994                     if (isFlat)
02995                     {
02996                         int leftMarginExtension = 16;
02997                         r = visualRect(option->direction,r,r.adjusted(leftMarginExtension,0,0,0));
02998                     }
02999 
03000                     return r;
03001                 }
03002                 case SC_GroupBoxCheckBox:
03003                 case SC_GroupBoxLabel:
03004                 {
03005                     QFont font = widget->font();
03006                     // calculate text width assuming bold text in flat group boxes
03007                     if (isFlat)
03008                         font.setBold(true);
03009 
03010                     QFontMetrics fontMetrics = QFontMetrics(font);
03011                     int h = fontMetrics.height();
03012                     int tw = fontMetrics.size(Qt::TextShowMnemonic, gbOpt->text + QLatin1String("  ")).width();
03013                     r.setHeight(h);
03014                     r.moveTop(8);
03015                     QRect cr;
03016                     if(gbOpt->subControls & QStyle::SC_GroupBoxCheckBox)
03017                     {
03018                         cr = subElementRect(SE_CheckBoxIndicator, option, widget);
03019                         QRect gcr((gbOpt->rect.width() - tw -cr.width())/2 , (h-cr.height())/2+r.y(), cr.width(), cr.height());
03020                         if(subControl == SC_GroupBoxCheckBox)
03021             {
03022                 if (!isFlat)
03023                 return visualRect(option->direction, option->rect, gcr);
03024                 else
03025                 return visualRect(option->direction, option->rect, QRect(0,0,cr.width(),cr.height()));
03026             }
03027                     }
03028 
03029                     // left align labels in flat group boxes, center align labels in framed group boxes
03030                     if (isFlat)
03031                         r = QRect(cr.width(),r.y(),tw,r.height());
03032                     else
03033                         r = QRect((gbOpt->rect.width() - tw - cr.width())/2 + cr.width(), r.y(), tw, r.height());
03034 
03035                     return visualRect(option->direction, option->rect, r);
03036                 }
03037                 default:
03038                     break;
03039             }
03040             break;
03041         }
03042         default:
03043             break;
03044     }
03045 
03046     return KStyle::subControlRect(control, option, subControl, widget);
03047 }
03048 
03049 QRect OxygenStyle::subElementRect(SubElement sr, const QStyleOption *opt, const QWidget *widget) const
03050 {
03051     QRect r;
03052 
03053     switch (sr) {
03054     case SE_TabWidgetTabBar: {
03055         const QStyleOptionTabWidgetFrame *twf  = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt);
03056         if(!twf) return QRect();
03057         r = QRect(QPoint(0,0), twf->tabBarSize);
03058 
03059         switch (twf->shape) {
03060         case QTabBar::RoundedNorth:
03061         case QTabBar::TriangularNorth: {
03062             r.setWidth(qMin(r.width(), twf->rect.width()
03063                             - twf->leftCornerWidgetSize.width()
03064                             - twf->rightCornerWidgetSize.width()));
03065             r.moveTopLeft(QPoint(twf->leftCornerWidgetSize.width(), 0));
03066             r = visualRect(twf->direction, twf->rect, r);
03067             break;
03068         }
03069         case QTabBar::RoundedSouth:
03070         case QTabBar::TriangularSouth: {
03071             r.setWidth(qMin(r.width(), twf->rect.width()
03072                             - twf->leftCornerWidgetSize.width()
03073                             - twf->rightCornerWidgetSize.width()));
03074             r.moveTopLeft(QPoint(twf->leftCornerWidgetSize.width(),
03075                                      twf->rect.height() - twf->tabBarSize.height()));
03076             r = visualRect(twf->direction, twf->rect, r);
03077             break;
03078         }
03079         case QTabBar::RoundedEast:
03080         case QTabBar::TriangularEast: {
03081             r.setHeight(qMin(r.height(), twf->rect.height()
03082                              - twf->leftCornerWidgetSize.height()
03083                              - twf->rightCornerWidgetSize.height()));
03084             r.moveTopLeft(QPoint(twf->rect.width() - twf->tabBarSize.width(),
03085                                      twf->leftCornerWidgetSize.height()));
03086             break;
03087         }
03088         case QTabBar::RoundedWest:
03089         case QTabBar::TriangularWest: {
03090             r.setHeight(qMin(r.height(), twf->rect.height()
03091                              - twf->leftCornerWidgetSize.height()
03092                              - twf->rightCornerWidgetSize.height()));
03093             r.moveTopLeft(QPoint(0, twf->leftCornerWidgetSize.height()));
03094             }
03095             break;
03096         }
03097         return r;
03098 
03099     }
03100     case SE_TabWidgetLeftCorner: {
03101         const QStyleOptionTabWidgetFrame *twf = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt);
03102         if(!twf) return QRect();
03103 
03104         QRect paneRect = subElementRect(SE_TabWidgetTabPane, twf, widget);
03105         switch (twf->shape) {
03106         case QTabBar::RoundedNorth:
03107         case QTabBar::TriangularNorth:
03108             r = QRect(QPoint(paneRect.x(), paneRect.y() - twf->leftCornerWidgetSize.height()), twf->leftCornerWidgetSize);
03109             r = visualRect(twf->direction, twf->rect, r);
03110             break;
03111         case QTabBar::RoundedSouth:
03112         case QTabBar::TriangularSouth:
03113             r = QRect(QPoint(paneRect.x(), paneRect.height()), twf->leftCornerWidgetSize);
03114             r = visualRect(twf->direction, twf->rect, r);
03115             break;
03116         case QTabBar::RoundedWest:
03117         case QTabBar::TriangularWest:
03118             r = QRect(QPoint(paneRect.x() - twf->leftCornerWidgetSize.width(), paneRect.y()), twf->leftCornerWidgetSize);
03119             break;
03120         case QTabBar::RoundedEast:
03121         case QTabBar::TriangularEast:
03122             r = QRect(QPoint(paneRect.x() + paneRect.width(), paneRect.y()), twf->leftCornerWidgetSize);
03123             break;
03124         default:
03125             break;
03126         }
03127 
03128         return r;
03129 
03130     }
03131     case SE_TabWidgetRightCorner: {
03132         const QStyleOptionTabWidgetFrame *twf = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt);
03133         if(!twf) return QRect();
03134 
03135         QRect paneRect = subElementRect(SE_TabWidgetTabPane, twf, widget);
03136         switch (twf->shape) {
03137         case QTabBar::RoundedNorth:
03138         case QTabBar::TriangularNorth:
03139             r = QRect(QPoint(paneRect.width() - twf->rightCornerWidgetSize.width(), paneRect.y() - twf->rightCornerWidgetSize.height()), twf->rightCornerWidgetSize);
03140             r = visualRect(twf->direction, twf->rect, r);
03141             break;
03142         case QTabBar::RoundedSouth:
03143         case QTabBar::TriangularSouth:
03144             r = QRect(QPoint(paneRect.width() - twf->rightCornerWidgetSize.width(), paneRect.height()), twf->rightCornerWidgetSize);
03145             r = visualRect(twf->direction, twf->rect, r);
03146             break;
03147         case QTabBar::RoundedWest:
03148         case QTabBar::TriangularWest:
03149             r = QRect(QPoint(paneRect.x() - twf->rightCornerWidgetSize.width(), paneRect.y() + paneRect.height() - twf->rightCornerWidgetSize.height()), twf->rightCornerWidgetSize);
03150             break;
03151         case QTabBar::RoundedEast:
03152         case QTabBar::TriangularEast:
03153             r = QRect(QPoint(paneRect.x() + paneRect.width(), paneRect.y() + paneRect.height() - twf->rightCornerWidgetSize.height()), twf->rightCornerWidgetSize);
03154             break;
03155         default:
03156             break;
03157         }
03158 
03159         return r;
03160         }
03161     case SE_TabBarTearIndicator: {
03162         const QStyleOptionTab *option = qstyleoption_cast<const QStyleOptionTab *>(opt);
03163         if(!option) return QRect();
03164 
03165         switch (option->shape) {
03166         case QTabBar::RoundedNorth:
03167         case QTabBar::TriangularNorth:
03168         case QTabBar::RoundedSouth:
03169         case QTabBar::TriangularSouth:
03170             r.setRect(option->rect.left(), option->rect.top(), 8, option->rect.height());
03171             break;
03172         case QTabBar::RoundedWest:
03173         case QTabBar::TriangularWest:
03174         case QTabBar::RoundedEast:
03175         case QTabBar::TriangularEast:
03176             r.setRect(option->rect.left(), option->rect.top(), option->rect.width(), 8);
03177             break;
03178         default:
03179             break;
03180         }
03181         r = visualRect(opt->direction, opt->rect, r);
03182         return r;
03183     }
03184     default:
03185         return KStyle::subElementRect(sr, opt, widget);
03186     }
03187 
03188 }
03189 
03190 void OxygenStyle::renderWindowIcon(QPainter *p, const QRectF &r, int &type) const
03191 {
03192     p->save();
03193     p->translate(r.topLeft());
03194     switch(type)
03195     {
03196         case Window::ButtonHelp:
03197         {
03198             p->translate(1.5, 1.5);
03199             p->drawArc(7,5,4,4,135*16, -180*16);
03200             p->drawArc(9,8,4,4,135*16,45*16);
03201             p->drawPoint(9,12);
03202             break;
03203         }
03204         case Window::ButtonMin:
03205         {
03206             p->drawLine(QPointF( 7.5, 9.5), QPointF(10.5,12.5));
03207             p->drawLine(QPointF(10.5,12.5), QPointF(13.5, 9.5));
03208             break;
03209         }
03210         case Window::ButtonRestore:
03211         {
03212             p->translate(1.5, 1.5);
03213             QPoint points[4] = {QPoint(9, 6), QPoint(12, 9), QPoint(9, 12), QPoint(6, 9)};
03214             p->drawPolygon(points, 4);
03215             break;
03216         }
03217         case Window::ButtonMax:
03218         {                    
03219             p->drawLine(QPointF( 7.5,11.5), QPointF(10.5, 8.5));
03220             p->drawLine(QPointF(10.5, 8.5), QPointF(13.5,11.5));
03221             break;
03222         }
03223         case Window::ButtonClose:
03224         {
03225             p->drawLine(QPointF( 7.5,7.5), QPointF(13.5,13.5));
03226             p->drawLine(QPointF(13.5,7.5), QPointF( 7.5,13.5));
03227             break;
03228         }
03229         default:
03230             break;
03231     }
03232     p->restore();
03233 }
03234 
03235 
03236 bool OxygenStyle::eventFilter(QObject *obj, QEvent *ev)
03237 {
03238     if (KStyle::eventFilter(obj, ev) )
03239         return true;
03240 
03241     // Track show events for progress bars
03242     if ( _animateProgressBar && qobject_cast<QProgressBar*>(obj) )
03243     {
03244         if ((ev->type() == QEvent::Show) && !animationTimer->isActive())
03245         {
03246             animationTimer->start( 50 );
03247         }
03248     }
03249 
03250     if (QToolBar *t = qobject_cast<QToolBar*>(obj))
03251     {
03252         switch(ev->type()) {
03253             case QEvent::Show:
03254             case QEvent::Resize: {
03255                 int x, y, w, h;
03256                 t->rect().getRect(&x, &y, &w, &h);
03257                 QRegion reg(x+4, y, w-8, h);
03258                 reg += QRegion(x, y+4, w, h-8);
03259                 reg += QRegion(x+2, y+1, w-4, h-2);
03260                 reg += QRegion(x+1, y+2, w-2, h-4);
03261                 if(t->mask() != reg)
03262                     t->setMask(reg);
03263                 return false;
03264             }
03265             default:
03266                 return false;
03267         }
03268     }
03269 
03270     if (QMenu *m = qobject_cast<QMenu*>(obj))
03271     {
03272         switch(ev->type()) {
03273         case QEvent::Show:
03274         case QEvent::Resize: {
03275             int x, y, w, h;
03276             m->rect().getRect(&x, &y, &w, &h);
03277             QRegion reg(x+4, y, w-8, h);
03278             reg += QRegion(x, y+4, w, h-8);
03279             reg += QRegion(x+2, y+1, w-4, h-2);
03280             reg += QRegion(x+1, y+2, w-2, h-4);
03281             if(m->mask() != reg)
03282                 m->setMask(reg);
03283             return false;
03284         }
03285         case QEvent::Paint:
03286         {
03287             QPainter p(m);
03288             QPaintEvent *e = (QPaintEvent*)ev;
03289             QRect r = m->rect();
03290             QColor color = m->palette().color(QPalette::Background);
03291             int splitY = qMin(200, 3*r.height()/4);
03292 
03293             p.setClipRegion(e->region());
03294 
03295             QRect upperRect = QRect(0, 0, r.width(), splitY);
03296             QPixmap tile = _helper.verticalGradient(color, splitY);
03297             p.drawTiledPixmap(upperRect, tile);
03298 
03299             QRect lowerRect = QRect(0,splitY, r.width(), r.height() - splitY);
03300             p.fillRect(lowerRect, _helper.backgroundBottomColor(color));
03301             return false;
03302         }
03303         default:
03304             return false;
03305         }
03306     }
03307 
03308     QWidget *widget = static_cast<QWidget*>(obj);
03309     if (widget->inherits("QComboBoxPrivateContainer")) {
03310         switch(ev->type()) {
03311         case QEvent::Show:
03312         case QEvent::Resize: 
03313         {
03314             int x, y, w, h;
03315             widget->rect().getRect(&x, &y, &w, &h);
03316             QRegion reg(x+4, y, w-8, h);
03317             reg += QRegion(x, y+4, w, h-8);
03318             reg += QRegion(x+2, y+1, w-4, h-2);
03319             reg += QRegion(x+1, y+2, w-2, h-4);
03320             if(widget->mask() != reg)
03321                 widget->setMask(reg);
03322             return false;
03323         }
03324         case QEvent::Paint:
03325         {
03326             QPainter p(widget);
03327             _helper.drawFloatFrame(&p, widget->rect(), widget->palette().color(QPalette::Window));
03328         }
03329         default:
03330             return false;
03331         }
03332     }
03333 
03334     if (widget->isWindow() && widget->isVisible()) {
03335         if (ev->type() == QEvent::Paint)
03336         {
03337             QBrush brush = widget->palette().brush(widget->backgroundRole());
03338             // don't use our background if the app requested something else,
03339             // e.g. a pixmap
03340             // TODO - draw our light effects over an arbitrary fill?
03341             if (brush.style() == Qt::SolidPattern) {
03342             }
03343 
03344             if(widget->testAttribute(Qt::WA_StyledBackground) && !widget->testAttribute(Qt::WA_NoSystemBackground))
03345             {
03346                 QPainter p(widget);
03347                 _helper.renderWindowBackground(&p, widget->rect(), widget,widget->window()->palette());
03348             }
03349         }
03350     }
03351 
03352     if (QMdiSubWindow *mw = qobject_cast<QMdiSubWindow*>(obj))
03353     {
03354         if (ev->type() == QEvent::Show || ev->type() == QEvent::Resize || ev->type() == QEvent::WindowStateChange)
03355         {
03356             int x, y, w, h;
03357             mw->rect().getRect(&x, &y, &w, &h);
03358             QRegion reg(x+4, y, w-8, h);
03359             reg += QRegion(x, y+4, w, h-8);
03360             reg += QRegion(x+2, y+1, w-4, h-2);
03361             reg += QRegion(x+1, y+2, w-2, h-4);
03362             if(mw->mask() != reg)
03363                 mw->setMask(reg);
03364             return false;
03365         }
03366     }
03367 
03368     if (QDockWidget*dw = qobject_cast<QDockWidget*>(obj))
03369     {
03370         if (ev->type() == QEvent::Show || ev->type() == QEvent::Resize)
03371         {
03372             int x, y, w, h;
03373             dw->rect().getRect(&x, &y, &w, &h);
03374             QRegion reg(x+4, y, w-8, h);
03375             reg += QRegion(x, y+4, w, h-8);
03376             reg += QRegion(x+2, y+1, w-4, h-2);
03377             reg += QRegion(x+1, y+2, w-2, h-4);
03378             if(dw->mask() != reg)
03379                 dw->setMask(reg);
03380             return false;
03381         }
03382         if (ev->type() == QEvent::Paint)
03383         {
03384             QPainter p(dw);
03385             if(dw->isWindow())
03386             {
03387                 _helper.drawFloatFrame(&p, dw->rect(), dw->palette().color(QPalette::Window));
03388                 return false;
03389             }
03390 
03391             QPixmap pm(dw->rect().size());
03392             pm.fill(Qt::transparent);
03393             QPainter pp(&pm);
03394             pp.setRenderHints(QPainter::Antialiasing);
03395             pp.translate(.5, .5);
03396             int x,y,w,h;
03397 
03398             dw->rect().getRect(&x, &y, &w, &h);
03399             x = 0; y = 0;
03400             h--; w--;
03401 
03402             QRect rect(x,y,w,h);
03403 
03404             QPalette pal = dw->palette();
03405             QColor color = pal.color(QPalette::Window);
03406             QColor light = _helper.calcLightColor(color);
03407             QColor dark = _helper.calcDarkColor(color);
03408 
03409             dark.setAlpha(200);
03410             light.setAlpha(150);
03411 
03412             // draw left and right border
03413             QLinearGradient lg(rect.topLeft(),rect.topRight());
03414             lg.setColorAt(0.0, light);
03415             lg.setColorAt(0.1, QColor(0,0,0,0));
03416             lg.setColorAt(0.9, QColor(0,0,0,0));
03417             lg.setColorAt(1.0, light);
03418             pp.setPen(QPen(lg,1));
03419             //pp.drawRoundedRect(rect.adjusted(1,1,-1,0),5,5);
03420             pp.drawRoundedRect(rect.adjusted(0,-1,0,-1),4,4);
03421             pp.drawRoundedRect(rect.adjusted(2,1,-2,-2),4,4);
03422 
03423             lg.setColorAt(0.0, dark);
03424             lg.setColorAt(0.1, QColor(0,0,0,0));
03425             lg.setColorAt(0.9, QColor(0,0,0,0));
03426             lg.setColorAt(1.0, dark);
03427             pp.setPen(QPen(lg,1));
03428             pp.setBrush(Qt::NoBrush);
03429             //pp.drawRoundedRect(rect.adjusted(0,0,0,-1),5,5);
03430             pp.drawRoundedRect(rect.adjusted(1,0,-1,-2),4,4);
03431 
03432             // fade
03433             QRect maskr = rect.adjusted(0,h/3,0,0);
03434             pp.setCompositionMode(QPainter::CompositionMode_DestinationIn);
03435             QLinearGradient mask(maskr.topLeft(),maskr.bottomLeft());
03436             mask.setColorAt(0.0,QColor(0,0,0,255));
03437             mask.setColorAt(1.0,QColor(0,0,0,150));
03438             pp.setBrush(mask);
03439             pp.setPen(QPen(mask,1));
03440             pp.drawRect(maskr);
03441             p.drawPixmap(dw->rect().topLeft(),pm);
03442 
03443             // draw top and bottom border
03444             renderSeparator(&p,QRect(x,y,w,2),dw->palette(),Qt::Horizontal);
03445             renderSeparator(&p,QRect(x,y+h-2,w,2),dw->palette(),Qt::Horizontal);
03446             return false;
03447         }
03448     }
03449 
03450     if (QToolBox *tb = qobject_cast<QToolBox*>(obj))
03451     {
03452         if (ev->type() == QEvent::Paint)
03453         {
03454             QRect r = tb->rect();
03455             StyleOptions opts = NoFill;
03456 
03457             QPainter p(tb);
03458             p.setClipRegion(((QPaintEvent*)ev)->region());
03459             renderSlab(&p, r, tb->palette().color(QPalette::Button), opts);
03460         }
03461         return false;
03462     }
03463 
03464     // style HLines/VLines here, as Qt doesn't make them stylable as primitives.
03465     // Qt bug is filed.
03466     if (QFrame *f = qobject_cast<QFrame*>(obj))
03467     {
03468         if (ev->type() == QEvent::Paint) {
03469             if (qobject_cast<KTitleWidget*>(f->parentWidget())) {
03470                 QPainter p(f);
03471                 _helper.renderWindowBackground(&p, f->rect(), f, f->window()->palette());
03472             } else {
03473                 QRect r = f->rect();
03474                 QPainter p(f);
03475                 p.setClipRegion(((QPaintEvent*)ev)->region());
03476                 p.setClipping(false);
03477                 Qt::Orientation o;
03478                 switch(f->frameShape())
03479                 {
03480                     case QFrame::HLine: { o = Qt::Horizontal; break; }
03481                     case QFrame::VLine: { o = Qt::Vertical; break; }
03482                     default: { return false; }
03483                 }
03484                 renderSeparator(&p, r, f->palette(), o);
03485                 return true;
03486             }
03487         }
03488         return false;
03489     }
03490 
03491     return false;
03492 }
03493 
03494 QIcon OxygenStyle::standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *option,
03495                                                const QWidget *widget) const
03496 {
03497     // get button color (unfortunately option and widget might not be set)
03498     QColor buttonColor;
03499     if (option)
03500         buttonColor = option->palette.button().color();
03501     else if (widget)
03502         buttonColor = widget->palette().button().color();
03503     else if (qApp) // might not have a QApplication
03504         buttonColor = qApp->palette().button().color();
03505     else // KCS is always safe
03506         buttonColor = KColorScheme(QPalette::Active, KColorScheme::Button,
03507                                    _config).background().color();
03508 
03509     switch (standardIcon) {
03510         case SP_TitleBarNormalButton:
03511         {
03512             QPixmap realpm(pixelMetric(QStyle::PM_SmallIconSize,0,0), pixelMetric(QStyle::PM_SmallIconSize,0,0));
03513             realpm.fill(QColor(0,0,0,0));
03514             QPixmap pm = _helper.windecoButton(buttonColor, false, 15);
03515             QPainter painter(&realpm);
03516             painter.drawPixmap(1,1,pm);
03517             painter.setRenderHints(QPainter::Antialiasing);
03518             painter.setBrush(Qt::NoBrush);
03519             QLinearGradient lg = _helper.decoGradient(QRect(3,3,11,11), QColor(0,0,0));
03520             painter.setPen(QPen(lg,1.4));
03521             QPointF points[4] = {QPointF(8.5, 6), QPointF(11, 8.5), QPointF(8.5, 11), QPointF(6, 8.5)};
03522             painter.drawPolygon(points, 4);
03523 
03524             return QIcon(realpm);
03525         }
03526 
03527         case SP_TitleBarCloseButton:
03528         case SP_DockWidgetCloseButton:
03529         {
03530             QPixmap realpm(pixelMetric(QStyle::PM_SmallIconSize,0,0), pixelMetric(QStyle::PM_SmallIconSize,0,0));
03531             realpm.fill(QColor(0,0,0,0));
03532             QPixmap pm = _helper.windecoButton(buttonColor, false, 15);
03533             QPainter painter(&realpm);
03534             painter.drawPixmap(1,1,pm);
03535             painter.setRenderHints(QPainter::Antialiasing);
03536             painter.setBrush(Qt::NoBrush);
03537             QLinearGradient lg = _helper.decoGradient(QRect(3,3,11,11), QColor(0,0,0));
03538             painter.setPen(QPen(lg,1.4));
03539             painter.drawLine( QPointF(6.5,6.5), QPointF(11.0,11.0) );
03540             painter.drawLine( QPointF(11.0,6.5), QPointF(6.5,11.0) );
03541 
03542             return QIcon(realpm);
03543         }
03544         default:
03545             return KStyle::standardPixmap(standardIcon, option, widget);
03546     }
03547 }
03548 
03549 QPoint OxygenStyle::handleRTL(const QStyleOption* opt, const QPoint& pos) const
03550 {
03551     return visualPos(opt->direction, opt->rect, pos);
03552 }
03553 
03554 QRect OxygenStyle::handleRTL(const QStyleOption* opt, const QRect& subRect) const
03555 {
03556     return visualRect(opt->direction, opt->rect, subRect);
03557 }
03558 
03559 // kate: indent-width 4; replace-tabs on; tab-width 4; space-indent on;

KStyles

Skip menu "KStyles"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members

API Reference

Skip menu "API Reference"
  • KCMShell
  • KNotify
  • KStyles
  • Nepomuk Daemons
Generated for API Reference by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal