[Xfce4-commits] r29929 - in thunar/branches/migration-to-gio: . thunar
Jannis Pohlmann
jannis at xfce.org
Thu May 7 18:42:52 CEST 2009
Author: jannis
Date: 2009-05-07 16:42:51 +0000 (Thu, 07 May 2009)
New Revision: 29929
Added:
thunar/branches/migration-to-gio/thunar/thunar-misc-jobs.c
thunar/branches/migration-to-gio/thunar/thunar-misc-jobs.h
Modified:
thunar/branches/migration-to-gio/ChangeLog
thunar/branches/migration-to-gio/thunar/Makefile.am
thunar/branches/migration-to-gio/thunar/thunar-create-dialog.h
thunar/branches/migration-to-gio/thunar/thunar-gio-extensions.c
thunar/branches/migration-to-gio/thunar/thunar-gio-extensions.h
thunar/branches/migration-to-gio/thunar/thunar-standard-view.c
thunar/branches/migration-to-gio/thunar/thunar-templates-action.c
Log:
* Makefile.am, thunar/thunar-misc-jobs.{c,h}: Add new file for
miscellaneous jobs. Add new job
thunar_misc_jobs_load_template_files() which recursively loads all
template files/directories as ThunarFile objects from
G_USER_DIRECTORY_TEMPLATES.
* thunar/thunar-gio-extensions.{c,h}: Add new method
g_file_new_for_user_special_dir() which creates a GFile for a
GUserDirectory and falls back to $HOME (so it's ignored later) if
the special dir is not set.
* thunar/thunar-create-dialog.h, thunar/thunar-standard-view.c,
thunar/thunar-templates-action.c: Migrate ThunarTemplatesAction away
from ThunarVFS. Use ThunarFile instead of ThunarVfsInfo for the
"create-template" signal. Load the templates menu using
thunar_misc_jobs_load_template_files().
Modified: thunar/branches/migration-to-gio/ChangeLog
===================================================================
--- thunar/branches/migration-to-gio/ChangeLog 2009-05-05 22:12:08 UTC (rev 29928)
+++ thunar/branches/migration-to-gio/ChangeLog 2009-05-07 16:42:51 UTC (rev 29929)
@@ -1,3 +1,20 @@
+2009-05-07 Jannis Pohlmann <jannis at xfce.org>
+
+ * Makefile.am, thunar/thunar-misc-jobs.{c,h}: Add new file for
+ miscellaneous jobs. Add new job
+ thunar_misc_jobs_load_template_files() which recursively loads all
+ template files/directories as ThunarFile objects from
+ G_USER_DIRECTORY_TEMPLATES.
+ * thunar/thunar-gio-extensions.{c,h}: Add new method
+ g_file_new_for_user_special_dir() which creates a GFile for a
+ GUserDirectory and falls back to $HOME (so it's ignored later) if
+ the special dir is not set.
+ * thunar/thunar-create-dialog.h, thunar/thunar-standard-view.c,
+ thunar/thunar-templates-action.c: Migrate ThunarTemplatesAction away
+ from ThunarVFS. Use ThunarFile instead of ThunarVfsInfo for the
+ "create-template" signal. Load the templates menu using
+ thunar_misc_jobs_load_template_files().
+
2009-05-05 Jannis Pohlmann <jannis at xfce.org>
* configure.in.in: Depend on exo-0.3.101svn-r29926 for ExoJob.
Modified: thunar/branches/migration-to-gio/thunar/Makefile.am
===================================================================
--- thunar/branches/migration-to-gio/thunar/Makefile.am 2009-05-05 22:12:08 UTC (rev 29928)
+++ thunar/branches/migration-to-gio/thunar/Makefile.am 2009-05-07 16:42:51 UTC (rev 29929)
@@ -122,6 +122,8 @@
thunar-location-entry.h \
thunar-metafile.c \
thunar-metafile.h \
+ thunar-misc-jobs.c \
+ thunar-misc-jobs.h \
thunar-navigator.c \
thunar-navigator.h \
thunar-pango-extensions.c \
Modified: thunar/branches/migration-to-gio/thunar/thunar-create-dialog.h
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-create-dialog.h 2009-05-05 22:12:08 UTC (rev 29928)
+++ thunar/branches/migration-to-gio/thunar/thunar-create-dialog.h 2009-05-07 16:42:51 UTC (rev 29929)
@@ -21,7 +21,7 @@
#ifndef __THUNAR_CREATE_DIALOG_H__
#define __THUNAR_CREATE_DIALOG_H__
-#include <thunar-vfs/thunar-vfs.h>
+#include <gtk/gtk.h>
G_BEGIN_DECLS;
Modified: thunar/branches/migration-to-gio/thunar/thunar-gio-extensions.c
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-gio-extensions.c 2009-05-05 22:12:08 UTC (rev 29928)
+++ thunar/branches/migration-to-gio/thunar/thunar-gio-extensions.c 2009-05-07 16:42:51 UTC (rev 29929)
@@ -63,6 +63,22 @@
+GFile *
+g_file_new_for_user_special_dir (GUserDirectory dir)
+{
+ const gchar *path;
+
+ _thunar_return_val_if_fail (dir >= 0 && dir < G_USER_N_DIRECTORIES, NULL);
+
+ path = g_get_user_special_dir (dir);
+ if (path == NULL)
+ path = xfce_get_homedir ();
+
+ return g_file_new_for_path (path);
+}
+
+
+
gboolean
g_file_is_root (GFile *file)
{
Modified: thunar/branches/migration-to-gio/thunar/thunar-gio-extensions.h
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-gio-extensions.h 2009-05-05 22:12:08 UTC (rev 29928)
+++ thunar/branches/migration-to-gio/thunar/thunar-gio-extensions.h 2009-05-07 16:42:51 UTC (rev 29929)
@@ -24,16 +24,17 @@
G_BEGIN_DECLS
-GFile *g_file_new_for_home (void);
-GFile *g_file_new_for_root (void);
-GFile *g_file_new_for_trash (void);
-GFile *g_file_new_for_desktop (void);
+GFile *g_file_new_for_home (void);
+GFile *g_file_new_for_root (void);
+GFile *g_file_new_for_trash (void);
+GFile *g_file_new_for_desktop (void);
+GFile *g_file_new_for_user_special_dir (GUserDirectory dir);
-gboolean g_file_is_root (GFile *file);
-gboolean g_file_is_trashed (GFile *file);
-gboolean g_file_is_desktop (GFile *file);
+gboolean g_file_is_root (GFile *file);
+gboolean g_file_is_trashed (GFile *file);
+gboolean g_file_is_desktop (GFile *file);
-gchar *g_file_size_humanize (guint64 size);
+gchar *g_file_size_humanize (guint64 size);
/**
* G_TYPE_FILE_LIST:
@@ -43,20 +44,20 @@
**/
#define G_TYPE_FILE_LIST (g_file_list_get_type ())
-GType g_file_list_get_type (void);
+GType g_file_list_get_type (void);
-GList *g_file_list_new_from_string (const gchar *string);
-gchar *g_file_list_to_string (GList *list);
-GList *g_file_list_append (GList *list,
- GFile *file);
-GList *g_file_list_prepend (GList *list,
- GFile *file);
-GList *g_file_list_copy (GList *list);
-void g_file_list_free (GList *list);
+GList *g_file_list_new_from_string (const gchar *string);
+gchar *g_file_list_to_string (GList *list);
+GList *g_file_list_append (GList *list,
+ GFile *file);
+GList *g_file_list_prepend (GList *list,
+ GFile *file);
+GList *g_file_list_copy (GList *list);
+void g_file_list_free (GList *list);
-gboolean g_volume_is_removable (GVolume *volume);
-gboolean g_volume_is_mounted (GVolume *volume);
-gboolean g_volume_is_present (GVolume *volume);
+gboolean g_volume_is_removable (GVolume *volume);
+gboolean g_volume_is_mounted (GVolume *volume);
+gboolean g_volume_is_present (GVolume *volume);
G_END_DECLS
Added: thunar/branches/migration-to-gio/thunar/thunar-misc-jobs.c
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-misc-jobs.c (rev 0)
+++ thunar/branches/migration-to-gio/thunar/thunar-misc-jobs.c 2009-05-07 16:42:51 UTC (rev 29929)
@@ -0,0 +1,104 @@
+/* vi:set et ai sw=2 sts=2 ts=2: */
+/*-
+ * Copyright (c) 2009 Jannis Pohlmann <jannis at xfce.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gio/gio.h>
+
+#include <thunar/thunar-io-scan-directory.h>
+#include <thunar/thunar-job.h>
+#include <thunar/thunar-misc-jobs.h>
+#include <thunar/thunar-private.h>
+#include <thunar/thunar-simple-job.h>
+
+
+
+static gboolean
+_thunar_misc_jobs_load_templates (ThunarJob *job,
+ GValueArray *param_values,
+ GError **error)
+{
+ ThunarFile *file;
+ GtkWidget *menu;
+ GFile *home_dir;
+ GFile *templates_dir;
+ GList *files = NULL;
+ GList *lp;
+ GList *paths = NULL;
+
+ _thunar_return_val_if_fail (THUNAR_IS_JOB (job), FALSE);
+ _thunar_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+ _thunar_return_val_if_fail (param_values != NULL && param_values->n_values == 1, FALSE);
+
+ menu = g_value_get_object (g_value_array_get_nth (param_values, 0));
+ g_object_set_data (G_OBJECT (job), "menu", menu);
+
+ home_dir = g_file_new_for_home ();
+ templates_dir = g_file_new_for_user_special_dir (G_USER_DIRECTORY_TEMPLATES);
+
+ if (G_LIKELY (!g_file_equal (templates_dir, home_dir)))
+ {
+ paths = thunar_io_scan_directory (job, templates_dir,
+ G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+ TRUE, NULL);
+
+ /* turn the GFile list into a ThunarFile list */
+ for (lp = g_list_last (paths);
+ lp != NULL && !exo_job_is_cancelled (EXO_JOB (job));
+ lp = lp->prev)
+ {
+ file = thunar_file_get (lp->data, NULL);
+ if (G_LIKELY (file != NULL))
+ files = g_list_prepend (files, file);
+ }
+
+ /* free the GFile list */
+ g_file_list_free (paths);
+ }
+
+ g_object_unref (templates_dir);
+ g_object_unref (home_dir);
+
+ if (files == NULL || exo_job_is_cancelled (EXO_JOB (job)))
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
+ _("No templates installed"));
+
+ return FALSE;
+ }
+ else
+ {
+ if (!thunar_job_files_ready (job, files))
+ thunar_file_list_free (files);
+
+ return TRUE;
+ }
+}
+
+
+
+ThunarJob *
+thunar_misc_jobs_load_template_files (GtkWidget *menu)
+{
+ return thunar_simple_job_launch (_thunar_misc_jobs_load_templates, 1,
+ GTK_TYPE_MENU, menu);
+}
Added: thunar/branches/migration-to-gio/thunar/thunar-misc-jobs.h
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-misc-jobs.h (rev 0)
+++ thunar/branches/migration-to-gio/thunar/thunar-misc-jobs.h 2009-05-07 16:42:51 UTC (rev 29929)
@@ -0,0 +1,32 @@
+/* vi:set et ai sw=2 sts=2 ts=2: */
+/*-
+ * Copyright (c) 2009 Jannis Pohlmann <jannis at xfce.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __THUNAR_MISC_JOBS_H__
+#define __THUNAR_MISC_JOBS_H__
+
+#include <thunar/thunar-job.h>
+
+G_BEGIN_DECLS
+
+ThunarJob *thunar_misc_jobs_load_template_files (GtkWidget *menu);
+
+G_END_DECLS
+
+#endif /* !__THUNAR_MISC_JOBS_H__ */
Modified: thunar/branches/migration-to-gio/thunar/thunar-standard-view.c
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-standard-view.c 2009-05-05 22:12:08 UTC (rev 29928)
+++ thunar/branches/migration-to-gio/thunar/thunar-standard-view.c 2009-05-07 16:42:51 UTC (rev 29929)
@@ -162,7 +162,7 @@
static void thunar_standard_view_action_create_folder (GtkAction *action,
ThunarStandardView *standard_view);
static void thunar_standard_view_action_create_template (GtkAction *action,
- const ThunarVfsInfo *info,
+ const ThunarFile *file,
ThunarStandardView *standard_view);
static void thunar_standard_view_action_properties (GtkAction *action,
ThunarStandardView *standard_view);
@@ -1865,32 +1865,28 @@
static void
thunar_standard_view_action_create_template (GtkAction *action,
- const ThunarVfsInfo *info,
+ const ThunarFile *file,
ThunarStandardView *standard_view)
{
ThunarApplication *application;
- const gchar *content_type;
ThunarFile *current_directory;
- GFile *file;
GList source_path_list;
GList target_path_list;
gchar *name;
gchar *title;
- gchar *uri;
- _thunar_return_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view));
_thunar_return_if_fail (GTK_IS_ACTION (action));
- _thunar_return_if_fail (info != NULL);
+ _thunar_return_if_fail (THUNAR_IS_FILE (file));
+ _thunar_return_if_fail (THUNAR_IS_STANDARD_VIEW (standard_view));
/* generate a title for the create dialog */
- title = g_strdup_printf (_("Create Document from template \"%s\""), info->display_name);
+ title = g_strdup_printf (_("Create Document from template \"%s\""),
+ thunar_file_get_display_name (file));
- content_type = thunar_vfs_mime_info_get_name (info->mime_info);
-
/* ask the user to enter a name for the new document */
name = thunar_show_create_dialog (GTK_WIDGET (standard_view),
- content_type,
- info->display_name,
+ thunar_file_get_content_type (file),
+ thunar_file_get_display_name (file),
title);
if (G_LIKELY (name != NULL))
{
@@ -1898,12 +1894,8 @@
current_directory = thunar_navigator_get_current_directory (THUNAR_NAVIGATOR (standard_view));
if (G_LIKELY (current_directory != NULL))
{
- uri = thunar_vfs_path_dup_uri (info->path);
- file = g_file_new_for_uri (uri);
- g_free (uri);
-
/* fake the source path list */
- source_path_list.data = file;
+ source_path_list.data = thunar_file_get_file (file);
source_path_list.next = NULL;
source_path_list.prev = NULL;
@@ -1920,7 +1912,6 @@
/* release the target path */
g_object_unref (target_path_list.data);
- g_object_unref (source_path_list.data);
}
/* release the file name */
Modified: thunar/branches/migration-to-gio/thunar/thunar-templates-action.c
===================================================================
--- thunar/branches/migration-to-gio/thunar/thunar-templates-action.c 2009-05-05 22:12:08 UTC (rev 29928)
+++ thunar/branches/migration-to-gio/thunar/thunar-templates-action.c 2009-05-07 16:42:51 UTC (rev 29929)
@@ -1,6 +1,7 @@
/* $Id$ */
/*-
* Copyright (c) 2005-2006 Benedikt Meurer <benny at xfce.org>
+ * Copyright (c) 2009 Jannis Pohlmann <jannis at xfce.org>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -21,8 +22,11 @@
#include <config.h>
#endif
-#include <thunar-vfs/thunar-vfs.h>
+#include <gio/gio.h>
+#include <thunar/thunar-icon-factory.h>
+#include <thunar/thunar-job.h>
+#include <thunar/thunar-misc-jobs.h>
#include <thunar/thunar-private.h>
#include <thunar/thunar-templates-action.h>
@@ -39,10 +43,9 @@
static void thunar_templates_action_class_init (ThunarTemplatesActionClass *klass);
+static void thunar_templates_action_init (ThunarTemplatesAction *templates_action);
+static void thunar_templates_action_finalize (GObject *object);
static GtkWidget *thunar_templates_action_create_menu_item (GtkAction *action);
-static void thunar_templates_action_fill_menu (ThunarTemplatesAction *templates_action,
- ThunarVfsPath *templates_path,
- GtkWidget *menu);
static void thunar_templates_action_menu_shown (GtkWidget *menu,
ThunarTemplatesAction *templates_action);
@@ -54,12 +57,14 @@
void (*create_empty_file) (ThunarTemplatesAction *templates_action);
void (*create_template) (ThunarTemplatesAction *templates_action,
- const ThunarVfsInfo *info);
+ const ThunarFile *file);
};
struct _ThunarTemplatesAction
{
- GtkAction __parent__;
+ GtkAction __parent__;
+
+ ThunarJob *job;
};
@@ -76,21 +81,13 @@
if (G_UNLIKELY (type == G_TYPE_INVALID))
{
- static const GTypeInfo info =
- {
- sizeof (ThunarTemplatesActionClass),
- NULL,
- NULL,
- (GClassInitFunc) thunar_templates_action_class_init,
- NULL,
- NULL,
- sizeof (ThunarTemplatesAction),
- 0,
- NULL,
- NULL,
- };
-
- type = g_type_register_static (GTK_TYPE_ACTION, I_("ThunarTemplatesAction"), &info, 0);
+ type = g_type_register_static_simple (GTK_TYPE_ACTION,
+ I_("ThunarTemplatesAction"),
+ sizeof (ThunarTemplatesActionClass),
+ (GClassInitFunc) thunar_templates_action_class_init,
+ sizeof (ThunarTemplatesAction),
+ (GInstanceInitFunc) thunar_templates_action_init,
+ 0);
}
return type;
@@ -102,10 +99,14 @@
thunar_templates_action_class_init (ThunarTemplatesActionClass *klass)
{
GtkActionClass *gtkaction_class;
+ GObjectClass *gobject_class;
/* determine the parent type class */
thunar_templates_action_parent_class = g_type_class_peek_parent (klass);
+ gobject_class = G_OBJECT_CLASS (klass);
+ gobject_class->finalize = thunar_templates_action_finalize;
+
gtkaction_class = GTK_ACTION_CLASS (klass);
gtkaction_class->create_menu_item = thunar_templates_action_create_menu_item;
@@ -127,23 +128,49 @@
/**
* ThunarTemplatesAction::create-template:
* @templates_action : a #ThunarTemplatesAction.
- * @info : the #ThunarVfsInfo of the template file.
+ * @file : the #ThunarFile of the template file.
*
* Emitted by @templates_action whenever the user requests to
* create a new file based on the template referred to by
- * @info.
+ * @file.
**/
templates_action_signals[CREATE_TEMPLATE] =
g_signal_new (I_("create-template"),
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (ThunarTemplatesActionClass, create_template),
- NULL, NULL, g_cclosure_marshal_VOID__BOXED,
- G_TYPE_NONE, 1, THUNAR_VFS_TYPE_INFO);
+ NULL, NULL, g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1, THUNAR_TYPE_FILE);
}
+static void
+thunar_templates_action_init (ThunarTemplatesAction *templates_action)
+{
+ templates_action->job = NULL;
+}
+
+
+
+static void
+thunar_templates_action_finalize (GObject *object)
+{
+ ThunarTemplatesAction *templates_action = THUNAR_TEMPLATES_ACTION (object);
+
+ if (templates_action->job != NULL)
+ {
+ g_signal_handlers_disconnect_matched (templates_action->job,
+ G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL,
+ templates_action);
+ g_object_unref (templates_action->job);
+ }
+
+ (*G_OBJECT_CLASS (thunar_templates_action_parent_class)->finalize) (object);
+}
+
+
+
static GtkWidget*
thunar_templates_action_create_menu_item (GtkAction *action)
{
@@ -165,256 +192,365 @@
-static gint
-info_compare (gconstpointer a,
- gconstpointer b)
-{
- const ThunarVfsInfo *info_a = a;
- const ThunarVfsInfo *info_b = b;
- gchar *name_a;
- gchar *name_b;
- gint result;
-
- /* sort folders before files */
- if (info_a->type == THUNAR_VFS_FILE_TYPE_DIRECTORY && info_b->type != THUNAR_VFS_FILE_TYPE_DIRECTORY)
- return -1;
- else if (info_a->type != THUNAR_VFS_FILE_TYPE_DIRECTORY && info_b->type == THUNAR_VFS_FILE_TYPE_DIRECTORY)
- return 1;
-
- /* compare by name */
- name_a = g_utf8_casefold (info_a->display_name, -1);
- name_b = g_utf8_casefold (info_b->display_name, -1);
- result = g_utf8_collate (name_a, name_b);
- g_free (name_b);
- g_free (name_a);
-
- return result;
-}
-
-
-
static void
item_activated (GtkWidget *item,
ThunarTemplatesAction *templates_action)
{
- const ThunarVfsInfo *info;
+ const ThunarFile *file;
_thunar_return_if_fail (THUNAR_IS_TEMPLATES_ACTION (templates_action));
_thunar_return_if_fail (GTK_IS_WIDGET (item));
- /* check if an info is set for the item (else it's the "Empty File" item) */
- info = g_object_get_data (G_OBJECT (item), I_("thunar-vfs-info"));
- if (G_UNLIKELY (info != NULL))
- g_signal_emit (G_OBJECT (templates_action), templates_action_signals[CREATE_TEMPLATE], 0, info);
+ /* check if a file is set for the item (else it's the "Empty File" item) */
+ file = g_object_get_data (G_OBJECT (item), I_("thunar-file"));
+ if (G_UNLIKELY (file != NULL))
+ {
+ g_signal_emit (G_OBJECT (templates_action),
+ templates_action_signals[CREATE_TEMPLATE], 0, file);
+ }
else
- g_signal_emit (G_OBJECT (templates_action), templates_action_signals[CREATE_EMPTY_FILE], 0);
+ {
+ g_signal_emit (G_OBJECT (templates_action),
+ templates_action_signals[CREATE_EMPTY_FILE], 0);
+ }
}
-static void
-thunar_templates_action_fill_menu (ThunarTemplatesAction *templates_action,
- ThunarVfsPath *templates_path,
- GtkWidget *menu)
+static GtkWidget *
+find_parent_menu (ThunarFile *file,
+ GList *dirs,
+ GList *items)
{
- ThunarVfsInfo *info;
- ThunarVfsPath *path;
- GtkIconTheme *icon_theme;
- const gchar *icon_name;
- const gchar *name;
- GtkWidget *submenu;
- GtkWidget *image;
- GtkWidget *item;
- gchar *absolute_path;
- gchar *label;
- gchar *dot;
- GList *info_list = NULL;
- GList *lp;
- GDir *dp;
+ GtkWidget *parent_menu = NULL;
+ GFile *parent;
+ GList *lp;
+ GList *ip;
- /* try to open the templates (sub)directory */
- absolute_path = thunar_vfs_path_dup_string (templates_path);
- dp = g_dir_open (absolute_path, 0, NULL);
- g_free (absolute_path);
+ /* determine the parent of the file */
+ parent = g_file_get_parent (thunar_file_get_file (file));
- /* read the directory contents (if opened successfully) */
- if (G_LIKELY (dp != NULL))
+ /* check if the file has a parent at all */
+ if (parent == NULL)
+ return NULL;
+
+ /* iterate over all dirs and menu items */
+ for (lp = g_list_first (dirs), ip = g_list_first (items);
+ parent_menu == NULL && lp != NULL && ip != NULL;
+ lp = lp->next, ip = ip->next)
{
- /* process all files within the directory */
- for (;;)
+ /* check if the current dir/item is the parent of our file */
+ if (g_file_equal (parent, thunar_file_get_file (lp->data)))
{
- /* read the name of the next file */
- name = g_dir_read_name (dp);
- if (G_UNLIKELY (name == NULL))
- break;
- else if (name[0] == '.')
- continue;
+ /* we want to insert an item for the file in this menu */
+ parent_menu = gtk_menu_item_get_submenu (ip->data);
+ }
+ }
- /* determine the info for that file */
- path = thunar_vfs_path_relative (templates_path, name);
- info = thunar_vfs_info_new_for_path (path, NULL);
- thunar_vfs_path_unref (path);
+ /* destroy the parent GFile */
+ g_object_unref (parent);
- /* add the info (if any) to our list */
- if (G_LIKELY (info != NULL))
- info_list = g_list_insert_sorted (info_list, info, info_compare);
- }
+ return parent_menu;
+}
- /* close the directory handle */
- g_dir_close (dp);
+
+
+static gint
+compare_files (ThunarFile *a,
+ ThunarFile *b)
+{
+ GFile *file_a;
+ GFile *file_b;
+ GFile *parent_a;
+ GFile *parent_b;
+
+ file_a = thunar_file_get_file (a);
+ file_b = thunar_file_get_file (b);
+
+ /* check whether the files are equal */
+ if (g_file_equal (file_a, file_b))
+ return 0;
+
+ /* directories always come first */
+ if (thunar_file_get_kind (a) == G_FILE_TYPE_DIRECTORY
+ && thunar_file_get_kind (b) != G_FILE_TYPE_DIRECTORY)
+ {
+ return -1;
}
+ else if (thunar_file_get_kind (a) != G_FILE_TYPE_DIRECTORY
+ && thunar_file_get_kind (b) == G_FILE_TYPE_DIRECTORY)
+ {
+ return 1;
+ }
- /* check if we have any infos */
- if (G_UNLIKELY (info_list == NULL))
- return;
+ /* ancestors come first */
+ if (g_file_has_prefix (file_b, file_a))
+ return -1;
+ else if (g_file_has_prefix (file_a, file_b))
+ return 1;
- /* determine the icon theme for the menu */
- icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (menu));
+ parent_a = g_file_get_parent (file_a);
+ parent_b = g_file_get_parent (file_b);
- /* add menu items for all infos */
- for (lp = info_list; lp != NULL; lp = lp->next)
+ if (g_file_equal (parent_a, parent_b))
{
- /* determine the info */
- info = lp->data;
+ g_object_unref (parent_a);
+ g_object_unref (parent_b);
- /* check if we have a regular file or a directory here */
- if (G_LIKELY (info->type == THUNAR_VFS_FILE_TYPE_REGULAR))
+ /* compare siblings by their display name */
+ return g_utf8_collate (thunar_file_get_display_name (a),
+ thunar_file_get_display_name (b));
+ }
+
+ /* again, ancestors come first */
+ if (g_file_has_prefix (file_b, parent_a))
+ {
+ g_object_unref (parent_a);
+ g_object_unref (parent_b);
+
+ return -1;
+ }
+ else if (g_file_has_prefix (file_a, parent_b))
+ {
+ g_object_unref (parent_a);
+ g_object_unref (parent_b);
+
+ return 1;
+ }
+
+ g_object_unref (parent_a);
+ g_object_unref (parent_b);
+
+ return 0;
+}
+
+
+
+static gboolean
+thunar_templates_action_files_ready (ThunarJob *job,
+ GList *files,
+ ThunarTemplatesAction *templates_action)
+{
+ ThunarIconFactory *icon_factory;
+ ThunarFile *file;
+ GdkPixbuf *icon;
+ GtkWidget *menu;
+ GtkWidget *parent_menu;
+ GtkWidget *submenu;
+ GtkWidget *image;
+ GtkWidget *item;
+ GList *lp;
+ GList *dirs = NULL;
+ GList *items = NULL;
+ GList *parent_menus = NULL;
+ GList *pp;
+ gchar *label;
+ gchar *dot;
+
+ /* determine the menu to add the items and submenus to */
+ menu = g_object_get_data (G_OBJECT (job), "menu");
+
+ /* do nothing if there is no menu */
+ if (menu == NULL)
+ return FALSE;
+
+ /* get the icon factory */
+ icon_factory = thunar_icon_factory_get_default ();
+
+ /* sort items so that directories come before files and ancestors come
+ * before descendants */
+ files = g_list_sort (files, (GCompareFunc) compare_files);
+
+ for (lp = g_list_first (files); lp != NULL; lp = lp->next)
+ {
+ file = lp->data;
+
+ /* determine the parent menu for this file/directory */
+ parent_menu = find_parent_menu (file, dirs, items);
+ parent_menu = parent_menu == NULL ? menu : parent_menu;
+
+ if (thunar_file_get_kind (file) == G_FILE_TYPE_DIRECTORY)
{
+ /* allocate a new submenu for the directory */
+ submenu = gtk_menu_new ();
+ exo_gtk_object_ref_sink (GTK_OBJECT (submenu));
+ gtk_menu_set_screen (GTK_MENU (submenu), gtk_widget_get_screen (menu));
+
+ /* allocate a new menu item for the directory */
+ item = gtk_image_menu_item_new_with_label (thunar_file_get_display_name (file));
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), submenu);
+
+ /* prepend the directory, its item and the parent menu it should
+ * later be added to to the respective lists */
+ dirs = g_list_prepend (dirs, file);
+ items = g_list_prepend (items, item);
+ parent_menus = g_list_prepend (parent_menus, parent_menu);
+ }
+ else
+ {
/* generate a label by stripping off the extension */
- label = g_strdup (info->display_name);
+ label = g_strdup (thunar_file_get_display_name (file));
dot = g_utf8_strrchr (label, -1, '.');
if (G_LIKELY (dot != NULL))
*dot = '\0';
/* allocate a new menu item */
item = gtk_image_menu_item_new_with_label (label);
- g_object_set_data_full (G_OBJECT (item), I_("thunar-vfs-info"), thunar_vfs_info_ref (info), (GDestroyNotify) thunar_vfs_info_unref);
- g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (item_activated), templates_action);
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+ g_object_set_data_full (G_OBJECT (item), I_("thunar-file"),
+ g_object_ref (file), g_object_unref);
+ g_signal_connect (item, "activate", G_CALLBACK (item_activated),
+ templates_action);
+ gtk_menu_shell_append (GTK_MENU_SHELL (parent_menu), item);
gtk_widget_show (item);
-
- /* lookup the icon for the mime type of that file */
- icon_name = thunar_vfs_mime_info_lookup_icon_name (info->mime_info, icon_theme);
-
- /* generate an image based on the named icon */
- image = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_MENU);
- gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
- gtk_widget_show (image);
-
- /* cleanup */
- g_free (label);
}
- else if (info->type == THUNAR_VFS_FILE_TYPE_DIRECTORY)
- {
- /* allocate a new submenu for the directory */
- submenu = gtk_menu_new ();
- exo_gtk_object_ref_sink (GTK_OBJECT (submenu));
- gtk_menu_set_screen (GTK_MENU (submenu), gtk_widget_get_screen (menu));
- /* fill the submenu from the folder contents */
- thunar_templates_action_fill_menu (templates_action, info->path, submenu);
+ /* determine the icon for this file/directory */
+ icon = thunar_icon_factory_load_file_icon (icon_factory, file,
+ THUNAR_FILE_ICON_STATE_DEFAULT,
+ GTK_ICON_SIZE_MENU);
- /* check if any items were added to the submenu */
- if (G_LIKELY (GTK_MENU_SHELL (submenu)->children != NULL))
- {
- /* hook up the submenu */
- item = gtk_image_menu_item_new_with_label (info->display_name);
- gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), submenu);
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
- gtk_widget_show (item);
+ /* allocate an image based on the icon */
+ image = gtk_image_new_from_pixbuf (icon);
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
+ gtk_widget_show (image);
- /* lookup the icon for the mime type of that file */
- icon_name = thunar_vfs_mime_info_lookup_icon_name (info->mime_info, icon_theme);
+ /* release the icon reference */
+ g_object_unref (icon);
+ }
- /* generate an image based on the named icon */
- image = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_MENU);
- gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
- gtk_widget_show (image);
- }
+ /* add all non-empty directory items to their parent menu */
+ for (lp = items, pp = parent_menus;
+ lp != NULL && pp != NULL;
+ lp = lp->next, pp = pp->next)
+ {
+ /* determine the submenu for this directory item */
+ submenu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (lp->data));
- /* cleanup */
- g_object_unref (G_OBJECT (submenu));
+ if (GTK_MENU_SHELL (submenu)->children == NULL)
+ {
+ /* the directory submenu is empty, destroy it */
+ gtk_widget_destroy (lp->data);
}
+ else
+ {
+ /* the directory has template files, so add it to its parent menu */
+ gtk_menu_shell_prepend (GTK_MENU_SHELL (pp->data), lp->data);
+ gtk_widget_show (lp->data);
+ }
}
- /* release the info list */
- thunar_vfs_info_list_free (info_list);
+ /* destroy lists */
+ g_list_free (dirs);
+ g_list_free (items);
+ g_list_free (parent_menus);
+
+ /* release the icon factory */
+ g_object_unref (icon_factory);
+
+ /* let the job destroy the file list */
+ return FALSE;
}
static void
-thunar_templates_action_menu_shown (GtkWidget *menu,
+thunar_templates_action_load_error (ThunarJob *job,
+ GError *error,
ThunarTemplatesAction *templates_action)
{
- ThunarVfsPath *templates_path;
- ThunarVfsPath *home_path;
- GtkWidget *image;
- GtkWidget *item;
- GList *children;
- gchar *templates_dir = NULL;
+ GtkWidget *item;
+ GtkWidget *menu;
+ _thunar_return_if_fail (THUNAR_IS_JOB (job));
+ _thunar_return_if_fail (error != NULL);
_thunar_return_if_fail (THUNAR_IS_TEMPLATES_ACTION (templates_action));
- _thunar_return_if_fail (GTK_IS_MENU_SHELL (menu));
+ _thunar_return_if_fail (templates_action->job == job);
- /* drop all existing children of the menu first */
- children = gtk_container_get_children (GTK_CONTAINER (menu));
- g_list_foreach (children, (GFunc) gtk_widget_destroy, NULL);
- g_list_free (children);
+ menu = g_object_get_data (G_OBJECT (job), "menu");
- /* determine the path to the ~/Templates folder */
- home_path = thunar_vfs_path_get_for_home ();
-
- templates_dir = g_strdup (g_get_user_special_dir (G_USER_DIRECTORY_TEMPLATES));
- if (G_UNLIKELY (templates_dir == NULL))
+ /* check if any items were added to the menu */
+ if (G_LIKELY (menu != NULL && GTK_MENU_SHELL (menu)->children == NULL))
{
- templates_dir = g_build_filename (G_DIR_SEPARATOR_S, xfce_get_homedir (),
- "Templates", NULL);
+ /* tell the user that no templates were found */
+ item = gtk_menu_item_new_with_label (error->message);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+ gtk_widget_set_sensitive (item, FALSE);
+ gtk_widget_show (item);
}
+}
- templates_path = thunar_vfs_path_new (templates_dir, NULL);
- if (G_UNLIKELY (templates_path == NULL))
- templates_path = thunar_vfs_path_relative (home_path,"Templates");
- g_free (templates_dir);
- thunar_vfs_path_unref (home_path);
+static void
+thunar_templates_action_load_finished (ThunarJob *job,
+ ThunarTemplatesAction *templates_action)
+{
+ GtkWidget *image;
+ GtkWidget *item;
+ GtkWidget *menu;
- if (!exo_str_is_equal (g_get_user_special_dir (G_USER_DIRECTORY_TEMPLATES),
- xfce_get_homedir ()))
- {
- /* fill the menu with files/folders from the ~/Templates folder */
- thunar_templates_action_fill_menu (templates_action, templates_path, menu);
- }
+ _thunar_return_if_fail (THUNAR_IS_JOB (job));
+ _thunar_return_if_fail (THUNAR_IS_TEMPLATES_ACTION (templates_action));
+ _thunar_return_if_fail (templates_action->job == job);
- /* check if any items were added to the menu */
- if (G_UNLIKELY (GTK_MENU_SHELL (menu)->children == NULL))
+ menu = g_object_get_data (G_OBJECT (job), "menu");
+ if (G_LIKELY (menu != NULL))
{
- /* tell the user that no templates were found */
- item = gtk_menu_item_new_with_label (_("No Templates installed"));
+ /* append a menu separator */
+ item = gtk_separator_menu_item_new ();
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
- gtk_widget_set_sensitive (item, FALSE);
gtk_widget_show (item);
+
+ /* add the "Empty File" item */
+ item = gtk_image_menu_item_new_with_mnemonic (_("_Empty File"));
+ g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (item_activated),
+ templates_action);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+ gtk_widget_show (item);
+
+ /* add the icon for the emtpy file item */
+ image = gtk_image_new_from_stock (GTK_STOCK_NEW, GTK_ICON_SIZE_MENU);
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
+ gtk_widget_show (image);
}
- /* append a menu separator */
- item = gtk_separator_menu_item_new ();
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
- gtk_widget_show (item);
+ g_signal_handlers_disconnect_matched (job, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL,
+ templates_action);
+ g_object_unref (job);
+}
- /* add the "Empty File" item */
- item = gtk_image_menu_item_new_with_mnemonic (_("_Empty File"));
- g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (item_activated), templates_action);
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
- gtk_widget_show (item);
- /* add the icon for the emtpy file item */
- image = gtk_image_new_from_stock (GTK_STOCK_NEW, GTK_ICON_SIZE_MENU);
- gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
- gtk_widget_show (image);
- /* cleanup */
- thunar_vfs_path_unref (templates_path);
+static void
+thunar_templates_action_menu_shown (GtkWidget *menu,
+ ThunarTemplatesAction *templates_action)
+{
+ GList *children;
+
+ _thunar_return_if_fail (THUNAR_IS_TEMPLATES_ACTION (templates_action));
+ _thunar_return_if_fail (GTK_IS_MENU_SHELL (menu));
+
+ /* drop all existing children of the menu first */
+ children = gtk_container_get_children (GTK_CONTAINER (menu));
+ g_list_foreach (children, (GFunc) gtk_widget_destroy, NULL);
+ g_list_free (children);
+
+ if (G_LIKELY (templates_action->job == NULL))
+ {
+ templates_action->job = thunar_misc_jobs_load_template_files (menu);
+ g_object_add_weak_pointer (G_OBJECT (templates_action->job),
+ (gpointer) &templates_action->job);
+
+ g_signal_connect (templates_action->job, "files-ready",
+ G_CALLBACK (thunar_templates_action_files_ready),
+ templates_action);
+ g_signal_connect (templates_action->job, "error",
+ G_CALLBACK (thunar_templates_action_load_error),
+ templates_action);
+ g_signal_connect (templates_action->job, "finished",
+ G_CALLBACK (thunar_templates_action_load_finished),
+ templates_action);
+ }
}
More information about the Xfce4-commits
mailing list