1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        src/richtext/richtextsymboldlg.cpp
3 // Purpose:
4 // Author:      Julian Smart
5 // Modified by:
6 // Created:     10/5/2006 3:11:58 PM
7 // Copyright:   (c) Julian Smart
8 // Licence:     wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10 
11 // For compilers that support precompilation, includes "wx/wx.h".
12 #include "wx/wxprec.h"
13 
14 
15 #if wxUSE_RICHTEXT
16 
17 #include "wx/richtext/richtextsymboldlg.h"
18 
19 #ifndef WX_PRECOMP
20     #include "wx/sizer.h"
21     #include "wx/stattext.h"
22     #include "wx/combobox.h"
23     #include "wx/button.h"
24     #include "wx/settings.h"
25     #include "wx/icon.h"
26     #include "wx/listbox.h"
27 #endif
28 
29 #include "wx/dcbuffer.h"
30 
31 // Only for cached font name
32 #include "wx/richtext/richtextctrl.h"
33 
34 /* Microsoft Unicode subset numbering
35  */
36 
37 typedef enum
38 {
39   U_BASIC_LATIN = 0,
40   U_LATIN_1_SUPPLEMENT = 1,
41   U_LATIN_EXTENDED_A = 2,
42   U_LATIN_EXTENDED_B = 3,
43   U_IPA_EXTENSIONS = 4,
44   U_SPACING_MODIFIER_LETTERS = 5,
45   U_COMBINING_DIACRITICAL_MARKS = 6,
46   U_BASIC_GREEK = 7,
47   U_GREEK_SYMBOLS_AND_COPTIC = 8,
48   U_CYRILLIC = 9,
49   U_ARMENIAN = 10,
50   U_HEBREW_EXTENDED = 12,
51   U_BASIC_HEBREW = 11,
52   U_BASIC_ARABIC = 13,
53   U_ARABIC_EXTENDED = 14,
54   U_DEVANAGARI = 15,
55   U_BENGALI = 16,
56   U_GURMUKHI = 17,
57   U_GUJARATI = 18,
58   U_ORIYA = 19,
59   U_TAMIL = 20,
60   U_TELUGU = 21,
61   U_KANNADA = 22,
62   U_MALAYALAM = 23,
63   U_THAI = 24,
64   U_LAO = 25,
65   U_GEORGIAN_EXTENDED = 27,
66   U_BASIC_GEORGIAN = 26,
67   U_HANGUL_JAMO = 28,
68   U_LATIN_EXTENDED_ADDITIONAL = 29,
69   U_GREEK_EXTENDED = 30,
70   U_GENERAL_PUNCTUATION = 31,
71   U_SUPERSCRIPTS_AND_SUBSCRIPTS = 32,
72   U_CURRENCY_SYMBOLS = 33,
73   U_COMBINING_DIACRITICAL_MARKS_FOR_SYMBOLS = 34,
74   U_LETTERLIKE_SYMBOLS = 35,
75   U_NUMBER_FORMS = 36,
76   U_ARROWS = 37,
77   U_MATHEMATICAL_OPERATORS = 38,
78   U_MISCELLANEOUS_TECHNICAL = 39,
79   U_CONTROL_PICTURES = 40,
80   U_OPTICAL_CHARACTER_RECOGNITION = 41,
81   U_ENCLOSED_ALPHANUMERICS = 42,
82   U_BOX_DRAWING = 43,
83   U_BLOCK_ELEMENTS = 44,
84   U_GEOMETRIC_SHAPES = 45,
85   U_MISCELLANEOUS_SYMBOLS = 46,
86   U_DINGBATS = 47,
87   U_CJK_SYMBOLS_AND_PUNCTUATION = 48,
88   U_HIRAGANA = 49,
89   U_KATAKANA = 50,
90   U_BOPOMOFO = 51,
91   U_HANGUL_COMPATIBILITY_JAMO = 52,
92   U_CJK_MISCELLANEOUS = 53,
93   U_ENCLOSED_CJK = 54,
94   U_CJK_COMPATIBILITY = 55,
95   U_HANGUL = 56,
96   U_HANGUL_SUPPLEMENTARY_A = 57,
97   U_HANGUL_SUPPLEMENTARY_B = 58,
98   U_CJK_UNIFIED_IDEOGRAPHS = 59,
99   U_PRIVATE_USE_AREA = 60,
100   U_CJK_COMPATIBILITY_IDEOGRAPHS = 61,
101   U_ALPHABETIC_PRESENTATION_FORMS = 62,
102   U_ARABIC_PRESENTATION_FORMS_A = 63,
103   U_COMBINING_HALF_MARKS = 64,
104   U_CJK_COMPATIBILITY_FORMS = 65,
105   U_SMALL_FORM_VARIANTS = 66,
106   U_ARABIC_PRESENTATION_FORMS_B = 67,
107   U_SPECIALS = 69,
108   U_HALFWIDTH_AND_FULLWIDTH_FORMS = 68,
109   U_LAST_PLUS_ONE
110 } wxUnicodeSubsetCodes;
111 
112 /* Unicode subsets */
113 #ifdef __UNICODE__
114 
115 static struct
116 {
117     int m_low, m_high;
118     wxUnicodeSubsetCodes m_subset;
119     const wxChar* m_name;
120 } g_UnicodeSubsetTable[] =
121 {
122   { 0x0000, 0x007E,
123     U_BASIC_LATIN, wxT("Basic Latin") },
124   { 0x00A0, 0x00FF,
125     U_LATIN_1_SUPPLEMENT, wxT("Latin-1 Supplement") },
126   { 0x0100, 0x017F,
127     U_LATIN_EXTENDED_A, wxT("Latin Extended-A") },
128   { 0x0180, 0x024F,
129     U_LATIN_EXTENDED_B, wxT("Latin Extended-B") },
130   { 0x0250, 0x02AF,
131     U_IPA_EXTENSIONS, wxT("IPA Extensions") },
132   { 0x02B0, 0x02FF,
133     U_SPACING_MODIFIER_LETTERS, wxT("Spacing Modifier Letters") },
134   { 0x0300, 0x036F,
135     U_COMBINING_DIACRITICAL_MARKS, wxT("Combining Diacritical Marks") },
136   { 0x0370, 0x03CF,
137     U_BASIC_GREEK, wxT("Basic Greek") },
138   { 0x03D0, 0x03FF,
139     U_GREEK_SYMBOLS_AND_COPTIC, wxT("Greek Symbols and Coptic") },
140   { 0x0400, 0x04FF,
141     U_CYRILLIC, wxT("Cyrillic") },
142   { 0x0530, 0x058F,
143     U_ARMENIAN, wxT("Armenian") },
144   { 0x0590, 0x05CF,
145     U_HEBREW_EXTENDED, wxT("Hebrew Extended") },
146   { 0x05D0, 0x05FF,
147     U_BASIC_HEBREW, wxT("Basic Hebrew") },
148   { 0x0600, 0x0652,
149     U_BASIC_ARABIC, wxT("Basic Arabic") },
150   { 0x0653, 0x06FF,
151     U_ARABIC_EXTENDED, wxT("Arabic Extended") },
152   { 0x0900, 0x097F,
153     U_DEVANAGARI, wxT("Devanagari") },
154   { 0x0980, 0x09FF,
155     U_BENGALI, wxT("Bengali") },
156   { 0x0A00, 0x0A7F,
157     U_GURMUKHI, wxT("Gurmukhi") },
158   { 0x0A80, 0x0AFF,
159     U_GUJARATI, wxT("Gujarati") },
160   { 0x0B00, 0x0B7F,
161     U_ORIYA, wxT("Oriya") },
162   { 0x0B80, 0x0BFF,
163     U_TAMIL, wxT("Tamil") },
164   { 0x0C00, 0x0C7F,
165     U_TELUGU, wxT("Telugu") },
166   { 0x0C80, 0x0CFF,
167     U_KANNADA, wxT("Kannada") },
168   { 0x0D00, 0x0D7F,
169     U_MALAYALAM, wxT("Malayalam") },
170   { 0x0E00, 0x0E7F,
171     U_THAI, wxT("Thai") },
172   { 0x0E80, 0x0EFF,
173     U_LAO, wxT("Lao") },
174   { 0x10A0, 0x10CF,
175     U_GEORGIAN_EXTENDED, wxT("Georgian Extended") },
176   { 0x10D0, 0x10FF,
177     U_BASIC_GEORGIAN, wxT("Basic Georgian") },
178   { 0x1100, 0x11FF,
179     U_HANGUL_JAMO, wxT("Hangul Jamo") },
180   { 0x1E00, 0x1EFF,
181     U_LATIN_EXTENDED_ADDITIONAL, wxT("Latin Extended Additional") },
182   { 0x1F00, 0x1FFF,
183     U_GREEK_EXTENDED, wxT("Greek Extended") },
184   { 0x2000, 0x206F,
185     U_GENERAL_PUNCTUATION, wxT("General Punctuation") },
186   { 0x2070, 0x209F,
187     U_SUPERSCRIPTS_AND_SUBSCRIPTS, wxT("Superscripts and Subscripts") },
188   { 0x20A0, 0x20CF,
189     U_CURRENCY_SYMBOLS, wxT("Currency Symbols") },
190   { 0x20D0, 0x20FF,
191     U_COMBINING_DIACRITICAL_MARKS_FOR_SYMBOLS, wxT("Combining Diacritical Marks for Symbols") },
192   { 0x2100, 0x214F,
193     U_LETTERLIKE_SYMBOLS, wxT("Letterlike Symbols") },
194   { 0x2150, 0x218F,
195     U_NUMBER_FORMS, wxT("Number Forms") },
196   { 0x2190, 0x21FF,
197     U_ARROWS, wxT("Arrows") },
198   { 0x2200, 0x22FF,
199     U_MATHEMATICAL_OPERATORS, wxT("Mathematical Operators") },
200   { 0x2300, 0x23FF,
201     U_MISCELLANEOUS_TECHNICAL, wxT("Miscellaneous Technical") },
202   { 0x2400, 0x243F,
203     U_CONTROL_PICTURES, wxT("Control Pictures") },
204   { 0x2440, 0x245F,
205     U_OPTICAL_CHARACTER_RECOGNITION, wxT("Optical Character Recognition") },
206   { 0x2460, 0x24FF,
207     U_ENCLOSED_ALPHANUMERICS, wxT("Enclosed Alphanumerics") },
208   { 0x2500, 0x257F,
209     U_BOX_DRAWING, wxT("Box Drawing") },
210   { 0x2580, 0x259F,
211     U_BLOCK_ELEMENTS, wxT("Block Elements") },
212   { 0x25A0, 0x25FF,
213     U_GEOMETRIC_SHAPES, wxT("Geometric Shapes") },
214   { 0x2600, 0x26FF,
215     U_MISCELLANEOUS_SYMBOLS, wxT("Miscellaneous Symbols") },
216   { 0x2700, 0x27BF,
217     U_DINGBATS, wxT("Dingbats") },
218   { 0x3000, 0x303F,
219     U_CJK_SYMBOLS_AND_PUNCTUATION, wxT("CJK Symbols and Punctuation") },
220   { 0x3040, 0x309F,
221     U_HIRAGANA, wxT("Hiragana") },
222   { 0x30A0, 0x30FF,
223     U_KATAKANA, wxT("Katakana") },
224   { 0x3100, 0x312F,
225     U_BOPOMOFO, wxT("Bopomofo") },
226   { 0x3130, 0x318F,
227     U_HANGUL_COMPATIBILITY_JAMO, wxT("Hangul Compatibility Jamo") },
228   { 0x3190, 0x319F,
229     U_CJK_MISCELLANEOUS, wxT("CJK Miscellaneous") },
230   { 0x3200, 0x32FF,
231     U_ENCLOSED_CJK, wxT("Enclosed CJK") },
232   { 0x3300, 0x33FF,
233     U_CJK_COMPATIBILITY, wxT("CJK Compatibility") },
234   { 0x3400, 0x4DB5,
235     U_CJK_UNIFIED_IDEOGRAPHS, wxT("CJK Unified Ideographs Extension A") },
236   { 0x4E00, 0x9FFF,
237     U_CJK_UNIFIED_IDEOGRAPHS, wxT("CJK Unified Ideographs") },
238   { 0xAC00, 0xD7A3,
239     U_HANGUL, wxT("Hangul Syllables") },
240   { 0xE000, 0xF8FF,
241     U_PRIVATE_USE_AREA, wxT("Private Use Area") },
242   { 0xF900, 0xFAFF,
243     U_CJK_COMPATIBILITY_IDEOGRAPHS, wxT("CJK Compatibility Ideographs") },
244   { 0xFB00, 0xFB4F,
245     U_ALPHABETIC_PRESENTATION_FORMS, wxT("Alphabetic Presentation Forms") },
246   { 0xFB50, 0xFDFF,
247     U_ARABIC_PRESENTATION_FORMS_A, wxT("Arabic Presentation Forms-A") },
248   { 0xFE20, 0xFE2F,
249     U_COMBINING_HALF_MARKS, wxT("Combining Half Marks") },
250   { 0xFE30, 0xFE4F,
251     U_CJK_COMPATIBILITY_FORMS, wxT("CJK Compatibility Forms") },
252   { 0xFE50, 0xFE6F,
253     U_SMALL_FORM_VARIANTS, wxT("Small Form Variants") },
254   { 0xFE70, 0xFEFE,
255     U_ARABIC_PRESENTATION_FORMS_B, wxT("Arabic Presentation Forms-B") },
256   { 0xFEFF, 0xFEFF,
257     U_SPECIALS, wxT("Specials") },
258   { 0xFF00, 0xFFEF,
259     U_HALFWIDTH_AND_FULLWIDTH_FORMS, wxT("Halfwidth and Fullwidth Forms") },
260   { 0xFFF0, 0xFFFD,
261     U_SPECIALS, wxT("Specials") }
262 };
263 
264 #endif // __UNICODE__
265 
266 #if 0
267 // Not yet used, but could be used to test under Win32 whether this subset is available
268 // for the given font. The Win32 function is allegedly not accurate, however.
269 bool wxSubsetValidForFont(int subsetIndex, FONTSIGNATURE *fontSig)
270 {
271     return (fontSig->fsUsb[g_UnicodeSubsetTable[subsetIndex].m_subset/32] & (1 << (g_UnicodeSubsetTable[subsetIndex].m_subset % 32)));
272 }
273 #endif
274 
275 bool wxSymbolPickerDialog::sm_showToolTips = false;
276 
277 /*!
278  * wxSymbolPickerDialog type definition
279  */
280 
281 wxIMPLEMENT_DYNAMIC_CLASS(wxSymbolPickerDialog, wxDialog);
282 
283 /*!
284  * wxSymbolPickerDialog event table definition
285  */
286 
wxBEGIN_EVENT_TABLE(wxSymbolPickerDialog,wxDialog)287 wxBEGIN_EVENT_TABLE(wxSymbolPickerDialog, wxDialog)
288     EVT_LISTBOX(ID_SYMBOLPICKERDIALOG_LISTCTRL, wxSymbolPickerDialog::OnSymbolSelected)
289 
290 ////@begin wxSymbolPickerDialog event table entries
291     EVT_COMBOBOX( ID_SYMBOLPICKERDIALOG_FONT, wxSymbolPickerDialog::OnFontCtrlSelected )
292 #if defined(__UNICODE__)
293     EVT_COMBOBOX( ID_SYMBOLPICKERDIALOG_SUBSET, wxSymbolPickerDialog::OnSubsetSelected )
294     EVT_UPDATE_UI( ID_SYMBOLPICKERDIALOG_SUBSET, wxSymbolPickerDialog::OnSymbolpickerdialogSubsetUpdate )
295 #endif
296 
297 #if defined(__UNICODE__)
298     EVT_COMBOBOX( ID_SYMBOLPICKERDIALOG_FROM, wxSymbolPickerDialog::OnFromUnicodeSelected )
299 #endif
300 
301     EVT_UPDATE_UI( wxID_OK, wxSymbolPickerDialog::OnOkUpdate )
302     EVT_BUTTON( wxID_HELP, wxSymbolPickerDialog::OnHelpClick )
303     EVT_UPDATE_UI( wxID_HELP, wxSymbolPickerDialog::OnHelpUpdate )
304 ////@end wxSymbolPickerDialog event table entries
305 
306 wxEND_EVENT_TABLE()
307 
308 IMPLEMENT_HELP_PROVISION(wxSymbolPickerDialog)
309 
310 /*!
311  * wxSymbolPickerDialog constructors
312  */
313 
314 wxSymbolPickerDialog::wxSymbolPickerDialog( )
315 {
316     Init();
317 }
318 
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)319 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 )
320 {
321     Init();
322     Create(symbol, fontName, normalTextFont, parent, id, caption, pos, size, style);
323 }
324 
325 /*!
326  * wxSymbolPickerDialog creator
327  */
328 
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)329 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 )
330 {
331     m_fontName = fontName;
332     m_normalTextFontName = normalTextFont;
333     m_symbol = symbol;
334 
335 ////@begin wxSymbolPickerDialog creation
336     SetExtraStyle(wxWS_EX_BLOCK_EVENTS|wxDIALOG_EX_CONTEXTHELP);
337     wxDialog::Create( parent, id, caption, pos, size, style );
338 
339     CreateControls();
340     if (GetSizer())
341     {
342         GetSizer()->SetSizeHints(this);
343     }
344     Centre();
345 ////@end wxSymbolPickerDialog creation
346     return true;
347 }
348 
349 /*!
350  * Member initialisation for wxSymbolPickerDialog
351  */
352 
Init()353 void wxSymbolPickerDialog::Init()
354 {
355 ////@begin wxSymbolPickerDialog member initialisation
356     m_fromUnicode = true;
357     m_fontCtrl = NULL;
358 #if defined(__UNICODE__)
359     m_subsetCtrl = NULL;
360 #endif
361     m_symbolsCtrl = NULL;
362     m_symbolStaticCtrl = NULL;
363     m_characterCodeCtrl = NULL;
364 #if defined(__UNICODE__)
365     m_fromUnicodeCtrl = NULL;
366 #endif
367     m_stdButtonSizer = NULL;
368 ////@end wxSymbolPickerDialog member initialisation
369     m_dontUpdate = false;
370 }
371 
372 /*!
373  * Control creation for wxSymbolPickerDialog
374  */
375 
CreateControls()376 void wxSymbolPickerDialog::CreateControls()
377 {
378 #ifdef __WXMAC__
379     SetWindowVariant(wxWINDOW_VARIANT_SMALL);
380 #endif
381 
382 ////@begin wxSymbolPickerDialog content construction
383     wxSymbolPickerDialog* itemDialog1 = this;
384 
385     wxBoxSizer* itemBoxSizer2 = new wxBoxSizer(wxVERTICAL);
386     itemDialog1->SetSizer(itemBoxSizer2);
387 
388     wxBoxSizer* itemBoxSizer3 = new wxBoxSizer(wxVERTICAL);
389     itemBoxSizer2->Add(itemBoxSizer3, 1, wxGROW|wxALL, 5);
390 
391     wxBoxSizer* itemBoxSizer4 = new wxBoxSizer(wxHORIZONTAL);
392     itemBoxSizer3->Add(itemBoxSizer4, 0, wxGROW, 5);
393 
394     wxBoxSizer* itemBoxSizer5 = new wxBoxSizer(wxHORIZONTAL);
395     itemBoxSizer4->Add(itemBoxSizer5, 1, wxGROW, 5);
396 
397     wxStaticText* itemStaticText6 = new wxStaticText( itemDialog1, wxID_STATIC, _("&Font:"), wxDefaultPosition, wxDefaultSize, 0 );
398     itemBoxSizer5->Add(itemStaticText6, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
399 
400     wxArrayString m_fontCtrlStrings;
401     m_fontCtrl = new wxComboBox( itemDialog1, ID_SYMBOLPICKERDIALOG_FONT, wxEmptyString, wxDefaultPosition, wxSize(240, -1), m_fontCtrlStrings, wxCB_READONLY );
402     m_fontCtrl->SetHelpText(_("The font from which to take the symbol."));
403     if (wxSymbolPickerDialog::ShowToolTips())
404         m_fontCtrl->SetToolTip(_("The font from which to take the symbol."));
405     itemBoxSizer5->Add(m_fontCtrl, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
406 
407     itemBoxSizer5->Add(5, 5, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
408 
409 #if defined(__UNICODE__)
410     wxStaticText* itemStaticText9 = new wxStaticText( itemDialog1, wxID_STATIC, _("&Subset:"), wxDefaultPosition, wxDefaultSize, 0 );
411     itemBoxSizer5->Add(itemStaticText9, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
412 
413 #endif
414 
415 #if defined(__UNICODE__)
416     wxArrayString m_subsetCtrlStrings;
417     m_subsetCtrl = new wxComboBox( itemDialog1, ID_SYMBOLPICKERDIALOG_SUBSET, wxEmptyString, wxDefaultPosition, wxDefaultSize, m_subsetCtrlStrings, wxCB_READONLY );
418     m_subsetCtrl->SetHelpText(_("Shows a Unicode subset."));
419     if (wxSymbolPickerDialog::ShowToolTips())
420         m_subsetCtrl->SetToolTip(_("Shows a Unicode subset."));
421     itemBoxSizer5->Add(m_subsetCtrl, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5);
422 
423 #endif
424 
425     m_symbolsCtrl = new wxSymbolListCtrl( itemDialog1, ID_SYMBOLPICKERDIALOG_LISTCTRL, wxDefaultPosition, wxSize(500, 200), 0 );
426     itemBoxSizer3->Add(m_symbolsCtrl, 1, wxGROW|wxALL, 5);
427 
428     wxBoxSizer* itemBoxSizer12 = new wxBoxSizer(wxHORIZONTAL);
429     itemBoxSizer3->Add(itemBoxSizer12, 0, wxGROW, 5);
430 
431     m_symbolStaticCtrl = new wxStaticText( itemDialog1, wxID_STATIC, _("xxxx"), wxDefaultPosition, wxSize(40, -1), wxALIGN_CENTRE );
432     itemBoxSizer12->Add(m_symbolStaticCtrl, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
433 
434     itemBoxSizer12->Add(5, 5, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
435 
436     wxStaticText* itemStaticText15 = new wxStaticText( itemDialog1, wxID_STATIC, _("&Character code:"), wxDefaultPosition, wxDefaultSize, 0 );
437     itemBoxSizer12->Add(itemStaticText15, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
438 
439     m_characterCodeCtrl = new wxTextCtrl( itemDialog1, ID_SYMBOLPICKERDIALOG_CHARACTERCODE, wxEmptyString, wxDefaultPosition, wxSize(140, -1), wxTE_READONLY|wxTE_CENTRE );
440     m_characterCodeCtrl->SetHelpText(_("The character code."));
441     if (wxSymbolPickerDialog::ShowToolTips())
442         m_characterCodeCtrl->SetToolTip(_("The character code."));
443     itemBoxSizer12->Add(m_characterCodeCtrl, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
444 
445     itemBoxSizer12->Add(5, 5, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5);
446 
447 #if defined(__UNICODE__)
448     wxStaticText* itemStaticText18 = new wxStaticText( itemDialog1, wxID_STATIC, _("&From:"), wxDefaultPosition, wxDefaultSize, 0 );
449     itemBoxSizer12->Add(itemStaticText18, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
450 
451 #endif
452 
453 #if defined(__UNICODE__)
454     wxArrayString m_fromUnicodeCtrlStrings;
455     m_fromUnicodeCtrlStrings.Add(_("ASCII"));
456     m_fromUnicodeCtrlStrings.Add(_("Unicode"));
457     m_fromUnicodeCtrl = new wxComboBox( itemDialog1, ID_SYMBOLPICKERDIALOG_FROM, _("Unicode"), wxDefaultPosition, wxDefaultSize, m_fromUnicodeCtrlStrings, wxCB_READONLY );
458     m_fromUnicodeCtrl->SetStringSelection(_("Unicode"));
459     m_fromUnicodeCtrl->SetHelpText(_("The range to show."));
460     if (wxSymbolPickerDialog::ShowToolTips())
461         m_fromUnicodeCtrl->SetToolTip(_("The range to show."));
462     itemBoxSizer12->Add(m_fromUnicodeCtrl, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
463 
464 #endif
465 
466     m_stdButtonSizer = new wxStdDialogButtonSizer;
467 
468     itemBoxSizer3->Add(m_stdButtonSizer, 0, wxGROW|wxTOP|wxBOTTOM, 5);
469     wxButton* itemButton21 = new wxButton( itemDialog1, wxID_OK, _("Insert"), wxDefaultPosition, wxDefaultSize, 0 );
470     itemButton21->SetDefault();
471     m_stdButtonSizer->AddButton(itemButton21);
472 
473     wxButton* itemButton22 = new wxButton( itemDialog1, wxID_CANCEL, _("Close"), wxDefaultPosition, wxDefaultSize, 0 );
474     m_stdButtonSizer->AddButton(itemButton22);
475 
476     wxButton* itemButton23 = new wxButton( itemDialog1, wxID_HELP, _("&Help"), wxDefaultPosition, wxDefaultSize, 0 );
477     m_stdButtonSizer->AddButton(itemButton23);
478 
479     m_stdButtonSizer->Realize();
480 
481 ////@end wxSymbolPickerDialog content construction
482 
483     if (GetHelpId() == -1)
484     {
485         wxWindow* button = FindWindowById(wxID_HELP);
486         if (button)
487             m_stdButtonSizer->Show(button, false);
488     }
489 
490     m_symbolsCtrl->SetFocus();
491 }
492 
493 /// Data transfer
TransferDataToWindow()494 bool wxSymbolPickerDialog::TransferDataToWindow()
495 {
496     m_dontUpdate = true;
497 
498     if (m_fontCtrl->GetCount() == 0)
499     {
500         wxArrayString faceNames = wxRichTextCtrl::GetAvailableFontNames();
501         faceNames.Sort();
502 
503         faceNames.Insert(_("(Normal text)"), 0);
504         m_fontCtrl->Append(faceNames);
505     }
506 
507     if (m_fontName.empty())
508         m_fontCtrl->SetSelection(0);
509     else
510     {
511         if (m_fontCtrl->FindString(m_fontName) != wxNOT_FOUND)
512             m_fontCtrl->SetStringSelection(m_fontName);
513         else
514             m_fontCtrl->SetSelection(0);
515     }
516 
517 #if defined(__UNICODE__)
518     if (m_subsetCtrl->GetCount() == 0)
519     {
520         // Insert items into subset combo
521         int i;
522         for (i = 0; i < (int) WXSIZEOF(g_UnicodeSubsetTable); i++)
523         {
524             m_subsetCtrl->Append(g_UnicodeSubsetTable[i].m_name);
525         }
526         m_subsetCtrl->SetSelection(0);
527     }
528 #endif
529 
530 #if defined(__UNICODE__)
531     m_symbolsCtrl->SetUnicodeMode(m_fromUnicode);
532 #endif
533 
534     if (!m_symbol.empty())
535     {
536         int sel = (int) m_symbol[0];
537         m_symbolsCtrl->SetSelection(sel);
538     }
539 
540     UpdateSymbolDisplay(true, m_symbol.empty());
541 
542     m_dontUpdate = false;
543 
544     return true;
545 }
546 
UpdateSymbolDisplay(bool updateSymbolList,bool showAtSubset)547 void wxSymbolPickerDialog::UpdateSymbolDisplay(bool updateSymbolList, bool showAtSubset)
548 {
549     wxFont font;
550     wxString fontNameToUse;
551     if (m_fontName.empty())
552         fontNameToUse = m_normalTextFontName;
553     else
554         fontNameToUse = m_fontName;
555 
556     if (!fontNameToUse.empty())
557     {
558         font = wxFont(14, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, fontNameToUse);
559     }
560     else
561         font = *wxNORMAL_FONT;
562 
563     if (updateSymbolList)
564     {
565         m_symbolsCtrl->SetFont(font);
566     }
567 
568     if (!m_symbol.empty())
569     {
570         m_symbolStaticCtrl->SetFont(font);
571         m_symbolStaticCtrl->SetLabelText(m_symbol);
572 
573         int symbol = (int) m_symbol[0];
574         m_characterCodeCtrl->SetValue(wxString::Format(wxT("%X hex (%d dec)"), symbol, symbol));
575     }
576     else
577     {
578         m_symbolStaticCtrl->SetLabel(wxEmptyString);
579         m_characterCodeCtrl->SetValue(wxEmptyString);
580     }
581 
582 #if defined(__UNICODE__)
583     if (showAtSubset)
584         ShowAtSubset();
585 #else
586     wxUnusedVar(showAtSubset);
587 #endif
588 }
589 
590 /// Show at the current subset selection
ShowAtSubset()591 void wxSymbolPickerDialog::ShowAtSubset()
592 {
593 #if defined(__UNICODE__)
594     if (m_fromUnicode)
595     {
596         int sel = m_subsetCtrl->GetSelection();
597         int low = g_UnicodeSubsetTable[sel].m_low;
598         m_symbolsCtrl->EnsureVisible(low);
599     }
600 #endif
601 }
602 
603 // Handle font selection
OnFontCtrlSelected(wxCommandEvent & WXUNUSED (event))604 void wxSymbolPickerDialog::OnFontCtrlSelected( wxCommandEvent& WXUNUSED(event) )
605 {
606     if (m_fontCtrl->GetSelection() == 0)
607         m_fontName.clear();
608     else
609         m_fontName = m_fontCtrl->GetStringSelection();
610 
611     UpdateSymbolDisplay();
612 }
613 
614 /// Respond to symbol selection
OnSymbolSelected(wxCommandEvent & event)615 void wxSymbolPickerDialog::OnSymbolSelected( wxCommandEvent& event )
616 {
617     if (m_dontUpdate)
618         return;
619 
620     int sel = event.GetSelection();
621     m_symbol.clear();
622     if (sel != wxNOT_FOUND)
623         m_symbol << (wxChar) sel;
624 
625 #if defined(__UNICODE__)
626     if (sel != -1 && m_fromUnicode)
627     {
628         // Need to make the subset selection reflect the current symbol
629         int i;
630         for (i = 0; i < (int) WXSIZEOF(g_UnicodeSubsetTable); i++)
631         {
632             if (sel >= g_UnicodeSubsetTable[i].m_low && sel <= g_UnicodeSubsetTable[i].m_high)
633             {
634                 m_dontUpdate = true;
635                 m_subsetCtrl->SetSelection(i);
636                 m_dontUpdate = false;
637                 break;
638             }
639         }
640     }
641 #endif
642 
643     UpdateSymbolDisplay(false, false);
644 }
645 
646 #if defined(__UNICODE__)
647 // Handle Unicode/ASCII selection
OnFromUnicodeSelected(wxCommandEvent & WXUNUSED (event))648 void wxSymbolPickerDialog::OnFromUnicodeSelected( wxCommandEvent& WXUNUSED(event) )
649 {
650     if (m_dontUpdate)
651         return;
652 
653     m_fromUnicode = (m_fromUnicodeCtrl->GetSelection() == 1);
654     m_symbolsCtrl->SetUnicodeMode(m_fromUnicode);
655     UpdateSymbolDisplay(false);
656 }
657 
658 // Handle subset selection
OnSubsetSelected(wxCommandEvent & WXUNUSED (event))659 void wxSymbolPickerDialog::OnSubsetSelected( wxCommandEvent& WXUNUSED(event) )
660 {
661     if (m_dontUpdate)
662         return;
663 
664     ShowAtSubset();
665 }
666 #endif
667 
668 #if defined(__UNICODE__)
669 
670 /*!
671  * wxEVT_UPDATE_UI event handler for ID_SYMBOLPICKERDIALOG_SUBSET
672  */
673 
OnSymbolpickerdialogSubsetUpdate(wxUpdateUIEvent & event)674 void wxSymbolPickerDialog::OnSymbolpickerdialogSubsetUpdate( wxUpdateUIEvent& event )
675 {
676     event.Enable(m_fromUnicode);
677 }
678 #endif
679 
680 /*!
681  * wxEVT_UPDATE_UI event handler for wxID_OK
682  */
683 
OnOkUpdate(wxUpdateUIEvent & event)684 void wxSymbolPickerDialog::OnOkUpdate( wxUpdateUIEvent& event )
685 {
686     event.Enable(HasSelection());
687 }
688 
689 /// Set Unicode mode
SetUnicodeMode(bool unicodeMode)690 void wxSymbolPickerDialog::SetUnicodeMode(bool unicodeMode)
691 {
692 #if defined(__UNICODE__)
693     m_dontUpdate = true;
694     m_fromUnicode = unicodeMode;
695     if (m_fromUnicodeCtrl)
696         m_fromUnicodeCtrl->SetSelection(m_fromUnicode ? 1 : 0);
697     UpdateSymbolDisplay();
698     m_dontUpdate = false;
699 #else
700     wxUnusedVar(unicodeMode);
701 #endif
702 }
703 
704 /// Get the selected symbol character
GetSymbolChar() const705 int wxSymbolPickerDialog::GetSymbolChar() const
706 {
707     if (m_symbol.empty())
708         return -1;
709     else
710         return (int) m_symbol[0];
711 }
712 
713 
714 /*!
715  * Get bitmap resources
716  */
717 
GetBitmapResource(const wxString & name)718 wxBitmap wxSymbolPickerDialog::GetBitmapResource( const wxString& name )
719 {
720     // Bitmap retrieval
721 ////@begin wxSymbolPickerDialog bitmap retrieval
722     wxUnusedVar(name);
723     return wxNullBitmap;
724 ////@end wxSymbolPickerDialog bitmap retrieval
725 }
726 
727 /*!
728  * Get icon resources
729  */
730 
GetIconResource(const wxString & name)731 wxIcon wxSymbolPickerDialog::GetIconResource( const wxString& name )
732 {
733     // Icon retrieval
734 ////@begin wxSymbolPickerDialog icon retrieval
735     wxUnusedVar(name);
736     return wxNullIcon;
737 ////@end wxSymbolPickerDialog icon retrieval
738 }
739 
740 /*!
741  * The scrolling symbol list.
742  */
743 
744 // ----------------------------------------------------------------------------
745 // event tables
746 // ----------------------------------------------------------------------------
747 
748 wxBEGIN_EVENT_TABLE(wxSymbolListCtrl, wxVScrolledWindow)
749     EVT_PAINT(wxSymbolListCtrl::OnPaint)
750     EVT_SIZE(wxSymbolListCtrl::OnSize)
751 
752     EVT_KEY_DOWN(wxSymbolListCtrl::OnKeyDown)
753     EVT_LEFT_DOWN(wxSymbolListCtrl::OnLeftDown)
754     EVT_LEFT_DCLICK(wxSymbolListCtrl::OnLeftDClick)
755 wxEND_EVENT_TABLE()
756 
757 // ============================================================================
758 // implementation
759 // ============================================================================
760 
761 wxIMPLEMENT_ABSTRACT_CLASS(wxSymbolListCtrl, wxVScrolledWindow);
762 
763 // ----------------------------------------------------------------------------
764 // wxSymbolListCtrl creation
765 // ----------------------------------------------------------------------------
766 
Init()767 void wxSymbolListCtrl::Init()
768 {
769     m_current = wxNOT_FOUND;
770     m_doubleBuffer = NULL;
771     m_cellSize = wxSize(40, 40);
772     m_minSymbolValue = 0;
773     m_maxSymbolValue = 255;
774     m_symbolsPerLine = 0;
775     m_unicodeMode = false;
776 }
777 
Create(wxWindow * parent,wxWindowID id,const wxPoint & pos,const wxSize & size,long style,const wxString & name)778 bool wxSymbolListCtrl::Create(wxWindow *parent,
779                         wxWindowID id,
780                         const wxPoint& pos,
781                         const wxSize& size,
782                         long style,
783                         const wxString& name)
784 {
785     style |= wxWANTS_CHARS | wxFULL_REPAINT_ON_RESIZE;
786 
787     if ((style & wxBORDER_MASK) == wxBORDER_DEFAULT)
788         style |= wxBORDER_THEME;
789 
790     if ( !wxVScrolledWindow::Create(parent, id, pos, size, style, name) )
791         return false;
792 
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);
797 
798     // flicker-free drawing requires this
799     SetBackgroundStyle(wxBG_STYLE_PAINT);
800 
801     SetFont(*wxNORMAL_FONT);
802 
803     SetupCtrl();
804 
805     SetInitialSize(size);
806 
807     return true;
808 }
809 
~wxSymbolListCtrl()810 wxSymbolListCtrl::~wxSymbolListCtrl()
811 {
812     delete m_doubleBuffer;
813 }
814 
815 // ----------------------------------------------------------------------------
816 // selection handling
817 // ----------------------------------------------------------------------------
818 
IsSelected(int item) const819 bool wxSymbolListCtrl::IsSelected(int item) const
820 {
821     return item == m_current;
822 }
823 
DoSetCurrent(int current)824 bool wxSymbolListCtrl::DoSetCurrent(int current)
825 {
826     wxASSERT_MSG( current == wxNOT_FOUND ||
827                     (current >= m_minSymbolValue && current <= m_maxSymbolValue),
828                   wxT("wxSymbolListCtrl::DoSetCurrent(): invalid symbol value") );
829 
830     if ( current == m_current )
831     {
832         // nothing to do
833         return false;
834     }
835 
836     if ( m_current != wxNOT_FOUND )
837         RefreshRow(SymbolValueToLineNumber(m_current));
838 
839     m_current = current;
840 
841     if ( m_current != wxNOT_FOUND )
842     {
843         int lineNo = SymbolValueToLineNumber(m_current);
844 
845         // if the line is not visible at all, we scroll it into view but we
846         // don't need to refresh it -- it will be redrawn anyhow
847         if ( !IsVisible(lineNo) )
848         {
849             ScrollToRow(lineNo);
850         }
851         else // line is at least partly visible
852         {
853             // it is, indeed, only partly visible, so scroll it into view to
854             // make it entirely visible
855             while ( (unsigned)lineNo + 1 == GetVisibleEnd() &&
856                     ScrollToRow(GetVisibleBegin() + 1) )
857                 ;
858 
859             // but in any case refresh it as even if it was only partly visible
860             // before we need to redraw it entirely as its background changed
861             RefreshRow(lineNo);
862         }
863     }
864 
865     return true;
866 }
867 
SendSelectedEvent()868 void wxSymbolListCtrl::SendSelectedEvent()
869 {
870     wxCommandEvent event(wxEVT_LISTBOX, GetId());
871     event.SetEventObject(this);
872     event.SetInt(m_current);
873 
874     (void)GetEventHandler()->ProcessEvent(event);
875 }
876 
SetSelection(int selection)877 void wxSymbolListCtrl::SetSelection(int selection)
878 {
879     wxCHECK_RET( selection == wxNOT_FOUND ||
880                   (selection >= m_minSymbolValue && selection < m_maxSymbolValue),
881                   wxT("wxSymbolListCtrl::SetSelection(): invalid symbol value") );
882 
883     DoSetCurrent(selection);
884 }
885 
886 // ----------------------------------------------------------------------------
887 // wxSymbolListCtrl appearance parameters
888 // ----------------------------------------------------------------------------
889 
SetMargins(const wxPoint & pt)890 void wxSymbolListCtrl::SetMargins(const wxPoint& pt)
891 {
892     if ( pt != m_ptMargins )
893     {
894         m_ptMargins = pt;
895 
896         Refresh();
897     }
898 }
899 
SetSelectionBackground(const wxColour & col)900 void wxSymbolListCtrl::SetSelectionBackground(const wxColour& col)
901 {
902     m_colBgSel = col;
903 }
904 
905 // ----------------------------------------------------------------------------
906 // wxSymbolListCtrl painting
907 // ----------------------------------------------------------------------------
908 
OnGetRowHeight(size_t WXUNUSED (line)) const909 wxCoord wxSymbolListCtrl::OnGetRowHeight(size_t WXUNUSED(line)) const
910 {
911     return m_cellSize.y + 2*m_ptMargins.y + 1 /* for divider */ ;
912 }
913 
914 // draws a line of symbols
OnDrawItem(wxDC & dc,const wxRect & rect,size_t n) const915 void wxSymbolListCtrl::OnDrawItem(wxDC& dc, const wxRect& rect, size_t n) const
916 {
917     wxColour oldTextColour = dc.GetTextForeground();
918     int startSymbol = n*m_symbolsPerLine;
919 
920     int i;
921     for (i = 0; i < m_symbolsPerLine; i++)
922     {
923         bool resetColour = false;
924         int symbol = startSymbol+i;
925         if (symbol == m_current)
926         {
927             dc.SetBrush(wxBrush(m_colBgSel));
928 
929             dc.SetTextForeground(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT));
930             resetColour = true;
931 
932             wxPen oldPen = dc.GetPen();
933             dc.SetPen(*wxTRANSPARENT_PEN);
934 
935             dc.DrawRectangle(rect.x + i*m_cellSize.x, rect.y, m_cellSize.x, rect.y+rect.height);
936             dc.SetPen(oldPen);
937         }
938 
939         // Don't draw first line
940         if (i != 0)
941             dc.DrawLine(rect.x + i*m_cellSize.x, rect.y, i*m_cellSize.x, rect.y+rect.height);
942 
943         if (symbol >= m_minSymbolValue && symbol <= m_maxSymbolValue)
944         {
945             wxString text;
946             text << (wxChar) symbol;
947 
948             wxCoord w, h;
949             dc.GetTextExtent(text, & w, & h);
950 
951             int x = rect.x + i*m_cellSize.x + (m_cellSize.x - w)/2;
952             int y = rect.y + (m_cellSize.y - h)/2;
953             dc.DrawText(text, x, y);
954         }
955 
956         if (resetColour)
957             dc.SetTextForeground(oldTextColour);
958     }
959 
960     // Draw horizontal separator line
961     dc.DrawLine(rect.x, rect.y+rect.height-1, rect.x+rect.width, rect.y+rect.height-1);
962 }
963 
OnPaint(wxPaintEvent & WXUNUSED (event))964 void wxSymbolListCtrl::OnPaint(wxPaintEvent& WXUNUSED(event))
965 {
966     // If size is larger, recalculate double buffer bitmap
967     wxSize clientSize = GetClientSize();
968 
969     if ( !m_doubleBuffer ||
970          clientSize.x > m_doubleBuffer->GetWidth() ||
971          clientSize.y > m_doubleBuffer->GetHeight() )
972     {
973         delete m_doubleBuffer;
974         m_doubleBuffer = new wxBitmap(clientSize.x+25,clientSize.y+25);
975     }
976 
977     wxBufferedPaintDC dc(this,*m_doubleBuffer);
978 
979     // the update rectangle
980     wxRect rectUpdate = GetUpdateClientRect();
981 
982     // fill it with background colour
983     dc.SetBackground(GetBackgroundColour());
984     dc.Clear();
985 
986     // set the font to be displayed
987     dc.SetFont(GetFont());
988 
989     // the bounding rectangle of the current line
990     wxRect rectRow;
991     rectRow.width = clientSize.x;
992 
993     dc.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)));
994     dc.SetTextForeground(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
995     dc.SetBackgroundMode(wxBRUSHSTYLE_TRANSPARENT);
996 
997     // iterate over all visible lines
998     const size_t lineMax = GetVisibleEnd();
999     for ( size_t line = GetVisibleBegin(); line < lineMax; line++ )
1000     {
1001         const wxCoord hRow = OnGetRowHeight(line);
1002 
1003         rectRow.height = hRow;
1004 
1005         // and draw the ones which intersect the update rect
1006         if ( rectRow.Intersects(rectUpdate) )
1007         {
1008             // don't allow drawing outside of the lines rectangle
1009             wxDCClipper clip(dc, rectRow);
1010 
1011             wxRect rect = rectRow;
1012             rect.Deflate(m_ptMargins.x, m_ptMargins.y);
1013             OnDrawItem(dc, rect, line);
1014         }
1015         else // no intersection
1016         {
1017             if ( rectRow.GetTop() > rectUpdate.GetBottom() )
1018             {
1019                 // we are already below the update rect, no need to continue
1020                 // further
1021                 break;
1022             }
1023             //else: the next line may intersect the update rect
1024         }
1025 
1026         rectRow.y += hRow;
1027     }
1028 }
1029 
1030 // ============================================================================
1031 // wxSymbolListCtrl keyboard/mouse handling
1032 // ============================================================================
1033 
DoHandleItemClick(int item,int WXUNUSED (flags))1034 void wxSymbolListCtrl::DoHandleItemClick(int item, int WXUNUSED(flags))
1035 {
1036     if (m_current != item)
1037     {
1038         m_current = item;
1039         Refresh();
1040         SendSelectedEvent();
1041     }
1042 }
1043 
1044 // ----------------------------------------------------------------------------
1045 // keyboard handling
1046 // ----------------------------------------------------------------------------
1047 
OnKeyDown(wxKeyEvent & event)1048 void wxSymbolListCtrl::OnKeyDown(wxKeyEvent& event)
1049 {
1050     // flags for DoHandleItemClick()
1051     int flags = ItemClick_Kbd;
1052     int current = m_current;
1053     // m_current might not be wxNOT_FOUND if a Unicode symbol is selected
1054     // before the mode is changed to ANSI
1055     if( current < m_minSymbolValue || current > m_maxSymbolValue )
1056         current = m_minSymbolValue;
1057 
1058     // Original first visible row
1059     int firstVisibleRow = GetVisibleRowsBegin();
1060     // Current row
1061     int currentRow = SymbolValueToLineNumber( current );
1062     // Number of visible rows
1063     int visibleRows = GetClientSize().y / OnGetRowHeight( 0 );
1064 
1065     // Which row to scroll to
1066     int scrollToRow = firstVisibleRow;
1067     // Check if the current symbol is visible
1068     if( currentRow < firstVisibleRow )
1069         scrollToRow = firstVisibleRow = currentRow;
1070     else if( currentRow >= firstVisibleRow + visibleRows )
1071         scrollToRow = firstVisibleRow = currentRow - visibleRows + 1;
1072 
1073     switch ( event.GetKeyCode() )
1074     {
1075         case WXK_HOME:
1076             current = m_minSymbolValue;
1077             scrollToRow = 0;
1078             break;
1079 
1080         case WXK_END:
1081             current = m_maxSymbolValue;
1082             scrollToRow = GetRowCount();
1083             break;
1084 
1085         case WXK_DOWN:
1086             current += m_symbolsPerLine;
1087             if( currentRow >= firstVisibleRow + visibleRows - 1 )
1088                 scrollToRow++;
1089             break;
1090 
1091         case WXK_UP:
1092             current -= m_symbolsPerLine;
1093             if( currentRow == firstVisibleRow )
1094                 scrollToRow--;
1095             break;
1096 
1097         case WXK_LEFT:
1098             current--;
1099             // Scroll up at leftmost position
1100             if( current < scrollToRow * m_symbolsPerLine )
1101                 scrollToRow--;
1102             break;
1103 
1104         case WXK_RIGHT:
1105             current++;
1106             // Scroll down at rightmost position
1107             if( current >= ( scrollToRow + visibleRows ) * m_symbolsPerLine )
1108                 scrollToRow++;
1109             break;
1110 
1111         case WXK_PAGEDOWN:
1112             current += visibleRows * m_symbolsPerLine;
1113             scrollToRow += visibleRows;
1114             break;
1115 
1116         case WXK_PAGEUP:
1117             current -= visibleRows * m_symbolsPerLine;
1118             scrollToRow -= visibleRows;
1119             break;
1120 
1121         case WXK_TAB:
1122             // Since we are using wxWANTS_CHARS we need to send navigation
1123             // events for the tabs on MSW
1124             {
1125                 wxNavigationKeyEvent ne;
1126                 ne.SetDirection(!event.ShiftDown());
1127                 ne.SetCurrentFocus(this);
1128                 ne.SetEventObject(this);
1129                 GetParent()->GetEventHandler()->ProcessEvent(ne);
1130             }
1131             wxFALLTHROUGH;
1132 
1133         default:
1134             event.Skip();
1135             return;
1136     }
1137 
1138     if( current < m_minSymbolValue || current > m_maxSymbolValue )
1139         return;
1140     if ( event.ShiftDown() )
1141        flags |= ItemClick_Shift;
1142     if ( event.ControlDown() )
1143         flags |= ItemClick_Ctrl;
1144 
1145     DoHandleItemClick(current, flags);
1146     ScrollToRow( scrollToRow );
1147 }
1148 
1149 // ----------------------------------------------------------------------------
1150 // wxSymbolListCtrl mouse handling
1151 // ----------------------------------------------------------------------------
1152 
OnLeftDown(wxMouseEvent & event)1153 void wxSymbolListCtrl::OnLeftDown(wxMouseEvent& event)
1154 {
1155     SetFocus();
1156 
1157     int item = HitTest(event.GetPosition());
1158 
1159     if ( item != wxNOT_FOUND )
1160     {
1161         int flags = 0;
1162         if ( event.ShiftDown() )
1163            flags |= ItemClick_Shift;
1164 
1165         // under Mac Apple-click is used in the same way as Ctrl-click
1166         // elsewhere
1167 #ifdef __WXMAC__
1168         if ( event.MetaDown() )
1169 #else
1170         if ( event.ControlDown() )
1171 #endif
1172             flags |= ItemClick_Ctrl;
1173 
1174         DoHandleItemClick(item, flags);
1175     }
1176 }
1177 
OnLeftDClick(wxMouseEvent & eventMouse)1178 void wxSymbolListCtrl::OnLeftDClick(wxMouseEvent& eventMouse)
1179 {
1180     int item = HitTest(eventMouse.GetPosition());
1181     if ( item != wxNOT_FOUND )
1182     {
1183 
1184         // if item double-clicked was not yet selected, then treat
1185         // this event as a left-click instead
1186         if ( item == m_current )
1187         {
1188             wxCommandEvent event(wxEVT_LISTBOX_DCLICK, GetId());
1189             event.SetEventObject(this);
1190             event.SetInt(item);
1191 
1192             (void)GetEventHandler()->ProcessEvent(event);
1193         }
1194         else
1195         {
1196             OnLeftDown(eventMouse);
1197         }
1198 
1199     }
1200 }
1201 
1202 // calculate line number from symbol value
SymbolValueToLineNumber(int item)1203 int wxSymbolListCtrl::SymbolValueToLineNumber(int item)
1204 {
1205     return (int) (item/m_symbolsPerLine);
1206 }
1207 
1208 // initialise control from current min/max values
SetupCtrl(bool scrollToSelection)1209 void wxSymbolListCtrl::SetupCtrl(bool scrollToSelection)
1210 {
1211     wxSize sz = GetClientSize();
1212 
1213     m_symbolsPerLine = sz.x/(m_cellSize.x+m_ptMargins.x);
1214     int noLines = (1 + SymbolValueToLineNumber(m_maxSymbolValue));
1215 
1216     SetRowCount(noLines);
1217     Refresh();
1218 
1219     if (scrollToSelection && m_current != wxNOT_FOUND && m_current >= m_minSymbolValue && m_current <= m_maxSymbolValue)
1220     {
1221         ScrollToRow(SymbolValueToLineNumber(m_current));
1222     }
1223 }
1224 
1225 // make this item visible
EnsureVisible(int item)1226 void wxSymbolListCtrl::EnsureVisible(int item)
1227 {
1228     if (item != wxNOT_FOUND && item >= m_minSymbolValue && item <= m_maxSymbolValue)
1229     {
1230         ScrollToRow(SymbolValueToLineNumber(item));
1231     }
1232 }
1233 
1234 
1235 // hit testing
HitTest(const wxPoint & pt)1236 int wxSymbolListCtrl::HitTest(const wxPoint& pt)
1237 {
1238     wxCoord lineHeight = OnGetRowHeight(0);
1239 
1240     int atLine = GetVisibleBegin() + (pt.y/lineHeight);
1241     int symbol = (atLine*m_symbolsPerLine) + (pt.x/(m_cellSize.x+1));
1242 
1243     if (symbol >= m_minSymbolValue && symbol <= m_maxSymbolValue)
1244         return symbol;
1245 
1246     return wxNOT_FOUND;
1247 }
1248 
1249 // Respond to size change
OnSize(wxSizeEvent & event)1250 void wxSymbolListCtrl::OnSize(wxSizeEvent& event)
1251 {
1252     SetupCtrl();
1253     event.Skip();
1254 }
1255 
1256 // set the current font
SetFont(const wxFont & font)1257 bool wxSymbolListCtrl::SetFont(const wxFont& font)
1258 {
1259     wxVScrolledWindow::SetFont(font);
1260 
1261     SetupCtrl();
1262 
1263     return true;
1264 }
1265 
1266 // set Unicode/ASCII mode
SetUnicodeMode(bool unicodeMode)1267 void wxSymbolListCtrl::SetUnicodeMode(bool unicodeMode)
1268 {
1269     bool changed = false;
1270     if (unicodeMode && !m_unicodeMode)
1271     {
1272         changed = true;
1273 
1274         m_minSymbolValue = 0;
1275         m_maxSymbolValue = 65535;
1276     }
1277     else if (!unicodeMode && m_unicodeMode)
1278     {
1279         changed = true;
1280         m_minSymbolValue = 0;
1281         m_maxSymbolValue = 255;
1282     }
1283     m_unicodeMode = unicodeMode;
1284 
1285     if (changed)
1286         SetupCtrl();
1287 }
1288 
1289 // ----------------------------------------------------------------------------
1290 // use the same default attributes as wxListBox
1291 // ----------------------------------------------------------------------------
1292 
1293 //static
1294 wxVisualAttributes
GetClassDefaultAttributes(wxWindowVariant variant)1295 wxSymbolListCtrl::GetClassDefaultAttributes(wxWindowVariant variant)
1296 {
1297     return wxListBox::GetClassDefaultAttributes(variant);
1298 }
1299 
1300 /*!
1301  * wxEVT_BUTTON event handler for wxID_HELP
1302  */
1303 
OnHelpClick(wxCommandEvent & WXUNUSED (event))1304 void wxSymbolPickerDialog::OnHelpClick( wxCommandEvent& WXUNUSED(event) )
1305 {
1306     if ((GetHelpInfo().GetHelpId() != -1) && GetHelpInfo().GetUICustomization())
1307         ShowHelp(this);
1308 }
1309 
1310 /*!
1311  * wxEVT_UPDATE_UI event handler for wxID_HELP
1312  */
1313 
OnHelpUpdate(wxUpdateUIEvent & event)1314 void wxSymbolPickerDialog::OnHelpUpdate( wxUpdateUIEvent& event )
1315 {
1316     event.Enable((GetHelpInfo().GetHelpId() != -1) && GetHelpInfo().GetUICustomization());
1317 }
1318 
1319 #endif
1320     // wxUSE_RICHTEXT
1321