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