]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/mac/textctrl.cpp
??
[wxWidgets.git] / src / mac / textctrl.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: textctrl.cpp
3// Purpose: wxTextCtrl
4// Author: AUTHOR
5// Modified by:
6// Created: ??/??/98
7// RCS-ID: $Id$
8// Copyright: (c) AUTHOR
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
13#pragma implementation "textctrl.h"
14#endif
15
16#ifndef __WXMAC__
17#include <sys/types.h>
18#include <sys/stat.h>
19#else
20#include <stat.h>
21#endif
22#include <fstream.h>
23
24#include "wx/textctrl.h"
25#include "wx/settings.h"
26#include "wx/filefn.h"
27#include "wx/utils.h"
28
29#if defined(__BORLANDC__) && !defined(__WIN32__)
30#include <alloc.h>
31#else
32#ifndef __MWERKS__
33#ifndef __GNUWIN32__
34#include <malloc.h>
35#endif
36#endif
37#endif
38
39#include "wx/mac/uma.h"
40
41IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl, wxControl)
42
43BEGIN_EVENT_TABLE(wxTextCtrl, wxControl)
44 EVT_DROP_FILES(wxTextCtrl::OnDropFiles)
45 EVT_CHAR(wxTextCtrl::OnChar)
46END_EVENT_TABLE()
47
48// Text item
49wxTextCtrl::wxTextCtrl()
50#ifndef NO_TEXT_WINDOW_STREAM
51 :streambuf()
52#endif
53{
54 m_fileName = "";
55}
56
57bool wxTextCtrl::Create(wxWindow *parent, wxWindowID id,
58 const wxString& st,
59 const wxPoint& pos,
60 const wxSize& size, long style,
61 const wxValidator& validator,
62 const wxString& name)
63{
64 m_macHorizontalBorder = 2 ; // additional pixels around the real control
65 m_macVerticalBorder = 2 ;
66
67 wxSize mySize = size ;
68
69 Rect bounds ;
70 Str255 title ;
71
72 if ( mySize.y == -1 )
73 {
74 if ( UMAHasAppearance() )
75 mySize.y = 16 ;
76 else
77 mySize.y = 24 ;
78 }
79 MacPreControlCreate( parent , id , "" , pos , mySize ,style, validator , name , &bounds , title ) ;
80
81 m_macControl = UMANewControl( parent->GetMacRootWindow() , &bounds , "\p" , true , 0 , 0 , 1,
82 kControlEditTextProc , (long) this ) ;
83 MacPostControlCreate() ;
84
85 wxString value ;
86
87 if( wxApp::s_macDefaultEncodingIsPC )
88 value = wxMacMakeMacStringFromPC( st ) ;
89 else
90 value = st ;
91 UMASetControlData( m_macControl, 0, kControlEditTextTextTag , value.Length() , (char*) ((const char*)value) ) ;
92
93 return TRUE;
94}
95
96wxString wxTextCtrl::GetValue() const
97{
98 Size actualsize;
99 UMAGetControlData( m_macControl, 0, kControlEditTextTextTag , 32767 , wxBuffer , &actualsize) ;
100 wxBuffer[actualsize] = 0 ;
101 if( wxApp::s_macDefaultEncodingIsPC )
102 return wxMacMakePCStringFromMac( wxBuffer ) ;
103 else
104 return wxString(wxBuffer);
105}
106
107void wxTextCtrl::SetValue(const wxString& st)
108{
109 wxString value ;
110
111 if( wxApp::s_macDefaultEncodingIsPC )
112 value = wxMacMakeMacStringFromPC( st ) ;
113 else
114 value = st ;
115 UMASetControlData( m_macControl, 0, kControlEditTextTextTag , value.Length() , (char*) ((const char*)value) ) ;
116 Refresh() ;
117// MacInvalidateControl() ;
118}
119
120void wxTextCtrl::SetSize(int x, int y, int width, int height, int sizeFlags)
121{
122 wxControl::SetSize( x , y , width , height , sizeFlags ) ;
123}
124
125// Clipboard operations
126void wxTextCtrl::Copy()
127{
128 TEHandle teH ;
129 long size ;
130
131 UMAGetControlData( m_macControl , 0, kControlEditTextTEHandleTag , sizeof( TEHandle ) , (char*) &teH , &size ) ;
132 TECopy( teH ) ;
133}
134
135void wxTextCtrl::Cut()
136{
137 TEHandle teH ;
138 long size ;
139
140 UMAGetControlData( m_macControl , 0, kControlEditTextTEHandleTag , sizeof( TEHandle ) , (char*) &teH , &size ) ;
141 TECut( teH ) ;
142// MacInvalidateControl() ;
143}
144
145void wxTextCtrl::Paste()
146{
147 TEHandle teH ;
148 long size ;
149
150 UMAGetControlData( m_macControl , 0, kControlEditTextTEHandleTag , sizeof( TEHandle ) , (char*) &teH , &size ) ;
151 TEPaste( teH ) ;
152// MacInvalidateControl() ;
153}
154
155void wxTextCtrl::SetEditable(bool editable)
156{
157 if ( editable )
158 UMAActivateControl( m_macControl ) ;
159 else
160 UMADeactivateControl( m_macControl ) ;
161}
162
163void wxTextCtrl::SetInsertionPoint(long pos)
164{
165 SetSelection( pos , pos ) ;
166}
167
168void wxTextCtrl::SetInsertionPointEnd()
169{
170 long pos = GetLastPosition();
171 SetInsertionPoint(pos);
172}
173
174long wxTextCtrl::GetInsertionPoint() const
175{
176 ControlEditTextSelectionRec selection ;
177 TEHandle teH ;
178 long size ;
179
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 ;
183}
184
185long wxTextCtrl::GetLastPosition() const
186{
187 ControlEditTextSelectionRec selection ;
188 TEHandle teH ;
189 long size ;
190
191 UMAGetControlData( m_macControl , 0, kControlEditTextTEHandleTag , sizeof( TEHandle ) , (char*) &teH , &size ) ;
192
193// UMAGetControlData( m_macControl , 0, kControlEditTextSelectionTag , sizeof( selection ) , (char*) &selection , &size ) ;
194 return (**teH).teLength ;
195}
196
197void wxTextCtrl::Replace(long from, long to, const wxString& value)
198{
199 TEHandle teH ;
200 long size ;
201
202 ControlEditTextSelectionRec selection ;
203
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 ) ;
209 TEDelete( teH ) ;
210 TEInsert( value , value.Length() , teH ) ;
211// MacInvalidateControl() ;
212}
213
214void wxTextCtrl::Remove(long from, long to)
215{
216 TEHandle teH ;
217 long size ;
218
219 ControlEditTextSelectionRec selection ;
220
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 ) ;
225 TEDelete( teH ) ;
226// MacInvalidateControl() ;
227}
228
229void wxTextCtrl::SetSelection(long from, long to)
230{
231 ControlEditTextSelectionRec selection ;
232 TEHandle teH ;
233 long size ;
234
235 UMAGetControlData( m_macControl , 0, kControlEditTextTEHandleTag , sizeof( TEHandle ) , (char*) &teH , &size ) ;
236
237 selection.selStart = from ;
238 selection.selEnd = to ;
239
240 UMASetControlData( m_macControl , 0, kControlEditTextSelectionTag , sizeof( selection ) , (char*) &selection ) ;
241 TESetSelect( selection.selStart , selection.selEnd , teH ) ;
242}
243
244bool wxTextCtrl::LoadFile(const wxString& file)
245{
246 if (!wxFileExists(file))
247 return FALSE;
248
249 m_fileName = file;
250
251 Clear();
252
253#ifndef __WXMAC__
254 ifstream input((char*) (const char*) file, ios::nocreate | ios::in);
255#else
256 ifstream input((char*) (const char*) file, ios::in);
257#endif
258 if (!input.bad())
259 {
260 struct stat stat_buf;
261 if (stat(file, &stat_buf) < 0)
262 return FALSE;
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));
266 long no_lines = 0;
267 long pos = 0;
268 while (!input.eof() && input.peek() != EOF)
269 {
270 input.getline(wxBuffer, 500);
271 int len = strlen(wxBuffer);
272 wxBuffer[len] = 13;
273 wxBuffer[len+1] = 10;
274 wxBuffer[len+2] = 0;
275 strcpy(tmp_buffer+pos, wxBuffer);
276 pos += strlen(wxBuffer);
277 no_lines++;
278 }
279
280 // TODO add line
281
282 free(tmp_buffer);
283
284 return TRUE;
285 }
286 return FALSE;
287}
288
289// If file is null, try saved file name first
290// Returns TRUE if succeeds.
291bool wxTextCtrl::SaveFile(const wxString& file)
292{
293 wxString theFile(file);
294 if (theFile == "")
295 theFile = m_fileName;
296 if (theFile == "")
297 return FALSE;
298 m_fileName = theFile;
299
300 ofstream output((char*) (const char*) theFile);
301 if (output.bad())
302 return FALSE;
303
304 // TODO get and save text
305
306 return FALSE;
307}
308
309void wxTextCtrl::WriteText(const wxString& text)
310{
311 TEHandle teH ;
312 long size ;
313
314 memcpy( wxBuffer, text , text.Length() ) ;
315 wxBuffer[text.Length() ] = 0 ;
316// wxMacConvertNewlines( wxBuffer , wxBuffer ) ;
317
318 UMAGetControlData( m_macControl , 0, kControlEditTextTEHandleTag , sizeof( TEHandle ) , (char*) &teH , &size ) ;
319
320 TEInsert( wxBuffer , strlen( wxBuffer) , teH ) ;
321 Refresh() ;
322}
323
324void wxTextCtrl::AppendText(const wxString& text)
325{
326 SetInsertionPointEnd();
327 WriteText(text);
328}
329
330void wxTextCtrl::Clear()
331{
332 TEHandle teH ;
333 long size ;
334 ControlEditTextSelectionRec selection ;
335
336 selection.selStart = 0 ;
337 selection.selEnd = 32767 ;
338
339 UMASetControlData( m_macControl , 0, kControlEditTextSelectionTag , sizeof( selection ) , (char*) &selection ) ;
340
341 UMAGetControlData( m_macControl , 0, kControlEditTextTEHandleTag , sizeof( TEHandle ) , (char*) &teH , &size ) ;
342 TECut( teH ) ;
343// MacInvalidateControl() ;
344}
345
346bool wxTextCtrl::IsModified() const
347{
348 return TRUE;
349}
350
351// Makes 'unmodified'
352void wxTextCtrl::DiscardEdits()
353{
354 // TODO
355}
356
357int wxTextCtrl::GetNumberOfLines() const
358{
359 // TODO
360 return 0;
361}
362
363long wxTextCtrl::XYToPosition(long x, long y) const
364{
365 // TODO
366 return 0;
367}
368
369void wxTextCtrl::PositionToXY(long pos, long *x, long *y) const
370{
371 // TODO
372}
373
374void wxTextCtrl::ShowPosition(long pos)
375{
376 // TODO
377}
378
379int wxTextCtrl::GetLineLength(long lineNo) const
380{
381 return GetValue().Length();
382}
383
384wxString wxTextCtrl::GetLineText(long lineNo) const
385{
386 return GetValue();
387}
388
389/*
390 * Text item
391 */
392
393void wxTextCtrl::Command(wxCommandEvent & event)
394{
395 SetValue (event.GetString());
396 ProcessCommand (event);
397}
398
399void wxTextCtrl::OnDropFiles(wxDropFilesEvent& event)
400{
401 // By default, load the first file into the text window.
402 if (event.GetNumberOfFiles() > 0)
403 {
404 LoadFile(event.GetFiles()[0]);
405 }
406}
407
408void wxTextCtrl::OnChar(wxKeyEvent& event)
409{
410 switch( event.KeyCode() )
411 {
412 case WXK_RETURN:
413 {
414 if ( !(m_windowStyle & wxTE_MULTILINE) )
415 {
416 wxCommandEvent event(wxEVT_COMMAND_TEXT_ENTER, m_windowId);
417 event.SetEventObject( this );
418 if ( GetEventHandler()->ProcessEvent(event) )
419 return;
420 }
421 //else: multiline controls need Enter for themselves
422
423 break;
424 }
425 case WXK_TAB:
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.
430 //
431 // NB: Notice that Ctrl-Tab is handled elsewhere and Alt-Tab is
432 // handled by Windows
433 {
434 wxNavigationKeyEvent eventNav;
435 eventNav.SetDirection(!event.ShiftDown());
436 eventNav.SetWindowChange(FALSE);
437 eventNav.SetEventObject(this);
438
439 if ( GetEventHandler()->ProcessEvent(eventNav) )
440 return;
441 }
442 break;
443
444 default:
445 event.Skip();
446 return;
447 }
448
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
451 // right here
452
453 // FIXME
454 event.Skip();
455}
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
458
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
466int wxTextCtrl::overflow(int c)
467{
468 // Make sure there is a holding area
469 if ( allocate()==EOF )
470 {
471 wxError("Streambuf allocation failed","Internal error");
472 return EOF;
473 }
474
475 // Verify that there are no characters in get area
476 if ( gptr() && gptr() < egptr() )
477 {
478 wxError("Who's trespassing my get area?","Internal error");
479 return EOF;
480 }
481
482 // Reset get area
483 setg(0,0,0);
484
485 // Make sure there is a put area
486 if ( ! pptr() )
487 {
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() );
491 }
492
493 // Determine how many characters have been inserted but no consumed
494 int plen = pptr() - pbase();
495
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
499 // safe copy.
500
501 // If c!=EOF, it is a character that must also be comsumed
502 int xtra = c==EOF? 0 : 1;
503
504 // Write temporary C-string to wxTextWindow
505 {
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
511 AppendText(txt);
512 delete[] txt;
513 }
514
515 // Reset put area
516 setp(pbase(), epptr());
517
518#if defined(__WATCOMC__)
519 return __NOT_EOF;
520#elif defined(zapeof) // HP-UX (all cfront based?)
521 return zapeof(c);
522#else
523 return c!=EOF ? c : 0; // this should make everybody happy
524#endif
525}
526
527//=========================================================================
528// called then "endl" is output (gcc) or then explicit sync is done (Borland)
529//=========================================================================
530int wxTextCtrl::sync()
531{
532 // Verify that there are no characters in get area
533 if ( gptr() && gptr() < egptr() )
534 {
535 wxError("Who's trespassing my get area?","Internal error");
536 return EOF;
537 }
538
539 if ( pptr() && pptr() > pbase() ) return overflow(EOF);
540
541 return 0;
542/* OLD CODE
543 int len = pptr() - pbase();
544 char *txt = new char[len+1];
545 strncpy(txt, pbase(), len);
546 txt[len] = '\0';
547 (*this) << txt;
548 setp(pbase(), epptr());
549 delete[] txt;
550 return 0;
551*/
552}
553
554//=========================================================================
555// Should not be called by a "ostream". Used by a "istream"
556//=========================================================================
557int wxTextCtrl::underflow()
558{
559 return EOF;
560}
561#endif
562
563wxTextCtrl& wxTextCtrl::operator<<(const wxString& s)
564{
565 AppendText(s);
566 return *this;
567}
568
569wxTextCtrl& wxTextCtrl::operator<<(float f)
570{
571 wxString str;
572 str.Printf("%.2f", f);
573 AppendText(str);
574 return *this;
575}
576
577wxTextCtrl& wxTextCtrl::operator<<(double d)
578{
579 wxString str;
580 str.Printf("%.2f", d);
581 AppendText(str);
582 return *this;
583}
584
585wxTextCtrl& wxTextCtrl::operator<<(int i)
586{
587 wxString str;
588 str.Printf("%d", i);
589 AppendText(str);
590 return *this;
591}
592
593wxTextCtrl& wxTextCtrl::operator<<(long i)
594{
595 wxString str;
596 str.Printf("%ld", i);
597 AppendText(str);
598 return *this;
599}
600
601wxTextCtrl& wxTextCtrl::operator<<(const char c)
602{
603 char buf[2];
604
605 buf[0] = c;
606 buf[1] = 0;
607 AppendText(buf);
608 return *this;
609}
610