个人工具
您位于: 首页 资源中心 原始部落 13109 解读 GtkFileChooser

解读 GtkFileChooser

by YangHong posted on 2007-01-09 12:37 last modified 2007-01-09 12:40 —

GTK+ 中的文件打开对话框

使用 gnome-vfs 后端的 GTK+ 打开对话框

1。Shortcuts (快捷连接):“家目录”,“桌面”

在 "gtkfilechooserdefault.c" 8765 行

/* Creates the list model for shortcuts */
static void
shortcuts_model_create (GtkFileChooserDefault *impl)
{
...
  if (impl->file_system)
    {
      shortcuts_append_home (impl);
      shortcuts_append_desktop (impl);
      shortcuts_add_volumes (impl);
    }
...

这里添加了默认的“家目录”,“桌面” 两项,然后是由不同的 GtkFilesystem 后端(实现了 GtkFileSystemIface)提供的所有卷列表(接口 list_volumes)。

2。卷:gtk+ 默认 GtkFilesystem 后端

gtkfilesystemunix.c:476 中的 list_volumes 实现提供了一个指向 '/' (文件系统) 的卷。

static GSList *
gtk_file_system_unix_list_volumes (GtkFileSystem *file_system)
{
  return g_slist_append (NULL, get_root_volume ());
}

3。卷:gnome-vfs 后端

由 libgnomeui/file-chooser/gtkfilesystemgnomevfs.[ch] 提供的基于 gnome-vfs 后端则提供了更多的可访问卷:

1。已连接的,当前用户可访问的卷
2。已挂载的,当前用户可访问的卷
3。网络服务器(即 Samba 网络)
4。文件系统 ('/')

这里卷包括所有 gnome-vfs 支持的“卷”,如光驱,U盘,移动硬盘,数码相机,MP3 等可移动设备,还有通过“连接到服务器”创建的到 FTP/SSH/WebDAV/Samba 的连接等。

GtkFilesystem 后端实现还要提供获取卷显示名称,图标,挂载状态,执行挂载(对于已经连接尝未挂载的卷)等函数。其中由 gtkfilechooserdefault.c 默认添加的“家目录”,“桌面” 两项的图标也需要由后端提供,我认为这是不合理的,既然 Gtk+ 中自带一个 GtkFilesystem 后端的实现(名为 "gtk+"),那么就不应该在 gtkfilechooserdefault.c 添加默认项,这里的默认项大可由后端实现自行添加(就多两行代码)。目前这样的做法不方便定制:)

4。标签支持

  iface->insert_bookmark = gtk_file_system_gnome_vfs_insert_bookmark;
  iface->remove_bookmark = gtk_file_system_gnome_vfs_remove_bookmark;
  iface->list_bookmarks = gtk_file_system_gnome_vfs_list_bookmarks;
#if GTK_CHECK_VERSION(2,7,0)
  iface->get_bookmark_label = gtk_file_system_gnome_vfs_get_bookmark_label;
  iface->set_bookmark_label = gtk_file_system_gnome_vfs_set_bookmark_label;
#endif

Gtk+ >= 2.7.0 中的文件对话框支持自定义标签名,所以有 get/set_bookmark_label 接口(应该说 GtkFileSystemIface 有了这两接口,才有前者)。

目前标签支持的代码在 gtk+ 后端和 gnome-vfs 后端是一样的,是重复了,和以上的获取卷图标名一样是重复的。为什么不实现一基类来更好地重用相同的代码呢?

5。与 GNOME 桌面的集成

通过 gnome-setting-daemon 监视  /desktop/gnome/interface/file_chooser_backend 的值,并设置相应的 xsetting (-> GtkSettings) 值 "gtk-file-chooser-backend",

xsetting 与 gtk-settings 的转换:

gtk+/gdk/x11/gdksettings.c

static const char gdk_settings_names[] =
...
  "Gtk/FileChooserBackend\0"  "gtk-file-chooser-backend\0"
...

gnome-settings-daemon/gnome-settings-xsettings.c:102

static TranslationEntry translations [] = {
...
  { "/desktop/gnome/interface/file_chooser_backend",    "Gtk/FileChooserBackend",
      GCONF_VALUE_STRING,       translate_string_string },
...

当 file_chooser_backend 改变时,gnome-setting-daemon 设置对应的 X 属性 "Gtk/FileChooserBackend",这时 Gtk+ 程序会调用对应的回调函数,并生成一个 GdkEvent :

gdk/x11/gdkevents-x11.c:2835
static void
gdk_xsettings_notify_cb (const char       *name,
                         XSettingsAction   action,
                         XSettingsSetting *setting,
                         void             *data)
{

...

  new_event.type = GDK_SETTING;
  new_event.setting.window = gdk_screen_get_root_window (screen);
  new_event.setting.send_event = FALSE;
  new_event.setting.name = NULL;
...
  gdk_event_put (&new_event);
}

gtk/gtkfilechooserdefault.c:463

static void
_gtk_file_chooser_default_class_init (GtkFileChooserDefaultClass *class)
{
...
  gtk_settings_install_property (g_param_spec_string ("gtk-file-chooser-backend",
                                                      P_("Default file chooser backend"),
                                                      P_("Name of the GtkFileChooser backend to use by default"),
                                                      NULL,
                                                      GTK_PARAM_READWRITE));
}

安装了这个属性,使得后续的程序中能获取到这个属性。

这样 Gtk+ 客户端就能通过 gtk_settings_get_default () 正确的获取到这个设置,并应用到自己的程序中。

GtkFileChooser 通过 "gtk-file-chooser-backend" 的值来装入默认的 file-system.

gtkfilechooserdefault.c:4835,在没有指定 file_system 参数时,通过 gtk_settings_get_default () 来获取默认设置,即可装入桌面系统中的默认值。

  if (backend)
    impl->file_system = gtk_file_system_create (backend);
  else
    {
      GtkSettings *settings = gtk_settings_get_default ();
      gchar *default_backend = NULL;

      g_object_get (settings, "gtk-file-chooser-backend", &default_backend, NULL);
      if (default_backend)
        {
          impl->file_system = gtk_file_system_create (default_backend);
          g_free (default_backend);
        }
    }

文档操作
13109
« 十二月 2008 »
十二月
1234567
891011121314
15161718192021
22232425262728
293031
最近帖子:
Blog Entry Test simple blog 3.0beta
更多...
分类:
GTK+/GNOME (0)
开源社区 (0)
自由桌面 (0)
本 站 赞 助 商
北京红旗中文贰仟