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