Add custom dialog to select system fonts on Windows (#491).
authorCarl Hetherington <cth@carlh.net>
Tue, 18 Aug 2015 22:30:42 +0000 (23:30 +0100)
committerCarl Hetherington <cth@carlh.net>
Tue, 18 Aug 2015 22:30:42 +0000 (23:30 +0100)
ChangeLog
src/wx/fonts_dialog.cc
src/wx/fonts_dialog.h
src/wx/system_font_dialog.cc [new file with mode: 0644]
src/wx/system_font_dialog.h [new file with mode: 0644]
src/wx/wscript

index fc0d7cc2c8f14526e754579572592a50673994d7..ddb575db4fbff11e6512ee9060974b3d5538f537 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
 2015-08-18  Carl Hetherington  <cth@carlh.net>
 
+       * Add custom dialog to select system fonts on Windows
+       (#491).
+
        * Version 2.1.41 released.
 
 2015-08-18  Carl Hetherington  <cth@carlh.net>
index 092faf9e6c0e96cb2de50daf41aabd56696b9deb..9564f6b77ab53471e9009b0df49dffc060e470b0 100644 (file)
 
 */
 
-#include "lib/font.h"
-#include "lib/subtitle_content.h"
 #include "fonts_dialog.h"
 #include "wx_util.h"
+#include "system_font_dialog.h"
+#include "lib/font.h"
+#include "lib/subtitle_content.h"
 #include <wx/wx.h>
+#include <boost/foreach.hpp>
 
 using std::list;
 using std::string;
@@ -31,6 +33,7 @@ using boost::shared_ptr;
 FontsDialog::FontsDialog (wxWindow* parent, shared_ptr<SubtitleContent> content)
        : wxDialog (parent, wxID_ANY, _("Fonts"))
        , _content (content)
+       , _set_from_system (0)
 {
        _fonts = new wxListCtrl (this, wxID_ANY, wxDefaultPosition, wxSize (400, 200), wxLC_REPORT | wxLC_SINGLE_SEL);
 
@@ -55,8 +58,12 @@ FontsDialog::FontsDialog (wxWindow* parent, shared_ptr<SubtitleContent> content)
 
        {
                wxSizer* s = new wxBoxSizer (wxVERTICAL);
-               _set_file = new wxButton (this, wxID_ANY, _("Set file..."));
-               s->Add (_set_file, 0, wxTOP | wxBOTTOM, DCPOMATIC_BUTTON_STACK_GAP);
+               _set_from_file = new wxButton (this, wxID_ANY, _("Set from .ttf file..."));
+               s->Add (_set_from_file, 0, wxTOP | wxBOTTOM, DCPOMATIC_BUTTON_STACK_GAP);
+#ifdef DCPOMATIC_WINDOWS
+               _set_from_system = new wxButton (this, wxID_ANY, _("Set from system font..."));
+               s->Add (_set_from_system, 0, wxTOP | wxBOTTOM, DCPOMATIC_BUTTON_STACK_GAP);
+#endif
                sizer->Add (s, 0, wxLEFT, DCPOMATIC_SIZER_X_GAP);
        }
 
@@ -70,12 +77,14 @@ FontsDialog::FontsDialog (wxWindow* parent, shared_ptr<SubtitleContent> content)
 
        SetSizerAndFit (overall_sizer);
 
-       _set_file->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&FontsDialog::set_file_clicked, this));
+       _set_from_file->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&FontsDialog::set_from_file_clicked, this));
+       if (_set_from_system) {
+               _set_from_system->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&FontsDialog::set_from_system_clicked, this));
+       }
        _fonts->Bind (wxEVT_COMMAND_LIST_ITEM_SELECTED, boost::bind (&FontsDialog::selection_changed, this));
        _fonts->Bind (wxEVT_COMMAND_LIST_ITEM_DESELECTED, boost::bind (&FontsDialog::selection_changed, this));
 
        setup ();
-       update_sensitivity ();
 }
 
 void
@@ -99,21 +108,13 @@ FontsDialog::setup ()
                }
                ++n;
        }
+
+       update_sensitivity ();
 }
 
 void
-FontsDialog::set_file_clicked ()
+FontsDialog::set_from_file_clicked ()
 {
-       shared_ptr<SubtitleContent> content = _content.lock ();
-       if (!content) {
-               return;
-       }
-
-       int item = _fonts->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
-       if (item == -1) {
-               return;
-       }
-
        /* The wxFD_CHANGE_DIR here prevents a `could not set working directory' error 123 on Windows when using
           non-Latin filenames or paths.
        */
@@ -125,16 +126,45 @@ FontsDialog::set_file_clicked ()
                return;
        }
 
-       string id = wx_to_std (_fonts->GetItemText (item, 0));
+       set_selected_font_file (wx_to_std (d->GetPath ()));
+       d->Destroy ();
+}
 
-       list<shared_ptr<Font> > fonts = content->fonts ();
-       for (list<shared_ptr<Font> >::iterator i = fonts.begin(); i != fonts.end(); ++i) {
-               if ((*i)->id() == id) {
-                       (*i)->set_file (wx_to_std (d->GetPath ()));
-               }
+void
+FontsDialog::set_from_system_clicked ()
+{
+       SystemFontDialog* d = new SystemFontDialog (this);
+       int const r = d->ShowModal ();
+
+       if (r != wxID_OK) {
+               d->Destroy ();
+               return;
        }
 
+       set_selected_font_file (d->get_font().get ());
        d->Destroy ();
+}
+
+void
+FontsDialog::set_selected_font_file (boost::filesystem::path file)
+{
+       shared_ptr<SubtitleContent> content = _content.lock ();
+       if (!content) {
+               return;
+       }
+
+       int item = _fonts->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
+       if (item == -1) {
+               return;
+       }
+
+       string id = wx_to_std (_fonts->GetItemText (item, 0));
+
+       BOOST_FOREACH (shared_ptr<Font> i, content->fonts ()) {
+               if (i->id() == id) {
+                       i->set_file (file);
+               }
+       }
 
        setup ();
 }
@@ -149,5 +179,8 @@ void
 FontsDialog::update_sensitivity ()
 {
        int const item = _fonts->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
-       _set_file->Enable (item != -1);
+       _set_from_file->Enable (item != -1);
+       if (_set_from_system) {
+               _set_from_system->Enable (item != -1);
+       }
 }
index 0d4bcfd7e8752b79980e9c0193e14606e8dc84c1..c29a982c932ee318a9d5550fa157304542463bc7 100644 (file)
@@ -20,6 +20,8 @@
 #include <wx/listctrl.h>
 #include <wx/wx.h>
 #include <boost/shared_ptr.hpp>
+#include <boost/weak_ptr.hpp>
+#include <boost/filesystem.hpp>
 
 class SubtitleContent;
 
@@ -30,11 +32,14 @@ public:
 
 private:
        void setup ();
-       void set_file_clicked ();
+       void set_from_file_clicked ();
+       void set_from_system_clicked ();
        void update_sensitivity ();
        void selection_changed ();
+       void set_selected_font_file (boost::filesystem::path file);
 
        boost::weak_ptr<SubtitleContent> _content;
        wxListCtrl* _fonts;
-       wxButton* _set_file;
+       wxButton* _set_from_file;
+       wxButton* _set_from_system;
 };
diff --git a/src/wx/system_font_dialog.cc b/src/wx/system_font_dialog.cc
new file mode 100644 (file)
index 0000000..62fd046
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+    Copyright (C) 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
+    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,
+    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.
+
+*/
+
+#include "system_font_dialog.h"
+#include "wx_util.h"
+#include <wx/listctrl.h>
+#include <boost/filesystem.hpp>
+#include <boost/foreach.hpp>
+
+using std::cout;
+using std::string;
+using boost::optional;
+
+SystemFontDialog::SystemFontDialog (wxWindow* parent)
+       : wxDialog (parent, wxID_ANY, _("Choose a font"))
+{
+       wxSizer* sizer = new wxBoxSizer (wxVERTICAL);
+
+       boost::filesystem::path fonts = "c:\\Windows\\Fonts";
+       char* windir = getenv ("windir");
+       if (windir) {
+               fonts = boost::filesystem::path (windir) / "Fonts";
+       }
+
+       for (
+               boost::filesystem::directory_iterator i = boost::filesystem::directory_iterator (fonts);
+               i != boost::filesystem::directory_iterator ();
+               ++i
+               ) {
+
+               string ext = i->path().extension().string ();
+               transform (ext.begin(), ext.end(), ext.begin(), ::tolower);
+
+               if (ext == ".ttf") {
+                       _fonts.push_back (i->path());
+               }
+       }
+
+       sort (_fonts.begin (), _fonts.end ());
+
+       _list = new wxListCtrl (this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxLC_NO_HEADER);
+       _list->InsertColumn (0, wxT (""));
+       _list->SetColumnWidth (0, 512);
+       sizer->Add (_list, 0, wxALL, DCPOMATIC_SIZER_X_GAP);
+
+       int n = 0;
+       BOOST_FOREACH (boost::filesystem::path i, _fonts) {
+               _list->InsertItem (n++, std_to_wx (i.leaf().stem().string ()));
+       }
+
+       wxSizer* buttons = CreateSeparatedButtonSizer (wxOK | wxCANCEL);
+       if (buttons) {
+               sizer->Add (buttons, wxSizerFlags().Expand().DoubleBorder());
+       }
+
+       SetSizerAndFit (sizer);
+
+       _list->Bind (wxEVT_COMMAND_LIST_ITEM_SELECTED, boost::bind (&SystemFontDialog::setup_sensitivity, this));
+       _list->Bind (wxEVT_COMMAND_LIST_ITEM_DESELECTED, boost::bind (&SystemFontDialog::setup_sensitivity, this));
+
+       setup_sensitivity ();
+}
+
+optional<boost::filesystem::path>
+SystemFontDialog::get_font () const
+{
+       int const s = _list->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
+       if (s == -1) {
+               return optional<boost::filesystem::path> ();
+       }
+
+       if (s < int (_fonts.size ())) {
+               return _fonts[s];
+       }
+
+       return optional<boost::filesystem::path> ();
+}
+
+void
+SystemFontDialog::setup_sensitivity ()
+{
+       wxButton* ok = dynamic_cast<wxButton *> (FindWindowById (wxID_OK, this));
+       if (ok) {
+               ok->Enable (_list->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED) != -1);
+       }
+}
diff --git a/src/wx/system_font_dialog.h b/src/wx/system_font_dialog.h
new file mode 100644 (file)
index 0000000..6d5aa0e
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+    Copyright (C) 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
+    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,
+    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.
+
+*/
+
+/** @class SystemFontDialog
+ *  @brief A dialog box to select one of the "system" fonts on Windows.
+ *
+ *  This is necessary because wxFileDialog on Windows will not display
+ *  the contents of c:\Windows\Fonts, so we need a different way to choose
+ *  one of those fonts.
+ */
+
+#include <wx/wx.h>
+#include <boost/filesystem.hpp>
+#include <boost/optional.hpp>
+#include <vector>
+
+class wxListCtrl;
+
+class SystemFontDialog : public wxDialog
+{
+public:
+       SystemFontDialog (wxWindow* parent);
+
+       boost::optional<boost::filesystem::path> get_font () const;
+
+private:
+       void setup_sensitivity ();
+
+       wxListCtrl* _list;
+       std::vector<boost::filesystem::path> _fonts;
+};
index 96a0c48693df3105ac63d64ba670c63a4b73216a..94df94ca3104bd36f12fbf7eeac39737cf3768e1 100644 (file)
@@ -65,6 +65,7 @@ sources = """
           servers_list_dialog.cc
           subtitle_panel.cc
           subtitle_view.cc
+          system_font_dialog.cc
           table_dialog.cc
           timecode.cc
           timeline.cc