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