Browse Source

Work in progress: replacing the old menu system with the new standard menu system using native menues.

merge-requests/365/head
eidheim 10 years ago
parent
commit
1aceafa78a
  1. 16
      src/config.cc
  2. 23
      src/juci.cc
  3. 1
      src/juci.h
  4. 69
      src/menu.cc
  5. 9
      src/menu.h
  6. 14
      src/singletons.cc
  7. 4
      src/singletons.h
  8. 128
      src/window.cc
  9. 9
      src/window.h

16
src/config.cc

@ -52,7 +52,21 @@ void MainConfig::find_or_create_config_files() {
} }
void MainConfig::retrieve_config() { void MainConfig::retrieve_config() {
Singleton::Config::window()->keybindings = cfg.get_child("keybindings"); auto keybindings_pt = cfg.get_child("keybindings");
for (auto &i : keybindings_pt) {
auto key = i.second.get_value<std::string>();
size_t pos=0;
while((pos=key.find('<', pos))!=std::string::npos) {
key.replace(pos, 1, "&lt;");
pos+=4;
}
pos=0;
while((pos=key.find('>', pos))!=std::string::npos) {
key.replace(pos, 1, "&gt;");
pos+=4;
}
Singleton::Config::menu()->keys[i.first] = key;
}
GenerateSource(); GenerateSource();
GenerateDirectoryFilter(); GenerateDirectoryFilter();

23
src/juci.cc

@ -38,7 +38,6 @@ int app::on_command_line(const Glib::RefPtr<Gio::ApplicationCommandLine> &cmd) {
} }
void app::on_activate() { void app::on_activate() {
window = std::unique_ptr<Window>(new Window());
add_window(*window); add_window(*window);
window->show(); window->show();
bool first_directory=true; bool first_directory=true;
@ -68,8 +67,30 @@ void app::on_activate() {
window->notebook.open(file); window->notebook.open(file);
} }
void app::on_startup() {
Gtk::Application::on_startup();
Singleton::menu()->build();
auto object = Singleton::menu()->builder->get_object("juci-menu");
auto juci_menu = Glib::RefPtr<Gio::Menu>::cast_dynamic(object);
object = Singleton::menu()->builder->get_object("window-menu");
auto window_menu = Glib::RefPtr<Gio::Menu>::cast_dynamic(object);
if (!juci_menu || !window_menu) {
std::cerr << "Menu not found." << std::endl;
}
else {
set_app_menu(juci_menu);
set_menubar(window_menu);
}
window->set_menu_actions();
}
app::app() : Gtk::Application("no.sout.juci", Gio::APPLICATION_NON_UNIQUE | Gio::APPLICATION_HANDLES_COMMAND_LINE) { app::app() : Gtk::Application("no.sout.juci", Gio::APPLICATION_NON_UNIQUE | Gio::APPLICATION_HANDLES_COMMAND_LINE) {
Glib::set_application_name("juCi++");
window = std::unique_ptr<Window>(new Window());
} }
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {

1
src/juci.h

@ -9,6 +9,7 @@ class app : public Gtk::Application {
app(); app();
int on_command_line(const Glib::RefPtr<Gio::ApplicationCommandLine> &cmd); int on_command_line(const Glib::RefPtr<Gio::ApplicationCommandLine> &cmd);
void on_activate(); void on_activate();
void on_startup();
private: private:
std::unique_ptr<Window> window; std::unique_ptr<Window> window;

69
src/menu.cc

@ -1,8 +1,65 @@
#include "menu.h" #include "menu.h"
#include "singletons.h"
#include <string>
#include <iostream> #include <iostream>
using namespace std; //TODO: remove
Menu::Menu() { Menu::Menu() {
action_group = Gtk::ActionGroup::create(); auto &keys=Singleton::Config::menu()->keys;
ui_xml =
"<interface>"
" <menu id='juci-menu'>"
" <section>"
" <item>"
" <attribute name='label' translatable='yes'>_About</attribute>"
" <attribute name='action'>win.about</attribute>"
" </item>"
" </section>"
" <section>"
" <item>"
" <attribute name='label' translatable='yes'>_Preferences</attribute>"
" <attribute name='action'>win.preferences</attribute>"
" </item>"
" </section>"
" <section>"
" <item>"
" <attribute name='label' translatable='yes'>_Quit</attribute>"
" <attribute name='action'>win.quit</attribute>"
" <attribute name='accel'>"+keys["quit"]+"</attribute>"
" </item>"
" </section>"
" </menu>"
""
" <menu id='window-menu'>"
" <submenu>"
" <attribute name='label' translatable='yes'>_File</attribute>"
" <section>"
" <item>"
" <attribute name='label' translatable='yes'>_New _File</attribute>"
" <attribute name='action'>win.new_file</attribute>"
" </item>"
" <item>"
" <attribute name='label' translatable='yes'>_New _Directory</attribute>"
" <attribute name='action'>win.new_directory</attribute>"
" </item>"
" </section>"
" <section>"
" <item>"
" <attribute name='label' translatable='yes'>_Open _File</attribute>"
" <attribute name='action'>win.open_file</attribute>"
" </item>"
" <item>"
" <attribute name='label' translatable='yes'>_Open _Directory</attribute>"
" <attribute name='action'>win.open_directory</attribute>"
" </item>"
" </section>"
" </submenu>"
" </menu>"
"</interface>";
/*action_group = Gtk::ActionGroup::create();
ui_manager = Gtk::UIManager::create(); ui_manager = Gtk::UIManager::create();
ui_manager->insert_action_group(action_group); ui_manager->insert_action_group(action_group);
@ -89,18 +146,20 @@ Menu::Menu() {
" <menuitem action=\"HelpAbout\"/>\n" " <menuitem action=\"HelpAbout\"/>\n"
" </menu>\n" " </menu>\n"
" </menubar>\n" " </menubar>\n"
"</ui>\n"; "</ui>\n";*/
} }
Gtk::Widget& Menu::get_widget() { Gtk::Widget& Menu::get_widget() {
return *ui_manager->get_widget("/MenuBar"); //return *ui_manager->get_widget("/MenuBar");
} }
void Menu::build() { void Menu::build() {
builder = Gtk::Builder::create();
try { try {
ui_manager->add_ui_from_string(ui_xml); builder->add_from_string(ui_xml);
} }
catch (const Glib::Error &ex) { catch (const Glib::Error &ex) {
std::cerr << "building menu failed" << ex.what(); std::cerr << "building menu failed: " << ex.what();
} }
} }

9
src/menu.h

@ -7,13 +7,16 @@
class Menu { class Menu {
public: public:
class Config {
public:
std::unordered_map<std::string, std::string> keys;
};
Menu(); Menu();
Gtk::Widget& get_widget(); Gtk::Widget& get_widget();
void build(); void build();
std::unordered_map<std::string, std::string> key_map;
std::string ui_xml; std::string ui_xml;
Glib::RefPtr<Gtk::UIManager> ui_manager; Glib::RefPtr<Gtk::Builder> builder;
Glib::RefPtr<Gtk::ActionGroup> action_group;
}; };
#endif // JUCI_MENU_H_ #endif // JUCI_MENU_H_

14
src/singletons.cc

@ -4,29 +4,39 @@ std::unique_ptr<Source::Config> Singleton::Config::source_=std::unique_ptr<Sourc
std::unique_ptr<Directories::Config> Singleton::Config::directories_=std::unique_ptr<Directories::Config>(new Directories::Config()); std::unique_ptr<Directories::Config> Singleton::Config::directories_=std::unique_ptr<Directories::Config>(new Directories::Config());
std::unique_ptr<Terminal::Config> Singleton::Config::terminal_=std::unique_ptr<Terminal::Config>(new Terminal::Config()); std::unique_ptr<Terminal::Config> Singleton::Config::terminal_=std::unique_ptr<Terminal::Config>(new Terminal::Config());
std::unique_ptr<Window::Config> Singleton::Config::window_ = std::unique_ptr<Window::Config>(new Window::Config()); std::unique_ptr<Window::Config> Singleton::Config::window_ = std::unique_ptr<Window::Config>(new Window::Config());
std::unique_ptr<Terminal> Singleton::terminal_=std::unique_ptr<Terminal>(); std::unique_ptr<Menu::Config> Singleton::Config::menu_ = std::unique_ptr<Menu::Config>(new Menu::Config());
std::unique_ptr<Directories> Singleton::directories_=std::unique_ptr<Directories>();
std::unique_ptr<Terminal> Singleton::terminal_=std::unique_ptr<Terminal>();
Terminal *Singleton::terminal() { Terminal *Singleton::terminal() {
if(!terminal_) if(!terminal_)
terminal_=std::unique_ptr<Terminal>(new Terminal()); terminal_=std::unique_ptr<Terminal>(new Terminal());
return terminal_.get(); return terminal_.get();
} }
std::unique_ptr<Directories> Singleton::directories_=std::unique_ptr<Directories>();
Directories *Singleton::directories() { Directories *Singleton::directories() {
if(!directories_) if(!directories_)
directories_=std::unique_ptr<Directories>(new Directories()); directories_=std::unique_ptr<Directories>(new Directories());
return directories_.get(); return directories_.get();
} }
std::unique_ptr<Gtk::Label> Singleton::status_=std::unique_ptr<Gtk::Label>(); std::unique_ptr<Gtk::Label> Singleton::status_=std::unique_ptr<Gtk::Label>();
Gtk::Label *Singleton::status() { Gtk::Label *Singleton::status() {
if(!status_) if(!status_)
status_=std::unique_ptr<Gtk::Label>(new Gtk::Label()); status_=std::unique_ptr<Gtk::Label>(new Gtk::Label());
return status_.get(); return status_.get();
} }
std::unique_ptr<Gtk::Label> Singleton::info_=std::unique_ptr<Gtk::Label>(); std::unique_ptr<Gtk::Label> Singleton::info_=std::unique_ptr<Gtk::Label>();
Gtk::Label *Singleton::info() { Gtk::Label *Singleton::info() {
if(!info_) if(!info_)
info_=std::unique_ptr<Gtk::Label>(new Gtk::Label()); info_=std::unique_ptr<Gtk::Label>(new Gtk::Label());
return info_.get(); return info_.get();
} }
std::unique_ptr<Menu> Singleton::menu_=std::unique_ptr<Menu>();
Menu *Singleton::menu() {
if(!menu_)
menu_=std::unique_ptr<Menu>(new Menu());
return menu_.get();
}

4
src/singletons.h

@ -25,12 +25,14 @@ public:
static Directories::Config *directories() {return directories_.get();} static Directories::Config *directories() {return directories_.get();}
static Window::Config *window() { return window_.get(); } static Window::Config *window() { return window_.get(); }
static Terminal::Config *terminal() {return terminal_.get();} static Terminal::Config *terminal() {return terminal_.get();}
static Menu::Config *menu() {return menu_.get();}
private: private:
static std::unique_ptr<Source::Config> source_; static std::unique_ptr<Source::Config> source_;
static std::unique_ptr<Window::Config> window_; static std::unique_ptr<Window::Config> window_;
static std::unique_ptr<Directories::Config> directories_; static std::unique_ptr<Directories::Config> directories_;
static std::unique_ptr<Terminal::Config> terminal_; static std::unique_ptr<Terminal::Config> terminal_;
static std::unique_ptr<Menu::Config> menu_;
}; };
static std::string config_dir() { return std::string(getenv(HOME)) + "/.juci/config/"; } static std::string config_dir() { return std::string(getenv(HOME)) + "/.juci/config/"; }
static std::string log_dir() { return std::string(getenv(HOME)) + "/.juci/log/"; } static std::string log_dir() { return std::string(getenv(HOME)) + "/.juci/log/"; }
@ -39,11 +41,13 @@ public:
static Directories *directories(); static Directories *directories();
static Gtk::Label *status(); static Gtk::Label *status();
static Gtk::Label *info(); static Gtk::Label *info();
static Menu *menu();
private: private:
static std::unique_ptr<Terminal> terminal_; static std::unique_ptr<Terminal> terminal_;
static std::unique_ptr<Gtk::Label> status_; static std::unique_ptr<Gtk::Label> status_;
static std::unique_ptr<Gtk::Label> info_; static std::unique_ptr<Gtk::Label> info_;
static std::unique_ptr<Directories> directories_; static std::unique_ptr<Directories> directories_;
static std::unique_ptr<Menu> menu_;
}; };
#endif // JUCI_SINGLETONS_H_ #endif // JUCI_SINGLETONS_H_

128
src/window.cc

@ -23,14 +23,7 @@ namespace sigc {
#endif #endif
} }
void Window::generate_keybindings() { Window::Window() : compiling(false) {
for (auto &i : Singleton::Config::window()->keybindings) {
auto key = i.second.get_value<std::string>();
menu.key_map[i.first] = key;
}
}
Window::Window() : box(Gtk::ORIENTATION_VERTICAL), compiling(false) {
JDEBUG("start"); JDEBUG("start");
set_title("juCi++"); set_title("juCi++");
set_events(Gdk::POINTER_MOTION_MASK|Gdk::FOCUS_CHANGE_MASK|Gdk::SCROLL_MASK); set_events(Gdk::POINTER_MOTION_MASK|Gdk::FOCUS_CHANGE_MASK|Gdk::SCROLL_MASK);
@ -39,15 +32,6 @@ Window::Window() : box(Gtk::ORIENTATION_VERTICAL), compiling(false) {
//PluginApi(&this->notebook, &this->menu); //PluginApi(&this->notebook, &this->menu);
add(box);
//TODO: Do not use deprecated ui_manager? And make menu shortcuts update when config.json is saved (in configure())
generate_keybindings();
create_menu();
menu.build();
add_accel_group(menu.ui_manager->get_accel_group());
box.pack_start(menu.get_widget(), Gtk::PACK_SHRINK);
directory_and_notebook_panes.pack1(*Singleton::directories(), Gtk::SHRINK); directory_and_notebook_panes.pack1(*Singleton::directories(), Gtk::SHRINK);
notebook_vbox.pack_start(notebook); notebook_vbox.pack_start(notebook);
notebook_vbox.pack_end(entry_box, Gtk::PACK_SHRINK); notebook_vbox.pack_end(entry_box, Gtk::PACK_SHRINK);
@ -64,7 +48,7 @@ Window::Window() : box(Gtk::ORIENTATION_VERTICAL), compiling(false) {
terminal_vbox.pack_end(info_and_status_hbox, Gtk::PACK_SHRINK); terminal_vbox.pack_end(info_and_status_hbox, Gtk::PACK_SHRINK);
vpaned.pack2(terminal_vbox, true, true); vpaned.pack2(terminal_vbox, true, true);
box.pack_end(vpaned); add(vpaned);
show_all_children(); show_all_children();
Singleton::directories()->on_row_activated=[this](const std::string &file) { Singleton::directories()->on_row_activated=[this](const std::string &file) {
@ -79,13 +63,11 @@ Window::Window() : box(Gtk::ORIENTATION_VERTICAL), compiling(false) {
}); });
entry_box.signal_show().connect([this](){ entry_box.signal_show().connect([this](){
box.set_focus_chain({&vpaned});
vpaned.set_focus_chain({&directory_and_notebook_panes}); vpaned.set_focus_chain({&directory_and_notebook_panes});
directory_and_notebook_panes.set_focus_chain({&notebook_vbox}); directory_and_notebook_panes.set_focus_chain({&notebook_vbox});
notebook_vbox.set_focus_chain({&entry_box}); notebook_vbox.set_focus_chain({&entry_box});
}); });
entry_box.signal_hide().connect([this](){ entry_box.signal_hide().connect([this](){
box.unset_focus_chain();
vpaned.unset_focus_chain(); vpaned.unset_focus_chain();
directory_and_notebook_panes.unset_focus_chain(); directory_and_notebook_panes.unset_focus_chain();
notebook_vbox.unset_focus_chain(); notebook_vbox.unset_focus_chain();
@ -105,7 +87,7 @@ Window::Window() : box(Gtk::ORIENTATION_VERTICAL), compiling(false) {
notebook.get_current_view()->search_highlight(last_search, case_sensitive_search, regex_search); notebook.get_current_view()->search_highlight(last_search, case_sensitive_search, regex_search);
} }
if(auto menu_item=dynamic_cast<Gtk::MenuItem*>(menu.ui_manager->get_widget("/MenuBar/SourceMenu/SourceIndentation/SourceIndentationAutoIndentBuffer"))) /*if(auto menu_item=dynamic_cast<Gtk::MenuItem*>(menu.ui_manager->get_widget("/MenuBar/SourceMenu/SourceIndentation/SourceIndentationAutoIndentBuffer")))
menu_item->set_sensitive((bool)notebook.get_current_view()->auto_indent); menu_item->set_sensitive((bool)notebook.get_current_view()->auto_indent);
if(auto menu_item=dynamic_cast<Gtk::MenuItem*>(menu.ui_manager->get_widget("/MenuBar/SourceMenu/SourceGotoDeclaration"))) if(auto menu_item=dynamic_cast<Gtk::MenuItem*>(menu.ui_manager->get_widget("/MenuBar/SourceMenu/SourceGotoDeclaration")))
@ -124,7 +106,7 @@ Window::Window() : box(Gtk::ORIENTATION_VERTICAL), compiling(false) {
menu_item->set_sensitive((bool)notebook.get_current_view()->apply_fix_its); menu_item->set_sensitive((bool)notebook.get_current_view()->apply_fix_its);
if(auto menu_item=dynamic_cast<Gtk::MenuItem*>(menu.ui_manager->get_widget("/MenuBar/SourceMenu/SourceFindDocumentation"))) if(auto menu_item=dynamic_cast<Gtk::MenuItem*>(menu.ui_manager->get_widget("/MenuBar/SourceMenu/SourceFindDocumentation")))
menu_item->set_sensitive((bool)notebook.get_current_view()->get_token_data); menu_item->set_sensitive((bool)notebook.get_current_view()->get_token_data);*/
Singleton::directories()->select(notebook.get_current_view()->file_path); Singleton::directories()->select(notebook.get_current_view()->file_path);
@ -170,11 +152,39 @@ void Window::configure() {
style_context->add_provider_for_screen(screen, css_provider, GTK_STYLE_PROVIDER_PRIORITY_SETTINGS); style_context->add_provider_for_screen(screen, css_provider, GTK_STYLE_PROVIDER_PRIORITY_SETTINGS);
} }
void Window::create_menu() { void Window::set_menu_actions() {
menu.action_group->add(Gtk::Action::create("FileQuit", "Quit juCi++"), Gtk::AccelKey(menu.key_map["quit"]), [this]() {
add_action("quit", [this]() {
hide(); hide();
}); });
menu.action_group->add(Gtk::Action::create("FileNewFile", "New File"), Gtk::AccelKey(menu.key_map["new_file"]), [this]() {
auto action=add_action("new_file", [this]() {
boost::filesystem::path path = Dialog::new_file();
if(path!="") {
if(boost::filesystem::exists(path)) {
Singleton::terminal()->print("Error: "+path.string()+" already exists.\n");
}
else {
if(juci::filesystem::write(path)) {
if(Singleton::directories()->current_path!="")
Singleton::directories()->update();
notebook.open(path.string());
Singleton::terminal()->print("New file "+path.string()+" created.\n");
}
else
Singleton::terminal()->print("Error: could not create new file "+path.string()+".\n");
}
}
});
auto accel_group=get_accel_group();
auto accel_grp=Gtk::AccelGroup::create();
/*menu.action_group->add(Gtk::Action::create("FileQuit", "Quit juCi++"), Gtk::AccelKey(key_map["quit"]), [this]() {
hide();
});
menu.action_group->add(Gtk::Action::create("FileNewFile", "New File"), Gtk::AccelKey(key_map["new_file"]), [this]() {
boost::filesystem::path path = Dialog::new_file(); boost::filesystem::path path = Dialog::new_file();
if(path!="") { if(path!="") {
if(boost::filesystem::exists(path)) { if(boost::filesystem::exists(path)) {
@ -192,7 +202,7 @@ void Window::create_menu() {
} }
} }
}); });
menu.action_group->add(Gtk::Action::create("FileNewFolder", "New Folder"), Gtk::AccelKey(menu.key_map["new_folder"]), [this]() { menu.action_group->add(Gtk::Action::create("FileNewFolder", "New Folder"), Gtk::AccelKey(key_map["new_folder"]), [this]() {
auto time_now=std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); auto time_now=std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
boost::filesystem::path path = Dialog::new_folder(); boost::filesystem::path path = Dialog::new_folder();
if(path!="" && boost::filesystem::exists(path)) { if(path!="" && boost::filesystem::exists(path)) {
@ -238,17 +248,17 @@ void Window::create_menu() {
Singleton::terminal()->print("Error: Could not create project "+project_path.string()+"\n"); Singleton::terminal()->print("Error: Could not create project "+project_path.string()+"\n");
} }
}); });
menu.action_group->add(Gtk::Action::create("FileOpenFile", "Open File"), Gtk::AccelKey(menu.key_map["open_file"]), [this]() { menu.action_group->add(Gtk::Action::create("FileOpenFile", "Open File"), Gtk::AccelKey(key_map["open_file"]), [this]() {
auto path=Dialog::select_file(); auto path=Dialog::select_file();
if(path!="") if(path!="")
notebook.open(path); notebook.open(path);
}); });
menu.action_group->add(Gtk::Action::create("FileOpenFolder", "Open Folder"), Gtk::AccelKey(menu.key_map["open_folder"]), [this]() { menu.action_group->add(Gtk::Action::create("FileOpenFolder", "Open Folder"), Gtk::AccelKey(key_map["open_folder"]), [this]() {
auto path = Dialog::select_folder(); auto path = Dialog::select_folder();
if (path!="" && boost::filesystem::exists(path)) if (path!="" && boost::filesystem::exists(path))
Singleton::directories()->open(path); Singleton::directories()->open(path);
}); });
menu.action_group->add(Gtk::Action::create("FileSaveAs", "Save As"), Gtk::AccelKey(menu.key_map["save_as"]), [this]() { menu.action_group->add(Gtk::Action::create("FileSaveAs", "Save As"), Gtk::AccelKey(key_map["save_as"]), [this]() {
auto path = Dialog::save_file(); auto path = Dialog::save_file();
if(path!="") { if(path!="") {
std::ofstream file(path); std::ofstream file(path);
@ -264,11 +274,11 @@ void Window::create_menu() {
Singleton::terminal()->print("Error saving file\n"); Singleton::terminal()->print("Error saving file\n");
} }
}); });
menu.action_group->add(Gtk::Action::create("Preferences", "Preferences..."), Gtk::AccelKey(menu.key_map["preferences"]), [this]() { menu.action_group->add(Gtk::Action::create("Preferences", "Preferences..."), Gtk::AccelKey(key_map["preferences"]), [this]() {
notebook.open(Singleton::config_dir()+"config.json"); notebook.open(Singleton::config_dir()+"config.json");
}); });
menu.action_group->add(Gtk::Action::create("FileSave", "Save"), Gtk::AccelKey(menu.key_map["save"]), [this]() { menu.action_group->add(Gtk::Action::create("FileSave", "Save"), Gtk::AccelKey(key_map["save"]), [this]() {
if(notebook.save_current()) { if(notebook.save_current()) {
if(notebook.get_current_page()!=-1) { if(notebook.get_current_page()!=-1) {
if(notebook.get_current_view()->file_path==Singleton::config_dir()+"config.json") { if(notebook.get_current_view()->file_path==Singleton::config_dir()+"config.json") {
@ -282,31 +292,31 @@ void Window::create_menu() {
} }
}); });
menu.action_group->add(Gtk::Action::create("EditCopy", "Copy"), Gtk::AccelKey(menu.key_map["edit_copy"]), [this]() { menu.action_group->add(Gtk::Action::create("EditCopy", "Copy"), Gtk::AccelKey(key_map["edit_copy"]), [this]() {
auto widget=get_focus(); auto widget=get_focus();
if(auto entry=dynamic_cast<Gtk::Entry*>(widget)) if(auto entry=dynamic_cast<Gtk::Entry*>(widget))
entry->copy_clipboard(); entry->copy_clipboard();
else if(auto text_view=dynamic_cast<Gtk::TextView*>(widget)) else if(auto text_view=dynamic_cast<Gtk::TextView*>(widget))
text_view->get_buffer()->copy_clipboard(Gtk::Clipboard::get()); text_view->get_buffer()->copy_clipboard(Gtk::Clipboard::get());
}); });
menu.action_group->add(Gtk::Action::create("EditCut", "Cut"), Gtk::AccelKey(menu.key_map["edit_cut"]), [this]() { menu.action_group->add(Gtk::Action::create("EditCut", "Cut"), Gtk::AccelKey(key_map["edit_cut"]), [this]() {
auto widget=get_focus(); auto widget=get_focus();
if(auto entry=dynamic_cast<Gtk::Entry*>(widget)) if(auto entry=dynamic_cast<Gtk::Entry*>(widget))
entry->cut_clipboard(); entry->cut_clipboard();
else if(notebook.get_current_page()!=-1) else if(notebook.get_current_page()!=-1)
notebook.get_current_view()->get_buffer()->cut_clipboard(Gtk::Clipboard::get()); notebook.get_current_view()->get_buffer()->cut_clipboard(Gtk::Clipboard::get());
}); });
menu.action_group->add(Gtk::Action::create("EditPaste", "Paste"), Gtk::AccelKey(menu.key_map["edit_paste"]), [this]() { menu.action_group->add(Gtk::Action::create("EditPaste", "Paste"), Gtk::AccelKey(key_map["edit_paste"]), [this]() {
auto widget=get_focus(); auto widget=get_focus();
if(auto entry=dynamic_cast<Gtk::Entry*>(widget)) if(auto entry=dynamic_cast<Gtk::Entry*>(widget))
entry->paste_clipboard(); entry->paste_clipboard();
else if(notebook.get_current_page()!=-1) else if(notebook.get_current_page()!=-1)
notebook.get_current_view()->paste(); notebook.get_current_view()->paste();
}); });
menu.action_group->add(Gtk::Action::create("EditFind", "Find"), Gtk::AccelKey(menu.key_map["edit_find"]), [this]() { menu.action_group->add(Gtk::Action::create("EditFind", "Find"), Gtk::AccelKey(key_map["edit_find"]), [this]() {
search_and_replace_entry(); search_and_replace_entry();
}); });
menu.action_group->add(Gtk::Action::create("EditUndo", "Undo"), Gtk::AccelKey(menu.key_map["edit_undo"]), [this]() { menu.action_group->add(Gtk::Action::create("EditUndo", "Undo"), Gtk::AccelKey(key_map["edit_undo"]), [this]() {
if(notebook.get_current_page()!=-1) { if(notebook.get_current_page()!=-1) {
auto undo_manager = notebook.get_current_view()->get_source_buffer()->get_undo_manager(); auto undo_manager = notebook.get_current_view()->get_source_buffer()->get_undo_manager();
if (undo_manager->can_undo()) { if (undo_manager->can_undo()) {
@ -315,7 +325,7 @@ void Window::create_menu() {
} }
} }
}); });
menu.action_group->add(Gtk::Action::create("EditRedo", "Redo"), Gtk::AccelKey(menu.key_map["edit_redo"]), [this]() { menu.action_group->add(Gtk::Action::create("EditRedo", "Redo"), Gtk::AccelKey(key_map["edit_redo"]), [this]() {
if(notebook.get_current_page()!=-1) { if(notebook.get_current_page()!=-1) {
auto undo_manager = notebook.get_current_view()->get_source_buffer()->get_undo_manager(); auto undo_manager = notebook.get_current_view()->get_source_buffer()->get_undo_manager();
if(undo_manager->can_redo()) { if(undo_manager->can_redo()) {
@ -326,30 +336,30 @@ void Window::create_menu() {
}); });
menu.action_group->add(Gtk::Action::create("SourceSpellCheck", "Spell Check")); menu.action_group->add(Gtk::Action::create("SourceSpellCheck", "Spell Check"));
menu.action_group->add(Gtk::Action::create("SourceSpellCheckBuffer", "Spell Check Buffer"), Gtk::AccelKey(menu.key_map["source_spellcheck"]), [this]() { menu.action_group->add(Gtk::Action::create("SourceSpellCheckBuffer", "Spell Check Buffer"), Gtk::AccelKey(key_map["source_spellcheck"]), [this]() {
if(notebook.get_current_page()!=-1) if(notebook.get_current_page()!=-1)
notebook.get_current_view()->spellcheck(); notebook.get_current_view()->spellcheck();
}); });
menu.action_group->add(Gtk::Action::create("SourceSpellCheckClear", "Clear Spelling Errors"), Gtk::AccelKey(menu.key_map["source_spellcheck_clear"]), [this]() { menu.action_group->add(Gtk::Action::create("SourceSpellCheckClear", "Clear Spelling Errors"), Gtk::AccelKey(key_map["source_spellcheck_clear"]), [this]() {
if(notebook.get_current_page()!=-1) if(notebook.get_current_page()!=-1)
notebook.get_current_view()->remove_spellcheck_errors(); notebook.get_current_view()->remove_spellcheck_errors();
}); });
menu.action_group->add(Gtk::Action::create("SourceSpellCheckNextError", "Go to next Spelling Error"), Gtk::AccelKey(menu.key_map["source_spellcheck_next_error"]), [this]() { menu.action_group->add(Gtk::Action::create("SourceSpellCheckNextError", "Go to next Spelling Error"), Gtk::AccelKey(key_map["source_spellcheck_next_error"]), [this]() {
if(notebook.get_current_page()!=-1) if(notebook.get_current_page()!=-1)
notebook.get_current_view()->goto_next_spellcheck_error(); notebook.get_current_view()->goto_next_spellcheck_error();
}); });
menu.action_group->add(Gtk::Action::create("SourceIndentation", "Indentation")); menu.action_group->add(Gtk::Action::create("SourceIndentation", "Indentation"));
menu.action_group->add(Gtk::Action::create("SourceIndentationSetBufferTab", "Set Current Buffer Tab"), Gtk::AccelKey(menu.key_map["source_indentation_set_buffer_tab"]), [this]() { menu.action_group->add(Gtk::Action::create("SourceIndentationSetBufferTab", "Set Current Buffer Tab"), Gtk::AccelKey(key_map["source_indentation_set_buffer_tab"]), [this]() {
set_tab_entry(); set_tab_entry();
}); });
menu.action_group->add(Gtk::Action::create("SourceIndentationAutoIndentBuffer", "Auto-Indent Current Buffer"), Gtk::AccelKey(menu.key_map["source_indentation_auto_indent_buffer"]), [this]() { menu.action_group->add(Gtk::Action::create("SourceIndentationAutoIndentBuffer", "Auto-Indent Current Buffer"), Gtk::AccelKey(key_map["source_indentation_auto_indent_buffer"]), [this]() {
if(notebook.get_current_page()!=-1 && notebook.get_current_view()->auto_indent) if(notebook.get_current_page()!=-1 && notebook.get_current_view()->auto_indent)
notebook.get_current_view()->auto_indent(); notebook.get_current_view()->auto_indent();
}); });
menu.action_group->add(Gtk::Action::create("SourceGotoLine", "Go to Line"), Gtk::AccelKey(menu.key_map["source_goto_line"]), [this]() { menu.action_group->add(Gtk::Action::create("SourceGotoLine", "Go to Line"), Gtk::AccelKey(key_map["source_goto_line"]), [this]() {
goto_line_entry(); goto_line_entry();
}); });
menu.action_group->add(Gtk::Action::create("SourceCenterCursor", "Center Cursor"), Gtk::AccelKey(menu.key_map["source_center_cursor"]), [this]() { menu.action_group->add(Gtk::Action::create("SourceCenterCursor", "Center Cursor"), Gtk::AccelKey(key_map["source_center_cursor"]), [this]() {
if(notebook.get_current_page()!=-1) { if(notebook.get_current_page()!=-1) {
while(gtk_events_pending()) while(gtk_events_pending())
gtk_main_iteration(); gtk_main_iteration();
@ -357,7 +367,7 @@ void Window::create_menu() {
notebook.get_current_view()->scroll_to(notebook.get_current_view()->get_buffer()->get_insert(), 0.0, 1.0, 0.5); notebook.get_current_view()->scroll_to(notebook.get_current_view()->get_buffer()->get_insert(), 0.0, 1.0, 0.5);
} }
}); });
menu.action_group->add(Gtk::Action::create("SourceGotoDeclaration", "Go to Declaration"), Gtk::AccelKey(menu.key_map["source_goto_declaration"]), [this]() { menu.action_group->add(Gtk::Action::create("SourceGotoDeclaration", "Go to Declaration"), Gtk::AccelKey(key_map["source_goto_declaration"]), [this]() {
if(notebook.get_current_page()!=-1) { if(notebook.get_current_page()!=-1) {
if(notebook.get_current_view()->get_declaration_location) { if(notebook.get_current_view()->get_declaration_location) {
auto location=notebook.get_current_view()->get_declaration_location(); auto location=notebook.get_current_view()->get_declaration_location();
@ -384,17 +394,17 @@ void Window::create_menu() {
} }
} }
}); });
menu.action_group->add(Gtk::Action::create("SourceGotoMethod", "Go to Method"), Gtk::AccelKey(menu.key_map["source_goto_method"]), [this]() { menu.action_group->add(Gtk::Action::create("SourceGotoMethod", "Go to Method"), Gtk::AccelKey(key_map["source_goto_method"]), [this]() {
if(notebook.get_current_page()!=-1) { if(notebook.get_current_page()!=-1) {
if(notebook.get_current_view()->goto_method) { if(notebook.get_current_view()->goto_method) {
notebook.get_current_view()->goto_method(); notebook.get_current_view()->goto_method();
} }
} }
}); });
menu.action_group->add(Gtk::Action::create("SourceRename", "Rename"), Gtk::AccelKey(menu.key_map["source_rename"]), [this]() { menu.action_group->add(Gtk::Action::create("SourceRename", "Rename"), Gtk::AccelKey(key_map["source_rename"]), [this]() {
rename_token_entry(); rename_token_entry();
}); });
menu.action_group->add(Gtk::Action::create("SourceFindDocumentation", "Find Documentation"), Gtk::AccelKey(menu.key_map["source_find_documentation"]), [this]() { menu.action_group->add(Gtk::Action::create("SourceFindDocumentation", "Find Documentation"), Gtk::AccelKey(key_map["source_find_documentation"]), [this]() {
if(notebook.get_current_page()!=-1) { if(notebook.get_current_page()!=-1) {
if(notebook.get_current_view()->get_token_data) { if(notebook.get_current_view()->get_token_data) {
auto data=notebook.get_current_view()->get_token_data(); auto data=notebook.get_current_view()->get_token_data();
@ -434,14 +444,14 @@ void Window::create_menu() {
} }
} }
}); });
menu.action_group->add(Gtk::Action::create("SourceGotoNextDiagnostic", "Go to next Diagnostic"), Gtk::AccelKey(menu.key_map["source_goto_next_diagnostic"]), [this]() { menu.action_group->add(Gtk::Action::create("SourceGotoNextDiagnostic", "Go to next Diagnostic"), Gtk::AccelKey(key_map["source_goto_next_diagnostic"]), [this]() {
if(notebook.get_current_page()!=-1) { if(notebook.get_current_page()!=-1) {
if(notebook.get_current_view()->goto_next_diagnostic) { if(notebook.get_current_view()->goto_next_diagnostic) {
notebook.get_current_view()->goto_next_diagnostic(); notebook.get_current_view()->goto_next_diagnostic();
} }
} }
}); });
menu.action_group->add(Gtk::Action::create("SourceApplyFixIts", "Apply Fix-Its"), Gtk::AccelKey(menu.key_map["source_apply_fix_its"]), [this]() { menu.action_group->add(Gtk::Action::create("SourceApplyFixIts", "Apply Fix-Its"), Gtk::AccelKey(key_map["source_apply_fix_its"]), [this]() {
if(notebook.get_current_page()!=-1) { if(notebook.get_current_page()!=-1) {
if(notebook.get_current_view()->apply_fix_its) { if(notebook.get_current_view()->apply_fix_its) {
notebook.get_current_view()->apply_fix_its(); notebook.get_current_view()->apply_fix_its();
@ -449,7 +459,7 @@ void Window::create_menu() {
} }
}); });
menu.action_group->add(Gtk::Action::create("ProjectCompileAndRun", "Compile and Run"), Gtk::AccelKey(menu.key_map["compile_and_run"]), [this]() { menu.action_group->add(Gtk::Action::create("ProjectCompileAndRun", "Compile and Run"), Gtk::AccelKey(key_map["compile_and_run"]), [this]() {
if(notebook.get_current_page()==-1 || compiling) if(notebook.get_current_page()==-1 || compiling)
return; return;
CMake cmake(notebook.get_current_view()->file_path); CMake cmake(notebook.get_current_view()->file_path);
@ -489,7 +499,7 @@ void Window::create_menu() {
} }
} }
}); });
menu.action_group->add(Gtk::Action::create("ProjectCompile", "Compile"), Gtk::AccelKey(menu.key_map["compile"]), [this]() { menu.action_group->add(Gtk::Action::create("ProjectCompile", "Compile"), Gtk::AccelKey(key_map["compile"]), [this]() {
if(notebook.get_current_page()==-1 || compiling) if(notebook.get_current_page()==-1 || compiling)
return; return;
CMake cmake(notebook.get_current_view()->file_path); CMake cmake(notebook.get_current_view()->file_path);
@ -501,7 +511,7 @@ void Window::create_menu() {
}); });
} }
}); });
menu.action_group->add(Gtk::Action::create("ProjectRunCommand", "Run Command"), Gtk::AccelKey(menu.key_map["run_command"]), [this]() { menu.action_group->add(Gtk::Action::create("ProjectRunCommand", "Run Command"), Gtk::AccelKey(key_map["run_command"]), [this]() {
entry_box.clear(); entry_box.clear();
entry_box.labels.emplace_back(); entry_box.labels.emplace_back();
auto label_it=entry_box.labels.begin(); auto label_it=entry_box.labels.begin();
@ -536,13 +546,13 @@ void Window::create_menu() {
}); });
entry_box.show(); entry_box.show();
}); });
menu.action_group->add(Gtk::Action::create("ProjectKillLastRunning", "Kill Last Process"), Gtk::AccelKey(menu.key_map["kill_last_running"]), [this]() { menu.action_group->add(Gtk::Action::create("ProjectKillLastRunning", "Kill Last Process"), Gtk::AccelKey(key_map["kill_last_running"]), [this]() {
Singleton::terminal()->kill_last_async_execute(); Singleton::terminal()->kill_last_async_execute();
}); });
menu.action_group->add(Gtk::Action::create("ProjectForceKillLastRunning", "Force Kill Last Process"), Gtk::AccelKey(menu.key_map["force_kill_last_running"]), [this]() { menu.action_group->add(Gtk::Action::create("ProjectForceKillLastRunning", "Force Kill Last Process"), Gtk::AccelKey(key_map["force_kill_last_running"]), [this]() {
Singleton::terminal()->kill_last_async_execute(true); Singleton::terminal()->kill_last_async_execute(true);
}); });
menu.action_group->add(Gtk::Action::create("WindowCloseTab", "Close Tab"), Gtk::AccelKey(menu.key_map["close_tab"]), [this]() { menu.action_group->add(Gtk::Action::create("WindowCloseTab", "Close Tab"), Gtk::AccelKey(key_map["close_tab"]), [this]() {
notebook.close_current_page(); notebook.close_current_page();
if(notebook.get_current_page()!=-1) { if(notebook.get_current_page()!=-1) {
notebook.get_current_view()->set_status(notebook.get_current_view()->status); notebook.get_current_view()->set_status(notebook.get_current_view()->status);
@ -553,12 +563,12 @@ void Window::create_menu() {
Singleton::info()->set_text(""); Singleton::info()->set_text("");
} }
}); });
menu.action_group->add(Gtk::Action::create("WindowNextTab", "Next Tab"), Gtk::AccelKey(menu.key_map["next_tab"]), [this]() { menu.action_group->add(Gtk::Action::create("WindowNextTab", "Next Tab"), Gtk::AccelKey(key_map["next_tab"]), [this]() {
if(notebook.get_current_page()!=-1) { if(notebook.get_current_page()!=-1) {
notebook.open(notebook.get_view((notebook.get_current_page()+1)%notebook.size())->file_path); notebook.open(notebook.get_view((notebook.get_current_page()+1)%notebook.size())->file_path);
} }
}); });
menu.action_group->add(Gtk::Action::create("WindowPreviousTab", "Previous Tab"), Gtk::AccelKey(menu.key_map["previous_tab"]), [this]() { menu.action_group->add(Gtk::Action::create("WindowPreviousTab", "Previous Tab"), Gtk::AccelKey(key_map["previous_tab"]), [this]() {
if(notebook.get_current_page()!=-1) { if(notebook.get_current_page()!=-1) {
int previous_page=notebook.get_current_page()-1; int previous_page=notebook.get_current_page()-1;
if(previous_page<0) if(previous_page<0)
@ -569,7 +579,7 @@ void Window::create_menu() {
menu.action_group->add(Gtk::Action::create("HelpAbout", "About"), [this] () { menu.action_group->add(Gtk::Action::create("HelpAbout", "About"), [this] () {
about.show(); about.show();
about.present(); about.present();
}); });*/
} }
bool Window::on_key_press_event(GdkEventKey *event) { bool Window::on_key_press_event(GdkEventKey *event) {

9
src/window.h

@ -5,10 +5,9 @@
#include "directories.h" #include "directories.h"
#include "entrybox.h" #include "entrybox.h"
#include "notebook.h" #include "notebook.h"
#include "menu.h"
#include <atomic> #include <atomic>
class Window : public Gtk::Window { class Window : public Gtk::ApplicationWindow {
public: public:
Window(); Window();
Notebook notebook; Notebook notebook;
@ -18,15 +17,14 @@ public:
std::string theme_variant; std::string theme_variant;
std::string version; std::string version;
std::pair<int, int> default_size; std::pair<int, int> default_size;
boost::property_tree::ptree keybindings;
}; };
void set_menu_actions();
protected: protected:
bool on_key_press_event(GdkEventKey *event); bool on_key_press_event(GdkEventKey *event);
bool on_delete_event (GdkEventAny *event); bool on_delete_event (GdkEventAny *event);
private: private:
Gtk::Box box;
Gtk::VPaned vpaned; Gtk::VPaned vpaned;
Gtk::Paned directory_and_notebook_panes; Gtk::Paned directory_and_notebook_panes;
Gtk::VBox notebook_vbox; Gtk::VBox notebook_vbox;
@ -35,17 +33,14 @@ private:
Gtk::HBox info_and_status_hbox; Gtk::HBox info_and_status_hbox;
Gtk::AboutDialog about; Gtk::AboutDialog about;
EntryBox entry_box; EntryBox entry_box;
Menu menu;
std::atomic<bool> compiling; std::atomic<bool> compiling;
void configure(); void configure();
void create_menu();
void hide(); void hide();
void search_and_replace_entry(); void search_and_replace_entry();
void set_tab_entry(); void set_tab_entry();
void goto_line_entry(); void goto_line_entry();
void rename_token_entry(); void rename_token_entry();
void generate_keybindings();
std::string last_search; std::string last_search;
std::string last_replace; std::string last_replace;
std::string last_run_command; std::string last_run_command;

Loading…
Cancel
Save