1 | /* This file is part of the KDE project |
2 | Copyright (C) 2000 Werner Trobin <trobin@kde.org> |
3 | Copyright (C) 2000,2006 David Faure <faure@kde.org> |
4 | |
5 | This library is free software; you can redistribute it and/or |
6 | modify it under the terms of the GNU Library General Public |
7 | License as published by the Free Software Foundation; either |
8 | version 2 of the License, or (at your option) any later version. |
9 | |
10 | This library is distributed in the hope that it will be useful, |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | Library General Public License for more details. |
14 | |
15 | You should have received a copy of the GNU Library General Public License |
16 | along with this library; see the file COPYING.LIB. If not, write to |
17 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
18 | Boston, MA 02110-1301, USA. |
19 | */ |
20 | |
21 | #ifndef kcommand_h |
22 | #define kcommand_h |
23 | |
24 | #include <kde3support_export.h> |
25 | |
26 | #include <QtCore/QList> |
27 | #include <QtCore/QString> |
28 | #include <QtCore/QObject> |
29 | |
30 | class KAction; |
31 | class KActionCollection; |
32 | class QAction; |
33 | |
34 | /** |
35 | * The abstract base class for all Commands. Commands are used to |
36 | * store information needed for Undo/Redo functionality... |
37 | * |
38 | * Note: you might want to use the QUndo framework instead. |
39 | * It didn't exist when K3Command was written. |
40 | */ |
41 | class KDE3SUPPORT_EXPORT K3Command |
42 | { |
43 | protected: |
44 | /** |
45 | * Creates a command. |
46 | */ |
47 | K3Command(); |
48 | |
49 | public: |
50 | virtual ~K3Command(); |
51 | |
52 | /** |
53 | * The main method: executes this command. |
54 | * Implement here what this command is about, and remember to |
55 | * record any information that will be helpful for #unexecute. |
56 | */ |
57 | virtual void execute() = 0; |
58 | /** |
59 | * Unexecutes (undo) this command. |
60 | * Implement here the steps to take for undoing the command. |
61 | * If your application uses actions for everything (it should), |
62 | * and if you implement unexecute correctly, the application is in the same |
63 | * state after unexecute as it was before execute. This means, the next |
64 | * call to execute will do the same thing as it did the first time. |
65 | */ |
66 | virtual void unexecute() = 0; |
67 | |
68 | /** |
69 | * @return the name of this command, translated, since it will appear |
70 | * in the menus. |
71 | */ |
72 | virtual QString name() const = 0; |
73 | protected: |
74 | virtual void virtual_hook( int id, void* data ); |
75 | private: |
76 | class Private; |
77 | Private* const d; |
78 | Q_DISABLE_COPY( K3Command ) |
79 | }; |
80 | |
81 | /** |
82 | * A command which stores its name. |
83 | * It is more memory-efficient to use K3Command and to implement the name() method, |
84 | * but in some cases it's more simple or more flexible to store the name at creation time. |
85 | * |
86 | * Note: you might want to use the QUndo framework instead. |
87 | * It didn't exist when K3Command was written. |
88 | */ |
89 | class KDE3SUPPORT_EXPORT K3NamedCommand : public K3Command |
90 | { |
91 | protected: |
92 | /** |
93 | * Creates a command. |
94 | * @param name the name of this command, translated, since it will appear |
95 | * in the menus. |
96 | */ |
97 | K3NamedCommand( const QString &name ); |
98 | |
99 | public: |
100 | /** |
101 | * @return the name of this command |
102 | */ |
103 | virtual QString name() const; |
104 | /** |
105 | * Updates the name of this command. |
106 | * Rarely necessary. |
107 | */ |
108 | void setName( const QString &name ); |
109 | |
110 | virtual ~K3NamedCommand(); |
111 | |
112 | protected: |
113 | virtual void virtual_hook( int id, void* data ); |
114 | |
115 | private: |
116 | class Private; |
117 | Private* const d; |
118 | Q_DISABLE_COPY( K3NamedCommand ) |
119 | }; |
120 | |
121 | /** |
122 | * A Macro Command is a command that holds several sub-commands. |
123 | * It will appear as one to the user and in the command history, |
124 | * but it can use the implementation of multiple commands internally. |
125 | */ |
126 | class KDE3SUPPORT_EXPORT K3MacroCommand : public K3NamedCommand |
127 | { |
128 | public: |
129 | /** |
130 | * Creates a macro command. You will then need to call addCommand |
131 | * for each subcommand to be added to this macro command. |
132 | * @param name the name of this command, translated, since it will appear |
133 | * in the menus. |
134 | */ |
135 | K3MacroCommand( const QString & name ); |
136 | virtual ~K3MacroCommand(); |
137 | |
138 | /** |
139 | * Appends a command to this macro command. |
140 | * The ownership is transferred to the macro command. |
141 | */ |
142 | void addCommand(K3Command *command); |
143 | |
144 | /** |
145 | * Executes this command, i.e. execute all the sub-commands |
146 | * in the order in which they were added. |
147 | */ |
148 | virtual void execute(); |
149 | /** |
150 | * Undoes the execution of this command, i.e. #unexecute all the sub-commands |
151 | * in the _reverse_ order to the one in which they were added. |
152 | */ |
153 | virtual void unexecute(); |
154 | |
155 | protected: |
156 | const QList<K3Command *> commands() const; |
157 | |
158 | virtual void virtual_hook( int id, void* data ); |
159 | |
160 | private: |
161 | class Private; |
162 | Private* const d; |
163 | Q_DISABLE_COPY( K3MacroCommand ) |
164 | }; |
165 | |
166 | |
167 | /** |
168 | * The command history stores a (user) configurable amount of |
169 | * Commands. It keeps track of its size and deletes commands |
170 | * if it gets too large. The user can set a maximum undo and |
171 | * a maximum redo limit (e.g. max. 50 undo / 30 redo commands). |
172 | * The K3CommandHistory keeps track of the "borders" and deletes |
173 | * commands, if appropriate. It also activates/deactivates the |
174 | * undo/redo actions in the menu and changes the text according |
175 | * to the name of the command. |
176 | * |
177 | * Note: you might want to use the QUndo framework instead. |
178 | * It didn't exist when K3Command was written. |
179 | */ |
180 | class KDE3SUPPORT_EXPORT K3CommandHistory : public QObject { |
181 | Q_OBJECT |
182 | public: |
183 | /** |
184 | * Creates a command history, to store commands. |
185 | * This constructor doesn't create actions, so you need to call |
186 | * #undo and #redo yourself. |
187 | */ |
188 | K3CommandHistory(); |
189 | |
190 | /** |
191 | * Creates a command history, to store commands. |
192 | * This also creates an undo and a redo action, in the @p actionCollection, |
193 | * using the standard names ("edit_undo" and "edit_redo"). |
194 | * @param withMenus if true, the actions will display a menu when plugged |
195 | * into a toolbar. |
196 | * @param actionCollection the parent collection |
197 | */ |
198 | K3CommandHistory(KActionCollection *actionCollection, bool = true); |
199 | |
200 | /** |
201 | * Destructs the command history object. |
202 | */ |
203 | virtual ~K3CommandHistory(); |
204 | |
205 | /** |
206 | * Erases all the undo/redo history. |
207 | * Use this when reloading the data, for instance, since this invalidates |
208 | * all the commands. |
209 | */ |
210 | void clear(); |
211 | |
212 | /** |
213 | * Adds a command to the history. Call this for each @p command you create. |
214 | * Unless you set @p execute to false, this will also execute the command. |
215 | * This means, most of the application's code will look like |
216 | * MyCommand * cmd = new MyCommand( parameters ); |
217 | * m_historyCommand.addCommand( cmd ); |
218 | * |
219 | * Note that the command history takes ownership of the command, it will delete |
220 | * it when the undo limit is reached, or when deleting the command history itself. |
221 | */ |
222 | void addCommand(K3Command *command, bool execute=true); |
223 | |
224 | /** |
225 | * @return the maximum number of items in the undo history |
226 | */ |
227 | int undoLimit() const; |
228 | /** |
229 | * Sets the maximum number of items in the undo history. |
230 | */ |
231 | void setUndoLimit(int limit); |
232 | /** |
233 | * @return the maximum number of items in the redo history |
234 | */ |
235 | int redoLimit() const; |
236 | /** |
237 | * Sets the maximum number of items in the redo history. |
238 | */ |
239 | void setRedoLimit(int limit); |
240 | |
241 | /** |
242 | * Enable or disable the undo and redo actions. |
243 | * This isn't usually necessary, but this method can be useful if |
244 | * you disable all actions (to go to a "readonly" state), and then |
245 | * want to come back to a readwrite mode. |
246 | */ |
247 | void updateActions(); |
248 | |
249 | /** |
250 | * @return the present command, i.e. the one that undo() would unexecute. |
251 | * This can be used to e.g. show selection. |
252 | */ |
253 | K3Command * presentCommand() const; |
254 | |
255 | /** |
256 | * @return true if undo is available, |
257 | * i.e. there is at least one command that can be undone right now |
258 | */ |
259 | bool isUndoAvailable() const; |
260 | |
261 | /** |
262 | * @return true if redo is available |
263 | * i.e. there is at least one command that can be redone right now |
264 | */ |
265 | bool isRedoAvailable() const; |
266 | |
267 | /** |
268 | * @return the list of next @p maxCommands actions that will be undone by undo() |
269 | * The returned list is empty if !isUndoAvailable(). |
270 | * Otherwise the list starts with the next command to undo, |
271 | * i.e. the order of the commands in the list is the reverse of the |
272 | * chronological order of the commands. |
273 | * @param maxCommands maximum number of commands requested. 0 means no maximum, |
274 | * all stored undo commands (within undoLimit()) are returned. |
275 | */ |
276 | QList<K3Command *> undoCommands( int maxCommands = 0 ) const; |
277 | |
278 | /** |
279 | * @return the list of next @p maxCommands actions that will be redone by redo() |
280 | * The returned list is empty if !isRedoAvailable(). |
281 | * Otherwise the list starts with the next command to redo. |
282 | * @param maxCommands maximum number of commands requested. 0 means no maximum, |
283 | * all stored redo commands (within redoLimit()) are returned. |
284 | */ |
285 | QList<K3Command *> redoCommands( int maxCommands = 0 ) const; |
286 | |
287 | public Q_SLOTS: |
288 | /** |
289 | * Undoes the last action. |
290 | * Call this if you don't use the builtin KActions. |
291 | */ |
292 | virtual void undo(); |
293 | /** |
294 | * Redoes the last undone action. |
295 | * Call this if you don't use the builtin KActions. |
296 | */ |
297 | virtual void redo(); |
298 | /** |
299 | * Remembers when you saved the document. |
300 | * Call this right after saving the document. As soon as |
301 | * the history reaches the current index again (via some |
302 | * undo/redo operations) it will emit documentRestored |
303 | * If you implemented undo/redo properly the document is |
304 | * the same you saved before. |
305 | */ |
306 | virtual void documentSaved(); |
307 | |
308 | Q_SIGNALS: |
309 | /** |
310 | * Emitted every time a command is executed |
311 | * (whether by addCommand, undo or redo). |
312 | * You can use this to update the GUI, for instance. |
313 | * @param command was executed |
314 | */ |
315 | void commandExecuted(K3Command *command); |
316 | |
317 | /** |
318 | * Emitted every time we reach the index where you |
319 | * saved the document for the last time. See documentSaved |
320 | */ |
321 | void documentRestored(); |
322 | |
323 | /** |
324 | * Emitted whenever the command history has changed, |
325 | * i.e. after addCommand, undo or redo. |
326 | * This is used by the actions to update themselves. |
327 | */ |
328 | void commandHistoryChanged(); |
329 | |
330 | private: |
331 | void clipCommands(); // ensures that the limits are kept |
332 | |
333 | private: |
334 | class K3CommandHistoryPrivate; |
335 | K3CommandHistoryPrivate * const d; |
336 | Q_DISABLE_COPY( K3CommandHistory ) |
337 | }; |
338 | |
339 | #include <ktoolbarpopupaction.h> |
340 | |
341 | /** |
342 | * This type of action is used to show undo or redo actions in the menu or in the |
343 | * toolbars. |
344 | * This action will keep itself up to date and change the text based on the undo |
345 | * history, plus it will disable itself when there is nothing to undo/redo. |
346 | * You will typically need two instances of this action per view (e.g. the mainwindow). |
347 | * @code |
348 | new KUndoRedoAction( KUndoRedoAction::Undo, view->actionCollection(), m_history ); |
349 | new KUndoRedoAction( KUndoRedoAction::Redo, view->actionCollection(), m_history ); |
350 | @endcode |
351 | * Note that there is no need to connect or even keep a reference to the object as |
352 | * all work is done automatically. |
353 | * |
354 | * Note: you might want to use the QUndo framework instead. |
355 | * It didn't exist when K3Command was written. |
356 | */ |
357 | class K3UndoRedoAction : public KToolBarPopupAction |
358 | { |
359 | Q_OBJECT |
360 | public: |
361 | enum Type { Undo, Redo }; |
362 | K3UndoRedoAction( Type type, KActionCollection* actionCollection, K3CommandHistory* commandHistory ); |
363 | |
364 | private Q_SLOTS: |
365 | void slotAboutToShow(); |
366 | void slotActionTriggered( QAction *action ); |
367 | void slotCommandHistoryChanged(); |
368 | |
369 | private: |
370 | class Private; |
371 | Private* const d; |
372 | Q_DISABLE_COPY( K3UndoRedoAction ) |
373 | }; |
374 | |
375 | #endif |
376 | |