From b7a34ebb5ed235575b3dcc9635d9c98d74aa0fd5 Mon Sep 17 00:00:00 2001 From: Colin Clark Date: Sat, 21 Mar 2020 15:09:54 +0000 Subject: [PATCH] Fix #737: Don't create new folder without confirmation https://github.com/BestImageViewer/geeqie/issues/737 --- src/ui_pathsel.c | 39 ++++++-------- src/utilops.c | 133 +++++++++++++++++++++++++++++++++++++++++++++-- src/utilops.h | 1 + src/view_dir.c | 39 +++++++++++++- 4 files changed, 181 insertions(+), 31 deletions(-) diff --git a/src/ui_pathsel.c b/src/ui_pathsel.c index 22144c48..a7e255fb 100644 --- a/src/ui_pathsel.c +++ b/src/ui_pathsel.c @@ -49,6 +49,7 @@ #include "ui_tabcomp.h" #include "ui_tree_edit.h" #include "uri_utils.h" +#include "utilops.h" #define DEST_WIDTH 250 @@ -734,24 +735,20 @@ static void dest_new_dir_cb(GtkWidget *widget, gpointer data) { Dest_Data *dd = data; gchar *path; - gchar *buf; - const gchar *tmp; - gboolean from_text = FALSE; + GtkWidget *dialog_window; - tmp = gtk_entry_get_text(GTK_ENTRY(dd->entry)); - if (!isname(tmp)) - { - buf = remove_trailing_slash(tmp); - path = g_strdup(buf); - g_free(buf); - buf = remove_level_from_path(path); - from_text = TRUE; - } - else +/* FIXME: on exit from the "new folder" modal dialog, focus returns to the main Geeqie + * window rather than the file dialog window. gtk_window_present() does not seem to + * function unless the window was previously minimized. + */ + dialog_window = gtk_widget_get_toplevel(widget); + gtk_window_iconify(GTK_WINDOW(dialog_window)); + path = new_folder(GTK_WINDOW(dialog_window), dd->path); + gtk_window_present(GTK_WINDOW(dialog_window)); + + if (path == NULL) { - buf = g_build_filename(dd->path, _("New folder"), NULL); - path = unique_filename(buf, NULL, " ", FALSE); - g_free(buf); + return; } if (!mkdir_utf8(path, 0755)) @@ -769,12 +766,6 @@ static void dest_new_dir_cb(GtkWidget *widget, gpointer data) GtkListStore *store; const gchar *text; - if (from_text) - { - dest_populate(dd, buf); - g_free(buf); - } - store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(dd->d_view))); text = filename_from_path(path); @@ -785,11 +776,11 @@ static void dest_new_dir_cb(GtkWidget *widget, gpointer data) if (dd->right_click_path) gtk_tree_path_free(dd->right_click_path); dd->right_click_path = gtk_tree_model_get_path(GTK_TREE_MODEL(store), &iter); - tree_edit_by_path(GTK_TREE_VIEW(dd->d_view), dd->right_click_path, 0, text, - dest_view_rename_cb, dd); gtk_entry_set_text(GTK_ENTRY(dd->entry), path); } + gtk_widget_grab_focus(GTK_WIDGET(dd->entry)); + g_free(path); } diff --git a/src/utilops.c b/src/utilops.c index 4f9d7126..e28acb02 100644 --- a/src/utilops.c +++ b/src/utilops.c @@ -2883,17 +2883,24 @@ static void file_util_create_dir_full(FileData *fd, const gchar *dest_path, GtkW if (dest_path) { + g_assert_not_reached(); // not used in current design ud->dest_path = g_strdup(dest_path); } else { - gchar *buf = g_build_filename(fd->path, _("New folder"), NULL); - ud->dest_path = unique_filename(buf, NULL, " ", FALSE); - g_free(buf); + gchar *buf = new_folder(GTK_WINDOW(parent), fd->path); + if (!buf) + { + ud->phase = UTILITY_PHASE_CANCEL; + ud->dir_fd = NULL; + } + else + { + ud->dest_path = buf; + ud->dir_fd = file_data_new_dir(ud->dest_path); + } } - ud->dir_fd = file_data_new_dir(ud->dest_path); - ud->done_func = done_func; ud->done_data = done_data; @@ -3137,4 +3144,120 @@ void file_util_copy_path_list_to_clipboard(GList *list, gboolean quoted) g_string_free(new, TRUE); filelist_free(list); } + +static gboolean new_folder_entry_activate_cb(GtkWidget *widget, gpointer data) +{ + GtkDialog *dialog = data; + + gtk_dialog_response(dialog, GTK_RESPONSE_ACCEPT); +} + +gchar *new_folder(GtkWindow *window , gchar *path) +{ + GtkWidget *hbox; + GtkWidget *vbox; + GtkWidget *label; + gchar *buf; + gchar *folder_name; + gchar *folder_path; + GtkWidget *image; + GtkWidget *folder_name_entry; + GtkWidget *dialog; + GtkWidget *dialog_warning; + GtkWidget *content_area; + gboolean ok_or_cancel = FALSE; + gint result; + gchar *new_folder_name; + gchar *new_folder_path_full = NULL; + gchar *window_title; + PangoLayout *layout; + gint width, height; + + buf = g_build_filename(path, _("New folder"), NULL); + folder_path = unique_filename(buf, NULL, " ", FALSE); + folder_name = g_path_get_basename(folder_path); + window_title = g_strconcat(_("Create Folder - "), GQ_APPNAME, NULL); + + dialog = gtk_dialog_new_with_buttons(window_title, + GTK_WINDOW(window), + GTK_DIALOG_MODAL, + GTK_STOCK_CANCEL, + GTK_RESPONSE_REJECT, + GTK_STOCK_OK, + GTK_RESPONSE_ACCEPT, + NULL); + + layout = gtk_widget_create_pango_layout(GTK_WIDGET(dialog), window_title); + pango_layout_get_pixel_size(layout, &width, &height); + gtk_window_set_default_size(GTK_WINDOW(dialog), width * 2, -1); + + content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); + vbox = gtk_vbox_new(FALSE, PREF_PAD_GAP); + gtk_box_pack_start(GTK_BOX(content_area), vbox, FALSE, FALSE, 0); + + hbox = gtk_hbox_new(FALSE, PREF_PAD_GAP); + gtk_container_set_border_width(GTK_CONTAINER(hbox), PREF_PAD_GAP); + gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); + image = gtk_image_new_from_icon_name("dialog-question", GTK_ICON_SIZE_DIALOG); + gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 0); + label = gtk_label_new(_("Create new folder")); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); + + folder_name_entry = gtk_entry_new(); + gtk_entry_set_text(GTK_ENTRY(folder_name_entry), folder_name); + gtk_box_pack_start(GTK_BOX(vbox), folder_name_entry, FALSE, FALSE, PREF_PAD_SPACE); + g_signal_connect(G_OBJECT(folder_name_entry), "activate", G_CALLBACK(new_folder_entry_activate_cb), dialog); + + gtk_widget_show_all(dialog); + + while (ok_or_cancel == FALSE) + { + result = gtk_dialog_run(GTK_DIALOG(dialog)); + + switch (result) + { + case GTK_RESPONSE_ACCEPT: + new_folder_name = g_strdup(gtk_entry_get_text(GTK_ENTRY(folder_name_entry))); + new_folder_path_full = g_build_filename(path, new_folder_name, NULL); + if (isname(new_folder_path_full)) + { + dialog_warning = gtk_message_dialog_new(GTK_WINDOW(window), + GTK_DIALOG_MODAL, + GTK_MESSAGE_WARNING, + GTK_BUTTONS_OK, + _("Cannot create folder:")); + gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog_warning), "%s", new_folder_name); + gtk_window_set_title(GTK_WINDOW(dialog_warning), GQ_APPNAME); + + gtk_dialog_run(GTK_DIALOG(dialog_warning)); + + gtk_widget_destroy(dialog_warning); + g_free(new_folder_path_full); + new_folder_path_full = NULL; + g_free(new_folder_name); + ok_or_cancel = FALSE; + } + else + { + ok_or_cancel = TRUE; + } + break; + case GTK_RESPONSE_REJECT: + ok_or_cancel = TRUE; + break; + default: + ok_or_cancel = TRUE; + break; + } + } + + g_free(buf); + g_free(folder_path); + g_free(folder_name); + g_object_unref(layout); + g_free(window_title); + gtk_widget_destroy(dialog); + + return new_folder_path_full; +} /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */ diff --git a/src/utilops.h b/src/utilops.h index d9c6a1b7..43a6b2a6 100644 --- a/src/utilops.h +++ b/src/utilops.h @@ -71,5 +71,6 @@ void file_util_delete_dir(FileData *source_fd, GtkWidget *parent); void file_util_copy_path_to_clipboard(FileData *fd, gboolean quoted); void file_util_copy_path_list_to_clipboard(GList *list, gboolean quoted); +gchar *new_folder(GtkWindow *window, gchar *path); #endif /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */ diff --git a/src/view_dir.c b/src/view_dir.c index d7ac1207..c5fc5e5a 100644 --- a/src/view_dir.c +++ b/src/view_dir.c @@ -594,6 +594,41 @@ static void vd_pop_menu_new_rename_cb(gboolean success, const gchar *new_path, g vd_rename_by_data(vd, fd); } +static void vd_pop_menu_new_folder_cb(gboolean success, const gchar *new_path, gpointer data) +{ + ViewDir *vd = data; + FileData *fd = NULL; + GtkTreeIter iter; + GtkTreePath *tpath; + GtkTreeModel *store; + + if (!success) return; + + switch (vd->type) + { + case DIRVIEW_LIST: + { + vd_refresh(vd); + fd = vdlist_row_by_path(vd, new_path, NULL); + }; + break; + case DIRVIEW_TREE: + { + FileData *new_fd = file_data_new_dir(new_path); + fd = vdtree_populate_path(vd, new_fd, TRUE, TRUE); + file_data_unref(new_fd); + } + break; + } + + if (!fd || !vd_find_row(vd, fd, &iter)) return; + store = gtk_tree_view_get_model(GTK_TREE_VIEW(vd->view)); + tpath = gtk_tree_model_get_path(store, &iter); + gtk_tree_view_set_cursor(GTK_TREE_VIEW(vd->view), tpath, NULL, FALSE); + + gtk_tree_path_free(tpath); +} + static void vd_pop_menu_new_cb(GtkWidget *widget, gpointer data) { ViewDir *vd = data; @@ -615,7 +650,7 @@ static void vd_pop_menu_new_cb(GtkWidget *widget, gpointer data) break; } - file_util_create_dir(dir_fd, widget, vd_pop_menu_new_rename_cb, vd); + file_util_create_dir(dir_fd, vd->layout->window, vd_pop_menu_new_folder_cb, vd); } static void vd_pop_menu_rename_cb(GtkWidget *widget, gpointer data) @@ -764,7 +799,7 @@ GtkWidget *vd_pop_menu(ViewDir *vd, FileData *fd) void vd_new_folder(ViewDir *vd, FileData *dir_fd) { - file_util_create_dir(dir_fd, vd->widget, vd_pop_menu_new_rename_cb, vd); + file_util_create_dir(dir_fd, vd->layout->window, vd_pop_menu_new_folder_cb, vd); } /* -- 2.20.1