1 /////////////////////////////////////////////////////////////////////////////
8 // Copyright: (c) AUTHOR
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "textctrl.h"
17 #include <sys/types.h>
25 #include "wx/button.h"
27 #include "wx/textctrl.h"
28 #include "wx/notebook.h"
29 #include "wx/tabctrl.h"
30 #include "wx/settings.h"
31 #include "wx/filefn.h"
34 #if defined(__BORLANDC__) && !defined(__WIN32__)
36 #elif !defined(__MWERKS__) && !defined(__GNUWIN32) && !defined(__WXMAC_X__)
40 #include "wx/mac/uma.h"
42 #if !USE_SHARED_LIBRARY
43 IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl
, wxControl
)
45 BEGIN_EVENT_TABLE(wxTextCtrl
, wxControl
)
46 EVT_DROP_FILES(wxTextCtrl::OnDropFiles
)
47 EVT_CHAR(wxTextCtrl::OnChar
)
48 EVT_MENU(wxID_CUT
, wxTextCtrl::OnCut
)
49 EVT_MENU(wxID_COPY
, wxTextCtrl::OnCopy
)
50 EVT_MENU(wxID_PASTE
, wxTextCtrl::OnPaste
)
51 EVT_MENU(wxID_UNDO
, wxTextCtrl::OnUndo
)
52 EVT_MENU(wxID_REDO
, wxTextCtrl::OnRedo
)
54 EVT_UPDATE_UI(wxID_CUT
, wxTextCtrl::OnUpdateCut
)
55 EVT_UPDATE_UI(wxID_COPY
, wxTextCtrl::OnUpdateCopy
)
56 EVT_UPDATE_UI(wxID_PASTE
, wxTextCtrl::OnUpdatePaste
)
57 EVT_UPDATE_UI(wxID_UNDO
, wxTextCtrl::OnUpdateUndo
)
58 EVT_UPDATE_UI(wxID_REDO
, wxTextCtrl::OnUpdateRedo
)
63 wxTextCtrl::wxTextCtrl()
67 const short kVerticalMargin
= 2 ;
68 const short kHorizontalMargin
= 2 ;
70 bool wxTextCtrl::Create(wxWindow
*parent
, wxWindowID id
,
73 const wxSize
& size
, long style
,
74 const wxValidator
& validator
,
77 // base initialization
78 if ( !CreateBase(parent
, id
, pos
, size
, style
, validator
, name
) )
81 wxSize mySize
= size
;
82 if ( UMAHasAppearance() )
84 m_macHorizontalBorder
= 5 ; // additional pixels around the real control
85 m_macVerticalBorder
= 5 ;
89 m_macHorizontalBorder
= 0 ; // additional pixels around the real control
90 m_macVerticalBorder
= 0 ;
99 if ( UMAHasAppearance() )
104 mySize
.y
+= 2 * m_macVerticalBorder
;
107 MacPreControlCreate( parent
, id
, "" , pos
, mySize
,style
, validator
, name
, &bounds
, title
) ;
109 m_macControl
= UMANewControl( parent
->GetMacRootWindow() , &bounds
, "\p" , true , 0 , 0 , 1,
110 ( style
& wxTE_PASSWORD
) ? kControlEditTextPasswordProc
: kControlEditTextProc
, (long) this ) ;
111 MacPostControlCreate() ;
119 UMAGetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
120 (*teH
)->lineHeight
= -1 ;
123 if( wxApp::s_macDefaultEncodingIsPC
)
124 value
= wxMacMakeMacStringFromPC( st
) ;
127 UMASetControlData( m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, value
.Length() , (char*) ((const char*)value
) ) ;
132 wxString
wxTextCtrl::GetValue() const
135 UMAGetControlData( m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, 32767 , wxBuffer
, &actualsize
) ;
136 wxBuffer
[actualsize
] = 0 ;
137 if( wxApp::s_macDefaultEncodingIsPC
)
138 return wxMacMakePCStringFromMac( wxBuffer
) ;
140 return wxString(wxBuffer
);
143 void wxTextCtrl::GetSelection(long* from
, long* to
) const
145 ControlEditTextSelectionRec selection
;
149 UMAGetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
151 *from
= (**teH
).selStart
;
152 *to
= (**teH
).selEnd
;
155 void wxTextCtrl::SetValue(const wxString
& st
)
159 if( wxApp::s_macDefaultEncodingIsPC
)
160 value
= wxMacMakeMacStringFromPC( st
) ;
163 UMASetControlData( m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, value
.Length() , (char*) ((const char*)value
) ) ;
164 WindowRef window
= GetMacRootWindow() ;
167 wxWindow
* win
= wxFindWinFromMacWindow( window
) ;
170 wxMacDrawingHelper
help( win
) ;
171 // the mac control manager always assumes to have the origin at 0,0
174 bool hasTabBehind
= false ;
175 wxWindow
* parent
= GetParent() ;
178 if( parent
->MacGetWindowData() )
180 UMASetThemeWindowBackground( win
->MacGetWindowData()->m_macWindow
, kThemeBrushDialogBackgroundActive
, false ) ;
184 if( parent
->IsKindOf( CLASSINFO( wxNotebook
) ) || parent
->IsKindOf( CLASSINFO( wxTabCtrl
) ))
186 if ( ((wxControl
*)parent
)->GetMacControl() )
187 SetUpControlBackground( ((wxControl
*)parent
)->GetMacControl() , -1 , true ) ;
191 parent
= parent
->GetParent() ;
194 UMADrawControl( m_macControl
) ;
195 UMASetThemeWindowBackground( win
->MacGetWindowData()->m_macWindow
, win
->MacGetWindowData()->m_macWindowBackgroundTheme
, false ) ;
196 wxDC::MacInvalidateSetup() ;
201 // Clipboard operations
202 void wxTextCtrl::Copy()
209 UMAGetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
213 err
= ClearCurrentScrap( );
222 void wxTextCtrl::Cut()
229 UMAGetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
233 err
= ClearCurrentScrap( );
239 // MacInvalidateControl() ;
243 void wxTextCtrl::Paste()
250 UMAGetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
253 WindowRef window
= GetMacRootWindow() ;
256 wxWindow
* win
= wxFindWinFromMacWindow( window
) ;
259 wxMacDrawingHelper
help( win
) ;
260 // the mac control manager always assumes to have the origin at 0,0
263 bool hasTabBehind
= false ;
264 wxWindow
* parent
= GetParent() ;
267 if( parent
->MacGetWindowData() )
269 UMASetThemeWindowBackground( win
->MacGetWindowData()->m_macWindow
, kThemeBrushDialogBackgroundActive
, false ) ;
273 if( parent
->IsKindOf( CLASSINFO( wxNotebook
) ) || parent
->IsKindOf( CLASSINFO( wxTabCtrl
) ))
275 if ( ((wxControl
*)parent
)->GetMacControl() )
276 SetUpControlBackground( ((wxControl
*)parent
)->GetMacControl() , -1 , true ) ;
280 parent
= parent
->GetParent() ;
283 UMADrawControl( m_macControl
) ;
284 UMASetThemeWindowBackground( win
->MacGetWindowData()->m_macWindow
, win
->MacGetWindowData()->m_macWindowBackgroundTheme
, false ) ;
285 wxDC::MacInvalidateSetup() ;
291 bool wxTextCtrl::CanCopy() const
293 // Can copy if there's a selection
295 GetSelection(& from
, & to
);
299 bool wxTextCtrl::CanCut() const
301 // Can cut if there's a selection
303 GetSelection(& from
, & to
);
307 bool wxTextCtrl::CanPaste() const
314 OSStatus err
= noErr
;
317 err
= GetCurrentScrap( &scrapRef
);
318 if ( err
!= noTypeErr
&& err
!= memFullErr
)
320 ScrapFlavorFlags flavorFlags
;
323 if (( err
= GetScrapFlavorFlags( scrapRef
, 'TEXT', &flavorFlags
)) == noErr
)
325 if (( err
= GetScrapFlavorSize( scrapRef
, 'TEXT', &byteCount
)) == noErr
)
334 if ( GetScrap( NULL
, 'TEXT' , &offset
) > 0 )
342 void wxTextCtrl::SetEditable(bool editable
)
345 UMAActivateControl( m_macControl
) ;
347 UMADeactivateControl( m_macControl
) ;
350 void wxTextCtrl::SetInsertionPoint(long pos
)
352 SetSelection( pos
, pos
) ;
355 void wxTextCtrl::SetInsertionPointEnd()
357 long pos
= GetLastPosition();
358 SetInsertionPoint(pos
);
361 long wxTextCtrl::GetInsertionPoint() const
363 ControlEditTextSelectionRec selection
;
367 UMAGetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
368 // UMAGetControlData( m_macControl , 0, kControlEditTextSelectionTag , sizeof( selection ) , (char*) &selection , &size ) ;
369 return (**teH
).selStart
;
372 long wxTextCtrl::GetLastPosition() const
374 ControlEditTextSelectionRec selection
;
378 UMAGetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
380 // UMAGetControlData( m_macControl , 0, kControlEditTextSelectionTag , sizeof( selection ) , (char*) &selection , &size ) ;
381 return (**teH
).teLength
;
384 void wxTextCtrl::Replace(long from
, long to
, const wxString
& value
)
389 ControlEditTextSelectionRec selection
;
391 selection
.selStart
= from
;
392 selection
.selEnd
= to
;
393 UMASetControlData( m_macControl
, 0, kControlEditTextSelectionTag
, sizeof( selection
) , (char*) &selection
) ;
394 UMAGetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
395 TESetSelect( from
, to
, teH
) ;
397 TEInsert( value
, value
.Length() , teH
) ;
398 // MacInvalidateControl() ;
401 void wxTextCtrl::Remove(long from
, long to
)
406 ControlEditTextSelectionRec selection
;
408 selection
.selStart
= from
;
409 selection
.selEnd
= to
;
410 UMASetControlData( m_macControl
, 0, kControlEditTextSelectionTag
, sizeof( selection
) , (char*) &selection
) ;
411 UMAGetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
413 // MacInvalidateControl() ;
416 void wxTextCtrl::SetSelection(long from
, long to
)
418 ControlEditTextSelectionRec selection
;
422 UMAGetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
424 selection
.selStart
= from
;
425 selection
.selEnd
= to
;
427 UMASetControlData( m_macControl
, 0, kControlEditTextSelectionTag
, sizeof( selection
) , (char*) &selection
) ;
428 TESetSelect( selection
.selStart
, selection
.selEnd
, teH
) ;
431 bool wxTextCtrl::LoadFile(const wxString
& file
)
433 if ( wxTextCtrlBase::LoadFile(file
) )
441 void wxTextCtrl::WriteText(const wxString
& text
)
446 memcpy( wxBuffer
, text
, text
.Length() ) ;
447 wxBuffer
[text
.Length() ] = 0 ;
448 // wxMacConvertNewlines( wxBuffer , wxBuffer ) ;
450 UMAGetControlData( m_macControl
, 0, kControlEditTextTEHandleTag
, sizeof( TEHandle
) , (char*) &teH
, &size
) ;
452 TEInsert( wxBuffer
, strlen( wxBuffer
) , teH
) ;
456 void wxTextCtrl::AppendText(const wxString
& text
)
458 SetInsertionPointEnd();
462 void wxTextCtrl::Clear()
464 UMASetControlData( m_macControl
, 0, ( m_windowStyle
& wxTE_PASSWORD
) ? kControlEditTextPasswordTag
: kControlEditTextTextTag
, 0 , (char*) ((const char*)NULL
) ) ;
468 bool wxTextCtrl::IsModified() const
473 bool wxTextCtrl::IsEditable() const
478 bool wxTextCtrl::AcceptsFocus() const
480 // we don't want focus if we can't be edited
481 return IsEditable() && wxControl::AcceptsFocus();
484 wxSize
wxTextCtrl::DoGetBestSize() const
489 if ( UMAHasAppearance() )
493 hText
+= 2 * m_macHorizontalBorder
;
496 wxGetCharSize(GetHWND(), &cx, &cy, &GetFont());
498 int wText = DEFAULT_ITEM_WIDTH;
500 int hText = EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy);
502 return wxSize(wText, hText);
504 if ( m_windowStyle
& wxTE_MULTILINE
)
506 hText
*= wxMin(GetNumberOfLines(), 5);
508 //else: for single line control everything is ok
509 return wxSize(wText
, hText
);
512 // ----------------------------------------------------------------------------
514 // ----------------------------------------------------------------------------
516 void wxTextCtrl::Undo()
523 void wxTextCtrl::Redo()
530 bool wxTextCtrl::CanUndo() const
535 bool wxTextCtrl::CanRedo() const
540 // Makes 'unmodified'
541 void wxTextCtrl::DiscardEdits()
546 int wxTextCtrl::GetNumberOfLines() const
552 long wxTextCtrl::XYToPosition(long x
, long y
) const
558 bool wxTextCtrl::PositionToXY(long pos
, long *x
, long *y
) const
563 void wxTextCtrl::ShowPosition(long pos
)
568 int wxTextCtrl::GetLineLength(long lineNo
) const
570 return GetValue().Length();
573 wxString
wxTextCtrl::GetLineText(long lineNo
) const
582 void wxTextCtrl::Command(wxCommandEvent
& event
)
584 SetValue (event
.GetString());
585 ProcessCommand (event
);
588 void wxTextCtrl::OnDropFiles(wxDropFilesEvent
& event
)
590 // By default, load the first file into the text window.
591 if (event
.GetNumberOfFiles() > 0)
593 LoadFile(event
.GetFiles()[0]);
597 void wxTextCtrl::OnChar(wxKeyEvent
& event
)
599 switch ( event
.KeyCode() )
602 if (m_windowStyle
& wxPROCESS_ENTER
)
604 wxCommandEvent
event(wxEVT_COMMAND_TEXT_ENTER
, m_windowId
);
605 event
.SetEventObject( this );
606 if ( GetEventHandler()->ProcessEvent(event
) )
609 if ( !(m_windowStyle
& wxTE_MULTILINE
) )
611 wxWindow
*parent
= GetParent();
612 wxPanel
*panel
= wxDynamicCast(parent
, wxPanel
);
613 while ( parent
!= NULL
&& panel
== NULL
)
615 parent
= parent
->GetParent() ;
616 panel
= wxDynamicCast(parent
, wxPanel
);
618 if ( panel
&& panel
->GetDefaultItem() )
620 wxButton
*def
= panel
->GetDefaultItem() ;
621 wxCommandEvent
event(wxEVT_COMMAND_BUTTON_CLICKED
, def
->GetId() );
622 event
.SetEventObject(def
);
628 //else: multiline controls need Enter for themselves
633 // always produce navigation event - even if we process TAB
634 // ourselves the fact that we got here means that the user code
635 // decided to skip processing of this TAB - probably to let it
636 // do its default job.
638 wxNavigationKeyEvent eventNav
;
639 eventNav
.SetDirection(!event
.ShiftDown());
640 eventNav
.SetWindowChange(event
.ControlDown());
641 eventNav
.SetEventObject(this);
643 if ( GetParent()->GetEventHandler()->ProcessEvent(eventNav
) )
651 EventRecord
*ev
= wxTheApp
->MacGetCurrentEvent() ;
654 keychar
= short(ev
->message
& charCodeMask
);
655 keycode
= short(ev
->message
& keyCodeMask
) >> 8 ;
656 UMAHandleControlKey( m_macControl
, keycode
, keychar
, ev
->modifiers
) ;
657 if ( keychar
>= 0x20 || event
.KeyCode() == WXK_RETURN
)
659 wxCommandEvent
event(wxEVT_COMMAND_TEXT_UPDATED
, m_windowId
);
660 event
.SetString( GetValue() ) ;
661 event
.SetEventObject( this );
662 GetEventHandler()->ProcessEvent(event
);
667 // ----------------------------------------------------------------------------
668 // standard handlers for standard edit menu events
669 // ----------------------------------------------------------------------------
671 void wxTextCtrl::OnCut(wxCommandEvent
& event
)
676 void wxTextCtrl::OnCopy(wxCommandEvent
& event
)
681 void wxTextCtrl::OnPaste(wxCommandEvent
& event
)
686 void wxTextCtrl::OnUndo(wxCommandEvent
& event
)
691 void wxTextCtrl::OnRedo(wxCommandEvent
& event
)
696 void wxTextCtrl::OnUpdateCut(wxUpdateUIEvent
& event
)
698 event
.Enable( CanCut() );
701 void wxTextCtrl::OnUpdateCopy(wxUpdateUIEvent
& event
)
703 event
.Enable( CanCopy() );
706 void wxTextCtrl::OnUpdatePaste(wxUpdateUIEvent
& event
)
708 event
.Enable( CanPaste() );
711 void wxTextCtrl::OnUpdateUndo(wxUpdateUIEvent
& event
)
713 event
.Enable( CanUndo() );
716 void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent
& event
)
718 event
.Enable( CanRedo() );