diff --git a/shared/shell/src/fsop.c b/shared/shell/src/fsop.c
index 0b62483..8a1437c 100644
--- a/shared/shell/src/fsop.c
+++ b/shared/shell/src/fsop.c
@@ -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(
diff --git a/shared/shell/src/res/menufslf.ui b/shared/shell/src/res/menufslf.ui
index 4ca4546..9f4fdf0 100644
--- a/shared/shell/src/res/menufslf.ui
+++ b/shared/shell/src/res/menufslf.ui
@@ -34,8 +34,9 @@
Create Shortcut
-
- control.no-op
+ control.view-op
Delete
+ 9
-
control.no-op
diff --git a/shared/shell/src/res/menufsvw.ui b/shared/shell/src/res/menufsvw.ui
index b85fbbc..b99ba21 100644
--- a/shared/shell/src/res/menufsvw.ui
+++ b/shared/shell/src/res/menufsvw.ui
@@ -44,8 +44,9 @@
Create Shortcut
-
- control.no-op
+ control.view-op
Delete
+ 9
-
control.no-op
diff --git a/shared/shell/src/vwfs.c b/shared/shell/src/vwfs.c
index 45c62c7..49df9d4 100644
--- a/shared/shell/src/vwfs.c
+++ b/shared/shell/src/vwfs.c
@@ -9,6 +9,7 @@
#include
#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);
+}