📄 textctrl.cpp
字号:
TXNSetBackground( m_txn , &tback );
}
void wxMacMLTEControl::TXNSetAttribute( const wxTextAttr& style , long from , long to )
{
TXNTypeAttributes typeAttr[4] ;
RGBColor color ;
int attrCount = 0 ;
if ( style.HasFont() )
{
const wxFont &font = style.GetFont() ;
#if 0 // old version
Str255 fontName = "\pMonaco" ;
SInt16 fontSize = 12 ;
Style fontStyle = normal ;
wxMacStringToPascal( font.GetFaceName() , fontName ) ;
fontSize = font.GetPointSize() ;
if ( font.GetUnderlined() )
fontStyle |= underline ;
if ( font.GetWeight() == wxBOLD )
fontStyle |= bold ;
if ( font.GetStyle() == wxITALIC )
fontStyle |= italic ;
typeAttr[attrCount].tag = kTXNQDFontNameAttribute ;
typeAttr[attrCount].size = kTXNQDFontNameAttributeSize ;
typeAttr[attrCount].data.dataPtr = (void*)fontName ;
attrCount++ ;
typeAttr[attrCount].tag = kTXNQDFontSizeAttribute ;
typeAttr[attrCount].size = kTXNFontSizeAttributeSize ;
typeAttr[attrCount].data.dataValue = (fontSize << 16) ;
attrCount++ ;
typeAttr[attrCount].tag = kTXNQDFontStyleAttribute ;
typeAttr[attrCount].size = kTXNQDFontStyleAttributeSize ;
typeAttr[attrCount].data.dataValue = fontStyle ;
attrCount++ ;
#else
typeAttr[attrCount].tag = kTXNATSUIStyle ;
typeAttr[attrCount].size = kTXNATSUIStyleSize ;
typeAttr[attrCount].data.dataValue = (UInt32)font.MacGetATSUStyle() ;
attrCount++ ;
#endif
}
if ( style.HasTextColour() )
{
color = MAC_WXCOLORREF(style.GetTextColour().GetPixel()) ;
typeAttr[attrCount].tag = kTXNQDFontColorAttribute ;
typeAttr[attrCount].size = kTXNQDFontColorAttributeSize ;
typeAttr[attrCount].data.dataPtr = (void*) &color ;
attrCount++ ;
}
if ( attrCount > 0 )
{
verify_noerr( TXNSetTypeAttributes( m_txn , attrCount , typeAttr, from , to ) );
// unfortunately the relayout is not automatic
TXNRecalcTextLayout( m_txn );
}
}
void wxMacMLTEControl::SetFont( const wxFont & font , const wxColour& foreground , long 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()
{
ClearCurrentScrap();
TXNCopy( m_txn );
TXNConvertToPublicScrap();
}
void wxMacMLTEControl::Cut()
{
ClearCurrentScrap();
TXNCut( m_txn );
TXNConvertToPublicScrap();
}
void wxMacMLTEControl::Paste()
{
TXNConvertFromPublicScrap();
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 ) ;
wxMacWindowClipper c( m_peer ) ;
TXNSetSelection( m_txn, from, to ) ;
TXNClear( m_txn ) ;
SetTXNData( value, kTXNUseCurrentSelection, kTXNUseCurrentSelection ) ;
}
void wxMacMLTEControl::Remove( long from , long to )
{
wxMacWindowClipper c( m_peer ) ;
wxMacEditHelper help( m_txn ) ;
TXNSetSelection( m_txn , from , to ) ;
TXNClear( m_txn ) ;
}
void wxMacMLTEControl::GetSelection( long* from, long* to) const
{
TXNGetSelection( m_txn , (TXNOffset*) from , (TXNOffset*) to ) ;
}
void wxMacMLTEControl::SetSelection( long from , long to )
{
wxMacWindowClipper c( m_peer ) ;
// change the selection
if ((from == -1) && (to == -1))
TXNSelectAll( m_txn );
else
TXNSetSelection( m_txn, from, to );
TXNShowSelection( m_txn, kTXNShowStart );
}
void wxMacMLTEControl::WriteText( const wxString& str )
{
wxString st = str ;
wxMacConvertNewlines10To13( &st ) ;
long start , end , dummy ;
GetSelection( &start , &dummy ) ;
wxMacWindowClipper c( m_peer ) ;
{
wxMacEditHelper helper( m_txn ) ;
SetTXNData( st, kTXNUseCurrentSelection, kTXNUseCurrentSelection ) ;
}
GetSelection( &dummy, &end ) ;
// TODO: SetStyle( start , end , GetDefaultStyle() ) ;
}
void wxMacMLTEControl::Clear()
{
wxMacWindowClipper c( m_peer ) ;
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 )
{
xpos = 0 ;
if ( n > 0 )
++ypos ;
lastHeight = curpt.v ;
}
else
++xpos ;
}
if ( y )
*y = ypos ;
if ( x )
*x = xpos ;
}
return false ;
}
void wxMacMLTEControl::ShowPosition( long pos )
{
#if TARGET_RT_MAC_MACHO && defined(AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER)
{
Point current, desired ;
TXNOffset selstart, selend;
TXNGetSelection( m_txn, &selstart, &selend );
TXNOffsetToPoint( m_txn, selstart, ¤t );
TXNOffsetToPoint( m_txn, pos, &desired );
// TODO: use HIPoints for 10.3 and above
if ( (UInt32)TXNScroll != (UInt32)kUnresolvedCFragSymbolAddress )
{
OSErr theErr = noErr;
SInt32 dv = desired.v - current.v;
SInt32 dh = desired.h - current.h;
TXNShowSelection( m_txn, kTXNShowStart ) ; // NB: should this be kTXNShowStart or kTXNShowEnd ??
theErr = TXNScroll( m_txn, kTXNScrollUnitsInPixels, kTXNScrollUnitsInPixels, &dv, &dh );
// there will be an error returned for classic MLTE implementation when the control is
// invisible, but HITextView works correctly, so we don't assert that one
// wxASSERT_MSG( theErr == noErr, _T("TXNScroll returned an error!") );
}
}
#endif
}
void wxMacMLTEControl::SetTXNData( const wxString& st, TXNOffset start, TXNOffset end )
{
#if wxUSE_UNICODE
#if SIZEOF_WCHAR_T == 2
size_t len = st.length() ;
TXNSetData( m_txn, kTXNUnicodeTextData, (void*)st.wc_str(), len * 2, start, end );
#else
wxMBConvUTF16 converter ;
ByteCount byteBufferLen = converter.WC2MB( NULL, st.wc_str(), 0 ) ;
UniChar *unibuf = (UniChar*)malloc( byteBufferLen ) ;
converter.WC2MB( (char*)unibuf, st.wc_str(), byteBufferLen ) ;
TXNSetData( m_txn, kTXNUnicodeTextData, (void*)unibuf, byteBufferLen, start, end ) ;
free( unibuf ) ;
#endif
#else
wxCharBuffer text = st.mb_str( wxConvLocal ) ;
TXNSetData( m_txn, kTXNTextData, (void*)text.data(), strlen( text ), start, end ) ;
#endif
}
wxString wxMacMLTEControl::GetLineText(long lineNo) const
{
wxString line ;
if ( lineNo < GetNumberOfLines() )
{
Point firstPoint;
Fixed lineWidth, lineHeight, currentHeight;
long ypos ;
// get the first possible position in the control
TXNOffsetToPoint(m_txn, 0, &firstPoint);
// Iterate through the lines until we reach the one we want,
// adding to our current y pixel point position
ypos = 0 ;
currentHeight = 0;
while (ypos < lineNo)
{
TXNGetLineMetrics(m_txn, ypos++, &lineWidth, &lineHeight);
currentHeight += lineHeight;
}
Point thePoint = { firstPoint.v + (currentHeight >> 16), firstPoint.h + (0) };
TXNOffset theOffset;
TXNPointToOffset(m_txn, thePoint, &theOffset);
wxString content = GetStringValue() ;
Point currentPoint = thePoint;
while (thePoint.v == currentPoint.v && theOffset < content.length())
{
line += content[theOffset];
TXNOffsetToPoint(m_txn, ++theOffset, ¤tPoint);
}
}
return line ;
}
int wxMacMLTEControl::GetLineLength(long lineNo) const
{
int theLength = 0;
if ( lineNo < GetNumberOfLines() )
{
Point firstPoint;
Fixed lineWidth, lineHeight, currentHeight;
long ypos;
// get the first possible position in the control
TXNOffsetToPoint(m_txn, 0, &firstPoint);
// Iterate through the lines until we reach the one we want,
// adding to our current y pixel point position
ypos = 0;
currentHeight = 0;
while (ypos < lineNo)
{
TXNGetLineMetrics(m_txn, ypos++, &lineWidth, &lineHeight);
currentHeight += lineHeight;
}
Point thePoint = { firstPoint.v + (currentHeight >> 16), firstPoint.h + (0) };
TXNOffset theOffset;
TXNPointToOffset(m_txn, thePoint, &theOffset);
wxString content = GetStringValue() ;
Point currentPoint = thePoint;
while (thePoint.v == currentPoint.v && theOffset < content.length())
{
++theLength;
TXNOffsetToPoint(m_txn, ++theOffset, ¤tPoint);
}
}
return theLength ;
}
// ----------------------------------------------------------------------------
// MLTE control implementation (classic part)
// ----------------------------------------------------------------------------
// OS X Notes : We still don't have a full replacement for MLTE, so this implementation
// has to live on. We have different problems coming from outdated implementations on the
// various OS X versions. Most deal with the scrollbars: they are not correctly embedded
// while this can be solved on 10.3 by reassigning them the correct place, on 10.2 there is
// no way out, therefore we are using our own implementation and our own scrollbars ....
#ifdef __WXMAC_OSX__
TXNScrollInfoUPP gTXNScrollInfoProc = NULL ;
ControlActionUPP gTXNScrollActionProc = NULL ;
pascal void wxMacMLTEClassicControl::TXNScrollInfoProc(
SInt32 iValue, SInt32 iMaximumValue,
TXNScrollBarOrientation iScrollBarOrientation, SInt32 iRefCon )
{
wxMacMLTEClassicControl* mlte = (wxMacMLTEClassicControl*) iRefCon ;
SInt32 value = wxMax( iValue , 0 ) ;
SInt32 maximum = wxMax( iMaximumValue , 0 ) ;
if ( iScrollBarOrientation == kTXNHorizontal )
{
if ( mlte->m_sbHorizontal )
{
SetControl32BitValue( mlte->m_sbHorizontal , value ) ;
SetControl32BitMaximum( mlte->m_sbHorizontal , maximum ) ;
mlte->m_lastHorizontalValue = value ;
}
}
else if ( iScrollBarOrientation == kTXNVertical )
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -