Added field implementation

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@71379 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Julian Smart
2012-05-09 11:06:04 +00:00
parent f819ed5d42
commit 7c9fdebe5f
8 changed files with 1550 additions and 45 deletions

View File

@@ -527,7 +527,7 @@ All (GUI):
- Fix WXK_MENU handling in wxStyledTextCtrl under wxGTK (cantabile). - Fix WXK_MENU handling in wxStyledTextCtrl under wxGTK (cantabile).
- Added wxAcceleratorEntry::ToRawString() (Armel Asselin). - Added wxAcceleratorEntry::ToRawString() (Armel Asselin).
- Added wxDataViewEvent::SetDragFlags() and GetDropEffect() (Friedrich). - Added wxDataViewEvent::SetDragFlags() and GetDropEffect() (Friedrich).
- Added support for fields and virtual attributes to wxRichTextCtrl.
GTK: GTK:

View File

@@ -131,6 +131,8 @@ class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextLine;
class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextParagraph; class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextParagraph;
class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextFileHandler; class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextFileHandler;
class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextDrawingHandler; class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextDrawingHandler;
class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextField;
class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextFieldType;
class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextStyleSheet; class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextStyleSheet;
class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextListStyleDefinition; class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextListStyleDefinition;
class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextEvent; class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextEvent;
@@ -193,7 +195,10 @@ enum wxRichTextHitTestFlags
wxRICHTEXT_HITTEST_NO_NESTED_OBJECTS = 0x20, wxRICHTEXT_HITTEST_NO_NESTED_OBJECTS = 0x20,
// Ignore floating objects // Ignore floating objects
wxRICHTEXT_HITTEST_NO_FLOATING_OBJECTS = 0x40 wxRICHTEXT_HITTEST_NO_FLOATING_OBJECTS = 0x40,
// Don't recurse into objects marked as atomic
wxRICHTEXT_HITTEST_HONOUR_ATOMIC = 0x80
}; };
/** /**
@@ -2407,10 +2412,16 @@ public:
wxRichTextRange GetOwnRangeIfTopLevel() const { return IsTopLevel() ? m_ownRange : m_range; } wxRichTextRange GetOwnRangeIfTopLevel() const { return IsTopLevel() ? m_ownRange : m_range; }
/** /**
Returns @true if this object this composite. Returns @true if this object is composite.
*/ */
virtual bool IsComposite() const { return false; } virtual bool IsComposite() const { return false; }
/**
Returns @true if no user editing can be done inside the object. This returns @true for simple objects,
@false for most composite objects, but @true for fields, which if composite, should not be user-edited.
*/
virtual bool IsAtomic() const { return true; }
/** /**
Returns a pointer to the parent object. Returns a pointer to the parent object.
*/ */
@@ -2498,7 +2509,7 @@ public:
wxRichTextAttr& GetAttributes() { return m_attributes; } wxRichTextAttr& GetAttributes() { return m_attributes; }
/** /**
Sets the object's properties. Returns the object's properties.
*/ */
wxRichTextProperties& GetProperties() { return m_properties; } wxRichTextProperties& GetProperties() { return m_properties; }
@@ -2508,7 +2519,7 @@ public:
const wxRichTextProperties& GetProperties() const { return m_properties; } const wxRichTextProperties& GetProperties() const { return m_properties; }
/** /**
Returns the object's properties. Sets the object's properties.
*/ */
void SetProperties(const wxRichTextProperties& props) { m_properties = props; } void SetProperties(const wxRichTextProperties& props) { m_properties = props; }
@@ -2726,6 +2737,12 @@ public:
*/ */
virtual bool IsComposite() const { return true; } virtual bool IsComposite() const { return true; }
/**
Returns @true if no user editing can be done inside the object. This returns @true for simple objects,
@false for most composite objects, but @true for fields, which if composite, should not be user-edited.
*/
virtual bool IsAtomic() const { return false; }
/** /**
Returns true if the buffer is empty. Returns true if the buffer is empty.
*/ */
@@ -2879,6 +2896,16 @@ public:
bool InsertImageWithUndo(wxRichTextBuffer* buffer, long pos, const wxRichTextImageBlock& imageBlock, bool InsertImageWithUndo(wxRichTextBuffer* buffer, long pos, const wxRichTextImageBlock& imageBlock,
wxRichTextCtrl* ctrl, int flags, const wxRichTextAttr& textAttr); wxRichTextCtrl* ctrl, int flags, const wxRichTextAttr& textAttr);
/**
Submits a command to insert the given field. Field data can be included in properties.
@see wxRichTextField, wxRichTextFieldType, wxRichTextFieldTypeStandard
*/
wxRichTextField* InsertFieldWithUndo(wxRichTextBuffer* buffer, long pos, const wxString& fieldType,
const wxRichTextProperties& properties,
wxRichTextCtrl* ctrl, int flags,
const wxRichTextAttr& textAttr);
/** /**
Returns the style that is appropriate for a new paragraph at this position. Returns the style that is appropriate for a new paragraph at this position.
If the previous paragraph has a paragraph style name, looks up the next-paragraph If the previous paragraph has a paragraph style name, looks up the next-paragraph
@@ -3418,6 +3445,470 @@ public:
protected: protected:
}; };
/**
@class wxRichTextField
This class implements the general concept of a field, an object that represents
additional functionality such as a footnote, a bookmark, a page number, a table
of contents, and so on. Extra information (such as a bookmark name) can be stored
in the object properties.
Drawing, layout, and property editing is delegated to classes derived
from wxRichTextFieldType, such as instances of wxRichTextFieldTypeStandard; this makes
the use of fields an efficient method of introducing extra functionality, since
most of the information required to draw a field (such as a bitmap) is kept centrally
in a single field type definition.
The FieldType property, accessed by SetFieldType/GetFieldType, is used to retrieve
the field type definition. So be careful not to overwrite this property.
wxRichTextField is derived from wxRichTextParagraphLayoutBox, which means that it
can contain its own read-only content, refreshed when the application calls the UpdateField
function. Whether a field is treated as a composite or a single graphic is determined
by the field type definition. If using wxRichTextFieldTypeStandard, passing the display
type wxRICHTEXT_FIELD_STYLE_COMPOSITE to the field type definition causes the field
to behave like a composite; the other display styles display a simple graphic.
When implementing a composite field, you will still need to derive from wxRichTextFieldTypeStandard
or wxRichTextFieldType, if only to implement UpdateField to refresh the field content
appropriately. wxRichTextFieldTypeStandard is only one possible implementation, but
covers common needs especially for simple, static fields using text or a bitmap.
Register field types on application initialisation with the static function
wxRichTextParagraphLayoutBox::AddFieldType. They will be deleted automatically
on application exit.
An application can write a field to a control with wxRichTextCtrl::WriteField,
taking a field type, the properties for the field, and optional attributes.
@library{wxrichtext}
@category{richtext}
@see wxRichTextFieldTypeStandard, wxRichTextFieldType, wxRichTextParagraphLayoutBox, wxRichTextProperties, wxRichTextCtrl
*/
class WXDLLIMPEXP_RICHTEXT wxRichTextField: public wxRichTextParagraphLayoutBox
{
DECLARE_DYNAMIC_CLASS(wxRichTextField)
public:
// Constructors
/**
Default constructor; optionally pass the parent object.
*/
wxRichTextField(const wxString& fieldType = wxEmptyString, wxRichTextObject* parent = NULL);
/**
Copy constructor.
*/
wxRichTextField(const wxRichTextField& obj): wxRichTextParagraphLayoutBox() { Copy(obj); }
// Overridables
virtual bool Draw(wxDC& dc, wxRichTextDrawingContext& context, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int descent, int style);
virtual bool Layout(wxDC& dc, wxRichTextDrawingContext& context, const wxRect& rect, const wxRect& parentRect, int style);
virtual bool GetRangeSize(const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, wxRichTextDrawingContext& context, int flags, wxPoint position = wxPoint(0,0), wxArrayInt* partialExtents = NULL) const;
virtual wxString GetXMLNodeName() const { return wxT("field"); }
virtual bool CanEditProperties() const;
virtual bool EditProperties(wxWindow* parent, wxRichTextBuffer* buffer);
virtual wxString GetPropertiesMenuLabel() const;
virtual bool AcceptsFocus() const { return false; }
virtual void CalculateRange(long start, long& end);
/**
If a field has children, we don't want the user to be able to edit it.
*/
virtual bool IsAtomic() const { return true; }
virtual bool IsEmpty() const { return false; }
virtual bool IsTopLevel() const;
// Accessors
void SetFieldType(const wxString& fieldType) { GetProperties().SetProperty(wxT("FieldType"), fieldType); }
wxString GetFieldType() const { return GetProperties().GetPropertyString(wxT("FieldType")); }
// Operations
/**
Update the field; delegated to the associated field type. This would typically expand the field to its value,
if this is a dynamically changing and/or composite field.
*/
virtual bool UpdateField();
virtual wxRichTextObject* Clone() const { return new wxRichTextField(*this); }
void Copy(const wxRichTextField& obj);
protected:
};
/**
@class wxRichTextFieldType
The base class for custom field types. Each type definition handles one
field type. Override functions to provide drawing, layout, updating and
property editing functionality for a field.
Register field types on application initialisation with the static function
wxRichTextParagraphLayoutBox::AddFieldType. They will be deleted automatically
on application exit.
@library{wxrichtext}
@category{richtext}
@see wxRichTextFieldTypeStandard, wxRichTextField, wxRichTextCtrl
*/
class WXDLLIMPEXP_RICHTEXT wxRichTextFieldType: public wxObject
{
DECLARE_CLASS(wxRichTextFieldType)
public:
/**
Creates a field type definition.
*/
wxRichTextFieldType(const wxString& name = wxEmptyString)
: m_name(name)
{ }
/**
Copy constructor.
*/
wxRichTextFieldType(const wxRichTextFieldType& fieldType) { Copy(fieldType); }
void Copy(const wxRichTextFieldType& fieldType) { m_name = fieldType.m_name; }
/**
Draw the item, within the given range. Some objects may ignore the range (for
example paragraphs) while others must obey it (lines, to implement wrapping)
*/
virtual bool Draw(wxRichTextField* obj, wxDC& dc, wxRichTextDrawingContext& context, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int descent, int style) = 0;
/**
Lay the item out at the specified position with the given size constraint.
Layout must set the cached size. @rect is the available space for the object,
and @a parentRect is the container that is used to determine a relative size
or position (for example if a text box must be 50% of the parent text box).
*/
virtual bool Layout(wxRichTextField* obj, wxDC& dc, wxRichTextDrawingContext& context, const wxRect& rect, const wxRect& parentRect, int style) = 0;
/**
Returns the object size for the given range. Returns @false if the range
is invalid for this object.
*/
virtual bool GetRangeSize(wxRichTextField* obj, const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, wxRichTextDrawingContext& context, int flags, wxPoint position = wxPoint(0,0), wxArrayInt* partialExtents = NULL) const = 0;
/**
Returns @true if we can edit the object's properties via a GUI.
*/
virtual bool CanEditProperties(wxRichTextField* WXUNUSED(obj)) const { return false; }
/**
Edits the object's properties via a GUI.
*/
virtual bool EditProperties(wxRichTextField* WXUNUSED(obj), wxWindow* WXUNUSED(parent), wxRichTextBuffer* WXUNUSED(buffer)) { return false; }
/**
Returns the label to be used for the properties context menu item.
*/
virtual wxString GetPropertiesMenuLabel(wxRichTextField* WXUNUSED(obj)) const { return wxEmptyString; }
/**
Update the field. This would typically expand the field to its value,
if this is a dynamically changing and/or composite field.
*/
virtual bool UpdateField(wxRichTextField* WXUNUSED(obj)) { return false; }
/**
Returns @true if this object is top-level, i.e. contains its own paragraphs, such as a text box.
*/
virtual bool IsTopLevel(wxRichTextField* WXUNUSED(obj)) const { return true; }
/**
Sets the field type name. There should be a unique name per field type object.
*/
void SetName(const wxString& name) { m_name = name; }
/**
Returns the field type name. There should be a unique name per field type object.
*/
wxString GetName() const { return m_name; }
protected:
wxString m_name;
};
WX_DECLARE_STRING_HASH_MAP(wxRichTextFieldType*, wxRichTextFieldTypeHashMap);
/**
@class wxRichTextFieldTypeStandard
A field type that can handle fields with text or bitmap labels, with a small range
of styles for implementing rectangular fields and fields that can be used for start
and end tags.
The border, text and background colours can be customised; the default is
white text on a black background.
The following display styles can be used.
@beginStyleTable
@style{wxRICHTEXT_FIELD_STYLE_COMPOSITE}
Creates a composite field; you will probably need to derive a new class to implement UpdateField.
@style{wxRICHTEXT_FIELD_STYLE_RECTANGLE}
Shows a rounded rectangle background.
@style{wxRICHTEXT_FIELD_STYLE_NO_BORDER}
Suppresses the background and border; mostly used with a bitmap label.
@style{wxRICHTEXT_FIELD_STYLE_START_TAG}
Shows a start tag background, with the pointy end facing right.
@style{wxRICHTEXT_FIELD_STYLE_END_TAG}
Shows an end tag background, with the pointy end facing left.
@endStyleTable
@library{wxrichtext}
@category{richtext}
@see wxRichTextFieldType, wxRichTextField, wxRichTextBuffer, wxRichTextCtrl
*/
class WXDLLIMPEXP_RICHTEXT wxRichTextFieldTypeStandard: public wxRichTextFieldType
{
DECLARE_CLASS(wxRichTextFieldTypeStandard)
public:
// Display style types
enum { wxRICHTEXT_FIELD_STYLE_COMPOSITE = 0x01,
wxRICHTEXT_FIELD_STYLE_RECTANGLE = 0x02,
wxRICHTEXT_FIELD_STYLE_NO_BORDER = 0x04,
wxRICHTEXT_FIELD_STYLE_START_TAG = 0x08,
wxRICHTEXT_FIELD_STYLE_END_TAG = 0x10
};
/**
Constructor, creating a field type definition with a text label.
@param parent
The name of the type definition. This must be unique, and is the type
name used when adding a field to a control.
@param label
The text label to be shown on the field.
@param displayStyle
The display style: one of wxRICHTEXT_FIELD_STYLE_RECTANGLE,
wxRICHTEXT_FIELD_STYLE_NO_BORDER, wxRICHTEXT_FIELD_STYLE_START_TAG,
wxRICHTEXT_FIELD_STYLE_END_TAG.
*/
wxRichTextFieldTypeStandard(const wxString& name, const wxString& label, int displayStyle = wxRICHTEXT_FIELD_STYLE_RECTANGLE);
/**
Constructor, creating a field type definition with a bitmap label.
@param parent
The name of the type definition. This must be unique, and is the type
name used when adding a field to a control.
@param label
The bitmap label to be shown on the field.
@param displayStyle
The display style: one of wxRICHTEXT_FIELD_STYLE_RECTANGLE,
wxRICHTEXT_FIELD_STYLE_NO_BORDER, wxRICHTEXT_FIELD_STYLE_START_TAG,
wxRICHTEXT_FIELD_STYLE_END_TAG.
*/
wxRichTextFieldTypeStandard(const wxString& name, const wxBitmap& bitmap, int displayStyle = wxRICHTEXT_FIELD_STYLE_NO_BORDER);
/**
The default constructor.
*/
wxRichTextFieldTypeStandard() { Init(); }
/**
The copy constructor.
*/
wxRichTextFieldTypeStandard(const wxRichTextFieldTypeStandard& field) { Copy(field); }
/**
Initialises the object.
*/
void Init();
/**
Copies the object.
*/
void Copy(const wxRichTextFieldTypeStandard& field);
/**
The assignment operator.
*/
void operator=(const wxRichTextFieldTypeStandard& field) { Copy(field); }
/**
Draw the item, within the given range. Some objects may ignore the range (for
example paragraphs) while others must obey it (lines, to implement wrapping)
*/
virtual bool Draw(wxRichTextField* obj, wxDC& dc, wxRichTextDrawingContext& context, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int descent, int style);
/**
Lay the item out at the specified position with the given size constraint.
Layout must set the cached size. @rect is the available space for the object,
and @a parentRect is the container that is used to determine a relative size
or position (for example if a text box must be 50% of the parent text box).
*/
virtual bool Layout(wxRichTextField* obj, wxDC& dc, wxRichTextDrawingContext& context, const wxRect& rect, const wxRect& parentRect, int style);
/**
Returns the object size for the given range. Returns @false if the range
is invalid for this object.
*/
virtual bool GetRangeSize(wxRichTextField* obj, const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, wxRichTextDrawingContext& context, int flags, wxPoint position = wxPoint(0,0), wxArrayInt* partialExtents = NULL) const;
/**
Get the size of the field, given the label, font size, and so on.
*/
wxSize GetSize(wxRichTextField* obj, wxDC& dc, wxRichTextDrawingContext& context, int style) const;
/**
Returns @true if the display type is wxRICHTEXT_FIELD_STYLE_COMPOSITE, @false otherwise.
*/
virtual bool IsTopLevel(wxRichTextField* WXUNUSED(obj)) const { return (GetDisplayStyle() & wxRICHTEXT_FIELD_STYLE_COMPOSITE) != 0; }
/**
Sets the text label for fields of this type.
*/
void SetLabel(const wxString& label) { m_label = label; }
/**
Returns the text label for fields of this type.
*/
const wxString& GetLabel() const { return m_label; }
/**
Sets the bitmap label for fields of this type.
*/
void SetBitmap(const wxBitmap& bitmap) { m_bitmap = bitmap; }
/**
Gets the bitmap label for fields of this type.
*/
const wxBitmap& GetBitmap() const { return m_bitmap; }
/**
Gets the display style for fields of this type.
*/
int GetDisplayStyle() const { return m_displayStyle; }
/**
Sets the display style for fields of this type.
*/
void SetDisplayStyle(int displayStyle) { m_displayStyle = displayStyle; }
/**
Gets the font used for drawing the text label.
*/
const wxFont& GetFont() const { return m_font; }
/**
Sets the font used for drawing the text label.
*/
void SetFont(const wxFont& font) { m_font = font; }
/**
Gets the colour used for drawing the text label.
*/
const wxColour& GetTextColour() const { return m_textColour; }
/**
Sets the colour used for drawing the text label.
*/
void SetTextColour(const wxColour& colour) { m_textColour = colour; }
/**
Gets the colour used for drawing the field border.
*/
const wxColour& GetBorderColour() const { return m_borderColour; }
/**
Sets the colour used for drawing the field border.
*/
void SetBorderColour(const wxColour& colour) { m_borderColour = colour; }
/**
Gets the colour used for drawing the field background.
*/
const wxColour& GetBackgroundColour() const { return m_backgroundColour; }
/**
Sets the colour used for drawing the field background.
*/
void SetBackgroundColour(const wxColour& colour) { m_backgroundColour = colour; }
/**
Sets the vertical padding (the distance between the border and the text).
*/
void SetVerticalPadding(int padding) { m_verticalPadding = padding; }
/**
Gets the vertical padding (the distance between the border and the text).
*/
int GetVerticalPadding() const { return m_verticalPadding; }
/**
Sets the horizontal padding (the distance between the border and the text).
*/
void SetHorizontalPadding(int padding) { m_horizontalPadding = padding; }
/**
Sets the horizontal padding (the distance between the border and the text).
*/
int GetHorizontalPadding() const { return m_horizontalPadding; }
/**
Sets the horizontal margin surrounding the field object.
*/
void SetHorizontalMargin(int margin) { m_horizontalMargin = margin; }
/**
Gets the horizontal margin surrounding the field object.
*/
int GetHorizontalMargin() const { return m_horizontalMargin; }
/**
Sets the vertical margin surrounding the field object.
*/
void SetVerticalMargin(int margin) { m_verticalMargin = margin; }
/**
Gets the vertical margin surrounding the field object.
*/
int GetVerticalMargin() const { return m_verticalMargin; }
protected:
wxString m_label;
int m_displayStyle;
wxFont m_font;
wxColour m_textColour;
wxColour m_borderColour;
wxColour m_backgroundColour;
int m_verticalPadding;
int m_horizontalPadding;
int m_horizontalMargin;
int m_verticalMargin;
wxBitmap m_bitmap;
};
/** /**
@class wxRichTextLine @class wxRichTextLine
@@ -4750,6 +5241,38 @@ public:
*/ */
static void CleanUpDrawingHandlers(); static void CleanUpDrawingHandlers();
/**
Returns the field types.
*/
static wxRichTextFieldTypeHashMap& GetFieldTypes() { return sm_fieldTypes; }
/**
Adds a field type.
@see RemoveFieldType(), FindFieldType(), wxRichTextField, wxRichTextFieldType, wxRichTextFieldTypeStandard
*/
static void AddFieldType(wxRichTextFieldType *fieldType);
/**
Removes a field type by name.
@see AddFieldType(), FindFieldType(), wxRichTextField, wxRichTextFieldType, wxRichTextFieldTypeStandard
*/
static bool RemoveFieldType(const wxString& name);
/**
Finds a field type by name.
@see RemoveFieldType(), AddFieldType(), wxRichTextField, wxRichTextFieldType, wxRichTextFieldTypeStandard
*/
static wxRichTextFieldType *FindFieldType(const wxString& name);
/**
Cleans up field types.
*/
static void CleanUpFieldTypes();
/** /**
Returns the renderer object. Returns the renderer object.
*/ */
@@ -4836,6 +5359,9 @@ protected:
/// Drawing handlers /// Drawing handlers
static wxList sm_drawingHandlers; static wxList sm_drawingHandlers;
/// Field types
static wxRichTextFieldTypeHashMap sm_fieldTypes;
/// Renderer /// Renderer
static wxRichTextRenderer* sm_renderer; static wxRichTextRenderer* sm_renderer;
@@ -5501,12 +6027,12 @@ public:
virtual void SetVisible(bool visible) { m_visible = visible; } virtual void SetVisible(bool visible) { m_visible = visible; }
/** /**
Sets the name of the nandler. Sets the name of the handler.
*/ */
void SetName(const wxString& name) { m_name = name; } void SetName(const wxString& name) { m_name = name; }
/** /**
Returns the name of the nandler. Returns the name of the handler.
*/ */
wxString GetName() const { return m_name; } wxString GetName() const { return m_name; }
@@ -5619,7 +6145,7 @@ protected:
@class wxRichTextDrawingHandler @class wxRichTextDrawingHandler
The base class for custom drawing handlers. The base class for custom drawing handlers.
Currently, drawing handlers can provide virtual handlers. Currently, drawing handlers can provide virtual attributes.
@library{wxrichtext} @library{wxrichtext}
@category{richtext} @category{richtext}
@@ -5649,12 +6175,12 @@ public:
virtual bool GetVirtualAttributes(wxRichTextAttr& attr, wxRichTextObject* obj) const = 0; virtual bool GetVirtualAttributes(wxRichTextAttr& attr, wxRichTextObject* obj) const = 0;
/** /**
Sets the name of the nandler. Sets the name of the handler.
*/ */
void SetName(const wxString& name) { m_name = name; } void SetName(const wxString& name) { m_name = name; }
/** /**
Returns the name of the nandler. Returns the name of the handler.
*/ */
wxString GetName() const { return m_name; } wxString GetName() const { return m_name; }

View File

@@ -1060,6 +1060,21 @@ public:
*/ */
virtual wxRichTextBox* WriteTextBox(const wxRichTextAttr& textAttr = wxRichTextAttr()); virtual wxRichTextBox* WriteTextBox(const wxRichTextAttr& textAttr = wxRichTextAttr());
/**
Writes a field at the current insertion point.
@param fieldType
The field type, matching an existing field type definition.
@param properties
Extra data for the field.
@param textAttr
Optional attributes.
@see wxRichTextField, wxRichTextFieldType, wxRichTextFieldTypeStandard
*/
virtual wxRichTextField* WriteField(const wxString& fieldType, const wxRichTextProperties& properties,
const wxRichTextAttr& textAttr = wxRichTextAttr());
/** /**
Write a table at the current insertion point, returning the table. Write a table at the current insertion point, returning the table.
You can then call SetFocusObject() to set the focus to the new object. You can then call SetFocusObject() to set the focus to the new object.

View File

@@ -77,7 +77,10 @@ enum wxRichTextHitTestFlags
wxRICHTEXT_HITTEST_NO_NESTED_OBJECTS = 0x20, wxRICHTEXT_HITTEST_NO_NESTED_OBJECTS = 0x20,
// Ignore floating objects // Ignore floating objects
wxRICHTEXT_HITTEST_NO_FLOATING_OBJECTS = 0x40 wxRICHTEXT_HITTEST_NO_FLOATING_OBJECTS = 0x40,
// Don't recurse into objects marked as atomic
wxRICHTEXT_HITTEST_HONOUR_ATOMIC = 0x80
}; };
/** /**
@@ -2286,10 +2289,16 @@ public:
wxRichTextRange GetOwnRangeIfTopLevel() const { return IsTopLevel() ? m_ownRange : m_range; } wxRichTextRange GetOwnRangeIfTopLevel() const { return IsTopLevel() ? m_ownRange : m_range; }
/** /**
Returns @true if this object this composite. Returns @true if this object is composite.
*/ */
virtual bool IsComposite() const { return false; } virtual bool IsComposite() const { return false; }
/**
Returns @true if no user editing can be done inside the object. This returns @true for simple objects,
@false for most composite objects, but @true for fields, which if composite, should not be user-edited.
*/
virtual bool IsAtomic() const { return true; }
/** /**
Returns a pointer to the parent object. Returns a pointer to the parent object.
*/ */
@@ -2605,6 +2614,12 @@ public:
*/ */
virtual bool IsComposite() const { return true; } virtual bool IsComposite() const { return true; }
/**
Returns @true if no user editing can be done inside the object. This returns @true for simple objects,
@false for most composite objects, but @true for fields, which if composite, should not be user-edited.
*/
virtual bool IsAtomic() const { return false; }
/** /**
Returns true if the buffer is empty. Returns true if the buffer is empty.
*/ */
@@ -2759,6 +2774,16 @@ public:
wxRichTextCtrl* ctrl, int flags, wxRichTextCtrl* ctrl, int flags,
const wxRichTextAttr& textAttr); const wxRichTextAttr& textAttr);
/**
Submits a command to insert the given field. Field data can be included in properties.
@see wxRichTextField, wxRichTextFieldType, wxRichTextFieldTypeStandard
*/
wxRichTextField* InsertFieldWithUndo(wxRichTextBuffer* buffer, long pos, const wxString& fieldType,
const wxRichTextProperties& properties,
wxRichTextCtrl* ctrl, int flags,
const wxRichTextAttr& textAttr);
/** /**
Returns the style that is appropriate for a new paragraph at this position. Returns the style that is appropriate for a new paragraph at this position.
If the previous paragraph has a paragraph style name, looks up the next-paragraph If the previous paragraph has a paragraph style name, looks up the next-paragraph
@@ -3298,6 +3323,470 @@ public:
protected: protected:
}; };
/**
@class wxRichTextField
This class implements the general concept of a field, an object that represents
additional functionality such as a footnote, a bookmark, a page number, a table
of contents, and so on. Extra information (such as a bookmark name) can be stored
in the object properties.
Drawing, layout, and property editing is delegated to classes derived
from wxRichTextFieldType, such as instances of wxRichTextFieldTypeStandard; this makes
the use of fields an efficient method of introducing extra functionality, since
most of the information required to draw a field (such as a bitmap) is kept centrally
in a single field type definition.
The FieldType property, accessed by SetFieldType/GetFieldType, is used to retrieve
the field type definition. So be careful not to overwrite this property.
wxRichTextField is derived from wxRichTextParagraphLayoutBox, which means that it
can contain its own read-only content, refreshed when the application calls the UpdateField
function. Whether a field is treated as a composite or a single graphic is determined
by the field type definition. If using wxRichTextFieldTypeStandard, passing the display
type wxRICHTEXT_FIELD_STYLE_COMPOSITE to the field type definition causes the field
to behave like a composite; the other display styles display a simple graphic.
When implementing a composite field, you will still need to derive from wxRichTextFieldTypeStandard
or wxRichTextFieldType, if only to implement UpdateField to refresh the field content
appropriately. wxRichTextFieldTypeStandard is only one possible implementation, but
covers common needs especially for simple, static fields using text or a bitmap.
Register field types on application initialisation with the static function
wxRichTextParagraphLayoutBox::AddFieldType. They will be deleted automatically
on application exit.
An application can write a field to a control with wxRichTextCtrl::WriteField,
taking a field type, the properties for the field, and optional attributes.
@library{wxrichtext}
@category{richtext}
@see wxRichTextFieldTypeStandard, wxRichTextFieldType, wxRichTextParagraphLayoutBox, wxRichTextProperties, wxRichTextCtrl
*/
class WXDLLIMPEXP_RICHTEXT wxRichTextField: public wxRichTextParagraphLayoutBox
{
DECLARE_DYNAMIC_CLASS(wxRichTextField)
public:
// Constructors
/**
Default constructor; optionally pass the parent object.
*/
wxRichTextField(const wxString& fieldType = wxEmptyString, wxRichTextObject* parent = NULL);
/**
Copy constructor.
*/
wxRichTextField(const wxRichTextField& obj): wxRichTextParagraphLayoutBox() { Copy(obj); }
// Overridables
virtual bool Draw(wxDC& dc, wxRichTextDrawingContext& context, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int descent, int style);
virtual bool Layout(wxDC& dc, wxRichTextDrawingContext& context, const wxRect& rect, const wxRect& parentRect, int style);
virtual bool GetRangeSize(const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, wxRichTextDrawingContext& context, int flags, wxPoint position = wxPoint(0,0), wxArrayInt* partialExtents = NULL) const;
virtual wxString GetXMLNodeName() const { return wxT("field"); }
virtual bool CanEditProperties() const;
virtual bool EditProperties(wxWindow* parent, wxRichTextBuffer* buffer);
virtual wxString GetPropertiesMenuLabel() const;
virtual bool AcceptsFocus() const { return false; }
virtual void CalculateRange(long start, long& end);
/**
If a field has children, we don't want the user to be able to edit it.
*/
virtual bool IsAtomic() const { return true; }
virtual bool IsEmpty() const { return false; }
virtual bool IsTopLevel() const;
// Accessors
void SetFieldType(const wxString& fieldType) { GetProperties().SetProperty(wxT("FieldType"), fieldType); }
wxString GetFieldType() const { return GetProperties().GetPropertyString(wxT("FieldType")); }
// Operations
/**
Update the field; delegated to the associated field type. This would typically expand the field to its value,
if this is a dynamically changing and/or composite field.
*/
virtual bool UpdateField();
virtual wxRichTextObject* Clone() const { return new wxRichTextField(*this); }
void Copy(const wxRichTextField& obj);
protected:
};
/**
@class wxRichTextFieldType
The base class for custom field types. Each type definition handles one
field type. Override functions to provide drawing, layout, updating and
property editing functionality for a field.
Register field types on application initialisation with the static function
wxRichTextParagraphLayoutBox::AddFieldType. They will be deleted automatically
on application exit.
@library{wxrichtext}
@category{richtext}
@see wxRichTextFieldTypeStandard, wxRichTextField, wxRichTextCtrl
*/
class WXDLLIMPEXP_RICHTEXT wxRichTextFieldType: public wxObject
{
DECLARE_CLASS(wxRichTextFieldType)
public:
/**
Creates a field type definition.
*/
wxRichTextFieldType(const wxString& name = wxEmptyString)
: m_name(name)
{ }
/**
Copy constructor.
*/
wxRichTextFieldType(const wxRichTextFieldType& fieldType) { Copy(fieldType); }
void Copy(const wxRichTextFieldType& fieldType) { m_name = fieldType.m_name; }
/**
Draw the item, within the given range. Some objects may ignore the range (for
example paragraphs) while others must obey it (lines, to implement wrapping)
*/
virtual bool Draw(wxRichTextField* obj, wxDC& dc, wxRichTextDrawingContext& context, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int descent, int style) = 0;
/**
Lay the item out at the specified position with the given size constraint.
Layout must set the cached size. @rect is the available space for the object,
and @a parentRect is the container that is used to determine a relative size
or position (for example if a text box must be 50% of the parent text box).
*/
virtual bool Layout(wxRichTextField* obj, wxDC& dc, wxRichTextDrawingContext& context, const wxRect& rect, const wxRect& parentRect, int style) = 0;
/**
Returns the object size for the given range. Returns @false if the range
is invalid for this object.
*/
virtual bool GetRangeSize(wxRichTextField* obj, const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, wxRichTextDrawingContext& context, int flags, wxPoint position = wxPoint(0,0), wxArrayInt* partialExtents = NULL) const = 0;
/**
Returns @true if we can edit the object's properties via a GUI.
*/
virtual bool CanEditProperties(wxRichTextField* WXUNUSED(obj)) const { return false; }
/**
Edits the object's properties via a GUI.
*/
virtual bool EditProperties(wxRichTextField* WXUNUSED(obj), wxWindow* WXUNUSED(parent), wxRichTextBuffer* WXUNUSED(buffer)) { return false; }
/**
Returns the label to be used for the properties context menu item.
*/
virtual wxString GetPropertiesMenuLabel(wxRichTextField* WXUNUSED(obj)) const { return wxEmptyString; }
/**
Update the field. This would typically expand the field to its value,
if this is a dynamically changing and/or composite field.
*/
virtual bool UpdateField(wxRichTextField* WXUNUSED(obj)) { return false; }
/**
Returns @true if this object is top-level, i.e. contains its own paragraphs, such as a text box.
*/
virtual bool IsTopLevel(wxRichTextField* WXUNUSED(obj)) const { return true; }
/**
Sets the field type name. There should be a unique name per field type object.
*/
void SetName(const wxString& name) { m_name = name; }
/**
Returns the field type name. There should be a unique name per field type object.
*/
wxString GetName() const { return m_name; }
protected:
wxString m_name;
};
WX_DECLARE_STRING_HASH_MAP(wxRichTextFieldType*, wxRichTextFieldTypeHashMap);
/**
@class wxRichTextFieldTypeStandard
A field type that can handle fields with text or bitmap labels, with a small range
of styles for implementing rectangular fields and fields that can be used for start
and end tags.
The border, text and background colours can be customised; the default is
white text on a black background.
The following display styles can be used.
@beginStyleTable
@style{wxRICHTEXT_FIELD_STYLE_COMPOSITE}
Creates a composite field; you will probably need to derive a new class to implement UpdateField.
@style{wxRICHTEXT_FIELD_STYLE_RECTANGLE}
Shows a rounded rectangle background.
@style{wxRICHTEXT_FIELD_STYLE_NO_BORDER}
Suppresses the background and border; mostly used with a bitmap label.
@style{wxRICHTEXT_FIELD_STYLE_START_TAG}
Shows a start tag background, with the pointy end facing right.
@style{wxRICHTEXT_FIELD_STYLE_END_TAG}
Shows an end tag background, with the pointy end facing left.
@endStyleTable
@library{wxrichtext}
@category{richtext}
@see wxRichTextFieldType, wxRichTextField, wxRichTextBuffer, wxRichTextCtrl
*/
class WXDLLIMPEXP_RICHTEXT wxRichTextFieldTypeStandard: public wxRichTextFieldType
{
DECLARE_CLASS(wxRichTextFieldTypeStandard)
public:
// Display style types
enum { wxRICHTEXT_FIELD_STYLE_COMPOSITE = 0x01,
wxRICHTEXT_FIELD_STYLE_RECTANGLE = 0x02,
wxRICHTEXT_FIELD_STYLE_NO_BORDER = 0x04,
wxRICHTEXT_FIELD_STYLE_START_TAG = 0x08,
wxRICHTEXT_FIELD_STYLE_END_TAG = 0x10
};
/**
Constructor, creating a field type definition with a text label.
@param parent
The name of the type definition. This must be unique, and is the type
name used when adding a field to a control.
@param label
The text label to be shown on the field.
@param displayStyle
The display style: one of wxRICHTEXT_FIELD_STYLE_RECTANGLE,
wxRICHTEXT_FIELD_STYLE_NO_BORDER, wxRICHTEXT_FIELD_STYLE_START_TAG,
wxRICHTEXT_FIELD_STYLE_END_TAG.
*/
wxRichTextFieldTypeStandard(const wxString& name, const wxString& label, int displayStyle = wxRICHTEXT_FIELD_STYLE_RECTANGLE);
/**
Constructor, creating a field type definition with a bitmap label.
@param parent
The name of the type definition. This must be unique, and is the type
name used when adding a field to a control.
@param label
The bitmap label to be shown on the field.
@param displayStyle
The display style: one of wxRICHTEXT_FIELD_STYLE_RECTANGLE,
wxRICHTEXT_FIELD_STYLE_NO_BORDER, wxRICHTEXT_FIELD_STYLE_START_TAG,
wxRICHTEXT_FIELD_STYLE_END_TAG.
*/
wxRichTextFieldTypeStandard(const wxString& name, const wxBitmap& bitmap, int displayStyle = wxRICHTEXT_FIELD_STYLE_NO_BORDER);
/**
The default constructor.
*/
wxRichTextFieldTypeStandard() { Init(); }
/**
The copy constructor.
*/
wxRichTextFieldTypeStandard(const wxRichTextFieldTypeStandard& field) { Copy(field); }
/**
Initialises the object.
*/
void Init();
/**
Copies the object.
*/
void Copy(const wxRichTextFieldTypeStandard& field);
/**
The assignment operator.
*/
void operator=(const wxRichTextFieldTypeStandard& field) { Copy(field); }
/**
Draw the item, within the given range. Some objects may ignore the range (for
example paragraphs) while others must obey it (lines, to implement wrapping)
*/
virtual bool Draw(wxRichTextField* obj, wxDC& dc, wxRichTextDrawingContext& context, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int descent, int style);
/**
Lay the item out at the specified position with the given size constraint.
Layout must set the cached size. @rect is the available space for the object,
and @a parentRect is the container that is used to determine a relative size
or position (for example if a text box must be 50% of the parent text box).
*/
virtual bool Layout(wxRichTextField* obj, wxDC& dc, wxRichTextDrawingContext& context, const wxRect& rect, const wxRect& parentRect, int style);
/**
Returns the object size for the given range. Returns @false if the range
is invalid for this object.
*/
virtual bool GetRangeSize(wxRichTextField* obj, const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, wxRichTextDrawingContext& context, int flags, wxPoint position = wxPoint(0,0), wxArrayInt* partialExtents = NULL) const;
/**
Get the size of the field, given the label, font size, and so on.
*/
wxSize GetSize(wxRichTextField* obj, wxDC& dc, wxRichTextDrawingContext& context, int style) const;
/**
Returns @true if the display type is wxRICHTEXT_FIELD_STYLE_COMPOSITE, @false otherwise.
*/
virtual bool IsTopLevel(wxRichTextField* WXUNUSED(obj)) const { return (GetDisplayStyle() & wxRICHTEXT_FIELD_STYLE_COMPOSITE) != 0; }
/**
Sets the text label for fields of this type.
*/
void SetLabel(const wxString& label) { m_label = label; }
/**
Returns the text label for fields of this type.
*/
const wxString& GetLabel() const { return m_label; }
/**
Sets the bitmap label for fields of this type.
*/
void SetBitmap(const wxBitmap& bitmap) { m_bitmap = bitmap; }
/**
Gets the bitmap label for fields of this type.
*/
const wxBitmap& GetBitmap() const { return m_bitmap; }
/**
Gets the display style for fields of this type.
*/
int GetDisplayStyle() const { return m_displayStyle; }
/**
Sets the display style for fields of this type.
*/
void SetDisplayStyle(int displayStyle) { m_displayStyle = displayStyle; }
/**
Gets the font used for drawing the text label.
*/
const wxFont& GetFont() const { return m_font; }
/**
Sets the font used for drawing the text label.
*/
void SetFont(const wxFont& font) { m_font = font; }
/**
Gets the colour used for drawing the text label.
*/
const wxColour& GetTextColour() const { return m_textColour; }
/**
Sets the colour used for drawing the text label.
*/
void SetTextColour(const wxColour& colour) { m_textColour = colour; }
/**
Gets the colour used for drawing the field border.
*/
const wxColour& GetBorderColour() const { return m_borderColour; }
/**
Sets the colour used for drawing the field border.
*/
void SetBorderColour(const wxColour& colour) { m_borderColour = colour; }
/**
Gets the colour used for drawing the field background.
*/
const wxColour& GetBackgroundColour() const { return m_backgroundColour; }
/**
Sets the colour used for drawing the field background.
*/
void SetBackgroundColour(const wxColour& colour) { m_backgroundColour = colour; }
/**
Sets the vertical padding (the distance between the border and the text).
*/
void SetVerticalPadding(int padding) { m_verticalPadding = padding; }
/**
Gets the vertical padding (the distance between the border and the text).
*/
int GetVerticalPadding() const { return m_verticalPadding; }
/**
Sets the horizontal padding (the distance between the border and the text).
*/
void SetHorizontalPadding(int padding) { m_horizontalPadding = padding; }
/**
Sets the horizontal padding (the distance between the border and the text).
*/
int GetHorizontalPadding() const { return m_horizontalPadding; }
/**
Sets the horizontal margin surrounding the field object.
*/
void SetHorizontalMargin(int margin) { m_horizontalMargin = margin; }
/**
Gets the horizontal margin surrounding the field object.
*/
int GetHorizontalMargin() const { return m_horizontalMargin; }
/**
Sets the vertical margin surrounding the field object.
*/
void SetVerticalMargin(int margin) { m_verticalMargin = margin; }
/**
Gets the vertical margin surrounding the field object.
*/
int GetVerticalMargin() const { return m_verticalMargin; }
protected:
wxString m_label;
int m_displayStyle;
wxFont m_font;
wxColour m_textColour;
wxColour m_borderColour;
wxColour m_backgroundColour;
int m_verticalPadding;
int m_horizontalPadding;
int m_horizontalMargin;
int m_verticalMargin;
wxBitmap m_bitmap;
};
/** /**
@class wxRichTextLine @class wxRichTextLine
@@ -4624,6 +5113,38 @@ public:
*/ */
static void CleanUpDrawingHandlers(); static void CleanUpDrawingHandlers();
/**
Returns the field types.
*/
static wxRichTextFieldTypeHashMap& GetFieldTypes() { return sm_fieldTypes; }
/**
Adds a field type.
@see RemoveFieldType(), FindFieldType(), wxRichTextField, wxRichTextFieldType, wxRichTextFieldTypeStandard
*/
static void AddFieldType(wxRichTextFieldType *fieldType);
/**
Removes a field type by name.
@see AddFieldType(), FindFieldType(), wxRichTextField, wxRichTextFieldType, wxRichTextFieldTypeStandard
*/
static bool RemoveFieldType(const wxString& name);
/**
Finds a field type by name.
@see RemoveFieldType(), AddFieldType(), wxRichTextField, wxRichTextFieldType, wxRichTextFieldTypeStandard
*/
static wxRichTextFieldType *FindFieldType(const wxString& name);
/**
Cleans up field types.
*/
static void CleanUpFieldTypes();
/** /**
Returns the renderer object. Returns the renderer object.
*/ */
@@ -4710,6 +5231,9 @@ protected:
/// Drawing handlers /// Drawing handlers
static wxList sm_drawingHandlers; static wxList sm_drawingHandlers;
/// Field types
static wxRichTextFieldTypeHashMap sm_fieldTypes;
/// Renderer /// Renderer
static wxRichTextRenderer* sm_renderer; static wxRichTextRenderer* sm_renderer;
@@ -5374,12 +5898,12 @@ public:
virtual void SetVisible(bool visible) { m_visible = visible; } virtual void SetVisible(bool visible) { m_visible = visible; }
/** /**
Sets the name of the nandler. Sets the name of the handler.
*/ */
void SetName(const wxString& name) { m_name = name; } void SetName(const wxString& name) { m_name = name; }
/** /**
Returns the name of the nandler. Returns the name of the handler.
*/ */
wxString GetName() const { return m_name; } wxString GetName() const { return m_name; }
@@ -5492,7 +6016,7 @@ protected:
@class wxRichTextDrawingHandler @class wxRichTextDrawingHandler
The base class for custom drawing handlers. The base class for custom drawing handlers.
Currently, drawing handlers can provide virtual handlers. Currently, drawing handlers can provide virtual attributes.
@library{wxrichtext} @library{wxrichtext}
@category{richtext} @category{richtext}
@@ -5522,12 +6046,12 @@ public:
virtual bool GetVirtualAttributes(wxRichTextAttr& attr, wxRichTextObject* obj) const = 0; virtual bool GetVirtualAttributes(wxRichTextAttr& attr, wxRichTextObject* obj) const = 0;
/** /**
Sets the name of the nandler. Sets the name of the handler.
*/ */
void SetName(const wxString& name) { m_name = name; } void SetName(const wxString& name) { m_name = name; }
/** /**
Returns the name of the nandler. Returns the name of the handler.
*/ */
wxString GetName() const { return m_name; } wxString GetName() const { return m_name; }

View File

@@ -1019,6 +1019,21 @@ public:
*/ */
virtual wxRichTextBox* WriteTextBox(const wxRichTextAttr& textAttr = wxRichTextAttr()); virtual wxRichTextBox* WriteTextBox(const wxRichTextAttr& textAttr = wxRichTextAttr());
/**
Writes a field at the current insertion point.
@param fieldType
The field type, matching an existing field type definition.
@param properties
Extra data for the field.
@param textAttr
Optional attributes.
@see wxRichTextField, wxRichTextFieldType, wxRichTextFieldTypeStandard
*/
virtual wxRichTextField* WriteField(const wxString& fieldType, const wxRichTextProperties& properties,
const wxRichTextAttr& textAttr = wxRichTextAttr());
/** /**
Write a table at the current insertion point, returning the table. Write a table at the current insertion point, returning the table.
You can then call SetFocusObject() to set the focus to the new object. You can then call SetFocusObject() to set the focus to the new object.

View File

@@ -3542,7 +3542,6 @@ void wxRichTextParagraphLayoutBox::PrepareContent(wxRichTextParagraphLayoutBox&
buffer->GetRichTextCtrl()->PrepareContent(container); buffer->GetRichTextCtrl()->PrepareContent(container);
} }
/// Set character or paragraph properties /// Set character or paragraph properties
bool wxRichTextParagraphLayoutBox::SetProperties(const wxRichTextRange& range, const wxRichTextProperties& properties, int flags) bool wxRichTextParagraphLayoutBox::SetProperties(const wxRichTextRange& range, const wxRichTextProperties& properties, int flags)
{ {
@@ -4611,7 +4610,6 @@ bool wxRichTextParagraph::Layout(wxDC& dc, wxRichTextDrawingContext& context, co
node = node->GetNext(); node = node->GetNext();
} }
#endif #endif
// Split up lines // Split up lines
@@ -4724,7 +4722,7 @@ bool wxRichTextParagraph::Layout(wxDC& dc, wxRichTextDrawingContext& context, co
wxRect oldAvailableRect = availableRect; wxRect oldAvailableRect = availableRect;
// Available width depends on the floating objects and the line height. // Available width depends on the floating objects and the line height.
// Note: the floating objects may be placed vertically along the two side of // Note: the floating objects may be placed vertically along the two sides of
// buffer, so we may have different available line widths with different // buffer, so we may have different available line widths with different
// [startY, endY]. So, we can't determine how wide the available // [startY, endY]. So, we can't determine how wide the available
// space is until we know the exact line height. // space is until we know the exact line height.
@@ -4740,7 +4738,6 @@ bool wxRichTextParagraph::Layout(wxDC& dc, wxRichTextDrawingContext& context, co
lineAscent = wxMax(childSize.y-childDescent, maxAscent); lineAscent = wxMax(childSize.y-childDescent, maxAscent);
} }
lineHeight = wxMax(lineHeight, (lineDescent + lineAscent)); lineHeight = wxMax(lineHeight, (lineDescent + lineAscent));
wxRect floatAvailableRect = collector->GetAvailableRect(rect.y + currentPosition.y, rect.y + currentPosition.y + lineHeight); wxRect floatAvailableRect = collector->GetAvailableRect(rect.y + currentPosition.y, rect.y + currentPosition.y + lineHeight);
// Adjust availableRect to the space that is available when taking floating objects into account. // Adjust availableRect to the space that is available when taking floating objects into account.
@@ -4764,7 +4761,6 @@ bool wxRichTextParagraph::Layout(wxDC& dc, wxRichTextDrawingContext& context, co
{ {
wxSize oldSize = child->GetCachedSize(); wxSize oldSize = child->GetCachedSize();
//child->SetCachedSize(wxDefaultSize);
// Lays out the object first with a given amount of space, and then if no width was specified in attr, // Lays out the object first with a given amount of space, and then if no width was specified in attr,
// lays out the object again using the minimum size // lays out the object again using the minimum size
child->Invalidate(wxRICHTEXT_ALL); child->Invalidate(wxRICHTEXT_ALL);
@@ -4772,7 +4768,6 @@ bool wxRichTextParagraph::Layout(wxDC& dc, wxRichTextDrawingContext& context, co
attr, child->GetAttributes(), availableRect, parentRect, style); attr, child->GetAttributes(), availableRect, parentRect, style);
childSize = child->GetCachedSize(); childSize = child->GetCachedSize();
childDescent = child->GetDescent(); childDescent = child->GetDescent();
//child->SetPosition(availableRect.GetPosition());
if (oldSize != child->GetCachedSize()) if (oldSize != child->GetCachedSize())
{ {
@@ -4999,7 +4994,6 @@ bool wxRichTextParagraph::Layout(wxDC& dc, wxRichTextDrawingContext& context, co
SetMinSize(marginRect.GetSize()); SetMinSize(marginRect.GetSize());
} }
#if wxRICHTEXT_USE_PARTIAL_TEXT_EXTENTS #if wxRICHTEXT_USE_PARTIAL_TEXT_EXTENTS
#if wxRICHTEXT_USE_OPTIMIZED_LINE_DRAWING #if wxRICHTEXT_USE_OPTIMIZED_LINE_DRAWING
// Use the text extents to calculate the size of each fragment in each line // Use the text extents to calculate the size of each fragment in each line
@@ -5177,7 +5171,6 @@ bool wxRichTextParagraph::GetRangeSize(const wxRichTextRange& range, wxSize& siz
wxRichTextObjectList::compatibility_iterator node = m_children.GetFirst(); wxRichTextObjectList::compatibility_iterator node = m_children.GetFirst();
while (node) while (node)
{ {
wxRichTextObject* child = node->GetData(); wxRichTextObject* child = node->GetData();
if (!child->GetRange().IsOutside(range)) if (!child->GetRange().IsOutside(range))
{ {
@@ -5203,7 +5196,7 @@ bool wxRichTextParagraph::GetRangeSize(const wxRichTextRange& range, wxSize& siz
rangeToUse.LimitTo(child->GetRange()); rangeToUse.LimitTo(child->GetRange());
int childDescent = 0; int childDescent = 0;
// At present wxRICHTEXT_HEIGHT_ONLY is only fast if we're already cached the size, // At present wxRICHTEXT_HEIGHT_ONLY is only fast if we've already cached the size,
// but it's only going to be used after caching has taken place. // but it's only going to be used after caching has taken place.
if ((flags & wxRICHTEXT_HEIGHT_ONLY) && child->GetCachedSize().y != 0) if ((flags & wxRICHTEXT_HEIGHT_ONLY) && child->GetCachedSize().y != 0)
{ {
@@ -5372,7 +5365,6 @@ bool wxRichTextParagraph::GetRangeSize(const wxRichTextRange& range, wxSize& siz
maxLineHeight = wxMax(maxLineHeight, (maxAscent + maxDescent)); maxLineHeight = wxMax(maxLineHeight, (maxAscent + maxDescent));
maxLineWidth += childSize.x; maxLineWidth += childSize.x;
} }
descent = wxMax(descent, childDescent);
} }
node2 = node2->GetNext(); node2 = node2->GetNext();
@@ -5511,7 +5503,11 @@ int wxRichTextParagraph::HitTest(wxDC& dc, wxRichTextDrawingContext& context, co
while (objNode) while (objNode)
{ {
wxRichTextObject* child = objNode->GetData(); wxRichTextObject* child = objNode->GetData();
if (child->IsTopLevel() && ((flags & wxRICHTEXT_HITTEST_NO_NESTED_OBJECTS) == 0)) // Don't recurse if we have wxRICHTEXT_HITTEST_NO_NESTED_OBJECTS,
// and also, if this seems composite but actually is marked as atomic,
// don't recurse.
if (child->IsTopLevel() && ((flags & wxRICHTEXT_HITTEST_NO_NESTED_OBJECTS) == 0) &&
(! (((flags & wxRICHTEXT_HITTEST_HONOUR_ATOMIC) != 0) && child->IsAtomic())))
{ {
{ {
int hitTest = child->HitTest(dc, context, pt, textPosition, obj, contextObj); int hitTest = child->HitTest(dc, context, pt, textPosition, obj, contextObj);
@@ -6506,8 +6502,8 @@ bool wxRichTextPlainText::DrawTabbedString(wxDC& dc, const wxRichTextAttr& attr,
x += w; x += w;
} }
return true;
return true;
} }
/// Lay the item out /// Lay the item out
@@ -6835,6 +6831,7 @@ IMPLEMENT_DYNAMIC_CLASS(wxRichTextBuffer, wxRichTextParagraphLayoutBox)
wxList wxRichTextBuffer::sm_handlers; wxList wxRichTextBuffer::sm_handlers;
wxList wxRichTextBuffer::sm_drawingHandlers; wxList wxRichTextBuffer::sm_drawingHandlers;
wxRichTextFieldTypeHashMap wxRichTextBuffer::sm_fieldTypes;
wxRichTextRenderer* wxRichTextBuffer::sm_renderer = NULL; wxRichTextRenderer* wxRichTextBuffer::sm_renderer = NULL;
int wxRichTextBuffer::sm_bulletRightMargin = 20; int wxRichTextBuffer::sm_bulletRightMargin = 20;
float wxRichTextBuffer::sm_bulletProportion = (float) 0.3; float wxRichTextBuffer::sm_bulletProportion = (float) 0.3;
@@ -7153,6 +7150,47 @@ wxRichTextObject* wxRichTextParagraphLayoutBox::InsertObjectWithUndo(wxRichTextB
return obj; return obj;
} }
wxRichTextField* wxRichTextParagraphLayoutBox::InsertFieldWithUndo(wxRichTextBuffer* buffer, long pos, const wxString& fieldType,
const wxRichTextProperties& properties,
wxRichTextCtrl* ctrl, int flags,
const wxRichTextAttr& textAttr)
{
wxRichTextAction* action = new wxRichTextAction(NULL, _("Insert Field"), wxRICHTEXT_INSERT, buffer, this, ctrl, false);
wxRichTextAttr* p = NULL;
wxRichTextAttr paraAttr;
if (flags & wxRICHTEXT_INSERT_WITH_PREVIOUS_PARAGRAPH_STYLE)
{
paraAttr = GetStyleForNewParagraph(buffer, pos);
if (!paraAttr.IsDefault())
p = & paraAttr;
}
wxRichTextAttr attr(buffer->GetDefaultStyle());
wxRichTextParagraph* newPara = new wxRichTextParagraph(this, & attr);
if (p)
newPara->SetAttributes(*p);
wxRichTextField* fieldObject = new wxRichTextField();
fieldObject->wxRichTextObject::SetProperties(properties);
fieldObject->SetFieldType(fieldType);
fieldObject->SetAttributes(textAttr);
newPara->AppendChild(fieldObject);
action->GetNewParagraphs().AppendChild(newPara);
action->GetNewParagraphs().UpdateRanges();
action->GetNewParagraphs().SetPartialParagraph(true);
action->SetPosition(pos);
// Set the range we'll need to delete in Undo
action->SetRange(wxRichTextRange(pos, pos));
buffer->SubmitAction(action);
wxRichTextField* obj = wxDynamicCast(GetLeafObjectAtPosition(pos), wxRichTextField);
return obj;
}
/// Get the style that is appropriate for a new paragraph at this position. /// Get the style that is appropriate for a new paragraph at this position.
/// If the previous paragraph has a paragraph style name, look up the next-paragraph /// If the previous paragraph has a paragraph style name, look up the next-paragraph
/// style. /// style.
@@ -8298,6 +8336,345 @@ bool wxRichTextBox::EditProperties(wxWindow* parent, wxRichTextBuffer* buffer)
return false; return false;
} }
/*!
* wxRichTextField
*/
IMPLEMENT_DYNAMIC_CLASS(wxRichTextField, wxRichTextParagraphLayoutBox)
wxRichTextField::wxRichTextField(const wxString& fieldType, wxRichTextObject* parent):
wxRichTextParagraphLayoutBox(parent)
{
SetFieldType(fieldType);
}
/// Draw the item
bool wxRichTextField::Draw(wxDC& dc, wxRichTextDrawingContext& context, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int descent, int style)
{
if (!IsShown())
return true;
wxRichTextFieldType* fieldType = wxRichTextBuffer::FindFieldType(GetFieldType());
if (fieldType && fieldType->Draw(this, dc, context, range, selection, rect, descent, style))
return true;
// Fallback; but don't draw guidelines.
style &= ~wxRICHTEXT_DRAW_GUIDELINES;
return wxRichTextParagraphLayoutBox::Draw(dc, context, range, selection, rect, descent, style);
}
bool wxRichTextField::Layout(wxDC& dc, wxRichTextDrawingContext& context, const wxRect& rect, const wxRect& parentRect, int style)
{
wxRichTextFieldType* fieldType = wxRichTextBuffer::FindFieldType(GetFieldType());
if (fieldType && fieldType->Layout(this, dc, context, rect, parentRect, style))
return true;
// Fallback
return wxRichTextParagraphLayoutBox::Layout(dc, context, rect, parentRect, style);
}
bool wxRichTextField::GetRangeSize(const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, wxRichTextDrawingContext& context, int flags, wxPoint position, wxArrayInt* partialExtents) const
{
wxRichTextFieldType* fieldType = wxRichTextBuffer::FindFieldType(GetFieldType());
if (fieldType)
return fieldType->GetRangeSize((wxRichTextField*) this, range, size, descent, dc, context, flags, position, partialExtents);
return wxRichTextParagraphLayoutBox::GetRangeSize(range, size, descent, dc, context, flags, position, partialExtents);
}
/// Calculate range
void wxRichTextField::CalculateRange(long start, long& end)
{
if (IsTopLevel())
wxRichTextParagraphLayoutBox::CalculateRange(start, end);
else
wxRichTextObject::CalculateRange(start, end);
}
/// Copy
void wxRichTextField::Copy(const wxRichTextField& obj)
{
wxRichTextParagraphLayoutBox::Copy(obj);
UpdateField();
}
// Edit properties via a GUI
bool wxRichTextField::EditProperties(wxWindow* parent, wxRichTextBuffer* buffer)
{
wxRichTextFieldType* fieldType = wxRichTextBuffer::FindFieldType(GetFieldType());
if (fieldType)
return fieldType->EditProperties(this, parent, buffer);
return false;
}
bool wxRichTextField::CanEditProperties() const
{
wxRichTextFieldType* fieldType = wxRichTextBuffer::FindFieldType(GetFieldType());
if (fieldType)
return fieldType->CanEditProperties((wxRichTextField*) this);
return false;
}
wxString wxRichTextField::GetPropertiesMenuLabel() const
{
wxRichTextFieldType* fieldType = wxRichTextBuffer::FindFieldType(GetFieldType());
if (fieldType)
return fieldType->GetPropertiesMenuLabel((wxRichTextField*) this);
return wxEmptyString;
}
bool wxRichTextField::UpdateField()
{
wxRichTextFieldType* fieldType = wxRichTextBuffer::FindFieldType(GetFieldType());
if (fieldType)
return fieldType->UpdateField((wxRichTextField*) this);
return false;
}
bool wxRichTextField::IsTopLevel() const
{
wxRichTextFieldType* fieldType = wxRichTextBuffer::FindFieldType(GetFieldType());
if (fieldType)
return fieldType->IsTopLevel((wxRichTextField*) this);
return true;
}
IMPLEMENT_CLASS(wxRichTextFieldType, wxObject)
IMPLEMENT_CLASS(wxRichTextFieldTypeStandard, wxRichTextFieldType)
wxRichTextFieldTypeStandard::wxRichTextFieldTypeStandard(const wxString& name, const wxString& label, int displayStyle)
{
Init();
SetName(name);
SetLabel(label);
SetDisplayStyle(displayStyle);
}
wxRichTextFieldTypeStandard::wxRichTextFieldTypeStandard(const wxString& name, const wxBitmap& bitmap, int displayStyle)
{
Init();
SetName(name);
SetBitmap(bitmap);
SetDisplayStyle(displayStyle);
}
void wxRichTextFieldTypeStandard::Init()
{
m_displayStyle = wxRICHTEXT_FIELD_STYLE_RECTANGLE;
m_font = wxFont(6, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL);
m_textColour = *wxWHITE;
m_borderColour = *wxBLACK;
m_backgroundColour = *wxBLACK;
m_verticalPadding = 1;
m_horizontalPadding = 3;
m_horizontalMargin = 2;
m_verticalMargin = 0;
}
void wxRichTextFieldTypeStandard::Copy(const wxRichTextFieldTypeStandard& field)
{
wxRichTextFieldType::Copy(field);
m_label = field.m_label;
m_displayStyle = field.m_displayStyle;
m_font = field.m_font;
m_textColour = field.m_textColour;
m_borderColour = field.m_borderColour;
m_backgroundColour = field.m_backgroundColour;
m_verticalPadding = field.m_verticalPadding;
m_horizontalPadding = field.m_horizontalPadding;
m_horizontalMargin = field.m_horizontalMargin;
m_bitmap = field.m_bitmap;
}
bool wxRichTextFieldTypeStandard::Draw(wxRichTextField* obj, wxDC& dc, wxRichTextDrawingContext& WXUNUSED(context), const wxRichTextRange& WXUNUSED(range), const wxRichTextSelection& selection, const wxRect& rect, int descent, int WXUNUSED(style))
{
if (m_displayStyle == wxRICHTEXT_FIELD_STYLE_COMPOSITE)
return false; // USe default composite drawing
else // if (m_displayStyle == wxRICHTEXT_FIELD_STYLE_RECTANGLE || m_displayStyle == wxRICHTEXT_FIELD_STYLE_NOBORDER)
{
int borderSize = 1;
wxPen borderPen(m_borderColour, 1, wxSOLID);
wxBrush backgroundBrush(m_backgroundColour);
wxColour textColour(m_textColour);
if (selection.WithinSelection(obj->GetRange().GetStart(), obj))
{
wxColour highlightColour(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT));
wxColour highlightTextColour(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT));
borderPen = wxPen(highlightTextColour, 1, wxSOLID);
backgroundBrush = wxBrush(highlightColour);
wxCheckSetBrush(dc, backgroundBrush);
wxCheckSetPen(dc, wxPen(highlightColour, 1, wxSOLID));
dc.DrawRectangle(rect);
}
if (m_displayStyle != wxRICHTEXT_FIELD_STYLE_NO_BORDER)
borderSize = 0;
// objectRect is the area where the content is drawn, after margins around it have been taken into account
wxRect objectRect = wxRect(wxPoint(rect.x + m_horizontalMargin, rect.y + wxMax(0, rect.height - descent - obj->GetCachedSize().y)),
wxSize(obj->GetCachedSize().x - 2*m_horizontalMargin - borderSize, obj->GetCachedSize().y));
// clientArea is where the text is actually written
wxRect clientArea = objectRect;
if (m_displayStyle == wxRICHTEXT_FIELD_STYLE_RECTANGLE)
{
dc.SetPen(borderPen);
dc.SetBrush(backgroundBrush);
dc.DrawRoundedRectangle(objectRect, 4.0);
}
else if (m_displayStyle == wxRICHTEXT_FIELD_STYLE_START_TAG)
{
int arrowLength = objectRect.height/2;
clientArea.width -= (arrowLength - m_horizontalPadding);
wxPoint pts[5];
pts[0].x = objectRect.x; pts[0].y = objectRect.y;
pts[1].x = objectRect.x + objectRect.width - arrowLength; pts[1].y = objectRect.y;
pts[2].x = objectRect.x + objectRect.width; pts[2].y = objectRect.y + (objectRect.height/2);
pts[3].x = objectRect.x + objectRect.width - arrowLength; pts[3].y = objectRect.y + objectRect.height;
pts[4].x = objectRect.x; pts[4].y = objectRect.y + objectRect.height;
dc.SetPen(borderPen);
dc.SetBrush(backgroundBrush);
dc.DrawPolygon(5, pts);
}
else if (m_displayStyle == wxRICHTEXT_FIELD_STYLE_END_TAG)
{
int arrowLength = objectRect.height/2;
clientArea.width -= (arrowLength - m_horizontalPadding);
clientArea.x += (arrowLength - m_horizontalPadding);
wxPoint pts[5];
pts[0].x = objectRect.x + objectRect.width; pts[0].y = objectRect.y;
pts[1].x = objectRect.x + arrowLength; pts[1].y = objectRect.y;
pts[2].x = objectRect.x; pts[2].y = objectRect.y + (objectRect.height/2);
pts[3].x = objectRect.x + arrowLength; pts[3].y = objectRect.y + objectRect.height;
pts[4].x = objectRect.x + objectRect.width; pts[4].y = objectRect.y + objectRect.height;
dc.SetPen(borderPen);
dc.SetBrush(backgroundBrush);
dc.DrawPolygon(5, pts);
}
if (m_bitmap.IsOk())
{
int x = clientArea.x + (clientArea.width - m_bitmap.GetWidth())/2;
int y = clientArea.y + m_verticalPadding;
dc.DrawBitmap(m_bitmap, x, y, true);
if (selection.WithinSelection(obj->GetRange().GetStart(), obj))
{
wxCheckSetBrush(dc, *wxBLACK_BRUSH);
wxCheckSetPen(dc, *wxBLACK_PEN);
dc.SetLogicalFunction(wxINVERT);
dc.DrawRectangle(wxRect(x, y, m_bitmap.GetWidth(), m_bitmap.GetHeight()));
dc.SetLogicalFunction(wxCOPY);
}
}
else
{
wxString label(m_label);
if (label.IsEmpty())
label = wxT("??");
int w, h, maxDescent;
dc.SetFont(m_font);
dc.GetTextExtent(m_label, & w, &h, & maxDescent);
dc.SetTextForeground(textColour);
int x = clientArea.x + (clientArea.width - w)/2;
int y = clientArea.y + (clientArea.height - (h - maxDescent))/2;
dc.DrawText(m_label, x, y);
}
}
return true;
}
bool wxRichTextFieldTypeStandard::Layout(wxRichTextField* obj, wxDC& dc, wxRichTextDrawingContext& context, const wxRect& WXUNUSED(rect), const wxRect& WXUNUSED(parentRect), int style)
{
if (m_displayStyle == wxRICHTEXT_FIELD_STYLE_COMPOSITE)
return false; // USe default composite layout
wxSize size = GetSize(obj, dc, context, style);
obj->SetCachedSize(size);
obj->SetMinSize(size);
obj->SetMaxSize(size);
return true;
}
bool wxRichTextFieldTypeStandard::GetRangeSize(wxRichTextField* obj, const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, wxRichTextDrawingContext& context, int flags, wxPoint position, wxArrayInt* partialExtents) const
{
if (IsTopLevel(obj))
return obj->wxRichTextParagraphLayoutBox::GetRangeSize(range, size, descent, dc, context, flags, position);
else
{
wxSize sz = GetSize(obj, dc, context, 0);
if (partialExtents)
{
int lastSize;
if (partialExtents->GetCount() > 0)
lastSize = (*partialExtents)[partialExtents->GetCount()-1];
else
lastSize = 0;
partialExtents->Add(lastSize + sz.x);
}
size = sz;
return true;
}
}
wxSize wxRichTextFieldTypeStandard::GetSize(wxRichTextField* WXUNUSED(obj), wxDC& dc, wxRichTextDrawingContext& WXUNUSED(context), int WXUNUSED(style)) const
{
int borderSize = 1;
int w = 0, h = 0, maxDescent = 0;
wxSize sz;
if (m_bitmap.IsOk())
{
w = m_bitmap.GetWidth();
h = m_bitmap.GetHeight();
sz = wxSize(w + m_horizontalMargin*2, h + m_verticalMargin*2);
}
else
{
wxString label(m_label);
if (label.IsEmpty())
label = wxT("??");
dc.SetFont(m_font);
dc.GetTextExtent(label, & w, &h, & maxDescent);
sz = wxSize(w + m_horizontalPadding*2 + m_horizontalMargin*2, h + m_verticalPadding *2 + m_verticalMargin*2);
}
if (m_displayStyle != wxRICHTEXT_FIELD_STYLE_NO_BORDER)
{
sz.x += borderSize*2;
sz.y += borderSize*2;
}
if (m_displayStyle == wxRICHTEXT_FIELD_STYLE_START_TAG || m_displayStyle == wxRICHTEXT_FIELD_STYLE_END_TAG)
{
// Add space for the arrow
sz.x += (sz.y/2 - m_horizontalPadding);
}
return sz;
}
IMPLEMENT_DYNAMIC_CLASS(wxRichTextCell, wxRichTextBox) IMPLEMENT_DYNAMIC_CLASS(wxRichTextCell, wxRichTextBox)
wxRichTextCell::wxRichTextCell(wxRichTextObject* parent): wxRichTextCell::wxRichTextCell(wxRichTextObject* parent):
@@ -8484,7 +8861,7 @@ bool wxRichTextTable::Layout(wxDC& dc, wxRichTextDrawingContext& context, const
wxArrayInt absoluteColWidths; wxArrayInt absoluteColWidths;
absoluteColWidths.Add(0, m_colCount); absoluteColWidths.Add(0, m_colCount);
// wxArrayInt absoluteColWidthsSpanning(m_colCount);
wxArrayInt percentageColWidths; wxArrayInt percentageColWidths;
percentageColWidths.Add(0, m_colCount); percentageColWidths.Add(0, m_colCount);
// wxArrayInt percentageColWidthsSpanning(m_colCount); // wxArrayInt percentageColWidthsSpanning(m_colCount);
@@ -9484,6 +9861,7 @@ public:
{ {
wxRichTextBuffer::CleanUpHandlers(); wxRichTextBuffer::CleanUpHandlers();
wxRichTextBuffer::CleanUpDrawingHandlers(); wxRichTextBuffer::CleanUpDrawingHandlers();
wxRichTextBuffer::CleanUpFieldTypes();
wxRichTextDecimalToRoman(-1); wxRichTextDecimalToRoman(-1);
wxRichTextParagraph::ClearDefaultTabs(); wxRichTextParagraph::ClearDefaultTabs();
wxRichTextCtrl::ClearAvailableFontNames(); wxRichTextCtrl::ClearAvailableFontNames();
@@ -9851,6 +10229,7 @@ bool wxRichTextAction::Undo()
container->DeleteRange(GetRange()); container->DeleteRange(GetRange());
container->UpdateRanges(); container->UpdateRanges();
// InvalidateHierarchy goes up the hierarchy as well as down, otherwise with a nested object, // InvalidateHierarchy goes up the hierarchy as well as down, otherwise with a nested object,
// Layout() would stop prematurely at the top level. // Layout() would stop prematurely at the top level.
container->InvalidateHierarchy(wxRichTextRange(GetRange().GetStart(), GetRange().GetStart())); container->InvalidateHierarchy(wxRichTextRange(GetRange().GetStart(), GetRange().GetStart()));
@@ -9882,6 +10261,7 @@ bool wxRichTextAction::Undo()
container->InsertFragment(GetRange().GetStart(), m_oldParagraphs); container->InsertFragment(GetRange().GetStart(), m_oldParagraphs);
container->UpdateRanges(); container->UpdateRanges();
// InvalidateHierarchy goes up the hierarchy as well as down, otherwise with a nested object, // InvalidateHierarchy goes up the hierarchy as well as down, otherwise with a nested object,
// Layout() would stop prematurely at the top level. // Layout() would stop prematurely at the top level.
container->InvalidateHierarchy(GetRange()); container->InvalidateHierarchy(GetRange());
@@ -11166,7 +11546,6 @@ void wxRichTextFontTable::Clear()
// wxTextBoxAttr // wxTextBoxAttr
void wxTextBoxAttr::Reset() void wxTextBoxAttr::Reset()
{ {
m_flags = 0; m_flags = 0;
@@ -12718,5 +13097,45 @@ void wxRichTextBuffer::CleanUpDrawingHandlers()
sm_drawingHandlers.Clear(); sm_drawingHandlers.Clear();
} }
void wxRichTextBuffer::AddFieldType(wxRichTextFieldType *fieldType)
{
sm_fieldTypes[fieldType->GetName()] = fieldType;
}
bool wxRichTextBuffer::RemoveFieldType(const wxString& name)
{
wxRichTextFieldTypeHashMap::iterator it = sm_fieldTypes.find(name);
if (it == sm_fieldTypes.end())
return false;
else
{
wxRichTextFieldType* fieldType = it->second;
sm_fieldTypes.erase(it);
delete fieldType;
return true;
}
}
wxRichTextFieldType *wxRichTextBuffer::FindFieldType(const wxString& name)
{
wxRichTextFieldTypeHashMap::iterator it = sm_fieldTypes.find(name);
if (it == sm_fieldTypes.end())
return NULL;
else
return it->second;
}
void wxRichTextBuffer::CleanUpFieldTypes()
{
wxRichTextFieldTypeHashMap::iterator it;
for( it = sm_fieldTypes.begin(); it != sm_fieldTypes.end(); ++it )
{
wxRichTextFieldType* fieldType = it->second;
delete fieldType;
}
sm_fieldTypes.clear();
}
#endif #endif
// wxUSE_RICHTEXT // wxUSE_RICHTEXT

View File

@@ -576,7 +576,7 @@ void wxRichTextCtrl::OnLeftClick(wxMouseEvent& event)
wxRichTextObject* hitObj = NULL; wxRichTextObject* hitObj = NULL;
wxRichTextObject* contextObj = NULL; wxRichTextObject* contextObj = NULL;
wxRichTextDrawingContext context(& GetBuffer()); wxRichTextDrawingContext context(& GetBuffer());
int hit = GetBuffer().HitTest(dc, context, event.GetLogicalPosition(dc), position, & hitObj, & contextObj); int hit = GetBuffer().HitTest(dc, context, event.GetLogicalPosition(dc), position, & hitObj, & contextObj, wxRICHTEXT_HITTEST_HONOUR_ATOMIC);
#if wxUSE_DRAG_AND_DROP #if wxUSE_DRAG_AND_DROP
// If there's no selection, or we're not inside it, this isn't an attempt to initiate Drag'n'Drop // If there's no selection, or we're not inside it, this isn't an attempt to initiate Drag'n'Drop
@@ -644,7 +644,7 @@ void wxRichTextCtrl::OnLeftUp(wxMouseEvent& event)
wxRichTextObject* contextObj = NULL; wxRichTextObject* contextObj = NULL;
wxRichTextDrawingContext context(& GetBuffer()); wxRichTextDrawingContext context(& GetBuffer());
// Only get objects at this level, not nested, because otherwise we couldn't swipe text at a single level. // Only get objects at this level, not nested, because otherwise we couldn't swipe text at a single level.
int hit = GetFocusObject()->HitTest(dc, context, logicalPt, position, & hitObj, & contextObj, wxRICHTEXT_HITTEST_NO_NESTED_OBJECTS); int hit = GetFocusObject()->HitTest(dc, context, logicalPt, position, & hitObj, & contextObj, wxRICHTEXT_HITTEST_NO_NESTED_OBJECTS|wxRICHTEXT_HITTEST_HONOUR_ATOMIC);
#if wxUSE_DRAG_AND_DROP #if wxUSE_DRAG_AND_DROP
if (m_preDrag) if (m_preDrag)
@@ -656,7 +656,7 @@ void wxRichTextCtrl::OnLeftUp(wxMouseEvent& event)
long position = 0; long position = 0;
wxRichTextObject* hitObj = NULL; wxRichTextObject* hitObj = NULL;
wxRichTextObject* contextObj = NULL; wxRichTextObject* contextObj = NULL;
int hit = GetBuffer().HitTest(dc, context, event.GetLogicalPosition(dc), position, & hitObj, & contextObj); int hit = GetBuffer().HitTest(dc, context, event.GetLogicalPosition(dc), position, & hitObj, & contextObj, wxRICHTEXT_HITTEST_HONOUR_ATOMIC);
wxRichTextParagraphLayoutBox* oldFocusObject = GetFocusObject(); wxRichTextParagraphLayoutBox* oldFocusObject = GetFocusObject();
wxRichTextParagraphLayoutBox* container = wxDynamicCast(contextObj, wxRichTextParagraphLayoutBox); wxRichTextParagraphLayoutBox* container = wxDynamicCast(contextObj, wxRichTextParagraphLayoutBox);
if (container && container != GetFocusObject() && container->AcceptsFocus()) if (container && container != GetFocusObject() && container->AcceptsFocus())
@@ -957,7 +957,7 @@ void wxRichTextCtrl::OnRightClick(wxMouseEvent& event)
wxRichTextObject* hitObj = NULL; wxRichTextObject* hitObj = NULL;
wxRichTextObject* contextObj = NULL; wxRichTextObject* contextObj = NULL;
wxRichTextDrawingContext context(& GetBuffer()); wxRichTextDrawingContext context(& GetBuffer());
int hit = GetFocusObject()->HitTest(dc, context, logicalPt, position, & hitObj, & contextObj); int hit = GetFocusObject()->HitTest(dc, context, logicalPt, position, & hitObj, & contextObj, wxRICHTEXT_HITTEST_HONOUR_ATOMIC);
if (hitObj && hitObj->GetContainer() != GetFocusObject()) if (hitObj && hitObj->GetContainer() != GetFocusObject())
{ {
@@ -1183,7 +1183,6 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event)
ScrollIntoView(m_caretPosition, WXK_LEFT); ScrollIntoView(m_caretPosition, WXK_LEFT);
// Always send this event; wxEVT_COMMAND_RICHTEXT_CONTENT_DELETED will be sent only if there is an actual deletion. // Always send this event; wxEVT_COMMAND_RICHTEXT_CONTENT_DELETED will be sent only if there is an actual deletion.
//if (deletions > 0)
{ {
wxRichTextEvent cmdEvent( wxRichTextEvent cmdEvent(
wxEVT_COMMAND_RICHTEXT_DELETE, wxEVT_COMMAND_RICHTEXT_DELETE,
@@ -1322,7 +1321,6 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event)
ScrollIntoView(m_caretPosition, WXK_LEFT); ScrollIntoView(m_caretPosition, WXK_LEFT);
// Always send this event; wxEVT_COMMAND_RICHTEXT_CONTENT_DELETED will be sent only if there is an actual deletion. // Always send this event; wxEVT_COMMAND_RICHTEXT_CONTENT_DELETED will be sent only if there is an actual deletion.
//if (deletions > 0)
{ {
wxRichTextEvent cmdEvent( wxRichTextEvent cmdEvent(
wxEVT_COMMAND_RICHTEXT_DELETE, wxEVT_COMMAND_RICHTEXT_DELETE,
@@ -1396,7 +1394,6 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event)
ScrollIntoView(m_caretPosition, WXK_LEFT); ScrollIntoView(m_caretPosition, WXK_LEFT);
// Always send this event; wxEVT_COMMAND_RICHTEXT_CONTENT_DELETED will be sent only if there is an actual deletion. // Always send this event; wxEVT_COMMAND_RICHTEXT_CONTENT_DELETED will be sent only if there is an actual deletion.
//if (deletions > 0)
{ {
wxRichTextEvent cmdEvent( wxRichTextEvent cmdEvent(
wxEVT_COMMAND_RICHTEXT_DELETE, wxEVT_COMMAND_RICHTEXT_DELETE,
@@ -2092,7 +2089,7 @@ bool wxRichTextCtrl::MoveDown(int noLines, int flags)
} }
wxRichTextParagraphLayoutBox* container = GetFocusObject(); wxRichTextParagraphLayoutBox* container = GetFocusObject();
int hitTestFlags = wxRICHTEXT_HITTEST_NO_NESTED_OBJECTS|wxRICHTEXT_HITTEST_NO_FLOATING_OBJECTS; int hitTestFlags = wxRICHTEXT_HITTEST_NO_NESTED_OBJECTS|wxRICHTEXT_HITTEST_NO_FLOATING_OBJECTS|wxRICHTEXT_HITTEST_HONOUR_ATOMIC;
if (notInThisObject) if (notInThisObject)
{ {
@@ -3004,6 +3001,13 @@ wxRichTextBox* wxRichTextCtrl::WriteTextBox(const wxRichTextAttr& textAttr)
return box; return box;
} }
wxRichTextField* wxRichTextCtrl::WriteField(const wxString& fieldType, const wxRichTextProperties& properties,
const wxRichTextAttr& textAttr)
{
return GetFocusObject()->InsertFieldWithUndo(& GetBuffer(), m_caretPosition+1, fieldType, properties,
this, wxRICHTEXT_INSERT_WITH_PREVIOUS_PARAGRAPH_STYLE, textAttr);
}
// Write a table at the current insertion point, returning the table. // Write a table at the current insertion point, returning the table.
wxRichTextTable* wxRichTextCtrl::WriteTable(int rows, int cols, const wxRichTextAttr& tableAttr, const wxRichTextAttr& cellAttr) wxRichTextTable* wxRichTextCtrl::WriteTable(int rows, int cols, const wxRichTextAttr& tableAttr, const wxRichTextAttr& cellAttr)
{ {
@@ -4576,7 +4580,6 @@ void wxRichTextCtrl::EnableVerticalScrollbar(bool enable)
SetupScrollbars(); SetupScrollbars();
} }
#if wxRICHTEXT_USE_OWN_CARET #if wxRICHTEXT_USE_OWN_CARET
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@@ -172,6 +172,8 @@ wxRichTextObject* wxRichTextXMLHandler::CreateObjectForXMLName(wxRichTextObject*
return new wxRichTextCell; return new wxRichTextCell;
else if (name == wxT("table")) else if (name == wxT("table"))
return new wxRichTextTable; return new wxRichTextTable;
else if (name == wxT("field"))
return new wxRichTextField;
else else
return NULL; return NULL;
} }
@@ -1085,6 +1087,7 @@ bool wxRichTextXMLHandler::ExportStyleDefinition(wxOutputStream& stream, wxRichT
OutputString(stream, wxT("</boxstyle>")); OutputString(stream, wxT("</boxstyle>"));
} }
WriteProperties(stream, def->GetProperties(), level);
return true; return true;
} }