]> git.saurik.com Git - wxWidgets.git/blobdiff - src/mac/carbon/textctrl.cpp
security fix to wxSingleInstanceChecker: check if the lock file was really created...
[wxWidgets.git] / src / mac / carbon / textctrl.cpp
index e99c566bdd7bfc23007513682e591bc0029ef2af..a522f2e9e9edba7926bf7663970a27cbe77dd467 100644 (file)
@@ -62,7 +62,7 @@
 
 #define TE_UNLIMITED_LENGTH 0xFFFFFFFFUL
 #if TARGET_API_MAC_OSX
- #define wxMAC_USE_MLTE 1
+ #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
@@ -784,10 +784,31 @@ bool wxTextCtrl::Create(wxWindow *parent, wxWindowID id,
     {
 #if wxMAC_USE_MLTE_HIVIEW
         HIRect hr = { bounds.left , bounds.top , bounds.right - bounds.left , bounds.bottom- bounds.top } ;
-        HITextViewCreate( &hr , 0, FrameOptionsFromWXStyle( m_windowStyle ) , (ControlRef*) &m_macControl ) ;
-        m_macTXN = HITextViewGetTXNObject((ControlRef) m_macControl) ;
-        AdjustAttributesFromWXStyle( (TXNObject) m_macTXN , m_windowStyle , true ) ;
-        HIViewSetVisible( (ControlRef) m_macControl , true ) ;
+        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;
 
@@ -795,8 +816,8 @@ bool wxTextCtrl::Create(wxWindow *parent, wxWindowID id,
                 | 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 );
@@ -838,15 +859,23 @@ bool wxTextCtrl::Create(wxWindow *parent, wxWindowID id,
     tback.bg.color = MAC_WXCOLORREF( GetBackgroundColour().GetPixel() );
     TXNSetBackground( (TXNObject) m_macTXN , &tback);
 
-    if ( m_windowStyle & wxTE_READONLY)
-    {
-        SetEditable( false ) ;
-    }
 #else
     wxMacCFStringHolder cf(st , m_font.GetEncoding()) ;
-    CreateEditUnicodeTextControl( MAC_WXHWND(parent->MacGetTopLevelWindowRef()), &bounds , cf , style & wxTE_PASSWORD , NULL , (ControlRef*) &m_macControl ) ;
+    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;
@@ -854,11 +883,32 @@ bool wxTextCtrl::Create(wxWindow *parent, wxWindowID id,
 
 void wxTextCtrl::MacVisibilityChanged() 
 {
-#if wxMAC_USE_MLTE && !wxMAC_USE_MLTE_HIVIEW
+#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() 
@@ -1194,6 +1244,9 @@ void wxTextCtrl::SetEditable(bool editable)
         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
     }
 }
@@ -1218,9 +1271,9 @@ long wxTextCtrl::GetInsertionPoint() const
 
 long wxTextCtrl::GetLastPosition() const
 {
-    Handle theText ;
     long actualsize = 0 ;
 #if wxMAC_USE_MLTE
+    Handle theText ;
     OSErr err = TXNGetDataEncoded( (TXNObject) m_macTXN, kTXNStartOffset, kTXNEndOffset, &theText , kTXNTextData );
     /* all done */
     if ( err )
@@ -1299,32 +1352,141 @@ bool wxTextCtrl::LoadFile(const wxString& file)
     return FALSE;
 }
 
+class wxMacFunctor
+{
+public :  
+    wxMacFunctor(){}
+    virtual ~wxMacFunctor() {}
+    virtual void* operator()() = 0 ;
+    static void* CallBackProc(void *param) 
+    {
+        wxMacFunctor* f = (wxMacFunctor*) param ;
+        void *result = (*f)() ;
+        return result ;
+    }
+} ;
+
+template<typename classtype,typename param1type>
+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<typename classtype, typename param1type> 
+void* wxMacMPRemoteCall( classtype *object , void (classtype::*function)( param1type p1 ) , param1type p1 )
+{
+    wxMacObjectFunctor1<classtype,param1type> params(object,function,p1) ;   
+    void *result = 
+        MPRemoteCall( wxMacFunctor::CallBackProc , &params  , kMPOwningProcessRemoteContext ) ;
+    return result ;
+}
+
+template<typename classtype, typename param1type> 
+void* wxMacMPRemoteCall( classtype *object , void (classtype::*function)( const param1type& p1 ) , param1type p1 )
+{
+    wxMacObjectFunctor1<classtype,param1type> params(object,function,p1) ;   
+    void *result = 
+        MPRemoteCall( wxMacFunctor::CallBackProc , &params  , kMPOwningProcessRemoteContext ) ;
+    return result ;
+}
+
+template<typename classtype, typename param1type> 
+void* wxMacMPRemoteGUICall( classtype *object , void (classtype::*function)( param1type p1 ) , param1type p1 )
+{
+    wxMutexGuiLeave() ;
+    void *result = wxMacMPRemoteCall( object , function , p1 ) ;
+    wxMutexGuiEnter() ;
+    return result ;
+}
+
+template<typename classtype, typename param1type> 
+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)
 {
-    wxString st = str ;
-    wxMacConvertNewlines13To10( &st ) ;
-#if wxMAC_USE_MLTE
-    bool formerEditable = m_editable ;
-    if ( !formerEditable )
-        SetEditable(true) ;
+    if ( !wxIsMainThread() )
     {
-        wxMacWindowStateSaver( 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() ) ;
+        // unfortunately CW 8 is not able to correctly deduce the template types, so we have 
+        // to instantiate explicitely
+        wxMacMPRemoteGUICall<wxTextCtrl,wxString>( this , &wxTextCtrl::WriteText , str ) ;
+        return ;
     }
-    if ( !formerEditable )
-        SetEditable( formerEditable ) ;
+    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() ;
-#else
-    wxMacCFStringHolder cf(st , m_font.GetEncoding() ) ;
-    CFStringRef value = cf ;
-    SetControlData(  (ControlRef) m_macControl , 0, kControlEditTextInsertCFStringRefTag, 
-        sizeof(CFStringRef), &value );
-#endif
+        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)
@@ -1389,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 ;
@@ -1483,7 +1652,7 @@ long wxTextCtrl::XYToPosition(long x, long y) const
     int lastHeight = 0 ;
 
     ItemCount n ;
-    for ( n = 0 ; n <= lastpos ; ++n )
+    for ( n = 0 ; n <= (ItemCount) lastpos ; ++n )
     {
         if ( y == ypos && x == xpos )
             return n ;
@@ -1525,7 +1694,7 @@ bool wxTextCtrl::PositionToXY(long pos, long *x, long *y) const
         int lastHeight = 0 ;
 
         ItemCount n ;
-        for ( n = 0 ; n <= pos ; ++n )
+        for ( n = 0 ; n <= (ItemCount) pos ; ++n )
         {
             TXNOffsetToPoint( (TXNObject) m_macTXN,  n , &curpt);
 
@@ -1591,7 +1760,7 @@ int wxTextCtrl::GetLineLength(long lineNo) const
         long lastpos = GetLastPosition() ;
 
         ItemCount n ;
-        for ( n = 0 ; n <= lastpos ; ++n )
+        for ( n = 0 ; n <= (ItemCount) lastpos ; ++n )
         {
             TXNOffsetToPoint( (TXNObject) m_macTXN,  n , &curpt);
 
@@ -1615,9 +1784,9 @@ int wxTextCtrl::GetLineLength(long lineNo) const
 
 wxString wxTextCtrl::GetLineText(long lineNo) const
 {
-    Point curpt ;
     wxString line ;
 #if wxMAC_USE_MLTE
+    Point curpt ;
     wxString content = GetValue() ;
 
     if ( lineNo < GetNumberOfLines() )
@@ -1632,7 +1801,7 @@ wxString wxTextCtrl::GetLineText(long lineNo) const
         long lastpos = GetLastPosition() ;
 
         ItemCount n ;
-        for ( n = 0 ; n <= lastpos ; ++n )
+        for ( n = 0 ; n <= (ItemCount)lastpos ; ++n )
         {
             TXNOffsetToPoint( (TXNObject) m_macTXN,  n , &curpt);
 
@@ -1743,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;