diff options
5 files changed, 43 insertions, 49 deletions
diff --git a/src/quickcontrolsimpl/qquickiconlabel.cpp b/src/quickcontrolsimpl/qquickiconlabel.cpp index 1c0c56c098..030399364f 100644 --- a/src/quickcontrolsimpl/qquickiconlabel.cpp +++ b/src/quickcontrolsimpl/qquickiconlabel.cpp @@ -8,7 +8,6 @@ #include "qquickmnemoniclabel_p.h" #include <QtGui/private/qguiapplication_p.h> -#include <QtGui/qpa/qplatformtheme.h> #include <QtQuick/private/qquickitem_p.h> #include <QtQuick/private/qquicktext_p.h> #include <QtQuickTemplates2/private/qquickicon_p.h> @@ -28,12 +27,6 @@ void QQuickIconLabelPrivate::completeComponent(QQuickItem *item) parserStatus->componentComplete(); } -void QQuickIconLabelPrivate::init() -{ - mnemonicEnabled = QGuiApplicationPrivate::platformTheme()->themeHint( - QPlatformTheme::MnemonicsEnabled).toBool(); -} - QQuickIconLabelPrivate::~QQuickIconLabelPrivate() = default; bool QQuickIconLabelPrivate::hasIcon() const @@ -366,13 +359,11 @@ void QQuickIconLabelPrivate::displayChange() QQuickIconLabel::QQuickIconLabel(QQuickItem *parent) : QQuickItem(*(new QQuickIconLabelPrivate), parent) { - d_func()->init(); } QQuickIconLabel::QQuickIconLabel(QQuickIconLabelPrivate &dd, QQuickItem *parent) : QQuickItem(dd, parent) { - d_func()->init(); } QQuickIconLabel::~QQuickIconLabel() diff --git a/src/quickcontrolsimpl/qquickiconlabel_p_p.h b/src/quickcontrolsimpl/qquickiconlabel_p_p.h index 15aa9fb42d..fba5132c7f 100644 --- a/src/quickcontrolsimpl/qquickiconlabel_p_p.h +++ b/src/quickcontrolsimpl/qquickiconlabel_p_p.h @@ -31,7 +31,6 @@ class Q_AUTOTEST_EXPORT QQuickIconLabelPrivate : public QQuickItemPrivate, Q_DECLARE_PUBLIC(QQuickIconLabel) public: - void init(); ~QQuickIconLabelPrivate() override; bool hasIcon() const; @@ -71,6 +70,10 @@ public: const QRectF &rectangle); bool mirrored = false; + // See QQuickMnemonicLabel::m_mnemonicEnabled for why this is true by default. + // We just act as an intermediary between types that require an Icon + Label, like Button, + // and the QQuickMnemonicLabel itself. Other types like CheckBox use QQuickCheckLabel directly, + // which derives from QQuickMnemonicLabel. bool mnemonicEnabled = true; QQuickIconLabel::Display display = QQuickIconLabel::TextBesideIcon; Qt::Alignment alignment = Qt::AlignCenter; diff --git a/src/quickcontrolsimpl/qquickmnemoniclabel.cpp b/src/quickcontrolsimpl/qquickmnemoniclabel.cpp index 471272ad45..01bb277b67 100644 --- a/src/quickcontrolsimpl/qquickmnemoniclabel.cpp +++ b/src/quickcontrolsimpl/qquickmnemoniclabel.cpp @@ -13,8 +13,6 @@ QT_BEGIN_NAMESPACE QQuickMnemonicLabel::QQuickMnemonicLabel(QQuickItem *parent) : QQuickText(parent) { - m_mnemonicEnabled = QGuiApplicationPrivate::platformTheme()->themeHint( - QPlatformTheme::MnemonicsEnabled).toBool(); } QString QQuickMnemonicLabel::text() const @@ -53,8 +51,7 @@ void QQuickMnemonicLabel::setText(const QString &text) \li \c false: the displayed text is \c "M&nemonic" (unchanged). \endlist - The default value is \c true if the platform supports mnemonics - (\c QPlatformTheme::MnemonicsEnabled), otherwise \c false. + The default value is \c true. */ bool QQuickMnemonicLabel::isMnemonicEnabled() const { @@ -103,7 +100,7 @@ void QQuickMnemonicLabel::updateMnemonic() while (len) { if (m_fullText.at(pos) == QLatin1Char('&') && (len == 1 || m_fullText.at(pos + 1) != QLatin1Char('&'))) { // A plain mnemonic marker, e.g. "M&nemonic": drop the "&" and - // underline the character that follows it. + // underline the character that follows it (if the platform supports it). if (showUnderline && (pos == 0 || m_fullText.at(pos - 1) != QLatin1Char('&'))) formats += underlineRange(pos); ++pos; @@ -116,8 +113,7 @@ void QQuickMnemonicLabel::updateMnemonic() m_fullText.at(pos + 3) == QLatin1Char(')')) { // A mnemonic with format "\s*(&X)", used when the label itself has // no natural character to underline (e.g. non-Latin scripts). Keep - // "X" in the text, and underline it if the platform draws - // underlines for shortcuts. + // "X" in the text, and underline it if the platform supports it. if (showUnderline) formats += underlineRange(pos + 1); } diff --git a/src/quickcontrolsimpl/qquickmnemoniclabel_p.h b/src/quickcontrolsimpl/qquickmnemoniclabel_p.h index b92a69ec42..71fd75ced8 100644 --- a/src/quickcontrolsimpl/qquickmnemoniclabel_p.h +++ b/src/quickcontrolsimpl/qquickmnemoniclabel_p.h @@ -41,6 +41,9 @@ public: private: void updateMnemonic(); + // True by default because it's the default for most types like Button: + // only ItemDelegate and its derived types set it to false. Note that underlining + // is controlled separately; see the docs for this property. bool m_mnemonicEnabled = true; QString m_fullText; }; diff --git a/tests/auto/quickcontrols/qquickabstractbutton/tst_qquickabstractbutton.cpp b/tests/auto/quickcontrols/qquickabstractbutton/tst_qquickabstractbutton.cpp index 0eec2ea57b..25e819b17a 100644 --- a/tests/auto/quickcontrols/qquickabstractbutton/tst_qquickabstractbutton.cpp +++ b/tests/auto/quickcontrols/qquickabstractbutton/tst_qquickabstractbutton.cpp @@ -90,28 +90,33 @@ void tst_QQuickAbstractButton::cleanupTestCase() void tst_QQuickAbstractButton::mnemonics_data() { - QTest::addColumn<bool>("expectedEnabledByDefault"); + QTest::addColumn<bool>("expectEnabledByDefault"); + QTest::addColumn<bool>("expectMnemonicStripped"); // The data tag is used as the QML type to instantiate; see mnemonics(). - QTest::newRow("Button") << platformSupportsMnemonics; - QTest::newRow("CheckBox") << platformSupportsMnemonics; - QTest::newRow("MenuItem") << platformSupportsMnemonics; - QTest::newRow("MenuBarItem") << platformSupportsMnemonics; - QTest::newRow("RadioButton") << platformSupportsMnemonics; - QTest::newRow("Switch") << platformSupportsMnemonics; - QTest::newRow("ToolButton") << platformSupportsMnemonics; + // The "&" should always be stripped from the displayed text for Button and its derived types, + // regardless of whether the platform supports mnemonics. For example, on Linux, the & is + // stripped and the next character underlined. On macOS, the & is just stripped. + QTest::newRow("Button") << platformSupportsMnemonics << true; + QTest::newRow("CheckBox") << platformSupportsMnemonics << true; + QTest::newRow("MenuItem") << platformSupportsMnemonics << true; + QTest::newRow("MenuBarItem") << platformSupportsMnemonics << true; + QTest::newRow("RadioButton") << platformSupportsMnemonics << true; + QTest::newRow("Switch") << platformSupportsMnemonics << true; + QTest::newRow("ToolButton") << platformSupportsMnemonics << true; // These types explicitly disable mnemonics regardless of platform. - QTest::newRow("ItemDelegate") << false; - QTest::newRow("CheckDelegate") << false; - QTest::newRow("RadioDelegate") << false; - QTest::newRow("SwipeDelegate") << false; - QTest::newRow("SwitchDelegate") << false; - QTest::newRow("DelayButton") << false; + QTest::newRow("ItemDelegate") << false << false; + QTest::newRow("CheckDelegate") << false << false; + QTest::newRow("RadioDelegate") << false << false; + QTest::newRow("SwipeDelegate") << false << false; + QTest::newRow("SwitchDelegate") << false << false; + QTest::newRow("DelayButton") << false << false; } void tst_QQuickAbstractButton::mnemonics() { - QFETCH(bool, expectedEnabledByDefault); + QFETCH(bool, expectEnabledByDefault); + QFETCH(bool, expectMnemonicStripped); const QString qmlType = QString::fromUtf8(QTest::currentDataTag()); ensureViewVisible(); @@ -145,19 +150,15 @@ void tst_QQuickAbstractButton::mnemonics() QVERIFY(textItem); auto *textItemPrivate = QQuickTextPrivate::get(textItem); - // First, check the defaults. - const bool usesMnemonicLabel = qobject_cast<QQuickMnemonicLabel *>(textItem); - const bool mnemonicStripped = usesMnemonicLabel && expectedEnabledByDefault; - // Whether the mnemonic character is actually underlined additionally depends on - // QPlatformTheme::UnderlineShortcut (which is false for e.g. macOS). - const bool mnemonicUnderlined = mnemonicStripped && platformUnderlinesShortcuts; - // The "&" should always be stripped from the displayed text when mnemonics are enabled, - // even if the platform doesn't underline the shortcut. - QCOMPARE(textItemPrivate->text, mnemonicStripped ? "Mnemonic" : "M&nemonic"); + // "&" is stripped for non-delegate types on every platform; whether the following + // character is underlined depends on QPlatformTheme::UnderlineShortcut. + const bool expectMnemonicUnderlined = expectMnemonicStripped && platformUnderlinesShortcuts; + + QCOMPARE(textItemPrivate->text, expectMnemonicStripped ? "Mnemonic" : "M&nemonic"); // There should only be one QTextLayout::FormatRange applied to the text: the one for the // underline. - QCOMPARE(textItemPrivate->layout.formats().size(), mnemonicUnderlined ? 1 : 0); - if (mnemonicUnderlined) { + QCOMPARE(textItemPrivate->layout.formats().size(), expectMnemonicUnderlined ? 1 : 0); + if (expectMnemonicUnderlined) { const QTextLayout::FormatRange underlineFormatRange = textItemPrivate->layout.formats().constFirst(); QCOMPARE(underlineFormatRange.start, 1); @@ -168,14 +169,14 @@ void tst_QQuickAbstractButton::mnemonics() // Set the text to something else to ensure that it picks up changes. control->setText(QStringLiteral("&Hello")); QCOMPARE(control->text(), QStringLiteral("&Hello")); - QCOMPARE(textItemPrivate->text, mnemonicStripped ? "Hello" : "&Hello"); + QCOMPARE(textItemPrivate->text, expectMnemonicStripped ? "Hello" : "&Hello"); const QSignalSpy clickSpy(control, SIGNAL(clicked())); QVERIFY(clickSpy.isValid()); int expectedClickedCount = 0; // Pressing the shortcut while visible should click the button. - if (expectedEnabledByDefault) + if (expectEnabledByDefault) ++expectedClickedCount; QTest::keyClick(view.get(), Qt::Key_H, Qt::AltModifier); QCOMPARE(clickSpy.count(), expectedClickedCount); @@ -186,7 +187,7 @@ void tst_QQuickAbstractButton::mnemonics() QCOMPARE(clickSpy.count(), expectedClickedCount); // Pressing the shortcut after showing should click the button. - if (expectedEnabledByDefault) + if (expectEnabledByDefault) ++expectedClickedCount; control->setVisible(true); QTest::keyClick(view.get(), Qt::Key_H, Qt::AltModifier); @@ -201,7 +202,7 @@ void tst_QQuickAbstractButton::mnemonics() QCOMPARE(clickSpy.count(), expectedClickedCount); // The new shortcut should. - if (expectedEnabledByDefault) + if (expectEnabledByDefault) ++expectedClickedCount; QTest::keyClick(view.get(), Qt::Key_S, Qt::AltModifier); QCOMPARE(clickSpy.count(), expectedClickedCount); @@ -213,7 +214,7 @@ void tst_QQuickAbstractButton::mnemonics() QCOMPARE(clickSpy.count(), expectedClickedCount); // Restore visibility; should click. - if (expectedEnabledByDefault) + if (expectEnabledByDefault) ++expectedClickedCount; control->setVisible(true); QTest::keyClick(view.get(), Qt::Key_H, Qt::AltModifier); @@ -231,7 +232,7 @@ void tst_QQuickAbstractButton::mnemonics() // Mnemonics in Action text should behave the same as the button's text. int expectedActionTriggeredCount = 0; - if (expectedEnabledByDefault) { + if (expectEnabledByDefault) { ++expectedClickedCount; ++expectedActionTriggeredCount; } |
