source: trunk/src/gui/util/qundogroup.cpp@ 1168

Last change on this file since 1168 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 15.3 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtGui module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qundogroup.h"
43#include "qundostack.h"
44#include "qundostack_p.h"
45
46#ifndef QT_NO_UNDOGROUP
47
48QT_BEGIN_NAMESPACE
49
50class QUndoGroupPrivate : public QObjectPrivate
51{
52 Q_DECLARE_PUBLIC(QUndoGroup)
53public:
54 QUndoGroupPrivate() : active(0) {}
55
56 QUndoStack *active;
57 QList<QUndoStack*> stack_list;
58};
59
60/*!
61 \class QUndoGroup
62 \brief The QUndoGroup class is a group of QUndoStack objects.
63 \since 4.2
64
65 For an overview of the Qt's undo framework, see the
66 \link qundo.html overview\endlink.
67
68 An application often has multiple undo stacks, one for each opened document. At the
69 same time, an application usually has one undo action and one redo action, which
70 triggers undo or redo in the active document.
71
72 QUndoGroup is a group of QUndoStack objects, one of which may be active. It has
73 an undo() and redo() slot, which calls QUndoStack::undo() and QUndoStack::redo()
74 for the active stack. It also has the functions createUndoAction() and createRedoAction().
75 The actions returned by these functions behave in the same way as those returned by
76 QUndoStack::createUndoAction() and QUndoStack::createRedoAction() of the active
77 stack.
78
79 Stacks are added to a group with addStack() and removed with removeStack(). A stack
80 is implicitly added to a group when it is created with the group as its parent
81 QObject.
82
83 It is the programmer's responsibility to specify which stack is active by
84 calling QUndoStack::setActive(), usually when the associated document window receives focus.
85 The active stack may also be set with setActiveStack(), and is returned by activeStack().
86
87 When a stack is added to a group using addStack(), the group does not take ownership
88 of the stack. This means the stack has to be deleted separately from the group. When
89 a stack is deleted, it is automatically removed from a group. A stack may belong to
90 only one group. Adding it to another group will cause it to be removed from the previous
91 group.
92
93 A QUndoGroup is also useful in conjunction with QUndoView. If a QUndoView is
94 set to watch a group using QUndoView::setGroup(), it will update itself to display
95 the active stack.
96*/
97
98/*!
99 Creates an empty QUndoGroup object with parent \a parent.
100
101 \sa addStack()
102*/
103
104QUndoGroup::QUndoGroup(QObject *parent)
105 : QObject(*new QUndoGroupPrivate(), parent)
106{
107}
108
109/*!
110 Destroys the QUndoGroup.
111*/
112QUndoGroup::~QUndoGroup()
113{
114 // Ensure all QUndoStacks no longer refer to this group.
115 Q_D(QUndoGroup);
116 QList<QUndoStack *>::iterator it = d->stack_list.begin();
117 QList<QUndoStack *>::iterator end = d->stack_list.end();
118 while (it != end) {
119 (*it)->d_func()->group = 0;
120 ++it;
121 }
122}
123
124/*!
125 Adds \a stack to this group. The group does not take ownership of the stack. Another
126 way of adding a stack to a group is by specifying the group as the stack's parent
127 QObject in QUndoStack::QUndoStack(). In this case, the stack is deleted when the
128 group is deleted, in the usual manner of QObjects.
129
130 \sa removeStack() stacks() QUndoStack::QUndoStack()
131*/
132
133void QUndoGroup::addStack(QUndoStack *stack)
134{
135 Q_D(QUndoGroup);
136
137 if (d->stack_list.contains(stack))
138 return;
139 d->stack_list.append(stack);
140
141 if (QUndoGroup *other = stack->d_func()->group)
142 other->removeStack(stack);
143 stack->d_func()->group = this;
144}
145
146/*!
147 Removes \a stack from this group. If the stack was the active stack in the group,
148 the active stack becomes 0.
149
150 \sa addStack() stacks() QUndoStack::~QUndoStack()
151*/
152
153void QUndoGroup::removeStack(QUndoStack *stack)
154{
155 Q_D(QUndoGroup);
156
157 if (d->stack_list.removeAll(stack) == 0)
158 return;
159 if (stack == d->active)
160 setActiveStack(0);
161 stack->d_func()->group = 0;
162}
163
164/*!
165 Returns a list of stacks in this group.
166
167 \sa addStack() removeStack()
168*/
169
170QList<QUndoStack*> QUndoGroup::stacks() const
171{
172 Q_D(const QUndoGroup);
173 return d->stack_list;
174}
175
176/*!
177 Sets the active stack of this group to \a stack.
178
179 If the stack is not a member of this group, this function does nothing.
180
181 Synonymous with calling QUndoStack::setActive() on \a stack.
182
183 The actions returned by createUndoAction() and createRedoAction() will now behave
184 in the same way as those returned by \a stack's QUndoStack::createUndoAction()
185 and QUndoStack::createRedoAction().
186
187 \sa QUndoStack::setActive() activeStack()
188*/
189
190void QUndoGroup::setActiveStack(QUndoStack *stack)
191{
192 Q_D(QUndoGroup);
193 if (d->active == stack)
194 return;
195
196 if (d->active != 0) {
197 disconnect(d->active, SIGNAL(canUndoChanged(bool)),
198 this, SIGNAL(canUndoChanged(bool)));
199 disconnect(d->active, SIGNAL(undoTextChanged(QString)),
200 this, SIGNAL(undoTextChanged(QString)));
201 disconnect(d->active, SIGNAL(canRedoChanged(bool)),
202 this, SIGNAL(canRedoChanged(bool)));
203 disconnect(d->active, SIGNAL(redoTextChanged(QString)),
204 this, SIGNAL(redoTextChanged(QString)));
205 disconnect(d->active, SIGNAL(indexChanged(int)),
206 this, SIGNAL(indexChanged(int)));
207 disconnect(d->active, SIGNAL(cleanChanged(bool)),
208 this, SIGNAL(cleanChanged(bool)));
209 }
210
211 d->active = stack;
212
213 if (d->active == 0) {
214 emit canUndoChanged(false);
215 emit undoTextChanged(QString());
216 emit canRedoChanged(false);
217 emit redoTextChanged(QString());
218 emit cleanChanged(true);
219 emit indexChanged(0);
220 } else {
221 connect(d->active, SIGNAL(canUndoChanged(bool)),
222 this, SIGNAL(canUndoChanged(bool)));
223 connect(d->active, SIGNAL(undoTextChanged(QString)),
224 this, SIGNAL(undoTextChanged(QString)));
225 connect(d->active, SIGNAL(canRedoChanged(bool)),
226 this, SIGNAL(canRedoChanged(bool)));
227 connect(d->active, SIGNAL(redoTextChanged(QString)),
228 this, SIGNAL(redoTextChanged(QString)));
229 connect(d->active, SIGNAL(indexChanged(int)),
230 this, SIGNAL(indexChanged(int)));
231 connect(d->active, SIGNAL(cleanChanged(bool)),
232 this, SIGNAL(cleanChanged(bool)));
233 emit canUndoChanged(d->active->canUndo());
234 emit undoTextChanged(d->active->undoText());
235 emit canRedoChanged(d->active->canRedo());
236 emit redoTextChanged(d->active->redoText());
237 emit cleanChanged(d->active->isClean());
238 emit indexChanged(d->active->index());
239 }
240
241 emit activeStackChanged(d->active);
242}
243
244/*!
245 Returns the active stack of this group.
246
247 If none of the stacks are active, or if the group is empty, this function
248 returns 0.
249
250 \sa setActiveStack() QUndoStack::setActive()
251*/
252
253QUndoStack *QUndoGroup::activeStack() const
254{
255 Q_D(const QUndoGroup);
256 return d->active;
257}
258
259/*!
260 Calls QUndoStack::undo() on the active stack.
261
262 If none of the stacks are active, or if the group is empty, this function
263 does nothing.
264
265 \sa redo() canUndo() setActiveStack()
266*/
267
268void QUndoGroup::undo()
269{
270 Q_D(QUndoGroup);
271 if (d->active != 0)
272 d->active->undo();
273}
274
275/*!
276 Calls QUndoStack::redo() on the active stack.
277
278 If none of the stacks are active, or if the group is empty, this function
279 does nothing.
280
281 \sa undo() canRedo() setActiveStack()
282*/
283
284
285void QUndoGroup::redo()
286{
287 Q_D(QUndoGroup);
288 if (d->active != 0)
289 d->active->redo();
290}
291
292/*!
293 Returns the value of the active stack's QUndoStack::canUndo().
294
295 If none of the stacks are active, or if the group is empty, this function
296 returns false.
297
298 \sa canRedo() setActiveStack()
299*/
300
301bool QUndoGroup::canUndo() const
302{
303 Q_D(const QUndoGroup);
304 return d->active != 0 && d->active->canUndo();
305}
306
307/*!
308 Returns the value of the active stack's QUndoStack::canRedo().
309
310 If none of the stacks are active, or if the group is empty, this function
311 returns false.
312
313 \sa canUndo() setActiveStack()
314*/
315
316bool QUndoGroup::canRedo() const
317{
318 Q_D(const QUndoGroup);
319 return d->active != 0 && d->active->canRedo();
320}
321
322/*!
323 Returns the value of the active stack's QUndoStack::undoText().
324
325 If none of the stacks are active, or if the group is empty, this function
326 returns an empty string.
327
328 \sa redoText() setActiveStack()
329*/
330
331QString QUndoGroup::undoText() const
332{
333 Q_D(const QUndoGroup);
334 return d->active == 0 ? QString() : d->active->undoText();
335}
336
337/*!
338 Returns the value of the active stack's QUndoStack::redoText().
339
340 If none of the stacks are active, or if the group is empty, this function
341 returns an empty string.
342
343 \sa undoText() setActiveStack()
344*/
345
346QString QUndoGroup::redoText() const
347{
348 Q_D(const QUndoGroup);
349 return d->active == 0 ? QString() : d->active->redoText();
350}
351
352/*!
353 Returns the value of the active stack's QUndoStack::isClean().
354
355 If none of the stacks are active, or if the group is empty, this function
356 returns true.
357
358 \sa setActiveStack()
359*/
360
361bool QUndoGroup::isClean() const
362{
363 Q_D(const QUndoGroup);
364 return d->active == 0 || d->active->isClean();
365}
366
367#ifndef QT_NO_ACTION
368
369/*!
370 Creates an undo QAction object with parent \a parent.
371
372 Triggering this action will cause a call to QUndoStack::undo() on the active stack.
373 The text of this action will always be the text of the command which will be undone
374 in the next call to undo(), prefixed by \a prefix. If there is no command available
375 for undo, if the group is empty or if none of the stacks are active, this action will
376 be disabled.
377
378 If \a prefix is empty, the default prefix "Undo" is used.
379
380 \sa createRedoAction() canUndo() QUndoCommand::text()
381*/
382
383QAction *QUndoGroup::createUndoAction(QObject *parent, const QString &prefix) const
384{
385 QString pref = prefix.isEmpty() ? tr("Undo") : prefix;
386 QUndoAction *result = new QUndoAction(pref, parent);
387 result->setEnabled(canUndo());
388 result->setPrefixedText(undoText());
389 connect(this, SIGNAL(canUndoChanged(bool)),
390 result, SLOT(setEnabled(bool)));
391 connect(this, SIGNAL(undoTextChanged(QString)),
392 result, SLOT(setPrefixedText(QString)));
393 connect(result, SIGNAL(triggered()), this, SLOT(undo()));
394 return result;
395}
396
397/*!
398 Creates an redo QAction object with parent \a parent.
399
400 Triggering this action will cause a call to QUndoStack::redo() on the active stack.
401 The text of this action will always be the text of the command which will be redone
402 in the next call to redo(), prefixed by \a prefix. If there is no command available
403 for redo, if the group is empty or if none of the stacks are active, this action will
404 be disabled.
405
406 If \a prefix is empty, the default prefix "Undo" is used.
407
408 \sa createUndoAction() canRedo() QUndoCommand::text()
409*/
410
411QAction *QUndoGroup::createRedoAction(QObject *parent, const QString &prefix) const
412{
413 QString pref = prefix.isEmpty() ? tr("Redo") : prefix;
414 QUndoAction *result = new QUndoAction(pref, parent);
415 result->setEnabled(canRedo());
416 result->setPrefixedText(redoText());
417 connect(this, SIGNAL(canRedoChanged(bool)),
418 result, SLOT(setEnabled(bool)));
419 connect(this, SIGNAL(redoTextChanged(QString)),
420 result, SLOT(setPrefixedText(QString)));
421 connect(result, SIGNAL(triggered()), this, SLOT(redo()));
422 return result;
423}
424
425#endif // QT_NO_ACTION
426
427/*! \fn void QUndoGroup::activeStackChanged(QUndoStack *stack)
428
429 This signal is emitted whenever the active stack of the group changes. This can happen
430 when setActiveStack() or QUndoStack::setActive() is called, or when the active stack
431 is removed form the group. \a stack is the new active stack. If no stack is active,
432 \a stack is 0.
433
434 \sa setActiveStack() QUndoStack::setActive()
435*/
436
437/*! \fn void QUndoGroup::indexChanged(int idx)
438
439 This signal is emitted whenever the active stack emits QUndoStack::indexChanged()
440 or the active stack changes.
441
442 \a idx is the new current index, or 0 if the active stack is 0.
443
444 \sa QUndoStack::indexChanged() setActiveStack()
445*/
446
447/*! \fn void QUndoGroup::cleanChanged(bool clean)
448
449 This signal is emitted whenever the active stack emits QUndoStack::cleanChanged()
450 or the active stack changes.
451
452 \a clean is the new state, or true if the active stack is 0.
453
454 \sa QUndoStack::cleanChanged() setActiveStack()
455*/
456
457/*! \fn void QUndoGroup::canUndoChanged(bool canUndo)
458
459 This signal is emitted whenever the active stack emits QUndoStack::canUndoChanged()
460 or the active stack changes.
461
462 \a canUndo is the new state, or false if the active stack is 0.
463
464 \sa QUndoStack::canUndoChanged() setActiveStack()
465*/
466
467/*! \fn void QUndoGroup::canRedoChanged(bool canRedo)
468
469 This signal is emitted whenever the active stack emits QUndoStack::canRedoChanged()
470 or the active stack changes.
471
472 \a canRedo is the new state, or false if the active stack is 0.
473
474 \sa QUndoStack::canRedoChanged() setActiveStack()
475*/
476
477/*! \fn void QUndoGroup::undoTextChanged(const QString &undoText)
478
479 This signal is emitted whenever the active stack emits QUndoStack::undoTextChanged()
480 or the active stack changes.
481
482 \a undoText is the new state, or an empty string if the active stack is 0.
483
484 \sa QUndoStack::undoTextChanged() setActiveStack()
485*/
486
487/*! \fn void QUndoGroup::redoTextChanged(const QString &redoText)
488
489 This signal is emitted whenever the active stack emits QUndoStack::redoTextChanged()
490 or the active stack changes.
491
492 \a redoText is the new state, or an empty string if the active stack is 0.
493
494 \sa QUndoStack::redoTextChanged() setActiveStack()
495*/
496
497QT_END_NAMESPACE
498
499#endif // QT_NO_UNDOGROUP
Note: See TracBrowser for help on using the repository browser.