Various bits mostly related to colour conversions.
authorCarl Hetherington <cth@carlh.net>
Sat, 17 Aug 2013 20:47:08 +0000 (21:47 +0100)
committerCarl Hetherington <cth@carlh.net>
Sat, 17 Aug 2013 20:47:08 +0000 (21:47 +0100)
40 files changed:
platform/windows/installer.nsi.32.in
platform/windows/installer.nsi.64.in
src/lib/colour_conversion.cc
src/lib/colour_conversion.h
src/lib/config.cc
src/lib/config.h
src/lib/dcp_video_frame.cc
src/lib/dcp_video_frame.h
src/lib/encoder.cc
src/lib/encoder.h
src/lib/server.cc
src/lib/server.h
src/lib/video_content.cc
src/lib/video_content.h
src/tools/dcpomatic_cli.cc
src/wx/colour_conversion_dialog.cc [deleted file]
src/wx/colour_conversion_dialog.h [deleted file]
src/wx/colour_conversion_editor.cc [new file with mode: 0644]
src/wx/colour_conversion_editor.h [new file with mode: 0644]
src/wx/config_dialog.cc
src/wx/config_dialog.h
src/wx/content_colour_conversion_dialog.cc [new file with mode: 0644]
src/wx/content_colour_conversion_dialog.h [new file with mode: 0644]
src/wx/editable_list.h
src/wx/film_editor.cc
src/wx/filter_dialog.cc
src/wx/filter_dialog.h
src/wx/filter_editor.cc [new file with mode: 0644]
src/wx/filter_editor.h [new file with mode: 0644]
src/wx/filter_view.cc [deleted file]
src/wx/filter_view.h [deleted file]
src/wx/preset_colour_conversion_dialog.cc [new file with mode: 0644]
src/wx/preset_colour_conversion_dialog.h [new file with mode: 0644]
src/wx/server_dialog.cc
src/wx/server_dialog.h
src/wx/video_panel.cc
src/wx/video_panel.h
src/wx/wscript
test/client_server_test.cc
test/test.cc

index 30cfd806d263f1283503a2f91f2ca5565aa4abcb..938024d575a7cb1157162266a22ba26ed1d19a0e 100644 (file)
@@ -48,9 +48,9 @@ File "%deps%/bin/libglib-2.0-0.dll"
 File "%deps%/bin/libgobject-2.0-0.dll"
 File "%deps%/bin/libiconv-2.dll"
 File "%deps%/bin/libjpeg-8.dll"
-File "%deps%/bin/libMagick++-5.dll"
-File "%deps%/bin/libMagickCore-5.dll"
-File "%deps%/bin/libMagickWand-5.dll"
+File "%deps%/bin/libMagick++-6.Q16-2.dll"
+File "%deps%/bin/libMagickCore-6.Q16-1.dll"
+File "%deps%/bin/libMagickWand-6.Q16-1.dll"
 File "%deps%/bin/libopenjpeg-1.dll"
 File "%deps%/bin/libpng15-15.dll"
 File "%deps%/bin/libsigc-2.0-0.dll"
index 3cc54b4fca4ee2ec649bc000c126c947ac30b3c0..941e1c04719dc22e5586c96142a7bc984e617257 100644 (file)
@@ -58,9 +58,9 @@ File "%deps%/bin/libglib-2.0-0.dll"
 File "%deps%/bin/libgobject-2.0-0.dll"
 File "%deps%/bin/libiconv-2.dll"
 File "%deps%/bin/libjpeg-8.dll"
-File "%deps%/bin/libMagick++-5.dll"
-File "%deps%/bin/libMagickCore-5.dll"
-File "%deps%/bin/libMagickWand-5.dll"
+File "%deps%/bin/libMagick++-6.Q16-2.dll"
+File "%deps%/bin/libMagickCore-6.Q16-1.dll"
+File "%deps%/bin/libMagickWand-6.Q16-1.dll"
 File "%deps%/bin/libopenjpeg-1.dll"
 File "%deps%/bin/libpng15-15.dll"
 File "%deps%/bin/libsigc-2.0-0.dll"
index 96dc0e2c91bbca1284b3f50a27193aef4534f49c..cc25ccc67fce6bba6f71fcc0f944c1ab8d2082ad 100644 (file)
 #include <libxml++/libxml++.h>
 #include <libdcp/colour_matrix.h>
 #include <libcxml/cxml.h>
+#include "config.h"
 #include "colour_conversion.h"
 
 #include "i18n.h"
 
 using std::list;
 using std::string;
+using std::cout;
+using std::vector;
 using boost::shared_ptr;
 using boost::lexical_cast;
+using boost::optional;
 
 ColourConversion::ColourConversion ()
-       : name (_("Untitled"))
-       , input_gamma (2.4)
+       : input_gamma (2.4)
        , input_gamma_linearised (true)
        , matrix (3, 3)
        , output_gamma (2.6)
@@ -44,9 +47,8 @@ ColourConversion::ColourConversion ()
        }
 }
 
-ColourConversion::ColourConversion (string n, float i, bool il, float const m[3][3], float o)
-       : name (n)
-       , input_gamma (i)
+ColourConversion::ColourConversion (double i, bool il, double const m[3][3], double o)
+       : input_gamma (i)
        , input_gamma_linearised (il)
        , matrix (3, 3)
        , output_gamma (o)
@@ -61,8 +63,7 @@ ColourConversion::ColourConversion (string n, float i, bool il, float const m[3]
 ColourConversion::ColourConversion (shared_ptr<cxml::Node> node)
        : matrix (3, 3)
 {
-       name = node->string_child ("Name");
-       input_gamma = node->number_child<float> ("InputGamma");
+       input_gamma = node->number_child<double> ("InputGamma");
        input_gamma_linearised = node->bool_child ("InputGammaLinearised");
 
        for (int i = 0; i < 3; ++i) {
@@ -75,16 +76,15 @@ ColourConversion::ColourConversion (shared_ptr<cxml::Node> node)
        for (list<shared_ptr<cxml::Node> >::iterator i = m.begin(); i != m.end(); ++i) {
                int const ti = (*i)->number_attribute<int> ("i");
                int const tj = (*i)->number_attribute<int> ("j");
-               matrix(ti, tj) = lexical_cast<float> ((*i)->content ());
+               matrix(ti, tj) = lexical_cast<double> ((*i)->content ());
        }
 
-       output_gamma = node->number_child<float> ("OutputGamma");
+       output_gamma = node->number_child<double> ("OutputGamma");
 }
 
 void
 ColourConversion::as_xml (xmlpp::Node* node) const
 {
-       node->add_child("Name")->add_child_text (name);
        node->add_child("InputGamma")->add_child_text (lexical_cast<string> (input_gamma));
        node->add_child("InputGammaLinearised")->add_child_text (input_gamma_linearised ? "1" : "0");
 
@@ -99,3 +99,79 @@ ColourConversion::as_xml (xmlpp::Node* node) const
 
        node->add_child("OutputGamma")->add_child_text (lexical_cast<string> (output_gamma));
 }
+
+optional<size_t>
+ColourConversion::preset () const
+{
+       vector<PresetColourConversion> presets = Config::instance()->colour_conversions ();
+       size_t i = 0;
+       while (i < presets.size() && (presets[i].conversion != *this)) {
+               ++i;
+       }
+
+       if (i >= presets.size ()) {
+               return optional<size_t> ();
+       }
+
+       return i;
+}
+
+PresetColourConversion::PresetColourConversion ()
+       : name (_("Untitled"))
+{
+
+}
+
+PresetColourConversion::PresetColourConversion (string n, double i, bool il, double const m[3][3], double o)
+       : name (n)
+       , conversion (i, il, m, o)
+{
+
+}
+
+PresetColourConversion::PresetColourConversion (shared_ptr<cxml::Node> node)
+       : conversion (node)
+{
+       name = node->string_child ("Name");
+}
+
+void
+PresetColourConversion::as_xml (xmlpp::Node* node) const
+{
+       conversion.as_xml (node);
+       node->add_child("Name")->add_child_text (name);
+}
+
+static bool
+about_equal (double a, double b)
+{
+       static const double eps = 1e-6;
+       return fabs (a - b) < eps;
+}
+
+bool
+operator== (ColourConversion const & a, ColourConversion const & b)
+{
+       if (
+               !about_equal (a.input_gamma, b.input_gamma) ||
+               a.input_gamma_linearised != b.input_gamma_linearised ||
+               !about_equal (a.output_gamma, b.output_gamma)) {
+               return false;
+       }
+
+       for (int i = 0; i < 3; ++i) {
+               for (int j = 0; j < 3; ++j) {
+                       if (!about_equal (a.matrix (i, j), b.matrix (i, j))) {
+                               return false;
+                       }
+               }
+       }
+
+       return true;
+}
+
+bool
+operator!= (ColourConversion const & a, ColourConversion const & b)
+{
+       return !(a == b);
+}
index ed89f8c635a9932d60fe78b14211320d58385801..85d951ce169dadb48f602f93d9c9d5990d1e145c 100644 (file)
 
 */
 
+#ifndef DCPOMATIC_COLOUR_CONVERSION_H
+#define DCPOMATIC_COLOUR_CONVERSION_H
+
 #include <boost/utility.hpp>
+#include <boost/optional.hpp>
 #include <boost/numeric/ublas/matrix.hpp>
 
 namespace cxml {
@@ -28,18 +32,37 @@ namespace xmlpp {
        class Node;
 }
 
-class ColourConversion : public boost::noncopyable
+class ColourConversion
 {
 public:
        ColourConversion ();
-       ColourConversion (std::string, float, bool, float const matrix[3][3], float);
+       ColourConversion (double, bool, double const matrix[3][3], double);
        ColourConversion (boost::shared_ptr<cxml::Node>);
 
+       virtual void as_xml (xmlpp::Node *) const;
+
+       boost::optional<size_t> preset () const;
+
+       double input_gamma;
+       bool input_gamma_linearised;
+       boost::numeric::ublas::matrix<double> matrix;
+       double output_gamma;
+};
+
+class PresetColourConversion
+{
+public:
+       PresetColourConversion ();
+       PresetColourConversion (std::string, double, bool, double const matrix[3][3], double);
+       PresetColourConversion (boost::shared_ptr<cxml::Node>);
+
        void as_xml (xmlpp::Node *) const;
 
        std::string name;
-       float input_gamma;
-       bool input_gamma_linearised;
-       boost::numeric::ublas::matrix<float> matrix;
-       float output_gamma;
+       ColourConversion conversion;
 };
+
+bool operator== (ColourConversion const &, ColourConversion const &);
+bool operator!= (ColourConversion const &, ColourConversion const &);
+
+#endif
index 0c8413be9f8509c8fed9027c0e06ca822ec36757..10cb13ecc2a0165829dfed0244fc7680049a20e7 100644 (file)
@@ -65,13 +65,8 @@ Config::Config ()
        _allowed_dcp_frame_rates.push_back (50);
        _allowed_dcp_frame_rates.push_back (60);
 
-       _colour_conversions.push_back (shared_ptr<ColourConversion> (
-                                              new ColourConversion (_("sRGB"), 2.4, true, libdcp::colour_matrix::xyz_to_rgb, 2.6))
-               );
-       
-       _colour_conversions.push_back (shared_ptr<ColourConversion> (
-                                              new ColourConversion (_("sRGB non-linearised"), 2.4, false, libdcp::colour_matrix::xyz_to_rgb, 2.6))
-               );
+       _colour_conversions.push_back (PresetColourConversion (_("sRGB"), 2.4, true, libdcp::colour_matrix::xyz_to_rgb, 2.6));
+       _colour_conversions.push_back (PresetColourConversion (_("sRGB non-linearised"), 2.4, false, libdcp::colour_matrix::xyz_to_rgb, 2.6));
 }
 
 void
@@ -91,7 +86,7 @@ Config::read ()
        
        list<shared_ptr<cxml::Node> > servers = f.node_children ("Server");
        for (list<shared_ptr<cxml::Node> >::iterator i = servers.begin(); i != servers.end(); ++i) {
-               _servers.push_back (shared_ptr<ServerDescription> (new ServerDescription (*i)));
+               _servers.push_back (ServerDescription (*i));
        }
 
        _tms_ip = f.string_child ("TMSIP");
@@ -130,7 +125,7 @@ Config::read ()
        }
        
        for (list<shared_ptr<cxml::Node> >::iterator i = cc.begin(); i != cc.end(); ++i) {
-               _colour_conversions.push_back (shared_ptr<ColourConversion> (new ColourConversion (*i)));
+               _colour_conversions.push_back (PresetColourConversion (*i));
        }
 }
 
@@ -163,7 +158,10 @@ Config::read_old_metadata ()
                } else if (k == N_("server_port")) {
                        _server_port = atoi (v.c_str ());
                } else if (k == N_("server")) {
-                       _servers.push_back (ServerDescription::create_from_metadata (v));
+                       optional<ServerDescription> server = ServerDescription::create_from_metadata (v);
+                       if (server) {
+                               _servers.push_back (server.get ());
+                       }
                } else if (k == N_("tms_ip")) {
                        _tms_ip = v;
                } else if (k == N_("tms_path")) {
@@ -237,8 +235,8 @@ Config::write () const
        root->add_child("DefaultDirectory")->add_child_text (_default_directory);
        root->add_child("ServerPort")->add_child_text (lexical_cast<string> (_server_port));
        
-       for (vector<shared_ptr<ServerDescription> >::const_iterator i = _servers.begin(); i != _servers.end(); ++i) {
-               (*i)->as_xml (root->add_child ("Server"));
+       for (vector<ServerDescription>::const_iterator i = _servers.begin(); i != _servers.end(); ++i) {
+               i->as_xml (root->add_child ("Server"));
        }
 
        root->add_child("TMSIP")->add_child_text (_tms_ip);
@@ -265,8 +263,8 @@ Config::write () const
        root->add_child("DefaultStillLength")->add_child_text (lexical_cast<string> (_default_still_length));
        root->add_child("DefaultJ2KBandwidth")->add_child_text (lexical_cast<string> (_default_j2k_bandwidth));
 
-       for (vector<shared_ptr<ColourConversion> >::const_iterator i = _colour_conversions.begin(); i != _colour_conversions.end(); ++i) {
-               (*i)->as_xml (root->add_child ("ColourConversion"));
+       for (vector<PresetColourConversion>::const_iterator i = _colour_conversions.begin(); i != _colour_conversions.end(); ++i) {
+               i->as_xml (root->add_child ("ColourConversion"));
        }
 
        doc.write_to_file_formatted (file (false));
index 40d06a1721493ab8105b13109c881ec37fd3b19c..bce6bfd7e2707ecbd7a196ee60ac69f4d1df5426 100644 (file)
@@ -29,6 +29,8 @@
 #include <boost/signals2.hpp>
 #include <libdcp/metadata.h>
 #include "dci_metadata.h"
+#include "colour_conversion.h"
+#include "server.h"
 
 class ServerDescription;
 class Scaler;
@@ -36,7 +38,6 @@ class Filter;
 class SoundProcessor;
 class DCPContentType;
 class Ratio;
-class ColourConversion;
 
 /** @class Config
  *  @brief A singleton class holding configuration.
@@ -62,7 +63,7 @@ public:
        }
 
        /** @return J2K encoding servers to use */
-       std::vector<boost::shared_ptr<ServerDescription> > servers () const {
+       std::vector<ServerDescription> servers () const {
                return _servers;
        }
 
@@ -123,7 +124,7 @@ public:
                return _default_j2k_bandwidth;
        }
 
-       std::vector<boost::shared_ptr<ColourConversion> > colour_conversions () const {
+       std::vector<PresetColourConversion> colour_conversions () const {
                return _colour_conversions;
        }
 
@@ -142,7 +143,7 @@ public:
        }
 
        /** @param s New list of servers */
-       void set_servers (std::vector<boost::shared_ptr<ServerDescription> > s) {
+       void set_servers (std::vector<ServerDescription> s) {
                _servers = s;
        }
 
@@ -210,7 +211,7 @@ public:
                _default_j2k_bandwidth = b;
        }
 
-       void set_colour_conversions (std::vector<boost::shared_ptr<ColourConversion> > const & c) {
+       void set_colour_conversions (std::vector<PresetColourConversion> const & c) {
                _colour_conversions = c;
        }
        
@@ -233,7 +234,7 @@ private:
        int _server_port;
 
        /** J2K encoding servers to use */
-       std::vector<boost::shared_ptr<ServerDescription> > _servers;
+       std::vector<ServerDescription> _servers;
        /** Scaler to use for the "A" part of A/B comparisons */
        Scaler const * _reference_scaler;
        /** Filters to use for the "A" part of A/B comparisons */
@@ -257,7 +258,7 @@ private:
        DCPContentType const * _default_dcp_content_type;
        libdcp::XMLMetadata _dcp_metadata;
        int _default_j2k_bandwidth;
-       std::vector<boost::shared_ptr<ColourConversion> > _colour_conversions;
+       std::vector<PresetColourConversion> _colour_conversions;
 
        /** Singleton instance, or 0 */
        static Config* _instance;
index 53cf1753a2d7bc117447fa455456b34053b0ae37..1cb20b61176f2b229aab97380f1fa5e6ecb500ea 100644 (file)
@@ -213,11 +213,11 @@ DCPVideoFrame::encode_locally ()
  *  @return Encoded data.
  */
 shared_ptr<EncodedData>
-DCPVideoFrame::encode_remotely (boost::shared_ptr<const ServerDescription> serv)
+DCPVideoFrame::encode_remotely (ServerDescription serv)
 {
        boost::asio::io_service io_service;
        boost::asio::ip::tcp::resolver resolver (io_service);
-       boost::asio::ip::tcp::resolver::query query (serv->host_name(), boost::lexical_cast<string> (Config::instance()->server_port ()));
+       boost::asio::ip::tcp::resolver::query query (serv.host_name(), boost::lexical_cast<string> (Config::instance()->server_port ()));
        boost::asio::ip::tcp::resolver::iterator endpoint_iterator = resolver.resolve (query);
 
        shared_ptr<Socket> socket (new Socket);
index 18c8fe628a20e2c1cabb5892ed9bed0d9b615482..ce6444293c2fedfbf1f587161aa43a7e9bf6330d 100644 (file)
@@ -105,7 +105,7 @@ public:
        DCPVideoFrame (boost::shared_ptr<const Image>, int, Eyes, int, int, boost::shared_ptr<Log>);
 
        boost::shared_ptr<EncodedData> encode_locally ();
-       boost::shared_ptr<EncodedData> encode_remotely (boost::shared_ptr<const ServerDescription>);
+       boost::shared_ptr<EncodedData> encode_remotely (ServerDescription);
 
        Eyes eyes () const {
                return _eyes;
index a1c02479936d00fbb2af25f9f81cf04ae35fe539..29fe64e26c993d6f17336e38669a990945032b45 100644 (file)
@@ -71,13 +71,13 @@ void
 Encoder::process_begin ()
 {
        for (int i = 0; i < Config::instance()->num_local_encoding_threads (); ++i) {
-               _threads.push_back (new boost::thread (boost::bind (&Encoder::encoder_thread, this, shared_ptr<ServerDescription> ())));
+               _threads.push_back (new boost::thread (boost::bind (&Encoder::encoder_thread, this, optional<ServerDescription> ())));
        }
 
-       vector<shared_ptr<ServerDescription> > servers = Config::instance()->servers ();
+       vector<ServerDescription> servers = Config::instance()->servers ();
 
-       for (vector<shared_ptr<ServerDescription> >::iterator i = servers.begin(); i != servers.end(); ++i) {
-               for (int j = 0; j < (*i)->threads (); ++j) {
+       for (vector<ServerDescription>::iterator i = servers.begin(); i != servers.end(); ++i) {
+               for (int j = 0; j < i->threads (); ++j) {
                        _threads.push_back (new boost::thread (boost::bind (&Encoder::encoder_thread, this, *i)));
                }
        }
@@ -244,7 +244,7 @@ Encoder::terminate_threads ()
 }
 
 void
-Encoder::encoder_thread (shared_ptr<ServerDescription> server)
+Encoder::encoder_thread (optional<ServerDescription> server)
 {
        /* Number of seconds that we currently wait between attempts
           to connect to the server; not relevant for localhost
@@ -275,7 +275,7 @@ Encoder::encoder_thread (shared_ptr<ServerDescription> server)
 
                if (server) {
                        try {
-                               encoded = vf->encode_remotely (server);
+                               encoded = vf->encode_remotely (server.get ());
 
                                if (remote_backoff > 0) {
                                        _film->log()->log (String::compose (N_("%1 was lost, but now she is found; removing backoff"), server->host_name ()));
index a4df202a21e6758da1cffb35dff53f0c73e3fcd0..c0ea30fcbb0a051582b24ddceb564d9ceeb873f4 100644 (file)
@@ -81,7 +81,7 @@ private:
        
        void frame_done ();
        
-       void encoder_thread (boost::shared_ptr<ServerDescription>);
+       void encoder_thread (boost::optional<ServerDescription>);
        void terminate_threads ();
 
        /** Film that we are encoding */
index 54cffc0774b0ed1a64d6c3e3873c7d0054806843..de265dca430043fdb174e5f014f5a2ba94c14531 100644 (file)
@@ -49,6 +49,7 @@ using boost::algorithm::split;
 using boost::thread;
 using boost::bind;
 using boost::scoped_array;
+using boost::optional;
 using libdcp::Size;
 
 ServerDescription::ServerDescription (shared_ptr<const cxml::Node> node)
@@ -68,17 +69,17 @@ ServerDescription::as_xml (xmlpp::Node* root) const
  *  @param v Metadata.
  *  @return ServerDescription, or 0.
  */
-shared_ptr<ServerDescription>
+optional<ServerDescription>
 ServerDescription::create_from_metadata (string v)
 {
        vector<string> b;
        split (b, v, is_any_of (N_(" ")));
 
        if (b.size() != 2) {
-               return shared_ptr<ServerDescription> ();
+               return optional<ServerDescription> ();
        }
 
-       return shared_ptr<ServerDescription> (new ServerDescription (b[0], atoi (b[1].c_str ())));
+       return ServerDescription (b[0], atoi (b[1].c_str ()));
 }
 
 Server::Server (shared_ptr<Log> log)
index 6307c1867686575fe3ac99ba9e13e0eaf5f2c238..56a1fdab9f20d133f9436c0c028015a8e13a4339 100644 (file)
@@ -17,6 +17,9 @@
 
 */
 
+#ifndef DCPOMATIC_SERVER_H
+#define DCPOMATIC_SERVER_H
+
 /** @file src/server.h
  *  @brief Class to describe a server to which we can send
  *  encoding work, and a class to implement such a server.
@@ -78,7 +81,7 @@ public:
 
        void as_xml (xmlpp::Node *) const;
        
-       static boost::shared_ptr<ServerDescription> create_from_metadata (std::string v);
+       static boost::optional<ServerDescription> create_from_metadata (std::string);
 
 private:
        /** server's host name */
@@ -104,3 +107,5 @@ private:
        boost::condition _worker_condition;
        boost::shared_ptr<Log> _log;
 };
+
+#endif
index f61518ec0f5b72f80a8ec936bcebc92ece04cdad..8b0ec4c997827619738cc56f62218c4797fa2219 100644 (file)
 #include "video_examiner.h"
 #include "ratio.h"
 #include "compose.hpp"
+#include "config.h"
+#include "colour_conversion.h"
 
 #include "i18n.h"
 
-int const VideoContentProperty::VIDEO_SIZE      = 0;
-int const VideoContentProperty::VIDEO_FRAME_RATE = 1;
-int const VideoContentProperty::VIDEO_FRAME_TYPE = 2;
-int const VideoContentProperty::VIDEO_CROP      = 3;
-int const VideoContentProperty::VIDEO_RATIO     = 4;
+int const VideoContentProperty::VIDEO_SIZE       = 0;
+int const VideoContentProperty::VIDEO_FRAME_RATE  = 1;
+int const VideoContentProperty::VIDEO_FRAME_TYPE  = 2;
+int const VideoContentProperty::VIDEO_CROP       = 3;
+int const VideoContentProperty::VIDEO_RATIO      = 4;
+int const VideoContentProperty::COLOUR_CONVERSION = 5;
 
 using std::string;
 using std::stringstream;
@@ -46,6 +49,7 @@ VideoContent::VideoContent (shared_ptr<const Film> f, Time s, VideoContent::Fram
        , _video_frame_rate (0)
        , _video_frame_type (VIDEO_FRAME_TYPE_2D)
        , _ratio (Ratio::from_id ("185"))
+       , _colour_conversion (Config::instance()->colour_conversions().front().conversion)
 {
 
 }
@@ -56,6 +60,7 @@ VideoContent::VideoContent (shared_ptr<const Film> f, boost::filesystem::path p)
        , _video_frame_rate (0)
        , _video_frame_type (VIDEO_FRAME_TYPE_2D)
        , _ratio (Ratio::from_id ("185"))
+       , _colour_conversion (Config::instance()->colour_conversions().front().conversion)
 {
 
 }
@@ -76,6 +81,7 @@ VideoContent::VideoContent (shared_ptr<const Film> f, shared_ptr<const cxml::Nod
        if (r) {
                _ratio = Ratio::from_id (r.get ());
        }
+       _colour_conversion = ColourConversion (node->node_child ("ColourConversion"));
 }
 
 void
@@ -94,6 +100,7 @@ VideoContent::as_xml (xmlpp::Node* node) const
        if (_ratio) {
                node->add_child("Ratio")->add_child_text (_ratio->id ());
        }
+       _colour_conversion.as_xml (node->add_child("ColourConversion"));
 }
 
 void
@@ -257,3 +264,14 @@ VideoContent::video_size_after_3d_split () const
 
        assert (false);
 }
+
+void
+VideoContent::set_colour_conversion (ColourConversion c)
+{
+       {
+               boost::mutex::scoped_lock lm (_mutex);
+               _colour_conversion = c;
+       }
+
+       signal_changed (VideoContentProperty::COLOUR_CONVERSION);
+}
index 97ef6a9fae710fba1b5e7482542b817514d6490a..72c72625b5c30a97927fdefe17b56c98492cf24f 100644 (file)
@@ -21,6 +21,7 @@
 #define DCPOMATIC_VIDEO_CONTENT_H
 
 #include "content.h"
+#include "colour_conversion.h"
 
 class VideoExaminer;
 class Ratio;
@@ -33,6 +34,7 @@ public:
        static int const VIDEO_FRAME_TYPE;
        static int const VIDEO_CROP;
        static int const VIDEO_RATIO;
+       static int const COLOUR_CONVERSION;
 };
 
 class VideoContent : public virtual Content
@@ -71,6 +73,8 @@ public:
        void set_top_crop (int);
        void set_bottom_crop (int);
 
+       void set_colour_conversion (ColourConversion);
+
        VideoFrameType video_frame_type () const {
                boost::mutex::scoped_lock lm (_mutex);
                return _video_frame_type;
@@ -88,6 +92,11 @@ public:
                return _ratio;
        }
 
+       ColourConversion colour_conversion () const {
+               boost::mutex::scoped_lock lm (_mutex);
+               return _colour_conversion;
+       }
+
        libdcp::Size video_size_after_3d_split () const;
 
 protected:
@@ -106,6 +115,7 @@ private:
        VideoFrameType _video_frame_type;
        Crop _crop;
        Ratio const * _ratio;
+       ColourConversion _colour_conversion;
 };
 
 #endif
index ff7ab6ffe59446f74a0628733b7a1768e8058e5d..7695e1e948b0cfde4a8703ef2371cffbd68e7a50 100644 (file)
@@ -116,7 +116,7 @@ main (int argc, char* argv[])
        dcpomatic_setup ();
 
        if (no_remote) {
-               Config::instance()->set_servers (vector<shared_ptr<ServerDescription> > ());
+               Config::instance()->set_servers (vector<ServerDescription> ());
        }
 
        cout << "DCP-o-matic " << dcpomatic_version << " git " << dcpomatic_git_commit;
diff --git a/src/wx/colour_conversion_dialog.cc b/src/wx/colour_conversion_dialog.cc
deleted file mode 100644 (file)
index 1a8008b..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
-    Copyright (C) 2013 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
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#include <boost/lexical_cast.hpp>
-#include <wx/spinctrl.h>
-#include <wx/gbsizer.h>
-#include "lib/colour_conversion.h"
-#include "wx_util.h"
-#include "colour_conversion_dialog.h"
-
-using std::string;
-using std::cout;
-using boost::shared_ptr;
-using boost::lexical_cast;
-
-ColourConversionDialog::ColourConversionDialog (wxWindow* parent, shared_ptr<ColourConversion> conversion)
-       : wxDialog (parent, wxID_ANY, _("Colour conversion"))
-       , _conversion (conversion)
-{
-       wxBoxSizer* overall_sizer = new wxBoxSizer (wxVERTICAL);
-       SetSizer (overall_sizer);
-
-       wxGridBagSizer* table = new wxGridBagSizer (DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
-       overall_sizer->Add (table, 1, wxEXPAND | wxALL, DCPOMATIC_DIALOG_BORDER);
-
-       int r = 0;
-
-       add_label_to_grid_bag_sizer (table, this, _("Name"), true, wxGBPosition (r, 0));
-       _name = new wxTextCtrl (this, wxID_ANY, wxT (""));
-       table->Add (_name, wxGBPosition (r, 1), wxDefaultSpan, wxEXPAND);
-       ++r;
-
-       add_label_to_grid_bag_sizer (table, this, _("Input gamma"), true, wxGBPosition (r, 0));
-       _input_gamma = new wxSpinCtrlDouble (this);
-       table->Add (_input_gamma, wxGBPosition (r, 1));
-       ++r;
-
-       _input_gamma_linearised = new wxCheckBox (this, wxID_ANY, _("Linearise input gamma curve for low values"));
-       table->Add (_input_gamma_linearised, wxGBPosition (r, 0), wxGBSpan (1, 2));
-       ++r;
-
-        wxClientDC dc (parent);
-        wxSize size = dc.GetTextExtent (wxT ("0.123456789012"));
-        size.SetHeight (-1);
-
-        wxTextValidator validator (wxFILTER_INCLUDE_CHAR_LIST);
-        wxArrayString list;
-
-        wxString n (wxT ("0123456789.-"));
-        for (size_t i = 0; i < n.Length(); ++i) {
-                list.Add (n[i]);
-        }
-
-        validator.SetIncludes (list);
-
-       add_label_to_grid_bag_sizer (table, this, _("Matrix"), true, wxGBPosition (r, 0));
-       wxFlexGridSizer* matrix_sizer = new wxFlexGridSizer (3, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
-       for (int x = 0; x < 3; ++x) {
-               for (int y = 0; y < 3; ++y) {
-                       _matrix[x][y] = new wxTextCtrl (this, wxID_ANY, wxT (""), wxDefaultPosition, size, 0, validator);
-                       matrix_sizer->Add (_matrix[x][y]);
-               }
-       }
-       table->Add (matrix_sizer, wxGBPosition (r, 1));
-       ++r;
-
-       add_label_to_grid_bag_sizer (table, this, _("Output gamma"), true, wxGBPosition (r, 0));
-       wxBoxSizer* output_sizer = new wxBoxSizer (wxHORIZONTAL);
-       /* TRANSLATORS: this means the mathematical reciprocal operation, i.e. we are dividing 1 by the control that
-          comes after it.
-       */
-       add_label_to_sizer (output_sizer, this, _("1 / "), false);
-       _output_gamma = new wxSpinCtrlDouble (this);
-       output_sizer->Add (_output_gamma);
-       table->Add (output_sizer, wxGBPosition (r, 1));
-       ++r;
-
-       wxSizer* buttons = CreateSeparatedButtonSizer (wxOK);
-       if (buttons) {
-               overall_sizer->Add (buttons, wxSizerFlags().Expand().DoubleBorder());
-       }
-
-       SetSizer (overall_sizer);
-       overall_sizer->Layout ();
-       overall_sizer->SetSizeHints (this);
-
-       _input_gamma->SetRange(0.1, 4.0);
-       _input_gamma->SetDigits (1);
-       _input_gamma->SetIncrement (0.1);
-       _output_gamma->SetRange(0.1, 4.0);
-       _output_gamma->SetDigits (1);
-       _output_gamma->SetIncrement (0.1);
-
-       _name->SetValue (std_to_wx (conversion->name));
-       _input_gamma->SetValue (conversion->input_gamma);
-       _input_gamma_linearised->SetValue (conversion->input_gamma_linearised);
-       for (int i = 0; i < 3; ++i) {
-               for (int j = 0; j < 3; ++j) {
-                       _matrix[i][j]->SetValue (std_to_wx (lexical_cast<string> (conversion->matrix(i, j))));
-               }
-       }
-       _output_gamma->SetValue (conversion->output_gamma);
-
-       _name->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&ColourConversionDialog::changed, this));
-       _input_gamma->Bind (wxEVT_COMMAND_SPINCTRLDOUBLE_UPDATED, boost::bind (&ColourConversionDialog::changed, this));
-       _input_gamma_linearised->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&ColourConversionDialog::changed, this));
-       _output_gamma->Bind (wxEVT_COMMAND_SPINCTRLDOUBLE_UPDATED, boost::bind (&ColourConversionDialog::changed, this));
-       for (int i = 0; i < 3; ++i) {
-               for (int j = 0; j < 3; ++j) {
-                       _matrix[i][j]->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&ColourConversionDialog::changed, this));
-               }
-       }
-}
-
-void
-ColourConversionDialog::changed ()
-{
-       _conversion->name = wx_to_std (_name->GetValue ());
-       _conversion->input_gamma = _input_gamma->GetValue ();
-       _conversion->input_gamma_linearised = _input_gamma_linearised->GetValue ();
-
-       for (int i = 0; i < 3; ++i) {
-               for (int j = 0; j < 3; ++j) {
-                       string const v = wx_to_std (_matrix[i][j]->GetValue ());
-                       if (v.empty ()) {
-                               _conversion->matrix (i, j) = 0;
-                       } else {
-                               _conversion->matrix (i, j) = lexical_cast<float> (v);
-                       }
-               }
-       }
-       _conversion->output_gamma = _output_gamma->GetValue ();
-}
-       
diff --git a/src/wx/colour_conversion_dialog.h b/src/wx/colour_conversion_dialog.h
deleted file mode 100644 (file)
index 8da6df1..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
-    Copyright (C) 2013 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
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#include <wx/wx.h>
-
-class wxSpinCtrlDouble;
-class ColourConversion;
-
-class ColourConversionDialog : public wxDialog
-{
-public:
-       ColourConversionDialog (wxWindow *, boost::shared_ptr<ColourConversion>);
-
-private:
-       void changed ();
-       
-       boost::shared_ptr<ColourConversion> _conversion;
-       wxTextCtrl* _name;
-       wxSpinCtrlDouble* _input_gamma;
-       wxCheckBox* _input_gamma_linearised;
-       wxTextCtrl* _matrix[3][3];
-       wxSpinCtrlDouble* _output_gamma;
-};
diff --git a/src/wx/colour_conversion_editor.cc b/src/wx/colour_conversion_editor.cc
new file mode 100644 (file)
index 0000000..091028d
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+    Copyright (C) 2013 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
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <boost/lexical_cast.hpp>
+#include <wx/spinctrl.h>
+#include <wx/gbsizer.h>
+#include "lib/colour_conversion.h"
+#include "wx_util.h"
+#include "colour_conversion_editor.h"
+
+using std::string;
+using std::cout;
+using std::stringstream;
+using boost::shared_ptr;
+using boost::lexical_cast;
+
+ColourConversionEditor::ColourConversionEditor (wxWindow* parent)
+       : wxPanel (parent, wxID_ANY)
+{
+       wxBoxSizer* overall_sizer = new wxBoxSizer (wxVERTICAL);
+       SetSizer (overall_sizer);
+
+       wxGridBagSizer* table = new wxGridBagSizer (DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
+       overall_sizer->Add (table, 1, wxEXPAND | wxALL, DCPOMATIC_DIALOG_BORDER);
+
+       int r = 0;
+
+       add_label_to_grid_bag_sizer (table, this, _("Input gamma"), true, wxGBPosition (r, 0));
+       _input_gamma = new wxSpinCtrlDouble (this);
+       table->Add (_input_gamma, wxGBPosition (r, 1));
+       ++r;
+
+       _input_gamma_linearised = new wxCheckBox (this, wxID_ANY, _("Linearise input gamma curve for low values"));
+       table->Add (_input_gamma_linearised, wxGBPosition (r, 0), wxGBSpan (1, 2));
+       ++r;
+
+        wxClientDC dc (parent);
+        wxSize size = dc.GetTextExtent (wxT ("-0.123456789012345678"));
+        size.SetHeight (-1);
+
+        wxTextValidator validator (wxFILTER_INCLUDE_CHAR_LIST);
+        wxArrayString list;
+
+        wxString n (wxT ("0123456789.-"));
+        for (size_t i = 0; i < n.Length(); ++i) {
+                list.Add (n[i]);
+        }
+
+        validator.SetIncludes (list);
+
+       add_label_to_grid_bag_sizer (table, this, _("Matrix"), true, wxGBPosition (r, 0));
+       wxFlexGridSizer* matrix_sizer = new wxFlexGridSizer (3, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
+       for (int i = 0; i < 3; ++i) {
+               for (int j = 0; j < 3; ++j) {
+                       _matrix[i][j] = new wxTextCtrl (this, wxID_ANY, wxT (""), wxDefaultPosition, size, 0, validator);
+                       matrix_sizer->Add (_matrix[i][j]);
+               }
+       }
+       table->Add (matrix_sizer, wxGBPosition (r, 1));
+       ++r;
+
+       add_label_to_grid_bag_sizer (table, this, _("Output gamma"), true, wxGBPosition (r, 0));
+       wxBoxSizer* output_sizer = new wxBoxSizer (wxHORIZONTAL);
+       /* TRANSLATORS: this means the mathematical reciprocal operation, i.e. we are dividing 1 by the control that
+          comes after it.
+       */
+       add_label_to_sizer (output_sizer, this, _("1 / "), false);
+       _output_gamma = new wxSpinCtrlDouble (this);
+       output_sizer->Add (_output_gamma);
+       table->Add (output_sizer, wxGBPosition (r, 1));
+       ++r;
+
+       _input_gamma->SetRange(0.1, 4.0);
+       _input_gamma->SetDigits (1);
+       _input_gamma->SetIncrement (0.1);
+       _output_gamma->SetRange(0.1, 4.0);
+       _output_gamma->SetDigits (1);
+       _output_gamma->SetIncrement (0.1);
+
+       _input_gamma->Bind (wxEVT_COMMAND_SPINCTRLDOUBLE_UPDATED, boost::bind (&ColourConversionEditor::changed, this));
+       _input_gamma_linearised->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&ColourConversionEditor::changed, this));
+       for (int i = 0; i < 3; ++i) {
+               for (int j = 0; j < 3; ++j) {
+                       _matrix[i][j]->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&ColourConversionEditor::changed, this));
+               }
+       }
+       _output_gamma->Bind (wxEVT_COMMAND_SPINCTRLDOUBLE_UPDATED, boost::bind (&ColourConversionEditor::changed, this));
+}
+
+void
+ColourConversionEditor::set (ColourConversion conversion)
+{
+       _input_gamma->SetValue (conversion.input_gamma);
+       _input_gamma_linearised->SetValue (conversion.input_gamma_linearised);
+       for (int i = 0; i < 3; ++i) {
+               for (int j = 0; j < 3; ++j) {
+                       stringstream s;
+                       s.setf (std::ios::fixed, std::ios::floatfield);
+                       s.precision (14);
+                       s << conversion.matrix (i, j);
+                       _matrix[i][j]->SetValue (std_to_wx (s.str ()));
+               }
+       }
+       _output_gamma->SetValue (conversion.output_gamma);
+}
+
+ColourConversion
+ColourConversionEditor::get () const
+{
+       ColourConversion conversion;
+       
+       conversion.input_gamma = _input_gamma->GetValue ();
+       conversion.input_gamma_linearised = _input_gamma_linearised->GetValue ();
+
+       for (int i = 0; i < 3; ++i) {
+               for (int j = 0; j < 3; ++j) {
+                       string const v = wx_to_std (_matrix[i][j]->GetValue ());
+                       if (v.empty ()) {
+                               conversion.matrix (i, j) = 0;
+                       } else {
+                               conversion.matrix (i, j) = lexical_cast<double> (v);
+                       }
+               }
+       }
+       
+       conversion.output_gamma = _output_gamma->GetValue ();
+
+       return conversion;
+}
+
+void
+ColourConversionEditor::changed ()
+{
+       Changed ();
+}
+
diff --git a/src/wx/colour_conversion_editor.h b/src/wx/colour_conversion_editor.h
new file mode 100644 (file)
index 0000000..8567cac
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+    Copyright (C) 2013 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
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef DCPOMATIC_COLOUR_CONVERSION_EDITOR_H
+#define DCPOMATIC_COLOUR_CONVERSION_EDITOR_H
+
+#include <boost/signals2.hpp>
+#include <wx/wx.h>
+
+class wxSpinCtrlDouble;
+class ColourConversion;
+
+class ColourConversionEditor : public wxPanel
+{
+public:
+       ColourConversionEditor (wxWindow *);
+
+       void set (ColourConversion);
+       ColourConversion get () const;
+
+       boost::signals2::signal<void ()> Changed;
+
+private:
+       void changed ();
+       
+       wxSpinCtrlDouble* _input_gamma;
+       wxCheckBox* _input_gamma_linearised;
+       wxTextCtrl* _matrix[3][3];
+       wxSpinCtrlDouble* _output_gamma;
+};
+
+#endif
index 66f0cd186b99a42317f25636ff6346f22a7f5788..7f1efa52f6082df074ec0e049c263c46843a1aa5 100644 (file)
@@ -40,7 +40,7 @@
 #include "server_dialog.h"
 #include "dir_picker_ctrl.h"
 #include "dci_metadata_dialog.h"
-#include "colour_conversion_dialog.h"
+#include "preset_colour_conversion_dialog.h"
 
 using std::vector;
 using std::string;
@@ -280,13 +280,13 @@ ConfigDialog::make_metadata_panel ()
 }
 
 static std::string
-server_column (shared_ptr<ServerDescription> s, int c)
+server_column (ServerDescription s, int c)
 {
        switch (c) {
        case 0:
-               return s->host_name ();
+               return s.host_name ();
        case 1:
-               return lexical_cast<string> (s->threads ());
+               return lexical_cast<string> (s.threads ());
        }
 
        return "";
@@ -434,9 +434,9 @@ ConfigDialog::default_j2k_bandwidth_changed ()
 }
 
 static std::string
-colour_conversion_column (shared_ptr<ColourConversion> c)
+colour_conversion_column (PresetColourConversion c)
 {
-       return c->name;
+       return c.name;
 }
 
 void
@@ -444,7 +444,7 @@ ConfigDialog::make_colour_conversions_panel ()
 {
        vector<string> columns;
        columns.push_back (wx_to_std (_("Name")));
-       _colour_conversions_panel = new EditableList<ColourConversion, ColourConversionDialog> (
+       _colour_conversions_panel = new EditableList<PresetColourConversion, PresetColourConversionDialog> (
                _notebook,
                columns,
                boost::bind (&Config::colour_conversions, Config::instance()),
index 60d9229c46ab63650c2ad6c5a4f909976f474bcc..82c4ee2a03b7a972f3796261dabc468046fe8848 100644 (file)
@@ -31,8 +31,8 @@
 class DirPickerCtrl;
 class wxNotebook;
 class ServerDescription;
-class ColourConversion;
-class ColourConversionDialog;
+class PresetColourConversion;
+class PresetColourConversionDialog;
 class ServerDialog;
 
 /** @class ConfigDialog
@@ -71,7 +71,7 @@ private:
        wxNotebook* _notebook;
        wxPanel* _misc_panel;
        wxPanel* _tms_panel;
-       EditableList<ColourConversion, ColourConversionDialog>* _colour_conversions_panel;
+       EditableList<PresetColourConversion, PresetColourConversionDialog>* _colour_conversions_panel;
        EditableList<ServerDescription, ServerDialog>* _servers_panel;
        wxPanel* _metadata_panel;
        wxCheckBox* _set_language;
diff --git a/src/wx/content_colour_conversion_dialog.cc b/src/wx/content_colour_conversion_dialog.cc
new file mode 100644 (file)
index 0000000..8fca090
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+    Copyright (C) 2013 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
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <wx/statline.h>
+#include "lib/colour_conversion.h"
+#include "lib/config.h"
+#include "wx_util.h"
+#include "content_colour_conversion_dialog.h"
+#include "colour_conversion_editor.h"
+
+using std::string;
+using std::vector;
+using std::cout;
+using boost::optional;
+
+ContentColourConversionDialog::ContentColourConversionDialog (wxWindow* parent)
+       : wxDialog (parent, wxID_ANY, _("Colour conversion"))
+       , _editor (new ColourConversionEditor (this))
+       , _setting (false)
+{
+       wxBoxSizer* overall_sizer = new wxBoxSizer (wxVERTICAL);
+       SetSizer (overall_sizer);
+
+       wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
+       _preset_check = new wxCheckBox (this, wxID_ANY, _("Use preset"));
+       table->Add (_preset_check, 0, wxALIGN_CENTER_VERTICAL);
+       _preset_choice = new wxChoice (this, wxID_ANY);
+       table->Add (_preset_choice);
+
+       overall_sizer->Add (table, 1, wxEXPAND | wxALL, DCPOMATIC_DIALOG_BORDER);
+       overall_sizer->Add (new wxStaticLine (this, wxID_ANY));
+       overall_sizer->Add (_editor);
+
+       wxSizer* buttons = CreateSeparatedButtonSizer (wxOK);
+       if (buttons) {
+               overall_sizer->Add (buttons, wxSizerFlags().Expand().DoubleBorder());
+       }
+
+       overall_sizer->Layout ();
+       overall_sizer->SetSizeHints (this);
+
+       _preset_check->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&ContentColourConversionDialog::preset_check_clicked, this));
+       _preset_choice->Bind (wxEVT_COMMAND_CHOICE_SELECTED, boost::bind (&ContentColourConversionDialog::preset_choice_changed, this));
+
+       _editor->Changed.connect (boost::bind (&ContentColourConversionDialog::check_for_preset, this));
+
+       vector<PresetColourConversion> presets = Config::instance()->colour_conversions ();
+       for (vector<PresetColourConversion>::const_iterator i = presets.begin(); i != presets.end(); ++i) {
+               _preset_choice->Append (std_to_wx (i->name));
+       }
+}
+
+ColourConversion
+ContentColourConversionDialog::get () const
+{
+       return _editor->get ();
+}
+
+void
+ContentColourConversionDialog::set (ColourConversion c)
+{
+       _setting = true;
+       _editor->set (c);
+       _setting = false;
+       
+       check_for_preset ();
+}
+
+void
+ContentColourConversionDialog::check_for_preset ()
+{
+       if (_setting) {
+               return;
+       }
+       
+       optional<size_t> preset = _editor->get().preset ();
+
+       _preset_check->SetValue (preset);
+       _preset_choice->Enable (preset);
+       _preset_choice->SetSelection (preset.get_value_or (-1));
+}
+
+void
+ContentColourConversionDialog::preset_check_clicked ()
+{
+       if (_preset_check->GetValue ()) {
+               _preset_choice->SetSelection (0);
+               preset_choice_changed ();
+       } else {
+               _preset_choice->SetSelection (-1);
+               _preset_choice->Enable (false);
+       }
+}
+
+void
+ContentColourConversionDialog::preset_choice_changed ()
+{
+       vector<PresetColourConversion> presets = Config::instance()->colour_conversions ();
+       int const s = _preset_choice->GetSelection();
+       if (s != -1) {
+               set (presets[s].conversion);
+       }
+}
+
+       
diff --git a/src/wx/content_colour_conversion_dialog.h b/src/wx/content_colour_conversion_dialog.h
new file mode 100644 (file)
index 0000000..e6069f1
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+    Copyright (C) 2013 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
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <wx/wx.h>
+
+class ColourConversionEditor;
+
+class ContentColourConversionDialog : public wxDialog
+{
+public:
+       ContentColourConversionDialog (wxWindow *);
+
+       void set (ColourConversion);
+       ColourConversion get () const;
+
+private:
+       void check_for_preset ();
+       void preset_check_clicked ();
+       void preset_choice_changed ();
+       
+       wxCheckBox* _preset_check;
+       wxChoice* _preset_choice;
+       ColourConversionEditor* _editor;
+       bool _setting;
+};
index 32cc326b69b4fbc2949642690c1920dec8e00ae6..5eb46e80d11caabe372df5b399d776f8d1d1fdf8 100644 (file)
@@ -26,9 +26,9 @@ public:
        EditableList (
                wxWindow* parent,
                std::vector<std::string> columns,
-               boost::function<std::vector<boost::shared_ptr<T> > ()> get,
-               boost::function<void (std::vector<boost::shared_ptr<T> >)> set,
-               boost::function<std::string (boost::shared_ptr<T>, int)> column
+               boost::function<std::vector<T> ()> get,
+               boost::function<void (std::vector<T>)> set,
+               boost::function<std::string (T, int)> column
                )
                : wxPanel (parent)
                , _get (get)
@@ -66,8 +66,8 @@ public:
                        table->Add (s, 0);
                }
 
-               std::vector<boost::shared_ptr<T> > current = _get ();
-               for (typename std::vector<boost::shared_ptr<T> >::iterator i = current.begin (); i != current.end(); ++i) {
+               std::vector<T> current = _get ();
+               for (typename std::vector<T>::iterator i = current.begin (); i != current.end(); ++i) {
                        add_to_control (*i);
                }
 
@@ -77,10 +77,14 @@ public:
 
                _list->Bind (wxEVT_COMMAND_LIST_ITEM_SELECTED, boost::bind (&EditableList::selection_changed, this));
                _list->Bind (wxEVT_COMMAND_LIST_ITEM_DESELECTED, boost::bind (&EditableList::selection_changed, this));
+               _list->Bind (wxEVT_SIZE, boost::bind (&EditableList::resized, this, _1));
                selection_changed ();
+
        }
 
-       void add_to_control (boost::shared_ptr<T> item)
+private:       
+
+       void add_to_control (T item)
        {
                wxListItem list_item;
                int const n = _list->GetItemCount ();
@@ -101,15 +105,18 @@ public:
 
        void add_clicked ()
        {
-               boost::shared_ptr<T> new_item (new T);
-               S* dialog = new S (this, new_item);
+               T new_item;
+               S* dialog = new S (this);
+               dialog->set (new_item);
                dialog->ShowModal ();
-               dialog->Destroy ();
 
-               add_to_control (new_item);
-               std::vector<boost::shared_ptr<T> > all = _get ();
-               all.push_back (new_item);
+               add_to_control (dialog->get ());
+               
+               std::vector<T> all = _get ();
+               all.push_back (dialog->get ());
                _set (all);
+               
+               dialog->Destroy ();
        }
 
        void edit_clicked ()
@@ -119,13 +126,15 @@ public:
                        return;
                }
 
-               std::vector<boost::shared_ptr<T> > all = _get ();
+               std::vector<T> all = _get ();
                assert (item >= 0 && item < int (all.size ()));
 
-               S* dialog = new S (this, all[item]);
+               S* dialog = new S (this);
+               dialog->set (all[item]);
                dialog->ShowModal ();
+               all[item] = dialog->get ();
                dialog->Destroy ();
-
+               
                for (int i = 0; i < _columns; ++i) {
                        _list->SetItem (item, i, std_to_wx (_column (all[item], i)));
                }
@@ -138,16 +147,24 @@ public:
                        _list->DeleteItem (i);
                }
                
-               std::vector<boost::shared_ptr<T> > all = _get ();
+               std::vector<T> all = _get ();
                all.erase (all.begin() + i);
                _set (all);
        }
 
-private:       
-       boost::function <std::vector<boost::shared_ptr<T> > ()> _get;
-       boost::function <void (std::vector<boost::shared_ptr<T> >)> _set;
+       void resized (wxSizeEvent& ev)
+       {
+               int const w = GetSize().GetWidth() / _columns;
+               for (int i = 0; i < _columns; ++i) {
+                       _list->SetColumnWidth (i, w);
+               }
+               ev.Skip ();
+       }
+
+       boost::function <std::vector<T> ()> _get;
+       boost::function <void (std::vector<T>)> _set;
        int _columns;
-       boost::function<std::string (boost::shared_ptr<T>, int)> _column;
+       boost::function<std::string (T, int)> _column;
 
        wxButton* _add;
        wxButton* _edit;
index 812da88bfe36b61512e60c5d24d5014b4172e686..28c315a969b61d126b89d4cbe49f4f26ffb13951 100644 (file)
@@ -741,6 +741,7 @@ FilmEditor::content_selection_changed ()
        film_content_changed (s, VideoContentProperty::VIDEO_CROP);
        film_content_changed (s, VideoContentProperty::VIDEO_RATIO);
        film_content_changed (s, VideoContentProperty::VIDEO_FRAME_TYPE);
+       film_content_changed (s, VideoContentProperty::COLOUR_CONVERSION);
        film_content_changed (s, AudioContentProperty::AUDIO_GAIN);
        film_content_changed (s, AudioContentProperty::AUDIO_DELAY);
        film_content_changed (s, AudioContentProperty::AUDIO_MAPPING);
index 2abe53026532aff7a42c54862132067898cdfccc..13907ae0cb9c468b63b88715b29d2f7ece4a6d46 100644 (file)
 
 #include "lib/film.h"
 #include "filter_dialog.h"
-#include "filter_view.h"
+#include "filter_editor.h"
 
 using namespace std;
 using boost::bind;
 
 FilterDialog::FilterDialog (wxWindow* parent, vector<Filter const *> const & f)
        : wxDialog (parent, wxID_ANY, wxString (_("Filters")))
-       , _filters (new FilterView (this, f))
+       , _filters (new FilterEditor (this, f))
 {
        wxBoxSizer* sizer = new wxBoxSizer (wxVERTICAL);
        sizer->Add (_filters, 1, wxEXPAND | wxALL, 6);
index 6f8b1dd1caf06497c13af4d304d5fa736f7988b4..d54e6f2e452c6c047dfc2cfb970eb668690142b7 100644 (file)
@@ -25,7 +25,7 @@
 #include <boost/signals2.hpp>
 
 class Film;
-class FilterView;
+class FilterEditor;
 class Filter;
 
 /** @class FilterDialog
@@ -41,5 +41,5 @@ public:
 private:
        void active_changed ();
        
-       FilterView* _filters;
+       FilterEditor* _filters;
 };
diff --git a/src/wx/filter_editor.cc b/src/wx/filter_editor.cc
new file mode 100644 (file)
index 0000000..4dd1800
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+    Copyright (C) 2012 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
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+/** @file  src/filter_editor.cc
+ *  @brief A panel to select FFmpeg filters.
+ */
+
+#include <iostream>
+#include <algorithm>
+#include "lib/filter.h"
+#include "filter_editor.h"
+#include "wx_util.h"
+
+using namespace std;
+
+FilterEditor::FilterEditor (wxWindow* parent, vector<Filter const *> const & active)
+       : wxPanel (parent)
+{
+       wxBoxSizer* sizer = new wxBoxSizer (wxVERTICAL);
+       SetSizer (sizer);
+       
+       vector<Filter const *> filters = Filter::all ();
+
+       typedef map<string, list<Filter const *> > CategoryMap;
+       CategoryMap categories;
+
+       for (vector<Filter const *>::iterator i = filters.begin(); i != filters.end(); ++i) {
+               CategoryMap::iterator j = categories.find ((*i)->category ());
+               if (j == categories.end ()) {
+                       list<Filter const *> c;
+                       c.push_back (*i);
+                       categories[(*i)->category()] = c;
+               } else {
+                       j->second.push_back (*i);
+               }
+       }
+
+       for (CategoryMap::iterator i = categories.begin(); i != categories.end(); ++i) {
+
+               wxStaticText* c = new wxStaticText (this, wxID_ANY, std_to_wx (i->first));
+               wxFont font = c->GetFont();
+               font.SetWeight(wxFONTWEIGHT_BOLD);
+               c->SetFont(font);
+               sizer->Add (c);
+
+               for (list<Filter const *>::iterator j = i->second.begin(); j != i->second.end(); ++j) {
+                       wxCheckBox* b = new wxCheckBox (this, wxID_ANY, std_to_wx ((*j)->name ()));
+                       bool const a = find (active.begin(), active.end(), *j) != active.end ();
+                       b->SetValue (a);
+                       _filters[*j] = b;
+                       b->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&FilterEditor::filter_toggled, this));
+                       sizer->Add (b);
+               }
+
+               sizer->AddSpacer (6);
+       }
+}
+
+void
+FilterEditor::filter_toggled ()
+{
+       ActiveChanged ();
+}
+
+vector<Filter const*>
+FilterEditor::active () const
+{
+       vector<Filter const *> active;
+       for (map<Filter const *, wxCheckBox*>::const_iterator i = _filters.begin(); i != _filters.end(); ++i) {
+               if (i->second->IsChecked ()) {
+                       active.push_back (i->first);
+               }
+       }
+
+       return active;
+}
diff --git a/src/wx/filter_editor.h b/src/wx/filter_editor.h
new file mode 100644 (file)
index 0000000..4e1d682
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+    Copyright (C) 2012 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
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+/** @file  src/filter_editor.h
+ *  @brief A panel to select FFmpeg filters.
+ */
+
+#include <boost/signals2.hpp>
+#include <vector>
+#include <map>
+#include <wx/wx.h>
+
+class Filter;
+
+/** @class FilterEditor
+ *  @brief A panel to select FFmpeg filters.
+ */
+class FilterEditor : public wxPanel
+{
+public:
+       FilterEditor (wxWindow *, std::vector<Filter const *> const &);
+
+       std::vector<Filter const *> active () const;
+
+       boost::signals2::signal<void()> ActiveChanged;
+
+private:
+       void filter_toggled ();
+
+       std::map<Filter const *, wxCheckBox *> _filters;
+};
diff --git a/src/wx/filter_view.cc b/src/wx/filter_view.cc
deleted file mode 100644 (file)
index 757daf3..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
-    Copyright (C) 2012 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
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-/** @file  src/filter_view.cc
- *  @brief A panel to select FFmpeg filters.
- */
-
-#include <iostream>
-#include <algorithm>
-#include "lib/filter.h"
-#include "filter_view.h"
-#include "wx_util.h"
-
-using namespace std;
-
-FilterView::FilterView (wxWindow* parent, vector<Filter const *> const & active)
-       : wxPanel (parent)
-{
-       wxBoxSizer* sizer = new wxBoxSizer (wxVERTICAL);
-       SetSizer (sizer);
-       
-       vector<Filter const *> filters = Filter::all ();
-
-       typedef map<string, list<Filter const *> > CategoryMap;
-       CategoryMap categories;
-
-       for (vector<Filter const *>::iterator i = filters.begin(); i != filters.end(); ++i) {
-               CategoryMap::iterator j = categories.find ((*i)->category ());
-               if (j == categories.end ()) {
-                       list<Filter const *> c;
-                       c.push_back (*i);
-                       categories[(*i)->category()] = c;
-               } else {
-                       j->second.push_back (*i);
-               }
-       }
-
-       for (CategoryMap::iterator i = categories.begin(); i != categories.end(); ++i) {
-
-               wxStaticText* c = new wxStaticText (this, wxID_ANY, std_to_wx (i->first));
-               wxFont font = c->GetFont();
-               font.SetWeight(wxFONTWEIGHT_BOLD);
-               c->SetFont(font);
-               sizer->Add (c);
-
-               for (list<Filter const *>::iterator j = i->second.begin(); j != i->second.end(); ++j) {
-                       wxCheckBox* b = new wxCheckBox (this, wxID_ANY, std_to_wx ((*j)->name ()));
-                       bool const a = find (active.begin(), active.end(), *j) != active.end ();
-                       b->SetValue (a);
-                       _filters[*j] = b;
-                       b->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&FilterView::filter_toggled, this));
-                       sizer->Add (b);
-               }
-
-               sizer->AddSpacer (6);
-       }
-}
-
-void
-FilterView::filter_toggled ()
-{
-       ActiveChanged ();
-}
-
-vector<Filter const*>
-FilterView::active () const
-{
-       vector<Filter const *> active;
-       for (map<Filter const *, wxCheckBox*>::const_iterator i = _filters.begin(); i != _filters.end(); ++i) {
-               if (i->second->IsChecked ()) {
-                       active.push_back (i->first);
-               }
-       }
-
-       return active;
-}
diff --git a/src/wx/filter_view.h b/src/wx/filter_view.h
deleted file mode 100644 (file)
index 7fbef84..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
-    Copyright (C) 2012 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
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-/** @file  src/filter_view.h
- *  @brief A panel to select FFmpeg filters.
- */
-
-#include <boost/signals2.hpp>
-#include <vector>
-#include <map>
-#include <wx/wx.h>
-
-class Filter;
-
-/** @class FilterView
- *  @brief A panel to select FFmpeg filters.
- */
-class FilterView : public wxPanel
-{
-public:
-       FilterView (wxWindow *, std::vector<Filter const *> const &);
-
-       std::vector<Filter const *> active () const;
-
-       boost::signals2::signal<void()> ActiveChanged;
-
-private:
-       void filter_toggled ();
-
-       std::map<Filter const *, wxCheckBox *> _filters;
-};
diff --git a/src/wx/preset_colour_conversion_dialog.cc b/src/wx/preset_colour_conversion_dialog.cc
new file mode 100644 (file)
index 0000000..8c4a6db
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+    Copyright (C) 2013 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
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <wx/statline.h>
+#include "lib/colour_conversion.h"
+#include "wx_util.h"
+#include "preset_colour_conversion_dialog.h"
+#include "colour_conversion_editor.h"
+
+using std::string;
+using std::cout;
+
+PresetColourConversionDialog::PresetColourConversionDialog (wxWindow* parent)
+       : wxDialog (parent, wxID_ANY, _("Colour conversion"))
+       , _editor (new ColourConversionEditor (this))
+{
+       wxBoxSizer* overall_sizer = new wxBoxSizer (wxVERTICAL);
+       SetSizer (overall_sizer);
+
+       wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
+       add_label_to_sizer (table, this, _("Name"), true);
+       _name = new wxTextCtrl (this, wxID_ANY, wxT (""));
+       table->Add (_name);
+
+       overall_sizer->Add (table, 1, wxEXPAND | wxALL, DCPOMATIC_DIALOG_BORDER);
+       overall_sizer->Add (new wxStaticLine (this, wxID_ANY));
+       overall_sizer->Add (_editor);
+
+       wxSizer* buttons = CreateSeparatedButtonSizer (wxOK);
+       if (buttons) {
+               overall_sizer->Add (buttons, wxSizerFlags().Expand().DoubleBorder());
+       }
+
+       overall_sizer->Layout ();
+       overall_sizer->SetSizeHints (this);
+}
+
+PresetColourConversion
+PresetColourConversionDialog::get () const
+{
+       PresetColourConversion pc;
+       pc.name = wx_to_std (_name->GetValue ());
+       pc.conversion = _editor->get ();
+       return pc;
+}
+
+void
+PresetColourConversionDialog::set (PresetColourConversion c)
+{
+       _name->SetValue (std_to_wx (c.name));
+       _editor->set (c.conversion);
+}
diff --git a/src/wx/preset_colour_conversion_dialog.h b/src/wx/preset_colour_conversion_dialog.h
new file mode 100644 (file)
index 0000000..4e61239
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+    Copyright (C) 2013 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
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <wx/wx.h>
+
+class ColourConversionEditor;
+
+class PresetColourConversionDialog : public wxDialog
+{
+public:
+       PresetColourConversionDialog (wxWindow *);
+
+       void set (PresetColourConversion);
+       PresetColourConversion get () const;
+
+private:
+       wxTextCtrl* _name;
+       ColourConversionEditor* _editor;
+};
index a0f1f04aea49098fd53492d270d9f4a452c686cd..31b3ce5dc5ee85da3286dd11a7303a33fee790c3 100644 (file)
 
 using boost::shared_ptr;
 
-ServerDialog::ServerDialog (wxWindow* parent, shared_ptr<ServerDescription> server)
+ServerDialog::ServerDialog (wxWindow* parent)
        : wxDialog (parent, wxID_ANY, _("Server"))
 {
-       if (server) {
-               _server = server;
-       } else {
-               _server.reset (new ServerDescription (wx_to_std (N_("localhost")), 1));
-       }
-               
        wxFlexGridSizer* table = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
        table->AddGrowableCol (1, 1);
 
@@ -43,12 +37,7 @@ ServerDialog::ServerDialog (wxWindow* parent, shared_ptr<ServerDescription> serv
        _threads = new wxSpinCtrl (this, wxID_ANY);
        table->Add (_threads, 1, wxEXPAND);
 
-       _host->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&ServerDialog::host_changed, this));
        _threads->SetRange (0, 256);
-       _threads->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&ServerDialog::threads_changed, this));
-
-       _host->SetValue (std_to_wx (_server->host_name ()));
-       _threads->SetValue (_server->threads ());
 
        wxBoxSizer* overall_sizer = new wxBoxSizer (wxVERTICAL);
        overall_sizer->Add (table, 1, wxEXPAND | wxALL, 6);
@@ -64,20 +53,18 @@ ServerDialog::ServerDialog (wxWindow* parent, shared_ptr<ServerDescription> serv
 }
 
 void
-ServerDialog::host_changed ()
-{
-       _server->set_host_name (wx_to_std (_host->GetValue ()));
-}
-
-void
-ServerDialog::threads_changed ()
+ServerDialog::set (ServerDescription server)
 {
-       _server->set_threads (_threads->GetValue ());
+       _host->SetValue (std_to_wx (server.host_name ()));
+       _threads->SetValue (server.threads ());
 }
 
-shared_ptr<ServerDescription>
-ServerDialog::server () const
+ServerDescription
+ServerDialog::get () const
 {
-       return _server;
+       ServerDescription server;
+       server.set_host_name (wx_to_std (_host->GetValue ()));
+       server.set_threads (_threads->GetValue ());
+       return server;
 }
 
index 3f1fa1f73021fb32bbc3c20d7e312163116326e1..a6f48fe7b71a5e82d296bff1ad3ed55ae329680b 100644 (file)
@@ -25,15 +25,12 @@ class ServerDescription;
 class ServerDialog : public wxDialog
 {
 public:
-       ServerDialog (wxWindow *, boost::shared_ptr<ServerDescription>);
+       ServerDialog (wxWindow *);
 
-       boost::shared_ptr<ServerDescription> server () const;
+       void set (ServerDescription);
+       ServerDescription get () const;
 
 private:
-       void host_changed ();
-       void threads_changed ();
-
-       boost::shared_ptr<ServerDescription> _server;
        wxTextCtrl* _host;
        wxSpinCtrl* _threads;
 };
index 5ba06b12d45196fe41bc4e9577d0f4a3ceb19f57..bb8476d63b7bbdf1d39624ac28f38b9f29ed887b 100644 (file)
@@ -27,6 +27,7 @@
 #include "video_panel.h"
 #include "wx_util.h"
 #include "film_editor.h"
+#include "content_colour_conversion_dialog.h"
 
 using std::vector;
 using std::string;
@@ -36,6 +37,7 @@ using std::list;
 using boost::shared_ptr;
 using boost::dynamic_pointer_cast;
 using boost::bind;
+using boost::optional;
 
 VideoPanel::VideoPanel (FilmEditor* e)
        : FilmEditorPanel (e, _("Video"))
@@ -78,17 +80,34 @@ VideoPanel::VideoPanel (FilmEditor* e)
        {
                add_label_to_grid_bag_sizer (grid, this, _("Filters"), true, wxGBPosition (r, 0));
                wxSizer* s = new wxBoxSizer (wxHORIZONTAL);
-               _filters = new wxStaticText (this, wxID_ANY, _("None"));
+
+               wxClientDC dc (this);
+               wxSize size = dc.GetTextExtent (wxT ("A quite long name"));
+               size.SetHeight (-1);
+               
+               _filters = new wxStaticText (this, wxID_ANY, _("None"), wxDefaultPosition, size);
                s->Add (_filters, 1, wxEXPAND | wxALIGN_CENTER_VERTICAL | wxTOP | wxBOTTOM | wxRIGHT, 6);
                _filters_button = new wxButton (this, wxID_ANY, _("Edit..."));
                s->Add (_filters_button, 0, wxALIGN_CENTER_VERTICAL);
                grid->Add (s, wxGBPosition (r, 1), wxDefaultSpan, wxALIGN_CENTER_VERTICAL);
        }
        ++r;
+       
+       {
+               add_label_to_grid_bag_sizer (grid, this, _("Colour conversion"), true, wxGBPosition (r, 0));
+               wxSizer* s = new wxBoxSizer (wxHORIZONTAL);
 
-       add_label_to_grid_bag_sizer (grid, this, _("Colour conversion"), true, wxGBPosition (r, 0));
-       _colour_conversion = new wxChoice (this, wxID_ANY);
-       grid->Add (_colour_conversion, wxGBPosition (r, 1));
+               wxClientDC dc (this);
+               wxSize size = dc.GetTextExtent (wxT ("A quite long name"));
+               size.SetHeight (-1);
+               
+               _colour_conversion = new wxStaticText (this, wxID_ANY, wxT (""), wxDefaultPosition, size);
+
+               s->Add (_colour_conversion, 1, wxEXPAND | wxALIGN_CENTER_VERTICAL | wxTOP | wxBOTTOM | wxRIGHT, 6);
+               _colour_conversion_button = new wxButton (this, wxID_ANY, _("Edit..."));
+               s->Add (_colour_conversion_button, 0, wxALIGN_CENTER_VERTICAL);
+               grid->Add (s, wxGBPosition (r, 1), wxDefaultSpan, wxALIGN_CENTER_VERTICAL);
+       }
        ++r;
 
        _description = new wxStaticText (this, wxID_ANY, wxT ("\n \n \n \n \n"), wxDefaultPosition, wxDefaultSize);
@@ -113,16 +132,14 @@ VideoPanel::VideoPanel (FilmEditor* e)
        _frame_type->Append (_("2D"));
        _frame_type->Append (_("3D left/right"));
 
-       setup_colour_conversions ();
-
-       _frame_type->Bind        (wxEVT_COMMAND_CHOICE_SELECTED,  boost::bind (&VideoPanel::frame_type_changed, this));
-       _left_crop->Bind         (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&VideoPanel::left_crop_changed, this));
-       _right_crop->Bind        (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&VideoPanel::right_crop_changed, this));
-       _top_crop->Bind          (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&VideoPanel::top_crop_changed, this));
-       _bottom_crop->Bind       (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&VideoPanel::bottom_crop_changed, this));
-       _ratio->Bind             (wxEVT_COMMAND_CHOICE_SELECTED,  boost::bind (&VideoPanel::ratio_changed, this));
-       _filters_button->Bind    (wxEVT_COMMAND_BUTTON_CLICKED,   boost::bind (&VideoPanel::edit_filters_clicked, this));
-       _colour_conversion->Bind (wxEVT_COMMAND_CHOICE_SELECTED,  boost::bind (&VideoPanel::colour_conversion_changed, this));
+       _frame_type->Bind               (wxEVT_COMMAND_CHOICE_SELECTED,  boost::bind (&VideoPanel::frame_type_changed, this));
+       _left_crop->Bind                (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&VideoPanel::left_crop_changed, this));
+       _right_crop->Bind               (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&VideoPanel::right_crop_changed, this));
+       _top_crop->Bind                 (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&VideoPanel::top_crop_changed, this));
+       _bottom_crop->Bind              (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&VideoPanel::bottom_crop_changed, this));
+       _ratio->Bind                    (wxEVT_COMMAND_CHOICE_SELECTED,  boost::bind (&VideoPanel::ratio_changed, this));
+       _filters_button->Bind           (wxEVT_COMMAND_BUTTON_CLICKED,   boost::bind (&VideoPanel::edit_filters_clicked, this));
+       _colour_conversion_button->Bind (wxEVT_COMMAND_BUTTON_CLICKED,   boost::bind (&VideoPanel::edit_colour_conversion_clicked, this));
 }
 
 
@@ -223,6 +240,10 @@ VideoPanel::film_content_changed (shared_ptr<Content> c, int property)
                setup_description ();
        } else if (property == VideoContentProperty::VIDEO_FRAME_RATE) {
                setup_description ();
+       } else if (property == VideoContentProperty::COLOUR_CONVERSION) {
+               optional<size_t> preset = vc ? vc->colour_conversion().preset () : optional<size_t> ();
+               vector<PresetColourConversion> cc = Config::instance()->colour_conversions ();
+               _colour_conversion->SetLabel (preset ? std_to_wx (cc[preset.get()].name) : _("Custom"));
        } else if (property == FFmpegContentProperty::FILTERS) {
                if (fc) {
                        pair<string, string> p = Filter::ffmpeg_strings (fc->filters ());
@@ -355,16 +376,18 @@ VideoPanel::frame_type_changed ()
 }
 
 void
-VideoPanel::setup_colour_conversions ()
+VideoPanel::edit_colour_conversion_clicked ()
 {
-       vector<shared_ptr<ColourConversion> > cc = Config::instance()->colour_conversions ();
-       for (vector<shared_ptr<ColourConversion> >::iterator i = cc.begin(); i != cc.end(); ++i) {
-               _colour_conversion->Append (std_to_wx ((*i)->name));
+       shared_ptr<VideoContent> vc = _editor->selected_video_content ();
+       if (!vc) {
+               return;
        }
-}
 
-void
-VideoPanel::colour_conversion_changed ()
-{
+       ColourConversion conversion = vc->colour_conversion ();
+       ContentColourConversionDialog* d = new ContentColourConversionDialog (this);
+       d->set (conversion);
+       d->ShowModal ();
 
+       vc->set_colour_conversion (d->get ());
+       d->Destroy ();
 }
index 62332a0520ae13c8985638c26f22a4e5f6eefcf1..2ecf3c87f449135756c21e280c439cc63abeb6ce 100644 (file)
@@ -41,10 +41,9 @@ private:
        void edit_filters_clicked ();
        void ratio_changed ();
        void frame_type_changed ();
-       void colour_conversion_changed ();
+       void edit_colour_conversion_clicked ();
 
        void setup_description ();
-       void setup_colour_conversions ();
 
        wxChoice* _frame_type;
        wxSpinCtrl* _left_crop;
@@ -56,5 +55,6 @@ private:
        wxStaticText* _description;
        wxStaticText* _filters;
        wxButton* _filters_button;
-       wxChoice* _colour_conversion;
+       wxStaticText* _colour_conversion;
+       wxButton* _colour_conversion_button;
 };
index e0566a6ed8deeb138ff57b238df01c43702fa40a..9c3ecdd71eacf10f9cc682055cfe66bc7eb94e86 100644 (file)
@@ -9,8 +9,9 @@ sources = """
           audio_mapping_view.cc
           audio_panel.cc
           audio_plot.cc
-          colour_conversion_dialog.cc
+          colour_conversion_editor.cc
           config_dialog.cc
+          content_colour_conversion_dialog.cc
           content_menu.cc
           dci_metadata_dialog.cc
           dir_picker_ctrl.cc
@@ -18,11 +19,12 @@ sources = """
           film_editor_panel.cc
           film_viewer.cc
           filter_dialog.cc
-          filter_view.cc
+          filter_editor.cc
           gain_calculator_dialog.cc
           job_manager_view.cc
           job_wrapper.cc
           new_film_dialog.cc
+          preset_colour_conversion_dialog.cc
           properties_dialog.cc
           repeat_dialog.cc
           server_dialog.cc
index d695f96ce182b3f15cba8a57d69836b83e2311e2..7faf47c4158a72e5c86d88c37051a3b827f0cb12 100644 (file)
@@ -29,7 +29,7 @@ using boost::shared_ptr;
 using boost::thread;
 
 void
-do_remote_encode (shared_ptr<DCPVideoFrame> frame, shared_ptr<ServerDescription> description, shared_ptr<EncodedData> locally_encoded)
+do_remote_encode (shared_ptr<DCPVideoFrame> frame, ServerDescription description, shared_ptr<EncodedData> locally_encoded)
 {
        shared_ptr<EncodedData> remotely_encoded;
        BOOST_CHECK_NO_THROW (remotely_encoded = frame->encode_remotely (description));
@@ -92,7 +92,7 @@ BOOST_AUTO_TEST_CASE (client_server_test)
        /* Let the server get itself ready */
        dcpomatic_sleep (1);
 
-       shared_ptr<ServerDescription> description (new ServerDescription ("localhost", 2));
+       ServerDescription description ("localhost", 2);
 
        list<thread*> threads;
        for (int i = 0; i < 8; ++i) {
index 21cf18c76e82678e8495c22d8849670344a06a7c..1c7b7e245c11e967cf59dd8f02e497aa67cd3212 100644 (file)
@@ -46,7 +46,7 @@ struct TestConfig
                dcpomatic_setup();
 
                Config::instance()->set_num_local_encoding_threads (1);
-               Config::instance()->set_servers (vector<shared_ptr<ServerDescription> > ());
+               Config::instance()->set_servers (vector<ServerDescription> ());
                Config::instance()->set_server_port (61920);
                Config::instance()->set_default_dci_metadata (DCIMetadata ());
                Config::instance()->set_default_container (static_cast<Ratio*> (0));