]> git.saurik.com Git - wxWidgets.git/blame - samples/text/text.cpp
Fix recreating of wxBitmapComboBox using untyped client data.
[wxWidgets.git] / samples / text / text.cpp
CommitLineData
02e8b87f 1/////////////////////////////////////////////////////////////////////////////
4aff28fc 2// Name: text.cpp
be5a51fb 3// Purpose: TextCtrl wxWidgets sample
02e8b87f
RR
4// Author: Robert Roebling
5// Modified by:
4aff28fc 6// Copyright: (c) Robert Roebling, Julian Smart, Vadim Zeitlin
526954c5 7// Licence: wxWindows licence
02e8b87f
RR
8/////////////////////////////////////////////////////////////////////////////
9
02e8b87f
RR
10// For compilers that support precompilation, includes "wx/wx.h".
11#include "wx/wxprec.h"
12
13#ifdef __BORLANDC__
14 #pragma hdrstop
15#endif
16
17#ifndef WX_PRECOMP
18 #include "wx/wx.h"
19#endif
20
21#if wxUSE_CLIPBOARD
22 #include "wx/dataobj.h"
23 #include "wx/clipbrd.h"
24#endif
25
0ddea946 26#if wxUSE_FILE
ae3dd4a5 27 #include "wx/file.h"
0ddea946
VZ
28#endif
29
02e8b87f
RR
30#if wxUSE_TOOLTIPS
31 #include "wx/tooltip.h"
32#endif
33
b6a0d8a2
VZ
34// We test for wxUSE_DRAG_AND_DROP also, because data objects may not be
35// implemented for compilers that can't cope with the OLE parts in
36// wxUSE_DRAG_AND_DROP.
37#if !wxUSE_DRAG_AND_DROP
38 #undef wxUSE_CLIPBOARD
39 #define wxUSE_CLIPBOARD 0
40#endif
41
e00a5d3c
JS
42#include "wx/colordlg.h"
43#include "wx/fontdlg.h"
ea180b18 44#include "wx/numdlg.h"
7fb3f3c4 45#include "wx/tokenzr.h"
e00a5d3c 46
e7092398 47#ifndef wxHAS_IMAGES_IN_RESOURCES
41f02b9a
FM
48 #include "../sample.xpm"
49#endif
50
02e8b87f
RR
51//----------------------------------------------------------------------
52// class definitions
53//----------------------------------------------------------------------
54
55class MyApp: public wxApp
56{
57public:
58 bool OnInit();
59};
60
61// a text ctrl which allows to call different wxTextCtrl functions
62// interactively by pressing function keys in it
63class MyTextCtrl : public wxTextCtrl
64{
65public:
66 MyTextCtrl(wxWindow *parent, wxWindowID id, const wxString &value,
67 const wxPoint &pos, const wxSize &size, int style = 0)
56c4a88b
VZ
68 : wxTextCtrl(parent, id, value, pos, size, style)
69 {
effbd41d 70 m_hasCapture = false;
56c4a88b 71 }
02e8b87f
RR
72
73 void OnKeyDown(wxKeyEvent& event);
74 void OnKeyUp(wxKeyEvent& event);
75 void OnChar(wxKeyEvent& event);
d7eee191 76
9ca03a57 77 void OnText(wxCommandEvent& event);
c5dd5a3d 78 void OnTextEnter(wxCommandEvent& event);
c57e3339 79 void OnTextURL(wxTextUrlEvent& event);
d7eee191
VZ
80 void OnTextMaxLen(wxCommandEvent& event);
81
78c91815
VZ
82 void OnTextCut(wxClipboardTextEvent & event);
83 void OnTextCopy(wxClipboardTextEvent & event);
84 void OnTextPaste(wxClipboardTextEvent & event);
85
4aff28fc 86 void OnMouseEvent(wxMouseEvent& event);
02e8b87f 87
94ccc254
VZ
88 void OnSetFocus(wxFocusEvent& event);
89 void OnKillFocus(wxFocusEvent& event);
90
56c4a88b
VZ
91 static bool ms_logKey;
92 static bool ms_logChar;
93 static bool ms_logMouse;
1ce58dc6 94 static bool ms_logText;
94ccc254 95 static bool ms_logFocus;
78c91815 96 static bool ms_logClip;
f152cf5a 97
02e8b87f 98private:
9a83f860 99 static inline wxChar GetChar(bool on, wxChar c) { return on ? c : wxT('-'); }
78c91815 100
94ccc254 101 void LogKeyEvent(const wxChar *name, wxKeyEvent& event) const;
78c91815 102 void LogClipEvent(const wxChar *what, wxClipboardTextEvent& event);
02e8b87f 103
56c4a88b
VZ
104 bool m_hasCapture;
105
02e8b87f
RR
106 DECLARE_EVENT_TABLE()
107};
108
109class MyPanel: public wxPanel
110{
111public:
112 MyPanel(wxFrame *frame, int x, int y, int w, int h);
925e9792
WS
113 virtual ~MyPanel()
114 {
b29903d4 115#if wxUSE_LOG
925e9792 116 delete wxLog::SetActiveTarget(m_logOld);
b29903d4
WS
117#endif // wxUSE_LOG
118 }
02e8b87f 119
b6a0d8a2
VZ
120#if wxUSE_CLIPBOARD
121 void DoPasteFromClipboard();
122 void DoCopyToClipboard();
123#endif // wxUSE_CLIPBOARD
124
cba1148d 125 void DoRemoveText();
cdd732de 126 void DoReplaceText();
29676ca0 127 void DoSelectText();
b6a0d8a2
VZ
128 void DoMoveToEndOfText();
129 void DoMoveToEndOfEntry();
6ce83213 130 void DoGetWindowCoordinates();
02e8b87f 131
5b07594a
VZ
132 // return true if currently text control has any selection
133 bool HasSelection() const
134 {
135 long from, to;
136 GetFocusedText()->GetSelection(&from, &to);
137 return from != to;
138 }
139
02e8b87f
RR
140 MyTextCtrl *m_text;
141 MyTextCtrl *m_password;
142 MyTextCtrl *m_enter;
143 MyTextCtrl *m_tab;
02e8b87f 144 MyTextCtrl *m_readonly;
d7eee191 145 MyTextCtrl *m_limited;
bb69661b 146
02e8b87f
RR
147 MyTextCtrl *m_multitext;
148 MyTextCtrl *m_horizontal;
02e8b87f 149
0ddea946
VZ
150 MyTextCtrl *m_textrich;
151
b29903d4 152#if wxUSE_LOG
02e8b87f 153 wxTextCtrl *m_log;
d847e69a 154 wxLog *m_logOld;
b29903d4 155#endif // wxUSE_LOG
d847e69a 156
89124b1a 157private:
5b07594a
VZ
158 // get the currently focused text control or return the default one
159 // (m_multitext) is no text ctrl has focus -- in any case, returns
160 // something non NULL
161 wxTextCtrl *GetFocusedText() const;
02e8b87f
RR
162};
163
164class MyFrame: public wxFrame
165{
166public:
ab1ca7b3 167 MyFrame(wxFrame *frame, const wxChar *title, int x, int y, int w, int h);
02e8b87f
RR
168
169 void OnQuit(wxCommandEvent& event);
170 void OnAbout(wxCommandEvent& event);
171#if wxUSE_TOOLTIPS
172 void OnSetTooltipDelay(wxCommandEvent& event);
173 void OnToggleTooltips(wxCommandEvent& event);
174#endif // wxUSE_TOOLTIPS
b6a0d8a2
VZ
175
176#if wxUSE_CLIPBOARD
656562d8 177 void OnPasteFromClipboard( wxCommandEvent& WXUNUSED(event) )
5b07594a 178 {
9a83f860 179 wxLogMessage(wxT("Pasting text from clipboard."));
5b07594a
VZ
180 m_panel->DoPasteFromClipboard();
181 }
656562d8 182 void OnCopyToClipboard( wxCommandEvent& WXUNUSED(event) )
5b07594a 183 {
9a83f860 184 wxLogMessage(wxT("Copying text to clipboard."));
5b07594a
VZ
185 m_panel->DoCopyToClipboard();
186 }
187
188 void OnUpdatePasteFromClipboard(wxUpdateUIEvent& event)
189 {
190 wxClipboardLocker lockClip;
191
192 event.Enable( wxTheClipboard->IsSupported(wxDF_TEXT) );
193 }
194
195 void OnUpdateCopyToClipboard(wxUpdateUIEvent& event)
196 {
197 event.Enable( m_panel->HasSelection() );
198 }
b6a0d8a2
VZ
199#endif // wxUSE_CLIPBOARD
200
be83461c
VZ
201 void OnAddTextLine(wxCommandEvent& WXUNUSED(event))
202 {
203 static int s_n = 0;
204 m_panel->m_textrich->AppendText(wxString::Format("Line %d\n", ++s_n));
205 }
206
656562d8 207 void OnAddTextFreeze( wxCommandEvent& WXUNUSED(event) )
eff00523 208 { DoAddText(true); }
656562d8 209 void OnAddText( wxCommandEvent& WXUNUSED(event) )
eff00523 210 { DoAddText(false); }
656562d8 211 void OnRemoveText( wxCommandEvent& WXUNUSED(event) )
cba1148d 212 { m_panel->DoRemoveText(); }
656562d8 213 void OnReplaceText( wxCommandEvent& WXUNUSED(event) )
cdd732de 214 { m_panel->DoReplaceText(); }
656562d8 215 void OnSelectText( wxCommandEvent& WXUNUSED(event) )
29676ca0 216 { m_panel->DoSelectText(); }
eff00523 217
656562d8 218 void OnMoveToEndOfText( wxCommandEvent& WXUNUSED(event) )
b6a0d8a2 219 { m_panel->DoMoveToEndOfText(); }
6ce83213
VZ
220
221 void OnGetWindowCoordinates( wxCommandEvent& WXUNUSED(event) )
222 { m_panel->DoGetWindowCoordinates(); }
223
656562d8 224 void OnMoveToEndOfEntry( wxCommandEvent& WXUNUSED(event) )
b6a0d8a2
VZ
225 { m_panel->DoMoveToEndOfEntry(); }
226
656562d8 227 void OnScrollLineDown(wxCommandEvent& WXUNUSED(event))
22670da4
VZ
228 {
229 if ( !m_panel->m_textrich->LineDown() )
43b2d5e7 230 {
9a83f860 231 wxLogMessage(wxT("Already at the bottom"));
43b2d5e7 232 }
22670da4
VZ
233 }
234
656562d8 235 void OnScrollLineUp(wxCommandEvent& WXUNUSED(event))
22670da4
VZ
236 {
237 if ( !m_panel->m_textrich->LineUp() )
43b2d5e7 238 {
9a83f860 239 wxLogMessage(wxT("Already at the top"));
43b2d5e7 240 }
22670da4
VZ
241 }
242
656562d8 243 void OnScrollPageDown(wxCommandEvent& WXUNUSED(event))
22670da4
VZ
244 {
245 if ( !m_panel->m_textrich->PageDown() )
43b2d5e7 246 {
9a83f860 247 wxLogMessage(wxT("Already at the bottom"));
43b2d5e7 248 }
22670da4
VZ
249 }
250
656562d8 251 void OnScrollPageUp(wxCommandEvent& WXUNUSED(event))
22670da4
VZ
252 {
253 if ( !m_panel->m_textrich->PageUp() )
43b2d5e7 254 {
9a83f860 255 wxLogMessage(wxT("Already at the top"));
43b2d5e7 256 }
22670da4 257 }
925e9792 258
ae25e5cc
RN
259 void OnGetLine(wxCommandEvent& WXUNUSED(event))
260 {
261 long nLine = wxGetNumberFromUser(wxT("Which line would you like to get?"),
262 wxT("Enter which line you would like to get"),
263 wxT("Get a line from the tabbed multiline text control") );
925e9792 264
ae25e5cc
RN
265 wxMessageBox(m_panel->m_tab->GetLineText(nLine));
266 }
267
268 void OnGetLineLength(wxCommandEvent& WXUNUSED(event))
269 {
270 long nLine = wxGetNumberFromUser(wxT("Which line would you like to get?"),
271 wxT("Enter which line you would like to get"),
272 wxT("Get length of a line from the tabbed multiline text control") );
925e9792
WS
273
274 wxMessageBox(wxString::Format(wxT("Length of line %i is:%i"),
ae25e5cc
RN
275 (int) nLine,
276 m_panel->m_tab->GetLineLength(nLine))
277 );
278 }
22670da4 279
b29903d4 280#if wxUSE_LOG
e66ad5c6 281 void OnLogClear(wxCommandEvent& event);
b29903d4 282#endif // wxUSE_LOG
0ddea946 283 void OnFileSave(wxCommandEvent& event);
b6a0d8a2 284 void OnFileLoad(wxCommandEvent& event);
e00a5d3c 285 void OnRichTextTest(wxCommandEvent& event);
b6a0d8a2 286
f6bcfd97
BP
287 void OnSetEditable(wxCommandEvent& event);
288 void OnSetEnabled(wxCommandEvent& event);
289
56c4a88b
VZ
290 void OnLogKey(wxCommandEvent& event)
291 {
292 MyTextCtrl::ms_logKey = event.IsChecked();
293 }
294
295 void OnLogChar(wxCommandEvent& event)
296 {
297 MyTextCtrl::ms_logChar = event.IsChecked();
298 }
299
300 void OnLogMouse(wxCommandEvent& event)
301 {
302 MyTextCtrl::ms_logMouse = event.IsChecked();
303 }
304
1ce58dc6
VZ
305 void OnLogText(wxCommandEvent& event)
306 {
307 MyTextCtrl::ms_logText = event.IsChecked();
308 }
309
94ccc254
VZ
310 void OnLogFocus(wxCommandEvent& event)
311 {
312 MyTextCtrl::ms_logFocus = event.IsChecked();
313 }
314
78c91815
VZ
315 void OnLogClip(wxCommandEvent& event)
316 {
317 MyTextCtrl::ms_logClip = event.IsChecked();
318 }
319
656562d8 320 void OnSetText(wxCommandEvent& WXUNUSED(event))
60f52320 321 {
9a83f860 322 m_panel->m_text->SetValue(wxT("Hello, world! (what else did you expect?)"));
7ddc9343
VZ
323 }
324
325 void OnChangeText(wxCommandEvent& WXUNUSED(event))
326 {
9a83f860 327 m_panel->m_text->ChangeValue(wxT("Changed, not set: no event"));
60f52320
VZ
328 }
329
02e8b87f
RR
330 void OnIdle( wxIdleEvent& event );
331
332private:
eff00523
VZ
333 void DoAddText(bool freeze)
334 {
cdd732de 335 wxTextCtrl * const text = m_panel->m_textrich;
cdd732de 336
eff00523
VZ
337 if ( freeze )
338 text->Freeze();
339
53aa9c77
VS
340 text->Clear();
341
eff00523 342 for ( int i = 0; i < 100; i++ )
0146a47e 343 {
4693b20c 344 text->AppendText(wxString::Format(wxT("Line %i\n"), i));
0146a47e 345 }
eff00523 346
53aa9c77
VS
347 text->SetInsertionPoint(0);
348
eff00523
VZ
349 if ( freeze )
350 text->Thaw();
351 }
352
b6a0d8a2
VZ
353 MyPanel *m_panel;
354
02e8b87f
RR
355 DECLARE_EVENT_TABLE()
356};
357
e00a5d3c
JS
358/*
359 * RichTextFrame is used to demonstrate rich text behaviour
360 */
361
362class RichTextFrame: public wxFrame
363{
364public:
365 RichTextFrame(wxWindow* parent, const wxString& title);
366
367// Event handlers
368
369 void OnClose(wxCommandEvent& event);
80185c6c 370 void OnIdle(wxIdleEvent& event);
e00a5d3c
JS
371 void OnLeftAlign(wxCommandEvent& event);
372 void OnRightAlign(wxCommandEvent& event);
373 void OnJustify(wxCommandEvent& event);
374 void OnCentre(wxCommandEvent& event);
375 void OnChangeFont(wxCommandEvent& event);
376 void OnChangeTextColour(wxCommandEvent& event);
377 void OnChangeBackgroundColour(wxCommandEvent& event);
378 void OnLeftIndent(wxCommandEvent& event);
379 void OnRightIndent(wxCommandEvent& event);
7fb3f3c4 380 void OnTabStops(wxCommandEvent& event);
e00a5d3c
JS
381
382private:
383 wxTextCtrl *m_textCtrl;
80185c6c 384 long m_currentPosition;
e00a5d3c
JS
385
386 DECLARE_EVENT_TABLE()
387};
388
02e8b87f
RR
389//----------------------------------------------------------------------
390// main()
391//----------------------------------------------------------------------
392
393IMPLEMENT_APP(MyApp)
394
395//----------------------------------------------------------------------
396// MyApp
397//----------------------------------------------------------------------
398
399enum
400{
91b07357
JS
401 TEXT_QUIT = wxID_EXIT,
402 TEXT_ABOUT = wxID_ABOUT,
403 TEXT_LOAD = 101,
ae3dd4a5 404 TEXT_SAVE,
e66ad5c6 405 TEXT_CLEAR,
e00a5d3c 406 TEXT_RICH_TEXT_TEST,
b6a0d8a2
VZ
407
408 // clipboard menu
409 TEXT_CLIPBOARD_COPY = 200,
410 TEXT_CLIPBOARD_PASTE,
78c91815 411 TEXT_CLIPBOARD_VETO,
02e8b87f
RR
412
413 // tooltip menu
b6a0d8a2
VZ
414 TEXT_TOOLTIPS_SETDELAY = 300,
415 TEXT_TOOLTIPS_ENABLE,
416
f6bcfd97 417 // text menu
eff00523
VZ
418 TEXT_ADD_SOME = 400,
419 TEXT_ADD_FREEZE,
be83461c 420 TEXT_ADD_LINE,
eff00523 421 TEXT_MOVE_ENDTEXT,
6ce83213 422 TEXT_GET_WINDOW_COORD,
f6bcfd97
BP
423 TEXT_MOVE_ENDENTRY,
424 TEXT_SET_EDITABLE,
22670da4
VZ
425 TEXT_SET_ENABLED,
426 TEXT_LINE_DOWN,
427 TEXT_LINE_UP,
428 TEXT_PAGE_DOWN,
429 TEXT_PAGE_UP,
925e9792 430
ae25e5cc
RN
431 TEXT_GET_LINE,
432 TEXT_GET_LINELENGTH,
925e9792 433
cba1148d 434 TEXT_REMOVE,
cdd732de 435 TEXT_REPLACE,
29676ca0 436 TEXT_SELECT,
60f52320 437 TEXT_SET,
7ddc9343 438 TEXT_CHANGE,
56c4a88b
VZ
439
440 // log menu
441 TEXT_LOG_KEY,
442 TEXT_LOG_CHAR,
443 TEXT_LOG_MOUSE,
1ce58dc6 444 TEXT_LOG_TEXT,
94ccc254 445 TEXT_LOG_FOCUS,
78c91815 446 TEXT_LOG_CLIP,
56c4a88b
VZ
447
448 TEXT_END
02e8b87f
RR
449};
450
451bool MyApp::OnInit()
452{
45e6e6f8
VZ
453 if ( !wxApp::OnInit() )
454 return false;
455
02e8b87f
RR
456 // Create the main frame window
457 MyFrame *frame = new MyFrame((wxFrame *) NULL,
9a83f860 458 wxT("Text wxWidgets sample"), 50, 50, 700, 550);
89124b1a 459 frame->SetSizeHints( 500, 400 );
02e8b87f 460
02e8b87f 461 wxMenu *file_menu = new wxMenu;
9a83f860
VZ
462 file_menu->Append(TEXT_SAVE, wxT("&Save file\tCtrl-S"),
463 wxT("Save the text control contents to file"));
464 file_menu->Append(TEXT_LOAD, wxT("&Load file\tCtrl-O"),
465 wxT("Load the sample file into text control"));
b6a0d8a2 466 file_menu->AppendSeparator();
9a83f860 467 file_menu->Append(TEXT_RICH_TEXT_TEST, wxT("Show Rich Text Editor"));
e00a5d3c 468 file_menu->AppendSeparator();
9a83f860 469 file_menu->Append(TEXT_ABOUT, wxT("&About\tAlt-A"));
b6a0d8a2 470 file_menu->AppendSeparator();
9a83f860 471 file_menu->Append(TEXT_QUIT, wxT("E&xit\tAlt-X"), wxT("Quit this sample"));
02e8b87f
RR
472
473 wxMenuBar *menu_bar = new wxMenuBar( wxMB_DOCKABLE );
9a83f860 474 menu_bar->Append(file_menu, wxT("&File"));
02e8b87f
RR
475
476#if wxUSE_TOOLTIPS
477 wxMenu *tooltip_menu = new wxMenu;
9a83f860 478 tooltip_menu->Append(TEXT_TOOLTIPS_SETDELAY, wxT("Set &delay\tCtrl-D"));
02e8b87f 479 tooltip_menu->AppendSeparator();
9a83f860
VZ
480 tooltip_menu->Append(TEXT_TOOLTIPS_ENABLE, wxT("&Toggle tooltips\tCtrl-T"),
481 wxT("enable/disable tooltips"), true);
effbd41d 482 tooltip_menu->Check(TEXT_TOOLTIPS_ENABLE, true);
9a83f860 483 menu_bar->Append(tooltip_menu, wxT("&Tooltips"));
02e8b87f
RR
484#endif // wxUSE_TOOLTIPS
485
b6a0d8a2 486#if wxUSE_CLIPBOARD
5b07594a
VZ
487 // notice that we use non default accelerators on purpose here to compare
488 // their behaviour with the built in handling of standard Ctrl/Cmd-C/V
b6a0d8a2 489 wxMenu *menuClipboard = new wxMenu;
9a83f860
VZ
490 menuClipboard->Append(TEXT_CLIPBOARD_COPY, wxT("&Copy\tCtrl-Shift-C"),
491 wxT("Copy the selection to the clipboard"));
492 menuClipboard->Append(TEXT_CLIPBOARD_PASTE, wxT("&Paste\tCtrl-Shift-V"),
493 wxT("Paste from clipboard to the text control"));
78c91815 494 menuClipboard->AppendSeparator();
9a83f860
VZ
495 menuClipboard->AppendCheckItem(TEXT_CLIPBOARD_VETO, wxT("Vet&o\tCtrl-Shift-O"),
496 wxT("Veto all clipboard operations"));
497 menu_bar->Append(menuClipboard, wxT("&Clipboard"));
b6a0d8a2
VZ
498#endif // wxUSE_CLIPBOARD
499
f6bcfd97 500 wxMenu *menuText = new wxMenu;
9a83f860
VZ
501 menuText->Append(TEXT_ADD_SOME, wxT("&Append some text\tCtrl-A"));
502 menuText->Append(TEXT_ADD_FREEZE, wxT("&Append text with freeze/thaw\tShift-Ctrl-A"));
503 menuText->Append(TEXT_ADD_LINE, wxT("Append a new &line\tAlt-Shift-A"));
504 menuText->Append(TEXT_REMOVE, wxT("&Remove first 10 characters\tCtrl-Y"));
505 menuText->Append(TEXT_REPLACE, wxT("&Replace characters 4 to 8 with ABC\tCtrl-R"));
506 menuText->Append(TEXT_SELECT, wxT("&Select characters 4 to 8\tCtrl-I"));
507 menuText->Append(TEXT_SET, wxT("&Set the first text zone value\tCtrl-E"));
508 menuText->Append(TEXT_CHANGE, wxT("&Change the first text zone value\tShift-Ctrl-E"));
cba1148d 509 menuText->AppendSeparator();
9a83f860
VZ
510 menuText->Append(TEXT_MOVE_ENDTEXT, wxT("Move cursor to the end of &text"));
511 menuText->Append(TEXT_MOVE_ENDENTRY, wxT("Move cursor to the end of &entry"));
512 menuText->AppendCheckItem(TEXT_SET_EDITABLE, wxT("Toggle &editable state"));
513 menuText->AppendCheckItem(TEXT_SET_ENABLED, wxT("Toggle e&nabled state"));
effbd41d
WS
514 menuText->Check(TEXT_SET_EDITABLE, true);
515 menuText->Check(TEXT_SET_ENABLED, true);
22670da4 516 menuText->AppendSeparator();
9a83f860
VZ
517 menuText->Append(TEXT_LINE_DOWN, wxT("Scroll text one line down"));
518 menuText->Append(TEXT_LINE_UP, wxT("Scroll text one line up"));
519 menuText->Append(TEXT_PAGE_DOWN, wxT("Scroll text one page down"));
520 menuText->Append(TEXT_PAGE_UP, wxT("Scroll text one page up"));
6ce83213 521 menuText->Append(TEXT_GET_WINDOW_COORD, wxT("Get window coordinates"));
ae25e5cc 522 menuText->AppendSeparator();
9a83f860
VZ
523 menuText->Append(TEXT_GET_LINE, wxT("Get the text of a line of the tabbed multiline"));
524 menuText->Append(TEXT_GET_LINELENGTH, wxT("Get the length of a line of the tabbed multiline"));
525 menu_bar->Append(menuText, wxT("Te&xt"));
56c4a88b 526
b29903d4 527#if wxUSE_LOG
56c4a88b 528 wxMenu *menuLog = new wxMenu;
9a83f860
VZ
529 menuLog->AppendCheckItem(TEXT_LOG_KEY, wxT("Log &key events"));
530 menuLog->AppendCheckItem(TEXT_LOG_CHAR, wxT("Log &char events"));
531 menuLog->AppendCheckItem(TEXT_LOG_MOUSE, wxT("Log &mouse events"));
532 menuLog->AppendCheckItem(TEXT_LOG_TEXT, wxT("Log &text events"));
533 menuLog->AppendCheckItem(TEXT_LOG_FOCUS, wxT("Log &focus events"));
534 menuLog->AppendCheckItem(TEXT_LOG_CLIP, wxT("Log clip&board events"));
56c4a88b 535 menuLog->AppendSeparator();
9a83f860
VZ
536 menuLog->Append(TEXT_CLEAR, wxT("&Clear the log\tCtrl-L"),
537 wxT("Clear the log window contents"));
94ccc254
VZ
538
539 // select only the interesting events by default
78c91815 540 MyTextCtrl::ms_logClip =
effbd41d 541 MyTextCtrl::ms_logText = true;
b29903d4 542
c9539346
VZ
543 menuLog->Check(TEXT_LOG_KEY, MyTextCtrl::ms_logKey);
544 menuLog->Check(TEXT_LOG_CHAR, MyTextCtrl::ms_logChar);
545 menuLog->Check(TEXT_LOG_TEXT, MyTextCtrl::ms_logText);
546
9a83f860 547 menu_bar->Append(menuLog, wxT("&Log"));
b29903d4 548#endif // wxUSE_LOG
b6a0d8a2 549
02e8b87f
RR
550 frame->SetMenuBar(menu_bar);
551
effbd41d 552 frame->Show(true);
02e8b87f 553
02e8b87f 554 // report success
effbd41d 555 return true;
02e8b87f
RR
556}
557
558//----------------------------------------------------------------------
559// MyTextCtrl
560//----------------------------------------------------------------------
561
562BEGIN_EVENT_TABLE(MyTextCtrl, wxTextCtrl)
563 EVT_KEY_DOWN(MyTextCtrl::OnKeyDown)
564 EVT_KEY_UP(MyTextCtrl::OnKeyUp)
565 EVT_CHAR(MyTextCtrl::OnChar)
d7eee191 566
effbd41d 567 EVT_TEXT(wxID_ANY, MyTextCtrl::OnText)
c5dd5a3d 568 EVT_TEXT_ENTER(wxID_ANY, MyTextCtrl::OnTextEnter)
effbd41d
WS
569 EVT_TEXT_URL(wxID_ANY, MyTextCtrl::OnTextURL)
570 EVT_TEXT_MAXLEN(wxID_ANY, MyTextCtrl::OnTextMaxLen)
78c91815
VZ
571 EVT_TEXT_CUT(wxID_ANY, MyTextCtrl::OnTextCut)
572 EVT_TEXT_COPY(wxID_ANY, MyTextCtrl::OnTextCopy)
573 EVT_TEXT_PASTE(wxID_ANY, MyTextCtrl::OnTextPaste)
d7eee191 574
4aff28fc 575 EVT_MOUSE_EVENTS(MyTextCtrl::OnMouseEvent)
94ccc254
VZ
576
577 EVT_SET_FOCUS(MyTextCtrl::OnSetFocus)
578 EVT_KILL_FOCUS(MyTextCtrl::OnKillFocus)
02e8b87f
RR
579END_EVENT_TABLE()
580
effbd41d
WS
581bool MyTextCtrl::ms_logKey = false;
582bool MyTextCtrl::ms_logChar = false;
583bool MyTextCtrl::ms_logMouse = false;
584bool MyTextCtrl::ms_logText = false;
585bool MyTextCtrl::ms_logFocus = false;
78c91815 586bool MyTextCtrl::ms_logClip = false;
56c4a88b 587
94ccc254 588void MyTextCtrl::LogKeyEvent(const wxChar *name, wxKeyEvent& event) const
02e8b87f
RR
589{
590 wxString key;
b1d4dd7a 591 long keycode = event.GetKeyCode();
02e8b87f
RR
592 {
593 switch ( keycode )
594 {
9a83f860
VZ
595 case WXK_BACK: key = wxT("BACK"); break;
596 case WXK_TAB: key = wxT("TAB"); break;
597 case WXK_RETURN: key = wxT("RETURN"); break;
598 case WXK_ESCAPE: key = wxT("ESCAPE"); break;
599 case WXK_SPACE: key = wxT("SPACE"); break;
600 case WXK_DELETE: key = wxT("DELETE"); break;
601 case WXK_START: key = wxT("START"); break;
602 case WXK_LBUTTON: key = wxT("LBUTTON"); break;
603 case WXK_RBUTTON: key = wxT("RBUTTON"); break;
604 case WXK_CANCEL: key = wxT("CANCEL"); break;
605 case WXK_MBUTTON: key = wxT("MBUTTON"); break;
606 case WXK_CLEAR: key = wxT("CLEAR"); break;
607 case WXK_SHIFT: key = wxT("SHIFT"); break;
608 case WXK_ALT: key = wxT("ALT"); break;
609 case WXK_CONTROL: key = wxT("CONTROL"); break;
610 case WXK_MENU: key = wxT("MENU"); break;
611 case WXK_PAUSE: key = wxT("PAUSE"); break;
612 case WXK_CAPITAL: key = wxT("CAPITAL"); break;
613 case WXK_END: key = wxT("END"); break;
614 case WXK_HOME: key = wxT("HOME"); break;
615 case WXK_LEFT: key = wxT("LEFT"); break;
616 case WXK_UP: key = wxT("UP"); break;
617 case WXK_RIGHT: key = wxT("RIGHT"); break;
618 case WXK_DOWN: key = wxT("DOWN"); break;
619 case WXK_SELECT: key = wxT("SELECT"); break;
620 case WXK_PRINT: key = wxT("PRINT"); break;
621 case WXK_EXECUTE: key = wxT("EXECUTE"); break;
622 case WXK_SNAPSHOT: key = wxT("SNAPSHOT"); break;
623 case WXK_INSERT: key = wxT("INSERT"); break;
624 case WXK_HELP: key = wxT("HELP"); break;
625 case WXK_NUMPAD0: key = wxT("NUMPAD0"); break;
626 case WXK_NUMPAD1: key = wxT("NUMPAD1"); break;
627 case WXK_NUMPAD2: key = wxT("NUMPAD2"); break;
628 case WXK_NUMPAD3: key = wxT("NUMPAD3"); break;
629 case WXK_NUMPAD4: key = wxT("NUMPAD4"); break;
630 case WXK_NUMPAD5: key = wxT("NUMPAD5"); break;
631 case WXK_NUMPAD6: key = wxT("NUMPAD6"); break;
632 case WXK_NUMPAD7: key = wxT("NUMPAD7"); break;
633 case WXK_NUMPAD8: key = wxT("NUMPAD8"); break;
634 case WXK_NUMPAD9: key = wxT("NUMPAD9"); break;
635 case WXK_MULTIPLY: key = wxT("MULTIPLY"); break;
636 case WXK_ADD: key = wxT("ADD"); break;
637 case WXK_SEPARATOR: key = wxT("SEPARATOR"); break;
638 case WXK_SUBTRACT: key = wxT("SUBTRACT"); break;
639 case WXK_DECIMAL: key = wxT("DECIMAL"); break;
640 case WXK_DIVIDE: key = wxT("DIVIDE"); break;
641 case WXK_F1: key = wxT("F1"); break;
642 case WXK_F2: key = wxT("F2"); break;
643 case WXK_F3: key = wxT("F3"); break;
644 case WXK_F4: key = wxT("F4"); break;
645 case WXK_F5: key = wxT("F5"); break;
646 case WXK_F6: key = wxT("F6"); break;
647 case WXK_F7: key = wxT("F7"); break;
648 case WXK_F8: key = wxT("F8"); break;
649 case WXK_F9: key = wxT("F9"); break;
650 case WXK_F10: key = wxT("F10"); break;
651 case WXK_F11: key = wxT("F11"); break;
652 case WXK_F12: key = wxT("F12"); break;
653 case WXK_F13: key = wxT("F13"); break;
654 case WXK_F14: key = wxT("F14"); break;
655 case WXK_F15: key = wxT("F15"); break;
656 case WXK_F16: key = wxT("F16"); break;
657 case WXK_F17: key = wxT("F17"); break;
658 case WXK_F18: key = wxT("F18"); break;
659 case WXK_F19: key = wxT("F19"); break;
660 case WXK_F20: key = wxT("F20"); break;
661 case WXK_F21: key = wxT("F21"); break;
662 case WXK_F22: key = wxT("F22"); break;
663 case WXK_F23: key = wxT("F23"); break;
664 case WXK_F24: key = wxT("F24"); break;
665 case WXK_NUMLOCK: key = wxT("NUMLOCK"); break;
666 case WXK_SCROLL: key = wxT("SCROLL"); break;
667 case WXK_PAGEUP: key = wxT("PAGEUP"); break;
668 case WXK_PAGEDOWN: key = wxT("PAGEDOWN"); break;
669 case WXK_NUMPAD_SPACE: key = wxT("NUMPAD_SPACE"); break;
670 case WXK_NUMPAD_TAB: key = wxT("NUMPAD_TAB"); break;
671 case WXK_NUMPAD_ENTER: key = wxT("NUMPAD_ENTER"); break;
672 case WXK_NUMPAD_F1: key = wxT("NUMPAD_F1"); break;
673 case WXK_NUMPAD_F2: key = wxT("NUMPAD_F2"); break;
674 case WXK_NUMPAD_F3: key = wxT("NUMPAD_F3"); break;
675 case WXK_NUMPAD_F4: key = wxT("NUMPAD_F4"); break;
676 case WXK_NUMPAD_HOME: key = wxT("NUMPAD_HOME"); break;
677 case WXK_NUMPAD_LEFT: key = wxT("NUMPAD_LEFT"); break;
678 case WXK_NUMPAD_UP: key = wxT("NUMPAD_UP"); break;
679 case WXK_NUMPAD_RIGHT: key = wxT("NUMPAD_RIGHT"); break;
680 case WXK_NUMPAD_DOWN: key = wxT("NUMPAD_DOWN"); break;
681 case WXK_NUMPAD_PAGEUP: key = wxT("NUMPAD_PAGEUP"); break;
682 case WXK_NUMPAD_PAGEDOWN: key = wxT("NUMPAD_PAGEDOWN"); break;
683 case WXK_NUMPAD_END: key = wxT("NUMPAD_END"); break;
684 case WXK_NUMPAD_BEGIN: key = wxT("NUMPAD_BEGIN"); break;
685 case WXK_NUMPAD_INSERT: key = wxT("NUMPAD_INSERT"); break;
686 case WXK_NUMPAD_DELETE: key = wxT("NUMPAD_DELETE"); break;
687 case WXK_NUMPAD_EQUAL: key = wxT("NUMPAD_EQUAL"); break;
688 case WXK_NUMPAD_MULTIPLY: key = wxT("NUMPAD_MULTIPLY"); break;
689 case WXK_NUMPAD_ADD: key = wxT("NUMPAD_ADD"); break;
690 case WXK_NUMPAD_SEPARATOR: key = wxT("NUMPAD_SEPARATOR"); break;
691 case WXK_NUMPAD_SUBTRACT: key = wxT("NUMPAD_SUBTRACT"); break;
692 case WXK_NUMPAD_DECIMAL: key = wxT("NUMPAD_DECIMAL"); break;
02e8b87f 693
4afd7529 694 default:
89124b1a
RR
695 {
696 if ( wxIsprint((int)keycode) )
9a83f860 697 key.Printf(wxT("'%c'"), (char)keycode);
1ce58dc6 698 else if ( keycode > 0 && keycode < 27 )
9a83f860 699 key.Printf(_("Ctrl-%c"), wxT('A') + keycode - 1);
89124b1a 700 else
9a83f860 701 key.Printf(wxT("unknown (%ld)"), keycode);
4afd7529 702 }
02e8b87f
RR
703 }
704 }
705
0d9b2c16 706#if wxUSE_UNICODE
9a83f860 707 key += wxString::Format(wxT(" (Unicode: %#04x)"), event.GetUnicodeKey());
0d9b2c16
VZ
708#endif // wxUSE_UNICODE
709
9a83f860 710 wxLogMessage( wxT("%s event: %s (flags = %c%c%c%c)"),
02e8b87f
RR
711 name,
712 key.c_str(),
9a83f860
VZ
713 GetChar( event.ControlDown(), wxT('C') ),
714 GetChar( event.AltDown(), wxT('A') ),
715 GetChar( event.ShiftDown(), wxT('S') ),
716 GetChar( event.MetaDown(), wxT('M') ) );
02e8b87f
RR
717}
718
c57e3339
VZ
719static wxString GetMouseEventDesc(const wxMouseEvent& ev)
720{
721 // click event
722 wxString button;
723 bool dbl, up;
724 if ( ev.LeftDown() || ev.LeftUp() || ev.LeftDClick() )
725 {
9a83f860 726 button = wxT("Left");
c57e3339
VZ
727 dbl = ev.LeftDClick();
728 up = ev.LeftUp();
729 }
730 else if ( ev.MiddleDown() || ev.MiddleUp() || ev.MiddleDClick() )
731 {
9a83f860 732 button = wxT("Middle");
c57e3339
VZ
733 dbl = ev.MiddleDClick();
734 up = ev.MiddleUp();
735 }
736 else if ( ev.RightDown() || ev.RightUp() || ev.RightDClick() )
737 {
9a83f860 738 button = wxT("Right");
c57e3339
VZ
739 dbl = ev.RightDClick();
740 up = ev.RightUp();
741 }
dcd6f736
VZ
742 else if ( ev.Aux1Down() || ev.Aux1Up() || ev.Aux1DClick() )
743 {
744 button = wxT("Aux1");
745 dbl = ev.Aux1DClick();
746 up = ev.Aux1Up();
747 }
748 else if ( ev.Aux2Down() || ev.Aux2Up() || ev.Aux2DClick() )
749 {
750 button = wxT("Aux2");
751 dbl = ev.Aux2DClick();
752 up = ev.Aux2Up();
753 }
754 else if ( ev.GetWheelRotation() )
755 {
756 return wxString::Format("Wheel rotation %+d", ev.GetWheelRotation());
757 }
c57e3339
VZ
758 else
759 {
9a83f860 760 return wxT("Unknown mouse event");
c57e3339 761 }
dcd6f736 762 wxASSERT(!(dbl && up));
c57e3339 763
9a83f860 764 return wxString::Format(wxT("%s mouse button %s"),
c57e3339 765 button.c_str(),
9a83f860
VZ
766 dbl ? wxT("double clicked")
767 : up ? wxT("released") : wxT("clicked"));
c57e3339
VZ
768}
769
4aff28fc
VZ
770void MyTextCtrl::OnMouseEvent(wxMouseEvent& ev)
771{
56c4a88b
VZ
772 ev.Skip();
773
1ce58dc6 774 if ( !ms_logMouse )
56c4a88b
VZ
775 return;
776
4aff28fc
VZ
777 if ( !ev.Moving() )
778 {
779 wxString msg;
780 if ( ev.Entering() )
781 {
9a83f860 782 msg = wxT("Mouse entered the window");
4aff28fc
VZ
783 }
784 else if ( ev.Leaving() )
785 {
9a83f860 786 msg = wxT("Mouse left the window");
4aff28fc
VZ
787 }
788 else
789 {
c57e3339 790 msg = GetMouseEventDesc(ev);
4aff28fc
VZ
791 }
792
9a83f860 793 msg << wxT(" at (") << ev.GetX() << wxT(", ") << ev.GetY() << wxT(") ");
692c9b86
VZ
794
795 long pos;
796 wxTextCtrlHitTestResult rc = HitTest(ev.GetPosition(), &pos);
797 if ( rc != wxTE_HT_UNKNOWN )
798 {
9a83f860 799 msg << wxT("at position ") << pos << wxT(' ');
692c9b86
VZ
800 }
801
9a83f860
VZ
802 msg << wxT("[Flags: ")
803 << GetChar( ev.LeftIsDown(), wxT('1') )
804 << GetChar( ev.MiddleIsDown(), wxT('2') )
805 << GetChar( ev.RightIsDown(), wxT('3') )
dcd6f736
VZ
806 << GetChar( ev.Aux1IsDown(), wxT('x') )
807 << GetChar( ev.Aux2IsDown(), wxT('X') )
9a83f860
VZ
808 << GetChar( ev.ControlDown(), wxT('C') )
809 << GetChar( ev.AltDown(), wxT('A') )
810 << GetChar( ev.ShiftDown(), wxT('S') )
811 << GetChar( ev.MetaDown(), wxT('M') )
812 << wxT(']');
4aff28fc
VZ
813
814 wxLogMessage(msg);
815 }
816 //else: we're not interested in mouse move events
817}
818
94ccc254
VZ
819void MyTextCtrl::OnSetFocus(wxFocusEvent& event)
820{
821 if ( ms_logFocus )
43b2d5e7 822 {
eba33006 823 wxLogMessage( wxT("%p got focus."), this);
43b2d5e7 824 }
94ccc254
VZ
825
826 event.Skip();
827}
828
829void MyTextCtrl::OnKillFocus(wxFocusEvent& event)
830{
831 if ( ms_logFocus )
43b2d5e7 832 {
eba33006 833 wxLogMessage( wxT("%p lost focus"), this);
43b2d5e7 834 }
94ccc254
VZ
835
836 event.Skip();
837}
838
9ca03a57 839void MyTextCtrl::OnText(wxCommandEvent& event)
02e8b87f 840{
1ce58dc6
VZ
841 if ( !ms_logText )
842 return;
843
9ca03a57 844 MyTextCtrl *win = (MyTextCtrl *)event.GetEventObject();
9a83f860
VZ
845 const wxChar *changeVerb = win->IsModified() ? wxT("changed")
846 : wxT("set by program");
ae3dd4a5
VZ
847 const wxChar *data = (const wxChar *)(win->GetClientData());
848 if ( data )
849 {
9a83f860 850 wxLogMessage(wxT("Text %s in control \"%s\""), changeVerb, data);
ae3dd4a5 851 }
f6bcfd97
BP
852 else
853 {
9a83f860 854 wxLogMessage(wxT("Text %s in some control"), changeVerb);
f6bcfd97 855 }
9ca03a57
VZ
856}
857
c5dd5a3d
VZ
858void MyTextCtrl::OnTextEnter(wxCommandEvent& event)
859{
860 if ( !ms_logText )
861 return;
862
863 MyTextCtrl *win = (MyTextCtrl *)event.GetEventObject();
864 const wxChar *data = (const wxChar *)(win->GetClientData());
865 if ( data )
866 {
9a83f860 867 wxLogMessage(wxT("Enter pressed in control '%s'"), data);
c5dd5a3d
VZ
868 }
869 else
870 {
9a83f860 871 wxLogMessage(wxT("Enter pressed in some control"));
c5dd5a3d
VZ
872 }
873}
874
656562d8 875void MyTextCtrl::OnTextMaxLen(wxCommandEvent& WXUNUSED(event))
d7eee191 876{
9a83f860 877 wxLogMessage(wxT("You can't enter more characters into this control."));
d7eee191
VZ
878}
879
78c91815
VZ
880
881void MyTextCtrl::OnTextCut(wxClipboardTextEvent& event)
882{
9a83f860 883 LogClipEvent(wxT("cut to"), event);
78c91815
VZ
884}
885
886void MyTextCtrl::OnTextCopy(wxClipboardTextEvent& event)
887{
9a83f860 888 LogClipEvent(wxT("copied to"), event);
78c91815
VZ
889}
890
891void MyTextCtrl::OnTextPaste(wxClipboardTextEvent& event)
892{
9a83f860 893 LogClipEvent(wxT("pasted from"), event);
78c91815
VZ
894}
895
896void MyTextCtrl::LogClipEvent(const wxChar *what, wxClipboardTextEvent& event)
897{
898 wxFrame *frame = wxDynamicCast(wxGetTopLevelParent(this), wxFrame);
9a83f860 899 wxCHECK_RET( frame, wxT("no parent frame?") );
78c91815
VZ
900
901 const bool veto = frame->GetMenuBar()->IsChecked(TEXT_CLIPBOARD_VETO);
902 if ( !veto )
903 event.Skip();
904
905 if ( ms_logClip )
906 {
9a83f860
VZ
907 wxLogMessage(wxT("Text %s%s the clipboard."),
908 veto ? wxT("not ") : wxT(""), what);
78c91815
VZ
909 }
910}
911
912
c57e3339
VZ
913void MyTextCtrl::OnTextURL(wxTextUrlEvent& event)
914{
915 const wxMouseEvent& ev = event.GetMouseEvent();
916
917 // filter out mouse moves, too many of them
918 if ( ev.Moving() )
919 return;
920
921 long start = event.GetURLStart(),
922 end = event.GetURLEnd();
923
9a83f860 924 wxLogMessage(wxT("Mouse event over URL '%s': %s"),
c57e3339
VZ
925 GetValue().Mid(start, end - start).c_str(),
926 GetMouseEventDesc(ev).c_str());
927}
928
9ca03a57
VZ
929void MyTextCtrl::OnChar(wxKeyEvent& event)
930{
1ce58dc6 931 if ( ms_logChar )
9a83f860 932 LogKeyEvent( wxT("Char"), event);
3017f78d 933
3017f78d 934 event.Skip();
02e8b87f
RR
935}
936
937void MyTextCtrl::OnKeyUp(wxKeyEvent& event)
938{
1ce58dc6 939 if ( ms_logKey )
9a83f860 940 LogKeyEvent( wxT("Key up"), event);
02e8b87f
RR
941
942 event.Skip();
943}
944
945void MyTextCtrl::OnKeyDown(wxKeyEvent& event)
946{
b1d4dd7a 947 switch ( event.GetKeyCode() )
02e8b87f
RR
948 {
949 case WXK_F1:
950 // show current position and text length
951 {
952 long line, column, pos = GetInsertionPoint();
953 PositionToXY(pos, &column, &line);
954
9a83f860 955 wxLogMessage(wxT("Current position: %ld\nCurrent line, column: (%ld, %ld)\nNumber of lines: %ld\nCurrent line length: %ld\nTotal text length: %u (%ld)"),
02e8b87f
RR
956 pos,
957 line, column,
8b1d8f36
VZ
958 (long) GetNumberOfLines(),
959 (long) GetLineLength(line),
d4964163 960 (unsigned int) GetValue().length(),
02e8b87f 961 GetLastPosition());
2b5f62a0
VZ
962
963 long from, to;
964 GetSelection(&from, &to);
965
966 wxString sel = GetStringSelection();
967
9a83f860
VZ
968 wxLogMessage(wxT("Selection: from %ld to %ld."), from, to);
969 wxLogMessage(wxT("Selection = '%s' (len = %u)"),
ce709481
RN
970 sel.c_str(),
971 (unsigned int) sel.length());
b7ca4853
VZ
972
973 const wxString text = GetLineText(line);
9a83f860 974 wxLogMessage(wxT("Current line: \"%s\"; length = %lu"),
b7ca4853 975 text.c_str(), text.length());
02e8b87f
RR
976 }
977 break;
978
979 case WXK_F2:
980 // go to the end
981 SetInsertionPointEnd();
982 break;
983
984 case WXK_F3:
985 // go to position 10
986 SetInsertionPoint(10);
987 break;
4afd7529 988
f152cf5a 989 case WXK_F4:
4afd7529
VZ
990 if (!m_hasCapture)
991 {
f152cf5a 992 wxLogDebug( wxT("Now capturing mouse and events.") );
effbd41d 993 m_hasCapture = true;
4afd7529
VZ
994 CaptureMouse();
995 }
996 else
997 {
f152cf5a 998 wxLogDebug( wxT("Stopped capturing mouse and events.") );
effbd41d 999 m_hasCapture = false;
4afd7529
VZ
1000 ReleaseMouse();
1001 }
f152cf5a 1002 break;
4afd7529
VZ
1003
1004 case WXK_F5:
1005 // insert a blank line
9a83f860 1006 WriteText(wxT("\n"));
ae3dd4a5 1007 break;
02e8b87f 1008
f6bcfd97 1009 case WXK_F6:
9a83f860 1010 wxLogMessage(wxT("IsModified() before SetValue(): %d"),
2b5f62a0 1011 IsModified());
9a83f860
VZ
1012 ChangeValue(wxT("ChangeValue() has been called"));
1013 wxLogMessage(wxT("IsModified() after SetValue(): %d"),
2b5f62a0 1014 IsModified());
f6bcfd97
BP
1015 break;
1016
1017 case WXK_F7:
9a83f860 1018 wxLogMessage(wxT("Position 10 should be now visible."));
f6bcfd97
BP
1019 ShowPosition(10);
1020 break;
18414479 1021
80695f83 1022 case WXK_F8:
9a83f860 1023 wxLogMessage(wxT("Control has been cleared"));
80695f83
VZ
1024 Clear();
1025 break;
1026
2b5f62a0 1027 case WXK_F9:
9a83f860 1028 WriteText(wxT("WriteText() has been called"));
2b5f62a0 1029 break;
18414479 1030
2b5f62a0 1031 case WXK_F10:
9a83f860 1032 AppendText(wxT("AppendText() has been called"));
2b5f62a0 1033 break;
dabb9b6d
VZ
1034
1035 case WXK_F11:
1036 DiscardEdits();
9a83f860 1037 wxLogMessage(wxT("Control marked as non modified"));
dabb9b6d 1038 break;
0ddea946 1039 }
02e8b87f 1040
1ce58dc6 1041 if ( ms_logKey )
94ccc254 1042 LogKeyEvent( wxT("Key down"), event);
f6bcfd97 1043
02e8b87f
RR
1044 event.Skip();
1045}
1046
1047//----------------------------------------------------------------------
1048// MyPanel
1049//----------------------------------------------------------------------
1050
02e8b87f 1051MyPanel::MyPanel( wxFrame *frame, int x, int y, int w, int h )
effbd41d 1052 : wxPanel( frame, wxID_ANY, wxPoint(x, y), wxSize(w, h) )
02e8b87f 1053{
b29903d4 1054#if wxUSE_LOG
9a83f860 1055 m_log = new wxTextCtrl( this, wxID_ANY, wxT("This is the log window.\n"),
30982415 1056 wxPoint(5,260), wxSize(630,100),
d2356abe 1057 wxTE_MULTILINE | wxTE_READONLY);
02e8b87f 1058
d847e69a 1059 m_logOld = wxLog::SetActiveTarget( new wxLogTextCtrl( m_log ) );
b29903d4 1060#endif // wxUSE_LOG
02e8b87f
RR
1061
1062 // single line text controls
1063
9a83f860 1064 m_text = new MyTextCtrl( this, wxID_ANY, wxT("Single line."),
b29903d4 1065 wxDefaultPosition, wxDefaultSize,
f6bcfd97 1066 wxTE_PROCESS_ENTER);
4ed0aceb
VZ
1067 m_text->SetForegroundColour(*wxBLUE);
1068 m_text->SetBackgroundColour(*wxLIGHT_GREY);
9a83f860 1069 (*m_text) << wxT(" Appended.");
02e8b87f 1070 m_text->SetInsertionPoint(0);
9a83f860 1071 m_text->WriteText( wxT("Prepended. ") );
bb69661b 1072
9a83f860 1073 m_password = new MyTextCtrl( this, wxID_ANY, wxT(""),
422d0ff0 1074 wxPoint(10,50), wxSize(140,wxDefaultCoord), wxTE_PASSWORD );
bb69661b 1075
7dd65e5a 1076 m_limited = new MyTextCtrl(this, wxID_ANY, "",
7a78a937 1077 wxPoint(10, 90), wxDefaultSize);
7dd65e5a 1078 m_limited->SetHint("Max 8 ch");
d7eee191 1079 m_limited->SetMaxLength(8);
7a78a937
VZ
1080 wxSize size2 = m_limited->GetSizeFromTextSize(m_limited->GetTextExtent("WWWWWWWW"));
1081 m_limited->SetSizeHints(size2, size2);
d7eee191 1082
02e8b87f
RR
1083 // multi line text controls
1084
7a78a937
VZ
1085 wxString string3L("Read only\nMultiline\nFitted size");
1086 m_readonly = new MyTextCtrl( this, wxID_ANY, string3L,
1087 wxPoint(10, 120), wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY );
1088 wxWindowDC dc(m_readonly);
1089 size2 = m_readonly->GetSizeFromTextSize(dc.GetMultiLineTextExtent(string3L));
1090 m_readonly->SetMinSize(size2);
1091
9a83f860 1092 m_horizontal = new MyTextCtrl( this, wxID_ANY, wxT("Multiline text control with a horizontal scrollbar.\n"),
b7f5f3cc 1093 wxPoint(10,170), wxSize(140,70), wxTE_MULTILINE | wxHSCROLL);
f6bcfd97
BP
1094
1095 // a little hack to use the command line argument for encoding testing
1096 if ( wxTheApp->argc == 2 )
1097 {
88fb99a2 1098 switch ( (wxChar)wxTheApp->argv[1][0] )
f6bcfd97
BP
1099 {
1100 case '2':
1101 m_horizontal->SetFont(wxFont(18, wxSWISS, wxNORMAL, wxNORMAL,
9a83f860 1102 false, wxT(""),
f6bcfd97 1103 wxFONTENCODING_ISO8859_2));
9a83f860 1104 m_horizontal->AppendText(wxT("\256lu\273ou\350k\375 k\371\362 zb\354sile \350e\271tina \253\273"));
f6bcfd97
BP
1105 break;
1106
aac7e7fe
VZ
1107 case '1':
1108 m_horizontal->SetFont(wxFont(18, wxSWISS, wxNORMAL, wxNORMAL,
9a83f860 1109 false, wxT(""),
aac7e7fe 1110 wxFONTENCODING_CP1251));
9a83f860 1111 m_horizontal->AppendText(wxT("\317\360\350\342\345\362!"));
aac7e7fe
VZ
1112 break;
1113
1114 case '8':
f6bcfd97 1115 m_horizontal->SetFont(wxFont(18, wxSWISS, wxNORMAL, wxNORMAL,
9a83f860 1116 false, wxT(""),
aac7e7fe 1117 wxFONTENCODING_CP1251));
60f52320 1118#if wxUSE_UNICODE
b7f5f3cc 1119 m_horizontal->AppendText(L"\x0412\x0430\x0434\x0438\x043c \x0426");
60f52320 1120#else
548bbe14 1121 m_horizontal->AppendText("\313\301\326\305\324\323\321 \325\304\301\336\316\331\315");
60f52320 1122#endif
f6bcfd97
BP
1123 }
1124 }
1125 else
1126 {
9a83f860 1127 m_horizontal->AppendText(wxT("Text in default encoding"));
f6bcfd97 1128 }
bb69661b 1129
6ab069f2 1130 m_multitext = new MyTextCtrl( this, wxID_ANY,
9a83f860 1131 wxT("Multi line without vertical scrollbar."),
6ab069f2 1132 wxPoint(180,10), wxSize(200,70), wxTE_MULTILINE | wxTE_NO_VSCROLL );
f6bcfd97 1133 m_multitext->SetFont(*wxITALIC_FONT);
9a83f860 1134 (*m_multitext) << wxT(" Appended.");
02e8b87f 1135 m_multitext->SetInsertionPoint(0);
9a83f860 1136 m_multitext->WriteText( wxT("Prepended. ") );
86028025 1137 m_multitext->SetForegroundColour(*wxYELLOW);
f6bcfd97 1138 m_multitext->SetBackgroundColour(*wxLIGHT_GREY);
bb69661b 1139
02e8b87f 1140#if wxUSE_TOOLTIPS
9a83f860 1141 m_multitext->SetToolTip(wxT("Press Fn function keys here"));
02e8b87f
RR
1142#endif
1143
9a83f860 1144 m_tab = new MyTextCtrl( this, 100, wxT("Multiline, allow <TAB> processing."),
7a78a937 1145 wxPoint(180,90), wxDefaultSize, wxTE_MULTILINE | wxTE_PROCESS_TAB );
9a83f860 1146 m_tab->SetClientData((void *)wxT("tab"));
02e8b87f 1147
9a83f860 1148 m_enter = new MyTextCtrl( this, 100, wxT("Multiline, allow <ENTER> processing."),
5a22377e 1149 wxPoint(180,170), wxSize(200,70), wxTE_MULTILINE);
9a83f860
VZ
1150 m_enter->SetClientData((void *)wxT("enter"));
1151
1152 m_textrich = new MyTextCtrl(this, wxID_ANY, wxT("Allows more than 30Kb of text\n")
1153 wxT("(even under broken Win9x)\n")
1154 wxT("and a very very very very very ")
1155 wxT("very very very long line to test ")
1156 wxT("wxHSCROLL style\n")
1157 wxT("\nAnd here is a link in quotation marks to ")
1158 wxT("test wxTE_AUTO_URL: \"http://www.wxwidgets.org\""),
5a22377e 1159 wxPoint(450, 10), wxSize(200, 230),
22095a6e 1160 wxTE_RICH | wxTE_MULTILINE | wxTE_AUTO_URL);
4bc1afd5
VZ
1161 m_textrich->SetStyle(0, 10, *wxRED);
1162 m_textrich->SetStyle(10, 20, *wxBLUE);
1163 m_textrich->SetStyle(30, 40,
1164 wxTextAttr(*wxGREEN, wxNullColour, *wxITALIC_FONT));
17665a2b 1165 m_textrich->SetDefaultStyle(wxTextAttr());
9a83f860
VZ
1166 m_textrich->AppendText(wxT("\n\nFirst 10 characters should be in red\n"));
1167 m_textrich->AppendText(wxT("Next 10 characters should be in blue\n"));
1168 m_textrich->AppendText(wxT("Next 10 characters should be normal\n"));
1169 m_textrich->AppendText(wxT("And the next 10 characters should be green and italic\n"));
17665a2b 1170 m_textrich->SetDefaultStyle(wxTextAttr(*wxCYAN, *wxBLUE));
9a83f860 1171 m_textrich->AppendText(wxT("This text should be cyan on blue\n"));
eda40bfc 1172 m_textrich->SetDefaultStyle(wxTextAttr(*wxBLUE, *wxWHITE));
9a83f860
VZ
1173 m_textrich->AppendText(wxT("And this should be in blue and the text you ")
1174 wxT("type should be in blue as well"));
b29903d4 1175
c9539346
VZ
1176
1177 // lay out the controls
b29903d4 1178 wxBoxSizer *column1 = new wxBoxSizer(wxVERTICAL);
c9539346
VZ
1179 column1->Add( m_text, 0, wxALL | wxEXPAND, 10 );
1180 column1->Add( m_password, 0, wxALL | wxEXPAND, 10 );
7a78a937
VZ
1181 column1->Add( m_readonly, 0, wxALL, 10 );
1182 column1->Add( m_limited, 0, wxALL, 10 );
b29903d4
WS
1183 column1->Add( m_horizontal, 1, wxALL | wxEXPAND, 10 );
1184
1185 wxBoxSizer *column2 = new wxBoxSizer(wxVERTICAL);
1186 column2->Add( m_multitext, 1, wxALL | wxEXPAND, 10 );
7a78a937 1187 column2->Add( m_tab, 0, wxALL | wxEXPAND, 10 );
b29903d4
WS
1188 column2->Add( m_enter, 1, wxALL | wxEXPAND, 10 );
1189
b29903d4
WS
1190 wxBoxSizer *row1 = new wxBoxSizer(wxHORIZONTAL);
1191 row1->Add( column1, 0, wxALL | wxEXPAND, 10 );
1192 row1->Add( column2, 1, wxALL | wxEXPAND, 10 );
c9539346 1193 row1->Add( m_textrich, 1, wxALL | wxEXPAND, 10 );
b29903d4
WS
1194
1195 wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
1196 topSizer->Add( row1, 2, wxALL | wxEXPAND, 10 );
1197
1198#if wxUSE_LOG
c9539346 1199 topSizer->Add( m_log, 1, wxALL | wxEXPAND, 10 );
b29903d4
WS
1200#endif
1201
b29903d4 1202 SetSizer(topSizer);
02e8b87f
RR
1203}
1204
5b07594a 1205wxTextCtrl *MyPanel::GetFocusedText() const
cba1148d
VZ
1206{
1207 wxWindow *win = FindFocus();
1208
1209 wxTextCtrl *text = win ? wxDynamicCast(win, wxTextCtrl) : NULL;
5b07594a 1210 return text ? text : m_multitext;
cba1148d
VZ
1211}
1212
b6a0d8a2
VZ
1213#if wxUSE_CLIPBOARD
1214void MyPanel::DoPasteFromClipboard()
02e8b87f 1215{
7e2c43b8
RR
1216 // On X11, we want to get the data from the primary selection instead
1217 // of the normal clipboard (which isn't normal under X11 at all). This
1218 // call has no effect under MSW.
1219 wxTheClipboard->UsePrimarySelection();
1220
02e8b87f
RR
1221 if (!wxTheClipboard->Open())
1222 {
b29903d4 1223#if wxUSE_LOG
9a83f860 1224 *m_log << wxT("Error opening the clipboard.\n");
b29903d4 1225#endif // wxUSE_LOG
02e8b87f
RR
1226 return;
1227 }
1228 else
1229 {
b29903d4 1230#if wxUSE_LOG
9a83f860 1231 *m_log << wxT("Successfully opened the clipboard.\n");
b29903d4 1232#endif // wxUSE_LOG
02e8b87f
RR
1233 }
1234
1235 wxTextDataObject data;
1236
1237 if (wxTheClipboard->IsSupported( data.GetFormat() ))
1238 {
b29903d4 1239#if wxUSE_LOG
9a83f860 1240 *m_log << wxT("Clipboard supports requested format.\n");
b29903d4 1241#endif // wxUSE_LOG
02e8b87f 1242
11e1c70d 1243 if (wxTheClipboard->GetData( data ))
02e8b87f 1244 {
b29903d4 1245#if wxUSE_LOG
9a83f860 1246 *m_log << wxT("Successfully retrieved data from the clipboard.\n");
b29903d4 1247#endif // wxUSE_LOG
5b07594a 1248 GetFocusedText()->AppendText(data.GetText());
02e8b87f
RR
1249 }
1250 else
1251 {
b29903d4 1252#if wxUSE_LOG
9a83f860 1253 *m_log << wxT("Error getting data from the clipboard.\n");
b29903d4 1254#endif // wxUSE_LOG
02e8b87f
RR
1255 }
1256 }
1257 else
1258 {
b29903d4 1259#if wxUSE_LOG
9a83f860 1260 *m_log << wxT("Clipboard doesn't support requested format.\n");
b29903d4 1261#endif // wxUSE_LOG
02e8b87f
RR
1262 }
1263
1264 wxTheClipboard->Close();
1265
b29903d4 1266#if wxUSE_LOG
9a83f860 1267 *m_log << wxT("Closed the clipboard.\n");
b29903d4 1268#endif // wxUSE_LOG
02e8b87f
RR
1269}
1270
b6a0d8a2 1271void MyPanel::DoCopyToClipboard()
02e8b87f 1272{
eff869aa
RR
1273 // On X11, we want to get the data from the primary selection instead
1274 // of the normal clipboard (which isn't normal under X11 at all). This
1275 // call has no effect under MSW.
1276 wxTheClipboard->UsePrimarySelection();
1277
5b07594a 1278 wxString text( GetFocusedText()->GetStringSelection() );
02e8b87f
RR
1279
1280 if (text.IsEmpty())
1281 {
b29903d4 1282#if wxUSE_LOG
9a83f860 1283 *m_log << wxT("No text to copy.\n");
b29903d4 1284#endif // wxUSE_LOG
02e8b87f
RR
1285
1286 return;
1287 }
1288
1289 if (!wxTheClipboard->Open())
1290 {
b29903d4 1291#if wxUSE_LOG
9a83f860 1292 *m_log << wxT("Error opening the clipboard.\n");
b29903d4 1293#endif // wxUSE_LOG
02e8b87f
RR
1294
1295 return;
1296 }
1297 else
1298 {
b29903d4 1299#if wxUSE_LOG
9a83f860 1300 *m_log << wxT("Successfully opened the clipboard.\n");
b29903d4 1301#endif // wxUSE_LOG
02e8b87f
RR
1302 }
1303
1304 wxTextDataObject *data = new wxTextDataObject( text );
1305
1306 if (!wxTheClipboard->SetData( data ))
1307 {
b29903d4 1308#if wxUSE_LOG
9a83f860 1309 *m_log << wxT("Error while copying to the clipboard.\n");
b29903d4 1310#endif // wxUSE_LOG
02e8b87f
RR
1311 }
1312 else
1313 {
b29903d4 1314#if wxUSE_LOG
9a83f860 1315 *m_log << wxT("Successfully copied data to the clipboard.\n");
b29903d4 1316#endif // wxUSE_LOG
02e8b87f
RR
1317 }
1318
1319 wxTheClipboard->Close();
1320
b29903d4 1321#if wxUSE_LOG
9a83f860 1322 *m_log << wxT("Closed the clipboard.\n");
b29903d4 1323#endif // wxUSE_LOG
02e8b87f
RR
1324}
1325
b6a0d8a2
VZ
1326#endif // wxUSE_CLIPBOARD
1327
1328void MyPanel::DoMoveToEndOfText()
02e8b87f
RR
1329{
1330 m_multitext->SetInsertionPointEnd();
1331 m_multitext->SetFocus();
1332}
1333
6ce83213
VZ
1334void MyPanel::DoGetWindowCoordinates()
1335{
1336 wxTextCtrl * const text = GetFocusedText();
1337
1338 const wxPoint pt0 = text->PositionToCoords(0);
1339 const wxPoint ptCur = text->PositionToCoords(text->GetInsertionPoint());
1340 *m_log << "Current position coordinates: "
1341 "(" << ptCur.x << ", " << ptCur.y << "), "
1342 "first position coordinates: "
1343 "(" << pt0.x << ", " << pt0.y << ")\n";
1344}
1345
b6a0d8a2 1346void MyPanel::DoMoveToEndOfEntry()
02e8b87f
RR
1347{
1348 m_text->SetInsertionPointEnd();
1349 m_text->SetFocus();
1350}
1351
cba1148d
VZ
1352void MyPanel::DoRemoveText()
1353{
5b07594a 1354 GetFocusedText()->Remove(0, 10);
cba1148d
VZ
1355}
1356
cdd732de
VZ
1357void MyPanel::DoReplaceText()
1358{
9a83f860 1359 GetFocusedText()->Replace(3, 8, wxT("ABC"));
cdd732de
VZ
1360}
1361
29676ca0
JS
1362void MyPanel::DoSelectText()
1363{
5b07594a 1364 GetFocusedText()->SetSelection(3, 8);
29676ca0
JS
1365}
1366
02e8b87f
RR
1367//----------------------------------------------------------------------
1368// MyFrame
1369//----------------------------------------------------------------------
1370
1371BEGIN_EVENT_TABLE(MyFrame, wxFrame)
b6a0d8a2
VZ
1372 EVT_MENU(TEXT_QUIT, MyFrame::OnQuit)
1373 EVT_MENU(TEXT_ABOUT, MyFrame::OnAbout)
0ddea946 1374 EVT_MENU(TEXT_SAVE, MyFrame::OnFileSave)
b6a0d8a2 1375 EVT_MENU(TEXT_LOAD, MyFrame::OnFileLoad)
e00a5d3c 1376 EVT_MENU(TEXT_RICH_TEXT_TEST, MyFrame::OnRichTextTest)
56c4a88b
VZ
1377
1378 EVT_MENU(TEXT_LOG_KEY, MyFrame::OnLogKey)
1ce58dc6
VZ
1379 EVT_MENU(TEXT_LOG_CHAR, MyFrame::OnLogChar)
1380 EVT_MENU(TEXT_LOG_MOUSE,MyFrame::OnLogMouse)
1381 EVT_MENU(TEXT_LOG_TEXT, MyFrame::OnLogText)
94ccc254 1382 EVT_MENU(TEXT_LOG_FOCUS,MyFrame::OnLogFocus)
78c91815 1383 EVT_MENU(TEXT_LOG_CLIP, MyFrame::OnLogClip)
b29903d4 1384#if wxUSE_LOG
60f52320 1385 EVT_MENU(TEXT_CLEAR, MyFrame::OnLogClear)
b29903d4 1386#endif // wxUSE_LOG
b6a0d8a2 1387
02e8b87f 1388#if wxUSE_TOOLTIPS
b6a0d8a2
VZ
1389 EVT_MENU(TEXT_TOOLTIPS_SETDELAY, MyFrame::OnSetTooltipDelay)
1390 EVT_MENU(TEXT_TOOLTIPS_ENABLE, MyFrame::OnToggleTooltips)
02e8b87f 1391#endif // wxUSE_TOOLTIPS
b6a0d8a2 1392
ee31c392 1393#if wxUSE_CLIPBOARD
b6a0d8a2
VZ
1394 EVT_MENU(TEXT_CLIPBOARD_PASTE, MyFrame::OnPasteFromClipboard)
1395 EVT_MENU(TEXT_CLIPBOARD_COPY, MyFrame::OnCopyToClipboard)
5b07594a
VZ
1396
1397 EVT_UPDATE_UI(TEXT_CLIPBOARD_PASTE, MyFrame::OnUpdatePasteFromClipboard)
1398 EVT_UPDATE_UI(TEXT_CLIPBOARD_COPY, MyFrame::OnUpdateCopyToClipboard)
ee31c392
VZ
1399#endif // wxUSE_CLIPBOARD
1400
cba1148d 1401 EVT_MENU(TEXT_REMOVE, MyFrame::OnRemoveText)
cdd732de 1402 EVT_MENU(TEXT_REPLACE, MyFrame::OnReplaceText)
29676ca0 1403 EVT_MENU(TEXT_SELECT, MyFrame::OnSelectText)
eff00523
VZ
1404 EVT_MENU(TEXT_ADD_SOME, MyFrame::OnAddText)
1405 EVT_MENU(TEXT_ADD_FREEZE, MyFrame::OnAddTextFreeze)
be83461c 1406 EVT_MENU(TEXT_ADD_LINE, MyFrame::OnAddTextLine)
b6a0d8a2 1407 EVT_MENU(TEXT_MOVE_ENDTEXT, MyFrame::OnMoveToEndOfText)
6ce83213 1408 EVT_MENU(TEXT_GET_WINDOW_COORD, MyFrame::OnGetWindowCoordinates)
b6a0d8a2
VZ
1409 EVT_MENU(TEXT_MOVE_ENDENTRY, MyFrame::OnMoveToEndOfEntry)
1410
f6bcfd97
BP
1411 EVT_MENU(TEXT_SET_EDITABLE, MyFrame::OnSetEditable)
1412 EVT_MENU(TEXT_SET_ENABLED, MyFrame::OnSetEnabled)
1413
22670da4
VZ
1414 EVT_MENU(TEXT_LINE_DOWN, MyFrame::OnScrollLineDown)
1415 EVT_MENU(TEXT_LINE_UP, MyFrame::OnScrollLineUp)
1416 EVT_MENU(TEXT_PAGE_DOWN, MyFrame::OnScrollPageDown)
1417 EVT_MENU(TEXT_PAGE_UP, MyFrame::OnScrollPageUp)
1418
7ddc9343
VZ
1419 EVT_MENU(TEXT_GET_LINE, MyFrame::OnGetLine)
1420 EVT_MENU(TEXT_GET_LINELENGTH, MyFrame::OnGetLineLength)
ae25e5cc 1421
60f52320 1422 EVT_MENU(TEXT_SET, MyFrame::OnSetText)
7ddc9343 1423 EVT_MENU(TEXT_CHANGE, MyFrame::OnChangeText)
60f52320 1424
b6a0d8a2 1425 EVT_IDLE(MyFrame::OnIdle)
02e8b87f
RR
1426END_EVENT_TABLE()
1427
ab1ca7b3 1428MyFrame::MyFrame(wxFrame *frame, const wxChar *title, int x, int y, int w, int h)
effbd41d 1429 : wxFrame(frame, wxID_ANY, title, wxPoint(x, y), wxSize(w, h) )
02e8b87f 1430{
41f02b9a
FM
1431 SetIcon(wxICON(sample));
1432
8520f137 1433#if wxUSE_STATUSBAR
02e8b87f 1434 CreateStatusBar(2);
8520f137 1435#endif // wxUSE_STATUSBAR
02e8b87f 1436
b6a0d8a2 1437 m_panel = new MyPanel( this, 10, 10, 300, 100 );
02e8b87f
RR
1438}
1439
1440void MyFrame::OnQuit (wxCommandEvent& WXUNUSED(event) )
1441{
effbd41d 1442 Close(true);
02e8b87f
RR
1443}
1444
1445void MyFrame::OnAbout( wxCommandEvent& WXUNUSED(event) )
1446{
1447 wxBeginBusyCursor();
1448
b6a0d8a2 1449 wxMessageDialog dialog(this,
9a83f860
VZ
1450 wxT("This is a text control sample. It demonstrates the many different\n")
1451 wxT("text control styles, the use of the clipboard, setting and handling\n")
1452 wxT("tooltips and intercepting key and char events.\n")
1453 wxT("\n")
1454 wxT("Copyright (c) 1999, Robert Roebling, Julian Smart, Vadim Zeitlin"),
1455 wxT("About wxTextCtrl Sample"),
b6a0d8a2
VZ
1456 wxOK | wxICON_INFORMATION);
1457
02e8b87f
RR
1458 dialog.ShowModal();
1459
1460 wxEndBusyCursor();
1461}
1462
1463#if wxUSE_TOOLTIPS
656562d8
VZ
1464
1465void MyFrame::OnSetTooltipDelay(wxCommandEvent& WXUNUSED(event))
02e8b87f
RR
1466{
1467 static long s_delay = 5000;
1468
1469 wxString delay;
9a83f860 1470 delay.Printf( wxT("%ld"), s_delay);
02e8b87f 1471
9a83f860
VZ
1472 delay = wxGetTextFromUser(wxT("Enter delay (in milliseconds)"),
1473 wxT("Set tooltip delay"),
bb69661b
VZ
1474 delay,
1475 this);
02e8b87f
RR
1476 if ( !delay )
1477 return; // cancelled
1478
9a83f860 1479 wxSscanf(delay, wxT("%ld"), &s_delay);
02e8b87f
RR
1480
1481 wxToolTip::SetDelay(s_delay);
1482
9a83f860 1483 wxLogStatus(this, wxT("Tooltip delay set to %ld milliseconds"), s_delay);
02e8b87f
RR
1484}
1485
656562d8 1486void MyFrame::OnToggleTooltips(wxCommandEvent& WXUNUSED(event))
02e8b87f 1487{
effbd41d 1488 static bool s_enabled = true;
02e8b87f
RR
1489
1490 s_enabled = !s_enabled;
1491
1492 wxToolTip::Enable(s_enabled);
1493
9a83f860 1494 wxLogStatus(this, wxT("Tooltips %sabled"), s_enabled ? wxT("en") : wxT("dis") );
02e8b87f
RR
1495}
1496#endif // tooltips
1497
b29903d4 1498#if wxUSE_LOG
e66ad5c6
VZ
1499void MyFrame::OnLogClear(wxCommandEvent& WXUNUSED(event))
1500{
1501 m_panel->m_log->Clear();
1502}
b29903d4 1503#endif // wxUSE_LOG
e66ad5c6 1504
f6bcfd97
BP
1505void MyFrame::OnSetEditable(wxCommandEvent& WXUNUSED(event))
1506{
effbd41d 1507 static bool s_editable = true;
f6bcfd97
BP
1508
1509 s_editable = !s_editable;
1510 m_panel->m_text->SetEditable(s_editable);
1511 m_panel->m_password->SetEditable(s_editable);
1512 m_panel->m_multitext->SetEditable(s_editable);
1513 m_panel->m_textrich->SetEditable(s_editable);
1514}
1515
1516void MyFrame::OnSetEnabled(wxCommandEvent& WXUNUSED(event))
1517{
1518 bool enabled = m_panel->m_text->IsEnabled();
1519 enabled = !enabled;
1520
1521 m_panel->m_text->Enable(enabled);
1522 m_panel->m_password->Enable(enabled);
1523 m_panel->m_multitext->Enable(enabled);
1524 m_panel->m_readonly->Enable(enabled);
d7eee191 1525 m_panel->m_limited->Enable(enabled);
f6bcfd97
BP
1526 m_panel->m_textrich->Enable(enabled);
1527}
1528
656562d8 1529void MyFrame::OnFileSave(wxCommandEvent& WXUNUSED(event))
0ddea946 1530{
9a83f860 1531 if ( m_panel->m_textrich->SaveFile(wxT("dummy.txt")) )
0ddea946
VZ
1532 {
1533#if wxUSE_FILE
1534 // verify that the fil length is correct (it wasn't under Win95)
4693b20c 1535 wxFile file(wxT("dummy.txt"));
aafbc345 1536 wxLogStatus(this,
9a83f860 1537 wxT("Successfully saved file (text len = %lu, file size = %ld)"),
aafbc345 1538 (unsigned long)m_panel->m_textrich->GetValue().length(),
2b5f62a0 1539 (long) file.Length());
0ddea946
VZ
1540#endif
1541 }
1542 else
9a83f860 1543 wxLogStatus(this, wxT("Couldn't save the file"));
0ddea946
VZ
1544}
1545
656562d8 1546void MyFrame::OnFileLoad(wxCommandEvent& WXUNUSED(event))
b6a0d8a2 1547{
9a83f860 1548 if ( m_panel->m_textrich->LoadFile(wxT("dummy.txt")) )
43b2d5e7 1549 {
9a83f860 1550 wxLogStatus(this, wxT("Successfully loaded file"));
43b2d5e7 1551 }
5e3dad49 1552 else
43b2d5e7 1553 {
9a83f860 1554 wxLogStatus(this, wxT("Couldn't load the file"));
43b2d5e7 1555 }
b6a0d8a2
VZ
1556}
1557
656562d8 1558void MyFrame::OnRichTextTest(wxCommandEvent& WXUNUSED(event))
e00a5d3c 1559{
9a83f860 1560 RichTextFrame* frame = new RichTextFrame(this, wxT("Rich Text Editor"));
effbd41d 1561 frame->Show(true);
e00a5d3c
JS
1562}
1563
02e8b87f
RR
1564void MyFrame::OnIdle( wxIdleEvent& event )
1565{
1566 // track the window which has the focus in the status bar
1567 static wxWindow *s_windowFocus = (wxWindow *)NULL;
1568 wxWindow *focus = wxWindow::FindFocus();
1569 if ( focus && (focus != s_windowFocus) )
1570 {
1571 s_windowFocus = focus;
1572
1573 wxString msg;
1574 msg.Printf(
1575#ifdef __WXMSW__
9a83f860 1576 wxT("Focus: wxWindow = %p, HWND = %p"),
02e8b87f 1577#else
9a83f860 1578 wxT("Focus: wxWindow = %p"),
02e8b87f
RR
1579#endif
1580 s_windowFocus
1581#ifdef __WXMSW__
647d7ce9 1582 , s_windowFocus->GetHWND()
02e8b87f
RR
1583#endif
1584 );
1585
8520f137 1586#if wxUSE_STATUSBAR
02e8b87f 1587 SetStatusText(msg);
8520f137 1588#endif // wxUSE_STATUSBAR
02e8b87f
RR
1589 }
1590 event.Skip();
1591}
e00a5d3c
JS
1592
1593/*
1594 * RichTextFrame is used to demonstrate rich text behaviour
1595 */
1596
1597enum
1598{
1599 RICHTEXT_CLOSE = 1000,
1600 RICHTEXT_LEFT_ALIGN,
1601 RICHTEXT_RIGHT_ALIGN,
1602 RICHTEXT_CENTRE,
1603 RICHTEXT_JUSTIFY,
1604 RICHTEXT_CHANGE_FONT,
1605 RICHTEXT_CHANGE_TEXT_COLOUR,
1606 RICHTEXT_CHANGE_BACKGROUND_COLOUR,
1607 RICHTEXT_LEFT_INDENT,
7fb3f3c4
MR
1608 RICHTEXT_RIGHT_INDENT,
1609 RICHTEXT_TAB_STOPS
e00a5d3c
JS
1610};
1611
1612BEGIN_EVENT_TABLE(RichTextFrame, wxFrame)
80185c6c 1613 EVT_IDLE(RichTextFrame::OnIdle)
e00a5d3c
JS
1614 EVT_MENU(RICHTEXT_CLOSE, RichTextFrame::OnClose)
1615 EVT_MENU(RICHTEXT_LEFT_ALIGN, RichTextFrame::OnLeftAlign)
1616 EVT_MENU(RICHTEXT_RIGHT_ALIGN, RichTextFrame::OnRightAlign)
1617 EVT_MENU(RICHTEXT_CENTRE, RichTextFrame::OnCentre)
1618 EVT_MENU(RICHTEXT_JUSTIFY, RichTextFrame::OnJustify)
1619 EVT_MENU(RICHTEXT_CHANGE_FONT, RichTextFrame::OnChangeFont)
1620 EVT_MENU(RICHTEXT_CHANGE_TEXT_COLOUR, RichTextFrame::OnChangeTextColour)
1621 EVT_MENU(RICHTEXT_CHANGE_BACKGROUND_COLOUR, RichTextFrame::OnChangeBackgroundColour)
1622 EVT_MENU(RICHTEXT_LEFT_INDENT, RichTextFrame::OnLeftIndent)
1623 EVT_MENU(RICHTEXT_RIGHT_INDENT, RichTextFrame::OnRightIndent)
7fb3f3c4 1624 EVT_MENU(RICHTEXT_TAB_STOPS, RichTextFrame::OnTabStops)
e00a5d3c
JS
1625END_EVENT_TABLE()
1626
1627RichTextFrame::RichTextFrame(wxWindow* parent, const wxString& title):
effbd41d 1628 wxFrame(parent, wxID_ANY, title, wxDefaultPosition, wxSize(300, 400))
e00a5d3c 1629{
80185c6c 1630 m_currentPosition = -1;
effbd41d 1631 m_textCtrl = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition,
e00a5d3c
JS
1632 wxDefaultSize, wxTE_MULTILINE|wxTE_RICH2);
1633
1634 wxString value;
1635 int i;
1636 for (i = 0; i < 10; i++)
1637 {
1638 int j;
1639 for (j = 0; j < 10; j++)
1640 {
1641 value << wxT("Hello, welcome to a very simple rich text editor. You can set some character and paragraph styles from the Edit menu. ");
1642 }
1643 value << wxT("\n\n");
1644 }
1645 m_textCtrl->SetValue(value);
1646
1647 wxMenuBar* menuBar = new wxMenuBar;
1648 wxMenu* fileMenu = new wxMenu;
1649 fileMenu->Append(RICHTEXT_CLOSE, _("Close\tCtrl+W"));
1650 menuBar->Append(fileMenu, _("File"));
1651
1652 wxMenu* editMenu = new wxMenu;
1653 editMenu->Append(RICHTEXT_LEFT_ALIGN, _("Left Align"));
1654 editMenu->Append(RICHTEXT_RIGHT_ALIGN, _("Right Align"));
1655 editMenu->Append(RICHTEXT_CENTRE, _("Centre"));
1656 editMenu->Append(RICHTEXT_JUSTIFY, _("Justify"));
1657 editMenu->AppendSeparator();
1658 editMenu->Append(RICHTEXT_CHANGE_FONT, _("Change Font"));
1659 editMenu->Append(RICHTEXT_CHANGE_TEXT_COLOUR, _("Change Text Colour"));
1660 editMenu->Append(RICHTEXT_CHANGE_BACKGROUND_COLOUR, _("Change Background Colour"));
1661 editMenu->AppendSeparator();
1662 editMenu->Append(RICHTEXT_LEFT_INDENT, _("Left Indent"));
7fb3f3c4
MR
1663 editMenu->Append(RICHTEXT_RIGHT_INDENT, _("Right Indent"));
1664 editMenu->Append(RICHTEXT_TAB_STOPS, _("Tab Stops"));
e00a5d3c
JS
1665 menuBar->Append(editMenu, _("Edit"));
1666
1667 SetMenuBar(menuBar);
8520f137 1668#if wxUSE_STATUSBAR
80185c6c 1669 CreateStatusBar();
8520f137 1670#endif // wxUSE_STATUSBAR
e00a5d3c
JS
1671}
1672
1673// Event handlers
1674
656562d8 1675void RichTextFrame::OnClose(wxCommandEvent& WXUNUSED(event))
e00a5d3c 1676{
effbd41d 1677 Close(true);
e00a5d3c
JS
1678}
1679
656562d8 1680void RichTextFrame::OnLeftAlign(wxCommandEvent& WXUNUSED(event))
e00a5d3c
JS
1681{
1682 wxTextAttr attr;
1683 attr.SetAlignment(wxTEXT_ALIGNMENT_LEFT);
1684
1685 long start, end;
1686 m_textCtrl->GetSelection(& start, & end);
1687 m_textCtrl->SetStyle(start, end, attr);
80185c6c
JS
1688
1689 m_currentPosition = -1;
e00a5d3c
JS
1690}
1691
656562d8 1692void RichTextFrame::OnRightAlign(wxCommandEvent& WXUNUSED(event))
e00a5d3c
JS
1693{
1694 wxTextAttr attr;
1695 attr.SetAlignment(wxTEXT_ALIGNMENT_RIGHT);
1696
1697 long start, end;
1698 m_textCtrl->GetSelection(& start, & end);
1699 m_textCtrl->SetStyle(start, end, attr);
80185c6c
JS
1700
1701 m_currentPosition = -1;
e00a5d3c
JS
1702}
1703
656562d8 1704void RichTextFrame::OnJustify(wxCommandEvent& WXUNUSED(event))
e00a5d3c
JS
1705{
1706 wxTextAttr attr;
1707 attr.SetAlignment(wxTEXT_ALIGNMENT_JUSTIFIED);
1708
1709 long start, end;
1710 m_textCtrl->GetSelection(& start, & end);
1711 m_textCtrl->SetStyle(start, end, attr);
80185c6c
JS
1712
1713 m_currentPosition = -1;
e00a5d3c
JS
1714}
1715
656562d8 1716void RichTextFrame::OnCentre(wxCommandEvent& WXUNUSED(event))
e00a5d3c
JS
1717{
1718 wxTextAttr attr;
1719 attr.SetAlignment(wxTEXT_ALIGNMENT_CENTRE);
1720
1721 long start, end;
1722 m_textCtrl->GetSelection(& start, & end);
1723 m_textCtrl->SetStyle(start, end, attr);
80185c6c
JS
1724
1725 m_currentPosition = -1;
e00a5d3c
JS
1726}
1727
656562d8 1728void RichTextFrame::OnChangeFont(wxCommandEvent& WXUNUSED(event))
e00a5d3c
JS
1729{
1730 wxFontData data;
1731
1732 wxFontDialog dialog(this, data);
1733
1734 if (dialog.ShowModal() == wxID_OK)
1735 {
1736 wxFontData retData = dialog.GetFontData();
1737 wxFont font = retData.GetChosenFont();
1738
1739 wxTextAttr attr;
1740 attr.SetFont(font);
925e9792 1741
e00a5d3c
JS
1742 long start, end;
1743 m_textCtrl->GetSelection(& start, & end);
1744 m_textCtrl->SetStyle(start, end, attr);
80185c6c
JS
1745
1746 m_currentPosition = -1;
e00a5d3c
JS
1747 }
1748}
1749
656562d8 1750void RichTextFrame::OnChangeTextColour(wxCommandEvent& WXUNUSED(event))
e00a5d3c
JS
1751{
1752 wxColourData data;
1753 data.SetColour(* wxBLACK);
effbd41d 1754 data.SetChooseFull(true);
e00a5d3c
JS
1755 for (int i = 0; i < 16; i++)
1756 {
925e9792 1757 wxColour colour((unsigned char)(i*16), (unsigned char)(i*16), (unsigned char)(i*16));
e00a5d3c
JS
1758 data.SetCustomColour(i, colour);
1759 }
1760
1761 wxColourDialog dialog(this, &data);
9a83f860 1762 dialog.SetTitle(wxT("Choose the text colour"));
e00a5d3c
JS
1763 if (dialog.ShowModal() == wxID_OK)
1764 {
1765 wxColourData retData = dialog.GetColourData();
1766 wxColour col = retData.GetColour();
1767
1768 wxTextAttr attr;
1769 attr.SetTextColour(col);
925e9792 1770
e00a5d3c
JS
1771 long start, end;
1772 m_textCtrl->GetSelection(& start, & end);
1773 m_textCtrl->SetStyle(start, end, attr);
80185c6c
JS
1774
1775 m_currentPosition = -1;
e00a5d3c
JS
1776 }
1777}
1778
656562d8 1779void RichTextFrame::OnChangeBackgroundColour(wxCommandEvent& WXUNUSED(event))
e00a5d3c
JS
1780{
1781 wxColourData data;
1782 data.SetColour(* wxWHITE);
effbd41d 1783 data.SetChooseFull(true);
e00a5d3c
JS
1784 for (int i = 0; i < 16; i++)
1785 {
925e9792 1786 wxColour colour((unsigned char)(i*16), (unsigned char)(i*16), (unsigned char)(i*16));
e00a5d3c
JS
1787 data.SetCustomColour(i, colour);
1788 }
1789
1790 wxColourDialog dialog(this, &data);
9a83f860 1791 dialog.SetTitle(wxT("Choose the text background colour"));
e00a5d3c
JS
1792 if (dialog.ShowModal() == wxID_OK)
1793 {
1794 wxColourData retData = dialog.GetColourData();
1795 wxColour col = retData.GetColour();
1796
1797 wxTextAttr attr;
1798 attr.SetBackgroundColour(col);
925e9792 1799
e00a5d3c
JS
1800 long start, end;
1801 m_textCtrl->GetSelection(& start, & end);
1802 m_textCtrl->SetStyle(start, end, attr);
80185c6c
JS
1803
1804 m_currentPosition = -1;
e00a5d3c
JS
1805 }
1806}
1807
656562d8 1808void RichTextFrame::OnLeftIndent(wxCommandEvent& WXUNUSED(event))
e00a5d3c 1809{
656562d8
VZ
1810 wxString indentStr = wxGetTextFromUser
1811 (
1812 _("Please enter the left indent in tenths of a millimetre."),
effbd41d
WS
1813 _("Left Indent"),
1814 wxEmptyString,
1815 this
656562d8 1816 );
e00a5d3c
JS
1817 if (!indentStr.IsEmpty())
1818 {
1819 int indent = wxAtoi(indentStr);
1820
1821 wxTextAttr attr;
1822 attr.SetLeftIndent(indent);
925e9792 1823
e00a5d3c
JS
1824 long start, end;
1825 m_textCtrl->GetSelection(& start, & end);
1826 m_textCtrl->SetStyle(start, end, attr);
80185c6c
JS
1827
1828 m_currentPosition = -1;
e00a5d3c
JS
1829 }
1830}
1831
656562d8 1832void RichTextFrame::OnRightIndent(wxCommandEvent& WXUNUSED(event))
e00a5d3c 1833{
656562d8
VZ
1834 wxString indentStr = wxGetTextFromUser
1835 (
1836 _("Please enter the right indent in tenths of a millimetre."),
effbd41d
WS
1837 _("Right Indent"),
1838 wxEmptyString,
1839 this
656562d8 1840 );
e00a5d3c
JS
1841 if (!indentStr.IsEmpty())
1842 {
1843 int indent = wxAtoi(indentStr);
1844
1845 wxTextAttr attr;
1846 attr.SetRightIndent(indent);
925e9792 1847
e00a5d3c
JS
1848 long start, end;
1849 m_textCtrl->GetSelection(& start, & end);
1850 m_textCtrl->SetStyle(start, end, attr);
80185c6c
JS
1851
1852 m_currentPosition = -1;
1853 }
1854}
1855
7fb3f3c4
MR
1856void RichTextFrame::OnTabStops(wxCommandEvent& WXUNUSED(event))
1857{
1858 wxString tabsStr = wxGetTextFromUser
1859 (
1860 _("Please enter the tab stop positions in tenths of a millimetre, separated by spaces.\nLeave empty to reset tab stops."),
1861 _("Tab Stops"),
1862 wxEmptyString,
1863 this
1864 );
1865
1866 wxArrayInt tabs;
1867
9a83f860 1868 wxStringTokenizer tokens(tabsStr, wxT(" "));
7fb3f3c4
MR
1869 while (tokens.HasMoreTokens())
1870 {
1871 wxString token = tokens.GetNextToken();
1872 tabs.Add(wxAtoi(token));
1873 }
1874
1875 wxTextAttr attr;
1876 attr.SetTabs(tabs);
1877
1878 long start, end;
1879 m_textCtrl->GetSelection(& start, & end);
1880 m_textCtrl->SetStyle(start, end, attr);
1881
1882 m_currentPosition = -1;
1883}
1884
656562d8 1885void RichTextFrame::OnIdle(wxIdleEvent& WXUNUSED(event))
80185c6c
JS
1886{
1887 long insertionPoint = m_textCtrl->GetInsertionPoint();
1888 if (insertionPoint != m_currentPosition)
1889 {
8520f137 1890#if wxUSE_STATUSBAR
80185c6c
JS
1891 wxTextAttr attr;
1892 if (m_textCtrl->GetStyle(insertionPoint, attr))
1893 {
1894 wxString msg;
1895 wxString facename(wxT("unknown"));
a1b806b9 1896 if (attr.GetFont().IsOk())
80185c6c
JS
1897 {
1898 facename = attr.GetFont().GetFaceName();
1899 }
1900 wxString alignment(wxT("unknown alignment"));
1901 if (attr.GetAlignment() == wxTEXT_ALIGNMENT_CENTRE)
1902 alignment = wxT("centred");
1903 else if (attr.GetAlignment() == wxTEXT_ALIGNMENT_RIGHT)
1904 alignment = wxT("right-aligned");
1905 else if (attr.GetAlignment() == wxTEXT_ALIGNMENT_LEFT)
1906 alignment = wxT("left-aligned");
1907 else if (attr.GetAlignment() == wxTEXT_ALIGNMENT_JUSTIFIED)
1908 alignment = wxT("justified");
ca746004
VZ
1909
1910 msg.Printf("Facename: %s", facename);
1911
1912 if (attr.HasTextColour())
1913 {
1914 msg += wxString::Format(", colour: %s",
1915 attr.GetTextColour().GetAsString());
1916 }
1917 else
1918 {
1919 msg += ", no colour";
1920 }
1921
1922 msg << ", " << alignment;
093dee5e
RN
1923
1924 if (attr.HasFont())
1925 {
1926 if (attr.GetFont().GetWeight() == wxBOLD)
1927 msg += wxT(" BOLD");
1928 else if (attr.GetFont().GetWeight() == wxNORMAL)
1929 msg += wxT(" NORMAL");
1930
1931 if (attr.GetFont().GetStyle() == wxITALIC)
1932 msg += wxT(" ITALIC");
1933
1934 if (attr.GetFont().GetUnderlined())
1935 msg += wxT(" UNDERLINED");
1936 }
1937
80185c6c
JS
1938 SetStatusText(msg);
1939 }
8520f137 1940#endif // wxUSE_STATUSBAR
80185c6c 1941 m_currentPosition = insertionPoint;
e00a5d3c
JS
1942 }
1943}