return doc;
}
+void
+Film::write_metadata (boost::filesystem::path path) const
+{
+ shared_ptr<xmlpp::Document> doc = metadata ();
+ doc->write_to_file_formatted (path.string());
+}
+
/** Write state to our `metadata' file */
void
Film::write_metadata () const
void use_template (std::string name);
std::list<std::string> read_metadata (boost::optional<boost::filesystem::path> path = boost::optional<boost::filesystem::path> ());
void write_metadata () const;
+ void write_metadata (boost::filesystem::path path) const;
void write_template (boost::filesystem::path path) const;
boost::shared_ptr<xmlpp::Document> metadata (bool with_content_paths = true) const;
+++ /dev/null
-/*
- Copyright (C) 2018 Carl Hetherington <cth@carlh.net>
-
- This file is part of DCP-o-matic.
-
- DCP-o-matic 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.
-
- DCP-o-matic 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 DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#include "spl.h"
-#include "spl_entry.h"
-#include <dcp/cpl.h>
-#include <dcp/dcp.h>
-#include <libxml++/libxml++.h>
-#include <boost/foreach.hpp>
-
-using boost::shared_ptr;
-
-SPL::SPL (boost::filesystem::path file)
-{
- cxml::Document f ("DCPPlaylist");
- f.read_file (file);
-
- name = f.string_attribute ("Name");
- BOOST_FOREACH (cxml::ConstNodePtr i, f.node_children("DCP")) {
- boost::filesystem::path dir(i->content());
- dcp::DCP dcp (dir);
- dcp.read ();
- BOOST_FOREACH (shared_ptr<dcp::CPL> j, dcp.cpls()) {
- if (j->id() == i->string_attribute("CPL")) {
- playlist.push_back (SPLEntry(j, dir));
- }
- }
- }
-}
-
-void
-SPL::as_xml (boost::filesystem::path file) const
-{
- xmlpp::Document doc;
- xmlpp::Element* root = doc.create_root_node ("DCPPlaylist");
- root->set_attribute ("Name", name);
-
- BOOST_FOREACH (SPLEntry i, playlist) {
- xmlpp::Element* d = root->add_child ("DCP");
- d->set_attribute ("CPL", i.cpl->id());
- d->add_child_text (i.directory.string());
- }
-
- doc.write_to_file_formatted(file.string());
-}
+++ /dev/null
-/*
- Copyright (C) 2018 Carl Hetherington <cth@carlh.net>
-
- This file is part of DCP-o-matic.
-
- DCP-o-matic 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.
-
- DCP-o-matic 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 DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#ifndef DCPOMATIC_SPL_H
-#define DCPOMATIC_SPL_H
-
-#include "spl_entry.h"
-#include <boost/filesystem.hpp>
-
-
-class SPL
-{
-public:
- SPL () {}
- SPL (boost::filesystem::path file);
-
- void as_xml (boost::filesystem::path file) const;
-
- std::string name;
- std::list<SPLEntry> playlist;
-};
-
-#endif
+++ /dev/null
-/*
- Copyright (C) 2018 Carl Hetherington <cth@carlh.net>
-
- This file is part of DCP-o-matic.
-
- DCP-o-matic 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.
-
- DCP-o-matic 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 DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#ifndef DCPOMATIC_SPL_ENTRY_H
-#define DCPOMATIC_SPL_ENTRY_H
-
-#include "dcpomatic_time.h"
-
-namespace dcp {
- class CPL;
-}
-
-class SPLEntry
-{
-public:
- SPLEntry (boost::shared_ptr<dcp::CPL> cpl_, boost::filesystem::path directory_)
- : cpl (cpl_)
- , directory (directory_)
- {}
-
- /* Length of black before this DCP */
- DCPTime black_before;
- boost::shared_ptr<dcp::CPL> cpl;
- boost::filesystem::path directory;
-};
-
-#endif
send_problem_report_job.cc
server.cc
shuffler.cc
- spl.cc
string_log_entry.cc
string_text_file.cc
string_text_file_content.cc
#include "lib/compose.hpp"
#include "lib/dcp_content.h"
#include "lib/job_manager.h"
-#include "lib/spl.h"
-#include "lib/spl_entry.h"
#include "lib/job.h"
#include "lib/film.h"
#include "lib/video_content.h"
Bind (wxEVT_MENU, boost::bind (&DOMFrame::back_frame, this), ID_back_frame);
Bind (wxEVT_MENU, boost::bind (&DOMFrame::forward_frame, this), ID_forward_frame);
+ reset_film ();
+
UpdateChecker::instance()->StateChanged.connect (boost::bind (&DOMFrame::update_checker_state_changed, this));
- _controls->SPLChanged.connect (boost::bind(&DOMFrame::set_spl, this, _1));
#ifdef DCPOMATIC_VARIANT_SWAROOP
MonitorChecker::instance()->StateChanged.connect(boost::bind(&DOMFrame::monitor_checker_state_changed, this));
MonitorChecker::instance()->run ();
boost::filesystem::is_regular_file(Config::path("position")) &&
boost::filesystem::is_regular_file(Config::path("spl.xml"))) {
- set_spl (SPL(Config::path("spl.xml")));
+ shared_ptr<Film> film (new Film(boost::optional<boost::filesystem::path>()));
+ film->read_metadata (Config::path("spl.xml"));
+ reset_film (film);
FILE* f = fopen_boost (Config::path("position"), "r");
if (f) {
char buffer[64];
void load_dcp (boost::filesystem::path dir)
{
+ DCPOMATIC_ASSERT (_film);
+
try {
- dcp::DCP dcp (dir);
- dcp.read ();
- SPL spl;
- BOOST_FOREACH (shared_ptr<dcp::CPL> j, dcp.cpls()) {
- spl.playlist.push_back (SPLEntry(j, dir));
+ shared_ptr<DCPContent> dcp (new DCPContent(_film, dir));
+ _film->examine_and_add_content (dcp);
+ bool const ok = display_progress (_("DCP-o-matic Player"), _("Loading DCP"));
+ if (!ok || !report_errors_from_last_job(this)) {
+ return;
}
- set_spl (spl);
Config::instance()->add_to_player_history (dir);
} catch (dcp::DCPReadError& e) {
error_dialog (this, wxString::Format(_("Could not load a DCP from %s"), std_to_wx(dir.string())), std_to_wx(e.what()));
return optional<dcp::EncryptedKDM>();
}
- void set_spl (SPL spl)
+ void reset_film (shared_ptr<Film> film = shared_ptr<Film>(new Film(optional<boost::filesystem::path>())))
{
-#ifdef DCPOMATIC_VARIANT_SWAROOP
- spl.as_xml (Config::path("spl.xml"));
-#endif
+ _film = film;
+ _viewer->set_film (_film);
+ _film->Change.connect (bind(&DOMFrame::film_changed, this, _1, _2));
+ }
- if (_viewer->playing ()) {
- _viewer->stop ();
+ void film_changed (ChangeType type, Film::Property property)
+ {
+ if (type != CHANGE_TYPE_DONE || property != Film::CONTENT) {
+ return;
}
- _film.reset (new Film (optional<boost::filesystem::path>()));
+ _film->write_metadata (Config::path("spl.xml"));
- if (spl.playlist.empty ()) {
- _viewer->set_film (_film);
- _info->triggered_update ();
- return;
+ if (_viewer->playing ()) {
+ _viewer->stop ();
}
/* Start off as Flat */
_film->set_container (Ratio::from_id("185"));
- /* Put 1 frame of black at the start so when we seek to 0 we don't see anything */
- DCPTime position = DCPTime::from_frames(1, _film->video_frame_rate());
- shared_ptr<DCPContent> first;
-
- BOOST_FOREACH (SPLEntry i, spl.playlist) {
- shared_ptr<DCPContent> dcp;
- try {
- dcp.reset (new DCPContent (_film, i.directory));
- } catch (boost::filesystem::filesystem_error& e) {
- error_dialog (this, _("Could not load DCP"), std_to_wx (e.what()));
- return;
- }
-
- if (!first) {
- first = dcp;
- }
-
- _film->examine_and_add_content (dcp, true);
- bool const ok = progress (_("Loading DCP"));
- if (!ok || !report_errors_from_last_job()) {
- return;
- }
-
- dcp->set_position (position + i.black_before);
- position += dcp->length_after_trim() + i.black_before;
-
+ BOOST_FOREACH (shared_ptr<Content> i, _film->content()) {
/* This DCP has been examined and loaded */
+ shared_ptr<DCPContent> dcp = dynamic_pointer_cast<DCPContent>(i);
+ DCPOMATIC_ASSERT (dcp);
if (dcp->needs_kdm()) {
optional<dcp::EncryptedKDM> kdm;
#ifdef DCPOMATIC_VARIANT_SWAROOP
if (dcp->three_d()) {
_film->set_three_d (true);
}
-
- _controls->log (wxString::Format(_("Load DCP %s"), i.directory.filename().string().c_str()));
}
- _viewer->set_film (_film);
_viewer->seek (DCPTime(), true);
_info->triggered_update ();
_cpl_menu->Remove (*i);
}
- if (spl.playlist.size() == 1) {
+ if (_film->content().size() == 1) {
/* Offer a CPL menu */
+ shared_ptr<DCPContent> first = dynamic_pointer_cast<DCPContent>(_film->content().front());
+ DCPOMATIC_ASSERT (first);
DCPExaminer ex (first);
int id = ID_view_cpl;
BOOST_FOREACH (shared_ptr<dcp::CPL> i, ex.cpls()) {
DCPOMATIC_ASSERT (dcp);
dcp->add_ov (wx_to_std(c->GetPath()));
JobManager::instance()->add(shared_ptr<Job>(new ExamineContentJob (_film, dcp)));
- bool const ok = progress (_("Loading DCP"));
- if (!ok || !report_errors_from_last_job()) {
+ bool const ok = display_progress (_("DCP-o-matic Player"), _("Loading DCP"));
+ if (!ok || !report_errors_from_last_job(this)) {
return;
}
BOOST_FOREACH (shared_ptr<TextContent> i, dcp->text) {
void file_close ()
{
- _viewer->set_film (shared_ptr<Film>());
- _film.reset ();
+ reset_film ();
_info->triggered_update ();
set_menu_sensitivity ();
}
JobManager* jm = JobManager::instance ();
jm->add (shared_ptr<Job> (new VerifyDCPJob (dcp->directories())));
- bool const ok = progress (_("Verifying DCP"));
+ bool const ok = display_progress (_("DCP-o-matic Player"), _("Verifying DCP"));
if (!ok) {
return;
}
private:
- /** @return false if the task was cancelled */
- bool progress (wxString task)
- {
- JobManager* jm = JobManager::instance ();
-
- wxProgressDialog* progress = new wxProgressDialog (_("DCP-o-matic Player"), task, 100, 0, wxPD_CAN_ABORT);
-
- bool ok = true;
-
- while (jm->work_to_do() || signal_manager->ui_idle()) {
- dcpomatic_sleep (1);
- if (!progress->Pulse()) {
- /* user pressed cancel */
- BOOST_FOREACH (shared_ptr<Job> i, jm->get()) {
- i->cancel();
- }
- ok = false;
- break;
- }
- }
-
- progress->Destroy ();
- return ok;
- }
-
- bool report_errors_from_last_job ()
- {
- JobManager* jm = JobManager::instance ();
-
- DCPOMATIC_ASSERT (!jm->get().empty());
-
- shared_ptr<Job> last = jm->get().back();
- if (last->finished_in_error()) {
- error_dialog(this, std_to_wx(last->error_summary()) + ".\n", std_to_wx(last->error_details()));
- return false;
- }
-
- return true;
- }
-
wxFrame* _dual_screen;
bool _update_news_requested;
PlayerInformation* _info;
#include "lib/job_manager.h"
#include "lib/player_video.h"
#include "lib/dcp_content.h"
-#include "lib/spl_entry.h"
+#include "lib/job.h"
+#include "lib/examine_content_job.h"
+#include "lib/cross.h"
#include <dcp/dcp.h>
#include <dcp/cpl.h>
#include <dcp/reel.h>
#include <wx/wx.h>
#include <wx/tglbtn.h>
#include <wx/listctrl.h>
+#include <wx/progdlg.h>
using std::string;
using std::list;
wxBoxSizer* e_sizer = new wxBoxSizer (wxHORIZONTAL);
- _cpl = new wxListCtrl (this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxLC_NO_HEADER);
+ _content_view = new wxListCtrl (this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxLC_NO_HEADER);
/* time */
- _cpl->AppendColumn (wxT(""), wxLIST_FORMAT_LEFT, 80);
+ _content_view->AppendColumn (wxT(""), wxLIST_FORMAT_LEFT, 80);
/* type */
- _cpl->AppendColumn (wxT(""), wxLIST_FORMAT_LEFT, 80);
+ _content_view->AppendColumn (wxT(""), wxLIST_FORMAT_LEFT, 80);
/* annotation text */
- _cpl->AppendColumn (wxT(""), wxLIST_FORMAT_LEFT, 580);
- e_sizer->Add (_cpl, 1, wxALL | wxEXPAND, DCPOMATIC_SIZER_GAP);
+ _content_view->AppendColumn (wxT(""), wxLIST_FORMAT_LEFT, 580);
+ e_sizer->Add (_content_view, 1, wxALL | wxEXPAND, DCPOMATIC_SIZER_GAP);
_spl_view = new wxListCtrl (this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxLC_NO_HEADER);
_spl_view->AppendColumn (wxT(""), wxLIST_FORMAT_LEFT, 80);
_log = new wxTextCtrl (this, wxID_ANY, wxT(""), wxDefaultPosition, wxSize(-1, 200), wxTE_READONLY | wxTE_MULTILINE);
_v_sizer->Add (_log, 0, wxALL | wxEXPAND, DCPOMATIC_SIZER_GAP);
- _cpl->Show (false);
+ _content_view->Show (false);
_spl_view->Show (false);
_add_button->Show (false);
_save_button->Show (false);
_forward_button->Bind (wxEVT_LEFT_DOWN, boost::bind(&Controls::forward_clicked, this, _1));
_frame_number->Bind (wxEVT_LEFT_DOWN, boost::bind(&Controls::frame_number_clicked, this));
_timecode->Bind (wxEVT_LEFT_DOWN, boost::bind(&Controls::timecode_clicked, this));
- _cpl->Bind (wxEVT_LIST_ITEM_SELECTED, boost::bind(&Controls::setup_sensitivity, this));
- _cpl->Bind (wxEVT_LIST_ITEM_DESELECTED, boost::bind(&Controls::setup_sensitivity, this));
+ _content_view->Bind (wxEVT_LIST_ITEM_SELECTED, boost::bind(&Controls::setup_sensitivity, this));
+ _content_view->Bind (wxEVT_LIST_ITEM_DESELECTED, boost::bind(&Controls::setup_sensitivity, this));
if (_jump_to_selected) {
_jump_to_selected->Bind (wxEVT_CHECKBOX, boost::bind (&Controls::jump_to_selected_clicked, this));
_jump_to_selected->SetValue (Config::instance()->jump_to_selected ());
void
Controls::add_clicked ()
{
- optional<CPL> sel = selected_cpl ();
+ shared_ptr<Content> sel = selected_content ();
DCPOMATIC_ASSERT (sel);
- _spl.playlist.push_back (SPLEntry(sel->first, sel->second));
- add_cpl_to_list (sel->first, _spl_view);
- SPLChanged (_spl);
+ _film->examine_and_add_content (sel);
+ bool const ok = display_progress (_("DCP-o-matic"), _("Loading DCP"));
+ if (!ok || !report_errors_from_last_job(this)) {
+ return;
+ }
+ if (_film->content().size() == 1) {
+ /* Put 1 frame of black at the start so when we seek to 0 we don't see anything */
+ sel->set_position (DCPTime::from_frames(1, _film->video_frame_rate()));
+ }
+ add_content_to_list (sel, _spl_view);
setup_sensitivity ();
}
);
if (d->ShowModal() == wxID_OK) {
- _spl.as_xml (boost::filesystem::path(wx_to_std(d->GetPath())));
+ _film->write_metadata(wx_to_std(d->GetPath()));
}
d->Destroy ();
);
if (d->ShowModal() == wxID_OK) {
- _spl = SPL (boost::filesystem::path(wx_to_std(d->GetPath())));
+ _film->read_metadata (boost::filesystem::path(wx_to_std(d->GetPath())));
_spl_view->DeleteAllItems ();
- BOOST_FOREACH (SPLEntry i, _spl.playlist) {
- add_cpl_to_list (i.cpl, _spl_view);
+ BOOST_FOREACH (shared_ptr<Content> i, _film->content()) {
+ shared_ptr<DCPContent> dcp = dynamic_pointer_cast<DCPContent>(i);
+ add_content_to_list (dcp, _spl_view);
}
- SPLChanged (_spl);
}
d->Destroy ();
{
/* examine content is the only job which stops the viewer working */
bool const active_job = _active_job && *_active_job != "examine_content";
- bool const c = ((_film && !_film->content().empty()) || !_spl.playlist.empty()) && !active_job;
+ bool const c = _film && !_film->content().empty() && !active_job;
_slider->Enable (c);
_rewind_button->Enable (c);
_eye->Enable (c && _film->three_d ());
}
- _add_button->Enable (Config::instance()->allow_spl_editing() && static_cast<bool>(selected_cpl()));
+ _add_button->Enable (Config::instance()->allow_spl_editing() && static_cast<bool>(selected_content()));
_save_button->Enable (Config::instance()->allow_spl_editing());
}
-optional<Controls::CPL>
-Controls::selected_cpl () const
+shared_ptr<Content>
+Controls::selected_content () const
{
- long int s = _cpl->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
+ long int s = _content_view->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
if (s == -1) {
- return optional<CPL>();
+ return shared_ptr<Content>();
}
- DCPOMATIC_ASSERT (s < int(_cpls.size()));
- return _cpls[s];
+ DCPOMATIC_ASSERT (s < int(_content.size()));
+ return _content[s];
}
void
void
Controls::show_extended_player_controls (bool s)
{
- _cpl->Show (s);
+ _content_view->Show (s);
if (s) {
update_dcp_directory ();
}
}
void
-Controls::add_cpl_to_list (shared_ptr<dcp::CPL> cpl, wxListCtrl* ctrl)
+Controls::add_content_to_list (shared_ptr<Content> content, wxListCtrl* ctrl)
{
- list<shared_ptr<dcp::Reel> > reels = cpl->reels ();
-
int const N = ctrl->GetItemCount();
wxListItem it;
- if (!reels.empty() && reels.front()->main_picture()) {
+ it.SetId(N);
+ it.SetColumn(0);
+ DCPTime length = content->length_after_trim ();
+ int seconds = length.seconds();
+ int minutes = seconds / 60;
+ seconds -= minutes * 60;
+ int hours = minutes / 60;
+ minutes -= hours * 60;
+ it.SetText(wxString::Format("%02d:%02d:%02d", hours, minutes, seconds));
+ ctrl->InsertItem(it);
+
+ shared_ptr<DCPContent> dcp = dynamic_pointer_cast<DCPContent>(content);
+ if (dcp && dcp->content_kind()) {
it.SetId(N);
- it.SetColumn(0);
- int seconds = rint(double(cpl->duration()) / reels.front()->main_picture()->frame_rate().as_float());
- int minutes = seconds / 60;
- seconds -= minutes * 60;
- int hours = minutes / 60;
- minutes -= hours * 60;
- it.SetText(wxString::Format("%02d:%02d:%02d", hours, minutes, seconds));
- ctrl->InsertItem(it);
+ it.SetColumn(1);
+ it.SetText(std_to_wx(dcp::content_kind_to_string(*dcp->content_kind())));
+ ctrl->SetItem(it);
}
- it.SetId(N);
- it.SetColumn(1);
- it.SetText(std_to_wx(dcp::content_kind_to_string(cpl->content_kind())));
- ctrl->SetItem(it);
-
it.SetId(N);
it.SetColumn(2);
- it.SetText(std_to_wx(cpl->annotation_text()));
+ it.SetText(std_to_wx(content->summary()));
ctrl->SetItem(it);
}
void
Controls::update_dcp_directory ()
{
- if (!_cpl->IsShown()) {
+ if (!_content_view->IsShown()) {
return;
}
using namespace boost::filesystem;
- _cpl->DeleteAllItems ();
- _cpls.clear ();
+ _content_view->DeleteAllItems ();
+ _content.clear ();
optional<path> dir = Config::instance()->player_content_directory();
if (!dir) {
return;
}
+ wxProgressDialog progress (_("DCP-o-matic"), _("Reading DCP directory"));
+ JobManager* jm = JobManager::instance ();
+
for (directory_iterator i = directory_iterator(*dir); i != directory_iterator(); ++i) {
try {
if (is_directory(*i) && (is_regular_file(*i / "ASSETMAP") || is_regular_file(*i / "ASSETMAP.xml"))) {
- string const x = i->path().string().substr(dir->string().length() + 1);
- dcp::DCP dcp (*i);
- dcp.read ();
- BOOST_FOREACH (shared_ptr<dcp::CPL> j, dcp.cpls()) {
- add_cpl_to_list (j, _cpl);
- _cpls.push_back (make_pair(j, *i));
+ shared_ptr<DCPContent> content (new DCPContent(_film, *i));
+ jm->add (shared_ptr<Job>(new ExamineContentJob(_film, content)));
+ while (jm->work_to_do()) {
+ if (!progress.Pulse()) {
+ /* user pressed cancel */
+ BOOST_FOREACH (shared_ptr<Job> i, jm->get()) {
+ i->cancel();
+ }
+ return;
+ }
+ dcpomatic_sleep (1);
+ }
+ if (report_errors_from_last_job (this)) {
+ add_content_to_list (content, _content_view);
+ _content.push_back (content);
}
}
} catch (boost::filesystem::filesystem_error& e) {
#include "lib/dcpomatic_time.h"
#include "lib/types.h"
#include "lib/film.h"
-#include "lib/spl.h"
#include <wx/wx.h>
#include <boost/shared_ptr.hpp>
#include <boost/signals2.hpp>
void show_extended_player_controls (bool s);
void log (wxString s);
- boost::signals2::signal<void (SPL)> SPLChanged;
-
private:
void update_position_label ();
void update_position_slider ();
typedef std::pair<boost::shared_ptr<dcp::CPL>, boost::filesystem::path> CPL;
- boost::optional<CPL> selected_cpl () const;
+ boost::shared_ptr<Content> selected_content () const;
#ifdef DCPOMATIC_VARIANT_SWAROOP
void pause_clicked ();
void stop_clicked ();
void add_clicked ();
void save_clicked ();
void load_clicked ();
- void add_cpl_to_list (boost::shared_ptr<dcp::CPL> cpl, wxListCtrl* list);
+ void add_content_to_list (boost::shared_ptr<Content> content, wxListCtrl* list);
boost::shared_ptr<Film> _film;
boost::shared_ptr<FilmViewer> _viewer;
wxCheckBox* _outline_content;
wxChoice* _eye;
wxCheckBox* _jump_to_selected;
- wxListCtrl* _cpl;
+ wxListCtrl* _content_view;
wxListCtrl* _spl_view;
wxTextCtrl* _log;
wxButton* _add_button;
wxButton* _save_button;
wxButton* _load_button;
- std::vector<CPL> _cpls;
+ std::vector<boost::shared_ptr<Content> > _content;
wxSlider* _slider;
wxButton* _rewind_button;
wxButton* _back_button;
wxToggleButton* _play_button;
#endif
boost::optional<std::string> _active_job;
- SPL _spl;
ClosedCaptionsDialog* _closed_captions_dialog;
/*
- Copyright (C) 2012-2016 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2012-2018 Carl Hetherington <cth@carlh.net>
This file is part of DCP-o-matic.
#include "wx_util.h"
#include "file_picker_ctrl.h"
#include "lib/config.h"
+#include "lib/job_manager.h"
#include "lib/util.h"
#include "lib/cross.h"
+#include "lib/job.h"
#include <dcp/locale_convert.h>
#include <wx/spinctrl.h>
#include <wx/splash.h>
+#include <wx/progdlg.h>
#include <wx/filepicker.h>
#include <boost/thread.hpp>
-using namespace std;
-using namespace boost;
+using std::string;
+using std::vector;
+using std::pair;
+using boost::shared_ptr;
+using boost::optional;
using dcp::locale_convert;
wxStaticText *
return mark_interval;
}
+
+
+/** @return false if the task was cancelled */
+bool
+display_progress (wxString title, wxString task)
+{
+ JobManager* jm = JobManager::instance ();
+
+ wxProgressDialog progress (title, task, 100, 0, wxPD_CAN_ABORT);
+
+ bool ok = true;
+
+ while (jm->work_to_do()) {
+ dcpomatic_sleep (1);
+ if (!progress.Pulse()) {
+ /* user pressed cancel */
+ BOOST_FOREACH (shared_ptr<Job> i, jm->get()) {
+ i->cancel();
+ }
+ ok = false;
+ break;
+ }
+ }
+
+ return ok;
+}
+
+bool
+report_errors_from_last_job (wxWindow* parent)
+{
+ JobManager* jm = JobManager::instance ();
+
+ DCPOMATIC_ASSERT (!jm->get().empty());
+
+ shared_ptr<Job> last = jm->get().back();
+ if (last->finished_in_error()) {
+ error_dialog(parent, std_to_wx(last->error_summary()) + ".\n", std_to_wx(last->error_details()));
+ return false;
+ }
+
+ return true;
+}
extern void setup_audio_channels_choice (wxChoice* choice, int minimum);
extern wxSplashScreen* maybe_show_splash ();
extern double calculate_mark_interval (double start);
+extern bool display_progress (wxString title, wxString task);
+extern bool report_errors_from_last_job (wxWindow* parent);
extern void checked_set (FilePickerCtrl* widget, boost::filesystem::path value);
extern void checked_set (wxDirPickerCtrl* widget, boost::filesystem::path value);