]> git.saurik.com Git - wxWidgets.git/blobdiff - samples/text/text.cpp
fill wxFocusEvent::m_win properly
[wxWidgets.git] / samples / text / text.cpp
index 6fc3a71448255cbd9f123b7bc1aa8fd4523df60f..7e872901669c43cee5a4d007cf0c1d4b6ab19f98 100644 (file)
@@ -1,15 +1,15 @@
 /////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////
-// Name:        controls.cpp
+// Name:        text.cpp
 // Purpose:     TextCtrl wxWindows sample
 // Author:      Robert Roebling
 // Modified by:
 // RCS-ID:      $Id$
 // Purpose:     TextCtrl wxWindows sample
 // Author:      Robert Roebling
 // Modified by:
 // RCS-ID:      $Id$
-// Copyright:   (c) Robert Roebling, Julian Smart
+// Copyright:   (c) Robert Roebling, Julian Smart, Vadim Zeitlin
 // Licence:     wxWindows license
 /////////////////////////////////////////////////////////////////////////////
 
 #ifdef __GNUG__
 // Licence:     wxWindows license
 /////////////////////////////////////////////////////////////////////////////
 
 #ifdef __GNUG__
-    #pragma implementation "controls.h"
+    #pragma implementation "text.cpp"
 #endif
 
 // For compilers that support precompilation, includes "wx/wx.h".
 #endif
 
 // For compilers that support precompilation, includes "wx/wx.h".
@@ -61,18 +61,32 @@ class MyTextCtrl : public wxTextCtrl
 public:
     MyTextCtrl(wxWindow *parent, wxWindowID id, const wxString &value,
                const wxPoint &pos, const wxSize &size, int style = 0)
 public:
     MyTextCtrl(wxWindow *parent, wxWindowID id, const wxString &value,
                const wxPoint &pos, const wxSize &size, int style = 0)
-        : wxTextCtrl(parent, id, value, pos, size, style) { m_hasCapture = FALSE; }
+        : wxTextCtrl(parent, id, value, pos, size, style)
+    {
+        m_hasCapture = FALSE;
+    }
 
     void OnKeyDown(wxKeyEvent& event);
     void OnKeyUp(wxKeyEvent& event);
     void OnChar(wxKeyEvent& event);
 
 
     void OnKeyDown(wxKeyEvent& event);
     void OnKeyUp(wxKeyEvent& event);
     void OnChar(wxKeyEvent& event);
 
-    bool  m_hasCapture;
+    void OnText(wxCommandEvent& event);
+    void OnTextURL(wxTextUrlEvent& event);
+    void OnTextMaxLen(wxCommandEvent& event);
+
+    void OnMouseEvent(wxMouseEvent& event);
+
+    static bool ms_logKey;
+    static bool ms_logChar;
+    static bool ms_logMouse;
+    static bool ms_logText;
 
 private:
     static inline wxChar GetChar(bool on, wxChar c) { return on ? c : _T('-'); }
     void LogEvent(const wxChar *name, wxKeyEvent& event) const;
 
 
 private:
     static inline wxChar GetChar(bool on, wxChar c) { return on ? c : _T('-'); }
     void LogEvent(const wxChar *name, wxKeyEvent& event) const;
 
+    bool m_hasCapture;
+
     DECLARE_EVENT_TABLE()
 };
 
     DECLARE_EVENT_TABLE()
 };
 
@@ -86,6 +100,7 @@ public:
     void DoCopyToClipboard();
 #endif // wxUSE_CLIPBOARD
 
     void DoCopyToClipboard();
 #endif // wxUSE_CLIPBOARD
 
+    void DoRemoveText();
     void DoMoveToEndOfText();
     void DoMoveToEndOfEntry();
 
     void DoMoveToEndOfText();
     void DoMoveToEndOfEntry();
 
@@ -96,6 +111,7 @@ public:
     MyTextCtrl    *m_enter;
     MyTextCtrl    *m_tab;
     MyTextCtrl    *m_readonly;
     MyTextCtrl    *m_enter;
     MyTextCtrl    *m_tab;
     MyTextCtrl    *m_readonly;
+    MyTextCtrl    *m_limited;
 
     MyTextCtrl    *m_multitext;
     MyTextCtrl    *m_horizontal;
 
     MyTextCtrl    *m_multitext;
     MyTextCtrl    *m_horizontal;
@@ -105,6 +121,10 @@ public:
     wxTextCtrl    *m_log;
 
 private:
     wxTextCtrl    *m_log;
 
 private:
+    // get the currently focused text control or return the default one is no
+    // text ctrl has focus
+    wxTextCtrl *GetFocusedText(wxTextCtrl *textDef);
+
     DECLARE_EVENT_TABLE()
 };
 
     DECLARE_EVENT_TABLE()
 };
 
@@ -127,18 +147,92 @@ public:
         { m_panel->DoCopyToClipboard(); }
 #endif // wxUSE_CLIPBOARD
 
         { m_panel->DoCopyToClipboard(); }
 #endif // wxUSE_CLIPBOARD
 
+    void OnAddTextFreeze( wxCommandEvent& event )
+        { DoAddText(true); }
+    void OnAddText( wxCommandEvent& event )
+        { DoAddText(false); }
+    void OnRemoveText( wxCommandEvent& event )
+        { m_panel->DoRemoveText(); }
+
     void OnMoveToEndOfText( wxCommandEvent &event )
         { m_panel->DoMoveToEndOfText(); }
     void OnMoveToEndOfEntry( wxCommandEvent &event )
         { m_panel->DoMoveToEndOfEntry(); }
 
     void OnMoveToEndOfText( wxCommandEvent &event )
         { m_panel->DoMoveToEndOfText(); }
     void OnMoveToEndOfEntry( wxCommandEvent &event )
         { m_panel->DoMoveToEndOfEntry(); }
 
+    void OnScrollLineDown(wxCommandEvent& event)
+    {
+        if ( !m_panel->m_textrich->LineDown() )
+            wxLogMessage(_T("Already at the bottom"));
+    }
+
+    void OnScrollLineUp(wxCommandEvent& event)
+    {
+        if ( !m_panel->m_textrich->LineUp() )
+            wxLogMessage(_T("Already at the top"));
+    }
+
+    void OnScrollPageDown(wxCommandEvent& event)
+    {
+        if ( !m_panel->m_textrich->PageDown() )
+            wxLogMessage(_T("Already at the bottom"));
+    }
+
+    void OnScrollPageUp(wxCommandEvent& event)
+    {
+        if ( !m_panel->m_textrich->PageUp() )
+            wxLogMessage(_T("Already at the top"));
+    }
+
     void OnLogClear(wxCommandEvent& event);
     void OnFileSave(wxCommandEvent& event);
     void OnFileLoad(wxCommandEvent& event);
 
     void OnLogClear(wxCommandEvent& event);
     void OnFileSave(wxCommandEvent& event);
     void OnFileLoad(wxCommandEvent& event);
 
+    void OnSetEditable(wxCommandEvent& event);
+    void OnSetEnabled(wxCommandEvent& event);
+
+    void OnLogKey(wxCommandEvent& event)
+    {
+        MyTextCtrl::ms_logKey = event.IsChecked();
+    }
+
+    void OnLogChar(wxCommandEvent& event)
+    {
+        MyTextCtrl::ms_logChar = event.IsChecked();
+    }
+
+    void OnLogMouse(wxCommandEvent& event)
+    {
+        MyTextCtrl::ms_logMouse = event.IsChecked();
+    }
+
+    void OnLogText(wxCommandEvent& event)
+    {
+        MyTextCtrl::ms_logText = event.IsChecked();
+    }
+
+    void OnSetText(wxCommandEvent& event)
+    {
+        m_panel->m_text->SetValue(_T("Hello, world (what else did you expect)?"));
+    }
+
     void OnIdle( wxIdleEvent& event );
 
 private:
     void OnIdle( wxIdleEvent& event );
 
 private:
+    void DoAddText(bool freeze)
+    {
+        wxTextCtrl *text = m_panel->m_textrich;
+        if ( freeze )
+            text->Freeze();
+
+        for ( int i = 0; i < 100; i++ )
+            text->AppendText(wxString::Format(wxT("Line %i\n"), i));
+
+        text->SetInsertionPoint(0);
+
+        if ( freeze )
+            text->Thaw();
+    }
+
     MyPanel *m_panel;
 
     DECLARE_EVENT_TABLE()
     MyPanel *m_panel;
 
     DECLARE_EVENT_TABLE()
@@ -170,21 +264,37 @@ enum
     TEXT_TOOLTIPS_SETDELAY = 300,
     TEXT_TOOLTIPS_ENABLE,
 
     TEXT_TOOLTIPS_SETDELAY = 300,
     TEXT_TOOLTIPS_ENABLE,
 
-    // move menu
-    TEXT_MOVE_ENDTEXT = 400,
-    TEXT_MOVE_ENDENTRY
+    // text menu
+    TEXT_ADD_SOME = 400,
+    TEXT_ADD_FREEZE,
+    TEXT_MOVE_ENDTEXT,
+    TEXT_MOVE_ENDENTRY,
+    TEXT_SET_EDITABLE,
+    TEXT_SET_ENABLED,
+    TEXT_LINE_DOWN,
+    TEXT_LINE_UP,
+    TEXT_PAGE_DOWN,
+    TEXT_PAGE_UP,
+    TEXT_REMOVE,
+    TEXT_SET,
+
+    // log menu
+    TEXT_LOG_KEY,
+    TEXT_LOG_CHAR,
+    TEXT_LOG_MOUSE,
+    TEXT_LOG_TEXT,
+
+    TEXT_END
 };
 
 bool MyApp::OnInit()
 {
     // Create the main frame window
     MyFrame *frame = new MyFrame((wxFrame *) NULL,
 };
 
 bool MyApp::OnInit()
 {
     // Create the main frame window
     MyFrame *frame = new MyFrame((wxFrame *) NULL,
-            "Text wxWindows sample", 50, 50, 660, 420);
+            "Text wxWindows sample", 50, 50, 700, 420);
     frame->SetSizeHints( 500, 400 );
 
     wxMenu *file_menu = new wxMenu;
     frame->SetSizeHints( 500, 400 );
 
     wxMenu *file_menu = new wxMenu;
-    file_menu->Append(TEXT_CLEAR, "&Clear the log\tCtrl-C",
-                      "Clear the log window contents");
     file_menu->Append(TEXT_SAVE, "&Save file\tCtrl-S",
                       "Save the text control contents to file");
     file_menu->Append(TEXT_LOAD, "&Load file\tCtrl-O",
     file_menu->Append(TEXT_SAVE, "&Save file\tCtrl-S",
                       "Save the text control contents to file");
     file_menu->Append(TEXT_LOAD, "&Load file\tCtrl-O",
@@ -192,7 +302,7 @@ bool MyApp::OnInit()
     file_menu->AppendSeparator();
     file_menu->Append(TEXT_ABOUT, "&About\tAlt-A");
     file_menu->AppendSeparator();
     file_menu->AppendSeparator();
     file_menu->Append(TEXT_ABOUT, "&About\tAlt-A");
     file_menu->AppendSeparator();
-    file_menu->Append(TEXT_QUIT, "E&xit\tAlt-X", "Quit controls sample");
+    file_menu->Append(TEXT_QUIT, "E&xit\tAlt-X", "Quit this sample");
 
     wxMenuBar *menu_bar = new wxMenuBar( wxMB_DOCKABLE );
     menu_bar->Append(file_menu, "&File");
 
     wxMenuBar *menu_bar = new wxMenuBar( wxMB_DOCKABLE );
     menu_bar->Append(file_menu, "&File");
@@ -216,10 +326,37 @@ bool MyApp::OnInit()
     menu_bar->Append(menuClipboard, "&Clipboard");
 #endif // wxUSE_CLIPBOARD
 
     menu_bar->Append(menuClipboard, "&Clipboard");
 #endif // wxUSE_CLIPBOARD
 
-    wxMenu *menuMove = new wxMenu;
-    menuMove->Append(TEXT_MOVE_ENDTEXT, "To the end of &text");
-    menuMove->Append(TEXT_MOVE_ENDENTRY, "To the end of &entry");
-    menu_bar->Append(menuMove, "&Move");
+    wxMenu *menuText = new wxMenu;
+    menuText->Append(TEXT_ADD_SOME, "&Append some text\tCtrl-A");
+    menuText->Append(TEXT_ADD_FREEZE, "&Append text with freeze/thaw\tShift-Ctrl-A");
+    menuText->Append(TEXT_REMOVE, "&Remove first 10 characters\tCtrl-X");
+    menuText->Append(TEXT_SET, "&Set the first text zone value\tCtrl-E");
+    menuText->AppendSeparator();
+    menuText->Append(TEXT_MOVE_ENDTEXT, "Move cursor to the end of &text");
+    menuText->Append(TEXT_MOVE_ENDENTRY, "Move cursor to the end of &entry");
+    menuText->Append(TEXT_SET_EDITABLE, "Toggle &editable state", "", TRUE);
+    menuText->Append(TEXT_SET_ENABLED, "Toggle e&nabled state", "", TRUE);
+    menuText->Check(TEXT_SET_EDITABLE, TRUE);
+    menuText->Check(TEXT_SET_ENABLED, TRUE);
+    menuText->AppendSeparator();
+    menuText->Append(TEXT_LINE_DOWN, "Scroll text one line down");
+    menuText->Append(TEXT_LINE_UP, "Scroll text one line up");
+    menuText->Append(TEXT_PAGE_DOWN, "Scroll text one page down");
+    menuText->Append(TEXT_PAGE_DOWN, "Scroll text one page up");
+    menu_bar->Append(menuText, "Te&xt");
+
+    wxMenu *menuLog = new wxMenu;
+    menuLog->Append(TEXT_LOG_KEY, "Log &key events", "", TRUE);
+    menuLog->Append(TEXT_LOG_CHAR, "Log &char events", "", TRUE);
+    menuLog->Append(TEXT_LOG_MOUSE, "Log &mouse events", "", TRUE);
+    menuLog->Append(TEXT_LOG_TEXT, "Log &text events", "", TRUE);
+    menuLog->AppendSeparator();
+    menuLog->Append(TEXT_CLEAR, "&Clear the log\tCtrl-C",
+                    "Clear the log window contents");
+    menuLog->Check(TEXT_LOG_KEY, TRUE);
+    menuLog->Check(TEXT_LOG_CHAR, TRUE);
+    menuLog->Check(TEXT_LOG_TEXT, TRUE);
+    menu_bar->Append(menuLog, "&Log");
 
     frame->SetMenuBar(menu_bar);
 
 
     frame->SetMenuBar(menu_bar);
 
@@ -239,8 +376,19 @@ BEGIN_EVENT_TABLE(MyTextCtrl, wxTextCtrl)
     EVT_KEY_DOWN(MyTextCtrl::OnKeyDown)
     EVT_KEY_UP(MyTextCtrl::OnKeyUp)
     EVT_CHAR(MyTextCtrl::OnChar)
     EVT_KEY_DOWN(MyTextCtrl::OnKeyDown)
     EVT_KEY_UP(MyTextCtrl::OnKeyUp)
     EVT_CHAR(MyTextCtrl::OnChar)
+
+    EVT_TEXT(-1, MyTextCtrl::OnText)
+    EVT_TEXT_URL(-1, MyTextCtrl::OnTextURL)
+    EVT_TEXT_MAXLEN(-1, MyTextCtrl::OnTextMaxLen)
+
+    EVT_MOUSE_EVENTS(MyTextCtrl::OnMouseEvent)
 END_EVENT_TABLE()
 
 END_EVENT_TABLE()
 
+bool MyTextCtrl::ms_logKey = TRUE;
+bool MyTextCtrl::ms_logChar = TRUE;
+bool MyTextCtrl::ms_logMouse = FALSE;
+bool MyTextCtrl::ms_logText = TRUE;
+
 void MyTextCtrl::LogEvent(const wxChar *name, wxKeyEvent& event) const
 {
     wxString key;
 void MyTextCtrl::LogEvent(const wxChar *name, wxKeyEvent& event) const
 {
     wxString key;
@@ -353,9 +501,11 @@ void MyTextCtrl::LogEvent(const wxChar *name, wxKeyEvent& event) const
             default:
             {
                if ( wxIsprint((int)keycode) )
             default:
             {
                if ( wxIsprint((int)keycode) )
-                   key.Printf( _T("'%c'") , (char)keycode);
+                   key.Printf(_T("'%c'"), (char)keycode);
+               else if ( keycode > 0 && keycode < 27 )
+                   key.Printf(_("Ctrl-%c"), _T('A') + keycode - 1);
                else
                else
-                   key.Printf( _T("unknown (%ld)"), keycode);
+                   key.Printf(_T("unknown (%ld)"), keycode);
             }
         }
     }
             }
         }
     }
@@ -367,37 +517,130 @@ void MyTextCtrl::LogEvent(const wxChar *name, wxKeyEvent& event) const
                   GetChar( event.AltDown(), _T('A') ),
                   GetChar( event.ShiftDown(), _T('S') ),
                   GetChar( event.MetaDown(), _T('M') ) );
                   GetChar( event.AltDown(), _T('A') ),
                   GetChar( event.ShiftDown(), _T('S') ),
                   GetChar( event.MetaDown(), _T('M') ) );
+}
+
+static wxString GetMouseEventDesc(const wxMouseEvent& ev)
+{
+    // click event
+    wxString button;
+    bool dbl, up;
+    if ( ev.LeftDown() || ev.LeftUp() || ev.LeftDClick() )
+    {
+        button = _T("Left");
+        dbl = ev.LeftDClick();
+        up = ev.LeftUp();
+    }
+    else if ( ev.MiddleDown() || ev.MiddleUp() || ev.MiddleDClick() )
+    {
+        button = _T("Middle");
+        dbl = ev.MiddleDClick();
+        up = ev.MiddleUp();
+    }
+    else if ( ev.RightDown() || ev.RightUp() || ev.RightDClick() )
+    {
+        button = _T("Right");
+        dbl = ev.RightDClick();
+        up = ev.RightUp();
+    }
+    else
+    {
+        return _T("Unknown mouse event");
+    }
 
 
+    return wxString::Format(_T("%s mouse button %s"),
+                            button.c_str(),
+                            dbl ? _T("double clicked")
+                                : up ? _T("released") : _T("clicked"));
 }
 
 }
 
-void MyTextCtrl::OnChar(wxKeyEvent& event)
+void MyTextCtrl::OnMouseEvent(wxMouseEvent& ev)
 {
 {
-    LogEvent( _T("Char"), event);
+    ev.Skip();
 
 
-    wxWindow *win = (wxWindow *)event.GetEventObject();
-    const wxChar *data = (const wxChar *)(win->GetClientData());
-    if ( data )
+    if ( !ms_logMouse )
+        return;
+
+    if ( !ev.Moving() )
     {
     {
-        wxLogMessage(_T(" (from control '%s')"), data);
+        wxString msg;
+        if ( ev.Entering() )
+        {
+            msg = _T("Mouse entered the window");
+        }
+        else if ( ev.Leaving() )
+        {
+            msg = _T("Mouse left the window");
+        }
+        else
+        {
+            msg = GetMouseEventDesc(ev);
+        }
+
+        msg << _T(" at (") << ev.GetX() << _T(", ") << ev.GetY() << _T(") ")
+            << _T("Flags: ")
+            << GetChar( ev.LeftIsDown(), _T('1') )
+            << GetChar( ev.MiddleIsDown(), _T('2') )
+            << GetChar( ev.RightIsDown(), _T('3') )
+            << GetChar( ev.ControlDown(), _T('C') )
+            << GetChar( ev.AltDown(), _T('A') )
+            << GetChar( ev.ShiftDown(), _T('S') )
+            << GetChar( ev.MetaDown(), _T('M') );
+
+        wxLogMessage(msg);
     }
     }
+    //else: we're not interested in mouse move events
+}
 
 
-/*  How are we supposed to test wxTE_PROCESS_TAB with this code?
+void MyTextCtrl::OnText(wxCommandEvent& event)
+{
+    if ( !ms_logText )
+        return;
 
 
-    if ( event.KeyCode() == WXK_TAB )
+    MyTextCtrl *win = (MyTextCtrl *)event.GetEventObject();
+    const wxChar *data = (const wxChar *)(win->GetClientData());
+    if ( data )
     {
     {
-        WriteText("\t");
+        wxLogMessage(_T("Text changed in control '%s'"), data);
     }
     else
     {
     }
     else
     {
-        event.Skip();
+        wxLogMessage(_T("Text changed in some control"));
     }
     }
-*/
+}
+
+void MyTextCtrl::OnTextMaxLen(wxCommandEvent& event)
+{
+    wxLogMessage(_T("You can't enter more characters into this control."));
+}
+
+void MyTextCtrl::OnTextURL(wxTextUrlEvent& event)
+{
+    const wxMouseEvent& ev = event.GetMouseEvent();
+
+    // filter out mouse moves, too many of them
+    if ( ev.Moving() )
+        return;
+
+    long start = event.GetURLStart(),
+         end = event.GetURLEnd();
+
+    wxLogMessage(_T("Mouse event over URL '%s': %s"),
+                 GetValue().Mid(start, end - start).c_str(),
+                 GetMouseEventDesc(ev).c_str());
+}
+
+void MyTextCtrl::OnChar(wxKeyEvent& event)
+{
+    if ( ms_logChar )
+        LogEvent( _T("Char"), event);
+
     event.Skip();
 }
 
 void MyTextCtrl::OnKeyUp(wxKeyEvent& event)
 {
     event.Skip();
 }
 
 void MyTextCtrl::OnKeyUp(wxKeyEvent& event)
 {
-    LogEvent( _T("Key up"), event);
+    if ( ms_logKey )
+        LogEvent( _T("Key up"), event);
 
     event.Skip();
 }
 
     event.Skip();
 }
@@ -412,15 +655,12 @@ void MyTextCtrl::OnKeyDown(wxKeyEvent& event)
                 long line, column, pos = GetInsertionPoint();
                 PositionToXY(pos, &column, &line);
 
                 long line, column, pos = GetInsertionPoint();
                 PositionToXY(pos, &column, &line);
 
-                wxLogMessage( _T("Current position: %ld\n"
-                        "Current line, column: (%ld, %ld)\n"
-                        "Number of lines: %ld\n"
-                        "Current line length: %ld\n"
-                        "Total text length: %ld"),
+                wxLogMessage( _T("Current position: %ld\nCurrent line, column: (%ld, %ld)\nNumber of lines: %ld\nCurrent line length: %ld\nTotal text length: %u (%ld)"),
                         pos,
                         line, column,
                         GetNumberOfLines(),
                         GetLineLength(line),
                         pos,
                         line, column,
                         GetNumberOfLines(),
                         GetLineLength(line),
+                        GetValue().length(),
                         GetLastPosition());
             }
             break;
                         GetLastPosition());
             }
             break;
@@ -455,10 +695,30 @@ void MyTextCtrl::OnKeyDown(wxKeyEvent& event)
             WriteText("\n");
             break;
 
             WriteText("\n");
             break;
 
-        default:
-            LogEvent( wxT("Key down"), event);
+        case WXK_F6:
+            SetValue("F6 was just pressed.");
+            break;
+
+        case WXK_F7:
+            ShowPosition(10);
+            break;
+
+        case WXK_F10:
+            {
+                long from, to;
+                GetSelection(&from, &to);
+
+                wxString sel = GetStringSelection();
+
+                wxLogMessage(_T("Selection: from %ld to %ld."), from, to);
+                wxLogMessage(_T("Selection = '%s' (len = %u)"),
+                             sel.c_str(), sel.length());
+            }
     }
 
     }
 
+    if ( ms_logKey )
+        LogEvent( wxT("Key down"), event);
+
     event.Skip();
 }
 
     event.Skip();
 }
 
@@ -473,7 +733,9 @@ END_EVENT_TABLE()
 MyPanel::MyPanel( wxFrame *frame, int x, int y, int w, int h )
        : wxPanel( frame, -1, wxPoint(x, y), wxSize(w, h) )
 {
 MyPanel::MyPanel( wxFrame *frame, int x, int y, int w, int h )
        : wxPanel( frame, -1, wxPoint(x, y), wxSize(w, h) )
 {
-    m_log = new wxTextCtrl( this, -1, "This is the log window.\n", wxPoint(5,260), wxSize(630,100), wxTE_MULTILINE );
+    m_log = new wxTextCtrl( this, -1, "This is the log window.\n",
+                            wxPoint(5,260), wxSize(630,100),
+                            wxTE_MULTILINE | wxTE_READONLY /* | wxTE_RICH */);
 
     wxLog *old_log = wxLog::SetActiveTarget( new wxLogTextCtrl( m_log ) );
 
 
     wxLog *old_log = wxLog::SetActiveTarget( new wxLogTextCtrl( m_log ) );
 
@@ -482,7 +744,10 @@ MyPanel::MyPanel( wxFrame *frame, int x, int y, int w, int h )
     // single line text controls
 
     m_text = new MyTextCtrl( this, -1, "Single line.",
     // single line text controls
 
     m_text = new MyTextCtrl( this, -1, "Single line.",
-      wxPoint(10,10), wxSize(140,-1), 0);
+                             wxPoint(10,10), wxSize(140,-1),
+                             wxTE_PROCESS_ENTER);
+    m_text->SetForegroundColour(*wxBLUE);
+    m_text->SetBackgroundColour(*wxLIGHT_GREY);
     (*m_text) << " Appended.";
     m_text->SetInsertionPoint(0);
     m_text->WriteText( "Prepended. " );
     (*m_text) << " Appended.";
     m_text->SetInsertionPoint(0);
     m_text->WriteText( "Prepended. " );
@@ -493,18 +758,58 @@ MyPanel::MyPanel( wxFrame *frame, int x, int y, int w, int h )
     m_readonly = new MyTextCtrl( this, -1, "Read only",
       wxPoint(10,90), wxSize(140,-1), wxTE_READONLY );
 
     m_readonly = new MyTextCtrl( this, -1, "Read only",
       wxPoint(10,90), wxSize(140,-1), wxTE_READONLY );
 
+    m_limited = new MyTextCtrl(this, -1, "Max 8 ch",
+                              wxPoint(10, 130), wxSize(140, -1));
+    m_limited->SetMaxLength(8);
+
     // multi line text controls
 
     m_horizontal = new MyTextCtrl( this, -1, "Multiline text control with a horizontal scrollbar.",
       wxPoint(10,170), wxSize(140,70), wxTE_MULTILINE | wxHSCROLL );
     // multi line text controls
 
     m_horizontal = new MyTextCtrl( this, -1, "Multiline text control with a horizontal scrollbar.",
       wxPoint(10,170), wxSize(140,70), wxTE_MULTILINE | wxHSCROLL );
-    m_horizontal->SetFont(wxFont(18, wxSWISS, wxNORMAL, wxNORMAL,
-                                 FALSE, "", wxFONTENCODING_KOI8));
+
+    // a little hack to use the command line argument for encoding testing
+    if ( wxTheApp->argc == 2 )
+    {
+        switch ( wxTheApp->argv[1][0] )
+        {
+            case '2':
+                m_horizontal->SetFont(wxFont(18, wxSWISS, wxNORMAL, wxNORMAL,
+                                             FALSE, "",
+                                             wxFONTENCODING_ISO8859_2));
+                m_horizontal->SetValue("®lu»ouèký kùò zbìsile èe¹tina «»");
+                break;
+
+            case '1':
+                m_horizontal->SetFont(wxFont(18, wxSWISS, wxNORMAL, wxNORMAL,
+                                             FALSE, "",
+                                             wxFONTENCODING_CP1251));
+                m_horizontal->SetValue("Ïðèâåò!");
+                break;
+
+            case '8':
+                m_horizontal->SetFont(wxFont(18, wxSWISS, wxNORMAL, wxNORMAL,
+                                             FALSE, "",
+                                             wxFONTENCODING_CP1251));
+#if wxUSE_UNICODE
+                m_horizontal->SetValue(L"\x0412\x0430\x0434\x0438\x043c \x0426");
+#else
+                m_horizontal->SetValue("ËÁÖÅÔÓÑ ÕÄÁÞÎÙÍ");
+#endif
+        }
+    }
+    else
+    {
+        m_horizontal->SetValue("Text in default encoding");
+    }
 
     m_multitext = new MyTextCtrl( this, -1, "Multi line.",
       wxPoint(180,10), wxSize(240,70), wxTE_MULTILINE );
 
     m_multitext = new MyTextCtrl( this, -1, "Multi line.",
       wxPoint(180,10), wxSize(240,70), wxTE_MULTILINE );
+    m_multitext->SetFont(*wxITALIC_FONT);
     (*m_multitext) << " Appended.";
     m_multitext->SetInsertionPoint(0);
     m_multitext->WriteText( "Prepended. " );
     (*m_multitext) << " Appended.";
     m_multitext->SetInsertionPoint(0);
     m_multitext->WriteText( "Prepended. " );
+    m_multitext->SetForegroundColour(*wxRED);
+    m_multitext->SetBackgroundColour(*wxLIGHT_GREY);
 
 #if wxUSE_TOOLTIPS
     m_multitext->SetToolTip("Press F1 here for statitics, F4 for capture and uncapture mouse.");
 
 #if wxUSE_TOOLTIPS
     m_multitext->SetToolTip("Press F1 here for statitics, F4 for capture and uncapture mouse.");
@@ -512,16 +817,48 @@ MyPanel::MyPanel( wxFrame *frame, int x, int y, int w, int h )
 
     m_tab = new MyTextCtrl( this, 100, "Multiline, allow <TAB> processing.",
       wxPoint(180,90), wxSize(240,70), wxTE_MULTILINE |  wxTE_PROCESS_TAB );
 
     m_tab = new MyTextCtrl( this, 100, "Multiline, allow <TAB> processing.",
       wxPoint(180,90), wxSize(240,70), wxTE_MULTILINE |  wxTE_PROCESS_TAB );
-    m_tab->SetClientData(_T("tab"));
+    m_tab->SetClientData((void *)_T("tab"));
 
     m_enter = new MyTextCtrl( this, 100, "Multiline, allow <ENTER> processing.",
       wxPoint(180,170), wxSize(240,70), wxTE_MULTILINE);
 
     m_enter = new MyTextCtrl( this, 100, "Multiline, allow <ENTER> processing.",
       wxPoint(180,170), wxSize(240,70), wxTE_MULTILINE);
-    m_enter->SetClientData(_T("enter"));
+    m_enter->SetClientData((void *)_T("enter"));
 
     m_textrich = new MyTextCtrl(this, -1, "Allows more than 30Kb of text\n"
 
     m_textrich = new MyTextCtrl(this, -1, "Allows more than 30Kb of text\n"
-                                "(even under broken Win9x)",
-                                wxPoint(450, 10), wxSize(200, 230),
-                                wxTE_RICH | wxTE_MULTILINE);
+                                "(even under broken Win9x)\n"
+                                "and a very very very very very "
+                                "very very very long line to test "
+                                "wxHSCROLL style",
+                                wxPoint(450, 10), wxSize(230, 230),
+                                wxTE_RICH |
+                                wxTE_MULTILINE |
+                                // wxTE_AUTO_URL |
+                                wxHSCROLL);
+
+#if 1
+    m_textrich->SetStyle(0, 10, *wxRED);
+    m_textrich->SetStyle(10, 20, *wxBLUE);
+    m_textrich->SetStyle(30, 40,
+                         wxTextAttr(*wxGREEN, wxNullColour, *wxITALIC_FONT));
+    m_textrich->SetDefaultStyle(wxTextAttr());
+    m_textrich->AppendText(_T("\n\nFirst 10 characters should be in red\n"));
+    m_textrich->AppendText(_T("Next 10 characters should be in blue\n"));
+    m_textrich->AppendText(_T("Next 10 characters should be normal\n"));
+    m_textrich->AppendText(_T("And the next 10 characters should be green and italic\n"));
+    m_textrich->SetDefaultStyle(wxTextAttr(*wxCYAN, *wxBLUE));
+    m_textrich->AppendText(_T("This text should be cyan on blue\n"));
+    m_textrich->SetDefaultStyle(wxTextAttr(*wxBLUE, *wxWHITE));
+    m_textrich->AppendText(_T("And this should be in blue and the text you ")
+                           _T("type should be in blue as well"));
+#else
+    m_textrich->SetFont(wxFont(12, wxFONTFAMILY_TELETYPE,
+                               wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL));
+    m_textrich->SetDefaultStyle(wxTextAttr(*wxRED));
+    m_textrich->AppendText(_T("Red text\n"));
+    m_textrich->SetDefaultStyle(wxTextAttr(wxNullColour, *wxLIGHT_GREY));
+    m_textrich->AppendText(_T("Red on grey text\n"));
+    m_textrich->SetDefaultStyle(wxTextAttr(*wxBLUE));
+    m_textrich->AppendText(_T("Blue on grey text\n"));
+#endif
 }
 
 void MyPanel::OnSize( wxSizeEvent &event )
 }
 
 void MyPanel::OnSize( wxSizeEvent &event )
@@ -531,6 +868,14 @@ void MyPanel::OnSize( wxSizeEvent &event )
     event.Skip();
 }
 
     event.Skip();
 }
 
+wxTextCtrl *MyPanel::GetFocusedText(wxTextCtrl *textDef)
+{
+    wxWindow *win = FindFocus();
+
+    wxTextCtrl *text = win ? wxDynamicCast(win, wxTextCtrl) : NULL;
+    return text ? text : textDef;
+}
+
 #if wxUSE_CLIPBOARD
 void MyPanel::DoPasteFromClipboard()
 {
 #if wxUSE_CLIPBOARD
 void MyPanel::DoPasteFromClipboard()
 {
@@ -632,6 +977,11 @@ void MyPanel::DoMoveToEndOfEntry()
     m_text->SetFocus();
 }
 
     m_text->SetFocus();
 }
 
+void MyPanel::DoRemoveText()
+{
+    GetFocusedText(m_multitext)->Remove(0, 10);
+}
+
 //----------------------------------------------------------------------
 // MyFrame
 //----------------------------------------------------------------------
 //----------------------------------------------------------------------
 // MyFrame
 //----------------------------------------------------------------------
@@ -641,7 +991,12 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame)
     EVT_MENU(TEXT_ABOUT,  MyFrame::OnAbout)
     EVT_MENU(TEXT_SAVE,   MyFrame::OnFileSave)
     EVT_MENU(TEXT_LOAD,   MyFrame::OnFileLoad)
     EVT_MENU(TEXT_ABOUT,  MyFrame::OnAbout)
     EVT_MENU(TEXT_SAVE,   MyFrame::OnFileSave)
     EVT_MENU(TEXT_LOAD,   MyFrame::OnFileLoad)
-    EVT_MENU(TEXT_CLEAR,  MyFrame::OnLogClear)
+
+    EVT_MENU(TEXT_LOG_KEY,  MyFrame::OnLogKey)
+    EVT_MENU(TEXT_LOG_CHAR, MyFrame::OnLogChar)
+    EVT_MENU(TEXT_LOG_MOUSE,MyFrame::OnLogMouse)
+    EVT_MENU(TEXT_LOG_TEXT, MyFrame::OnLogText)
+    EVT_MENU(TEXT_CLEAR,    MyFrame::OnLogClear)
 
 #if wxUSE_TOOLTIPS
     EVT_MENU(TEXT_TOOLTIPS_SETDELAY,  MyFrame::OnSetTooltipDelay)
 
 #if wxUSE_TOOLTIPS
     EVT_MENU(TEXT_TOOLTIPS_SETDELAY,  MyFrame::OnSetTooltipDelay)
@@ -653,9 +1008,22 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame)
     EVT_MENU(TEXT_CLIPBOARD_COPY,     MyFrame::OnCopyToClipboard)
 #endif // wxUSE_CLIPBOARD
 
     EVT_MENU(TEXT_CLIPBOARD_COPY,     MyFrame::OnCopyToClipboard)
 #endif // wxUSE_CLIPBOARD
 
+    EVT_MENU(TEXT_REMOVE,             MyFrame::OnRemoveText)
+    EVT_MENU(TEXT_ADD_SOME,           MyFrame::OnAddText)
+    EVT_MENU(TEXT_ADD_FREEZE,         MyFrame::OnAddTextFreeze)
     EVT_MENU(TEXT_MOVE_ENDTEXT,       MyFrame::OnMoveToEndOfText)
     EVT_MENU(TEXT_MOVE_ENDENTRY,      MyFrame::OnMoveToEndOfEntry)
 
     EVT_MENU(TEXT_MOVE_ENDTEXT,       MyFrame::OnMoveToEndOfText)
     EVT_MENU(TEXT_MOVE_ENDENTRY,      MyFrame::OnMoveToEndOfEntry)
 
+    EVT_MENU(TEXT_SET_EDITABLE,       MyFrame::OnSetEditable)
+    EVT_MENU(TEXT_SET_ENABLED,        MyFrame::OnSetEnabled)
+
+    EVT_MENU(TEXT_LINE_DOWN,          MyFrame::OnScrollLineDown)
+    EVT_MENU(TEXT_LINE_UP,            MyFrame::OnScrollLineUp)
+    EVT_MENU(TEXT_PAGE_DOWN,          MyFrame::OnScrollPageDown)
+    EVT_MENU(TEXT_PAGE_UP,            MyFrame::OnScrollPageUp)
+
+    EVT_MENU(TEXT_SET,                MyFrame::OnSetText)
+
     EVT_IDLE(MyFrame::OnIdle)
 END_EVENT_TABLE()
 
     EVT_IDLE(MyFrame::OnIdle)
 END_EVENT_TABLE()
 
@@ -682,7 +1050,7 @@ void MyFrame::OnAbout( wxCommandEvent& WXUNUSED(event) )
         "tooltips and intercepting key and char events.\n"
         "\n"
         "Copyright (c) 1999, Robert Roebling, Julian Smart, Vadim Zeitlin",
         "tooltips and intercepting key and char events.\n"
         "\n"
         "Copyright (c) 1999, Robert Roebling, Julian Smart, Vadim Zeitlin",
-        "About Text Controls",
+        "About wxTextCtrl Sample",
         wxOK | wxICON_INFORMATION);
 
     dialog.ShowModal();
         wxOK | wxICON_INFORMATION);
 
     dialog.ShowModal();
@@ -729,15 +1097,38 @@ void MyFrame::OnLogClear(wxCommandEvent& WXUNUSED(event))
     m_panel->m_log->Clear();
 }
 
     m_panel->m_log->Clear();
 }
 
+void MyFrame::OnSetEditable(wxCommandEvent& WXUNUSED(event))
+{
+    static bool s_editable = TRUE;
+
+    s_editable = !s_editable;
+    m_panel->m_text->SetEditable(s_editable);
+    m_panel->m_password->SetEditable(s_editable);
+    m_panel->m_multitext->SetEditable(s_editable);
+    m_panel->m_textrich->SetEditable(s_editable);
+}
+
+void MyFrame::OnSetEnabled(wxCommandEvent& WXUNUSED(event))
+{
+    bool enabled = m_panel->m_text->IsEnabled();
+    enabled = !enabled;
+
+    m_panel->m_text->Enable(enabled);
+    m_panel->m_password->Enable(enabled);
+    m_panel->m_multitext->Enable(enabled);
+    m_panel->m_readonly->Enable(enabled);
+    m_panel->m_limited->Enable(enabled);
+    m_panel->m_textrich->Enable(enabled);
+}
+
 void MyFrame::OnFileSave(wxCommandEvent& event)
 {
     if ( m_panel->m_textrich->SaveFile("dummy.txt") )
     {
 #if wxUSE_FILE
         // verify that the fil length is correct (it wasn't under Win95)
 void MyFrame::OnFileSave(wxCommandEvent& event)
 {
     if ( m_panel->m_textrich->SaveFile("dummy.txt") )
     {
 #if wxUSE_FILE
         // verify that the fil length is correct (it wasn't under Win95)
-        wxFile file("dummy.txt");
-        wxLogStatus(this, _T("Successfully saved file "
-                             "(text len = %ld, file size = %ld)"),
+        wxFile file(wxT("dummy.txt"));
+        wxLogStatus(this, _T("Successfully saved file (text len = %ld, file size = %ld)"),
                     m_panel->m_textrich->GetValue().length(),
                     file.Length());
 #endif
                     m_panel->m_textrich->GetValue().length(),
                     file.Length());
 #endif