summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2017-05-09 11:24:03 +0100
committerCarl Hetherington <cth@carlh.net>2017-05-09 11:24:03 +0100
commit89ae13638097f259f3e50b4b61068dd23451107d (patch)
treed58d8d0d10e5582b959ec41286943e6f4d81b8ac /src
parent7844347e7d89ffb256167192fb414c35d416e14d (diff)
Simple cover sheet support (#1039).
Diffstat (limited to 'src')
-rw-r--r--src/lib/config.cc24
-rw-r--r--src/lib/config.h12
-rw-r--r--src/lib/film.cc21
-rw-r--r--src/lib/util.cc27
-rw-r--r--src/lib/util.h1
-rw-r--r--src/lib/writer.cc47
-rw-r--r--src/lib/writer.h1
-rw-r--r--src/wx/config_dialog.cc66
8 files changed, 180 insertions, 19 deletions
diff --git a/src/lib/config.cc b/src/lib/config.cc
index c0ab44923..a19a60f55 100644
--- a/src/lib/config.cc
+++ b/src/lib/config.cc
@@ -132,6 +132,7 @@ Config::set_defaults ()
_allowed_dcp_frame_rates.push_back (60);
set_kdm_email_to_default ();
+ set_cover_sheet_to_default ();
}
void
@@ -329,6 +330,9 @@ try
}
_preview_sound = f.optional_bool_child("PreviewSound").get_value_or (false);
_preview_sound_output = f.optional_string_child("PreviewSoundOutput");
+ if (f.optional_string_child("CoverSheet")) {
+ _cover_sheet = f.optional_string_child("CoverSheet").get();
+ }
/* Replace any cinemas from config.xml with those from the configured file */
if (boost::filesystem::exists (_cinemas_file)) {
@@ -514,6 +518,7 @@ Config::write_config () const
if (_preview_sound_output) {
root->add_child("PreviewSoundOutput")->add_child_text (_preview_sound_output.get());
}
+ root->add_child("CoverSheet")->add_child_text (_cover_sheet);
try {
doc.write_to_file_formatted (path("config.xml").string ());
@@ -608,6 +613,18 @@ Config::reset_kdm_email ()
}
void
+Config::set_cover_sheet_to_default ()
+{
+ _cover_sheet = _(
+ "$CPL_NAME\n\n"
+ "Type: $TYPE\n"
+ "Format: $CONTAINER\n"
+ "Audio: $AUDIO\n"
+ "Length: $LENGTH\n"
+ );
+}
+
+void
Config::add_to_history (boost::filesystem::path p)
{
/* Remove existing instances of this path in the history */
@@ -707,3 +724,10 @@ Config::config_path ()
{
return path("config.xml", false);
}
+
+void
+Config::reset_cover_sheet ()
+{
+ set_cover_sheet_to_default ();
+ changed ();
+}
diff --git a/src/lib/config.h b/src/lib/config.h
index 3e74a5049..fc6315242 100644
--- a/src/lib/config.h
+++ b/src/lib/config.h
@@ -327,6 +327,10 @@ public:
return _preview_sound;
}
+ std::string cover_sheet () const {
+ return _cover_sheet;
+ }
+
boost::optional<std::string> preview_sound_output () const {
return _preview_sound_output;
}
@@ -599,6 +603,12 @@ public:
maybe_set (_nagged[nag], nagged);
}
+ void set_cover_sheet (std::string s) {
+ maybe_set (_cover_sheet, s);
+ }
+
+ void reset_cover_sheet ();
+
void changed (Property p = OTHER);
boost::signals2::signal<void (Property)> Changed;
/** Emitted if read() failed on an existing Config file. There is nothing
@@ -629,6 +639,7 @@ private:
void read ();
void set_defaults ();
void set_kdm_email_to_default ();
+ void set_cover_sheet_to_default ();
void read_cinemas (cxml::Document const & f);
boost::shared_ptr<dcp::CertificateChain> create_certificate_chain ();
boost::filesystem::path directory_or (boost::optional<boost::filesystem::path> dir, boost::filesystem::path a) const;
@@ -737,6 +748,7 @@ private:
bool _preview_sound;
/** name of a specific sound output stream to use for preview, or empty to use the default */
boost::optional<std::string> _preview_sound_output;
+ std::string _cover_sheet;
/** Singleton instance, or 0 */
static Config* _instance;
diff --git a/src/lib/film.cc b/src/lib/film.cc
index df19af77f..04ff00250 100644
--- a/src/lib/film.cc
+++ b/src/lib/film.cc
@@ -723,24 +723,9 @@ Film::isdcf_name (bool if_created_now) const
/* Count mapped audio channels */
- int non_lfe = 0;
- int lfe = 0;
-
- BOOST_FOREACH (int i, mapped_audio_channels ()) {
- if (i >= audio_channels()) {
- /* This channel is mapped but is not included in the DCP */
- continue;
- }
-
- if (static_cast<dcp::Channel> (i) == dcp::LFE) {
- ++lfe;
- } else {
- ++non_lfe;
- }
- }
-
- if (non_lfe) {
- d += String::compose("_%1%2", non_lfe, lfe);
+ pair<int, int> ch = audio_channel_types (mapped_audio_channels(), audio_channels());
+ if (ch.first) {
+ d += String::compose("_%1%2", ch.first, ch.second);
}
/* XXX: HI/VI */
diff --git a/src/lib/util.cc b/src/lib/util.cc
index 574d1d889..b1dfeab55 100644
--- a/src/lib/util.cc
+++ b/src/lib/util.cc
@@ -88,6 +88,7 @@ using std::pair;
using std::cout;
using std::bad_alloc;
using std::set_terminate;
+using std::make_pair;
using boost::shared_ptr;
using boost::thread;
using boost::optional;
@@ -706,3 +707,29 @@ careful_string_filter (string s)
return out;
}
+
+/** @param mapped List of mapped audio channels from a Film.
+ * @param channels Total number of channels in the Film.
+ * @return First: number of non-LFE channels, second: number of LFE channels.
+ */
+pair<int, int>
+audio_channel_types (list<int> mapped, int channels)
+{
+ int non_lfe = 0;
+ int lfe = 0;
+
+ BOOST_FOREACH (int i, mapped) {
+ if (i >= channels) {
+ /* This channel is mapped but is not included in the DCP */
+ continue;
+ }
+
+ if (static_cast<dcp::Channel> (i) == dcp::LFE) {
+ ++lfe;
+ } else {
+ ++non_lfe;
+ }
+ }
+
+ return make_pair (non_lfe, lfe);
+}
diff --git a/src/lib/util.h b/src/lib/util.h
index 4e6e50dd7..db6c37fe1 100644
--- a/src/lib/util.h
+++ b/src/lib/util.h
@@ -83,5 +83,6 @@ extern std::string video_asset_filename (boost::shared_ptr<dcp::PictureAsset> as
extern std::string audio_asset_filename (boost::shared_ptr<dcp::SoundAsset> asset, int reel_index, int reel_count, boost::optional<std::string> content_summary);
extern float relaxed_string_to_float (std::string);
extern std::string careful_string_filter (std::string);
+extern std::pair<int, int> audio_channel_types (std::list<int> mapped, int channels);
#endif
diff --git a/src/lib/writer.cc b/src/lib/writer.cc
index 87cdac2d8..ec4689b2f 100644
--- a/src/lib/writer.cc
+++ b/src/lib/writer.cc
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2012-2016 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2012-2017 Carl Hetherington <cth@carlh.net>
This file is part of DCP-o-matic.
@@ -539,6 +539,51 @@ Writer::finish ()
LOG_GENERAL (
N_("Wrote %1 FULL, %2 FAKE, %3 REPEAT, %4 pushed to disk"), _full_written, _fake_written, _repeat_written, _pushed_to_disk
);
+
+ write_cover_sheet ();
+}
+
+void
+Writer::write_cover_sheet ()
+{
+ boost::filesystem::path const cover = _film->file ("COVER_SHEET.txt");
+ FILE* f = fopen_boost (cover, "w");
+ if (!f) {
+ throw OpenFileError (cover, errno, false);
+ }
+
+ string text = Config::instance()->cover_sheet ();
+ boost::algorithm::replace_all (text, "$CPL_NAME", _film->name());
+ boost::algorithm::replace_all (text, "$TYPE", _film->dcp_content_type()->pretty_name());
+ boost::algorithm::replace_all (text, "$CONTAINER", _film->container()->nickname());
+
+ pair<int, int> ch = audio_channel_types (_film->mapped_audio_channels(), _film->audio_channels());
+ string description = String::compose("%1.%2", ch.first, ch.second);
+
+ if (description == "0.0") {
+ description = _("None");
+ } else if (description == "1.0") {
+ description = _("Mono");
+ } else if (description == "2.0") {
+ description = _("Stereo");
+ }
+ boost::algorithm::replace_all (text, "$AUDIO", description);
+
+ int h, m, s, fr;
+ _film->length().split (_film->video_frame_rate(), h, m, s, fr);
+ string length;
+ if (h == 0 && m == 0) {
+ length = String::compose("%1s", s);
+ } else if (h == 0 && m > 0) {
+ length = String::compose("%1m%2s", m, s);
+ } else if (h > 0 && m > 0) {
+ length = String::compose("%1h%2m%3s", h, m, s);
+ }
+
+ boost::algorithm::replace_all (text, "$LENGTH", length);
+
+ fwrite (text.c_str(), 1, text.length(), f);
+ fclose (f);
}
/** @param frame Frame index within the whole DCP.
diff --git a/src/lib/writer.h b/src/lib/writer.h
index 1e4d3b6a3..cb1bdc5cc 100644
--- a/src/lib/writer.h
+++ b/src/lib/writer.h
@@ -117,6 +117,7 @@ private:
bool have_sequenced_image_at_queue_head ();
size_t video_reel (int frame) const;
void set_digest_progress (Job* job, float progress);
+ void write_cover_sheet ();
/** our Film */
boost::shared_ptr<const Film> _film;
diff --git a/src/wx/config_dialog.cc b/src/wx/config_dialog.cc
index 570d5e448..49a8a6849 100644
--- a/src/wx/config_dialog.cc
+++ b/src/wx/config_dialog.cc
@@ -1482,6 +1482,71 @@ private:
wxButton* _reset_kdm_email;
};
+class CoverSheetPage : public StandardPage
+{
+public:
+
+ CoverSheetPage (wxSize panel_size, int border)
+#ifdef DCPOMATIC_OSX
+ /* We have to force both width and height of this one */
+ : StandardPage (wxSize (480, 128), border)
+#else
+ : StandardPage (panel_size, border)
+#endif
+ {}
+
+ wxString GetName () const
+ {
+ return _("Cover Sheet");
+ }
+
+#ifdef DCPOMATIC_OSX
+ wxBitmap GetLargeIcon () const
+ {
+ return wxBitmap ("cover_sheet", wxBITMAP_TYPE_PNG_RESOURCE);
+ }
+#endif
+
+private:
+ void setup ()
+ {
+ _cover_sheet = new wxTextCtrl (_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (-1, 200), wxTE_MULTILINE);
+ _panel->GetSizer()->Add (_cover_sheet, 0, wxEXPAND | wxALL, _border);
+
+ _reset_cover_sheet = new wxButton (_panel, wxID_ANY, _("Reset to default text"));
+ _panel->GetSizer()->Add (_reset_cover_sheet, 0, wxEXPAND | wxALL, _border);
+
+ _cover_sheet->Bind (wxEVT_TEXT, boost::bind (&CoverSheetPage::cover_sheet_changed, this));
+ _reset_cover_sheet->Bind (wxEVT_BUTTON, boost::bind (&CoverSheetPage::reset_cover_sheet, this));
+ }
+
+ void config_changed ()
+ {
+ checked_set (_cover_sheet, Config::instance()->cover_sheet ());
+ }
+
+ void cover_sheet_changed ()
+ {
+ if (_cover_sheet->GetValue().IsEmpty ()) {
+ /* Sometimes we get sent an erroneous notification that the cover sheet
+ is empty; I don't know why.
+ */
+ return;
+ }
+ Config::instance()->set_cover_sheet (wx_to_std (_cover_sheet->GetValue ()));
+ }
+
+ void reset_cover_sheet ()
+ {
+ Config::instance()->reset_cover_sheet ();
+ checked_set (_cover_sheet, Config::instance()->cover_sheet ());
+ }
+
+ wxTextCtrl* _cover_sheet;
+ wxButton* _reset_cover_sheet;
+};
+
+
/** @class AdvancedPage
* @brief Advanced page of the preferences dialog.
*/
@@ -1730,6 +1795,7 @@ create_config_dialog ()
e->AddPage (new KeysPage (ps, border));
e->AddPage (new TMSPage (ps, border));
e->AddPage (new KDMEmailPage (ps, border));
+ e->AddPage (new CoverSheetPage (ps, border));
e->AddPage (new AdvancedPage (ps, border));
return e;
}