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