fixed error handling on sequential file check
[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 <QFileInfo>
23 #include <QThread>
24 #include <QMutex>
25 #include <QWaitCondition>
26 #include <QDir>
27 #include <QFSFileEngine>
28 #include <QMap>
29 #include <QSet>
30
31 #include "progressbar.h"
32
33
34 class FileManipulatorThread;
35
36
37 class FileOperator : public QWidget {
38     Q_OBJECT
39
40 public:
41     // DONT_ASK_ONCE is a hackish way to avoid asking twice to overwrite the same directory when moving
42     enum Response{NONE, ABORT, RETRY, IGNORE, KEEP, OVERWRITE, SKIP_DIR, ASK, DONT_ASK_ONCE};
43
44     FileOperator(QWidget *parent = 0);
45
46     static QString shortenPath(const QString &path);
47     static QString unwindPath(const QString &path);
48
49     void deleteFiles(const QFileInfoList &files);
50     void copyFiles(const QFileInfoList &files, QDir &destination);
51     void moveFiles(const QFileInfoList &files, QDir &destination);
52
53 public slots:
54     void showErrorPrompt(FileManipulatorThread* manipulator,
55         const QString &message,
56         const QString &fileName,
57         const int err);
58     void showOverwritePrompt(FileManipulatorThread* manipulator,
59         const QString &fileName,
60         const bool dirOverDir);
61     void showInputFilenamePrompt(FileManipulatorThread* manipulator,
62         const QFileInfo &fileName,
63         const bool dirOverDir);
64
65     void remove(FileManipulatorThread* manipulator);
66     void setBarSize(FileManipulatorThread* manipulator, unsigned int size);
67     void updateProgress(FileManipulatorThread* manipulator, int value);
68     void showPaused(FileManipulatorThread* manipulator);
69
70     void togglePauseOperation(FileManipulatorThread* manipulator);
71     void abortOperation(FileManipulatorThread* manipulator);
72
73 protected:
74     void caterNewThread(FileManipulatorThread *thread);
75
76     QList<FileManipulatorThread*> manipulatorList;
77 };
78
79
80 class FileManipulatorThread : public QThread {
81     Q_OBJECT
82
83 public:
84     explicit FileManipulatorThread(const QFileInfoList files, QDir dest = QDir());
85     ~FileManipulatorThread();
86     void setResponse(const FileOperator::Response response, const bool appyToAll = false, const int err = 0);
87
88     void setText(int value);
89
90     void wake();
91
92     ProgressBar *progressBar;
93
94     QMutex mutex;
95     // the new name entered from the overwrite dialog
96     QString newNameFromDialog;
97     // flags to abort/pause the operation
98     bool abort, pause;
99
100 protected:
101     void processFiles(const QFileInfoList &files);
102     virtual void perform(const QFileInfo &file) = 0;
103
104     bool remove(QString &fileName, const bool doUpdates = false);
105     bool remove(const QFileInfoList &files, const bool doUpdates = false);
106     bool remove(const QFileInfo &file, const bool doUpdates = false);
107
108     void copy(const QFileInfo &file);
109
110     unsigned int calculateFileSize(const QFileInfoList &files,
111         const bool count = false,
112         const bool addSize = false);
113
114     QFileInfoList listDirFiles(const QString &dirPath);
115
116     void setBarSize(unsigned int size);
117     void updateProgress(int value);
118     void updateFile(const QString &name);
119
120     void waitOnCond();
121
122     bool checkSequentialFile(const QFSFileEngine &engine);
123
124     QWaitCondition waitCond;
125
126     // files to process by the operation
127     const QFileInfoList files;
128     // destination for files - changes as the operation recurses into directories
129     QDir dest;
130
131     // responses from the dialog prompts (error and overwrite)
132     FileOperator::Response response;
133     FileOperator::Response overwriteAll;
134     // an array indicating whether to always ignore the error of index errno
135     bool ignoreAll[256];
136
137     // set of files that won't be deleted by the remove(...) functions
138     // used when move(...) would not overwrite target file to ensure the source file doesn't get deleted
139     QSet<QString> removeExcludeFiles;
140
141     // A map of file paths to their size. Not the actual size, but what is calculated for the
142     // purpose of the progressbar for the given operation. So either fileSize/BLOCK_SIZE or simply
143     // 1 for a file and file count for dirs (or both for copy&delete)
144     QMap<QString, qint64> fileSizeMap;
145
146     // the name of the file thats being processed (for progressBar) and the text of the progressBar (the format)
147     QString fileName, barText;
148     // stamp of the last ETA recalculation - done every second
149     time_t lastTimeUpdate;
150     time_t startTime, waitTime;
151     char timeBuf[10];
152     // progress information of the bar and for the current file
153     unsigned int barSize, barValue, fileSize, fileValue;
154
155 signals:
156     void showErrorPrompt(FileManipulatorThread*, const QString&, const QString&, const int);
157     void showOverwritePrompt(FileManipulatorThread*, const QString&, const bool);
158     void showInputFilenamePrompt(FileManipulatorThread*, const QFileInfo&, const bool);
159     void finished(FileManipulatorThread*);
160     void setBarSize(FileManipulatorThread*, unsigned int);
161     void updateProgress(FileManipulatorThread*, int);
162     void operationPaused(FileManipulatorThread*);
163 };
164
165
166 class DeleteThread : public FileManipulatorThread {
167     Q_OBJECT
168
169 public:
170     explicit DeleteThread(const QFileInfoList &files);
171
172 protected:
173     void run();
174     virtual void perform(const QFileInfo &file);
175 };
176
177
178 class CopyThread : public FileManipulatorThread {
179     Q_OBJECT
180
181 public:
182     explicit CopyThread(const QFileInfoList &files, QDir &dest);
183
184 protected:
185     void run();
186     virtual void perform(const QFileInfo &file);
187 };
188
189
190 class MoveThread : public FileManipulatorThread {
191     Q_OBJECT
192
193 public:
194     explicit MoveThread(const QFileInfoList &files, QDir &dest);
195
196 protected:
197     void run();
198     virtual void perform(const QFileInfo &file);
199     void rename(const QFileInfoList &files, const QDir &dest);
200 };
201
202
203 #endif // FILEOPERATOR_H