static void reload_menu (GnomeControlCenter *shell) { GError *error; GMenuTreeDirectory *d; GMenuTreeIter *iter; GMenuTreeItemType next_type; error = NULL; if (!gmenu_tree_load_sync (shell->priv->menu_tree, &error)) { g_warning ("Could not load control center menu: %s", error->message); g_clear_error (&error); return; } d = gmenu_tree_get_root_directory (shell->priv->menu_tree); iter = gmenu_tree_directory_iter (d); while ((next_type = gmenu_tree_iter_next (iter)) != GMENU_TREE_ITEM_INVALID) { if (next_type == GMENU_TREE_ITEM_DIRECTORY) { GMenuTreeDirectory *subdir; const gchar *dir_name; GMenuTreeIter *sub_iter; GMenuTreeItemType sub_next_type; subdir = gmenu_tree_iter_get_directory (iter); dir_name = gmenu_tree_directory_get_name (subdir); maybe_add_category_view (shell, dir_name); /* add the items from this category to the model */ sub_iter = gmenu_tree_directory_iter (subdir); while ((sub_next_type = gmenu_tree_iter_next (sub_iter)) != GMENU_TREE_ITEM_INVALID) { if (sub_next_type == GMENU_TREE_ITEM_ENTRY) { GMenuTreeEntry *item = gmenu_tree_iter_get_entry (sub_iter); cc_shell_model_add_item (CC_SHELL_MODEL (shell->priv->store), dir_name, item); gmenu_tree_item_unref (item); } } gmenu_tree_iter_unref (sub_iter); gmenu_tree_item_unref (subdir); } } gmenu_tree_iter_unref (iter); }
static void get_flattened_entries_recurse (GMenuTreeDirectory *dir, GHashTable *entry_set) { GMenuTreeIter *iter = gmenu_tree_directory_iter (dir); GMenuTreeItemType next_type; while ((next_type = gmenu_tree_iter_next (iter)) != GMENU_TREE_ITEM_INVALID) { gpointer item = NULL; switch (next_type) { case GMENU_TREE_ITEM_ENTRY: { GMenuTreeEntry *entry; item = entry = gmenu_tree_iter_get_entry (iter); /* Key is owned by entry */ g_hash_table_replace (entry_set, (char*)gmenu_tree_entry_get_desktop_file_id (entry), gmenu_tree_item_ref (entry)); } break; case GMENU_TREE_ITEM_DIRECTORY: { item = gmenu_tree_iter_get_directory (iter); get_flattened_entries_recurse ((GMenuTreeDirectory*)item, entry_set); } break; default: break; } if (item != NULL) gmenu_tree_item_unref (item); } gmenu_tree_iter_unref (iter); }
int main() { auto tree=gmenu_tree_new(menu_name, GMENU_TREE_FLAGS_NONE); //no need flags, defaults is good enough { char lang[locale_size]; //here we get system locale string strcpy(lang,getenv("LANG")); char* country=0; //and parse it to 3 strings - lang, country, modifier char* modifier=0; //char* enc=0; //it could be useful somewhere else. let it be commented for(int i=0;lang[i];++i){ switch(lang[i]){ case '_': lang[i]=0; country=lang+i+1; break; case '@': lang[i]=0; modifier=lang+i+1; break; case '.': lang[i]=0; //enc=lang+i+1; break; } } { int loc_i=0; //current locale index if(*lang&&country&&modifier){ strcpy(locales[loc_i++]+4,(std::string("[")+lang+"_"+country+"@"+modifier+"]").c_str()); } if(*lang&&country){ strcpy(locales[loc_i++]+4,(std::string("[")+lang+"_"+country+"]").c_str()); } if(*lang&&modifier){ strcpy(locales[loc_i++]+4,(std::string("[")+lang+"@"+modifier+"]").c_str()); } if(*lang){ strcpy(locales[loc_i++]+4,(std::string("[")+lang+"]").c_str()); } locales[loc_i+1][0]=0; //barier to stop in case of buggy .desktop entry } } while(!gmenu_tree_load_sync(tree,NULL)){ //wait for load usleep(sync_wait_time); } qu.push(gmenu_tree_get_root_directory(tree)); //push root menu dir in queue while(!qu.empty()){ //while queue not empty, create menu for first dir auto& dir=qu.front(); { const char* name=gmenu_tree_directory_get_menu_id(dir); //menu id used as unique fvwm menu suffix printf("DestroyMenu \"FvwmMenu%s\"\n",name); printf("AddToMenu \"FvwmMenu%s\"\n",name); } auto it=gmenu_tree_directory_iter(dir); //iterator decltype(gmenu_tree_iter_next(it)) next_type; //iterator type while ((next_type=gmenu_tree_iter_next(it))!=GMENU_TREE_ITEM_INVALID){ switch (next_type){ case GMENU_TREE_ITEM_DIRECTORY:{ //add directory function popup and queue it auto cur=gmenu_tree_iter_get_directory(it); printf("+ \"%s\" Popup \"FvwmMenu%s\"\n", gmenu_tree_directory_get_name(cur), gmenu_tree_directory_get_menu_id(cur)); qu.push(cur); break; } case GMENU_TREE_ITEM_ENTRY:{ auto cur=gmenu_tree_iter_get_entry(it); auto inf=gmenu_tree_entry_get_app_info(cur); std::string exec=g_desktop_app_info_get_string(inf,"Exec"); //get exec command int index; while((index=exec.find('%'))!=-1){ //delete all % params exec.erase(index,2); } int loc_i=0; char* name=0; do{ //find localised name in standard specified order name=g_desktop_app_info_get_string(inf,locales[loc_i]); ++loc_i; }while(!name&&locales[loc_i][0]); if(name){ //if name not empty printf("+ \"%s\" Exec exec %s\n",name,exec.c_str()); //add menu entry } break; } case GMENU_TREE_ITEM_SEPARATOR:{ //add empty menu entry printf("+ \"\" Nop"); } default:{ //TODO: add other types if needed } } } gmenu_tree_iter_unref(it); //unref iterator (dunno why, but why not?) printf("\n"); //just for better readability qu.pop(); } return 0; }
static GtkWidget * populate_menu_from_directory (GtkWidget *menu, GMenuTreeDirectory *directory) { GList *children; gboolean add_separator; GMenuTreeIter *iter; GMenuTreeItemType next_type; children = gtk_container_get_children (GTK_CONTAINER (menu)); add_separator = (children != NULL); g_list_free (children); iter = gmenu_tree_directory_iter (directory); while ((next_type = gmenu_tree_iter_next (iter)) != GMENU_TREE_ITEM_INVALID) { gpointer item = NULL; if (add_separator || next_type == GMENU_TREE_ITEM_SEPARATOR) { add_menu_separator (menu); add_separator = FALSE; } switch (next_type) { case GMENU_TREE_ITEM_DIRECTORY: item = gmenu_tree_iter_get_directory (iter); create_submenu (menu, item, NULL); break; case GMENU_TREE_ITEM_ENTRY: item = gmenu_tree_iter_get_entry (iter); create_menuitem (menu, item, NULL); break; case GMENU_TREE_ITEM_SEPARATOR : /* already added */ break; case GMENU_TREE_ITEM_ALIAS: item = gmenu_tree_iter_get_alias (iter); create_menuitem_from_alias (menu, item); break; case GMENU_TREE_ITEM_HEADER: item = gmenu_tree_iter_get_header (iter); create_header (menu, item); break; default: break; } if (item) gmenu_tree_item_unref (item); } gmenu_tree_iter_unref (iter); return menu; }
/* * This function inherit from gnome-menus/util/test-menu-spec.c */ static void traverse_directory(GMenuTreeDirectory *dir, GtkWidget *parent) { GMenuTreeIter *iter = NULL; GtkWidget *dir_submenu = parent ? gtk_menu_new() : NULL; GtkWidget *entry_submenu = gtk_menu_new(); GIcon *icon = NULL; const char *text = NULL; GtkWidget *menuitem = NULL; iter = gmenu_tree_directory_iter(dir); while (TRUE) { gpointer item = NULL; switch (gmenu_tree_iter_next(iter)) { case GMENU_TREE_ITEM_INVALID: goto done; case GMENU_TREE_ITEM_ENTRY: item = gmenu_tree_iter_get_entry(iter); GDesktopAppInfo *appinfo = gmenu_tree_entry_get_app_info((GMenuTreeEntry *)item); icon = g_app_info_get_icon((GAppInfo *)appinfo); text = g_app_info_get_display_name((GAppInfo *)appinfo); menuitem = menu_item_new_with_icon_text(icon, text); gtk_menu_shell_append(GTK_MENU_SHELL(entry_submenu), menuitem); g_object_connect(G_OBJECT(menuitem), "signal::activate", G_CALLBACK(menu_item_activate), appinfo, NULL); break; case GMENU_TREE_ITEM_DIRECTORY: item = gmenu_tree_iter_get_directory(iter); icon = gmenu_tree_directory_get_icon((GMenuTreeDirectory *)item); text = gmenu_tree_directory_get_name((GMenuTreeDirectory *)item); menuitem = menu_item_new_with_icon_text(icon, text); gtk_menu_shell_append(dir_submenu ? GTK_MENU_SHELL(dir_submenu) : GTK_MENU_SHELL(popup), menuitem); traverse_directory(item, menuitem); break; } if (item) { gmenu_tree_item_unref(item); item = NULL; } continue; done: break; } if (parent) { if (dir_submenu) gtk_menu_item_set_submenu(GTK_MENU_ITEM(parent), dir_submenu); gtk_menu_item_set_submenu(GTK_MENU_ITEM(parent), entry_submenu); } if (iter) { gmenu_tree_iter_unref(iter); iter = NULL; } }