]> git.saurik.com Git - wxWidgets.git/blobdiff - samples/widgets/textctrl.cpp
Reorganize and improve wxSizer::SetItemMinSize() documentation.
[wxWidgets.git] / samples / widgets / textctrl.cpp
index 94d0a322d73bdd1e9183b03d59980ff988aa621f..4a7c0dd6595118e2f88b4f595ec82ea82c3c9b38 100644 (file)
@@ -1,5 +1,5 @@
 /////////////////////////////////////////////////////////////////////////////
-// Program:     wxWindows Widgets Sample
+// Program:     wxWidgets Widgets Sample
 // Name:        textctrl.cpp
 // Purpose:     part of the widgets sample showing wxTextCtrl
 // Author:      Vadim Zeitlin
     #include "wx/log.h"
     #include "wx/timer.h"
 
+    #include "wx/bitmap.h"
     #include "wx/button.h"
     #include "wx/checkbox.h"
     #include "wx/radiobox.h"
     #include "wx/statbox.h"
     #include "wx/stattext.h"
     #include "wx/textctrl.h"
+    #include "wx/msgdlg.h"
 #endif
 
 #include "wx/sizer.h"
+#include "wx/ioswrap.h"
 
 #include "widgets.h"
 
@@ -50,7 +53,7 @@
 // control ids
 enum
 {
-    TextPage_Reset = 100,
+    TextPage_Reset = wxID_HIGHEST,
 
     TextPage_Set,
     TextPage_Add,
@@ -58,6 +61,8 @@ enum
     TextPage_Clear,
     TextPage_Load,
 
+    TextPage_StreamRedirector,
+
     TextPage_Password,
     TextPage_WrapLines,
     TextPage_Textctrl
@@ -67,22 +72,57 @@ enum
 enum TextLines
 {
     TextLines_Single,
-    TextLines_Multi
+    TextLines_Multi,
+    TextLines_Max
+};
+
+// wrap style radio box
+enum WrapStyle
+{
+    WrapStyle_None,
+    WrapStyle_Word,
+    WrapStyle_Char,
+    WrapStyle_Best,
+    WrapStyle_Max
+};
+
+#ifdef __WXMSW__
+
+// textctrl kind values
+enum TextKind
+{
+    TextKind_Plain,
+    TextKind_Rich,
+    TextKind_Rich2,
+    TextKind_Max
 };
 
+#endif // __WXMSW__
+
 // default values for the controls
 static const struct ControlValues
 {
     TextLines textLines;
+
     bool password;
-    bool wraplines;
     bool readonly;
+    bool filename;
+
+    WrapStyle wrapStyle;
+
+#ifdef __WXMSW__
+    TextKind textKind;
+#endif // __WXMSW__
 } DEFAULTS =
 {
     TextLines_Multi,    // multiline
-    FALSE,              // not password
-    TRUE,               // do wrap lines
-    FALSE               // not readonly
+    false,              // not password
+    false,              // not readonly
+    false,              // not filename
+    WrapStyle_Word,     // wrap on word boundaries
+#ifdef __WXMSW__
+    TextKind_Plain      // plain EDIT control
+#endif // __WXMSW__
 };
 
 // ----------------------------------------------------------------------------
@@ -94,8 +134,15 @@ class TextWidgetsPage : public WidgetsPage
 {
 public:
     // ctor(s) and dtor
-    TextWidgetsPage(wxNotebook *notebook, wxImageList *imaglist);
-    virtual ~TextWidgetsPage();
+    TextWidgetsPage(WidgetsBookCtrl *book, wxImageList *imaglist);
+    virtual ~TextWidgetsPage(){};
+
+    virtual wxControl *GetWidget() const { return m_text; }
+    virtual wxTextEntryBase *GetTextEntry() const { return m_text; }
+    virtual void RecreateWidget() { CreateText(); }
+
+    // lazy creation of the content
+    virtual void CreateContent();
 
 protected:
     // create an info text contorl
@@ -117,6 +164,7 @@ protected:
     void OnButtonClear(wxCommandEvent& event);
     void OnButtonLoad(wxCommandEvent& event);
 
+    void OnStreamRedirector(wxCommandEvent& event);
     void OnButtonQuit(wxCommandEvent& event);
 
     void OnText(wxCommandEvent& event);
@@ -151,10 +199,18 @@ protected:
     // the radiobox to choose between single and multi line
     wxRadioBox *m_radioTextLines;
 
+    // and another one to choose the wrapping style
+    wxRadioBox *m_radioWrap;
+
     // the checkboxes controlling text ctrl styles
     wxCheckBox *m_chkPassword,
-               *m_chkWrapLines,
-               *m_chkReadonly;
+               *m_chkReadonly,
+               *m_chkFilename;
+
+    // under MSW we test rich edit controls as well here
+#ifdef __WXMSW__
+    wxRadioBox *m_radioKind;
+#endif // __WXMSW__
 
     // the textctrl itself and the sizer it is in
     wxTextCtrl *m_text;
@@ -167,7 +223,8 @@ protected:
                *m_textPosLast,
                *m_textLineLast,
                *m_textSelFrom,
-               *m_textSelTo;
+               *m_textSelTo,
+               *m_textRange;
 
     // and the data to show in them
     long m_posCur,
@@ -175,11 +232,69 @@ protected:
          m_selFrom,
          m_selTo;
 
+    wxString m_range10_20;
+
 private:
-    // any class wishing to process wxWindows events must use this macro
-    DECLARE_EVENT_TABLE();
+    // any class wishing to process wxWidgets events must use this macro
+    DECLARE_EVENT_TABLE()
+    DECLARE_WIDGETS_PAGE(TextWidgetsPage)
+};
+
+// ----------------------------------------------------------------------------
+// WidgetsTextCtrl
+// ----------------------------------------------------------------------------
+
+class WidgetsTextCtrl : public wxTextCtrl
+{
+public:
+    WidgetsTextCtrl(wxWindow *parent,
+                    wxWindowID id,
+                    const wxString& value,
+                    int flags)
+        : wxTextCtrl(parent, id, value, wxDefaultPosition, wxDefaultSize, flags)
+    {
+    }
 
-    DECLARE_WIDGETS_PAGE(TextWidgetsPage);
+protected:
+    void OnRightClick(wxMouseEvent& event)
+    {
+        wxString where;
+        wxTextCoord x, y;
+        switch ( HitTest(event.GetPosition(), &x, &y) )
+        {
+            default:
+                wxFAIL_MSG( wxT("unexpected HitTest() result") );
+                // fall through
+
+            case wxTE_HT_UNKNOWN:
+                x = y = -1;
+                where = wxT("nowhere near");
+                break;
+
+            case wxTE_HT_BEFORE:
+                where = wxT("before");
+                break;
+
+            case wxTE_HT_BELOW:
+                where = wxT("below");
+                break;
+
+            case wxTE_HT_BEYOND:
+                where = wxT("beyond");
+                break;
+
+            case wxTE_HT_ON_TEXT:
+                where = wxT("at");
+                break;
+        }
+
+        wxLogMessage(wxT("Mouse is %s (%ld, %ld)"), where.c_str(), x, y);
+
+        event.Skip();
+    }
+
+private:
+    DECLARE_EVENT_TABLE()
 };
 
 // ----------------------------------------------------------------------------
@@ -191,6 +306,8 @@ BEGIN_EVENT_TABLE(TextWidgetsPage, WidgetsPage)
 
     EVT_BUTTON(TextPage_Reset, TextWidgetsPage::OnButtonReset)
 
+    EVT_BUTTON(TextPage_StreamRedirector, TextWidgetsPage::OnStreamRedirector)
+
     EVT_BUTTON(TextPage_Clear, TextWidgetsPage::OnButtonClear)
     EVT_BUTTON(TextPage_Set, TextWidgetsPage::OnButtonSet)
     EVT_BUTTON(TextPage_Add, TextWidgetsPage::OnButtonAdd)
@@ -207,31 +324,47 @@ BEGIN_EVENT_TABLE(TextWidgetsPage, WidgetsPage)
     EVT_TEXT(TextPage_Textctrl, TextWidgetsPage::OnText)
     EVT_TEXT_ENTER(TextPage_Textctrl, TextWidgetsPage::OnTextEnter)
 
-    EVT_CHECKBOX(-1, TextWidgetsPage::OnCheckOrRadioBox)
-    EVT_RADIOBOX(-1, TextWidgetsPage::OnCheckOrRadioBox)
+    EVT_CHECKBOX(wxID_ANY, TextWidgetsPage::OnCheckOrRadioBox)
+    EVT_RADIOBOX(wxID_ANY, TextWidgetsPage::OnCheckOrRadioBox)
+END_EVENT_TABLE()
+
+BEGIN_EVENT_TABLE(WidgetsTextCtrl, wxTextCtrl)
+    EVT_RIGHT_UP(WidgetsTextCtrl::OnRightClick)
 END_EVENT_TABLE()
 
 // ============================================================================
 // implementation
 // ============================================================================
 
-IMPLEMENT_WIDGETS_PAGE(TextWidgetsPage, _T("Text"));
+#if defined(__WXX11__)
+    #define FAMILY_CTRLS NATIVE_CTRLS
+#elif defined(__WXUNIVERSAL__)
+    #define FAMILY_CTRLS UNIVERSAL_CTRLS
+#else
+    #define FAMILY_CTRLS NATIVE_CTRLS
+#endif
+
+IMPLEMENT_WIDGETS_PAGE(TextWidgetsPage, wxT("Text"),
+                       FAMILY_CTRLS | EDITABLE_CTRLS
+                       );
 
 // ----------------------------------------------------------------------------
 // TextWidgetsPage creation
 // ----------------------------------------------------------------------------
 
-TextWidgetsPage::TextWidgetsPage(wxNotebook *notebook, wxImageList *imaglist)
-               : WidgetsPage(notebook)
+TextWidgetsPage::TextWidgetsPage(WidgetsBookCtrl *book, wxImageList *imaglist)
+               : WidgetsPage(book, imaglist, text_xpm)
 {
-    imaglist->Add(wxBitmap(text_xpm));
-
     // init everything
+#ifdef __WXMSW__
+    m_radioKind =
+#endif // __WXMSW__
+    m_radioWrap =
     m_radioTextLines = (wxRadioBox *)NULL;
 
     m_chkPassword =
-    m_chkWrapLines =
-    m_chkReadonly = (wxCheckBox *)NULL;
+    m_chkReadonly =
+    m_chkFilename = (wxCheckBox *)NULL;
 
     m_text =
     m_textPosCur =
@@ -240,23 +373,28 @@ TextWidgetsPage::TextWidgetsPage(wxNotebook *notebook, wxImageList *imaglist)
     m_textPosLast =
     m_textLineLast =
     m_textSelFrom =
-    m_textSelTo = (wxTextCtrl *)NULL;
+    m_textSelTo =
+    m_textRange = (wxTextCtrl *)NULL;
+
     m_sizerText = (wxSizer *)NULL;
 
     m_posCur =
     m_posLast =
     m_selFrom =
     m_selTo = -2; // not -1 which means "no selection"
+}
 
+void TextWidgetsPage::CreateContent()
+{
     // left pane
     static const wxString modes[] =
     {
-        _T("single line"),
-        _T("multi line"),
+        wxT("single line"),
+        wxT("multi line"),
     };
 
-    wxStaticBox *box = new wxStaticBox(this, -1, _T("&Set textctrl parameters"));
-    m_radioTextLines = new wxRadioBox(this, -1, _T("&Number of lines:"),
+    wxStaticBox *box = new wxStaticBox(this, wxID_ANY, wxT("&Set textctrl parameters"));
+    m_radioTextLines = new wxRadioBox(this, wxID_ANY, wxT("&Number of lines:"),
                                       wxDefaultPosition, wxDefaultSize,
                                       WXSIZEOF(modes), modes,
                                       1, wxRA_SPECIFY_COLS);
@@ -264,41 +402,78 @@ TextWidgetsPage::TextWidgetsPage(wxNotebook *notebook, wxImageList *imaglist)
     wxSizer *sizerLeft = new wxStaticBoxSizer(box, wxVERTICAL);
 
     sizerLeft->Add(m_radioTextLines, 0, wxGROW | wxALL, 5);
-    sizerLeft->Add(5, 5, 0, wxGROW | wxALL, 5); // spacer
+    sizerLeft->AddSpacer(5);
 
     m_chkPassword = CreateCheckBoxAndAddToSizer(
-                        sizerLeft, _T("&Password control"), TextPage_Password
+                        sizerLeft, wxT("&Password control"), TextPage_Password
                     );
-    m_chkWrapLines = CreateCheckBoxAndAddToSizer(
-                        sizerLeft, _T("Line &wrap"), TextPage_WrapLines
-                     );
     m_chkReadonly = CreateCheckBoxAndAddToSizer(
-                        sizerLeft, _T("&Read-only mode")
+                        sizerLeft, wxT("&Read-only mode")
                     );
+    m_chkFilename = CreateCheckBoxAndAddToSizer(
+                        sizerLeft, wxT("&Filename control")
+                    );
+    m_chkFilename->Disable(); // not implemented yet
+    sizerLeft->AddSpacer(5);
+
+    static const wxString wrap[] =
+    {
+        wxT("no wrap"),
+        wxT("word wrap"),
+        wxT("char wrap"),
+        wxT("best wrap"),
+    };
+
+    m_radioWrap = new wxRadioBox(this, wxID_ANY, wxT("&Wrap style:"),
+                                 wxDefaultPosition, wxDefaultSize,
+                                 WXSIZEOF(wrap), wrap,
+                                 1, wxRA_SPECIFY_COLS);
+    sizerLeft->Add(m_radioWrap, 0, wxGROW | wxALL, 5);
 
-    wxButton *btn = new wxButton(this, TextPage_Reset, _T("&Reset"));
+#ifdef __WXMSW__
+    static const wxString kinds[] =
+    {
+        wxT("plain edit"),
+        wxT("rich edit"),
+        wxT("rich edit 2.0"),
+    };
+
+    m_radioKind = new wxRadioBox(this, wxID_ANY, wxT("Control &kind"),
+                                 wxDefaultPosition, wxDefaultSize,
+                                 WXSIZEOF(kinds), kinds,
+                                 1, wxRA_SPECIFY_COLS);
+
+    sizerLeft->AddSpacer(5);
+    sizerLeft->Add(m_radioKind, 0, wxGROW | wxALL, 5);
+#endif // __WXMSW__
+
+    wxButton *btn = new wxButton(this, TextPage_Reset, wxT("&Reset"));
+    sizerLeft->Add(2, 2, 0, wxGROW | wxALL, 1); // spacer
     sizerLeft->Add(btn, 0, wxALIGN_CENTRE_HORIZONTAL | wxALL, 15);
 
     // middle pane
-    wxStaticBox *box2 = new wxStaticBox(this, -1, _T("&Change contents:"));
+    wxStaticBox *box2 = new wxStaticBox(this, wxID_ANY, wxT("&Change contents:"));
     wxSizer *sizerMiddleUp = new wxStaticBoxSizer(box2, wxVERTICAL);
 
-    btn = new wxButton(this, TextPage_Set, _T("&Set text value"));
-    sizerMiddleUp->Add(btn, 0, wxALL | wxGROW, 5);
+    btn = new wxButton(this, TextPage_Set, wxT("&Set text value"));
+    sizerMiddleUp->Add(btn, 0, wxALL | wxGROW, 1);
+
+    btn = new wxButton(this, TextPage_Add, wxT("&Append text"));
+    sizerMiddleUp->Add(btn, 0, wxALL | wxGROW, 1);
 
-    btn = new wxButton(this, TextPage_Add, _T("&Append text"));
-    sizerMiddleUp->Add(btn, 0, wxALL | wxGROW, 5);
+    btn = new wxButton(this, TextPage_Insert, wxT("&Insert text"));
+    sizerMiddleUp->Add(btn, 0, wxALL | wxGROW, 1);
 
-    btn = new wxButton(this, TextPage_Insert, _T("&Insert text"));
-    sizerMiddleUp->Add(btn, 0, wxALL | wxGROW, 5);
+    btn = new wxButton(this, TextPage_Load, wxT("&Load file"));
+    sizerMiddleUp->Add(btn, 0, wxALL | wxGROW, 1);
 
-    btn = new wxButton(this, TextPage_Load, _T("&Load file"));
-    sizerMiddleUp->Add(btn, 0, wxALL | wxGROW, 5);
+    btn = new wxButton(this, TextPage_Clear, wxT("&Clear"));
+    sizerMiddleUp->Add(btn, 0, wxALL | wxGROW, 1);
 
-    btn = new wxButton(this, TextPage_Clear, _T("&Clear"));
-    sizerMiddleUp->Add(btn, 0, wxALL | wxGROW, 5);
+    btn = new wxButton(this, TextPage_StreamRedirector, wxT("St&ream redirection"));
+    sizerMiddleUp->Add(btn, 0, wxALL | wxGROW, 1);
 
-    wxStaticBox *box4 = new wxStaticBox(this, -1, _T("&Info:"));
+    wxStaticBox *box4 = new wxStaticBox(this, wxID_ANY, wxT("&Info:"));
     wxSizer *sizerMiddleDown = new wxStaticBoxSizer(box4, wxVERTICAL);
 
     m_textPosCur = CreateInfoText();
@@ -308,19 +483,19 @@ TextWidgetsPage::TextWidgetsPage(wxNotebook *notebook, wxImageList *imaglist)
     wxSizer *sizerRow = new wxBoxSizer(wxHORIZONTAL);
     sizerRow->Add(CreateTextWithLabelSizer
                   (
-                    _T("Current pos:"),
+                    wxT("Current pos:"),
                     m_textPosCur
                   ),
                   0, wxRIGHT, 5);
     sizerRow->Add(CreateTextWithLabelSizer
                   (
-                    _T("Col:"),
+                    wxT("Col:"),
                     m_textColCur
                   ),
                   0, wxLEFT | wxRIGHT, 5);
     sizerRow->Add(CreateTextWithLabelSizer
                   (
-                    _T("Row:"),
+                    wxT("Row:"),
                     m_textRowCur
                   ),
                   0, wxLEFT, 5);
@@ -332,9 +507,9 @@ TextWidgetsPage::TextWidgetsPage(wxNotebook *notebook, wxImageList *imaglist)
                      (
                         CreateTextWithLabelSizer
                         (
-                          _T("Number of lines:"),
+                          wxT("Number of lines:"),
                           m_textLineLast,
-                          _T("Last position:"),
+                          wxT("Last position:"),
                           m_textPosLast
                         ),
                         0, wxALL, 5
@@ -346,23 +521,37 @@ TextWidgetsPage::TextWidgetsPage(wxNotebook *notebook, wxImageList *imaglist)
                      (
                         CreateTextWithLabelSizer
                         (
-                          _T("Selection: from"),
+                          wxT("Selection: from"),
                           m_textSelFrom,
-                          _T("to"),
+                          wxT("to"),
                           m_textSelTo
                         ),
                         0, wxALL, 5
                      );
+
+    m_textRange = new wxTextCtrl(this, wxID_ANY, wxEmptyString,
+                                 wxDefaultPosition, wxDefaultSize,
+                                 wxTE_READONLY);
+    sizerMiddleDown->Add
+                     (
+                        CreateTextWithLabelSizer
+                        (
+                          wxT("Range 10..20:"),
+                          m_textRange
+                        ),
+                        0, wxALL, 5
+                     );
+
     wxSizer *sizerMiddle = new wxBoxSizer(wxVERTICAL);
     sizerMiddle->Add(sizerMiddleUp, 0, wxGROW);
     sizerMiddle->Add(sizerMiddleDown, 1, wxGROW | wxTOP, 5);
 
     // right pane
-    wxStaticBox *box3 = new wxStaticBox(this, -1, _T("&Text:"));
+    wxStaticBox *box3 = new wxStaticBox(this, wxID_ANY, wxT("&Text:"));
     m_sizerText = new wxStaticBoxSizer(box3, wxHORIZONTAL);
     Reset();
     CreateText();
-    m_sizerText->SetMinSize(250, 0);
+    m_sizerText->SetMinSize(150, 0);
 
     // the 3 panes panes compose the upper part of the window
     wxSizer *sizerTop = new wxBoxSizer(wxHORIZONTAL);
@@ -370,14 +559,7 @@ TextWidgetsPage::TextWidgetsPage(wxNotebook *notebook, wxImageList *imaglist)
     sizerTop->Add(sizerMiddle, 0, wxGROW | wxALL, 10);
     sizerTop->Add(m_sizerText, 1, wxGROW | (wxALL & ~wxRIGHT), 10);
 
-    SetAutoLayout(TRUE);
     SetSizer(sizerTop);
-
-    sizerTop->Fit(this);
-}
-
-TextWidgetsPage::~TextWidgetsPage()
-{
 }
 
 // ----------------------------------------------------------------------------
@@ -390,12 +572,12 @@ wxTextCtrl *TextWidgetsPage::CreateInfoText()
     if ( !s_maxWidth )
     {
         // calc it once only
-        GetTextExtent(_T("9999999"), &s_maxWidth, NULL);
+        GetTextExtent(wxT("9999999"), &s_maxWidth, NULL);
     }
 
-    wxTextCtrl *text = new wxTextCtrl(this, -1, _T(""),
+    wxTextCtrl *text = new wxTextCtrl(this, wxID_ANY, wxEmptyString,
                                       wxDefaultPosition,
-                                      wxSize(s_maxWidth, -1),
+                                      wxSize(s_maxWidth, wxDefaultCoord),
                                       wxTE_READONLY);
     return text;
 }
@@ -406,12 +588,12 @@ wxSizer *TextWidgetsPage::CreateTextWithLabelSizer(const wxString& label,
                                                  wxTextCtrl *text2)
 {
     wxSizer *sizerRow = new wxBoxSizer(wxHORIZONTAL);
-    sizerRow->Add(new wxStaticText(this, -1, label), 0,
+    sizerRow->Add(new wxStaticText(this, wxID_ANY, label), 0,
                   wxALIGN_CENTRE_VERTICAL | wxRIGHT, 5);
     sizerRow->Add(text, 0, wxALIGN_CENTRE_VERTICAL);
     if ( text2 )
     {
-        sizerRow->Add(new wxStaticText(this, -1, label2), 0,
+        sizerRow->Add(new wxStaticText(this, wxID_ANY, label2), 0,
                       wxALIGN_CENTRE_VERTICAL | wxLEFT | wxRIGHT, 5);
         sizerRow->Add(text2, 0, wxALIGN_CENTRE_VERTICAL);
     }
@@ -426,25 +608,32 @@ wxSizer *TextWidgetsPage::CreateTextWithLabelSizer(const wxString& label,
 void TextWidgetsPage::Reset()
 {
     m_radioTextLines->SetSelection(DEFAULTS.textLines);
+
     m_chkPassword->SetValue(DEFAULTS.password);
-    m_chkWrapLines->SetValue(DEFAULTS.wraplines);
     m_chkReadonly->SetValue(DEFAULTS.readonly);
+    m_chkFilename->SetValue(DEFAULTS.filename);
+
+    m_radioWrap->SetSelection(DEFAULTS.wrapStyle);
+
+#ifdef __WXMSW__
+    m_radioKind->SetSelection(DEFAULTS.textKind);
+#endif // __WXMSW__
 }
 
 void TextWidgetsPage::CreateText()
 {
-    int flags = 0;
+    int flags = ms_defaultFlags;
     switch ( m_radioTextLines->GetSelection() )
     {
         default:
-            wxFAIL_MSG( _T("unexpected radio box selection") );
+            wxFAIL_MSG( wxT("unexpected lines radio box selection") );
 
         case TextLines_Single:
             break;
 
         case TextLines_Multi:
             flags |= wxTE_MULTILINE;
-            m_chkPassword->SetValue(FALSE);
+            m_chkPassword->SetValue(false);
             break;
     }
 
@@ -452,28 +641,72 @@ void TextWidgetsPage::CreateText()
         flags |= wxTE_PASSWORD;
     if ( m_chkReadonly->GetValue() )
         flags |= wxTE_READONLY;
-    if ( !m_chkWrapLines->GetValue() )
-        flags |= wxHSCROLL;
+
+    switch ( m_radioWrap->GetSelection() )
+    {
+        default:
+            wxFAIL_MSG( wxT("unexpected wrap style radio box selection") );
+
+        case WrapStyle_None:
+            flags |= wxTE_DONTWRAP; // same as wxHSCROLL
+            break;
+
+        case WrapStyle_Word:
+            flags |= wxTE_WORDWRAP;
+            break;
+
+        case WrapStyle_Char:
+            flags |= wxTE_CHARWRAP;
+            break;
+
+        case WrapStyle_Best:
+            // this is default but use symbolic file name for consistency
+            flags |= wxTE_BESTWRAP;
+            break;
+    }
+
+#ifdef __WXMSW__
+    switch ( m_radioKind->GetSelection() )
+    {
+        default:
+            wxFAIL_MSG( wxT("unexpected kind radio box selection") );
+
+        case TextKind_Plain:
+            break;
+
+        case TextKind_Rich:
+            flags |= wxTE_RICH;
+            break;
+
+        case TextKind_Rich2:
+            flags |= wxTE_RICH2;
+            break;
+    }
+#endif // __WXMSW__
 
     wxString valueOld;
     if ( m_text )
     {
         valueOld = m_text->GetValue();
 
-        m_sizerText->Remove(m_text);
+        m_sizerText->Detach( m_text );
         delete m_text;
     }
     else
     {
-        valueOld = _T("Hello, Universe!");
+        valueOld = wxT("Hello, Universe!");
     }
 
-    m_text = new wxTextCtrl(this, TextPage_Textctrl,
-                            valueOld,
-                            wxDefaultPosition, wxDefaultSize,
-                            flags);
+    m_text = new WidgetsTextCtrl(this, TextPage_Textctrl, valueOld, flags);
+
+#if 0
+    if ( m_chkFilename->GetValue() )
+        ;
+#endif // TODO
+
+    // cast to int needed to silence gcc warning about different enums
     m_sizerText->Add(m_text, 1, wxALL |
-                     (flags & wxTE_MULTILINE ? wxGROW
+                     (flags & wxTE_MULTILINE ? (int)wxGROW
                                              : wxALIGN_TOP), 5);
     m_sizerText->Layout();
 }
@@ -521,7 +754,7 @@ void TextWidgetsPage::OnIdle(wxIdleEvent& WXUNUSED(event))
     if ( m_textLineLast )
     {
         m_textLineLast->SetValue(
-                wxString::Format(_T("%ld"), m_text->GetNumberOfLines()));
+                wxString::Format(wxT("%d"), m_text->GetNumberOfLines()) );
     }
 
     if ( m_textSelFrom && m_textSelTo )
@@ -544,6 +777,16 @@ void TextWidgetsPage::OnIdle(wxIdleEvent& WXUNUSED(event))
             m_selTo = selTo;
         }
     }
+
+    if ( m_textRange )
+    {
+        wxString range = m_text->GetRange(10, 20);
+        if ( range != m_range10_20 )
+        {
+            m_range10_20 = range;
+            m_textRange->SetValue(range);
+        }
+    }
 }
 
 void TextWidgetsPage::OnButtonReset(wxCommandEvent& WXUNUSED(event))
@@ -555,20 +798,30 @@ void TextWidgetsPage::OnButtonReset(wxCommandEvent& WXUNUSED(event))
 
 void TextWidgetsPage::OnButtonSet(wxCommandEvent& WXUNUSED(event))
 {
-    m_text->SetValue(_T("Yellow submarine"));
+    m_text->SetValue(m_text->GetWindowStyle() & wxTE_MULTILINE
+                        ? wxT("Here,\nthere and\neverywhere")
+                        : wxT("Yellow submarine"));
+
     m_text->SetFocus();
 }
 
 void TextWidgetsPage::OnButtonAdd(wxCommandEvent& WXUNUSED(event))
 {
-    m_text->AppendText(_T("here, there and everywhere"));
-    m_text->SetFocus();
+    if ( m_text->GetWindowStyle() & wxTE_MULTILINE )
+    {
+        m_text->AppendText(wxT("We all live in a\n"));
+    }
+
+    m_text->AppendText(wxT("Yellow submarine"));
 }
 
 void TextWidgetsPage::OnButtonInsert(wxCommandEvent& WXUNUSED(event))
 {
-    m_text->WriteText(_T("is there anybody going to listen to my story"));
-    m_text->SetFocus();
+    m_text->WriteText(wxT("Is there anybody going to listen to my story"));
+    if ( m_text->GetWindowStyle() & wxTE_MULTILINE )
+    {
+        m_text->WriteText(wxT("\nall about the girl who came to stay"));
+    }
 }
 
 void TextWidgetsPage::OnButtonClear(wxCommandEvent& WXUNUSED(event))
@@ -581,14 +834,14 @@ void TextWidgetsPage::OnButtonLoad(wxCommandEvent& WXUNUSED(event))
 {
     // search for the file in several dirs where it's likely to be
     wxPathList pathlist;
-    pathlist.Add(_T("."));
-    pathlist.Add(_T(".."));
-    pathlist.Add(_T("../../../samples/widgets"));
+    pathlist.Add(wxT("."));
+    pathlist.Add(wxT(".."));
+    pathlist.Add(wxT("../../../samples/widgets"));
 
-    wxString filename = pathlist.FindValidPath(_T("textctrl.cpp"));
+    wxString filename = pathlist.FindValidPath(wxT("textctrl.cpp"));
     if ( !filename )
     {
-        wxLogError(_T("File textctrl.cpp not found."));
+        wxLogError(wxT("File textctrl.cpp not found."));
     }
     else // load it
     {
@@ -596,13 +849,14 @@ void TextWidgetsPage::OnButtonLoad(wxCommandEvent& WXUNUSED(event))
         if ( !m_text->LoadFile(filename) )
         {
             // this is not supposed to happen ...
-            wxLogError(_T("Error loading file."));
+            wxLogError(wxT("Error loading file."));
         }
         else
         {
             long elapsed = sw.Time();
-            wxLogMessage(_T("Loaded file '%s' in %u.%us"),
-                         filename.c_str(), elapsed / 1000, elapsed % 1000);
+            wxLogMessage(wxT("Loaded file '%s' in %lu.%us"),
+                         filename.c_str(), elapsed / 1000,
+                         (unsigned int) elapsed % 1000);
         }
     }
 }
@@ -626,33 +880,48 @@ void TextWidgetsPage::OnUpdateUIPasswordCheckbox(wxUpdateUIEvent& event)
 void TextWidgetsPage::OnUpdateUIResetButton(wxUpdateUIEvent& event)
 {
     event.Enable( (m_radioTextLines->GetSelection() != DEFAULTS.textLines) ||
-                  (m_chkReadonly->GetValue() != DEFAULTS.readonly) ||
+#ifdef __WXMSW__
+                  (m_radioKind->GetSelection() != DEFAULTS.textKind) ||
+#endif // __WXMSW__
                   (m_chkPassword->GetValue() != DEFAULTS.password) ||
-                  (m_chkWrapLines->GetValue() != DEFAULTS.wraplines) );
+                  (m_chkReadonly->GetValue() != DEFAULTS.readonly) ||
+                  (m_chkFilename->GetValue() != DEFAULTS.filename) ||
+                  (m_radioWrap->GetSelection() != DEFAULTS.wrapStyle) );
 }
 
-void TextWidgetsPage::OnText(wxCommandEvent& event)
+void TextWidgetsPage::OnText(wxCommandEvent& WXUNUSED(event))
 {
     // small hack to suppress the very first message: by then the logging is
     // not yet redirected and so initial setting of the text value results in
     // an annoying message box
-    static bool s_firstTime = TRUE;
+    static bool s_firstTime = true;
     if ( s_firstTime )
     {
-        s_firstTime = FALSE;
+        s_firstTime = false;
         return;
     }
 
-    wxLogMessage(_T("Text ctrl value changed"));
+    wxLogMessage(wxT("Text ctrl value changed"));
 }
 
 void TextWidgetsPage::OnTextEnter(wxCommandEvent& event)
 {
-    wxLogMessage(_T("Text entered: '%s'"), event.GetString().c_str());
+    wxLogMessage(wxT("Text entered: '%s'"), event.GetString().c_str());
+    event.Skip();
 }
 
-void TextWidgetsPage::OnCheckOrRadioBox(wxCommandEvent& event)
+void TextWidgetsPage::OnCheckOrRadioBox(wxCommandEvent& WXUNUSED(event))
 {
     CreateText();
 }
 
+void TextWidgetsPage::OnStreamRedirector(wxCommandEvent& WXUNUSED(event))
+{
+#if wxHAS_TEXT_WINDOW_STREAM
+    wxStreamToTextRedirector redirect(m_text);
+    wxString str( wxT("Outputed to cout, appears in wxTextCtrl!") );
+    wxSTD cout << str << wxSTD endl;
+#else
+    wxMessageBox(wxT("This wxWidgets build does not support wxStreamToTextRedirector"));
+#endif
+}