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