1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/richtext/richtextsymboldlg.cpp 
   4 // Author:      Julian Smart 
   6 // Created:     10/5/2006 3:11:58 PM 
   8 // Copyright:   (c) Julian Smart 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // For compilers that support precompilation, includes "wx/wx.h". 
  13 #include "wx/wxprec.h" 
  21 #include "wx/richtext/richtextsymboldlg.h" 
  25     #include "wx/stattext.h" 
  26     #include "wx/combobox.h" 
  27     #include "wx/button.h" 
  28     #include "wx/settings.h" 
  30     #include "wx/listbox.h" 
  33 #include "wx/fontenum.h" 
  34 #include "wx/dcbuffer.h" 
  36 /* Microsoft Unicode subset numbering 
  42   U_LATIN_1_SUPPLEMENT 
= 1, 
  43   U_LATIN_EXTENDED_A 
= 2, 
  44   U_LATIN_EXTENDED_B 
= 3, 
  46   U_SPACING_MODIFIER_LETTERS 
= 5, 
  47   U_COMBINING_DIACRITICAL_MARKS 
= 6, 
  49   U_GREEK_SYMBOLS_AND_COPTIC 
= 8, 
  52   U_HEBREW_EXTENDED 
= 12, 
  55   U_ARABIC_EXTENDED 
= 14, 
  67   U_GEORGIAN_EXTENDED 
= 27, 
  68   U_BASIC_GEORGIAN 
= 26, 
  70   U_LATIN_EXTENDED_ADDITIONAL 
= 29, 
  71   U_GREEK_EXTENDED 
= 30, 
  72   U_GENERAL_PUNCTUATION 
= 31, 
  73   U_SUPERSCRIPTS_AND_SUBSCRIPTS 
= 32, 
  74   U_CURRENCY_SYMBOLS 
= 33, 
  75   U_COMBINING_DIACRITICAL_MARKS_FOR_SYMBOLS 
= 34, 
  76   U_LETTERLIKE_SYMBOLS 
= 35, 
  79   U_MATHEMATICAL_OPERATORS 
= 38, 
  80   U_MISCELLANEOUS_TECHNICAL 
= 39, 
  81   U_CONTROL_PICTURES 
= 40, 
  82   U_OPTICAL_CHARACTER_RECOGNITION 
= 41, 
  83   U_ENCLOSED_ALPHANUMERICS 
= 42, 
  85   U_BLOCK_ELEMENTS 
= 44, 
  86   U_GEOMETRIC_SHAPES 
= 45, 
  87   U_MISCELLANEOUS_SYMBOLS 
= 46, 
  89   U_CJK_SYMBOLS_AND_PUNCTUATION 
= 48, 
  93   U_HANGUL_COMPATIBILITY_JAMO 
= 52, 
  94   U_CJK_MISCELLANEOUS 
= 53, 
  96   U_CJK_COMPATIBILITY 
= 55, 
  98   U_HANGUL_SUPPLEMENTARY_A 
= 57, 
  99   U_HANGUL_SUPPLEMENTARY_B 
= 58, 
 100   U_CJK_UNIFIED_IDEOGRAPHS 
= 59, 
 101   U_PRIVATE_USE_AREA 
= 60, 
 102   U_CJK_COMPATIBILITY_IDEOGRAPHS 
= 61, 
 103   U_ALPHABETIC_PRESENTATION_FORMS 
= 62, 
 104   U_ARABIC_PRESENTATION_FORMS_A 
= 63, 
 105   U_COMBINING_HALF_MARKS 
= 64, 
 106   U_CJK_COMPATIBILITY_FORMS 
= 65, 
 107   U_SMALL_FORM_VARIANTS 
= 66, 
 108   U_ARABIC_PRESENTATION_FORMS_B 
= 67, 
 110   U_HALFWIDTH_AND_FULLWIDTH_FORMS 
= 68, 
 112 } wxUnicodeSubsetCodes
; 
 114 /* Unicode subsets */ 
 120     wxUnicodeSubsetCodes m_subset
; 
 122 } g_UnicodeSubsetTable
[] = 
 125     U_BASIC_LATIN
, wxT("Basic Latin") }, 
 127     U_LATIN_1_SUPPLEMENT
, wxT("Latin-1 Supplement") }, 
 129     U_LATIN_EXTENDED_A
, wxT("Latin Extended-A") }, 
 131     U_LATIN_EXTENDED_B
, wxT("Latin Extended-B") }, 
 133     U_IPA_EXTENSIONS
, wxT("IPA Extensions") }, 
 135     U_SPACING_MODIFIER_LETTERS
, wxT("Spacing Modifier Letters") }, 
 137     U_COMBINING_DIACRITICAL_MARKS
, wxT("Combining Diacritical Marks") }, 
 139     U_BASIC_GREEK
, wxT("Basic Greek") }, 
 141     U_GREEK_SYMBOLS_AND_COPTIC
, wxT("Greek Symbols and Coptic") }, 
 143     U_CYRILLIC
, wxT("Cyrillic") }, 
 145     U_ARMENIAN
, wxT("Armenian") }, 
 147     U_HEBREW_EXTENDED
, wxT("Hebrew Extended") }, 
 149     U_BASIC_HEBREW
, wxT("Basic Hebrew") }, 
 151     U_BASIC_ARABIC
, wxT("Basic Arabic") }, 
 153     U_ARABIC_EXTENDED
, wxT("Arabic Extended") }, 
 155     U_DEVANAGARI
, wxT("Devanagari") }, 
 157     U_BENGALI
, wxT("Bengali") }, 
 159     U_GURMUKHI
, wxT("Gurmukhi") }, 
 161     U_GUJARATI
, wxT("Gujarati") }, 
 163     U_ORIYA
, wxT("Oriya") }, 
 165     U_TAMIL
, wxT("Tamil") }, 
 167     U_TELUGU
, wxT("Telugu") }, 
 169     U_KANNADA
, wxT("Kannada") }, 
 171     U_MALAYALAM
, wxT("Malayalam") }, 
 173     U_THAI
, wxT("Thai") }, 
 177     U_GEORGIAN_EXTENDED
, wxT("Georgian Extended") }, 
 179     U_BASIC_GEORGIAN
, wxT("Basic Georgian") }, 
 181     U_HANGUL_JAMO
, wxT("Hangul Jamo") }, 
 183     U_LATIN_EXTENDED_ADDITIONAL
, wxT("Latin Extended Additional") }, 
 185     U_GREEK_EXTENDED
, wxT("Greek Extended") }, 
 187     U_GENERAL_PUNCTUATION
, wxT("General Punctuation") }, 
 189     U_SUPERSCRIPTS_AND_SUBSCRIPTS
, wxT("Superscripts and Subscripts") }, 
 191     U_CURRENCY_SYMBOLS
, wxT("Currency Symbols") }, 
 193     U_COMBINING_DIACRITICAL_MARKS_FOR_SYMBOLS
, wxT("Combining Diacritical Marks for Symbols") }, 
 195     U_LETTERLIKE_SYMBOLS
, wxT("Letterlike Symbols") }, 
 197     U_NUMBER_FORMS
, wxT("Number Forms") }, 
 199     U_ARROWS
, wxT("Arrows") }, 
 201     U_MATHEMATICAL_OPERATORS
, wxT("Mathematical Operators") }, 
 203     U_MISCELLANEOUS_TECHNICAL
, wxT("Miscellaneous Technical") }, 
 205     U_CONTROL_PICTURES
, wxT("Control Pictures") }, 
 207     U_OPTICAL_CHARACTER_RECOGNITION
, wxT("Optical Character Recognition") }, 
 209     U_ENCLOSED_ALPHANUMERICS
, wxT("Enclosed Alphanumerics") }, 
 211     U_BOX_DRAWING
, wxT("Box Drawing") }, 
 213     U_BLOCK_ELEMENTS
, wxT("Block Elements") }, 
 215     U_GEOMETRIC_SHAPES
, wxT("Geometric Shapes") }, 
 217     U_MISCELLANEOUS_SYMBOLS
, wxT("Miscellaneous Symbols") }, 
 219     U_DINGBATS
, wxT("Dingbats") }, 
 221     U_CJK_SYMBOLS_AND_PUNCTUATION
, wxT("CJK Symbols and Punctuation") }, 
 223     U_HIRAGANA
, wxT("Hiragana") }, 
 225     U_KATAKANA
, wxT("Katakana") }, 
 227     U_BOPOMOFO
, wxT("Bopomofo") }, 
 229     U_HANGUL_COMPATIBILITY_JAMO
, wxT("Hangul Compatibility Jamo") }, 
 231     U_CJK_MISCELLANEOUS
, wxT("CJK Miscellaneous") }, 
 233     U_ENCLOSED_CJK
, wxT("Enclosed CJK") }, 
 235     U_CJK_COMPATIBILITY
, wxT("CJK Compatibility") }, 
 237     U_CJK_UNIFIED_IDEOGRAPHS
, wxT("CJK Unified Ideographs Extension A") }, 
 239     U_CJK_UNIFIED_IDEOGRAPHS
, wxT("CJK Unified Ideographs") }, 
 241     U_HANGUL
, wxT("Hangul Syllables") }, 
 243     U_PRIVATE_USE_AREA
, wxT("Private Use Area") }, 
 245     U_CJK_COMPATIBILITY_IDEOGRAPHS
, wxT("CJK Compatibility Ideographs") }, 
 247     U_ALPHABETIC_PRESENTATION_FORMS
, wxT("Alphabetic Presentation Forms") }, 
 249     U_ARABIC_PRESENTATION_FORMS_A
, wxT("Arabic Presentation Forms-A") }, 
 251     U_COMBINING_HALF_MARKS
, wxT("Combining Half Marks") }, 
 253     U_CJK_COMPATIBILITY_FORMS
, wxT("CJK Compatibility Forms") }, 
 255     U_SMALL_FORM_VARIANTS
, wxT("Small Form Variants") }, 
 257     U_ARABIC_PRESENTATION_FORMS_B
, wxT("Arabic Presentation Forms-B") }, 
 259     U_SPECIALS
, wxT("Specials") }, 
 261     U_HALFWIDTH_AND_FULLWIDTH_FORMS
, wxT("Halfwidth and Fullwidth Forms") }, 
 263     U_SPECIALS
, wxT("Specials") } 
 266 #endif // __UNICODE__ 
 269 // Not yet used, but could be used to test under Win32 whether this subset is available 
 270 // for the given font. The Win32 function is allegedly not accurate, however. 
 271 bool wxSubsetValidForFont(int subsetIndex
, FONTSIGNATURE 
*fontSig
) 
 273     return (fontSig
->fsUsb
[g_UnicodeSubsetTable
[subsetIndex
].m_subset
/32] & (1 << (g_UnicodeSubsetTable
[subsetIndex
].m_subset 
% 32))); 
 278  * wxSymbolPickerDialog type definition 
 281 IMPLEMENT_DYNAMIC_CLASS( wxSymbolPickerDialog
, wxDialog 
) 
 284  * wxSymbolPickerDialog event table definition 
 287 BEGIN_EVENT_TABLE( wxSymbolPickerDialog
, wxDialog 
) 
 288     EVT_LISTBOX(ID_SYMBOLPICKERDIALOG_LISTCTRL
, wxSymbolPickerDialog::OnSymbolSelected
) 
 290 ////@begin wxSymbolPickerDialog event table entries 
 291     EVT_COMBOBOX( ID_SYMBOLPICKERDIALOG_FONT
, wxSymbolPickerDialog::OnFontCtrlSelected 
) 
 293 #if defined(__UNICODE__) 
 294     EVT_COMBOBOX( ID_SYMBOLPICKERDIALOG_SUBSET
, wxSymbolPickerDialog::OnSubsetSelected 
) 
 297 #if defined(__UNICODE__) 
 298     EVT_COMBOBOX( ID_SYMBOLPICKERDIALOG_FROM
, wxSymbolPickerDialog::OnFromUnicodeSelected 
) 
 301 #if defined(__WXMSW__) || defined(__WXGTK__) || defined(__WXOS2__) || defined(__WXMGL__) || defined(__WXMOTIF__) || defined(__WXCOCOA__) || defined(__WXX11__) || defined(__WXPALMOS__) 
 302     EVT_UPDATE_UI( wxID_OK
, wxSymbolPickerDialog::OnOkUpdate 
) 
 305 #if defined(__WXMAC__) 
 306     EVT_UPDATE_UI( wxID_OK
, wxSymbolPickerDialog::OnOkUpdate 
) 
 309 ////@end wxSymbolPickerDialog event table entries 
 314  * wxSymbolPickerDialog constructors 
 317 wxSymbolPickerDialog::wxSymbolPickerDialog( ) 
 322 wxSymbolPickerDialog::wxSymbolPickerDialog( const wxString
& symbol
, const wxString
& fontName
, const wxString
& normalTextFont
, wxWindow
* parent
, wxWindowID id
, const wxString
& caption
, const wxPoint
& pos
, const wxSize
& size
, long style 
) 
 325     Create(symbol
, fontName
, normalTextFont
, parent
, id
, caption
, pos
, size
, style
); 
 329  * wxSymbolPickerDialog creator 
 332 bool wxSymbolPickerDialog::Create( const wxString
& symbol
, const wxString
& fontName
, const wxString
& normalTextFont
, wxWindow
* parent
, wxWindowID id
, const wxString
& caption
, const wxPoint
& pos
, const wxSize
& size
, long style 
) 
 334     m_fontName 
= fontName
; 
 335     m_normalTextFontName 
= normalTextFont
; 
 338 ////@begin wxSymbolPickerDialog creation 
 339     SetExtraStyle(GetExtraStyle()|wxWS_EX_BLOCK_EVENTS
|wxDIALOG_EX_CONTEXTHELP
); 
 340     wxDialog::Create( parent
, id
, caption
, pos
, size
, style 
); 
 345         GetSizer()->SetSizeHints(this); 
 348 ////@end wxSymbolPickerDialog creation 
 353  * Member initialisation for wxSymbolPickerDialog 
 356 void wxSymbolPickerDialog::Init() 
 358 ////@begin wxSymbolPickerDialog member initialisation 
 359     m_fromUnicode 
= true; 
 361 #if defined(__UNICODE__) 
 364     m_symbolsCtrl 
= NULL
; 
 365     m_symbolStaticCtrl 
= NULL
; 
 366     m_characterCodeCtrl 
= NULL
; 
 367 #if defined(__UNICODE__) 
 368     m_fromUnicodeCtrl 
= NULL
; 
 370 ////@end wxSymbolPickerDialog member initialisation 
 371     m_dontUpdate 
= false; 
 375  * Control creation for wxSymbolPickerDialog 
 378 void wxSymbolPickerDialog::CreateControls() 
 380 ////@begin wxSymbolPickerDialog content construction 
 381     wxSymbolPickerDialog
* itemDialog1 
= this; 
 383     wxBoxSizer
* itemBoxSizer2 
= new wxBoxSizer(wxVERTICAL
); 
 384     itemDialog1
->SetSizer(itemBoxSizer2
); 
 386     wxBoxSizer
* itemBoxSizer3 
= new wxBoxSizer(wxVERTICAL
); 
 387     itemBoxSizer2
->Add(itemBoxSizer3
, 1, wxGROW
|wxALL
, 5); 
 389     wxBoxSizer
* itemBoxSizer4 
= new wxBoxSizer(wxHORIZONTAL
); 
 390     itemBoxSizer3
->Add(itemBoxSizer4
, 0, wxGROW
, 5); 
 392     wxBoxSizer
* itemBoxSizer5 
= new wxBoxSizer(wxHORIZONTAL
); 
 393     itemBoxSizer4
->Add(itemBoxSizer5
, 1, wxGROW
, 5); 
 395     wxStaticText
* itemStaticText6 
= new wxStaticText( itemDialog1
, wxID_STATIC
, _("&Font:"), wxDefaultPosition
, wxDefaultSize
, 0 ); 
 396     itemBoxSizer5
->Add(itemStaticText6
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
|wxADJUST_MINSIZE
, 5); 
 398     wxString
* m_fontCtrlStrings 
= NULL
; 
 399     m_fontCtrl 
= new wxComboBox( itemDialog1
, 
 400                                  ID_SYMBOLPICKERDIALOG_FONT
, 
 403                                  wxSize(240, wxDefaultCoord
), 
 407     itemBoxSizer5
->Add(m_fontCtrl
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5); 
 409     itemBoxSizer5
->Add(5, 5, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5); 
 411 #if defined(__UNICODE__) 
 412     wxStaticText
* itemStaticText9 
= new wxStaticText( itemDialog1
, wxID_STATIC
, _("&Subset:"), wxDefaultPosition
, wxDefaultSize
, 0 ); 
 413     itemBoxSizer5
->Add(itemStaticText9
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
|wxADJUST_MINSIZE
, 5); 
 417 #if defined(__UNICODE__) 
 418     wxString
* m_subsetCtrlStrings 
= NULL
; 
 419     m_subsetCtrl 
= new wxComboBox( itemDialog1
, 
 420                                    ID_SYMBOLPICKERDIALOG_SUBSET
, 
 427     m_subsetCtrl
->SetHelpText(_("Shows a Unicode subset.")); 
 429         m_subsetCtrl
->SetToolTip(_("Shows a Unicode subset.")); 
 430     itemBoxSizer5
->Add(m_subsetCtrl
, 1, wxALIGN_CENTER_VERTICAL
|wxALL
, 5); 
 434     m_symbolsCtrl 
= new wxSymbolListCtrl( itemDialog1
, ID_SYMBOLPICKERDIALOG_LISTCTRL
, wxDefaultPosition
, wxSize(500, 240), wxSIMPLE_BORDER 
); 
 435     itemBoxSizer3
->Add(m_symbolsCtrl
, 1, wxGROW
|wxALL
, 5); 
 437     wxBoxSizer
* itemBoxSizer12 
= new wxBoxSizer(wxHORIZONTAL
); 
 438     itemBoxSizer3
->Add(itemBoxSizer12
, 0, wxGROW
, 5); 
 440     m_symbolStaticCtrl 
= new wxStaticText( itemDialog1
, wxID_STATIC
, _("xxxx"), wxDefaultPosition
, wxSize(40, wxDefaultCoord
), wxALIGN_CENTRE 
); 
 441     itemBoxSizer12
->Add(m_symbolStaticCtrl
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
|wxADJUST_MINSIZE
, 5); 
 443     itemBoxSizer12
->Add(5, 5, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5); 
 445     wxStaticText
* itemStaticText15 
= new wxStaticText( itemDialog1
, wxID_STATIC
, _("&Character code:"), wxDefaultPosition
, wxDefaultSize
, 0 ); 
 446     itemBoxSizer12
->Add(itemStaticText15
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
|wxADJUST_MINSIZE
, 5); 
 448     m_characterCodeCtrl 
= new wxTextCtrl( itemDialog1
, 
 449                                           ID_SYMBOLPICKERDIALOG_CHARACTERCODE
, 
 452                                           wxSize(140, wxDefaultCoord
), 
 453                                           wxTE_READONLY
|wxTE_CENTRE 
); 
 454     itemBoxSizer12
->Add(m_characterCodeCtrl
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5); 
 456     itemBoxSizer12
->Add(5, 5, 1, wxALIGN_CENTER_VERTICAL
|wxALL
, 5); 
 458 #if defined(__UNICODE__) 
 459     wxStaticText
* itemStaticText18 
= new wxStaticText( itemDialog1
, wxID_STATIC
, _("&From:"), wxDefaultPosition
, wxDefaultSize
, 0 ); 
 460     itemBoxSizer12
->Add(itemStaticText18
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
|wxADJUST_MINSIZE
, 5); 
 464 #if defined(__UNICODE__) 
 465     wxString m_fromUnicodeCtrlStrings
[] = { 
 469     m_fromUnicodeCtrl 
= new wxComboBox( itemDialog1
, ID_SYMBOLPICKERDIALOG_FROM
, _("ASCII"), wxDefaultPosition
, wxDefaultSize
, 2, m_fromUnicodeCtrlStrings
, wxCB_READONLY 
); 
 470     m_fromUnicodeCtrl
->SetStringSelection(_("ASCII")); 
 471     itemBoxSizer12
->Add(m_fromUnicodeCtrl
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5); 
 475 #if defined(__WXMSW__) || defined(__WXGTK__) || defined(__WXOS2__) || defined(__WXMGL__) || defined(__WXMOTIF__) || defined(__WXCOCOA__) || defined(__WXX11__) || defined(__WXPALMOS__) 
 476     wxBoxSizer
* itemBoxSizer20 
= new wxBoxSizer(wxHORIZONTAL
); 
 477     itemBoxSizer3
->Add(itemBoxSizer20
, 0, wxGROW
, 5); 
 479     itemBoxSizer20
->Add(5, 5, 1, wxALIGN_CENTER_VERTICAL
|wxALL
, 5); 
 481     wxButton
* itemButton22 
= new wxButton( itemDialog1
, wxID_OK
, _("Insert"), wxDefaultPosition
, wxDefaultSize
, 0 ); 
 482     itemButton22
->SetDefault(); 
 483     itemButton22
->SetHelpText(_("Inserts the chosen symbol.")); 
 485         itemButton22
->SetToolTip(_("Inserts the chosen symbol.")); 
 486     itemBoxSizer20
->Add(itemButton22
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5); 
 488     wxButton
* itemButton23 
= new wxButton( itemDialog1
, wxID_CANCEL
, _("Close"), wxDefaultPosition
, wxDefaultSize
, 0 ); 
 489     itemButton23
->SetHelpText(_("Closes the dialog without inserting a symbol.")); 
 491         itemButton23
->SetToolTip(_("Closes the dialog without inserting a symbol.")); 
 492     itemBoxSizer20
->Add(itemButton23
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5); 
 496 #if defined(__WXMAC__) 
 497     wxBoxSizer
* itemBoxSizer24 
= new wxBoxSizer(wxHORIZONTAL
); 
 498     itemBoxSizer3
->Add(itemBoxSizer24
, 0, wxGROW
, 5); 
 500     itemBoxSizer24
->Add(5, 5, 1, wxALIGN_CENTER_VERTICAL
|wxALL
, 5); 
 502     wxButton
* itemButton26 
= new wxButton( itemDialog1
, wxID_CANCEL
, _("Close"), wxDefaultPosition
, wxDefaultSize
, 0 ); 
 503     itemButton26
->SetHelpText(_("Closes the dialog without inserting a symbol.")); 
 505         itemButton26
->SetToolTip(_("Closes the dialog without inserting a symbol.")); 
 506     itemBoxSizer24
->Add(itemButton26
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5); 
 508     wxButton
* itemButton27 
= new wxButton( itemDialog1
, wxID_OK
, _("Insert"), wxDefaultPosition
, wxDefaultSize
, 0 ); 
 509     itemButton27
->SetDefault(); 
 510     itemButton27
->SetHelpText(_("Inserts the chosen symbol.")); 
 512         itemButton27
->SetToolTip(_("Inserts the chosen symbol.")); 
 513     itemBoxSizer24
->Add(itemButton27
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5); 
 517 ////@end wxSymbolPickerDialog content construction 
 522 bool wxSymbolPickerDialog::TransferDataToWindow() 
 526     if (m_fontCtrl
->GetCount() == 0) 
 528         wxArrayString faceNames 
= wxFontEnumerator::GetFacenames(); 
 531         faceNames
.Insert(_("(Normal text)"), 0); 
 532         m_fontCtrl
->Append(faceNames
); 
 535     if (m_fontName
.empty()) 
 536         m_fontCtrl
->SetSelection(0); 
 539         if (m_fontCtrl
->FindString(m_fontName
) != wxNOT_FOUND
) 
 540             m_fontCtrl
->SetStringSelection(m_fontName
); 
 542             m_fontCtrl
->SetSelection(0); 
 545     if (!m_symbol
.empty()) 
 547         int sel 
= (int) m_symbol
[0]; 
 548         m_symbolsCtrl
->SetSelection(sel
); 
 551 #if defined(__UNICODE__) 
 552     if (m_subsetCtrl
->GetCount() == 0) 
 554         // Insert items into subset combo 
 556         for (i 
= 0; i 
< (int) (sizeof(g_UnicodeSubsetTable
)/sizeof(g_UnicodeSubsetTable
[0])); i
++) 
 558             m_subsetCtrl
->Append(g_UnicodeSubsetTable
[i
].m_name
); 
 560         m_subsetCtrl
->SetSelection(0); 
 564     UpdateSymbolDisplay(); 
 566     m_dontUpdate 
= false; 
 571 void wxSymbolPickerDialog::UpdateSymbolDisplay(bool updateSymbolList
, bool showAtSubset
) 
 574     wxString fontNameToUse
; 
 575     if (m_fontName
.empty()) 
 576         fontNameToUse 
= m_normalTextFontName
; 
 578         fontNameToUse 
= m_fontName
; 
 580     if (!fontNameToUse
.empty()) 
 582         font 
= wxFont(14, wxDEFAULT
, wxNORMAL
, wxNORMAL
, false, fontNameToUse
); 
 585         font 
= *wxNORMAL_FONT
; 
 587     if (updateSymbolList
) 
 589         m_symbolsCtrl
->SetFont(font
); 
 592     if (!m_symbol
.empty()) 
 594         m_symbolStaticCtrl
->SetFont(font
); 
 595         m_symbolStaticCtrl
->SetLabel(m_symbol
); 
 597         int symbol 
= (int) m_symbol
[0]; 
 598         m_characterCodeCtrl
->SetValue(wxString::Format(wxT("%X hex (%d dec)"), symbol
, symbol
)); 
 602         m_symbolStaticCtrl
->SetLabel(wxEmptyString
); 
 603         m_characterCodeCtrl
->SetValue(wxEmptyString
); 
 606 #if defined(__UNICODE__) 
 610     wxUnusedVar(showAtSubset
); 
 614 /// Show at the current subset selection 
 615 void wxSymbolPickerDialog::ShowAtSubset() 
 617 #if defined(__UNICODE__) 
 620         int sel 
= m_subsetCtrl
->GetSelection(); 
 621         int low 
= g_UnicodeSubsetTable
[sel
].m_low
; 
 622         m_symbolsCtrl
->EnsureVisible(low
); 
 627 // Handle font selection 
 628 void wxSymbolPickerDialog::OnFontCtrlSelected( wxCommandEvent
& WXUNUSED(event
) ) 
 630     if (m_fontCtrl
->GetSelection() == 0) 
 631         m_fontName 
= wxEmptyString
; 
 633         m_fontName 
= m_fontCtrl
->GetStringSelection(); 
 635     UpdateSymbolDisplay(); 
 638 /// Respond to symbol selection 
 639 void wxSymbolPickerDialog::OnSymbolSelected( wxCommandEvent
& event 
) 
 644     int sel 
= event
.GetSelection(); 
 645     if (sel 
== wxNOT_FOUND
) 
 646         m_symbol 
= wxEmptyString
; 
 649         m_symbol 
= wxEmptyString
; 
 650         m_symbol 
<< (wxChar
) sel
; 
 653 #if defined(__UNICODE__) 
 654     if (sel 
!= -1 && m_fromUnicode
) 
 656         // Need to make the subset selection reflect the current symbol 
 658         for (i 
= 0; i 
< (int) (sizeof(g_UnicodeSubsetTable
)/sizeof(g_UnicodeSubsetTable
[0])); i
++) 
 660             if (sel 
>= g_UnicodeSubsetTable
[i
].m_low 
&& sel 
<= g_UnicodeSubsetTable
[i
].m_high
) 
 663                 m_subsetCtrl
->SetSelection(i
); 
 664                 m_dontUpdate 
= false; 
 671     UpdateSymbolDisplay(false, false); 
 674 #if defined(__UNICODE__) 
 675 // Handle Unicode/ASCII selection 
 676 void wxSymbolPickerDialog::OnFromUnicodeSelected( wxCommandEvent
& WXUNUSED(event
) ) 
 681     m_fromUnicode 
= (m_fromUnicodeCtrl
->GetSelection() == 1); 
 682     m_symbolsCtrl
->SetUnicodeMode(m_fromUnicode
); 
 683     UpdateSymbolDisplay(false); 
 686 // Handle subset selection 
 687 void wxSymbolPickerDialog::OnSubsetSelected( wxCommandEvent
& WXUNUSED(event
) ) 
 697  * wxEVT_UPDATE_UI event handler for wxID_OK 
 700 void wxSymbolPickerDialog::OnOkUpdate( wxUpdateUIEvent
& event 
) 
 702     event
.Enable(HasSelection()); 
 706 void wxSymbolPickerDialog::SetUnicodeMode(bool unicodeMode
) 
 708 #if defined(__UNICODE__) 
 710     m_fromUnicode 
= unicodeMode
; 
 711     if (m_fromUnicodeCtrl
) 
 712         m_fromUnicodeCtrl
->SetSelection(m_fromUnicode 
? 1 : 0); 
 713     UpdateSymbolDisplay(); 
 714     m_dontUpdate 
= false; 
 716     wxUnusedVar(unicodeMode
); 
 720 /// Get the selected symbol character 
 721 int wxSymbolPickerDialog::GetSymbolChar() const 
 723     if (m_symbol
.empty()) 
 726         return (int) m_symbol
[0]; 
 731  * Should we show tooltips? 
 734 bool wxSymbolPickerDialog::ShowToolTips() 
 740  * Get bitmap resources 
 743 wxBitmap 
wxSymbolPickerDialog::GetBitmapResource( const wxString
& name 
) 
 746 ////@begin wxSymbolPickerDialog bitmap retrieval 
 749 ////@end wxSymbolPickerDialog bitmap retrieval 
 756 wxIcon 
wxSymbolPickerDialog::GetIconResource( const wxString
& name 
) 
 759 ////@begin wxSymbolPickerDialog icon retrieval 
 762 ////@end wxSymbolPickerDialog icon retrieval 
 766  * The scrolling symbol list. 
 769 // ---------------------------------------------------------------------------- 
 771 // ---------------------------------------------------------------------------- 
 773 BEGIN_EVENT_TABLE(wxSymbolListCtrl
, wxVScrolledWindow
) 
 774     EVT_PAINT(wxSymbolListCtrl::OnPaint
) 
 775     EVT_SIZE(wxSymbolListCtrl::OnSize
) 
 777     EVT_KEY_DOWN(wxSymbolListCtrl::OnKeyDown
) 
 778     EVT_LEFT_DOWN(wxSymbolListCtrl::OnLeftDown
) 
 779     EVT_LEFT_DCLICK(wxSymbolListCtrl::OnLeftDClick
) 
 782 // ============================================================================ 
 784 // ============================================================================ 
 786 IMPLEMENT_ABSTRACT_CLASS(wxSymbolListCtrl
, wxVScrolledWindow
) 
 788 // ---------------------------------------------------------------------------- 
 789 // wxSymbolListCtrl creation 
 790 // ---------------------------------------------------------------------------- 
 792 void wxSymbolListCtrl::Init() 
 794     m_current 
= wxNOT_FOUND
; 
 795     m_doubleBuffer 
= NULL
; 
 796     m_cellSize 
= wxSize(40, 40); 
 797     m_minSymbolValue 
= 0; 
 798     m_maxSymbolValue 
= 255; 
 799     m_symbolsPerLine 
= 0; 
 800     m_unicodeMode 
= false; 
 803 bool wxSymbolListCtrl::Create(wxWindow 
*parent
, 
 808                         const wxString
& name
) 
 810     style 
|= wxWANTS_CHARS 
| wxFULL_REPAINT_ON_RESIZE
; 
 811     if ( !wxVScrolledWindow::Create(parent
, id
, pos
, size
, style
, name
) ) 
 814     // make sure the native widget has the right colour since we do 
 815     // transparent drawing by default 
 816     SetBackgroundColour(GetBackgroundColour()); 
 817     m_colBgSel 
= wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT
); 
 819     // flicker-free drawing requires this 
 820     SetBackgroundStyle(wxBG_STYLE_CUSTOM
); 
 822     SetFont(*wxNORMAL_FONT
); 
 829 wxSymbolListCtrl::~wxSymbolListCtrl() 
 831     delete m_doubleBuffer
; 
 834 // ---------------------------------------------------------------------------- 
 835 // selection handling 
 836 // ---------------------------------------------------------------------------- 
 838 bool wxSymbolListCtrl::IsSelected(int item
) const 
 840     return item 
== m_current
; 
 843 bool wxSymbolListCtrl::DoSetCurrent(int current
) 
 845     wxASSERT_MSG( current 
== wxNOT_FOUND 
|| 
 846                     (current 
>= m_minSymbolValue 
&& current 
<= m_maxSymbolValue
), 
 847                   _T("wxSymbolListCtrl::DoSetCurrent(): invalid symbol value") ); 
 849     if ( current 
== m_current 
) 
 855     if ( m_current 
!= wxNOT_FOUND 
) 
 856         RefreshLine(SymbolValueToLineNumber(m_current
)); 
 860     if ( m_current 
!= wxNOT_FOUND 
) 
 862         int lineNo 
= SymbolValueToLineNumber(m_current
); 
 864         // if the line is not visible at all, we scroll it into view but we 
 865         // don't need to refresh it -- it will be redrawn anyhow 
 866         if ( !IsVisible(lineNo
) ) 
 868             ScrollToLine(lineNo
); 
 870         else // line is at least partly visible 
 872             // it is, indeed, only partly visible, so scroll it into view to 
 873             // make it entirely visible 
 874             while ( unsigned(lineNo
) == GetLastVisibleLine() && 
 875                     ScrollToLine(GetVisibleBegin()+1) ) 
 878             // but in any case refresh it as even if it was only partly visible 
 879             // before we need to redraw it entirely as its background changed 
 887 void wxSymbolListCtrl::SendSelectedEvent() 
 889     wxCommandEvent 
event(wxEVT_COMMAND_LISTBOX_SELECTED
, GetId()); 
 890     event
.SetEventObject(this); 
 891     event
.SetInt(m_current
); 
 893     (void)GetEventHandler()->ProcessEvent(event
); 
 896 void wxSymbolListCtrl::SetSelection(int selection
) 
 898     wxCHECK_RET( selection 
== wxNOT_FOUND 
|| 
 899                   (selection 
>= m_minSymbolValue 
&& selection 
< m_maxSymbolValue
), 
 900                   _T("wxSymbolListCtrl::SetSelection(): invalid symbol value") ); 
 902     DoSetCurrent(selection
); 
 905 // ---------------------------------------------------------------------------- 
 906 // wxSymbolListCtrl appearance parameters 
 907 // ---------------------------------------------------------------------------- 
 909 void wxSymbolListCtrl::SetMargins(const wxPoint
& pt
) 
 911     if ( pt 
!= m_ptMargins 
) 
 919 void wxSymbolListCtrl::SetSelectionBackground(const wxColour
& col
) 
 924 // ---------------------------------------------------------------------------- 
 925 // wxSymbolListCtrl painting 
 926 // ---------------------------------------------------------------------------- 
 928 wxCoord 
wxSymbolListCtrl::OnGetLineHeight(size_t WXUNUSED(line
)) const 
 930     return m_cellSize
.y 
+ 2*m_ptMargins
.y 
+ 1 /* for divider */ ; 
 933 // draws a line of symbols 
 934 void wxSymbolListCtrl::OnDrawItem(wxDC
& dc
, const wxRect
& rect
, size_t n
) const 
 936     wxColour oldTextColour 
= dc
.GetTextForeground(); 
 937     int startSymbol 
= n
*m_symbolsPerLine
; 
 940     for (i 
= 0; i 
< m_symbolsPerLine
; i
++) 
 942         bool resetColour 
= false; 
 943         int symbol 
= startSymbol
+i
; 
 944         if (symbol 
== m_current
) 
 946             dc
.SetBrush(wxBrush(m_colBgSel
)); 
 948             dc
.SetTextForeground(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT
)); 
 951             wxPen oldPen 
= dc
.GetPen(); 
 952             dc
.SetPen(*wxTRANSPARENT_PEN
); 
 954             dc
.DrawRectangle(rect
.x 
+ i
*m_cellSize
.x
, rect
.y
, m_cellSize
.x
, rect
.y
+rect
.height
); 
 958         // Don't draw first line 
 960             dc
.DrawLine(rect
.x 
+ i
*m_cellSize
.x
, rect
.y
, i
*m_cellSize
.x
, rect
.y
+rect
.height
); 
 962         if (symbol 
>= m_minSymbolValue 
&& symbol 
<= m_maxSymbolValue
) 
 965             text 
<< (wxChar
) symbol
; 
 968             dc
.GetTextExtent(text
, & w
, & h
); 
 970             int x 
= rect
.x 
+ i
*m_cellSize
.x 
+ (m_cellSize
.x 
- w
)/2; 
 971             int y 
= rect
.y 
+ (m_cellSize
.y 
- h
)/2; 
 972             dc
.DrawText(text
, x
, y
); 
 976             dc
.SetTextForeground(oldTextColour
); 
 979     // Draw horizontal separator line 
 980     dc
.DrawLine(rect
.x
, rect
.y
+rect
.height
-1, rect
.x
+rect
.width
, rect
.y
+rect
.height
-1); 
 983 void wxSymbolListCtrl::OnPaint(wxPaintEvent
& WXUNUSED(event
)) 
 985     // If size is larger, recalculate double buffer bitmap 
 986     wxSize clientSize 
= GetClientSize(); 
 988     if ( !m_doubleBuffer 
|| 
 989          clientSize
.x 
> m_doubleBuffer
->GetWidth() || 
 990          clientSize
.y 
> m_doubleBuffer
->GetHeight() ) 
 992         delete m_doubleBuffer
; 
 993         m_doubleBuffer 
= new wxBitmap(clientSize
.x
+25,clientSize
.y
+25); 
 996     wxBufferedPaintDC 
dc(this,*m_doubleBuffer
); 
 998     // the update rectangle 
 999     wxRect rectUpdate 
= GetUpdateClientRect(); 
1001     // fill it with background colour 
1002     dc
.SetBackground(GetBackgroundColour()); 
1005     // set the font to be displayed 
1006     dc
.SetFont(GetFont()); 
1008     // the bounding rectangle of the current line 
1010     rectLine
.width 
= clientSize
.x
; 
1012     dc
.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT
))); 
1013     dc
.SetTextForeground(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT
)); 
1014     dc
.SetBackgroundMode(wxTRANSPARENT
); 
1016     // iterate over all visible lines 
1017     const size_t lineMax 
= GetVisibleEnd(); 
1018     for ( size_t line 
= GetFirstVisibleLine(); line 
< lineMax
; line
++ ) 
1020         const wxCoord hLine 
= OnGetLineHeight(line
); 
1022         rectLine
.height 
= hLine
; 
1024         // and draw the ones which intersect the update rect 
1025         if ( rectLine
.Intersects(rectUpdate
) ) 
1027             // don't allow drawing outside of the lines rectangle 
1028             wxDCClipper 
clip(dc
, rectLine
); 
1030             wxRect rect 
= rectLine
; 
1031             rect
.Deflate(m_ptMargins
.x
, m_ptMargins
.y
); 
1032             OnDrawItem(dc
, rect
, line
); 
1034         else // no intersection 
1036             if ( rectLine
.GetTop() > rectUpdate
.GetBottom() ) 
1038                 // we are already below the update rect, no need to continue 
1042             //else: the next line may intersect the update rect 
1045         rectLine
.y 
+= hLine
; 
1049 // ============================================================================ 
1050 // wxSymbolListCtrl keyboard/mouse handling 
1051 // ============================================================================ 
1053 void wxSymbolListCtrl::DoHandleItemClick(int item
, int WXUNUSED(flags
)) 
1055     if (m_current 
!= item
) 
1059         SendSelectedEvent(); 
1063 // ---------------------------------------------------------------------------- 
1064 // keyboard handling 
1065 // ---------------------------------------------------------------------------- 
1067 void wxSymbolListCtrl::OnKeyDown(wxKeyEvent
& event
) 
1069     // No keyboard interface for now 
1072     // flags for DoHandleItemClick() 
1073     int flags 
= ItemClick_Kbd
; 
1075     int currentLineNow 
= SymbolValueToLineNumber(m_current
); 
1078     switch ( event
.GetKeyCode() ) 
1085             currentLine 
= GetLineCount() - 1; 
1089             if ( currentLineNow 
== (int)GetLineCount() - 1 ) 
1092             currentLine 
= currentLineNow 
+ 1; 
1096             if ( m_current 
== wxNOT_FOUND 
) 
1097                 currentLine 
= GetLineCount() - 1; 
1098             else if ( currentLineNow 
!= 0 ) 
1099                 currentLine 
= currentLineNow 
- 1; 
1100             else // currentLineNow == 0 
1106             currentLine 
= GetFirstVisibleLine(); 
1110             if ( currentLineNow 
== (int)GetFirstVisibleLine() ) 
1115             currentLine 
= GetFirstVisibleLine(); 
1119             // hack: pressing space should work like a mouse click rather than 
1120             // like a keyboard arrow press, so trick DoHandleItemClick() in 
1121             // thinking we were clicked 
1122             flags 
&= ~ItemClick_Kbd
; 
1123             currentLine 
= currentLineNow
; 
1128             // Since we are using wxWANTS_CHARS we need to send navigation 
1129             // events for the tabs on MSW 
1131                 wxNavigationKeyEvent ne
; 
1132                 ne
.SetDirection(!event
.ShiftDown()); 
1133                 ne
.SetCurrentFocus(this); 
1134                 ne
.SetEventObject(this); 
1135                 GetParent()->GetEventHandler()->ProcessEvent(ne
); 
1137             // fall through to default 
1141             currentLine 
= 0; // just to silent the stupid compiler warnings 
1142             wxUnusedVar(currentNow
); 
1147     if ( event
.ShiftDown() ) 
1148        flags 
|= ItemClick_Shift
; 
1149     if ( event
.ControlDown() ) 
1150         flags 
|= ItemClick_Ctrl
; 
1152     DoHandleItemClick(current
, flags
); 
1157 // ---------------------------------------------------------------------------- 
1158 // wxSymbolListCtrl mouse handling 
1159 // ---------------------------------------------------------------------------- 
1161 void wxSymbolListCtrl::OnLeftDown(wxMouseEvent
& event
) 
1165     int item 
= HitTest(event
.GetPosition()); 
1167     if ( item 
!= wxNOT_FOUND 
) 
1170         if ( event
.ShiftDown() ) 
1171            flags 
|= ItemClick_Shift
; 
1173         // under Mac Apple-click is used in the same way as Ctrl-click 
1176         if ( event
.MetaDown() ) 
1178         if ( event
.ControlDown() ) 
1180             flags 
|= ItemClick_Ctrl
; 
1182         DoHandleItemClick(item
, flags
); 
1186 void wxSymbolListCtrl::OnLeftDClick(wxMouseEvent
& eventMouse
) 
1188     int item 
= HitTest(eventMouse
.GetPosition()); 
1189     if ( item 
!= wxNOT_FOUND 
) 
1192         // if item double-clicked was not yet selected, then treat 
1193         // this event as a left-click instead 
1194         if ( item 
== m_current 
) 
1196             wxCommandEvent 
event(wxEVT_COMMAND_LISTBOX_DOUBLECLICKED
, GetId()); 
1197             event
.SetEventObject(this); 
1200             (void)GetEventHandler()->ProcessEvent(event
); 
1204             OnLeftDown(eventMouse
); 
1210 // calculate line number from symbol value 
1211 int wxSymbolListCtrl::SymbolValueToLineNumber(int item
) 
1213     return (int) (item
/m_symbolsPerLine
); 
1216 // initialise control from current min/max values 
1217 void wxSymbolListCtrl::SetupCtrl(bool scrollToSelection
) 
1219     wxSize sz 
= GetClientSize(); 
1221     m_symbolsPerLine 
= sz
.x
/(m_cellSize
.x
+m_ptMargins
.x
); 
1222     int noLines 
= (1 + SymbolValueToLineNumber(m_maxSymbolValue
)); 
1224     SetLineCount(noLines
); 
1227     if (scrollToSelection 
&& m_current 
!= wxNOT_FOUND 
&& m_current 
>= m_minSymbolValue 
&& m_current 
<= m_maxSymbolValue
) 
1229         ScrollToLine(SymbolValueToLineNumber(m_current
)); 
1233 // make this item visible 
1234 void wxSymbolListCtrl::EnsureVisible(int item
) 
1236     if (item 
!= wxNOT_FOUND 
&& item 
>= m_minSymbolValue 
&& item 
<= m_maxSymbolValue
) 
1238         ScrollToLine(SymbolValueToLineNumber(item
)); 
1244 int wxSymbolListCtrl::HitTest(const wxPoint
& pt
) 
1246     wxCoord lineHeight 
= OnGetLineHeight(0); 
1248     int atLine 
= GetVisibleBegin() + (pt
.y
/lineHeight
); 
1249     int symbol 
= (atLine
*m_symbolsPerLine
) + (pt
.x
/(m_cellSize
.x
+1)); 
1251     if (symbol 
>= m_minSymbolValue 
&& symbol 
<= m_maxSymbolValue
) 
1257 // Respond to size change 
1258 void wxSymbolListCtrl::OnSize(wxSizeEvent
& event
) 
1264 // set the current font 
1265 bool wxSymbolListCtrl::SetFont(const wxFont
& font
) 
1267     wxVScrolledWindow::SetFont(font
); 
1274 // set Unicode/ASCII mode 
1275 void wxSymbolListCtrl::SetUnicodeMode(bool unicodeMode
) 
1277     bool changed 
= false; 
1278     if (unicodeMode 
&& !m_unicodeMode
) 
1282         m_minSymbolValue 
= 0; 
1283         m_maxSymbolValue 
= 65535; 
1285     else if (!unicodeMode 
&& m_unicodeMode
) 
1288         m_minSymbolValue 
= 0; 
1289         m_maxSymbolValue 
= 255; 
1291     m_unicodeMode 
= unicodeMode
; 
1297 // ---------------------------------------------------------------------------- 
1298 // use the same default attributes as wxListBox 
1299 // ---------------------------------------------------------------------------- 
1303 wxSymbolListCtrl::GetClassDefaultAttributes(wxWindowVariant variant
) 
1305     return wxListBox::GetClassDefaultAttributes(variant
); 
1308 #endif // wxUSE_RICHTEXT