summaryrefslogtreecommitdiff
path: root/ui
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@gmail.com>2024-07-26 15:48:13 +0200
committerFelix Morgner <felix.morgner@gmail.com>2024-07-26 15:48:13 +0200
commit7a093920809394f7f31b75c444fe6009d1de7005 (patch)
treeb348b9731a6f771209fa5d1ca2330aae27402b2d /ui
parent3d02c5f637f47493d15be3f18cc295010f08c727 (diff)
downloadturns-7a093920809394f7f31b75c444fe6009d1de7005.tar.xz
turns-7a093920809394f7f31b75c444fe6009d1de7005.zip
ui: tracker implement loading UI
Diffstat (limited to 'ui')
-rw-r--r--ui/include/turns/ui/windows/tracker.hpp9
-rw-r--r--ui/res/ui.cmb9
-rw-r--r--ui/src/windows/tracker.cpp83
3 files changed, 88 insertions, 13 deletions
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 <optional>
#include <string>
+#include <stdexcept>
namespace turns::ui::windows
{
@@ -32,15 +33,22 @@ namespace turns::ui::windows
tracker(BaseObjectType * base, Glib::RefPtr<Gtk::Builder> 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<Gio::AsyncResult> result) -> void;
+ auto handle_open_response(Glib::RefPtr<Gio::AsyncResult> result, Glib::RefPtr<Gtk::FileDialog> dialog) -> void;
auto handle_save(bool force_ask) -> void;
auto handle_save_done(Glib::RefPtr<Gio::AsyncResult> result) -> void;
auto handle_save_response(Glib::RefPtr<Gio::AsyncResult> result, Glib::RefPtr<Gtk::FileDialog> 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<Gio::File> 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 <nlohmann/json.hpp>
#include <format>
+#include <stdexcept>
+#include <string_view>
#include <utility>
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<Gtk::FileFilter>::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<Gio::AsyncResult> 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<Gio::AsyncResult> result, Glib::RefPtr<Gtk::FileDialog> 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<Gio::AsyncResult> result, Glib::RefPtr<Gtk::FileDialog> 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())