From 42688aea2d1703c2942e281658ca8183f728f8fa Mon Sep 17 00:00:00 2001 From: Julian Smart Date: Wed, 8 Nov 2006 14:05:50 +0000 Subject: [PATCH] Added a couple of text effects Added style description Fixed some bugs in style comparison Fixed extra newline when loading git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@43197 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/richtext/richtextbuffer.h | 55 +++++++-- include/wx/richtext/richtextfontpage.h | 10 ++ include/wx/richtext/richtextformatdlg.h | 6 + include/wx/richtext/richtextstyles.h | 26 ++++- samples/richtext/richtext.cpp | 5 +- src/richtext/richtextbuffer.cpp | 201 ++++++++++++++++++++++++++++---- src/richtext/richtextctrl.cpp | 3 + src/richtext/richtextfontpage.cpp | 113 +++++++++++++++++- src/richtext/richtextformatdlg.cpp | 9 ++ src/richtext/richtexthtml.cpp | 13 ++- src/richtext/richtextstyles.cpp | 4 + src/richtext/richtextxml.cpp | 48 +++++++- 12 files changed, 444 insertions(+), 49 deletions(-) diff --git a/include/wx/richtext/richtextbuffer.h b/include/wx/richtext/richtextbuffer.h index 063e1bd..8a1149d 100644 --- a/include/wx/richtext/richtextbuffer.h +++ b/include/wx/richtext/richtextbuffer.h @@ -199,6 +199,7 @@ class WXDLLIMPEXP_RICHTEXT wxRichTextBuffer; #define wxTEXT_ATTR_BULLET_NAME 0x00100000 #define wxTEXT_ATTR_URL 0x00200000 #define wxTEXT_ATTR_PAGE_BREAK 0x00400000 +#define wxTEXT_ATTR_EFFECTS 0x00800000 /*! * Styles for wxTextAttrEx::SetBulletStyle @@ -223,6 +224,22 @@ class WXDLLIMPEXP_RICHTEXT wxRichTextBuffer; #define wxTEXT_ATTR_BULLET_STYLE_ALIGN_CENTRE 0x00002000 /*! + * Styles for wxTextAttrEx::SetTextEffects + */ + +#define wxTEXT_ATTR_EFFECT_NONE 0x00000000 +#define wxTEXT_ATTR_EFFECT_CAPITALS 0x00000001 +#define wxTEXT_ATTR_EFFECT_SMALL_CAPITALS 0x00000002 +#define wxTEXT_ATTR_EFFECT_STRIKETHROUGH 0x00000004 +#define wxTEXT_ATTR_EFFECT_DOUBLE_STRIKETHROUGH 0x00000008 +#define wxTEXT_ATTR_EFFECT_SHADOW 0x00000010 +#define wxTEXT_ATTR_EFFECT_EMBOSS 0x00000020 +#define wxTEXT_ATTR_EFFECT_OUTLINE 0x00000040 +#define wxTEXT_ATTR_EFFECT_ENGRAVE 0x00000080 +#define wxTEXT_ATTR_EFFECT_SUPERSCRIPT 0x00000100 +#define wxTEXT_ATTR_EFFECT_SUBSCRIPT 0x00000200 + +/*! * Line spacing values */ @@ -234,7 +251,7 @@ class WXDLLIMPEXP_RICHTEXT wxRichTextBuffer; * Character and paragraph combined styles */ -#define wxTEXT_ATTR_CHARACTER (wxTEXT_ATTR_FONT | wxTEXT_ATTR_BACKGROUND_COLOUR | wxTEXT_ATTR_TEXT_COLOUR | wxTEXT_ATTR_CHARACTER_STYLE_NAME | wxTEXT_ATTR_URL) +#define wxTEXT_ATTR_CHARACTER (wxTEXT_ATTR_FONT|wxTEXT_ATTR_EFFECTS|wxTEXT_ATTR_BACKGROUND_COLOUR|wxTEXT_ATTR_TEXT_COLOUR|wxTEXT_ATTR_CHARACTER_STYLE_NAME|wxTEXT_ATTR_URL) #define wxTEXT_ATTR_PARAGRAPH (wxTEXT_ATTR_ALIGNMENT|wxTEXT_ATTR_LEFT_INDENT|wxTEXT_ATTR_RIGHT_INDENT|wxTEXT_ATTR_TABS|\ wxTEXT_ATTR_PARA_SPACING_BEFORE|wxTEXT_ATTR_PARA_SPACING_AFTER|wxTEXT_ATTR_LINE_SPACING|\ @@ -348,6 +365,8 @@ public: void SetBulletFont(const wxString& bulletFont) { m_bulletFont = bulletFont; } void SetURL(const wxString& url) { m_urlTarget = url; SetFlags(GetFlags() | wxTEXT_ATTR_URL); } void SetPageBreak(bool pageBreak = true) { SetFlags(pageBreak ? (GetFlags() | wxTEXT_ATTR_PAGE_BREAK) : (GetFlags() & ~wxTEXT_ATTR_PAGE_BREAK)); } + void SetTextEffects(int effects) { m_textEffects = effects; SetFlags(GetFlags() | wxTEXT_ATTR_EFFECTS); } + void SetTextEffectFlags(int effects) { m_textEffectFlags = effects; } const wxString& GetCharacterStyleName() const { return m_characterStyleName; } const wxString& GetParagraphStyleName() const { return m_paragraphStyleName; } @@ -361,6 +380,8 @@ public: const wxString& GetBulletName() const { return m_bulletName; } const wxString& GetBulletFont() const { return m_bulletFont; } const wxString& GetURL() const { return m_urlTarget; } + int GetTextEffects() const { return m_textEffects; } + int GetTextEffectFlags() const { return m_textEffectFlags; } bool HasWeight() const { return (GetFlags() & wxTEXT_ATTR_FONT_WEIGHT) != 0; } bool HasSize() const { return (GetFlags() & wxTEXT_ATTR_FONT_SIZE) != 0; } @@ -380,6 +401,8 @@ public: bool HasBulletName() const { return HasFlag(wxTEXT_ATTR_BULLET_NAME); } bool HasURL() const { return HasFlag(wxTEXT_ATTR_URL); } bool HasPageBreak() const { return HasFlag(wxTEXT_ATTR_PAGE_BREAK); } + bool HasTextEffects() const { return HasFlag(wxTEXT_ATTR_EFFECTS); } + bool HasTextEffect(int effect) const { return HasFlag(wxTEXT_ATTR_EFFECTS) && ((GetTextEffectFlags() & effect) != 0); } // Is this a character style? bool IsCharacterStyle() const { return (0 != (GetFlags() & wxTEXT_ATTR_CHARACTER)); } @@ -388,11 +411,7 @@ public: // returns false if we have any attributes set, true otherwise bool IsDefault() const { - return !HasTextColour() && !HasBackgroundColour() && !HasFont() && !HasAlignment() && - !HasTabs() && !HasLeftIndent() && !HasRightIndent() && - !HasParagraphSpacingAfter() && !HasParagraphSpacingBefore() && !HasLineSpacing() && - !HasCharacterStyleName() && !HasParagraphStyleName() && !HasListStyleName() && - !HasBulletNumber() && !HasBulletStyle() && !HasBulletText() && !HasBulletName() && !HasURL(); + return (GetFlags() == 0); } // return the attribute having the valid font and colours: it uses the @@ -409,6 +428,8 @@ private: int m_lineSpacing; int m_bulletStyle; int m_bulletNumber; + int m_textEffects; + int m_textEffectFlags; wxString m_bulletText; wxString m_bulletFont; wxString m_bulletName; @@ -496,6 +517,8 @@ public: void SetBulletName(const wxString& name) { m_bulletName = name; m_flags |= wxTEXT_ATTR_BULLET_NAME; } void SetURL(const wxString& url) { m_urlTarget = url; m_flags |= wxTEXT_ATTR_URL; } void SetPageBreak(bool pageBreak = true) { SetFlags(pageBreak ? (GetFlags() | wxTEXT_ATTR_PAGE_BREAK) : (GetFlags() & ~wxTEXT_ATTR_PAGE_BREAK)); } + void SetTextEffects(int effects) { m_textEffects = effects; SetFlags(GetFlags() | wxTEXT_ATTR_EFFECTS); } + void SetTextEffectFlags(int effects) { m_textEffectFlags = effects; } const wxColour& GetTextColour() const { return m_colText; } const wxColour& GetBackgroundColour() const { return m_colBack; } @@ -524,6 +547,8 @@ public: const wxString& GetBulletFont() const { return m_bulletFont; } const wxString& GetBulletName() const { return m_bulletName; } const wxString& GetURL() const { return m_urlTarget; } + int GetTextEffects() const { return m_textEffects; } + int GetTextEffectFlags() const { return m_textEffectFlags; } // accessors bool HasTextColour() const { return m_colText.Ok() && HasFlag(wxTEXT_ATTR_TEXT_COLOUR) ; } @@ -551,6 +576,8 @@ public: bool HasBulletName() const { return (m_flags & wxTEXT_ATTR_BULLET_NAME) != 0; } bool HasURL() const { return HasFlag(wxTEXT_ATTR_URL); } bool HasPageBreak() const { return HasFlag(wxTEXT_ATTR_PAGE_BREAK); } + bool HasTextEffects() const { return HasFlag(wxTEXT_ATTR_EFFECTS); } + bool HasTextEffect(int effect) const { return HasFlag(wxTEXT_ATTR_EFFECTS) && ((GetTextEffectFlags() & effect) != 0); } bool HasFlag(long flag) const { return (m_flags & flag) != 0; } @@ -561,11 +588,7 @@ public: // returns false if we have any attributes set, true otherwise bool IsDefault() const { - return !HasTextColour() && !HasBackgroundColour() && !HasFont() && !HasAlignment() && - !HasTabs() && !HasLeftIndent() && !HasRightIndent() && - !HasParagraphSpacingAfter() && !HasParagraphSpacingBefore() && !HasLineSpacing() && - !HasCharacterStyleName() && !HasParagraphStyleName() && !HasListStyleName() && - !HasBulletNumber() && !HasBulletStyle() && !HasBulletText() && !HasBulletName() && !HasURL(); + return GetFlags() == 0; } // return the attribute having the valid font and colours: it uses the @@ -591,6 +614,8 @@ private: int m_lineSpacing; int m_bulletStyle; int m_bulletNumber; + int m_textEffects; + int m_textEffectFlags; wxString m_bulletText; wxString m_bulletFont; wxString m_bulletName; @@ -1036,7 +1061,7 @@ public: /// Combines 'style' with 'currentStyle' for the purpose of summarising the attributes of a range of /// content. - bool CollectStyle(wxTextAttrEx& currentStyle, const wxTextAttrEx& style, long& multipleStyleAttributes); + bool CollectStyle(wxTextAttrEx& currentStyle, const wxTextAttrEx& style, long& multipleStyleAttributes, int& multipleTextEffectAttributes); /// Set list style virtual bool SetListStyle(const wxRichTextRange& range, wxRichTextListStyleDefinition* def, int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO, int startFrom = 1, int specifiedLevel = -1); @@ -2267,6 +2292,12 @@ WXDLLIMPEXP_RICHTEXT bool wxRichTextApplyStyle(wxRichTextAttr& destStyle, const WXDLLIMPEXP_RICHTEXT bool wxRichTextApplyStyle(wxTextAttrEx& destStyle, const wxRichTextAttr& style, wxRichTextAttr* compareWith = NULL); WXDLLIMPEXP_RICHTEXT bool wxRichTextApplyStyle(wxRichTextAttr& destStyle, const wxRichTextAttr& style, wxRichTextAttr* compareWith = NULL); +/// Combine two bitlists +WXDLLIMPEXP_RICHTEXT bool wxRichTextCombineBitlists(int& valueA, int valueB, int& flagsA, int flagsB); + +/// Compare two bitlists +WXDLLIMPEXP_RICHTEXT bool wxRichTextBitlistsEqPartial(int valueA, int valueB, int flags); + /// Split into paragraph and character styles WXDLLIMPEXP_RICHTEXT bool wxRichTextSplitParaCharStyles(const wxTextAttrEx& style, wxTextAttrEx& parStyle, wxTextAttrEx& charStyle); diff --git a/include/wx/richtext/richtextfontpage.h b/include/wx/richtext/richtextfontpage.h index 48fb930..839e9ce 100644 --- a/include/wx/richtext/richtextfontpage.h +++ b/include/wx/richtext/richtextfontpage.h @@ -97,6 +97,12 @@ public: /// wxEVT_COMMAND_COMBOBOX_SELECTED event handler for ID_RICHTEXTFONTPAGE_UNDERLINING_CTRL void OnUnderliningCtrlSelected( wxCommandEvent& event ); + /// wxEVT_COMMAND_CHECKBOX_CLICKED event handler for ID_RICHTEXTFONTPAGE_STRIKETHROUGHCTRL + void OnStrikethroughctrlClick( wxCommandEvent& event ); + + /// wxEVT_COMMAND_CHECKBOX_CLICKED event handler for ID_RICHTEXTFONTPAGE_CAPSCTRL + void OnCapsctrlClick( wxCommandEvent& event ); + ////@end wxRichTextFontPage event handler declarations ////@begin wxRichTextFontPage member function declarations @@ -120,6 +126,8 @@ public: wxComboBox* m_weightCtrl; wxComboBox* m_underliningCtrl; wxRichTextColourSwatchCtrl* m_colourCtrl; + wxCheckBox* m_strikethroughCtrl; + wxCheckBox* m_capitalsCtrl; wxRichTextFontPreviewCtrl* m_previewCtrl; /// Control identifiers enum { @@ -132,6 +140,8 @@ public: ID_RICHTEXTFONTPAGE_WEIGHTCTRL = 10004, ID_RICHTEXTFONTPAGE_UNDERLINING_CTRL = 10008, ID_RICHTEXTFONTPAGE_COLOURCTRL = 10009, + ID_RICHTEXTFONTPAGE_STRIKETHROUGHCTRL = 10010, + ID_RICHTEXTFONTPAGE_CAPSCTRL = 10011, ID_RICHTEXTFONTPAGE_PREVIEWCTRL = 10003 }; ////@end wxRichTextFontPage member variables diff --git a/include/wx/richtext/richtextformatdlg.h b/include/wx/richtext/richtextformatdlg.h index af41de9..0e3aec2 100644 --- a/include/wx/richtext/richtextformatdlg.h +++ b/include/wx/richtext/richtextformatdlg.h @@ -222,9 +222,15 @@ public: wxWindow(parent, id, pos, sz, style) { SetBackgroundColour(*wxWHITE); + m_textEffects = 0; } + void SetTextEffects(int effects) { m_textEffects = effects; } + int GetTextEffects() const { return m_textEffects; } + private: + int m_textEffects; + void OnPaint(wxPaintEvent& event); DECLARE_EVENT_TABLE() }; diff --git a/include/wx/richtext/richtextstyles.h b/include/wx/richtext/richtextstyles.h index bce0f33..30ec7fe 100644 --- a/include/wx/richtext/richtextstyles.h +++ b/include/wx/richtext/richtextstyles.h @@ -85,6 +85,10 @@ public: void SetName(const wxString& name) { m_name = name; } const wxString& GetName() const { return m_name; } + /// Sets and gets the style description + void SetDescription(const wxString& descr) { m_description = descr; } + const wxString& GetDescription() const { return m_description; } + /// Sets and gets the name of the style that this style is based on void SetBaseStyle(const wxString& name) { m_baseStyle = name; } const wxString& GetBaseStyle() const { return m_baseStyle; } @@ -97,6 +101,7 @@ public: protected: wxString m_name; wxString m_baseStyle; + wxString m_description; wxRichTextAttr m_style; }; @@ -327,6 +332,14 @@ public: wxRichTextStyleSheet* GetPreviousSheet() const { return m_previousSheet; } void SetPreviousSheet(wxRichTextStyleSheet* sheet) { m_previousSheet = sheet; } + /// Sets and gets the name of the style sheet + void SetName(const wxString& name) { m_name = name; } + const wxString& GetName() const { return m_name; } + + /// Sets and gets the style description + void SetDescription(const wxString& descr) { m_description = descr; } + const wxString& GetDescription() const { return m_description; } + /// Implementation /// Add a definition to one of the style lists @@ -340,12 +353,15 @@ public: protected: - wxList m_characterStyleDefinitions; - wxList m_paragraphStyleDefinitions; - wxList m_listStyleDefinitions; + wxString m_description; + wxString m_name; + + wxList m_characterStyleDefinitions; + wxList m_paragraphStyleDefinitions; + wxList m_listStyleDefinitions; - wxRichTextStyleSheet* m_previousSheet; - wxRichTextStyleSheet* m_nextSheet; + wxRichTextStyleSheet* m_previousSheet; + wxRichTextStyleSheet* m_nextSheet; }; #if wxUSE_HTML diff --git a/samples/richtext/richtext.cpp b/samples/richtext/richtext.cpp index 08d7db7..ff192a8 100644 --- a/samples/richtext/richtext.cpp +++ b/samples/richtext/richtext.cpp @@ -735,8 +735,8 @@ MyFrame::MyFrame(const wxString& title, wxWindowID id, const wxPoint& pos, r.EndItalic(); r.EndBold(); - r.Newline(); + r.WriteImage(wxBitmap(zebra_xpm)); r.EndAlignment(); @@ -745,6 +745,7 @@ MyFrame::MyFrame(const wxString& title, wxWindowID id, const wxPoint& pos, r.Newline(); r.WriteText(wxT("What can you do with this thing? ")); + r.WriteImage(wxBitmap(smiley_xpm)); r.WriteText(wxT(" Well, you can change text ")); @@ -1100,7 +1101,7 @@ void MyFrame::OnFont(wxCommandEvent& WXUNUSED(event)) if (formatDlg.ShowModal() == wxID_OK) { - formatDlg.ApplyStyle(m_richTextCtrl, range); + formatDlg.ApplyStyle(m_richTextCtrl, range, wxRICHTEXT_SETSTYLE_WITH_UNDO|wxRICHTEXT_SETSTYLE_OPTIMIZE|wxRICHTEXT_SETSTYLE_CHARACTERS_ONLY); } // Old method using wxFontDialog diff --git a/src/richtext/richtextbuffer.cpp b/src/richtext/richtextbuffer.cpp index 064e792..e361c51 100644 --- a/src/richtext/richtextbuffer.cpp +++ b/src/richtext/richtextbuffer.cpp @@ -1853,7 +1853,7 @@ static bool wxHasStyle(long flags, long style) /// Combines 'style' with 'currentStyle' for the purpose of summarising the attributes of a range of /// content. -bool wxRichTextParagraphLayoutBox::CollectStyle(wxTextAttrEx& currentStyle, const wxTextAttrEx& style, long& multipleStyleAttributes) +bool wxRichTextParagraphLayoutBox::CollectStyle(wxTextAttrEx& currentStyle, const wxTextAttrEx& style, long& multipleStyleAttributes, int& multipleTextEffectAttributes) { if (style.HasFont()) { @@ -2066,7 +2066,7 @@ bool wxRichTextParagraphLayoutBox::CollectStyle(wxTextAttrEx& currentStyle, cons { if (currentStyle.HasParagraphSpacingAfter()) { - if (currentStyle.HasParagraphSpacingAfter() != style.HasParagraphSpacingAfter()) + if (currentStyle.GetParagraphSpacingAfter() != style.GetParagraphSpacingAfter()) { // Clash of style - mark as such multipleStyleAttributes |= wxTEXT_ATTR_PARA_SPACING_AFTER; @@ -2081,7 +2081,7 @@ bool wxRichTextParagraphLayoutBox::CollectStyle(wxTextAttrEx& currentStyle, cons { if (currentStyle.HasParagraphSpacingBefore()) { - if (currentStyle.HasParagraphSpacingBefore() != style.HasParagraphSpacingBefore()) + if (currentStyle.GetParagraphSpacingBefore() != style.GetParagraphSpacingBefore()) { // Clash of style - mark as such multipleStyleAttributes |= wxTEXT_ATTR_PARA_SPACING_BEFORE; @@ -2096,7 +2096,7 @@ bool wxRichTextParagraphLayoutBox::CollectStyle(wxTextAttrEx& currentStyle, cons { if (currentStyle.HasLineSpacing()) { - if (currentStyle.HasLineSpacing() != style.HasLineSpacing()) + if (currentStyle.GetLineSpacing() != style.GetLineSpacing()) { // Clash of style - mark as such multipleStyleAttributes |= wxTEXT_ATTR_LINE_SPACING; @@ -2111,7 +2111,7 @@ bool wxRichTextParagraphLayoutBox::CollectStyle(wxTextAttrEx& currentStyle, cons { if (currentStyle.HasCharacterStyleName()) { - if (currentStyle.HasCharacterStyleName() != style.HasCharacterStyleName()) + if (currentStyle.GetCharacterStyleName() != style.GetCharacterStyleName()) { // Clash of style - mark as such multipleStyleAttributes |= wxTEXT_ATTR_CHARACTER_STYLE_NAME; @@ -2126,7 +2126,7 @@ bool wxRichTextParagraphLayoutBox::CollectStyle(wxTextAttrEx& currentStyle, cons { if (currentStyle.HasParagraphStyleName()) { - if (currentStyle.HasParagraphStyleName() != style.HasParagraphStyleName()) + if (currentStyle.GetParagraphStyleName() != style.GetParagraphStyleName()) { // Clash of style - mark as such multipleStyleAttributes |= wxTEXT_ATTR_PARAGRAPH_STYLE_NAME; @@ -2141,7 +2141,7 @@ bool wxRichTextParagraphLayoutBox::CollectStyle(wxTextAttrEx& currentStyle, cons { if (currentStyle.HasListStyleName()) { - if (currentStyle.HasListStyleName() != style.HasListStyleName()) + if (currentStyle.GetListStyleName() != style.GetListStyleName()) { // Clash of style - mark as such multipleStyleAttributes |= wxTEXT_ATTR_LIST_STYLE_NAME; @@ -2156,7 +2156,7 @@ bool wxRichTextParagraphLayoutBox::CollectStyle(wxTextAttrEx& currentStyle, cons { if (currentStyle.HasBulletStyle()) { - if (currentStyle.HasBulletStyle() != style.HasBulletStyle()) + if (currentStyle.GetBulletStyle() != style.GetBulletStyle()) { // Clash of style - mark as such multipleStyleAttributes |= wxTEXT_ATTR_BULLET_STYLE; @@ -2171,7 +2171,7 @@ bool wxRichTextParagraphLayoutBox::CollectStyle(wxTextAttrEx& currentStyle, cons { if (currentStyle.HasBulletNumber()) { - if (currentStyle.HasBulletNumber() != style.HasBulletNumber()) + if (currentStyle.GetBulletNumber() != style.GetBulletNumber()) { // Clash of style - mark as such multipleStyleAttributes |= wxTEXT_ATTR_BULLET_NUMBER; @@ -2186,7 +2186,7 @@ bool wxRichTextParagraphLayoutBox::CollectStyle(wxTextAttrEx& currentStyle, cons { if (currentStyle.HasBulletText()) { - if (currentStyle.HasBulletText() != style.HasBulletText()) + if (currentStyle.GetBulletText() != style.GetBulletText()) { // Clash of style - mark as such multipleStyleAttributes |= wxTEXT_ATTR_BULLET_TEXT; @@ -2204,7 +2204,7 @@ bool wxRichTextParagraphLayoutBox::CollectStyle(wxTextAttrEx& currentStyle, cons { if (currentStyle.HasBulletName()) { - if (currentStyle.HasBulletName() != style.HasBulletName()) + if (currentStyle.GetBulletName() != style.GetBulletName()) { // Clash of style - mark as such multipleStyleAttributes |= wxTEXT_ATTR_BULLET_NAME; @@ -2221,7 +2221,7 @@ bool wxRichTextParagraphLayoutBox::CollectStyle(wxTextAttrEx& currentStyle, cons { if (currentStyle.HasURL()) { - if (currentStyle.HasURL() != style.HasURL()) + if (currentStyle.GetURL() != style.GetURL()) { // Clash of style - mark as such multipleStyleAttributes |= wxTEXT_ATTR_URL; @@ -2234,6 +2234,33 @@ bool wxRichTextParagraphLayoutBox::CollectStyle(wxTextAttrEx& currentStyle, cons } } + if (style.HasTextEffects() && !wxHasStyle(multipleStyleAttributes, wxTEXT_ATTR_EFFECTS)) + { + if (currentStyle.HasTextEffects()) + { + // We need to find the bits in the new style that are different: + // just look at those bits that are specified by the new style. + + int currentRelevantTextEffects = currentStyle.GetTextEffects() & style.GetTextEffectFlags(); + int newRelevantTextEffects = style.GetTextEffects() & style.GetTextEffectFlags(); + + if (currentRelevantTextEffects != newRelevantTextEffects) + { + // Find the text effects that were different, using XOR + int differentEffects = currentRelevantTextEffects ^ newRelevantTextEffects; + + // Clash of style - mark as such + multipleTextEffectAttributes |= differentEffects; + currentStyle.SetTextEffectFlags(currentStyle.GetTextEffectFlags() & ~differentEffects); + } + } + else + { + currentStyle.SetTextEffects(style.GetTextEffects()); + currentStyle.SetTextEffectFlags(style.GetTextEffectFlags()); + } + } + return true; } @@ -2247,7 +2274,8 @@ bool wxRichTextParagraphLayoutBox::GetStyleForRange(const wxRichTextRange& range // The attributes that aren't valid because of multiple styles within the range long multipleStyleAttributes = 0; - + int multipleTextEffectAttributes = 0; + wxRichTextObjectList::compatibility_iterator node = GetChildren().GetFirst(); while (node) { @@ -2258,7 +2286,7 @@ bool wxRichTextParagraphLayoutBox::GetStyleForRange(const wxRichTextRange& range { wxTextAttrEx paraStyle = para->GetCombinedAttributes(); - CollectStyle(style, paraStyle, multipleStyleAttributes); + CollectStyle(style, paraStyle, multipleStyleAttributes, multipleTextEffectAttributes); } else { @@ -2268,7 +2296,7 @@ bool wxRichTextParagraphLayoutBox::GetStyleForRange(const wxRichTextRange& range // First collect paragraph attributes only wxTextAttrEx paraStyle = para->GetCombinedAttributes(); paraStyle.SetFlags(paraStyle.GetFlags() & wxTEXT_ATTR_PARAGRAPH); - CollectStyle(style, paraStyle, multipleStyleAttributes); + CollectStyle(style, paraStyle, multipleStyleAttributes, multipleTextEffectAttributes); wxRichTextObjectList::compatibility_iterator childNode = para->GetChildren().GetFirst(); @@ -2282,7 +2310,7 @@ bool wxRichTextParagraphLayoutBox::GetStyleForRange(const wxRichTextRange& range // Now collect character attributes only childStyle.SetFlags(childStyle.GetFlags() & wxTEXT_ATTR_CHARACTER); - CollectStyle(style, childStyle, multipleStyleAttributes); + CollectStyle(style, childStyle, multipleStyleAttributes, multipleTextEffectAttributes); } childNode = childNode->GetNext(); @@ -4106,6 +4134,8 @@ bool wxRichTextPlainText::Draw(wxDC& dc, const wxRichTextRange& range, const wxR long len = range.GetLength(); wxString stringChunk = m_text.Mid(range.GetStart() - offset, (size_t) len); + if (textAttr.HasTextEffects() && (textAttr.GetTextEffects() & wxTEXT_ATTR_EFFECT_CAPITALS)) + stringChunk.MakeUpper(); int charHeight = dc.GetCharHeight(); @@ -4278,6 +4308,15 @@ bool wxRichTextPlainText::DrawTabbedString(wxDC& dc, const wxTextAttrEx& attr, c dc.DrawRectangle(selRect); } dc.DrawText(stringChunk, x, y); + + if (attr.HasTextEffects() && (attr.GetTextEffects() & wxTEXT_ATTR_EFFECT_STRIKETHROUGH)) + { + wxPen oldPen = dc.GetPen(); + dc.SetPen(wxPen(attr.GetTextColour(), 1)); + dc.DrawLine(x, (int) (y+(h/2)+0.5), x+w, (int) (y+(h/2)+0.5)); + dc.SetPen(oldPen); + } + x = nextTabPos; } } @@ -4293,6 +4332,15 @@ bool wxRichTextPlainText::DrawTabbedString(wxDC& dc, const wxTextAttrEx& attr, c dc.DrawRectangle(selRect); } dc.DrawText(str, x, y); + + if (attr.HasTextEffects() && (attr.GetTextEffects() & wxTEXT_ATTR_EFFECT_STRIKETHROUGH)) + { + wxPen oldPen = dc.GetPen(); + dc.SetPen(wxPen(attr.GetTextColour(), 1)); + dc.DrawLine(x, (int) (y+(h/2)+0.5), x+w, (int) (y+(h/2)+0.5)); + dc.SetPen(oldPen); + } + x += w; } return true; @@ -4314,8 +4362,12 @@ bool wxRichTextPlainText::Layout(wxDC& dc, const wxRect& WXUNUSED(rect), int WXU if (textAttr.GetFont().Ok()) dc.SetFont(textAttr.GetFont()); + wxString str = m_text; + if (textAttr.HasTextEffects() && (textAttr.GetTextEffects() & wxTEXT_ATTR_EFFECT_CAPITALS)) + str.MakeUpper(); + wxCoord w, h; - dc.GetTextExtent(m_text, & w, & h, & m_descent); + dc.GetTextExtent(str, & w, & h, & m_descent); m_size = wxSize(w, dc.GetCharHeight()); return true; @@ -4355,6 +4407,10 @@ bool wxRichTextPlainText::GetRangeSize(const wxRichTextRange& range, wxSize& siz int startPos = range.GetStart() - GetRange().GetStart(); long len = range.GetLength(); wxString stringChunk = m_text.Mid(startPos, (size_t) len); + + if (textAttr.HasTextEffects() && (textAttr.GetTextEffects() & wxTEXT_ATTR_EFFECT_CAPITALS)) + stringChunk.MakeUpper(); + wxCoord w, h; int width = 0; if (stringChunk.Find(wxT('\t')) != wxNOT_FOUND) @@ -6329,6 +6385,8 @@ bool wxTextAttrEq(const wxTextAttrEx& attr1, const wxRichTextAttr& attr2) attr1.GetFont().GetWeight() == attr2.GetFontWeight() && attr1.GetFont().GetFaceName() == attr2.GetFontFaceName() && attr1.GetFont().GetUnderlined() == attr2.GetFontUnderlined() && + attr1.GetTextEffects() == attr2.GetTextEffects() && + attr1.GetTextEffectFlags() == attr2.GetTextEffectFlags() && attr1.GetAlignment() == attr2.GetAlignment() && attr1.GetLeftIndent() == attr2.GetLeftIndent() && attr1.GetRightIndent() == attr2.GetRightIndent() && @@ -6438,6 +6496,14 @@ bool wxTextAttrEqPartial(const wxTextAttrEx& attr1, const wxTextAttrEx& attr2, i (attr1.HasPageBreak() != attr2.HasPageBreak())) return false; + if (flags & wxTEXT_ATTR_EFFECTS) + { + if (attr1.HasTextEffects() != attr2.HasTextEffects()) + return false; + if (!wxRichTextBitlistsEqPartial(attr1.GetTextEffects(), attr2.GetTextEffects(), attr2.GetTextEffectFlags())) + return false; + } + return true; } @@ -6532,6 +6598,14 @@ bool wxTextAttrEqPartial(const wxTextAttrEx& attr1, const wxRichTextAttr& attr2, (attr1.HasPageBreak() != attr2.HasPageBreak())) return false; + if (flags & wxTEXT_ATTR_EFFECTS) + { + if (attr1.HasTextEffects() != attr2.HasTextEffects()) + return false; + if (!wxRichTextBitlistsEqPartial(attr1.GetTextEffects(), attr2.GetTextEffects(), attr2.GetTextEffectFlags())) + return false; + } + return true; } @@ -6550,7 +6624,6 @@ bool wxRichTextTabsEq(const wxArrayInt& tabs1, const wxArrayInt& tabs2) return true; } - /// Apply one style to another bool wxRichTextApplyStyle(wxTextAttrEx& destStyle, const wxTextAttrEx& style) { @@ -6658,6 +6731,20 @@ bool wxRichTextApplyStyle(wxTextAttrEx& destStyle, const wxTextAttrEx& style) if (style.HasPageBreak()) destStyle.SetPageBreak(); + if (style.HasTextEffects()) + { + int destBits = destStyle.GetTextEffects(); + int destFlags = destStyle.GetTextEffectFlags(); + + int srcBits = style.GetTextEffects(); + int srcFlags = style.GetTextEffectFlags(); + + wxRichTextCombineBitlists(destBits, srcBits, destFlags, srcFlags); + + destStyle.SetTextEffects(destBits); + destStyle.SetTextEffectFlags(destFlags); + } + return true; } @@ -6878,9 +6965,54 @@ bool wxRichTextApplyStyle(wxTextAttrEx& destStyle, const wxRichTextAttr& style, 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(); + + wxRichTextCombineBitlists(destBits, srcBits, destFlags, srcFlags); + + destStyle.SetTextEffects(destBits); + destStyle.SetTextEffectFlags(destFlags); + } + } + return true; } +/// Combine two bitlists, specifying the bits of interest with separate flags. +bool wxRichTextCombineBitlists(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 wxRichTextBitlistsEqPartial(int valueA, int valueB, int flags) +{ + int relevantBitsA = valueA & flags; + int relevantBitsB = valueB & flags; + return (relevantBitsA != relevantBitsB); +} + /// Split into paragraph and character styles bool wxRichTextSplitParaCharStyles(const wxTextAttrEx& style, wxTextAttrEx& parStyle, wxTextAttrEx& charStyle) { @@ -7003,6 +7135,8 @@ void wxRichTextAttr::Init() 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_bulletNumber = 0; } @@ -7023,6 +7157,8 @@ void wxRichTextAttr::Copy(const wxRichTextAttr& attr) m_fontWeight = attr.m_fontWeight; m_fontUnderlined = attr.m_fontUnderlined; m_fontFaceName = attr.m_fontFaceName; + m_textEffects = attr.m_textEffects; + m_textEffectFlags = attr.m_textEffectFlags; m_paragraphSpacingAfter = attr.m_paragraphSpacingAfter; m_paragraphSpacingBefore = attr.m_paragraphSpacingBefore; @@ -7048,6 +7184,8 @@ void wxRichTextAttr::operator= (const wxRichTextAttr& attr) // operators void wxRichTextAttr::operator= (const wxTextAttrEx& attr) { + m_flags = attr.GetFlags(); + m_colText = attr.GetTextColour(); m_colBack = attr.GetBackgroundColour(); m_textAlignment = attr.GetAlignment(); @@ -7055,7 +7193,8 @@ void wxRichTextAttr::operator= (const wxTextAttrEx& attr) m_leftSubIndent = attr.GetLeftSubIndent(); m_rightIndent = attr.GetRightIndent(); m_tabs = attr.GetTabs(); - m_flags = attr.GetFlags(); + m_textEffects = attr.GetTextEffects(); + m_textEffectFlags = attr.GetTextEffectFlags(); m_paragraphSpacingAfter = attr.GetParagraphSpacingAfter(); m_paragraphSpacingBefore = attr.GetParagraphSpacingBefore(); @@ -7110,6 +7249,9 @@ bool wxRichTextAttr::operator== (const wxRichTextAttr& attr) const GetBulletFont() == attr.GetBulletFont() && GetBulletName() == attr.GetBulletName() && + GetTextEffects() == attr.GetTextEffects() && + GetTextEffectFlags() == attr.GetTextEffectFlags() && + m_fontSize == attr.m_fontSize && m_fontStyle == attr.m_fontStyle && m_fontWeight == attr.m_fontWeight && @@ -7141,6 +7283,8 @@ void wxRichTextAttr::CopyTo(wxTextAttrEx& attr) const attr.SetCharacterStyleName(m_characterStyleName); attr.SetParagraphStyleName(m_paragraphStyleName); attr.SetListStyleName(m_listStyleName); + attr.SetTextEffects(m_textEffects); + attr.SetTextEffectFlags(m_textEffectFlags); attr.SetURL(m_urlTarget); @@ -7272,6 +7416,12 @@ wxRichTextAttr wxRichTextAttr::Combine(const wxRichTextAttr& attr, if (attr.HasPageBreak()) newAttr.SetPageBreak(); + if (attr.HasTextEffects()) + { + newAttr.SetTextEffects(attr.GetTextEffects()); + newAttr.SetTextEffectFlags(attr.GetTextEffectFlags()); + } + return newAttr; } @@ -7291,6 +7441,8 @@ void wxTextAttrEx::Init() 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_bulletNumber = 0; } @@ -7311,6 +7463,8 @@ void wxTextAttrEx::Copy(const wxTextAttrEx& attr) m_bulletFont = attr.m_bulletFont; m_bulletName = attr.m_bulletName; m_urlTarget = attr.m_urlTarget; + m_textEffects = attr.m_textEffects; + m_textEffectFlags = attr.m_textEffectFlags; } // Assignment from a wxTextAttrEx object @@ -7332,6 +7486,7 @@ bool wxTextAttrEx::operator== (const wxTextAttrEx& attr) const GetTextColour() == attr.GetTextColour() && GetBackgroundColour() == attr.GetBackgroundColour() && GetFont() == attr.GetFont() && + GetTextEffects() == attr.GetTextEffects() && GetAlignment() == attr.GetAlignment() && GetLeftIndent() == attr.GetLeftIndent() && GetRightIndent() == attr.GetRightIndent() && @@ -7499,6 +7654,12 @@ wxTextAttrEx wxTextAttrEx::CombineEx(const wxTextAttrEx& attr, if (attr.HasURL()) newAttr.SetURL(attr.GetURL()); + if (attr.HasTextEffects()) + { + newAttr.SetTextEffects(attr.GetTextEffects()); + newAttr.SetTextEffectFlags(attr.GetTextEffectFlags()); + } + return newAttr; } @@ -7571,12 +7732,12 @@ bool wxRichTextPlainTextHandler::DoLoadFile(wxRichTextBuffer *buffer, wxInputStr } } + buffer->ResetAndClearCommands(); buffer->Clear(); buffer->AddParagraphs(str); buffer->UpdateRanges(); return true; - } bool wxRichTextPlainTextHandler::DoSaveFile(wxRichTextBuffer *buffer, wxOutputStream& stream) diff --git a/src/richtext/richtextctrl.cpp b/src/richtext/richtextctrl.cpp index 636c494..f894b85 100644 --- a/src/richtext/richtextctrl.cpp +++ b/src/richtext/richtextctrl.cpp @@ -137,6 +137,7 @@ bool wxRichTextCtrl::Create( wxWindow* parent, wxWindowID id, const wxString& va if (style & wxTE_READONLY) SetEditable(false); + // The base attributes must all have default values wxTextAttrEx attributes; attributes.SetFont(GetFont()); attributes.SetTextColour(*wxBLACK); @@ -145,6 +146,8 @@ bool wxRichTextCtrl::Create( wxWindow* parent, wxWindowID id, const wxString& va attributes.SetLineSpacing(10); attributes.SetParagraphSpacingAfter(10); attributes.SetParagraphSpacingBefore(0); + attributes.SetTextEffects(0); + attributes.SetTextEffectFlags(wxTEXT_ATTR_EFFECT_STRIKETHROUGH|wxTEXT_ATTR_EFFECT_CAPITALS); SetBasicStyle(attributes); diff --git a/src/richtext/richtextfontpage.cpp b/src/richtext/richtextfontpage.cpp index fc220dd..a445486 100644 --- a/src/richtext/richtextfontpage.cpp +++ b/src/richtext/richtextfontpage.cpp @@ -38,6 +38,10 @@ BEGIN_EVENT_TABLE( wxRichTextFontPage, wxPanel ) EVT_COMBOBOX( ID_RICHTEXTFONTPAGE_UNDERLINING_CTRL, wxRichTextFontPage::OnUnderliningCtrlSelected ) + EVT_CHECKBOX( ID_RICHTEXTFONTPAGE_STRIKETHROUGHCTRL, wxRichTextFontPage::OnStrikethroughctrlClick ) + + EVT_CHECKBOX( ID_RICHTEXTFONTPAGE_CAPSCTRL, wxRichTextFontPage::OnCapsctrlClick ) + ////@end wxRichTextFontPage event table entries END_EVENT_TABLE() @@ -75,6 +79,8 @@ void wxRichTextFontPage::Init() m_weightCtrl = NULL; m_underliningCtrl = NULL; m_colourCtrl = NULL; + m_strikethroughCtrl = NULL; + m_capitalsCtrl = NULL; m_previewCtrl = NULL; ////@end wxRichTextFontPage member initialisation } @@ -122,7 +128,7 @@ void wxRichTextFontPage::CreateControls() wxStaticText* itemStaticText6 = new wxStaticText( itemPanel1, wxID_STATIC, _("&Font:"), wxDefaultPosition, wxDefaultSize, 0 ); itemBoxSizer5->Add(itemStaticText6, 0, wxALIGN_LEFT|wxLEFT|wxRIGHT|wxTOP|wxADJUST_MINSIZE, 5); - m_faceTextCtrl = new wxTextCtrl( itemPanel1, ID_RICHTEXTFONTPAGE_FACETEXTCTRL, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_faceTextCtrl = new wxTextCtrl( itemPanel1, ID_RICHTEXTFONTPAGE_FACETEXTCTRL, _T(""), wxDefaultPosition, wxDefaultSize, 0 ); m_faceTextCtrl->SetHelpText(_("Type a font name.")); if (ShowToolTips()) m_faceTextCtrl->SetToolTip(_("Type a font name.")); @@ -140,7 +146,7 @@ void wxRichTextFontPage::CreateControls() wxStaticText* itemStaticText10 = new wxStaticText( itemPanel1, wxID_STATIC, _("&Size:"), wxDefaultPosition, wxDefaultSize, 0 ); itemBoxSizer9->Add(itemStaticText10, 0, wxALIGN_LEFT|wxLEFT|wxRIGHT|wxTOP|wxADJUST_MINSIZE, 5); - m_sizeTextCtrl = new wxTextCtrl( itemPanel1, ID_RICHTEXTFONTPAGE_SIZETEXTCTRL, wxEmptyString, wxDefaultPosition, wxSize(50, -1), 0 ); + m_sizeTextCtrl = new wxTextCtrl( itemPanel1, ID_RICHTEXTFONTPAGE_SIZETEXTCTRL, _T(""), wxDefaultPosition, wxSize(50, -1), 0 ); m_sizeTextCtrl->SetHelpText(_("Type a size in points.")); if (ShowToolTips()) m_sizeTextCtrl->SetToolTip(_("Type a size in points.")); @@ -163,7 +169,7 @@ void wxRichTextFontPage::CreateControls() itemBoxSizer14->Add(itemStaticText15, 0, wxALIGN_LEFT|wxLEFT|wxRIGHT|wxTOP|wxADJUST_MINSIZE, 5); wxString* m_styleCtrlStrings = NULL; - m_styleCtrl = new wxComboBox( itemPanel1, ID_RICHTEXTFONTPAGE_STYLECTRL, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, m_styleCtrlStrings, wxCB_READONLY ); + m_styleCtrl = new wxComboBox( itemPanel1, ID_RICHTEXTFONTPAGE_STYLECTRL, _T(""), wxDefaultPosition, wxDefaultSize, 0, m_styleCtrlStrings, wxCB_READONLY ); m_styleCtrl->SetHelpText(_("Select regular or italic style.")); if (ShowToolTips()) m_styleCtrl->SetToolTip(_("Select regular or italic style.")); @@ -176,7 +182,7 @@ void wxRichTextFontPage::CreateControls() itemBoxSizer17->Add(itemStaticText18, 0, wxALIGN_LEFT|wxLEFT|wxRIGHT|wxTOP|wxADJUST_MINSIZE, 5); wxString* m_weightCtrlStrings = NULL; - m_weightCtrl = new wxComboBox( itemPanel1, ID_RICHTEXTFONTPAGE_WEIGHTCTRL, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, m_weightCtrlStrings, wxCB_READONLY ); + m_weightCtrl = new wxComboBox( itemPanel1, ID_RICHTEXTFONTPAGE_WEIGHTCTRL, _T(""), wxDefaultPosition, wxDefaultSize, 0, m_weightCtrlStrings, wxCB_READONLY ); m_weightCtrl->SetHelpText(_("Select regular or bold.")); if (ShowToolTips()) m_weightCtrl->SetToolTip(_("Select regular or bold.")); @@ -189,7 +195,7 @@ void wxRichTextFontPage::CreateControls() itemBoxSizer20->Add(itemStaticText21, 0, wxALIGN_LEFT|wxLEFT|wxRIGHT|wxTOP|wxADJUST_MINSIZE, 5); wxString* m_underliningCtrlStrings = NULL; - m_underliningCtrl = new wxComboBox( itemPanel1, ID_RICHTEXTFONTPAGE_UNDERLINING_CTRL, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, m_underliningCtrlStrings, wxCB_READONLY ); + m_underliningCtrl = new wxComboBox( itemPanel1, ID_RICHTEXTFONTPAGE_UNDERLINING_CTRL, _T(""), wxDefaultPosition, wxDefaultSize, 0, m_underliningCtrlStrings, wxCB_READONLY ); m_underliningCtrl->SetHelpText(_("Select underlining or no underlining.")); if (ShowToolTips()) m_underliningCtrl->SetToolTip(_("Select underlining or no underlining.")); @@ -207,6 +213,23 @@ void wxRichTextFontPage::CreateControls() m_colourCtrl->SetToolTip(_("Click to change the text colour.")); itemBoxSizer23->Add(m_colourCtrl, 0, wxALIGN_LEFT|wxALL, 5); + wxBoxSizer* itemBoxSizer26 = new wxBoxSizer(wxHORIZONTAL); + itemBoxSizer3->Add(itemBoxSizer26, 0, wxGROW, 5); + + m_strikethroughCtrl = new wxCheckBox( itemPanel1, ID_RICHTEXTFONTPAGE_STRIKETHROUGHCTRL, _("&Strikethrough"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE ); + m_strikethroughCtrl->SetValue(false); + m_strikethroughCtrl->SetHelpText(_("Check to show a line through the text.")); + if (ShowToolTips()) + m_strikethroughCtrl->SetToolTip(_("Check to show a line through the text.")); + itemBoxSizer26->Add(m_strikethroughCtrl, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + m_capitalsCtrl = new wxCheckBox( itemPanel1, ID_RICHTEXTFONTPAGE_CAPSCTRL, _("Ca&pitals"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE ); + m_capitalsCtrl->SetValue(false); + m_capitalsCtrl->SetHelpText(_("Check to show the text in capitals.")); + if (ShowToolTips()) + m_capitalsCtrl->SetToolTip(_("Check to show the text in capitals.")); + itemBoxSizer26->Add(m_capitalsCtrl, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + itemBoxSizer3->Add(5, 5, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5); m_previewCtrl = new wxRichTextFontPreviewCtrl( itemPanel1, ID_RICHTEXTFONTPAGE_PREVIEWCTRL, wxDefaultPosition, wxSize(100, 80), wxSIMPLE_BORDER ); @@ -329,6 +352,26 @@ bool wxRichTextFontPage::TransferDataFromWindow() } else attr->SetFlags(attr->GetFlags() & (~ wxTEXT_ATTR_TEXT_COLOUR)); + + if (m_strikethroughCtrl->Get3StateValue() != wxCHK_UNDETERMINED) + { + attr->SetTextEffectFlags(attr->GetTextEffectFlags() | wxTEXT_ATTR_EFFECT_STRIKETHROUGH); + + if (m_strikethroughCtrl->Get3StateValue() == wxCHK_CHECKED) + attr->SetTextEffects(attr->GetTextEffects() | wxTEXT_ATTR_EFFECT_STRIKETHROUGH); + else + attr->SetTextEffects(attr->GetTextEffects() & ~wxTEXT_ATTR_EFFECT_STRIKETHROUGH); + } + + if (m_capitalsCtrl->Get3StateValue() != wxCHK_UNDETERMINED) + { + attr->SetTextEffectFlags(attr->GetTextEffectFlags() | wxTEXT_ATTR_EFFECT_CAPITALS); + + if (m_capitalsCtrl->Get3StateValue() == wxCHK_CHECKED) + attr->SetTextEffects(attr->GetTextEffects() | wxTEXT_ATTR_EFFECT_CAPITALS); + else + attr->SetTextEffects(attr->GetTextEffects() & ~wxTEXT_ATTR_EFFECT_CAPITALS); + } return true; } @@ -406,6 +449,34 @@ bool wxRichTextFontPage::TransferDataToWindow() m_colourPresent = true; } + if (attr->HasTextEffects()) + { + if (attr->GetTextEffectFlags() & wxTEXT_ATTR_EFFECT_STRIKETHROUGH) + { + if (attr->GetTextEffects() & wxTEXT_ATTR_EFFECT_STRIKETHROUGH) + m_strikethroughCtrl->Set3StateValue(wxCHK_CHECKED); + else + m_strikethroughCtrl->Set3StateValue(wxCHK_UNCHECKED); + } + else + m_strikethroughCtrl->Set3StateValue(wxCHK_UNDETERMINED); + + if (attr->GetTextEffectFlags() & wxTEXT_ATTR_EFFECT_CAPITALS) + { + if (attr->GetTextEffects() & wxTEXT_ATTR_EFFECT_CAPITALS) + m_capitalsCtrl->Set3StateValue(wxCHK_CHECKED); + else + m_capitalsCtrl->Set3StateValue(wxCHK_UNCHECKED); + } + else + m_capitalsCtrl->Set3StateValue(wxCHK_UNDETERMINED); + } + else + { + m_strikethroughCtrl->Set3StateValue(wxCHK_UNDETERMINED); + m_capitalsCtrl->Set3StateValue(wxCHK_UNDETERMINED); + } + UpdatePreview(); m_dontUpdate = false; @@ -472,8 +543,21 @@ void wxRichTextFontPage::UpdatePreview() font.SetUnderlined(underlined); } + + int textEffects = 0; + + if (m_strikethroughCtrl->Get3StateValue() == wxCHK_CHECKED) + { + textEffects |= wxTEXT_ATTR_EFFECT_STRIKETHROUGH; + } + + if (m_capitalsCtrl->Get3StateValue() == wxCHK_CHECKED) + { + textEffects |= wxTEXT_ATTR_EFFECT_CAPITALS; + } m_previewCtrl->SetFont(font); + m_previewCtrl->SetTextEffects(textEffects); m_previewCtrl->Refresh(); } @@ -628,3 +712,22 @@ void wxRichTextFontPage::OnColourClicked( wxCommandEvent& WXUNUSED(event) ) UpdatePreview(); } +/*! + * wxEVT_COMMAND_CHECKBOX_CLICKED event handler for ID_RICHTEXTFONTPAGE_STRIKETHROUGHCTRL + */ + +void wxRichTextFontPage::OnStrikethroughctrlClick( wxCommandEvent& WXUNUSED(event) ) +{ + UpdatePreview(); +} + +/*! + * wxEVT_COMMAND_CHECKBOX_CLICKED event handler for ID_RICHTEXTFONTPAGE_CAPSCTRL + */ + +void wxRichTextFontPage::OnCapsctrlClick( wxCommandEvent& WXUNUSED(event) ) +{ + UpdatePreview(); +} + + diff --git a/src/richtext/richtextformatdlg.cpp b/src/richtext/richtextformatdlg.cpp index 7c21d4c..018bbb7 100644 --- a/src/richtext/richtextformatdlg.cpp +++ b/src/richtext/richtextformatdlg.cpp @@ -408,6 +408,8 @@ void wxRichTextFontPreviewCtrl::OnPaint(wxPaintEvent& WXUNUSED(event)) long w = 0, h = 0; wxString text(_("ABCDEFGabcdefg12345")); + if (GetTextEffects() & wxTEXT_ATTR_EFFECT_CAPITALS) + text.MakeUpper(); dc.GetTextExtent( text, &w, &h); int cx = wxMax(2, (size.x/2) - (w/2)); @@ -416,6 +418,13 @@ void wxRichTextFontPreviewCtrl::OnPaint(wxPaintEvent& WXUNUSED(event)) dc.SetTextForeground(GetForegroundColour()); dc.SetClippingRegion(2, 2, size.x-4, size.y-4); dc.DrawText(text, cx, cy); + + if (GetTextEffects() & wxTEXT_ATTR_EFFECT_STRIKETHROUGH) + { + dc.SetPen(wxPen(GetForegroundColour(), 1)); + dc.DrawLine(cx, (int) (cy + h/2 + 0.5), cx + w, (int) (cy + h/2 + 0.5)); + } + dc.DestroyClippingRegion(); } } diff --git a/src/richtext/richtexthtml.cpp b/src/richtext/richtexthtml.cpp index c1722d2..965bbd4 100644 --- a/src/richtext/richtexthtml.cpp +++ b/src/richtext/richtexthtml.cpp @@ -100,8 +100,13 @@ bool wxRichTextHTMLHandler::DoSaveFile(wxRichTextBuffer *buffer, wxOutputStream& { wxTextAttrEx charStyle(para->GetCombinedAttributes(obj->GetAttributes())); BeginCharacterFormatting(currentCharStyle, charStyle, paraStyle, stream); + + wxString text = textObj->GetText(); - str << textObj->GetText(); + if (charStyle.HasTextEffects() && (charStyle.GetTextEffects() & wxTEXT_ATTR_EFFECT_CAPITALS)) + text.MakeUpper(); + + str << text; EndCharacterFormatting(currentCharStyle, charStyle, paraStyle, stream); } @@ -321,6 +326,12 @@ void wxRichTextHTMLHandler::OutputParagraphFormatting(const wxTextAttrEx& WXUNUS wxString align = GetAlignment(thisStyle); str << wxString::Format(wxT("

"), align.c_str()); } + + if (thisStyle.HasPageBreak()) + { + wxTextOutputStream str(stream); + str << wxT("

\n"); + } } void wxRichTextHTMLHandler::NavigateToListPosition(const wxTextAttrEx& thisStyle, wxTextOutputStream& str) diff --git a/src/richtext/richtextstyles.cpp b/src/richtext/richtextstyles.cpp index 804f280..7ecf846 100644 --- a/src/richtext/richtextstyles.cpp +++ b/src/richtext/richtextstyles.cpp @@ -45,6 +45,7 @@ void wxRichTextStyleDefinition::Copy(const wxRichTextStyleDefinition& def) m_name = def.m_name; m_baseStyle = def.m_baseStyle; m_style = def.m_style; + m_description = def.m_description; } bool wxRichTextStyleDefinition::Eq(const wxRichTextStyleDefinition& def) const @@ -376,6 +377,9 @@ void wxRichTextStyleSheet::Copy(const wxRichTextStyleSheet& sheet) wxRichTextListStyleDefinition* def = (wxRichTextListStyleDefinition*) node->GetData(); AddListStyle(new wxRichTextListStyleDefinition(*def)); } + + SetName(sheet.GetName()); + SetDescription(sheet.GetDescription()); } /// Equality diff --git a/src/richtext/richtextxml.cpp b/src/richtext/richtextxml.cpp index 82170da..2a9ac74 100644 --- a/src/richtext/richtextxml.cpp +++ b/src/richtext/richtextxml.cpp @@ -42,6 +42,7 @@ bool wxRichTextXMLHandler::DoLoadFile(wxRichTextBuffer *buffer, wxInputStream& s return false; buffer->ResetAndClearCommands(); + buffer->Clear(); wxXmlDocument* xmlDoc = new wxXmlDocument; bool success = true; @@ -55,6 +56,7 @@ bool wxRichTextXMLHandler::DoLoadFile(wxRichTextBuffer *buffer, wxInputStream& s if (!xmlDoc->Load(stream, encoding)) { + buffer->ResetAndClearCommands(); success = false; } else @@ -215,6 +217,10 @@ bool wxRichTextXMLHandler::ImportXML(wxRichTextBuffer* buffer, wxXmlNode* node) if (GetFlags() & wxRICHTEXT_HANDLER_INCLUDE_STYLESHEET) { wxRichTextStyleSheet* sheet = new wxRichTextStyleSheet; + wxString sheetName = node->GetPropVal(wxT("name"), wxEmptyString); + wxString sheetDescription = node->GetPropVal(wxT("description"), wxEmptyString); + sheet->SetName(sheetName); + sheet->SetDescription(sheetDescription); wxXmlNode* child = node->GetChildren(); while (child) @@ -573,7 +579,12 @@ bool wxRichTextXMLHandler::DoSaveFile(wxRichTextBuffer *buffer, wxOutputStream& if (buffer->GetStyleSheet() && (GetFlags() & wxRICHTEXT_HANDLER_INCLUDE_STYLESHEET)) { OutputIndentation(stream, level); - OutputString(stream, wxT(""), convMem, convFile); + wxString nameAndDescr; + if (!buffer->GetStyleSheet()->GetName().IsEmpty()) + nameAndDescr << wxT(" name=\"") << buffer->GetStyleSheet()->GetName() << wxT("\""); + if (!buffer->GetStyleSheet()->GetDescription().IsEmpty()) + nameAndDescr << wxT(" description=\"") << buffer->GetStyleSheet()->GetDescription() << wxT("\""); + OutputString(stream, wxString(wxT(""), convMem, convFile); int i; @@ -773,10 +784,15 @@ bool wxRichTextXMLHandler::ExportStyleDefinition(wxOutputStream& stream, wxMBCon if (!baseStyle.IsEmpty()) baseStyleProp = wxT(" basestyle=\"") + baseStyle + wxT("\""); + wxString descr = def->GetDescription(); + wxString descrProp; + if (!descr.IsEmpty()) + descrProp = wxT(" description=\"") + descr + wxT("\""); + if (charDef) { OutputIndentation(stream, level); - OutputString(stream, wxT(""), convMem, convFile); + OutputString(stream, wxT(""), convMem, convFile); level ++; @@ -800,7 +816,7 @@ bool wxRichTextXMLHandler::ExportStyleDefinition(wxOutputStream& stream, wxMBCon if (!listDef->GetNextStyle().IsEmpty()) baseStyleProp << wxT(" basestyle=\"") << listDef->GetNextStyle() << wxT("\""); - OutputString(stream, wxT(""), convMem, convFile); + OutputString(stream, wxT(""), convMem, convFile); level ++; @@ -841,7 +857,7 @@ bool wxRichTextXMLHandler::ExportStyleDefinition(wxOutputStream& stream, wxMBCon if (!listDef->GetNextStyle().IsEmpty()) baseStyleProp << wxT(" basestyle=\"") << listDef->GetNextStyle() << wxT("\""); - OutputString(stream, wxT(""), convMem, convFile); + OutputString(stream, wxT(""), convMem, convFile); level ++; @@ -896,6 +912,13 @@ wxString wxRichTextXMLHandler::CreateStyle(const wxTextAttrEx& attr, bool isPara str << wxT(" fontface=\"") << attr.GetFont().GetFaceName() << wxT("\""); } + if (attr.HasTextEffects()) + { + str << wxT(" texteffects=\""); + str << attr.GetTextEffects(); + str << wxT("\""); + } + if (!attr.GetCharacterStyleName().empty()) str << wxT(" characterstyle=\"") << wxString(attr.GetCharacterStyleName()) << wxT("\""); @@ -964,6 +987,11 @@ wxString wxRichTextXMLHandler::CreateStyle(const wxTextAttrEx& attr, bool isPara } str << wxT("\""); } + + if (attr.HasPageBreak()) + { + str << wxT(" pagebreak=\"1\""); + } } return str; @@ -1048,6 +1076,12 @@ bool wxRichTextXMLHandler::GetStyle(wxTextAttrEx& attr, wxXmlNode* node, bool is if (!value.empty()) attr.SetCharacterStyleName(value); + value = node->GetPropVal(wxT("texteffects"), wxEmptyString); + if (!value.IsEmpty()) + { + attr.SetTextEffects(wxAtoi(value)); + } + // Set paragraph attributes if (isPara) { @@ -1145,6 +1179,12 @@ bool wxRichTextXMLHandler::GetStyle(wxTextAttrEx& attr, wxXmlNode* node, bool is } attr.SetTabs(tabs); } + + value = node->GetPropVal(wxT("pagebreak"), wxEmptyString); + if (!value.IsEmpty()) + { + attr.SetPageBreak(wxAtoi(value) != 0); + } } return true; -- 2.7.4