Re: GtkFileSystemGnomeVFS



On Fri, 2004-02-13 at 17:51, Owen Taylor wrote:
> On Fri, 2004-02-13 at 06:34, Alexander Larsson wrote:

> > Although the I don't think the gtk_file_chooser_set_backend (chooser, 
> > "gnome-vfs") API works. Currently the file-system is a property of the
> > FileChooser and also a property of FileChooserDialog that is mirrored to
> > the internal FileChooser on construction time. You can't actually get at
> > the FileChooser for the dialog, and it would be preferable if we could
> > instantiate the right file-system object on FileChooser construction
> > time.
> 
> Remmeber, GtkFileChooser is the interface, not the implementation. So
> all properties are just getting forwarded. The main difference with
> the file-system property is that it works a bit different because
> it is construct-only parameter.
> 
> > So. What about a new string property "file-system-backend", in both
> > FileChooser and FileChooserDialog, behaving much like the current
> > file-system type but referencing a loadable filesystem module (by name)
> > instead of a string, and then we add this new API:
> 
> Well, just in GtkFileChooser, then implemented in GtkFileChooserWidget
> and GtkFileChooserDialog
> 
> Yes, a string property similar to file-system is basically what I had
> in mind. It probably is easiest to keep it construct-only, as evil
> as construct-only properties are...
> 
> The file-system property should be removed since GtkFileSystem is not
> public API; it was just added for testing purposes.
> 
> > GtkWidget *
> > gtk_file_chooser_dialog_new_with_backend (const gchar         *title,
> >                                           GtkWindow           *parent,
> >                                           GtkFileChooserAction action,
> >                                           const char          *backend,
> >                                           const gchar         *first_button_text,
> >                                           ...)
> 
> Ick, but yeah, that looks about right. I don't think adding the backend
> argument to gtk_file_chooser_dialog_new() is a good idea.

How about this patch? It changes the old "file-system" property into a
string, and does named lookups for filesystem backends. It also adds
gtk_file_chooser_dialog_new_with_backend and fixes an issue with the
folder mode and volumes in gtkfilechooserdefault.

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 Alexander Larsson                                            Red Hat, Inc 
                   alexl redhat com    alla lysator liu se 
He's an otherworldly arachnophobic master criminal possessed of the uncanny 
powers of an insect. She's a time-travelling hypochondriac opera singer 
descended from a line of powerful witches. They fight crime! 
Index: gtk/gtkfilechooser.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkfilechooser.c,v
retrieving revision 1.23
diff -u -p -r1.23 gtkfilechooser.c
--- gtk/gtkfilechooser.c	16 Jan 2004 23:09:24 -0000	1.23
+++ gtk/gtkfilechooser.c	16 Feb 2004 15:21:54 -0000
@@ -95,10 +95,10 @@ gtk_file_chooser_class_init (gpointer g_
 							  GTK_FILE_CHOOSER_ACTION_OPEN,
 							  G_PARAM_READWRITE));
   g_object_interface_install_property (g_iface,
-				       g_param_spec_object ("file-system",
-							    P_("File System"),
-							    P_("File system object to use"),
-							    GTK_TYPE_FILE_SYSTEM,
+				       g_param_spec_string ("file-system",
+							    P_("File System backed"),
+							    P_("Name of file system backend to use"),
+							    NULL, 
 							    G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
   g_object_interface_install_property (g_iface,
 				       g_param_spec_object ("filter",
Index: gtk/gtkfilechooserdefault.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkfilechooserdefault.c,v
retrieving revision 1.65
diff -u -p -r1.65 gtkfilechooserdefault.c
--- gtk/gtkfilechooserdefault.c	10 Feb 2004 19:48:38 -0000	1.65
+++ gtk/gtkfilechooserdefault.c	16 Feb 2004 15:21:54 -0000
@@ -51,6 +51,12 @@
 #include "gtktypebuiltins.h"
 #include "gtkvbox.h"
 
+#if defined (G_OS_UNIX)
+#include "gtkfilesystemunix.h"
+#elif defined (G_OS_WIN32)
+#include "gtkfilesystemwin32.h"
+#endif
+
 #include <string.h>
 #include <time.h>
 
@@ -1725,28 +1731,42 @@ gtk_file_chooser_default_set_property (G
       break;
     case GTK_FILE_CHOOSER_PROP_FILE_SYSTEM:
       {
-	GtkFileSystem *file_system = g_value_get_object (value);
-	if (impl->file_system != file_system)
+	GType file_system_type;
+	const char *file_system = g_value_get_string (value);
+	
+	if (impl->file_system)
 	  {
-	    if (impl->file_system)
-	      {
-		g_signal_handler_disconnect (impl->file_system, impl->volumes_changed_id);
-		impl->volumes_changed_id = 0;
-		g_signal_handler_disconnect (impl->file_system, impl->bookmarks_changed_id);
-		impl->bookmarks_changed_id = 0;
-		g_object_unref (impl->file_system);
-	      }
-	    impl->file_system = file_system;
-	    if (impl->file_system)
-	      {
-		g_object_ref (impl->file_system);
-		impl->volumes_changed_id = g_signal_connect (impl->file_system, "volumes-changed",
-							     G_CALLBACK (volumes_changed_cb),
-							     impl);
-		impl->bookmarks_changed_id = g_signal_connect (impl->file_system, "bookmarks-changed",
-							       G_CALLBACK (bookmarks_changed_cb),
-							       impl);
-	      }
+	    g_signal_handler_disconnect (impl->file_system, impl->volumes_changed_id);
+	    impl->volumes_changed_id = 0;
+	    g_signal_handler_disconnect (impl->file_system, impl->bookmarks_changed_id);
+	    impl->bookmarks_changed_id = 0;
+	    g_object_unref (impl->file_system);
+	  }
+
+	file_system_type = G_TYPE_INVALID;
+	if (file_system)
+	  file_system_type = _gtk_file_system_lookup  (file_system);
+	if (file_system_type == G_TYPE_INVALID)
+	  {
+#if defined (G_OS_UNIX)
+	    file_system_type = GTK_TYPE_FILE_SYSTEM_UNIX;
+#elif defined (G_OS_WIN32)
+	    file_system_type = GTK_TYPE_FILE_SYSTEM_WIN32;
+#else
+#error "No default filesystem implementation on the platform"
+#endif
+	  }
+	
+	impl->file_system = g_object_new (file_system_type, NULL);
+	
+	if (impl->file_system)
+	  {
+	    impl->volumes_changed_id = g_signal_connect (impl->file_system, "volumes-changed",
+							 G_CALLBACK (volumes_changed_cb),
+							 impl);
+	    impl->bookmarks_changed_id = g_signal_connect (impl->file_system, "bookmarks-changed",
+							   G_CALLBACK (bookmarks_changed_cb),
+							   impl);
 	  }
       }
       break;
@@ -2067,18 +2087,36 @@ static void
 set_tree_model (GtkFileChooserDefault *impl, const GtkFilePath *path)
 {
   GtkFileSystemVolume *volume;
-  GtkFilePath *volume_path;
+  GtkFilePath *base_path, *parent_path;
 
+  base_path = NULL;
+  
   volume = gtk_file_system_get_volume_for_path (impl->file_system, path);
-  volume_path = gtk_file_system_volume_get_base_path (impl->file_system, volume);
+  
+  if (volume)
+    base_path = gtk_file_system_volume_get_base_path (impl->file_system, volume);
+  
+  if (base_path == NULL)
+    {
+      base_path = gtk_file_path_copy (path);
+      while (gtk_file_system_get_parent (impl->file_system,
+					 base_path,
+					 &parent_path,
+					 NULL) &&
+	     parent_path != NULL)
+	{
+	  gtk_file_path_free (base_path);
+	  base_path = parent_path;
+	}
+    }
 
-  if (impl->current_volume_path && gtk_file_path_compare (volume_path, impl->current_volume_path) == 0)
+  if (impl->current_volume_path && gtk_file_path_compare (base_path, impl->current_volume_path) == 0)
     goto out;
 
   if (impl->tree_model)
     g_object_unref (impl->tree_model);
 
-  impl->current_volume_path = gtk_file_path_copy (volume_path);
+  impl->current_volume_path = gtk_file_path_copy (base_path);
 
   impl->tree_model = _gtk_file_system_model_new (impl->file_system, impl->current_volume_path, -1,
 						 GTK_FILE_INFO_DISPLAY_NAME);
@@ -2090,8 +2128,9 @@ set_tree_model (GtkFileChooserDefault *i
 
  out:
 
-  gtk_file_path_free (volume_path);
-  gtk_file_system_volume_free (impl->file_system, volume);
+  gtk_file_path_free (base_path);
+  if (volume) 
+    gtk_file_system_volume_free (impl->file_system, volume);
 }
 
 static void
@@ -3199,7 +3238,7 @@ list_mtime_data_func (GtkTreeViewColumn 
 }
 
 GtkWidget *
-_gtk_file_chooser_default_new (GtkFileSystem *file_system)
+_gtk_file_chooser_default_new (const char *file_system)
 {
   return  g_object_new (GTK_TYPE_FILE_CHOOSER_DEFAULT,
 			"file-system", file_system,
Index: gtk/gtkfilechooserdefault.h
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkfilechooserdefault.h,v
retrieving revision 1.3
diff -u -p -r1.3 gtkfilechooserdefault.h
--- gtk/gtkfilechooserdefault.h	23 Oct 2003 00:26:15 -0000	1.3
+++ gtk/gtkfilechooserdefault.h	16 Feb 2004 15:21:54 -0000
@@ -33,7 +33,7 @@ G_BEGIN_DECLS
 typedef struct _GtkFileChooserDefault      GtkFileChooserDefault;
 
 GType      _gtk_file_chooser_default_get_type (void);
-GtkWidget *_gtk_file_chooser_default_new      (GtkFileSystem *file_system);
+GtkWidget *_gtk_file_chooser_default_new      (const char *file_system);
 
 G_END_DECLS
 
Index: gtk/gtkfilechooserdialog.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkfilechooserdialog.c,v
retrieving revision 1.11
diff -u -p -r1.11 gtkfilechooserdialog.c
--- gtk/gtkfilechooserdialog.c	14 Feb 2004 01:23:58 -0000	1.11
+++ gtk/gtkfilechooserdialog.c	16 Feb 2004 15:21:54 -0000
@@ -33,13 +33,14 @@ struct _GtkFileChooserDialogPrivate
 {
   GtkWidget *widget;
 
-  GtkFileSystem *file_system;
+  char *file_system;
 };
 
 #define GTK_FILE_CHOOSER_DIALOG_GET_PRIVATE(o)  (GTK_FILE_CHOOSER_DIALOG (o)->priv)
 
 static void gtk_file_chooser_dialog_class_init (GtkFileChooserDialogClass *class);
 static void gtk_file_chooser_dialog_init       (GtkFileChooserDialog      *dialog);
+static void gtk_file_chooser_dialog_finalize   (GObject                   *object);
 
 static GObject* gtk_file_chooser_dialog_constructor  (GType                  type,
 						      guint                  n_construct_properties,
@@ -109,6 +110,7 @@ gtk_file_chooser_dialog_class_init (GtkF
   gobject_class->constructor = gtk_file_chooser_dialog_constructor;
   gobject_class->set_property = gtk_file_chooser_dialog_set_property;
   gobject_class->get_property = gtk_file_chooser_dialog_get_property;
+  gobject_class->finalize = gtk_file_chooser_dialog_finalize;
 
   widget_class->realize = gtk_file_chooser_dialog_realize;
   widget_class->style_set = gtk_file_chooser_dialog_style_set;
@@ -130,6 +132,14 @@ gtk_file_chooser_dialog_init (GtkFileCho
   gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
 }
 
+static void
+gtk_file_chooser_dialog_finalize (GObject *object)
+{
+  GtkFileChooserDialog *dialog = GTK_FILE_CHOOSER_DIALOG (object);
+
+  g_free (dialog->priv->file_system);
+}
+
 /* Callback used when the user activates a file in the file chooser widget */
 static void
 file_chooser_widget_file_activated (GtkFileChooser       *chooser,
@@ -186,17 +196,8 @@ gtk_file_chooser_dialog_set_property (GO
   switch (prop_id)
     {
     case GTK_FILE_CHOOSER_PROP_FILE_SYSTEM:
-      {
-	GtkFileSystem *file_system = g_value_get_object (value);
-	if (priv->file_system != file_system)
-	  {
-	    if (priv->file_system)
-	      g_object_unref (priv->file_system);
-	    priv->file_system = file_system;
-	    if (priv->file_system)
-	      g_object_ref (priv->file_system);
-	  }
-      }
+      g_free (priv->file_system);
+      priv->file_system = g_value_dup_string (value);
       break;
     default:
       g_object_set_property (G_OBJECT (priv->widget), pspec->name, value);
@@ -341,3 +342,57 @@ gtk_file_chooser_dialog_new (const gchar
 
   return result;
 }
+
+/**
+ * gtk_file_chooser_dialog_new_with_backend:
+ * @title: Title of the dialog, or %NULL
+ * @parent: Transient parent of the dialog, or %NULL
+ * @backend: The name of the specific filesystem backend to use.
+ * @action: Open or save mode for the dialog
+ * @first_button_text: stock ID or text to go in the first button, or %NULL
+ * @Varargs: response ID for the first button, then additional (button, id) pairs, ending with %NULL
+ *
+ * Creates a new #GtkFileChooserDialog with a specified backend. This is
+ * especially useful if use gtk_file_chooser_set_local_only to allow
+ * non-local files and you use a more expressive vfs, such as gnome-vfs,
+ * to load files.
+ *
+ * Return value: a new #GtkFileChooserDialog
+ *
+ * Since: 2.4
+ **/
+GtkWidget *
+gtk_file_chooser_dialog_new_with_backend (const gchar          *title,
+					  GtkWindow            *parent,
+					  GtkFileChooserAction  action,
+					  const gchar          *backend,
+					  const gchar          *first_button_text,
+					  ...)
+{
+  GtkWidget *result;
+  va_list varargs;
+  const char *button_text = first_button_text;
+  gint response_id;
+
+  result = g_object_new (GTK_TYPE_FILE_CHOOSER_DIALOG,
+			 "title", title,
+			 "action", action,
+			 "file-system", backend,
+			 NULL);
+
+  if (parent)
+    gtk_window_set_transient_for (GTK_WINDOW (result), parent);
+
+  va_start (varargs, first_button_text);
+
+  while (button_text)
+    {
+      response_id = va_arg (varargs, gint);
+      gtk_dialog_add_button (GTK_DIALOG (result), button_text, response_id);
+      button_text = va_arg (varargs, const gchar *);
+    }
+
+  va_end (varargs);
+
+  return result;
+}
Index: gtk/gtkfilechooserdialog.h
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkfilechooserdialog.h,v
retrieving revision 1.1.1.1
diff -u -p -r1.1.1.1 gtkfilechooserdialog.h
--- gtk/gtkfilechooserdialog.h	21 Mar 2003 20:34:02 -0000	1.1.1.1
+++ gtk/gtkfilechooserdialog.h	16 Feb 2004 15:21:54 -0000
@@ -50,12 +50,18 @@ struct _GtkFileChooserDialog
   GtkFileChooserDialogPrivate *priv;
 };
 
-GType      gtk_file_chooser_dialog_get_type (void);
-GtkWidget *gtk_file_chooser_dialog_new      (const gchar         *title,
-					     GtkWindow           *parent,
-					     GtkFileChooserAction action,
-					     const gchar         *first_button_text,
-					     ...);
+GType      gtk_file_chooser_dialog_get_type         (void);
+GtkWidget *gtk_file_chooser_dialog_new              (const gchar          *title,
+						     GtkWindow            *parent,
+						     GtkFileChooserAction  action,
+						     const gchar          *first_button_text,
+						     ...);
+GtkWidget *gtk_file_chooser_dialog_new_with_backend (const gchar          *title,
+						     GtkWindow            *parent,
+						     GtkFileChooserAction  action,
+						     const gchar          *backend,
+						     const gchar          *first_button_text,
+						     ...);
 
 G_END_DECLS
 
Index: gtk/gtkfilechooserwidget.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkfilechooserwidget.c,v
retrieving revision 1.12
diff -u -p -r1.12 gtkfilechooserwidget.c
--- gtk/gtkfilechooserwidget.c	16 Dec 2003 22:58:58 -0000	1.12
+++ gtk/gtkfilechooserwidget.c	16 Feb 2004 15:21:54 -0000
@@ -23,23 +23,18 @@
 #include "gtkfilechooserutils.h"
 #include "gtktypebuiltins.h"
 
-#if defined (G_OS_UNIX)
-#include "gtkfilesystemunix.h"
-#elif defined (G_OS_WIN32)
-#include "gtkfilesystemwin32.h"
-#endif
-
 struct _GtkFileChooserWidgetPrivate
 {
   GtkWidget *impl;
 
-  GtkFileSystem *file_system;
+  char *file_system;
 };
 
 #define GTK_FILE_CHOOSER_WIDGET_GET_PRIVATE(o)  (GTK_FILE_CHOOSER_WIDGET (o)->priv)
 
 static void gtk_file_chooser_widget_class_init   (GtkFileChooserWidgetClass *class);
 static void gtk_file_chooser_widget_init         (GtkFileChooserWidget      *chooser_widget);
+static void gtk_file_chooser_widget_finalize     (GObject                   *object);
 
 static GObject* gtk_file_chooser_widget_constructor  (GType                  type,
 						      guint                  n_construct_properties,
@@ -102,6 +97,7 @@ gtk_file_chooser_widget_class_init (GtkF
   gobject_class->constructor = gtk_file_chooser_widget_constructor;
   gobject_class->set_property = gtk_file_chooser_widget_set_property;
   gobject_class->get_property = gtk_file_chooser_widget_get_property;
+  gobject_class->finalize = gtk_file_chooser_widget_finalize;
 
   _gtk_file_chooser_install_properties (gobject_class);
 
@@ -117,6 +113,14 @@ gtk_file_chooser_widget_init (GtkFileCho
   chooser_widget->priv = priv;
 }
 
+static void
+gtk_file_chooser_widget_finalize (GObject *object)
+{
+  GtkFileChooserWidget *chooser = GTK_FILE_CHOOSER_WIDGET (object);
+
+  g_free (chooser->priv->file_system);
+}
+
 static GObject*
 gtk_file_chooser_widget_constructor (GType                  type,
 				     guint                  n_construct_properties,
@@ -134,16 +138,8 @@ gtk_file_chooser_widget_constructor (GTy
 
   gtk_widget_push_composite_child ();
 
-  if (!priv->file_system)
-    {
-#if defined (G_OS_UNIX)
-      priv->file_system = gtk_file_system_unix_new ();
-#elif defined (G_OS_WIN32)
-      priv->file_system = gtk_file_system_win32_new ();
-#endif
-    }
-      
   priv->impl = _gtk_file_chooser_default_new (priv->file_system);
+  
   gtk_box_pack_start (GTK_BOX (object), priv->impl, TRUE, TRUE, 0);
   gtk_widget_show (priv->impl);
 
@@ -175,17 +171,8 @@ gtk_file_chooser_widget_set_property (GO
   switch (prop_id)
     {
     case GTK_FILE_CHOOSER_PROP_FILE_SYSTEM:
-      {
-	GtkFileSystem *file_system = g_value_get_object (value);
-	if (priv->file_system != file_system)
-	  {
-	    if (priv->file_system)
-	      g_object_unref (priv->file_system);
-	    priv->file_system = file_system;
-	    if (priv->file_system)
-	      g_object_ref (priv->file_system);
-	  }
-      }
+      g_free (priv->file_system);
+      priv->file_system = g_value_dup_string (value);
       break;
     default:
       g_object_set_property (G_OBJECT (priv->impl), pspec->name, value);
Index: gtk/gtkfilesystem.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkfilesystem.c,v
retrieving revision 1.21
diff -u -p -r1.21 gtkfilesystem.c
--- gtk/gtkfilesystem.c	30 Jan 2004 19:49:36 -0000	1.21
+++ gtk/gtkfilesystem.c	16 Feb 2004 15:21:54 -0000
@@ -18,9 +18,10 @@
  * Boston, MA 02111-1307, USA.
  */
 
-
+#include <gmodule.h>
 #include "gtkfilesystem.h"
 #include "gtkicontheme.h"
+#include "gtkmain.h"
 
 #include <string.h>
 
@@ -886,3 +887,70 @@ gtk_file_paths_free (GSList *paths)
 
   g_slist_free (paths);
 }
+
+/*****************************************
+ *         GtkFileSystem modules         *
+ *****************************************/
+
+static GSList *loaded_file_systems;
+
+struct FileSystemInfo {
+  char *name;
+  GType type;
+};
+
+GType
+_gtk_file_system_lookup (const char *file_system_name)
+{
+  struct FileSystemInfo *file_system_info;
+  GSList *l;
+  char *module_name;
+  GModule *module;
+  GType type;
+  GType (*fsmod_init_func)(void);
+
+  for (l = loaded_file_systems; l != NULL; l = l->next)
+    {
+      file_system_info = l->data;
+
+      if (strcmp (file_system_info->name, file_system_name) == 0)
+	return file_system_info->type;
+    }
+
+  type = G_TYPE_INVALID;
+    
+  if (g_module_supported ())
+    {
+      module_name = _gtk_find_module (file_system_name, "filesystems");
+
+      if (module_name != NULL)
+	{
+	  module = g_module_open (module_name, G_MODULE_BIND_LAZY);
+
+	  if (module &&
+	      g_module_symbol (module, "get_filesystem_type",
+			       (gpointer *) &fsmod_init_func) &&
+	      fsmod_init_func)
+	    {
+	      g_module_make_resident (module);
+
+	      file_system_info = g_new (struct FileSystemInfo, 1);
+	      file_system_info->name = g_strdup (file_system_name);
+	      file_system_info->type = (fsmod_init_func)();
+
+	      loaded_file_systems = g_slist_prepend (loaded_file_systems,
+						     file_system_info);
+	      
+	      type = file_system_info->type;
+	      
+	    }
+	  else
+	    g_module_close (module);
+	}
+
+      g_free(module_name);
+
+    }
+  
+  return type;
+}
Index: gtk/gtkfilesystem.h
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkfilesystem.h,v
retrieving revision 1.17
diff -u -p -r1.17 gtkfilesystem.h
--- gtk/gtkfilesystem.h	27 Jan 2004 23:20:01 -0000	1.17
+++ gtk/gtkfilesystem.h	16 Feb 2004 15:21:54 -0000
@@ -335,6 +335,10 @@ GSList *gtk_file_paths_sort (GSList *pat
 GSList *gtk_file_paths_copy (GSList *paths);
 void    gtk_file_paths_free (GSList *paths);
 
+/* GtkFileSystem modules support */
+
+GType   _gtk_file_system_lookup (const char *file_system_name);
+
 G_END_DECLS
 
 #endif /* __GTK_FILE_SYSTEM_H__ */


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