forked from sjg20/paperman
-
Notifications
You must be signed in to change notification settings - Fork 0
/
desktopundo.h
371 lines (298 loc) · 12.2 KB
/
desktopundo.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
/*
License: GPL-2
An electronic filing cabinet: scan, print, stack, arrange
Copyright (C) 2009 Simon Glass, chch-kiwi@users.sourceforge.net
.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
X-Comment: On Debian GNU/Linux systems, the complete text of the GNU General
Public License can be found in the /usr/share/common-licenses/GPL file.
*/
#include <QBitArray>
#include <QHash>
#include <QUndoCommand>
#include <QModelIndexList>
#include <QStringList>
#include "err.h"
class Desktopmodel;
/** this is our version of an undo stack. We use this subclass so we can add
new features to it later*/
class Desktopundostack : public QUndoStack
{
public:
Desktopundostack (QObject *parent = 0);
~Desktopundostack ();
};
/** this is an undo command. All undo commands are subclasses of this. We
provide error handling and a way of remembering the sequence number of
every undo command */
class Desktopundocmd : public QUndoCommand
{
public:
Desktopundocmd (Desktopmodel *model);
~Desktopundocmd ();
/** check if there has been an error, and complain to the user if so
\param err error to complain about (NULL if all ok) */
void complain (err_info *err);
/** record that we are about to add items. We record the number of items
currently in the desk so that we know later how many were added.
\param parent parent (desk) which will receive the new items */
void aboutToAdd (QModelIndex parent);
protected:
/** sequence number of this undo command. This is allocated globally and
is unique across all models which use undo/redo */
int _seq;
Desktopmodel *_model; //!< the model in use
};
/** delete a group of stacks. We record the filenames of the deleted items
since the model indexes may change. We move them into the trash (or another
directory if provided) and record the filenames obtained there also.
Finally we record the file information so we can restore page number
and position */
class UCTrashStacks : public Desktopundocmd
{
public:
UCTrashStacks (Desktopmodel *model,
QModelIndexList &list, QModelIndex &parent, QString destdir, bool copy);
void redo();
void undo();
const QStringList &trashlist () const { return _trashlist; }
private:
QString _dir; //!< desk directory
QStringList _filenames; //!< the list of filenames to delete
QStringList _trashlist; //!< the resulting filenames in the trash
QList<pagepos_info> _files; //!< file information for each file
QString _destdir; //!< destination directory ("" for trash)
bool _copy; //!< true to copy, else move
};
/** move a group of stacks. We record the filenames of the deleted items
since the model indexes may change. We also record the original position
and the new position to support undo / redo */
class UCMove : public Desktopundocmd
{
public:
UCMove (Desktopmodel *model, QModelIndexList &list, QModelIndex &parent,
QList<QPoint> &oldplist, QList<QPoint> &plist);
void redo();
void undo();
private:
QString _dir; //!< desk directory
QStringList _filenames; //!< the list of filenames to move
QList<QPoint> _oldpos; //!< old positions
QList<QPoint> _newpos; //!< new positions
};
/** duplicate a group of stacks. We record the original filenames and the
duplicate filenames. To redo we create the duplicates, while ensuring
that the duplicate filesnames are unit. To undo, we simply remove
the duplicates */
class UCDuplicate : public Desktopundocmd
{
public:
UCDuplicate (Desktopmodel *model, QModelIndexList &list, QModelIndex &parent,
File::e_type type, int odd_even = 3);
void redo();
void undo();
private:
QString _dir; //!< desk directory
QStringList _filenames; //!< the list of filenames to move
QStringList _newnames; //!< the list of duplicated filenames
File::e_type _type; // the type of duplication to perform
int _odd_even; //!< bit 0 means duplicate even pages, bit 1 means odd
};
/** this unstacks a group of stacks completely, so that each stack becomes
a set of single page stacks.
To redo this, we record (for each stack) a list of filenames for each
of the unstacked pages. In other words, a single filename becomes a list
of filenames.
Note that one page always remains in the original stack - i.e. we do
not need to create a new stack for that page.
To undo, we restack all the filenames for each stack into the original
stack, deleting them afterwards */
class UCUnstackStacks : public Desktopundocmd
{
public:
UCUnstackStacks (Desktopmodel *model, QModelIndexList &list, QModelIndex &parent);
void redo();
void undo();
private:
QString _dir; //!< desk directory
QStringList _filenames; //!< the list of filenames to unstack
QList<QStringList> _newnames; //!< the list of duplicated filenames for each stack
};
/** this unstacks a single page from a stack, optionally removing it from
the original stack.
To redo this, we perform the stack.
To undo, we either insert the page back into the stack and delete its own
stack, or (if _remove is false) just delete its own stack. */
class UCUnstackPage : public Desktopundocmd
{
public:
UCUnstackPage (Desktopmodel *model, QModelIndex &ind,
int pagenum, bool remove);
void redo();
void undo();
private:
QString _dir; //!< desk directory
QString _filename; //!< the filename of the original stack
QString _newname; //!< the filename of the unstacked page
int _pagenum; //!< page number to unstack
bool _remove; //!< true if the page was removed from the original stack
};
/** this deletes a set of pages from a stack, removing then from
the original stack. We do this by just marking them as deleted, so that undo
is easy.
To redo this, we perform the delete.
To undo, we unmark the pages in the stack so that they reappear
*/
class UCDeletePages : public Desktopundocmd
{
public:
UCDeletePages (Desktopmodel *model, QModelIndex &ind, QBitArray &pages);
void redo();
void undo();
private:
QString _dir; //!< desk directory
QString _filename; //!< the filename of the original stack
QString _newname; //!< the filename of the stack where the unstacked pages end up
QBitArray _pages; //!< list of pages to delete, one bit for each (true = delete)
QByteArray _del_info; //!< information about deleted pages
int _count; //!< number of pages to delete
};
/** stack one or more stacks into a destination stack, inserting them at
a given page number. This records the destination filename and the filenames
of all the stacked items, so that we can unstack them. It also records the
destination page number, which gives us the starting page number for
unstacking during an undo. Finally, we record the file information for each
stacked item, which gives us the number of pages in each. That allows us to
know how many pages to put into each unstacked stack during an undo.
It is also possible to pass in the list of positions for each item. This is
used when the current positions have been updated already and we want to
provide an earlier possition (drag & drop has this problem) */
class UCStackStacks : public Desktopundocmd
{
public:
UCStackStacks (Desktopmodel *model, QModelIndex &dest,
QModelIndexList &list, int pagenum, QList<QPoint> *poslist);
void redo();
void undo();
private:
QString _dir; //!< desk directory
QString _destdir; //!< dest desk directory
QString _destname; //!< the filename of the destination stack
QString _srcdir; //!< source desk directory
QStringList _filenames; //!< the list of filenames to stack
int _pagenum; //!< page number in dest to stack before
QList<pagepos_info> _pagepos; //!< file information for each file
};
/** this changes directory. This is a bit of an odd thing to undo, but
our Desktopmodel does not cope with multiple directories. Maybe this needs
to change but for the moment that is the way it is.
Changing directories resets the Desktopmodel since there is now a whole
new set of items to remember. The items in the previous model are forgotten
and a maxdesk.ini file is written out.
The effect of having this undo command is that you can move something to
another directory, change there, move it around and stack it, and then
undo the whole sequence back to the original directory if you like.
Redoing this changes the path and root to the new directory.
Undoing this changes it back */
class UCChangeDir : public Desktopundocmd
{
public:
UCChangeDir (Desktopmodel *model, QString dirPath, QString rootPath,
QString oldPath, QString oldRoot);
void redo();
void undo();
private:
QString _newpath; //!< the new directory
QString _oldpath; //!< the old directory
QString _newroot; //!< the root path for the new directory
QString _oldroot; //!< the root path for the old directory
};
/** rename a stack. To redo this we change the stack name in the model
and rename on the filesystem. To undo we change the name back in both
places */
class UCRenameStack : public Desktopundocmd
{
public:
/** create an undo record for renaming a stack, and execute it
\param model model to work with
\param ind model index of stack
\param newname new filename (including .max extension) */
UCRenameStack (Desktopmodel *model, const QModelIndex &ind, QString newname);
void redo();
void undo();
private:
QString _dir; //!< desk directory
QString _newname; //!< the new name
QString _oldname; //!< the old name
};
/** rename a page. To redo this we rename in the maxdesk layer. To undo we
change the name back */
class UCRenamePage : public Desktopundocmd
{
public:
/** create an undo record for renaming a stack, and execute it
\param model model to work with
\param ind model index of stack
\param newname new filename (including .max extension) */
UCRenamePage (Desktopmodel *model, const QModelIndex &ind, QString newname);
void redo();
void undo();
private:
QString _dir; //!< desk directory
QString _fname; //!< filename of stack to rename
QString _newname; //!< the new name
QString _oldname; //!< the old name
int _pagenum; //!< the current page number
};
/** update stack annotations. To redo this we write the updatein the
maxdesk layer. To undo we write the old details */
class UCUpdateAnnot : public Desktopundocmd
{
public:
/** create an undo record for renaming a stack, and execute it
\param model model to work with
\param ind model index of stack
\param updates annotation strings to update, indexed by MAXA_... */
UCUpdateAnnot (Desktopmodel *model, const QModelIndex &ind, QHash<int, QString> &updates);
void redo();
void undo();
private:
QString _dir; //!< desk directory
QString _fname; //!< filename of stack to adjust
QHash<int, QString> _old; //!< old details
QHash<int, QString> _new; //!< new details
};
/** this adds a new repository to the list
Undoing this removes the repository */
class UCAddRepository : public Desktopundocmd
{
public:
UCAddRepository (Desktopmodel *model, QString dirPath);
void redo();
void undo();
private:
QString _dirpath; //!< the new directory
};
/** this removes a new repository from the list
Undoing this adds the repository back */
class UCRemoveRepository : public Desktopundocmd
{
public:
UCRemoveRepository (Desktopmodel *model, QString dirPath);
void redo();
void undo();
private:
QString _dirpath; //!< the directory to remove
};