2
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
4
* This program is free software; you can redistribute it and/or
5
* modify it under the terms of the GNU General Public License as
6
* published by the Free Software Foundation; version 2 of the
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
14
* You should have received a copy of the GNU General Public License
15
* along with this program; if not, write to the Free Software
16
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22
#include "plugin_manager.h"
23
#include "editor_base.h"
24
#include "grt_manager.h"
25
#include "base/string_utilities.h"
27
#include "interfaces/plugin.h"
34
static std::string get_args_hash(const grt::BaseListRef &list)
38
for (size_t c= list.count(), i= 0; i < c; i++)
40
switch (list.get(i).type())
43
hash+= grt::ObjectRef::cast_from(list.get(i)).id();
46
hash+= get_args_hash(grt::BaseListRef::cast_from(list.get(i)));
49
hash+= list.get(i).repr();
58
PluginManagerImpl::PluginManagerImpl(grt::CPPModuleLoader *loader)
61
_grtm= GRTManager::get_instance_for(loader->get_grt());
63
InterfaceImplBase::Register<PluginInterfaceImpl>(loader->get_grt());
68
****************************************************************************
69
* @brief Sets the GRT tree path where the plugin registry is located
73
****************************************************************************
75
void PluginManagerImpl::set_registry_paths(const std::string &plugins_path,
76
const std::string &groups_path)
78
_registry_path= plugins_path;
79
_group_registry_path= groups_path;
83
bool PluginManagerImpl::check_plugin_validity(const app_PluginRef &plugin, grt::Module *module)
85
if (plugin->pluginType() == GUI_PLUGIN_TYPE)
87
// not much that can be tested here, maybe check if the dll actually exists
90
else if (plugin->pluginType() == STANDALONE_GUI_PLUGIN_TYPE
91
|| plugin->pluginType() == NORMAL_PLUGIN_TYPE)
93
// check if the module matches and the function exists
94
if (plugin->moduleName() != module->name())
96
g_warning("Plugin '%s' from module %s declares moduleName() as '%s', which doesn't match the module it belongs to",
97
plugin->name().c_str(), module->name().c_str(), plugin->moduleName().c_str());
102
std::string f= plugin->moduleFunctionName();
103
if (!module->has_function(f))
105
g_warning("Plugin '%s' from module %s has invalid moduleFunctionName '%s'",
106
plugin->name().c_str(), module->name().c_str(), f.c_str());
112
else if (plugin->pluginType() == INTERNAL_PLUGIN_TYPE)
116
else if (0 == (*plugin->pluginType()).find(CUSTOM_PLUGIN_TYPE))
122
g_warning("Plugin '%s' from module %s has invalid type '%s'", plugin->name().c_str(),
123
module->name().c_str(), plugin->pluginType().c_str());
129
void PluginManagerImpl::set_plugin_enabled(const app_PluginRef &plugin, bool flag)
131
grt::StringListRef disabled_list(get_disabled_plugin_names());
132
size_t idx= disabled_list.get_index(plugin->name());
134
if (flag && idx != grt::BaseListRef::npos)
136
disabled_list.remove(idx);
137
if (plugin->groups().count() == 0)
138
add_plugin_to_group(plugin, "Others/Menu/Ungrouped");
141
for (size_t d= plugin->groups().count(), j= 0; j < d; j++)
142
add_plugin_to_group(plugin, plugin->groups()[j]);
145
else if (!flag && idx == grt::BaseListRef::npos)
147
disabled_list.insert(plugin->name());
148
// remove the plugin from all groups
149
grt::ListRef<app_PluginGroup> groups(get_plugin_groups());
150
for (unsigned int c= groups.count(), i= 0; i < c; i++)
151
groups[i]->plugins().remove_value(plugin);
156
bool PluginManagerImpl::plugin_enabled(const std::string &plugin_name)
158
grt::StringListRef names(get_disabled_plugin_names());
159
if (names.get_index(plugin_name) == grt::BaseListRef::npos)
165
grt::StringListRef PluginManagerImpl::get_disabled_plugin_names()
167
std::string disabled_path(_registry_path);
168
base::pop_path_back(disabled_path);
169
base::pop_path_back(disabled_path);
170
disabled_path.append("/options/disabledPlugins");
171
return grt::StringListRef::cast_from(_grtm->get_grt()->get(disabled_path));
175
****************************************************************************
176
* @brief Refreshes the list of plugins from the list of modules and DLLs
178
* Scans the list of registered modules for plugins.
179
* Modules exporting plugins must implement PluginInterface.
180
* The list of scanned plugins is stored in the GRT tree.
182
****************************************************************************
184
void PluginManagerImpl::rescan_plugins()
186
grt::ListRef<app_Plugin> plugin_list= get_plugin_list();
187
grt::GRT *grt= _grtm->get_grt();
188
std::set<std::string> disabled_plugins;
190
// make a set of disabled plugin names
192
grt::StringListRef list= get_disabled_plugin_names();
194
for (grt::StringListRef::const_iterator i= list.begin(); i != list.end(); ++i)
196
disabled_plugins.insert(*i);
201
while (plugin_list.count() > 0)
202
plugin_list.remove(0);
204
// clear group contents
206
grt::ListRef<app_PluginGroup> groups;
207
app_PluginGroupRef group;
209
groups= get_plugin_groups();
210
for (unsigned int c= groups.count(), i= 0; i < c; i++)
213
while (group->plugins().count() > 0)
214
group->plugins().remove(0);
218
// get list of modules that implement the plugin interface
219
std::vector<Module*> plugin_modules= grt->find_modules_matching("PluginInterface", "");
221
_plugin_source_module.clear();
223
// add all modules to the plugins list
224
for (std::vector<Module*>::const_iterator pm= plugin_modules.begin(); pm != plugin_modules.end(); ++pm)
226
grt::ListRef<app_Plugin> plist;
229
grt::ValueRef result= (*pm)->call_function("getPluginInfo", grt::BaseListRef());
231
plist= grt::ListRef<app_Plugin>::cast_from(result);
232
if (!plist.is_valid() || plist.count() == 0)
234
grt->send_warning("Module "+(*pm)->name()+" implements PluginInterface but does not export any plugins", "");
238
catch (std::exception &exc)
240
grt->send_error("Module "+(*pm)->name()+" had an error while executing getPluginInfo: "+exc.what(),
241
"Location: "+(*pm)->path());
245
size_t i, c= plist.count();
246
for (i= 0; i < c; i++)
248
app_PluginRef plugin= plist[i];
250
if (_plugin_source_module.find(plugin->name()) != _plugin_source_module.end())
252
grt->send_warning("Duplicate plugin name "+*plugin->name(),
253
base::strfmt("There is more than one plugin with the name %s (in %s and %s).",
254
plugin->name().c_str(), (*pm)->name().c_str(), _plugin_source_module[plugin->name()].c_str()));
255
// must reset internal references in the object or we get a leak because of the cycles
256
plugin->reset_references();
260
if (!check_plugin_validity(plugin, *pm))
264
_plugin_source_module[plugin->name()]= (*pm)->name();
266
// add to the plugin list
267
if (plugin_list.is_valid())
268
plugin_list.insert(plugin);
270
if (disabled_plugins.find(*plugin->name()) != disabled_plugins.end())
273
grt->send_info("Plugin "+*plugin->name()+" is disabled, skipping...", "");
277
if (plugin->groups().count() == 0)
278
add_plugin_to_group(plugin, "Others/Menu/Ungrouped");
281
for (size_t d= plugin->groups().count(), j= 0; j < d; j++)
282
add_plugin_to_group(plugin, plugin->groups()[j]);
291
app_PluginGroupRef PluginManagerImpl::get_group(const std::string &group_name)
293
grt::ListRef<app_PluginGroup> groups;
294
app_PluginGroupRef group;
296
groups= get_plugin_groups();
298
for (unsigned int c= groups.count(), i= 0; i < c; i++)
300
if (groups[i]->name() == group_name)
311
void PluginManagerImpl::add_plugin_to_group(const app_PluginRef &plugin, const std::string &group_name)
313
app_PluginGroupRef group= get_group(group_name);
315
if (group.is_valid())
316
group->plugins().insert(plugin);
317
// TODO: warning for now disabled, fix group loading
319
// g_warning("Plugin %s could not be added to unknown group %s", plugin->name().c_str(), group_name.c_str());
325
****************************************************************************
326
* @brief Sets callbacks for handling of GUI plugins
328
* @param open callback for opening a plugin
329
* @param show callback for showing a plugin
330
* @param close callback for closing a plugin
332
****************************************************************************
334
void PluginManagerImpl::set_gui_plugin_callbacks(const OpenGUIPluginSlot &open,
335
const ShowGUIPluginSlot &show,
336
const CloseGUIPluginSlot &close)
338
_open_gui_plugin_slot= open;
339
_show_gui_plugin_slot= show;
340
_close_gui_plugin_slot= close;
347
****************************************************************************
348
* @brief Adds a list of plugins to the plugin registry
350
* @param list of plugins
352
****************************************************************************
354
void PluginManagerImpl::register_plugins(grt::ListRef<app_Plugin> plugins)
356
grt::ListRef<app_Plugin> list= get_plugin_list();
358
for (unsigned int c= plugins.count(), i= 0; i < c; i++)
359
list.insert(plugins[i]);
366
****************************************************************************
367
* @brief Return list of registered plugin groups
369
* @return List of plugin groups
370
****************************************************************************
372
grt::ListRef<app_PluginGroup> PluginManagerImpl::get_plugin_groups()
374
return grt::ListRef<app_PluginGroup>::cast_from(_grtm->get_grt()->get(_group_registry_path));
380
****************************************************************************
381
* @brief Returns list of all registered plugins.
383
* The list of plugins is looked up at the GRT tree path set with
384
* set_registry_path()
386
* @param group optional name of plugin group (allows * wildcards)
388
* @return List of plugins.
389
****************************************************************************
391
grt::ListRef<app_Plugin> PluginManagerImpl::get_plugin_list(const std::string &group)
394
return grt::ListRef<app_Plugin>::cast_from(_grtm->get_grt()->get(_registry_path));
397
grt::ListRef<app_Plugin> rlist(_grtm->get_grt()), list;
398
std::string left, right;
400
// groups are expected to be either in group/subgroup format or group (which will be interpreted as group/*)
402
if (group.find('/') != std::string::npos)
404
left= group.substr(0, group.find('/'));
405
right= group.substr(group.find('/')+1);
413
list= grt::ListRef<app_Plugin>::cast_from(_grtm->get_grt()->get(_registry_path));
415
for (size_t c= list.count(), i= 0; i < c; i++)
417
app_PluginRef plugin(list[i]);
418
grt::StringListRef groups(plugin->groups());
421
if (!plugin_enabled(plugin->name()))
424
for (size_t gc= groups.count(), g= 0; g < gc; g++)
426
std::string gstr(groups[g]);
427
std::string gleft, gright;
428
std::string::size_type pos;
430
if ((pos= gstr.find('/')))
432
gleft= gstr.substr(0, pos);
433
gright= gstr.substr(pos+1);
441
if ((left=="*" || left == gleft) && (right=="*" || right == gright))
448
rlist.insert(plugin);
456
bool PluginManagerImpl::check_plugin_input(const app_PluginInputDefinitionRef &def,
457
const grt::ValueRef &value)
459
if (def.is_instance(app_PluginFileInput::static_class_name()))
461
if (value.is_valid() && value.type() != StringType)
464
else if (def.is_instance(app_PluginSelectionInput::static_class_name()))
466
if (!value.is_valid() || value.type() != ListType)
469
app_PluginSelectionInputRef sdef(app_PluginSelectionInputRef::cast_from(def));
470
grt::ObjectListRef olist(grt::ObjectListRef::cast_from(value));
472
for (size_t d= olist.count(), j= 0; j < d; j++)
474
grt::ObjectRef value(olist.get(j));
477
for (size_t c= sdef->objectStructNames().count(), i= 0; i < c; i++)
479
if (value.is_instance(sdef->objectStructNames()[i]))
489
std::string card= *sdef->argumentCardinality();
492
if (olist.count() != 1)
495
else if (card == "?")
497
if (olist.count() > 1)
500
else if (card == "+")
502
if (olist.count() == 0)
505
else if (card == "*")
509
if (olist.count() != 1)
513
else if (def.is_instance(app_PluginObjectInput::static_class_name()))
515
if (!value.is_valid() || value.type() != ObjectType)
518
app_PluginObjectInputRef odef(app_PluginObjectInputRef::cast_from(def));
520
if (!grt::ObjectRef::cast_from(value).is_instance(odef->objectStructName()))
530
bool PluginManagerImpl::check_input_for_plugin(const app_PluginRef &plugin, const grt::BaseListRef &args)
532
if (args.count() != plugin->inputValues().count())
535
for (size_t c= plugin->inputValues().count(), i= 0; i < c; i++)
537
if (!check_plugin_input(plugin->inputValues()[i], args[i]))
544
app_PluginRef PluginManagerImpl::select_plugin_for_input(const std::string &group, const grt::BaseListRef &args)
546
ListRef<app_Plugin> plugins= get_plugin_list(group);
547
app_PluginRef best_match;
550
for (size_t c= plugins.count(), i= 0; i < c; i++)
552
app_PluginRef plugin= plugins[i];
554
if (check_input_for_plugin(plugin, args) && *plugin->rating() > rating)
557
rating= *plugin->rating();
567
****************************************************************************
568
* @brief Returns list of plugins that can be called on the objects
571
* @param objects list of objects
572
* @param group optional name of group for filtering (eg: catalog/Editors)
574
* @return list of plugins
575
****************************************************************************
578
std::vector<app_PluginRef> PluginManagerImpl::get_plugins_for_objects(const grt::ObjectListRef &objects,
579
const std::string &group)
581
std::vector<app_PluginRef> plist;
582
grt::ListRef<app_Plugin> plugins;
584
plugins= get_plugin_list(group);
585
size_t i, c= plugins.count();
587
// look for plugins that take 1 ObjectInput arg that is compatible with the obj list
588
if (objects.count() == 1)
589
for (i= 0; i < c; i++)
591
app_PluginRef plugin(plugins[i]);
593
if (plugin->inputValues().count() == 1 &&
594
plugin->inputValues()[0]->is_instance(app_PluginObjectInput::static_class_name()))
596
app_PluginObjectInputRef oinput(app_PluginObjectInputRef::cast_from(plugin->inputValues()[0]));
597
std::string struct_name= oinput->objectStructName();
600
for (size_t oc= objects.count(), oi= 0; oi < oc; oi++)
602
if (!objects[oi].is_instance(struct_name))
610
plist.push_back(plugin);
614
// look for plugins that take selection as input and are compatible with the obj list
615
for (i= 0; i < c; i++)
617
app_PluginRef plugin(plugins[i]);
619
if (plugin->inputValues().count() == 1 &&
620
plugin->inputValues()[0]->is_instance(app_PluginSelectionInput::static_class_name()))
622
app_PluginSelectionInputRef oinput(app_PluginSelectionInputRef::cast_from(plugin->inputValues()[0]));
623
std::string card= *oinput->argumentCardinality();
624
grt::StringListRef struct_names(oinput->objectStructNames());
629
if (objects.count() != 1)
632
else if (card == "?")
634
if (objects.count() > 1)
637
else if (card == "+")
639
if (objects.count() == 0)
642
else if (card == "*")
646
if (objects.count() != 1)
650
for (size_t oc= objects.count(), oi= 0; oi < oc && ok; oi++)
652
for (size_t sc= struct_names.count(), si= 0; si < sc && ok; si++)
654
if (!objects[oi].is_instance(struct_names[si]))
663
plist.push_back(plugin);
672
****************************************************************************
673
* @brief Returns list of plugins in the named group.
677
* @return List of plugins
679
****************************************************************************
681
std::vector<app_PluginRef> PluginManagerImpl::get_plugins_for_group(const std::string &group)
683
std::vector<app_PluginRef> rlist;
684
grt::ListRef<app_Plugin> list= get_plugin_list(group);
686
for (size_t c= list.count(), i= 0; i < c; i++)
687
rlist.push_back(list[i]);
694
****************************************************************************
695
* @brief Return named plugin
700
****************************************************************************
702
app_PluginRef PluginManagerImpl::get_plugin(const std::string &name)
704
grt::ListRef<app_Plugin> plugins= get_plugin_list();
706
for (size_t c= plugins.count(), i= 0; i < c; i++)
708
if (*plugins[i]->name() == name)
711
return app_PluginRef();
715
static std::string make_open_plugin_id(const grt::Module *module,
716
const std::string &class_name,
717
const grt::BaseListRef &args)
719
std::string argshash= get_args_hash(args);
721
return module->name()+"/"+class_name+"//"+argshash;
727
std::vector<NativeHandle> PluginManagerImpl::get_similar_open_plugins(grt::Module *module, const std::string &class_name, grt::BaseListRef)
729
std::vector<NativeHandle> handles;
731
std::string prefix= module->name()+"/"+class_name+"//";
733
for (std::map<std::string, NativeHandle>::const_iterator iter= _open_gui_plugins.begin();
734
iter != _open_gui_plugins.end(); ++iter)
736
if (iter->first.substr(0, prefix.size()) == prefix)
737
handles.push_back(iter->second);
745
std::string PluginManagerImpl::open_gui_plugin(const app_PluginRef &plugin, const grt::BaseListRef &args, GUIPluginFlags flags)
747
if (!plugin.is_valid())
748
throw std::invalid_argument("Attempt to open an invalid plugin");
750
if (*plugin->pluginType() == GUI_PLUGIN_TYPE)
752
if (_grtm->in_main_thread())
753
return open_gui_plugin_main(plugin, args, flags);
756
GRTDispatcher *disp= _grtm->get_dispatcher();
758
// request the plugin to be executed and opened by the frontend in the main thread
759
DispatcherCallback<std::string> *cb= new DispatcherCallback<std::string>(boost::bind(&PluginManagerImpl::open_gui_plugin_main,this,
760
plugin, args, flags));
762
disp->call_from_main_thread(cb, false, false);
766
grt::Module *module= _grtm->get_grt()->get_module(_plugin_source_module[plugin->name()]);
767
// build the handle name ourselves
768
return make_open_plugin_id(module, plugin->moduleFunctionName(), args);
771
else if (*plugin->pluginType() == STANDALONE_GUI_PLUGIN_TYPE)
773
if (_grtm->in_main_thread())
774
open_standalone_plugin_main(plugin, args);
777
GRTDispatcher *disp= _grtm->get_dispatcher();
779
// request the plugin to be executed and opened by the frontend in the main thread
780
DispatcherCallback<void> *cb= new DispatcherCallback<void>(boost::bind(&PluginManagerImpl::open_standalone_plugin_main, this,
783
disp->call_from_main_thread(cb, false, false);
788
else if (*plugin->pluginType() == INTERNAL_PLUGIN_TYPE)
790
if (_grtm->in_main_thread())
791
open_normal_plugin_grt(_grtm->get_grt(), plugin, args);
794
GRTDispatcher *disp= _grtm->get_dispatcher();
796
// request the plugin to be executed and opened by the frontend in the main thread
797
DispatcherCallback<grt::ValueRef> *cb= new DispatcherCallback<grt::ValueRef>(boost::bind(&PluginManagerImpl::open_normal_plugin_grt, this,
798
_grtm->get_grt(), plugin, args));
800
disp->call_from_main_thread(cb, false, false);
805
else // a normal plugin implemented by a GRT module
807
if (_grtm->in_main_thread())
809
_grtm->get_dispatcher()->execute_simple_function("Open normal plugin",
810
boost::bind(&PluginManagerImpl::open_normal_plugin_grt, this, _1, plugin, args));
813
open_normal_plugin_grt(_grtm->get_grt(), plugin, args);
820
****************************************************************************
821
* @brief Executes the plugin with the given list of arguments
823
* If the plugin is a GUI type plugin, the GUI plugin callbacks are executed
824
* in the main thread and may return a handle to pass back to the frontend
827
* If the plugin is a normal type plugin, it will be just executed in the
828
* GRT thread, as usual.
830
* @param plugin object
831
* @param args list of
833
* @return An identifier/handle for the opened plugin, if it's a GUI plugin
834
* or "" for other types of plugins.
835
****************************************************************************
837
std::string PluginManagerImpl::open_plugin(const app_PluginRef &plugin, const grt::BaseListRef &args)
839
return open_gui_plugin(plugin, args, NoFlags);
843
grt::ValueRef PluginManagerImpl::execute_plugin_function(const app_PluginRef &plugin, const grt::BaseListRef &args)
845
grt::Module *module= _grtm->get_grt()->get_module(plugin->moduleName());
848
throw grt::grt_runtime_error("Cannot execute plugin "+*plugin->name(), "Called module "+*plugin->moduleName()+" not found");
850
return module->call_function(*plugin->moduleFunctionName(), args);
853
grt::ValueRef PluginManagerImpl::open_normal_plugin_grt(grt::GRT *grt, const app_PluginRef &plugin,
854
const grt::BaseListRef &args)
856
grt::Module *module= _grtm->get_grt()->get_module(plugin->moduleName());
859
throw grt::grt_runtime_error("Cannot execute plugin "+*plugin->name(), "Called module "+*plugin->moduleName()+" not found");
861
return module->call_function(*plugin->moduleFunctionName(), args);
865
void PluginManagerImpl::open_standalone_plugin_main(const app_PluginRef &plugin, const grt::BaseListRef &args)
867
grt::Module *module= _grtm->get_grt()->get_module(plugin->moduleName());
870
throw grt::grt_runtime_error("Cannot execute plugin "+*plugin->name(), "Called module "+*plugin->moduleName()+" not found");
872
module->call_function(*plugin->moduleFunctionName(), args);
877
std::string PluginManagerImpl::open_gui_plugin_main(const app_PluginRef &plugin,
878
const grt::BaseListRef &args,
879
GUIPluginFlags flags)
882
grt::Module *module= _grtm->get_grt()->get_module(_plugin_source_module[plugin->name()]);
883
std::string open_plugin_id= make_open_plugin_id(module, plugin->moduleFunctionName(), args);
885
if (_open_gui_plugins.find(open_plugin_id) != _open_gui_plugins.end())
887
handle= _open_gui_plugins[open_plugin_id];
888
_show_gui_plugin_slot(handle);
892
grt::Module *module= _grtm->get_grt()->get_module(_plugin_source_module[plugin->name()]);
894
// open the editor and get a handle for the GUI object to pass to the frontend
895
NativeHandle handle= _open_gui_plugin_slot(_grtm,
897
*plugin->moduleName(),
898
*plugin->moduleFunctionName(),
903
_open_gui_plugins[open_plugin_id]= handle;
904
_show_gui_plugin_slot(handle);
908
return open_plugin_id;
914
****************************************************************************
915
* @brief Shows a previously opened (GUI) plugin.
917
* @param handle returned by open_plugin
919
* @return always 0 at the moment
920
****************************************************************************
922
int PluginManagerImpl::show_plugin(const std::string &handle)
924
if (_grtm->in_main_thread())
925
return show_gui_plugin_main(handle);
928
GRTDispatcher *disp= _grtm->get_dispatcher();
929
// request the plugin to be executed and opened by the frontend in the main thread
931
DispatcherCallback<int> *cb= new DispatcherCallback<int>(boost::bind(&PluginManagerImpl::show_gui_plugin_main, this, handle));
933
disp->call_from_main_thread(cb, false, false);
937
// return value is ignored atm.
944
int PluginManagerImpl::show_gui_plugin_main(const std::string &handle)
946
if (_open_gui_plugins.find(handle) != _open_gui_plugins.end())
948
NativeHandle hdl= _open_gui_plugins[handle];
949
_show_gui_plugin_slot(hdl);
959
****************************************************************************
960
* @brief Closes a previously opened (GUI) plugin.
962
* @param handle return by open_plugin
964
* @return always 0 at the moment
965
****************************************************************************
967
int PluginManagerImpl::close_plugin(const std::string &handle)
969
if (_grtm->in_main_thread())
970
return close_gui_plugin_main(handle);
973
GRTDispatcher *disp= _grtm->get_dispatcher();
974
// request the plugin to be executed and opened by the frontend in the main thread
976
DispatcherCallback<int> *cb= new DispatcherCallback<int>(boost::bind(&PluginManagerImpl::close_gui_plugin_main, this, handle));
978
disp->call_from_main_thread(cb, false, false);
982
// return value is ignored atm.
988
//--------------------------------------------------------------------------------------------------
990
int PluginManagerImpl::close_gui_plugin_main(const std::string &handle)
992
if (_open_gui_plugins.find(handle) != _open_gui_plugins.end())
994
NativeHandle hdl= _open_gui_plugins[handle];
995
_close_gui_plugin_slot(hdl);
1001
//--------------------------------------------------------------------------------------------------
1003
void PluginManagerImpl::forget_gui_plugin_handle(NativeHandle handle)
1005
for (std::map<std::string,NativeHandle>::iterator iter= _open_gui_plugins.begin();
1006
iter != _open_gui_plugins.end(); ++iter)
1008
if (iter->second == handle)
1010
_open_gui_plugins.erase(iter);
1016
//--------------------------------------------------------------------------------------------------
1018
void PluginManagerImpl::close_and_forget_gui_plugin(NativeHandle handle)
1020
for (std::map<std::string,NativeHandle>::iterator iter= _open_gui_plugins.begin();
1021
iter != _open_gui_plugins.end(); ++iter)
1023
if (iter->second == handle)
1025
_close_gui_plugin_slot(handle);
1026
_open_gui_plugins.erase(iter);
1033
//--------------------------------------------------------------------------------------------------
1035
grt::ValueRef ArgumentPool::find_match(const app_PluginInputDefinitionRef &pdef, std::string &searched_key_name_ret, bool strict) const
1037
std::string key = pdef.class_name();
1039
if (pdef.class_name() == app_PluginSelectionInput::static_class_name())
1041
app_PluginSelectionInputRef sdef(app_PluginSelectionInputRef::cast_from(pdef));
1044
key.append(":").append(*pdef->name()).append(":");
1045
searched_key_name_ret= key;
1048
const_iterator iter;
1049
if ((iter= find(key)) == end())
1050
return grt::ValueRef();
1052
if (!iter->second.is_valid() || !grt::ObjectListRef::can_wrap(iter->second))
1053
return grt::ValueRef();
1055
grt::ObjectListRef olist(grt::ObjectListRef::cast_from(iter->second));
1059
// check if value matches the requirements
1060
for (size_t d= olist.count(), j= 0; j < d; j++)
1062
grt::ObjectRef value(olist.get(j));
1065
for (size_t c= sdef->objectStructNames().count(), i= 0; i < c; i++)
1067
if (value.is_instance(sdef->objectStructNames()[i]))
1080
std::string card= *sdef->argumentCardinality();
1083
if (olist.count() != 1)
1086
else if (card == "?")
1088
if (olist.count() > 1)
1091
else if (card == "+")
1093
if (olist.count() == 0)
1096
else if (card == "*")
1100
if (olist.count() != 1)
1109
if (pdef.class_name() == app_PluginObjectInput::static_class_name())
1110
key.append(":").append(*pdef->name()).append(":").append(*app_PluginObjectInputRef::cast_from(pdef)->objectStructName());
1111
else if (pdef.class_name() == app_PluginFileInput::static_class_name())
1114
key.append(":").append(*pdef->name()).append(":").append(app_PluginFileInputRef::cast_from(pdef)->dialogType());
1116
key.append(":").append(":").append(app_PluginFileInputRef::cast_from(pdef)->dialogType());
1118
else if (pdef.class_name() == app_PluginInputDefinition::static_class_name())
1119
key.append(":").append(*pdef->name());
1121
searched_key_name_ret= key;
1123
const_iterator iter;
1124
if ((iter= find(key)) != end())
1125
return iter->second;
1128
return grt::ValueRef();
1131
void ArgumentPool::dump_keys(const boost::function<void (std::string)> &dump_function) const
1133
for (ArgumentPool::const_iterator i= begin(); i != end(); ++i)
1136
dump_function(i->first+"\n");
1138
g_message("%s", i->first.c_str());
1142
void ArgumentPool::add_simple_value(const std::string &name, const grt::ValueRef &value)
1144
std::string prefix= "app.PluginInputDefinition:"+name;
1146
(*this)[prefix]= value;
1149
void ArgumentPool::add_list_for_selection(const std::string &source_name,
1150
const grt::ObjectListRef &list)
1152
std::string prefix= "app.PluginSelectionInput:"+source_name+":";
1154
(*this)[prefix]= list;
1158
void ArgumentPool::add_entries_for_object(const std::string &name,
1159
const grt::ObjectRef &object,
1160
const std::string &topmost_class_name)
1162
if (object.is_valid())
1164
grt::GRT *grt= object.get_grt();
1165
std::string prefix= "app.PluginObjectInput:"+name+":";
1166
std::string class_name= object.class_name();
1170
grt::MetaClass *mc= grt->get_metaclass(class_name);
1171
(*this)[prefix+mc->name()]= object;
1173
class_name = mc->parent() ? mc->parent()->name() : "";
1174
if (topmost_class_name.empty() || class_name.empty() || done)
1176
if (topmost_class_name == class_name)
1182
bool ArgumentPool::needs_simple_input(const app_PluginRef &plugin, const std::string &name)
1184
const size_t c= plugin->inputValues().count();
1185
for (size_t i= 0; i < c; i++)
1187
app_PluginInputDefinitionRef pdef(plugin->inputValues().get(i));
1189
if (pdef.class_name() == app_PluginInputDefinition::static_class_name())
1191
if (pdef->name() == name)
1198
app_PluginFileInputRef ArgumentPool::needs_file_input(const app_PluginRef &plugin)
1200
const size_t c= plugin->inputValues().count();
1201
for (size_t i= 0; i < c; i++)
1203
app_PluginInputDefinitionRef pdef(plugin->inputValues().get(i));
1205
if (pdef.is_instance(app_PluginFileInput::static_class_name()))
1206
return app_PluginFileInputRef::cast_from(pdef);
1208
return app_PluginFileInputRef();
1211
void ArgumentPool::add_file_input(const app_PluginFileInputRef &pdef,
1212
const std::string &value)
1214
std::string key = app_PluginFileInput::static_class_name();
1215
key.append(":").append(*pdef->name()).append(":").append(pdef->dialogType());
1217
(*this)[key]= grt::StringRef(value);
1220
grt::BaseListRef ArgumentPool::build_argument_list(const app_PluginRef &plugin)
1222
// build the argument list
1223
grt::BaseListRef fargs(plugin->get_grt());
1225
const size_t c= plugin->inputValues().count();
1226
for (size_t i= 0; i < c; i++)
1228
app_PluginInputDefinitionRef pdef(plugin->inputValues().get(i));
1229
std::string searched_key;
1230
grt::ValueRef argument= find_match(pdef, searched_key);
1231
if (!argument.is_valid())
1233
g_message("Cannot satisfy plugin input for %s: %s", plugin->name().c_str(), searched_key.c_str());
1234
g_message("Missing input: %s", pdef.repr().c_str());
1236
throw grt::grt_runtime_error("Cannot execute "+*plugin->name(),
1237
"Plugin requires unavailable argument value.");
1239
fargs.ginsert(argument);