From d73e6791fc93a590630b6deb918a6518b91ea142 Mon Sep 17 00:00:00 2001
From: Vadim Zeitlin <vadim@wxwidgets.org>
Date: Fri, 19 Oct 2001 16:27:15 +0000
Subject: [PATCH] added wxStreamToTextRedirector

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@12088 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
---
 docs/changes.txt           |  6 +++
 docs/latex/wx/classes.tex  |  1 +
 docs/latex/wx/strtotxt.tex | 76 ++++++++++++++++++++++++++++++++++++++
 docs/latex/wx/text.tex     | 71 ++++++++++++++++++++++++++++-------
 include/wx/textctrl.h      | 53 +++++++++++++++++---------
 src/common/textcmn.cpp     | 41 ++------------------
 6 files changed, 179 insertions(+), 69 deletions(-)
 create mode 100644 docs/latex/wx/strtotxt.tex

diff --git a/docs/changes.txt b/docs/changes.txt
index 5869c3091b..c3636a97f2 100644
--- a/docs/changes.txt
+++ b/docs/changes.txt
@@ -4,6 +4,11 @@ wxWindows 2 Change Log
 INCOMPATIBLE CHANGES SINCE 2.2.x
 ================================
 
+All (GUI):
+
+- wxGridCellAttrProvider class API changed, you will need to update your code
+  if you derived any classes from it
+
 wxMSW:
 
 - child frames appear in the taskbar by default now, use wxFRAME_NO_TASKBAR
@@ -27,6 +32,7 @@ All (GUI):
 - wxFindReplaceDialog added (based on work of Markus Greither)
 - wxTextCtrl::SetMaxLength() added (wxMSW/wxGTK)
 - polygon support in wxRegion (Klaas Holwerda)
+- wxStreamToTextRedirector to allow easily redirect cout to wxTextCtrl added
 - fixed bug with using wxExecute() to capture huge amounts of output
 
 wxHTML:
diff --git a/docs/latex/wx/classes.tex b/docs/latex/wx/classes.tex
index 989007a828..550913a5eb 100644
--- a/docs/latex/wx/classes.tex
+++ b/docs/latex/wx/classes.tex
@@ -279,6 +279,7 @@
 \input stopwtch.tex
 \input strmbase.tex
 \input stream.tex
+\input strtotxt.tex
 \input wxstring.tex
 \input propstfv.tex
 \input strlist.tex
diff --git a/docs/latex/wx/strtotxt.tex b/docs/latex/wx/strtotxt.tex
new file mode 100644
index 0000000000..33c051c593
--- /dev/null
+++ b/docs/latex/wx/strtotxt.tex
@@ -0,0 +1,76 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Name:        strtotxt.tex
+%% Purpose:     wxStreamToTextRedirector documentation
+%% Author:      Vadim Zeitlin
+%% Modified by:
+%% Created:     19.10.01
+%% RCS-ID:      $Id$
+%% Copyright:   (c) 2001 Vadim Zeitlin <vadim@wxwindows.org>
+%% License:     wxWindows license
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\section{\class{wxStreamToTextRedirector}}\label{wxstreamtotextredirector}
+
+This class can be used to (temporarily) redirect all output sent to a C++
+ostream object to a \helpref{wxTextCtrl}{wxtextctrl} instead.
+
+{\bf NB:} Some compilers and/or build configurations don't support multiply
+inheriting \helpref{wxTextCtrl}{wxtextctrl} from {\tt std::streambuf} in which
+case this class is not compiled in. You also must have {\tt wxUSE\_STD\_IOSTREAM} 
+option on (i.e. set to $1$) in your setup.h to be able to use it. Under Unix,
+specify {\tt --enable-std\_iostreams} switch when running configure for this.
+
+Example of usage:
+{\small%
+\begin{verbatim}
+  using namespace std;
+
+  wxTextCtrl *text = new wxTextCtrl(...);
+
+  {
+    wxStreamToTextRedirector redirect(text);
+
+    // this goes to the text control
+    cout << "Hello, text!" << endl;
+  }
+
+  // this goes soemwhere else, presumably to stdout
+  cout << "Hello, console!" << endl;
+\end{verbatim}
+}%
+
+\wxheading{Derived from}
+
+No base class
+
+\wxheading{Include files}
+
+<wx/textctrl.h>
+
+\wxheading{See also}
+
+\helpref{wxTextCtrl}{wxtextctrl}
+
+\latexignore{\rtfignore{\wxheading{Members}}}
+
+\membersection{wxStreamToTextRedirector::wxStreamToTextRedirector}\label{wxstreamtotextredirectorctor}
+
+\func{}{wxStreamToTextRedirector}{\param{wxTextCtrl }{*text}, \param{ostream *ostr = NULL}}
+
+The constructor starts redirecting output sent to {\it ostr} or {\it cout} for
+the default parameter value to the text control {\it text}.
+
+\wxheading{Parameters}
+
+\docparam{text}{The text control to append output too, must be non NULL}
+
+\docparam{ostr}{The C++ stream to redirect, {\it cout} is used if it is NULL}
+
+\membersection{wxStreamToTextRedirector::\destruct{wxStreamToTextRedirector}}
+
+\func{}{\destruct{wxStreamToTextRedirector}}{\void}
+
+When a wxStreamToTextRedirector object is destroyed, the redirection is ended
+and any output sent to the C++ ostream which had been specified at the time of
+the object construction will go to its original destination.
+
diff --git a/docs/latex/wx/text.tex b/docs/latex/wx/text.tex
index 529a451b79..8d26a475c3 100644
--- a/docs/latex/wx/text.tex
+++ b/docs/latex/wx/text.tex
@@ -45,10 +45,10 @@ it to always show it. It doesn't do anything under other platforms.}
 See also \helpref{window styles overview}{windowstyles} and 
 \helpref{wxTextCtrl::wxTextCtrl}{wxtextctrlconstr}.
 
-\wxheading{Remarks}
+\wxheading{wxTextCtrl and C++ streams}
 
-This class multiply-inherits from {\bf streambuf} where compilers allow, allowing code such as 
-the following:
+This class multiply-inherits from {\bf streambuf} where compilers allow,
+allowing code such as the following:
 
 {\small%
 \begin{verbatim}
@@ -61,13 +61,62 @@ the following:
 \end{verbatim}
 }%
 
-If your compiler does not support derivation from {\bf streambuf} and gives a compile error, define the symbol 
-{\bf NO\_TEXT\_WINDOW\_STREAM} in the wxTextCtrl header file.
+If your compiler does not support derivation from {\bf streambuf} and gives a
+compile error, define the symbol {\bf NO\_TEXT\_WINDOW\_STREAM} in the
+wxTextCtrl header file.
+
+Note that independently of this setting you can always use wxTextCtrl itself
+in a stream-like manner:
+
+{\small%
+\begin{verbatim}
+  wxTextCtrl *control = new wxTextCtrl(...);
+
+  *control << 123.456 << " some text\n";
+\end{verbatim}
+}%
+
+always works. However the possibility to create an ostream associated with
+wxTextCtrl may be useful if you need to redirect the output of a function
+taking an ostream as parameter to a text control.
+
+Another commonly requested need is to redirect {\bf std::cout} to the text
+control. This could be done in the following way:
+
+{\small%
+\begin{verbatim}
+  #include <iostream>
+
+  wxTextCtrl *control = new wxTextCtrl(...);
+
+  std::streambuf *sbOld = std::cout.rdbuf();
+  std::cout.rdbuf(*control);
+
+  // use cout as usual, the output appears in the text control
+  ...
+
+  std::cout.rdbuf(sbOld);
+\end{verbatim}
+}%
+
+But wxWindows provides a convenient class to make it even simpler so instead
+you may just do
+
+{\small%
+\begin{verbatim}
+  #include <iostream>
+
+  wxTextCtrl *control = new wxTextCtrl(...);
+
+  wxStreamToTextRedirector redirect(control);
+
+  // all output to cout goes into the text control until the exit from current
+  // scope
+\end{verbatim}
+}%
 
-% VZ: it is wrong to say that C++ iostreams are deprecated, we need a better
-%     wording here - disabling this for now
-%Note that any use of C++ iostreams (including this one) is deprecated and might
-%get completely removed in the future.
+See \helpref{wxStreamToTextRedirector}{wxstreamtotextredirector} for more
+details.
 
 \wxheading{Event handling}
 
@@ -93,10 +142,6 @@ into the control than the limit set by
 \helpref{SetMaxLength}{wxtextctrlsetmaxlength}.}
 \end{twocollist}%
 
-%\wxheading{See also}
-%
-%\helpref{wxRichTextCtrl}{wxrichtextctrl}
-%
 \latexignore{\rtfignore{\wxheading{Members}}}
 
 \membersection{wxTextCtrl::wxTextCtrl}\label{wxtextctrlconstr}
diff --git a/include/wx/textctrl.h b/include/wx/textctrl.h
index fe3046b45c..9ed802bd35 100644
--- a/include/wx/textctrl.h
+++ b/include/wx/textctrl.h
@@ -30,14 +30,8 @@
 // and streambuf: it complains about deriving a huge class from the huge class
 // streambuf. !! Also, can't use streambuf if making or using a DLL :-(
 
-#if (defined(__BORLANDC__)) || defined(__MWERKS__) || defined(_WINDLL) || defined(WXUSINGDLL) || defined(WXMAKINGDLL)
-    #define NO_TEXT_WINDOW_STREAM
-#endif
-
-// the streambuf which is used in the declaration of wxTextCtrlBase below is not compatible
-// with the standard-conforming implementation found in newer egcs versions
-// (that is, the libstdc++ v3 that is shipped with it)
-#if defined(__GNUC__)&&( (__GNUC__>2) ||( (__GNUC__==2)&&(__GNUC_MINOR__>97) ) )
+#if (defined(__BORLANDC__)) || defined(__MWERKS__) || \
+    defined(WXUSINGDLL) || defined(WXMAKINGDLL)
     #define NO_TEXT_WINDOW_STREAM
 #endif
 
@@ -228,11 +222,9 @@ public:
     virtual void SelectAll();
     virtual void SetEditable(bool editable) = 0;
 
-    // streambuf methods
+    // override streambuf method
 #ifndef NO_TEXT_WINDOW_STREAM
     int overflow(int i);
-    int sync();
-    int underflow();
 #endif // NO_TEXT_WINDOW_STREAM
 
     // stream-like insertion operators: these are always available, whether we
@@ -256,13 +248,6 @@ protected:
 
     // the text style which will be used for any new text added to the control
     wxTextAttr m_defaultStyle;
-
-private:
-#ifndef NO_TEXT_WINDOW_STREAM
-#if !wxUSE_IOSTREAMH
-    char *m_streambuf;
-#endif
-#endif
 };
 
 // ----------------------------------------------------------------------------
@@ -341,6 +326,38 @@ typedef void (wxEvtHandler::*wxTextUrlEventFunction)(wxTextUrlEvent&);
 #define EVT_TEXT_URL(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_COMMAND_TEXT_URL, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) (wxTextUrlEventFunction) & fn, (wxObject *) NULL ),
 #define EVT_TEXT_MAXLEN(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_COMMAND_TEXT_MAXLEN, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) & fn, (wxObject *) NULL ),
 
+#ifndef NO_TEXT_WINDOW_STREAM
+
+// ----------------------------------------------------------------------------
+// wxStreamToTextRedirector: this class redirects all data sent to the given
+// C++ stream to the wxTextCtrl given to its ctor during its lifetime.
+// ----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxStreamToTextRedirector
+{
+public:
+    wxStreamToTextRedirector(wxTextCtrl *text, wxSTD ostream *ostr = NULL)
+        : m_ostr(ostr ? *ostr : wxSTD::cout)
+    {
+        m_sbufOld = m_ostr.rdbuf();
+        m_ostr.rdbuf(text);
+    }
+
+    ~wxStreamToTextRedirector()
+    {
+        m_ostr.rdbuf(m_sbufOld);
+    }
+
+private:
+    // the stream we're redirecting
+    wxSTD ostream&   m_ostr;
+
+    // the old streambuf (before we changed it)
+    wxSTD streambuf *m_sbufOld;
+};
+
+#endif // !NO_TEXT_WINDOW_STREAM
+
 #endif // wxUSE_TEXTCTRL
 
 #endif
diff --git a/src/common/textcmn.cpp b/src/common/textcmn.cpp
index 7ced7d2de5..b2e57eb854 100644
--- a/src/common/textcmn.cpp
+++ b/src/common/textcmn.cpp
@@ -59,24 +59,10 @@ DEFINE_EVENT_TYPE(wxEVT_COMMAND_TEXT_MAXLEN)
 
 wxTextCtrlBase::wxTextCtrlBase()
 {
-#ifndef NO_TEXT_WINDOW_STREAM
-    #if wxUSE_IOSTREAMH
-        if (allocate())
-            setp(base(),ebuf());
-    #else
-        m_streambuf = new char[64];
-        setp(m_streambuf, m_streambuf + 64);
-    #endif //wxUSE_IOSTREAMH
-#endif // NO_TEXT_WINDOW_STREAM
 }
 
 wxTextCtrlBase::~wxTextCtrlBase()
 {
-#ifndef NO_TEXT_WINDOW_STREAM
-#if !wxUSE_IOSTREAMH
-  delete[] m_streambuf;
-#endif
-#endif
 }
 
 // ----------------------------------------------------------------------------
@@ -215,35 +201,14 @@ wxTextCtrl& wxTextCtrlBase::operator<<(const wxChar c)
 
 #ifndef NO_TEXT_WINDOW_STREAM
 
-int wxTextCtrlBase::overflow( int WXUNUSED(c) )
+int wxTextCtrlBase::overflow(int c)
 {
-    int len = pptr() - pbase();
-    char *txt = new char[len+1];
-    strncpy(txt, pbase(), len);
-    txt[len] = '\0';
-    (*this) << txt;
-    setp(pbase(), epptr());
-    delete[] txt;
-    return EOF;
-}
+    AppendText((wxChar)c);
 
-int wxTextCtrlBase::sync()
-{
-    int len = pptr() - pbase();
-    char *txt = new char[len+1];
-    strncpy(txt, pbase(), len);
-    txt[len] = '\0';
-    (*this) << txt;
-    setp(pbase(), epptr());
-    delete[] txt;
+    // return something different from EOF
     return 0;
 }
 
-int wxTextCtrlBase::underflow()
-{
-    return EOF;
-}
-
 #endif // NO_TEXT_WINDOW_STREAM
 
 // ----------------------------------------------------------------------------
-- 
2.50.0

