From 60f87acd9512ffd6b81363dfa0374beb082ebbfc Mon Sep 17 00:00:00 2001 From: tedjk Date: Thu, 12 Mar 2015 12:14:03 +0100 Subject: [PATCH] BAB-48 BAB-49 #resolve #comment can add menu elements from plugins now #time 7h --- juci/.#keybindings.cc | 1 + juci/api.cc | 135 ++++++++++++++++++++++++++++++---------- juci/api.h | 26 +++++++- juci/api_ext.cc | 2 + juci/menu.cc | 2 +- juci/plugins.py | 20 ++++++ juci/plugins/plugins.py | 22 ++++--- juci/plugins/snippet.py | 26 ++++++-- juci/window.cc | 31 +++++---- 9 files changed, 204 insertions(+), 61 deletions(-) create mode 120000 juci/.#keybindings.cc create mode 100644 juci/plugins.py diff --git a/juci/.#keybindings.cc b/juci/.#keybindings.cc new file mode 120000 index 0000000..16e3c07 --- /dev/null +++ b/juci/.#keybindings.cc @@ -0,0 +1 @@ +forgie@surface.2943:1426063539 \ No newline at end of file diff --git a/juci/api.cc b/juci/api.cc index a6c2931..1f3b7cb 100644 --- a/juci/api.cc +++ b/juci/api.cc @@ -45,18 +45,11 @@ std::string libjuci::ApiServiceProvider::GetWord() { } void libjuci::ApiServiceProvider::AddKeybinding() { - - libjuci::ApiServiceProvider::menu_->keybindings_.action_group_menu() - ->add(Gtk::Action::create("PluginSnippet", "Snippet")); + libjuci::LoadPlugin(g_project_root+"plugins.py"); - libjuci::ApiServiceProvider::menu_->keybindings_.action_group_menu() - ->add(Gtk::Action::create("PluginAddSnippet", - "Add snippet"), - Gtk::AccelKey("space"), - []() { - libjuci::LoadPlugin("snippet"); - }); - + // libjuci::AddMenuElement("Snippet"); + // libjuci::AddMenuElement("Bobby"); + //TODO forgie: update views } @@ -74,62 +67,133 @@ void libjuci::ReplaceLine(const std::string line) { << std::endl; } std::string libjuci::GetWord() { - // boost::python::str converted(libjuci::ApiServiceProvider::GetWord() ); return libjuci::ApiServiceProvider::GetWord(); - // return converted; } void libjuci::AddMenuElement(std::string plugin_name){ - libjuci::EditUiString(plugin_name); - + libjuci::AddMenuXml(plugin_name, "PluginMenu"); + std::string plugin_action_name = plugin_name+"Menu"; + libjuci::ApiServiceProvider::menu_->keybindings_.action_group_menu() - ->add(Gtk::Action::create("Plugin"+plugin_name, plugin_name)); - /* + ->add(Gtk::Action::create(plugin_action_name, plugin_name)); +} + +void libjuci::AddSubMenuElement(std::string parent_menu, + std::string menu_name, + std::string menu_func_name, + std::string plugin_path, + std::string menu_keybinding) { + + libjuci::AddSubMenuXml(menu_func_name, parent_menu); + libjuci::ApiServiceProvider::menu_->keybindings_.action_group_menu() - ->add(Gtk::Action::create("PluginAdd"+plugin_name, - "Add snippet"), - Gtk::AccelKey("space"), - []() { - libjuci::LoadPlugin("snippet"); - });*/ + ->add(Gtk::Action::create(menu_func_name, + menu_name), + Gtk::AccelKey(menu_keybinding), + [=]() { + libjuci::LoadPluginFunction(menu_func_name, plugin_path); + }); } -void libjuci::EditUiString(std::string plugin_name){ +void libjuci::AddMenuXml(std::string plugin_name, std::string parent_menu) { + std::string temp_menu = libjuci::ApiServiceProvider::menu_ ->keybindings_.model_.menu_ui_string(); - std::size_t plugin_menu_pos = temp_menu.find("PluginMenu"); + std::size_t plugin_menu_pos = temp_menu.find(parent_menu); + // +2 gets you outside of the tag:<'menu_name'> ref: keybindings.cc + plugin_menu_pos+=parent_menu.size() +2; std::string menu_prefix = temp_menu.substr(0, plugin_menu_pos); std::string menu_suffix = temp_menu.substr(plugin_menu_pos); + std::string menu_input = - " " + " " // " " " "; + libjuci::ApiServiceProvider::menu_->keybindings_.model_.menu_ui_string_ = + menu_prefix + menu_input + menu_suffix; +} + +void libjuci::AddSubMenuXml(std::string plugin_name, std::string parent_menu){ + std::string temp_menu = libjuci::ApiServiceProvider::menu_ + ->keybindings_.model_.menu_ui_string(); + + std::size_t parent_menu_pos = temp_menu.find(parent_menu); + // +2 gets you outside of the tag:<'menu_name'> ref: keybindings.cc + parent_menu_pos+=parent_menu.size() +2; + std::string menu_prefix = temp_menu.substr(0, parent_menu_pos); + std::string menu_suffix = temp_menu.substr(parent_menu_pos); + + std::string menu_input = + " "; + + libjuci::ApiServiceProvider::menu_->keybindings_.model_.menu_ui_string_ = menu_prefix + menu_input + menu_suffix; + std::cout << libjuci::ApiServiceProvider::menu_ + ->keybindings_.model_.menu_ui_string_ << std::endl; } ////////////////////////////// //// Boost.Python methods //// ////////////////////////////// -boost::python::api::object libjuci::openPythonScript(const std::string path, +boost::python::api::object libjuci::OpenPythonScript(const std::string path, boost::python::api::object python_name_space) { - std::string temp = g_project_root + path + ".py"; - boost::python::str the_path(temp); - return boost::python::exec_file(the_path, python_name_space);//, python_name_space); + boost::python::str str_path(path); + return boost::python::exec_file(str_path, python_name_space);//, python_name_space); } void libjuci::LoadPlugin(const std::string& plugin_name) { + std::cout << "libjuci::LoadPlugin " << plugin_name << std::endl; + try{ + Py_Initialize(); + boost::python::api::object main_module = boost::python::import("__main__"); + boost::python::api::object main_namespace = + main_module.attr("__dict__"); + boost::python::api::object ignored2 = + OpenPythonScript(plugin_name, main_namespace); + + }catch(boost::python::error_already_set const&) { + PyErr_Print(); + } +} + +void libjuci::LoadPluginFunction(const std::string &function_name, + const std::string &plugin_path){ + try{ + Py_Initialize(); + boost::python::api::object main_module = boost::python::import("__main__"); + boost::python::api::object main_namespace = main_module.attr("__dict__"); + boost::python::api::object ignored2 = OpenPythonScript(plugin_path, + main_namespace); + + boost::python::str func_name(function_name); + // for extracting return value from python: + boost::python::object returnValue = boost::python::eval(func_name, + main_namespace); + //std::string return_value = boost::python::extract(pySnippet); + //do something with return_value + }catch(boost::python::error_already_set const&) { + PyErr_Print(); + } + + //std::cout << __func__ << " - " << function_name << std::endl; +} + +void libjuci::InitPlugin(const std::string& plugin_path) { + std::cout << "libjuci::InitPlugin " << plugin_path << std::endl; try{ Py_Initialize(); boost::python::api::object main_module = boost::python::import("__main__"); boost::python::api::object main_namespace = main_module.attr("__dict__"); - boost::python::api::object ignored2 = openPythonScript(plugin_name, main_namespace); + boost::python::api::object ignored2 = OpenPythonScript(plugin_path, + main_namespace); /* for extracting return value from python: */ - //boost::python::object returnValue = boost::python::eval("function_name()", main_namespace); + boost::python::object returnValue = boost::python::eval("initPlugin()", + main_namespace); //std::string return_value = boost::python::extract(pySnippet); //do something with return_value }catch(boost::python::error_already_set const&) { @@ -159,10 +223,13 @@ void libjuci::IterToWordEnd(Gtk::TextIter &iter) { Glib::RefPtr libjuci::BufferFromNotebook() { //finding focused view int i = 0; - while(!libjuci::ApiServiceProvider::notebook_->source_vec_.at(i)->view().has_focus()) { + while(!libjuci::ApiServiceProvider::notebook_->source_vec_.at(i) + ->view().has_focus()) { i++; } - return Glib::RefPtr(libjuci::ApiServiceProvider::notebook_->source_vec_.at(i)->view().get_buffer()); + return Glib::RefPtr(libjuci::ApiServiceProvider::notebook_ + ->source_vec_.at(i) + ->view().get_buffer()); } Gtk::TextIter libjuci::IterFromNotebook() { diff --git a/juci/api.h b/juci/api.h index 84e9677..0bf08ae 100644 --- a/juci/api.h +++ b/juci/api.h @@ -14,7 +14,7 @@ namespace libjuci { ///////////////////////////// //// API ServiceProvider //// ///////////////////////////// - struct ApiServiceProvider { + class ApiServiceProvider { public: static std::shared_ptr menu_; static std::shared_ptr notebook_; @@ -27,6 +27,12 @@ namespace libjuci { static std::string GetWord(); static void ReplaceWord(const std::string word); static void ReplaceLine(const std::string line); + static void AddMenuElement(const std::string plugin_name); + static void AddSubMenuElement(const std::string parent_menu, + const std::string menu_name, + const std::string menu_func_name, + const std::string plugin_path, + const std::string menu_keybinding); }; /////////////////////// @@ -46,15 +52,29 @@ namespace libjuci { std::string GetWord(); void AddMenuElement(const std::string plugin_name); - void EditUiString(const std::string plugin_name); + + void AddSubMenuElement(const std::string parent_menu, + const std::string menu_name, + const std::string menu_func_name, + const std::string plugin_path, + const std::string menu_keybinding); + + void AddMenuXml(const std::string plugin_name, + const string parent_menu); + void AddSubMenuXml(const std::string plugin_name, + const string parent_menu); //TODO forgie: Make more functions targeting the python module ////////////////////////////// //// Boost.Python methods //// ////////////////////////////// - boost::python::api::object openPythonScript(const std::string path, + boost::python::api::object OpenPythonScript(const std::string path, boost::python::api::object python_name_space); void LoadPlugin(const std::string& plugin_name); + void LoadPluginFunction(const std::string &function_name, const std::string &plugin_path); + + void InitPlugin(const std::string& plugin_path); + }//libjuci #endif // JUCI_API_H diff --git a/juci/api_ext.cc b/juci/api_ext.cc index 09da044..e04bc11 100644 --- a/juci/api_ext.cc +++ b/juci/api_ext.cc @@ -4,7 +4,9 @@ BOOST_PYTHON_MODULE(juci_to_python_api) { using namespace boost::python; // plugin inclusion def("addMenuElement", &libjuci::AddMenuElement); + def("addSubMenuElement", &libjuci::AddSubMenuElement); def("loadPlugin", &libjuci::LoadPlugin); + def("initPlugin", &libjuci::InitPlugin); // text editing def("replaceLine", &libjuci::ReplaceLine); diff --git a/juci/menu.cc b/juci/menu.cc index 870f570..db504a4 100644 --- a/juci/menu.cc +++ b/juci/menu.cc @@ -55,7 +55,7 @@ Menu::Controller::Controller(Keybindings::Controller& keybindings) : [this]() { OnHelpAbout(); }); - keybindings_.BuildMenu(); + //keybindings_.BuildMenu(); // moved to window.cc keybindings_.BuildHiddenMenu(); } // Controller Gtk::Box &Menu::Controller::view() { diff --git a/juci/plugins.py b/juci/plugins.py new file mode 100644 index 0000000..9f4f39a --- /dev/null +++ b/juci/plugins.py @@ -0,0 +1,20 @@ +#!/usr/bin/python +#snippet plugin +import juci_to_python_api +import os +import glob + +def loadplugins(): + cwd = os.getcwd() + plugin_files = glob.glob(cwd+"/plugins/*.py") + for current_file in plugin_files: + (filepath, filename) = os.path.split(current_file) + (name, extension) = filename.split(".") + if filename != "plugins.py": + print(filename+" ("+current_file+") loading...") + #juci_to_python_api.loadPlugin(current_file) +# juci_to_python_api.addMenuElement(name.capitalize())#, current_file) + juci_to_python_api.initPlugin(current_file) + print(filename+" loaded...") + +loadplugins() diff --git a/juci/plugins/plugins.py b/juci/plugins/plugins.py index b5b4f1f..b5bbf4d 100644 --- a/juci/plugins/plugins.py +++ b/juci/plugins/plugins.py @@ -1,13 +1,19 @@ #!/usr/bin/python #snippet plugin import juci_to_python_api -import os, glob +import os +import glob -cwd = os.getcwd() +def loadplugins(): + cwd = os.getcwd() + plugin_files = glob.glob(cwd+"/plugins/*.py") + for current_file in plugin_files: + (filepath, filename) = os.path.split(current_file) + (name, extension) = filename.split(".") + print(filename+" ("+current_file+") loading...") + #juci_to_python_api.loadPlugin(current_file) +# juci_to_python_api.addMenuElement(name.capitalize())#, current_file) + juci_to_python_api.initPlugin(current_file) + print(filename+" loaded...") -plugins = glob.glob(cwd+"/*.py") -for current_file in plugins: - (filepath, filename) = os.path.split(current_file) - if filename != "plugins.py": - juci_to_python_api.loadPlugin(filename) - juci_to_python_api.addMenuElement(filename) +loadplugins() diff --git a/juci/plugins/snippet.py b/juci/plugins/snippet.py index 96c420c..4451424 100644 --- a/juci/plugins/snippet.py +++ b/juci/plugins/snippet.py @@ -1,18 +1,30 @@ #!/usr/bin/python #snippet plugin -import juci_to_python_api +import juci_to_python_api as juci +import inspect + +def initPlugin(): + juci.addMenuElement("Snippet") + juci.addSubMenuElement("SnippetMenu", #name of parent menu + "Insert snippet", #menu description + "insertSnippet()", #function to execute + inspect.getfile(inspect.currentframe()), + "space") snippets = {} + snippets["for"] = """\ for(#int i=0; #i<#v.size(); #i++) { std::cout << v[i] << std::endl; } """ + snippets["if"] = """\ if(#) { # } """ + snippets["ifelse"] = """\ if(#) { # @@ -20,16 +32,19 @@ if(#) { # } """ + snippets["while"] = """\ while(#) { # } """ + snippets["main"] = """\ int main(int argc, char *argv[]) { //Do something } """ + snippets["hello"] = """\ #include @@ -37,6 +52,7 @@ int main(int argc, char *argv[]) { std::cout << "Hello, world! << std::endl; } """ + def getSnippet(word): try: output = snippets[word] @@ -44,7 +60,9 @@ def getSnippet(word): output = word return output -theWord=juci_to_python_api.getWord() -output=getSnippet(theWord) +def insertSnippet(): + theWord=juci.getWord() + output=getSnippet(theWord) + juci.replaceWord(output) + -juci_to_python_api.replaceWord(output) diff --git a/juci/window.cc b/juci/window.cc index 2cab213..4ee9fbf 100644 --- a/juci/window.cc +++ b/juci/window.cc @@ -12,29 +12,38 @@ Window::Window() : [this]() { OnWindowHide(); }); - keybindings_.action_group_menu()->add(Gtk::Action::create("FileOpenFile", - Gtk::Stock::OPEN), - [this]() { - OnOpenFile(); - }); + keybindings_.action_group_menu()->add(Gtk::Action::create("FileOpenFile", + Gtk::Stock::OPEN), + [this]() { + OnOpenFile(); + }); + libjuci::ApiServiceProvider::menu_ = + std::shared_ptr(&menu_); + + libjuci::ApiServiceProvider::notebook_ = + std::shared_ptr(¬ebook_); - libjuci::ApiServiceProvider::menu_ = std::shared_ptr(&menu_); - libjuci::ApiServiceProvider::notebook_ = std::shared_ptr(¬ebook_); - libjuci::ApiServiceProvider::AddKeybinding(); + libjuci::ApiServiceProvider::AddKeybinding(); add_accel_group(keybindings_.ui_manager_menu()->get_accel_group()); add_accel_group(keybindings_.ui_manager_hidden()->get_accel_group()); - + + //moved here from menu.cc by forgie + keybindings_.BuildMenu(); + window_box_.pack_start(menu_.view(), Gtk::PACK_SHRINK); window_box_.pack_start(notebook_.entry_view(), Gtk::PACK_SHRINK); window_box_.pack_start(notebook_.view()); show_all_children(); } // Window constructor + void Window::OnWindowHide(){ //TODO forgie: find out how to 'remove' the pointers //TODO forgie: Make shared_ptr - libjuci::ApiServiceProvider::notebook_ = std::shared_ptr(nullptr); - libjuci::ApiServiceProvider::menu_ = std::shared_ptr(nullptr); + //libjuci::ApiServiceProvider::notebook_ = + // std::shared_ptr(nullptr); + // libjuci::ApiServiceProvider::menu_ = + // std::shared_ptr(nullptr); hide(); }