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