+2013-04-28 Carl Hetherington <cth@carlh.net>
+
+ * Version 0.88 released.
+
+2013-04-28 Carl Hetherington <cth@carlh.net>
+
+ * Fix broken external audio support.
+
2013-04-24 Carl Hetherington <cth@carlh.net>
* Allow use of existing empty directories for new films (without
files (such as those from DVDs or Blu-Rays) for presentation on DCI-compliant
digital projectors.
-Package: dvdomatic-dbg
+Package: dcpomatic-dbg
Architecture: i386
Section: debug
Priority: extra
-Depends: ${dvdomatic:Depends}, ${misc:Depends}
-Description: debugging symbols for dvdomatic
- This package contains the debugging symbols for dvdomatic.
+Depends: ${dcpomatic:Depends}, ${misc:Depends}
+Description: debugging symbols for dcpomatic
+ This package contains the debugging symbols for dcpomatic.
files (such as those from DVDs or Blu-Rays) for presentation on DCI-compliant
digital projectors.
-Package: dvdomatic-dbg
+Package: dcpomatic-dbg
Architecture: amd64
Section: debug
Priority: extra
-Depends: ${dvdomatic:Depends}, ${misc:Depends}
-Description: debugging symbols for dvdomatic
- This package contains the debugging symbols for dvdomatic.
+Depends: ${dcpomatic:Depends}, ${misc:Depends}
+Description: debugging symbols for dcpomatic
+ This package contains the debugging symbols for dcpomatic.
files (such as those from DVDs or Blu-Rays) for presentation on DCI-compliant
digital projectors.
-Package: dvdomatic-dbg
+Package: dcpomatic-dbg
Architecture: i386
Section: debug
Priority: extra
-Depends: ${dvdomatic:Depends}, ${misc:Depends}
-Description: debugging symbols for dvdomatic
- This package contains the debugging symbols for dvdomatic.
+Depends: ${dcpomatic:Depends}, ${misc:Depends}
+Description: debugging symbols for dcpomatic
+ This package contains the debugging symbols for dcpomatic.
files (such as those from DVDs or Blu-Rays) for presentation on DCI-compliant
digital projectors.
-Package: dvdomatic-dbg
+Package: dcpomatic-dbg
Architecture: amd64
Section: debug
Priority: extra
-Depends: ${dvdomatic:Depends}, ${misc:Depends}
-Description: debugging symbols for dvdomatic
- This package contains the debugging symbols for dvdomatic.
+Depends: ${dcpomatic:Depends}, ${misc:Depends}
+Description: debugging symbols for dcpomatic
+ This package contains the debugging symbols for dcpomatic.
-dcpomatic (0.84-1) UNRELEASED; urgency=low
+dvdomatic (0.88-1) UNRELEASED; urgency=low
+
+ * New upstream release.
+
+ -- Carl Hetherington <carl@houllier.lan> Sun, 28 Apr 2013 16:28:17 +0100
+
+dvdomatic (0.87-1) UNRELEASED; urgency=low
+
+ * New upstream release.
+
+ -- Carl Hetherington <carl@houllier.lan> Fri, 26 Apr 2013 09:53:27 +0100
+
+dvdomatic (0.86-1) UNRELEASED; urgency=low
+
+ * New upstream release.
+
+ -- Carl Hetherington <carl@houllier.lan> Tue, 23 Apr 2013 08:13:13 +0100
+
+dvdomatic (0.85-1) UNRELEASED; urgency=low
+
+ * New upstream release.
+
+ -- Carl Hetherington <carl@houllier.lan> Tue, 23 Apr 2013 00:08:20 +0100
+
+dvdomatic (0.84-1) UNRELEASED; urgency=low
* New upstream release.
.PHONY: override_dh_strip
override_dh_strip:
- dh_strip --dbg-package=dvdomatic-dbg
+ dh_strip --dbg-package=dcpomatic-dbg
continue;
}
- shared_ptr<const AudioContent> ac = dynamic_pointer_cast<AudioContent> (*j);
+ shared_ptr<const AudioContent> ac = dynamic_pointer_cast<const AudioContent> (*j);
assert (ac);
add (AudioMapping::Channel (ac, (*i)->number_child<int> ("ContentIndex")), static_cast<libdcp::Channel> ((*i)->number_child<int> ("DCP")));
using std::ofstream;
using std::list;
using boost::shared_ptr;
+using boost::lexical_cast;
using boost::optional;
Config* Config::_instance = 0;
, _reference_scaler (Scaler::from_id (N_("bicubic")))
, _tms_path (N_("."))
, _sound_processor (SoundProcessor::from_id (N_("dolby_cp750")))
+ , _default_still_length (10)
{
_allowed_dcp_frame_rates.push_back (24);
_allowed_dcp_frame_rates.push_back (25);
_language = f.optional_string_child ("Language");
_default_dci_metadata = DCIMetadata (f.node_child ("DCIMetadata"));
+ _default_still_length = f.optional_number_child<int>("DefaultStillLength").get_value_or (10);
}
void
xmlpp::Document doc;
xmlpp::Element* root = doc.create_root_node ("Config");
- root->add_child("NumLocalEncodingThreads")->add_child_text (boost::lexical_cast<string> (_num_local_encoding_threads));
+ root->add_child("NumLocalEncodingThreads")->add_child_text (lexical_cast<string> (_num_local_encoding_threads));
root->add_child("DefaultDirectory")->add_child_text (_default_directory);
- root->add_child("ServerPort")->add_child_text (boost::lexical_cast<string> (_server_port));
+ root->add_child("ServerPort")->add_child_text (lexical_cast<string> (_server_port));
if (_reference_scaler) {
root->add_child("ReferenceScaler")->add_child_text (_reference_scaler->id ());
}
_default_dci_metadata.as_xml (root->add_child ("DCIMetadata"));
+ root->add_child("DefaultStillLength")->add_child_text (lexical_cast<string> (_default_still_length));
+
doc.write_to_file_formatted (file (false));
}
return _language;
}
+ int default_still_length () const {
+ return _default_still_length;
+ }
+
/** @param n New number of local encoding threads */
void set_num_local_encoding_threads (int n) {
_num_local_encoding_threads = n;
void unset_language () {
_language = boost::none;
}
-
+
+ void set_default_still_length (int s) {
+ _default_still_length = s;
+ }
+
void write () const;
static Config* instance ();
/** Default DCI metadata for newly-created Films */
DCIMetadata _default_dci_metadata;
boost::optional<std::string> _language;
+ int _default_still_length;
/** Singleton instance, or 0 */
static Config* _instance;
{
set_dci_date_today ();
- _playlist->ContentChanged.connect (bind (&Film::content_changed, this, _1, _2));
+ _playlist->Changed.connect (bind (&Film::playlist_changed, this));
+ _playlist->ContentChanged.connect (bind (&Film::playlist_content_changed, this, _1, _2));
/* Make state.directory a complete path without ..s (where possible)
(Code swiped from Adam Bowen on stackoverflow)
: boost::enable_shared_from_this<Film> (o)
/* note: the copied film shares the original's log */
, _log (o._log)
- , _playlist (new Playlist)
+ , _playlist (new Playlist (o._playlist))
, _directory (o._directory)
, _name (o._name)
, _use_dci_name (o._use_dci_name)
, _dci_date (o._dci_date)
, _dirty (o._dirty)
{
- for (ContentList::const_iterator i = o._content.begin(); i != o._content.end(); ++i) {
- _content.push_back ((*i)->clone ());
- }
-
- _playlist->ContentChanged.connect (bind (&Film::content_changed, this, _1, _2));
-
- _playlist->setup (_content);
+ _playlist->ContentChanged.connect (bind (&Film::playlist_content_changed, this, _1, _2));
}
string
throw MissingSettingError (_("format"));
}
- if (content().empty ()) {
+ if (_playlist->content().empty ()) {
throw MissingSettingError (_("content"));
}
void
Film::write_metadata () const
{
- ContentList the_content = content ();
-
boost::mutex::scoped_lock lm (_state_mutex);
LocaleGuard lg;
root->add_child("DCPFrameRate")->add_child_text (boost::lexical_cast<string> (_dcp_frame_rate));
root->add_child("DCIDate")->add_child_text (boost::gregorian::to_iso_string (_dci_date));
_audio_mapping.as_xml (root->add_child("AudioMapping"));
-
- for (ContentList::iterator i = the_content.begin(); i != the_content.end(); ++i) {
- (*i)->as_xml (root->add_child ("Content"));
- }
+ _playlist->as_xml (root->add_child ("Playlist"));
doc.write_to_file_formatted (file ("metadata.xml"));
_dcp_frame_rate = f.number_child<int> ("DCPFrameRate");
_dci_date = boost::gregorian::from_undelimited_string (f.string_child ("DCIDate"));
- list<shared_ptr<cxml::Node> > c = f.node_children ("Content");
- for (list<shared_ptr<cxml::Node> >::iterator i = c.begin(); i != c.end(); ++i) {
-
- string const type = (*i)->string_child ("Type");
- boost::shared_ptr<Content> c;
-
- if (type == "FFmpeg") {
- c.reset (new FFmpegContent (*i));
- } else if (type == "ImageMagick") {
- c.reset (new ImageMagickContent (*i));
- } else if (type == "Sndfile") {
- c.reset (new SndfileContent (*i));
- }
-
- _content.push_back (c);
- }
-
- /* This must come after we've loaded the content, as we're looking things up in _content */
- _audio_mapping.set_from_xml (_content, f.node_child ("AudioMapping"));
+ _playlist->set_from_xml (f.node_child ("Playlist"));
+ _audio_mapping.set_from_xml (_playlist->content(), f.node_child ("AudioMapping"));
_dirty = false;
-
- _playlist->setup (_content);
}
libdcp::Size
signal_changed (TRUST_CONTENT_HEADERS);
- if (!_trust_content_headers && !content().empty()) {
+
+ ContentList content = _playlist->content ();
+ if (!_trust_content_headers && !content.empty()) {
/* We just said that we don't trust the content's header */
- ContentList c = content ();
- for (ContentList::iterator i = c.begin(); i != c.end(); ++i) {
+ for (ContentList::iterator i = content.begin(); i != content.end(); ++i) {
examine_content (*i);
}
}
switch (p) {
case Film::CONTENT:
- _playlist->setup (content ());
set_dcp_frame_rate (best_dcp_frame_rate (video_frame_rate ()));
set_audio_mapping (_playlist->default_audio_mapping ());
break;
return shared_ptr<Player> (new Player (shared_from_this (), _playlist));
}
+ContentList
+Film::content () const
+{
+ return _playlist->content ();
+}
+
void
Film::add_content (shared_ptr<Content> c)
{
- {
- boost::mutex::scoped_lock lm (_state_mutex);
- _content.push_back (c);
- }
-
- signal_changed (CONTENT);
-
+ _playlist->add (c);
examine_content (c);
}
void
Film::remove_content (shared_ptr<Content> c)
{
- {
- boost::mutex::scoped_lock lm (_state_mutex);
- ContentList::iterator i = find (_content.begin(), _content.end(), c);
- if (i != _content.end ()) {
- _content.erase (i);
- }
- }
-
- signal_changed (CONTENT);
+ _playlist->remove (c);
}
void
Film::move_content_earlier (shared_ptr<Content> c)
{
- {
- boost::mutex::scoped_lock lm (_state_mutex);
- ContentList::iterator i = find (_content.begin(), _content.end(), c);
- if (i == _content.begin () || i == _content.end()) {
- return;
- }
-
- ContentList::iterator j = i;
- --j;
-
- swap (*i, *j);
- }
-
- signal_changed (CONTENT);
+ _playlist->move_earlier (c);
}
void
Film::move_content_later (shared_ptr<Content> c)
{
- {
- boost::mutex::scoped_lock lm (_state_mutex);
- ContentList::iterator i = find (_content.begin(), _content.end(), c);
- if (i == _content.end()) {
- return;
- }
-
- ContentList::iterator j = i;
- ++j;
- if (j == _content.end ()) {
- return;
- }
-
- swap (*i, *j);
- }
-
- signal_changed (CONTENT);
-
+ _playlist->move_later (c);
}
ContentAudioFrame
return _playlist->content_length ();
}
-/** Unfortunately this is needed as the GUI has FFmpeg-specific controls */
-shared_ptr<FFmpegContent>
-Film::ffmpeg () const
-{
- boost::mutex::scoped_lock lm (_state_mutex);
-
- for (ContentList::const_iterator i = _content.begin (); i != _content.end(); ++i) {
- shared_ptr<FFmpegContent> f = boost::dynamic_pointer_cast<FFmpegContent> (*i);
- if (f) {
- return f;
- }
- }
-
- return shared_ptr<FFmpegContent> ();
-}
-
vector<FFmpegSubtitleStream>
Film::ffmpeg_subtitle_streams () const
{
- shared_ptr<FFmpegContent> f = ffmpeg ();
+ shared_ptr<FFmpegContent> f = _playlist->ffmpeg ();
if (f) {
return f->subtitle_streams ();
}
boost::optional<FFmpegSubtitleStream>
Film::ffmpeg_subtitle_stream () const
{
- shared_ptr<FFmpegContent> f = ffmpeg ();
+ shared_ptr<FFmpegContent> f = _playlist->ffmpeg ();
if (f) {
return f->subtitle_stream ();
}
vector<FFmpegAudioStream>
Film::ffmpeg_audio_streams () const
{
- shared_ptr<FFmpegContent> f = ffmpeg ();
+ shared_ptr<FFmpegContent> f = _playlist->ffmpeg ();
if (f) {
return f->audio_streams ();
}
boost::optional<FFmpegAudioStream>
Film::ffmpeg_audio_stream () const
{
- shared_ptr<FFmpegContent> f = ffmpeg ();
+ shared_ptr<FFmpegContent> f = _playlist->ffmpeg ();
if (f) {
return f->audio_stream ();
}
void
Film::set_ffmpeg_subtitle_stream (FFmpegSubtitleStream s)
{
- shared_ptr<FFmpegContent> f = ffmpeg ();
+ shared_ptr<FFmpegContent> f = _playlist->ffmpeg ();
if (f) {
f->set_subtitle_stream (s);
}
void
Film::set_ffmpeg_audio_stream (FFmpegAudioStream s)
{
- shared_ptr<FFmpegContent> f = ffmpeg ();
+ shared_ptr<FFmpegContent> f = _playlist->ffmpeg ();
if (f) {
f->set_audio_stream (s);
}
}
void
-Film::content_changed (boost::weak_ptr<Content> c, int p)
+Film::playlist_content_changed (boost::weak_ptr<Content> c, int p)
{
if (p == VideoContentProperty::VIDEO_FRAME_RATE) {
set_dcp_frame_rate (best_dcp_frame_rate (video_frame_rate ()));
ui_signaller->emit (boost::bind (boost::ref (ContentChanged), c, p));
}
}
+
+void
+Film::playlist_changed ()
+{
+ signal_changed (CONTENT);
+}
+
+int
+Film::loop () const
+{
+ return _playlist->loop ();
+}
+
+void
+Film::set_loop (int c)
+{
+ _playlist->set_loop (c);
+}
/* Proxies for some Playlist methods */
+ ContentList content () const;
+
ContentAudioFrame audio_length () const;
int audio_channels () const;
int audio_frame_rate () const;
void set_ffmpeg_subtitle_stream (FFmpegSubtitleStream);
void set_ffmpeg_audio_stream (FFmpegAudioStream);
+ void set_loop (int);
+ int loop () const;
+
enum TrimType {
CPL,
ENCODE
NAME,
USE_DCI_NAME,
TRUST_CONTENT_HEADERS,
- /** The content list has changed (i.e. content has been added, moved around or removed) */
+ /** The playlist's content list has changed (i.e. content has been added, moved around or removed) */
CONTENT,
+ LOOP,
DCP_CONTENT_TYPE,
FORMAT,
CROP,
return _trust_content_headers;
}
- ContentList content () const {
- boost::mutex::scoped_lock lm (_state_mutex);
- return _content;
- }
-
DCPContentType const * dcp_content_type () const {
boost::mutex::scoped_lock lm (_state_mutex);
return _dcp_content_type;
void analyse_audio_finished ();
std::string video_state_identifier () const;
void read_metadata ();
- void content_changed (boost::weak_ptr<Content>, int);
- boost::shared_ptr<FFmpegContent> ffmpeg () const;
+ void playlist_changed ();
+ void playlist_content_changed (boost::weak_ptr<Content>, int);
void setup_default_audio_mapping ();
std::string filename_safe_name () const;
/** True if a auto-generated DCI-compliant name should be used for our DCP */
bool _use_dci_name;
bool _trust_content_headers;
- ContentList _content;
/** The type of content that this Film represents (feature, trailer etc.) */
DCPContentType const * _dcp_content_type;
/** The format to present this Film in (flat, scope, etc.) */
#include <libcxml/cxml.h>
#include "imagemagick_content.h"
#include "imagemagick_decoder.h"
+#include "config.h"
#include "compose.hpp"
#include "i18n.h"
{
boost::mutex::scoped_lock lm (_mutex);
/* Initial length */
- _video_length = 10 * 24;
+ _video_length = Config::instance()->default_still_length() * 24;
}
take_from_video_decoder (decoder);
double video_so_far = 0;
double audio_so_far = 0;
-
- list<shared_ptr<const VideoContent> > vc = _playlist->video ();
- for (list<shared_ptr<const VideoContent> >::iterator i = vc.begin(); i != vc.end(); ++i) {
-
- shared_ptr<const VideoContent> video_content;
- shared_ptr<const AudioContent> audio_content;
- shared_ptr<VideoDecoder> video_decoder;
- shared_ptr<AudioDecoder> audio_decoder;
-
- /* XXX: into content? */
-
- shared_ptr<const FFmpegContent> fc = dynamic_pointer_cast<const FFmpegContent> (*i);
- if (fc) {
- shared_ptr<FFmpegDecoder> fd (
- new FFmpegDecoder (
- _film, fc, _video,
- _audio && _playlist->audio_from() == Playlist::AUDIO_FFMPEG,
- _subtitles
- )
- );
+
+ for (int l = 0; l < _playlist->loop(); ++l) {
+ list<shared_ptr<const VideoContent> > vc = _playlist->video ();
+ for (list<shared_ptr<const VideoContent> >::iterator i = vc.begin(); i != vc.end(); ++i) {
- video_content = fc;
- audio_content = fc;
- video_decoder = fd;
- audio_decoder = fd;
- }
-
- shared_ptr<const ImageMagickContent> ic = dynamic_pointer_cast<const ImageMagickContent> (*i);
- if (ic) {
- video_content = ic;
- video_decoder.reset (new ImageMagickDecoder (_film, ic));
+ shared_ptr<const VideoContent> video_content;
+ shared_ptr<const AudioContent> audio_content;
+ shared_ptr<VideoDecoder> video_decoder;
+ shared_ptr<AudioDecoder> audio_decoder;
+
+ /* XXX: into content? */
+
+ shared_ptr<const FFmpegContent> fc = dynamic_pointer_cast<const FFmpegContent> (*i);
+ if (fc) {
+ shared_ptr<FFmpegDecoder> fd (
+ new FFmpegDecoder (
+ _film, fc, _video,
+ _audio && _playlist->audio_from() == Playlist::AUDIO_FFMPEG,
+ _subtitles
+ )
+ );
+
+ video_content = fc;
+ audio_content = fc;
+ video_decoder = fd;
+ audio_decoder = fd;
+ }
+
+ shared_ptr<const ImageMagickContent> ic = dynamic_pointer_cast<const ImageMagickContent> (*i);
+ if (ic) {
+ video_content = ic;
+ video_decoder.reset (new ImageMagickDecoder (_film, ic));
+ }
+
+ video_decoder->connect_video (shared_from_this ());
+ _video_decoders.push_back (video_decoder);
+ _video_start.push_back (video_so_far);
+ video_so_far += video_content->video_length() / video_content->video_frame_rate();
+
+ if (audio_decoder && _playlist->audio_from() == Playlist::AUDIO_FFMPEG) {
+ audio_decoder->Audio.connect (bind (&Player::process_audio, this, audio_content, _1, _2));
+ _audio_decoders.push_back (audio_decoder);
+ _audio_start.push_back (audio_so_far);
+ audio_so_far += double(audio_content->audio_length()) / audio_content->audio_frame_rate();
+ }
}
- video_decoder->connect_video (shared_from_this ());
- _video_decoders.push_back (video_decoder);
- _video_start.push_back (video_so_far);
- video_so_far += video_content->video_length() / video_content->video_frame_rate();
-
- if (audio_decoder && _playlist->audio_from() == Playlist::AUDIO_FFMPEG) {
- audio_decoder->Audio.connect (bind (&Player::process_audio, this, audio_content, _1, _2));
- _audio_decoders.push_back (audio_decoder);
- _audio_start.push_back (audio_so_far);
- audio_so_far += double(audio_content->audio_length()) / audio_content->audio_frame_rate();
- }
- }
-
- _video_decoder = 0;
- _sequential_audio_decoder = 0;
-
- if (_playlist->audio_from() == Playlist::AUDIO_SNDFILE) {
+ _video_decoder = 0;
+ _sequential_audio_decoder = 0;
- list<shared_ptr<const AudioContent> > ac = _playlist->audio ();
- for (list<shared_ptr<const AudioContent> >::iterator i = ac.begin(); i != ac.end(); ++i) {
-
- shared_ptr<const SndfileContent> sc = dynamic_pointer_cast<const SndfileContent> (*i);
- assert (sc);
+ if (_playlist->audio_from() == Playlist::AUDIO_SNDFILE) {
- shared_ptr<AudioDecoder> d (new SndfileDecoder (_film, sc));
- d->Audio.connect (bind (&Player::process_audio, this, sc, _1, _2));
- _audio_decoders.push_back (d);
- _audio_start.push_back (audio_so_far);
+ list<shared_ptr<const AudioContent> > ac = _playlist->audio ();
+ for (list<shared_ptr<const AudioContent> >::iterator i = ac.begin(); i != ac.end(); ++i) {
+
+ shared_ptr<const SndfileContent> sc = dynamic_pointer_cast<const SndfileContent> (*i);
+ assert (sc);
+
+ shared_ptr<AudioDecoder> d (new SndfileDecoder (_film, sc));
+ d->Audio.connect (bind (&Player::process_audio, this, sc, _1, _2));
+ _audio_decoders.push_back (d);
+ _audio_start.push_back (audio_so_far);
+ }
}
}
}
double
Player::last_video_time () const
{
+ if (_video_decoder >= _video_decoders.size ()) {
+ return 0;
+ }
+
return _video_start[_video_decoder] + _video_decoders[_video_decoder]->last_content_time ();
}
}
if (p == VideoContentProperty::VIDEO_LENGTH) {
- if (dynamic_pointer_cast<FFmpegContent> (c)) {
- /* FFmpeg content length changes are serious; we need new decoders */
- _have_valid_decoders = false;
- }
+ _have_valid_decoders = false;
}
}
*/
+#include <libcxml/cxml.h>
#include <boost/shared_ptr.hpp>
#include <boost/lexical_cast.hpp>
#include "playlist.h"
#include "ffmpeg_decoder.h"
#include "ffmpeg_content.h"
#include "imagemagick_decoder.h"
+#include "imagemagick_content.h"
#include "job.h"
using std::list;
Playlist::Playlist ()
: _audio_from (AUDIO_FFMPEG)
+ , _loop (1)
{
}
+Playlist::Playlist (shared_ptr<const Playlist> other)
+ : _audio_from (other->_audio_from)
+ , _loop (other->_loop)
+{
+ for (ContentList::const_iterator i = other->_content.begin(); i != other->_content.end(); ++i) {
+ _content.push_back ((*i)->clone ());
+ }
+
+ setup ();
+}
+
void
-Playlist::setup (ContentList content)
+Playlist::setup ()
{
_audio_from = AUDIO_FFMPEG;
_content_connections.clear ();
- for (ContentList::const_iterator i = content.begin(); i != content.end(); ++i) {
+ for (ContentList::const_iterator i = _content.begin(); i != _content.end(); ++i) {
/* Video is video */
shared_ptr<VideoContent> vc = dynamic_pointer_cast<VideoContent> (*i);
_content_connections.push_back ((*i)->Changed.connect (bind (&Playlist::content_changed, this, _1, _2)));
}
-
- Changed ();
}
/** @return Length of our audio */
break;
}
- return len;
+ return len * _loop;
}
/** @return number of audio channels */
len += (*i)->video_length ();
}
- return len;
+ return len * _loop;
}
bool
}
}
+ t += lexical_cast<string> (_loop);
+
return md5_digest (t.c_str(), t.length());
}
}
}
+ t += lexical_cast<string> (_loop);
+
return md5_digest (t.c_str(), t.length());
}
ContentVideoFrame (audio_length() * vfr / afr)
);
}
+
+void
+Playlist::set_from_xml (shared_ptr<const cxml::Node> node)
+{
+ list<shared_ptr<cxml::Node> > c = node->node_children ("Content");
+ for (list<shared_ptr<cxml::Node> >::iterator i = c.begin(); i != c.end(); ++i) {
+
+ string const type = (*i)->string_child ("Type");
+ boost::shared_ptr<Content> c;
+
+ if (type == "FFmpeg") {
+ c.reset (new FFmpegContent (*i));
+ } else if (type == "ImageMagick") {
+ c.reset (new ImageMagickContent (*i));
+ } else if (type == "Sndfile") {
+ c.reset (new SndfileContent (*i));
+ }
+
+ _content.push_back (c);
+ }
+
+ _loop = node->number_child<int> ("Loop");
+
+ setup ();
+}
+
+void
+Playlist::as_xml (xmlpp::Node* node)
+{
+ for (ContentList::iterator i = _content.begin(); i != _content.end(); ++i) {
+ (*i)->as_xml (node->add_child ("Content"));
+ }
+
+ node->add_child("Loop")->add_child_text(lexical_cast<string> (_loop));
+}
+
+void
+Playlist::add (shared_ptr<Content> c)
+{
+ _content.push_back (c);
+ setup ();
+ Changed ();
+}
+
+void
+Playlist::remove (shared_ptr<Content> c)
+{
+ ContentList::iterator i = find (_content.begin(), _content.end(), c);
+ if (i != _content.end ()) {
+ _content.erase (i);
+ }
+
+ setup ();
+ Changed ();
+}
+
+void
+Playlist::move_earlier (shared_ptr<Content> c)
+{
+ ContentList::iterator i = find (_content.begin(), _content.end(), c);
+ if (i == _content.begin () || i == _content.end()) {
+ return;
+ }
+
+ ContentList::iterator j = i;
+ --j;
+
+ swap (*i, *j);
+
+ setup ();
+ Changed ();
+}
+
+void
+Playlist::move_later (shared_ptr<Content> c)
+{
+ ContentList::iterator i = find (_content.begin(), _content.end(), c);
+ if (i == _content.end()) {
+ return;
+ }
+
+ ContentList::iterator j = i;
+ ++j;
+ if (j == _content.end ()) {
+ return;
+ }
+
+ swap (*i, *j);
+
+ setup ();
+ Changed ();
+}
+
+void
+Playlist::set_loop (int l)
+{
+ _loop = l;
+ Changed ();
+}
+
+shared_ptr<FFmpegContent>
+Playlist::ffmpeg () const
+{
+ for (ContentList::const_iterator i = _content.begin(); i != _content.end(); ++i) {
+ shared_ptr<FFmpegContent> fc = dynamic_pointer_cast<FFmpegContent> (*i);
+ if (fc) {
+ return fc;
+ }
+ }
+
+ return shared_ptr<FFmpegContent> ();
+}
{
public:
Playlist ();
+ Playlist (boost::shared_ptr<const Playlist>);
- void setup (ContentList);
+ void as_xml (xmlpp::Node *);
+ void set_from_xml (boost::shared_ptr<const cxml::Node>);
+
+ void add (boost::shared_ptr<Content>);
+ void remove (boost::shared_ptr<Content>);
+ void move_earlier (boost::shared_ptr<Content>);
+ void move_later (boost::shared_ptr<Content>);
ContentAudioFrame audio_length () const;
int audio_channels () const;
return _audio_from;
}
+ ContentList content () const {
+ return _content;
+ }
+
+ boost::shared_ptr<FFmpegContent> ffmpeg () const;
+
std::list<boost::shared_ptr<const VideoContent> > video () const {
return _video;
}
std::string audio_digest () const;
std::string video_digest () const;
+ int loop () const {
+ return _loop;
+ }
+
+ void set_loop (int l);
+
mutable boost::signals2::signal<void ()> Changed;
mutable boost::signals2::signal<void (boost::weak_ptr<Content>, int)> ContentChanged;
private:
+ void setup ();
void content_changed (boost::weak_ptr<Content>, int);
/** where we should get our audio from */
AudioFrom _audio_from;
+ /** all our content */
+ ContentList _content;
/** all our content which contains video */
std::list<boost::shared_ptr<const VideoContent> > _video;
/** all our content which contains audio. This may contain the same objects
*/
std::list<boost::shared_ptr<const AudioContent> > _audio;
+ int _loop;
+
std::list<boost::signals2::connection> _content_connections;
};
"Project-Id-Version: IT VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-04-22 15:06+0100\n"
-"PO-Revision-Date: 2013-04-03 15:04+0100\n"
+"PO-Revision-Date: 2013-04-28 10:26+0100\n"
"Last-Translator: Maci <macibro@gmail.com>\n"
"Language-Team: \n"
"Language: Italiano\n"
msgstr "16:9 all'interno di Flat"
#: src/lib/format.cc:115
-#, fuzzy
msgid "16:9 within Scope"
-msgstr "16:9 all'interno di Flat"
+msgstr "16:9 all'interno di Scope"
#: src/lib/filter.cc:88
msgid "3D denoiser"
#: src/lib/format.cc:79
msgid "4:3"
-msgstr ""
+msgstr "4:3"
#: src/lib/format.cc:87
msgid "4:3 within Flat"
#: src/lib/examine_content_job.cc:58
msgid "Examine content of %1"
-msgstr "Esamo il contenuto di %1"
+msgstr "Esamino il contenuto di %1"
#: src/lib/filter.cc:72
msgid "Experimental horizontal deblocking filter 1"
#: src/lib/job.cc:302
msgid "OK (ran for %1)"
-msgstr "OK (procede al %1)"
+msgstr "OK (eseguito in %1)"
#: src/lib/filter.cc:91
msgid "Overcomplete wavelet denoiser"
#: src/lib/exceptions.cc:29
msgid "could not open file %1"
-msgstr "non riesco ad aprire il file per leggerlo"
+msgstr "non riesco ad aprire %1"
#: src/lib/dcp_video_frame.cc:388
msgid "could not open file for reading"
#: src/lib/exceptions.cc:44
msgid "could not read from file %1 (%2)"
-msgstr "Non posso creare la directory remota %1 (%2)"
+msgstr "non posso leggere dal file %1 (%2)"
#: src/lib/encoder.cc:137 src/lib/encoder.cc:314
msgid "could not run sample-rate converter"
-msgstr "non riesco a lanciare il convertitore della frequenza di campionamento"
+msgstr "non riesco a eseguire il convertitore della frequenza di campionamento"
#: src/lib/scp_dcp_job.cc:86
msgid "could not start SCP session (%1)"
#: src/lib/exceptions.cc:50
msgid "could not write to file %1 (%2)"
-msgstr "Non posso scrivere il file remoto (%1)"
+msgstr "non posso scrivere il file (%1)"
#: src/lib/sndfile_decoder.cc:94
msgid "external audio files have differing lengths"
#: src/lib/imagemagick_decoder.cc:60
msgid "no still image files found"
-msgstr "file del fermo immagine non trovati"
+msgstr "file immagini statiche non trovati"
#: src/lib/subtitle.cc:58
msgid "non-bitmap subtitles not yet supported"
SndfileDecoder::~SndfileDecoder ()
{
- if (_sndfile) {
- sf_close (_sndfile);
- }
+ sf_close (_sndfile);
}
bool
int audio_frame_rate () const;
private:
- SNDFILE* open_file (sf_count_t &);
- void close_file (SNDFILE*);
-
boost::shared_ptr<const SndfileContent> _sndfile_content;
SNDFILE* _sndfile;
SF_INFO _info;
"Project-Id-Version: IT VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-04-22 15:06+0100\n"
-"PO-Revision-Date: 2013-04-03 13:00+0100\n"
+"PO-Revision-Date: 2013-04-28 10:31+0100\n"
"Last-Translator: Maci <macibro@gmail.com>\n"
"Language-Team: \n"
"Language: Italiano\n"
#include <boost/lexical_cast.hpp>
#include <boost/filesystem.hpp>
#include <wx/stdpaths.h>
+#include <wx/notebook.h>
#include "lib/config.h"
#include "lib/server.h"
#include "lib/format.h"
ConfigDialog::ConfigDialog (wxWindow* parent)
: wxDialog (parent, wxID_ANY, _("DCP-o-matic Preferences"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
{
+ 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_servers_panel ();
+ _notebook->AddPage (_servers_panel, _("Encoding servers"), false);
+ make_tms_panel ();
+ _notebook->AddPage (_tms_panel, _("TMS"), false);
+ make_ab_panel ();
+ _notebook->AddPage (_ab_panel, _("A/B mode"), false);
+
+ wxBoxSizer* overall_sizer = new wxBoxSizer (wxVERTICAL);
+ overall_sizer->Add (s, 1, wxEXPAND | wxALL, 6);
+
+ wxSizer* buttons = CreateSeparatedButtonSizer (wxOK);
+ if (buttons) {
+ overall_sizer->Add (buttons, wxSizerFlags().Expand().DoubleBorder());
+ }
+
+ SetSizer (overall_sizer);
+ overall_sizer->Layout ();
+ overall_sizer->SetSizeHints (this);
+}
+
+void
+ConfigDialog::make_misc_panel ()
+{
+ _misc_panel = new wxPanel (_notebook);
+ wxBoxSizer* s = new wxBoxSizer (wxVERTICAL);
+ _misc_panel->SetSizer (s);
+
wxFlexGridSizer* table = new wxFlexGridSizer (3, 6, 6);
table->AddGrowableCol (1, 1);
+ s->Add (table, 1, wxALL | wxEXPAND, 8);
- _set_language = new wxCheckBox (this, wxID_ANY, _("Set language"));
+ _set_language = new wxCheckBox (_misc_panel, wxID_ANY, _("Set language"));
table->Add (_set_language, 1, wxEXPAND);
- _language = new wxChoice (this, wxID_ANY);
+ _language = new wxChoice (_misc_panel, wxID_ANY);
_language->Append (wxT ("English"));
_language->Append (wxT ("Français"));
_language->Append (wxT ("Italiano"));
table->Add (_language, 1, wxEXPAND);
table->AddSpacer (0);
- table->AddSpacer (0);
- wxStaticText* restart = add_label_to_sizer (table, this, _("(restart DCP-o-matic to see language changes)"));
+ wxStaticText* restart = add_label_to_sizer (table, _misc_panel, _("(restart DCP-o-matic to see language changes)"));
wxFont font = restart->GetFont();
font.SetStyle (wxFONTSTYLE_ITALIC);
font.SetPointSize (font.GetPointSize() - 1);
restart->SetFont (font);
table->AddSpacer (0);
-
- add_label_to_sizer (table, this, _("TMS IP address"));
- _tms_ip = new wxTextCtrl (this, wxID_ANY);
- table->Add (_tms_ip, 1, wxEXPAND);
- table->AddSpacer (0);
-
- add_label_to_sizer (table, this, _("TMS target path"));
- _tms_path = new wxTextCtrl (this, wxID_ANY);
- table->Add (_tms_path, 1, wxEXPAND);
- table->AddSpacer (0);
-
- add_label_to_sizer (table, this, _("TMS user name"));
- _tms_user = new wxTextCtrl (this, wxID_ANY);
- table->Add (_tms_user, 1, wxEXPAND);
table->AddSpacer (0);
- add_label_to_sizer (table, this, _("TMS password"));
- _tms_password = new wxTextCtrl (this, wxID_ANY);
- table->Add (_tms_password, 1, wxEXPAND);
- table->AddSpacer (0);
-
- add_label_to_sizer (table, this, _("Threads to use for encoding on this host"));
- _num_local_encoding_threads = new wxSpinCtrl (this);
+ add_label_to_sizer (table, _misc_panel, _("Threads to use for encoding on this host"));
+ _num_local_encoding_threads = new wxSpinCtrl (_misc_panel);
table->Add (_num_local_encoding_threads, 1, wxEXPAND);
table->AddSpacer (0);
- add_label_to_sizer (table, this, _("Default directory for new films"));
+ add_label_to_sizer (table, _misc_panel, _("Default duration of still images"));
+ _default_still_length = new wxSpinCtrl (_misc_panel);
+ table->Add (_default_still_length, 1, wxEXPAND);
+ add_label_to_sizer (table, _misc_panel, _("s"));
+
+ add_label_to_sizer (table, _misc_panel, _("Default directory for new films"));
#ifdef __WXMSW__
- _default_directory = new DirPickerCtrl (this);
+ _default_directory = new DirPickerCtrl (_misc_panel);
#else
- _default_directory = new wxDirPickerCtrl (this, wxDD_DIR_MUST_EXIST);
+ _default_directory = new wxDirPickerCtrl (_misc_panel, wxDD_DIR_MUST_EXIST);
#endif
table->Add (_default_directory, 1, wxEXPAND);
table->AddSpacer (0);
- add_label_to_sizer (table, this, _("Default DCI name details"));
- _default_dci_metadata_button = new wxButton (this, wxID_ANY, _("Edit..."));
+ add_label_to_sizer (table, _misc_panel, _("Default DCI name details"));
+ _default_dci_metadata_button = new wxButton (_misc_panel, wxID_ANY, _("Edit..."));
table->Add (_default_dci_metadata_button);
table->AddSpacer (1);
- add_label_to_sizer (table, this, _("Reference scaler for A/B"));
- _reference_scaler = new wxChoice (this, wxID_ANY);
- vector<Scaler const *> const sc = Scaler::all ();
- for (vector<Scaler const *>::const_iterator i = sc.begin(); i != sc.end(); ++i) {
- _reference_scaler->Append (std_to_wx ((*i)->name ()));
- }
-
- table->Add (_reference_scaler, 1, wxEXPAND);
- table->AddSpacer (0);
-
- {
- add_label_to_sizer (table, this, _("Reference filters for A/B"));
- wxSizer* s = new wxBoxSizer (wxHORIZONTAL);
- _reference_filters = new wxStaticText (this, wxID_ANY, wxT (""));
- s->Add (_reference_filters, 1, wxEXPAND);
- _reference_filters_button = new wxButton (this, wxID_ANY, _("Edit..."));
- s->Add (_reference_filters_button, 0);
- table->Add (s, 1, wxEXPAND);
- table->AddSpacer (0);
- }
-
- add_label_to_sizer (table, this, _("Encoding Servers"));
- _servers = new wxListCtrl (this, wxID_ANY, wxDefaultPosition, wxSize (220, 100), wxLC_REPORT | wxLC_SINGLE_SEL);
- wxListItem ip;
- ip.SetId (0);
- ip.SetText (_("IP address"));
- ip.SetWidth (120);
- _servers->InsertColumn (0, ip);
- ip.SetId (1);
- ip.SetText (_("Threads"));
- ip.SetWidth (80);
- _servers->InsertColumn (1, ip);
- table->Add (_servers, 1, wxEXPAND | wxALL);
-
- {
- wxSizer* s = new wxBoxSizer (wxVERTICAL);
- _add_server = new wxButton (this, wxID_ANY, _("Add"));
- s->Add (_add_server);
- _edit_server = new wxButton (this, wxID_ANY, _("Edit"));
- s->Add (_edit_server);
- _remove_server = new wxButton (this, wxID_ANY, _("Remove"));
- s->Add (_remove_server);
- table->Add (s, 0);
- }
-
Config* config = Config::instance ();
_set_language->SetValue (config->language ());
_set_language->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (ConfigDialog::set_language_changed), 0, this);
_language->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (ConfigDialog::language_changed), 0, this);
+
+ _num_local_encoding_threads->SetRange (1, 128);
+ _num_local_encoding_threads->SetValue (config->num_local_encoding_threads ());
+ _num_local_encoding_threads->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (ConfigDialog::num_local_encoding_threads_changed), 0, this);
+
+ _default_still_length->SetRange (1, 3600);
+ _default_still_length->SetValue (config->default_still_length ());
+ _default_still_length->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (ConfigDialog::default_still_length_changed), 0, this);
+
+ _default_directory->SetPath (std_to_wx (config->default_directory_or (wx_to_std (wxStandardPaths::Get().GetDocumentsDir()))));
+ _default_directory->Connect (wxID_ANY, wxEVT_COMMAND_DIRPICKER_CHANGED, wxCommandEventHandler (ConfigDialog::default_directory_changed), 0, this);
+
+ _default_dci_metadata_button->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (ConfigDialog::edit_default_dci_metadata_clicked), 0, 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, 6, 6);
+ table->AddGrowableCol (1, 1);
+ s->Add (table, 1, wxALL | wxEXPAND, 8);
+
+ add_label_to_sizer (table, _tms_panel, _("IP address"));
+ _tms_ip = new wxTextCtrl (_tms_panel, wxID_ANY);
+ table->Add (_tms_ip, 1, wxEXPAND);
+
+ add_label_to_sizer (table, _tms_panel, _("Target path"));
+ _tms_path = new wxTextCtrl (_tms_panel, wxID_ANY);
+ table->Add (_tms_path, 1, wxEXPAND);
+
+ add_label_to_sizer (table, _tms_panel, _("User name"));
+ _tms_user = new wxTextCtrl (_tms_panel, wxID_ANY);
+ table->Add (_tms_user, 1, wxEXPAND);
+
+ add_label_to_sizer (table, _tms_panel, _("Password"));
+ _tms_password = new wxTextCtrl (_tms_panel, wxID_ANY);
+ table->Add (_tms_password, 1, wxEXPAND);
+
+ Config* config = Config::instance ();
+
_tms_ip->SetValue (std_to_wx (config->tms_ip ()));
_tms_ip->Connect (wxID_ANY, wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler (ConfigDialog::tms_ip_changed), 0, this);
_tms_path->SetValue (std_to_wx (config->tms_path ()));
_tms_user->Connect (wxID_ANY, wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler (ConfigDialog::tms_user_changed), 0, this);
_tms_password->SetValue (std_to_wx (config->tms_password ()));
_tms_password->Connect (wxID_ANY, wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler (ConfigDialog::tms_password_changed), 0, this);
+}
- _num_local_encoding_threads->SetRange (1, 128);
- _num_local_encoding_threads->SetValue (config->num_local_encoding_threads ());
- _num_local_encoding_threads->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (ConfigDialog::num_local_encoding_threads_changed), 0, this);
+void
+ConfigDialog::make_ab_panel ()
+{
+ _ab_panel = new wxPanel (_notebook);
+ wxBoxSizer* s = new wxBoxSizer (wxVERTICAL);
+ _ab_panel->SetSizer (s);
- _default_directory->SetPath (std_to_wx (config->default_directory_or (wx_to_std (wxStandardPaths::Get().GetDocumentsDir()))));
- _default_directory->Connect (wxID_ANY, wxEVT_COMMAND_DIRPICKER_CHANGED, wxCommandEventHandler (ConfigDialog::default_directory_changed), 0, this);
+ wxFlexGridSizer* table = new wxFlexGridSizer (3, 6, 6);
+ table->AddGrowableCol (1, 1);
+ s->Add (table, 1, wxALL, 8);
+
+ add_label_to_sizer (table, _ab_panel, _("Reference scaler"));
+ _reference_scaler = new wxChoice (_ab_panel, wxID_ANY);
+ vector<Scaler const *> const sc = Scaler::all ();
+ for (vector<Scaler const *>::const_iterator i = sc.begin(); i != sc.end(); ++i) {
+ _reference_scaler->Append (std_to_wx ((*i)->name ()));
+ }
- _default_dci_metadata_button->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (ConfigDialog::edit_default_dci_metadata_clicked), 0, this);
+ table->Add (_reference_scaler, 1, wxEXPAND);
+ table->AddSpacer (0);
+
+ {
+ add_label_to_sizer (table, _ab_panel, _("Reference filters"));
+ wxSizer* s = new wxBoxSizer (wxHORIZONTAL);
+ _reference_filters = new wxStaticText (_ab_panel, wxID_ANY, wxT (""));
+ s->Add (_reference_filters, 1, wxEXPAND);
+ _reference_filters_button = new wxButton (_ab_panel, wxID_ANY, _("Edit..."));
+ s->Add (_reference_filters_button, 0);
+ table->Add (s, 1, wxEXPAND);
+ table->AddSpacer (0);
+ }
+ Config* config = Config::instance ();
+
_reference_scaler->SetSelection (Scaler::as_index (config->reference_scaler ()));
_reference_scaler->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (ConfigDialog::reference_scaler_changed), 0, this);
pair<string, string> p = Filter::ffmpeg_strings (config->reference_filters ());
_reference_filters->SetLabel (std_to_wx (p.first) + N_(" ") + std_to_wx (p.second));
_reference_filters_button->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (ConfigDialog::edit_reference_filters_clicked), 0, this);
+}
+
+void
+ConfigDialog::make_servers_panel ()
+{
+ _servers_panel = new wxPanel (_notebook);
+ wxBoxSizer* s = new wxBoxSizer (wxVERTICAL);
+ _servers_panel->SetSizer (s);
+
+ wxFlexGridSizer* table = new wxFlexGridSizer (2, 6, 6);
+ table->AddGrowableCol (0, 1);
+ s->Add (table, 1, wxALL | wxEXPAND, 8);
+
+ Config* config = Config::instance ();
+
+ _servers = new wxListCtrl (_servers_panel, wxID_ANY, wxDefaultPosition, wxSize (220, 100), wxLC_REPORT | wxLC_SINGLE_SEL);
+ wxListItem ip;
+ ip.SetId (0);
+ ip.SetText (_("IP address"));
+ ip.SetWidth (120);
+ _servers->InsertColumn (0, ip);
+ ip.SetId (1);
+ ip.SetText (_("Threads"));
+ ip.SetWidth (80);
+ _servers->InsertColumn (1, ip);
+ table->Add (_servers, 1, wxEXPAND | wxALL);
+
+ {
+ wxSizer* s = new wxBoxSizer (wxVERTICAL);
+ _add_server = new wxButton (_servers_panel, wxID_ANY, _("Add"));
+ s->Add (_add_server);
+ _edit_server = new wxButton (_servers_panel, wxID_ANY, _("Edit"));
+ s->Add (_edit_server);
+ _remove_server = new wxButton (_servers_panel, wxID_ANY, _("Remove"));
+ s->Add (_remove_server);
+ table->Add (s, 0);
+ }
vector<ServerDescription*> servers = config->servers ();
for (vector<ServerDescription*>::iterator i = servers.begin(); i != servers.end(); ++i) {
_servers->Connect (wxID_ANY, wxEVT_COMMAND_LIST_ITEM_DESELECTED, wxListEventHandler (ConfigDialog::server_selection_changed), 0, this);
wxListEvent ev;
server_selection_changed (ev);
-
- wxBoxSizer* overall_sizer = new wxBoxSizer (wxVERTICAL);
- overall_sizer->Add (table, 1, wxEXPAND | wxALL, 6);
-
- wxSizer* buttons = CreateSeparatedButtonSizer (wxOK);
- if (buttons) {
- overall_sizer->Add (buttons, wxSizerFlags().Expand().DoubleBorder());
- }
-
- SetSizer (overall_sizer);
- overall_sizer->Layout ();
- overall_sizer->SetSizeHints (this);
}
void
{
_language->Enable (_set_language->GetValue ());
}
+
+void
+ConfigDialog::default_still_length_changed (wxCommandEvent &)
+{
+ Config::instance()->set_default_still_length (_default_still_length->GetValue ());
+}
#include <wx/filepicker.h>
class DirPickerCtrl;
+class wxNotebook;
class ServerDescription;
void tms_user_changed (wxCommandEvent &);
void tms_password_changed (wxCommandEvent &);
void num_local_encoding_threads_changed (wxCommandEvent &);
+ void default_still_length_changed (wxCommandEvent &);
void default_directory_changed (wxCommandEvent &);
void edit_default_dci_metadata_clicked (wxCommandEvent &);
void reference_scaler_changed (wxCommandEvent &);
void add_server_to_control (ServerDescription *);
void setup_language_sensitivity ();
+ void make_misc_panel ();
+ void make_tms_panel ();
+ void make_ab_panel ();
+ void make_servers_panel ();
+
+ wxNotebook* _notebook;
+ wxPanel* _misc_panel;
+ wxPanel* _tms_panel;
+ wxPanel* _ab_panel;
+ wxPanel* _servers_panel;
wxCheckBox* _set_language;
wxChoice* _language;
wxTextCtrl* _tms_ip;
wxTextCtrl* _tms_user;
wxTextCtrl* _tms_password;
wxSpinCtrl* _num_local_encoding_threads;
+ wxSpinCtrl* _default_still_length;
#ifdef __WXMSW__
DirPickerCtrl* _default_directory;
#else
_content_edit->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::content_edit_clicked), 0, this);
_content_earlier->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::content_earlier_clicked), 0, this);
_content_later->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::content_later_clicked), 0, this);
+ _loop_content->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (FilmEditor::loop_content_toggled), 0, this);
+ _loop_count->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::loop_count_changed), 0, this);
_left_crop->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::left_crop_changed), 0, this);
_right_crop->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::right_crop_changed), 0, this);
_top_crop->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::top_crop_changed), 0, this);
_content_sizer->Add (s, 1, wxEXPAND | wxALL, 6);
}
+ wxBoxSizer* h = new wxBoxSizer (wxHORIZONTAL);
+ _loop_content = new wxCheckBox (_content_panel, wxID_ANY, _("Loop everything"));
+ h->Add (_loop_content, 0, wxALL, 6);
+ _loop_count = new wxSpinCtrl (_content_panel, wxID_ANY);
+ h->Add (_loop_count, 0, wxALL, 6);
+ add_label_to_sizer (h, _content_panel, _("times"));
+ _content_sizer->Add (h, 0, wxALL, 6);
+
_content_information = new wxTextCtrl (_content_panel, wxID_ANY, wxT ("\n\n\n\n"), wxDefaultPosition, wxDefaultSize, wxTE_READONLY | wxTE_MULTILINE);
_content_sizer->Add (_content_information, 1, wxEXPAND | wxALL, 6);
+
+ _loop_count->SetRange (2, 1024);
}
void
setup_show_audio_sensitivity ();
setup_length ();
break;
+ case Film::LOOP:
+ checked_set (_loop_content, _film->loop() > 1);
+ checked_set (_loop_count, _film->loop());
+ setup_loop_sensitivity ();
+ break;
case Film::TRUST_CONTENT_HEADERS:
checked_set (_trust_content_headers, _film->trust_content_headers ());
break;
film_changed (Film::NAME);
film_changed (Film::USE_DCI_NAME);
film_changed (Film::CONTENT);
+ film_changed (Film::LOOP);
film_changed (Film::TRUST_CONTENT_HEADERS);
film_changed (Film::DCP_CONTENT_TYPE);
film_changed (Film::FORMAT);
void
FilmEditor::content_add_clicked (wxCommandEvent &)
{
- wxFileDialog* d = new wxFileDialog (this);
+ wxFileDialog* d = new wxFileDialog (this, _("Choose a file or files"), wxT (""), wxT (""), wxT ("*.*"), wxFD_MULTIPLE);
int const r = d->ShowModal ();
d->Destroy ();
return;
}
- boost::filesystem::path p (wx_to_std (d->GetPath()));
+ wxArrayString paths;
+ d->GetPaths (paths);
- if (ImageMagickContent::valid_file (p)) {
- _film->add_content (shared_ptr<ImageMagickContent> (new ImageMagickContent (p)));
- } else if (SndfileContent::valid_file (p)) {
- _film->add_content (shared_ptr<SndfileContent> (new SndfileContent (p)));
- } else {
- _film->add_content (shared_ptr<FFmpegContent> (new FFmpegContent (p)));
+ for (unsigned int i = 0; i < paths.GetCount(); ++i) {
+ boost::filesystem::path p (wx_to_std (paths[i]));
+
+ if (ImageMagickContent::valid_file (p)) {
+ _film->add_content (shared_ptr<ImageMagickContent> (new ImageMagickContent (p)));
+ } else if (SndfileContent::valid_file (p)) {
+ _film->add_content (shared_ptr<SndfileContent> (new SndfileContent (p)));
+ } else {
+ _film->add_content (shared_ptr<FFmpegContent> (new FFmpegContent (p)));
+ }
}
-
}
void
{
_film->set_trim_type (_trim_type->GetSelection () == 0 ? Film::CPL : Film::ENCODE);
}
+
+void
+FilmEditor::loop_content_toggled (wxCommandEvent &)
+{
+ if (_loop_content->GetValue ()) {
+ _film->set_loop (_loop_count->GetValue ());
+ } else {
+ _film->set_loop (1);
+ }
+
+ setup_loop_sensitivity ();
+}
+
+void
+FilmEditor::loop_count_changed (wxCommandEvent &)
+{
+ _film->set_loop (_loop_count->GetValue ());
+}
+
+void
+FilmEditor::setup_loop_sensitivity ()
+{
+ _loop_count->Enable (_loop_content->GetValue ());
+}
void dcp_frame_rate_changed (wxCommandEvent &);
void best_dcp_frame_rate_clicked (wxCommandEvent &);
void edit_filters_clicked (wxCommandEvent &);
+ void loop_content_toggled (wxCommandEvent &);
+ void loop_count_changed (wxCommandEvent &);
/* Handle changes to the model */
void film_changed (Film::Property);
void setup_length ();
void setup_content_information ();
void setup_content_button_sensitivity ();
+ void setup_loop_sensitivity ();
void active_jobs_changed (bool);
boost::shared_ptr<Content> selected_content ();
wxButton* _content_earlier;
wxButton* _content_later;
wxTextCtrl* _content_information;
+ wxCheckBox* _loop_content;
+ wxSpinCtrl* _loop_count;
wxButton* _edit_dci_button;
wxChoice* _format;
wxStaticText* _format_description;
"Project-Id-Version: IT VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-04-22 15:06+0100\n"
-"PO-Revision-Date: 2013-04-03 12:37+0100\n"
+"PO-Revision-Date: 2013-04-28 10:27+0100\n"
"Last-Translator: Maci <macibro@gmail.com>\n"
"Language-Team: \n"
"Language: Italiano\n"
#: src/wx/film_editor.cc:1276
msgid "1 channel"
-msgstr "Canale 1"
+msgstr "1 canale"
#: src/wx/film_editor.cc:184
msgid "A/B"
#: src/wx/film_editor.cc:824
#, c-format
msgid "Audio will be resampled from %dHz to %dHz\n"
-msgstr ""
+msgstr "L'Audio sarà ricampionato da %dHz a %dHz\n"
#: src/wx/job_wrapper.cc:38
#, c-format
#: src/wx/film_editor.cc:1371
#, c-format
msgid "Cropped to %dx%d (%.2f:1)\n"
-msgstr ""
+msgstr "Tagliato da %dx%d (%.2f:1)\n"
#: src/wx/dci_metadata_dialog.cc:28
msgid "DCI name"
#: src/wx/gain_calculator_dialog.cc:27
msgid "Gain Calculator"
-msgstr "Calcola il guadagno audio"
+msgstr "Calcolatore del guadagno audio"
#: src/wx/properties_dialog.cc:59
msgid "Gb"
#: src/wx/film_editor.cc:1360
#, c-format
msgid "Original video is %dx%d (%.2f:1)\n"
-msgstr ""
+msgstr "Il video originale è %dx%d (%.2f:1)\n"
#: src/wx/dci_metadata_dialog.cc:57
msgid "Package Type (e.g. OV)"
#: src/wx/film_editor.cc:1392
#, c-format
msgid "Padded with black to %dx%d (%.2f:1)\n"
-msgstr ""
+msgstr "Riempito con nero a %dx%d (%.2f:1)\n"
#: src/wx/audio_dialog.cc:60
msgid "Peak"
#: src/wx/film_editor.cc:1384
#, c-format
msgid "Scaled to %dx%d (%.2f:1)\n"
-msgstr ""
+msgstr "Scalato a %dx%d (%.2f:1)\n"
#: src/wx/film_editor.cc:319
msgid "Scaler"
msgstr "Taglia fotogrammi"
#: src/wx/film_editor.cc:179
-#, fuzzy
msgid "Trim method"
-msgstr "Taglia fotogrammi"
+msgstr "Metodo di taglio"
#: src/wx/film_editor.cc:125
msgid "Trust content's header"
#: src/wx/film_editor.cc:428
msgid "With Subtitles"
-msgstr "Con Sottotitoli"
+msgstr "Con sottotitoli"
#: src/wx/film_editor.cc:1278
msgid "channels"
#: src/wx/film_editor.cc:212
msgid "encode all frames and play the subset"
-msgstr ""
+msgstr "Codifica tutti i fotogrammi e riproduci la selezione"
#: src/wx/film_editor.cc:213
msgid "encode only the subset"
-msgstr ""
+msgstr "codifica solo la selezione"
#: src/wx/film_editor.cc:694 src/wx/film_editor.cc:697
msgid "frames"
#: src/wx/film_editor.cc:440
msgid "pixels"
-msgstr ""
+msgstr "pizels"
#. / TRANSLATORS: `s' here is an abbreviation for seconds, the unit of time
#: src/wx/film_editor.cc:197