Fixed delete dialog silent fail
[qtfileman:qtfileman.git] / src / filedeleter.cpp
1 #include "filedeleter.h"
2
3 #include <QFileInfo>
4 #include <QMutex>
5 #include <QDir>
6
7 #include <QtDebug>
8
9 #include <unistd.h>
10 #include <errno.h>
11
12 #define SYNCRONIZED_BLOCK QMutexLocker locker(&mutex)
13
14 struct FileDeleterPrivate {
15     QMutex mutex;
16     bool canceled;
17     bool preparing;
18     quint64 deleteCount;
19     quint64 itemCount;
20     QFileInfoList list;
21
22     void setCanceled(bool c) {
23         SYNCRONIZED_BLOCK;
24         canceled = c;
25     }
26
27     bool isCanceled() {
28         SYNCRONIZED_BLOCK;
29         return canceled;
30     }
31 };
32
33 FileDeleter::FileDeleter(const QFileInfoList& list, QObject *parent) :
34     QThread(parent),
35     d_ptr(new FileDeleterPrivate)
36 {
37     d_ptr->list = list;
38 }
39
40 FileDeleter::~FileDeleter()
41 {
42     delete d_ptr;
43 }
44
45 void FileDeleter::run()
46 {
47     d_ptr->setCanceled(false);
48     d_ptr->itemCount = 0;
49     d_ptr->preparing = true;
50     deleteItems(d_ptr->list);
51     d_ptr->deleteCount = 0;
52     d_ptr->preparing = false;
53     deleteItems(d_ptr->list);
54     emit endDelete(d_ptr->isCanceled());
55 }
56
57 void FileDeleter::abortDelete()
58 {
59     d_ptr->setCanceled(true);
60 }
61
62 void FileDeleter::deleteItems(const QFileInfoList &items)
63 {
64     foreach(QFileInfo item, items) {
65         if (d_ptr->isCanceled())
66             return;
67         if (item.isDir())
68             deleteDir(QDir(item.canonicalFilePath()));
69         else
70             deleteFile(item);
71     }
72 }
73
74 void FileDeleter::deleteFile(const QFileInfo &file)
75 {
76     if (d_ptr->preparing) {
77         d_ptr->itemCount++;
78         emit prepareProgress(d_ptr->itemCount);
79     } else {
80         QFile fileToRemove(file.absoluteFilePath());
81         if (!fileToRemove.remove()) {
82             emit fail(tr("%s: %s")
83                       .arg(file.absoluteFilePath())
84                       .arg(fileToRemove.errorString()));
85             d_ptr->setCanceled(true);
86         } else {
87             d_ptr->deleteCount++;
88             emit delProgress(
89                     double(d_ptr->deleteCount)/d_ptr->itemCount*100.0,
90                     file.absoluteFilePath());
91         }
92     }
93 }
94
95 void FileDeleter::deleteDir(const QDir &dir)
96 {
97     if (d_ptr->preparing) {
98         d_ptr->itemCount++;
99         emit prepareProgress(d_ptr->itemCount);
100     }
101     deleteItems(dir.entryInfoList(QDir::NoDotAndDotDot|QDir::AllEntries|QDir::Hidden|QDir::System));
102     if (!d_ptr->isCanceled() && !d_ptr->preparing) {
103         if (::rmdir(dir.absolutePath().toLocal8Bit().constData()) == -1) {
104             emit fail(tr("%s: %s")
105                       .arg(dir.absolutePath())
106                       .arg(QString(::strerror(errno))));
107             d_ptr->setCanceled(true);
108         } else {
109             d_ptr->deleteCount++;
110             emit delProgress(
111                     double(d_ptr->deleteCount)/d_ptr->itemCount*100.0,
112                     dir.absolutePath());
113         }
114     }
115 }