예제 #1
0
파일: parser.c 프로젝트: reiver-dev/menugen
static int walk_menu(GarconMenuElement *element, struct menugen_parser *self, menugen_parser_cb callback, void *arg) {
    void *nextarg = NULL;
    int children = 0;

    if (ISMENU(element)) {

        GarconMenu* menu = (GarconMenu *)element;
        GarconMenuDirectory* directory = garcon_menu_get_directory(menu);
        GList *elements = garcon_menu_get_elements(menu);

        int visible = directory != NULL && garcon_menu_directory_get_visible(directory);
        int haschildred = elements != NULL && elements->data != NULL;

        if (visible && haschildred) {
            struct menu_item item = {
                .type = MENU,
                .name = garcon_menu_directory_get_name(directory),
                .icon = garcon_menu_directory_get_icon_name(directory)
            };
            nextarg = callback(&item, arg);
        }

        if (!nextarg)
            nextarg = arg;

        for (GList *el = elements; el != NULL; el = el->next) {
            GarconMenuElement *me = el->data;
            children += walk_menu(me, self, callback, nextarg);
        }

        g_list_free(elements);

        if (visible && haschildred) {
            struct menu_item item = {
                .type = MENUEND,
                .children = children,
                .name = garcon_menu_directory_get_name(directory),
                .icon = garcon_menu_directory_get_icon_name(directory),
                .prevarg = nextarg
            };
            callback(&item, arg);
        }

    } else if (ISITEM(element)) {
static void _xfdashboard_applications_menu_model_fill_model_collect_menu(XfdashboardApplicationsMenuModel *self,
																			GarconMenu *inMenu,
																			GarconMenu *inParentMenu,
																			XfdashboardApplicationsMenuModelFillData *inFillData)
{
	XfdashboardApplicationsMenuModelPrivate			*priv;
	GarconMenu										*menu;
	GarconMenu										*section;
	GList											*elements, *element;

	g_return_if_fail(XFDASHBOARD_IS_APPLICATIONS_MENU_MODEL(self));
	g_return_if_fail(GARCON_IS_MENU(inMenu));

	priv=self->priv;
	section=NULL;
	menu=priv->rootMenu;

	/* Increase reference on menu going to be processed to keep it alive */
	g_object_ref(inMenu);

	/* Skip additional check on root menu as it must be processed normally and non-disruptively */
	if(inMenu!=priv->rootMenu)
	{
		/* Find section to add menu to */
		section=_xfdashboard_applications_menu_model_find_section(self, inMenu, inFillData);

		/* Add menu to model if no duplicate or similar menu exist */
		menu=_xfdashboard_applications_menu_model_find_similar_menu(self, inMenu, inFillData);
		if(!menu)
		{
			const gchar									*title=garcon_menu_element_get_name(GARCON_MENU_ELEMENT(inMenu));
			const gchar									*description=garcon_menu_element_get_comment(GARCON_MENU_ELEMENT(inMenu));

			/* Insert row into model because there is no duplicate
			 * and no similar menu
			 */
			inFillData->sequenceID++;
			clutter_model_append(CLUTTER_MODEL(self),
									XFDASHBOARD_APPLICATIONS_MENU_MODEL_COLUMN_SEQUENCE_ID, inFillData->sequenceID,
									XFDASHBOARD_APPLICATIONS_MENU_MODEL_COLUMN_MENU_ELEMENT, inMenu,
									XFDASHBOARD_APPLICATIONS_MENU_MODEL_COLUMN_PARENT_MENU, inParentMenu,
									XFDASHBOARD_APPLICATIONS_MENU_MODEL_COLUMN_SECTION, section,
									XFDASHBOARD_APPLICATIONS_MENU_MODEL_COLUMN_TITLE, title,
									XFDASHBOARD_APPLICATIONS_MENU_MODEL_COLUMN_DESCRIPTION, description,
									-1);

			/* Add menu to list of populated ones */
			inFillData->populatedMenus=g_slist_prepend(inFillData->populatedMenus, inMenu);

			/* All menu items should be added to this newly created menu */
			menu=inMenu;

			/* Find section of newly created menu to */
			section=_xfdashboard_applications_menu_model_find_section(self, menu, inFillData);
		}
	}

	/* Iterate through menu and add menu items and sub-menus */
	elements=garcon_menu_get_elements(inMenu);
	for(element=elements; element; element=g_list_next(element))
	{
		GarconMenuElement							*menuElement;

		/* Get menu element from list */
		menuElement=GARCON_MENU_ELEMENT(element->data);

		/* Check if menu element is visible */
		if(!menuElement || !garcon_menu_element_get_visible(menuElement)) continue;

		/* If element is a menu call this function recursively */
		if(GARCON_IS_MENU(menuElement))
		{
			_xfdashboard_applications_menu_model_fill_model_collect_menu(self, GARCON_MENU(menuElement), menu, inFillData);
		}

		/* Insert row into model if menu element is a menu item if it does not
		 * belong to root menu.
		 */
		if(GARCON_IS_MENU_ITEM(menuElement) &&
			menu!=priv->rootMenu)
		{
			const gchar								*title=garcon_menu_element_get_name(menuElement);
			const gchar								*description=garcon_menu_element_get_comment(menuElement);

			/* Add menu item to model */
			inFillData->sequenceID++;
			clutter_model_append(CLUTTER_MODEL(self),
									XFDASHBOARD_APPLICATIONS_MENU_MODEL_COLUMN_SEQUENCE_ID, inFillData->sequenceID,
									XFDASHBOARD_APPLICATIONS_MENU_MODEL_COLUMN_MENU_ELEMENT, menuElement,
									XFDASHBOARD_APPLICATIONS_MENU_MODEL_COLUMN_PARENT_MENU, menu,
									XFDASHBOARD_APPLICATIONS_MENU_MODEL_COLUMN_SECTION, section,
									XFDASHBOARD_APPLICATIONS_MENU_MODEL_COLUMN_TITLE, title,
									XFDASHBOARD_APPLICATIONS_MENU_MODEL_COLUMN_DESCRIPTION, description,
									-1);
		}
	}
	g_list_free(elements);

	/* Connect signal 'reload-required' to recognize changes in menus */
	g_signal_connect_swapped(inMenu, "reload-required", G_CALLBACK(_xfdashboard_applications_menu_model_on_reload_required), self);

	/* Release allocated resources */
	g_object_unref(inMenu);
}