diff --git a/src/widgets/widgets/qprogressbar.cpp b/src/widgets/widgets/qprogressbar.cpp index 72e937b604..6b3dadddf0 100644 --- a/src/widgets/widgets/qprogressbar.cpp +++ b/src/widgets/widgets/qprogressbar.cpp @@ -41,6 +41,7 @@ #include "qprogressbar.h" #ifndef QT_NO_PROGRESSBAR +#include #include #include #include @@ -61,6 +62,7 @@ public: QProgressBarPrivate(); void init(); + void initDefaultFormat(); inline void resetLayoutItemMargins(); int minimum; @@ -68,6 +70,7 @@ public: int value; Qt::Alignment alignment; uint textVisible : 1; + uint defaultFormat: 1; int lastPaintedValue; Qt::Orientation orientation; bool invertedAppearance; @@ -79,9 +82,16 @@ public: QProgressBarPrivate::QProgressBarPrivate() : minimum(0), maximum(100), value(-1), alignment(Qt::AlignLeft), textVisible(true), - lastPaintedValue(-1), orientation(Qt::Horizontal), invertedAppearance(false), - textDirection(QProgressBar::TopToBottom), format(QLatin1String("%p%")) + defaultFormat(true), lastPaintedValue(-1), orientation(Qt::Horizontal), invertedAppearance(false), + textDirection(QProgressBar::TopToBottom) { + initDefaultFormat(); +} + +void QProgressBarPrivate::initDefaultFormat() +{ + if (defaultFormat) + format = QLatin1String("%p") + locale.percent(); } void QProgressBarPrivate::init() @@ -466,19 +476,21 @@ QString QProgressBar::text() const qint64 totalSteps = qint64(d->maximum) - d->minimum; QString result = d->format; - result.replace(QLatin1String("%m"), QString::number(totalSteps)); - result.replace(QLatin1String("%v"), QString::number(d->value)); + QLocale locale = d->locale; // Omit group separators for compatibility with previous versions that were non-localized. + locale.setNumberOptions(locale.numberOptions() | QLocale::OmitGroupSeparator); + result.replace(QLatin1String("%m"), locale.toString(totalSteps)); + result.replace(QLatin1String("%v"), locale.toString(d->value)); // If max and min are equal and we get this far, it means that the // progress bar has one step and that we are on that step. Return // 100% here in order to avoid division by zero further down. if (totalSteps == 0) { - result.replace(QLatin1String("%p"), QString::number(100)); + result.replace(QLatin1String("%p"), locale.toString(int(100))); return result; } int progress = (qreal(d->value) - d->minimum) * 100.0 / totalSteps; - result.replace(QLatin1String("%p"), QString::number(progress)); + result.replace(QLatin1String("%p"), locale.toString(progress)); return result; } @@ -568,12 +580,19 @@ QProgressBar::Direction QProgressBar::textDirection() const bool QProgressBar::event(QEvent *e) { Q_D(QProgressBar); - if (e->type() == QEvent::StyleChange + switch (e->type()) { + case QEvent::StyleChange: #ifdef Q_OS_MAC - || e->type() == QEvent::MacSizeChange + case QEvent::MacSizeChange: #endif - ) d->resetLayoutItemMargins(); + break; + case QEvent::LocaleChange: + d->initDefaultFormat(); + break; + default: + break; + } return QWidget::event(e); } @@ -596,6 +615,15 @@ void QProgressBar::setFormat(const QString &format) if (d->format == format) return; d->format = format; + d->defaultFormat = false; + update(); +} + +void QProgressBar::resetFormat() +{ + Q_D(QProgressBar); + d->defaultFormat = true; + d->initDefaultFormat(); update(); } diff --git a/src/widgets/widgets/qprogressbar.h b/src/widgets/widgets/qprogressbar.h index 99fbe005ed..71bb2fc8f8 100644 --- a/src/widgets/widgets/qprogressbar.h +++ b/src/widgets/widgets/qprogressbar.h @@ -65,7 +65,7 @@ class Q_WIDGETS_EXPORT QProgressBar : public QWidget Q_PROPERTY(Qt::Orientation orientation READ orientation WRITE setOrientation) Q_PROPERTY(bool invertedAppearance READ invertedAppearance WRITE setInvertedAppearance) Q_PROPERTY(Direction textDirection READ textDirection WRITE setTextDirection) - Q_PROPERTY(QString format READ format WRITE setFormat) + Q_PROPERTY(QString format READ format WRITE setFormat RESET resetFormat) public: enum Direction { TopToBottom, BottomToTop }; @@ -96,6 +96,7 @@ public: QProgressBar::Direction textDirection() const; void setFormat(const QString &format); + void resetFormat(); QString format() const; public Q_SLOTS: diff --git a/tests/auto/widgets/widgets/qprogressbar/tst_qprogressbar.cpp b/tests/auto/widgets/widgets/qprogressbar/tst_qprogressbar.cpp index 5ad9aa7690..2bbfb48e63 100644 --- a/tests/auto/widgets/widgets/qprogressbar/tst_qprogressbar.cpp +++ b/tests/auto/widgets/widgets/qprogressbar/tst_qprogressbar.cpp @@ -42,6 +42,7 @@ #include #include "qprogressbar.h" +#include #include #include #include @@ -64,6 +65,7 @@ private slots: void sizeHint(); void formatedText_data(); void formatedText(); + void localizedFormattedText(); void task245201_testChangeStyleAndDelete_data(); void task245201_testChangeStyleAndDelete(); @@ -301,6 +303,40 @@ void tst_QProgressBar::formatedText() QCOMPARE(bar.text(), text); } +void tst_QProgressBar::localizedFormattedText() // QTBUG-28751 +{ + QProgressBar bar; + const int value = 42; + bar.setValue(value); + const QString defaultExpectedNumber = QString::number(value); + const QString defaultExpectedValue = defaultExpectedNumber + QLatin1Char('%'); + QCOMPARE(bar.text(), defaultExpectedValue); + + // Temporarily switch to Egyptian, which has a different percent sign and number formatting + QLocale egypt(QLocale::Arabic, QLocale::Egypt); + bar.setLocale(egypt); + const QString egyptianExpectedNumber = egypt.toString(value); + const QString egyptianExpectedValue = egyptianExpectedNumber + egypt.percent(); + if (egyptianExpectedValue == defaultExpectedValue) + QSKIP("Egyptian locale does not work on this system."); + QCOMPARE(bar.text(), egyptianExpectedValue); + + bar.setLocale(QLocale()); + QCOMPARE(bar.text(), defaultExpectedValue); + + // Set a custom format containing only the number + bar.setFormat(QStringLiteral("%p")); + QCOMPARE(bar.text(), defaultExpectedNumber); + bar.setLocale(egypt); + QCOMPARE(bar.text(), egyptianExpectedNumber); + + // Clear the format + bar.resetFormat(); + QCOMPARE(bar.text(), egyptianExpectedValue); + bar.setLocale(QLocale()); + QCOMPARE(bar.text(), defaultExpectedValue); +} + void tst_QProgressBar::task245201_testChangeStyleAndDelete_data() { QTest::addColumn("style1_str");