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