First go at configurable config.xml location.
authorCarl Hetherington <cth@carlh.net>
Tue, 25 Jul 2017 15:49:35 +0000 (16:49 +0100)
committerCarl Hetherington <cth@carlh.net>
Tue, 25 Jul 2017 15:49:35 +0000 (16:49 +0100)
12 files changed:
ChangeLog
src/lib/config.cc
src/lib/config.h
src/tools/dcpomatic.cc
src/wx/config_dialog.cc
src/wx/config_move_dialog.cc [new file with mode: 0644]
src/wx/config_move_dialog.h [new file with mode: 0644]
src/wx/confirm_kdm_email_dialog.cc
src/wx/confirm_kdm_email_dialog.h
src/wx/question_dialog.cc [new file with mode: 0644]
src/wx/question_dialog.h [new file with mode: 0644]
src/wx/wscript

index 7b887af45be03fa777cf3ec617bf98ee3c9633a2..687e30757454ce37c1e8e03a71157ee2e1847eee 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2017-07-25  Carl Hetherington  <cth@carlh.net>
+
+       * Configurable config.xml location (#780, #1100).
+
 2017-07-24  Carl Hetherington  <cth@carlh.net>
 
        * Update ISDCF name when DCP frame rate changes (#1102).
index b7b7b22421c814f4ec2205f106c042c8e90dae4b..02724e6956bb23be4b2a1ffad578afdad855ff78 100644 (file)
@@ -162,25 +162,12 @@ Config::create_certificate_chain ()
                );
 }
 
-boost::filesystem::path
-Config::target (boost::filesystem::path file)
-{
-       cxml::Document f ("Config");
-       f.read_file (file);
-       optional<string> link = f.optional_string_child ("Link");
-       if (link) {
-               return target (*link);
-       }
-
-       return file;
-}
-
 void
 Config::read ()
 try
 {
        cxml::Document f ("Config");
-       f.read_file (target(path("config.xml")));
+       f.read_file (config_file());
 
        optional<int> version = f.optional_number_child<int> ("Version");
 
@@ -548,7 +535,7 @@ Config::write_config () const
        root->add_child("CoverSheet")->add_child_text (_cover_sheet);
 
        try {
-               doc.write_to_file_formatted (target(path("config.xml")).string ());
+               doc.write_to_file_formatted(config_file().string());
        } catch (xmlpp::exception& e) {
                string s = e.what ();
                trim (s);
@@ -748,11 +735,19 @@ Config::delete_template (string name) const
        boost::filesystem::remove (template_path (name));
 }
 
-/** @return Path to the config.xml, for telling the user what it is */
+/** @return Path to the config.xml containing the actual settings, following a link if required */
 boost::filesystem::path
-Config::config_path ()
+Config::config_file ()
 {
-       return path("config.xml", false);
+       cxml::Document f ("Config");
+       boost::filesystem::path main = path("config.xml", false);
+       f.read_file (main);
+       optional<string> link = f.optional_string_child("Link");
+       if (link) {
+               return *link;
+       }
+
+       return main;
 }
 
 void
@@ -761,3 +756,25 @@ Config::reset_cover_sheet ()
        set_cover_sheet_to_default ();
        changed ();
 }
+
+void
+Config::link (boost::filesystem::path new_file) const
+{
+       xmlpp::Document doc;
+       doc.create_root_node("Config")->add_child("Link")->add_child_text(new_file.string());
+       try {
+               doc.write_to_file_formatted(path("config.xml", true).string());
+       } catch (xmlpp::exception& e) {
+               string s = e.what ();
+               trim (s);
+               throw FileError (s, path("config.xml"));
+       }
+}
+
+void
+Config::copy_and_link (boost::filesystem::path new_file) const
+{
+       write ();
+       boost::filesystem::copy_file (config_file(), new_file, boost::filesystem::copy_option::overwrite_if_exists);
+       link (new_file);
+}
index 200857aa9f74be788bbac14089eacda2d41e71c6..3317f1f100a2a874e9c0276f1e15072957ec2e61 100644 (file)
@@ -629,6 +629,8 @@ public:
        void write () const;
        void write_config () const;
        void write_cinemas () const;
+       void link (boost::filesystem::path new_file) const;
+       void copy_and_link (boost::filesystem::path new_file) const;
 
        void save_template (boost::shared_ptr<const Film> film, std::string name) const;
        bool existing_template (std::string name) const;
@@ -641,12 +643,11 @@ public:
        static void drop ();
        static void restore_defaults ();
        static bool have_existing (std::string);
-       static boost::filesystem::path config_path ();
+       static boost::filesystem::path config_file ();
 
 private:
        Config ();
        static boost::filesystem::path path (std::string file, bool create_directories = true);
-       static boost::filesystem::path target (boost::filesystem::path file);
        void read ();
        void set_defaults ();
        void set_kdm_email_to_default ();
index 80b25ba2e5dee5549601288f96c73420cba0d16b..4b79d67ed028e37d2c69888bb72d97c1475eec14 100644 (file)
@@ -667,7 +667,7 @@ private:
                                _("You are making a DKDM which is encrypted by a private key held in"
                                  "\n\n<tt>%s</tt>\n\nIt is <span weight=\"bold\" size=\"larger\">VITALLY IMPORTANT</span> "
                                  "that you <span weight=\"bold\" size=\"larger\">BACK UP THIS FILE</span> since if it is lost "
-                                 "your DKDMs (and the DCPs they protect) will become useless."), std_to_wx(Config::config_path().string()).data()
+                                 "your DKDMs (and the DCPs they protect) will become useless."), std_to_wx(Config::config_file().string()).data()
                                )
                        );
 
index 233766cbaddd27395ea77033f5c872441a01fb3c..f41d5146cb503d928143853f50d12751f28d297c 100644 (file)
@@ -34,6 +34,7 @@
 #include "email_dialog.h"
 #include "name_format_editor.h"
 #include "nag_dialog.h"
+#include "config_move_dialog.h"
 #include "lib/config.h"
 #include "lib/ratio.h"
 #include "lib/filter.h"
@@ -212,6 +213,11 @@ private:
                table->Add (_server_encoding_threads, wxGBPosition (r, 1));
                ++r;
 
+               add_label_to_sizer (table, _panel, _("Configuration file"), true, wxGBPosition (r, 0));
+               _config_file = new FilePickerCtrl (_panel, _("Select configuration file"), "*.xml", true);
+               table->Add (_config_file, wxGBPosition (r, 1));
+               ++r;
+
                add_label_to_sizer (table, _panel, _("Cinema and screen database file"), true, wxGBPosition (r, 0));
                _cinemas_file = new FilePickerCtrl (_panel, _("Select cinema and screen database file"), "*.xml", true);
                table->Add (_cinemas_file, wxGBPosition (r, 1));
@@ -265,6 +271,7 @@ private:
 
                _set_language->Bind         (wxEVT_CHECKBOX,           boost::bind (&GeneralPage::set_language_changed,  this));
                _language->Bind             (wxEVT_CHOICE,             boost::bind (&GeneralPage::language_changed,      this));
+               _config_file->Bind          (wxEVT_FILEPICKER_CHANGED, boost::bind (&GeneralPage::config_file_changed,   this));
                _cinemas_file->Bind         (wxEVT_FILEPICKER_CHANGED, boost::bind (&GeneralPage::cinemas_file_changed,  this));
                _preview_sound->Bind        (wxEVT_CHECKBOX,           boost::bind (&GeneralPage::preview_sound_changed, this));
                _preview_sound_output->Bind (wxEVT_CHOICE,             boost::bind (&GeneralPage::preview_sound_output_changed, this));
@@ -325,6 +332,7 @@ private:
                checked_set (_check_for_test_updates, config->check_for_test_updates ());
                checked_set (_issuer, config->dcp_issuer ());
                checked_set (_creator, config->dcp_creator ());
+               checked_set (_config_file, config->config_file());
                checked_set (_cinemas_file, config->cinemas_file());
                checked_set (_preview_sound, config->preview_sound());
 
@@ -438,6 +446,32 @@ private:
                Config::instance()->set_dcp_creator (wx_to_std (_creator->GetValue ()));
        }
 
+       void config_file_changed ()
+       {
+               Config* config = Config::instance();
+               boost::filesystem::path new_file = wx_to_std(_config_file->GetPath());
+               if (new_file == config->config_file()) {
+                       return;
+               }
+               bool copy_and_link = true;
+               if (boost::filesystem::exists(new_file)) {
+                       ConfigMoveDialog* d = new ConfigMoveDialog (_panel, new_file);
+                       if (d->ShowModal() == wxID_OK) {
+                               copy_and_link = false;
+                       }
+                       d->Destroy ();
+               }
+
+               if (copy_and_link) {
+                       config->write ();
+                       if (new_file != config->config_file()) {
+                               config->copy_and_link (new_file);
+                       }
+               } else {
+                       config->link (new_file);
+               }
+       }
+
        void cinemas_file_changed ()
        {
                Config::instance()->set_cinemas_file (wx_to_std (_cinemas_file->GetPath ()));
@@ -463,6 +497,7 @@ private:
        wxChoice* _language;
        wxSpinCtrl* _master_encoding_threads;
        wxSpinCtrl* _server_encoding_threads;
+       FilePickerCtrl* _config_file;
        FilePickerCtrl* _cinemas_file;
        wxCheckBox* _preview_sound;
        wxChoice* _preview_sound_output;
diff --git a/src/wx/config_move_dialog.cc b/src/wx/config_move_dialog.cc
new file mode 100644 (file)
index 0000000..ec677f6
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+    Copyright (C) 2017 Carl Hetherington <cth@carlh.net>
+
+    This file is part of DCP-o-matic.
+
+    DCP-o-matic is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    DCP-o-matic is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with DCP-o-matic.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "config_move_dialog.h"
+#include "wx_util.h"
+#include <boost/filesystem.hpp>
+
+ConfigMoveDialog::ConfigMoveDialog (wxWindow* parent, boost::filesystem::path new_file)
+       : QuestionDialog (
+               parent,
+               _("Move configuration"),
+               _("Use this file as new configuration"),
+               _("Overwrite this file with current configuration")
+               )
+{
+       wxString message = wxString::Format (
+               _("The file %s already exists.  Do you want to use it as your new configuration or overwrite it with your current configuration?"),
+               std_to_wx(new_file.string()).data()
+               );
+
+       _sizer->Add (new wxStaticText (this, wxID_ANY, message), 1, wxEXPAND | wxALL, DCPOMATIC_DIALOG_BORDER);
+
+       layout ();
+}
diff --git a/src/wx/config_move_dialog.h b/src/wx/config_move_dialog.h
new file mode 100644 (file)
index 0000000..b7cea11
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+    Copyright (C) 2017 Carl Hetherington <cth@carlh.net>
+
+    This file is part of DCP-o-matic.
+
+    DCP-o-matic is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    DCP-o-matic is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with DCP-o-matic.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "question_dialog.h"
+#include <boost/filesystem.hpp>
+
+class ConfigMoveDialog : public QuestionDialog
+{
+public:
+       ConfigMoveDialog (wxWindow* parent, boost::filesystem::path new_file);
+};
index d622f2934524c7d20637485941bfe282f25fc89e..4815f26dbd8749619a4c1d72d15d9528fe6da24f 100644 (file)
@@ -28,31 +28,21 @@ using std::list;
 using std::string;
 
 ConfirmKDMEmailDialog::ConfirmKDMEmailDialog (wxWindow* parent, list<string> emails)
-       : wxDialog (parent, wxID_ANY, _("Confirm KDM email"))
+       : QuestionDialog (parent, _("Confirm KDM email"), _("Send emails"), _("Don't send emails"))
 {
-       wxBoxSizer* sizer = new wxBoxSizer (wxVERTICAL);
-
        wxString message = _("Are you sure you want to send emails to the following addresses?\n\n");
        BOOST_FOREACH (string i, emails) {
                message += "\t" + std_to_wx (i) + "\n";
        }
 
-       sizer->Add (new wxStaticText (this, wxID_ANY, message), 1, wxEXPAND | wxALL, DCPOMATIC_DIALOG_BORDER);
+       _sizer->Add (new wxStaticText (this, wxID_ANY, message), 1, wxEXPAND | wxALL, DCPOMATIC_DIALOG_BORDER);
 
        wxCheckBox* shut_up = new wxCheckBox (this, wxID_ANY, _("Don't ask this again"));
-       sizer->Add (shut_up, 0, wxALL, DCPOMATIC_DIALOG_BORDER);
+       _sizer->Add (shut_up, 0, wxALL, DCPOMATIC_DIALOG_BORDER);
 
        shut_up->Bind (wxEVT_CHECKBOX, bind (&ConfirmKDMEmailDialog::shut_up, this, _1));
 
-       wxStdDialogButtonSizer* buttons = CreateStdDialogButtonSizer (0);
-       sizer->Add (CreateSeparatedSizer(buttons), wxSizerFlags().Expand().DoubleBorder());
-       buttons->SetAffirmativeButton (new wxButton (this, wxID_OK, _("Send emails")));
-       buttons->SetNegativeButton (new wxButton (this, wxID_CANCEL, _("Don't send emails")));
-       buttons->Realize ();
-
-       SetSizer (sizer);
-       sizer->Layout ();
-       sizer->SetSizeHints (this);
+       layout ();
 }
 
 void
index 84182ad935b402c63cfff89653189a0f7d061c47..311cb08ea6dbddcd8a171e4f5bbf417011d893eb 100644 (file)
 
 */
 
+#include "question_dialog.h"
 #include <wx/wx.h>
 #include <list>
 
-class ConfirmKDMEmailDialog : public wxDialog
+class ConfirmKDMEmailDialog : public QuestionDialog
 {
 public:
        ConfirmKDMEmailDialog (wxWindow* parent, std::list<std::string> addresses);
diff --git a/src/wx/question_dialog.cc b/src/wx/question_dialog.cc
new file mode 100644 (file)
index 0000000..5b6c0b4
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+    Copyright (C) 2017 Carl Hetherington <cth@carlh.net>
+
+    This file is part of DCP-o-matic.
+
+    DCP-o-matic is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    DCP-o-matic is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with DCP-o-matic.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "question_dialog.h"
+
+QuestionDialog::QuestionDialog (wxWindow* parent, wxString title, wxString affirmative, wxString negative)
+       : wxDialog (parent, wxID_ANY, title)
+       , _affirmative (affirmative)
+       , _negative (negative)
+{
+       _sizer = new wxBoxSizer (wxVERTICAL);
+       SetSizer (_sizer);
+}
+
+void
+QuestionDialog::layout ()
+{
+       wxStdDialogButtonSizer* buttons = CreateStdDialogButtonSizer (0);
+       _sizer->Add (CreateSeparatedSizer(buttons), wxSizerFlags().Expand().DoubleBorder());
+       buttons->SetAffirmativeButton (new wxButton (this, wxID_OK, _affirmative));
+       buttons->SetNegativeButton (new wxButton (this, wxID_CANCEL, _negative));
+       buttons->Realize ();
+
+       _sizer->Layout ();
+       _sizer->SetSizeHints (this);
+}
diff --git a/src/wx/question_dialog.h b/src/wx/question_dialog.h
new file mode 100644 (file)
index 0000000..a3b0517
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+    Copyright (C) 2017 Carl Hetherington <cth@carlh.net>
+
+    This file is part of DCP-o-matic.
+
+    DCP-o-matic is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    DCP-o-matic is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with DCP-o-matic.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include <wx/wx.h>
+
+class QuestionDialog : public wxDialog
+{
+public:
+       QuestionDialog (wxWindow* parent, wxString title, wxString affirmative, wxString negative);
+
+protected:
+       void layout ();
+       wxSizer* _sizer;
+       wxString _affirmative;
+       wxString _negative;
+};
index 142f0a24eb3f28bc4c64727e88a5585c4fcf53e2..66b928247c3eadb5cda91e0c89550a0486f5b74f 100644 (file)
@@ -35,6 +35,7 @@ sources = """
           cinema_dialog.cc
           colour_conversion_editor.cc
           config_dialog.cc
+          config_move_dialog.cc
           confirm_kdm_email_dialog.cc
           content_colour_conversion_dialog.cc
           content_menu.cc
@@ -76,6 +77,7 @@ sources = """
           normal_job_view.cc
           playhead_to_timecode_dialog.cc
           playhead_to_frame_dialog.cc
+          question_dialog.cc
           repeat_dialog.cc
           report_problem_dialog.cc
           rename_template_dialog.cc