#include "translit.h" IMPLEMENT_APP(TranslitGUI) bool TranslitGUI::OnInit() { TranslitFrame *translitFrame = new TranslitFrame(); translitFrame->Show(true); return true; } TranslitFrame::TranslitFrame(): wxFrame(nullptr, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(640,540), wxDEFAULT_FRAME_STYLE | wxRESIZE_BORDER, wxEmptyString) { main_panel = new wxPanel(this, wxID_ANY); main_sizer = new wxBoxSizer(wxVERTICAL); textfield_in = new wxTextCtrl(main_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(640,240), wxTE_MULTILINE, wxDefaultValidator); textfield_out = new wxTextCtrl(main_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(640,240), wxTE_MULTILINE, wxDefaultValidator); select_scheme = new wxComboBox(main_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY, wxDefaultValidator); select_scheme->Insert(wxT("ALA-LC (Library of Congress)"), SCHEME_LC); select_scheme->Insert(wxT("DIN 1460 (German academic)"), SCHEME_DIN); select_scheme->Insert(wxT("BGN/PCGN (British official)"), SCHEME_PCGN); select_scheme->Insert(wxT("ISO/R9 (Hybrid 1954/1968, OUP)"), SCHEME_OUP); select_scheme->Insert(wxT("ISO/R9 (invertible, international)"), SCHEME_ISO); select_scheme->Insert(wxT("Serbian national/official"), SCHEME_SRB); #ifdef TRANSLIT_OUP select_scheme->SetSelection(SCHEME_OUP); #else select_scheme->SetSelection(SCHEME_LC); #endif select_scheme->Bind(wxEVT_COMBOBOX, &TranslitFrame::set_lang_options, this); select_lang = new wxComboBox(main_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY, wxDefaultValidator); select_lang->Insert(wxT("Russian"), LANG_RUS); select_lang->Insert(wxT("Ukrainian"), LANG_UKR); select_lang->Insert(wxT("Belarusian"), LANG_BEL); select_lang->Insert(wxT("Bulgarian"), LANG_BG); select_lang->Insert(wxT("Historical"), LANG_CS); select_lang->SetSelection(LANG_RUS); select_sizer = new wxBoxSizer(wxHORIZONTAL); select_sizer->Add(select_scheme, 2, wxEXPAND | wxALL); select_sizer->Add(select_lang, 2, wxEXPAND | wxALL); translit_button = new wxButton(main_panel, wxID_OK, wxT("Run")); translit_button->Bind(wxEVT_BUTTON, &TranslitFrame::do_translit, this); clear_button = new wxButton(main_panel, wxID_CLEAR, wxT("Clear")); clear_button->Bind(wxEVT_BUTTON, &TranslitFrame::clear_text, this); copy_button = new wxButton(main_panel, wxID_COPY, wxT("Copy")); copy_button->Bind(wxEVT_BUTTON, &TranslitFrame::copy_text, this); quit_button = new wxButton(main_panel, wxID_EXIT, wxT("Exit")); quit_button->Bind(wxEVT_BUTTON, &TranslitFrame::OnExit, this); button_sizer = new wxBoxSizer(wxHORIZONTAL); button_sizer->Add(translit_button, 2, wxEXPAND | wxALL); button_sizer->Add(quit_button, 2, wxEXPAND | wxALL); button_sizer->Add(copy_button, 2, wxEXPAND | wxALL); button_sizer->Add(clear_button, 2, wxEXPAND | wxALL); main_sizer->Add(select_sizer, 0, wxEXPAND | wxALL, 5); main_sizer->Add(textfield_in, 2, wxEXPAND | wxALL, 5); main_sizer->Add(textfield_out, 2, wxEXPAND | wxALL, 5); main_sizer->Add(button_sizer, 0, wxEXPAND | wxALL, 2); main_panel->SetSizer(main_sizer); } void TranslitFrame::OnExit(wxCommandEvent& WXUNUSED(event)) { Close(true); } void TranslitFrame::set_lang_options(wxCommandEvent& WXUNUSED(event)) { if (select_scheme->GetSelection() == SCHEME_SRB || select_scheme->GetSelection() == SCHEME_ISO) select_lang->Enable(false); else select_lang->Enable(true); } void TranslitFrame::do_translit(wxCommandEvent& WXUNUSED(event)) { map char_map; wxString text_lat; wxString text_cyr = textfield_in->GetValue(); int scheme_selected = select_scheme->GetSelection(); int lang_selected = select_lang->GetSelection(); switch (scheme_selected) { case SCHEME_LC: char_map = ala_lc[0]; char_map.insert(ala_lc[lang_selected + 1].begin(), ala_lc[lang_selected + 1].end()); break; case SCHEME_DIN: char_map = din_1460[0]; char_map.insert(din_1460[lang_selected + 1].begin(), din_1460[lang_selected + 1].end()); break; case SCHEME_PCGN: char_map = bgp_pcgn[0]; char_map.insert(bgp_pcgn[lang_selected + 1].begin(), bgp_pcgn[lang_selected + 1].end()); break; case SCHEME_OUP: char_map = iso9_old[0]; char_map.insert(iso9_old[lang_selected + 1].begin(), iso9_old[lang_selected + 1].end()); break; case SCHEME_ISO: char_map = iso9_new; break; case SCHEME_SRB: char_map = srb_nat; break; } text_lat = replace_chars(text_cyr, char_map, scheme_selected, lang_selected); textfield_out->ChangeValue(text_lat); } void TranslitFrame::clear_text(wxCommandEvent& WXUNUSED(event)) { textfield_out->Clear(); textfield_in->Clear(); } void TranslitFrame::copy_text(wxCommandEvent& WXUNUSED(event)) { wxString text_to_copy = textfield_out->GetValue(); if (wxTheClipboard->Open()) { wxTheClipboard->SetData(new wxTextDataObject(text_to_copy)); wxTheClipboard->Close(); } } wxString TranslitFrame::replace_chars(wxString& text_in, map char_map, int scheme_type, int lang) { wxString text_out, subst; wxChar char_curr, char_prev, char_next; size_t char_no, char_max; const static wxRegEx match_vowels(wxT("[АЕЁИЙІОУЮЯЭЬЪѢѴаеёийіоуюяьъѣѵ]+")); const static wxRegEx match_upper(wxT("[А-ЯЪЬЀ-ЏҐѰѲѴѢѤѦѨѪѬѠ]+")); text_out.Clear(); char_max = text_in.length(); for (char_no = 0; char_no < char_max; char_no++) { char_curr = text_in[char_no]; if (char_no > 0) char_prev = text_in[char_no - 1]; if (char_no < char_max - 1) char_next = text_in[char_no + 1]; if (scheme_type == SCHEME_PCGN && lang == LANG_RUS) { if ((char_prev && match_vowels.Matches(char_prev)) || (char_no == 0 || char_prev == ' ' || char_prev == '\n')) { if (char_curr == L'е' || char_curr == L'ё') { text_out += L'y' + char_curr; continue; } else if (char_curr == L'Е' ) { if (char_next && match_upper.Matches(char_next)) text_out += L"YE"; else text_out += L"Ye"; continue; } else if (char_curr == L'Ë') { if (char_next && match_upper.Matches(char_next)) text_out += L"YË"; else text_out += L"Yë"; continue; } } } if (char_map.count(char_curr) > 0) { subst = char_map.find(char_curr)->second; // heuristic for smart detection of capitalization // TO DO: this doesn't work yet for diacritics if (char_next && match_upper.Matches(char_next) && match_upper.Matches(char_curr)) subst = subst.Upper(); text_out += subst; } else { text_out += char_curr; } } return text_out; }