X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/4bb6408c2631988fab9925014c6619358bf867de..6ceeeafd563ff120631f3bb26ee2a2978a46d583:/src/motif/textctrl.cpp?ds=sidebyside diff --git a/src/motif/textctrl.cpp b/src/motif/textctrl.cpp index 6727160c89..f637e1fa42 100644 --- a/src/motif/textctrl.cpp +++ b/src/motif/textctrl.cpp @@ -1,438 +1,744 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: textctrl.cpp +// Name: src/motif/textctrl.cpp // Purpose: wxTextCtrl // Author: Julian Smart // Modified by: // Created: 17/09/98 // RCS-ID: $Id$ // Copyright: (c) Julian Smart -// Licence: wxWindows licence +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -#ifdef __GNUG__ -#pragma implementation "textctrl.h" -#endif +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" #include #include -#include +#include #include "wx/textctrl.h" -#include "wx/settings.h" + +#ifndef WX_PRECOMP + #include "wx/utils.h" + #include "wx/settings.h" +#endif + #include "wx/filefn.h" -#include "wx/utils.h" -#if defined(__BORLANDC__) && !defined(__WIN32__) -#include -#else -#ifndef __GNUWIN32__ -#include +#ifdef __VMS__ +#pragma message disable nosimpint #endif +#include +#ifdef __VMS__ +#pragma message enable nosimpint #endif -#if !USE_SHARED_LIBRARY -IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl, wxControl) +#include "wx/motif/private.h" -BEGIN_EVENT_TABLE(wxTextCtrl, wxControl) - EVT_DROP_FILES(wxTextCtrl::OnDropFiles) -END_EVENT_TABLE() -#endif +// ---------------------------------------------------------------------------- +// private functions +// ---------------------------------------------------------------------------- + +// helper: inserts the new text in the value of the text ctrl and returns the +// result in place +static void MergeChangesIntoString(wxString& value, + XmTextVerifyCallbackStruct *textStruct); + +// callbacks +static void wxTextWindowChangedProc(Widget w, XtPointer clientData, XtPointer ptr); +static void wxTextWindowModifyProc(Widget w, XtPointer clientData, XmTextVerifyCallbackStruct *cbs); +static void wxTextWindowGainFocusProc(Widget w, XtPointer clientData, XmAnyCallbackStruct *cbs); +static void wxTextWindowLoseFocusProc(Widget w, XtPointer clientData, XmAnyCallbackStruct *cbs); +static void wxTextWindowActivateProc(Widget w, XtPointer clientData, XmAnyCallbackStruct *ptr); + + BEGIN_EVENT_TABLE(wxTextCtrl, wxTextCtrlBase) + EVT_DROP_FILES(wxTextCtrl::OnDropFiles) + EVT_CHAR(wxTextCtrl::OnChar) + + EVT_MENU(wxID_CUT, wxTextCtrl::OnCut) + EVT_MENU(wxID_COPY, wxTextCtrl::OnCopy) + EVT_MENU(wxID_PASTE, wxTextCtrl::OnPaste) + EVT_MENU(wxID_UNDO, wxTextCtrl::OnUndo) + EVT_MENU(wxID_REDO, wxTextCtrl::OnRedo) + + EVT_UPDATE_UI(wxID_CUT, wxTextCtrl::OnUpdateCut) + EVT_UPDATE_UI(wxID_COPY, wxTextCtrl::OnUpdateCopy) + EVT_UPDATE_UI(wxID_PASTE, wxTextCtrl::OnUpdatePaste) + EVT_UPDATE_UI(wxID_UNDO, wxTextCtrl::OnUpdateUndo) + EVT_UPDATE_UI(wxID_REDO, wxTextCtrl::OnUpdateRedo) + + END_EVENT_TABLE() + +// ============================================================================ +// implementation +// ============================================================================ + +// ---------------------------------------------------------------------------- +// wxTextCtrl +// ---------------------------------------------------------------------------- // Text item wxTextCtrl::wxTextCtrl() -#ifndef NO_TEXT_WINDOW_STREAM - :streambuf() -#endif { - m_fileName = ""; + m_tempCallbackStruct = NULL; + m_modified = false; + m_processedDefault = false; +} + +bool wxTextCtrl::Create(wxWindow *parent, + wxWindowID id, + const wxString& value, + const wxPoint& pos, + const wxSize& size, + long style, + const wxValidator& validator, + const wxString& name) +{ + if( !CreateControl( parent, id, pos, size, style, validator, name ) ) + return false; + PreCreation(); + + m_tempCallbackStruct = NULL; + m_modified = false; + m_processedDefault = false; + + Widget parentWidget = (Widget) parent->GetClientWidget(); + + Bool wantHorizScroll = (m_windowStyle & wxHSCROLL) != 0 ? True : False; + // If we don't have horizontal scrollbars, we want word wrap. + // OpenMotif 2.1 crashes if wantWordWrap is True in Japanese + // locale (and probably other multibyte locales). The check might be + // more precise +#if wxCHECK_LESSTIF() || wxCHECK_MOTIF_VERSION( 2, 2 ) + Bool wantWordWrap = wantHorizScroll == True ? False : True; +#else + Bool wantWordWrap = False; +#endif + + if (m_windowStyle & wxTE_MULTILINE) + { + Arg args[8]; + int count = 0; + XtSetArg (args[count], XmNscrollHorizontal, wantHorizScroll); ++count; + if( m_font.IsOk() ) + XtSetArg (args[count], (String) wxFont::GetFontTag(), + m_font.GetFontType( XtDisplay(parentWidget) ) ); ++count; + XtSetArg (args[count], XmNwordWrap, wantWordWrap); ++count; + XtSetArg (args[count], XmNvalue, (const char*)value.mb_str()); ++count; + XtSetArg (args[count], XmNeditable, + style & wxTE_READONLY ? False : True); ++count; + XtSetArg (args[count], XmNeditMode, XmMULTI_LINE_EDIT ); ++count; + + m_mainWidget = + (WXWidget) XmCreateScrolledText(parentWidget, + name.char_str(), + args, count); + + XtManageChild ((Widget) m_mainWidget); + } + else + { + m_mainWidget = (WXWidget)XtVaCreateManagedWidget + ( + name.mb_str(), + xmTextWidgetClass, + parentWidget, + wxFont::GetFontTag(), m_font.GetFontType( XtDisplay(parentWidget) ), + XmNvalue, (const char*)value.mb_str(), + XmNeditable, (style & wxTE_READONLY) ? + False : True, + NULL + ); + +#if 0 + // TODO: Is this relevant? What does it do? + int noCols = 2; + if (!value.empty() && (value.length() > (unsigned int) noCols)) + noCols = value.length(); + XtVaSetValues((Widget) m_mainWidget, + XmNcolumns, noCols, + NULL); +#endif + } + + // remove border if asked for + if ( style & wxNO_BORDER ) + { + XtVaSetValues((Widget)m_mainWidget, + XmNshadowThickness, 0, + NULL); + } + + // install callbacks + XtAddCallback((Widget) m_mainWidget, XmNvalueChangedCallback, (XtCallbackProc)wxTextWindowChangedProc, (XtPointer)this); + + XtAddCallback((Widget) m_mainWidget, XmNmodifyVerifyCallback, (XtCallbackProc)wxTextWindowModifyProc, (XtPointer)this); + + XtAddCallback((Widget) m_mainWidget, XmNactivateCallback, (XtCallbackProc)wxTextWindowActivateProc, (XtPointer)this); + + XtAddCallback((Widget) m_mainWidget, XmNfocusCallback, (XtCallbackProc)wxTextWindowGainFocusProc, (XtPointer)this); + + XtAddCallback((Widget) m_mainWidget, XmNlosingFocusCallback, (XtCallbackProc)wxTextWindowLoseFocusProc, (XtPointer)this); + + PostCreation(); + AttachWidget (parent, m_mainWidget, (WXWidget) NULL, + pos.x, pos.y, size.x, size.y); + + return true; } -bool wxTextCtrl::Create(wxWindow *parent, wxWindowID id, - const wxString& value, - const wxPoint& pos, - const wxSize& size, long style, - const wxValidator& validator, - const wxString& name) +WXWidget wxTextCtrl::GetTopWidget() const { - m_fileName = ""; - SetName(name); - SetValidator(validator); - if (parent) parent->AddChild(this); + return IsMultiLine() ? (WXWidget)XtParent((Widget)m_mainWidget) + : m_mainWidget; +} - m_windowStyle = style; +wxString wxTextCtrl::GetValue() const +{ + wxString str; // result - if ( id == -1 ) - m_windowId = (int)NewControlId(); + if (m_windowStyle & wxTE_PASSWORD) + { + // the value is stored always in m_value because it can't be retrieved + // from the text control + str = m_value; + } else - m_windowId = id; + { + str = wxTextEntry::GetValue(); - return TRUE; + if ( m_tempCallbackStruct ) + { + // the string in the control isn't yet updated, can't use it as is + MergeChangesIntoString(str, (XmTextVerifyCallbackStruct *) + m_tempCallbackStruct); + } + } + + return str; } -wxString wxTextCtrl::GetValue() const +void wxTextCtrl::DoSetValue(const wxString& text, int flags) { - // TODO - return wxString(""); + m_inSetValue = true; + + XmTextSetString ((Widget) m_mainWidget, text.char_str()); + XtVaSetValues ((Widget) m_mainWidget, + XmNcursorPosition, text.length(), + NULL); + + SetInsertionPoint(text.length()); + XmTextShowPosition ((Widget) m_mainWidget, text.length()); + m_modified = true; + + m_inSetValue = false; + + if ( flags & SetValue_SendEvent ) + SendTextUpdatedEvent(); } -void wxTextCtrl::SetValue(const wxString& value) +bool wxTextCtrl::IsModified() const { - // TODO + return m_modified; } -void wxTextCtrl::SetSize(int x, int y, int width, int height, int sizeFlags) +// Makes modified or unmodified +void wxTextCtrl::MarkDirty() { - // TODO + m_modified = true; } -// Clipboard operations -void wxTextCtrl::Copy() +void wxTextCtrl::DiscardEdits() { - // TODO + m_modified = false; } -void wxTextCtrl::Cut() +int wxTextCtrl::GetNumberOfLines() const { - // TODO + // HIDEOUSLY inefficient, but we have no choice. + char *s = XmTextGetString ((Widget) m_mainWidget); + if (s) + { + long i = 0; + int currentLine = 0; + bool finished = false; + while (!finished) + { + int ch = s[i]; + if (ch == '\n') + { + currentLine++; + i++; + } + else if (ch == 0) + { + finished = true; + } + else + i++; + } + + XtFree (s); + return currentLine; + } + return 0; } -void wxTextCtrl::Paste() +long wxTextCtrl::XYToPosition(long x, long y) const { - // TODO +/* It seems, that there is a bug in some versions of the Motif library, + so the original wxWin-Code doesn't work. */ + /* + Widget textWidget = (Widget) handle; + return (long) XmTextXYToPos (textWidget, (Position) x, (Position) y); + */ + /* Now a little workaround: */ + long r=0; + for (int i=0; i 0) + { + LoadFile(event.GetFiles()[0]); + } } -void wxTextCtrl::Replace(long from, long to, const wxString& value) +void wxTextCtrl::OnChar(wxKeyEvent& event) { - // TODO + // Indicates that we should generate a normal command, because + // we're letting default behaviour happen (otherwise it's vetoed + // by virtue of overriding OnChar) + m_processedDefault = true; + + if (m_tempCallbackStruct) + { + XmTextVerifyCallbackStruct *textStruct = + (XmTextVerifyCallbackStruct *) m_tempCallbackStruct; + textStruct->doit = True; + if (wxIsascii(event.m_keyCode) && (textStruct->text->length == 1)) + { + textStruct->text->ptr[0] = (char)((event.m_keyCode == WXK_RETURN) ? 10 : event.m_keyCode); + } + } } -void wxTextCtrl::Remove(long from, long to) +void wxTextCtrl::ChangeFont(bool keepOriginalSize) { - // TODO + wxWindow::ChangeFont(keepOriginalSize); } -void wxTextCtrl::SetSelection(long from, long to) +void wxTextCtrl::ChangeBackgroundColour() { - // TODO + wxWindow::ChangeBackgroundColour(); + + /* TODO: should scrollbars be affected? Should probably have separate + * function to change them (by default, taken from wxSystemSettings) + */ + if (m_windowStyle & wxTE_MULTILINE) + { + Widget parent = XtParent ((Widget) m_mainWidget); + Widget hsb, vsb; + + XtVaGetValues (parent, + XmNhorizontalScrollBar, &hsb, + XmNverticalScrollBar, &vsb, + NULL); + wxColour backgroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE); + if (hsb) + wxDoChangeBackgroundColour((WXWidget) hsb, backgroundColour, true); + if (vsb) + wxDoChangeBackgroundColour((WXWidget) vsb, backgroundColour, true); + + // MBN: why change parent background? + // DoChangeBackgroundColour((WXWidget) parent, m_backgroundColour, true); + } } -bool wxTextCtrl::LoadFile(const wxString& file) +void wxTextCtrl::ChangeForegroundColour() { - if (!wxFileExists(file)) - return FALSE; + wxWindow::ChangeForegroundColour(); - m_fileName = file; + if (m_windowStyle & wxTE_MULTILINE) + { + Widget parent = XtParent ((Widget) m_mainWidget); + Widget hsb, vsb; + + XtVaGetValues (parent, + XmNhorizontalScrollBar, &hsb, + XmNverticalScrollBar, &vsb, + NULL); + + /* TODO: should scrollbars be affected? Should probably have separate + * function to change them (by default, taken from wxSystemSettings) + if (hsb) + DoChangeForegroundColour((WXWidget) hsb, m_foregroundColour); + if (vsb) + DoChangeForegroundColour((WXWidget) vsb, m_foregroundColour); + */ + wxDoChangeForegroundColour((WXWidget) parent, m_foregroundColour); + } +} - Clear(); +void wxTextCtrl::DoSendEvents(void *wxcbs, long keycode) +{ + // we're in process of updating the text control + m_tempCallbackStruct = wxcbs; - ifstream input((char*) (const char*) file, ios::nocreate | ios::in); + XmTextVerifyCallbackStruct *cbs = (XmTextVerifyCallbackStruct *)wxcbs; - if (!input.bad()) - { - struct stat stat_buf; - if (stat(file, &stat_buf) < 0) - return FALSE; - // This may need to be a bigger buffer than the file size suggests, - // if it's a UNIX file. Give it an extra 1000 just in case. - char *tmp_buffer = (char*)malloc((size_t)(stat_buf.st_size+1+1000)); - long no_lines = 0; - long pos = 0; - while (!input.eof() && input.peek() != EOF) - { - input.getline(wxBuffer, 500); - int len = strlen(wxBuffer); - wxBuffer[len] = 13; - wxBuffer[len+1] = 10; - wxBuffer[len+2] = 0; - strcpy(tmp_buffer+pos, wxBuffer); - pos += strlen(wxBuffer); - no_lines++; - } + wxKeyEvent event (wxEVT_CHAR); + event.SetId(GetId()); + event.m_keyCode = keycode; + event.SetEventObject(this); - // TODO add line + // Only if wxTextCtrl::OnChar is called will this be set to True (and + // the character passed through) + cbs->doit = False; - free(tmp_buffer); + HandleWindowEvent(event); - return TRUE; + if ( !InSetValue() && m_processedDefault ) + { + // Can generate a command + wxCommandEvent commandEvent(wxEVT_COMMAND_TEXT_UPDATED, GetId()); + commandEvent.SetEventObject(this); + ProcessCommand(commandEvent); } - return FALSE; + + // do it after the (user) event handlers processed the events because + // otherwise GetValue() would return incorrect (not yet updated value) + m_tempCallbackStruct = NULL; } -// If file is null, try saved file name first -// Returns TRUE if succeeds. -bool wxTextCtrl::SaveFile(const wxString& file) +wxSize wxDoGetSingleTextCtrlBestSize( Widget textWidget, + const wxWindow* window ) { - wxString theFile(file); - if (theFile == "") - theFile = m_fileName; - if (theFile == "") - return FALSE; - m_fileName = theFile; + Dimension xmargin, ymargin, highlight, shadow; + char* value; - ofstream output((char*) (const char*) theFile); - if (output.bad()) - return FALSE; + XtVaGetValues( textWidget, + XmNmarginWidth, &xmargin, + XmNmarginHeight, &ymargin, + XmNvalue, &value, + XmNhighlightThickness, &highlight, + XmNshadowThickness, &shadow, + NULL ); - // TODO get and save text + if( !value ) + value = wxMOTIF_STR("|"); - return FALSE; -} + int x, y; + window->GetTextExtent( value, &x, &y ); -void wxTextCtrl::WriteText(const wxString& text) -{ - // TODO write text to control -} + if( x < 90 ) + x = 90; -void wxTextCtrl::Clear() -{ - // TODO + return wxSize( x + 2 * xmargin + 2 * highlight + 2 * shadow, + // MBN: +2 necessary: Lesstif bug or mine? + y + 2 * ymargin + 2 * highlight + 2 * shadow + 2 ); } -bool wxTextCtrl::IsModified() const +wxSize wxTextCtrl::DoGetBestSize() const { - // TODO - return FALSE; -} + if( IsSingleLine() ) + { + wxSize best = wxControl::DoGetBestSize(); +#if wxCHECK_MOTIF_VERSION( 2, 3 ) + // OpenMotif 2.3 gives way too big X sizes + wxSize other_best = wxDoGetSingleTextCtrlBestSize + ( (Widget) GetTopWidget(), this ); + return wxSize( other_best.x, best.y ); +#else + if( best.x < 90 ) best.x = 90; -// Makes 'unmodified' -void wxTextCtrl::DiscardEdits() -{ - // TODO + return best; +#endif + } + else + return wxWindow::DoGetBestSize(); } -int wxTextCtrl::GetNumberOfLines() const -{ - // TODO - return 0; -} +// ---------------------------------------------------------------------------- +// helpers and Motif callbacks +// ---------------------------------------------------------------------------- -long wxTextCtrl::XYToPosition(long x, long y) const +static void MergeChangesIntoString(wxString& value, + XmTextVerifyCallbackStruct *cbs) { - // TODO - return 0; + /* _sm_ + * At least on my system (SunOS 4.1.3 + Motif 1.2), you need to think of + * every event as a replace event. cbs->text->ptr gives the replacement + * text, cbs->startPos gives the index of the first char affected by the + * replace, and cbs->endPos gives the index one more than the last char + * affected by the replace (startPos == endPos implies an empty range). + * Hence, a deletion is represented by replacing all input text with a + * blank string ("", *not* NULL!). A simple insertion that does not + * overwrite any text has startPos == endPos. + */ + + if ( !value ) + { + // easy case: the ol value was empty + value = cbs->text->ptr; + } + else + { + // merge the changes into the value + const char * const passwd = value; + int len = value.length(); + + len += ( cbs->text->ptr ? + strlen(cbs->text->ptr) : + 0 ) + 1; // + new text (if any) + NUL + len -= cbs->endPos - cbs->startPos; // - text from affected region. + + char * newS = new char [len]; + char * dest = newS, + * insert = cbs->text->ptr; + + // Copy (old) text from passwd, up to the start posn of the change. + int i; + const char * p = passwd; + for (i = 0; i < cbs->startPos; ++i) + *dest++ = *p++; + + // Copy the text to be inserted). + if (insert) + while (*insert) + *dest++ = *insert++; + + // Finally, copy into newS any remaining text from passwd[endPos] on. + for (p = passwd + cbs->endPos; *p; ) + *dest++ = *p++; + *dest = 0; + + value = newS; + + delete[] newS; + } } -void wxTextCtrl::PositionToXY(long pos, long *x, long *y) const +static void +wxTextWindowChangedProc (Widget w, XtPointer clientData, XtPointer WXUNUSED(ptr)) { - // TODO + if (!wxGetWindowFromTable(w)) + // Widget has been deleted! + return; + + wxTextCtrl *tw = (wxTextCtrl *) clientData; + tw->SetModified(true); } -void wxTextCtrl::ShowPosition(long pos) +static void +wxTextWindowModifyProc (Widget WXUNUSED(w), XtPointer clientData, XmTextVerifyCallbackStruct *cbs) { - // TODO + wxTextCtrl *tw = (wxTextCtrl *) clientData; + tw->m_processedDefault = false; + + // First, do some stuff if it's a password control: in this case, we need + // to store the string inside the class because GetValue() can't retrieve + // it from the text ctrl. We do *not* do it in other circumstances because + // it would double the amount of memory needed. + + if ( tw->GetWindowStyleFlag() & wxTE_PASSWORD ) + { + MergeChangesIntoString(tw->m_value, cbs); + + if ( cbs->text->length > 0 ) + { + int i; + for (i = 0; i < cbs->text->length; ++i) + cbs->text->ptr[i] = '*'; + cbs->text->ptr[i] = '\0'; + } + } + + if(tw->InSetValue()) + return; + + // If we're already within an OnChar, return: probably a programmatic + // insertion. + if (tw->m_tempCallbackStruct) + return; + + // Check for a backspace + if (cbs->startPos == (cbs->currInsert - 1)) + { + tw->DoSendEvents((void *)cbs, WXK_DELETE); + + return; + } + + // Pasting operation: let it through without calling OnChar + if (cbs->text->length > 1) + return; + + // Something other than text + if (cbs->text->ptr == NULL) + return; + + // normal key press + char ch = cbs->text->ptr[0]; + tw->DoSendEvents((void *)cbs, ch == '\n' ? '\r' : ch); } -int wxTextCtrl::GetLineLength(long lineNo) const +static void +wxTextWindowGainFocusProc (Widget w, XtPointer clientData, XmAnyCallbackStruct *WXUNUSED(cbs)) { - // TODO - return 0; + if (!wxGetWindowFromTable(w)) + return; + + wxTextCtrl *tw = (wxTextCtrl *) clientData; + wxFocusEvent event(wxEVT_SET_FOCUS, tw->GetId()); + event.SetEventObject(tw); + tw->HandleWindowEvent(event); } -wxString wxTextCtrl::GetLineText(long lineNo) const +static void +wxTextWindowLoseFocusProc (Widget w, XtPointer clientData, XmAnyCallbackStruct *WXUNUSED(cbs)) { - // TODO - return wxString(""); + if (!wxGetWindowFromTable(w)) + return; + + wxTextCtrl *tw = (wxTextCtrl *) clientData; + wxFocusEvent event(wxEVT_KILL_FOCUS, tw->GetId()); + event.SetEventObject(tw); + tw->HandleWindowEvent(event); } -/* - * Text item - */ - -void wxTextCtrl::Command(wxCommandEvent & event) +static void wxTextWindowActivateProc(Widget w, XtPointer clientData, + XmAnyCallbackStruct *WXUNUSED(ptr)) { - SetValue (event.GetString()); - ProcessCommand (event); + if (!wxGetWindowFromTable(w)) + return; + + wxTextCtrl *tw = (wxTextCtrl *) clientData; + + if (tw->InSetValue()) + return; + + wxCommandEvent event(wxEVT_COMMAND_TEXT_ENTER); + event.SetId(tw->GetId()); + event.SetEventObject(tw); + tw->ProcessCommand(event); } -void wxTextCtrl::OnDropFiles(wxDropFilesEvent& event) +void wxTextCtrl::OnCut(wxCommandEvent& WXUNUSED(event)) { - // By default, load the first file into the text window. - if (event.GetNumberOfFiles() > 0) - { - LoadFile(event.GetFiles()[0]); - } + Cut(); } -// The streambuf code was partly taken from chapter 3 by Jerry Schwarz of -// AT&T's "C++ Lanuage System Release 3.0 Library Manual" - Stein Somers - -//========================================================================= -// Called then the buffer is full (gcc 2.6.3) -// or when "endl" is output (Borland 4.5) -//========================================================================= -// Class declaration using multiple inheritance doesn't work properly for -// Borland. See note in wb_text.h. -#ifndef NO_TEXT_WINDOW_STREAM -int wxTextCtrl::overflow(int c) -{ - // Make sure there is a holding area - if ( allocate()==EOF ) - { - wxError("Streambuf allocation failed","Internal error"); - return EOF; - } - - // Verify that there are no characters in get area - if ( gptr() && gptr() < egptr() ) - { - wxError("Who's trespassing my get area?","Internal error"); - return EOF; - } - - // Reset get area - setg(0,0,0); - - // Make sure there is a put area - if ( ! pptr() ) - { -/* This doesn't seem to be fatal so comment out error message */ -// wxError("Put area not opened","Internal error"); - setp( base(), base() ); - } - - // Determine how many characters have been inserted but no consumed - int plen = pptr() - pbase(); - - // Now Jerry relies on the fact that the buffer is at least 2 chars - // long, but the holding area "may be as small as 1" ??? - // And we need an additional \0, so let's keep this inefficient but - // safe copy. - - // If c!=EOF, it is a character that must also be comsumed - int xtra = c==EOF? 0 : 1; - - // Write temporary C-string to wxTextWindow - { - char *txt = new char[plen+xtra+1]; - memcpy(txt, pbase(), plen); - txt[plen] = (char)c; // append c - txt[plen+xtra] = '\0'; // append '\0' or overwrite c - // If the put area already contained \0, output will be truncated there - WriteText(txt); - delete[] txt; - } - - // Reset put area - setp(pbase(), epptr()); - -#if defined(__WATCOMC__) - return __NOT_EOF; -#elif defined(zapeof) // HP-UX (all cfront based?) - return zapeof(c); -#else - return c!=EOF ? c : 0; // this should make everybody happy -#endif +void wxTextCtrl::OnCopy(wxCommandEvent& WXUNUSED(event)) +{ + Copy(); } -//========================================================================= -// called then "endl" is output (gcc) or then explicit sync is done (Borland) -//========================================================================= -int wxTextCtrl::sync() -{ - // Verify that there are no characters in get area - if ( gptr() && gptr() < egptr() ) - { - wxError("Who's trespassing my get area?","Internal error"); - return EOF; - } - - if ( pptr() && pptr() > pbase() ) return overflow(EOF); - - return 0; -/* OLD CODE - 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 0; -*/ +void wxTextCtrl::OnPaste(wxCommandEvent& WXUNUSED(event)) +{ + Paste(); } -//========================================================================= -// Should not be called by a "ostream". Used by a "istream" -//========================================================================= -int wxTextCtrl::underflow() +void wxTextCtrl::OnUndo(wxCommandEvent& WXUNUSED(event)) { - return EOF; + Undo(); } -#endif -wxTextCtrl& wxTextCtrl::operator<<(const wxString& s) +void wxTextCtrl::OnRedo(wxCommandEvent& WXUNUSED(event)) { - WriteText(s); - return *this; + Redo(); } -wxTextCtrl& wxTextCtrl::operator<<(float f) +void wxTextCtrl::OnUpdateCut(wxUpdateUIEvent& event) { - wxString str; - str.Printf("%.2f", f); - WriteText(str); - return *this; + event.Enable( CanCut() ); } -wxTextCtrl& wxTextCtrl::operator<<(double d) +void wxTextCtrl::OnUpdateCopy(wxUpdateUIEvent& event) { - wxString str; - str.Printf("%.2f", d); - WriteText(str); - return *this; + event.Enable( CanCopy() ); } -wxTextCtrl& wxTextCtrl::operator<<(int i) +void wxTextCtrl::OnUpdatePaste(wxUpdateUIEvent& event) { - wxString str; - str.Printf("%d", i); - WriteText(str); - return *this; + event.Enable( CanPaste() ); } -wxTextCtrl& wxTextCtrl::operator<<(long i) +void wxTextCtrl::OnUpdateUndo(wxUpdateUIEvent& event) { - wxString str; - str.Printf("%ld", i); - WriteText(str); - return *this; + event.Enable( CanUndo() ); } -wxTextCtrl& wxTextCtrl::operator<<(const char c) +void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent& event) { - char buf[2]; - - buf[0] = c; - buf[1] = 0; - WriteText(buf); - return *this; + event.Enable( CanRedo() ); } -