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
[email protected]
http://foo-projects.org/mailman/listinfo/xfce4-commits