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