From 0f24892294a54be79741deae78464e9541d309f3 Mon Sep 17 00:00:00 2001
From: Nikhil Tanwar <2002nikhiltanwar@gmail.com>
Date: Sun, 16 Jul 2023 23:10:17 +0530
Subject: [PATCH 1/4] New settings entry: Move files to trash
Added a new settings entry to toggle if deleted files should move to trash/recycle bin.
---
resources/css/_settingsManager.css | 12 ++++++++
resources/i18n/en.json | 3 +-
resources/icons/check-solid.svg | 1 +
resources/kiwix.qrc | 1 +
src/settingsmanager.cpp | 10 ++++++-
src/settingsmanager.h | 4 +++
src/settingsview.cpp | 16 ++++++++++-
src/settingsview.h | 4 ++-
ui/settings.ui | 44 ++++++++++++++++++++++++++++++
9 files changed, 91 insertions(+), 4 deletions(-)
create mode 100644 resources/icons/check-solid.svg
diff --git a/resources/css/_settingsManager.css b/resources/css/_settingsManager.css
index c1ef9a1..38a3516 100644
--- a/resources/css/_settingsManager.css
+++ b/resources/css/_settingsManager.css
@@ -57,3 +57,15 @@ QPushButton:hover {
min-width: 14px;
font: bold;
}
+
+QCheckBox::indicator {
+ width: 16px;
+ height: 16px;
+ border: 2px solid black;
+ border-radius: 5px;
+ padding: 4px;
+}
+
+QCheckBox::indicator:checked {
+ image: url(:/icons/check-solid.svg);
+}
diff --git a/resources/i18n/en.json b/resources/i18n/en.json
index 7191d45..1512927 100644
--- a/resources/i18n/en.json
+++ b/resources/i18n/en.json
@@ -151,5 +151,6 @@
"resume-download": "Resume download",
"open-folder": "Open folder",
"couldnt-open-location": "Couldn't open location",
- "couldnt-open-location-text": "Kiwix is not able to open folder {{FOLDER}}"
+ "couldnt-open-location-text": "Kiwix is not able to open folder {{FOLDER}}",
+ "move-files-to-trash": "Move deleted files to trash"
}
diff --git a/resources/icons/check-solid.svg b/resources/icons/check-solid.svg
new file mode 100644
index 0000000..ba7a20b
--- /dev/null
+++ b/resources/icons/check-solid.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/resources/kiwix.qrc b/resources/kiwix.qrc
index a9a3c9b..c25bd43 100644
--- a/resources/kiwix.qrc
+++ b/resources/kiwix.qrc
@@ -60,5 +60,6 @@
icons/caret-right-solid.svg
icons/caret-up-solid.svg
icons/kiwix-logo.svg
+ icons/check-solid.svg
diff --git a/src/settingsmanager.cpp b/src/settingsmanager.cpp
index bfdf0e3..a0a7605 100644
--- a/src/settingsmanager.cpp
+++ b/src/settingsmanager.cpp
@@ -16,7 +16,7 @@ SettingsView* SettingsManager::getView()
{
if (m_view == nullptr) {
auto view = new SettingsView();
- view->init(m_zoomFactor * 100, m_downloadDir, m_monitorDir);
+ view->init(m_zoomFactor * 100, m_downloadDir, m_monitorDir, m_moveToTrash);
connect(view, &QObject::destroyed, this, [=]() { m_view = nullptr; });
m_view = view;
}
@@ -89,6 +89,13 @@ void SettingsManager::setMonitorDir(QString monitorDir)
emit(monitorDirChanged(monitorDir));
}
+void SettingsManager::setMoveToTrash(bool moveToTrash)
+{
+ m_moveToTrash = moveToTrash;
+ setSettings("moveToTrash", m_moveToTrash);
+ emit(moveToTrashChanged(m_moveToTrash));
+}
+
void SettingsManager::initSettings()
{
m_kiwixServerPort = m_settings.value("localKiwixServer/port", 8080).toInt();
@@ -96,4 +103,5 @@ void SettingsManager::initSettings()
m_downloadDir = m_settings.value("download/dir", QString::fromStdString(kiwix::getDataDirectory())).toString();
m_kiwixServerIpAddress = m_settings.value("localKiwixServer/ipAddress", QString("0.0.0.0")).toString();
m_monitorDir = m_settings.value("monitor/dir", QString("")).toString();
+ m_moveToTrash = m_settings.value("moveToTrash", true).toBool();
}
diff --git a/src/settingsmanager.h b/src/settingsmanager.h
index 2976ba4..501fe7e 100644
--- a/src/settingsmanager.h
+++ b/src/settingsmanager.h
@@ -27,6 +27,7 @@ public:
qreal getZoomFactor() const { return m_zoomFactor; }
QString getDownloadDir() const { return m_downloadDir; }
QString getMonitorDir() const { return m_monitorDir; }
+ bool getMoveToTrash() const { return m_moveToTrash; }
public slots:
void setKiwixServerPort(int port);
@@ -34,6 +35,7 @@ public slots:
void setZoomFactor(qreal zoomFactor);
void setDownloadDir(QString downloadDir);
void setMonitorDir(QString monitorDir);
+ void setMoveToTrash(bool moveToTrash);
private:
void initSettings();
@@ -42,6 +44,7 @@ signals:
void zoomChanged(qreal zoomFactor);
void downloadDirChanged(QString downloadDir);
void monitorDirChanged(QString monitorDir);
+ void moveToTrashChanged(bool moveToTrash);
private:
QSettings m_settings;
@@ -51,6 +54,7 @@ private:
qreal m_zoomFactor;
QString m_downloadDir;
QString m_monitorDir;
+ bool m_moveToTrash;
};
#endif // SETTINGSMANAGER_H
diff --git a/src/settingsview.cpp b/src/settingsview.cpp
index 0e4f8c4..973c17f 100644
--- a/src/settingsview.cpp
+++ b/src/settingsview.cpp
@@ -14,6 +14,7 @@ SettingsView::SettingsView(QWidget *parent)
QString styleSheet = QString(file.readAll());
ui->widget->setStyleSheet(styleSheet);
connect(ui->zoomPercentSpinBox, QOverload::of(&QSpinBox::valueChanged), this, &SettingsView::setZoom);
+ connect(ui->moveToTrashToggle, &QCheckBox::clicked, this, &SettingsView::setMoveToTrash);
connect(ui->browseButton, &QPushButton::clicked, this, &SettingsView::browseDownloadDir);
connect(ui->resetButton, &QPushButton::clicked, this, &SettingsView::resetDownloadDir);
connect(ui->monitorBrowse, &QPushButton::clicked, this, &SettingsView::browseMonitorDir);
@@ -21,6 +22,7 @@ SettingsView::SettingsView(QWidget *parent)
connect(KiwixApp::instance()->getSettingsManager(), &SettingsManager::downloadDirChanged, this, &SettingsView::onDownloadDirChanged);
connect(KiwixApp::instance()->getSettingsManager(), &SettingsManager::monitorDirChanged, this, &SettingsView::onMonitorDirChanged);
connect(KiwixApp::instance()->getSettingsManager(), &SettingsManager::zoomChanged, this, &SettingsView::onZoomChanged);
+ connect(KiwixApp::instance()->getSettingsManager(), &SettingsManager::moveToTrashChanged, this, &SettingsView::onMoveToTrashChanged);
ui->settingsLabel->setText(gt("settings"));
ui->zoomPercentLabel->setText(gt("zoom-level-setting"));
ui->downloadDirLabel->setText(gt("download-directory-setting"));
@@ -31,9 +33,10 @@ SettingsView::SettingsView(QWidget *parent)
ui->monitorBrowse->setText(gt("browse"));
ui->monitorHelp->setText("?");
ui->monitorHelp->setToolTip(gt("monitor-directory-tooltip"));
+ ui->moveToTrashLabel->setText(gt("move-files-to-trash"));
}
-void SettingsView::init(int zoomPercent, const QString &downloadDir, const QString &monitorDir)
+void SettingsView::init(int zoomPercent, const QString &downloadDir, const QString &monitorDir, const bool moveToTrash)
{
ui->zoomPercentSpinBox->setValue(zoomPercent);
ui->downloadDirPath->setText(downloadDir);
@@ -41,6 +44,7 @@ void SettingsView::init(int zoomPercent, const QString &downloadDir, const QStri
ui->monitorClear->hide();
}
ui->monitorDirPath->setText(monitorDir);
+ ui->moveToTrashToggle->setChecked(moveToTrash);
}
bool SettingsView::confirmDialog( QString messageText, QString messageTitle)
{
@@ -131,6 +135,11 @@ void SettingsView::setZoom(int zoomPercent)
KiwixApp::instance()->getSettingsManager()->setZoomFactor(zoomFactor);
}
+void SettingsView::setMoveToTrash(bool moveToTrash)
+{
+ KiwixApp::instance()->getSettingsManager()->setMoveToTrash(moveToTrash);
+}
+
void SettingsView::onDownloadDirChanged(const QString &dir)
{
ui->downloadDirPath->setText(dir);
@@ -151,3 +160,8 @@ void SettingsView::onZoomChanged(qreal zoomFactor)
qreal zoomPercent = zoomFactor * 100;
ui->zoomPercentSpinBox->setValue(zoomPercent);
}
+
+void SettingsView::onMoveToTrashChanged(bool moveToTrash)
+{
+ ui->moveToTrashToggle->setChecked(moveToTrash);
+}
diff --git a/src/settingsview.h b/src/settingsview.h
index c5e28cc..d68faef 100644
--- a/src/settingsview.h
+++ b/src/settingsview.h
@@ -11,16 +11,18 @@ class SettingsView : public QWidget
public:
SettingsView(QWidget *parent = nullptr);
~SettingsView(){};
- void init(int zoomPercent, const QString &downloadDir, const QString &monitorDir);
+ void init(int zoomPercent, const QString &downloadDir, const QString &monitorDir, const bool moveToTrash);
public Q_SLOTS:
void resetDownloadDir();
void browseDownloadDir();
void browseMonitorDir();
void clearMonitorDir();
void setZoom(int zoomPercent);
+ void setMoveToTrash(bool moveToTrash);
void onDownloadDirChanged(const QString &dir);
void onMonitorDirChanged(const QString &dir);
void onZoomChanged(qreal zoomFactor);
+ void onMoveToTrashChanged(bool moveToTrash);
private:
bool confirmDialogDownloadDir(const QString& dir);
bool confirmDialog(QString messageText, QString messageTitle);
diff --git a/ui/settings.ui b/ui/settings.ui
index 2d15ed3..33c4235 100644
--- a/ui/settings.ui
+++ b/ui/settings.ui
@@ -284,6 +284,50 @@
+ -
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
+ 0
+
+
-
+
+
+ Move deleted files to trash
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+
+
+
+ true
+
+
+
+
+
-
From ea5173706bebac8b4d50e1cf7ce186d3bb2b9dca Mon Sep 17 00:00:00 2001
From: Nikhil Tanwar <2002nikhiltanwar@gmail.com>
Date: Sun, 16 Jul 2023 23:55:07 +0530
Subject: [PATCH 2/4] Allow user to choose between deleting permanently or
moving to trash
Added functionality to delete files to trash or deleting them permanently.
---
resources/i18n/en.json | 4 +++-
src/contentmanager.cpp | 26 ++++++++++++++++++++++----
src/contentmanager.h | 2 +-
3 files changed, 26 insertions(+), 6 deletions(-)
diff --git a/resources/i18n/en.json b/resources/i18n/en.json
index 1512927..ad79185 100644
--- a/resources/i18n/en.json
+++ b/resources/i18n/en.json
@@ -152,5 +152,7 @@
"open-folder": "Open folder",
"couldnt-open-location": "Couldn't open location",
"couldnt-open-location-text": "Kiwix is not able to open folder {{FOLDER}}",
- "move-files-to-trash": "Move deleted files to trash"
+ "move-files-to-trash": "Move deleted files to trash",
+ "move-files-to-trash-text": "This action will move the file to trash.",
+ "perma-delete-files-text": "This action will permanently delete the file."
}
diff --git a/src/contentmanager.cpp b/src/contentmanager.cpp
index 60c0e6f..4fa2cf7 100644
--- a/src/contentmanager.cpp
+++ b/src/contentmanager.cpp
@@ -473,20 +473,37 @@ QString ContentManager::downloadBook(const QString &id)
return QString::fromStdString(download->getDid());
}
-void ContentManager::eraseBookFilesFromComputer(const QString dirPath, const QString fileName)
+void ContentManager::eraseBookFilesFromComputer(const QString dirPath, const QString fileName, const bool moveToTrash)
{
if (fileName == "*") {
return;
}
QDir dir(dirPath, fileName);
for(const QString& file: dir.entryList()) {
- dir.remove(file);
+ if (moveToTrash)
+ QFile::moveToTrash(dir.filePath(file));
+ else
+ dir.remove(file);
}
}
+QString formatText(QString text)
+{
+ QString finalText = "
";
+ finalText += text;
+ finalText += "";
+ return finalText;
+}
+
void ContentManager::eraseBook(const QString& id)
{
auto text = gt("delete-book-text");
+ const auto moveToTrash = KiwixApp::instance()->getSettingsManager()->getMoveToTrash();
+ if (moveToTrash) {
+ text += formatText(gt("move-files-to-trash-text"));
+ } else {
+ text += formatText(gt("perma-delete-files-text"));
+ }
text = text.replace("{{ZIM}}", QString::fromStdString(mp_library->getBookById(id).getTitle()));
KiwixConfirmBox *dialog = new KiwixConfirmBox(gt("delete-book"), text, false, mp_view);
dialog->show();
@@ -496,7 +513,7 @@ void ContentManager::eraseBook(const QString& id)
kiwix::Book book = mp_library->getBookById(id);
QString dirPath = QString::fromStdString(kiwix::removeLastPathElement(book.getPath()));
QString fileName = QString::fromStdString(kiwix::getLastPathElement(book.getPath())) + "*";
- eraseBookFilesFromComputer(dirPath, fileName);
+ eraseBookFilesFromComputer(dirPath, fileName, moveToTrash);
mp_library->removeBookFromLibraryById(id);
mp_library->save();
emit mp_library->bookmarksChanged();
@@ -576,7 +593,8 @@ void ContentManager::cancelBook(const QString& id)
}
QString dirPath = QString::fromStdString(kiwix::removeLastPathElement(download->getPath()));
QString filename = QString::fromStdString(kiwix::getLastPathElement(download->getPath())) + "*";
- eraseBookFilesFromComputer(dirPath, filename);
+ // incompleted downloaded file should be perma deleted
+ eraseBookFilesFromComputer(dirPath, filename, false);
mp_library->removeBookFromLibraryById(id);
mp_library->save();
emit(oneBookChanged(id));
diff --git a/src/contentmanager.h b/src/contentmanager.h
index 60db333..ad3bfe9 100644
--- a/src/contentmanager.h
+++ b/src/contentmanager.h
@@ -49,7 +49,7 @@ private:
QStringList m_categories;
QStringList getBookIds();
- void eraseBookFilesFromComputer(const QString dirPath, const QString filename);
+ void eraseBookFilesFromComputer(const QString dirPath, const QString filename, const bool moveToTrash);
QList> getBooksList();
ContentManagerModel *managerModel;
QMutex remoteLibraryLocker;
From 5ee18f1b40abbaa61661a0f3566cbb0657d0320d Mon Sep 17 00:00:00 2001
From: Nikhil Tanwar <2002nikhiltanwar@gmail.com>
Date: Mon, 17 Jul 2023 02:33:16 +0530
Subject: [PATCH 3/4] Always monitor download directory
This change puts download directory in an always monitoring state.
For any files downloaded using kiwix downloader (and hence saved in download directory), this will automatically update the library if file is restored after deletion.
---
src/kiwixapp.cpp | 19 ++++++++++++-------
src/library.cpp | 21 +++++++++++----------
src/library.h | 10 ++++++----
3 files changed, 29 insertions(+), 21 deletions(-)
diff --git a/src/kiwixapp.cpp b/src/kiwixapp.cpp
index 46f07c7..568b7d5 100644
--- a/src/kiwixapp.cpp
+++ b/src/kiwixapp.cpp
@@ -99,13 +99,17 @@ void KiwixApp::init()
}
});
connect(&m_watcher, &QFileSystemWatcher::directoryChanged, this, [=](QString monitorDir) {
- m_library.asyncLoadMonitorDir(monitorDir);
+ m_library.asyncUpdateFromDir(monitorDir);
});
QString monitorDir = m_settingsManager.getMonitorDir();
- if (monitorDir != "") {
- m_library.setMonitorDirZims(m_library.getLibraryZimsFromDir(monitorDir));
- m_watcher.addPath(monitorDir);
- m_library.asyncLoadMonitorDir(monitorDir);
+ QString downloadDir = m_settingsManager.getDownloadDir();
+ auto dirList = QSet({monitorDir, downloadDir});
+ for (auto dir : dirList) {
+ if (dir != "") {
+ m_library.setMonitorDirZims(dir, m_library.getLibraryZimsFromDir(dir));
+ m_watcher.addPath(dir);
+ m_library.asyncUpdateFromDir(dir);
+ }
}
}
@@ -284,13 +288,14 @@ bool KiwixApp::isCurrentArticleBookmarked()
void KiwixApp::setMonitorDir(const QString &dir) {
m_settingsManager.setMonitorDir(dir);
- m_library.setMonitorDirZims(QStringList());
+ m_library.setMonitorDirZims(dir, QStringList());
for (auto path : m_watcher.directories()) {
m_watcher.removePath(path);
}
if (dir != "") {
m_watcher.addPath(dir);
- m_library.asyncLoadMonitorDir(dir);
+ m_watcher.addPath(m_settingsManager.getDownloadDir());
+ m_library.asyncUpdateFromDir(dir);
}
}
diff --git a/src/library.cpp b/src/library.cpp
index 7d8d371..7ec7318 100644
--- a/src/library.cpp
+++ b/src/library.cpp
@@ -115,9 +115,9 @@ void Library::save()
m_library.writeBookmarksToFile(kiwix::appendToDirectory(m_libraryDirectory.toStdString(), "library.bookmarks.xml"));
}
-void Library::setMonitorDirZims(QStringList zimList)
+void Library::setMonitorDirZims(QString monitorDir, QStringList zimList)
{
- m_monitorDirZims = zimList;
+ m_knownZimsInDir[monitorDir] = zimList;
}
QStringList Library::getLibraryZimsFromDir(QString dir) const
@@ -133,13 +133,12 @@ QStringList Library::getLibraryZimsFromDir(QString dir) const
return zimsInDir;
}
-void Library::loadMonitorDir(QString monitorDir)
+void Library::updateFromDir(QString monitorDir)
{
- QMutex mutex;
- QMutexLocker locker(&mutex);
+ QMutexLocker locker(&m_updateFromDirMutex);
const QDir dir(monitorDir);
QStringList newDirEntries = dir.entryList({"*.zim"});
- QStringList oldDirEntries = m_monitorDirZims;
+ QStringList oldDirEntries = m_knownZimsInDir[monitorDir];
for (auto &str : newDirEntries) {
str = QDir::toNativeSeparators(monitorDir + "/" + str);
}
@@ -160,18 +159,20 @@ void Library::loadMonitorDir(QString monitorDir)
needsRefresh |= manager.addBookFromPath(book.toStdString());
}
for (auto bookPath : removedZims) {
- removeBookFromLibraryById(QString::fromStdString(m_library.getBookByPath(bookPath.toStdString()).getId()));
+ try {
+ removeBookFromLibraryById(QString::fromStdString(m_library.getBookByPath(bookPath.toStdString()).getId()));
+ } catch (...) {}
}
if (needsRefresh) {
- setMonitorDirZims(newDir.values());
emit(booksChanged());
+ setMonitorDirZims(monitorDir, newDir.values());
}
}
-void Library::asyncLoadMonitorDir(QString dir)
+void Library::asyncUpdateFromDir(QString dir)
{
QtConcurrent::run( [=]() {
- loadMonitorDir(dir);
+ updateFromDir(dir);
});
}
diff --git a/src/library.h b/src/library.h
index 45d113a..b741c67 100644
--- a/src/library.h
+++ b/src/library.h
@@ -11,6 +11,7 @@
#include
#include
#include
+#include
#define TQS(v) (QString::fromStdString(v))
#define FORWARD_GETTER(METH) QString METH() const { return TQS(mp_book->METH()); }
@@ -34,14 +35,14 @@ public:
QStringList listBookIds(const kiwix::Filter& filter, kiwix::supportedListSortBy sortBy, bool ascending) const;
const std::vector getBookmarks(bool onlyValidBookmarks = false) const { return m_library.getBookmarks(onlyValidBookmarks); }
QStringList getLibraryZimsFromDir(QString dir) const;
- void setMonitorDirZims(QStringList zimList);
+ void setMonitorDirZims(QString monitorDir, QStringList zimList);
void addBookToLibrary(kiwix::Book& book);
void removeBookFromLibraryById(const QString& id);
void addBookmark(kiwix::Bookmark& bookmark);
void removeBookmark(const QString& zimId, const QString& url);
void save();
- void loadMonitorDir(QString dir);
- void asyncLoadMonitorDir(QString dir);
+ void updateFromDir(QString dir);
+ void asyncUpdateFromDir(QString dir);
kiwix::Library& getKiwixLibrary() { return m_library; }
public slots:
const kiwix::Book& getBookById(QString id) const;
@@ -51,9 +52,10 @@ signals:
void bookmarksChanged();
private:
+ QMutex m_updateFromDirMutex;
kiwix::Library m_library;
QString m_libraryDirectory;
- QStringList m_monitorDirZims;
+ QMap m_knownZimsInDir;
friend class LibraryManipulator;
};
From e7dc33a3363c7191a9748f7f2a5e632aa95274fc Mon Sep 17 00:00:00 2001
From: Nikhil Tanwar <2002nikhiltanwar@gmail.com>
Date: Thu, 3 Aug 2023 11:35:57 +0530
Subject: [PATCH 4/4] Remove moveToTrash feature for QT versions pre 5.15
The settings entry is hidden when the QT version is not supported
The file is always permanently deleted - dialog box indicates this.
---
src/contentmanager.cpp | 8 +++++++-
src/settingsview.cpp | 5 +++++
2 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/src/contentmanager.cpp b/src/contentmanager.cpp
index 4fa2cf7..1c45467 100644
--- a/src/contentmanager.cpp
+++ b/src/contentmanager.cpp
@@ -480,10 +480,12 @@ void ContentManager::eraseBookFilesFromComputer(const QString dirPath, const QSt
}
QDir dir(dirPath, fileName);
for(const QString& file: dir.entryList()) {
+#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
if (moveToTrash)
QFile::moveToTrash(dir.filePath(file));
else
- dir.remove(file);
+#endif
+ dir.remove(file); // moveToTrash will always be false here, no check required.
}
}
@@ -498,7 +500,11 @@ QString formatText(QString text)
void ContentManager::eraseBook(const QString& id)
{
auto text = gt("delete-book-text");
+#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
const auto moveToTrash = KiwixApp::instance()->getSettingsManager()->getMoveToTrash();
+#else
+ const auto moveToTrash = false; // we do not support move to trash functionality for qt versions below 5.15
+#endif
if (moveToTrash) {
text += formatText(gt("move-files-to-trash-text"));
} else {
diff --git a/src/settingsview.cpp b/src/settingsview.cpp
index 973c17f..30f608b 100644
--- a/src/settingsview.cpp
+++ b/src/settingsview.cpp
@@ -34,6 +34,11 @@ SettingsView::SettingsView(QWidget *parent)
ui->monitorHelp->setText("?");
ui->monitorHelp->setToolTip(gt("monitor-directory-tooltip"));
ui->moveToTrashLabel->setText(gt("move-files-to-trash"));
+#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
+ ui->moveToTrashLabel->hide();
+ ui->moveToTrashToggle->hide();
+#endif
+
}
void SettingsView::init(int zoomPercent, const QString &downloadDir, const QString &monitorDir, const bool moveToTrash)