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

133 lines
4.5 KiB

#include "untrashjob.h"
namespace Fm {
UntrashJob::UntrashJob() {
}
static const char trash_query[] =
G_FILE_ATTRIBUTE_STANDARD_TYPE","
G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME","
G_FILE_ATTRIBUTE_STANDARD_NAME","
G_FILE_ATTRIBUTE_STANDARD_IS_VIRTUAL","
G_FILE_ATTRIBUTE_STANDARD_SIZE","
G_FILE_ATTRIBUTE_UNIX_BLOCKS","
G_FILE_ATTRIBUTE_UNIX_BLOCK_SIZE","
G_FILE_ATTRIBUTE_ID_FILESYSTEM","
"trash::orig-path";
bool UntrashJob::ensure_parent_dir(GFile* orig_path) {
GFile* parent = g_file_get_parent(orig_path);
gboolean ret = g_file_query_exists(parent, cancellable().get());
if(!ret) {
GErrorPtr err;
_retry_mkdir:
if(!g_file_make_directory_with_parents(parent, cancellable().get(), &err)) {
if(!isCancelled()) {
ErrorAction act = emitError(err, ErrorSeverity::MODERATE);
err = nullptr;
if(act == ErrorAction::RETRY) {
goto _retry_mkdir;
}
}
}
else {
ret = TRUE;
}
}
g_object_unref(parent);
return ret;
}
void UntrashJob::exec() {
#if 0
gboolean ret = TRUE;
GList* l;
GError* err = nullptr;
FmJob* fmjob = FM_JOB(job);
job->total = fm_path_list_get_length(job->srcs);
fm_file_ops_job_emit_prepared(job);
l = fm_path_list_peek_head_link(job->srcs);
for(; !fm_job_is_cancelled(fmjob) && l; l = l->next) {
GFile* gf;
GFileInfo* inf;
FmPath* path = FM_PATH(l->data);
if(!fm_path_is_trash(path)) {
continue;
}
gf = fm_path_to_gfile(path);
_retry_get_orig_path:
inf = g_file_query_info(gf, trash_query, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, fm_job_get_cancellable(fmjob), &err);
if(inf) {
const char* orig_path_str = g_file_info_get_attribute_byte_string(inf, "trash::orig-path");
fm_file_ops_job_emit_cur_file(job, g_file_info_get_display_name(inf));
if(orig_path_str) {
/* FIXME: what if orig_path_str is a relative path?
* This is actually allowed by the horrible trash spec. */
GFile* orig_path = fm_file_new_for_commandline_arg(orig_path_str);
FmFolder* src_folder = fm_folder_find_by_path(fm_path_get_parent(path));
FmPath* orig_fm_path = fm_path_new_for_gfile(orig_path);
FmFolder* dst_folder = fm_folder_find_by_path(fm_path_get_parent(orig_fm_path));
fm_path_unref(orig_fm_path);
/* ensure the existence of parent folder. */
if(ensure_parent_dir(fmjob, orig_path)) {
ret = _fm_file_ops_job_move_file(job, gf, inf, orig_path, path, src_folder, dst_folder);
}
if(src_folder) {
g_object_unref(src_folder);
}
if(dst_folder) {
g_object_unref(dst_folder);
}
g_object_unref(orig_path);
}
else {
ErrorAction act;
g_set_error(&err, G_IO_ERROR, G_IO_ERROR_FAILED,
_("Cannot untrash file '%s': original path not known"),
g_file_info_get_display_name(inf));
act = emitError( err, ErrorSeverity::MODERATE);
g_clear_error(&err);
if(act == ErrorAction::ABORT) {
g_object_unref(inf);
g_object_unref(gf);
return FALSE;
}
}
g_object_unref(inf);
}
else {
char* basename = g_file_get_basename(gf);
char* disp = basename ? g_filename_display_name(basename) : nullptr;
g_free(basename);
/* FIXME: translate it */
fm_file_ops_job_emit_cur_file(job, disp ? disp : "(invalid file)");
g_free(disp);
if(err) {
ErrorAction act = emitError( err, ErrorSeverity::MODERATE);
g_error_free(err);
err = nullptr;
if(act == ErrorAction::RETRY) {
goto _retry_get_orig_path;
}
else if(act == ErrorAction::ABORT) {
g_object_unref(gf);
return FALSE;
}
}
}
g_object_unref(gf);
++job->finished;
fm_file_ops_job_emit_percent(job);
}
#endif
}
} // namespace Fm