qundostack.cpp

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

Generated by Squish Coco Non-Commercial 4.3.0-BETA-master-30-08-2018-4cb69e9