summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCarlos Manuel Duclos Vergara <carlos.duclos@nokia.com>2010-01-25 15:10:21 (GMT)
committerJason McDonald <jason.mcdonald@nokia.com>2010-01-29 11:22:57 (GMT)
commit95a4f3a8ab58d7b85b8b957065a07c549b090450 (patch)
tree907ccbe2516b80dc2c4b9873ab82de716849427e
parent24e76d093905ae0ce996bda38546265ab587bc4e (diff)
downloadQt-95a4f3a8ab58d7b85b8b957065a07c549b090450.zip
Qt-95a4f3a8ab58d7b85b8b957065a07c549b090450.tar.gz
Qt-95a4f3a8ab58d7b85b8b957065a07c549b090450.tar.bz2
Drawing fake buttons using QMacStyle+QStyleOptionViewItemV4 lead to crash.
The problem here is the fact that we "trusted" the user when the widget type was specified. The fix consists in checking the result of the conversions, if the conversion was successful (i.e. the widget was of the type specified by the user) then we proceed as usual. If the conversion was not successful (i.e. wrong widget type) then we ask the style for a sensible size. I modified this for QPushButton, QSlider and QToolButton. Task-number: qtbug-7522 Reviewed-by: jbache (cherry picked from commit f92e9c32160ca32b93173dafad2734963528446d)
-rw-r--r--src/gui/styles/qmacstyle_mac.mm176
1 files changed, 104 insertions, 72 deletions
diff --git a/src/gui/styles/qmacstyle_mac.mm b/src/gui/styles/qmacstyle_mac.mm
index 97d69b2..f4af579 100644
--- a/src/gui/styles/qmacstyle_mac.mm
+++ b/src/gui/styles/qmacstyle_mac.mm
@@ -667,32 +667,47 @@ static QSize qt_aqua_get_known_size(QStyle::ContentsType ct, const QWidget *widg
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 @@ static QSize qt_aqua_get_known_size(QStyle::ContentsType ct, const QWidget *widg
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 @@ static QSize qt_aqua_get_known_size(QStyle::ContentsType ct, const QWidget *widg
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);
- }
- } 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);
+ 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 {
+ // 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);