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

KDEUI

kstyle.cpp

Go to the documentation of this file.
00001 
00046 #include "kstyle.h"
00047 #include "kstyle.moc"
00048 
00049 #include <QtCore/qalgorithms.h>
00050 #include <QtCore/QCache>
00051 #include <QtCore/QEvent>
00052 #include <QtCore/QVariant>
00053 #include <QtGui/QAbstractItemView>
00054 #include <QtGui/QApplication>
00055 #include <QtGui/QDialogButtonBox>
00056 #include <QtGui/QFormLayout>
00057 #include <QtGui/QIcon>
00058 #include <QtGui/QLabel>
00059 #include <QtGui/QKeyEvent>
00060 #include <QtGui/QPainter>
00061 #include <QtGui/QScrollBar>
00062 #include <QtGui/QStyleOption>
00063 
00064 #include <kcomponentdata.h>
00065 #include <kglobal.h>
00066 #include <kconfiggroup.h>
00067 
00068 #include "kglobalsettings.h"
00069 
00070 #include <QDebug>
00071 
00072 //### FIXME: Who to credit these to?
00073 static const qint32 u_arrow[]={-1,-3, 0,-3, -2,-2, 1,-2, -3,-1, 2,-1, -4,0, 3,0, -4,1, 3,1};
00074 static const qint32 d_arrow[]={-4,-2, 3,-2, -4,-1, 3,-1, -3,0, 2,0, -2,1, 1,1, -1,2, 0,2};
00075 static const qint32 l_arrow[]={-3,-1, -3,0, -2,-2, -2,1, -1,-3, -1,2, 0,-4, 0,3, 1,-4, 1,3};
00076 static const qint32 r_arrow[]={-2,-4, -2,3, -1,-4, -1,3, 0,-3, 0,2, 1,-2, 1,1, 2,-1, 2,0};
00077 #define QCOORDARRLEN(x) sizeof(x)/(sizeof(qint32)*2)
00078 
00079 
00088 // ----------------------------------------------------------------------------
00089 
00090 
00091 // For item view selections
00092 struct SelectionTiles
00093 {
00094     QPixmap left, center, right;
00095 };
00096 
00097 
00098 // ----------------------------------------------------------------------------
00099 
00100 static const QStyle::StyleHint SH_KCustomStyleElement = (QStyle::StyleHint)0xff000001;
00101 static const int X_KdeBase = 0xff000000;
00102 
00103 class KStylePrivate
00104 {
00105 public:
00106     KStylePrivate();
00107     QCache<quint64, SelectionTiles> selectionCache;
00108     KComponentData m_componentData;
00109 
00110     QHash<QString, int> styleElements;
00111     int hintCounter, controlCounter, subElementCounter;
00112 };
00113 
00114 KStylePrivate::KStylePrivate() : m_componentData()
00115 {
00116     if(KGlobal::hasMainComponent())
00117     {
00118         m_componentData = KGlobal::mainComponent();
00119     } else
00120     {
00121         QString name(QApplication::applicationName());
00122 
00123         if(name.isEmpty())
00124             name=qAppName();
00125 
00126         if(name.isEmpty())
00127             name="KStyle";
00128 
00129         m_componentData = KComponentData(name.toLatin1(), name.toLatin1(), KComponentData::SkipMainComponentRegistration);
00130     }
00131     selectionCache.setMaxCost(10);
00132     controlCounter = subElementCounter = X_KdeBase;
00133     hintCounter = X_KdeBase+1; //sic! X_KdeBase is covered by SH_KCustomStyleElement
00134 }
00135 
00136 
00137 // ----------------------------------------------------------------------------
00138 
00139 
00140 KStyle::KStyle() : clickedLabel(0), d(new KStylePrivate)
00141 {
00142     //Set up some default metrics...
00143     setWidgetLayoutProp(WT_Generic, Generic::DefaultFrameWidth, 2);
00144     setWidgetLayoutProp(WT_Generic, Generic::DefaultLayoutSpacing, 6);
00145     setWidgetLayoutProp(WT_Generic, Generic::DefaultLayoutMargin, 9);
00146 
00147     setWidgetLayoutProp(WT_PushButton, PushButton::ContentsMargin, 5);
00148     setWidgetLayoutProp(WT_PushButton, PushButton::FocusMargin,    3);
00149     setWidgetLayoutProp(WT_PushButton, PushButton::PressedShiftHorizontal, 2);
00150     setWidgetLayoutProp(WT_PushButton, PushButton::PressedShiftVertical,   2);
00151     setWidgetLayoutProp(WT_PushButton, PushButton::MenuIndicatorSize,      8);
00152     setWidgetLayoutProp(WT_PushButton, PushButton::TextToIconSpace,        6);
00153 
00154     setWidgetLayoutProp(WT_Splitter, Splitter::Width, 6); //As KStyle in KDE3
00155 
00156     setWidgetLayoutProp(WT_CheckBox, CheckBox::Size, 16);
00157     setWidgetLayoutProp(WT_CheckBox, CheckBox::BoxTextSpace, 6);
00158     setWidgetLayoutProp(WT_CheckBox, CheckBox::NoLabelFocusMargin, 1);
00159 
00160     setWidgetLayoutProp(WT_RadioButton, RadioButton::Size, 16);
00161     setWidgetLayoutProp(WT_RadioButton, RadioButton::BoxTextSpace, 6);
00162 
00163     setWidgetLayoutProp(WT_DockWidget, DockWidget::TitleTextColor,
00164                         ColorMode(QPalette::HighlightedText));
00165     setWidgetLayoutProp(WT_DockWidget, DockWidget::TitleMargin, 2);
00166     setWidgetLayoutProp(WT_DockWidget, DockWidget::FrameWidth, 3);
00167     setWidgetLayoutProp(WT_DockWidget, DockWidget::SeparatorExtent, 6);
00168 
00169     setWidgetLayoutProp(WT_ProgressBar, ProgressBar::GrooveMargin,  2);
00170     setWidgetLayoutProp(WT_ProgressBar, ProgressBar::SideTextSpace, 3); //(Matches QCommonStyle)
00171     setWidgetLayoutProp(WT_ProgressBar, ProgressBar::MaxBusyIndicatorSize, 10000);
00172     setWidgetLayoutProp(WT_ProgressBar, ProgressBar::BusyIndicatorSize,    10);
00173     setWidgetLayoutProp(WT_ProgressBar, ProgressBar::Precision,            1);
00174 
00175     setWidgetLayoutProp(WT_MenuBar, MenuBar::ItemSpacing,   14);
00176     setWidgetLayoutProp(WT_MenuBar, MenuBar::Margin,        2);
00177     setWidgetLayoutProp(WT_MenuBar, MenuBar::Margin + Left,  4);
00178     setWidgetLayoutProp(WT_MenuBar, MenuBar::Margin + Right, 4);
00179 
00180     setWidgetLayoutProp(WT_MenuBarItem, MenuBarItem::Margin, 1);
00181 
00182     setWidgetLayoutProp(WT_Menu, Menu::FrameWidth, 1);
00183     setWidgetLayoutProp(WT_Menu, Menu::Margin,     3);
00184     setWidgetLayoutProp(WT_Menu, Menu::ScrollerHeight, 10);
00185     setWidgetLayoutProp(WT_Menu, Menu::TearOffHeight, 10);
00186 
00187     setWidgetLayoutProp(WT_MenuItem, MenuItem::CheckWidth, 12);
00188     setWidgetLayoutProp(WT_MenuItem, MenuItem::CheckSpace, 3);
00189     setWidgetLayoutProp(WT_MenuItem, MenuItem::IconWidth, 12);
00190     setWidgetLayoutProp(WT_MenuItem, MenuItem::IconSpace, 3);
00191     setWidgetLayoutProp(WT_MenuItem, MenuItem::ArrowWidth, 11);
00192     setWidgetLayoutProp(WT_MenuItem, MenuItem::ArrowSpace, 3);
00193     setWidgetLayoutProp(WT_MenuItem, MenuItem::Margin,     2);
00194     setWidgetLayoutProp(WT_MenuItem, MenuItem::SeparatorHeight, 0); //the margins give enough rooms
00195     setWidgetLayoutProp(WT_MenuItem, MenuItem::MinHeight,  16);
00196     setWidgetLayoutProp(WT_MenuItem, MenuItem::TextColor, ColorMode(QPalette::Text));
00197     setWidgetLayoutProp(WT_MenuItem, MenuItem::ActiveTextColor, ColorMode(QPalette::HighlightedText));
00198     setWidgetLayoutProp(WT_MenuItem, MenuItem::DisabledTextColor,       ColorMode(QPalette::Text));
00199     setWidgetLayoutProp(WT_MenuItem, MenuItem::ActiveDisabledTextColor, ColorMode(QPalette::Text));
00200 
00201     //KDE default is single top button, double bottom one
00202     setWidgetLayoutProp(WT_ScrollBar, ScrollBar::DoubleTopButton, 0);
00203     setWidgetLayoutProp(WT_ScrollBar, ScrollBar::DoubleBotButton, 1);
00204     setWidgetLayoutProp(WT_ScrollBar, ScrollBar::SingleButtonHeight, 16);
00205     setWidgetLayoutProp(WT_ScrollBar, ScrollBar::DoubleButtonHeight, 32);
00206     setWidgetLayoutProp(WT_ScrollBar, ScrollBar::BarWidth, 16);
00207     setWidgetLayoutProp(WT_ScrollBar, ScrollBar::ArrowColor,
00208                             ColorMode(ColorMode::BWAutoContrastMode, QPalette::Button));
00209     setWidgetLayoutProp(WT_ScrollBar, ScrollBar::ActiveArrowColor,
00210                             ColorMode(ColorMode::BWAutoContrastMode, QPalette::ButtonText));
00211 
00212     setWidgetLayoutProp(WT_TabBar, TabBar::TabContentsMargin, 6);
00213     setWidgetLayoutProp(WT_TabBar, TabBar::TabFocusMargin, 3);
00214     setWidgetLayoutProp(WT_TabBar, TabBar::TabOverlap, 0);
00215     setWidgetLayoutProp(WT_TabBar, TabBar::BaseHeight, 2);
00216     setWidgetLayoutProp(WT_TabBar, TabBar::BaseOverlap, 2);
00217     setWidgetLayoutProp(WT_TabBar, TabBar::ScrollButtonWidth, 10);
00218     setWidgetLayoutProp(WT_TabBar, TabBar::TabTextToIconSpace, 6);
00219 
00220     setWidgetLayoutProp(WT_TabWidget, TabWidget::ContentsMargin, 2);
00221 
00222     setWidgetLayoutProp(WT_Tree, Tree::MaxExpanderSize, 9);
00223 
00224     setWidgetLayoutProp(WT_Slider, Slider::HandleThickness, 20);
00225     setWidgetLayoutProp(WT_Slider, Slider::HandleLength, 16);
00226 
00227     setWidgetLayoutProp(WT_SpinBox, SpinBox::FrameWidth, 1);
00228     setWidgetLayoutProp(WT_SpinBox, SpinBox::ButtonWidth, 16);
00229     setWidgetLayoutProp(WT_SpinBox, SpinBox::ButtonSpacing, 1);
00230     setWidgetLayoutProp(WT_SpinBox, SpinBox::ButtonMargin+Right, 1);
00231     setWidgetLayoutProp(WT_SpinBox, SpinBox::ButtonMargin+Top, 1);
00232     setWidgetLayoutProp(WT_SpinBox, SpinBox::ButtonMargin+Bot, 1);
00233 
00234     setWidgetLayoutProp(WT_ComboBox, ComboBox::FrameWidth, 1);
00235     setWidgetLayoutProp(WT_ComboBox, ComboBox::ButtonWidth, 16);
00236     setWidgetLayoutProp(WT_ComboBox, ComboBox::ButtonMargin+Right, 1);
00237     setWidgetLayoutProp(WT_ComboBox, ComboBox::ButtonMargin+Top, 1);
00238     setWidgetLayoutProp(WT_ComboBox, ComboBox::ButtonMargin+Bot, 1);
00239     setWidgetLayoutProp(WT_ComboBox, ComboBox::FocusMargin, 1);
00240 
00241     setWidgetLayoutProp(WT_Header, Header::ContentsMargin, 3);
00242     setWidgetLayoutProp(WT_Header, Header::TextToIconSpace, 3);
00243     setWidgetLayoutProp(WT_Header, Header::MarkSize, 9);
00244 
00245     setWidgetLayoutProp(WT_GroupBox, GroupBox::FrameWidth, 2);
00246     setWidgetLayoutProp(WT_GroupBox, GroupBox::TextAlignTop, false);
00247     setWidgetLayoutProp(WT_GroupBox, GroupBox::TitleTextColor, ColorMode(QPalette::Text));
00248 
00249     setWidgetLayoutProp(WT_ToolBar, ToolBar::HandleExtent, 6);
00250     setWidgetLayoutProp(WT_ToolBar, ToolBar::SeparatorExtent, 6);
00251     setWidgetLayoutProp(WT_ToolBar, ToolBar::ExtensionExtent, 10);
00252     setWidgetLayoutProp(WT_ToolBar, ToolBar::FrameWidth, 2);
00253     setWidgetLayoutProp(WT_ToolBar, ToolBar::ItemSpacing, 3);
00254     setWidgetLayoutProp(WT_ToolBar, ToolBar::ItemMargin, 1);
00255 
00256     setWidgetLayoutProp(WT_ToolButton, ToolButton::ContentsMargin, 5);
00257     setWidgetLayoutProp(WT_ToolButton, ToolButton::FocusMargin,    3);
00258     setWidgetLayoutProp(WT_ToolButton, ToolButton::MenuIndicatorSize, 11);
00259 
00260     setWidgetLayoutProp(WT_ToolBoxTab, ToolBoxTab::Margin, 0);
00261 
00262     setWidgetLayoutProp(WT_Window, Window::TitleTextColor, ColorMode(QPalette::HighlightedText));
00263     setWidgetLayoutProp(WT_Window, Window::TitleHeight, 20);
00264     setWidgetLayoutProp(WT_Window, Window::TitleMargin, 2);
00265     setWidgetLayoutProp(WT_Window, Window::NoTitleFrame, 0);
00266     setWidgetLayoutProp(WT_Window, Window::ButtonWidth, 16);
00267     setWidgetLayoutProp(WT_Window, Window::ButtonSpace, 2);
00268     setWidgetLayoutProp(WT_Window, Window::ButtonToTextSpace, 3);
00269 }
00270 
00271 KStyle::~KStyle()
00272 {
00273     // this is just for stupid msvc compiler to force the creation of
00274     // DoubleButtonOption::defaultOption() inside kstyle lib
00275     // hope the optimizer won't throw it away
00276     const DoubleButtonOption* bOpt = extractOption<const DoubleButtonOption*>(NULL);
00277     Q_UNUSED(bOpt)
00278 #ifdef __GNUC__
00279 #warning "mem leak: need to delete bOpt"
00280 #endif
00281     delete d;
00282 }
00283 
00284 
00285 /*
00286     Custom Style Element runtime extension:
00287     We reserve one StyleHint to let the effective style inform widgets whether it supports certain
00288     string based style elements.
00289     As this could lead to number conflicts (i.e. an app utilizing one of the hints itself for other
00290     purposes) there're various safety mechanisms to rule out such interference.
00291 
00292     1) It's most unlikely that a widget in some 3rd party app will accidentally call a general
00293     QStyle/KStyle styleHint() or draw*() and (unconditionally) expect a valid return, however:
00294     a. The StyleHint is not directly above Qt's custom base, assuming most 3rd party apps would
00295     - in case - make use of such
00296     b. In order to be accepted, the StyleHint query must pass a widget with a perfectly matching
00297     name, containing the typical element prefix ("CE_", etc.) and being supported by the current style
00298     c. Instead using Qt's fragile qstyleoption_cast on the QStyleOption provided to the StyleHint
00299     query, try to dump out a string and hope for the best, we now manipulate the widgets objectName().
00300     Plain Qt dependent widgets can do that themselves and if a widget uses KStyle's convenience access
00301     functions, it won't notice this at all
00302 
00303     2) The key problem is that a common KDE widget will run into an apps custom style which will then
00304     falsely respond to the styleHint() call with an invalid value.
00305     To prevent this, supporting styles *must* set a Q_CLASSINFO "X-KDE-CustomElements".
00306 
00307     3) If any of the above traps snaps, the returned id is 0 - the QStyle default, indicating
00308     that this element is not supported by the current style.
00309 
00310     Obviously, this contains the "diminished clean" action to (temporarily) manipulate the
00311     objectName() of a const QWidget* - but this happens completely inside KStyle or the widget, if
00312     it does not make use of KStyles static convenience functions.
00313     My biggest worry here would be, that in a multithreaded environment a thread (usually not being
00314     owner of the widget) does something crucially relying on the widgets name property...
00315     This however would also have to happen during the widget construction or stylechanges, when
00316     the functions in doubt will typically be called.
00317     So this is imho unlikely causing any trouble, ever.
00318 */
00319 
00320 /*
00321     The functions called by the real style implementation to add support for a certain element.
00322     Checks for well-formed string (containing the element prefix) and returns 0 otherwise.
00323     Checks whether the element is already supported or inserts it otherwise; Returns the proper id
00324     NOTICE: We could check for "X-KDE-CustomElements", but this would bloat style start up times
00325     (if they e.g. register 100 elements or so)
00326 */
00327 
00328 
00329 static inline int newStyleElement(const QString &element, const char *check, int &counter, QHash<QString, int> *elements)
00330 {
00331     if (!element.contains(check))
00332         return 0;
00333     int id = elements->value(element, 0);
00334     if (!id) {
00335         ++counter;
00336         id = counter;
00337         elements->insert(element, id);
00338     }
00339     return id;
00340 }
00341 
00342 QStyle::StyleHint KStyle::newStyleHint(const QString &element)
00343 {
00344     return (StyleHint)newStyleElement(element, "SH_", d->hintCounter, &d->styleElements);
00345 }
00346 
00347 QStyle::ControlElement KStyle::newControlElement(const QString &element)
00348 {
00349     return (ControlElement)newStyleElement(element, "CE_", d->controlCounter, &d->styleElements);
00350 }
00351 
00352 KStyle::SubElement KStyle::newSubElement(const QString &element)
00353 {
00354     return (SubElement)newStyleElement(element, "SE_", d->subElementCounter, &d->styleElements);
00355 }
00356 
00357 
00358 QString KStyle::defaultStyle()
00359 {
00360 #ifdef Q_WS_X11
00361     return QString("oxygen");
00362 #else
00363     return QString(); // native style
00364 #endif
00365 }
00366 
00367 /*
00368     The functions called by widgets that request custom element support, passed to the effective style.
00369     Collected in a static inline function due to similarity.
00370 */
00371 
00372 static inline int customStyleElement(QStyle::StyleHint type, const QString &element, QWidget *widget)
00373 {
00374     if (!widget || widget->style()->metaObject()->indexOfClassInfo("X-KDE-CustomElements") < 0)
00375         return 0;
00376 
00377     const QString originalName = widget->objectName();
00378     widget->setObjectName(element);
00379     const int id = widget->style()->styleHint(type, 0, widget);
00380     widget->setObjectName(originalName);
00381     return id;
00382 }
00383 
00384 QStyle::StyleHint KStyle::customStyleHint(const QString &element, const QWidget *widget)
00385 {
00386     return (StyleHint) customStyleElement(SH_KCustomStyleElement, element, const_cast<QWidget*>(widget));
00387 }
00388 
00389 QStyle::ControlElement KStyle::customControlElement(const QString &element, const QWidget *widget)
00390 {
00391     return (ControlElement) customStyleElement(SH_KCustomStyleElement, element, const_cast<QWidget*>(widget));
00392 }
00393 
00394 QStyle::SubElement KStyle::customSubElement(const QString &element, const QWidget *widget)
00395 {
00396     return (SubElement) customStyleElement(SH_KCustomStyleElement, element, const_cast<QWidget*>(widget));
00397 }
00398 
00399 void KStyle::polish(QWidget *w)
00400 {
00401     if (qobject_cast<QLabel*>(w) ) {
00402         w->installEventFilter(this);
00403     }
00404 
00405     // Enable hover effects in all itemviews
00406     if (QAbstractItemView *itemView = qobject_cast<QAbstractItemView*>(w) ) {
00407         itemView->viewport()->setAttribute(Qt::WA_Hover);
00408     }
00409 
00410     QCommonStyle::polish(w);
00411 }
00412 void KStyle::unpolish(QWidget *w)
00413 {
00414     if (qobject_cast<QLabel*>(w) ) {
00415         w->removeEventFilter(this);
00416     }
00417 
00418     QCommonStyle::unpolish(w);
00419 }
00420 void KStyle::polish(QApplication *a)
00421 {
00422     QCommonStyle::polish(a);
00423 }
00424 void KStyle::unpolish(QApplication *a)
00425 {
00426     QCommonStyle::unpolish(a);
00427 }
00428 void KStyle::polish(QPalette &pal)
00429 {
00430     QCommonStyle::polish(pal);
00431 }
00432 QRect KStyle::itemTextRect(const QFontMetrics &fm, const QRect &r,
00433                        int flags, bool enabled,
00434                        const QString &text) const
00435 {
00436     return QCommonStyle::itemTextRect(fm, r, flags, enabled, text);
00437 }
00438 QRect KStyle::itemPixmapRect(const QRect &r, int flags, const QPixmap &pixmap) const
00439 {
00440     return QCommonStyle::itemPixmapRect(r, flags, pixmap);
00441 }
00442 void KStyle::drawItemText(QPainter *painter, const QRect &rect,
00443                       int flags, const QPalette &pal, bool enabled,
00444                       const QString &text, QPalette::ColorRole textRole) const
00445 {
00446     QCommonStyle::drawItemText(painter, rect, flags, pal, enabled,
00447                                text, textRole);
00448 }
00449 void KStyle::drawItemPixmap(QPainter *painter, const QRect &rect,
00450                             int alignment, const QPixmap &pixmap) const
00451 {
00452     QCommonStyle::drawItemPixmap(painter, rect, alignment, pixmap);
00453 }
00454 QPalette KStyle::standardPalette() const
00455 {
00456     return KGlobalSettings::createApplicationPalette(
00457         KSharedConfig::openConfig(d->m_componentData));
00458 }
00459 QPixmap KStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt,
00460                                const QWidget *widget) const
00461 {
00462     return QCommonStyle::standardPixmap(standardPixmap, opt, widget);
00463 }
00464 QPixmap KStyle::generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap,
00465                                     const QStyleOption *opt) const
00466 {
00467     return QCommonStyle::generatedIconPixmap(iconMode, pixmap, opt);
00468 }
00469 
00470 void KStyle::drawInsideRect(QPainter* p, const QRect& r) const
00471 {
00472     p->drawRect(r.x(), r.y(), r.width() - 1, r.height() - 1);
00473 }
00474 
00475 QRect KStyle::centerRect(const QRect &in, int w, int h) const
00476 {
00477     return QRect(in.x() + (in.width() - w)/2, in.y() + (in.height() - h)/2, w, h);
00478 }
00479 
00480 QRect KStyle::centerRect(const QRect &in, const QSize &size) const
00481 {
00482     return centerRect(in, size.width(), size.height());
00483 }
00484 
00485 
00486 
00487 void KStyle::drawKStylePrimitive(WidgetType widgetType, int primitive,
00488                                  const QStyleOption* opt,
00489                                  const QRect &r, const QPalette &pal,
00490                                  State flags, QPainter* p,
00491                                  const QWidget* widget,
00492                                  KStyle::Option* kOpt) const
00493 {
00494     switch (widgetType)
00495     {
00496         case WT_Tree:
00497         {
00498         switch (primitive)
00499         {
00500             case Tree::VerticalBranch:
00501             case Tree::HorizontalBranch:
00502                 //### FIXME: set sane color.
00503                 p->fillRect(r, QBrush(Qt::Dense4Pattern));
00504                 return;
00505             case Tree::ExpanderOpen:
00506             case Tree::ExpanderClosed:
00507             {
00508                 p->setPen(pal.text().color());
00509                 drawInsideRect(p, r); //the border.
00510                 int signLineSize = r.width()/4;
00511                 p->drawLine(r.center().x() - signLineSize, r.center().y(),
00512                             r.center().x() + signLineSize, r.center().y()); //-
00513                 if (primitive == Tree::ExpanderClosed) //vertical line of +
00514                     p->drawLine(r.center().x(), r.center().y() - signLineSize,
00515                                 r.center().x(), r.center().y() + signLineSize);
00516                 return;
00517             }
00518             default:
00519                 break;
00520         }
00521 
00522         break;
00523         }
00524 
00525         case WT_SpinBox:
00526         {
00527         switch (primitive)
00528         {
00529             case SpinBox::PlusSymbol:
00530             case SpinBox::MinusSymbol:
00531             {
00532                 p->setPen( pal.buttonText().color() );
00533 
00534                 int l = qMin( r.width()-2, r.height()-2 );
00535                 QPoint c = r.center();
00536 
00537                 p->drawLine( c.x()-l/2, c.y(), c.x()+l/2, c.y() );
00538                 if (primitive == SpinBox::PlusSymbol ) {
00539                     p->drawLine( c.x(), c.y()-l/2, c.x(), c.y()+l/2 );
00540                 }
00541 
00542                 return;
00543             }
00544             default:
00545                 break;
00546         }
00547 
00548         break;
00549         }
00550 
00551         case WT_GroupBox:
00552         {
00553             if (primitive == GroupBox::FlatFrame) {
00554                 QPen oldPen = p->pen();
00555                 p->setPen(pal.color(QPalette::WindowText) );
00556                 p->drawLine(r.topLeft(), r.topRight() );
00557                 p->setPen(oldPen);
00558             }
00559 
00560             break;
00561         }
00562 
00563         case WT_ToolBoxTab:
00564         {
00565             if (primitive == ToolBoxTab::Panel) {
00566                 drawKStylePrimitive(WT_ToolButton, ToolButton::Panel, opt, r, pal, flags, p, widget);
00567             }
00568 
00569             break;
00570         }
00571 
00572         case WT_DockWidget:
00573         {
00574             switch (primitive)
00575             {
00576                 case DockWidget::TitlePanel:
00577                     p->fillRect(r, pal.color(QPalette::Highlight) );
00578                     return;
00579 
00580                 case DockWidget::SeparatorHandle:
00581                     return;
00582 
00583                 default:
00584                     break;
00585             }
00586 
00587             break;
00588         }
00589 
00590         case WT_Window:
00591         {
00592             switch (primitive)
00593             {
00594                 case Window::TitlePanel:
00595                     p->fillRect(r, pal.color(QPalette::Highlight) );
00596                     return;
00597 
00598                 case Window::ButtonMenu:
00599                 {
00600                     KStyle::TitleButtonOption* tbkOpts =
00601                             extractOption<KStyle::TitleButtonOption*>(kOpt);
00602                     if (!tbkOpts->icon.isNull()) {
00603                         tbkOpts->icon.paint(p, r);
00604                     } else {
00605                         QStyleOption tool(0);
00606                         tool.palette = pal;
00607                         // TODO: give it a nice KDE logo.
00608                         QPixmap pm = standardPixmap(SP_TitleBarMenuButton, &tool, widget);
00609                         tool.rect = r;
00610                         p->save();
00611                         drawItemPixmap(p, r, Qt::AlignCenter, pm);
00612                         p->restore();
00613                     }
00614                     return;
00615                 }
00616 
00617                 case Window::ButtonMin:
00618                 case Window::ButtonMax:
00619                 case Window::ButtonRestore:
00620                 case Window::ButtonClose:
00621                 case Window::ButtonShade:
00622                 case Window::ButtonUnshade:
00623                 case Window::ButtonHelp:
00624                 {
00625                     KStyle::TitleButtonOption* tbkOpts =
00626                             extractOption<KStyle::TitleButtonOption*>(kOpt);
00627                     State bflags = flags;
00628                     bflags &= ~State_Sunken;
00629                     if (tbkOpts->active)
00630                         bflags |= State_Sunken;
00631                     drawKStylePrimitive(WT_ToolButton, ToolButton::Panel, opt, r, pal, bflags, p, widget);
00632                     return;
00633                 }
00634             }
00635 
00636             break;
00637         }
00638 
00639         case WT_TabBar:
00640         {
00641             // For vertical text fallback, provide the generic text implementation
00642             // a transformed rotated painter, with rect swizzled appropriately
00643             if (primitive == TabBar::EastText || primitive == TabBar::WestText)
00644             {
00645                 QTransform tr;
00646 
00647                 if (primitive == TabBar::WestText)
00648                 {
00649                     tr.translate(r.x(), r.height() + r.y());
00650                     tr.rotate(-90);
00651                 }
00652                 else
00653                 {
00654                     tr.translate(r.width() + r.x(), r.y());
00655                     tr.rotate(90);
00656                 }
00657 
00658                 p->save();
00659                 p->setTransform(tr, true);
00660                 drawKStylePrimitive(WT_TabBar, Generic::Text, opt,
00661                     QRect(0, 0, r.height(), r.width()), pal, flags, p, widget, kOpt);
00662                 p->restore();
00663             }
00664             break;
00665         }
00666 
00667         default:
00668             break;
00669     }
00670 
00671     if (primitive == Generic::Text)
00672     {
00673         KStyle::TextOption* textOpts = extractOption<KStyle::TextOption*>(kOpt);
00674 
00675         //### debug
00676         //p->setPen(Qt::green);
00677         //drawInsideRect(p, r);
00678 
00679         QColor col = textOpts->color.color(pal);
00680         QPen   old = p->pen();
00681         p->setPen(col);
00682         drawItemText(p, r, Qt::AlignVCenter | Qt::TextShowMnemonic | textOpts->hAlign, pal, flags & State_Enabled,
00683                         textOpts->text);
00684         p->setPen(old);
00685     }
00686     else if (primitive == Generic::Icon)
00687     {
00688         KStyle::IconOption* iconOpts = extractOption<KStyle::IconOption*>(kOpt);
00689         QIcon::Mode mode;
00690 
00691         // Select the correct icon from the iconset
00692         if (flags & State_Enabled)
00693             if (iconOpts->active)
00694                 mode = QIcon::Active;
00695             else
00696                 mode = QIcon::Normal;
00697         else
00698             mode = QIcon::Disabled;
00699 
00700         QSize size = iconOpts->size;
00701         if(!size.isValid())
00702             size = QSize(pixelMetric(PM_SmallIconSize), pixelMetric(PM_SmallIconSize));
00703         QPixmap icon = iconOpts->icon.pixmap(size, mode);
00704         p->drawPixmap(centerRect(r, icon.size()), icon);
00705     }
00706     else if (primitive == Generic::FocusIndicator)
00707     {
00708         QPen pen;
00709         pen.setWidth(0);
00710         pen.setStyle(Qt::DotLine);
00711         p->setPen(pen);
00712         drawInsideRect(p, r);
00713     }
00714     else if (primitive >= Generic::ArrowUp && primitive <= Generic::ArrowLeft)
00715     {
00716         //### FIXME: Helper for these sorts of things, as Keramik has virtually
00717         //identical code!
00718         KStyle::ColorOption* colorOpt   = extractOption<KStyle::ColorOption*>(kOpt);
00719         QColor               arrowColor = colorOpt->color.color(pal);
00720 
00721         QPolygon poly;
00722 
00723         switch (primitive)
00724         {
00725             case Generic::ArrowUp:
00726                 poly.setPoints(QCOORDARRLEN(u_arrow), u_arrow);
00727                 break;
00728 
00729             case Generic::ArrowDown:
00730                 poly.setPoints(QCOORDARRLEN(d_arrow), d_arrow);
00731                 break;
00732 
00733             case Generic::ArrowLeft:
00734                 poly.setPoints(QCOORDARRLEN(l_arrow), l_arrow);
00735                 break;
00736 
00737             default:
00738                 poly.setPoints(QCOORDARRLEN(r_arrow), r_arrow);
00739         }
00740 
00741         if ( flags & State_Enabled )
00742         {
00743             //CHECKME: Why is the -1 needed?
00744             poly.translate(r.x() + r.width()/2 - 1, r.y() + r.height()/2);
00745 
00746             p->setPen(arrowColor);
00747             p->drawPolygon(poly);
00748         }
00749         else
00750         {
00751             //Disabled ones ignore color parameter
00752             poly.translate(r.x() + r.width()/2, r.y() + r.height()/2 + 1);
00753             p->setPen( pal.color( QPalette::Light ) );
00754             p->drawPolygon(poly);
00755             poly.translate(-1,-1);
00756             p->setPen(pal.mid().color());
00757             p->drawPolygon(poly);
00758         }
00759 
00760     }
00761 #if 0 //Reenable if you need a debug aid
00762     else
00763     {
00764         p->setPen(Qt::red);
00765         drawInsideRect(p, r);
00766     }
00767 #endif
00768 }
00769 
00770 
00771 void KStyle::setWidgetLayoutProp(WidgetType widget, int metric, int value)
00772 {
00773     if (metrics.size() <= widget)
00774         metrics.resize(widget + 1);
00775 
00776     QVector<int>& widgetMetrics = metrics[widget];
00777     if (widgetMetrics.size() <= metric)
00778         widgetMetrics.resize(metric + 1);
00779 
00780     widgetMetrics[metric] = value;
00781 }
00782 
00783 int KStyle::widgetLayoutProp(WidgetType widget, int metric,
00784                              const QStyleOption* opt,
00785                              const QWidget* w ) const
00786 {
00787     Q_UNUSED(opt)
00788     Q_UNUSED(w)
00789 
00790     if (metrics.size() <= widget)
00791         return 0;
00792 
00793     const QVector<int>& widgetMetrics = metrics[widget];
00794     if (widgetMetrics.size() <= metric)
00795         return 0;
00796 
00797     return widgetMetrics[metric];
00798 }
00799 
00800 QSize KStyle::expandDim(const QSize& orig, WidgetType wt, int baseMarginMetric,
00801                         const QStyleOption* opt, const QWidget* w, bool rotated) const
00802 {
00803     int addWidth =  2*widgetLayoutProp(wt, baseMarginMetric + MainMargin, opt, w) +
00804                     widgetLayoutProp(wt, baseMarginMetric + Left, opt, w) +
00805                     widgetLayoutProp(wt, baseMarginMetric + Right, opt, w);
00806 
00807     int addHeight = 2*widgetLayoutProp(wt, baseMarginMetric + MainMargin, opt, w) +
00808                     widgetLayoutProp(wt, baseMarginMetric + Top, opt, w) +
00809                     widgetLayoutProp(wt, baseMarginMetric + Bot, opt, w);
00810 
00811     return QSize(orig.width() + (rotated? addHeight: addWidth), 
00812                  orig.height() + (rotated? addWidth: addHeight));
00813 }
00814 
00815 QRect KStyle::insideMargin(const QRect &orig, WidgetType wt,
00816                            int baseMarginMetric,
00817                            const QStyleOption* opt, const QWidget* w) const
00818 {
00819     int x1 = orig.topLeft().x();
00820     int y1 = orig.topLeft().y();
00821     int x2 = orig.bottomRight().x();
00822     int y2 = orig.bottomRight().y();
00823 
00824     x1 += widgetLayoutProp(wt, baseMarginMetric + MainMargin, opt, w);
00825     x1 += widgetLayoutProp(wt, baseMarginMetric + Left, opt, w);
00826 
00827     y1 += widgetLayoutProp(wt, baseMarginMetric + MainMargin, opt, w);
00828     y1 += widgetLayoutProp(wt, baseMarginMetric + Top, opt, w);
00829 
00830     x2 -= widgetLayoutProp(wt, baseMarginMetric + MainMargin, opt, w);
00831     x2 -= widgetLayoutProp(wt, baseMarginMetric + Right, opt, w);
00832 
00833     y2 -= widgetLayoutProp(wt, baseMarginMetric + MainMargin, opt, w);
00834     y2 -= widgetLayoutProp(wt, baseMarginMetric + Bot, opt, w);
00835 
00836     return QRect(x1, y1, x2 - x1 + 1, y2 - y1 + 1);
00837 }
00838 
00839 QRect KStyle::handleRTL(const QStyleOption* opt, const QRect& subRect) const
00840 {
00841     return visualRect(opt->direction, opt->rect, subRect);
00842 }
00843 
00844 QPoint KStyle::handleRTL(const QStyleOption* opt, const QPoint& pos) const
00845 {
00846     return visualPos(opt->direction, opt->rect, pos);
00847 }
00848 
00849 void KStyle::drawPrimitive(PrimitiveElement elem, const QStyleOption* option, QPainter* painter, const QWidget* widget) const
00850 {
00851     //Extract the stuff we need out of the option
00852     State flags = option->state;
00853     QRect      r     = option->rect;
00854     QPalette   pal   = option->palette;
00855 
00856     switch (elem)
00857     {
00858         case PE_FrameFocusRect:
00859             drawKStylePrimitive(WT_Generic, Generic::FocusIndicator, option, r, pal, flags, painter, widget);
00860             return;
00861         case PE_IndicatorArrowUp:
00862             drawKStylePrimitive(WT_Generic, Generic::ArrowUp, option, r, pal, flags, painter, widget);
00863             return;
00864         case PE_IndicatorArrowDown:
00865             drawKStylePrimitive(WT_Generic, Generic::ArrowDown, option, r, pal, flags, painter, widget);
00866             return;
00867         case PE_IndicatorArrowLeft:
00868             drawKStylePrimitive(WT_Generic, Generic::ArrowLeft, option, r, pal, flags, painter, widget);
00869             return;
00870         case PE_IndicatorArrowRight:
00871             drawKStylePrimitive(WT_Generic, Generic::ArrowRight, option, r, pal, flags, painter, widget);
00872             return;
00873         case PE_IndicatorMenuCheckMark:
00874             //### check flags
00875             drawKStylePrimitive(WT_MenuItem, MenuItem::CheckOn, option, r, pal, flags, painter, widget);
00876             return;
00877         case PE_IndicatorCheckBox:
00878             if (flags & State_NoChange)
00879                 drawKStylePrimitive(WT_CheckBox, CheckBox::CheckTriState, option, r, pal, flags, painter, widget);
00880             else if (flags & State_On)
00881                 drawKStylePrimitive(WT_CheckBox, CheckBox::CheckOn, option, r, pal, flags, painter, widget);
00882             else
00883                 drawKStylePrimitive(WT_CheckBox, CheckBox::CheckOff, option, r, pal, flags, painter, widget);
00884             return;
00885         case PE_IndicatorRadioButton:
00886             if (flags & State_On)
00887                 drawKStylePrimitive(WT_RadioButton, RadioButton::RadioOn, option, r, pal, flags, painter, widget);
00888             else
00889                 drawKStylePrimitive(WT_RadioButton, RadioButton::RadioOff, option, r, pal, flags, painter, widget);
00890             return;
00891         case PE_IndicatorBranch:
00892         {
00893             int centerX = r.x() + r.width()/2;
00894             int centerY = r.y() + r.height()/2;
00895 
00896             int expanderAdjust = 0;
00897             //First, determine whether we need to draw an expander.
00898             if (flags & State_Children)
00899             {
00900                 //How large should we make it?
00901                 int sizeLimit = qMin(qMin(r.width(), r.height()),
00902                                      widgetLayoutProp(WT_Tree, Tree::MaxExpanderSize, option, widget));
00903                 if ((sizeLimit & 1) == 0)
00904                     --sizeLimit;
00905 
00906                 expanderAdjust = sizeLimit/2 + 1;
00907 
00908                 QRect expanderRect = QRect(centerX - sizeLimit/2, centerY - sizeLimit/2,
00909                                            sizeLimit, sizeLimit);
00910 
00911                 drawKStylePrimitive(WT_Tree, flags & State_Open ? Tree::ExpanderOpen : Tree::ExpanderClosed,
00912                                     option, expanderRect, pal, flags, painter, widget);
00913             }
00914 
00915             //Now, draw the branches. The top line gets drawn unless we're completely
00916             //w/o any indication of a neightbor
00917             if (flags & (State_Item | State_Children | State_Sibling))
00918             {
00919                 QRect topLine = QRect(QPoint(centerX, r.y()), QPoint(centerX, centerY - expanderAdjust));
00920                 drawKStylePrimitive(WT_Tree, Tree::VerticalBranch, option, topLine, pal, flags, painter, widget);
00921             }
00922 
00923             //The right/left (depending on dir) line gets drawn if we have an item
00924             if (flags & State_Item)
00925             {
00926                 QRect horLine;
00927                 if (option->direction == Qt::LeftToRight)
00928                     horLine = QRect(QPoint(centerX + expanderAdjust, centerY),
00929                                     QPoint(r.right(), centerY));
00930                 else
00931                     horLine = QRect(QPoint(r.left(), centerY),
00932                                     QPoint(centerX - expanderAdjust, centerY));
00933                 drawKStylePrimitive(WT_Tree, Tree::HorizontalBranch, option, horLine, pal, flags, painter, widget);
00934             }
00935 
00936             //The bottom if we have a sibling
00937             if (flags & State_Sibling)
00938             {
00939                 QRect botLine = QRect(QPoint(centerX, centerY + expanderAdjust),
00940                                       QPoint(centerX, r.bottom()));
00941                 drawKStylePrimitive(WT_Tree, Tree::VerticalBranch, option, botLine, pal, flags, painter, widget);
00942             }
00943             return;
00944         }
00945         case PE_FrameMenu:
00946             drawKStylePrimitive(WT_Menu, Generic::Frame, option, r, pal, flags, painter, widget);
00947             return;
00948         case PE_IndicatorHeaderArrow:
00949         {
00950             const QStyleOptionHeader *hOpt = qstyleoption_cast<const QStyleOptionHeader *>(option);
00951             int primitive = 0;
00952             if (flags&State_UpArrow || (hOpt && hOpt->sortIndicator==QStyleOptionHeader::SortUp))
00953                 primitive = Generic::ArrowUp;
00954             else if (flags&State_DownArrow || (hOpt && hOpt->sortIndicator==QStyleOptionHeader::SortDown))
00955                 primitive = Generic::ArrowDown;
00956             if (primitive != 0)
00957                 drawKStylePrimitive(WT_Header, primitive, option, r, pal, flags, painter, widget);
00958             return;
00959         }
00960         case PE_FrameTabBarBase:
00961         {
00962             drawKStylePrimitive(WT_TabBar, TabBar::BaseFrame,option,r,pal,flags,painter,widget);
00963             return;
00964         }
00965         case PE_IndicatorTabTear:
00966         {
00967             drawKStylePrimitive(WT_TabBar, TabBar::IndicatorTear,option,r,pal,flags,painter,widget);
00968             return;
00969         }
00970         case PE_FrameTabWidget:
00971         {
00972             drawKStylePrimitive(WT_TabWidget, Generic::Frame,option,r,pal,flags,painter,widget);
00973             return;
00974         }
00975 
00976         case PE_PanelLineEdit:
00977         {
00978             drawKStylePrimitive(WT_LineEdit, LineEdit::Panel,option,r,pal,flags,painter,widget);
00979             return;
00980         }
00981 
00982         case PE_FrameLineEdit:
00983         {
00984             drawKStylePrimitive(WT_LineEdit, Generic::Frame,option,r,pal,flags,painter,widget);
00985             return;
00986         }
00987 
00988         case PE_FrameGroupBox:
00989         {
00990             if (const QStyleOptionFrame *fOpt =
00991                 qstyleoption_cast<const QStyleOptionFrame *>(option))
00992             {
00993                 QStyleOptionFrameV2 fOpt2(*fOpt);
00994 
00995                 if (fOpt2.features & QStyleOptionFrameV2::Flat) {
00996                     drawKStylePrimitive(WT_GroupBox, GroupBox::FlatFrame,option,r,pal,flags,painter,widget);
00997                 } else {
00998                     drawKStylePrimitive(WT_GroupBox, Generic::Frame,option,r,pal,flags,painter,widget);
00999                 }
01000             }
01001             return;
01002         }
01003 
01004         case PE_FrameStatusBar:
01005         {
01006             drawKStylePrimitive(WT_StatusBar, Generic::Frame,option,r,pal,flags,painter,widget);
01007             return;
01008         }
01009 
01010         case PE_FrameDockWidget:
01011         {
01012             drawKStylePrimitive(WT_DockWidget, Generic::Frame,option,r,pal,flags,painter,widget);
01013             return;
01014         }
01015 
01016         case PE_IndicatorDockWidgetResizeHandle:
01017         {
01018             drawKStylePrimitive(WT_DockWidget, DockWidget::SeparatorHandle, option, r, pal, flags,
01019                                 painter, widget);
01020             return;
01021         }
01022 
01023         case PE_FrameWindow:
01024         {
01025             drawKStylePrimitive(WT_Window, Generic::Frame,option,r,pal,flags,painter,widget);
01026             return;
01027         }
01028 
01029         case PE_Frame:
01030         {
01031             drawKStylePrimitive(WT_Generic, Generic::Frame,option,r,pal,flags,painter,widget);
01032             return;
01033         }
01034 
01035         case PE_IndicatorToolBarHandle:
01036         {
01037             if (flags & State_Horizontal)
01038                 drawKStylePrimitive(WT_ToolBar, ToolBar::HandleHor,
01039                                     option,r,pal,flags,painter,widget);
01040             else
01041                 drawKStylePrimitive(WT_ToolBar, ToolBar::HandleVert,
01042                                     option,r,pal,flags,painter,widget);
01043             return;
01044         }
01045 
01046         case PE_IndicatorToolBarSeparator:
01047             drawKStylePrimitive(WT_ToolBar, ToolBar::Separator,option,r,pal,flags,painter,widget);
01048             return;
01049 
01050         case PE_PanelButtonCommand:
01051            //case PE_PanelButtonBevel: // ### CHECKME
01052             drawKStylePrimitive(WT_PushButton, PushButton::Panel, option, r, pal, flags, painter, widget);
01053             return;
01054         case PE_FrameDefaultButton:
01055             drawKStylePrimitive(WT_PushButton, PushButton::DefaultButtonFrame, option, r, pal, flags, painter, widget);
01056             return;
01057 
01058         case PE_PanelButtonTool:
01059             drawKStylePrimitive(WT_ToolButton, ToolButton::Panel,option,r,pal,flags,painter,widget);
01060             return;
01061 
01062         case PE_IndicatorButtonDropDown:
01063             drawKStylePrimitive(WT_ToolButton, Generic::ArrowDown, option, r, pal, flags, painter, widget);
01064             return;
01065 
01066         case PE_PanelItemViewItem: {
01067 
01068             const QStyleOptionViewItemV4 *opt = qstyleoption_cast<const QStyleOptionViewItemV4*>(option);
01069             const QAbstractItemView *view = qobject_cast<const QAbstractItemView *>(widget);
01070             bool hover = (option->state & State_MouseOver) && (!view ||
01071                          view->selectionMode() != QAbstractItemView::NoSelection);
01072 
01073             bool hasCustomBackground = opt->backgroundBrush.style() != Qt::NoBrush &&
01074                                         !(option->state & State_Selected);
01075             bool hasSolidBackground = !hasCustomBackground || opt->backgroundBrush.style() == Qt::SolidPattern;
01076 
01077             const qreal rounding = 2.5;
01078 
01079             if (!hover && !(option->state & State_Selected) && !hasCustomBackground &&
01080                 !(opt->features & QStyleOptionViewItemV2::Alternate))
01081                 return;
01082 
01083             QPalette::ColorGroup cg;
01084             if (option->state & State_Enabled)
01085                 cg = (option->state & State_Active) ? QPalette::Normal : QPalette::Inactive;
01086             else
01087                 cg = QPalette::Disabled;
01088 
01089             QColor color;
01090 
01091             if (hasCustomBackground && hasSolidBackground)
01092                 color = opt->backgroundBrush.color();
01093             else
01094                 color = option->palette.color(cg, QPalette::Highlight);
01095 
01096             if (hover && !hasCustomBackground) {
01097                 if (!(option->state & State_Selected))
01098                     color.setAlphaF(.20);
01099                 else
01100                     color = color.lighter(110);
01101             }
01102 
01103             if (opt && (opt->features & QStyleOptionViewItemV2::Alternate))
01104                 painter->fillRect(option->rect, option->palette.brush(cg, QPalette::AlternateBase));
01105 
01106             if (!hover && !(option->state & State_Selected) && !hasCustomBackground)
01107                 return;
01108 
01109             quint64 key = quint64(option->rect.height()) << 32 | color.rgba();
01110             SelectionTiles* tiles = d->selectionCache.object(key);
01111             if (!tiles && hasSolidBackground)
01112             {
01113                 QImage image(32 + 16, option->rect.height(), QImage::Format_ARGB32_Premultiplied);
01114                 image.fill(0);
01115 
01116                 QRect r = image.rect().adjusted(0, 0, -1, -1);
01117 
01118                 QPainterPath path1, path2;
01119                 path1.addRoundedRect(r, rounding, rounding);
01120                 path2.addRoundedRect(r.adjusted(1, 1, -1, -1), rounding - 1, rounding - 1);
01121 
01122                 // items with custom background brushes always have their background drawn
01123                 // regardless of whether they are hovered or selected or neither so
01124                 // the gradient effect needs to be more subtle
01125                 int lightenAmount = hasCustomBackground ? 110 : 130;
01126                 QLinearGradient gradient(0, 0, 0, r.bottom());
01127                 gradient.setColorAt(0, color.lighter(lightenAmount));
01128                 gradient.setColorAt(1, color);
01129 
01130                 QPainter p(&image);
01131                 p.setRenderHint(QPainter::Antialiasing);
01132                 p.translate(.5, .5);
01133                 p.setPen(QPen(color, 1));
01134                 p.setBrush(gradient);
01135                 p.drawPath(path1);
01136                 p.strokePath(path2, QPen(QColor(255, 255, 255, 64), 1));
01137                 p.end();
01138 
01139                 QPixmap pixmap = QPixmap::fromImage(image);
01140 
01141                 tiles = new SelectionTiles;
01142                 tiles->left   = pixmap.copy(0, 0, 8, image.height());
01143                 tiles->center = pixmap.copy(8, 0, 32, image.height());
01144                 tiles->right  = pixmap.copy(40, 0, 8, image.height());
01145 
01146                 d->selectionCache.insert(key, tiles);
01147             }
01148             else if (hasCustomBackground && !hasSolidBackground)
01149             {
01150                 painter->setBrush(opt->backgroundBrush);
01151                 painter->setPen(Qt::NoPen);
01152                 painter->drawRect(opt->rect);
01153                 return;
01154             }
01155 
01156             bool roundedLeft  = false;
01157             bool roundedRight = false;
01158             if (opt) {
01159                 roundedLeft  = (opt->viewItemPosition == QStyleOptionViewItemV4::Beginning);
01160                 roundedRight = (opt->viewItemPosition == QStyleOptionViewItemV4::End);
01161                 if (opt->viewItemPosition == QStyleOptionViewItemV4::OnlyOne ||
01162                     opt->viewItemPosition == QStyleOptionViewItemV4::Invalid ||
01163                     (view && view->selectionBehavior() != QAbstractItemView::SelectRows))
01164                 {
01165                     roundedLeft  = true;
01166                     roundedRight = true;
01167                 }
01168             }
01169 
01170             QRect r = option->rect;
01171             bool reverseLayout = option->direction == Qt::RightToLeft;
01172 
01173             if (!reverseLayout ? roundedLeft : roundedRight) {
01174                 painter->drawPixmap(r.topLeft(), tiles->left);
01175                 r.adjust(8, 0, 0, 0);
01176             }
01177             if (!reverseLayout ? roundedRight : roundedLeft) {
01178                 painter->drawPixmap(r.right() - 8 + 1, r.top(), tiles->right);
01179                 r.adjust(0, 0, -8, 0);
01180             }
01181             if (r.isValid())
01182                 painter->drawTiledPixmap(r, tiles->center);
01183 
01184             return;
01185         }
01186 
01187         default:
01188             break;
01189     }
01190 
01191     QCommonStyle::drawPrimitive(elem, option, painter, widget);
01192 }
01193 
01194 void KStyle::drawControl(ControlElement element, const QStyleOption* option, QPainter* p, const QWidget* widget) const
01195 {
01196     //Extract the stuff we need out of the option
01197     State flags = option->state;
01198     QRect      r     = option->rect;
01199     QPalette   pal   = option->palette;
01200 
01201     switch (element)
01202     {
01203         case CE_PushButton:
01204         {
01205             const QStyleOptionButton* bOpt = qstyleoption_cast<const QStyleOptionButton*>(option);
01206             if (!bOpt) return;
01207 
01208             //Draw the bevel outside
01209             drawControl(CE_PushButtonBevel, option, p, widget);
01210 
01211             //Now, draw the label...
01212             QRect labelRect = r;
01213 
01214             //Move inside of default indicator margin if need be
01215             if ((bOpt->features & QStyleOptionButton::DefaultButton) || (bOpt->features & QStyleOptionButton::AutoDefaultButton))
01216                 labelRect = insideMargin(labelRect, WT_PushButton, PushButton::DefaultIndicatorMargin, option, widget);
01217 
01218             //now get the contents area
01219             labelRect = insideMargin(labelRect, WT_PushButton, PushButton::ContentsMargin, option, widget);
01220 
01221             //### do we do anything for RTL here?
01222 
01223             QStyleOptionButton bOptTmp = *bOpt;
01224             bOptTmp.rect = labelRect;
01225             drawControl(CE_PushButtonLabel, &bOptTmp, p, widget);
01226 
01227             //Finally, renderer the focus indicator if need be
01228             if (flags & State_HasFocus)
01229             {
01230                 QRect focusRect = insideMargin(r, WT_PushButton, PushButton::FocusMargin, option, widget);
01231 
01232                 QStyleOptionFocusRect foOpts;
01233                 foOpts.palette         = pal;
01234                 foOpts.rect            = focusRect;
01235                 foOpts.state           = flags;
01236 
01237                 drawKStylePrimitive(WT_PushButton, Generic::FocusIndicator, &foOpts, focusRect, pal, flags, p, widget);
01238             }
01239 
01240             return;
01241         }
01242 
01243         case CE_PushButtonBevel:
01244         {
01245             const QStyleOptionButton* bOpt = qstyleoption_cast<const QStyleOptionButton*>(option);
01246             if (!bOpt) return;
01247 
01248             //Check whether we should draw default indicator.
01249             if (bOpt->features & QStyleOptionButton::DefaultButton)
01250                 drawPrimitive(PE_FrameDefaultButton, option, p, widget);
01251 
01252             QRect bevelRect = r;
01253             //Exclude the margin if default or auto-default
01254             if ((bOpt->features & QStyleOptionButton::DefaultButton) || (bOpt->features & QStyleOptionButton::AutoDefaultButton))
01255                 bevelRect = insideMargin(r, WT_PushButton, PushButton::DefaultIndicatorMargin, option, widget);
01256 
01257             //Now draw the bevel itself.
01258             QStyleOptionButton bOptTmp = *bOpt;
01259             bOptTmp.rect = bevelRect;
01260             drawPrimitive(PE_PanelButtonCommand, &bOptTmp, p, widget);
01261 
01262             return;
01263         }
01264 
01265         case CE_PushButtonLabel:
01266         {
01267             const QStyleOptionButton* bOpt = qstyleoption_cast<const QStyleOptionButton*>(option);
01268             if (!bOpt) return;
01269 
01270             //Extract out coordinates for easier manipulation
01271             //(OK, OK, for easier stealing of code from Keramik)
01272             int x, y, w, h;
01273             r.getRect(&x, &y, &w, &h);
01274 
01275             //Are we active? If so, shift contents
01276             bool active = (flags & State_On) || (flags & State_Sunken);
01277             if (active)
01278             {
01279                 x += widgetLayoutProp(WT_PushButton, PushButton::PressedShiftHorizontal, option, widget);
01280                 y += widgetLayoutProp(WT_PushButton, PushButton::PressedShiftVertical, option, widget);
01281             }
01282 
01283             //Layout the stuff. Do we need space for indicator?
01284             //we do this separately, and push it to the end, removing its space from layout.
01285             if (bOpt->features & QStyleOptionButton::HasMenu)
01286             {
01287                 int indicatorWidth = widgetLayoutProp(WT_PushButton, PushButton::MenuIndicatorSize, option, widget);
01288                 w -= indicatorWidth;
01289 
01290                 //Draw the arrow...
01291                 drawKStylePrimitive(WT_PushButton, Generic::ArrowDown, option,
01292                                     handleRTL(bOpt, QRect(x + w, y, indicatorWidth, h)),
01293                                     pal, flags, p, widget);
01294             }
01295 
01296             // Draw the icon if there is one
01297             if (!bOpt->icon.isNull())
01298             {
01299                 QSize iconSize(pixelMetric(PM_SmallIconSize),pixelMetric(PM_SmallIconSize));
01300                 IconOption icoOpt;
01301                 icoOpt.icon   = bOpt->icon;
01302                 icoOpt.size   = bOpt->iconSize;
01303                 icoOpt.active = flags & State_HasFocus;
01304 
01305                 if (!bOpt->text.isEmpty())
01306                 {
01307                     int margin = widgetLayoutProp(WT_PushButton, PushButton::TextToIconSpace, option, widget);
01308                     //Center text + icon w/margin in between..
01309 
01310                     //Calculate length of both.
01311                     int length = iconSize.width() + margin
01312                                   + p->fontMetrics().size(Qt::TextShowMnemonic, bOpt->text).width();
01313 
01314                     //Calculate offset.
01315                     int offset = (w - length)/2;
01316 
01317                     //draw icon
01318                     QRect rect = QRect(QPoint(x + offset, y + h/2 - iconSize.height()/2), iconSize);
01319                     drawKStylePrimitive(WT_PushButton, Generic::Icon, option,
01320                                         handleRTL(bOpt, rect),
01321                                         pal, flags, p, widget, &icoOpt);
01322 
01323                     //new bounding rect for the text
01324                     x += offset + iconSize.width() + margin;
01325                     w =  length - iconSize.width() - margin;
01326                 }
01327                 else
01328                 {
01329                     //Icon only. Center it. (Thankfully, they killed the icon + pixmap insanity in Qt4. Whee!
01330                     //(no need to do anything for RTL here, it's symmetric)
01331                     drawKStylePrimitive(WT_PushButton, Generic::Icon, option,
01332                                         QRect(x, y, w, h),
01333                                         pal, flags, p, widget, &icoOpt);
01334                 }
01335             }
01336             else
01337             {
01338                 //Center the text
01339                 int textW = p->fontMetrics().size(Qt::TextShowMnemonic, bOpt->text).width();
01340                 x += (w - textW)/2;
01341                 w =  textW;
01342             }
01343 
01344             TextOption lbOpt(bOpt->text);
01345             drawKStylePrimitive(WT_PushButton, Generic::Text, option, handleRTL(bOpt, QRect(x, y, w, h)),
01346                                     pal, flags, p, widget, &lbOpt);
01347 
01348             return;
01349         }
01350 
01351         case CE_DockWidgetTitle:
01352         {
01353             const QStyleOptionDockWidget* dwOpt = ::qstyleoption_cast<const QStyleOptionDockWidget*>(option);
01354             if (!dwOpt) return;
01355 
01356             QRect textRect = insideMargin(r, WT_DockWidget, DockWidget::TitleMargin, option, widget);
01357             drawKStylePrimitive(WT_DockWidget, DockWidget::TitlePanel, option, r, pal, flags, p, widget);
01358 
01359             TextOption lbOpt(dwOpt->title);
01360             lbOpt.color = widgetLayoutProp(WT_DockWidget, DockWidget::TitleTextColor,
01361                                            option, widget);
01362             drawKStylePrimitive(WT_DockWidget, Generic::Text, option, textRect, pal, flags, p, widget, &lbOpt);
01363             return;
01364         }
01365 
01366         case CE_ToolBoxTabShape:
01367         {
01368             drawKStylePrimitive(WT_ToolBoxTab, ToolBoxTab::Panel, option, r, pal, flags, p, widget);
01369             return;
01370         }
01371 /*
01372         case CE_ToolBoxTabLabel:
01373         {
01374             drawKStylePrimitive(WT_ToolBoxTab, Generic::Text, option, r, pal, flags, p, widget);
01375             return;
01376         }
01377 */
01378         case CE_CheckBox:
01379         {
01380             const QStyleOptionButton* bOpt = qstyleoption_cast<const QStyleOptionButton*>(option);
01381             if (!bOpt) return;
01382 
01383             //Draw the checkbox
01384             QRect checkBox = subElementRect(SE_CheckBoxIndicator, option, widget);
01385             QStyleOptionButton bOptTmp = *bOpt;
01386             bOptTmp.rect = checkBox;
01387             drawPrimitive(PE_IndicatorCheckBox, &bOptTmp, p, widget);
01388 
01389             // pixmap and text label...
01390             bOptTmp.rect = subElementRect(SE_CheckBoxContents, option, widget);
01391             drawControl(CE_CheckBoxLabel, &bOptTmp, p, widget);
01392 
01393             //Draw the focus rect...
01394             if (flags & State_HasFocus)
01395             {
01396                 QRect focusRect = subElementRect(SE_CheckBoxFocusRect, option, widget);
01397                 drawKStylePrimitive(WT_CheckBox, Generic::FocusIndicator, option, focusRect,
01398                                     pal, flags, p, widget);
01399             }
01400             return;
01401         }
01402 
01403         case CE_CheckBoxLabel:
01404         {
01405             const QStyleOptionButton* bOpt = qstyleoption_cast<const QStyleOptionButton*>(option);
01406             if (!bOpt) return;
01407 
01408             int textShift = 0; // shift text in case there is a label pixmap
01409             // draw the pixmap, if there is one
01410             if (!bOpt->icon.isNull())
01411             {
01412                 IconOption icoOpt;
01413                 icoOpt.icon   = bOpt->icon;
01414                 icoOpt.size   = bOpt->iconSize;
01415                 icoOpt.active = flags & State_HasFocus;
01416 
01417                 QRect iconRect(r.x(), r.y() + (r.height()-bOpt->iconSize.height())/2,
01418                                bOpt->iconSize.width(), bOpt->iconSize.height());
01419                 drawKStylePrimitive(WT_CheckBox, Generic::Icon, option,
01420                                     handleRTL(bOpt, iconRect),
01421                                     pal, flags, p, widget, &icoOpt);
01422 
01423                 textShift = bOpt->iconSize.width() +
01424                         widgetLayoutProp(WT_RadioButton, RadioButton::BoxTextSpace, option, widget);
01425             }
01426 
01427 
01428             if (!bOpt->text.isEmpty() ) {
01429                 TextOption lbOpt(bOpt->text);
01430                 drawKStylePrimitive(WT_CheckBox, Generic::Text, option,
01431                                     handleRTL(bOpt, r.adjusted(textShift,0,0,0)),
01432                                     pal, flags, p, widget, &lbOpt);
01433             }
01434 
01435             return;
01436         }
01437 
01438         case CE_RadioButton:
01439         {
01440             const QStyleOptionButton* bOpt = qstyleoption_cast<const QStyleOptionButton*>(option);
01441             if (!bOpt) return;
01442 
01443             //Draw the indicator
01444             QRect indicator = subElementRect(SE_RadioButtonIndicator, option, widget);
01445             QStyleOptionButton bOptTmp = *bOpt;
01446             bOptTmp.rect = indicator;
01447             drawPrimitive(PE_IndicatorRadioButton, &bOptTmp, p, widget);
01448 
01449             // pixmap and text label...
01450             bOptTmp.rect = subElementRect(SE_RadioButtonContents, option, widget);
01451             drawControl(CE_RadioButtonLabel, &bOptTmp, p, widget);
01452 
01453             //Draw the focus rect...
01454             if (flags & State_HasFocus)
01455             {
01456                 QRect focusRect = subElementRect(SE_RadioButtonFocusRect, option, widget);
01457                 drawKStylePrimitive(WT_RadioButton, Generic::FocusIndicator, option, focusRect,
01458                                     pal, flags, p, widget);
01459             }
01460             return;
01461         }
01462 
01463         case CE_RadioButtonLabel:
01464         {
01465             const QStyleOptionButton* bOpt = qstyleoption_cast<const QStyleOptionButton*>(option);
01466             if (!bOpt) return;
01467 
01468             int textShift = 0; // shift text in case there is a label pixmap
01469             // draw the pixmap, if there is one
01470             if (!bOpt->icon.isNull())
01471             {
01472                 IconOption icoOpt;
01473                 icoOpt.icon   = bOpt->icon;
01474                 icoOpt.active = flags & State_HasFocus;
01475                 icoOpt.size   = bOpt->iconSize;
01476 
01477                 QRect iconRect(r.x(), r.y() + (r.height()-bOpt->iconSize.height())/2,
01478                                bOpt->iconSize.width(), bOpt->iconSize.height());
01479                 drawKStylePrimitive(WT_RadioButton, Generic::Icon, option,
01480                                     handleRTL(bOpt, iconRect),
01481                                     pal, flags, p, widget, &icoOpt);
01482 
01483                 textShift = bOpt->iconSize.width() +
01484                         widgetLayoutProp(WT_RadioButton, RadioButton::BoxTextSpace, option, widget);
01485             }
01486 
01487             TextOption lbOpt(bOpt->text);
01488             drawKStylePrimitive(WT_RadioButton, Generic::Text, option,
01489                                 handleRTL(bOpt, r.adjusted(textShift,0,0,0)),
01490                                 pal, flags, p, widget, &lbOpt);
01491             return;
01492         }
01493 
01494         //The CE_ProgressBar implementation inside QCommonStyle is acceptible.
01495         //We just implement the subElementRect's it uses
01496 
01497         case CE_ProgressBarGroove:
01498         {
01499             drawKStylePrimitive(WT_ProgressBar, ProgressBar::Groove,  option, r,
01500                                 pal, flags, p, widget);
01501             return;
01502         }
01503 
01504         case CE_ProgressBarContents:
01505         {
01506             const QStyleOptionProgressBar* pbOpt = qstyleoption_cast<const QStyleOptionProgressBar*>(option);
01507             const QStyleOptionProgressBarV2* pbOpt2 = qstyleoption_cast<const QStyleOptionProgressBarV2*>(option);
01508             if  (!pbOpt) return;
01509 
01510             //We layout as if LTR, relying on visualRect to fix it up
01511             double progress    = pbOpt->progress - pbOpt->minimum;
01512             int steps          = qMax(pbOpt->maximum  - pbOpt->minimum, 1);
01513             bool busyIndicator = (pbOpt->minimum == 0 && pbOpt->maximum == 0);
01514             bool horizontal    = !pbOpt2 || pbOpt2->orientation == Qt::Horizontal;
01515 
01516             //Do we have to draw anything?
01517             if (!progress && ! busyIndicator)
01518                 return;
01519 
01520             //Calculate width fraction
01521             double widthFrac;
01522             if (busyIndicator)
01523                 widthFrac = widgetLayoutProp(WT_ProgressBar, ProgressBar::BusyIndicatorSize, option, widget) / 100.0;
01524             else
01525                 widthFrac = progress / steps;
01526 
01527             //And now the pixel width
01528             int width = qMin(r.width(), (int)(widthFrac * double(r.width())));
01529             int height = qMin(r.height(), (int)(widthFrac * r.height()));
01530 
01531             if (busyIndicator)
01532             {
01533                 int size = width;
01534                 if (!horizontal)
01535                     size = height;
01536                 //Clamp to upper width limit
01537                 if (size > widgetLayoutProp(WT_ProgressBar, ProgressBar::MaxBusyIndicatorSize, option, widget))
01538                     size = widgetLayoutProp(WT_ProgressBar, ProgressBar::MaxBusyIndicatorSize, option, widget);
01539 
01540                 //A busy indicator with width 0 is kind of useless
01541                 if (size < 1) size = 1;
01542 
01543 
01544                 int remSize = (horizontal ? r.width() : r.height()) - size; //The space around which we move around...
01545                 if (remSize <= 0) remSize = 1;  //Do something non-crashy when too small...
01546 
01547                 int pstep =  int(progress)%(2*remSize);
01548 
01549                 if (pstep > remSize)
01550                 {
01551                     //Bounce about.. We're remWidth + some delta, we want to be remWidth - delta...
01552                     // - ( (remWidth + some delta) - 2* remWidth )  = - (some deleta - remWidth) = remWidth - some delta..
01553                     pstep = -(pstep - 2*remSize);
01554                 }
01555 
01556                 QRect indicatorRect;
01557                 if (horizontal)
01558                     indicatorRect = QRect(r.x() + pstep, r.y(), size, r.height());
01559                 else
01560                     indicatorRect = QRect(r.x(), r.y() + pstep, r.width(), size);
01561                 drawKStylePrimitive(WT_ProgressBar, ProgressBar::BusyIndicator, option, handleRTL(option, indicatorRect),
01562                                     pal, flags, p, widget);
01563             }
01564             else
01565             {
01566                 QRect indicatorRect;
01567                 if (horizontal)
01568                     indicatorRect = QRect(r.x(), r.y(), width, r.height());
01569                 else
01570                     indicatorRect = QRect(r.x(), r.bottom()-height+1, r.width(), height);
01571                 drawKStylePrimitive(WT_ProgressBar, ProgressBar::Indicator, option, handleRTL(option, indicatorRect),
01572                                     pal, flags, p, widget);
01573             }
01574             return;
01575         }
01576 
01577         case CE_ProgressBarLabel:
01578         {
01579             const QStyleOptionProgressBar* pbOpt = qstyleoption_cast<const QStyleOptionProgressBar*>(option);
01580             const QStyleOptionProgressBarV2* pbOpt2 = qstyleoption_cast<const QStyleOptionProgressBarV2*>(option);
01581             if (pbOpt)
01582             {
01583                 TextOption lbOpt(pbOpt->text);
01584                 bool horizontal = !pbOpt2 || pbOpt2->orientation == Qt::Horizontal;
01585                 bool reverseLayout = option->direction == Qt::RightToLeft;
01586 
01587                 p->save();
01588 
01589                 // rotate label for vertical layout
01590                 if (!horizontal && !reverseLayout)
01591                 {
01592                     p->translate(r.topRight());
01593                     p->rotate(90.0);
01594                 }
01595                 else if (!horizontal)
01596                 {
01597                     p->translate(r.bottomLeft());
01598                     p->rotate(-90.0);
01599                 }
01600 
01601                 if (useSideText(pbOpt))
01602                 {
01603                     lbOpt.color = QPalette::ButtonText;
01604 
01605                     //### or other way around?
01606                     if (option->direction == Qt::LeftToRight)
01607                         lbOpt.hAlign = Qt::AlignRight;
01608                     else
01609                         lbOpt.hAlign = Qt::AlignLeft;
01610 
01611                     //Handle side margin.
01612                     int marWidth = widgetLayoutProp(WT_ProgressBar, ProgressBar::SideTextSpace, option, widget);
01613 
01614                     drawKStylePrimitive(WT_ProgressBar, Generic::Text, option,
01615                             horizontal? r.adjusted(0, marWidth, 0, -marWidth) : QRect(0, marWidth, r.height(), r.width()-marWidth),
01616                             pal, flags, p, widget, &lbOpt);
01617                 }
01618                 else
01619                 {
01620                     if (pbOpt->textAlignment == Qt::AlignLeft) //TODO: Check BIDI?
01621                         lbOpt.hAlign = Qt::AlignHCenter;
01622                     else
01623                         lbOpt.hAlign = pbOpt->textAlignment;
01624 
01625                     //Now, we need to figure out the geometry of the indicator.
01626                     QRect progressRect;
01627                     double progress    = pbOpt->progress - pbOpt->minimum;
01628                     int steps          = qMax(pbOpt->maximum  - pbOpt->minimum, 1);
01629                     bool busyIndicator = (steps <= 1);
01630 
01631                     int width;
01632                     int height;
01633                     if (busyIndicator)
01634                     {
01635                         //how did this happen? handle as 0%
01636                         width = 0;
01637                         height = 0;
01638                     }
01639                     else
01640                     {
01641                         double widthFrac = progress / steps;;
01642                         width = qMin(r.width(), (int)(widthFrac * r.width()));
01643                         height = qMin(r.height(), (int)(widthFrac * r.height()));
01644                     }
01645 
01646                     //If there is any indicator, we do two paths, with different
01647                     //clipping rects, for the two colors.
01648                     if (width || height)
01649                     {
01650                         if (horizontal)
01651                             p->setClipRect(handleRTL(option, QRect(r.x(), r.y(), width, r.height())));
01652                         else if (!reverseLayout)
01653                             p->setClipRect(QRect(r.height()-height, 0, r.height(), r.width()));
01654                         else
01655                             p->setClipRect(QRect(0, 0, height, r.width()));
01656                         lbOpt.color = QPalette::HighlightedText;
01657                         drawKStylePrimitive(WT_ProgressBar, Generic::Text, option,
01658                                             horizontal? r: QRect(0,0,r.height(),r.width()),
01659                                             pal, flags, p, widget, &lbOpt);
01660 
01661                         if (horizontal)
01662                             p->setClipRect(handleRTL(option, QRect(r.x() + width, r.y(), r.width() - width, r.height())));
01663                         else if (!reverseLayout)
01664                             p->setClipRect(QRect(0, 0, r.height()-height, r.width()));
01665                         else
01666                             p->setClipRect(QRect(height, 0, r.height()-height, r.width()));
01667                         lbOpt.color = QPalette::ButtonText;
01668                         drawKStylePrimitive(WT_ProgressBar, Generic::Text, option,
01669                                             horizontal? r: QRect(0,0,r.height(),r.width()),
01670                                             pal, flags, p, widget, &lbOpt);
01671                         p->setClipping(false);
01672                     }
01673                     else
01674                     {
01675                         lbOpt.color = QPalette::ButtonText;
01676                         drawKStylePrimitive(WT_ProgressBar, Generic::Text, option,
01677                                             horizontal? r: QRect(0,0,r.height(),r.width()),
01678                                             pal, flags, p, widget, &lbOpt);
01679                     }
01680                 }
01681                 p->restore();
01682             }
01683             return;
01684         }
01685 
01686         case CE_MenuBarItem:
01687         {
01688             const QStyleOptionMenuItem* mOpt = ::qstyleoption_cast<const QStyleOptionMenuItem*>(option);
01689             if (!mOpt) return;
01690 
01691             //Bevel...
01692             drawKStylePrimitive(WT_MenuBarItem, MenuBarItem::Panel, option, r,
01693                                 pal, flags, p, widget);
01694 
01695             //Text...
01696             QRect textRect = insideMargin(r, WT_MenuBarItem, MenuBarItem::Margin, option, widget);
01697 
01698 
01699             TextOption lbOpt(mOpt->text);
01700             drawKStylePrimitive(WT_MenuBarItem, Generic::Text, option, textRect,
01701                                 pal, flags, p, widget, &lbOpt);
01702 
01703             return;
01704         }
01705 
01706         case CE_MenuBarEmptyArea:
01707         {
01708             drawKStylePrimitive(WT_MenuBar, MenuBar::EmptyArea,  option, r,
01709                                 pal, flags, p, widget);
01710             return;
01711         }
01712 
01713         case CE_MenuEmptyArea:
01714         case CE_MenuVMargin:
01715         case CE_MenuHMargin:
01716         {
01717             drawKStylePrimitive(WT_Menu, Menu::Background,  option, r,
01718                                 pal, flags, p, widget);
01719             return;
01720         }
01721 
01722         case CE_MenuItem:
01723         {
01724 
01725             //First of all,render the background.
01726             drawKStylePrimitive(WT_Menu, Menu::Background, option, r,
01727                                 pal, flags, p, widget);
01728 
01729             const QStyleOptionMenuItem* miOpt = ::qstyleoption_cast<const QStyleOptionMenuItem*>(option);
01730             if (!miOpt || miOpt->menuItemType == QStyleOptionMenuItem::EmptyArea) return;
01731 
01732             //Remove the margin (for everything but the column background)
01733             QRect ir = insideMargin(r, WT_MenuItem, MenuItem::Margin, option, widget);
01734 
01735 
01736             //First, figure out the left column width. When CheckAlongsideIcon is disabled it's just
01737             // the icon column width. Otherwise it consists of CheckWidth+CheckSpace+icon column width.
01738             int iconColW = miOpt->maxIconWidth;
01739             iconColW     = qMax(iconColW, widgetLayoutProp(WT_MenuItem, MenuItem::IconWidth, option, widget));
01740             int checkColW = widgetLayoutProp(WT_MenuItem, MenuItem::CheckWidth, option, widget);
01741             int checkSpace = widgetLayoutProp(WT_MenuItem, MenuItem::CheckSpace, option, widget);
01742 
01743             int leftColW = iconColW;
01744             // only use the additional check row if the menu has checkable menuItems.
01745             bool checkAlongsideIcon = (miOpt->menuHasCheckableItems &&
01746                     widgetLayoutProp(WT_MenuItem, MenuItem::CheckAlongsideIcon, option, widget) );
01747             if (checkAlongsideIcon)
01748             {
01749                 leftColW = checkColW + checkSpace + iconColW;
01750             }
01751 
01752             //And the right arrow column...
01753             int rightColW = widgetLayoutProp(WT_MenuItem, MenuItem::ArrowSpace, option, widget) +
01754                             widgetLayoutProp(WT_MenuItem, MenuItem::ArrowWidth, option, widget);
01755 
01756             //Render left column background. This is a bit tricky, since we don't use the V margin.
01757             QRect leftColRect(ir.x(), r.y(), leftColW, r.height());
01758             drawKStylePrimitive(WT_MenuItem, MenuItem::CheckColumn, option, handleRTL(option, leftColRect),
01759                                 pal, flags, p, widget);
01760 
01761             //Separators: done with the bg, can paint them and bail them out.
01762             if (miOpt->menuItemType == QStyleOptionMenuItem::Separator)
01763             {
01764                 drawKStylePrimitive(WT_MenuItem, MenuItem::Separator, option, ir, pal, flags, p, widget);
01765                 return;
01766             }
01767 
01768             //Now paint the active indicator --- other stuff goes on top of it
01769             bool active = (flags & State_Selected);
01770 
01771             //Active indicator...
01772             if (active)
01773                 drawKStylePrimitive(WT_MenuItem, MenuItem::ItemIndicator, option, handleRTL(option, r), pal, flags, p, widget);
01774 
01775 
01776             ColorMode textColor = (flags & State_Enabled) ? (widgetLayoutProp(WT_MenuItem, active ?
01777                                                                   MenuItem::ActiveTextColor :
01778                                                                           MenuItem::TextColor, option, widget))
01779                                                           : (widgetLayoutProp(WT_MenuItem, active ?
01780                                                                   MenuItem::ActiveDisabledTextColor:
01781                                                                           MenuItem::DisabledTextColor, option, widget));
01782 
01783             //Readjust the column rectangle back to proper height
01784             leftColRect = QRect(ir.x(), ir.y(), leftColW, ir.height());
01785             // Paint checkbox, etc.
01786             if (!checkAlongsideIcon && !miOpt->icon.isNull() )
01787             {
01788                 // there is an icon and the item is checked, so paint a CheckIcon
01789                 if (miOpt->checked)
01790                 {
01791                     drawKStylePrimitive(WT_MenuItem, MenuItem::CheckIcon,
01792                                         option, handleRTL(option, leftColRect), pal, flags,
01793                                         p, widget);
01794                 }
01795             }
01796             else
01797             {
01798                 // paint a normal check- resp. radiomark.
01799                 QRect checkColRect;
01800                 if (checkAlongsideIcon)
01801                 {
01802                     checkColRect = QRect(leftColRect.x(), leftColRect.y(),
01803                                          checkColW, leftColRect.height() );
01804                 }
01805                 else
01806                 {
01807                     checkColRect = leftColRect;
01808                 }
01809 
01810                 bool checked = miOpt->checked;
01811                 if (miOpt->checkType == QStyleOptionMenuItem::NonExclusive)
01812                 {
01813                     drawKStylePrimitive(WT_MenuItem, checked ? MenuItem::CheckOn : MenuItem::CheckOff,
01814                                         option, handleRTL(option, checkColRect), pal, flags,
01815                                         p, widget);
01816                 }
01817                 else if (miOpt->checkType == QStyleOptionMenuItem::Exclusive)
01818                 {
01819                     drawKStylePrimitive(WT_MenuItem, checked ? MenuItem::RadioOn : MenuItem::RadioOff,
01820                                         option, handleRTL(option, checkColRect), pal, flags,
01821                                         p, widget);
01822                 }
01823             }
01824             // Paint the menu icon.
01825             if (!miOpt->icon.isNull())
01826             {
01827                 int iconSize = pixelMetric(PM_SmallIconSize);
01828 
01829                 QRect iconColRect;
01830                 if (checkAlongsideIcon)
01831                 {
01832                     iconColRect = QRect(leftColRect.x()+checkColW+checkSpace, leftColRect.y(),
01833                                         leftColRect.width()-(checkColW+checkSpace), leftColRect.height() );
01834                 }
01835                 else
01836                 {
01837                     iconColRect = leftColRect;
01838                 }
01839                 IconOption icoOpt;
01840                 icoOpt.icon   = miOpt->icon;
01841                 icoOpt.active = flags & State_Selected;
01842                 drawKStylePrimitive(WT_MenuItem, Generic::Icon, option,
01843                                     handleRTL(option, centerRect(iconColRect, iconSize, iconSize)),
01844                                     pal, flags, p, widget, &icoOpt);
01845             }
01846 
01847             //Now include the spacing when calculating the next columns
01848             leftColW += widgetLayoutProp(WT_MenuItem, MenuItem::IconSpace, option, widget);
01849 
01850             //Render the text, including any accel.
01851             QString text = miOpt->text;
01852             QRect   textRect = QRect(ir.x() + leftColW, ir.y(), ir.width() - leftColW - rightColW, ir.height());
01853             QFont   font = miOpt->font;
01854             const QFont oldFont = p->font();
01855 
01856             p->setFont(font);
01857             int tabPos = miOpt->text.indexOf(QLatin1Char('\t'));
01858             if (tabPos != -1)
01859             {
01860                 text = miOpt->text.left(tabPos);
01861                 QString accl = miOpt->text.mid (tabPos + 1);
01862 
01863                 //Draw the accel.
01864                 TextOption lbOpt(accl);
01865                 lbOpt.color  = textColor;
01866                 lbOpt.hAlign = Qt::AlignRight;
01867                 drawKStylePrimitive(WT_MenuItem, Generic::Text, option, handleRTL(option, textRect),
01868                                 pal, flags, p, widget, &lbOpt);
01869             }
01870 
01871             //Draw the text.
01872             TextOption lbOpt(text);
01873             lbOpt.color = textColor;
01874             drawKStylePrimitive(WT_MenuItem, Generic::Text, option, handleRTL(option, textRect),
01875                                 pal, flags, p, widget, &lbOpt);
01876 
01877             p->setFont(oldFont);
01878 
01879             //Render arrow, if need be.
01880             if (miOpt->menuItemType == QStyleOptionMenuItem::SubMenu)
01881             {
01882                 ColorOption arrowColor;
01883                 arrowColor.color = textColor;
01884 
01885                 int aw = widgetLayoutProp(WT_MenuItem, MenuItem::ArrowWidth, option, widget);
01886 
01887                 QRect arrowRect(ir.x() + ir.width() - aw, ir.y(), aw, ir.height());
01888                 drawKStylePrimitive(WT_MenuItem, option->direction == Qt::LeftToRight ?
01889                                                        Generic::ArrowRight : Generic::ArrowLeft,
01890                                     option, handleRTL(option, arrowRect), pal, flags, p, widget, &arrowColor);
01891             }
01892 
01893             return;
01894         }
01895 
01896         case CE_ScrollBarAddLine:
01897         case CE_ScrollBarSubLine:
01898         {
01899             const QStyleOptionSlider* slOpt = ::qstyleoption_cast<const QStyleOptionSlider*>(option);
01900             if (!slOpt) return;
01901 
01902             //Fix up the rectangle to be what we want
01903             r = internalSubControlRect(CC_ScrollBar, slOpt,
01904                 element == CE_ScrollBarAddLine ? SC_ScrollBarAddLine : SC_ScrollBarSubLine, widget);
01905             const_cast<QStyleOption*>(option)->rect = r;
01906 
01907 
01908             bool doubleButton = false;
01909 
01910             //See whether we're a double-button...
01911             if (element == CE_ScrollBarAddLine && widgetLayoutProp(WT_ScrollBar, ScrollBar::DoubleBotButton, option, widget))
01912                 doubleButton = true;
01913             if (element == CE_ScrollBarSubLine && widgetLayoutProp(WT_ScrollBar, ScrollBar::DoubleTopButton, option, widget))
01914                 doubleButton = true;
01915 
01916             if (doubleButton)
01917             {
01918                 if (flags & State_Horizontal)
01919                 {
01920                     DoubleButtonOption::ActiveButton ab = DoubleButtonOption::None;
01921 
01922                     //Depending on RTL direction, the one on the left is either up or down.
01923                     bool leftAdds, rightAdds;
01924                     if (slOpt->direction == Qt::LeftToRight)
01925                     {
01926                         leftAdds  = false;
01927                         rightAdds = true;
01928                     }
01929                     else
01930                     {
01931                         leftAdds  = true;
01932                         rightAdds = false;
01933                     }
01934 
01935                     //Determine whether any of the buttons is active
01936                     if (flags & State_Sunken)
01937                     {
01938                         if (((slOpt->activeSubControls & SC_ScrollBarAddLine) && leftAdds) ||
01939                             ((slOpt->activeSubControls & SC_ScrollBarSubLine) && !leftAdds))
01940                             ab = DoubleButtonOption::Left;
01941 
01942                         if (((slOpt->activeSubControls & SC_ScrollBarAddLine) && rightAdds) ||
01943                             ((slOpt->activeSubControls & SC_ScrollBarSubLine) && !rightAdds))
01944                             ab = DoubleButtonOption::Right;
01945                     }
01946 
01947                     DoubleButtonOption bOpt(ab);
01948                     drawKStylePrimitive(WT_ScrollBar, ScrollBar::DoubleButtonHor,
01949                                         option, r, pal, flags, p, widget, &bOpt);
01950 
01951                     //Draw the left arrow..
01952                     QRect leftSubButton = QRect(r.x(), r.y(), r.width()/2, r.height());
01953 
01954                     ColorOption colOpt;
01955                     colOpt.color = widgetLayoutProp(WT_ScrollBar, ScrollBar::ArrowColor, option, widget);
01956                     if (ab == DoubleButtonOption::Left)
01957                         colOpt.color = widgetLayoutProp(WT_ScrollBar, ScrollBar::ActiveArrowColor, option, widget);
01958 
01959                     drawKStylePrimitive(WT_ScrollBar, Generic::ArrowLeft, option, leftSubButton, pal,
01960                                         flags, p, widget, &colOpt);
01961 
01962                     //Right half..
01963                     QRect rightSubButton;
01964                     rightSubButton.setBottomRight(r.bottomRight());
01965                     rightSubButton.setLeft       (leftSubButton.right() + 1);
01966                     rightSubButton.setTop        (r.top());
01967 
01968                     //Chose proper color
01969                     colOpt.color = widgetLayoutProp(WT_ScrollBar, ScrollBar::ArrowColor, option, widget);
01970                     if (ab == DoubleButtonOption::Right)
01971                         colOpt.color = widgetLayoutProp(WT_ScrollBar, ScrollBar::ActiveArrowColor, option, widget);
01972 
01973                     drawKStylePrimitive(WT_ScrollBar, Generic::ArrowRight, option, rightSubButton, pal,
01974                                         flags, p, widget, &colOpt);
01975                 }
01976                 else
01977                 {
01978                     DoubleButtonOption::ActiveButton ab = DoubleButtonOption::None;
01979 
01980                     //Determine whether any of the buttons is active
01981                     //Qt sets both sunken and activeSubControls for active,
01982                     //just activeSubControls for hover.
01983                     if (flags & State_Sunken)
01984                     {
01985                         if (slOpt->activeSubControls & SC_ScrollBarSubLine)
01986                             ab = DoubleButtonOption::Top;
01987 
01988                         if (slOpt->activeSubControls & SC_ScrollBarAddLine)
01989                             ab = DoubleButtonOption::Bottom;
01990                     }
01991 
01992                     //Paint the bevel
01993                     DoubleButtonOption bOpt(ab);
01994                     drawKStylePrimitive(WT_ScrollBar, ScrollBar::DoubleButtonVert,
01995                                         option, r, pal, flags, p, widget, &bOpt);
01996 
01997                     //Paint top button.
01998                     ColorOption colOpt;
01999                     colOpt.color = widgetLayoutProp(WT_ScrollBar, ScrollBar::ArrowColor, option, widget);
02000 
02001                     if (ab == DoubleButtonOption::Top)
02002                         colOpt.color = widgetLayoutProp(WT_ScrollBar, ScrollBar::ActiveArrowColor, option, widget);
02003 
02004 
02005                     QRect topSubButton = QRect(r.x(), r.y(), r.width(), r.height()/2);
02006                     drawKStylePrimitive(WT_ScrollBar, Generic::ArrowUp, option, topSubButton, pal,
02007                                         flags, p, widget, &colOpt);
02008 
02009                     //Paint bot button
02010                     QRect botSubButton;
02011                     botSubButton.setBottomRight(r.bottomRight());
02012                     botSubButton.setLeft       (r.left());
02013                     botSubButton.setTop        (topSubButton.bottom() + 1);
02014 
02015                     colOpt.color = widgetLayoutProp(WT_ScrollBar, ScrollBar::ArrowColor, option, widget);
02016 
02017                     if (ab == DoubleButtonOption::Bottom)
02018                         colOpt.color = widgetLayoutProp(WT_ScrollBar, ScrollBar::ActiveArrowColor, option, widget);
02019 
02020                     drawKStylePrimitive(WT_ScrollBar, Generic::ArrowDown, option, botSubButton, pal,
02021                                         flags, p, widget, &colOpt);
02022                 }
02023             }
02024             else
02025             {   // Single button
02026                 if (flags & State_Horizontal)
02027                 {
02028                     drawKStylePrimitive(WT_ScrollBar, ScrollBar::SingleButtonHor,
02029                                         option, r, pal, flags, p, widget);
02030 
02031                     int  primitive;
02032                     bool active   = false;
02033 
02034                     if (element == CE_ScrollBarAddLine)
02035                     {
02036                         if (slOpt->direction == Qt::LeftToRight)
02037                             primitive = Generic::ArrowRight;
02038                         else
02039                             primitive = Generic::ArrowLeft;
02040 
02041                         if ((slOpt->activeSubControls & SC_ScrollBarAddLine) && (flags & State_Sunken))
02042                             active = true;
02043                     }
02044                     else
02045                     {
02046                         if (slOpt->direction == Qt::LeftToRight)
02047                             primitive = Generic::ArrowLeft;
02048                         else
02049                             primitive = Generic::ArrowRight;
02050 
02051                         if ((slOpt->activeSubControls & SC_ScrollBarSubLine) && (flags & State_Sunken))
02052                             active = true;
02053                     }
02054 
02055                     ColorOption colOpt;
02056                     colOpt.color = widgetLayoutProp(WT_ScrollBar, ScrollBar::ArrowColor, option, widget);
02057                     if (active)
02058                         colOpt.color = widgetLayoutProp(WT_ScrollBar, ScrollBar::ActiveArrowColor, option, widget);
02059 
02060                     drawKStylePrimitive(WT_ScrollBar, primitive, option, r, pal,
02061                                         flags, p, widget, &colOpt);
02062                 }
02063                 else
02064                 {
02065                     drawKStylePrimitive(WT_ScrollBar, ScrollBar::SingleButtonVert,
02066                                         option, r, pal, flags, p, widget);
02067 
02068                     int  primitive;
02069                     bool active   = false;
02070 
02071                     if (element == CE_ScrollBarAddLine)
02072                     {
02073                         primitive = Generic::ArrowDown;
02074                         if ((slOpt->activeSubControls & SC_ScrollBarAddLine) && (flags & State_Sunken))
02075                             active = true;
02076                     }
02077                     else
02078                     {
02079                         primitive = Generic::ArrowUp;
02080                         if ((slOpt->activeSubControls & SC_ScrollBarSubLine) && (flags & State_Sunken))
02081                             active = true;
02082                     }
02083 
02084                     ColorOption colOpt;
02085                     colOpt.color = widgetLayoutProp(WT_ScrollBar, ScrollBar::ArrowColor, option, widget);
02086                     if (active)
02087                         colOpt.color = widgetLayoutProp(WT_ScrollBar, ScrollBar::ActiveArrowColor, option, widget);
02088 
02089                     drawKStylePrimitive(WT_ScrollBar, primitive, option, r, pal,
02090                                         flags, p, widget, &colOpt);
02091                 }
02092             }
02093             return;
02094         }
02095 
02096 // TODO: what about CE_ScrollBarFirst, CE_ScrollBarLast...?
02097 //         case CE_ScrollBarFirst:
02098 //         case CE_ScrollBarLast:
02099 
02100         case CE_ScrollBarSlider:
02101         {
02102             drawKStylePrimitive(WT_ScrollBar,
02103                                 (flags & State_Horizontal) ? ScrollBar::SliderHor  :
02104                                         ScrollBar::SliderVert,
02105                                 option, r, pal, flags, p, widget);
02106             return;
02107         }
02108 
02109         case CE_ScrollBarAddPage:
02110         {
02111             const QStyleOptionSlider* slOpt = ::qstyleoption_cast<const QStyleOptionSlider*>(option);
02112             if (!slOpt) return;
02113 
02114             if (flags & State_Horizontal)
02115                 drawKStylePrimitive(WT_ScrollBar,
02116                                 (slOpt->direction == Qt::LeftToRight) ? ScrollBar::GrooveAreaHorRight :
02117                                         ScrollBar::GrooveAreaHorLeft,
02118                                 option, r, pal, flags, p, widget);
02119             else
02120                 drawKStylePrimitive(WT_ScrollBar, ScrollBar::GrooveAreaVertBottom,
02121                                                      option, r, pal, flags, p, widget);
02122             return;
02123         }
02124 
02125         case CE_ScrollBarSubPage:
02126         {
02127             const QStyleOptionSlider* slOpt = ::qstyleoption_cast<const QStyleOptionSlider*>(option);
02128             if (!slOpt) return;
02129 
02130             if (flags & State_Horizontal)
02131                 drawKStylePrimitive(WT_ScrollBar,
02132                                 (slOpt->direction == Qt::LeftToRight) ? ScrollBar::GrooveAreaHorLeft :
02133                                         ScrollBar::GrooveAreaHorRight,
02134                                 option, r, pal, flags, p, widget);
02135             else
02136                 drawKStylePrimitive(WT_ScrollBar, ScrollBar::GrooveAreaVertTop,
02137                                                      option, r, pal, flags, p, widget);
02138             return;
02139         }
02140 
02141         //QCS's CE_TabBarTab is perfectly fine, so we just handle the subbits
02142 
02143         case CE_TabBarTabShape:
02144         {
02145             const QStyleOptionTab* tabOpt = qstyleoption_cast<const QStyleOptionTab*>(option);
02146             if (!tabOpt) return;
02147 
02148             // TabOverlap handling
02149             int tabOverlap = pixelMetric(PM_TabBarTabOverlap, option, widget);
02150             bool beginning = tabOpt->position == QStyleOptionTab::Beginning;
02151             bool onlyOne = tabOpt->position == QStyleOptionTab::OnlyOneTab;
02152             if (!beginning && !onlyOne) {
02153                 switch (tabSide(tabOpt)) {
02154                     case North:
02155                     case South:
02156                         if (option->direction == Qt::LeftToRight)
02157                             r.adjust(-tabOverlap, 0, 0, 0);
02158                         else
02159                             r.adjust(0, 0, tabOverlap, 0);
02160                         break;
02161                     case East:
02162                     case West:
02163                         r.adjust(0, -tabOverlap, 0, 0);
02164                     default:
02165                         break;
02166                 }
02167             }
02168 
02169             int prim;
02170             switch (tabSide(tabOpt))
02171             {
02172             case North:
02173                 prim = TabBar::NorthTab; break;
02174             case South:
02175                 prim = TabBar::SouthTab; break;
02176             case East:
02177                 prim = TabBar::EastTab; break;
02178             default:
02179                 prim = TabBar::WestTab; break;
02180             }
02181 
02182             drawKStylePrimitive(WT_TabBar, prim, option, r, pal, flags, p, widget);
02183 
02184             return;
02185         }
02186 
02187         case CE_TabBarTabLabel:
02188         {
02189             const QStyleOptionTab* tabOpt = qstyleoption_cast<const QStyleOptionTab*>(option);
02190             if (!tabOpt) return;
02191 
02192             //First, we get our content region.
02193             QRect labelRect = marginAdjustedTab(tabOpt, TabBar::TabContentsMargin);
02194 
02195             Side tabSd = tabSide(tabOpt);
02196 
02197             //Now, what we do, depends on rotation, LTR vs. RTL, and text/icon combinations.
02198             //First, figure out if we have to deal with icons, and place them if need be.
02199             if (!tabOpt->icon.isNull())
02200             {
02201                 int iconSize = pixelMetric(PM_SmallIconSize);
02202                 IconOption icoOpt;
02203                 icoOpt.icon   = tabOpt->icon;
02204                 icoOpt.active = flags & State_Selected;
02205 
02206                 if (tabOpt->text.isNull())
02207                 {
02208                     //Icon only. Easy.
02209                     drawKStylePrimitive(WT_TabBar, Generic::Icon, option, labelRect,
02210                                         pal, flags, p, widget, &icoOpt);
02211                     return;
02212                 }
02213 
02214                 //OK, we have to stuff both icon and text. So we figure out where to stick the icon.
02215                 QRect iconRect;
02216 
02217                 if (tabSd == North || tabSd == South)
02218                 {
02219                     //OK, this is simple affair, we just pick a side for the icon
02220                     //based on layout direction. (Actually, I guess text
02221                     //would be more accurate, but I am -so- not doing BIDI here)
02222                     if (tabOpt->direction == Qt::LeftToRight)
02223                     {
02224                         //We place icon on the left.
02225                         iconRect = QRect(labelRect.x(), labelRect.y(), iconSize, labelRect.height());
02226 
02227                         //Adjust the text rect.
02228                         labelRect.setLeft(labelRect.x() + iconSize +
02229                             widgetLayoutProp(WT_TabBar, TabBar::TabTextToIconSpace, option, widget));
02230                     }
02231                     else
02232                     {
02233                         //We place icon on the right
02234                         iconRect = QRect(labelRect.x() + labelRect.width() - iconSize, labelRect.y(),
02235                                          iconSize, labelRect.height());
02236                         //Adjust the text rect
02237                         labelRect.setWidth(labelRect.width() - iconSize -
02238                             widgetLayoutProp(WT_TabBar, TabBar::TabTextToIconSpace, option, widget));
02239                     }
02240                 }
02241                 else
02242                 {
02243                     bool aboveIcon = false;
02244                     if (tabSd == West && tabOpt->direction == Qt::RightToLeft)
02245                         aboveIcon = true;
02246                     if (tabSd == East && tabOpt->direction == Qt::LeftToRight)
02247                         aboveIcon = true;
02248 
02249                     if (aboveIcon)
02250                     {
02251                         iconRect = QRect(labelRect.x(), labelRect.y(),
02252                                          labelRect.width(), iconSize);
02253                         labelRect.setTop(labelRect.y() + iconSize +
02254                             widgetLayoutProp(WT_TabBar, TabBar::TabTextToIconSpace, option, widget));
02255                     }
02256                     else
02257                     {
02258                         iconRect = QRect(labelRect.x(), labelRect.y() + labelRect.height() - iconSize,
02259                                          labelRect.width(), iconSize);
02260                         labelRect.setHeight(labelRect.height() - iconSize -
02261                             widgetLayoutProp(WT_TabBar, TabBar::TabTextToIconSpace, option, widget));
02262                     }
02263                 }
02264 
02265                 //Draw the thing
02266                 drawKStylePrimitive(WT_TabBar, Generic::Icon, option, iconRect,
02267                                     pal, flags, p, widget, &icoOpt);
02268             } //if have icon.
02269 
02270             //Draw text
02271             if (!tabOpt->text.isNull())
02272             {
02273                 TextOption lbOpt(tabOpt->text);
02274                 if (widget)
02275                     lbOpt.color = widget->foregroundRole();
02276 
02277                 int primitive = Generic::Text; // For horizontal tabs
02278 
02279                 if (tabSd == East)
02280                     primitive = TabBar::EastText;
02281                 else if (tabSd == West)
02282                     primitive = TabBar::WestText;
02283 
02284                 drawKStylePrimitive(WT_TabBar, primitive, option, labelRect,
02285                                     pal, flags, p, widget, &lbOpt);
02286             }
02287 
02288             //If need be, draw focus rect
02289             if (tabOpt->state & State_HasFocus)
02290             {
02291                 QRect focusRect = marginAdjustedTab(tabOpt, TabBar::TabFocusMargin);
02292                 drawKStylePrimitive(WT_TabBar, Generic::FocusIndicator, option, focusRect,
02293                                     pal, flags, p, widget);
02294             }
02295             return;
02296         }
02297 
02298         case CE_ToolBar:
02299         {
02300             if (flags & State_Horizontal)
02301                 drawKStylePrimitive(WT_ToolBar, ToolBar::PanelHor,option,r,pal,flags,p,widget);
02302             else
02303                 drawKStylePrimitive(WT_ToolBar, ToolBar::PanelVert,option,r,pal,flags,p,widget);
02304 
02305             return;
02306         }
02307 
02308         case CE_HeaderSection:
02309         {
02310             if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
02311                 drawKStylePrimitive(WT_Header, (header->orientation==Qt::Horizontal)?Header::SectionHor:Header::SectionVert,
02312                                     option, r, pal, flags, p, widget);
02313                 return;
02314             }
02315         }
02316 
02317         case CE_HeaderLabel:
02318         {
02319             if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
02320                 QRect textRect = r;
02321                 if (!header->icon.isNull()) {
02322                     bool enabled = flags & State_Enabled;
02323                     QPixmap pm = header->icon.pixmap(pixelMetric(PM_SmallIconSize), enabled?QIcon::Normal:QIcon::Disabled);
02324 
02325                     // TODO: respect header->iconAlignment.
02326                     bool reverseLayout = header->direction == Qt::RightToLeft;
02327                     int iy = r.top()+(r.height()-pm.height())/2;
02328                     int ix = reverseLayout ? r.right()-pm.width() : r.left();
02329                     QRect iconRect = QRect(ix, iy, pm.width(), pm.height() );
02330 
02331                     IconOption iconOpt;
02332                     iconOpt.icon = pm;
02333                     drawKStylePrimitive(WT_Header, Generic::Icon, option, iconRect, pal, flags, p, widget, &iconOpt);
02334 
02335                     // adjust the rect for the text...
02336                     int spacing = widgetLayoutProp(WT_Header, Header::TextToIconSpace, option, widget);
02337                     if (reverseLayout)
02338                     {
02339                         textRect.setRight(r.right()-iconRect.width()-spacing );
02340                     }
02341                     else
02342                     {
02343                         textRect.setLeft(r.x()+iconRect.width()+spacing );
02344                     }
02345                 }
02346 
02347                 TextOption lbOpt(header->text);
02348                 lbOpt.hAlign = header->textAlignment;
02349                 drawKStylePrimitive(WT_Header, Generic::Text, option, textRect, pal, flags, p, widget, &lbOpt);
02350             }
02351             return;
02352         }
02353 
02354         case CE_Splitter:
02355         {
02356             if (flags&State_Horizontal)
02357                 drawKStylePrimitive(WT_Splitter, Splitter::HandleHor, option, r, pal, flags, p, widget);
02358             else
02359                 drawKStylePrimitive(WT_Splitter, Splitter::HandleVert, option, r, pal, flags, p, widget);
02360             return;
02361         }
02362 
02363         default:
02364             break;
02365     }
02366 
02367     QCommonStyle::drawControl(element, option, p, widget);
02368 }
02369 
02370 
02371 int KStyle::styleHint (StyleHint hint, const QStyleOption* option, const QWidget* widget, QStyleHintReturn* returnData) const
02372 {
02373     switch (hint)
02374     {
02375         case SH_MenuBar_MouseTracking:
02376         case SH_Menu_MouseTracking:
02377             return true;
02378 
02379         case SH_TitleBar_NoBorder:
02380             return widgetLayoutProp(WT_Window, Window::NoTitleFrame, option, widget);
02381 
02382         case SH_GroupBox_TextLabelVerticalAlignment:
02383             if (widgetLayoutProp(WT_GroupBox, GroupBox::TextAlignTop, option, widget) )
02384                 return Qt::AlignTop;
02385             else
02386                 return Qt::AlignVCenter;
02387 
02388         case SH_GroupBox_TextLabelColor:
02389         {
02390             ColorMode cm( widgetLayoutProp(WT_GroupBox, GroupBox::TitleTextColor,
02391                           option, widget) );
02392             return cm.color(option ? option->palette : qApp->palette()).rgba();
02393         }
02394 
02395         case SH_DialogButtonLayout:
02396             return QDialogButtonBox::KdeLayout;
02397 
02398         case SH_ScrollBar_MiddleClickAbsolutePosition:
02399             return true;
02400 
02401         // Don't draw the branch as selected in tree views
02402         case SH_ItemView_ShowDecorationSelected:
02403             return false;
02404 
02405         case SH_ItemView_ActivateItemOnSingleClick:
02406             return d->m_componentData.config()->group("KDE").readEntry("SingleClick", KDE_DEFAULT_SINGLECLICK );
02407         case SH_KCustomStyleElement:
02408             if (!widget)
02409                 return 0;
02410             return d->styleElements.value(widget->objectName(), 0);
02411 
02412         // per HIG, align the contents in a form layout to the left
02413         case SH_FormLayoutFormAlignment:
02414             return Qt::AlignLeft | Qt::AlignTop;
02415 
02416         // per HIG, align the labels in a form layout to the right
02417         case SH_FormLayoutLabelAlignment:
02418             return Qt::AlignRight;
02419 
02420         case SH_FormLayoutFieldGrowthPolicy:
02421             return QFormLayout::ExpandingFieldsGrow;
02422 
02423         case SH_FormLayoutWrapPolicy:
02424             return QFormLayout::DontWrapRows;
02425 
02426         case SH_MessageBox_TextInteractionFlags:
02427             return true;
02428 
02429         default:
02430             break;
02431     };
02432 
02433     return QCommonStyle::styleHint(hint, option, widget, returnData);
02434 }
02435 
02436 int KStyle::pixelMetric(PixelMetric metric, const QStyleOption* option, const QWidget* widget) const
02437 {
02438     switch (metric)
02439     {
02440         case PM_DefaultFrameWidth:
02441             if (qstyleoption_cast<const QStyleOptionGroupBox *>(option) )
02442                 return widgetLayoutProp(WT_GroupBox, GroupBox::FrameWidth, option, widget);
02443             else
02444                 return widgetLayoutProp(WT_Generic, Generic::DefaultFrameWidth, option, widget);
02445 
02446         case PM_DefaultChildMargin:
02447         case PM_DefaultTopLevelMargin:
02448             return widgetLayoutProp(WT_Generic, Generic::DefaultLayoutMargin, option, widget);
02449 
02450         case PM_LayoutHorizontalSpacing:
02451         case PM_LayoutVerticalSpacing:
02452             // use layoutSpacingImplementation
02453             return -1;
02454 
02455         case PM_DefaultLayoutSpacing:
02456             return widgetLayoutProp(WT_Generic, Generic::DefaultLayoutSpacing, option, widget);
02457 
02458         case PM_LayoutLeftMargin:
02459         case PM_LayoutTopMargin:
02460         case PM_LayoutRightMargin:
02461         case PM_LayoutBottomMargin:
02462         {
02463             PixelMetric marginMetric;
02464             if ((option && (option->state & QStyle::State_Window))
02465                 || (widget && widget->isWindow())) {
02466                 marginMetric = PM_DefaultTopLevelMargin;
02467             } else {
02468                 marginMetric = PM_DefaultChildMargin;
02469             }
02470             return pixelMetric(marginMetric, option, widget);
02471         }
02472 
02473         case PM_ButtonMargin:
02474             return 0; //Better not return anything here since we already
02475             //incorporated this into SE_PushButtonContents
02476         case PM_ButtonDefaultIndicator:
02477             // PushButton::DefaultIndicatorMargin is used throughout KStyle button
02478             // implementation code, so this probably is not necessary.
02479             // return it in case Apps rely on this metric, though.
02480             return widgetLayoutProp(WT_PushButton, PushButton::DefaultIndicatorMargin, option, widget);
02481         case PM_ButtonShiftHorizontal:
02482             return widgetLayoutProp(WT_PushButton, PushButton::PressedShiftHorizontal, option, widget);
02483         case PM_ButtonShiftVertical:
02484             return widgetLayoutProp(WT_PushButton, PushButton::PressedShiftVertical, option, widget);
02485         case PM_MenuButtonIndicator:
02486             if (qstyleoption_cast<const QStyleOptionToolButton*>(option))
02487                 return widgetLayoutProp(WT_ToolButton, ToolButton::MenuIndicatorSize, option, widget);
02488             else
02489                 return widgetLayoutProp(WT_PushButton, PushButton::MenuIndicatorSize, option, widget);
02490 
02491         case PM_SplitterWidth:
02492             return widgetLayoutProp(WT_Splitter, Splitter::Width, option, widget);
02493 
02494         case PM_IndicatorWidth:
02495         case PM_IndicatorHeight:
02496             return widgetLayoutProp(WT_CheckBox, CheckBox::Size, option, widget);
02497 
02498         case PM_ExclusiveIndicatorWidth:
02499         case PM_ExclusiveIndicatorHeight:
02500             return widgetLayoutProp(WT_RadioButton, RadioButton::Size, option, widget);
02501 
02502         case PM_DockWidgetFrameWidth:
02503             return widgetLayoutProp(WT_DockWidget, DockWidget::FrameWidth, option, widget);
02504 
02505         case PM_DockWidgetSeparatorExtent:
02506             return widgetLayoutProp(WT_DockWidget, DockWidget::SeparatorExtent, option, widget);
02507 
02508         // handle extent only used somewhere in Qt3support, don't care.
02509         // case PM_DockWidgetHandleExtent:
02510 
02511         case PM_DockWidgetTitleMargin:
02512             return widgetLayoutProp(WT_DockWidget, DockWidget::TitleMargin, option, widget);
02513 
02514         case PM_ProgressBarChunkWidth:
02515             return widgetLayoutProp(WT_ProgressBar, ProgressBar::Precision, option, widget);
02516 
02517         case PM_MenuBarPanelWidth:
02518             return 0; //Simplification: just one primitive is used and it includes the border
02519 
02520         case PM_MenuBarHMargin:
02521         {
02522             //Calculate how much extra space we need besides the frame size. We use the left margin
02523             //here, and adjust the total rect by the difference between it and the right margin
02524             int spaceL = widgetLayoutProp(WT_MenuBar, MenuBar::Margin, option, widget) + widgetLayoutProp(WT_MenuBar, MenuBar::Margin + Left, option, widget);
02525 
02526             return spaceL;
02527         }
02528 
02529         case PM_MenuBarVMargin:
02530         {
02531             //As above, we return the top one, and fudge the total size for the bottom.
02532             int spaceT = widgetLayoutProp(WT_MenuBar, MenuBar::Margin, option, widget) + widgetLayoutProp(WT_MenuBar, MenuBar::Margin + Top, option, widget);
02533             return spaceT;
02534         }
02535 
02536         case PM_MenuBarItemSpacing:
02537             return widgetLayoutProp(WT_MenuBar, MenuBar::ItemSpacing, option, widget);
02538 
02539         case PM_MenuDesktopFrameWidth:
02540             return 0; //### CHECKME
02541 
02542         case PM_MenuPanelWidth:
02543             return widgetLayoutProp(WT_Menu, Menu::FrameWidth, option, widget);
02544 
02545             /* ### seems to trigger Qt bug. So we loose the margins for now
02546         case PM_MenuHMargin:
02547         {
02548             //Calculate how much extra space we need besides the frame size. We use the left margin
02549             //here, and adjust the total rect by the difference between it and the right margin
02550             int spaceL = widgetLayoutProp(WT_Menu, Menu::Margin, option, widget) + widgetLayoutProp(WT_Menu, Menu::Margin + Left, option, widget) -
02551                     widgetLayoutProp(WT_Menu, Menu::FrameWidth, option, widget);
02552 
02553             return spaceL;
02554         }
02555 
02556         case PM_MenuVMargin:
02557         {
02558             //As above, we return the top one, and fudge the total size for the bottom.
02559             int spaceT = widgetLayoutProp(WT_Menu, Menu::Margin, option, widget) + widgetLayoutProp(WT_Menu, Menu::Margin + Top, option, widget) -
02560                 widgetLayoutProp(WT_Menu, Menu::FrameWidth, option, widget);
02561             return spaceT;
02562         }     */
02563 
02564         case PM_MenuScrollerHeight:
02565             return widgetLayoutProp(WT_Menu, Menu::ScrollerHeight, option, widget);
02566 
02567         case PM_MenuTearoffHeight:
02568             return widgetLayoutProp(WT_Menu, Menu::TearOffHeight, option, widget);
02569 
02570         case PM_TabBarTabHSpace:
02571         {
02572             const QStyleOptionTab* tabOpt = qstyleoption_cast<const QStyleOptionTab*>(option);
02573             if (tabOpt)
02574             {
02575                 //Perhaps we can avoid the extra margin...
02576                 if (tabOpt->text.isNull() && !tabOpt->icon.isNull())
02577                     return 0;
02578                 if (tabOpt->icon.isNull() && !tabOpt->text.isNull())
02579                     return 0;
02580             }
02581 
02582             return widgetLayoutProp(WT_TabBar, TabBar::TabTextToIconSpace, option, widget);
02583         }
02584 
02585         case PM_TabBarTabVSpace:
02586             return 0;
02587 
02588         case PM_TabBarBaseHeight:
02589             return widgetLayoutProp(WT_TabBar, TabBar::BaseHeight, option, widget);
02590 
02591         case PM_TabBarBaseOverlap:
02592             return widgetLayoutProp(WT_TabBar, TabBar::BaseOverlap, option, widget);
02593 
02594         case PM_TabBarTabOverlap:
02595             return widgetLayoutProp(WT_TabBar, TabBar::TabOverlap, option, widget);
02596 
02597         case PM_TabBarScrollButtonWidth:
02598             return widgetLayoutProp(WT_TabBar, TabBar::ScrollButtonWidth, option, widget);
02599 
02600         case PM_TabBarTabShiftVertical:
02601             return 1;
02602 
02603         case PM_TabBarTabShiftHorizontal:
02604             return 0;
02605 
02606         case PM_SliderControlThickness:
02607             return widgetLayoutProp(WT_Slider, Slider::HandleThickness, option, widget);
02608 
02609         case PM_SliderLength:
02610             return widgetLayoutProp(WT_Slider, Slider::HandleLength, option, widget);
02611 
02612         case PM_SliderThickness:
02613         {
02614             // not sure what the difference to PM_SliderControlThickness actually is
02615             return widgetLayoutProp(WT_Slider, Slider::HandleThickness, option, widget);
02616         }
02617 
02618         case PM_SpinBoxFrameWidth:
02619             return widgetLayoutProp(WT_SpinBox, SpinBox::FrameWidth, option, widget);
02620 
02621         case PM_ComboBoxFrameWidth:
02622             return widgetLayoutProp(WT_ComboBox, ComboBox::FrameWidth, option, widget);
02623 
02624         case PM_HeaderMarkSize:
02625             return widgetLayoutProp(WT_Header, Header::MarkSize, option, widget);
02626 
02627         case PM_HeaderMargin:
02628             return widgetLayoutProp(WT_Header, Header::TextToIconSpace, option, widget);
02629 
02630         case PM_ToolBarFrameWidth:
02631             return widgetLayoutProp(WT_ToolBar, ToolBar::FrameWidth, option, widget);
02632 
02633         case PM_ToolBarHandleExtent:
02634             return widgetLayoutProp(WT_ToolBar, ToolBar::HandleExtent, option, widget);
02635 
02636         case PM_ToolBarSeparatorExtent:
02637             return widgetLayoutProp(WT_ToolBar, ToolBar::SeparatorExtent, option, widget);
02638 
02639         case PM_ToolBarExtensionExtent:
02640             return widgetLayoutProp(WT_ToolBar, ToolBar::ExtensionExtent, option, widget);
02641 
02642         case PM_ToolBarItemMargin:
02643             return widgetLayoutProp(WT_ToolBar, ToolBar::ItemMargin, option, widget);
02644 
02645         case PM_ToolBarItemSpacing:
02646             return widgetLayoutProp(WT_ToolBar, ToolBar::ItemSpacing, option, widget);
02647 
02648         case PM_ScrollBarExtent:
02649             return widgetLayoutProp(WT_ScrollBar, ScrollBar::BarWidth, option, widget);
02650 
02651         case PM_TitleBarHeight:
02652             return widgetLayoutProp(WT_Window, Window::TitleHeight, option, widget);
02653 
02654         default:
02655             break;
02656     }
02657 
02658     return QCommonStyle::pixelMetric(metric, option, widget);
02659 }
02660 
02661 int KStyle::layoutSpacingImplementation(QSizePolicy::ControlType control1, QSizePolicy::ControlType control2, Qt::Orientation orientation, const QStyleOption *option, const QWidget *widget) const
02662 {
02663     Q_UNUSED(control1); Q_UNUSED(control2); Q_UNUSED(orientation);
02664 
02665     return pixelMetric(PM_DefaultLayoutSpacing, option, widget);
02666 }
02667 
02668 
02669 bool KStyle::isVerticalTab(const QStyleOptionTab* tbOpt) const
02670 {
02671     switch (tbOpt->shape)
02672     {
02673     case QTabBar::RoundedWest:
02674     case QTabBar::RoundedEast:
02675     case QTabBar::TriangularWest:
02676     case QTabBar::TriangularEast:
02677         return true;
02678     default:
02679         return false;
02680     }
02681 }
02682 
02683 bool KStyle::isReflectedTab(const QStyleOptionTab* tbOpt) const
02684 {
02685     switch (tbOpt->shape)
02686     {
02687     case QTabBar::RoundedEast:
02688     case QTabBar::TriangularEast:
02689     case QTabBar::RoundedSouth:
02690     case QTabBar::TriangularSouth:
02691         return true;
02692     default:
02693         return false;
02694     }
02695 }
02696 
02697 KStyle::Side KStyle::tabSide(const QStyleOptionTab* tbOpt) const
02698 {
02699     switch (tbOpt->shape)
02700     {
02701     case QTabBar::RoundedEast:
02702     case QTabBar::TriangularEast:
02703         return East;
02704     case QTabBar::RoundedWest:
02705     case QTabBar::TriangularWest:
02706         return West;
02707     case QTabBar::RoundedNorth:
02708     case QTabBar::TriangularNorth:
02709         return North;
02710     default:
02711         return South;
02712     }
02713 }
02714 
02715 QRect KStyle::marginAdjustedTab(const QStyleOptionTab* tabOpt, int property) const
02716 {
02717     QRect r = tabOpt->rect;
02718 
02719     //For region, we first figure out the geometry if it was normal, and adjust.
02720     //this takes some rotating
02721     bool vertical = isVerticalTab (tabOpt);
02722     bool flip     = isReflectedTab(tabOpt);
02723 
02724     QRect idializedGeometry = vertical ? QRect(0, 0, r.height(), r.width())
02725                                         : QRect(0, 0, r.width(),  r.height());
02726 
02727     QRect contentArea = insideMargin(idializedGeometry, WT_TabBar, property, tabOpt, 0);
02728 
02729     int leftMargin  = contentArea.x();
02730     int rightMargin = idializedGeometry.width() - 1 - contentArea.right();
02731     int topMargin   = contentArea.y();
02732     int botMargin   = idializedGeometry.height() - 1 - contentArea.bottom();
02733 
02734     if (vertical)
02735     {
02736         int t       = rightMargin;
02737         rightMargin = topMargin;
02738         topMargin   = leftMargin;
02739         leftMargin  = botMargin;
02740         botMargin   = t;
02741 
02742         if (!flip)
02743             qSwap(leftMargin, rightMargin);
02744     }
02745     else if (flip)
02746     {
02747         qSwap(topMargin, botMargin);
02748         //For horizontal tabs, we also want to reverse stuff for RTL!
02749         if (tabOpt->direction == Qt::RightToLeft)
02750             qSwap(leftMargin, rightMargin);
02751     }
02752 
02753     QRect geom =
02754         QRect(QPoint(leftMargin, topMargin),
02755                 QPoint(r.width()  - 1 - rightMargin,
02756                         r.height() - 1 - botMargin));
02757     geom.translate(r.topLeft());
02758     return geom;
02759 }
02760 
02761 bool KStyle::useSideText(const QStyleOptionProgressBar* pbOpt) const
02762 {
02763     if (widgetLayoutProp(WT_ProgressBar, ProgressBar::SideText) == 0)
02764         return false;
02765 
02766     if (!pbOpt) return false; //Paranoia
02767 
02768     if (!pbOpt->textVisible) return false; //Don't allocate side margin if text display is off...
02769 
02770     if (pbOpt->textAlignment & Qt::AlignHCenter) return false; //### do we want this? we don't
02771                                                               //force indicator to the side outside
02772                                                               //the main otherwise.
02773 
02774     if (pbOpt->minimum == pbOpt->maximum) return false;
02775 
02776     int widthAlloc = pbOpt->fontMetrics.width(QLatin1String("100%"));
02777 
02778     if (pbOpt->fontMetrics.width(pbOpt->text) > widthAlloc)
02779         return false; //Doesn't fit!
02780 
02781     return true;
02782 }
02783 
02784 int KStyle::sideTextWidth(const QStyleOptionProgressBar* pbOpt) const
02785 {
02786     return pbOpt->fontMetrics.width(QLatin1String("100%")) +
02787                                     2*widgetLayoutProp(WT_ProgressBar, ProgressBar::SideTextSpace);
02788 }
02789 
02790 QRect KStyle::subElementRect(SubElement sr, const QStyleOption* option, const QWidget* widget) const
02791 {
02792     QRect r = option->rect;
02793 
02794     switch (sr)
02795     {
02796         case SE_PushButtonContents:
02797         {
02798             const QStyleOptionButton* bOpt = qstyleoption_cast<const QStyleOptionButton*>(option);
02799             if (!bOpt) return r;
02800 
02801             if ((bOpt->features & QStyleOptionButton::DefaultButton) || (bOpt->features & QStyleOptionButton::AutoDefaultButton))
02802                 r = insideMargin(r, WT_PushButton, PushButton::DefaultIndicatorMargin, option, widget);
02803 
02804             return insideMargin(r, WT_PushButton, PushButton::ContentsMargin, option, widget);
02805         }
02806 
02807         case SE_PushButtonFocusRect:
02808         {
02809             const QStyleOptionButton* bOpt = qstyleoption_cast<const QStyleOptionButton*>(option);
02810             if (!bOpt) return r;
02811 
02812             if ((bOpt->features & QStyleOptionButton::DefaultButton) || (bOpt->features & QStyleOptionButton::AutoDefaultButton))
02813                 r = insideMargin(r, WT_PushButton, PushButton::DefaultIndicatorMargin, option, widget);
02814 
02815             return insideMargin(r, WT_PushButton, PushButton::FocusMargin, option, widget);
02816         }
02817 
02818         case SE_ToolBoxTabContents:
02819         {
02820             return insideMargin(r, WT_ToolBoxTab, ToolBoxTab::Margin, option, widget);
02821         }
02822 
02823         case SE_CheckBoxContents:
02824         {
02825             r.setX(r.x() + widgetLayoutProp(WT_CheckBox, CheckBox::Size, option, widget) +
02826                            widgetLayoutProp(WT_CheckBox, CheckBox::BoxTextSpace, option, widget));
02827             return handleRTL(option, r);
02828         }
02829 
02830         case SE_RadioButtonContents:
02831         {
02832             r.setX(r.x() + widgetLayoutProp(WT_RadioButton, RadioButton::Size, option, widget) +
02833                     widgetLayoutProp(WT_RadioButton, RadioButton::BoxTextSpace, option, widget));
02834             return handleRTL(option, r);
02835         }
02836 
02837         case SE_CheckBoxFocusRect:
02838         {
02839             const QStyleOptionButton* bOpt = qstyleoption_cast<const QStyleOptionButton*>(option);
02840             if (!bOpt) return r;
02841 
02842             QRect ret;
02843 
02844             if (bOpt->text.isEmpty())
02845             {
02846                 // first convert, so we can deal with logical coords
02847                 QRect checkRect =
02848                         handleRTL(option, subElementRect(SE_CheckBoxIndicator, option, widget) );
02849                 ret = insideMargin(checkRect, WT_CheckBox, CheckBox::NoLabelFocusMargin, option, widget);
02850             }
02851             else
02852             {
02853                 // first convert, so we can deal with logical coords
02854                 QRect contentsRect =
02855                         handleRTL(option, subElementRect(SE_CheckBoxContents, option, widget) );
02856                 ret = insideMargin(contentsRect, WT_CheckBox, CheckBox::FocusMargin, option, widget);
02857             }
02858             // convert back to screen coords
02859             return handleRTL(option, ret);
02860         }
02861 
02862         case SE_RadioButtonFocusRect:
02863         {
02864             // first convert it back to logical coords
02865             QRect contentsRect =
02866                     handleRTL(option, subElementRect(SE_RadioButtonContents, option, widget) );
02867 
02868             // modify the rect and convert back to screen coords
02869             return handleRTL(option,
02870                              insideMargin(contentsRect, WT_RadioButton,
02871                                           RadioButton::FocusMargin, option, widget) );
02872         }
02873 
02874         case SE_ProgressBarGroove:
02875         {
02876             const QStyleOptionProgressBar* pbOpt = ::qstyleoption_cast<const QStyleOptionProgressBar*>(option);
02877             if (useSideText(pbOpt))
02878             {
02879                 r.setWidth(r.width() - sideTextWidth(pbOpt));
02880                 return r;
02881             }
02882 
02883             //Centering mode --- could be forced or side... so the groove area is everything
02884             return r;
02885         }
02886 
02887         case SE_ProgressBarContents:
02888         {
02889             QRect grooveRect = subElementRect(SE_ProgressBarGroove, option, widget);
02890             return insideMargin(grooveRect, WT_ProgressBar, ProgressBar::GrooveMargin, option, widget);
02891         }
02892 
02893         case SE_ProgressBarLabel:
02894         {
02895             const QStyleOptionProgressBar* pbOpt = ::qstyleoption_cast<const QStyleOptionProgressBar*>(option);
02896             if (useSideText(pbOpt))
02897             {
02898                 int width = sideTextWidth(pbOpt);
02899                 return QRect(r.x() + r.width() - width, r.y(), width, r.height());
02900             }
02901 
02902             //The same as the contents area..
02903             return subElementRect(SE_PushButtonContents, option, widget);
02904         }
02905 
02906         // SE_TabWidgetTabPane implementation in QCommonStyle is perfectly fine.
02907         case SE_TabWidgetTabContents:
02908         {
02909             const QStyleOptionTabWidgetFrame* tabOpt = qstyleoption_cast<const QStyleOptionTabWidgetFrame*>(option);
02910             if (!tabOpt) break;
02911 
02912             // use QCommonStyle's SE_TabWidgetTabPane, and adjust the result
02913             // according to the custom frame width.
02914             QRect pane = QCommonStyle::subElementRect(SE_TabWidgetTabPane, option, widget);
02915             int m   = widgetLayoutProp(WT_TabWidget, TabWidget::ContentsMargin, option, widget);
02916             int top = m+widgetLayoutProp(WT_TabWidget, TabWidget::ContentsMargin+Top,
02917                                          option, widget);
02918             int bot = m+widgetLayoutProp(WT_TabWidget, TabWidget::ContentsMargin+Bot,
02919                                          option, widget);
02920             int left = m+widgetLayoutProp(WT_TabWidget, TabWidget::ContentsMargin+Left,
02921                                          option, widget);
02922             int right = m+widgetLayoutProp(WT_TabWidget, TabWidget::ContentsMargin+Right,
02923                                          option, widget);
02924 
02925             switch (tabOpt->shape) {
02926                 case QTabBar::RoundedNorth:
02927                 case QTabBar::TriangularNorth:
02928                     return pane.adjusted(left,top,-right,-bot);
02929                 case QTabBar::RoundedEast:
02930                 case QTabBar::TriangularEast:
02931                     return pane.adjusted(bot,left, -top,-right);
02932                 case QTabBar::RoundedSouth:
02933                 case QTabBar::TriangularSouth:
02934                     return pane.adjusted(right,bot, -left,-top);
02935                 case QTabBar::RoundedWest:
02936                 case QTabBar::TriangularWest:
02937                     return pane.adjusted(top,right, -bot,-left);
02938             }
02939         }
02940         default:
02941             break;
02942     }
02943 
02944     return QCommonStyle::subElementRect(sr, option, widget);
02945 }
02946 
02947 void  KStyle::drawComplexControl (ComplexControl cc, const QStyleOptionComplex* opt,
02948                                    QPainter *p,      const QWidget* w) const
02949 {
02950     //Extract the stuff we need out of the option
02951     State flags = opt->state;
02952     QRect      r     = opt->rect;
02953     QPalette   pal   = opt->palette;
02954 
02955     switch (cc)
02956     {
02957         case CC_ScrollBar:
02958         {
02959             QStyleOptionComplex* mutableOpt = const_cast<QStyleOptionComplex*>(opt);
02960             if ((mutableOpt->subControls & SC_ScrollBarSubLine) || (mutableOpt->subControls & SC_ScrollBarAddLine))
02961             {
02962                 //If we paint one of the buttons, must paint both!
02963                 mutableOpt->subControls |= SC_ScrollBarSubPage | SC_ScrollBarAddLine;
02964             }
02965             //Note: we falldown to the base intentionally
02966         }
02967         break;
02968 
02969         case CC_Q3ListView:
02970         {
02971             const QStyleOptionQ3ListView* lvOpt = qstyleoption_cast<const QStyleOptionQ3ListView*>(opt);
02972             Q_ASSERT (lvOpt);
02973 
02974             if (lvOpt->subControls & SC_Q3ListView)
02975                 QCommonStyle::drawComplexControl(cc, opt, p, w);
02976 
02977             if (lvOpt->items.isEmpty())
02978                 return;
02979 
02980             // If we have a branch or are expanded...
02981             if (lvOpt->subControls & (SC_Q3ListViewBranch | SC_Q3ListViewExpand))
02982             {
02983                 QStyleOptionQ3ListViewItem item  = lvOpt->items.at(0);
02984 
02985                 int y = r.y();
02986 
02987                 QStyleOption opt; //For painting
02988                 opt.palette   = lvOpt->palette;
02989                 opt.direction = Qt::LeftToRight;
02990 
02991                 //Remap the painter so (0,0) corresponds to the origin
02992                 //of the widget, to help out the line align code.
02993                 //Extract the paint offset. Here be dragons
02994                 //(and not the cute green Patron of the project, either)
02995                 int cX = w ? w->property("contentsX").toInt() : 0;
02996                 int cY = w ? w->property("contentsY").toInt() : 0;
02997 
02998                 QPoint adjustCoords = p->matrix().map(QPoint(0,0)) + QPoint(cX, cY);
02999                 p->translate(-adjustCoords);
03000 
03001                 if (lvOpt->activeSubControls == SC_All && (lvOpt->subControls & SC_Q3ListViewExpand)) {
03002                     //### CHECKME: this is from KStyle3, and needs to be re-checked/tested
03003                     // We only need to draw a vertical line
03004                     //Route through the Qt4 style-call.
03005                     QStyleOption opt;
03006                     opt.rect  = QRect(r.topLeft() + adjustCoords, r.size());
03007                     opt.state = State_Sibling;
03008                     drawPrimitive(PE_IndicatorBranch, &opt, p, 0);
03009                 } else {
03010                     int childPos = 1;
03011 
03012                     // Draw all the expand/close boxes, and nearby branches
03013                     while (childPos < lvOpt->items.size() && y < r.height())
03014                     {
03015                         const QStyleOptionQ3ListViewItem& child = lvOpt->items.at(childPos);
03016                         if (!(child.features & QStyleOptionQ3ListViewItem::Visible))
03017                         {
03018                             childPos++;
03019                             continue;
03020                         }
03021 
03022                         //Route through the Qt4 style-call.
03023                         opt.rect  = QRect(r.x() + adjustCoords.x(), y + adjustCoords.y(),
03024                                           r.width(), child.height);
03025                         opt.state = State_Item;
03026 
03027                         if (child.features & QStyleOptionQ3ListViewItem::Expandable || child.childCount)
03028                         {
03029                             opt.state |= State_Children;
03030                             opt.state |= (child.state & State_Open);
03031                         }
03032 
03033                         //See if we have a visible sibling
03034                         int siblingPos = 0;
03035                         for (siblingPos = childPos + 1; siblingPos < lvOpt->items.size(); ++siblingPos)
03036                         {
03037                             if (lvOpt->items.at(siblingPos).features & QStyleOptionQ3ListViewItem::Visible)
03038                             {
03039                                 opt.state |= State_Sibling;
03040                                 break;
03041                             }
03042                         }
03043 
03044                         //If on screen, paint it
03045                         if (y + child.height > 0)
03046                             drawPrimitive(PE_IndicatorBranch, &opt, p, 0);
03047 
03048                         if (!siblingPos)
03049                             break;
03050 
03051                         //If we have a sibling, and an expander, also have to draw
03052                         //a line for below the immediate area
03053                         if ((opt.state & State_Children) && (opt.state & State_Sibling))
03054                         {
03055                             opt.state = State_Sibling;
03056                             opt.rect  = QRect(r.x() + adjustCoords.x(),
03057                                               y + adjustCoords.y() + child.height,
03058                                               r.width(), child.totalHeight - child.height);
03059                             if (opt.rect.height())
03060                                 drawPrimitive(PE_IndicatorBranch, &opt, p, 0);
03061                         }
03062 
03063                         y += child.totalHeight;
03064                         childPos = siblingPos;
03065                     } //loop through items
03066                 } //complex case
03067 
03068                 p->translate(adjustCoords);
03069             } //if have branch or expander
03070         } //CC_Q3ListView
03071         break;
03072 
03073         case CC_Slider:
03074         {
03075             if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt))
03076             {
03077                 QRect groove = subControlRect(CC_Slider, slider, SC_SliderGroove, w);
03078                 QRect handle = subControlRect(CC_Slider, slider, SC_SliderHandle, w);
03079                 bool hor = slider->orientation == Qt::Horizontal;
03080 
03081                 if (slider->subControls & SC_SliderTickmarks)
03082                 {
03083                     // TODO: make tickmarks customizable with Slider::Tickmark-primitives?
03084                     QStyleOptionSlider tmpSlider = *slider;
03085                     tmpSlider.subControls = SC_SliderTickmarks;
03086                     QCommonStyle::drawComplexControl(cc, &tmpSlider, p, w);
03087                 }
03088 
03089                 if ((slider->subControls & SC_SliderGroove) && groove.isValid())
03090                 {
03091                     drawKStylePrimitive(WT_Slider, hor ? Slider::GrooveHor : Slider::GrooveVert, opt, groove, pal, flags, p, w);
03092                 }
03093 
03094                 if (slider->subControls & SC_SliderHandle)
03095                 {
03096                     drawKStylePrimitive(WT_Slider, hor ? Slider::HandleHor : Slider::HandleVert, opt, handle, pal, flags, p, w);
03097 
03098                     if (slider->state & State_HasFocus) {
03099                         QRect focus = subElementRect(SE_SliderFocusRect, slider, w);
03100                         drawKStylePrimitive(WT_Slider, Generic::FocusIndicator, opt, focus, pal, flags, p, w, 0);
03101                     }
03102                 }
03103             } //option OK
03104             return;
03105         } //CC_Slider
03106 
03107         case CC_SpinBox:
03108         {
03109             if (const QStyleOptionSpinBox *sb = qstyleoption_cast<const QStyleOptionSpinBox *>(opt) )
03110             {
03111                 bool activeSbUp = sb->activeSubControls&SC_SpinBoxUp && (flags & State_Sunken);
03112                 bool activeSbDown = sb->activeSubControls&SC_SpinBoxDown && (flags & State_Sunken);
03113 
03114                 if (sb->subControls & SC_SpinBoxFrame)
03115                 {
03116                     drawKStylePrimitive(WT_SpinBox, Generic::Frame, opt, r, pal, flags, p, w);
03117                 }
03118 
03119                 if (sb->subControls & SC_SpinBoxEditField)
03120                 {
03121                     QRect editField = subControlRect(CC_SpinBox, opt, SC_SpinBoxEditField, w);
03122                     drawKStylePrimitive(WT_SpinBox, SpinBox::EditField, opt, editField, pal, flags, p, w);
03123                 }
03124 
03125                 QRect upRect, downRect;
03126                 if (sb->subControls & (SC_SpinBoxUp | SC_SpinBoxDown))
03127                 {
03128                     upRect   = subControlRect(CC_SpinBox, opt, SC_SpinBoxUp,   w);
03129                     downRect = subControlRect(CC_SpinBox, opt, SC_SpinBoxDown, w);
03130                     QRect buttonAreaRect = upRect | downRect;
03131                     drawKStylePrimitive(WT_SpinBox, SpinBox::ButtonArea, opt, buttonAreaRect, pal, flags, p, w);
03132                 }
03133 
03134                 if (sb->subControls & SC_SpinBoxUp)
03135                 {
03136                     // adjust the sunken state flag...
03137                     State upFlags = flags;
03138                     if (activeSbUp)
03139                         upFlags |= State_Sunken;
03140                     else
03141                         upFlags &= ~State_Sunken;
03142 
03143                     drawKStylePrimitive(WT_SpinBox, SpinBox::UpButton, opt, upRect, pal, upFlags, p, w);
03144 
03145                     // draw symbol...
03146                     int primitive;
03147                     if (sb->buttonSymbols == QAbstractSpinBox::PlusMinus)
03148                         primitive = SpinBox::PlusSymbol;
03149                     else
03150                         primitive = Generic::ArrowUp;
03151                     drawKStylePrimitive(WT_SpinBox, primitive, opt, upRect, pal, upFlags, p, w);
03152                 }
03153 
03154                 if (sb->subControls & SC_SpinBoxDown)
03155                 {
03156                     // adjust the sunken state flag...
03157                     State downFlags = flags;
03158                     if (activeSbDown)
03159                         downFlags |= State_Sunken;
03160                     else
03161                         downFlags &= ~State_Sunken;
03162 
03163                     drawKStylePrimitive(WT_SpinBox, SpinBox::DownButton, opt, downRect, pal, downFlags, p, w);
03164 
03165                     // draw symbol...
03166                     int primitive;
03167                     if (sb->buttonSymbols == QAbstractSpinBox::PlusMinus)
03168                         primitive = SpinBox::MinusSymbol;
03169                     else
03170                         primitive = Generic::ArrowDown;
03171                     drawKStylePrimitive(WT_SpinBox, primitive, opt, downRect, pal, downFlags, p, w);
03172                 }
03173 
03174                 return;
03175             } //option OK
03176         } //CC_SpinBox
03177 
03178         case CC_ComboBox:
03179         {
03180             if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(opt) )
03181             {
03182                 if (cb->subControls & SC_ComboBoxFrame)
03183                 {
03184                     drawKStylePrimitive(WT_ComboBox, Generic::Frame, opt, r, pal, flags, p, w);
03185 
03186                     // focus indicator
03187                     if (cb->state & State_HasFocus) {
03188                         QRect editField = subControlRect(CC_ComboBox, opt, SC_ComboBoxEditField, w);
03189                         QRect focusRect = insideMargin(editField, WT_ComboBox, ComboBox::FocusMargin, opt, w);
03190                         drawKStylePrimitive(WT_ComboBox, Generic::FocusIndicator, opt, focusRect, pal, flags, p, w, 0);
03191                     }
03192                 }
03193 
03194                 if (cb->subControls & SC_ComboBoxEditField)
03195                 {
03196                     QRect editField = subControlRect(CC_ComboBox, opt, SC_ComboBoxEditField, w);
03197                     drawKStylePrimitive(WT_ComboBox, ComboBox::EditField, opt, editField, pal, flags, p, w);
03198                 }
03199 
03200                 if (cb->subControls & SC_ComboBoxArrow)
03201                 {
03202                     QRect buttonRect = subControlRect(CC_ComboBox, opt, SC_ComboBoxArrow, w);
03203                     drawKStylePrimitive(WT_ComboBox, ComboBox::Button, opt, buttonRect, pal, flags, p, w);
03204 
03205                     // draw symbol...
03206                     drawKStylePrimitive(WT_ComboBox, Generic::ArrowDown, opt, buttonRect, pal, flags, p, w);
03207                 }
03208 
03209                 return;
03210             } //option OK
03211             break;
03212         } //CC_Combo
03213 
03214         case CC_ToolButton:
03215         {
03216             if (const QStyleOptionToolButton *tool = qstyleoption_cast<const QStyleOptionToolButton *>(opt)) {
03217                 QRect buttonRect = subControlRect(cc, tool, SC_ToolButton, w);
03218                 QRect menuRect = subControlRect(cc, tool, SC_ToolButtonMenu, w);
03219 
03220                 // State_AutoRaise: only draw button when State_MouseOver
03221                 State bflags = tool->state;
03222                 if (bflags & State_AutoRaise) {
03223                     if (!(bflags & State_MouseOver)) {
03224                         bflags &= ~State_Raised;
03225                     }
03226                 }
03227                 State mflags = bflags;
03228 
03229                 // mouse pressed...
03230                 if (tool->activeSubControls & SC_ToolButton)
03231                     bflags |= State_Sunken;
03232                 if (tool->activeSubControls & SC_ToolButtonMenu)
03233                     mflags |= State_Sunken;
03234 
03235                 QStyleOption tOpt(0);
03236                 tOpt.palette = pal;
03237 
03238                 if (tool->subControls & SC_ToolButton) {
03239                     if (bflags & (State_Sunken | State_On | State_Raised)) {
03240                         tOpt.rect = buttonRect;
03241                         tOpt.state = bflags;
03242                         drawPrimitive(PE_PanelButtonTool, &tOpt, p, w);
03243                     }
03244                 }
03245 
03246                 if (tool->subControls & SC_ToolButtonMenu) {
03247                     tOpt.rect = menuRect;
03248                     tOpt.state = mflags;
03249                     drawPrimitive(PE_IndicatorButtonDropDown, &tOpt, p, w);
03250                 } else if (tool->features & QStyleOptionToolButton::HasMenu) {
03251                     // This is requesting KDE3-style arrow indicator, per Qt 4.4 behavior. Qt 4.3 prefers to hide
03252                     // the fact of the menu's existence. Whee! Since we don't know how to paint this right,
03253                     // though, we have to have some metrics set for it to look nice.
03254                     int size = widgetLayoutProp(WT_ToolButton, ToolButton::InlineMenuIndicatorSize, opt, w);
03255 
03256                     if (size) {
03257                         int xOff = widgetLayoutProp(WT_ToolButton, ToolButton::InlineMenuIndicatorXOff, opt, w);
03258                         int yOff = widgetLayoutProp(WT_ToolButton, ToolButton::InlineMenuIndicatorYOff, opt, w);
03259 
03260                         QRect r = QRect(buttonRect.right() + xOff, buttonRect.bottom() + yOff, size, size);
03261                         tOpt.rect  = r;
03262                         tOpt.state = bflags;
03263                         drawPrimitive(PE_IndicatorButtonDropDown, &tOpt, p, w);
03264                     }
03265                 }
03266 
03267                 if (flags & State_HasFocus) {
03268                     QRect focusRect = insideMargin(r, WT_ToolButton, ToolButton::FocusMargin, opt, w);
03269                     tOpt.rect = focusRect;
03270                     tOpt.state = bflags;
03271                     drawKStylePrimitive(WT_ToolButton, Generic::FocusIndicator, &tOpt, focusRect, pal, bflags, p, w);
03272                 }
03273 
03274                 // CE_ToolButtonLabel expects a readjusted rect, for the button area proper
03275                 QStyleOptionToolButton labelOpt = *tool;
03276                 labelOpt.rect = buttonRect;
03277                 drawControl(CE_ToolButtonLabel, &labelOpt, p, w);
03278 
03279                 return;
03280             }
03281             break;
03282         } //CC_ToolButton
03283 
03284         case CC_TitleBar:
03285         {
03286             const QStyleOptionTitleBar *tb =
03287                     qstyleoption_cast<const QStyleOptionTitleBar *>(opt);
03288             if (!tb)
03289                 break;
03290 
03291             // title bar
03292             drawKStylePrimitive(WT_Window, Window::TitlePanel, opt, r, pal, flags, p, w);
03293 
03294             // TODO: different color depending on Active/inactive state
03295             // draw title text
03296             QRect textRect = subControlRect(CC_TitleBar, tb, SC_TitleBarLabel, w);
03297             TextOption textOpt(tb->text);
03298             textOpt.color = widgetLayoutProp(WT_Window, Window::TitleTextColor, opt, w);
03299             drawKStylePrimitive(WT_Window, Generic::Text, opt, textRect,
03300                                 pal, flags, p, w, &textOpt);
03301 
03302             TitleButtonOption buttonKOpt;
03303             buttonKOpt.icon = tb->icon;
03304 
03305             if ((tb->subControls & SC_TitleBarSysMenu) &&
03306                  (tb->titleBarFlags & Qt::WindowSystemMenuHint))
03307             {
03308                 buttonKOpt.active = (tb->activeSubControls & SC_TitleBarSysMenu)
03309                         && (tb->state & State_Sunken);
03310                 QRect br = subControlRect(CC_TitleBar, tb, SC_TitleBarSysMenu, w);
03311                 drawKStylePrimitive(WT_Window, Window::ButtonMenu, opt, br, pal, flags, p, w,
03312                                    &buttonKOpt);
03313             }
03314 
03315             if ((tb->subControls & SC_TitleBarMinButton) &&
03316                  (tb->titleBarFlags & Qt::WindowMinimizeButtonHint))
03317             {
03318                 buttonKOpt.active = (tb->activeSubControls & SC_TitleBarMinButton)
03319                         && (tb->state & State_Sunken);
03320                 QRect br = subControlRect(CC_TitleBar, tb, SC_TitleBarMinButton, w);
03321                 drawKStylePrimitive(WT_Window, Window::ButtonMin, opt, br, pal, flags, p, w,
03322                                     &buttonKOpt);
03323             }
03324 
03325             if ((tb->subControls & SC_TitleBarMaxButton) &&
03326                  (tb->titleBarFlags & Qt::WindowMaximizeButtonHint))
03327             {
03328                 buttonKOpt.active = (tb->activeSubControls & SC_TitleBarMaxButton)
03329                         && (tb->state & State_Sunken);
03330                 QRect br = subControlRect(CC_TitleBar, tb, SC_TitleBarMaxButton, w);
03331                 drawKStylePrimitive(WT_Window, Window::ButtonMax, opt, br, pal, flags, p, w,
03332                                     &buttonKOpt);
03333             }
03334 
03335             if ((tb->subControls & SC_TitleBarCloseButton) &&
03336                  (tb->titleBarFlags & Qt::WindowSystemMenuHint))
03337             {
03338 //                 bool hover = (tb->activeSubControls & SC_TitleBarCloseButton)
03339 //                         && (tb->state & State_MouseOver);
03340                 buttonKOpt.active = (tb->activeSubControls & SC_TitleBarCloseButton)
03341                         && (tb->state & State_Sunken);
03342                 QRect br = subControlRect(CC_TitleBar, tb, SC_TitleBarCloseButton, w);
03343                 drawKStylePrimitive(WT_Window, Window::ButtonClose, opt, br, pal, flags, p, w,
03344                                     &buttonKOpt);
03345             }
03346 
03347             if ((tb->subControls & SC_TitleBarNormalButton) &&
03348                  (((tb->titleBarFlags & Qt::WindowMinimizeButtonHint) &&
03349                  (tb->titleBarState & Qt::WindowMinimized)) ||
03350                  ((tb->titleBarFlags & Qt::WindowMaximizeButtonHint) &&
03351                  (tb->titleBarState & Qt::WindowMaximized))))
03352             {
03353                 buttonKOpt.active = (tb->activeSubControls & SC_TitleBarNormalButton)
03354                         && (tb->state & State_Sunken);
03355                 QRect br = subControlRect(CC_TitleBar, tb, SC_TitleBarNormalButton, w);
03356                 drawKStylePrimitive(WT_Window, Window::ButtonRestore, opt, br, pal, flags, p, w,
03357                                     &buttonKOpt);
03358             }
03359 
03360             if (tb->subControls & SC_TitleBarShadeButton)
03361             {
03362                 buttonKOpt.active = (tb->activeSubControls & SC_TitleBarShadeButton)
03363                         && (tb->state & State_Sunken);
03364                 QRect br = subControlRect(CC_TitleBar, tb, SC_TitleBarShadeButton, w);
03365                 drawKStylePrimitive(WT_Window, Window::ButtonShade, opt, br, pal, flags, p, w,
03366                                     &buttonKOpt);
03367             }
03368 
03369             if (tb->subControls & SC_TitleBarUnshadeButton)
03370             {
03371                 buttonKOpt.active = (tb->activeSubControls & SC_TitleBarUnshadeButton)
03372                         && (tb->state & State_Sunken);
03373                 QRect br = subControlRect(CC_TitleBar, tb, SC_TitleBarUnshadeButton, w);
03374                 drawKStylePrimitive(WT_Window, Window::ButtonUnshade, opt, br, pal, flags, p, w,
03375                                     &buttonKOpt);
03376             }
03377 
03378             if ((tb->subControls & SC_TitleBarContextHelpButton)
03379                 && (tb->titleBarFlags & Qt::WindowContextHelpButtonHint))
03380             {
03381                 buttonKOpt.active = (tb->activeSubControls & SC_TitleBarContextHelpButton)
03382                         && (tb->state & State_Sunken);
03383                 QRect br = subControlRect(CC_TitleBar, tb, SC_TitleBarContextHelpButton, w);
03384                 drawKStylePrimitive(WT_Window, Window::ButtonHelp, opt, br, pal, flags, p, w,
03385                                     &buttonKOpt);
03386             }
03387 
03388             return;
03389         } // CC_TitleBar
03390 
03391         default:
03392             break;
03393     } //switch
03394 
03395     QCommonStyle::drawComplexControl(cc, opt, p, w);
03396 }
03397 
03398 
03399 QRect KStyle::internalSubControlRect (ComplexControl control, const QStyleOptionComplex* option,
03400                                        SubControl subControl, const QWidget* widget) const
03401 {
03402     QRect r = option->rect;
03403 
03404     if (control == CC_ScrollBar)
03405     {
03406         switch (subControl)
03407         {
03408             //The "top" arrow
03409             case SC_ScrollBarSubLine:
03410             {
03411                 int majorSize;
03412                 if (widgetLayoutProp(WT_ScrollBar, ScrollBar::DoubleTopButton, option, widget))
03413                     majorSize = widgetLayoutProp(WT_ScrollBar, ScrollBar::DoubleButtonHeight, option, widget);
03414                 else
03415                     majorSize = widgetLayoutProp(WT_ScrollBar, ScrollBar::SingleButtonHeight, option, widget);
03416 
03417                 if (option->state & State_Horizontal)
03418                     return handleRTL(option, QRect(r.x(), r.y(), majorSize, r.height()));
03419                 else
03420                     return handleRTL(option, QRect(r.x(), r.y(), r.width(), majorSize));
03421 
03422             }
03423 
03424             //The "bottom" arrow
03425             case SC_ScrollBarAddLine:
03426             {
03427                 int majorSize;
03428                 if (widgetLayoutProp(WT_ScrollBar, ScrollBar::DoubleBotButton, option, widget))
03429                     majorSize = widgetLayoutProp(WT_ScrollBar, ScrollBar::DoubleButtonHeight, option, widget);
03430                 else
03431                     majorSize = widgetLayoutProp(WT_ScrollBar, ScrollBar::SingleButtonHeight, option, widget);
03432 
03433                 if (option->state & State_Horizontal)
03434                     return handleRTL(option, QRect(r.right() - majorSize + 1, r.y(), majorSize, r.height()));
03435                 else
03436                     return handleRTL(option, QRect(r.x(), r.bottom() - majorSize + 1, r.width(), majorSize));
03437             }
03438 
03439             default:
03440                 break;
03441         }
03442     }
03443 
03444     return QRect();
03445 }
03446 
03447 
03448 QRect KStyle::subControlRect(ComplexControl control, const QStyleOptionComplex* option,
03449                                 SubControl subControl, const QWidget* widget) const
03450 {
03451     QRect r = option->rect;
03452 
03453     switch (control)
03454     {
03455         case CC_ScrollBar:
03456         {
03457             switch (subControl)
03458             {
03459                 //For both arrows, we return -everything-,
03460                 //to get stuff to repaint right. See internalSubControlRect
03461                 //for the real thing
03462                 case SC_ScrollBarSubLine:
03463                 case SC_ScrollBarAddLine:
03464                     return r;
03465 
03466                 //The main groove area. This is used to compute the others...
03467                 case SC_ScrollBarGroove:
03468                 {
03469                     QRect top = handleRTL(option, internalSubControlRect(control, option, SC_ScrollBarSubLine, widget));
03470                     QRect bot = handleRTL(option, internalSubControlRect(control, option, SC_ScrollBarAddLine, widget));
03471 
03472                     QPoint topLeftCorner, botRightCorner;
03473                     if (option->state & State_Horizontal)
03474                     {
03475                         topLeftCorner  = QPoint(top.right() + 1, top.top());
03476                         botRightCorner = QPoint(bot.left()  - 1, top.bottom());
03477                     }
03478                     else
03479                     {
03480                         topLeftCorner  = QPoint(top.left(),  top.bottom() + 1);
03481                         botRightCorner = QPoint(top.right(), bot.top()    - 1);
03482                     }
03483 
03484                     return handleRTL(option, QRect(topLeftCorner, botRightCorner));
03485                 }
03486 
03487                 case SC_ScrollBarFirst:
03488                 case SC_ScrollBarLast:
03489                     return QRect();
03490 
03491                 case SC_ScrollBarSlider:
03492                 {
03493                     const QStyleOptionSlider* slOpt = ::qstyleoption_cast<const QStyleOptionSlider*>(option);
03494 
03495                     //We do handleRTL here to unreflect things if need be
03496                     QRect groove = handleRTL(option, subControlRect(control, option, SC_ScrollBarGroove, widget));
03497             Q_ASSERT (slOpt);
03498 
03499                     if (slOpt->minimum == slOpt->maximum)
03500                         return groove;
03501 
03502                     //Figure out how much room we have..
03503                     int space;
03504                     if (option->state & State_Horizontal)
03505                         space = groove.width();
03506                     else
03507                         space = groove.height();
03508 
03509                     //Calculate the portion of this space that the slider should take up.
03510                     int sliderSize = int(space * float(slOpt->pageStep) /
03511                                             (slOpt->maximum - slOpt->minimum + slOpt->pageStep));
03512 
03513                     if (sliderSize < widgetLayoutProp(WT_ScrollBar, ScrollBar::MinimumSliderHeight, option, widget))
03514                         sliderSize = widgetLayoutProp(WT_ScrollBar, ScrollBar::MinimumSliderHeight, option, widget);
03515 
03516                     if (sliderSize > space)
03517                         sliderSize = space;
03518 
03519                     //What do we have remaining?
03520                     space = space - sliderSize;
03521 
03522                     //uhm, yeah, nothing much
03523                     if (space <= 0)
03524                         return groove;
03525 
03526                     int pos = qRound(float(slOpt->sliderPosition - slOpt->minimum)/
03527                                             (slOpt->maximum - slOpt->minimum)*space);
03528                     if (option->state & State_Horizontal)
03529                         return handleRTL(option, QRect(groove.x() + pos, groove.y(), sliderSize, groove.height()));
03530                     else
03531                         return handleRTL(option, QRect(groove.x(), groove.y() + pos, groove.width(), sliderSize));
03532                 }
03533 
03534                 case SC_ScrollBarSubPage:
03535                 {
03536                     //We do handleRTL here to unreflect things if need be
03537                     QRect slider = handleRTL(option, subControlRect(control, option, SC_ScrollBarSlider, widget));
03538                     QRect groove = handleRTL(option, subControlRect(control, option, SC_ScrollBarGroove, widget));
03539 
03540                     //We're above the slider in the groove.
03541                     if (option->state & State_Horizontal)
03542                         return handleRTL(option, QRect(groove.x(), groove.y(), slider.x() - groove.x(), groove.height()));
03543                     else
03544                         return handleRTL(option, QRect(groove.x(), groove.y(), groove.width(), slider.y() - groove.y()));
03545                 }
03546 
03547                 case SC_ScrollBarAddPage:
03548                 {
03549                     //We do handleRTL here to unreflect things if need be
03550                     QRect slider = handleRTL(option, subControlRect(control, option, SC_ScrollBarSlider, widget));
03551                     QRect groove = handleRTL(option, subControlRect(control, option, SC_ScrollBarGroove, widget));
03552 
03553                     //We're below the slider in the groove.
03554                     if (option->state & State_Horizontal)
03555                         return handleRTL(option,
03556                                 QRect(slider.right() + 1, groove.y(), groove.right() - slider.right(), groove.height()));
03557                     else
03558                         return handleRTL(option,
03559                                 QRect(groove.x(), slider.bottom() + 1, groove.width(), groove.bottom() - slider.bottom()));
03560                 }
03561 
03562                 default:
03563                     break;
03564             }
03565         } //CC_ScrollBar
03566 
03567         case CC_SpinBox:
03568         {
03569             if (const QStyleOptionSpinBox *sb = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) {
03570 
03571                 int fw = widgetLayoutProp(WT_SpinBox, SpinBox::FrameWidth, option, widget);
03572                 int bw = widgetLayoutProp(WT_SpinBox, SpinBox::ButtonWidth, option, widget);
03573                 int bm = widgetLayoutProp(WT_SpinBox, SpinBox::ButtonMargin, option, widget);
03574                 int bml = bm + widgetLayoutProp(WT_SpinBox, SpinBox::ButtonMargin + Left, option, widget);
03575                 int bmr = bm + widgetLayoutProp(WT_SpinBox, SpinBox::ButtonMargin + Right, option, widget);
03576                 int bmt = bm + widgetLayoutProp(WT_SpinBox, SpinBox::ButtonMargin + Top, option, widget);
03577                 int bmb = bm + widgetLayoutProp(WT_SpinBox, SpinBox::ButtonMargin + Bot, option, widget);
03578                 int bs = widgetLayoutProp(WT_SpinBox, SpinBox::ButtonSpacing, option, widget);
03579                 bool symmButtons = widgetLayoutProp(WT_SpinBox, SpinBox::SymmetricButtons, option, widget);
03580                 bool supportFrameless = widgetLayoutProp(WT_SpinBox, SpinBox::SupportFrameless, option, widget);
03581 
03582                 // SpinBox without a frame, set the corresponding layout values to 0, reduce button width.
03583                 if (supportFrameless && !sb->frame)
03584                 {
03585                     bw = bw - bmr; // reduce button with as the right button margin will be ignored.
03586                     fw = 0;
03587                     bmt = bmb = bmr = 0;
03588                 }
03589 
03590                 const int buttonsWidth = bw-bml-bmr;
03591                 const int buttonsLeft = r.right()-bw+bml+1;
03592 
03593                 // compute the height of each button...
03594                 int availableButtonHeight = r.height()-bmt-bmb - bs;
03595                 if (symmButtons)
03596                 {
03597                     // make sure the availableButtonHeight is even by reducing the
03598                     // button spacing by 1 if necessary. Results in both buttons
03599                     // of the same height...
03600                     if (availableButtonHeight%2 != 0)
03601                     {
03602                         --bs;
03603 
03604                         // recalculate...
03605                         availableButtonHeight = r.height()-bmt-bmb - bs;
03606                     }
03607                 }
03608                 int heightUp = availableButtonHeight / 2;
03609                 int heightDown = availableButtonHeight - heightUp;
03610 
03611 
03612                 switch (subControl) {
03613                     case SC_SpinBoxUp:
03614                         return handleRTL(option,
03615                                          QRect(buttonsLeft, r.top()+bmt, buttonsWidth, heightUp) );
03616                     case SC_SpinBoxDown:
03617                         return handleRTL(option,
03618                                          QRect(buttonsLeft, r.bottom()-bmb-heightDown+1, buttonsWidth, heightDown) );
03619                     case SC_SpinBoxEditField:
03620                     {
03621                         QRect labelRect(r.left()+fw, r.top()+fw, r.width()-fw-bw, r.height()-2*fw);
03622                         labelRect = insideMargin(labelRect, WT_SpinBox, SpinBox::ContentsMargin, option, widget);
03623                         return handleRTL(option, labelRect );
03624                     }
03625                     case SC_SpinBoxFrame:
03626                         return (sb->frame || !supportFrameless) ? r : QRect();
03627                     default:
03628                         break;
03629                 }
03630             } //option ok
03631         } //CC_SpinBox
03632 
03633         case CC_ComboBox:
03634         {
03635             if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
03636 
03637                 int fw = widgetLayoutProp(WT_ComboBox, ComboBox::FrameWidth, option, widget);
03638                 int bw = widgetLayoutProp(WT_ComboBox, ComboBox::ButtonWidth, option, widget);
03639                 int bm = widgetLayoutProp(WT_ComboBox, ComboBox::ButtonMargin, option, widget);
03640                 int bml = bm + widgetLayoutProp(WT_ComboBox, ComboBox::ButtonMargin + Left, option, widget);
03641                 int bmr = bm + widgetLayoutProp(WT_ComboBox, ComboBox::ButtonMargin + Right, option, widget);
03642                 int bmt = bm + widgetLayoutProp(WT_ComboBox, ComboBox::ButtonMargin + Top, option, widget);
03643                 int bmb = bm + widgetLayoutProp(WT_ComboBox, ComboBox::ButtonMargin + Bot, option, widget);
03644                 bool supportFrameless = widgetLayoutProp(WT_ComboBox, ComboBox::SupportFrameless, option, widget);
03645 
03646                 // ComboBox without a frame, set the corresponding layout values to 0, reduce button width.
03647                 if (supportFrameless && !cb->frame)
03648                 {
03649                     bw = bw - bmr; // reduce button with as the right button margin will be ignored.
03650                     fw = 0;
03651                     bmt = bmb = bmr = 0;
03652                 }
03653 
03654                 switch (subControl) {
03655                     case SC_ComboBoxFrame:
03656                         return (cb->frame || !supportFrameless) ? r : QRect();
03657                     case SC_ComboBoxArrow:
03658                         return handleRTL(option,
03659                                          QRect(r.right()-bw+bml+1, r.top()+bmt, bw-bml-bmr, r.height()-bmt-bmb) );
03660                     case SC_ComboBoxEditField:
03661                     {
03662                         QRect labelRect(r.left()+fw, r.top()+fw, r.width()-fw-bw, r.height()-2*fw);
03663                         labelRect = insideMargin(labelRect, WT_ComboBox, ComboBox::ContentsMargin, option, widget);
03664                         return handleRTL(option, labelRect );
03665                     }
03666                     case SC_ComboBoxListBoxPopup:
03667                         // TODO: need to add layoutProps to control the popup rect?
03668 //                         return cb->popupRect;
03669                         // popupRect seems to be empty, so use QStyleOption::rect as Qt's styles do
03670                         return r;
03671                     default:
03672                         break;
03673                 }
03674             } //option ok
03675         } //CC_ComboBox
03676 
03677         case CC_TitleBar:
03678         {
03679             const QStyleOptionTitleBar *tbOpt =
03680                     qstyleoption_cast<const QStyleOptionTitleBar *>(option);
03681             if (!tbOpt)
03682                 break;
03683 
03684             QRect ret = insideMargin(r, WT_Window, Window::TitleMargin, option, widget);
03685 
03686             const int btnHeight = ret.height();
03687             const int btnWidth = widgetLayoutProp(WT_Window, Window::ButtonWidth, option, widget);
03688             const int btnSpace = widgetLayoutProp(WT_Window, Window::ButtonSpace, option, widget);
03689             const int titleSpace = widgetLayoutProp(WT_Window, Window::ButtonToTextSpace, option, widget);
03690 
03691             bool isMinimized = tbOpt->titleBarState & Qt::WindowMinimized;
03692             bool isMaximized = tbOpt->titleBarState & Qt::WindowMaximized;
03693 
03694             // button layout:  menu -title- help,shade,min,max,close
03695 
03696             bool menuCloseBtn = tbOpt->titleBarFlags & Qt::WindowSystemMenuHint;
03697             bool minBtn = !isMinimized &&
03698                     (tbOpt->titleBarFlags & Qt::WindowMinimizeButtonHint);
03699             bool maxBtn = !isMaximized &&
03700                     (tbOpt->titleBarFlags & Qt::WindowMaximizeButtonHint);
03701             bool restoreBtn =
03702                     (isMinimized && (tbOpt->titleBarFlags & Qt::WindowMinimizeButtonHint)) ||
03703                     (isMaximized && (tbOpt->titleBarFlags & Qt::WindowMaximizeButtonHint));
03704             bool shadeBtn = tbOpt->titleBarFlags & Qt::WindowShadeButtonHint;
03705             bool helpBtn = tbOpt->titleBarFlags & Qt::WindowContextHelpButtonHint;
03706 
03707 
03708             int btnOffsetCount = 0; // for button rects; count the position in the button bar
03709 
03710             switch (subControl) {
03711                 case SC_TitleBarLabel:
03712                 {
03713                     if (tbOpt->titleBarFlags & Qt::WindowTitleHint)
03714                     {
03715                         int cLeft = 0; // count buttons in the button bar
03716                         int cRight = 0;
03717 
03718                         if (menuCloseBtn) {
03719                             // menu and close button
03720                             ++cLeft;
03721                             ++cRight;
03722                         }
03723                         if (minBtn)     ++cRight;
03724                         if (restoreBtn) ++cRight;
03725                         if (maxBtn)     ++cRight;
03726                         if (shadeBtn)   ++cRight;
03727                         if (helpBtn)    ++cRight;
03728 
03729                         ret.adjust( cLeft*btnWidth+(cLeft-1)*btnSpace+titleSpace, 0,
03730                                     -(titleSpace+cRight*btnWidth+(cRight-1)*btnSpace), 0 );
03731                     }
03732                     break;
03733                 }
03734 
03735                 case SC_TitleBarSysMenu:
03736                 {
03737                     if (tbOpt->titleBarFlags & Qt::WindowSystemMenuHint) {
03738                         ret.setRect(ret.left(), ret.top(), btnWidth, btnHeight);
03739                     }
03740                     break;
03741                 }
03742 
03743                 case SC_TitleBarContextHelpButton:
03744                     if (helpBtn)
03745                         ++btnOffsetCount;
03746                 case SC_TitleBarMinButton:
03747                     if (minBtn)
03748                         ++btnOffsetCount;
03749                     else if (subControl == SC_TitleBarMinButton)
03750                         return QRect();
03751                 case SC_TitleBarNormalButton:
03752                     if (restoreBtn)
03753                         ++btnOffsetCount;
03754                     else if (subControl == SC_TitleBarNormalButton)
03755                         return QRect();
03756                 case SC_TitleBarMaxButton:
03757                     if (maxBtn)
03758                         ++btnOffsetCount;
03759                     else if (subControl == SC_TitleBarMaxButton)
03760                         return QRect();
03761                 case SC_TitleBarShadeButton:
03762                     if (!isMinimized && shadeBtn)
03763                         ++btnOffsetCount;
03764                     else if (subControl == SC_TitleBarShadeButton)
03765                         return QRect();
03766                 case SC_TitleBarUnshadeButton:
03767                     if (isMinimized && shadeBtn)
03768                         ++btnOffsetCount;
03769                     else if (subControl == SC_TitleBarUnshadeButton)
03770                         return QRect();
03771                 case SC_TitleBarCloseButton:
03772                 {
03773                     if (menuCloseBtn)
03774                         ++btnOffsetCount;
03775                     else if (subControl == SC_TitleBarCloseButton)
03776                         return QRect();
03777                     // set the rect for all buttons that fell through:
03778                     ret.setRect(ret.right()-btnOffsetCount*btnWidth-(btnOffsetCount-1)*btnSpace,
03779                                 ret.top(), btnWidth, btnHeight);
03780                     break;
03781                 }
03782 
03783                 default:
03784                     return QRect();
03785             }
03786 
03787             return visualRect(tbOpt->direction, tbOpt->rect, ret);
03788 
03789         } // CC_TitleBar
03790 
03791         default:
03792             break;
03793     }
03794 
03795     return QCommonStyle::subControlRect(control, option, subControl, widget);
03796 }
03797 
03798 /*
03799  Checks whether the point is before the bound rect for
03800  bound of given orientation
03801 */
03802 static bool preceeds(const QPoint &pt, const QRect &bound,
03803                      const QStyleOption* opt)
03804 {
03805     if (opt->state & QStyle::State_Horizontal)
03806     {
03807         //What's earlier depends on RTL or not
03808         if (opt->direction == Qt::LeftToRight)
03809             return pt.x() < bound.right();
03810         else
03811             return pt.x() > bound.x();
03812     }
03813     else
03814     {
03815         return pt.y() < bound.y();
03816     }
03817 }
03818 
03819 static QStyle::SubControl buttonPortion(const QRect &totalRect,
03820                                         const QPoint &pt,
03821                                         const QStyleOption* opt)
03822 {
03823    if (opt->state & QStyle::State_Horizontal)
03824    {
03825         //What's earlier depends on RTL or not
03826         if (opt->direction == Qt::LeftToRight)
03827             return pt.x() < totalRect.center().x() ? QStyle::SC_ScrollBarSubLine : QStyle::SC_ScrollBarAddLine;
03828         else
03829             return pt.x() > totalRect.center().x() ? QStyle::SC_ScrollBarSubLine : QStyle::SC_ScrollBarAddLine;
03830     }
03831     else
03832     {
03833         return pt.y() < totalRect.center().y() ? QStyle::SC_ScrollBarSubLine : QStyle::SC_ScrollBarAddLine;
03834     }
03835 }
03836 
03837 QStyle::SubControl KStyle::hitTestComplexControl(ComplexControl cc, const QStyleOptionComplex* opt,
03838                                              const QPoint& pt, const QWidget* w) const
03839 {
03840     if (cc == CC_ScrollBar)
03841     {
03842         //First, check whether we're inside the groove or not...
03843         QRect groove = subControlRect(CC_ScrollBar, opt, SC_ScrollBarGroove, w);
03844 
03845         if (groove.contains(pt))
03846         {
03847             //Must be either page up/page down, or just click on the slider.
03848             //Grab the slider to compare
03849             QRect slider = subControlRect(CC_ScrollBar, opt, SC_ScrollBarSlider, w);
03850 
03851             if (slider.contains(pt))
03852                 return SC_ScrollBarSlider;
03853             else if (preceeds(pt, slider, opt))
03854                 return SC_ScrollBarSubPage;
03855             else
03856                 return SC_ScrollBarAddPage;
03857         }
03858         else
03859         {
03860             //This is one of the up/down buttons. First, decide which one it is.
03861             if (preceeds(pt, groove, opt))
03862             {
03863                 //"Upper" button
03864                 if (widgetLayoutProp(WT_ScrollBar, ScrollBar::DoubleTopButton, 0, w))
03865                 {
03866                     QRect buttonRect = internalSubControlRect(CC_ScrollBar, opt, SC_ScrollBarSubLine, w);
03867                     return buttonPortion(buttonRect, pt, opt);
03868                 }
03869                 else
03870                     return SC_ScrollBarSubLine; //Easy one!
03871             }
03872             else
03873             {
03874                 //"Bottom" button
03875                 if (widgetLayoutProp(WT_ScrollBar, ScrollBar::DoubleBotButton, 0, w))
03876                 {
03877                     QRect buttonRect = internalSubControlRect(CC_ScrollBar, opt, SC_ScrollBarAddLine, w);
03878                     return buttonPortion(buttonRect, pt, opt);
03879                 }
03880                 else
03881                     return SC_ScrollBarAddLine; //Easy one!
03882             }
03883         }
03884     }
03885 
03886     return QCommonStyle::hitTestComplexControl(cc, opt, pt, w);
03887 }
03888 
03889 
03890 QSize KStyle::sizeFromContents(ContentsType type, const QStyleOption* option, const QSize& contentsSize, const QWidget* widget) const
03891 {
03892     switch (type)
03893     {
03894         case CT_PushButton:
03895         {
03896             const QStyleOptionButton* bOpt = qstyleoption_cast<const QStyleOptionButton*>(option);
03897             if (!bOpt) return contentsSize;
03898 
03899             QSize size = contentsSize;
03900 
03901             if ((bOpt->features & QStyleOptionButton::DefaultButton) || (bOpt->features & QStyleOptionButton::AutoDefaultButton))
03902                 size = expandDim(size, WT_PushButton, PushButton::DefaultIndicatorMargin, option, widget);
03903 
03904             //### TODO: Handle minimum size limits, extra spacing as in current styles ??
03905             size = expandDim(size, WT_PushButton, PushButton::ContentsMargin, option, widget);
03906 
03907             if (!bOpt->text.isEmpty() && !bOpt->icon.isNull()) {
03908                 // Incorporate the spacing between the icon and text. Qt sticks 4 there,
03909                 // but we use PushButton::TextToIconSpace.
03910                 size.setWidth(size.width() - 4 + widgetLayoutProp(WT_PushButton, PushButton::TextToIconSpace, option, widget));
03911             }
03912             return size;
03913         }
03914 
03915         case CT_ToolButton:
03916         {
03917             // We want to avoid super-skiny buttons, for things like "up" when icons + text
03918             // For this, we would like to make width >= height.
03919             // However, once we get here, QToolButton may have already put in the menu area
03920             // (PM_MenuButtonIndicator) into the width. So we may have to take it out, fix things
03921             // up, and add it back in. So much for class-independent rendering...
03922             QSize size = contentsSize;
03923             int   menuAreaWidth = 0;
03924             if (const QStyleOptionToolButton* tbOpt = qstyleoption_cast<const QStyleOptionToolButton*>(option)) {
03925                 if (tbOpt->features & QStyleOptionToolButton::MenuButtonPopup)
03926                     menuAreaWidth = pixelMetric(QStyle::PM_MenuButtonIndicator, option, widget);
03927                 else if (tbOpt->features & QStyleOptionToolButton::HasMenu)
03928                     size.setWidth(size.width() + widgetLayoutProp(WT_ToolButton, ToolButton::InlineMenuIndicatorSize, tbOpt, widget));
03929             }
03930 
03931             size.setWidth(size.width() - menuAreaWidth);
03932             if (size.width() < size.height())
03933                 size.setWidth(size.height());
03934             size.setWidth(size.width() + menuAreaWidth);
03935 
03936             return expandDim(size, WT_ToolButton, ToolButton::ContentsMargin, option, widget);
03937         }
03938 
03939         case CT_CheckBox:
03940         {
03941             //Add size for indicator ### handle empty case differently?
03942             int indicator = widgetLayoutProp(WT_CheckBox, CheckBox::Size, option, widget);
03943             int spacer    = widgetLayoutProp(WT_CheckBox, CheckBox::BoxTextSpace, option, widget);
03944 
03945             //Make sure we include space for the focus rect margin
03946             QSize size = expandDim(contentsSize, WT_CheckBox, CheckBox::FocusMargin, option, widget);
03947 
03948             //Make sure we can fit the indicator (### an extra margin around that?)
03949             size.setHeight(qMax(size.height(), indicator));
03950 
03951             //Add space for the indicator and the icon
03952             size.setWidth(size.width() + indicator + spacer);
03953 
03954             return size;
03955         }
03956 
03957         case CT_RadioButton:
03958         {
03959             //Add size for indicator
03960             int indicator = widgetLayoutProp(WT_RadioButton, RadioButton::Size, option, widget);
03961             int spacer    = widgetLayoutProp(WT_RadioButton, RadioButton::BoxTextSpace, option, widget);
03962 
03963             //Make sure we include space for the focus rect margin
03964             QSize size = expandDim(contentsSize, WT_RadioButton, RadioButton::FocusMargin, option, widget);
03965 
03966             //Make sure we can fit the indicator (### an extra margin around that?)
03967             size.setHeight(qMax(size.height(), indicator));
03968 
03969             //Add space for the indicator and the icon
03970             size.setWidth(size.width() + indicator + spacer);
03971 
03972             return size;
03973         }
03974 
03975         case CT_ProgressBar:
03976         {
03977             QSize size = contentsSize;
03978 
03979             const QStyleOptionProgressBar* pbOpt = ::qstyleoption_cast<const QStyleOptionProgressBar*>(option);
03980             if (useSideText(pbOpt))
03981             {
03982                 //Allocate extra room for side text
03983                 size.setWidth(size.width() + sideTextWidth(pbOpt));
03984             }
03985 
03986             return size;
03987         }
03988 
03989 
03990         case CT_MenuBar:
03991         {
03992             int extraW = widgetLayoutProp(WT_MenuBar, MenuBar::Margin + Right, option, widget) -
03993                             widgetLayoutProp(WT_MenuBar, MenuBar::Margin + Left, option, widget);
03994 
03995             int extraH = widgetLayoutProp(WT_MenuBar, MenuBar::Margin + Bot, option, widget) -
03996                             widgetLayoutProp(WT_MenuBar, MenuBar::Margin + Top, option, widget);
03997 
03998             return QSize(contentsSize.width() + extraW, contentsSize.height() + extraH);
03999         }
04000 
04001         case CT_Menu:
04002         {
04003             int extraW = widgetLayoutProp(WT_Menu, Menu::Margin + Right, option, widget) -
04004                             widgetLayoutProp(WT_Menu, Menu::Margin + Left, option, widget);
04005 
04006             int extraH = widgetLayoutProp(WT_Menu, Menu::Margin + Bot, option, widget) -
04007                             widgetLayoutProp(WT_Menu, Menu::Margin + Top, option, widget);
04008 
04009             return QSize(contentsSize.width() + extraW, contentsSize.height() + extraH);
04010         }
04011 
04012         case CT_MenuItem:
04013         {
04014             const QStyleOptionMenuItem* miOpt = ::qstyleoption_cast<const QStyleOptionMenuItem*>(option);
04015             if (!miOpt) return contentsSize; //Someone is asking for trouble..
04016 
04017             //First, we calculate the intrinsic size of the item..
04018             QSize insideSize;
04019 
04020             switch (miOpt->menuItemType)
04021             {
04022                 case QStyleOptionMenuItem::Normal:
04023                 case QStyleOptionMenuItem::DefaultItem: //huh?
04024                 case QStyleOptionMenuItem::SubMenu:
04025                 {
04026                     int iconColW = miOpt->maxIconWidth;
04027                     iconColW     = qMax(iconColW, widgetLayoutProp(WT_MenuItem, MenuItem::IconWidth, option, widget));
04028 
04029                     int leftColW = iconColW;
04030                     if (miOpt->menuHasCheckableItems &&
04031                         widgetLayoutProp(WT_MenuItem, MenuItem::CheckAlongsideIcon, option, widget) )
04032                     {
04033                         leftColW = widgetLayoutProp(WT_MenuItem, MenuItem::CheckWidth, option, widget) +
04034                                 widgetLayoutProp(WT_MenuItem, MenuItem::CheckSpace, option, widget) +
04035                                 iconColW;
04036                     }
04037 
04038                     leftColW     += widgetLayoutProp(WT_MenuItem, MenuItem::IconSpace, option, widget);
04039 
04040                     int rightColW = widgetLayoutProp(WT_MenuItem, MenuItem::ArrowSpace, option, widget) +
04041                                     widgetLayoutProp(WT_MenuItem, MenuItem::ArrowWidth, option, widget);
04042 
04043                     QFontMetrics fm(miOpt->font);
04044 
04045                     int textW;
04046                     int tabPos = miOpt->text.indexOf(QLatin1Char('\t'));
04047                     if (tabPos == -1)
04048                     {
04049                         //No accel..
04050                         textW = fm.width(miOpt->text);
04051                     }
04052                     else
04053                     {
04054                         // The width of the accelerator is not included here since
04055                         // Qt will add that on separately after obtaining the
04056                         // sizeFromContents() for each menu item in the menu to be shown
04057                         // ( see QMenuPrivate::calcActionRects() )
04058                         QString text = miOpt->text.left(tabPos);
04059                         textW = fm.width(text) +
04060                                 widgetLayoutProp(WT_MenuItem,MenuItem::AccelSpace,option,widget);
04061                     }
04062 
04063                     #ifdef __GNUC__
04064                     #warning Extra M-width needed to avoid menu items being stuck together with their shortcuts, \
04065                              possibly due to wrongly reported text metrics
04066                     #endif
04067                     textW += fm.width('M');
04068 
04069                     int h = qMax(contentsSize.height(), widgetLayoutProp(WT_MenuItem, MenuItem::MinHeight, option, widget));
04070                     insideSize = QSize(leftColW + textW + rightColW, h);
04071                     break;
04072                 }
04073 
04074                 case QStyleOptionMenuItem::Separator:
04075                 {
04076                     insideSize = QSize(10, widgetLayoutProp(WT_MenuItem, MenuItem::SeparatorHeight, option, widget));
04077                 }
04078                 break;
04079 
04080 
04081                 //Double huh if we get those.
04082                 case QStyleOptionMenuItem::Scroller:
04083                 case QStyleOptionMenuItem::TearOff:
04084                 case QStyleOptionMenuItem::Margin:
04085                 case QStyleOptionMenuItem::EmptyArea:
04086                     return contentsSize;
04087             }
04088 
04089             //...now apply the outermost margin.
04090             return expandDim(insideSize, WT_MenuItem, MenuItem::Margin, option, widget);
04091         }
04092 
04093         case CT_MenuBarItem:
04094             return expandDim(contentsSize, WT_MenuBarItem, MenuBarItem::Margin, option, widget);
04095 
04096         case CT_TabBarTab:
04097         {
04098             //With our PM_TabBarTabHSpace/VSpace, Qt should give us what we want for
04099             //contentsSize, so we just expand that. Qt also takes care of
04100             //the vertical thing.
04101 
04102             bool rotated = false; // indicates whether the tab is rotated by 90 degrees
04103             if (const QStyleOptionTab *tabOpt = qstyleoption_cast<const QStyleOptionTab*>(option)) {
04104                 rotated = isVerticalTab(tabOpt);
04105             }
04106 
04107             return expandDim(contentsSize, WT_TabBar, TabBar::TabContentsMargin, option, widget, rotated);
04108         }
04109 
04110         case CT_TabWidget:
04111         {
04112             const QStyleOptionTabWidgetFrame* tabOpt = qstyleoption_cast<const QStyleOptionTabWidgetFrame*>(option);
04113             if (!tabOpt) break;
04114 
04115             int m = widgetLayoutProp(WT_TabWidget, TabWidget::ContentsMargin, option, widget);
04116             int vert = 2*m +
04117                     widgetLayoutProp(WT_TabWidget, TabWidget::ContentsMargin+Top, option, widget) +
04118                     widgetLayoutProp(WT_TabWidget, TabWidget::ContentsMargin+Bot, option, widget);
04119             int hor = 2*m +
04120                     widgetLayoutProp(WT_TabWidget, TabWidget::ContentsMargin+Left, option, widget) +
04121                     widgetLayoutProp(WT_TabWidget, TabWidget::ContentsMargin+Right, option, widget);
04122 
04123             switch (tabOpt->shape) {
04124                 case QTabBar::RoundedNorth:
04125                 case QTabBar::TriangularNorth:
04126                 case QTabBar::RoundedWest:
04127                 case QTabBar::TriangularWest:
04128                     return contentsSize + QSize(hor, vert);
04129                 case QTabBar::RoundedSouth:
04130                 case QTabBar::TriangularSouth:
04131                 case QTabBar::RoundedEast:
04132                 case QTabBar::TriangularEast:
04133                     return contentsSize + QSize(vert,hor);
04134             }
04135         }
04136 
04137         case CT_HeaderSection:
04138         {
04139             if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
04140                 QSize iconSize = header->icon.isNull() ? QSize(0,0) : QSize(22,22);
04141                 QSize textSize = header->fontMetrics.size(0, header->text);
04142                 int iconSpacing = widgetLayoutProp(WT_Header, Header::TextToIconSpace, option, widget);
04143                 int w = iconSize.width() + iconSpacing + textSize.width();
04144                 int h = qMax(iconSize.height(), textSize.height() );
04145 
04146                 return expandDim(QSize(w, h), WT_Header, Header::ContentsMargin, option, widget);
04147             }
04148         }
04149 
04150         case CT_ComboBox:
04151         {
04152             // TODO: Figure out what to do with the button margins
04153             QSize size = contentsSize;
04154 
04155             // Add the contents margin
04156             size = expandDim(size, WT_ComboBox, ComboBox::ContentsMargin, option, widget);
04157 
04158             // Add the button width
04159             size.rwidth() += widgetLayoutProp(WT_ComboBox, ComboBox::ButtonWidth, option, widget);
04160 
04161             // Add the frame width
04162             size.rwidth()  += widgetLayoutProp(WT_ComboBox, ComboBox::FrameWidth, option, widget) * 2;
04163             size.rheight() += widgetLayoutProp(WT_ComboBox, ComboBox::FrameWidth, option, widget) * 2;
04164 
04165             return size;
04166         }
04167 
04168         default:
04169             break;
04170     }
04171 
04172     return QCommonStyle::sizeFromContents(type, option, contentsSize, widget);
04173 }
04174 
04175 bool KStyle::eventFilter(QObject *obj, QEvent *ev)
04176 {
04177     if (QCommonStyle::eventFilter(obj, ev) )
04178         return true;
04179 
04180     if (QLabel *lbl = qobject_cast<QLabel*>(obj) ) {
04181         QWidget *buddy = lbl->buddy();
04182         if (buddy) {
04183             switch (ev->type() ) {
04184                 case QEvent::MouseButtonPress:
04185                 {
04186                     QMouseEvent *mev = dynamic_cast<QMouseEvent*>(ev);
04187                     if (!mev) break;
04188 
04189                     if (lbl->rect().contains(mev->pos() ) ) {
04190                         clickedLabel = obj;
04191                         lbl->repaint();
04192                     }
04193                     break;
04194                 }
04195                 case QEvent::MouseButtonRelease:
04196                 {
04197                     QMouseEvent *mev = dynamic_cast<QMouseEvent*>(ev);
04198                     if (!mev) break;
04199 
04200                     if (clickedLabel) {
04201                         clickedLabel = 0;
04202                         lbl->update();
04203                     }
04204 
04205                 // set focus to the buddy...
04206                     if (lbl->rect().contains(mev->pos() ) ) {
04207                         buddy->setFocus(Qt::ShortcutFocusReason);
04208                     }
04209                     break;
04210                 }
04211                 case QEvent::Paint:
04212                     if (obj == clickedLabel && buddy->isEnabled()) {
04213                     // paint focus rect
04214                         QPainter p(lbl);
04215                         QStyleOptionFocusRect foOpts;
04216                         QRect foRect(0,0,lbl->width(),lbl->height());
04217                         foOpts.palette = lbl->palette();
04218                         foOpts.rect    = foRect;
04219                         drawKStylePrimitive(WT_Generic, Generic::FocusIndicator, &foOpts,
04220                                             foRect, lbl->palette(), 0, &p, lbl);
04221                     }
04222                     break;
04223 
04224                 default:
04225                     break;
04226             }
04227         }
04228     }
04229 
04230     return false;
04231 }
04232 
04233 KStyle::ColorMode::ColorMode(QPalette::ColorRole _role):
04234     mode(PaletteEntryMode),
04235     role(_role)
04236 {}
04237 
04238 KStyle::ColorMode::ColorMode(Mode _mode, QPalette::ColorRole _role):
04239     mode(_mode),
04240     role(_role)
04241 {}
04242 
04243 KStyle::ColorMode::operator int() const
04244 {
04245     return int(role) | int(mode);
04246 }
04247 
04248 KStyle::ColorMode::ColorMode(int encoded)
04249 {
04250     mode = (encoded & BWAutoContrastMode) ? BWAutoContrastMode : PaletteEntryMode;
04251     role = QPalette::ColorRole(encoded & (~BWAutoContrastMode));
04252 }
04253 
04254 QColor KStyle::ColorMode::color(const QPalette& palette)
04255 {
04256     QColor palColor = palette.color(role);
04257 
04258     if (mode == BWAutoContrastMode) {
04259         if (qGray(palColor.rgb()) > 128) { //### CHECKME
04260             palColor = Qt::black;
04261         } else {
04262             palColor = Qt::white;
04263         }
04264     }
04265     return palColor;
04266 }
04267 
04268 KStyle::TextOption::TextOption()
04269 {
04270     init();
04271 }
04272 
04273 KStyle::TextOption::TextOption(const QString& _text):
04274     text(_text)
04275 {
04276     init();
04277 }
04278 
04279 void KStyle::TextOption::init()
04280 {
04281     hAlign = Qt::AlignLeft; //NOTE: Check BIDI?
04282 }
04283 
04284 // kate: indent-width 4; replace-tabs on; tab-width 4; space-indent on;

KDEUI

Skip menu "KDEUI"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs 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