Fix sizeHint for QAbstractSpinBox

The current size hint is not correct and the text is truncated
when using prefix/suffix.

Update QCommonStyle::sizeFromContents() to get the button
and frame widths into account for the QSpinBox width.

Update sizeFromContents() in the different styles to be
consistent with the change in QCommonStyle.

Update minimumSizeHint(), calculate it using the prefix and
data range. The SpinBox can shrunk over the suffix if any.

Task-number: QTBUG-28863

Change-Id: Ia742232edf8b11d0283e8136c2818928f8755103
Reviewed-by: J-P Nurmi <jpnurmi@digia.com>
This commit is contained in:
Caroline Chao 2013-02-05 13:04:01 +01:00 committed by The Qt Project
parent 8f00f2020b
commit a317ee0a6f
7 changed files with 38 additions and 35 deletions

View File

@ -4808,6 +4808,16 @@ QSize QCommonStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt,
}
break;
#endif // QT_NO_ITEMVIEWS
#ifndef QT_NO_SPINBOX
case CT_SpinBox:
if (const QStyleOptionSpinBox *vopt = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
// Add button + frame widths
int buttonWidth = 20;
int fw = vopt->frame ? proxy()->pixelMetric(PM_SpinBoxFrameWidth, vopt, widget) : 0;
sz += QSize(buttonWidth + 2*fw, 2*fw);
}
break;
#endif
case CT_ScrollBar:
case CT_MenuBar:
case CT_Menu:

View File

@ -3910,7 +3910,7 @@ QSize QGtkStyle::sizeFromContents(ContentsType type, const QStyleOption *option,
break;
case CT_SpinBox:
// QSpinBox does some nasty things that depends on CT_LineEdit
newSize = size + QSize(0, -d->gtk_widget_get_style(d->gtkWidget("GtkSpinButton"))->ythickness * 2);
newSize = newSize + QSize(0, -d->gtk_widget_get_style(d->gtkWidget("GtkSpinButton"))->ythickness * 2);
break;
case CT_RadioButton:
case CT_CheckBox:

View File

@ -5985,10 +5985,11 @@ QSize QMacStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt,
switch (ct) {
case QStyle::CT_SpinBox:
// hack to work around horrible sizeHint() code in QAbstractSpinBox
// hack to work around horrible sizeHint() code in QAbstractSpinBox
sz = QCommonStyle::sizeFromContents(ct, opt, csz, widget);
sz.setHeight(sz.height() - 3);
break;
case QStyle::CT_TabWidget:
case QStyle::CT_TabWidget:
// the size between the pane and the "contentsRect" (+4,+4)
// (the "contentsRect" is on the inside of the pane)
sz = QCommonStyle::sizeFromContents(ct, opt, csz, widget);

View File

@ -2358,7 +2358,6 @@ QSize QWindowsStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt,
sz += QSize(QWindowsStylePrivate::windowsItemHMargin * 4, QWindowsStylePrivate::windowsItemVMargin * 2);
break;
#endif
// Otherwise, fall through
case CT_ToolButton:
if (qstyleoption_cast<const QStyleOptionToolButton *>(opt))
return sz += QSize(7, 6);

View File

@ -825,14 +825,13 @@ QSize QAbstractSpinBox::sizeHint() const
ensurePolished();
const QFontMetrics fm(fontMetrics());
int h = d->edit->sizeHint().height() + 4;
int h = d->edit->sizeHint().height();
int w = 0;
QString s;
s = d->prefix + d->textFromValue(d->minimum) + d->suffix + QLatin1Char(' ');
s.truncate(18);
QString fixedContent = d->prefix + d->suffix + QLatin1Char(' ');
s = d->textFromValue(d->minimum) + fixedContent;
w = qMax(w, fm.width(s));
s = d->prefix + d->textFromValue(d->maximum) + d->suffix + QLatin1Char(' ');
s.truncate(18);
s = d->textFromValue(d->maximum) + fixedContent;
w = qMax(w, fm.width(s));
if (d->specialValueText.size()) {
s = d->specialValueText;
@ -857,27 +856,29 @@ QSize QAbstractSpinBox::minimumSizeHint() const
{
Q_D(const QAbstractSpinBox);
if (d->cachedMinimumSizeHint.isEmpty()) {
//Use the prefix and range to calculate the minimumSizeHint
ensurePolished();
const QFontMetrics fm(fontMetrics());
int h = d->edit->minimumSizeHint().height();
int w = fm.width(QLatin1String("1000"));
int w = 0;
QString s;
QString fixedContent = d->prefix + QLatin1Char(' ');
s = d->textFromValue(d->minimum) + fixedContent;
w = qMax(w, fm.width(s));
s = d->textFromValue(d->maximum) + fixedContent;
w = qMax(w, fm.width(s));
if (d->specialValueText.size()) {
s = d->specialValueText;
w = qMax(w, fm.width(s));
}
w += 2; // cursor blinking space
QStyleOptionSpinBox opt;
initStyleOption(&opt);
QSize hint(w, h);
QSize extra(35, 6);
opt.rect.setSize(hint + extra);
extra += hint - style()->subControlRect(QStyle::CC_SpinBox, &opt,
QStyle::SC_SpinBoxEditField, this).size();
// get closer to final result by repeating the calculation
opt.rect.setSize(hint + extra);
extra += hint - style()->subControlRect(QStyle::CC_SpinBox, &opt,
QStyle::SC_SpinBoxEditField, this).size();
hint += extra;
opt.rect = rect();
d->cachedMinimumSizeHint = style()->sizeFromContents(QStyle::CT_SpinBox, &opt, hint, this)
.expandedTo(QApplication::globalStrut());
@ -1724,7 +1725,8 @@ void QAbstractSpinBoxPrivate::setRange(const QVariant &min, const QVariant &max)
clearCache();
minimum = min;
maximum = (variantCompare(min, max) < 0 ? max : min);
cachedSizeHint = QSize(); // minimumSizeHint doesn't care about min/max
cachedSizeHint = QSize();
cachedMinimumSizeHint = QSize(); // minimumSizeHint cares about min/max
reset();
if (!(bound(value) == value)) {

View File

@ -981,9 +981,9 @@ QSize QDateTimeEdit::sizeHint() const
int h = d->edit->sizeHint().height();
int w = 0;
QString s;
s = d->textFromValue(d->minimum) + QLatin1String(" ");
s = d->textFromValue(d->minimum) + QLatin1Char(' ');
w = qMax<int>(w, fm.width(s));
s = d->textFromValue(d->maximum) + QLatin1String(" ");
s = d->textFromValue(d->maximum) + QLatin1Char(' ');
w = qMax<int>(w, fm.width(s));
if (d->specialValueText.size()) {
s = d->specialValueText;
@ -1000,19 +1000,8 @@ QSize QDateTimeEdit::sizeHint() const
} else
#endif
{
QSize extra(35, 6);
QStyleOptionSpinBox opt;
initStyleOption(&opt);
opt.rect.setSize(hint + extra);
extra += hint - style()->subControlRect(QStyle::CC_SpinBox, &opt,
QStyle::SC_SpinBoxEditField, this).size();
// get closer to final result by repeating the calculation
opt.rect.setSize(hint + extra);
extra += hint - style()->subControlRect(QStyle::CC_SpinBox, &opt,
QStyle::SC_SpinBoxEditField, this).size();
hint += extra;
opt.rect = rect();
d->cachedSizeHint = style()->sizeFromContents(QStyle::CT_SpinBox, &opt, hint, this)
.expandedTo(QApplication::globalStrut());
}
@ -1023,6 +1012,7 @@ QSize QDateTimeEdit::sizeHint() const
return d->cachedSizeHint;
}
/*!
\reimp
*/

View File

@ -268,6 +268,7 @@ void QSpinBox::setPrefix(const QString &prefix)
d->updateEdit();
d->cachedSizeHint = QSize();
d->cachedMinimumSizeHint = QSize(); // minimumSizeHint cares about the prefix
updateGeometry();
}