diff --git a/synfig-studio/src/gui/CMakeLists.txt b/synfig-studio/src/gui/CMakeLists.txt index 0ba29ba..220ddbc 100644 --- a/synfig-studio/src/gui/CMakeLists.txt +++ b/synfig-studio/src/gui/CMakeLists.txt @@ -43,6 +43,7 @@ target_sources(synfigstudio "${CMAKE_CURRENT_LIST_DIR}/ipc.cpp" "${CMAKE_CURRENT_LIST_DIR}/keymapsettings.cpp" "${CMAKE_CURRENT_LIST_DIR}/onemoment.cpp" + "${CMAKE_CURRENT_LIST_DIR}/pluginmanager.cpp" "${CMAKE_CURRENT_LIST_DIR}/preview.cpp" "${CMAKE_CURRENT_LIST_DIR}/renddesc.cpp" "${CMAKE_CURRENT_LIST_DIR}/render.cpp" diff --git a/synfig-studio/src/gui/Makefile.am b/synfig-studio/src/gui/Makefile.am index 989fd71..61ee7b9 100644 --- a/synfig-studio/src/gui/Makefile.am +++ b/synfig-studio/src/gui/Makefile.am @@ -52,6 +52,7 @@ OTHER_HH = \ ipc.h \ keymapsettings.h \ onemoment.h \ + pluginmanager.h \ preview.h \ renddesc.h \ render.h \ @@ -83,6 +84,7 @@ OTHER_CC = \ ipc.cpp \ keymapsettings.cpp \ onemoment.cpp \ + pluginmanager.cpp \ preview.cpp \ renddesc.cpp \ render.cpp \ diff --git a/synfig-studio/src/gui/app.cpp b/synfig-studio/src/gui/app.cpp index 211ef17..976edaa 100644 --- a/synfig-studio/src/gui/app.cpp +++ b/synfig-studio/src/gui/app.cpp @@ -313,7 +313,7 @@ int studio::App::preferred_y_size = 270; String studio::App::predefined_size (DEFAULT_PREDEFINED_SIZE); String studio::App::predefined_fps (DEFAULT_PREDEFINED_FPS); float studio::App::preferred_fps = 24.0; -synfigapp::PluginManager studio::App::plugin_manager; +PluginManager studio::App::plugin_manager; std::set< String > studio::App::brushes_path; String studio::App::image_editor_path; @@ -1203,12 +1203,12 @@ DEFINE_ACTION("keyframe-properties", _("Properties")); " " ; - list plugin_list = studio::App::plugin_manager.get_list(); - for(list::const_iterator p=plugin_list.begin();p!=plugin_list.end();++p) { + list plugin_list = studio::App::plugin_manager.get_list(); + for(list::const_iterator p=plugin_list.begin();p!=plugin_list.end();++p) { // TODO: (Plugins) Arrange menu items into groups - synfigapp::PluginManager::plugin plugin = *p; + PluginManager::plugin plugin = *p; DEFINE_ACTION(plugin.id, plugin.name); ui_info_menu += strprintf(" ", plugin.id.c_str()); diff --git a/synfig-studio/src/gui/app.h b/synfig-studio/src/gui/app.h index 60db59a..95d533a 100644 --- a/synfig-studio/src/gui/app.h +++ b/synfig-studio/src/gui/app.h @@ -47,7 +47,7 @@ #include #include #include -#include +#include "pluginmanager.h" #include "iconcontroller.h" #include "mainwindow.h" @@ -218,7 +218,7 @@ public: static bool use_dark_theme; static bool show_file_toolbar; - static synfigapp::PluginManager plugin_manager; + static PluginManager plugin_manager; static synfig::String image_editor_path; static std::set< synfig::String > brushes_path; static synfig::String custom_filename_prefix; diff --git a/synfig-studio/src/gui/pluginmanager.cpp b/synfig-studio/src/gui/pluginmanager.cpp new file mode 100644 index 0000000..6f88c06 --- /dev/null +++ b/synfig-studio/src/gui/pluginmanager.cpp @@ -0,0 +1,226 @@ +/* === S Y N F I G ========================================================= */ +/*! \file synfigapp/pluginmanager.cpp +** \brief Plugin Manager responsible for loading plugins +** +** $Id$ +** +** \legal +** Copyright (c) 2012-2013 Konstantin Dmitriev +** +** This package 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. +** +** This package 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. +** \endlegal +*/ +/* ========================================================================= */ + +/* === H E A D E R S ======================================================= */ + +#ifdef USING_PCH +# include "pch.h" +#else +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "pluginmanager.h" + +#include + +#include +#include + +#include +#include +#include +#include + +#include + +#endif + +/* === U S I N G =========================================================== */ + +using namespace std; +using namespace etl; +using namespace synfig; +using namespace studio; + +/* === M A C R O S ========================================================= */ + + +/* === G L O B A L S ======================================================= */ + +/* === M E T H O D S ======================================================= */ + +PluginManager::PluginManager(): + list_() +{ +} // END of synfigapp::PluginManager::PluginManager() + +void +PluginManager::load_dir( const std::string &pluginsprefix ) +{ + + synfig::info("Loading plugins from %s", pluginsprefix.c_str()); + + DIR *dir; + struct dirent *entry; + + dir = opendir(pluginsprefix.c_str()); + if(dir) { + while ( (entry = readdir(dir)) != NULL) { + if ( std::string(entry->d_name) != std::string(".") && std::string(entry->d_name) != std::string("..") ) { + std::string pluginpath; + pluginpath = pluginsprefix+ETL_DIRECTORY_SEPARATOR+entry->d_name; + struct stat sb; + stat(pluginpath.c_str(), &sb); + // error handling if stat failed + if (S_ISDIR(sb.st_mode)) { + // checking if directory contains a plugin... + DIR *plugindir; + struct dirent *plugindirentry; + + plugindir = opendir(pluginpath.c_str()); + if(plugindir) { + while ( (plugindirentry = readdir(plugindir)) != NULL) { + if ( std::string(plugindirentry->d_name) == std::string("plugin.xml") ){ + std::string pluginfilepath; + pluginfilepath = pluginpath+ETL_DIRECTORY_SEPARATOR+plugindirentry->d_name; + + load_plugin(pluginfilepath); + } + } + closedir(plugindir); + } + else + synfig::warning("Can't read plugin directory!"); + + /*plugindir = opendir(pluginpath.c_str()); + if(!plugindir) { + synfig::warning("Can't read plugin directory!"); + return; + } + + while ( (plugindirentry = readdir(plugindir)) != NULL) { + if ( std::string(plugindirentry->d_name) == std::string("plugin.xml") ){ + std::string pluginfilepath; + pluginfilepath = pluginpath+ETL_DIRECTORY_SEPARATOR+plugindirentry->d_name; + + load_plugin(pluginfilepath); + } + }*/ + + } + } + + }; + + closedir(dir); + } +} // END of synfigapp::PluginManager::load_dir() + +void +PluginManager::load_plugin( const std::string &path ) +{ + // Get locale + std::string current_locale = setlocale(LC_ALL, NULL); + + synfig::info(" Loading plugin: %s", basename(dirname(path)).c_str()); + + PluginManager::plugin p; + std::string plugindir = dirname(path); + p.id=plugindir; + + // parse xml file + try + { + xmlpp::DomParser parser; + //parser.set_validate(); + parser.set_substitute_entities(); //We just want the text to be resolved/unescaped automatically. + parser.parse_file(path); + if(parser) + { + //Walk the tree: + const xmlpp::Node* pNode = parser.get_document()->get_root_node(); //deleted by DomParser. + if ( std::string(pNode->get_name()) == std::string("plugin") ){ + //Recurse through child nodes: + xmlpp::Node::NodeList list = pNode->get_children(); + + unsigned int name_relevance = 0; + + for(xmlpp::Node::NodeList::iterator iter = list.begin(); iter != list.end(); ++iter) + { + const xmlpp::Node* node = *iter; + if ( std::string(node->get_name()) == std::string("name") ) { + + const xmlpp::Element* nodeElement = dynamic_cast(node); + + xmlpp::Node::NodeList l = nodeElement->get_children(); + xmlpp::Node::NodeList::iterator i = l.begin(); + xmlpp::Node* n = *i; + + const xmlpp::TextNode* nodeText = dynamic_cast(n); + + if(nodeText) + { + // Get the language attribute + const xmlpp::Attribute* langAttribute = nodeElement->get_attribute("lang", "xml"); + + if (langAttribute) { + // Element have language attribute, + std::string lang = langAttribute->get_value(); + // let's compare it with current locale + if (!current_locale.compare(0, lang.size(), lang)) { + if (lang.size() > name_relevance){ + p.name=nodeText->get_content(); + } + } + } else { + // Element have no language attribute - use as fallback + if (name_relevance == 0){ + p.name=nodeText->get_content(); + } + } + } + + } else if ( std::string(node->get_name()) == std::string("exec") ) { + + xmlpp::Node::NodeList l = node->get_children(); + xmlpp::Node::NodeList::iterator i = l.begin(); + xmlpp::Node* n = *i; + + const xmlpp::TextNode* nodeText = dynamic_cast(n); + + if(nodeText) + { + p.path=plugindir+ETL_DIRECTORY_SEPARATOR+nodeText->get_content(); + } + } + } + } else { + synfig::info("Invalid plugin.xml file."); + } + } + } + catch(const std::exception& ex) + { + std::cout << "Exception caught: " << ex.what() << std::endl; + } + + if ( p.id != "" && p.name != "" && p.path != ""){ + list_.push_back(p); + } else { + synfig::warning("Invalid plugin.xml file!"); + } +} + +PluginManager::~PluginManager() +{ +} diff --git a/synfig-studio/src/gui/pluginmanager.h b/synfig-studio/src/gui/pluginmanager.h new file mode 100644 index 0000000..e75ee16 --- /dev/null +++ b/synfig-studio/src/gui/pluginmanager.h @@ -0,0 +1,92 @@ +/* === S Y N F I G ========================================================= */ +/*! \file synfigapp/pluginmanager.h +** \brief Plugin Manager responsible for loading plugins +** +** $Id$ +** +** \legal +** Copyright (c) 2012-2013 Konstantin Dmitriev +** +** This package 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. +** +** This package 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. +** \endlegal +*/ +/* ========================================================================= */ + +/* === S T A R T =========================================================== */ + +#ifndef __SYNFIG_GTKMM_PLUGINMANAGER_H +#define __SYNFIG_GTKMM_PLUGINMANAGER_H + +/* === H E A D E R S ======================================================= */ + +#include +#include +#include +#include + +/* === M A C R O S ========================================================= */ + +/* === T Y P E D E F S ===================================================== */ + +/* === C L A S S E S & S T R U C T S ======================================= */ + +namespace studio { + +class PluginManager +{ + /* + -- ** -- P U B L I C T Y P E S --------------------------------------------- + */ + +public: + struct plugin{ + std::string id; + std::string name; + std::string path; + }; + + /* + -- ** -- P U B L I C D A T A ------------------------------------------------ + */ + +public: + + /* + -- ** -- P R I V A T E D A T A --------------------------------------------- + */ + +private: + + std::list< plugin > list_; + +protected: + + /* + -- ** -- P U B L I C M E T H O D S ----------------------------------------- + */ + +public: + PluginManager(); + ~PluginManager(); + + void load_dir( const std::string &pluginsprefix ); + void load_plugin( const std::string &path ); + + std::list< plugin > get_list() { return list_; }; + +}; // END class PluginManager + + +}; // END namespace synfigapp + +/* === E N D =============================================================== */ + +#endif diff --git a/synfig-studio/src/synfigapp/CMakeLists.txt b/synfig-studio/src/synfigapp/CMakeLists.txt index b060cad..1b449db 100644 --- a/synfig-studio/src/synfigapp/CMakeLists.txt +++ b/synfig-studio/src/synfigapp/CMakeLists.txt @@ -14,7 +14,6 @@ target_sources(synfigapp "${CMAKE_CURRENT_LIST_DIR}/inputdevice.cpp" "${CMAKE_CURRENT_LIST_DIR}/instance.cpp" "${CMAKE_CURRENT_LIST_DIR}/main.cpp" - "${CMAKE_CURRENT_LIST_DIR}/pluginmanager.cpp" "${CMAKE_CURRENT_LIST_DIR}/settings.cpp" "${CMAKE_CURRENT_LIST_DIR}/timegather.cpp" "${CMAKE_CURRENT_LIST_DIR}/uimanager.cpp" diff --git a/synfig-studio/src/synfigapp/Makefile.am b/synfig-studio/src/synfigapp/Makefile.am index 3229bd8..35e6266 100644 --- a/synfig-studio/src/synfigapp/Makefile.am +++ b/synfig-studio/src/synfigapp/Makefile.am @@ -324,7 +324,6 @@ SYNFIGAPPHH = \ inputdevice.h \ instance.h \ main.h \ - pluginmanager.h \ settings.h \ uimanager.h \ value_desc.h \ @@ -343,7 +342,6 @@ SYNFIGAPPCC = \ inputdevice.cpp \ instance.cpp \ main.cpp \ - pluginmanager.cpp \ settings.cpp \ uimanager.cpp \ value_desc.cpp diff --git a/synfig-studio/src/synfigapp/pluginmanager.cpp b/synfig-studio/src/synfigapp/pluginmanager.cpp deleted file mode 100644 index 962dd45..0000000 --- a/synfig-studio/src/synfigapp/pluginmanager.cpp +++ /dev/null @@ -1,226 +0,0 @@ -/* === S Y N F I G ========================================================= */ -/*! \file synfigapp/pluginmanager.cpp -** \brief Plugin Manager responsible for loading plugins -** -** $Id$ -** -** \legal -** Copyright (c) 2012-2013 Konstantin Dmitriev -** -** This package 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. -** -** This package 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. -** \endlegal -*/ -/* ========================================================================= */ - -/* === H E A D E R S ======================================================= */ - -#ifdef USING_PCH -# include "pch.h" -#else -#ifdef HAVE_CONFIG_H -# include -#endif - -#include "pluginmanager.h" - -#include - -#include -#include - -#include -#include -#include -#include - -#include - -#endif - -/* === U S I N G =========================================================== */ - -using namespace std; -using namespace etl; -using namespace synfig; -using namespace synfigapp; - -/* === M A C R O S ========================================================= */ - - -/* === G L O B A L S ======================================================= */ - -/* === M E T H O D S ======================================================= */ - -PluginManager::PluginManager(): - list_() -{ -} // END of synfigapp::PluginManager::PluginManager() - -void -PluginManager::load_dir( const std::string &pluginsprefix ) -{ - - synfig::info("Loading plugins from %s", pluginsprefix.c_str()); - - DIR *dir; - struct dirent *entry; - - dir = opendir(pluginsprefix.c_str()); - if(dir) { - while ( (entry = readdir(dir)) != NULL) { - if ( std::string(entry->d_name) != std::string(".") && std::string(entry->d_name) != std::string("..") ) { - std::string pluginpath; - pluginpath = pluginsprefix+ETL_DIRECTORY_SEPARATOR+entry->d_name; - struct stat sb; - stat(pluginpath.c_str(), &sb); - // error handling if stat failed - if (S_ISDIR(sb.st_mode)) { - // checking if directory contains a plugin... - DIR *plugindir; - struct dirent *plugindirentry; - - plugindir = opendir(pluginpath.c_str()); - if(plugindir) { - while ( (plugindirentry = readdir(plugindir)) != NULL) { - if ( std::string(plugindirentry->d_name) == std::string("plugin.xml") ){ - std::string pluginfilepath; - pluginfilepath = pluginpath+ETL_DIRECTORY_SEPARATOR+plugindirentry->d_name; - - load_plugin(pluginfilepath); - } - } - closedir(plugindir); - } - else - synfig::warning("Can't read plugin directory!"); - - /*plugindir = opendir(pluginpath.c_str()); - if(!plugindir) { - synfig::warning("Can't read plugin directory!"); - return; - } - - while ( (plugindirentry = readdir(plugindir)) != NULL) { - if ( std::string(plugindirentry->d_name) == std::string("plugin.xml") ){ - std::string pluginfilepath; - pluginfilepath = pluginpath+ETL_DIRECTORY_SEPARATOR+plugindirentry->d_name; - - load_plugin(pluginfilepath); - } - }*/ - - } - } - - }; - - closedir(dir); - } -} // END of synfigapp::PluginManager::load_dir() - -void -PluginManager::load_plugin( const std::string &path ) -{ - // Get locale - std::string current_locale = setlocale(LC_ALL, NULL); - - synfig::info(" Loading plugin: %s", basename(dirname(path)).c_str()); - - PluginManager::plugin p; - std::string plugindir = dirname(path); - p.id=plugindir; - - // parse xml file - try - { - xmlpp::DomParser parser; - //parser.set_validate(); - parser.set_substitute_entities(); //We just want the text to be resolved/unescaped automatically. - parser.parse_file(path); - if(parser) - { - //Walk the tree: - const xmlpp::Node* pNode = parser.get_document()->get_root_node(); //deleted by DomParser. - if ( std::string(pNode->get_name()) == std::string("plugin") ){ - //Recurse through child nodes: - xmlpp::Node::NodeList list = pNode->get_children(); - - unsigned int name_relevance = 0; - - for(xmlpp::Node::NodeList::iterator iter = list.begin(); iter != list.end(); ++iter) - { - const xmlpp::Node* node = *iter; - if ( std::string(node->get_name()) == std::string("name") ) { - - const xmlpp::Element* nodeElement = dynamic_cast(node); - - xmlpp::Node::NodeList l = nodeElement->get_children(); - xmlpp::Node::NodeList::iterator i = l.begin(); - xmlpp::Node* n = *i; - - const xmlpp::TextNode* nodeText = dynamic_cast(n); - - if(nodeText) - { - // Get the language attribute - const xmlpp::Attribute* langAttribute = nodeElement->get_attribute("lang", "xml"); - - if (langAttribute) { - // Element have language attribute, - std::string lang = langAttribute->get_value(); - // let's compare it with current locale - if (!current_locale.compare(0, lang.size(), lang)) { - if (lang.size() > name_relevance){ - p.name=nodeText->get_content(); - } - } - } else { - // Element have no language attribute - use as fallback - if (name_relevance == 0){ - p.name=nodeText->get_content(); - } - } - } - - } else if ( std::string(node->get_name()) == std::string("exec") ) { - - xmlpp::Node::NodeList l = node->get_children(); - xmlpp::Node::NodeList::iterator i = l.begin(); - xmlpp::Node* n = *i; - - const xmlpp::TextNode* nodeText = dynamic_cast(n); - - if(nodeText) - { - p.path=plugindir+ETL_DIRECTORY_SEPARATOR+nodeText->get_content(); - } - } - } - } else { - synfig::info("Invalid plugin.xml file."); - } - } - } - catch(const std::exception& ex) - { - std::cout << "Exception caught: " << ex.what() << std::endl; - } - - if ( p.id != "" && p.name != "" && p.path != ""){ - list_.push_back(p); - } else { - synfig::warning("Invalid plugin.xml file!"); - } -} - -PluginManager::~PluginManager() -{ -} diff --git a/synfig-studio/src/synfigapp/pluginmanager.h b/synfig-studio/src/synfigapp/pluginmanager.h deleted file mode 100644 index d6717be..0000000 --- a/synfig-studio/src/synfigapp/pluginmanager.h +++ /dev/null @@ -1,92 +0,0 @@ -/* === S Y N F I G ========================================================= */ -/*! \file synfigapp/pluginmanager.h -** \brief Plugin Manager responsible for loading plugins -** -** $Id$ -** -** \legal -** Copyright (c) 2012-2013 Konstantin Dmitriev -** -** This package 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. -** -** This package 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. -** \endlegal -*/ -/* ========================================================================= */ - -/* === S T A R T =========================================================== */ - -#ifndef __SYNFIG_APP_PLUGINMANAGER_H -#define __SYNFIG_APP_PLUGINMANAGER_H - -/* === H E A D E R S ======================================================= */ - -#include -#include -#include -#include - -/* === M A C R O S ========================================================= */ - -/* === T Y P E D E F S ===================================================== */ - -/* === C L A S S E S & S T R U C T S ======================================= */ - -namespace synfigapp { - -class PluginManager -{ - /* - -- ** -- P U B L I C T Y P E S --------------------------------------------- - */ - -public: - struct plugin{ - std::string id; - std::string name; - std::string path; - }; - - /* - -- ** -- P U B L I C D A T A ------------------------------------------------ - */ - -public: - - /* - -- ** -- P R I V A T E D A T A --------------------------------------------- - */ - -private: - - std::list< plugin > list_; - -protected: - - /* - -- ** -- P U B L I C M E T H O D S ----------------------------------------- - */ - -public: - PluginManager(); - ~PluginManager(); - - void load_dir( const std::string &pluginsprefix ); - void load_plugin( const std::string &path ); - - std::list< plugin > get_list() { return list_; }; - -}; // END class PluginManager - - -}; // END namespace synfigapp - -/* === E N D =============================================================== */ - -#endif