X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Ftools%2Fdcpomatic_batch.cc;h=e476c2163a552a8842b05bc566c37fcba80b3262;hb=HEAD;hp=d3aa2500b6fe22965c206e8dae2406df308059b0;hpb=b915348a8288d68e2ff114fb3dd89ad22e699969;p=dcpomatic.git diff --git a/src/tools/dcpomatic_batch.cc b/src/tools/dcpomatic_batch.cc index d3aa2500b..e476c2163 100644 --- a/src/tools/dcpomatic_batch.cc +++ b/src/tools/dcpomatic_batch.cc @@ -22,8 +22,10 @@ #include "wx/about_dialog.h" #include "wx/dcpomatic_button.h" #include "wx/full_config_dialog.h" +#include "wx/id.h" #include "wx/job_manager_view.h" #include "wx/servers_list_dialog.h" +#include "wx/wx_ptr.h" #include "wx/wx_signal_manager.h" #include "wx/wx_util.h" #include "lib/compose.hpp" @@ -32,15 +34,21 @@ #include "lib/film.h" #include "lib/job.h" #include "lib/job_manager.h" +#include "lib/make_dcp.h" #include "lib/transcode_job.h" #include "lib/util.h" #include "lib/version.h" +#include +#include +LIBDCP_DISABLE_WARNINGS #include #include +#include #include #include #include #include +LIBDCP_ENABLE_WARNINGS #include #include @@ -64,7 +72,7 @@ static list films_to_load; enum { - ID_file_add_film = 1, + ID_file_add_film = DCPOMATIC_MAIN_MENU, ID_tools_encoding_servers, ID_help_about }; @@ -82,7 +90,7 @@ setup_menu (wxMenuBar* m) #endif #ifdef DCPOMATIC_OSX - file->Append (wxID_PREFERENCES, _("&Preferences...\tCtrl-P")); + file->Append(wxID_PREFERENCES, _("&Preferences...\tCtrl-,")); #else auto edit = new wxMenu; edit->Append (wxID_PREFERENCES, _("&Preferences...\tCtrl-P")); @@ -106,6 +114,36 @@ setup_menu (wxMenuBar* m) class DOMFrame : public wxFrame { public: + enum class Tool { + ADD, + PAUSE + }; + + class DCPDropTarget : public wxFileDropTarget + { + public: + DCPDropTarget(DOMFrame* owner) + : _frame(owner) + {} + + bool OnDropFiles(wxCoord, wxCoord, wxArrayString const& filenames) override + { + if (filenames.GetCount() == 1) { + /* Try to load a directory */ + auto path = boost::filesystem::path(wx_to_std(filenames[0])); + if (dcp::filesystem::is_directory(path)) { + _frame->start_job(wx_to_std(filenames[0])); + return true; + } + } + + return false; + } + + private: + DOMFrame* _frame; + }; + explicit DOMFrame (wxString const & title) : wxFrame (nullptr, -1, title) , _sizer (new wxBoxSizer(wxVERTICAL)) @@ -127,46 +165,47 @@ public: s->Add (panel, 1, wxEXPAND); SetSizer (s); - auto job_manager_view = new JobManagerView (panel, true); - _sizer->Add (job_manager_view, 1, wxALL | wxEXPAND, 6); + wxBitmap add(icon_path("add"), wxBITMAP_TYPE_PNG); + wxBitmap pause(icon_path("pause"), wxBITMAP_TYPE_PNG); - auto buttons = new wxBoxSizer (wxHORIZONTAL); - auto add = new Button (panel, _("Add Film...")); - add->Bind (wxEVT_BUTTON, boost::bind(&DOMFrame::add_film, this)); - buttons->Add (add, 1, wxALL, 6); - _pause = new Button (panel, _("Pause")); - _pause->Bind (wxEVT_BUTTON, boost::bind(&DOMFrame::pause, this)); - buttons->Add (_pause, 1, wxALL, 6); - _resume = new Button (panel, _("Resume")); - _resume->Bind (wxEVT_BUTTON, boost::bind(&DOMFrame::resume, this)); - buttons->Add (_resume, 1, wxALL, 6); + auto toolbar = new wxToolBar(panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTB_HORIZONTAL); + toolbar->SetMargins(4, 4); + toolbar->SetToolBitmapSize(wxSize(32, 32)); + toolbar->AddTool(static_cast(Tool::ADD), _("Add film"), add, _("Add film for conversion")); + toolbar->AddCheckTool(static_cast(Tool::PAUSE), _("Pause/resume"), pause, wxNullBitmap, _("Pause or resume conversion")); + toolbar->Realize(); + _sizer->Add(toolbar, 0, wxALL, 6); - setup_sensitivity (); + toolbar->Bind(wxEVT_TOOL, bind(&DOMFrame::tool_clicked, this, _1)); - _sizer->Add (buttons, 0, wxALL, 6); + auto job_manager_view = new JobManagerView (panel, true); + _sizer->Add (job_manager_view, 1, wxALL | wxEXPAND, 6); panel->SetSizer (_sizer); Bind (wxEVT_CLOSE_WINDOW, boost::bind(&DOMFrame::close, this, _1)); Bind (wxEVT_SIZE, boost::bind(&DOMFrame::sized, this, _1)); - } - void setup_sensitivity () - { - _pause->Enable (!JobManager::instance()->paused()); - _resume->Enable (JobManager::instance()->paused()); - } - - void pause () - { - JobManager::instance()->pause(); - setup_sensitivity (); + SetDropTarget(new DCPDropTarget(this)); } - void resume () + void tool_clicked(wxCommandEvent& ev) { - JobManager::instance()->resume(); - setup_sensitivity (); + switch (static_cast(ev.GetId())) { + case Tool::ADD: + add_film(); + break; + case Tool::PAUSE: + { + auto jm = JobManager::instance(); + if (jm->paused()) { + jm->resume(); + } else { + jm->pause(); + } + break; + } + } } void start_job (boost::filesystem::path path) @@ -211,7 +250,7 @@ public: } } - film->make_dcp (TranscodeJob::ChangedBehaviour::STOP); + make_dcp (film, TranscodeJob::ChangedBehaviour::STOP); } catch (std::exception& e) { auto p = std_to_wx (path.string ()); auto b = p.ToUTF8 (); @@ -232,16 +271,14 @@ private: return true; } - auto d = new wxMessageDialog ( - 0, + auto d = make_wx( + nullptr, _("There are unfinished jobs; are you sure you want to quit?"), _("Unfinished jobs"), wxYES_NO | wxYES_DEFAULT | wxICON_QUESTION ); - bool const r = d->ShowModal() == wxID_YES; - d->Destroy (); - return r; + return d->ShowModal() == wxID_YES; } void close (wxCloseEvent& ev) @@ -285,22 +322,21 @@ private: void help_about () { - auto d = new AboutDialog (this); + auto d = make_wx(this); d->ShowModal (); - d->Destroy (); } void add_film () { - auto c = new wxDirDialog (this, _("Select film to open"), wxStandardPaths::Get().GetDocumentsDir(), wxDEFAULT_DIALOG_STYLE | wxDD_DIR_MUST_EXIST); + auto dialog = make_wx(this, _("Select film to open"), wxStandardPaths::Get().GetDocumentsDir(), wxDEFAULT_DIALOG_STYLE | wxDD_DIR_MUST_EXIST); if (_last_parent) { - c->SetPath (std_to_wx(_last_parent.get().string())); + dialog->SetPath(std_to_wx(_last_parent.get().string())); } int r; while (true) { - r = c->ShowModal (); - if (r == wxID_OK && c->GetPath() == wxStandardPaths::Get().GetDocumentsDir()) { + r = dialog->ShowModal(); + if (r == wxID_OK && dialog->GetPath() == wxStandardPaths::Get().GetDocumentsDir()) { error_dialog (this, _("You did not select a folder. Make sure that you select a folder before clicking Open.")); } else { break; @@ -308,12 +344,10 @@ private: } if (r == wxID_OK) { - start_job (wx_to_std (c->GetPath ())); + start_job(wx_to_std(dialog->GetPath())); } - _last_parent = boost::filesystem::path (wx_to_std (c->GetPath ())).parent_path (); - - c->Destroy (); + _last_parent = boost::filesystem::path(wx_to_std(dialog->GetPath())).parent_path(); } void config_changed (Config::Property what) @@ -350,8 +384,6 @@ private: wxSizer* _sizer; wxPreferencesEditor* _config_dialog = nullptr; ServersListDialog* _servers_list_dialog = nullptr; - wxButton* _pause; - wxButton* _resume; }; @@ -361,30 +393,30 @@ static const wxCmdLineEntryDesc command_line_description[] = { }; -class JobServer : public Server +class JobServer : public Server, public Signaller { public: - explicit JobServer (DOMFrame* frame) + JobServer() : Server (BATCH_JOB_PORT) - , _frame (frame) {} void handle (shared_ptr socket) override { try { - int const length = socket->read_uint32 (); - scoped_array buffer(new char[length]); - socket->read (reinterpret_cast(buffer.get()), length); - string s (buffer.get()); - _frame->start_job (s); - socket->write (reinterpret_cast("OK"), 3); + auto const length = socket->read_uint32(); + if (length < 65536) { + scoped_array buffer(new char[length]); + socket->read(reinterpret_cast(buffer.get()), length); + string s(buffer.get()); + emit(boost::bind(boost::ref(StartJob), s)); + socket->write (reinterpret_cast("OK"), 3); + } } catch (...) { } } -private: - DOMFrame* _frame; + boost::signals2::signal StartJob; }; @@ -397,7 +429,7 @@ class App : public wxApp SetAppName (_("DCP-o-matic Batch Converter")); is_batch_converter = true; - 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)); auto splash = maybe_show_splash (); @@ -438,19 +470,24 @@ class App : public wxApp } _frame->Show (); - auto server = new JobServer (_frame); - new thread (boost::bind (&JobServer::run, server)); + try { + auto server = new JobServer(); + server->StartJob.connect(bind(&DOMFrame::start_job, _frame, _1)); + new thread (boost::bind (&JobServer::run, server)); + } catch (boost::system::system_error& e) { + error_dialog(_frame, _("Could not listen for new batch jobs. Perhaps another instance of the DCP-o-matic Batch Converter is running.")); + } signal_manager = new wxSignalManager (this); this->Bind (wxEVT_IDLE, boost::bind (&App::idle, this)); shared_ptr film; for (auto i: films_to_load) { - if (boost::filesystem::is_directory(i)) { + if (dcp::filesystem::is_directory(i)) { try { film = make_shared(i); film->read_metadata (); - film->make_dcp (TranscodeJob::ChangedBehaviour::EXAMINE_THEN_STOP); + make_dcp (film, TranscodeJob::ChangedBehaviour::EXAMINE_THEN_STOP); } catch (exception& e) { error_dialog ( 0, @@ -484,9 +521,9 @@ class App : public wxApp return true; } - 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)