76f5535c41a745d49af202547aa527e76a2488ab
[case] / src / fileoperator.h
1 // case - file manager for N900
2 // Copyright (C) 2010 Lukas Hrazky <lukkash@email.cz>
3 // 
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 // 
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 // 
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17
18 #ifndef FILEOPERATOR_H
19 #define FILEOPERATOR_H
20
21 #include <QWidget>
22 #include <QProgressBar>
23 #include <QFileInfo>
24 #include <QThread>
25 #include <QMutex>
26 #include <QWaitCondition>
27 #include <QDir>
28 #include <QMap>
29 #include <QSet>
30
31
32 class FileManipulatorThread;
33
34
35 class FileOperator : public QWidget {
36     Q_OBJECT
37
38 public:
39     // DONT_ASK_ONCE is a hackish way to avoid asking twice to overwrite the same directory when moving
40     enum Response{NONE, ABORT, RETRY, IGNORE, KEEP, OVERWRITE, SKIP_DIR, ASK, DONT_ASK_ONCE};
41
42     FileOperator(QWidget *parent = 0);
43
44     static QString shortenPath(const QString &path);
45     static QString unwindPath(const QString &path);
46
47     void deleteFiles(const QFileInfoList &files);
48     void copyFiles(const QFileInfoList &files, QDir &destination);
49     void moveFiles(const QFileInfoList &files, QDir &destination);
50
51 public slots:
52     void showErrorPrompt(FileManipulatorThread* manipulator,
53         const QString &message,
54         const QString &fileName,
55         const int err);
56     void showOverwritePrompt(FileManipulatorThread* manipulator,
57         const QString &fileName,
58         const bool dirOverDir);
59     void showInputFilenamePrompt(FileManipulatorThread* manipulator,
60         const QFileInfo &fileName,
61         const bool dirOverDir);
62
63     void remove(FileManipulatorThread* manipulator);
64     void setBarSize(FileManipulatorThread* manipulator, unsigned int size);
65     void updateProgress(FileManipulatorThread* manipulator, int value);
66
67 protected:
68     void caterNewThread(FileManipulatorThread *thread);
69
70     QList<FileManipulatorThread*> manipulatorList;
71 };
72
73
74 class FileManipulatorThread : public QThread {
75     Q_OBJECT
76
77 public:
78     explicit FileManipulatorThread(const QFileInfoList files, QDir dest = QDir());
79     ~FileManipulatorThread();
80     void setResponse(const FileOperator::Response response, const bool appyToAll = false, const int err = 0);
81
82     void setText(int value);
83
84     QProgressBar *progressBar;
85
86     time_t startTime;
87     QMutex mutex;
88     QWaitCondition waitCond;
89     // the new name entered from the overwrite dialog
90     QString newNameFromDialog;
91
92 protected:
93     void processFiles(const QFileInfoList &files);
94     virtual void perform(const QFileInfo &file) = 0;
95
96     bool remove(QString &fileName, const bool doUpdates = false);
97     bool remove(const QFileInfoList &files, const bool doUpdates = false);
98     bool remove(const QFileInfo &file, const bool doUpdates = false);
99
100     void copy(const QFileInfo &file);
101
102     unsigned int calculateFileSize(const QFileInfoList &files,
103         const bool count = false,
104         const bool addSize = false);
105
106     QFileInfoList listDirFiles(const QString &dirPath);
107
108     void setBarSize(unsigned int size);
109     void updateProgress(int value);
110     void updateFile(const QString &name);
111
112     // files to process by the operation
113     const QFileInfoList files;
114     // destination for files - changes as the operation recurses into directories
115     QDir dest;
116
117     // responses from the dialog prompts (error and overwrite)
118     FileOperator::Response response;
119     FileOperator::Response overwriteAll;
120     // a flag to abort the operation
121     bool abort;
122     // an array indicating whether to always ignore the error of index errno
123     bool ignoreAll[256];
124
125     // set of files that won't be deleted by the remove(...) functions
126     // used when move(...) would not overwrite target file to ensure the source file doesn't get deleted
127     QSet<QString> removeExcludeFiles;
128
129     // A map of file paths to their size. Not the actual size, but what is calculated for the
130     // purpose of the progressbar for the given operation. So either fileSize/BLOCK_SIZE or simply
131     // 1 for a file and file count for dirs (or both for copy&delete)
132     QMap<QString, qint64> fileSizeMap;
133
134     // the name of the file thats being processed (for progressBar) and the text of the progressBar (the format)
135     QString fileName, barText;
136     // stamp of the last ETA recalculation - done every second
137     time_t lastTimeUpdate;
138     char timeBuf[10];
139     // progress information of the bar and for the current file
140     unsigned int barSize, barValue, fileSize, fileValue;
141
142 signals:
143     void showErrorPrompt(FileManipulatorThread*, const QString&, const QString&, const int);
144     void showOverwritePrompt(FileManipulatorThread*, const QString&, const bool);
145     void showInputFilenamePrompt(FileManipulatorThread*, const QFileInfo&, const bool);
146     void finished(FileManipulatorThread*);
147     void setBarSize(FileManipulatorThread*, unsigned int);
148     void updateProgress(FileManipulatorThread*, int);
149 };
150
151
152 class DeleteThread : public FileManipulatorThread {
153     Q_OBJECT
154
155 public:
156     explicit DeleteThread(const QFileInfoList &files);
157
158 protected:
159     void run();
160     virtual void perform(const QFileInfo &file);
161 };
162
163
164 class CopyThread : public FileManipulatorThread {
165     Q_OBJECT
166
167 public:
168     explicit CopyThread(const QFileInfoList &files, QDir &dest);
169
170 protected:
171     void run();
172     virtual void perform(const QFileInfo &file);
173 };
174
175
176 class MoveThread : public FileManipulatorThread {
177     Q_OBJECT
178
179 public:
180     explicit MoveThread(const QFileInfoList &files, QDir &dest);
181
182 protected:
183     void run();
184     virtual void perform(const QFileInfo &file);
185     void rename(const QFileInfoList &files, const QDir &dest);
186 };
187
188
189 #endif // FILEOPERATOR_H