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