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)
This commit is contained in:
Alexander Potashev 2011-05-09 10:35:29 +02:00 committed by Olivier Goffart
parent e04ad81dc4
commit ec4d346f95
7 changed files with 166 additions and 17 deletions

View 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)),

View 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)),

View 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

View File

@ -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>

View 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
{

View File

@ -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>

View 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"