5591a20093
This is never going to work, so complain about trying to do it to help with catching this bug. This is possible thanks to the new OnDynamicBind() method invoked whenever a dynamic event handler is bound to a control, so this doesn't detect all possible occurrences of the bug (such as specifying the handler in a static event table or in a validator), but it's still better than nothing. In the future OnDynamicBind() should be extended for other invalid calls, e.g. binding a handler for wxEVT_TEXT_ENTER to a non-text control shouldn't work neither, ideally.
1261 lines
41 KiB
C++
1261 lines
41 KiB
C++
///////////////////////////////////////////////////////////////////////////////
|
|
// Name: src/common/textcmn.cpp
|
|
// Purpose: implementation of platform-independent functions of wxTextCtrl
|
|
// Author: Julian Smart
|
|
// Modified by:
|
|
// Created: 13.07.99
|
|
// Copyright: (c) wxWidgets team
|
|
// Licence: wxWindows licence
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
// ============================================================================
|
|
// declarations
|
|
// ============================================================================
|
|
|
|
// for compilers that support precompilation, includes "wx.h".
|
|
#include "wx/wxprec.h"
|
|
|
|
#ifdef __BORLANDC__
|
|
#pragma hdrstop
|
|
#endif
|
|
|
|
#ifndef WX_PRECOMP
|
|
#include "wx/event.h"
|
|
#endif // WX_PRECOMP
|
|
|
|
#if wxUSE_TEXTCTRL
|
|
|
|
#include "wx/textctrl.h"
|
|
|
|
#ifndef WX_PRECOMP
|
|
#include "wx/intl.h"
|
|
#include "wx/log.h"
|
|
#endif // WX_PRECOMP
|
|
|
|
#include "wx/ffile.h"
|
|
|
|
extern WXDLLEXPORT_DATA(const char) wxTextCtrlNameStr[] = "text";
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// macros
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// we don't have any objects of type wxTextCtrlBase in the program, only
|
|
// wxTextCtrl, so this cast is safe
|
|
#define TEXTCTRL(ptr) ((wxTextCtrl *)(ptr))
|
|
|
|
// ============================================================================
|
|
// implementation
|
|
// ============================================================================
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// XTI
|
|
// ----------------------------------------------------------------------------
|
|
|
|
wxDEFINE_FLAGS( wxTextCtrlStyle )
|
|
wxBEGIN_FLAGS( wxTextCtrlStyle )
|
|
// new style border flags, we put them first to
|
|
// use them for streaming out
|
|
wxFLAGS_MEMBER(wxBORDER_SIMPLE)
|
|
wxFLAGS_MEMBER(wxBORDER_SUNKEN)
|
|
wxFLAGS_MEMBER(wxBORDER_DOUBLE)
|
|
wxFLAGS_MEMBER(wxBORDER_RAISED)
|
|
wxFLAGS_MEMBER(wxBORDER_STATIC)
|
|
wxFLAGS_MEMBER(wxBORDER_NONE)
|
|
|
|
// old style border flags
|
|
wxFLAGS_MEMBER(wxSIMPLE_BORDER)
|
|
wxFLAGS_MEMBER(wxSUNKEN_BORDER)
|
|
wxFLAGS_MEMBER(wxDOUBLE_BORDER)
|
|
wxFLAGS_MEMBER(wxRAISED_BORDER)
|
|
wxFLAGS_MEMBER(wxSTATIC_BORDER)
|
|
wxFLAGS_MEMBER(wxBORDER)
|
|
|
|
// standard window styles
|
|
wxFLAGS_MEMBER(wxTAB_TRAVERSAL)
|
|
wxFLAGS_MEMBER(wxCLIP_CHILDREN)
|
|
wxFLAGS_MEMBER(wxTRANSPARENT_WINDOW)
|
|
wxFLAGS_MEMBER(wxWANTS_CHARS)
|
|
wxFLAGS_MEMBER(wxFULL_REPAINT_ON_RESIZE)
|
|
wxFLAGS_MEMBER(wxALWAYS_SHOW_SB )
|
|
wxFLAGS_MEMBER(wxVSCROLL)
|
|
wxFLAGS_MEMBER(wxHSCROLL)
|
|
|
|
wxFLAGS_MEMBER(wxTE_PROCESS_ENTER)
|
|
wxFLAGS_MEMBER(wxTE_PROCESS_TAB)
|
|
wxFLAGS_MEMBER(wxTE_MULTILINE)
|
|
wxFLAGS_MEMBER(wxTE_PASSWORD)
|
|
wxFLAGS_MEMBER(wxTE_READONLY)
|
|
wxFLAGS_MEMBER(wxHSCROLL)
|
|
wxFLAGS_MEMBER(wxTE_RICH)
|
|
wxFLAGS_MEMBER(wxTE_RICH2)
|
|
wxFLAGS_MEMBER(wxTE_AUTO_URL)
|
|
wxFLAGS_MEMBER(wxTE_NOHIDESEL)
|
|
wxFLAGS_MEMBER(wxTE_LEFT)
|
|
wxFLAGS_MEMBER(wxTE_CENTRE)
|
|
wxFLAGS_MEMBER(wxTE_RIGHT)
|
|
wxFLAGS_MEMBER(wxTE_DONTWRAP)
|
|
wxFLAGS_MEMBER(wxTE_CHARWRAP)
|
|
wxFLAGS_MEMBER(wxTE_WORDWRAP)
|
|
wxEND_FLAGS( wxTextCtrlStyle )
|
|
|
|
wxIMPLEMENT_DYNAMIC_CLASS_XTI(wxTextCtrl, wxControl, "wx/textctrl.h");
|
|
|
|
wxBEGIN_PROPERTIES_TABLE(wxTextCtrl)
|
|
wxEVENT_PROPERTY( TextUpdated, wxEVT_TEXT, wxCommandEvent )
|
|
wxEVENT_PROPERTY( TextEnter, wxEVT_TEXT_ENTER, wxCommandEvent )
|
|
|
|
wxPROPERTY( Font, wxFont, SetFont, GetFont , wxEMPTY_PARAMETER_VALUE, \
|
|
0 /*flags*/, wxT("Helpstring"), wxT("group") )
|
|
wxPROPERTY( Value, wxString, SetValue, GetValue, wxString(), \
|
|
0 /*flags*/, wxT("Helpstring"), wxT("group"))
|
|
|
|
wxPROPERTY_FLAGS( WindowStyle, wxTextCtrlStyle, long, SetWindowStyleFlag, \
|
|
GetWindowStyleFlag, wxEMPTY_PARAMETER_VALUE, 0 /*flags*/, \
|
|
wxT("Helpstring"), wxT("group")) // style
|
|
wxEND_PROPERTIES_TABLE()
|
|
|
|
wxEMPTY_HANDLERS_TABLE(wxTextCtrl)
|
|
|
|
wxCONSTRUCTOR_6( wxTextCtrl, wxWindow*, Parent, wxWindowID, Id, \
|
|
wxString, Value, wxPoint, Position, wxSize, Size, \
|
|
long, WindowStyle)
|
|
|
|
|
|
wxIMPLEMENT_DYNAMIC_CLASS(wxTextUrlEvent, wxCommandEvent);
|
|
|
|
wxDEFINE_EVENT( wxEVT_TEXT, wxCommandEvent );
|
|
wxDEFINE_EVENT( wxEVT_TEXT_ENTER, wxCommandEvent );
|
|
wxDEFINE_EVENT( wxEVT_TEXT_URL, wxTextUrlEvent );
|
|
wxDEFINE_EVENT( wxEVT_TEXT_MAXLEN, wxCommandEvent );
|
|
|
|
wxIMPLEMENT_ABSTRACT_CLASS(wxTextCtrlBase, wxControl);
|
|
|
|
// ============================================================================
|
|
// wxTextAttr implementation
|
|
// ============================================================================
|
|
|
|
wxTextAttr::wxTextAttr(const wxColour& colText,
|
|
const wxColour& colBack,
|
|
const wxFont& font,
|
|
wxTextAttrAlignment alignment): m_textAlignment(alignment), m_colText(colText), m_colBack(colBack)
|
|
{
|
|
Init();
|
|
|
|
if (m_colText.IsOk()) m_flags |= wxTEXT_ATTR_TEXT_COLOUR;
|
|
if (m_colBack.IsOk()) m_flags |= wxTEXT_ATTR_BACKGROUND_COLOUR;
|
|
if (alignment != wxTEXT_ALIGNMENT_DEFAULT)
|
|
m_flags |= wxTEXT_ATTR_ALIGNMENT;
|
|
|
|
GetFontAttributes(font);
|
|
}
|
|
|
|
// Initialisation
|
|
void wxTextAttr::Init()
|
|
{
|
|
m_textAlignment = wxTEXT_ALIGNMENT_DEFAULT;
|
|
m_flags = 0;
|
|
m_leftIndent = 0;
|
|
m_leftSubIndent = 0;
|
|
m_rightIndent = 0;
|
|
|
|
m_fontSize = 12;
|
|
m_fontStyle = wxFONTSTYLE_NORMAL;
|
|
m_fontWeight = wxFONTWEIGHT_NORMAL;
|
|
m_fontUnderlined = false;
|
|
m_fontStrikethrough = false;
|
|
m_fontEncoding = wxFONTENCODING_DEFAULT;
|
|
m_fontFamily = wxFONTFAMILY_DEFAULT;
|
|
|
|
m_paragraphSpacingAfter = 0;
|
|
m_paragraphSpacingBefore = 0;
|
|
m_lineSpacing = 0;
|
|
m_bulletStyle = wxTEXT_ATTR_BULLET_STYLE_NONE;
|
|
m_textEffects = wxTEXT_ATTR_EFFECT_NONE;
|
|
m_textEffectFlags = wxTEXT_ATTR_EFFECT_NONE;
|
|
m_outlineLevel = 0;
|
|
m_bulletNumber = 0;
|
|
}
|
|
|
|
// Copy
|
|
void wxTextAttr::Copy(const wxTextAttr& attr)
|
|
{
|
|
m_colText = attr.m_colText;
|
|
m_colBack = attr.m_colBack;
|
|
m_textAlignment = attr.m_textAlignment;
|
|
m_leftIndent = attr.m_leftIndent;
|
|
m_leftSubIndent = attr.m_leftSubIndent;
|
|
m_rightIndent = attr.m_rightIndent;
|
|
m_tabs = attr.m_tabs;
|
|
m_flags = attr.m_flags;
|
|
|
|
m_fontSize = attr.m_fontSize;
|
|
m_fontStyle = attr.m_fontStyle;
|
|
m_fontWeight = attr.m_fontWeight;
|
|
m_fontUnderlined = attr.m_fontUnderlined;
|
|
m_fontStrikethrough = attr.m_fontStrikethrough;
|
|
m_fontFaceName = attr.m_fontFaceName;
|
|
m_fontEncoding = attr.m_fontEncoding;
|
|
m_fontFamily = attr.m_fontFamily;
|
|
m_textEffects = attr.m_textEffects;
|
|
m_textEffectFlags = attr.m_textEffectFlags;
|
|
|
|
m_paragraphSpacingAfter = attr.m_paragraphSpacingAfter;
|
|
m_paragraphSpacingBefore = attr.m_paragraphSpacingBefore;
|
|
m_lineSpacing = attr.m_lineSpacing;
|
|
m_characterStyleName = attr.m_characterStyleName;
|
|
m_paragraphStyleName = attr.m_paragraphStyleName;
|
|
m_listStyleName = attr.m_listStyleName;
|
|
m_bulletStyle = attr.m_bulletStyle;
|
|
m_bulletNumber = attr.m_bulletNumber;
|
|
m_bulletText = attr.m_bulletText;
|
|
m_bulletFont = attr.m_bulletFont;
|
|
m_bulletName = attr.m_bulletName;
|
|
m_outlineLevel = attr.m_outlineLevel;
|
|
|
|
m_urlTarget = attr.m_urlTarget;
|
|
}
|
|
|
|
// operators
|
|
void wxTextAttr::operator= (const wxTextAttr& attr)
|
|
{
|
|
Copy(attr);
|
|
}
|
|
|
|
// Equality test
|
|
bool wxTextAttr::operator== (const wxTextAttr& attr) const
|
|
{
|
|
return GetFlags() == attr.GetFlags() &&
|
|
|
|
(!HasTextColour() || (GetTextColour() == attr.GetTextColour())) &&
|
|
(!HasBackgroundColour() || (GetBackgroundColour() == attr.GetBackgroundColour())) &&
|
|
|
|
(!HasAlignment() || (GetAlignment() == attr.GetAlignment())) &&
|
|
(!HasLeftIndent() || (GetLeftIndent() == attr.GetLeftIndent() &&
|
|
GetLeftSubIndent() == attr.GetLeftSubIndent())) &&
|
|
(!HasRightIndent() || (GetRightIndent() == attr.GetRightIndent())) &&
|
|
(!HasTabs() || (TabsEq(GetTabs(), attr.GetTabs()))) &&
|
|
|
|
(!HasParagraphSpacingAfter() || (GetParagraphSpacingAfter() == attr.GetParagraphSpacingAfter())) &&
|
|
(!HasParagraphSpacingBefore() || (GetParagraphSpacingBefore() == attr.GetParagraphSpacingBefore())) &&
|
|
(!HasLineSpacing() || (GetLineSpacing() == attr.GetLineSpacing())) &&
|
|
(!HasCharacterStyleName() || (GetCharacterStyleName() == attr.GetCharacterStyleName())) &&
|
|
(!HasParagraphStyleName() || (GetParagraphStyleName() == attr.GetParagraphStyleName())) &&
|
|
(!HasListStyleName() || (GetListStyleName() == attr.GetListStyleName())) &&
|
|
|
|
(!HasBulletStyle() || (GetBulletStyle() == attr.GetBulletStyle())) &&
|
|
(!HasBulletText() || (GetBulletText() == attr.GetBulletText())) &&
|
|
(!HasBulletNumber() || (GetBulletNumber() == attr.GetBulletNumber())) &&
|
|
(GetBulletFont() == attr.GetBulletFont()) &&
|
|
(!HasBulletName() || (GetBulletName() == attr.GetBulletName())) &&
|
|
|
|
(!HasTextEffects() || (GetTextEffects() == attr.GetTextEffects() &&
|
|
GetTextEffectFlags() == attr.GetTextEffectFlags())) &&
|
|
|
|
(!HasOutlineLevel() || (GetOutlineLevel() == attr.GetOutlineLevel())) &&
|
|
|
|
(!HasFontSize() || (GetFontSize() == attr.GetFontSize())) &&
|
|
(!HasFontItalic() || (GetFontStyle() == attr.GetFontStyle())) &&
|
|
(!HasFontWeight() || (GetFontWeight() == attr.GetFontWeight())) &&
|
|
(!HasFontUnderlined() || (GetFontUnderlined() == attr.GetFontUnderlined())) &&
|
|
(!HasFontStrikethrough() || (GetFontStrikethrough() == attr.GetFontStrikethrough())) &&
|
|
(!HasFontFaceName() || (GetFontFaceName() == attr.GetFontFaceName())) &&
|
|
(!HasFontEncoding() || (GetFontEncoding() == attr.GetFontEncoding())) &&
|
|
(!HasFontFamily() || (GetFontFamily() == attr.GetFontFamily())) &&
|
|
|
|
(!HasURL() || (GetURL() == attr.GetURL()));
|
|
}
|
|
|
|
// Partial equality test. Only returns false if an attribute doesn't match.
|
|
bool wxTextAttr::EqPartial(const wxTextAttr& attr, bool weakTest) const
|
|
{
|
|
int flags = attr.GetFlags();
|
|
|
|
if (!weakTest &&
|
|
((!HasTextColour() && attr.HasTextColour()) ||
|
|
(!HasBackgroundColour() && attr.HasBackgroundColour()) ||
|
|
(!HasFontFaceName() && attr.HasFontFaceName()) ||
|
|
(!HasFontSize() && attr.HasFontSize()) ||
|
|
(!HasFontWeight() && attr.HasFontWeight()) ||
|
|
(!HasFontItalic() && attr.HasFontItalic()) ||
|
|
(!HasFontUnderlined() && attr.HasFontUnderlined()) ||
|
|
(!HasFontStrikethrough() && attr.HasFontStrikethrough()) ||
|
|
(!HasFontEncoding() && attr.HasFontEncoding()) ||
|
|
(!HasFontFamily() && attr.HasFontFamily()) ||
|
|
(!HasURL() && attr.HasURL()) ||
|
|
(!HasAlignment() && attr.HasAlignment()) ||
|
|
(!HasLeftIndent() && attr.HasLeftIndent()) ||
|
|
(!HasParagraphSpacingAfter() && attr.HasParagraphSpacingAfter()) ||
|
|
(!HasParagraphSpacingBefore() && attr.HasParagraphSpacingBefore()) ||
|
|
(!HasLineSpacing() && attr.HasLineSpacing()) ||
|
|
(!HasCharacterStyleName() && attr.HasCharacterStyleName()) ||
|
|
(!HasParagraphStyleName() && attr.HasParagraphStyleName()) ||
|
|
(!HasListStyleName() && attr.HasListStyleName()) ||
|
|
(!HasBulletStyle() && attr.HasBulletStyle()) ||
|
|
(!HasBulletNumber() && attr.HasBulletNumber()) ||
|
|
(!HasBulletText() && attr.HasBulletText()) ||
|
|
(!HasBulletName() && attr.HasBulletName()) ||
|
|
(!HasTabs() && attr.HasTabs()) ||
|
|
(!HasTextEffects() && attr.HasTextEffects()) ||
|
|
(!HasOutlineLevel() && attr.HasOutlineLevel())))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (HasTextColour() && attr.HasTextColour() && GetTextColour() != attr.GetTextColour())
|
|
return false;
|
|
|
|
if (HasBackgroundColour() && attr.HasBackgroundColour() && GetBackgroundColour() != attr.GetBackgroundColour())
|
|
return false;
|
|
|
|
if (HasFontFaceName() && attr.HasFontFaceName() && GetFontFaceName() != attr.GetFontFaceName())
|
|
return false;
|
|
|
|
// This checks whether the two objects have the same font size dimension (px versus pt)
|
|
if (HasFontSize() && attr.HasFontSize() && (flags & wxTEXT_ATTR_FONT) != (GetFlags() & wxTEXT_ATTR_FONT))
|
|
return false;
|
|
|
|
if (HasFontPointSize() && attr.HasFontPointSize() && GetFontSize() != attr.GetFontSize())
|
|
return false;
|
|
|
|
if (HasFontPixelSize() && attr.HasFontPixelSize() && GetFontSize() != attr.GetFontSize())
|
|
return false;
|
|
|
|
if (HasFontWeight() && attr.HasFontWeight() && GetFontWeight() != attr.GetFontWeight())
|
|
return false;
|
|
|
|
if (HasFontItalic() && attr.HasFontItalic() && GetFontStyle() != attr.GetFontStyle())
|
|
return false;
|
|
|
|
if (HasFontUnderlined() && attr.HasFontUnderlined() && GetFontUnderlined() != attr.GetFontUnderlined())
|
|
return false;
|
|
|
|
if (HasFontStrikethrough() && attr.HasFontStrikethrough() && GetFontStrikethrough() != attr.GetFontStrikethrough())
|
|
return false;
|
|
|
|
if (HasFontEncoding() && attr.HasFontEncoding() && GetFontEncoding() != attr.GetFontEncoding())
|
|
return false;
|
|
|
|
if (HasFontFamily() && attr.HasFontFamily() && GetFontFamily() != attr.GetFontFamily())
|
|
return false;
|
|
|
|
if (HasURL() && attr.HasURL() && GetURL() != attr.GetURL())
|
|
return false;
|
|
|
|
if (HasAlignment() && attr.HasAlignment() && GetAlignment() != attr.GetAlignment())
|
|
return false;
|
|
|
|
if (HasLeftIndent() && attr.HasLeftIndent() &&
|
|
((GetLeftIndent() != attr.GetLeftIndent()) || (GetLeftSubIndent() != attr.GetLeftSubIndent())))
|
|
return false;
|
|
|
|
if (HasRightIndent() && attr.HasRightIndent() && (GetRightIndent() != attr.GetRightIndent()))
|
|
return false;
|
|
|
|
if (HasParagraphSpacingAfter() && attr.HasParagraphSpacingAfter() &&
|
|
(GetParagraphSpacingAfter() != attr.GetParagraphSpacingAfter()))
|
|
return false;
|
|
|
|
if (HasParagraphSpacingBefore() && attr.HasParagraphSpacingBefore() &&
|
|
(GetParagraphSpacingBefore() != attr.GetParagraphSpacingBefore()))
|
|
return false;
|
|
|
|
if (HasLineSpacing() && attr.HasLineSpacing() && (GetLineSpacing() != attr.GetLineSpacing()))
|
|
return false;
|
|
|
|
if (HasCharacterStyleName() && attr.HasCharacterStyleName() && (GetCharacterStyleName() != attr.GetCharacterStyleName()))
|
|
return false;
|
|
|
|
if (HasParagraphStyleName() && attr.HasParagraphStyleName() && (GetParagraphStyleName() != attr.GetParagraphStyleName()))
|
|
return false;
|
|
|
|
if (HasListStyleName() && attr.HasListStyleName() && (GetListStyleName() != attr.GetListStyleName()))
|
|
return false;
|
|
|
|
if (HasBulletStyle() && attr.HasBulletStyle() && (GetBulletStyle() != attr.GetBulletStyle()))
|
|
return false;
|
|
|
|
if (HasBulletNumber() && attr.HasBulletNumber() && (GetBulletNumber() != attr.GetBulletNumber()))
|
|
return false;
|
|
|
|
if (HasBulletText() && attr.HasBulletText() &&
|
|
(GetBulletText() != attr.GetBulletText()) &&
|
|
(GetBulletFont() != attr.GetBulletFont()))
|
|
return false;
|
|
|
|
if (HasBulletName() && attr.HasBulletName() && (GetBulletName() != attr.GetBulletName()))
|
|
return false;
|
|
|
|
if (HasTabs() && attr.HasTabs() && !TabsEq(GetTabs(), attr.GetTabs()))
|
|
return false;
|
|
|
|
if ((HasPageBreak() != attr.HasPageBreak()))
|
|
return false;
|
|
|
|
if ((GetFlags() & wxTEXT_ATTR_AVOID_PAGE_BREAK_BEFORE) != (attr.GetFlags() & wxTEXT_ATTR_AVOID_PAGE_BREAK_BEFORE))
|
|
return false;
|
|
|
|
if ((GetFlags() & wxTEXT_ATTR_AVOID_PAGE_BREAK_AFTER) != (attr.GetFlags() & wxTEXT_ATTR_AVOID_PAGE_BREAK_AFTER))
|
|
return false;
|
|
|
|
if (HasTextEffects() && attr.HasTextEffects())
|
|
{
|
|
if (!BitlistsEqPartial(GetTextEffects(), attr.GetTextEffects(), GetTextEffectFlags()))
|
|
return false;
|
|
}
|
|
|
|
if (HasOutlineLevel() && attr.HasOutlineLevel() && (GetOutlineLevel() != attr.GetOutlineLevel()))
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
// Create font from font attributes.
|
|
wxFont wxTextAttr::GetFont() const
|
|
{
|
|
if ( !HasFont() )
|
|
return wxNullFont;
|
|
|
|
int fontSize = 10;
|
|
if (HasFontSize())
|
|
fontSize = GetFontSize();
|
|
|
|
wxFontStyle fontStyle = wxFONTSTYLE_NORMAL;
|
|
if (HasFontItalic())
|
|
fontStyle = GetFontStyle();
|
|
|
|
wxFontWeight fontWeight = wxFONTWEIGHT_NORMAL;
|
|
if (HasFontWeight())
|
|
fontWeight = GetFontWeight();
|
|
|
|
bool underlined = false;
|
|
if (HasFontUnderlined())
|
|
underlined = GetFontUnderlined();
|
|
|
|
bool strikethrough = false;
|
|
if (HasFontStrikethrough())
|
|
strikethrough = GetFontStrikethrough();
|
|
|
|
wxString fontFaceName;
|
|
if (HasFontFaceName())
|
|
fontFaceName = GetFontFaceName();
|
|
|
|
wxFontEncoding encoding = wxFONTENCODING_DEFAULT;
|
|
if (HasFontEncoding())
|
|
encoding = GetFontEncoding();
|
|
|
|
wxFontFamily fontFamily = wxFONTFAMILY_DEFAULT;
|
|
if (HasFontFamily())
|
|
fontFamily = GetFontFamily();
|
|
|
|
if (HasFontPixelSize())
|
|
{
|
|
wxFont font(wxSize(0, fontSize), fontFamily, fontStyle, fontWeight, underlined, fontFaceName, encoding);
|
|
if (strikethrough)
|
|
font.SetStrikethrough(true);
|
|
return font;
|
|
}
|
|
else
|
|
{
|
|
wxFont font(fontSize, fontFamily, fontStyle, fontWeight, underlined, fontFaceName, encoding);
|
|
if (strikethrough)
|
|
font.SetStrikethrough(true);
|
|
return font;
|
|
}
|
|
}
|
|
|
|
// Get attributes from font.
|
|
bool wxTextAttr::GetFontAttributes(const wxFont& font, int flags)
|
|
{
|
|
if (!font.IsOk())
|
|
return false;
|
|
|
|
// If we pass both pixel and point size attributes, this is an indication
|
|
// to choose the most appropriate units.
|
|
if ((flags & wxTEXT_ATTR_FONT) == wxTEXT_ATTR_FONT)
|
|
{
|
|
if (font.IsUsingSizeInPixels())
|
|
{
|
|
m_fontSize = font.GetPixelSize().y;
|
|
flags &= ~wxTEXT_ATTR_FONT_POINT_SIZE;
|
|
}
|
|
else
|
|
{
|
|
m_fontSize = font.GetPointSize();
|
|
flags &= ~wxTEXT_ATTR_FONT_PIXEL_SIZE;
|
|
}
|
|
}
|
|
else if (flags & wxTEXT_ATTR_FONT_POINT_SIZE)
|
|
{
|
|
m_fontSize = font.GetPointSize();
|
|
flags &= ~wxTEXT_ATTR_FONT_PIXEL_SIZE;
|
|
}
|
|
else if (flags & wxTEXT_ATTR_FONT_PIXEL_SIZE)
|
|
{
|
|
m_fontSize = font.GetPixelSize().y;
|
|
}
|
|
|
|
if (flags & wxTEXT_ATTR_FONT_ITALIC)
|
|
m_fontStyle = font.GetStyle();
|
|
|
|
if (flags & wxTEXT_ATTR_FONT_WEIGHT)
|
|
m_fontWeight = font.GetWeight();
|
|
|
|
if (flags & wxTEXT_ATTR_FONT_UNDERLINE)
|
|
m_fontUnderlined = font.GetUnderlined();
|
|
|
|
if (flags & wxTEXT_ATTR_FONT_STRIKETHROUGH)
|
|
m_fontStrikethrough = font.GetStrikethrough();
|
|
|
|
if (flags & wxTEXT_ATTR_FONT_FACE)
|
|
m_fontFaceName = font.GetFaceName();
|
|
|
|
if (flags & wxTEXT_ATTR_FONT_ENCODING)
|
|
m_fontEncoding = font.GetEncoding();
|
|
|
|
if (flags & wxTEXT_ATTR_FONT_FAMILY)
|
|
{
|
|
// wxFont might not know its family, avoid setting m_fontFamily to an
|
|
// invalid value and rather pretend that we don't have any font family
|
|
// information at all in this case
|
|
const wxFontFamily fontFamily = font.GetFamily();
|
|
if ( fontFamily == wxFONTFAMILY_UNKNOWN )
|
|
flags &= ~wxTEXT_ATTR_FONT_FAMILY;
|
|
else
|
|
m_fontFamily = fontFamily;
|
|
}
|
|
|
|
m_flags |= flags;
|
|
|
|
return true;
|
|
}
|
|
|
|
// Resets bits in destination so new attributes aren't merged with mutually exclusive ones
|
|
static bool wxResetIncompatibleBits(const int mask, const int srcFlags, int& destFlags, int& destBits)
|
|
{
|
|
if ((srcFlags & mask) && (destFlags & mask))
|
|
{
|
|
destBits &= ~mask;
|
|
destFlags &= ~mask;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool wxTextAttr::Apply(const wxTextAttr& style, const wxTextAttr* compareWith)
|
|
{
|
|
wxTextAttr& destStyle = (*this);
|
|
|
|
if (style.HasFontWeight())
|
|
{
|
|
if (!(compareWith && compareWith->HasFontWeight() && compareWith->GetFontWeight() == style.GetFontWeight()))
|
|
destStyle.SetFontWeight(style.GetFontWeight());
|
|
}
|
|
|
|
if (style.HasFontPointSize())
|
|
{
|
|
if (!(compareWith && compareWith->HasFontPointSize() && compareWith->GetFontSize() == style.GetFontSize()))
|
|
destStyle.SetFontPointSize(style.GetFontSize());
|
|
}
|
|
else if (style.HasFontPixelSize())
|
|
{
|
|
if (!(compareWith && compareWith->HasFontPixelSize() && compareWith->GetFontSize() == style.GetFontSize()))
|
|
destStyle.SetFontPixelSize(style.GetFontSize());
|
|
}
|
|
|
|
if (style.HasFontItalic())
|
|
{
|
|
if (!(compareWith && compareWith->HasFontItalic() && compareWith->GetFontStyle() == style.GetFontStyle()))
|
|
destStyle.SetFontStyle(style.GetFontStyle());
|
|
}
|
|
|
|
if (style.HasFontUnderlined())
|
|
{
|
|
if (!(compareWith && compareWith->HasFontUnderlined() && compareWith->GetFontUnderlined() == style.GetFontUnderlined()))
|
|
destStyle.SetFontUnderlined(style.GetFontUnderlined());
|
|
}
|
|
|
|
if (style.HasFontStrikethrough())
|
|
{
|
|
if (!(compareWith && compareWith->HasFontStrikethrough() && compareWith->GetFontStrikethrough() == style.GetFontStrikethrough()))
|
|
destStyle.SetFontStrikethrough(style.GetFontStrikethrough());
|
|
}
|
|
|
|
if (style.HasFontFaceName())
|
|
{
|
|
if (!(compareWith && compareWith->HasFontFaceName() && compareWith->GetFontFaceName() == style.GetFontFaceName()))
|
|
destStyle.SetFontFaceName(style.GetFontFaceName());
|
|
}
|
|
|
|
if (style.HasFontEncoding())
|
|
{
|
|
if (!(compareWith && compareWith->HasFontEncoding() && compareWith->GetFontEncoding() == style.GetFontEncoding()))
|
|
destStyle.SetFontEncoding(style.GetFontEncoding());
|
|
}
|
|
|
|
if (style.HasFontFamily())
|
|
{
|
|
if (!(compareWith && compareWith->HasFontFamily() && compareWith->GetFontFamily() == style.GetFontFamily()))
|
|
destStyle.SetFontFamily(style.GetFontFamily());
|
|
}
|
|
|
|
if (style.GetTextColour().IsOk() && style.HasTextColour())
|
|
{
|
|
if (!(compareWith && compareWith->HasTextColour() && compareWith->GetTextColour() == style.GetTextColour()))
|
|
destStyle.SetTextColour(style.GetTextColour());
|
|
}
|
|
|
|
if (style.GetBackgroundColour().IsOk() && style.HasBackgroundColour())
|
|
{
|
|
if (!(compareWith && compareWith->HasBackgroundColour() && compareWith->GetBackgroundColour() == style.GetBackgroundColour()))
|
|
destStyle.SetBackgroundColour(style.GetBackgroundColour());
|
|
}
|
|
|
|
if (style.HasAlignment())
|
|
{
|
|
if (!(compareWith && compareWith->HasAlignment() && compareWith->GetAlignment() == style.GetAlignment()))
|
|
destStyle.SetAlignment(style.GetAlignment());
|
|
}
|
|
|
|
if (style.HasTabs())
|
|
{
|
|
if (!(compareWith && compareWith->HasTabs() && TabsEq(compareWith->GetTabs(), style.GetTabs())))
|
|
destStyle.SetTabs(style.GetTabs());
|
|
}
|
|
|
|
if (style.HasLeftIndent())
|
|
{
|
|
if (!(compareWith && compareWith->HasLeftIndent() && compareWith->GetLeftIndent() == style.GetLeftIndent()
|
|
&& compareWith->GetLeftSubIndent() == style.GetLeftSubIndent()))
|
|
destStyle.SetLeftIndent(style.GetLeftIndent(), style.GetLeftSubIndent());
|
|
}
|
|
|
|
if (style.HasRightIndent())
|
|
{
|
|
if (!(compareWith && compareWith->HasRightIndent() && compareWith->GetRightIndent() == style.GetRightIndent()))
|
|
destStyle.SetRightIndent(style.GetRightIndent());
|
|
}
|
|
|
|
if (style.HasParagraphSpacingAfter())
|
|
{
|
|
if (!(compareWith && compareWith->HasParagraphSpacingAfter() && compareWith->GetParagraphSpacingAfter() == style.GetParagraphSpacingAfter()))
|
|
destStyle.SetParagraphSpacingAfter(style.GetParagraphSpacingAfter());
|
|
}
|
|
|
|
if (style.HasParagraphSpacingBefore())
|
|
{
|
|
if (!(compareWith && compareWith->HasParagraphSpacingBefore() && compareWith->GetParagraphSpacingBefore() == style.GetParagraphSpacingBefore()))
|
|
destStyle.SetParagraphSpacingBefore(style.GetParagraphSpacingBefore());
|
|
}
|
|
|
|
if (style.HasLineSpacing())
|
|
{
|
|
if (!(compareWith && compareWith->HasLineSpacing() && compareWith->GetLineSpacing() == style.GetLineSpacing()))
|
|
destStyle.SetLineSpacing(style.GetLineSpacing());
|
|
}
|
|
|
|
if (style.HasCharacterStyleName())
|
|
{
|
|
if (!(compareWith && compareWith->HasCharacterStyleName() && compareWith->GetCharacterStyleName() == style.GetCharacterStyleName()))
|
|
destStyle.SetCharacterStyleName(style.GetCharacterStyleName());
|
|
}
|
|
|
|
if (style.HasParagraphStyleName())
|
|
{
|
|
if (!(compareWith && compareWith->HasParagraphStyleName() && compareWith->GetParagraphStyleName() == style.GetParagraphStyleName()))
|
|
destStyle.SetParagraphStyleName(style.GetParagraphStyleName());
|
|
}
|
|
|
|
if (style.HasListStyleName())
|
|
{
|
|
if (!(compareWith && compareWith->HasListStyleName() && compareWith->GetListStyleName() == style.GetListStyleName()))
|
|
destStyle.SetListStyleName(style.GetListStyleName());
|
|
}
|
|
|
|
if (style.HasBulletStyle())
|
|
{
|
|
if (!(compareWith && compareWith->HasBulletStyle() && compareWith->GetBulletStyle() == style.GetBulletStyle()))
|
|
destStyle.SetBulletStyle(style.GetBulletStyle());
|
|
}
|
|
|
|
if (style.HasBulletText())
|
|
{
|
|
if (!(compareWith && compareWith->HasBulletText() && compareWith->GetBulletText() == style.GetBulletText()))
|
|
{
|
|
destStyle.SetBulletText(style.GetBulletText());
|
|
destStyle.SetBulletFont(style.GetBulletFont());
|
|
}
|
|
}
|
|
|
|
if (style.HasBulletNumber())
|
|
{
|
|
if (!(compareWith && compareWith->HasBulletNumber() && compareWith->GetBulletNumber() == style.GetBulletNumber()))
|
|
destStyle.SetBulletNumber(style.GetBulletNumber());
|
|
}
|
|
|
|
if (style.HasBulletName())
|
|
{
|
|
if (!(compareWith && compareWith->HasBulletName() && compareWith->GetBulletName() == style.GetBulletName()))
|
|
destStyle.SetBulletName(style.GetBulletName());
|
|
}
|
|
|
|
if (style.HasURL())
|
|
{
|
|
if (!(compareWith && compareWith->HasURL() && compareWith->GetURL() == style.GetURL()))
|
|
destStyle.SetURL(style.GetURL());
|
|
}
|
|
|
|
if (style.HasPageBreak())
|
|
{
|
|
if (!(compareWith && compareWith->HasPageBreak()))
|
|
destStyle.SetPageBreak();
|
|
}
|
|
|
|
if (style.GetFlags() & wxTEXT_ATTR_AVOID_PAGE_BREAK_BEFORE)
|
|
{
|
|
if (!(compareWith && (compareWith->GetFlags() & wxTEXT_ATTR_AVOID_PAGE_BREAK_BEFORE)))
|
|
destStyle.SetFlags(destStyle.GetFlags()|wxTEXT_ATTR_AVOID_PAGE_BREAK_BEFORE);
|
|
}
|
|
|
|
if (style.GetFlags() & wxTEXT_ATTR_AVOID_PAGE_BREAK_AFTER)
|
|
{
|
|
if (!(compareWith && (compareWith->GetFlags() & wxTEXT_ATTR_AVOID_PAGE_BREAK_AFTER)))
|
|
destStyle.SetFlags(destStyle.GetFlags()|wxTEXT_ATTR_AVOID_PAGE_BREAK_AFTER);
|
|
}
|
|
|
|
if (style.HasTextEffects())
|
|
{
|
|
if (!(compareWith && compareWith->HasTextEffects() && compareWith->GetTextEffects() == style.GetTextEffects()))
|
|
{
|
|
int destBits = destStyle.GetTextEffects();
|
|
int destFlags = destStyle.GetTextEffectFlags();
|
|
|
|
int srcBits = style.GetTextEffects();
|
|
int srcFlags = style.GetTextEffectFlags();
|
|
|
|
// Reset incompatible bits in the destination
|
|
wxResetIncompatibleBits((wxTEXT_ATTR_EFFECT_SUPERSCRIPT|wxTEXT_ATTR_EFFECT_SUBSCRIPT), srcFlags, destFlags, destBits);
|
|
wxResetIncompatibleBits((wxTEXT_ATTR_EFFECT_CAPITALS|wxTEXT_ATTR_EFFECT_SMALL_CAPITALS), srcFlags, destFlags, destBits);
|
|
wxResetIncompatibleBits((wxTEXT_ATTR_EFFECT_STRIKETHROUGH|wxTEXT_ATTR_EFFECT_DOUBLE_STRIKETHROUGH), srcFlags, destFlags, destBits);
|
|
|
|
CombineBitlists(destBits, srcBits, destFlags, srcFlags);
|
|
|
|
destStyle.SetTextEffects(destBits);
|
|
destStyle.SetTextEffectFlags(destFlags);
|
|
}
|
|
}
|
|
|
|
if (style.HasOutlineLevel())
|
|
{
|
|
if (!(compareWith && compareWith->HasOutlineLevel() && compareWith->GetOutlineLevel() == style.GetOutlineLevel()))
|
|
destStyle.SetOutlineLevel(style.GetOutlineLevel());
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/* static */
|
|
wxTextAttr wxTextAttr::Combine(const wxTextAttr& attr,
|
|
const wxTextAttr& attrDef,
|
|
const wxTextCtrlBase *text)
|
|
{
|
|
wxFont font;
|
|
if (attr.HasFont())
|
|
font = attr.GetFont();
|
|
|
|
if ( !font.IsOk() )
|
|
{
|
|
if (attrDef.HasFont())
|
|
font = attrDef.GetFont();
|
|
|
|
if ( text && !font.IsOk() )
|
|
font = text->GetFont();
|
|
}
|
|
|
|
wxColour colFg = attr.GetTextColour();
|
|
if ( !colFg.IsOk() )
|
|
{
|
|
colFg = attrDef.GetTextColour();
|
|
|
|
if ( text && !colFg.IsOk() )
|
|
colFg = text->GetForegroundColour();
|
|
}
|
|
|
|
wxColour colBg = attr.GetBackgroundColour();
|
|
if ( !colBg.IsOk() )
|
|
{
|
|
colBg = attrDef.GetBackgroundColour();
|
|
|
|
if ( text && !colBg.IsOk() )
|
|
colBg = text->GetBackgroundColour();
|
|
}
|
|
|
|
wxTextAttr newAttr(colFg, colBg, font);
|
|
|
|
if (attr.HasAlignment())
|
|
newAttr.SetAlignment(attr.GetAlignment());
|
|
else if (attrDef.HasAlignment())
|
|
newAttr.SetAlignment(attrDef.GetAlignment());
|
|
|
|
if (attr.HasTabs())
|
|
newAttr.SetTabs(attr.GetTabs());
|
|
else if (attrDef.HasTabs())
|
|
newAttr.SetTabs(attrDef.GetTabs());
|
|
|
|
if (attr.HasLeftIndent())
|
|
newAttr.SetLeftIndent(attr.GetLeftIndent(), attr.GetLeftSubIndent());
|
|
else if (attrDef.HasLeftIndent())
|
|
newAttr.SetLeftIndent(attrDef.GetLeftIndent(), attr.GetLeftSubIndent());
|
|
|
|
if (attr.HasRightIndent())
|
|
newAttr.SetRightIndent(attr.GetRightIndent());
|
|
else if (attrDef.HasRightIndent())
|
|
newAttr.SetRightIndent(attrDef.GetRightIndent());
|
|
|
|
return newAttr;
|
|
}
|
|
|
|
/// Compare tabs
|
|
bool wxTextAttr::TabsEq(const wxArrayInt& tabs1, const wxArrayInt& tabs2)
|
|
{
|
|
if (tabs1.GetCount() != tabs2.GetCount())
|
|
return false;
|
|
|
|
size_t i;
|
|
for (i = 0; i < tabs1.GetCount(); i++)
|
|
{
|
|
if (tabs1[i] != tabs2[i])
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// Remove attributes
|
|
bool wxTextAttr::RemoveStyle(wxTextAttr& destStyle, const wxTextAttr& style)
|
|
{
|
|
int flags = style.GetFlags();
|
|
int destFlags = destStyle.GetFlags();
|
|
|
|
// We must treat text effects specially, since we must remove only some.
|
|
if (style.HasTextEffects() && (style.GetTextEffectFlags() != 0))
|
|
{
|
|
int newTextEffectFlags = destStyle.GetTextEffectFlags() & ~style.GetTextEffectFlags();
|
|
int newTextEffects = destStyle.GetTextEffects() & ~style.GetTextEffectFlags();
|
|
destStyle.SetTextEffects(newTextEffects);
|
|
destStyle.SetTextEffectFlags(newTextEffectFlags);
|
|
|
|
// Don't remove wxTEXT_ATTR_EFFECTS unless the resulting flags are zero
|
|
if (newTextEffectFlags != 0)
|
|
flags &= ~wxTEXT_ATTR_EFFECTS;
|
|
}
|
|
|
|
destStyle.SetFlags(destFlags & ~flags);
|
|
|
|
return true;
|
|
}
|
|
|
|
/// Combine two bitlists, specifying the bits of interest with separate flags.
|
|
bool wxTextAttr::CombineBitlists(int& valueA, int valueB, int& flagsA, int flagsB)
|
|
{
|
|
// We want to apply B's bits to A, taking into account each's flags which indicate which bits
|
|
// are to be taken into account. A zero in B's bits should reset that bit in A but only if B's flags
|
|
// indicate it.
|
|
|
|
// First, reset the 0 bits from B. We make a mask so we're only dealing with B's zero
|
|
// bits at this point, ignoring any 1 bits in B or 0 bits in B that are not relevant.
|
|
int valueA2 = ~(~valueB & flagsB) & valueA;
|
|
|
|
// Now combine the 1 bits.
|
|
int valueA3 = (valueB & flagsB) | valueA2;
|
|
|
|
valueA = valueA3;
|
|
flagsA = (flagsA | flagsB);
|
|
|
|
return true;
|
|
}
|
|
|
|
/// Compare two bitlists
|
|
bool wxTextAttr::BitlistsEqPartial(int valueA, int valueB, int flags)
|
|
{
|
|
int relevantBitsA = valueA & flags;
|
|
int relevantBitsB = valueB & flags;
|
|
return relevantBitsA == relevantBitsB;
|
|
}
|
|
|
|
/// Split into paragraph and character styles
|
|
bool wxTextAttr::SplitParaCharStyles(const wxTextAttr& style, wxTextAttr& parStyle, wxTextAttr& charStyle)
|
|
{
|
|
wxTextAttr defaultCharStyle1(style);
|
|
wxTextAttr defaultParaStyle1(style);
|
|
defaultCharStyle1.SetFlags(defaultCharStyle1.GetFlags()&wxTEXT_ATTR_CHARACTER);
|
|
defaultParaStyle1.SetFlags(defaultParaStyle1.GetFlags()&wxTEXT_ATTR_PARAGRAPH);
|
|
|
|
charStyle.Apply(defaultCharStyle1);
|
|
parStyle.Apply(defaultParaStyle1);
|
|
|
|
return true;
|
|
}
|
|
|
|
// apply styling to text range
|
|
bool wxTextCtrlBase::SetStyle(long WXUNUSED(start), long WXUNUSED(end),
|
|
const wxTextAttr& WXUNUSED(style))
|
|
{
|
|
// to be implemented in derived classes
|
|
return false;
|
|
}
|
|
|
|
// get the styling at the given position
|
|
bool wxTextCtrlBase::GetStyle(long WXUNUSED(position), wxTextAttr& WXUNUSED(style))
|
|
{
|
|
// to be implemented in derived classes
|
|
return false;
|
|
}
|
|
|
|
// change default text attributes
|
|
bool wxTextCtrlBase::SetDefaultStyle(const wxTextAttr& style)
|
|
{
|
|
// keep the old attributes if the new style doesn't specify them unless the
|
|
// new style is empty - then reset m_defaultStyle (as there is no other way
|
|
// to do it)
|
|
if ( style.IsDefault() )
|
|
m_defaultStyle = style;
|
|
else
|
|
m_defaultStyle = wxTextAttr::Combine(style, m_defaultStyle, this);
|
|
|
|
return true;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// file IO functions
|
|
// ----------------------------------------------------------------------------
|
|
|
|
bool wxTextAreaBase::DoLoadFile(const wxString& filename, int WXUNUSED(fileType))
|
|
{
|
|
#if wxUSE_FFILE
|
|
wxFFile file(filename);
|
|
if ( file.IsOpened() )
|
|
{
|
|
wxString text;
|
|
if ( file.ReadAll(&text) )
|
|
{
|
|
SetValue(text);
|
|
|
|
DiscardEdits();
|
|
m_filename = filename;
|
|
|
|
return true;
|
|
}
|
|
}
|
|
#else
|
|
(void)filename; // avoid compiler warning about unreferenced parameter
|
|
#endif // wxUSE_FFILE
|
|
|
|
wxLogError(_("File couldn't be loaded."));
|
|
|
|
return false;
|
|
}
|
|
|
|
bool wxTextAreaBase::DoSaveFile(const wxString& filename, int WXUNUSED(fileType))
|
|
{
|
|
#if wxUSE_FFILE
|
|
wxFFile file(filename, wxT("w"));
|
|
if ( file.IsOpened() && file.Write(GetValue()) )
|
|
{
|
|
// if it worked, save for future calls
|
|
m_filename = filename;
|
|
|
|
// it's not modified any longer
|
|
DiscardEdits();
|
|
|
|
return true;
|
|
}
|
|
#else
|
|
(void)filename; // avoid compiler warning about unreferenced parameter
|
|
#endif // wxUSE_FFILE
|
|
|
|
return false;
|
|
}
|
|
|
|
bool wxTextAreaBase::SaveFile(const wxString& filename, int fileType)
|
|
{
|
|
wxString filenameToUse = filename.empty() ? m_filename : filename;
|
|
if ( filenameToUse.empty() )
|
|
{
|
|
// what kind of message to give? is it an error or a program bug?
|
|
wxLogDebug(wxT("Can't save textctrl to file without filename."));
|
|
|
|
return false;
|
|
}
|
|
|
|
return DoSaveFile(filenameToUse, fileType);
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// stream-like insertion operator
|
|
// ----------------------------------------------------------------------------
|
|
|
|
wxTextCtrl& wxTextCtrlBase::operator<<(const wxString& s)
|
|
{
|
|
AppendText(s);
|
|
return *TEXTCTRL(this);
|
|
}
|
|
|
|
wxTextCtrl& wxTextCtrlBase::operator<<(double d)
|
|
{
|
|
return *this << wxString::Format("%.2f", d);
|
|
}
|
|
|
|
wxTextCtrl& wxTextCtrlBase::operator<<(int i)
|
|
{
|
|
return *this << wxString::Format("%d", i);
|
|
}
|
|
|
|
wxTextCtrl& wxTextCtrlBase::operator<<(long l)
|
|
{
|
|
return *this << wxString::Format("%ld", l);
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// streambuf methods implementation
|
|
// ----------------------------------------------------------------------------
|
|
|
|
#if wxHAS_TEXT_WINDOW_STREAM
|
|
|
|
int wxTextCtrlBase::overflow(int c)
|
|
{
|
|
AppendText((wxChar)c);
|
|
|
|
// return something different from EOF
|
|
return 0;
|
|
}
|
|
|
|
#endif // wxHAS_TEXT_WINDOW_STREAM
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// emulating key presses
|
|
// ----------------------------------------------------------------------------
|
|
|
|
bool wxTextCtrlBase::EmulateKeyPress(const wxKeyEvent& event)
|
|
{
|
|
bool handled = false;
|
|
// we have a native implementation for Win32 and so don't need this one
|
|
#ifndef __WIN32__
|
|
wxChar ch = 0;
|
|
int keycode = event.GetKeyCode();
|
|
|
|
long from, to;
|
|
GetSelection(&from,&to);
|
|
long insert = GetInsertionPoint();
|
|
long last = GetLastPosition();
|
|
|
|
// catch arrow left and right
|
|
|
|
switch ( keycode )
|
|
{
|
|
case WXK_LEFT:
|
|
if ( event.ShiftDown() )
|
|
SetSelection( (from > 0 ? from - 1 : 0) , to );
|
|
else
|
|
{
|
|
if ( from != to )
|
|
insert = from;
|
|
else if ( insert > 0 )
|
|
insert -= 1;
|
|
SetInsertionPoint( insert );
|
|
}
|
|
handled = true;
|
|
break;
|
|
case WXK_RIGHT:
|
|
if ( event.ShiftDown() )
|
|
SetSelection( from, (to < last ? to + 1 : last) );
|
|
else
|
|
{
|
|
if ( from != to )
|
|
insert = to;
|
|
else if ( insert < last )
|
|
insert += 1;
|
|
SetInsertionPoint( insert );
|
|
}
|
|
handled = true;
|
|
break;
|
|
case WXK_NUMPAD0:
|
|
case WXK_NUMPAD1:
|
|
case WXK_NUMPAD2:
|
|
case WXK_NUMPAD3:
|
|
case WXK_NUMPAD4:
|
|
case WXK_NUMPAD5:
|
|
case WXK_NUMPAD6:
|
|
case WXK_NUMPAD7:
|
|
case WXK_NUMPAD8:
|
|
case WXK_NUMPAD9:
|
|
ch = (wxChar)(wxT('0') + keycode - WXK_NUMPAD0);
|
|
break;
|
|
|
|
case WXK_MULTIPLY:
|
|
case WXK_NUMPAD_MULTIPLY:
|
|
ch = wxT('*');
|
|
break;
|
|
|
|
case WXK_ADD:
|
|
case WXK_NUMPAD_ADD:
|
|
ch = wxT('+');
|
|
break;
|
|
|
|
case WXK_SUBTRACT:
|
|
case WXK_NUMPAD_SUBTRACT:
|
|
ch = wxT('-');
|
|
break;
|
|
|
|
case WXK_DECIMAL:
|
|
case WXK_NUMPAD_DECIMAL:
|
|
ch = wxT('.');
|
|
break;
|
|
|
|
case WXK_DIVIDE:
|
|
case WXK_NUMPAD_DIVIDE:
|
|
ch = wxT('/');
|
|
break;
|
|
|
|
case WXK_DELETE:
|
|
case WXK_NUMPAD_DELETE:
|
|
// delete the character at cursor
|
|
{
|
|
const long pos = GetInsertionPoint();
|
|
if ( pos < GetLastPosition() )
|
|
Remove(pos, pos + 1);
|
|
handled = true;
|
|
}
|
|
break;
|
|
|
|
case WXK_BACK:
|
|
// delete the character before the cursor
|
|
{
|
|
const long pos = GetInsertionPoint();
|
|
if ( pos > 0 )
|
|
Remove(pos - 1, pos);
|
|
handled = true;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
#if wxUSE_UNICODE
|
|
if ( event.GetUnicodeKey() )
|
|
{
|
|
ch = event.GetUnicodeKey();
|
|
}
|
|
else
|
|
#endif
|
|
if ( keycode < 256 && keycode >= 0 && wxIsprint(keycode) )
|
|
{
|
|
// FIXME this is not going to work for non letters...
|
|
if ( !event.ShiftDown() )
|
|
{
|
|
keycode = wxTolower(keycode);
|
|
}
|
|
|
|
ch = (wxChar)keycode;
|
|
}
|
|
else
|
|
{
|
|
ch = wxT('\0');
|
|
}
|
|
}
|
|
|
|
if ( ch )
|
|
{
|
|
WriteText(ch);
|
|
|
|
handled = true;
|
|
}
|
|
#else // __WIN32__
|
|
wxUnusedVar(event);
|
|
#endif // !__WIN32__/__WIN32__
|
|
|
|
return handled;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Other miscellaneous stuff
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// do the window-specific processing after processing the update event
|
|
void wxTextCtrlBase::DoUpdateWindowUI(wxUpdateUIEvent& event)
|
|
{
|
|
// call inherited, but skip the wxControl's version, and call directly the
|
|
// wxWindow's one instead, because the only reason why we are overriding this
|
|
// function is that we want to use SetValue() instead of wxControl::SetLabel()
|
|
wxWindowBase::DoUpdateWindowUI(event);
|
|
|
|
// update text
|
|
if ( event.GetSetText() )
|
|
{
|
|
if ( event.GetText() != GetValue() )
|
|
SetValue(event.GetText());
|
|
}
|
|
}
|
|
|
|
bool wxTextCtrlBase::OnDynamicBind(wxDynamicEventTableEntry& entry)
|
|
{
|
|
if ( entry.m_eventType == wxEVT_TEXT_ENTER )
|
|
{
|
|
wxCHECK_MSG
|
|
(
|
|
HasFlag(wxTE_PROCESS_ENTER),
|
|
false,
|
|
wxS("Must have wxTE_PROCESS_ENTER for wxEVT_TEXT_ENTER to work")
|
|
);
|
|
}
|
|
|
|
return wxControl::OnDynamicBind(entry);
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// hit testing
|
|
// ----------------------------------------------------------------------------
|
|
|
|
wxTextCtrlHitTestResult
|
|
wxTextAreaBase::HitTest(const wxPoint& pt, wxTextCoord *x, wxTextCoord *y) const
|
|
{
|
|
// implement in terms of the other overload as the native ports typically
|
|
// can get the position and not (x, y) pair directly (although wxUniv
|
|
// directly gets x and y -- and so overrides this method as well)
|
|
long pos;
|
|
wxTextCtrlHitTestResult rc = HitTest(pt, &pos);
|
|
|
|
if ( rc != wxTE_HT_UNKNOWN )
|
|
{
|
|
PositionToXY(pos, x, y);
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
|
|
wxTextCtrlHitTestResult
|
|
wxTextAreaBase::HitTest(const wxPoint& WXUNUSED(pt), long * WXUNUSED(pos)) const
|
|
{
|
|
// not implemented
|
|
return wxTE_HT_UNKNOWN;
|
|
}
|
|
|
|
wxPoint wxTextAreaBase::PositionToCoords(long pos) const
|
|
{
|
|
wxCHECK_MSG( IsValidPosition(pos), wxDefaultPosition,
|
|
wxS("Position argument out of range.") );
|
|
|
|
return DoPositionToCoords(pos);
|
|
}
|
|
|
|
wxPoint wxTextAreaBase::DoPositionToCoords(long WXUNUSED(pos)) const
|
|
{
|
|
return wxDefaultPosition;
|
|
}
|
|
|
|
#else // !wxUSE_TEXTCTRL
|
|
|
|
// define this one even if !wxUSE_TEXTCTRL because it is also used by other
|
|
// controls (wxComboBox and wxSpinCtrl)
|
|
|
|
wxDEFINE_EVENT( wxEVT_TEXT, wxCommandEvent );
|
|
|
|
#endif // wxUSE_TEXTCTRL/!wxUSE_TEXTCTRL
|