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