X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Fwx%2Fwx_util.cc;h=40e72543a7e374495057f8872c792b68f1ed71e8;hb=e5ccfb7ec74aa8a25371a85c0a013a285884e41f;hp=b9e78932ae88b7664bf360b12ea3d859f5119ca1;hpb=820e2b300b09c586e987a9761b102e2b51374cfd;p=dcpomatic.git diff --git a/src/wx/wx_util.cc b/src/wx/wx_util.cc index b9e78932a..40e72543a 100644 --- a/src/wx/wx_util.cc +++ b/src/wx/wx_util.cc @@ -1,19 +1,20 @@ /* - Copyright (C) 2012 Carl Hetherington + Copyright (C) 2012-2015 Carl Hetherington - This program is free software; you can redistribute it and/or modify + This file is part of DCP-o-matic. + + DCP-o-matic is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + DCP-o-matic is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with DCP-o-matic. If not, see . */ @@ -21,12 +22,12 @@ * @brief Some utility functions and classes. */ -#include -#include -#include #include "wx_util.h" -#include "config.h" -#include "util.h" +#include "file_picker_ctrl.h" +#include "lib/config.h" +#include "lib/util.h" +#include +#include using namespace std; using namespace boost; @@ -40,7 +41,11 @@ using namespace boost; * @param prop Proportion to pass when calling Add() on the wxSizer. */ wxStaticText * +#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__ @@ -48,14 +53,18 @@ add_label_to_sizer (wxSizer* s, wxWindow* p, wxString t, bool left, int prop) flags |= wxALIGN_RIGHT; t += wxT (":"); } -#endif +#endif wxStaticText* m = new wxStaticText (p, wxID_ANY, t); s->Add (m, prop, flags, 6); return m; } wxStaticText * -add_label_to_grid_bag_sizer (wxGridBagSizer* s, wxWindow* p, wxString t, bool left, wxGBPosition pos, wxGBSpan span) +#ifdef __WXOSX__ +add_label_to_sizer (wxGridBagSizer* s, wxWindow* p, wxString t, bool left, wxGBPosition pos, wxGBSpan span) +#else +add_label_to_sizer (wxGridBagSizer* s, wxWindow* p, wxString t, bool, wxGBPosition pos, wxGBSpan span) +#endif { int flags = wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT; #ifdef __WXOSX__ @@ -63,7 +72,7 @@ add_label_to_grid_bag_sizer (wxGridBagSizer* s, wxWindow* p, wxString t, bool le flags |= wxALIGN_RIGHT; t += wxT (":"); } -#endif +#endif wxStaticText* m = new wxStaticText (p, wxID_ANY, t); s->Add (m, pos, span, flags); return m; @@ -76,7 +85,19 @@ add_label_to_grid_bag_sizer (wxGridBagSizer* s, wxWindow* p, wxString t, bool le 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 | wxICON_ERROR); + d->ShowModal (); + d->Destroy (); +} + +/** Pop up an error dialogue box. + * @param parent Parent. + * @param m Message. + */ +void +message_dialog (wxWindow* parent, wxString m) +{ + wxMessageDialog* d = new wxMessageDialog (parent, m, _("DCP-o-matic"), wxOK | wxICON_INFORMATION); d->ShowModal (); d->Destroy (); } @@ -84,12 +105,12 @@ 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; } - + /** @param s wxWidgets string. * @return Corresponding STL string. @@ -97,7 +118,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. @@ -109,42 +130,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 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 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) { @@ -152,16 +137,16 @@ string_client_data (wxClientData* o) } void -checked_set (wxFilePickerCtrl* widget, string value) +checked_set (FilePickerCtrl* widget, boost::filesystem::path value) { - if (widget->GetPath() != std_to_wx (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)); + widget->SetPath (std_to_wx (value.string())); } } @@ -173,6 +158,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) { @@ -188,7 +182,7 @@ checked_set (wxChoice* widget, string value) if (widget->GetSelection() != -1) { o = widget->GetClientObject (widget->GetSelection ()); } - + if (!o || string_client_data(o) != value) { for (unsigned int i = 0; i < widget->GetCount(); ++i) { if (string_client_data (widget->GetClientObject (i)) == value) { @@ -198,6 +192,29 @@ checked_set (wxChoice* widget, string value) } } +void +checked_set (wxChoice* widget, vector > items) +{ + vector > 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 >::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) { @@ -206,6 +223,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) { @@ -214,6 +239,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) { @@ -231,7 +264,7 @@ checked_set (wxRadioButton* widget, bool value) } void -dvdomatic_setup_i18n () +dcpomatic_setup_i18n () { int language = wxLANGUAGE_DEFAULT; @@ -247,21 +280,80 @@ 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 +#endif + +#ifdef DCPOMATIC_LINUX + locale->AddCatalogLookupPathPrefix (LINUX_LOCALE_PREFIX); + + /* 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 ("dcpomatic2-wxstd")); +#endif + + locale->AddCatalog (wxT ("libdcpomatic2-wx")); + locale->AddCatalog (wxT ("dcpomatic2")); - locale->AddCatalog (wxT ("libdvdomatic-wx")); - locale->AddCatalog (wxT ("dvdomatic")); - 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; +} + +wxString +time_to_timecode (DCPTime t, double fps) +{ + double w = t.seconds (); + int const h = (w / 3600); + w -= h * 3600; + int const m = (w / 60); + w -= m * 60; + int const s = floor (w); + w -= s; + int const f = lrint (w * fps); + return wxString::Format (wxT("%02d:%02d:%02d.%02d"), h, m, s, f); }