summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2014-05-28 23:25:11 +0100
committerCarl Hetherington <cth@carlh.net>2014-05-28 23:25:11 +0100
commit93439dbc6d93dafd88e80d51d6473c8d97aa02c7 (patch)
tree60696c8c2e35a7035800aa2b8b4becdd56b339a8 /src
parent487b34e3dfdcbeea608aa89d4999c6f201a74583 (diff)
Modify KDM generation to work with CPLs rather than DCPs, and allow
user to specify a particular CPL to use. Tidy up the KDM dialog a bit.
Diffstat (limited to 'src')
-rw-r--r--src/lib/film.cc28
-rw-r--r--src/lib/film.h6
-rw-r--r--src/lib/kdm.cc20
-rw-r--r--src/lib/kdm.h6
-rw-r--r--src/lib/types.h15
-rw-r--r--src/tools/dcpomatic.cc19
-rw-r--r--src/tools/dcpomatic_kdm.cc21
-rw-r--r--src/wx/kdm_dialog.cc193
-rw-r--r--src/wx/kdm_dialog.h12
-rw-r--r--src/wx/wx_util.h3
10 files changed, 226 insertions, 97 deletions
diff --git a/src/lib/film.cc b/src/lib/film.cc
index 5fde0447a..1b5b2b366 100644
--- a/src/lib/film.cc
+++ b/src/lib/film.cc
@@ -766,11 +766,11 @@ Film::j2c_path (int f, Eyes e, bool t) const
return file (p);
}
-/** @return List of subdirectories (not full paths) containing DCPs that can be successfully libdcp::DCP::read() */
-list<boost::filesystem::path>
-Film::dcps () const
+/** Find all the DCPs in our directory that can be libdcp::DCP::read() and return details of their CPLs */
+vector<CPLSummary>
+Film::cpls () const
{
- list<boost::filesystem::path> out;
+ vector<CPLSummary> out;
boost::filesystem::path const dir = directory ();
for (boost::filesystem::directory_iterator i = boost::filesystem::directory_iterator(dir); i != boost::filesystem::directory_iterator(); ++i) {
@@ -782,7 +782,11 @@ Film::dcps () const
try {
libdcp::DCP dcp (*i);
dcp.read ();
- out.push_back (i->path().leaf ());
+ out.push_back (
+ CPLSummary (
+ i->path().leaf().string(), dcp.cpls().front()->id(), dcp.cpls().front()->name(), dcp.cpls().front()->filename()
+ )
+ );
} catch (...) {
}
@@ -982,28 +986,18 @@ Film::frame_size () const
libdcp::KDM
Film::make_kdm (
shared_ptr<libdcp::Certificate> target,
- boost::filesystem::path dcp_dir,
+ boost::filesystem::path cpl_file,
boost::posix_time::ptime from,
boost::posix_time::ptime until
) const
{
shared_ptr<const Signer> signer = make_signer ();
- libdcp::DCP dcp (dir (dcp_dir.string ()));
-
- try {
- dcp.read ();
- } catch (...) {
- throw KDMError (_("Could not read DCP to make KDM for"));
- }
-
time_t now = time (0);
struct tm* tm = localtime (&now);
string const issue_date = libdcp::tm_to_string (tm);
- dcp.cpls().front()->set_mxf_keys (key ());
-
- return libdcp::KDM (dcp.cpls().front(), signer, target, from, until, "DCP-o-matic", issue_date);
+ return libdcp::KDM (cpl_file, signer, target, key (), from, until, "DCP-o-matic", issue_date);
}
list<libdcp::KDM>
diff --git a/src/lib/film.h b/src/lib/film.h
index 162b67b35..06c770efa 100644
--- a/src/lib/film.h
+++ b/src/lib/film.h
@@ -98,7 +98,7 @@ public:
libdcp::Size full_frame () const;
libdcp::Size frame_size () const;
- std::list<boost::filesystem::path> dcps () const;
+ std::vector<CPLSummary> cpls () const;
boost::shared_ptr<Player> make_player () const;
boost::shared_ptr<Playlist> playlist () const;
@@ -123,14 +123,14 @@ public:
libdcp::KDM
make_kdm (
boost::shared_ptr<libdcp::Certificate> target,
- boost::filesystem::path dcp,
+ boost::filesystem::path cpl_file,
boost::posix_time::ptime from,
boost::posix_time::ptime until
) const;
std::list<libdcp::KDM> make_kdms (
std::list<boost::shared_ptr<Screen> >,
- boost::filesystem::path dcp,
+ boost::filesystem::path cpl_file,
boost::posix_time::ptime from,
boost::posix_time::ptime until
) const;
diff --git a/src/lib/kdm.cc b/src/lib/kdm.cc
index 2a8e191e7..d5d5ec0a0 100644
--- a/src/lib/kdm.cc
+++ b/src/lib/kdm.cc
@@ -102,12 +102,12 @@ static list<ScreenKDM>
make_screen_kdms (
shared_ptr<const Film> film,
list<shared_ptr<Screen> > screens,
- boost::filesystem::path dcp,
+ boost::filesystem::path cpl,
boost::posix_time::ptime from,
boost::posix_time::ptime to
)
{
- list<libdcp::KDM> kdms = film->make_kdms (screens, dcp, from, to);
+ list<libdcp::KDM> kdms = film->make_kdms (screens, cpl, from, to);
list<ScreenKDM> screen_kdms;
@@ -126,12 +126,12 @@ static list<CinemaKDMs>
make_cinema_kdms (
shared_ptr<const Film> film,
list<shared_ptr<Screen> > screens,
- boost::filesystem::path dcp,
+ boost::filesystem::path cpl,
boost::posix_time::ptime from,
boost::posix_time::ptime to
)
{
- list<ScreenKDM> screen_kdms = make_screen_kdms (film, screens, dcp, from, to);
+ list<ScreenKDM> screen_kdms = make_screen_kdms (film, screens, cpl, from, to);
list<CinemaKDMs> cinema_kdms;
while (!screen_kdms.empty ()) {
@@ -171,13 +171,13 @@ void
write_kdm_files (
shared_ptr<const Film> film,
list<shared_ptr<Screen> > screens,
- boost::filesystem::path dcp,
+ boost::filesystem::path cpl,
boost::posix_time::ptime from,
boost::posix_time::ptime to,
boost::filesystem::path directory
)
{
- list<ScreenKDM> screen_kdms = make_screen_kdms (film, screens, dcp, from, to);
+ list<ScreenKDM> screen_kdms = make_screen_kdms (film, screens, cpl, from, to);
/* Write KDMs to the specified directory */
for (list<ScreenKDM>::iterator i = screen_kdms.begin(); i != screen_kdms.end(); ++i) {
@@ -191,13 +191,13 @@ void
write_kdm_zip_files (
shared_ptr<const Film> film,
list<shared_ptr<Screen> > screens,
- boost::filesystem::path dcp,
+ boost::filesystem::path cpl,
boost::posix_time::ptime from,
boost::posix_time::ptime to,
boost::filesystem::path directory
)
{
- list<CinemaKDMs> cinema_kdms = make_cinema_kdms (film, screens, dcp, from, to);
+ list<CinemaKDMs> cinema_kdms = make_cinema_kdms (film, screens, cpl, from, to);
for (list<CinemaKDMs>::const_iterator i = cinema_kdms.begin(); i != cinema_kdms.end(); ++i) {
boost::filesystem::path path = directory;
@@ -210,12 +210,12 @@ void
email_kdms (
shared_ptr<const Film> film,
list<shared_ptr<Screen> > screens,
- boost::filesystem::path dcp,
+ boost::filesystem::path cpl,
boost::posix_time::ptime from,
boost::posix_time::ptime to
)
{
- list<CinemaKDMs> cinema_kdms = make_cinema_kdms (film, screens, dcp, from, to);
+ list<CinemaKDMs> cinema_kdms = make_cinema_kdms (film, screens, cpl, from, to);
for (list<CinemaKDMs>::const_iterator i = cinema_kdms.begin(); i != cinema_kdms.end(); ++i) {
diff --git a/src/lib/kdm.h b/src/lib/kdm.h
index c4fd43d49..8aacd7b72 100644
--- a/src/lib/kdm.h
+++ b/src/lib/kdm.h
@@ -26,7 +26,7 @@ class Film;
extern void write_kdm_files (
boost::shared_ptr<const Film> film,
std::list<boost::shared_ptr<Screen> > screens,
- boost::filesystem::path dcp,
+ boost::filesystem::path cpl,
boost::posix_time::ptime from,
boost::posix_time::ptime to,
boost::filesystem::path directory
@@ -35,7 +35,7 @@ extern void write_kdm_files (
extern void write_kdm_zip_files (
boost::shared_ptr<const Film> film,
std::list<boost::shared_ptr<Screen> > screens,
- boost::filesystem::path dcp,
+ boost::filesystem::path cpl,
boost::posix_time::ptime from,
boost::posix_time::ptime to,
boost::filesystem::path directory
@@ -44,7 +44,7 @@ extern void write_kdm_zip_files (
extern void email_kdms (
boost::shared_ptr<const Film> film,
std::list<boost::shared_ptr<Screen> > screens,
- boost::filesystem::path dcp,
+ boost::filesystem::path cpl,
boost::posix_time::ptime from,
boost::posix_time::ptime to
);
diff --git a/src/lib/types.h b/src/lib/types.h
index 3fab302fc..4eb3d927e 100644
--- a/src/lib/types.h
+++ b/src/lib/types.h
@@ -138,6 +138,21 @@ struct Crop
void as_xml (xmlpp::Node *) const;
};
+struct CPLSummary
+{
+ CPLSummary (std::string d, std::string i, std::string a, boost::filesystem::path f)
+ : dcp_directory (d)
+ , cpl_id (i)
+ , cpl_annotation_text (a)
+ , cpl_file (f)
+ {}
+
+ std::string dcp_directory;
+ std::string cpl_id;
+ std::string cpl_annotation_text;
+ boost::filesystem::path cpl_file;
+};
+
extern bool operator== (Crop const & a, Crop const & b);
extern bool operator!= (Crop const & a, Crop const & b);
diff --git a/src/tools/dcpomatic.cc b/src/tools/dcpomatic.cc
index da994796e..0ec2a81a4 100644
--- a/src/tools/dcpomatic.cc
+++ b/src/tools/dcpomatic.cc
@@ -30,6 +30,7 @@
#include <wx/stdpaths.h>
#include <wx/cmdline.h>
#include <wx/preferences.h>
+#include <libdcp/exceptions.h>
#include "wx/film_viewer.h"
#include "wx/film_editor.h"
#include "wx/job_manager_view.h"
@@ -161,7 +162,7 @@ load_film (boost::filesystem::path file)
#define ALWAYS 0x0
#define NEEDS_FILM 0x1
#define NOT_DURING_DCP_CREATION 0x2
-#define NEEDS_DCP 0x4
+#define NEEDS_CPL 0x4
map<wxMenuItem*, int> menu_items;
@@ -181,7 +182,7 @@ set_menu_sensitivity ()
++i;
}
bool const dcp_creation = (i != jobs.end ()) && !(*i)->finished ();
- bool const have_dcp = film && !film->dcps().empty ();
+ bool const have_cpl = film && !film->cpls().empty ();
for (map<wxMenuItem*, int>::iterator j = menu_items.begin(); j != menu_items.end(); ++j) {
@@ -195,7 +196,7 @@ set_menu_sensitivity ()
enabled = false;
}
- if ((j->second & NEEDS_DCP) && !have_dcp) {
+ if ((j->second & NEEDS_CPL) && !have_cpl) {
enabled = false;
}
@@ -247,9 +248,9 @@ setup_menu (wxMenuBar* m)
jobs_menu = new wxMenu;
add_item (jobs_menu, _("&Make DCP"), ID_jobs_make_dcp, NEEDS_FILM | NOT_DURING_DCP_CREATION);
- add_item (jobs_menu, _("Make &KDMs..."), ID_jobs_make_kdms, NEEDS_FILM | NEEDS_DCP);
- add_item (jobs_menu, _("&Send DCP to TMS"), ID_jobs_send_dcp_to_tms, NEEDS_FILM | NOT_DURING_DCP_CREATION | NEEDS_DCP);
- add_item (jobs_menu, _("S&how DCP"), ID_jobs_show_dcp, NEEDS_FILM | NOT_DURING_DCP_CREATION | NEEDS_DCP);
+ add_item (jobs_menu, _("Make &KDMs..."), ID_jobs_make_kdms, NEEDS_FILM);
+ add_item (jobs_menu, _("&Send DCP to TMS"), ID_jobs_send_dcp_to_tms, NEEDS_FILM | NOT_DURING_DCP_CREATION | NEEDS_CPL);
+ add_item (jobs_menu, _("S&how DCP"), ID_jobs_show_dcp, NEEDS_FILM | NOT_DURING_DCP_CREATION | NEEDS_CPL);
wxMenu* tools = new wxMenu;
add_item (tools, _("Hints..."), ID_tools_hints, 0);
@@ -494,12 +495,14 @@ private:
try {
if (d->write_to ()) {
- write_kdm_files (film, d->screens (), d->dcp (), d->from (), d->until (), d->directory ());
+ write_kdm_files (film, d->screens (), d->cpl (), d->from (), d->until (), d->directory ());
} else {
JobManager::instance()->add (
- shared_ptr<Job> (new SendKDMEmailJob (film, d->screens (), d->dcp (), d->from (), d->until ()))
+ shared_ptr<Job> (new SendKDMEmailJob (film, d->screens (), d->cpl (), d->from (), d->until ()))
);
}
+ } catch (libdcp::NotEncryptedError& e) {
+ error_dialog (this, _("CPL's content is not encrypted."));
} catch (exception& e) {
error_dialog (this, e.what ());
} catch (...) {
diff --git a/src/tools/dcpomatic_kdm.cc b/src/tools/dcpomatic_kdm.cc
index 3a2068d2b..041f6c7ef 100644
--- a/src/tools/dcpomatic_kdm.cc
+++ b/src/tools/dcpomatic_kdm.cc
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2013-2014 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
@@ -30,6 +30,7 @@ using std::stringstream;
using std::cout;
using std::cerr;
using std::list;
+using std::vector;
using boost::shared_ptr;
static string program_name;
@@ -219,14 +220,14 @@ int main (int argc, char* argv[])
}
/* XXX: allow specification of this */
- list<boost::filesystem::path> dcps = film->dcps ();
- if (dcps.empty ()) {
- error ("no DCPs found in film");
- } else if (dcps.size() > 1) {
- error ("more than one DCP found in film");
+ vector<CPLSummary> cpls = film->cpls ();
+ if (cpls.empty ()) {
+ error ("no CPLs found in film");
+ } else if (cpls.size() > 1) {
+ error ("more than one CPL found in film");
}
- boost::filesystem::path dcp = dcps.front ();
+ boost::filesystem::path cpl = cpls.front().cpl_file;
if (cinema_name.empty ()) {
@@ -235,7 +236,7 @@ int main (int argc, char* argv[])
}
shared_ptr<libdcp::Certificate> certificate (new libdcp::Certificate (boost::filesystem::path (certificate_file)));
- libdcp::KDM kdm = film->make_kdm (certificate, dcp, valid_from.get(), valid_to.get());
+ libdcp::KDM kdm = film->make_kdm (certificate, cpl, valid_from.get(), valid_to.get());
kdm.as_xml (output);
if (verbose) {
cout << "Generated KDM " << output << " for certificate.\n";
@@ -259,12 +260,12 @@ int main (int argc, char* argv[])
try {
if (zip) {
- write_kdm_zip_files (film, (*i)->screens(), dcp, valid_from.get(), valid_to.get(), output);
+ write_kdm_zip_files (film, (*i)->screens(), cpl, valid_from.get(), valid_to.get(), output);
if (verbose) {
cout << "Wrote ZIP files to " << output << "\n";
}
} else {
- write_kdm_files (film, (*i)->screens(), dcp, valid_from.get(), valid_to.get(), output);
+ write_kdm_files (film, (*i)->screens(), cpl, valid_from.get(), valid_to.get(), output);
if (verbose) {
cout << "Wrote KDM files to " << output << "\n";
}
diff --git a/src/wx/kdm_dialog.cc b/src/wx/kdm_dialog.cc
index 5fb031324..42b8297f0 100644
--- a/src/wx/kdm_dialog.cc
+++ b/src/wx/kdm_dialog.cc
@@ -22,6 +22,7 @@
#include <wx/timectrl.h>
#include <wx/stdpaths.h>
#include <wx/listctrl.h>
+#include <libcxml/cxml.h>
#include "lib/cinema.h"
#include "lib/config.h"
#include "lib/film.h"
@@ -40,17 +41,29 @@ using std::map;
using std::list;
using std::pair;
using std::cout;
+using std::vector;
using std::make_pair;
using boost::shared_ptr;
KDMDialog::KDMDialog (wxWindow* parent, boost::shared_ptr<const Film> film)
: wxDialog (parent, wxID_ANY, _("Make KDMs"))
{
+ /* Main sizer */
wxBoxSizer* vertical = new wxBoxSizer (wxVERTICAL);
- wxBoxSizer* targets = new wxBoxSizer (wxHORIZONTAL);
+
+ /* Font for sub-headings */
+ wxFont subheading_font (*wxNORMAL_FONT);
+ subheading_font.SetWeight (wxFONTWEIGHT_BOLD);
+
+
+ /* Sub-heading: Screens */
+ wxStaticText* h = new wxStaticText (this, wxID_ANY, _("Screens"));
+ h->SetFont (subheading_font);
+ vertical->Add (h, 0, wxALIGN_CENTER_VERTICAL);
+ wxBoxSizer* targets = new wxBoxSizer (wxHORIZONTAL);
_targets = new wxTreeCtrl (this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTR_HIDE_ROOT | wxTR_MULTIPLE | wxTR_HAS_BUTTONS);
- targets->Add (_targets, 1, wxEXPAND | wxALL, 6);
+ targets->Add (_targets, 1, wxEXPAND | wxTOP | wxRIGHT, DCPOMATIC_SIZER_GAP);
_root = _targets->AddRoot ("Foo");
@@ -64,24 +77,30 @@ KDMDialog::KDMDialog (wxWindow* parent, boost::shared_ptr<const Film> film)
wxBoxSizer* target_buttons = new wxBoxSizer (wxVERTICAL);
_add_cinema = new wxButton (this, wxID_ANY, _("Add Cinema..."));
- target_buttons->Add (_add_cinema, 1, wxEXPAND, 6);
+ target_buttons->Add (_add_cinema, 1, wxEXPAND | wxALL, DCPOMATIC_BUTTON_STACK_GAP);
_edit_cinema = new wxButton (this, wxID_ANY, _("Edit Cinema..."));
- target_buttons->Add (_edit_cinema, 1, wxEXPAND, 6);
+ target_buttons->Add (_edit_cinema, 1, wxEXPAND | wxALL, DCPOMATIC_BUTTON_STACK_GAP);
_remove_cinema = new wxButton (this, wxID_ANY, _("Remove Cinema"));
- target_buttons->Add (_remove_cinema, 1, wxEXPAND, 6);
+ target_buttons->Add (_remove_cinema, 1, wxEXPAND | wxALL, DCPOMATIC_BUTTON_STACK_GAP);
_add_screen = new wxButton (this, wxID_ANY, _("Add Screen..."));
- target_buttons->Add (_add_screen, 1, wxEXPAND, 6);
+ target_buttons->Add (_add_screen, 1, wxEXPAND | wxALL, DCPOMATIC_BUTTON_STACK_GAP);
_edit_screen = new wxButton (this, wxID_ANY, _("Edit Screen..."));
- target_buttons->Add (_edit_screen, 1, wxEXPAND, 6);
+ target_buttons->Add (_edit_screen, 1, wxEXPAND | wxALL, DCPOMATIC_BUTTON_STACK_GAP);
_remove_screen = new wxButton (this, wxID_ANY, _("Remove Screen"));
- target_buttons->Add (_remove_screen, 1, wxEXPAND, 6);
+ target_buttons->Add (_remove_screen, 1, wxEXPAND | wxALL, DCPOMATIC_BUTTON_STACK_GAP);
+
+ targets->Add (target_buttons, 0, 0);
- targets->Add (target_buttons, 0, 0, 6);
+ vertical->Add (targets, 1, wxEXPAND);
- vertical->Add (targets, 1, wxEXPAND | wxALL, 6);
- wxFlexGridSizer* table = new wxFlexGridSizer (3, 2, 6);
+ /* Sub-heading: Timing */
+ h = new wxStaticText (this, wxID_ANY, _("Timing"));
+ h->SetFont (subheading_font);
+ vertical->Add (h, 0, wxALIGN_CENTER_VERTICAL | wxTOP, DCPOMATIC_SIZER_Y_GAP * 2);
+
+ wxFlexGridSizer* table = new wxFlexGridSizer (3, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
add_label_to_sizer (table, this, _("From"), true);
wxDateTime from;
from.SetToCurrent ();
@@ -99,30 +118,46 @@ KDMDialog::KDMDialog (wxWindow* parent, boost::shared_ptr<const Film> film)
_until_time = new wxTimePickerCtrl (this, wxID_ANY, to);
table->Add (_until_time, 1, wxEXPAND);
- vertical->Add (table, 0, wxEXPAND | wxALL, 6);
+ vertical->Add (table, 0, wxEXPAND | wxTOP, DCPOMATIC_SIZER_GAP);
+
- _dcps = new wxListCtrl (this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxLC_SINGLE_SEL);
- wxListItem ip;
- ip.SetId (0);
- ip.SetText (_("DCP"));
- ip.SetWidth (400);
- _dcps->InsertColumn (0, ip);
- vertical->Add (_dcps, 0, wxEXPAND | wxALL, 6);
+ /* Sub-heading: CPL */
+ h = new wxStaticText (this, wxID_ANY, _("CPL"));
+ h->SetFont (subheading_font);
+ vertical->Add (h, 0, wxALIGN_CENTER_VERTICAL | wxTOP, DCPOMATIC_SIZER_Y_GAP * 2);
- list<boost::filesystem::path> dcps = film->dcps ();
- for (list<boost::filesystem::path>::const_iterator i = dcps.begin(); i != dcps.end(); ++i) {
- wxListItem item;
- int const n = _dcps->GetItemCount ();
- item.SetId (n);
- _dcps->InsertItem (item);
- _dcps->SetItem (n, 0, std_to_wx (i->string ()));
-
- if (dcps.size() == 1 || i->string() == film->dcp_name ()) {
- _dcps->SetItemState (n, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
- }
- }
+ /* CPL choice */
+ wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
+ add_label_to_sizer (s, this, _("CPL"), true);
+ _cpl = new wxChoice (this, wxID_ANY);
+ s->Add (_cpl, 1, wxEXPAND);
+ _cpl_browse = new wxButton (this, wxID_ANY, _("Browse..."));
+ s->Add (_cpl_browse, 0);
+ vertical->Add (s, 0, wxEXPAND | wxTOP, DCPOMATIC_SIZER_GAP + 2);
+
+ /* CPL details */
+ table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
+ add_label_to_sizer (table, this, _("DCP directory"), true);
+ _dcp_directory = new wxStaticText (this, wxID_ANY, "");
+ table->Add (_dcp_directory);
+ add_label_to_sizer (table, this, _("CPL ID"), true);
+ _cpl_id = new wxStaticText (this, wxID_ANY, "");
+ table->Add (_cpl_id);
+ add_label_to_sizer (table, this, _("CPL annotation text"), true);
+ _cpl_annotation_text = new wxStaticText (this, wxID_ANY, "");
+ table->Add (_cpl_annotation_text);
+ vertical->Add (table, 0, wxEXPAND | wxTOP, DCPOMATIC_SIZER_GAP + 2);
+
+ _cpls = film->cpls ();
+ update_cpl_choice ();
- table = new wxFlexGridSizer (2, 2, 6);
+
+ /* Sub-heading: Output */
+ h = new wxStaticText (this, wxID_ANY, _("Output"));
+ h->SetFont (subheading_font);
+ vertical->Add (h, 0, wxALIGN_CENTER_VERTICAL | wxTOP, DCPOMATIC_SIZER_Y_GAP * 2);
+
+ table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, 0);
_write_to = new wxRadioButton (this, wxID_ANY, _("Write to"));
table->Add (_write_to, 1, wxEXPAND);
@@ -141,15 +176,22 @@ KDMDialog::KDMDialog (wxWindow* parent, boost::shared_ptr<const Film> film)
table->Add (_email, 1, wxEXPAND);
table->AddSpacer (0);
- vertical->Add (table, 0, wxEXPAND | wxALL, 6);
+ vertical->Add (table, 0, wxEXPAND | wxTOP, DCPOMATIC_SIZER_GAP);
+
+ /* Make an overall sizer to get a nice border, and put some buttons in */
+
+ wxBoxSizer* overall_sizer = new wxBoxSizer (wxVERTICAL);
+ overall_sizer->Add (vertical, 0, wxEXPAND | wxTOP | wxLEFT | wxRIGHT, DCPOMATIC_DIALOG_BORDER);
wxSizer* buttons = CreateSeparatedButtonSizer (wxOK | wxCANCEL);
if (buttons) {
- vertical->Add (buttons, wxSizerFlags().Expand().DoubleBorder());
+ overall_sizer->Add (buttons, 0, wxEXPAND | wxTOP, DCPOMATIC_SIZER_Y_GAP);
}
_write_to->SetValue (true);
+ /* Bind */
+
_targets->Bind (wxEVT_COMMAND_TREE_SEL_CHANGED, boost::bind (&KDMDialog::setup_sensitivity, this));
_add_cinema->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&KDMDialog::add_cinema_clicked, this));
@@ -160,17 +202,17 @@ KDMDialog::KDMDialog (wxWindow* parent, boost::shared_ptr<const Film> film)
_edit_screen->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&KDMDialog::edit_screen_clicked, this));
_remove_screen->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&KDMDialog::remove_screen_clicked, this));
- _dcps->Bind (wxEVT_COMMAND_LIST_ITEM_SELECTED, boost::bind (&KDMDialog::setup_sensitivity, this));
- _dcps->Bind (wxEVT_COMMAND_LIST_ITEM_DESELECTED, boost::bind (&KDMDialog::setup_sensitivity, this));
+ _cpl->Bind (wxEVT_COMMAND_CHOICE_SELECTED, boost::bind (&KDMDialog::update_cpl_summary, this));
+ _cpl_browse->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&KDMDialog::cpl_browse_clicked, this));
_write_to->Bind (wxEVT_COMMAND_RADIOBUTTON_SELECTED, boost::bind (&KDMDialog::setup_sensitivity, this));
_email->Bind (wxEVT_COMMAND_RADIOBUTTON_SELECTED, boost::bind (&KDMDialog::setup_sensitivity, this));
setup_sensitivity ();
-
- SetSizer (vertical);
- vertical->Layout ();
- vertical->SetSizeHints (this);
+
+ SetSizer (overall_sizer);
+ overall_sizer->Layout ();
+ overall_sizer->SetSizeHints (this);
}
list<pair<wxTreeItemId, shared_ptr<Cinema> > >
@@ -212,7 +254,7 @@ KDMDialog::setup_sensitivity ()
{
bool const sc = selected_cinemas().size() == 1;
bool const ss = selected_screens().size() == 1;
- bool const sd = _dcps->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED) != -1;
+ bool const sd = _cpl->GetSelection() != -1;
_edit_cinema->Enable (sc);
_remove_cinema->Enable (sc);
@@ -419,11 +461,11 @@ KDMDialog::until () const
}
boost::filesystem::path
-KDMDialog::dcp () const
+KDMDialog::cpl () const
{
- int const item = _dcps->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
+ int const item = _cpl->GetSelection ();
assert (item >= 0);
- return wx_to_std (_dcps->GetItemText (item));
+ return _cpls[item].cpl_file;
}
boost::filesystem::path
@@ -437,3 +479,66 @@ KDMDialog::write_to () const
{
return _write_to->GetValue ();
}
+
+void
+KDMDialog::update_cpl_choice ()
+{
+ _cpl->Clear ();
+
+ for (vector<CPLSummary>::const_iterator i = _cpls.begin(); i != _cpls.end(); ++i) {
+ _cpl->Append (std_to_wx (i->cpl_id));
+
+ if (_cpls.size() > 0) {
+ _cpl->SetSelection (0);
+ }
+ }
+
+ update_cpl_summary ();
+}
+
+void
+KDMDialog::update_cpl_summary ()
+{
+ int const n = _cpl->GetSelection();
+ if (n == wxNOT_FOUND) {
+ return;
+ }
+
+ _dcp_directory->SetLabel (std_to_wx (_cpls[n].dcp_directory));
+ _cpl_id->SetLabel (std_to_wx (_cpls[n].cpl_id));
+ _cpl_annotation_text->SetLabel (std_to_wx (_cpls[n].cpl_annotation_text));
+}
+
+void
+KDMDialog::cpl_browse_clicked ()
+{
+ wxFileDialog d (this, _("Select CPL XML file"), wxEmptyString, wxEmptyString, "*.xml");
+ if (d.ShowModal() == wxID_CANCEL) {
+ return;
+ }
+
+ boost::filesystem::path cpl_file (wx_to_std (d.GetPath ()));
+ boost::filesystem::path dcp_dir = cpl_file.parent_path ();
+
+ /* XXX: hack alert */
+ cxml::Document cpl_document ("CompositionPlaylist");
+ cpl_document.read_file (cpl_file);
+
+ try {
+ _cpls.push_back (
+ CPLSummary (
+ dcp_dir.filename().string(),
+ cpl_document.string_child("Id").substr (9),
+ cpl_document.string_child ("ContentTitleText"),
+ cpl_file
+ )
+ );
+ } catch (cxml::Error) {
+ error_dialog (this, _("This is not a valid CPL file"));
+ return;
+ }
+
+ update_cpl_choice ();
+ _cpl->SetSelection (_cpls.size() - 1);
+ update_cpl_summary ();
+}
diff --git a/src/wx/kdm_dialog.h b/src/wx/kdm_dialog.h
index db51d6d03..6327b29e8 100644
--- a/src/wx/kdm_dialog.h
+++ b/src/wx/kdm_dialog.h
@@ -45,7 +45,7 @@ public:
/** @return KDM until time in local time */
boost::posix_time::ptime until () const;
- boost::filesystem::path dcp () const;
+ boost::filesystem::path cpl () const;
boost::filesystem::path directory () const;
bool write_to () const;
@@ -61,6 +61,9 @@ private:
std::list<std::pair<wxTreeItemId, boost::shared_ptr<Cinema> > > selected_cinemas () const;
std::list<std::pair<wxTreeItemId, boost::shared_ptr<Screen> > > selected_screens () const;
void setup_sensitivity ();
+ void update_cpl_choice ();
+ void update_cpl_summary ();
+ void cpl_browse_clicked ();
static boost::posix_time::ptime posix_time (wxDatePickerCtrl *, wxTimePickerCtrl *);
@@ -75,7 +78,11 @@ private:
wxDatePickerCtrl* _until_date;
wxTimePickerCtrl* _from_time;
wxTimePickerCtrl* _until_time;
- wxListCtrl* _dcps;
+ wxChoice* _cpl;
+ wxButton* _cpl_browse;
+ wxStaticText* _dcp_directory;
+ wxStaticText* _cpl_id;
+ wxStaticText* _cpl_annotation_text;
wxRadioButton* _write_to;
#ifdef DCPOMATIC_USE_OWN_DIR_PICKER
DirPickerCtrl* _folder;
@@ -87,4 +94,5 @@ private:
wxTreeItemId _root;
std::map<wxTreeItemId, boost::shared_ptr<Cinema> > _cinemas;
std::map<wxTreeItemId, boost::shared_ptr<Screen> > _screens;
+ std::vector<CPLSummary> _cpls;
};
diff --git a/src/wx/wx_util.h b/src/wx/wx_util.h
index 585541150..77ecd9db9 100644
--- a/src/wx/wx_util.h
+++ b/src/wx/wx_util.h
@@ -35,7 +35,10 @@ class wxGridBagSizer;
#define DCPOMATIC_SIZER_X_GAP 8
#define DCPOMATIC_SIZER_Y_GAP 8
+#define DCPOMATIC_SIZER_GAP 8
#define DCPOMATIC_DIALOG_BORDER 12
+/** Spacing to use between buttons in a vertical line */
+#define DCPOMATIC_BUTTON_STACK_GAP 2
/** @file src/wx/wx_util.h
* @brief Some utility functions and classes.