/* 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 */ // PlugInManager.cpp: implementation of the CPlugInManager class. // ////////////////////////////////////////////////////////////////////// #include "pluginmanager.h" #include "modulesystem.h" #include "qerplugin.h" #include "iplugin.h" #include "math/vector.h" #include "string/string.h" #include "error.h" #include "select.h" #include "plugin.h" #include "modulesystem.h" #include /* plugin manager --------------------------------------- */ class CPluginSlot : public IPlugIn { CopiedString m_menu_name; const _QERPluginTable *mpTable; std::list m_CommandStrings; std::list m_CommandTitleStrings; std::list m_CommandIDs; public: /*! build directly from a SYN_PROVIDE interface */ CPluginSlot(ui::Widget main_window, const char *name, const _QERPluginTable &table); /*! dispatching a command by name to the plugin */ void Dispatch(const char *p); // IPlugIn ------------------------------------------------------------ const char *getMenuName(); std::size_t getCommandCount(); const char *getCommand(std::size_t n); const char *getCommandTitle(std::size_t n); void addMenuID(std::size_t n); bool ownsCommandID(std::size_t n); }; CPluginSlot::CPluginSlot(ui::Widget main_window, const char *name, const _QERPluginTable &table) { mpTable = &table; m_menu_name = name; const char *commands = mpTable->m_pfnQERPlug_GetCommandList(); const char *titles = mpTable->m_pfnQERPlug_GetCommandTitleList(); StringTokeniser commandTokeniser(commands, ",;"); StringTokeniser titleTokeniser(titles, ",;"); const char *cmdToken = commandTokeniser.getToken(); const char *titleToken = titleTokeniser.getToken(); while (!string_empty(cmdToken)) { if (string_empty(titleToken)) { m_CommandStrings.push_back(cmdToken); m_CommandTitleStrings.push_back(cmdToken); cmdToken = commandTokeniser.getToken(); titleToken = ""; } else { m_CommandStrings.push_back(cmdToken); m_CommandTitleStrings.push_back(titleToken); cmdToken = commandTokeniser.getToken(); titleToken = titleTokeniser.getToken(); } } mpTable->m_pfnQERPlug_Init(0, (void *) main_window); } const char *CPluginSlot::getMenuName() { return m_menu_name.c_str(); } std::size_t CPluginSlot::getCommandCount() { return m_CommandStrings.size(); } const char *CPluginSlot::getCommand(std::size_t n) { std::list::iterator i = m_CommandStrings.begin(); while (n-- != 0) { ++i; } return (*i).c_str(); } const char *CPluginSlot::getCommandTitle(std::size_t n) { std::list::iterator i = m_CommandTitleStrings.begin(); while (n-- != 0) { ++i; } return (*i).c_str(); } void CPluginSlot::addMenuID(std::size_t n) { m_CommandIDs.push_back(n); } bool CPluginSlot::ownsCommandID(std::size_t n) { for (std::list::iterator i = m_CommandIDs.begin(); i != m_CommandIDs.end(); ++i) { if (*i == n) { return true; } } return false; } void CPluginSlot::Dispatch(const char *p) { Vector3 vMin, vMax; Select_GetBounds(vMin, vMax); mpTable->m_pfnQERPlug_Dispatch(p, reinterpret_cast( &vMin ), reinterpret_cast( &vMax ), true); //QE_SingleBrush(true)); } class CPluginSlots { std::list mSlots; public: virtual ~CPluginSlots(); void AddPluginSlot(ui::Widget main_window, const char *name, const _QERPluginTable &table) { mSlots.push_back(new CPluginSlot(main_window, name, table)); } void PopulateMenu(PluginsVisitor &menu); bool Dispatch(std::size_t n, const char *p); }; CPluginSlots::~CPluginSlots() { std::list::iterator iSlot; for (iSlot = mSlots.begin(); iSlot != mSlots.end(); ++iSlot) { delete *iSlot; *iSlot = 0; } } void CPluginSlots::PopulateMenu(PluginsVisitor &menu) { std::list::iterator iPlug; for (iPlug = mSlots.begin(); iPlug != mSlots.end(); ++iPlug) { menu.visit(*(*iPlug)); } } bool CPluginSlots::Dispatch(std::size_t n, const char *p) { std::list::iterator iPlug; for (iPlug = mSlots.begin(); iPlug != mSlots.end(); ++iPlug) { CPluginSlot *pPlug = *iPlug; if (pPlug->ownsCommandID(n)) { pPlug->Dispatch(p); return true; } } return false; } CPluginSlots g_plugin_slots; void FillPluginSlots(CPluginSlots &slots, ui::Widget main_window) { class AddPluginVisitor : public PluginModules::Visitor { CPluginSlots &m_slots; ui::Widget m_main_window; public: AddPluginVisitor(CPluginSlots &slots, ui::Widget main_window) : m_slots(slots), m_main_window(main_window) { } void visit(const char *name, const _QERPluginTable &table) const { m_slots.AddPluginSlot(m_main_window, name, table); } } visitor(slots, main_window); Radiant_getPluginModules().foreachModule(visitor); } #include "pluginmanager.h" CPlugInManager g_PlugInMgr; CPlugInManager &GetPlugInMgr() { return g_PlugInMgr; } void CPlugInManager::Dispatch(std::size_t n, const char *p) { g_plugin_slots.Dispatch(n, p); } void CPlugInManager::Init(ui::Widget main_window) { FillPluginSlots(g_plugin_slots, main_window); } void CPlugInManager::constructMenu(PluginsVisitor &menu) { g_plugin_slots.PopulateMenu(menu); } void CPlugInManager::Shutdown() { }