]> git.saurik.com Git - wxWidgets.git/blob - samples/widgets/textctrl.cpp
glibc's vswprintf doesn't nul terminate on truncation.
[wxWidgets.git] / samples / widgets / textctrl.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Program: wxWidgets Widgets Sample
3 // Name: textctrl.cpp
4 // Purpose: part of the widgets sample showing wxTextCtrl
5 // Author: Vadim Zeitlin
6 // Created: 27.03.01
7 // Id: $Id$
8 // Copyright: (c) 2001 Vadim Zeitlin
9 // License: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 // for compilers that support precompilation, includes "wx/wx.h".
21 #include "wx/wxprec.h"
22
23 #ifdef __BORLANDC__
24 #pragma hdrstop
25 #endif
26
27 // for all others, include the necessary headers
28 #ifndef WX_PRECOMP
29 #include "wx/log.h"
30 #include "wx/timer.h"
31
32 #include "wx/bitmap.h"
33 #include "wx/button.h"
34 #include "wx/checkbox.h"
35 #include "wx/radiobox.h"
36 #include "wx/statbox.h"
37 #include "wx/stattext.h"
38 #include "wx/textctrl.h"
39 #include "wx/msgdlg.h"
40 #endif
41
42 #include "wx/sizer.h"
43 #include "wx/ioswrap.h"
44
45 #include "widgets.h"
46
47 #include "icons/text.xpm"
48
49 // ----------------------------------------------------------------------------
50 // constants
51 // ----------------------------------------------------------------------------
52
53 // control ids
54 enum
55 {
56 TextPage_Reset = wxID_HIGHEST,
57
58 TextPage_Set,
59 TextPage_Add,
60 TextPage_Insert,
61 TextPage_Clear,
62 TextPage_Load,
63
64 TextPage_StreamRedirector,
65
66 TextPage_Password,
67 TextPage_WrapLines,
68 TextPage_Textctrl
69 };
70
71 // textctrl line number radiobox values
72 enum TextLines
73 {
74 TextLines_Single,
75 TextLines_Multi,
76 TextLines_Max
77 };
78
79 // wrap style radio box
80 enum WrapStyle
81 {
82 WrapStyle_None,
83 WrapStyle_Word,
84 WrapStyle_Char,
85 WrapStyle_Best,
86 WrapStyle_Max
87 };
88
89 #ifdef __WXMSW__
90
91 // textctrl kind values
92 enum TextKind
93 {
94 TextKind_Plain,
95 TextKind_Rich,
96 TextKind_Rich2,
97 TextKind_Max
98 };
99
100 #endif // __WXMSW__
101
102 // default values for the controls
103 static const struct ControlValues
104 {
105 TextLines textLines;
106
107 bool password;
108 bool readonly;
109 bool filename;
110
111 WrapStyle wrapStyle;
112
113 #ifdef __WXMSW__
114 TextKind textKind;
115 #endif // __WXMSW__
116 } DEFAULTS =
117 {
118 TextLines_Multi, // multiline
119 false, // not password
120 false, // not readonly
121 false, // not filename
122 WrapStyle_Word, // wrap on word boundaries
123 #ifdef __WXMSW__
124 TextKind_Plain // plain EDIT control
125 #endif // __WXMSW__
126 };
127
128 // ----------------------------------------------------------------------------
129 // TextWidgetsPage
130 // ----------------------------------------------------------------------------
131
132 // Define a new frame type: this is going to be our main frame
133 class TextWidgetsPage : public WidgetsPage
134 {
135 public:
136 // ctor(s) and dtor
137 TextWidgetsPage(WidgetsBookCtrl *book, wxImageList *imaglist);
138 virtual ~TextWidgetsPage(){};
139
140 virtual wxControl *GetWidget() const { return m_text; }
141 virtual void RecreateWidget() { CreateText(); }
142
143 // lazy creation of the content
144 virtual void CreateContent();
145
146 protected:
147 // create an info text contorl
148 wxTextCtrl *CreateInfoText();
149
150 // create a horz sizer holding a static text and this text control
151 wxSizer *CreateTextWithLabelSizer(const wxString& label,
152 wxTextCtrl *text,
153 const wxString& label2 = wxEmptyString,
154 wxTextCtrl *text2 = NULL);
155
156 // event handlers
157 void OnButtonReset(wxCommandEvent& event);
158 void OnButtonClearLog(wxCommandEvent& event);
159
160 void OnButtonSet(wxCommandEvent& event);
161 void OnButtonAdd(wxCommandEvent& event);
162 void OnButtonInsert(wxCommandEvent& event);
163 void OnButtonClear(wxCommandEvent& event);
164 void OnButtonLoad(wxCommandEvent& event);
165
166 void OnStreamRedirector(wxCommandEvent& event);
167 void OnButtonQuit(wxCommandEvent& event);
168
169 void OnText(wxCommandEvent& event);
170 void OnTextEnter(wxCommandEvent& event);
171
172 void OnCheckOrRadioBox(wxCommandEvent& event);
173
174 void OnUpdateUIClearButton(wxUpdateUIEvent& event);
175
176 void OnUpdateUIPasswordCheckbox(wxUpdateUIEvent& event);
177 void OnUpdateUIWrapLinesCheckbox(wxUpdateUIEvent& event);
178
179 void OnUpdateUIResetButton(wxUpdateUIEvent& event);
180
181 void OnIdle(wxIdleEvent& event);
182
183 // reset the textctrl parameters
184 void Reset();
185
186 // (re)create the textctrl
187 void CreateText();
188
189 // is the control currently single line?
190 bool IsSingleLine() const
191 {
192 return m_radioTextLines->GetSelection() == TextLines_Single;
193 }
194
195 // the controls
196 // ------------
197
198 // the radiobox to choose between single and multi line
199 wxRadioBox *m_radioTextLines;
200
201 // and another one to choose the wrapping style
202 wxRadioBox *m_radioWrap;
203
204 // the checkboxes controlling text ctrl styles
205 wxCheckBox *m_chkPassword,
206 *m_chkReadonly,
207 *m_chkFilename;
208
209 // under MSW we test rich edit controls as well here
210 #ifdef __WXMSW__
211 wxRadioBox *m_radioKind;
212 #endif // __WXMSW__
213
214 // the textctrl itself and the sizer it is in
215 wxTextCtrl *m_text;
216 wxSizer *m_sizerText;
217
218 // the information text zones
219 wxTextCtrl *m_textPosCur,
220 *m_textRowCur,
221 *m_textColCur,
222 *m_textPosLast,
223 *m_textLineLast,
224 *m_textSelFrom,
225 *m_textSelTo,
226 *m_textRange;
227
228 // and the data to show in them
229 long m_posCur,
230 m_posLast,
231 m_selFrom,
232 m_selTo;
233
234 wxString m_range10_20;
235
236 private:
237 // any class wishing to process wxWidgets events must use this macro
238 DECLARE_EVENT_TABLE()
239 DECLARE_WIDGETS_PAGE(TextWidgetsPage)
240 };
241
242 // ----------------------------------------------------------------------------
243 // WidgetsTextCtrl
244 // ----------------------------------------------------------------------------
245
246 class WidgetsTextCtrl : public wxTextCtrl
247 {
248 public:
249 WidgetsTextCtrl(wxWindow *parent,
250 wxWindowID id,
251 const wxString& value,
252 int flags)
253 : wxTextCtrl(parent, id, value, wxDefaultPosition, wxDefaultSize, flags)
254 {
255 }
256
257 protected:
258 void OnRightClick(wxMouseEvent& event)
259 {
260 wxString where;
261 wxTextCoord x, y;
262 switch ( HitTest(event.GetPosition(), &x, &y) )
263 {
264 default:
265 wxFAIL_MSG( _T("unexpected HitTest() result") );
266 // fall through
267
268 case wxTE_HT_UNKNOWN:
269 x = y = -1;
270 where = _T("nowhere near");
271 break;
272
273 case wxTE_HT_BEFORE:
274 where = _T("before");
275 break;
276
277 case wxTE_HT_BELOW:
278 where = _T("below");
279 break;
280
281 case wxTE_HT_BEYOND:
282 where = _T("beyond");
283 break;
284
285 case wxTE_HT_ON_TEXT:
286 where = _T("at");
287 break;
288 }
289
290 wxLogMessage(_T("Mouse is %s (%ld, %ld)"), where.c_str(), x, y);
291
292 event.Skip();
293 }
294
295 private:
296 DECLARE_EVENT_TABLE()
297 };
298
299 // ----------------------------------------------------------------------------
300 // event tables
301 // ----------------------------------------------------------------------------
302
303 BEGIN_EVENT_TABLE(TextWidgetsPage, WidgetsPage)
304 EVT_IDLE(TextWidgetsPage::OnIdle)
305
306 EVT_BUTTON(TextPage_Reset, TextWidgetsPage::OnButtonReset)
307
308 EVT_BUTTON(TextPage_StreamRedirector, TextWidgetsPage::OnStreamRedirector)
309
310 EVT_BUTTON(TextPage_Clear, TextWidgetsPage::OnButtonClear)
311 EVT_BUTTON(TextPage_Set, TextWidgetsPage::OnButtonSet)
312 EVT_BUTTON(TextPage_Add, TextWidgetsPage::OnButtonAdd)
313 EVT_BUTTON(TextPage_Insert, TextWidgetsPage::OnButtonInsert)
314 EVT_BUTTON(TextPage_Load, TextWidgetsPage::OnButtonLoad)
315
316 EVT_UPDATE_UI(TextPage_Clear, TextWidgetsPage::OnUpdateUIClearButton)
317
318 EVT_UPDATE_UI(TextPage_Password, TextWidgetsPage::OnUpdateUIPasswordCheckbox)
319 EVT_UPDATE_UI(TextPage_WrapLines, TextWidgetsPage::OnUpdateUIWrapLinesCheckbox)
320
321 EVT_UPDATE_UI(TextPage_Reset, TextWidgetsPage::OnUpdateUIResetButton)
322
323 EVT_TEXT(TextPage_Textctrl, TextWidgetsPage::OnText)
324 EVT_TEXT_ENTER(TextPage_Textctrl, TextWidgetsPage::OnTextEnter)
325
326 EVT_CHECKBOX(wxID_ANY, TextWidgetsPage::OnCheckOrRadioBox)
327 EVT_RADIOBOX(wxID_ANY, TextWidgetsPage::OnCheckOrRadioBox)
328 END_EVENT_TABLE()
329
330 BEGIN_EVENT_TABLE(WidgetsTextCtrl, wxTextCtrl)
331 EVT_RIGHT_UP(WidgetsTextCtrl::OnRightClick)
332 END_EVENT_TABLE()
333
334 // ============================================================================
335 // implementation
336 // ============================================================================
337
338 #if defined(__WXX11__)
339 #define FAMILY_CTRLS NATIVE_CTRLS
340 #elif defined(__WXUNIVERSAL__)
341 #define FAMILY_CTRLS UNIVERSAL_CTRLS
342 #else
343 #define FAMILY_CTRLS NATIVE_CTRLS
344 #endif
345
346 IMPLEMENT_WIDGETS_PAGE(TextWidgetsPage, _T("Text"),
347 FAMILY_CTRLS | EDITABLE_CTRLS
348 );
349
350 // ----------------------------------------------------------------------------
351 // TextWidgetsPage creation
352 // ----------------------------------------------------------------------------
353
354 TextWidgetsPage::TextWidgetsPage(WidgetsBookCtrl *book, wxImageList *imaglist)
355 : WidgetsPage(book, imaglist, text_xpm)
356 {
357 // init everything
358 #ifdef __WXMSW__
359 m_radioKind =
360 #endif // __WXMSW__
361 m_radioWrap =
362 m_radioTextLines = (wxRadioBox *)NULL;
363
364 m_chkPassword =
365 m_chkReadonly =
366 m_chkFilename = (wxCheckBox *)NULL;
367
368 m_text =
369 m_textPosCur =
370 m_textRowCur =
371 m_textColCur =
372 m_textPosLast =
373 m_textLineLast =
374 m_textSelFrom =
375 m_textSelTo =
376 m_textRange = (wxTextCtrl *)NULL;
377
378 m_sizerText = (wxSizer *)NULL;
379
380 m_posCur =
381 m_posLast =
382 m_selFrom =
383 m_selTo = -2; // not -1 which means "no selection"
384 }
385
386 void TextWidgetsPage::CreateContent()
387 {
388 // left pane
389 static const wxString modes[] =
390 {
391 _T("single line"),
392 _T("multi line"),
393 };
394
395 wxStaticBox *box = new wxStaticBox(this, wxID_ANY, _T("&Set textctrl parameters"));
396 m_radioTextLines = new wxRadioBox(this, wxID_ANY, _T("&Number of lines:"),
397 wxDefaultPosition, wxDefaultSize,
398 WXSIZEOF(modes), modes,
399 1, wxRA_SPECIFY_COLS);
400
401 wxSizer *sizerLeft = new wxStaticBoxSizer(box, wxVERTICAL);
402
403 sizerLeft->Add(m_radioTextLines, 0, wxGROW | wxALL, 5);
404 sizerLeft->AddSpacer(5);
405
406 m_chkPassword = CreateCheckBoxAndAddToSizer(
407 sizerLeft, _T("&Password control"), TextPage_Password
408 );
409 m_chkReadonly = CreateCheckBoxAndAddToSizer(
410 sizerLeft, _T("&Read-only mode")
411 );
412 m_chkFilename = CreateCheckBoxAndAddToSizer(
413 sizerLeft, _T("&Filename control")
414 );
415 m_chkFilename->Disable(); // not implemented yet
416 sizerLeft->AddSpacer(5);
417
418 static const wxString wrap[] =
419 {
420 _T("no wrap"),
421 _T("word wrap"),
422 _T("char wrap"),
423 _T("best wrap"),
424 };
425
426 m_radioWrap = new wxRadioBox(this, wxID_ANY, _T("&Wrap style:"),
427 wxDefaultPosition, wxDefaultSize,
428 WXSIZEOF(wrap), wrap,
429 1, wxRA_SPECIFY_COLS);
430 sizerLeft->Add(m_radioWrap, 0, wxGROW | wxALL, 5);
431
432 #ifdef __WXMSW__
433 static const wxString kinds[] =
434 {
435 _T("plain edit"),
436 _T("rich edit"),
437 _T("rich edit 2.0"),
438 };
439
440 m_radioKind = new wxRadioBox(this, wxID_ANY, _T("Control &kind"),
441 wxDefaultPosition, wxDefaultSize,
442 WXSIZEOF(kinds), kinds,
443 1, wxRA_SPECIFY_COLS);
444
445 sizerLeft->AddSpacer(5);
446 sizerLeft->Add(m_radioKind, 0, wxGROW | wxALL, 5);
447 #endif // __WXMSW__
448
449 wxButton *btn = new wxButton(this, TextPage_Reset, _T("&Reset"));
450 sizerLeft->Add(2, 2, 0, wxGROW | wxALL, 1); // spacer
451 sizerLeft->Add(btn, 0, wxALIGN_CENTRE_HORIZONTAL | wxALL, 15);
452
453 // middle pane
454 wxStaticBox *box2 = new wxStaticBox(this, wxID_ANY, _T("&Change contents:"));
455 wxSizer *sizerMiddleUp = new wxStaticBoxSizer(box2, wxVERTICAL);
456
457 btn = new wxButton(this, TextPage_Set, _T("&Set text value"));
458 sizerMiddleUp->Add(btn, 0, wxALL | wxGROW, 1);
459
460 btn = new wxButton(this, TextPage_Add, _T("&Append text"));
461 sizerMiddleUp->Add(btn, 0, wxALL | wxGROW, 1);
462
463 btn = new wxButton(this, TextPage_Insert, _T("&Insert text"));
464 sizerMiddleUp->Add(btn, 0, wxALL | wxGROW, 1);
465
466 btn = new wxButton(this, TextPage_Load, _T("&Load file"));
467 sizerMiddleUp->Add(btn, 0, wxALL | wxGROW, 1);
468
469 btn = new wxButton(this, TextPage_Clear, _T("&Clear"));
470 sizerMiddleUp->Add(btn, 0, wxALL | wxGROW, 1);
471
472 btn = new wxButton(this, TextPage_StreamRedirector, _T("St&ream redirection"));
473 sizerMiddleUp->Add(btn, 0, wxALL | wxGROW, 1);
474
475 wxStaticBox *box4 = new wxStaticBox(this, wxID_ANY, _T("&Info:"));
476 wxSizer *sizerMiddleDown = new wxStaticBoxSizer(box4, wxVERTICAL);
477
478 m_textPosCur = CreateInfoText();
479 m_textRowCur = CreateInfoText();
480 m_textColCur = CreateInfoText();
481
482 wxSizer *sizerRow = new wxBoxSizer(wxHORIZONTAL);
483 sizerRow->Add(CreateTextWithLabelSizer
484 (
485 _T("Current pos:"),
486 m_textPosCur
487 ),
488 0, wxRIGHT, 5);
489 sizerRow->Add(CreateTextWithLabelSizer
490 (
491 _T("Col:"),
492 m_textColCur
493 ),
494 0, wxLEFT | wxRIGHT, 5);
495 sizerRow->Add(CreateTextWithLabelSizer
496 (
497 _T("Row:"),
498 m_textRowCur
499 ),
500 0, wxLEFT, 5);
501 sizerMiddleDown->Add(sizerRow, 0, wxALL, 5);
502
503 m_textLineLast = CreateInfoText();
504 m_textPosLast = CreateInfoText();
505 sizerMiddleDown->Add
506 (
507 CreateTextWithLabelSizer
508 (
509 _T("Number of lines:"),
510 m_textLineLast,
511 _T("Last position:"),
512 m_textPosLast
513 ),
514 0, wxALL, 5
515 );
516
517 m_textSelFrom = CreateInfoText();
518 m_textSelTo = CreateInfoText();
519 sizerMiddleDown->Add
520 (
521 CreateTextWithLabelSizer
522 (
523 _T("Selection: from"),
524 m_textSelFrom,
525 _T("to"),
526 m_textSelTo
527 ),
528 0, wxALL, 5
529 );
530
531 m_textRange = new wxTextCtrl(this, wxID_ANY, wxEmptyString,
532 wxDefaultPosition, wxDefaultSize,
533 wxTE_READONLY);
534 sizerMiddleDown->Add
535 (
536 CreateTextWithLabelSizer
537 (
538 _T("Range 10..20:"),
539 m_textRange
540 ),
541 0, wxALL, 5
542 );
543
544 wxSizer *sizerMiddle = new wxBoxSizer(wxVERTICAL);
545 sizerMiddle->Add(sizerMiddleUp, 0, wxGROW);
546 sizerMiddle->Add(sizerMiddleDown, 1, wxGROW | wxTOP, 5);
547
548 // right pane
549 wxStaticBox *box3 = new wxStaticBox(this, wxID_ANY, _T("&Text:"));
550 m_sizerText = new wxStaticBoxSizer(box3, wxHORIZONTAL);
551 Reset();
552 CreateText();
553 m_sizerText->SetMinSize(150, 0);
554
555 // the 3 panes panes compose the upper part of the window
556 wxSizer *sizerTop = new wxBoxSizer(wxHORIZONTAL);
557 sizerTop->Add(sizerLeft, 0, wxGROW | (wxALL & ~wxLEFT), 10);
558 sizerTop->Add(sizerMiddle, 0, wxGROW | wxALL, 10);
559 sizerTop->Add(m_sizerText, 1, wxGROW | (wxALL & ~wxRIGHT), 10);
560
561 SetSizer(sizerTop);
562
563 sizerTop->Fit(this);
564 }
565
566 // ----------------------------------------------------------------------------
567 // creation helpers
568 // ----------------------------------------------------------------------------
569
570 wxTextCtrl *TextWidgetsPage::CreateInfoText()
571 {
572 static int s_maxWidth = 0;
573 if ( !s_maxWidth )
574 {
575 // calc it once only
576 GetTextExtent(_T("9999999"), &s_maxWidth, NULL);
577 }
578
579 wxTextCtrl *text = new wxTextCtrl(this, wxID_ANY, wxEmptyString,
580 wxDefaultPosition,
581 wxSize(s_maxWidth, wxDefaultCoord),
582 wxTE_READONLY);
583 return text;
584 }
585
586 wxSizer *TextWidgetsPage::CreateTextWithLabelSizer(const wxString& label,
587 wxTextCtrl *text,
588 const wxString& label2,
589 wxTextCtrl *text2)
590 {
591 wxSizer *sizerRow = new wxBoxSizer(wxHORIZONTAL);
592 sizerRow->Add(new wxStaticText(this, wxID_ANY, label), 0,
593 wxALIGN_CENTRE_VERTICAL | wxRIGHT, 5);
594 sizerRow->Add(text, 0, wxALIGN_CENTRE_VERTICAL);
595 if ( text2 )
596 {
597 sizerRow->Add(new wxStaticText(this, wxID_ANY, label2), 0,
598 wxALIGN_CENTRE_VERTICAL | wxLEFT | wxRIGHT, 5);
599 sizerRow->Add(text2, 0, wxALIGN_CENTRE_VERTICAL);
600 }
601
602 return sizerRow;
603 }
604
605 // ----------------------------------------------------------------------------
606 // operations
607 // ----------------------------------------------------------------------------
608
609 void TextWidgetsPage::Reset()
610 {
611 m_radioTextLines->SetSelection(DEFAULTS.textLines);
612
613 m_chkPassword->SetValue(DEFAULTS.password);
614 m_chkReadonly->SetValue(DEFAULTS.readonly);
615 m_chkFilename->SetValue(DEFAULTS.filename);
616
617 m_radioWrap->SetSelection(DEFAULTS.wrapStyle);
618
619 #ifdef __WXMSW__
620 m_radioKind->SetSelection(DEFAULTS.textKind);
621 #endif // __WXMSW__
622 }
623
624 void TextWidgetsPage::CreateText()
625 {
626 int flags = ms_defaultFlags;
627 switch ( m_radioTextLines->GetSelection() )
628 {
629 default:
630 wxFAIL_MSG( _T("unexpected lines radio box selection") );
631
632 case TextLines_Single:
633 break;
634
635 case TextLines_Multi:
636 flags |= wxTE_MULTILINE;
637 m_chkPassword->SetValue(false);
638 break;
639 }
640
641 if ( m_chkPassword->GetValue() )
642 flags |= wxTE_PASSWORD;
643 if ( m_chkReadonly->GetValue() )
644 flags |= wxTE_READONLY;
645
646 switch ( m_radioWrap->GetSelection() )
647 {
648 default:
649 wxFAIL_MSG( _T("unexpected wrap style radio box selection") );
650
651 case WrapStyle_None:
652 flags |= wxTE_DONTWRAP; // same as wxHSCROLL
653 break;
654
655 case WrapStyle_Word:
656 flags |= wxTE_WORDWRAP;
657 break;
658
659 case WrapStyle_Char:
660 flags |= wxTE_CHARWRAP;
661 break;
662
663 case WrapStyle_Best:
664 // this is default but use symbolic file name for consistency
665 flags |= wxTE_BESTWRAP;
666 break;
667 }
668
669 #ifdef __WXMSW__
670 switch ( m_radioKind->GetSelection() )
671 {
672 default:
673 wxFAIL_MSG( _T("unexpected kind radio box selection") );
674
675 case TextKind_Plain:
676 break;
677
678 case TextKind_Rich:
679 flags |= wxTE_RICH;
680 break;
681
682 case TextKind_Rich2:
683 flags |= wxTE_RICH2;
684 break;
685 }
686 #endif // __WXMSW__
687
688 wxString valueOld;
689 if ( m_text )
690 {
691 valueOld = m_text->GetValue();
692
693 m_sizerText->Detach( m_text );
694 delete m_text;
695 }
696 else
697 {
698 valueOld = _T("Hello, Universe!");
699 }
700
701 m_text = new WidgetsTextCtrl(this, TextPage_Textctrl, valueOld, flags);
702
703 #if 0
704 if ( m_chkFilename->GetValue() )
705 ;
706 #endif // TODO
707
708 // cast to int needed to silence gcc warning about different enums
709 m_sizerText->Add(m_text, 1, wxALL |
710 (flags & wxTE_MULTILINE ? (int)wxGROW
711 : wxALIGN_TOP), 5);
712 m_sizerText->Layout();
713 }
714
715 // ----------------------------------------------------------------------------
716 // event handlers
717 // ----------------------------------------------------------------------------
718
719 void TextWidgetsPage::OnIdle(wxIdleEvent& WXUNUSED(event))
720 {
721 // update all info texts
722
723 if ( m_textPosCur )
724 {
725 long posCur = m_text->GetInsertionPoint();
726 if ( posCur != m_posCur )
727 {
728 m_textPosCur->Clear();
729 m_textRowCur->Clear();
730 m_textColCur->Clear();
731
732 long col, row;
733 m_text->PositionToXY(posCur, &col, &row);
734
735 *m_textPosCur << posCur;
736 *m_textRowCur << row;
737 *m_textColCur << col;
738
739 m_posCur = posCur;
740 }
741 }
742
743 if ( m_textPosLast )
744 {
745 long posLast = m_text->GetLastPosition();
746 if ( posLast != m_posLast )
747 {
748 m_textPosLast->Clear();
749 *m_textPosLast << posLast;
750
751 m_posLast = posLast;
752 }
753 }
754
755 if ( m_textLineLast )
756 {
757 m_textLineLast->SetValue(
758 wxString::Format(_T("%d"), m_text->GetNumberOfLines()) );
759 }
760
761 if ( m_textSelFrom && m_textSelTo )
762 {
763 long selFrom, selTo;
764 m_text->GetSelection(&selFrom, &selTo);
765 if ( selFrom != m_selFrom )
766 {
767 m_textSelFrom->Clear();
768 *m_textSelFrom << selFrom;
769
770 m_selFrom = selFrom;
771 }
772
773 if ( selTo != m_selTo )
774 {
775 m_textSelTo->Clear();
776 *m_textSelTo << selTo;
777
778 m_selTo = selTo;
779 }
780 }
781
782 if ( m_textRange )
783 {
784 wxString range = m_text->GetRange(10, 20);
785 if ( range != m_range10_20 )
786 {
787 m_range10_20 = range;
788 m_textRange->SetValue(range);
789 }
790 }
791 }
792
793 void TextWidgetsPage::OnButtonReset(wxCommandEvent& WXUNUSED(event))
794 {
795 Reset();
796
797 CreateText();
798 }
799
800 void TextWidgetsPage::OnButtonSet(wxCommandEvent& WXUNUSED(event))
801 {
802 m_text->SetValue(m_text->GetWindowStyle() & wxTE_MULTILINE
803 ? _T("Here,\nthere and\neverywhere")
804 : _T("Yellow submarine"));
805
806 m_text->SetFocus();
807 }
808
809 void TextWidgetsPage::OnButtonAdd(wxCommandEvent& WXUNUSED(event))
810 {
811 if ( m_text->GetWindowStyle() & wxTE_MULTILINE )
812 {
813 m_text->AppendText(_T("We all live in a\n"));
814 }
815
816 m_text->AppendText(_T("Yellow submarine"));
817 }
818
819 void TextWidgetsPage::OnButtonInsert(wxCommandEvent& WXUNUSED(event))
820 {
821 m_text->WriteText(_T("Is there anybody going to listen to my story"));
822 if ( m_text->GetWindowStyle() & wxTE_MULTILINE )
823 {
824 m_text->WriteText(_T("\nall about the girl who came to stay"));
825 }
826 }
827
828 void TextWidgetsPage::OnButtonClear(wxCommandEvent& WXUNUSED(event))
829 {
830 m_text->Clear();
831 m_text->SetFocus();
832 }
833
834 void TextWidgetsPage::OnButtonLoad(wxCommandEvent& WXUNUSED(event))
835 {
836 // search for the file in several dirs where it's likely to be
837 wxPathList pathlist;
838 pathlist.Add(_T("."));
839 pathlist.Add(_T(".."));
840 pathlist.Add(_T("../../../samples/widgets"));
841
842 wxString filename = pathlist.FindValidPath(_T("textctrl.cpp"));
843 if ( !filename )
844 {
845 wxLogError(_T("File textctrl.cpp not found."));
846 }
847 else // load it
848 {
849 wxStopWatch sw;
850 if ( !m_text->LoadFile(filename) )
851 {
852 // this is not supposed to happen ...
853 wxLogError(_T("Error loading file."));
854 }
855 else
856 {
857 long elapsed = sw.Time();
858 wxLogMessage(_T("Loaded file '%s' in %lu.%us"),
859 filename.c_str(), elapsed / 1000,
860 (unsigned int) elapsed % 1000);
861 }
862 }
863 }
864
865 void TextWidgetsPage::OnUpdateUIClearButton(wxUpdateUIEvent& event)
866 {
867 event.Enable(!m_text->GetValue().empty());
868 }
869
870 void TextWidgetsPage::OnUpdateUIWrapLinesCheckbox(wxUpdateUIEvent& event)
871 {
872 event.Enable( !IsSingleLine() );
873 }
874
875 void TextWidgetsPage::OnUpdateUIPasswordCheckbox(wxUpdateUIEvent& event)
876 {
877 // can't put multiline control in password mode
878 event.Enable( IsSingleLine() );
879 }
880
881 void TextWidgetsPage::OnUpdateUIResetButton(wxUpdateUIEvent& event)
882 {
883 event.Enable( (m_radioTextLines->GetSelection() != DEFAULTS.textLines) ||
884 #ifdef __WXMSW__
885 (m_radioKind->GetSelection() != DEFAULTS.textKind) ||
886 #endif // __WXMSW__
887 (m_chkPassword->GetValue() != DEFAULTS.password) ||
888 (m_chkReadonly->GetValue() != DEFAULTS.readonly) ||
889 (m_chkFilename->GetValue() != DEFAULTS.filename) ||
890 (m_radioWrap->GetSelection() != DEFAULTS.wrapStyle) );
891 }
892
893 void TextWidgetsPage::OnText(wxCommandEvent& WXUNUSED(event))
894 {
895 // small hack to suppress the very first message: by then the logging is
896 // not yet redirected and so initial setting of the text value results in
897 // an annoying message box
898 static bool s_firstTime = true;
899 if ( s_firstTime )
900 {
901 s_firstTime = false;
902 return;
903 }
904
905 wxLogMessage(_T("Text ctrl value changed"));
906 }
907
908 void TextWidgetsPage::OnTextEnter(wxCommandEvent& event)
909 {
910 wxLogMessage(_T("Text entered: '%s'"), event.GetString().c_str());
911 event.Skip();
912 }
913
914 void TextWidgetsPage::OnCheckOrRadioBox(wxCommandEvent& WXUNUSED(event))
915 {
916 CreateText();
917 }
918
919 void TextWidgetsPage::OnStreamRedirector(wxCommandEvent& WXUNUSED(event))
920 {
921 #if wxHAS_TEXT_WINDOW_STREAM
922 wxStreamToTextRedirector redirect(m_text);
923 wxString str( _T("Outputed to cout, appears in wxTextCtrl!") );
924 wxSTD cout << str << wxSTD endl;
925 #else
926 wxMessageBox(_T("This wxWidgets build does not support wxStreamToTextRedirector"));
927 #endif
928 }