Added support for sub-object virtual attributes (temporary attributes for characters within objects)
and also virtual text that can replace the actual text. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@73454 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -125,6 +125,7 @@ enum wxRichTextFileType
|
|||||||
class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextCtrl;
|
class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextCtrl;
|
||||||
class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextObject;
|
class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextObject;
|
||||||
class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextImage;
|
class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextImage;
|
||||||
|
class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextPlainText;
|
||||||
class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextCacheObject;
|
class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextCacheObject;
|
||||||
class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextObjectList;
|
class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextObjectList;
|
||||||
class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextLine;
|
class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextLine;
|
||||||
@@ -1543,9 +1544,16 @@ public:
|
|||||||
*/
|
*/
|
||||||
void SetTextBoxAttr(const wxTextBoxAttr& attr) { m_textBoxAttr = attr; }
|
void SetTextBoxAttr(const wxTextBoxAttr& attr) { m_textBoxAttr = attr; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns @true if no attributes are set.
|
||||||
|
*/
|
||||||
|
bool IsDefault() const { return (GetFlags() == 0) && m_textBoxAttr.IsDefault(); }
|
||||||
|
|
||||||
wxTextBoxAttr m_textBoxAttr;
|
wxTextBoxAttr m_textBoxAttr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
WX_DECLARE_USER_EXPORTED_OBJARRAY(wxRichTextAttr, wxRichTextAttrArray, WXDLLIMPEXP_RICHTEXT);
|
||||||
|
|
||||||
WX_DECLARE_USER_EXPORTED_OBJARRAY(wxVariant, wxRichTextVariantArray, WXDLLIMPEXP_RICHTEXT);
|
WX_DECLARE_USER_EXPORTED_OBJARRAY(wxVariant, wxRichTextVariantArray, WXDLLIMPEXP_RICHTEXT);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2106,9 +2114,9 @@ public:
|
|||||||
Pass the buffer to the context so the context can retrieve information
|
Pass the buffer to the context so the context can retrieve information
|
||||||
such as virtual attributes.
|
such as virtual attributes.
|
||||||
*/
|
*/
|
||||||
wxRichTextDrawingContext(wxRichTextBuffer* buffer) { Init(); m_buffer = buffer; }
|
wxRichTextDrawingContext(wxRichTextBuffer* buffer);
|
||||||
|
|
||||||
void Init() { m_buffer = NULL; }
|
void Init() { m_buffer = NULL; m_enableVirtualAttributes = true; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Does this object have virtual attributes?
|
Does this object have virtual attributes?
|
||||||
@@ -2129,7 +2137,45 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool ApplyVirtualAttributes(wxRichTextAttr& attr, wxRichTextObject* obj) const;
|
bool ApplyVirtualAttributes(wxRichTextAttr& attr, wxRichTextObject* obj) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Gets the count for mixed virtual attributes for individual positions within the object.
|
||||||
|
For example, individual characters within a text object may require special highlighting.
|
||||||
|
*/
|
||||||
|
int GetVirtualSubobjectAttributesCount(wxRichTextObject* obj) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Gets the mixed virtual attributes for individual positions within the object.
|
||||||
|
For example, individual characters within a text object may require special highlighting.
|
||||||
|
The function is passed the count returned by GetVirtualSubobjectAttributesCount.
|
||||||
|
*/
|
||||||
|
int GetVirtualSubobjectAttributes(wxRichTextObject* obj, wxArrayInt& positions, wxRichTextAttrArray& attributes) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Do we have virtual text for this object? Virtual text allows an application
|
||||||
|
to replace characters in an object for editing and display purposes, for example
|
||||||
|
for highlighting special characters.
|
||||||
|
*/
|
||||||
|
bool HasVirtualText(const wxRichTextPlainText* obj) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Gets the virtual text for this object.
|
||||||
|
*/
|
||||||
|
bool GetVirtualText(const wxRichTextPlainText* obj, wxString& text) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Enables virtual attribute processing.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void EnableVirtualAttributes(bool b) { m_enableVirtualAttributes = b; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns @true if virtual attribute processing is enabled.
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool GetVirtualAttributesEnabled() const { return m_enableVirtualAttributes; }
|
||||||
|
|
||||||
wxRichTextBuffer* m_buffer;
|
wxRichTextBuffer* m_buffer;
|
||||||
|
bool m_enableVirtualAttributes;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2252,13 +2298,26 @@ public:
|
|||||||
/**
|
/**
|
||||||
Returns @true if this object can merge itself with the given one.
|
Returns @true if this object can merge itself with the given one.
|
||||||
*/
|
*/
|
||||||
virtual bool CanMerge(wxRichTextObject* WXUNUSED(object)) const { return false; }
|
virtual bool CanMerge(wxRichTextObject* WXUNUSED(object), wxRichTextDrawingContext& WXUNUSED(context)) const { return false; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns @true if this object merged itself with the given one.
|
Returns @true if this object merged itself with the given one.
|
||||||
The calling code will then delete the given object.
|
The calling code will then delete the given object.
|
||||||
*/
|
*/
|
||||||
virtual bool Merge(wxRichTextObject* WXUNUSED(object)) { return false; }
|
virtual bool Merge(wxRichTextObject* WXUNUSED(object), wxRichTextDrawingContext& WXUNUSED(context)) { return false; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
JACS
|
||||||
|
Returns @true if this object can potentially be split, by virtue of having
|
||||||
|
different virtual attributes for individual sub-objects.
|
||||||
|
*/
|
||||||
|
virtual bool CanSplit(wxRichTextDrawingContext& WXUNUSED(context)) const { return false; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns the final object in the split objects if this object was split due to differences between sub-object virtual attributes.
|
||||||
|
Returns itself if it was not split.
|
||||||
|
*/
|
||||||
|
virtual wxRichTextObject* Split(wxRichTextDrawingContext& WXUNUSED(context)) { return this; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Dump object data to the given output stream for debugging.
|
Dump object data to the given output stream for debugging.
|
||||||
@@ -2811,7 +2870,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
Recursively merges all pieces that can be merged.
|
Recursively merges all pieces that can be merged.
|
||||||
*/
|
*/
|
||||||
bool Defragment(const wxRichTextRange& range = wxRICHTEXT_ALL);
|
bool Defragment(wxRichTextDrawingContext& context, const wxRichTextRange& range = wxRICHTEXT_ALL);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Moves the object recursively, by adding the offset from old to new.
|
Moves the object recursively, by adding the offset from old to new.
|
||||||
@@ -4295,12 +4354,16 @@ public:
|
|||||||
|
|
||||||
virtual bool IsEmpty() const { return m_text.empty(); }
|
virtual bool IsEmpty() const { return m_text.empty(); }
|
||||||
|
|
||||||
virtual bool CanMerge(wxRichTextObject* object) const;
|
virtual bool CanMerge(wxRichTextObject* object, wxRichTextDrawingContext& context) const;
|
||||||
|
|
||||||
virtual bool Merge(wxRichTextObject* object);
|
virtual bool Merge(wxRichTextObject* object, wxRichTextDrawingContext& context);
|
||||||
|
|
||||||
virtual void Dump(wxTextOutputStream& stream);
|
virtual void Dump(wxTextOutputStream& stream);
|
||||||
|
|
||||||
|
virtual bool CanSplit(wxRichTextDrawingContext& context) const;
|
||||||
|
|
||||||
|
virtual wxRichTextObject* Split(wxRichTextDrawingContext& context);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Get the first position from pos that has a line break character.
|
Get the first position from pos that has a line break character.
|
||||||
*/
|
*/
|
||||||
@@ -6254,6 +6317,31 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual bool GetVirtualAttributes(wxRichTextAttr& attr, wxRichTextObject* obj) const = 0;
|
virtual bool GetVirtualAttributes(wxRichTextAttr& attr, wxRichTextObject* obj) const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Gets the count for mixed virtual attributes for individual positions within the object.
|
||||||
|
For example, individual characters within a text object may require special highlighting.
|
||||||
|
*/
|
||||||
|
virtual int GetVirtualSubobjectAttributesCount(wxRichTextObject* obj) const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Gets the mixed virtual attributes for individual positions within the object.
|
||||||
|
For example, individual characters within a text object may require special highlighting.
|
||||||
|
Returns the number of virtual attributes found.
|
||||||
|
*/
|
||||||
|
virtual int GetVirtualSubobjectAttributes(wxRichTextObject* obj, wxArrayInt& positions, wxRichTextAttrArray& attributes) const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Do we have virtual text for this object? Virtual text allows an application
|
||||||
|
to replace characters in an object for editing and display purposes, for example
|
||||||
|
for highlighting special characters.
|
||||||
|
*/
|
||||||
|
virtual bool HasVirtualText(const wxRichTextPlainText* obj) const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Gets the virtual text for this object.
|
||||||
|
*/
|
||||||
|
virtual bool GetVirtualText(const wxRichTextPlainText* obj, wxString& text) const = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Sets the name of the handler.
|
Sets the name of the handler.
|
||||||
*/
|
*/
|
||||||
|
@@ -1760,6 +1760,18 @@ public:
|
|||||||
*/
|
*/
|
||||||
wxRect GetScaledRect(const wxRect& rect) const;
|
wxRect GetScaledRect(const wxRect& rect) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns @true if this control can use virtual attributes and virtual text.
|
||||||
|
The default is @false.
|
||||||
|
*/
|
||||||
|
bool GetVirtualAttributesEnabled() const { return m_useVirtualAttributes; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
Pass @true to let the control use virtual attributes.
|
||||||
|
The default is @false.
|
||||||
|
*/
|
||||||
|
void EnableVirtualAttributes(bool b) { m_useVirtualAttributes = b; }
|
||||||
|
|
||||||
// Command handlers
|
// Command handlers
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2254,6 +2266,9 @@ protected:
|
|||||||
/// Are we editable?
|
/// Are we editable?
|
||||||
bool m_editable;
|
bool m_editable;
|
||||||
|
|
||||||
|
/// Can we use virtual attributes and virtual text?
|
||||||
|
bool m_useVirtualAttributes;
|
||||||
|
|
||||||
/// Is the vertical scrollbar enabled?
|
/// Is the vertical scrollbar enabled?
|
||||||
bool m_verticalScrollbarEnabled;
|
bool m_verticalScrollbarEnabled;
|
||||||
|
|
||||||
|
@@ -1424,9 +1424,16 @@ public:
|
|||||||
*/
|
*/
|
||||||
void SetTextBoxAttr(const wxTextBoxAttr& attr) { m_textBoxAttr = attr; }
|
void SetTextBoxAttr(const wxTextBoxAttr& attr) { m_textBoxAttr = attr; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns @true if no attributes are set.
|
||||||
|
*/
|
||||||
|
bool IsDefault() const { return (GetFlags() == 0) && m_textBoxAttr.IsDefault(); }
|
||||||
|
|
||||||
wxTextBoxAttr m_textBoxAttr;
|
wxTextBoxAttr m_textBoxAttr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
WX_DECLARE_USER_EXPORTED_OBJARRAY(wxRichTextAttr, wxRichTextAttrArray, WXDLLIMPEXP_RICHTEXT);
|
||||||
|
|
||||||
WX_DECLARE_USER_EXPORTED_OBJARRAY(wxVariant, wxRichTextVariantArray, WXDLLIMPEXP_RICHTEXT);
|
WX_DECLARE_USER_EXPORTED_OBJARRAY(wxVariant, wxRichTextVariantArray, WXDLLIMPEXP_RICHTEXT);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2010,6 +2017,43 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool ApplyVirtualAttributes(wxRichTextAttr& attr, wxRichTextObject* obj) const;
|
bool ApplyVirtualAttributes(wxRichTextAttr& attr, wxRichTextObject* obj) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Gets the count for mixed virtual attributes for individual positions within the object.
|
||||||
|
For example, individual characters within a text object may require special highlighting.
|
||||||
|
*/
|
||||||
|
int GetVirtualSubobjectAttributesCount(wxRichTextObject* obj) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Gets the mixed virtual attributes for individual positions within the object.
|
||||||
|
For example, individual characters within a text object may require special highlighting.
|
||||||
|
The function is passed the count returned by GetVirtualSubobjectAttributesCount.
|
||||||
|
*/
|
||||||
|
int GetVirtualSubobjectAttributes(wxRichTextObject* obj, wxArrayInt& positions, wxRichTextAttrArray& attributes) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Do we have virtual text for this object? Virtual text allows an application
|
||||||
|
to replace characters in an object for editing and display purposes, for example
|
||||||
|
for highlighting special characters.
|
||||||
|
*/
|
||||||
|
bool HasVirtualText(const wxRichTextPlainText* obj) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Gets the virtual text for this object.
|
||||||
|
*/
|
||||||
|
bool GetVirtualText(const wxRichTextPlainText* obj, wxString& text) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Enables virtual attribute processing.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void EnableVirtualAttributes(bool b);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns @true if virtual attribute processing is enabled.
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool GetVirtualAttributesEnabled() const;
|
||||||
|
|
||||||
wxRichTextBuffer* m_buffer;
|
wxRichTextBuffer* m_buffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -2129,13 +2173,25 @@ public:
|
|||||||
/**
|
/**
|
||||||
Returns @true if this object can merge itself with the given one.
|
Returns @true if this object can merge itself with the given one.
|
||||||
*/
|
*/
|
||||||
virtual bool CanMerge(wxRichTextObject* WXUNUSED(object)) const { return false; }
|
virtual bool CanMerge(wxRichTextObject* object, wxRichTextDrawingContext& context) const { return false; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns @true if this object merged itself with the given one.
|
Returns @true if this object merged itself with the given one.
|
||||||
The calling code will then delete the given object.
|
The calling code will then delete the given object.
|
||||||
*/
|
*/
|
||||||
virtual bool Merge(wxRichTextObject* WXUNUSED(object)) { return false; }
|
virtual bool Merge(wxRichTextObject* object, wxRichTextDrawingContext& context) { return false; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns @true if this object can potentially be split, by virtue of having
|
||||||
|
different virtual attributes for individual sub-objects.
|
||||||
|
*/
|
||||||
|
virtual bool CanSplit(wxRichTextDrawingContext& context) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns the final object in the split objects if this object was split due to differences between sub-object virtual attributes.
|
||||||
|
Returns itself if it was not split.
|
||||||
|
*/
|
||||||
|
virtual wxRichTextObject* Split(wxRichTextDrawingContext& context);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Dump object data to the given output stream for debugging.
|
Dump object data to the given output stream for debugging.
|
||||||
@@ -2688,7 +2744,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
Recursively merges all pieces that can be merged.
|
Recursively merges all pieces that can be merged.
|
||||||
*/
|
*/
|
||||||
bool Defragment(const wxRichTextRange& range = wxRICHTEXT_ALL);
|
bool Defragment(wxRichTextDrawingContext& context, const wxRichTextRange& range = wxRICHTEXT_ALL);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Moves the object recursively, by adding the offset from old to new.
|
Moves the object recursively, by adding the offset from old to new.
|
||||||
@@ -4169,9 +4225,13 @@ public:
|
|||||||
|
|
||||||
virtual bool IsEmpty() const { return m_text.empty(); }
|
virtual bool IsEmpty() const { return m_text.empty(); }
|
||||||
|
|
||||||
virtual bool CanMerge(wxRichTextObject* object) const;
|
virtual bool CanMerge(wxRichTextObject* object, wxRichTextDrawingContext& context) const;
|
||||||
|
|
||||||
virtual bool Merge(wxRichTextObject* object);
|
virtual bool Merge(wxRichTextObject* object, wxRichTextDrawingContext& context);
|
||||||
|
|
||||||
|
virtual bool CanSplit(wxRichTextDrawingContext& context) const;
|
||||||
|
|
||||||
|
virtual wxRichTextObject* Split(wxRichTextDrawingContext& context);
|
||||||
|
|
||||||
virtual void Dump(wxTextOutputStream& stream);
|
virtual void Dump(wxTextOutputStream& stream);
|
||||||
|
|
||||||
@@ -6112,6 +6172,31 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual bool GetVirtualAttributes(wxRichTextAttr& attr, wxRichTextObject* obj) const = 0;
|
virtual bool GetVirtualAttributes(wxRichTextAttr& attr, wxRichTextObject* obj) const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Gets the count for mixed virtual attributes for individual positions within the object.
|
||||||
|
For example, individual characters within a text object may require special highlighting.
|
||||||
|
*/
|
||||||
|
virtual int GetVirtualSubobjectAttributesCount(wxRichTextObject* obj) const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Gets the mixed virtual attributes for individual positions within the object.
|
||||||
|
For example, individual characters within a text object may require special highlighting.
|
||||||
|
Returns the number of virtual attributes found.
|
||||||
|
*/
|
||||||
|
virtual int GetVirtualSubobjectAttributes(wxRichTextObject* obj, wxArrayInt& positions, wxRichTextAttrArray& attributes) const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Do we have virtual text for this object? Virtual text allows an application
|
||||||
|
to replace characters in an object for editing and display purposes, for example
|
||||||
|
for highlighting special characters.
|
||||||
|
*/
|
||||||
|
virtual bool HasVirtualText(const wxRichTextPlainText* obj) const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Gets the virtual text for this object.
|
||||||
|
*/
|
||||||
|
virtual bool GetVirtualText(const wxRichTextPlainText* obj, wxString& text) const = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Sets the name of the handler.
|
Sets the name of the handler.
|
||||||
*/
|
*/
|
||||||
|
@@ -1725,6 +1725,18 @@ public:
|
|||||||
*/
|
*/
|
||||||
wxRect GetScaledRect(const wxRect& rect) const;
|
wxRect GetScaledRect(const wxRect& rect) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns @true if this control can use virtual attributes and virtual text.
|
||||||
|
The default is @false.
|
||||||
|
*/
|
||||||
|
bool GetVirtualAttributesEnabled() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Pass @true to let the control use virtual attributes.
|
||||||
|
The default is @false.
|
||||||
|
*/
|
||||||
|
void EnableVirtualAttributes(bool b);
|
||||||
|
|
||||||
// Command handlers
|
// Command handlers
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -1181,7 +1181,8 @@ void MyFrame::WriteInitialText()
|
|||||||
cellAttr.GetTextBoxAttr().GetWidth().SetValue(200, wxTEXT_ATTR_UNITS_PIXELS);
|
cellAttr.GetTextBoxAttr().GetWidth().SetValue(200, wxTEXT_ATTR_UNITS_PIXELS);
|
||||||
cellAttr.GetTextBoxAttr().GetHeight().SetValue(150, wxTEXT_ATTR_UNITS_PIXELS);
|
cellAttr.GetTextBoxAttr().GetHeight().SetValue(150, wxTEXT_ATTR_UNITS_PIXELS);
|
||||||
|
|
||||||
wxRichTextTable* table = r.WriteTable(3, 2, attr, cellAttr);
|
//wxRichTextTable* table = r.WriteTable(3, 2, attr, cellAttr);
|
||||||
|
wxRichTextTable* table = r.WriteTable(24, 2, attr, cellAttr);
|
||||||
int i, j;
|
int i, j;
|
||||||
for (j = 0; j < table->GetRowCount(); j++)
|
for (j = 0; j < table->GetRowCount(); j++)
|
||||||
{
|
{
|
||||||
@@ -2080,6 +2081,31 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual bool GetVirtualAttributes(wxRichTextAttr& attr, wxRichTextObject* obj) const;
|
virtual bool GetVirtualAttributes(wxRichTextAttr& attr, wxRichTextObject* obj) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Gets the count for mixed virtual attributes for individual positions within the object.
|
||||||
|
For example, individual characters within a text object may require special highlighting.
|
||||||
|
*/
|
||||||
|
virtual int GetVirtualSubobjectAttributesCount(wxRichTextObject* WXUNUSED(obj)) const { return 0; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
Gets the mixed virtual attributes for individual positions within the object.
|
||||||
|
For example, individual characters within a text object may require special highlighting.
|
||||||
|
Returns the number of virtual attributes found.
|
||||||
|
*/
|
||||||
|
virtual int GetVirtualSubobjectAttributes(wxRichTextObject* WXUNUSED(obj), wxArrayInt& WXUNUSED(positions), wxRichTextAttrArray& WXUNUSED(attributes)) const { return 0; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
Do we have virtual text for this object? Virtual text allows an application
|
||||||
|
to replace characters in an object for editing and display purposes, for example
|
||||||
|
for highlighting special characters.
|
||||||
|
*/
|
||||||
|
virtual bool HasVirtualText(const wxRichTextPlainText* WXUNUSED(obj)) const { return false; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
Gets the virtual text for this object.
|
||||||
|
*/
|
||||||
|
virtual bool GetVirtualText(const wxRichTextPlainText* WXUNUSED(obj), wxString& WXUNUSED(text)) const { return false; }
|
||||||
|
|
||||||
wxColour m_lockBackgroundColour;
|
wxColour m_lockBackgroundColour;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -1400,7 +1400,7 @@ wxRichTextObject* wxRichTextCompositeObject::GetChildAtPosition(long pos) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Recursively merge all pieces that can be merged.
|
/// Recursively merge all pieces that can be merged.
|
||||||
bool wxRichTextCompositeObject::Defragment(const wxRichTextRange& range)
|
bool wxRichTextCompositeObject::Defragment(wxRichTextDrawingContext& context, const wxRichTextRange& range)
|
||||||
{
|
{
|
||||||
wxRichTextObjectList::compatibility_iterator node = m_children.GetFirst();
|
wxRichTextObjectList::compatibility_iterator node = m_children.GetFirst();
|
||||||
while (node)
|
while (node)
|
||||||
@@ -1410,24 +1410,85 @@ bool wxRichTextCompositeObject::Defragment(const wxRichTextRange& range)
|
|||||||
{
|
{
|
||||||
wxRichTextCompositeObject* composite = wxDynamicCast(child, wxRichTextCompositeObject);
|
wxRichTextCompositeObject* composite = wxDynamicCast(child, wxRichTextCompositeObject);
|
||||||
if (composite)
|
if (composite)
|
||||||
composite->Defragment();
|
composite->Defragment(context);
|
||||||
|
|
||||||
if (node->GetNext())
|
// Optimization: if there are no virtual attributes, we won't need to
|
||||||
|
// to split objects in order to paint individually attributed chunks.
|
||||||
|
// So only merge in this case.
|
||||||
|
if (!context.GetVirtualAttributesEnabled())
|
||||||
{
|
{
|
||||||
wxRichTextObject* nextChild = node->GetNext()->GetData();
|
if (node->GetNext())
|
||||||
if (child->CanMerge(nextChild) && child->Merge(nextChild))
|
|
||||||
{
|
{
|
||||||
nextChild->Dereference();
|
wxRichTextObject* nextChild = node->GetNext()->GetData();
|
||||||
m_children.Erase(node->GetNext());
|
if (child->CanMerge(nextChild, context) && child->Merge(nextChild, context))
|
||||||
|
{
|
||||||
// Don't set node -- we'll see if we can merge again with the next
|
nextChild->Dereference();
|
||||||
// child.
|
m_children.Erase(node->GetNext());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
node = node->GetNext();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
node = node->GetNext();
|
node = node->GetNext();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
node = node->GetNext();
|
{
|
||||||
|
// If we might have virtual attributes, we first see if we have to split
|
||||||
|
// objects so that they may be painted with potential virtual attributes,
|
||||||
|
// since text objects can only draw or measure with a single attributes object
|
||||||
|
// at a time.
|
||||||
|
wxRichTextObject* childAfterSplit = child;
|
||||||
|
if (child->CanSplit(context))
|
||||||
|
{
|
||||||
|
childAfterSplit = child->Split(context);
|
||||||
|
node = m_children.Find(childAfterSplit);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node->GetNext())
|
||||||
|
{
|
||||||
|
wxRichTextObject* nextChild = node->GetNext()->GetData();
|
||||||
|
wxRichTextObjectList::compatibility_iterator nextNode = node->GetNext();
|
||||||
|
|
||||||
|
// First split child and nextChild so we have smaller fragments to merge.
|
||||||
|
// Then Merge only has to test per-object virtual attributes
|
||||||
|
// because for an object with all the same sub-object attributes,
|
||||||
|
// then any general virtual attributes should be merged with sub-objects by
|
||||||
|
// the implementation.
|
||||||
|
|
||||||
|
wxRichTextObject* nextChildAfterSplit = nextChild;
|
||||||
|
|
||||||
|
if (nextChildAfterSplit->CanSplit(context))
|
||||||
|
nextChildAfterSplit = nextChild->Split(context);
|
||||||
|
|
||||||
|
bool splitNextChild = nextChild != nextChildAfterSplit;
|
||||||
|
|
||||||
|
// See if we can merge this new fragment with (perhaps the first part of) the next object.
|
||||||
|
// Note that we use nextChild because if we had split nextChild, the first object always
|
||||||
|
// remains (and further parts are appended). However we must use childAfterSplit since
|
||||||
|
// it's the last part of a possibly split child.
|
||||||
|
|
||||||
|
if (childAfterSplit->CanMerge(nextChild, context) && childAfterSplit->Merge(nextChild, context))
|
||||||
|
{
|
||||||
|
nextChild->Dereference();
|
||||||
|
m_children.Erase(node->GetNext());
|
||||||
|
|
||||||
|
// Don't set node -- we'll see if we can merge again with the next
|
||||||
|
// child. UNLESS we split this or the next child, in which case we know we have to
|
||||||
|
// move on to the end of the next child.
|
||||||
|
if (splitNextChild)
|
||||||
|
node = m_children.Find(nextChildAfterSplit);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (splitNextChild)
|
||||||
|
node = m_children.Find(nextChildAfterSplit); // start from the last object in the split
|
||||||
|
else
|
||||||
|
node = node->GetNext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
node = node->GetNext();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
node = node->GetNext();
|
node = node->GetNext();
|
||||||
@@ -3795,8 +3856,21 @@ wxRichTextRange wxRichTextParagraphLayoutBox::GetInvalidRange(bool wholeParagrap
|
|||||||
wxRichTextParagraph* para1 = GetParagraphAtPosition(range.GetStart());
|
wxRichTextParagraph* para1 = GetParagraphAtPosition(range.GetStart());
|
||||||
if (para1)
|
if (para1)
|
||||||
range.SetStart(para1->GetRange().GetStart());
|
range.SetStart(para1->GetRange().GetStart());
|
||||||
// floating layout make all child should be relayout
|
|
||||||
range.SetEnd(GetOwnRange().GetEnd());
|
// FIXME: be more intelligent about this. Check if we have floating objects
|
||||||
|
// before the end of the range. But it's not clear how we can in general
|
||||||
|
// tell where it's safe to stop laying out.
|
||||||
|
// Anyway, this code is central to efficiency when laying in floating mode.
|
||||||
|
if (!wxRichTextBuffer::GetFloatingLayoutMode())
|
||||||
|
{
|
||||||
|
wxRichTextParagraph* para2 = GetParagraphAtPosition(range.GetEnd());
|
||||||
|
if (para2)
|
||||||
|
range.SetEnd(para2->GetRange().GetEnd());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
// Floating layout means that all children should be laid out,
|
||||||
|
// because we can't tell how the whole buffer will be affected.
|
||||||
|
range.SetEnd(GetOwnRange().GetEnd());
|
||||||
}
|
}
|
||||||
return range;
|
return range;
|
||||||
}
|
}
|
||||||
@@ -6313,8 +6387,14 @@ bool wxRichTextPlainText::Draw(wxDC& dc, wxRichTextDrawingContext& context, cons
|
|||||||
|
|
||||||
int offset = GetRange().GetStart();
|
int offset = GetRange().GetStart();
|
||||||
|
|
||||||
// Replace line break characters with spaces
|
|
||||||
wxString str = m_text;
|
wxString str = m_text;
|
||||||
|
if (context.HasVirtualText(this))
|
||||||
|
{
|
||||||
|
if (!context.GetVirtualText(this, str) || str.Length() != m_text.Length())
|
||||||
|
str = m_text;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replace line break characters with spaces
|
||||||
wxString toRemove = wxRichTextLineBreakChar;
|
wxString toRemove = wxRichTextLineBreakChar;
|
||||||
str.Replace(toRemove, wxT(" "));
|
str.Replace(toRemove, wxT(" "));
|
||||||
if (textAttr.HasTextEffects() && (textAttr.GetTextEffects() & (wxTEXT_ATTR_EFFECT_CAPITALS|wxTEXT_ATTR_EFFECT_SMALL_CAPITALS)))
|
if (textAttr.HasTextEffects() && (textAttr.GetTextEffects() & (wxTEXT_ATTR_EFFECT_CAPITALS|wxTEXT_ATTR_EFFECT_SMALL_CAPITALS)))
|
||||||
@@ -6696,6 +6776,12 @@ bool wxRichTextPlainText::GetRangeSize(const wxRichTextRange& range, wxSize& siz
|
|||||||
long len = range.GetLength();
|
long len = range.GetLength();
|
||||||
|
|
||||||
wxString str(m_text);
|
wxString str(m_text);
|
||||||
|
if (context.HasVirtualText(this))
|
||||||
|
{
|
||||||
|
if (!context.GetVirtualText(this, str) || str.Length() != m_text.Length())
|
||||||
|
str = m_text;
|
||||||
|
}
|
||||||
|
|
||||||
wxString toReplace = wxRichTextLineBreakChar;
|
wxString toReplace = wxRichTextLineBreakChar;
|
||||||
str.Replace(toReplace, wxT(" "));
|
str.Replace(toReplace, wxT(" "));
|
||||||
|
|
||||||
@@ -6902,15 +6988,44 @@ wxString wxRichTextPlainText::GetTextForRange(const wxRichTextRange& range) cons
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if this object can merge itself with the given one.
|
/// Returns true if this object can merge itself with the given one.
|
||||||
bool wxRichTextPlainText::CanMerge(wxRichTextObject* object) const
|
bool wxRichTextPlainText::CanMerge(wxRichTextObject* object, wxRichTextDrawingContext& context) const
|
||||||
{
|
{
|
||||||
return object->GetClassInfo() == wxCLASSINFO(wxRichTextPlainText) &&
|
// JACS 2013-01-27
|
||||||
(m_text.empty() || (wxTextAttrEq(GetAttributes(), object->GetAttributes()) && m_properties == object->GetProperties()));
|
if (!context.GetVirtualAttributesEnabled())
|
||||||
|
{
|
||||||
|
return object->GetClassInfo() == wxCLASSINFO(wxRichTextPlainText) &&
|
||||||
|
(m_text.empty() || (wxTextAttrEq(GetAttributes(), object->GetAttributes()) && m_properties == object->GetProperties()));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wxRichTextPlainText* otherObj = wxDynamicCast(object, wxRichTextPlainText);
|
||||||
|
if (!otherObj || m_text.empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!wxTextAttrEq(GetAttributes(), object->GetAttributes()) || !(m_properties == object->GetProperties()))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Check if differing virtual attributes makes it impossible to merge
|
||||||
|
// these strings.
|
||||||
|
|
||||||
|
bool hasVirtualAttr1 = context.HasVirtualAttributes((wxRichTextObject*) this);
|
||||||
|
bool hasVirtualAttr2 = context.HasVirtualAttributes((wxRichTextObject*) object);
|
||||||
|
if (!hasVirtualAttr1 && !hasVirtualAttr2)
|
||||||
|
return true;
|
||||||
|
else if (hasVirtualAttr1 != hasVirtualAttr2)
|
||||||
|
return false;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wxRichTextAttr virtualAttr1 = context.GetVirtualAttributes((wxRichTextObject*) this);
|
||||||
|
wxRichTextAttr virtualAttr2 = context.GetVirtualAttributes((wxRichTextObject*) object);
|
||||||
|
return virtualAttr1 == virtualAttr2;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if this object merged itself with the given one.
|
/// Returns true if this object merged itself with the given one.
|
||||||
/// The calling code will then delete the given object.
|
/// The calling code will then delete the given object.
|
||||||
bool wxRichTextPlainText::Merge(wxRichTextObject* object)
|
bool wxRichTextPlainText::Merge(wxRichTextObject* object, wxRichTextDrawingContext& WXUNUSED(context))
|
||||||
{
|
{
|
||||||
wxRichTextPlainText* textObject = wxDynamicCast(object, wxRichTextPlainText);
|
wxRichTextPlainText* textObject = wxDynamicCast(object, wxRichTextPlainText);
|
||||||
wxASSERT( textObject != NULL );
|
wxASSERT( textObject != NULL );
|
||||||
@@ -6925,6 +7040,214 @@ bool wxRichTextPlainText::Merge(wxRichTextObject* object)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool wxRichTextPlainText::CanSplit(wxRichTextDrawingContext& context) const
|
||||||
|
{
|
||||||
|
// If this object has any virtual attributes at all, whether for the whole object
|
||||||
|
// or individual ones, we should try splitting it by calling Split.
|
||||||
|
// Must be more than one character in order to be able to split.
|
||||||
|
return m_text.Length() > 1 && context.HasVirtualAttributes((wxRichTextObject*) this);
|
||||||
|
}
|
||||||
|
|
||||||
|
wxRichTextObject* wxRichTextPlainText::Split(wxRichTextDrawingContext& context)
|
||||||
|
{
|
||||||
|
int count = context.GetVirtualSubobjectAttributesCount(this);
|
||||||
|
if (count > 0 && GetParent())
|
||||||
|
{
|
||||||
|
wxRichTextCompositeObject* parent = wxDynamicCast(GetParent(), wxRichTextCompositeObject);
|
||||||
|
wxRichTextObjectList::compatibility_iterator node = parent->GetChildren().Find(this);
|
||||||
|
if (node)
|
||||||
|
{
|
||||||
|
const wxRichTextAttr emptyAttr;
|
||||||
|
wxRichTextObjectList::compatibility_iterator next = node->GetNext();
|
||||||
|
|
||||||
|
wxArrayInt positions;
|
||||||
|
wxRichTextAttrArray attributes;
|
||||||
|
if (context.GetVirtualSubobjectAttributes(this, positions, attributes) && positions.GetCount() > 0)
|
||||||
|
{
|
||||||
|
wxASSERT(positions.GetCount() == attributes.GetCount());
|
||||||
|
|
||||||
|
// We will gather up runs of text with the same virtual attributes
|
||||||
|
|
||||||
|
int len = m_text.Length();
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
// runStart and runEnd represent the accumulated run with a consistent attribute
|
||||||
|
// that hasn't yet been appended
|
||||||
|
int runStart = -1;
|
||||||
|
int runEnd = -1;
|
||||||
|
wxRichTextAttr currentAttr;
|
||||||
|
wxString text = m_text;
|
||||||
|
wxRichTextPlainText* lastPlainText = this;
|
||||||
|
|
||||||
|
for (i = 0; i < (int) positions.GetCount(); i++)
|
||||||
|
{
|
||||||
|
int pos = positions[i];
|
||||||
|
wxASSERT(pos >= 0 && pos < len);
|
||||||
|
if (pos >= 0 && pos < len)
|
||||||
|
{
|
||||||
|
const wxRichTextAttr& attr = attributes[i];
|
||||||
|
|
||||||
|
if (pos == 0)
|
||||||
|
{
|
||||||
|
runStart = 0;
|
||||||
|
currentAttr = attr;
|
||||||
|
}
|
||||||
|
// Check if there was a gap from the last known attribute and this.
|
||||||
|
// In that case, we need to do something with the span of non-attributed text.
|
||||||
|
else if ((pos-1) > runEnd)
|
||||||
|
{
|
||||||
|
if (runEnd == -1)
|
||||||
|
{
|
||||||
|
// We hadn't processed anything previously, so the previous run is from the text start
|
||||||
|
// to just before this position. The current attribute remains empty.
|
||||||
|
runStart = 0;
|
||||||
|
runEnd = pos-1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If the previous attribute matches the gap's attribute (i.e., no attributes)
|
||||||
|
// then just extend the run.
|
||||||
|
if (currentAttr.IsDefault())
|
||||||
|
{
|
||||||
|
runEnd = pos-1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// We need to add an object, or reuse the existing one.
|
||||||
|
if (runStart == 0)
|
||||||
|
{
|
||||||
|
lastPlainText = this;
|
||||||
|
SetText(text.Mid(runStart, runEnd - runStart + 1));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wxRichTextPlainText* obj = new wxRichTextPlainText;
|
||||||
|
lastPlainText = obj;
|
||||||
|
obj->SetAttributes(GetAttributes());
|
||||||
|
obj->SetProperties(GetProperties());
|
||||||
|
obj->SetParent(parent);
|
||||||
|
|
||||||
|
obj->SetText(text.Mid(runStart, runEnd - runStart + 1));
|
||||||
|
if (next)
|
||||||
|
parent->GetChildren().Insert(next, obj);
|
||||||
|
else
|
||||||
|
parent->GetChildren().Append(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
runStart = runEnd+1;
|
||||||
|
runEnd = pos-1;
|
||||||
|
|
||||||
|
currentAttr = emptyAttr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wxASSERT(runEnd == pos-1);
|
||||||
|
|
||||||
|
// Now we only have to deal with the previous run
|
||||||
|
if (currentAttr == attr)
|
||||||
|
{
|
||||||
|
// If we still have the same attributes, then we
|
||||||
|
// simply increase the run size.
|
||||||
|
runEnd = pos;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (runEnd >= 0)
|
||||||
|
{
|
||||||
|
// We need to add an object, or reuse the existing one.
|
||||||
|
if (runStart == 0)
|
||||||
|
{
|
||||||
|
lastPlainText = this;
|
||||||
|
SetText(text.Mid(runStart, runEnd - runStart + 1));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wxRichTextPlainText* obj = new wxRichTextPlainText;
|
||||||
|
lastPlainText = obj;
|
||||||
|
obj->SetAttributes(GetAttributes());
|
||||||
|
obj->SetProperties(GetProperties());
|
||||||
|
obj->SetParent(parent);
|
||||||
|
|
||||||
|
obj->SetText(text.Mid(runStart, runEnd - runStart + 1));
|
||||||
|
if (next)
|
||||||
|
parent->GetChildren().Insert(next, obj);
|
||||||
|
else
|
||||||
|
parent->GetChildren().Append(obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
runStart = pos;
|
||||||
|
runEnd = pos;
|
||||||
|
|
||||||
|
currentAttr = attr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We may still have a run to add, and possibly a no-attribute text fragment after that.
|
||||||
|
// If the whole string was already a single attribute (the run covers the whole string), don't split.
|
||||||
|
if ((runStart != -1) && !(runStart == 0 && runEnd == (len-1)))
|
||||||
|
{
|
||||||
|
// If the current attribute is empty, merge the run with the next fragment
|
||||||
|
// which by definition (because it's not specified) has empty attributes.
|
||||||
|
if (currentAttr.IsDefault())
|
||||||
|
runEnd = (len-1);
|
||||||
|
|
||||||
|
if (runEnd < (len-1))
|
||||||
|
{
|
||||||
|
// We need to add an object, or reuse the existing one.
|
||||||
|
if (runStart == 0)
|
||||||
|
{
|
||||||
|
lastPlainText = this;
|
||||||
|
SetText(text.Mid(runStart, runEnd - runStart + 1));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wxRichTextPlainText* obj = new wxRichTextPlainText;
|
||||||
|
lastPlainText = obj;
|
||||||
|
obj->SetAttributes(GetAttributes());
|
||||||
|
obj->SetProperties(GetProperties());
|
||||||
|
obj->SetParent(parent);
|
||||||
|
|
||||||
|
obj->SetText(text.Mid(runStart, runEnd - runStart + 1));
|
||||||
|
if (next)
|
||||||
|
parent->GetChildren().Insert(next, obj);
|
||||||
|
else
|
||||||
|
parent->GetChildren().Append(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
runStart = runEnd+1;
|
||||||
|
runEnd = (len-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now the last, non-attributed fragment at the end, if any
|
||||||
|
if ((runStart < len) && !(runStart == 0 && runEnd == (len-1)))
|
||||||
|
{
|
||||||
|
wxASSERT(runStart != 0);
|
||||||
|
|
||||||
|
wxRichTextPlainText* obj = new wxRichTextPlainText;
|
||||||
|
obj->SetAttributes(GetAttributes());
|
||||||
|
obj->SetProperties(GetProperties());
|
||||||
|
obj->SetParent(parent);
|
||||||
|
|
||||||
|
obj->SetText(text.Mid(runStart, runEnd - runStart + 1));
|
||||||
|
if (next)
|
||||||
|
parent->GetChildren().Insert(next, obj);
|
||||||
|
else
|
||||||
|
parent->GetChildren().Append(obj);
|
||||||
|
|
||||||
|
lastPlainText = obj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return lastPlainText;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/// Dump to output stream for debugging
|
/// Dump to output stream for debugging
|
||||||
void wxRichTextPlainText::Dump(wxTextOutputStream& stream)
|
void wxRichTextPlainText::Dump(wxTextOutputStream& stream)
|
||||||
{
|
{
|
||||||
@@ -13098,6 +13421,9 @@ void wxTextAttrCollectCommonAttributes(wxTextAttr& currentStyle, const wxTextAtt
|
|||||||
|
|
||||||
WX_DEFINE_OBJARRAY(wxRichTextVariantArray);
|
WX_DEFINE_OBJARRAY(wxRichTextVariantArray);
|
||||||
|
|
||||||
|
// JACS 2013-01-27
|
||||||
|
WX_DEFINE_OBJARRAY(wxRichTextAttrArray);
|
||||||
|
|
||||||
IMPLEMENT_DYNAMIC_CLASS(wxRichTextProperties, wxObject)
|
IMPLEMENT_DYNAMIC_CLASS(wxRichTextProperties, wxObject)
|
||||||
|
|
||||||
bool wxRichTextProperties::operator==(const wxRichTextProperties& props) const
|
bool wxRichTextProperties::operator==(const wxRichTextProperties& props) const
|
||||||
@@ -13411,8 +13737,19 @@ bool wxRichTextSelection::WithinSelection(const wxRichTextRange& range, const wx
|
|||||||
IMPLEMENT_CLASS(wxRichTextDrawingHandler, wxObject)
|
IMPLEMENT_CLASS(wxRichTextDrawingHandler, wxObject)
|
||||||
IMPLEMENT_CLASS(wxRichTextDrawingContext, wxObject)
|
IMPLEMENT_CLASS(wxRichTextDrawingContext, wxObject)
|
||||||
|
|
||||||
|
wxRichTextDrawingContext::wxRichTextDrawingContext(wxRichTextBuffer* buffer)
|
||||||
|
{
|
||||||
|
Init();
|
||||||
|
m_buffer = buffer;
|
||||||
|
if (m_buffer && m_buffer->GetRichTextCtrl())
|
||||||
|
EnableVirtualAttributes(m_buffer->GetRichTextCtrl()->GetVirtualAttributesEnabled());
|
||||||
|
}
|
||||||
|
|
||||||
bool wxRichTextDrawingContext::HasVirtualAttributes(wxRichTextObject* obj) const
|
bool wxRichTextDrawingContext::HasVirtualAttributes(wxRichTextObject* obj) const
|
||||||
{
|
{
|
||||||
|
if (!GetVirtualAttributesEnabled())
|
||||||
|
return false;
|
||||||
|
|
||||||
wxList::compatibility_iterator node = m_buffer->GetDrawingHandlers().GetFirst();
|
wxList::compatibility_iterator node = m_buffer->GetDrawingHandlers().GetFirst();
|
||||||
while (node)
|
while (node)
|
||||||
{
|
{
|
||||||
@@ -13428,6 +13765,9 @@ bool wxRichTextDrawingContext::HasVirtualAttributes(wxRichTextObject* obj) const
|
|||||||
wxRichTextAttr wxRichTextDrawingContext::GetVirtualAttributes(wxRichTextObject* obj) const
|
wxRichTextAttr wxRichTextDrawingContext::GetVirtualAttributes(wxRichTextObject* obj) const
|
||||||
{
|
{
|
||||||
wxRichTextAttr attr;
|
wxRichTextAttr attr;
|
||||||
|
if (!GetVirtualAttributesEnabled())
|
||||||
|
return attr;
|
||||||
|
|
||||||
// We apply all handlers, so we can may combine several different attributes
|
// We apply all handlers, so we can may combine several different attributes
|
||||||
wxList::compatibility_iterator node = m_buffer->GetDrawingHandlers().GetFirst();
|
wxList::compatibility_iterator node = m_buffer->GetDrawingHandlers().GetFirst();
|
||||||
while (node)
|
while (node)
|
||||||
@@ -13447,6 +13787,9 @@ wxRichTextAttr wxRichTextDrawingContext::GetVirtualAttributes(wxRichTextObject*
|
|||||||
|
|
||||||
bool wxRichTextDrawingContext::ApplyVirtualAttributes(wxRichTextAttr& attr, wxRichTextObject* obj) const
|
bool wxRichTextDrawingContext::ApplyVirtualAttributes(wxRichTextAttr& attr, wxRichTextObject* obj) const
|
||||||
{
|
{
|
||||||
|
if (!GetVirtualAttributesEnabled())
|
||||||
|
return false;
|
||||||
|
|
||||||
if (HasVirtualAttributes(obj))
|
if (HasVirtualAttributes(obj))
|
||||||
{
|
{
|
||||||
wxRichTextAttr a(GetVirtualAttributes(obj));
|
wxRichTextAttr a(GetVirtualAttributes(obj));
|
||||||
@@ -13457,6 +13800,75 @@ bool wxRichTextDrawingContext::ApplyVirtualAttributes(wxRichTextAttr& attr, wxRi
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int wxRichTextDrawingContext::GetVirtualSubobjectAttributesCount(wxRichTextObject* obj) const
|
||||||
|
{
|
||||||
|
if (!GetVirtualAttributesEnabled())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
wxList::compatibility_iterator node = m_buffer->GetDrawingHandlers().GetFirst();
|
||||||
|
while (node)
|
||||||
|
{
|
||||||
|
wxRichTextDrawingHandler *handler = (wxRichTextDrawingHandler*)node->GetData();
|
||||||
|
int count = handler->GetVirtualSubobjectAttributesCount(obj);
|
||||||
|
if (count > 0)
|
||||||
|
return count;
|
||||||
|
|
||||||
|
node = node->GetNext();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int wxRichTextDrawingContext::GetVirtualSubobjectAttributes(wxRichTextObject* obj, wxArrayInt& positions, wxRichTextAttrArray& attributes) const
|
||||||
|
{
|
||||||
|
if (!GetVirtualAttributesEnabled())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
wxList::compatibility_iterator node = m_buffer->GetDrawingHandlers().GetFirst();
|
||||||
|
while (node)
|
||||||
|
{
|
||||||
|
wxRichTextDrawingHandler *handler = (wxRichTextDrawingHandler*)node->GetData();
|
||||||
|
if (handler->GetVirtualSubobjectAttributes(obj, positions, attributes))
|
||||||
|
return positions.GetCount();
|
||||||
|
|
||||||
|
node = node->GetNext();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxRichTextDrawingContext::HasVirtualText(const wxRichTextPlainText* obj) const
|
||||||
|
{
|
||||||
|
if (!GetVirtualAttributesEnabled())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
wxList::compatibility_iterator node = m_buffer->GetDrawingHandlers().GetFirst();
|
||||||
|
while (node)
|
||||||
|
{
|
||||||
|
wxRichTextDrawingHandler *handler = (wxRichTextDrawingHandler*)node->GetData();
|
||||||
|
if (handler->HasVirtualText(obj))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
node = node->GetNext();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxRichTextDrawingContext::GetVirtualText(const wxRichTextPlainText* obj, wxString& text) const
|
||||||
|
{
|
||||||
|
if (!GetVirtualAttributesEnabled())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
wxList::compatibility_iterator node = m_buffer->GetDrawingHandlers().GetFirst();
|
||||||
|
while (node)
|
||||||
|
{
|
||||||
|
wxRichTextDrawingHandler *handler = (wxRichTextDrawingHandler*)node->GetData();
|
||||||
|
if (handler->GetVirtualText(obj, text))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
node = node->GetNext();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/// Adds a handler to the end
|
/// Adds a handler to the end
|
||||||
void wxRichTextBuffer::AddDrawingHandler(wxRichTextDrawingHandler *handler)
|
void wxRichTextBuffer::AddDrawingHandler(wxRichTextDrawingHandler *handler)
|
||||||
{
|
{
|
||||||
|
@@ -355,6 +355,7 @@ void wxRichTextCtrl::Init()
|
|||||||
m_selectionAnchorObject = NULL;
|
m_selectionAnchorObject = NULL;
|
||||||
m_selectionState = wxRichTextCtrlSelectionState_Normal;
|
m_selectionState = wxRichTextCtrlSelectionState_Normal;
|
||||||
m_editable = true;
|
m_editable = true;
|
||||||
|
m_useVirtualAttributes = false;
|
||||||
m_verticalScrollbarEnabled = true;
|
m_verticalScrollbarEnabled = true;
|
||||||
m_caretAtLineStart = false;
|
m_caretAtLineStart = false;
|
||||||
m_dragging = false;
|
m_dragging = false;
|
||||||
@@ -2941,7 +2942,8 @@ void wxRichTextCtrl::DoWriteText(const wxString& value, int flags)
|
|||||||
wxString valueUnix = wxTextFile::Translate(value, wxTextFileType_Unix);
|
wxString valueUnix = wxTextFile::Translate(value, wxTextFileType_Unix);
|
||||||
|
|
||||||
GetFocusObject()->InsertTextWithUndo(& GetBuffer(), m_caretPosition+1, valueUnix, this, wxRICHTEXT_INSERT_WITH_PREVIOUS_PARAGRAPH_STYLE);
|
GetFocusObject()->InsertTextWithUndo(& GetBuffer(), m_caretPosition+1, valueUnix, this, wxRICHTEXT_INSERT_WITH_PREVIOUS_PARAGRAPH_STYLE);
|
||||||
GetBuffer().Defragment();
|
wxRichTextDrawingContext context(& GetBuffer());
|
||||||
|
GetBuffer().Defragment(context);
|
||||||
|
|
||||||
if ( flags & SetValue_SendEvent )
|
if ( flags & SetValue_SendEvent )
|
||||||
wxTextCtrl::SendTextUpdatedEvent(this);
|
wxTextCtrl::SendTextUpdatedEvent(this);
|
||||||
@@ -3890,7 +3892,7 @@ bool wxRichTextCtrl::LayoutContent(bool onlyVisibleRect)
|
|||||||
dc.SetFont(GetFont());
|
dc.SetFont(GetFont());
|
||||||
|
|
||||||
wxRichTextDrawingContext context(& GetBuffer());
|
wxRichTextDrawingContext context(& GetBuffer());
|
||||||
GetBuffer().Defragment();
|
GetBuffer().Defragment(context);
|
||||||
GetBuffer().UpdateRanges(); // If items were deleted, ranges need recalculation
|
GetBuffer().UpdateRanges(); // If items were deleted, ranges need recalculation
|
||||||
GetBuffer().Layout(dc, context, availableSpace, availableSpace, flags);
|
GetBuffer().Layout(dc, context, availableSpace, availableSpace, flags);
|
||||||
GetBuffer().Invalidate(wxRICHTEXT_NONE);
|
GetBuffer().Invalidate(wxRICHTEXT_NONE);
|
||||||
|
@@ -75,7 +75,8 @@ bool wxRichTextHTMLHandler::DoSaveFile(wxRichTextBuffer *buffer, wxOutputStream&
|
|||||||
|
|
||||||
ClearTemporaryImageLocations();
|
ClearTemporaryImageLocations();
|
||||||
|
|
||||||
buffer->Defragment();
|
wxRichTextDrawingContext context(buffer);
|
||||||
|
buffer->Defragment(context);
|
||||||
|
|
||||||
#if wxUSE_UNICODE
|
#if wxUSE_UNICODE
|
||||||
wxCSConv* customEncoding = NULL;
|
wxCSConv* customEncoding = NULL;
|
||||||
|
Reference in New Issue
Block a user