1 ///////////////////////////////////////////////////////////////////////////// 
   4 // Author:      Julian Smart 
   8 // Copyright:   (c) Julian Smart 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // ============================================================================ 
  14 // ============================================================================ 
  16 // ---------------------------------------------------------------------------- 
  18 // ---------------------------------------------------------------------------- 
  20 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) 
  21     #pragma implementation "textctrl.h" 
  24 // For compilers that support precompilation, includes "wx.h". 
  25 #include "wx/wxprec.h" 
  28 #define XtParent XTPARENT 
  33 #include <sys/types.h> 
  37 #include "wx/textctrl.h" 
  38 #include "wx/settings.h" 
  39 #include "wx/filefn.h" 
  43 #pragma message disable nosimpint 
  47 #pragma message enable nosimpint 
  50 #include "wx/motif/private.h" 
  52 // ---------------------------------------------------------------------------- 
  54 // ---------------------------------------------------------------------------- 
  56 // helper: inserts the new text in the value of the text ctrl and returns the 
  58 static void MergeChangesIntoString(wxString
& value
, 
  59                                    XmTextVerifyCallbackStruct 
*textStruct
); 
  62 static void wxTextWindowChangedProc(Widget w
, XtPointer clientData
, XtPointer ptr
); 
  63 static void wxTextWindowModifyProc(Widget w
, XtPointer clientData
, XmTextVerifyCallbackStruct 
*cbs
); 
  64 static void wxTextWindowGainFocusProc(Widget w
, XtPointer clientData
, XmAnyCallbackStruct 
*cbs
); 
  65 static void wxTextWindowLoseFocusProc(Widget w
, XtPointer clientData
, XmAnyCallbackStruct 
*cbs
); 
  66 static void wxTextWindowActivateProc(Widget w
, XtPointer clientData
, XmAnyCallbackStruct 
*ptr
); 
  68     IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl
, wxControl
) 
  70     BEGIN_EVENT_TABLE(wxTextCtrl
, wxControl
) 
  71         EVT_DROP_FILES(wxTextCtrl::OnDropFiles
) 
  72         EVT_CHAR(wxTextCtrl::OnChar
) 
  74     EVT_MENU(wxID_CUT
, wxTextCtrl::OnCut
) 
  75     EVT_MENU(wxID_COPY
, wxTextCtrl::OnCopy
) 
  76     EVT_MENU(wxID_PASTE
, wxTextCtrl::OnPaste
) 
  77     EVT_MENU(wxID_UNDO
, wxTextCtrl::OnUndo
) 
  78     EVT_MENU(wxID_REDO
, wxTextCtrl::OnRedo
) 
  80     EVT_UPDATE_UI(wxID_CUT
, wxTextCtrl::OnUpdateCut
) 
  81     EVT_UPDATE_UI(wxID_COPY
, wxTextCtrl::OnUpdateCopy
) 
  82     EVT_UPDATE_UI(wxID_PASTE
, wxTextCtrl::OnUpdatePaste
) 
  83     EVT_UPDATE_UI(wxID_UNDO
, wxTextCtrl::OnUpdateUndo
) 
  84     EVT_UPDATE_UI(wxID_REDO
, wxTextCtrl::OnUpdateRedo
) 
  88 // ============================================================================ 
  90 // ============================================================================ 
  92 // ---------------------------------------------------------------------------- 
  94 // ---------------------------------------------------------------------------- 
  97 wxTextCtrl::wxTextCtrl() 
  99     m_tempCallbackStruct 
= (void*) NULL
; 
 101     m_processedDefault 
= false; 
 104 bool wxTextCtrl::Create(wxWindow 
*parent
, 
 106                         const wxString
& value
, 
 110                         const wxValidator
& validator
, 
 111                         const wxString
& name
) 
 113     if( !CreateControl( parent
, id
, pos
, size
, style
, validator
, name 
) ) 
 116     m_tempCallbackStruct 
= (void*) NULL
; 
 118     m_processedDefault 
= false; 
 120     m_backgroundColour 
= *wxWHITE
; 
 122     Widget parentWidget 
= (Widget
) parent
->GetClientWidget(); 
 124     bool wantHorizScrolling 
= ((m_windowStyle 
& wxHSCROLL
) != 0); 
 126     // If we don't have horizontal scrollbars, we want word wrap. 
 127     bool wantWordWrap 
= !wantHorizScrolling
; 
 129     if (m_windowStyle 
& wxTE_MULTILINE
) 
 132         XtSetArg (args
[0], XmNscrollHorizontal
, wantHorizScrolling 
? True 
: False
); 
 133         XtSetArg (args
[1], XmNwordWrap
, wantWordWrap 
? True 
: False
); 
 135         m_mainWidget 
= (WXWidget
) XmCreateScrolledText(parentWidget
, 
 136                                                        wxConstCast(name
.c_str(), char), 
 139         XtVaSetValues ((Widget
) m_mainWidget
, 
 140                         XmNeditable
, ((style 
& wxTE_READONLY
) ? False 
: True
), 
 141                         XmNeditMode
, XmMULTI_LINE_EDIT
, 
 143         XtManageChild ((Widget
) m_mainWidget
); 
 147         m_mainWidget 
= (WXWidget
)XtVaCreateManagedWidget
 
 149                                   wxConstCast(name
.c_str(), char), 
 155         XtVaSetValues ((Widget
) m_mainWidget
, 
 156                         XmNeditable
, ((style 
& wxTE_READONLY
) ? False 
: True
), 
 159         // TODO: Is this relevant? What does it do? 
 161         if (!value
.IsNull() && (value
.Length() > (unsigned int) noCols
)) 
 162             noCols 
= value
.Length(); 
 163         XtVaSetValues((Widget
) m_mainWidget
, 
 168     // remove border if asked for 
 169     if ( style 
& wxNO_BORDER 
) 
 171         XtVaSetValues((Widget
)m_mainWidget
, 
 172                       XmNshadowThickness
, 0, 
 176     if ( !value
.empty() ) 
 178         // do this instead... MB 
 180         XtVaSetValues( (Widget
) m_mainWidget
, 
 181                        XmNvalue
, wxConstCast(value
.c_str(), char), 
 186     XtAddCallback((Widget
) m_mainWidget
, XmNvalueChangedCallback
, (XtCallbackProc
)wxTextWindowChangedProc
, (XtPointer
)this); 
 188     XtAddCallback((Widget
) m_mainWidget
, XmNmodifyVerifyCallback
, (XtCallbackProc
)wxTextWindowModifyProc
, (XtPointer
)this); 
 190     XtAddCallback((Widget
) m_mainWidget
, XmNactivateCallback
, (XtCallbackProc
)wxTextWindowActivateProc
, (XtPointer
)this); 
 192     XtAddCallback((Widget
) m_mainWidget
, XmNfocusCallback
, (XtCallbackProc
)wxTextWindowGainFocusProc
, (XtPointer
)this); 
 194     XtAddCallback((Widget
) m_mainWidget
, XmNlosingFocusCallback
, (XtCallbackProc
)wxTextWindowLoseFocusProc
, (XtPointer
)this); 
 199     AttachWidget (parent
, m_mainWidget
, (WXWidget
) NULL
, 
 200                   pos
.x
, pos
.y
, size
.x
, size
.y
); 
 202     ChangeBackgroundColour(); 
 207 WXWidget 
wxTextCtrl::GetTopWidget() const 
 209     return IsMultiLine() ? (WXWidget
)XtParent((Widget
)m_mainWidget
) 
 213 wxString 
wxTextCtrl::GetValue() const 
 215     wxString str
; // result 
 217     if (m_windowStyle 
& wxTE_PASSWORD
) 
 219         // the value is stored always in m_value because it can't be retrieved 
 220         // from the text control 
 225         // just get the string from Motif 
 226         char *s 
= XmTextGetString ((Widget
) m_mainWidget
); 
 232         //else: return empty string 
 234         if ( m_tempCallbackStruct 
) 
 236             // the string in the control isn't yet updated, can't use it as is 
 237             MergeChangesIntoString(str
, (XmTextVerifyCallbackStruct 
*) 
 238                                    m_tempCallbackStruct
); 
 245 void wxTextCtrl::SetValue(const wxString
& value
) 
 249     // do this instead... MB 
 251     // with (at least) OpenMotif 2.1 this causes a lot of flicker 
 253     XtVaSetValues( (Widget
) m_mainWidget
, 
 254                    XmNvalue
, wxConstCast(value
.c_str(), char), 
 261     m_inSetValue 
= false; 
 264 // Clipboard operations 
 265 void wxTextCtrl::Copy() 
 267     XmTextCopy((Widget
) m_mainWidget
, CurrentTime
); 
 270 void wxTextCtrl::Cut() 
 272     XmTextCut((Widget
) m_mainWidget
, CurrentTime
); 
 275 void wxTextCtrl::Paste() 
 277     XmTextPaste((Widget
) m_mainWidget
); 
 280 bool wxTextCtrl::CanCopy() const 
 282     // Can copy if there's a selection 
 284     GetSelection(& from
, & to
); 
 285     return (from 
!= to
) ; 
 288 bool wxTextCtrl::CanCut() const 
 290     // Can cut if there's a selection 
 292     GetSelection(& from
, & to
); 
 293     return (from 
!= to
) && (IsEditable()); 
 296 bool wxTextCtrl::CanPaste() const 
 298     return IsEditable() ; 
 302 void wxTextCtrl::Undo() 
 304     // Not possible in Motif 
 307 void wxTextCtrl::Redo() 
 309     // Not possible in Motif 
 312 bool wxTextCtrl::CanUndo() const 
 318 bool wxTextCtrl::CanRedo() const 
 324 // If the return values from and to are the same, there is no 
 326 void wxTextCtrl::GetSelection(long* from
, long* to
) const 
 328     XmTextPosition left
, right
; 
 330     XmTextGetSelectionPosition((Widget
) m_mainWidget
, & left
, & right
); 
 336 bool wxTextCtrl::IsEditable() const 
 338     return (XmTextGetEditable((Widget
) m_mainWidget
) != 0); 
 341 void wxTextCtrl::SetEditable(bool editable
) 
 343     XmTextSetEditable((Widget
) m_mainWidget
, (Boolean
) editable
); 
 346 void wxTextCtrl::SetInsertionPoint(long pos
) 
 348     XmTextSetInsertionPosition ((Widget
) m_mainWidget
, (XmTextPosition
) pos
); 
 351 void wxTextCtrl::SetInsertionPointEnd() 
 353     wxTextPos pos 
= GetLastPosition(); 
 354     SetInsertionPoint(pos
); 
 357 long wxTextCtrl::GetInsertionPoint() const 
 359     return (long) XmTextGetInsertionPosition ((Widget
) m_mainWidget
); 
 362 wxTextPos 
wxTextCtrl::GetLastPosition() const 
 364     return (long) XmTextGetLastPosition ((Widget
) m_mainWidget
); 
 367 void wxTextCtrl::Replace(long from
, long to
, const wxString
& value
) 
 369     XmTextReplace ((Widget
) m_mainWidget
, (XmTextPosition
) from
, (XmTextPosition
) to
, 
 370         wxConstCast(value
.c_str(), char)); 
 373 void wxTextCtrl::Remove(long from
, long to
) 
 375     XmTextSetSelection ((Widget
) m_mainWidget
, (XmTextPosition
) from
, (XmTextPosition
) to
, 
 377     XmTextRemove ((Widget
) m_mainWidget
); 
 380 void wxTextCtrl::SetSelection(long from
, long to
) 
 383         to 
= GetLastPosition(); 
 385     XmTextSetSelection ((Widget
) m_mainWidget
, (XmTextPosition
) from
, (XmTextPosition
) to
, 
 389 void wxTextCtrl::WriteText(const wxString
& text
) 
 391     long textPosition 
= GetInsertionPoint() + text
.length(); 
 392     XmTextInsert ((Widget
) m_mainWidget
, GetInsertionPoint(), 
 393                   wxConstCast(text
.c_str(), char)); 
 394     XtVaSetValues ((Widget
) m_mainWidget
, XmNcursorPosition
, textPosition
, NULL
); 
 395     SetInsertionPoint(textPosition
); 
 396     XmTextShowPosition ((Widget
) m_mainWidget
, textPosition
); 
 400 void wxTextCtrl::AppendText(const wxString
& text
) 
 402     wxTextPos textPosition 
= GetLastPosition() + text
.length(); 
 403     XmTextInsert ((Widget
) m_mainWidget
, GetLastPosition(), 
 404                   wxConstCast(text
.c_str(), char)); 
 405     XtVaSetValues ((Widget
) m_mainWidget
, XmNcursorPosition
, textPosition
, NULL
); 
 406     SetInsertionPoint(textPosition
); 
 407     XmTextShowPosition ((Widget
) m_mainWidget
, textPosition
); 
 411 void wxTextCtrl::Clear() 
 413     XmTextSetString ((Widget
) m_mainWidget
, ""); 
 417 bool wxTextCtrl::IsModified() const 
 422 // Makes modified or unmodified 
 423 void wxTextCtrl::MarkDirty() 
 428 void wxTextCtrl::DiscardEdits() 
 433 int wxTextCtrl::GetNumberOfLines() const 
 435     // HIDEOUSLY inefficient, but we have no choice. 
 436     char *s 
= XmTextGetString ((Widget
) m_mainWidget
); 
 441         bool finished 
= false; 
 464 long wxTextCtrl::XYToPosition(long x
, long y
) const 
 466 /* It seems, that there is a bug in some versions of the Motif library, 
 467     so the original wxWin-Code doesn't work. */ 
 469     Widget textWidget = (Widget) handle; 
 470     return (long) XmTextXYToPos (textWidget, (Position) x, (Position) y); 
 472     /* Now a little workaround: */ 
 474     for (int i
=0; i
<y
; i
++) r
+=(GetLineLength(i
)+1); 
 478 bool wxTextCtrl::PositionToXY(long pos
, long *x
, long *y
) const 
 481     XmTextPosToXY((Widget
) m_mainWidget
, pos
, &xx
, &yy
); 
 490 void wxTextCtrl::ShowPosition(long pos
) 
 492     XmTextShowPosition ((Widget
) m_mainWidget
, (XmTextPosition
) pos
); 
 495 int wxTextCtrl::GetLineLength(long lineNo
) const 
 497     wxString str 
= GetLineText (lineNo
); 
 498     return (int) str
.Length(); 
 501 wxString 
wxTextCtrl::GetLineText(long lineNo
) const 
 503     // HIDEOUSLY inefficient, but we have no choice. 
 504     char *s 
= XmTextGetString ((Widget
) m_mainWidget
); 
 511         for (i 
= 0; currentLine 
!= lineNo 
&& s
[i
]; i
++ ) 
 516             for (j 
= 0; s
[i
] && s
[i
] != '\n'; i
++, j
++ ) 
 523         return wxEmptyString
; 
 530 void wxTextCtrl::Command(wxCommandEvent 
& event
) 
 532     SetValue (event
.GetString()); 
 533     ProcessCommand (event
); 
 536 void wxTextCtrl::OnDropFiles(wxDropFilesEvent
& event
) 
 538     // By default, load the first file into the text window. 
 539     if (event
.GetNumberOfFiles() > 0) 
 541         LoadFile(event
.GetFiles()[0]); 
 545 void wxTextCtrl::OnChar(wxKeyEvent
& event
) 
 547     // Indicates that we should generate a normal command, because 
 548     // we're letting default behaviour happen (otherwise it's vetoed 
 549     // by virtue of overriding OnChar) 
 550     m_processedDefault 
= true; 
 552     if (m_tempCallbackStruct
) 
 554         XmTextVerifyCallbackStruct 
*textStruct 
= 
 555             (XmTextVerifyCallbackStruct 
*) m_tempCallbackStruct
; 
 556         textStruct
->doit 
= True
; 
 557         if (isascii(event
.m_keyCode
) && (textStruct
->text
->length 
== 1)) 
 559             textStruct
->text
->ptr
[0] = ((event
.m_keyCode 
== WXK_RETURN
) ? 10 : event
.m_keyCode
); 
 564 void wxTextCtrl::ChangeFont(bool keepOriginalSize
) 
 566     wxWindow::ChangeFont(keepOriginalSize
); 
 569 void wxTextCtrl::ChangeBackgroundColour() 
 571     wxWindow::ChangeBackgroundColour(); 
 573     /* TODO: should scrollbars be affected? Should probably have separate 
 574     * function to change them (by default, taken from wxSystemSettings) 
 576     if (m_windowStyle 
& wxTE_MULTILINE
) 
 578         Widget parent 
= XtParent ((Widget
) m_mainWidget
); 
 581         XtVaGetValues (parent
, 
 582             XmNhorizontalScrollBar
, &hsb
, 
 583             XmNverticalScrollBar
, &vsb
, 
 585         wxColour backgroundColour 
= wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
); 
 587             wxDoChangeBackgroundColour((WXWidget
) hsb
, backgroundColour
, true); 
 589             wxDoChangeBackgroundColour((WXWidget
) vsb
, backgroundColour
, true); 
 591         // MBN: why change parent background? 
 592         // DoChangeBackgroundColour((WXWidget) parent, m_backgroundColour, true); 
 596 void wxTextCtrl::ChangeForegroundColour() 
 598     wxWindow::ChangeForegroundColour(); 
 600     if (m_windowStyle 
& wxTE_MULTILINE
) 
 602         Widget parent 
= XtParent ((Widget
) m_mainWidget
); 
 605         XtVaGetValues (parent
, 
 606             XmNhorizontalScrollBar
, &hsb
, 
 607             XmNverticalScrollBar
, &vsb
, 
 610             /* TODO: should scrollbars be affected? Should probably have separate 
 611             * function to change them (by default, taken from wxSystemSettings) 
 613             DoChangeForegroundColour((WXWidget) hsb, m_foregroundColour); 
 615             DoChangeForegroundColour((WXWidget) vsb, m_foregroundColour); 
 617         wxDoChangeForegroundColour((WXWidget
) parent
, m_foregroundColour
); 
 621 void wxTextCtrl::DoSendEvents(void *wxcbs
, long keycode
) 
 623     // we're in process of updating the text control 
 624     m_tempCallbackStruct 
= wxcbs
; 
 626     XmTextVerifyCallbackStruct 
*cbs 
= (XmTextVerifyCallbackStruct 
*)wxcbs
; 
 628     wxKeyEvent 
event (wxEVT_CHAR
); 
 629     event
.SetId(GetId()); 
 630     event
.m_keyCode 
= keycode
; 
 631     event
.SetEventObject(this); 
 633     // Only if wxTextCtrl::OnChar is called will this be set to True (and 
 634     // the character passed through) 
 637     GetEventHandler()->ProcessEvent(event
); 
 639     if ( !InSetValue() && m_processedDefault 
) 
 641         // Can generate a command 
 642         wxCommandEvent 
commandEvent(wxEVT_COMMAND_TEXT_UPDATED
, GetId()); 
 643         commandEvent
.SetEventObject(this); 
 644         ProcessCommand(commandEvent
); 
 647     // do it after the (user) event handlers processed the events because 
 648     // otherwise GetValue() would return incorrect (not yet updated value) 
 649     m_tempCallbackStruct 
= NULL
; 
 652 wxSize 
wxDoGetSingleTextCtrlBestSize( Widget textWidget
, 
 653                                       const wxWindow
* window 
) 
 655     Dimension xmargin
, ymargin
, highlight
, shadow
; 
 658     XtVaGetValues( textWidget
, 
 659                    XmNmarginWidth
, &xmargin
, 
 660                    XmNmarginHeight
, &ymargin
, 
 662                    XmNhighlightThickness
, &highlight
, 
 663                    XmNshadowThickness
, &shadow
, 
 670     window
->GetTextExtent( value
, &x
, &y 
); 
 672     if( x 
< 100 ) x 
= 100; 
 674     return wxSize( x 
+ 2 * xmargin 
+ 2 * highlight 
+ 2 * shadow
, 
 675                    // MBN: +2 necessary: Lesstif bug or mine? 
 676                    y 
+ 2 * ymargin 
+ 2 * highlight 
+ 2 * shadow 
+ 2 ); 
 679 wxSize 
wxTextCtrl::DoGetBestSize() const 
 683         wxSize best 
= wxControl::DoGetBestSize(); 
 685         if( best
.x 
< 110 ) best
.x 
= 110; 
 690         return wxWindow::DoGetBestSize(); 
 693 // ---------------------------------------------------------------------------- 
 694 // helpers and Motif callbacks 
 695 // ---------------------------------------------------------------------------- 
 697 static void MergeChangesIntoString(wxString
& value
, 
 698                                    XmTextVerifyCallbackStruct 
*cbs
) 
 701      * At least on my system (SunOS 4.1.3 + Motif 1.2), you need to think of 
 702      * every event as a replace event.  cbs->text->ptr gives the replacement 
 703      * text, cbs->startPos gives the index of the first char affected by the 
 704      * replace, and cbs->endPos gives the index one more than the last char 
 705      * affected by the replace (startPos == endPos implies an empty range). 
 706      * Hence, a deletion is represented by replacing all input text with a 
 707      * blank string ("", *not* NULL!).  A simple insertion that does not 
 708      * overwrite any text has startPos == endPos. 
 713         // easy case: the ol value was empty 
 714         value 
= cbs
->text
->ptr
; 
 718         // merge the changes into the value 
 719         const char * const passwd 
= value
; 
 720         int len 
= value
.length(); 
 722         len 
+= ( cbs
->text
->ptr 
? 
 723                  strlen(cbs
->text
->ptr
) : 
 724                  0 ) + 1;                      // + new text (if any) + NUL 
 725         len 
-= cbs
->endPos 
- cbs
->startPos
;    // - text from affected region. 
 727         char * newS 
= new char [len
]; 
 729              * insert 
= cbs
->text
->ptr
; 
 731         // Copy (old) text from passwd, up to the start posn of the change. 
 733         const char * p 
= passwd
; 
 734         for (i 
= 0; i 
< cbs
->startPos
; ++i
) 
 737         // Copy the text to be inserted). 
 742         // Finally, copy into newS any remaining text from passwd[endPos] on. 
 743         for (p 
= passwd 
+ cbs
->endPos
; *p
; ) 
 754 wxTextWindowChangedProc (Widget w
, XtPointer clientData
, XtPointer 
WXUNUSED(ptr
)) 
 756     if (!wxGetWindowFromTable(w
)) 
 757         // Widget has been deleted! 
 760     wxTextCtrl 
*tw 
= (wxTextCtrl 
*) clientData
; 
 761     tw
->SetModified(true); 
 765 wxTextWindowModifyProc (Widget 
WXUNUSED(w
), XtPointer clientData
, XmTextVerifyCallbackStruct 
*cbs
) 
 767     wxTextCtrl 
*tw 
= (wxTextCtrl 
*) clientData
; 
 768     tw
->m_processedDefault 
= false; 
 770     // First, do some stuff if it's a password control: in this case, we need 
 771     // to store the string inside the class because GetValue() can't retrieve 
 772     // it from the text ctrl. We do *not* do it in other circumstances because 
 773     // it would double the amount of memory needed. 
 775     if ( tw
->GetWindowStyleFlag() & wxTE_PASSWORD 
) 
 777         MergeChangesIntoString(tw
->m_value
, cbs
); 
 779         if ( cbs
->text
->length 
> 0 ) 
 782             for (i 
= 0; i 
< cbs
->text
->length
; ++i
) 
 783                 cbs
->text
->ptr
[i
] = '*'; 
 784             cbs
->text
->ptr
[i
] = '\0'; 
 791     // If we're already within an OnChar, return: probably a programmatic 
 793     if (tw
->m_tempCallbackStruct
) 
 796     // Check for a backspace 
 797     if (cbs
->startPos 
== (cbs
->currInsert 
- 1)) 
 799         tw
->DoSendEvents((void *)cbs
, WXK_DELETE
); 
 804     // Pasting operation: let it through without calling OnChar 
 805     if (cbs
->text
->length 
> 1) 
 808     // Something other than text 
 809     if (cbs
->text
->ptr 
== NULL
) 
 813     char ch 
= cbs
->text
->ptr
[0]; 
 814     tw
->DoSendEvents((void *)cbs
, ch 
== '\n' ? '\r' : ch
); 
 818 wxTextWindowGainFocusProc (Widget w
, XtPointer clientData
, XmAnyCallbackStruct 
*WXUNUSED(cbs
)) 
 820     if (!wxGetWindowFromTable(w
)) 
 823     wxTextCtrl 
*tw 
= (wxTextCtrl 
*) clientData
; 
 824     wxFocusEvent 
event(wxEVT_SET_FOCUS
, tw
->GetId()); 
 825     event
.SetEventObject(tw
); 
 826     tw
->GetEventHandler()->ProcessEvent(event
); 
 830 wxTextWindowLoseFocusProc (Widget w
, XtPointer clientData
, XmAnyCallbackStruct 
*WXUNUSED(cbs
)) 
 832     if (!wxGetWindowFromTable(w
)) 
 835     wxTextCtrl 
*tw 
= (wxTextCtrl 
*) clientData
; 
 836     wxFocusEvent 
event(wxEVT_KILL_FOCUS
, tw
->GetId()); 
 837     event
.SetEventObject(tw
); 
 838     tw
->GetEventHandler()->ProcessEvent(event
); 
 841 static void wxTextWindowActivateProc(Widget w
, XtPointer clientData
, 
 842                                      XmAnyCallbackStruct 
*WXUNUSED(ptr
)) 
 844     if (!wxGetWindowFromTable(w
)) 
 847     wxTextCtrl 
*tw 
= (wxTextCtrl 
*) clientData
; 
 849     if (tw
->InSetValue()) 
 852     wxCommandEvent 
event(wxEVT_COMMAND_TEXT_ENTER
); 
 853     event
.SetId(tw
->GetId()); 
 854     event
.SetEventObject(tw
); 
 855     tw
->ProcessCommand(event
); 
 858 void wxTextCtrl::OnCut(wxCommandEvent
& WXUNUSED(event
)) 
 863 void wxTextCtrl::OnCopy(wxCommandEvent
& WXUNUSED(event
)) 
 868 void wxTextCtrl::OnPaste(wxCommandEvent
& WXUNUSED(event
)) 
 873 void wxTextCtrl::OnUndo(wxCommandEvent
& WXUNUSED(event
)) 
 878 void wxTextCtrl::OnRedo(wxCommandEvent
& WXUNUSED(event
)) 
 883 void wxTextCtrl::OnUpdateCut(wxUpdateUIEvent
& event
) 
 885     event
.Enable( CanCut() ); 
 888 void wxTextCtrl::OnUpdateCopy(wxUpdateUIEvent
& event
) 
 890     event
.Enable( CanCopy() ); 
 893 void wxTextCtrl::OnUpdatePaste(wxUpdateUIEvent
& event
) 
 895     event
.Enable( CanPaste() ); 
 898 void wxTextCtrl::OnUpdateUndo(wxUpdateUIEvent
& event
) 
 900     event
.Enable( CanUndo() ); 
 903 void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent
& event
) 
 905     event
.Enable( CanRedo() );