Allow using not only prefixes for undo command text
authorAlexander Potashev <aspotashev@gmail.com>
Mon, 9 May 2011 08:35:29 +0000 (10:35 +0200)
committerOlivier Goffart <olivier.goffart@nokia.com>
Tue, 10 May 2011 10:54:56 +0000 (12:54 +0200)
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
src/gui/util/qundostack.cpp
src/gui/util/qundostack_p.h
tests/auto/qundogroup/testdata/qundogroup.ts [new file with mode: 0644]
tests/auto/qundogroup/tst_qundogroup.cpp
tests/auto/qundostack/testdata/qundostack.ts [new file with mode: 0644]
tests/auto/qundostack/tst_qundostack.cpp

index 42cda74..a24ce8d 100644 (file)
@@ -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)),
index 6b038ee..417f02e 100644 (file)
@@ -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)),
index 3c7d0e7..2906fd8 100644 (file)
@@ -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 (file)
index 0000000..a059bcb
--- /dev/null
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="en">
+<context>
+    <name>QUndoGroup</name>
+    <message>
+        <source>Undo %1</source>
+        <translation>undo-prefix %1 undo-suffix</translation>
+    </message>
+    <message>
+        <source>Undo</source>
+        <comment>Default text for undo action</comment>
+        <translation>Undo-default-text</translation>
+    </message>
+    <message>
+        <source>Redo %1</source>
+        <translation>redo-prefix %1 redo-suffix</translation>
+    </message>
+    <message>
+        <source>Redo</source>
+        <comment>Default text for redo action</comment>
+        <translation>Redo-default-text</translation>
+    </message>
+</context>
+</TS>
index 8927f85..d2909b7 100644 (file)
@@ -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 (file)
index 0000000..4584036
--- /dev/null
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="en">
+<context>
+    <name>QUndoStack</name>
+    <message>
+        <source>Undo %1</source>
+        <translation>undo-prefix %1 undo-suffix</translation>
+    </message>
+    <message>
+        <source>Undo</source>
+        <comment>Default text for undo action</comment>
+        <translation>Undo-default-text</translation>
+    </message>
+    <message>
+        <source>Redo %1</source>
+        <translation>redo-prefix %1 redo-suffix</translation>
+    </message>
+    <message>
+        <source>Redo</source>
+        <comment>Default text for redo action</comment>
+        <translation>Redo-default-text</translation>
+    </message>
+</context>
+</TS>
index 739d3f2..bcab43d 100644 (file)
@@ -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"