X-Git-Url: https://main.carlh.net/gitweb/?p=dcpomatic.git;a=blobdiff_plain;f=src%2Fwx%2Fwx_util.cc;h=8b6d0961ba74a0f91b3e59d11c3b309a9ade9bc5;hp=cb9f72a42b0e689e1edd83d045570587f73609c8;hb=d31674ec14bb533fe2b195601e9ee2fe03848487;hpb=94056bf7f8fdef32da3cd78eff68d58560b4e6be diff --git a/src/wx/wx_util.cc b/src/wx/wx_util.cc index cb9f72a42..8b6d0961b 100644 --- a/src/wx/wx_util.cc +++ b/src/wx/wx_util.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2016 Carl Hetherington + Copyright (C) 2012-2020 Carl Hetherington This file is part of DCP-o-matic. @@ -24,14 +24,45 @@ #include "wx_util.h" #include "file_picker_ctrl.h" +#include "static_text.h" +#include "password_entry.h" #include "lib/config.h" +#include "lib/job_manager.h" #include "lib/util.h" -#include "lib/locale_convert.h" +#include "lib/cross.h" +#include "lib/job.h" +#include "lib/warnings.h" +#include +DCPOMATIC_DISABLE_WARNINGS #include +#include +#include +#include +DCPOMATIC_ENABLE_WARNINGS #include -using namespace std; -using namespace boost; +using std::string; +using std::vector; +using std::pair; +using std::shared_ptr; +using boost::optional; +using dcp::locale_convert; +using namespace dcpomatic; + +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 StaticText (p, t); +} /** Add a wxStaticText to a wxSizer, aligning it at vertical centre. * @param s Sizer to add to. @@ -41,52 +72,80 @@ using namespace boost; * 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, bool left, int prop, int flags) +{ +#ifdef __WXOSX__ + if (left) { + flags |= wxALIGN_RIGHT; + } +#endif + auto m = create_label (p, t, left); + s->Add (m, prop, flags, 6); + return m; +} + wxStaticText * #ifdef __WXOSX__ -add_label_to_sizer (wxSizer* s, wxWindow* p, wxString t, bool left, int prop) +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); + auto 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 e) { - wxMessageDialog* d = new wxMessageDialog (parent, m, _("DCP-o-matic"), wxOK | wxICON_ERROR); + auto 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 (); } @@ -98,11 +157,12 @@ error_dialog (wxWindow* parent, wxString m) void message_dialog (wxWindow* parent, wxString m) { - wxMessageDialog* d = new wxMessageDialog (parent, m, _("DCP-o-matic"), wxOK | wxICON_INFORMATION); + auto d = new wxMessageDialog (parent, m, _("DCP-o-matic"), wxOK | wxICON_INFORMATION); d->ShowModal (); d->Destroy (); } +/** @return true if the user answered "yes" */ bool confirm_dialog (wxWindow* parent, wxString m) { @@ -151,6 +211,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) { @@ -179,7 +253,7 @@ checked_set (wxChoice* widget, int value) void checked_set (wxChoice* widget, string value) { - wxClientData* o = 0; + wxClientData* o = nullptr; if (widget->GetSelection() != -1) { o = widget->GetClientObject (widget->GetSelection ()); } @@ -211,8 +285,8 @@ checked_set (wxChoice* widget, vector > items) } 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))); + for (auto i: items) { + widget->Append (std_to_wx(i.first), new wxStringClientData(std_to_wx(i.second))); } } @@ -224,6 +298,14 @@ checked_set (wxTextCtrl* widget, string value) } } +void +checked_set (PasswordEntry* entry, string value) +{ + if (entry->get() != value) { + entry->set(value); + } +} + void checked_set (wxTextCtrl* widget, wxString value) { @@ -269,15 +351,15 @@ dcpomatic_setup_i18n () { int language = wxLANGUAGE_DEFAULT; - boost::optional config_lang = Config::instance()->language (); + auto config_lang = Config::instance()->language (); if (config_lang && !config_lang->empty ()) { - wxLanguageInfo const * li = wxLocale::FindLanguageInfo (std_to_wx (config_lang.get ())); + auto const li = wxLocale::FindLanguageInfo (std_to_wx (config_lang.get ())); if (li) { language = li->Language; } } - wxLocale* locale = 0; + wxLocale* locale = nullptr; if (wxLocale::IsAvailable (language)) { locale = new wxLocale (language, wxLOCALE_LOAD_DEFAULT); @@ -293,6 +375,9 @@ dcpomatic_setup_i18n () of wxWidgets. */ locale->AddCatalog (wxT ("dcpomatic2-wxstd")); + + /* Fedora 29 (at least) installs wxstd3.mo instead of wxstd.mo */ + locale->AddCatalog (wxT ("wxstd3")); #endif locale->AddCatalog (wxT ("libdcpomatic2-wx")); @@ -333,7 +418,7 @@ wx_get (wxSpinCtrlDouble* w) wxString context_translation (wxString s) { - wxString t = wxGetTranslation (s); + auto t = wxGetTranslation (s); if (t == s) { /* No translation; strip the context */ int c = t.Find (wxT ("|")); @@ -348,7 +433,7 @@ context_translation (wxString s) wxString time_to_timecode (DCPTime t, double fps) { - double w = t.seconds (); + auto w = t.seconds (); int const h = (w / 3600); w -= h * 3600; int const m = (w / 60); @@ -381,3 +466,140 @@ setup_audio_channels_choice (wxChoice* choice, int minimum) checked_set (choice, items); } + +wxSplashScreen * +maybe_show_splash () +{ + wxSplashScreen* splash = nullptr; + try { + wxBitmap bitmap; + if (bitmap.LoadFile(bitmap_path("splash"), 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; +} + +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; +} + + +/** @return false if the task was cancelled */ +bool +display_progress (wxString title, wxString task) +{ + auto jm = JobManager::instance (); + + wxProgressDialog progress (title, task, 100, 0, wxPD_CAN_ABORT); + + bool ok = true; + + while (jm->work_to_do()) { + dcpomatic_sleep_seconds (1); + if (!progress.Pulse()) { + /* user pressed cancel */ + for (auto i: jm->get()) { + i->cancel(); + } + ok = false; + break; + } + } + + return ok; +} + + +int +get_offsets (vector& offsets) +{ + offsets.push_back (Offset(_("UTC-11"), -11, 0)); + offsets.push_back (Offset(_("UTC-10"), -10, 0)); + offsets.push_back (Offset(_("UTC-9"), -9, 0)); + offsets.push_back (Offset(_("UTC-8"), -8, 0)); + offsets.push_back (Offset(_("UTC-7"), -7, 0)); + offsets.push_back (Offset(_("UTC-6"), -6, 0)); + offsets.push_back (Offset(_("UTC-5"), -5, 0)); + offsets.push_back (Offset(_("UTC-4:30"), -4, 30)); + offsets.push_back (Offset(_("UTC-4"), -4, 0)); + offsets.push_back (Offset(_("UTC-3:30"), -3, 30)); + offsets.push_back (Offset(_("UTC-3"), -3, 0)); + offsets.push_back (Offset(_("UTC-2"), -2, 0)); + offsets.push_back (Offset(_("UTC-1"), -1, 0)); + int utc = offsets.size(); + offsets.push_back (Offset(_("UTC") , 0, 0)); + offsets.push_back (Offset(_("UTC+1"), 1, 0)); + offsets.push_back (Offset(_("UTC+2"), 2, 0)); + offsets.push_back (Offset(_("UTC+3"), 3, 0)); + offsets.push_back (Offset(_("UTC+4"), 4, 0)); + offsets.push_back (Offset(_("UTC+5"), 5, 0)); + offsets.push_back (Offset(_("UTC+5:30"), 5, 30)); + offsets.push_back (Offset(_("UTC+6"), 6, 0)); + offsets.push_back (Offset(_("UTC+7"), 7, 0)); + offsets.push_back (Offset(_("UTC+8"), 8, 0)); + offsets.push_back (Offset(_("UTC+9"), 9, 0)); + offsets.push_back (Offset(_("UTC+9:30"), 9, 30)); + offsets.push_back (Offset(_("UTC+10"), 10, 0)); + offsets.push_back (Offset(_("UTC+11"), 11, 0)); + offsets.push_back (Offset(_("UTC+12"), 12, 0)); + + return utc; +} + + +wxString +bitmap_path (string name) +{ + boost::filesystem::path base; + +#ifdef DCPOMATIC_DEBUG + /* Hack to allow Linux and OS X to find icons when running from the source tree */ + char* path = getenv ("DCPOMATIC_GRAPHICS"); + if (path) { + base = path; + } else { + base = resources_path(); + } +#else + base = resources_path(); +#endif + + boost::filesystem::path p = base / String::compose("%1.png", name); + return std_to_wx (p.string()); +} + + +wxSize +small_button_size (wxWindow* parent, wxString text) +{ + wxClientDC dc (parent); + auto size = dc.GetTextExtent (text); + size.SetHeight (-1); + size.IncBy (24, 0); + return size; +} +