Subversion Repositories Scribus

Rev

Rev 1371 | Rev 1385 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1111 tsoots 1
/***************************************************************************
2
 *   Copyright (C) 2005 by Riku Leino                                      *
3
 *   tsoots@gmail.com                                                      *
4
 *                                                                         *
5
 *   This program is free software; you can redistribute it and/or modify  *
6
 *   it under the terms of the GNU General Public License as published by  *
7
 *   the Free Software Foundation; either version 2 of the License, or     *
8
 *   (at your option) any later version.                                   *
9
 *                                                                         *
10
 *   This program 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         *
13
 *   GNU General Public License for more details.                          *
14
 *                                                                         *
15
 *   You should have received a copy of the GNU General Public License     *
16
 *   along with this program; if not, write to the                         *
17
 *   Free Software Foundation, Inc.,                                       *
18
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
19
 ***************************************************************************/
20
 
21
#ifndef UNDOMANAGER_H
22
#define UNDOMANAGER_H
23
 
24
#include <vector>
25
#include <utility>
26
#include <qobject.h>
27
#include <qpixmap.h>
1190 tsoots 28
#include <qstring.h>
1111 tsoots 29
#include "undostate.h"
30
#include "undoobject.h"
31
 
1142 tsoots 32
class UndoGui;
1197 tsoots 33
class PrefsContext;
1142 tsoots 34
 
1111 tsoots 35
typedef std::pair<UndoObject*, UndoState*> ActionPair;
36
typedef std::vector<ActionPair> ActionList;
37
typedef std::pair<ActionList::iterator, ActionList> StackPair;
38
typedef QMap<QString, StackPair> StackMap;
39
 
40
/**
41
 * @brief UndoManager handles the undo stack.
42
 *
43
 * UndoManager is the engine of the undo/redo handling. When ever an undoable
44
 * action happens an UndoState object will be sent to the UndoManager which then
45
 * stores the state in the undo stack. When an undo is requested the state is
46
 * send back to it's creator which is then responsible for doing the actual undo or
47
 * redo.
48
 *
49
 * UndoManager also handles the UndoGuis by linking them together and reporting
50
 * all undo/redo actions to the guis for them to update the visual representation.
51
 * For this to work all UndoGuis need to be registered to the UndoManager with the
52
 * registerGui() method.
53
 *
54
 * @author Riku Leino tsoots@gmail.com
55
 * @date December 2004
56
 */
57
class UndoManager : public QObject
58
{
59
        Q_OBJECT
60
 
61
private:
1213 tsoots 62
 
63
/*** UndoManager::TransactionState ***************************************************/
64
 
65
        /**
66
         * @brief TransactionState provides a container where multiple actions can be stored
67
         * @brief as a single action which then appears in the attached <code>UndoGui</code>s.
68
         * @author Riku Leino tsoots@gmail.com
69
         * @date January 2005
70
         */
71
        class TransactionState : public UndoState
72
        {
73
        private:
74
                /** @brief Number of undo states stored in this transaction */
75
                uint _size;
76
                /** @brief vector to keep the states in */
77
                std::vector<ActionPair*> states;
78
        public:
79
                /** @brief Creates a new TransactionState instance */
80
                TransactionState();
81
                /** @brief Destroys the TransactionState instance */
82
                ~TransactionState();
83
                /**
84
                 * @brief Add a new <code>UndoState</code> object to the transaction.
85
                 * @param state state to be added to the transaction
86
                 */
87
                void pushBack(UndoObject *target, UndoState *state);
88
                /**
89
                 * @brief Returns the count of the <code>UndoState</code> objects in this transaction.
90
                 * @return count of the <code>UndoState</code> objects in this transaction
91
                 */
92
                uint sizet();
1226 tsoots 93
                /** @brief Use the name from last action added to this <code>TransactionState</code> */
94
                void useActionName();
1213 tsoots 95
                /**
96
                 * @brief Returns an <code>UndoState</code> object at <code>index</code>.
97
                 * @param index index from where an <code>UndoState</code> object is returned.
98
                 * If <code>index</code> is out of scope <code>NULL</code> will be rerturned.
99
                 * @return <code>UndoState</code> object from <code>index</code> or <code>NULL</code>
100
                 * if <code>index</code> is out of scope.
101
                 */
102
                ActionPair* at(int index);
1238 tsoots 103
                /**
104
                 * @brief Replace object with id uid with new UndoObject newUndoObject.
105
                 * @param uid id of the object that is wanted to be replaced
106
                 * @param newUndoObject object that is used for replacing
107
                 */
108
                void replace(ulong uid, UndoObject *newUndoObject);
1213 tsoots 109
        };
110
 
111
/*** UndoManager::TransactionObject ***************************************************/
112
 
113
        /**
114
         * @brief Dummy subclass of <code>UndoObject</code> which is used for holding the name
115
         * @brief for the transaction's target object(group) (f.e "Selection", "Group", "Script"...).
116
         * @author Riku Leino tsoots@gmail.com
117
         * @date January 2005
118
         */
119
        class TransactionObject : public UndoObject
120
        {
121
        public:
122
                TransactionObject() {};
1226 tsoots 123
                virtual ~TransactionObject() {};
1213 tsoots 124
                void restore(UndoState*, bool) {};
125
        };
126
 
127
/**************************************************************************************/
128
 
1111 tsoots 129
        /**
130
         * @brief The only instance of UndoManager available.
131
         *
132
         * UndoManager is singleton and the instance can be queried with the method
133
         * instance().
134
         */
135
        static UndoManager* _instance;
136
 
137
        /** @brief Should undo states be stored or ignored */
138
        static bool _undoEnabled;
139
 
1197 tsoots 140
        PrefsContext *prefs;
141
 
1111 tsoots 142
        /** @brief Doc to which the currently active stack belongs */
143
        QString currentDoc;
144
 
145
        /**
146
         * @brief Id number of the object for what the object specific undo is shown
147
         * @brief or -1 if global undo is used.
148
         */
149
        int currentUndoObjectId;
150
 
1213 tsoots 151
        /**
1238 tsoots 152
         * @brief Stores the transactions which are currently started but not
153
         * @brief canceled or commited.
154
         */
155
        std::vector<std::pair<TransactionObject*, TransactionState*> > transactions;
156
 
157
        /**
1213 tsoots 158
         * @brief If in transaction mode this is the container for incoming <code>UndoState</code>
159
         * @brief objects.
160
         *
161
         * It is also used to detect if we are in the transaction mode. When it is <code>NULL</code>
162
         * normal mode is on.
163
         */
164
        TransactionState *transaction;
165
 
166
        /** @brief Dummy object for storing transaction target's name */
167
        TransactionObject *transactionTarget;
168
 
1111 tsoots 169
        /**
170
         * @brief UndoGuis attached to this UndoManager
171
         * @sa UndoGui
172
         * @sa UndoWidget
173
         * @sa UndoPalette
174
         */
175
        std::vector<UndoGui*> undoGuis;
176
 
177
        /** @brief Undo stacks for all open documents */
178
        StackMap stacks;
179
 
1262 tsoots 180
        /** @brief Maximum length of the undo stack. 0 marks for infinite length. */
1111 tsoots 181
        int historyLength;
182
 
1262 tsoots 183
        /**
1111 tsoots 184
         * @brief Initializes the UndoGui.
185
         * @param gui UndoGui to be initialized
186
         * @param uid UndoObject's id if in object specific mode or -1 to tell
187
         * that global undo is used.
188
         */
189
        void setState(UndoGui* gui, int uid = -1);
190
 
1262 tsoots 191
        /**
192
         * @brief Disconnect all attached UndoGui instances from signals provided by this
193
         * @brief class and other UndoGui objects.
194
         */
1111 tsoots 195
        void connectGuis();
1262 tsoots 196
        /**
197
         * @brief Connect all attached UndoGui instances to signals provided by this
198
         * @brief class and other UndoGui objects.
199
         */
1111 tsoots 200
        void disconnectGuis();
1262 tsoots 201
        /**
202
         * @brief Load icons needed for Action History window.
203
         */
1190 tsoots 204
        void initIcons();
1262 tsoots 205
        /**
206
         * @brief Checks the stack length against historyLength variable and removes
207
         * @brief actions until it is of right length.
208
         *
209
         * This method is used when a user alters the history length option in preferences
210
         * and whenever a new action is added to the stack.
211
         */
1197 tsoots 212
        void checkStackLength();
1262 tsoots 213
        /**
214
         * @brief Extracts actions from TransactionState object and undos them.
215
         * @param tstate TransactionState object from where the actions are going to be extracted.
216
         */
1213 tsoots 217
        void doTransactionUndo(TransactionState *tstate);
1262 tsoots 218
        /**
219
         * @brief Extracts actions from TransactionState object and redos them.
220
         * @param tstate TransactionState object from where the actions are going to be extracted.
221
         */
1213 tsoots 222
        void doTransactionRedo(TransactionState *tstate);
1111 tsoots 223
 
224
public:
225
        /**
226
         * @brief Returns a pointer to the UndoManager instance
227
         * @return A pointer to the UndoManager instance
228
         */
229
        static UndoManager* instance();
230
 
231
        /**
232
         * @brief Deletes the UndoManager Instance
233
         *
234
         * Must be called when UndoManager is no more needed.
235
         */
236
        static void deleteInstance();
237
 
238
        /**
239
         * @brief Sets the undo action tracking enabled or disabled.
240
         * @param isEnabled If true undo stack is updated with the states sent
241
         * to the UndoManager else undo stack is not updated and attached UndoGuis
242
         * are not informed of the actions.
243
         */
244
        void setUndoEnabled(bool isEnabled);
245
 
246
        /**
247
         * @brief Returns true if undo actions are stored, if not will return false.
248
         * @return true if undo actions are stored, if not will return false
249
         */
250
        static bool undoEnabled();
251
 
252
        /**
1213 tsoots 253
         * @brief Start a transaction.
254
         *
255
         * After this method has been invoked <code>UndoManager</code> will switch to the
256
     * transaction (silent) mode where it does not report actions to the attached
1357 tsoots 257
         * <code>UndoGui</code> widgets but stores all incoming <code>UndoState</code> objects into
1213 tsoots 258
         * the transaction container which after call to the method commit() will be sent
259
         * to the guis as a single undo action. Transaction can be named when starting it or
260
         * naming can be done when commiting it.
261
         * @param targetName name for the target of this transaction (f.e. "Selection")
1262 tsoots 262
         * @param targetPixmap Icon for the target on which this transaction works.
263
         * this icon will be drawn first when the action is presented in Action History
264
         * window and icon for the action will be drawn over this one.
1213 tsoots 265
         * @param name name for the transaction (f.e. "Move" would make with the above
266
         * "Move Selection")
267
         * @param description description for the transaction
1250 tsoots 268
         * @param actionPixmap icon for the action performed by the transaction
1213 tsoots 269
         * @sa commit()
270
         */
271
        void beginTransaction(const QString &targetName = "",
1250 tsoots 272
                          QPixmap *targetPixmap = 0,
273
                          const QString &actionName = "",
1213 tsoots 274
                          const QString &description = "",
1250 tsoots 275
                          QPixmap *actionPixmap = 0);
1213 tsoots 276
 
277
        /**
278
         * @brief Cancels the current transaction and deletes groupped <code>UndoState</code>s.
279
         * @brief Nothing from canceled transaction will be sent to the undo gui widgets.
280
         */
281
        void cancelTransaction();
282
 
283
        /**
284
         * @brief Commit the current transaction.
285
         *
286
         * Current transaction will be commited and <code>UndoManager</code> will be switched
287
         * to the normal mode. Commited transaction will be sent to the attached undo gui
288
         * widgets and it will show up there as a single undo action. Details used as a parameter
289
         * will be details shown in the gui widgets.
290
         * @param targetName name for the target of this transaction (f.e. "Selection")
1262 tsoots 291
         * @param targetPixmap Icon for the target on which this transaction works.
292
         * this icon will be drawn first when the action is presented in Action History
293
         * window and icon for the action will be drawn over this one.
1213 tsoots 294
         * @param name name for the action
295
         * @param description description for the action
1250 tsoots 296
         * @param actionPixmap icon for the action performed by the transaction
1213 tsoots 297
         * @sa beginTransaction()
298
         */
299
        void commit(const QString &targetName = "",
1250 tsoots 300
                QPixmap *targetPixmap = 0,
1213 tsoots 301
                const QString &name = "",
302
                const QString &description = "",
1250 tsoots 303
                QPixmap *actionPixmap = 0);
1213 tsoots 304
 
305
        /**
306
         * @brief Returns true if in transaction mode if not will return false.
307
         * @return true if in transaction mode if not will return false
308
         */
309
        bool isTransactionMode();
310
 
311
        /**
1111 tsoots 312
         * @brief Register an UndoGui to the UndoManager.
313
         *
314
         * After registering a gui to the manager the gui will be updated with the
315
         * undo action information received by the UndoManager. Actions done with the
316
         * UndoGui to be registered are also handled after registering.
317
         * @param gui A pointer to the UndoGui that is wanted to be registered.
318
         */
319
        void registerGui(UndoGui* gui);
320
 
321
        /**
322
         * @brief Removes an UndoGui from UndoManager.
323
         * @param gui UndoGui to be removed from the UndoManager.
324
         */
325
        void removeGui(UndoGui* gui);
326
 
327
        /**
328
         * @brief Changes the active undo stack.
329
         *
330
         * Sets the stack connected to the name <code>stackName</code> active. Calling
331
         * this method will send clear() signal to the attached <code>UndoGui</code>s and
332
         * will update their undo stack representations.
333
         * @param stackName Name of the stack to be used
334
         */
335
        void switchStack(const QString& stackName);
336
 
337
        /**
338
         * @brief Rename the current stack
339
         * @param newName New name for the current stack.
340
         */
1252 tsoots 341
        void renameStack(const QString& newName);
1111 tsoots 342
 
343
        /**
344
         * @brief Remove the stack with the name <code>stackName</code>
345
         * @param stackName Name of the stack that is wanted to be removed
346
         */
1252 tsoots 347
        void removeStack(const QString& stackName);
1111 tsoots 348
 
349
        /**
350
         * @brief Returns true if there are actions that can be undone otherwise returns false.
351
         *
352
         * This is useful when undo/redo actions are handled with a gui that is not attached to
353
         * the UndoManager (f.e. menu items) and when those gui items are wanted to set enabled
354
         * or disabled depending on the status of the undo stack.
355
         * @return true if there are actions that can be undone otherwise returns false
356
         */
357
        bool hasUndoActions();
358
 
359
        /**
360
         * @brief Returns true if there are actions that can be redone otherwise returns false.
361
         * @return true if there are actions that can be redone otherwise returns false
362
         * @sa UndoManager::hasUndoActions()
363
         */
364
        bool hasRedoActions();
365
 
366
        /**
367
         * @brief Switches the state of UndoManager (global/object specific undo).
368
         *
369
         * If parameter uid is less than 0 global undo is used else the undo state
370
         * is object specific using the object whose uid is given as a parameter.
371
         * @param uid UndoObject's id for what the object specific undo is wanted or
372
         * -1 if global undo is wanted.
373
         */
374
        void showObject(int uid);
375
 
376
        /**
1238 tsoots 377
         * @brief Replace an UndoObject with the id uid with a new UndoObject new.
378
         * @param uid Id for the UndoObject that is wanted to be replaced.
379
         * @param newUndoObject UndoObject which will replace an old UndoObject in the stack.
380
         */
1252 tsoots 381
        void replaceObject(ulong uid, UndoObject *newUndoObject);
1238 tsoots 382
 
383
        /**
1111 tsoots 384
         * @brief Returns the maximum length of the undostack.
385
         * @return the maximum length of the undostack
386
         */
387
        int getHistoryLength();
388
 
1199 tsoots 389
        /**
1190 tsoots 390
        * @name Action strings
391
        * Strings describing undo actions
392
        */
393
        /*@{*/
394
        static const QString AddVGuide;
395
        static const QString AddHGuide;
396
        static const QString DelVGuide;
397
        static const QString DelHGuide;
398
        static const QString MoveVGuide;
399
        static const QString MoveHGuide;
400
        static const QString LockGuides;
401
        static const QString UnlockGuides;
1204 tsoots 402
        static const QString Move;
1206 tsoots 403
        static const QString Resize;
1211 tsoots 404
        static const QString Rotate;
405
        static const QString MoveFromTo;
406
        static const QString ResizeFromTo;
407
        static const QString RotateFromTo;
1226 tsoots 408
        static const QString Selection;
409
        static const QString Group;
1355 tsoots 410
        static const QString SelectionGroup;
1238 tsoots 411
        static const QString Create;
412
        static const QString CreateTo;
1247 tsoots 413
        static const QString AlignDistribute;
414
        static const QString ItemsInvolved;
415
        static const QString Cancel;
1286 tsoots 416
        static const QString SetFill;
417
        static const QString ColorFromTo;
418
        static const QString SetShade;
419
        static const QString ShadeFromTo;
420
        static const QString SetLineColor;
421
        static const QString SetLineShade;
1287 tsoots 422
        static const QString FlipH;
423
        static const QString FlipV;
1290 tsoots 424
        static const QString Lock;
425
        static const QString UnLock;
426
        static const QString SizeLock;
427
        static const QString SizeUnLock;
1293 tsoots 428
        static const QString Ungroup;
1340 tsoots 429
        static const QString Delete;
1357 tsoots 430
        static const QString Rename;
431
        static const QString FromTo;
432
        static const QString ApplyTemplate;
1369 tsoots 433
        static const QString Paste;
434
        static const QString Cut;
1371 tsoots 435
        static const QString Transparency;
436
        static const QString LineTransparency;
1383 tsoots 437
        static const QString LineStyle;
1190 tsoots 438
        /*@}*/
1204 tsoots 439
 
1190 tsoots 440
        /**
441
         * @name Action icons
442
         * Icons for undo actions
443
         */
444
        /*@{*/
1250 tsoots 445
/*** Icons for UndoObjects *******************************************/
446
        static QPixmap *IImageFrame;
447
        static QPixmap *ITextFrame;
448
        static QPixmap *ILine;
449
        static QPixmap *IPolygon;
450
        static QPixmap *IPolyline;
451
        static QPixmap *IPathText;
1254 tsoots 452
        static QPixmap *IGroup;
1250 tsoots 453
/*** Icons for actions ***********************************************/
454
        static QPixmap *IMove;
455
        static QPixmap *IResize;
456
        static QPixmap *IRotate;
1190 tsoots 457
        static QPixmap *IGuides;
458
        static QPixmap *ILockGuides;
1247 tsoots 459
        static QPixmap *IAlignDistribute;
1286 tsoots 460
        static QPixmap *IFill;
461
        static QPixmap *IShade;
1287 tsoots 462
        static QPixmap *IFlipH;
463
        static QPixmap *IFlipV;
1290 tsoots 464
        static QPixmap *ILock;
465
        static QPixmap *IUnLock;
1340 tsoots 466
        static QPixmap *IDelete;
467
        static QPixmap *ICreate;
1369 tsoots 468
        static QPixmap *IPaste;
469
        static QPixmap *ICut;
1371 tsoots 470
        static QPixmap *ITransparency;
1383 tsoots 471
        static QPixmap *ILineStyle;
1190 tsoots 472
        /*@}*/
473
 
1111 tsoots 474
protected:
475
        /** @brief Creates a new UndoManager instance */
476
        UndoManager();
477
 
478
        /** @brief Destroys the UndoManager instance */
479
        ~UndoManager();
480
 
481
private slots:
482
        /**
483
         * @brief Take undo steps the given amount
484
         *
485
         * When an UndoGui is registered to the UndoManager gui's undo() signal
486
         * is connected to this slot. Emitting an undo() signal will make the
487
         * UndoManager perform undo actions the given number of steps.
488
         * @param steps Number of undo actions to make
489
         */
490
        void doUndo(int steps);
491
 
492
        /**
493
         * @brief Take redo steps the given amount
494
         * @param steps Number of redo actions to make
495
         * @sa UndoManager::doUndo(int steps)
496
         */
497
        void doRedo(int steps);
498
 
499
public slots:
500
        /**
501
         * @brief Adds a new action to the undo stack.
502
         *
503
         * If _unodEnabled is true the action will be stored otherwise it will
504
         * be just ignored. When a new action is added redo items from the stack
505
         * will be removed and the current action will be set to the one which was
506
         * added.
507
         * @param target Source of the action. When undoing/redoing this action
508
         * restore() method of this UndoObject will be called.
509
         * @param state UndoSate describing the state (action).
1356 tsoots 510
         * @param targetPixmap Is used to override the default target icon in this action.
1111 tsoots 511
         */
1340 tsoots 512
        void action(UndoObject* target, UndoState* state, QPixmap *targetPixmap = 0);
1111 tsoots 513
 
514
        /**
1356 tsoots 515
         * @brief Adds a new action to the undo stack.
516
         *
517
         * If _unodEnabled is true the action will be stored otherwise it will
518
         * be just ignored. When a new action is added redo items from the stack
519
         * will be removed and the current action will be set to the one which was
520
         * added.
521
         * @param target Source of the action. When undoing/redoing this action
522
         * restore() method of this UndoObject will be called.
523
         * @param state UndoSate describing the state (action).
524
         * @param targetName Is used to override the default target name in this action.
525
         * @param targetPixmap Is used to override the default target icon in this action.
526
         */
527
        void action(UndoObject* target, UndoState* state, const QString &targetName, QPixmap *targetPixmap = 0);
528
 
529
        /**
1111 tsoots 530
         * @brief Informs UndoManager to perform undo
531
         *
532
         * If an undo is wanted and the caller is not registered UndoGui this method
533
         * can be used. Useful for example with the menu entry for undo.
534
         * @param steps Number of undo steps to take
535
         */
536
        void undo(int steps);
537
 
538
        /**
539
         * @brief Informs UndoManager to perform redo
540
         * @param steps Number of redo steps to take
541
         * @sa UndoManager::undo(int steps)
542
         */
543
        void redo(int steps);
544
 
1197 tsoots 545
        /**
546
         * @brief Sets the length of the undo stack.
547
         *
548
         * Tells how many UndoStates are stored.
549
         * @param steps number of UndoStates to store in the undo stack
550
         */
551
        void setHistoryLength(int steps);
552
 
1111 tsoots 553
signals:
554
        /**
555
         * @brief Emitted when a new undo action is stored to the undo stack.
556
         *
557
         * This signal is connected to the registered UndoGuis for them to update the
558
         * visual representation of the undo stack.
559
         * @param target Source of the action
560
         * @param state UndoState describing the action
561
         */
562
        void newAction(UndoObject* target, UndoState* state);
563
 
564
        /**
565
         * @brief Emitted when an undo action has been done.
566
         *
567
         * It is connected to attached guis to inform them to update the visual
1190 tsoots 568
         * representation of the undo stack. This signal will be also sent to the
569
         * <code>UndoGui</code> where it came from.
1111 tsoots 570
         * @param steps Number of steps to take
571
         */
572
        void undoSignal(int steps);
573
 
574
        /**
575
         * @brief Emitted when a redo action has been done.
576
         * @param steps Number of steps to take
577
         * @sa UndoManager::undoSignal(int steps)
578
         */
579
        void redoSignal(int steps);
580
 
581
        /**
582
         * @brief This signal is used to notify registered UndoGui instances that
583
         * @brief history limit is reached and the last item from the stack
584
         * @brief representation should be removed.
585
         */
586
        void popBack();
587
 
588
        /**
589
         * @brief This signal is emitted when all requested undo/redo actions have been done.
590
         *
591
         * It could be used in the application as a signal when the view can be rendered
592
         * again after undo/redo.
593
         */
594
        void undoRedoDone();
1190 tsoots 595
 
1111 tsoots 596
};
597
 
1190 tsoots 598
typedef UndoManager Um;
599
 
1111 tsoots 600
#endif