]> git.saurik.com Git - wxWidgets.git/blobdiff - samples/text/text.cpp
Tcl regex lib
[wxWidgets.git] / samples / text / text.cpp
index 6fc3a71448255cbd9f123b7bc1aa8fd4523df60f..5f4ba2899cc8409ccfb2424bca39f8788e270b0f 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".
@@ -36,6 +36,8 @@
     #include "wx/tooltip.h"
 #endif
 
     #include "wx/tooltip.h"
 #endif
 
+    #include "wx/progdlg.h"
+
 // We test for wxUSE_DRAG_AND_DROP also, because data objects may not be
 // implemented for compilers that can't cope with the OLE parts in
 // wxUSE_DRAG_AND_DROP.
 // We test for wxUSE_DRAG_AND_DROP also, because data objects may not be
 // implemented for compilers that can't cope with the OLE parts in
 // wxUSE_DRAG_AND_DROP.
@@ -61,17 +63,35 @@ 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);
+
+    void OnSetFocus(wxFocusEvent& event);
+    void OnKillFocus(wxFocusEvent& event);
+
+    static bool ms_logKey;
+    static bool ms_logChar;
+    static bool ms_logMouse;
+    static bool ms_logText;
+    static bool ms_logFocus;
 
 private:
     static inline wxChar GetChar(bool on, wxChar c) { return on ? c : _T('-'); }
 
 private:
     static inline wxChar GetChar(bool on, wxChar c) { return on ? c : _T('-'); }
-    void LogEvent(const wxChar *name, wxKeyEvent& event) const;
+    void LogKeyEvent(const wxChar *name, wxKeyEvent& event) const;
+
+    bool m_hasCapture;
 
     DECLARE_EVENT_TABLE()
 };
 
     DECLARE_EVENT_TABLE()
 };
@@ -80,12 +100,14 @@ class MyPanel: public wxPanel
 {
 public:
     MyPanel(wxFrame *frame, int x, int y, int w, int h);
 {
 public:
     MyPanel(wxFrame *frame, int x, int y, int w, int h);
+    virtual ~MyPanel() { delete wxLog::SetActiveTarget(m_logOld); }
 
 #if wxUSE_CLIPBOARD
     void DoPasteFromClipboard();
     void DoCopyToClipboard();
 #endif // wxUSE_CLIPBOARD
 
 
 #if wxUSE_CLIPBOARD
     void DoPasteFromClipboard();
     void DoCopyToClipboard();
 #endif // wxUSE_CLIPBOARD
 
+    void DoRemoveText();
     void DoMoveToEndOfText();
     void DoMoveToEndOfEntry();
 
     void DoMoveToEndOfText();
     void DoMoveToEndOfEntry();
 
@@ -96,6 +118,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;
@@ -104,7 +127,13 @@ public:
 
     wxTextCtrl    *m_log;
 
 
     wxTextCtrl    *m_log;
 
+    wxLog         *m_logOld;
+
 private:
 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 +156,103 @@ 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 OnLogFocus(wxCommandEvent& event)
+    {
+        MyTextCtrl::ms_logFocus = 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();
+
+        text->Clear();
+
+        wxProgressDialog dlg(_T("Wait..."), _T("Updating"), 100, this);
+        for ( int i = 0; i < 100; i++ )
+        {
+            dlg.Update(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 +284,38 @@ 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_LOG_FOCUS,
+
+    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 +323,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 +347,49 @@ 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->Append(TEXT_LOG_FOCUS, "Log &focus events", "", TRUE);
+    menuLog->AppendSeparator();
+    menuLog->Append(TEXT_CLEAR, "&Clear the log\tCtrl-C",
+                    "Clear the log window contents");
+
+    // select only the interesting events by default
+#if 0
+    menuLog->Check(TEXT_LOG_KEY, TRUE);
+    menuLog->Check(TEXT_LOG_CHAR, TRUE);
+    menuLog->Check(TEXT_LOG_TEXT, TRUE);
+
+    MyTextCtrl::ms_logKey =
+    MyTextCtrl::ms_logChar =
+    MyTextCtrl::ms_logText = TRUE;
+#else
+    menuLog->Check(TEXT_LOG_FOCUS, TRUE);
+    MyTextCtrl::ms_logFocus = TRUE;
+#endif
+    menu_bar->Append(menuLog, "&Log");
 
     frame->SetMenuBar(menu_bar);
 
 
     frame->SetMenuBar(menu_bar);
 
@@ -239,9 +409,24 @@ 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)
+
+    EVT_SET_FOCUS(MyTextCtrl::OnSetFocus)
+    EVT_KILL_FOCUS(MyTextCtrl::OnKillFocus)
 END_EVENT_TABLE()
 
 END_EVENT_TABLE()
 
-void MyTextCtrl::LogEvent(const wxChar *name, wxKeyEvent& event) const
+bool MyTextCtrl::ms_logKey = FALSE;
+bool MyTextCtrl::ms_logChar = FALSE;
+bool MyTextCtrl::ms_logMouse = FALSE;
+bool MyTextCtrl::ms_logText = FALSE;
+bool MyTextCtrl::ms_logFocus = FALSE;
+
+void MyTextCtrl::LogKeyEvent(const wxChar *name, wxKeyEvent& event) const
 {
     wxString key;
     long keycode = event.KeyCode();
 {
     wxString key;
     long keycode = event.KeyCode();
@@ -353,9 +538,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 +554,146 @@ 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::OnSetFocus(wxFocusEvent& event)
+{
+    if ( ms_logFocus )
+        wxLogMessage("%p got focus.", this);
+
+    event.Skip();
+}
+
+void MyTextCtrl::OnKillFocus(wxFocusEvent& event)
+{
+    if ( ms_logFocus )
+        wxLogMessage("%p lost focus", this);
+
+    event.Skip();
+}
+
+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 )
+        LogKeyEvent( _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 )
+        LogKeyEvent( _T("Key up"), event);
 
     event.Skip();
 }
 
     event.Skip();
 }
@@ -412,15 +708,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;
@@ -445,7 +738,7 @@ void MyTextCtrl::OnKeyDown(wxKeyEvent& event)
             else
             {
                 wxLogDebug( wxT("Stopped capturing mouse and events.") );
             else
             {
                 wxLogDebug( wxT("Stopped capturing mouse and events.") );
-                m_hasCapture = TRUE;
+                m_hasCapture = FALSE;
                 ReleaseMouse();
             }
             break;
                 ReleaseMouse();
             }
             break;
@@ -455,10 +748,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 )
+        LogKeyEvent( wxT("Key down"), event);
+
     event.Skip();
 }
 
     event.Skip();
 }
 
@@ -473,16 +786,19 @@ 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 ) );
-
-    delete old_log;
+    m_logOld = wxLog::SetActiveTarget( new wxLogTextCtrl( m_log ) );
 
     // 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 +809,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 +868,37 @@ 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);
+
+    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"));
 }
 
 void MyPanel::OnSize( wxSizeEvent &event )
 }
 
 void MyPanel::OnSize( wxSizeEvent &event )
@@ -531,6 +908,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 +1017,11 @@ void MyPanel::DoMoveToEndOfEntry()
     m_text->SetFocus();
 }
 
     m_text->SetFocus();
 }
 
+void MyPanel::DoRemoveText()
+{
+    GetFocusedText(m_multitext)->Remove(0, 10);
+}
+
 //----------------------------------------------------------------------
 // MyFrame
 //----------------------------------------------------------------------
 //----------------------------------------------------------------------
 // MyFrame
 //----------------------------------------------------------------------
@@ -641,7 +1031,13 @@ 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_LOG_FOCUS,MyFrame::OnLogFocus)
+    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 +1049,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 +1091,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 +1138,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