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