/* 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 "stream/stringstream.h" #include "commands.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_globalCommandNames; class PluginCaller { CPluginSlot* slot; const char* name; public: PluginCaller( CPluginSlot* slot_, const char* name_ ) : slot( slot_ ), name( name_ ){ } void operator()(){ slot->Dispatch( name ); } }; std::list m_callbacks; public: /*! build directly from a SYN_PROVIDE interface */ CPluginSlot( QWidget* 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 ); const char* getGlobalCommand( std::size_t n ); }; CPluginSlot::CPluginSlot( QWidget* 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, ",;" ); while ( 1 ) { const char* cmdToken = commandTokeniser.getToken(); const char *titleToken = titleTokeniser.getToken(); if( string_empty( cmdToken ) ) break; m_CommandStrings.push_back( cmdToken ); if ( string_empty( titleToken ) ) m_CommandTitleStrings.push_back( cmdToken ); else m_CommandTitleStrings.push_back( titleToken ); m_callbacks.emplace_back( PluginCaller( this, m_CommandStrings.back().c_str() ) ); StringOutputStream str( 64 ); { if( !string_equal_nocase_n( cmdToken, getMenuName(), string_length( getMenuName() ) ) ){ //plugin name is not part of command name str << getMenuName() << "::"; } /* remove spaces + camelcasify */ const char* p = cmdToken; bool wasspace = false; while( *p ){ if( *p == ' ' ){ wasspace = true; } else if( wasspace ){ wasspace = false; str << static_cast( std::toupper( *p ) ); } else{ str << *p; } ++p; } /* del trailing periods */ char* pp = &( *( str.end() - 1 ) ); while( *pp == '.' ){ *pp = '\0'; --pp; } *str.c_str() = std::tolower( *str.c_str() ); //put to the end of the list this way } m_globalCommandNames.emplace_back( str.c_str() ); if ( !plugin_menu_special( cmdToken ) ) //ain't special GlobalCommands_insert( str.c_str(), makeCallback( m_callbacks.back() ) ); } 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(); } const char* CPluginSlot::getGlobalCommand( std::size_t n ){ std::list::iterator i = m_globalCommandNames.begin(); while ( n-- != 0 ) ++i; return ( *i ).c_str(); } 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( QWidget* main_window, const char* name, const _QERPluginTable& table ){ mSlots.push_back( new CPluginSlot( main_window, name, table ) ); } void PopulateMenu( PluginsVisitor& menu ); }; 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 ) ); } } CPluginSlots g_plugin_slots; void FillPluginSlots( CPluginSlots& slots, QWidget* main_window ){ class AddPluginVisitor : public PluginModules::Visitor { CPluginSlots& m_slots; QWidget* m_main_window; public: AddPluginVisitor( CPluginSlots& slots, QWidget* 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 ); } CPlugInManager g_PlugInMgr; CPlugInManager& GetPlugInMgr(){ return g_PlugInMgr; } void CPlugInManager::Init( QWidget* main_window ){ FillPluginSlots( g_plugin_slots, main_window ); } void CPlugInManager::constructMenu( PluginsVisitor& menu ){ g_plugin_slots.PopulateMenu( menu ); } void CPlugInManager::Shutdown(){ }