Various bits related to subtitle font handling, particularly copying fonts to the...
[dcpomatic.git] / src / wx / wx_util.cc
index 1a7b73faffe42e54cd064ed58d3776fcc7f734a3..ea8255f8169a9ae7fbddf01c5e771ed1dbc7bac1 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2012 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -24,9 +24,9 @@
 #include <boost/thread.hpp>
 #include <wx/filepicker.h>
 #include <wx/spinctrl.h>
+#include "lib/config.h"
+#include "lib/util.h"
 #include "wx_util.h"
-#include "config.h"
-#include "util.h"
 
 using namespace std;
 using namespace boost;
@@ -35,21 +35,45 @@ using namespace boost;
  *  @param s Sizer to add to.
  *  @param p Parent window for the wxStaticText.
  *  @param t Text for the wxStaticText.
+ *  @param left true if this label is a `left label'; ie the sort
+ *  of label which should be right-aligned on OS X.
  *  @param prop Proportion to pass when calling Add() on the wxSizer.
  */
 wxStaticText *
-add_label_to_sizer (wxSizer* s, wxWindow* p, wxString t, int prop)
+#ifdef __WXOSX__
+add_label_to_sizer (wxSizer* s, wxWindow* p, wxString t, bool left, int prop)
+#else
+add_label_to_sizer (wxSizer* s, wxWindow* p, wxString t, bool, int prop)
+#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, prop, wxALIGN_CENTER_VERTICAL | wxALL, 6);
+       s->Add (m, prop, flags, 6);
        return m;
 }
 
 wxStaticText *
-add_label_to_grid_bag_sizer (wxGridBagSizer* s, wxWindow* p, wxString t, wxGBPosition pos, wxGBSpan span)
+#ifdef __WXOSX__
+add_label_to_grid_bag_sizer (wxGridBagSizer* s, wxWindow* p, wxString t, bool left, wxGBPosition pos, wxGBSpan span)
+#else
+add_label_to_grid_bag_sizer (wxGridBagSizer* s, wxWindow* p, wxString 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, wxALIGN_CENTER_VERTICAL | wxALL, 6);
+       s->Add (m, pos, span, flags);
        return m;
 }
 
@@ -60,7 +84,7 @@ add_label_to_grid_bag_sizer (wxGridBagSizer* s, wxWindow* p, wxString t, wxGBPos
 void
 error_dialog (wxWindow* parent, wxString m)
 {
-       wxMessageDialog* d = new wxMessageDialog (parent, m, _("DVD-o-matic"), wxOK);
+       wxMessageDialog* d = new wxMessageDialog (parent, m, _("DCP-o-matic"), wxOK);
        d->ShowModal ();
        d->Destroy ();
 }
@@ -68,7 +92,7 @@ error_dialog (wxWindow* parent, wxString m)
 bool
 confirm_dialog (wxWindow* parent, wxString m)
 {
-       wxMessageDialog* d = new wxMessageDialog (parent, m, _("DVD-o-matic"), wxYES_NO | wxICON_QUESTION);
+       wxMessageDialog* d = new wxMessageDialog (parent, m, _("DCP-o-matic"), wxYES_NO | wxICON_QUESTION);
        int const r = d->ShowModal ();
        d->Destroy ();
        return r == wxID_YES;
@@ -81,7 +105,7 @@ confirm_dialog (wxWindow* parent, wxString m)
 string
 wx_to_std (wxString s)
 {
-       return string (s.mb_str ());
+       return string (s.ToUTF8 ());
 }
 
 /** @param s STL string.
@@ -93,42 +117,6 @@ std_to_wx (string s)
        return wxString (s.c_str(), wxConvUTF8);
 }
 
-int const ThreadedStaticText::_update_event_id = 10000;
-
-/** @param parent Parent for the wxStaticText.
- *  @param initial Initial text for the wxStaticText while the computation is being run.
- *  @param fn Function which works out what the wxStaticText content should be and returns it.
- */
-ThreadedStaticText::ThreadedStaticText (wxWindow* parent, wxString initial, function<string ()> fn)
-       : wxStaticText (parent, wxID_ANY, initial)
-{
-       Connect (_update_event_id, wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler (ThreadedStaticText::thread_finished), 0, this);
-       _thread = new thread (bind (&ThreadedStaticText::run, this, fn));
-}
-
-ThreadedStaticText::~ThreadedStaticText ()
-{
-       _thread->interrupt ();
-       _thread->join ();
-       delete _thread;
-}
-
-/** Run our thread and post the result to the GUI thread via AddPendingEvent */
-void
-ThreadedStaticText::run (function<string ()> fn)
-{
-       wxCommandEvent ev (wxEVT_COMMAND_TEXT_UPDATED, _update_event_id);
-       ev.SetString (std_to_wx (fn ()));
-       GetEventHandler()->AddPendingEvent (ev);
-}
-
-/** Called in the GUI thread when our worker thread has finished */
-void
-ThreadedStaticText::thread_finished (wxCommandEvent& ev)
-{
-       SetLabel (ev.GetString ());
-}
-
 string
 string_client_data (wxClientData* o)
 {
@@ -157,6 +145,15 @@ checked_set (wxSpinCtrl* widget, int value)
        }
 }
 
+void
+checked_set (wxSpinCtrlDouble* widget, double value)
+{
+       /* XXX: completely arbitrary epsilon */
+       if (fabs (widget->GetValue() - value) > 1e-16) {
+               widget->SetValue (value);
+       }
+}
+
 void
 checked_set (wxChoice* widget, int value)
 {
@@ -182,6 +179,29 @@ checked_set (wxChoice* widget, string value)
        }
 }
 
+void
+checked_set (wxChoice* widget, vector<pair<string, string> > items)
+{
+       vector<pair<string, string> > current;
+       for (unsigned int i = 0; i < widget->GetCount(); ++i) {
+               current.push_back (
+                       make_pair (
+                               wx_to_std (widget->GetString (i)),
+                               string_client_data (widget->GetClientObject (i))
+                               )
+                       );
+       }
+
+       if (current == items) {
+               return;
+       }
+
+       widget->Clear ();
+       for (vector<pair<string, string> >::const_iterator i = items.begin(); i != items.end(); ++i) {
+               widget->Append (std_to_wx (i->first), new wxStringClientData (std_to_wx (i->second)));
+       }
+}
+
 void
 checked_set (wxTextCtrl* widget, string value)
 {
@@ -190,6 +210,14 @@ checked_set (wxTextCtrl* widget, string value)
        }
 }
 
+void
+checked_set (wxTextCtrl* widget, wxString value)
+{
+       if (widget->GetValue() != value) {
+               widget->ChangeValue (value);
+       }
+}
+
 void
 checked_set (wxStaticText* widget, string value)
 {
@@ -198,6 +226,14 @@ checked_set (wxStaticText* widget, string value)
        }
 }
 
+void
+checked_set (wxStaticText* widget, wxString value)
+{
+       if (widget->GetLabel() != value) {
+               widget->SetLabel (value);
+       }
+}
+
 void
 checked_set (wxCheckBox* widget, bool value)
 {
@@ -215,7 +251,7 @@ checked_set (wxRadioButton* widget, bool value)
 }
 
 void
-dvdomatic_setup_i18n ()
+dcpomatic_setup_i18n ()
 {
        int language = wxLANGUAGE_DEFAULT;
 
@@ -231,21 +267,68 @@ dvdomatic_setup_i18n ()
        if (wxLocale::IsAvailable (language)) {
                locale = new wxLocale (language, wxLOCALE_LOAD_DEFAULT);
 
-#ifdef DVDOMATIC_WINDOWS
+#ifdef DCPOMATIC_WINDOWS
                locale->AddCatalogLookupPathPrefix (std_to_wx (mo_path().string()));
 #endif         
 
-               locale->AddCatalog (wxT ("libdvdomatic-wx"));
-               locale->AddCatalog (wxT ("dvdomatic"));
+#ifdef DCPOMATIC_POSIX
+               locale->AddCatalogLookupPathPrefix (LINUX_LOCALE_PREFIX);
+#endif
+
+#ifdef DCPOMATIC_LINUX
+               /* We have to include the wxWidgets .mo in our distribution,
+                  so we rename it to avoid clashes with any other installation
+                  of wxWidgets.
+               */
+               locale->AddCatalog (wxT ("dcpomatic-wxstd"));
+#endif         
+               
+               locale->AddCatalog (wxT ("libdcpomatic-wx"));
+               locale->AddCatalog (wxT ("dcpomatic"));
                
                if (!locale->IsOk()) {
                        delete locale;
                        locale = new wxLocale (wxLANGUAGE_ENGLISH);
-                       language = wxLANGUAGE_ENGLISH;
                }
        }
 
        if (locale) {
-               dvdomatic_setup_gettext_i18n (wx_to_std (locale->GetCanonicalName ()));
+               dcpomatic_setup_gettext_i18n (wx_to_std (locale->GetCanonicalName ()));
        }
 }
+
+int
+wx_get (wxSpinCtrl* w)
+{
+       return w->GetValue ();
+}
+
+int
+wx_get (wxChoice* w)
+{
+       return w->GetSelection ();
+}
+
+double
+wx_get (wxSpinCtrlDouble* w)
+{
+       return w->GetValue ();
+}
+
+/** @param s String of the form Context|String
+ *  @return translation, or String if no translation is available.
+ */
+wxString
+context_translation (wxString s)
+{
+       wxString t = wxGetTranslation (s);
+       if (t == s) {
+               /* No translation; strip the context */
+               int c = t.Find (wxT ("|"));
+               if (c != wxNOT_FOUND) {
+                       t = t.Mid (c + 1);
+               }
+       }
+
+       return t;
+}