X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/facd6764872eede45605ba7c9dfa0e1d0c708fa2..94f9b1f0f3afa5cdb1f54f2bd8af582bdd78bf6f:/src/mac/carbon/textctrl.cpp diff --git a/src/mac/carbon/textctrl.cpp b/src/mac/carbon/textctrl.cpp index ffd659b5eb..a522f2e9e9 100644 --- a/src/mac/carbon/textctrl.cpp +++ b/src/mac/carbon/textctrl.cpp @@ -61,6 +61,88 @@ #include "wx/mac/uma.h" #define TE_UNLIMITED_LENGTH 0xFFFFFFFFUL +#if TARGET_API_MAC_OSX + #define wxMAC_USE_MLTE 0 + #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2 + #define wxMAC_USE_MLTE_HIVIEW 1 + #else + #define wxMAC_USE_MLTE_HIVIEW 0 + #endif +#else + // there is no unicodetextctrl on classic, and hopefully MLTE works better there + #define wxMAC_USE_MLTE 1 + #define wxMAC_USE_MLTE_HIVIEW 0 +#endif + +#if wxMAC_USE_MLTE + +TXNFrameOptions FrameOptionsFromWXStyle( long wxStyle ) +{ + TXNFrameOptions frameOptions = + kTXNDontDrawCaretWhenInactiveMask ; + if ( ! ( wxStyle & wxTE_NOHIDESEL ) ) + frameOptions |= kTXNDontDrawSelectionWhenInactiveMask ; + + if ( wxStyle & wxTE_MULTILINE ) + { + if ( ! ( wxStyle & wxTE_DONTWRAP ) ) + frameOptions |= kTXNAlwaysWrapAtViewEdgeMask ; + else + { + frameOptions |= kTXNAlwaysWrapAtViewEdgeMask ; + frameOptions |= kTXNWantHScrollBarMask ; + } + + if ( !(wxStyle & wxTE_NO_VSCROLL ) ) + frameOptions |= kTXNWantVScrollBarMask ; + } + else + frameOptions |= kTXNSingleLineOnlyMask ; + return frameOptions ; +} + +void AdjustAttributesFromWXStyle( TXNObject txn , long wxStyle , bool visible ) +{ + TXNControlTag iControlTags[3] = { kTXNDoFontSubstitution, kTXNWordWrapStateTag }; + TXNControlData iControlData[3] = { {false}, {kTXNNoAutoWrap} }; + int toptag = 2 ; +#if TARGET_API_MAC_OSX + iControlTags[2] = kTXNVisibilityTag ; + iControlData[2].uValue = visible ; + toptag++ ; +#endif + + if ( wxStyle & wxTE_MULTILINE ) + { + if (wxStyle & wxTE_DONTWRAP) + iControlData[1].uValue = kTXNNoAutoWrap ; + else + iControlData[1].uValue = kTXNAutoWrap ; + + } + verify_noerr( TXNSetTXNObjectControls( txn, false, toptag, + iControlTags, iControlData )) ; + + Str255 fontName ; + SInt16 fontSize ; + Style fontStyle ; + + GetThemeFont(kThemeSystemFont , GetApplicationScript() , fontName , &fontSize , &fontStyle ) ; + + TXNTypeAttributes typeAttr[] = + { + { kTXNQDFontNameAttribute , kTXNQDFontNameAttributeSize , { (void*) fontName } } , + { kTXNQDFontSizeAttribute , kTXNFontSizeAttributeSize , { (void*) (fontSize << 16) } } , + { kTXNQDFontStyleAttribute , kTXNQDFontStyleAttributeSize , { (void*) normal } } , + } ; + + verify_noerr( TXNSetTypeAttributes (txn, sizeof( typeAttr ) / sizeof(TXNTypeAttributes) , typeAttr, + kTXNStartOffset, + kTXNEndOffset) ); + +} + +#if !wxMAC_USE_MLTE_HIVIEW // CS:TODO we still have a problem getting properly at the text events of a control because under Carbon // the MLTE engine registers itself for the key events thus the normal flow never occurs, the only measure for the @@ -168,11 +250,13 @@ OSStatus MLTESetObjectVisibility( STPTextPaneVars *varsp, Boolean vis , long wxS TXNControlData iControlData[1] = {{ vis }}; err = ::TXNSetTXNObjectControls( varsp->fTXNRec, false, 1, iControlTags, iControlData ); #endif - if ( vis ) + wxTextCtrl* textctrl = (wxTextCtrl*) GetControlReference(varsp->fUserPaneRec); + if ( vis && textctrl ) { Rect bounds ; UMAGetControlBoundsInWindowCoords( varsp->fUserPaneRec, &bounds); TPCalculateBounds( varsp , bounds ) ; + wxMacWindowClipper cl(textctrl) ; TXNSetFrameBounds( varsp->fTXNRec, varsp->fRTextArea.top, varsp->fRTextArea.left, varsp->fRTextArea.bottom, varsp->fRTextArea.right, varsp->fTXNFrame); TXNShowSelection( varsp->fTXNRec, kTXNShowStart); @@ -204,7 +288,8 @@ static void TPUpdateVisibility(ControlRef theControl) { // we only recalculate when visible, otherwise scrollbars get drawn at incorrect places if ( varsp->fVisible ) { - TXNSetFrameBounds( varsp->fTXNRec, varsp->fRTextArea.top, varsp->fRTextArea.left, + wxMacWindowClipper cl(textctrl) ; + TXNSetFrameBounds( varsp->fTXNRec, varsp->fRTextArea.top, varsp->fRTextArea.left, varsp->fRTextArea.bottom, varsp->fRTextArea.right, varsp->fTXNFrame); } InvalWindowRect( GetControlOwner( theControl ) , &oldBounds ) ; @@ -557,7 +642,7 @@ OSStatus mUPOpenControl(STPTextPaneVars* &handle, ControlRef theControl, long wx SetControlData(theControl, kControlEntireControl, kControlUserPaneKeyDownProcTag, sizeof(gTPKeyProc), &gTPKeyProc); SetControlData(theControl, kControlEntireControl, kControlUserPaneActivateProcTag, sizeof(gTPActivateProc), &gTPActivateProc); SetControlData(theControl, kControlEntireControl, kControlUserPaneFocusProcTag, sizeof(gTPFocusProc), &gTPFocusProc); - + /* calculate the rectangles used by the control */ UMAGetControlBoundsInWindowCoords(theControl, &bounds); varsp->fRTextOutlineRegion = NewRgn() ; @@ -568,26 +653,7 @@ OSStatus mUPOpenControl(STPTextPaneVars* &handle, ControlRef theControl, long wx /* create the new edit field */ - TXNFrameOptions frameOptions = - kTXNDontDrawCaretWhenInactiveMask ; - if ( ! ( wxStyle & wxTE_NOHIDESEL ) ) - frameOptions |= kTXNDontDrawSelectionWhenInactiveMask ; - - if ( wxStyle & wxTE_MULTILINE ) - { - if ( ! ( wxStyle & wxTE_DONTWRAP ) ) - frameOptions |= kTXNAlwaysWrapAtViewEdgeMask ; - else - { - frameOptions |= kTXNAlwaysWrapAtViewEdgeMask ; - frameOptions |= kTXNWantHScrollBarMask ; - } - - if ( !(wxStyle & wxTE_NO_VSCROLL ) ) - frameOptions |= kTXNWantVScrollBarMask ; - } - else - frameOptions |= kTXNSingleLineOnlyMask ; + TXNFrameOptions frameOptions = FrameOptionsFromWXStyle( wxStyle ) ; verify_noerr(TXNNewObject(NULL, varsp->fOwner, &varsp->fRTextArea, frameOptions , @@ -596,40 +662,7 @@ OSStatus mUPOpenControl(STPTextPaneVars* &handle, ControlRef theControl, long wx kTXNSystemDefaultEncoding, &varsp->fTXNRec, &varsp->fTXNFrame, (TXNObjectRefcon) varsp)); - TXNControlTag iControlTags[3] = { kTXNDoFontSubstitution, kTXNWordWrapStateTag }; - TXNControlData iControlData[3] = { {false}, {kTXNAutoWrap} }; - int toptag = 2 ; -#if TARGET_API_MAC_OSX - iControlTags[2] = kTXNVisibilityTag ; - iControlData[2].uValue = false ; - toptag++ ; -#endif - iControlData[1].uValue = varsp->fVisible ; - - if ( (wxStyle & wxTE_MULTILINE) && (wxStyle & wxTE_DONTWRAP) ) - iControlData[2].uValue = kTXNNoAutoWrap ; - - verify_noerr( TXNSetTXNObjectControls( varsp->fTXNRec, false, toptag, - iControlTags, iControlData )) ; - - Str255 fontName ; - SInt16 fontSize ; - Style fontStyle ; - - GetThemeFont(kThemeSmallSystemFont , GetApplicationScript() , fontName , &fontSize , &fontStyle ) ; - - TXNTypeAttributes typeAttr[] = - { - { kTXNQDFontNameAttribute , kTXNQDFontNameAttributeSize , { (void*) fontName } } , - { kTXNQDFontSizeAttribute , kTXNFontSizeAttributeSize , { (void*) (fontSize << 16) } } , - { kTXNQDFontStyleAttribute , kTXNQDFontStyleAttributeSize , { (void*) normal } } , - } ; - - err = TXNSetTypeAttributes (varsp->fTXNRec, sizeof( typeAttr ) / sizeof(TXNTypeAttributes) , typeAttr, - kTXNStartOffset, - kTXNEndOffset); - - + AdjustAttributesFromWXStyle( varsp->fTXNRec , wxStyle , varsp->fVisible ) ; /* perform final activations and setup for our text field. Here, we assume that the window is going to be the 'active' window. */ TPActivatePaneText(varsp, varsp->fIsActive && varsp->fInFocus); @@ -637,27 +670,11 @@ OSStatus mUPOpenControl(STPTextPaneVars* &handle, ControlRef theControl, long wx return err; } +#else +struct STPTextPaneVars +{ +} ; - - -#if !USE_SHARED_LIBRARY -IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl, wxControl) - -BEGIN_EVENT_TABLE(wxTextCtrl, wxControl) - EVT_DROP_FILES(wxTextCtrl::OnDropFiles) - EVT_CHAR(wxTextCtrl::OnChar) - EVT_MENU(wxID_CUT, wxTextCtrl::OnCut) - EVT_MENU(wxID_COPY, wxTextCtrl::OnCopy) - EVT_MENU(wxID_PASTE, wxTextCtrl::OnPaste) - EVT_MENU(wxID_UNDO, wxTextCtrl::OnUndo) - EVT_MENU(wxID_REDO, wxTextCtrl::OnRedo) - - EVT_UPDATE_UI(wxID_CUT, wxTextCtrl::OnUpdateCut) - EVT_UPDATE_UI(wxID_COPY, wxTextCtrl::OnUpdateCopy) - EVT_UPDATE_UI(wxID_PASTE, wxTextCtrl::OnUpdatePaste) - EVT_UPDATE_UI(wxID_UNDO, wxTextCtrl::OnUpdateUndo) - EVT_UPDATE_UI(wxID_REDO, wxTextCtrl::OnUpdateRedo) -END_EVENT_TABLE() #endif static void SetTXNData( STPTextPaneVars *varsp, TXNObject txn , const wxString& st , TXNOffset start , TXNOffset end ) @@ -683,6 +700,29 @@ static void SetTXNData( STPTextPaneVars *varsp, TXNObject txn , const wxString& #endif } + +#endif + +#if !USE_SHARED_LIBRARY +IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl, wxControl) + +BEGIN_EVENT_TABLE(wxTextCtrl, wxControl) + EVT_DROP_FILES(wxTextCtrl::OnDropFiles) + EVT_CHAR(wxTextCtrl::OnChar) + EVT_MENU(wxID_CUT, wxTextCtrl::OnCut) + EVT_MENU(wxID_COPY, wxTextCtrl::OnCopy) + EVT_MENU(wxID_PASTE, wxTextCtrl::OnPaste) + EVT_MENU(wxID_UNDO, wxTextCtrl::OnUndo) + EVT_MENU(wxID_REDO, wxTextCtrl::OnRedo) + + EVT_UPDATE_UI(wxID_CUT, wxTextCtrl::OnUpdateCut) + EVT_UPDATE_UI(wxID_COPY, wxTextCtrl::OnUpdateCopy) + EVT_UPDATE_UI(wxID_PASTE, wxTextCtrl::OnUpdatePaste) + EVT_UPDATE_UI(wxID_UNDO, wxTextCtrl::OnUpdateUndo) + EVT_UPDATE_UI(wxID_REDO, wxTextCtrl::OnUpdateRedo) +END_EVENT_TABLE() +#endif + // Text item void wxTextCtrl::Init() { @@ -697,11 +737,15 @@ void wxTextCtrl::Init() wxTextCtrl::~wxTextCtrl() { +#if wxMAC_USE_MLTE SetControlReference((ControlRef)m_macControl, 0) ; +#if !wxMAC_USE_MLTE_HIVIEW TXNDeleteObject((TXNObject)m_macTXN); +#endif /* delete our private storage */ free(m_macTXNvars); /* zero the control reference */ +#endif } @@ -736,20 +780,51 @@ bool wxTextCtrl::Create(wxWindow *parent, wxWindowID id, wxString st = str ; wxMacConvertNewlines13To10( &st ) ; +#if wxMAC_USE_MLTE { +#if wxMAC_USE_MLTE_HIVIEW + HIRect hr = { bounds.left , bounds.top , bounds.right - bounds.left , bounds.bottom- bounds.top } ; + HIViewRef scrollView = NULL ; + TXNFrameOptions frameOptions = FrameOptionsFromWXStyle( style ) ; + + if ( frameOptions & (kTXNWantVScrollBarMask|kTXNWantHScrollBarMask) ) + { + HIScrollViewCreate(( frameOptions & kTXNWantHScrollBarMask ? kHIScrollViewOptionsHorizScroll : 0) | + ( frameOptions & kTXNWantVScrollBarMask ? kHIScrollViewOptionsVertScroll: 0 ) , &scrollView ) ; + + HIViewSetFrame( scrollView, &hr ); + HIViewSetVisible( scrollView, true ); + } + HIViewRef textView ; + HITextViewCreate( NULL , 0, frameOptions , (ControlRef*) &textView ) ; + m_macTXN = HITextViewGetTXNObject( textView) ; + AdjustAttributesFromWXStyle( (TXNObject) m_macTXN , style , true ) ; + HIViewSetVisible( (ControlRef) textView , true ) ; + if ( scrollView ) + { + HIViewAddSubview( scrollView , textView ) ; + m_macControl = (WXWidget) scrollView ; + } + else + { + m_macControl = (WXWidget) textView ; + } +#else short featurSet; featurSet = kControlSupportsEmbedding | kControlSupportsFocus | kControlWantsIdle | kControlWantsActivate | kControlHandlesTracking | kControlHasSpecialBackground | kControlGetsFocusOnClick | kControlSupportsLiveFeedback; /* create the control */ - m_macControl = (WXWidget) ::NewControl(MAC_WXHWND(parent->MacGetTopLevelWindowRef()), &bounds, "\p", true , featurSet, 0, featurSet, kControlUserPaneProc, (long) this ); - /* set up the mUP specific features and data */ + verify_noerr( CreateUserPaneControl( MAC_WXHWND(GetParent()->MacGetTopLevelWindowRef()) , &bounds, featurSet , (ControlRef*) &m_macControl) ) ; + wxMacWindowClipper c(this) ; STPTextPaneVars *varsp ; mUPOpenControl( varsp, (ControlRef) m_macControl, m_windowStyle ); m_macTXNvars = varsp ; m_macTXN = varsp->fTXNRec ; +#endif + if ( style & wxTE_PASSWORD ) { UniChar c = 0xA5 ; @@ -758,17 +833,24 @@ bool wxTextCtrl::Create(wxWindow *parent, wxWindowID id, } MacPostControlCreate(pos,size) ; +#if !wxMAC_USE_MLTE_HIVIEW if ( MacIsReallyShown() ) MLTESetObjectVisibility( (STPTextPaneVars*) m_macTXNvars, true , GetWindowStyle() ) ; +#endif { wxMacWindowClipper clipper( this ) ; +#if !wxMAC_USE_MLTE_HIVIEW TPUpdateVisibility( (ControlRef) m_macControl ) ; +#endif SetTXNData( (STPTextPaneVars *)m_macTXNvars , (TXNObject) m_macTXN , st , kTXNStartOffset, kTXNEndOffset ) ; TXNSetSelection( (TXNObject) m_macTXN, 0, 0); TXNShowSelection( (TXNObject) m_macTXN, kTXNShowStart); } + + // in case MLTE is catching events before we get the chance to do so, we'd have to reintroduce the tlw-handler in front : + // parent->MacGetTopLevelWindow()->MacInstallTopLevelWindowEventHandler() ; SetBackgroundColour( *wxWHITE ) ; @@ -777,20 +859,56 @@ bool wxTextCtrl::Create(wxWindow *parent, wxWindowID id, tback.bg.color = MAC_WXCOLORREF( GetBackgroundColour().GetPixel() ); TXNSetBackground( (TXNObject) m_macTXN , &tback); +#else + wxMacCFStringHolder cf(st , m_font.GetEncoding()) ; + CFStringRef cfr = cf ; + Boolean isPassword = ( m_windowStyle & wxTE_PASSWORD ) != 0 ; + CreateEditUnicodeTextControl( MAC_WXHWND(parent->MacGetTopLevelWindowRef()), &bounds , cfr , isPassword , NULL , (ControlRef*) &m_macControl ) ; + if ( !(m_windowStyle & wxTE_MULTILINE) ) + { + Boolean singleline = true ; + ::SetControlData( (ControlHandle) m_macControl, kControlEditTextPart , kControlEditTextSingleLineTag , sizeof( singleline ) , &singleline ) ; + } + MacPostControlCreate(pos,size) ; + +#endif if ( m_windowStyle & wxTE_READONLY) { SetEditable( false ) ; } + return TRUE; } void wxTextCtrl::MacVisibilityChanged() { +#if wxMAC_USE_MLTE +#if !wxMAC_USE_MLTE_HIVIEW MLTESetObjectVisibility((STPTextPaneVars*) m_macTXNvars , MacIsReallyShown() , GetWindowStyle() ) ; if ( !MacIsReallyShown() ) InvalWindowRect( GetControlOwner( (ControlHandle) m_macControl ) , &((STPTextPaneVars *)m_macTXNvars)->fRBounds ) ; - +#endif +#else + if ( !(m_windowStyle & wxTE_MULTILINE) && MacIsReallyShown() ) + { + // work around a refresh issue insofar as not always the entire content is shown even if this would be possible + ControlEditTextSelectionRec sel ; + CFStringRef value = NULL ; + Size actualSize = 0 ; + ResType datatag = GetWindowStyle() & wxTE_PASSWORD ? + kControlEditTextPasswordCFStringTag : kControlEditTextCFStringTag ; + + verify_noerr( GetControlData( (ControlRef) m_macControl , 0, kControlEditTextSelectionTag, + sizeof(ControlEditTextSelectionRec), &sel, &actualSize ) ); + verify_noerr( GetControlData( (ControlRef) m_macControl , 0, datatag , sizeof(CFStringRef), &value, &actualSize ) ); + + verify_noerr( SetControlData( (ControlRef) m_macControl , 0, datatag, sizeof(CFStringRef), &value ) ); + verify_noerr( SetControlData( (ControlRef) m_macControl , 0, kControlEditTextSelectionTag, sizeof(ControlEditTextSelectionRec), &sel ) ); + + CFRelease( value ) ; + } +#endif } void wxTextCtrl::MacEnabledStateChanged() @@ -800,10 +918,10 @@ void wxTextCtrl::MacEnabledStateChanged() wxString wxTextCtrl::GetValue() const { - Size actualSize = 0; wxString result ; +#if wxMAC_USE_MLTE OSStatus err ; - + Size actualSize = 0; { #if wxUSE_UNICODE Handle theText ; @@ -862,13 +980,35 @@ wxString wxTextCtrl::GetValue() const } #endif } +#else + CFStringRef value = NULL ; + Size actualSize = 0 ; + + verify_noerr( GetControlData( (ControlRef) m_macControl , 0, GetWindowStyle() & wxTE_PASSWORD ? + kControlEditTextPasswordCFStringTag : kControlEditTextCFStringTag, + sizeof(CFStringRef), &value, &actualSize ) ); + if ( value ) + { + wxMacCFStringHolder cf(value) ; + result = cf.AsString() ; + } +#endif wxMacConvertNewlines10To13( &result ) ; return result ; } void wxTextCtrl::GetSelection(long* from, long* to) const -{ +{ +#if wxMAC_USE_MLTE TXNGetSelection( (TXNObject) m_macTXN , (TXNOffset*) from , (TXNOffset*) to ) ; +#else + ControlEditTextSelectionRec sel ; + Size actualSize ; + verify_noerr( GetControlData( (ControlRef) m_macControl , 0, kControlEditTextSelectionTag, + sizeof(ControlEditTextSelectionRec), &sel, &actualSize ) ); + if ( from ) *from = sel.selStart ; + if ( to ) *to = sel.selEnd ; +#endif } void wxTextCtrl::SetValue(const wxString& str) @@ -879,21 +1019,30 @@ void wxTextCtrl::SetValue(const wxString& str) wxString st = str ; wxMacConvertNewlines13To10( &st ) ; - +#if wxMAC_USE_MLTE { wxMacWindowClipper c( this ) ; bool formerEditable = m_editable ; if ( !formerEditable ) SetEditable(true) ; +#if !wxMAC_USE_MLTE_HIVIEW // otherwise scrolling might have problems ? TPUpdateVisibility( ( (STPTextPaneVars *)m_macTXNvars)->fUserPaneRec ) ; +#endif SetTXNData( (STPTextPaneVars *)m_macTXNvars , (TXNObject) m_macTXN , st , kTXNStartOffset, kTXNEndOffset ) ; TXNSetSelection( (TXNObject) m_macTXN, 0, 0); TXNShowSelection( (TXNObject) m_macTXN, kTXNShowStart); if ( !formerEditable ) SetEditable(formerEditable) ; } +#else + wxMacCFStringHolder cf(st , m_font.GetEncoding() ) ; + CFStringRef value = cf ; + verify_noerr( SetControlData( (ControlRef) m_macControl , 0, GetWindowStyle() & wxTE_PASSWORD ? + kControlEditTextPasswordCFStringTag : kControlEditTextCFStringTag, + sizeof(CFStringRef), &value ) ); +#endif } void wxTextCtrl::SetMaxLength(unsigned long len) @@ -906,6 +1055,7 @@ bool wxTextCtrl::SetFont( const wxFont& font ) if ( !wxTextCtrlBase::SetFont( font ) ) return FALSE ; +#if wxMAC_USE_MLTE wxMacWindowClipper c( this ) ; bool formerEditable = m_editable ; if ( !formerEditable ) @@ -942,11 +1092,13 @@ bool wxTextCtrl::SetFont( const wxFont& font ) if ( !formerEditable ) SetEditable(formerEditable) ; +#endif return true ; } bool wxTextCtrl::SetStyle(long start, long end, const wxTextAttr& style) { +#if wxMAC_USE_MLTE bool formerEditable = m_editable ; if ( !formerEditable ) SetEditable(true) ; @@ -995,7 +1147,7 @@ bool wxTextCtrl::SetStyle(long start, long end, const wxTextAttr& style) } if ( !formerEditable ) SetEditable(formerEditable) ; - +#endif return TRUE ; } @@ -1011,9 +1163,11 @@ void wxTextCtrl::Copy() { if (CanCopy()) { +#if wxMAC_USE_MLTE ClearCurrentScrap(); TXNCopy((TXNObject)m_macTXN); TXNConvertToPublicScrap(); +#endif } } @@ -1021,10 +1175,11 @@ void wxTextCtrl::Cut() { if (CanCut()) { +#if wxMAC_USE_MLTE ClearCurrentScrap(); TXNCut((TXNObject)m_macTXN); TXNConvertToPublicScrap(); - +#endif wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, m_windowId); event.SetString( GetValue() ) ; event.SetEventObject( this ); @@ -1036,11 +1191,11 @@ void wxTextCtrl::Paste() { if (CanPaste()) { - +#if wxMAC_USE_MLTE TXNConvertFromPublicScrap(); TXNPaste((TXNObject)m_macTXN); SetStyle( kTXNUseCurrentSelection , kTXNUseCurrentSelection , GetDefaultStyle() ) ; - +#endif wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, m_windowId); event.SetString( GetValue() ) ; event.SetEventObject( this ); @@ -1073,7 +1228,11 @@ bool wxTextCtrl::CanPaste() const if (!IsEditable()) return FALSE; +#if wxMAC_USE_MLTE return TXNIsScrapPastable() ; +#else + return true ; +#endif } void wxTextCtrl::SetEditable(bool editable) @@ -1081,11 +1240,14 @@ void wxTextCtrl::SetEditable(bool editable) if ( editable != m_editable ) { m_editable = editable ; - +#if wxMAC_USE_MLTE TXNControlTag tag[] = { kTXNIOPrivilegesTag } ; TXNControlData data[] = { { editable ? kTXNReadWrite : kTXNReadOnly } } ; TXNSetTXNObjectControls( (TXNObject) m_macTXN , false , sizeof(tag) / sizeof (TXNControlTag) , tag , data ) ; - +#else + Boolean value = !editable ; + ::SetControlData( (ControlHandle) m_macControl, 0, kControlEditTextLockedTag , sizeof( value ) , &value ) ; +#endif } } @@ -1109,8 +1271,9 @@ long wxTextCtrl::GetInsertionPoint() const long wxTextCtrl::GetLastPosition() const { + long actualsize = 0 ; +#if wxMAC_USE_MLTE Handle theText ; - long actualsize ; OSErr err = TXNGetDataEncoded( (TXNObject) m_macTXN, kTXNStartOffset, kTXNEndOffset, &theText , kTXNTextData ); /* all done */ if ( err ) @@ -1122,11 +1285,13 @@ long wxTextCtrl::GetLastPosition() const actualsize = GetHandleSize( theText ) ; DisposeHandle( theText ) ; } +#endif return actualsize ; } void wxTextCtrl::Replace(long from, long to, const wxString& str) { +#if wxMAC_USE_MLTE wxString value = str ; wxMacConvertNewlines13To10( &value ) ; @@ -1140,10 +1305,12 @@ void wxTextCtrl::Replace(long from, long to, const wxString& str) SetEditable( formerEditable ) ; Refresh() ; +#endif } void wxTextCtrl::Remove(long from, long to) { +#if wxMAC_USE_MLTE bool formerEditable = m_editable ; if ( !formerEditable ) SetEditable(true) ; @@ -1153,20 +1320,26 @@ void wxTextCtrl::Remove(long from, long to) SetEditable( formerEditable ) ; Refresh() ; +#endif } void wxTextCtrl::SetSelection(long from, long to) { - STPTextPaneVars *varsp = (STPTextPaneVars *) m_macTXNvars; - /* and our drawing environment as the operation - may force a redraw in the text area. */ - SetPort(varsp->fDrawingEnvironment); +#if wxMAC_USE_MLTE /* change the selection */ if ((from == -1) && (to == -1)) TXNSelectAll((TXNObject) m_macTXN); else - TXNSetSelection( varsp->fTXNRec, from, to); + TXNSetSelection( (TXNObject) m_macTXN, from, to); TXNShowSelection( (TXNObject) m_macTXN, kTXNShowStart); +#else + ControlEditTextSelectionRec sel ; + sel.selStart = from ; + sel.selEnd = to ; + verify_noerr( SetControlData( (ControlRef) m_macControl , 0, kControlEditTextSelectionTag, + sizeof(ControlEditTextSelectionRec), &sel ) ); + +#endif } bool wxTextCtrl::LoadFile(const wxString& file) @@ -1179,23 +1352,141 @@ bool wxTextCtrl::LoadFile(const wxString& file) return FALSE; } -void wxTextCtrl::WriteText(const wxString& str) +class wxMacFunctor { - wxString st = str ; - wxMacConvertNewlines13To10( &st ) ; +public : + wxMacFunctor(){} + virtual ~wxMacFunctor() {} + virtual void* operator()() = 0 ; + static void* CallBackProc(void *param) + { + wxMacFunctor* f = (wxMacFunctor*) param ; + void *result = (*f)() ; + return result ; + } +} ; - bool formerEditable = m_editable ; - if ( !formerEditable ) - SetEditable(true) ; - long start , end , dummy ; - GetSelection( &start , &dummy ) ; - SetTXNData( (STPTextPaneVars *)m_macTXNvars , (TXNObject) m_macTXN , st , kTXNUseCurrentSelection, kTXNUseCurrentSelection ) ; - GetSelection( &dummy , &end ) ; - SetStyle( start , end , GetDefaultStyle() ) ; - if ( !formerEditable ) - SetEditable( formerEditable ) ; +template +class wxMacObjectFunctor1 : public wxMacFunctor +{ + typedef void (classtype::*function)( param1type p1 ) ; + typedef void (classtype::*ref_function)( const param1type& p1 ) ; +public : + wxMacObjectFunctor1( classtype *obj , function f , param1type p1 ) : + wxMacFunctor( ) + { + m_object = obj ; + m_function = f ; + m_param1 = p1 ; + } + + wxMacObjectFunctor1( classtype *obj , ref_function f , param1type p1 ) : + wxMacFunctor( ) + { + m_object = obj ; + m_refFunction = f ; + m_param1 = p1 ; + } + + ~wxMacObjectFunctor1() {} + + virtual void* operator()() + { + (m_object->*m_function)(m_param1) ; + return NULL ; + } +private : + classtype* m_object ; + param1type m_param1 ; + union + { + function m_function ; + ref_function m_refFunction ; + } ; +} ; + +template +void* wxMacMPRemoteCall( classtype *object , void (classtype::*function)( param1type p1 ) , param1type p1 ) +{ + wxMacObjectFunctor1 params(object,function,p1) ; + void *result = + MPRemoteCall( wxMacFunctor::CallBackProc , ¶ms , kMPOwningProcessRemoteContext ) ; + return result ; +} + +template +void* wxMacMPRemoteCall( classtype *object , void (classtype::*function)( const param1type& p1 ) , param1type p1 ) +{ + wxMacObjectFunctor1 params(object,function,p1) ; + void *result = + MPRemoteCall( wxMacFunctor::CallBackProc , ¶ms , kMPOwningProcessRemoteContext ) ; + return result ; +} + +template +void* wxMacMPRemoteGUICall( classtype *object , void (classtype::*function)( param1type p1 ) , param1type p1 ) +{ + wxMutexGuiLeave() ; + void *result = wxMacMPRemoteCall( object , function , p1 ) ; + wxMutexGuiEnter() ; + return result ; +} + +template +void* wxMacMPRemoteGUICall( classtype *object , void (classtype::*function)( const param1type& p1 ) , param1type p1 ) +{ + wxMutexGuiLeave() ; + void *result = wxMacMPRemoteCall( object , function , p1 ) ; + wxMutexGuiEnter() ; + return result ; +} + +void wxTextCtrl::WriteText(const wxString& str) +{ + if ( !wxIsMainThread() ) + { + // unfortunately CW 8 is not able to correctly deduce the template types, so we have + // to instantiate explicitely + wxMacMPRemoteGUICall( this , &wxTextCtrl::WriteText , str ) ; + return ; + } + else + { + wxString st = str ; + wxMacConvertNewlines13To10( &st ) ; + #if wxMAC_USE_MLTE + bool formerEditable = m_editable ; + if ( !formerEditable ) + SetEditable(true) ; + { + wxMacWindowStateSaver s( this ) ; + long start , end , dummy ; + GetSelection( &start , &dummy ) ; + SetTXNData( (STPTextPaneVars *)m_macTXNvars , (TXNObject) m_macTXN , st , kTXNUseCurrentSelection, kTXNUseCurrentSelection ) ; + GetSelection( &dummy , &end ) ; + SetStyle( start , end , GetDefaultStyle() ) ; + } + if ( !formerEditable ) + SetEditable( formerEditable ) ; - MacRedrawControl() ; + MacRedrawControl() ; + #else + #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2 + wxMacCFStringHolder cf(st , m_font.GetEncoding() ) ; + CFStringRef value = cf ; + SetControlData( (ControlRef) m_macControl , 0, kControlEditTextInsertCFStringRefTag, + sizeof(CFStringRef), &value ); + #else + wxString val = GetValue() ; + long start , end ; + GetSelection( &start , &end ) ; + val.Remove( start , end - start ) ; + val.insert( start , str ) ; + SetValue( val ) ; + SetInsertionPoint( start + str.Length() ) ; + #endif + #endif + } } void wxTextCtrl::AppendText(const wxString& text) @@ -1206,6 +1497,7 @@ void wxTextCtrl::AppendText(const wxString& text) void wxTextCtrl::Clear() { +#if wxMAC_USE_MLTE bool formerEditable = m_editable ; if ( !formerEditable ) SetEditable(true) ; @@ -1216,6 +1508,9 @@ void wxTextCtrl::Clear() SetEditable( formerEditable ) ; Refresh() ; +#else + SetValue(wxEmptyString) ; +#endif } bool wxTextCtrl::IsModified() const @@ -1256,6 +1551,13 @@ wxSize wxTextCtrl::DoGetBestSize() const break ; } +#if !wxMAC_USE_MLTE + // unicode text control is using client size, ie 3 pixels on every side + // TODO make this fit into normal window size concept, probably having + // to reintroduce the margin vars + hText -= 6 ; +#endif + if ( m_windowStyle & wxTE_MULTILINE ) { hText *= 5 ; @@ -1272,7 +1574,9 @@ void wxTextCtrl::Undo() { if (CanUndo()) { +#if wxMAC_USE_MLTE TXNUndo((TXNObject)m_macTXN); +#endif } } @@ -1280,7 +1584,9 @@ void wxTextCtrl::Redo() { if (CanRedo()) { +#if wxMAC_USE_MLTE TXNRedo((TXNObject)m_macTXN); +#endif } } @@ -1290,7 +1596,11 @@ bool wxTextCtrl::CanUndo() const { return false ; } +#if wxMAC_USE_MLTE return TXNCanUndo((TXNObject)m_macTXN,NULL); +#else + return false ; +#endif } bool wxTextCtrl::CanRedo() const @@ -1299,7 +1609,11 @@ bool wxTextCtrl::CanRedo() const { return false ; } +#if wxMAC_USE_MLTE return TXNCanRedo((TXNObject)m_macTXN,NULL); +#else + return false ; +#endif } // Makes modifie or unmodified @@ -1315,24 +1629,98 @@ void wxTextCtrl::DiscardEdits() int wxTextCtrl::GetNumberOfLines() const { - ItemCount lines ; + ItemCount lines = 0 ; +#if wxMAC_USE_MLTE TXNGetLineCount((TXNObject)m_macTXN, &lines ) ; +#endif return lines ; } long wxTextCtrl::XYToPosition(long x, long y) const { - // TODO +#if wxMAC_USE_MLTE + Point curpt ; + + long lastpos = GetLastPosition() ; + + // TODO find a better implementation : while we can get the + // line metrics of a certain line, we don't get its starting + // position, so it would probably be rather a binary search + // for the start position + long xpos = 0 ; + long ypos = 0 ; + int lastHeight = 0 ; + + ItemCount n ; + for ( n = 0 ; n <= (ItemCount) lastpos ; ++n ) + { + if ( y == ypos && x == xpos ) + return n ; + + TXNOffsetToPoint( (TXNObject) m_macTXN, n , &curpt); + + if ( curpt.v > lastHeight ) + { + xpos = 0 ; + if ( n > 0 ) + ++ypos ; + lastHeight = curpt.v ; + } + else + ++xpos ; + } +#endif return 0; } bool wxTextCtrl::PositionToXY(long pos, long *x, long *y) const { +#if wxMAC_USE_MLTE + Point curpt ; + + long lastpos = GetLastPosition() ; + + if ( y ) *y = 0 ; + if ( x ) *x = 0 ; + + if ( pos <= lastpos ) + { + // TODO find a better implementation : while we can get the + // line metrics of a certain line, we don't get its starting + // position, so it would probably be rather a binary search + // for the start position + long xpos = 0 ; + long ypos = 0 ; + int lastHeight = 0 ; + + ItemCount n ; + for ( n = 0 ; n <= (ItemCount) pos ; ++n ) + { + TXNOffsetToPoint( (TXNObject) m_macTXN, n , &curpt); + + if ( curpt.v > lastHeight ) + { + xpos = 0 ; + if ( n > 0 ) + ++ypos ; + lastHeight = curpt.v ; + } + else + ++xpos ; + } + if ( y ) *y = ypos ; + if ( x ) *x = xpos ; + } +#else + if ( y ) *y = 0 ; + if ( x ) *x = 0 ; +#endif return FALSE ; } void wxTextCtrl::ShowPosition(long pos) { +#if wxMAC_USE_MLTE #if TARGET_RT_MAC_MACHO && defined(AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER) { Point current ; @@ -1353,61 +1741,90 @@ void wxTextCtrl::ShowPosition(long pos) } } #endif +#endif } int wxTextCtrl::GetLineLength(long lineNo) const { - // TODO change this if possible to reflect real lines - wxString content = GetValue() ; - - // Find line first - int count = 0; - for (size_t i = 0; i < content.Length() ; i++) +#if wxMAC_USE_MLTE + Point curpt ; + if ( lineNo < GetNumberOfLines() ) { - if (count == lineNo) + // TODO find a better implementation : while we can get the + // line metrics of a certain line, we don't get its starting + // position, so it would probably be rather a binary search + // for the start position + long xpos = 0 ; + long ypos = 0 ; + int lastHeight = 0 ; + long lastpos = GetLastPosition() ; + + ItemCount n ; + for ( n = 0 ; n <= (ItemCount) lastpos ; ++n ) { - // Count chars in line then - count = 0; - for (size_t j = i; j < content.Length(); j++) + TXNOffsetToPoint( (TXNObject) m_macTXN, n , &curpt); + + if ( curpt.v > lastHeight ) { - count++; - if (content[j] == '\n') return count; + if ( ypos == lineNo ) + return xpos ; + + xpos = 0 ; + if ( n > 0 ) + ++ypos ; + lastHeight = curpt.v ; } - - return count; + else + ++xpos ; } - if (content[i] == '\n') count++; } +#endif return 0; } wxString wxTextCtrl::GetLineText(long lineNo) const { - // TODO change this if possible to reflect real lines + wxString line ; +#if wxMAC_USE_MLTE + Point curpt ; wxString content = GetValue() ; - // Find line first - int count = 0; - for (size_t i = 0; i < content.Length() ; i++) + if ( lineNo < GetNumberOfLines() ) { - if (count == lineNo) + // TODO find a better implementation : while we can get the + // line metrics of a certain line, we don't get its starting + // position, so it would probably be rather a binary search + // for the start position + long xpos = 0 ; + long ypos = 0 ; + int lastHeight = 0 ; + long lastpos = GetLastPosition() ; + + ItemCount n ; + for ( n = 0 ; n <= (ItemCount)lastpos ; ++n ) { - // Add chars in line then - wxString tmp; + TXNOffsetToPoint( (TXNObject) m_macTXN, n , &curpt); - for (size_t j = i; j < content.Length(); j++) + if ( curpt.v > lastHeight ) { - if (content[j] == '\n') - return tmp; - - tmp += content[j]; + if ( ypos == lineNo ) + return line ; + + xpos = 0 ; + if ( n > 0 ) + ++ypos ; + lastHeight = curpt.v ; + } + else + { + if ( ypos == lineNo ) + line += content[n] ; + ++xpos ; } - - return tmp; } - if (content[i] == '\n') count++; } - return wxEmptyString ; +#endif + return line ; } /* @@ -1495,7 +1912,7 @@ void wxTextCtrl::OnChar(wxKeyEvent& event) } } - // this will make wxWindows eat the ENTER key so that + // this will make wxWidgets eat the ENTER key so that // we actually prevent line wrapping in a single line // text control eat_key = TRUE;