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

Last change on this file 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()