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