Skip to content
This repository has been archived by the owner on Oct 4, 2023. It is now read-only.

Commit

Permalink
Better compliance to freedesktop spec (url escaping, relative paths i…
Browse files Browse the repository at this point in the history
…n non-home partitions). License headers in new files
  • Loading branch information
FreeSlave committed Feb 12, 2018
1 parent a8d21ea commit 97a4b40
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 6 deletions.
33 changes: 27 additions & 6 deletions Trashcan.cpp
@@ -1,23 +1,44 @@
/*
* Copyright (C) 2018 Roman Chistokhodov <freeslave93@gmail.com>
* This file is part of Phototonic Image Viewer.
*
* Phototonic is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Phototonic is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Phototonic. If not, see <http://www.gnu.org/licenses/>.
*/

#include <QtGlobal>
#include "Trashcan.h"

#if defined(Q_OS_UNIX) && !defined(Q_OS_ANDROID) && !defined(Q_OS_DARWIN)

// Implementation for freedesktop systems adheres to https://specifications.freedesktop.org/trash-spec/trashspec-latest.html

#include <QDateTime>
#include <QDir>
#include <QFileInfo>
#include <QFile>
#include <QStandardPaths>
#include <QStorageInfo>
#include <QTextStream>
#include <QUrl>

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <cerrno>

static Trash::Result moveToTrashDir(const QString& filePath, const QDir& trashDir, QString& error)
static Trash::Result moveToTrashDir(const QString& filePath, const QDir& trashDir, QString& error, const QStorageInfo& nonHomeStorage)
{
const QDir trashInfoDir = QDir(trashDir.filePath("info"));
const QDir trashFilesDir = QDir(trashDir.filePath("files"));
Expand All @@ -39,8 +60,8 @@ static Trash::Result moveToTrashDir(const QString& filePath, const QDir& trashDi
}
const QString moveHere = trashFilesDir.filePath(fileName);
const QString deletionDate = QDateTime::currentDateTime().toString(Qt::ISODate);
QString escapedPath = filePath;
escapedPath.replace('\\', "\\").replace('\n', "\\n").replace('\r', "\\r").replace('\t', "\\t");
const QString path = nonHomeStorage.isValid() ? QDir(nonHomeStorage.rootPath()).relativeFilePath(filePath) : filePath;
const QString escapedPath = QString::fromUtf8(QUrl::toPercentEncoding(path, "/"));
QFile infoFile;
if (infoFile.open(fd, QIODevice::WriteOnly, QFileDevice::AutoCloseHandle)) {
QTextStream out(&infoFile);
Expand Down Expand Up @@ -85,7 +106,7 @@ Trash::Result Trash::moveToTrash(const QString &path, QString &error, Trash::Opt
if (QStorageInfo(homeDataLocation) == filePathStorage || trashOptions == Trash::ForceDeletionToHomeTrash) {
const QDir homeTrashDirectory = QDir(homeDataDirectory.filePath("Trash"));
if (homeTrashDirectory.mkpath(".")) {
return moveToTrashDir(filePath, homeTrashDirectory, error);
return moveToTrashDir(filePath, homeTrashDirectory, error, QStorageInfo());
} else {
error = "Could not ensure that home trash directory exists";
return Trash::Error;
Expand All @@ -99,14 +120,14 @@ Trash::Result Trash::moveToTrash(const QString &path, QString &error, Trash::Opt
if (S_ISDIR(trashStat.st_mode) && !S_ISLNK(trashStat.st_mode) && (trashStat.st_mode & S_ISVTX)) {
const QString subdir = QString::number(getuid());
if (topdirTrash.mkpath(subdir)) {
return moveToTrashDir(filePath, QDir(topdirTrash.filePath(subdir)), error);
return moveToTrashDir(filePath, QDir(topdirTrash.filePath(subdir)), error, filePathStorage);
}
}
}
// if we're still here, $topdir/.Trash does not exist or failed some check
QDir topdirUserTrash = QDir(topdir.filePath(QString(".Trash-%1").arg(getuid())));
if (topdirUserTrash.mkpath(".")) {
return moveToTrashDir(filePath, topdirUserTrash, error);
return moveToTrashDir(filePath, topdirUserTrash, error, filePathStorage);
}
error = "Could not find trash directory for the disk where the file resides";
return Trash::NeedsUserInput;
Expand Down
18 changes: 18 additions & 0 deletions Trashcan.h
@@ -1,3 +1,21 @@
/*
* Copyright (C) 2018 Roman Chistokhodov <freeslave93@gmail.com>
* This file is part of Phototonic Image Viewer.
*
* Phototonic is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Phototonic is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Phototonic. If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef TRASHCAN_H
#define TRASHCAN_H

Expand Down

0 comments on commit 97a4b40

Please sign in to comment.