#include "wx/wx_util.h"
#include "wx/job_manager_view.h"
#include "wx/drive_wipe_warning_dialog.h"
+#include "wx/try_unmount_dialog.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 "lib/copy_to_drive_job.h"
#include "lib/job_manager.h"
#include "lib/disk_writer_messages.h"
+#include "lib/version.h"
#include <wx/wx.h>
#include <boost/process.hpp>
#ifdef DCPOMATIC_WINDOWS
#endif
#ifdef DCPOMATIC_OSX
#include <ApplicationServices/ApplicationServices.h>
+#include <notify.h>
#endif
using std::string;
using std::exception;
using std::cout;
using std::cerr;
-using std::runtime_error;
using boost::shared_ptr;
+using boost::optional;
class DOMFrame : public wxFrame
{
*/
dcpomatic_log.reset(new FileLog(config_path() / "disk.log"));
dcpomatic_log->set_types (dcpomatic_log->types() | LogEntry::TYPE_DISK);
- LOG_DISK_NC("dcpomatic_disk started");
+ LOG_DISK("dcpomatic_disk %1 started", dcpomatic_git_commit);
drive_refresh ();
- Bind (wxEVT_SIZE, boost::bind (&DOMFrame::sized, this, _1));
+ Bind (wxEVT_SIZE, boost::bind(&DOMFrame::sized, this, _1));
+ Bind (wxEVT_CLOSE_WINDOW, boost::bind(&DOMFrame::close, this, _1));
JobManager::instance()->ActiveJobsChanged.connect(boost::bind(&DOMFrame::setup_sensitivity, this));
_writer = new boost::process::child (disk_writer_path());
#endif
- /* _writer is always running on macOS at the moment */
+#ifdef DCPOMATIC_OSX
+ LOG_DISK_NC("Sending notification to writer daemon");
+ notify_post ("com.dcpomatic.disk.writer.start");
+#endif
}
~DOMFrame ()
{
- _nanomsg.blocking_send(DISK_WRITER_QUIT "\n");
+ _nanomsg.send(DISK_WRITER_QUIT "\n", 2000);
}
private:
ev.Skip ();
}
+
+ bool should_close ()
+ {
+ if (!JobManager::instance()->work_to_do()) {
+ return true;
+ }
+
+ wxMessageDialog* d = new wxMessageDialog (
+ 0,
+ _("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;
+ }
+
+
+ void close (wxCloseEvent& ev)
+ {
+ if (!should_close()) {
+ ev.Veto ();
+ return;
+ }
+
+ ev.Skip ();
+ }
+
+
void open ()
{
wxDirDialog* d = new wxDirDialog (this, _("Choose a DCP folder"), wxT(""), wxDD_DIR_MUST_EXIST);
{
DCPOMATIC_ASSERT (_drive->GetSelection() != wxNOT_FOUND);
DCPOMATIC_ASSERT (static_cast<bool>(_dcp_path));
+
+ Drive const& drive = _drives[_drive->GetSelection()];
+ if (drive.mounted()) {
+ TryUnmountDialog* d = new TryUnmountDialog(this, drive.description());
+ int const r = d->ShowModal ();
+ d->Destroy ();
+ if (r != wxID_OK) {
+ return;
+ }
+
+ LOG_DISK("Sending unmount request to disk writer for %1", drive.as_xml());
+ if (!_nanomsg.send(DISK_WRITER_UNMOUNT "\n", 2000)) {
+ throw CommunicationFailedError ();
+ }
+ if (!_nanomsg.send(drive.as_xml(), 2000)) {
+ throw CommunicationFailedError ();
+ }
+ optional<string> reply = _nanomsg.receive (2000);
+ if (!reply || *reply != DISK_WRITER_OK) {
+ MessageDialog* 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()))
+ );
+ m->ShowModal ();
+ m->Destroy ();
+ return;
+ }
+ }
+
+
DriveWipeWarningDialog* d = new DriveWipeWarningDialog (this, _drive->GetString(_drive->GetSelection()));
int const r = d->ShowModal ();
bool ok = r == wxID_OK && d->confirmed();
_drive->Clear ();
int re_select = wxNOT_FOUND;
int j = 0;
- _drives.clear ();
- BOOST_FOREACH (Drive i, get_drives()) {
- if (!i.mounted()) {
- _drives.push_back (i);
- }
- }
+ _drives = Drive::get ();
BOOST_FOREACH (Drive i, _drives) {
wxString const s = std_to_wx(i.description());
if (s == current) {
JobManagerView* _jobs;
boost::optional<boost::filesystem::path> _dcp_path;
std::vector<Drive> _drives;
+#ifndef DCPOMATIC_OSX
boost::process::child* _writer;
+#endif
Nanomsg _nanomsg;
wxSizer* _sizer;
};
*/
Config::drop ();
+ DiskWarningDialog* warning = new DiskWarningDialog ();
+ warning->ShowModal ();
+ if (!warning->confirmed()) {
+ return false;
+ }
+ warning->Destroy ();
+
_frame = new DOMFrame (_("DCP-o-matic Disk Writer"));
SetTopWindow (_frame);
catch (exception& e)
{
error_dialog (0, wxString::Format ("DCP-o-matic could not start."), std_to_wx(e.what()));
+ return false;
}
return true;
ev.Skip ();
}
+ void report_exception ()
+ {
+ try {
+ throw;
+ } catch (FileError& e) {
+ error_dialog (
+ 0,
+ wxString::Format (
+ _("An exception occurred: %s (%s)\n\n") + REPORT_PROBLEM,
+ std_to_wx (e.what()),
+ std_to_wx (e.file().string().c_str ())
+ )
+ );
+ } catch (exception& e) {
+ error_dialog (
+ 0,
+ wxString::Format (
+ _("An exception occurred: %s.\n\n") + REPORT_PROBLEM,
+ std_to_wx (e.what ())
+ )
+ );
+ } catch (...) {
+ error_dialog (0, _("An unknown exception occurred.") + " " + REPORT_PROBLEM);
+ }
+ }
+
+ bool OnExceptionInMainLoop ()
+ {
+ report_exception ();
+ /* This will terminate the program */
+ return false;
+ }
+
+ void OnUnhandledException ()
+ {
+ report_exception ();
+ }
+
DOMFrame* _frame;
};