X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/ee2ec18e88701d8f0709009616584153ca85d7a7..2865d42dd600e0260cb8b9c4310b587c3558798c:/src/common/textcmn.cpp diff --git a/src/common/textcmn.cpp b/src/common/textcmn.cpp index 6f53679d6b..d38b4dfbb0 100644 --- a/src/common/textcmn.cpp +++ b/src/common/textcmn.cpp @@ -35,6 +35,8 @@ #include "wx/ffile.h" +extern WXDLLEXPORT_DATA(const char) wxTextCtrlNameStr[] = "text"; + // ---------------------------------------------------------------------------- // macros // ---------------------------------------------------------------------------- @@ -47,36 +49,109 @@ // 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_COMMAND_TEXT_UPDATED, wxCommandEvent ) +wxEVENT_PROPERTY( TextEnter, wxEVT_COMMAND_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) + + IMPLEMENT_DYNAMIC_CLASS(wxTextUrlEvent, wxCommandEvent) -DEFINE_EVENT_TYPE(wxEVT_COMMAND_TEXT_UPDATED) -DEFINE_EVENT_TYPE(wxEVT_COMMAND_TEXT_ENTER) -DEFINE_EVENT_TYPE(wxEVT_COMMAND_TEXT_URL) -DEFINE_EVENT_TYPE(wxEVT_COMMAND_TEXT_MAXLEN) +wxDEFINE_EVENT( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEvent ); +wxDEFINE_EVENT( wxEVT_COMMAND_TEXT_ENTER, wxCommandEvent ); +wxDEFINE_EVENT( wxEVT_COMMAND_TEXT_URL, wxTextUrlEvent ); +wxDEFINE_EVENT( wxEVT_COMMAND_TEXT_MAXLEN, wxCommandEvent ); IMPLEMENT_ABSTRACT_CLASS(wxTextCtrlBase, wxControl) -// ---------------------------------------------------------------------------- -// style functions - not implemented here -// ---------------------------------------------------------------------------- +// ============================================================================ +// wxTextAttr implementation +// ============================================================================ wxTextAttr::wxTextAttr(const wxColour& colText, const wxColour& colBack, const wxFont& font, - wxTextAttrAlignment alignment) - : m_colText(colText), m_colBack(colBack), m_font(font), m_textAlignment(alignment) + wxTextAttrAlignment alignment): m_textAlignment(alignment), m_colText(colText), m_colBack(colBack) { - m_flags = 0; - m_leftIndent = 0; - m_leftSubIndent = 0; - m_rightIndent = 0; + Init(); + if (m_colText.Ok()) m_flags |= wxTEXT_ATTR_TEXT_COLOUR; if (m_colBack.Ok()) m_flags |= wxTEXT_ATTR_BACKGROUND_COLOUR; - if (m_font.Ok()) m_flags |= wxTEXT_ATTR_FONT; if (alignment != wxTEXT_ALIGNMENT_DEFAULT) m_flags |= wxTEXT_ATTR_ALIGNMENT; + + GetFontAttributes(font); } +// Initialisation void wxTextAttr::Init() { m_textAlignment = wxTEXT_ALIGNMENT_DEFAULT; @@ -84,6 +159,506 @@ void wxTextAttr::Init() m_leftIndent = 0; m_leftSubIndent = 0; m_rightIndent = 0; + + m_fontSize = 12; + m_fontStyle = wxFONTSTYLE_NORMAL; + m_fontWeight = wxFONTWEIGHT_NORMAL; + m_fontUnderlined = 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_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() && + + GetTextColour() == attr.GetTextColour() && + GetBackgroundColour() == attr.GetBackgroundColour() && + + GetAlignment() == attr.GetAlignment() && + GetLeftIndent() == attr.GetLeftIndent() && + GetLeftSubIndent() == attr.GetLeftSubIndent() && + GetRightIndent() == attr.GetRightIndent() && + TabsEq(GetTabs(), attr.GetTabs()) && + + GetParagraphSpacingAfter() == attr.GetParagraphSpacingAfter() && + GetParagraphSpacingBefore() == attr.GetParagraphSpacingBefore() && + GetLineSpacing() == attr.GetLineSpacing() && + GetCharacterStyleName() == attr.GetCharacterStyleName() && + GetParagraphStyleName() == attr.GetParagraphStyleName() && + GetListStyleName() == attr.GetListStyleName() && + + GetBulletStyle() == attr.GetBulletStyle() && + GetBulletText() == attr.GetBulletText() && + GetBulletNumber() == attr.GetBulletNumber() && + GetBulletFont() == attr.GetBulletFont() && + GetBulletName() == attr.GetBulletName() && + + GetTextEffects() == attr.GetTextEffects() && + GetTextEffectFlags() == attr.GetTextEffectFlags() && + + GetOutlineLevel() == attr.GetOutlineLevel() && + + GetFontSize() == attr.GetFontSize() && + GetFontStyle() == attr.GetFontStyle() && + GetFontWeight() == attr.GetFontWeight() && + GetFontUnderlined() == attr.GetFontUnderlined() && + GetFontFaceName() == attr.GetFontFaceName() && + GetFontEncoding() == attr.GetFontEncoding() && + GetFontFamily() == attr.GetFontFamily() && + + GetURL() == attr.GetURL(); +} + +// Partial equality test. Only returns false if an attribute doesn't match. +bool wxTextAttr::EqPartial(const wxTextAttr& attr) const +{ + int flags = attr.GetFlags(); + + if ((flags & wxTEXT_ATTR_TEXT_COLOUR) && GetTextColour() != attr.GetTextColour()) + return false; + + if ((flags & wxTEXT_ATTR_BACKGROUND_COLOUR) && GetBackgroundColour() != attr.GetBackgroundColour()) + return false; + + if ((flags & wxTEXT_ATTR_FONT_FACE) && + GetFontFaceName() != attr.GetFontFaceName()) + return false; + + if ((flags & wxTEXT_ATTR_FONT_SIZE) && + GetFontSize() != attr.GetFontSize()) + return false; + + if ((flags & wxTEXT_ATTR_FONT_WEIGHT) && + GetFontWeight() != attr.GetFontWeight()) + return false; + + if ((flags & wxTEXT_ATTR_FONT_ITALIC) && + GetFontStyle() != attr.GetFontStyle()) + return false; + + if ((flags & wxTEXT_ATTR_FONT_UNDERLINE) && + GetFontUnderlined() != attr.GetFontUnderlined()) + return false; + + if ((flags & wxTEXT_ATTR_FONT_ENCODING) && + GetFontEncoding() != attr.GetFontEncoding()) + return false; + + if ((flags & wxTEXT_ATTR_FONT_FAMILY) && + GetFontFamily() != attr.GetFontFamily()) + return false; + + if ((flags & wxTEXT_ATTR_URL) && GetURL() != attr.GetURL()) + return false; + + if ((flags & wxTEXT_ATTR_ALIGNMENT) && GetAlignment() != attr.GetAlignment()) + return false; + + if ((flags & wxTEXT_ATTR_LEFT_INDENT) && + ((GetLeftIndent() != attr.GetLeftIndent()) || (GetLeftSubIndent() != attr.GetLeftSubIndent()))) + return false; + + if ((flags & wxTEXT_ATTR_RIGHT_INDENT) && + (GetRightIndent() != attr.GetRightIndent())) + return false; + + if ((flags & wxTEXT_ATTR_PARA_SPACING_AFTER) && + (GetParagraphSpacingAfter() != attr.GetParagraphSpacingAfter())) + return false; + + if ((flags & wxTEXT_ATTR_PARA_SPACING_BEFORE) && + (GetParagraphSpacingBefore() != attr.GetParagraphSpacingBefore())) + return false; + + if ((flags & wxTEXT_ATTR_LINE_SPACING) && + (GetLineSpacing() != attr.GetLineSpacing())) + return false; + + if ((flags & wxTEXT_ATTR_CHARACTER_STYLE_NAME) && + (GetCharacterStyleName() != attr.GetCharacterStyleName())) + return false; + + if ((flags & wxTEXT_ATTR_PARAGRAPH_STYLE_NAME) && + (GetParagraphStyleName() != attr.GetParagraphStyleName())) + return false; + + if ((flags & wxTEXT_ATTR_LIST_STYLE_NAME) && + (GetListStyleName() != attr.GetListStyleName())) + return false; + + if ((flags & wxTEXT_ATTR_BULLET_STYLE) && + (GetBulletStyle() != attr.GetBulletStyle())) + return false; + + if ((flags & wxTEXT_ATTR_BULLET_NUMBER) && + (GetBulletNumber() != attr.GetBulletNumber())) + return false; + + if ((flags & wxTEXT_ATTR_BULLET_TEXT) && + (GetBulletText() != attr.GetBulletText()) && + (GetBulletFont() != attr.GetBulletFont())) + return false; + + if ((flags & wxTEXT_ATTR_BULLET_NAME) && + (GetBulletName() != attr.GetBulletName())) + return false; + + if ((flags & wxTEXT_ATTR_TABS) && + !TabsEq(GetTabs(), attr.GetTabs())) + return false; + + if ((flags & wxTEXT_ATTR_PAGE_BREAK) && + (HasPageBreak() != attr.HasPageBreak())) + return false; + + if (flags & wxTEXT_ATTR_EFFECTS) + { + if (HasTextEffects() != attr.HasTextEffects()) + return false; + if (!BitlistsEqPartial(GetTextEffects(), attr.GetTextEffects(), attr.GetTextEffectFlags())) + return false; + } + + if ((flags & wxTEXT_ATTR_OUTLINE_LEVEL) && + (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(); + + int fontStyle = wxNORMAL; + if (HasFontItalic()) + fontStyle = GetFontStyle(); + + int fontWeight = wxNORMAL; + if (HasFontWeight()) + fontWeight = GetFontWeight(); + + bool underlined = false; + if (HasFontUnderlined()) + underlined = GetFontUnderlined(); + + wxString fontFaceName; + if (HasFontFaceName()) + fontFaceName = GetFontFaceName(); + + wxFontEncoding encoding = wxFONTENCODING_DEFAULT; + if (HasFontEncoding()) + encoding = GetFontEncoding(); + + wxFontFamily fontFamily = wxFONTFAMILY_DEFAULT; + if (HasFontFamily()) + fontFamily = GetFontFamily(); + + wxFont font(fontSize, fontFamily, fontStyle, fontWeight, underlined, fontFaceName, encoding); + return font; +} + +// Get attributes from font. +bool wxTextAttr::GetFontAttributes(const wxFont& font, int flags) +{ + if (!font.Ok()) + return false; + + if (flags & wxTEXT_ATTR_FONT_SIZE) + m_fontSize = font.GetPointSize(); + + 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_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.HasFontSize()) + { + if (!(compareWith && compareWith->HasFontSize() && compareWith->GetFontSize() == style.GetFontSize())) + destStyle.SetFontSize(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.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().Ok() && style.HasTextColour()) + { + if (!(compareWith && compareWith->HasTextColour() && compareWith->GetTextColour() == style.GetTextColour())) + destStyle.SetTextColour(style.GetTextColour()); + } + + if (style.GetBackgroundColour().Ok() && 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.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 */ @@ -91,10 +666,14 @@ wxTextAttr wxTextAttr::Combine(const wxTextAttr& attr, const wxTextAttr& attrDef, const wxTextCtrlBase *text) { - wxFont font = attr.GetFont(); + wxFont font; + if (attr.HasFont()) + font = attr.GetFont(); + if ( !font.Ok() ) { - font = attrDef.GetFont(); + if (attrDef.HasFont()) + font = attrDef.GetFont(); if ( text && !font.Ok() ) font = text->GetFont(); @@ -143,32 +722,86 @@ wxTextAttr wxTextAttr::Combine(const wxTextAttr& attr, return newAttr; } -void wxTextAttr::operator= (const wxTextAttr& attr) +/// Compare tabs +bool wxTextAttr::TabsEq(const wxArrayInt& tabs1, const wxArrayInt& tabs2) { - m_font = attr.m_font; - 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; + 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(); + + 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 TextCtrl classes + // 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 TextCtrl classes + // to be implemented in derived classes return false; } @@ -186,17 +819,11 @@ bool wxTextCtrlBase::SetDefaultStyle(const wxTextAttr& style) return true; } -// get default text attributes -const wxTextAttr& wxTextCtrlBase::GetDefaultStyle() const -{ - return m_defaultStyle; -} - // ---------------------------------------------------------------------------- // file IO functions // ---------------------------------------------------------------------------- -bool wxTextCtrlBase::DoLoadFile(const wxString& filename, int WXUNUSED(fileType)) +bool wxTextAreaBase::DoLoadFile(const wxString& filename, int WXUNUSED(fileType)) { #if wxUSE_FFILE wxFFile file(filename); @@ -207,21 +834,37 @@ bool wxTextCtrlBase::DoLoadFile(const wxString& filename, int WXUNUSED(fileType) { SetValue(text); - DiscardEdits(); - - m_filename = filename; - return true; } } +#endif // wxUSE_FFILE + + return false; +} +bool wxTextCtrlBase::DoLoadFile(const wxString& filename, int fileType) +{ + if ( wxTextAreaBase::DoLoadFile(filename, fileType) ) + { + DiscardEdits(); + m_filename = filename; + return true; + } wxLogError(_("File couldn't be loaded.")); -#endif // wxUSE_FFILE + return false; +} +bool wxTextAreaBase::DoSaveFile(const wxString& filename, int WXUNUSED(fileType)) +{ +#if wxUSE_FFILE + wxFFile file(filename, wxT("w")); + return file.IsOpened() && file.Write(GetValue(), *wxConvCurrent); +#else return false; +#endif // wxUSE_FFILE } -bool wxTextCtrlBase::SaveFile(const wxString& filename, int fileType) +bool wxTextAreaBase::SaveFile(const wxString& filename, int fileType) { wxString filenameToUse = filename.empty() ? m_filename : filename; if ( filenameToUse.empty() ) @@ -235,11 +878,9 @@ bool wxTextCtrlBase::SaveFile(const wxString& filename, int fileType) return DoSaveFile(filenameToUse, fileType); } -bool wxTextCtrlBase::DoSaveFile(const wxString& filename, int WXUNUSED(fileType)) +bool wxTextCtrlBase::DoSaveFile(const wxString& filename, int fileType) { -#if wxUSE_FFILE - wxFFile file(filename, _T("w")); - if ( file.IsOpened() && file.Write(GetValue()) ) + if ( wxTextAreaBase::DoSaveFile(filename, fileType) ) { // if it worked, save for future calls m_filename = filename; @@ -249,10 +890,6 @@ bool wxTextCtrlBase::DoSaveFile(const wxString& filename, int WXUNUSED(fileType) return true; } -#endif // wxUSE_FFILE - - wxLogError(_("The text couldn't be saved.")); - return false; } @@ -266,41 +903,19 @@ wxTextCtrl& wxTextCtrlBase::operator<<(const wxString& s) return *TEXTCTRL(this); } -wxTextCtrl& wxTextCtrlBase::operator<<(float f) -{ - wxString str; - str.Printf(wxT("%.2f"), f); - AppendText(str); - return *TEXTCTRL(this); -} - wxTextCtrl& wxTextCtrlBase::operator<<(double d) { - wxString str; - str.Printf(wxT("%.2f"), d); - AppendText(str); - return *TEXTCTRL(this); + return *this << wxString::Format("%.2f", d); } wxTextCtrl& wxTextCtrlBase::operator<<(int i) { - wxString str; - str.Printf(wxT("%d"), i); - AppendText(str); - return *TEXTCTRL(this); -} - -wxTextCtrl& wxTextCtrlBase::operator<<(long i) -{ - wxString str; - str.Printf(wxT("%ld"), i); - AppendText(str); - return *TEXTCTRL(this); + return *this << wxString::Format("%d", i); } -wxTextCtrl& wxTextCtrlBase::operator<<(const wxChar c) +wxTextCtrl& wxTextCtrlBase::operator<<(long l) { - return operator<<(wxString(c)); + return *this << wxString::Format("%ld", l); } // ---------------------------------------------------------------------------- @@ -319,43 +934,14 @@ int wxTextCtrlBase::overflow(int c) #endif // wxHAS_TEXT_WINDOW_STREAM -// ---------------------------------------------------------------------------- -// clipboard stuff -// ---------------------------------------------------------------------------- - -bool wxTextCtrlBase::CanCopy() const -{ - // can copy if there's a selection - long from, to; - GetSelection(&from, &to); - return from != to; -} - -bool wxTextCtrlBase::CanCut() const -{ - // can cut if there's a selection and if we're not read only - return CanCopy() && IsEditable(); -} - -bool wxTextCtrlBase::CanPaste() const -{ - // can paste if we are not read only - return IsEditable(); -} - // ---------------------------------------------------------------------------- // emulating key presses // ---------------------------------------------------------------------------- -#ifdef __WIN32__ -// the generic version is unused in wxMSW -bool wxTextCtrlBase::EmulateKeyPress(const wxKeyEvent& WXUNUSED(event)) -{ - return false; -} -#else // !__WIN32__ bool wxTextCtrlBase::EmulateKeyPress(const wxKeyEvent& event) { + // we have a native implementation for Win32 and so don't need this one +#ifndef __WIN32__ wxChar ch = 0; int keycode = event.GetKeyCode(); switch ( keycode ) @@ -370,32 +956,32 @@ bool wxTextCtrlBase::EmulateKeyPress(const wxKeyEvent& event) case WXK_NUMPAD7: case WXK_NUMPAD8: case WXK_NUMPAD9: - ch = (wxChar)(_T('0') + keycode - WXK_NUMPAD0); + ch = (wxChar)(wxT('0') + keycode - WXK_NUMPAD0); break; case WXK_MULTIPLY: case WXK_NUMPAD_MULTIPLY: - ch = _T('*'); + ch = wxT('*'); break; case WXK_ADD: case WXK_NUMPAD_ADD: - ch = _T('+'); + ch = wxT('+'); break; case WXK_SUBTRACT: case WXK_NUMPAD_SUBTRACT: - ch = _T('-'); + ch = wxT('-'); break; case WXK_DECIMAL: case WXK_NUMPAD_DECIMAL: - ch = _T('.'); + ch = wxT('.'); break; case WXK_DIVIDE: case WXK_NUMPAD_DIVIDE: - ch = _T('/'); + ch = wxT('/'); break; case WXK_DELETE: @@ -437,7 +1023,7 @@ bool wxTextCtrlBase::EmulateKeyPress(const wxKeyEvent& event) } else { - ch = _T('\0'); + ch = wxT('\0'); } } @@ -447,38 +1033,12 @@ bool wxTextCtrlBase::EmulateKeyPress(const wxKeyEvent& event) return true; } +#else // __WIN32__ + wxUnusedVar(event); +#endif // !__WIN32__/__WIN32__ return false; } -#endif // !__WIN32__ - -// ---------------------------------------------------------------------------- -// selection and ranges -// ---------------------------------------------------------------------------- - -void wxTextCtrlBase::SelectAll() -{ - SetSelection(0, GetLastPosition()); -} - -wxString wxTextCtrlBase::GetStringSelection() const -{ - long from, to; - GetSelection(&from, &to); - - return GetRange(from, to); -} - -wxString wxTextCtrlBase::GetRange(long from, long to) const -{ - wxString sel; - if ( from < to ) - { - sel = GetValue().Mid(from, to - from); - } - - return sel; -} // do the window-specific processing after processing the update event void wxTextCtrlBase::DoUpdateWindowUI(wxUpdateUIEvent& event) @@ -501,7 +1061,7 @@ void wxTextCtrlBase::DoUpdateWindowUI(wxUpdateUIEvent& event) // ---------------------------------------------------------------------------- wxTextCtrlHitTestResult -wxTextCtrlBase::HitTest(const wxPoint& pt, wxTextCoord *x, wxTextCoord *y) const +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 @@ -518,36 +1078,17 @@ wxTextCtrlBase::HitTest(const wxPoint& pt, wxTextCoord *x, wxTextCoord *y) const } wxTextCtrlHitTestResult -wxTextCtrlBase::HitTest(const wxPoint& WXUNUSED(pt), - long * WXUNUSED(pos)) const +wxTextAreaBase::HitTest(const wxPoint& WXUNUSED(pt), long * WXUNUSED(pos)) const { // not implemented return wxTE_HT_UNKNOWN; } -// ---------------------------------------------------------------------------- -// events -// ---------------------------------------------------------------------------- - -void wxTextCtrlBase::SendTextUpdatedEvent() -{ - wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, GetId()); - - // do not do this as it could be very inefficient if the text control - // contains a lot of text and we're not using ref-counted wxString - // implementation -- instead, event.GetString() will query the control for - // its current text if needed - //event.SetString(GetValue()); - - event.SetEventObject(this); - GetEventHandler()->ProcessEvent(event); -} - #else // !wxUSE_TEXTCTRL // define this one even if !wxUSE_TEXTCTRL because it is also used by other // controls (wxComboBox and wxSpinCtrl) -DEFINE_EVENT_TYPE(wxEVT_COMMAND_TEXT_UPDATED) +wxDEFINE_EVENT( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEvent ); #endif // wxUSE_TEXTCTRL/!wxUSE_TEXTCTRL