OpenCoverage

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

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