don't log mouse events by default
[wxWidgets.git] / samples / text / text.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: text.cpp
3 // Purpose: TextCtrl wxWindows sample
4 // Author: Robert Roebling
5 // Modified by:
6 // RCS-ID: $Id$
7 // Copyright: (c) Robert Roebling, Julian Smart, Vadim Zeitlin
8 // Licence: wxWindows license
9 /////////////////////////////////////////////////////////////////////////////
10
11 #ifdef __GNUG__
12 #pragma implementation "text.cpp"
13 #endif
14
15 // For compilers that support precompilation, includes "wx/wx.h".
16 #include "wx/wxprec.h"
17
18 #ifdef __BORLANDC__
19 #pragma hdrstop
20 #endif
21
22 #ifndef WX_PRECOMP
23 #include "wx/wx.h"
24 #endif
25
26 #if wxUSE_CLIPBOARD
27 #include "wx/dataobj.h"
28 #include "wx/clipbrd.h"
29 #endif
30
31 #if wxUSE_FILE
32 #include "wx/file.h"
33 #endif
34
35 #if wxUSE_TOOLTIPS
36 #include "wx/tooltip.h"
37 #endif
38
39 // We test for wxUSE_DRAG_AND_DROP also, because data objects may not be
40 // implemented for compilers that can't cope with the OLE parts in
41 // wxUSE_DRAG_AND_DROP.
42 #if !wxUSE_DRAG_AND_DROP
43 #undef wxUSE_CLIPBOARD
44 #define wxUSE_CLIPBOARD 0
45 #endif
46
47 //----------------------------------------------------------------------
48 // class definitions
49 //----------------------------------------------------------------------
50
51 class MyApp: public wxApp
52 {
53 public:
54 bool OnInit();
55 };
56
57 // a text ctrl which allows to call different wxTextCtrl functions
58 // interactively by pressing function keys in it
59 class MyTextCtrl : public wxTextCtrl
60 {
61 public:
62 MyTextCtrl(wxWindow *parent, wxWindowID id, const wxString &value,
63 const wxPoint &pos, const wxSize &size, int style = 0)
64 : wxTextCtrl(parent, id, value, pos, size, style)
65 {
66 m_hasCapture = FALSE;
67 }
68
69 void OnKeyDown(wxKeyEvent& event);
70 void OnKeyUp(wxKeyEvent& event);
71 void OnChar(wxKeyEvent& event);
72
73 void OnText(wxCommandEvent& event);
74 void OnTextURL(wxTextUrlEvent& event);
75 void OnTextMaxLen(wxCommandEvent& event);
76
77 void OnMouseEvent(wxMouseEvent& event);
78
79 static bool ms_logKey;
80 static bool ms_logChar;
81 static bool ms_logMouse;
82
83 private:
84 static inline wxChar GetChar(bool on, wxChar c) { return on ? c : _T('-'); }
85 void LogEvent(const wxChar *name, wxKeyEvent& event) const;
86
87 bool m_hasCapture;
88
89 DECLARE_EVENT_TABLE()
90 };
91
92 class MyPanel: public wxPanel
93 {
94 public:
95 MyPanel(wxFrame *frame, int x, int y, int w, int h);
96
97 #if wxUSE_CLIPBOARD
98 void DoPasteFromClipboard();
99 void DoCopyToClipboard();
100 #endif // wxUSE_CLIPBOARD
101
102 void DoMoveToEndOfText();
103 void DoMoveToEndOfEntry();
104
105 void OnSize( wxSizeEvent &event );
106
107 MyTextCtrl *m_text;
108 MyTextCtrl *m_password;
109 MyTextCtrl *m_enter;
110 MyTextCtrl *m_tab;
111 MyTextCtrl *m_readonly;
112 MyTextCtrl *m_limited;
113
114 MyTextCtrl *m_multitext;
115 MyTextCtrl *m_horizontal;
116
117 MyTextCtrl *m_textrich;
118
119 wxTextCtrl *m_log;
120
121 private:
122 DECLARE_EVENT_TABLE()
123 };
124
125 class MyFrame: public wxFrame
126 {
127 public:
128 MyFrame(wxFrame *frame, const char *title, int x, int y, int w, int h);
129
130 void OnQuit(wxCommandEvent& event);
131 void OnAbout(wxCommandEvent& event);
132 #if wxUSE_TOOLTIPS
133 void OnSetTooltipDelay(wxCommandEvent& event);
134 void OnToggleTooltips(wxCommandEvent& event);
135 #endif // wxUSE_TOOLTIPS
136
137 #if wxUSE_CLIPBOARD
138 void OnPasteFromClipboard( wxCommandEvent &event )
139 { m_panel->DoPasteFromClipboard(); }
140 void OnCopyToClipboard( wxCommandEvent &event )
141 { m_panel->DoCopyToClipboard(); }
142 #endif // wxUSE_CLIPBOARD
143
144 void OnAddTextFreeze( wxCommandEvent& event )
145 { DoAddText(true); }
146 void OnAddText( wxCommandEvent& event )
147 { DoAddText(false); }
148
149 void OnMoveToEndOfText( wxCommandEvent &event )
150 { m_panel->DoMoveToEndOfText(); }
151 void OnMoveToEndOfEntry( wxCommandEvent &event )
152 { m_panel->DoMoveToEndOfEntry(); }
153
154 void OnScrollLineDown(wxCommandEvent& event)
155 {
156 if ( !m_panel->m_textrich->LineDown() )
157 wxLogMessage(_T("Already at the bottom"));
158 }
159
160 void OnScrollLineUp(wxCommandEvent& event)
161 {
162 if ( !m_panel->m_textrich->LineUp() )
163 wxLogMessage(_T("Already at the top"));
164 }
165
166 void OnScrollPageDown(wxCommandEvent& event)
167 {
168 if ( !m_panel->m_textrich->PageDown() )
169 wxLogMessage(_T("Already at the bottom"));
170 }
171
172 void OnScrollPageUp(wxCommandEvent& event)
173 {
174 if ( !m_panel->m_textrich->PageUp() )
175 wxLogMessage(_T("Already at the top"));
176 }
177
178 void OnLogClear(wxCommandEvent& event);
179 void OnFileSave(wxCommandEvent& event);
180 void OnFileLoad(wxCommandEvent& event);
181
182 void OnSetEditable(wxCommandEvent& event);
183 void OnSetEnabled(wxCommandEvent& event);
184
185 void OnLogKey(wxCommandEvent& event)
186 {
187 MyTextCtrl::ms_logKey = event.IsChecked();
188 }
189
190 void OnLogChar(wxCommandEvent& event)
191 {
192 MyTextCtrl::ms_logChar = event.IsChecked();
193 }
194
195 void OnLogMouse(wxCommandEvent& event)
196 {
197 MyTextCtrl::ms_logMouse = event.IsChecked();
198 }
199
200 void OnIdle( wxIdleEvent& event );
201
202 private:
203 void DoAddText(bool freeze)
204 {
205 wxTextCtrl *text = m_panel->m_textrich;
206 if ( freeze )
207 text->Freeze();
208
209 for ( int i = 0; i < 100; i++ )
210 text->AppendText(wxString::Format(wxT("Line %i\n"), i));
211
212 text->SetInsertionPoint(0);
213
214 if ( freeze )
215 text->Thaw();
216 }
217
218 MyPanel *m_panel;
219
220 DECLARE_EVENT_TABLE()
221 };
222
223 //----------------------------------------------------------------------
224 // main()
225 //----------------------------------------------------------------------
226
227 IMPLEMENT_APP(MyApp)
228
229 //----------------------------------------------------------------------
230 // MyApp
231 //----------------------------------------------------------------------
232
233 enum
234 {
235 TEXT_QUIT = 100,
236 TEXT_ABOUT,
237 TEXT_LOAD,
238 TEXT_SAVE,
239 TEXT_CLEAR,
240
241 // clipboard menu
242 TEXT_CLIPBOARD_COPY = 200,
243 TEXT_CLIPBOARD_PASTE,
244
245 // tooltip menu
246 TEXT_TOOLTIPS_SETDELAY = 300,
247 TEXT_TOOLTIPS_ENABLE,
248
249 // text menu
250 TEXT_ADD_SOME = 400,
251 TEXT_ADD_FREEZE,
252 TEXT_MOVE_ENDTEXT,
253 TEXT_MOVE_ENDENTRY,
254 TEXT_SET_EDITABLE,
255 TEXT_SET_ENABLED,
256 TEXT_LINE_DOWN,
257 TEXT_LINE_UP,
258 TEXT_PAGE_DOWN,
259 TEXT_PAGE_UP,
260
261 // log menu
262 TEXT_LOG_KEY,
263 TEXT_LOG_CHAR,
264 TEXT_LOG_MOUSE,
265
266 TEXT_END
267 };
268
269 bool MyApp::OnInit()
270 {
271 // Create the main frame window
272 MyFrame *frame = new MyFrame((wxFrame *) NULL,
273 "Text wxWindows sample", 50, 50, 700, 420);
274 frame->SetSizeHints( 500, 400 );
275
276 wxMenu *file_menu = new wxMenu;
277 file_menu->Append(TEXT_SAVE, "&Save file\tCtrl-S",
278 "Save the text control contents to file");
279 file_menu->Append(TEXT_LOAD, "&Load file\tCtrl-O",
280 "Load the sample file into text control");
281 file_menu->AppendSeparator();
282 file_menu->Append(TEXT_ABOUT, "&About\tAlt-A");
283 file_menu->AppendSeparator();
284 file_menu->Append(TEXT_QUIT, "E&xit\tAlt-X", "Quit this sample");
285
286 wxMenuBar *menu_bar = new wxMenuBar( wxMB_DOCKABLE );
287 menu_bar->Append(file_menu, "&File");
288
289 #if wxUSE_TOOLTIPS
290 wxMenu *tooltip_menu = new wxMenu;
291 tooltip_menu->Append(TEXT_TOOLTIPS_SETDELAY, "Set &delay\tCtrl-D");
292 tooltip_menu->AppendSeparator();
293 tooltip_menu->Append(TEXT_TOOLTIPS_ENABLE, "&Toggle tooltips\tCtrl-T",
294 "enable/disable tooltips", TRUE);
295 tooltip_menu->Check(TEXT_TOOLTIPS_ENABLE, TRUE);
296 menu_bar->Append(tooltip_menu, "&Tooltips");
297 #endif // wxUSE_TOOLTIPS
298
299 #if wxUSE_CLIPBOARD
300 wxMenu *menuClipboard = new wxMenu;
301 menuClipboard->Append(TEXT_CLIPBOARD_COPY, "&Copy\tCtrl-C",
302 "Copy the first line to the clipboard");
303 menuClipboard->Append(TEXT_CLIPBOARD_PASTE, "&Paste\tCtrl-V",
304 "Paste from clipboard to the text control");
305 menu_bar->Append(menuClipboard, "&Clipboard");
306 #endif // wxUSE_CLIPBOARD
307
308 wxMenu *menuText = new wxMenu;
309 menuText->Append(TEXT_ADD_SOME, "&Append some text\tCtrl-A");
310 menuText->Append(TEXT_ADD_FREEZE, "&Append text with freeze/thaw\tShift-Ctrl-A");
311 menuText->Append(TEXT_MOVE_ENDTEXT, "Move cursor to the end of &text");
312 menuText->Append(TEXT_MOVE_ENDENTRY, "Move cursor to the end of &entry");
313 menuText->Append(TEXT_SET_EDITABLE, "Toggle &editable state", "", TRUE);
314 menuText->Append(TEXT_SET_ENABLED, "Toggle e&nabled state", "", TRUE);
315 menuText->Check(TEXT_SET_EDITABLE, TRUE);
316 menuText->Check(TEXT_SET_ENABLED, TRUE);
317 menuText->AppendSeparator();
318 menuText->Append(TEXT_LINE_DOWN, "Scroll text one line down");
319 menuText->Append(TEXT_LINE_UP, "Scroll text one line up");
320 menuText->Append(TEXT_PAGE_DOWN, "Scroll text one page down");
321 menuText->Append(TEXT_PAGE_DOWN, "Scroll text one page up");
322 menu_bar->Append(menuText, "Te&xt");
323
324 wxMenu *menuLog = new wxMenu;
325 menuLog->Append(TEXT_LOG_KEY, "Log &key events", "", TRUE);
326 menuLog->Append(TEXT_LOG_CHAR, "Log &char events", "", TRUE);
327 menuLog->Append(TEXT_LOG_MOUSE, "Log &mouse events", "", TRUE);
328 menuLog->AppendSeparator();
329 menuLog->Append(TEXT_CLEAR, "&Clear the log\tCtrl-C",
330 "Clear the log window contents");
331 menuLog->Check(TEXT_LOG_KEY, TRUE);
332 menuLog->Check(TEXT_LOG_CHAR, TRUE);
333 menu_bar->Append(menuLog, "&Log");
334
335 frame->SetMenuBar(menu_bar);
336
337 frame->Show(TRUE);
338
339 SetTopWindow(frame);
340
341 // report success
342 return TRUE;
343 }
344
345 //----------------------------------------------------------------------
346 // MyTextCtrl
347 //----------------------------------------------------------------------
348
349 BEGIN_EVENT_TABLE(MyTextCtrl, wxTextCtrl)
350 EVT_KEY_DOWN(MyTextCtrl::OnKeyDown)
351 EVT_KEY_UP(MyTextCtrl::OnKeyUp)
352 EVT_CHAR(MyTextCtrl::OnChar)
353
354 EVT_TEXT(-1, MyTextCtrl::OnText)
355 EVT_TEXT_URL(-1, MyTextCtrl::OnTextURL)
356 EVT_TEXT_MAXLEN(-1, MyTextCtrl::OnTextMaxLen)
357
358 EVT_MOUSE_EVENTS(MyTextCtrl::OnMouseEvent)
359 END_EVENT_TABLE()
360
361 bool MyTextCtrl::ms_logKey = TRUE;
362 bool MyTextCtrl::ms_logChar = TRUE;
363 bool MyTextCtrl::ms_logMouse = FALSE;
364
365 void MyTextCtrl::LogEvent(const wxChar *name, wxKeyEvent& event) const
366 {
367 wxString key;
368 long keycode = event.KeyCode();
369 {
370 switch ( keycode )
371 {
372 case WXK_BACK: key = "BACK"; break;
373 case WXK_TAB: key = "TAB"; break;
374 case WXK_RETURN: key = "RETURN"; break;
375 case WXK_ESCAPE: key = "ESCAPE"; break;
376 case WXK_SPACE: key = "SPACE"; break;
377 case WXK_DELETE: key = "DELETE"; break;
378 case WXK_START: key = "START"; break;
379 case WXK_LBUTTON: key = "LBUTTON"; break;
380 case WXK_RBUTTON: key = "RBUTTON"; break;
381 case WXK_CANCEL: key = "CANCEL"; break;
382 case WXK_MBUTTON: key = "MBUTTON"; break;
383 case WXK_CLEAR: key = "CLEAR"; break;
384 case WXK_SHIFT: key = "SHIFT"; break;
385 case WXK_ALT: key = "ALT"; break;
386 case WXK_CONTROL: key = "CONTROL"; break;
387 case WXK_MENU: key = "MENU"; break;
388 case WXK_PAUSE: key = "PAUSE"; break;
389 case WXK_CAPITAL: key = "CAPITAL"; break;
390 case WXK_PRIOR: key = "PRIOR"; break;
391 case WXK_NEXT: key = "NEXT"; break;
392 case WXK_END: key = "END"; break;
393 case WXK_HOME: key = "HOME"; break;
394 case WXK_LEFT: key = "LEFT"; break;
395 case WXK_UP: key = "UP"; break;
396 case WXK_RIGHT: key = "RIGHT"; break;
397 case WXK_DOWN: key = "DOWN"; break;
398 case WXK_SELECT: key = "SELECT"; break;
399 case WXK_PRINT: key = "PRINT"; break;
400 case WXK_EXECUTE: key = "EXECUTE"; break;
401 case WXK_SNAPSHOT: key = "SNAPSHOT"; break;
402 case WXK_INSERT: key = "INSERT"; break;
403 case WXK_HELP: key = "HELP"; break;
404 case WXK_NUMPAD0: key = "NUMPAD0"; break;
405 case WXK_NUMPAD1: key = "NUMPAD1"; break;
406 case WXK_NUMPAD2: key = "NUMPAD2"; break;
407 case WXK_NUMPAD3: key = "NUMPAD3"; break;
408 case WXK_NUMPAD4: key = "NUMPAD4"; break;
409 case WXK_NUMPAD5: key = "NUMPAD5"; break;
410 case WXK_NUMPAD6: key = "NUMPAD6"; break;
411 case WXK_NUMPAD7: key = "NUMPAD7"; break;
412 case WXK_NUMPAD8: key = "NUMPAD8"; break;
413 case WXK_NUMPAD9: key = "NUMPAD9"; break;
414 case WXK_MULTIPLY: key = "MULTIPLY"; break;
415 case WXK_ADD: key = "ADD"; break;
416 case WXK_SEPARATOR: key = "SEPARATOR"; break;
417 case WXK_SUBTRACT: key = "SUBTRACT"; break;
418 case WXK_DECIMAL: key = "DECIMAL"; break;
419 case WXK_DIVIDE: key = "DIVIDE"; break;
420 case WXK_F1: key = "F1"; break;
421 case WXK_F2: key = "F2"; break;
422 case WXK_F3: key = "F3"; break;
423 case WXK_F4: key = "F4"; break;
424 case WXK_F5: key = "F5"; break;
425 case WXK_F6: key = "F6"; break;
426 case WXK_F7: key = "F7"; break;
427 case WXK_F8: key = "F8"; break;
428 case WXK_F9: key = "F9"; break;
429 case WXK_F10: key = "F10"; break;
430 case WXK_F11: key = "F11"; break;
431 case WXK_F12: key = "F12"; break;
432 case WXK_F13: key = "F13"; break;
433 case WXK_F14: key = "F14"; break;
434 case WXK_F15: key = "F15"; break;
435 case WXK_F16: key = "F16"; break;
436 case WXK_F17: key = "F17"; break;
437 case WXK_F18: key = "F18"; break;
438 case WXK_F19: key = "F19"; break;
439 case WXK_F20: key = "F20"; break;
440 case WXK_F21: key = "F21"; break;
441 case WXK_F22: key = "F22"; break;
442 case WXK_F23: key = "F23"; break;
443 case WXK_F24: key = "F24"; break;
444 case WXK_NUMLOCK: key = "NUMLOCK"; break;
445 case WXK_SCROLL: key = "SCROLL"; break;
446 case WXK_PAGEUP: key = "PAGEUP"; break;
447 case WXK_PAGEDOWN: key = "PAGEDOWN"; break;
448 case WXK_NUMPAD_SPACE: key = "NUMPAD_SPACE"; break;
449 case WXK_NUMPAD_TAB: key = "NUMPAD_TAB"; break;
450 case WXK_NUMPAD_ENTER: key = "NUMPAD_ENTER"; break;
451 case WXK_NUMPAD_F1: key = "NUMPAD_F1"; break;
452 case WXK_NUMPAD_F2: key = "NUMPAD_F2"; break;
453 case WXK_NUMPAD_F3: key = "NUMPAD_F3"; break;
454 case WXK_NUMPAD_F4: key = "NUMPAD_F4"; break;
455 case WXK_NUMPAD_HOME: key = "NUMPAD_HOME"; break;
456 case WXK_NUMPAD_LEFT: key = "NUMPAD_LEFT"; break;
457 case WXK_NUMPAD_UP: key = "NUMPAD_UP"; break;
458 case WXK_NUMPAD_RIGHT: key = "NUMPAD_RIGHT"; break;
459 case WXK_NUMPAD_DOWN: key = "NUMPAD_DOWN"; break;
460 case WXK_NUMPAD_PRIOR: key = "NUMPAD_PRIOR"; break;
461 case WXK_NUMPAD_PAGEUP: key = "NUMPAD_PAGEUP"; break;
462 case WXK_NUMPAD_PAGEDOWN: key = "NUMPAD_PAGEDOWN"; break;
463 case WXK_NUMPAD_END: key = "NUMPAD_END"; break;
464 case WXK_NUMPAD_BEGIN: key = "NUMPAD_BEGIN"; break;
465 case WXK_NUMPAD_INSERT: key = "NUMPAD_INSERT"; break;
466 case WXK_NUMPAD_DELETE: key = "NUMPAD_DELETE"; break;
467 case WXK_NUMPAD_EQUAL: key = "NUMPAD_EQUAL"; break;
468 case WXK_NUMPAD_MULTIPLY: key = "NUMPAD_MULTIPLY"; break;
469 case WXK_NUMPAD_ADD: key = "NUMPAD_ADD"; break;
470 case WXK_NUMPAD_SEPARATOR: key = "NUMPAD_SEPARATOR"; break;
471 case WXK_NUMPAD_SUBTRACT: key = "NUMPAD_SUBTRACT"; break;
472 case WXK_NUMPAD_DECIMAL: key = "NUMPAD_DECIMAL"; break;
473
474 default:
475 {
476 if ( wxIsprint((int)keycode) )
477 key.Printf( _T("'%c'") , (char)keycode);
478 else
479 key.Printf( _T("unknown (%ld)"), keycode);
480 }
481 }
482 }
483
484 wxLogMessage( _T("%s event: %s (flags = %c%c%c%c)"),
485 name,
486 key.c_str(),
487 GetChar( event.ControlDown(), _T('C') ),
488 GetChar( event.AltDown(), _T('A') ),
489 GetChar( event.ShiftDown(), _T('S') ),
490 GetChar( event.MetaDown(), _T('M') ) );
491 }
492
493 static wxString GetMouseEventDesc(const wxMouseEvent& ev)
494 {
495 // click event
496 wxString button;
497 bool dbl, up;
498 if ( ev.LeftDown() || ev.LeftUp() || ev.LeftDClick() )
499 {
500 button = _T("Left");
501 dbl = ev.LeftDClick();
502 up = ev.LeftUp();
503 }
504 else if ( ev.MiddleDown() || ev.MiddleUp() || ev.MiddleDClick() )
505 {
506 button = _T("Middle");
507 dbl = ev.MiddleDClick();
508 up = ev.MiddleUp();
509 }
510 else if ( ev.RightDown() || ev.RightUp() || ev.RightDClick() )
511 {
512 button = _T("Right");
513 dbl = ev.RightDClick();
514 up = ev.RightUp();
515 }
516 else
517 {
518 return _T("Unknown mouse event");
519 }
520
521 return wxString::Format(_T("%s mouse button %s"),
522 button.c_str(),
523 dbl ? _T("double clicked")
524 : up ? _T("released") : _T("clicked"));
525 }
526
527 void MyTextCtrl::OnMouseEvent(wxMouseEvent& ev)
528 {
529 ev.Skip();
530
531 if ( !MyTextCtrl::ms_logMouse )
532 return;
533
534 if ( !ev.Moving() )
535 {
536 wxString msg;
537 if ( ev.Entering() )
538 {
539 msg = _T("Mouse entered the window");
540 }
541 else if ( ev.Leaving() )
542 {
543 msg = _T("Mouse left the window");
544 }
545 else
546 {
547 msg = GetMouseEventDesc(ev);
548 }
549
550 msg << _T(" at (") << ev.GetX() << _T(", ") << ev.GetY() << _T(") ")
551 << _T("Flags: ")
552 << GetChar( ev.LeftIsDown(), _T('1') )
553 << GetChar( ev.MiddleIsDown(), _T('2') )
554 << GetChar( ev.RightIsDown(), _T('3') )
555 << GetChar( ev.ControlDown(), _T('C') )
556 << GetChar( ev.AltDown(), _T('A') )
557 << GetChar( ev.ShiftDown(), _T('S') )
558 << GetChar( ev.MetaDown(), _T('M') );
559
560 wxLogMessage(msg);
561 }
562 //else: we're not interested in mouse move events
563 }
564
565 void MyTextCtrl::OnText(wxCommandEvent& event)
566 {
567 MyTextCtrl *win = (MyTextCtrl *)event.GetEventObject();
568 const wxChar *data = (const wxChar *)(win->GetClientData());
569 if ( data )
570 {
571 wxLogMessage(_T("Text changed in control '%s'"), data);
572 }
573 else
574 {
575 wxLogMessage(_T("Text changed in some control"));
576 }
577 }
578
579 void MyTextCtrl::OnTextMaxLen(wxCommandEvent& event)
580 {
581 wxLogMessage(_T("You can't enter more characters into this control."));
582 }
583
584 void MyTextCtrl::OnTextURL(wxTextUrlEvent& event)
585 {
586 const wxMouseEvent& ev = event.GetMouseEvent();
587
588 // filter out mouse moves, too many of them
589 if ( ev.Moving() )
590 return;
591
592 long start = event.GetURLStart(),
593 end = event.GetURLEnd();
594
595 wxLogMessage(_T("Mouse event over URL '%s': %s"),
596 GetValue().Mid(start, end - start).c_str(),
597 GetMouseEventDesc(ev).c_str());
598 }
599
600 void MyTextCtrl::OnChar(wxKeyEvent& event)
601 {
602 if ( MyTextCtrl::ms_logChar )
603 LogEvent( _T("Char"), event);
604
605 event.Skip();
606 }
607
608 void MyTextCtrl::OnKeyUp(wxKeyEvent& event)
609 {
610 if ( MyTextCtrl::ms_logKey )
611 LogEvent( _T("Key up"), event);
612
613 event.Skip();
614 }
615
616 void MyTextCtrl::OnKeyDown(wxKeyEvent& event)
617 {
618 switch ( event.KeyCode() )
619 {
620 case WXK_F1:
621 // show current position and text length
622 {
623 long line, column, pos = GetInsertionPoint();
624 PositionToXY(pos, &column, &line);
625
626 wxLogMessage( _T("Current position: %ld\nCurrent line, column: (%ld, %ld)\nNumber of lines: %ld\nCurrent line length: %ld\nTotal text length: %u (%ld)"),
627 pos,
628 line, column,
629 GetNumberOfLines(),
630 GetLineLength(line),
631 GetValue().length(),
632 GetLastPosition());
633 }
634 break;
635
636 case WXK_F2:
637 // go to the end
638 SetInsertionPointEnd();
639 break;
640
641 case WXK_F3:
642 // go to position 10
643 SetInsertionPoint(10);
644 break;
645
646 case WXK_F4:
647 if (!m_hasCapture)
648 {
649 wxLogDebug( wxT("Now capturing mouse and events.") );
650 m_hasCapture = TRUE;
651 CaptureMouse();
652 }
653 else
654 {
655 wxLogDebug( wxT("Stopped capturing mouse and events.") );
656 m_hasCapture = TRUE;
657 ReleaseMouse();
658 }
659 break;
660
661 case WXK_F5:
662 // insert a blank line
663 WriteText("\n");
664 break;
665
666 case WXK_F6:
667 SetValue("F6 was just pressed.");
668 break;
669
670 case WXK_F7:
671 ShowPosition(10);
672 break;
673 }
674
675 if ( MyTextCtrl::ms_logKey )
676 LogEvent( wxT("Key down"), event);
677
678 event.Skip();
679 }
680
681 //----------------------------------------------------------------------
682 // MyPanel
683 //----------------------------------------------------------------------
684
685 BEGIN_EVENT_TABLE(MyPanel, wxPanel)
686 EVT_SIZE(MyPanel::OnSize)
687 END_EVENT_TABLE()
688
689 MyPanel::MyPanel( wxFrame *frame, int x, int y, int w, int h )
690 : wxPanel( frame, -1, wxPoint(x, y), wxSize(w, h) )
691 {
692 m_log = new wxTextCtrl( this, -1, "This is the log window.\n", wxPoint(5,260), wxSize(630,100), wxTE_MULTILINE );
693
694 wxLog *old_log = wxLog::SetActiveTarget( new wxLogTextCtrl( m_log ) );
695
696 delete old_log;
697
698 // single line text controls
699
700 m_text = new MyTextCtrl( this, -1, "Single line.",
701 wxPoint(10,10), wxSize(140,-1),
702 wxTE_PROCESS_ENTER);
703 m_text->SetForegroundColour(*wxBLUE);
704 m_text->SetBackgroundColour(*wxLIGHT_GREY);
705 (*m_text) << " Appended.";
706 m_text->SetInsertionPoint(0);
707 m_text->WriteText( "Prepended. " );
708
709 m_password = new MyTextCtrl( this, -1, "",
710 wxPoint(10,50), wxSize(140,-1), wxTE_PASSWORD );
711
712 m_readonly = new MyTextCtrl( this, -1, "Read only",
713 wxPoint(10,90), wxSize(140,-1), wxTE_READONLY );
714
715 m_limited = new MyTextCtrl(this, -1, "Max 8 ch",
716 wxPoint(10, 130), wxSize(140, -1));
717 m_limited->SetMaxLength(8);
718
719 // multi line text controls
720
721 m_horizontal = new MyTextCtrl( this, -1, "Multiline text control with a horizontal scrollbar.",
722 wxPoint(10,170), wxSize(140,70), wxTE_MULTILINE | wxHSCROLL );
723
724 // a little hack to use the command line argument for encoding testing
725 if ( wxTheApp->argc == 2 )
726 {
727 switch ( wxTheApp->argv[1][0] )
728 {
729 case '2':
730 m_horizontal->SetFont(wxFont(18, wxSWISS, wxNORMAL, wxNORMAL,
731 FALSE, "",
732 wxFONTENCODING_ISO8859_2));
733 m_horizontal->SetValue("®lu»ouèký kùò zbìsile èe¹tina «»");
734 break;
735
736 default:
737 m_horizontal->SetFont(wxFont(18, wxSWISS, wxNORMAL, wxNORMAL,
738 FALSE, "",
739 wxFONTENCODING_KOI8));
740 m_horizontal->SetValue("ËÁÖÅÔÓÑ ÕÄÁÞÎÙÍ");
741 }
742 }
743 else
744 {
745 m_horizontal->SetValue("Text in default encoding");
746 }
747
748 m_multitext = new MyTextCtrl( this, -1, "Multi line.",
749 wxPoint(180,10), wxSize(240,70), wxTE_MULTILINE );
750 m_multitext->SetFont(*wxITALIC_FONT);
751 (*m_multitext) << " Appended.";
752 m_multitext->SetInsertionPoint(0);
753 m_multitext->WriteText( "Prepended. " );
754 m_multitext->SetForegroundColour(*wxRED);
755 m_multitext->SetBackgroundColour(*wxLIGHT_GREY);
756
757 #if wxUSE_TOOLTIPS
758 m_multitext->SetToolTip("Press F1 here for statitics, F4 for capture and uncapture mouse.");
759 #endif
760
761 m_tab = new MyTextCtrl( this, 100, "Multiline, allow <TAB> processing.",
762 wxPoint(180,90), wxSize(240,70), wxTE_MULTILINE | wxTE_PROCESS_TAB );
763 m_tab->SetClientData((void *)_T("tab"));
764
765 m_enter = new MyTextCtrl( this, 100, "Multiline, allow <ENTER> processing.",
766 wxPoint(180,170), wxSize(240,70), wxTE_MULTILINE);
767 m_enter->SetClientData((void *)_T("enter"));
768
769 m_textrich = new MyTextCtrl(this, -1, "Allows more than 30Kb of text\n"
770 "(even under broken Win9x)\n"
771 "and a very very very very very "
772 "very very very long line to test "
773 "wxHSCROLL style",
774 wxPoint(450, 10), wxSize(230, 230),
775 wxTE_RICH |
776 wxTE_MULTILINE |
777 wxTE_AUTO_URL |
778 wxHSCROLL);
779
780 #if 1
781 m_textrich->SetStyle(0, 10, *wxRED);
782 m_textrich->SetStyle(10, 20, *wxBLUE);
783 m_textrich->SetStyle(30, 40,
784 wxTextAttr(*wxGREEN, wxNullColour, *wxITALIC_FONT));
785 m_textrich->SetDefaultStyle(wxTextAttr());
786 m_textrich->AppendText(_T("\n\nFirst 10 characters should be in red\n"));
787 m_textrich->AppendText(_T("Next 10 characters should be in blue\n"));
788 m_textrich->AppendText(_T("Next 10 characters should be normal\n"));
789 m_textrich->AppendText(_T("And the next 10 characters should be green and italic\n"));
790 m_textrich->SetDefaultStyle(wxTextAttr(*wxCYAN, *wxBLUE));
791 m_textrich->AppendText(_T("This text should be cyan on blue\n"));
792 m_textrich->SetDefaultStyle(*wxBLUE);
793 m_textrich->AppendText(_T("And this should be in blue and the text you ")
794 _T("type should be in blue as well"));
795 #else
796 m_textrich->SetFont(wxFont(12, wxFONTFAMILY_TELETYPE,
797 wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL));
798 m_textrich->SetDefaultStyle(wxTextAttr(*wxRED));
799 m_textrich->AppendText(_T("Red text\n"));
800 m_textrich->SetDefaultStyle(wxTextAttr(wxNullColour, *wxLIGHT_GREY));
801 m_textrich->AppendText(_T("Red on grey text\n"));
802 m_textrich->SetDefaultStyle(wxTextAttr(*wxBLUE));
803 m_textrich->AppendText(_T("Blue on grey text\n"));
804 #endif
805 }
806
807 void MyPanel::OnSize( wxSizeEvent &event )
808 {
809 wxSize client_area( GetClientSize() );
810 m_log->SetSize( 0, 260, client_area.x, client_area.y - 260 );
811 event.Skip();
812 }
813
814 #if wxUSE_CLIPBOARD
815 void MyPanel::DoPasteFromClipboard()
816 {
817 // On X11, we want to get the data from the primary selection instead
818 // of the normal clipboard (which isn't normal under X11 at all). This
819 // call has no effect under MSW.
820 wxTheClipboard->UsePrimarySelection();
821
822 if (!wxTheClipboard->Open())
823 {
824 *m_log << "Error opening the clipboard.\n";
825 return;
826 }
827 else
828 {
829 *m_log << "Successfully opened the clipboard.\n";
830 }
831
832 wxTextDataObject data;
833
834 if (wxTheClipboard->IsSupported( data.GetFormat() ))
835 {
836 *m_log << "Clipboard supports requested format.\n";
837
838 if (wxTheClipboard->GetData( data ))
839 {
840 *m_log << "Successfully retrieved data from the clipboard.\n";
841 *m_multitext << data.GetText() << "\n";
842 }
843 else
844 {
845 *m_log << "Error getting data from the clipboard.\n";
846 }
847 }
848 else
849 {
850 *m_log << "Clipboard doesn't support requested format.\n";
851 }
852
853 wxTheClipboard->Close();
854
855 *m_log << "Closed the clipboard.\n";
856 }
857
858 void MyPanel::DoCopyToClipboard()
859 {
860 // On X11, we want to get the data from the primary selection instead
861 // of the normal clipboard (which isn't normal under X11 at all). This
862 // call has no effect under MSW.
863 wxTheClipboard->UsePrimarySelection();
864
865 wxString text( m_multitext->GetLineText(0) );
866
867 if (text.IsEmpty())
868 {
869 *m_log << "No text to copy.\n";
870
871 return;
872 }
873
874 if (!wxTheClipboard->Open())
875 {
876 *m_log << "Error opening the clipboard.\n";
877
878 return;
879 }
880 else
881 {
882 *m_log << "Successfully opened the clipboard.\n";
883 }
884
885 wxTextDataObject *data = new wxTextDataObject( text );
886
887 if (!wxTheClipboard->SetData( data ))
888 {
889 *m_log << "Error while copying to the clipboard.\n";
890 }
891 else
892 {
893 *m_log << "Successfully copied data to the clipboard.\n";
894 }
895
896 wxTheClipboard->Close();
897
898 *m_log << "Closed the clipboard.\n";
899 }
900
901 #endif // wxUSE_CLIPBOARD
902
903 void MyPanel::DoMoveToEndOfText()
904 {
905 m_multitext->SetInsertionPointEnd();
906 m_multitext->SetFocus();
907 }
908
909 void MyPanel::DoMoveToEndOfEntry()
910 {
911 m_text->SetInsertionPointEnd();
912 m_text->SetFocus();
913 }
914
915 //----------------------------------------------------------------------
916 // MyFrame
917 //----------------------------------------------------------------------
918
919 BEGIN_EVENT_TABLE(MyFrame, wxFrame)
920 EVT_MENU(TEXT_QUIT, MyFrame::OnQuit)
921 EVT_MENU(TEXT_ABOUT, MyFrame::OnAbout)
922 EVT_MENU(TEXT_SAVE, MyFrame::OnFileSave)
923 EVT_MENU(TEXT_LOAD, MyFrame::OnFileLoad)
924
925 EVT_MENU(TEXT_LOG_KEY, MyFrame::OnLogKey)
926 EVT_MENU(TEXT_LOG_CHAR, MyFrame::OnLogChar)
927 EVT_MENU(TEXT_LOG_MOUSE, MyFrame::OnLogMouse)
928 EVT_MENU(TEXT_CLEAR, MyFrame::OnLogClear)
929
930 #if wxUSE_TOOLTIPS
931 EVT_MENU(TEXT_TOOLTIPS_SETDELAY, MyFrame::OnSetTooltipDelay)
932 EVT_MENU(TEXT_TOOLTIPS_ENABLE, MyFrame::OnToggleTooltips)
933 #endif // wxUSE_TOOLTIPS
934
935 #if wxUSE_CLIPBOARD
936 EVT_MENU(TEXT_CLIPBOARD_PASTE, MyFrame::OnPasteFromClipboard)
937 EVT_MENU(TEXT_CLIPBOARD_COPY, MyFrame::OnCopyToClipboard)
938 #endif // wxUSE_CLIPBOARD
939
940 EVT_MENU(TEXT_ADD_SOME, MyFrame::OnAddText)
941 EVT_MENU(TEXT_ADD_FREEZE, MyFrame::OnAddTextFreeze)
942 EVT_MENU(TEXT_MOVE_ENDTEXT, MyFrame::OnMoveToEndOfText)
943 EVT_MENU(TEXT_MOVE_ENDENTRY, MyFrame::OnMoveToEndOfEntry)
944
945 EVT_MENU(TEXT_SET_EDITABLE, MyFrame::OnSetEditable)
946 EVT_MENU(TEXT_SET_ENABLED, MyFrame::OnSetEnabled)
947
948 EVT_MENU(TEXT_LINE_DOWN, MyFrame::OnScrollLineDown)
949 EVT_MENU(TEXT_LINE_UP, MyFrame::OnScrollLineUp)
950 EVT_MENU(TEXT_PAGE_DOWN, MyFrame::OnScrollPageDown)
951 EVT_MENU(TEXT_PAGE_UP, MyFrame::OnScrollPageUp)
952
953 EVT_IDLE(MyFrame::OnIdle)
954 END_EVENT_TABLE()
955
956 MyFrame::MyFrame(wxFrame *frame, const char *title, int x, int y, int w, int h)
957 : wxFrame(frame, -1, title, wxPoint(x, y), wxSize(w, h) )
958 {
959 CreateStatusBar(2);
960
961 m_panel = new MyPanel( this, 10, 10, 300, 100 );
962 }
963
964 void MyFrame::OnQuit (wxCommandEvent& WXUNUSED(event) )
965 {
966 Close(TRUE);
967 }
968
969 void MyFrame::OnAbout( wxCommandEvent& WXUNUSED(event) )
970 {
971 wxBeginBusyCursor();
972
973 wxMessageDialog dialog(this,
974 "This is a text control sample. It demonstrates the many different\n"
975 "text control styles, the use of the clipboard, setting and handling\n"
976 "tooltips and intercepting key and char events.\n"
977 "\n"
978 "Copyright (c) 1999, Robert Roebling, Julian Smart, Vadim Zeitlin",
979 "About wxTextCtrl Sample",
980 wxOK | wxICON_INFORMATION);
981
982 dialog.ShowModal();
983
984 wxEndBusyCursor();
985 }
986
987 #if wxUSE_TOOLTIPS
988 void MyFrame::OnSetTooltipDelay(wxCommandEvent& event)
989 {
990 static long s_delay = 5000;
991
992 wxString delay;
993 delay.Printf( _T("%ld"), s_delay);
994
995 delay = wxGetTextFromUser("Enter delay (in milliseconds)",
996 "Set tooltip delay",
997 delay,
998 this);
999 if ( !delay )
1000 return; // cancelled
1001
1002 wxSscanf(delay, _T("%ld"), &s_delay);
1003
1004 wxToolTip::SetDelay(s_delay);
1005
1006 wxLogStatus(this, _T("Tooltip delay set to %ld milliseconds"), s_delay);
1007 }
1008
1009 void MyFrame::OnToggleTooltips(wxCommandEvent& event)
1010 {
1011 static bool s_enabled = TRUE;
1012
1013 s_enabled = !s_enabled;
1014
1015 wxToolTip::Enable(s_enabled);
1016
1017 wxLogStatus(this, _T("Tooltips %sabled"), s_enabled ? _T("en") : _T("dis") );
1018 }
1019 #endif // tooltips
1020
1021 void MyFrame::OnLogClear(wxCommandEvent& WXUNUSED(event))
1022 {
1023 m_panel->m_log->Clear();
1024 }
1025
1026 void MyFrame::OnSetEditable(wxCommandEvent& WXUNUSED(event))
1027 {
1028 static bool s_editable = TRUE;
1029
1030 s_editable = !s_editable;
1031 m_panel->m_text->SetEditable(s_editable);
1032 m_panel->m_password->SetEditable(s_editable);
1033 m_panel->m_multitext->SetEditable(s_editable);
1034 m_panel->m_textrich->SetEditable(s_editable);
1035 }
1036
1037 void MyFrame::OnSetEnabled(wxCommandEvent& WXUNUSED(event))
1038 {
1039 bool enabled = m_panel->m_text->IsEnabled();
1040 enabled = !enabled;
1041
1042 m_panel->m_text->Enable(enabled);
1043 m_panel->m_password->Enable(enabled);
1044 m_panel->m_multitext->Enable(enabled);
1045 m_panel->m_readonly->Enable(enabled);
1046 m_panel->m_limited->Enable(enabled);
1047 m_panel->m_textrich->Enable(enabled);
1048 }
1049
1050 void MyFrame::OnFileSave(wxCommandEvent& event)
1051 {
1052 if ( m_panel->m_textrich->SaveFile("dummy.txt") )
1053 {
1054 #if wxUSE_FILE
1055 // verify that the fil length is correct (it wasn't under Win95)
1056 wxFile file(wxT("dummy.txt"));
1057 wxLogStatus(this, _T("Successfully saved file (text len = %ld, file size = %ld)"),
1058 m_panel->m_textrich->GetValue().length(),
1059 file.Length());
1060 #endif
1061 }
1062 else
1063 wxLogStatus(this, _T("Couldn't save the file"));
1064 }
1065
1066 void MyFrame::OnFileLoad(wxCommandEvent& event)
1067 {
1068 if ( m_panel->m_textrich->LoadFile("dummy.txt") )
1069 wxLogStatus(this, _T("Successfully loaded file"));
1070 else
1071 wxLogStatus(this, _T("Couldn't load the file"));
1072 }
1073
1074 void MyFrame::OnIdle( wxIdleEvent& event )
1075 {
1076 // track the window which has the focus in the status bar
1077 static wxWindow *s_windowFocus = (wxWindow *)NULL;
1078 wxWindow *focus = wxWindow::FindFocus();
1079 if ( focus && (focus != s_windowFocus) )
1080 {
1081 s_windowFocus = focus;
1082
1083 wxString msg;
1084 msg.Printf(
1085 #ifdef __WXMSW__
1086 _T("Focus: wxWindow = %p, HWND = %08x"),
1087 #else
1088 _T("Focus: wxWindow = %p"),
1089 #endif
1090 s_windowFocus
1091 #ifdef __WXMSW__
1092 , s_windowFocus->GetHWND()
1093 #endif
1094 );
1095
1096 SetStatusText(msg);
1097 }
1098 event.Skip();
1099 }