new style for the progressbars, display more info
[case] / src / fileoperator.h
index 7672de1..076250d 100644 (file)
 #define FILEOPERATOR_H
 
 #include <QWidget>
-#include <QProgressBar>
 #include <QFileInfo>
 #include <QThread>
 #include <QMutex>
 #include <QWaitCondition>
 #include <QDir>
+#include <QFSFileEngine>
 #include <QMap>
+#include <QSet>
+
+#include "progressbar.h"
 
 
 class FileManipulatorThread;
@@ -36,25 +39,43 @@ class FileOperator : public QWidget {
 
 public:
     // DONT_ASK_ONCE is a hackish way to avoid asking twice to overwrite the same directory when moving
-    enum Response{NONE, ABORT, RETRY, IGNORE, KEEP, OVERWRITE, DONT_ASK_ONCE};
+    enum Response{NONE, ABORT, RETRY, IGNORE, KEEP, OVERWRITE, SKIP_DIR, ASK, DONT_ASK_ONCE};
 
     FileOperator(QWidget *parent = 0);
 
+    static QString shortenPath(const QString &path);
+    static QString unwindPath(const QString &path);
+
     void deleteFiles(const QFileInfoList &files);
     void copyFiles(const QFileInfoList &files, QDir &destination);
     void moveFiles(const QFileInfoList &files, QDir &destination);
 
 public slots:
-    void showErrorPrompt(FileManipulatorThread* manipulator, const QString &message, const int err);
-    void showOverwritePrompt(FileManipulatorThread* manipulator, const QString &fileName, const bool dirOverDir);
+    void showErrorPrompt(FileManipulatorThread* manipulator,
+        const QString &message,
+        const QString &fileName,
+        const int err);
+    void showOverwritePrompt(FileManipulatorThread* manipulator,
+        const QString &fileName,
+        const bool dirOverDir);
+    void showInputFilenamePrompt(FileManipulatorThread* manipulator,
+        const QFileInfo &fileName,
+        const bool dirOverDir);
+
     void remove(FileManipulatorThread* manipulator);
     void setBarSize(FileManipulatorThread* manipulator, unsigned int size);
     void updateProgress(FileManipulatorThread* manipulator, int value);
+    void updateMainText(FileManipulatorThread* manipulator, const QString &text);
+    void showPaused(FileManipulatorThread* manipulator);
+
+    void togglePauseOperation(FileManipulatorThread* manipulator);
+    void abortOperation(FileManipulatorThread* manipulator);
 
 protected:
     void caterNewThread(FileManipulatorThread *thread);
 
     QList<FileManipulatorThread*> manipulatorList;
+    QPixmap deleteIcon, inverseDeleteIcon, copyIcon, inverseCopyIcon, moveIcon, inverseMoveIcon;
 };
 
 
@@ -63,51 +84,85 @@ class FileManipulatorThread : public QThread {
 
 public:
     explicit FileManipulatorThread(const QFileInfoList files, QDir dest = QDir());
+    ~FileManipulatorThread();
     void setResponse(const FileOperator::Response response, const bool appyToAll = false, const int err = 0);
 
-    QProgressBar *widget;
+    void setText(int value);
+
+    void wake();
+
+    ProgressBar *progressBar;
+
+    QMutex mutex;
+    // the new name entered from the overwrite dialog
+    QString newNameFromDialog;
+    // flags to abort/pause the operation
+    bool abort, pause;
 
 protected:
     void processFiles(const QFileInfoList &files);
     virtual void perform(const QFileInfo &file) = 0;
 
-    bool remove(QString &filename, const bool ignoreDirNotEmpty = false);
-    bool remove(const QFileInfoList &files, const bool ignoreDirNotEmpty = false);
-    bool remove(const QFileInfo &file, const bool ignoreDirNotEmpty = false);
+    bool remove(QString &fileName, const bool doUpdates = false);
+    bool remove(const QFileInfoList &files, const bool doUpdates = false);
+    bool remove(const QFileInfo &file, const bool doUpdates = false);
 
-    void copy(const QFileInfo &file, const bool removeAfterCopy);
+    void copy(const QFileInfo &file);
 
-    unsigned int countFiles(const QFileInfoList &files);
-    unsigned int calculateFileSize(const QFileInfoList &files);
+    unsigned int calculateFileSize(const QFileInfoList &files,
+        const bool count = false,
+        const bool addSize = false);
 
     QFileInfoList listDirFiles(const QString &dirPath);
 
     void setBarSize(unsigned int size);
     void updateProgress(int value);
-    void updateFile(const QString &fileName);
+    void updateFile(const QString &name);
 
+    void waitOnCond();
+
+    bool checkSequentialFile(const QFSFileEngine &engine);
+
+    QWaitCondition waitCond;
+
+    // files to process by the operation
     const QFileInfoList files;
+    // destination for files - changes as the operation recurses into directories
     QDir dest;
 
+    // responses from the dialog prompts (error and overwrite)
     FileOperator::Response response;
     FileOperator::Response overwriteAll;
-    bool abort;
+    // an array indicating whether to always ignore the error of index errno
     bool ignoreAll[256];
 
-    QMap<QString, qint64> fileSizeMap;
+    // set of files that won't be deleted by the remove(...) functions
+    // used when move(...) would not overwrite target file to ensure the source file doesn't get deleted
+    QSet<QString> removeExcludeFiles;
 
-    QMutex mutex;
-    QWaitCondition waitCond;
+    // A map of file paths to their size. Not the actual size, but what is calculated for the
+    // purpose of the progressbar for the given operation. So either fileSize/BLOCK_SIZE or simply
+    // 1 for a file and file count for dirs (or both for copy&delete)
+    QMap<QString, qint64> fileSizeMap;
 
+    // the text of the progressBar (the format)
+    QString barText;
+    // stamp of the last ETA recalculation - done every second
+    time_t lastTimeUpdate;
+    time_t startTime, waitTime;
+    char timeBuf[10];
+    // progress information of the bar and for the current file
     unsigned int barSize, barValue, fileSize, fileValue;
 
 signals:
-    void showErrorPrompt(FileManipulatorThread*, const QString&, const int);
+    void showErrorPrompt(FileManipulatorThread*, const QString&, const QString&, const int);
     void showOverwritePrompt(FileManipulatorThread*, const QString&, const bool);
+    void showInputFilenamePrompt(FileManipulatorThread*, const QFileInfo&, const bool);
     void finished(FileManipulatorThread*);
     void setBarSize(FileManipulatorThread*, unsigned int);
     void updateProgress(FileManipulatorThread*, int);
-    void updateFile(FileManipulatorThread*, const QString&);
+    void updateFileName(FileManipulatorThread*, QString);
+    void operationPaused(FileManipulatorThread*);
 };
 
 
@@ -115,7 +170,7 @@ class DeleteThread : public FileManipulatorThread {
     Q_OBJECT
 
 public:
-    explicit DeleteThread(const QFileInfoList &files) : FileManipulatorThread(files) {}
+    explicit DeleteThread(const QFileInfoList &files);
 
 protected:
     void run();
@@ -127,7 +182,7 @@ class CopyThread : public FileManipulatorThread {
     Q_OBJECT
 
 public:
-    explicit CopyThread(const QFileInfoList &files, QDir &dest) : FileManipulatorThread(files, dest) {}
+    explicit CopyThread(const QFileInfoList &files, QDir &dest);
 
 protected:
     void run();
@@ -139,7 +194,7 @@ class MoveThread : public FileManipulatorThread {
     Q_OBJECT
 
 public:
-    explicit MoveThread(const QFileInfoList &files, QDir &dest) : FileManipulatorThread(files, dest) {}
+    explicit MoveThread(const QFileInfoList &files, QDir &dest);
 
 protected:
     void run();