diff --git src/gui/generalsettings.cpp src/gui/generalsettings.cpp
index dd8037d..7aed285 100644
--- src/gui/generalsettings.cpp
+++ src/gui/generalsettings.cpp
@@ -69,6 +69,7 @@ GeneralSettings::GeneralSettings(QWidget *parent) :
connect(_ui->newFolderLimitCheckBox, SIGNAL(toggled(bool)), SLOT(saveMiscSettings()));
connect(_ui->newFolderLimitSpinBox, SIGNAL(valueChanged(int)), SLOT(saveMiscSettings()));
connect(_ui->newExternalStorage, SIGNAL(toggled(bool)), SLOT(saveMiscSettings()));
+ connect(_ui->moveToTrashCheckBox, SIGNAL(toggled(bool)), SLOT(saveMiscSettings()));
#ifndef WITH_CRASHREPORTER
_ui->crashreporterCheckBox->setVisible(false);
@@ -119,6 +120,7 @@ void GeneralSettings::loadMiscSettings()
_ui->newFolderLimitCheckBox->setChecked(newFolderLimit.first);
_ui->newFolderLimitSpinBox->setValue(newFolderLimit.second);
_ui->newExternalStorage->setChecked(cfgFile.confirmExternalStorage());
+ _ui->moveToTrashCheckBox->setChecked(cfgFile.moveToTrash());
_ui->monoIconsCheckBox->setChecked(cfgFile.monoIcons());
}
@@ -155,6 +157,7 @@ void GeneralSettings::saveMiscSettings()
cfgFile.setNewBigFolderSizeLimit(_ui->newFolderLimitCheckBox->isChecked(),
_ui->newFolderLimitSpinBox->value());
cfgFile.setConfirmExternalStorage(_ui->newExternalStorage->isChecked());
+ cfgFile.setMoveToTrash(_ui->moveToTrashCheckBox->isChecked());
}
void GeneralSettings::slotToggleLaunchOnStartup(bool enable)
diff --git src/gui/generalsettings.ui src/gui/generalsettings.ui
index 20f2c86..d2fcd66 100644
--- src/gui/generalsettings.ui
+++ src/gui/generalsettings.ui
@@ -129,6 +129,13 @@
-
+
+
+ Move deleted files to trash
+
+
+
+ -
diff --git src/libsync/configfile.cpp src/libsync/configfile.cpp
index f7350ce..5821011 100644
--- src/libsync/configfile.cpp
+++ src/libsync/configfile.cpp
@@ -69,6 +69,7 @@ static const char downloadLimitC[] = "BWLimit/downloadLimit";
static const char newBigFolderSizeLimitC[] = "newBigFolderSizeLimit";
static const char useNewBigFolderSizeLimitC[] = "useNewBigFolderSizeLimit";
static const char confirmExternalStorageC[] = "confirmExternalStorage";
+static const char moveToTrashC[] = "moveToTrash";
static const char maxLogLinesC[] = "Logging/maxLogLines";
@@ -608,6 +609,16 @@ void ConfigFile::setConfirmExternalStorage(bool isChecked)
setValue(confirmExternalStorageC, isChecked);
}
+bool ConfigFile::moveToTrash() const
+{
+ return getValue(moveToTrashC, QString(), true).toBool();
+}
+
+void ConfigFile::setMoveToTrash(bool isChecked)
+{
+ setValue(moveToTrashC, isChecked);
+}
+
bool ConfigFile::promptDeleteFiles() const
{
QSettings settings(configFile(), QSettings::IniFormat);
diff --git src/libsync/configfile.h src/libsync/configfile.h
index 0fe3b3c..174b745 100644
--- src/libsync/configfile.h
+++ src/libsync/configfile.h
@@ -107,6 +107,8 @@ public:
void setNewBigFolderSizeLimit(bool isChecked, quint64 mbytes);
bool confirmExternalStorage() const;
void setConfirmExternalStorage(bool);
+ bool moveToTrash() const;
+ void setMoveToTrash(bool);
static bool setConfDir(const QString &value);
diff --git src/libsync/filesystem.cpp src/libsync/filesystem.cpp
index be63fec..5d2a302 100644
--- src/libsync/filesystem.cpp
+++ src/libsync/filesystem.cpp
@@ -14,7 +14,9 @@
#include "filesystem.h"
+#include "configfile.h"
#include "utility.h"
+#include
#include
#include
#include
@@ -588,15 +590,79 @@ bool FileSystem::remove(const QString &fileName, QString *errorString)
setFileReadOnly(fileName, false);
}
#endif
- QFile f(fileName);
- if (!f.remove()) {
- if (errorString) {
- *errorString = f.errorString();
+#ifdef Q_OS_UNIX
+ int _moveToTrash = -1;
+ ConfigFile cfgFile;
+ _moveToTrash = cfgFile.moveToTrash() ? 1 : 0;
+
+ if(_moveToTrash == 1){
+ Q_UNUSED(errorString);
+ qDebug() << "moving" << fileName << "to trash";
+ if (!moveToTrash(fileName)) {
+ return false;
}
+ }
+ if(_moveToTrash == 0) {
+#endif
+ QFile f(fileName);
+ if (!f.remove()) {
+ if (errorString) {
+ *errorString = f.errorString();
+ }
+ return false;
+ }
+#ifdef Q_OS_UNIX
+ }
+#endif
+ return true;
+}
+
+#ifdef Q_OS_UNIX
+bool FileSystem::moveToTrash(const QString &fileName)
+{
+ QString trashPath, trashFilePath, trashInfoPath;
+ QString xdgDataHome = QFile::decodeName(qgetenv("XDG_DATA_HOME"));
+ if (xdgDataHome.isEmpty()) {
+ trashPath=QDir::homePath()+"/.local/share/Trash/"; // trash path that should exist
+ } else {
+ trashPath=xdgDataHome+"/Trash/";
+ }
+
+ trashFilePath=trashPath+"files/"; // trash file path contain delete files
+ trashInfoPath=trashPath+"info/"; // trash info path contain delete files information
+
+ if (!(QDir().mkpath(trashFilePath) && QDir().mkpath(trashInfoPath)))
+ return false; //mkpath will return true if path exists
+
+ // create file format for trash info file----- START
+ QFileInfo f(fileName);
+ QFile infoFile(trashInfoPath+f.fileName()+".trashinfo"); //filename+.trashinfo // create file information file in /.local/share/Trash/info/ folder
+
+ infoFile.open(QIODevice::ReadWrite);
+
+ QTextStream stream(&infoFile); // for write data on open file
+
+ QByteArray info = "[Trash Info]\n";
+ info += "Path=";
+ info += QUrl::toPercentEncoding(f.absoluteFilePath(),"~_-./");
+ info += '\n';
+ info += "DeletionDate=";
+ info += QDateTime::currentDateTime().toString(Qt::ISODate).toLatin1();
+ info += '\n';
+
+ stream << info;
+
+ infoFile.close();
+
+ // create info file format of trash file----- END
+
+ QDir file;
+ if (!file.rename(f.absoluteFilePath(),trashFilePath+f.fileName())){ // rename(file old path, file trash path)
return false;
}
return true;
}
+#endif
bool FileSystem::isFileLocked(const QString& fileName)
{
diff --git src/libsync/filesystem.h src/libsync/filesystem.h
index 36ac8d5..599b6a6 100644
--- src/libsync/filesystem.h
+++ src/libsync/filesystem.h
@@ -162,6 +162,9 @@ bool uncheckedRenameReplace(const QString &originFileName,
*/
bool OWNCLOUDSYNC_EXPORT remove(const QString &fileName, QString *errorString = 0);
+#ifdef Q_OS_UNIX
+bool moveToTrash(const QString &filename);
+#endif
/**
* Replacement for QFile::open(ReadOnly) followed by a seek().
* This version sets a more permissive sharing mode on Windows.
diff --git src/libsync/propagatorjobs.cpp src/libsync/propagatorjobs.cpp
index 771b282..f8eeaf2 100644
--- src/libsync/propagatorjobs.cpp
+++ src/libsync/propagatorjobs.cpp
@@ -13,6 +13,7 @@
* for more details.
*/
+#include "configfile.h"
#include "propagatorjobs.h"
#include "owncloudpropagator_p.h"
#include "propagateremotemove.h"
@@ -50,6 +51,13 @@ namespace OCC {
*/
bool PropagateLocalRemove::removeRecursively(const QString& path)
{
+#ifdef Q_OS_UNIX
+ if (_moveToTrash == -1){
+ ConfigFile cfgFile;
+ _moveToTrash = cfgFile.moveToTrash() ? 1 : 0;
+ }
+#endif
+
bool success = true;
QString absolute = propagator()->_localDir + _item->_file + path;
QDirIterator di(absolute, QDir::AllEntries | QDir::Hidden | QDir::System | QDir::NoDotAndDotDot);
@@ -59,21 +67,27 @@ bool PropagateLocalRemove::removeRecursively(const QString& path)
while (di.hasNext()) {
di.next();
const QFileInfo& fi = di.fileInfo();
- bool ok;
+ bool ok = true;
// The use of isSymLink here is okay:
// we never want to go into this branch for .lnk files
bool isDir = fi.isDir() && !fi.isSymLink();
- if (isDir) {
- ok = removeRecursively(path + QLatin1Char('/') + di.fileName()); // recursive
- } else {
- QString removeError;
- ok = FileSystem::remove(di.filePath(), &removeError);
- if (!ok) {
- _error += PropagateLocalRemove::tr("Error removing '%1': %2;").
- arg(QDir::toNativeSeparators(di.filePath()), removeError) + " ";
- qDebug() << "Error removing " << di.filePath() << ':' << removeError;
+#ifdef Q_OS_UNIX
+ if (_moveToTrash == 0) {
+#endif
+ if (isDir) {
+ ok = removeRecursively(path + QLatin1Char('/') + di.fileName()); // recursive
+ } else {
+ QString removeError;
+ ok = FileSystem::remove(di.filePath(), &removeError);
+ if (!ok) {
+ _error += PropagateLocalRemove::tr("Error removing '%1': %2;").
+ arg(QDir::toNativeSeparators(di.filePath()), removeError) + " ";
+ qDebug() << "Error removing " << di.filePath() << ':' << removeError;
+ }
}
+#ifdef Q_OS_UNIX
}
+#endif
if (success && !ok) {
// We need to delete the entries from the database now from the deleted vector
foreach(const auto &it, deleted) {
@@ -93,7 +107,16 @@ bool PropagateLocalRemove::removeRecursively(const QString& path)
}
}
if (success) {
- success = QDir().rmdir(absolute);
+#ifdef Q_OS_UNIX
+ if (_moveToTrash == 0) {
+#endif
+ success = QDir().rmdir(absolute);
+#ifdef Q_OS_UNIX
+ }
+ if (_moveToTrash == 1) {
+ success = FileSystem::remove(absolute);
+ }
+#endif
if (!success) {
_error += PropagateLocalRemove::tr("Could not remove folder '%1'")
.arg(QDir::toNativeSeparators(absolute)) + " ";
diff --git src/libsync/propagatorjobs.h src/libsync/propagatorjobs.h
index c3898db..8df73f6 100644
--- src/libsync/propagatorjobs.h
+++ src/libsync/propagatorjobs.h
@@ -40,11 +40,12 @@ static const char checkSumAdlerC[] = "Adler32";
class PropagateLocalRemove : public PropagateItemJob {
Q_OBJECT
public:
- PropagateLocalRemove (OwncloudPropagator* propagator,const SyncFileItemPtr& item) : PropagateItemJob(propagator, item) {}
+ PropagateLocalRemove (OwncloudPropagator* propagator,const SyncFileItemPtr& item) : PropagateItemJob(propagator, item), _moveToTrash(-1) {}
void start() Q_DECL_OVERRIDE;
private:
bool removeRecursively(const QString &path);
QString _error;
+ int _moveToTrash;
};
/**