Author: jannis
Date: 2007-02-13 23:59:11 +0000 (Tue, 13 Feb 2007)
New Revision: 24973

Modified:
   libfrap/trunk/libfrap/menu/
   libfrap/trunk/libfrap/menu/ChangeLog
   libfrap/trunk/libfrap/menu/frap-menu.c
   libfrap/trunk/libfrap/menu/tdb/
   libfrap/trunk/libfrap/menu/tests/
   libfrap/trunk/libfrap/menu/tests/data/
Log:
        * frap-menu.c: Add frap_menu_collect_files() and 
          frap_menu_collect_files_from_path() in order to collect potential
          desktop entry filenames for each menu prior to resolving the menu
          items. In these methods, desktop name collisions are handled by using
          a (desktop-file id => absolute filename) mapping. After all filenames
          are collected, we can simply iterate over them in order to resolve
          the menu items. All in all, this mechanism adds some memory overhead
          but reduces filesystem I/O at the same time.
        * ./, tdb/, tests/, tests/data/: Add better svn:ignore properties for
          the subdirectories.


Property changes on: libfrap/trunk/libfrap/menu
___________________________________________________________________
Name: svn:ignore
   - .deps
.libs
Makefile
Makefile.in
.*.swp


   + .deps
.libs
Makefile
Makefile.in
.*.swp
*.tmp


Modified: libfrap/trunk/libfrap/menu/ChangeLog
===================================================================
--- libfrap/trunk/libfrap/menu/ChangeLog        2007-02-13 20:26:36 UTC (rev 
24972)
+++ libfrap/trunk/libfrap/menu/ChangeLog        2007-02-13 23:59:11 UTC (rev 
24973)
@@ -1,3 +1,16 @@
+2007-02-13     Jannis Pohlmann <[EMAIL PROTECTED]>
+
+       * frap-menu.c: Add frap_menu_collect_files() and 
+         frap_menu_collect_files_from_path() in order to collect potential
+         desktop entry filenames for each menu prior to resolving the menu
+         items. In these methods, desktop name collisions are handled by using
+         a (desktop-file id => absolute filename) mapping. After all filenames
+         are collected, we can simply iterate over them in order to resolve
+         the menu items. All in all, this mechanism adds some memory overhead
+         but reduces filesystem I/O at the same time.
+       * ./, tdb/, tests/, tests/data/: Add better svn:ignore properties for
+         the subdirectories.
+
 2007-02-08     Jannis Pohlmann <[EMAIL PROTECTED]>
 
        * frap-menu-item.c: Must have accidently reverted this file before

Modified: libfrap/trunk/libfrap/menu/frap-menu.c
===================================================================
--- libfrap/trunk/libfrap/menu/frap-menu.c      2007-02-13 20:26:36 UTC (rev 
24972)
+++ libfrap/trunk/libfrap/menu/frap-menu.c      2007-02-13 23:59:11 UTC (rev 
24973)
@@ -178,13 +178,21 @@
 
 } FrapMenuParseContext;
 
+typedef struct _FrapMenuPair
+{
+  gpointer first;
+  gpointer second;
+} FrapMenuPair;
 
-
 typedef struct _FrapMenuParseInfo
 {
   /* Directory names */
-  GSList           *directory_names;
+  GSList     *directory_names;
 
+  /* Desktop entry files items (desktop-file id => absolute filename) used for
+   * resolving the menu items */
+  GHashTable *files;
+
 } FrapMenuParseInfo;
 
 
@@ -274,14 +282,17 @@
                                                                             
FrapMenuRules         *rules);
 static void               frap_menu_add_move                               
(FrapMenu              *menu,
                                                                             
FrapMenuMove          *move);
+static void               frap_menu_collect_files                          
(FrapMenu              *menu);
+static void               frap_menu_collect_files_from_path                
(FrapMenu              *menu,
+                                                                            
const gchar           *path,
+                                                                            
const gchar           *id_prefix);
 static void               frap_menu_resolve_items                          
(FrapMenu              *menu,
                                                                             
gboolean               only_unallocated);
 static void               frap_menu_resolve_items_by_rule                  
(FrapMenu              *menu,
                                                                             
FrapMenuStandardRules *rule);
-static void               frap_menu_resolve_items_from_path_by_rule        
(FrapMenu              *menu,
-                                                                            
FrapMenuStandardRules *rule,
-                                                                            
const gchar           *path,
-                                                                            
const gchar           *id_prefix);
+static void               frap_menu_resolve_item_by_rule                   
(const gchar           *desktop_id,
+                                                                            
const gchar           *filename,
+                                                                            
FrapMenuPair          *data);
 static void               frap_menu_resolve_deleted                        
(FrapMenu              *menu);
 static void               frap_menu_resolve_moves                          
(FrapMenu              *menu);
 
@@ -490,6 +501,7 @@
 
   menu->priv->parse_info = g_new (FrapMenuParseInfo, 1);
   menu->priv->parse_info->directory_names = NULL;
+  menu->priv->parse_info->files = g_hash_table_new_full (g_str_hash, 
g_str_equal, g_free, g_free);
 }
 
 
@@ -1078,6 +1090,10 @@
   frap_menu_resolve_directory (menu);
   frap_menu_resolve_moves (menu);
 
+  /* Collect all potential menu item filenames */
+  frap_menu_collect_files (menu);
+
+  /* Resolve menu items in two steps to handle <OnlyUnallocated/> properly */
   frap_menu_resolve_items (menu, FALSE);
   frap_menu_resolve_items (menu, TRUE);
   
@@ -1474,6 +1490,12 @@
   g_slist_foreach (parse_info->directory_names, (GFunc) g_free, NULL);
   g_slist_free (parse_info->directory_names);
 
+#if GLIB_CHECK_VERSION(2,12,0)
+  g_hash_table_unref (parse_info->files);
+#else
+  g_hash_table_destroy (parse_info->files);
+#endif
+
   /* Free parse info */
   g_free (parse_info);
 }
@@ -2206,7 +2228,7 @@
             }
           
           /* Free the absolute path */
-          g_free (absolute_path);
+         g_free (absolute_path);
 
           /* Cancel search if we found the menu directory file */
           if (G_UNLIKELY (found))
@@ -2223,6 +2245,97 @@
 
 
 static void
+frap_menu_collect_files (FrapMenu *menu)
+{
+  GSList *iter;
+
+  g_return_if_fail (FRAP_IS_MENU (menu));
+
+  /* Collect desktop entry filenames */
+  for (iter = g_slist_reverse (frap_menu_get_app_dirs (menu)); iter != NULL; 
iter = g_slist_next (iter))
+    frap_menu_collect_files_from_path (menu, iter->data, NULL);
+
+  /* Collect filenames for submenus */
+  for (iter = menu->priv->submenus; iter != NULL; iter = g_slist_next (iter))
+    frap_menu_collect_files (FRAP_MENU (iter->data));
+}
+
+
+
+static void
+frap_menu_collect_files_from_path (FrapMenu    *menu,
+                                   const gchar *path,
+                                   const gchar *id_prefix)
+{
+  GDir        *dir;
+  const gchar *filename;
+  gchar       *absolute_path;
+  gchar       *new_id_prefix;
+  gchar       *desktop_id;
+
+  g_return_if_fail (FRAP_IS_MENU (menu));
+  g_return_if_fail (path != NULL && g_path_is_absolute (path));
+
+  /* Skip directory if it doesn't exist */
+  if (G_UNLIKELY (!g_file_test (path, G_FILE_TEST_EXISTS | 
G_FILE_TEST_IS_DIR)))
+    return;
+
+  /* Open directory for reading */
+  dir = g_dir_open (path, 0, NULL);
+
+  /* Abort if directory cannot be opened */
+  if (G_UNLIKELY (dir == NULL))
+    return;
+
+  /* Read file by file */
+  while ((filename = g_dir_read_name (dir)) != NULL)
+    {
+      /* Build absolute path */
+      absolute_path = g_build_filename (path, filename, NULL);
+
+      /* Treat files and directories differently */
+      if (g_file_test (absolute_path, G_FILE_TEST_IS_DIR))
+        {
+          /* Create new desktop-file id prefix */
+          if (G_LIKELY (id_prefix == NULL))
+            new_id_prefix = g_strdup (filename);
+          else
+            new_id_prefix = g_strjoin ("-", id_prefix, filename, NULL);
+
+          /* Collect files in the directory */
+          frap_menu_collect_files_from_path (menu, absolute_path, 
new_id_prefix);
+
+          /* Free id prefix */
+          g_free (new_id_prefix);
+        }
+      else
+        {
+          /* Skip all filenames which do not end with .desktop */
+          if (G_LIKELY (g_str_has_suffix (filename, ".desktop")))
+            {
+              /* Create desktop-file id */
+              if (G_LIKELY (id_prefix == NULL))
+                desktop_id = g_strdup (filename);
+              else
+                desktop_id = g_strjoin ("-", id_prefix, filename, NULL);
+
+              /* Insert into the files hash table if the desktop-file id does 
not exist in there yet */
+              if (G_LIKELY (g_hash_table_lookup 
(menu->priv->parse_info->files, desktop_id) == NULL))
+                g_hash_table_insert (menu->priv->parse_info->files, g_strdup 
(desktop_id), g_strdup (absolute_path));
+
+              /* Free desktop-file id */
+              g_free (desktop_id);
+            }
+        }
+
+      /* Free absolute path */
+      g_free (absolute_path);
+    }
+}
+
+
+
+static void
 frap_menu_resolve_items (FrapMenu *menu,
                          gboolean  only_unallocated)
 {
@@ -2271,110 +2384,52 @@
 frap_menu_resolve_items_by_rule (FrapMenu              *menu,
                                  FrapMenuStandardRules *rule)
 {
-  GSList *iter;
+  FrapMenuPair pair;
+  GSList      *iter;
 
   g_return_if_fail (FRAP_IS_MENU (menu));
   g_return_if_fail (FRAP_IS_MENU_STANDARD_RULES (rule));
 
-  /* Iterate over all application directories */
-  for (iter = frap_menu_get_app_dirs (menu); iter != NULL; iter = g_slist_next 
(iter))
-    {
-      /* Resolve items in the current directory */
-      frap_menu_resolve_items_from_path_by_rule (menu, rule, iter->data, NULL);
-    }
+  /* Store menu and rule pointer in the pair */
+  pair.first = menu;
+  pair.second = rule;
+
+  /* Try to insert each of the collected desktop entry filenames into the menu 
*/
+  g_hash_table_foreach (menu->priv->parse_info->files, (GHFunc) 
frap_menu_resolve_item_by_rule, &pair);
 }
 
 
 
-static void 
-frap_menu_resolve_items_from_path_by_rule (FrapMenu              *menu,
-                                           FrapMenuStandardRules *rule,
-                                           const gchar           *path,
-                                           const gchar           *id_prefix)
+static void
+frap_menu_resolve_item_by_rule (const gchar  *desktop_id,
+                                const gchar  *filename,
+                                FrapMenuPair *data)
 {
-  FrapMenuItem *item;
-  GDir         *dir;
-  const gchar  *filename;
-  gchar        *absolute_path;
-  gchar        *new_id_prefix;
-  gchar        *desktop_id;
+  FrapMenu              *menu;
+  FrapMenuStandardRules *rule;
+  FrapMenuItem          *item;
 
-  g_return_if_fail (FRAP_IS_MENU (menu));
-  g_return_if_fail (path != NULL);
-  g_return_if_fail (g_path_is_absolute (path));
+  g_return_if_fail (FRAP_IS_MENU (data->first));
+  g_return_if_fail (FRAP_IS_MENU_STANDARD_RULES (data->second));
 
-  /* Skip directory if it doesn't exist */
-  if (!g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))
-    return;
+  /* Restore menu and rule from the data pair */
+  menu = FRAP_MENU (data->first);
+  rule = FRAP_MENU_STANDARD_RULES (data->second);
 
-  /* Open directory for reading */
-  dir = g_dir_open (path, 0, NULL);
+  /* Try to load the menu item from the cache */
+  item = frap_menu_item_cache_lookup (menu->priv->cache, filename, desktop_id);
 
-  /* Abort if directory cannot be openend */
-  if (G_UNLIKELY (dir == NULL))
-    return;
-
-  /* Read file by file */
-  while ((filename = g_dir_read_name (dir)) != NULL)
+  if (G_LIKELY (item != NULL))
     {
-      /* Build absolute filename */
-      absolute_path = g_build_filename (path, filename, NULL);
-
-      /* Determine if we have a file or a directory */
-      if (g_file_test (absolute_path, G_FILE_TEST_IS_DIR))
+      /* Only include item if menu not only includes unallocated items
+       * or if the item is not allocated yet */
+      if (!menu->priv->only_unallocated || (frap_menu_item_get_allocated 
(item) < 1))
         {
-          /* Create new desktop file id prefix */
-          if (G_LIKELY (id_prefix == NULL))
-            new_id_prefix = g_strdup (filename);
-          else
-            new_id_prefix = g_strjoin ("-", id_prefix, filename, NULL);
-
-          /* Resolve items in that directory */
-          frap_menu_resolve_items_from_path_by_rule (menu, rule, 
absolute_path, new_id_prefix);
-
-          /* Free the prefix */
-          g_free (new_id_prefix);
+          /* Add item to the pool if it matches the include rule */
+          if (G_LIKELY (frap_menu_standard_rules_get_include (rule) && 
frap_menu_rules_match (FRAP_MENU_RULES (rule), item)))
+            frap_menu_item_pool_insert (menu->priv->pool, item);
         }
-      else 
-        {
-          /* Skip all filenames which do not end with .desktop */
-          if (G_LIKELY (g_str_has_suffix (filename, ".desktop")))
-            {
-              /* Create desktop file id */
-              if (G_LIKELY (id_prefix == NULL))
-                desktop_id = g_strdup (filename);
-              else
-                desktop_id = g_strjoin ("-", id_prefix, filename, NULL);
-
-              /* Try to load the menu item from the cache */
-              item = frap_menu_item_cache_lookup (menu->priv->cache, 
absolute_path, desktop_id);
-
-              if (G_LIKELY (item != NULL))
-                {
-                  /* Only include item if menu not only includes unallocated 
items
-                   * or if the item is not allocated yet */
-                  if (!menu->priv->only_unallocated || 
(frap_menu_item_get_allocated (item) < 1))
-                    {
-                      /* Add item to the pool if it matches the include rule */
-                      if (G_LIKELY (frap_menu_standard_rules_get_include 
(rule) 
-                                    && frap_menu_rules_match (FRAP_MENU_RULES 
(rule), item)))
-                        {
-                          frap_menu_item_pool_insert (menu->priv->pool, item);
-                        }
-                    }
-                }
-
-              /* Free desktop id */
-              g_free (desktop_id);
-            }
-        }
-
-      /* Free the absolute path */
-      g_free (absolute_path);
     }
-
-  /* Close directory */
-  g_dir_close (dir);
 }
 
 


Property changes on: libfrap/trunk/libfrap/menu/tdb
___________________________________________________________________
Name: svn:ignore
   + Makefile
Makefile.in
*.tmp
.*.swp
.libs
.deps
tdbconfig.h



Property changes on: libfrap/trunk/libfrap/menu/tests
___________________________________________________________________
Name: svn:ignore
   + Makefile
Makefile.in
*.bak
*.tmp
.libs
.deps
.*.swp



Property changes on: libfrap/trunk/libfrap/menu/tests/data
___________________________________________________________________
Name: svn:ignore
   + Makefile
Makefile.in


_______________________________________________
Xfce4-commits mailing list
Xfce4-commits@xfce.org
http://foo-projects.org/mailman/listinfo/xfce4-commits

Reply via email to