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