diff options
| author | Carl Hetherington <cth@carlh.net> | 2014-03-17 00:22:52 +0000 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2014-03-17 00:22:52 +0000 |
| commit | 2e504b33eb9f38cac629ad31b7c107fb0cf5efda (patch) | |
| tree | 9c571653f312597b744896d45e27d422acbeea88 /src | |
| parent | a4c19a34244aeaf183c25878933b570fc5c0ee34 (diff) | |
| parent | 48b2c7b8ec57e72f2f27d5080e54e4b3c3fcda3d (diff) | |
Merge master.
Diffstat (limited to 'src')
32 files changed, 909 insertions, 849 deletions
diff --git a/src/lib/audio_content.cc b/src/lib/audio_content.cc index 01d1ecc38..6da5afa0c 100644 --- a/src/lib/audio_content.cc +++ b/src/lib/audio_content.cc @@ -141,7 +141,9 @@ AudioContent::audio_analysis_path () const return boost::filesystem::path (); } - return film->audio_analysis_path (dynamic_pointer_cast<const AudioContent> (shared_from_this ())); + boost::filesystem::path p = film->audio_analysis_dir (); + p /= digest (); + return p; } string diff --git a/src/lib/audio_content.h b/src/lib/audio_content.h index 18d88bccb..cecc8f13d 100644 --- a/src/lib/audio_content.h +++ b/src/lib/audio_content.h @@ -57,9 +57,9 @@ public: virtual int output_audio_frame_rate () const = 0; virtual AudioMapping audio_mapping () const = 0; virtual void set_audio_mapping (AudioMapping) = 0; + virtual boost::filesystem::path audio_analysis_path () const; boost::signals2::connection analyse_audio (boost::function<void()>); - boost::filesystem::path audio_analysis_path () const; void set_audio_gain (float); void set_audio_delay (int); diff --git a/src/lib/config.h b/src/lib/config.h index 14cd640ee..68aae7414 100644 --- a/src/lib/config.h +++ b/src/lib/config.h @@ -66,6 +66,7 @@ public: void set_use_any_servers (bool u) { _use_any_servers = u; + write (); } bool use_any_servers () const { @@ -75,6 +76,7 @@ public: /** @param s New list of servers */ void set_servers (std::vector<std::string> s) { _servers = s; + write (); } /** @return Host names / IP addresses of J2K encoding servers that should definitely be used */ @@ -182,35 +184,42 @@ public: /** @param n New number of local encoding threads */ void set_num_local_encoding_threads (int n) { _num_local_encoding_threads = n; + write (); } void set_default_directory (boost::filesystem::path d) { _default_directory = d; + write (); } /** @param p New server port */ void set_server_port_base (int p) { _server_port_base = p; + write (); } /** @param i IP address of a TMS that we can copy DCPs to */ void set_tms_ip (std::string i) { _tms_ip = i; + write (); } /** @param p Path on a TMS that we should write DCPs to */ void set_tms_path (std::string p) { _tms_path = p; + write (); } /** @param u User name to log into the TMS with */ void set_tms_user (std::string u) { _tms_user = u; + write (); } /** @param p Password to log into the TMS with */ void set_tms_password (std::string p) { _tms_password = p; + write (); } void add_cinema (boost::shared_ptr<Cinema> c) { @@ -223,74 +232,92 @@ public: void set_allowed_dcp_frame_rates (std::list<int> const & r) { _allowed_dcp_frame_rates = r; + write (); } void set_default_dci_metadata (DCIMetadata d) { _default_dci_metadata = d; + write (); } void set_language (std::string l) { _language = l; + write (); } void unset_language () { _language = boost::none; + write (); } void set_default_still_length (int s) { _default_still_length = s; + write (); } void set_default_container (Ratio const * c) { _default_container = c; + write (); } void set_default_dcp_content_type (DCPContentType const * t) { _default_dcp_content_type = t; + write (); } void set_dcp_metadata (dcp::XMLMetadata m) { _dcp_metadata = m; + write (); } void set_default_j2k_bandwidth (int b) { _default_j2k_bandwidth = b; + write (); } void set_default_audio_delay (int d) { _default_audio_delay = d; + write (); } void set_colour_conversions (std::vector<PresetColourConversion> const & c) { _colour_conversions = c; + write (); } void set_mail_server (std::string s) { _mail_server = s; + write (); } void set_mail_user (std::string u) { _mail_user = u; + write (); } void set_mail_password (std::string p) { _mail_password = p; + write (); } void set_kdm_from (std::string f) { _kdm_from = f; + write (); } void set_kdm_email (std::string e) { _kdm_email = e; + write (); } void set_check_for_updates (bool c) { _check_for_updates = c; + write (); } void set_check_for_test_updates (bool c) { _check_for_test_updates = c; + write (); } void write () const; diff --git a/src/lib/content.cc b/src/lib/content.cc index 814d9c1a5..1fb4681a2 100644 --- a/src/lib/content.cc +++ b/src/lib/content.cc @@ -195,7 +195,10 @@ Content::clone () const xmlpp::Document doc; xmlpp::Node* node = doc.create_root_node ("Content"); as_xml (node); - return content_factory (film, cxml::NodePtr (new cxml::Node (node)), Film::current_state_version); + + /* notes is unused here (we assume) */ + list<string> notes; + return content_factory (film, cxml::NodePtr (new cxml::Node (node)), Film::current_state_version, notes); } string diff --git a/src/lib/content_factory.cc b/src/lib/content_factory.cc index 825c80498..092efd790 100644 --- a/src/lib/content_factory.cc +++ b/src/lib/content_factory.cc @@ -25,17 +25,18 @@ #include "util.h" using std::string; +using std::list; using boost::shared_ptr; shared_ptr<Content> -content_factory (shared_ptr<const Film> film, cxml::NodePtr node, int version) +content_factory (shared_ptr<const Film> film, cxml::NodePtr node, int version, list<string>& notes) { string const type = node->string_child ("Type"); boost::shared_ptr<Content> content; if (type == "FFmpeg") { - content.reset (new FFmpegContent (film, node, version)); + content.reset (new FFmpegContent (film, node, version, notes)); } else if (type == "Image") { content.reset (new ImageContent (film, node, version)); } else if (type == "Sndfile") { diff --git a/src/lib/content_factory.h b/src/lib/content_factory.h index 071d925e0..2eeebbc9f 100644 --- a/src/lib/content_factory.h +++ b/src/lib/content_factory.h @@ -19,5 +19,5 @@ class Film; -extern boost::shared_ptr<Content> content_factory (boost::shared_ptr<const Film>, cxml::NodePtr, int); +extern boost::shared_ptr<Content> content_factory (boost::shared_ptr<const Film>, cxml::NodePtr, int, std::list<std::string> &); extern boost::shared_ptr<Content> content_factory (boost::shared_ptr<const Film>, boost::filesystem::path); diff --git a/src/lib/cross.cc b/src/lib/cross.cc index 786f4b997..8785553cb 100644 --- a/src/lib/cross.cc +++ b/src/lib/cross.cc @@ -310,8 +310,11 @@ Waker::nudge () Waker::Waker () { -#ifdef DCPOMATIC_OSX - IOPMAssertionCreateWithName (kIOPMAssertionTypeNoIdleSleep, kIOPMAssertionLevelOn, CFSTR ("Encoding DCP"), &_assertion_id); +#ifdef DCPOMATIC_OSX + /* We should use this */ + // IOPMAssertionCreateWithName (kIOPMAssertionTypeNoIdleSleep, kIOPMAssertionLevelOn, CFSTR ("Encoding DCP"), &_assertion_id); + /* but it's not available on 10.5, so we use this */ + IOPMAssertionCreate (kIOPMAssertionTypeNoIdleSleep, kIOPMAssertionLevelOn, &_assertion_id); #endif } diff --git a/src/lib/ffmpeg_content.cc b/src/lib/ffmpeg_content.cc index 2b535a2ab..90c00283d 100644 --- a/src/lib/ffmpeg_content.cc +++ b/src/lib/ffmpeg_content.cc @@ -58,7 +58,7 @@ FFmpegContent::FFmpegContent (shared_ptr<const Film> f, boost::filesystem::path } -FFmpegContent::FFmpegContent (shared_ptr<const Film> f, shared_ptr<const cxml::Node> node, int version) +FFmpegContent::FFmpegContent (shared_ptr<const Film> f, shared_ptr<const cxml::Node> node, int version, list<string>& notes) : Content (f, node) , VideoContent (f, node, version) , AudioContent (f, node) @@ -82,7 +82,12 @@ FFmpegContent::FFmpegContent (shared_ptr<const Film> f, shared_ptr<const cxml::N c = node->node_children ("Filter"); for (list<cxml::NodePtr>::iterator i = c.begin(); i != c.end(); ++i) { - _filters.push_back (Filter::from_id ((*i)->content ())); + Filter const * f = Filter::from_id ((*i)->content ()); + if (f) { + _filters.push_back (f); + } else { + notes.push_back (String::compose (_("DCP-o-matic no longer supports the `%1' filter, so it has been turned off."), (*i)->content())); + } } _first_video = node->optional_number_child<double> ("FirstVideo"); @@ -213,13 +218,13 @@ FFmpegContent::technical_summary () const ss = _subtitle_stream->technical_summary (); } - pair<string, string> filt = Filter::ffmpeg_strings (_filters); + string filt = Filter::ffmpeg_string (_filters); return Content::technical_summary() + " - " + VideoContent::technical_summary() + " - " + AudioContent::technical_summary() + " - " + String::compose ( - "ffmpeg: audio %1, subtitle %2, filters %3 %4", as, ss, filt.first, filt.second + "ffmpeg: audio %1, subtitle %2, filters %3", as, ss, filt ); } @@ -470,3 +475,23 @@ FFmpegContent::identifier () const return s.str (); } +boost::filesystem::path +FFmpegContent::audio_analysis_path () const +{ + shared_ptr<const Film> film = _film.lock (); + if (!film) { + return boost::filesystem::path (); + } + + /* We need to include the stream ID in this path so that we get different + analyses for each stream. + */ + + boost::filesystem::path p = film->audio_analysis_dir (); + string name = digest (); + if (audio_stream ()) { + name += "_" + audio_stream()->identifier (); + } + p /= name; + return p; +} diff --git a/src/lib/ffmpeg_content.h b/src/lib/ffmpeg_content.h index 935d9560d..e4c4a8a52 100644 --- a/src/lib/ffmpeg_content.h +++ b/src/lib/ffmpeg_content.h @@ -127,7 +127,7 @@ class FFmpegContent : public VideoContent, public AudioContent, public SubtitleC { public: FFmpegContent (boost::shared_ptr<const Film>, boost::filesystem::path); - FFmpegContent (boost::shared_ptr<const Film>, boost::shared_ptr<const cxml::Node>, int version); + FFmpegContent (boost::shared_ptr<const Film>, boost::shared_ptr<const cxml::Node>, int version, std::list<std::string> &); FFmpegContent (boost::shared_ptr<const Film>, std::vector<boost::shared_ptr<Content> >); boost::shared_ptr<FFmpegContent> shared_from_this () { @@ -150,6 +150,7 @@ public: int output_audio_frame_rate () const; AudioMapping audio_mapping () const; void set_audio_mapping (AudioMapping); + boost::filesystem::path audio_analysis_path () const; void set_filters (std::vector<Filter const *> const &); diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index d37399eb3..32b00a1d6 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -487,14 +487,9 @@ FFmpegDecoder::decode_video_packet () list<pair<shared_ptr<Image>, int64_t> > images = graph->process (_frame); - string post_process = Filter::ffmpeg_strings (_ffmpeg_content->filters()).second; - for (list<pair<shared_ptr<Image>, int64_t> >::iterator i = images.begin(); i != images.end(); ++i) { shared_ptr<Image> image = i->first; - if (!post_process.empty ()) { - image = image->post_process (post_process, true); - } if (i->second != AV_NOPTS_VALUE) { video (image, false, ContentTime::from_seconds (i->second * av_q2d (_format_context->streams[_video_stream]->time_base)) + _pts_offset); diff --git a/src/lib/film.cc b/src/lib/film.cc index 21e7383bf..cc80f5bc2 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -232,11 +232,9 @@ Film::filename_safe_name () const } boost::filesystem::path -Film::audio_analysis_path (shared_ptr<const AudioContent> c) const +Film::audio_analysis_dir () const { - boost::filesystem::path p = dir ("analysis"); - p /= c->digest(); - return p; + return dir ("analysis"); } /** Add suitable Jobs to the JobManager to create a DCP for this Film */ @@ -383,8 +381,10 @@ Film::write_metadata () const _dirty = false; } -/** Read state from our metadata file */ -void +/** Read state from our metadata file. + * @return Notes about things that the user should know about, or empty. + */ +list<string> Film::read_metadata () { LocaleGuard lg; @@ -432,9 +432,13 @@ Film::read_metadata () _three_d = f.bool_child ("ThreeD"); _interop = f.bool_child ("Interop"); _key = dcp::Key (f.string_child ("Key")); - _playlist->set_from_xml (shared_from_this(), f.node_child ("Playlist"), _state_version); + + list<string> notes; + /* This method is the only one that can return notes (so far) */ + _playlist->set_from_xml (shared_from_this(), f.node_child ("Playlist"), _state_version, notes); _dirty = false; + return notes; } /** Given a directory name, return its full path within the Film's directory. @@ -923,6 +927,7 @@ Film::set_sequence_video (bool s) signal_changed (SEQUENCE_VIDEO); } +/** @return Size of the largest possible image in whatever resolution we are using */ dcp::Size Film::full_frame () const { @@ -937,6 +942,13 @@ Film::full_frame () const return dcp::Size (); } +/** @return Size of the frame */ +dcp::Size +Film::frame_size () const +{ + return fit_ratio_within (container()->ratio(), full_frame ()); +} + dcp::KDM Film::make_kdm ( shared_ptr<dcp::Certificate> target, diff --git a/src/lib/film.h b/src/lib/film.h index f776a3f72..9d1445d92 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -63,7 +63,7 @@ public: boost::filesystem::path info_path (int, Eyes) const; boost::filesystem::path internal_video_mxf_dir () const; boost::filesystem::path internal_video_mxf_filename () const; - boost::filesystem::path audio_analysis_path (boost::shared_ptr<const AudioContent>) const; + boost::filesystem::path audio_analysis_dir () const; boost::filesystem::path video_mxf_filename () const; boost::filesystem::path audio_mxf_filename () const; @@ -83,7 +83,7 @@ public: boost::filesystem::path file (boost::filesystem::path f) const; boost::filesystem::path dir (boost::filesystem::path d) const; - void read_metadata (); + std::list<std::string> read_metadata (); void write_metadata () const; boost::shared_ptr<xmlpp::Document> metadata () const; @@ -96,6 +96,7 @@ public: } dcp::Size full_frame () const; + dcp::Size frame_size () const; std::list<boost::filesystem::path> dcps () const; diff --git a/src/lib/filter.cc b/src/lib/filter.cc index 640a531e8..a7dd9c5ce 100644 --- a/src/lib/filter.cc +++ b/src/lib/filter.cc @@ -24,7 +24,6 @@ #include "filter.h" extern "C" { #include <libavfilter/avfilter.h> -#include <libpostproc/postprocess.h> } #include "i18n.h" @@ -36,15 +35,13 @@ vector<Filter const *> Filter::_filters; /** @param i Our id. * @param n User-visible name. * @param c User-visible category. - * @param v String for a FFmpeg video filter descriptor, or "". - * @param p String for a FFmpeg post-processing descriptor, or "". + * @param v String for a FFmpeg video filter descriptor. */ -Filter::Filter (string i, string n, string c, string v, string p) +Filter::Filter (string i, string n, string c, string v) : _id (i) , _name (n) , _category (c) , _vf (v) - , _pp (p) { } @@ -65,75 +62,41 @@ Filter::setup_filters () { /* Note: "none" is a magic id name, so don't use it here */ - maybe_add (N_("pphb"), _("Horizontal deblocking filter"), _("De-blocking"), N_(""), N_("hb")); - maybe_add (N_("ppvb"), _("Vertical deblocking filter"), _("De-blocking"), N_(""), N_("vb")); - maybe_add (N_("ppha"), _("Horizontal deblocking filter A"), _("De-blocking"), N_(""), N_("ha")); - maybe_add (N_("ppva"), _("Vertical deblocking filter A"), _("De-blocking"), N_(""), N_("va")); - maybe_add (N_("pph1"), _("Experimental horizontal deblocking filter 1"), _("De-blocking"), N_(""), N_("h1")); - maybe_add (N_("pphv"), _("Experimental vertical deblocking filter 1"), _("De-blocking"), N_(""), N_("v1")); - maybe_add (N_("ppdr"), _("Deringing filter"), _("Misc"), N_(""), N_("dr")); - maybe_add (N_("pplb"), _("Linear blend deinterlacer"), _("De-interlacing"), N_(""), N_("lb")); - maybe_add (N_("ppli"), _("Linear interpolating deinterlacer"), _("De-interlacing"), N_(""), N_("li")); - maybe_add (N_("ppci"), _("Cubic interpolating deinterlacer"), _("De-interlacing"), N_(""), N_("ci")); - maybe_add (N_("ppmd"), _("Median deinterlacer"), _("De-interlacing"), N_(""), N_("md")); - maybe_add (N_("ppfd"), _("FFMPEG deinterlacer"), _("De-interlacing"), N_(""), N_("fd")); - maybe_add (N_("ppl5"), _("FIR low-pass deinterlacer"), _("De-interlacing"), N_(""), N_("l5")); - maybe_add (N_("mcdeint"), _("Motion compensating deinterlacer"), _("De-interlacing"), N_("mcdeint"), N_("")); - maybe_add (N_("kerndeint"), _("Kernel deinterlacer"), _("De-interlacing"), N_("kerndeint"), N_("")); - maybe_add (N_("yadif"), _("Yet Another Deinterlacing Filter"), _("De-interlacing"), N_("yadif"), N_("")); - maybe_add (N_("pptn"), _("Temporal noise reducer"), _("Noise reduction"), N_(""), N_("tn")); - maybe_add (N_("ppfq"), _("Force quantizer"), _("Misc"), N_(""), N_("fq")); - maybe_add (N_("gradfun"), _("Gradient debander"), _("Misc"), N_("gradfun"), N_("")); - maybe_add (N_("unsharp"), _("Unsharp mask and Gaussian blur"), _("Misc"), N_("unsharp"), N_("")); - maybe_add (N_("denoise3d"), _("3D denoiser"), _("Noise reduction"), N_("denoise3d"), N_("")); - maybe_add (N_("hqdn3d"), _("High quality 3D denoiser"), _("Noise reduction"), N_("hqdn3d"), N_("")); - maybe_add (N_("telecine"), _("Telecine filter"), _("Misc"), N_("telecine"), N_("")); - maybe_add (N_("ow"), _("Overcomplete wavelet denoiser"), _("Noise reduction"), N_("mp=ow"), N_("")); + maybe_add (N_("mcdeint"), _("Motion compensating deinterlacer"), _("De-interlacing"), N_("mcdeint")); + maybe_add (N_("kerndeint"), _("Kernel deinterlacer"), _("De-interlacing"), N_("kerndeint")); + maybe_add (N_("yadif"), _("Yet Another Deinterlacing Filter"), _("De-interlacing"), N_("yadif")); + maybe_add (N_("gradfun"), _("Gradient debander"), _("Misc"), N_("gradfun")); + maybe_add (N_("unsharp"), _("Unsharp mask and Gaussian blur"), _("Misc"), N_("unsharp")); + maybe_add (N_("denoise3d"), _("3D denoiser"), _("Noise reduction"), N_("denoise3d")); + maybe_add (N_("hqdn3d"), _("High quality 3D denoiser"), _("Noise reduction"), N_("hqdn3d")); + maybe_add (N_("telecine"), _("Telecine filter"), _("Misc"), N_("telecine")); + maybe_add (N_("ow"), _("Overcomplete wavelet denoiser"), _("Noise reduction"), N_("mp=ow")); } void -Filter::maybe_add (string i, string n, string c, string v, string p) +Filter::maybe_add (string i, string n, string c, string v) { - if (!v.empty ()) { - if (avfilter_get_by_name (i.c_str())) { - _filters.push_back (new Filter (i, n, c, v, p)); - } - } else if (!p.empty ()) { - pp_mode* m = pp_get_mode_by_name_and_quality (p.c_str(), PP_QUALITY_MAX); - if (m) { - _filters.push_back (new Filter (i, n, c, v, p)); - pp_free_mode (m); - } + if (avfilter_get_by_name (i.c_str())) { + _filters.push_back (new Filter (i, n, c, v)); } } /** @param filters Set of filters. - * @return A pair; .first is a string to pass to FFmpeg for the video filters, - * .second is a string to pass for the post-processors. + * @return String to pass to FFmpeg for the video filters. */ -pair<string, string> -Filter::ffmpeg_strings (vector<Filter const *> const & filters) +string +Filter::ffmpeg_string (vector<Filter const *> const & filters) { string vf; - string pp; for (vector<Filter const *>::const_iterator i = filters.begin(); i != filters.end(); ++i) { - if (!(*i)->vf().empty ()) { - if (!vf.empty ()) { - vf += N_(","); - } - vf += (*i)->vf (); - } - - if (!(*i)->pp().empty ()) { - if (!pp.empty()) { - pp += N_(","); - } - pp += (*i)->pp (); + if (!vf.empty ()) { + vf += N_(","); } + vf += (*i)->vf (); } - return make_pair (vf, pp); + return vf; } /** @param d Our id. diff --git a/src/lib/filter.h b/src/lib/filter.h index 5971cd5cf..258e74991 100644 --- a/src/lib/filter.h +++ b/src/lib/filter.h @@ -29,12 +29,16 @@ #include <boost/utility.hpp> /** @class Filter - * @brief A class to describe one of FFmpeg's video or post-processing filters. + * @brief A class to describe one of FFmpeg's video filters. + * + * We don't support FFmpeg's post-processing filters here as they cannot cope with greater than + * 8bpp. FFmpeg quantizes e.g. yuv422p10le down to yuv422p before running such filters, which + * we don't really want to do. */ class Filter : public boost::noncopyable { public: - Filter (std::string, std::string, std::string, std::string, std::string); + Filter (std::string, std::string, std::string, std::string); /** @return our id */ std::string id () const { @@ -51,11 +55,6 @@ public: return _vf; } - /** @return string for a FFmpeg post-processing descriptor */ - std::string pp () const { - return _pp; - } - std::string category () const { return _category; } @@ -63,7 +62,7 @@ public: static std::vector<Filter const *> all (); static Filter const * from_id (std::string); static void setup_filters (); - static std::pair<std::string, std::string> ffmpeg_strings (std::vector<Filter const *> const &); + static std::string ffmpeg_string (std::vector<Filter const *> const &); private: @@ -74,12 +73,10 @@ private: std::string _category; /** string for a FFmpeg video filter descriptor */ std::string _vf; - /** string for a FFmpeg post-processing descriptor */ - std::string _pp; /** all available filters */ static std::vector<Filter const *> _filters; - static void maybe_add (std::string, std::string, std::string, std::string, std::string); + static void maybe_add (std::string, std::string, std::string, std::string); }; #endif diff --git a/src/lib/filter_graph.cc b/src/lib/filter_graph.cc index 48d94e175..5add16d19 100644 --- a/src/lib/filter_graph.cc +++ b/src/lib/filter_graph.cc @@ -60,7 +60,7 @@ FilterGraph::FilterGraph (shared_ptr<const FFmpegContent> content, dcp::Size s, { _frame = av_frame_alloc (); - string filters = Filter::ffmpeg_strings (content->filters()).first; + string filters = Filter::ffmpeg_string (content->filters()); if (filters.empty ()) { filters = "copy"; } diff --git a/src/lib/image.cc b/src/lib/image.cc index 98645c299..c3b1ca77a 100644 --- a/src/lib/image.cc +++ b/src/lib/image.cc @@ -168,51 +168,6 @@ Image::scale (dcp::Size out_size, Scaler const * scaler, AVPixelFormat out_forma return scaled; } -/** Run a FFmpeg post-process on this image and return the processed version. - * @param pp Flags for the required set of post processes. - * @return Post-processed image. - */ -shared_ptr<Image> -Image::post_process (string pp, bool aligned) const -{ - shared_ptr<Image> out (new Image (pixel_format(), size (), aligned)); - - int pp_format = 0; - switch (pixel_format()) { - case PIX_FMT_YUV420P: - pp_format = PP_FORMAT_420; - break; - case PIX_FMT_YUV422P10LE: - case PIX_FMT_YUV422P: - case PIX_FMT_UYVY422: - pp_format = PP_FORMAT_422; - break; - case PIX_FMT_YUV444P: - case PIX_FMT_YUV444P9BE: - case PIX_FMT_YUV444P9LE: - case PIX_FMT_YUV444P10BE: - case PIX_FMT_YUV444P10LE: - pp_format = PP_FORMAT_444; - default: - throw PixelFormatError ("post_process", pixel_format()); - } - - pp_mode* mode = pp_get_mode_by_name_and_quality (pp.c_str (), PP_QUALITY_MAX); - pp_context* context = pp_get_context (size().width, size().height, pp_format | PP_CPU_CAPS_MMX2); - - pp_postprocess ( - (const uint8_t **) data(), stride(), - out->data(), out->stride(), - size().width, size().height, - 0, 0, mode, context, 0 - ); - - pp_free_mode (mode); - pp_free_context (context); - - return out; -} - shared_ptr<Image> Image::crop (Crop crop, bool aligned) const { diff --git a/src/lib/image.h b/src/lib/image.h index 3220a23b4..5eba11041 100644 --- a/src/lib/image.h +++ b/src/lib/image.h @@ -58,7 +58,6 @@ public: int lines (int) const; boost::shared_ptr<Image> scale (dcp::Size, Scaler const *, AVPixelFormat, bool aligned) const; - boost::shared_ptr<Image> post_process (std::string, bool aligned) const; boost::shared_ptr<Image> crop (Crop c, bool aligned) const; boost::shared_ptr<Image> crop_scale_window (Crop c, dcp::Size, dcp::Size, Scaler const *, AVPixelFormat, bool aligned) const; diff --git a/src/lib/player.cc b/src/lib/player.cc index e89e84aa6..f83e4ed26 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -81,7 +81,7 @@ Player::Player (shared_ptr<const Film> f, shared_ptr<const Playlist> p) _playlist_changed_connection = _playlist->Changed.connect (bind (&Player::playlist_changed, this)); _playlist_content_changed_connection = _playlist->ContentChanged.connect (bind (&Player::content_changed, this, _1, _2, _3)); _film_changed_connection = _film->Changed.connect (bind (&Player::film_changed, this, _1)); - set_video_container_size (fit_ratio_within (_film->container()->ratio (), _film->full_frame ())); + set_video_container_size (_film->frame_size ()); } void diff --git a/src/lib/playlist.cc b/src/lib/playlist.cc index b7b4c20f7..c46e65d8b 100644 --- a/src/lib/playlist.cc +++ b/src/lib/playlist.cc @@ -113,11 +113,11 @@ Playlist::video_identifier () const /** @param node <Playlist> node */ void -Playlist::set_from_xml (shared_ptr<const Film> film, shared_ptr<const cxml::Node> node, int version) +Playlist::set_from_xml (shared_ptr<const Film> film, shared_ptr<const cxml::Node> node, int version, list<string>& notes) { list<cxml::NodePtr> c = node->node_children ("Content"); for (list<cxml::NodePtr>::iterator i = c.begin(); i != c.end(); ++i) { - _content.push_back (content_factory (film, *i, version)); + _content.push_back (content_factory (film, *i, version, notes)); } sort (_content.begin(), _content.end(), ContentSorter ()); diff --git a/src/lib/playlist.h b/src/lib/playlist.h index 35709f109..444eb9ae5 100644 --- a/src/lib/playlist.h +++ b/src/lib/playlist.h @@ -57,7 +57,7 @@ public: ~Playlist (); void as_xml (xmlpp::Node *); - void set_from_xml (boost::shared_ptr<const Film>, boost::shared_ptr<const cxml::Node>, int); + void set_from_xml (boost::shared_ptr<const Film>, boost::shared_ptr<const cxml::Node>, int, std::list<std::string> &); void add (boost::shared_ptr<Content>); void remove (boost::shared_ptr<Content>); diff --git a/src/lib/video_content.cc b/src/lib/video_content.cc index 11310c5da..c3aea2b0f 100644 --- a/src/lib/video_content.cc +++ b/src/lib/video_content.cc @@ -442,19 +442,30 @@ VideoContentScale::name () const return _("No scale"); } +/** @param display_container Size of the container that we are displaying this content in. + * @param film_container The size of the film's image. + */ dcp::Size -VideoContentScale::size (shared_ptr<const VideoContent> c, dcp::Size container) const +VideoContentScale::size (shared_ptr<const VideoContent> c, dcp::Size display_container, dcp::Size film_container) const { if (_ratio) { - return fit_ratio_within (_ratio->ratio (), container); + return fit_ratio_within (_ratio->ratio (), display_container); } - /* Force scale if the container is smaller than the content's image */ - if (_scale || container.width < c->video_size().width || container.height < c->video_size().height) { - return fit_ratio_within (c->video_size().ratio (), container); + libdcp::Size const ac = c->video_size_after_crop (); + + /* Force scale if the film_container is smaller than the content's image */ + if (_scale || film_container.width < ac.width || film_container.height < ac.height) { + return fit_ratio_within (ac.ratio (), display_container); } - return c->video_size (); + /* Scale the image so that it will be in the right place in film_container, even if display_container is a + different size. + */ + return libdcp::Size ( + c->video_size().width * float(display_container.width) / film_container.width, + c->video_size().height * float(display_container.height) / film_container.height + ); } void diff --git a/src/lib/video_content.h b/src/lib/video_content.h index a82c6c221..d2b19480f 100644 --- a/src/lib/video_content.h +++ b/src/lib/video_content.h @@ -45,7 +45,7 @@ public: VideoContentScale (bool); VideoContentScale (boost::shared_ptr<cxml::Node>); - dcp::Size size (boost::shared_ptr<const VideoContent>, dcp::Size) const; + dcp::Size size (boost::shared_ptr<const VideoContent>, dcp::Size, dcp::Size) const; std::string id () const; std::string name () const; void as_xml (xmlpp::Node *) const; @@ -64,7 +64,9 @@ public: } private: + /** a ratio to stretch the content to, or 0 for no stretch */ Ratio const * _ratio; + /** true if we want to scale the content */ bool _scale; static std::vector<VideoContentScale> _scales; diff --git a/src/lib/writer.cc b/src/lib/writer.cc index 33b7dd51e..125efd644 100644 --- a/src/lib/writer.cc +++ b/src/lib/writer.cc @@ -45,6 +45,9 @@ #include "i18n.h" +/* OS X strikes again */ +#undef set_key + using std::make_pair; using std::pair; using std::string; @@ -91,7 +94,7 @@ Writer::Writer (shared_ptr<const Film> f, weak_ptr<Job> j) _picture_mxf.reset (new dcp::MonoPictureMXF (dcp::Fraction (_film->video_frame_rate (), 1))); } - _picture_mxf->set_size (fit_ratio_within (_film->container()->ratio(), _film->full_frame ())); + _picture_mxf->set_size (_film->frame_size ()); if (_film->encrypted ()) { _picture_mxf->set_key (_film->key ()); diff --git a/src/tools/dcpomatic.cc b/src/tools/dcpomatic.cc index 6b534f4de..2f64371ae 100644 --- a/src/tools/dcpomatic.cc +++ b/src/tools/dcpomatic.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2013 Carl Hetherington <cth@carlh.net> + Copyright (C) 2012-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 @@ -29,6 +29,7 @@ #include <wx/generic/aboutdlgg.h> #include <wx/stdpaths.h> #include <wx/cmdline.h> +#include <wx/preferences.h> #include "wx/film_viewer.h" #include "wx/film_editor.h" #include "wx/job_manager_view.h" @@ -114,7 +115,7 @@ private: }; -void +static void maybe_save_then_delete_film () { if (!film) { @@ -135,6 +136,30 @@ maybe_save_then_delete_film () film.reset (); } +static void +check_film_state_version (int v) +{ + if (v == 4) { + error_dialog ( + 0, + _("This film was created with an old version of DVD-o-matic and may not load correctly " + "in this version. Please check the film's settings carefully.") + ); + } +} + +static void +load_film (boost::filesystem::path file) +{ + film.reset (new Film (file)); + list<string> const notes = film->read_metadata (); + check_film_state_version (film->state_version ()); + for (list<string>::const_iterator i = notes.begin(); i != notes.end(); ++i) { + error_dialog (0, std_to_wx (*i)); + } + film->log()->set_level (log_level); +} + #define ALWAYS 0x0 #define NEEDS_FILM 0x1 #define NOT_DURING_DCP_CREATION 0x2 @@ -142,14 +167,14 @@ maybe_save_then_delete_film () map<wxMenuItem*, int> menu_items; -void +static void add_item (wxMenu* menu, wxString text, int id, int sens) { wxMenuItem* item = menu->Append (id, text); menu_items.insert (make_pair (item, sens)); } -void +static void set_menu_sensitivity () { list<shared_ptr<Job> > jobs = JobManager::instance()->get (); @@ -194,7 +219,7 @@ enum { ID_tools_check_for_updates }; -void +static void setup_menu (wxMenuBar* m) { wxMenu* file = new wxMenu; @@ -256,6 +281,7 @@ public: : wxFrame (NULL, -1, title) , _hints_dialog (0) , _servers_list_dialog (0) + , _config_dialog (0) { #if defined(DCPOMATIC_WINDOWS) && defined(DCPOMATIC_WINDOWS_CONSOLE) AllocConsole(); @@ -326,17 +352,6 @@ public: overall_panel->SetSizer (main_sizer); } - void check_film_state_version (int v) - { - if (v == 4) { - error_dialog ( - this, - _("This film was created with an old version of DVD-o-matic and may not load correctly " - "in this version. Please check the film's settings carefully.") - ); - } - } - private: void set_film () @@ -416,10 +431,7 @@ private: if (r == wxID_OK) { maybe_save_then_delete_film (); try { - film.reset (new Film (wx_to_std (c->GetPath ()))); - film->read_metadata (); - check_film_state_version (film->state_version ()); - film->log()->set_level (log_level); + load_film (wx_to_std (c->GetPath ())); set_film (); } catch (std::exception& e) { wxString p = c->GetPath (); @@ -450,10 +462,10 @@ private: void edit_preferences () { - ConfigDialog* d = new ConfigDialog (this); - d->ShowModal (); - d->Destroy (); - Config::instance()->write (); + if (!_config_dialog) { + _config_dialog = create_config_dialog (); + } + _config_dialog->Show (this); } void jobs_make_dcp () @@ -592,6 +604,7 @@ private: HintsDialog* _hints_dialog; ServersListDialog* _servers_list_dialog; + wxPreferencesEditor* _config_dialog; }; static const wxCmdLineEntryDesc command_line_description[] = { @@ -645,9 +658,7 @@ class App : public wxApp if (!film_to_load.empty() && boost::filesystem::is_directory (film_to_load)) { try { - film.reset (new Film (film_to_load)); - film->read_metadata (); - film->log()->set_level (log_level); + load_film (film_to_load); } catch (exception& e) { error_dialog (0, std_to_wx (String::compose (wx_to_std (_("Could not load film %1 (%2)")), film_to_load, e.what()))); } @@ -677,7 +688,7 @@ class App : public wxApp _timer->Start (1000); if (film) { - _frame->check_film_state_version (film->state_version ()); + check_film_state_version (film->state_version ()); } UpdateChecker::instance()->StateChanged.connect (boost::bind (&App::update_checker_state_changed, this)); diff --git a/src/wx/about_dialog.cc b/src/wx/about_dialog.cc index 3c0730870..01332dfcc 100644 --- a/src/wx/about_dialog.cc +++ b/src/wx/about_dialog.cc @@ -91,92 +91,96 @@ AboutDialog::AboutDialog (wxWindow* parent) add_section (_("Written by"), written_by); wxArrayString translated_by; - translated_by.Add (wxT ("Adam Klotblixt")); - translated_by.Add (wxT ("Lilian Lefranc")); translated_by.Add (wxT ("Manuel AC")); - translated_by.Add (wxT ("Markus Raab")); translated_by.Add (wxT ("Massimiliano Broggi")); - translated_by.Add (wxT ("Olivier Perriere")); - translated_by.Add (wxT ("Thierry Journet")); translated_by.Add (wxT ("William Fanelli")); + translated_by.Add (wxT ("Thierry Journet")); + translated_by.Add (wxT ("Adam Klotblixt")); + translated_by.Add (wxT ("Lilian Lefranc")); + translated_by.Add (wxT ("Olivier Perriere")); + translated_by.Add (wxT ("Markus Raab")); add_section (_("Translated by"), translated_by); + wxArrayString artwork_by; + artwork_by.Add (wxT ("David Vignoni")); + add_section (_("Artwork by"), artwork_by); + wxArrayString supported_by; + supported_by.Add (wxT ("Manual AC")); + supported_by.Add (wxT ("Kambiz Afshar")); + supported_by.Add (wxT ("Jeff Boot")); + supported_by.Add (wxT ("Kieran Carroll")); + supported_by.Add (wxT ("Frank Cianciolo")); + supported_by.Add (wxT ("Cinema Clarici")); supported_by.Add (wxT ("Adam Colt")); - supported_by.Add (wxT ("Adam Klotblixt")); - supported_by.Add (wxT ("Aldo Midali")); supported_by.Add (wxT ("Andres Fink")); - supported_by.Add (wxT ("Andrä Steiner")); - supported_by.Add (wxT ("Carsten Kurz")); - supported_by.Add (wxT ("Cinema Clarici")); supported_by.Add (wxT ("Evan Freeze")); - supported_by.Add (wxT ("Filip Kovcin")); + supported_by.Add (wxT ("Rodolfo Giuliano")); supported_by.Add (wxT ("Flor Guillaume")); - supported_by.Add (wxT ("Frank Cianciolo")); - supported_by.Add (wxT ("Frank de Wulf")); + supported_by.Add (wxT ("Jonathan Jensen")); + supported_by.Add (wxT ("Adam Klotblixt")); + supported_by.Add (wxT ("Filip Kovcin")); + supported_by.Add (wxT ("Carsten Kurz")); + supported_by.Add (wxT ("Lilian Lefranc")); + supported_by.Add (wxT ("Sean Leigh")); + supported_by.Add (wxT ("Olivier Lemaire")); supported_by.Add (wxT ("Gavin Lewarne")); + supported_by.Add (wxT ("Theo Lipfert")); + supported_by.Add (wxT ("Mattias Mattsson")); + supported_by.Add (wxT ("Kjarten Michaelsen")); + supported_by.Add (wxT ("Aldo Midali")); + supported_by.Add (wxT ("Sylvain Mielle")); + supported_by.Add (wxT ("Lindsay Morris")); + supported_by.Add (wxT ("Tim O'Brien")); supported_by.Add (wxT ("Ivan Pullman")); - supported_by.Add (wxT ("Jeff Boot")); - supported_by.Add (wxT ("Jonathan Jensen")); + supported_by.Add (wxT ("Andrä Steiner")); supported_by.Add (wxT ("Jussi Siponen")); - supported_by.Add (wxT ("Kambiz Afshar")); - supported_by.Add (wxT ("Kieran Carroll")); - supported_by.Add (wxT ("Kjarten Michaelsen")); supported_by.Add (wxT ("Lasse Salling")); - supported_by.Add (wxT ("Lilian Lefranc")); - supported_by.Add (wxT ("Lindsay Morris")); - supported_by.Add (wxT ("Manual AC")); - supported_by.Add (wxT ("Mattias Mattsson")); supported_by.Add (wxT ("Mike Stiebing")); - supported_by.Add (wxT ("Olivier Lemaire")); supported_by.Add (wxT ("Randy Stankey")); - supported_by.Add (wxT ("Rodolfo Giuliano")); - supported_by.Add (wxT ("Sean Leigh")); - supported_by.Add (wxT ("Sylvain Mielle")); - supported_by.Add (wxT ("Theo Lipfert")); - supported_by.Add (wxT ("Tim O'Brien")); supported_by.Add (wxT ("Wolfgang Woehl")); supported_by.Add (wxT ("Wolfram Weber")); + supported_by.Add (wxT ("Frank de Wulf")); add_section (_("Supported by"), supported_by); wxArrayString tested_by; - tested_by.Add (wxT ("Ada de Kamper")); - tested_by.Add (wxT ("Adam Colt")); - tested_by.Add (wxT ("Adam Keay")); - tested_by.Add (wxT ("Anders Nordentoft-Madsen")); - tested_by.Add (wxT ("Andreas Eli")); - tested_by.Add (wxT ("Andreas Weiss")); - tested_by.Add (wxT ("Bill Lam")); - tested_by.Add (wxT ("Brad Miller")); - tested_by.Add (wxT ("Carsten Kurz")); + tested_by.Add (wxT ("Trever Anderson")); + tested_by.Add (wxT ("Mike Blakesley")); tested_by.Add (wxT ("David Booty")); - tested_by.Add (wxT ("Denzil Kriekenbeek")); - tested_by.Add (wxT ("Gavin Lewarne")); - tested_by.Add (wxT ("Greg Rooke")); - tested_by.Add (wxT ("Gérald Maruccia")); + tested_by.Add (wxT ("Roop Chand")); + tested_by.Add (wxT ("Adam Colt")); tested_by.Add (wxT ("John Convertino")); + tested_by.Add (wxT ("Andreas Eli")); + tested_by.Add (wxT ("Maurizio Giampà ")); + tested_by.Add (wxT ("Luke Granger-Brown")); + tested_by.Add (wxT ("Steve Guttag")); + tested_by.Add (wxT ("Patrick Haderer")); tested_by.Add (wxT ("Jonathan Jensen")); - tested_by.Add (wxT ("Karim Senoucci")); + tested_by.Add (wxT ("Thierry Journet")); + tested_by.Add (wxT ("Ada de Kamper")); + tested_by.Add (wxT ("Stefan Karner")); + tested_by.Add (wxT ("Adam Keay")); + tested_by.Add (wxT ("Simon Kesselman")); + tested_by.Add (wxT ("Pepijn Klijs")); + tested_by.Add (wxT ("Denzil Kriekenbeek")); + tested_by.Add (wxT ("Carsten Kurz")); + tested_by.Add (wxT ("Bill Lam")); tested_by.Add (wxT ("Lilian Lefranc")); - tested_by.Add (wxT ("Luke Granger-Brown")); - tested_by.Add (wxT ("Markus Raab")); + tested_by.Add (wxT ("Olivier Lemaire")); + tested_by.Add (wxT ("Gavin Lewarne")); tested_by.Add (wxT ("Mattias Mattsson")); - tested_by.Add (wxT ("Maurizio Giampà ")); + tested_by.Add (wxT ("Gérald Maruccia")); + tested_by.Add (wxT ("Will Meadows")); + tested_by.Add (wxT ("Brad Miller")); + tested_by.Add (wxT ("Anders Nordentoft-Madsen")); tested_by.Add (wxT ("Mauro Ottonello")); - tested_by.Add (wxT ("Mike Blakesley")); - tested_by.Add (wxT ("Olivier Lemaire")); - tested_by.Add (wxT ("Patrick Haderer")); - tested_by.Add (wxT ("Paul Willmott")); - tested_by.Add (wxT ("Pepijn Klijs")); tested_by.Add (wxT ("Peter Puchner")); - tested_by.Add (wxT ("Roop Chand")); - tested_by.Add (wxT ("Simon Kesselman")); + tested_by.Add (wxT ("Markus Raab")); + tested_by.Add (wxT ("Greg Rooke")); + tested_by.Add (wxT ("Karim Senoucci")); tested_by.Add (wxT ("Simon Vannarath")); - tested_by.Add (wxT ("Stefan Karner")); - tested_by.Add (wxT ("Steve Guttag")); - tested_by.Add (wxT ("Thierry Journet")); - tested_by.Add (wxT ("Trever Anderson")); - tested_by.Add (wxT ("Will Meadows")); + tested_by.Add (wxT ("Andreas Weiss")); + tested_by.Add (wxT ("Paul Willmott")); tested_by.Add (wxT ("Wolfgang Woehl")); add_section (_("Tested by"), tested_by); diff --git a/src/wx/config_dialog.cc b/src/wx/config_dialog.cc index 911cb4b3f..44745006c 100644 --- a/src/wx/config_dialog.cc +++ b/src/wx/config_dialog.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2012 Carl Hetherington <cth@carlh.net> + Copyright (C) 2012-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 @@ -25,7 +25,9 @@ #include <boost/lexical_cast.hpp> #include <boost/filesystem.hpp> #include <wx/stdpaths.h> -#include <wx/notebook.h> +#include <wx/preferences.h> +#include <wx/filepicker.h> +#include <wx/spinctrl.h> #include <dcp/colour_matrix.h> #include "lib/config.h" #include "lib/ratio.h" @@ -35,6 +37,7 @@ #include "lib/colour_conversion.h" #include "config_dialog.h" #include "wx_util.h" +#include "editable_list.h" #include "filter_dialog.h" #include "dir_picker_ctrl.h" #include "dci_metadata_dialog.h" @@ -44,561 +47,691 @@ using std::vector; using std::string; using std::list; +using std::cout; using boost::bind; using boost::shared_ptr; using boost::lexical_cast; -ConfigDialog::ConfigDialog (wxWindow* parent) - : wxDialog (parent, wxID_ANY, _("DCP-o-matic Preferences"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) +class Page { - wxBoxSizer* s = new wxBoxSizer (wxVERTICAL); - _notebook = new wxNotebook (this, wxID_ANY); - s->Add (_notebook, 1); - - make_misc_panel (); - _notebook->AddPage (_misc_panel, _("Miscellaneous"), true); - make_defaults_panel (); - _notebook->AddPage (_defaults_panel, _("Defaults"), false); - make_servers_panel (); - _notebook->AddPage (_servers_panel, _("Encoding servers"), false); - make_colour_conversions_panel (); - _notebook->AddPage (_colour_conversions_panel, _("Colour conversions"), false); - make_metadata_panel (); - _notebook->AddPage (_metadata_panel, _("Metadata"), false); - make_tms_panel (); - _notebook->AddPage (_tms_panel, _("TMS"), false); - make_kdm_email_panel (); - _notebook->AddPage (_kdm_email_panel, _("KDM email"), false); - - wxBoxSizer* overall_sizer = new wxBoxSizer (wxVERTICAL); - overall_sizer->Add (s, 1, wxEXPAND | wxALL, DCPOMATIC_DIALOG_BORDER); - - wxSizer* buttons = CreateSeparatedButtonSizer (wxOK); - if (buttons) { - overall_sizer->Add (buttons, wxSizerFlags().Expand().DoubleBorder()); - } - - SetSizer (overall_sizer); - overall_sizer->Layout (); - overall_sizer->SetSizeHints (this); -} +public: + Page (wxSize panel_size, int border) + : _panel_size (panel_size) + , _border (border) + {} + +protected: + wxSize _panel_size; + int _border; +}; -void -ConfigDialog::make_misc_panel () +class GeneralPage : public wxStockPreferencesPage, public Page { - _misc_panel = new wxPanel (_notebook); - wxBoxSizer* s = new wxBoxSizer (wxVERTICAL); - _misc_panel->SetSizer (s); - - wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP); - table->AddGrowableCol (1, 1); - s->Add (table, 1, wxALL | wxEXPAND, 8); - - _set_language = new wxCheckBox (_misc_panel, wxID_ANY, _("Set language")); - table->Add (_set_language, 1); - _language = new wxChoice (_misc_panel, wxID_ANY); - _language->Append (wxT ("English")); - _language->Append (wxT ("Français")); - _language->Append (wxT ("Italiano")); - _language->Append (wxT ("Español")); - _language->Append (wxT ("Svenska")); - _language->Append (wxT ("Deutsch")); - table->Add (_language); - - wxStaticText* restart = add_label_to_sizer (table, _misc_panel, _("(restart DCP-o-matic to see language changes)"), false); - wxFont font = restart->GetFont(); - font.SetStyle (wxFONTSTYLE_ITALIC); - font.SetPointSize (font.GetPointSize() - 1); - restart->SetFont (font); - table->AddSpacer (0); - - add_label_to_sizer (table, _misc_panel, _("Threads to use for encoding on this host"), true); - _num_local_encoding_threads = new wxSpinCtrl (_misc_panel); - table->Add (_num_local_encoding_threads, 1); - - add_label_to_sizer (table, _misc_panel, _("Outgoing mail server"), true); - _mail_server = new wxTextCtrl (_misc_panel, wxID_ANY); - table->Add (_mail_server, 1, wxEXPAND | wxALL); - - add_label_to_sizer (table, _misc_panel, _("Mail user name"), true); - _mail_user = new wxTextCtrl (_misc_panel, wxID_ANY); - table->Add (_mail_user, 1, wxEXPAND | wxALL); - - add_label_to_sizer (table, _misc_panel, _("Mail password"), true); - _mail_password = new wxTextCtrl (_misc_panel, wxID_ANY); - table->Add (_mail_password, 1, wxEXPAND | wxALL); - - wxStaticText* plain = add_label_to_sizer (table, _misc_panel, _("(password will be stored on disk in plaintext)"), false); - plain->SetFont (font); - table->AddSpacer (0); - - add_label_to_sizer (table, _misc_panel, _("From address for KDM emails"), true); - _kdm_from = new wxTextCtrl (_misc_panel, wxID_ANY); - table->Add (_kdm_from, 1, wxEXPAND | wxALL); +public: + GeneralPage (wxSize panel_size, int border) + : wxStockPreferencesPage (Kind_General) + , Page (panel_size, border) + {} - _check_for_updates = new wxCheckBox (_misc_panel, wxID_ANY, _("Check for updates on startup")); - table->Add (_check_for_updates, 1, wxEXPAND | wxALL); - table->AddSpacer (0); + wxWindow* CreateWindow (wxWindow* parent) + { + wxPanel* panel = new wxPanel (parent); + wxBoxSizer* s = new wxBoxSizer (wxVERTICAL); + panel->SetSizer (s); + + wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP); + table->AddGrowableCol (1, 1); + s->Add (table, 1, wxALL | wxEXPAND, _border); + + _set_language = new wxCheckBox (panel, wxID_ANY, _("Set language")); + table->Add (_set_language, 1); + _language = new wxChoice (panel, wxID_ANY); + _language->Append (wxT ("English")); + _language->Append (wxT ("Français")); + _language->Append (wxT ("Italiano")); + _language->Append (wxT ("Español")); + _language->Append (wxT ("Svenska")); + _language->Append (wxT ("Deutsch")); + table->Add (_language); + + wxStaticText* restart = add_label_to_sizer (table, panel, _("(restart DCP-o-matic to see language changes)"), false); + wxFont font = restart->GetFont(); + font.SetStyle (wxFONTSTYLE_ITALIC); + font.SetPointSize (font.GetPointSize() - 1); + restart->SetFont (font); + table->AddSpacer (0); + + add_label_to_sizer (table, panel, _("Threads to use for encoding on this host"), true); + _num_local_encoding_threads = new wxSpinCtrl (panel); + table->Add (_num_local_encoding_threads, 1); + + add_label_to_sizer (table, panel, _("Outgoing mail server"), true); + _mail_server = new wxTextCtrl (panel, wxID_ANY); + table->Add (_mail_server, 1, wxEXPAND | wxALL); + + add_label_to_sizer (table, panel, _("Mail user name"), true); + _mail_user = new wxTextCtrl (panel, wxID_ANY); + table->Add (_mail_user, 1, wxEXPAND | wxALL); + + add_label_to_sizer (table, panel, _("Mail password"), true); + _mail_password = new wxTextCtrl (panel, wxID_ANY); + table->Add (_mail_password, 1, wxEXPAND | wxALL); + + wxStaticText* plain = add_label_to_sizer (table, panel, _("(password will be stored on disk in plaintext)"), false); + plain->SetFont (font); + table->AddSpacer (0); + + add_label_to_sizer (table, panel, _("From address for KDM emails"), true); + _kdm_from = new wxTextCtrl (panel, wxID_ANY); + table->Add (_kdm_from, 1, wxEXPAND | wxALL); + + _check_for_updates = new wxCheckBox (panel, wxID_ANY, _("Check for updates on startup")); + table->Add (_check_for_updates, 1, wxEXPAND | wxALL); + table->AddSpacer (0); + + _check_for_test_updates = new wxCheckBox (panel, wxID_ANY, _("Check for testing updates as well as stable ones")); + table->Add (_check_for_test_updates, 1, wxEXPAND | wxALL); + table->AddSpacer (0); + + Config* config = Config::instance (); + + _set_language->SetValue (config->language ()); + + if (config->language().get_value_or ("") == "fr") { + _language->SetSelection (1); + } else if (config->language().get_value_or ("") == "it") { + _language->SetSelection (2); + } else if (config->language().get_value_or ("") == "es") { + _language->SetSelection (3); + } else if (config->language().get_value_or ("") == "sv") { + _language->SetSelection (4); + } else if (config->language().get_value_or ("") == "de") { + _language->SetSelection (5); + } else { + _language->SetSelection (0); + } + + setup_language_sensitivity (); + + _set_language->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&GeneralPage::set_language_changed, this)); + _language->Bind (wxEVT_COMMAND_CHOICE_SELECTED, boost::bind (&GeneralPage::language_changed, this)); + + _num_local_encoding_threads->SetRange (1, 128); + _num_local_encoding_threads->SetValue (config->num_local_encoding_threads ()); + _num_local_encoding_threads->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&GeneralPage::num_local_encoding_threads_changed, this)); + + _mail_server->SetValue (std_to_wx (config->mail_server ())); + _mail_server->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&GeneralPage::mail_server_changed, this)); + _mail_user->SetValue (std_to_wx (config->mail_user ())); + _mail_user->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&GeneralPage::mail_user_changed, this)); + _mail_password->SetValue (std_to_wx (config->mail_password ())); + _mail_password->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&GeneralPage::mail_password_changed, this)); + _kdm_from->SetValue (std_to_wx (config->kdm_from ())); + _kdm_from->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&GeneralPage::kdm_from_changed, this)); + _check_for_updates->SetValue (config->check_for_updates ()); + _check_for_updates->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&GeneralPage::check_for_updates_changed, this)); + _check_for_test_updates->SetValue (config->check_for_test_updates ()); + _check_for_test_updates->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&GeneralPage::check_for_test_updates_changed, this)); + + return panel; + } - _check_for_test_updates = new wxCheckBox (_misc_panel, wxID_ANY, _("Check for testing updates as well as stable ones")); - table->Add (_check_for_test_updates, 1, wxEXPAND | wxALL); - table->AddSpacer (0); - - Config* config = Config::instance (); +private: + void setup_language_sensitivity () + { + _language->Enable (_set_language->GetValue ()); + } - _set_language->SetValue (config->language ()); + void set_language_changed () + { + setup_language_sensitivity (); + if (_set_language->GetValue ()) { + language_changed (); + } else { + Config::instance()->unset_language (); + } + } - if (config->language().get_value_or ("") == "fr") { - _language->SetSelection (1); - } else if (config->language().get_value_or ("") == "it") { - _language->SetSelection (2); - } else if (config->language().get_value_or ("") == "es") { - _language->SetSelection (3); - } else if (config->language().get_value_or ("") == "sv") { - _language->SetSelection (4); - } else if (config->language().get_value_or ("") == "de") { - _language->SetSelection (5); - } else { - _language->SetSelection (0); - } - - setup_language_sensitivity (); - - _set_language->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&ConfigDialog::set_language_changed, this)); - _language->Bind (wxEVT_COMMAND_CHOICE_SELECTED, boost::bind (&ConfigDialog::language_changed, this)); - - _num_local_encoding_threads->SetRange (1, 128); - _num_local_encoding_threads->SetValue (config->num_local_encoding_threads ()); - _num_local_encoding_threads->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&ConfigDialog::num_local_encoding_threads_changed, this)); - - _mail_server->SetValue (std_to_wx (config->mail_server ())); - _mail_server->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&ConfigDialog::mail_server_changed, this)); - _mail_user->SetValue (std_to_wx (config->mail_user ())); - _mail_user->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&ConfigDialog::mail_user_changed, this)); - _mail_password->SetValue (std_to_wx (config->mail_password ())); - _mail_password->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&ConfigDialog::mail_password_changed, this)); - _kdm_from->SetValue (std_to_wx (config->kdm_from ())); - _kdm_from->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&ConfigDialog::kdm_from_changed, this)); - _check_for_updates->SetValue (config->check_for_updates ()); - _check_for_updates->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&ConfigDialog::check_for_updates_changed, this)); - _check_for_test_updates->SetValue (config->check_for_test_updates ()); - _check_for_test_updates->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&ConfigDialog::check_for_test_updates_changed, this)); -} + void language_changed () + { + switch (_language->GetSelection ()) { + case 0: + Config::instance()->set_language ("en"); + break; + case 1: + Config::instance()->set_language ("fr"); + break; + case 2: + Config::instance()->set_language ("it"); + break; + case 3: + Config::instance()->set_language ("es"); + break; + case 4: + Config::instance()->set_language ("sv"); + break; + case 5: + Config::instance()->set_language ("de"); + break; + } + } + + void mail_server_changed () + { + Config::instance()->set_mail_server (wx_to_std (_mail_server->GetValue ())); + } + + void mail_user_changed () + { + Config::instance()->set_mail_user (wx_to_std (_mail_user->GetValue ())); + } + + void mail_password_changed () + { + Config::instance()->set_mail_password (wx_to_std (_mail_password->GetValue ())); + } + + void kdm_from_changed () + { + Config::instance()->set_kdm_from (wx_to_std (_kdm_from->GetValue ())); + } -void -ConfigDialog::make_defaults_panel () -{ - _defaults_panel = new wxPanel (_notebook); - wxBoxSizer* s = new wxBoxSizer (wxVERTICAL); - _defaults_panel->SetSizer (s); + void check_for_updates_changed () + { + Config::instance()->set_check_for_updates (_check_for_updates->GetValue ()); + } + + void check_for_test_updates_changed () + { + Config::instance()->set_check_for_test_updates (_check_for_test_updates->GetValue ()); + } - wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP); - table->AddGrowableCol (1, 1); - s->Add (table, 1, wxALL | wxEXPAND, 8); + void num_local_encoding_threads_changed () + { + Config::instance()->set_num_local_encoding_threads (_num_local_encoding_threads->GetValue ()); + } + + wxCheckBox* _set_language; + wxChoice* _language; + wxSpinCtrl* _num_local_encoding_threads; + wxTextCtrl* _mail_server; + wxTextCtrl* _mail_user; + wxTextCtrl* _mail_password; + wxTextCtrl* _kdm_from; + wxCheckBox* _check_for_updates; + wxCheckBox* _check_for_test_updates; +}; + +class DefaultsPage : public wxPreferencesPage, public Page +{ +public: + DefaultsPage (wxSize panel_size, int border) + : Page (panel_size, border) + {} + + wxString GetName () const + { + return _("Defaults"); + } +#ifdef DCPOMATIC_OSX + wxBitmap GetLargeIcon () const { - add_label_to_sizer (table, _defaults_panel, _("Default duration of still images"), true); - wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); - _default_still_length = new wxSpinCtrl (_defaults_panel); - s->Add (_default_still_length); - add_label_to_sizer (s, _defaults_panel, _("s"), false); - table->Add (s, 1); + return wxBitmap ("defaults", wxBITMAP_TYPE_PNG_RESOURCE); } +#endif - add_label_to_sizer (table, _defaults_panel, _("Default directory for new films"), true); + wxWindow* CreateWindow (wxWindow* parent) + { + wxPanel* panel = new wxPanel (parent); + wxBoxSizer* s = new wxBoxSizer (wxVERTICAL); + panel->SetSizer (s); + + wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP); + table->AddGrowableCol (1, 1); + s->Add (table, 1, wxALL | wxEXPAND, _border); + + { + add_label_to_sizer (table, panel, _("Default duration of still images"), true); + wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); + _still_length = new wxSpinCtrl (panel); + s->Add (_still_length); + add_label_to_sizer (s, panel, _("s"), false); + table->Add (s, 1); + } + + add_label_to_sizer (table, panel, _("Default directory for new films"), true); #ifdef DCPOMATIC_USE_OWN_DIR_PICKER - _default_directory = new DirPickerCtrl (_defaults_panel); + _directory = new DirPickerCtrl (panel); #else - _default_directory = new wxDirPickerCtrl (_defaults_panel, wxDD_DIR_MUST_EXIST); + _directory = new wxDirPickerCtrl (panel, wxDD_DIR_MUST_EXIST); #endif - table->Add (_default_directory, 1, wxEXPAND); - - add_label_to_sizer (table, _defaults_panel, _("Default DCI name details"), true); - _default_dci_metadata_button = new wxButton (_defaults_panel, wxID_ANY, _("Edit...")); - table->Add (_default_dci_metadata_button); + table->Add (_directory, 1, wxEXPAND); + + add_label_to_sizer (table, panel, _("Default DCI name details"), true); + _dci_metadata_button = new wxButton (panel, wxID_ANY, _("Edit...")); + table->Add (_dci_metadata_button); + + add_label_to_sizer (table, panel, _("Default container"), true); + _container = new wxChoice (panel, wxID_ANY); + table->Add (_container); + + add_label_to_sizer (table, panel, _("Default content type"), true); + _dcp_content_type = new wxChoice (panel, wxID_ANY); + table->Add (_dcp_content_type); + + { + add_label_to_sizer (table, panel, _("Default JPEG2000 bandwidth"), true); + wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); + _j2k_bandwidth = new wxSpinCtrl (panel); + s->Add (_j2k_bandwidth); + add_label_to_sizer (s, panel, _("Mbit/s"), false); + table->Add (s, 1); + } + + { + add_label_to_sizer (table, panel, _("Default audio delay"), true); + wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); + _audio_delay = new wxSpinCtrl (panel); + s->Add (_audio_delay); + add_label_to_sizer (s, panel, _("ms"), false); + table->Add (s, 1); + } - add_label_to_sizer (table, _defaults_panel, _("Default container"), true); - _default_container = new wxChoice (_defaults_panel, wxID_ANY); - table->Add (_default_container); + add_label_to_sizer (table, panel, _("Default issuer"), true); + _issuer = new wxTextCtrl (panel, wxID_ANY); + table->Add (_issuer, 1, wxEXPAND); + + add_label_to_sizer (table, panel, _("Default creator"), true); + _creator = new wxTextCtrl (panel, wxID_ANY); + table->Add (_creator, 1, wxEXPAND); + + Config* config = Config::instance (); + + _still_length->SetRange (1, 3600); + _still_length->SetValue (config->default_still_length ()); + _still_length->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&DefaultsPage::still_length_changed, this)); + + _directory->SetPath (std_to_wx (config->default_directory_or (wx_to_std (wxStandardPaths::Get().GetDocumentsDir())).string ())); + _directory->Bind (wxEVT_COMMAND_DIRPICKER_CHANGED, boost::bind (&DefaultsPage::directory_changed, this)); + + _dci_metadata_button->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&DefaultsPage::edit_dci_metadata_clicked, this, parent)); + + vector<Ratio const *> ratio = Ratio::all (); + int n = 0; + for (vector<Ratio const *>::iterator i = ratio.begin(); i != ratio.end(); ++i) { + _container->Append (std_to_wx ((*i)->nickname ())); + if (*i == config->default_container ()) { + _container->SetSelection (n); + } + ++n; + } + + _container->Bind (wxEVT_COMMAND_CHOICE_SELECTED, boost::bind (&DefaultsPage::container_changed, this)); + + vector<DCPContentType const *> const ct = DCPContentType::all (); + n = 0; + for (vector<DCPContentType const *>::const_iterator i = ct.begin(); i != ct.end(); ++i) { + _dcp_content_type->Append (std_to_wx ((*i)->pretty_name ())); + if (*i == config->default_dcp_content_type ()) { + _dcp_content_type->SetSelection (n); + } + ++n; + } + + _dcp_content_type->Bind (wxEVT_COMMAND_CHOICE_SELECTED, boost::bind (&DefaultsPage::dcp_content_type_changed, this)); + + _j2k_bandwidth->SetRange (50, 250); + _j2k_bandwidth->SetValue (config->default_j2k_bandwidth() / 1000000); + _j2k_bandwidth->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&DefaultsPage::j2k_bandwidth_changed, this)); + + _audio_delay->SetRange (-1000, 1000); + _audio_delay->SetValue (config->default_audio_delay ()); + _audio_delay->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&DefaultsPage::audio_delay_changed, this)); + + _issuer->SetValue (std_to_wx (config->dcp_metadata().issuer)); + _issuer->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&DefaultsPage::issuer_changed, this)); + _creator->SetValue (std_to_wx (config->dcp_metadata().creator)); + _creator->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&DefaultsPage::creator_changed, this)); + + return panel; + } - add_label_to_sizer (table, _defaults_panel, _("Default content type"), true); - _default_dcp_content_type = new wxChoice (_defaults_panel, wxID_ANY); - table->Add (_default_dcp_content_type); +private: + void j2k_bandwidth_changed () + { + Config::instance()->set_default_j2k_bandwidth (_j2k_bandwidth->GetValue() * 1000000); + } + + void audio_delay_changed () + { + Config::instance()->set_default_audio_delay (_audio_delay->GetValue()); + } + void directory_changed () { - add_label_to_sizer (table, _defaults_panel, _("Default JPEG2000 bandwidth"), true); - wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); - _default_j2k_bandwidth = new wxSpinCtrl (_defaults_panel); - s->Add (_default_j2k_bandwidth); - add_label_to_sizer (s, _defaults_panel, _("Mbit/s"), false); - table->Add (s, 1); + Config::instance()->set_default_directory (wx_to_std (_directory->GetPath ())); } + void edit_dci_metadata_clicked (wxWindow* parent) { - add_label_to_sizer (table, _defaults_panel, _("Default audio delay"), true); - wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); - _default_audio_delay = new wxSpinCtrl (_defaults_panel); - s->Add (_default_audio_delay); - add_label_to_sizer (s, _defaults_panel, _("ms"), false); - table->Add (s, 1); + DCIMetadataDialog* d = new DCIMetadataDialog (parent, Config::instance()->default_dci_metadata ()); + d->ShowModal (); + Config::instance()->set_default_dci_metadata (d->dci_metadata ()); + d->Destroy (); } - Config* config = Config::instance (); + void still_length_changed () + { + Config::instance()->set_default_still_length (_still_length->GetValue ()); + } - _default_still_length->SetRange (1, 3600); - _default_still_length->SetValue (config->default_still_length ()); - _default_still_length->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&ConfigDialog::default_still_length_changed, this)); - - _default_directory->SetPath (std_to_wx (config->default_directory_or (wx_to_std (wxStandardPaths::Get().GetDocumentsDir())).string ())); - _default_directory->Bind (wxEVT_COMMAND_DIRPICKER_CHANGED, boost::bind (&ConfigDialog::default_directory_changed, this)); - - _default_dci_metadata_button->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&ConfigDialog::edit_default_dci_metadata_clicked, this)); - - vector<Ratio const *> ratio = Ratio::all (); - int n = 0; - for (vector<Ratio const *>::iterator i = ratio.begin(); i != ratio.end(); ++i) { - _default_container->Append (std_to_wx ((*i)->nickname ())); - if (*i == config->default_container ()) { - _default_container->SetSelection (n); - } - ++n; + void container_changed () + { + vector<Ratio const *> ratio = Ratio::all (); + Config::instance()->set_default_container (ratio[_container->GetSelection()]); } - - _default_container->Bind (wxEVT_COMMAND_CHOICE_SELECTED, boost::bind (&ConfigDialog::default_container_changed, this)); - vector<DCPContentType const *> const ct = DCPContentType::all (); - n = 0; - for (vector<DCPContentType const *>::const_iterator i = ct.begin(); i != ct.end(); ++i) { - _default_dcp_content_type->Append (std_to_wx ((*i)->pretty_name ())); - if (*i == config->default_dcp_content_type ()) { - _default_dcp_content_type->SetSelection (n); - } - ++n; + void dcp_content_type_changed () + { + vector<DCPContentType const *> ct = DCPContentType::all (); + Config::instance()->set_default_dcp_content_type (ct[_dcp_content_type->GetSelection()]); } - _default_dcp_content_type->Bind (wxEVT_COMMAND_CHOICE_SELECTED, boost::bind (&ConfigDialog::default_dcp_content_type_changed, this)); - - _default_j2k_bandwidth->SetRange (50, 250); - _default_j2k_bandwidth->SetValue (config->default_j2k_bandwidth() / 1000000); - _default_j2k_bandwidth->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&ConfigDialog::default_j2k_bandwidth_changed, this)); - - _default_audio_delay->SetRange (-1000, 1000); - _default_audio_delay->SetValue (config->default_audio_delay ()); - _default_audio_delay->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&ConfigDialog::default_audio_delay_changed, this)); -} - -void -ConfigDialog::make_tms_panel () -{ - _tms_panel = new wxPanel (_notebook); - wxBoxSizer* s = new wxBoxSizer (wxVERTICAL); - _tms_panel->SetSizer (s); - - wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP); - table->AddGrowableCol (1, 1); - s->Add (table, 1, wxALL | wxEXPAND, 8); - - add_label_to_sizer (table, _tms_panel, _("IP address"), true); - _tms_ip = new wxTextCtrl (_tms_panel, wxID_ANY); - table->Add (_tms_ip, 1, wxEXPAND); - - add_label_to_sizer (table, _tms_panel, _("Target path"), true); - _tms_path = new wxTextCtrl (_tms_panel, wxID_ANY); - table->Add (_tms_path, 1, wxEXPAND); - - add_label_to_sizer (table, _tms_panel, _("User name"), true); - _tms_user = new wxTextCtrl (_tms_panel, wxID_ANY); - table->Add (_tms_user, 1, wxEXPAND); - - add_label_to_sizer (table, _tms_panel, _("Password"), true); - _tms_password = new wxTextCtrl (_tms_panel, wxID_ANY); - table->Add (_tms_password, 1, wxEXPAND); - - Config* config = Config::instance (); + void issuer_changed () + { + libdcp::XMLMetadata m = Config::instance()->dcp_metadata (); + m.issuer = wx_to_std (_issuer->GetValue ()); + Config::instance()->set_dcp_metadata (m); + } - _tms_ip->SetValue (std_to_wx (config->tms_ip ())); - _tms_ip->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&ConfigDialog::tms_ip_changed, this)); - _tms_path->SetValue (std_to_wx (config->tms_path ())); - _tms_path->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&ConfigDialog::tms_path_changed, this)); - _tms_user->SetValue (std_to_wx (config->tms_user ())); - _tms_user->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&ConfigDialog::tms_user_changed, this)); - _tms_password->SetValue (std_to_wx (config->tms_password ())); - _tms_password->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&ConfigDialog::tms_password_changed, this)); -} - -void -ConfigDialog::make_metadata_panel () -{ - _metadata_panel = new wxPanel (_notebook); - wxBoxSizer* s = new wxBoxSizer (wxVERTICAL); - _metadata_panel->SetSizer (s); - - wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP); - table->AddGrowableCol (1, 1); - s->Add (table, 1, wxALL | wxEXPAND, 8); - - add_label_to_sizer (table, _metadata_panel, _("Issuer"), true); - _issuer = new wxTextCtrl (_metadata_panel, wxID_ANY); - table->Add (_issuer, 1, wxEXPAND); - - add_label_to_sizer (table, _metadata_panel, _("Creator"), true); - _creator = new wxTextCtrl (_metadata_panel, wxID_ANY); - table->Add (_creator, 1, wxEXPAND); - - Config* config = Config::instance (); - - _issuer->SetValue (std_to_wx (config->dcp_metadata().issuer)); - _issuer->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&ConfigDialog::issuer_changed, this)); - _creator->SetValue (std_to_wx (config->dcp_metadata().creator)); - _creator->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&ConfigDialog::creator_changed, this)); -} - -static string -server_column (string s) -{ - return s; -} - -void -ConfigDialog::make_servers_panel () -{ - _servers_panel = new wxPanel (_notebook); - wxBoxSizer* s = new wxBoxSizer (wxVERTICAL); - _servers_panel->SetSizer (s); - - _use_any_servers = new wxCheckBox (_servers_panel, wxID_ANY, _("Use all servers")); - s->Add (_use_any_servers, 0, wxALL, DCPOMATIC_SIZER_X_GAP); + void creator_changed () + { + libdcp::XMLMetadata m = Config::instance()->dcp_metadata (); + m.creator = wx_to_std (_creator->GetValue ()); + Config::instance()->set_dcp_metadata (m); + } - vector<string> columns; - columns.push_back (wx_to_std (_("IP address / host name"))); - _servers_list = new EditableList<std::string, ServerDialog> ( - _servers_panel, - columns, - boost::bind (&Config::servers, Config::instance()), - boost::bind (&Config::set_servers, Config::instance(), _1), - boost::bind (&server_column, _1) - ); - - s->Add (_servers_list, 1, wxEXPAND | wxALL, DCPOMATIC_SIZER_X_GAP); - - _use_any_servers->SetValue (Config::instance()->use_any_servers ()); - _use_any_servers->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&ConfigDialog::use_any_servers_changed, this)); -} - -void -ConfigDialog::use_any_servers_changed () -{ - Config::instance()->set_use_any_servers (_use_any_servers->GetValue ()); -} - -void -ConfigDialog::language_changed () -{ - switch (_language->GetSelection ()) { - case 0: - Config::instance()->set_language ("en"); - break; - case 1: - Config::instance()->set_language ("fr"); - break; - case 2: - Config::instance()->set_language ("it"); - break; - case 3: - Config::instance()->set_language ("es"); - break; - case 4: - Config::instance()->set_language ("sv"); - break; - case 5: - Config::instance()->set_language ("de"); - break; + wxSpinCtrl* _j2k_bandwidth; + wxSpinCtrl* _audio_delay; + wxButton* _dci_metadata_button; + wxSpinCtrl* _still_length; +#ifdef DCPOMATIC_USE_OWN_DIR_PICKER + DirPickerCtrl* _directory; +#else + wxDirPickerCtrl* _directory; +#endif + wxChoice* _container; + wxChoice* _dcp_content_type; + wxTextCtrl* _issuer; + wxTextCtrl* _creator; +}; + +class EncodingServersPage : public wxPreferencesPage, public Page +{ +public: + EncodingServersPage (wxSize panel_size, int border) + : Page (panel_size, border) + {} + + wxString GetName () const + { + return _("Servers"); } -} - -void -ConfigDialog::tms_ip_changed () -{ - Config::instance()->set_tms_ip (wx_to_std (_tms_ip->GetValue ())); -} - -void -ConfigDialog::tms_path_changed () -{ - Config::instance()->set_tms_path (wx_to_std (_tms_path->GetValue ())); -} - -void -ConfigDialog::tms_user_changed () -{ - Config::instance()->set_tms_user (wx_to_std (_tms_user->GetValue ())); -} -void -ConfigDialog::tms_password_changed () -{ - Config::instance()->set_tms_password (wx_to_std (_tms_password->GetValue ())); -} +#ifdef DCPOMATIC_OSX + wxBitmap GetLargeIcon () const + { + return wxBitmap ("servers", wxBITMAP_TYPE_PNG_RESOURCE); + } +#endif -void -ConfigDialog::num_local_encoding_threads_changed () -{ - Config::instance()->set_num_local_encoding_threads (_num_local_encoding_threads->GetValue ()); -} + wxWindow* CreateWindow (wxWindow* parent) + { + wxPanel* panel = new wxPanel (parent, wxID_ANY, wxDefaultPosition, _panel_size); + wxBoxSizer* s = new wxBoxSizer (wxVERTICAL); + panel->SetSizer (s); + + _use_any_servers = new wxCheckBox (panel, wxID_ANY, _("Use all servers")); + s->Add (_use_any_servers, 0, wxALL, _border); + + vector<string> columns; + columns.push_back (wx_to_std (_("IP address / host name"))); + _servers_list = new EditableList<string, ServerDialog> ( + panel, + columns, + boost::bind (&Config::servers, Config::instance()), + boost::bind (&Config::set_servers, Config::instance(), _1), + boost::bind (&EncodingServersPage::server_column, this, _1) + ); + + s->Add (_servers_list, 1, wxEXPAND | wxALL, _border); + + _use_any_servers->SetValue (Config::instance()->use_any_servers ()); + _use_any_servers->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&EncodingServersPage::use_any_servers_changed, this)); + + return panel; + } -void -ConfigDialog::default_directory_changed () -{ - Config::instance()->set_default_directory (wx_to_std (_default_directory->GetPath ())); -} +private: -void -ConfigDialog::edit_default_dci_metadata_clicked () -{ - DCIMetadataDialog* d = new DCIMetadataDialog (this, Config::instance()->default_dci_metadata ()); - d->ShowModal (); - Config::instance()->set_default_dci_metadata (d->dci_metadata ()); - d->Destroy (); -} - -void -ConfigDialog::set_language_changed () -{ - setup_language_sensitivity (); - if (_set_language->GetValue ()) { - language_changed (); - } else { - Config::instance()->unset_language (); + void use_any_servers_changed () + { + Config::instance()->set_use_any_servers (_use_any_servers->GetValue ()); } -} - -void -ConfigDialog::setup_language_sensitivity () -{ - _language->Enable (_set_language->GetValue ()); -} -void -ConfigDialog::default_still_length_changed () -{ - Config::instance()->set_default_still_length (_default_still_length->GetValue ()); -} + string server_column (string s) + { + return s; + } -void -ConfigDialog::default_container_changed () -{ - vector<Ratio const *> ratio = Ratio::all (); - Config::instance()->set_default_container (ratio[_default_container->GetSelection()]); -} + wxCheckBox* _use_any_servers; + EditableList<string, ServerDialog>* _servers_list; +}; -void -ConfigDialog::default_dcp_content_type_changed () +class ColourConversionsPage : public wxPreferencesPage, public Page { - vector<DCPContentType const *> ct = DCPContentType::all (); - Config::instance()->set_default_dcp_content_type (ct[_default_dcp_content_type->GetSelection()]); -} +public: + ColourConversionsPage (wxSize panel_size, int border) + : Page (panel_size, border) + {} + + wxString GetName () const + { + return _("Colour Conversions"); + } -void -ConfigDialog::issuer_changed () -{ - dcp::XMLMetadata m = Config::instance()->dcp_metadata (); - m.issuer = wx_to_std (_issuer->GetValue ()); - Config::instance()->set_dcp_metadata (m); -} +#ifdef DCPOMATIC_OSX + wxBitmap GetLargeIcon () const + { + return wxBitmap ("colour_conversions", wxBITMAP_TYPE_PNG_RESOURCE); + } +#endif + wxWindow* CreateWindow (wxWindow* parent) + { + wxPanel* panel = new wxPanel (parent, wxID_ANY, wxDefaultPosition, _panel_size); + wxBoxSizer* s = new wxBoxSizer (wxVERTICAL); + panel->SetSizer (s); + + vector<string> columns; + columns.push_back (wx_to_std (_("Name"))); + wxPanel* list = new EditableList<PresetColourConversion, PresetColourConversionDialog> ( + panel, + columns, + boost::bind (&Config::colour_conversions, Config::instance()), + boost::bind (&Config::set_colour_conversions, Config::instance(), _1), + boost::bind (&ColourConversionsPage::colour_conversion_column, this, _1), + 300 + ); + + s->Add (list, 1, wxEXPAND | wxALL, _border); + return panel; + } -void -ConfigDialog::creator_changed () -{ - dcp::XMLMetadata m = Config::instance()->dcp_metadata (); - m.creator = wx_to_std (_creator->GetValue ()); - Config::instance()->set_dcp_metadata (m); -} +private: + string colour_conversion_column (PresetColourConversion c) + { + return c.name; + } +}; -void -ConfigDialog::default_j2k_bandwidth_changed () +class TMSPage : public wxPreferencesPage, public Page { - Config::instance()->set_default_j2k_bandwidth (_default_j2k_bandwidth->GetValue() * 1000000); -} +public: + TMSPage (wxSize panel_size, int border) + : Page (panel_size, border) + {} -void -ConfigDialog::default_audio_delay_changed () -{ - Config::instance()->set_default_audio_delay (_default_audio_delay->GetValue()); -} + wxString GetName () const + { + return _("TMS"); + } -static std::string -colour_conversion_column (PresetColourConversion c) -{ - return c.name; -} +#ifdef DCPOMATIC_OSX + wxBitmap GetLargeIcon () const + { + return wxBitmap ("tms", wxBITMAP_TYPE_PNG_RESOURCE); + } +#endif -void -ConfigDialog::make_colour_conversions_panel () -{ - vector<string> columns; - columns.push_back (wx_to_std (_("Name"))); - _colour_conversions_panel = new EditableList<PresetColourConversion, PresetColourConversionDialog> ( - _notebook, - columns, - boost::bind (&Config::colour_conversions, Config::instance()), - boost::bind (&Config::set_colour_conversions, Config::instance(), _1), - boost::bind (&colour_conversion_column, _1), - 300 - ); -} + wxWindow* CreateWindow (wxWindow* parent) + { + wxPanel* panel = new wxPanel (parent, wxID_ANY, wxDefaultPosition, _panel_size); + wxBoxSizer* s = new wxBoxSizer (wxVERTICAL); + panel->SetSizer (s); + + wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP); + table->AddGrowableCol (1, 1); + s->Add (table, 1, wxALL | wxEXPAND, _border); + + add_label_to_sizer (table, panel, _("IP address"), true); + _tms_ip = new wxTextCtrl (panel, wxID_ANY); + table->Add (_tms_ip, 1, wxEXPAND); + + add_label_to_sizer (table, panel, _("Target path"), true); + _tms_path = new wxTextCtrl (panel, wxID_ANY); + table->Add (_tms_path, 1, wxEXPAND); + + add_label_to_sizer (table, panel, _("User name"), true); + _tms_user = new wxTextCtrl (panel, wxID_ANY); + table->Add (_tms_user, 1, wxEXPAND); + + add_label_to_sizer (table, panel, _("Password"), true); + _tms_password = new wxTextCtrl (panel, wxID_ANY); + table->Add (_tms_password, 1, wxEXPAND); + + Config* config = Config::instance (); + + _tms_ip->SetValue (std_to_wx (config->tms_ip ())); + _tms_ip->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&TMSPage::tms_ip_changed, this)); + _tms_path->SetValue (std_to_wx (config->tms_path ())); + _tms_path->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&TMSPage::tms_path_changed, this)); + _tms_user->SetValue (std_to_wx (config->tms_user ())); + _tms_user->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&TMSPage::tms_user_changed, this)); + _tms_password->SetValue (std_to_wx (config->tms_password ())); + _tms_password->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&TMSPage::tms_password_changed, this)); + + return panel; + } -void -ConfigDialog::mail_server_changed () -{ - Config::instance()->set_mail_server (wx_to_std (_mail_server->GetValue ())); -} +private: + void tms_ip_changed () + { + Config::instance()->set_tms_ip (wx_to_std (_tms_ip->GetValue ())); + } + + void tms_path_changed () + { + Config::instance()->set_tms_path (wx_to_std (_tms_path->GetValue ())); + } + + void tms_user_changed () + { + Config::instance()->set_tms_user (wx_to_std (_tms_user->GetValue ())); + } + + void tms_password_changed () + { + Config::instance()->set_tms_password (wx_to_std (_tms_password->GetValue ())); + } -void -ConfigDialog::mail_user_changed () -{ - Config::instance()->set_mail_user (wx_to_std (_mail_user->GetValue ())); -} + wxTextCtrl* _tms_ip; + wxTextCtrl* _tms_path; + wxTextCtrl* _tms_user; + wxTextCtrl* _tms_password; +}; -void -ConfigDialog::mail_password_changed () +class KDMEmailPage : public wxPreferencesPage, public Page { - Config::instance()->set_mail_password (wx_to_std (_mail_password->GetValue ())); -} +public: -void -ConfigDialog::kdm_from_changed () -{ - Config::instance()->set_kdm_from (wx_to_std (_kdm_from->GetValue ())); -} + KDMEmailPage (wxSize panel_size, int border) + : Page (panel_size, border) + {} + + wxString GetName () const + { + return _("KDM Email"); + } -void -ConfigDialog::make_kdm_email_panel () -{ - _kdm_email_panel = new wxPanel (_notebook); - wxBoxSizer* s = new wxBoxSizer (wxVERTICAL); - _kdm_email_panel->SetSizer (s); +#ifdef DCPOMATIC_OSX + wxBitmap GetLargeIcon () const + { + return wxBitmap ("kdm_email", wxBITMAP_TYPE_PNG_RESOURCE); + } +#endif - _kdm_email = new wxTextCtrl (_kdm_email_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE); - s->Add (_kdm_email, 1, wxEXPAND | wxALL, 12); + wxWindow* CreateWindow (wxWindow* parent) + { + /* We have to force both width and height of this one */ +#ifdef DCPOMATIC_OSX + wxPanel* panel = new wxPanel (parent, wxID_ANY, wxDefaultPosition, wxSize (480, 128)); +#else + wxPanel* panel = new wxPanel (parent); +#endif + wxBoxSizer* s = new wxBoxSizer (wxVERTICAL); + panel->SetSizer (s); + + _kdm_email = new wxTextCtrl (panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize (480, 128), wxTE_MULTILINE); + s->Add (_kdm_email, 1, wxEXPAND | wxALL, _border); + + _kdm_email->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&KDMEmailPage::kdm_email_changed, this)); + _kdm_email->SetValue (wx_to_std (Config::instance()->kdm_email ())); + + return panel; + } - _kdm_email->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&ConfigDialog::kdm_email_changed, this)); - _kdm_email->SetValue (wx_to_std (Config::instance()->kdm_email ())); -} +private: + void kdm_email_changed () + { + Config::instance()->set_kdm_email (wx_to_std (_kdm_email->GetValue ())); + } -void -ConfigDialog::kdm_email_changed () -{ - Config::instance()->set_kdm_email (wx_to_std (_kdm_email->GetValue ())); -} + wxTextCtrl* _kdm_email; +}; -void -ConfigDialog::check_for_updates_changed () +wxPreferencesEditor* +create_config_dialog () { - Config::instance()->set_check_for_updates (_check_for_updates->GetValue ()); -} + wxPreferencesEditor* e = new wxPreferencesEditor (); -void -ConfigDialog::check_for_test_updates_changed () -{ - Config::instance()->set_check_for_test_updates (_check_for_test_updates->GetValue ()); +#ifdef DCPOMATIC_OSX + /* Width that we force some of the config panels to be on OSX so that + the containing window doesn't shrink too much when we select those panels. + This is obviously an unpleasant hack. + */ + wxSize ps = wxSize (480, -1); + int const border = 16; +#else + wxSize ps = wxDefaultSize; + int const border = 8; +#endif + + e->AddPage (new GeneralPage (ps, border)); + e->AddPage (new DefaultsPage (ps, border)); + e->AddPage (new EncodingServersPage (ps, border)); + e->AddPage (new ColourConversionsPage (ps, border)); + e->AddPage (new TMSPage (ps, border)); + e->AddPage (new KDMEmailPage (ps, border)); + return e; } diff --git a/src/wx/config_dialog.h b/src/wx/config_dialog.h index 8a17de58d..183a23440 100644 --- a/src/wx/config_dialog.h +++ b/src/wx/config_dialog.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2012 Carl Hetherington <cth@carlh.net> + Copyright (C) 2012-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 @@ -18,103 +18,9 @@ */ /** @file src/config_dialog.h - * @brief A dialogue to edit DCP-o-matic configuration. + * @brief A dialog to edit DCP-o-matic configuration. */ -#include <wx/wx.h> -#include <wx/spinctrl.h> -#include <wx/listctrl.h> -#include <wx/filepicker.h> -#include "wx_util.h" -#include "editable_list.h" - -class DirPickerCtrl; -class wxNotebook; -class PresetColourConversion; -class PresetColourConversionDialog; -class ServerDialog; - -/** @class ConfigDialog - * @brief A dialogue to edit DCP-o-matic configuration. - */ -class ConfigDialog : public wxDialog -{ -public: - ConfigDialog (wxWindow *); - -private: - void set_language_changed (); - void language_changed (); - void tms_ip_changed (); - void tms_path_changed (); - void tms_user_changed (); - void tms_password_changed (); - void num_local_encoding_threads_changed (); - void default_still_length_changed (); - void default_directory_changed (); - void edit_default_dci_metadata_clicked (); - void default_container_changed (); - void default_dcp_content_type_changed (); - void issuer_changed (); - void creator_changed (); - void default_j2k_bandwidth_changed (); - void default_audio_delay_changed (); - void mail_server_changed (); - void mail_user_changed (); - void mail_password_changed (); - void kdm_from_changed (); - void kdm_email_changed (); - void use_any_servers_changed (); - - void setup_language_sensitivity (); - - void make_misc_panel (); - void make_defaults_panel (); - void make_servers_panel (); - void make_tms_panel (); - void make_metadata_panel (); - void make_colour_conversions_panel (); - void make_kdm_email_panel (); - - void check_for_updates_changed (); - void check_for_test_updates_changed (); - - wxNotebook* _notebook; - wxPanel* _misc_panel; - wxPanel* _defaults_panel; - wxPanel* _servers_panel; - wxPanel* _tms_panel; - EditableList<PresetColourConversion, PresetColourConversionDialog>* _colour_conversions_panel; - wxPanel* _metadata_panel; - wxCheckBox* _set_language; - wxChoice* _language; - wxChoice* _default_container; - wxChoice* _default_dcp_content_type; - wxTextCtrl* _tms_ip; - wxTextCtrl* _tms_path; - wxTextCtrl* _tms_user; - wxTextCtrl* _tms_password; - wxSpinCtrl* _num_local_encoding_threads; - wxTextCtrl* _mail_server; - wxTextCtrl* _mail_user; - wxTextCtrl* _mail_password; - wxTextCtrl* _kdm_from; - wxSpinCtrl* _default_still_length; -#ifdef DCPOMATIC_USE_OWN_DIR_PICKER - DirPickerCtrl* _default_directory; -#else - wxDirPickerCtrl* _default_directory; -#endif - wxButton* _default_dci_metadata_button; - wxTextCtrl* _issuer; - wxTextCtrl* _creator; - wxSpinCtrl* _default_j2k_bandwidth; - wxSpinCtrl* _default_audio_delay; - wxPanel* _kdm_email_panel; - wxTextCtrl* _kdm_email; - wxCheckBox* _use_any_servers; - wxCheckBox* _check_for_updates; - wxCheckBox* _check_for_test_updates; - EditableList<std::string, ServerDialog>* _servers_list; -}; +class wxPreferencesEditor; +wxPreferencesEditor* create_config_dialog (); diff --git a/src/wx/editable_list.h b/src/wx/editable_list.h index 20d180f20..470be2d09 100644 --- a/src/wx/editable_list.h +++ b/src/wx/editable_list.h @@ -18,6 +18,7 @@ */ #include <wx/wx.h> +#include <wx/listctrl.h> template<class T, class S> class EditableList : public wxPanel diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index f426a7c6e..7e1b61811 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2012 Carl Hetherington <cth@carlh.net> + Copyright (C) 2012-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 @@ -429,7 +429,7 @@ FilmViewer::player_changed (bool frequent) if (frequent) { return; } - + calculate_sizes (); fetch_current_frame_again (); } diff --git a/src/wx/kdm_dialog.cc b/src/wx/kdm_dialog.cc index 5410f6cec..1f4d62bde 100644 --- a/src/wx/kdm_dialog.cc +++ b/src/wx/kdm_dialog.cc @@ -83,15 +83,20 @@ KDMDialog::KDMDialog (wxWindow* parent, boost::shared_ptr<const Film> film) wxFlexGridSizer* table = new wxFlexGridSizer (3, 2, 6); add_label_to_sizer (table, this, _("From"), true); - _from_date = new wxDatePickerCtrl (this, wxID_ANY); + wxDateTime from; + from.SetToCurrent (); + _from_date = new wxDatePickerCtrl (this, wxID_ANY, from); table->Add (_from_date, 1, wxEXPAND); - _from_time = new wxTimePickerCtrl (this, wxID_ANY); + _from_time = new wxTimePickerCtrl (this, wxID_ANY, from); table->Add (_from_time, 1, wxEXPAND); - + add_label_to_sizer (table, this, _("Until"), true); - _until_date = new wxDatePickerCtrl (this, wxID_ANY); + wxDateTime to = from; + /* 1 week from now */ + to.Add (wxDateSpan (0, 0, 1, 0)); + _until_date = new wxDatePickerCtrl (this, wxID_ANY, to); table->Add (_until_date, 1, wxEXPAND); - _until_time = new wxTimePickerCtrl (this, wxID_ANY); + _until_time = new wxTimePickerCtrl (this, wxID_ANY, to); table->Add (_until_time, 1, wxEXPAND); vertical->Add (table, 0, wxEXPAND | wxALL, 6); @@ -117,7 +122,7 @@ KDMDialog::KDMDialog (wxWindow* parent, boost::shared_ptr<const Film> film) } } - table = new wxFlexGridSizer (3, 2, 6); + table = new wxFlexGridSizer (2, 2, 6); _write_to = new wxRadioButton (this, wxID_ANY, _("Write to")); table->Add (_write_to, 1, wxEXPAND); @@ -125,13 +130,12 @@ KDMDialog::KDMDialog (wxWindow* parent, boost::shared_ptr<const Film> film) #ifdef DCPOMATIC_USE_OWN_DIR_PICKER _folder = new DirPickerCtrl (this); #else - _folder = new wxDirPickerCtrl (this, wxID_ANY); + _folder = new wxDirPickerCtrl (this, wxID_ANY, wxEmptyString, wxDirSelectorPromptStr, wxDefaultPosition, wxSize (300, -1)); #endif _folder->SetPath (wxStandardPaths::Get().GetDocumentsDir()); table->Add (_folder, 1, wxEXPAND); - table->AddSpacer (0); _email = new wxRadioButton (this, wxID_ANY, _("Send by email")); table->Add (_email, 1, wxEXPAND); @@ -144,6 +148,8 @@ KDMDialog::KDMDialog (wxWindow* parent, boost::shared_ptr<const Film> film) vertical->Add (buttons, wxSizerFlags().Expand().DoubleBorder()); } + _write_to->SetValue (true); + _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)); diff --git a/src/wx/new_film_dialog.cc b/src/wx/new_film_dialog.cc index e0ad2c457..f6d910282 100644 --- a/src/wx/new_film_dialog.cc +++ b/src/wx/new_film_dialog.cc @@ -50,7 +50,7 @@ NewFilmDialog::NewFilmDialog (wxWindow* parent) #ifdef DCPOMATIC_USE_OWN_DIR_PICKER _folder = new DirPickerCtrl (this); #else - _folder = new wxDirPickerCtrl (this, wxID_ANY); + _folder = new wxDirPickerCtrl (this, wxID_ANY, wxEmptyString, wxDirSelectorPromptStr, wxDefaultPosition, wxSize (300, -1)); #endif if (!_directory) { diff --git a/src/wx/video_panel.cc b/src/wx/video_panel.cc index eb45d4bc8..533545f64 100644 --- a/src/wx/video_panel.cc +++ b/src/wx/video_panel.cc @@ -240,12 +240,11 @@ VideoPanel::film_content_changed (int property) _colour_conversion->SetLabel (preset ? std_to_wx (cc[preset.get()].name) : _("Custom")); } else if (property == FFmpegContentProperty::FILTERS) { if (fcs) { - pair<string, string> p = Filter::ffmpeg_strings (fcs->filters ()); - if (p.first.empty () && p.second.empty ()) { + string const p = Filter::ffmpeg_string (fcs->filters ()); + if (p.empty ()) { _filters->SetLabel (_("None")); } else { - string const b = p.first + " " + p.second; - _filters->SetLabel (std_to_wx (b)); + _filters->SetLabel (std_to_wx (p)); } } } @@ -305,8 +304,8 @@ VideoPanel::setup_description () ++lines; } - dcp::Size const container_size = fit_ratio_within (_editor->film()->container()->ratio (), _editor->film()->full_frame ()); - dcp::Size const scaled = vcs->scale().size (vcs, container_size); + dcp::Size const container_size = _editor->film()->frame_size (); + dcp::Size const scaled = vcs->scale().size (vcs, container_size, container_size); if (scaled != vcs->video_size_after_crop ()) { d << wxString::Format ( |
