Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qundostack.cpp
Go to the documentation of this file.
1// Copyright (C) 2020 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5#include <QtCore/qdebug.h>
6#include "qundostack.h"
7#if QT_CONFIG(undogroup)
8#include "qundogroup.h"
9#endif
10#include "qundostack_p.h"
11
12QT_BEGIN_NAMESPACE
13
14/*!
15 \class QUndoCommand
16 \brief The QUndoCommand class is the base class of all commands stored on a QUndoStack.
17 \since 4.2
18
19 \inmodule QtGui
20
21 For an overview of Qt's Undo Framework, see the
22 \l{Overview of Qt's Undo Framework}{overview document}.
23
24 A QUndoCommand represents a single editing action on a document; for example,
25 inserting or deleting a block of text in a text editor. QUndoCommand can apply
26 a change to the document with redo() and undo the change with undo(). The
27 implementations for these functions must be provided in a derived class.
28
29 \snippet code/src_gui_util_qundostack.cpp 0
30
31 A QUndoCommand has an associated text(). This is a short string
32 describing what the command does. It is used to update the text
33 properties of the stack's undo and redo actions; see
34 QUndoStack::createUndoAction() and QUndoStack::createRedoAction().
35
36 QUndoCommand objects are owned by the stack they were pushed on.
37 QUndoStack deletes a command if it has been undone and a new command is pushed. For example:
38
39\snippet code/src_gui_util_qundostack.cpp 1
40
41 In effect, when a command is pushed, it becomes the top-most command
42 on the stack.
43
44 To support command compression, QUndoCommand has an id() and the virtual function
45 mergeWith(). These functions are used by QUndoStack::push().
46
47 To support command macros, a QUndoCommand object can have any number of child
48 commands. Undoing or redoing the parent command will cause the child
49 commands to be undone or redone. A command can be assigned
50 to a parent explicitly in the constructor. In this case, the command
51 will be owned by the parent.
52
53 The parent in this case is usually an empty command, in that it doesn't
54 provide its own implementation of undo() and redo(). Instead, it uses
55 the base implementations of these functions, which simply call undo() or
56 redo() on all its children. The parent should, however, have a meaningful
57 text().
58
59 \snippet code/src_gui_util_qundostack.cpp 2
60
61 Another way to create macros is to use the convenience functions
62 QUndoStack::beginMacro() and QUndoStack::endMacro().
63
64 \sa QUndoStack
65*/
66
67/*!
68 Constructs a QUndoCommand object with the given \a parent and \a text.
69
70 If \a parent is not \nullptr, this command is appended to parent's
71 child list. The parent command then owns this command and will delete
72 it in its destructor.
73
74 \sa ~QUndoCommand()
75*/
76
77QUndoCommand::QUndoCommand(const QString &text, QUndoCommand *parent)
78 : QUndoCommand(parent)
79{
80 setText(text);
81}
82
83/*!
84 Constructs a QUndoCommand object with parent \a parent.
85
86 If \a parent is not \nullptr, this command is appended to parent's
87 child list. The parent command then owns this command and will delete
88 it in its destructor.
89
90 \sa ~QUndoCommand()
91*/
92
93QUndoCommand::QUndoCommand(QUndoCommand *parent)
94{
95 d = new QUndoCommandPrivate;
96 if (parent != nullptr)
97 parent->d->child_list.append(this);
98}
99
100/*!
101 Destroys the QUndoCommand object and all child commands.
102
103 \sa QUndoCommand()
104*/
105
106QUndoCommand::~QUndoCommand()
107{
108 qDeleteAll(d->child_list);
109 delete d;
110}
111
112/*!
113 \since 5.9
114
115 Returns whether the command is obsolete.
116
117 The boolean is used for the automatic removal of commands that are not necessary in the
118 stack anymore. The isObsolete function is checked in the functions QUndoStack::push(),
119 QUndoStack::undo(), QUndoStack::redo(), and QUndoStack::setIndex().
120
121 \sa setObsolete(), mergeWith(), QUndoStack::push(), QUndoStack::undo(), QUndoStack::redo()
122*/
123
124bool QUndoCommand::isObsolete() const
125{
126 return d->obsolete;
127}
128
129/*!
130 \since 5.9
131
132 Sets whether the command is obsolete to \a obsolete.
133
134 \sa isObsolete(), mergeWith(), QUndoStack::push(), QUndoStack::undo(), QUndoStack::redo()
135*/
136
137void QUndoCommand::setObsolete(bool obsolete)
138{
139 d->obsolete = obsolete;
140}
141
142/*!
143 Returns the ID of this command.
144
145 A command ID is used in command compression. It must be an integer unique to
146 this command's class, or -1 if the command doesn't support compression.
147
148 If the command supports compression this function must be overridden in the
149 derived class to return the correct ID. The base implementation returns -1.
150
151 QUndoStack::push() will only try to merge two commands if they have the
152 same ID, and the ID is not -1.
153
154 \sa mergeWith(), QUndoStack::push()
155*/
156
157int QUndoCommand::id() const
158{
159 return -1;
160}
161
162/*!
163 Attempts to merge this command with \a command. Returns \c true on
164 success; otherwise returns \c false.
165
166 If this function returns \c true, calling this command's redo() must have the same
167 effect as redoing both this command and \a command.
168 Similarly, calling this command's undo() must have the same effect as undoing
169 \a command and this command.
170
171 QUndoStack will only try to merge two commands if they have the same id, and
172 the id is not -1.
173
174 The default implementation returns \c false.
175
176 \snippet code/src_gui_util_qundostack.cpp 3
177
178 \sa id(), QUndoStack::push()
179*/
180
181bool QUndoCommand::mergeWith(const QUndoCommand *command)
182{
183 Q_UNUSED(command);
184 return false;
185}
186
187/*!
188 Applies a change to the document. This function must be implemented in
189 the derived class. Calling QUndoStack::push(),
190 QUndoStack::undo() or QUndoStack::redo() from this function leads to
191 undefined beahavior.
192
193 The default implementation calls redo() on all child commands.
194
195 \sa undo()
196*/
197
198void QUndoCommand::redo()
199{
200 for (int i = 0; i < d->child_list.size(); ++i)
201 d->child_list.at(i)->redo();
202}
203
204/*!
205 Reverts a change to the document. After undo() is called, the state of
206 the document should be the same as before redo() was called. This function must
207 be implemented in the derived class. Calling QUndoStack::push(),
208 QUndoStack::undo() or QUndoStack::redo() from this function leads to
209 undefined beahavior.
210
211 The default implementation calls undo() on all child commands in reverse order.
212
213 \sa redo()
214*/
215
216void QUndoCommand::undo()
217{
218 for (int i = d->child_list.size() - 1; i >= 0; --i)
219 d->child_list.at(i)->undo();
220}
221
222/*!
223 Returns a short text string describing what this command does; for example,
224 "insert text".
225
226 The text is used for names of items in QUndoView.
227
228 \sa actionText(), setText(), QUndoStack::createUndoAction(), QUndoStack::createRedoAction()
229*/
230
231QString QUndoCommand::text() const
232{
233 return d->text;
234}
235
236/*!
237 \since 4.8
238
239 Returns a short text string describing what this command does; for example,
240 "insert text".
241
242 The text is used when the text properties of the stack's undo and redo
243 actions are updated.
244
245 \sa text(), setText(), QUndoStack::createUndoAction(), QUndoStack::createRedoAction()
246*/
247
248QString QUndoCommand::actionText() const
249{
250 return d->actionText;
251}
252
253/*!
254 Sets the command's text to be the \a text specified.
255
256 The specified text should be a short user-readable string describing what this
257 command does.
258
259 If you need to have two different strings for text() and actionText(), separate
260 them with "\\n" and pass into this function. Even if you do not use this feature
261 for English strings during development, you can still let translators use two
262 different strings in order to match specific languages' needs.
263 The described feature and the function actionText() are available since Qt 4.8.
264
265 \sa text(), actionText(), QUndoStack::createUndoAction(), QUndoStack::createRedoAction()
266*/
267
268void QUndoCommand::setText(const QString &text)
269{
270 int cdpos = text.indexOf(u'\n');
271 if (cdpos > 0) {
272 d->text = text.left(cdpos);
273 d->actionText = text.mid(cdpos + 1);
274 } else {
275 d->text = text;
276 d->actionText = text;
277 }
278}
279
280/*!
281 \since 4.4
282
283 Returns the number of child commands in this command.
284
285 \sa child()
286*/
287
288int QUndoCommand::childCount() const
289{
290 return d->child_list.size();
291}
292
293/*!
294 \since 4.4
295
296 Returns the child command at \a index.
297
298 \sa childCount(), QUndoStack::command()
299*/
300
301const QUndoCommand *QUndoCommand::child(int index) const
302{
303 if (index < 0 || index >= d->child_list.size())
304 return nullptr;
305 return d->child_list.at(index);
306}
307
308#if QT_CONFIG(undostack)
309
310/*!
311 \class QUndoStack
312 \brief The QUndoStack class is a stack of QUndoCommand objects.
313 \since 4.2
314
315 \inmodule QtGui
316
317 For an overview of Qt's Undo Framework, see the
318 \l{Overview of Qt's Undo Framework}{overview document}.
319
320 An undo stack maintains a stack of commands that have been applied to a
321 document.
322
323 New commands are pushed on the stack using push(). Commands can be
324 undone and redone using undo() and redo(), or by triggering the
325 actions returned by createUndoAction() and createRedoAction().
326
327 QUndoStack keeps track of the \a current command. This is the command
328 which will be executed by the next call to redo(). The index of this
329 command is returned by index(). The state of the edited object can be
330 rolled forward or back using setIndex(). If the top-most command on the
331 stack has already been redone, index() is equal to count().
332
333 QUndoStack provides support for undo and redo actions, command
334 compression, command macros, and supports the concept of a
335 \e{clean state}.
336
337 \section1 Undo and Redo Actions
338
339 QUndoStack provides convenient undo and redo QAction objects, which
340 can be inserted into a menu or a toolbar. When commands are undone or
341 redone, QUndoStack updates the text properties of these actions
342 to reflect what change they will trigger. The actions are also disabled
343 when no command is available for undo or redo. These actions
344 are returned by QUndoStack::createUndoAction() and QUndoStack::createRedoAction().
345
346 \section1 Command Compression and Macros
347
348 Command compression is useful when several commands can be compressed
349 into a single command that can be undone and redone in a single operation.
350 For example, when a user types a character in a text editor, a new command
351 is created. This command inserts the character into the document at the
352 cursor position. However, it is more convenient for the user to be able
353 to undo or redo typing of whole words, sentences, or paragraphs.
354 Command compression allows these single-character commands to be merged
355 into a single command which inserts or deletes sections of text.
356 For more information, see QUndoCommand::mergeWith() and push().
357
358 A command macro is a sequence of commands, all of which are undone and
359 redone in one go. Command macros are created by giving a command a list
360 of child commands.
361 Undoing or redoing the parent command will cause the child commands to
362 be undone or redone. Command macros may be created explicitly
363 by specifying a parent in the QUndoCommand constructor, or by using the
364 convenience functions beginMacro() and endMacro().
365
366 Although command compression and macros appear to have the same effect to the
367 user, they often have different uses in an application. Commands that
368 perform small changes to a document may be usefully compressed if there is
369 no need to individually record them, and if only larger changes are relevant
370 to the user.
371 However, for commands that need to be recorded individually, or those that
372 cannot be compressed, it is useful to use macros to provide a more convenient
373 user experience while maintaining a record of each command.
374
375 \section1 Clean State
376
377 QUndoStack supports the concept of a clean state. When the
378 document is saved to disk, the stack can be marked as clean using
379 setClean(). Whenever the stack returns to this state through undoing and
380 redoing commands, it emits the signal cleanChanged(). This signal
381 is also emitted when the stack leaves the clean state. This signal is
382 usually used to enable and disable the save actions in the application,
383 and to update the document's title to reflect that it contains unsaved
384 changes.
385
386 \section1 Obsolete Commands
387
388 QUndoStack is able to delete commands from the stack if the command is no
389 longer needed. One example may be to delete a command when two commands are
390 merged together in such a way that the merged command has no function. This
391 can be seen with move commands where the user moves their mouse to one part
392 of the screen and then moves it to the original position. The merged command
393 results in a mouse movement of 0. This command can be deleted since it serves
394 no purpose. Another example is with networking commands that fail due to connection
395 issues. In this case, the command is to be removed from the stack because the redo()
396 and undo() functions have no function since there was connection issues.
397
398 A command can be marked obsolete with the QUndoCommand::setObsolete() function.
399 The QUndoCommand::isObsolete() flag is checked in QUndoStack::push(),
400 QUndoStack::undo(), QUndoStack::redo(), and QUndoStack::setIndex() after calling
401 QUndoCommand::undo(), QUndoCommand::redo() and QUndoCommand:mergeWith() where
402 applicable.
403
404 If a command is set obsolete and the clean index is greater than or equal to the
405 current command index, then the clean index will be reset when the command is
406 deleted from the stack.
407
408 \sa QUndoCommand, QUndoView
409*/
410
411/*! \internal
412 Sets the current index to \a idx, emitting appropriate signals. If \a clean is true,
413 makes \a idx the clean index as well.
414*/
415
416void QUndoStackPrivate::setIndex(int idx, bool clean)
417{
418 Q_Q(QUndoStack);
419
420 bool was_clean = index == clean_index;
421
422 const bool indexChanged = idx != index;
423 if (indexChanged) {
424 index = idx;
425 emit q->indexChanged(index);
426 }
427
428 const ActionState newUndoState{q->canUndo(), q->undoText()};
429 if (indexChanged || newUndoState != undoActionState) {
430 undoActionState = newUndoState;
431 emit q->canUndoChanged(undoActionState.enabled);
432 emit q->undoTextChanged(undoActionState.text);
433 }
434
435 const ActionState newRedoState{q->canRedo(), q->redoText()};
436 if (indexChanged || newRedoState != redoActionState) {
437 redoActionState = newRedoState;
438 emit q->canRedoChanged(redoActionState.enabled);
439 emit q->redoTextChanged(redoActionState.text);
440 }
441
442 if (clean)
443 clean_index = index;
444
445 bool is_clean = index == clean_index;
446 if (is_clean != was_clean)
447 emit q->cleanChanged(is_clean);
448}
449
450/*! \internal
451 If the number of commands on the stack exceedes the undo limit, deletes commands from
452 the bottom of the stack.
453
454 Returns \c true if commands were deleted.
455*/
456
457bool QUndoStackPrivate::checkUndoLimit()
458{
459 if (undo_limit <= 0 || !macro_stack.isEmpty() || undo_limit >= command_list.size())
460 return false;
461
462 int del_count = command_list.size() - undo_limit;
463
464 for (int i = 0; i < del_count; ++i)
465 delete command_list.takeFirst();
466
467 index -= del_count;
468 if (clean_index != -1) {
469 if (clean_index < del_count)
470 clean_index = -1; // we've deleted the clean command
471 else
472 clean_index -= del_count;
473 }
474
475 return true;
476}
477
478/*!
479 Constructs an empty undo stack with the parent \a parent. The
480 stack will initially be in the clean state. If \a parent is a
481 QUndoGroup object, the stack is automatically added to the group.
482
483 \sa push()
484*/
485
486QUndoStack::QUndoStack(QObject *parent)
487 : QObject(*(new QUndoStackPrivate), parent)
488{
489#if QT_CONFIG(undogroup)
490 if (QUndoGroup *group = qobject_cast<QUndoGroup*>(parent))
491 group->addStack(this);
492#endif
493}
494
495/*!
496 Destroys the undo stack, deleting any commands that are on it. If the
497 stack is in a QUndoGroup, the stack is automatically removed from the group.
498
499 \sa QUndoStack()
500*/
501
502QUndoStack::~QUndoStack()
503{
504#if QT_CONFIG(undogroup)
505 Q_D(QUndoStack);
506 if (d->group != nullptr)
507 d->group->removeStack(this);
508#endif
509 clear();
510}
511
512/*!
513 Clears the command stack by deleting all commands on it, and returns the stack
514 to the clean state.
515
516 Commands are not undone or redone; the state of the edited object remains
517 unchanged.
518
519 This function is usually used when the contents of the document are
520 abandoned.
521
522 \sa QUndoStack()
523*/
524
525void QUndoStack::clear()
526{
527 Q_D(QUndoStack);
528
529 if (d->command_list.isEmpty())
530 return;
531
532 bool was_clean = isClean();
533
534 d->macro_stack.clear();
535 qDeleteAll(d->command_list);
536 d->command_list.clear();
537
538 d->index = 0;
539 d->clean_index = 0;
540
541 emit indexChanged(0);
542 emit canUndoChanged(false);
543 emit undoTextChanged(QString());
544 emit canRedoChanged(false);
545 emit redoTextChanged(QString());
546
547 if (!was_clean)
548 emit cleanChanged(true);
549}
550
551/*!
552 Pushes \a cmd on the stack or merges it with the most recently executed command.
553 In either case, executes \a cmd by calling its redo() function.
554
555 If \a cmd's id is not -1, and if the id is the same as that of the
556 most recently executed command, QUndoStack will attempt to merge the two
557 commands by calling QUndoCommand::mergeWith() on the most recently executed
558 command. If QUndoCommand::mergeWith() returns \c true, \a cmd is deleted.
559
560 After calling QUndoCommand::redo() and, if applicable, QUndoCommand::mergeWith(),
561 QUndoCommand::isObsolete() will be called for \a cmd or the merged command.
562 If QUndoCommand::isObsolete() returns \c true, then \a cmd or the merged command
563 will be deleted from the stack.
564
565 In all other cases \a cmd is simply pushed on the stack.
566
567 If commands were undone before \a cmd was pushed, the current command and
568 all commands above it are deleted. Hence \a cmd always ends up being the
569 top-most on the stack.
570
571 Once a command is pushed, the stack takes ownership of it. There
572 are no getters to return the command, since modifying it after it has
573 been executed will almost always lead to corruption of the document's
574 state.
575
576 \sa QUndoCommand::id(), QUndoCommand::mergeWith()
577*/
578
579void QUndoStack::push(QUndoCommand *cmd)
580{
581 Q_D(QUndoStack);
582 if (!cmd->isObsolete())
583 cmd->redo();
584
585 bool macro = !d->macro_stack.isEmpty();
586
587 QUndoCommand *cur = nullptr;
588 if (macro) {
589 QUndoCommand *macro_cmd = d->macro_stack.constLast();
590 if (!macro_cmd->d->child_list.isEmpty())
591 cur = macro_cmd->d->child_list.constLast();
592 } else {
593 if (d->index > 0)
594 cur = d->command_list.at(d->index - 1);
595 while (d->index < d->command_list.size())
596 delete d->command_list.takeLast();
597 if (d->clean_index > d->index)
598 d->clean_index = -1; // we've deleted the clean state
599 }
600
601 bool try_merge = cur != nullptr
602 && cur->id() != -1
603 && cur->id() == cmd->id()
604 && (macro || d->index != d->clean_index);
605
606 if (try_merge && cur->mergeWith(cmd)) {
607 delete cmd;
608
609 if (macro) {
610 if (cur->isObsolete())
611 delete d->macro_stack.constLast()->d->child_list.takeLast();
612 } else {
613 if (cur->isObsolete()) {
614 delete d->command_list.takeLast();
615
616 d->setIndex(d->index - 1, false);
617 } else {
618 emit indexChanged(d->index);
619 emit canUndoChanged(canUndo());
620 emit undoTextChanged(undoText());
621 emit canRedoChanged(canRedo());
622 emit redoTextChanged(redoText());
623 }
624 }
625 } else if (cmd->isObsolete()) {
626 delete cmd; // command should be deleted and NOT added to the stack
627 } else {
628 if (macro) {
629 d->macro_stack.constLast()->d->child_list.append(cmd);
630 } else {
631 d->command_list.append(cmd);
632 d->checkUndoLimit();
633 d->setIndex(d->index + 1, false);
634 }
635 }
636}
637
638/*!
639 Marks the stack as clean and emits cleanChanged() if the stack was
640 not already clean.
641
642 This is typically called when a document is saved, for example.
643
644 Whenever the stack returns to this state through the use of undo/redo
645 commands, it emits the signal cleanChanged(). This signal is also
646 emitted when the stack leaves the clean state.
647
648 \sa isClean(), resetClean(), cleanIndex()
649*/
650
651void QUndoStack::setClean()
652{
653 Q_D(QUndoStack);
654 if (Q_UNLIKELY(!d->macro_stack.isEmpty())) {
655 qWarning("QUndoStack::setClean(): cannot set clean in the middle of a macro");
656 return;
657 }
658
659 d->setIndex(d->index, true);
660}
661
662/*!
663 \since 5.8
664
665 Leaves the clean state and emits cleanChanged() if the stack was clean.
666 This method resets the clean index to -1.
667
668 This is typically called in the following cases, when a document has been:
669 \list
670 \li created basing on some template and has not been saved,
671 so no filename has been associated with the document yet.
672 \li restored from a backup file.
673 \li changed outside of the editor and the user did not reload it.
674 \endlist
675
676 \sa isClean(), setClean(), cleanIndex()
677*/
678
679void QUndoStack::resetClean()
680{
681 Q_D(QUndoStack);
682 const bool was_clean = isClean();
683 d->clean_index = -1;
684 if (was_clean)
685 emit cleanChanged(false);
686}
687
688/*!
689 \since 5.12
690 \property QUndoStack::clean
691 \brief the clean status of this stack.
692
693 This property indicates whether or not the stack is clean. For example, a
694 stack is clean when a document has been saved.
695
696 \sa isClean(), setClean(), resetClean(), cleanIndex()
697*/
698
699/*!
700 If the stack is in the clean state, returns \c true; otherwise returns \c false.
701
702 \sa setClean(), cleanIndex()
703*/
704
705bool QUndoStack::isClean() const
706{
707 Q_D(const QUndoStack);
708 if (!d->macro_stack.isEmpty())
709 return false;
710 return d->clean_index == d->index;
711}
712
713/*!
714 Returns the clean index. This is the index at which setClean() was called.
715
716 A stack may not have a clean index. This happens if a document is saved,
717 some commands are undone, then a new command is pushed. Since
718 push() deletes all the undone commands before pushing the new command, the stack
719 can't return to the clean state again. In this case, this function returns -1.
720 The -1 may also be returned after an explicit call to resetClean().
721
722 \sa isClean(), setClean()
723*/
724
725int QUndoStack::cleanIndex() const
726{
727 Q_D(const QUndoStack);
728 return d->clean_index;
729}
730
731/*!
732 Undoes the command below the current command by calling QUndoCommand::undo().
733 Decrements the current command index.
734
735 If the stack is empty, or if the bottom command on the stack has already been
736 undone, this function does nothing.
737
738 After the command is undone, if QUndoCommand::isObsolete() returns \c true,
739 then the command will be deleted from the stack. Additionally, if the clean
740 index is greater than or equal to the current command index, then the clean
741 index is reset.
742
743 \sa redo(), index()
744*/
745
746void QUndoStack::undo()
747{
748 Q_D(QUndoStack);
749 if (d->index == 0)
750 return;
751
752 if (Q_UNLIKELY(!d->macro_stack.isEmpty())) {
753 qWarning("QUndoStack::undo(): cannot undo in the middle of a macro");
754 return;
755 }
756
757 int idx = d->index - 1;
758 QUndoCommand *cmd = d->command_list.at(idx);
759
760 if (!cmd->isObsolete())
761 cmd->undo();
762
763 if (cmd->isObsolete()) { // A separate check is done b/c the undo command may set obsolete flag
764 delete d->command_list.takeAt(idx);
765
766 if (d->clean_index > idx)
767 resetClean();
768 }
769
770 d->setIndex(idx, false);
771}
772
773/*!
774 Redoes the current command by calling QUndoCommand::redo(). Increments the current
775 command index.
776
777 If the stack is empty, or if the top command on the stack has already been
778 redone, this function does nothing.
779
780 If QUndoCommand::isObsolete() returns true for the current command, then
781 the command will be deleted from the stack. Additionally, if the clean
782 index is greater than or equal to the current command index, then the clean
783 index is reset.
784
785 \sa undo(), index()
786*/
787
788void QUndoStack::redo()
789{
790 Q_D(QUndoStack);
791 if (d->index == d->command_list.size())
792 return;
793
794 if (Q_UNLIKELY(!d->macro_stack.isEmpty())) {
795 qWarning("QUndoStack::redo(): cannot redo in the middle of a macro");
796 return;
797 }
798
799 int idx = d->index;
800 QUndoCommand *cmd = d->command_list.at(idx);
801
802 if (!cmd->isObsolete())
803 cmd->redo(); // A separate check is done b/c the undo command may set obsolete flag
804
805 if (cmd->isObsolete()) {
806 delete d->command_list.takeAt(idx);
807
808 if (d->clean_index > idx)
809 resetClean();
810
811 d->setIndex(idx, false);
812 } else {
813 d->setIndex(d->index + 1, false);
814 }
815}
816
817/*!
818 Returns the number of commands on the stack. Macro commands are counted as
819 one command.
820
821 \sa index(), setIndex(), command()
822*/
823
824int QUndoStack::count() const
825{
826 Q_D(const QUndoStack);
827 return d->command_list.size();
828}
829
830/*!
831 Returns the index of the current command. This is the command that will be
832 executed on the next call to redo(). It is not always the top-most command
833 on the stack, since a number of commands may have been undone.
834
835 \sa undo(), redo(), count()
836*/
837
838int QUndoStack::index() const
839{
840 Q_D(const QUndoStack);
841 return d->index;
842}
843
844/*!
845 Repeatedly calls undo() or redo() until the current command index reaches
846 \a idx. This function can be used to roll the state of the document forwards
847 of backwards. indexChanged() is emitted only once.
848
849 \sa index(), count(), undo(), redo()
850*/
851
852void QUndoStack::setIndex(int idx)
853{
854 Q_D(QUndoStack);
855 if (Q_UNLIKELY(!d->macro_stack.isEmpty())) {
856 qWarning("QUndoStack::setIndex(): cannot set index in the middle of a macro");
857 return;
858 }
859
860 if (idx < 0)
861 idx = 0;
862 else if (idx > d->command_list.size())
863 idx = d->command_list.size();
864
865 int i = d->index;
866 while (i < idx) {
867 QUndoCommand *cmd = d->command_list.at(i);
868
869 if (!cmd->isObsolete())
870 cmd->redo(); // A separate check is done b/c the undo command may set obsolete flag
871
872 if (cmd->isObsolete()) {
873 delete d->command_list.takeAt(i);
874
875 if (d->clean_index > i)
876 resetClean();
877
878 idx--; // Subtract from idx because we removed a command
879 } else {
880 i++;
881 }
882 }
883
884 while (i > idx) {
885 QUndoCommand *cmd = d->command_list.at(--i);
886
887 cmd->undo();
888 if (cmd->isObsolete()) {
889 delete d->command_list.takeAt(i);
890
891 if (d->clean_index > i)
892 resetClean();
893 }
894 }
895
896 d->setIndex(idx, false);
897}
898
899/*!
900 \since 5.12
901 \property QUndoStack::canUndo
902 \brief whether this stack can undo.
903
904 This property indicates whether or not there is a command that can be
905 undone.
906
907 \sa canUndo(), index(), canRedo()
908*/
909
910/*!
911 Returns \c true if there is a command available for undo; otherwise returns \c false.
912
913 This function returns \c false if the stack is empty, or if the bottom command
914 on the stack has already been undone.
915
916 Synonymous with index() == 0.
917
918 \sa index(), canRedo()
919*/
920
921bool QUndoStack::canUndo() const
922{
923 Q_D(const QUndoStack);
924 if (!d->macro_stack.isEmpty())
925 return false;
926 return d->index > 0;
927}
928
929/*!
930 \since 5.12
931 \property QUndoStack::canRedo
932 \brief whether this stack can redo.
933
934 This property indicates whether or not there is a command that can be
935 redone.
936
937 \sa canRedo(), index(), canUndo()
938*/
939
940/*!
941 Returns \c true if there is a command available for redo; otherwise returns \c false.
942
943 This function returns \c false if the stack is empty or if the top command
944 on the stack has already been redone.
945
946 Synonymous with index() == count().
947
948 \sa index(), canUndo()
949*/
950
951bool QUndoStack::canRedo() const
952{
953 Q_D(const QUndoStack);
954 if (!d->macro_stack.isEmpty())
955 return false;
956 return d->index < d->command_list.size();
957}
958
959/*!
960 \since 5.12
961 \property QUndoStack::undoText
962 \brief the undo text of the next command that is undone.
963
964 This property holds the text of the command which will be undone in the
965 next call to undo().
966
967 \sa undoText(), QUndoCommand::actionText(), redoText()
968*/
969
970/*!
971 Returns the text of the command which will be undone in the next call to undo().
972
973 \sa QUndoCommand::actionText(), redoText()
974*/
975
976QString QUndoStack::undoText() const
977{
978 Q_D(const QUndoStack);
979 if (!d->macro_stack.isEmpty())
980 return QString();
981 if (d->index > 0)
982 return d->command_list.at(d->index - 1)->actionText();
983 return QString();
984}
985
986/*!
987 \since 5.12
988 \property QUndoStack::redoText
989 \brief the redo text of the next command that is redone.
990
991 This property holds the text of the command which will be redone in the
992 next call to redo().
993
994 \sa redoText(), QUndoCommand::actionText(), undoText()
995*/
996
997/*!
998 Returns the text of the command which will be redone in the next call to redo().
999
1000 \sa QUndoCommand::actionText(), undoText()
1001*/
1002
1003QString QUndoStack::redoText() const
1004{
1005 Q_D(const QUndoStack);
1006 if (!d->macro_stack.isEmpty())
1007 return QString();
1008 if (d->index < d->command_list.size())
1009 return d->command_list.at(d->index)->actionText();
1010 return QString();
1011}
1012
1013#ifndef QT_NO_ACTION
1014
1015/*!
1016 \internal
1017
1018 Sets the text property of \a action to \a text, applying \a prefix, and falling back to \a defaultText if \a text is empty.
1019*/
1020void QUndoStackPrivate::setPrefixedText(QAction *action, const QString &prefix, const QString &defaultText, const QString &text)
1021{
1022 if (defaultText.isEmpty()) {
1023 QString s = prefix;
1024 if (!prefix.isEmpty() && !text.isEmpty())
1025 s.append(u' ');
1026 s.append(text);
1027 action->setText(s);
1028 } else {
1029 if (text.isEmpty())
1030 action->setText(defaultText);
1031 else
1032 action->setText(prefix.arg(text));
1033 }
1034};
1035
1036/*!
1037 Creates an undo QAction object with the given \a parent.
1038
1039 Triggering this action will cause a call to undo(). The text of this action
1040 is the text of the command which will be undone in the next call to undo(),
1041 prefixed by the specified \a prefix. If there is no command available for undo,
1042 this action will be disabled.
1043
1044 If \a prefix is empty, the default template "Undo %1" is used instead of prefix.
1045 Before Qt 4.8, the prefix "Undo" was used by default.
1046
1047 \sa createRedoAction(), canUndo(), QUndoCommand::text()
1048*/
1049
1050QAction *QUndoStack::createUndoAction(QObject *parent, const QString &prefix) const
1051{
1052 QAction *action = new QAction(parent);
1053 action->setEnabled(canUndo());
1054
1055 QString effectivePrefix = prefix;
1056 QString defaultText;
1057 if (prefix.isEmpty()) {
1058 effectivePrefix = tr("Undo %1");
1059 defaultText = tr("Undo", "Default text for undo action");
1060 }
1061
1062 QUndoStackPrivate::setPrefixedText(action, effectivePrefix, defaultText, undoText());
1063
1064 connect(this, &QUndoStack::canUndoChanged, action, &QAction::setEnabled);
1065 connect(this, &QUndoStack::undoTextChanged, action, [=](const QString &text) {
1066 QUndoStackPrivate::setPrefixedText(action, effectivePrefix, defaultText, text);
1067 });
1068 connect(action, &QAction::triggered, this, &QUndoStack::undo);
1069
1070 return action;
1071}
1072
1073/*!
1074 Creates an redo QAction object with the given \a parent.
1075
1076 Triggering this action will cause a call to redo(). The text of this action
1077 is the text of the command which will be redone in the next call to redo(),
1078 prefixed by the specified \a prefix. If there is no command available for redo,
1079 this action will be disabled.
1080
1081 If \a prefix is empty, the default template "Redo %1" is used instead of prefix.
1082 Before Qt 4.8, the prefix "Redo" was used by default.
1083
1084 \sa createUndoAction(), canRedo(), QUndoCommand::text()
1085*/
1086
1087QAction *QUndoStack::createRedoAction(QObject *parent, const QString &prefix) const
1088{
1089 QAction *action = new QAction(parent);
1090 action->setEnabled(canRedo());
1091
1092 QString effectivePrefix = prefix;
1093 QString defaultText;
1094 if (prefix.isEmpty()) {
1095 effectivePrefix = tr("Redo %1");
1096 defaultText = tr("Redo", "Default text for redo action");
1097 }
1098
1099 QUndoStackPrivate::setPrefixedText(action, effectivePrefix, defaultText, redoText());
1100
1101 connect(this, &QUndoStack::canRedoChanged, action, &QAction::setEnabled);
1102 connect(this, &QUndoStack::redoTextChanged, action, [=](const QString &text) {
1103 QUndoStackPrivate::setPrefixedText(action, effectivePrefix, defaultText, text);
1104 });
1105 connect(action, &QAction::triggered, this, &QUndoStack::redo);
1106
1107 return action;
1108}
1109
1110#endif // QT_NO_ACTION
1111
1112/*!
1113 Begins composition of a macro command with the given \a text description.
1114
1115 An empty command described by the specified \a text is pushed on the stack.
1116 Any subsequent commands pushed on the stack will be appended to the empty
1117 command's children until endMacro() is called.
1118
1119 Calls to beginMacro() and endMacro() may be nested, but every call to
1120 beginMacro() must have a matching call to endMacro().
1121
1122 While a macro is being composed, the stack is disabled. This means that:
1123 \list
1124 \li indexChanged() and cleanChanged() are not emitted,
1125 \li canUndo() and canRedo() return false,
1126 \li calling undo() or redo() has no effect,
1127 \li the undo/redo actions are disabled.
1128 \endlist
1129
1130 The stack becomes enabled and appropriate signals are emitted when endMacro()
1131 is called for the outermost macro.
1132
1133 \snippet code/src_gui_util_qundostack.cpp 4
1134
1135 This code is equivalent to:
1136
1137 \snippet code/src_gui_util_qundostack.cpp 5
1138
1139 \sa endMacro()
1140*/
1141
1142void QUndoStack::beginMacro(const QString &text)
1143{
1144 Q_D(QUndoStack);
1145 QUndoCommand *cmd = new QUndoCommand();
1146 cmd->setText(text);
1147
1148 if (d->macro_stack.isEmpty()) {
1149 while (d->index < d->command_list.size())
1150 delete d->command_list.takeLast();
1151 if (d->clean_index > d->index)
1152 d->clean_index = -1; // we've deleted the clean state
1153 d->command_list.append(cmd);
1154 } else {
1155 d->macro_stack.constLast()->d->child_list.append(cmd);
1156 }
1157 d->macro_stack.append(cmd);
1158
1159 if (d->macro_stack.size() == 1) {
1160 emit canUndoChanged(false);
1161 emit undoTextChanged(QString());
1162 emit canRedoChanged(false);
1163 emit redoTextChanged(QString());
1164 }
1165}
1166
1167/*!
1168 Ends composition of a macro command.
1169
1170 If this is the outermost macro in a set nested macros, this function emits
1171 indexChanged() once for the entire macro command.
1172
1173 \sa beginMacro()
1174*/
1175
1176void QUndoStack::endMacro()
1177{
1178 Q_D(QUndoStack);
1179 if (Q_UNLIKELY(d->macro_stack.isEmpty())) {
1180 qWarning("QUndoStack::endMacro(): no matching beginMacro()");
1181 return;
1182 }
1183
1184 d->macro_stack.removeLast();
1185
1186 if (d->macro_stack.isEmpty()) {
1187 d->checkUndoLimit();
1188 d->setIndex(d->index + 1, false);
1189 }
1190}
1191
1192/*!
1193 \since 4.4
1194
1195 Returns a const pointer to the command at \a index.
1196
1197 This function returns a const pointer, because modifying a command,
1198 once it has been pushed onto the stack and executed, almost always
1199 causes corruption of the state of the document, if the command is
1200 later undone or redone.
1201
1202 \sa QUndoCommand::child()
1203*/
1204const QUndoCommand *QUndoStack::command(int index) const
1205{
1206 Q_D(const QUndoStack);
1207
1208 if (index < 0 || index >= d->command_list.size())
1209 return nullptr;
1210 return d->command_list.at(index);
1211}
1212
1213/*!
1214 Returns the text of the command at index \a idx.
1215
1216 \sa beginMacro()
1217*/
1218
1219QString QUndoStack::text(int idx) const
1220{
1221 Q_D(const QUndoStack);
1222
1223 if (idx < 0 || idx >= d->command_list.size())
1224 return QString();
1225 return d->command_list.at(idx)->text();
1226}
1227
1228/*!
1229 \property QUndoStack::undoLimit
1230 \brief the maximum number of commands on this stack.
1231 \since 4.3
1232
1233 When the number of commands on a stack exceedes the stack's undoLimit, commands are
1234 deleted from the bottom of the stack. Macro commands (commands with child commands)
1235 are treated as one command. The default value is 0, which means that there is no
1236 limit.
1237
1238 This property may only be set when the undo stack is empty, since setting it on a
1239 non-empty stack might delete the command at the current index. Calling setUndoLimit()
1240 on a non-empty stack prints a warning and does nothing.
1241*/
1242
1243void QUndoStack::setUndoLimit(int limit)
1244{
1245 Q_D(QUndoStack);
1246
1247 if (Q_UNLIKELY(!d->command_list.isEmpty())) {
1248 qWarning("QUndoStack::setUndoLimit(): an undo limit can only be set when the stack is empty");
1249 return;
1250 }
1251
1252 if (limit == d->undo_limit)
1253 return;
1254 d->undo_limit = limit;
1255 d->checkUndoLimit();
1256}
1257
1258int QUndoStack::undoLimit() const
1259{
1260 Q_D(const QUndoStack);
1261
1262 return d->undo_limit;
1263}
1264
1265/*!
1266 \property QUndoStack::active
1267 \brief the active status of this stack.
1268
1269 An application often has multiple undo stacks, one for each opened document. The active
1270 stack is the one associated with the currently active document. If the stack belongs
1271 to a QUndoGroup, calls to QUndoGroup::undo() or QUndoGroup::redo() will be forwarded
1272 to this stack when it is active. If the QUndoGroup is watched by a QUndoView, the view
1273 will display the contents of this stack when it is active. If the stack does not belong to
1274 a QUndoGroup, making it active has no effect.
1275
1276 It is the programmer's responsibility to specify which stack is active by
1277 calling setActive(), usually when the associated document window receives focus.
1278
1279 \sa QUndoGroup
1280*/
1281
1282void QUndoStack::setActive(bool active)
1283{
1284#if !QT_CONFIG(undogroup)
1285 Q_UNUSED(active);
1286#else
1287 Q_D(QUndoStack);
1288
1289 if (d->group != nullptr) {
1290 if (active)
1291 d->group->setActiveStack(this);
1292 else if (d->group->activeStack() == this)
1293 d->group->setActiveStack(nullptr);
1294 }
1295#endif
1296}
1297
1298bool QUndoStack::isActive() const
1299{
1300#if !QT_CONFIG(undogroup)
1301 return true;
1302#else
1303 Q_D(const QUndoStack);
1304 return d->group == nullptr || d->group->activeStack() == this;
1305#endif
1306}
1307
1308/*!
1309 \fn void QUndoStack::indexChanged(int idx)
1310
1311 This signal is emitted whenever a command modifies the state of the document.
1312 This happens when a command is undone or redone. When a macro
1313 command is undone or redone, or setIndex() is called, this signal
1314 is emitted only once.
1315
1316 \a idx specifies the index of the current command, ie. the command which will be
1317 executed on the next call to redo().
1318
1319 \sa index(), setIndex()
1320*/
1321
1322/*!
1323 \fn void QUndoStack::cleanChanged(bool clean)
1324
1325 This signal is emitted whenever the stack enters or leaves the clean state.
1326 If \a clean is true, the stack is in a clean state; otherwise this signal
1327 indicates that it has left the clean state.
1328
1329 \sa isClean(), setClean()
1330*/
1331
1332/*!
1333 \fn void QUndoStack::undoTextChanged(const QString &undoText)
1334
1335 This signal is emitted whenever the value of undoText() changes. It is
1336 used to update the text property of the undo action returned by createUndoAction().
1337 \a undoText specifies the new text.
1338*/
1339
1340/*!
1341 \fn void QUndoStack::canUndoChanged(bool canUndo)
1342
1343 This signal is emitted whenever the value of canUndo() changes. It is
1344 used to enable or disable the undo action returned by createUndoAction().
1345 \a canUndo specifies the new value.
1346*/
1347
1348/*!
1349 \fn void QUndoStack::redoTextChanged(const QString &redoText)
1350
1351 This signal is emitted whenever the value of redoText() changes. It is
1352 used to update the text property of the redo action returned by createRedoAction().
1353 \a redoText specifies the new text.
1354*/
1355
1356/*!
1357 \fn void QUndoStack::canRedoChanged(bool canRedo)
1358
1359 This signal is emitted whenever the value of canRedo() changes. It is
1360 used to enable or disable the redo action returned by createRedoAction().
1361 \a canRedo specifies the new value.
1362*/
1363
1364QT_END_NAMESPACE
1365
1366#include "moc_qundostack.cpp"
1367
1368#endif // QT_CONFIG(undostack)