new style for the progressbars, display more info
[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 updateMainText(FileManipulatorThread* manipulator, const QString &text);
69     void showPaused(FileManipulatorThread* manipulator);
70
71     void togglePauseOperation(FileManipulatorThread* manipulator);
72     void abortOperation(FileManipulatorThread* manipulator);
73
74 protected:
75     void caterNewThread(FileManipulatorThread *thread);
76
77     QList<FileManipulatorThread*> manipulatorList;
78     QPixmap deleteIcon, inverseDeleteIcon, copyIcon, inverseCopyIcon, moveIcon, inverseMoveIcon;
79 };
80
81
82 class FileManipulatorThread : public QThread {
83     Q_OBJECT
84
85 public:
86     explicit FileManipulatorThread(const QFileInfoList files, QDir dest = QDir());
87     ~FileManipulatorThread();
88     void setResponse(const FileOperator::Response response, const bool appyToAll = false, const int err = 0);
89
90     void setText(int value);
91
92     void wake();
93
94     ProgressBar *progressBar;
95
96     QMutex mutex;
97     // the new name entered from the overwrite dialog
98     QString newNameFromDialog;
99     // flags to abort/pause the operation
100     bool abort, pause;
101
102 protected:
103     void processFiles(const QFileInfoList &files);
104     virtual void perform(const QFileInfo &file) = 0;
105
106     bool remove(QString &fileName, const bool doUpdates = false);
107     bool remove(const QFileInfoList &files, const bool doUpdates = false);
108     bool remove(const QFileInfo &file, const bool doUpdates = false);
109
110     void copy(const QFileInfo &file);
111
112     unsigned int calculateFileSize(const QFileInfoList &files,
113         const bool count = false,
114         const bool addSize = false);
115
116     QFileInfoList listDirFiles(const QString &dirPath);
117
118     void setBarSize(unsigned int size);
119     void updateProgress(int value);
120     void updateFile(const QString &name);
121
122     void waitOnCond();
123
124     bool checkSequentialFile(const QFSFileEngine &engine);
125
126     QWaitCondition waitCond;
127
128     // files to process by the operation
129     const QFileInfoList files;
130     // destination for files - changes as the operation recurses into directories
131     QDir dest;
132
133     // responses from the dialog prompts (error and overwrite)
134     FileOperator::Response response;
135     FileOperator::Response overwriteAll;
136     // an array indicating whether to always ignore the error of index errno
137     bool ignoreAll[256];
138
139     // set of files that won't be deleted by the remove(...) functions
140     // used when move(...) would not overwrite target file to ensure the source file doesn't get deleted
141     QSet<QString> removeExcludeFiles;
142
143     // A map of file paths to their size. Not the actual size, but what is calculated for the
144     // purpose of the progressbar for the given operation. So either fileSize/BLOCK_SIZE or simply
145     // 1 for a file and file count for dirs (or both for copy&delete)
146     QMap<QString, qint64> fileSizeMap;
147
148     // the text of the progressBar (the format)
149     QString barText;
150     // stamp of the last ETA recalculation - done every second
151     time_t lastTimeUpdate;
152     time_t startTime, waitTime;
153     char timeBuf[10];
154     // progress information of the bar and for the current file
155     unsigned int barSize, barValue, fileSize, fileValue;
156
157 signals:
158     void showErrorPrompt(FileManipulatorThread*, const QString&, const QString&, const int);
159     void showOverwritePrompt(FileManipulatorThread*, const QString&, const bool);
160     void showInputFilenamePrompt(FileManipulatorThread*, const QFileInfo&, const bool);
161     void finished(FileManipulatorThread*);
162     void setBarSize(FileManipulatorThread*, unsigned int);
163     void updateProgress(FileManipulatorThread*, int);
164     void updateFileName(FileManipulatorThread*, QString);
165     void operationPaused(FileManipulatorThread*);
166 };
167
168
169 class DeleteThread : public FileManipulatorThread {
170     Q_OBJECT
171
172 public:
173     explicit DeleteThread(const QFileInfoList &files);
174
175 protected:
176     void run();
177     virtual void perform(const QFileInfo &file);
178 };
179
180
181 class CopyThread : public FileManipulatorThread {
182     Q_OBJECT
183
184 public:
185     explicit CopyThread(const QFileInfoList &files, QDir &dest);
186
187 protected:
188     void run();
189     virtual void perform(const QFileInfo &file);
190 };
191
192
193 class MoveThread : public FileManipulatorThread {
194     Q_OBJECT
195
196 public:
197     explicit MoveThread(const QFileInfoList &files, QDir &dest);
198
199 protected:
200     void run();
201     virtual void perform(const QFileInfo &file);
202     void rename(const QFileInfoList &files, const QDir &dest);
203 };
204
205
206 #endif // FILEOPERATOR_H