From decffc9d95b06407367a542379787ebe74f800c1 Mon Sep 17 00:00:00 2001 From: Jonathan Blandford Date: Mon, 23 Feb 2004 07:11:31 +0000 Subject: [PATCH] Use the GtkPathBar by default now. Mon Feb 23 02:08:42 2004 Jonathan Blandford * gtk/gtkfilechooserdefault.c (file_pane_create): Use the GtkPathBar by default now. * gtk/gtkpathbar.c (gtk_path_bar_set_path): Correctly set the current path from the path. (gtk_path_bar_class_init): new signal (button_clicked_cb): emit the signal when we're selected. (gtk_path_bar_clear_buttons): Fix a crasher when we weren't clearing thr first_scrolled_button. --- ChangeLog | 12 ++ ChangeLog.pre-2-10 | 12 ++ ChangeLog.pre-2-4 | 12 ++ ChangeLog.pre-2-6 | 12 ++ ChangeLog.pre-2-8 | 12 ++ gtk/gtkfilechooserdefault.c | 149 +++++++------------------ gtk/gtkpathbar.c | 213 ++++++++++++++++++++++++------------ gtk/gtkpathbar.h | 16 +-- 8 files changed, 252 insertions(+), 186 deletions(-) diff --git a/ChangeLog b/ChangeLog index 553349d307..501ee78006 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +Mon Feb 23 02:08:42 2004 Jonathan Blandford + + * gtk/gtkfilechooserdefault.c (file_pane_create): Use the + GtkPathBar by default now. + + * gtk/gtkpathbar.c (gtk_path_bar_set_path): Correctly set the + current path from the path. + (gtk_path_bar_class_init): new signal + (button_clicked_cb): emit the signal when we're selected. + (gtk_path_bar_clear_buttons): Fix a crasher when we weren't + clearing thr first_scrolled_button. + Mon Feb 23 02:26:15 2004 Matthias Clasen * gtk/gtkcombobox.c (gtk_combo_box_size_allocate): Fix the diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 553349d307..501ee78006 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,15 @@ +Mon Feb 23 02:08:42 2004 Jonathan Blandford + + * gtk/gtkfilechooserdefault.c (file_pane_create): Use the + GtkPathBar by default now. + + * gtk/gtkpathbar.c (gtk_path_bar_set_path): Correctly set the + current path from the path. + (gtk_path_bar_class_init): new signal + (button_clicked_cb): emit the signal when we're selected. + (gtk_path_bar_clear_buttons): Fix a crasher when we weren't + clearing thr first_scrolled_button. + Mon Feb 23 02:26:15 2004 Matthias Clasen * gtk/gtkcombobox.c (gtk_combo_box_size_allocate): Fix the diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index 553349d307..501ee78006 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,15 @@ +Mon Feb 23 02:08:42 2004 Jonathan Blandford + + * gtk/gtkfilechooserdefault.c (file_pane_create): Use the + GtkPathBar by default now. + + * gtk/gtkpathbar.c (gtk_path_bar_set_path): Correctly set the + current path from the path. + (gtk_path_bar_class_init): new signal + (button_clicked_cb): emit the signal when we're selected. + (gtk_path_bar_clear_buttons): Fix a crasher when we weren't + clearing thr first_scrolled_button. + Mon Feb 23 02:26:15 2004 Matthias Clasen * gtk/gtkcombobox.c (gtk_combo_box_size_allocate): Fix the diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index 553349d307..501ee78006 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,15 @@ +Mon Feb 23 02:08:42 2004 Jonathan Blandford + + * gtk/gtkfilechooserdefault.c (file_pane_create): Use the + GtkPathBar by default now. + + * gtk/gtkpathbar.c (gtk_path_bar_set_path): Correctly set the + current path from the path. + (gtk_path_bar_class_init): new signal + (button_clicked_cb): emit the signal when we're selected. + (gtk_path_bar_clear_buttons): Fix a crasher when we weren't + clearing thr first_scrolled_button. + Mon Feb 23 02:26:15 2004 Matthias Clasen * gtk/gtkcombobox.c (gtk_combo_box_size_allocate): Fix the diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 553349d307..501ee78006 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,15 @@ +Mon Feb 23 02:08:42 2004 Jonathan Blandford + + * gtk/gtkfilechooserdefault.c (file_pane_create): Use the + GtkPathBar by default now. + + * gtk/gtkpathbar.c (gtk_path_bar_set_path): Correctly set the + current path from the path. + (gtk_path_bar_class_init): new signal + (button_clicked_cb): emit the signal when we're selected. + (gtk_path_bar_clear_buttons): Fix a crasher when we weren't + clearing thr first_scrolled_button. + Mon Feb 23 02:26:15 2004 Matthias Clasen * gtk/gtkcombobox.c (gtk_combo_box_size_allocate): Fix the diff --git a/gtk/gtkfilechooserdefault.c b/gtk/gtkfilechooserdefault.c index 7c4cc47935..f1c2aa260d 100644 --- a/gtk/gtkfilechooserdefault.c +++ b/gtk/gtkfilechooserdefault.c @@ -102,13 +102,11 @@ struct _GtkFileChooserDefault GtkFilePath *current_folder; GtkFilePath *preview_path; - GtkWidget *up_button; GtkWidget *new_folder_button; GtkWidget *preview_frame; GtkWidget *filter_combo; - GtkWidget *folder_label; GtkWidget *tree_scrollwin; GtkWidget *tree; GtkWidget *shortcuts_scrollwin; @@ -249,7 +247,9 @@ static void list_row_activated (GtkTreeView *tree_view, GtkFileChooserDefault *impl); static void entry_activate (GtkEntry *entry, GtkFileChooserDefault *impl); - +static void path_bar_clicked (GtkPathBar *path_bar, + const char *file_path, + GtkFileChooserDefault *impl); static void add_bookmark_button_clicked_cb (GtkButton *button, GtkFileChooserDefault *impl); static void remove_bookmark_button_clicked_cb (GtkButton *button, @@ -873,30 +873,6 @@ create_shortcuts_model (GtkFileChooserDefault *impl) gtk_tree_view_set_model (GTK_TREE_VIEW (impl->shortcuts_tree), GTK_TREE_MODEL (impl->shortcuts_model)); } -/* Callback used when the "Up" toolbar button is clicked */ -static void -up_button_clicked_cb (GtkButton *button, - GtkFileChooserDefault *impl) -{ - GtkFilePath *parent_path; - GError *error; - - error = NULL; - if (gtk_file_system_get_parent (impl->file_system, impl->current_folder, &parent_path, &error)) - { - if (parent_path) /* If we were on a root, parent_path will be NULL */ - { - _gtk_file_chooser_set_current_folder_path (GTK_FILE_CHOOSER (impl), parent_path); - gtk_file_path_free (parent_path); - } - } - else - error_dialog (impl, - _("Could not go to the parent folder of %s:\n%s"), - impl->current_folder, - error); -} - /* Callback used when the "New Folder" toolbar button is clicked */ static void new_folder_button_clicked (GtkButton *button, @@ -1005,67 +981,6 @@ button_new (GtkFileChooserDefault *impl, return button; } -/* Creates the widgets for the current folder indicator */ -static GtkWidget * -current_folder_create (GtkFileChooserDefault *impl) -{ - GtkWidget *hbox; - - hbox = gtk_hbox_new (FALSE, 12); - gtk_widget_show (hbox); - - /* Up button */ - - impl->up_button = button_new (impl, - _("Up"), - GTK_STOCK_GO_UP, - FALSE, - TRUE, - G_CALLBACK (up_button_clicked_cb)); - gtk_box_pack_start (GTK_BOX (hbox), impl->up_button, FALSE, FALSE, 0); - - /* Current folder label */ - - impl->folder_label = gtk_label_new (NULL); - gtk_misc_set_alignment (GTK_MISC (impl->folder_label), 0.0, 0.5); - gtk_box_pack_start (GTK_BOX (hbox), impl->folder_label, FALSE, FALSE, 0); - gtk_widget_show (impl->folder_label); - - /* New folder button for save mode */ - - impl->new_folder_button = gtk_button_new_from_stock (GTK_STOCK_NEW); - g_signal_connect (impl->new_folder_button, "clicked", - G_CALLBACK (new_folder_button_clicked), impl); - gtk_box_pack_end (GTK_BOX (hbox), impl->new_folder_button, FALSE, FALSE, 0); - - if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE) - gtk_widget_show (impl->new_folder_button); - - return hbox; -} - -/* Sets the sensitivity of the toolbar buttons */ -static void -toolbar_check_sensitivity (GtkFileChooserDefault *impl) -{ - GtkFilePath *parent_path; - gboolean has_parent; - - has_parent = FALSE; - - /* I don't think we need to check GError here, do we? */ - if (gtk_file_system_get_parent (impl->file_system, impl->current_folder, &parent_path, NULL)) - { - if (parent_path) - { - gtk_file_path_free (parent_path); - has_parent = TRUE; - } - } - - gtk_widget_set_sensitive (GTK_WIDGET (impl->up_button), has_parent); -} - /* Creates the widgets for the folder tree */ static GtkWidget * create_folder_tree (GtkFileChooserDefault *impl) @@ -1555,16 +1470,24 @@ file_pane_create (GtkFileChooserDefault *impl) vbox = gtk_vbox_new (FALSE, 6); gtk_widget_show (vbox); - /* Current folder indicator */ - - widget = current_folder_create (impl); - impl->path_bar = g_object_new (gtk_path_bar_get_type (), NULL); + /* The path bar and 'Create Folder' button */ + hbox = gtk_hbox_new (FALSE, 12); + gtk_widget_show (hbox); + impl->path_bar = g_object_new (GTK_TYPE_PATH_BAR, NULL); + g_signal_connect (impl->path_bar, "path_clicked", G_CALLBACK (path_bar_clicked), impl); gtk_widget_show_all (impl->path_bar); -#ifdef USE_PATH_BAR - gtk_box_pack_start (GTK_BOX (vbox), impl->path_bar, FALSE, FALSE, 0); -#else - gtk_box_pack_start (GTK_BOX (vbox), widget, FALSE, FALSE, 0); -#endif + gtk_box_pack_start (GTK_BOX (hbox), impl->path_bar, TRUE, TRUE, 0); + + /* Create Folder */ + impl->new_folder_button = gtk_button_new_with_mnemonic (_("Create _Folder")); + g_signal_connect (impl->new_folder_button, "clicked", + G_CALLBACK (new_folder_button_clicked), impl); + gtk_box_pack_end (GTK_BOX (hbox), impl->new_folder_button, FALSE, FALSE, 0); + + if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE || + impl->folder_mode) + gtk_widget_show (impl->new_folder_button); + gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); /* Box for lists and preview */ @@ -1810,7 +1733,12 @@ gtk_file_chooser_default_set_property (GObject *object, } } else - gtk_widget_hide (impl->new_folder_button); + { + if (impl->folder_mode) + gtk_widget_show (impl->new_folder_button); + else + gtk_widget_hide (impl->new_folder_button); + } break; case GTK_FILE_CHOOSER_PROP_FILE_SYSTEM_BACKEND: @@ -1829,11 +1757,13 @@ gtk_file_chooser_default_set_property (GObject *object, { gtk_widget_hide (impl->list_scrollwin); gtk_widget_show (impl->tree_scrollwin); + gtk_widget_show (impl->new_folder_button); } else { gtk_widget_hide (impl->tree_scrollwin); gtk_widget_show (impl->list_scrollwin); + gtk_widget_hide (impl->new_folder_button); } } } @@ -2212,7 +2142,6 @@ gtk_file_chooser_default_set_current_folder (GtkFileChooser *chooser, const GtkFilePath *path) { GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser); - char *str; if (impl->current_folder) gtk_file_path_free (impl->current_folder); @@ -2220,13 +2149,7 @@ gtk_file_chooser_default_set_current_folder (GtkFileChooser *chooser, impl->current_folder = gtk_file_path_copy (path); /* Change the current folder label */ - - str = g_strdup_printf (_("Current folder: %s"), gtk_file_path_get_string (path)); - gtk_label_set_text (GTK_LABEL (impl->folder_label), str); -#ifdef USE_PATH_BAR - gtk_path_bar_set_path (GTK_PATH_BAR (impl->path_bar), gtk_file_path_get_string (path)); -#endif - g_free (str); + gtk_path_bar_set_path (GTK_PATH_BAR (impl->path_bar), path, impl->file_system, NULL); /* Update the folder tree */ @@ -2249,7 +2172,6 @@ gtk_file_chooser_default_set_current_folder (GtkFileChooser *chooser, /* Refresh controls */ shortcuts_unselect_all (impl); - toolbar_check_sensitivity (impl); g_signal_emit_by_name (impl, "current-folder-changed", 0); @@ -3089,6 +3011,19 @@ entry_activate (GtkEntry *entry, } } + +static void +path_bar_clicked (GtkPathBar *path_bar, + const char *file_path, + GtkFileChooserDefault *impl) +{ + GtkFilePath *new_folder = NULL; + + new_folder = gtk_file_path_new_dup (file_path); + _gtk_file_chooser_set_current_folder_path (GTK_FILE_CHOOSER (impl), new_folder); + gtk_file_path_free (new_folder); +} + static const GtkFileInfo * get_list_file_info (GtkFileChooserDefault *impl, GtkTreeIter *iter) diff --git a/gtk/gtkpathbar.c b/gtk/gtkpathbar.c index e377e5598f..2d615f745e 100644 --- a/gtk/gtkpathbar.c +++ b/gtk/gtkpathbar.c @@ -21,12 +21,23 @@ #include "gtktogglebutton.h" #include "gtkarrow.h" #include "gtklabel.h" +#include "gtkmain.h" +#include "gtkmarshalers.h" + +enum { + PATH_CLICKED, + LAST_SIGNAL +}; + +static guint path_bar_signals [LAST_SIGNAL] = { 0 }; + G_DEFINE_TYPE (GtkPathBar, gtk_path_bar, GTK_TYPE_CONTAINER); -static void gtk_path_bar_destroy (GtkObject *object); + +static void gtk_path_bar_finalize (GObject *object); static void gtk_path_bar_size_request (GtkWidget *widget, GtkRequisition *requisition); static void gtk_path_bar_size_allocate (GtkWidget *widget, @@ -84,7 +95,7 @@ gtk_path_bar_class_init (GtkPathBarClass *path_bar_class) widget_class = (GtkWidgetClass *) path_bar_class; container_class = (GtkContainerClass *) path_bar_class; - object_class->destroy = gtk_path_bar_destroy; + gobject_class->finalize = gtk_path_bar_finalize; widget_class->size_request = gtk_path_bar_size_request; widget_class->size_allocate = gtk_path_bar_size_allocate; @@ -95,19 +106,28 @@ gtk_path_bar_class_init (GtkPathBarClass *path_bar_class) container_class->remove = gtk_path_bar_remove; /* FIXME: */ /* container_class->child_type = gtk_path_bar_child_type;*/ + + path_bar_signals [PATH_CLICKED] = + g_signal_new ("path_clicked", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (GtkPathBarClass, path_clicked), + NULL, NULL, + _gtk_marshal_VOID__STRING, + G_TYPE_NONE, 1, + G_TYPE_STRING); } static void -gtk_path_bar_destroy (GtkObject *object) +gtk_path_bar_finalize (GObject *object) { GtkPathBar *path_bar; path_bar = GTK_PATH_BAR (object); + g_list_free (path_bar->button_list); - g_free ((void *) path_bar->path); - - GTK_OBJECT_CLASS (gtk_path_bar_parent_class)->destroy (object); + G_OBJECT_CLASS (parent_class)->finalize (object); } /* Size requisition: @@ -261,7 +281,8 @@ gtk_path_bar_size_allocate (GtkWidget *widget, { child = GTK_WIDGET (list->data); - if (width + child->requisition.width + path_bar->spacing + slider_space > allocation_width) + if (width + child->requisition.width + + path_bar->spacing + slider_space > allocation_width) reached_end = TRUE; else width += child->requisition.width + path_bar->spacing; @@ -457,7 +478,8 @@ static void gtk_path_bar_scroll_down (GtkWidget *button, GtkPathBar *path_bar) { GList *list; - GList *down_button, *up_button; + GList *down_button = NULL; + GList *up_button = NULL; gint space_available; gint space_needed; gint border_width; @@ -532,82 +554,129 @@ gtk_path_bar_clear_buttons (GtkPathBar *path_bar) { gtk_container_remove (GTK_CONTAINER (path_bar), path_bar->button_list->data); } + path_bar->first_scrolled_button = NULL; } -/* FIXME: Do this right. Quick hack to get something on the screen. Get in - * sync with nautilus-spatial-window.c:location_button_clicked_callback */ - -static GList * -gtk_path_bar_get_description_list (const gchar *path) +static void +button_clicked_cb (GtkWidget *button, + gpointer data) { - GList *description_list = NULL; - gchar** str_list; - gint i = 0; + GtkWidget *path_bar; - str_list = g_strsplit (path, "/", -1); + path_bar = button->parent; + g_assert (path_bar); - while (str_list[i]) + g_signal_emit (path_bar, path_bar_signals [PATH_CLICKED], 0, (const char *) data); +} + +static GtkWidget * +make_directory_button (const char *dir_name, + GtkFilePath *path, + gboolean current_dir) +{ + GtkWidget *button, *label; + + button = gtk_toggle_button_new (); + if (current_dir) { - if (str_list[i][0] == '\000') - g_free (str_list[i]); - else - description_list = g_list_prepend (description_list, str_list[i]); - - i++; + /* Yay gsignal! */ + g_signal_connect (G_OBJECT (button), "toggled", + G_CALLBACK (gtk_toggle_button_set_active), + GINT_TO_POINTER (TRUE)); } - g_free (str_list); - - description_list = g_list_append (description_list, " / "); - - return description_list; -} - -/* FIXME: non UTF-8 strings */ -void -gtk_path_bar_set_path (GtkPathBar *path_bar, - const gchar *path) -{ - GList *button_list = NULL; - GList *description_list; - GList *list; - - g_return_if_fail (GTK_IS_PATH_BAR (path_bar)); - g_return_if_fail (path != NULL); - - if (path_bar->path) - g_free ((void *) path_bar->path); - gtk_path_bar_clear_buttons (path_bar); - - /* New path */ - path_bar->path = g_strdup (path); - description_list = gtk_path_bar_get_description_list (path); - for (list = description_list; list; list = list->next) + else + { + gchar *str; + + str = g_strdup (gtk_file_path_get_string (path)); + g_signal_connect (button, "clicked", G_CALLBACK (button_clicked_cb), str); + g_object_weak_ref (G_OBJECT (button), (GWeakNotify) g_free, str); + } + + label = gtk_label_new (NULL); + + if (current_dir) { - GtkWidget *button, *label; gchar *label_str; - - button = gtk_toggle_button_new (); - - if (list->prev == NULL) - { - label_str = g_strdup_printf ("%s", (char *)list->data); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE); - } - else - { - label_str = g_strdup_printf ("%s",(char *) list->data); - } - - label = gtk_label_new (NULL); + + label_str = g_markup_printf_escaped ("%s", dir_name); gtk_label_set_markup (GTK_LABEL (label), label_str); - gtk_container_add (GTK_CONTAINER (button), label); - button_list = g_list_prepend (button_list, button); - gtk_container_add (GTK_CONTAINER (path_bar), button); - gtk_widget_show_all (button); + g_free (label_str); + + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE); + } + else + { + gtk_label_set_text (GTK_LABEL (label), dir_name); } - path_bar->button_list = g_list_reverse (button_list); - gtk_widget_queue_resize (GTK_WIDGET (path_bar)); + gtk_container_add (GTK_CONTAINER (button), label); + gtk_widget_show_all (button); + + return button; } +void +gtk_path_bar_set_path (GtkPathBar *path_bar, + const GtkFilePath *file_path, + GtkFileSystem *file_system, + GError **error) +{ + gboolean valid = TRUE; + GtkFilePath *path; + gboolean first_directory = TRUE; + + gtk_path_bar_clear_buttons (path_bar); + path = gtk_file_path_copy (file_path); + + while (path != NULL) + { + GtkFilePath *parent_path = NULL; + GtkWidget *button; + const gchar *display_name; + GError *err = NULL; + + valid = gtk_file_system_get_parent (file_system, + path, + &parent_path, + &err); + if (!valid) + { + g_propagate_error (error, err); + g_error_free (err); + gtk_file_path_free (path); + break; + } + + if (parent_path) + { + GtkFileFolder *file_folder; + GtkFileInfo *file_info; + + file_folder = gtk_file_system_get_folder (file_system, parent_path, + GTK_FILE_INFO_DISPLAY_NAME, NULL); + file_info = gtk_file_folder_get_info (file_folder, path, NULL); + display_name = gtk_file_info_get_display_name (file_info); + button = make_directory_button (display_name, path, first_directory); + gtk_file_info_free (file_info); + /* FIXME: ask owen about mem management. gtk_file_folder_free (file_folder); */ + } + else + { + /* We've reached the root node */ + /* FIXME: gtk_file_system_get_root_display_name() or something */ + button = make_directory_button (gtk_file_path_get_string (path), + path, first_directory); + } + + gtk_container_add (GTK_CONTAINER (path_bar), button); + path_bar->button_list = g_list_prepend (path_bar->button_list, button); + gtk_file_path_free (path); + + path = parent_path; + first_directory = FALSE; + } + + path_bar->button_list = g_list_reverse (path_bar->button_list); +} diff --git a/gtk/gtkpathbar.h b/gtk/gtkpathbar.h index 0fcee4b761..04dd3b7ce0 100644 --- a/gtk/gtkpathbar.h +++ b/gtk/gtkpathbar.h @@ -21,6 +21,7 @@ #define __GTK_PATH_BAR__ #include "gtkcontainer.h" +#include "gtkfilesystem.h" G_BEGIN_DECLS @@ -39,28 +40,29 @@ struct _GtkPathBar { GtkContainer parent; - const char *path; GList *button_list; GList *first_scrolled_button; + GtkWidget *up_slider_button; + GtkWidget *down_slider_button; gint16 slider_width; gint16 spacing; gint16 button_offset; guint slider_visible : 1; - GtkWidget *up_slider_button; - GtkWidget *down_slider_button; }; struct _GtkPathBarClass { GtkContainerClass parent_class; - void (* path_clicked) (GtkPathBar *path_bar); + void (* path_clicked) (GtkPathBar *path_bar, + const gchar *file_path); }; GType gtk_path_bar_get_type (void) G_GNUC_CONST; -void gtk_path_bar_set_path (GtkPathBar *path_bar, - const gchar *path); - +void gtk_path_bar_set_path (GtkPathBar *path_bar, + const GtkFilePath *file_path, + GtkFileSystem *file_system, + GError **error); G_END_DECLS #endif /* __GTK_PATH_BAR__ */