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