+2017-03-03 Carl Hetherington <cth@carlh.net>
+
+ * Add option to write KDMs to separate folders
+ or ZIP files.
+
2017-02-28 Carl Hetherington <cth@carlh.net>
* Updated de_DE translation from Carsten Kurz.
using std::string;
using std::runtime_error;
using boost::shared_ptr;
+using boost::function;
void
CinemaKDMs::make_zip_file (boost::filesystem::path zip_file, dcp::NameFormat name_format, dcp::NameFormat::Map name_values) const
return cinema_kdms;
}
+/** Write one directory per cinema into another directory */
+int
+CinemaKDMs::write_directories (
+ list<CinemaKDMs> cinema_kdms,
+ boost::filesystem::path directory,
+ dcp::NameFormat container_name_format,
+ dcp::NameFormat filename_format,
+ dcp::NameFormat::Map name_values,
+ function<bool (boost::filesystem::path)> confirm_overwrite
+ )
+{
+ /* No specific screen */
+ name_values['s'] = "";
+
+ int written = 0;
+
+ BOOST_FOREACH (CinemaKDMs const & i, cinema_kdms) {
+ boost::filesystem::path path = directory;
+ name_values['c'] = i.cinema->name;
+ path /= container_name_format.get(name_values, "");
+ if (!boost::filesystem::exists (path) || confirm_overwrite (path)) {
+ boost::filesystem::create_directories (path);
+ ScreenKDM::write_files (i.screen_kdms, path, filename_format, name_values, confirm_overwrite);
+ }
+ written += i.screen_kdms.size();
+ }
+
+ return written;
+}
+
/** Write one ZIP file per cinema into a directory */
-void
+int
CinemaKDMs::write_zip_files (
list<CinemaKDMs> cinema_kdms,
boost::filesystem::path directory,
- dcp::NameFormat name_format,
- dcp::NameFormat::Map name_values
+ dcp::NameFormat container_name_format,
+ dcp::NameFormat filename_format,
+ dcp::NameFormat::Map name_values,
+ function<bool (boost::filesystem::path)> confirm_overwrite
)
{
/* No specific screen */
name_values['s'] = "";
+ int written = 0;
+
BOOST_FOREACH (CinemaKDMs const & i, cinema_kdms) {
boost::filesystem::path path = directory;
name_values['c'] = i.cinema->name;
- path /= name_format.get(name_values, ".zip");
- i.make_zip_file (path, name_format, name_values);
+ path /= container_name_format.get(name_values, ".zip");
+ if (!boost::filesystem::exists (path) || confirm_overwrite (path)) {
+ if (boost::filesystem::exists (path)) {
+ /* Creating a new zip file over an existing one is an error */
+ boost::filesystem::remove (path);
+ }
+ i.make_zip_file (path, filename_format, name_values);
+ written += i.screen_kdms.size();
+ }
}
+
+ return written;
}
/** Email one ZIP file per cinema to the cinema.
static std::list<CinemaKDMs> collect (std::list<ScreenKDM> kdms);
- static void write_zip_files (
+ static int write_directories (
std::list<CinemaKDMs> cinema_kdms,
boost::filesystem::path directory,
- dcp::NameFormat name_format,
- dcp::NameFormat::Map name_values
+ dcp::NameFormat container_name_format,
+ dcp::NameFormat filename_format,
+ dcp::NameFormat::Map name_values,
+ boost::function<bool (boost::filesystem::path)> confirm_overwrite
+ );
+
+ static int write_zip_files (
+ std::list<CinemaKDMs> cinema_kdms,
+ boost::filesystem::path directory,
+ dcp::NameFormat container_name_format,
+ dcp::NameFormat filename_format,
+ dcp::NameFormat::Map name_values,
+ boost::function<bool (boost::filesystem::path)> confirm_overwrite
);
static void email (
_cinemas_file = path ("cinemas.xml");
_show_hints_before_make_dcp = true;
_confirm_kdm_email = true;
+ _kdm_container_name_format = dcp::NameFormat ("KDM %f %c");
_kdm_filename_format = dcp::NameFormat ("KDM %f %c %s");
_dcp_metadata_filename_format = dcp::NameFormat ("%t");
_dcp_asset_filename_format = dcp::NameFormat ("%t");
_cinemas_file = f.optional_string_child("CinemasFile").get_value_or (path ("cinemas.xml").string ());
_show_hints_before_make_dcp = f.optional_bool_child("ShowHintsBeforeMakeDCP").get_value_or (true);
_confirm_kdm_email = f.optional_bool_child("ConfirmKDMEmail").get_value_or (true);
+ _kdm_container_name_format = dcp::NameFormat (f.optional_string_child("KDMContainerNameFormat").get_value_or ("KDM %f %c"));
_kdm_filename_format = dcp::NameFormat (f.optional_string_child("KDMFilenameFormat").get_value_or ("KDM %f %c %s"));
_dcp_metadata_filename_format = dcp::NameFormat (f.optional_string_child("DCPMetadataFilenameFormat").get_value_or ("%t"));
_dcp_asset_filename_format = dcp::NameFormat (f.optional_string_child("DCPAssetFilenameFormat").get_value_or ("%t"));
root->add_child("ShowHintsBeforeMakeDCP")->add_child_text (_show_hints_before_make_dcp ? "1" : "0");
root->add_child("ConfirmKDMEmail")->add_child_text (_confirm_kdm_email ? "1" : "0");
root->add_child("KDMFilenameFormat")->add_child_text (_kdm_filename_format.specification ());
+ root->add_child("KDMContainerNameFormat")->add_child_text (_kdm_container_name_format.specification ());
root->add_child("DCPMetadataFilenameFormat")->add_child_text (_dcp_metadata_filename_format.specification ());
root->add_child("DCPAssetFilenameFormat")->add_child_text (_dcp_asset_filename_format.specification ());
return _confirm_kdm_email;
}
+ dcp::NameFormat kdm_container_name_format () const {
+ return _kdm_container_name_format;
+ }
+
dcp::NameFormat kdm_filename_format () const {
return _kdm_filename_format;
}
maybe_set (_confirm_kdm_email, s);
}
+ void set_kdm_container_name_format (dcp::NameFormat n) {
+ maybe_set (_kdm_container_name_format, n);
+ }
+
void set_kdm_filename_format (dcp::NameFormat n) {
maybe_set (_kdm_filename_format, n);
}
bool _show_hints_before_make_dcp;
bool _confirm_kdm_email;
dcp::NameFormat _kdm_filename_format;
+ dcp::NameFormat _kdm_container_name_format;
dcp::NameFormat _dcp_metadata_filename_format;
dcp::NameFormat _dcp_asset_filename_format;
);
if (zip) {
- CinemaKDMs::write_zip_files (
+ int const N = CinemaKDMs::write_zip_files (
CinemaKDMs::collect (screen_kdms),
output,
+ Config::instance()->kdm_container_name_format(),
Config::instance()->kdm_filename_format(),
- values
+ values,
+ bind (&always_overwrite)
);
if (verbose) {
- cout << "Wrote ZIP files to " << output << "\n";
+ cout << "Wrote " << N << " ZIP files to " << output << "\n";
}
} else {
- ScreenKDM::write_files (
+ int const N = ScreenKDM::write_files (
screen_kdms, output, Config::instance()->kdm_filename_format(), values,
bind (&always_overwrite)
);
if (verbose) {
- cout << "Wrote KDM files to " << output << "\n";
+ cout << "Wrote " << N << " KDM files to " << output << "\n";
}
}
} catch (FileError& e) {
if (result.first) {
JobManager::instance()->add (result.first);
}
+
+ if (result.second > 0) {
+ /* XXX: proper plural form support in wxWidgets? */
+ wxString s = result.second == 1 ? _("%d KDM written to %s") : _("%d KDMs written to %s");
+ message_dialog (
+ this,
+ wxString::Format (s, result.second, std_to_wx(_output->directory().string()).data())
+ );
+ }
}
table->Add (_type, 1, wxEXPAND);
_type->SetSelection (0);
+ {
+ int flags = wxALIGN_TOP | wxTOP | wxLEFT | wxRIGHT;
+ wxString t = _("Folder / ZIP name format");
+#ifdef __WXOSX__
+ flags |= wxALIGN_RIGHT;
+ t += wxT (":");
+#endif
+ wxStaticText* m = new wxStaticText (this, wxID_ANY, t);
+ table->Add (m, 0, flags, DCPOMATIC_SIZER_Y_GAP);
+ }
+
+ _container_name_format = new NameFormatEditor (this, Config::instance()->kdm_container_name_format(), dcp::NameFormat::Map(), dcp::NameFormat::Map(), "");
+ table->Add (_container_name_format->panel(), 1, wxEXPAND);
+
{
int flags = wxALIGN_TOP | wxTOP | wxLEFT | wxRIGHT;
wxString t = _("Filename format");
table->Add (_folder, 1, wxEXPAND);
+ wxSizer* write_options = new wxBoxSizer(wxVERTICAL);
+ _write_flat = new wxRadioButton (this, wxID_ANY, _("Write all KDMs to the same folder"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP);
+ write_options->Add (_write_flat);
+ _write_folder = new wxRadioButton (this, wxID_ANY, _("Write a folder for each cinema's KDMs"));
+ write_options->Add (_write_folder);
+ _write_zip = new wxRadioButton (this, wxID_ANY, _("Write a ZIP file for each cinema's KDMs"));
+ write_options->Add (_write_zip);
+ table->AddSpacer (0);
+ table->Add (write_options);
+
_email = new wxCheckBox (this, wxID_ANY, _("Send by email"));
table->Add (_email, 1, wxEXPAND);
table->AddSpacer (0);
void
KDMOutputPanel::setup_sensitivity ()
{
- _folder->Enable (_write_to->GetValue ());
+ bool const write = _write_to->GetValue ();
+ _folder->Enable (write);
+ _write_flat->Enable (write);
+ _write_folder->Enable (write);
+ _write_zip->Enable (write);
}
pair<shared_ptr<Job>, int>
name_values['b'] = dcp::LocalTime(timing->from()).date() + " " + dcp::LocalTime(timing->from()).time_of_day();
name_values['e'] = dcp::LocalTime(timing->until()).date() + " " + dcp::LocalTime(timing->until()).time_of_day();
- if (_write_to->GetValue ()) {
- written = ScreenKDM::write_files (
- screen_kdms,
- directory(),
- _filename_format->get(),
- name_values,
- confirm_overwrite
- );
+ if (_write_to->GetValue()) {
+ if (_write_flat->GetValue()) {
+ written = ScreenKDM::write_files (
+ screen_kdms,
+ directory(),
+ _filename_format->get(),
+ name_values,
+ confirm_overwrite
+ );
+ } else if (_write_folder->GetValue()) {
+ written = CinemaKDMs::write_directories (
+ CinemaKDMs::collect (screen_kdms),
+ directory(),
+ _container_name_format->get(),
+ _filename_format->get(),
+ name_values,
+ confirm_overwrite
+ );
+ } else if (_write_zip->GetValue()) {
+ written = CinemaKDMs::write_zip_files (
+ CinemaKDMs::collect (screen_kdms),
+ directory(),
+ _container_name_format->get(),
+ _filename_format->get(),
+ name_values,
+ confirm_overwrite
+ );
+ }
}
if (_email->GetValue ()) {
#include <wx/wx.h>
#include <boost/filesystem.hpp>
+class wxRadioButton;
class wxDirPickerCtrl;
class DirPickerCtrl;
class KDMTimingPanel;
private:
wxChoice* _type;
+ NameFormatEditor* _container_name_format;
NameFormatEditor* _filename_format;
wxCheckBox* _write_to;
#ifdef DCPOMATIC_USE_OWN_PICKER
#else
wxDirPickerCtrl* _folder;
#endif
+ wxRadioButton* _write_flat;
+ wxRadioButton* _write_folder;
+ wxRadioButton* _write_zip;
wxCheckBox* _email;
};
, _suffix (suffix)
{
_sizer->Add (_specification, 0, wxEXPAND, DCPOMATIC_SIZER_Y_GAP);
- _sizer->Add (_example, 0, wxBOTTOM, DCPOMATIC_SIZER_Y_GAP);
+ if (!_examples.empty ()) {
+ _sizer->Add (_example, 0, wxBOTTOM, DCPOMATIC_SIZER_Y_GAP);
+ }
_panel->SetSizer (_sizer);
for (dcp::NameFormat::Map::const_iterator i = titles.begin(); i != titles.end(); ++i) {
void
NameFormatEditor::update_example ()
{
+ if (_examples.empty ()) {
+ return;
+ }
+
_name.set_specification (careful_string_filter (wx_to_std (_specification->GetValue ())));
wxString example = wxString::Format (_("e.g. %s"), std_to_wx (_name.get (_examples, _suffix)));