std::shared_ptr
[dcpomatic.git] / src / tools / dcpomatic_disk.cc
index b2678ce42a788409480ad110f80f20085d704055..ac0bb68df47dce48dc5be26074fcedfafdd5d463 100644 (file)
 #include "lib/job_manager.h"
 #include "lib/disk_writer_messages.h"
 #include "lib/version.h"
+#include "lib/warnings.h"
 #include <wx/wx.h>
+DCPOMATIC_DISABLE_WARNINGS
 #include <boost/process.hpp>
+DCPOMATIC_ENABLE_WARNINGS
 #ifdef DCPOMATIC_WINDOWS
 #include <boost/process/windows.hpp>
 #endif
 #ifdef DCPOMATIC_OSX
-#include <ApplicationServices/ApplicationServices.h>
 #include <notify.h>
 #endif
 
@@ -49,8 +51,19 @@ using std::string;
 using std::exception;
 using std::cout;
 using std::cerr;
-using boost::shared_ptr;
+using std::shared_ptr;
 using boost::optional;
+#if BOOST_VERSION >= 106100
+using namespace boost::placeholders;
+#endif
+
+
+#ifdef DCPOMATIC_OSX
+enum {
+       ID_tools_uninstall = 1,
+};
+#endif
+
 
 class DOMFrame : public wxFrame
 {
@@ -60,6 +73,15 @@ public:
                , _nanomsg (true)
                , _sizer (new wxBoxSizer(wxVERTICAL))
        {
+#ifdef DCPOMATIC_OSX
+               wxMenuBar* bar = new wxMenuBar;
+               wxMenu* tools = new wxMenu;
+               tools->Append(ID_tools_uninstall, _("Uninstall..."));
+               bar->Append(tools, _("Tools"));
+               SetMenuBar (bar);
+               Bind (wxEVT_MENU, boost::bind(&DOMFrame::uninstall, this), ID_tools_uninstall);
+#endif
+
                /* Use a panel as the only child of the Frame so that we avoid
                   the dark-grey background on Windows.
                */
@@ -107,7 +129,7 @@ public:
                _sizer->Add (grid, 1, wxALL | wxEXPAND, DCPOMATIC_DIALOG_BORDER);
                overall_panel->SetSizer (_sizer);
                Fit ();
-               SetSize (768, GetSize().GetHeight() + 32);
+               SetSize (1024, GetSize().GetHeight() + 32);
 
                /* XXX: this is a hack, but I expect we'll need logs and I'm not sure if there's
                 * a better place to put them.
@@ -118,7 +140,8 @@ public:
 
                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));
 
@@ -129,8 +152,12 @@ public:
 #endif
 
 #ifdef DCPOMATIC_LINUX
-               LOG_DISK("Starting writer process %1", disk_writer_path().string());
-               _writer = new boost::process::child (disk_writer_path());
+               if (getenv("DCPOMATIC_NO_START_WRITER")) {
+                       LOG_DISK_NC("Not starting writer process as DCPOMATIC_NO_START_WRITER is set");
+               } else {
+                       LOG_DISK("Starting writer process %1", disk_writer_path().string());
+                       _writer = new boost::process::child (disk_writer_path());
+               }
 #endif
 
 #ifdef DCPOMATIC_OSX
@@ -151,6 +178,45 @@ private:
                ev.Skip ();
        }
 
+
+#ifdef DCPOMATIC_OSX
+       void uninstall()
+       {
+               system(String::compose("osascript \"%1/uninstall_disk.applescript\"", resources_path().string()).c_str());
+       }
+#endif
+
+
+       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);
@@ -172,6 +238,31 @@ private:
                DCPOMATIC_ASSERT (_drive->GetSelection() != wxNOT_FOUND);
                DCPOMATIC_ASSERT (static_cast<bool>(_dcp_path));
 
+               bool have_writer = true;
+               if (!_nanomsg.send(DISK_WRITER_PING "\n", 2000)) {
+                       have_writer = false;
+               } else {
+                       optional<string> reply = _nanomsg.receive (2000);
+                       if (!reply || *reply != DISK_WRITER_PONG) {
+                               have_writer = false;
+                       }
+               }
+
+               if (!have_writer) {
+#ifdef DCPOMATIC_WINDOWS
+                       MessageDialog* 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.")
+                               );
+                       m->ShowModal ();
+                       m->Destroy ();
+                       return;
+#else
+                       throw CommunicationFailedError ();
+#endif
+               }
+
                Drive const& drive = _drives[_drive->GetSelection()];
                if (drive.mounted()) {
                        TryUnmountDialog* d = new TryUnmountDialog(this, drive.description());
@@ -281,10 +372,9 @@ public:
                        unsetenv ("UBUNTU_MENUPROXY");
 #endif
 
-#ifdef __WXOSX__
-                       ProcessSerialNumber serial;
-                       GetCurrentProcess (&serial);
-                       TransformProcessType (&serial, kProcessTransformToForegroundApplication);
+#ifdef DCPOMATIC_OSX
+                       dcpomatic_sleep_seconds (1);
+                       make_foreground_application ();
 #endif
 
                        dcpomatic_setup_path_encoding ();
@@ -312,6 +402,7 @@ public:
                        if (!warning->confirmed()) {
                                return false;
                        }
+                       warning->Destroy ();
 
                        _frame = new DOMFrame (_("DCP-o-matic Disk Writer"));
                        SetTopWindow (_frame);