diff --git a/CMakeLists.txt b/CMakeLists.txt index 5185456..8c418d6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required (VERSION 2.8.8) project(juci) -set(JUCI_VERSION "1.4.0.1") +set(JUCI_VERSION "1.4.0.2") set(CPACK_PACKAGE_NAME "jucipp") set(CPACK_PACKAGE_CONTACT "Ole Christian Eidheim ") diff --git a/src/config.cc b/src/config.cc index 92ae884..a461226 100644 --- a/src/config.cc +++ b/src/config.cc @@ -191,7 +191,6 @@ void Config::read(const boost::property_tree::ptree &cfg) { window.theme_name=cfg.get("gtk_theme.name"); window.theme_variant=cfg.get("gtk_theme.variant"); window.version = cfg.get("version"); - window.default_size = {cfg.get("default_window_size.width"), cfg.get("default_window_size.height")}; project.default_build_path=cfg.get("project.default_build_path"); project.debug_build_path=cfg.get("project.debug_build_path"); diff --git a/src/config.h b/src/config.h index 42b0b18..1e9bff1 100644 --- a/src/config.h +++ b/src/config.h @@ -19,7 +19,6 @@ public: std::string theme_name; std::string theme_variant; std::string version; - std::pair default_size; }; class Terminal { diff --git a/src/files.h b/src/files.h index a78253c..e50dc05 100644 --- a/src/files.h +++ b/src/files.h @@ -6,10 +6,6 @@ /// the changes to user's ~/.juci/config/config.json files const std::string default_config_file = R"RAW({ "version": ")RAW"+std::string(JUCI_VERSION)+R"RAW(", - "default_window_size": { - "width": 800, - "height": 600 - }, "gtk_theme": { "name_comment": "Use \"\" for default theme, At least these two exist on all systems: Adwaita, Raleigh", "name": "", diff --git a/src/juci.cc b/src/juci.cc index 93a0e2d..6091a7c 100644 --- a/src/juci.cc +++ b/src/juci.cc @@ -46,30 +46,14 @@ int Application::on_command_line(const Glib::RefPtr } void Application::on_activate() { - add_window(Window::get()); - Window::get().show(); + std::vector> file_offsets; + std::string current_file; + Window::get().load_session(directories, files, file_offsets, current_file, directories.empty() && files.empty()); - std::string last_current_file; + Window::get().add_widgets(); - if(directories.empty() && files.empty()) { - try { - boost::property_tree::ptree pt; - boost::property_tree::read_json((Config::get().home_juci_path/"last_session.json").string(), pt); - auto folder=pt.get("folder"); - if(!folder.empty() && boost::filesystem::exists(folder) && boost::filesystem::is_directory(folder)) - directories.emplace_back(folder); - for(auto &pt_file: pt.get_child("files")) { - auto notebook=pt_file.second.get("notebook", -1); - auto file=pt_file.second.get("file", ""); - if(!file.empty() && boost::filesystem::exists(file) && !boost::filesystem::is_directory(file)) - files.emplace_back(file, notebook); - } - last_current_file=pt.get("current_file"); - if(!boost::filesystem::exists(last_current_file) || boost::filesystem::is_directory(last_current_file)) - last_current_file.clear(); - } - catch(const std::exception &) {} - } + add_window(Window::get()); + Window::get().show(); bool first_directory=true; for(auto &directory: directories) { @@ -87,7 +71,7 @@ void Application::on_activate() { else it++; } - std::thread another_juci_app([this, directory, files_in_directory](){ + std::thread another_juci_app([directory, files_in_directory](){ Terminal::get().async_print("Executing: juci "+directory.string()+files_in_directory+"\n"); Terminal::get().process("juci "+directory.string()+files_in_directory, "", false); }); @@ -95,14 +79,28 @@ void Application::on_activate() { } } - for(auto &file: files) - Notebook::get().open(file.first, file.second); + for(size_t i=0;iplace_cursor_at_line_offset(file_offsets[i].first, file_offsets[i].second); + view->scroll_to_cursor_delayed(view, true, false); + } + } + } for(auto &error: errors) Terminal::get().print(error, true); - if(!last_current_file.empty()) - Notebook::get().open(last_current_file); + if(!current_file.empty()) { + Notebook::get().open(current_file); + if(auto view=Notebook::get().get_current_view()) { + auto iter=view->get_buffer()->get_insert()->get_iter(); + // To update cursor history + view->place_cursor_at_line_offset(iter.get_line(), iter.get_line_offset()); + view->hide_tooltips(); + } + } } void Application::on_startup() { diff --git a/src/juci.h b/src/juci.h index 39dd9b2..5a4a4bb 100644 --- a/src/juci.h +++ b/src/juci.h @@ -36,6 +36,6 @@ public: void on_startup() override; private: std::vector directories; - std::vector > files; + std::vector> files; std::vector errors; }; diff --git a/src/notebook.cc b/src/notebook.cc index 39dcd70..882462c 100644 --- a/src/notebook.cc +++ b/src/notebook.cc @@ -450,27 +450,6 @@ bool Notebook::save_current() { return false; } -void Notebook::save_session() { - try { - boost::property_tree::ptree pt_root, pt_files; - pt_root.put("folder", Directories::get().path.string()); - for(size_t notebook_index=0;notebook_indexfile_path.string()); - pt_files.push_back(std::make_pair("", pt_child)); - } - } - pt_root.add_child("files", pt_files); - if(auto view=Notebook::get().get_current_view()) - pt_root.put("current_file", view->file_path.string()); - boost::property_tree::write_json((Config::get().home_juci_path/"last_session.json").string(), pt_root); - } - catch(const std::exception &) {} -} - bool Notebook::close(size_t index) { if(auto view=get_view(index)) { if(view->get_buffer()->get_modified()){ @@ -611,6 +590,17 @@ boost::filesystem::path Notebook::get_current_folder() { return boost::filesystem::path(); } +std::vector> Notebook::get_notebook_views() { + std::vector> notebook_views; + for(size_t notebook_index=0;notebook_indexupdate_status_location) view->update_status_location(view); diff --git a/src/notebook.h b/src/notebook.h index 36e7d3e..b9c36b8 100644 --- a/src/notebook.h +++ b/src/notebook.h @@ -37,7 +37,6 @@ public: void configure(size_t index); bool save(size_t index); bool save_current(); - void save_session(); bool close(size_t index); bool close_current(); void next(); @@ -46,6 +45,7 @@ public: /// Hide/Show tabs. void toggle_tabs(); boost::filesystem::path get_current_folder(); + std::vector> get_notebook_views(); Gtk::Label status_location; Gtk::Label status_file_path; diff --git a/src/project.cc b/src/project.cc index c191eed..2ea5003 100644 --- a/src/project.cc +++ b/src/project.cc @@ -19,15 +19,13 @@ boost::filesystem::path Project::debug_last_stop_file_path; std::unordered_map Project::run_arguments; -std::unordered_map Project::debug_run_arguments; +std::unordered_map Project::debug_run_arguments; std::atomic Project::compiling(false); std::atomic Project::debugging(false); std::pair > Project::debug_stop; std::string Project::debug_status; std::shared_ptr Project::current; -#ifdef JUCI_ENABLE_DEBUG -std::unordered_map Project::LLDB::debug_options; -#endif +std::unique_ptr Project::Base::debug_options; Gtk::Label &Project::debug_status_label() { static Gtk::Label label; @@ -256,32 +254,6 @@ void Project::Base::debug_start() { } #ifdef JUCI_ENABLE_DEBUG -Project::LLDB::DebugOptions::DebugOptions() : Base::DebugOptions() { - remote_enabled.set_active(false); - remote_enabled.set_label("Enabled"); - remote_enabled.signal_clicked().connect([this] { - remote_host.set_sensitive(remote_enabled.get_active()); - }); - remote_host.set_sensitive(false); - remote_host.set_placeholder_text("host:port"); - remote_host.signal_activate().connect([this] { - set_visible(false); - }); - - auto remote_vbox=Gtk::manage(new Gtk::Box(Gtk::Orientation::ORIENTATION_VERTICAL)); - remote_vbox->pack_start(remote_enabled, true, true); - remote_vbox->pack_end(remote_host, true, true); - - auto remote_frame=Gtk::manage(new Gtk::Frame()); - remote_frame->set_label("Remote Debugging"); - remote_frame->add(*remote_vbox); - - vbox.pack_end(*remote_frame, true, true); - - show_all(); - set_visible(false); -} - std::pair Project::LLDB::debug_get_run_arguments() { auto debug_build_path=build->get_debug_path(); auto default_build_path=build->get_default_path(); @@ -292,7 +264,7 @@ std::pair Project::LLDB::debug_get_run_arguments() { auto run_arguments_it=debug_run_arguments.find(project_path); std::string arguments; if(run_arguments_it!=debug_run_arguments.end()) - arguments=run_arguments_it->second; + arguments=run_arguments_it->second.arguments; if(arguments.empty()) { auto view=Notebook::get().get_current_view(); @@ -311,10 +283,47 @@ std::pair Project::LLDB::debug_get_run_arguments() { return {project_path, arguments}; } -Gtk::Popover *Project::LLDB::debug_get_options() { - if(!build->project_path.empty()) - return &debug_options[build->project_path.string()]; - return nullptr; +Project::DebugOptions *Project::LLDB::debug_get_options() { + if(build->project_path.empty()) + return nullptr; + + debug_options=std::make_unique(); + + auto &arguments=Project::debug_run_arguments[build->project_path.string()]; + + auto remote_enabled=Gtk::manage(new Gtk::CheckButton()); + auto remote_host_port=Gtk::manage(new Gtk::Entry()); + remote_enabled->set_active(arguments.remote_enabled); + remote_enabled->set_label("Enabled"); + remote_enabled->signal_clicked().connect([remote_enabled, remote_host_port] { + remote_host_port->set_sensitive(remote_enabled->get_active()); + }); + + remote_host_port->set_sensitive(arguments.remote_enabled); + remote_host_port->set_text(arguments.remote_host_port); + remote_host_port->set_placeholder_text("host:port"); + remote_host_port->signal_activate().connect([] { + debug_options->hide(); + }); + + auto self=this->shared_from_this(); + debug_options->signal_hide().connect([self, remote_enabled, remote_host_port] { + auto &arguments=Project::debug_run_arguments[self->build->project_path.string()]; + arguments.remote_enabled=remote_enabled->get_active(); + arguments.remote_host_port=remote_host_port->get_text(); + }); + + auto remote_vbox=Gtk::manage(new Gtk::Box(Gtk::Orientation::ORIENTATION_VERTICAL)); + remote_vbox->pack_start(*remote_enabled, true, true); + remote_vbox->pack_end(*remote_host_port, true, true); + + auto remote_frame=Gtk::manage(new Gtk::Frame()); + remote_frame->set_label("Remote Debugging"); + remote_frame->add(*remote_vbox); + + debug_options->vbox.pack_end(*remote_frame, true, true); + + return debug_options.get(); } void Project::LLDB::debug_start() { @@ -328,7 +337,7 @@ void Project::LLDB::debug_start() { auto run_arguments_it=debug_run_arguments.find(project_path->string()); auto run_arguments=std::make_shared(); if(run_arguments_it!=debug_run_arguments.end()) - *run_arguments=run_arguments_it->second; + *run_arguments=run_arguments_it->second.arguments; if(run_arguments->empty()) { auto view=Notebook::get().get_current_view(); @@ -368,9 +377,9 @@ void Project::LLDB::debug_start() { } std::string remote_host; - auto options_it=debug_options.find(project_path->string()); - if(options_it!=debug_options.end() && options_it->second.remote_enabled.get_active()) - remote_host=options_it->second.remote_host.get_text(); + auto debug_run_arguments_it=debug_run_arguments.find(project_path->string()); + if(debug_run_arguments_it!=debug_run_arguments.end() && debug_run_arguments_it->second.remote_enabled) + remote_host=debug_run_arguments_it->second.remote_host_port; static auto on_exit_it=Debug::LLDB::get().on_exit.end(); if(on_exit_it!=Debug::LLDB::get().on_exit.end()) diff --git a/src/project.h b/src/project.h index 81a8505..d0db2c6 100644 --- a/src/project.h +++ b/src/project.h @@ -9,13 +9,26 @@ #include "project_build.h" namespace Project { + class DebugRunArguments { + public: + std::string arguments; + bool remote_enabled; + std::string remote_host_port; + }; + + class DebugOptions : public Gtk::Popover { + public: + DebugOptions() : Gtk::Popover(), vbox(Gtk::Orientation::ORIENTATION_VERTICAL) { add(vbox); } + Gtk::Box vbox; + }; + Gtk::Label &debug_status_label(); void save_files(const boost::filesystem::path &path); void on_save(size_t index); extern boost::filesystem::path debug_last_stop_file_path; extern std::unordered_map run_arguments; - extern std::unordered_map debug_run_arguments; + extern std::unordered_map debug_run_arguments; extern std::atomic compiling; extern std::atomic debugging; extern std::pair > debug_stop; @@ -26,14 +39,7 @@ namespace Project { class Base : public std::enable_shared_from_this { protected: -#ifdef JUCI_ENABLE_DEBUG - class DebugOptions : public Gtk::Popover { - public: - DebugOptions() : Gtk::Popover(), vbox(Gtk::Orientation::ORIENTATION_VERTICAL) { add(vbox); } - protected: - Gtk::Box vbox; - }; -#endif + static std::unique_ptr debug_options; public: Base() {} Base(std::unique_ptr &&build): build(std::move(build)) {} @@ -51,7 +57,7 @@ namespace Project { virtual void show_symbols(); virtual std::pair debug_get_run_arguments(); - virtual Gtk::Popover *debug_get_options() { return nullptr; } + virtual Project::DebugOptions *debug_get_options() { return nullptr; } Tooltips debug_variable_tooltips; virtual void debug_start(); virtual void debug_continue() {} @@ -71,23 +77,13 @@ namespace Project { }; class LLDB : public virtual Base { -#ifdef JUCI_ENABLE_DEBUG - class DebugOptions : public Base::DebugOptions { - public: - DebugOptions(); - Gtk::CheckButton remote_enabled; - Gtk::Entry remote_host; - }; - static std::unordered_map debug_options; -#endif - public: LLDB() {} ~LLDB() { dispatcher.disconnect(); } #ifdef JUCI_ENABLE_DEBUG std::pair debug_get_run_arguments() override; - Gtk::Popover *debug_get_options() override; + Project::DebugOptions *debug_get_options() override; void debug_start() override; void debug_continue() override; void debug_stop() override; diff --git a/src/window.cc b/src/window.cc index bca1863..6411481 100644 --- a/src/window.cc +++ b/src/window.cc @@ -21,95 +21,15 @@ Window::Window() { Menu::get().right_click_line_menu->attach_to_widget(*this); Menu::get().right_click_selected_menu->attach_to_widget(*this); - - set_default_size(Config::get().window.default_size.first, Config::get().window.default_size.second); - - auto directories_scrolled_window=Gtk::manage(new Gtk::ScrolledWindow()); - directories_scrolled_window->add(Directories::get()); - auto notebook_vbox=Gtk::manage(new Gtk::Box(Gtk::Orientation::ORIENTATION_VERTICAL)); - notebook_vbox->pack_start(Notebook::get()); - notebook_vbox->pack_end(EntryBox::get(), Gtk::PACK_SHRINK); - - auto terminal_scrolled_window=Gtk::manage(new Gtk::ScrolledWindow()); - terminal_scrolled_window->add(Terminal::get()); - - auto notebook_and_terminal_vpaned=Gtk::manage(new Gtk::Paned(Gtk::Orientation::ORIENTATION_VERTICAL)); - notebook_and_terminal_vpaned->set_position(static_cast(0.75*Config::get().window.default_size.second)); - notebook_and_terminal_vpaned->pack1(*notebook_vbox, Gtk::SHRINK); - notebook_and_terminal_vpaned->pack2(*terminal_scrolled_window, Gtk::SHRINK); - - auto hpaned=Gtk::manage(new Gtk::Paned()); - hpaned->set_position(static_cast(0.2*Config::get().window.default_size.first)); - hpaned->pack1(*directories_scrolled_window, Gtk::SHRINK); - hpaned->pack2(*notebook_and_terminal_vpaned, Gtk::SHRINK); - - auto status_hbox=Gtk::manage(new Gtk::Box()); - status_hbox->set_homogeneous(true); - status_hbox->pack_start(*Gtk::manage(new Gtk::Box())); - auto status_right_hbox=Gtk::manage(new Gtk::Box()); - status_right_hbox->pack_end(Notebook::get().status_state, Gtk::PACK_SHRINK); - auto status_right_overlay=Gtk::manage(new Gtk::Overlay()); - status_right_overlay->add(*status_right_hbox); - status_right_overlay->add_overlay(Notebook::get().status_diagnostics); - status_hbox->pack_end(*status_right_overlay); - - auto status_overlay=Gtk::manage(new Gtk::Overlay()); - status_overlay->add(*status_hbox); - auto status_file_info_hbox=Gtk::manage(new Gtk::Box); - status_file_info_hbox->pack_start(Notebook::get().status_file_path, Gtk::PACK_SHRINK); - status_file_info_hbox->pack_start(Notebook::get().status_branch, Gtk::PACK_SHRINK); - status_file_info_hbox->pack_start(Notebook::get().status_location, Gtk::PACK_SHRINK); - status_overlay->add_overlay(*status_file_info_hbox); - status_overlay->add_overlay(Project::debug_status_label()); - - auto vbox=Gtk::manage(new Gtk::Box(Gtk::Orientation::ORIENTATION_VERTICAL)); - vbox->pack_start(*hpaned); - vbox->pack_start(*status_overlay, Gtk::PACK_SHRINK); - - auto overlay_vbox=Gtk::manage(new Gtk::Box(Gtk::Orientation::ORIENTATION_VERTICAL)); - auto overlay_hbox=Gtk::manage(new Gtk::Box()); - overlay_vbox->set_hexpand(false); - overlay_vbox->set_halign(Gtk::Align::ALIGN_START); - overlay_vbox->pack_start(Info::get(), Gtk::PACK_SHRINK, 20); - overlay_hbox->set_hexpand(false); - overlay_hbox->set_halign(Gtk::Align::ALIGN_END); - overlay_hbox->pack_end(*overlay_vbox, Gtk::PACK_SHRINK, 20); - - auto overlay=Gtk::manage(new Gtk::Overlay()); - overlay->add(*vbox); - overlay->add_overlay(*overlay_hbox); - overlay->set_overlay_pass_through(*overlay_hbox, true); - add(*overlay); - - show_all_children(); - Info::get().hide(); - - //Scroll to end of terminal whenever info is printed - Terminal::get().signal_size_allocate().connect([terminal_scrolled_window](Gtk::Allocation& allocation){ - auto adjustment=terminal_scrolled_window->get_vadjustment(); - adjustment->set_value(adjustment->get_upper()-adjustment->get_page_size()); - Terminal::get().queue_draw(); - }); - - EntryBox::get().signal_show().connect([this, hpaned, notebook_and_terminal_vpaned, notebook_vbox](){ - hpaned->set_focus_chain({notebook_and_terminal_vpaned}); - notebook_and_terminal_vpaned->set_focus_chain({notebook_vbox}); - notebook_vbox->set_focus_chain({&EntryBox::get()}); - }); - EntryBox::get().signal_hide().connect([this, hpaned, notebook_and_terminal_vpaned, notebook_vbox](){ - hpaned->unset_focus_chain(); - notebook_and_terminal_vpaned->unset_focus_chain(); - notebook_vbox->unset_focus_chain(); - }); - EntryBox::get().signal_hide().connect([this]() { + EntryBox::get().signal_hide().connect([]() { if(auto view=Notebook::get().get_current_view()) view->grab_focus(); }); Notebook::get().on_change_page=[this](Source::View *view) { if(search_entry_shown && EntryBox::get().labels.size()>0) { - view->update_search_occurrences=[this](int number){ + view->update_search_occurrences=[](int number){ EntryBox::get().labels.begin()->update(0, std::to_string(number)); }; view->search_highlight(last_search, case_sensitive_search, regex_search); @@ -170,7 +90,7 @@ Window::Window() { Project::current=nullptr; }); - Gtk::Settings::get_default()->connect_property_changed("gtk-theme-name", [this] { + Gtk::Settings::get_default()->connect_property_changed("gtk-theme-name", [] { Directories::get().update(); if(auto view=Notebook::get().get_current_view()) Notebook::get().update_status(view); @@ -1115,15 +1035,15 @@ void Window::set_menu_actions() { }; label_it->update(0, ""); EntryBox::get().entries.emplace_back(run_arguments.second, [this, run_arguments_first=std::move(run_arguments.first)](const std::string& content){ - Project::debug_run_arguments[run_arguments_first]=content; + Project::debug_run_arguments[run_arguments_first].arguments=content; EntryBox::get().hide(); }, 50); auto entry_it=EntryBox::get().entries.begin(); entry_it->set_placeholder_text("Debug: Set Run Arguments"); if(auto options=project->debug_get_options()) { - EntryBox::get().buttons.emplace_back("", [this, options]() { - options->set_visible(true); + EntryBox::get().buttons.emplace_back("", [options]() { + options->show_all(); }); EntryBox::get().buttons.back().set_image_from_icon_name("preferences-system"); EntryBox::get().buttons.back().set_always_show_image(true); @@ -1281,6 +1201,90 @@ void Window::activate_menu_items() { #endif } +void Window::add_widgets() { + auto directories_scrolled_window=Gtk::manage(new Gtk::ScrolledWindow()); + directories_scrolled_window->add(Directories::get()); + + auto notebook_vbox=Gtk::manage(new Gtk::Box(Gtk::Orientation::ORIENTATION_VERTICAL)); + notebook_vbox->pack_start(Notebook::get()); + notebook_vbox->pack_end(EntryBox::get(), Gtk::PACK_SHRINK); + + auto terminal_scrolled_window=Gtk::manage(new Gtk::ScrolledWindow()); + terminal_scrolled_window->add(Terminal::get()); + + int width, height; + get_default_size(width, height); + + auto notebook_and_terminal_vpaned=Gtk::manage(new Gtk::Paned(Gtk::Orientation::ORIENTATION_VERTICAL)); + notebook_and_terminal_vpaned->set_position(static_cast(0.75*height)); + notebook_and_terminal_vpaned->pack1(*notebook_vbox, Gtk::SHRINK); + notebook_and_terminal_vpaned->pack2(*terminal_scrolled_window, Gtk::SHRINK); + + auto hpaned=Gtk::manage(new Gtk::Paned()); + hpaned->set_position(static_cast(0.2*width)); + hpaned->pack1(*directories_scrolled_window, Gtk::SHRINK); + hpaned->pack2(*notebook_and_terminal_vpaned, Gtk::SHRINK); + + auto status_hbox=Gtk::manage(new Gtk::Box()); + status_hbox->set_homogeneous(true); + status_hbox->pack_start(*Gtk::manage(new Gtk::Box())); + auto status_right_hbox=Gtk::manage(new Gtk::Box()); + status_right_hbox->pack_end(Notebook::get().status_state, Gtk::PACK_SHRINK); + auto status_right_overlay=Gtk::manage(new Gtk::Overlay()); + status_right_overlay->add(*status_right_hbox); + status_right_overlay->add_overlay(Notebook::get().status_diagnostics); + status_hbox->pack_end(*status_right_overlay); + + auto status_overlay=Gtk::manage(new Gtk::Overlay()); + status_overlay->add(*status_hbox); + auto status_file_info_hbox=Gtk::manage(new Gtk::Box); + status_file_info_hbox->pack_start(Notebook::get().status_file_path, Gtk::PACK_SHRINK); + status_file_info_hbox->pack_start(Notebook::get().status_branch, Gtk::PACK_SHRINK); + status_file_info_hbox->pack_start(Notebook::get().status_location, Gtk::PACK_SHRINK); + status_overlay->add_overlay(*status_file_info_hbox); + status_overlay->add_overlay(Project::debug_status_label()); + + auto vbox=Gtk::manage(new Gtk::Box(Gtk::Orientation::ORIENTATION_VERTICAL)); + vbox->pack_start(*hpaned); + vbox->pack_start(*status_overlay, Gtk::PACK_SHRINK); + + auto overlay_vbox=Gtk::manage(new Gtk::Box(Gtk::Orientation::ORIENTATION_VERTICAL)); + auto overlay_hbox=Gtk::manage(new Gtk::Box()); + overlay_vbox->set_hexpand(false); + overlay_vbox->set_halign(Gtk::Align::ALIGN_START); + overlay_vbox->pack_start(Info::get(), Gtk::PACK_SHRINK, 20); + overlay_hbox->set_hexpand(false); + overlay_hbox->set_halign(Gtk::Align::ALIGN_END); + overlay_hbox->pack_end(*overlay_vbox, Gtk::PACK_SHRINK, 20); + + auto overlay=Gtk::manage(new Gtk::Overlay()); + overlay->add(*vbox); + overlay->add_overlay(*overlay_hbox); + overlay->set_overlay_pass_through(*overlay_hbox, true); + add(*overlay); + + show_all_children(); + Info::get().hide(); + + //Scroll to end of terminal whenever info is printed + Terminal::get().signal_size_allocate().connect([terminal_scrolled_window](Gtk::Allocation& allocation){ + auto adjustment=terminal_scrolled_window->get_vadjustment(); + adjustment->set_value(adjustment->get_upper()-adjustment->get_page_size()); + Terminal::get().queue_draw(); + }); + + EntryBox::get().signal_show().connect([this, hpaned, notebook_and_terminal_vpaned, notebook_vbox](){ + hpaned->set_focus_chain({notebook_and_terminal_vpaned}); + notebook_and_terminal_vpaned->set_focus_chain({notebook_vbox}); + notebook_vbox->set_focus_chain({&EntryBox::get()}); + }); + EntryBox::get().signal_hide().connect([this, hpaned, notebook_and_terminal_vpaned, notebook_vbox](){ + hpaned->unset_focus_chain(); + notebook_and_terminal_vpaned->unset_focus_chain(); + notebook_vbox->unset_focus_chain(); + }); +} + bool Window::on_key_press_event(GdkEventKey *event) { if(event->keyval==GDK_KEY_Escape) { EntryBox::get().hide(); @@ -1321,7 +1325,7 @@ bool Window::on_key_press_event(GdkEventKey *event) { } bool Window::on_delete_event(GdkEventAny *event) { - Notebook::get().save_session(); + save_session(); for(size_t c=Notebook::get().size()-1;c!=static_cast(-1);--c) { if(!Notebook::get().close(c)) @@ -1552,3 +1556,121 @@ void Window::rename_token_entry() { } } } + +void Window::save_session() { + try { + boost::property_tree::ptree root_pt; + root_pt.put("folder", Directories::get().path.string()); + + boost::property_tree::ptree files_pt; + for(auto ¬ebook_view: Notebook::get().get_notebook_views()) { + boost::property_tree::ptree file_pt; + file_pt.put("path", notebook_view.second->file_path.string()); + file_pt.put("notebook", notebook_view.first); + auto iter=notebook_view.second->get_buffer()->get_insert()->get_iter(); + file_pt.put("line", iter.get_line()); + file_pt.put("line_offset", iter.get_line_offset()); + files_pt.push_back(std::make_pair("", file_pt)); + } + root_pt.add_child("files", files_pt); + + boost::property_tree::ptree current_file_pt; + if(auto view=Notebook::get().get_current_view()) { + current_file_pt.put("path", view->file_path.string()); + auto iter=view->get_buffer()->get_insert()->get_iter(); + current_file_pt.put("line", iter.get_line()); + current_file_pt.put("line_offset", iter.get_line_offset()); + } + std::string current_path; + if(auto view=Notebook::get().get_current_view()) + current_path=view->file_path.string(); + root_pt.put("current_file", current_path); + + boost::property_tree::ptree run_arguments_pt; + for(auto &run_argument: Project::run_arguments) { + if(run_argument.second.empty()) + continue; + boost::system::error_code ec; + if(boost::filesystem::exists(run_argument.first, ec) && boost::filesystem::is_directory(run_argument.first, ec)) { + boost::property_tree::ptree run_argument_pt; + run_argument_pt.put("path", run_argument.first); + run_argument_pt.put("arguments", run_argument.second); + run_arguments_pt.push_back(std::make_pair("", run_argument_pt)); + } + } + root_pt.add_child("run_arguments", run_arguments_pt); + + boost::property_tree::ptree debug_run_arguments_pt; + for(auto &debug_run_argument: Project::debug_run_arguments) { + if(debug_run_argument.second.arguments.empty() && !debug_run_argument.second.remote_enabled && debug_run_argument.second.remote_host_port.empty()) + continue; + boost::system::error_code ec; + if(boost::filesystem::exists(debug_run_argument.first, ec) && boost::filesystem::is_directory(debug_run_argument.first, ec)) { + boost::property_tree::ptree debug_run_argument_pt; + debug_run_argument_pt.put("path", debug_run_argument.first); + debug_run_argument_pt.put("arguments", debug_run_argument.second.arguments); + debug_run_argument_pt.put("remote_enabled", debug_run_argument.second.remote_enabled); + debug_run_argument_pt.put("remote_host_port", debug_run_argument.second.remote_host_port); + debug_run_arguments_pt.push_back(std::make_pair("", debug_run_argument_pt)); + } + } + root_pt.add_child("debug_run_arguments", debug_run_arguments_pt); + + int width, height; + get_size(width, height); + boost::property_tree::ptree window_pt; + window_pt.put("width", width); + window_pt.put("height", height); + root_pt.add_child("window", window_pt); + + boost::property_tree::write_json((Config::get().home_juci_path/"last_session.json").string(), root_pt); + } + catch(...) {} +} + +void Window::load_session(std::vector &directories, std::vector > &files, std::vector > &file_offsets, std::string ¤t_file, bool read_directories_and_files) { + try { + boost::property_tree::ptree root_pt; + boost::property_tree::read_json((Config::get().home_juci_path/"last_session.json").string(), root_pt); + if(read_directories_and_files) { + auto folder=root_pt.get("folder"); + if(!folder.empty() && boost::filesystem::exists(folder) && boost::filesystem::is_directory(folder)) + directories.emplace_back(folder); + + for(auto &file_pt: root_pt.get_child("files")) { + auto file=file_pt.second.get("path"); + auto notebook=file_pt.second.get("notebook"); + auto line=file_pt.second.get("line"); + auto line_offset=file_pt.second.get("line_offset"); + if(!file.empty() && boost::filesystem::exists(file) && !boost::filesystem::is_directory(file)) { + files.emplace_back(file, notebook); + file_offsets.emplace_back(line, line_offset); + } + } + + current_file=root_pt.get("current_file"); + } + + for(auto &run_argument: root_pt.get_child(("run_arguments"))) { + auto path=run_argument.second.get("path"); + boost::system::error_code ec; + if(boost::filesystem::exists(path, ec) && boost::filesystem::is_directory(path, ec)) + Project::run_arguments.emplace(path, run_argument.second.get("arguments")); + } + + for(auto &debug_run_argument: root_pt.get_child(("debug_run_arguments"))) { + auto path=debug_run_argument.second.get("path"); + boost::system::error_code ec; + if(boost::filesystem::exists(path, ec) && boost::filesystem::is_directory(path, ec)) + Project::debug_run_arguments.emplace(path, Project::DebugRunArguments{debug_run_argument.second.get("arguments"), + debug_run_argument.second.get("remote_enabled"), + debug_run_argument.second.get("remote_host_port")}); + } + + auto window_pt=root_pt.get_child("window"); + set_default_size(window_pt.get("width"), window_pt.get("height")); + } + catch(...) { + set_default_size(800, 600); + } +} diff --git a/src/window.h b/src/window.h index f71ce83..97be899 100644 --- a/src/window.h +++ b/src/window.h @@ -1,6 +1,7 @@ #pragma once #include #include +#include class Window : public Gtk::ApplicationWindow { Window(); @@ -9,6 +10,9 @@ public: static Window singleton; return singleton; } + void add_widgets(); + void save_session(); + void load_session(std::vector &directories, std::vector> &files, std::vector> &file_offsets, std::string ¤t_file, bool read_directories_and_files); protected: bool on_key_press_event(GdkEventKey *event) override;