/* Copyright (C) 1999-2006 Id Software, Inc. and contributors. For a list of contributors, see the accompanying CONTRIBUTORS file. This file is part of GtkRadiant. GtkRadiant is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. GtkRadiant is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GtkRadiant; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "pluginmenu.h" #include #include "stream/textstream.h" #include "gtkutil/pointer.h" #include "gtkutil/menu.h" #include "pluginmanager.h" #include "mainframe.h" #include "preferences.h" int m_nNextPlugInID = 0; void plugin_activated(ui::Widget widget, gpointer data) { const char *str = (const char *) g_object_get_data(G_OBJECT(widget), "command"); GetPlugInMgr().Dispatch(gpointer_to_int(data), str); } #include void PlugInMenu_Add(ui::Menu plugin_menu, IPlugIn *pPlugIn) { ui::Widget item{ui::null}, parent{ui::null}; ui::Menu menu{ui::null}, subMenu{ui::null}; const char *menuText, *menuCommand; std::stack menuStack; parent = ui::MenuItem(pPlugIn->getMenuName()); parent.show(); plugin_menu.add(parent); std::size_t nCount = pPlugIn->getCommandCount(); if (nCount > 0) { menu = ui::Menu(ui::New); if (g_Layout_enableDetachableMenus.m_value) { menu_tearoff(menu); } while (nCount > 0) { menuText = pPlugIn->getCommandTitle(--nCount); menuCommand = pPlugIn->getCommand(nCount); if (menuText != 0 && strlen(menuText) > 0) { if (!strcmp(menuText, "-")) { item = ui::Widget::from(gtk_menu_item_new()); gtk_widget_set_sensitive(item, FALSE); } else if (!strcmp(menuText, ">")) { menuText = pPlugIn->getCommandTitle(--nCount); menuCommand = pPlugIn->getCommand(nCount); if (!strcmp(menuText, "-") || !strcmp(menuText, ">") || !strcmp(menuText, "<")) { globalErrorStream() << pPlugIn->getMenuName() << " Invalid title (" << menuText << ") for submenu.\n"; continue; } item = ui::MenuItem(menuText); item.show(); menu.add(item); subMenu = ui::Menu(ui::New); gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), subMenu); menuStack.push(menu); menu = subMenu; continue; } else if (!strcmp(menuText, "<")) { if (!menuStack.empty()) { menu = menuStack.top(); menuStack.pop(); } else { globalErrorStream() << pPlugIn->getMenuName() << ": Attempt to end non-existent submenu ignored.\n"; } continue; } else { item = ui::MenuItem(menuText); g_object_set_data(G_OBJECT(item), "command", const_cast( static_cast( menuCommand ))); item.connect("activate", G_CALLBACK(plugin_activated), gint_to_pointer(m_nNextPlugInID)); } item.show(); menu.add(item); pPlugIn->addMenuID(m_nNextPlugInID++); } } if (!menuStack.empty()) { std::size_t size = menuStack.size(); if (size != 0) { globalErrorStream() << pPlugIn->getMenuName() << " mismatched > <. " << Unsigned(size) << " submenu(s) not closed.\n"; } for (std::size_t i = 0; i < (size - 1); i++) { menuStack.pop(); } menu = menuStack.top(); menuStack.pop(); } gtk_menu_item_set_submenu(GTK_MENU_ITEM(parent), menu); } } ui::Menu g_plugins_menu{ui::null}; ui::MenuItem g_plugins_menu_separator{ui::null}; void PluginsMenu_populate() { class PluginsMenuConstructor : public PluginsVisitor { ui::Menu m_menu; public: PluginsMenuConstructor(ui::Menu menu) : m_menu(menu) { } void visit(IPlugIn &plugin) { PlugInMenu_Add(m_menu, &plugin); } }; PluginsMenuConstructor constructor(g_plugins_menu); GetPlugInMgr().constructMenu(constructor); } void PluginsMenu_clear() { m_nNextPlugInID = 0; GList *lst = g_list_find(gtk_container_get_children(GTK_CONTAINER(g_plugins_menu)), g_plugins_menu_separator._handle); while (lst->next) { g_plugins_menu.remove(ui::Widget::from(lst->next->data)); lst = g_list_find(gtk_container_get_children(GTK_CONTAINER(g_plugins_menu)), g_plugins_menu_separator._handle); } } ui::MenuItem create_plugins_menu() { // Plugins menu auto plugins_menu_item = new_sub_menu_item_with_mnemonic("_Plugins"); auto menu = ui::Menu::from(gtk_menu_item_get_submenu(plugins_menu_item)); if (g_Layout_enableDetachableMenus.m_value) { menu_tearoff(menu); } g_plugins_menu = menu; //TODO: some modules/plugins do not yet support refresh #if 0 create_menu_item_with_mnemonic( menu, "Refresh", makeCallbackF(Restart) ); // NOTE: the seperator is used when doing a refresh of the list, everything past the seperator is removed g_plugins_menu_separator = menu_separator( menu ); #endif PluginsMenu_populate(); return plugins_menu_item; }