Prevent un-prompted overwrite of files when exporting things from config (#1383).
[dcpomatic.git] / src / wx / wx_util.cc
index cb9f72a42b0e689e1edd83d045570587f73609c8..db63400315e899cb1488705dffa3dda15adad12d 100644 (file)
 #include "file_picker_ctrl.h"
 #include "lib/config.h"
 #include "lib/util.h"
-#include "lib/locale_convert.h"
+#include "lib/cross.h"
+#include <dcp/locale_convert.h>
 #include <wx/spinctrl.h>
+#include <wx/splash.h>
+#include <wx/filepicker.h>
 #include <boost/thread.hpp>
 
 using namespace std;
 using namespace boost;
+using dcp::locale_convert;
+
+wxStaticText *
+#ifdef __WXOSX__
+create_label (wxWindow* p, wxString t, bool left)
+#else
+create_label (wxWindow* p, wxString t, bool)
+#endif
+{
+#ifdef __WXOSX__
+       if (left) {
+               t += wxT (":");
+       }
+#endif
+       return new wxStaticText (p, wxID_ANY, t);
+}
 
 /** Add a wxStaticText to a wxSizer, aligning it at vertical centre.
  *  @param s Sizer to add to.
@@ -42,51 +61,79 @@ using namespace boost;
  *  @param prop Proportion to pass when calling Add() on the wxSizer.
  */
 wxStaticText *
+add_label_to_sizer (wxSizer* s, wxWindow* p, wxString t, bool left, int prop, int flags)
+{
 #ifdef __WXOSX__
-add_label_to_sizer (wxSizer* s, wxWindow* p, wxString t, bool left, int prop)
+       if (left) {
+               flags |= wxALIGN_RIGHT;
+       }
+#endif
+       wxStaticText* m = create_label (p, t, left);
+       s->Add (m, prop, flags, 6);
+       return m;
+}
+
+wxStaticText *
+#ifdef __WXOSX__
+add_label_to_sizer (wxSizer* s, wxStaticText* t, bool left, int prop, int flags)
 #else
-add_label_to_sizer (wxSizer* s, wxWindow* p, wxString t, bool, int prop)
+add_label_to_sizer (wxSizer* s, wxStaticText* t, bool, int prop, int flags)
 #endif
+{
+#ifdef __WXOSX__
+       if (left) {
+               flags |= wxALIGN_RIGHT;
+       }
+#endif
+       s->Add (t, prop, flags, 6);
+       return t;
+}
+
+wxStaticText *
+add_label_to_sizer (wxGridBagSizer* s, wxWindow* p, wxString t, bool left, wxGBPosition pos, wxGBSpan span)
 {
        int flags = wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT;
 #ifdef __WXOSX__
        if (left) {
                flags |= wxALIGN_RIGHT;
-               t += wxT (":");
        }
 #endif
-       wxStaticText* m = new wxStaticText (p, wxID_ANY, t);
-       s->Add (m, prop, flags, 6);
+       wxStaticText* m = create_label (p, t, left);
+       s->Add (m, pos, span, flags);
        return m;
 }
 
 wxStaticText *
 #ifdef __WXOSX__
-add_label_to_sizer (wxGridBagSizer* s, wxWindow* p, wxString t, bool left, wxGBPosition pos, wxGBSpan span)
+add_label_to_sizer (wxGridBagSizer* s, wxStaticText* t, bool left, wxGBPosition pos, wxGBSpan span)
 #else
-add_label_to_sizer (wxGridBagSizer* s, wxWindow* p, wxString t, bool, wxGBPosition pos, wxGBSpan span)
+add_label_to_sizer (wxGridBagSizer* s, wxStaticText* t, bool, wxGBPosition pos, wxGBSpan span)
 #endif
 {
        int flags = wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT;
 #ifdef __WXOSX__
        if (left) {
                flags |= wxALIGN_RIGHT;
-               t += wxT (":");
        }
 #endif
-       wxStaticText* m = new wxStaticText (p, wxID_ANY, t);
-       s->Add (m, pos, span, flags);
-       return m;
+       s->Add (t, pos, span, flags);
+       return t;
 }
 
 /** Pop up an error dialogue box.
  *  @param parent Parent.
  *  @param m Message.
+ *  @param e Extended message.
  */
 void
-error_dialog (wxWindow* parent, wxString m)
+error_dialog (wxWindow* parent, wxString m, optional<wxString> e)
 {
        wxMessageDialog* d = new wxMessageDialog (parent, m, _("DCP-o-matic"), wxOK | wxICON_ERROR);
+       if (e) {
+               wxString em = *e;
+               em[0] = wxToupper (em[0]);
+               d->SetExtendedMessage (em);
+       }
        d->ShowModal ();
        d->Destroy ();
 }
@@ -151,6 +198,20 @@ checked_set (FilePickerCtrl* widget, boost::filesystem::path value)
        }
 }
 
+void
+checked_set (wxDirPickerCtrl* widget, boost::filesystem::path value)
+{
+       if (widget->GetPath() != std_to_wx (value.string())) {
+               if (value.empty()) {
+                       /* Hack to make wxWidgets clear the control when we are passed
+                          an empty value.
+                       */
+                       value = " ";
+               }
+               widget->SetPath (std_to_wx (value.string()));
+       }
+}
+
 void
 checked_set (wxSpinCtrl* widget, int value)
 {
@@ -381,3 +442,57 @@ setup_audio_channels_choice (wxChoice* choice, int minimum)
 
        checked_set (choice, items);
 }
+
+wxSplashScreen *
+maybe_show_splash ()
+{
+       wxSplashScreen* splash = 0;
+       try {
+               if (!Config::have_existing ("config.xml")) {
+                       wxBitmap bitmap;
+                       boost::filesystem::path p = shared_path () / "splash.png";
+                       if (bitmap.LoadFile (std_to_wx (p.string ()), wxBITMAP_TYPE_PNG)) {
+                               splash = new wxSplashScreen (bitmap, wxSPLASH_CENTRE_ON_SCREEN | wxSPLASH_NO_TIMEOUT, 0, 0, -1);
+                               wxYield ();
+                       }
+               }
+       } catch (boost::filesystem::filesystem_error& e) {
+               /* Maybe we couldn't find the splash image; never mind */
+       }
+
+       return splash;
+}
+
+optional<boost::filesystem::path>
+path_from_file_dialog (wxFileDialog* dialog, string extension)
+{
+       boost::filesystem::path p(wx_to_std(dialog->GetPath()));
+       p.replace_extension(extension);
+       if (boost::filesystem::is_regular_file(p) && !confirm_dialog(dialog, wxString::Format(_("A file named %s already exists.  Do you want to replace it?"), std_to_wx(p.filename().string())))) {
+               return optional<boost::filesystem::path>();
+       }
+       return p;
+}
+
+double
+calculate_mark_interval (double mark_interval)
+{
+       if (mark_interval > 5) {
+               mark_interval -= lrint (mark_interval) % 5;
+       }
+       if (mark_interval > 10) {
+               mark_interval -= lrint (mark_interval) % 10;
+       }
+       if (mark_interval > 60) {
+               mark_interval -= lrint (mark_interval) % 60;
+       }
+       if (mark_interval > 3600) {
+               mark_interval -= lrint (mark_interval) % 3600;
+       }
+
+       if (mark_interval < 1) {
+               mark_interval = 1;
+       }
+
+       return mark_interval;
+}