Index: src/menu-dentry.c =================================================================== RCS file: /var/cvs/xfce/xfce4/xfdesktop/src/menu-dentry.c,v retrieving revision 1.9 diff -u -u -r1.9 menu-dentry.c --- src/menu-dentry.c 26 Feb 2004 03:38:31 -0000 1.9 +++ src/menu-dentry.c 29 Feb 2004 01:57:58 -0000 @@ -54,6 +54,10 @@ #define PATH_MAX 4096 #endif +static void menu_dentry_legacy_init(); +static GList *menu_dentry_legacy_add_all(GList *menu_data, + const gchar *basepath,MenuPathType pathtype); + static const char *dentry_keywords [] = { "Name", "Comment", "Icon", "Hidden", "Categories", "OnlyShowIn", "Exec", "Terminal", @@ -62,8 +66,10 @@ static char *dentry_paths[] = { "/usr/local/share/applications/", "/usr/share/applications/", + "/opt/gnome/share/applications", + "/opt/gnome2/share/applications", "/usr/share/applications/kde/", - "/usr/share/gnome/apps/", + NULL }; /* these .desktop files _should_ have an OnlyShowIn key, but don't. i'm going @@ -77,7 +83,19 @@ "kappfinder", NULL }; - + +static const gchar *legacy_dirs[] = { + "/usr/share/gnome/apps", + "/usr/local/share/gnome/apps", + "/opt/gnome/share/apps", + "/usr/share/applnk", + "/usr/local/share/applnk", + NULL +}; + +static GHashTable *dir_to_cat = NULL; + + /* we don't want most command-line parameters if they're given. */ static gchar * sanitise_dentry_cmd(gchar *cmd) { @@ -158,6 +176,30 @@ return menu_data; } +static gchar * +build_path(const gchar *basepath, const gchar *path, const gchar *name) +{ + gchar *newpath = NULL; + + if(basepath) { + gboolean free_bp = FALSE; + + if(basepath[strlen(basepath)-1] == '/') { + basepath = g_strndup(basepath, strlen(basepath)-1); + free_bp = TRUE; + } + if(*path == '/') + newpath = g_strdup_printf ("%s%s/%s", basepath, path, name); + else + newpath = g_strdup_printf ("%s/%s/%s", basepath, path, name); + if(free_bp) + g_free((char *)basepath); + } else + newpath = g_strdup_printf ("%s/%s", path, name); + + return newpath; +} + static MenuItem * parse_dentry_attr (MenuItemType type, XfceDesktopEntry *de, gchar const *basepath, gchar const *path) @@ -166,6 +208,7 @@ gchar *name = NULL; gchar *cmd = NULL; gchar *ifile = NULL; + gchar *p; int term; gint i; @@ -197,25 +240,15 @@ g_free(tmp); } + while((p=strchr(name, '/'))) + *p = ' '; + term = 0; xfce_desktop_entry_get_int (de, "Terminal", &term); xfce_desktop_entry_get_string (de, "Icon", TRUE, &ifile); - if(basepath) { - gboolean free_bp = FALSE; - if(basepath[strlen(basepath)-1] == '/') { - basepath = g_strndup(basepath, strlen(basepath)-1); - free_bp = TRUE; - } - if(*path == '/') - mi->path = g_strdup_printf ("%s%s/%s", basepath, path, name); - else - mi->path = g_strdup_printf ("%s/%s/%s", basepath, path, name); - if(free_bp) - g_free((char *)basepath); - } else - mi->path = g_strdup_printf ("%s/%s", path, name); + mi->path = build_path(basepath, path, name); if(g_hash_table_lookup(menu_entry_hash, mi->path)) { g_free(mi->path); @@ -247,8 +280,8 @@ } static GList * -parse_dentry (XfceDesktopEntry *de, GList *menu_data, const char *basepath, - MenuPathType pathtype) +parse_dentry (XfceDesktopEntry *de, GList *menu_data, const gchar *basepath, + MenuPathType pathtype, gboolean is_legacy, const gchar *extra_cat) { gchar *categories, *hidden; gchar **catv; @@ -264,6 +297,7 @@ hidden = NULL; newpaths = NULL; onlyshowin = NULL; + xfce_desktop_entry_get_string (de, "OnlyShowIn", FALSE, &onlyshowin); if (onlyshowin) { tmp = g_strdup_printf (";%s;", onlyshowin); @@ -272,10 +306,8 @@ tmp = NULL; } - if (onlyshowin && !g_strrstr (onlyshowin, ";XFCE;")) { - g_free (onlyshowin); - return menu_data; - } + if (onlyshowin && !g_strrstr (onlyshowin, ";XFCE;")) + goto cleanup; if (onlyshowin) { g_free (onlyshowin); @@ -283,30 +315,34 @@ } xfce_desktop_entry_get_string(de, "Hidden", FALSE, &hidden); - if(hidden && !g_strcasecmp(hidden, "true")) { - g_free(hidden); - return menu_data; - } - if (hidden) - g_free(hidden); + if(hidden && !g_strcasecmp(hidden, "true")) + goto cleanup; xfce_desktop_entry_get_string (de, "Categories", TRUE, &categories); - /* hack: leave out items that look like they are KDE control panels */ - if(categories && strstr(categories, ";X-KDE-")) { - g_free(categories); - return menu_data; - } - - if(pathtype==MPATH_SIMPLE || pathtype==MPATH_SIMPLE_UNIQUE) - newpaths = menuspec_get_path_simple(categories); - else if(pathtype==MPATH_MULTI || pathtype==MPATH_MULTI_UNIQUE) - newpaths = menuspec_get_path_multilevel(categories); - else - return NULL; - - if(!newpaths) - return NULL; + if(categories) { + /* hack: leave out items that look like they are KDE control panels */ + if(strstr(categories, ";X-KDE-")) + goto cleanup; + + if(pathtype==MPATH_SIMPLE || pathtype==MPATH_SIMPLE_UNIQUE) + newpaths = menuspec_get_path_simple(categories); + else if(pathtype==MPATH_MULTI || pathtype==MPATH_MULTI_UNIQUE) + newpaths = menuspec_get_path_multilevel(categories); + + if(!newpaths) + goto cleanup; + } else if(is_legacy) { + newpaths = g_ptr_array_new(); + if(pathtype==MPATH_SIMPLE || pathtype==MPATH_SIMPLE_UNIQUE) { + gchar *p, *pathtmp = g_strdup(extra_cat); + if((p=strstr(pathtmp+1, "/"))) + *p = 0; + g_ptr_array_add(newpaths, pathtmp); + } else if(pathtype==MPATH_MULTI || pathtype==MPATH_MULTI_UNIQUE) + g_ptr_array_add(newpaths, g_strdup(extra_cat)); + } else + goto cleanup; if(pathtype == MPATH_SIMPLE_UNIQUE) { /* grab first of the most general */ @@ -336,6 +372,14 @@ } } + cleanup: + + if(newpaths) + menuspec_path_free(newpaths); + if(onlyshowin) + g_free(onlyshowin); + if(hidden) + g_free(hidden); if(categories) g_free(categories); @@ -350,7 +394,7 @@ dentry = xfce_desktop_entry_new (filename, dentry_keywords, G_N_ELEMENTS (dentry_keywords)); xfce_desktop_entry_parse (dentry); - menu_data = parse_dentry (dentry, menu_data, basepath, pathtype); + menu_data = parse_dentry (dentry, menu_data, basepath, pathtype, FALSE, NULL); g_object_unref (G_OBJECT (dentry)); return menu_data; } @@ -370,7 +414,7 @@ menuspec_parse_categories(catfile); g_free(catfile); - for(i = 0; i < G_N_ELEMENTS (dentry_paths); i++) { + for(i = 0; dentry_paths[i]; i++) { pathd = dentry_paths[i]; d = g_dir_open (pathd, 0, NULL); @@ -404,6 +448,9 @@ g_dir_close(d); } g_free(kde_dentry_path); + + menu_dentry_legacy_init(); + menu_data = menu_dentry_legacy_add_all(menu_data, basepath, pathtype); menuspec_free(); @@ -439,3 +486,118 @@ return (modified); } + + +/******************************************************************************* + * legacy dir support. bleh. + ******************************************************************************/ + +static GList * +menu_dentry_legacy_parse_dentry_file(const gchar *filename, GList *menu_data, + const gchar *catdir, const gchar *basepath, MenuPathType pathtype) +{ + XfceDesktopEntry *dentry; + gchar *category, *precat, *p; + + /* FIXME: do this recursively for multiple dirs */ + if((p=strchr(catdir, '/'))) + *p = 0; + precat = g_hash_table_lookup(dir_to_cat, catdir); + if(!precat) + precat = (gchar *)catdir; + + category = (gchar *)menuspec_cat_to_displayname(precat); + if(!category) + category = precat; + + dentry = xfce_desktop_entry_new (filename, dentry_keywords, + G_N_ELEMENTS(dentry_keywords)); + xfce_desktop_entry_parse(dentry); + menu_data = parse_dentry(dentry, menu_data, basepath, pathtype, TRUE, category); + g_object_unref(G_OBJECT(dentry)); + + return menu_data; +} +static GList * +menu_dentry_legacy_process_dir(GList *menu_data, const gchar *basedir, + const gchar *catdir, const gchar *basepath, MenuPathType pathtype) +{ + GDir *dir = NULL; + gchar const *file = NULL; + gchar curdir[PATH_MAX], newcatdir[PATH_MAX], fullpath[PATH_MAX]; + + + if(!catdir) + strncpy(curdir, basedir, PATH_MAX); + else + g_snprintf(curdir, PATH_MAX, "%s/%s", basedir, catdir); + + if(!(dir = g_dir_open(curdir, 0, NULL))) + goto cleanup; + + while((file = g_dir_read_name(dir))) { + g_snprintf(fullpath, PATH_MAX, "%s/%s", curdir, file); + if(g_file_test(fullpath, G_FILE_TEST_IS_DIR)) { + if(*file == '.' || strstr(file, "Settings")) /* FIXME: this is questionable */ + continue; + if(catdir) + g_snprintf(newcatdir, PATH_MAX, "%s/%s", catdir, file); + else + strncpy(newcatdir, file, PATH_MAX); + menu_data = menu_dentry_legacy_process_dir(menu_data, basedir, + newcatdir, basepath, pathtype); + } else if(catdir && g_str_has_suffix(file, ".desktop")) { + menu_data = menu_dentry_legacy_parse_dentry_file(fullpath, + menu_data, catdir, basepath, pathtype); + } + } + + cleanup: + + if(dir) + g_dir_close(dir); + + return menu_data; +} + +static GList * +menu_dentry_legacy_add_all(GList *menu_data, const gchar *basepath, + MenuPathType pathtype) +{ + gint i; + const gchar *kdedir = g_getenv("KDEDIR"); + gchar extradir[PATH_MAX]; + + for(i=0; legacy_dirs[i]; i++) + menu_data = menu_dentry_legacy_process_dir(menu_data, legacy_dirs[i], + NULL, basepath, pathtype); + + if(kdedir && strcmp(kdedir, "/usr")) { + g_snprintf(extradir, PATH_MAX, "%s/share/applnk", kdedir); + menu_data = menu_dentry_legacy_process_dir(menu_data, extradir, NULL, + basepath, pathtype); + } + + return menu_data; +} + +static void +menu_dentry_legacy_init() +{ + static gboolean is_inited = FALSE; + + if(is_inited) + return; + + if(dir_to_cat) + g_hash_table_destroy(dir_to_cat); + dir_to_cat = g_hash_table_new(g_str_hash, g_str_equal); + g_hash_table_insert(dir_to_cat, "Internet", "Network"); + g_hash_table_insert(dir_to_cat, "OpenOffice.org", "Office"); + g_hash_table_insert(dir_to_cat, "Utilities", "Utility"); + g_hash_table_insert(dir_to_cat, "Toys", "Utility"); + g_hash_table_insert(dir_to_cat, "Multimedia", "AudioVideo"); + g_hash_table_insert(dir_to_cat, "Applications", "Core"); + + is_inited = TRUE; +} Index: src/menuspec.c =================================================================== RCS file: /var/cvs/xfce/xfce4/xfdesktop/src/menuspec.c,v retrieving revision 1.2 diff -u -u -r1.2 menuspec.c --- src/menuspec.c 16 Feb 2004 06:41:49 -0000 1.2 +++ src/menuspec.c 29 Feb 2004 01:57:58 -0000 @@ -471,7 +471,13 @@ return paths; } -G_INLINE_FUNC void +G_CONST_RETURN gchar * +menuspec_cat_to_displayname(const gchar *category) +{ + return g_hash_table_lookup(cat_to_displayname, category); +} + +void menuspec_path_free(GPtrArray *paths) { if(!paths) Index: src/menuspec.h =================================================================== RCS file: /var/cvs/xfce/xfce4/xfdesktop/src/menuspec.h,v retrieving revision 1.1 diff -u -u -r1.1 menuspec.h --- src/menuspec.h 10 Feb 2004 03:36:13 -0000 1.1 +++ src/menuspec.h 29 Feb 2004 01:57:58 -0000 @@ -71,6 +71,8 @@ */ GPtrArray *menuspec_get_path_multilevel(const gchar *categories); +G_CONST_RETURN gchar *menuspec_cat_to_displayname(const gchar *category); + /** * @brief Frees menu path lists. * @@ -80,6 +82,6 @@ * @param paths A GPtrArray obtained from either menuspec_get_path_simple() or * menuspec_get_path_multilevel(). */ -void menuspec_path_free(GPtrArray *paths); +G_INLINE_FUNC void menuspec_path_free(GPtrArray *paths); #endif /* ifdef __MENUSPEC_H__ */