src/gui/styles/qplastiquestyle.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 **
00003 ** Copyright (C) 1992-2006 Trolltech ASA. All rights reserved.
00004 **
00005 ** This file is part of the QtGui module of the Qt Toolkit.
00006 **
00007 ** This file may be used under the terms of the GNU General Public
00008 ** License version 2.0 as published by the Free Software Foundation
00009 ** and appearing in the file LICENSE.GPL included in the packaging of
00010 ** this file.  Please review the following information to ensure GNU
00011 ** General Public Licensing requirements will be met:
00012 ** http://www.trolltech.com/products/qt/opensource.html
00013 **
00014 ** If you are unsure which license is appropriate for your use, please
00015 ** review the following information:
00016 ** http://www.trolltech.com/products/qt/licensing.html or contact the
00017 ** sales department at sales@trolltech.com.
00018 **
00019 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00020 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00021 **
00022 ****************************************************************************/
00023 
00024 #include "qplastiquestyle.h"
00025 
00026 #if !defined(QT_NO_STYLE_PLASTIQUE) || defined(QT_PLUGIN)
00027 
00028 static bool UsePixmapCache = true;
00029 static const bool AnimateBusyProgressBar = true;
00030 static const bool AnimateProgressBar = false;
00031 // #define QPlastique_MaskButtons
00032 static const int ProgressBarFps = 25;
00033 
00034 #include "qwindowsstyle_p.h"
00035 #include <qapplication.h>
00036 #include <qbitmap.h>
00037 #include <qabstractitemview.h>
00038 #include <qcheckbox.h>
00039 #include <qcombobox.h>
00040 #include <qdatetime.h>
00041 #include <qdebug.h>
00042 #include <qdialogbuttonbox.h>
00043 #include <qgroupbox.h>
00044 #include <qimage.h>
00045 #include <qlineedit.h>
00046 #include <qmainwindow.h>
00047 #include <qmenu.h>
00048 #include <qmenubar.h>
00049 #include <qpainter.h>
00050 #include <qpaintengine.h>
00051 #include <qpainterpath.h>
00052 #include <qpalette.h>
00053 #include <qpen.h>
00054 #include <qpixmap.h>
00055 #include <qpixmapcache.h>
00056 #include <qprogressbar.h>
00057 #include <qpushbutton.h>
00058 #include <qradiobutton.h>
00059 #include <qscrollbar.h>
00060 #include <qspinbox.h>
00061 #include <qsplitter.h>
00062 #include <qstyleoption.h>
00063 #include <qtextedit.h>
00064 #include <qtoolbar.h>
00065 #include <qtoolbox.h>
00066 #include <qtoolbutton.h>
00067 #include <qworkspace.h>
00068 #include <qprocess.h>
00069 #include <qfileinfo.h>
00070 #include <qsettings.h>
00071 #include <qdir.h>
00072 #include <limits.h>
00073 
00074 // from windows style
00075 static const int windowsItemFrame        =  2; // menu item frame width
00076 static const int windowsSepHeight        =  2; // separator item height
00077 static const int windowsItemHMargin      =  3; // menu item hor text margin
00078 static const int windowsItemVMargin      =  2; // menu item ver text margin
00079 static const int windowsArrowHMargin     =  6; // arrow horizontal margin
00080 static const int windowsTabSpacing       = 12; // space between text and tab
00081 static const int windowsCheckMarkHMargin =  2; // horiz. margins of check mark
00082 static const int windowsRightBorder      = 15; // right border on windows
00083 static const int windowsCheckMarkWidth   = 12; // checkmarks width on windows
00084 
00085 static const char * const qt_plastique_slider_verticalhandle[] = {
00086     "15 11 4 1",
00087     "   c None",
00088     "+  c #979797",
00089     "@  c #C9C9C9",
00090     "$  c #C1C1C1",
00091     " $++++++++$    ",
00092     "$+        +$   ",
00093     "+  $$      +$  ",
00094     "+  $@       +$ ",
00095     "+            +$",
00096     "+             +",
00097     "+            +$",
00098     "+  $$       +$ ",
00099     "+  $@      +$  ",
00100     "$+        +$   ",
00101     " $++++++++$    "};
00102 
00103 static const char * const qt_plastique_slider_verticalhandle_left[] = {
00104     "15 11 4 1",
00105     "   c None",
00106     "+  c #979797",
00107     "@  c #C9C9C9",
00108     "$  c #C1C1C1",
00109     "    $++++++++$ ",
00110     "   $+        +$",
00111     "  $+      $$  +",
00112     " $+       $@  +",
00113     "$+            +",
00114     "+             +",
00115     "$+            +",
00116     " $+       $$  +",
00117     "  $+      $@  +",
00118     "   $+        +$",
00119     "    $++++++++$ "};
00120 
00121 static const char * const qt_plastique_slider_horizontalhandle[] = {
00122     "11 15 4 1",
00123     "   c None",
00124     "+  c #979797",
00125     "@  c #C9C9C9",
00126     "$  c #C1C1C1",
00127     " $+++++++$ ",
00128     "$+       +$",
00129     "+         +",
00130     "+ $$   $$ +",
00131     "+ $@   $@ +",
00132     "+         +",
00133     "+         +",
00134     "+         +",
00135     "+         +",
00136     "+         +",
00137     "$+       +$",
00138     " $+     +$ ",
00139     "  $+   +$  ",
00140     "   $+ +$   ",
00141     "    $+$    "};
00142 
00143 static const char * const qt_plastique_slider_horizontalhandle_up[] = {
00144     "11 15 4 1",
00145     "   c None",
00146     "+  c #979797",
00147     "@  c #C9C9C9",
00148     "$  c #C1C1C1",
00149     "    $+$    ",
00150     "   $+ +$   ",
00151     "  $+   +$  ",
00152     " $+     +$ ",
00153     "$+       +$",
00154     "+         +",
00155     "+         +",
00156     "+         +",
00157     "+         +",
00158     "+         +",
00159     "+ $$   $$ +",
00160     "+ $@   $@ +",
00161     "+         +",
00162     "$+       +$",
00163     " $+++++++$ "};
00164 
00165 static const char * const qt_scrollbar_button_arrow_left[] = {
00166     "4 7 2 1",
00167     "   c None",
00168     "*  c #BFBFBF",
00169     "   *",
00170     "  **",
00171     " ***",
00172     "****",
00173     " ***",
00174     "  **",
00175     "   *"};
00176 
00177 static const char * const qt_scrollbar_button_arrow_right[] = {
00178     "4 7 2 1",
00179     "   c None",
00180     "*  c #BFBFBF",
00181     "*   ",
00182     "**  ",
00183     "*** ",
00184     "****",
00185     "*** ",
00186     "**  ",
00187     "*   "};
00188 
00189 static const char * const qt_scrollbar_button_arrow_up[] = {
00190     "7 4 2 1",
00191     "   c None",
00192     "*  c #BFBFBF",
00193     "   *   ",
00194     "  ***  ",
00195     " ***** ",
00196     "*******"};
00197 
00198 static const char * const qt_scrollbar_button_arrow_down[] = {
00199     "7 4 2 1",
00200     "   c None",
00201     "*  c #BFBFBF",
00202     "*******",
00203     " ***** ",
00204     "  ***  ",
00205     "   *   "};
00206 
00207 static const char * const qt_scrollbar_button_left[] = {
00208     "16 16 6 1",
00209     "   c None",
00210     ".  c #BFBFBF",
00211     "+  c #979797",
00212     "#  c #FAFAFA",
00213     "<  c #FAFAFA",
00214     "*  c #FAFAFA",
00215     " .+++++++++++++.",
00216     ".+#############+",
00217     "+#            <+",
00218     "+#            <+",
00219     "+#            <+",
00220     "+#            <+",
00221     "+#            <+",
00222     "+#            <+",
00223     "+#            <+",
00224     "+#            <+",
00225     "+#            <+",
00226     "+#            <+",
00227     "+#            <+",
00228     "+#            <+",
00229     ".+<<<<<<<<<<<<<+",
00230     " .+++++++++++++."};
00231 
00232 static const char * const qt_scrollbar_button_right[] = {
00233     "16 16 6 1",
00234     "   c None",
00235     ".  c #BFBFBF",
00236     "+  c #979797",
00237     "#  c #FAFAFA",
00238     "<  c #FAFAFA",
00239     "*  c #FAFAFA",
00240     ".+++++++++++++. ",
00241     "+#############+.",
00242     "+#            <+",
00243     "+#            <+",
00244     "+#            <+",
00245     "+#            <+",
00246     "+#            <+",
00247     "+#            <+",
00248     "+#            <+",
00249     "+#            <+",
00250     "+#            <+",
00251     "+#            <+",
00252     "+#            <+",
00253     "+#            <+",
00254     "+<<<<<<<<<<<<<+.",
00255     ".+++++++++++++. "};
00256 
00257 static const char * const qt_scrollbar_button_up[] = {
00258     "16 16 6 1",
00259     "   c None",
00260     ".  c #BFBFBF",
00261     "+  c #979797",
00262     "#  c #FAFAFA",
00263     "<  c #FAFAFA",
00264     "*  c #FAFAFA",
00265     " .++++++++++++. ",
00266     ".+############+.",
00267     "+#            <+",
00268     "+#            <+",
00269     "+#            <+",
00270     "+#            <+",
00271     "+#            <+",
00272     "+#            <+",
00273     "+#            <+",
00274     "+#            <+",
00275     "+#            <+",
00276     "+#            <+",
00277     "+#            <+",
00278     "+#            <+",
00279     "+<<<<<<<<<<<<<<+",
00280     ".++++++++++++++."};
00281 
00282 static const char * const qt_scrollbar_button_down[] = {
00283     "16 16 6 1",
00284     "   c None",
00285     ".  c #BFBFBF",
00286     "+  c #979797",
00287     "#  c #FAFAFA",
00288     "<  c #FAFAFA",
00289     "*  c #FAFAFA",
00290     "++++++++++++++++",
00291     "+##############+",
00292     "+#            <+",
00293     "+#            <+",
00294     "+#            <+",
00295     "+#            <+",
00296     "+#            <+",
00297     "+#            <+",
00298     "+#            <+",
00299     "+#            <+",
00300     "+#            <+",
00301     "+#            <+",
00302     "+#            <+",
00303     "+#            <+",
00304     ".+<<<<<<<<<<<<+.",
00305     " .++++++++++++. "};
00306 
00307 static const char * const qt_scrollbar_slider_pattern_vertical[] = {
00308     "10 18 3 1",
00309     "   c None",
00310     ".  c #BFBFBF",
00311     "+  c #979797",
00312     "..  ..  ..",
00313     ".+  .+  .+",
00314     "          ",
00315     "          ",
00316     "..  ..  ..",
00317     ".+  .+  .+",
00318     "          ",
00319     "          ",
00320     "..  ..  ..",
00321     ".+  .+  .+",
00322     "          ",
00323     "          ",
00324     "..  ..  ..",
00325     ".+  .+  .+",
00326     "          ",
00327     "          ",
00328     "..  ..  ..",
00329     ".+  .+  .+"};
00330 
00331 static const char * const qt_scrollbar_slider_pattern_horizontal[] = {
00332     "18 10 3 1",
00333     "   c None",
00334     ".  c #BFBFBF",
00335     "+  c #979797",
00336     "..  ..  ..  ..  ..",
00337     ".+  .+  .+  .+  .+",
00338     "                  ",
00339     "                  ",
00340     "..  ..  ..  ..  ..",
00341     ".+  .+  .+  .+  .+",
00342     "                  ",
00343     "                  ",
00344     "..  ..  ..  ..  ..",
00345     ".+  .+  .+  .+  .+"};
00346 
00347 static const char * const qt_toolbarhandle[] = {
00348     "6 6 4 1",
00349     "       c None",
00350     ".      c #C5C5C5",
00351     "+      c #EEEEEE",
00352     "@      c #FAFAFA",
00353     "..    ",
00354     ".+@   ",
00355     " @@   ",
00356     "   .. ",
00357     "   .+@",
00358     "    @@"};
00359 
00360 static const char * const qt_simple_toolbarhandle[] = {
00361     "3 3 4 1",
00362     "       c None",
00363     ".      c #C5C5C5",
00364     "+      c #EEEEEE",
00365     "@      c #FAFAFA",
00366     ".. ",
00367     ".+@",
00368     " @@"};
00369 
00370 static const char * const qt_titlebar_context_help[] = {
00371 "27 27 5 1",
00372 "  c None",
00373 ". c #0A0C12",
00374 "+ c #1B202D",
00375 "@ c #293144",
00376 "# c #3C435D",
00377 "                           ",
00378 "                           ",
00379 "                           ",
00380 "                           ",
00381 "                           ",
00382 "                           ",
00383 "                           ",
00384 "                           ",
00385 "           +@##@+          ",
00386 "         .@@@.+@@..        ",
00387 "         .##+  +@@+.       ",
00388 "         .##@  @#@+.       ",
00389 "         ....  +@+..       ",
00390 "            .@+@@..        ",
00391 "            +#@@+          ",
00392 "            .##.           ",
00393 "            .++.           ",
00394 "            .++.           ",
00395 "            +##+           ",
00396 "            .@@.           ",
00397 "                           ",
00398 "                           ",
00399 "                           ",
00400 "                           ",
00401 "                           ",
00402 "                           ",
00403 "                           "};
00404 
00405 #define BEGIN_PLASTIQUE_PIXMAPCACHE(a) \
00406     QRect rect = button->rect; \
00407     QPixmap cache; \
00408     QPainter *p = painter; \
00409     QString unique = uniqueName((a), option, option->rect.size()); \
00410     if (UsePixmapCache) { \
00411         if (!QPixmapCache::find(unique, cache)) { \
00412             rect.setRect(0, 0, option->rect.width(), option->rect.height()); \
00413             cache = QPixmap(option->rect.size()); \
00414             cache.fill(Qt::transparent); \
00415             p = new QPainter(&cache); \
00416         } else { \
00417             painter->drawPixmap(button->rect.topLeft(), cache); \
00418             break; \
00419         } \
00420     }
00421 
00422 #define END_PLASTIQUE_PIXMAPCACHE \
00423     if (p != painter) { \
00424         p->end(); \
00425         delete p; \
00426         painter->drawPixmap(option->rect.topLeft(), cache); \
00427         QPixmapCache::insert(unique, cache); \
00428     }
00429 
00430 static QLinearGradient qMapGradientToRect(const QLinearGradient &gradient, const QRectF &rect)
00431 {
00432     QLinearGradient tmpGrad(rect.center().x(), rect.top(),
00433                             rect.center().x(), rect.bottom());
00434     tmpGrad.setStops(gradient.stops());
00435     return tmpGrad;
00436 }
00437 
00438 static QBrush qMapBrushToRect(const QBrush &brush, const QRectF &rect)
00439 {
00440     if (!brush.gradient())
00441         return brush;
00442 
00443     // ### Ugly assumption that it's a linear gradient
00444     QBrush tmp(qMapGradientToRect(*static_cast<const QLinearGradient *>(brush.gradient()), rect));
00445     return tmp;
00446 }
00447 
00448 static void qBrushSetAlphaF(QBrush *brush, qreal alpha)
00449 {
00450     if (const QGradient *gradient = brush->gradient()) {
00451         // Use the gradient. Call QColor::setAlphaF() on all color stops.
00452         QGradientStops stops = gradient->stops();
00453         QMutableVectorIterator<QGradientStop> it(stops);
00454         QColor tmpColor;
00455         while (it.hasNext()) {
00456             it.next();
00457             tmpColor = it.value().second;
00458             tmpColor.setAlphaF(alpha * tmpColor.alphaF());
00459             it.setValue(QPair<qreal, QColor>(it.value().first, tmpColor));
00460         }
00461 
00462         switch (gradient->type()) {
00463         case QGradient::RadialGradient: {
00464             QRadialGradient grad = *static_cast<const QRadialGradient *>(gradient);
00465             grad.setStops(stops);
00466             *brush = QBrush(grad);
00467             break;
00468         }
00469         case QGradient::ConicalGradient: {
00470             QConicalGradient grad = *static_cast<const QConicalGradient *>(gradient);
00471             grad.setStops(stops);
00472             *brush = QBrush(grad);
00473             break;
00474         }
00475         default:
00476             qWarning("QPlastiqueStyle::qBrushLight() - unknown gradient type"
00477                      " - falling back to QLinearGradient");
00478         case QGradient::LinearGradient: {
00479             QLinearGradient grad = *static_cast<const QLinearGradient *>(gradient);
00480             grad.setStops(stops);
00481             *brush = QBrush(grad);
00482             break;
00483         }
00484         }
00485     } else if (!brush->texture().isNull()) {
00486         // Modify the texture - ridiculously expensive.
00487         QPixmap texture = brush->texture();
00488         QPixmap pixmap;
00489         QString name = QString("qbrushtexture-alpha-%1-%2").arg(alpha).arg(texture.serialNumber());
00490         if (UsePixmapCache && !QPixmapCache::find(name, pixmap)) {
00491             QImage image = texture.toImage();
00492             QRgb *rgb = reinterpret_cast<QRgb *>(image.bits());
00493             int pixels = image.width() * image.height();
00494             QColor tmpColor;
00495             while (pixels--) {
00496                 tmpColor.setRgb(*rgb);
00497                 tmpColor.setAlphaF(alpha * tmpColor.alphaF());
00498                 *rgb++ = tmpColor.rgba();
00499             }
00500             pixmap = QPixmap::fromImage(image);
00501             QPixmapCache::insert(name, pixmap);
00502         }
00503         brush->setTexture(pixmap);
00504     } else {
00505         // Use the color
00506         QColor tmpColor = brush->color();
00507         tmpColor.setAlphaF(alpha * tmpColor.alphaF());
00508         brush->setColor(tmpColor);
00509     }
00510 }
00511 
00512 static QBrush qBrushLight(QBrush brush, int light)
00513 {
00514     if (const QGradient *gradient = brush.gradient()) {
00515         // Use the gradient. Call QColor::light() on all color stops.
00516         QGradientStops stops = gradient->stops();
00517         QMutableVectorIterator<QGradientStop> it(stops);
00518         while (it.hasNext()) {
00519             it.next();
00520             it.setValue(QPair<qreal, QColor>(it.value().first, it.value().second.light(light)));
00521         }
00522 
00523         switch (gradient->type()) {
00524         case QGradient::RadialGradient: {
00525             QRadialGradient grad = *static_cast<const QRadialGradient *>(gradient);
00526             grad.setStops(stops);
00527             brush = QBrush(grad);
00528             break;
00529         }
00530         case QGradient::ConicalGradient: {
00531             QConicalGradient grad = *static_cast<const QConicalGradient *>(gradient);
00532             grad.setStops(stops);
00533             brush = QBrush(grad);
00534             break;
00535         }
00536         default:
00537             qWarning("QPlastiqueStyle::qBrushLight() - unknown gradient type"
00538                      " - falling back to QLinearGradient");
00539         case QGradient::LinearGradient: {
00540             QLinearGradient grad = *static_cast<const QLinearGradient *>(gradient);
00541             grad.setStops(stops);
00542             brush = QBrush(grad);
00543             break;
00544         }
00545         }
00546     } else if (!brush.texture().isNull()) {
00547         // Modify the texture - ridiculously expensive.
00548         QPixmap texture = brush.texture();
00549         QPixmap pixmap;
00550         QString name = QString("qbrushtexture-light-%1-%2").arg(light).arg(texture.serialNumber());
00551         if (UsePixmapCache && !QPixmapCache::find(name, pixmap)) {
00552             QImage image = texture.toImage();
00553             QRgb *rgb = reinterpret_cast<QRgb *>(image.bits());
00554             int pixels = image.width() * image.height();
00555             QColor tmpColor;
00556             while (pixels--) {
00557                 tmpColor.setRgb(*rgb);
00558                 *rgb++ = tmpColor.light(light).rgba();
00559             }
00560             pixmap = QPixmap::fromImage(image);
00561             QPixmapCache::insert(name, pixmap);
00562         }
00563         brush.setTexture(pixmap);
00564     } else {
00565         // Use the color
00566         brush.setColor(brush.color().light(light));
00567     }
00568     return brush;
00569 }
00570 
00571 static QBrush qBrushDark(QBrush brush, int dark)
00572 {
00573     if (const QGradient *gradient = brush.gradient()) {
00574         // Use the gradient. Call QColor::dark() on all color stops.
00575         QGradientStops stops = gradient->stops();
00576         QMutableVectorIterator<QGradientStop> it(stops);
00577         while (it.hasNext()) {
00578             it.next();
00579             it.setValue(QPair<qreal, QColor>(it.value().first, it.value().second.dark(dark)));
00580         }
00581 
00582         switch (gradient->type()) {
00583         case QGradient::RadialGradient: {
00584             QRadialGradient grad = *static_cast<const QRadialGradient *>(gradient);
00585             grad.setStops(stops);
00586             brush = QBrush(grad);
00587             break;
00588         }
00589         case QGradient::ConicalGradient: {
00590             QConicalGradient grad = *static_cast<const QConicalGradient *>(gradient);
00591             grad.setStops(stops);
00592             brush = QBrush(grad);
00593             break;
00594         }
00595         default:
00596             qWarning("QPlastiqueStyle::qBrushDark() - unknown gradient type"
00597                      " - falling back to QLinearGradient");
00598         case QGradient::LinearGradient: {
00599             QLinearGradient grad = *static_cast<const QLinearGradient *>(gradient);
00600             grad.setStops(stops);
00601             brush = QBrush(grad);
00602             break;
00603         }
00604         }
00605     } else if (!brush.texture().isNull()) {
00606         // Modify the texture - ridiculously expensive.
00607         QPixmap texture = brush.texture();
00608         QPixmap pixmap;
00609         QString name = QString("qbrushtexture-dark-%1-%2").arg(dark).arg(brush.texture().serialNumber());
00610         if (UsePixmapCache && !QPixmapCache::find(name, pixmap)) {
00611             QImage image = texture.toImage();
00612             QRgb *rgb = reinterpret_cast<QRgb *>(image.bits());
00613             int pixels = image.width() * image.height();
00614             QColor tmpColor;
00615             while (pixels--) {
00616                 tmpColor.setRgb(*rgb);
00617                 *rgb++ = tmpColor.dark(dark).rgba();
00618             }
00619             pixmap = QPixmap::fromImage(image);
00620             QPixmapCache::insert(name, pixmap);
00621         }
00622         brush.setTexture(pixmap);
00623     } else {
00624         // Use the color
00625         brush.setColor(brush.color().dark(dark));
00626     }
00627     return brush;
00628 }
00629 
00630 /*
00631     Draws a rounded frame using the provided brush for 1, and adds 0.5 alpha
00632     for 0.
00633 
00634      0111111110
00635     01        10
00636     1          1
00637     1          1
00638     1          1
00639     01        10
00640      0111111110
00641 */
00642 static void qt_plastique_draw_frame(QPainter *painter, const QRect &rect, const QStyleOption *option,
00643                                     QFrame::Shadow shadow = QFrame::Plain)
00644 {
00645     QPen oldPen = painter->pen();
00646     QBrush border;
00647     QBrush corner;
00648     QBrush innerTopLeft;
00649     QBrush innerBottomRight;
00650 
00651     if (shadow != QFrame::Plain && (option->state & QStyle::State_HasFocus)) {
00652         border = option->palette.highlight();
00653         qBrushSetAlphaF(&border, 0.8);
00654         corner = option->palette.highlight();
00655         qBrushSetAlphaF(&corner, 0.5);
00656         innerTopLeft = qBrushDark(option->palette.highlight(), 125);
00657         innerBottomRight = option->palette.highlight();
00658         qBrushSetAlphaF(&innerBottomRight, 0.65);
00659     } else {
00660         border = option->palette.shadow();
00661         qBrushSetAlphaF(&border, 0.4);
00662         corner = option->palette.shadow();
00663         qBrushSetAlphaF(&corner, 0.25);
00664         innerTopLeft = option->palette.shadow();
00665         innerBottomRight = option->palette.shadow();
00666         if (shadow == QFrame::Sunken) {
00667             qBrushSetAlphaF(&innerTopLeft, 0.23);
00668             qBrushSetAlphaF(&innerBottomRight, 0.075);
00669         } else {
00670             qBrushSetAlphaF(&innerTopLeft, 0.075);
00671             qBrushSetAlphaF(&innerBottomRight, 0.23);
00672         }
00673     }
00674 
00675     // Opaque corner lines
00676     painter->setPen(QPen(border, 0));
00677     painter->drawLine(rect.left() + 2, rect.top(), rect.right() - 2, rect.top());
00678     painter->drawLine(rect.left() + 2, rect.bottom(), rect.right() - 2, rect.bottom());
00679     painter->drawLine(rect.left(), rect.top() + 2, rect.left(), rect.bottom() - 2);
00680     painter->drawLine(rect.right(), rect.top() + 2, rect.right(), rect.bottom() - 2);
00681 
00682     // Opaque corner dots
00683     painter->drawPoint(rect.left() + 1, rect.top() + 1);
00684     painter->drawPoint(rect.left() + 1, rect.bottom() - 1);
00685     painter->drawPoint(rect.right() - 1, rect.top() + 1);
00686     painter->drawPoint(rect.right() - 1, rect.bottom() - 1);
00687 
00688     // Shaded corner dots
00689     painter->setPen(QPen(corner, 0));
00690     painter->drawPoint(rect.left(), rect.top() + 1);
00691     painter->drawPoint(rect.left(), rect.bottom() - 1);
00692     painter->drawPoint(rect.left() + 1, rect.top());
00693     painter->drawPoint(rect.left() + 1, rect.bottom());
00694     painter->drawPoint(rect.right(), rect.top() + 1);
00695     painter->drawPoint(rect.right(), rect.bottom() - 1);
00696     painter->drawPoint(rect.right() - 1, rect.top());
00697     painter->drawPoint(rect.right() - 1, rect.bottom());
00698 
00699     // Shadows
00700     if (shadow != QFrame::Plain) {
00701         painter->setPen(QPen(innerTopLeft, 0));
00702         painter->drawLine(rect.left() + 2, rect.top() + 1, rect.right() - 2, rect.top() + 1);
00703         painter->drawLine(rect.left() + 1, rect.top() + 2, rect.left() + 1, rect.bottom() - 2);
00704         painter->setPen(QPen(innerBottomRight, 0));
00705         painter->drawLine(rect.left() + 2, rect.bottom() - 1, rect.right() - 2, rect.bottom() - 1);
00706         painter->drawLine(rect.right() - 1, rect.top() + 2, rect.right() - 1, rect.bottom() - 2);
00707     }
00708 
00709     painter->setPen(oldPen);
00710 }
00711 
00712 static QColor mergedColors(const QColor &colorA, const QColor &colorB, int factor = 50)
00713 {
00714     const int maxFactor = 100;
00715     QColor tmp = colorA;
00716     tmp.setRed((tmp.red() * factor) / maxFactor + (colorB.red() * (maxFactor - factor)) / maxFactor);
00717     tmp.setGreen((tmp.green() * factor) / maxFactor + (colorB.green() * (maxFactor - factor)) / maxFactor);
00718     tmp.setBlue((tmp.blue() * factor) / maxFactor + (colorB.blue() * (maxFactor - factor)) / maxFactor);
00719     return tmp;
00720 }
00721 
00722 static QString uniqueName(const QString &key, const QStyleOption *option, const QSize &size)
00723 {
00724     QString tmp;
00725     const QStyleOptionComplex *complexOption = qstyleoption_cast<const QStyleOptionComplex *>(option);
00726     tmp.sprintf("%s-%d-%d-%d-%dx%d", key.toLatin1().constData(), uint(option->state),
00727                 complexOption ? uint(complexOption->activeSubControls) : uint(0),
00728                 option->palette.serialNumber(), size.width(), size.height());
00729     return tmp;
00730 }
00731 
00732 static void qt_plastique_draw_gradient(QPainter *painter, const QRect &rect, const QColor &gradientStart,
00733                                        const QColor &gradientStop)
00734 {
00735     QString gradientName;
00736     gradientName.sprintf("%dx%d-%x-%x", rect.width(), rect.height(), gradientStart.rgba(), gradientStop.rgba());
00737     QPixmap cache;
00738     if (!UsePixmapCache || !QPixmapCache::find(gradientName, cache)) {
00739         cache = QPixmap(rect.size());
00740         cache.fill(Qt::white);
00741         QPainter cachePainter(&cache);
00742         QRect pixmapRect(0, 0, rect.width(), rect.height());
00743         int x = pixmapRect.center().x();
00744         QLinearGradient gradient(x, pixmapRect.top(), x, pixmapRect.bottom());
00745         gradient.setColorAt(0, gradientStart);
00746         gradient.setColorAt(1, gradientStop);
00747         cachePainter.fillRect(pixmapRect, gradient);
00748         cachePainter.end();
00749         if (UsePixmapCache)
00750             QPixmapCache::insert(gradientName, cache);
00751     }
00752     painter->drawPixmap(rect, cache);
00753 }
00754 
00755 static void qt_plastique_drawFrame(QPainter *painter, const QStyleOption *option, const QWidget *widget)
00756 {
00757     QRect rect = option->rect;
00758     QPen oldPen = painter->pen();
00759 
00760     QColor borderColor = option->palette.background().color().dark(178);
00761     QColor gradientStartColor = option->palette.button().color().light(104);
00762     QColor gradientStopColor = option->palette.button().color().dark(105);
00763     QColor alphaCornerColor;
00764     if (widget) {
00765         // ### backgroundrole/foregroundrole should be part of the style option
00766         alphaCornerColor = mergedColors(option->palette.color(widget->backgroundRole()), borderColor);
00767     } else {
00768         alphaCornerColor = mergedColors(option->palette.background().color(), borderColor);
00769     }
00770 
00771     // outline / border
00772     painter->setPen(borderColor);
00773     painter->drawLine(rect.left() + 2, rect.top(), rect.right() - 2, rect.top());
00774     painter->drawLine(rect.left() + 2, rect.bottom(), rect.right() - 2, rect.bottom());
00775     painter->drawLine(rect.left(), rect.top() + 2, rect.left(), rect.bottom() - 2);
00776     painter->drawLine(rect.right(), rect.top() + 2, rect.right(), rect.bottom() - 2);
00777     painter->drawPoint(rect.left() + 1, rect.top() + 1);
00778     painter->drawPoint(rect.right() - 1, rect.top() + 1);
00779     painter->drawPoint(rect.left() + 1, rect.bottom() - 1);
00780     painter->drawPoint(rect.right() - 1, rect.bottom() - 1);
00781 
00782     painter->setPen(alphaCornerColor);
00783     painter->drawPoint(rect.left() + 1, rect.top());
00784     painter->drawPoint(rect.right() - 1, rect.top());
00785     painter->drawPoint(rect.left() + 1, rect.bottom());
00786     painter->drawPoint(rect.right() - 1, rect.bottom());
00787     painter->drawPoint(rect.left(), rect.top() + 1);
00788     painter->drawPoint(rect.right(), rect.top() + 1);
00789     painter->drawPoint(rect.left(), rect.bottom() - 1);
00790     painter->drawPoint(rect.right(), rect.bottom() - 1);
00791 
00792     // inner border
00793     if ((option->state & QStyle::State_Sunken) || (option->state & QStyle::State_On))
00794         painter->setPen(option->palette.button().color().dark(118));
00795     else
00796         painter->setPen(gradientStartColor);
00797     painter->drawLine(rect.left() + 2, rect.top() + 1, rect.right() - 2, option->rect.top() + 1);
00798     painter->drawLine(rect.left() + 1, rect.top() + 2, rect.left() + 1, option->rect.bottom() - 2);
00799 
00800     if ((option->state & QStyle::State_Sunken) || (option->state & QStyle::State_On))
00801         painter->setPen(option->palette.button().color().dark(110));
00802     else
00803         painter->setPen(gradientStopColor.dark(102));
00804     painter->drawLine(rect.left() + 2, rect.bottom() - 1, rect.right() - 2, rect.bottom() - 1);
00805     painter->drawLine(rect.right() - 1, rect.top() + 2, rect.right() - 1, rect.bottom() - 2);
00806 
00807     painter->setPen(oldPen);
00808 }
00809 
00810 static void qt_plastique_drawShadedPanel(QPainter *painter, const QStyleOption *option, bool base,
00811                                          const QWidget *widget)
00812 {
00813     QRect rect = option->rect;
00814     QPen oldPen = painter->pen();
00815 
00816     QColor gradientStartColor = option->palette.button().color().light(104);
00817     QColor gradientStopColor = option->palette.button().color().dark(105);
00818 
00819     // gradient fill
00820     if ((option->state & QStyle::State_Enabled) || !(option->state & QStyle::State_AutoRaise)) {
00821         if ((option->state & QStyle::State_Sunken) || (option->state & QStyle::State_On)) {
00822             qt_plastique_draw_gradient(painter, rect.adjusted(1, 1, -1, -1),
00823                                        option->palette.button().color().dark(114),
00824                                        option->palette.button().color().dark(106));
00825         } else {
00826             qt_plastique_draw_gradient(painter, rect.adjusted(1, 1, -1, -1),
00827                                        base ? option->palette.background().color().light(105) : gradientStartColor,
00828                                        base ? option->palette.background().color().dark(102) : gradientStopColor);
00829         }
00830     }
00831 
00832     qt_plastique_drawFrame(painter, option, widget);
00833 
00834     painter->setPen(oldPen);
00835 }
00836 
00837 static void qt_plastique_draw_mdibutton(QPainter *painter, const QStyleOptionTitleBar *option, const QRect &tmp, bool hover, bool sunken)
00838 {
00839     if (tmp.isNull())
00840         return;
00841     bool active = (option->titleBarState & QStyle::State_Active);
00842 
00843     // ### use palette colors instead
00844     QColor mdiButtonGradientStartColor;
00845     QColor mdiButtonGradientStopColor;
00846     if (active) {
00847         mdiButtonGradientStartColor = QColor((hover || sunken) ? 0x7d8bb1 : 0x55689a);
00848         mdiButtonGradientStopColor = QColor((hover || sunken) ? 0x939ebe : 0x7381ab);
00849     } else {
00850         mdiButtonGradientStartColor = QColor((hover || sunken) ? 0x9e9e9e : 0x818181);
00851         mdiButtonGradientStopColor = QColor((hover || sunken) ? 0xababab : 0x929292);
00852     }
00853 
00854     qt_plastique_draw_gradient(painter, tmp.adjusted(1, 1, -1, -1),
00855                                mdiButtonGradientStartColor, mdiButtonGradientStopColor);
00856 
00857     QColor mdiButtonBorderColor;
00858     if (active) {
00859         mdiButtonBorderColor = (hover || sunken) ? QColor(0x627097) : QColor(0x324577);
00860     } else {
00861         mdiButtonBorderColor = (hover || sunken) ? QColor(0x838383) : QColor(0x5e5e5e);
00862     }
00863     painter->setPen(QPen(mdiButtonBorderColor, 1));
00864     painter->drawLine(tmp.left() + 2, tmp.top(), tmp.right() - 2, tmp.top());
00865     painter->drawLine(tmp.left() + 2, tmp.bottom(), tmp.right() - 2, tmp.bottom());
00866     painter->drawLine(tmp.left(), tmp.top() + 2, tmp.left(), tmp.bottom() - 2);
00867     painter->drawLine(tmp.right(), tmp.top() + 2, tmp.right(), tmp.bottom() - 2);
00868     painter->drawPoint(tmp.left() + 1, tmp.top() + 1);
00869     painter->drawPoint(tmp.right() - 1, tmp.top() + 1);
00870     painter->drawPoint(tmp.left() + 1, tmp.bottom() - 1);
00871     painter->drawPoint(tmp.right() - 1, tmp.bottom() - 1);
00872 }
00873 
00874 #ifndef QT_NO_DOCKWIDGET
00875 static QString elliditide(const QString &text, const QFontMetrics &fontMetrics, const QRect &rect, int *textWidth = 0)
00876 {
00877     // Chop and insert ellide into title if text is too wide
00878     QString title = text;
00879     int width = textWidth ? *textWidth : fontMetrics.width(text);
00880     QString ellipsis = QLatin1String("...");
00881     if (width > rect.width()) {
00882         QString leftHalf = title.left(title.size() / 2);
00883         QString rightHalf = title.mid(leftHalf.size() + 1);
00884         while (!leftHalf.isEmpty() && !rightHalf.isEmpty()) {
00885             leftHalf.chop(1);
00886             int width = fontMetrics.width(leftHalf + ellipsis + rightHalf);
00887             if (width < rect.width()) {
00888                 title = leftHalf + ellipsis + rightHalf;
00889                 width = width;
00890                 break;
00891             }
00892             rightHalf.remove(0, 1);
00893             width = fontMetrics.width(leftHalf + ellipsis + rightHalf);
00894             if (width < rect.width()) {
00895                 title = leftHalf + ellipsis + rightHalf;
00896                 width = width;
00897                 break;
00898             }
00899         }
00900     }
00901     if (textWidth)
00902         *textWidth = width;
00903     return title;
00904 }
00905 #endif
00906 
00907 #if !defined(QT_NO_DOCKWIDGET) || !defined(QT_NO_SPLITTER)
00908 static void qt_plastique_draw_handle(QPainter *painter, const QStyleOption *option,
00909                                      const QRect &rect, Qt::Orientation orientation,
00910                                      const QWidget *widget)
00911 {
00912     QColor borderColor = option->palette.background().color().dark(178);
00913     QColor alphaCornerColor;
00914     if (widget) {
00915         // ### backgroundrole/foregroundrole should be part of the style option
00916         alphaCornerColor = mergedColors(option->palette.color(widget->backgroundRole()), borderColor);
00917     } else {
00918         alphaCornerColor = mergedColors(option->palette.background().color(), borderColor);
00919     }
00920 
00921     QImage handle(qt_simple_toolbarhandle);
00922     handle.setColor(1, alphaCornerColor.rgba());
00923     handle.setColor(2, mergedColors(alphaCornerColor, option->palette.base().color()).rgba());
00924     handle.setColor(3, option->palette.base().color().rgba());
00925 
00926     const int spacing = 2;
00927 
00928     if (orientation == Qt::Vertical) {
00929         int nchunks = rect.width() / (handle.width() + spacing);
00930         for (int i = 0; i < nchunks; ++i)
00931             painter->drawImage(QPoint(rect.left() + i * (handle.width() + spacing), rect.top()), handle);
00932     } else {
00933         int nchunks = rect.height() / (handle.height() + spacing);
00934         for (int i = 0; i < nchunks; ++i)
00935             painter->drawImage(QPoint(rect.left(), rect.top() + i * (handle.height() + spacing)), handle);
00936     }
00937 }
00938 #endif
00939 
00940 class QPlastiqueStylePrivate : public QWindowsStylePrivate
00941 {
00942     Q_DECLARE_PUBLIC(QPlastiqueStyle)
00943 public:
00944     QPlastiqueStylePrivate();
00945     virtual ~QPlastiqueStylePrivate();
00946     void lookupIconTheme() const;
00947 
00948 #ifndef QT_NO_PROGRESSBAR
00949     QList<QProgressBar *> bars;
00950     int progressBarAnimateTimer;
00951     QTime timer;
00952 #endif
00953 };
00954 
00958 QPlastiqueStylePrivate::QPlastiqueStylePrivate() :
00959     QWindowsStylePrivate()
00960 #ifndef QT_NO_PROGRESSBAR
00961     , progressBarAnimateTimer(0)
00962 #endif
00963 {
00964     if (!qgetenv("QT_STYLE_NO_PIXMAPCACHE").isNull())
00965         UsePixmapCache = false;
00966 }
00967 
00971 QPlastiqueStylePrivate::~QPlastiqueStylePrivate()
00972 {
00973 }
00974 
00991 QPlastiqueStyle::QPlastiqueStyle()
00992     : QWindowsStyle(*new QPlastiqueStylePrivate)
00993 {
00994     setObjectName(QLatin1String("Plastique"));
00995 }
00996 
01000 QPlastiqueStyle::~QPlastiqueStyle()
01001 {
01002 }
01003 
01007 void QPlastiqueStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option,
01008                                     QPainter *painter, const QWidget *widget) const
01009 {
01010     Q_ASSERT(option);
01011 
01012     QColor borderColor = option->palette.background().color().dark(178);
01013     QColor gradientStartColor = option->palette.button().color().light(104);
01014     QColor gradientStopColor = option->palette.button().color().dark(105);
01015     QColor baseGradientStartColor = option->palette.base().color().dark(101);
01016     QColor baseGradientStopColor = option->palette.base().color().dark(106);
01017     QColor highlightedGradientStartColor = option->palette.button().color().light(101);
01018     QColor highlightedGradientStopColor = mergedColors(option->palette.button().color(), option->palette.highlight().color(), 85);
01019     QColor highlightedBaseGradientStartColor = option->palette.base().color();
01020     QColor highlightedBaseGradientStopColor = mergedColors(option->palette.base().color().dark(105), option->palette.highlight().color(), 70);
01021     QColor highlightedDarkInnerBorderColor = mergedColors(option->palette.button().color(), option->palette.highlight().color(), 35);
01022     QColor highlightedLightInnerBorderColor = mergedColors(option->palette.button().color(), option->palette.highlight().color(), 58);
01023     QColor alphaCornerColor;
01024     if (widget) {
01025         // ### backgroundrole/foregroundrole should be part of the style option
01026         alphaCornerColor = mergedColors(option->palette.color(widget->backgroundRole()), borderColor);
01027     } else {
01028         alphaCornerColor = mergedColors(option->palette.background().color(), borderColor);
01029     }
01030     QColor alphaInnerColor = mergedColors(highlightedLightInnerBorderColor, gradientStartColor);
01031     QColor alphaInnerColorNoHover = mergedColors(borderColor, gradientStartColor);
01032     QColor alphaTextColor = mergedColors(option->palette.background().color(), option->palette.text().color());
01033     QColor alphaLightTextColor = mergedColors(option->palette.background().color().light(250), option->palette.text().color().light(250));
01034     QColor lightShadow = option->palette.button().color().light(105);
01035     QColor shadowGradientStartColor = option->palette.button().color().dark(115);
01036     QColor shadow = shadowGradientStartColor;
01037 
01038     switch (element) {
01039     case PE_IndicatorButtonDropDown:
01040         drawPrimitive(PE_PanelButtonTool, option, painter, widget);
01041         break;
01042     case PE_FrameDefaultButton:
01043         if (!(option->state & QStyle::State_Enabled))
01044             break;
01045         painter->setPen(QPen(QColor(0, 0, 0, 127), 0));
01046         painter->drawLine(option->rect.left() + 2, option->rect.top(),
01047                           option->rect.right() - 2, option->rect.top());
01048         painter->drawLine(option->rect.left() + 2, option->rect.bottom(),
01049                           option->rect.right() - 2, option->rect.bottom());
01050         painter->drawLine(option->rect.left(), option->rect.top() + 2,
01051                           option->rect.left(), option->rect.bottom() - 2);
01052         painter->drawLine(option->rect.right(), option->rect.top() + 2,
01053                           option->rect.right(), option->rect.bottom() - 2);
01054         painter->drawPoint(option->rect.left() + 1, option->rect.top() + 1);
01055         painter->drawPoint(option->rect.right() - 1, option->rect.top() + 1);
01056         painter->drawPoint(option->rect.left() + 1, option->rect.bottom() - 1);
01057         painter->drawPoint(option->rect.right() - 1, option->rect.bottom() - 1);
01058         painter->setPen(QPen(QColor(0, 0, 0, 63), 0));
01059         painter->drawPoint(option->rect.left() + 1, option->rect.top());
01060         painter->drawPoint(option->rect.right() - 1, option->rect.top());
01061         painter->drawPoint(option->rect.left(), option->rect.top() + 1);
01062         painter->drawPoint(option->rect.right(), option->rect.top() + 1);
01063         painter->drawPoint(option->rect.left() + 1, option->rect.bottom());
01064         painter->drawPoint(option->rect.right() - 1, option->rect.bottom());
01065         painter->drawPoint(option->rect.left(), option->rect.bottom() - 1);
01066         painter->drawPoint(option->rect.right(), option->rect.bottom() - 1);
01067         break;
01068 #ifndef QT_NO_TABWIDGET
01069     case PE_FrameTabWidget:
01070         if (const QStyleOptionTabWidgetFrame *twf = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(option)) {
01071             if (twf->shape != QTabBar::RoundedNorth && twf->shape != QTabBar::RoundedWest &&
01072                 twf->shape != QTabBar::RoundedSouth && twf->shape != QTabBar::RoundedEast) {
01073                 QWindowsStyle::drawPrimitive(element, option, painter, widget);
01074                 break;
01075             }
01076 
01077             int borderThickness = pixelMetric(PM_TabBarBaseOverlap, twf, widget);
01078             bool reverse = (twf->direction == Qt::RightToLeft);
01079 
01080             painter->save();
01081 
01082             // Start by filling the contents of the tab widget frame (which is
01083             // actually a panel).
01084             painter->fillRect(option->rect.adjusted(1, 1, -1, -1), option->palette.window());
01085 
01086             QRect tabBarRect;
01087             switch (twf->shape) {
01088             case QTabBar::RoundedNorth:
01089                 if (reverse)
01090                     tabBarRect = QRect(twf->rect.right() - twf->leftCornerWidgetSize.width() - twf->tabBarSize.width() + 1, twf->rect.top(), twf->tabBarSize.width(), borderThickness);
01091                 else
01092                     tabBarRect = QRect(twf->rect.left() + twf->leftCornerWidgetSize.width(), twf->rect.top(), twf->tabBarSize.width(), borderThickness);
01093                 break ;
01094             case QTabBar::RoundedWest:
01095                 tabBarRect = QRect(twf->rect.left(), twf->rect.top() + twf->leftCornerWidgetSize.height(), borderThickness, twf->tabBarSize.height());
01096                 break ;
01097             case QTabBar::RoundedEast:
01098                 tabBarRect = QRect(twf->rect.right() - borderThickness + 1, twf->rect.top()  + twf->leftCornerWidgetSize.height(),
01099                                    borderThickness, twf->tabBarSize.height());
01100                 break ;
01101             case QTabBar::RoundedSouth:
01102                 if (reverse)
01103                     tabBarRect = QRect(twf->rect.right() - twf->leftCornerWidgetSize.width() - twf->tabBarSize.width() + 1,
01104                                        twf->rect.bottom() - borderThickness + 1, twf->tabBarSize.width(), borderThickness);
01105                 else
01106                     tabBarRect = QRect(twf->rect.left() + twf->leftCornerWidgetSize.width(),
01107                                        twf->rect.bottom() - borderThickness + 1, twf->tabBarSize.width(), borderThickness);
01108                 break ;
01109             default:
01110                 break;
01111             }
01112 
01113             QRegion region(twf->rect);
01114             region -= tabBarRect;
01115             painter->setClipRegion(region);
01116 
01117             // Outer border
01118             QLine leftLine = QLine(twf->rect.topLeft() + QPoint(0, 2), twf->rect.bottomLeft() - QPoint(0, 2));
01119             QLine rightLine = QLine(twf->rect.topRight() + QPoint(0, 2), twf->rect.bottomRight() - QPoint(0, 2));
01120             QLine bottomLine = QLine(twf->rect.bottomLeft() + QPoint(2, 0), twf->rect.bottomRight() - QPoint(2, 0));
01121             QLine topLine = QLine(twf->rect.topLeft() + QPoint(2, 0), twf->rect.topRight() - QPoint(2, 0));
01122 
01123             QBrush border = option->palette.shadow();
01124             qBrushSetAlphaF(&border, 0.4);
01125             painter->setPen(QPen(border, 0));
01126             painter->drawLine(topLine);
01127 
01128             // Inner border
01129             QLine innerLeftLine = QLine(leftLine.p1() + QPoint(1, 0), leftLine.p2() + QPoint(1, 0));
01130             QLine innerRightLine = QLine(rightLine.p1() - QPoint(1, 0), rightLine.p2() - QPoint(1, 0));
01131             QLine innerBottomLine = QLine(bottomLine.p1() - QPoint(0, 1), bottomLine.p2() - QPoint(0, 1));
01132             QLine innerTopLine = QLine(topLine.p1() + QPoint(0, 1), topLine.p2() + QPoint(0, 1));
01133 
01134             // Rounded Corner
01135             QPoint leftBottomOuterCorner = QPoint(innerLeftLine.p2() + QPoint(0, 1));
01136             QPoint leftBottomInnerCorner1 = QPoint(leftLine.p2() + QPoint(0, 1));
01137             QPoint leftBottomInnerCorner2 = QPoint(bottomLine.p1() - QPoint(1, 0));
01138             QPoint rightBottomOuterCorner = QPoint(innerRightLine.p2() + QPoint(0, 1));
01139             QPoint rightBottomInnerCorner1 = QPoint(rightLine.p2() + QPoint(0, 1));
01140             QPoint rightBottomInnerCorner2 = QPoint(bottomLine.p2() + QPoint(1, 0));
01141             QPoint rightTopOuterCorner = QPoint(innerRightLine.p1() - QPoint(0, 1));
01142             QPoint rightTopInnerCorner1 = QPoint(rightLine.p1() - QPoint(0, 1));
01143             QPoint rightTopInnerCorner2 = QPoint(topLine.p2() + QPoint(1, 0));
01144             QPoint leftTopOuterCorner = QPoint(innerLeftLine.p1() - QPoint(0, 1));
01145             QPoint leftTopInnerCorner1 = QPoint(leftLine.p1() - QPoint(0, 1));
01146             QPoint leftTopInnerCorner2 = QPoint(topLine.p1() - QPoint(1, 0));
01147 
01148             painter->drawLine(leftLine);
01149             painter->drawLine(rightLine);
01150             painter->drawLine(bottomLine);
01151             painter->drawPoint(leftBottomOuterCorner);
01152             painter->drawPoint(rightBottomOuterCorner);
01153             painter->drawPoint(rightTopOuterCorner);
01154             painter->drawPoint(leftTopOuterCorner);
01155 
01156             QBrush innerTopLeft = option->palette.shadow();
01157             qBrushSetAlphaF(&innerTopLeft, 0.075);
01158             painter->setPen(QPen(innerTopLeft, 0));
01159             painter->drawLine(innerLeftLine);
01160             painter->drawLine(innerTopLine);
01161 
01162             QBrush innerBottomRight = option->palette.shadow();
01163             qBrushSetAlphaF(&innerBottomRight, 0.23);
01164             painter->setPen(QPen(innerBottomRight, 0));
01165             painter->drawLine(innerRightLine);
01166             painter->drawLine(innerBottomLine);
01167 
01168             QBrush corner = option->palette.shadow();
01169             qBrushSetAlphaF(&corner, 0.25);
01170             painter->setPen(QPen(corner, 0));
01171             painter->drawPoint(leftBottomInnerCorner1);
01172             painter->drawPoint(leftBottomInnerCorner2);
01173             painter->drawPoint(rightBottomInnerCorner1);
01174             painter->drawPoint(rightBottomInnerCorner2);
01175             painter->drawPoint(rightTopInnerCorner1);
01176             painter->drawPoint(rightTopInnerCorner2);
01177             painter->drawPoint(leftTopInnerCorner1);
01178             painter->drawPoint(leftTopInnerCorner2);
01179 
01180             painter->restore();
01181         }
01182         break ;
01183 #endif // QT_NO_TABWIDGET
01184 #ifndef QT_NO_TABBAR
01185     case PE_FrameTabBarBase:
01186         if (const QStyleOptionTabBarBase *tbb = qstyleoption_cast<const QStyleOptionTabBarBase *>(option)) {
01187             if (tbb->shape != QTabBar::RoundedNorth && tbb->shape != QTabBar::RoundedWest &&
01188                 tbb->shape != QTabBar::RoundedSouth && tbb->shape != QTabBar::RoundedEast) {
01189                 QWindowsStyle::drawPrimitive(element, option, painter, widget);
01190                 break;
01191             }
01192 
01193             painter->save();
01194 
01195             QRegion region(tbb->rect);
01196             region -= tbb->tabBarRect;
01197             painter->setClipRegion(region);
01198 
01199             QLine topLine = QLine(tbb->rect.bottomLeft() - QPoint(0, 1), tbb->rect.bottomRight() - QPoint(0, 1));
01200             QLine bottomLine = QLine(tbb->rect.bottomLeft(), tbb->rect.bottomRight());
01201 
01202             QBrush border = option->palette.shadow();
01203             qBrushSetAlphaF(&border, 0.4);
01204             QBrush innerTopLeft = option->palette.shadow();
01205             qBrushSetAlphaF(&innerTopLeft, 0.075);
01206             QBrush innerBottomRight = option->palette.shadow();
01207             qBrushSetAlphaF(&innerBottomRight, 0.23);
01208             QBrush corner = option->palette.shadow();
01209             qBrushSetAlphaF(&corner, 0.25);
01210 
01211             if (tbb->shape == QTabBar::RoundedSouth)
01212                 painter->setPen(QPen(corner, 0));
01213             else
01214                 painter->setPen(QPen(border, 0));
01215             painter->drawLine(topLine);
01216 
01217             if (tbb->shape != QTabBar::RoundedSouth)
01218                 painter->setPen(QPen(innerTopLeft, 0));
01219             else
01220                 painter->setPen(QPen(border, 0));
01221             painter->drawLine(bottomLine);
01222 
01223             painter->restore();
01224         }
01225         break ;
01226 #endif // QT_NO_TABBAR
01227 #ifndef QT_NO_GROUPBOX
01228     case PE_FrameGroupBox:
01229         if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(option)) {
01230             QStyleOptionFrameV2 frameV2(*frame);
01231             if (frameV2.features & QStyleOptionFrameV2::Flat) {
01232                 QPen oldPen = painter->pen();
01233                 painter->setPen(borderColor);
01234                 painter->drawLine(frameV2.rect.topLeft(), frameV2.rect.topRight());
01235                 painter->setPen(oldPen);
01236             } else {
01237                 frameV2.state &= ~(State_Sunken | State_HasFocus);
01238                 drawPrimitive(PE_Frame, &frameV2, painter, widget);
01239             }
01240         }
01241         break;
01242 #endif // QT_NO_GROUPBOX
01243     case PE_Frame: {
01244         QFrame::Shadow shadow = QFrame::Plain;
01245         if (option->state & State_Sunken)
01246             shadow = QFrame::Sunken;
01247         else if (option->state & State_Raised)
01248             shadow = QFrame::Raised;
01249         qt_plastique_draw_frame(painter, option->rect, option, shadow);
01250         break;
01251     }
01252 #ifndef QT_NO_LINEEDIT
01253     case PE_FrameLineEdit:
01254         qt_plastique_draw_frame(painter, option->rect, option, QFrame::Sunken);
01255         break;
01256     case PE_PanelLineEdit:
01257         if (const QStyleOptionFrame *lineEdit = qstyleoption_cast<const QStyleOptionFrame *>(option)) {
01258             // Panel of a line edit inside combo box or spin box is drawn in CC_ComboBox and CC_SpinBox
01259             if (widget) {
01260 #ifndef QT_NO_COMBOBOX
01261                 if (qobject_cast<const QComboBox *>(widget->parentWidget()))
01262                     break;
01263 #endif
01264 #ifndef QT_NO_SPINBOX
01265                 if (qobject_cast<const QAbstractSpinBox *>(widget->parentWidget()))
01266                     break;
01267 #endif
01268             }
01269 
01270             painter->save();
01271 
01272             // Fill the line edit insides
01273             QRect filledRect = lineEdit->rect.adjusted(1, 1, -1, -1);
01274             QBrush baseBrush = qMapBrushToRect(lineEdit->palette.base(), filledRect);
01275             painter->setBrushOrigin(filledRect.topLeft());
01276             painter->fillRect(filledRect.adjusted(1, 1, -1, -1), baseBrush);
01277 
01278             painter->setPen(QPen(baseBrush, 0));
01279             painter->drawLine(filledRect.left(), filledRect.top() + 1,
01280                               filledRect.left(), filledRect.bottom() - 1);
01281             painter->drawLine(filledRect.right(), filledRect.top() + 1,
01282                               filledRect.right(), filledRect.bottom() - 1);
01283             painter->drawLine(filledRect.left() + 1, filledRect.top(),
01284                               filledRect.right() - 1, filledRect.top());
01285             painter->drawLine(filledRect.left() + 1, filledRect.bottom(),
01286                               filledRect.right() - 1, filledRect.bottom());
01287             if (lineEdit->lineWidth != 0)
01288                 qt_plastique_draw_frame(painter, option->rect, option, QFrame::Sunken);
01289 
01290             painter->restore();
01291             break;
01292         }
01293 #endif // QT_NO_LINEEDIT
01294     case PE_FrameDockWidget:
01295     case PE_FrameMenu:
01296     case PE_FrameStatusBar: {
01297         // Draws the frame around a popup menu.
01298         QPen oldPen = painter->pen();
01299         painter->setPen(borderColor);
01300         painter->drawRect(option->rect.adjusted(0, 0, -1, -1));
01301         painter->setPen(alphaCornerColor);
01302         painter->drawPoint(option->rect.topLeft());
01303         painter->drawPoint(option->rect.topRight());
01304         painter->drawPoint(option->rect.bottomLeft());
01305         painter->drawPoint(option->rect.bottomRight());
01306         painter->setPen(oldPen);
01307         break;
01308     }
01309 #ifdef QT3_SUPPORT
01310     case PE_Q3DockWindowSeparator: {
01311         QPen oldPen = painter->pen();
01312         painter->setPen(alphaCornerColor);
01313         QRect rect = option->rect;
01314         if (option->state & State_Horizontal) {
01315             painter->drawLine(rect.right(), rect.top() + 2, rect.right(), rect.bottom() - 1);
01316         } else {
01317             painter->drawLine(rect.left() + 2, rect.bottom(), rect.right() - 1, rect.bottom());
01318         }
01319         painter->setPen(oldPen);
01320         break;
01321     }
01322     case PE_Q3Separator: {
01323         QPen oldPen = painter->pen();
01324         painter->setPen(alphaCornerColor);
01325         if ((option->state & State_Horizontal) == 0)
01326             painter->drawLine(option->rect.bottomLeft(), option->rect.bottomRight());
01327         else
01328             painter->drawLine(option->rect.topRight(), option->rect.bottomRight());
01329         painter->setPen(option->palette.background().color().light(104));
01330         if ((option->state & State_Horizontal) == 0)
01331             painter->drawLine(option->rect.topLeft(), option->rect.topRight());
01332         else
01333             painter->drawLine(option->rect.topLeft(), option->rect.bottomLeft());
01334         painter->setPen(oldPen);
01335         break;
01336     }
01337 #endif // QT3_SUPPORT
01338 #ifndef QT_NO_MAINWINDOW
01339     case PE_PanelMenuBar:
01340         if (widget && qobject_cast<const QMainWindow *>(widget->parentWidget())
01341 #ifdef QT3_SUPPORT
01342             || (widget->parentWidget() && widget->parentWidget()->inherits("Q3MainWindow"))
01343 #endif
01344             ) {
01345             // Draws the light line above and the dark line below menu bars and
01346             // tool bars.
01347             QPen oldPen = painter->pen();
01348             if (element == PE_PanelMenuBar || (option->state & State_Horizontal)) {
01349                 painter->setPen(alphaCornerColor);
01350                 painter->drawLine(option->rect.left(), option->rect.bottom(),
01351                                   option->rect.right(), option->rect.bottom());
01352                 painter->setPen(option->palette.background().color().light(104));
01353                 painter->drawLine(option->rect.left(), option->rect.top(),
01354                                   option->rect.right(), option->rect.top());
01355             } else {
01356                 painter->setPen(option->palette.background().color().light(104));
01357                 painter->drawLine(option->rect.left(), option->rect.top(),
01358                                   option->rect.left(), option->rect.bottom());
01359                 painter->setPen(alphaCornerColor);
01360                 painter->drawLine(option->rect.right(), option->rect.top(),
01361                                   option->rect.right(), option->rect.bottom());
01362             }
01363             painter->setPen(oldPen);
01364         }
01365         break;
01366 #endif // QT_NO_MAINWINDOW
01367     case PE_IndicatorHeaderArrow: {
01368         bool usedAntialiasing = painter->renderHints() & QPainter::Antialiasing;
01369         if (!usedAntialiasing)
01370             painter->setRenderHint(QPainter::Antialiasing);
01371         QWindowsStyle::drawPrimitive(element, option, painter, widget);
01372         if (!usedAntialiasing)
01373             painter->setRenderHint(QPainter::Antialiasing, false);
01374         break;
01375     }
01376     case PE_PanelButtonTool:
01377         // Draws a tool button (f.ex., in QToolBar and QTabBar)
01378         if ((option->state & State_Enabled) || !(option->state & State_AutoRaise))
01379             qt_plastique_drawShadedPanel(painter, option, true, widget);
01380         break;
01381 #ifndef QT_NO_TOOLBAR
01382     case PE_IndicatorToolBarHandle: {
01383         QPixmap cache;
01384         QRect rect = option->rect;
01385 #ifdef QT3_SUPPORT
01386         if (widget && widget->inherits("Q3DockWindowHandle") && widget->parentWidget()->inherits("Q3DockWindow")) {
01387             if (!(option->state & State_Horizontal))
01388                 rect.adjust(2, 0, -2, 0);
01389         }
01390 #endif
01391         QString pixmapName = uniqueName(QLatin1String("toolbarhandle"), option, rect.size());
01392         if (!UsePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
01393             cache = QPixmap(rect.size());
01394             cache.fill(Qt::transparent);
01395             QPainter cachePainter(&cache);
01396             QRect cacheRect(QPoint(0, 0), rect.size());
01397             if (widget)
01398                 cachePainter.fillRect(cacheRect, option->palette.brush(widget->backgroundRole()));
01399             else
01400                 cachePainter.fillRect(cacheRect, option->palette.background());
01401 
01402             QImage handle(qt_toolbarhandle);
01403             handle.setColor(1, alphaCornerColor.rgba());
01404             handle.setColor(2, mergedColors(alphaCornerColor, option->palette.base().color()).rgba());
01405             handle.setColor(3, option->palette.base().color().rgba());
01406 
01407             if (option->state & State_Horizontal) {
01408                 int nchunks = cacheRect.height() / handle.height();
01409                 int indent = (cacheRect.height() - (nchunks * handle.height())) / 2;
01410                 for (int i = 0; i < nchunks; ++i)
01411                     cachePainter.drawImage(QPoint(cacheRect.left() + 3, cacheRect.top() + indent + i * handle.height()),
01412                                            handle);
01413             } else {
01414                 int nchunks = cacheRect.width() / handle.width();
01415                 int indent = (cacheRect.width() - (nchunks * handle.width())) / 2;
01416                 for (int i = 0; i < nchunks; ++i)
01417                     cachePainter.drawImage(QPoint(cacheRect.left() + indent + i * handle.width(), cacheRect.top() + 3),
01418                                            handle);
01419             }
01420             cachePainter.end();
01421             if (UsePixmapCache)
01422                 QPixmapCache::insert(pixmapName, cache);
01423         }
01424         painter->drawPixmap(rect.topLeft(), cache);
01425         break;
01426     }
01427     case PE_IndicatorToolBarSeparator: {
01428         QPen oldPen = painter->pen();
01429         painter->setPen(alphaCornerColor);
01430         if (option->state & State_Horizontal) {
01431             painter->drawLine(option->rect.left(), option->rect.top() + 1, option->rect.left(), option->rect.bottom() - 2);
01432             painter->setPen(option->palette.base().color());
01433             painter->drawLine(option->rect.right(), option->rect.top() + 1, option->rect.right(), option->rect.bottom() - 2);
01434         } else {
01435             painter->drawLine(option->rect.left() + 1, option->rect.top(), option->rect.right() - 2, option->rect.top());
01436             painter->setPen(option->palette.base().color());
01437             painter->drawLine(option->rect.left() + 1, option->rect.bottom(), option->rect.right() - 2, option->rect.bottom());
01438         }
01439         painter->setPen(oldPen);
01440         break;
01441     }
01442 #endif // QT_NO_TOOLBAR
01443     case PE_PanelButtonCommand:
01444         if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) {
01445             bool sunken = (button->state & State_Sunken) || (button->state & State_On);
01446             if ((button->features & QStyleOptionButton::Flat) && !sunken)
01447                 break;
01448 
01449             bool defaultButton = (button->features & (QStyleOptionButton::DefaultButton
01450                                                       | QStyleOptionButton::AutoDefaultButton));
01451 
01452             BEGIN_PLASTIQUE_PIXMAPCACHE(QString("pushbutton-%1").arg(defaultButton))
01453 
01454             QPen oldPen = p->pen();
01455             bool hover = (button->state & State_Enabled) && (button->state & State_MouseOver);
01456 
01457             // Give the painter a different brush origin for sunken buttons
01458             if (sunken) {
01459                 // ### No such function
01460                 // p->setPenOrigin(rect.left() + 1, rect.top() + 1);
01461                 p->setBrushOrigin(rect.left() + 1, rect.top() + 1);
01462             }
01463 
01464             // Draw border
01465             qt_plastique_draw_frame(p, rect, option);
01466 
01467             // Fill the panel
01468             QRectF fillRect = rect.adjusted(2, 2, -2, -2);
01469 
01470             // Button colors
01471             QBrush alphaCornerBrush = qMapBrushToRect(qBrushDark(option->palette.button(), 165), rect);
01472             qBrushSetAlphaF(&alphaCornerBrush, 0.5);
01473             QBrush buttonGradientBrush;
01474             QBrush leftLineGradientBrush;
01475             QBrush rightLineGradientBrush;
01476             QBrush sunkenButtonGradientBrush;
01477             QBrush sunkenLeftLineGradientBrush;
01478             QBrush sunkenRightLineGradientBrush;
01479             QBrush buttonBrush = qMapBrushToRect(option->palette.button(), rect);
01480             if (buttonBrush.gradient() || !buttonBrush.texture().isNull()) {
01481                 buttonGradientBrush = buttonBrush;
01482                 sunkenButtonGradientBrush = qBrushDark(buttonBrush, 108);
01483                 leftLineGradientBrush = qBrushLight(buttonBrush, 105);
01484                 rightLineGradientBrush = qBrushDark(buttonBrush, 105);
01485                 sunkenLeftLineGradientBrush = qBrushDark(buttonBrush, 110);
01486                 sunkenRightLineGradientBrush = qBrushDark(buttonBrush, 106);
01487             } else {
01488                 // Generate gradients
01489                 QLinearGradient buttonGradient(rect.topLeft(), rect.bottomLeft());
01490                 buttonGradient.setColorAt(0.0, buttonBrush.color().light(104));
01491                 buttonGradient.setColorAt(1.0, buttonBrush.color().dark(110));
01492                 buttonGradientBrush = QBrush(buttonGradient);
01493 
01494                 QLinearGradient buttonGradient2(rect.topLeft(), rect.bottomLeft());
01495                 buttonGradient2.setColorAt(0.0, buttonBrush.color().dark(113));
01496                 buttonGradient2.setColorAt(1.0, buttonBrush.color().dark(103));
01497                 sunkenButtonGradientBrush = QBrush(buttonGradient2);
01498 
01499                 QLinearGradient buttonGradient3(rect.topLeft(), rect.bottomLeft());
01500                 buttonGradient3.setColorAt(0.0, buttonBrush.color().light(105));
01501                 buttonGradient3.setColorAt(1.0, buttonBrush.color());
01502                 leftLineGradientBrush = QBrush(buttonGradient3);
01503 
01504                 QLinearGradient buttonGradient4(rect.topLeft(), rect.bottomLeft());
01505                 buttonGradient4.setColorAt(0.0, buttonBrush.color());
01506                 buttonGradient4.setColorAt(1.0, buttonBrush.color().dark(110));
01507                 rightLineGradientBrush = QBrush(buttonGradient4);
01508 
01509                 QLinearGradient buttonGradient5(rect.topLeft(), rect.bottomLeft());
01510                 buttonGradient5.setColorAt(0.0, buttonBrush.color().dark(113));
01511                 buttonGradient5.setColorAt(1.0, buttonBrush.color().dark(107));
01512                 sunkenLeftLineGradientBrush = QBrush(buttonGradient5);
01513 
01514                 QLinearGradient buttonGradient6(rect.topLeft(), rect.bottomLeft());
01515                 buttonGradient6.setColorAt(0.0, buttonBrush.color().dark(108));
01516                 buttonGradient6.setColorAt(1.0, buttonBrush.color().dark(103));
01517                 sunkenRightLineGradientBrush = QBrush(buttonGradient6);
01518             }
01519 
01520             // Main fill
01521             p->fillRect(fillRect,
01522                               qMapBrushToRect(sunken ? sunkenButtonGradientBrush
01523                                               : buttonGradientBrush, rect));
01524 
01525             // Top line
01526             p->setPen(QPen(qBrushLight(qMapBrushToRect(sunken ? sunkenButtonGradientBrush
01527                                             : buttonGradientBrush, rect), 105), 0));
01528             p->drawLine(QPointF(rect.left() + 2, rect.top() + 1),
01529                               QPointF(rect.right() - 2, rect.top() + 1));
01530 
01531             // Bottom line
01532             p->setPen(QPen(qBrushDark(qMapBrushToRect(sunken ? sunkenButtonGradientBrush
01533                                             : buttonGradientBrush, rect), 105), 0));
01534             p->drawLine(QPointF(rect.left() + 2, rect.bottom() - 1),
01535                               QPointF(rect.right() - 2, rect.bottom() - 1));
01536 
01537             // Left line
01538             p->setPen(QPen(qMapBrushToRect(sunken ? sunkenLeftLineGradientBrush
01539                                                  : leftLineGradientBrush, rect), 1));
01540             p->drawLine(QPointF(rect.left() + 1, rect.top() + 2),
01541                               QPointF(rect.left() + 1, rect.bottom() - 2));
01542 
01543             // Right line
01544             p->setPen(QPen(qMapBrushToRect(sunken ? sunkenRightLineGradientBrush
01545                                                  : rightLineGradientBrush, rect), 1));
01546             p->drawLine(QPointF(rect.right() - 1, rect.top() + 2),
01547                               QPointF(rect.right() - 1, rect.bottom() - 2));
01548 
01549             // Hovering
01550             if (hover && !sunken) {
01551                 QBrush hover = qMapBrushToRect(option->palette.highlight(), rect);
01552                 QBrush hoverOuter = hover;
01553                 qBrushSetAlphaF(&hoverOuter, 0.7);
01554 
01555                 p->setPen(QPen(hover, 0));
01556                 p->drawLine(rect.left() + 2, rect.top(), rect.right() - 2, rect.top());
01557                 p->drawLine(rect.left() + 2, rect.bottom(), rect.right() - 2, rect.bottom());
01558 
01559                 p->setPen(QPen(hoverOuter, 0));
01560                 p->drawLine(rect.left() + 1, rect.top() + 1, rect.right() - 1, rect.top() + 1);
01561                 p->drawLine(rect.left() + 1, rect.bottom() - 1, rect.right() - 1, rect.bottom() - 1);
01562 
01563                 QBrush hoverInner = hover;
01564                 qBrushSetAlphaF(&hoverInner, 0.45);
01565                 p->setPen(QPen(hoverInner, 0));
01566                 p->drawLine(rect.left() + 1, rect.top() + 2, rect.right() - 1, rect.top() + 2);
01567                 p->drawLine(rect.left() + 1, rect.bottom() - 2, rect.right() - 1, rect.bottom() - 2);
01568 
01569                 QBrush hoverSide = hover;
01570                 qBrushSetAlphaF(&hoverSide, 0.075);
01571                 p->setPen(QPen(hoverSide, 0));
01572                 p->drawLine(rect.left() + 1, rect.top() + 2, rect.left() + 1, rect.bottom() - 2);
01573                 p->drawLine(rect.right() - 1, rect.top() + 2, rect.right() - 1, rect.bottom() - 2);
01574             }
01575 
01576             p->setPen(oldPen);
01577 
01578             END_PLASTIQUE_PIXMAPCACHE
01579         }
01580         break;
01581     case PE_IndicatorCheckBox:
01582         if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) {
01583             BEGIN_PLASTIQUE_PIXMAPCACHE(QLatin1String("checkbox"))
01584 
01585             p->save();
01586 
01587             // Outline
01588             QBrush border = option->palette.shadow();
01589             qBrushSetAlphaF(&border, 0.4);
01590             p->setPen(QPen(border, 0));
01591             p->drawLine(rect.left() + 1, rect.top(), rect.right() - 1, rect.top());
01592             p->drawLine(rect.left() + 1, rect.bottom(), rect.right() - 1, rect.bottom());
01593             p->drawLine(rect.left(), rect.top() + 1, rect.left(), rect.bottom() - 1);
01594             p->drawLine(rect.right(), rect.top() + 1, rect.right(), rect.bottom() - 1);
01595 
01596             QBrush corner = option->palette.shadow();
01597             qBrushSetAlphaF(&corner, 0.2);
01598             p->setPen(QPen(corner, 0));
01599             p->drawPoint(rect.topLeft());
01600             p->drawPoint(rect.topRight());
01601             p->drawPoint(rect.bottomLeft());
01602             p->drawPoint(rect.bottomRight());
01603 
01604             // Fill
01605             QBrush baseBrush = qMapBrushToRect(button->palette.base(), rect);
01606             if (!baseBrush.gradient() && baseBrush.texture().isNull()) {
01607                 QLinearGradient gradient(rect.center().x(), rect.top(), rect.center().x(), rect.bottom());
01608                 gradient.setColorAt(0, baseBrush.color());
01609                 gradient.setColorAt(1, baseBrush.color().dark(105));
01610                 baseBrush = gradient;
01611             }
01612             p->fillRect(rect.adjusted(1, 1, -1, -1), baseBrush);
01613 
01614             // Hover
01615             if ((button->state & State_Enabled) && (button->state & State_MouseOver)) {
01616                 QBrush pen = qMapBrushToRect(button->palette.highlight(), rect);
01617                 qBrushSetAlphaF(&pen, 0.8);
01618                 p->setPen(QPen(pen, 0));
01619                 p->drawRect(rect.adjusted(1, 1, -2, -2));
01620                 qBrushSetAlphaF(&pen, 0.5);
01621                 p->setPen(QPen(pen, 0));
01622                 p->drawRect(rect.adjusted(2, 2, -3, -3));
01623 
01624                 qBrushSetAlphaF(&pen, 0.2);
01625                 p->setBrush(pen);
01626                 p->drawRect(rect.adjusted(2, 2, -3, -3));
01627             }
01628 
01629             // Indicator
01630             bool on = button->state & State_On;
01631             bool sunken = button->state & State_Sunken;
01632             bool unchanged = button->state & State_NoChange;
01633             bool enabled = button->state & State_Enabled;
01634             if (on || (enabled && sunken) || unchanged) {
01635                 p->setRenderHint(QPainter::Antialiasing);
01636                 QBrush pointBrush = qMapBrushToRect(button->palette.text(), rect);
01637                 if (sunken)
01638                     qBrushSetAlphaF(&pointBrush, 0.5);
01639                 else if (unchanged)
01640                     qBrushSetAlphaF(&pointBrush, 0.3);
01641                 p->setPen(QPen(pointBrush, 3));
01642                 p->drawLine(rect.left() + 4, rect.top() + 4, rect.right() - 3, rect.bottom() - 3);
01643                 p->drawLine(rect.right() - 3, rect.top() + 4, rect.left() + 4, rect.bottom() - 3);
01644             }
01645 
01646             p->restore();
01647             END_PLASTIQUE_PIXMAPCACHE
01648         }
01649         break;
01650     case PE_IndicatorRadioButton:
01651         if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) {
01652             BEGIN_PLASTIQUE_PIXMAPCACHE(QLatin1String("radiobutton"))
01653 
01654             p->save();
01655             p->setRenderHint(QPainter::Antialiasing);
01656 
01657             // The the filled ellipse
01658             QBrush border = qMapBrushToRect(option->palette.shadow(), rect);
01659             qBrushSetAlphaF(&border, 0.51);
01660             p->setPen(QPen(border, 0));
01661 
01662             QBrush baseBrush = qMapBrushToRect(button->palette.base(), rect);
01663             if (!baseBrush.gradient() && baseBrush.texture().isNull()) {
01664                 QLinearGradient gradient(rect.center().x(), rect.top(), rect.center().x(), rect.bottom());
01665                 gradient.setColorAt(0, baseBrush.color());
01666                 gradient.setColorAt(1, baseBrush.color().dark(105));
01667                 baseBrush = gradient;
01668             }
01669             p->setBrush(baseBrush);
01670             p->drawEllipse(QRectF(rect).adjusted(1, 1, -1, -1));
01671 
01672             // Hover
01673             if ((button->state & State_Enabled) && (button->state & State_MouseOver)) {
01674                 QBrush pen = qMapBrushToRect(button->palette.highlight(), rect);
01675                 qBrushSetAlphaF(&pen, 0.8);
01676                 p->setPen(QPen(pen, 0));
01677                 qBrushSetAlphaF(&pen, 0.2);
01678                 p->setBrush(pen);
01679                 p->drawEllipse(QRectF(rect).adjusted(2, 2, -2, -2));
01680             }
01681 
01682             // Indicator
01683             bool on = button->state & State_On;
01684             bool sunken = button->state & State_Sunken;
01685             bool enabled = button->state & State_Enabled;
01686             if (on || (enabled && sunken)) {
01687                 p->setPen(Qt::NoPen);
01688                 QBrush pointBrush = qMapBrushToRect(button->palette.text(), rect);
01689                 if (sunken)
01690                     qBrushSetAlphaF(&pointBrush, 0.5);
01691                 p->setBrush(pointBrush);
01692                 p->drawEllipse(QRectF(rect).adjusted(3, 3, -3, -3));
01693             }
01694 
01695             p->restore();
01696             END_PLASTIQUE_PIXMAPCACHE
01697         }
01698         break;
01699 #ifndef QT_NO_DOCKWIDGET
01700     case PE_IndicatorDockWidgetResizeHandle:
01701         if ((option->state & State_Enabled) && (option->state & State_MouseOver))
01702             painter->fillRect(option->rect, QColor(255, 255, 255, 128));
01703         if (option->state & State_Horizontal) {
01704             int width = option->rect.width() / 3;
01705             QRect rect(option->rect.center().x() - width / 2,
01706                        option->rect.top() + (option->rect.height() / 2) - 1, width, 3);
01707             qt_plastique_draw_handle(painter, option, rect, Qt::Vertical, widget);
01708         } else {
01709             int height = option->rect.height() / 3;
01710             QRect rect(option->rect.left() + (option->rect.width() / 2 - 1),
01711                        option->rect.center().y() - height / 2, 3, height);
01712             qt_plastique_draw_handle(painter, option, rect, Qt::Horizontal, widget);
01713         }
01714         break;
01715 #endif // QT_NO_DOCKWIDGET
01716     case PE_IndicatorViewItemCheck: {
01717         QStyleOptionButton button;
01718         button.QStyleOption::operator=(*option);
01719         button.state &= ~State_MouseOver;
01720         drawPrimitive(PE_IndicatorCheckBox, &button, painter, widget);
01721         break;
01722     }
01723     case PE_FrameWindow: {
01724         painter->save();
01725         bool active = (option->state & State_Active);
01726         int titleBarStop = option->rect.top() + pixelMetric(PM_TitleBarHeight, option, widget);
01727 
01728         QPalette palette = option->palette;
01729         if (!active)
01730             palette.setCurrentColorGroup(QPalette::Disabled);
01731 
01732         // Frame and rounded corners
01733         painter->setPen(mergedColors(palette.highlight().color(), Qt::black, 50));
01734 
01735         // bottom border line
01736         painter->drawLine(option->rect.left() + 1, option->rect.bottom(), option->rect.right() - 1, option->rect.bottom());
01737 
01738         // bottom left and right side border lines
01739         painter->drawLine(option->rect.left(), titleBarStop, option->rect.left(), option->rect.bottom() - 1);
01740         painter->drawLine(option->rect.right(), titleBarStop, option->rect.right(), option->rect.bottom() - 1);
01741         painter->drawPoint(option->rect.left() + 1, option->rect.bottom() - 1);
01742         painter->drawPoint(option->rect.right() - 1, option->rect.bottom() - 1);
01743 
01744 #ifdef QT3_SUPPORT
01745         if (widget && widget->inherits("Q3DockWindow")) {
01746             // also draw the frame on the title bar
01747             painter->drawLine(option->rect.left() + 1, option->rect.top(),
01748                               option->rect.right() - 1, option->rect.top());
01749             painter->drawLine(option->rect.left(), option->rect.top() + 1,
01750                               option->rect.left(), titleBarStop);
01751             painter->drawLine(option->rect.right(), option->rect.top() + 1,
01752                               option->rect.right(), titleBarStop);
01753         }
01754 #endif
01755 
01756         // alpha corners
01757         painter->setPen(mergedColors(palette.highlight().color(), palette.background().color(), 55));
01758         painter->drawPoint(option->rect.left() + 2, option->rect.bottom() - 1);
01759         painter->drawPoint(option->rect.left() + 1, option->rect.bottom() - 2);
01760         painter->drawPoint(option->rect.right() - 2, option->rect.bottom() - 1);
01761         painter->drawPoint(option->rect.right() - 1, option->rect.bottom() - 2);
01762 
01763 #ifdef QT3_SUPPORT
01764         if (widget && widget->inherits("Q3DockWindow")) {
01765             // also draw the frame on the title bar
01766             painter->drawPoint(option->rect.topLeft());
01767             painter->drawPoint(option->rect.topRight());
01768         }
01769 #endif
01770 
01771         // upper and lower left inner
01772         painter->setPen(active ? mergedColors(palette.highlight().color(), palette.background().color()) : palette.background().color().dark(120));
01773         painter->drawLine(option->rect.left() + 1, titleBarStop, option->rect.left() + 1, option->rect.bottom() - 2);
01774 
01775 #ifdef QT3_SUPPORT
01776         if (widget && widget->inherits("Q3DockWindow")) {
01777             // also draw the frame on the title bar
01778             painter->drawLine(option->rect.left() + 1, option->rect.top() + 1,
01779                               option->rect.left() + 1, titleBarStop);
01780             painter->drawLine(option->rect.right() - 1, option->rect.top() + 1,
01781                               option->rect.right() - 1, titleBarStop);
01782             painter->drawLine(option->rect.left() + 1, option->rect.top() + 1,
01783                               option->rect.right() - 1, option->rect.top() + 1);
01784         }
01785 #endif
01786 
01787         painter->setPen(active ? mergedColors(palette.highlight().color(), palette.background().color(), 57) : palette.background().color().dark(130));
01788         painter->drawLine(option->rect.right() - 1, titleBarStop, option->rect.right() - 1, option->rect.bottom() - 2);
01789         painter->drawLine(option->rect.left() + 1, option->rect.bottom() - 1, option->rect.right() - 1, option->rect.bottom() - 1);
01790 
01791         painter->restore();
01792     }
01793         break;
01794     case PE_IndicatorBranch: {
01795         int mid_h = option->rect.x() + option->rect.width() / 2;
01796         int mid_v = option->rect.y() + option->rect.height() / 2;
01797         int bef_h = mid_h;
01798         int bef_v = mid_v;
01799         int aft_h = mid_h;
01800         int aft_v = mid_v;
01801         QBrush brush(option->palette.dark().color(), Qt::Dense4Pattern);
01802         if (option->state & State_Item) {
01803             if (option->direction == Qt::RightToLeft)
01804                 painter->fillRect(option->rect.left(), mid_v, bef_h - option->rect.left(), 1, brush);
01805             else
01806                 painter->fillRect(aft_h, mid_v, option->rect.right() - aft_h + 1, 1, brush);
01807         }
01808         if (option->state & State_Sibling)
01809             painter->fillRect(mid_h, aft_v, 1, option->rect.bottom() - aft_v + 1, brush);
01810         if (option->state & (State_Open | State_Children | State_Item | State_Sibling))
01811             painter->fillRect(mid_h, option->rect.y(), 1, bef_v - option->rect.y(), brush);
01812 
01813         if (option->state & State_Children) {
01814             painter->save();
01815             QPoint center = option->rect.center();
01816             // border
01817             QRect fullRect(center.x() - 4, center.y() - 4, 9, 9);
01818             painter->setPen(borderColor);
01819             painter->drawLine(fullRect.left() + 1, fullRect.top(),
01820                               fullRect.right() - 1, fullRect.top());
01821             painter->drawLine(fullRect.left() + 1, fullRect.bottom(),
01822                               fullRect.right() - 1, fullRect.bottom());
01823             painter->drawLine(fullRect.left(), fullRect.top() + 1,
01824                               fullRect.left(), fullRect.bottom() - 1);
01825             painter->drawLine(fullRect.right(), fullRect.top() + 1,
01826                               fullRect.right(), fullRect.bottom() - 1);
01827             // "antialiased" corners
01828             painter->setPen(alphaCornerColor);
01829             painter->drawPoint(fullRect.topLeft());
01830             painter->drawPoint(fullRect.topRight());
01831             painter->drawPoint(fullRect.bottomLeft());
01832             painter->drawPoint(fullRect.bottomRight());
01833             // fill
01834             QRect adjustedRect = fullRect;
01835             QRect gradientRect(adjustedRect.left() + 1, adjustedRect.top() + 1,
01836                                adjustedRect.right() - adjustedRect.left() - 1,
01837                                adjustedRect.bottom() - adjustedRect.top() - 1);
01838             qt_plastique_draw_gradient(painter, gradientRect, baseGradientStartColor, baseGradientStopColor);
01839             // draw "+" or "-"
01840             painter->setPen(alphaTextColor);
01841             painter->drawLine(center.x() - 2, center.y(), center.x() + 2, center.y());
01842             if (!(option->state & State_Open))
01843                 painter->drawLine(center.x(), center.y() - 2, center.x(), center.y() + 2);
01844             painter->restore();
01845         }
01846     }
01847         break;
01848     default:
01849         QWindowsStyle::drawPrimitive(element, option, painter, widget);
01850         break;
01851     }
01852 }
01853 
01857 void QPlastiqueStyle::drawControl(ControlElement element, const QStyleOption *option,
01858                                   QPainter *painter, const QWidget *widget) const
01859 {
01860     Q_D(const QPlastiqueStyle);
01861     QColor borderColor = option->palette.background().color().dark(178);
01862     QColor alphaCornerColor;
01863     if (widget) {
01864         // ### backgroundrole/foregroundrole should be part of the style option
01865         alphaCornerColor = mergedColors(option->palette.color(widget->backgroundRole()), borderColor);
01866     } else {
01867         alphaCornerColor = mergedColors(option->palette.background().color(), borderColor);
01868     }
01869     QColor alphaTextColor = mergedColors(option->palette.background().color(), option->palette.text().color());
01870 
01871     QColor gradientStartColor = option->palette.button().color().light(104);
01872     QColor gradientStopColor = option->palette.button().color().dark(105);
01873 
01874     QColor shadowGradientStartColor = option->palette.button().color().dark(115);
01875     QColor shadowGradientStopColor = option->palette.button().color().dark(120);
01876 
01877     QColor highlightedGradientStartColor = option->palette.button().color().light(101);
01878     QColor highlightedGradientStopColor = mergedColors(option->palette.button().color(), option->palette.highlight().color(), 85);
01879 
01880     QColor lightShadowGradientStartColor = highlightedGradientStartColor.light(105);
01881     QColor lightShadowGradientStopColor = highlightedGradientStopColor.light(105);
01882 
01883     QColor highlightedDarkInnerBorderColor = mergedColors(option->palette.button().color(), option->palette.highlight().color(), 35);
01884     QColor highlightedLightInnerBorderColor = mergedColors(option->palette.button().color(), option->palette.highlight().color(), 58);
01885 
01886     QColor alphaInnerColor = mergedColors(highlightedDarkInnerBorderColor, option->palette.base().color());
01887     QColor lightShadow = lightShadowGradientStartColor;
01888     QColor shadow = shadowGradientStartColor;
01889 
01890     switch (element) {
01891 #ifndef QT_NO_TABBAR
01892     case CE_TabBarTabShape:
01893         if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(option)) {
01894 
01895             if (tab->shape != QTabBar::RoundedNorth && tab->shape != QTabBar::RoundedWest &&
01896                 tab->shape != QTabBar::RoundedSouth && tab->shape != QTabBar::RoundedEast) {
01897                 QWindowsStyle::drawControl(element, option, painter, widget);
01898                 break;
01899             }
01900 
01901             painter->save();
01902 
01903             // Set up some convenience variables
01904             bool disabled = !(tab->state & State_Enabled);
01905             bool onlyTab = tab->position == QStyleOptionTab::OnlyOneTab;
01906             bool selected = (tab->state & State_Selected) || onlyTab;
01907             bool mouseOver = (tab->state & State_MouseOver) && !selected && !disabled;
01908             bool previousSelected = tab->selectedPosition == QStyleOptionTab::PreviousIsSelected;
01909             bool nextSelected = tab->selectedPosition == QStyleOptionTab::NextIsSelected;
01910             bool leftCornerWidget = (tab->cornerWidgets & QStyleOptionTab::LeftCornerWidget);
01911             bool reverse = (tab->direction == Qt::RightToLeft);
01912 
01913             int lowerTop = selected ? 0 : 3; // to make the selected tab bigger than the rest
01914             QRect adjustedRect;
01915             bool atEnd = (tab->position == QStyleOptionTab::End) || onlyTab;
01916             bool atBeginning = ((tab->position == QStyleOptionTab::Beginning) || onlyTab)
01917                                && !leftCornerWidget;
01918             bool reverseShadow = false;
01919 
01920             int borderThickness = pixelMetric(PM_TabBarBaseOverlap, tab, widget);
01921             int marginLeft = 0;
01922             if ((atBeginning && !selected) || (selected && leftCornerWidget && ((tab->position == QStyleOptionTab::Beginning) || onlyTab))) {
01923                 marginLeft = 1;
01924             }
01925 
01926             // I've set the names based on the natural coordinate system. Vectors are used to rotate everything
01927             // if the orientation of the tab bare is different than north.
01928             {
01929                 // Coordinates of corners of rectangle for transformation
01930                 QPoint topLeft;
01931                 QPoint topRight;
01932                 QPoint bottomLeft;
01933                 QPoint bottomRight;
01934 
01935                 // Fill with normalized vectors in the direction of the coordinate system
01936                 // (down and right should be complement of up and left, or it will look odd)
01937                 QPoint vectorUp;
01938                 QPoint vectorDown;
01939                 QPoint vectorLeft;
01940                 QPoint vectorRight;
01941 
01942                 QBrush border = option->palette.shadow();
01943                 qBrushSetAlphaF(&border, 0.4);
01944                 QBrush innerTopLeft = option->palette.shadow();
01945                 qBrushSetAlphaF(&innerTopLeft, 0.075);
01946                 QBrush innerBottomRight = option->palette.shadow();
01947                 qBrushSetAlphaF(&innerBottomRight, 0.23);
01948                 QBrush corner = option->palette.shadow();
01949                 qBrushSetAlphaF(&corner, 0.25);
01950 
01951                 QBrush baseColor1;
01952                 QBrush baseColor2;
01953 
01954                 switch (tab->shape) {
01955                 case QTabBar::RoundedNorth:
01956                     vectorUp = QPoint(0, -1);
01957                     vectorDown = QPoint(0, 1);
01958 
01959                     if (reverse) {
01960                         vectorLeft = QPoint(1, 0);
01961                         vectorRight = QPoint(-1, 0);
01962                         reverseShadow = true;
01963                     } else {
01964                         vectorLeft = QPoint(-1, 0);
01965                         vectorRight = QPoint(1, 0);
01966                     }
01967 
01968                     if (reverse) {
01969                         topLeft = tab->rect.topRight();
01970                         topRight = tab->rect.topLeft();
01971                         bottomLeft = tab->rect.bottomRight();
01972                         bottomRight = tab->rect.bottomLeft();
01973                     } else {
01974                         topLeft = tab->rect.topLeft();
01975                         topRight = tab->rect.topRight();
01976                         bottomLeft = tab->rect.bottomLeft();
01977                         bottomRight = tab->rect.bottomRight();
01978                     }
01979 
01980 
01981                     baseColor1 = border;
01982                     baseColor2 = innerTopLeft;
01983                     break ;
01984                 case QTabBar::RoundedWest:
01985                     vectorUp = QPoint(-1, 0);
01986                     vectorDown = QPoint(1, 0);
01987                     vectorLeft = QPoint(0, -1);
01988                     vectorRight = QPoint(0, 1);
01989 
01990                     topLeft = tab->rect.topLeft();
01991                     topRight = tab->rect.bottomLeft();
01992                     bottomLeft = tab->rect.topRight();
01993                     bottomRight = tab->rect.bottomRight();
01994 
01995                     baseColor1 = border;
01996                     baseColor2 = innerTopLeft;
01997                     break ;
01998                 case QTabBar::RoundedEast:
01999                     vectorUp = QPoint(1, 0);
02000                     vectorDown = QPoint(-1, 0);
02001                     vectorLeft = QPoint(0, -1);
02002                     vectorRight = QPoint(0, 1);
02003 
02004                     topLeft = tab->rect.topRight();
02005                     topRight = tab->rect.bottomRight();
02006                     bottomLeft = tab->rect.topLeft();
02007                     bottomRight = tab->rect.bottomLeft();
02008 
02009                     baseColor1 = border;
02010                     baseColor2 = innerBottomRight;
02011                     break ;
02012                 case QTabBar::RoundedSouth:
02013                     vectorUp = QPoint(0, 1);
02014                     vectorDown = QPoint(0, -1);
02015 
02016                     if (reverse) {
02017                         vectorLeft = QPoint(1, 0);
02018                         vectorRight = QPoint(-1, 0);
02019                         reverseShadow = true;
02020 
02021                         topLeft = tab->rect.bottomRight();
02022                         topRight = tab->rect.bottomLeft();
02023                         bottomLeft = tab->rect.topRight();
02024                         bottomRight = tab->rect.topLeft();
02025                     } else {
02026                         vectorLeft = QPoint(-1, 0);
02027                         vectorRight = QPoint(1, 0);
02028 
02029                         topLeft = tab->rect.bottomLeft();
02030                         topRight = tab->rect.bottomRight();
02031                         bottomLeft = tab->rect.topLeft();
02032                         bottomRight = tab->rect.topRight();
02033                     }
02034 
02035                     baseColor1 = border;
02036                     baseColor2 = innerBottomRight;
02037                     break ;
02038                 default:
02039                     break;
02040                 }
02041 
02042                 // Make the tab smaller when it's at the end, so that we are able to draw the corner
02043                 if (atEnd) {
02044                     topRight += vectorLeft;
02045                     bottomRight += vectorLeft;
02046                 }
02047 
02048                 {
02049                     // Outer border
02050                     QLine topLine;
02051                     {
02052                         QPoint adjustTopLineLeft = (vectorRight * (marginLeft + (previousSelected ? 0 : 1))) +
02053                                                    (vectorDown * lowerTop);
02054                         QPoint adjustTopLineRight = (vectorDown * lowerTop);
02055                         if (atBeginning || selected)
02056                             adjustTopLineLeft += vectorRight;
02057                         if (atEnd || selected)
02058                             adjustTopLineRight += 2 * vectorLeft;
02059 
02060                         topLine = QLine(topLeft + adjustTopLineLeft, topRight + adjustTopLineRight);
02061                     }
02062 
02063                     QLine leftLine;
02064                     {
02065                         QPoint adjustLeftLineTop = (vectorRight * marginLeft) + (vectorDown * (lowerTop + 1));
02066                         QPoint adjustLeftLineBottom = (vectorRight * marginLeft) + (vectorUp * borderThickness);
02067                         if (atBeginning || selected)
02068                             adjustLeftLineTop += vectorDown; // Make place for rounded corner
02069                         if (atBeginning && selected)
02070                             adjustLeftLineBottom += borderThickness * vectorDown;
02071                         else if (selected)
02072                             adjustLeftLineBottom += vectorUp;
02073 
02074                         leftLine = QLine(topLeft + adjustLeftLineTop, bottomLeft + adjustLeftLineBottom);
02075                     }
02076 
02077                     QLine rightLine;
02078                     {
02079                         QPoint adjustRightLineTop = vectorDown * (2 + lowerTop);
02080                         QPoint adjustRightLineBottom = vectorUp * borderThickness;
02081                         if (selected)
02082                             adjustRightLineBottom += vectorUp;
02083 
02084                         rightLine = QLine(topRight + adjustRightLineTop, bottomRight + adjustRightLineBottom);
02085                     }
02086 
02087                     // Background
02088                     QPoint startPoint = topLine.p1() + vectorDown + vectorLeft;
02089                     if (mouseOver)
02090                         startPoint += vectorDown;
02091                     QPoint endPoint = rightLine.p2();
02092 
02093                     if (tab->state & State_Enabled) {
02094                         QRect fillRect = QRect(startPoint, endPoint).normalized();
02095                         if (fillRect.isValid()) {
02096                             if (selected) {
02097                                 fillRect = QRect(startPoint, endPoint + vectorLeft + vectorDown * 3).normalized();
02098                                 painter->fillRect(fillRect, option->palette.window());
02099 
02100                                 // Connect to the base
02101                                 painter->setPen(QPen(option->palette.window(), 0));
02102                                 painter->drawPoint(rightLine.p2() + vectorDown);
02103                                 painter->drawPoint(rightLine.p2() + vectorDown + vectorDown);
02104                                 painter->drawPoint(rightLine.p2() + vectorDown + vectorDown + vectorRight);
02105                                 if (tab->position != QStyleOptionTab::Beginning) {
02106                                     painter->drawPoint(leftLine.p2() + vectorDown);
02107                                     painter->drawPoint(leftLine.p2() + vectorDown + vectorDown);
02108                                     painter->drawPoint(leftLine.p2() + vectorDown + vectorDown + vectorLeft);
02109                                 }
02110                             } else {
02111                                 QBrush buttonGradientBrush;
02112                                 QBrush buttonBrush = qMapBrushToRect(option->palette.button(), fillRect);
02113                                 if (buttonBrush.gradient() || !buttonBrush.texture().isNull()) {
02114                                     buttonGradientBrush = buttonBrush;
02115                                 } else {
02116                                     // Generate gradients
02117                                     QLinearGradient buttonGradient(fillRect.topLeft(), fillRect.bottomLeft());
02118                                     buttonGradient.setColorAt(0.0, buttonBrush.color().light(104));
02119                                     buttonGradient.setColorAt(1.0, buttonBrush.color().dark(110));
02120                                     buttonGradientBrush = QBrush(buttonGradient);
02121                                 }
02122 
02123                                 painter->fillRect(fillRect, buttonGradientBrush);
02124                             }
02125                         }
02126                     }
02127 
02128                     QPoint rightCornerDot = topRight + vectorLeft + (lowerTop + 1)*vectorDown;
02129                     QPoint leftCornerDot = topLeft + (marginLeft + 1)*vectorRight + (lowerTop + 1)*vectorDown;
02130                     QPoint bottomRightConnectToBase = rightLine.p2() + vectorRight + vectorDown;
02131                     QPoint bottomLeftConnectToBase = leftLine.p2() + vectorLeft + vectorDown;
02132 
02133                     painter->setPen(QPen(border, 0));
02134                     painter->drawLine(topLine);
02135 
02136                     if (mouseOver) {
02137                         QLine secondHoverLine = QLine(topLine.p1() + vectorDown * 2 + vectorLeft, topLine.p2() + vectorDown * 2 + vectorRight);
02138                         painter->setPen(highlightedLightInnerBorderColor);
02139                         painter->drawLine(secondHoverLine);
02140                     }
02141 
02142                     if (mouseOver)
02143                         painter->setPen(QPen(border, 0));
02144                     if (!previousSelected)
02145                         painter->drawLine(leftLine);
02146                     if (atEnd || selected) {
02147                         painter->drawLine(rightLine);
02148                         painter->drawPoint(rightCornerDot);
02149                     }
02150                     if (atBeginning || selected)
02151                         painter->drawPoint(leftCornerDot);
02152                     if (selected) {
02153                         painter->drawPoint(bottomRightConnectToBase);
02154                         painter->drawPoint(bottomLeftConnectToBase);
02155                     }
02156 
02157                     // Antialiasing
02158                     painter->setPen(QPen(corner, 0));
02159                     if (atBeginning || selected)
02160                         painter->drawPoint(topLine.p1() + vectorLeft);
02161                     if (!previousSelected)
02162                         painter->drawPoint(leftLine.p1() + vectorUp);
02163                     if (atEnd || selected) {
02164                         painter->drawPoint(topLine.p2() + vectorRight);
02165                         painter->drawPoint(rightLine.p1() + vectorUp);
02166                     }
02167 
02168                     if (selected) {
02169                         painter->drawPoint(bottomRightConnectToBase + vectorLeft);
02170                         if (!atBeginning) {
02171                             painter->drawPoint(bottomLeftConnectToBase + vectorRight);
02172 
02173                             if (((tab->position == QStyleOptionTab::Beginning) || onlyTab) && leftCornerWidget) {
02174                                 // A special case: When the first tab is selected and
02175                                 // has a left corner widget, it needs to do more work
02176                                 // to connect to the base
02177                                 QPoint p1 = bottomLeftConnectToBase + vectorDown;
02178 
02179                                 painter->drawPoint(p1);
02180                             }
02181                         }
02182                     }
02183 
02184                     // Inner border
02185                     QLine innerTopLine = QLine(topLine.p1() + vectorDown, topLine.p2() + vectorDown);
02186                     if (!selected) {
02187                         QLinearGradient topLineGradient(innerTopLine.p1(),innerTopLine.p2());
02188                         topLineGradient.setColorAt(0, lightShadowGradientStartColor);
02189                         topLineGradient.setColorAt(1, lightShadowGradientStopColor);
02190                         painter->setPen(QPen(mouseOver ? QBrush(highlightedDarkInnerBorderColor) : QBrush(topLineGradient), 1));
02191                     } else {
02192                         painter->setPen(QPen(innerTopLeft, 0));
02193                     }
02194                     painter->drawLine(innerTopLine);
02195 
02196                     QLine innerLeftLine = QLine(leftLine.p1() + vectorRight + vectorDown, leftLine.p2() + vectorRight);
02197                     QLine innerRightLine = QLine(rightLine.p1() + vectorLeft + vectorDown, rightLine.p2() + vectorLeft);
02198 
02199                     if (selected) {
02200                         innerRightLine = QLine(innerRightLine.p1() + vectorUp, innerRightLine.p2());
02201                         innerLeftLine = QLine(innerLeftLine.p1() + vectorUp, innerLeftLine.p2());
02202                     }
02203 
02204                     if (selected || atBeginning) {
02205                         QBrush leftLineGradientBrush;
02206                         QRect rect = QRect(innerLeftLine.p1(), innerLeftLine.p2()).normalized();
02207                         QBrush buttonBrush = qMapBrushToRect(option->palette.button(), rect);
02208                         if (buttonBrush.gradient() || !buttonBrush.texture().isNull()) {
02209                             leftLineGradientBrush = qBrushLight(buttonBrush, 105);
02210                         } else {
02211                             QLinearGradient buttonGradient3(rect.topLeft(), rect.bottomLeft());
02212                             buttonGradient3.setColorAt(0.0, buttonBrush.color().light(105));
02213                             buttonGradient3.setColorAt(1.0, buttonBrush.color());
02214                             leftLineGradientBrush = QBrush(buttonGradient3);
02215                         }
02216 
02217                         if (!selected)
02218                             painter->setPen(QPen(leftLineGradientBrush, 0));
02219 
02220                         // Assume the sun is on the same side in Right-To-Left layouts and draw the
02221                         // light shadow on the left side always (the right line is on the left side in
02222                         // reverse layouts for north and south)
02223                         if (reverseShadow)
02224                             painter->drawLine(innerRightLine);
02225                         else
02226                             painter->drawLine(innerLeftLine);
02227                     }
02228 
02229                     if (atEnd || selected) {
02230                         if (!selected) {
02231                             QBrush rightLineGradientBrush;
02232                             QRect rect = QRect(innerRightLine.p1(), innerRightLine.p2()).normalized();
02233                             QBrush buttonBrush = qMapBrushToRect(option->palette.button(), rect);
02234                             if (buttonBrush.gradient() || !buttonBrush.texture().isNull()) {
02235                                 rightLineGradientBrush = qBrushDark(buttonBrush, 105);
02236                             } else {
02237                                 QLinearGradient buttonGradient4(rect.topLeft(), rect.bottomLeft());
02238                                 buttonGradient4.setColorAt(0.0, buttonBrush.color());
02239                                 buttonGradient4.setColorAt(1.0, buttonBrush.color().dark(110));
02240                                 rightLineGradientBrush = QBrush(buttonGradient4);
02241                             }
02242 
02243                             painter->setPen(QPen(rightLineGradientBrush, 0));
02244                         } else {
02245                             painter->setPen(QPen(innerBottomRight, 0));
02246                         }
02247 
02248                         if (reverseShadow)
02249                             painter->drawLine(innerLeftLine);
02250                         else
02251                             painter->drawLine(innerRightLine);
02252                     }
02253 
02254 
02255                     // Base
02256                     QLine baseLine = QLine(bottomLeft + marginLeft * 2 * vectorRight, bottomRight);
02257                     {
02258 
02259                         QPoint adjustedLeft;
02260                         QPoint adjustedRight;
02261 
02262                         if (atEnd && !selected) {
02263                             baseLine = QLine(baseLine.p1(), baseLine.p2() + vectorRight);
02264                         }
02265 
02266                         if (nextSelected) {
02267                             adjustedRight += vectorLeft;
02268                             baseLine = QLine(baseLine.p1(), baseLine.p2() + vectorLeft);
02269                         }
02270                         if (previousSelected) {
02271                             adjustedLeft += vectorRight;
02272                             baseLine = QLine(baseLine.p1() + vectorRight, baseLine.p2());
02273                         }
02274                         if (atBeginning)
02275                             adjustedLeft += vectorRight;
02276 
02277                         painter->setPen(QPen(baseColor2, 0));
02278                         if (!selected)
02279                             painter->drawLine(baseLine);
02280 
02281                         if (atEnd && !selected)
02282                             painter->drawPoint(baseLine.p2() + vectorRight);
02283 
02284                         if (atBeginning && !selected)
02285                             adjustedLeft = vectorRight;
02286                         else
02287                             adjustedLeft = QPoint(0, 0);
02288                         painter->setPen(QPen(baseColor1, 0));
02289                         if (!selected)
02290                             painter->drawLine(bottomLeft + vectorUp + adjustedLeft, baseLine.p2() + vectorUp);
02291 
02292                         QPoint endPoint = bottomRight + vectorUp;
02293                         if (atEnd && !selected)
02294                             painter->drawPoint(endPoint);
02295 
02296                         // For drawing a lower left "fake" corner on the base when the first tab is unselected
02297                         if (atBeginning && !selected) {
02298                             painter->drawPoint(baseLine.p1() + vectorLeft);
02299                         }
02300 
02301                         painter->setPen(QPen(corner, 0));
02302                         if (nextSelected)
02303                             painter->drawPoint(endPoint);
02304                         else if (selected)
02305                             painter->drawPoint(endPoint + vectorRight);
02306 
02307                         // For drawing a lower left "fake" corner on the base when the first tab is unselected
02308                         if (atBeginning && !selected) {
02309                             painter->drawPoint(baseLine.p1() + 2 * vectorLeft);
02310                         }
02311                     }
02312                 }
02313             }
02314 
02315             // Yay we're done
02316 
02317             painter->restore();
02318         }
02319         break;
02320 #endif // QT_NO_TABBAR
02321 #ifndef QT_NO_PROGRESSBAR
02322     case CE_ProgressBarGroove:
02323         if (const QStyleOptionProgressBar *bar = qstyleoption_cast<const QStyleOptionProgressBar *>(option)) {
02324             QRect rect = bar->rect;
02325             QPen oldPen = painter->pen();
02326 
02327             // outline
02328             painter->setPen(borderColor);
02329             painter->drawLine(rect.left() + 2, rect.top(), rect.right() - 2, rect.top());
02330             painter->drawLine(rect.left() + 2, rect.bottom(), rect.right() - 2, rect.bottom());
02331             painter->drawLine(rect.left(), rect.top() + 2, rect.left(), rect.bottom() - 2);
02332             painter->drawLine(rect.right(), rect.top() + 2, rect.right(), rect.bottom() - 2);
02333             painter->drawPoint(rect.left() + 1, rect.top() + 1);
02334             painter->drawPoint(rect.right() - 1, rect.top() + 1);
02335             painter->drawPoint(rect.left() + 1, rect.bottom() - 1);
02336             painter->drawPoint(rect.right() - 1, rect.bottom() - 1);
02337 
02338             // alpha corners
02339             painter->setPen(alphaCornerColor);
02340             painter->drawPoint(rect.left(), rect.top() + 1);
02341             painter->drawPoint(rect.left() + 1, rect.top());
02342             painter->drawPoint(rect.right(), rect.top() + 1);
02343             painter->drawPoint(rect.right() - 1, rect.top());
02344             painter->drawPoint(rect.left(), rect.bottom() - 1);
02345             painter->drawPoint(rect.left() + 1, rect.bottom());
02346             painter->drawPoint(rect.right(), rect.bottom() - 1);
02347             painter->drawPoint(rect.right() - 1, rect.bottom());
02348 
02349             // inner outline, north-west
02350             painter->setPen(gradientStartColor.dark(105));
02351             painter->drawLine(rect.left() + 2, rect.top() + 1, rect.right() - 2, rect.top() + 1);
02352             painter->drawLine(rect.left() + 1, rect.top() + 2, rect.left() + 1, rect.bottom() - 2);
02353 
02354             // base of the groove
02355             painter->setPen(QPen());
02356             painter->fillRect(rect.adjusted(2, 2, -2, -1), QBrush(bar->palette.base().color()));
02357             painter->setPen(bar->palette.base().color());
02358             painter->drawLine(rect.right() - 1, rect.top() + 2, rect.right() - 1, rect.bottom() - 2);
02359 
02360             painter->setPen(oldPen);
02361         }
02362         break;
02363     case CE_ProgressBarLabel:
02364         if (const QStyleOptionProgressBar *bar = qstyleoption_cast<const QStyleOptionProgressBar *>(option)) {
02365             // The busy indicator doesn't draw a label
02366             if (bar->minimum == 0 && bar->maximum == 0)
02367                 return;
02368 
02369             painter->save();
02370 
02371             QRect rect = bar->rect;
02372             QRect leftRect;
02373 
02374             QFont font;
02375             font.setBold(true);
02376             painter->setFont(font);
02377             painter->setPen(bar->palette.text().color());
02378 
02379             bool vertical = false;
02380             bool inverted = false;
02381             bool bottomToTop = false;
02382             // Get extra style options if version 2
02383             if (const QStyleOptionProgressBarV2 *bar2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option)) {
02384                 vertical = (bar2->orientation == Qt::Vertical);
02385                 inverted = bar2->invertedAppearance;
02386                 bottomToTop = bar2->bottomToTop;
02387             }
02388 
02389             if (vertical) {
02390                 rect = QRect(rect.left(), rect.top(), rect.height(), rect.width()); // flip width and height
02391                 QMatrix m;
02392                 if (bottomToTop) {
02393                     m.translate(0.0, rect.width());
02394                     m.rotate(-90);
02395                 } else {
02396                     m.translate(rect.height(), 0.0);
02397                     m.rotate(90);
02398                 }
02399                 painter->setMatrix(m);
02400             }
02401 
02402             int progressIndicatorPos = int(((bar->progress - bar->minimum) / double(bar->maximum - bar->minimum)) * rect.width());
02403 
02404             bool flip = (!vertical && (((bar->direction == Qt::RightToLeft) && !inverted)
02405                                        || ((bar->direction == Qt::LeftToRight) && inverted))) || (vertical && ((!inverted && !bottomToTop) || (inverted && bottomToTop)));
02406             if (flip) {
02407                 int indicatorPos = rect.width() - progressIndicatorPos;
02408                 if (indicatorPos >= 0 && indicatorPos <= rect.width()) {
02409                     painter->setPen(bar->palette.base().color());
02410                     leftRect = QRect(rect.left(), rect.top(), indicatorPos, rect.height());
02411                 } else if (indicatorPos > rect.width()) {
02412                     painter->setPen(bar->palette.text().color());
02413                 } else {
02414                     painter->setPen(bar->palette.base().color());
02415                 }
02416             } else {
02417                 if (progressIndicatorPos >= 0 && progressIndicatorPos <= rect.width()) {
02418                     leftRect = QRect(rect.left(), rect.top(), progressIndicatorPos, rect.height());
02419                 } else if (progressIndicatorPos > rect.width()) {
02420                     painter->setPen(bar->palette.base().color());
02421                 } else {
02422                     painter->setPen(bar->palette.text().color());
02423                 }
02424             }
02425 
02426             painter->drawText(rect, bar->text, QTextOption(Qt::AlignAbsolute | Qt::AlignHCenter | Qt::AlignVCenter));
02427             if (!leftRect.isNull()) {
02428                 painter->setPen(flip ? bar->palette.text().color() : bar->palette.base().color());
02429                 painter->setClipRect(leftRect, Qt::IntersectClip);
02430                 painter->drawText(rect, bar->text, QTextOption(Qt::AlignAbsolute | Qt::AlignHCenter | Qt::AlignVCenter));
02431             }
02432 
02433             painter->restore();
02434         }
02435         break;
02436     case CE_ProgressBarContents:
02437         if (const QStyleOptionProgressBar *bar = qstyleoption_cast<const QStyleOptionProgressBar *>(option)) {
02438             if (bar->progress == -1)
02439                 break;
02440 
02441             QRect rect = bar->rect;
02442             bool vertical = false;
02443             bool inverted = false;
02444             bool indeterminate = (bar->minimum == 0 && bar->maximum == 0);
02445             if (!indeterminate && bar->progress == -1)
02446                 break;
02447 
02448             painter->save();
02449 
02450             // Get extra style options if version 2
02451             if (const QStyleOptionProgressBarV2 *bar2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option)) {
02452                 vertical = (bar2->orientation == Qt::Vertical);
02453                 inverted = bar2->invertedAppearance;
02454             }
02455 
02456             // If the orientation is vertical, we use a transform to rotate
02457             // the progress bar 90 degrees clockwise.  This way we can use the
02458             // same rendering code for both orientations.
02459             if (vertical) {
02460                 rect = QRect(rect.left(), rect.top(), rect.height(), rect.width()); // flip width and height
02461                 QMatrix m;
02462                 m.translate(rect.height()-1, 0);
02463                 m.rotate(90.0);
02464                 painter->setMatrix(m);
02465             }
02466 
02467             int maxWidth = rect.width() - 4;
02468             int minWidth = 4;
02469             int progress = qMax(bar->progress, bar->minimum); // workaround for bug in QProgressBar
02470             int width = indeterminate ? maxWidth : qMax(int((((progress - bar->minimum))
02471                                                              / double(bar->maximum - bar->minimum)) * maxWidth), minWidth);
02472             bool reverse = (!vertical && (bar->direction == Qt::RightToLeft)) || vertical;
02473             if (inverted)
02474                 reverse = !reverse;
02475 
02476             QRect progressBar;
02477             if (!indeterminate) {
02478                 if (!reverse) {
02479                     progressBar.setRect(rect.left() + 2, rect.top() + 2, width, rect.height() - 4);
02480                 } else {
02481                     progressBar.setRect(rect.right() - 1 - width, rect.top() + 2, width, rect.height() - 4);
02482                 }
02483             } else {
02484                 int slideWidth = ((rect.width() - 4) * 2) / 3;
02485                 int step = ((d->animateStep * slideWidth) / ProgressBarFps) % slideWidth;
02486                 if ((((d->animateStep * slideWidth) / ProgressBarFps) % (2 * slideWidth)) >= slideWidth)
02487                     step = slideWidth - step;
02488                 progressBar.setRect(rect.left() + 2 + step, rect.top() + 2,
02489                                     slideWidth / 2, rect.height() - 4);
02490             }
02491 
02492             // outline
02493             painter->setPen(highlightedDarkInnerBorderColor);
02494             if (!reverse) {
02495                 if (width == minWidth) {
02496                     painter->drawPoint(progressBar.left() + 1, progressBar.top());
02497                     painter->drawPoint(progressBar.left() + 1, progressBar.bottom());
02498                 } else {
02499                     if (indeterminate) {
02500                         painter->drawLine(progressBar.left() + 2, progressBar.top(),
02501                                           progressBar.right() - 2, progressBar.top());
02502                         painter->drawLine(progressBar.left() + 2, progressBar.bottom(),
02503                                           progressBar.right() - 2, progressBar.bottom());
02504                     } else {
02505                         painter->drawLine(progressBar.left() + 1, progressBar.top(),
02506                                           progressBar.right() - 2, progressBar.top());
02507                         painter->drawLine(progressBar.left() + 1, progressBar.bottom(),
02508                                           progressBar.right() - 2, progressBar.bottom());
02509                     }
02510                 }
02511 
02512                 if (indeterminate) {
02513                     painter->drawLine(progressBar.left(), progressBar.top() + 2,
02514                                       progressBar.left(), progressBar.bottom() - 2);
02515                 } else {
02516                     painter->drawLine(progressBar.left(), progressBar.top() + 1,
02517                                       progressBar.left(), progressBar.bottom() - 1);
02518                 }
02519                 painter->drawLine(progressBar.right(), progressBar.top() + 2,
02520                                   progressBar.right(), progressBar.bottom() - 2);
02521             } else {
02522                 if (width == minWidth) {
02523                     painter->drawPoint(progressBar.right() - 1, progressBar.top());
02524                     painter->drawPoint(progressBar.right() - 1, progressBar.bottom());
02525                 } else {
02526                     if (indeterminate) {
02527                         painter->drawLine(progressBar.right() - 2, progressBar.top(),
02528                                           progressBar.left() + 2, progressBar.top());
02529                         painter->drawLine(progressBar.right() - 2, progressBar.bottom(),
02530                                           progressBar.left() + 2, progressBar.bottom());
02531                     } else {
02532                         painter->drawLine(progressBar.right() - 1, progressBar.top(),
02533                                           progressBar.left() + 2, progressBar.top());
02534                         painter->drawLine(progressBar.right() - 1, progressBar.bottom(),
02535                                           progressBar.left() + 2, progressBar.bottom());
02536                     }
02537                 }
02538                 if (indeterminate) {
02539                     painter->drawLine(progressBar.right(), progressBar.top() + 2,
02540                                       progressBar.right(), progressBar.bottom() - 2);
02541                 } else {
02542                     painter->drawLine(progressBar.right(), progressBar.top() + 1,
02543                                       progressBar.right(), progressBar.bottom() - 1);
02544                 }
02545                 painter->drawLine(progressBar.left(), progressBar.top() + 2,
02546                                   progressBar.left(), progressBar.bottom() - 2);
02547             }
02548 
02549             // alpha corners
02550             painter->setPen(alphaInnerColor);
02551             if (!reverse) {
02552                 if (indeterminate) {
02553                     painter->drawPoint(progressBar.left() + 1, progressBar.top());
02554                     painter->drawPoint(progressBar.left(), progressBar.top() + 1);
02555                     painter->drawPoint(progressBar.left() + 1, progressBar.bottom());
02556                     painter->drawPoint(progressBar.left(), progressBar.bottom() - 1);
02557                 } else {
02558                     painter->drawPoint(progressBar.left(), progressBar.top());
02559                     painter->drawPoint(progressBar.left(), progressBar.bottom());
02560                 }
02561                 painter->drawPoint(progressBar.right() - 1, progressBar.top());
02562                 painter->drawPoint(progressBar.right(), progressBar.top() + 1);
02563                 painter->drawPoint(progressBar.right() - 1, progressBar.bottom());
02564                 painter->drawPoint(progressBar.right(), progressBar.bottom() - 1);
02565             } else {
02566                 if (indeterminate) {
02567                     painter->drawPoint(progressBar.right() - 1, progressBar.top());
02568                     painter->drawPoint(progressBar.right(), progressBar.top() + 1);
02569                     painter->drawPoint(progressBar.right() - 1, progressBar.bottom());
02570                     painter->drawPoint(progressBar.right(), progressBar.bottom() - 1);
02571                 } else {
02572                     painter->drawPoint(progressBar.right(), progressBar.top());
02573                     painter->drawPoint(progressBar.right(), progressBar.bottom());
02574                 }
02575                 painter->drawPoint(progressBar.left() + 1, progressBar.top());
02576                 painter->drawPoint(progressBar.left(), progressBar.top() + 1);
02577                 painter->drawPoint(progressBar.left() + 1, progressBar.bottom());
02578                 painter->drawPoint(progressBar.left(), progressBar.bottom() - 1);
02579             }
02580 
02581             // contents
02582             painter->setPen(QPen());
02583 
02584             QString progressBarName = uniqueName(QLatin1String("progressBarContents"),
02585                                                  option, rect.size());
02586             QPixmap cache;
02587             if ((!UsePixmapCache || !QPixmapCache::find(progressBarName, cache)) && rect.height() > 7) {
02588                 QSize size = rect.size();
02589                 cache = QPixmap(QSize(size.width() - 6 + 30, size.height() - 6));
02590                 cache.fill(Qt::white);
02591                 QPainter cachePainter(&cache);
02592                 QRect pixmapRect(0, 0, cache.width(), cache.height());
02593 
02594                 int leftEdge = 0;
02595                 bool flip = false;
02596                 while (leftEdge < cache.width() + 1) {
02597                     QColor rectColor = option->palette.highlight().color();
02598                     QColor lineColor = option->palette.highlight().color();
02599                     if (flip) {
02600                         flip = false;
02601                         rectColor = rectColor.light(105);
02602                         lineColor = lineColor.light(105);
02603                     } else {
02604                         flip = true;
02605                     }
02606 
02607                     cachePainter.setPen(lineColor);
02608                     cachePainter.drawLine(pixmapRect.left() + leftEdge - 1, pixmapRect.top(),
02609                                           pixmapRect.left() + leftEdge + 9, pixmapRect.top());
02610                     cachePainter.drawLine(pixmapRect.left() + leftEdge - 1, pixmapRect.bottom(),
02611                                           pixmapRect.left() + leftEdge + 9, pixmapRect.bottom());
02612                     cachePainter.fillRect(QRect(pixmapRect.left() + leftEdge, pixmapRect.top(),
02613                                                 10, pixmapRect.height()), rectColor);
02614 
02615                     leftEdge += 10;
02616                 }
02617 
02618                 if (UsePixmapCache)
02619                     QPixmapCache::insert(progressBarName, cache);
02620             }
02621             painter->setClipRect(progressBar.adjusted(1, 0, -1, -1));
02622 
02623             if (!indeterminate) {
02624                 int step = (AnimateProgressBar || (indeterminate && AnimateBusyProgressBar)) ? (d->animateStep % 20) : 0;
02625                 if (!vertical)
02626                     progressBar.adjust(0, 1, 0, 1);
02627                 if (reverse)
02628                     painter->drawPixmap(progressBar.left() - 25 + step, progressBar.top(), cache);
02629                 else
02630                     painter->drawPixmap(progressBar.left() - 25 - step + width % 20, progressBar.top(), cache);
02631             } else {
02632                 painter->drawPixmap(progressBar.left(), progressBar.top(), cache);
02633             }
02634 
02635             painter->restore();
02636         }
02637         break;
02638 #endif // QT_NO_PROGRESSBAR
02639     case CE_HeaderSection:
02640         // Draws the header in tables.
02641         if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
02642             QPixmap cache;
02643             QString pixmapName = uniqueName("headersection", option, option->rect.size());
02644             pixmapName += QLatin1String("-") + QString::number(int(header->position));
02645             pixmapName += QLatin1String("-") + QString::number(int(header->orientation));
02646 
02647             if (!UsePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
02648                 cache = QPixmap(option->rect.size());
02649                 cache.fill(Qt::white);
02650                 QRect pixmapRect(0, 0, option->rect.width(), option->rect.height());
02651                 QPainter cachePainter(&cache);
02652 
02653                 bool sunken = (header->state & State_Enabled) && (header->state & State_Sunken);
02654 
02655                 QColor headerGradientStart = sunken ? option->palette.background().color().dark(114) : gradientStartColor;
02656                 QColor headerGradientStop = sunken ? option->palette.background().color().dark(106) : gradientStopColor;
02657 
02658                 QColor lightLine = sunken ? option->palette.background().color().dark(118) : gradientStartColor;
02659                 QColor darkLine = sunken ? option->palette.background().color().dark(110) : gradientStopColor.dark(105);
02660 
02661                 qt_plastique_draw_gradient(&cachePainter, pixmapRect,
02662                                            headerGradientStart, headerGradientStop);
02663 
02664                 cachePainter.setPen(borderColor);
02665                 cachePainter.drawRect(pixmapRect.adjusted(0, 0, -1, -1));
02666                 cachePainter.setPen(alphaCornerColor);
02667                 cachePainter.drawPoint(pixmapRect.topLeft());
02668                 cachePainter.drawPoint(pixmapRect.topRight());
02669                 cachePainter.drawPoint(pixmapRect.bottomLeft());
02670                 cachePainter.drawPoint(pixmapRect.bottomRight());
02671 
02672                 // inner lines
02673                 cachePainter.setPen(lightLine);
02674                 cachePainter.drawLine(pixmapRect.left() + 2, pixmapRect.top() + 1,
02675                                       pixmapRect.right() - 2, pixmapRect.top() + 1);
02676                 cachePainter.drawLine(pixmapRect.left() + 1, pixmapRect.top() + 2,
02677                                       pixmapRect.left() + 1, pixmapRect.bottom() - 2);
02678                 cachePainter.setPen(darkLine);
02679                 cachePainter.drawLine(pixmapRect.left() + 2, pixmapRect.bottom() - 1,
02680                                       pixmapRect.right() - 2, pixmapRect.bottom() - 1);
02681                 cachePainter.drawLine(pixmapRect.right() - 1, pixmapRect.bottom() - 2,
02682                                       pixmapRect.right() - 1, pixmapRect.top() + 2);
02683                 cachePainter.end();
02684                 if (UsePixmapCache)
02685                     QPixmapCache::insert(pixmapName, cache);
02686             }
02687             painter->drawPixmap(option->rect.topLeft(), cache);
02688 
02689         }
02690         break;
02691 #ifndef QT_NO_MENU
02692     case CE_MenuItem:
02693         // Draws one item in a popup menu.
02694         if (const QStyleOptionMenuItem *menuItem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
02695             painter->save();
02696 
02697             if (menuItem->menuItemType == QStyleOptionMenuItem::Separator) {
02698                 painter->fillRect(menuItem->rect, option->palette.background().color().light(103));
02699 
02700                 int w = 0;
02701                 if (!menuItem->text.isEmpty()) {
02702                     painter->setFont(menuItem->font);
02703                     drawItemText(painter, menuItem->rect.adjusted(5, 0, -5, 0), Qt::AlignLeft | Qt::AlignVCenter,
02704                                  menuItem->palette, menuItem->state & State_Enabled, menuItem->text,
02705                                  QPalette::Text);
02706                     w = menuItem->fontMetrics.width(menuItem->text) + 5;
02707                 }
02708 
02709                 painter->setPen(alphaCornerColor);
02710                 bool reverse = menuItem->direction == Qt::RightToLeft;
02711                 painter->drawLine(menuItem->rect.left() + 5 + (reverse ? 0 : w), menuItem->rect.center().y(),
02712                                   menuItem->rect.right() - 5 - (reverse ? w : 0), menuItem->rect.center().y());
02713 
02714                 painter->restore();
02715                 break;
02716             }
02717 
02718             bool selected = menuItem->state & State_Selected;
02719             bool checkable = menuItem->checkType != QStyleOptionMenuItem::NotCheckable;
02720             bool checked = menuItem->checked;
02721             bool enabled = menuItem->state & State_Enabled;
02722 
02723             if (selected && enabled) {
02724                 qt_plastique_draw_gradient(painter, menuItem->rect,
02725                                            option->palette.highlight().color().light(105),
02726                                            option->palette.highlight().color().dark(110));
02727 
02728                 painter->setPen(option->palette.highlight().color().light(110));
02729                 painter->drawLine(option->rect.topLeft(), option->rect.topRight());
02730                 painter->setPen(option->palette.highlight().color().dark(115));
02731                 painter->drawLine(option->rect.bottomLeft(), option->rect.bottomRight());
02732             } else {
02733                 painter->fillRect(option->rect, option->palette.background().color().light(103));
02734             }
02735 
02736             // Check
02737             QRect checkRect(option->rect.left() + 7, option->rect.center().y() - 6, 13, 13);
02738             checkRect = visualRect(menuItem->direction, menuItem->rect, checkRect);
02739             if (checkable) {
02740                 if ((menuItem->checkType & QStyleOptionMenuItem::Exclusive) && menuItem->icon.isNull()) {
02741                     QStyleOptionButton button;
02742                     button.rect = checkRect;
02743                     button.state = menuItem->state;
02744                     if (checked)
02745                         button.state |= State_On;
02746                     button.palette = menuItem->palette;
02747                     drawPrimitive(PE_IndicatorRadioButton, &button, painter, widget);
02748                 } else {
02749                     if (menuItem->icon.isNull()) {
02750                         QStyleOptionButton button;
02751                         button.rect = checkRect;
02752                         button.state = menuItem->state;
02753                         if (checked)
02754                             button.state |= State_On;
02755                         button.palette = menuItem->palette;
02756                         drawPrimitive(PE_IndicatorCheckBox, &button, painter, widget);
02757                     } else if (checked) {
02758                         int iconSize = qMax(menuItem->maxIconWidth, 20);
02759                         QRect sunkenRect(option->rect.left() + 1,
02760                                          option->rect.top() + (option->rect.height() - iconSize) / 2 + 1,
02761                                          iconSize, iconSize);
02762                         sunkenRect = visualRect(menuItem->direction, menuItem->rect, sunkenRect);
02763 
02764                         QStyleOption opt = *option;
02765                         opt.state |= State_Sunken;
02766                         opt.rect = sunkenRect;
02767                         qt_plastique_drawShadedPanel(painter, &opt, false, widget);
02768                     }
02769                 }
02770             }
02771 
02772             // Text and icon, ripped from windows style
02773             bool dis = !(menuItem->state & State_Enabled);
02774             bool act = menuItem->state & State_Selected;
02775             const QStyleOption *opt = option;
02776             const QStyleOptionMenuItem *menuitem = menuItem;
02777             int checkcol = qMax(menuitem->maxIconWidth, 20);
02778             QPainter *p = painter;
02779             QRect vCheckRect = visualRect(opt->direction, menuitem->rect,
02780                                           QRect(menuitem->rect.x(), menuitem->rect.y(),
02781                                                 checkcol, menuitem->rect.height()));
02782             if (!menuItem->icon.isNull()) {
02783                 QIcon::Mode mode = dis ? QIcon::Disabled : QIcon::Normal;
02784                 if (act && !dis)
02785                     mode = QIcon::Active;
02786                 QPixmap pixmap;
02787                 if (checked)
02788                     pixmap = menuItem->icon.pixmap(pixelMetric(PM_SmallIconSize), mode, QIcon::On);
02789                 else
02790                     pixmap = menuItem->icon.pixmap(pixelMetric(PM_SmallIconSize), mode);
02791                 int pixw = pixmap.width();
02792                 int pixh = pixmap.height();
02793 
02794                 QRect pmr(0, 0, pixw, pixh);
02795                 pmr.moveCenter(vCheckRect.center());
02796                 painter->setPen(menuItem->palette.text().color());
02797                 if (checkable && checked)
02798                     painter->drawPixmap(QPoint(pmr.left() + 1, pmr.top() + 1), pixmap);
02799                 else
02800                     painter->drawPixmap(pmr.topLeft(), pixmap);
02801             }
02802 
02803             if (selected) {
02804                 painter->setPen(menuItem->palette.highlightedText().color());
02805             } else {
02806                 painter->setPen(menuItem->palette.text().color());
02807             }
02808             int x, y, w, h;
02809             menuitem->rect.getRect(&x, &y, &w, &h);
02810             int tab = menuitem->tabWidth;
02811             QColor discol;
02812             if (dis) {
02813                 discol = menuitem->palette.text().color();
02814                 p->setPen(discol);
02815             }
02816             int xm = windowsItemFrame + checkcol + windowsItemHMargin;
02817             int xpos = menuitem->rect.x() + xm;
02818             QRect textRect(xpos, y + windowsItemVMargin, w - xm - windowsRightBorder - tab + 1, h - 2 * windowsItemVMargin);
02819             QRect vTextRect = visualRect(opt->direction, menuitem->rect, textRect);
02820             QString s = menuitem->text;
02821             if (!s.isEmpty()) {                     // draw text
02822                 p->save();
02823                 int t = s.indexOf(QLatin1Char('\t'));
02824                 int text_flags = Qt::AlignVCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
02825                 if (!styleHint(SH_UnderlineShortcut, menuitem, widget))
02826                     text_flags |= Qt::TextHideMnemonic;
02827                 text_flags |= Qt::AlignLeft;
02828                 if (t >= 0) {
02829                     QRect vShortcutRect = visualRect(opt->direction, menuitem->rect,
02830                         QRect(textRect.topRight(), QPoint(menuitem->rect.right(), textRect.bottom())));
02831                     if (dis && !act) {
02832                         p->setPen(menuitem->palette.light().color());
02833                         p->drawText(vShortcutRect.adjusted(1,1,1,1), text_flags, s.mid(t + 1));
02834                         p->setPen(discol);
02835                     }
02836                     p->drawText(vShortcutRect, text_flags, s.mid(t + 1));
02837                     s = s.left(t);
02838                 }
02839                 QFont font = menuitem->font;
02840                 if (menuitem->menuItemType == QStyleOptionMenuItem::DefaultItem)
02841                     font.setBold(true);
02842                 p->setFont(font);
02843                 if (dis && !act) {
02844                     p->setPen(menuitem->palette.light().color());
02845                     p->drawText(vTextRect.adjusted(1,1,1,1), text_flags, s.left(t));
02846                     p->setPen(discol);
02847                 }
02848                 p->drawText(vTextRect, text_flags, s.left(t));
02849                 p->restore();
02850             }
02851 
02852             // Arrow
02853             if (menuItem->menuItemType == QStyleOptionMenuItem::SubMenu) {// draw sub menu arrow
02854                 int dim = (menuItem->rect.height() - 4) / 2;
02855                 PrimitiveElement arrow;
02856                 arrow = (opt->direction == Qt::RightToLeft) ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight;
02857                 int xpos = menuItem->rect.left() + menuItem->rect.width() - 6 - 2 - dim;
02858                 QRect  vSubMenuRect = visualRect(option->direction, menuItem->rect,
02859                                                  QRect(xpos, menuItem->rect.top() + menuItem->rect.height() / 2 - dim / 2, dim, dim));
02860                 QStyleOptionMenuItem newMI = *menuItem;
02861                 newMI.rect = vSubMenuRect;
02862                 newMI.state = option->state & State_Enabled;
02863                 if (selected)
02864                     newMI.palette.setColor(QPalette::ButtonText,
02865                                            newMI.palette.highlightedText().color());
02866                 drawPrimitive(arrow, &newMI, painter, widget);
02867             }
02868 
02869             painter->restore();
02870         }
02871         break;
02872 #endif // QT_NO_MENU
02873 #ifndef QT_NO_MENUBAR
02874     case CE_MenuBarItem:
02875         // Draws a menu bar item; File, Edit, Help etc..
02876         if ((option->state & State_Selected) && (option->state & State_Enabled)) {
02877             QPixmap cache;
02878             QString pixmapName = uniqueName(QLatin1String("menubaritem"), option, option->rect.size());
02879             if (!UsePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
02880                 cache = QPixmap(option->rect.size());
02881                 cache.fill(Qt::white);
02882                 QRect pixmapRect(0, 0, option->rect.width(), option->rect.height());
02883                 QPainter cachePainter(&cache);
02884 
02885                 QRect rect = pixmapRect;
02886 
02887                 // gradient fill
02888                 if (option->state & QStyle::State_Enabled) {
02889                     if ((option->state & QStyle::State_Sunken) || (option->state & QStyle::State_On)) {
02890                         qt_plastique_draw_gradient(&cachePainter, rect.adjusted(1, 1, -1, -1),
02891                                                    option->palette.button().color().dark(114),
02892                                                    option->palette.button().color().dark(106));
02893                     } else {
02894                         qt_plastique_draw_gradient(&cachePainter, rect.adjusted(1, 1, -1, -1),
02895                                                    option->palette.background().color().light(105),
02896                                                    option->palette.background().color().dark(102));
02897                     }
02898                 }
02899 
02900                 // outer border and corners
02901                 cachePainter.setPen(borderColor);
02902                 cachePainter.drawRect(rect.adjusted(0, 0, -1, -1));
02903                 cachePainter.setPen(alphaCornerColor);
02904                 cachePainter.drawPoint(rect.topLeft());
02905                 cachePainter.drawPoint(rect.topRight());
02906                 cachePainter.drawPoint(rect.bottomLeft());
02907                 cachePainter.drawPoint(rect.bottomRight());
02908 
02909                 // inner border
02910                 if ((option->state & QStyle::State_Sunken) || (option->state & QStyle::State_On))
02911                     cachePainter.setPen(option->palette.button().color().dark(118));
02912                 else
02913                     cachePainter.setPen(gradientStartColor);
02914                 cachePainter.drawLine(rect.left() + 1, rect.top() + 1, rect.right() - 1, rect.top() + 1);
02915                 cachePainter.drawLine(rect.left() + 1, rect.top() + 2, rect.left() + 1, rect.bottom() - 2);
02916 
02917                 if ((option->state & QStyle::State_Sunken) || (option->state & QStyle::State_On))
02918                     cachePainter.setPen(option->palette.button().color().dark(114));
02919                 else
02920                     cachePainter.setPen(gradientStopColor.dark(102));
02921                 cachePainter.drawLine(rect.left() + 1, rect.bottom() - 1, rect.right() - 1, rect.bottom() - 1);
02922                 cachePainter.drawLine(rect.right() - 1, rect.top() + 1, rect.right() - 1, rect.bottom() - 2);
02923                 cachePainter.end();
02924                 if (UsePixmapCache)
02925                     QPixmapCache::insert(pixmapName, cache);
02926             }
02927             painter->drawPixmap(option->rect.topLeft(), cache);
02928         } else {
02929             painter->fillRect(option->rect, option->palette.background());
02930         }
02931         QCommonStyle::drawControl(element, option, painter, widget);
02932         break;
02933 #endif // QT_NO_MENUBAR
02934 #ifndef QT_NO_TOOLBOX
02935     case CE_ToolBoxTab:
02936         if (const QStyleOptionToolBox *toolBox = qstyleoption_cast<const QStyleOptionToolBox *>(option)) {
02937             painter->save();
02938 
02939             int width = toolBox->rect.width();
02940             int diag = toolBox->rect.height() - 2;
02941 
02942             // The essential points
02943             QPoint rightMost(toolBox->rect.right(), toolBox->rect.bottom() - 2);
02944             QPoint rightEdge(toolBox->rect.right() - width / 10, toolBox->rect.bottom() - 2);
02945             QPoint leftEdge(toolBox->rect.right() - width / 10 - diag, toolBox->rect.top());
02946             QPoint leftMost(toolBox->rect.left(), toolBox->rect.top());
02947             QPoint upOne(0, -1);
02948             QPoint downOne(0, 1);
02949             QPoint leftOne(-1, 0);
02950             QPoint rightOne(1, 0);
02951 
02952             // The upper path
02953             QPainterPath upperPath(rightMost + rightOne);
02954             upperPath.lineTo(rightEdge);
02955             upperPath.lineTo(leftEdge);
02956             upperPath.lineTo(leftMost + leftOne);
02957             upperPath.lineTo(toolBox->rect.topLeft() + leftOne + upOne);
02958             upperPath.lineTo(toolBox->rect.topRight() + rightOne + upOne);
02959             upperPath.lineTo(rightMost + rightOne);
02960 
02961             // The lower path
02962             QPainterPath lowerPath(rightMost + rightOne);
02963             lowerPath.lineTo(rightEdge);
02964             lowerPath.lineTo(leftEdge);
02965             lowerPath.lineTo(leftMost + leftOne);
02966             lowerPath.lineTo(toolBox->rect.bottomLeft() + leftOne + downOne);
02967             lowerPath.lineTo(toolBox->rect.bottomRight() + rightOne + downOne);
02968             lowerPath.lineTo(rightMost);
02969 
02970             //painter->fillRect(option->rect, toolBox->palette.base());
02971 
02972             // Fill the tab
02973             // if (toolBox->selectedPosition == QStyleOptionToolBox::PreviousIsSelected) {
02974             //    painter->fillPath(upperPath, toolBox->palette.base());
02975             //    painter->fillPath(lowerPath, toolBox->palette.background());
02976             // } else {
02977             //    painter->fillPath(upperPath, toolBox->palette.background());
02978             //    painter->fillPath(lowerPath, toolBox->palette.base());
02979             // }
02980 
02981             // Draw the outline
02982             painter->setPen(borderColor);
02983             painter->drawLine(rightMost, rightEdge);
02984             painter->drawLine(rightEdge + leftOne, leftEdge);
02985             painter->drawLine(leftEdge + leftOne, leftMost);
02986             painter->setPen(toolBox->palette.base().color());
02987             painter->drawLine(rightMost + downOne, rightEdge + downOne);
02988             painter->drawLine(rightEdge + leftOne + downOne, leftEdge + downOne);
02989             painter->drawLine(leftEdge + leftOne + downOne, leftMost + downOne);
02990 
02991             painter->restore();
02992         }
02993         break;
02994 #endif // QT_NO_TOOLBOX
02995 #ifndef QT_NO_SPLITTER
02996     case CE_Splitter:
02997         if ((option->state & State_Enabled) && (option->state & State_MouseOver))
02998             painter->fillRect(option->rect, QColor(255, 255, 255, 128));
02999         if (option->state & State_Horizontal) {
03000             int height = option->rect.height() / 3;
03001             QRect rect(option->rect.left() + (option->rect.width() / 2 - 1),
03002                        option->rect.center().y() - height / 2, 3, height);
03003             qt_plastique_draw_handle(painter, option, rect, Qt::Horizontal, widget);
03004         } else {
03005             int width = option->rect.width() / 3;
03006             QRect rect(option->rect.center().x() - width / 2,
03007                        option->rect.top() + (option->rect.height() / 2) - 1, width, 3);
03008             qt_plastique_draw_handle(painter, option, rect, Qt::Vertical, widget);
03009         }
03010         break;
03011 #endif // QT_NO_SPLITTER
03012 #ifndef QT_NO_DOCKWIDGET
03013     case CE_DockWidgetTitle:
03014         if (const QStyleOptionDockWidget *dockWidget = qstyleoption_cast<const QStyleOptionDockWidget *>(option)) {
03015             painter->save();
03016 
03017             // Find text width and title rect
03018             int textWidth = option->fontMetrics.width(dockWidget->title);
03019             int margin = 4;
03020             QRect titleRect = visualRect(dockWidget->direction, dockWidget->rect,
03021                                          dockWidget->rect.adjusted(margin, 0, -margin * 2 - 26, 0));
03022 
03023             // Chop and insert ellide into title if text is too wide
03024             QString title = elliditide(dockWidget->title, dockWidget->fontMetrics, titleRect, &textWidth);
03025 
03026             // Draw the toolbar handle pattern to the left and right of the text
03027             QImage handle(qt_toolbarhandle);
03028             handle.setColor(1, alphaCornerColor.rgba());
03029             handle.setColor(2, mergedColors(alphaCornerColor, option->palette.base().color()).rgba());
03030             handle.setColor(3, option->palette.base().color().rgba());
03031 
03032             if (title.isEmpty()) {
03033                 // Joint handle if there's no title
03034                 QRect r;
03035 #ifdef QT3_SUPPORT
03036                 // Q3DockWindow doesn't need space for buttons
03037                 if (widget && widget->inherits("Q3DockWindowTitleBar")) {
03038                     r = dockWidget->rect;
03039                 } else
03040 #endif
03041                     r.setRect(titleRect.left(), titleRect.top(), titleRect.width(), titleRect.bottom());
03042                 int nchunks = (r.width() / handle.width()) - 1;
03043                 int indent = (r.width() - (nchunks * handle.width())) / 2;
03044                 for (int i = 0; i < nchunks; ++i) {
03045                     painter->drawImage(QPoint(r.left() + indent + i * handle.width(),
03046                                               r.center().y() - handle.height() / 2),
03047                                        handle);
03048                 }
03049             } else {
03050                 // Handle pattern to the left of the title
03051                 QRect leftSide(titleRect.left(), titleRect.top(),
03052                                titleRect.