- Fix WXK_MENU handling in wxStyledTextCtrl under wxGTK (cantabile).
- Added wxAcceleratorEntry::ToRawString() (Armel Asselin).
- Added wxDataViewEvent::SetDragFlags() and GetDropEffect() (Friedrich).
-
+- Added support for fields and virtual attributes to wxRichTextCtrl.
GTK:
class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextParagraph;
class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextFileHandler;
class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextDrawingHandler;
+class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextField;
+class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextFieldType;
class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextStyleSheet;
class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextListStyleDefinition;
class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextEvent;
wxRICHTEXT_HITTEST_NO_NESTED_OBJECTS = 0x20,
// 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
};
/**
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; }
+ /**
+ 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.
*/
wxRichTextAttr& GetAttributes() { return m_attributes; }
/**
- Sets the object's properties.
+ Returns the object's properties.
*/
wxRichTextProperties& GetProperties() { 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; }
*/
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.
*/
bool InsertImageWithUndo(wxRichTextBuffer* buffer, long pos, const wxRichTextImageBlock& imageBlock,
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.
If the previous paragraph has a paragraph style name, looks up the next-paragraph
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
*/
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.
*/
/// Drawing handlers
static wxList sm_drawingHandlers;
+ /// Field types
+ static wxRichTextFieldTypeHashMap sm_fieldTypes;
+
/// Renderer
static wxRichTextRenderer* sm_renderer;
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; }
/**
- Returns the name of the nandler.
+ Returns the name of the handler.
*/
wxString GetName() const { return m_name; }
@class wxRichTextDrawingHandler
The base class for custom drawing handlers.
- Currently, drawing handlers can provide virtual handlers.
+ Currently, drawing handlers can provide virtual attributes.
@library{wxrichtext}
@category{richtext}
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; }
/**
- Returns the name of the nandler.
+ Returns the name of the handler.
*/
wxString GetName() const { return m_name; }
*/
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.
You can then call SetFocusObject() to set the focus to the new object.
wxRICHTEXT_HITTEST_NO_NESTED_OBJECTS = 0x20,
// 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
};
/**
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; }
+ /**
+ 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.
*/
*/
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.
*/
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.
If the previous paragraph has a paragraph style name, looks up the next-paragraph
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
*/
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.
*/
/// Drawing handlers
static wxList sm_drawingHandlers;
+ /// Field types
+ static wxRichTextFieldTypeHashMap sm_fieldTypes;
+
/// Renderer
static wxRichTextRenderer* sm_renderer;
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; }
/**
- Returns the name of the nandler.
+ Returns the name of the handler.
*/
wxString GetName() const { return m_name; }
@class wxRichTextDrawingHandler
The base class for custom drawing handlers.
- Currently, drawing handlers can provide virtual handlers.
+ Currently, drawing handlers can provide virtual attributes.
@library{wxrichtext}
@category{richtext}
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; }
/**
- Returns the name of the nandler.
+ Returns the name of the handler.
*/
wxString GetName() const { return m_name; }
*/
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.
You can then call SetFocusObject() to set the focus to the new object.
buffer->GetRichTextCtrl()->PrepareContent(container);
}
-
/// Set character or paragraph properties
bool wxRichTextParagraphLayoutBox::SetProperties(const wxRichTextRange& range, const wxRichTextProperties& properties, int flags)
{
node = node->GetNext();
}
-
#endif
// Split up lines
wxRect oldAvailableRect = availableRect;
// 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
// [startY, endY]. So, we can't determine how wide the available
// space is until we know the exact line height.
lineAscent = wxMax(childSize.y-childDescent, maxAscent);
}
lineHeight = wxMax(lineHeight, (lineDescent + lineAscent));
-
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.
{
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 again using the minimum size
child->Invalidate(wxRICHTEXT_ALL);
attr, child->GetAttributes(), availableRect, parentRect, style);
childSize = child->GetCachedSize();
childDescent = child->GetDescent();
- //child->SetPosition(availableRect.GetPosition());
if (oldSize != child->GetCachedSize())
{
SetMinSize(marginRect.GetSize());
}
-
#if wxRICHTEXT_USE_PARTIAL_TEXT_EXTENTS
#if wxRICHTEXT_USE_OPTIMIZED_LINE_DRAWING
// Use the text extents to calculate the size of each fragment in each line
wxRichTextObjectList::compatibility_iterator node = m_children.GetFirst();
while (node)
{
-
wxRichTextObject* child = node->GetData();
if (!child->GetRange().IsOutside(range))
{
rangeToUse.LimitTo(child->GetRange());
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.
if ((flags & wxRICHTEXT_HEIGHT_ONLY) && child->GetCachedSize().y != 0)
{
maxLineHeight = wxMax(maxLineHeight, (maxAscent + maxDescent));
maxLineWidth += childSize.x;
}
- descent = wxMax(descent, childDescent);
}
node2 = node2->GetNext();
while (objNode)
{
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);
x += w;
}
- return true;
+ return true;
}
/// Lay the item out
IMPLEMENT_DYNAMIC_CLASS(wxRichTextBuffer, wxRichTextParagraphLayoutBox)
-wxList wxRichTextBuffer::sm_handlers;
-wxList wxRichTextBuffer::sm_drawingHandlers;
-wxRichTextRenderer* wxRichTextBuffer::sm_renderer = NULL;
-int wxRichTextBuffer::sm_bulletRightMargin = 20;
-float wxRichTextBuffer::sm_bulletProportion = (float) 0.3;
+wxList wxRichTextBuffer::sm_handlers;
+wxList wxRichTextBuffer::sm_drawingHandlers;
+wxRichTextFieldTypeHashMap wxRichTextBuffer::sm_fieldTypes;
+wxRichTextRenderer* wxRichTextBuffer::sm_renderer = NULL;
+int wxRichTextBuffer::sm_bulletRightMargin = 20;
+float wxRichTextBuffer::sm_bulletProportion = (float) 0.3;
/// Initialisation
void wxRichTextBuffer::Init()
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.
/// If the previous paragraph has a paragraph style name, look up the next-paragraph
/// style.
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)
wxRichTextCell::wxRichTextCell(wxRichTextObject* parent):
wxArrayInt absoluteColWidths;
absoluteColWidths.Add(0, m_colCount);
- // wxArrayInt absoluteColWidthsSpanning(m_colCount);
+
wxArrayInt percentageColWidths;
percentageColWidths.Add(0, m_colCount);
// wxArrayInt percentageColWidthsSpanning(m_colCount);
{
wxRichTextBuffer::CleanUpHandlers();
wxRichTextBuffer::CleanUpDrawingHandlers();
+ wxRichTextBuffer::CleanUpFieldTypes();
wxRichTextDecimalToRoman(-1);
wxRichTextParagraph::ClearDefaultTabs();
wxRichTextCtrl::ClearAvailableFontNames();
container->DeleteRange(GetRange());
container->UpdateRanges();
+
// InvalidateHierarchy goes up the hierarchy as well as down, otherwise with a nested object,
// Layout() would stop prematurely at the top level.
container->InvalidateHierarchy(wxRichTextRange(GetRange().GetStart(), GetRange().GetStart()));
container->InsertFragment(GetRange().GetStart(), m_oldParagraphs);
container->UpdateRanges();
+
// InvalidateHierarchy goes up the hierarchy as well as down, otherwise with a nested object,
// Layout() would stop prematurely at the top level.
container->InvalidateHierarchy(GetRange());
// wxTextBoxAttr
-
void wxTextBoxAttr::Reset()
{
m_flags = 0;
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
// wxUSE_RICHTEXT
wxRichTextObject* hitObj = NULL;
wxRichTextObject* contextObj = NULL;
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 there's no selection, or we're not inside it, this isn't an attempt to initiate Drag'n'Drop
wxRichTextObject* contextObj = NULL;
wxRichTextDrawingContext context(& GetBuffer());
// 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 (m_preDrag)
long position = 0;
wxRichTextObject* hitObj = 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* container = wxDynamicCast(contextObj, wxRichTextParagraphLayoutBox);
if (container && container != GetFocusObject() && container->AcceptsFocus())
wxRichTextObject* hitObj = NULL;
wxRichTextObject* contextObj = NULL;
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())
{
ScrollIntoView(m_caretPosition, WXK_LEFT);
// Always send this event; wxEVT_COMMAND_RICHTEXT_CONTENT_DELETED will be sent only if there is an actual deletion.
- //if (deletions > 0)
{
wxRichTextEvent cmdEvent(
wxEVT_COMMAND_RICHTEXT_DELETE,
ScrollIntoView(m_caretPosition, WXK_LEFT);
// Always send this event; wxEVT_COMMAND_RICHTEXT_CONTENT_DELETED will be sent only if there is an actual deletion.
- //if (deletions > 0)
{
wxRichTextEvent cmdEvent(
wxEVT_COMMAND_RICHTEXT_DELETE,
ScrollIntoView(m_caretPosition, WXK_LEFT);
// Always send this event; wxEVT_COMMAND_RICHTEXT_CONTENT_DELETED will be sent only if there is an actual deletion.
- //if (deletions > 0)
{
wxRichTextEvent cmdEvent(
wxEVT_COMMAND_RICHTEXT_DELETE,
}
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)
{
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.
wxRichTextTable* wxRichTextCtrl::WriteTable(int rows, int cols, const wxRichTextAttr& tableAttr, const wxRichTextAttr& cellAttr)
{
SetupScrollbars();
}
-
#if wxRICHTEXT_USE_OWN_CARET
// ----------------------------------------------------------------------------
return new wxRichTextCell;
else if (name == wxT("table"))
return new wxRichTextTable;
+ else if (name == wxT("field"))
+ return new wxRichTextField;
else
return NULL;
}
OutputString(stream, wxT("</boxstyle>"));
}
+ WriteProperties(stream, def->GetProperties(), level);
return true;
}