Enhancement: Fixes #414, shell - delete file support

This commit is contained in:
Rory Fewell
2025-12-16 20:26:47 +00:00
parent 410fd88339
commit 7df520ee0d
4 changed files with 157 additions and 20 deletions

View File

@@ -205,9 +205,22 @@ static void wintc_sh_fs_operation_constructed(
{
WinTCShFSOperation* fs_operation = WINTC_SH_FS_OPERATION(object);
// Check things are set
// There must always be files to work on
//
if (!(fs_operation->list_files) || !(fs_operation->dest))
if (!(fs_operation->list_files))
{
fs_operation->operation_kind = WINTC_SH_FS_OPERATION_INVALID;
}
// Copying/moving requires a destination
//
if (
!(fs_operation->dest) &&
(
fs_operation->operation_kind == WINTC_SH_FS_OPERATION_COPY ||
fs_operation->operation_kind == WINTC_SH_FS_OPERATION_MOVE
)
)
{
fs_operation->operation_kind = WINTC_SH_FS_OPERATION_INVALID;
}
@@ -234,7 +247,15 @@ static void wintc_sh_fs_operation_constructed(
)
{
fs_operation->operation_kind = WINTC_SH_FS_OPERATION_TRASH;
g_clear_pointer(
&(fs_operation->dest),
(GDestroyNotify) g_free
);
}
(G_OBJECT_CLASS(wintc_sh_fs_operation_parent_class))
->constructed(object);
}
static void wintc_sh_fs_operation_dispose(
@@ -319,9 +340,15 @@ static void wintc_sh_fs_operation_set_property(
case PROP_DESTINATION:
fs_operation->dest = g_value_dup_string(value);
fs_operation->dest_file = get_g_file_for_target(
fs_operation->dest
);
if (fs_operation->dest)
{
fs_operation->dest_file =
get_g_file_for_target(
fs_operation->dest
);
}
break;
case PROP_OPERATION:
@@ -418,8 +445,12 @@ static void wintc_sh_fs_operation_step(
const gchar* src_path = (gchar*) fs_operation->iter_op->data;
GFile* src_file = get_g_file_for_target(src_path);
g_object_ref(dest_file);
gboolean dest_file_is_temp = FALSE;
// If the target of a copy or move is a directory, then we must create a
// temporary GFile object to hold the destination file path within that
// directory
//
if (
(
fs_operation->operation_kind == WINTC_SH_FS_OPERATION_COPY ||
@@ -431,7 +462,7 @@ static void wintc_sh_fs_operation_step(
)
)
{
g_object_unref(dest_file);
dest_file_is_temp = TRUE;
dest_file =
get_g_file_for_copymove(
@@ -493,7 +524,7 @@ static void wintc_sh_fs_operation_step(
g_file_trash_async(
src_file,
G_PRIORITY_DEFAULT,
NULL, // FIXME: Cancellable, should use this!
fs_operation->cancellable,
(GAsyncReadyCallback) cb_async_file_op,
fs_operation
);
@@ -505,7 +536,10 @@ static void wintc_sh_fs_operation_step(
break;
}
g_object_unref(dest_file);
if (dest_file_is_temp)
{
g_object_unref(dest_file);
}
}
static void wintc_sh_fs_operation_update_progress_text(

View File

@@ -34,8 +34,9 @@
<attribute name="label">Create Shortcut</attribute>
</item>
<item>
<attribute name="action">control.no-op</attribute>
<attribute name="action">control.view-op</attribute>
<attribute name="label">Delete</attribute>
<attribute name="target" type="i">9</attribute>
</item>
<item>
<attribute name="action">control.no-op</attribute>

View File

@@ -44,8 +44,9 @@
<attribute name="label">Create Shortcut</attribute>
</item>
<item>
<attribute name="action">control.no-op</attribute>
<attribute name="action">control.view-op</attribute>
<attribute name="label">Delete</attribute>
<attribute name="target" type="i">9</attribute>
</item>
<item>
<attribute name="action">control.no-op</attribute>

View File

@@ -9,6 +9,7 @@
#include <wintc/shlang.h>
#include "../public/fsclipbd.h"
#include "../public/fsop.h"
#include "../public/vwfs.h"
//
@@ -127,6 +128,14 @@ static gboolean real_activate_item(
GError** error
);
static gchar* wintc_sh_view_fs_build_path_for_view_item(
WinTCShViewFS* view_fs,
WinTCShextViewItem* item
);
static GList* wintc_sh_view_fs_convert_list_hashes(
WinTCShViewFS* view_fs,
GList* list_items
);
static WinTCShextViewItem* wintc_sh_view_fs_get_view_item(
WinTCShViewFS* view_fs,
guint item_hash
@@ -135,6 +144,12 @@ static void wintc_sh_view_fs_update_new_templates(
WinTCShViewFS* view_fs
);
static gboolean shopr_delete(
WinTCIShextView* view,
WinTCShextOperation* operation,
GtkWindow* wnd,
GError** error
);
static gboolean shopr_new(
WinTCIShextView* view,
WinTCShextOperation* operation,
@@ -161,6 +176,10 @@ static void on_file_monitor_changed(
GFileMonitorEvent event_type,
gpointer user_data
);
static void on_fs_operation_done(
WinTCShFSOperation* self,
WINTC_UNUSED(gpointer user_data)
);
//
// GLIB OOP/CLASS INSTANCE DEFINITIONS
@@ -756,12 +775,14 @@ static void wintc_sh_view_fs_refresh_items(
}
static WinTCShextOperation* wintc_sh_view_fs_spawn_operation(
WINTC_UNUSED(WinTCIShextView* view),
gint operation_id,
GList* targets,
WinTCIShextView* view,
gint operation_id,
GList* targets,
WINTC_UNUSED(GError** error)
)
{
WinTCShViewFS* view_fs = WINTC_SH_VIEW_FS(view);
// Spawn op
//
WinTCShextOperation* ret = g_new(WinTCShextOperation, 1);
@@ -777,6 +798,14 @@ static WinTCShextOperation* wintc_sh_view_fs_spawn_operation(
ret->func = shopr_paste;
break;
case WINTC_SHEXT_KNOWN_OP_DELETE:
ret->func = shopr_delete;
ret->priv = wintc_sh_view_fs_convert_list_hashes(
view_fs,
g_steal_pointer(&targets)
);
break;
default:
// Could be a NEW operation...
//
@@ -911,14 +940,15 @@ static gboolean real_activate_item(
// If the target is a dir or has a shell extension then set that as
// the target path
//
gchar* next_path = g_build_path(
G_DIR_SEPARATOR_S,
view_fs->path,
item->display_name,
NULL
);
gchar* next_path;
gchar* target_path = NULL;
next_path =
wintc_sh_view_fs_build_path_for_view_item(
view_fs,
item
);
if (!(item->is_leaf))
{
target_path = g_strdup_printf("file://%s", next_path);
@@ -969,6 +999,42 @@ static gboolean real_activate_item(
return success;
}
static gchar* wintc_sh_view_fs_build_path_for_view_item(
WinTCShViewFS* view_fs,
WinTCShextViewItem* item
)
{
return g_build_path(
G_DIR_SEPARATOR_S,
view_fs->path,
item->display_name,
NULL
);
}
static GList* wintc_sh_view_fs_convert_list_hashes(
WinTCShViewFS* view_fs,
GList* list_items
)
{
for (GList* iter = list_items; iter; iter = iter->next)
{
WinTCShextViewItem* item =
wintc_sh_view_fs_get_view_item(
view_fs,
GPOINTER_TO_UINT(iter->data)
);
iter->data =
wintc_sh_view_fs_build_path_for_view_item(
view_fs,
item
);
}
return list_items;
}
static WinTCShextViewItem* wintc_sh_view_fs_get_view_item(
WinTCShViewFS* view_fs,
guint item_hash
@@ -1123,6 +1189,32 @@ static void wintc_sh_view_fs_update_new_templates(
//
// CALLBACKS
//
static gboolean shopr_delete(
WINTC_UNUSED(WinTCIShextView* view),
WinTCShextOperation* operation,
GtkWindow* wnd,
WINTC_UNUSED(GError** error)
)
{
WinTCShFSOperation* op =
wintc_sh_fs_operation_new(
(GList*) operation->priv,
NULL,
WINTC_SH_FS_OPERATION_TRASH
);
g_signal_connect(
op,
"done",
G_CALLBACK(on_fs_operation_done),
operation->priv
);
wintc_sh_fs_operation_do(op, wnd);
return TRUE;
}
static gboolean shopr_new(
WinTCIShextView* view,
WinTCShextOperation* operation,
@@ -1423,3 +1515,12 @@ static void on_file_monitor_changed(
g_list_free(data);
g_free(file_path);
}
static void on_fs_operation_done(
WinTCShFSOperation* self,
gpointer user_data
)
{
g_list_free_full((GList*) user_data, g_free);
g_object_unref(self);
}