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