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 IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl, wxControl)
43 BEGIN_EVENT_TABLE(wxTextCtrl, wxControl)
44 EVT_DROP_FILES(wxTextCtrl::OnDropFiles)
45 EVT_CHAR(wxTextCtrl::OnChar)
49 wxTextCtrl::wxTextCtrl()
50 #ifndef NO_TEXT_WINDOW_STREAM
57 bool wxTextCtrl::Create(wxWindow *parent, wxWindowID id,
60 const wxSize& size, long style,
61 const wxValidator& validator,
64 m_macHorizontalBorder = 2 ; // additional pixels around the real control
65 m_macVerticalBorder = 2 ;
67 wxSize mySize = size ;
74 if ( UMAHasAppearance() )
79 MacPreControlCreate( parent , id , "" , pos , mySize ,style, validator , name , &bounds , title ) ;
81 m_macControl = UMANewControl( parent->GetMacRootWindow() , &bounds , "\p" , true , 0 , 0 , 1,
82 kControlEditTextProc , (long) this ) ;
83 MacPostControlCreate() ;
87 if( wxApp::s_macDefaultEncodingIsPC )
88 value = wxMacMakeMacStringFromPC( st ) ;
91 UMASetControlData( m_macControl, 0, kControlEditTextTextTag , value.Length() , (char*) ((const char*)value) ) ;
96 wxString wxTextCtrl::GetValue() const
99 UMAGetControlData( m_macControl, 0, kControlEditTextTextTag , 32767 , wxBuffer , &actualsize) ;
100 wxBuffer[actualsize] = 0 ;
101 if( wxApp::s_macDefaultEncodingIsPC )
102 return wxMacMakePCStringFromMac( wxBuffer ) ;
104 return wxString(wxBuffer);
107 void wxTextCtrl::SetValue(const wxString& st)
111 if( wxApp::s_macDefaultEncodingIsPC )
112 value = wxMacMakeMacStringFromPC( st ) ;
115 UMASetControlData( m_macControl, 0, kControlEditTextTextTag , value.Length() , (char*) ((const char*)value) ) ;
117 // MacInvalidateControl() ;
120 void wxTextCtrl::SetSize(int x, int y, int width, int height, int sizeFlags)
122 wxControl::SetSize( x , y , width , height , sizeFlags ) ;
125 // Clipboard operations
126 void wxTextCtrl::Copy()
131 UMAGetControlData( m_macControl , 0, kControlEditTextTEHandleTag , sizeof( TEHandle ) , (char*) &teH , &size ) ;
135 void wxTextCtrl::Cut()
140 UMAGetControlData( m_macControl , 0, kControlEditTextTEHandleTag , sizeof( TEHandle ) , (char*) &teH , &size ) ;
142 // MacInvalidateControl() ;
145 void wxTextCtrl::Paste()
150 UMAGetControlData( m_macControl , 0, kControlEditTextTEHandleTag , sizeof( TEHandle ) , (char*) &teH , &size ) ;
152 // MacInvalidateControl() ;
155 void wxTextCtrl::SetEditable(bool editable)
158 UMAActivateControl( m_macControl ) ;
160 UMADeactivateControl( m_macControl ) ;
163 void wxTextCtrl::SetInsertionPoint(long pos)
165 SetSelection( pos , pos ) ;
168 void wxTextCtrl::SetInsertionPointEnd()
170 long pos = GetLastPosition();
171 SetInsertionPoint(pos);
174 long wxTextCtrl::GetInsertionPoint() const
176 ControlEditTextSelectionRec selection ;
180 UMAGetControlData( m_macControl , 0, kControlEditTextTEHandleTag , sizeof( TEHandle ) , (char*) &teH , &size ) ;
181 // UMAGetControlData( m_macControl , 0, kControlEditTextSelectionTag , sizeof( selection ) , (char*) &selection , &size ) ;
182 return (**teH).selStart ;
185 long wxTextCtrl::GetLastPosition() const
187 ControlEditTextSelectionRec selection ;
191 UMAGetControlData( m_macControl , 0, kControlEditTextTEHandleTag , sizeof( TEHandle ) , (char*) &teH , &size ) ;
193 // UMAGetControlData( m_macControl , 0, kControlEditTextSelectionTag , sizeof( selection ) , (char*) &selection , &size ) ;
194 return (**teH).teLength ;
197 void wxTextCtrl::Replace(long from, long to, const wxString& value)
202 ControlEditTextSelectionRec selection ;
204 selection.selStart = from ;
205 selection.selEnd = to ;
206 UMASetControlData( m_macControl , 0, kControlEditTextSelectionTag , sizeof( selection ) , (char*) &selection ) ;
207 UMAGetControlData( m_macControl , 0, kControlEditTextTEHandleTag , sizeof( TEHandle ) , (char*) &teH , &size ) ;
208 TESetSelect( from , to , teH ) ;
210 TEInsert( value , value.Length() , teH ) ;
211 // MacInvalidateControl() ;
214 void wxTextCtrl::Remove(long from, long to)
219 ControlEditTextSelectionRec selection ;
221 selection.selStart = from ;
222 selection.selEnd = to ;
223 UMASetControlData( m_macControl , 0, kControlEditTextSelectionTag , sizeof( selection ) , (char*) &selection ) ;
224 UMAGetControlData( m_macControl , 0, kControlEditTextTEHandleTag , sizeof( TEHandle ) , (char*) &teH , &size ) ;
226 // MacInvalidateControl() ;
229 void wxTextCtrl::SetSelection(long from, long to)
231 ControlEditTextSelectionRec selection ;
235 UMAGetControlData( m_macControl , 0, kControlEditTextTEHandleTag , sizeof( TEHandle ) , (char*) &teH , &size ) ;
237 selection.selStart = from ;
238 selection.selEnd = to ;
240 UMASetControlData( m_macControl , 0, kControlEditTextSelectionTag , sizeof( selection ) , (char*) &selection ) ;
241 TESetSelect( selection.selStart , selection.selEnd , teH ) ;
244 bool wxTextCtrl::LoadFile(const wxString& file)
246 if (!wxFileExists(file))
254 ifstream input((char*) (const char*) file, ios::nocreate | ios::in);
256 ifstream input((char*) (const char*) file, ios::in);
260 struct stat stat_buf;
261 if (stat(file, &stat_buf) < 0)
263 // This may need to be a bigger buffer than the file size suggests,
264 // if it's a UNIX file. Give it an extra 1000 just in case.
265 char *tmp_buffer = (char*)malloc((size_t)(stat_buf.st_size+1+1000));
268 while (!input.eof() && input.peek() != EOF)
270 input.getline(wxBuffer, 500);
271 int len = strlen(wxBuffer);
273 wxBuffer[len+1] = 10;
275 strcpy(tmp_buffer+pos, wxBuffer);
276 pos += strlen(wxBuffer);
289 // If file is null, try saved file name first
290 // Returns TRUE if succeeds.
291 bool wxTextCtrl::SaveFile(const wxString& file)
293 wxString theFile(file);
295 theFile = m_fileName;
298 m_fileName = theFile;
300 ofstream output((char*) (const char*) theFile);
304 // TODO get and save text
309 void wxTextCtrl::WriteText(const wxString& text)
314 memcpy( wxBuffer, text , text.Length() ) ;
315 wxBuffer[text.Length() ] = 0 ;
316 // wxMacConvertNewlines( wxBuffer , wxBuffer ) ;
318 UMAGetControlData( m_macControl , 0, kControlEditTextTEHandleTag , sizeof( TEHandle ) , (char*) &teH , &size ) ;
320 TEInsert( wxBuffer , strlen( wxBuffer) , teH ) ;
324 void wxTextCtrl::AppendText(const wxString& text)
326 SetInsertionPointEnd();
330 void wxTextCtrl::Clear()
334 ControlEditTextSelectionRec selection ;
336 selection.selStart = 0 ;
337 selection.selEnd = 32767 ;
339 UMASetControlData( m_macControl , 0, kControlEditTextSelectionTag , sizeof( selection ) , (char*) &selection ) ;
341 UMAGetControlData( m_macControl , 0, kControlEditTextTEHandleTag , sizeof( TEHandle ) , (char*) &teH , &size ) ;
343 // MacInvalidateControl() ;
346 bool wxTextCtrl::IsModified() const
351 // Makes 'unmodified'
352 void wxTextCtrl::DiscardEdits()
357 int wxTextCtrl::GetNumberOfLines() const
363 long wxTextCtrl::XYToPosition(long x, long y) const
369 void wxTextCtrl::PositionToXY(long pos, long *x, long *y) const
374 void wxTextCtrl::ShowPosition(long pos)
379 int wxTextCtrl::GetLineLength(long lineNo) const
381 return GetValue().Length();
384 wxString wxTextCtrl::GetLineText(long lineNo) const
393 void wxTextCtrl::Command(wxCommandEvent & event)
395 SetValue (event.GetString());
396 ProcessCommand (event);
399 void wxTextCtrl::OnDropFiles(wxDropFilesEvent& event)
401 // By default, load the first file into the text window.
402 if (event.GetNumberOfFiles() > 0)
404 LoadFile(event.GetFiles()[0]);
408 void wxTextCtrl::OnChar(wxKeyEvent& event)
410 switch( event.KeyCode() )
414 if ( !(m_windowStyle & wxTE_MULTILINE) )
416 wxCommandEvent event(wxEVT_COMMAND_TEXT_ENTER, m_windowId);
417 event.SetEventObject( this );
418 if ( GetEventHandler()->ProcessEvent(event) )
421 //else: multiline controls need Enter for themselves
426 // always produce navigation event - even if we process TAB
427 // ourselves the fact that we got here means that the user code
428 // decided to skip processing of this TAB - probably to let it
429 // do its default job.
431 // NB: Notice that Ctrl-Tab is handled elsewhere and Alt-Tab is
432 // handled by Windows
434 wxNavigationKeyEvent eventNav;
435 eventNav.SetDirection(!event.ShiftDown());
436 eventNav.SetWindowChange(FALSE);
437 eventNav.SetEventObject(this);
439 if ( GetEventHandler()->ProcessEvent(eventNav) )
449 // don't just call event.Skip() because this will cause TABs and ENTERs
450 // be passed upwards and we don't always want this - instead process it
456 // The streambuf code was partly taken from chapter 3 by Jerry Schwarz of
457 // AT&T's "C++ Lanuage System Release 3.0 Library Manual" - Stein Somers
459 //=========================================================================
460 // Called then the buffer is full (gcc 2.6.3)
461 // or when "endl" is output (Borland 4.5)
462 //=========================================================================
463 // Class declaration using multiple inheritance doesn't work properly for
464 // Borland. See note in wb_text.h.
465 #ifndef NO_TEXT_WINDOW_STREAM
466 int wxTextCtrl::overflow(int c)
468 // Make sure there is a holding area
469 if ( allocate()==EOF )
471 wxError("Streambuf allocation failed","Internal error");
475 // Verify that there are no characters in get area
476 if ( gptr() && gptr() < egptr() )
478 wxError("Who's trespassing my get area?","Internal error");
485 // Make sure there is a put area
488 /* This doesn't seem to be fatal so comment out error message */
489 // wxError("Put area not opened","Internal error");
490 setp( base(), base() );
493 // Determine how many characters have been inserted but no consumed
494 int plen = pptr() - pbase();
496 // Now Jerry relies on the fact that the buffer is at least 2 chars
497 // long, but the holding area "may be as small as 1" ???
498 // And we need an additional \0, so let's keep this inefficient but
501 // If c!=EOF, it is a character that must also be comsumed
502 int xtra = c==EOF? 0 : 1;
504 // Write temporary C-string to wxTextWindow
506 char *txt = new char[plen+xtra+1];
507 memcpy(txt, pbase(), plen);
508 txt[plen] = (char)c; // append c
509 txt[plen+xtra] = '\0'; // append '\0' or overwrite c
510 // If the put area already contained \0, output will be truncated there
516 setp(pbase(), epptr());
518 #if defined(__WATCOMC__)
520 #elif defined(zapeof) // HP-UX (all cfront based?)
523 return c!=EOF ? c : 0; // this should make everybody happy
527 //=========================================================================
528 // called then "endl" is output (gcc) or then explicit sync is done (Borland)
529 //=========================================================================
530 int wxTextCtrl::sync()
532 // Verify that there are no characters in get area
533 if ( gptr() && gptr() < egptr() )
535 wxError("Who's trespassing my get area?","Internal error");
539 if ( pptr() && pptr() > pbase() ) return overflow(EOF);
543 int len = pptr() - pbase();
544 char *txt = new char[len+1];
545 strncpy(txt, pbase(), len);
548 setp(pbase(), epptr());
554 //=========================================================================
555 // Should not be called by a "ostream". Used by a "istream"
556 //=========================================================================
557 int wxTextCtrl::underflow()
563 wxTextCtrl& wxTextCtrl::operator<<(const wxString& s)
569 wxTextCtrl& wxTextCtrl::operator<<(float f)
572 str.Printf("%.2f", f);
577 wxTextCtrl& wxTextCtrl::operator<<(double d)
580 str.Printf("%.2f", d);
585 wxTextCtrl& wxTextCtrl::operator<<(int i)
593 wxTextCtrl& wxTextCtrl::operator<<(long i)
596 str.Printf("%ld", i);
601 wxTextCtrl& wxTextCtrl::operator<<(const char c)