source: trunk/doc/src/examples/undoframework.qdoc@ 651

Last change on this file since 651 was 651, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.2 sources.

File size: 11.5 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2010 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 documentation 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/*!
43 \example tools/undoframework
44 \title Undo Framework Example
45
46 This example shows how to implement undo/redo functionality
47 with the Qt undo framework.
48
49 \image undoframeworkexample.png The Undo Diagram Example
50
51 In the Qt undo framework, all actions that the user performs are
52 implemented in classes that inherit QUndoCommand. An undo command
53 class knows how to both \l{QUndoCommand::}{redo()} - or just do
54 the first time - and \l{QUndoCommand::}{undo()} an action. For
55 each action the user performs, a command is placed on a
56 QUndoStack. Since the stack contains all commands executed
57 (stacked in chronological order) on the document, it can roll the
58 state of the document backwards and forwards by undoing and redoing
59 its commands. See the \l{Overview of Qt's Undo Framework}{overview
60 document} for a high-level introduction to the undo framework.
61
62 The undo example implements a simple diagram application. It is
63 possible to add and delete items, which are either box or
64 rectangular shaped, and move the items by dragging them with the
65 mouse. The undo stack is shown in a QUndoView, which is a list in
66 which the commands are shown as list items. Undo and redo are
67 available through the edit menu. The user can also select a command
68 from the undo view.
69
70 We use the \l{The Graphics View Framework}{graphics view
71 framework} to implement the diagram. We only treat the related
72 code briefly as the framework has examples of its own (e.g., the
73 \l{Diagram Scene Example}).
74
75 The example consists of the following classes:
76
77 \list
78 \o \c MainWindow is the main window and arranges the
79 example's widgets. It creates the commands based
80 on user input and keeps them on the command stack.
81 \o \c AddCommand adds an item to the scene.
82 \o \c DeleteCommand deletes an item from the scene.
83 \o \c MoveCommand when an item is moved the MoveCommand keeps record
84 of the start and stop positions of the move, and it
85 moves the item according to these when \c redo() and \c undo()
86 is called.
87 \o \c DiagramScene inherits QGraphicsScene and
88 emits signals for the \c MoveComands when an item is moved.
89 \o \c DiagramItem inherits QGraphicsPolygonItem and represents
90 an item in the diagram.
91 \endlist
92
93 \section1 MainWindow Class Definition
94
95 \snippet examples/tools/undoframework/mainwindow.h 0
96
97 The \c MainWindow class maintains the undo stack, i.e., it creates
98 \l{QUndoCommand}s and pushes and pops them from the stack when it
99 receives the \c triggered() signal from \c undoAction and \c
100 redoAction.
101
102 \section1 MainWindow Class Implementation
103
104 We will start with a look at the constructor:
105
106 \snippet examples/tools/undoframework/mainwindow.cpp 0
107
108 In the constructor, we set up the DiagramScene and QGraphicsView.
109
110 Here is the \c createUndoView() function:
111
112 \snippet examples/tools/undoframework/mainwindow.cpp 1
113
114 The QUndoView is a widget that display the text, which is set with
115 the \l{QUndoCommand::}{setText()} function, for each QUndoCommand
116 in the undo stack in a list.
117
118 Here is the \c createActions() function:
119
120 \snippet examples/tools/undoframework/mainwindow.cpp 2
121 \codeline
122 \snippet examples/tools/undoframework/mainwindow.cpp 3
123 \dots
124 \snippet examples/tools/undoframework/mainwindow.cpp 5
125
126 The \c createActions() function sets up all the examples actions
127 in the manner shown above. The
128 \l{QUndoStack::}{createUndoAction()} and
129 \l{QUndoStack::}{createRedoAction()} helps us crate actions that
130 are disabled and enabled based on the state of the stack. Also,
131 the text of the action will be updated automatically based on the
132 \l{QUndoCommand::}{text()} of the undo commands. For the other
133 actions we have implemented slots in the \c MainWindow class.
134
135 Here is the \c createMenus() function:
136
137 \snippet examples/tools/undoframework/mainwindow.cpp 6
138
139 \dots
140 \snippet examples/tools/undoframework/mainwindow.cpp 7
141 \dots
142 \snippet examples/tools/undoframework/mainwindow.cpp 8
143
144 We have to use the QMenu \c aboutToShow() and \c aboutToHide()
145 signals since we only want \c deleteAction to be enabled when we
146 have selected an item.
147
148 Here is the \c itemMoved() slot:
149
150 \snippet examples/tools/undoframework/mainwindow.cpp 9
151
152 We simply push a MoveCommand on the stack, which calls \c redo()
153 on it.
154
155 Here is the \c deleteItem() slot:
156
157 \snippet examples/tools/undoframework/mainwindow.cpp 10
158
159 An item must be selected to be deleted. We need to check if it is
160 selected as the \c deleteAction may be enabled even if an item is
161 not selected. This can happen as we do not catch a signal or event
162 when an item is selected.
163
164 Here is the \c itemMenuAboutToShow() and itemMenuAboutToHide() slots:
165
166 \snippet examples/tools/undoframework/mainwindow.cpp 11
167 \codeline
168 \snippet examples/tools/undoframework/mainwindow.cpp 12
169
170 We implement \c itemMenuAboutToShow() and \c itemMenuAboutToHide()
171 to get a dynamic item menu. These slots are connected to the
172 \l{QMenu::}{aboutToShow()} and \l{QMenu::}{aboutToHide()} signals.
173 We need this to disable or enable the \c deleteAction.
174
175 Here is the \c addBox() slot:
176
177 \snippet examples/tools/undoframework/mainwindow.cpp 13
178
179 The \c addBox() function creates an AddCommand and pushes it on
180 the undo stack.
181
182 Here is the \c addTriangle() sot:
183
184 \snippet examples/tools/undoframework/mainwindow.cpp 14
185
186 The \c addTriangle() function creates an AddCommand and pushes it
187 on the undo stack.
188
189 Here is the implementation of \c about():
190
191 \snippet examples/tools/undoframework/mainwindow.cpp 15
192
193 The about slot is triggered by the \c aboutAction and displays an
194 about box for the example.
195
196 \section1 AddCommand Class Definition
197
198 \snippet examples/tools/undoframework/commands.h 2
199
200 The \c AddCommand class adds DiagramItem graphics items to the
201 DiagramScene.
202
203 \section1 AddCommand Class Implementation
204
205 We start with the constructor:
206
207 \snippet examples/tools/undoframework/commands.cpp 7
208
209 We first create the DiagramItem to add to the DiagramScene. The
210 \l{QUndoCommand::}{setText()} function let us set a QString that
211 describes the command. We use this to get custom messages in the
212 QUndoView and in the menu of the main window.
213
214 \snippet examples/tools/undoframework/commands.cpp 8
215
216 \c undo() removes the item from the scene. We need to update the
217 scene as ...(ask Andreas)
218
219 \snippet examples/tools/undoframework/commands.cpp 9
220
221 We set the position of the item as we do not do this in the
222 constructor.
223
224 \section1 DeleteCommand Class Definition
225
226 \snippet examples/tools/undoframework/commands.h 1
227
228 The DeleteCommand class implements the functionality to remove an
229 item from the scene.
230
231 \section1 DeleteCommand Class Implementation
232
233 \snippet examples/tools/undoframework/commands.cpp 4
234
235 We know that there must be one selected item as it is not possible
236 to create a DeleteCommand unless the item to be deleted is
237 selected and that only one item can be selected at any time.
238 The item must be unselected if it is inserted back into the
239 scene.
240
241 \snippet examples/tools/undoframework/commands.cpp 5
242
243 The item is simply reinserted into the scene.
244
245 \snippet examples/tools/undoframework/commands.cpp 6
246
247 The item is removed from the scene.
248
249 \section1 MoveCommand Class Definition
250
251 \snippet examples/tools/undoframework/commands.h 0
252
253 The \l{QUndoCommand::}{mergeWith()} is reimplemented to make
254 consecutive moves of an item one MoveCommand, i.e, the item will
255 be moved back to the start position of the first move.
256
257 \section1 MoveCommand Class Implementation
258
259
260 The constructor of MoveCommand looks like this:
261
262 \snippet examples/tools/undoframework/commands.cpp 0
263
264 We save both the old and new positions for undo and redo
265 respectively.
266
267 \snippet examples/tools/undoframework/commands.cpp 2
268
269 We simply set the items old position and update the scene.
270
271 \snippet examples/tools/undoframework/commands.cpp 3
272
273 We set the item to its new position.
274
275 \snippet examples/tools/undoframework/commands.cpp 1
276
277 Whenever a MoveCommand is created, this function is called to
278 check if it should be merged with the previous command. It is the
279 previous command object that is kept on the stack. The function
280 returns true if the command is merged; otherwise false.
281
282 We first check whether it is the same item that has been moved
283 twice, in which case we merge the commands. We update the position
284 of the item so that it will take the last position in the move
285 sequence when undone.
286
287 \section1 DiagramScene Class Definition
288
289 \snippet examples/tools/undoframework/diagramscene.h 0
290
291 The DiagramScene implements the functionality to move a
292 DiagramItem with the mouse. It emits a signal when a move is
293 completed. This is caught by the \c MainWindow, which makes
294 MoveCommands. We do not examine the implementation of DiagramScene
295 as it only deals with graphics framework issues.
296
297 \section1 The \c main() Function
298
299 The \c main() function of the program looks like this:
300
301 \snippet examples/tools/undoframework/main.cpp 0
302
303 We draw a grid in the background of the DiagramScene, so we use a
304 resource file. The rest of the function creates the \c MainWindow and
305 shows it as a top level window.
306*/
Note: See TracBrowser for help on using the repository browser.