Re: New file chooser (latest version)



On Mon, 2004-03-01 at 15:09, Jonathan Blandford wrote:
> muppet <scott asofyet org> writes:
> > Path Bar:
> > The current directory is always at the end, even when you go
> > backwards. If i recall the original proposal correctly, the child
> > directories should stick around until you change to a directory that's
> > not currently in the PathBar.  Use case:  i want to jump back up two
> > levels really quick to make sure i'm getting the file in the right
> > subdir, so i click on the parent in the PathBar.  Now i have to
> > navigate back to the child, whereas if the PathBar kept its full path,
> > i'd be able just to click on the one at the end again.
> 
> We're not going to get this working for 2.4.0 unless someone
> miraculously provides a patch.  Would be nice (TM).

like this?

(against HEAD as of five minutes ago.)


Index: gtk/gtkpathbar.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkpathbar.c,v
retrieving revision 1.7
diff -u -r1.7 gtkpathbar.c
--- gtk/gtkpathbar.c	25 Feb 2004 08:55:48 -0000	1.7
+++ gtk/gtkpathbar.c	2 Mar 2004 04:01:26 -0000
@@ -551,7 +551,7 @@
 
 
 
-/* Public functions. */
+/* Public functions (and their helpers). */
 static void
 gtk_path_bar_clear_buttons (GtkPathBar *path_bar)
 {
@@ -563,20 +563,58 @@
 }
 
 static void
-button_clicked_cb (GtkWidget *button,
-		   gpointer   data)
+button_clicked_cb (GtkWidget *button)
 {
   GtkWidget *path_bar;
   GtkFilePath *file_path;
 
+  gtk_toggle_button_set_active (button, TRUE);
+
   path_bar = button->parent;
   g_assert (path_bar);
 
-  file_path = gtk_file_path_new_dup ((char *)data);
+  file_path = gtk_file_path_new_dup (g_object_get_data (G_OBJECT (button),
+							"path"));
   g_signal_emit (path_bar, path_bar_signals [PATH_CLICKED], 0, file_path);
   gtk_file_path_free (file_path);
 }
 
+/* cosmetic, only */
+static void
+dir_button_set_current (GtkWidget * button,
+			gboolean is_current)
+{
+  GtkWidget * label;
+  const gchar * dir_name;
+  dir_name = (const gchar *) g_object_get_data (G_OBJECT (button), "dir_name");
+  label = gtk_bin_get_child (GTK_BIN (button));
+  if (is_current)
+    {
+      char * markup = g_markup_printf_escaped ("<b>%s</b>", dir_name);
+      gtk_label_set_markup (GTK_LABEL (label), markup);
+      g_free (markup);
+    }
+  else
+    {
+      gtk_label_set_text (GTK_LABEL (label), dir_name);
+    }
+  if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)) != is_current)
+    {
+      g_signal_handlers_block_by_func (G_OBJECT (button), button_clicked_cb, NULL);
+      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), is_current);
+      g_signal_handlers_unblock_by_func (G_OBJECT (button), button_clicked_cb, NULL);
+    }
+}
+
+/* gtk_file_free_path() is a macro, and sometimes not defined as something
+ * of which we can take the address.  here's a real function we can use as
+ * a callback. */
+static void
+real_free_path (GtkFilePath * p)
+{
+  gtk_file_path_free (p);
+}
+
 static GtkWidget *
 make_directory_button (const char  *dir_name,
 		       GtkFilePath *path,
@@ -585,46 +623,22 @@
   GtkWidget *button, *label;
       
   button = gtk_toggle_button_new ();
-  if (current_dir)
-    {
-      /* Yay gsignal! */
-      g_signal_connect (G_OBJECT (button), "toggled",
-			G_CALLBACK (gtk_toggle_button_set_active),
-			GINT_TO_POINTER (TRUE));
-    }
-  else
-    {
-      gchar *str;
+  g_signal_connect (button, "clicked", G_CALLBACK (button_clicked_cb), NULL);
 
-      /* FIXME: gtk_file_path_free is not be a function!! I have to
-       * copy it to a string in order to manage this correctly */
-      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);
-    }
+  g_object_set_data_full (G_OBJECT (button), "dir_name",
+			  g_strdup (dir_name),
+			  (GDestroyNotify) g_free);
+  g_object_set_data_full (G_OBJECT (button), "path",
+			  gtk_file_path_new_dup (path),
+			  (GDestroyNotify) real_free_path);
 
   label = gtk_label_new (NULL);
 
-  if (current_dir)
-    {
-      gchar *label_str;
-      
-      label_str = g_markup_printf_escaped ("<b>%s</b>", dir_name);
-      gtk_label_set_markup (GTK_LABEL (label), label_str);
-      g_free (label_str);
-
-      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
-    }
-  else
-    {
-      gtk_label_set_text (GTK_LABEL (label), dir_name);
-    }
-
   gtk_container_add (GTK_CONTAINER (button), label);
   gtk_widget_show_all (button);
 
+  dir_button_set_current (button, current_dir);
+
   return button;
 }
 
@@ -637,10 +651,30 @@
 {
   GtkFilePath *path;
   gboolean first_directory = TRUE;
+  GList * i;
+  GtkWidget * in_path = NULL;
   
   g_return_if_fail (GTK_IS_PATH_BAR (path_bar));
   g_return_if_fail (file_path != NULL);
   g_return_if_fail (file_system != NULL);
+
+  for (i = path_bar->button_list ; i != NULL; i = i->next)
+    {
+      GtkFilePath * thispath = g_object_get_data (G_OBJECT (i->data), "path");
+      if (0 == gtk_file_path_compare (file_path, thispath))
+	in_path = i->data;
+    }
+  if (in_path)
+    {
+      for (i = path_bar->button_list ; i != NULL; i = i->next)
+        dir_button_set_current (GTK_WIDGET (i->data), i->data == in_path);
+      return;
+    }
+
+  /*
+   * file_path is not already in our list of displayed paths.
+   * start over.
+   */
 
   gtk_path_bar_clear_buttons (path_bar);
   path = gtk_file_path_copy (file_path);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]