]> git.saurik.com Git - wxWidgets.git/blame - src/mac/textctrl.cpp
Removed Vadim's surplus code in clipboard.
[wxWidgets.git] / src / mac / textctrl.cpp
CommitLineData
e9576ca5
SC
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
519cb848
SC
39#include "wx/mac/uma.h"
40
e9576ca5
SC
41#if !USE_SHARED_LIBRARY
42IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl, wxControl)
43
44BEGIN_EVENT_TABLE(wxTextCtrl, wxControl)
45 EVT_DROP_FILES(wxTextCtrl::OnDropFiles)
519cb848 46 EVT_CHAR(wxTextCtrl::OnChar)
e9576ca5
SC
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,
519cb848 60 const wxString& st,
e9576ca5
SC
61 const wxPoint& pos,
62 const wxSize& size, long style,
63 const wxValidator& validator,
64 const wxString& name)
65{
519cb848
SC
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;
e9576ca5
SC
96}
97
98wxString wxTextCtrl::GetValue() const
99{
519cb848
SC
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);
e9576ca5
SC
107}
108
519cb848
SC
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() ;
e9576ca5
SC
120}
121
122void wxTextCtrl::SetSize(int x, int y, int width, int height, int sizeFlags)
123{
519cb848 124 wxControl::SetSize( x , y , width , height , sizeFlags ) ;
e9576ca5
SC
125}
126
127// Clipboard operations
128void wxTextCtrl::Copy()
129{
519cb848
SC
130 TEHandle teH ;
131 long size ;
132
133 UMAGetControlData( m_macControl , 0, kControlEditTextTEHandleTag , sizeof( TEHandle ) , (char*) &teH , &size ) ;
134 TECopy( teH ) ;
e9576ca5
SC
135}
136
137void wxTextCtrl::Cut()
138{
519cb848
SC
139 TEHandle teH ;
140 long size ;
141
142 UMAGetControlData( m_macControl , 0, kControlEditTextTEHandleTag , sizeof( TEHandle ) , (char*) &teH , &size ) ;
143 TECut( teH ) ;
144// MacInvalidateControl() ;
e9576ca5
SC
145}
146
147void wxTextCtrl::Paste()
148{
519cb848
SC
149 TEHandle teH ;
150 long size ;
151
152 UMAGetControlData( m_macControl , 0, kControlEditTextTEHandleTag , sizeof( TEHandle ) , (char*) &teH , &size ) ;
153 TEPaste( teH ) ;
154// MacInvalidateControl() ;
e9576ca5
SC
155}
156
157void wxTextCtrl::SetEditable(bool editable)
158{
519cb848
SC
159 if ( editable )
160 UMAActivateControl( m_macControl ) ;
161 else
162 UMADeactivateControl( m_macControl ) ;
e9576ca5
SC
163}
164
165void wxTextCtrl::SetInsertionPoint(long pos)
166{
519cb848 167 SetSelection( pos , pos ) ;
e9576ca5
SC
168}
169
170void wxTextCtrl::SetInsertionPointEnd()
171{
172 long pos = GetLastPosition();
173 SetInsertionPoint(pos);
174}
175
176long wxTextCtrl::GetInsertionPoint() const
177{
519cb848
SC
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 ;
e9576ca5
SC
185}
186
187long wxTextCtrl::GetLastPosition() const
188{
519cb848
SC
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 ;
e9576ca5
SC
197}
198
199void wxTextCtrl::Replace(long from, long to, const wxString& value)
200{
519cb848
SC
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() ;
e9576ca5
SC
214}
215
216void wxTextCtrl::Remove(long from, long to)
217{
519cb848
SC
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() ;
e9576ca5
SC
229}
230
231void wxTextCtrl::SetSelection(long from, long to)
232{
519cb848
SC
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 ) ;
e9576ca5
SC
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{
519cb848
SC
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() ;
e9576ca5
SC
324}
325
13c21be5
HH
326void wxTextCtrl::AppendText(const wxString& text)
327{
519cb848
SC
328 SetInsertionPointEnd();
329 WriteText(text);
13c21be5
HH
330}
331
e9576ca5
SC
332void wxTextCtrl::Clear()
333{
519cb848
SC
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() ;
e9576ca5
SC
346}
347
348bool wxTextCtrl::IsModified() const
349{
519cb848 350 return TRUE;
e9576ca5
SC
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{
519cb848 383 return GetValue().Length();
e9576ca5
SC
384}
385
386wxString wxTextCtrl::GetLineText(long lineNo) const
387{
519cb848 388 return GetValue();
e9576ca5
SC
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
519cb848
SC
410void wxTextCtrl::OnChar(wxKeyEvent& event)
411{
412 bool handleIt = true ;
413 switch( event.KeyCode() )
414 {
415 case WXK_RETURN:
416 {
417/* Oh yes it will, because we also specify DLGC_WANTCHARS
418 wxASSERT_MSG( m_windowStyle & wxTE_PROCESS_ENTER,
419 "this text ctrl should never receive return" );
420*/
421
422 if ( (m_windowStyle & wxTE_MULTILINE) == 0 )
423 {
424 wxWindow* parent = GetParent() ;
425 while( parent )
426 {
427 if ( parent->GetDefaultItem() )
428 {
429 wxButton *defaultBtn = parent->GetDefaultItem() ;
430 wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, defaultBtn->GetId() );
431 event.SetEventObject(defaultBtn);
432 defaultBtn->Command(event);
433 return ;
434 }
435 parent = parent->GetParent() ;
436 } ;
437 }
438 break;
439 }
440 case WXK_TAB:
441 // only produce navigation event if we don't process TAB ourself or
442 // if it's a Shift-Tab keypress (we assume nobody will ever need
443 // this key combo for himself)
444 //
445 // NB: Notice that Ctrl-Tab is handled elsewhere and Alt-Tab is
446 // handled by Windows
447 if ( event.ShiftDown() || !(m_windowStyle & wxTE_PROCESS_TAB) )
448 {
449 wxNavigationKeyEvent eventNav;
450 eventNav.SetDirection(!event.ShiftDown());
451 eventNav.SetWindowChange(FALSE);
452 eventNav.SetEventObject(this);
453
454 if ( GetEventHandler()->ProcessEvent(eventNav) )
455 return;
456 }
457 break;
458 }
459 if ( handleIt )
460 {
461 EventRecord *ev = wxTheApp->MacGetCurrentEvent() ;
462 short keycode ;
463 short keychar ;
464 keychar = short(ev->message & charCodeMask);
465 keycode = short(ev->message & keyCodeMask) >> 8 ;
466 UMAHandleControlKey( m_macControl , keycode , keychar , ev->modifiers ) ;
467 if ( keychar >= 0x20 )
468 {
469 {
470 wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, m_windowId);
471 wxString val(GetValue());
472 if ( !val.IsNull() )
473 event.m_commandString = WXSTRINGCAST val;
474 event.SetEventObject( this );
475 ProcessCommand(event);
476 }
477 }
478 }
479}
e9576ca5
SC
480// The streambuf code was partly taken from chapter 3 by Jerry Schwarz of
481// AT&T's "C++ Lanuage System Release 3.0 Library Manual" - Stein Somers
482
483//=========================================================================
484// Called then the buffer is full (gcc 2.6.3)
485// or when "endl" is output (Borland 4.5)
486//=========================================================================
487// Class declaration using multiple inheritance doesn't work properly for
488// Borland. See note in wb_text.h.
489#ifndef NO_TEXT_WINDOW_STREAM
490int wxTextCtrl::overflow(int c)
491{
492 // Make sure there is a holding area
493 if ( allocate()==EOF )
494 {
495 wxError("Streambuf allocation failed","Internal error");
496 return EOF;
497 }
498
499 // Verify that there are no characters in get area
500 if ( gptr() && gptr() < egptr() )
501 {
502 wxError("Who's trespassing my get area?","Internal error");
503 return EOF;
504 }
505
506 // Reset get area
507 setg(0,0,0);
508
509 // Make sure there is a put area
510 if ( ! pptr() )
511 {
512/* This doesn't seem to be fatal so comment out error message */
513// wxError("Put area not opened","Internal error");
514 setp( base(), base() );
515 }
516
517 // Determine how many characters have been inserted but no consumed
518 int plen = pptr() - pbase();
519
520 // Now Jerry relies on the fact that the buffer is at least 2 chars
521 // long, but the holding area "may be as small as 1" ???
522 // And we need an additional \0, so let's keep this inefficient but
523 // safe copy.
524
525 // If c!=EOF, it is a character that must also be comsumed
526 int xtra = c==EOF? 0 : 1;
527
528 // Write temporary C-string to wxTextWindow
529 {
530 char *txt = new char[plen+xtra+1];
531 memcpy(txt, pbase(), plen);
532 txt[plen] = (char)c; // append c
533 txt[plen+xtra] = '\0'; // append '\0' or overwrite c
534 // If the put area already contained \0, output will be truncated there
13c21be5 535 AppendText(txt);
e9576ca5
SC
536 delete[] txt;
537 }
538
539 // Reset put area
540 setp(pbase(), epptr());
541
542#if defined(__WATCOMC__)
543 return __NOT_EOF;
544#elif defined(zapeof) // HP-UX (all cfront based?)
545 return zapeof(c);
546#else
547 return c!=EOF ? c : 0; // this should make everybody happy
548#endif
549}
550
551//=========================================================================
552// called then "endl" is output (gcc) or then explicit sync is done (Borland)
553//=========================================================================
554int wxTextCtrl::sync()
555{
556 // Verify that there are no characters in get area
557 if ( gptr() && gptr() < egptr() )
558 {
559 wxError("Who's trespassing my get area?","Internal error");
560 return EOF;
561 }
562
563 if ( pptr() && pptr() > pbase() ) return overflow(EOF);
564
565 return 0;
566/* OLD CODE
567 int len = pptr() - pbase();
568 char *txt = new char[len+1];
569 strncpy(txt, pbase(), len);
570 txt[len] = '\0';
571 (*this) << txt;
572 setp(pbase(), epptr());
573 delete[] txt;
574 return 0;
575*/
576}
577
578//=========================================================================
579// Should not be called by a "ostream". Used by a "istream"
580//=========================================================================
581int wxTextCtrl::underflow()
582{
583 return EOF;
584}
585#endif
586
587wxTextCtrl& wxTextCtrl::operator<<(const wxString& s)
588{
13c21be5 589 AppendText(s);
e9576ca5
SC
590 return *this;
591}
592
593wxTextCtrl& wxTextCtrl::operator<<(float f)
594{
595 wxString str;
596 str.Printf("%.2f", f);
13c21be5 597 AppendText(str);
e9576ca5
SC
598 return *this;
599}
600
601wxTextCtrl& wxTextCtrl::operator<<(double d)
602{
603 wxString str;
604 str.Printf("%.2f", d);
13c21be5 605 AppendText(str);
e9576ca5
SC
606 return *this;
607}
608
609wxTextCtrl& wxTextCtrl::operator<<(int i)
610{
611 wxString str;
612 str.Printf("%d", i);
13c21be5 613 AppendText(str);
e9576ca5
SC
614 return *this;
615}
616
617wxTextCtrl& wxTextCtrl::operator<<(long i)
618{
619 wxString str;
620 str.Printf("%ld", i);
13c21be5 621 AppendText(str);
e9576ca5
SC
622 return *this;
623}
624
625wxTextCtrl& wxTextCtrl::operator<<(const char c)
626{
627 char buf[2];
628
629 buf[0] = c;
630 buf[1] = 0;
13c21be5 631 AppendText(buf);
e9576ca5
SC
632 return *this;
633}
634