+ObMenuEntry* menu_add_normal(ObMenu *self, gint id, const gchar *label,
+ GSList *actions, gboolean allow_shortcut)
+{
+ ObMenuEntry *e;
+
+ e = menu_entry_new(self, OB_MENU_ENTRY_TYPE_NORMAL, id);
+ e->data.normal.actions = actions;
+
+ menu_entry_set_label(e, label, allow_shortcut);
+
+ self->entries = g_list_append(self->entries, e);
+ self->more_menu->entries = self->entries; /* keep it in sync */
+ return e;
+}
+
+ObMenuEntry* menu_get_more(ObMenu *self, guint show_from)
+{
+ ObMenuEntry *e;
+ e = menu_entry_new(self, OB_MENU_ENTRY_TYPE_SUBMENU, -1);
+ /* points to itself */
+ e->data.submenu.name = g_strdup(self->name);
+ e->data.submenu.submenu = self;
+ e->data.submenu.show_from = show_from;
+ return e;
+}
+
+ObMenuEntry* menu_add_submenu(ObMenu *self, gint id, const gchar *submenu)
+{
+ ObMenuEntry *e;
+
+ e = menu_entry_new(self, OB_MENU_ENTRY_TYPE_SUBMENU, id);
+ e->data.submenu.name = g_strdup(submenu);
+
+ self->entries = g_list_append(self->entries, e);
+ self->more_menu->entries = self->entries; /* keep it in sync */
+ return e;
+}
+
+ObMenuEntry* menu_add_separator(ObMenu *self, gint id, const gchar *label)
+{
+ ObMenuEntry *e;
+
+ e = menu_entry_new(self, OB_MENU_ENTRY_TYPE_SEPARATOR, id);
+
+ menu_entry_set_label(e, label, FALSE);
+
+ self->entries = g_list_append(self->entries, e);
+ self->more_menu->entries = self->entries; /* keep it in sync */
+ return e;
+}
+
+void menu_set_show_func(ObMenu *self, ObMenuShowFunc func)
+{
+ self->show_func = func;
+}
+
+void menu_set_hide_func(ObMenu *self, ObMenuHideFunc func)
+{
+ self->hide_func = func;
+}
+
+void menu_set_update_func(ObMenu *self, ObMenuUpdateFunc func)
+{
+ self->update_func = func;
+}
+
+void menu_set_execute_func(ObMenu *self, ObMenuExecuteFunc func)
+{
+ self->execute_func = func;
+ self->more_menu->execute_func = func; /* keep it in sync */
+}
+
+void menu_set_cleanup_func(ObMenu *self, ObMenuCleanupFunc func)
+{
+ self->cleanup_func = func;