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