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/dcbuffer.h" 
  35 // Only for cached font name 
  36 #include "wx/richtext/richtextctrl.h" 
  38 /* Microsoft Unicode subset numbering 
  44   U_LATIN_1_SUPPLEMENT 
= 1, 
  45   U_LATIN_EXTENDED_A 
= 2, 
  46   U_LATIN_EXTENDED_B 
= 3, 
  48   U_SPACING_MODIFIER_LETTERS 
= 5, 
  49   U_COMBINING_DIACRITICAL_MARKS 
= 6, 
  51   U_GREEK_SYMBOLS_AND_COPTIC 
= 8, 
  54   U_HEBREW_EXTENDED 
= 12, 
  57   U_ARABIC_EXTENDED 
= 14, 
  69   U_GEORGIAN_EXTENDED 
= 27, 
  70   U_BASIC_GEORGIAN 
= 26, 
  72   U_LATIN_EXTENDED_ADDITIONAL 
= 29, 
  73   U_GREEK_EXTENDED 
= 30, 
  74   U_GENERAL_PUNCTUATION 
= 31, 
  75   U_SUPERSCRIPTS_AND_SUBSCRIPTS 
= 32, 
  76   U_CURRENCY_SYMBOLS 
= 33, 
  77   U_COMBINING_DIACRITICAL_MARKS_FOR_SYMBOLS 
= 34, 
  78   U_LETTERLIKE_SYMBOLS 
= 35, 
  81   U_MATHEMATICAL_OPERATORS 
= 38, 
  82   U_MISCELLANEOUS_TECHNICAL 
= 39, 
  83   U_CONTROL_PICTURES 
= 40, 
  84   U_OPTICAL_CHARACTER_RECOGNITION 
= 41, 
  85   U_ENCLOSED_ALPHANUMERICS 
= 42, 
  87   U_BLOCK_ELEMENTS 
= 44, 
  88   U_GEOMETRIC_SHAPES 
= 45, 
  89   U_MISCELLANEOUS_SYMBOLS 
= 46, 
  91   U_CJK_SYMBOLS_AND_PUNCTUATION 
= 48, 
  95   U_HANGUL_COMPATIBILITY_JAMO 
= 52, 
  96   U_CJK_MISCELLANEOUS 
= 53, 
  98   U_CJK_COMPATIBILITY 
= 55, 
 100   U_HANGUL_SUPPLEMENTARY_A 
= 57, 
 101   U_HANGUL_SUPPLEMENTARY_B 
= 58, 
 102   U_CJK_UNIFIED_IDEOGRAPHS 
= 59, 
 103   U_PRIVATE_USE_AREA 
= 60, 
 104   U_CJK_COMPATIBILITY_IDEOGRAPHS 
= 61, 
 105   U_ALPHABETIC_PRESENTATION_FORMS 
= 62, 
 106   U_ARABIC_PRESENTATION_FORMS_A 
= 63, 
 107   U_COMBINING_HALF_MARKS 
= 64, 
 108   U_CJK_COMPATIBILITY_FORMS 
= 65, 
 109   U_SMALL_FORM_VARIANTS 
= 66, 
 110   U_ARABIC_PRESENTATION_FORMS_B 
= 67, 
 112   U_HALFWIDTH_AND_FULLWIDTH_FORMS 
= 68, 
 114 } wxUnicodeSubsetCodes
; 
 116 /* Unicode subsets */ 
 122     wxUnicodeSubsetCodes m_subset
; 
 124 } g_UnicodeSubsetTable
[] = 
 127     U_BASIC_LATIN
, wxT("Basic Latin") }, 
 129     U_LATIN_1_SUPPLEMENT
, wxT("Latin-1 Supplement") }, 
 131     U_LATIN_EXTENDED_A
, wxT("Latin Extended-A") }, 
 133     U_LATIN_EXTENDED_B
, wxT("Latin Extended-B") }, 
 135     U_IPA_EXTENSIONS
, wxT("IPA Extensions") }, 
 137     U_SPACING_MODIFIER_LETTERS
, wxT("Spacing Modifier Letters") }, 
 139     U_COMBINING_DIACRITICAL_MARKS
, wxT("Combining Diacritical Marks") }, 
 141     U_BASIC_GREEK
, wxT("Basic Greek") }, 
 143     U_GREEK_SYMBOLS_AND_COPTIC
, wxT("Greek Symbols and Coptic") }, 
 145     U_CYRILLIC
, wxT("Cyrillic") }, 
 147     U_ARMENIAN
, wxT("Armenian") }, 
 149     U_HEBREW_EXTENDED
, wxT("Hebrew Extended") }, 
 151     U_BASIC_HEBREW
, wxT("Basic Hebrew") }, 
 153     U_BASIC_ARABIC
, wxT("Basic Arabic") }, 
 155     U_ARABIC_EXTENDED
, wxT("Arabic Extended") }, 
 157     U_DEVANAGARI
, wxT("Devanagari") }, 
 159     U_BENGALI
, wxT("Bengali") }, 
 161     U_GURMUKHI
, wxT("Gurmukhi") }, 
 163     U_GUJARATI
, wxT("Gujarati") }, 
 165     U_ORIYA
, wxT("Oriya") }, 
 167     U_TAMIL
, wxT("Tamil") }, 
 169     U_TELUGU
, wxT("Telugu") }, 
 171     U_KANNADA
, wxT("Kannada") }, 
 173     U_MALAYALAM
, wxT("Malayalam") }, 
 175     U_THAI
, wxT("Thai") }, 
 179     U_GEORGIAN_EXTENDED
, wxT("Georgian Extended") }, 
 181     U_BASIC_GEORGIAN
, wxT("Basic Georgian") }, 
 183     U_HANGUL_JAMO
, wxT("Hangul Jamo") }, 
 185     U_LATIN_EXTENDED_ADDITIONAL
, wxT("Latin Extended Additional") }, 
 187     U_GREEK_EXTENDED
, wxT("Greek Extended") }, 
 189     U_GENERAL_PUNCTUATION
, wxT("General Punctuation") }, 
 191     U_SUPERSCRIPTS_AND_SUBSCRIPTS
, wxT("Superscripts and Subscripts") }, 
 193     U_CURRENCY_SYMBOLS
, wxT("Currency Symbols") }, 
 195     U_COMBINING_DIACRITICAL_MARKS_FOR_SYMBOLS
, wxT("Combining Diacritical Marks for Symbols") }, 
 197     U_LETTERLIKE_SYMBOLS
, wxT("Letterlike Symbols") }, 
 199     U_NUMBER_FORMS
, wxT("Number Forms") }, 
 201     U_ARROWS
, wxT("Arrows") }, 
 203     U_MATHEMATICAL_OPERATORS
, wxT("Mathematical Operators") }, 
 205     U_MISCELLANEOUS_TECHNICAL
, wxT("Miscellaneous Technical") }, 
 207     U_CONTROL_PICTURES
, wxT("Control Pictures") }, 
 209     U_OPTICAL_CHARACTER_RECOGNITION
, wxT("Optical Character Recognition") }, 
 211     U_ENCLOSED_ALPHANUMERICS
, wxT("Enclosed Alphanumerics") }, 
 213     U_BOX_DRAWING
, wxT("Box Drawing") }, 
 215     U_BLOCK_ELEMENTS
, wxT("Block Elements") }, 
 217     U_GEOMETRIC_SHAPES
, wxT("Geometric Shapes") }, 
 219     U_MISCELLANEOUS_SYMBOLS
, wxT("Miscellaneous Symbols") }, 
 221     U_DINGBATS
, wxT("Dingbats") }, 
 223     U_CJK_SYMBOLS_AND_PUNCTUATION
, wxT("CJK Symbols and Punctuation") }, 
 225     U_HIRAGANA
, wxT("Hiragana") }, 
 227     U_KATAKANA
, wxT("Katakana") }, 
 229     U_BOPOMOFO
, wxT("Bopomofo") }, 
 231     U_HANGUL_COMPATIBILITY_JAMO
, wxT("Hangul Compatibility Jamo") }, 
 233     U_CJK_MISCELLANEOUS
, wxT("CJK Miscellaneous") }, 
 235     U_ENCLOSED_CJK
, wxT("Enclosed CJK") }, 
 237     U_CJK_COMPATIBILITY
, wxT("CJK Compatibility") }, 
 239     U_CJK_UNIFIED_IDEOGRAPHS
, wxT("CJK Unified Ideographs Extension A") }, 
 241     U_CJK_UNIFIED_IDEOGRAPHS
, wxT("CJK Unified Ideographs") }, 
 243     U_HANGUL
, wxT("Hangul Syllables") }, 
 245     U_PRIVATE_USE_AREA
, wxT("Private Use Area") }, 
 247     U_CJK_COMPATIBILITY_IDEOGRAPHS
, wxT("CJK Compatibility Ideographs") }, 
 249     U_ALPHABETIC_PRESENTATION_FORMS
, wxT("Alphabetic Presentation Forms") }, 
 251     U_ARABIC_PRESENTATION_FORMS_A
, wxT("Arabic Presentation Forms-A") }, 
 253     U_COMBINING_HALF_MARKS
, wxT("Combining Half Marks") }, 
 255     U_CJK_COMPATIBILITY_FORMS
, wxT("CJK Compatibility Forms") }, 
 257     U_SMALL_FORM_VARIANTS
, wxT("Small Form Variants") }, 
 259     U_ARABIC_PRESENTATION_FORMS_B
, wxT("Arabic Presentation Forms-B") }, 
 261     U_SPECIALS
, wxT("Specials") }, 
 263     U_HALFWIDTH_AND_FULLWIDTH_FORMS
, wxT("Halfwidth and Fullwidth Forms") }, 
 265     U_SPECIALS
, wxT("Specials") } 
 268 #endif // __UNICODE__ 
 271 // Not yet used, but could be used to test under Win32 whether this subset is available 
 272 // for the given font. The Win32 function is allegedly not accurate, however. 
 273 bool wxSubsetValidForFont(int subsetIndex
, FONTSIGNATURE 
*fontSig
) 
 275     return (fontSig
->fsUsb
[g_UnicodeSubsetTable
[subsetIndex
].m_subset
/32] & (1 << (g_UnicodeSubsetTable
[subsetIndex
].m_subset 
% 32))); 
 279 bool wxSymbolPickerDialog::sm_showToolTips 
= false; 
 282  * wxSymbolPickerDialog type definition 
 285 IMPLEMENT_DYNAMIC_CLASS( wxSymbolPickerDialog
, wxDialog 
) 
 288  * wxSymbolPickerDialog event table definition 
 291 BEGIN_EVENT_TABLE( wxSymbolPickerDialog
, wxDialog 
) 
 292     EVT_LISTBOX(ID_SYMBOLPICKERDIALOG_LISTCTRL
, wxSymbolPickerDialog::OnSymbolSelected
) 
 294 ////@begin wxSymbolPickerDialog event table entries 
 295     EVT_COMBOBOX( ID_SYMBOLPICKERDIALOG_FONT
, wxSymbolPickerDialog::OnFontCtrlSelected 
) 
 297 #if defined(__UNICODE__) 
 298     EVT_COMBOBOX( ID_SYMBOLPICKERDIALOG_SUBSET
, wxSymbolPickerDialog::OnSubsetSelected 
) 
 301 #if defined(__UNICODE__) 
 302     EVT_COMBOBOX( ID_SYMBOLPICKERDIALOG_FROM
, wxSymbolPickerDialog::OnFromUnicodeSelected 
) 
 305     EVT_UPDATE_UI( wxID_OK
, wxSymbolPickerDialog::OnOkUpdate 
) 
 307 ////@end wxSymbolPickerDialog event table entries 
 312  * wxSymbolPickerDialog constructors 
 315 wxSymbolPickerDialog::wxSymbolPickerDialog( ) 
 320 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 
) 
 323     Create(symbol
, fontName
, normalTextFont
, parent
, id
, caption
, pos
, size
, style
); 
 327  * wxSymbolPickerDialog creator 
 330 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 
) 
 332     m_fontName 
= fontName
; 
 333     m_normalTextFontName 
= normalTextFont
; 
 336 ////@begin wxSymbolPickerDialog creation 
 337     SetExtraStyle(GetExtraStyle()|wxWS_EX_BLOCK_EVENTS
|wxDIALOG_EX_CONTEXTHELP
); 
 338     wxDialog::Create( parent
, id
, caption
, pos
, size
, style 
); 
 343         GetSizer()->SetSizeHints(this); 
 346 ////@end wxSymbolPickerDialog creation 
 351  * Member initialisation for wxSymbolPickerDialog 
 354 void wxSymbolPickerDialog::Init() 
 356 ////@begin wxSymbolPickerDialog member initialisation 
 357     m_fromUnicode 
= true; 
 359 #if defined(__UNICODE__) 
 362     m_symbolsCtrl 
= NULL
; 
 363     m_symbolStaticCtrl 
= NULL
; 
 364     m_characterCodeCtrl 
= NULL
; 
 365 #if defined(__UNICODE__) 
 366     m_fromUnicodeCtrl 
= NULL
; 
 368 ////@end wxSymbolPickerDialog member initialisation 
 369     m_dontUpdate 
= false; 
 373  * Control creation for wxSymbolPickerDialog 
 376 void wxSymbolPickerDialog::CreateControls() 
 378 ////@begin wxSymbolPickerDialog content construction 
 379     wxSymbolPickerDialog
* itemDialog1 
= this; 
 381     wxBoxSizer
* itemBoxSizer2 
= new wxBoxSizer(wxVERTICAL
); 
 382     itemDialog1
->SetSizer(itemBoxSizer2
); 
 384     wxBoxSizer
* itemBoxSizer3 
= new wxBoxSizer(wxVERTICAL
); 
 385     itemBoxSizer2
->Add(itemBoxSizer3
, 1, wxGROW
|wxALL
, 5); 
 387     wxBoxSizer
* itemBoxSizer4 
= new wxBoxSizer(wxHORIZONTAL
); 
 388     itemBoxSizer3
->Add(itemBoxSizer4
, 0, wxGROW
, 5); 
 390     wxBoxSizer
* itemBoxSizer5 
= new wxBoxSizer(wxHORIZONTAL
); 
 391     itemBoxSizer4
->Add(itemBoxSizer5
, 1, wxGROW
, 5); 
 393     wxStaticText
* itemStaticText6 
= new wxStaticText( itemDialog1
, wxID_STATIC
, _("&Font:"), wxDefaultPosition
, wxDefaultSize
, 0 ); 
 394     itemBoxSizer5
->Add(itemStaticText6
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5); 
 396     wxString
* m_fontCtrlStrings 
= NULL
; 
 397     m_fontCtrl 
= new wxComboBox( itemDialog1
, ID_SYMBOLPICKERDIALOG_FONT
, wxEmptyString
, wxDefaultPosition
, wxSize(240, -1), 0, m_fontCtrlStrings
, wxCB_READONLY 
); 
 398     m_fontCtrl
->SetHelpText(_("The font from which to take the symbol.")); 
 400         m_fontCtrl
->SetToolTip(_("The font from which to take the symbol.")); 
 401     itemBoxSizer5
->Add(m_fontCtrl
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5); 
 403     itemBoxSizer5
->Add(5, 5, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5); 
 405 #if defined(__UNICODE__) 
 406     wxStaticText
* itemStaticText9 
= new wxStaticText( itemDialog1
, wxID_STATIC
, _("&Subset:"), wxDefaultPosition
, wxDefaultSize
, 0 ); 
 407     itemBoxSizer5
->Add(itemStaticText9
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5); 
 411 #if defined(__UNICODE__) 
 412     wxString
* m_subsetCtrlStrings 
= NULL
; 
 413     m_subsetCtrl 
= new wxComboBox( itemDialog1
, ID_SYMBOLPICKERDIALOG_SUBSET
, wxEmptyString
, wxDefaultPosition
, wxDefaultSize
, 0, m_subsetCtrlStrings
, wxCB_READONLY 
); 
 414     m_subsetCtrl
->SetHelpText(_("Shows a Unicode subset.")); 
 416         m_subsetCtrl
->SetToolTip(_("Shows a Unicode subset.")); 
 417     itemBoxSizer5
->Add(m_subsetCtrl
, 1, wxALIGN_CENTER_VERTICAL
|wxALL
, 5); 
 421     m_symbolsCtrl 
= new wxSymbolListCtrl( itemDialog1
, ID_SYMBOLPICKERDIALOG_LISTCTRL
, wxDefaultPosition
, wxSize(500, 240), wxSIMPLE_BORDER 
); 
 422     itemBoxSizer3
->Add(m_symbolsCtrl
, 1, wxGROW
|wxALL
, 5); 
 424     wxBoxSizer
* itemBoxSizer12 
= new wxBoxSizer(wxHORIZONTAL
); 
 425     itemBoxSizer3
->Add(itemBoxSizer12
, 0, wxGROW
, 5); 
 427     m_symbolStaticCtrl 
= new wxStaticText( itemDialog1
, wxID_STATIC
, _("xxxx"), wxDefaultPosition
, wxSize(40, -1), wxALIGN_CENTRE 
); 
 428     itemBoxSizer12
->Add(m_symbolStaticCtrl
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5); 
 430     itemBoxSizer12
->Add(5, 5, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5); 
 432     wxStaticText
* itemStaticText15 
= new wxStaticText( itemDialog1
, wxID_STATIC
, _("&Character code:"), wxDefaultPosition
, wxDefaultSize
, 0 ); 
 433     itemBoxSizer12
->Add(itemStaticText15
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5); 
 435     m_characterCodeCtrl 
= new wxTextCtrl( itemDialog1
, ID_SYMBOLPICKERDIALOG_CHARACTERCODE
, wxEmptyString
, wxDefaultPosition
, wxSize(140, -1), wxTE_READONLY
|wxTE_CENTRE 
); 
 436     m_characterCodeCtrl
->SetHelpText(_("The character code.")); 
 438         m_characterCodeCtrl
->SetToolTip(_("The character code.")); 
 439     itemBoxSizer12
->Add(m_characterCodeCtrl
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5); 
 441     itemBoxSizer12
->Add(5, 5, 1, wxALIGN_CENTER_VERTICAL
|wxALL
, 5); 
 443 #if defined(__UNICODE__) 
 444     wxStaticText
* itemStaticText18 
= new wxStaticText( itemDialog1
, wxID_STATIC
, _("&From:"), wxDefaultPosition
, wxDefaultSize
, 0 ); 
 445     itemBoxSizer12
->Add(itemStaticText18
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5); 
 449 #if defined(__UNICODE__) 
 450     wxString m_fromUnicodeCtrlStrings
[] = { 
 454     m_fromUnicodeCtrl 
= new wxComboBox( itemDialog1
, ID_SYMBOLPICKERDIALOG_FROM
, _("ASCII"), wxDefaultPosition
, wxDefaultSize
, 2, m_fromUnicodeCtrlStrings
, wxCB_READONLY 
); 
 455     m_fromUnicodeCtrl
->SetStringSelection(_("ASCII")); 
 456     m_fromUnicodeCtrl
->SetHelpText(_("The range to show.")); 
 458         m_fromUnicodeCtrl
->SetToolTip(_("The range to show.")); 
 459     itemBoxSizer12
->Add(m_fromUnicodeCtrl
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5); 
 463 #if defined(__WXMSW__) || defined(__WXGTK__) || defined(__WXPM__) || defined(__WXMGL__) || defined(__WXMOTIF__) || defined(__WXCOCOA__) || defined(__WXX11__) || defined(__WXPALMOS__) 
 464     wxBoxSizer
* itemBoxSizer20 
= new wxBoxSizer(wxHORIZONTAL
); 
 465     itemBoxSizer3
->Add(itemBoxSizer20
, 0, wxGROW
, 5); 
 467     itemBoxSizer20
->Add(5, 5, 1, wxALIGN_CENTER_VERTICAL
|wxALL
, 5); 
 469     wxButton
* itemButton22 
= new wxButton( itemDialog1
, wxID_OK
, _("Insert"), wxDefaultPosition
, wxDefaultSize
, 0 ); 
 470     itemButton22
->SetDefault(); 
 471     itemButton22
->SetHelpText(_("Inserts the chosen symbol.")); 
 473         itemButton22
->SetToolTip(_("Inserts the chosen symbol.")); 
 474     itemBoxSizer20
->Add(itemButton22
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5); 
 476     wxButton
* itemButton23 
= new wxButton( itemDialog1
, wxID_CANCEL
, _("Close"), wxDefaultPosition
, wxDefaultSize
, 0 ); 
 477     itemButton23
->SetHelpText(_("Closes the dialog without inserting a symbol.")); 
 479         itemButton23
->SetToolTip(_("Closes the dialog without inserting a symbol.")); 
 480     itemBoxSizer20
->Add(itemButton23
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5); 
 484 #if defined(__WXMAC__) 
 485     wxBoxSizer
* itemBoxSizer24 
= new wxBoxSizer(wxHORIZONTAL
); 
 486     itemBoxSizer3
->Add(itemBoxSizer24
, 0, wxGROW
, 5); 
 488     itemBoxSizer24
->Add(5, 5, 1, wxALIGN_CENTER_VERTICAL
|wxALL
, 5); 
 490     wxButton
* itemButton26 
= new wxButton( itemDialog1
, wxID_CANCEL
, _("Close"), wxDefaultPosition
, wxDefaultSize
, 0 ); 
 491     itemButton26
->SetHelpText(_("Closes the dialog without inserting a symbol.")); 
 493         itemButton26
->SetToolTip(_("Closes the dialog without inserting a symbol.")); 
 494     itemBoxSizer24
->Add(itemButton26
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5); 
 496     wxButton
* itemButton27 
= new wxButton( itemDialog1
, wxID_OK
, _("Insert"), wxDefaultPosition
, wxDefaultSize
, 0 ); 
 497     itemButton27
->SetDefault(); 
 498     itemButton27
->SetHelpText(_("Inserts the chosen symbol.")); 
 500         itemButton27
->SetToolTip(_("Inserts the chosen symbol.")); 
 501     itemBoxSizer24
->Add(itemButton27
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5); 
 505 ////@end wxSymbolPickerDialog content construction 
 510 bool wxSymbolPickerDialog::TransferDataToWindow() 
 514     if (m_fontCtrl
->GetCount() == 0) 
 516         wxArrayString faceNames 
= wxRichTextCtrl::GetAvailableFontNames(); 
 519         faceNames
.Insert(_("(Normal text)"), 0); 
 520         m_fontCtrl
->Append(faceNames
); 
 523     if (m_fontName
.empty()) 
 524         m_fontCtrl
->SetSelection(0); 
 527         if (m_fontCtrl
->FindString(m_fontName
) != wxNOT_FOUND
) 
 528             m_fontCtrl
->SetStringSelection(m_fontName
); 
 530             m_fontCtrl
->SetSelection(0); 
 533     if (!m_symbol
.empty()) 
 535         int sel 
= (int) m_symbol
[0]; 
 536         m_symbolsCtrl
->SetSelection(sel
); 
 539 #if defined(__UNICODE__) 
 540     if (m_subsetCtrl
->GetCount() == 0) 
 542         // Insert items into subset combo 
 544         for (i 
= 0; i 
< (int) (sizeof(g_UnicodeSubsetTable
)/sizeof(g_UnicodeSubsetTable
[0])); i
++) 
 546             m_subsetCtrl
->Append(g_UnicodeSubsetTable
[i
].m_name
); 
 548         m_subsetCtrl
->SetSelection(0); 
 552     UpdateSymbolDisplay(); 
 554     m_dontUpdate 
= false; 
 559 void wxSymbolPickerDialog::UpdateSymbolDisplay(bool updateSymbolList
, bool showAtSubset
) 
 562     wxString fontNameToUse
; 
 563     if (m_fontName
.empty()) 
 564         fontNameToUse 
= m_normalTextFontName
; 
 566         fontNameToUse 
= m_fontName
; 
 568     if (!fontNameToUse
.empty()) 
 570         font 
= wxFont(14, wxDEFAULT
, wxNORMAL
, wxNORMAL
, false, fontNameToUse
); 
 573         font 
= *wxNORMAL_FONT
; 
 575     if (updateSymbolList
) 
 577         m_symbolsCtrl
->SetFont(font
); 
 580     if (!m_symbol
.empty()) 
 582         m_symbolStaticCtrl
->SetFont(font
); 
 583         m_symbolStaticCtrl
->SetLabel(m_symbol
); 
 585         int symbol 
= (int) m_symbol
[0]; 
 586         m_characterCodeCtrl
->SetValue(wxString::Format(wxT("%X hex (%d dec)"), symbol
, symbol
)); 
 590         m_symbolStaticCtrl
->SetLabel(wxEmptyString
); 
 591         m_characterCodeCtrl
->SetValue(wxEmptyString
); 
 594 #if defined(__UNICODE__) 
 598     wxUnusedVar(showAtSubset
); 
 602 /// Show at the current subset selection 
 603 void wxSymbolPickerDialog::ShowAtSubset() 
 605 #if defined(__UNICODE__) 
 608         int sel 
= m_subsetCtrl
->GetSelection(); 
 609         int low 
= g_UnicodeSubsetTable
[sel
].m_low
; 
 610         m_symbolsCtrl
->EnsureVisible(low
); 
 615 // Handle font selection 
 616 void wxSymbolPickerDialog::OnFontCtrlSelected( wxCommandEvent
& WXUNUSED(event
) ) 
 618     if (m_fontCtrl
->GetSelection() == 0) 
 619         m_fontName 
= wxEmptyString
; 
 621         m_fontName 
= m_fontCtrl
->GetStringSelection(); 
 623     UpdateSymbolDisplay(); 
 626 /// Respond to symbol selection 
 627 void wxSymbolPickerDialog::OnSymbolSelected( wxCommandEvent
& event 
) 
 632     int sel 
= event
.GetSelection(); 
 633     if (sel 
== wxNOT_FOUND
) 
 634         m_symbol 
= wxEmptyString
; 
 637         m_symbol 
= wxEmptyString
; 
 638         m_symbol 
<< (wxChar
) sel
; 
 641 #if defined(__UNICODE__) 
 642     if (sel 
!= -1 && m_fromUnicode
) 
 644         // Need to make the subset selection reflect the current symbol 
 646         for (i 
= 0; i 
< (int) (sizeof(g_UnicodeSubsetTable
)/sizeof(g_UnicodeSubsetTable
[0])); i
++) 
 648             if (sel 
>= g_UnicodeSubsetTable
[i
].m_low 
&& sel 
<= g_UnicodeSubsetTable
[i
].m_high
) 
 651                 m_subsetCtrl
->SetSelection(i
); 
 652                 m_dontUpdate 
= false; 
 659     UpdateSymbolDisplay(false, false); 
 662 #if defined(__UNICODE__) 
 663 // Handle Unicode/ASCII selection 
 664 void wxSymbolPickerDialog::OnFromUnicodeSelected( wxCommandEvent
& WXUNUSED(event
) ) 
 669     m_fromUnicode 
= (m_fromUnicodeCtrl
->GetSelection() == 1); 
 670     m_symbolsCtrl
->SetUnicodeMode(m_fromUnicode
); 
 671     UpdateSymbolDisplay(false); 
 674 // Handle subset selection 
 675 void wxSymbolPickerDialog::OnSubsetSelected( wxCommandEvent
& WXUNUSED(event
) ) 
 685  * wxEVT_UPDATE_UI event handler for wxID_OK 
 688 void wxSymbolPickerDialog::OnOkUpdate( wxUpdateUIEvent
& event 
) 
 690     event
.Enable(HasSelection()); 
 694 void wxSymbolPickerDialog::SetUnicodeMode(bool unicodeMode
) 
 696 #if defined(__UNICODE__) 
 698     m_fromUnicode 
= unicodeMode
; 
 699     if (m_fromUnicodeCtrl
) 
 700         m_fromUnicodeCtrl
->SetSelection(m_fromUnicode 
? 1 : 0); 
 701     UpdateSymbolDisplay(); 
 702     m_dontUpdate 
= false; 
 704     wxUnusedVar(unicodeMode
); 
 708 /// Get the selected symbol character 
 709 int wxSymbolPickerDialog::GetSymbolChar() const 
 711     if (m_symbol
.empty()) 
 714         return (int) m_symbol
[0]; 
 719  * Get bitmap resources 
 722 wxBitmap 
wxSymbolPickerDialog::GetBitmapResource( const wxString
& name 
) 
 725 ////@begin wxSymbolPickerDialog bitmap retrieval 
 728 ////@end wxSymbolPickerDialog bitmap retrieval 
 735 wxIcon 
wxSymbolPickerDialog::GetIconResource( const wxString
& name 
) 
 738 ////@begin wxSymbolPickerDialog icon retrieval 
 741 ////@end wxSymbolPickerDialog icon retrieval 
 745  * The scrolling symbol list. 
 748 // ---------------------------------------------------------------------------- 
 750 // ---------------------------------------------------------------------------- 
 752 BEGIN_EVENT_TABLE(wxSymbolListCtrl
, wxVScrolledWindow
) 
 753     EVT_PAINT(wxSymbolListCtrl::OnPaint
) 
 754     EVT_SIZE(wxSymbolListCtrl::OnSize
) 
 756     EVT_KEY_DOWN(wxSymbolListCtrl::OnKeyDown
) 
 757     EVT_LEFT_DOWN(wxSymbolListCtrl::OnLeftDown
) 
 758     EVT_LEFT_DCLICK(wxSymbolListCtrl::OnLeftDClick
) 
 761 // ============================================================================ 
 763 // ============================================================================ 
 765 IMPLEMENT_ABSTRACT_CLASS(wxSymbolListCtrl
, wxVScrolledWindow
) 
 767 // ---------------------------------------------------------------------------- 
 768 // wxSymbolListCtrl creation 
 769 // ---------------------------------------------------------------------------- 
 771 void wxSymbolListCtrl::Init() 
 773     m_current 
= wxNOT_FOUND
; 
 774     m_doubleBuffer 
= NULL
; 
 775     m_cellSize 
= wxSize(40, 40); 
 776     m_minSymbolValue 
= 0; 
 777     m_maxSymbolValue 
= 255; 
 778     m_symbolsPerLine 
= 0; 
 779     m_unicodeMode 
= false; 
 782 bool wxSymbolListCtrl::Create(wxWindow 
*parent
, 
 787                         const wxString
& name
) 
 789     style 
|= wxWANTS_CHARS 
| wxFULL_REPAINT_ON_RESIZE
; 
 790     if ( !wxVScrolledWindow::Create(parent
, id
, pos
, size
, style
, name
) ) 
 793     // make sure the native widget has the right colour since we do 
 794     // transparent drawing by default 
 795     SetBackgroundColour(GetBackgroundColour()); 
 796     m_colBgSel 
= wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT
); 
 798     // flicker-free drawing requires this 
 799     SetBackgroundStyle(wxBG_STYLE_CUSTOM
); 
 801     SetFont(*wxNORMAL_FONT
); 
 808 wxSymbolListCtrl::~wxSymbolListCtrl() 
 810     delete m_doubleBuffer
; 
 813 // ---------------------------------------------------------------------------- 
 814 // selection handling 
 815 // ---------------------------------------------------------------------------- 
 817 bool wxSymbolListCtrl::IsSelected(int item
) const 
 819     return item 
== m_current
; 
 822 bool wxSymbolListCtrl::DoSetCurrent(int current
) 
 824     wxASSERT_MSG( current 
== wxNOT_FOUND 
|| 
 825                     (current 
>= m_minSymbolValue 
&& current 
<= m_maxSymbolValue
), 
 826                   _T("wxSymbolListCtrl::DoSetCurrent(): invalid symbol value") ); 
 828     if ( current 
== m_current 
) 
 834     if ( m_current 
!= wxNOT_FOUND 
) 
 835         RefreshLine(SymbolValueToLineNumber(m_current
)); 
 839     if ( m_current 
!= wxNOT_FOUND 
) 
 841         int lineNo 
= SymbolValueToLineNumber(m_current
); 
 843         // if the line is not visible at all, we scroll it into view but we 
 844         // don't need to refresh it -- it will be redrawn anyhow 
 845         if ( !IsVisible(lineNo
) ) 
 847             ScrollToLine(lineNo
); 
 849         else // line is at least partly visible 
 851             // it is, indeed, only partly visible, so scroll it into view to 
 852             // make it entirely visible 
 853             while ( unsigned(lineNo
) == GetLastVisibleLine() && 
 854                     ScrollToLine(GetVisibleBegin()+1) ) 
 857             // but in any case refresh it as even if it was only partly visible 
 858             // before we need to redraw it entirely as its background changed 
 866 void wxSymbolListCtrl::SendSelectedEvent() 
 868     wxCommandEvent 
event(wxEVT_COMMAND_LISTBOX_SELECTED
, GetId()); 
 869     event
.SetEventObject(this); 
 870     event
.SetInt(m_current
); 
 872     (void)GetEventHandler()->ProcessEvent(event
); 
 875 void wxSymbolListCtrl::SetSelection(int selection
) 
 877     wxCHECK_RET( selection 
== wxNOT_FOUND 
|| 
 878                   (selection 
>= m_minSymbolValue 
&& selection 
< m_maxSymbolValue
), 
 879                   _T("wxSymbolListCtrl::SetSelection(): invalid symbol value") ); 
 881     DoSetCurrent(selection
); 
 884 // ---------------------------------------------------------------------------- 
 885 // wxSymbolListCtrl appearance parameters 
 886 // ---------------------------------------------------------------------------- 
 888 void wxSymbolListCtrl::SetMargins(const wxPoint
& pt
) 
 890     if ( pt 
!= m_ptMargins 
) 
 898 void wxSymbolListCtrl::SetSelectionBackground(const wxColour
& col
) 
 903 // ---------------------------------------------------------------------------- 
 904 // wxSymbolListCtrl painting 
 905 // ---------------------------------------------------------------------------- 
 907 wxCoord 
wxSymbolListCtrl::OnGetLineHeight(size_t WXUNUSED(line
)) const 
 909     return m_cellSize
.y 
+ 2*m_ptMargins
.y 
+ 1 /* for divider */ ; 
 912 // draws a line of symbols 
 913 void wxSymbolListCtrl::OnDrawItem(wxDC
& dc
, const wxRect
& rect
, size_t n
) const 
 915     wxColour oldTextColour 
= dc
.GetTextForeground(); 
 916     int startSymbol 
= n
*m_symbolsPerLine
; 
 919     for (i 
= 0; i 
< m_symbolsPerLine
; i
++) 
 921         bool resetColour 
= false; 
 922         int symbol 
= startSymbol
+i
; 
 923         if (symbol 
== m_current
) 
 925             dc
.SetBrush(wxBrush(m_colBgSel
)); 
 927             dc
.SetTextForeground(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT
)); 
 930             wxPen oldPen 
= dc
.GetPen(); 
 931             dc
.SetPen(*wxTRANSPARENT_PEN
); 
 933             dc
.DrawRectangle(rect
.x 
+ i
*m_cellSize
.x
, rect
.y
, m_cellSize
.x
, rect
.y
+rect
.height
); 
 937         // Don't draw first line 
 939             dc
.DrawLine(rect
.x 
+ i
*m_cellSize
.x
, rect
.y
, i
*m_cellSize
.x
, rect
.y
+rect
.height
); 
 941         if (symbol 
>= m_minSymbolValue 
&& symbol 
<= m_maxSymbolValue
) 
 944             text 
<< (wxChar
) symbol
; 
 947             dc
.GetTextExtent(text
, & w
, & h
); 
 949             int x 
= rect
.x 
+ i
*m_cellSize
.x 
+ (m_cellSize
.x 
- w
)/2; 
 950             int y 
= rect
.y 
+ (m_cellSize
.y 
- h
)/2; 
 951             dc
.DrawText(text
, x
, y
); 
 955             dc
.SetTextForeground(oldTextColour
); 
 958     // Draw horizontal separator line 
 959     dc
.DrawLine(rect
.x
, rect
.y
+rect
.height
-1, rect
.x
+rect
.width
, rect
.y
+rect
.height
-1); 
 962 void wxSymbolListCtrl::OnPaint(wxPaintEvent
& WXUNUSED(event
)) 
 964     // If size is larger, recalculate double buffer bitmap 
 965     wxSize clientSize 
= GetClientSize(); 
 967     if ( !m_doubleBuffer 
|| 
 968          clientSize
.x 
> m_doubleBuffer
->GetWidth() || 
 969          clientSize
.y 
> m_doubleBuffer
->GetHeight() ) 
 971         delete m_doubleBuffer
; 
 972         m_doubleBuffer 
= new wxBitmap(clientSize
.x
+25,clientSize
.y
+25); 
 975     wxBufferedPaintDC 
dc(this,*m_doubleBuffer
); 
 977     // the update rectangle 
 978     wxRect rectUpdate 
= GetUpdateClientRect(); 
 980     // fill it with background colour 
 981     dc
.SetBackground(GetBackgroundColour()); 
 984     // set the font to be displayed 
 985     dc
.SetFont(GetFont()); 
 987     // the bounding rectangle of the current line 
 989     rectLine
.width 
= clientSize
.x
; 
 991     dc
.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT
))); 
 992     dc
.SetTextForeground(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT
)); 
 993     dc
.SetBackgroundMode(wxTRANSPARENT
); 
 995     // iterate over all visible lines 
 996     const size_t lineMax 
= GetVisibleEnd(); 
 997     for ( size_t line 
= GetFirstVisibleLine(); line 
< lineMax
; line
++ ) 
 999         const wxCoord hLine 
= OnGetLineHeight(line
); 
1001         rectLine
.height 
= hLine
; 
1003         // and draw the ones which intersect the update rect 
1004         if ( rectLine
.Intersects(rectUpdate
) ) 
1006             // don't allow drawing outside of the lines rectangle 
1007             wxDCClipper 
clip(dc
, rectLine
); 
1009             wxRect rect 
= rectLine
; 
1010             rect
.Deflate(m_ptMargins
.x
, m_ptMargins
.y
); 
1011             OnDrawItem(dc
, rect
, line
); 
1013         else // no intersection 
1015             if ( rectLine
.GetTop() > rectUpdate
.GetBottom() ) 
1017                 // we are already below the update rect, no need to continue 
1021             //else: the next line may intersect the update rect 
1024         rectLine
.y 
+= hLine
; 
1028 // ============================================================================ 
1029 // wxSymbolListCtrl keyboard/mouse handling 
1030 // ============================================================================ 
1032 void wxSymbolListCtrl::DoHandleItemClick(int item
, int WXUNUSED(flags
)) 
1034     if (m_current 
!= item
) 
1038         SendSelectedEvent(); 
1042 // ---------------------------------------------------------------------------- 
1043 // keyboard handling 
1044 // ---------------------------------------------------------------------------- 
1046 void wxSymbolListCtrl::OnKeyDown(wxKeyEvent
& event
) 
1048     // No keyboard interface for now 
1051     // flags for DoHandleItemClick() 
1052     int flags 
= ItemClick_Kbd
; 
1054     int currentLineNow 
= SymbolValueToLineNumber(m_current
); 
1057     switch ( event
.GetKeyCode() ) 
1064             currentLine 
= GetLineCount() - 1; 
1068             if ( currentLineNow 
== (int)GetLineCount() - 1 ) 
1071             currentLine 
= currentLineNow 
+ 1; 
1075             if ( m_current 
== wxNOT_FOUND 
) 
1076                 currentLine 
= GetLineCount() - 1; 
1077             else if ( currentLineNow 
!= 0 ) 
1078                 currentLine 
= currentLineNow 
- 1; 
1079             else // currentLineNow == 0 
1085             currentLine 
= GetFirstVisibleLine(); 
1089             if ( currentLineNow 
== (int)GetFirstVisibleLine() ) 
1094             currentLine 
= GetFirstVisibleLine(); 
1098             // hack: pressing space should work like a mouse click rather than 
1099             // like a keyboard arrow press, so trick DoHandleItemClick() in 
1100             // thinking we were clicked 
1101             flags 
&= ~ItemClick_Kbd
; 
1102             currentLine 
= currentLineNow
; 
1107             // Since we are using wxWANTS_CHARS we need to send navigation 
1108             // events for the tabs on MSW 
1110                 wxNavigationKeyEvent ne
; 
1111                 ne
.SetDirection(!event
.ShiftDown()); 
1112                 ne
.SetCurrentFocus(this); 
1113                 ne
.SetEventObject(this); 
1114                 GetParent()->GetEventHandler()->ProcessEvent(ne
); 
1116             // fall through to default 
1120             currentLine 
= 0; // just to silent the stupid compiler warnings 
1121             wxUnusedVar(currentNow
); 
1126     if ( event
.ShiftDown() ) 
1127        flags 
|= ItemClick_Shift
; 
1128     if ( event
.ControlDown() ) 
1129         flags 
|= ItemClick_Ctrl
; 
1131     DoHandleItemClick(current
, flags
); 
1136 // ---------------------------------------------------------------------------- 
1137 // wxSymbolListCtrl mouse handling 
1138 // ---------------------------------------------------------------------------- 
1140 void wxSymbolListCtrl::OnLeftDown(wxMouseEvent
& event
) 
1144     int item 
= HitTest(event
.GetPosition()); 
1146     if ( item 
!= wxNOT_FOUND 
) 
1149         if ( event
.ShiftDown() ) 
1150            flags 
|= ItemClick_Shift
; 
1152         // under Mac Apple-click is used in the same way as Ctrl-click 
1155         if ( event
.MetaDown() ) 
1157         if ( event
.ControlDown() ) 
1159             flags 
|= ItemClick_Ctrl
; 
1161         DoHandleItemClick(item
, flags
); 
1165 void wxSymbolListCtrl::OnLeftDClick(wxMouseEvent
& eventMouse
) 
1167     int item 
= HitTest(eventMouse
.GetPosition()); 
1168     if ( item 
!= wxNOT_FOUND 
) 
1171         // if item double-clicked was not yet selected, then treat 
1172         // this event as a left-click instead 
1173         if ( item 
== m_current 
) 
1175             wxCommandEvent 
event(wxEVT_COMMAND_LISTBOX_DOUBLECLICKED
, GetId()); 
1176             event
.SetEventObject(this); 
1179             (void)GetEventHandler()->ProcessEvent(event
); 
1183             OnLeftDown(eventMouse
); 
1189 // calculate line number from symbol value 
1190 int wxSymbolListCtrl::SymbolValueToLineNumber(int item
) 
1192     return (int) (item
/m_symbolsPerLine
); 
1195 // initialise control from current min/max values 
1196 void wxSymbolListCtrl::SetupCtrl(bool scrollToSelection
) 
1198     wxSize sz 
= GetClientSize(); 
1200     m_symbolsPerLine 
= sz
.x
/(m_cellSize
.x
+m_ptMargins
.x
); 
1201     int noLines 
= (1 + SymbolValueToLineNumber(m_maxSymbolValue
)); 
1203     SetLineCount(noLines
); 
1206     if (scrollToSelection 
&& m_current 
!= wxNOT_FOUND 
&& m_current 
>= m_minSymbolValue 
&& m_current 
<= m_maxSymbolValue
) 
1208         ScrollToLine(SymbolValueToLineNumber(m_current
)); 
1212 // make this item visible 
1213 void wxSymbolListCtrl::EnsureVisible(int item
) 
1215     if (item 
!= wxNOT_FOUND 
&& item 
>= m_minSymbolValue 
&& item 
<= m_maxSymbolValue
) 
1217         ScrollToLine(SymbolValueToLineNumber(item
)); 
1223 int wxSymbolListCtrl::HitTest(const wxPoint
& pt
) 
1225     wxCoord lineHeight 
= OnGetLineHeight(0); 
1227     int atLine 
= GetVisibleBegin() + (pt
.y
/lineHeight
); 
1228     int symbol 
= (atLine
*m_symbolsPerLine
) + (pt
.x
/(m_cellSize
.x
+1)); 
1230     if (symbol 
>= m_minSymbolValue 
&& symbol 
<= m_maxSymbolValue
) 
1236 // Respond to size change 
1237 void wxSymbolListCtrl::OnSize(wxSizeEvent
& event
) 
1243 // set the current font 
1244 bool wxSymbolListCtrl::SetFont(const wxFont
& font
) 
1246     wxVScrolledWindow::SetFont(font
); 
1253 // set Unicode/ASCII mode 
1254 void wxSymbolListCtrl::SetUnicodeMode(bool unicodeMode
) 
1256     bool changed 
= false; 
1257     if (unicodeMode 
&& !m_unicodeMode
) 
1261         m_minSymbolValue 
= 0; 
1262         m_maxSymbolValue 
= 65535; 
1264     else if (!unicodeMode 
&& m_unicodeMode
) 
1267         m_minSymbolValue 
= 0; 
1268         m_maxSymbolValue 
= 255; 
1270     m_unicodeMode 
= unicodeMode
; 
1276 // ---------------------------------------------------------------------------- 
1277 // use the same default attributes as wxListBox 
1278 // ---------------------------------------------------------------------------- 
1282 wxSymbolListCtrl::GetClassDefaultAttributes(wxWindowVariant variant
) 
1284     return wxListBox::GetClassDefaultAttributes(variant
); 
1287 #endif // wxUSE_RICHTEXT