From: Carl Hetherington Date: Sun, 29 Jan 2017 23:51:25 +0000 (+0000) Subject: Merge branch 'master' of ssh://git.carlh.net/home/carl/git/dcpomatic X-Git-Tag: v2.10.7-test~4 X-Git-Url: https://git.carlh.net/gitweb/?p=dcpomatic.git;a=commitdiff_plain;h=b3234e76d2f614c2b05034c0bdae8d5a4e9de9ea;hp=70b923d244255cc1425f0ade4b3d280e07da7038 Merge branch 'master' of ssh://git.carlh.net/home/carl/git/dcpomatic --- diff --git a/ChangeLog b/ChangeLog index f9744368b..28316e12e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2017-01-28 Carl Hetherington + + * Add priority control buttons to batch converter (#961). + 2017-01-18 Carl Hetherington * Updated uk_UA translation from Igor Voytovich. diff --git a/cscript b/cscript index 808432fda..adafda00a 100644 --- a/cscript +++ b/cscript @@ -269,7 +269,7 @@ def dependencies(target): return (('ffmpeg-cdist', 'c7df8d5', ffmpeg_options), ('libdcp', '839bc2d'), - ('libsub', '2163c97')) + ('libsub', 'd557f39')) def configure_options(target): opt = '' diff --git a/graphics/wscript b/graphics/wscript index d70ba1e69..26fad9fa7 100644 --- a/graphics/wscript +++ b/graphics/wscript @@ -28,5 +28,5 @@ def build(bld): # Install stuff for POSIX systems if not bld.env.TARGET_WINDOWS: - bld.install_files('${PREFIX}/share/dcpomatic2', 'linux/16/dcpomatic2.png') + bld.install_as('${PREFIX}/share/dcpomatic2/dcpomatic2_server_small.png', 'linux/16/dcpomatic2.png') bld.install_files('${PREFIX}/share/dcpomatic2', 'splash.png') diff --git a/src/lib/job.cc b/src/lib/job.cc index dba21f91c..dacc8bf31 100644 --- a/src/lib/job.cc +++ b/src/lib/job.cc @@ -239,10 +239,17 @@ Job::finished_cancelled () const } bool -Job::paused () const +Job::paused_by_user () const { boost::mutex::scoped_lock lm (_state_mutex); - return _state == PAUSED; + return _state == PAUSED_BY_USER; +} + +bool +Job::paused_by_priority () const +{ + boost::mutex::scoped_lock lm (_state_mutex); + return _state == PAUSED_BY_PRIORITY; } /** Set the state of this job. @@ -287,7 +294,7 @@ Job::check_for_interruption_or_pause () boost::this_thread::interruption_point (); boost::mutex::scoped_lock lm (_state_mutex); - while (_state == PAUSED) { + while (_state == PAUSED_BY_USER || _state == PAUSED_BY_PRIORITY) { emit (boost::bind (boost::ref (Progress))); _pause_changed.wait (lm); } @@ -450,7 +457,8 @@ Job::json_status () const return N_("new"); case RUNNING: return N_("running"); - case PAUSED: + case PAUSED_BY_USER: + case PAUSED_BY_PRIORITY: return N_("paused"); case FINISHED_OK: return N_("finished_ok"); @@ -481,7 +489,7 @@ Job::cancel () return; } - if (paused ()) { + if (paused_by_user() || paused_by_priority()) { resume (); } @@ -493,10 +501,19 @@ Job::cancel () } void -Job::pause () +Job::pause_by_user () +{ + if (running ()) { + set_state (PAUSED_BY_USER); + _pause_changed.notify_all (); + } +} + +void +Job::pause_by_priority () { if (running ()) { - set_state (PAUSED); + set_state (PAUSED_BY_PRIORITY); _pause_changed.notify_all (); } } @@ -504,7 +521,7 @@ Job::pause () void Job::resume () { - if (paused ()) { + if (paused_by_user() || paused_by_priority()) { set_state (RUNNING); _pause_changed.notify_all (); } diff --git a/src/lib/job.h b/src/lib/job.h index 660ddaa13..311f9cc91 100644 --- a/src/lib/job.h +++ b/src/lib/job.h @@ -50,7 +50,8 @@ public: virtual void run () = 0; void start (); - void pause (); + void pause_by_user (); + void pause_by_priority (); void resume (); void cancel (); @@ -60,7 +61,8 @@ public: bool finished_ok () const; bool finished_in_error () const; bool finished_cancelled () const; - bool paused () const; + bool paused_by_user () const; + bool paused_by_priority () const; std::string error_summary () const; std::string error_details () const; @@ -94,7 +96,8 @@ protected: enum State { NEW, ///< the job hasn't been started yet RUNNING, ///< the job is running - PAUSED, ///< the job has been paused + PAUSED_BY_USER, ///< the job has been paused + PAUSED_BY_PRIORITY, ///< the job has been paused FINISHED_OK, ///< the job has finished successfully FINISHED_ERROR, ///< the job has finished in error FINISHED_CANCELLED ///< the job was cancelled diff --git a/src/lib/job_manager.cc b/src/lib/job_manager.cc index c9924d226..3992e685e 100644 --- a/src/lib/job_manager.cc +++ b/src/lib/job_manager.cc @@ -210,3 +210,72 @@ JobManager::analyse_audio ( emit (boost::bind (boost::ref (JobAdded), weak_ptr (job))); } + +void +JobManager::increase_priority (shared_ptr job) +{ + bool changed = false; + + { + boost::mutex::scoped_lock lm (_mutex); + list >::iterator last = _jobs.end (); + for (list >::iterator i = _jobs.begin(); i != _jobs.end(); ++i) { + if (*i == job && last != _jobs.end()) { + swap (*i, *last); + changed = true; + break; + } + last = i; + } + } + + if (changed) { + priority_changed (); + } +} + +void +JobManager::priority_changed () +{ + { + boost::mutex::scoped_lock lm (_mutex); + + bool first = true; + BOOST_FOREACH (shared_ptr i, _jobs) { + if (first) { + if (i->is_new ()) { + i->start (); + } else if (i->paused_by_priority ()) { + i->resume (); + } + first = false; + } else { + if (i->running ()) { + i->pause_by_priority (); + } + } + } + } + + emit (boost::bind (boost::ref (JobsReordered))); +} + +void +JobManager::decrease_priority (shared_ptr job) +{ + bool changed = false; + + for (list >::iterator i = _jobs.begin(); i != _jobs.end(); ++i) { + list >::iterator next = i; + ++next; + if (*i == job && next != _jobs.end()) { + swap (*i, *next); + changed = true; + break; + } + } + + if (changed) { + priority_changed (); + } +} diff --git a/src/lib/job_manager.h b/src/lib/job_manager.h index c6be2a78e..c623b6ef9 100644 --- a/src/lib/job_manager.h +++ b/src/lib/job_manager.h @@ -40,11 +40,12 @@ extern bool wait_for_jobs (); class JobManager : public Signaller, public boost::noncopyable { public: - boost::shared_ptr add (boost::shared_ptr); std::list > get () const; bool work_to_do () const; bool errors () const; + void increase_priority (boost::shared_ptr); + void decrease_priority (boost::shared_ptr); void analyse_audio ( boost::shared_ptr film, @@ -54,6 +55,7 @@ public: ); boost::signals2::signal)> JobAdded; + boost::signals2::signal JobsReordered; boost::signals2::signal, boost::optional)> ActiveJobsChanged; static JobManager* instance (); @@ -67,8 +69,10 @@ private: ~JobManager (); void scheduler (); void start (); + void priority_changed (); mutable boost::mutex _mutex; + /** List of jobs in the order that they will be executed */ std::list > _jobs; bool _terminate; diff --git a/src/tools/dcpomatic_batch.cc b/src/tools/dcpomatic_batch.cc index 054497c33..308874354 100644 --- a/src/tools/dcpomatic_batch.cc +++ b/src/tools/dcpomatic_batch.cc @@ -59,7 +59,7 @@ void setup_menu (wxMenuBar* m) { wxMenu* file = new wxMenu; - file->Append (ID_file_add_film, _("&Add Film...")); + file->Append (ID_file_add_film, _("&Add Film...\tCtrl-A")); #ifdef DCPOMATIC_OSX file->Append (wxID_EXIT, _("&Exit")); #else diff --git a/src/wx/batch_job_view.cc b/src/wx/batch_job_view.cc index 2a5e690d7..772c726f2 100644 --- a/src/wx/batch_job_view.cc +++ b/src/wx/batch_job_view.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2016 Carl Hetherington + Copyright (C) 2012-2017 Carl Hetherington This file is part of DCP-o-matic. @@ -19,8 +19,11 @@ */ #include "batch_job_view.h" +#include "lib/job_manager.h" #include +#include +using std::list; using boost::shared_ptr; BatchJobView::BatchJobView (shared_ptr job, wxWindow* parent, wxWindow* container, wxFlexGridSizer* table) @@ -34,3 +37,44 @@ BatchJobView::insert_position () const { return _table->GetEffectiveRowsCount() * _table->GetEffectiveColsCount(); } + +void +BatchJobView::finish_setup (wxWindow* parent, wxSizer* sizer) +{ + _higher_priority = new wxButton (parent, wxID_ANY, _("Higher prioirity")); + _higher_priority->Bind (wxEVT_BUTTON, boost::bind (&BatchJobView::higher_priority_clicked, this)); + sizer->Add (_higher_priority, 1, wxALIGN_CENTER_VERTICAL); + _lower_priority = new wxButton (parent, wxID_ANY, _("Lower prioirity")); + _lower_priority->Bind (wxEVT_BUTTON, boost::bind (&BatchJobView::lower_priority_clicked, this)); + sizer->Add (_lower_priority, 1, wxALIGN_CENTER_VERTICAL); +} +void +BatchJobView::higher_priority_clicked () +{ + JobManager::instance()->increase_priority (_job); +} + +void +BatchJobView::lower_priority_clicked () +{ + JobManager::instance()->decrease_priority (_job); +} + +void +BatchJobView::job_list_changed () +{ + bool high = false; + bool low = false; + list > jobs = JobManager::instance()->get(); + if (!jobs.empty ()) { + if (_job != jobs.front()) { + high = true; + } + if (_job != jobs.back()) { + low = true; + } + } + + _higher_priority->Enable (high); + _lower_priority->Enable (low); +} diff --git a/src/wx/batch_job_view.h b/src/wx/batch_job_view.h index d65596864..40dceff31 100644 --- a/src/wx/batch_job_view.h +++ b/src/wx/batch_job_view.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2016 Carl Hetherington + Copyright (C) 2012-2017 Carl Hetherington This file is part of DCP-o-matic. @@ -27,4 +27,12 @@ public: private: int insert_position () const; + void job_list_changed (); + + void finish_setup (wxWindow* parent, wxSizer* sizer); + void higher_priority_clicked (); + void lower_priority_clicked (); + + wxButton* _higher_priority; + wxButton* _lower_priority; }; diff --git a/src/wx/job_manager_view.cc b/src/wx/job_manager_view.cc index 6cea40c89..42d5f9dbe 100644 --- a/src/wx/job_manager_view.cc +++ b/src/wx/job_manager_view.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2015 Carl Hetherington + Copyright (C) 2012-2017 Carl Hetherington This file is part of DCP-o-matic. @@ -31,6 +31,7 @@ #include "lib/util.h" #include "lib/exceptions.h" #include "lib/compose.hpp" +#include #include using std::string; @@ -40,6 +41,7 @@ using std::min; using std::cout; using boost::shared_ptr; using boost::weak_ptr; +using boost::bind; /** @param parent Parent window. * @param batch true to use BatchJobView, false to use NormalJobView. @@ -67,6 +69,7 @@ JobManagerView::JobManagerView (wxWindow* parent, bool batch) _timer->Start (1000); JobManager::instance()->JobAdded.connect (bind (&JobManagerView::job_added, this, _1)); + JobManager::instance()->JobsReordered.connect (bind (&JobManagerView::replace, this)); } void @@ -85,6 +88,7 @@ JobManagerView::job_added (weak_ptr j) } FitInside(); + job_list_changed (); } void @@ -94,3 +98,41 @@ JobManagerView::periodic () (*i)->maybe_pulse (); } } + +void +JobManagerView::replace () +{ + /* Make a new version of _job_records which reflects the order in JobManager's job list */ + + list > new_job_records; + + BOOST_FOREACH (shared_ptr i, JobManager::instance()->get()) { + /* Find this job's JobView */ + BOOST_FOREACH (shared_ptr j, _job_records) { + if (j->job() == i) { + new_job_records.push_back (j); + break; + } + } + } + + BOOST_FOREACH (shared_ptr i, _job_records) { + i->detach (); + } + + _job_records = new_job_records; + + BOOST_FOREACH (shared_ptr i, _job_records) { + i->insert (i->insert_position ()); + } + + job_list_changed (); +} + +void +JobManagerView::job_list_changed () +{ + BOOST_FOREACH (shared_ptr i, _job_records) { + i->job_list_changed (); + } +} diff --git a/src/wx/job_manager_view.h b/src/wx/job_manager_view.h index 7784c71ee..77114a97c 100644 --- a/src/wx/job_manager_view.h +++ b/src/wx/job_manager_view.h @@ -40,6 +40,8 @@ public: private: void job_added (boost::weak_ptr); void periodic (); + void replace (); + void job_list_changed (); wxPanel* _panel; wxFlexGridSizer* _table; diff --git a/src/wx/job_view.cc b/src/wx/job_view.cc index 8e7040c3b..13c3bc7ab 100644 --- a/src/wx/job_view.cc +++ b/src/wx/job_view.cc @@ -52,20 +52,20 @@ JobView::setup () _table->Insert (n, _gauge_message, 1, wxEXPAND | wxLEFT | wxRIGHT); ++n; - wxBoxSizer* buttons = new wxBoxSizer (wxHORIZONTAL); + _buttons = new wxBoxSizer (wxHORIZONTAL); _cancel = new wxButton (_container, wxID_ANY, _("Cancel")); _cancel->Bind (wxEVT_BUTTON, &JobView::cancel_clicked, this); - buttons->Add (_cancel, 1, wxALIGN_CENTER_VERTICAL); + _buttons->Add (_cancel, 1, wxALIGN_CENTER_VERTICAL); _details = new wxButton (_container, wxID_ANY, _("Details...")); _details->Bind (wxEVT_BUTTON, &JobView::details_clicked, this); _details->Enable (false); - buttons->Add (_details, 1, wxALIGN_CENTER_VERTICAL); + _buttons->Add (_details, 1, wxALIGN_CENTER_VERTICAL); - finish_setup (_container, buttons); + finish_setup (_container, _buttons); - _table->Insert (n, buttons, 1, wxALIGN_CENTER_VERTICAL | wxALL, 3); + _table->Insert (n, _buttons, 1, wxALIGN_CENTER_VERTICAL | wxALL, 3); _progress_connection = _job->Progress.connect (boost::bind (&JobView::progress, this)); _finished_connection = _job->Finished.connect (boost::bind (&JobView::finished, this)); @@ -134,3 +134,18 @@ JobView::cancel_clicked (wxCommandEvent &) _job->cancel (); } } + +void +JobView::insert (int pos) +{ + _table->Insert (pos, _gauge_message, 1, wxEXPAND | wxLEFT | wxRIGHT); + _table->Insert (pos + 1, _buttons, 1, wxALIGN_CENTER_VERTICAL | wxALL, 3); + _table->Layout (); +} + +void +JobView::detach () +{ + _table->Detach (_gauge_message); + _table->Detach (_buttons); +} diff --git a/src/wx/job_view.h b/src/wx/job_view.h index 8cd34fdab..8c0214d9d 100644 --- a/src/wx/job_view.h +++ b/src/wx/job_view.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2015 Carl Hetherington + Copyright (C) 2012-2017 Carl Hetherington This file is part of DCP-o-matic. @@ -42,19 +42,28 @@ public: JobView (boost::shared_ptr job, wxWindow* parent, wxWindow* container, wxFlexGridSizer* table); virtual ~JobView () {} - void setup (); + virtual int insert_position () const = 0; + virtual void job_list_changed () {} + void setup (); void maybe_pulse (); + void insert (int pos); + void detach (); + + boost::shared_ptr job () const { + return _job; + } protected: virtual void finished (); boost::shared_ptr _job; wxFlexGridSizer* _table; + wxBoxSizer* _buttons; + wxBoxSizer* _gauge_message; private: - virtual int insert_position () const = 0; virtual void finish_setup (wxWindow *, wxSizer *) {} void progress (); @@ -63,7 +72,6 @@ private: wxWindow* _parent; wxWindow* _container; - wxBoxSizer* _gauge_message; wxGauge* _gauge; wxStaticText* _message; wxButton* _cancel; diff --git a/src/wx/normal_job_view.cc b/src/wx/normal_job_view.cc index 9bfa332c9..22b3e1cc7 100644 --- a/src/wx/normal_job_view.cc +++ b/src/wx/normal_job_view.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2016 Carl Hetherington + Copyright (C) 2012-2017 Carl Hetherington This file is part of DCP-o-matic. @@ -48,11 +48,11 @@ NormalJobView::insert_position () const void NormalJobView::pause_clicked () { - if (_job->paused()) { + if (_job->paused_by_user()) { _job->resume (); _pause->SetLabel (_("Pause")); } else { - _job->pause (); + _job->pause_by_user (); _pause->SetLabel (_("Resume")); } }