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