-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathdesktopmodel.h
1444 lines (1078 loc) · 54.6 KB
/
desktopmodel.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
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*
License: GPL-2
An electronic filing cabinet: scan, print, stack, arrange
Copyright (C) 2009 Simon Glass, [email protected]
.
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 <QContextMenuEvent>
#include <QMouseEvent>
#include <QKeyEvent>
class QFontMetrics;
class Desk;
class Desktopitem;
class Desktopmodelconv;
class Desktopundostack;
class Filepage;
class PPage;
class Measure;
class Paperscan;
class QImage;
struct err_info;
struct max_page_info;
#include "qstring.h"
#include "qwidget.h"
#include "desk.h"
#include "file.h"
#include "qabstractitemmodel.h"
#include <QSortFilterProxyModel>
class QUndoStack;
#if 0
typedef struct ditem_info
{
file_info *file; //! the file this item refers to
QPixmap pixmap; //! the pixmap for this item
bool valid; //! true if we have valid info for this item
} ditem_info;
#endif
/* a directory containing a list of files
typedef struct diritem_info
{
QList<File *> _file;
} diritem_info;
*/
typedef struct pagepos_info
{
QPoint pos;
int pagenum;
int pagecount;
} pagepos_info;
/** implements an item model, which contains a number of thumbnails representing
paper stacks */
class Desktopmodel : public QAbstractItemModel
{
Q_OBJECT
// allow the undo classes to access our state and in particular the opXXX functions
friend class UCTrashStacks;
friend class UCMove;
friend class UCDuplicate;
friend class UCUnstackStacks;
friend class UCUnstackPage;
friend class UCStackStacks;
friend class UCChangeDir;
friend class UCRenameStack;
friend class UCRenamePage;
friend class UCDeletePages;
friend class UCUpdateAnnot;
friend class UCAddRepository;
friend class UCRemoveRepository;
public:
Desktopmodel(QObject *parent);
~Desktopmodel();
// debug output
QDebug debug (void) const;
enum e_role
{
/* roles available in this model:
Qt::DisplayRole QString stack name
Qt::EditRole QString stack name (same as display)
Qt::DecorationRole QIcon a QIcon of the pixmap
*/
Role_position = Qt::UserRole, // QPoint position
Role_pixmap, // QPixmap pixmap
Role_pagenum, // Int page number
Role_pagecount, // Int page count
Role_pagename, // QString page name
Role_preview_maxsize, // QSize max preview size for file (this is the preview pixmap)
Role_title_maxsize, // QSize title size
Role_pagename_maxsize, // QSize max page name size
Role_maxsize, // QSize max size including all features
Role_pagename_list, // QStringList list of page names
Role_valid, // bool item has been built
Role_droptarget, // bool true if this item is the drop target
Role_message, // QString error or descriptive message
Role_filename, // QString the file's filename (excluding directory)
Role_pathname, // QString the file's full path
Role_author, // QString the author
Role_title, // QString the title (filename with perhaps some special characters like /)
Role_keywords, // QString the keywords
Role_notes, // QString the notes
Role_error, // QString an error message, if available
Role_count
};
/** returns a pointer to the undo stack for this model
\return pointer to model's undo stack */
Desktopundostack *getUndoStack (void);
/** sets the model converter to use when needed for accessing the
source model (as opposed to any proxy which might be in the way
This class should only use this for assertion purposes
\param modelconv new model converter to use */
void setModelConv (Desktopmodelconv *modelconv);
/** return the total number of pages of all stacks in the list */
int listPagecount (const QModelIndexList &list);
/************************ MODEL ACCESS FUNCTIONS *******************/
/** retrieve data from the model
\param index index to retrieve
\param role role required
\returns data from the model */
QVariant data (const QModelIndex &index, int role = Qt::DisplayRole) const;
/** set data in the model and update the view
\param index index to update
\param value data value
\param role role required */
bool setData (const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
/** returns flags for a given model index
\param index index to check
\returns flags for the given index */
Qt::ItemFlags flags (const QModelIndex &index) const;
/** returns the number of rows under a given parent
\param parent the parent index to check
\returns number of rows under the parent */
int rowCount (const QModelIndex &parent) const;
/** returns the number of columns under a given parent
\param parent the parent index to check
\returns number of columns under the parent */
int columnCount (const QModelIndex &parent) const;
/** returns the drop actions supported by this model
\returns drop actions */
Qt::DropActions supportedDropActions() const;
/** returns an index given the parent, row and column
\param row row to retrieve
\param column column to retrieve
\param parent parent index
\returns the index of the item, or QModelIndex() if none was found */
QModelIndex index (int row, int col, const QModelIndex& parent) const;
/** looks up a filename and returns its index
\param fname filename to look up
\param parent parent index (must be an index of a desk)
\returns the model index for that filename, which is null if not found */
QModelIndex index (const QString &fname, QModelIndex parent) const;
/** returns the parent of a given index
\param index index to check
\returns the parent of the item */
QModelIndex parent (const QModelIndex& index) const;
/** remove a Desk and all its children and File objects
This only updates our internal data - it does not delete any files on disk.
\param index Index of Desk to delete (must be a top-level item)
\returns true on success, false on failure (which would be bad) */
bool removeDesk (const QString &pathname);
//* returns a list of mime types that we can generate */
QStringList mimeTypes() const;
QMimeData *mimeData (const QModelIndexList &list) const;
/** given a parent index which points to a desk, get the desk's directory
name. It is safe to store this (instead of a model index) as it
shouldn't change
\param parent parent to look up
\returns full directory path for parent */
QString deskToDirname (QModelIndex parent);
/** given a directory name, return an index to the desk for this directory.
If not found then an invalid model index will be returned
\param dir directory path to look up
\returns the model index for that directory */
QModelIndex deskFromDirname (QString &dir);
/** builds a filename list from the given model index list. This list
is a string containing each filename (not full pathname) separated
by a space. Where the filename includes a space, the filename is
enclosed in double quotes
\param list list of model indexes to include in the list
\returns the list of filenames */
QStringList listToFilenames (const QModelIndexList &list);
/** builds a list of model indexes given a list of filenames. If any one
filename is not found, then a null model index will be inserted in
that position
\param slist list of filenames to look up
\returns a list of model indexes, one for each filename */
QModelIndexList listFromFilenames (const QStringList &slist,
QModelIndex parent);
/** gets the file info for a given model index
\param index the model index to look up
\returns a pointer to the file information */
File *getFile (const QModelIndex &index) const;
/** gets the desk info for a given model index
\param index the model index to look up
\returns a pointer to the file information, or 0 if not valid */
Desk *getDesk (const QModelIndex &index) const;
QString &deskRootDir (QModelIndex index);
pagepos_info getPosData (const QModelIndex &index) const;
/************************ OTHER FUNCTIONS *******************/
/** sort a model index list in the way that delete operations require
it. This is by order of row number, highest first. This allows
a delete to proceed through the list from the start, deleting
as it goes, without having to worry about row numbers later in
the list changing underneath it.
\param list list to sort */
void sortForDelete (QModelIndexList &list);
/** sort a model index list so that items appear from top to bottom,
left to right */
void sortByPosition (QModelIndexList &list);
/** print some progress information in the status bar */
void progress (const char *fmt, ...);
/** cancel a background refresh operation */
void stopUpdate (void);
#if 0
/** update the pixmap of an item item (which depends on its page number)
\param di item information
\param pagename returns page name of current page */
void updatePixmap (ditem_info &di, QString &pagename);
#endif
/** resize all items in the model by measuring them. This ignores all
previously-held information about size and starts again. It scans
each page of each stack to obtain the maximum preview size and
pagename size. Then it updates the model, which causes the view
to update
\param parent parent desk */
void resizeAll (QModelIndex parent);
void setDropTarget (const QModelIndex &index);
const QPersistentModelIndex *dropTarget (void);
bool isMinorChange (void) const { return _minor_change; }
/* a list of filenames has been added to a directory. If the directory
has been loaded into a desk, this desk needs to be notified. This
function handle that. It simply adds the files to the desk
\param dir directory which now contains the new files
\param fnamelist list of filenames added */
void addFilesToDesk (QString dir, QStringList &fnamelist);
/* a list of filenames has been removed from a directory. If the directory
has been loaded into a desk, this desk needs to be notified. This
function handle that. It simply removes the files from the desk */
void removeFilesFromDesk (QString dir, QStringList &fnamelist);
/** clear all files in a desk */
void clearAll (QModelIndex &parent);
/****************** operations which support undo / redo ***************/
/** add a number of stacks to a given stack. Stacks are added in order
and are inserted before the destination stack's current page.
Supports undo
Note: src MUST BE SORTED from highest row number to lowest, otherwise
this algorithm will crash!
\param dest destination stack to add to
\param src list of source stacks, ordered from high row number to low
\returns error, or NULL if none */
err_info *stackItems (QModelIndex dest, QModelIndexList &src,
QList<QPoint> *poslist);
bool checkerr (struct err_info *err);
/** duplicate a list of stacks. The new stacks will be added to the end
of the model. Supports undo
Commits any pending scan.
\param list the list of stacks to duplicate
\param parent parent stack
\returns error, or NULL if none */
err_info *duplicate (QModelIndexList &list, QModelIndex parent);
void duplicatePdf (QModelIndexList &list, QModelIndex parent);
void duplicateJpeg (QModelIndexList &list, QModelIndex parent);
/** duplicate a file as a .max file
\param item item to duplicate (NULL means the current item in the viewer)
\param parent parent stack
\param odd_even which pages to duplicate: 1 = even, 2 = odd, 3 = both */
void duplicateMax (QModelIndexList &list, QModelIndex parent, int odd_even = 3);
/** delete a list of stacks by moving them to the trash. The list may
contain null model indexes, which are ignored. Supports undo
Commits any pending scan
\param list list of stacks to delete, ordered from high row number to low
\param parent parent desk
\returns error, or NULL if none */
void trashStacks (QModelIndexList &list, QModelIndex parent);
/** conveniece function similar to the above
Commits any pending scan
\param index stack to delete */
void trashStack (QModelIndex &ind);
/** unstack a list of stacks. Every page in the stack will get its own
separate stack containing a single page. Supports undo
Commits any pending scan
\param list list of stacks to unstack
\param parent parent desk
\returns error, or NULL if none */
err_info *unstackStacks (QModelIndexList &list, QModelIndex parent);
/** unstack a single page from a stack, to create a new stack containing
only that page. Supports undo
Commits any pending scan
\param ind the index of the stack to process
\param pagenum the page number to unstack (-1 for current page)
\param remove true to remove the page from the stack also */
void unstackPage (QModelIndex &ind, int pagenum, bool remove);
#if 0
// maybe implement this later
/** unstack a list of pages from a stack, to create a new stack containing
those pages. Supports undo.
It is also possible to just mark the pages as deleted. They will still
disappear but in this case a new stack is not created. A markOnly
operation can be undone simply by reversing the marking, whereas
otherwise the pages must be restacked into the original stack (assuming
they were removed).
Commits any pending scan
\param ind the index of the stack to process
\param pages the page numbers to unstack
\param remove true to remove the pages from the stack also
\param markOnly true to just mark them deleted and not create the new stack
false to create the new stack */
void unstackPages (QModelIndex &ind, QBitArray &pages, bool remove, bool markOnly);
#endif
/** delete a list of pages from a stack. Supports undo.
Commits any pending scan
\param ind the index of the stack to process
\param pages the page numbers to unstack, bit n is true to unstack page n */
void deletePages (QModelIndex &ind, QBitArray &pages);
/** create and execute a new undo record to move stacks to a new position.
Supports undo
\param list list of stacks to move
\param parent parent desk
\param oldplist oldp osition for each stack
\param plist new position for each stack */
void move (QModelIndexList &list, QModelIndex parent, QList<QPoint> &oldplist, QList<QPoint> &plist);
/** move a list of files to the given directory. Supports undo
Commits any pending scan
\param list list of stacks to move
\param parent desk containing stacks
\param dir destination directory
\param translist returns list of resulting filenames
\param copy true to copy, false to move */
void moveToDir (QModelIndexList &list, QModelIndex parent, QString &dir,
QStringList &trashlist, bool copy = false);
/** change directory. Supports undo
The root directory is used to set up a trash directory for the model.
We allow an option to not use the undo stack - this is for the first
first directory change on startup, since undoing that would put us back
into not having a current directory. We don't want to user to be able
to undo this first directory change.
Commits any pending scan
\param dirpath directory to search
\param rootpath root directory for this branch of the model
\param allow_undo use the undo else (else we just do the operation now) */
void changeDir (QString dirPath, QString rootPath, bool allow_undo);
/** rename a stack. Supports undo.
\param index stack to rename
\param newname new name for stack, excluding .max extension */
void renameStack (const QModelIndex &index, QString newname);
/** rename a stack's current page. Supports undo.
\param index stack containing page to rename
\param newname new name for page */
void renamePage (const QModelIndex &index, QString newname);
/** add a new repository to the list. Supports undo.
\param dirPath path to repository */
void addRepository (QString dir_path);
/** remove a repository from the list. Supports undo.
\param dirPath path to repository */
void removeRepository (QString dir_path);
/** arrange the selected items in the given order. Supports undo
Commits any pending scan
\param type order type (t_arrangeBy)
\param list list of items to arrange
\param parent parent desk
\param oldplist current (original) position of items */
void arrangeBy (int type, QModelIndexList &list, QModelIndex parent, QList<QPoint> &oldplist);
/** update the annotation text on a stack. Supports undo
Does not affect a pending scan
\param ind index to update
\param updates updates to apply, indexed by MAXA_... */
void updateAnnot (QModelIndex &ind, QHash<int, QString> &updates);
/** returns an annotation text item on a stack
If an error occurs then this will be stored with the file and available
through the Role_error role.
\param ind index to check
\param type annotation type to return (File::e_annot)
\returns returns text for annotation, if no error and it is available
*/
QString getAnnot (QModelIndex ind, File::e_annot type) const;
QModelIndex showFilesIn(const QString& dirPath, const QString &rootPath,
Measure *meas);
/*********************** UNDO / REDO operations **********************/
protected:
/* these 'op' functions are used by the undo / redo stack to actually
perform operations on the model */
/** delete a list of stacks by moving them to the trash or another
directory. The list may contain null model indexes, which are ignored
\param list list of stacks to delete, ordered from high row number to low
\param trashlist returns a list of filenames of the files that were placed in
the trash. These will normally be the same as the original
filenames, except when a file of the same name already
exists in the trash, in which case we rename this new one
\param dest use this directory instead of the trash
\param copy true to copy instead of move
\returns error, or NULL if none */
err_info *opTrashStacks (QModelIndexList &list, QModelIndex parent,
QStringList &trashlist, QString &dest, bool copy);
/** undelete a list of files by moving them from the trash or another
directory. Each file is renamed as it is moved according to the
supplied name in filenames. You must have one 'filenames' entry for
each 'trashlist' entry.
\param trashlist list of stacks to undelete (filename only, no path)
\param filenames list of filenames to use, one for each trash file
(note this may be updated if the filenames have to change)
\param pagepos if non-NULL, this is a list of pagepos_info records,
one for each of the files to be undelete. This provides
the position and page number for each undeleted file
\param src use this directory instead of the trash
\param copy true to copy instead of move
\returns error, or NULL if none */
err_info *opUntrashStacks (QStringList &trashlist, QModelIndex parent, QStringList &filenames,
QList<pagepos_info> *pagepos, QString &src, bool copy);
/** move a list of stacks to the given positions
\param list list of stacks to move
\param newpos new position for each stack */
void opMoveStacks (QModelIndexList &list, QModelIndex parent, QList<QPoint> &newpos);
/** duplicate a list of stacks, recording its name in namelist (which
should be empty when this function is called.
\param list list of stacks to duplicate
\param parent parent desk
\param namelist returns list of filenames used
\param type type to duplicate as e_type (e.g. max, pdf)
\param odd_even only supported for type = Type_max
normally 3
- bit 0 set means duplicate even pages
- bit 1 set means duplicate odd pages
\returns error, or NULL if none */
err_info *opDuplicateStacks (QModelIndexList &list, QModelIndex parent, QStringList &namelist,
File::e_type type, int odd_even = 3);
/** delete a single stack without moving it to the trash
\param index stack to delete
\returns error, or NULL if none */
err_info *opDeleteStack (QModelIndex &index);
/** delete a list of stacks without moving them to the trash. The list may
contain null model indexes, which are ignored
\param list list of stacks to delete, ordered from high row number to low
\returns error, or NULL if none */
err_info *opDeleteStacks (QModelIndexList &list, QModelIndex parent);
/** unstack a list of stacks. For each stackm this produces a number of new
separate stacks. We record the names of these in _newnames. Each item
of _newnames is a string list, containing one filename for each page
of that stack that was unstacked
\param list list of stacks to unstack
\param newnames list of name lists for each stack
\returns error, or NULL if none */
err_info *opUnstackStacks (QModelIndexList &list, QModelIndex parent,
QList<QStringList> &newnames);
/** given a list of stacks, this function restacks pages onto them. The
pages to be restacked are in pagenames which is a list of stringlists,
one for each stack. The contents of each stringlist are scanned and
each filename is stacked back onto the original stack, in order
\param list list of stacks to replenish
\param pagenames list of stringlists, each containing a list of page
names to restack
\param destpage destination page in each destination stack to insert
the new stacks into (-1 for the current page in each
stack, in which case it returns the actual dest page
of the first stack)
\returns error, or NULL if none */
err_info *opRestackStacks (QModelIndexList &list, QModelIndex parent,
QList<QModelIndexList> &pages_list, int &destpage);
/** unstack a single page from a stack, creating a new stack for it
containing just that page
\param index index of stack to find page
\param pagenum page number to unstack (-1 for current). Returns page
actually unstacked
\param remove true to remove the page from the source stack, false
to just copy it (leaving the original page intact)
\param newname returns the name given to the new single-page stack
\returns error, or NULL if none */
err_info *opUnstackPage (QModelIndex &index, int &pagenum,
bool remove, QString &newname);
/** stack a list of stacks into a stack at page 'pagenum'
\param index index of destination stack
\param list list of stacks to stack
\param pagenum destination page number (stacks will be inserted here).
If this is -1, the current page in the destination
stack is used (and returns this number)
\returns error, or NULL if none */
err_info *opStackStacks (QModelIndex &index, QModelIndexList &list, int &pagenum);
/** unstack a number of groups of pages from a source stack, putting each
group into its own new stack. The pages are removed from the source
stack.
The first page to be unstacked is srcpagenum. The files list gives
information about each file to be unstacked - in particular it gives
the position and the number of pages in each new stack
The total number of pages, n, to be unstacked is therefore the number of
items in the files list (and also namelist). After this operation, pages
'srcpagenum' to 'srcpagenum + n - 1' will have been removed from the stack
This operation is really used for undoing a stack operation, where a
number of stacks were stacked into another stack.
\param src source stack from which to unstack
\param newnames the name of each new stack
\param srcpagenum the first source stack page number to unstack
\param pagepos information about each new stack
->pagecount number of pages to unstack
->pos position to unstack to
\returns error, or NULL if none */
err_info *opUnstackFromStack (QModelIndex &pagepos, QStringList &_newnames,
int srcpagenum, QList<pagepos_info> &files);
/** Change directory operation
The root directory is used to set up a trash directory for the model.
\param dirpath directory to search
\param rootpath root directory for this branch of the model */
void opChangeDir (QString &dirPath, QString &rootPath);
/** rename a stack
\param index the stack to rename
\param newname the new name to be given (this will auto-rename and
return what is actually assigned
\returns error, or NULL if none */
err_info *opRenameStack (const QModelIndex &index, QString &newname);
/** rename a page and move to show that page
\param index the stack containing the page to rename
\param pagenum the page number to rename
\param newname the new name to be given
\returns error, or NULL if none */
err_info *opRenamePage (const QModelIndex &index, int pagenum, QString &newname);
/** delete a list of pages from a stack.
\param ind the index of the stack to process
\param pages the page numbers to delete, bit n is true to delete page n
\param del_info information about deleted pages, used for undo
\param count returns number of pages deleted */
err_info *opDeletePages (QModelIndex &ind, QBitArray &pages,
QByteArray &del_info, int &count);
/** undelete a list of pages from a stack.
This works by restoring the supplied page info into the stack and marking
those pages as undeleted again.
The pages array is the one passed to opDeletePages() so needs to be
processed in forward order. For example, if in a delete bits 2 and 4 were
set we might have:
0 fred
1 john
2 mary x
3 bert
4 mark x
5 anne
6 joan
where x marks a page to be deleted. Afterwards we get:
0 fred
1 john
2 bert
3 anne
4 joan
For the undelete, we also get bits 2 and 4 set. These bits mark where
pages should be inserted. The first is before page 2:
0 fred
1 john
2 mary x
3 bert
4 anne
5 joan
and the second before page 4 to give the original stack
0 fred
1 john
2 mary x
3 bert
4 mark x
5 anne
6 joan
\param ind the index of the stack to process
\param pages the page numbers to undelete, bit n is true to undelete page n
\param del_info information about deleted pages, previously stored
\param count number of pages to restore */
err_info *opUndeletePages (QModelIndex &ind, QBitArray &pages,
QByteArray &del_info, int count);
/** update the annotation strings of a stack
\param ind index of stack to update
\param updates updates to make, indexed by type (MAXA_...) */
err_info *opUpdateAnnot (QModelIndex &ind, QHash<int, QString> &updates);
/** update the list of repositories by adding/removing a dir
\param dirpath Directory to add / delete
\param add_not_delete true to add, false to delete */
void opUpdateRepositoryList (QString &dirpath, bool add_not_delete);
public:
// this is public since it is called from outside the undo system
/** email a set of files as attachments, optionally converting them first.
If more than one file is sent, then they are packed into a zip archive
as it seems that Thunderbird can't cope with more than one attachment
through its '-compose- interface
\param parent desk containing the files
\param slist list of files to send
\param type type to convert to (or Type_other to leave as is)
\returns error or NULL if ok */
err_info *opEmailFiles (QModelIndex parent, QModelIndexList &slist,
File::e_type type);
#if 0 //p
Desktopitem *itemFind (const QPoint & opos, int &which);
Desk *getDesk () { return _desk; }
void repaintItem( Desktopitem *item );
#endif
/****************************** scanning operations **********************/
/*
beginScan() is called when we start scanning into a new stack
- it creates the stack and emits beginningScan() for the benefit
of Pagewidget
pageStarting() is called when a new page is starting to be scanned.
- we simply remember this in case we are asked to create a preview
for Pagewidget
- we also emit beginningPage() for the benefit of Pagewidget
(this will likely call Desktopmodel::registerScaledImageSize() to
tell Desktopmodel what scale is required for previews)
pageProgress() is called regularly as the page is scanned in
- we record the data that we are given in case we are asked to
create a preview later on
- we also emit dataAddedToPage() for the benefit of Pagewidget
(which might call Desktopmodel::getScaledImage())
- if we were told about a required scaled image size
by a call to Desktopmodel::setScaledImageSize (see above)
then we emit newScaledImage() for the benefit of Pagewidget.
It will draw it on the screen
addPageToScan() is called after every page is scanned to add a new
page to the stack. It adds the page and emits newScannedPage()
for the benefit of Pagewidget. At this point all page progress
is irrelevant as the page has been committed
confirmScan() is called at the end to finalise the stack
or:
cancelScan() is called at the end to cancel the stack
- it deleted it as if the scan had never taken place
*/
/** add a new paper stack to the model for scanning into. Later, you
must call either confirmScan() to save it or cancelScan() to
remove it.
\param parent parent desk to scan into
\param stack stack to add
\returns error, or NULL if none */
err_info *beginScan (QModelIndex parent, const QString &stack_name);
/** confirm and save the pending scan */
err_info *confirmScan (void);
/** cancel and remove the pending scan */
err_info *cancelScan (void);
/** add a newly scanned page to the current scan file
\param max_page_info info about the page
\param coverageStr page coverage info */
err_info *addPageToScan (const Filepage *mp, const QString &coverageStr);
/** returns the size of the stack currently being scanned. It will grow
as more pages are added */
int getScanSize (void);
/** a new page is starting to be scanned */
void pageStarting (Paperscan &scan, const PPage *page);
/** new data has arrived for the current page */
void pageProgress (Paperscan &scan, const PPage *page);
/** tell Desktopmodel what size we want the scaled images to be */
void registerScaledImageSize (const QSize &size);
/** this is a bit of a monster... it commits changes to a stack, but this
is not always simple. There are three cases:
1 we are doing it from a pagemodel, where we want to support undo
2 we are doing it from a pagemodel, but undo cannot be supported
because the user has clicked elsewhere - conceptually we can
imagine that the scan can commit become a single operation
3 the pagemodel has lost everything, because another directory
has been selected
For 1 we use the normal 'undo' functions
For 2 we use the direct 'op' functions
For 3 we use maxdesk directly (yukk!)
In order to simplify this we would need Desktopmodel to be more
aware of directories, perhaps unifying Desktopmodel and Dirmodel.
But for the moment that seems a bridge to far, with other uncertain
implications, so we are left with this function
\param ind index of stack to commit (will be ignored if the directory
has changed
\param del_count number of pages to delete
\param page bit n means delete page n
\param allow_undo true to allow the user to undo this */
err_info *scanCommitPages (QModelIndex &ind, int del_count,
QBitArray &page, bool allow_undo);
signals:
/** indicate that we are about to start scanning into an item
\index item we are scanning into */
void beginningScan (const QModelIndex &index);
/** indicate that we are about to scan a new page */
void beginningPage (void);
/** indicate that a scan is about to end
\param cancel true if scan was cancelled (so stack is about to be deleted) */
void endingScan (bool cancel);
/** indicate that a new scaled image is available for the page currently
being scanned
\param image the new part of the image
\param scaled_linenum destination start line number for this image */
void newScaledImage (const QImage &image, int scaled_linenum);
/** request that the scan stack be commited, because we are about to
operate on it */
void commitScanStack (void);
/** request an update to the repository list
\param dirpath Directory to add to / delete from list
\param add_not_delete true to add, false to delete
*/
void updateRepositoryList (QString &dirpath, bool add_not_delete);
private:
bool getNewScaledImage (Paperscan &scan, const PPage *page, const char *data,
int nbytes, QImage &image, int &scaled_linenum);
/** check if the list contains the scan stack - if so commit it
returns false if we are scanning and so the operation is not permitted */
bool checkScanStack (QModelIndexList &list, QModelIndex parent);
/***********************************************************************/
public:
#if 0 //p
Q3DragObject *dragObject(void);
/** confirm the addition of a paper stack to a maxdesk */
struct err_info *confirmPaperstack (Desk *maxdesk, file_info *f);
struct err_info *cancelPaperstack (Desk *maxdesk, file_info *f);
err_info *operation (Desk::operation_t type, int ival);
/** sets the debug level to use for newly created max files */
void setDebugLevel (int level);
/** returns true if the user is busy scrolling through pages */
bool userBusy (void);
void updatePage (Desktopitem *item);
void pageLeft (Desktopitem *item = 0);
void pageRight (Desktopitem *item = 0);
#endif
//! record that no items have been added
void resetAdded (void);
/** record that items are about to be added
\param parent parent (desk) which will contain new items */
void aboutToAdd (QModelIndex parent);
/** request information on items added by a recent operation
\param parent parent containing new items
\param start returns row of first item added
\param count returns number of items added
\returns true if any items added */
bool itemsAdded (QModelIndex parent, int &start, int &count);
//! returns the current directory path being displayed
QString &getDirPath (void);
/** clear the current directory path */
void resetDirPath (void);
/** read an image for page 'pagenum' of the file
\param ind model index to read
\param pagenum page number to read
\param do_scale always false, not used (TODO: remove?)
\param *imagep returns pointer to allocated image (must be deleted by caller)
\param Size returns original size of image (image may be slightly
larger to accomodate padding margins)