--- /dev/null
+#include <dcp/language_tag.h>
+#include <wx/listctrl.h>
+#include <wx/srchctrl.h>
+#include <wx/wx.h>
+#include <boost/algorithm/string.hpp>
+#include <boost/bind.hpp>
+#include <boost/enable_shared_from_this.hpp>
+#include <boost/foreach.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/signals2.hpp>
+#include <iostream>
+#include <iterator>
+
+
+using std::string;
+using std::vector;
+using boost::enable_shared_from_this;
+using boost::optional;
+using boost::shared_ptr;
+using boost::weak_ptr;
+
+
+class SubtagListCtrl : public wxListCtrl
+{
+public:
+ SubtagListCtrl (wxWindow* parent)
+ : wxListCtrl (parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxLC_SINGLE_SEL | wxLC_NO_HEADER | wxLC_VIRTUAL)
+ {
+ AppendColumn ("", wxLIST_FORMAT_LEFT, 80);
+ AppendColumn ("", wxLIST_FORMAT_LEFT, 400);
+ }
+
+ void set_type_and_search (dcp::LanguageTag::SubtagType type, string search, optional<dcp::LanguageTag::Subtag> subtag = optional<dcp::LanguageTag::Subtag>())
+ {
+ _all_subtags = dcp::LanguageTag::get_all(type);
+ set_search (search);
+ if (subtag) {
+ vector<dcp::LanguageTag::Subtag>::iterator i = find(_matching_subtags.begin(), _matching_subtags.end(), *subtag);
+ if (i != _matching_subtags.end()) {
+ SetItemState (std::distance(_matching_subtags.begin(), i), wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
+ }
+ }
+ }
+
+ void set_search (string search)
+ {
+ if (search == "") {
+ _matching_subtags = _all_subtags;
+ } else {
+ _matching_subtags.clear ();
+
+ boost::algorithm::to_lower(search);
+ BOOST_FOREACH (dcp::LanguageTag::Subtag const& i, _all_subtags) {
+ if (
+ (boost::algorithm::to_lower_copy(i.subtag).find(search) != string::npos) ||
+ (boost::algorithm::to_lower_copy(i.description).find(search) != string::npos)) {
+ _matching_subtags.push_back (i);
+ }
+ }
+ }
+
+ SetItemCount (_matching_subtags.size());
+ if (GetItemCount() > 0) {
+ RefreshItems (0, GetItemCount() - 1);
+ }
+ }
+
+ optional<dcp::LanguageTag::Subtag> selected_subtag () const
+ {
+ long int selected = GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
+ if (selected == -1) {
+ return optional<dcp::LanguageTag::Subtag>();
+ }
+
+ //DCPOMATIC_ASSERT (selected < _matching_subtags.size());
+ return _matching_subtags[selected];
+ }
+
+private:
+ wxString OnGetItemText (long item, long column) const
+ {
+ if (column == 0) {
+ return _matching_subtags[item].subtag;
+ } else {
+ return _matching_subtags[item].description;
+ }
+ }
+
+ std::vector<dcp::LanguageTag::Subtag> _all_subtags;
+ std::vector<dcp::LanguageTag::Subtag> _matching_subtags;
+};
+
+
+class LanguageSubtagPanel : public wxPanel
+{
+public:
+ LanguageSubtagPanel (wxWindow* parent)
+ : wxPanel (parent, wxID_ANY)
+ {
+#ifdef __WXGTK3__
+ int const height = 30;
+#else
+ int const height = -1;
+#endif
+
+ _search = new wxSearchCtrl (this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(200, height));
+ _list = new SubtagListCtrl (this);
+
+ wxBoxSizer* sizer = new wxBoxSizer (wxVERTICAL);
+ sizer->Add (_search, 0, wxALL, 8);
+ sizer->Add (_list, 1, wxALL, 8);
+ SetSizerAndFit (sizer);
+
+ _search->Bind (wxEVT_TEXT, boost::bind(&LanguageSubtagPanel::search_changed, this));
+ _list->Bind (wxEVT_LIST_ITEM_SELECTED, boost::bind(&LanguageSubtagPanel::selection_changed, this));
+ _list->Bind (wxEVT_LIST_ITEM_DESELECTED, boost::bind(&LanguageSubtagPanel::selection_changed, this));
+ }
+
+ void set_type_and_search (dcp::LanguageTag::SubtagType type, string search, optional<dcp::LanguageTag::Subtag> subtag = optional<dcp::LanguageTag::Subtag>())
+ {
+ _list->set_type_and_search (type, search, subtag);
+ _search->SetValue (wxString(search));
+ }
+
+ boost::signals2::signal<void (optional<dcp::LanguageTag::Subtag>)> SelectionChanged;
+ boost::signals2::signal<void (string)> SearchChanged;
+
+private:
+ void search_changed ()
+ {
+ _list->set_search (_search->GetValue().ToStdString());
+ SearchChanged (_search->GetValue().ToStdString());
+ }
+
+ void selection_changed ()
+ {
+ SelectionChanged (_list->selected_subtag());
+ }
+
+ wxSearchCtrl* _search;
+ SubtagListCtrl* _list;
+};
+
+
+
+
+class LanguageTagDialog : public wxDialog
+{
+public:
+ class Subtag
+ {
+ public:
+ Subtag (dcp::LanguageTag::SubtagType type_, dcp::LanguageTag::Subtag subtag_)
+ : type (type_)
+ , subtag (subtag_)
+ {}
+
+ dcp::LanguageTag::SubtagType type;
+ dcp::LanguageTag::Subtag subtag;
+ std::string last_search;
+ };
+
+ LanguageTagDialog (wxWindow* parent)
+ : wxDialog (parent, wxID_ANY, "Language Tag")
+ {
+ _current_tag_list = new wxListCtrl (this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxLC_SINGLE_SEL | wxLC_NO_HEADER);
+ _current_tag_list->AppendColumn ("", wxLIST_FORMAT_LEFT, 200);
+ _current_tag_list->AppendColumn ("", wxLIST_FORMAT_LEFT, 400);
+
+ wxBoxSizer* button_sizer = new wxBoxSizer (wxVERTICAL);
+ _add_script = new wxButton(this, wxID_ANY, "Add script");
+ button_sizer->Add (_add_script, 1, wxTOP | wxBOTTOM | wxEXPAND, 2);
+ _add_region = new wxButton(this, wxID_ANY, "Add region");
+ button_sizer->Add (_add_region, 1, wxTOP | wxBOTTOM | wxEXPAND, 2);
+ _add_variant = new wxButton(this, wxID_ANY, "Add variant");
+ button_sizer->Add (_add_variant, 1, wxTOP | wxBOTTOM | wxEXPAND, 2);
+ _add_external = new wxButton(this, wxID_ANY, "Add external");
+ button_sizer->Add (_add_external, 1, wxTOP | wxBOTTOM | wxEXPAND, 2);
+
+ _choose_subtag_panel = new LanguageSubtagPanel (this);
+ _choose_subtag_panel->set_type_and_search (dcp::LanguageTag::LANGUAGE, "de");
+
+ wxBoxSizer* overall_sizer = new wxBoxSizer (wxHORIZONTAL);
+ overall_sizer->Add (_current_tag_list, 1, wxALL, 8);
+ overall_sizer->Add (button_sizer, 0, wxALL, 8);
+ overall_sizer->Add (_choose_subtag_panel, 1, wxALL, 8);
+
+ SetSizerAndFit (overall_sizer);
+
+ add_to_current_tag (dcp::LanguageTag::LANGUAGE, dcp::LanguageTag::Subtag("en", "English"));
+
+ _add_script->Bind (wxEVT_BUTTON, boost::bind(&LanguageTagDialog::add_to_current_tag, this, dcp::LanguageTag::SCRIPT, dcp::LanguageTag::Subtag()));
+ _add_region->Bind (wxEVT_BUTTON, boost::bind(&LanguageTagDialog::add_to_current_tag, this, dcp::LanguageTag::REGION, dcp::LanguageTag::Subtag()));
+ _add_variant->Bind (wxEVT_BUTTON, boost::bind(&LanguageTagDialog::add_to_current_tag, this, dcp::LanguageTag::VARIANT, dcp::LanguageTag::Subtag()));
+ _add_external->Bind (wxEVT_BUTTON, boost::bind(&LanguageTagDialog::add_to_current_tag, this, dcp::LanguageTag::EXTLANG, dcp::LanguageTag::Subtag()));
+ _choose_subtag_panel->SelectionChanged.connect(bind(&LanguageTagDialog::chosen_subtag_changed, this, _1));
+ _choose_subtag_panel->SearchChanged.connect(bind(&LanguageTagDialog::search_changed, this, _1));
+ _current_tag_list->Bind (wxEVT_LIST_ITEM_SELECTED, boost::bind(&LanguageTagDialog::current_tag_selection_changed, this));
+ _current_tag_list->Bind (wxEVT_LIST_ITEM_DESELECTED, boost::bind(&LanguageTagDialog::current_tag_selection_changed, this));
+ }
+
+ dcp::LanguageTag get () const
+ {
+ dcp::LanguageTag tag;
+
+ vector<string> variants;
+ vector<string> extlangs;
+
+ BOOST_FOREACH (Subtag i, _current_tag_subtags) {
+ switch (i.type) {
+ case dcp::LanguageTag::LANGUAGE:
+ tag.set_language (i.subtag.subtag);
+ break;
+ case dcp::LanguageTag::SCRIPT:
+ tag.set_script (i.subtag.subtag);
+ break;
+ case dcp::LanguageTag::REGION:
+ tag.set_region (i.subtag.subtag);
+ break;
+ case dcp::LanguageTag::VARIANT:
+ variants.push_back (i.subtag.subtag);
+ break;
+ case dcp::LanguageTag::EXTLANG:
+ extlangs.push_back (i.subtag.subtag);
+ break;
+ }
+ }
+
+ tag.set_variants (variants);
+ tag.set_extlangs (extlangs);
+ return tag;
+ }
+
+
+private:
+
+ string subtag_type_name (dcp::LanguageTag::SubtagType type)
+ {
+ switch (type) {
+ case dcp::LanguageTag::LANGUAGE:
+ return "Language";
+ case dcp::LanguageTag::SCRIPT:
+ return "Script";
+ case dcp::LanguageTag::REGION:
+ return "Region";
+ case dcp::LanguageTag::VARIANT:
+ return "Variant";
+ case dcp::LanguageTag::EXTLANG:
+ return "External";
+ }
+
+ return "";
+ }
+
+ void search_changed (string search)
+ {
+ long int selected = _current_tag_list->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
+ if (selected >= 0) {
+ _current_tag_subtags[selected].last_search = search;
+ }
+ }
+
+ void add_to_current_tag (dcp::LanguageTag::SubtagType type, dcp::LanguageTag::Subtag subtag)
+ {
+ _current_tag_subtags.push_back (Subtag(type, subtag));
+ wxListItem it;
+ it.SetId (_current_tag_list->GetItemCount());
+ it.SetColumn (0);
+ it.SetText (subtag_type_name(type));
+ _current_tag_list->InsertItem (it);
+ it.SetColumn (1);
+ it.SetText ("Select...");
+ _current_tag_list->SetItem (it);
+ _current_tag_list->SetItemState (_current_tag_list->GetItemCount() - 1, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
+ _choose_subtag_panel->set_type_and_search (type, "");
+ setup_sensitivity ();
+ }
+
+ void current_tag_selection_changed ()
+ {
+ long int selected = _current_tag_list->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
+ if (selected >= 0) {
+ _choose_subtag_panel->Enable (true);
+ _choose_subtag_panel->set_type_and_search (_current_tag_subtags[selected].type, _current_tag_subtags[selected].last_search, _current_tag_subtags[selected].subtag);
+ } else {
+ _choose_subtag_panel->Enable (false);
+ }
+ }
+
+ void chosen_subtag_changed (optional<dcp::LanguageTag::Subtag> selection)
+ {
+ if (!selection) {
+ return;
+ }
+
+ long int selected = _current_tag_list->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
+ if (selected >= 0) {
+ _current_tag_subtags[selected].subtag = *selection;
+ _current_tag_list->SetItem (selected, 0, subtag_type_name(_current_tag_subtags[selected].type));
+ _current_tag_list->SetItem (selected, 1, selection->description);
+ }
+ }
+
+ void setup_sensitivity ()
+ {
+ _add_script->Enable ();
+ _add_region->Enable ();
+ _add_variant->Enable ();
+ _add_external->Enable ();
+ BOOST_FOREACH (Subtag const& i, _current_tag_subtags) {
+ switch (i.type) {
+ case dcp::LanguageTag::SCRIPT:
+ _add_script->Enable (false);
+ break;
+ case dcp::LanguageTag::REGION:
+ _add_region->Enable (false);
+ break;
+ case dcp::LanguageTag::VARIANT:
+ _add_variant->Enable (false);
+ break;
+ case dcp::LanguageTag::EXTLANG:
+ _add_external->Enable (false);
+ break;
+ }
+ }
+ }
+
+ vector<Subtag> _current_tag_subtags;
+ wxListCtrl* _current_tag_list;
+ LanguageSubtagPanel* _choose_subtag_panel;
+ wxButton* _add_script;
+ wxButton* _add_region;
+ wxButton* _add_variant;
+ wxButton* _add_external;
+};
+
+
+class MyApp : public wxApp
+{
+public:
+ virtual bool OnInit()
+ {
+ LanguageTagDialog* dialog = new LanguageTagDialog (0);
+ dialog->ShowModal ();
+ return true;
+ }
+};
+
+wxIMPLEMENT_APP(MyApp);
+