📄 textctrl.cpp
字号:
break ;
}
return result ;
}
static pascal OSStatus wxMacUnicodeTextControlEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
{
OSStatus result = eventNotHandledErr ;
switch ( GetEventClass( event ) )
{
case kEventClassControl :
result = wxMacUnicodeTextControlControlEventHandler( handler , event , data ) ;
break ;
default :
break ;
}
return result ;
}
DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacUnicodeTextControlEventHandler )
wxMacUnicodeTextControl::wxMacUnicodeTextControl( wxTextCtrl *wxPeer,
const wxString& str,
const wxPoint& pos,
const wxSize& size, long style )
: wxMacTextControl( wxPeer )
{
m_font = wxPeer->GetFont() ;
m_windowStyle = style ;
Rect bounds = wxMacGetBoundsForControl( wxPeer , pos , size ) ;
wxString st = str ;
wxMacConvertNewlines10To13( &st ) ;
wxMacCFStringHolder cf(st , m_font.GetEncoding()) ;
CFStringRef cfr = cf ;
Boolean isPassword = ( m_windowStyle & wxTE_PASSWORD ) != 0 ;
m_valueTag = isPassword ? kControlEditTextPasswordCFStringTag : kControlEditTextCFStringTag ;
OSStatus err = CreateEditUnicodeTextControl(
MAC_WXHWND(wxPeer->MacGetTopLevelWindowRef()), &bounds , cfr ,
isPassword , NULL , &m_controlRef ) ;
verify_noerr( err );
if ( !(m_windowStyle & wxTE_MULTILINE) )
SetData<Boolean>( kControlEditTextPart , kControlEditTextSingleLineTag , true ) ;
InstallControlEventHandler( m_controlRef , GetwxMacUnicodeTextControlEventHandlerUPP(),
GetEventTypeCount(unicodeTextControlEventList), unicodeTextControlEventList, this,
&m_focusHandlerRef);
}
wxMacUnicodeTextControl::~wxMacUnicodeTextControl()
{
::RemoveEventHandler( m_focusHandlerRef );
}
void wxMacUnicodeTextControl::VisibilityChanged(bool shown)
{
if ( !(m_windowStyle & wxTE_MULTILINE) && shown )
{
// 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 ;
verify_noerr( GetData<ControlEditTextSelectionRec>( 0, kControlEditTextSelectionTag, &sel ) );
verify_noerr( GetData<CFStringRef>( 0, m_valueTag, &value ) );
verify_noerr( SetData<CFStringRef>( 0, m_valueTag, &value ) );
verify_noerr( SetData<ControlEditTextSelectionRec>( 0, kControlEditTextSelectionTag, &sel ) );
CFRelease( value ) ;
}
}
wxString wxMacUnicodeTextControl::GetStringValue() const
{
wxString result ;
CFStringRef value = GetData<CFStringRef>(0, m_valueTag) ;
if ( value )
{
wxMacCFStringHolder cf(value) ;
result = cf.AsString() ;
}
#if '\n' == 10
wxMacConvertNewlines13To10( &result ) ;
#else
wxMacConvertNewlines10To13( &result ) ;
#endif
return result ;
}
void wxMacUnicodeTextControl::SetStringValue( const wxString &str )
{
wxString st = str ;
wxMacConvertNewlines10To13( &st ) ;
wxMacCFStringHolder cf( st , m_font.GetEncoding() ) ;
verify_noerr( SetData<CFStringRef>( 0, m_valueTag , cf ) ) ;
}
void wxMacUnicodeTextControl::Copy()
{
SendHICommand( kHICommandCopy ) ;
}
void wxMacUnicodeTextControl::Cut()
{
SendHICommand( kHICommandCut ) ;
}
void wxMacUnicodeTextControl::Paste()
{
SendHICommand( kHICommandPaste ) ;
}
bool wxMacUnicodeTextControl::CanPaste() const
{
return true ;
}
void wxMacUnicodeTextControl::SetEditable(bool editable)
{
#if 0 // leads to problem because text cannot be selected anymore
SetData<Boolean>( kControlEditTextPart , kControlEditTextLockedTag , (Boolean) !editable ) ;
#endif
}
void wxMacUnicodeTextControl::GetSelection( long* from, long* to ) const
{
ControlEditTextSelectionRec sel ;
if (HasFocus())
verify_noerr( GetData<ControlEditTextSelectionRec>( 0, kControlEditTextSelectionTag, &sel ) ) ;
else
sel = m_selection ;
if ( from )
*from = sel.selStart ;
if ( to )
*to = sel.selEnd ;
}
void wxMacUnicodeTextControl::SetSelection( long from , long to )
{
ControlEditTextSelectionRec sel ;
wxString result ;
int textLength = 0 ;
CFStringRef value = GetData<CFStringRef>(0, m_valueTag) ;
if ( value )
{
wxMacCFStringHolder cf(value) ;
textLength = cf.AsString().length() ;
}
if ((from == -1) && (to == -1))
{
from = 0 ;
to = textLength ;
}
else
{
from = wxMin(textLength,wxMax(from,0)) ;
to = wxMax(0,wxMin(textLength,to)) ;
}
sel.selStart = from ;
sel.selEnd = to ;
if ( HasFocus() )
SetData<ControlEditTextSelectionRec>( 0, kControlEditTextSelectionTag, &sel ) ;
else
m_selection = sel;
}
void wxMacUnicodeTextControl::WriteText( const wxString& str )
{
wxString st = str ;
wxMacConvertNewlines10To13( &st ) ;
#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2
if ( HasFocus() )
{
wxMacCFStringHolder cf(st , m_font.GetEncoding() ) ;
CFStringRef value = cf ;
SetData<CFStringRef>( 0, kControlEditTextInsertCFStringRefTag, &value );
}
else
#endif
{
wxString val = GetStringValue() ;
long start , end ;
GetSelection( &start , &end ) ;
val.Remove( start , end - start ) ;
val.insert( start , str ) ;
SetStringValue( val ) ;
SetSelection( start + str.length() , start + str.length() ) ;
}
}
#endif
// ----------------------------------------------------------------------------
// MLTE control implementation (common part)
// ----------------------------------------------------------------------------
// if MTLE is read only, no changes at all are allowed, not even from
// procedural API, in order to allow changes via API all the same we must undo
// the readonly status while we are executing, this class helps to do so
class wxMacEditHelper
{
public :
wxMacEditHelper( TXNObject txn )
{
TXNControlTag tag[] = { kTXNIOPrivilegesTag } ;
m_txn = txn ;
TXNGetTXNObjectControls( m_txn , 1 , tag , m_data ) ;
if ( m_data[0].uValue == kTXNReadOnly )
{
TXNControlData data[] = { { kTXNReadWrite } } ;
TXNSetTXNObjectControls( m_txn , false , 1 , tag , data ) ;
}
}
~wxMacEditHelper()
{
TXNControlTag tag[] = { kTXNIOPrivilegesTag } ;
if ( m_data[0].uValue == kTXNReadOnly )
TXNSetTXNObjectControls( m_txn , false , 1 , tag , m_data ) ;
}
protected :
TXNObject m_txn ;
TXNControlData m_data[1] ;
} ;
wxMacMLTEControl::wxMacMLTEControl( wxTextCtrl *peer )
: wxMacTextControl( peer )
{
SetNeedsFocusRect( true ) ;
}
wxString wxMacMLTEControl::GetStringValue() const
{
wxString result ;
OSStatus err ;
Size actualSize = 0;
{
#if wxUSE_UNICODE
Handle theText ;
err = TXNGetDataEncoded( m_txn, kTXNStartOffset, kTXNEndOffset, &theText, kTXNUnicodeTextData );
// all done
if ( err != noErr )
{
actualSize = 0 ;
}
else
{
actualSize = GetHandleSize( theText ) / sizeof(UniChar) ;
if ( actualSize > 0 )
{
wxChar *ptr = NULL ;
#if SIZEOF_WCHAR_T == 2
ptr = new wxChar[actualSize + 1] ;
wxStrncpy( ptr , (wxChar*)(*theText) , actualSize ) ;
#else
SetHandleSize( theText, (actualSize + 1) * sizeof(UniChar) ) ;
HLock( theText ) ;
(((UniChar*)*theText)[actualSize]) = 0 ;
wxMBConvUTF16 converter ;
size_t noChars = converter.MB2WC( NULL , (const char*)*theText , 0 ) ;
wxASSERT_MSG( noChars != wxCONV_FAILED, _T("Unable to count the number of characters in this string!") );
ptr = new wxChar[noChars + 1] ;
noChars = converter.MB2WC( ptr , (const char*)*theText , noChars + 1 ) ;
wxASSERT_MSG( noChars != wxCONV_FAILED, _T("Conversion of string failed!") );
ptr[noChars] = 0 ;
HUnlock( theText ) ;
#endif
ptr[actualSize] = 0 ;
result = wxString( ptr ) ;
delete [] ptr ;
}
DisposeHandle( theText ) ;
}
#else
Handle theText ;
err = TXNGetDataEncoded( m_txn , kTXNStartOffset, kTXNEndOffset, &theText, kTXNTextData );
// all done
if ( err != noErr )
{
actualSize = 0 ;
}
else
{
actualSize = GetHandleSize( theText ) ;
if ( actualSize > 0 )
{
HLock( theText ) ;
result = wxString( *theText , wxConvLocal , actualSize ) ;
HUnlock( theText ) ;
}
DisposeHandle( theText ) ;
}
#endif
}
#if '\n' == 10
wxMacConvertNewlines13To10( &result ) ;
#else
wxMacConvertNewlines10To13( &result ) ;
#endif
return result ;
}
void wxMacMLTEControl::SetStringValue( const wxString &str )
{
wxString st = str;
wxMacConvertNewlines10To13( &st );
{
wxMacWindowClipper c( m_peer );
{
wxMacEditHelper help( m_txn );
SetTXNData( st, kTXNStartOffset, kTXNEndOffset );
}
TXNSetSelection( m_txn, 0, 0 );
TXNShowSelection( m_txn, kTXNShowStart );
}
}
TXNFrameOptions wxMacMLTEControl::FrameOptionsFromWXStyle( long wxStyle )
{
TXNFrameOptions frameOptions = kTXNDontDrawCaretWhenInactiveMask;
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3
frameOptions |= kTXNDoFontSubstitutionMask;
#endif
if ( ! (wxStyle & wxTE_NOHIDESEL) )
frameOptions |= kTXNDontDrawSelectionWhenInactiveMask ;
if ( wxStyle & (wxHSCROLL | wxTE_DONTWRAP) )
frameOptions |= kTXNWantHScrollBarMask ;
if ( wxStyle & wxTE_MULTILINE )
{
frameOptions |= kTXNAlwaysWrapAtViewEdgeMask ;
if ( !(wxStyle & wxTE_NO_VSCROLL) )
{
frameOptions |= kTXNWantVScrollBarMask ;
// The following code causes drawing problems on 10.4. Perhaps it can be restored for
// older versions of the OS, but I'm not sure it's appropriate to put a grow icon here
// anyways, as AFAIK users can't actually use it to resize the text ctrl.
// if ( frameOptions & kTXNWantHScrollBarMask )
// frameOptions |= kTXNDrawGrowIconMask ;
}
}
else
{
frameOptions |= kTXNSingleLineOnlyMask ;
}
return frameOptions ;
}
void wxMacMLTEControl::AdjustCreationAttributes( const wxColour &background, bool visible )
{
TXNControlTag iControlTags[] =
{
kTXNDoFontSubstitution,
kTXNWordWrapStateTag ,
};
TXNControlData iControlData[] =
{
{ true },
{ kTXNNoAutoWrap },
};
int toptag = WXSIZEOF( iControlTags ) ;
if ( m_windowStyle & wxTE_MULTILINE )
{
iControlData[1].uValue =
(m_windowStyle & wxTE_DONTWRAP)
? kTXNNoAutoWrap
: kTXNAutoWrap;
}
OSStatus err = TXNSetTXNObjectControls( m_txn, false, toptag, iControlTags, iControlData ) ;
verify_noerr( err );
// setting the default font:
// under 10.2 this causes a visible caret, therefore we avoid it
if ( UMAGetSystemVersion() >= 0x1030 )
{
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 } } ,
} ;
err = TXNSetTypeAttributes(
m_txn, sizeof(typeAttr) / sizeof(TXNTypeAttributes),
typeAttr, kTXNStartOffset, kTXNEndOffset );
verify_noerr( err );
}
if ( m_windowStyle & wxTE_PASSWORD )
{
UniChar c = 0x00A5 ;
err = TXNEchoMode( m_txn , c , 0 , true );
verify_noerr( err );
}
TXNBackground tback;
tback.bgType = kTXNBackgroundTypeRGB;
tback.bg.color = MAC_WXCOLORREF( background.GetPixel() );
TXNSetBackground( m_txn , &tback );
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
if ( UMAGetSystemVersion() >= 0x1040 )
{
TXNCommandEventSupportOptions options ;
if ( TXNGetCommandEventSupport( m_txn, &options ) == noErr )
{
options |=
kTXNSupportEditCommandProcessing
| kTXNSupportEditCommandUpdating
| kTXNSupportSpellCheckCommandProcessing
| kTXNSupportSpellCheckCommandUpdating
| kTXNSupportFontCommandProcessing
| kTXNSupportFontCommandUpdating;
TXNSetCommandEventSupport( m_txn , options ) ;
}
}
#endif
}
void wxMacMLTEControl::SetBackground( const wxBrush &brush )
{
// currently only solid background are supported
TXNBackground tback;
tback.bgType = kTXNBackgroundTypeRGB;
tback.bg.color = MAC_WXCOLORREF( brush.GetColour().GetPixel() );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -