From d73e6791fc93a590630b6deb918a6518b91ea142 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin 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 +%% 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} + + + +\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 + + 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 + + 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.45.2