4 * ROX-Filer, filer for the ROX desktop project
5 * Copyright (C) 2002, the ROX-Filer team.
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the Free
9 * Software Foundation; either version 2 of the License, or (at your option)
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 * You should have received a copy of the GNU General Public License along with
18 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
19 * Place, Suite 330, Boston, MA 02111-1307 USA
22 /* appmenu.c - handles application-specific menus read from XMLwrapper.xml */
32 #include <libxml/parser.h>
37 #include "gui_support.h"
47 /* Static prototypes */
48 static void apprun_menu(GtkWidget
*item
, gpointer data
);
49 static GtkWidget
*create_menu_item(xmlNode
*node
);
51 /* There can only be one menu open at a time... we store: */
52 static GtkWidget
*current_menu
= NULL
; /* The GtkMenu */
53 static guchar
*current_app_path
= NULL
; /* The path of the application */
54 static GList
*current_items
= NULL
; /* The GtkMenuItems we added directly
55 * to it --- not submenu items.
58 /****************************************************************
59 * EXTERNAL INTERFACE *
60 ****************************************************************/
62 /* Removes all appmenu menu items */
63 void appmenu_remove(void)
70 for (next
= current_items
; next
; next
= next
->next
)
71 gtk_widget_destroy((GtkWidget
*) next
->data
);
73 g_free(current_app_path
);
74 current_app_path
= NULL
;
77 g_list_free(current_items
);
81 /* Add AppMenu entries to 'menu', if appropriate.
82 * This function modifies the menu stored in "menu".
83 * 'app_dir' is the pathname of the application directory, and 'item'
84 * is the corresponding DirItem.
85 * Call appmenu_remove() to undo the effect.
87 void appmenu_add(const gchar
*app_dir
, DirItem
*item
, GtkWidget
*menu
)
89 XMLwrapper
*ai
= NULL
;
94 g_return_if_fail(menu
!= NULL
);
96 /* Should have called appmenu_remove() already... */
97 g_return_if_fail(current_menu
== NULL
);
99 ai
= appinfo_get(app_dir
, item
);
101 return; /* No appmenu (or invalid XML) */
103 /* OK, we've got a valid info file and parsed it.
104 * Now build the GtkMenuItem widgets and add them to the menu
105 * (if there are any).
108 node
= xml_get_section(ai
, NULL
, "AppMenu");
112 g_return_if_fail(current_items
== NULL
);
114 /* Add the menu entries */
115 for (node
= node
->xmlChildrenNode
; node
; node
= node
->next
)
119 item
= create_menu_item(node
);
122 current_items
= g_list_prepend(current_items
, item
);
125 sep
= gtk_menu_item_new();
126 current_items
= g_list_prepend(current_items
, sep
);
127 gtk_widget_show(sep
);
129 for (next
= current_items
; next
; next
= next
->next
)
130 gtk_menu_shell_prepend(GTK_MENU_SHELL(menu
),
131 GTK_WIDGET(next
->data
));
134 current_app_path
= g_strdup(app_dir
);
141 /****************************************************************
142 * INTERNAL FUNCTIONS *
143 ****************************************************************/
145 /* Create a new menu and return it */
146 static GtkWidget
*appmenu_add_submenu(xmlNode
*subm_node
)
151 /* Create the new submenu */
152 sub_menu
= gtk_menu_new();
154 /* Add the menu entries */
155 for (node
= subm_node
->xmlChildrenNode
; node
; node
= node
->next
)
159 item
= create_menu_item(node
);
161 gtk_menu_shell_append(GTK_MENU_SHELL(sub_menu
), item
);
167 /* Create and return a menu item */
168 static GtkWidget
*create_menu_item(xmlNode
*node
)
171 guchar
*label
, *option
= NULL
;
174 if (node
->type
!= XML_ELEMENT_NODE
)
177 if (strcmp(node
->name
, "Item") == 0)
180 option
= xmlGetProp(node
, "option");
182 else if (strcmp(node
->name
, "AppMenu") == 0)
187 /* Create the item */
188 label
= xmlGetProp(node
, "label");
190 label
= g_strdup(_("<missing label>"));
191 item
= gtk_menu_item_new_with_label(label
);
193 gtk_widget_set_accel_path(item
, NULL
, NULL
); /* XXX */
199 /* Add submenu items */
201 gtk_menu_item_set_submenu(GTK_MENU_ITEM(item
),
202 appmenu_add_submenu(node
));
206 /* Set up callback */
210 g_object_set_data_full(G_OBJECT(item
), "option",
216 g_signal_connect(item
, "activate", G_CALLBACK(apprun_menu
),
220 gtk_widget_show(item
);
225 /* Function called to execute an AppMenu item */
226 static void apprun_menu(GtkWidget
*item
, gpointer data
)
231 g_return_if_fail(current_app_path
!= NULL
);
233 option
= g_object_get_data(G_OBJECT(item
), "option");
235 argv
[0] = g_strconcat(current_app_path
, "/AppRun", NULL
);
236 argv
[1] = option
; /* (may be NULL) */
239 rox_spawn(NULL
, (const gchar
**) argv
);