#include "wx/wx_util.h"
#include "lib/analytics.h"
#include "lib/audio_content.h"
-#include "lib/check_content_change_job.h"
+#include "lib/check_content_job.h"
#include "lib/cinema.h"
#include "lib/compose.hpp"
#include "lib/config.h"
#include "lib/kdm_with_metadata.h"
#include "lib/log.h"
#include "lib/make_dcp.h"
+#include "lib/release_notes.h"
#include "lib/screen.h"
#include "lib/send_kdm_email_job.h"
#include "lib/signal_manager.h"
public:
explicit DOMFrame (wxString const& title)
: wxFrame (nullptr, -1, title)
+ /* Use a panel as the only child of the Frame so that we avoid
+ the dark-grey background on Windows.
+ */
+ , _overall_panel(new wxPanel(this, wxID_ANY))
+ , _film_viewer(_overall_panel)
{
#if defined(DCPOMATIC_WINDOWS)
if (Config::instance()->win32_console()) {
Bind (wxEVT_CLOSE_WINDOW, boost::bind (&DOMFrame::close, this, _1));
Bind (wxEVT_SHOW, boost::bind (&DOMFrame::show, this, _1));
- /* Use a panel as the only child of the Frame so that we avoid
- the dark-grey background on Windows.
- */
- auto overall_panel = new wxPanel (this, wxID_ANY);
-
- _film_viewer.reset (new FilmViewer (overall_panel));
- _controls = new StandardControls (overall_panel, _film_viewer, true);
- _film_editor = new FilmEditor (overall_panel, _film_viewer);
- auto job_manager_view = new JobManagerView (overall_panel, false);
+ _controls = new StandardControls(_overall_panel, _film_viewer, true);
+ _film_editor = new FilmEditor(_overall_panel, _film_viewer);
+ auto job_manager_view = new JobManagerView(_overall_panel, false);
auto right_sizer = new wxBoxSizer (wxVERTICAL);
- right_sizer->Add (_film_viewer->panel(), 2, wxEXPAND | wxALL, 6);
+ right_sizer->Add(_film_viewer.panel(), 2, wxEXPAND | wxALL, 6);
right_sizer->Add (_controls, 0, wxEXPAND | wxALL, 6);
right_sizer->Add (job_manager_view, 1, wxEXPAND | wxALL, 6);
_film_editor->content_panel()->SelectionChanged.connect (boost::bind (&DOMFrame::set_menu_sensitivity, this));
set_title ();
- JobManager::instance()->ActiveJobsChanged.connect (boost::bind (&DOMFrame::set_menu_sensitivity, this));
+ JobManager::instance()->ActiveJobsChanged.connect(boost::bind(&DOMFrame::active_jobs_changed, this));
- overall_panel->SetSizer (main_sizer);
+ _overall_panel->SetSizer(main_sizer);
UpdateChecker::instance()->StateChanged.connect(boost::bind(&DOMFrame::update_checker_state_changed, this));
#else
int accelerators = 6;
#endif
- auto accel = new wxAcceleratorEntry[accelerators];
+ std::vector<wxAcceleratorEntry> accel(accelerators);
/* [Shortcut] Ctrl+A:Add file(s) to the film */
accel[0].Set (wxACCEL_CTRL, static_cast<int>('A'), ID_add_file);
/* [Shortcut] Delete:Remove selected content from film */
Bind (wxEVT_MENU, boost::bind (&DOMFrame::timeline_pressed, this), ID_timeline);
Bind (wxEVT_MENU, boost::bind (&DOMFrame::back_frame, this), ID_back_frame);
Bind (wxEVT_MENU, boost::bind (&DOMFrame::forward_frame, this), ID_forward_frame);
- wxAcceleratorTable accel_table (accelerators, accel);
+ wxAcceleratorTable accel_table (accelerators, accel.data());
SetAcceleratorTable (accel_table);
- delete[] accel;
}
void remove_accelerators ()
set_film (film);
- JobManager::instance()->add(shared_ptr<Job>(new CheckContentChangeJob(film)));
+ JobManager::instance()->add(make_shared<CheckContentJob>(film));
}
catch (FileNotFoundError& e) {
auto const dir = e.file().parent_path();
void set_film (shared_ptr<Film> film)
{
_film = film;
- _film_viewer->set_film (_film);
- _film_editor->set_film (_film);
+ _film_viewer.set_film(_film);
+ _film_editor->set_film(_film);
_controls->set_film (_film);
if (_video_waveform_dialog) {
_video_waveform_dialog->Destroy ();
if (_film) {
_film->Change.connect (boost::bind (&DOMFrame::film_change, this, _1));
_film->Message.connect (boost::bind(&DOMFrame::film_message, this, _1));
+ _film->DirtyChange.connect (boost::bind(&DOMFrame::set_title, this));
dcpomatic_log = _film->log ();
}
set_title ();
void view_closed_captions ()
{
- _film_viewer->show_closed_captions ();
+ _film_viewer.show_closed_captions ();
}
void view_video_waveform ()
ev.Skip ();
}
+ void active_jobs_changed()
+ {
+ /* ActiveJobsChanged can be called while JobManager holds a lock on its mutex, making
+ * the call to JobManager::get() in set_menu_sensitivity() deadlock unless we work around
+ * it by using an idle callback. This feels quite unpleasant.
+ */
+ signal_manager->when_idle(boost::bind(&DOMFrame::set_menu_sensitivity, this));
+ }
+
void set_menu_sensitivity ()
{
auto jobs = JobManager::instance()->get ();
void start_stop_pressed ()
{
- if (_film_viewer->playing()) {
- _film_viewer->stop();
+ if (_film_viewer.playing()) {
+ _film_viewer.stop();
} else {
- _film_viewer->start();
+ _film_viewer.start();
}
}
void back_frame ()
{
- _film_viewer->seek_by (-_film_viewer->one_video_frame(), true);
+ _film_viewer.seek_by(-_film_viewer.one_video_frame(), true);
}
void forward_frame ()
{
- _film_viewer->seek_by (_film_viewer->one_video_frame(), true);
+ _film_viewer.seek_by(_film_viewer.one_video_frame(), true);
}
void analytics_message (string title, string html)
void set_title ()
{
auto s = wx_to_std(_("DCP-o-matic"));
- if (_film && _film->directory()) {
- s += " - " + _film->directory()->string();
+ if (_film) {
+ if (_film->directory()) {
+ s += " - " + _film->directory()->string();
+ }
+ if (_film->dirty()) {
+ s += " *";
+ }
}
SetTitle (std_to_wx(s));
}
FilmEditor* _film_editor;
- std::shared_ptr<FilmViewer> _film_viewer;
+ wxPanel* _overall_panel;
+ FilmViewer _film_viewer;
StandardControls* _controls;
VideoWaveformDialog* _video_waveform_dialog = nullptr;
SystemInformationDialog* _system_information_dialog = nullptr;
try {
wxInitAllImageHandlers ();
- Config::FailedToLoad.connect (boost::bind (&App::config_failed_to_load, this));
+ Config::FailedToLoad.connect(boost::bind(&App::config_failed_to_load, this, _1));
Config::Warning.connect (boost::bind (&App::config_warning, this, _1));
_splash = maybe_show_splash ();
if (Config::instance()->check_for_updates ()) {
UpdateChecker::instance()->run ();
}
+
+ auto release_notes = find_release_notes();
+ if (release_notes) {
+ auto notes = new HTMLDialog(nullptr, _("Release notes"), std_to_wx(*release_notes), true);
+ notes->Centre();
+ notes->ShowModal();
+ notes->Destroy();
+ }
}
catch (exception& e)
{
}
}
- void config_failed_to_load ()
+ void config_failed_to_load (Config::LoadFailure what)
{
- message_dialog (_frame, _("The existing configuration failed to load. Default values will be used instead. These may take a short time to create."));
+ report_config_load_failure(_frame, what);
}
void config_warning (string m)