diff --git a/ChangeLog b/ChangeLog index a84ac86252448981d40d2ff4f96bdf477b411970..b436175f4d1ac17a51815b8cd058283905e4ad73 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2008-11-30 Nick Schermer <nick@xfce.org> + + * thunar/thunar-dialogs.c, thunar/thunar-dialogs.h, + thunar/thunar-standard-view.c: Move the rename dialog to + thunar-dialog.c so we can share it with the treeview. + * thunar/thunar-tree-view.c: Add rename option to the tree pane. + 2008-11-30 Jannis Pohlmann <jannis@xfce.org> * thunar/thunar-history.c (thunar_history_set_current_directory): diff --git a/thunar/thunar-dialogs.c b/thunar/thunar-dialogs.c index 2098a5ec2d6c7ec046c779d797c2abeb809577d4..df2d884cca74b952657bf2de911e37db2bbe5b78 100644 --- a/thunar/thunar-dialogs.c +++ b/thunar/thunar-dialogs.c @@ -40,6 +40,135 @@ +gboolean +thunar_dialogs_show_rename_file (GtkWindow *parent, + ThunarFile *file) +{ + ThunarIconFactory *icon_factory; + GtkIconTheme *icon_theme; + const gchar *filename; + const gchar *text; + GtkWidget *dialog; + GtkWidget *entry; + GtkWidget *label; + GtkWidget *image; + GtkWidget *table; + GdkPixbuf *icon; + GError *error = NULL; + glong offset; + gchar *title; + gint response; + gboolean succeed = FALSE; + + _thunar_return_val_if_fail (GTK_IS_WINDOW (parent), FALSE); + _thunar_return_val_if_fail (THUNAR_IS_FILE (file), FALSE); + + /* take an extra reference on the file */ + g_object_ref (G_OBJECT (file)); + + /* get the filename of the file */ + filename = thunar_file_get_display_name (file); + + /* create a new dialog window */ + title = g_strdup_printf (_("Rename \"%s\""), filename); + dialog = gtk_dialog_new_with_buttons (title, + GTK_WINDOW (parent), + GTK_DIALOG_MODAL + | GTK_DIALOG_NO_SEPARATOR + | GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + _("_Rename"), GTK_RESPONSE_OK, + NULL); + gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); + gtk_window_set_default_size (GTK_WINDOW (dialog), 300, -1); + g_free (title); + + table = g_object_new (GTK_TYPE_TABLE, "border-width", 6, "column-spacing", 6, "row-spacing", 3, NULL); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), table, TRUE, TRUE, 0); + gtk_widget_show (table); + + icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (dialog)); + icon_factory = thunar_icon_factory_get_for_icon_theme (icon_theme); + icon = thunar_icon_factory_load_file_icon (icon_factory, file, THUNAR_FILE_ICON_STATE_DEFAULT, 48); + g_object_unref (G_OBJECT (icon_factory)); + + image = gtk_image_new_from_pixbuf (icon); + gtk_misc_set_padding (GTK_MISC (image), 6, 6); + gtk_table_attach (GTK_TABLE (table), image, 0, 1, 0, 2, GTK_FILL, GTK_FILL, 0, 0); + g_object_unref (G_OBJECT (icon)); + gtk_widget_show (image); + + label = gtk_label_new (_("Enter the new name:")); + gtk_misc_set_alignment (GTK_MISC (label), 0.0f, 0.5f); + gtk_table_attach (GTK_TABLE (table), label, 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0); + gtk_widget_show (label); + + entry = gtk_entry_new (); + gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE); + gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 1, 2, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0); + gtk_widget_show (entry); + + /* setup the old filename */ + gtk_entry_set_text (GTK_ENTRY (entry), filename); + + /* check if we don't have a directory here */ + if (!thunar_file_is_directory (file)) + { + /* check if the filename contains a dot */ + text = g_utf8_strrchr (filename, -1, '.'); + if (G_LIKELY (text != NULL)) + { + /* grab focus to the entry first, else the selection will be altered later */ + gtk_widget_grab_focus (entry); + + /* determine the UTF-8 char offset */ + offset = g_utf8_pointer_to_offset (filename, text); + + /* select the text prior to the dot */ + if (G_LIKELY (offset > 0)) + gtk_entry_select_region (GTK_ENTRY (entry), 0, offset); + } + } + + /* run the dialog */ + response = gtk_dialog_run (GTK_DIALOG (dialog)); + if (G_LIKELY (response == GTK_RESPONSE_OK)) + { + /* hide the dialog */ + gtk_widget_hide (dialog); + + /* determine the new filename */ + text = gtk_entry_get_text (GTK_ENTRY (entry)); + + /* check if we have a new name here */ + if (G_LIKELY (!exo_str_is_equal (filename, text))) + { + /* try to rename the file */ + if (!thunar_file_rename (file, text, &error)) + { + /* display an error message */ + thunar_dialogs_show_error (GTK_WIDGET (parent), error, _("Failed to rename \"%s\""), filename); + + /* release the error */ + g_error_free (error); + } + else + { + /* we've succeeded */ + succeed = TRUE; + } + } + } + + /* cleanup */ + g_object_unref (G_OBJECT (file)); + gtk_widget_destroy (dialog); + + return succeed; +} + + + /** * thunar_dialogs_show_about: * @parent : the parent #GtkWindow or %NULL. diff --git a/thunar/thunar-dialogs.h b/thunar/thunar-dialogs.h index 4830fcb4eb672202b5d2864736a64ac769e635e8..d89aac81ceaebcadbe8ea119acf06eb5fea3c2f8 100644 --- a/thunar/thunar-dialogs.h +++ b/thunar/thunar-dialogs.h @@ -21,9 +21,13 @@ #define __THUNAR_DIALOGS_H__ #include <thunar-vfs/thunar-vfs.h> +#include <thunar/thunar-file.h> G_BEGIN_DECLS; +gboolean thunar_dialogs_show_rename_file (GtkWindow *parent, + ThunarFile *file) G_GNUC_INTERNAL; + void thunar_dialogs_show_about (GtkWindow *parent, const gchar *title, const gchar *format, diff --git a/thunar/thunar-standard-view.c b/thunar/thunar-standard-view.c index c076d1d3bc65d29e7322ec08fa367264637ca584..4b12fa5d7b29676fe69aa4206da967cd170a9e40 100644 --- a/thunar/thunar-standard-view.c +++ b/thunar/thunar-standard-view.c @@ -2211,22 +2211,8 @@ static void thunar_standard_view_action_rename (GtkAction *action, ThunarStandardView *standard_view) { - ThunarIconFactory *icon_factory; - GtkIconTheme *icon_theme; - const gchar *filename; - const gchar *text; - ThunarFile *file; - GtkWidget *window; - GtkWidget *dialog; - GtkWidget *entry; - GtkWidget *label; - GtkWidget *image; - GtkWidget *table; - GdkPixbuf *icon; - GError *error = NULL; - glong offset; - gchar *title; - gint response; + ThunarFile *file; + GtkWidget *window; _thunar_return_if_fail (GTK_IS_ACTION (action)); _thunar_return_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view)); @@ -2234,107 +2220,23 @@ thunar_standard_view_action_rename (GtkAction *action, /* start renaming if we have exactly one selected file */ if (G_LIKELY (standard_view->selected_files != NULL && standard_view->selected_files->next == NULL)) { - /* determine the file in question */ - file = g_object_ref (G_OBJECT (standard_view->selected_files->data)); - filename = thunar_file_get_display_name (file); - - /* create a new dialog window */ - title = g_strdup_printf (_("Rename \"%s\""), filename); + /* get the window */ window = gtk_widget_get_toplevel (GTK_WIDGET (standard_view)); - dialog = gtk_dialog_new_with_buttons (title, - GTK_WINDOW (window), - GTK_DIALOG_MODAL - | GTK_DIALOG_NO_SEPARATOR - | GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - _("_Rename"), GTK_RESPONSE_OK, - NULL); - gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); - gtk_window_set_default_size (GTK_WINDOW (dialog), 300, -1); - g_free (title); - - table = g_object_new (GTK_TYPE_TABLE, "border-width", 6, "column-spacing", 6, "row-spacing", 3, NULL); - gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), table, TRUE, TRUE, 0); - gtk_widget_show (table); - - icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (dialog)); - icon_factory = thunar_icon_factory_get_for_icon_theme (icon_theme); - icon = thunar_icon_factory_load_file_icon (icon_factory, file, THUNAR_FILE_ICON_STATE_DEFAULT, 48); - g_object_unref (G_OBJECT (icon_factory)); - - image = gtk_image_new_from_pixbuf (icon); - gtk_misc_set_padding (GTK_MISC (image), 6, 6); - gtk_table_attach (GTK_TABLE (table), image, 0, 1, 0, 2, GTK_FILL, GTK_FILL, 0, 0); - g_object_unref (G_OBJECT (icon)); - gtk_widget_show (image); - - label = gtk_label_new (_("Enter the new name:")); - gtk_misc_set_alignment (GTK_MISC (label), 0.0f, 0.5f); - gtk_table_attach (GTK_TABLE (table), label, 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0); - gtk_widget_show (label); - - entry = gtk_entry_new (); - gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE); - gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 1, 2, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0); - gtk_widget_show (entry); - - /* setup the old filename */ - gtk_entry_set_text (GTK_ENTRY (entry), filename); - - /* check if we don't have a directory here */ - if (!thunar_file_is_directory (file)) - { - /* check if the filename contains a dot */ - text = g_utf8_strrchr (filename, -1, '.'); - if (G_LIKELY (text != NULL)) - { - /* grab focus to the entry first, else the selection will be altered later */ - gtk_widget_grab_focus (entry); - /* determine the UTF-8 char offset */ - offset = g_utf8_pointer_to_offset (filename, text); - - /* select the text prior to the dot */ - if (G_LIKELY (offset > 0)) - gtk_entry_select_region (GTK_ENTRY (entry), 0, offset); - } - } + /* get the file */ + file = THUNAR_FILE (standard_view->selected_files->data); - /* run the dialog */ - response = gtk_dialog_run (GTK_DIALOG (dialog)); - if (G_LIKELY (response == GTK_RESPONSE_OK)) + /* run the rename dialog */ + if (thunar_dialogs_show_rename_file (GTK_WINDOW (window), file)) { - /* determine the new filename */ - text = gtk_entry_get_text (GTK_ENTRY (entry)); + /* make sure the file is still visible */ + thunar_view_scroll_to_file (THUNAR_VIEW (standard_view), file, TRUE, FALSE, 0.0f, 0.0f); - /* check if we have a new name here */ - if (G_LIKELY (!exo_str_is_equal (filename, text))) - { - /* try to rename the file */ - if (!thunar_file_rename (file, text, &error)) - { - /* display an error message */ - thunar_dialogs_show_error (GTK_WIDGET (standard_view), error, _("Failed to rename \"%s\""), filename); - - /* release the error */ - g_error_free (error); - } - else - { - /* make sure the file is still visible */ - thunar_view_scroll_to_file (THUNAR_VIEW (standard_view), file, TRUE, FALSE, 0.0f, 0.0f); - - /* update the selection, so we get updated actions, statusbar, - * etc. with the new file name and probably new mime type. - */ - thunar_standard_view_selection_changed (standard_view); - } - } + /* update the selection, so we get updated actions, statusbar, + * etc. with the new file name and probably new mime type. + */ + thunar_standard_view_selection_changed (standard_view); } - - /* cleanup */ - g_object_unref (G_OBJECT (file)); - gtk_widget_destroy (dialog); } else if (g_list_length (standard_view->selected_files) > 1) { diff --git a/thunar/thunar-tree-view.c b/thunar/thunar-tree-view.c index eb3ff9100fb8c465ec97d5f98d425d0dae7d99b9..e7ee697df60870ed3c2549dff989ed7fe532b72d 100644 --- a/thunar/thunar-tree-view.c +++ b/thunar/thunar-tree-view.c @@ -139,6 +139,7 @@ static void thunar_tree_view_action_copy (ThunarTreeV static void thunar_tree_view_action_create_folder (ThunarTreeView *view); static void thunar_tree_view_action_cut (ThunarTreeView *view); static void thunar_tree_view_action_delete (ThunarTreeView *view); +static void thunar_tree_view_action_rename (ThunarTreeView *view); static void thunar_tree_view_action_eject (ThunarTreeView *view); static void thunar_tree_view_action_empty_trash (ThunarTreeView *view); static gboolean thunar_tree_view_action_mount (ThunarTreeView *view); @@ -1196,7 +1197,7 @@ thunar_tree_view_context_menu (ThunarTreeView *view, gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image); gtk_widget_show (image); - /* "Delete" doesn't make much sense for volumes */ + /* "Delete" and "Rename" don't make much sense for volumes */ if (G_LIKELY (volume == NULL)) { /* determine the parent file (required to determine "Delete" sensitivity) */ @@ -1217,6 +1218,22 @@ thunar_tree_view_context_menu (ThunarTreeView *view, /* cleanup */ if (G_LIKELY (parent_file != NULL)) g_object_unref (G_OBJECT (parent_file)); + + /* don't show the "Rename" action in the trash */ + if (G_LIKELY (!thunar_file_is_trashed (file))) + { + /* append a separator item */ + item = gtk_separator_menu_item_new (); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + gtk_widget_show (item); + + /* append the "Rename" menu action */ + item = gtk_image_menu_item_new_with_mnemonic (_("_Rename...")); + g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (thunar_tree_view_action_rename), view); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + gtk_widget_set_sensitive (item, thunar_file_is_writable (file)); + gtk_widget_show (item); + } } /* append a separator item */ @@ -1618,6 +1635,31 @@ thunar_tree_view_action_delete (ThunarTreeView *view) +static void +thunar_tree_view_action_rename (ThunarTreeView *view) +{ + ThunarFile *file; + GtkWidget *window; + + _thunar_return_if_fail (THUNAR_IS_TREE_VIEW (view)); + + /* determine the selected file */ + file = thunar_tree_view_get_selected_file (view); + if (G_LIKELY (file != NULL)) + { + /* get the toplevel window */ + window = gtk_widget_get_toplevel (GTK_WIDGET (view)); + + /* run the rename dialog */ + thunar_dialogs_show_rename_file (GTK_WINDOW (window), file); + + /* release the file */ + g_object_unref (G_OBJECT (file)); + } +} + + + static void thunar_tree_view_action_eject (ThunarTreeView *view) {