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 switch( event
.KeyCode() )
416 if ( !(m_windowStyle
& wxTE_MULTILINE
) )
418 wxCommandEvent
event(wxEVT_COMMAND_TEXT_ENTER
, m_windowId
);
419 event
.SetEventObject( this );
420 if ( GetEventHandler()->ProcessEvent(event
) )
423 //else: multiline controls need Enter for themselves
428 // always produce navigation event - even if we process TAB
429 // ourselves the fact that we got here means that the user code
430 // decided to skip processing of this TAB - probably to let it
431 // do its default job.
433 // NB: Notice that Ctrl-Tab is handled elsewhere and Alt-Tab is
434 // handled by Windows
436 wxNavigationKeyEvent eventNav
;
437 eventNav
.SetDirection(!event
.ShiftDown());
438 eventNav
.SetWindowChange(FALSE
);
439 eventNav
.SetEventObject(this);
441 if ( GetEventHandler()->ProcessEvent(eventNav
) )
451 // don't just call event.Skip() because this will cause TABs and ENTERs
452 // be passed upwards and we don't always want this - instead process it
458 // The streambuf code was partly taken from chapter 3 by Jerry Schwarz of
459 // AT&T's "C++ Lanuage System Release 3.0 Library Manual" - Stein Somers
461 //=========================================================================
462 // Called then the buffer is full (gcc 2.6.3)
463 // or when "endl" is output (Borland 4.5)
464 //=========================================================================
465 // Class declaration using multiple inheritance doesn't work properly for
466 // Borland. See note in wb_text.h.
467 #ifndef NO_TEXT_WINDOW_STREAM
468 int wxTextCtrl::overflow(int c
)
470 // Make sure there is a holding area
471 if ( allocate()==EOF
)
473 wxError("Streambuf allocation failed","Internal error");
477 // Verify that there are no characters in get area
478 if ( gptr() && gptr() < egptr() )
480 wxError("Who's trespassing my get area?","Internal error");
487 // Make sure there is a put area
490 /* This doesn't seem to be fatal so comment out error message */
491 // wxError("Put area not opened","Internal error");
492 setp( base(), base() );
495 // Determine how many characters have been inserted but no consumed
496 int plen
= pptr() - pbase();
498 // Now Jerry relies on the fact that the buffer is at least 2 chars
499 // long, but the holding area "may be as small as 1" ???
500 // And we need an additional \0, so let's keep this inefficient but
503 // If c!=EOF, it is a character that must also be comsumed
504 int xtra
= c
==EOF
? 0 : 1;
506 // Write temporary C-string to wxTextWindow
508 char *txt
= new char[plen
+xtra
+1];
509 memcpy(txt
, pbase(), plen
);
510 txt
[plen
] = (char)c
; // append c
511 txt
[plen
+xtra
] = '\0'; // append '\0' or overwrite c
512 // If the put area already contained \0, output will be truncated there
518 setp(pbase(), epptr());
520 #if defined(__WATCOMC__)
522 #elif defined(zapeof) // HP-UX (all cfront based?)
525 return c
!=EOF
? c
: 0; // this should make everybody happy
529 //=========================================================================
530 // called then "endl" is output (gcc) or then explicit sync is done (Borland)
531 //=========================================================================
532 int wxTextCtrl::sync()
534 // Verify that there are no characters in get area
535 if ( gptr() && gptr() < egptr() )
537 wxError("Who's trespassing my get area?","Internal error");
541 if ( pptr() && pptr() > pbase() ) return overflow(EOF
);
545 int len = pptr() - pbase();
546 char *txt = new char[len+1];
547 strncpy(txt, pbase(), len);
550 setp(pbase(), epptr());
556 //=========================================================================
557 // Should not be called by a "ostream". Used by a "istream"
558 //=========================================================================
559 int wxTextCtrl::underflow()
565 wxTextCtrl
& wxTextCtrl::operator<<(const wxString
& s
)
571 wxTextCtrl
& wxTextCtrl::operator<<(float f
)
574 str
.Printf("%.2f", f
);
579 wxTextCtrl
& wxTextCtrl::operator<<(double d
)
582 str
.Printf("%.2f", d
);
587 wxTextCtrl
& wxTextCtrl::operator<<(int i
)
595 wxTextCtrl
& wxTextCtrl::operator<<(long i
)
598 str
.Printf("%ld", i
);
603 wxTextCtrl
& wxTextCtrl::operator<<(const char c
)