src/gui/styles/qmacstyle_mac.mm
changeset 18 2f34d5167611
parent 3 41300fa6a67c
child 30 5dc02b23752f
--- a/src/gui/styles/qmacstyle_mac.mm	Tue Feb 02 00:43:10 2010 +0200
+++ b/src/gui/styles/qmacstyle_mac.mm	Fri Apr 16 15:50:13 2010 +0300
@@ -1,6 +1,6 @@
 /****************************************************************************
 **
-** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
 ** All rights reserved.
 ** Contact: Nokia Corporation (qt-info@nokia.com)
 **
@@ -667,32 +667,47 @@
 
     switch (ct) {
     case QStyle::CT_PushButton: {
-        const QPushButton *psh = static_cast<const QPushButton *>(widg);
-        QString buttonText = qt_mac_removeMnemonics(psh->text());
-        if (buttonText.contains(QLatin1Char('\n')))
-            ret = QSize(-1, -1);
-        else if (sz == QAquaSizeLarge)
-            ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricPushButtonHeight));
-        else if (sz == QAquaSizeSmall)
-            ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricSmallPushButtonHeight));
-        else if (sz == QAquaSizeMini)
-            ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricMiniPushButtonHeight));
-
-        if (!psh->icon().isNull()){
-            // If the button got an icon, and the icon is larger than the
-            // button, we can't decide on a default size
-            ret.setWidth(-1);
-            if (ret.height() < psh->iconSize().height())
-                ret.setHeight(-1);
-        }
-        else if (buttonText == QLatin1String("OK") || buttonText == QLatin1String("Cancel")){
-            // Aqua Style guidelines restrict the size of OK and Cancel buttons to 68 pixels.
-            // However, this doesn't work for German, therefore only do it for English,
-            // I suppose it would be better to do some sort of lookups for languages
-            // that like to have really long words.
-            ret.setWidth(77 - 8);
-        }
-
+        const QPushButton *psh = qobject_cast<const QPushButton *>(widg);
+        // If this comparison is false, then the widget was not a push button.
+        // This is bad and there's very little we can do since we were requested to find a
+        // sensible size for a widget that pretends to be a QPushButton but is not.
+        if(psh) {
+            QString buttonText = qt_mac_removeMnemonics(psh->text());
+            if (buttonText.contains(QLatin1Char('\n')))
+                ret = QSize(-1, -1);
+            else if (sz == QAquaSizeLarge)
+                ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricPushButtonHeight));
+            else if (sz == QAquaSizeSmall)
+                ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricSmallPushButtonHeight));
+            else if (sz == QAquaSizeMini)
+                ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricMiniPushButtonHeight));
+
+            if (!psh->icon().isNull()){
+                // If the button got an icon, and the icon is larger than the
+                // button, we can't decide on a default size
+                ret.setWidth(-1);
+                if (ret.height() < psh->iconSize().height())
+                    ret.setHeight(-1);
+            }
+            else if (buttonText == QLatin1String("OK") || buttonText == QLatin1String("Cancel")){
+                // Aqua Style guidelines restrict the size of OK and Cancel buttons to 68 pixels.
+                // However, this doesn't work for German, therefore only do it for English,
+                // I suppose it would be better to do some sort of lookups for languages
+                // that like to have really long words.
+                ret.setWidth(77 - 8);
+            }
+        } else {
+            // The only sensible thing to do is to return whatever the style suggests...
+            if (sz == QAquaSizeLarge)
+                ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricPushButtonHeight));
+            else if (sz == QAquaSizeSmall)
+                ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricSmallPushButtonHeight));
+            else if (sz == QAquaSizeMini)
+                ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricMiniPushButtonHeight));
+            else
+                // Since there's no default size we return the large size...
+                ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricPushButtonHeight));
+         }
 #if 0 //Not sure we are applying the rules correctly for RadioButtons/CheckBoxes --Sam
     } else if (ct == QStyle::CT_RadioButton) {
         QRadioButton *rdo = static_cast<QRadioButton *>(widg);
@@ -749,23 +764,30 @@
         if (sz == QAquaSizeSmall) {
             int width = 0, height = 0;
             if (szHint == QSize(-1, -1)) { //just 'guess'..
-                const QToolButton *bt = static_cast<const QToolButton *>(widg);
-                if (!bt->icon().isNull()) {
-                    QSize iconSize = bt->iconSize();
-                    QSize pmSize = bt->icon().actualSize(QSize(32, 32), QIcon::Normal);
-                    width = qMax(width, qMax(iconSize.width(), pmSize.width()));
-                    height = qMax(height, qMax(iconSize.height(), pmSize.height()));
-                }
-                if (!bt->text().isNull() && bt->toolButtonStyle() != Qt::ToolButtonIconOnly) {
-                    int text_width = bt->fontMetrics().width(bt->text()),
-                       text_height = bt->fontMetrics().height();
-                    if (bt->toolButtonStyle() == Qt::ToolButtonTextUnderIcon) {
-                        width = qMax(width, text_width);
-                        height += text_height;
-                    } else {
-                        width += text_width;
-                        width = qMax(height, text_height);
+                const QToolButton *bt = qobject_cast<const QToolButton *>(widg);
+                // If this conversion fails then the widget was not what it claimed to be.
+                if(bt) {
+                    if (!bt->icon().isNull()) {
+                        QSize iconSize = bt->iconSize();
+                        QSize pmSize = bt->icon().actualSize(QSize(32, 32), QIcon::Normal);
+                        width = qMax(width, qMax(iconSize.width(), pmSize.width()));
+                        height = qMax(height, qMax(iconSize.height(), pmSize.height()));
                     }
+                    if (!bt->text().isNull() && bt->toolButtonStyle() != Qt::ToolButtonIconOnly) {
+                        int text_width = bt->fontMetrics().width(bt->text()),
+                           text_height = bt->fontMetrics().height();
+                        if (bt->toolButtonStyle() == Qt::ToolButtonTextUnderIcon) {
+                            width = qMax(width, text_width);
+                            height += text_height;
+                        } else {
+                            width += text_width;
+                            width = qMax(height, text_height);
+                        }
+                    }
+                } else {
+                    // Let's return the size hint...
+                    width = szHint.width();
+                    height = szHint.height();
                 }
             } else {
                 width = szHint.width();
@@ -778,37 +800,47 @@
         break;
     case QStyle::CT_Slider: {
         int w = -1;
-        const QSlider *sld = static_cast<const QSlider *>(widg);
-        if (sz == QAquaSizeLarge) {
-            if (sld->orientation() == Qt::Horizontal) {
-                w = qt_mac_aqua_get_metric(kThemeMetricHSliderHeight);
-                if (sld->tickPosition() != QSlider::NoTicks)
-                    w += qt_mac_aqua_get_metric(kThemeMetricHSliderTickHeight);
-            } else {
-                w = qt_mac_aqua_get_metric(kThemeMetricVSliderWidth);
-                if (sld->tickPosition() != QSlider::NoTicks)
-                    w += qt_mac_aqua_get_metric(kThemeMetricVSliderTickWidth);
+        const QSlider *sld = qobject_cast<const QSlider *>(widg);
+        // If this conversion fails then the widget was not what it claimed to be.
+        if(sld) {
+            if (sz == QAquaSizeLarge) {
+                if (sld->orientation() == Qt::Horizontal) {
+                    w = qt_mac_aqua_get_metric(kThemeMetricHSliderHeight);
+                    if (sld->tickPosition() != QSlider::NoTicks)
+                        w += qt_mac_aqua_get_metric(kThemeMetricHSliderTickHeight);
+                } else {
+                    w = qt_mac_aqua_get_metric(kThemeMetricVSliderWidth);
+                    if (sld->tickPosition() != QSlider::NoTicks)
+                        w += qt_mac_aqua_get_metric(kThemeMetricVSliderTickWidth);
+                }
+            } else if (sz == QAquaSizeSmall) {
+                if (sld->orientation() == Qt::Horizontal) {
+                    w = qt_mac_aqua_get_metric(kThemeMetricSmallHSliderHeight);
+                    if (sld->tickPosition() != QSlider::NoTicks)
+                        w += qt_mac_aqua_get_metric(kThemeMetricSmallHSliderTickHeight);
+                } else {
+                    w = qt_mac_aqua_get_metric(kThemeMetricSmallVSliderWidth);
+                    if (sld->tickPosition() != QSlider::NoTicks)
+                        w += qt_mac_aqua_get_metric(kThemeMetricSmallVSliderTickWidth);
+                }
+            } else if (sz == QAquaSizeMini) {
+                if (sld->orientation() == Qt::Horizontal) {
+                    w = qt_mac_aqua_get_metric(kThemeMetricMiniHSliderHeight);
+                    if (sld->tickPosition() != QSlider::NoTicks)
+                        w += qt_mac_aqua_get_metric(kThemeMetricMiniHSliderTickHeight);
+                } else {
+                    w = qt_mac_aqua_get_metric(kThemeMetricMiniVSliderWidth);
+                    if (sld->tickPosition() != QSlider::NoTicks)
+                        w += qt_mac_aqua_get_metric(kThemeMetricMiniVSliderTickWidth);
+                }
             }
-        } else if (sz == QAquaSizeSmall) {
-            if (sld->orientation() == Qt::Horizontal) {
-                w = qt_mac_aqua_get_metric(kThemeMetricSmallHSliderHeight);
-                if (sld->tickPosition() != QSlider::NoTicks)
-                    w += qt_mac_aqua_get_metric(kThemeMetricSmallHSliderTickHeight);
-            } else {
-                w = qt_mac_aqua_get_metric(kThemeMetricSmallVSliderWidth);
-                if (sld->tickPosition() != QSlider::NoTicks)
-                    w += qt_mac_aqua_get_metric(kThemeMetricSmallVSliderTickWidth);
-            }
-        } else if (sz == QAquaSizeMini) {
-            if (sld->orientation() == Qt::Horizontal) {
-                w = qt_mac_aqua_get_metric(kThemeMetricMiniHSliderHeight);
-                if (sld->tickPosition() != QSlider::NoTicks)
-                    w += qt_mac_aqua_get_metric(kThemeMetricMiniHSliderTickHeight);
-            } else {
-                w = qt_mac_aqua_get_metric(kThemeMetricMiniVSliderWidth);
-                if (sld->tickPosition() != QSlider::NoTicks)
-                    w += qt_mac_aqua_get_metric(kThemeMetricMiniVSliderTickWidth);
-            }
+        } else {
+            // This is tricky, we were requested to find a size for a slider which is not
+            // a slider. We don't know if this is vertical or horizontal or if we need to
+            // have tick marks or not.
+            // For this case we will return an horizontal slider without tick marks.
+            w = qt_mac_aqua_get_metric(kThemeMetricHSliderHeight);
+            w += qt_mac_aqua_get_metric(kThemeMetricHSliderTickHeight);
         }
         if (sld->orientation() == Qt::Horizontal)
             ret.setHeight(w);
@@ -2379,7 +2411,12 @@
         ret = 0;
         break;
     case PM_ToolBarFrameWidth:
-        ret = 0;
+        ret = 1;
+        if (widget) {
+            if (QMainWindow * mainWindow = qobject_cast<QMainWindow *>(widget->parent()))
+                if (mainWindow->unifiedTitleAndToolBarOnMac())
+                    ret = 0;
+        }
         break;
     default:
         ret = QWindowsStyle::pixelMetric(metric, opt, widget);
@@ -3343,8 +3380,14 @@
                         if (tb->toolButtonStyle != Qt::ToolButtonIconOnly) {
                             needText = true;
                             if (tb->toolButtonStyle == Qt::ToolButtonTextUnderIcon) {
-                                pr.setHeight(pixmap.size().height());
-                                cr.adjust(0, pr.bottom() + 1, 0, 1);
+                                QMainWindow *mw = qobject_cast<QMainWindow *>(w->window());
+                                if (mw && mw->unifiedTitleAndToolBarOnMac()) {
+                                    pr.setHeight(pixmap.size().height());
+                                    cr.adjust(0, pr.bottom() + 1, 0, 1);
+                                } else {
+                                    pr.setHeight(pixmap.size().height() + 6);
+                                    cr.adjust(0, pr.bottom(), 0, -3);
+                                }       
                                 alignment |= Qt::AlignCenter;
                             } else {
                                 pr.setWidth(pixmap.width() + 8);
@@ -3706,7 +3749,7 @@
                     QPalette np = tab->palette;
                     np.setColor(QPalette::WindowText, QColor(255, 255, 255, 75));
                     QRect nr = subElementRect(SE_TabBarTabText, opt, w);
-                    nr.moveTop(+1);
+                    nr.moveTop(-1);
                     int alignment = Qt::AlignCenter | Qt::TextShowMnemonic | Qt::TextHideMnemonic;
                     proxy()->drawItemText(p, nr, alignment, np, tab->state & State_Enabled,
                                                tab->text, QPalette::WindowText);
@@ -3996,7 +4039,7 @@
                 // This is mainly to handle cases where someone sets the font on the window
                 // and then the combo inherits it and passes it onward. At that point the resolve mask
                 // is very, very weak. This makes it stonger.
-                myFont.setPointSizeF(mi->font.pointSizeF());
+                myFont.setPointSizeF(QFontInfo(mi->font).pointSizeF());
                 p->setFont(myFont);
                 p->drawText(xpos, yPos, contentRect.width() - xm - tabwidth + 1,
                             contentRect.height(), text_flags ^ Qt::AlignRight, s);
@@ -4309,8 +4352,6 @@
                 rect.setY(0);
                 rect.setHeight(widget->height());
             }
-            if (opt->direction == Qt::RightToLeft)
-                rect.adjust(15, 0, -20, 0);
         }
         break;
     case SE_ProgressBarGroove:
@@ -5685,12 +5726,16 @@
         break;
     case CT_ToolButton:
         if (widget && qobject_cast<const QToolBar *>(widget->parentWidget())) {
-            sz.rwidth() += 4;
-            if (sz.height() <= 32) {
-                // Workaround strange HIToolBar bug when getting constraints.
-                sz.rheight() += 1;
+            if (QMainWindow * mainWindow = qobject_cast<QMainWindow *>(widget->parent())) {
+                if (mainWindow->unifiedTitleAndToolBarOnMac()) {
+                    sz.rwidth() += 4;
+                    if (sz.height() <= 32) {
+                        // Workaround strange HIToolBar bug when getting constraints.
+                        sz.rheight() += 1;
+                    }
+                    return sz;
+                }
             }
-            return sz;
         }
         sz.rwidth() += 10;
         sz.rheight() += 10;