From 7a093920809394f7f31b75c444fe6009d1de7005 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Fri, 26 Jul 2024 15:48:13 +0200 Subject: ui: tracker implement loading UI --- ui/include/turns/ui/windows/tracker.hpp | 9 ++++ ui/res/ui.cmb | 9 ++-- ui/src/windows/tracker.cpp | 83 +++++++++++++++++++++++++++++---- 3 files changed, 88 insertions(+), 13 deletions(-) (limited to 'ui') diff --git a/ui/include/turns/ui/windows/tracker.hpp b/ui/include/turns/ui/windows/tracker.hpp index 6d0b4d6..f520097 100644 --- a/ui/include/turns/ui/windows/tracker.hpp +++ b/ui/include/turns/ui/windows/tracker.hpp @@ -23,6 +23,7 @@ #include #include +#include namespace turns::ui::windows { @@ -32,15 +33,22 @@ namespace turns::ui::windows tracker(BaseObjectType * base, Glib::RefPtr const builder); private: + auto do_save() -> void; + auto handle_add_participant() -> void; auto handle_delete_participant(Glib::VariantBase param) -> void; auto handle_edit_participant(Glib::VariantBase param) -> void; + auto handle_open() -> void; + auto handle_open_done(Glib::RefPtr result) -> void; + auto handle_open_response(Glib::RefPtr result, Glib::RefPtr dialog) -> void; auto handle_save(bool force_ask) -> void; auto handle_save_done(Glib::RefPtr result) -> void; auto handle_save_response(Glib::RefPtr result, Glib::RefPtr dialog) -> void; auto handle_stop() -> void; + auto setup_actions() -> void; + auto show_error_toast(std::exception const & e) -> void; auto update_subtitle() -> void; @@ -57,6 +65,7 @@ namespace turns::ui::windows std::string m_file_tag{}; Glib::RefPtr m_file{}; + std::string m_buffer{}; }; } // namespace turns::ui::windows diff --git a/ui/res/ui.cmb b/ui/res/ui.cmb index 37ecbb2..28ef448 100644 --- a/ui/res/ui.cmb +++ b/ui/res/ui.cmb @@ -24,7 +24,7 @@ (1,7,"GtkMenuButton","open_main_menu",3,None,"end",None,None,None,None), (1,8,"GtkButton","add_participant",3,None,"start",None,1,None,None), (1,9,"(menu)","main_menu",None,None,None,None,-1,None,None), - (1,10,"(item)",None,9,None,None,None,3,None,None), + (1,10,"(item)",None,9,None,None,None,4,None,None), (1,18,"GtkButton","start",3,None,"start",None,2,None,None), (1,19,"(item)",None,9,None,None,None,None,None,None), (1,20,"GtkRevealer","controls",2,None,"bottom",None,-1,None,None), @@ -32,12 +32,13 @@ (1,22,"GtkButton",None,21,None,"start",None,-1,None,None), (1,23,"GtkButton",None,21,None,"center",None,-1,None,None), (1,24,"GtkButton",None,21,None,"end",None,-1,None,None), - (1,25,"(item)",None,9,None,None,None,1,None,None), + (1,25,"(item)",None,9,None,None,None,2,None,None), (1,26,"AdwToastOverlay","overlay",2,None,None,None,-1,None,None), (1,30,"GtkStack","stack",26,None,None,None,-1,None,None), (1,31,"AdwStatusPage","empty",30,None,None,None,None,None,None), (1,32,"GtkButton",None,31,None,None,None,None,None,None), - (1,33,"(item)",None,9,None,None,None,2,None,None), + (1,33,"(item)",None,9,None,None,None,3,None,None), + (1,34,"(item)",None,9,None,None,None,1,None,None), (2,1,"AdwDialog","participant_editor",None,None,None,None,-1,None,None), (2,2,"AdwToolbarView",None,1,None,None,None,-1,None,None), (2,3,"AdwHeaderBar",None,2,None,"top",None,-1,None,None), @@ -111,6 +112,8 @@ (1,32,"GtkWidget","halign","center",None,None,None,None,None,None,None,None,None), (1,33,"(item)","action","win.save-as",None,None,None,None,None,None,None,None,None), (1,33,"(item)","label","Save as...",1,None,None,None,None,None,None,None,None), + (1,34,"(item)","action","win.open",None,None,None,None,None,None,None,None,None), + (1,34,"(item)","label","_Open...",1,None,None,None,None,None,None,None,None), (2,1,"AdwDialog","child",None,None,None,None,None,2,None,None,None,None), (2,1,"AdwDialog","default-widget",None,None,None,None,None,None,None,None,None,None), (2,1,"GtkWidget","hexpand","True",None,None,None,None,None,None,None,None,None), diff --git a/ui/src/windows/tracker.cpp b/ui/src/windows/tracker.cpp index 5afadc5..6c248fe 100644 --- a/ui/src/windows/tracker.cpp +++ b/ui/src/windows/tracker.cpp @@ -20,6 +20,8 @@ #include #include +#include +#include #include namespace turns::ui::windows @@ -82,6 +84,12 @@ namespace turns::ui::windows // clang-format on } + auto tracker::do_save() -> void + { + m_buffer = m_turn_order->serialize().dump(2); + m_file->replace_contents_async(sigc::mem_fun(*this, &tracker::handle_save_done), m_buffer, m_file_tag); + } + auto tracker::handle_add_participant() -> void { auto [lifeline, dialog] = editor_for(nullptr); @@ -104,11 +112,62 @@ namespace turns::ui::windows dialog->present(this); } + auto tracker::handle_open() -> void + { + auto filters = Gio::ListStore::create(); + auto filter = Gtk::FileFilter::create(); + filter->set_name(_("Turns Files")); + filter->add_pattern("*.trns"); + filters->append(filter); + + auto dialog = Gtk::FileDialog::create(); + dialog->set_filters(filters); + dialog->open(sigc::bind(sigc::mem_fun(*this, &tracker::handle_open_response), dialog)); + } + + auto tracker::handle_open_done(Glib::RefPtr result) -> void + try + { + set_sensitive(); + char * data{}; + auto size = std::size_t{}; + if (!m_file->load_contents_finish(result, data, size, m_file_tag)) + { + m_file.reset(); + m_file_tag.clear(); + return; + } + auto deserialized = nlohmann::json::parse(std::string_view{data, size}); + m_turn_order->load(deserialized); + auto name = m_file->get_basename(); + auto message = std::vformat(_(lang::successfully_opened_format), std::make_format_args(name)); + auto toast = adw_toast_new(message.c_str()); + adw_toast_overlay_add_toast(m_overlay, toast); + set_title(std::format("{} - {}", _(lang::turns), name)); + } + catch (std::exception const & e) + { + show_error_toast(e); + } + + auto tracker::handle_open_response(Glib::RefPtr result, Glib::RefPtr dialog) -> void + try + { + m_file = dialog->open_finish(result); + m_file->load_contents_async(sigc::mem_fun(*this, &tracker::handle_open_done)); + set_sensitive(false); + } + catch (std::exception const & e) + { + set_sensitive(); + show_error_toast(e); + } + auto tracker::handle_save(bool force_ask) -> void { if (m_file && !force_ask) { - m_file->replace_contents_async(sigc::mem_fun(*this, &tracker::handle_save_done), m_turn_order->serialize().dump(2), m_file_tag); + do_save(); } else { @@ -145,27 +204,21 @@ namespace turns::ui::windows } catch (Gio::Error const & e) { - auto error = e.what(); - auto message = std::vformat(_(lang::saving_failed_format), std::make_format_args(error)); - auto toast = adw_toast_new(message.c_str()); - adw_toast_overlay_add_toast(m_overlay, toast); + show_error_toast(e); } auto tracker::handle_save_response(Glib::RefPtr result, Glib::RefPtr dialog) -> void try { m_file = dialog->save_finish(result); - m_file->replace_contents_async(sigc::mem_fun(*this, &tracker::handle_save_done), m_turn_order->serialize().dump(2), m_file_tag); + do_save(); set_sensitive(false); } catch (Gtk::DialogError const & e) { if (e.code() == Gtk::DialogError::FAILED) { - auto error = e.what(); - auto message = std::vformat(_(lang::saving_failed_format), std::make_format_args(error)); - auto toast = adw_toast_new(message.c_str()); - adw_toast_overlay_add_toast(m_overlay, toast); + show_error_toast(e); } } @@ -249,9 +302,11 @@ namespace turns::ui::windows // win.delete // win.edit + // win.open { add_action_with_parameter("delete", Glib::VARIANT_TYPE_INT32, sigc::mem_fun(*this, &tracker::handle_delete_participant)); add_action_with_parameter("edit", Glib::VARIANT_TYPE_INT32, sigc::mem_fun(*this, &tracker::handle_edit_participant)); + add_action("open", sigc::mem_fun(*this, &tracker::handle_open)); } // win.save @@ -275,6 +330,14 @@ namespace turns::ui::windows } } + auto tracker::show_error_toast(std::exception const & e) -> void + { + auto error = e.what(); + auto message = std::vformat(_(lang::saving_failed_format), std::make_format_args(error)); + auto toast = adw_toast_new(message.c_str()); + adw_toast_overlay_add_toast(m_overlay, toast); + } + auto tracker::update_subtitle() -> void { if (m_turn_order->is_empty()) -- cgit v1.2.3