]> git.saurik.com Git - wxWidgets.git/blame - src/mac/textctrl.cpp
mac changes : wxDC - removed doubly defined vars (inherited from base) and fixed...
[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
03e11df5
GD
16#ifdef __UNIX__
17 #include <sys/types.h>
18 #include <sys/stat.h>
e9576ca5 19#else
03e11df5 20 #include <stat.h>
e9576ca5
SC
21#endif
22#include <fstream.h>
23
03e11df5
GD
24#include "wx/app.h"
25#include "wx/button.h"
26#include "wx/panel.h"
e9576ca5
SC
27#include "wx/textctrl.h"
28#include "wx/settings.h"
29#include "wx/filefn.h"
30#include "wx/utils.h"
31
32#if defined(__BORLANDC__) && !defined(__WIN32__)
03e11df5
GD
33 #include <alloc.h>
34#elif !defined(__MWERKS__) && !defined(__GNUWIN32) && !defined(__WXMAC_X__)
35 #include <malloc.h>
e9576ca5
SC
36#endif
37
519cb848
SC
38#include "wx/mac/uma.h"
39
2f1ae414 40#if !USE_SHARED_LIBRARY
e9576ca5
SC
41IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl, wxControl)
42
43BEGIN_EVENT_TABLE(wxTextCtrl, wxControl)
44 EVT_DROP_FILES(wxTextCtrl::OnDropFiles)
519cb848 45 EVT_CHAR(wxTextCtrl::OnChar)
2f1ae414
SC
46 EVT_MENU(wxID_CUT, wxTextCtrl::OnCut)
47 EVT_MENU(wxID_COPY, wxTextCtrl::OnCopy)
48 EVT_MENU(wxID_PASTE, wxTextCtrl::OnPaste)
49 EVT_MENU(wxID_UNDO, wxTextCtrl::OnUndo)
50 EVT_MENU(wxID_REDO, wxTextCtrl::OnRedo)
51
52 EVT_UPDATE_UI(wxID_CUT, wxTextCtrl::OnUpdateCut)
53 EVT_UPDATE_UI(wxID_COPY, wxTextCtrl::OnUpdateCopy)
54 EVT_UPDATE_UI(wxID_PASTE, wxTextCtrl::OnUpdatePaste)
55 EVT_UPDATE_UI(wxID_UNDO, wxTextCtrl::OnUpdateUndo)
56 EVT_UPDATE_UI(wxID_REDO, wxTextCtrl::OnUpdateRedo)
e9576ca5 57END_EVENT_TABLE()
2f1ae414 58#endif
e9576ca5
SC
59
60// Text item
61wxTextCtrl::wxTextCtrl()
e9576ca5 62{
e9576ca5
SC
63}
64
2f1ae414
SC
65const short kVerticalMargin = 2 ;
66const short kHorizontalMargin = 2 ;
67
e9576ca5 68bool wxTextCtrl::Create(wxWindow *parent, wxWindowID id,
519cb848 69 const wxString& st,
e9576ca5
SC
70 const wxPoint& pos,
71 const wxSize& size, long style,
72 const wxValidator& validator,
73 const wxString& name)
74{
2f1ae414
SC
75 // base initialization
76 if ( !CreateBase(parent, id, pos, size, style, validator, name) )
77 return FALSE;
519cb848
SC
78
79 wxSize mySize = size ;
2f1ae414
SC
80 if ( UMAHasAppearance() )
81 {
82 m_macHorizontalBorder = 5 ; // additional pixels around the real control
83 m_macVerticalBorder = 5 ;
84 }
85 else
86 {
87 m_macHorizontalBorder = 0 ; // additional pixels around the real control
88 m_macVerticalBorder = 0 ;
89 }
90
519cb848
SC
91
92 Rect bounds ;
93 Str255 title ;
2f1ae414 94
519cb848
SC
95 if ( mySize.y == -1 )
96 {
97 if ( UMAHasAppearance() )
2f1ae414 98 mySize.y = 13 ;
519cb848
SC
99 else
100 mySize.y = 24 ;
2f1ae414
SC
101
102 mySize.y += 2 * m_macVerticalBorder ;
519cb848 103 }
2f1ae414 104
519cb848
SC
105 MacPreControlCreate( parent , id , "" , pos , mySize ,style, validator , name , &bounds , title ) ;
106
107 m_macControl = UMANewControl( parent->GetMacRootWindow() , &bounds , "\p" , true , 0 , 0 , 1,
2f1ae414 108 ( style & wxTE_PASSWORD ) ? kControlEditTextPasswordProc : kControlEditTextProc , (long) this ) ;
519cb848
SC
109 MacPostControlCreate() ;
110
111 wxString value ;
112
5b781a67
SC
113 {
114 TEHandle teH ;
115 long size ;
116
117 UMAGetControlData( m_macControl , 0, kControlEditTextTEHandleTag , sizeof( TEHandle ) , (char*) &teH , &size ) ;
118 (*teH)->lineHeight = -1 ;
119 }
120
519cb848
SC
121 if( wxApp::s_macDefaultEncodingIsPC )
122 value = wxMacMakeMacStringFromPC( st ) ;
123 else
124 value = st ;
2f1ae414 125 UMASetControlData( m_macControl, 0, ( m_windowStyle & wxTE_PASSWORD ) ? kControlEditTextPasswordTag : kControlEditTextTextTag , value.Length() , (char*) ((const char*)value) ) ;
519cb848
SC
126
127 return TRUE;
e9576ca5
SC
128}
129
130wxString wxTextCtrl::GetValue() const
131{
519cb848 132 Size actualsize;
2f1ae414 133 UMAGetControlData( m_macControl, 0, ( m_windowStyle & wxTE_PASSWORD ) ? kControlEditTextPasswordTag : kControlEditTextTextTag , 32767 , wxBuffer , &actualsize) ;
519cb848
SC
134 wxBuffer[actualsize] = 0 ;
135 if( wxApp::s_macDefaultEncodingIsPC )
136 return wxMacMakePCStringFromMac( wxBuffer ) ;
137 else
138 return wxString(wxBuffer);
e9576ca5
SC
139}
140
2f1ae414
SC
141void wxTextCtrl::GetSelection(long* from, long* to) const
142{
143 ControlEditTextSelectionRec selection ;
144 TEHandle teH ;
145 long size ;
146
147 UMAGetControlData( m_macControl , 0, kControlEditTextTEHandleTag , sizeof( TEHandle ) , (char*) &teH , &size ) ;
148
149 *from = (**teH).selStart;
150 *to = (**teH).selEnd;
151}
152
519cb848
SC
153void wxTextCtrl::SetValue(const wxString& st)
154{
155 wxString value ;
156
157 if( wxApp::s_macDefaultEncodingIsPC )
158 value = wxMacMakeMacStringFromPC( st ) ;
159 else
160 value = st ;
2f1ae414 161 UMASetControlData( m_macControl, 0, ( m_windowStyle & wxTE_PASSWORD ) ? kControlEditTextPasswordTag : kControlEditTextTextTag , value.Length() , (char*) ((const char*)value) ) ;
5b781a67 162 UMADrawControl( m_macControl ) ;
e9576ca5
SC
163}
164
e9576ca5
SC
165// Clipboard operations
166void wxTextCtrl::Copy()
167{
2f1ae414
SC
168 if (CanCopy())
169 {
170 TEHandle teH ;
171 long size ;
519cb848 172
2f1ae414
SC
173 UMAGetControlData( m_macControl , 0, kControlEditTextTEHandleTag , sizeof( TEHandle ) , (char*) &teH , &size ) ;
174 TECopy( teH ) ;
175#if TARGET_CARBON
176 OSStatus err ;
177 err = ClearCurrentScrap( );
178#else
179 OSErr err ;
180 err = ZeroScrap( );
181#endif
182 TEToScrap() ;
183 }
e9576ca5
SC
184}
185
186void wxTextCtrl::Cut()
187{
2f1ae414
SC
188 if (CanCut())
189 {
190 TEHandle teH ;
191 long size ;
519cb848 192
2f1ae414
SC
193 UMAGetControlData( m_macControl , 0, kControlEditTextTEHandleTag , sizeof( TEHandle ) , (char*) &teH , &size ) ;
194 TECut( teH ) ;
195#if TARGET_CARBON
196 OSStatus err ;
197 err = ClearCurrentScrap( );
198#else
199 OSErr err ;
200 err = ZeroScrap( );
201#endif
202 TEToScrap() ;
203 // MacInvalidateControl() ;
204 }
e9576ca5
SC
205}
206
207void wxTextCtrl::Paste()
208{
2f1ae414
SC
209 if (CanPaste())
210 {
211 TEHandle teH ;
212 long size ;
519cb848 213
2f1ae414
SC
214 UMAGetControlData( m_macControl , 0, kControlEditTextTEHandleTag , sizeof( TEHandle ) , (char*) &teH , &size ) ;
215 TEFromScrap() ;
216 TEPaste( teH ) ;
5b781a67 217 UMADrawControl( m_macControl ) ;
2f1ae414
SC
218 }
219}
220
221bool wxTextCtrl::CanCopy() const
222{
223 // Can copy if there's a selection
224 long from, to;
225 GetSelection(& from, & to);
226 return (from != to);
227}
228
229bool wxTextCtrl::CanCut() const
230{
231 // Can cut if there's a selection
232 long from, to;
233 GetSelection(& from, & to);
234 return (from != to);
235}
236
237bool wxTextCtrl::CanPaste() const
238{
239 if (!IsEditable())
240 return FALSE;
241
242 long offset ;
243#if TARGET_CARBON
244 OSStatus err = noErr;
245 ScrapRef scrapRef;
246
247 err = GetCurrentScrap( &scrapRef );
248 if ( err != noTypeErr && err != memFullErr )
249 {
250 ScrapFlavorFlags flavorFlags;
251 Size byteCount;
252
253 if (( err = GetScrapFlavorFlags( scrapRef, 'TEXT', &flavorFlags )) == noErr)
254 {
255 if (( err = GetScrapFlavorSize( scrapRef, 'TEXT', &byteCount )) == noErr)
256 {
257 return TRUE ;
258 }
259 }
260 }
261 return FALSE;
262
263#else
264 if ( GetScrap( NULL , 'TEXT' , &offset ) > 0 )
265 {
266 return TRUE ;
267 }
268#endif
269 return FALSE ;
e9576ca5
SC
270}
271
272void wxTextCtrl::SetEditable(bool editable)
273{
519cb848
SC
274 if ( editable )
275 UMAActivateControl( m_macControl ) ;
276 else
277 UMADeactivateControl( m_macControl ) ;
e9576ca5
SC
278}
279
280void wxTextCtrl::SetInsertionPoint(long pos)
281{
519cb848 282 SetSelection( pos , pos ) ;
e9576ca5
SC
283}
284
285void wxTextCtrl::SetInsertionPointEnd()
286{
287 long pos = GetLastPosition();
288 SetInsertionPoint(pos);
289}
290
291long wxTextCtrl::GetInsertionPoint() const
292{
519cb848
SC
293 ControlEditTextSelectionRec selection ;
294 TEHandle teH ;
295 long size ;
296
297 UMAGetControlData( m_macControl , 0, kControlEditTextTEHandleTag , sizeof( TEHandle ) , (char*) &teH , &size ) ;
298// UMAGetControlData( m_macControl , 0, kControlEditTextSelectionTag , sizeof( selection ) , (char*) &selection , &size ) ;
299 return (**teH).selStart ;
e9576ca5
SC
300}
301
302long wxTextCtrl::GetLastPosition() const
303{
519cb848
SC
304 ControlEditTextSelectionRec selection ;
305 TEHandle teH ;
306 long size ;
307
308 UMAGetControlData( m_macControl , 0, kControlEditTextTEHandleTag , sizeof( TEHandle ) , (char*) &teH , &size ) ;
309
310// UMAGetControlData( m_macControl , 0, kControlEditTextSelectionTag , sizeof( selection ) , (char*) &selection , &size ) ;
311 return (**teH).teLength ;
e9576ca5
SC
312}
313
314void wxTextCtrl::Replace(long from, long to, const wxString& value)
315{
519cb848
SC
316 TEHandle teH ;
317 long size ;
318
319 ControlEditTextSelectionRec selection ;
320
321 selection.selStart = from ;
322 selection.selEnd = to ;
323 UMASetControlData( m_macControl , 0, kControlEditTextSelectionTag , sizeof( selection ) , (char*) &selection ) ;
324 UMAGetControlData( m_macControl , 0, kControlEditTextTEHandleTag , sizeof( TEHandle ) , (char*) &teH , &size ) ;
325 TESetSelect( from , to , teH ) ;
326 TEDelete( teH ) ;
327 TEInsert( value , value.Length() , teH ) ;
328// MacInvalidateControl() ;
e9576ca5
SC
329}
330
331void wxTextCtrl::Remove(long from, long to)
332{
519cb848
SC
333 TEHandle teH ;
334 long size ;
335
336 ControlEditTextSelectionRec selection ;
337
338 selection.selStart = from ;
339 selection.selEnd = to ;
340 UMASetControlData( m_macControl , 0, kControlEditTextSelectionTag , sizeof( selection ) , (char*) &selection ) ;
341 UMAGetControlData( m_macControl , 0, kControlEditTextTEHandleTag , sizeof( TEHandle ) , (char*) &teH , &size ) ;
342 TEDelete( teH ) ;
343// MacInvalidateControl() ;
e9576ca5
SC
344}
345
346void wxTextCtrl::SetSelection(long from, long to)
347{
519cb848
SC
348 ControlEditTextSelectionRec selection ;
349 TEHandle teH ;
350 long size ;
351
352 UMAGetControlData( m_macControl , 0, kControlEditTextTEHandleTag , sizeof( TEHandle ) , (char*) &teH , &size ) ;
353
354 selection.selStart = from ;
355 selection.selEnd = to ;
356
357 UMASetControlData( m_macControl , 0, kControlEditTextSelectionTag , sizeof( selection ) , (char*) &selection ) ;
358 TESetSelect( selection.selStart , selection.selEnd , teH ) ;
e9576ca5
SC
359}
360
361bool wxTextCtrl::LoadFile(const wxString& file)
362{
2f1ae414 363 if ( wxTextCtrlBase::LoadFile(file) )
e9576ca5 364 {
2f1ae414 365 return TRUE;
e9576ca5 366 }
e9576ca5
SC
367
368 return FALSE;
369}
370
371void wxTextCtrl::WriteText(const wxString& text)
372{
519cb848
SC
373 TEHandle teH ;
374 long size ;
375
376 memcpy( wxBuffer, text , text.Length() ) ;
377 wxBuffer[text.Length() ] = 0 ;
378// wxMacConvertNewlines( wxBuffer , wxBuffer ) ;
379
380 UMAGetControlData( m_macControl , 0, kControlEditTextTEHandleTag , sizeof( TEHandle ) , (char*) &teH , &size ) ;
381
382 TEInsert( wxBuffer , strlen( wxBuffer) , teH ) ;
383 Refresh() ;
e9576ca5
SC
384}
385
13c21be5
HH
386void wxTextCtrl::AppendText(const wxString& text)
387{
519cb848
SC
388 SetInsertionPointEnd();
389 WriteText(text);
13c21be5
HH
390}
391
e9576ca5
SC
392void wxTextCtrl::Clear()
393{
2f1ae414
SC
394 UMASetControlData( m_macControl, 0, ( m_windowStyle & wxTE_PASSWORD ) ? kControlEditTextPasswordTag : kControlEditTextTextTag , 0 , (char*) ((const char*)NULL) ) ;
395 Refresh() ;
e9576ca5
SC
396}
397
398bool wxTextCtrl::IsModified() const
399{
519cb848 400 return TRUE;
e9576ca5
SC
401}
402
2f1ae414
SC
403bool wxTextCtrl::IsEditable() const
404{
405 return IsEnabled();
406}
407
408bool wxTextCtrl::AcceptsFocus() const
409{
410 // we don't want focus if we can't be edited
411 return IsEditable() && wxControl::AcceptsFocus();
412}
413
414wxSize wxTextCtrl::DoGetBestSize() const
415{
416 int wText = 100 ;
417
418 int hText ;
419 if ( UMAHasAppearance() )
420 hText = 13 ;
421 else
422 hText = 24 ;
423 hText += 2 * m_macHorizontalBorder ;
424/*
425 int cx, cy;
426 wxGetCharSize(GetHWND(), &cx, &cy, &GetFont());
427
428 int wText = DEFAULT_ITEM_WIDTH;
429
430 int hText = EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy);
431
432 return wxSize(wText, hText);
433*/
434 if ( m_windowStyle & wxTE_MULTILINE )
435 {
436 hText *= wxMin(GetNumberOfLines(), 5);
437 }
438 //else: for single line control everything is ok
439 return wxSize(wText, hText);
440}
441
442// ----------------------------------------------------------------------------
443// Undo/redo
444// ----------------------------------------------------------------------------
445
446void wxTextCtrl::Undo()
447{
448 if (CanUndo())
449 {
450 }
451}
452
453void wxTextCtrl::Redo()
454{
455 if (CanRedo())
456 {
457 }
458}
459
460bool wxTextCtrl::CanUndo() const
461{
462 return FALSE ;
463}
464
465bool wxTextCtrl::CanRedo() const
466{
467 return FALSE ;
468}
469
e9576ca5
SC
470// Makes 'unmodified'
471void wxTextCtrl::DiscardEdits()
472{
473 // TODO
474}
475
476int wxTextCtrl::GetNumberOfLines() const
477{
478 // TODO
479 return 0;
480}
481
482long wxTextCtrl::XYToPosition(long x, long y) const
483{
484 // TODO
485 return 0;
486}
487
2f1ae414 488bool wxTextCtrl::PositionToXY(long pos, long *x, long *y) const
e9576ca5 489{
2f1ae414 490 return FALSE ;
e9576ca5
SC
491}
492
493void wxTextCtrl::ShowPosition(long pos)
494{
495 // TODO
496}
497
498int wxTextCtrl::GetLineLength(long lineNo) const
499{
519cb848 500 return GetValue().Length();
e9576ca5
SC
501}
502
503wxString wxTextCtrl::GetLineText(long lineNo) const
504{
519cb848 505 return GetValue();
e9576ca5
SC
506}
507
508/*
509 * Text item
510 */
511
512void wxTextCtrl::Command(wxCommandEvent & event)
513{
514 SetValue (event.GetString());
515 ProcessCommand (event);
516}
517
518void wxTextCtrl::OnDropFiles(wxDropFilesEvent& event)
519{
520 // By default, load the first file into the text window.
521 if (event.GetNumberOfFiles() > 0)
522 {
523 LoadFile(event.GetFiles()[0]);
524 }
525}
526
519cb848
SC
527void wxTextCtrl::OnChar(wxKeyEvent& event)
528{
2f1ae414 529 switch ( event.KeyCode() )
519cb848
SC
530 {
531 case WXK_RETURN:
2f1ae414
SC
532 if (m_windowStyle & wxPROCESS_ENTER)
533 {
e7549107
SC
534 wxCommandEvent event(wxEVT_COMMAND_TEXT_ENTER, m_windowId);
535 event.SetEventObject( this );
536 if ( GetEventHandler()->ProcessEvent(event) )
537 return;
2f1ae414
SC
538 }
539 if ( !(m_windowStyle & wxTE_MULTILINE) )
540 {
541 wxWindow *parent = GetParent();
542 wxPanel *panel = wxDynamicCast(parent, wxPanel);
543 while ( parent != NULL && panel == NULL )
544 {
545 parent = parent->GetParent() ;
546 panel = wxDynamicCast(parent, wxPanel);
547 }
548 if ( panel && panel->GetDefaultItem() )
549 {
550 wxButton *def = panel->GetDefaultItem() ;
551 wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, def->GetId() );
552 event.SetEventObject(def);
553 def->Command(event);
554 event.Skip() ;
555 return ;
556 }
519cb848 557 }
e7549107
SC
558 //else: multiline controls need Enter for themselves
559
519cb848 560 break;
2f1ae414 561
519cb848 562 case WXK_TAB:
e7549107
SC
563 // always produce navigation event - even if we process TAB
564 // ourselves the fact that we got here means that the user code
565 // decided to skip processing of this TAB - probably to let it
566 // do its default job.
519cb848
SC
567 {
568 wxNavigationKeyEvent eventNav;
569 eventNav.SetDirection(!event.ShiftDown());
2f1ae414 570 eventNav.SetWindowChange(event.ControlDown());
519cb848 571 eventNav.SetEventObject(this);
e7549107 572
2f1ae414 573 if ( GetParent()->GetEventHandler()->ProcessEvent(eventNav) )
519cb848 574 return;
2f1ae414
SC
575 event.Skip() ;
576 return ;
519cb848
SC
577 }
578 break;
579 }
e7549107 580
2f1ae414
SC
581 EventRecord *ev = wxTheApp->MacGetCurrentEvent() ;
582 short keycode ;
583 short keychar ;
584 keychar = short(ev->message & charCodeMask);
585 keycode = short(ev->message & keyCodeMask) >> 8 ;
586 UMAHandleControlKey( m_macControl , keycode , keychar , ev->modifiers ) ;
587 if ( keychar >= 0x20 || event.KeyCode() == WXK_RETURN)
588 {
589 wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, m_windowId);
590 event.SetString( GetValue() ) ;
591 event.SetEventObject( this );
592 GetEventHandler()->ProcessEvent(event);
593 }
594
e9576ca5
SC
595}
596
2f1ae414
SC
597// ----------------------------------------------------------------------------
598// standard handlers for standard edit menu events
599// ----------------------------------------------------------------------------
600
601void wxTextCtrl::OnCut(wxCommandEvent& event)
602{
603 Cut();
e9576ca5
SC
604}
605
2f1ae414 606void wxTextCtrl::OnCopy(wxCommandEvent& event)
e9576ca5 607{
2f1ae414 608 Copy();
e9576ca5 609}
e9576ca5 610
2f1ae414 611void wxTextCtrl::OnPaste(wxCommandEvent& event)
e9576ca5 612{
2f1ae414 613 Paste();
e9576ca5
SC
614}
615
2f1ae414 616void wxTextCtrl::OnUndo(wxCommandEvent& event)
e9576ca5 617{
2f1ae414 618 Undo();
e9576ca5
SC
619}
620
2f1ae414 621void wxTextCtrl::OnRedo(wxCommandEvent& event)
e9576ca5 622{
2f1ae414 623 Redo();
e9576ca5
SC
624}
625
2f1ae414 626void wxTextCtrl::OnUpdateCut(wxUpdateUIEvent& event)
e9576ca5 627{
2f1ae414 628 event.Enable( CanCut() );
e9576ca5
SC
629}
630
2f1ae414 631void wxTextCtrl::OnUpdateCopy(wxUpdateUIEvent& event)
e9576ca5 632{
2f1ae414 633 event.Enable( CanCopy() );
e9576ca5
SC
634}
635
2f1ae414 636void wxTextCtrl::OnUpdatePaste(wxUpdateUIEvent& event)
e9576ca5 637{
2f1ae414
SC
638 event.Enable( CanPaste() );
639}
e9576ca5 640
2f1ae414
SC
641void wxTextCtrl::OnUpdateUndo(wxUpdateUIEvent& event)
642{
643 event.Enable( CanUndo() );
644}
645
646void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent& event)
647{
648 event.Enable( CanRedo() );
e9576ca5
SC
649}
650