1 /////////////////////////////////////////////////////////////////////////////
8 // Copyright: (c) AUTHOR
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "textctrl.h"
17 #include <sys/types.h>
24 #include "wx/textctrl.h"
25 #include "wx/settings.h"
26 #include "wx/filefn.h"
29 #if defined(__BORLANDC__) && !defined(__WIN32__)
39 #include "wx/mac/uma.h"
41 #if !USE_SHARED_LIBRARY
42 IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl
, wxControl
)
44 BEGIN_EVENT_TABLE(wxTextCtrl
, wxControl
)
45 EVT_DROP_FILES(wxTextCtrl::OnDropFiles
)
46 EVT_CHAR(wxTextCtrl::OnChar
)
51 wxTextCtrl::wxTextCtrl()
52 #ifndef NO_TEXT_WINDOW_STREAM
59 bool wxTextCtrl::Create(wxWindow
*parent
, wxWindowID id
,
62 const wxSize
& size
, long style
,
63 const wxValidator
& validator
,
66 m_macHorizontalBorder
= 2 ; // additional pixels around the real control
67 m_macVerticalBorder
= 2 ;
69 wxSize mySize
= size
;
76 if ( UMAHasAppearance() )
81 MacPreControlCreate( parent
, id
, "" , pos
, mySize
,style
, validator
, name
, &bounds
, title
) ;
83 m_macControl
= UMANewControl( parent
->GetMacRootWindow() , &bounds
, "\p" , true , 0 , 0 , 1,
84 kControlEditTextProc
, (long) this ) ;
85 MacPostControlCreate() ;
89 if( wxApp::s_macDefaultEncodingIsPC
)
90 value
= wxMacMakeMacStringFromPC( st
) ;
93 UMASetControlData( m_macControl
, 0, kControlEditTextTextTag
, value
.Length() , (char*) ((const char*)value
) ) ;
98 wxString
wxTextCtrl::GetValue() const
101 UMAGetControlData( m_macControl
, 0, kControlEditTextTextTag
, 32767 , wxBuffer
, &actualsize
) ;
102 wxBuffer
[actualsize
] = 0 ;
103 if( wxApp::s_macDefaultEncodingIsPC
)
104 return wxMacMakePCStringFromMac( wxBuffer
) ;
106 return wxString(wxBuffer
);
109 void wxTextCtrl::SetValue(const wxString
& st
)
113 if( wxApp::s_macDefaultEncodingIsPC
)
114 value
= wxMacMakeMacStringFromPC( st
) ;
117 UMASetControlData( m_macControl
, 0, kControlEditTextTextTag
, value
.Length() , (char*) ((const char*)value
) ) ;
119 // MacInvalidateControl() ;
122 void wxTextCtrl::SetSize(int x
, int y
, int width
, int height
, int sizeFlags
)
124 wxControl::SetSize( x
, y
, width
, height
, sizeFlags
) ;
127 // Clipboard operations
128 void wxTextCtrl::Copy()
133 UMAGetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
137 void wxTextCtrl::Cut()
142 UMAGetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
144 // MacInvalidateControl() ;
147 void wxTextCtrl::Paste()
152 UMAGetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
154 // MacInvalidateControl() ;
157 void wxTextCtrl::SetEditable(bool editable
)
160 UMAActivateControl( m_macControl
) ;
162 UMADeactivateControl( m_macControl
) ;
165 void wxTextCtrl::SetInsertionPoint(long pos
)
167 SetSelection( pos
, pos
) ;
170 void wxTextCtrl::SetInsertionPointEnd()
172 long pos
= GetLastPosition();
173 SetInsertionPoint(pos
);
176 long wxTextCtrl::GetInsertionPoint() const
178 ControlEditTextSelectionRec selection
;
182 UMAGetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
183 // UMAGetControlData( m_macControl , 0, kControlEditTextSelectionTag , sizeof( selection ) , (char*) &selection , &size ) ;
184 return (**teH
).selStart
;
187 long wxTextCtrl::GetLastPosition() const
189 ControlEditTextSelectionRec selection
;
193 UMAGetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
195 // UMAGetControlData( m_macControl , 0, kControlEditTextSelectionTag , sizeof( selection ) , (char*) &selection , &size ) ;
196 return (**teH
).teLength
;
199 void wxTextCtrl::Replace(long from
, long to
, const wxString
& value
)
204 ControlEditTextSelectionRec selection
;
206 selection
.selStart
= from
;
207 selection
.selEnd
= to
;
208 UMASetControlData( m_macControl
, 0, kControlEditTextSelectionTag
, sizeof( selection
) , (char*) &selection
) ;
209 UMAGetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
210 TESetSelect( from
, to
, teH
) ;
212 TEInsert( value
, value
.Length() , teH
) ;
213 // MacInvalidateControl() ;
216 void wxTextCtrl::Remove(long from
, long to
)
221 ControlEditTextSelectionRec selection
;
223 selection
.selStart
= from
;
224 selection
.selEnd
= to
;
225 UMASetControlData( m_macControl
, 0, kControlEditTextSelectionTag
, sizeof( selection
) , (char*) &selection
) ;
226 UMAGetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
228 // MacInvalidateControl() ;
231 void wxTextCtrl::SetSelection(long from
, long to
)
233 ControlEditTextSelectionRec selection
;
237 UMAGetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
239 selection
.selStart
= from
;
240 selection
.selEnd
= to
;
242 UMASetControlData( m_macControl
, 0, kControlEditTextSelectionTag
, sizeof( selection
) , (char*) &selection
) ;
243 TESetSelect( selection
.selStart
, selection
.selEnd
, teH
) ;
246 bool wxTextCtrl::LoadFile(const wxString
& file
)
248 if (!wxFileExists(file
))
256 ifstream
input((char*) (const char*) file
, ios::nocreate
| ios::in
);
258 ifstream
input((char*) (const char*) file
, ios::in
);
262 struct stat stat_buf
;
263 if (stat(file
, &stat_buf
) < 0)
265 // This may need to be a bigger buffer than the file size suggests,
266 // if it's a UNIX file. Give it an extra 1000 just in case.
267 char *tmp_buffer
= (char*)malloc((size_t)(stat_buf
.st_size
+1+1000));
270 while (!input
.eof() && input
.peek() != EOF
)
272 input
.getline(wxBuffer
, 500);
273 int len
= strlen(wxBuffer
);
275 wxBuffer
[len
+1] = 10;
277 strcpy(tmp_buffer
+pos
, wxBuffer
);
278 pos
+= strlen(wxBuffer
);
291 // If file is null, try saved file name first
292 // Returns TRUE if succeeds.
293 bool wxTextCtrl::SaveFile(const wxString
& file
)
295 wxString
theFile(file
);
297 theFile
= m_fileName
;
300 m_fileName
= theFile
;
302 ofstream
output((char*) (const char*) theFile
);
306 // TODO get and save text
311 void wxTextCtrl::WriteText(const wxString
& text
)
316 memcpy( wxBuffer
, text
, text
.Length() ) ;
317 wxBuffer
[text
.Length() ] = 0 ;
318 // wxMacConvertNewlines( wxBuffer , wxBuffer ) ;
320 UMAGetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
322 TEInsert( wxBuffer
, strlen( wxBuffer
) , teH
) ;
326 void wxTextCtrl::AppendText(const wxString
& text
)
328 SetInsertionPointEnd();
332 void wxTextCtrl::Clear()
336 ControlEditTextSelectionRec selection
;
338 selection
.selStart
= 0 ;
339 selection
.selEnd
= 32767 ;
341 UMASetControlData( m_macControl
, 0, kControlEditTextSelectionTag
, sizeof( selection
) , (char*) &selection
) ;
343 UMAGetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
345 // MacInvalidateControl() ;
348 bool wxTextCtrl::IsModified() const
353 // Makes 'unmodified'
354 void wxTextCtrl::DiscardEdits()
359 int wxTextCtrl::GetNumberOfLines() const
365 long wxTextCtrl::XYToPosition(long x
, long y
) const
371 void wxTextCtrl::PositionToXY(long pos
, long *x
, long *y
) const
376 void wxTextCtrl::ShowPosition(long pos
)
381 int wxTextCtrl::GetLineLength(long lineNo
) const
383 return GetValue().Length();
386 wxString
wxTextCtrl::GetLineText(long lineNo
) const
395 void wxTextCtrl::Command(wxCommandEvent
& event
)
397 SetValue (event
.GetString());
398 ProcessCommand (event
);
401 void wxTextCtrl::OnDropFiles(wxDropFilesEvent
& event
)
403 // By default, load the first file into the text window.
404 if (event
.GetNumberOfFiles() > 0)
406 LoadFile(event
.GetFiles()[0]);
410 void wxTextCtrl::OnChar(wxKeyEvent
& event
)
412 bool handleIt
= true ;
413 switch( event
.KeyCode() )
417 /* Oh yes it will, because we also specify DLGC_WANTCHARS
418 wxASSERT_MSG( m_windowStyle & wxTE_PROCESS_ENTER,
419 "this text ctrl should never receive return" );
422 if ( (m_windowStyle
& wxTE_MULTILINE
) == 0 )
424 wxWindow
* parent
= GetParent() ;
427 if ( parent
->GetDefaultItem() )
429 wxButton
*defaultBtn
= parent
->GetDefaultItem() ;
430 wxCommandEvent
event(wxEVT_COMMAND_BUTTON_CLICKED
, defaultBtn
->GetId() );
431 event
.SetEventObject(defaultBtn
);
432 defaultBtn
->Command(event
);
435 parent
= parent
->GetParent() ;
441 // only produce navigation event if we don't process TAB ourself or
442 // if it's a Shift-Tab keypress (we assume nobody will ever need
443 // this key combo for himself)
445 // NB: Notice that Ctrl-Tab is handled elsewhere and Alt-Tab is
446 // handled by Windows
447 if ( event
.ShiftDown() || !(m_windowStyle
& wxTE_PROCESS_TAB
) )
449 wxNavigationKeyEvent eventNav
;
450 eventNav
.SetDirection(!event
.ShiftDown());
451 eventNav
.SetWindowChange(FALSE
);
452 eventNav
.SetEventObject(this);
454 if ( GetEventHandler()->ProcessEvent(eventNav
) )
461 EventRecord
*ev
= wxTheApp
->MacGetCurrentEvent() ;
464 keychar
= short(ev
->message
& charCodeMask
);
465 keycode
= short(ev
->message
& keyCodeMask
) >> 8 ;
466 UMAHandleControlKey( m_macControl
, keycode
, keychar
, ev
->modifiers
) ;
467 if ( keychar
>= 0x20 )
470 wxCommandEvent
event(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
);
471 wxString
val(GetValue());
473 event
.m_commandString
= WXSTRINGCAST val
;
474 event
.SetEventObject( this );
475 ProcessCommand(event
);
480 // The streambuf code was partly taken from chapter 3 by Jerry Schwarz of
481 // AT&T's "C++ Lanuage System Release 3.0 Library Manual" - Stein Somers
483 //=========================================================================
484 // Called then the buffer is full (gcc 2.6.3)
485 // or when "endl" is output (Borland 4.5)
486 //=========================================================================
487 // Class declaration using multiple inheritance doesn't work properly for
488 // Borland. See note in wb_text.h.
489 #ifndef NO_TEXT_WINDOW_STREAM
490 int wxTextCtrl::overflow(int c
)
492 // Make sure there is a holding area
493 if ( allocate()==EOF
)
495 wxError("Streambuf allocation failed","Internal error");
499 // Verify that there are no characters in get area
500 if ( gptr() && gptr() < egptr() )
502 wxError("Who's trespassing my get area?","Internal error");
509 // Make sure there is a put area
512 /* This doesn't seem to be fatal so comment out error message */
513 // wxError("Put area not opened","Internal error");
514 setp( base(), base() );
517 // Determine how many characters have been inserted but no consumed
518 int plen
= pptr() - pbase();
520 // Now Jerry relies on the fact that the buffer is at least 2 chars
521 // long, but the holding area "may be as small as 1" ???
522 // And we need an additional \0, so let's keep this inefficient but
525 // If c!=EOF, it is a character that must also be comsumed
526 int xtra
= c
==EOF
? 0 : 1;
528 // Write temporary C-string to wxTextWindow
530 char *txt
= new char[plen
+xtra
+1];
531 memcpy(txt
, pbase(), plen
);
532 txt
[plen
] = (char)c
; // append c
533 txt
[plen
+xtra
] = '\0'; // append '\0' or overwrite c
534 // If the put area already contained \0, output will be truncated there
540 setp(pbase(), epptr());
542 #if defined(__WATCOMC__)
544 #elif defined(zapeof) // HP-UX (all cfront based?)
547 return c
!=EOF
? c
: 0; // this should make everybody happy
551 //=========================================================================
552 // called then "endl" is output (gcc) or then explicit sync is done (Borland)
553 //=========================================================================
554 int wxTextCtrl::sync()
556 // Verify that there are no characters in get area
557 if ( gptr() && gptr() < egptr() )
559 wxError("Who's trespassing my get area?","Internal error");
563 if ( pptr() && pptr() > pbase() ) return overflow(EOF
);
567 int len = pptr() - pbase();
568 char *txt = new char[len+1];
569 strncpy(txt, pbase(), len);
572 setp(pbase(), epptr());
578 //=========================================================================
579 // Should not be called by a "ostream". Used by a "istream"
580 //=========================================================================
581 int wxTextCtrl::underflow()
587 wxTextCtrl
& wxTextCtrl::operator<<(const wxString
& s
)
593 wxTextCtrl
& wxTextCtrl::operator<<(float f
)
596 str
.Printf("%.2f", f
);
601 wxTextCtrl
& wxTextCtrl::operator<<(double d
)
604 str
.Printf("%.2f", d
);
609 wxTextCtrl
& wxTextCtrl::operator<<(int i
)
617 wxTextCtrl
& wxTextCtrl::operator<<(long i
)
620 str
.Printf("%ld", i
);
625 wxTextCtrl
& wxTextCtrl::operator<<(const char c
)