From ca8b28f2efff34b9939035a7aeb1de1e3ac98a0c Mon Sep 17 00:00:00 2001
From: Julian Smart <julian@anthemion.co.uk>
Date: Tue, 6 Apr 1999 16:32:33 +0000
Subject: [PATCH] Added some missing wxTextCtrl functions: Undo, Redo, CanUndo,
 CanRedo, CanCopy, CanCut, CanPaste, GetSelection, IsEditable. Also added
 wxNotebook::SetTabSize (only implemented on wxMSW but necessary when using
 just an icon).

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@2054 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
---
 docs/latex/wx/text.tex        | 99 ++++++++++++++++++++++++++++-------
 include/wx/generic/notebook.h |  3 ++
 include/wx/gtk/notebook.h     |  3 ++
 include/wx/gtk/textctrl.h     | 16 ++++++
 include/wx/gtk1/notebook.h    |  3 ++
 include/wx/gtk1/textctrl.h    | 16 ++++++
 include/wx/motif/textctrl.h   | 14 +++++
 include/wx/msw/textctrl.h     | 16 ++++++
 include/wx/stubs/notebook.h   |  3 ++
 include/wx/stubs/textctrl.h   | 18 ++++++-
 src/generic/notebook.cpp      |  5 ++
 src/gtk/notebook.cpp          |  5 ++
 src/gtk/textctrl.cpp          | 65 +++++++++++++++++++++++
 src/gtk1/notebook.cpp         |  5 ++
 src/gtk1/textctrl.cpp         | 65 +++++++++++++++++++++++
 src/motif/textctrl.cpp        | 61 +++++++++++++++++++++
 src/msw/textctrl.cpp          | 84 +++++++++++++++++++++++++++--
 src/stubs/notebook.cpp        |  5 ++
 src/stubs/textctrl.cpp        | 63 ++++++++++++++++++++--
 19 files changed, 522 insertions(+), 27 deletions(-)

diff --git a/docs/latex/wx/text.tex b/docs/latex/wx/text.tex
index 7b431f2672..54395fae08 100644
--- a/docs/latex/wx/text.tex
+++ b/docs/latex/wx/text.tex
@@ -122,6 +122,59 @@ apply.
 
 Destructor, destroying the text control.
 
+\membersection{wxTextCtrl::AppendText}\label{wxtextctrlappendtext}
+
+\func{void}{AppendText}{\param{const wxString\& }{ text}}
+
+Appends the text to the end of the text control.
+
+\wxheading{Parameters}
+
+\docparam{text}{Text to write to the text control.}
+
+\wxheading{Remarks}
+
+After the text is appended, the insertion point will be at the end of the text control. If this behaviour is not desired,
+the programmer should use \helpref{GetInsertionPoint}{wxtextctrlgetinsertionpoint} and \helpref{SetInsertionPoint}{wxtextctrlsetinsertionpoint}.
+
+\wxheading{See also}
+
+\helpref{wxTextCtrl::WriteText}{wxtextctrlwritetext}
+
+\membersection{wxTextCtrl::CanCopy}\label{wxtextctrlcancopy}
+
+\func{virtual bool}{CanCopy}{\void}
+
+Returns TRUE if the selection can be copied to the clipboard.
+
+\membersection{wxTextCtrl::CanCut}\label{wxtextctrlcancut}
+
+\func{virtual bool}{CanCut}{\void}
+
+Returns TRUE if the selection can be cut to the clipboard.
+
+\membersection{wxTextCtrl::CanPaste}\label{wxtextctrlcanpaste}
+
+\func{virtual bool}{CanPaste}{\void}
+
+Returns TRUE if the contents of the clipboard can be pasted into the
+text control. On some platforms (Motif, GTK) this is an approximation
+and returns TRUE if the control is editable, FALSE otherwise.
+
+\membersection{wxTextCtrl::CanRedo}\label{wxtextctrlcanredo}
+
+\func{virtual bool}{CanRedo}{\void}
+
+Returns TRUE if there is a redo facility available and the last operation
+can be redone.
+
+\membersection{wxTextCtrl::CanUndo}\label{wxtextctrlcanundo}
+
+\func{virtual bool}{CanUndo}{\void}
+
+Returns TRUE if there is an undo facility available and the last operation
+can be undone.
+
 \membersection{wxTextCtrl::Clear}\label{wxtextctrlclear}
 
 \func{virtual void}{Clear}{\void}
@@ -232,6 +285,19 @@ calculated by actually counting newline characters in the buffer. You
 may wish to avoid using functions that work with line numbers if you are
 working with controls that contain large amounts of text.
 
+\membersection{wxTextCtrl::GetSelection}\label{wxtextctrlgetselection}
+
+\func{virtual void}{GetSelection}{\param{long*}{ from}, \param{long*}{ to}}
+
+Gets the current selection span. If the returned values are equal, there was
+no selection.
+
+\wxheading{Parameters}
+
+\docparam{from}{The returned first position.}
+
+\docparam{to}{The returned last position.}
+
 \membersection{wxTextCtrl::GetValue}\label{wxtextctrlgetvalue}
 
 \constfunc{wxString}{GetValue}{\void}
@@ -338,6 +404,13 @@ parameter).
 y values, so (x,y) = PositionToXY() is equivalent to the call described
 above.}
 
+\membersection{wxTextCtrl::Redo}\label{wxtextctrlredo}
+
+\func{virtual void}{Redo}{\void}
+
+If there is a redo facility and the last operation can be redone, redoes the last operation. Does nothing
+if there is no redo facility.
+
 \membersection{wxTextCtrl::Remove}\label{wxtextctrlremove}
 
 \func{virtual void}{Remove}{\param{long}{ from}, \param{long}{ to}}
@@ -440,6 +513,13 @@ Makes the line containing the given position visible.
 
 \docparam{pos}{The position that should be visible.}
 
+\membersection{wxTextCtrl::Undo}\label{wxtextctrlundo}
+
+\func{virtual void}{Undo}{\void}
+
+If there is an undo facility and the last operation can be undone, undoes the last operation. Does nothing
+if there is no undo facility.
+
 \membersection{wxTextCtrl::WriteText}\label{wxtextctrlwritetext}
 
 \func{void}{WriteText}{\param{const wxString\& }{ text}}
@@ -458,25 +538,6 @@ line breaks.  See \helpref{wxTextCtrl::\cinsert}{wxtextctrlinsert} and \helpref{
 
 After the write operation, the insertion point will be at the end of the inserted text, so subsequent write operations will be appended. To append text after the user may have interacted with the control, call \helpref{wxTextCtrl::SetInsertionPointEnd}{wxtextctrlsetinsertionpointend} before writing.
 
-\membersection{wxTextCtrl::AppendText}\label{wxtextctrlappendtext}
-
-\func{void}{AppendText}{\param{const wxString\& }{ text}}
-
-Appends the text to the end of the text control.
-
-\wxheading{Parameters}
-
-\docparam{text}{Text to write to the text control.}
-
-\wxheading{Remarks}
-
-After the text is appended, the insertion point will be at the end of the text control. If this behaviour is not desired,
-the programmer should use \helpref{GetInsertionPoint}{wxtextctrlgetinsertionpoint} and \helpref{SetInsertionPoint}{wxtextctrlsetinsertionpoint}.
-
-\wxheading{See also}
-
-\helpref{wxTextCtrl::WriteText}{wxtextctrlwritetext}
-
 \membersection{wxTextCtrl::XYToPosition}\label{wxtextctrlxytoposition}
 
 \func{long}{XYToPosition}{\param{long}{ x}, \param{long}{ y}}
diff --git a/include/wx/generic/notebook.h b/include/wx/generic/notebook.h
index 99fb13d1ad..fe6d8c82de 100644
--- a/include/wx/generic/notebook.h
+++ b/include/wx/generic/notebook.h
@@ -149,6 +149,9 @@ public:
     // set the padding between tabs (in pixels)
   void SetPadding(const wxSize& padding);
 
+    // Sets the size of the tabs (assumes all tabs are the same size)
+  void SetTabSize(const wxSize& sz);
+
   // operations
   // ----------
     // remove one page from the notebook, and delete the page.
diff --git a/include/wx/gtk/notebook.h b/include/wx/gtk/notebook.h
index 97c86e7ee9..34e2906a9c 100644
--- a/include/wx/gtk/notebook.h
+++ b/include/wx/gtk/notebook.h
@@ -134,6 +134,9 @@ public:
     // set the padding between tabs (in pixels)
   void SetPadding(const wxSize& padding);
 
+    // Sets the size of the tabs (assumes all tabs are the same size)
+  void SetTabSize(const wxSize& sz);
+
   // operations
   // ----------
     // remove one page from the notebook but do not destroy it
diff --git a/include/wx/gtk/textctrl.h b/include/wx/gtk/textctrl.h
index fcc1be71f3..2512ce42c1 100644
--- a/include/wx/gtk/textctrl.h
+++ b/include/wx/gtk/textctrl.h
@@ -100,6 +100,22 @@ class wxTextCtrl: public wxControl
     void Paste();
     void Clear();
 
+    virtual bool CanCopy() const;
+    virtual bool CanCut() const;
+    virtual bool CanPaste() const;
+
+    // Undo/redo
+    virtual void Undo();
+    virtual void Redo();
+
+    virtual bool CanUndo() const;
+    virtual bool CanRedo() const;
+
+    // If the return values from and to are the same, there is no
+    // selection.
+    virtual void GetSelection(long* from, long* to) const;
+    virtual bool IsEditable() const ;
+
     void OnChar( wxKeyEvent &event );
 
 #ifndef NO_TEXT_WINDOW_STREAM
diff --git a/include/wx/gtk1/notebook.h b/include/wx/gtk1/notebook.h
index 97c86e7ee9..34e2906a9c 100644
--- a/include/wx/gtk1/notebook.h
+++ b/include/wx/gtk1/notebook.h
@@ -134,6 +134,9 @@ public:
     // set the padding between tabs (in pixels)
   void SetPadding(const wxSize& padding);
 
+    // Sets the size of the tabs (assumes all tabs are the same size)
+  void SetTabSize(const wxSize& sz);
+
   // operations
   // ----------
     // remove one page from the notebook but do not destroy it
diff --git a/include/wx/gtk1/textctrl.h b/include/wx/gtk1/textctrl.h
index fcc1be71f3..2512ce42c1 100644
--- a/include/wx/gtk1/textctrl.h
+++ b/include/wx/gtk1/textctrl.h
@@ -100,6 +100,22 @@ class wxTextCtrl: public wxControl
     void Paste();
     void Clear();
 
+    virtual bool CanCopy() const;
+    virtual bool CanCut() const;
+    virtual bool CanPaste() const;
+
+    // Undo/redo
+    virtual void Undo();
+    virtual void Redo();
+
+    virtual bool CanUndo() const;
+    virtual bool CanRedo() const;
+
+    // If the return values from and to are the same, there is no
+    // selection.
+    virtual void GetSelection(long* from, long* to) const;
+    virtual bool IsEditable() const ;
+
     void OnChar( wxKeyEvent &event );
 
 #ifndef NO_TEXT_WINDOW_STREAM
diff --git a/include/wx/motif/textctrl.h b/include/wx/motif/textctrl.h
index 091f5e6763..6622976caf 100644
--- a/include/wx/motif/textctrl.h
+++ b/include/wx/motif/textctrl.h
@@ -77,6 +77,16 @@ public:
     virtual void Copy();
     virtual void Cut();
     virtual void Paste();
+    virtual bool CanCopy() const;
+    virtual bool CanCut() const;
+    virtual bool CanPaste() const;
+
+    // Undo/redo
+    virtual void Undo();
+    virtual void Redo();
+
+    virtual bool CanUndo() const;
+    virtual bool CanRedo() const;
 
     virtual void SetInsertionPoint(long pos);
     virtual void SetInsertionPointEnd();
@@ -86,6 +96,10 @@ public:
     virtual void Remove(long from, long to);
     virtual void SetSelection(long from, long to);
     virtual void SetEditable(bool editable);
+    // If the return values from and to are the same, there is no
+    // selection.
+    virtual void GetSelection(long* from, long* to) const;
+    virtual bool IsEditable() const ;
 
     // streambuf implementation
 #ifndef NO_TEXT_WINDOW_STREAM
diff --git a/include/wx/msw/textctrl.h b/include/wx/msw/textctrl.h
index 1e47cb7547..142ee8ba49 100644
--- a/include/wx/msw/textctrl.h
+++ b/include/wx/msw/textctrl.h
@@ -93,6 +93,17 @@ public:
     virtual void Cut();
     virtual void Paste();
 
+    virtual bool CanCopy() const;
+    virtual bool CanCut() const;
+    virtual bool CanPaste() const;
+
+    // Undo/redo
+    virtual void Undo();
+    virtual void Redo();
+
+    virtual bool CanUndo() const;
+    virtual bool CanRedo() const;
+
     virtual void SetInsertionPoint(long pos);
     virtual void SetInsertionPointEnd();
     virtual long GetInsertionPoint() const ;
@@ -102,6 +113,11 @@ public:
     virtual void SetSelection(long from, long to);
     virtual void SetEditable(bool editable);
 
+    // If the return values from and to are the same, there is no
+    // selection.
+    virtual void GetSelection(long* from, long* to) const;
+    virtual bool IsEditable() const ;
+
     // streambuf implementation
 #ifndef NO_TEXT_WINDOW_STREAM
     int overflow(int i);
diff --git a/include/wx/stubs/notebook.h b/include/wx/stubs/notebook.h
index 83f8c1ce4e..18b0793da2 100644
--- a/include/wx/stubs/notebook.h
+++ b/include/wx/stubs/notebook.h
@@ -128,6 +128,9 @@ public:
     // set the padding between tabs (in pixels)
   void SetPadding(const wxSize& padding);
 
+    // Sets the size of the tabs (assumes all tabs are the same size)
+  void SetTabSize(const wxSize& sz);
+
   // operations
   // ----------
     // remove one page from the notebook
diff --git a/include/wx/stubs/textctrl.h b/include/wx/stubs/textctrl.h
index 675e21bb3f..0834e1a43b 100644
--- a/include/wx/stubs/textctrl.h
+++ b/include/wx/stubs/textctrl.h
@@ -85,6 +85,17 @@ public:
   virtual void Cut();
   virtual void Paste();
   
+  virtual bool CanCopy() const;
+  virtual bool CanCut() const;
+  virtual bool CanPaste() const;
+
+  // Undo/redo
+  virtual void Undo();
+  virtual void Redo();
+
+  virtual bool CanUndo() const;
+  virtual bool CanRedo() const;
+
   virtual void SetInsertionPoint(long pos);
   virtual void SetInsertionPointEnd();
   virtual long GetInsertionPoint() const ;
@@ -93,7 +104,12 @@ public:
   virtual void Remove(long from, long to);
   virtual void SetSelection(long from, long to);
   virtual void SetEditable(bool editable);
-  
+
+  // If the return values from and to are the same, there is no
+  // selection.
+  virtual void GetSelection(long* from, long* to) const;
+  virtual bool IsEditable() const ;
+
   // streambuf implementation
 #ifndef NO_TEXT_WINDOW_STREAM
   int overflow(int i);
diff --git a/src/generic/notebook.cpp b/src/generic/notebook.cpp
index 3be3cd9634..90782f4545 100644
--- a/src/generic/notebook.cpp
+++ b/src/generic/notebook.cpp
@@ -601,6 +601,11 @@ wxRect wxNotebook::GetAvailableClientSize()
     return rect;
 }
 
+void wxNotebook::SetTabSize(const wxSize& sz)
+{
+    // TODO
+}
+
 /*
  * wxNotebookTabView
  */
diff --git a/src/gtk/notebook.cpp b/src/gtk/notebook.cpp
index 96be1af67e..ea57e8c433 100644
--- a/src/gtk/notebook.cpp
+++ b/src/gtk/notebook.cpp
@@ -509,6 +509,11 @@ void wxNotebook::SetPadding( const wxSize &WXUNUSED(padding) )
     wxFAIL_MSG( "wxNotebook::SetPadding not implemented" );
 }
 
+void wxNotebook::SetTabSize(const wxSize& sz)
+{
+    wxFAIL_MSG( "wxNotebook::SetTabSize not implemented" );
+}
+
 bool wxNotebook::DeleteAllPages()
 {
     wxCHECK_MSG( m_widget != NULL, FALSE, "invalid notebook" );
diff --git a/src/gtk/textctrl.cpp b/src/gtk/textctrl.cpp
index 94e4126e60..4da56a23e5 100644
--- a/src/gtk/textctrl.cpp
+++ b/src/gtk/textctrl.cpp
@@ -703,6 +703,71 @@ void wxTextCtrl::Paste()
 #endif
 }
 
+bool wxTextCtrl::CanCopy() const
+{
+    // Can copy if there's a selection
+    long from, to;
+    GetSelection(& from, & to);
+    return (from != to) ;
+}
+
+bool wxTextCtrl::CanCut() const
+{
+    // Can cut if there's a selection
+    long from, to;
+    GetSelection(& from, & to);
+    return (from != to) ;
+}
+
+bool wxTextCtrl::CanPaste() const
+{
+    return IsEditable() ;
+}
+
+// Undo/redo
+void wxTextCtrl::Undo()
+{
+    // TODO
+    wxFAIL_MSG( "wxTextCtrl::Undo not implemented" );
+}
+
+void wxTextCtrl::Redo()
+{
+    // TODO
+    wxFAIL_MSG( "wxTextCtrl::Redo not implemented" );
+}
+
+bool wxTextCtrl::CanUndo() const
+{
+    // TODO
+    wxFAIL_MSG( "wxTextCtrl::CanUndo not implemented" );
+    return FALSE;
+}
+
+bool wxTextCtrl::CanRedo() const
+{
+    // TODO
+    wxFAIL_MSG( "wxTextCtrl::CanRedo not implemented" );
+    return FALSE;
+}
+
+// If the return values from and to are the same, there is no
+// selection.
+void wxTextCtrl::GetSelection(long* from, long* to) const
+{
+    // TODO
+    *from = 0;
+    *to = 0;
+    wxFAIL_MSG( "wxTextCtrl::GetSelection not implemented" );
+}
+
+bool wxTextCtrl::IsEditable() const
+{
+    // TODO
+    wxFAIL_MSG( "wxTextCtrl::IsEditable not implemented" );
+    return FALSE;
+}
+
 void wxTextCtrl::Clear()
 {
     SetValue( "" );
diff --git a/src/gtk1/notebook.cpp b/src/gtk1/notebook.cpp
index 96be1af67e..ea57e8c433 100644
--- a/src/gtk1/notebook.cpp
+++ b/src/gtk1/notebook.cpp
@@ -509,6 +509,11 @@ void wxNotebook::SetPadding( const wxSize &WXUNUSED(padding) )
     wxFAIL_MSG( "wxNotebook::SetPadding not implemented" );
 }
 
+void wxNotebook::SetTabSize(const wxSize& sz)
+{
+    wxFAIL_MSG( "wxNotebook::SetTabSize not implemented" );
+}
+
 bool wxNotebook::DeleteAllPages()
 {
     wxCHECK_MSG( m_widget != NULL, FALSE, "invalid notebook" );
diff --git a/src/gtk1/textctrl.cpp b/src/gtk1/textctrl.cpp
index 94e4126e60..4da56a23e5 100644
--- a/src/gtk1/textctrl.cpp
+++ b/src/gtk1/textctrl.cpp
@@ -703,6 +703,71 @@ void wxTextCtrl::Paste()
 #endif
 }
 
+bool wxTextCtrl::CanCopy() const
+{
+    // Can copy if there's a selection
+    long from, to;
+    GetSelection(& from, & to);
+    return (from != to) ;
+}
+
+bool wxTextCtrl::CanCut() const
+{
+    // Can cut if there's a selection
+    long from, to;
+    GetSelection(& from, & to);
+    return (from != to) ;
+}
+
+bool wxTextCtrl::CanPaste() const
+{
+    return IsEditable() ;
+}
+
+// Undo/redo
+void wxTextCtrl::Undo()
+{
+    // TODO
+    wxFAIL_MSG( "wxTextCtrl::Undo not implemented" );
+}
+
+void wxTextCtrl::Redo()
+{
+    // TODO
+    wxFAIL_MSG( "wxTextCtrl::Redo not implemented" );
+}
+
+bool wxTextCtrl::CanUndo() const
+{
+    // TODO
+    wxFAIL_MSG( "wxTextCtrl::CanUndo not implemented" );
+    return FALSE;
+}
+
+bool wxTextCtrl::CanRedo() const
+{
+    // TODO
+    wxFAIL_MSG( "wxTextCtrl::CanRedo not implemented" );
+    return FALSE;
+}
+
+// If the return values from and to are the same, there is no
+// selection.
+void wxTextCtrl::GetSelection(long* from, long* to) const
+{
+    // TODO
+    *from = 0;
+    *to = 0;
+    wxFAIL_MSG( "wxTextCtrl::GetSelection not implemented" );
+}
+
+bool wxTextCtrl::IsEditable() const
+{
+    // TODO
+    wxFAIL_MSG( "wxTextCtrl::IsEditable not implemented" );
+    return FALSE;
+}
+
 void wxTextCtrl::Clear()
 {
     SetValue( "" );
diff --git a/src/motif/textctrl.cpp b/src/motif/textctrl.cpp
index b84167773a..a9ae3f9b0a 100644
--- a/src/motif/textctrl.cpp
+++ b/src/motif/textctrl.cpp
@@ -245,6 +245,67 @@ void wxTextCtrl::Paste()
     XmTextPaste((Widget) m_mainWidget);
 }
 
+bool wxTextCtrl::CanCopy() const
+{
+    // Can copy if there's a selection
+    long from, to;
+    GetSelection(& from, & to);
+    return (from != to) ;
+}
+
+bool wxTextCtrl::CanCut() const
+{
+    // Can cut if there's a selection
+    long from, to;
+    GetSelection(& from, & to);
+    return (from != to) ;
+}
+
+bool wxTextCtrl::CanPaste() const
+{
+    return IsEditable() ;
+}
+
+// Undo/redo
+void wxTextCtrl::Undo()
+{
+    // Not possible in Motif
+}
+
+void wxTextCtrl::Redo()
+{
+    // Not possible in Motif
+}
+
+bool wxTextCtrl::CanUndo() const
+{
+    // No Undo in Motif
+    return FALSE;
+}
+
+bool wxTextCtrl::CanRedo() const
+{
+    // No Redo in Motif
+    return FALSE;
+}
+
+// If the return values from and to are the same, there is no
+// selection.
+void wxTextCtrl::GetSelection(long* from, long* to) const
+{
+    XmTextPosition left, right;
+
+    XmTextGetSelectionPosition((Widget) m_mainWidget, & left, & right);
+
+    *from = (long) left;
+    *to = (long) right;
+}
+
+bool wxTextCtrl::IsEditable() const
+{
+    return (XmTextGetEditable((Widget) m_mainWidget) != 0);
+}
+
 void wxTextCtrl::SetEditable(bool editable)
 {
     XmTextSetEditable((Widget) m_mainWidget, (Boolean) editable);
diff --git a/src/msw/textctrl.cpp b/src/msw/textctrl.cpp
index 9d5a411fdb..d08a18f028 100644
--- a/src/msw/textctrl.cpp
+++ b/src/msw/textctrl.cpp
@@ -729,9 +729,87 @@ wxString wxTextCtrl::GetLineText(long lineNo) const
   return wxString(wxBuffer);
 }
 
-/*
- * Text item
- */
+bool wxTextCtrl::CanCopy() const
+{
+    // Can copy if there's a selection
+    long from, to;
+    GetSelection(& from, & to);
+    return (from != to) ;
+}
+
+bool wxTextCtrl::CanCut() const
+{
+    // Can cut if there's a selection
+    long from, to;
+    GetSelection(& from, & to);
+    return (from != to) ;
+}
+
+bool wxTextCtrl::CanPaste() const
+{
+    int dataFormat = 0; // 0 == any format
+    return (::SendMessage( (HWND) GetHWND(), EM_CANPASTE, (WPARAM) (UINT) dataFormat, 0) != 0);
+}
+
+// Undo/redo
+void wxTextCtrl::Undo()
+{
+    if (CanUndo())
+    {
+        ::SendMessage((HWND) GetHWND(), EM_UNDO, 0, 0);
+    }
+}
+
+void wxTextCtrl::Redo()
+{
+    if (CanRedo())
+    {
+        // Same as Undo, since Undo undoes the undo, i.e. a redo.
+        ::SendMessage((HWND) GetHWND(), EM_UNDO, 0, 0);
+    }
+}
+
+bool wxTextCtrl::CanUndo() const
+{
+    return (::SendMessage((HWND) GetHWND(), EM_CANUNDO, 0, 0) != 0);
+}
+
+bool wxTextCtrl::CanRedo() const
+{
+    return (::SendMessage((HWND) GetHWND(), EM_CANUNDO, 0, 0) != 0);
+}
+
+// If the return values from and to are the same, there is no
+// selection.
+void wxTextCtrl::GetSelection(long* from, long* to) const
+{
+#if wxUSE_RICHEDIT
+    if (m_isRich)
+    {
+        CHARRANGE charRange;
+        ::SendMessage((HWND) GetHWND(), EM_EXGETSEL, 0, (LPARAM) (CHARRANGE*) & charRange);
+
+        *from = charRange.cpMin;
+        *to = charRange.cpMax;
+
+        return;
+    }
+#endif
+    DWORD dwStart, dwEnd;
+    WPARAM wParam = (WPARAM) (DWORD*) dwStart; // receives starting position
+    LPARAM lParam = (LPARAM) (DWORD*) dwEnd;   // receives ending position
+
+    ::SendMessage((HWND) GetHWND(), EM_GETSEL, wParam, lParam);
+
+    *from = dwStart;
+    *to = dwEnd;
+}
+
+bool wxTextCtrl::IsEditable() const
+{
+    long style = ::GetWindowLong((HWND) GetHWND(), GWL_STYLE);
+    return ((style & ES_READONLY) == 0);
+}
 
 void wxTextCtrl::Command(wxCommandEvent & event)
 {
diff --git a/src/stubs/notebook.cpp b/src/stubs/notebook.cpp
index 312dd0f3d3..f7ee49cd5d 100644
--- a/src/stubs/notebook.cpp
+++ b/src/stubs/notebook.cpp
@@ -375,3 +375,8 @@ void wxNotebook::ChangePage(int nOldSel, int nSel)
     m_nSelection = nSel;
 }
 
+void wxNotebook::SetTabSize(const wxSize& sz)
+{
+    // TODO
+}
+
diff --git a/src/stubs/textctrl.cpp b/src/stubs/textctrl.cpp
index a9ede8a5a4..a43a38acc9 100644
--- a/src/stubs/textctrl.cpp
+++ b/src/stubs/textctrl.cpp
@@ -267,10 +267,65 @@ wxString wxTextCtrl::GetLineText(long lineNo) const
     return wxString("");
 }
 
-/*
- * Text item
- */
- 
+bool wxTextCtrl::CanCopy() const
+{
+    // Can copy if there's a selection
+    long from, to;
+    GetSelection(& from, & to);
+    return (from != to) ;
+}
+
+bool wxTextCtrl::CanCut() const
+{
+    // Can cut if there's a selection
+    long from, to;
+    GetSelection(& from, & to);
+    return (from != to) ;
+}
+
+bool wxTextCtrl::CanPaste() const
+{
+    return IsEditable() ;
+}
+
+// Undo/redo
+void wxTextCtrl::Undo()
+{
+    // TODO
+}
+
+void wxTextCtrl::Redo()
+{
+    // TODO
+}
+
+bool wxTextCtrl::CanUndo() const
+{
+    // TODO
+    return FALSE;
+}
+
+bool wxTextCtrl::CanRedo() const
+{
+    // TODO
+    return FALSE;
+}
+
+// If the return values from and to are the same, there is no
+// selection.
+void wxTextCtrl::GetSelection(long* from, long* to) const
+{
+    // TODO
+    *from = 0;
+    *to = 0;
+}
+
+bool wxTextCtrl::IsEditable() const
+{
+    // TODO
+    return FALSE;
+}
+
 void wxTextCtrl::Command(wxCommandEvent & event)
 {
     SetValue (event.GetString());
-- 
2.50.0

