You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
libfm-qt-packaging/src/core/untrashjob.cpp

77 lines
2.9 KiB

#include "untrashjob.h"
#include "filetransferjob.h"
namespace Fm {
UntrashJob::UntrashJob(FilePathList srcPaths):
srcPaths_{std::move(srcPaths)} {
}
void UntrashJob::exec() {
// preparing for the job
FilePathList validSrcPaths;
FilePathList origPaths;
for(auto& srcPath: srcPaths_) {
if(isCancelled()) {
break;
}
GErrorPtr err;
GFileInfoPtr srcInfo{
g_file_query_info(srcPath.gfile().get(),
"trash::orig-path",
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
cancellable().get(),
&err),
false
};
if(srcInfo) {
const char* orig_path_str = g_file_info_get_attribute_byte_string(srcInfo.get(), "trash::orig-path");
if(orig_path_str) {
validSrcPaths.emplace_back(srcPath);
origPaths.emplace_back(FilePath::fromPathStr(orig_path_str));
}
else {
ErrorAction act;
g_set_error(&err, G_IO_ERROR, G_IO_ERROR_FAILED,
tr("Cannot untrash file '%s': original path not known").toUtf8().constData(),
g_file_info_get_display_name(srcInfo.get()));
// FIXME: do we need to retry here?
emitError(err, ErrorSeverity::MODERATE);
}
}
else {
// FIXME: do we need to retry here?
emitError(err);
}
}
// collected original paths of the trashed files
// use the file transfer job to handle the actual file move
FileTransferJob fileTransferJob{std::move(validSrcPaths), std::move(origPaths), FileTransferJob::Mode::MOVE};
// FIXME:
// I'm not sure why specifying Qt::DirectConnection is needed here since the caller & receiver are in the same thread. :-(
// However without this, the signals/slots here will cause deadlocks.
connect(&fileTransferJob, &FileTransferJob::preparedToRun, this, &UntrashJob::preparedToRun, Qt::DirectConnection);
connect(&fileTransferJob, &FileTransferJob::error, this, &UntrashJob::error, Qt::DirectConnection);
connect(&fileTransferJob, &FileTransferJob::fileExists, this, &UntrashJob::fileExists, Qt::DirectConnection);
// cancel the file transfer subjob if the parent job is cancelled
connect(this, &UntrashJob::cancelled, &fileTransferJob,
[&fileTransferJob]() {
if(!fileTransferJob.isCancelled()) {
fileTransferJob.cancel();
}
}, Qt::DirectConnection);
// cancel the parent job if the file transfer subjob is cancelled
connect(&fileTransferJob, &FileTransferJob::cancelled, this,
[this]() {
if(!isCancelled()) {
cancel();
}
}, Qt::DirectConnection);
fileTransferJob.run();
}
} // namespace Fm