X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Ftools%2Fdcpomatic_disk.cc;h=3daffb72d0b94d7d8b0c1b340f4d1359bcaa2c3f;hb=472959c1357f43e2eb33366c58bed0466474c2b7;hp=ac0bb68df47dce48dc5be26074fcedfafdd5d463;hpb=dd9be86db6cde0afa5da0d1d1ac43b42e05dca26;p=dcpomatic.git diff --git a/src/tools/dcpomatic_disk.cc b/src/tools/dcpomatic_disk.cc index ac0bb68df..3daffb72d 100644 --- a/src/tools/dcpomatic_disk.cc +++ b/src/tools/dcpomatic_disk.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2019-2020 Carl Hetherington + Copyright (C) 2019-2021 Carl Hetherington This file is part of DCP-o-matic. @@ -18,22 +18,24 @@ */ -#include "wx/wx_signal_manager.h" -#include "wx/wx_util.h" -#include "wx/job_manager_view.h" + +#include "wx/disk_warning_dialog.h" #include "wx/drive_wipe_warning_dialog.h" -#include "wx/try_unmount_dialog.h" +#include "wx/job_manager_view.h" #include "wx/message_dialog.h" -#include "wx/disk_warning_dialog.h" -#include "lib/file_log.h" -#include "lib/dcpomatic_log.h" -#include "lib/util.h" +#include "wx/try_unmount_dialog.h" +#include "wx/wx_util.h" +#include "wx/wx_signal_manager.h" +#include "wx/wx_util.h" #include "lib/config.h" -#include "lib/signal_manager.h" -#include "lib/cross.h" #include "lib/copy_to_drive_job.h" -#include "lib/job_manager.h" +#include "lib/cross.h" +#include "lib/dcpomatic_log.h" #include "lib/disk_writer_messages.h" +#include "lib/file_log.h" +#include "lib/job_manager.h" +#include "lib/signal_manager.h" +#include "lib/util.h" #include "lib/version.h" #include "lib/warnings.h" #include @@ -47,11 +49,13 @@ DCPOMATIC_ENABLE_WARNINGS #include #endif -using std::string; -using std::exception; -using std::cout; + using std::cerr; +using std::cout; +using std::exception; +using std::make_shared; using std::shared_ptr; +using std::string; using boost::optional; #if BOOST_VERSION >= 106100 using namespace boost::placeholders; @@ -69,13 +73,13 @@ class DOMFrame : public wxFrame { public: explicit DOMFrame (wxString const & title) - : wxFrame (0, -1, title) + : wxFrame (nullptr, wxID_ANY, title) , _nanomsg (true) , _sizer (new wxBoxSizer(wxVERTICAL)) { #ifdef DCPOMATIC_OSX - wxMenuBar* bar = new wxMenuBar; - wxMenu* tools = new wxMenu; + auto bar = new wxMenuBar; + auto tools = new wxMenu; tools->Append(ID_tools_uninstall, _("Uninstall...")); bar->Append(tools, _("Tools")); SetMenuBar (bar); @@ -85,16 +89,16 @@ public: /* Use a panel as the only child of the Frame so that we avoid the dark-grey background on Windows. */ - wxPanel* overall_panel = new wxPanel (this); - wxSizer* s = new wxBoxSizer (wxHORIZONTAL); + auto overall_panel = new wxPanel (this); + auto s = new wxBoxSizer (wxHORIZONTAL); s->Add (overall_panel, 1, wxEXPAND); SetSizer (s); - wxGridBagSizer* grid = new wxGridBagSizer (DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP); + auto grid = new wxGridBagSizer (DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP); int r = 0; add_label_to_sizer (grid, overall_panel, _("DCP"), true, wxGBPosition(r, 0)); - wxBoxSizer* dcp_name_sizer = new wxBoxSizer (wxHORIZONTAL); + auto dcp_name_sizer = new wxBoxSizer (wxHORIZONTAL); _dcp_name = new wxStaticText (overall_panel, wxID_ANY, wxEmptyString); dcp_name_sizer->Add (_dcp_name, 1, wxALIGN_CENTER_VERTICAL | wxRIGHT, DCPOMATIC_SIZER_X_GAP); _dcp_open = new wxButton (overall_panel, wxID_ANY, _("Open...")); @@ -103,7 +107,7 @@ public: ++r; add_label_to_sizer (grid, overall_panel, _("Drive"), true, wxGBPosition(r, 0)); - wxBoxSizer* drive_sizer = new wxBoxSizer (wxHORIZONTAL); + auto drive_sizer = new wxBoxSizer (wxHORIZONTAL); _drive = new wxChoice (overall_panel, wxID_ANY); drive_sizer->Add (_drive, 1, wxALIGN_CENTER_VERTICAL | wxRIGHT, DCPOMATIC_SIZER_X_GAP); _drive_refresh = new wxButton (overall_panel, wxID_ANY, _("Refresh")); @@ -193,7 +197,7 @@ private: return true; } - wxMessageDialog* d = new wxMessageDialog ( + auto d = new wxMessageDialog ( 0, _("There are unfinished jobs; are you sure you want to quit?"), _("Unfinished jobs"), @@ -219,7 +223,7 @@ private: void open () { - wxDirDialog* d = new wxDirDialog (this, _("Choose a DCP folder"), wxT(""), wxDD_DIR_MUST_EXIST); + auto d = new wxDirDialog (this, _("Choose a DCP folder"), wxT(""), wxDD_DIR_MUST_EXIST); int r = d->ShowModal (); boost::filesystem::path const path (wx_to_std(d->GetPath())); d->Destroy (); @@ -235,22 +239,43 @@ private: void copy () { + /* Check that the selected drive still exists and update its properties if so */ + drive_refresh (); + if (_drive->GetSelection() == wxNOT_FOUND) { + error_dialog (this, _("The disk you selected is no longer available. Please choose another.")); + return; + } + DCPOMATIC_ASSERT (_drive->GetSelection() != wxNOT_FOUND); DCPOMATIC_ASSERT (static_cast(_dcp_path)); - bool have_writer = true; - if (!_nanomsg.send(DISK_WRITER_PING "\n", 2000)) { - have_writer = false; - } else { - optional reply = _nanomsg.receive (2000); - if (!reply || *reply != DISK_WRITER_PONG) { - have_writer = false; + auto ping = [this](int attempt) { + if (_nanomsg.send(DISK_WRITER_PING "\n", 2000)) { + auto reply = _nanomsg.receive (2000); + if (reply && *reply == DISK_WRITER_PONG) { + return true; + } else if (reply) { + LOG_DISK("Unexpected response %1 to ping received (attempt %2)", *reply, attempt); + } else { + LOG_DISK("No reply received from ping (attempt %1)", attempt); + } + } else { + LOG_DISK("Could not send ping to writer (attempt %1)", attempt); + } + return false; + }; + + bool have_writer = false; + for (int i = 0; i < 8; ++i) { + if (ping(i + 1)) { + have_writer = true; + break; } } if (!have_writer) { #ifdef DCPOMATIC_WINDOWS - MessageDialog* m = new MessageDialog ( + auto m = new MessageDialog ( this, _("DCP-o-matic Disk Writer"), _("Do you see a 'User Account Control' dialogue asking about dcpomatic2_disk_writer.exe? If so, click 'Yes', then try again.") @@ -259,13 +284,14 @@ private: m->Destroy (); return; #else + LOG_DISK_NC ("Failed to ping writer"); throw CommunicationFailedError (); #endif } - Drive const& drive = _drives[_drive->GetSelection()]; + auto const& drive = _drives[_drive->GetSelection()]; if (drive.mounted()) { - TryUnmountDialog* d = new TryUnmountDialog(this, drive.description()); + auto d = new TryUnmountDialog(this, drive.description()); int const r = d->ShowModal (); d->Destroy (); if (r != wxID_OK) { @@ -274,14 +300,17 @@ private: LOG_DISK("Sending unmount request to disk writer for %1", drive.as_xml()); if (!_nanomsg.send(DISK_WRITER_UNMOUNT "\n", 2000)) { + LOG_DISK_NC("Failed to send unmount request."); throw CommunicationFailedError (); } if (!_nanomsg.send(drive.as_xml(), 2000)) { + LOG_DISK_NC("Failed to send drive for unmount request."); throw CommunicationFailedError (); } - optional reply = _nanomsg.receive (2000); + /* The reply may have to wait for the user to authenticate, so let's wait a while */ + auto reply = _nanomsg.receive (30000); if (!reply || *reply != DISK_WRITER_OK) { - MessageDialog* m = new MessageDialog ( + auto * m = new MessageDialog ( this, _("DCP-o-matic Disk Writer"), wxString::Format(_("The drive %s could not be unmounted.\nClose any application that is using it, then try again."), std_to_wx(drive.description())) @@ -293,7 +322,7 @@ private: } - DriveWipeWarningDialog* d = new DriveWipeWarningDialog (this, _drive->GetString(_drive->GetSelection())); + auto * d = new DriveWipeWarningDialog (this, _drive->GetString(_drive->GetSelection())); int const r = d->ShowModal (); bool ok = r == wxID_OK && d->confirmed(); d->Destroy (); @@ -302,7 +331,7 @@ private: return; } - JobManager::instance()->add(shared_ptr(new CopyToDriveJob(*_dcp_path, _drives[_drive->GetSelection()], _nanomsg))); + JobManager::instance()->add(make_shared(*_dcp_path, _drives[_drive->GetSelection()], _nanomsg)); setup_sensitivity (); } @@ -317,8 +346,8 @@ private: int re_select = wxNOT_FOUND; int j = 0; _drives = Drive::get (); - BOOST_FOREACH (Drive i, _drives) { - wxString const s = std_to_wx(i.description()); + for (auto i: _drives) { + auto const s = std_to_wx(i.description()); if (s == current) { re_select = j; } @@ -349,6 +378,7 @@ private: wxSizer* _sizer; }; + class App : public wxApp { public: @@ -397,7 +427,7 @@ public: */ Config::drop (); - DiskWarningDialog* warning = new DiskWarningDialog (); + auto warning = new DiskWarningDialog (); warning->ShowModal (); if (!warning->confirmed()) { return false;