[Xfce4-commits] <xfdesktop:master> Fix template sub-menu loading code (Bug 10138)

Eric Koegel noreply at xfce.org
Tue Oct 29 16:56:01 CET 2013


Updating branch refs/heads/master
         to 11b1396b120e4719abf19ae37589a73f900b3ff7 (commit)
       from 82b385d0e243dc26429b8cc647630f18107ebe6a (commit)

commit 11b1396b120e4719abf19ae37589a73f900b3ff7
Author: Eric Koegel <eric.koegel at gmail.com>
Date:   Mon Oct 28 16:38:30 2013 +0300

    Fix template sub-menu loading code (Bug 10138)
    
    The old code recursively searched the XDG_TEMPLATES_DIR for files
    that can be used as templates. This patch changes it so that it
    only searches that directory and limits the number of items shown
    to the xfconf property max-template-files which is set to 16 to
    keep the sub-menu usable. It also only shows files which are not
    marked as hidden or backup to eliminate clutter.

 common/xfdesktop-common.h         |    1 +
 src/xfdesktop-file-icon-manager.c |  289 ++++++++++++++++++++-----------------
 2 files changed, 161 insertions(+), 129 deletions(-)

diff --git a/common/xfdesktop-common.h b/common/xfdesktop-common.h
index 3377461..e1b3878 100644
--- a/common/xfdesktop-common.h
+++ b/common/xfdesktop-common.h
@@ -61,6 +61,7 @@
 #define DESKTOP_ICONS_SHOW_TRASH             "/desktop-icons/file-icons/show-trash"
 #define DESKTOP_ICONS_SHOW_FILESYSTEM        "/desktop-icons/file-icons/show-filesystem"
 #define DESKTOP_ICONS_SHOW_REMOVABLE         "/desktop-icons/file-icons/show-removable"
+#define DESKTOP_ICONS_MAX_TEMPLATE_FILES     "/desktop-icons/file-icons/max-template-files"
 
 /**
  * File information namespaces queried for #GFileInfo objects.
diff --git a/src/xfdesktop-file-icon-manager.c b/src/xfdesktop-file-icon-manager.c
index 63d00c4..a4432cb 100644
--- a/src/xfdesktop-file-icon-manager.c
+++ b/src/xfdesktop-file-icon-manager.c
@@ -76,8 +76,8 @@
 #include <libxfce4util/libxfce4util.h>
 #include <libxfce4ui/libxfce4ui.h>
 
-#define SAVE_DELAY 7000
-#define BORDER     8
+#define SAVE_DELAY  7000
+#define BORDER         8
 
 typedef enum
 {
@@ -90,7 +90,8 @@ typedef enum
     PROP_SHOW_NETWORK_VOLUME,
     PROP_SHOW_DEVICE_VOLUME,
     PROP_SHOW_UNKNOWN_VOLUME,
-    PROP_SHOW_THUMBNAILS
+    PROP_SHOW_THUMBNAILS,
+    PROP_MAX_TEMPLATES,
 } XfdesktopFileIconManagerProp;
 
 struct _XfdesktopFileIconManagerPrivate
@@ -139,6 +140,8 @@ struct _XfdesktopFileIconManagerPrivate
 #endif
 
     XfdesktopThumbnailer *thumbnailer;
+
+    guint max_templates;
 };
 
 static void xfdesktop_file_icon_manager_set_property(GObject *object,
@@ -206,6 +209,11 @@ static void xfdesktop_file_icon_manager_update_image(GtkWidget *widget,
                                                      gchar *thumbfile,
                                                      XfdesktopFileIconManager *fmanager);
 
+static void
+xfdesktop_file_icon_manager_set_max_templates(XfdesktopFileIconManager *manager,
+                                              gint max_templates);
+
+
 G_DEFINE_TYPE_EXTENDED(XfdesktopFileIconManager,
                        xfdesktop_file_icon_manager,
                        G_TYPE_OBJECT, 0,
@@ -318,6 +326,12 @@ xfdesktop_file_icon_manager_class_init(XfdesktopFileIconManagerClass *klass)
                                                          "show-thumbnails",
                                                          TRUE,
                                                          XFDESKTOP_PARAM_FLAGS));
+    g_object_class_install_property(gobject_class, PROP_MAX_TEMPLATES,
+                                    g_param_spec_uint("max-templates",
+                                                      "max-templates",
+                                                      "max-templates",
+                                                      0, G_MAXUSHORT, 16,
+                                                      XFDESKTOP_PARAM_FLAGS));
 #undef XFDESKTOP_PARAM_FLAGS
 
     xfdesktop_app_info_quark = g_quark_from_static_string("xfdesktop-app-info-quark");
@@ -388,6 +402,11 @@ xfdesktop_file_icon_manager_set_property(GObject *object,
                                                             g_value_get_boolean(value));
             break;
 
+        case PROP_MAX_TEMPLATES:
+            xfdesktop_file_icon_manager_set_max_templates(fmanager,
+                                                          g_value_get_uint(value));
+            break;
+
         default:
             G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
     }
@@ -440,7 +459,11 @@ xfdesktop_file_icon_manager_get_property(GObject *object,
         case PROP_SHOW_THUMBNAILS:
             g_value_set_boolean(value, fmanager->priv->show_thumbnails);
             break;
-        
+
+        case PROP_MAX_TEMPLATES:
+            g_value_set_int(value, fmanager->priv->max_templates);
+            break;
+
         default:
             G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
     }
@@ -1166,24 +1189,24 @@ static gint
 compare_template_files(gconstpointer a,
                        gconstpointer b)
 {
-  GFileInfo *info_a = g_object_get_data(G_OBJECT(a), "info");
-  GFileInfo *info_b = g_object_get_data(G_OBJECT(b), "info");
-  GFileType type_a = g_file_info_get_file_type(info_a);
-  GFileType type_b = g_file_info_get_file_type(info_b);
-  const gchar* name_a = g_file_info_get_display_name(info_a);
-  const gchar* name_b = g_file_info_get_display_name(info_b);
+    GFileInfo *info_a = g_object_get_data(G_OBJECT(a), "info");
+    GFileInfo *info_b = g_object_get_data(G_OBJECT(b), "info");
+    GFileType type_a = g_file_info_get_file_type(info_a);
+    GFileType type_b = g_file_info_get_file_type(info_b);
+    const gchar* name_a = g_file_info_get_display_name(info_a);
+    const gchar* name_b = g_file_info_get_display_name(info_b);
 
-  if(!info_a || !info_b)
-    return 0;
+    if(!info_a || !info_b)
+        return 0;
 
-  if(type_a == type_b) {
-      return g_strcmp0(name_a, name_b);
-  } else {
-      if(type_a == G_FILE_TYPE_DIRECTORY)
-          return -1;
-      else
-          return 1;
-  }
+    if(type_a == type_b) {
+        return g_strcmp0(name_a, name_b);
+    } else {
+        if(type_a == G_FILE_TYPE_DIRECTORY)
+            return -1;
+        else
+            return 1;
+    }
 }
 
 static gboolean
@@ -1191,94 +1214,84 @@ xfdesktop_file_icon_menu_fill_template_menu(GtkWidget *menu,
                                             GFile *template_dir,
                                             XfdesktopFileIconManager *fmanager)
 {
-  GFileEnumerator *enumerator;
-  GtkWidget *item, *image, *submenu;
-  GFileInfo *info;
-  GFile *file;
-  GIcon *icon;
-  GList *files = NULL, *lp;
-  gchar *label, *dot;
-  gboolean have_templates = FALSE;
-  
-  g_return_val_if_fail(G_IS_FILE(template_dir), FALSE);
-
-  enumerator = g_file_enumerate_children(template_dir,
-                                         XFDESKTOP_FILE_INFO_NAMESPACE,
-                                         G_FILE_QUERY_INFO_NONE,
-                                         NULL, NULL);
-
-  if(enumerator) {
-      while((info = g_file_enumerator_next_file(enumerator, NULL, NULL))) {
-          file = g_file_get_child(template_dir, g_file_info_get_name(info));
-          g_object_set_data_full(G_OBJECT(file), "info", info, g_object_unref);
-          files = g_list_prepend(files, file);
-      }
+    GFileEnumerator *enumerator;
+    GtkWidget *item, *image;
+    GFileInfo *info;
+    GFile *file;
+    GIcon *icon;
+    GList *files = NULL, *lp;
+    gchar *label, *dot;
+    gboolean have_templates = FALSE;
+    guint items = 0;
+
+    g_return_val_if_fail(G_IS_FILE(template_dir), FALSE);
+
+    enumerator = g_file_enumerate_children(template_dir,
+                                           XFDESKTOP_FILE_INFO_NAMESPACE,
+                                           G_FILE_QUERY_INFO_NONE,
+                                           NULL, NULL);
+
+    if(enumerator) {
+        while((info = g_file_enumerator_next_file(enumerator, NULL, NULL))) {
+            file = g_file_get_child(template_dir, g_file_info_get_name(info));
+            g_object_set_data_full(G_OBJECT(file), "info", info, g_object_unref);
+            files = g_list_prepend(files, file);
+        }
 
-      g_object_unref(enumerator);
-  }
+        g_object_unref(enumerator);
+    }
 
-  files = g_list_sort(files, compare_template_files);
+    files = g_list_sort(files, compare_template_files);
 
-  for(lp = files; lp != NULL; lp = lp->next) {
-      file = lp->data;
-      info = g_object_get_data(G_OBJECT(file), "info");
+    for(lp = files; lp != NULL && items < fmanager->priv->max_templates; lp = lp->next) {
+        file = lp->data;
+        info = g_object_get_data(G_OBJECT(file), "info");
 
-      if(g_file_info_get_file_type(info) == G_FILE_TYPE_DIRECTORY) {
-          /* allocate a new submenu for the directory */
-          submenu = gtk_menu_new();
-          g_object_ref_sink(submenu);
-          gtk_menu_set_screen(GTK_MENU(submenu), gtk_widget_get_screen(menu));
+        /* Skip directories */
+        if(g_file_info_get_file_type(info) != G_FILE_TYPE_DIRECTORY) {
+            /* skip hidden & backup files */
+            if(g_file_info_get_is_hidden(info) || g_file_info_get_is_backup(info)) {
+                g_object_unref(file);
+                continue;
+            }
 
-          /* fill the submenu from the folder contents */
-          have_templates = xfdesktop_file_icon_menu_fill_template_menu(submenu, file, fmanager)
-                           || have_templates;
+            /* generate a label by stripping off the extension */
+            label = g_strdup(g_file_info_get_display_name(info));
+            dot = g_utf8_strrchr(label, -1, '.');
+            if(dot)
+                *dot = '\0';
 
-          /* check if any items were added to the submenu */
-          if (gtk_menu_item_get_submenu(GTK_MENU_ITEM(submenu)))
-            {
-              /* create a new menu item for the submenu */
-              item = gtk_image_menu_item_new_with_label (g_file_info_get_display_name(info));
-              icon = g_file_info_get_icon(info);
-              image = gtk_image_new_from_gicon(icon, GTK_ICON_SIZE_MENU);
-              gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
-              gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), submenu);
-              gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
-              gtk_widget_show (item);
-            }
+            /* allocate a new menu item */
+            item = gtk_image_menu_item_new_with_label(label);
 
-          /* cleanup */
-          g_object_unref (submenu);
-      } else {
-          /* generate a label by stripping off the extension */
-          label = g_strdup(g_file_info_get_display_name(info));
-          dot = g_utf8_strrchr(label, -1, '.');
-          if(dot)
-              *dot = '\0';
+            /* determine the icon to display */
+            icon = g_file_info_get_icon(info);
+            image = gtk_image_new_from_gicon(icon, GTK_ICON_SIZE_MENU);
+            gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
 
-          /* allocate a new menu item */
-          item = gtk_image_menu_item_new_with_label(label);
-          icon = g_file_info_get_icon(info);
-          image = gtk_image_new_from_gicon(icon, GTK_ICON_SIZE_MENU);
-          gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
-          gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
-          gtk_widget_show(item);
+            /* add the item to the menu */
+            gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+            gtk_widget_show(item);
 
-          g_object_set_data_full(G_OBJECT(item), "file", 
-                                 g_object_ref(file), g_object_unref);
+            g_object_set_data_full(G_OBJECT(item), "file",
+                                   g_object_ref(file), g_object_unref);
 
-          g_signal_connect (G_OBJECT(item), "activate",
-                            G_CALLBACK(xfdesktop_file_icon_template_item_activated),
-                            fmanager);
+            g_signal_connect(G_OBJECT(item), "activate",
+                             G_CALLBACK(xfdesktop_file_icon_template_item_activated),
+                             fmanager);
 
-          have_templates = TRUE;
-      }
+            have_templates = TRUE;
+            /* keep it under fmanager->priv->max_templates otherwise the menu
+             * could have tons of items and be unusable */
+            items++;
+        }
 
-      g_object_unref(file);
-  }
+        g_object_unref(file);
+    }
 
-  g_list_free(files);
+    g_list_free(files);
 
-  return have_templates;
+    return have_templates;
 }
 
 #ifdef HAVE_THUNARX
@@ -1454,45 +1467,49 @@ xfdesktop_file_icon_manager_populate_context_menu(XfceDesktop *desktop,
                     gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(mi), img);
                     gtk_widget_show(img);
                     
-                    /* create from template submenu */
+                    /* create from template submenu, 0 disables the sub-menu */
+                    if(fmanager->priv->max_templates > 0) {
+                        mi = gtk_menu_item_new_with_mnemonic(_("Create From _Template"));
+                        gtk_widget_show(mi);
+                        gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
 
-                    mi = gtk_menu_item_new_with_mnemonic(_("Create From _Template"));
-                    gtk_widget_show(mi);
-                    gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
-                    
-                    tmpl_menu = gtk_menu_new();
-                    gtk_menu_item_set_submenu(GTK_MENU_ITEM(mi), tmpl_menu);
-                    
-                    home_dir = g_file_new_for_path(xfce_get_homedir());
-                    templates_dir_path = g_get_user_special_dir(G_USER_DIRECTORY_TEMPLATES);
-                    if(templates_dir_path) {
-                        templates_dir = g_file_new_for_path(templates_dir_path);
-                    }
+                        tmpl_menu = gtk_menu_new();
+                        gtk_menu_item_set_submenu(GTK_MENU_ITEM(mi), tmpl_menu);
 
-                    if(templates_dir && !g_file_equal(home_dir, templates_dir))
-                    {
-                        xfdesktop_file_icon_menu_fill_template_menu(tmpl_menu,
-                                                                    templates_dir,
-                                                                    fmanager);
-                    }
+                        /* check if XDG_TEMPLATES_DIR="$HOME" and don't show
+                         * templates if so. */
+                        home_dir = g_file_new_for_path(xfce_get_homedir());
+                        templates_dir_path = g_get_user_special_dir(G_USER_DIRECTORY_TEMPLATES);
+                        if(templates_dir_path) {
+                            templates_dir = g_file_new_for_path(templates_dir_path);
+                        }
 
-                    if(templates_dir)
-                        g_object_unref(templates_dir);
-                    g_object_unref(home_dir);
+                        if(templates_dir && !g_file_equal(home_dir, templates_dir))
+                        {
+                            xfdesktop_file_icon_menu_fill_template_menu(tmpl_menu,
+                                                                        templates_dir,
+                                                                        fmanager);
+                        }
 
-                    img = gtk_image_new_from_stock(GTK_STOCK_NEW, GTK_ICON_SIZE_MENU);
-                    gtk_widget_show(img);
-                    mi = gtk_image_menu_item_new_with_mnemonic(_("_Empty File"));
-                    gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(mi), img);
-                    gtk_widget_show(mi);
-                    gtk_menu_shell_append(GTK_MENU_SHELL(tmpl_menu), mi);
-                    g_signal_connect(G_OBJECT(mi), "activate",
-                                     G_CALLBACK(xfdesktop_file_icon_template_item_activated),
-                                     fmanager);
-                    
-                    mi = gtk_separator_menu_item_new();
-                    gtk_widget_show(mi);
-                    gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
+                        if(templates_dir)
+                            g_object_unref(templates_dir);
+                        g_object_unref(home_dir);
+
+                        /* add the "Empty File" template option */
+                        img = gtk_image_new_from_stock(GTK_STOCK_NEW, GTK_ICON_SIZE_MENU);
+                        gtk_widget_show(img);
+                        mi = gtk_image_menu_item_new_with_mnemonic(_("_Empty File"));
+                        gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(mi), img);
+                        gtk_widget_show(mi);
+                        gtk_menu_shell_append(GTK_MENU_SHELL(tmpl_menu), mi);
+                        g_signal_connect(G_OBJECT(mi), "activate",
+                                         G_CALLBACK(xfdesktop_file_icon_template_item_activated),
+                                         fmanager);
+
+                        mi = gtk_separator_menu_item_new();
+                        gtk_widget_show(mi);
+                        gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
+                    }
                 }
             } else {
                 if(xfdesktop_file_utils_file_is_executable(info)) {
@@ -3604,6 +3621,8 @@ xfdesktop_file_icon_manager_new(GFile *folder,
                            G_OBJECT(fmanager), "show-unknown-volume");
     xfconf_g_property_bind(channel, DESKTOP_ICONS_SHOW_THUMBNAILS, G_TYPE_BOOLEAN,
                            G_OBJECT(fmanager), "show-thumbnails");
+    xfconf_g_property_bind(channel, DESKTOP_ICONS_MAX_TEMPLATE_FILES, G_TYPE_INT,
+                           G_OBJECT(fmanager), "max-templates");
 
     return XFDESKTOP_ICON_VIEW_MANAGER(fmanager);
 }
@@ -3707,6 +3726,18 @@ xfdesktop_file_icon_manager_set_show_thumbnails(XfdesktopFileIconManager *manage
 }
 
 static void
+xfdesktop_file_icon_manager_set_max_templates(XfdesktopFileIconManager *manager,
+                                              gint max_templates)
+{
+    g_return_if_fail(XFDESKTOP_IS_FILE_ICON_MANAGER(manager));
+
+    if(max_templates < 0 || max_templates > G_MAXUSHORT)
+        return;
+
+    manager->priv->max_templates = max_templates;
+}
+
+static void
 xfdesktop_file_icon_manager_set_show_special_file(XfdesktopFileIconManager *manager,
                                                   XfdesktopSpecialFileIconType type,
                                                   gboolean show_special_file)


More information about the Xfce4-commits mailing list