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
)