source: trunk/src/gui/util/qundostack.cpp@ 234

Last change on this file since 234 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 32.6 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the QtGui module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include <QtCore/qdebug.h>
43#include "qundostack.h"
44#include "qundogroup.h"
45#include "qundostack_p.h"
46
47#ifndef QT_NO_UNDOCOMMAND
48
49QT_BEGIN_NAMESPACE
50
51/*!
52 \class QUndoCommand
53 \brief The QUndoCommand class is the base class of all commands stored on a QUndoStack.
54 \since 4.2
55 \ingroup misc
56
57 For an overview of Qt's Undo Framework, see the
58 \l{Overview of Qt's Undo Framework}{overview document}.
59
60 A QUndoCommand represents a single editing action on a document; for example,
61 inserting or deleting a block of text in a text editor. QUndoCommand can apply
62 a change to the document with redo() and undo the change with undo(). The
63 implementations for these functions must be provided in a derived class.
64
65 \snippet doc/src/snippets/code/src_gui_util_qundostack.cpp 0
66
67 A QUndoCommand has an associated text(). This is a short string
68 describing what the command does. It is used to update the text
69 properties of the stack's undo and redo actions; see
70 QUndoStack::createUndoAction() and QUndoStack::createRedoAction().
71
72 QUndoCommand objects are owned by the stack they were pushed on.
73 QUndoStack deletes a command if it has been undone and a new command is pushed. For example:
74
75\snippet doc/src/snippets/code/src_gui_util_qundostack.cpp 1
76
77 In effect, when a command is pushed, it becomes the top-most command
78 on the stack.
79
80 To support command compression, QUndoCommand has an id() and the virtual function
81 mergeWith(). These functions are used by QUndoStack::push().
82
83 To support command macros, a QUndoCommand object can have any number of child
84 commands. Undoing or redoing the parent command will cause the child
85 commands to be undone or redone. A command can be assigned
86 to a parent explicitly in the constructor. In this case, the command
87 will be owned by the parent.
88
89 The parent in this case is usually an empty command, in that it doesn't
90 provide its own implementation of undo() and redo(). Instead, it uses
91 the base implementations of these functions, which simply call undo() or
92 redo() on all its children. The parent should, however, have a meaningful
93 text().
94
95 \snippet doc/src/snippets/code/src_gui_util_qundostack.cpp 2
96
97 Another way to create macros is to use the convenience functions
98 QUndoStack::beginMacro() and QUndoStack::endMacro().
99
100 \sa QUndoStack
101*/
102
103/*!
104 Constructs a QUndoCommand object with the given \a parent and \a text.
105
106 If \a parent is not 0, this command is appended to parent's child list.
107 The parent command then owns this command and will delete it in its
108 destructor.
109
110 \sa ~QUndoCommand()
111*/
112
113QUndoCommand::QUndoCommand(const QString &text, QUndoCommand *parent)
114{
115 d = new QUndoCommandPrivate;
116 if (parent != 0)
117 parent->d->child_list.append(this);
118 d->text = text;
119}
120
121/*!
122 Constructs a QUndoCommand object with parent \a parent.
123
124 If \a parent is not 0, this command is appended to parent's child list.
125 The parent command then owns this command and will delete it in its
126 destructor.
127
128 \sa ~QUndoCommand()
129*/
130
131QUndoCommand::QUndoCommand(QUndoCommand *parent)
132{
133 d = new QUndoCommandPrivate;
134 if (parent != 0)
135 parent->d->child_list.append(this);
136}
137
138/*!
139 Destroys the QUndoCommand object and all child commands.
140
141 \sa QUndoCommand()
142*/
143
144QUndoCommand::~QUndoCommand()
145{
146 qDeleteAll(d->child_list);
147 delete d;
148}
149
150/*!
151 Returns the ID of this command.
152
153 A command ID is used in command compression. It must be an integer unique to
154 this command's class, or -1 if the command doesn't support compression.
155
156 If the command supports compression this function must be overridden in the
157 derived class to return the correct ID. The base implementation returns -1.
158
159 QUndoStack::push() will only try to merge two commands if they have the
160 same ID, and the ID is not -1.
161
162 \sa mergeWith(), QUndoStack::push()
163*/
164
165int QUndoCommand::id() const
166{
167 return -1;
168}
169
170/*!
171 Attempts to merge this command with \a command. Returns true on
172 success; otherwise returns false.
173
174 If this function returns true, calling this command's redo() must have the same
175 effect as redoing both this command and \a command.
176 Similarly, calling this command's undo() must have the same effect as undoing
177 \a command and this command.
178
179 QUndoStack will only try to merge two commands if they have the same id, and
180 the id is not -1.
181
182 The default implementation returns false.
183
184 \snippet doc/src/snippets/code/src_gui_util_qundostack.cpp 3
185
186 \sa id() QUndoStack::push()
187*/
188
189bool QUndoCommand::mergeWith(const QUndoCommand *command)
190{
191 Q_UNUSED(command);
192 return false;
193}
194
195/*!
196 Applies a change to the document. This function must be implemented in
197 the derived class. Calling QUndoStack::push(),
198 QUndoStack::undo() or QUndoStack::redo() from this function leads to
199 undefined beahavior.
200
201 The default implementation calls redo() on all child commands.
202
203 \sa undo()
204*/
205
206void QUndoCommand::redo()
207{
208 for (int i = 0; i < d->child_list.size(); ++i)
209 d->child_list.at(i)->redo();
210}
211
212/*!
213 Reverts a change to the document. After undo() is called, the state of
214 the document should be the same as before redo() was called. This function must
215 be implemented in the derived class. Calling QUndoStack::push(),
216 QUndoStack::undo() or QUndoStack::redo() from this function leads to
217 undefined beahavior.
218
219 The default implementation calls undo() on all child commands in reverse order.
220
221 \sa redo()
222*/
223
224void QUndoCommand::undo()
225{
226 for (int i = d->child_list.size() - 1; i >= 0; --i)
227 d->child_list.at(i)->undo();
228}
229
230/*!
231 Returns a short text string describing what this command does; for example,
232 "insert text".
233
234 The text is used when the text properties of the stack's undo and redo
235 actions are updated.
236
237 \sa setText(), QUndoStack::createUndoAction(), QUndoStack::createRedoAction()
238*/
239
240QString QUndoCommand::text() const
241{
242 return d->text;
243}
244
245/*!
246 Sets the command's text to be the \a text specified.
247
248 The specified text should be a short user-readable string describing what this
249 command does.
250
251 \sa text() QUndoStack::createUndoAction() QUndoStack::createRedoAction()
252*/
253
254void QUndoCommand::setText(const QString &text)
255{
256 d->text = text;
257}
258
259/*!
260 \since 4.4
261
262 Returns the number of child commands in this command.
263
264 \sa child()
265*/
266
267int QUndoCommand::childCount() const
268{
269 return d->child_list.count();
270}
271
272/*!
273 \since 4.4
274
275 Returns the child command at \a index.
276
277 \sa childCount(), QUndoStack::command()
278*/
279
280const QUndoCommand *QUndoCommand::child(int index) const
281{
282 if (index < 0 || index >= d->child_list.count())
283 return 0;
284 return d->child_list.at(index);
285}
286
287#endif // QT_NO_UNDOCOMMAND
288
289#ifndef QT_NO_UNDOSTACK
290
291/*!
292 \class QUndoStack
293 \brief The QUndoStack class is a stack of QUndoCommand objects.
294 \since 4.2
295 \ingroup misc
296
297 For an overview of Qt's Undo Framework, see the
298 \l{Overview of Qt's Undo Framework}{overview document}.
299
300 An undo stack maintains a stack of commands that have been applied to a
301 document.
302
303 New commands are pushed on the stack using push(). Commands can be
304 undone and redone using undo() and redo(), or by triggering the
305 actions returned by createUndoAction() and createRedoAction().
306
307 QUndoStack keeps track of the \a current command. This is the command
308 which will be executed by the next call to redo(). The index of this
309 command is returned by index(). The state of the edited object can be
310 rolled forward or back using setIndex(). If the top-most command on the
311 stack has already been redone, index() is equal to count().
312
313 QUndoStack provides support for undo and redo actions, command
314 compression, command macros, and supports the concept of a
315 \e{clean state}.
316
317 \section1 Undo and Redo Actions
318
319 QUndoStack provides convenient undo and redo QAction objects, which
320 can be inserted into a menu or a toolbar. When commands are undone or
321 redone, QUndoStack updates the text properties of these actions
322 to reflect what change they will trigger. The actions are also disabled
323 when no command is available for undo or redo. These actions
324 are returned by QUndoStack::createUndoAction() and QUndoStack::createRedoAction().
325
326 \section1 Command Compression and Macros
327
328 Command compression is useful when several commands can be compressed
329 into a single command that can be undone and redone in a single operation.
330 For example, when a user types a character in a text editor, a new command
331 is created. This command inserts the character into the document at the
332 cursor position. However, it is more convenient for the user to be able
333 to undo or redo typing of whole words, sentences, or paragraphs.
334 Command compression allows these single-character commands to be merged
335 into a single command which inserts or deletes sections of text.
336 For more information, see QUndoCommand::mergeWith() and push().
337
338 A command macro is a sequence of commands, all of which are undone and
339 redone in one go. Command macros are created by giving a command a list
340 of child commands.
341 Undoing or redoing the parent command will cause the child commands to
342 be undone or redone. Command macros may be created explicitly
343 by specifying a parent in the QUndoCommand constructor, or by using the
344 convenience functions beginMacro() and endMacro().
345
346 Although command compression and macros appear to have the same effect to the
347 user, they often have different uses in an application. Commands that
348 perform small changes to a document may be usefully compressed if there is
349 no need to individually record them, and if only larger changes are relevant
350 to the user.
351 However, for commands that need to be recorded individually, or those that
352 cannot be compressed, it is useful to use macros to provide a more convenient
353 user experience while maintaining a record of each command.
354
355 \section1 Clean State
356
357 QUndoStack supports the concept of a clean state. When the
358 document is saved to disk, the stack can be marked as clean using
359 setClean(). Whenever the stack returns to this state through undoing and
360 redoing commands, it emits the signal cleanChanged(). This signal
361 is also emitted when the stack leaves the clean state. This signal is
362 usually used to enable and disable the save actions in the application,
363 and to update the document's title to reflect that it contains unsaved
364 changes.
365
366 \sa QUndoCommand, QUndoView
367*/
368
369#ifndef QT_NO_ACTION
370
371QUndoAction::QUndoAction(const QString &prefix, QObject *parent)
372 : QAction(parent)
373{
374 m_prefix = prefix;
375}
376
377void QUndoAction::setPrefixedText(const QString &text)
378{
379 QString s = m_prefix;
380 if (!m_prefix.isEmpty() && !text.isEmpty())
381 s.append(QLatin1Char(' '));
382 s.append(text);
383 setText(s);
384}
385
386#endif // QT_NO_ACTION
387
388/*! \internal
389 Sets the current index to \a idx, emitting appropriate signals. If \a clean is true,
390 makes \a idx the clean index as well.
391*/
392
393void QUndoStackPrivate::setIndex(int idx, bool clean)
394{
395 Q_Q(QUndoStack);
396
397 bool was_clean = index == clean_index;
398
399 if (idx != index) {
400 index = idx;
401 emit q->indexChanged(index);
402 emit q->canUndoChanged(q->canUndo());
403 emit q->undoTextChanged(q->undoText());
404 emit q->canRedoChanged(q->canRedo());
405 emit q->redoTextChanged(q->redoText());
406 }
407
408 if (clean)
409 clean_index = index;
410
411 bool is_clean = index == clean_index;
412 if (is_clean != was_clean)
413 emit q->cleanChanged(is_clean);
414}
415
416/*! \internal
417 If the number of commands on the stack exceedes the undo limit, deletes commands from
418 the bottom of the stack.
419
420 Returns true if commands were deleted.
421*/
422
423bool QUndoStackPrivate::checkUndoLimit()
424{
425 if (undo_limit <= 0 || !macro_stack.isEmpty() || undo_limit >= command_list.count())
426 return false;
427
428 int del_count = command_list.count() - undo_limit;
429
430 for (int i = 0; i < del_count; ++i)
431 delete command_list.takeFirst();
432
433 index -= del_count;
434 if (clean_index != -1) {
435 if (clean_index < del_count)
436 clean_index = -1; // we've deleted the clean command
437 else
438 clean_index -= del_count;
439 }
440
441 return true;
442}
443
444/*!
445 Constructs an empty undo stack with the parent \a parent. The
446 stack will initally be in the clean state. If \a parent is a
447 QUndoGroup object, the stack is automatically added to the group.
448
449 \sa push()
450*/
451
452QUndoStack::QUndoStack(QObject *parent)
453 : QObject(*(new QUndoStackPrivate), parent)
454{
455#ifndef QT_NO_UNDOGROUP
456 if (QUndoGroup *group = qobject_cast<QUndoGroup*>(parent))
457 group->addStack(this);
458#endif
459}
460
461/*!
462 Destroys the undo stack, deleting any commands that are on it. If the
463 stack is in a QUndoGroup, the stack is automatically removed from the group.
464
465 \sa QUndoStack()
466*/
467
468QUndoStack::~QUndoStack()
469{
470#ifndef QT_NO_UNDOGROUP
471 Q_D(QUndoStack);
472 if (d->group != 0)
473 d->group->removeStack(this);
474#endif
475 clear();
476}
477
478/*!
479 Clears the command stack by deleting all commands on it, and returns the stack
480 to the clean state.
481
482 Commands are not undone or redone; the state of the edited object remains
483 unchanged.
484
485 This function is usually used when the contents of the document are
486 abandoned.
487
488 \sa QUndoStack()
489*/
490
491void QUndoStack::clear()
492{
493 Q_D(QUndoStack);
494
495 if (d->command_list.isEmpty())
496 return;
497
498 bool was_clean = isClean();
499
500 d->macro_stack.clear();
501 qDeleteAll(d->command_list);
502 d->command_list.clear();
503
504 d->index = 0;
505 d->clean_index = 0;
506
507 emit indexChanged(0);
508 emit canUndoChanged(false);
509 emit undoTextChanged(QString());
510 emit canRedoChanged(false);
511 emit redoTextChanged(QString());
512
513 if (!was_clean)
514 emit cleanChanged(true);
515}
516
517/*!
518 Pushes \a cmd on the stack or merges it with the most recently executed command.
519 In either case, executes \a cmd by calling its redo() function.
520
521 If \a cmd's id is not -1, and if the id is the same as that of the
522 most recently executed command, QUndoStack will attempt to merge the two
523 commands by calling QUndoCommand::mergeWith() on the most recently executed
524 command. If QUndoCommand::mergeWith() returns true, \a cmd is deleted.
525
526 In all other cases \a cmd is simply pushed on the stack.
527
528 If commands were undone before \a cmd was pushed, the current command and
529 all commands above it are deleted. Hence \a cmd always ends up being the
530 top-most on the stack.
531
532 Once a command is pushed, the stack takes ownership of it. There
533 are no getters to return the command, since modifying it after it has
534 been executed will almost always lead to corruption of the document's
535 state.
536
537 \sa QUndoCommand::id() QUndoCommand::mergeWith()
538*/
539
540void QUndoStack::push(QUndoCommand *cmd)
541{
542 Q_D(QUndoStack);
543 cmd->redo();
544
545 bool macro = !d->macro_stack.isEmpty();
546
547 QUndoCommand *cur = 0;
548 if (macro) {
549 QUndoCommand *macro_cmd = d->macro_stack.last();
550 if (!macro_cmd->d->child_list.isEmpty())
551 cur = macro_cmd->d->child_list.last();
552 } else {
553 if (d->index > 0)
554 cur = d->command_list.at(d->index - 1);
555 while (d->index < d->command_list.size())
556 delete d->command_list.takeLast();
557 if (d->clean_index > d->index)
558 d->clean_index = -1; // we've deleted the clean state
559 }
560
561 bool try_merge = cur != 0
562 && cur->id() != -1
563 && cur->id() == cmd->id()
564 && (macro || d->index != d->clean_index);
565
566 if (try_merge && cur->mergeWith(cmd)) {
567 delete cmd;
568 if (!macro) {
569 emit indexChanged(d->index);
570 emit canUndoChanged(canUndo());
571 emit undoTextChanged(undoText());
572 emit canRedoChanged(canRedo());
573 emit redoTextChanged(redoText());
574 }
575 } else {
576 if (macro) {
577 d->macro_stack.last()->d->child_list.append(cmd);
578 } else {
579 d->command_list.append(cmd);
580 d->checkUndoLimit();
581 d->setIndex(d->index + 1, false);
582 }
583 }
584}
585
586/*!
587 Marks the stack as clean and emits cleanChanged() if the stack was
588 not already clean.
589
590 Whenever the stack returns to this state through the use of undo/redo
591 commands, it emits the signal cleanChanged(). This signal is also
592 emitted when the stack leaves the clean state.
593
594 \sa isClean(), cleanIndex()
595*/
596
597void QUndoStack::setClean()
598{
599 Q_D(QUndoStack);
600 if (!d->macro_stack.isEmpty()) {
601 qWarning("QUndoStack::setClean(): cannot set clean in the middle of a macro");
602 return;
603 }
604
605 d->setIndex(d->index, true);
606}
607
608/*!
609 If the stack is in the clean state, returns true; otherwise returns false.
610
611 \sa setClean() cleanIndex()
612*/
613
614bool QUndoStack::isClean() const
615{
616 Q_D(const QUndoStack);
617 if (!d->macro_stack.isEmpty())
618 return false;
619 return d->clean_index == d->index;
620}
621
622/*!
623 Returns the clean index. This is the index at which setClean() was called.
624
625 A stack may not have a clean index. This happens if a document is saved,
626 some commands are undone, then a new command is pushed. Since
627 push() deletes all the undone commands before pushing the new command, the stack
628 can't return to the clean state again. In this case, this function returns -1.
629
630 \sa isClean() setClean()
631*/
632
633int QUndoStack::cleanIndex() const
634{
635 Q_D(const QUndoStack);
636 return d->clean_index;
637}
638
639/*!
640 Undoes the command below the current command by calling QUndoCommand::undo().
641 Decrements the current command index.
642
643 If the stack is empty, or if the bottom command on the stack has already been
644 undone, this function does nothing.
645
646 \sa redo() index()
647*/
648
649void QUndoStack::undo()
650{
651 Q_D(QUndoStack);
652 if (d->index == 0)
653 return;
654
655 if (!d->macro_stack.isEmpty()) {
656 qWarning("QUndoStack::undo(): cannot undo in the middle of a macro");
657 return;
658 }
659
660 int idx = d->index - 1;
661 d->command_list.at(idx)->undo();
662 d->setIndex(idx, false);
663}
664
665/*!
666 Redoes the current command by calling QUndoCommand::redo(). Increments the current
667 command index.
668
669 If the stack is empty, or if the top command on the stack has already been
670 redone, this function does nothing.
671
672 \sa undo() index()
673*/
674
675void QUndoStack::redo()
676{
677 Q_D(QUndoStack);
678 if (d->index == d->command_list.size())
679 return;
680
681 if (!d->macro_stack.isEmpty()) {
682 qWarning("QUndoStack::redo(): cannot redo in the middle of a macro");
683 return;
684 }
685
686 d->command_list.at(d->index)->redo();
687 d->setIndex(d->index + 1, false);
688}
689
690/*!
691 Returns the number of commands on the stack. Macro commands are counted as
692 one command.
693
694 \sa index() setIndex() command()
695*/
696
697int QUndoStack::count() const
698{
699 Q_D(const QUndoStack);
700 return d->command_list.size();
701}
702
703/*!
704 Returns the index of the current command. This is the command that will be
705 executed on the next call to redo(). It is not always the top-most command
706 on the stack, since a number of commands may have been undone.
707
708 \sa undo() redo() count()
709*/
710
711int QUndoStack::index() const
712{
713 Q_D(const QUndoStack);
714 return d->index;
715}
716
717/*!
718 Repeatedly calls undo() or redo() until the the current command index reaches
719 \a idx. This function can be used to roll the state of the document forwards
720 of backwards. indexChanged() is emitted only once.
721
722 \sa index() count() undo() redo()
723*/
724
725void QUndoStack::setIndex(int idx)
726{
727 Q_D(QUndoStack);
728 if (!d->macro_stack.isEmpty()) {
729 qWarning("QUndoStack::setIndex(): cannot set index in the middle of a macro");
730 return;
731 }
732
733 if (idx < 0)
734 idx = 0;
735 else if (idx > d->command_list.size())
736 idx = d->command_list.size();
737
738 int i = d->index;
739 while (i < idx)
740 d->command_list.at(i++)->redo();
741 while (i > idx)
742 d->command_list.at(--i)->undo();
743
744 d->setIndex(idx, false);
745}
746
747/*!
748 Returns true if there is a command available for undo; otherwise returns false.
749
750 This function returns false if the stack is empty, or if the bottom command
751 on the stack has already been undone.
752
753 Synonymous with index() == 0.
754
755 \sa index() canRedo()
756*/
757
758bool QUndoStack::canUndo() const
759{
760 Q_D(const QUndoStack);
761 if (!d->macro_stack.isEmpty())
762 return false;
763 return d->index > 0;
764}
765
766/*!
767 Returns true if there is a command available for redo; otherwise returns false.
768
769 This function returns false if the stack is empty or if the top command
770 on the stack has already been redone.
771
772 Synonymous with index() == count().
773
774 \sa index() canUndo()
775*/
776
777bool QUndoStack::canRedo() const
778{
779 Q_D(const QUndoStack);
780 if (!d->macro_stack.isEmpty())
781 return false;
782 return d->index < d->command_list.size();
783}
784
785/*!
786 Returns the text of the command which will be undone in the next call to undo().
787
788 \sa QUndoCommand::text() redoText()
789*/
790
791QString QUndoStack::undoText() const
792{
793 Q_D(const QUndoStack);
794 if (!d->macro_stack.isEmpty())
795 return QString();
796 if (d->index > 0)
797 return d->command_list.at(d->index - 1)->text();
798 return QString();
799}
800
801/*!
802 Returns the text of the command which will be redone in the next call to redo().
803
804 \sa QUndoCommand::text() undoText()
805*/
806
807QString QUndoStack::redoText() const
808{
809 Q_D(const QUndoStack);
810 if (!d->macro_stack.isEmpty())
811 return QString();
812 if (d->index < d->command_list.size())
813 return d->command_list.at(d->index)->text();
814 return QString();
815}
816
817#ifndef QT_NO_ACTION
818
819/*!
820 Creates an undo QAction object with the given \a parent.
821
822 Triggering this action will cause a call to undo(). The text of this action
823 is the text of the command which will be undone in the next call to undo(),
824 prefixed by the specified \a prefix. If there is no command available for undo,
825 this action will be disabled.
826
827 If \a prefix is empty, the default prefix "Undo" is used.
828
829 \sa createRedoAction(), canUndo(), QUndoCommand::text()
830*/
831
832QAction *QUndoStack::createUndoAction(QObject *parent, const QString &prefix) const
833{
834 QString pref = prefix.isEmpty() ? tr("Undo") : prefix;
835 QUndoAction *result = new QUndoAction(pref, parent);
836 result->setEnabled(canUndo());
837 result->setPrefixedText(undoText());
838 connect(this, SIGNAL(canUndoChanged(bool)),
839 result, SLOT(setEnabled(bool)));
840 connect(this, SIGNAL(undoTextChanged(QString)),
841 result, SLOT(setPrefixedText(QString)));
842 connect(result, SIGNAL(triggered()), this, SLOT(undo()));
843 return result;
844}
845
846/*!
847 Creates an redo QAction object with the given \a parent.
848
849 Triggering this action will cause a call to redo(). The text of this action
850 is the text of the command which will be redone in the next call to redo(),
851 prefixed by the specified \a prefix. If there is no command available for redo,
852 this action will be disabled.
853
854 If \a prefix is empty, the default prefix "Redo" is used.
855
856 \sa createUndoAction(), canRedo(), QUndoCommand::text()
857*/
858
859QAction *QUndoStack::createRedoAction(QObject *parent, const QString &prefix) const
860{
861 QString pref = prefix.isEmpty() ? tr("Redo") : prefix;
862 QUndoAction *result = new QUndoAction(pref, parent);
863 result->setEnabled(canRedo());
864 result->setPrefixedText(redoText());
865 connect(this, SIGNAL(canRedoChanged(bool)),
866 result, SLOT(setEnabled(bool)));
867 connect(this, SIGNAL(redoTextChanged(QString)),
868 result, SLOT(setPrefixedText(QString)));
869 connect(result, SIGNAL(triggered()), this, SLOT(redo()));
870 return result;
871}
872
873#endif // QT_NO_ACTION
874
875/*!
876 Begins composition of a macro command with the given \a text description.
877
878 An empty command described by the specified \a text is pushed on the stack.
879 Any subsequent commands pushed on the stack will be appended to the empty
880 command's children until endMacro() is called.
881
882 Calls to beginMacro() and endMacro() may be nested, but every call to
883 beginMacro() must have a matching call to endMacro().
884
885 While a macro is composed, the stack is disabled. This means that:
886 \list
887 \i indexChanged() and cleanChanged() are not emitted,
888 \i canUndo() and canRedo() return false,
889 \i calling undo() or redo() has no effect,
890 \i the undo/redo actions are disabled.
891 \endlist
892
893 The stack becomes enabled and appropriate signals are emitted when endMacro()
894 is called for the outermost macro.
895
896 \snippet doc/src/snippets/code/src_gui_util_qundostack.cpp 4
897
898 This code is equivalent to:
899
900 \snippet doc/src/snippets/code/src_gui_util_qundostack.cpp 5
901
902 \sa endMacro()
903*/
904
905void QUndoStack::beginMacro(const QString &text)
906{
907 Q_D(QUndoStack);
908 QUndoCommand *cmd = new QUndoCommand();
909 cmd->setText(text);
910
911 if (d->macro_stack.isEmpty()) {
912 while (d->index < d->command_list.size())
913 delete d->command_list.takeLast();
914 if (d->clean_index > d->index)
915 d->clean_index = -1; // we've deleted the clean state
916 d->command_list.append(cmd);
917 } else {
918 d->macro_stack.last()->d->child_list.append(cmd);
919 }
920 d->macro_stack.append(cmd);
921
922 if (d->macro_stack.count() == 1) {
923 emit canUndoChanged(false);
924 emit undoTextChanged(QString());
925 emit canRedoChanged(false);
926 emit redoTextChanged(QString());
927 }
928}
929
930/*!
931 Ends composition of a macro command.
932
933 If this is the outermost macro in a set nested macros, this function emits
934 indexChanged() once for the entire macro command.
935
936 \sa beginMacro()
937*/
938
939void QUndoStack::endMacro()
940{
941 Q_D(QUndoStack);
942 if (d->macro_stack.isEmpty()) {
943 qWarning("QUndoStack::endMacro(): no matching beginMacro()");
944 return;
945 }
946
947 d->macro_stack.removeLast();
948
949 if (d->macro_stack.isEmpty()) {
950 d->checkUndoLimit();
951 d->setIndex(d->index + 1, false);
952 }
953}
954
955/*!
956 \since 4.4
957
958 Returns a const pointer to the command at \a index.
959
960 This function returns a const pointer, because modifying a command,
961 once it has been pushed onto the stack and executed, almost always
962 causes corruption of the state of the document, if the command is
963 later undone or redone.
964
965 \sa QUndoCommand::child()
966*/
967const QUndoCommand *QUndoStack::command(int index) const
968{
969 Q_D(const QUndoStack);
970
971 if (index < 0 || index >= d->command_list.count())
972 return 0;
973 return d->command_list.at(index);
974}
975
976/*!
977 Returns the text of the command at index \a idx.
978
979 \sa beginMacro()
980*/
981
982QString QUndoStack::text(int idx) const
983{
984 Q_D(const QUndoStack);
985
986 if (idx < 0 || idx >= d->command_list.size())
987 return QString();
988 return d->command_list.at(idx)->text();
989}
990
991/*!
992 \property QUndoStack::undoLimit
993 \brief the maximum number of commands on this stack.
994 \since 4.3
995
996 When the number of commands on a stack exceedes the stack's undoLimit, commands are
997 deleted from the bottom of the stack. Macro commands (commands with child commands)
998 are treated as one command. The default value is 0, which means that there is no
999 limit.
1000
1001 This property may only be set when the undo stack is empty, since setting it on a
1002 non-empty stack might delete the command at the current index. Calling setUndoLimit()
1003 on a non-empty stack prints a warning and does nothing.
1004*/
1005
1006void QUndoStack::setUndoLimit(int limit)
1007{
1008 Q_D(QUndoStack);
1009
1010 if (!d->command_list.isEmpty()) {
1011 qWarning("QUndoStack::setUndoLimit(): an undo limit can only be set when the stack is empty");
1012 return;
1013 }
1014
1015 if (limit == d->undo_limit)
1016 return;
1017 d->undo_limit = limit;
1018 d->checkUndoLimit();
1019}
1020
1021int QUndoStack::undoLimit() const
1022{
1023 Q_D(const QUndoStack);
1024
1025 return d->undo_limit;
1026}
1027
1028/*!
1029 \property QUndoStack::active
1030 \brief the active status of this stack.
1031
1032 An application often has multiple undo stacks, one for each opened document. The active
1033 stack is the one associated with the currently active document. If the stack belongs
1034 to a QUndoGroup, calls to QUndoGroup::undo() or QUndoGroup::redo() will be forwarded
1035 to this stack when it is active. If the QUndoGroup is watched by a QUndoView, the view
1036 will display the contents of this stack when it is active. If the stack does not belong to
1037 a QUndoGroup, making it active has no effect.
1038
1039 It is the programmer's responsibility to specify which stack is active by
1040 calling setActive(), usually when the associated document window receives focus.
1041
1042 \sa QUndoGroup
1043*/
1044
1045void QUndoStack::setActive(bool active)
1046{
1047#ifdef QT_NO_UNDOGROUP
1048 Q_UNUSED(active);
1049#else
1050 Q_D(QUndoStack);
1051
1052 if (d->group != 0) {
1053 if (active)
1054 d->group->setActiveStack(this);
1055 else if (d->group->activeStack() == this)
1056 d->group->setActiveStack(0);
1057 }
1058#endif
1059}
1060
1061bool QUndoStack::isActive() const
1062{
1063#ifdef QT_NO_UNDOGROUP
1064 return true;
1065#else
1066 Q_D(const QUndoStack);
1067 return d->group == 0 || d->group->activeStack() == this;
1068#endif
1069}
1070
1071/*!
1072 \fn void QUndoStack::indexChanged(int idx)
1073
1074 This signal is emitted whenever a command modifies the state of the document.
1075 This happens when a command is undone or redone. When a macro
1076 command is undone or redone, or setIndex() is called, this signal
1077 is emitted only once.
1078
1079 \a idx specifies the index of the current command, ie. the command which will be
1080 executed on the next call to redo().
1081
1082 \sa index() setIndex()
1083*/
1084
1085/*!
1086 \fn void QUndoStack::cleanChanged(bool clean)
1087
1088 This signal is emitted whenever the stack enters or leaves the clean state.
1089 If \a clean is true, the stack is in a clean state; otherwise this signal
1090 indicates that it has left the clean state.
1091
1092 \sa isClean() setClean()
1093*/
1094
1095/*!
1096 \fn void QUndoStack::undoTextChanged(const QString &undoText)
1097
1098 This signal is emitted whenever the value of undoText() changes. It is
1099 used to update the text property of the undo action returned by createUndoAction().
1100 \a undoText specifies the new text.
1101*/
1102
1103/*!
1104 \fn void QUndoStack::canUndoChanged(bool canUndo)
1105
1106 This signal is emitted whenever the value of canUndo() changes. It is
1107 used to enable or disable the undo action returned by createUndoAction().
1108 \a canUndo specifies the new value.
1109*/
1110
1111/*!
1112 \fn void QUndoStack::redoTextChanged(const QString &redoText)
1113
1114 This signal is emitted whenever the value of redoText() changes. It is
1115 used to update the text property of the redo action returned by createRedoAction().
1116 \a redoText specifies the new text.
1117*/
1118
1119/*!
1120 \fn void QUndoStack::canRedoChanged(bool canRedo)
1121
1122 This signal is emitted whenever the value of canRedo() changes. It is
1123 used to enable or disable the redo action returned by createRedoAction().
1124 \a canRedo specifies the new value.
1125*/
1126
1127QT_END_NAMESPACE
1128
1129#endif // QT_NO_UNDOSTACK
Note: See TracBrowser for help on using the repository browser.