1 /*
2 SPDX-FileCopyrightText: 2008 Joris Guisson <joris.guisson@gmail.com>
3 SPDX-FileCopyrightText: 2008 Ivan Vasic <ivasic@gmail.com>
4
5 SPDX-License-Identifier: GPL-2.0-or-later
6 */
7 #include "deletedatafilesjob.h"
8 #include <QDir>
9 #include <kio/deletejob.h>
10 #include <kio/jobuidelegate.h>
11 #include <util/fileops.h>
12 #include <util/functions.h>
13 #include <util/log.h>
14
15 namespace bt
16 {
17 DeleteDataFilesJob::DeleteDataFilesJob(const QString &base)
18 : Job(true, nullptr)
19 , base(base)
20 , directory_tree(nullptr)
21 {
22 }
23
24 DeleteDataFilesJob::~DeleteDataFilesJob()
25 {
26 delete directory_tree;
27 }
28
29 void DeleteDataFilesJob::addFile(const QString &file)
30 {
31 files.append(QUrl::fromLocalFile(file));
32 }
33
34 void DeleteDataFilesJob::addEmptyDirectoryCheck(const QString &fpath)
35 {
36 if (!directory_tree)
37 directory_tree = new DirTree(base);
38
39 directory_tree->insert(fpath);
CacheFile()40 }
41
42 void DeleteDataFilesJob::start()
43 {
44 active_job = KIO::del(files, KIO::HideProgressInfo);
45 connect(active_job, &KIO::Job::result, this, &DeleteDataFilesJob::onDeleteJobDone);
46 }
47
48 void DeleteDataFilesJob::onDeleteJobDone(KJob *j)
49 {
~CacheFile()50 if (j != active_job)
51 return;
52
53 if (active_job->error())
54 active_job->uiDelegate()->showErrorMessage();
55 active_job = nullptr;
changePath(const QString & npath)56
57 if (directory_tree)
58 directory_tree->doDeleteOnEmpty(base);
59
60 setError(0);
openFile(Mode mode)61 emitResult();
62 }
63
64 void DeleteDataFilesJob::kill(bool quietly)
65 {
66 Q_UNUSED(quietly);
67 }
68
69 DeleteDataFilesJob::DirTree::DirTree(const QString &name)
70 : name(name)
71 {
72 subdirs.setAutoDelete(true);
73 }
74
75 DeleteDataFilesJob::DirTree::~DirTree()
76 {
77 }
78
79 void DeleteDataFilesJob::DirTree::insert(const QString &fpath)
80 {
81 int i = fpath.indexOf(bt::DirSeparator());
open(const QString & path,Uint64 size)82 if (i == -1) // last part of fpath is a file, so we need to ignore that
83 return;
84
85 QString dn = fpath.left(i);
86 DirTree *d = subdirs.find(dn);
87 if (!d) {
88 d = new DirTree(dn);
89 subdirs.insert(dn, d);
map(MMappeable * thing,Uint64 off,Uint32 size,Mode mode)90 }
91
92 d->insert(fpath.mid(i + 1));
93 }
94
95 void DeleteDataFilesJob::DirTree::doDeleteOnEmpty(const QString &base)
96 {
97 bt::PtrMap<QString, DirTree>::iterator i = subdirs.begin();
98 while (i != subdirs.end()) {
99 i->second->doDeleteOnEmpty(base + i->first + bt::DirSeparator());
100 ++i;
101 }
102
103 QDir dir(base);
104 QStringList el = dir.entryList(QDir::AllEntries | QDir::System | QDir::Hidden);
105 el.removeAll(".");
106 el.removeAll("..");
107 if (el.count() == 0) {
108 // no childern so delete the directory
109 Out(SYS_DIO | LOG_DEBUG) << "Deleting empty directory : " << base << endl;
110 bt::Delete(base, true);
111 }
112 }
113 }
114