+ margins.rightMargin = wxConvertToTXN(style.GetRightIndent());
+ }
+ controlAttrCount++ ;
+ }
+
+ if ( style.HasTabs() )
+ {
+ const wxArrayInt& tabarray = style.GetTabs();
+ // unfortunately Mac only applies a tab distance, not individually different tabs
+ controlTags[controlAttrCount] = kTXNTabSettingsTag;
+ if ( tabarray.size() > 0 )
+ controlData[controlAttrCount].tabValue.value = wxConvertToTXN(tabarray[0]);
+ else
+ controlData[controlAttrCount].tabValue.value = 72 ;
+
+ controlData[controlAttrCount].tabValue.tabType = kTXNLeftTab;
+ controlAttrCount++ ;
+ }
+
+ // unfortunately the relayout is not automatic
+ if ( controlAttrCount > 0 )
+ {
+ verify_noerr( TXNSetTXNObjectControls (m_txn, false /* don't clear all */, controlAttrCount,
+ controlTags, controlData) );
+ relayout = true;
+ }
+
+ if ( typeAttrCount > 0 )
+ {
+ verify_noerr( TXNSetTypeAttributes( m_txn , typeAttrCount, typeAttr, from , to ) );
+ relayout = true;
+ }
+
+ if ( tabs != NULL )
+ {
+ delete[] tabs;
+ }
+
+ if ( relayout )
+ {
+ TXNRecalcTextLayout( m_txn );
+ }
+}
+
+void wxMacMLTEControl::SetFont(const wxFont & font,
+ const wxColour& foreground,
+ long WXUNUSED(windowStyle))
+{
+ wxMacEditHelper help( m_txn ) ;
+ TXNSetAttribute( wxTextAttr( foreground, wxNullColour, font ), kTXNStartOffset, kTXNEndOffset ) ;
+}
+
+void wxMacMLTEControl::SetStyle( long start, long end, const wxTextAttr& style )
+{
+ wxMacEditHelper help( m_txn ) ;
+ TXNSetAttribute( style, start, end ) ;
+}
+
+void wxMacMLTEControl::Copy()
+{
+ TXNCopy( m_txn );
+}
+
+void wxMacMLTEControl::Cut()
+{
+ TXNCut( m_txn );
+}
+
+void wxMacMLTEControl::Paste()
+{
+ TXNPaste( m_txn );
+}
+
+bool wxMacMLTEControl::CanPaste() const
+{
+ return TXNIsScrapPastable() ;
+}
+
+void wxMacMLTEControl::SetEditable(bool editable)
+{
+ TXNControlTag tag[] = { kTXNIOPrivilegesTag } ;
+ TXNControlData data[] = { { editable ? kTXNReadWrite : kTXNReadOnly } } ;
+ TXNSetTXNObjectControls( m_txn, false, WXSIZEOF(tag), tag, data ) ;
+}
+
+wxTextPos wxMacMLTEControl::GetLastPosition() const
+{
+ wxTextPos actualsize = 0 ;
+
+ Handle theText ;
+ OSErr err = TXNGetDataEncoded( m_txn, kTXNStartOffset, kTXNEndOffset, &theText, kTXNTextData );
+
+ // all done
+ if ( err == noErr )
+ {
+ actualsize = GetHandleSize( theText ) ;
+ DisposeHandle( theText ) ;
+ }
+ else
+ {
+ actualsize = 0 ;
+ }
+
+ return actualsize ;
+}
+
+void wxMacMLTEControl::Replace( long from , long to , const wxString &str )
+{
+ wxString value = str ;
+ wxMacConvertNewlines10To13( &value ) ;
+
+ wxMacEditHelper help( m_txn ) ;
+#ifndef __LP64__
+ wxMacWindowClipper c( m_peer ) ;
+#endif
+
+ TXNSetSelection( m_txn, from, to == -1 ? kTXNEndOffset : to ) ;
+ TXNClear( m_txn ) ;
+ SetTXNData( value, kTXNUseCurrentSelection, kTXNUseCurrentSelection ) ;
+}
+
+void wxMacMLTEControl::Remove( long from , long to )
+{
+#ifndef __LP64__
+ wxMacWindowClipper c( m_peer ) ;
+#endif
+ wxMacEditHelper help( m_txn ) ;
+ TXNSetSelection( m_txn , from , to ) ;
+ TXNClear( m_txn ) ;
+}
+
+void wxMacMLTEControl::GetSelection( long* from, long* to) const
+{
+ TXNOffset f,t ;
+ TXNGetSelection( m_txn , &f , &t ) ;
+ *from = f;
+ *to = t;
+}
+
+void wxMacMLTEControl::SetSelection( long from , long to )
+{
+#ifndef __LP64__
+ wxMacWindowClipper c( m_peer ) ;
+#endif
+
+ // change the selection
+ if ((from == -1) && (to == -1))
+ TXNSelectAll( m_txn );
+ else
+ TXNSetSelection( m_txn, from, to == -1 ? kTXNEndOffset : to );
+
+ TXNShowSelection( m_txn, kTXNShowStart );
+}
+
+void wxMacMLTEControl::WriteText( const wxString& str )
+{
+ wxString st = str ;
+ wxMacConvertNewlines10To13( &st ) ;
+
+ long start , end , dummy ;
+
+ GetSelection( &start , &dummy ) ;
+#ifndef __LP64__
+ wxMacWindowClipper c( m_peer ) ;
+#endif
+
+ {
+ wxMacEditHelper helper( m_txn ) ;
+ SetTXNData( st, kTXNUseCurrentSelection, kTXNUseCurrentSelection ) ;
+ }
+
+ GetSelection( &dummy, &end ) ;
+
+ // TODO: SetStyle( start , end , GetDefaultStyle() ) ;
+}
+
+void wxMacMLTEControl::Clear()
+{
+#ifndef __LP64__
+ wxMacWindowClipper c( m_peer ) ;
+#endif
+ wxMacEditHelper st( m_txn ) ;
+ TXNSetSelection( m_txn , kTXNStartOffset , kTXNEndOffset ) ;
+ TXNClear( m_txn ) ;
+}
+
+bool wxMacMLTEControl::CanUndo() const
+{
+ return TXNCanUndo( m_txn , NULL ) ;
+}
+
+void wxMacMLTEControl::Undo()
+{
+ TXNUndo( m_txn ) ;
+}
+
+bool wxMacMLTEControl::CanRedo() const
+{
+ return TXNCanRedo( m_txn , NULL ) ;
+}
+
+void wxMacMLTEControl::Redo()
+{
+ TXNRedo( m_txn ) ;
+}
+
+int wxMacMLTEControl::GetNumberOfLines() const
+{
+ ItemCount lines = 0 ;
+ TXNGetLineCount( m_txn, &lines ) ;
+
+ return lines ;
+}
+
+long wxMacMLTEControl::XYToPosition(long x, long y) const
+{
+ Point curpt ;
+ wxTextPos 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, ypos = 0 ;
+ int lastHeight = 0 ;
+ ItemCount n ;
+
+ lastpos = GetLastPosition() ;
+ for ( n = 0 ; n <= (ItemCount) lastpos ; ++n )
+ {
+ if ( y == ypos && x == xpos )
+ return n ;
+
+ TXNOffsetToPoint( m_txn, n, &curpt ) ;
+
+ if ( curpt.v > lastHeight )
+ {
+ xpos = 0 ;
+ if ( n > 0 )
+ ++ypos ;
+
+ lastHeight = curpt.v ;
+ }
+ else
+ ++xpos ;
+ }
+
+ return 0 ;
+}
+
+bool wxMacMLTEControl::PositionToXY( long pos, long *x, long *y ) const
+{
+ Point curpt ;
+ wxTextPos lastpos ;
+
+ if ( y )
+ *y = 0 ;
+ if ( x )
+ *x = 0 ;
+
+ lastpos = GetLastPosition() ;
+ 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, ypos = 0 ;
+ int lastHeight = 0 ;
+ ItemCount n ;
+
+ for ( n = 0 ; n <= (ItemCount) pos ; ++n )
+ {
+ TXNOffsetToPoint( m_txn, n, &curpt ) ;
+
+ if ( curpt.v > lastHeight )