+2016-02-18 c.hetherington <cth@carlh.net>
+
+ * Add some more information to the content properties
+ dialogue (#791).
+
2016-02-17 Carl Hetherington <cth@carlh.net>
* Store cinema / screen certificates in a separate
}
void
-AudioContent::add_properties (list<pair<string, string> >& p) const
+AudioContent::add_properties (list<UserProperty>& p) const
{
- p.push_back (make_pair (_("DCP audio frame rate"), raw_convert<string> (resampled_audio_frame_rate ())));
+ shared_ptr<const AudioStream> stream;
+ if (audio_streams().size() == 1) {
+ stream = audio_streams().front ();
+ }
+
+ if (stream) {
+ p.push_back (UserProperty (_("Audio"), _("Channels"), stream->channels ()));
+ p.push_back (UserProperty (_("Audio"), _("Content audio frame rate"), stream->frame_rate(), _("Hz")));
+ }
+
+ shared_ptr<const Film> film = _film.lock ();
+ DCPOMATIC_ASSERT (film);
+
+ FrameRateChange const frc = film->active_frame_rate_change (position ());
+ ContentTime const c (full_length(), frc);
+
+ p.push_back (
+ UserProperty (_("Length"), _("Full length in video frames at content rate"), c.frames_round(frc.source))
+ );
+
+ if (stream) {
+ p.push_back (
+ UserProperty (
+ _("Length"),
+ _("Full length in audio frames at content rate"),
+ c.frames_round (stream->frame_rate ())
+ )
+ );
+ }
+
+ p.push_back (UserProperty (_("Audio"), _("DCP frame rate"), resampled_audio_frame_rate ()));
+ p.push_back (UserProperty (_("Length"), _("Full length in video frames at DCP rate"), c.frames_round (frc.dcp)));
+
+ if (stream) {
+ p.push_back (
+ UserProperty (
+ _("Length"),
+ _("Full length in audio frames at DCP rate"),
+ c.frames_round (resampled_audio_frame_rate ())
+ )
+ );
+ }
}
protected:
- void add_properties (std::list<std::pair<std::string, std::string> > &) const;
+ void add_properties (std::list<UserProperty> &) const;
private:
/** Gain to apply to audio in dB */
return s;
}
-/** @return a list of properties that might be interesting to the user; first string is the property name,
- * second is the value.
- */
-list<pair<string, string> >
-Content::properties () const
+/** @return a list of properties that might be interesting to the user */
+list<Content::UserProperty>
+Content::user_properties () const
{
- list<pair<string, string> > p;
+ list<UserProperty> p;
add_properties (p);
return p;
}
#include "types.h"
#include "signaller.h"
#include "dcpomatic_time.h"
+#include "raw_convert.h"
#include <libcxml/cxml.h>
#include <boost/filesystem.hpp>
#include <boost/signals2.hpp>
*/
virtual std::list<DCPTime> reel_split_points () const;
- std::list<std::pair<std::string, std::string> > properties () const;
-
boost::shared_ptr<Content> clone () const;
void set_path (boost::filesystem::path);
boost::shared_ptr<const Film> film () const;
+ class UserProperty
+ {
+ public:
+ template <class T>
+ UserProperty (std::string category_, std::string key_, T value_, std::string unit_ = "")
+ : category (category_)
+ , key (key_)
+ , value (raw_convert<std::string> (value_))
+ , unit (unit_)
+ {}
+
+ std::string category;
+ std::string key;
+ std::string value;
+ std::string unit;
+ };
+
+ std::list<UserProperty> user_properties () const;
+
boost::signals2::signal<void (boost::weak_ptr<Content>, int, bool)> Changed;
protected:
void signal_changed (int);
- virtual void add_properties (std::list<std::pair<std::string, std::string> > &) const {}
+
+ virtual void add_properties (std::list<UserProperty> &) const {}
boost::weak_ptr<const Film> _film;
}
void
-DCPContent::add_properties (list<pair<string, string> >& p) const
+DCPContent::add_properties (list<UserProperty>& p) const
{
SingleStreamAudioContent::add_properties (p);
}
bool can_reference_subtitle (std::list<std::string> &) const;
protected:
- void add_properties (std::list<std::pair<std::string, std::string> >& p) const;
+ void add_properties (std::list<UserProperty>& p) const;
private:
void read_directory (boost::filesystem::path);
}
void
-FFmpegContent::add_properties (list<pair<string, string> >& p) const
+FFmpegContent::add_properties (list<UserProperty>& p) const
{
VideoContent::add_properties (p);
AudioContent::add_properties (p);
case AVCOL_RANGE_UNSPECIFIED:
/// TRANSLATORS: this means that the range of pixel values used in this
/// file is unknown (not specified in the file).
- p.push_back (make_pair (_("Colour range"), _("Unspecified")));
+ p.push_back (UserProperty (_("Video"), _("Colour range"), _("Unspecified")));
break;
case AVCOL_RANGE_MPEG:
/// TRANSLATORS: this means that the range of pixel values used in this
/// file is limited, so that not all possible values are valid.
- p.push_back (make_pair (_("Colour range"), String::compose (_("Limited (%1-%2)"), (total - sub) / 2, (total + sub) / 2)));
+ p.push_back (
+ UserProperty (
+ _("Video"), _("Colour range"), String::compose (_("Limited (%1-%2)"), (total - sub) / 2, (total + sub) / 2)
+ )
+ );
break;
case AVCOL_RANGE_JPEG:
/// TRANSLATORS: this means that the range of pixel values used in this
/// file is full, so that all possible pixel values are valid.
- p.push_back (make_pair (_("Colour range"), String::compose (_("Full (0-%1)"), total)));
+ p.push_back (UserProperty (_("Video"), _("Colour range"), String::compose (_("Full (0-%1)"), total)));
break;
default:
DCPOMATIC_ASSERT (false);
case AVCOL_RANGE_UNSPECIFIED:
/// TRANSLATORS: this means that the range of pixel values used in this
/// file is unknown (not specified in the file).
- p.push_back (make_pair (_("Colour range"), _("Unspecified")));
+ p.push_back (UserProperty (_("Video"), _("Colour range"), _("Unspecified")));
break;
case AVCOL_RANGE_MPEG:
/// TRANSLATORS: this means that the range of pixel values used in this
/// file is limited, so that not all possible values are valid.
- p.push_back (make_pair (_("Colour range"), _("Limited")));
+ p.push_back (UserProperty (_("Video"), _("Colour range"), _("Limited")));
break;
case AVCOL_RANGE_JPEG:
/// TRANSLATORS: this means that the range of pixel values used in this
/// file is full, so that all possible pixel values are valid.
- p.push_back (make_pair (_("Colour range"), _("Full")));
+ p.push_back (UserProperty (_("Video"), _("Colour range"), _("Full")));
break;
default:
DCPOMATIC_ASSERT (false);
};
DCPOMATIC_ASSERT (AVCOL_PRI_NB == 10);
- p.push_back (make_pair (_("Colour primaries"), primaries[_color_primaries]));
+ p.push_back (UserProperty (_("Video"), _("Colour primaries"), primaries[_color_primaries]));
char const * transfers[] = {
_("Unspecified"),
};
DCPOMATIC_ASSERT (AVCOL_TRC_NB == 16);
- p.push_back (make_pair (_("Colour transfer characteristic"), transfers[_color_trc]));
+ p.push_back (UserProperty (_("Video"), _("Colour transfer characteristic"), transfers[_color_trc]));
char const * spaces[] = {
_("RGB / sRGB (IEC61966-2-1)"),
};
DCPOMATIC_ASSERT (AVCOL_SPC_NB == 11);
- p.push_back (make_pair (_("Colourspace"), spaces[_colorspace]));
+ p.push_back (UserProperty (_("Video"), _("Colourspace"), spaces[_colorspace]));
if (_bits_per_pixel) {
- p.push_back (make_pair (_("Bits per pixel"), raw_convert<string> (_bits_per_pixel.get ())));
+ p.push_back (UserProperty (_("Video"), _("Bits per pixel"), raw_convert<string> (_bits_per_pixel.get ())));
}
}
std::list<ContentTimePeriod> text_subtitles_during (ContentTimePeriod, bool starting) const;
protected:
- void add_properties (std::list<std::pair<std::string, std::string> > &) const;
+ void add_properties (std::list<UserProperty> &) const;
private:
friend struct ffmpeg_pts_offset_test;
return s;
}
-void
-SingleStreamAudioContent::add_properties (list<pair<string, string> >& p) const
-{
- p.push_back (make_pair (_("Audio channels"), raw_convert<string> (audio_stream()->channels ())));
- p.push_back (make_pair (_("Content audio frame rate"), raw_convert<string> (audio_stream()->frame_rate ())));
-
- AudioContent::add_properties (p);
-}
void take_from_audio_examiner (boost::shared_ptr<AudioExaminer>);
protected:
- void add_properties (std::list<std::pair<std::string, std::string> > &) const;
-
boost::shared_ptr<AudioStream> _audio_stream;
};
}
void
-VideoContent::add_properties (list<pair<string, string> >& p) const
+VideoContent::add_properties (list<UserProperty>& p) const
{
- p.push_back (make_pair (_("Video length"), raw_convert<string> (video_length ()) + " " + _("video frames")));
- p.push_back (make_pair (_("Video size"), raw_convert<string> (video_size().width) + "x" + raw_convert<string> (video_size().height)));
- p.push_back (make_pair (_("Video frame rate"), raw_convert<string> (video_frame_rate()) + " " + _("frames per second")));
+ p.push_back (UserProperty (_("Video"), _("Length"), raw_convert<string> (video_length ()), _("video frames")));
+ p.push_back (UserProperty (_("Video"), _("Size"), raw_convert<string> (video_size().width) + "x" + raw_convert<string> (video_size().height)));
+ p.push_back (UserProperty (_("Video"), _("Frame rate"), raw_convert<string> (video_frame_rate()), _("frames per second")));
}
double
protected:
void take_from_video_examiner (boost::shared_ptr<VideoExaminer>);
- void add_properties (std::list<std::pair<std::string, std::string> > &) const;
+ void add_properties (std::list<UserProperty> &) const;
Frame _video_length;
/** Video frame rate, or not set if this content should use the DCP's frame rate */
#include "lib/audio_content.h"
#include "lib/single_stream_audio_content.h"
#include <boost/algorithm/string.hpp>
+#include <boost/foreach.hpp>
using std::string;
using std::list;
using std::pair;
+using std::map;
using boost::shared_ptr;
using boost::dynamic_pointer_cast;
add (_("Filename"), true);
add (new wxStaticText (this, wxID_ANY, std_to_wx (n)));
- list<pair<string, string> > properties = content->properties ();
- for (list<pair<string, string> >::const_iterator i = properties.begin(); i != properties.end(); ++i) {
- add (std_to_wx (i->first), true);
- add (new wxStaticText (this, wxID_ANY, std_to_wx (i->second)));
+ map<string, list<Content::UserProperty> > grouped;
+ BOOST_FOREACH (Content::UserProperty i, content->user_properties()) {
+ if (grouped.find(i.category) == grouped.end()) {
+ grouped[i.category] = list<Content::UserProperty> ();
+ }
+ grouped[i.category].push_back (i);
+ }
+
+ for (map<string, list<Content::UserProperty> >::const_iterator i = grouped.begin(); i != grouped.end(); ++i) {
+ add (std_to_wx ("<b>" + i->first + "</b>"), false);
+ add_spacer ();
+
+ BOOST_FOREACH (Content::UserProperty j, i->second) {
+ add (std_to_wx (j.key), true);
+ add (new wxStaticText (this, wxID_ANY, std_to_wx (j.value + " " + j.unit)));
+ }
}
layout ();
}
void
+#ifdef DCPOMATIC_OSX
TableDialog::add (wxString text, bool label)
+#else
+TableDialog::add (wxString text, bool)
+#endif
{
- add_label_to_sizer (_table, this, text, label);
+ int flags = wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT;
+#ifdef __WXOSX__
+ if (label) {
+ flags |= wxALIGN_RIGHT;
+ t += wxT (":");
+ }
+#endif
+ wxStaticText* m = new wxStaticText (this, wxID_ANY, wxT (""));
+ m->SetLabelMarkup (text);
+ _table->Add (m, 0, flags, 6);
}
void