diff options
Diffstat (limited to 'fiv-context-menu.c')
-rw-r--r-- | fiv-context-menu.c | 57 |
1 files changed, 53 insertions, 4 deletions
diff --git a/fiv-context-menu.c b/fiv-context-menu.c index b5dafc4..16460b6 100644 --- a/fiv-context-menu.c +++ b/fiv-context-menu.c @@ -1,7 +1,7 @@ // // fiv-context-menu.c: popup menu // -// Copyright (c) 2021 - 2022, Přemysl Eric Janouch <p@janouch.name> +// Copyright (c) 2021 - 2024, Přemysl Eric Janouch <p@janouch.name> // // Permission to use, copy, modify, and/or distribute this software for any // purpose with or without fee is hereby granted. @@ -328,6 +328,17 @@ open_context_unref(gpointer data, G_GNUC_UNUSED GClosure *closure) } static void +show_error_dialog(GtkWindow *parent, GError *error) +{ + GtkWidget *dialog = + gtk_message_dialog_new(GTK_WINDOW(parent), GTK_DIALOG_MODAL, + GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, "%s", error->message); + gtk_dialog_run(GTK_DIALOG(dialog)); + gtk_widget_destroy(dialog); + g_error_free(error); +} + +static void open_context_launch(GtkWidget *widget, OpenContext *self) { GdkAppLaunchContext *context = @@ -342,8 +353,9 @@ open_context_launch(GtkWidget *widget, OpenContext *self) (void) g_app_info_set_as_last_used_for_type( self->app_info, self->content_type, NULL); } else { - g_warning("%s", error->message); - g_error_free(error); + GtkWindow *window = g_weak_ref_get(&self->window); + show_error_dialog(window, error); + g_clear_object(&window); } g_list_free(files); g_object_unref(context); @@ -396,6 +408,15 @@ on_chooser_activate(GtkMenuItem *item, gpointer user_data) GtkWidget *dialog = gtk_app_chooser_dialog_new_for_content_type(window, GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL, ctx->content_type); g_clear_object(&window); + +#if 0 + // This exists as a concept in mimeapps.list, but GNOME infuriatingly + // infers it from the last used application if missing. + gtk_app_chooser_widget_set_show_default( + GTK_APP_CHOOSER_WIDGET(gtk_app_chooser_dialog_get_widget( + GTK_APP_CHOOSER_DIALOG(dialog))), TRUE); +#endif + if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) { ctx->app_info = gtk_app_chooser_get_app_info(GTK_APP_CHOOSER(dialog)); open_context_launch(GTK_WIDGET(item), ctx); @@ -414,6 +435,24 @@ on_info_activate(G_GNUC_UNUSED GtkMenuItem *item, gpointer user_data) g_free(uri); } +void +fiv_context_menu_remove(GtkWindow *parent, GFile *file) +{ + // TODO(p): Use g_file_trash_async(), for which we need a task manager. + GError *error = NULL; + if (!g_file_trash(file, NULL, &error)) + show_error_dialog(parent, error); +} + +static void +on_trash_activate(G_GNUC_UNUSED GtkMenuItem *item, gpointer user_data) +{ + OpenContext *ctx = user_data; + GtkWindow *window = g_weak_ref_get(&ctx->window); + fiv_context_menu_remove(window, ctx->file); + g_clear_object(&window); +} + static gboolean destroy_widget_idle_source_func(GtkWidget *widget) { @@ -494,11 +533,21 @@ fiv_context_menu_new(GtkWidget *widget, GFile *file) ctx, open_context_unref, 0); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); + // TODO(p): Can we avoid using the "trash" string constant for this check? + if (!g_file_has_uri_scheme(file, "trash")) { + gtk_menu_shell_append( + GTK_MENU_SHELL(menu), gtk_separator_menu_item_new()); + + item = gtk_menu_item_new_with_mnemonic("Move to _Trash"); + g_signal_connect_data(item, "activate", G_CALLBACK(on_trash_activate), + g_rc_box_acquire(ctx), open_context_unref, 0); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); + } if (type == G_FILE_TYPE_REGULAR) { gtk_menu_shell_append( GTK_MENU_SHELL(menu), gtk_separator_menu_item_new()); - item = gtk_menu_item_new_with_mnemonic("_Information..."); + item = gtk_menu_item_new_with_mnemonic("_Information"); g_signal_connect_data(item, "activate", G_CALLBACK(on_info_activate), g_rc_box_acquire(ctx), open_context_unref, 0); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); |