Fix merge.
authorCarl Hetherington <cth@carlh.net>
Tue, 8 Mar 2016 10:36:44 +0000 (10:36 +0000)
committerCarl Hetherington <cth@carlh.net>
Tue, 8 Mar 2016 10:36:44 +0000 (10:36 +0000)
ChangeLog
src/lib/cinema.cc
src/lib/cinema.h
src/lib/film.cc
src/lib/film.h
src/tools/dcpomatic_kdm.cc
src/tools/dcpomatic_kdm_cli.cc
src/wx/cinema_dialog.cc
src/wx/cinema_dialog.h
src/wx/kdm_dialog.h
src/wx/screens_panel.cc

index 89472fec5e63969cf7205628123fa1fda8fd6297..a98e4ffc00a775e8b8c938bc1af0c131fa41eb07 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
 2016-03-08  Carl Hetherington  <cth@carlh.net>
 
+       * Store time zone with cinemas and use them to
+       mark KDM start and end times correctly (#788).
+
        * Bump ffmpeg to git master, somewhere post 3.0.
 
 2016-03-08  Carl Hetherington  <cth@carlh.net>
index ebd7160098df67d6657016427e09ca6037b47451..5e2b1b533bb49df0926844c15366fec3ff88e063 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2013-2015 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2013-2016 Carl Hetherington <cth@carlh.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
 
 #include "cinema.h"
 #include "screen.h"
+#include "dcpomatic_assert.h"
 #include <libcxml/cxml.h>
+#include <dcp/raw_convert.h>
 #include <libxml++/libxml++.h>
 #include <boost/foreach.hpp>
+#include <iostream>
 
 using std::list;
 using std::string;
@@ -29,6 +32,7 @@ using boost::shared_ptr;
 
 Cinema::Cinema (cxml::ConstNodePtr node)
        : name (node->string_child ("Name"))
+       , _utc_offset (node->optional_number_child<int>("UTCOffset").get_value_or (0))
 {
        BOOST_FOREACH (cxml::ConstNodePtr i, node->node_children("Email")) {
                emails.push_back (i->content ());
@@ -56,6 +60,8 @@ Cinema::as_xml (xmlpp::Element* parent) const
                parent->add_child("Email")->add_child_text (i);
        }
 
+       parent->add_child("UTCOffset")->add_child_text (dcp::raw_convert<string> (_utc_offset));
+
        BOOST_FOREACH (shared_ptr<Screen> i, _screens) {
                i->as_xml (parent->add_child ("Screen"));
        }
@@ -73,3 +79,10 @@ Cinema::remove_screen (shared_ptr<Screen> s)
 {
        _screens.remove (s);
 }
+
+void
+Cinema::set_utc_offset (int o)
+{
+       DCPOMATIC_ASSERT (o >= -11 && o <= 12);
+       _utc_offset = o;
+}
index aec4c83eca5ac25346a9754d62f69a61700565e6..7df83c7678f2c4c40ef9751707d20908917a6966 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2013-2014 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2013-2016 Carl Hetherington <cth@carlh.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -33,15 +33,16 @@ class Screen;
 /** @class Cinema
  *  @brief A description of a Cinema for KDM generation.
  *
- *  This is a cinema name, contact email addresses and a list of
+ *  This is a cinema name, some metadata and a list of
  *  Screen objects.
  */
 class Cinema : public boost::enable_shared_from_this<Cinema>
 {
 public:
-       Cinema (std::string const & n, std::list<std::string> const & e)
+       Cinema (std::string const & n, std::list<std::string> const & e, int utc_offset)
                : name (n)
                , emails (e)
+               , _utc_offset (utc_offset)
        {}
 
        Cinema (cxml::ConstNodePtr);
@@ -53,12 +54,21 @@ public:
        void add_screen (boost::shared_ptr<Screen>);
        void remove_screen (boost::shared_ptr<Screen>);
 
+       void set_utc_offset (int o);
+
        std::string name;
        std::list<std::string> emails;
+       int utc_offset () const {
+               return _utc_offset;
+       }
        std::list<boost::shared_ptr<Screen> > screens () const {
                return _screens;
        }
 
 private:
        std::list<boost::shared_ptr<Screen> > _screens;
+       /** Offset such that the equivalent time in UTC can be determined
+           by subtracting the offset from the local time.
+       */
+       int _utc_offset;
 };
index 1b0f140959cb5b5b09372a78f63b4cd234bd592c..e669ea4ae434a2f8d08cdbb0b0aca78370d9f86e 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2012-2016 Carl Hetherington <cth@carlh.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -50,6 +50,7 @@
 #include "ffmpeg_content.h"
 #include "dcp_content.h"
 #include "screen_kdm.h"
+#include "cinema.h"
 #include <libcxml/cxml.h>
 #include <dcp/cpl.h>
 #include <dcp/certificate_chain.h>
@@ -1163,6 +1164,9 @@ Film::frame_size () const
        return fit_ratio_within (container()->ratio(), full_frame ());
 }
 
+/** @param from KDM from time expressed as a local time with an offset from UTC
+ *  @param to KDM to time expressed as a local time with an offset from UTC
+ */
 dcp::EncryptedKDM
 Film::make_kdm (
        dcp::Certificate recipient,
@@ -1184,12 +1188,15 @@ Film::make_kdm (
                ).encrypt (signer, recipient, trusted_devices, formulation);
 }
 
+/** @param from KDM from time expressed as a local time in the time zone of the Screen's Cinema.
+ *  @param to KDM to time expressed as a local time in the time zone of the Screen's Cinema.
+ */
 list<ScreenKDM>
 Film::make_kdms (
        list<shared_ptr<Screen> > screens,
        boost::filesystem::path dcp,
-       dcp::LocalTime from,
-       dcp::LocalTime until,
+       boost::posix_time::ptime from,
+       boost::posix_time::ptime until,
        dcp::Formulation formulation
        ) const
 {
@@ -1197,7 +1204,16 @@ Film::make_kdms (
 
        BOOST_FOREACH (shared_ptr<Screen> i, screens) {
                if (i->recipient) {
-                       kdms.push_back (ScreenKDM (i, make_kdm (i->recipient.get(), i->trusted_devices, dcp, from, until, formulation)));
+                       dcp::EncryptedKDM const kdm = make_kdm (
+                               i->recipient.get(),
+                               i->trusted_devices,
+                               dcp,
+                               dcp::LocalTime (from, i->cinema->utc_offset(), 0),
+                               dcp::LocalTime (until, i->cinema->utc_offset(), 0),
+                               formulation
+                               );
+
+                       kdms.push_back (ScreenKDM (i, kdm));
                }
        }
 
index b34e4bcfa03883c39359d840e3a7d22cf468b7b7..b8e31a4205650c08a4fd8775948f93ffca773aa7 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2012-2016 Carl Hetherington <cth@carlh.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -132,8 +132,8 @@ public:
        std::list<ScreenKDM> make_kdms (
                std::list<boost::shared_ptr<Screen> >,
                boost::filesystem::path cpl_file,
-               dcp::LocalTime from,
-               dcp::LocalTime until,
+               boost::posix_time::ptime from,
+               boost::posix_time::ptime until,
                dcp::Formulation formulation
                ) const;
 
index 643aaeb7730a8cc830175d9a99253159cf731510..b98ec84a9aa939cf165c84bd1283afc8aad10e56 100644 (file)
@@ -38,6 +38,7 @@
 #include "lib/cinema_kdms.h"
 #include "lib/send_kdm_email_job.h"
 #include "lib/compose.hpp"
+#include "lib/cinema.h"
 #include <dcp/encrypted_kdm.h>
 #include <dcp/decrypted_kdm.h>
 #include <dcp/exceptions.h>
@@ -270,7 +271,11 @@ private:
 
                                /* Make an empty KDM */
                                dcp::DecryptedKDM kdm (
-                                       _timing->from(), _timing->until(), decrypted.annotation_text(), decrypted.content_title_text(), dcp::LocalTime().as_string()
+                                       dcp::LocalTime (_timing->from(), i->cinema->utc_offset(), 0),
+                                       dcp::LocalTime (_timing->until(), i->cinema->utc_offset(), 0),
+                                       decrypted.annotation_text(),
+                                       decrypted.content_title_text(),
+                                       dcp::LocalTime().as_string()
                                        );
 
                                /* Add keys from the DKDM */
index 2f8212a619fe2acc0e5035ea93b3d04031ff67a4..2a6ce9e12620aa5360bf132b2c010f9f189a6487 100644 (file)
@@ -46,8 +46,8 @@ help ()
        cerr << "Syntax: " << program_name << " [OPTION] [<FILM>]\n"
                "  -h, --help             show this help\n"
                "  -o, --output           output file or directory\n"
-               "  -f, --valid-from       valid from time (in local time zone) (e.g. \"2013-09-28 01:41:51\") or \"now\"\n"
-               "  -t, --valid-to         valid to time (in local time zone) (e.g. \"2014-09-28 01:41:51\")\n"
+               "  -f, --valid-from       valid from time (in local time zone of the cinema) (e.g. \"2013-09-28 01:41:51\") or \"now\"\n"
+               "  -t, --valid-to         valid to time (in local time zone of the cinema) (e.g. \"2014-09-28 01:41:51\")\n"
                "  -d, --valid-duration   valid duration (e.g. \"1 day\", \"4 hours\", \"2 weeks\")\n"
                "      --formulation      modified-transitional-1, dci-any or dci-specific [default modified-transitional-1]\n"
                "  -z, --zip              ZIP each cinema's KDMs into its own file\n"
@@ -283,7 +283,7 @@ int main (int argc, char* argv[])
 
                try {
                        list<ScreenKDM> screen_kdms = film->make_kdms (
-                               (*i)->screens(), cpl, dcp::LocalTime (valid_from.get()), dcp::LocalTime (valid_to.get()), formulation
+                               (*i)->screens(), cpl, valid_from.get(), valid_to.get(), formulation
                                );
 
                        if (zip) {
index 183e3b1b263daf709e1b03d9f545bb09de6b6cea..6fb4acc6b5f8465851731fa7b997f9a94828acfc 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2012 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2012-2016 Carl Hetherington <cth@carlh.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -19,6 +19,7 @@
 
 #include "cinema_dialog.h"
 #include "wx_util.h"
+#include "lib/dcpomatic_assert.h"
 #include <boost/foreach.hpp>
 
 using std::string;
@@ -35,7 +36,7 @@ column (string s)
        return s;
 }
 
-CinemaDialog::CinemaDialog (wxWindow* parent, string title, string name, list<string> emails)
+CinemaDialog::CinemaDialog (wxWindow* parent, string title, string name, list<string> emails, int utc_offset)
        : wxDialog (parent, wxID_ANY, std_to_wx (title))
 {
        wxBoxSizer* overall_sizer = new wxBoxSizer (wxVERTICAL);
@@ -49,6 +50,11 @@ CinemaDialog::CinemaDialog (wxWindow* parent, string title, string name, list<st
        sizer->Add (_name, wxGBPosition (r, 1));
        ++r;
 
+       add_label_to_sizer (sizer, this, _("UTC offset (time zone)"), true, wxGBPosition (r, 0));
+       _utc_offset = new wxChoice (this, wxID_ANY);
+       sizer->Add (_utc_offset, wxGBPosition (r, 1));
+       ++r;
+
        add_label_to_sizer (sizer, this, _("Email addresses for KDM delivery"), false, wxGBPosition (r, 0), wxGBSpan (1, 2));
        ++r;
 
@@ -70,6 +76,16 @@ CinemaDialog::CinemaDialog (wxWindow* parent, string title, string name, list<st
                overall_sizer->Add (buttons, wxSizerFlags().Expand().DoubleBorder());
        }
 
+       for (int i = -11; i <= -1; ++i) {
+               _utc_offset->Append (wxString::Format (_("UTC%d"), i));
+       }
+       _utc_offset->Append (_("UTC"));
+       for (int i = 1; i <= 12; ++i) {
+               _utc_offset->Append (wxString::Format (_("UTC+%d"), i));
+       }
+
+       _utc_offset->SetSelection (utc_offset + 11);
+
        overall_sizer->Layout ();
        overall_sizer->SetSizeHints (this);
 }
@@ -99,3 +115,9 @@ CinemaDialog::emails () const
        copy (_emails.begin(), _emails.end(), back_inserter (e));
        return e;
 }
+
+int
+CinemaDialog::utc_offset () const
+{
+       return _utc_offset->GetSelection() - 11;
+}
index 7d27bd94b473492cfc8dd90fc605bf20f19a3977..a34935e51274193a1fcfa9399ed11fb7969fda66 100644 (file)
 class CinemaDialog : public wxDialog
 {
 public:
-       CinemaDialog (wxWindow *, std::string, std::string name = "", std::list<std::string> emails = std::list<std::string> ());
+       CinemaDialog (wxWindow *, std::string, std::string name = "", std::list<std::string> emails = std::list<std::string> (), int utc_offset = 0);
 
        std::string name () const;
        std::list<std::string> emails () const;
+       int utc_offset () const;
 
 private:
        std::vector<std::string> get_emails () const;
@@ -39,4 +40,5 @@ private:
        wxTextCtrl* _name;
        EditableList<std::string, EmailDialog>* _email_list;
        std::vector<std::string> _emails;
+       wxChoice* _utc_offset;
 };
index 3ec21b41dd5b824dcbdf0ed5a849609b6fffff93..0f7840045c6ac93c7eff6e2e9836e016cb1dd5b4 100644 (file)
@@ -39,9 +39,9 @@ public:
        KDMDialog (wxWindow *, boost::shared_ptr<const Film>);
 
        std::list<boost::shared_ptr<Screen> > screens () const;
-       /** @return KDM from time in local time */
+       /** @return KDM from time in local time; note that ptime has no time zone information */
        boost::posix_time::ptime from () const;
-       /** @return KDM until time in local time */
+       /** @return KDM until time in local time; note that ptime has no time zone information */
        boost::posix_time::ptime until () const;
 
        boost::filesystem::path cpl () const;
index 63d528b77c1b20089163f9d3f4ed367ef2ee854f..a75316d8cc7bcede0992e649e9bd837b30e7a638 100644 (file)
@@ -149,7 +149,7 @@ ScreensPanel::add_cinema_clicked ()
 {
        CinemaDialog* d = new CinemaDialog (this, "Add Cinema");
        if (d->ShowModal () == wxID_OK) {
-               shared_ptr<Cinema> c (new Cinema (d->name(), d->emails()));
+               shared_ptr<Cinema> c (new Cinema (d->name(), d->emails(), d->utc_offset()));
                Config::instance()->add_cinema (c);
                add_cinema (c);
        }
@@ -166,10 +166,11 @@ ScreensPanel::edit_cinema_clicked ()
 
        pair<wxTreeItemId, shared_ptr<Cinema> > c = *_selected_cinemas.begin();
 
-       CinemaDialog* d = new CinemaDialog (this, "Edit cinema", c.second->name, c.second->emails);
+       CinemaDialog* d = new CinemaDialog (this, "Edit cinema", c.second->name, c.second->emails, c.second->utc_offset());
        if (d->ShowModal () == wxID_OK) {
                c.second->name = d->name ();
                c.second->emails = d->emails ();
+               c.second->set_utc_offset (d->utc_offset ());
                _targets->SetItemText (c.first, std_to_wx (d->name()));
                Config::instance()->changed ();
        }