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