added support for both ent and def files at the same time
[xonotic/netradiant.git] / radiant / pluginmanager.cpp
1 /*
2 Copyright (C) 1999-2006 Id Software, Inc. and contributors.
3 For a list of contributors, see the accompanying CONTRIBUTORS file.
4
5 This file is part of GtkRadiant.
6
7 GtkRadiant is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 GtkRadiant is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GtkRadiant; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20 */
21
22 // PlugInManager.cpp: implementation of the CPlugInManager class.
23 //
24 //////////////////////////////////////////////////////////////////////
25
26 #include "pluginmanager.h"
27
28 #include "modulesystem.h"
29 #include "qerplugin.h"
30 #include "iplugin.h"
31
32 #include "math/vector.h"
33 #include "string/string.h"
34
35 #include "error.h"
36 #include "select.h"
37 #include "plugin.h"
38
39 #include "modulesystem.h"
40
41 #include <list>
42
43 /* plugin manager --------------------------------------- */
44 class CPluginSlot : public IPlugIn
45 {
46   CopiedString m_menu_name;
47   const _QERPluginTable *mpTable;
48   std::list<CopiedString> m_CommandStrings;
49   std::list<CopiedString> m_CommandTitleStrings;
50   std::list<std::size_t> m_CommandIDs;
51   
52 public:
53   /*!
54   build directly from a SYN_PROVIDE interface
55   */
56   CPluginSlot(GtkWidget* main_window, const char* name, const _QERPluginTable& table);
57   /*!
58   dispatching a command by name to the plugin
59   */
60   void Dispatch(const char *p);
61
62   // IPlugIn ------------------------------------------------------------
63   const char* getMenuName();
64   std::size_t getCommandCount();
65   const char* getCommand(std::size_t n);  
66   const char* getCommandTitle(std::size_t n);
67   void addMenuID(std::size_t n);
68   bool ownsCommandID(std::size_t n);
69   
70 };
71
72 CPluginSlot::CPluginSlot(GtkWidget* main_window, const char* name, const _QERPluginTable& table)
73 {
74   mpTable = &table;
75   m_menu_name = name;
76
77   const char* commands = mpTable->m_pfnQERPlug_GetCommandList();
78   const char* titles = mpTable->m_pfnQERPlug_GetCommandTitleList();
79
80   StringTokeniser commandTokeniser(commands, ",;");
81   StringTokeniser titleTokeniser(titles, ",;");
82   
83   const char* cmdToken = commandTokeniser.getToken();
84   const char *titleToken = titleTokeniser.getToken();
85   while (!string_empty(cmdToken))
86   {
87     if(string_empty(titleToken))
88     {
89       m_CommandStrings.push_back(cmdToken);
90       m_CommandTitleStrings.push_back(cmdToken);
91       cmdToken = commandTokeniser.getToken();
92       titleToken = "";
93     }
94     else
95     {
96       m_CommandStrings.push_back(cmdToken);
97       m_CommandTitleStrings.push_back(titleToken);
98       cmdToken = commandTokeniser.getToken();
99       titleToken = titleTokeniser.getToken();
100     }
101   }
102   mpTable->m_pfnQERPlug_Init(0, (void*)main_window);
103 }
104
105 const char* CPluginSlot::getMenuName()
106 {
107   return m_menu_name.c_str();
108 }
109
110 std::size_t CPluginSlot::getCommandCount()
111 {
112   return m_CommandStrings.size();  
113 }
114   
115 const char* CPluginSlot::getCommand(std::size_t n)
116 {
117   std::list<CopiedString>::iterator i = m_CommandStrings.begin();
118   while(n-- != 0)
119     ++i;
120   return (*i).c_str();  
121 }
122
123 const char* CPluginSlot::getCommandTitle(std::size_t n)
124 {
125   std::list<CopiedString>::iterator i = m_CommandTitleStrings.begin();
126   while(n-- != 0)
127     ++i;
128   return (*i).c_str();  
129 }
130
131 void CPluginSlot::addMenuID(std::size_t n)
132 {
133   m_CommandIDs.push_back(n);
134 }
135
136 bool CPluginSlot::ownsCommandID(std::size_t n)
137 {
138   for(std::list<std::size_t>::iterator i = m_CommandIDs.begin(); i != m_CommandIDs.end(); ++i)
139   {
140     if (*i == n)
141       return true;
142   }
143   return false;
144 }
145
146 void CPluginSlot::Dispatch(const char *p)
147 {
148   Vector3 vMin, vMax;
149   Select_GetBounds (vMin, vMax);
150   mpTable->m_pfnQERPlug_Dispatch(p, reinterpret_cast<float*>(&vMin), reinterpret_cast<float*>(&vMax), true);//QE_SingleBrush(true));
151 }
152
153
154 class CPluginSlots
155 {
156   std::list<CPluginSlot *> mSlots;
157 public:
158   virtual ~CPluginSlots();
159
160   void AddPluginSlot(GtkWidget* main_window, const char* name, const _QERPluginTable& table)
161   {
162     mSlots.push_back(new CPluginSlot(main_window, name, table));
163   }
164   
165   void PopulateMenu(PluginsVisitor& menu);
166   bool Dispatch(std::size_t n, const char* p);
167 };
168
169 CPluginSlots::~CPluginSlots()
170 {
171   std::list<CPluginSlot *>::iterator iSlot;
172   for(iSlot=mSlots.begin(); iSlot!=mSlots.end(); ++iSlot)
173   {
174     delete *iSlot;
175     *iSlot = 0;
176   }
177 }
178
179 void CPluginSlots::PopulateMenu(PluginsVisitor& menu)
180 {
181   std::list<CPluginSlot *>::iterator iPlug;
182   for(iPlug=mSlots.begin(); iPlug != mSlots.end(); ++iPlug)
183   {
184     menu.visit(*(*iPlug));
185   }
186 }
187
188 bool CPluginSlots::Dispatch(std::size_t n, const char* p)
189 {
190   std::list<CPluginSlot *>::iterator iPlug;
191   for(iPlug=mSlots.begin(); iPlug!=mSlots.end(); ++iPlug)
192   {
193     CPluginSlot *pPlug = *iPlug;
194     if (pPlug->ownsCommandID(n))
195     {
196       pPlug->Dispatch(p);
197       return true;
198     }
199   }
200   return false;
201 }
202
203 CPluginSlots g_plugin_slots;
204
205
206 void FillPluginSlots(CPluginSlots& slots, GtkWidget* main_window)
207 {
208   class AddPluginVisitor : public PluginModules::Visitor
209   {
210     CPluginSlots& m_slots;
211     GtkWidget* m_main_window;
212   public:
213     AddPluginVisitor(CPluginSlots& slots, GtkWidget* main_window)
214       : m_slots(slots), m_main_window(main_window)
215     {
216     }
217     void visit(const char* name, const _QERPluginTable& table) const
218     {
219       m_slots.AddPluginSlot(m_main_window, name, table);
220     }
221   } visitor(slots, main_window);
222
223   Radiant_getPluginModules().foreachModule(visitor);
224 }
225
226
227 #include "pluginmanager.h"
228
229 CPlugInManager g_PlugInMgr;
230
231 CPlugInManager& GetPlugInMgr()
232 {
233   return g_PlugInMgr;
234 }
235
236 void CPlugInManager::Dispatch(std::size_t n, const char * p)
237 {
238   g_plugin_slots.Dispatch(n, p);
239 }
240
241 void CPlugInManager::Init(GtkWidget* main_window)
242 {
243   FillPluginSlots(g_plugin_slots, main_window);
244 }
245
246 void CPlugInManager::constructMenu(PluginsVisitor& menu)
247 {
248   g_plugin_slots.PopulateMenu(menu);
249 }
250
251 void CPlugInManager::Shutdown()
252 {
253 }