Remember whether Content or DCP is selected in a new ui.xml state file.
authorCarl Hetherington <cth@carlh.net>
Fri, 22 Dec 2023 16:02:43 +0000 (17:02 +0100)
committerCarl Hetherington <cth@carlh.net>
Sun, 28 Jan 2024 01:01:58 +0000 (02:01 +0100)
src/lib/film.cc
src/lib/film.h
src/tools/dcpomatic.cc
src/wx/film_editor.cc
src/wx/film_editor.h

index 871ec76b8404b5a6f9d28a0b88b72281a7f791bb..c56cd36df6f0ae9ada472efcb582245c21f636f5 100644 (file)
@@ -114,6 +114,7 @@ using namespace dcpomatic;
 
 
 static constexpr char metadata_file[] = "metadata.xml";
+static constexpr char ui_state_file[] = "ui.xml";
 
 
 /* 5 -> 6
@@ -2231,3 +2232,53 @@ Film::set_territory_type(TerritoryType type)
        _territory_type = type;
 }
 
+
+void
+Film::set_ui_state(string key, string value)
+{
+       _ui_state[key] = value;
+       write_ui_state();
+}
+
+
+boost::optional<std::string>
+Film::ui_state(string key) const
+{
+       auto iter = _ui_state.find(key);
+       if (iter == _ui_state.end()) {
+               return {};
+       }
+
+       return iter->second;
+}
+
+
+void
+Film::write_ui_state() const
+{
+       auto doc = make_shared<xmlpp::Document>();
+       auto root = doc->create_root_node("UI");
+
+       for (auto state: _ui_state) {
+               root->add_child(state.first)->add_child_text(state.second);
+       }
+
+       try {
+               doc->write_to_file_formatted(dcp::filesystem::fix_long_path(file(ui_state_file)).string());
+       } catch (...) {}
+}
+
+
+void
+Film::read_ui_state()
+{
+       try {
+               cxml::Document xml("UI");
+               xml.read_file(dcp::filesystem::fix_long_path(file(ui_state_file)));
+               for (auto node: xml.node_children()) {
+                       if (!node->is_text()) {
+                               _ui_state[node->name()] = node->content();
+                       }
+               }
+       } catch (...) {}
+}
index 43a41ad45d5a43fbeaf92accdea2595e9155e6db..036bbed7ef3ad8e0a13aa6c24ea5223bbbc52b1b 100644 (file)
@@ -434,6 +434,10 @@ public:
 
        void add_ffoc_lfoc (Markers& markers) const;
 
+       void set_ui_state(std::string key, std::string value);
+       boost::optional<std::string> ui_state(std::string key) const;
+       void read_ui_state();
+
        /** Emitted when some property has of the Film is about to change or has changed */
        mutable boost::signals2::signal<void (ChangeType, FilmProperty)> Change;
 
@@ -477,6 +481,7 @@ private:
        void check_settings_consistency ();
        void maybe_set_container_and_resolution ();
        void set_dirty (bool dirty);
+       void write_ui_state() const;
 
        /** Log to write to */
        std::shared_ptr<Log> _log;
@@ -562,6 +567,8 @@ private:
        */
        bool _tolerant;
 
+       std::map<std::string, std::string> _ui_state;
+
        mutable boost::mutex _info_file_mutex;
 
        boost::signals2::scoped_connection _playlist_change_connection;
index 7c00ef12f8631edab9c5e8000c377b0e10b50b09..d3efd1f978669c87706b821d5057e5b443149364 100644 (file)
@@ -465,6 +465,7 @@ public:
        {
                auto film = make_shared<Film>(file);
                auto const notes = film->read_metadata ();
+               film->read_ui_state();
 
                if (film->state_version() == 4) {
                        error_dialog (
index 9f54db58e027e9b651f830d098d41045c0e91775..fae02787ab2c12d5cc8e9328138a4d4fea0933d7 100644 (file)
@@ -54,13 +54,15 @@ FilmEditor::FilmEditor(wxWindow* parent, FilmViewer& viewer)
 {
        auto s = new wxBoxSizer (wxVERTICAL);
 
-       auto notebook = new wxNotebook(this, wxID_ANY);
-       s->Add(notebook, 1, wxEXPAND);
+       _notebook = new wxNotebook(this, wxID_ANY);
+       s->Add(_notebook, 1, wxEXPAND);
 
-       _content_panel = new ContentPanel(notebook, _film, viewer);
-       notebook->AddPage(_content_panel->window(), _("Content"), true);
-       _dcp_panel = new DCPPanel(notebook, _film, viewer);
-       notebook->AddPage(_dcp_panel->panel (), _("DCP"), false);
+       _content_panel = new ContentPanel(_notebook, _film, viewer);
+       _notebook->AddPage(_content_panel->window(), _("Content"), true);
+       _dcp_panel = new DCPPanel(_notebook, _film, viewer);
+       _notebook->AddPage(_dcp_panel->panel (), _("DCP"), false);
+
+       _notebook->Bind(wxEVT_NOTEBOOK_PAGE_CHANGED, boost::bind(&FilmEditor::page_changed, this, _1));
 
        JobManager::instance()->ActiveJobsChanged.connect (
                bind(&FilmEditor::active_jobs_changed, this, _2)
@@ -71,6 +73,18 @@ FilmEditor::FilmEditor(wxWindow* parent, FilmViewer& viewer)
 }
 
 
+void
+FilmEditor::page_changed(wxBookCtrlEvent& ev)
+{
+       /* One of these events arrives early on with GetOldSelection() being a non-existent tab,
+        * and we want to ignore that.
+        */
+       if (_film && ev.GetOldSelection() < 2) {
+               _film->set_ui_state("FilmEditorTab", ev.GetSelection() == 0 ? "content" : "dcp");
+       }
+}
+
+
 /** Called when the metadata stored in the Film object has changed;
  *  so that we can update the GUI.
  *  @param p Property of the Film that has changed.
@@ -144,6 +158,13 @@ FilmEditor::set_film (shared_ptr<Film> film)
        if (!_film->content().empty()) {
                _content_panel->set_selection (_film->content().front());
        }
+
+       auto tab = _film->ui_state("FilmEditorTab").get_value_or("content");
+       if (tab == "content") {
+               _notebook->SetSelection(0);
+       } else if (tab == "dcp") {
+               _notebook->SetSelection(1);
+       }
 }
 
 
index 75a09ba029fcf9237b1de64dbe540b122568b779..54d639ef595bd12102f66091a86d66d0ac4abbab 100644 (file)
@@ -36,6 +36,7 @@ class ContentPanel;
 class DCPPanel;
 class Film;
 class FilmViewer;
+class wxBookCtrlEvent;
 class wxNotebook;
 
 
@@ -71,6 +72,9 @@ private:
        void set_general_sensitivity (bool);
        void active_jobs_changed (boost::optional<std::string>);
 
+       void page_changed(wxBookCtrlEvent& ev);
+
+       wxNotebook* _notebook;
        ContentPanel* _content_panel;
        DCPPanel* _dcp_panel;