From ec4d346f95de4933b660d5ce005751abdced4c7d Mon Sep 17 00:00:00 2001 From: Alexander Potashev Date: Mon, 9 May 2011 10:35:29 +0200 Subject: [PATCH] Allow using not only prefixes for undo command text Functions QUndo{Group,Stack}::create{Undo,Redo}Action() now use action text templates "Undo %1" and "Redo %1" if no custom prefix was provided. This makes more flexible translations possible. The surrounding text (like "Undo" and "Redo") can now be suffixed to the command name as German and Korean languages require ("%1 rueckgaengig machen" for German). Also, now the default action text (when no command can be undone) can be translated differently from the prefix. For example, it can be translated as "Undo action", not just "Undo". When a non-empty prefix is passed to QUndo*****::create****Action(), those functions work as before, and the features described above become unavailable. Task-number: QTBUG-14442 Merge-request: 1212 Reviewed-by: ossi (cherry picked from commit 213c25ad24e4f3b0a44f82f23d34746cd294f8d6) --- src/gui/util/qundogroup.cpp | 18 ++++++--- src/gui/util/qundostack.cpp | 41 ++++++++++++++------ src/gui/util/qundostack_p.h | 2 + tests/auto/qundogroup/testdata/qundogroup.ts | 25 ++++++++++++ tests/auto/qundogroup/tst_qundogroup.cpp | 37 ++++++++++++++++++ tests/auto/qundostack/testdata/qundostack.ts | 25 ++++++++++++ tests/auto/qundostack/tst_qundostack.cpp | 35 +++++++++++++++++ 7 files changed, 166 insertions(+), 17 deletions(-) create mode 100644 tests/auto/qundogroup/testdata/qundogroup.ts create mode 100644 tests/auto/qundostack/testdata/qundostack.ts diff --git a/src/gui/util/qundogroup.cpp b/src/gui/util/qundogroup.cpp index 42cda7462ae..a24ce8dce84 100644 --- a/src/gui/util/qundogroup.cpp +++ b/src/gui/util/qundogroup.cpp @@ -375,15 +375,18 @@ bool QUndoGroup::isClean() const for undo, if the group is empty or if none of the stacks are active, this action will be disabled. - If \a prefix is empty, the default prefix "Undo" is used. + If \a prefix is empty, the default template "Undo %1" is used instead of prefix. + Before Qt 4.8, the prefix "Undo" was used by default. \sa createRedoAction() canUndo() QUndoCommand::text() */ QAction *QUndoGroup::createUndoAction(QObject *parent, const QString &prefix) const { - QString pref = prefix.isEmpty() ? tr("Undo") : prefix; - QUndoAction *result = new QUndoAction(pref, parent); + QUndoAction *result = new QUndoAction(prefix, parent); + if (prefix.isEmpty()) + result->setTextFormat(tr("Undo %1"), tr("Undo", "Default text for undo action")); + result->setEnabled(canUndo()); result->setPrefixedText(undoText()); connect(this, SIGNAL(canUndoChanged(bool)), @@ -403,15 +406,18 @@ QAction *QUndoGroup::createUndoAction(QObject *parent, const QString &prefix) co for redo, if the group is empty or if none of the stacks are active, this action will be disabled. - If \a prefix is empty, the default prefix "Undo" is used. + If \a prefix is empty, the default template "Redo %1" is used instead of prefix. + Before Qt 4.8, the prefix "Redo" was used by default. \sa createUndoAction() canRedo() QUndoCommand::text() */ QAction *QUndoGroup::createRedoAction(QObject *parent, const QString &prefix) const { - QString pref = prefix.isEmpty() ? tr("Redo") : prefix; - QUndoAction *result = new QUndoAction(pref, parent); + QUndoAction *result = new QUndoAction(prefix, parent); + if (prefix.isEmpty()) + result->setTextFormat(tr("Redo %1"), tr("Redo", "Default text for redo action")); + result->setEnabled(canRedo()); result->setPrefixedText(redoText()); connect(this, SIGNAL(canRedoChanged(bool)), diff --git a/src/gui/util/qundostack.cpp b/src/gui/util/qundostack.cpp index 6b038ee52e4..417f02e4b24 100644 --- a/src/gui/util/qundostack.cpp +++ b/src/gui/util/qundostack.cpp @@ -374,11 +374,24 @@ QUndoAction::QUndoAction(const QString &prefix, QObject *parent) void QUndoAction::setPrefixedText(const QString &text) { - QString s = m_prefix; - if (!m_prefix.isEmpty() && !text.isEmpty()) - s.append(QLatin1Char(' ')); - s.append(text); - setText(s); + if (m_defaultText.isEmpty()) { + QString s = m_prefix; + if (!m_prefix.isEmpty() && !text.isEmpty()) + s.append(QLatin1Char(' ')); + s.append(text); + setText(s); + } else { + if (text.isEmpty()) + setText(m_defaultText); + else + setText(m_prefix.arg(text)); + } +} + +void QUndoAction::setTextFormat(const QString &textFormat, const QString &defaultText) +{ + m_prefix = textFormat; + m_defaultText = defaultText; } #endif // QT_NO_ACTION @@ -822,15 +835,18 @@ QString QUndoStack::redoText() const prefixed by the specified \a prefix. If there is no command available for undo, this action will be disabled. - If \a prefix is empty, the default prefix "Undo" is used. + If \a prefix is empty, the default template "Undo %1" is used instead of prefix. + Before Qt 4.8, the prefix "Undo" was used by default. \sa createRedoAction(), canUndo(), QUndoCommand::text() */ QAction *QUndoStack::createUndoAction(QObject *parent, const QString &prefix) const { - QString pref = prefix.isEmpty() ? tr("Undo") : prefix; - QUndoAction *result = new QUndoAction(pref, parent); + QUndoAction *result = new QUndoAction(prefix, parent); + if (prefix.isEmpty()) + result->setTextFormat(tr("Undo %1"), tr("Undo", "Default text for undo action")); + result->setEnabled(canUndo()); result->setPrefixedText(undoText()); connect(this, SIGNAL(canUndoChanged(bool)), @@ -849,15 +865,18 @@ QAction *QUndoStack::createUndoAction(QObject *parent, const QString &prefix) co prefixed by the specified \a prefix. If there is no command available for redo, this action will be disabled. - If \a prefix is empty, the default prefix "Redo" is used. + If \a prefix is empty, the default template "Redo %1" is used instead of prefix. + Before Qt 4.8, the prefix "Redo" was used by default. \sa createUndoAction(), canRedo(), QUndoCommand::text() */ QAction *QUndoStack::createRedoAction(QObject *parent, const QString &prefix) const { - QString pref = prefix.isEmpty() ? tr("Redo") : prefix; - QUndoAction *result = new QUndoAction(pref, parent); + QUndoAction *result = new QUndoAction(prefix, parent); + if (prefix.isEmpty()) + result->setTextFormat(tr("Redo %1"), tr("Redo", "Default text for redo action")); + result->setEnabled(canRedo()); result->setPrefixedText(redoText()); connect(this, SIGNAL(canRedoChanged(bool)), diff --git a/src/gui/util/qundostack_p.h b/src/gui/util/qundostack_p.h index 3c7d0e7d853..2906fd8564b 100644 --- a/src/gui/util/qundostack_p.h +++ b/src/gui/util/qundostack_p.h @@ -98,10 +98,12 @@ class QUndoAction : public QAction Q_OBJECT public: QUndoAction(const QString &prefix, QObject *parent = 0); + void setTextFormat(const QString &textFormat, const QString &defaultText); public Q_SLOTS: void setPrefixedText(const QString &text); private: QString m_prefix; + QString m_defaultText; }; #endif // QT_NO_ACTION diff --git a/tests/auto/qundogroup/testdata/qundogroup.ts b/tests/auto/qundogroup/testdata/qundogroup.ts new file mode 100644 index 00000000000..a059bcb4867 --- /dev/null +++ b/tests/auto/qundogroup/testdata/qundogroup.ts @@ -0,0 +1,25 @@ + + + + + QUndoGroup + + Undo %1 + undo-prefix %1 undo-suffix + + + Undo + Default text for undo action + Undo-default-text + + + Redo %1 + redo-prefix %1 redo-suffix + + + Redo + Default text for redo action + Redo-default-text + + + diff --git a/tests/auto/qundogroup/tst_qundogroup.cpp b/tests/auto/qundogroup/tst_qundogroup.cpp index 8927f859ecf..d2909b733ed 100644 --- a/tests/auto/qundogroup/tst_qundogroup.cpp +++ b/tests/auto/qundogroup/tst_qundogroup.cpp @@ -201,6 +201,7 @@ private slots: void deleteStack(); void checkSignals(); void addStackAndDie(); + void commandTextFormat(); }; tst_QUndoGroup::tst_QUndoGroup() @@ -604,6 +605,42 @@ void tst_QUndoGroup::addStackAndDie() delete stack; } +void tst_QUndoGroup::commandTextFormat() +{ + QString binDir = QLibraryInfo::location(QLibraryInfo::BinariesPath); + QVERIFY(!QProcess::execute(binDir + "/lrelease testdata/qundogroup.ts")); + + QTranslator translator; + QVERIFY(translator.load("testdata/qundogroup.qm")); + qApp->installTranslator(&translator); + + QUndoGroup group; + QAction *undo_action = group.createUndoAction(0); + QAction *redo_action = group.createRedoAction(0); + + QCOMPARE(undo_action->text(), QString("Undo-default-text")); + QCOMPARE(redo_action->text(), QString("Redo-default-text")); + + QUndoStack stack(&group); + stack.setActive(); + QString str; + + stack.push(new AppendCommand(&str, "foo")); + QCOMPARE(undo_action->text(), QString("undo-prefix append undo-suffix")); + QCOMPARE(redo_action->text(), QString("Redo-default-text")); + + stack.push(new InsertCommand(&str, 0, "bar")); + stack.undo(); + QCOMPARE(undo_action->text(), QString("undo-prefix append undo-suffix")); + QCOMPARE(redo_action->text(), QString("redo-prefix insert redo-suffix")); + + stack.undo(); + QCOMPARE(undo_action->text(), QString("Undo-default-text")); + QCOMPARE(redo_action->text(), QString("redo-prefix append redo-suffix")); + + qApp->removeTranslator(&translator); +} + #else class tst_QUndoGroup : public QObject { diff --git a/tests/auto/qundostack/testdata/qundostack.ts b/tests/auto/qundostack/testdata/qundostack.ts new file mode 100644 index 00000000000..4584036af2f --- /dev/null +++ b/tests/auto/qundostack/testdata/qundostack.ts @@ -0,0 +1,25 @@ + + + + + QUndoStack + + Undo %1 + undo-prefix %1 undo-suffix + + + Undo + Default text for undo action + Undo-default-text + + + Redo %1 + redo-prefix %1 redo-suffix + + + Redo + Default text for redo action + Redo-default-text + + + diff --git a/tests/auto/qundostack/tst_qundostack.cpp b/tests/auto/qundostack/tst_qundostack.cpp index 739d3f26828..bcab43d4af3 100644 --- a/tests/auto/qundostack/tst_qundostack.cpp +++ b/tests/auto/qundostack/tst_qundostack.cpp @@ -220,6 +220,7 @@ private slots: void macroBeginEnd(); void compression(); void undoLimit(); + void commandTextFormat(); }; tst_QUndoStack::tst_QUndoStack() @@ -2935,6 +2936,40 @@ void tst_QUndoStack::undoLimit() true); // redoChanged } +void tst_QUndoStack::commandTextFormat() +{ + QString binDir = QLibraryInfo::location(QLibraryInfo::BinariesPath); + QVERIFY(!QProcess::execute(binDir + "/lrelease testdata/qundostack.ts")); + + QTranslator translator; + QVERIFY(translator.load("testdata/qundostack.qm")); + qApp->installTranslator(&translator); + + QUndoStack stack; + QAction *undo_action = stack.createUndoAction(0); + QAction *redo_action = stack.createRedoAction(0); + + QCOMPARE(undo_action->text(), QString("Undo-default-text")); + QCOMPARE(redo_action->text(), QString("Redo-default-text")); + + QString str; + + stack.push(new AppendCommand(&str, "foo")); + QCOMPARE(undo_action->text(), QString("undo-prefix append undo-suffix")); + QCOMPARE(redo_action->text(), QString("Redo-default-text")); + + stack.push(new InsertCommand(&str, 0, "bar")); + stack.undo(); + QCOMPARE(undo_action->text(), QString("undo-prefix append undo-suffix")); + QCOMPARE(redo_action->text(), QString("redo-prefix insert redo-suffix")); + + stack.undo(); + QCOMPARE(undo_action->text(), QString("Undo-default-text")); + QCOMPARE(redo_action->text(), QString("redo-prefix append redo-suffix")); + + qApp->removeTranslator(&translator); +} + QTEST_MAIN(tst_QUndoStack) #include "tst_qundostack.moc"