X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/d390f6eefc317e8db03a9e891011d74bf4b7e1b2..dde4740fe1dddbb2738a0afd054f493cb0dd67d1:/src/motif/textctrl.cpp?ds=sidebyside diff --git a/src/motif/textctrl.cpp b/src/motif/textctrl.cpp index 5a8950d25d..06e42ff6c7 100644 --- a/src/motif/textctrl.cpp +++ b/src/motif/textctrl.cpp @@ -17,13 +17,21 @@ // headers // ---------------------------------------------------------------------------- -#ifdef __GNUG__ +#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) #pragma implementation "textctrl.h" #endif +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#ifdef __VMS +#define XtParent XTPARENT +#endif + +#include "wx/defs.h" + #include #include -#include #include #include "wx/textctrl.h" @@ -31,7 +39,13 @@ #include "wx/filefn.h" #include "wx/utils.h" +#ifdef __VMS__ +#pragma message disable nosimpint +#endif #include +#ifdef __VMS__ +#pragma message enable nosimpint +#endif #include "wx/motif/private.h" @@ -51,7 +65,6 @@ static void wxTextWindowGainFocusProc(Widget w, XtPointer clientData, XmAnyCallb static void wxTextWindowLoseFocusProc(Widget w, XtPointer clientData, XmAnyCallbackStruct *cbs); static void wxTextWindowActivateProc(Widget w, XtPointer clientData, XmAnyCallbackStruct *ptr); -#if !USE_SHARED_LIBRARY IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl, wxControl) BEGIN_EVENT_TABLE(wxTextCtrl, wxControl) @@ -71,7 +84,6 @@ static void wxTextWindowActivateProc(Widget w, XtPointer clientData, XmAnyCallba EVT_UPDATE_UI(wxID_REDO, wxTextCtrl::OnUpdateRedo) END_EVENT_TABLE() -#endif // ============================================================================ // implementation @@ -83,13 +95,10 @@ static void wxTextWindowActivateProc(Widget w, XtPointer clientData, XmAnyCallba // Text item wxTextCtrl::wxTextCtrl() -#ifndef NO_TEXT_WINDOW_STREAM - : streambuf() -#endif { m_tempCallbackStruct = (void*) NULL; - m_modified = FALSE; - m_processedDefault = FALSE; + m_modified = false; + m_processedDefault = false; } bool wxTextCtrl::Create(wxWindow *parent, @@ -101,24 +110,14 @@ bool wxTextCtrl::Create(wxWindow *parent, const wxValidator& validator, const wxString& name) { - m_tempCallbackStruct = (void*) NULL; - m_modified = FALSE; - m_processedDefault = FALSE; - // m_backgroundColour = parent->GetBackgroundColour(); - m_backgroundColour = * wxWHITE; - m_foregroundColour = parent->GetForegroundColour(); - - SetName(name); - SetValidator(validator); - if (parent) - parent->AddChild(this); + if( !CreateControl( parent, id, pos, size, style, validator, name ) ) + return false; - m_windowStyle = style; + m_tempCallbackStruct = (void*) NULL; + m_modified = false; + m_processedDefault = false; - if ( id == -1 ) - m_windowId = (int)NewControlId(); - else - m_windowId = id; + m_backgroundColour = *wxWHITE; Widget parentWidget = (Widget) parent->GetClientWidget(); @@ -134,7 +133,7 @@ bool wxTextCtrl::Create(wxWindow *parent, XtSetArg (args[1], XmNwordWrap, wantWordWrap ? True : False); m_mainWidget = (WXWidget) XmCreateScrolledText(parentWidget, - (char*)name.c_str(), + wxConstCast(name.c_str(), char), args, 2); XtVaSetValues ((Widget) m_mainWidget, @@ -147,12 +146,16 @@ bool wxTextCtrl::Create(wxWindow *parent, { m_mainWidget = (WXWidget)XtVaCreateManagedWidget ( - (char*)name.c_str(), + wxConstCast(name.c_str(), char), xmTextWidgetClass, parentWidget, NULL ); + XtVaSetValues ((Widget) m_mainWidget, + XmNeditable, ((style & wxTE_READONLY) ? False : True), + NULL); + // TODO: Is this relevant? What does it do? int noCols = 2; if (!value.IsNull() && (value.Length() > (unsigned int) noCols)) @@ -170,8 +173,14 @@ bool wxTextCtrl::Create(wxWindow *parent, NULL); } - if ( !!value ) - XmTextSetString ((Widget) m_mainWidget, (char*)value.c_str()); + if ( !value.empty() ) + { + // do this instead... MB + // + XtVaSetValues( (Widget) m_mainWidget, + XmNvalue, wxConstCast(value.c_str(), char), + NULL); + } // install callbacks XtAddCallback((Widget) m_mainWidget, XmNvalueChangedCallback, (XtCallbackProc)wxTextWindowChangedProc, (XtPointer)this); @@ -185,20 +194,24 @@ bool wxTextCtrl::Create(wxWindow *parent, XtAddCallback((Widget) m_mainWidget, XmNlosingFocusCallback, (XtCallbackProc)wxTextWindowLoseFocusProc, (XtPointer)this); // font - m_windowFont = parent->GetFont(); - ChangeFont(FALSE); + ChangeFont(false); - SetCanAddEventHandler(TRUE); - AttachWidget (parent, m_mainWidget, (WXWidget) NULL, pos.x, pos.y, size.x, size.y); + wxSize best = GetBestSize(); + if( size.x != -1 ) best.x = size.x; + if( size.y != -1 ) best.y = size.y; + + AttachWidget (parent, m_mainWidget, (WXWidget) NULL, + pos.x, pos.y, best.x, best.y); ChangeBackgroundColour(); - return TRUE; + return true; } WXWidget wxTextCtrl::GetTopWidget() const { - return ((m_windowStyle & wxTE_MULTILINE) ? (WXWidget) XtParent((Widget) m_mainWidget) : m_mainWidget); + return IsMultiLine() ? (WXWidget)XtParent((Widget)m_mainWidget) + : m_mainWidget; } wxString wxTextCtrl::GetValue() const @@ -235,11 +248,21 @@ wxString wxTextCtrl::GetValue() const void wxTextCtrl::SetValue(const wxString& value) { - m_inSetValue = TRUE; + m_inSetValue = true; + + // do this instead... MB + // + // with (at least) OpenMotif 2.1 this causes a lot of flicker +#if 0 + XtVaSetValues( (Widget) m_mainWidget, + XmNvalue, wxConstCast(value.c_str(), char), + NULL); +#endif - XmTextSetString ((Widget) m_mainWidget, (char*)value.c_str()); + Clear(); + AppendText( value ); - m_inSetValue = FALSE; + m_inSetValue = false; } // Clipboard operations @@ -271,7 +294,7 @@ bool wxTextCtrl::CanCut() const // Can cut if there's a selection long from, to; GetSelection(& from, & to); - return (from != to) ; + return (from != to) && (IsEditable()); } bool wxTextCtrl::CanPaste() const @@ -293,13 +316,13 @@ void wxTextCtrl::Redo() bool wxTextCtrl::CanUndo() const { // No Undo in Motif - return FALSE; + return false; } bool wxTextCtrl::CanRedo() const { // No Redo in Motif - return FALSE; + return false; } // If the return values from and to are the same, there is no @@ -331,7 +354,7 @@ void wxTextCtrl::SetInsertionPoint(long pos) void wxTextCtrl::SetInsertionPointEnd() { - long pos = GetLastPosition(); + wxTextPos pos = GetLastPosition(); SetInsertionPoint(pos); } @@ -340,7 +363,7 @@ long wxTextCtrl::GetInsertionPoint() const return (long) XmTextGetInsertionPosition ((Widget) m_mainWidget); } -long wxTextCtrl::GetLastPosition() const +wxTextPos wxTextCtrl::GetLastPosition() const { return (long) XmTextGetLastPosition ((Widget) m_mainWidget); } @@ -348,7 +371,7 @@ long wxTextCtrl::GetLastPosition() const void wxTextCtrl::Replace(long from, long to, const wxString& value) { XmTextReplace ((Widget) m_mainWidget, (XmTextPosition) from, (XmTextPosition) to, - (char*) (const char*) value); + wxConstCast(value.c_str(), char)); } void wxTextCtrl::Remove(long from, long to) @@ -360,113 +383,39 @@ void wxTextCtrl::Remove(long from, long to) void wxTextCtrl::SetSelection(long from, long to) { + if( to == -1 ) + to = GetLastPosition(); + XmTextSetSelection ((Widget) m_mainWidget, (XmTextPosition) from, (XmTextPosition) to, (Time) 0); } -bool wxTextCtrl::LoadFile(const wxString& file) -{ - if (!wxFileExists(file)) - return FALSE; - - m_fileName = file; - - Clear(); - - Widget textWidget = (Widget) m_mainWidget; - FILE *fp; - - struct stat statb; - if ((stat ((char*) (const char*) file, &statb) == -1) || (statb.st_mode & S_IFMT) != S_IFREG || - !(fp = fopen ((char*) (const char*) file, "r"))) - { - return FALSE; - } - else - { - long len = statb.st_size; - char *text; - if (!(text = XtMalloc ((unsigned) (len + 1)))) - { - fclose (fp); - return FALSE; - } - if (fread (text, sizeof (char), len, fp) != (size_t) len) - { - } - fclose (fp); - - text[len] = 0; - XmTextSetString (textWidget, text); - // m_textPosition = len; - XtFree (text); - m_modified = FALSE; - return TRUE; - } -} - -// If file is null, try saved file name first -// Returns TRUE if succeeds. -bool wxTextCtrl::SaveFile(const wxString& file) -{ - wxString theFile(file); - if (theFile == "") - theFile = m_fileName; - if (theFile == "") - return FALSE; - m_fileName = theFile; - - Widget textWidget = (Widget) m_mainWidget; - FILE *fp; - - if (!(fp = fopen ((char*) (const char*) theFile, "w"))) - { - return FALSE; - } - else - { - char *text = XmTextGetString (textWidget); - long len = XmTextGetLastPosition (textWidget); - - if (fwrite (text, sizeof (char), len, fp) != (size_t) len) - { - // Did not write whole file - } - // Make sure newline terminates the file - if (text[len - 1] != '\n') - fputc ('\n', fp); - - fclose (fp); - XtFree (text); - m_modified = FALSE; - return TRUE; - } -} - void wxTextCtrl::WriteText(const wxString& text) { - long textPosition = GetInsertionPoint() + strlen (text); - XmTextInsert ((Widget) m_mainWidget, GetInsertionPoint(), (char*) (const char*) text); + long textPosition = GetInsertionPoint() + text.length(); + XmTextInsert ((Widget) m_mainWidget, GetInsertionPoint(), + wxConstCast(text.c_str(), char)); XtVaSetValues ((Widget) m_mainWidget, XmNcursorPosition, textPosition, NULL); SetInsertionPoint(textPosition); XmTextShowPosition ((Widget) m_mainWidget, textPosition); - m_modified = TRUE; + m_modified = true; } void wxTextCtrl::AppendText(const wxString& text) { - long textPosition = GetLastPosition() + strlen(text); - XmTextInsert ((Widget) m_mainWidget, GetLastPosition(), (char*) (const char*) text); + wxTextPos textPosition = GetLastPosition() + text.length(); + XmTextInsert ((Widget) m_mainWidget, GetLastPosition(), + wxConstCast(text.c_str(), char)); XtVaSetValues ((Widget) m_mainWidget, XmNcursorPosition, textPosition, NULL); SetInsertionPoint(textPosition); XmTextShowPosition ((Widget) m_mainWidget, textPosition); - m_modified = TRUE; + m_modified = true; } void wxTextCtrl::Clear() { XmTextSetString ((Widget) m_mainWidget, ""); - m_modified = FALSE; + m_modified = false; } bool wxTextCtrl::IsModified() const @@ -474,10 +423,15 @@ bool wxTextCtrl::IsModified() const return m_modified; } -// Makes 'unmodified' +// Makes modified or unmodified +void wxTextCtrl::MarkDirty() +{ + m_modified = true; +} + void wxTextCtrl::DiscardEdits() { - m_modified = FALSE; + m_modified = false; } int wxTextCtrl::GetNumberOfLines() const @@ -488,7 +442,7 @@ int wxTextCtrl::GetNumberOfLines() const { long i = 0; int currentLine = 0; - bool finished = FALSE; + bool finished = false; while (!finished) { int ch = s[i]; @@ -499,7 +453,7 @@ int wxTextCtrl::GetNumberOfLines() const } else if (ch == 0) { - finished = TRUE; + finished = true; } else i++; @@ -525,11 +479,16 @@ long wxTextCtrl::XYToPosition(long x, long y) const return r+x; } -void wxTextCtrl::PositionToXY(long pos, long *x, long *y) const +bool wxTextCtrl::PositionToXY(long pos, long *x, long *y) const { Position xx, yy; XmTextPosToXY((Widget) m_mainWidget, pos, &xx, &yy); - *x = xx; *y = yy; + if ( x ) + *x = xx; + if ( y ) + *y = yy; + + return true; } void wxTextCtrl::ShowPosition(long pos) @@ -587,167 +546,12 @@ void wxTextCtrl::OnDropFiles(wxDropFilesEvent& event) } } -// 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("wxTextCtrl::overflow: 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 -} - -//========================================================================= -// 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; - */ -} - -//========================================================================= -// Should not be called by a "ostream". Used by a "istream" -//========================================================================= -int wxTextCtrl::underflow() -{ - return EOF; -} -#endif - -wxTextCtrl& wxTextCtrl::operator<<(const wxString& s) -{ - AppendText(s); - return *this; -} - -wxTextCtrl& wxTextCtrl::operator<<(float f) -{ - wxString str; - str.Printf("%.2f", f); - AppendText(str); - return *this; -} - -wxTextCtrl& wxTextCtrl::operator<<(double d) -{ - wxString str; - str.Printf("%.2f", d); - AppendText(str); - return *this; -} - -wxTextCtrl& wxTextCtrl::operator<<(int i) -{ - wxString str; - str.Printf("%d", i); - AppendText(str); - return *this; -} - -wxTextCtrl& wxTextCtrl::operator<<(long i) -{ - wxString str; - str.Printf("%ld", i); - AppendText(str); - return *this; -} - -wxTextCtrl& wxTextCtrl::operator<<(const char c) -{ - char buf[2]; - - buf[0] = c; - buf[1] = 0; - AppendText(buf); - return *this; -} - void wxTextCtrl::OnChar(wxKeyEvent& event) { // 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; + m_processedDefault = true; if (m_tempCallbackStruct) { @@ -782,13 +586,14 @@ void wxTextCtrl::ChangeBackgroundColour() XmNhorizontalScrollBar, &hsb, XmNverticalScrollBar, &vsb, NULL); - wxColour backgroundColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE); + wxColour backgroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE); if (hsb) - DoChangeBackgroundColour((WXWidget) hsb, backgroundColour, TRUE); + wxDoChangeBackgroundColour((WXWidget) hsb, backgroundColour, true); if (vsb) - DoChangeBackgroundColour((WXWidget) vsb, backgroundColour, TRUE); + wxDoChangeBackgroundColour((WXWidget) vsb, backgroundColour, true); - DoChangeBackgroundColour((WXWidget) parent, m_backgroundColour, TRUE); + // MBN: why change parent background? + // DoChangeBackgroundColour((WXWidget) parent, m_backgroundColour, true); } } @@ -813,7 +618,7 @@ void wxTextCtrl::ChangeForegroundColour() if (vsb) DoChangeForegroundColour((WXWidget) vsb, m_foregroundColour); */ - DoChangeForegroundColour((WXWidget) parent, m_foregroundColour); + wxDoChangeForegroundColour((WXWidget) parent, m_foregroundColour); } } @@ -848,6 +653,41 @@ void wxTextCtrl::DoSendEvents(void *wxcbs, long keycode) m_tempCallbackStruct = NULL; } +wxSize wxDoGetSingleTextCtrlBestSize( Widget textWidget, + const wxWindow* window ) +{ + Dimension xmargin, ymargin, highlight, shadow; + char* value; + + XtVaGetValues( textWidget, + XmNmarginWidth, &xmargin, + XmNmarginHeight, &ymargin, + XmNvalue, &value, + XmNhighlightThickness, &highlight, + XmNshadowThickness, &shadow, + NULL ); + + if( !value ) + value = "|"; + + int x, y; + window->GetTextExtent( value, &x, &y ); + + if( x < 100 ) x = 100; + + return wxSize( x + 2 * xmargin + 2 * highlight + 2 * shadow, + // MBN: +2 necessary: Lesstif bug or mine? + y + 2 * ymargin + 2 * highlight + 2 * shadow + 2 ); +} + +wxSize wxTextCtrl::DoGetBestSize() const +{ + if( IsSingleLine() ) + return wxDoGetSingleTextCtrlBestSize( (Widget)m_mainWidget, this ); + else + return wxWindow::DoGetBestSize(); +} + // ---------------------------------------------------------------------------- // helpers and Motif callbacks // ---------------------------------------------------------------------------- @@ -877,7 +717,9 @@ static void MergeChangesIntoString(wxString& value, const char * const passwd = value; int len = value.length(); - len += strlen(cbs->text->ptr) + 1; // + new text (if any) + NUL + 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]; @@ -891,8 +733,9 @@ static void MergeChangesIntoString(wxString& value, *dest++ = *p++; // Copy the text to be inserted). - while (*insert) - *dest++ = *insert++; + if (insert) + while (*insert) + *dest++ = *insert++; // Finally, copy into newS any remaining text from passwd[endPos] on. for (p = passwd + cbs->endPos; *p; ) @@ -906,21 +749,21 @@ static void MergeChangesIntoString(wxString& value, } static void -wxTextWindowChangedProc (Widget w, XtPointer clientData, XtPointer ptr) +wxTextWindowChangedProc (Widget w, XtPointer clientData, XtPointer WXUNUSED(ptr)) { if (!wxGetWindowFromTable(w)) // Widget has been deleted! return; wxTextCtrl *tw = (wxTextCtrl *) clientData; - tw->SetModified(TRUE); + tw->SetModified(true); } static void -wxTextWindowModifyProc (Widget w, XtPointer clientData, XmTextVerifyCallbackStruct *cbs) +wxTextWindowModifyProc (Widget WXUNUSED(w), XtPointer clientData, XmTextVerifyCallbackStruct *cbs) { wxTextCtrl *tw = (wxTextCtrl *) clientData; - tw->m_processedDefault = FALSE; + 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 @@ -940,6 +783,9 @@ wxTextWindowModifyProc (Widget w, XtPointer clientData, XmTextVerifyCallbackStru } } + if(tw->InSetValue()) + return; + // If we're already within an OnChar, return: probably a programmatic // insertion. if (tw->m_tempCallbackStruct) @@ -967,7 +813,7 @@ wxTextWindowModifyProc (Widget w, XtPointer clientData, XmTextVerifyCallbackStru } static void -wxTextWindowGainFocusProc (Widget w, XtPointer clientData, XmAnyCallbackStruct *cbs) +wxTextWindowGainFocusProc (Widget w, XtPointer clientData, XmAnyCallbackStruct *WXUNUSED(cbs)) { if (!wxGetWindowFromTable(w)) return; @@ -979,7 +825,7 @@ wxTextWindowGainFocusProc (Widget w, XtPointer clientData, XmAnyCallbackStruct * } static void -wxTextWindowLoseFocusProc (Widget w, XtPointer clientData, XmAnyCallbackStruct *cbs) +wxTextWindowLoseFocusProc (Widget w, XtPointer clientData, XmAnyCallbackStruct *WXUNUSED(cbs)) { if (!wxGetWindowFromTable(w)) return; @@ -991,7 +837,7 @@ wxTextWindowLoseFocusProc (Widget w, XtPointer clientData, XmAnyCallbackStruct * } static void wxTextWindowActivateProc(Widget w, XtPointer clientData, - XmAnyCallbackStruct *ptr) + XmAnyCallbackStruct *WXUNUSED(ptr)) { if (!wxGetWindowFromTable(w)) return;