diff --git a/include/wx/richtext/richtextbackgroundpage.h b/include/wx/richtext/richtextbackgroundpage.h new file mode 100644 index 0000000000..f2b1cc8bd3 --- /dev/null +++ b/include/wx/richtext/richtextbackgroundpage.h @@ -0,0 +1,110 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: richtextbackgroundpage.h +// Purpose: +// Author: Julian Smart +// Modified by: +// Created: 13/11/2010 11:17:25 +// RCS-ID: +// Copyright: (c) Julian Smart +// Licence: +///////////////////////////////////////////////////////////////////////////// + +#ifndef _RICHTEXTBACKGROUNDPAGE_H_ +#define _RICHTEXTBACKGROUNDPAGE_H_ + +/*! + * Includes + */ + +#include "wx/richtext/richtextdialogpage.h" + +////@begin includes +#include "wx/statline.h" +////@end includes + +/*! + * Forward declarations + */ + +class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextColourSwatchCtrl; + +/*! + * Control identifiers + */ + +////@begin control identifiers +#define SYMBOL_WXRICHTEXTBACKGROUNDPAGE_STYLE wxTAB_TRAVERSAL +#define SYMBOL_WXRICHTEXTBACKGROUNDPAGE_TITLE wxEmptyString +#define SYMBOL_WXRICHTEXTBACKGROUNDPAGE_IDNAME ID_RICHTEXTBACKGROUNDPAGE +#define SYMBOL_WXRICHTEXTBACKGROUNDPAGE_SIZE wxSize(400, 300) +#define SYMBOL_WXRICHTEXTBACKGROUNDPAGE_POSITION wxDefaultPosition +////@end control identifiers + + +/*! + * wxRichTextBackgroundPage class declaration + */ + +class WXDLLIMPEXP_RICHTEXT wxRichTextBackgroundPage: public wxRichTextDialogPage +{ + DECLARE_DYNAMIC_CLASS( wxRichTextBackgroundPage ) + DECLARE_EVENT_TABLE() + DECLARE_HELP_PROVISION() + +public: + /// Constructors + wxRichTextBackgroundPage(); + wxRichTextBackgroundPage( wxWindow* parent, wxWindowID id = SYMBOL_WXRICHTEXTBACKGROUNDPAGE_IDNAME, const wxPoint& pos = SYMBOL_WXRICHTEXTBACKGROUNDPAGE_POSITION, const wxSize& size = SYMBOL_WXRICHTEXTBACKGROUNDPAGE_SIZE, long style = SYMBOL_WXRICHTEXTBACKGROUNDPAGE_STYLE ); + + /// Creation + bool Create( wxWindow* parent, wxWindowID id = SYMBOL_WXRICHTEXTBACKGROUNDPAGE_IDNAME, const wxPoint& pos = SYMBOL_WXRICHTEXTBACKGROUNDPAGE_POSITION, const wxSize& size = SYMBOL_WXRICHTEXTBACKGROUNDPAGE_SIZE, long style = SYMBOL_WXRICHTEXTBACKGROUNDPAGE_STYLE ); + + /// Destructor + ~wxRichTextBackgroundPage(); + + /// Initialises member variables + void Init(); + + /// Creates the controls and sizers + void CreateControls(); + + /// Gets the attributes from the formatting dialog + wxRichTextAttr* GetAttributes(); + + /// Data transfer + virtual bool TransferDataToWindow(); + virtual bool TransferDataFromWindow(); + + /// Respond to colour swatch click + void OnColourSwatch(wxCommandEvent& event); + +////@begin wxRichTextBackgroundPage event handler declarations + +////@end wxRichTextBackgroundPage event handler declarations + +////@begin wxRichTextBackgroundPage member function declarations + + /// Retrieves bitmap resources + wxBitmap GetBitmapResource( const wxString& name ); + + /// Retrieves icon resources + wxIcon GetIconResource( const wxString& name ); +////@end wxRichTextBackgroundPage member function declarations + + /// Should we show tooltips? + static bool ShowToolTips(); + +////@begin wxRichTextBackgroundPage member variables + wxCheckBox* m_backgroundColourCheckBox; + wxRichTextColourSwatchCtrl* m_backgroundColourSwatch; + /// Control identifiers + enum { + ID_RICHTEXTBACKGROUNDPAGE = 10845, + ID_RICHTEXT_BACKGROUND_COLOUR_CHECKBOX = 10846, + ID_RICHTEXT_BACKGROUND_COLOUR_SWATCH = 10847 + }; +////@end wxRichTextBackgroundPage member variables +}; + +#endif + // _RICHTEXTBACKGROUNDPAGE_H_ diff --git a/include/wx/richtext/richtextborderspage.h b/include/wx/richtext/richtextborderspage.h new file mode 100644 index 0000000000..4452d78921 --- /dev/null +++ b/include/wx/richtext/richtextborderspage.h @@ -0,0 +1,251 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: richtextborderspage.h +// Purpose: +// Author: Julian Smart +// Modified by: +// Created: 21/10/2010 11:34:24 +// RCS-ID: +// Copyright: (c) Julian Smart +// Licence: +///////////////////////////////////////////////////////////////////////////// + +#ifndef _RICHTEXTBORDERSPAGE_H_ +#define _RICHTEXTBORDERSPAGE_H_ + + +/*! + * Includes + */ + +#include "wx/richtext/richtextdialogpage.h" + +////@begin includes +#include "wx/notebook.h" +#include "wx/statline.h" +////@end includes + +/*! + * Forward declarations + */ + +class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextColourSwatchCtrl; +class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextBorderPreviewCtrl; + +/*! + * Control identifiers + */ + +////@begin control identifiers +#define SYMBOL_WXRICHTEXTBORDERSPAGE_STYLE wxTAB_TRAVERSAL +#define SYMBOL_WXRICHTEXTBORDERSPAGE_TITLE wxEmptyString +#define SYMBOL_WXRICHTEXTBORDERSPAGE_IDNAME ID_RICHTEXTBORDERSPAGE +#define SYMBOL_WXRICHTEXTBORDERSPAGE_SIZE wxSize(400, 300) +#define SYMBOL_WXRICHTEXTBORDERSPAGE_POSITION wxDefaultPosition +////@end control identifiers + + +/*! + * wxRichTextBordersPage class declaration + */ + +class WXDLLIMPEXP_RICHTEXT wxRichTextBordersPage: public wxRichTextDialogPage +{ + DECLARE_DYNAMIC_CLASS( wxRichTextBordersPage ) + DECLARE_EVENT_TABLE() + DECLARE_HELP_PROVISION() + +public: + /// Constructors + wxRichTextBordersPage(); + wxRichTextBordersPage( wxWindow* parent, wxWindowID id = SYMBOL_WXRICHTEXTBORDERSPAGE_IDNAME, const wxPoint& pos = SYMBOL_WXRICHTEXTBORDERSPAGE_POSITION, const wxSize& size = SYMBOL_WXRICHTEXTBORDERSPAGE_SIZE, long style = SYMBOL_WXRICHTEXTBORDERSPAGE_STYLE ); + + /// Creation + bool Create( wxWindow* parent, wxWindowID id = SYMBOL_WXRICHTEXTBORDERSPAGE_IDNAME, const wxPoint& pos = SYMBOL_WXRICHTEXTBORDERSPAGE_POSITION, const wxSize& size = SYMBOL_WXRICHTEXTBORDERSPAGE_SIZE, long style = SYMBOL_WXRICHTEXTBORDERSPAGE_STYLE ); + + /// Destructor + ~wxRichTextBordersPage(); + + /// Initialises member variables + void Init(); + + /// Creates the controls and sizers + void CreateControls(); + + /// Gets the attributes from the formatting dialog + wxRichTextAttr* GetAttributes(); + + /// Data transfer + virtual bool TransferDataToWindow(); + virtual bool TransferDataFromWindow(); + + /// Updates the preview + void OnCommand(wxCommandEvent& event); + + /// Fill style combo + virtual void FillStyleComboBox(wxComboBox* styleComboBox); + + /// Set the border controls + static void SetBorderValue(wxTextAttrBorder& border, /* wxTextAttrBorder& borderToReset, */ wxTextCtrl* widthValueCtrl, wxComboBox* widthUnitsCtrl, wxCheckBox* checkBox, + wxComboBox* styleCtrl, wxRichTextColourSwatchCtrl* colourCtrl, const wxArrayInt& borderStyles); + + /// Get data from the border controls + static void GetBorderValue(wxTextAttrBorder& border, /* wxTextAttrBorder& borderToReset, */ wxTextCtrl* widthValueCtrl, wxComboBox* widthUnitsCtrl, wxCheckBox* checkBox, + wxComboBox* styleCtrl, wxRichTextColourSwatchCtrl* colourCtrl, const wxArrayInt& borderStyles); + +////@begin wxRichTextBordersPage event handler declarations + + /// wxEVT_COMMAND_CHECKBOX_CLICKED event handler for ID_RICHTEXT_BORDER_LEFT_CHECKBOX + void OnRichtextBorderCheckboxClick( wxCommandEvent& event ); + + /// wxEVT_UPDATE_UI event handler for ID_RICHTEXT_BORDER_LEFT + void OnRichtextBorderLeftUpdate( wxUpdateUIEvent& event ); + + /// wxEVT_UPDATE_UI event handler for ID_RICHTEXT_BORDER_RIGHT + void OnRichtextBorderRightUpdate( wxUpdateUIEvent& event ); + + /// wxEVT_UPDATE_UI event handler for ID_RICHTEXT_BORDER_TOP + void OnRichtextBorderTopUpdate( wxUpdateUIEvent& event ); + + /// wxEVT_UPDATE_UI event handler for ID_RICHTEXT_BORDER_BOTTOM + void OnRichtextBorderBottomUpdate( wxUpdateUIEvent& event ); + + /// wxEVT_UPDATE_UI event handler for ID_RICHTEXT_OUTLINE_LEFT + void OnRichtextOutlineLeftUpdate( wxUpdateUIEvent& event ); + + /// wxEVT_UPDATE_UI event handler for ID_RICHTEXT_OUTLINE_RIGHT + void OnRichtextOutlineRightUpdate( wxUpdateUIEvent& event ); + + /// wxEVT_UPDATE_UI event handler for ID_RICHTEXT_OUTLINE_TOP + void OnRichtextOutlineTopUpdate( wxUpdateUIEvent& event ); + + /// wxEVT_UPDATE_UI event handler for ID_RICHTEXT_OUTLINE_BOTTOM + void OnRichtextOutlineBottomUpdate( wxUpdateUIEvent& event ); + +////@end wxRichTextBordersPage event handler declarations + +////@begin wxRichTextBordersPage member function declarations + + /// Retrieves bitmap resources + wxBitmap GetBitmapResource( const wxString& name ); + + /// Retrieves icon resources + wxIcon GetIconResource( const wxString& name ); +////@end wxRichTextBordersPage member function declarations + + /// Should we show tooltips? + static bool ShowToolTips(); + +////@begin wxRichTextBordersPage member variables + wxCheckBox* m_leftBorderCheckbox; + wxTextCtrl* m_leftBorderWidth; + wxComboBox* m_leftBorderWidthUnits; + wxComboBox* m_leftBorderStyle; + wxRichTextColourSwatchCtrl* m_leftBorderColour; + wxCheckBox* m_rightBorderCheckbox; + wxTextCtrl* m_rightBorderWidth; + wxComboBox* m_rightBorderWidthUnits; + wxComboBox* m_rightBorderStyle; + wxRichTextColourSwatchCtrl* m_rightBorderColour; + wxCheckBox* m_topBorderCheckbox; + wxTextCtrl* m_topBorderWidth; + wxComboBox* m_topBorderWidthUnits; + wxComboBox* m_topBorderStyle; + wxRichTextColourSwatchCtrl* m_topBorderColour; + wxCheckBox* m_bottomBorderCheckbox; + wxTextCtrl* m_bottomBorderWidth; + wxComboBox* m_bottomBorderWidthUnits; + wxComboBox* m_bottomBorderStyle; + wxRichTextColourSwatchCtrl* m_bottomBorderColour; + wxCheckBox* m_leftOutlineCheckbox; + wxTextCtrl* m_leftOutlineWidth; + wxComboBox* m_leftOutlineWidthUnits; + wxComboBox* m_leftOutlineStyle; + wxRichTextColourSwatchCtrl* m_leftOutlineColour; + wxCheckBox* m_rightOutlineCheckbox; + wxTextCtrl* m_rightOutlineWidth; + wxComboBox* m_rightOutlineWidthUnits; + wxComboBox* m_rightOutlineStyle; + wxRichTextColourSwatchCtrl* m_rightOutlineColour; + wxCheckBox* m_topOutlineCheckbox; + wxTextCtrl* m_topOutlineWidth; + wxComboBox* m_topOutlineWidthUnits; + wxComboBox* m_topOutlineStyle; + wxRichTextColourSwatchCtrl* m_topOutlineColour; + wxCheckBox* m_bottomOutlineCheckbox; + wxTextCtrl* m_bottomOutlineWidth; + wxComboBox* m_bottomOutlineWidthUnits; + wxComboBox* m_bottomOutlineStyle; + wxRichTextColourSwatchCtrl* m_bottomOutlineColour; + wxRichTextBorderPreviewCtrl* m_borderPreviewCtrl; + /// Control identifiers + enum { + ID_RICHTEXTBORDERSPAGE = 10800, + ID_RICHTEXTBORDERSPAGE_NOTEBOOK = 10801, + ID_RICHTEXTBORDERSPAGE_BORDERS = 10802, + ID_RICHTEXT_BORDER_LEFT_CHECKBOX = 10803, + ID_RICHTEXT_BORDER_LEFT = 10804, + ID_RICHTEXT_BORDER_LEFT_UNITS = 10805, + ID_RICHTEXT_BORDER_LEFT_STYLE = 10806, + ID_RICHTEXT_BORDER_LEFT_COLOUR = 10807, + ID_RICHTEXT_BORDER_RIGHT_CHECKBOX = 10808, + ID_RICHTEXT_BORDER_RIGHT = 10809, + ID_RICHTEXT_BORDER_RIGHT_UNITS = 10810, + ID_RICHTEXT_BORDER_RIGHT_STYLE = 10811, + ID_RICHTEXT_BORDER_RIGHT_COLOUR = 10812, + ID_RICHTEXT_BORDER_TOP_CHECKBOX = 10813, + ID_RICHTEXT_BORDER_TOP = 10814, + ID_RICHTEXT_BORDER_TOP_UNITS = 10815, + ID_RICHTEXT_BORDER_TOP_STYLE = 10816, + ID_RICHTEXT_BORDER_TOP_COLOUR = 10817, + ID_RICHTEXT_BORDER_BOTTOM_CHECKBOX = 10818, + ID_RICHTEXT_BORDER_BOTTOM = 10819, + ID_RICHTEXT_BORDER_BOTTOM_UNITS = 10820, + ID_RICHTEXT_BORDER_BOTTOM_STYLE = 10821, + ID_RICHTEXT_BORDER_BOTTOM_COLOUR = 10822, + ID_RICHTEXTBORDERSPAGE_OUTLINE = 10823, + ID_RICHTEXT_OUTLINE_LEFT_CHECKBOX = 10824, + ID_RICHTEXT_OUTLINE_LEFT = 10825, + ID_RICHTEXT_OUTLINE_LEFT_UNITS = 10826, + ID_RICHTEXT_OUTLINE_LEFT_STYLE = 10827, + ID_RICHTEXT_OUTLINE_LEFT_COLOUR = 10828, + ID_RICHTEXT_OUTLINE_RIGHT_CHECKBOX = 10829, + ID_RICHTEXT_OUTLINE_RIGHT = 10830, + ID_RICHTEXT_OUTLINE_RIGHT_UNITS = 10831, + ID_RICHTEXT_OUTLINE_RIGHT_STYLE = 10832, + ID_RICHTEXT_OUTLINE_RIGHT_COLOUR = 10833, + ID_RICHTEXT_OUTLINE_TOP_CHECKBOX = 10834, + ID_RICHTEXT_OUTLINE_TOP = 10835, + ID_RICHTEXT_OUTLINE_TOP_UNITS = 10836, + ID_RICHTEXT_OUTLINE_TOP_STYLE = 10837, + ID_RICHTEXT_OUTLINE_TOP_COLOUR = 10838, + ID_RICHTEXT_OUTLINE_BOTTOM_CHECKBOX = 10839, + ID_RICHTEXT_OUTLINE_BOTTOM = 10840, + ID_RICHTEXT_OUTLINE_BOTTOM_UNITS = 10841, + ID_RICHTEXT_OUTLINE_BOTTOM_STYLE = 10842, + ID_RICHTEXT_OUTLINE_BOTTOM_COLOUR = 10843, + ID_RICHTEXT_BORDER_PREVIEW = 10844 + }; +////@end wxRichTextBordersPage member variables + + wxArrayInt m_borderStyles; + wxArrayString m_borderStyleNames; + bool m_ignoreUpdates; +}; + +class WXDLLIMPEXP_RICHTEXT wxRichTextBorderPreviewCtrl : public wxWindow +{ +public: + wxRichTextBorderPreviewCtrl(wxWindow *parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& sz = wxDefaultSize, long style = 0); + + void SetAttributes(wxRichTextAttr* attr) { m_attributes = attr; } + wxRichTextAttr* GetAttributes() const { return m_attributes; } + +private: + wxRichTextAttr* m_attributes; + + void OnPaint(wxPaintEvent& event); + DECLARE_EVENT_TABLE() +}; + +#endif + // _RICHTEXTBORDERSPAGE_H_ diff --git a/include/wx/richtext/richtextbuffer.h b/include/wx/richtext/richtextbuffer.h index 0c80994a4d..c58edf7ce4 100644 --- a/include/wx/richtext/richtextbuffer.h +++ b/include/wx/richtext/richtextbuffer.h @@ -99,7 +99,7 @@ // Include the faster, direct implementation for output #define wxRICHTEXT_HAVE_DIRECT_OUTPUT 1 -/*! +/* * Special characters */ @@ -118,7 +118,7 @@ enum wxRichTextFileType wxRICHTEXT_TYPE_PDF }; -/*! +/* * Forward declarations */ @@ -136,6 +136,8 @@ class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextEvent; class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextRenderer; class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextBuffer; class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextXMLHandler; +class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextParagraphLayoutBox; +class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextImageBlock; class WXDLLIMPEXP_FWD_XML wxXmlNode; class wxRichTextFloatCollector; @@ -152,7 +154,7 @@ class wxRichTextFloatCollector; // the rect passed to Layout. #define wxRICHTEXT_LAYOUT_SPECIFIED_RECT 0x10 -/*! +/* * Flags to pass to Draw */ @@ -160,9 +162,12 @@ class wxRichTextFloatCollector; // where one line may be drawn higher (on the next page) compared // with the previous line #define wxRICHTEXT_DRAW_IGNORE_CACHE 0x01 +#define wxRICHTEXT_DRAW_SELECTED 0x02 +#define wxRICHTEXT_DRAW_PRINT 0x04 +#define wxRICHTEXT_DRAW_GUIDELINES 0x08 -/*! - * Flags returned from hit-testing +/* + * Flags returned from hit-testing, or passed to hit-test function. */ enum wxRichTextHitTestFlags { @@ -179,7 +184,10 @@ enum wxRichTextHitTestFlags wxRICHTEXT_HITTEST_ON = 0x08, // The point was on space outside content - wxRICHTEXT_HITTEST_OUTSIDE = 0x10 + wxRICHTEXT_HITTEST_OUTSIDE = 0x10, + + // Only do hit-testing at the current level (don't traverse into top-level objects) + wxRICHTEXT_HITTEST_NO_NESTED_OBJECTS = 0x20 }; /*! @@ -229,7 +237,7 @@ enum wxRichTextHitTestFlags #define wxRICHTEXT_SETSTYLE_REMOVE 0x80 /*! - * Flags for text insertion + * Flags for object insertion */ #define wxRICHTEXT_INSERT_NONE 0x00 @@ -249,19 +257,20 @@ enum wxRichTextHitTestFlags typedef unsigned short wxTextAttrDimensionFlags; -// Miscelaneous text box flags +// Miscellaneous text box flags enum wxTextBoxAttrFlags { wxTEXT_BOX_ATTR_FLOAT = 0x00000001, wxTEXT_BOX_ATTR_CLEAR = 0x00000002, - wxTEXT_BOX_ATTR_COLLAPSE_BORDERS = 0x00000004 + wxTEXT_BOX_ATTR_COLLAPSE_BORDERS = 0x00000004, + wxTEXT_BOX_ATTR_VERTICAL_ALIGNMENT = 0x00000004 }; // Whether a value is present, used in dimension flags enum wxTextAttrValueFlags { - wxTEXT_ATTR_VALUE_PRESENT = 0x1000, - wxTEXT_ATTR_VALUE_PRESENT_MASK = 0x1000 + wxTEXT_ATTR_VALUE_VALID = 0x1000, + wxTEXT_ATTR_VALUE_VALID_MASK = 0x1000 }; // Units - included in the dimension value @@ -279,7 +288,7 @@ enum wxTextAttrUnits enum wxTextBoxAttrPosition { wxTEXT_BOX_ATTR_POSITION_STATIC = 0x0000, // Default is static, i.e. as per normal layout - wxTEXT_BOX_ATTR_POSITION_RELATIVE = 0x0010, + wxTEXT_BOX_ATTR_POSITION_RELATIVE = 0x0010, // Relative to the relevant edge wxTEXT_BOX_ATTR_POSITION_ABSOLUTE = 0x0020, wxTEXT_BOX_ATTR_POSITION_MASK = 0x00F0 @@ -290,8 +299,8 @@ class WXDLLIMPEXP_RICHTEXT wxTextAttrDimension { public: wxTextAttrDimension() { Reset(); } - wxTextAttrDimension(int value, wxTextAttrDimensionFlags flags = wxTEXT_ATTR_VALUE_PRESENT|wxTEXT_ATTR_UNITS_TENTHS_MM) { m_value = value; m_flags = flags; } - + wxTextAttrDimension(int value, wxTextAttrUnits units = wxTEXT_ATTR_UNITS_TENTHS_MM) { m_value = value; m_flags = units|wxTEXT_ATTR_VALUE_VALID; } + void Reset() { m_value = 0; m_flags = 0; } // Partial equality test @@ -305,26 +314,27 @@ public: void CollectCommonAttributes(const wxTextAttrDimension& attr, wxTextAttrDimension& clashingAttr, wxTextAttrDimension& absentAttr); bool operator==(const wxTextAttrDimension& dim) const { return m_value == dim.m_value && m_flags == dim.m_flags; } - + int GetValue() const { return m_value; } float GetValueMM() const { return float(m_value) / 10.0; } - void SetValueMM(float value) { m_value = (int) ((value * 10.0) + 0.5); m_flags |= wxTEXT_ATTR_VALUE_PRESENT; } - void SetValue(int value) { m_value = value; m_flags |= wxTEXT_ATTR_VALUE_PRESENT; } - void SetValue(int value, wxTextAttrDimensionFlags flags) { m_value = value; m_flags = flags; } + void SetValueMM(float value) { m_value = (int) ((value * 10.0) + 0.5); m_flags |= wxTEXT_ATTR_VALUE_VALID; } + void SetValue(int value) { m_value = value; m_flags |= wxTEXT_ATTR_VALUE_VALID; } + void SetValue(int value, wxTextAttrDimensionFlags flags) { SetValue(value); m_flags = flags; } + void SetValue(int value, wxTextAttrUnits units) { m_value = value; m_flags = units | wxTEXT_ATTR_VALUE_VALID; } void SetValue(const wxTextAttrDimension& dim) { (*this) = dim; } - + wxTextAttrUnits GetUnits() const { return (wxTextAttrUnits) (m_flags & wxTEXT_ATTR_UNITS_MASK); } void SetUnits(wxTextAttrUnits units) { m_flags &= ~wxTEXT_ATTR_UNITS_MASK; m_flags |= units; } - + wxTextBoxAttrPosition GetPosition() const { return (wxTextBoxAttrPosition) (m_flags & wxTEXT_BOX_ATTR_POSITION_MASK); } void SetPosition(wxTextBoxAttrPosition pos) { m_flags &= ~wxTEXT_BOX_ATTR_POSITION_MASK; m_flags |= pos; } - - bool IsPresent() const { return (m_flags & wxTEXT_ATTR_VALUE_PRESENT) != 0; } - void SetPresent(bool b) { m_flags &= ~wxTEXT_ATTR_VALUE_PRESENT_MASK; m_flags |= (b ? wxTEXT_ATTR_VALUE_PRESENT : 0); } - + + bool IsValid() const { return (m_flags & wxTEXT_ATTR_VALUE_VALID) != 0; } + void SetValid(bool b) { m_flags &= ~wxTEXT_ATTR_VALUE_VALID_MASK; m_flags |= (b ? wxTEXT_ATTR_VALUE_VALID : 0); } + wxTextAttrDimensionFlags GetFlags() const { return m_flags; } void SetFlags(wxTextAttrDimensionFlags flags) { m_flags = flags; } - + int m_value; wxTextAttrDimensionFlags m_flags; }; @@ -333,10 +343,12 @@ public: class WXDLLIMPEXP_RICHTEXT wxTextAttrDimensions { public: + wxTextAttrDimensions() {} + void Reset() { m_left.Reset(); m_top.Reset(); m_right.Reset(); m_bottom.Reset(); } - + bool operator==(const wxTextAttrDimensions& dims) const { return m_left == dims.m_left && m_top == dims.m_top && m_right == dims.m_right && m_bottom == dims.m_bottom; } - + // Partial equality test bool EqPartial(const wxTextAttrDimensions& dims) const; @@ -368,13 +380,56 @@ public: wxTextAttrDimension m_bottom; }; +// A class for width and height +class WXDLLIMPEXP_RICHTEXT wxTextAttrSize +{ +public: + wxTextAttrSize() {} + + void Reset() { m_width.Reset(); m_height.Reset(); } + + bool operator==(const wxTextAttrSize& size) const { return m_width == size.m_width && m_height == size.m_height ; } + + // Partial equality test + bool EqPartial(const wxTextAttrSize& dims) const; + + // Apply border to 'this', but not if the same as compareWith + bool Apply(const wxTextAttrSize& dims, const wxTextAttrSize* compareWith = NULL); + + // Collects the attributes that are common to a range of content, building up a note of + // which attributes are absent in some objects and which clash in some objects. + void CollectCommonAttributes(const wxTextAttrSize& attr, wxTextAttrSize& clashingAttr, wxTextAttrSize& absentAttr); + + // Remove specified attributes from this object + bool RemoveStyle(const wxTextAttrSize& attr); + + // Width and height + + wxTextAttrDimension& GetWidth() { return m_width; } + const wxTextAttrDimension& GetWidth() const { return m_width; } + + void SetWidth(int value, wxTextAttrDimensionFlags flags) { m_width.SetValue(value, flags); } + void SetWidth(int value, wxTextAttrUnits units) { m_width.SetValue(value, units); } + void SetWidth(const wxTextAttrDimension& dim) { m_width.SetValue(dim); } + + wxTextAttrDimension& GetHeight() { return m_height; } + const wxTextAttrDimension& GetHeight() const { return m_height; } + + void SetHeight(int value, wxTextAttrDimensionFlags flags) { m_height.SetValue(value, flags); } + void SetHeight(int value, wxTextAttrUnits units) { m_height.SetValue(value, units); } + void SetHeight(const wxTextAttrDimension& dim) { m_height.SetValue(dim); } + + wxTextAttrDimension m_width; + wxTextAttrDimension m_height; +}; + // A class to make it easier to convert dimensions class WXDLLIMPEXP_RICHTEXT wxTextAttrDimensionConverter { public: wxTextAttrDimensionConverter(wxDC& dc, double scale = 1.0, const wxSize& parentSize = wxDefaultSize); wxTextAttrDimensionConverter(int ppi, double scale = 1.0, const wxSize& parentSize = wxDefaultSize); - + int GetPixels(const wxTextAttrDimension& dim, int direction = wxHORIZONTAL) const; int GetTenthsMM(const wxTextAttrDimension& dim) const; @@ -439,12 +494,21 @@ enum wxTextBoxAttrCollapseMode wxTEXT_BOX_ATTR_COLLAPSE_FULL = 1 }; +// Vertical alignment values +enum wxTextBoxAttrVerticalAlignment +{ + wxTEXT_BOX_ATTR_VERTICAL_ALIGNMENT_NONE = 0, + wxTEXT_BOX_ATTR_VERTICAL_ALIGNMENT_TOP = 1, + wxTEXT_BOX_ATTR_VERTICAL_ALIGNMENT_CENTRE = 2, + wxTEXT_BOX_ATTR_VERTICAL_ALIGNMENT_BOTTOM = 3 +}; + // Border class WXDLLIMPEXP_RICHTEXT wxTextAttrBorder { public: wxTextAttrBorder() { Reset(); } - + bool operator==(const wxTextAttrBorder& border) const { return m_flags == border.m_flags && m_borderStyle == border.m_borderStyle && @@ -477,13 +541,15 @@ public: wxTextAttrDimension& GetWidth() { return m_borderWidth; } const wxTextAttrDimension& GetWidth() const { return m_borderWidth; } void SetWidth(const wxTextAttrDimension& width) { m_borderWidth = width; } + void SetWidth(int value, wxTextAttrUnits units = wxTEXT_ATTR_UNITS_TENTHS_MM) { SetWidth(wxTextAttrDimension(value, units)); } bool HasStyle() const { return (m_flags & wxTEXT_BOX_ATTR_BORDER_STYLE) != 0; } bool HasColour() const { return (m_flags & wxTEXT_BOX_ATTR_BORDER_COLOUR) != 0; } - bool HasWidth() const { return m_borderWidth.IsPresent(); } - - bool IsValid() const { return HasStyle() && HasColour() && HasWidth(); } - + bool HasWidth() const { return m_borderWidth.IsValid(); } + + bool IsValid() const { return HasWidth(); } + void MakeValid() { m_borderWidth.SetValid(true); } + int GetFlags() const { return m_flags; } void SetFlags(int flags) { m_flags = flags; } void AddFlag(int flag) { m_flags |= flag; } @@ -516,7 +582,8 @@ public: // Set width of all borders void SetWidth(const wxTextAttrDimension& width); - + void SetWidth(int value, wxTextAttrUnits units = wxTEXT_ATTR_UNITS_TENTHS_MM) { SetWidth(wxTextAttrDimension(value, units)); } + // Reset void Reset() { m_left.Reset(); m_right.Reset(); m_top.Reset(); m_bottom.Reset(); } @@ -532,21 +599,21 @@ public: // Collects the attributes that are common to a range of content, building up a note of // which attributes are absent in some objects and which clash in some objects. void CollectCommonAttributes(const wxTextAttrBorders& attr, wxTextAttrBorders& clashingAttr, wxTextAttrBorders& absentAttr); - - bool HasBorder() const { return m_left.IsValid() || m_right.IsValid() || m_top.IsValid() || m_bottom.IsValid(); } + + bool IsValid() const { return m_left.IsValid() || m_right.IsValid() || m_top.IsValid() || m_bottom.IsValid(); } const wxTextAttrBorder& GetLeft() const { return m_left; } wxTextAttrBorder& GetLeft() { return m_left; } - + const wxTextAttrBorder& GetRight() const { return m_right; } wxTextAttrBorder& GetRight() { return m_right; } - + const wxTextAttrBorder& GetTop() const { return m_top; } wxTextAttrBorder& GetTop() { return m_top; } - + const wxTextAttrBorder& GetBottom() const { return m_bottom; } wxTextAttrBorder& GetBottom() { return m_bottom; } - + wxTextAttrBorder m_left, m_right, m_top, m_bottom; }; @@ -562,10 +629,10 @@ public: wxTextBoxAttr() { Init(); } wxTextBoxAttr(const wxTextBoxAttr& attr) { Init(); (*this) = attr; } - // Initialise this object. + /// Initialise this object. void Init() { Reset(); } - // Reset this object. + /// Reset this object. void Reset(); // Copy. Unnecessary since we let it do a binary copy @@ -574,169 +641,213 @@ public: // Assignment //void operator= (const wxTextBoxAttr& attr); - // Equality test + /// Equality test bool operator== (const wxTextBoxAttr& attr) const; - // Partial equality test + /// Partial equality test, ignoring unset attributes. bool EqPartial(const wxTextBoxAttr& attr) const; - // Merges the given attributes. If compareWith - // is non-NULL, then it will be used to mask out those attributes that are the same in style - // and compareWith, for situations where we don't want to explicitly set inherited attributes. + /// Merges the given attributes. If compareWith + /// is non-NULL, then it will be used to mask out those attributes that are the same in style + /// and compareWith, for situations where we don't want to explicitly set inherited attributes. bool Apply(const wxTextBoxAttr& style, const wxTextBoxAttr* compareWith = NULL); - - // Collects the attributes that are common to a range of content, building up a note of - // which attributes are absent in some objects and which clash in some objects. + + /// Collects the attributes that are common to a range of content, building up a note of + /// which attributes are absent in some objects and which clash in some objects. void CollectCommonAttributes(const wxTextBoxAttr& attr, wxTextBoxAttr& clashingAttr, wxTextBoxAttr& absentAttr); - // Remove specified attributes from this object + /// Removes the specified attributes from this object bool RemoveStyle(const wxTextBoxAttr& attr); - // Set flags + /// Sets the flags. void SetFlags(int flags) { m_flags = flags; } - // Get flags + /// Returns the flags. int GetFlags() const { return m_flags; } - // Is this flag present? + /// Is this flag present? bool HasFlag(wxTextBoxAttrFlags flag) const { return (m_flags & flag) != 0; } - // Remove this flag + /// Remove this flag void RemoveFlag(wxTextBoxAttrFlags flag) { m_flags &= ~flag; } - // Add this flag + /// Add this flag void AddFlag(wxTextBoxAttrFlags flag) { m_flags |= flag; } - // Is this default? I.e. no flags set + /// Is this default? I.e. no attributes set. bool IsDefault() const; - // Float mode - short int GetFloatMode() const { return m_floatMode; } - void SetFloatMode(short int mode) { m_floatMode = mode; m_flags |= wxTEXT_BOX_ATTR_FLOAT; } + /// Get the float mode. + wxTextBoxAttrFloatStyle GetFloatMode() const { return m_floatMode; } + + /// Set the float mode. + void SetFloatMode(wxTextBoxAttrFloatStyle mode) { m_floatMode = mode; m_flags |= wxTEXT_BOX_ATTR_FLOAT; } + + /// Do we have a float mode? bool HasFloatMode() const { return HasFlag(wxTEXT_BOX_ATTR_FLOAT); } + + /// Is this object floating? bool IsFloating() const { return HasFloatMode() && GetFloatMode() != wxTEXT_BOX_ATTR_FLOAT_NONE; } - // Whether to wrap text after object - short int GetClearMode() const { return m_clearMode; } - void SetClearMode(short int mode) { m_clearMode = mode; m_flags |= wxTEXT_BOX_ATTR_CLEAR; } + /// Returns the clear mode - whether to wrap text after object. Currently unimplemented. + wxTextBoxAttrClearStyle GetClearMode() const { return m_clearMode; } + + /// Set the clear mode. Currently unimplemented. + void SetClearMode(wxTextBoxAttrClearStyle mode) { m_clearMode = mode; m_flags |= wxTEXT_BOX_ATTR_CLEAR; } + + /// Do we have a clear mode? bool HasClearMode() const { return HasFlag(wxTEXT_BOX_ATTR_CLEAR); } - // Whether to collapse borders - int GetCollapseBorders() const { return m_collapseMode ; } - void SetCollapseBorders(int collapse) { m_collapseMode = collapse; m_flags |= wxTEXT_BOX_ATTR_COLLAPSE_BORDERS; } + /// Returns the collapse mode - whether to collapse borders. Currently unimplemented. + wxTextBoxAttrCollapseMode GetCollapseBorders() const { return m_collapseMode; } + + /// Sets the collapse mode - whether to collapse borders. Currently unimplemented. + void SetCollapseBorders(wxTextBoxAttrCollapseMode collapse) { m_collapseMode = collapse; m_flags |= wxTEXT_BOX_ATTR_COLLAPSE_BORDERS; } + + /// Do we have a collapse borders flag? bool HasCollapseBorders() const { return HasFlag(wxTEXT_BOX_ATTR_COLLAPSE_BORDERS); } - - // Margins - + + /// Returns the vertical alignment. + wxTextBoxAttrVerticalAlignment GetVerticalAlignment() const { return m_verticalAlignment; } + + /// Set the vertical alignment. + void SetVerticalAlignment(wxTextBoxAttrVerticalAlignment verticalAlignment) { m_verticalAlignment = verticalAlignment; m_flags |= wxTEXT_BOX_ATTR_VERTICAL_ALIGNMENT; } + + /// Do we have a vertical alignment flag? + bool HasVerticalAlignment() const { return HasFlag(wxTEXT_BOX_ATTR_VERTICAL_ALIGNMENT); } + + /// Gets the margin values. wxTextAttrDimensions& GetMargins() { return m_margins; } const wxTextAttrDimensions& GetMargins() const { return m_margins; } + /// Gets the left margin. wxTextAttrDimension& GetLeftMargin() { return m_margins.m_left; } const wxTextAttrDimension& GetLeftMargin() const { return m_margins.m_left; } + /// Gets the right margin. wxTextAttrDimension& GetRightMargin() { return m_margins.m_right; } const wxTextAttrDimension& GetRightMargin() const { return m_margins.m_right; } + /// Gets the top margin. wxTextAttrDimension& GetTopMargin() { return m_margins.m_top; } const wxTextAttrDimension& GetTopMargin() const { return m_margins.m_top; } - + + /// Gets the bottom margin. wxTextAttrDimension& GetBottomMargin() { return m_margins.m_bottom; } const wxTextAttrDimension& GetBottomMargin() const { return m_margins.m_bottom; } - // Position - + /// Returns the position. wxTextAttrDimensions& GetPosition() { return m_position; } const wxTextAttrDimensions& GetPosition() const { return m_position; } + /// Returns the left position. wxTextAttrDimension& GetLeft() { return m_position.m_left; } const wxTextAttrDimension& GetLeft() const { return m_position.m_left; } + /// Returns the right position. wxTextAttrDimension& GetRight() { return m_position.m_right; } const wxTextAttrDimension& GetRight() const { return m_position.m_right; } + /// Returns the top position. wxTextAttrDimension& GetTop() { return m_position.m_top; } const wxTextAttrDimension& GetTop() const { return m_position.m_top; } - + + /// Returns the bottom position. wxTextAttrDimension& GetBottom() { return m_position.m_bottom; } const wxTextAttrDimension& GetBottom() const { return m_position.m_bottom; } - // Padding - + /// Returns the padding values. wxTextAttrDimensions& GetPadding() { return m_padding; } const wxTextAttrDimensions& GetPadding() const { return m_padding; } + /// Returns the left padding value. wxTextAttrDimension& GetLeftPadding() { return m_padding.m_left; } const wxTextAttrDimension& GetLeftPadding() const { return m_padding.m_left; } - + + /// Returns the right padding value. wxTextAttrDimension& GetRightPadding() { return m_padding.m_right; } const wxTextAttrDimension& GetRightPadding() const { return m_padding.m_right; } - + + /// Returns the top padding value. wxTextAttrDimension& GetTopPadding() { return m_padding.m_top; } const wxTextAttrDimension& GetTopPadding() const { return m_padding.m_top; } + /// Returns the bottom padding value. wxTextAttrDimension& GetBottomPadding() { return m_padding.m_bottom; } const wxTextAttrDimension& GetBottomPadding() const { return m_padding.m_bottom; } - - // Border + /// Returns the borders. wxTextAttrBorders& GetBorder() { return m_border; } const wxTextAttrBorders& GetBorder() const { return m_border; } + /// Returns the left border. wxTextAttrBorder& GetLeftBorder() { return m_border.m_left; } const wxTextAttrBorder& GetLeftBorder() const { return m_border.m_left; } + /// Returns the top border. wxTextAttrBorder& GetTopBorder() { return m_border.m_top; } const wxTextAttrBorder& GetTopBorder() const { return m_border.m_top; } + /// Returns the right border. wxTextAttrBorder& GetRightBorder() { return m_border.m_right; } const wxTextAttrBorder& GetRightBorder() const { return m_border.m_right; } + /// Returns the bottom border. wxTextAttrBorder& GetBottomBorder() { return m_border.m_bottom; } const wxTextAttrBorder& GetBottomBorder() const { return m_border.m_bottom; } - - // Outline + /// Returns the outline. wxTextAttrBorders& GetOutline() { return m_outline; } const wxTextAttrBorders& GetOutline() const { return m_outline; } + /// Returns the left outline. wxTextAttrBorder& GetLeftOutline() { return m_outline.m_left; } const wxTextAttrBorder& GetLeftOutline() const { return m_outline.m_left; } + /// Returns the top outline. wxTextAttrBorder& GetTopOutline() { return m_outline.m_top; } const wxTextAttrBorder& GetTopOutline() const { return m_outline.m_top; } + /// Returns the right outline. wxTextAttrBorder& GetRightOutline() { return m_outline.m_right; } const wxTextAttrBorder& GetRightOutline() const { return m_outline.m_right; } + /// Returns the bottom outline. wxTextAttrBorder& GetBottomOutline() { return m_outline.m_bottom; } const wxTextAttrBorder& GetBottomOutline() const { return m_outline.m_bottom; } + /// Returns the object size. + wxTextAttrSize& GetSize() { return m_size; } + const wxTextAttrSize& GetSize() const { return m_size; } - // Width and height - - wxTextAttrDimension& GetWidth() { return m_width; } - const wxTextAttrDimension& GetWidth() const { return m_width; } + /// Sets the object size. + void SetSize(const wxTextAttrSize& sz) { m_size = sz; } - wxTextAttrDimension& GetHeight() { return m_height; } - const wxTextAttrDimension& GetHeight() const { return m_height; } + /// Returns the object width. + wxTextAttrDimension& GetWidth() { return m_size.m_width; } + const wxTextAttrDimension& GetWidth() const { return m_size.m_width; } + + /// Returns the object height. + wxTextAttrDimension& GetHeight() { return m_size.m_height; } + const wxTextAttrDimension& GetHeight() const { return m_size.m_height; } public: - int m_flags; - - wxTextAttrDimensions m_margins; - wxTextAttrDimensions m_padding; - wxTextAttrDimensions m_position; + int m_flags; - wxTextAttrDimension m_width; - wxTextAttrDimension m_height; + wxTextAttrDimensions m_margins; + wxTextAttrDimensions m_padding; + wxTextAttrDimensions m_position; - wxTextAttrBorders m_border; - wxTextAttrBorders m_outline; + wxTextAttrSize m_size; - short int m_floatMode; - short int m_clearMode; - short int m_collapseMode; + wxTextAttrBorders m_border; + wxTextAttrBorders m_outline; + + wxTextBoxAttrFloatStyle m_floatMode; + wxTextBoxAttrClearStyle m_clearMode; + wxTextBoxAttrCollapseMode m_collapseMode; + wxTextBoxAttrVerticalAlignment m_verticalAlignment; }; // ---------------------------------------------------------------------------- @@ -747,16 +858,16 @@ class WXDLLIMPEXP_RICHTEXT wxRichTextAttr: public wxTextAttr { public: wxRichTextAttr(const wxTextAttr& attr) { wxTextAttr::Copy(attr); } - wxRichTextAttr(const wxRichTextAttr& attr) : wxTextAttr() { Copy(attr); } + wxRichTextAttr(const wxRichTextAttr& attr): wxTextAttr() { Copy(attr); } wxRichTextAttr() {} - + // Copy void Copy(const wxRichTextAttr& attr); - + // Assignment void operator=(const wxRichTextAttr& attr) { Copy(attr); } void operator=(const wxTextAttr& attr) { wxTextAttr::Copy(attr); } - + // Equality test bool operator==(const wxRichTextAttr& attr) const; @@ -778,7 +889,7 @@ public: wxTextBoxAttr& GetTextBoxAttr() { return m_textBoxAttr; } const wxTextBoxAttr& GetTextBoxAttr() const { return m_textBoxAttr; } void SetTextBoxAttr(const wxTextBoxAttr& attr) { m_textBoxAttr = attr; } - + wxTextBoxAttr m_textBoxAttr; }; @@ -793,7 +904,7 @@ class WXDLLIMPEXP_RICHTEXT wxRichTextProperties: public wxObject DECLARE_DYNAMIC_CLASS(wxRichTextProperties) public: wxRichTextProperties() {} - wxRichTextProperties(const wxRichTextProperties& props) : wxObject() { Copy(props); } + wxRichTextProperties(const wxRichTextProperties& props): wxObject() { Copy(props); } void operator=(const wxRichTextProperties& props) { Copy(props); } bool operator==(const wxRichTextProperties& props) const; @@ -922,9 +1033,100 @@ protected: long m_end; }; +WX_DECLARE_USER_EXPORTED_OBJARRAY(wxRichTextRange, wxRichTextRangeArray, WXDLLIMPEXP_RICHTEXT); + #define wxRICHTEXT_ALL wxRichTextRange(-2, -2) #define wxRICHTEXT_NONE wxRichTextRange(-1, -1) +// ---------------------------------------------------------------------------- +// wxRichTextSelection: stores selection information +// ---------------------------------------------------------------------------- + +#define wxRICHTEXT_NO_SELECTION wxRichTextRange(-2, -2) + +class WXDLLIMPEXP_RICHTEXT wxRichTextSelection +{ +public: + wxRichTextSelection(const wxRichTextSelection& sel) { Copy(sel); } + wxRichTextSelection(const wxRichTextRange& range, wxRichTextParagraphLayoutBox* container) { m_ranges.Add(range); m_container = container; } + wxRichTextSelection() { Reset(); } + + /// Reset the selection + void Reset() { m_ranges.Clear(); m_container = NULL; } + + /// Set the selection + void Set(const wxRichTextRange& range, wxRichTextParagraphLayoutBox* container) + { m_ranges.Clear(); m_ranges.Add(range); m_container = container; } + + /// Add a selection + void Add(const wxRichTextRange& range) + { m_ranges.Add(range); } + + /// Set the selections + void Set(const wxRichTextRangeArray& ranges, wxRichTextParagraphLayoutBox* container) + { m_ranges = ranges; m_container = container; } + + /// Copy + void Copy(const wxRichTextSelection& sel) + { m_ranges = sel.m_ranges; m_container = sel.m_container; } + + /// Assignment + void operator=(const wxRichTextSelection& sel) { Copy(sel); } + + /// Equality test + bool operator==(const wxRichTextSelection& sel) const; + + /// Index operator + wxRichTextRange operator[](size_t i) const { return GetRange(i); } + + /// Get the selection ranges + wxRichTextRangeArray& GetRanges() { return m_ranges; } + const wxRichTextRangeArray& GetRanges() const { return m_ranges; } + + /// Set the selection ranges + void SetRanges(const wxRichTextRangeArray& ranges) { m_ranges = ranges; } + + /// Get the number of ranges in the selection + size_t GetCount() const { return m_ranges.GetCount(); } + + /// Get the given range + wxRichTextRange GetRange(size_t i) const { return m_ranges[i]; } + + /// Get the first range if there is one, otherwise wxRICHTEXT_NO_SELECTION. + wxRichTextRange GetRange() const { return (m_ranges.GetCount() > 0) ? (m_ranges[0]) : wxRICHTEXT_NO_SELECTION; } + + /// Set a single range. + void SetRange(const wxRichTextRange& range) { m_ranges.Clear(); m_ranges.Add(range); } + + /// Get the container for which the selection is valid + wxRichTextParagraphLayoutBox* GetContainer() const { return m_container; } + + /// Set the container for which the selection is valid + void SetContainer(wxRichTextParagraphLayoutBox* container) { m_container = container; } + + /// Is the selection valid? + bool IsValid() const { return m_ranges.GetCount() > 0 && GetContainer(); } + + /// Get the selection appropriate to the specified object, if any; returns an empty array if none + /// at the level of the object's container. + wxRichTextRangeArray GetSelectionForObject(wxRichTextObject* obj) const; + + /// Is the given position within the selection? + bool WithinSelection(long pos, wxRichTextObject* obj) const; + + /// Is the given position within the selection? + bool WithinSelection(long pos) const { return WithinSelection(pos, m_ranges); } + + /// Is the given position within the selection range? + static bool WithinSelection(long pos, const wxRichTextRangeArray& ranges); + + /// Is the given range within the selection range? + static bool WithinSelection(const wxRichTextRange& range, const wxRichTextRangeArray& ranges); + + wxRichTextRangeArray m_ranges; + wxRichTextParagraphLayoutBox* m_container; +}; + /*! * wxRichTextObject class declaration * This is the base for drawable objects. @@ -943,15 +1145,18 @@ public: /// 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(wxDC& dc, const wxRichTextRange& range, const wxRichTextRange& selectionRange, const wxRect& rect, int descent, int style) = 0; + virtual bool Draw(wxDC& dc, 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. virtual bool Layout(wxDC& dc, const wxRect& rect, int style) = 0; /// Hit-testing: returns a flag indicating hit test details, plus - /// information about position - virtual int HitTest(wxDC& WXUNUSED(dc), const wxPoint& WXUNUSED(pt), long& WXUNUSED(textPosition)) { return false; } + /// information about position. contextObj is returned to specify what object + /// position is relevant to, since otherwise there's an ambiguity. + /// obj may not a child of contextObj, since we may be referring to the container itself + /// if we have no hit on a child - for example if we click outside an object. + virtual int HitTest(wxDC& dc, const wxPoint& pt, long& textPosition, wxRichTextObject** obj, wxRichTextObject** contextObj, int flags = 0); /// Finds the absolute position and row height for the given character position virtual bool FindPosition(wxDC& WXUNUSED(dc), long WXUNUSED(index), wxPoint& WXUNUSED(pt), int* WXUNUSED(height), bool WXUNUSED(forceLineStart)) { return false; } @@ -961,8 +1166,11 @@ public: /// the text. For a longer string, it might use the parent width for example. virtual wxSize GetBestSize() const { return m_size; } - /// Get the object size for the given range. Returns false if the range - /// is invalid for this object. + /** + Gets the object size for the given range. Returns false if the range + is invalid for this object. + */ + virtual bool GetRangeSize(const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, int flags, wxPoint position = wxPoint(0,0), wxArrayInt* partialExtents = NULL) const = 0; /// Do a split, returning an object containing the second part, and setting @@ -1009,9 +1217,17 @@ public: /// Edit properties via a GUI virtual bool EditProperties(wxWindow* WXUNUSED(parent), wxRichTextBuffer* WXUNUSED(buffer)) { return false; } + /// Return the label to be used for the properties context menu item. + virtual wxString GetPropertiesMenuLabel() const { return wxEmptyString; } + + /// Returns true if objects of this class can accept the focus, i.e. a call to SetFocusObject + /// is possible. For example, containers supporting text, such as a text box object, can accept the focus, + /// but a table can't (set the focus to individual cells instead). + virtual bool AcceptsFocus() const { return false; } + #if wxUSE_XML /// Import this object from XML - virtual bool ImportFromXML(wxRichTextBuffer* buffer, wxXmlNode* node, wxRichTextXMLHandler* handler); + virtual bool ImportFromXML(wxRichTextBuffer* buffer, wxXmlNode* node, wxRichTextXMLHandler* handler, bool* recurse); #endif #if wxRICHTEXT_HAVE_DIRECT_OUTPUT @@ -1026,20 +1242,49 @@ public: /// Does this object take note of paragraph attributes? Text and image objects don't. virtual bool UsesParagraphAttributes() const { return true; } - + /// What is the XML node name of this object? virtual wxString GetXMLNodeName() const { return wxT("unknown"); } + /// Invalidate the buffer. With no argument, invalidates whole buffer. + virtual void Invalidate(const wxRichTextRange& invalidRange = wxRICHTEXT_ALL); + + /// Can this object handle the selections of its children? FOr example, a table. + virtual bool HandlesChildSelections() const { return false; } + + /// Returns a selection object specifying the selections between start and end character positions. + /// For example, a table would deduce what cells (of range length 1) are selected when dragging across the table. + virtual wxRichTextSelection GetSelection(long WXUNUSED(start), long WXUNUSED(end)) const { return wxRichTextSelection(); } + // Accessors /// Get/set the cached object size as calculated by Layout. virtual wxSize GetCachedSize() const { return m_size; } virtual void SetCachedSize(const wxSize& sz) { m_size = sz; } + /// Get/set the maximum object size as calculated by Layout. This allows + /// us to fit an object to its contents or allocate extra space if required. + virtual wxSize GetMaxSize() const { return m_maxSize; } + virtual void SetMaxSize(const wxSize& sz) { m_maxSize = sz; } + + /// Get/set the minimum object size as calculated by Layout. This allows + /// us to constrain an object to its absolute minimum size if necessary. + virtual wxSize GetMinSize() const { return m_minSize; } + virtual void SetMinSize(const wxSize& sz) { m_minSize = sz; } + + /// Get the 'natural' size for an object. For an image, it would be the + /// image size. + virtual wxTextAttrSize GetNaturalSize() const { return wxTextAttrSize(); } + /// Get/set the object position virtual wxPoint GetPosition() const { return m_pos; } virtual void SetPosition(const wxPoint& pos) { m_pos = pos; } + /// Get the absolute object position, by traversing up the child/parent hierarchy + /// TODO: may not be needed, if all object positions are in fact relative to the + /// top of the coordinate space. + virtual wxPoint GetAbsolutePosition() const; + /// Get the rectangle enclosing the object virtual wxRect GetRect() const { return wxRect(GetPosition(), GetCachedSize()); } @@ -1050,9 +1295,15 @@ public: const wxRichTextRange& GetRange() const { return m_range; } wxRichTextRange& GetRange() { return m_range; } - /// Get/set dirty flag (whether the object needs Layout to be called) - virtual bool GetDirty() const { return m_dirty; } - virtual void SetDirty(bool dirty) { m_dirty = dirty; } + /// Set the 'own' range, for a top-level object with its own position space + void SetOwnRange(const wxRichTextRange& range) { m_ownRange = range; } + + /// Get own range (valid if top-level) + const wxRichTextRange& GetOwnRange() const { return m_ownRange; } + wxRichTextRange& GetOwnRange() { return m_ownRange; } + + /// Get own range only if a top-level object + wxRichTextRange GetOwnRangeIfTopLevel() const { return IsTopLevel() ? m_ownRange : m_range; } /// Is this composite? virtual bool IsComposite() const { return false; } @@ -1061,19 +1312,37 @@ public: virtual wxRichTextObject* GetParent() const { return m_parent; } virtual void SetParent(wxRichTextObject* parent) { m_parent = parent; } - /// Set the margin around the object + /// Get/set the top-level container of this object. + /// May return itself if it's a container; use GetParentContainer to return + /// a different container. + virtual wxRichTextParagraphLayoutBox* GetContainer() const; + + /// Get/set the top-level container of this object. + /// Returns a different container than itself, unless there's no parent, in which case it will return NULL. + virtual wxRichTextParagraphLayoutBox* GetParentContainer() const { return GetParent() ? GetParent()->GetContainer() : GetContainer(); } + + /// Set the margin around the object, in pixels virtual void SetMargins(int margin); virtual void SetMargins(int leftMargin, int rightMargin, int topMargin, int bottomMargin); - virtual int GetLeftMargin() const { return m_leftMargin; } - virtual int GetRightMargin() const { return m_rightMargin; } - virtual int GetTopMargin() const { return m_topMargin; } - virtual int GetBottomMargin() const { return m_bottomMargin; } + virtual int GetLeftMargin() const; + virtual int GetRightMargin() const; + virtual int GetTopMargin() const; + virtual int GetBottomMargin() const; + + /// Calculate the available content space in the given rectangle, given the + /// margins, border and padding specified in the object's attributes. + virtual wxRect GetAvailableContentArea(wxDC& dc, const wxRect& outerRect) const; + + /// 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 + virtual bool LayoutToBestSize(wxDC& dc, wxRichTextBuffer* buffer, + const wxRichTextAttr& parentAttr, const wxRichTextAttr& attr, const wxRect& availableParentSpace, int style); /// Set/get attributes object void SetAttributes(const wxRichTextAttr& attr) { m_attributes = attr; } const wxRichTextAttr& GetAttributes() const { return m_attributes; } wxRichTextAttr& GetAttributes() { return m_attributes; } - + /// Set/get properties wxRichTextProperties& GetProperties() { return m_properties; } const wxRichTextProperties& GetProperties() const { return m_properties; } @@ -1086,8 +1355,24 @@ public: /// Gets the containing buffer wxRichTextBuffer* GetBuffer() const; + /// Sets the identifying name for this object, as a property. + void SetName(const wxString& name) { m_properties.SetProperty(wxT("name"), name); } + + /// Gets the identifying name for this object. + wxString GetName() const { return m_properties.GetPropertyString(wxT("name")); } + + /// Is this object top-level, i.e. with its own paragraphs, such as a text box? + virtual bool IsTopLevel() const { return false; } + + /// Returns @true if the object will be shown, @false otherwise. + bool IsShown() const { return m_show; } + // Operations + /// Call to show or hide this object. This function does not cause the content to be + /// laid out or redrawn. + virtual void Show(bool show) { m_show = show; } + /// Clone the object virtual wxRichTextObject* Clone() const { return NULL; } @@ -1099,6 +1384,9 @@ public: void Reference() { m_refCount ++; } void Dereference(); + /// Move the object recursively, by adding the offset from old to new + virtual void Move(const wxPoint& pt); + /// Convert units in tenths of a millimetre to device units int ConvertTenthsMMToPixels(wxDC& dc, int units) const; static int ConvertTenthsMMToPixels(int ppi, int units, double scale = 1.0); @@ -1106,41 +1394,47 @@ public: /// Convert units in pixels to tenths of a millimetre int ConvertPixelsToTenthsMM(wxDC& dc, int pixels) const; static int ConvertPixelsToTenthsMM(int ppi, int pixels, double scale = 1.0); - + /// Draw the borders and background for the given rectangle and attributes. - /// Width and height are taken to be the content size, so excluding any - /// border, margin and padding. - static bool DrawBoxAttributes(wxDC& dc, const wxRichTextAttr& attr, const wxRect& boxRect); + /// Width and height are taken to be the outer margin size, not the content. + static bool DrawBoxAttributes(wxDC& dc, wxRichTextBuffer* buffer, const wxRichTextAttr& attr, const wxRect& boxRect, int flags = 0); /// Draw a border - static bool DrawBorder(wxDC& dc, const wxTextAttrBorders& attr, const wxRect& rect); + static bool DrawBorder(wxDC& dc, wxRichTextBuffer* buffer, const wxTextAttrBorders& attr, const wxRect& rect, int flags = 0); /// Get the various rectangles of the box model in pixels. You can either specify contentRect (inner) /// or marginRect (outer), and the other must be the default rectangle (no width or height). /// Note that the outline doesn't affect the position of the rectangle, it's drawn in whatever space /// is available. - static bool GetBoxRects(wxDC& dc, const wxRichTextAttr& attr, wxRect& marginRect, wxRect& borderRect, wxRect& contentRect, wxRect& paddingRect, wxRect& outlineRect); + static bool GetBoxRects(wxDC& dc, wxRichTextBuffer* buffer, const wxRichTextAttr& attr, wxRect& marginRect, wxRect& borderRect, wxRect& contentRect, wxRect& paddingRect, wxRect& outlineRect); + + /// Get the total margin for the object in pixels, taking into account margin, padding and border size + static bool GetTotalMargin(wxDC& dc, wxRichTextBuffer* buffer, const wxRichTextAttr& attr, int& leftMargin, int& rightMargin, + int& topMargin, int& bottomMargin); + + /// Returns the rectangle which the child has available to it given restrictions specified in the + /// child attribute, e.g. 50% width of the parent, 400 pixels, x position 20% of the parent, etc. + static wxRect AdjustAvailableSpace(wxDC& dc, wxRichTextBuffer* buffer, const wxRichTextAttr& parentAttr, const wxRichTextAttr& childAttr, const wxRect& availableParentSpace); protected: wxSize m_size; + wxSize m_maxSize; + wxSize m_minSize; wxPoint m_pos; int m_descent; // Descent for this object (if any) - bool m_dirty; int m_refCount; + bool m_show; wxRichTextObject* m_parent; /// The range of this object (start position to end position) wxRichTextRange m_range; - /// Margins - int m_leftMargin; - int m_rightMargin; - int m_topMargin; - int m_bottomMargin; + /// The internal range of this object, if it's a top-level object with its own range space + wxRichTextRange m_ownRange; /// Attributes wxRichTextAttr m_attributes; - + /// Properties wxRichTextProperties m_properties; }; @@ -1165,7 +1459,7 @@ public: /// Hit-testing: returns a flag indicating hit test details, plus /// information about position - virtual int HitTest(wxDC& dc, const wxPoint& pt, long& textPosition); + virtual int HitTest(wxDC& dc, const wxPoint& pt, long& textPosition, wxRichTextObject** obj, wxRichTextObject** contextObj, int flags = 0); /// Finds the absolute position and row height for the given character position virtual bool FindPosition(wxDC& dc, long index, wxPoint& pt, int* height, bool forceLineStart); @@ -1179,9 +1473,16 @@ public: /// Get any text in this object for the given range virtual wxString GetTextForRange(const wxRichTextRange& range) const; + /// Gets the object size for the given range. Returns false if the range + /// is invalid for this object. + virtual bool GetRangeSize(const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, int flags, wxPoint position = wxPoint(0,0), wxArrayInt* partialExtents = NULL) const; + /// Dump to output stream for debugging virtual void Dump(wxTextOutputStream& stream); + /// Invalidate the buffer. With no argument, invalidates whole buffer. + virtual void Invalidate(const wxRichTextRange& invalidRange = wxRICHTEXT_ALL); + // Accessors /// Get the children @@ -1194,16 +1495,15 @@ public: /// Get the nth child wxRichTextObject* GetChild(size_t n) const ; - /// Get/set dirty flag - virtual bool GetDirty() const { return m_dirty; } - virtual void SetDirty(bool dirty) { m_dirty = dirty; } - /// Is this composite? virtual bool IsComposite() const { return true; } /// Returns true if the buffer is empty virtual bool IsEmpty() const { return GetChildCount() == 0; } + /// Get the child object at the given character position + virtual wxRichTextObject* GetChildAtPosition(long pos) const; + // Operations /// Copy @@ -1227,6 +1527,9 @@ public: /// Recursively merge all pieces that can be merged. bool Defragment(const wxRichTextRange& range = wxRICHTEXT_ALL); + /// Move the object recursively, by adding the offset from old to new + virtual void Move(const wxPoint& pt); + protected: wxRichTextObjectList m_children; }; @@ -1250,15 +1553,15 @@ public: /// Hit-testing: returns a flag indicating hit test details, plus /// information about position - virtual int HitTest(wxDC& dc, const wxPoint& pt, long& textPosition); + virtual int HitTest(wxDC& dc, const wxPoint& pt, long& textPosition, wxRichTextObject** obj, wxRichTextObject** contextObj, int flags = 0); /// Draw the item - virtual bool Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextRange& selectionRange, const wxRect& rect, int descent, int style); + virtual bool Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int descent, int style); /// Lay the item out virtual bool Layout(wxDC& dc, const wxRect& rect, int style); - /// Get/set the object size for the given range. Returns false if the range + /// Gets the object size for the given range. Returns false if the range /// is invalid for this object. virtual bool GetRangeSize(const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, int flags, wxPoint position = wxPoint(0,0), wxArrayInt* partialExtents = NULL) const; @@ -1270,7 +1573,7 @@ public: #if wxUSE_XML /// Import this object from XML - virtual bool ImportFromXML(wxRichTextBuffer* buffer, wxXmlNode* node, wxRichTextXMLHandler* handler); + virtual bool ImportFromXML(wxRichTextBuffer* buffer, wxXmlNode* node, wxRichTextXMLHandler* handler, bool* recurse); #endif #if wxRICHTEXT_HAVE_DIRECT_OUTPUT @@ -1286,6 +1589,11 @@ public: /// What is the XML node name of this object? virtual wxString GetXMLNodeName() const { return wxT("paragraphlayout"); } + /// Returns true if objects of this class can accept the focus, i.e. a call to SetFocusObject + /// is possible. For example, containers supporting text, such as a text box object, can accept the focus, + /// but a table can't (set the focus to individual cells instead). + virtual bool AcceptsFocus() const { return true; } + // Accessors /// Associate a control with the buffer, for operations that for example require refreshing the window. @@ -1298,13 +1606,41 @@ public: void SetPartialParagraph(bool partialPara) { m_partialParagraph = partialPara; } bool GetPartialParagraph() const { return m_partialParagraph; } - /// If this is a buffer, returns the current style sheet. The base layout box - /// class doesn't have an associated style sheet. - virtual wxRichTextStyleSheet* GetStyleSheet() const { return NULL; } + /// Returns the style sheet associated with the overall buffer. + virtual wxRichTextStyleSheet* GetStyleSheet() const; + + /// Is this object top-level, i.e. with its own paragraphs, such as a text box? + virtual bool IsTopLevel() const { return true; } // Operations + + /// Submit command to insert paragraphs + bool InsertParagraphsWithUndo(long pos, const wxRichTextParagraphLayoutBox& paragraphs, wxRichTextCtrl* ctrl, wxRichTextBuffer* buffer, int flags = 0); + + /// Submit command to insert the given text + bool InsertTextWithUndo(long pos, const wxString& text, wxRichTextCtrl* ctrl, wxRichTextBuffer* buffer, int flags = 0); + + /// Submit command to insert the given text + bool InsertNewlineWithUndo(long pos, wxRichTextCtrl* ctrl, wxRichTextBuffer* buffer, int flags = 0); + + /// Submit command to insert the given image + bool InsertImageWithUndo(long pos, const wxRichTextImageBlock& imageBlock, + wxRichTextCtrl* ctrl, wxRichTextBuffer* buffer, int flags, + const wxRichTextAttr& textAttr); + + /// 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. + wxRichTextAttr GetStyleForNewParagraph(wxRichTextBuffer* buffer, long pos, bool caretPosition = false, bool lookUpNewParaStyle=false) const; + + /// Insert an object. + wxRichTextObject* InsertObjectWithUndo(long pos, wxRichTextObject *object, wxRichTextCtrl* ctrl, wxRichTextBuffer* buffer, int flags = 0); + + /// Submit command to delete this range + bool DeleteRangeWithUndo(const wxRichTextRange& range, wxRichTextCtrl* ctrl, wxRichTextBuffer* buffer); + /// Draw the floats of this buffer - void DrawFloats(wxDC& dc, const wxRichTextRange& range, const wxRichTextRange& selectionRange, const wxRect& rect, int descent, int style); + void DrawFloats(wxDC& dc, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int descent, int style); /// Move an anchored object to another paragraph void MoveAnchoredObjectToParagraph(wxRichTextParagraph* from, wxRichTextParagraph* to, wxRichTextObject* obj); @@ -1351,7 +1687,7 @@ public: virtual wxRichTextLine* GetLineForVisibleLineNumber(long lineNumber) const; /// Get the leaf object in a paragraph at this position. - /// Given a line number, get the corresponding wxRichTextLine object. + /// Given a position, get the corresponding wxRichTextLine object. virtual wxRichTextObject* GetLeafObjectAtPosition(long position) const; /// Get the paragraph by number @@ -1381,10 +1717,10 @@ public: /// Set text attributes: character and/or paragraph styles. virtual bool SetStyle(const wxRichTextRange& range, const wxRichTextAttr& style, int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO); - /// Set image attribute - void SetImageStyle(wxRichTextImage *image, const wxRichTextAttr& textAttr, int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO); + /// Set the attributes for the given object only, for example the box attributes for a text box. + virtual void SetStyle(wxRichTextObject *obj, const wxRichTextAttr& textAttr, int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO); - /// Get the conbined text attributes for this position. + /// Get the combined text attributes for this position. virtual bool GetStyle(long position, wxRichTextAttr& style); /// Get the content (uncombined) attributes for this position. @@ -1459,7 +1795,7 @@ public: void operator= (const wxRichTextParagraphLayoutBox& obj) { Copy(obj); } /// Calculate ranges - virtual void UpdateRanges() { long end; CalculateRange(0, end); } + virtual void UpdateRanges(); /// Get all the text virtual wxString GetText() const; @@ -1478,19 +1814,34 @@ public: virtual const wxRichTextAttr& GetBasicStyle() const { return m_attributes; } /// Invalidate the buffer. With no argument, invalidates whole buffer. - void Invalidate(const wxRichTextRange& invalidRange = wxRICHTEXT_ALL); + virtual void Invalidate(const wxRichTextRange& invalidRange = wxRICHTEXT_ALL); + + /// Do the (in)validation for this object only + virtual void DoInvalidate(const wxRichTextRange& invalidRange); + + /// Do the (in)validation both up and down the hierarchy + virtual void InvalidateHierarchy(const wxRichTextRange& invalidRange = wxRICHTEXT_ALL); /// Gather information about floating objects. If untilObj is non-NULL, /// will stop getting information if the current object is this, since we /// will collect the rest later. - virtual bool UpdateFloatingObjects(int width, wxRichTextObject* untilObj = NULL); + virtual bool UpdateFloatingObjects(const wxRect& availableRect, wxRichTextObject* untilObj = NULL); /// Get invalid range, rounding to entire paragraphs if argument is true. wxRichTextRange GetInvalidRange(bool wholeParagraphs = false) const; + /// Does this object need layout? + bool IsDirty() const { return m_invalidRange != wxRICHTEXT_NONE; } + /// Get the wxRichTextFloatCollector of this object wxRichTextFloatCollector* GetFloatCollector() { return m_floatCollector; } + /// Get the number of floating objects at this level + int GetFloatingObjectCount() const; + + /// Get a list of floating objects + bool GetFloatingObjects(wxRichTextObjectList& objects) const; + protected: wxRichTextCtrl* m_ctrl; wxRichTextAttr m_defaultAttributes; @@ -1505,40 +1856,65 @@ protected: wxRichTextFloatCollector* m_floatCollector; }; -/*! - * wxRichTextBox class declaration - * TODO: a floating text box +/** + @class wxRichTextBox + + wxRichTextBox is a floating or inline text box, containing paragraphs. */ -class WXDLLIMPEXP_RICHTEXT wxRichTextBox: public wxRichTextCompositeObject +class WXDLLIMPEXP_RICHTEXT wxRichTextBox: public wxRichTextParagraphLayoutBox { DECLARE_DYNAMIC_CLASS(wxRichTextBox) public: // Constructors + /** + Default constructor; optionally pass the parent object. + */ + wxRichTextBox(wxRichTextObject* parent = NULL); - wxRichTextBox(const wxRichTextBox& obj): wxRichTextCompositeObject() { Copy(obj); } + + /** + Copy constructor. + */ + + wxRichTextBox(const wxRichTextBox& obj): wxRichTextParagraphLayoutBox() { Copy(obj); } // Overrideables - /// Draw the item - virtual bool Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextRange& selectionRange, const wxRect& rect, int descent, int style); + /** + Draws the item. + */ - /// Lay the item out - virtual bool Layout(wxDC& dc, const wxRect& rect, int style); + virtual bool Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int descent, int style); - /// Get/set the object size for the given range. Returns false if the range - /// is invalid for this object. - virtual bool GetRangeSize(const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, int flags, wxPoint position = wxPoint(0,0), wxArrayInt* partialExtents = NULL) const; + /** + Returns the XML node name of this object. + */ + + virtual wxString GetXMLNodeName() const { return wxT("textbox"); } + + /// Can we edit properties via a GUI? + virtual bool CanEditProperties() const { return true; } + + /// Edit properties via a GUI + virtual bool EditProperties(wxWindow* parent, wxRichTextBuffer* buffer); + + /// Return the label to be used for the properties context menu item. + virtual wxString GetPropertiesMenuLabel() const { return _("&Box"); } // Accessors // Operations - /// Clone + /** + Makes a clone of this object. + */ virtual wxRichTextObject* Clone() const { return new wxRichTextBox(*this); } - /// Copy + /** + Copies this object. + */ void Copy(const wxRichTextBox& obj); protected: @@ -1640,7 +2016,7 @@ WX_DECLARE_LIST_WITH_DECL( wxRichTextLine, wxRichTextLineList , class WXDLLIMPEX * This object represents a single paragraph (or in a straight text editor, a line). */ -class WXDLLIMPEXP_RICHTEXT wxRichTextParagraph: public wxRichTextBox +class WXDLLIMPEXP_RICHTEXT wxRichTextParagraph: public wxRichTextCompositeObject { DECLARE_DYNAMIC_CLASS(wxRichTextParagraph) public: @@ -1649,17 +2025,17 @@ public: wxRichTextParagraph(wxRichTextObject* parent = NULL, wxRichTextAttr* style = NULL); wxRichTextParagraph(const wxString& text, wxRichTextObject* parent = NULL, wxRichTextAttr* paraStyle = NULL, wxRichTextAttr* charStyle = NULL); virtual ~wxRichTextParagraph(); - wxRichTextParagraph(const wxRichTextParagraph& obj): wxRichTextBox() { Copy(obj); } + wxRichTextParagraph(const wxRichTextParagraph& obj): wxRichTextCompositeObject() { Copy(obj); } // Overrideables /// Draw the item - virtual bool Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextRange& selectionRange, const wxRect& rect, int descent, int style); + virtual bool Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int descent, int style); /// Lay the item out virtual bool Layout(wxDC& dc, const wxRect& rect, int style); - /// Get/set the object size for the given range. Returns false if the range + /// Gets the object size for the given range. Returns false if the range /// is invalid for this object. virtual bool GetRangeSize(const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, int flags, wxPoint position = wxPoint(0,0), wxArrayInt* partialExtents = NULL) const; @@ -1667,8 +2043,8 @@ public: virtual bool FindPosition(wxDC& dc, long index, wxPoint& pt, int* height, bool forceLineStart); /// Hit-testing: returns a flag indicating hit test details, plus - /// information about position - virtual int HitTest(wxDC& dc, const wxPoint& pt, long& textPosition); + /// information about position and the object that was found. + virtual int HitTest(wxDC& dc, const wxPoint& pt, long& textPosition, wxRichTextObject** obj, wxRichTextObject** contextObj, int flags = 0); /// Calculate range virtual void CalculateRange(long start, long& end); @@ -1695,7 +2071,7 @@ public: // Implementation /// Apply paragraph styles such as centering to the wrapped lines - virtual void ApplyParagraphStyle(const wxRichTextAttr& attr, const wxRect& rect, wxDC& dc); + virtual void ApplyParagraphStyle(wxRichTextLine* line, const wxRichTextAttr& attr, const wxRect& rect, wxDC& dc); /// Insert text at the given position virtual bool InsertText(long pos, const wxString& text); @@ -1732,10 +2108,10 @@ public: /// Get combined attributes of the base style, paragraph style and character style. We use this to dynamically /// retrieve the actual style. - wxRichTextAttr GetCombinedAttributes(const wxRichTextAttr& contentStyle) const; + wxRichTextAttr GetCombinedAttributes(const wxRichTextAttr& contentStyle, bool includingBoxAttr = false) const; /// Get combined attributes of the base style and paragraph style. - wxRichTextAttr GetCombinedAttributes() const; + wxRichTextAttr GetCombinedAttributes(bool includingBoxAttr = false) const; /// Get the first position from pos that has a line break character. long GetFirstLineBreakPosition(long pos); @@ -1779,12 +2155,12 @@ public: // Overrideables /// Draw the item - virtual bool Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextRange& selectionRange, const wxRect& rect, int descent, int style); + virtual bool Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int descent, int style); /// Lay the item out virtual bool Layout(wxDC& dc, const wxRect& rect, int style); - /// Get/set the object size for the given range. Returns false if the range + /// Gets the object size for the given range. Returns false if the range /// is invalid for this object. virtual bool GetRangeSize(const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, int flags, wxPoint position = wxPoint(0,0), wxArrayInt* partialExtents = NULL) const; @@ -1822,7 +2198,7 @@ public: #if wxUSE_XML /// Import this object from XML - virtual bool ImportFromXML(wxRichTextBuffer* buffer, wxXmlNode* node, wxRichTextXMLHandler* handler); + virtual bool ImportFromXML(wxRichTextBuffer* buffer, wxXmlNode* node, wxRichTextXMLHandler* handler, bool* recurse); #endif #if wxRICHTEXT_HAVE_DIRECT_OUTPUT @@ -1968,7 +2344,7 @@ public: // Overrideables /// Draw the item - virtual bool Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextRange& selectionRange, const wxRect& rect, int descent, int style); + virtual bool Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int descent, int style); /// Lay the item out virtual bool Layout(wxDC& dc, const wxRect& rect, int style); @@ -1977,6 +2353,10 @@ public: /// is invalid for this object. virtual bool GetRangeSize(const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, int flags, wxPoint position = wxPoint(0,0), wxArrayInt* partialExtents = NULL) const; + /// Get the 'natural' size for an object. For an image, it would be the + /// image size. + virtual wxTextAttrSize GetNaturalSize() const; + /// Returns true if the object is empty. An image is never empty; if the image is broken, that's not the same thing as empty. virtual bool IsEmpty() const { return false; /* !m_imageBlock.Ok(); */ } @@ -1986,12 +2366,15 @@ public: /// Edit properties via a GUI virtual bool EditProperties(wxWindow* parent, wxRichTextBuffer* buffer); + /// Return the label to be used for the properties context menu item. + virtual wxString GetPropertiesMenuLabel() const { return _("&Picture"); } + /// Does this object take note of paragraph attributes? Text and image objects don't. virtual bool UsesParagraphAttributes() const { return false; } #if wxUSE_XML /// Import this object from XML - virtual bool ImportFromXML(wxRichTextBuffer* buffer, wxXmlNode* node, wxRichTextXMLHandler* handler); + virtual bool ImportFromXML(wxRichTextBuffer* buffer, wxXmlNode* node, wxRichTextXMLHandler* handler, bool* recurse); #endif #if wxRICHTEXT_HAVE_DIRECT_OUTPUT @@ -2289,6 +2672,10 @@ public: // Implementation + /// Hit-testing: returns a flag indicating hit test details, plus + /// information about position + virtual int HitTest(wxDC& dc, const wxPoint& pt, long& textPosition, wxRichTextObject** obj, wxRichTextObject** contextObj, int flags = 0); + /// Copy void Copy(const wxRichTextBuffer& obj); @@ -2312,7 +2699,7 @@ public: const wxRichTextAttr& textAttr = wxRichTextAttr()); /// Submit command to insert an object - bool InsertObjectWithUndo(long pos, wxRichTextObject *object, wxRichTextCtrl* ctrl, int flags); + wxRichTextObject* InsertObjectWithUndo(long pos, wxRichTextObject *object, wxRichTextCtrl* ctrl, int flags); /// Submit command to delete this range bool DeleteRangeWithUndo(const wxRichTextRange& range, wxRichTextCtrl* ctrl); @@ -2321,11 +2708,6 @@ public: void Modify(bool modify = true) { m_modified = modify; } bool IsModified() const { return m_modified; } - /// 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. - wxRichTextAttr GetStyleForNewParagraph(long pos, bool caretPosition = false, bool lookUpNewParaStyle=false) const; - /// Dumps contents of buffer for debugging purposes virtual void Dump(); virtual void Dump(wxTextOutputStream& stream) { wxRichTextParagraphLayoutBox::Dump(stream); } @@ -2435,6 +2817,245 @@ protected: double m_scale; }; +/** + @class wxRichTextCell + + wxRichTextCell is the cell in a table. + */ + +class WXDLLIMPEXP_RICHTEXT wxRichTextCell: public wxRichTextBox +{ + DECLARE_DYNAMIC_CLASS(wxRichTextCell) +public: +// Constructors + + /** + Default constructor; optionally pass the parent object. + */ + + wxRichTextCell(wxRichTextObject* parent = NULL); + + /** + Copy constructor. + */ + + wxRichTextCell(const wxRichTextCell& obj): wxRichTextBox() { Copy(obj); } + +// Overrideables + + /** + Draws the item. + */ + + virtual bool Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int descent, int style); + + /** + Returns the XML node name of this object. + */ + + virtual wxString GetXMLNodeName() const { return wxT("cell"); } + + /// Can we edit properties via a GUI? + virtual bool CanEditProperties() const { return true; } + + /// Edit properties via a GUI + virtual bool EditProperties(wxWindow* parent, wxRichTextBuffer* buffer); + + /// Return the label to be used for the properties context menu item. + virtual wxString GetPropertiesMenuLabel() const { return _("&Cell"); } + +// Accessors + +// Operations + + /** + Makes a clone of this object. + */ + virtual wxRichTextObject* Clone() const { return new wxRichTextCell(*this); } + + /** + Copies this object. + */ + void Copy(const wxRichTextCell& obj); + +protected: +}; + +/** + @class wxRichTextTable + + wxRichTextTable represents a table with arbitrary columns and rows. + */ + +WX_DEFINE_ARRAY_PTR(wxRichTextObject*, wxRichTextObjectPtrArray); +WX_DECLARE_OBJARRAY(wxRichTextObjectPtrArray, wxRichTextObjectPtrArrayArray); + +class WXDLLIMPEXP_RICHTEXT wxRichTextTable: public wxRichTextBox +{ + DECLARE_DYNAMIC_CLASS(wxRichTextTable) +public: + +// Constructors + + /** + Default constructor; optionally pass the parent object. + */ + + wxRichTextTable(wxRichTextObject* parent = NULL); + + /** + Copy constructor. + */ + + wxRichTextTable(const wxRichTextTable& obj): wxRichTextBox() { Copy(obj); } + +// Overrideables + + // Draws the object. + virtual bool Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int descent, int style); + + // Returns the XML node name of this object. + virtual wxString GetXMLNodeName() const { return wxT("table"); } + + // Lays the object out. + virtual bool Layout(wxDC& dc, const wxRect& rect, int style); + + // Gets the range size. + virtual bool GetRangeSize(const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, int flags, wxPoint position = wxPoint(0,0), wxArrayInt* partialExtents = NULL) const; + + // Deletes content in the given range. + virtual bool DeleteRange(const wxRichTextRange& range); + + // Gets any text in this object for the given range. + virtual wxString GetTextForRange(const wxRichTextRange& range) const; + +#if wxUSE_XML + // Import this object from XML + virtual bool ImportFromXML(wxRichTextBuffer* buffer, wxXmlNode* node, wxRichTextXMLHandler* handler, bool* recurse); +#endif + +#if wxRICHTEXT_HAVE_DIRECT_OUTPUT + // Export this object directly to the given stream. + virtual bool ExportXML(wxOutputStream& stream, int indent, wxRichTextXMLHandler* handler); +#endif + +#if wxRICHTEXT_HAVE_XMLDOCUMENT_OUTPUT + // Export this object to the given parent node, usually creating at least one child node. + virtual bool ExportXML(wxXmlNode* parent, wxRichTextXMLHandler* handler); +#endif + + /// Finds the absolute position and row height for the given character position + virtual bool FindPosition(wxDC& dc, long index, wxPoint& pt, int* height, bool forceLineStart); + + /// Calculate range + virtual void CalculateRange(long start, long& end); + + /// Can this object handle the selections of its children? FOr example, a table. + virtual bool HandlesChildSelections() const { return true; } + + /// Returns a selection object specifying the selections between start and end character positions. + /// For example, a table would deduce what cells (of range length 1) are selected when dragging across the table. + virtual wxRichTextSelection GetSelection(long start, long end) const; + + /// Can we edit properties via a GUI? + virtual bool CanEditProperties() const { return true; } + + /// Edit properties via a GUI + virtual bool EditProperties(wxWindow* parent, wxRichTextBuffer* buffer); + + /// Return the label to be used for the properties context menu item. + virtual wxString GetPropertiesMenuLabel() const { return _("&Table"); } + + /// Returns true if objects of this class can accept the focus, i.e. a call to SetFocusObject + /// is possible. For example, containers supporting text, such as a text box object, can accept the focus, + /// but a table can't (set the focus to individual cells instead). + virtual bool AcceptsFocus() const { return false; } + +// Accessors + + const wxRichTextObjectPtrArrayArray& GetCells() const { return m_cells; } + wxRichTextObjectPtrArrayArray& GetCells() { return m_cells; } + + int GetRowCount() const { return m_rowCount; } + int GetColumnCount() const { return m_colCount; } + + /// Get the cell at the given row/column position + virtual wxRichTextCell* GetCell(int row, int col) const; + + /// Get the cell at the given character position (in the range of the table). + virtual wxRichTextCell* GetCell(long pos) const; + + /// Get the row/column for a given character position + virtual bool GetCellRowColumnPosition(long pos, int& row, int& col) const; + +// Operations + + /** + Clears the table. + */ + + virtual void ClearTable(); + + /** + Creates a table of the given dimensions. + */ + + virtual bool CreateTable(int rows, int cols); + + /** + Sets the attributes for the cells specified by the selection. + */ + + virtual bool SetCellStyle(const wxRichTextSelection& selection, const wxRichTextAttr& style, int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO); + + /** + Deletes rows from the given row position. + */ + + virtual bool DeleteRows(int startRow, int noRows = 1); + + /** + Deletes columns from the given column position. + */ + + virtual bool DeleteColumns(int startCol, int noCols = 1); + + /** + Adds rows from the given row position. + */ + + virtual bool AddRows(int startRow, int noRows = 1, const wxRichTextAttr& attr = wxRichTextAttr()); + + /** + Adds columns from the given column position. + */ + + virtual bool AddColumns(int startCol, int noCols = 1, const wxRichTextAttr& attr = wxRichTextAttr()); + + // Makes a clone of this object. + virtual wxRichTextObject* Clone() const { return new wxRichTextTable(*this); } + + // Copies this object. + void Copy(const wxRichTextTable& obj); + +protected: + + int m_rowCount; + int m_colCount; + + // An array of rows, each of which is a wxRichTextObjectPtrArray containing + // the cell objects. The cell objects are also children of this object. + // Problem: if boxes are immediate children of a box, this will cause problems + // with wxRichTextParagraphLayoutBox functions (and functions elsewhere) that + // expect to find just paragraphs. May have to adjust the way we handle the + // hierarchy to accept non-paragraph objects in a a paragraph layout box. + // We'll be overriding much wxRichTextParagraphLayoutBox functionality so this + // may not be such a problem. Perhaps the table should derive from a different + // class? + wxRichTextObjectPtrArrayArray m_cells; +}; + + /*! * The command identifiers * @@ -2444,7 +3065,41 @@ enum wxRichTextCommandId { wxRICHTEXT_INSERT, wxRICHTEXT_DELETE, - wxRICHTEXT_CHANGE_STYLE + wxRICHTEXT_CHANGE_ATTRIBUTES, + wxRICHTEXT_CHANGE_STYLE, + wxRICHTEXT_CHANGE_OBJECT +}; + +/*! + * A class for specifying an object anywhere in an object hierarchy, + * without using a pointer, necessary since wxRTC commands may delete + * and recreate sub-objects so physical object addresses change. An array + * of positions (one per hierarchy level) is used. + * + */ + +class WXDLLIMPEXP_RICHTEXT wxRichTextObjectAddress +{ +public: + // Creates the address given container and object. + wxRichTextObjectAddress(wxRichTextParagraphLayoutBox* topLevelContainer, wxRichTextObject* obj) { Create(topLevelContainer, obj); } + wxRichTextObjectAddress() { Init(); } + wxRichTextObjectAddress(const wxRichTextObjectAddress& address) { Copy(address); } + + void Init() {} + void Copy(const wxRichTextObjectAddress& address) { m_address = address.m_address; } + void operator=(const wxRichTextObjectAddress& address) { Copy(address); } + + wxRichTextObject* GetObject(wxRichTextParagraphLayoutBox* topLevelContainer) const; + bool Create(wxRichTextParagraphLayoutBox* topLevelContainer, wxRichTextObject* obj); + + wxArrayInt& GetAddress() { return m_address; } + const wxArrayInt& GetAddress() const { return m_address; } + void SetAddress(const wxArrayInt& address) { m_address = address; } + +protected: + + wxArrayInt m_address; }; /*! @@ -2458,7 +3113,7 @@ class WXDLLIMPEXP_RICHTEXT wxRichTextCommand: public wxCommand public: // Ctor for one action wxRichTextCommand(const wxString& name, wxRichTextCommandId id, wxRichTextBuffer* buffer, - wxRichTextCtrl* ctrl, bool ignoreFirstTime = false); + wxRichTextParagraphLayoutBox* container, wxRichTextCtrl* ctrl, bool ignoreFirstTime = false); // Ctor for multiple actions wxRichTextCommand(const wxString& name); @@ -2486,7 +3141,10 @@ protected: class WXDLLIMPEXP_RICHTEXT wxRichTextAction: public wxObject { public: - wxRichTextAction(wxRichTextCommand* cmd, const wxString& name, wxRichTextCommandId id, wxRichTextBuffer* buffer, + /// Constructor. 'buffer' is the top-level buffer, while 'container' is the object within + /// which the action is taking place. In the simplest case, they are the same. + wxRichTextAction(wxRichTextCommand* cmd, const wxString& name, wxRichTextCommandId id, + wxRichTextBuffer* buffer, wxRichTextParagraphLayoutBox* container, wxRichTextCtrl* ctrl, bool ignoreFirstTime = false); virtual ~wxRichTextAction(); @@ -2505,6 +3163,15 @@ public: wxRichTextParagraphLayoutBox& GetNewParagraphs() { return m_newParagraphs; } wxRichTextParagraphLayoutBox& GetOldParagraphs() { return m_oldParagraphs; } + /// Get the attributes + wxRichTextAttr& GetAttributes() { return m_attributes; } + + /// An object to replace the one at the position + /// defined by the container address and the action's range start position. + wxRichTextObject* GetObject() const { return m_object; } + void SetObject(wxRichTextObject* obj) { m_object = obj; m_objectAddress.Create(m_buffer, m_object); } + void MakeObject(wxRichTextObject* obj) { m_objectAddress.Create(m_buffer, obj); } + /// Calculate arrays for refresh optimization void CalculateRefreshOptimizations(wxArrayInt& optimizationLineCharPositions, wxArrayInt& optimizationLineYPositions); @@ -2516,6 +3183,14 @@ public: void SetRange(const wxRichTextRange& range) { m_range = range; } const wxRichTextRange& GetRange() const { return m_range; } + /// The address (nested position) of the container within the buffer being manipulated + wxRichTextObjectAddress& GetContainerAddress() { return m_containerAddress; } + const wxRichTextObjectAddress& GetContainerAddress() const { return m_containerAddress; } + void SetContainerAddress(const wxRichTextObjectAddress& address) { m_containerAddress = address; } + void SetContainerAddress(wxRichTextParagraphLayoutBox* container, wxRichTextObject* obj) { m_containerAddress.Create(container, obj); } + + /// Returns the container that this action refers to, using the container address and top-level buffer. + wxRichTextParagraphLayoutBox* GetContainer() const; /// Get name const wxString& GetName() const { return m_name; } @@ -2526,6 +3201,11 @@ protected: // Buffer wxRichTextBuffer* m_buffer; + // The address (nested position) of the container being manipulated. + // This is necessary because objects are deleted, and we can't + // therefore store actual pointers. + wxRichTextObjectAddress m_containerAddress; + // Control wxRichTextCtrl* m_ctrl; @@ -2535,6 +3215,19 @@ protected: // Stores the old paragraphs wxRichTextParagraphLayoutBox m_oldParagraphs; + // Stores an object to replace the one at the position + // defined by the container address and the action's range start position. + wxRichTextObject* m_object; + + // Stores the attributes + wxRichTextAttr m_attributes; + + // The address of the object being manipulated (used for changing an individual object or its attributes) + wxRichTextObjectAddress m_objectAddress; + + // Stores the old attributes + // wxRichTextAttr m_oldAttributes; + // The affected range wxRichTextRange m_range; diff --git a/include/wx/richtext/richtextbulletspage.h b/include/wx/richtext/richtextbulletspage.h index beafe36a97..88ea4eba2d 100644 --- a/include/wx/richtext/richtextbulletspage.h +++ b/include/wx/richtext/richtextbulletspage.h @@ -15,6 +15,8 @@ /*! * Includes */ + +#include "wx/richtext/richtextdialogpage.h" #include "wx/spinbutt.h" // for wxSpinEvent /*! @@ -32,7 +34,7 @@ class wxRichTextCtrl; ////@begin control identifiers #define SYMBOL_WXRICHTEXTBULLETSPAGE_STYLE wxRESIZE_BORDER|wxTAB_TRAVERSAL -#define SYMBOL_WXRICHTEXTBULLETSPAGE_TITLE wxT("") +#define SYMBOL_WXRICHTEXTBULLETSPAGE_TITLE wxEmptyString #define SYMBOL_WXRICHTEXTBULLETSPAGE_IDNAME ID_RICHTEXTBULLETSPAGE #define SYMBOL_WXRICHTEXTBULLETSPAGE_SIZE wxSize(400, 300) #define SYMBOL_WXRICHTEXTBULLETSPAGE_POSITION wxDefaultPosition @@ -42,10 +44,11 @@ class wxRichTextCtrl; * wxRichTextBulletsPage class declaration */ -class WXDLLIMPEXP_RICHTEXT wxRichTextBulletsPage: public wxPanel +class WXDLLIMPEXP_RICHTEXT wxRichTextBulletsPage: public wxRichTextDialogPage { DECLARE_DYNAMIC_CLASS( wxRichTextBulletsPage ) DECLARE_EVENT_TABLE() + DECLARE_HELP_PROVISION() public: /// Constructors diff --git a/include/wx/richtext/richtextctrl.h b/include/wx/richtext/richtextctrl.h index f2d976a6dd..6456ef94af 100644 --- a/include/wx/richtext/richtextctrl.h +++ b/include/wx/richtext/richtextctrl.h @@ -48,6 +48,13 @@ class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextStyleDefinition; #define wxRICHTEXT_CTRL_DOWN 0x02 #define wxRICHTEXT_ALT_DOWN 0x04 +/* Extra flags + */ + +// Don't draw guide lines around boxes and tables +#define wxRICHTEXT_EX_NO_GUIDELINES 0x00000100 + + /* Defaults */ @@ -66,14 +73,17 @@ class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextStyleDefinition; // Milliseconds before layout occurs after resize #define wxRICHTEXT_DEFAULT_LAYOUT_INTERVAL 50 +/* Identifiers + */ +#define wxID_RICHTEXT_PROPERTIES1 (wxID_HIGHEST + 1) +#define wxID_RICHTEXT_PROPERTIES2 (wxID_HIGHEST + 2) +#define wxID_RICHTEXT_PROPERTIES3 (wxID_HIGHEST + 3) + /*! * Forward declarations */ -/*! - * wxRichTextItem class declaration - */ - +#if 0 // Drawing styles/states #define wxRICHTEXT_SELECTED 0x01 #define wxRICHTEXT_TAGGED 0x02 @@ -81,6 +91,67 @@ class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextStyleDefinition; #define wxRICHTEXT_FOCUSSED 0x04 // The item itself has the focus #define wxRICHTEXT_IS_FOCUS 0x08 +#endif + +// Normal selection occurs initially and as user drags within one container. +// Common ancestor selection occurs when the user starts dragging across containers +// that have a common ancestor, for example the cells in a table. +enum wxRichTextCtrlSelectionState +{ + wxRichTextCtrlSelectionState_Normal, + wxRichTextCtrlSelectionState_CommonAncestor +}; + +/*! + * wxRichTextContextMenuPropertiesInfo keeps track of objects that appear in the context menu, + * whose properties are available to be edited. + */ + +class WXDLLIMPEXP_RICHTEXT wxRichTextContextMenuPropertiesInfo +{ +public: + wxRichTextContextMenuPropertiesInfo() { Init(); } + +// Operations + + /// Initialisation + void Init() {} + + /// Add an item + bool AddItem(const wxString& label, wxRichTextObject* obj); + + /// Returns number of menu items were added. + int AddMenuItems(wxMenu* menu, int startCmd = wxID_RICHTEXT_PROPERTIES1) const; + + /// Add appropriate menu items for the current container and clicked on object + /// (and container's parent, if appropriate). + int AddItems(wxRichTextObject* container, wxRichTextObject* obj); + + /// Clear the items + void Clear() { m_objects.Clear(); m_labels.Clear(); } + +// Accessors + /// Gets the nth label + wxString GetLabel(int n) const { return m_labels[n]; } + + /// Gets the nth object + wxRichTextObject* GetObject(int n) const { return m_objects[n]; } + + /// Get objects + wxRichTextObjectPtrArray& GetObjects() { return m_objects; } + const wxRichTextObjectPtrArray& GetObjects() const { return m_objects; } + + /// Get labels + wxArrayString& GetLabels() { return m_labels; } + const wxArrayString& GetLabels() const { return m_labels; } + + /// Get number of items + int GetCount() const { return m_objects.GetCount(); } + + //wxArrayInt m_ids; + wxRichTextObjectPtrArray m_objects; + wxArrayString m_labels; +}; /*! * wxRichTextCtrl class declaration @@ -132,6 +203,11 @@ public: virtual void GetSelection(long* from, long* to) const; virtual wxString GetStringSelection() const; + + const wxRichTextSelection& GetSelection() const { return m_selection; } + wxRichTextSelection& GetSelection() { return m_selection; } + void SetSelection(const wxRichTextSelection& sel) { m_selection = sel; } + /// Get filename wxString GetFilename() const { return m_filename; } @@ -185,12 +261,21 @@ public: long GetSelectionAnchor() const { return m_selectionAnchor; } void SetSelectionAnchor(long anchor) { m_selectionAnchor = anchor; } - /// The wxRichTextObject object under mouse if any - wxRichTextObject* GetCurrentObject() const { return m_currentObject; } - void SetCurrentObject(wxRichTextObject* obj) { m_currentObject = obj; } + /// Anchor object if selecting multiple containers. + wxRichTextObject* GetSelectionAnchorObject() const { return m_selectionAnchorObject; } + void SetSelectionAnchorObject(wxRichTextObject* anchor) { m_selectionAnchorObject = anchor; } + + wxRichTextContextMenuPropertiesInfo& GetContextMenuPropertiesInfo() { return m_contextMenuPropertiesInfo; } + const wxRichTextContextMenuPropertiesInfo& GetContextMenuPropertiesInfo() const { return m_contextMenuPropertiesInfo; } + + /// The wxRichTextObject object that currently has the editing focus + wxRichTextParagraphLayoutBox* GetFocusObject() const { return m_focusObject; } + bool SetFocusObject(wxRichTextParagraphLayoutBox* obj, bool setCaretPosition = true); // Operations + void Invalidate() { GetBuffer().Invalidate(wxRICHTEXT_ALL); } + // editing virtual void Clear(); virtual void Replace(long from, long to, const wxString& value); @@ -229,13 +314,15 @@ public: virtual bool SetStyle(const wxRichTextRange& range, const wxRichTextAttr& style); virtual bool GetStyle(long position, wxTextAttr& style); virtual bool GetStyle(long position, wxRichTextAttr& style); + virtual bool GetStyle(long position, wxRichTextAttr& style, wxRichTextParagraphLayoutBox* container); - // Set an image style - void SetImageStyle(wxRichTextImage *image, const wxRichTextAttr& textAttr); + // Set the style for a single object + virtual void SetStyle(wxRichTextObject *obj, const wxRichTextAttr& textAttr); // get the common set of styles for the range virtual bool GetStyleForRange(const wxRichTextRange& range, wxTextAttr& style); virtual bool GetStyleForRange(const wxRichTextRange& range, wxRichTextAttr& style); + virtual bool GetStyleForRange(const wxRichTextRange& range, wxRichTextAttr& style, wxRichTextParagraphLayoutBox* container); // extended style setting operation with flags including: // wxRICHTEXT_SETSTYLE_WITH_UNDO, wxRICHTEXT_SETSTYLE_OPTIMIZE, wxRICHTEXT_SETSTYLE_PARAGRAPHS_ONLY, wxRICHTEXT_SETSTYLE_CHARACTERS_ONLY // see richtextbuffer.h for more details. @@ -243,6 +330,7 @@ public: /// Get the content (uncombined) attributes for this position. virtual bool GetUncombinedStyle(long position, wxRichTextAttr& style); + virtual bool GetUncombinedStyle(long position, wxRichTextAttr& style, wxRichTextParagraphLayoutBox* container); virtual bool SetDefaultStyle(const wxTextAttr& style); virtual bool SetDefaultStyle(const wxRichTextAttr& style); @@ -316,8 +404,14 @@ public: virtual void SelectAll(); virtual void SetEditable(bool editable); + /// Returns true if there was a selection and the object containing the selection + /// was the same as the current focus object. virtual bool HasSelection() const; + /// Returns true if there was a selection, whether or not the current focus object + /// is the same as the selection's container object. + virtual bool HasUnfocusedSelection() const; + ///// Functionality specific to wxRichTextCtrl /// Write an image at the current insertion point. Supply optional type to use @@ -338,6 +432,14 @@ public: virtual bool WriteImage(const wxRichTextImageBlock& imageBlock, const wxRichTextAttr& textAttr = wxRichTextAttr()); + /// Write a text box at the current insertion point, returning the text box. + /// You can then call SetFocusObject() to set the focus to the new object. + virtual wxRichTextBox* WriteTextBox(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. + virtual wxRichTextTable* WriteTable(int rows, int cols, const wxRichTextAttr& tableAttr = wxRichTextAttr(), const wxRichTextAttr& cellAttr = wxRichTextAttr()); + /// Insert a newline (actually paragraph) at the current insertion point. virtual bool Newline(); @@ -484,11 +586,12 @@ public: wxRichTextRange GetSelectionRange() const; void SetSelectionRange(const wxRichTextRange& range); - /// Get/set the selection range in character positions. -1, -1 means no selection. + /// Get/set the selection range in character positions. -2, -2 means no selection + /// -1, -1 means select everything. /// The range is in internal format, i.e. a single character selection is denoted /// by (n, n) - const wxRichTextRange& GetInternalSelectionRange() const { return m_selectionRange; } - void SetInternalSelectionRange(const wxRichTextRange& range) { m_selectionRange = range; } + wxRichTextRange GetInternalSelectionRange() const { return m_selection.GetRange(); } + void SetInternalSelectionRange(const wxRichTextRange& range) { m_selection.Set(range, GetFocusObject()); } /// Add a new paragraph of text to the end of the buffer virtual wxRichTextRange AddParagraph(const wxString& text); @@ -501,7 +604,7 @@ public: virtual bool LayoutContent(bool onlyVisibleRect = false); /// Move the caret to the given character position - virtual bool MoveCaret(long pos, bool showAtLineStart = false); + virtual bool MoveCaret(long pos, bool showAtLineStart = false, wxRichTextParagraphLayoutBox* container = NULL); /// Move right virtual bool MoveRight(int noPositions = 1, int flags = 0); @@ -638,7 +741,7 @@ public: void OnUndo(wxCommandEvent& event); void OnRedo(wxCommandEvent& event); void OnSelectAll(wxCommandEvent& event); - void OnImage(wxCommandEvent& event); + void OnProperties(wxCommandEvent& event); void OnClear(wxCommandEvent& event); void OnUpdateCut(wxUpdateUIEvent& event); @@ -647,7 +750,7 @@ public: void OnUpdateUndo(wxUpdateUIEvent& event); void OnUpdateRedo(wxUpdateUIEvent& event); void OnUpdateSelectAll(wxUpdateUIEvent& event); - void OnUpdateImage(wxUpdateUIEvent& event); + void OnUpdateProperties(wxUpdateUIEvent& event); void OnUpdateClear(wxUpdateUIEvent& event); // Show a context menu for Rich Edit controls (the standard @@ -721,7 +824,7 @@ public: virtual bool ShouldInheritColours() const { return false; } /// Position the caret - virtual void PositionCaret(); + virtual void PositionCaret(wxRichTextParagraphLayoutBox* container = NULL); /// Extend the selection, returning true if the selection was /// changed. Selections are in caret positions. @@ -731,7 +834,7 @@ public: virtual bool ScrollIntoView(long position, int keyCode); /// Refresh the area affected by a selection change - bool RefreshForSelectionChange(const wxRichTextRange& oldSelection, const wxRichTextRange& newSelection); + bool RefreshForSelectionChange(const wxRichTextSelection& oldSelection, const wxRichTextSelection& newSelection); /// The caret position is the character position just before the caret. /// A value of -1 means the caret is at the start of the buffer. @@ -753,8 +856,9 @@ public: /// to the start of the next, which may be the exact same caret position. void MoveCaretBack(long oldPosition) ; - /// Get the caret height and position for the given character position - bool GetCaretPositionForIndex(long position, wxRect& rect); + /// Get the caret height and position for the given character position. If container is null, + /// the current focus object will be used. + bool GetCaretPositionForIndex(long position, wxRect& rect, wxRichTextParagraphLayoutBox* container = NULL); /// Gets the line for the visible caret position. If the caret is /// shown at the very end of the line, it means the next character is actually @@ -812,19 +916,32 @@ public: // Implementation - /// Font names take a long time to retrieve, so cache them (on demand) - static const wxArrayString& GetAvailableFontNames(); - static void ClearAvailableFontNames(); + /// Set up the caret for the given position and container, after a mouse click + bool SetCaretPositionAfterClick(wxRichTextParagraphLayoutBox* container, long position, int hitTestFlags, bool extendSelection = false); - WX_FORWARD_TO_SCROLL_HELPER() + /// Find the caret position for the combination of hit-test flags and character position. + /// Returns the caret position and also an indication of where to place the caret (caretLineStart) + /// since this is ambiguous (same position used for end of line and start of next). + long FindCaretPositionForCharacterPosition(long position, int hitTestFlags, wxRichTextParagraphLayoutBox* container, + bool& caretLineStart); - // implement wxTextEntry methods - virtual wxString DoGetValue() const; + /// Font names take a long time to retrieve, so cache them (on demand) + static const wxArrayString& GetAvailableFontNames(); + static void ClearAvailableFontNames(); + + WX_FORWARD_TO_SCROLL_HELPER() + + // implement wxTextEntry methods + virtual wxString DoGetValue() const; protected: // implement the wxTextEntry pure virtual method virtual wxWindow *GetEditableWindow() { return this; } + // margins functions + virtual bool DoSetMargins(const wxPoint& pt); + virtual wxPoint DoGetMargins() const; + // FIXME: this does not work, it allows this code to compile but will fail // during run-time #ifndef __WXUNIVERSAL__ @@ -872,12 +989,17 @@ private: long m_caretPositionForDefaultStyle; /// Selection range in character positions. -2, -2 means no selection. - wxRichTextRange m_selectionRange; + wxRichTextSelection m_selection; + + wxRichTextCtrlSelectionState m_selectionState; /// Anchor so we know how to extend the selection /// It's a caret position since it's between two characters. long m_selectionAnchor; + /// Anchor object if selecting multiple container objects, such as grid cells. + wxRichTextObject* m_selectionAnchorObject; + /// Are we editable? bool m_editable; @@ -904,9 +1026,11 @@ private: wxCursor m_urlCursor; static wxArrayString sm_availableFontNames; - /// The wxRichTextObject object under mouse if any - wxRichTextObject* m_currentObject; - long m_imagePropertyId; + + wxRichTextContextMenuPropertiesInfo m_contextMenuPropertiesInfo; + + /// The object that currently has the editing focus + wxRichTextParagraphLayoutBox* m_focusObject; }; /*! @@ -919,14 +1043,14 @@ public: wxRichTextEvent(wxEventType commandType = wxEVT_NULL, int winid = 0) : wxNotifyEvent(commandType, winid), m_flags(0), m_position(-1), m_oldStyleSheet(NULL), m_newStyleSheet(NULL), - m_char((wxChar) 0) + m_char((wxChar) 0), m_container(NULL), m_oldContainer(NULL) { } wxRichTextEvent(const wxRichTextEvent& event) : wxNotifyEvent(event), m_flags(event.m_flags), m_position(-1), m_oldStyleSheet(event.m_oldStyleSheet), m_newStyleSheet(event.m_newStyleSheet), - m_char((wxChar) 0) + m_char((wxChar) 0), m_container(event.m_container), m_oldContainer(event.m_oldContainer) { } long GetPosition() const { return m_position; } @@ -947,15 +1071,23 @@ public: wxChar GetCharacter() const { return m_char; } void SetCharacter(wxChar ch) { m_char = ch; } + wxRichTextParagraphLayoutBox* GetContainer() const { return m_container; } + void SetContainer(wxRichTextParagraphLayoutBox* container) { m_container = container; } + + wxRichTextParagraphLayoutBox* GetOldContainer() const { return m_oldContainer; } + void SetOldContainer(wxRichTextParagraphLayoutBox* container) { m_oldContainer = container; } + virtual wxEvent *Clone() const { return new wxRichTextEvent(*this); } protected: - int m_flags; - long m_position; - wxRichTextStyleSheet* m_oldStyleSheet; - wxRichTextStyleSheet* m_newStyleSheet; - wxRichTextRange m_range; - wxChar m_char; + int m_flags; + long m_position; + wxRichTextStyleSheet* m_oldStyleSheet; + wxRichTextStyleSheet* m_newStyleSheet; + wxRichTextRange m_range; + wxChar m_char; + wxRichTextParagraphLayoutBox* m_container; + wxRichTextParagraphLayoutBox* m_oldContainer; private: DECLARE_DYNAMIC_CLASS_NO_ASSIGN(wxRichTextEvent) @@ -982,6 +1114,7 @@ wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_RICHTEXT, wxEVT_COMMAND_RICHTEXT_CONTENT_D wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_RICHTEXT, wxEVT_COMMAND_RICHTEXT_STYLE_CHANGED, wxRichTextEvent ); wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_RICHTEXT, wxEVT_COMMAND_RICHTEXT_SELECTION_CHANGED, wxRichTextEvent ); wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_RICHTEXT, wxEVT_COMMAND_RICHTEXT_BUFFER_RESET, wxRichTextEvent ); +wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_RICHTEXT, wxEVT_COMMAND_RICHTEXT_FOCUS_OBJECT_CHANGED, wxRichTextEvent ); typedef void (wxEvtHandler::*wxRichTextEventFunction)(wxRichTextEvent&); diff --git a/include/wx/richtext/richtextdialogpage.h b/include/wx/richtext/richtextdialogpage.h new file mode 100644 index 0000000000..694cb56972 --- /dev/null +++ b/include/wx/richtext/richtextdialogpage.h @@ -0,0 +1,41 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: wx/richtext/richtextdialogpage.h +// Purpose: Formatting dialog page base class for wxRTC +// Author: Julian Smart +// Modified by: +// Created: 2010-11-14 +// RCS-ID: $Id$ +// Copyright: (c) Julian Smart +// Licence: wxWindows Licence +///////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_RICHTEXTDIALOGPAGE_H_ +#define _WX_RICHTEXTDIALOGPAGE_H_ + +#if wxUSE_RICHTEXT + +#include "wx/panel.h" +#include "wx/richtext/richtextuicustomization.h" + +/** + @class wxRichTextDialogPage + The base class for formatting dialog pages. + **/ + +class WXDLLIMPEXP_RICHTEXT wxRichTextDialogPage: public wxPanel +{ +public: + wxRichTextDialogPage() {} + wxRichTextDialogPage(wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = 0) + { + Create(parent, id, pos, size, style); + } + + DECLARE_BASE_CLASS_HELP_PROVISION() +}; + +#endif + // wxUSE_RICHTEXT + +#endif + // _WX_RICHTEXTDIALOGPAGE_H_ diff --git a/include/wx/richtext/richtextfontpage.h b/include/wx/richtext/richtextfontpage.h index b43f5f2caf..28e005d0a2 100644 --- a/include/wx/richtext/richtextfontpage.h +++ b/include/wx/richtext/richtextfontpage.h @@ -16,6 +16,8 @@ * Includes */ +#include "wx/richtext/richtextdialogpage.h" + ////@begin includes ////@end includes @@ -35,7 +37,7 @@ class wxRichTextFontPreviewCtrl; ////@begin control identifiers #define SYMBOL_WXRICHTEXTFONTPAGE_STYLE wxTAB_TRAVERSAL -#define SYMBOL_WXRICHTEXTFONTPAGE_TITLE wxT("") +#define SYMBOL_WXRICHTEXTFONTPAGE_TITLE wxEmptyString #define SYMBOL_WXRICHTEXTFONTPAGE_IDNAME ID_RICHTEXTFONTPAGE #define SYMBOL_WXRICHTEXTFONTPAGE_SIZE wxSize(200, 100) #define SYMBOL_WXRICHTEXTFONTPAGE_POSITION wxDefaultPosition @@ -45,10 +47,11 @@ class wxRichTextFontPreviewCtrl; * wxRichTextFontPage class declaration */ -class WXDLLIMPEXP_RICHTEXT wxRichTextFontPage: public wxPanel +class WXDLLIMPEXP_RICHTEXT wxRichTextFontPage: public wxRichTextDialogPage { DECLARE_DYNAMIC_CLASS( wxRichTextFontPage ) DECLARE_EVENT_TABLE() + DECLARE_HELP_PROVISION() public: /// Constructors diff --git a/include/wx/richtext/richtextformatdlg.h b/include/wx/richtext/richtextformatdlg.h index ea3a34af24..1f22c147f2 100644 --- a/include/wx/richtext/richtextformatdlg.h +++ b/include/wx/richtext/richtextformatdlg.h @@ -29,6 +29,7 @@ #include "wx/richtext/richtextbuffer.h" #include "wx/richtext/richtextstyles.h" +#include "wx/richtext/richtextuicustomization.h" class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextFormattingDialog; class WXDLLIMPEXP_FWD_CORE wxImageList; @@ -43,8 +44,12 @@ class WXDLLIMPEXP_FWD_CORE wxImageList; #define wxRICHTEXT_FORMAT_BULLETS 0x0008 #define wxRICHTEXT_FORMAT_INDENTS_SPACING 0x0010 #define wxRICHTEXT_FORMAT_LIST_STYLE 0x0020 +#define wxRICHTEXT_FORMAT_MARGINS 0x0040 +#define wxRICHTEXT_FORMAT_SIZE 0x0080 +#define wxRICHTEXT_FORMAT_BORDERS 0x0100 +#define wxRICHTEXT_FORMAT_BACKGROUND 0x0200 -#define wxRICHTEXT_FORMAT_HELP_BUTTON 0x0100 +#define wxRICHTEXT_FORMAT_HELP_BUTTON 0x1000 /*! * Indices for bullet styles in list control @@ -99,7 +104,7 @@ public: virtual int GetPageImage(int WXUNUSED(id)) const { return -1; } /// Invoke help for the dialog - virtual bool ShowHelp(int WXUNUSED(page), wxRichTextFormattingDialog* WXUNUSED(dialog)) { return false; } + virtual bool ShowHelp(int page, wxRichTextFormattingDialog* dialog); /// Set the sheet style, called at the start of wxRichTextFormattingDialog::Create virtual bool SetSheetStyle(wxRichTextFormattingDialog* dialog); @@ -115,6 +120,8 @@ public: class WXDLLIMPEXP_RICHTEXT wxRichTextFormattingDialog: public wxPropertySheetDialog { DECLARE_CLASS(wxRichTextFormattingDialog) +DECLARE_HELP_PROVISION() + public: wxRichTextFormattingDialog() { Init(); } @@ -154,11 +161,24 @@ public: /// Apply attributes to the given range virtual bool ApplyStyle(wxRichTextCtrl* ctrl, const wxRichTextRange& range, int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO|wxRICHTEXT_SETSTYLE_OPTIMIZE); + + /// Apply attributes to the object being edited, if any + virtual bool ApplyStyle(wxRichTextCtrl* ctrl, int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO); /// Gets and sets the attributes const wxRichTextAttr& GetAttributes() const { return m_attributes; } wxRichTextAttr& GetAttributes() { return m_attributes; } void SetAttributes(const wxRichTextAttr& attr) { m_attributes = attr; } +#if 0 + /// Gets and sets the attributes that the user wants to reset + const wxRichTextAttr& GetResetAttributes() const { return m_resetAttributes; } + wxRichTextAttr& GetResetAttributes() { return m_resetAttributes; } + void SetResetAttributes(const wxRichTextAttr& attr) { m_resetAttributes = attr; } +#endif + /// If editing the attributes for a particular object, such as an image, + /// set the object so the code can initialize attributes such as size correctly. + wxRichTextObject* GetObject() const { return m_object; } + void SetObject(wxRichTextObject* obj) { m_object = obj; } /// Transfers the data and from to the window virtual bool TransferDataToWindow(); @@ -170,6 +190,7 @@ public: /// Respond to help command void OnHelp(wxCommandEvent& event); + void OnUpdateHelp(wxUpdateUIEvent& event); /// Set/get image list void SetImageList(wxImageList* imageList) { m_imageList = imageList; } @@ -185,6 +206,9 @@ public: /// Helper for pages to get the attributes static wxRichTextAttr* GetDialogAttributes(wxWindow* win); + /// Helper for pages to get the reset attributes + static wxRichTextAttr* GetDialogResetAttributes(wxWindow* win); + /// Helper for pages to get the style static wxRichTextStyleDefinition* GetDialogStyleDefinition(wxWindow* win); @@ -194,15 +218,29 @@ public: /// Determines whether tooltips will be shown static void SetShowToolTips(bool show) { sm_showToolTips = show; } + /// Set the dimension into the value and units controls + static void SetDimensionValue(wxTextAttrDimension& dim, wxTextCtrl* valueCtrl, wxComboBox* unitsCtrl, wxCheckBox* checkBox); + + /// Get the dimension from the value and units controls + static void GetDimensionValue(wxTextAttrDimension& dim, wxTextCtrl* valueCtrl, wxComboBox* unitsCtrl, wxCheckBox* checkBox); + + /// Convert CM to MM + static bool ConvertFromString(const wxString& string, int& ret, int scale); + /// Map book control page index to our page id void AddPageId(int id) { m_pageIds.Add(id); } + + /// Find a page by class + wxWindow* FindPage(wxClassInfo* info) const; protected: wxImageList* m_imageList; wxRichTextAttr m_attributes; + //wxRichTextAttr m_resetAttributes; wxRichTextStyleDefinition* m_styleDefinition; wxRichTextStyleSheet* m_styleSheet; + wxRichTextObject* m_object; wxArrayInt m_pageIds; // mapping of book control indexes to page ids static wxRichTextFormattingDialogFactory* ms_FormattingDialogFactory; diff --git a/include/wx/richtext/richtextimagedlg.h b/include/wx/richtext/richtextimagedlg.h index 10b0ddc123..d80725ac97 100644 --- a/include/wx/richtext/richtextimagedlg.h +++ b/include/wx/richtext/richtextimagedlg.h @@ -2,10 +2,10 @@ // Name: wx/richtext/richtextimagedlg.h // Purpose: // Author: Mingquan Yang -// Modified by: +// Modified by: Julian Smart // Created: Wed 02 Jun 2010 11:27:23 CST // RCS-ID: -// Copyright: (c) Mingquan Yang +// Copyright: (c) Mingquan Yang, Julian Smart // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// @@ -17,7 +17,9 @@ /*! * Includes */ + #include "wx/richtext/richtextbuffer.h" +#include "wx/richtext/richtextformatdlg.h" /*! * Forward declarations @@ -32,33 +34,32 @@ class WXDLLIMPEXP_FWD_CORE wxTextCtrl; */ ////@begin control identifiers -#define SYMBOL_WXRICHTEXTIMAGEDIALOG_STYLE wxDEFAULT_DIALOG_STYLE|wxTAB_TRAVERSAL -#define SYMBOL_WXRICHTEXTIMAGEDIALOG_TITLE _("Image Properties") -#define SYMBOL_WXRICHTEXTIMAGEDIALOG_IDNAME ID_WXRICHTEXTIMAGEPAGE -#define SYMBOL_WXRICHTEXTIMAGEDIALOG_SIZE wxSize(400, 300) -#define SYMBOL_WXRICHTEXTIMAGEDIALOG_POSITION wxDefaultPosition +#define SYMBOL_WXRICHTEXTOBJECTPROPERTIESDIALOG_STYLE wxDEFAULT_DIALOG_STYLE|wxTAB_TRAVERSAL +#define SYMBOL_WXRICHTEXTOBJECTPROPERTIESDIALOG_TITLE _("Object Properties") +#define SYMBOL_WXRICHTEXTOBJECTPROPERTIESDIALOG_IDNAME ID_RICHTEXTOBJECTPROPERTIESDIALOG +#define SYMBOL_WXRICHTEXTOBJECTPROPERTIESDIALOG_SIZE wxSize(400, 300) +#define SYMBOL_WXRICHTEXTOBJECTPROPERTIESDIALOG_POSITION wxDefaultPosition ////@end control identifiers - /*! - * wxRichTextImageDialog class declaration + * wxRichTextObjectPropertiesDialog class declaration */ -class WXDLLIMPEXP_RICHTEXT wxRichTextImageDialog: public wxDialog -{ - DECLARE_DYNAMIC_CLASS( wxRichTextImageDialog ) +class WXDLLIMPEXP_RICHTEXT wxRichTextObjectPropertiesDialog: public wxRichTextFormattingDialog +{ + DECLARE_DYNAMIC_CLASS( wxRichTextObjectPropertiesDialog ) DECLARE_EVENT_TABLE() public: /// Constructors - wxRichTextImageDialog(); - wxRichTextImageDialog( wxWindow* parent, wxWindowID id = SYMBOL_WXRICHTEXTIMAGEDIALOG_IDNAME, const wxString& caption = SYMBOL_WXRICHTEXTIMAGEDIALOG_TITLE, const wxPoint& pos = SYMBOL_WXRICHTEXTIMAGEDIALOG_POSITION, const wxSize& size = SYMBOL_WXRICHTEXTIMAGEDIALOG_SIZE, long style = SYMBOL_WXRICHTEXTIMAGEDIALOG_STYLE ); + wxRichTextObjectPropertiesDialog(); + wxRichTextObjectPropertiesDialog( wxRichTextObject* obj, wxWindow* parent, wxWindowID id = SYMBOL_WXRICHTEXTOBJECTPROPERTIESDIALOG_IDNAME, const wxString& caption = SYMBOL_WXRICHTEXTOBJECTPROPERTIESDIALOG_TITLE, const wxPoint& pos = SYMBOL_WXRICHTEXTOBJECTPROPERTIESDIALOG_POSITION, const wxSize& size = SYMBOL_WXRICHTEXTOBJECTPROPERTIESDIALOG_SIZE, long style = SYMBOL_WXRICHTEXTOBJECTPROPERTIESDIALOG_STYLE ); /// Creation - bool Create( wxWindow* parent, wxWindowID id = SYMBOL_WXRICHTEXTIMAGEDIALOG_IDNAME, const wxString& caption = SYMBOL_WXRICHTEXTIMAGEDIALOG_TITLE, const wxPoint& pos = SYMBOL_WXRICHTEXTIMAGEDIALOG_POSITION, const wxSize& size = SYMBOL_WXRICHTEXTIMAGEDIALOG_SIZE, long style = SYMBOL_WXRICHTEXTIMAGEDIALOG_STYLE ); + bool Create( wxRichTextObject* obj, wxWindow* parent, wxWindowID id = SYMBOL_WXRICHTEXTOBJECTPROPERTIESDIALOG_IDNAME, const wxString& caption = SYMBOL_WXRICHTEXTOBJECTPROPERTIESDIALOG_TITLE, const wxPoint& pos = SYMBOL_WXRICHTEXTOBJECTPROPERTIESDIALOG_POSITION, const wxSize& size = SYMBOL_WXRICHTEXTOBJECTPROPERTIESDIALOG_SIZE, long style = SYMBOL_WXRICHTEXTOBJECTPROPERTIESDIALOG_STYLE ); /// Destructor - ~wxRichTextImageDialog(); + ~wxRichTextObjectPropertiesDialog(); /// Initialises member variables void Init(); @@ -66,77 +67,28 @@ public: /// Creates the controls and sizers void CreateControls(); - /// Set the dimension into the value and units controls - void SetDimensionValue(wxTextAttrDimension& dim, wxTextCtrl* valueCtrl, wxComboBox* unitsCtrl); +////@begin wxRichTextObjectPropertiesDialog event handler declarations - /// Get the dimension from the value and units controls - void GetDimensionValue(wxTextAttrDimension& dim, wxTextCtrl* valueCtrl, wxComboBox* unitsCtrl); - -////@begin wxRichTextImageDialog event handler declarations +////@end wxRichTextObjectPropertiesDialog event handler declarations - /// wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_RICHTEXTIMAGEDIALOG_PARA_UP - void OnRichtextimagedialogParaUpClick( wxCommandEvent& event ); - - /// wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_RICHTEXTIMAGEDIALOG_DOWN - void OnRichtextimagedialogDownClick( wxCommandEvent& event ); - -////@end wxRichTextImageDialog event handler declarations - -////@begin wxRichTextImageDialog member function declarations +////@begin wxRichTextObjectPropertiesDialog member function declarations /// Retrieves bitmap resources wxBitmap GetBitmapResource( const wxString& name ); /// Retrieves icon resources wxIcon GetIconResource( const wxString& name ); -////@end wxRichTextImageDialog member function declarations +////@end wxRichTextObjectPropertiesDialog member function declarations /// Should we show tooltips? static bool ShowToolTips(); - /// Set the image attribute - void SetImageAttr(const wxRichTextAttr& textAttr); - wxRichTextImage* ApplyImageAttr(); - - /// Set the anchored object - void SetImageObject(wxRichTextImage *image, wxRichTextBuffer* buffer); - - virtual bool TransferDataFromWindow(); - virtual bool TransferDataToWindow(); -private: - /// Convert CM to MM - bool ConvertFromString(const wxString& string, int& ret, int scale); -private: - wxRichTextAttr m_textAttr; - -////@begin wxRichTextImageDialog member variables - wxComboBox* m_float; - wxTextCtrl* m_width; - wxComboBox* m_unitsW; - wxTextCtrl* m_height; - wxComboBox* m_unitsH; - wxTextCtrl* m_offset; - wxComboBox* m_unitsOffset; - wxButton* m_saveButton; - wxButton* m_cancelButton; +////@begin wxRichTextObjectPropertiesDialog member variables /// Control identifiers enum { - ID_WXRICHTEXTIMAGEPAGE = 10015, - ID_RICHTEXTIMAGEDIALOG_FLOATING_MODE = 10017, - ID_RICHTEXTIMAGEDIALOG_WIDTH = 10018, - ID_RICHTEXTIMAGEDIALOG_UNITS_W = 10019, - ID_RICHTEXTIMAGEDIALOG_HEIGHT = 10020, - ID_RICHTEXTIMAGEDIALOG_UNITS_H = 10021, - ID_RICHTEXTIMAGEDIALOG_OFFSET = 10022, - ID_RICHTEXTIMAGEDIALOG_OFFSET_UNITS = 10023, - ID_RICHTEXTIMAGEDIALOG_PARA_UP = 10024, - ID_RICHTEXTIMAGEDIALOG_DOWN = 10025 + ID_RICHTEXTOBJECTPROPERTIESDIALOG = 10650 }; -////@end wxRichTextImageDialog member variables - - wxRichTextBuffer* m_buffer; - wxRichTextObject* m_image; - wxRichTextObject* m_parent; +////@end wxRichTextObjectPropertiesDialog member variables }; #endif diff --git a/include/wx/richtext/richtextindentspage.h b/include/wx/richtext/richtextindentspage.h index 1d77ca7756..0e734dea80 100644 --- a/include/wx/richtext/richtextindentspage.h +++ b/include/wx/richtext/richtextindentspage.h @@ -16,6 +16,8 @@ * Includes */ +#include "wx/richtext/richtextdialogpage.h" + ////@begin includes #include "wx/statline.h" ////@end includes @@ -44,10 +46,11 @@ class wxRichTextCtrl; * wxRichTextIndentsSpacingPage class declaration */ -class WXDLLIMPEXP_RICHTEXT wxRichTextIndentsSpacingPage: public wxPanel +class WXDLLIMPEXP_RICHTEXT wxRichTextIndentsSpacingPage: public wxRichTextDialogPage { DECLARE_DYNAMIC_CLASS( wxRichTextIndentsSpacingPage ) DECLARE_EVENT_TABLE() + DECLARE_HELP_PROVISION() public: /// Constructors diff --git a/include/wx/richtext/richtextliststylepage.h b/include/wx/richtext/richtextliststylepage.h index 92b7c67e52..4eedafa1cb 100644 --- a/include/wx/richtext/richtextliststylepage.h +++ b/include/wx/richtext/richtextliststylepage.h @@ -16,6 +16,8 @@ * Includes */ +#include "wx/richtext/richtextdialogpage.h" + ////@begin includes #include "wx/spinctrl.h" #include "wx/notebook.h" @@ -28,7 +30,7 @@ ////@begin control identifiers #define SYMBOL_WXRICHTEXTLISTSTYLEPAGE_STYLE wxRESIZE_BORDER|wxTAB_TRAVERSAL -#define SYMBOL_WXRICHTEXTLISTSTYLEPAGE_TITLE wxT("") +#define SYMBOL_WXRICHTEXTLISTSTYLEPAGE_TITLE wxEmptyString #define SYMBOL_WXRICHTEXTLISTSTYLEPAGE_IDNAME ID_RICHTEXTLISTSTYLEPAGE #define SYMBOL_WXRICHTEXTLISTSTYLEPAGE_SIZE wxSize(400, 300) #define SYMBOL_WXRICHTEXTLISTSTYLEPAGE_POSITION wxDefaultPosition @@ -38,10 +40,11 @@ * wxRichTextListStylePage class declaration */ -class WXDLLIMPEXP_RICHTEXT wxRichTextListStylePage: public wxPanel +class WXDLLIMPEXP_RICHTEXT wxRichTextListStylePage: public wxRichTextDialogPage { DECLARE_DYNAMIC_CLASS( wxRichTextListStylePage ) DECLARE_EVENT_TABLE() + DECLARE_HELP_PROVISION() public: /// Constructors diff --git a/include/wx/richtext/richtextmarginspage.h b/include/wx/richtext/richtextmarginspage.h new file mode 100644 index 0000000000..b05f385146 --- /dev/null +++ b/include/wx/richtext/richtextmarginspage.h @@ -0,0 +1,179 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: richtextmarginspage.h +// Purpose: +// Author: Julian Smart +// Modified by: +// Created: 20/10/2010 10:27:34 +// RCS-ID: +// Copyright: (c) Julian Smart +// Licence: +///////////////////////////////////////////////////////////////////////////// + +#ifndef _RICHTEXTMARGINSPAGE_H_ +#define _RICHTEXTMARGINSPAGE_H_ + + +/*! + * Includes + */ + +#include "wx/richtext/richtextdialogpage.h" + +////@begin includes +#include "wx/statline.h" +////@end includes + +/*! + * Forward declarations + */ + +////@begin forward declarations +////@end forward declarations + +/*! + * Control identifiers + */ + +////@begin control identifiers +#define SYMBOL_WXRICHTEXTMARGINSPAGE_STYLE wxTAB_TRAVERSAL +#define SYMBOL_WXRICHTEXTMARGINSPAGE_TITLE wxEmptyString +#define SYMBOL_WXRICHTEXTMARGINSPAGE_IDNAME ID_WXRICHTEXTMARGINSPAGE +#define SYMBOL_WXRICHTEXTMARGINSPAGE_SIZE wxSize(400, 300) +#define SYMBOL_WXRICHTEXTMARGINSPAGE_POSITION wxDefaultPosition +////@end control identifiers + + +/*! + * wxRichTextMarginsPage class declaration + */ + +class WXDLLIMPEXP_RICHTEXT wxRichTextMarginsPage: public wxRichTextDialogPage +{ + DECLARE_DYNAMIC_CLASS( wxRichTextMarginsPage ) + DECLARE_EVENT_TABLE() + DECLARE_HELP_PROVISION() + +public: + /// Constructors + wxRichTextMarginsPage(); + wxRichTextMarginsPage( wxWindow* parent, wxWindowID id = SYMBOL_WXRICHTEXTMARGINSPAGE_IDNAME, const wxPoint& pos = SYMBOL_WXRICHTEXTMARGINSPAGE_POSITION, const wxSize& size = SYMBOL_WXRICHTEXTMARGINSPAGE_SIZE, long style = SYMBOL_WXRICHTEXTMARGINSPAGE_STYLE ); + + /// Creation + bool Create( wxWindow* parent, wxWindowID id = SYMBOL_WXRICHTEXTMARGINSPAGE_IDNAME, const wxPoint& pos = SYMBOL_WXRICHTEXTMARGINSPAGE_POSITION, const wxSize& size = SYMBOL_WXRICHTEXTMARGINSPAGE_SIZE, long style = SYMBOL_WXRICHTEXTMARGINSPAGE_STYLE ); + + /// Destructor + ~wxRichTextMarginsPage(); + + /// Initialises member variables + void Init(); + + /// Creates the controls and sizers + void CreateControls(); + + /// Gets the attributes from the formatting dialog + wxRichTextAttr* GetAttributes(); + + /// Data transfer + virtual bool TransferDataToWindow(); + virtual bool TransferDataFromWindow(); + +////@begin wxRichTextMarginsPage event handler declarations + + /// wxEVT_UPDATE_UI event handler for ID_RICHTEXT_LEFT_MARGIN + void OnRichtextLeftMarginUpdate( wxUpdateUIEvent& event ); + + /// wxEVT_UPDATE_UI event handler for ID_RICHTEXT_RIGHT_MARGIN + void OnRichtextRightMarginUpdate( wxUpdateUIEvent& event ); + + /// wxEVT_UPDATE_UI event handler for ID_RICHTEXT_TOP_MARGIN + void OnRichtextTopMarginUpdate( wxUpdateUIEvent& event ); + + /// wxEVT_UPDATE_UI event handler for ID_RICHTEXT_BOTTOM_MARGIN + void OnRichtextBottomMarginUpdate( wxUpdateUIEvent& event ); + + /// wxEVT_UPDATE_UI event handler for ID_RICHTEXT_LEFT_PADDING + void OnRichtextLeftPaddingUpdate( wxUpdateUIEvent& event ); + + /// wxEVT_UPDATE_UI event handler for ID_RICHTEXT_RIGHT_PADDING + void OnRichtextRightPaddingUpdate( wxUpdateUIEvent& event ); + + /// wxEVT_UPDATE_UI event handler for ID_RICHTEXT_TOP_PADDING + void OnRichtextTopPaddingUpdate( wxUpdateUIEvent& event ); + + /// wxEVT_UPDATE_UI event handler for ID_RICHTEXT_BOTTOM_PADDING + void OnRichtextBottomPaddingUpdate( wxUpdateUIEvent& event ); + +////@end wxRichTextMarginsPage event handler declarations + +////@begin wxRichTextMarginsPage member function declarations + + /// Retrieves bitmap resources + wxBitmap GetBitmapResource( const wxString& name ); + + /// Retrieves icon resources + wxIcon GetIconResource( const wxString& name ); +////@end wxRichTextMarginsPage member function declarations + + /// Should we show tooltips? + static bool ShowToolTips(); + +////@begin wxRichTextMarginsPage member variables + wxCheckBox* m_leftMarginCheckbox; + wxTextCtrl* m_marginLeft; + wxComboBox* m_unitsMarginLeft; + wxCheckBox* m_rightMarginCheckbox; + wxTextCtrl* m_marginRight; + wxComboBox* m_unitsMarginRight; + wxCheckBox* m_topMarginCheckbox; + wxTextCtrl* m_marginTop; + wxComboBox* m_unitsMarginTop; + wxCheckBox* m_bottomMarginCheckbox; + wxTextCtrl* m_marginBottom; + wxComboBox* m_unitsMarginBottom; + wxCheckBox* m_leftPaddingCheckbox; + wxTextCtrl* m_paddingLeft; + wxComboBox* m_unitsPaddingLeft; + wxCheckBox* m_rightPaddingCheckbox; + wxTextCtrl* m_paddingRight; + wxComboBox* m_unitsPaddingRight; + wxCheckBox* m_topPaddingCheckbox; + wxTextCtrl* m_paddingTop; + wxComboBox* m_unitsPaddingTop; + wxCheckBox* m_bottomPaddingCheckbox; + wxTextCtrl* m_paddingBottom; + wxComboBox* m_unitsPaddingBottom; + /// Control identifiers + enum { + ID_WXRICHTEXTMARGINSPAGE = 10750, + ID_RICHTEXT_LEFT_MARGIN_CHECKBOX = 10751, + ID_RICHTEXT_LEFT_MARGIN = 10752, + ID_RICHTEXT_LEFT_MARGIN_UNITS = 10753, + ID_RICHTEXT_RIGHT_MARGIN_CHECKBOX = 10754, + ID_RICHTEXT_RIGHT_MARGIN = 10755, + ID_RICHTEXT_RIGHT_MARGIN_UNITS = 10756, + ID_RICHTEXT_TOP_MARGIN_CHECKBOX = 10757, + ID_RICHTEXT_TOP_MARGIN = 10758, + ID_RICHTEXT_TOP_MARGIN_UNITS = 10759, + ID_RICHTEXT_BOTTOM_MARGIN_CHECKBOX = 10760, + ID_RICHTEXT_BOTTOM_MARGIN = 10761, + ID_RICHTEXT_BOTTOM_MARGIN_UNITS = 10762, + ID_RICHTEXT_LEFT_PADDING_CHECKBOX = 10763, + ID_RICHTEXT_LEFT_PADDING = 10764, + ID_RICHTEXT_LEFT_PADDING_UNITS = 10765, + ID_RICHTEXT_RIGHT_PADDING_CHECKBOX = 10766, + ID_RICHTEXT_RIGHT_PADDING = 10767, + ID_RICHTEXT_RIGHT_PADDING_UNITS = 10768, + ID_RICHTEXT_TOP_PADDING_CHECKBOX = 10769, + ID_RICHTEXT_TOP_PADDING = 10770, + ID_RICHTEXT_TOP_PADDING_UNITS = 10771, + ID_RICHTEXT_BOTTOM_PADDING_CHECKBOX = 10772, + ID_RICHTEXT_BOTTOM_PADDING = 10773, + ID_RICHTEXT_BOTTOM_PADDING_UNITS = 10774 + }; +////@end wxRichTextMarginsPage member variables + + bool m_ignoreUpdates; +}; + +#endif + // _RICHTEXTMARGINSPAGE_H_ diff --git a/include/wx/richtext/richtextprint.h b/include/wx/richtext/richtextprint.h index dc7b0c2ac9..29b86945e7 100644 --- a/include/wx/richtext/richtextprint.h +++ b/include/wx/richtext/richtextprint.h @@ -145,6 +145,7 @@ private: int m_numPages; wxArrayInt m_pageBreaksStart; wxArrayInt m_pageBreaksEnd; + wxArrayInt m_pageYOffsets; int m_marginLeft, m_marginTop, m_marginRight, m_marginBottom; wxRichTextHeaderFooterData m_headerFooterData; diff --git a/include/wx/richtext/richtextsizepage.h b/include/wx/richtext/richtextsizepage.h new file mode 100644 index 0000000000..ba2fb76733 --- /dev/null +++ b/include/wx/richtext/richtextsizepage.h @@ -0,0 +1,159 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: richtextsizepage.h +// Purpose: +// Author: Julian Smart +// Modified by: +// Created: 20/10/2010 10:23:24 +// RCS-ID: +// Copyright: (c) Julian Smart +// Licence: +///////////////////////////////////////////////////////////////////////////// + +#ifndef _RICHTEXTSIZEPAGE_H_ +#define _RICHTEXTSIZEPAGE_H_ + +/*! + * Includes + */ + +#include "wx/richtext/richtextdialogpage.h" +#include "wx/sizer.h" + +////@begin includes +#include "wx/statline.h" +////@end includes + +/*! + * Forward declarations + */ + + +/*! + * Control identifiers + */ + +////@begin control identifiers +#define SYMBOL_WXRICHTEXTSIZEPAGE_STYLE wxTAB_TRAVERSAL +#define SYMBOL_WXRICHTEXTSIZEPAGE_TITLE wxEmptyString +#define SYMBOL_WXRICHTEXTSIZEPAGE_IDNAME ID_WXRICHTEXTSIZEPAGE +#define SYMBOL_WXRICHTEXTSIZEPAGE_SIZE wxSize(400, 300) +#define SYMBOL_WXRICHTEXTSIZEPAGE_POSITION wxDefaultPosition +////@end control identifiers + + +/*! + * wxRichTextSizePage class declaration + */ + +class WXDLLIMPEXP_RICHTEXT wxRichTextSizePage: public wxRichTextDialogPage +{ + DECLARE_DYNAMIC_CLASS( wxRichTextSizePage ) + DECLARE_EVENT_TABLE() + DECLARE_HELP_PROVISION() + +public: + /// Constructors + wxRichTextSizePage(); + wxRichTextSizePage( wxWindow* parent, wxWindowID id = SYMBOL_WXRICHTEXTSIZEPAGE_IDNAME, const wxPoint& pos = SYMBOL_WXRICHTEXTSIZEPAGE_POSITION, const wxSize& size = SYMBOL_WXRICHTEXTSIZEPAGE_SIZE, long style = SYMBOL_WXRICHTEXTSIZEPAGE_STYLE ); + + /// Creation + bool Create( wxWindow* parent, wxWindowID id = SYMBOL_WXRICHTEXTSIZEPAGE_IDNAME, const wxPoint& pos = SYMBOL_WXRICHTEXTSIZEPAGE_POSITION, const wxSize& size = SYMBOL_WXRICHTEXTSIZEPAGE_SIZE, long style = SYMBOL_WXRICHTEXTSIZEPAGE_STYLE ); + + /// Destructor + ~wxRichTextSizePage(); + + /// Initialises member variables + void Init(); + + /// Creates the controls and sizers + void CreateControls(); + + /// Gets the attributes from the formatting dialog + wxRichTextAttr* GetAttributes(); + + /// Data transfer + virtual bool TransferDataToWindow(); + virtual bool TransferDataFromWindow(); + + /// Show/hide position controls + void ShowPositionControls(bool show); + + /// Show/hide floating controls + void ShowFloatingControls(bool show); + +////@begin wxRichTextSizePage event handler declarations + + /// wxEVT_UPDATE_UI event handler for ID_RICHTEXT_WIDTH + void OnRichtextWidthUpdate( wxUpdateUIEvent& event ); + + /// wxEVT_UPDATE_UI event handler for ID_RICHTEXT_HEIGHT + void OnRichtextHeightUpdate( wxUpdateUIEvent& event ); + + /// wxEVT_UPDATE_UI event handler for ID_RICHTEXT_VERTICAL_ALIGNMENT_COMBOBOX + void OnRichtextVerticalAlignmentComboboxUpdate( wxUpdateUIEvent& event ); + + /// wxEVT_UPDATE_UI event handler for ID_RICHTEXT_OFFSET + void OnRichtextOffsetUpdate( wxUpdateUIEvent& event ); + + /// wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_RICHTEXT_PARA_UP + void OnRichtextParaUpClick( wxCommandEvent& event ); + + /// wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_RICHTEXT_PARA_DOWN + void OnRichtextParaDownClick( wxCommandEvent& event ); + +////@end wxRichTextSizePage event handler declarations + +////@begin wxRichTextSizePage member function declarations + + /// Retrieves bitmap resources + wxBitmap GetBitmapResource( const wxString& name ); + + /// Retrieves icon resources + wxIcon GetIconResource( const wxString& name ); +////@end wxRichTextSizePage member function declarations + + /// Should we show tooltips? + static bool ShowToolTips(); + +////@begin wxRichTextSizePage member variables + wxBoxSizer* m_parentSizer; + wxBoxSizer* m_floatingControls; + wxComboBox* m_float; + wxCheckBox* m_widthCheckbox; + wxTextCtrl* m_width; + wxComboBox* m_unitsW; + wxCheckBox* m_heightCheckbox; + wxTextCtrl* m_height; + wxComboBox* m_unitsH; + wxBoxSizer* m_alignmentControls; + wxCheckBox* m_verticalAlignmentCheckbox; + wxComboBox* m_verticalAlignmentComboBox; + wxBoxSizer* m_positionControls; + wxBoxSizer* m_moveObjectParentSizer; + wxCheckBox* m_offsetYCheckbox; + wxTextCtrl* m_offset; + wxComboBox* m_unitsOffset; + wxBoxSizer* m_moveObjectSizer; + /// Control identifiers + enum { + ID_WXRICHTEXTSIZEPAGE = 10700, + ID_RICHTEXT_FLOATING_MODE = 10701, + ID_RICHTEXT_WIDTH_CHECKBOX = 10702, + ID_RICHTEXT_WIDTH = 10703, + ID_RICHTEXT_UNITS_W = 10704, + ID_RICHTEXT_HEIGHT_CHECKBOX = 10705, + ID_RICHTEXT_HEIGHT = 10706, + ID_RICHTEXT_UNITS_H = 10707, + ID_RICHTEXT_VERTICAL_ALIGNMENT_CHECKBOX = 10708, + ID_RICHTEXT_VERTICAL_ALIGNMENT_COMBOBOX = 10709, + ID_RICHTEXT_OFFSET_CHECKBOX = 10710, + ID_RICHTEXT_OFFSET = 10711, + ID_RICHTEXT_OFFSET_UNITS = 10712, + ID_RICHTEXT_PARA_UP = 10713, + ID_RICHTEXT_PARA_DOWN = 10714 + }; +////@end wxRichTextSizePage member variables +}; + +#endif + // _RICHTEXTSIZEPAGE_H_ diff --git a/include/wx/richtext/richtextstyledlg.h b/include/wx/richtext/richtextstyledlg.h index 403b180708..3dc8528ab8 100644 --- a/include/wx/richtext/richtextstyledlg.h +++ b/include/wx/richtext/richtextstyledlg.h @@ -16,6 +16,8 @@ * Includes */ +#include "wx/richtext/richtextuicustomization.h" + ////@begin includes ////@end includes @@ -31,6 +33,7 @@ class wxBoxSizer; class wxRichTextStyleListCtrl; class wxRichTextCtrl; +class wxStdDialogButtonSizer; ////@end forward declarations class WXDLLIMPEXP_FWD_CORE wxButton; @@ -79,6 +82,7 @@ class WXDLLIMPEXP_RICHTEXT wxRichTextStyleOrganiserDialog: public wxDialog { DECLARE_DYNAMIC_CLASS( wxRichTextStyleOrganiserDialog ) DECLARE_EVENT_TABLE() + DECLARE_HELP_PROVISION() public: /// Constructors @@ -207,6 +211,7 @@ public: wxButton* m_closeButton; wxBoxSizer* m_bottomButtonSizer; wxCheckBox* m_restartNumberingCtrl; + wxStdDialogButtonSizer* m_stdButtonSizer; wxButton* m_okButton; wxButton* m_cancelButton; /// Control identifiers diff --git a/include/wx/richtext/richtextstylepage.h b/include/wx/richtext/richtextstylepage.h index f9478309b4..0d6457a8db 100644 --- a/include/wx/richtext/richtextstylepage.h +++ b/include/wx/richtext/richtextstylepage.h @@ -12,13 +12,15 @@ #ifndef _RICHTEXTSTYLEPAGE_H_ #define _RICHTEXTSTYLEPAGE_H_ +#include "wx/richtext/richtextdialogpage.h" + /*! * Control identifiers */ ////@begin control identifiers #define SYMBOL_WXRICHTEXTSTYLEPAGE_STYLE wxRESIZE_BORDER|wxTAB_TRAVERSAL -#define SYMBOL_WXRICHTEXTSTYLEPAGE_TITLE wxT("") +#define SYMBOL_WXRICHTEXTSTYLEPAGE_TITLE wxEmptyString #define SYMBOL_WXRICHTEXTSTYLEPAGE_IDNAME ID_RICHTEXTSTYLEPAGE #define SYMBOL_WXRICHTEXTSTYLEPAGE_SIZE wxSize(400, 300) #define SYMBOL_WXRICHTEXTSTYLEPAGE_POSITION wxDefaultPosition @@ -28,10 +30,11 @@ * wxRichTextStylePage class declaration */ -class wxRichTextStylePage: public wxPanel +class WXDLLIMPEXP_RICHTEXT wxRichTextStylePage: public wxRichTextDialogPage { DECLARE_DYNAMIC_CLASS( wxRichTextStylePage ) DECLARE_EVENT_TABLE() + DECLARE_HELP_PROVISION() public: /// Constructors diff --git a/include/wx/richtext/richtextstyles.h b/include/wx/richtext/richtextstyles.h index 022f81e33a..4ebcedecdd 100644 --- a/include/wx/richtext/richtextstyles.h +++ b/include/wx/richtext/richtextstyles.h @@ -240,6 +240,40 @@ protected: wxRichTextAttr m_levelStyles[10]; }; +/*! + * wxRichTextBoxStyleDefinition class declaration, for box attributes in objects such as wxRichTextBox. + */ + +class WXDLLIMPEXP_RICHTEXT wxRichTextBoxStyleDefinition: public wxRichTextStyleDefinition +{ + DECLARE_DYNAMIC_CLASS(wxRichTextBoxStyleDefinition) +public: + + /// Copy constructor + wxRichTextBoxStyleDefinition(const wxRichTextBoxStyleDefinition& def) { Copy(def); } + + /// Default constructor + wxRichTextBoxStyleDefinition(const wxString& name = wxEmptyString): + wxRichTextStyleDefinition(name) {} + + // Destructor + virtual ~wxRichTextBoxStyleDefinition() {} + + /// Copies from def + void Copy(const wxRichTextBoxStyleDefinition& def); + + /// Assignment operator + void operator =(const wxRichTextBoxStyleDefinition& def) { Copy(def); } + + /// Equality operator + bool operator ==(const wxRichTextBoxStyleDefinition& def) const; + + /// Clones the object + virtual wxRichTextStyleDefinition* Clone() const { return new wxRichTextBoxStyleDefinition(*this); } + +protected: +}; + /*! * The style sheet */ @@ -280,6 +314,9 @@ public: /// Add a definition to the list style list bool AddListStyle(wxRichTextListStyleDefinition* def); + /// Add a definition to the box style list + bool AddBoxStyle(wxRichTextBoxStyleDefinition* def); + /// Add a definition to the appropriate style list bool AddStyle(wxRichTextStyleDefinition* def); @@ -292,6 +329,9 @@ public: /// Remove a list style bool RemoveListStyle(wxRichTextStyleDefinition* def, bool deleteStyle = false) { return RemoveStyle(m_listStyleDefinitions, def, deleteStyle); } + /// Remove a box style + bool RemoveBoxStyle(wxRichTextStyleDefinition* def, bool deleteStyle = false) { return RemoveStyle(m_boxStyleDefinitions, def, deleteStyle); } + /// Remove a style bool RemoveStyle(wxRichTextStyleDefinition* def, bool deleteStyle = false); @@ -304,6 +344,9 @@ public: /// Find a list definition by name wxRichTextListStyleDefinition* FindListStyle(const wxString& name, bool recurse = true) const { return (wxRichTextListStyleDefinition*) FindStyle(m_listStyleDefinitions, name, recurse); } + /// Find a box definition by name + wxRichTextBoxStyleDefinition* FindBoxStyle(const wxString& name, bool recurse = true) const { return (wxRichTextBoxStyleDefinition*) FindStyle(m_boxStyleDefinitions, name, recurse); } + /// Find any definition by name wxRichTextStyleDefinition* FindStyle(const wxString& name, bool recurse = true) const; @@ -316,6 +359,9 @@ public: /// Return the number of list styles size_t GetListStyleCount() const { return m_listStyleDefinitions.GetCount(); } + /// Return the number of box styles + size_t GetBoxStyleCount() const { return m_boxStyleDefinitions.GetCount(); } + /// Return the nth character style wxRichTextCharacterStyleDefinition* GetCharacterStyle(size_t n) const { return (wxRichTextCharacterStyleDefinition*) m_characterStyleDefinitions.Item(n)->GetData(); } @@ -325,6 +371,9 @@ public: /// Return the nth list style wxRichTextListStyleDefinition* GetListStyle(size_t n) const { return (wxRichTextListStyleDefinition*) m_listStyleDefinitions.Item(n)->GetData(); } + /// Return the nth box style + wxRichTextBoxStyleDefinition* GetBoxStyle(size_t n) const { return (wxRichTextBoxStyleDefinition*) m_boxStyleDefinitions.Item(n)->GetData(); } + /// Delete all styles void DeleteStyles(); @@ -372,6 +421,7 @@ protected: wxList m_characterStyleDefinitions; wxList m_paragraphStyleDefinitions; wxList m_listStyleDefinitions; + wxList m_boxStyleDefinitions; wxRichTextStyleSheet* m_previousSheet; wxRichTextStyleSheet* m_nextSheet; @@ -395,7 +445,8 @@ public: wxRICHTEXT_STYLE_ALL, wxRICHTEXT_STYLE_PARAGRAPH, wxRICHTEXT_STYLE_CHARACTER, - wxRICHTEXT_STYLE_LIST + wxRICHTEXT_STYLE_LIST, + wxRICHTEXT_STYLE_BOX }; wxRichTextStyleListBox() diff --git a/include/wx/richtext/richtextsymboldlg.h b/include/wx/richtext/richtextsymboldlg.h index 20992812ff..c77884dc06 100644 --- a/include/wx/richtext/richtextsymboldlg.h +++ b/include/wx/richtext/richtextsymboldlg.h @@ -16,6 +16,7 @@ * Includes */ +#include "wx/richtext/richtextuicustomization.h" #include "wx/dialog.h" #include "wx/vscroll.h" @@ -29,6 +30,7 @@ class WXDLLIMPEXP_FWD_CORE wxTextCtrl; ////@begin forward declarations class wxSymbolListCtrl; +class wxStdDialogButtonSizer; ////@end forward declarations // __UNICODE__ is a symbol used by DialogBlocks-generated code. @@ -56,6 +58,7 @@ class WXDLLIMPEXP_RICHTEXT wxSymbolPickerDialog: public wxDialog { DECLARE_DYNAMIC_CLASS( wxSymbolPickerDialog ) DECLARE_EVENT_TABLE() + DECLARE_HELP_PROVISION() public: /// Constructors @@ -158,6 +161,7 @@ public: #if defined(__UNICODE__) wxComboBox* m_fromUnicodeCtrl; #endif + wxStdDialogButtonSizer* m_stdButtonSizer; wxString m_fontName; wxString m_symbol; bool m_fromUnicode; diff --git a/include/wx/richtext/richtexttabspage.h b/include/wx/richtext/richtexttabspage.h index 162601251f..1495c664df 100644 --- a/include/wx/richtext/richtexttabspage.h +++ b/include/wx/richtext/richtexttabspage.h @@ -16,6 +16,8 @@ * Includes */ +#include "wx/richtext/richtextdialogpage.h" + ////@begin includes ////@end includes @@ -32,7 +34,7 @@ ////@begin control identifiers #define SYMBOL_WXRICHTEXTTABSPAGE_STYLE wxRESIZE_BORDER|wxTAB_TRAVERSAL -#define SYMBOL_WXRICHTEXTTABSPAGE_TITLE wxT("") +#define SYMBOL_WXRICHTEXTTABSPAGE_TITLE wxEmptyString #define SYMBOL_WXRICHTEXTTABSPAGE_IDNAME ID_RICHTEXTTABSPAGE #define SYMBOL_WXRICHTEXTTABSPAGE_SIZE wxSize(400, 300) #define SYMBOL_WXRICHTEXTTABSPAGE_POSITION wxDefaultPosition @@ -42,10 +44,11 @@ * wxRichTextTabsPage class declaration */ -class WXDLLIMPEXP_RICHTEXT wxRichTextTabsPage: public wxPanel +class WXDLLIMPEXP_RICHTEXT wxRichTextTabsPage: public wxRichTextDialogPage { DECLARE_DYNAMIC_CLASS( wxRichTextTabsPage ) DECLARE_EVENT_TABLE() + DECLARE_HELP_PROVISION() public: /// Constructors diff --git a/include/wx/richtext/richtextuicustomization.h b/include/wx/richtext/richtextuicustomization.h new file mode 100644 index 0000000000..ea20a60d69 --- /dev/null +++ b/include/wx/richtext/richtextuicustomization.h @@ -0,0 +1,123 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: wx/richtext/richtextuicustomization.h +// Purpose: UI customization base class for wxRTC +// Author: Julian Smart +// Modified by: +// Created: 2010-11-14 +// RCS-ID: $Id$ +// Copyright: (c) Julian Smart +// Licence: wxWindows Licence +///////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_RICHTEXTUICUSTOMIZATION_H_ +#define _WX_RICHTEXTUICUSTOMIZATION_H_ + +#if wxUSE_RICHTEXT + +/** + @class wxRichTextUICustomization + The base class for functionality to plug in to various rich text control dialogs, + currently allowing the application to respond to Help button clicks without the + need to derive new dialog classes. + + The application will typically have calls like this in its initialisation: + + wxRichTextFormattingDialog::SetHelpId(ID_HELP_FORMATTINGDIALOG); + wxRichTextFormattingDialog::SetUICustomization(& wxGetApp().GetRichTextUICustomization()); + wxRichTextBordersPage::SetHelpId(ID_HELP_BORDERSPAGE); + + Only the wxRichTextFormattingDialog class needs to have its customization object and help id set, + though the application set them for individual pages if it wants. + **/ + +class WXDLLIMPEXP_RICHTEXT wxRichTextUICustomization +{ +public: + wxRichTextUICustomization() {} + virtual ~wxRichTextUICustomization() {} + + /// Show the help given the current active window, and a help topic id. + virtual bool ShowHelp(wxWindow* win, long id) = 0; +}; + +/** + @class wxRichTextHelpInfo + This class is used as a static member of dialogs, to store the help topic for the dialog + and also the customization object that will allow help to be shown appropriately for the application. + **/ + +class WXDLLIMPEXP_RICHTEXT wxRichTextHelpInfo +{ +public: + wxRichTextHelpInfo() + { + m_helpTopic = -1; + m_uiCustomization = NULL; + } + virtual ~wxRichTextHelpInfo() {} + + virtual bool ShowHelp(wxWindow* win) + { + if (m_uiCustomization && m_helpTopic != -1) + return m_uiCustomization->ShowHelp(win, m_helpTopic); + else + return false; + } + + /// Get the help topic identifier. + long GetHelpId() const { return m_helpTopic; } + + /// Set the help topic identifier. + void SetHelpId(long id) { m_helpTopic = id; } + + /// Get the UI customization object. + wxRichTextUICustomization* GetUICustomization() const { return m_uiCustomization; } + + /// Set the UI customization object. + void SetUICustomization(wxRichTextUICustomization* customization) { m_uiCustomization = customization; } + + /// Is there a valid help topic id? + bool HasHelpId() const { return m_helpTopic != -1; } + + /// Is there a valid customization object? + bool HasUICustomization() const { return m_uiCustomization != NULL; } + +protected: + wxRichTextUICustomization* m_uiCustomization; + long m_helpTopic; +}; + +/// Add this to the base class of dialogs + +#define DECLARE_BASE_CLASS_HELP_PROVISION() \ + virtual long GetHelpId() const = 0; \ + virtual wxRichTextUICustomization* GetUICustomization() const = 0; \ + virtual bool ShowHelp(wxWindow* win) = 0; + +/// A macro to make it easy to add help topic provision and UI customization +/// to a class. Optionally, add virtual functions to a base class +/// using DECLARE_BASE_CLASS_HELP_PROVISION. This means that the formatting dialog +/// can obtain help topics from its individual pages without needing +/// to know in advance what page classes are being used, allowing for extension +/// of the formatting dialog. + +#define DECLARE_HELP_PROVISION() \ + virtual long GetHelpId() const { return sm_helpInfo.GetHelpId(); } \ + virtual void SetHelpId(long id) { sm_helpInfo.SetHelpId(id); } \ + virtual wxRichTextUICustomization* GetUICustomization() const { return sm_helpInfo.GetUICustomization(); } \ + virtual void SetUICustomization(wxRichTextUICustomization* customization) { sm_helpInfo.SetUICustomization(customization); } \ + virtual bool ShowHelp(wxWindow* win) { return sm_helpInfo.ShowHelp(win); } \ +protected: \ + static wxRichTextHelpInfo sm_helpInfo; \ +public: + +/// Add this to the implementation file for each dialog that needs help provision. + +#define IMPLEMENT_HELP_PROVISION(theClass) \ + wxRichTextHelpInfo theClass::sm_helpInfo; + +#endif + // wxUSE_RICHTEXT + +#endif + // _WX_RICHTEXTUICUSTOMIZATION_H_ diff --git a/include/wx/richtext/richtextxml.h b/include/wx/richtext/richtextxml.h index a14e397bde..baf52c79a2 100644 --- a/include/wx/richtext/richtextxml.h +++ b/include/wx/richtext/richtextxml.h @@ -94,6 +94,7 @@ public: wxString GetNodeContent(wxXmlNode *node); wxString GetParamValue(wxXmlNode *node, const wxString& param); wxString GetText(wxXmlNode *node, const wxString& param = wxEmptyString, bool translate = false); + static wxXmlNode* FindNode(wxXmlNode* node, const wxString& name); protected: #if wxUSE_STREAMS diff --git a/samples/richtext/richtext.cpp b/samples/richtext/richtext.cpp index 1f728785ae..6868d5a6f4 100644 --- a/samples/richtext/richtext.cpp +++ b/samples/richtext/richtext.cpp @@ -719,6 +719,8 @@ MyFrame::MyFrame(const wxString& title, wxWindowID id, const wxPoint& pos, m_richTextCtrl->SetFont(font); + m_richTextCtrl->SetMargins(10, 10); + m_richTextCtrl->SetStyleSheet(wxGetApp().GetStyleSheet()); combo->SetStyleSheet(wxGetApp().GetStyleSheet()); @@ -757,6 +759,7 @@ void MyFrame::WriteInitialText() r.Freeze(); +#if 1 r.BeginParagraphSpacing(0, 20); r.BeginAlignment(wxTEXT_ALIGNMENT_CENTRE); @@ -950,7 +953,69 @@ void MyFrame::WriteInitialText() r.WriteText(wxT("Note: this sample content was generated programmatically from within the MyFrame constructor in the demo. The images were loaded from inline XPMs. Enjoy wxRichTextCtrl!\n")); r.EndParagraphSpacing(); +#endif +#if 1 + { + // Add a text box + + r.Newline(); + + wxRichTextAttr attr; + attr.GetTextBoxAttr().GetMargins().GetLeft().SetValue(20, wxTEXT_ATTR_UNITS_PIXELS); + attr.GetTextBoxAttr().GetMargins().GetTop().SetValue(20, wxTEXT_ATTR_UNITS_PIXELS); + attr.GetTextBoxAttr().GetMargins().GetRight().SetValue(20, wxTEXT_ATTR_UNITS_PIXELS); + attr.GetTextBoxAttr().GetMargins().GetBottom().SetValue(20, wxTEXT_ATTR_UNITS_PIXELS); + + attr.GetTextBoxAttr().GetBorder().SetColour(*wxBLACK); + attr.GetTextBoxAttr().GetBorder().SetWidth(1, wxTEXT_ATTR_UNITS_PIXELS); + attr.GetTextBoxAttr().GetBorder().SetStyle(wxTEXT_BOX_ATTR_BORDER_SOLID); + + wxRichTextBox* textBox = r.WriteTextBox(attr); + r.SetFocusObject(textBox); + + r.WriteText(wxT("This is a text box. Just testing! Once more unto the breach, dear friends, once more...")); + + r.SetFocusObject(NULL); // Set the focus back to the main buffer + r.SetInsertionPointEnd(); + } +#endif +#if 1 + { + // Add a table + + r.Newline(); + + wxRichTextAttr attr; + attr.GetTextBoxAttr().GetMargins().GetLeft().SetValue(5, wxTEXT_ATTR_UNITS_PIXELS); + attr.GetTextBoxAttr().GetMargins().GetTop().SetValue(5, wxTEXT_ATTR_UNITS_PIXELS); + attr.GetTextBoxAttr().GetMargins().GetRight().SetValue(5, wxTEXT_ATTR_UNITS_PIXELS); + attr.GetTextBoxAttr().GetMargins().GetBottom().SetValue(5, wxTEXT_ATTR_UNITS_PIXELS); + attr.GetTextBoxAttr().GetPadding() = attr.GetTextBoxAttr().GetMargins(); + + attr.GetTextBoxAttr().GetBorder().SetColour(*wxBLACK); + attr.GetTextBoxAttr().GetBorder().SetWidth(1, wxTEXT_ATTR_UNITS_PIXELS); + attr.GetTextBoxAttr().GetBorder().SetStyle(wxTEXT_BOX_ATTR_BORDER_SOLID); + + wxRichTextAttr cellAttr = attr; + cellAttr.GetTextBoxAttr().GetWidth().SetValue(200, wxTEXT_ATTR_UNITS_PIXELS); + cellAttr.GetTextBoxAttr().GetHeight().SetValue(150, wxTEXT_ATTR_UNITS_PIXELS); + + wxRichTextTable* table = r.WriteTable(3, 2, attr, cellAttr); + int i, j; + for (j = 0; j < table->GetRowCount(); j++) + { + for (i = 0; i < table->GetColumnCount(); i++) + { + wxString msg = wxString::Format(wxT("This is cell %d, %d"), (j+1), (i+1)); + r.SetFocusObject(table->GetCell(j, i)); + r.WriteText(msg); + } + } + r.SetFocusObject(NULL); // Set the focus back to the main buffer + r.SetInsertionPointEnd(); + } +#endif r.Thaw(); r.EndSuppressUndo(); @@ -1199,15 +1264,14 @@ void MyFrame::OnImage(wxCommandEvent& WXUNUSED(event)) range = m_richTextCtrl->GetSelectionRange(); wxASSERT(range.ToInternal().GetLength() == 1); - wxRichTextImage* image = wxDynamicCast(m_richTextCtrl->GetBuffer().GetLeafObjectAtPosition(range.GetStart()), wxRichTextImage); + wxRichTextImage* image = wxDynamicCast(m_richTextCtrl->GetFocusObject()->GetLeafObjectAtPosition(range.GetStart()), wxRichTextImage); if (image) { - wxRichTextImageDialog imageDlg(this); - imageDlg.SetImageObject(image, &m_richTextCtrl->GetBuffer()); + wxRichTextObjectPropertiesDialog imageDlg(image, this); if (imageDlg.ShowModal() == wxID_OK) { - image = imageDlg.ApplyImageAttr(); + imageDlg.ApplyStyle(m_richTextCtrl); } } } @@ -1263,7 +1327,7 @@ void MyFrame::OnUpdateImage(wxUpdateUIEvent& event) range = m_richTextCtrl->GetSelectionRange(); if (range.ToInternal().GetLength() == 1) { - obj = m_richTextCtrl->GetBuffer().GetLeafObjectAtPosition(range.GetStart()); + obj = m_richTextCtrl->GetFocusObject()->GetLeafObjectAtPosition(range.GetStart()); if (obj && obj->IsKindOf(CLASSINFO(wxRichTextImage))) { event.Enable(true); diff --git a/src/richtext/richtextbackgroundpage.cpp b/src/richtext/richtextbackgroundpage.cpp new file mode 100644 index 0000000000..1530fdfce2 --- /dev/null +++ b/src/richtext/richtextbackgroundpage.cpp @@ -0,0 +1,239 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: richtextbackgroundpage.cpp +// Purpose: +// Author: Julian Smart +// Modified by: +// Created: 13/11/2010 11:17:25 +// RCS-ID: +// Copyright: (c) Julian Smart +// Licence: wxWindows Licence +///////////////////////////////////////////////////////////////////////////// + +// For compilers that support precompilation, includes "wx/wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +////@begin includes +////@end includes + +#include "wx/richtext/richtextbackgroundpage.h" +#include "wx/richtext/richtextformatdlg.h" + +////@begin XPM images +////@end XPM images + + +/*! + * wxRichTextBackgroundPage type definition + */ + +IMPLEMENT_DYNAMIC_CLASS( wxRichTextBackgroundPage, wxRichTextDialogPage ) + + +/*! + * wxRichTextBackgroundPage event table definition + */ + +BEGIN_EVENT_TABLE( wxRichTextBackgroundPage, wxRichTextDialogPage ) +EVT_BUTTON(ID_RICHTEXT_BACKGROUND_COLOUR_SWATCH, wxRichTextBackgroundPage::OnColourSwatch) + +////@begin wxRichTextBackgroundPage event table entries +////@end wxRichTextBackgroundPage event table entries + +END_EVENT_TABLE() + +IMPLEMENT_HELP_PROVISION(wxRichTextBackgroundPage) + +/*! + * wxRichTextBackgroundPage constructors + */ + +wxRichTextBackgroundPage::wxRichTextBackgroundPage() +{ + Init(); +} + +wxRichTextBackgroundPage::wxRichTextBackgroundPage( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) +{ + Init(); + Create(parent, id, pos, size, style); +} + + +/*! + * wxRichTextBackgroundPage creator + */ + +bool wxRichTextBackgroundPage::Create( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) +{ +////@begin wxRichTextBackgroundPage creation + SetExtraStyle(wxWS_EX_VALIDATE_RECURSIVELY); + wxRichTextDialogPage::Create( parent, id, pos, size, style ); + + CreateControls(); + if (GetSizer()) + { + GetSizer()->SetSizeHints(this); + } + Centre(); +////@end wxRichTextBackgroundPage creation + return true; +} + + +/*! + * wxRichTextBackgroundPage destructor + */ + +wxRichTextBackgroundPage::~wxRichTextBackgroundPage() +{ +////@begin wxRichTextBackgroundPage destruction +////@end wxRichTextBackgroundPage destruction +} + + +/*! + * Member initialisation + */ + +void wxRichTextBackgroundPage::Init() +{ +////@begin wxRichTextBackgroundPage member initialisation + m_backgroundColourCheckBox = NULL; + m_backgroundColourSwatch = NULL; +////@end wxRichTextBackgroundPage member initialisation +} + + +/*! + * Control creation for wxRichTextBackgroundPage + */ + +void wxRichTextBackgroundPage::CreateControls() +{ +////@begin wxRichTextBackgroundPage content construction + wxRichTextBackgroundPage* itemRichTextDialogPage1 = this; + + wxBoxSizer* itemBoxSizer2 = new wxBoxSizer(wxVERTICAL); + itemRichTextDialogPage1->SetSizer(itemBoxSizer2); + + wxBoxSizer* itemBoxSizer3 = new wxBoxSizer(wxVERTICAL); + itemBoxSizer2->Add(itemBoxSizer3, 1, wxGROW, 5); + + wxBoxSizer* itemBoxSizer4 = new wxBoxSizer(wxHORIZONTAL); + itemBoxSizer3->Add(itemBoxSizer4, 0, wxGROW, 5); + + wxStaticText* itemStaticText5 = new wxStaticText( itemRichTextDialogPage1, wxID_STATIC, _("Background"), wxDefaultPosition, wxDefaultSize, 0 ); + itemStaticText5->SetFont(wxFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).GetPointSize(), wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).GetFamily(), wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).GetStyle(), wxBOLD, false, wxT(""))); + itemBoxSizer4->Add(itemStaticText5, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + wxStaticLine* itemStaticLine6 = new wxStaticLine( itemRichTextDialogPage1, wxID_STATIC, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); + itemBoxSizer4->Add(itemStaticLine6, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + wxBoxSizer* itemBoxSizer7 = new wxBoxSizer(wxHORIZONTAL); + itemBoxSizer3->Add(itemBoxSizer7, 0, wxGROW, 5); + + itemBoxSizer7->Add(5, 5, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + m_backgroundColourCheckBox = new wxCheckBox( itemRichTextDialogPage1, ID_RICHTEXT_BACKGROUND_COLOUR_CHECKBOX, _("Background &colour:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_backgroundColourCheckBox->SetValue(false); + m_backgroundColourCheckBox->SetHelpText(_("Enables a background colour.")); + if (wxRichTextBackgroundPage::ShowToolTips()) + m_backgroundColourCheckBox->SetToolTip(_("Enables a background colour.")); + itemBoxSizer7->Add(m_backgroundColourCheckBox, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + m_backgroundColourSwatch = new wxRichTextColourSwatchCtrl( itemRichTextDialogPage1, ID_RICHTEXT_BACKGROUND_COLOUR_SWATCH, wxDefaultPosition, wxSize(80, 20), wxBORDER_THEME ); + m_backgroundColourSwatch->SetHelpText(_("The background colour.")); + if (wxRichTextBackgroundPage::ShowToolTips()) + m_backgroundColourSwatch->SetToolTip(_("The background colour.")); + itemBoxSizer7->Add(m_backgroundColourSwatch, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + +////@end wxRichTextBackgroundPage content construction +} + + +/*! + * Should we show tooltips? + */ + +wxRichTextAttr* wxRichTextBackgroundPage::GetAttributes() +{ + return wxRichTextFormattingDialog::GetDialogAttributes(this); +} + +bool wxRichTextBackgroundPage::TransferDataToWindow() +{ + wxRichTextAttr* attr = GetAttributes(); + if (!attr->HasBackgroundColour()) + { + m_backgroundColourCheckBox->SetValue(false); + m_backgroundColourSwatch->SetColour(*wxWHITE); + } + else + { + m_backgroundColourCheckBox->SetValue(true); + m_backgroundColourSwatch->SetColour(attr->GetBackgroundColour()); + } + + return true; +} + +bool wxRichTextBackgroundPage::TransferDataFromWindow() +{ + wxRichTextAttr* attr = GetAttributes(); + if (m_backgroundColourCheckBox->GetValue()) + { + attr->SetBackgroundColour(m_backgroundColourSwatch->GetColour()); + } + else + { + attr->SetFlags(attr->GetFlags() & ~wxTEXT_ATTR_BACKGROUND_COLOUR); + } + + return true; +} + +// Respond to colour swatch click +void wxRichTextBackgroundPage::OnColourSwatch(wxCommandEvent& event) +{ + m_backgroundColourCheckBox->SetValue(true); + event.Skip(); +} + +bool wxRichTextBackgroundPage::ShowToolTips() +{ + return true; +} + +/*! + * Get bitmap resources + */ + +wxBitmap wxRichTextBackgroundPage::GetBitmapResource( const wxString& name ) +{ + // Bitmap retrieval +////@begin wxRichTextBackgroundPage bitmap retrieval + wxUnusedVar(name); + return wxNullBitmap; +////@end wxRichTextBackgroundPage bitmap retrieval +} + +/*! + * Get icon resources + */ + +wxIcon wxRichTextBackgroundPage::GetIconResource( const wxString& name ) +{ + // Icon retrieval +////@begin wxRichTextBackgroundPage icon retrieval + wxUnusedVar(name); + return wxNullIcon; +////@end wxRichTextBackgroundPage icon retrieval +} diff --git a/src/richtext/richtextborderspage.cpp b/src/richtext/richtextborderspage.cpp new file mode 100644 index 0000000000..b7c9f743bf --- /dev/null +++ b/src/richtext/richtextborderspage.cpp @@ -0,0 +1,923 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: richtextborderspage.cpp +// Purpose: +// Author: Julian Smart +// Modified by: +// Created: 21/10/2010 11:34:24 +// RCS-ID: +// Copyright: (c) Julian Smart +// Licence: +///////////////////////////////////////////////////////////////////////////// + +// For compilers that support precompilation, includes "wx/wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +////@begin includes +#include "wx/imaglist.h" +////@end includes + +#include "wx/richtext/richtextborderspage.h" + +////@begin XPM images +////@end XPM images + + +/*! + * wxRichTextBordersPage type definition + */ + +IMPLEMENT_DYNAMIC_CLASS( wxRichTextBordersPage, wxRichTextDialogPage ) + + +/*! + * wxRichTextBordersPage event table definition + */ + +BEGIN_EVENT_TABLE( wxRichTextBordersPage, wxRichTextDialogPage ) + + EVT_CHECKBOX(wxID_ANY, wxRichTextBordersPage::OnCommand) + EVT_TEXT(wxID_ANY, wxRichTextBordersPage::OnCommand) + EVT_TEXT_ENTER(wxID_ANY, wxRichTextBordersPage::OnCommand) + EVT_COMBOBOX(wxID_ANY, wxRichTextBordersPage::OnCommand) + EVT_BUTTON(wxID_ANY, wxRichTextBordersPage::OnCommand) + +////@begin wxRichTextBordersPage event table entries + EVT_CHECKBOX( ID_RICHTEXT_BORDER_LEFT_CHECKBOX, wxRichTextBordersPage::OnRichtextBorderCheckboxClick ) + + EVT_UPDATE_UI( ID_RICHTEXT_BORDER_LEFT, wxRichTextBordersPage::OnRichtextBorderLeftUpdate ) + + EVT_UPDATE_UI( ID_RICHTEXT_BORDER_LEFT_UNITS, wxRichTextBordersPage::OnRichtextBorderLeftUpdate ) + + EVT_UPDATE_UI( ID_RICHTEXT_BORDER_LEFT_STYLE, wxRichTextBordersPage::OnRichtextBorderLeftUpdate ) + + EVT_UPDATE_UI( ID_RICHTEXT_BORDER_LEFT_COLOUR, wxRichTextBordersPage::OnRichtextBorderLeftUpdate ) + + EVT_CHECKBOX( ID_RICHTEXT_BORDER_RIGHT_CHECKBOX, wxRichTextBordersPage::OnRichtextBorderCheckboxClick ) + + EVT_UPDATE_UI( ID_RICHTEXT_BORDER_RIGHT, wxRichTextBordersPage::OnRichtextBorderRightUpdate ) + + EVT_UPDATE_UI( ID_RICHTEXT_BORDER_RIGHT_UNITS, wxRichTextBordersPage::OnRichtextBorderRightUpdate ) + + EVT_UPDATE_UI( ID_RICHTEXT_BORDER_RIGHT_STYLE, wxRichTextBordersPage::OnRichtextBorderRightUpdate ) + + EVT_UPDATE_UI( ID_RICHTEXT_BORDER_RIGHT_COLOUR, wxRichTextBordersPage::OnRichtextBorderRightUpdate ) + + EVT_CHECKBOX( ID_RICHTEXT_BORDER_TOP_CHECKBOX, wxRichTextBordersPage::OnRichtextBorderCheckboxClick ) + + EVT_UPDATE_UI( ID_RICHTEXT_BORDER_TOP, wxRichTextBordersPage::OnRichtextBorderTopUpdate ) + + EVT_UPDATE_UI( ID_RICHTEXT_BORDER_TOP_UNITS, wxRichTextBordersPage::OnRichtextBorderTopUpdate ) + + EVT_UPDATE_UI( ID_RICHTEXT_BORDER_TOP_STYLE, wxRichTextBordersPage::OnRichtextBorderTopUpdate ) + + EVT_UPDATE_UI( ID_RICHTEXT_BORDER_TOP_COLOUR, wxRichTextBordersPage::OnRichtextBorderTopUpdate ) + + EVT_CHECKBOX( ID_RICHTEXT_BORDER_BOTTOM_CHECKBOX, wxRichTextBordersPage::OnRichtextBorderCheckboxClick ) + + EVT_UPDATE_UI( ID_RICHTEXT_BORDER_BOTTOM, wxRichTextBordersPage::OnRichtextBorderBottomUpdate ) + + EVT_UPDATE_UI( ID_RICHTEXT_BORDER_BOTTOM_UNITS, wxRichTextBordersPage::OnRichtextBorderBottomUpdate ) + + EVT_UPDATE_UI( ID_RICHTEXT_BORDER_BOTTOM_STYLE, wxRichTextBordersPage::OnRichtextBorderBottomUpdate ) + + EVT_UPDATE_UI( ID_RICHTEXT_BORDER_BOTTOM_COLOUR, wxRichTextBordersPage::OnRichtextBorderBottomUpdate ) + + EVT_CHECKBOX( ID_RICHTEXT_OUTLINE_LEFT_CHECKBOX, wxRichTextBordersPage::OnRichtextBorderCheckboxClick ) + + EVT_UPDATE_UI( ID_RICHTEXT_OUTLINE_LEFT, wxRichTextBordersPage::OnRichtextOutlineLeftUpdate ) + + EVT_UPDATE_UI( ID_RICHTEXT_OUTLINE_LEFT_UNITS, wxRichTextBordersPage::OnRichtextOutlineLeftUpdate ) + + EVT_UPDATE_UI( ID_RICHTEXT_OUTLINE_LEFT_STYLE, wxRichTextBordersPage::OnRichtextOutlineLeftUpdate ) + + EVT_UPDATE_UI( ID_RICHTEXT_OUTLINE_LEFT_COLOUR, wxRichTextBordersPage::OnRichtextOutlineLeftUpdate ) + + EVT_CHECKBOX( ID_RICHTEXT_OUTLINE_RIGHT_CHECKBOX, wxRichTextBordersPage::OnRichtextBorderCheckboxClick ) + + EVT_UPDATE_UI( ID_RICHTEXT_OUTLINE_RIGHT, wxRichTextBordersPage::OnRichtextOutlineRightUpdate ) + + EVT_UPDATE_UI( ID_RICHTEXT_OUTLINE_RIGHT_UNITS, wxRichTextBordersPage::OnRichtextOutlineRightUpdate ) + + EVT_UPDATE_UI( ID_RICHTEXT_OUTLINE_RIGHT_STYLE, wxRichTextBordersPage::OnRichtextOutlineRightUpdate ) + + EVT_UPDATE_UI( ID_RICHTEXT_OUTLINE_RIGHT_COLOUR, wxRichTextBordersPage::OnRichtextOutlineRightUpdate ) + + EVT_CHECKBOX( ID_RICHTEXT_OUTLINE_TOP_CHECKBOX, wxRichTextBordersPage::OnRichtextBorderCheckboxClick ) + + EVT_UPDATE_UI( ID_RICHTEXT_OUTLINE_TOP, wxRichTextBordersPage::OnRichtextOutlineTopUpdate ) + + EVT_UPDATE_UI( ID_RICHTEXT_OUTLINE_TOP_UNITS, wxRichTextBordersPage::OnRichtextOutlineTopUpdate ) + + EVT_UPDATE_UI( ID_RICHTEXT_OUTLINE_TOP_STYLE, wxRichTextBordersPage::OnRichtextOutlineTopUpdate ) + + EVT_UPDATE_UI( ID_RICHTEXT_OUTLINE_TOP_COLOUR, wxRichTextBordersPage::OnRichtextOutlineTopUpdate ) + + EVT_CHECKBOX( ID_RICHTEXT_OUTLINE_BOTTOM_CHECKBOX, wxRichTextBordersPage::OnRichtextBorderCheckboxClick ) + + EVT_UPDATE_UI( ID_RICHTEXT_OUTLINE_BOTTOM, wxRichTextBordersPage::OnRichtextOutlineBottomUpdate ) + + EVT_UPDATE_UI( ID_RICHTEXT_OUTLINE_BOTTOM_UNITS, wxRichTextBordersPage::OnRichtextOutlineBottomUpdate ) + + EVT_UPDATE_UI( ID_RICHTEXT_OUTLINE_BOTTOM_STYLE, wxRichTextBordersPage::OnRichtextOutlineBottomUpdate ) + + EVT_UPDATE_UI( ID_RICHTEXT_OUTLINE_BOTTOM_COLOUR, wxRichTextBordersPage::OnRichtextOutlineBottomUpdate ) + +////@end wxRichTextBordersPage event table entries + +END_EVENT_TABLE() + +IMPLEMENT_HELP_PROVISION(wxRichTextBordersPage) + +/*! + * wxRichTextBordersPage constructors + */ + +wxRichTextBordersPage::wxRichTextBordersPage() +{ + Init(); +} + +wxRichTextBordersPage::wxRichTextBordersPage( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) +{ + Init(); + Create(parent, id, pos, size, style); +} + + +/*! + * wxRichTextBordersPage creator + */ + +bool wxRichTextBordersPage::Create( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) +{ +////@begin wxRichTextBordersPage creation + SetExtraStyle(wxWS_EX_VALIDATE_RECURSIVELY); + wxRichTextDialogPage::Create( parent, id, pos, size, style ); + + CreateControls(); + if (GetSizer()) + { + GetSizer()->SetSizeHints(this); + } + Centre(); +////@end wxRichTextBordersPage creation + return true; +} + + +/*! + * wxRichTextBordersPage destructor + */ + +wxRichTextBordersPage::~wxRichTextBordersPage() +{ +////@begin wxRichTextBordersPage destruction +////@end wxRichTextBordersPage destruction +} + + +/*! + * Member initialisation + */ + +void wxRichTextBordersPage::Init() +{ + m_ignoreUpdates = false; + +////@begin wxRichTextBordersPage member initialisation + m_leftBorderCheckbox = NULL; + m_leftBorderWidth = NULL; + m_leftBorderWidthUnits = NULL; + m_leftBorderStyle = NULL; + m_leftBorderColour = NULL; + m_rightBorderCheckbox = NULL; + m_rightBorderWidth = NULL; + m_rightBorderWidthUnits = NULL; + m_rightBorderStyle = NULL; + m_rightBorderColour = NULL; + m_topBorderCheckbox = NULL; + m_topBorderWidth = NULL; + m_topBorderWidthUnits = NULL; + m_topBorderStyle = NULL; + m_topBorderColour = NULL; + m_bottomBorderCheckbox = NULL; + m_bottomBorderWidth = NULL; + m_bottomBorderWidthUnits = NULL; + m_bottomBorderStyle = NULL; + m_bottomBorderColour = NULL; + m_leftOutlineCheckbox = NULL; + m_leftOutlineWidth = NULL; + m_leftOutlineWidthUnits = NULL; + m_leftOutlineStyle = NULL; + m_leftOutlineColour = NULL; + m_rightOutlineCheckbox = NULL; + m_rightOutlineWidth = NULL; + m_rightOutlineWidthUnits = NULL; + m_rightOutlineStyle = NULL; + m_rightOutlineColour = NULL; + m_topOutlineCheckbox = NULL; + m_topOutlineWidth = NULL; + m_topOutlineWidthUnits = NULL; + m_topOutlineStyle = NULL; + m_topOutlineColour = NULL; + m_bottomOutlineCheckbox = NULL; + m_bottomOutlineWidth = NULL; + m_bottomOutlineWidthUnits = NULL; + m_bottomOutlineStyle = NULL; + m_bottomOutlineColour = NULL; + m_borderPreviewCtrl = NULL; +////@end wxRichTextBordersPage member initialisation +} + + +/*! + * Control creation for wxRichTextBordersPage + */ + +void wxRichTextBordersPage::CreateControls() +{ +////@begin wxRichTextBordersPage content construction + wxRichTextBordersPage* itemRichTextDialogPage1 = this; + + wxBoxSizer* itemBoxSizer2 = new wxBoxSizer(wxVERTICAL); + itemRichTextDialogPage1->SetSizer(itemBoxSizer2); + + wxBoxSizer* itemBoxSizer3 = new wxBoxSizer(wxVERTICAL); + itemBoxSizer2->Add(itemBoxSizer3, 1, wxGROW|wxALL, 5); + + wxNotebook* itemNotebook4 = new wxNotebook( itemRichTextDialogPage1, ID_RICHTEXTBORDERSPAGE_NOTEBOOK, wxDefaultPosition, wxDefaultSize, wxBK_DEFAULT ); + + wxPanel* itemPanel5 = new wxPanel( itemNotebook4, ID_RICHTEXTBORDERSPAGE_BORDERS, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + itemPanel5->SetExtraStyle(wxWS_EX_VALIDATE_RECURSIVELY); + wxBoxSizer* itemBoxSizer6 = new wxBoxSizer(wxVERTICAL); + itemPanel5->SetSizer(itemBoxSizer6); + + wxBoxSizer* itemBoxSizer7 = new wxBoxSizer(wxVERTICAL); + itemBoxSizer6->Add(itemBoxSizer7, 0, wxGROW|wxALL, 5); + wxBoxSizer* itemBoxSizer8 = new wxBoxSizer(wxHORIZONTAL); + itemBoxSizer7->Add(itemBoxSizer8, 0, wxGROW, 5); + wxStaticText* itemStaticText9 = new wxStaticText( itemPanel5, wxID_STATIC, _("Border"), wxDefaultPosition, wxDefaultSize, 0 ); + itemStaticText9->SetFont(wxFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).GetPointSize(), wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).GetFamily(), wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).GetStyle(), wxBOLD, false, wxT(""))); + itemBoxSizer8->Add(itemStaticText9, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + wxStaticLine* itemStaticLine10 = new wxStaticLine( itemPanel5, wxID_STATIC, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); + itemBoxSizer8->Add(itemStaticLine10, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + wxBoxSizer* itemBoxSizer11 = new wxBoxSizer(wxHORIZONTAL); + itemBoxSizer7->Add(itemBoxSizer11, 0, wxGROW, 5); + itemBoxSizer11->Add(5, 5, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + wxFlexGridSizer* itemFlexGridSizer13 = new wxFlexGridSizer(0, 2, 0, 0); + itemBoxSizer11->Add(itemFlexGridSizer13, 0, wxGROW, 5); + m_leftBorderCheckbox = new wxCheckBox( itemPanel5, ID_RICHTEXT_BORDER_LEFT_CHECKBOX, _("&Left:"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER ); + m_leftBorderCheckbox->SetValue(false); + itemFlexGridSizer13->Add(m_leftBorderCheckbox, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxALL, 5); + + wxBoxSizer* itemBoxSizer15 = new wxBoxSizer(wxHORIZONTAL); + itemFlexGridSizer13->Add(itemBoxSizer15, 0, wxGROW|wxALIGN_CENTER_VERTICAL, 5); + m_leftBorderWidth = new wxTextCtrl( itemPanel5, ID_RICHTEXT_BORDER_LEFT, wxEmptyString, wxDefaultPosition, wxSize(50, -1), 0 ); + itemBoxSizer15->Add(m_leftBorderWidth, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP|wxBOTTOM, 5); + + wxArrayString m_leftBorderWidthUnitsStrings; + m_leftBorderWidthUnitsStrings.Add(_("px")); + m_leftBorderWidthUnitsStrings.Add(_("cm")); + m_leftBorderWidthUnits = new wxComboBox( itemPanel5, ID_RICHTEXT_BORDER_LEFT_UNITS, _("px"), wxDefaultPosition, wxSize(60, -1), m_leftBorderWidthUnitsStrings, wxCB_READONLY ); + m_leftBorderWidthUnits->SetStringSelection(_("px")); + m_leftBorderWidthUnits->SetHelpText(_("Units for the left border width.")); + if (wxRichTextBordersPage::ShowToolTips()) + m_leftBorderWidthUnits->SetToolTip(_("Units for the left border width.")); + itemBoxSizer15->Add(m_leftBorderWidthUnits, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + itemBoxSizer15->Add(2, 5, 0, wxALIGN_CENTER_VERTICAL|wxALL, 2); + + wxArrayString m_leftBorderStyleStrings; + m_leftBorderStyle = new wxComboBox( itemPanel5, ID_RICHTEXT_BORDER_LEFT_STYLE, wxEmptyString, wxDefaultPosition, wxDefaultSize, m_leftBorderStyleStrings, wxCB_READONLY ); + itemBoxSizer15->Add(m_leftBorderStyle, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + itemBoxSizer15->Add(2, 5, 0, wxALIGN_CENTER_VERTICAL|wxALL, 2); + + m_leftBorderColour = new wxRichTextColourSwatchCtrl( itemPanel5, ID_RICHTEXT_BORDER_LEFT_COLOUR, wxDefaultPosition, wxSize(40, 20), wxBORDER_THEME ); + itemBoxSizer15->Add(m_leftBorderColour, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + m_rightBorderCheckbox = new wxCheckBox( itemPanel5, ID_RICHTEXT_BORDER_RIGHT_CHECKBOX, _("&Right:"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER ); + m_rightBorderCheckbox->SetValue(false); + itemFlexGridSizer13->Add(m_rightBorderCheckbox, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxALL, 5); + + wxBoxSizer* itemBoxSizer23 = new wxBoxSizer(wxHORIZONTAL); + itemFlexGridSizer13->Add(itemBoxSizer23, 0, wxGROW|wxALIGN_CENTER_VERTICAL, 5); + m_rightBorderWidth = new wxTextCtrl( itemPanel5, ID_RICHTEXT_BORDER_RIGHT, wxEmptyString, wxDefaultPosition, wxSize(50, -1), 0 ); + itemBoxSizer23->Add(m_rightBorderWidth, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP|wxBOTTOM, 5); + + wxArrayString m_rightBorderWidthUnitsStrings; + m_rightBorderWidthUnitsStrings.Add(_("px")); + m_rightBorderWidthUnitsStrings.Add(_("cm")); + m_rightBorderWidthUnits = new wxComboBox( itemPanel5, ID_RICHTEXT_BORDER_RIGHT_UNITS, _("px"), wxDefaultPosition, wxSize(60, -1), m_rightBorderWidthUnitsStrings, wxCB_READONLY ); + m_rightBorderWidthUnits->SetStringSelection(_("px")); + m_rightBorderWidthUnits->SetHelpText(_("Units for the right border width.")); + if (wxRichTextBordersPage::ShowToolTips()) + m_rightBorderWidthUnits->SetToolTip(_("Units for the right border width.")); + itemBoxSizer23->Add(m_rightBorderWidthUnits, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + itemBoxSizer23->Add(2, 5, 0, wxALIGN_CENTER_VERTICAL|wxALL, 2); + + wxArrayString m_rightBorderStyleStrings; + m_rightBorderStyle = new wxComboBox( itemPanel5, ID_RICHTEXT_BORDER_RIGHT_STYLE, wxEmptyString, wxDefaultPosition, wxDefaultSize, m_rightBorderStyleStrings, wxCB_READONLY ); + itemBoxSizer23->Add(m_rightBorderStyle, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + itemBoxSizer23->Add(2, 5, 0, wxALIGN_CENTER_VERTICAL|wxALL, 2); + + m_rightBorderColour = new wxRichTextColourSwatchCtrl( itemPanel5, ID_RICHTEXT_BORDER_RIGHT_COLOUR, wxDefaultPosition, wxSize(40, 20), wxBORDER_THEME ); + itemBoxSizer23->Add(m_rightBorderColour, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + m_topBorderCheckbox = new wxCheckBox( itemPanel5, ID_RICHTEXT_BORDER_TOP_CHECKBOX, _("&Top:"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER ); + m_topBorderCheckbox->SetValue(false); + itemFlexGridSizer13->Add(m_topBorderCheckbox, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxALL, 5); + + wxBoxSizer* itemBoxSizer31 = new wxBoxSizer(wxHORIZONTAL); + itemFlexGridSizer13->Add(itemBoxSizer31, 0, wxGROW|wxALIGN_CENTER_VERTICAL, 5); + m_topBorderWidth = new wxTextCtrl( itemPanel5, ID_RICHTEXT_BORDER_TOP, wxEmptyString, wxDefaultPosition, wxSize(50, -1), 0 ); + itemBoxSizer31->Add(m_topBorderWidth, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP|wxBOTTOM, 5); + + wxArrayString m_topBorderWidthUnitsStrings; + m_topBorderWidthUnitsStrings.Add(_("px")); + m_topBorderWidthUnitsStrings.Add(_("cm")); + m_topBorderWidthUnits = new wxComboBox( itemPanel5, ID_RICHTEXT_BORDER_TOP_UNITS, _("px"), wxDefaultPosition, wxSize(60, -1), m_topBorderWidthUnitsStrings, wxCB_READONLY ); + m_topBorderWidthUnits->SetStringSelection(_("px")); + m_topBorderWidthUnits->SetHelpText(_("Units for the top border width.")); + if (wxRichTextBordersPage::ShowToolTips()) + m_topBorderWidthUnits->SetToolTip(_("Units for the top border width.")); + itemBoxSizer31->Add(m_topBorderWidthUnits, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + itemBoxSizer31->Add(2, 5, 0, wxALIGN_CENTER_VERTICAL|wxALL, 2); + + wxArrayString m_topBorderStyleStrings; + m_topBorderStyle = new wxComboBox( itemPanel5, ID_RICHTEXT_BORDER_TOP_STYLE, wxEmptyString, wxDefaultPosition, wxDefaultSize, m_topBorderStyleStrings, wxCB_READONLY ); + itemBoxSizer31->Add(m_topBorderStyle, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + itemBoxSizer31->Add(2, 5, 0, wxALIGN_CENTER_VERTICAL|wxALL, 2); + + m_topBorderColour = new wxRichTextColourSwatchCtrl( itemPanel5, ID_RICHTEXT_BORDER_TOP_COLOUR, wxDefaultPosition, wxSize(40, 20), wxBORDER_THEME ); + itemBoxSizer31->Add(m_topBorderColour, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + m_bottomBorderCheckbox = new wxCheckBox( itemPanel5, ID_RICHTEXT_BORDER_BOTTOM_CHECKBOX, _("&Bottom:"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER ); + m_bottomBorderCheckbox->SetValue(false); + itemFlexGridSizer13->Add(m_bottomBorderCheckbox, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxALL, 5); + + wxBoxSizer* itemBoxSizer39 = new wxBoxSizer(wxHORIZONTAL); + itemFlexGridSizer13->Add(itemBoxSizer39, 0, wxGROW|wxALIGN_CENTER_VERTICAL, 5); + m_bottomBorderWidth = new wxTextCtrl( itemPanel5, ID_RICHTEXT_BORDER_BOTTOM, wxEmptyString, wxDefaultPosition, wxSize(50, -1), 0 ); + itemBoxSizer39->Add(m_bottomBorderWidth, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP|wxBOTTOM, 5); + + wxArrayString m_bottomBorderWidthUnitsStrings; + m_bottomBorderWidthUnitsStrings.Add(_("px")); + m_bottomBorderWidthUnitsStrings.Add(_("cm")); + m_bottomBorderWidthUnits = new wxComboBox( itemPanel5, ID_RICHTEXT_BORDER_BOTTOM_UNITS, _("px"), wxDefaultPosition, wxSize(60, -1), m_bottomBorderWidthUnitsStrings, wxCB_READONLY ); + m_bottomBorderWidthUnits->SetStringSelection(_("px")); + m_bottomBorderWidthUnits->SetHelpText(_("Units for the bottom border width.")); + if (wxRichTextBordersPage::ShowToolTips()) + m_bottomBorderWidthUnits->SetToolTip(_("Units for the bottom border width.")); + itemBoxSizer39->Add(m_bottomBorderWidthUnits, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + itemBoxSizer39->Add(2, 5, 0, wxALIGN_CENTER_VERTICAL|wxALL, 2); + + wxArrayString m_bottomBorderStyleStrings; + m_bottomBorderStyle = new wxComboBox( itemPanel5, ID_RICHTEXT_BORDER_BOTTOM_STYLE, wxEmptyString, wxDefaultPosition, wxDefaultSize, m_bottomBorderStyleStrings, wxCB_READONLY ); + itemBoxSizer39->Add(m_bottomBorderStyle, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + itemBoxSizer39->Add(2, 5, 0, wxALIGN_CENTER_VERTICAL|wxALL, 2); + + m_bottomBorderColour = new wxRichTextColourSwatchCtrl( itemPanel5, ID_RICHTEXT_BORDER_BOTTOM_COLOUR, wxDefaultPosition, wxSize(40, 20), wxBORDER_THEME ); + itemBoxSizer39->Add(m_bottomBorderColour, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + itemNotebook4->AddPage(itemPanel5, _("Border")); + + wxPanel* itemPanel46 = new wxPanel( itemNotebook4, ID_RICHTEXTBORDERSPAGE_OUTLINE, wxDefaultPosition, wxDefaultSize, wxNO_BORDER|wxTAB_TRAVERSAL ); + itemPanel46->SetExtraStyle(wxWS_EX_VALIDATE_RECURSIVELY); + wxBoxSizer* itemBoxSizer47 = new wxBoxSizer(wxVERTICAL); + itemPanel46->SetSizer(itemBoxSizer47); + + wxBoxSizer* itemBoxSizer48 = new wxBoxSizer(wxVERTICAL); + itemBoxSizer47->Add(itemBoxSizer48, 0, wxGROW|wxALL, 5); + wxBoxSizer* itemBoxSizer49 = new wxBoxSizer(wxHORIZONTAL); + itemBoxSizer48->Add(itemBoxSizer49, 0, wxGROW, 5); + wxStaticText* itemStaticText50 = new wxStaticText( itemPanel46, wxID_STATIC, _("Outline"), wxDefaultPosition, wxDefaultSize, 0 ); + itemStaticText50->SetFont(wxFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).GetPointSize(), wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).GetFamily(), wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).GetStyle(), wxBOLD, false, wxT(""))); + itemBoxSizer49->Add(itemStaticText50, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + wxStaticLine* itemStaticLine51 = new wxStaticLine( itemPanel46, wxID_STATIC, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); + itemBoxSizer49->Add(itemStaticLine51, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + wxBoxSizer* itemBoxSizer52 = new wxBoxSizer(wxHORIZONTAL); + itemBoxSizer48->Add(itemBoxSizer52, 0, wxGROW, 5); + itemBoxSizer52->Add(5, 5, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + wxFlexGridSizer* itemFlexGridSizer54 = new wxFlexGridSizer(0, 2, 0, 0); + itemBoxSizer52->Add(itemFlexGridSizer54, 0, wxGROW, 5); + m_leftOutlineCheckbox = new wxCheckBox( itemPanel46, ID_RICHTEXT_OUTLINE_LEFT_CHECKBOX, _("&Left:"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER ); + m_leftOutlineCheckbox->SetValue(false); + itemFlexGridSizer54->Add(m_leftOutlineCheckbox, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxALL, 5); + + wxBoxSizer* itemBoxSizer56 = new wxBoxSizer(wxHORIZONTAL); + itemFlexGridSizer54->Add(itemBoxSizer56, 0, wxGROW|wxALIGN_CENTER_VERTICAL, 5); + m_leftOutlineWidth = new wxTextCtrl( itemPanel46, ID_RICHTEXT_OUTLINE_LEFT, wxEmptyString, wxDefaultPosition, wxSize(50, -1), 0 ); + itemBoxSizer56->Add(m_leftOutlineWidth, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP|wxBOTTOM, 5); + + wxArrayString m_leftOutlineWidthUnitsStrings; + m_leftOutlineWidthUnitsStrings.Add(_("px")); + m_leftOutlineWidthUnitsStrings.Add(_("cm")); + m_leftOutlineWidthUnits = new wxComboBox( itemPanel46, ID_RICHTEXT_OUTLINE_LEFT_UNITS, _("px"), wxDefaultPosition, wxSize(60, -1), m_leftOutlineWidthUnitsStrings, wxCB_READONLY ); + m_leftOutlineWidthUnits->SetStringSelection(_("px")); + m_leftOutlineWidthUnits->SetHelpText(_("Units for the left outline width.")); + if (wxRichTextBordersPage::ShowToolTips()) + m_leftOutlineWidthUnits->SetToolTip(_("Units for the left outline width.")); + itemBoxSizer56->Add(m_leftOutlineWidthUnits, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + itemBoxSizer56->Add(2, 5, 0, wxALIGN_CENTER_VERTICAL|wxALL, 2); + + wxArrayString m_leftOutlineStyleStrings; + m_leftOutlineStyle = new wxComboBox( itemPanel46, ID_RICHTEXT_OUTLINE_LEFT_STYLE, wxEmptyString, wxDefaultPosition, wxDefaultSize, m_leftOutlineStyleStrings, wxCB_READONLY ); + itemBoxSizer56->Add(m_leftOutlineStyle, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + itemBoxSizer56->Add(2, 5, 0, wxALIGN_CENTER_VERTICAL|wxALL, 2); + + m_leftOutlineColour = new wxRichTextColourSwatchCtrl( itemPanel46, ID_RICHTEXT_OUTLINE_LEFT_COLOUR, wxDefaultPosition, wxSize(40, 20), wxBORDER_THEME ); + itemBoxSizer56->Add(m_leftOutlineColour, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + m_rightOutlineCheckbox = new wxCheckBox( itemPanel46, ID_RICHTEXT_OUTLINE_RIGHT_CHECKBOX, _("&Right:"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER ); + m_rightOutlineCheckbox->SetValue(false); + itemFlexGridSizer54->Add(m_rightOutlineCheckbox, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxALL, 5); + + wxBoxSizer* itemBoxSizer64 = new wxBoxSizer(wxHORIZONTAL); + itemFlexGridSizer54->Add(itemBoxSizer64, 0, wxGROW|wxALIGN_CENTER_VERTICAL, 5); + m_rightOutlineWidth = new wxTextCtrl( itemPanel46, ID_RICHTEXT_OUTLINE_RIGHT, wxEmptyString, wxDefaultPosition, wxSize(50, -1), 0 ); + itemBoxSizer64->Add(m_rightOutlineWidth, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP|wxBOTTOM, 5); + + wxArrayString m_rightOutlineWidthUnitsStrings; + m_rightOutlineWidthUnitsStrings.Add(_("px")); + m_rightOutlineWidthUnitsStrings.Add(_("cm")); + m_rightOutlineWidthUnits = new wxComboBox( itemPanel46, ID_RICHTEXT_OUTLINE_RIGHT_UNITS, _("px"), wxDefaultPosition, wxSize(60, -1), m_rightOutlineWidthUnitsStrings, wxCB_READONLY ); + m_rightOutlineWidthUnits->SetStringSelection(_("px")); + m_rightOutlineWidthUnits->SetHelpText(_("Units for the right outline width.")); + if (wxRichTextBordersPage::ShowToolTips()) + m_rightOutlineWidthUnits->SetToolTip(_("Units for the right outline width.")); + itemBoxSizer64->Add(m_rightOutlineWidthUnits, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + itemBoxSizer64->Add(2, 5, 0, wxALIGN_CENTER_VERTICAL|wxALL, 2); + + wxArrayString m_rightOutlineStyleStrings; + m_rightOutlineStyle = new wxComboBox( itemPanel46, ID_RICHTEXT_OUTLINE_RIGHT_STYLE, wxEmptyString, wxDefaultPosition, wxDefaultSize, m_rightOutlineStyleStrings, wxCB_READONLY ); + itemBoxSizer64->Add(m_rightOutlineStyle, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + itemBoxSizer64->Add(2, 5, 0, wxALIGN_CENTER_VERTICAL|wxALL, 2); + + m_rightOutlineColour = new wxRichTextColourSwatchCtrl( itemPanel46, ID_RICHTEXT_OUTLINE_RIGHT_COLOUR, wxDefaultPosition, wxSize(40, 20), wxBORDER_THEME ); + itemBoxSizer64->Add(m_rightOutlineColour, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + m_topOutlineCheckbox = new wxCheckBox( itemPanel46, ID_RICHTEXT_OUTLINE_TOP_CHECKBOX, _("&Top:"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER ); + m_topOutlineCheckbox->SetValue(false); + itemFlexGridSizer54->Add(m_topOutlineCheckbox, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxALL, 5); + + wxBoxSizer* itemBoxSizer72 = new wxBoxSizer(wxHORIZONTAL); + itemFlexGridSizer54->Add(itemBoxSizer72, 0, wxGROW|wxALIGN_CENTER_VERTICAL, 5); + m_topOutlineWidth = new wxTextCtrl( itemPanel46, ID_RICHTEXT_OUTLINE_TOP, wxEmptyString, wxDefaultPosition, wxSize(50, -1), 0 ); + itemBoxSizer72->Add(m_topOutlineWidth, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP|wxBOTTOM, 5); + + wxArrayString m_topOutlineWidthUnitsStrings; + m_topOutlineWidthUnitsStrings.Add(_("px")); + m_topOutlineWidthUnitsStrings.Add(_("cm")); + m_topOutlineWidthUnits = new wxComboBox( itemPanel46, ID_RICHTEXT_OUTLINE_TOP_UNITS, _("px"), wxDefaultPosition, wxSize(60, -1), m_topOutlineWidthUnitsStrings, wxCB_READONLY ); + m_topOutlineWidthUnits->SetStringSelection(_("px")); + m_topOutlineWidthUnits->SetHelpText(_("Units for the top outline width.")); + if (wxRichTextBordersPage::ShowToolTips()) + m_topOutlineWidthUnits->SetToolTip(_("Units for the top outline width.")); + itemBoxSizer72->Add(m_topOutlineWidthUnits, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + itemBoxSizer72->Add(2, 5, 0, wxALIGN_CENTER_VERTICAL|wxALL, 2); + + wxArrayString m_topOutlineStyleStrings; + m_topOutlineStyle = new wxComboBox( itemPanel46, ID_RICHTEXT_OUTLINE_TOP_STYLE, wxEmptyString, wxDefaultPosition, wxDefaultSize, m_topOutlineStyleStrings, wxCB_READONLY ); + itemBoxSizer72->Add(m_topOutlineStyle, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + itemBoxSizer72->Add(2, 5, 0, wxALIGN_CENTER_VERTICAL|wxALL, 2); + + m_topOutlineColour = new wxRichTextColourSwatchCtrl( itemPanel46, ID_RICHTEXT_OUTLINE_TOP_COLOUR, wxDefaultPosition, wxSize(40, 20), wxBORDER_THEME ); + itemBoxSizer72->Add(m_topOutlineColour, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + m_bottomOutlineCheckbox = new wxCheckBox( itemPanel46, ID_RICHTEXT_OUTLINE_BOTTOM_CHECKBOX, _("&Bottom:"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER ); + m_bottomOutlineCheckbox->SetValue(false); + itemFlexGridSizer54->Add(m_bottomOutlineCheckbox, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxALL, 5); + + wxBoxSizer* itemBoxSizer80 = new wxBoxSizer(wxHORIZONTAL); + itemFlexGridSizer54->Add(itemBoxSizer80, 0, wxGROW|wxALIGN_CENTER_VERTICAL, 5); + m_bottomOutlineWidth = new wxTextCtrl( itemPanel46, ID_RICHTEXT_OUTLINE_BOTTOM, wxEmptyString, wxDefaultPosition, wxSize(50, -1), 0 ); + itemBoxSizer80->Add(m_bottomOutlineWidth, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP|wxBOTTOM, 5); + + wxArrayString m_bottomOutlineWidthUnitsStrings; + m_bottomOutlineWidthUnitsStrings.Add(_("px")); + m_bottomOutlineWidthUnitsStrings.Add(_("cm")); + m_bottomOutlineWidthUnits = new wxComboBox( itemPanel46, ID_RICHTEXT_OUTLINE_BOTTOM_UNITS, _("px"), wxDefaultPosition, wxSize(60, -1), m_bottomOutlineWidthUnitsStrings, wxCB_READONLY ); + m_bottomOutlineWidthUnits->SetStringSelection(_("px")); + m_bottomOutlineWidthUnits->SetHelpText(_("Units for the bottom outline width.")); + if (wxRichTextBordersPage::ShowToolTips()) + m_bottomOutlineWidthUnits->SetToolTip(_("Units for the bottom outline width.")); + itemBoxSizer80->Add(m_bottomOutlineWidthUnits, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + itemBoxSizer80->Add(2, 5, 0, wxALIGN_CENTER_VERTICAL|wxALL, 2); + + wxArrayString m_bottomOutlineStyleStrings; + m_bottomOutlineStyle = new wxComboBox( itemPanel46, ID_RICHTEXT_OUTLINE_BOTTOM_STYLE, wxEmptyString, wxDefaultPosition, wxDefaultSize, m_bottomOutlineStyleStrings, wxCB_READONLY ); + itemBoxSizer80->Add(m_bottomOutlineStyle, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + itemBoxSizer80->Add(2, 5, 0, wxALIGN_CENTER_VERTICAL|wxALL, 2); + + m_bottomOutlineColour = new wxRichTextColourSwatchCtrl( itemPanel46, ID_RICHTEXT_OUTLINE_BOTTOM_COLOUR, wxDefaultPosition, wxSize(40, 20), wxBORDER_THEME ); + itemBoxSizer80->Add(m_bottomOutlineColour, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + itemNotebook4->AddPage(itemPanel46, _("Outline")); + + itemBoxSizer3->Add(itemNotebook4, 0, wxGROW|wxALL, 5); + + m_borderPreviewCtrl = new wxRichTextBorderPreviewCtrl( itemRichTextDialogPage1, ID_RICHTEXT_BORDER_PREVIEW, wxDefaultPosition, wxSize(60, 60), wxBORDER_THEME ); + itemBoxSizer3->Add(m_borderPreviewCtrl, 1, wxGROW|wxLEFT|wxRIGHT|wxBOTTOM, 5); + +////@end wxRichTextBordersPage content construction + + m_borderStyles.Add(wxTEXT_BOX_ATTR_BORDER_NONE); m_borderStyleNames.Add(_("None")); + m_borderStyles.Add(wxTEXT_BOX_ATTR_BORDER_SOLID); m_borderStyleNames.Add(_("Solid")); + m_borderStyles.Add(wxTEXT_BOX_ATTR_BORDER_DOTTED); m_borderStyleNames.Add(_("Dotted")); + m_borderStyles.Add(wxTEXT_BOX_ATTR_BORDER_DASHED); m_borderStyleNames.Add(_("Dashed")); + m_borderStyles.Add(wxTEXT_BOX_ATTR_BORDER_DOUBLE); m_borderStyleNames.Add(_("Double")); + m_borderStyles.Add(wxTEXT_BOX_ATTR_BORDER_GROOVE); m_borderStyleNames.Add(_("Groove")); + m_borderStyles.Add(wxTEXT_BOX_ATTR_BORDER_RIDGE); m_borderStyleNames.Add(_("Ridge")); + m_borderStyles.Add(wxTEXT_BOX_ATTR_BORDER_INSET); m_borderStyleNames.Add(_("Inset")); + m_borderStyles.Add(wxTEXT_BOX_ATTR_BORDER_OUTSET); m_borderStyleNames.Add(_("Outset")); + + m_ignoreUpdates = true; + + FillStyleComboBox(m_leftBorderStyle); + FillStyleComboBox(m_rightBorderStyle); + FillStyleComboBox(m_topBorderStyle); + FillStyleComboBox(m_bottomBorderStyle); + + FillStyleComboBox(m_leftOutlineStyle); + FillStyleComboBox(m_rightOutlineStyle); + FillStyleComboBox(m_topOutlineStyle); + FillStyleComboBox(m_bottomOutlineStyle); + + m_borderPreviewCtrl->SetAttributes(GetAttributes()); + + m_ignoreUpdates = false; +} + + +/*! + * Should we show tooltips? + */ + +bool wxRichTextBordersPage::ShowToolTips() +{ + return true; +} + +// Updates the preview +void wxRichTextBordersPage::OnCommand(wxCommandEvent& event) +{ + event.Skip(); + if (m_ignoreUpdates) + return; + + if (m_borderPreviewCtrl) + { + TransferDataFromWindow(); + m_borderPreviewCtrl->Refresh(); + } +} + +wxRichTextAttr* wxRichTextBordersPage::GetAttributes() +{ + return wxRichTextFormattingDialog::GetDialogAttributes(this); +} + +// Fill style combo +void wxRichTextBordersPage::FillStyleComboBox(wxComboBox* styleComboBox) +{ + styleComboBox->Freeze(); + styleComboBox->Append(m_borderStyleNames); + styleComboBox->Thaw(); +} + +bool wxRichTextBordersPage::TransferDataToWindow() +{ + m_ignoreUpdates = true; + + // Border + SetBorderValue(GetAttributes()->GetTextBoxAttr().GetBorder().GetLeft(), m_leftBorderWidth, m_leftBorderWidthUnits, m_leftBorderCheckbox, m_leftBorderStyle, m_leftBorderColour, m_borderStyles); + SetBorderValue(GetAttributes()->GetTextBoxAttr().GetBorder().GetRight(), m_rightBorderWidth, m_rightBorderWidthUnits, m_rightBorderCheckbox, m_rightBorderStyle, m_rightBorderColour, m_borderStyles); + SetBorderValue(GetAttributes()->GetTextBoxAttr().GetBorder().GetTop(), m_topBorderWidth, m_topBorderWidthUnits, m_topBorderCheckbox, m_topBorderStyle, m_topBorderColour, m_borderStyles); + SetBorderValue(GetAttributes()->GetTextBoxAttr().GetBorder().GetBottom(), m_bottomBorderWidth, m_bottomBorderWidthUnits, m_bottomBorderCheckbox, m_bottomBorderStyle, m_bottomBorderColour, m_borderStyles); + + // Outline + SetBorderValue(GetAttributes()->GetTextBoxAttr().GetOutline().GetLeft(), m_leftOutlineWidth, m_leftOutlineWidthUnits, m_leftOutlineCheckbox, m_leftOutlineStyle, m_leftOutlineColour, m_borderStyles); + SetBorderValue(GetAttributes()->GetTextBoxAttr().GetOutline().GetRight(), m_rightOutlineWidth, m_rightOutlineWidthUnits, m_rightOutlineCheckbox, m_rightOutlineStyle, m_rightOutlineColour, m_borderStyles); + SetBorderValue(GetAttributes()->GetTextBoxAttr().GetOutline().GetTop(), m_topOutlineWidth, m_topOutlineWidthUnits, m_topOutlineCheckbox, m_topOutlineStyle, m_topOutlineColour, m_borderStyles); + SetBorderValue(GetAttributes()->GetTextBoxAttr().GetOutline().GetBottom(), m_bottomOutlineWidth, m_bottomOutlineWidthUnits, m_bottomOutlineCheckbox, m_bottomOutlineStyle, m_bottomOutlineColour, m_borderStyles); + + m_ignoreUpdates = false; + + return true; +} + +bool wxRichTextBordersPage::TransferDataFromWindow() +{ + // Border + GetBorderValue(GetAttributes()->GetTextBoxAttr().GetBorder().GetLeft(), m_leftBorderWidth, m_leftBorderWidthUnits, m_leftBorderCheckbox, m_leftBorderStyle, m_leftBorderColour, m_borderStyles); + GetBorderValue(GetAttributes()->GetTextBoxAttr().GetBorder().GetRight(), m_rightBorderWidth, m_rightBorderWidthUnits, m_rightBorderCheckbox, m_rightBorderStyle, m_rightBorderColour, m_borderStyles); + GetBorderValue(GetAttributes()->GetTextBoxAttr().GetBorder().GetTop(), m_topBorderWidth, m_topBorderWidthUnits, m_topBorderCheckbox, m_topBorderStyle, m_topBorderColour, m_borderStyles); + GetBorderValue(GetAttributes()->GetTextBoxAttr().GetBorder().GetBottom(), m_bottomBorderWidth, m_bottomBorderWidthUnits, m_bottomBorderCheckbox, m_bottomBorderStyle, m_bottomBorderColour, m_borderStyles); + + // Outline + GetBorderValue(GetAttributes()->GetTextBoxAttr().GetOutline().GetLeft(), m_leftOutlineWidth, m_leftOutlineWidthUnits, m_leftOutlineCheckbox, m_leftOutlineStyle, m_leftOutlineColour, m_borderStyles); + GetBorderValue(GetAttributes()->GetTextBoxAttr().GetOutline().GetRight(), m_rightOutlineWidth, m_rightOutlineWidthUnits, m_rightOutlineCheckbox, m_rightOutlineStyle, m_rightOutlineColour, m_borderStyles); + GetBorderValue(GetAttributes()->GetTextBoxAttr().GetOutline().GetTop(), m_topOutlineWidth, m_topOutlineWidthUnits, m_topOutlineCheckbox, m_topOutlineStyle, m_topOutlineColour, m_borderStyles); + GetBorderValue(GetAttributes()->GetTextBoxAttr().GetOutline().GetBottom(), m_bottomOutlineWidth, m_bottomOutlineWidthUnits, m_bottomOutlineCheckbox, m_bottomOutlineStyle, m_bottomOutlineColour, m_borderStyles); + + return true; +} + +// Set the border controls +void wxRichTextBordersPage::SetBorderValue(wxTextAttrBorder& border, /* wxTextAttrBorder& borderToReset, */ wxTextCtrl* widthValueCtrl, wxComboBox* widthUnitsCtrl, wxCheckBox* checkBox, + wxComboBox* styleCtrl, wxRichTextColourSwatchCtrl* colourCtrl, const wxArrayInt& borderStyles) +{ + if (!border.IsValid()) + { + checkBox->Set3StateValue(wxCHK_UNDETERMINED); + widthValueCtrl->SetValue(wxT("1")); + widthUnitsCtrl->SetSelection(0); + colourCtrl->SetColour(*wxBLACK); + styleCtrl->SetSelection(0); + } + else + { + wxRichTextFormattingDialog::SetDimensionValue(border.GetWidth(), widthValueCtrl, widthUnitsCtrl, checkBox); + + int sel = borderStyles.Index(border.GetStyle()); + if (sel == -1) + sel = 1; + styleCtrl->SetSelection(sel); + colourCtrl->SetColour(border.GetColour()); + + if (sel == 0) + checkBox->Set3StateValue(wxCHK_UNCHECKED); + else + checkBox->Set3StateValue(wxCHK_CHECKED); + } +} + +// Get data from the border controls +void wxRichTextBordersPage::GetBorderValue(wxTextAttrBorder& border, /* wxTextAttrBorder& borderToReset, */ wxTextCtrl* widthValueCtrl, wxComboBox* widthUnitsCtrl, wxCheckBox* checkBox, + wxComboBox* styleCtrl, wxRichTextColourSwatchCtrl* colourCtrl, const wxArrayInt& borderStyles) +{ + wxRichTextFormattingDialog::GetDimensionValue(border.GetWidth(), widthValueCtrl, widthUnitsCtrl, checkBox); + + int sel = styleCtrl->GetSelection(); + border.SetColour(colourCtrl->GetColour()); + + if (checkBox->Get3StateValue() == wxCHK_UNDETERMINED) + { + // When we apply the attributes, we won't apply this one, to leave the original unchanged. + border.Reset(); + // borderToReset.Reset(); + } + else if (checkBox->Get3StateValue() == wxCHK_UNCHECKED) + { + // We make a note to reset this attribute. + // borderToReset.GetWidth().MakeValid(); + border.SetStyle(wxTEXT_BOX_ATTR_BORDER_NONE); + } + else + { + // borderToReset.Reset(); // Don't reset this, in case we were going to previously. + if (sel != -1) + border.SetStyle(borderStyles[sel]); + } +} + +/*! + * Get bitmap resources + */ + +wxBitmap wxRichTextBordersPage::GetBitmapResource( const wxString& name ) +{ + // Bitmap retrieval +////@begin wxRichTextBordersPage bitmap retrieval + wxUnusedVar(name); + return wxNullBitmap; +////@end wxRichTextBordersPage bitmap retrieval +} + +/*! + * Get icon resources + */ + +wxIcon wxRichTextBordersPage::GetIconResource( const wxString& name ) +{ + // Icon retrieval +////@begin wxRichTextBordersPage icon retrieval + wxUnusedVar(name); + return wxNullIcon; +////@end wxRichTextBordersPage icon retrieval +} + + +/*! + * wxEVT_UPDATE_UI event handler for ID_RICHTEXT_BORDER_LEFT + */ + +void wxRichTextBordersPage::OnRichtextBorderLeftUpdate( wxUpdateUIEvent& event ) +{ + event.Enable(m_leftBorderCheckbox->Get3StateValue() == wxCHK_CHECKED); +} + + +/*! + * wxEVT_UPDATE_UI event handler for ID_RICHTEXT_BORDER_RIGHT + */ + +void wxRichTextBordersPage::OnRichtextBorderRightUpdate( wxUpdateUIEvent& event ) +{ + event.Enable(m_rightBorderCheckbox->Get3StateValue() == wxCHK_CHECKED); +} + + +/*! + * wxEVT_UPDATE_UI event handler for ID_RICHTEXT_BORDER_TOP + */ + +void wxRichTextBordersPage::OnRichtextBorderTopUpdate( wxUpdateUIEvent& event ) +{ + event.Enable(m_topBorderCheckbox->Get3StateValue() == wxCHK_CHECKED); +} + +/*! + * wxEVT_UPDATE_UI event handler for ID_RICHTEXT_BORDER_BOTTOM + */ + +void wxRichTextBordersPage::OnRichtextBorderBottomUpdate( wxUpdateUIEvent& event ) +{ + event.Enable(m_bottomBorderCheckbox->Get3StateValue() == wxCHK_CHECKED); +} + + +/*! + * wxEVT_UPDATE_UI event handler for ID_RICHTEXT_OUTLINE_LEFT + */ + +void wxRichTextBordersPage::OnRichtextOutlineLeftUpdate( wxUpdateUIEvent& event ) +{ + event.Enable(m_leftOutlineCheckbox->Get3StateValue() == wxCHK_CHECKED); +} + + +/*! + * wxEVT_UPDATE_UI event handler for ID_RICHTEXT_OUTLINE_RIGHT + */ + +void wxRichTextBordersPage::OnRichtextOutlineRightUpdate( wxUpdateUIEvent& event ) +{ + event.Enable(m_rightOutlineCheckbox->Get3StateValue() == wxCHK_CHECKED); +} + + +/*! + * wxEVT_UPDATE_UI event handler for ID_RICHTEXT_OUTLINE_TOP + */ + +void wxRichTextBordersPage::OnRichtextOutlineTopUpdate( wxUpdateUIEvent& event ) +{ + event.Enable(m_topOutlineCheckbox->Get3StateValue() == wxCHK_CHECKED); +} + + +/*! + * wxEVT_UPDATE_UI event handler for ID_RICHTEXT_OUTLINE_BOTTOM + */ + +void wxRichTextBordersPage::OnRichtextOutlineBottomUpdate( wxUpdateUIEvent& event ) +{ + event.Enable(m_bottomOutlineCheckbox->Get3StateValue() == wxCHK_CHECKED); +} + +/*! + * wxEVT_COMMAND_CHECKBOX_CLICKED event handler for ID_RICHTEXT_BORDER_LEFT_CHECKBOX + */ + +void wxRichTextBordersPage::OnRichtextBorderCheckboxClick( wxCommandEvent& event ) +{ + if (m_ignoreUpdates) + return; + + m_ignoreUpdates = true; + wxCheckBox* checkBox = NULL; + wxComboBox* comboBox = NULL; + if (event.GetId() == ID_RICHTEXT_OUTLINE_LEFT_CHECKBOX) + { + checkBox = m_leftOutlineCheckbox; + comboBox = m_leftOutlineStyle; + } + else if (event.GetId() == ID_RICHTEXT_OUTLINE_TOP_CHECKBOX) + { + checkBox = m_topOutlineCheckbox; + comboBox = m_topOutlineStyle; + } + else if (event.GetId() == ID_RICHTEXT_OUTLINE_RIGHT_CHECKBOX) + { + checkBox = m_rightOutlineCheckbox; + comboBox = m_rightOutlineStyle; + } + else if (event.GetId() == ID_RICHTEXT_OUTLINE_BOTTOM_CHECKBOX) + { + checkBox = m_bottomOutlineCheckbox; + comboBox = m_bottomOutlineStyle; + } + else if (event.GetId() == ID_RICHTEXT_BORDER_LEFT_CHECKBOX) + { + checkBox = m_leftBorderCheckbox; + comboBox = m_leftBorderStyle; + } + else if (event.GetId() == ID_RICHTEXT_BORDER_TOP_CHECKBOX) + { + checkBox = m_topBorderCheckbox; + comboBox = m_topBorderStyle; + } + else if (event.GetId() == ID_RICHTEXT_BORDER_RIGHT_CHECKBOX) + { + checkBox = m_rightBorderCheckbox; + comboBox = m_rightBorderStyle; + } + else if (event.GetId() == ID_RICHTEXT_BORDER_BOTTOM_CHECKBOX) + { + checkBox = m_bottomBorderCheckbox; + comboBox = m_bottomBorderStyle; + } + + if (checkBox && comboBox) + { + if (checkBox->Get3StateValue() == wxCHK_UNCHECKED || checkBox->Get3StateValue() == wxCHK_UNDETERMINED) + comboBox->SetSelection(0); + else + comboBox->SetSelection(1); + + TransferDataFromWindow(); + m_borderPreviewCtrl->Refresh(); + } + + m_ignoreUpdates = false; +} + +BEGIN_EVENT_TABLE(wxRichTextBorderPreviewCtrl, wxWindow) + EVT_PAINT(wxRichTextBorderPreviewCtrl::OnPaint) +END_EVENT_TABLE() + +wxRichTextBorderPreviewCtrl::wxRichTextBorderPreviewCtrl(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& sz, long style) +{ + if ((style & wxBORDER_MASK) == wxBORDER_DEFAULT) + style |= wxBORDER_THEME; + + m_attributes = NULL; + + wxWindow::Create(parent, id, pos, sz, style); + SetBackgroundColour(*wxWHITE); +} + +void wxRichTextBorderPreviewCtrl::OnPaint(wxPaintEvent& WXUNUSED(event)) +{ + wxPaintDC dc(this); + + if (m_attributes) + { + wxRect rect = GetClientRect(); + + int margin = 10; + rect.x += margin; + rect.y += margin; + rect.width -= 2*margin; + rect.height -= 2*margin; + + wxRichTextObject::DrawBorder(dc, NULL, m_attributes->GetTextBoxAttr().GetOutline(), rect); + + rect.x += margin; + rect.y += margin; + rect.width -= 2*margin; + rect.height -= 2*margin; + + wxRichTextObject::DrawBorder(dc, NULL, m_attributes->GetTextBoxAttr().GetBorder(), rect); + } +} diff --git a/src/richtext/richtextbuffer.cpp b/src/richtext/richtextbuffer.cpp index 04a62fab25..83c74a023f 100644 --- a/src/richtext/richtextbuffer.cpp +++ b/src/richtext/richtextbuffer.cpp @@ -8,7 +8,7 @@ // Copyright: (c) Julian Smart // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// - +wxRICHTEXT_NONE // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" @@ -41,6 +41,7 @@ #include "wx/richtext/richtextctrl.h" #include "wx/richtext/richtextstyles.h" #include "wx/richtext/richtextimagedlg.h" +#include "wx/richtext/richtextsizepage.h" #include "wx/listimpl.cpp" #include "wx/arrimpl.cpp" @@ -82,7 +83,7 @@ int wxRichTextFloatRectMapCmp(wxRichTextFloatRectMap* r1, wxRichTextFloatRectMap class wxRichTextFloatCollector { public: - wxRichTextFloatCollector(int width); + wxRichTextFloatCollector(const wxRect& availableRect); ~wxRichTextFloatCollector(); // Collect the floating objects info in the given paragraph @@ -104,10 +105,16 @@ public: int GetLastRectBottom(); // Draw the floats inside a rect - void Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextRange& selectionRange, const wxRect& rect, int descent, int style); + void Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int descent, int style); // HitTest the floats - int HitTest(wxDC& dc, const wxPoint& pt, long& textPosition); + int HitTest(wxDC& dc, const wxPoint& pt, long& textPosition, wxRichTextObject** obj, int flags); + + // Get floating object count + int GetFloatingObjectCount() const { return m_left.GetCount() + m_right.GetCount(); } + + // Get floating objects + bool GetFloatingObjects(wxRichTextObjectList& objects) const; static int SearchAdjacentRect(const wxRichTextFloatRectMapArray& array, int point); @@ -115,17 +122,30 @@ public: static void FreeFloatRectMapArray(wxRichTextFloatRectMapArray& array); - static void DrawFloat(const wxRichTextFloatRectMapArray& array, wxDC& dc, const wxRichTextRange& range, const wxRichTextRange& selectionRange, const wxRect& rect, int descent, int style); + static void DrawFloat(const wxRichTextFloatRectMapArray& array, wxDC& dc, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int descent, int style); - static int HitTestFloat(const wxRichTextFloatRectMapArray& array, wxDC& WXUNUSED(dc), const wxPoint& pt, long& textPosition); + static int HitTestFloat(const wxRichTextFloatRectMapArray& array, wxDC& WXUNUSED(dc), const wxPoint& pt, long& textPosition, wxRichTextObject** obj, int flags); private: wxRichTextFloatRectMapArray m_left; wxRichTextFloatRectMapArray m_right; - int m_width; + //int m_width; + wxRect m_availableRect; wxRichTextParagraph* m_para; }; +// Get floating objects +bool wxRichTextFloatCollector::GetFloatingObjects(wxRichTextObjectList& objects) const +{ + size_t i; + for (i = 0; i < m_left.GetCount(); i++) + objects.Append(m_left[i]->anchor); + for (i = 0; i < m_right.GetCount(); i++) + objects.Append(m_right[i]->anchor); + return true; +} + + /* * Binary search helper function * The argument point is the Y coordinate, and this fuction @@ -183,9 +203,9 @@ int wxRichTextFloatCollector::GetWidthFromFloatRect(const wxRichTextFloatRectMap return ret; } -wxRichTextFloatCollector::wxRichTextFloatCollector(int width) : m_left(wxRichTextFloatRectMapCmp), m_right(wxRichTextFloatRectMapCmp) +wxRichTextFloatCollector::wxRichTextFloatCollector(const wxRect& rect) : m_left(wxRichTextFloatRectMapCmp), m_right(wxRichTextFloatRectMapCmp) { - m_width = width; + m_availableRect = rect; m_para = NULL; } @@ -207,9 +227,9 @@ int wxRichTextFloatCollector::GetFitPosition(const wxRichTextFloatRectMapArray& if (array.GetCount() == 0) return start; - unsigned int i = SearchAdjacentRect(array, start); + int i = SearchAdjacentRect(array, start); int last = start; - while (i < array.GetCount()) + while (i < (int) array.GetCount()) { if (array[i]->startY - last >= height) return last + 1; @@ -233,33 +253,35 @@ int wxRichTextFloatCollector::GetFitPosition(int direction, int start, int heigh } } +// Adds a floating image to the float collector. +// The actual positioning is done by wxRichTextParagraph::LayoutFloat. void wxRichTextFloatCollector::CollectFloat(wxRichTextParagraph* para, wxRichTextObject* floating) { - int direction = floating->GetFloatDirection(); + int direction = floating->GetFloatDirection(); - wxPoint pos = floating->GetPosition(); - wxSize size = floating->GetCachedSize(); - wxRichTextFloatRectMap *map = new wxRichTextFloatRectMap(pos.y, pos.y + size.y, size.x, floating); - switch (direction) - { - case wxTEXT_BOX_ATTR_FLOAT_NONE: - delete map; - break; - case wxTEXT_BOX_ATTR_FLOAT_LEFT: - // Just a not-enough simple assertion - wxASSERT (m_left.Index(map) == wxNOT_FOUND); - m_left.Add(map); - break; - case wxTEXT_BOX_ATTR_FLOAT_RIGHT: - wxASSERT (m_right.Index(map) == wxNOT_FOUND); - m_right.Add(map); - break; - default: - delete map; - wxASSERT("Must some error occurs"); - } + wxPoint pos = floating->GetPosition(); + wxSize size = floating->GetCachedSize(); + wxRichTextFloatRectMap *map = new wxRichTextFloatRectMap(pos.y, pos.y + size.y, size.x, floating); + switch (direction) + { + case wxTEXT_BOX_ATTR_FLOAT_NONE: + delete map; + break; + case wxTEXT_BOX_ATTR_FLOAT_LEFT: + // Just a not-enough simple assertion + wxASSERT (m_left.Index(map) == wxNOT_FOUND); + m_left.Add(map); + break; + case wxTEXT_BOX_ATTR_FLOAT_RIGHT: + wxASSERT (m_right.Index(map) == wxNOT_FOUND); + m_right.Add(map); + break; + default: + delete map; + wxASSERT("Unrecognised float attribute."); + } - m_para = para; + m_para = para; } void wxRichTextFloatCollector::CollectFloat(wxRichTextParagraph* para) @@ -290,18 +312,21 @@ wxRect wxRichTextFloatCollector::GetAvailableRect(int startY, int endY) int widthLeft = 0, widthRight = 0; if (m_left.GetCount() != 0) { - unsigned int i = SearchAdjacentRect(m_left, startY); - if (i < m_left.GetCount()) + int i = SearchAdjacentRect(m_left, startY); + if (i < (int) m_left.GetCount()) widthLeft = GetWidthFromFloatRect(m_left, i, startY, endY); } if (m_right.GetCount() != 0) { - unsigned int j = SearchAdjacentRect(m_right, startY); - if (j < m_right.GetCount()) + int j = SearchAdjacentRect(m_right, startY); + if (j < (int) m_right.GetCount()) widthRight = GetWidthFromFloatRect(m_right, j, startY, endY); } - return wxRect(widthLeft, 0, m_width - widthLeft - widthRight, 0); + // TODO: actually we want to use the actual image positions to find the + // available remaining space, since the image might not be right up against + // the left or right edge of the container. + return wxRect(widthLeft + m_availableRect.x, 0, m_availableRect.width - widthLeft - widthRight, 0); } int wxRichTextFloatCollector::GetLastRectBottom() @@ -319,48 +344,52 @@ int wxRichTextFloatCollector::GetLastRectBottom() return ret; } -void wxRichTextFloatCollector::DrawFloat(const wxRichTextFloatRectMapArray& array, wxDC& dc, const wxRichTextRange& WXUNUSED(range), const wxRichTextRange& WXUNUSED(selectionRange), const wxRect& rect, int descent, int style) +void wxRichTextFloatCollector::DrawFloat(const wxRichTextFloatRectMapArray& array, wxDC& dc, const wxRichTextRange& WXUNUSED(range), const wxRichTextSelection& selection, const wxRect& rect, int descent, int style) { int start = rect.y; int end = rect.y + rect.height; - unsigned int i, j; + int i, j; i = SearchAdjacentRect(array, start); - if (i >= array.GetCount()) + if (i < 0 || i >= (int) array.GetCount()) return; j = SearchAdjacentRect(array, end); - if (j >= array.GetCount()) + if (j < 0 || j >= (int) array.GetCount()) j = array.GetCount() - 1; while (i <= j) { wxRichTextObject* obj = array[i]->anchor; wxRichTextRange r = obj->GetRange(); - obj->Draw(dc, r, wxRichTextRange(0, -1), wxRect(obj->GetPosition(), obj->GetCachedSize()), descent, style); + obj->Draw(dc, r, selection, wxRect(obj->GetPosition(), obj->GetCachedSize()), descent, style); i++; } } -void wxRichTextFloatCollector::Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextRange& selectionRange, const wxRect& rect, int descent, int style) +void wxRichTextFloatCollector::Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int descent, int style) { if (m_left.GetCount() > 0) - DrawFloat(m_left, dc, range, selectionRange, rect, descent, style); + DrawFloat(m_left, dc, range, selection, rect, descent, style); if (m_right.GetCount() > 0) - DrawFloat(m_right, dc, range, selectionRange, rect, descent, style); + DrawFloat(m_right, dc, range, selection, rect, descent, style); } -int wxRichTextFloatCollector::HitTestFloat(const wxRichTextFloatRectMapArray& array, wxDC& WXUNUSED(dc), const wxPoint& pt, long& textPosition) +int wxRichTextFloatCollector::HitTestFloat(const wxRichTextFloatRectMapArray& array, wxDC& WXUNUSED(dc), const wxPoint& pt, long& textPosition, wxRichTextObject** obj, int WXUNUSED(flags)) { - unsigned int i; + int i; if (array.GetCount() == 0) return wxRICHTEXT_HITTEST_NONE; i = SearchAdjacentRect(array, pt.y); - if (i >= array.GetCount()) + if (i < 0 || i >= (int) array.GetCount()) return wxRICHTEXT_HITTEST_NONE; + if (!array[i]->anchor->IsShown()) + return wxRICHTEXT_HITTEST_NONE; + wxPoint point = array[i]->anchor->GetPosition(); wxSize size = array[i]->anchor->GetCachedSize(); if (point.x <= pt.x && point.x + size.x >= pt.x && point.y <= pt.y && point.y + size.y >= pt.y) { textPosition = array[i]->anchor->GetRange().GetStart(); + * obj = array[i]->anchor; if (pt.x > (pt.x + pt.x + size.x) / 2) return wxRICHTEXT_HITTEST_BEFORE; else @@ -370,12 +399,12 @@ int wxRichTextFloatCollector::HitTestFloat(const wxRichTextFloatRectMapArray& ar return wxRICHTEXT_HITTEST_NONE; } -int wxRichTextFloatCollector::HitTest(wxDC& dc, const wxPoint& pt, long& textPosition) +int wxRichTextFloatCollector::HitTest(wxDC& dc, const wxPoint& pt, long& textPosition, wxRichTextObject** obj, int flags) { - int ret = HitTestFloat(m_left, dc, pt, textPosition); + int ret = HitTestFloat(m_left, dc, pt, textPosition, obj, flags); if (ret == wxRICHTEXT_HITTEST_NONE) { - ret = HitTestFloat(m_right, dc, pt, textPosition); + ret = HitTestFloat(m_right, dc, pt, textPosition, obj, flags); } return ret; } @@ -435,14 +464,10 @@ IMPLEMENT_CLASS(wxRichTextObject, wxObject) wxRichTextObject::wxRichTextObject(wxRichTextObject* parent) { - m_dirty = false; m_refCount = 1; m_parent = parent; - m_leftMargin = 0; - m_rightMargin = 0; - m_topMargin = 0; - m_bottomMargin = 0; m_descent = 0; + m_show = true; } wxRichTextObject::~wxRichTextObject() @@ -460,25 +485,84 @@ void wxRichTextObject::Dereference() void wxRichTextObject::Copy(const wxRichTextObject& obj) { m_size = obj.m_size; + m_maxSize = obj.m_maxSize; + m_minSize = obj.m_minSize; m_pos = obj.m_pos; - m_dirty = obj.m_dirty; m_range = obj.m_range; + m_ownRange = obj.m_ownRange; m_attributes = obj.m_attributes; m_properties = obj.m_properties; m_descent = obj.m_descent; + m_show = obj.m_show; +} + +// Get/set the top-level container of this object. +wxRichTextParagraphLayoutBox* wxRichTextObject::GetContainer() const +{ + const wxRichTextObject* p = this; + while (p) + { + if (p->IsTopLevel()) + { + return wxDynamicCast(p, wxRichTextParagraphLayoutBox); + } + p = p->GetParent(); + } + return NULL; } void wxRichTextObject::SetMargins(int margin) { - m_leftMargin = m_rightMargin = m_topMargin = m_bottomMargin = margin; + SetMargins(margin, margin, margin, margin); } void wxRichTextObject::SetMargins(int leftMargin, int rightMargin, int topMargin, int bottomMargin) { - m_leftMargin = leftMargin; - m_rightMargin = rightMargin; - m_topMargin = topMargin; - m_bottomMargin = bottomMargin; + GetAttributes().GetTextBoxAttr().GetMargins().GetLeft().SetValue(leftMargin, wxTEXT_ATTR_UNITS_PIXELS); + GetAttributes().GetTextBoxAttr().GetMargins().GetRight().SetValue(rightMargin, wxTEXT_ATTR_UNITS_PIXELS); + GetAttributes().GetTextBoxAttr().GetMargins().GetTop().SetValue(topMargin, wxTEXT_ATTR_UNITS_PIXELS); + GetAttributes().GetTextBoxAttr().GetMargins().GetBottom().SetValue(bottomMargin, wxTEXT_ATTR_UNITS_PIXELS); +} + +int wxRichTextObject::GetLeftMargin() const +{ + return GetAttributes().GetTextBoxAttr().GetMargins().GetLeft().GetValue(); +} + +int wxRichTextObject::GetRightMargin() const +{ + return GetAttributes().GetTextBoxAttr().GetMargins().GetRight().GetValue(); +} + +int wxRichTextObject::GetTopMargin() const +{ + return GetAttributes().GetTextBoxAttr().GetMargins().GetTop().GetValue(); +} + +int wxRichTextObject::GetBottomMargin() const +{ + return GetAttributes().GetTextBoxAttr().GetMargins().GetBottom().GetValue(); +} + +// Calculate the available content space in the given rectangle, given the +// margins, border and padding specified in the object's attributes. +wxRect wxRichTextObject::GetAvailableContentArea(wxDC& dc, const wxRect& outerRect) const +{ + wxRect marginRect, borderRect, contentRect, paddingRect, outlineRect; + marginRect = outerRect; + GetBoxRects(dc, GetBuffer(), GetAttributes(), marginRect, borderRect, contentRect, paddingRect, outlineRect); + return contentRect; +} + +// Invalidate the buffer. With no argument, invalidates whole buffer. +void wxRichTextObject::Invalidate(const wxRichTextRange& invalidRange) +{ + if (invalidRange != wxRICHTEXT_NONE) + { + SetCachedSize(wxDefaultSize); + SetMaxSize(wxDefaultSize); + SetMinSize(wxDefaultSize); + } } // Convert units in tenths of a millimetre to device units @@ -502,6 +586,10 @@ int wxRichTextObject::ConvertTenthsMMToPixels(int ppi, int units, double scale) if (scale != 1.0) pixels /= scale; + // If the result is very small, make it at least one pixel in size. + if (pixels == 0 && units > 0) + pixels = 1; + return (int) pixels; } @@ -530,43 +618,62 @@ int wxRichTextObject::ConvertPixelsToTenthsMM(int ppi, int pixels, double scale) } // Draw the borders and background for the given rectangle and attributes. -// Width and height are taken to be the content size, so excluding any -// border, margin and padding. -bool wxRichTextObject::DrawBoxAttributes(wxDC& dc, const wxRichTextAttr& attr, const wxRect& boxRect) +// Width and height are taken to be the outer margin size, not the content. +bool wxRichTextObject::DrawBoxAttributes(wxDC& dc, wxRichTextBuffer* buffer, const wxRichTextAttr& attr, const wxRect& boxRect, int flags) { // Assume boxRect is the area around the content - wxRect contentRect = boxRect; - wxRect marginRect, borderRect, paddingRect, outlineRect; + wxRect marginRect = boxRect; + wxRect contentRect, borderRect, paddingRect, outlineRect; - GetBoxRects(dc, attr, marginRect, borderRect, contentRect, paddingRect, outlineRect); + GetBoxRects(dc, buffer, attr, marginRect, borderRect, contentRect, paddingRect, outlineRect); // Margin is transparent. Draw background from margin. - if (attr.HasBackgroundColour()) + if (attr.HasBackgroundColour() || (flags & wxRICHTEXT_DRAW_SELECTED)) { - wxPen pen(attr.GetBackgroundColour()); - wxBrush brush(attr.GetBackgroundColour()); + wxColour colour; + if (flags & wxRICHTEXT_DRAW_SELECTED) + { + // TODO: get selection colour from control? + colour = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT); + } + else + colour = attr.GetBackgroundColour(); + + wxPen pen(colour); + wxBrush brush(colour); dc.SetPen(pen); dc.SetBrush(brush); dc.DrawRectangle(marginRect); } - if (attr.GetTextBoxAttr().GetBorder().HasBorder()) - DrawBorder(dc, attr.GetTextBoxAttr().GetBorder(), borderRect); + if (flags & wxRICHTEXT_DRAW_GUIDELINES) + { + wxRichTextAttr editBorderAttr = attr; + // TODO: make guideline colour configurable + editBorderAttr.GetTextBoxAttr().GetBorder().SetColour(*wxLIGHT_GREY); + editBorderAttr.GetTextBoxAttr().GetBorder().SetWidth(1, wxTEXT_ATTR_UNITS_PIXELS); + editBorderAttr.GetTextBoxAttr().GetBorder().SetStyle(wxTEXT_BOX_ATTR_BORDER_SOLID); - if (attr.GetTextBoxAttr().GetOutline().HasBorder()) - DrawBorder(dc, attr.GetTextBoxAttr().GetOutline(), outlineRect); + DrawBorder(dc, buffer, editBorderAttr.GetTextBoxAttr().GetBorder(), borderRect, flags); + } + + if (attr.GetTextBoxAttr().GetBorder().IsValid()) + DrawBorder(dc, buffer, attr.GetTextBoxAttr().GetBorder(), borderRect); + + if (attr.GetTextBoxAttr().GetOutline().IsValid()) + DrawBorder(dc, buffer, attr.GetTextBoxAttr().GetOutline(), outlineRect); return true; } // Draw a border -bool wxRichTextObject::DrawBorder(wxDC& dc, const wxTextAttrBorders& attr, const wxRect& rect) +bool wxRichTextObject::DrawBorder(wxDC& dc, wxRichTextBuffer* buffer, const wxTextAttrBorders& attr, const wxRect& rect, int WXUNUSED(flags)) { int borderLeft = 0, borderRight = 0, borderTop = 0, borderBottom = 0; - wxTextAttrDimensionConverter converter(dc); + wxTextAttrDimensionConverter converter(dc, buffer ? buffer->GetScale() : 1.0); - if (attr.GetLeft().IsValid()) + if (attr.GetLeft().IsValid() && attr.GetLeft().GetStyle() != wxTEXT_BOX_ATTR_BORDER_NONE) { borderLeft = converter.GetPixels(attr.GetLeft().GetWidth()); wxColour col(attr.GetLeft().GetColour()); @@ -579,7 +686,7 @@ bool wxRichTextObject::DrawBorder(wxDC& dc, const wxTextAttrBorders& attr, const penStyle = wxDOT; else if (attr.GetLeft().GetStyle() == wxTEXT_BOX_ATTR_BORDER_DASHED) penStyle = wxLONG_DASH; - wxPen pen(col); + wxPen pen(col, 1, penStyle); dc.SetPen(pen); dc.DrawLine(rect.x, rect.y, rect.x, rect.y + rect.height); @@ -594,7 +701,7 @@ bool wxRichTextObject::DrawBorder(wxDC& dc, const wxTextAttrBorders& attr, const } } - if (attr.GetRight().IsValid()) + if (attr.GetRight().IsValid() && attr.GetRight().GetStyle() != wxTEXT_BOX_ATTR_BORDER_NONE) { borderRight = converter.GetPixels(attr.GetRight().GetWidth()); @@ -608,9 +715,9 @@ bool wxRichTextObject::DrawBorder(wxDC& dc, const wxTextAttrBorders& attr, const penStyle = wxDOT; else if (attr.GetRight().GetStyle() == wxTEXT_BOX_ATTR_BORDER_DASHED) penStyle = wxLONG_DASH; - wxPen pen(col); + wxPen pen(col, 1, penStyle); dc.SetPen(pen); - dc.DrawLine(rect.x + rect.width, rect.y, rect.x + rect.width, rect.y + rect.height); + dc.DrawLine(rect.x + rect.width, rect.y, rect.x + rect.width, rect.y + rect.height + 1); } else if (borderRight > 1) @@ -623,7 +730,7 @@ bool wxRichTextObject::DrawBorder(wxDC& dc, const wxTextAttrBorders& attr, const } } - if (attr.GetTop().IsValid()) + if (attr.GetTop().IsValid() && attr.GetTop().GetStyle() != wxTEXT_BOX_ATTR_BORDER_NONE) { borderTop = converter.GetPixels(attr.GetTop().GetWidth()); @@ -637,7 +744,7 @@ bool wxRichTextObject::DrawBorder(wxDC& dc, const wxTextAttrBorders& attr, const penStyle = wxDOT; else if (attr.GetTop().GetStyle() == wxTEXT_BOX_ATTR_BORDER_DASHED) penStyle = wxLONG_DASH; - wxPen pen(col); + wxPen pen(col, 1, penStyle); dc.SetPen(pen); dc.DrawLine(rect.x, rect.y, rect.x + rect.width, rect.y); @@ -652,7 +759,7 @@ bool wxRichTextObject::DrawBorder(wxDC& dc, const wxTextAttrBorders& attr, const } } - if (attr.GetBottom().IsValid()) + if (attr.GetBottom().IsValid() && attr.GetBottom().GetStyle() != wxTEXT_BOX_ATTR_BORDER_NONE) { borderBottom = converter.GetPixels(attr.GetBottom().GetWidth()); wxColour col(attr.GetTop().GetColour()); @@ -665,7 +772,7 @@ bool wxRichTextObject::DrawBorder(wxDC& dc, const wxTextAttrBorders& attr, const penStyle = wxDOT; else if (attr.GetBottom().GetStyle() == wxTEXT_BOX_ATTR_BORDER_DASHED) penStyle = wxLONG_DASH; - wxPen pen(col); + wxPen pen(col, 1, penStyle); dc.SetPen(pen); dc.DrawLine(rect.x, rect.y + rect.height, rect.x + rect.width, rect.y + rect.height); @@ -690,49 +797,49 @@ bool wxRichTextObject::DrawBorder(wxDC& dc, const wxTextAttrBorders& attr, const // // | Margin | Border | Padding | CONTENT | Padding | Border | Margin | -bool wxRichTextObject::GetBoxRects(wxDC& dc, const wxRichTextAttr& attr, wxRect& marginRect, wxRect& borderRect, wxRect& contentRect, wxRect& paddingRect, wxRect& outlineRect) +bool wxRichTextObject::GetBoxRects(wxDC& dc, wxRichTextBuffer* buffer, const wxRichTextAttr& attr, wxRect& marginRect, wxRect& borderRect, wxRect& contentRect, wxRect& paddingRect, wxRect& outlineRect) { int borderLeft = 0, borderRight = 0, borderTop = 0, borderBottom = 0; int outlineLeft = 0, outlineRight = 0, outlineTop = 0, outlineBottom = 0; int paddingLeft = 0, paddingRight = 0, paddingTop = 0, paddingBottom = 0; int marginLeft = 0, marginRight = 0, marginTop = 0, marginBottom = 0; - wxTextAttrDimensionConverter converter(dc); + wxTextAttrDimensionConverter converter(dc, buffer ? buffer->GetScale() : 1.0); - if (attr.GetTextBoxAttr().GetMargins().GetLeft().IsPresent()) + if (attr.GetTextBoxAttr().GetMargins().GetLeft().IsValid()) marginLeft = converter.GetPixels(attr.GetTextBoxAttr().GetMargins().GetLeft()); - if (attr.GetTextBoxAttr().GetMargins().GetRight().IsPresent()) + if (attr.GetTextBoxAttr().GetMargins().GetRight().IsValid()) marginRight = converter.GetPixels(attr.GetTextBoxAttr().GetMargins().GetRight()); - if (attr.GetTextBoxAttr().GetMargins().GetTop().IsPresent()) + if (attr.GetTextBoxAttr().GetMargins().GetTop().IsValid()) marginTop = converter.GetPixels(attr.GetTextBoxAttr().GetMargins().GetTop()); - if (attr.GetTextBoxAttr().GetMargins().GetLeft().IsPresent()) + if (attr.GetTextBoxAttr().GetMargins().GetLeft().IsValid()) marginBottom = converter.GetPixels(attr.GetTextBoxAttr().GetMargins().GetBottom()); - if (attr.GetTextBoxAttr().GetBorder().GetLeft().GetWidth().IsPresent()) + if (attr.GetTextBoxAttr().GetBorder().GetLeft().GetWidth().IsValid()) borderLeft = converter.GetPixels(attr.GetTextBoxAttr().GetBorder().GetLeft().GetWidth()); - if (attr.GetTextBoxAttr().GetBorder().GetRight().GetWidth().IsPresent()) + if (attr.GetTextBoxAttr().GetBorder().GetRight().GetWidth().IsValid()) borderRight = converter.GetPixels(attr.GetTextBoxAttr().GetBorder().GetRight().GetWidth()); - if (attr.GetTextBoxAttr().GetBorder().GetTop().GetWidth().IsPresent()) + if (attr.GetTextBoxAttr().GetBorder().GetTop().GetWidth().IsValid()) borderTop = converter.GetPixels(attr.GetTextBoxAttr().GetBorder().GetTop().GetWidth()); - if (attr.GetTextBoxAttr().GetBorder().GetLeft().GetWidth().IsPresent()) + if (attr.GetTextBoxAttr().GetBorder().GetLeft().GetWidth().IsValid()) borderBottom = converter.GetPixels(attr.GetTextBoxAttr().GetBorder().GetBottom().GetWidth()); - if (attr.GetTextBoxAttr().GetPadding().GetLeft().IsPresent()) + if (attr.GetTextBoxAttr().GetPadding().GetLeft().IsValid()) paddingLeft = converter.GetPixels(attr.GetTextBoxAttr().GetPadding().GetLeft()); - if (attr.GetTextBoxAttr().GetPadding().GetRight().IsPresent()) + if (attr.GetTextBoxAttr().GetPadding().GetRight().IsValid()) paddingRight = converter.GetPixels(attr.GetTextBoxAttr().GetPadding().GetRight()); - if (attr.GetTextBoxAttr().GetPadding().GetTop().IsPresent()) + if (attr.GetTextBoxAttr().GetPadding().GetTop().IsValid()) paddingTop = converter.GetPixels(attr.GetTextBoxAttr().GetPadding().GetTop()); - if (attr.GetTextBoxAttr().GetPadding().GetLeft().IsPresent()) + if (attr.GetTextBoxAttr().GetPadding().GetBottom().IsValid()) paddingBottom = converter.GetPixels(attr.GetTextBoxAttr().GetPadding().GetBottom()); - if (attr.GetTextBoxAttr().GetOutline().GetLeft().GetWidth().IsPresent()) + if (attr.GetTextBoxAttr().GetOutline().GetLeft().GetWidth().IsValid()) outlineLeft = converter.GetPixels(attr.GetTextBoxAttr().GetOutline().GetLeft().GetWidth()); - if (attr.GetTextBoxAttr().GetOutline().GetRight().GetWidth().IsPresent()) + if (attr.GetTextBoxAttr().GetOutline().GetRight().GetWidth().IsValid()) outlineRight = converter.GetPixels(attr.GetTextBoxAttr().GetOutline().GetRight().GetWidth()); - if (attr.GetTextBoxAttr().GetOutline().GetTop().GetWidth().IsPresent()) + if (attr.GetTextBoxAttr().GetOutline().GetTop().GetWidth().IsValid()) outlineTop = converter.GetPixels(attr.GetTextBoxAttr().GetOutline().GetTop().GetWidth()); - if (attr.GetTextBoxAttr().GetOutline().GetLeft().GetWidth().IsPresent()) + if (attr.GetTextBoxAttr().GetOutline().GetBottom().GetWidth().IsValid()) outlineBottom = converter.GetPixels(attr.GetTextBoxAttr().GetOutline().GetBottom().GetWidth()); int leftTotal = marginLeft + borderLeft + paddingLeft; @@ -774,8 +881,73 @@ bool wxRichTextObject::GetBoxRects(wxDC& dc, const wxRichTextAttr& attr, wxRect& return true; } +// Get the total margin for the object in pixels, taking into account margin, padding and border size +bool wxRichTextObject::GetTotalMargin(wxDC& dc, wxRichTextBuffer* buffer, const wxRichTextAttr& attr, int& leftMargin, int& rightMargin, + int& topMargin, int& bottomMargin) +{ + // Assume boxRect is the area around the content + wxRect contentRect, marginRect, borderRect, paddingRect, outlineRect; + marginRect = wxRect(0, 0, 1000, 1000); -/// Dump to output stream for debugging + GetBoxRects(dc, buffer, attr, marginRect, borderRect, contentRect, paddingRect, outlineRect); + + leftMargin = contentRect.GetLeft() - marginRect.GetLeft(); + rightMargin = marginRect.GetRight() - contentRect.GetRight(); + topMargin = contentRect.GetTop() - marginRect.GetTop(); + bottomMargin = marginRect.GetBottom() - contentRect.GetBottom(); + + return true; +} + +// Returns the rectangle which the child has available to it given restrictions specified in the +// child attribute, e.g. 50% width of the parent, 400 pixels, x position 20% of the parent, etc. +wxRect wxRichTextObject::AdjustAvailableSpace(wxDC& dc, wxRichTextBuffer* buffer, const wxRichTextAttr& WXUNUSED(parentAttr), const wxRichTextAttr& childAttr, const wxRect& availableParentSpace) +{ + wxRect rect = availableParentSpace; + double scale = 1.0; + if (buffer) + scale = buffer->GetScale(); + + wxTextAttrDimensionConverter converter(dc, scale, availableParentSpace.GetSize()); + + if (childAttr.GetTextBoxAttr().GetWidth().IsValid()) + rect.width = converter.GetPixels(childAttr.GetTextBoxAttr().GetWidth()); + + if (childAttr.GetTextBoxAttr().GetHeight().IsValid()) + rect.height = converter.GetPixels(childAttr.GetTextBoxAttr().GetHeight()); + + // Can specify either left or right for the position (we're assuming we can't + // set the left and right edges to effectively set the size. Would we want to do that?) + if (childAttr.GetTextBoxAttr().GetPosition().GetLeft().IsValid()) + { + rect.x = rect.x + converter.GetPixels(childAttr.GetTextBoxAttr().GetPosition().GetLeft()); + } + else if (childAttr.GetTextBoxAttr().GetPosition().GetRight().IsValid()) + { + int x = converter.GetPixels(childAttr.GetTextBoxAttr().GetPosition().GetRight()); + if (childAttr.GetTextBoxAttr().GetPosition().GetRight().GetPosition() == wxTEXT_BOX_ATTR_POSITION_RELATIVE) + rect.x = availableParentSpace.x + availableParentSpace.width - rect.width; + else + rect.x += x; + } + + if (childAttr.GetTextBoxAttr().GetPosition().GetTop().IsValid()) + { + rect.y = rect.y + converter.GetPixels(childAttr.GetTextBoxAttr().GetPosition().GetTop()); + } + else if (childAttr.GetTextBoxAttr().GetPosition().GetBottom().IsValid()) + { + int y = converter.GetPixels(childAttr.GetTextBoxAttr().GetPosition().GetBottom()); + if (childAttr.GetTextBoxAttr().GetPosition().GetBottom().GetPosition() == wxTEXT_BOX_ATTR_POSITION_RELATIVE) + rect.y = availableParentSpace.y + availableParentSpace.height - rect.height; + else + rect.y += y; + } + + return rect; +} + +// Dump to output stream for debugging void wxRichTextObject::Dump(wxTextOutputStream& stream) { stream << GetClassInfo()->GetClassName() << wxT("\n"); @@ -783,7 +955,7 @@ void wxRichTextObject::Dump(wxTextOutputStream& stream) stream << wxString::Format(wxT("Text colour: %d,%d,%d."), (int) m_attributes.GetTextColour().Red(), (int) m_attributes.GetTextColour().Green(), (int) m_attributes.GetTextColour().Blue()) << wxT("\n"); } -/// Gets the containing buffer +// Gets the containing buffer wxRichTextBuffer* wxRichTextObject::GetBuffer() const { const wxRichTextObject* obj = this; @@ -792,6 +964,102 @@ wxRichTextBuffer* wxRichTextObject::GetBuffer() const return wxDynamicCast(obj, wxRichTextBuffer); } +// Get the absolute object position, by traversing up the child/parent hierarchy +wxPoint wxRichTextObject::GetAbsolutePosition() const +{ + wxPoint pt = GetPosition(); + + wxRichTextObject* p = GetParent(); + while (p) + { + pt = pt + p->GetPosition(); + p = p->GetParent(); + } + + return pt; +} + +// Hit-testing: returns a flag indicating hit test details, plus +// information about position +int wxRichTextObject::HitTest(wxDC& WXUNUSED(dc), const wxPoint& pt, long& textPosition, wxRichTextObject** obj, wxRichTextObject** contextObj, int WXUNUSED(flags)) +{ + if (!IsShown()) + return wxRICHTEXT_HITTEST_NONE; + + wxRect rect = GetRect(); + if (pt.x >= rect.x && pt.x < rect.x + rect.width && + pt.y >= rect.y && pt.y < rect.y + rect.height) + { + *obj = this; + *contextObj = GetParentContainer(); + textPosition = GetRange().GetStart(); + return wxRICHTEXT_HITTEST_ON; + } + else + return wxRICHTEXT_HITTEST_NONE; +} + +// 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 maximum ('best') size +bool wxRichTextObject::LayoutToBestSize(wxDC& dc, wxRichTextBuffer* buffer, + const wxRichTextAttr& parentAttr, const wxRichTextAttr& attr, const wxRect& availableParentSpace, + int style) +{ + wxRect availableChildRect = AdjustAvailableSpace(dc, buffer, parentAttr, attr, availableParentSpace); + wxRect originalAvailableRect = availableChildRect; + Layout(dc, availableChildRect, style); + + wxSize maxSize = GetMaxSize(); + + // Don't ignore if maxSize.x is zero, since we need to redo the paragraph's lines + // on this basis + if (!attr.GetTextBoxAttr().GetWidth().IsValid() && maxSize.x < availableChildRect.width /* && maxSize.x > 0 */) + { + // Redo the layout with a fixed, minimum size this time. + Invalidate(wxRICHTEXT_ALL); + wxRichTextAttr newAttr(attr); + newAttr.GetTextBoxAttr().GetWidth().SetValue(maxSize.x, wxTEXT_ATTR_UNITS_PIXELS); + newAttr.GetTextBoxAttr().GetWidth().SetPosition(wxTEXT_BOX_ATTR_POSITION_ABSOLUTE); + + availableChildRect = AdjustAvailableSpace(dc, buffer, parentAttr, newAttr, availableParentSpace); + + // If a paragraph, align the whole paragraph. + // Problem with this: if we're limited by a floating object, a line may be centered + // w.r.t. the smaller resulting box rather than the actual available width. + if (attr.HasAlignment()) + { + // centering, right-justification + if (GetAttributes().GetAlignment() == wxTEXT_ALIGNMENT_CENTRE) + { + availableChildRect.x = (originalAvailableRect.GetWidth() - availableChildRect.GetWidth())/2 + availableChildRect.x; + } + else if (GetAttributes().GetAlignment() == wxTEXT_ALIGNMENT_RIGHT) + { + availableChildRect.x = availableChildRect.x + originalAvailableRect.GetWidth() - availableChildRect.GetWidth(); + } + } + + Layout(dc, availableChildRect, style); + } + + /* + __________________ + | ____________ | + | | | | + + + */ + + return true; +} + +// Move the object recursively, by adding the offset from old to new +void wxRichTextObject::Move(const wxPoint& pt) +{ + SetPosition(pt); +} + + /*! * wxRichTextCompositeObject * This is the base for drawable objects. @@ -901,22 +1169,34 @@ void wxRichTextCompositeObject::Copy(const wxRichTextCompositeObject& obj) /// Hit-testing: returns a flag indicating hit test details, plus /// information about position -int wxRichTextCompositeObject::HitTest(wxDC& dc, const wxPoint& pt, long& textPosition) +int wxRichTextCompositeObject::HitTest(wxDC& dc, const wxPoint& pt, long& textPosition, wxRichTextObject** obj, wxRichTextObject** contextObj, int flags) { + if (!IsShown()) + return wxRICHTEXT_HITTEST_NONE; + wxRichTextObjectList::compatibility_iterator node = m_children.GetFirst(); while (node) { wxRichTextObject* child = node->GetData(); - int ret = child->HitTest(dc, pt, textPosition); - if (ret != wxRICHTEXT_HITTEST_NONE) - return ret; + if (child->IsShown() && child->IsTopLevel() && (flags & wxRICHTEXT_HITTEST_NO_NESTED_OBJECTS)) + { + // Just check if we hit the overall object + int ret = child->wxRichTextObject::HitTest(dc, pt, textPosition, obj, contextObj, flags); + if (ret != wxRICHTEXT_HITTEST_NONE) + return ret; + } + else if (child->IsShown()) + { + int ret = child->HitTest(dc, pt, textPosition, obj, contextObj, flags); + if (ret != wxRICHTEXT_HITTEST_NONE) + return ret; + } node = node->GetNext(); } - textPosition = GetRange().GetEnd()-1; - return wxRICHTEXT_HITTEST_AFTER|wxRICHTEXT_HITTEST_OUTSIDE; + return wxRICHTEXT_HITTEST_NONE; } /// Finds the absolute position and row height for the given character position @@ -927,7 +1207,11 @@ bool wxRichTextCompositeObject::FindPosition(wxDC& dc, long index, wxPoint& pt, { wxRichTextObject* child = node->GetData(); - if (child->FindPosition(dc, index, pt, height, forceLineStart)) + // Don't recurse if the child is a top-level object, + // such as a text box, because the character position will no longer + // apply. By definition, a top-level object has its own range of + // character positions. + if (!child->IsTopLevel() && child->FindPosition(dc, index, pt, height, forceLineStart)) return true; node = node->GetNext(); @@ -942,6 +1226,12 @@ void wxRichTextCompositeObject::CalculateRange(long start, long& end) long current = start; long lastEnd = current; + if (IsTopLevel()) + { + current = 0; + lastEnd = 0; + } + wxRichTextObjectList::compatibility_iterator node = m_children.GetFirst(); while (node) { @@ -956,13 +1246,28 @@ void wxRichTextCompositeObject::CalculateRange(long start, long& end) node = node->GetNext(); } - end = lastEnd; + if (IsTopLevel()) + { + // A top-level object always has a range of size 1, + // because its children don't count at this level. + end = start; + m_range.SetRange(start, start); - // An object with no children has zero length - if (m_children.GetCount() == 0) - end --; + // An object with no children has zero length + if (m_children.GetCount() == 0) + lastEnd --; + m_ownRange.SetRange(0, lastEnd); + } + else + { + end = lastEnd; - m_range.SetRange(start, end); + // An object with no children has zero length + if (m_children.GetCount() == 0) + end --; + + m_range.SetRange(start, end); + } } /// Delete range from layout. @@ -986,7 +1291,9 @@ bool wxRichTextCompositeObject::DeleteRange(const wxRichTextRange& range) if (!obj->GetRange().IsOutside(range)) { - obj->DeleteRange(range); + // No need to delete within a top-level object; just removing this object will do fine + if (!obj->IsTopLevel()) + obj->DeleteRange(range); // Delete an empty object, or paragraph within this range. if (obj->IsEmpty() || @@ -1027,6 +1334,20 @@ wxString wxRichTextCompositeObject::GetTextForRange(const wxRichTextRange& range return text; } +/// Get the child object at the given character position +wxRichTextObject* wxRichTextCompositeObject::GetChildAtPosition(long pos) const +{ + wxRichTextObjectList::compatibility_iterator node = m_children.GetFirst(); + while (node) + { + wxRichTextObject* child = node->GetData(); + if (child->GetRange().GetStart() == pos) + return child; + node = node->GetNext(); + } + return NULL; +} + /// Recursively merge all pieces that can be merged. bool wxRichTextCompositeObject::Defragment(const wxRichTextRange& range) { @@ -1098,6 +1419,147 @@ void wxRichTextCompositeObject::Dump(wxTextOutputStream& stream) } } +/// Get/set the object size for the given range. Returns false if the range +/// is invalid for this object. +bool wxRichTextCompositeObject::GetRangeSize(const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, int flags, wxPoint position, wxArrayInt* partialExtents) const +{ + if (!range.IsWithin(GetRange())) + return false; + + wxSize sz; + + wxArrayInt childExtents; + wxArrayInt* p; + if (partialExtents) + p = & childExtents; + else + p = NULL; + + wxRichTextObjectList::compatibility_iterator node = m_children.GetFirst(); + while (node) + { + wxRichTextObject* child = node->GetData(); + if (!child->GetRange().IsOutside(range)) + { + // Floating objects have a zero size within the paragraph. + if (child->IsFloating()) + { + if (partialExtents) + { + int lastSize; + if (partialExtents->GetCount() > 0) + lastSize = (*partialExtents)[partialExtents->GetCount()-1]; + else + lastSize = 0; + + partialExtents->Add(0 /* zero size */ + lastSize); + } + } + else + { + wxSize childSize; + + wxRichTextRange rangeToUse = range; + rangeToUse.LimitTo(child->GetRange()); + if (child->IsTopLevel()) + rangeToUse = child->GetOwnRange(); + + int childDescent = 0; + + // At present wxRICHTEXT_HEIGHT_ONLY is only fast if we're 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) + { + childDescent = child->GetDescent(); + childSize = child->GetCachedSize(); + + sz.y = wxMax(sz.y, childSize.y); + sz.x += childSize.x; + descent = wxMax(descent, childDescent); + } + else if (child->GetRangeSize(rangeToUse, childSize, childDescent, dc, flags, wxPoint(position.x + sz.x, position.y), p)) + { + sz.y = wxMax(sz.y, childSize.y); + sz.x += childSize.x; + descent = wxMax(descent, childDescent); + + if ((flags & wxRICHTEXT_CACHE_SIZE) && (rangeToUse == child->GetRange() || child->IsTopLevel())) + { + child->SetCachedSize(childSize); + child->SetDescent(childDescent); + } + + if (partialExtents) + { + int lastSize; + if (partialExtents->GetCount() > 0) + lastSize = (*partialExtents)[partialExtents->GetCount()-1]; + else + lastSize = 0; + + size_t i; + for (i = 0; i < childExtents.GetCount(); i++) + { + partialExtents->Add(childExtents[i] + lastSize); + } + } + } + } + + if (p) + p->Clear(); + } + + node = node->GetNext(); + } + size = sz; + return true; +} + +// Invalidate the buffer. With no argument, invalidates whole buffer. +void wxRichTextCompositeObject::Invalidate(const wxRichTextRange& invalidRange) +{ + wxRichTextObject::Invalidate(invalidRange); + + wxRichTextObjectList::compatibility_iterator node = m_children.GetFirst(); + while (node) + { + wxRichTextObject* child = node->GetData(); + if (invalidRange != wxRICHTEXT_ALL && invalidRange != wxRICHTEXT_NONE && child->GetRange().IsOutside(invalidRange)) + { + // Skip + } + else if (child->IsTopLevel()) + { + if (invalidRange == wxRICHTEXT_NONE) + child->Invalidate(wxRICHTEXT_NONE); + else + child->Invalidate(wxRICHTEXT_ALL); // All children must be invalidated if within parent range + } + else + child->Invalidate(invalidRange); + node = node->GetNext(); + } +} + +// Move the object recursively, by adding the offset from old to new +void wxRichTextCompositeObject::Move(const wxPoint& pt) +{ + wxPoint oldPos = GetPosition(); + SetPosition(pt); + wxPoint offset = pt - oldPos; + + wxRichTextObjectList::compatibility_iterator node = m_children.GetFirst(); + while (node) + { + wxRichTextObject* child = node->GetData(); + wxPoint childPos = child->GetPosition() + offset; + child->Move(childPos); + node = node->GetNext(); + } +} + + /*! * wxRichTextParagraphLayoutBox * This box knows how to lay out paragraphs. @@ -1127,12 +1589,11 @@ void wxRichTextParagraphLayoutBox::Init() // For now, assume is the only box and has no initial size. m_range = wxRichTextRange(0, -1); + m_ownRange = wxRichTextRange(0, -1); - m_invalidRange.SetRange(-1, -1); - m_leftMargin = 4; - m_rightMargin = 4; - m_topMargin = 4; - m_bottomMargin = 4; + m_invalidRange = wxRICHTEXT_ALL; + + SetMargins(4); m_partialParagraph = false; m_floatCollector = NULL; } @@ -1159,11 +1620,11 @@ void wxRichTextParagraphLayoutBox::Copy(const wxRichTextParagraphLayoutBox& obj) } // Gather information about floating objects -bool wxRichTextParagraphLayoutBox::UpdateFloatingObjects(int width, wxRichTextObject* untilObj) +bool wxRichTextParagraphLayoutBox::UpdateFloatingObjects(const wxRect& availableRect, wxRichTextObject* untilObj) { if (m_floatCollector != NULL) delete m_floatCollector; - m_floatCollector = new wxRichTextFloatCollector(width); + m_floatCollector = new wxRichTextFloatCollector(availableRect); wxRichTextObjectList::compatibility_iterator node = m_children.GetFirst(); while (node && node->GetData() != untilObj) { @@ -1177,24 +1638,66 @@ bool wxRichTextParagraphLayoutBox::UpdateFloatingObjects(int width, wxRichTextOb return true; } -// HitTest -int wxRichTextParagraphLayoutBox::HitTest(wxDC& dc, const wxPoint& pt, long& textPosition) +// Returns the style sheet associated with the overall buffer. +wxRichTextStyleSheet* wxRichTextParagraphLayoutBox::GetStyleSheet() const { + return GetBuffer() ? GetBuffer()->GetStyleSheet() : (wxRichTextStyleSheet*) NULL; +} + +// Get the number of floating objects at this level +int wxRichTextParagraphLayoutBox::GetFloatingObjectCount() const +{ + if (m_floatCollector) + return m_floatCollector->GetFloatingObjectCount(); + else + return 0; +} + +// Get a list of floating objects +bool wxRichTextParagraphLayoutBox::GetFloatingObjects(wxRichTextObjectList& objects) const +{ + if (m_floatCollector) + { + return m_floatCollector->GetFloatingObjects(objects); + } + else + return false; +} + +// Calculate ranges +void wxRichTextParagraphLayoutBox::UpdateRanges() +{ + long start = 0; + if (GetParent()) + start = GetRange().GetStart(); + long end; + CalculateRange(start, end); +} + +// HitTest +int wxRichTextParagraphLayoutBox::HitTest(wxDC& dc, const wxPoint& pt, long& textPosition, wxRichTextObject** obj, wxRichTextObject** contextObj, int flags) +{ + if (!IsShown()) + return wxRICHTEXT_HITTEST_NONE; + int ret = wxRICHTEXT_HITTEST_NONE; if (m_floatCollector) - ret = m_floatCollector->HitTest(dc, pt, textPosition); + ret = m_floatCollector->HitTest(dc, pt, textPosition, obj, flags); if (ret == wxRICHTEXT_HITTEST_NONE) - return wxRichTextCompositeObject::HitTest(dc, pt, textPosition); + return wxRichTextCompositeObject::HitTest(dc, pt, textPosition, obj, contextObj, flags); else + { + *contextObj = this; return ret; + } } /// Draw the floating objects -void wxRichTextParagraphLayoutBox::DrawFloats(wxDC& dc, const wxRichTextRange& range, const wxRichTextRange& selectionRange, const wxRect& rect, int descent, int style) +void wxRichTextParagraphLayoutBox::DrawFloats(wxDC& dc, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int descent, int style) { if (m_floatCollector) - m_floatCollector->Draw(dc, range, selectionRange, rect, descent, style); + m_floatCollector->Draw(dc, range, selection, rect, descent, style); } void wxRichTextParagraphLayoutBox::MoveAnchoredObjectToParagraph(wxRichTextParagraph* from, wxRichTextParagraph* to, wxRichTextObject* obj) @@ -1207,18 +1710,37 @@ void wxRichTextParagraphLayoutBox::MoveAnchoredObjectToParagraph(wxRichTextParag } /// Draw the item -bool wxRichTextParagraphLayoutBox::Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextRange& selectionRange, const wxRect& rect, int descent, int style) +bool wxRichTextParagraphLayoutBox::Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int descent, int style) { - DrawFloats(dc, range, selectionRange, rect, descent, style); + if (!IsShown()) + return true; + + wxRect thisRect(GetPosition(), GetCachedSize()); + + int flags = style; + if (selection.IsValid() && GetParentContainer() != this && selection.WithinSelection(GetRange().GetStart(), GetParentContainer())) + flags |= wxRICHTEXT_DRAW_SELECTED; + + // Don't draw guidelines if at top level + int theseFlags = flags; + if (!GetParent()) + theseFlags &= ~wxRICHTEXT_DRAW_GUIDELINES; + DrawBoxAttributes(dc, GetBuffer(), GetAttributes(), thisRect, theseFlags); + + DrawFloats(dc, range, selection, rect, descent, style); wxRichTextObjectList::compatibility_iterator node = m_children.GetFirst(); while (node) { - wxRichTextParagraph* child = wxDynamicCast(node->GetData(), wxRichTextParagraph); - wxASSERT (child != NULL); + wxRichTextObject* child = node->GetData(); if (child && !child->GetRange().IsOutside(range)) { wxRect childRect(child->GetPosition(), child->GetCachedSize()); + wxRichTextRange childRange = range; + if (child->IsTopLevel()) + { + childRange = child->GetOwnRange(); + } if (((style & wxRICHTEXT_DRAW_IGNORE_CACHE) == 0) && childRect.GetTop() > rect.GetBottom()) { @@ -1230,7 +1752,7 @@ bool wxRichTextParagraphLayoutBox::Draw(wxDC& dc, const wxRichTextRange& range, // Skip } else - child->Draw(dc, range, selectionRange, rect, descent, style); + child->Draw(dc, childRange, selection, rect, descent, style); } node = node->GetNext(); @@ -1241,6 +1763,11 @@ bool wxRichTextParagraphLayoutBox::Draw(wxDC& dc, const wxRichTextRange& range, /// Lay the item out bool wxRichTextParagraphLayoutBox::Layout(wxDC& dc, const wxRect& rect, int style) { + SetPosition(rect.GetPosition()); + + if (!IsShown()) + return true; + wxRect availableSpace; bool formatRect = (style & wxRICHTEXT_LAYOUT_SPECIFIED_RECT) == wxRICHTEXT_LAYOUT_SPECIFIED_RECT; @@ -1251,10 +1778,8 @@ bool wxRichTextParagraphLayoutBox::Layout(wxDC& dc, const wxRect& rect, int styl // everything up to the start of the visible area is laid out correctly. if (formatRect) { - availableSpace = wxRect(0 + m_leftMargin, - 0 + m_topMargin, - rect.width - m_leftMargin - m_rightMargin, - rect.height); + wxRect rect2(0, 0, rect.width, rect.height); + availableSpace = GetAvailableContentArea(dc, rect2); // Invalidate the part of the buffer from the first visible line // to the end. If other parts of the buffer are currently invalid, @@ -1265,15 +1790,29 @@ bool wxRichTextParagraphLayoutBox::Layout(wxDC& dc, const wxRect& rect, int styl if (line) startPos = line->GetAbsoluteRange().GetStart(); - Invalidate(wxRichTextRange(startPos, GetRange().GetEnd())); + Invalidate(wxRichTextRange(startPos, GetOwnRange().GetEnd())); } else - availableSpace = wxRect(rect.x + m_leftMargin, - rect.y + m_topMargin, - rect.width - m_leftMargin - m_rightMargin, - rect.height - m_topMargin - m_bottomMargin); + { + availableSpace = GetAvailableContentArea(dc, rect); + } + + int leftMargin, rightMargin, topMargin, bottomMargin; + wxRichTextObject::GetTotalMargin(dc, GetBuffer(), GetAttributes(), leftMargin, rightMargin, + topMargin, bottomMargin); int maxWidth = 0; + int maxHeight = 0; + + // The maximum paragraph maximum width, so we can set the overall maximum width for this object + int maxMaxWidth = 0; + + // The maximum paragraph minimum width, so we can set the overall minimum width for this object + int maxMinWidth = 0; + + // If we have vertical alignment, we must recalculate everything. + bool hasVerticalAlignment = (GetAttributes().GetTextBoxAttr().HasVerticalAlignment() && + (GetAttributes().GetTextBoxAttr().GetVerticalAlignment() > wxTEXT_BOX_ATTR_VERTICAL_ALIGNMENT_TOP)); wxRichTextObjectList::compatibility_iterator node = m_children.GetFirst(); @@ -1285,10 +1824,10 @@ bool wxRichTextParagraphLayoutBox::Layout(wxDC& dc, const wxRect& rect, int styl if (invalidRange == wxRICHTEXT_NONE && !formatRect) return true; - if (invalidRange == wxRICHTEXT_ALL) + if (invalidRange == wxRICHTEXT_ALL || hasVerticalAlignment) layoutAll = true; else // If we know what range is affected, start laying out from that point on. - if (invalidRange.GetStart() >= GetRange().GetStart()) + if (invalidRange.GetStart() >= GetOwnRange().GetStart()) { wxRichTextParagraph* firstParagraph = GetParagraphAtPosition(invalidRange.GetStart()); if (firstParagraph) @@ -1313,7 +1852,7 @@ bool wxRichTextParagraphLayoutBox::Layout(wxDC& dc, const wxRect& rect, int styl } } - UpdateFloatingObjects(availableSpace.width, node ? node->GetData() : (wxRichTextObject*) NULL); + UpdateFloatingObjects(availableSpace, node ? node->GetData() : (wxRichTextObject*) NULL); // A way to force speedy rest-of-buffer layout (the 'else' below) bool forceQuickLayout = false; @@ -1325,58 +1864,144 @@ bool wxRichTextParagraphLayoutBox::Layout(wxDC& dc, const wxRect& rect, int styl wxRichTextParagraph* child = wxDynamicCast(node->GetData(), wxRichTextParagraph); wxCHECK_MSG( child, false, wxT("Unknown object in layout") ); - // TODO: what if the child hasn't been laid out (e.g. involved in Undo) but still has 'old' lines - if ( !forceQuickLayout && - (layoutAll || - child->GetLines().IsEmpty() || - !child->GetRange().IsOutside(invalidRange)) ) + if (child && child->IsShown()) { - child->Layout(dc, availableSpace, style); - - // Layout must set the cached size - availableSpace.y += child->GetCachedSize().y; - maxWidth = wxMax(maxWidth, child->GetCachedSize().x); - - // If we're just formatting the visible part of the buffer, - // and we're now past the bottom of the window, start quick - // layout. - if (formatRect && child->GetPosition().y > rect.GetBottom()) - forceQuickLayout = true; - } - else - { - // We're outside the immediately affected range, so now let's just - // move everything up or down. This assumes that all the children have previously - // been laid out and have wrapped line lists associated with them. - // TODO: check all paragraphs before the affected range. - - int inc = availableSpace.y - child->GetPosition().y; - - while (node) + // TODO: what if the child hasn't been laid out (e.g. involved in Undo) but still has 'old' lines + if ( !forceQuickLayout && + (layoutAll || + child->GetLines().IsEmpty() || + !child->GetRange().IsOutside(invalidRange)) ) { - wxRichTextParagraph* child = wxDynamicCast(node->GetData(), wxRichTextParagraph); - if (child) - { - if (child->GetLines().GetCount() == 0) - child->Layout(dc, availableSpace, style); - else - child->SetPosition(wxPoint(child->GetPosition().x, child->GetPosition().y + inc)); + // 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->LayoutToBestSize(dc, GetBuffer(), + GetAttributes(), child->GetAttributes(), availableSpace, style&~wxRICHTEXT_LAYOUT_SPECIFIED_RECT); - availableSpace.y += child->GetCachedSize().y; - maxWidth = wxMax(maxWidth, child->GetCachedSize().x); - } + // Layout must set the cached size + availableSpace.y += child->GetCachedSize().y; + maxWidth = wxMax(maxWidth, child->GetCachedSize().x); + maxMinWidth = wxMax(maxMinWidth, child->GetMinSize().x); + maxMaxWidth = wxMax(maxMaxWidth, child->GetMaxSize().x); - node = node->GetNext(); + // If we're just formatting the visible part of the buffer, + // and we're now past the bottom of the window, and we don't have any + // floating objects (since they may cause wrapping to change for the rest of the + // the buffer), start quick layout. + if (!hasVerticalAlignment && formatRect && child->GetPosition().y > rect.GetBottom() && GetFloatingObjectCount() == 0) + forceQuickLayout = true; + } + else + { + // We're outside the immediately affected range, so now let's just + // move everything up or down. This assumes that all the children have previously + // been laid out and have wrapped line lists associated with them. + // TODO: check all paragraphs before the affected range. + + int inc = availableSpace.y - child->GetPosition().y; + + while (node) + { + wxRichTextParagraph* child = wxDynamicCast(node->GetData(), wxRichTextParagraph); + if (child) + { + if (child->GetLines().GetCount() == 0) + { + // 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->LayoutToBestSize(dc, GetBuffer(), + GetAttributes(), child->GetAttributes(), availableSpace, style&~wxRICHTEXT_LAYOUT_SPECIFIED_RECT); + + //child->Layout(dc, availableChildRect, style); + } + else + child->Move(wxPoint(child->GetPosition().x, child->GetPosition().y + inc)); + + availableSpace.y += child->GetCachedSize().y; + maxWidth = wxMax(maxWidth, child->GetCachedSize().x); + maxMinWidth = wxMax(maxMinWidth, child->GetMinSize().x); + maxMaxWidth = wxMax(maxMaxWidth, child->GetMaxSize().x); + } + + node = node->GetNext(); + } + break; } - break; } node = node->GetNext(); } - SetCachedSize(wxSize(maxWidth, availableSpace.y)); + node = m_children.GetLast(); + if (node && node->GetData()->IsShown()) + { + wxRichTextObject* child = node->GetData(); + // maxHeight = (child->GetPosition().y - GetPosition().y) + child->GetCachedSize().y; + maxHeight = child->GetPosition().y - (GetPosition().y + topMargin) + child->GetCachedSize().y; + } + else + maxHeight = 0; // topMargin + bottomMargin; + + // TODO: (also in para layout) should set the + // object's size to an absolute one if specified, + // but if not specified, calculate it from content. + + // We need to add back the margins etc. + { + wxRect marginRect, borderRect, contentRect, paddingRect, outlineRect; + contentRect = wxRect(wxPoint(0, 0), wxSize(maxWidth, maxHeight)); + GetBoxRects(dc, GetBuffer(), GetAttributes(), marginRect, borderRect, contentRect, paddingRect, outlineRect); + SetCachedSize(marginRect.GetSize()); + } + + // The maximum size is the greatest of all maximum widths for all paragraphs. + { + wxRect marginRect, borderRect, contentRect, paddingRect, outlineRect; + contentRect = wxRect(wxPoint(0, 0), wxSize(maxMaxWidth, maxHeight)); // Actually max height is a lie, we can't know it + GetBoxRects(dc, GetBuffer(), GetAttributes(), marginRect, borderRect, contentRect, paddingRect, outlineRect); + SetMaxSize(marginRect.GetSize()); + } + + // The minimum size is the greatest of all minimum widths for all paragraphs. + { + wxRect marginRect, borderRect, contentRect, paddingRect, outlineRect; + contentRect = wxRect(wxPoint(0, 0), wxSize(maxMinWidth, maxHeight)); // Actually max height is a lie, we can't know it + GetBoxRects(dc, GetBuffer(), GetAttributes(), marginRect, borderRect, contentRect, paddingRect, outlineRect); + SetMinSize(marginRect.GetSize()); + } + + if (GetAttributes().GetTextBoxAttr().HasVerticalAlignment() && + (GetAttributes().GetTextBoxAttr().GetVerticalAlignment() > wxTEXT_BOX_ATTR_VERTICAL_ALIGNMENT_TOP)) + { + int yOffset = 0; + int leftOverSpace = availableSpace.height - topMargin - bottomMargin - maxHeight; + if (leftOverSpace > 0) + { + if (GetAttributes().GetTextBoxAttr().GetVerticalAlignment() == wxTEXT_BOX_ATTR_VERTICAL_ALIGNMENT_CENTRE) + { + yOffset = (leftOverSpace/2); + } + else if (GetAttributes().GetTextBoxAttr().GetVerticalAlignment() == wxTEXT_BOX_ATTR_VERTICAL_ALIGNMENT_BOTTOM) + { + yOffset = leftOverSpace; + } + } + + // Move all the children to vertically align the content + // This doesn't take into account floating objects, unfortunately. + if (yOffset != 0) + { + wxRichTextObjectList::compatibility_iterator node = m_children.GetFirst(); + while (node) + { + wxRichTextParagraph* child = wxDynamicCast(node->GetData(), wxRichTextParagraph); + if (child) + child->Move(wxPoint(child->GetPosition().x, child->GetPosition().y + yOffset)); + + node = node->GetNext(); + } + } + } - m_dirty = false; m_invalidRange = wxRICHTEXT_NONE; return true; @@ -1436,6 +2061,9 @@ bool wxRichTextParagraphLayoutBox::GetRangeSize(const wxRichTextRange& range, wx wxRichTextRange rangeToFind = range; rangeToFind.LimitTo(childRange); + if (child->IsTopLevel()) + rangeToFind = child->GetOwnRange(); + wxSize childSize; int childDescent = 0; @@ -1467,14 +2095,17 @@ wxRichTextParagraph* wxRichTextParagraphLayoutBox::GetParagraphAtPosition(long p { // child is a paragraph wxRichTextParagraph* child = wxDynamicCast(node->GetData(), wxRichTextParagraph); - wxASSERT (child != NULL); + // wxASSERT (child != NULL); - // Return first child in buffer if position is -1 - // if (pos == -1) - // return child; + if (child) + { + // Return first child in buffer if position is -1 + // if (pos == -1) + // return child; - if (child->GetRange().Contains(pos)) - return child; + if (child->GetRange().Contains(pos)) + return child; + } node = node->GetNext(); } @@ -1496,23 +2127,26 @@ wxRichTextLine* wxRichTextParagraphLayoutBox::GetLineAtPosition(long pos, bool c { // child is a paragraph wxRichTextParagraph* child = wxDynamicCast(obj, wxRichTextParagraph); - wxASSERT (child != NULL); + // wxASSERT (child != NULL); - wxRichTextLineList::compatibility_iterator node2 = child->GetLines().GetFirst(); - while (node2) + if (child) { - wxRichTextLine* line = node2->GetData(); + wxRichTextLineList::compatibility_iterator node2 = child->GetLines().GetFirst(); + while (node2) + { + wxRichTextLine* line = node2->GetData(); - wxRichTextRange range = line->GetAbsoluteRange(); + wxRichTextRange range = line->GetAbsoluteRange(); - if (range.Contains(pos) || + if (range.Contains(pos) || - // If the position is end-of-paragraph, then return the last line of - // of the paragraph. - ((range.GetEnd() == child->GetRange().GetEnd()-1) && (pos == child->GetRange().GetEnd()))) - return line; + // If the position is end-of-paragraph, then return the last line of + // of the paragraph. + ((range.GetEnd() == child->GetRange().GetEnd()-1) && (pos == child->GetRange().GetEnd()))) + return line; - node2 = node2->GetNext(); + node2 = node2->GetNext(); + } } } @@ -1533,19 +2167,22 @@ wxRichTextLine* wxRichTextParagraphLayoutBox::GetLineAtYPosition(int y) const while (node) { wxRichTextParagraph* child = wxDynamicCast(node->GetData(), wxRichTextParagraph); - wxASSERT (child != NULL); + // wxASSERT (child != NULL); - wxRichTextLineList::compatibility_iterator node2 = child->GetLines().GetFirst(); - while (node2) + if (child) { - wxRichTextLine* line = node2->GetData(); + wxRichTextLineList::compatibility_iterator node2 = child->GetLines().GetFirst(); + while (node2) + { + wxRichTextLine* line = node2->GetData(); - wxRect rect(line->GetRect()); + wxRect rect(line->GetRect()); - if (y <= rect.GetBottom()) - return line; + if (y <= rect.GetBottom()) + return line; - node2 = node2->GetNext(); + node2 = node2->GetNext(); + } } node = node->GetNext(); @@ -1568,9 +2205,11 @@ int wxRichTextParagraphLayoutBox::GetLineCount() const while (node) { wxRichTextParagraph* child = wxDynamicCast(node->GetData(), wxRichTextParagraph); - wxASSERT (child != NULL); + // wxASSERT (child != NULL); + + if (child) + count += child->GetLines().GetCount(); - count += child->GetLines().GetCount(); node = node->GetNext(); } return count; @@ -1625,7 +2264,6 @@ wxRichTextRange wxRichTextParagraphLayoutBox::AddParagraph(const wxString& text, AppendChild(para); UpdateRanges(); - SetDirty(true); return para->GetRange(); } @@ -1701,8 +2339,6 @@ wxRichTextRange wxRichTextParagraphLayoutBox::AddParagraphs(const wxString& text UpdateRanges(); - SetDirty(false); - return wxRichTextRange(firstPara->GetRange().GetStart(), lastPara->GetRange().GetEnd()); } @@ -1735,7 +2371,6 @@ wxRichTextRange wxRichTextParagraphLayoutBox::AddImage(const wxImage& image, wxR para->AppendChild(new wxRichTextImage(image, this, cStyle)); UpdateRanges(); - SetDirty(true); return para->GetRange(); } @@ -1747,8 +2382,6 @@ wxRichTextRange wxRichTextParagraphLayoutBox::AddImage(const wxImage& image, wxR bool wxRichTextParagraphLayoutBox::InsertFragment(long position, wxRichTextParagraphLayoutBox& fragment) { - SetDirty(true); - // First, find the first paragraph whose starting position is within the range. wxRichTextParagraph* para = GetParagraphAtPosition(position); if (para) @@ -2008,37 +2641,40 @@ long wxRichTextParagraphLayoutBox::GetVisibleLineNumber(long pos, bool caretPosi while (node) { wxRichTextParagraph* child = wxDynamicCast(node->GetData(), wxRichTextParagraph); - wxASSERT( child != NULL ); + // wxASSERT( child != NULL ); - if (child->GetRange().Contains(pos)) + if (child) { - wxRichTextLineList::compatibility_iterator node2 = child->GetLines().GetFirst(); - while (node2) + if (child->GetRange().Contains(pos)) { - wxRichTextLine* line = node2->GetData(); - wxRichTextRange lineRange = line->GetAbsoluteRange(); - - if (lineRange.Contains(pos) || pos == lineRange.GetStart()) + wxRichTextLineList::compatibility_iterator node2 = child->GetLines().GetFirst(); + while (node2) { - // If the caret is displayed at the end of the previous wrapped line, - // we want to return the line it's _displayed_ at (not the actual line - // containing the position). - if (lineRange.GetStart() == pos && !startOfLine && child->GetRange().GetStart() != pos) - return lineCount - 1; - else - return lineCount; + wxRichTextLine* line = node2->GetData(); + wxRichTextRange lineRange = line->GetAbsoluteRange(); + + if (lineRange.Contains(pos) || pos == lineRange.GetStart()) + { + // If the caret is displayed at the end of the previous wrapped line, + // we want to return the line it's _displayed_ at (not the actual line + // containing the position). + if (lineRange.GetStart() == pos && !startOfLine && child->GetRange().GetStart() != pos) + return lineCount - 1; + else + return lineCount; + } + + lineCount ++; + + node2 = node2->GetNext(); } - - lineCount ++; - - node2 = node2->GetNext(); + // If we didn't find it in the lines, it must be + // the last position of the paragraph. So return the last line. + return lineCount-1; } - // If we didn't find it in the lines, it must be - // the last position of the paragraph. So return the last line. - return lineCount-1; + else + lineCount += child->GetLines().GetCount(); } - else - lineCount += child->GetLines().GetCount(); node = node->GetNext(); } @@ -2056,25 +2692,28 @@ wxRichTextLine* wxRichTextParagraphLayoutBox::GetLineForVisibleLineNumber(long l while (node) { wxRichTextParagraph* child = wxDynamicCast(node->GetData(), wxRichTextParagraph); - wxASSERT(child != NULL); + // wxASSERT(child != NULL); - if (lineNumber < (int) (child->GetLines().GetCount() + lineCount)) + if (child) { - wxRichTextLineList::compatibility_iterator node2 = child->GetLines().GetFirst(); - while (node2) + if (lineNumber < (int) (child->GetLines().GetCount() + lineCount)) { - wxRichTextLine* line = node2->GetData(); + wxRichTextLineList::compatibility_iterator node2 = child->GetLines().GetFirst(); + while (node2) + { + wxRichTextLine* line = node2->GetData(); - if (lineCount == lineNumber) - return line; + if (lineCount == lineNumber) + return line; - lineCount ++; + lineCount ++; - node2 = node2->GetNext(); + node2 = node2->GetNext(); + } } + else + lineCount += child->GetLines().GetCount(); } - else - lineCount += child->GetLines().GetCount(); node = node->GetNext(); } @@ -2092,93 +2731,96 @@ bool wxRichTextParagraphLayoutBox::DeleteRange(const wxRichTextRange& range) while (node) { wxRichTextParagraph* obj = wxDynamicCast(node->GetData(), wxRichTextParagraph); - wxASSERT (obj != NULL); + // wxASSERT (obj != NULL); wxRichTextObjectList::compatibility_iterator next = node->GetNext(); - // Delete the range in each paragraph - - if (!obj->GetRange().IsOutside(range)) + if (obj) { - // Deletes the content of this object within the given range - obj->DeleteRange(range); + // Delete the range in each paragraph - wxRichTextRange thisRange = obj->GetRange(); - wxRichTextAttr thisAttr = obj->GetAttributes(); - - // If the whole paragraph is within the range to delete, - // delete the whole thing. - if (range.GetStart() <= thisRange.GetStart() && range.GetEnd() >= thisRange.GetEnd()) + if (!obj->GetRange().IsOutside(range)) { - // Delete the whole object - RemoveChild(obj, true); - obj = NULL; - } - else if (!firstPara) - firstPara = obj; + // Deletes the content of this object within the given range + obj->DeleteRange(range); - // If the range includes the paragraph end, we need to join this - // and the next paragraph. - if (range.GetEnd() <= thisRange.GetEnd()) - { - // We need to move the objects from the next paragraph - // to this paragraph + wxRichTextRange thisRange = obj->GetRange(); + wxRichTextAttr thisAttr = obj->GetAttributes(); - wxRichTextParagraph* nextParagraph = NULL; - if ((range.GetEnd() < thisRange.GetEnd()) && obj) - nextParagraph = obj; - else + // If the whole paragraph is within the range to delete, + // delete the whole thing. + if (range.GetStart() <= thisRange.GetStart() && range.GetEnd() >= thisRange.GetEnd()) { - // We're ending at the end of the paragraph, so merge the _next_ paragraph. - if (next) - nextParagraph = wxDynamicCast(next->GetData(), wxRichTextParagraph); + // Delete the whole object + RemoveChild(obj, true); + obj = NULL; } + else if (!firstPara) + firstPara = obj; - bool applyFinalParagraphStyle = firstPara && nextParagraph && nextParagraph != firstPara; - - wxRichTextAttr nextParaAttr; - if (applyFinalParagraphStyle) + // If the range includes the paragraph end, we need to join this + // and the next paragraph. + if (range.GetEnd() <= thisRange.GetEnd()) { - // Special case when deleting the end of a paragraph - use _this_ paragraph's style, - // not the next one. - if (range.GetStart() == range.GetEnd() && range.GetStart() == thisRange.GetEnd()) - nextParaAttr = thisAttr; + // We need to move the objects from the next paragraph + // to this paragraph + + wxRichTextParagraph* nextParagraph = NULL; + if ((range.GetEnd() < thisRange.GetEnd()) && obj) + nextParagraph = obj; else - nextParaAttr = nextParagraph->GetAttributes(); - } - - if (firstPara && nextParagraph && firstPara != nextParagraph) - { - // Move the objects to the previous para - wxRichTextObjectList::compatibility_iterator node1 = nextParagraph->GetChildren().GetFirst(); - - while (node1) { - wxRichTextObject* obj1 = node1->GetData(); - - firstPara->AppendChild(obj1); - - wxRichTextObjectList::compatibility_iterator next1 = node1->GetNext(); - nextParagraph->GetChildren().Erase(node1); - - node1 = next1; + // We're ending at the end of the paragraph, so merge the _next_ paragraph. + if (next) + nextParagraph = wxDynamicCast(next->GetData(), wxRichTextParagraph); } - // Delete the paragraph - RemoveChild(nextParagraph, true); + bool applyFinalParagraphStyle = firstPara && nextParagraph && nextParagraph != firstPara; + + wxRichTextAttr nextParaAttr; + if (applyFinalParagraphStyle) + { + // Special case when deleting the end of a paragraph - use _this_ paragraph's style, + // not the next one. + if (range.GetStart() == range.GetEnd() && range.GetStart() == thisRange.GetEnd()) + nextParaAttr = thisAttr; + else + nextParaAttr = nextParagraph->GetAttributes(); + } + + if (firstPara && nextParagraph && firstPara != nextParagraph) + { + // Move the objects to the previous para + wxRichTextObjectList::compatibility_iterator node1 = nextParagraph->GetChildren().GetFirst(); + + while (node1) + { + wxRichTextObject* obj1 = node1->GetData(); + + firstPara->AppendChild(obj1); + + wxRichTextObjectList::compatibility_iterator next1 = node1->GetNext(); + nextParagraph->GetChildren().Erase(node1); + + node1 = next1; + } + + // Delete the paragraph + RemoveChild(nextParagraph, true); + } + + // Avoid empty paragraphs + if (firstPara && firstPara->GetChildren().GetCount() == 0) + { + wxRichTextPlainText* text = new wxRichTextPlainText(wxEmptyString); + firstPara->AppendChild(text); + } + + if (applyFinalParagraphStyle) + firstPara->SetAttributes(nextParaAttr); + + return true; } - - // Avoid empty paragraphs - if (firstPara && firstPara->GetChildren().GetCount() == 0) - { - wxRichTextPlainText* text = new wxRichTextPlainText(wxEmptyString); - firstPara->AppendChild(text); - } - - if (applyFinalParagraphStyle) - firstPara->SetAttributes(nextParaAttr); - - return true; } } @@ -2324,6 +2966,8 @@ bool wxRichTextParagraphLayoutBox::SetStyle(const wxRichTextRange& range, const if (style.IsParagraphStyle()) paragraphStyle = true; + wxRichTextBuffer* buffer = GetBuffer(); + bool withUndo = ((flags & wxRICHTEXT_SETSTYLE_WITH_UNDO) != 0); bool applyMinimal = ((flags & wxRICHTEXT_SETSTYLE_OPTIMIZE) != 0); bool parasOnly = ((flags & wxRICHTEXT_SETSTYLE_PARAGRAPHS_ONLY) != 0); @@ -2334,43 +2978,43 @@ bool wxRichTextParagraphLayoutBox::SetStyle(const wxRichTextRange& range, const // Apply paragraph style first, if any wxRichTextAttr wholeStyle(style); - if (!removeStyle && wholeStyle.HasParagraphStyleName() && GetStyleSheet()) + if (!removeStyle && wholeStyle.HasParagraphStyleName() && buffer->GetStyleSheet()) { - wxRichTextParagraphStyleDefinition* def = GetStyleSheet()->FindParagraphStyle(wholeStyle.GetParagraphStyleName()); + wxRichTextParagraphStyleDefinition* def = buffer->GetStyleSheet()->FindParagraphStyle(wholeStyle.GetParagraphStyleName()); if (def) - wxRichTextApplyStyle(wholeStyle, def->GetStyleMergedWithBase(GetStyleSheet())); + wxRichTextApplyStyle(wholeStyle, def->GetStyleMergedWithBase(buffer->GetStyleSheet())); } // Limit the attributes to be set to the content to only character attributes. wxRichTextAttr characterAttributes(wholeStyle); characterAttributes.SetFlags(characterAttributes.GetFlags() & (wxTEXT_ATTR_CHARACTER)); - if (!removeStyle && characterAttributes.HasCharacterStyleName() && GetStyleSheet()) + if (!removeStyle && characterAttributes.HasCharacterStyleName() && buffer->GetStyleSheet()) { - wxRichTextCharacterStyleDefinition* def = GetStyleSheet()->FindCharacterStyle(characterAttributes.GetCharacterStyleName()); + wxRichTextCharacterStyleDefinition* def = buffer->GetStyleSheet()->FindCharacterStyle(characterAttributes.GetCharacterStyleName()); if (def) - wxRichTextApplyStyle(characterAttributes, def->GetStyleMergedWithBase(GetStyleSheet())); + wxRichTextApplyStyle(characterAttributes, def->GetStyleMergedWithBase(buffer->GetStyleSheet())); } // If we are associated with a control, make undoable; otherwise, apply immediately // to the data. - bool haveControl = (GetRichTextCtrl() != NULL); + bool haveControl = (buffer->GetRichTextCtrl() != NULL); wxRichTextAction* action = NULL; if (haveControl && withUndo) { - action = new wxRichTextAction(NULL, _("Change Style"), wxRICHTEXT_CHANGE_STYLE, & GetRichTextCtrl()->GetBuffer(), GetRichTextCtrl()); + action = new wxRichTextAction(NULL, _("Change Style"), wxRICHTEXT_CHANGE_STYLE, buffer, this, buffer->GetRichTextCtrl()); action->SetRange(range); - action->SetPosition(GetRichTextCtrl()->GetCaretPosition()); + action->SetPosition(buffer->GetRichTextCtrl()->GetCaretPosition()); } wxRichTextObjectList::compatibility_iterator node = m_children.GetFirst(); while (node) { wxRichTextParagraph* para = wxDynamicCast(node->GetData(), wxRichTextParagraph); - wxASSERT (para != NULL); + // wxASSERT (para != NULL); if (para && para->GetChildCount() > 0) { @@ -2412,7 +3056,7 @@ bool wxRichTextParagraphLayoutBox::SetStyle(const wxRichTextRange& range, const { // Only apply attributes that will make a difference to the combined // style as seen on the display - wxRichTextAttr combinedAttr(para->GetCombinedAttributes()); + wxRichTextAttr combinedAttr(para->GetCombinedAttributes(true)); wxRichTextApplyStyle(newPara->GetAttributes(), wholeStyle, & combinedAttr); } else @@ -2491,7 +3135,7 @@ bool wxRichTextParagraphLayoutBox::SetStyle(const wxRichTextRange& range, const { // Only apply attributes that will make a difference to the combined // style as seen on the display - wxRichTextAttr combinedAttr(newPara->GetCombinedAttributes(child->GetAttributes())); + wxRichTextAttr combinedAttr(newPara->GetCombinedAttributes(child->GetAttributes(), true)); wxRichTextApplyStyle(child->GetAttributes(), characterAttributes, & combinedAttr); } else @@ -2512,39 +3156,40 @@ bool wxRichTextParagraphLayoutBox::SetStyle(const wxRichTextRange& range, const // Do action, or delay it until end of batch. if (haveControl && withUndo) - GetRichTextCtrl()->GetBuffer().SubmitAction(action); + buffer->SubmitAction(action); return true; } -void wxRichTextParagraphLayoutBox::SetImageStyle(wxRichTextImage *image, const wxRichTextAttr& textAttr, int flags) +// Just change the attributes for this single object. +void wxRichTextParagraphLayoutBox::SetStyle(wxRichTextObject* obj, const wxRichTextAttr& textAttr, int flags) { + wxRichTextBuffer* buffer = GetBuffer(); bool withUndo = flags & wxRICHTEXT_SETSTYLE_WITH_UNDO; - bool haveControl = (GetRichTextCtrl() != NULL); - wxRichTextParagraph* newPara wxDUMMY_INITIALIZE(NULL); - wxRichTextParagraph* para = GetParagraphAtPosition(image->GetRange().GetStart()); + bool resetExistingStyle = ((flags & wxRICHTEXT_SETSTYLE_RESET) != 0); + bool haveControl = (buffer->GetRichTextCtrl() != NULL); + wxRichTextAction *action = NULL; - wxRichTextAttr oldTextAttr = image->GetAttributes(); + wxRichTextAttr newAttr = obj->GetAttributes(); + if (resetExistingStyle) + newAttr = textAttr; + else + newAttr.Apply(textAttr); if (haveControl && withUndo) { - action = new wxRichTextAction(NULL, _("Change Image Style"), wxRICHTEXT_CHANGE_STYLE, & GetRichTextCtrl()->GetBuffer(), GetRichTextCtrl()); - action->SetRange(image->GetRange().FromInternal()); - action->SetPosition(GetRichTextCtrl()->GetCaretPosition()); - image->SetAttributes(textAttr); + action = new wxRichTextAction(NULL, _("Change Object Style"), wxRICHTEXT_CHANGE_ATTRIBUTES, buffer, obj->GetContainer(), buffer->GetRichTextCtrl()); + action->SetRange(obj->GetRange().FromInternal()); + action->SetPosition(buffer->GetRichTextCtrl()->GetCaretPosition()); + action->MakeObject(obj); - // Set the new attribute - newPara = new wxRichTextParagraph(*para); - action->GetNewParagraphs().AppendChild(newPara); - // Change back to the old one - image->SetAttributes(oldTextAttr); - action->GetOldParagraphs().AppendChild(new wxRichTextParagraph(*para)); + action->GetAttributes() = newAttr; } else - newPara = para; + obj->GetAttributes() = newAttr; if (haveControl && withUndo) - GetRichTextCtrl()->GetBuffer().SubmitAction(action); + buffer->SubmitAction(action); } /// Get the text attributes for this position. @@ -2630,12 +3275,12 @@ bool wxRichTextParagraphLayoutBox::GetStyleForRange(const wxRichTextRange& range wxRichTextObjectList::compatibility_iterator node = GetChildren().GetFirst(); while (node) { - wxRichTextParagraph* para = (wxRichTextParagraph*) node->GetData(); - if (!(para->GetRange().GetStart() > range.GetEnd() || para->GetRange().GetEnd() < range.GetStart())) + wxRichTextParagraph* para = wxDynamicCast(node->GetData(), wxRichTextParagraph); + if (para && !(para->GetRange().GetStart() > range.GetEnd() || para->GetRange().GetEnd() < range.GetStart())) { if (para->GetChildren().GetCount() == 0) { - wxRichTextAttr paraStyle = para->GetCombinedAttributes(); + wxRichTextAttr paraStyle = para->GetCombinedAttributes(true /* use box attributes */); CollectStyle(style, paraStyle, clashingAttr, absentAttrPara); } @@ -2656,7 +3301,7 @@ bool wxRichTextParagraphLayoutBox::GetStyleForRange(const wxRichTextRange& range wxRichTextObject* child = childNode->GetData(); if (!(child->GetRange().GetStart() > range.GetEnd() || child->GetRange().GetEnd() < range.GetStart())) { - wxRichTextAttr childStyle = para->GetCombinedAttributes(child->GetAttributes()); + wxRichTextAttr childStyle = para->GetCombinedAttributes(child->GetAttributes(), true /* include box attributes */); // Now collect character attributes only childStyle.SetFlags(childStyle.GetFlags() & wxTEXT_ATTR_CHARACTER); @@ -2693,7 +3338,7 @@ bool wxRichTextParagraphLayoutBox::HasCharacterAttributes(const wxRichTextRange& while (node) { wxRichTextParagraph* para = wxDynamicCast(node->GetData(), wxRichTextParagraph); - wxASSERT (para != NULL); + // wxASSERT (para != NULL); if (para) { @@ -2746,7 +3391,7 @@ bool wxRichTextParagraphLayoutBox::HasParagraphAttributes(const wxRichTextRange& while (node) { wxRichTextParagraph* para = wxDynamicCast(node->GetData(), wxRichTextParagraph); - wxASSERT (para != NULL); + // wxASSERT (para != NULL); if (para) { @@ -2775,39 +3420,69 @@ void wxRichTextParagraphLayoutBox::Reset() { Clear(); - wxRichTextBuffer* buffer = wxDynamicCast(this, wxRichTextBuffer); - if (buffer && GetRichTextCtrl()) + wxRichTextBuffer* buffer = GetBuffer(); + if (buffer && buffer->GetRichTextCtrl()) { - wxRichTextEvent event(wxEVT_COMMAND_RICHTEXT_BUFFER_RESET, GetRichTextCtrl()->GetId()); - event.SetEventObject(GetRichTextCtrl()); + wxRichTextEvent event(wxEVT_COMMAND_RICHTEXT_BUFFER_RESET, buffer->GetRichTextCtrl()->GetId()); + event.SetEventObject(buffer->GetRichTextCtrl()); + event.SetContainer(this); buffer->SendEvent(event, true); } AddParagraph(wxEmptyString); - Invalidate(wxRICHTEXT_ALL); + InvalidateHierarchy(wxRICHTEXT_ALL); } /// Invalidate the buffer. With no argument, invalidates whole buffer. void wxRichTextParagraphLayoutBox::Invalidate(const wxRichTextRange& invalidRange) { - SetDirty(true); + wxRichTextCompositeObject::Invalidate(invalidRange); + DoInvalidate(invalidRange); +} + +// Do the (in)validation for this object only +void wxRichTextParagraphLayoutBox::DoInvalidate(const wxRichTextRange& invalidRange) +{ if (invalidRange == wxRICHTEXT_ALL) { m_invalidRange = wxRICHTEXT_ALL; - return; } - // Already invalidating everything - if (m_invalidRange == wxRICHTEXT_ALL) - return; + else if (m_invalidRange == wxRICHTEXT_ALL) + { + } + else + { + if ((invalidRange.GetStart() < m_invalidRange.GetStart()) || m_invalidRange.GetStart() == -1) + m_invalidRange.SetStart(invalidRange.GetStart()); + if (invalidRange.GetEnd() > m_invalidRange.GetEnd()) + m_invalidRange.SetEnd(invalidRange.GetEnd()); + } +} - if ((invalidRange.GetStart() < m_invalidRange.GetStart()) || m_invalidRange.GetStart() == -1) - m_invalidRange.SetStart(invalidRange.GetStart()); - if (invalidRange.GetEnd() > m_invalidRange.GetEnd()) - m_invalidRange.SetEnd(invalidRange.GetEnd()); +// Do the (in)validation both up and down the hierarchy +void wxRichTextParagraphLayoutBox::InvalidateHierarchy(const wxRichTextRange& invalidRange) +{ + Invalidate(invalidRange); + + if (invalidRange != wxRICHTEXT_NONE) + { + // Now go up the hierarchy + wxRichTextObject* thisObj = this; + wxRichTextObject* p = GetParent(); + while (p) + { + wxRichTextParagraphLayoutBox* l = wxDynamicCast(p, wxRichTextParagraphLayoutBox); + if (l) + l->DoInvalidate(thisObj->GetRange()); + + thisObj = p; + p = p->GetParent(); + } + } } /// Get invalid range, rounding to entire paragraphs if argument is true. @@ -2824,7 +3499,7 @@ wxRichTextRange wxRichTextParagraphLayoutBox::GetInvalidRange(bool wholeParagrap if (para1) range.SetStart(para1->GetRange().GetStart()); // floating layout make all child should be relayout - range.SetEnd(GetRange().GetEnd()); + range.SetEnd(GetOwnRange().GetEnd()); } return range; } @@ -2865,7 +3540,7 @@ bool wxRichTextParagraphLayoutBox::ApplyStyleSheet(wxRichTextStyleSheet* styleSh while (node) { wxRichTextParagraph* para = wxDynamicCast(node->GetData(), wxRichTextParagraph); - wxASSERT (para != NULL); + // wxASSERT (para != NULL); if (para) { @@ -2950,7 +3625,8 @@ bool wxRichTextParagraphLayoutBox::ApplyStyleSheet(wxRichTextStyleSheet* styleSh /// Set list style bool wxRichTextParagraphLayoutBox::SetListStyle(const wxRichTextRange& range, wxRichTextListStyleDefinition* def, int flags, int startFrom, int specifiedLevel) { - wxRichTextStyleSheet* styleSheet = GetStyleSheet(); + wxRichTextBuffer* buffer = GetBuffer(); + wxRichTextStyleSheet* styleSheet = buffer->GetStyleSheet(); bool withUndo = ((flags & wxRICHTEXT_SETSTYLE_WITH_UNDO) != 0); // bool applyMinimal = ((flags & wxRICHTEXT_SETSTYLE_OPTIMIZE) != 0); @@ -2965,22 +3641,22 @@ bool wxRichTextParagraphLayoutBox::SetListStyle(const wxRichTextRange& range, wx // If we are associated with a control, make undoable; otherwise, apply immediately // to the data. - bool haveControl = (GetRichTextCtrl() != NULL); + bool haveControl = (buffer->GetRichTextCtrl() != NULL); wxRichTextAction* action = NULL; if (haveControl && withUndo) { - action = new wxRichTextAction(NULL, _("Change List Style"), wxRICHTEXT_CHANGE_STYLE, & GetRichTextCtrl()->GetBuffer(), GetRichTextCtrl()); + action = new wxRichTextAction(NULL, _("Change List Style"), wxRICHTEXT_CHANGE_STYLE, buffer, this, buffer->GetRichTextCtrl()); action->SetRange(range); - action->SetPosition(GetRichTextCtrl()->GetCaretPosition()); + action->SetPosition(buffer->GetRichTextCtrl()->GetCaretPosition()); } wxRichTextObjectList::compatibility_iterator node = m_children.GetFirst(); while (node) { wxRichTextParagraph* para = wxDynamicCast(node->GetData(), wxRichTextParagraph); - wxASSERT (para != NULL); + // wxASSERT (para != NULL); if (para && para->GetChildCount() > 0) { @@ -3059,16 +3735,17 @@ bool wxRichTextParagraphLayoutBox::SetListStyle(const wxRichTextRange& range, wx // Do action, or delay it until end of batch. if (haveControl && withUndo) - GetRichTextCtrl()->GetBuffer().SubmitAction(action); + buffer->SubmitAction(action); return true; } bool wxRichTextParagraphLayoutBox::SetListStyle(const wxRichTextRange& range, const wxString& defName, int flags, int startFrom, int specifiedLevel) { - if (GetStyleSheet()) + wxRichTextBuffer* buffer = GetBuffer(); + if (buffer && buffer->GetStyleSheet()) { - wxRichTextListStyleDefinition* def = GetStyleSheet()->FindListStyle(defName); + wxRichTextListStyleDefinition* def = buffer->GetStyleSheet()->FindListStyle(defName); if (def) return SetListStyle(range, def, flags, startFrom, specifiedLevel); } @@ -3091,7 +3768,8 @@ bool wxRichTextParagraphLayoutBox::NumberList(const wxRichTextRange& range, wxRi bool wxRichTextParagraphLayoutBox::DoNumberList(const wxRichTextRange& range, const wxRichTextRange& promotionRange, int promoteBy, wxRichTextListStyleDefinition* def, int flags, int startFrom, int specifiedLevel) { - wxRichTextStyleSheet* styleSheet = GetStyleSheet(); + wxRichTextBuffer* buffer = GetBuffer(); + wxRichTextStyleSheet* styleSheet = buffer->GetStyleSheet(); bool withUndo = ((flags & wxRICHTEXT_SETSTYLE_WITH_UNDO) != 0); // bool applyMinimal = ((flags & wxRICHTEXT_SETSTYLE_OPTIMIZE) != 0); @@ -3127,22 +3805,22 @@ bool wxRichTextParagraphLayoutBox::DoNumberList(const wxRichTextRange& range, co // If we are associated with a control, make undoable; otherwise, apply immediately // to the data. - bool haveControl = (GetRichTextCtrl() != NULL); + bool haveControl = (buffer->GetRichTextCtrl() != NULL); wxRichTextAction* action = NULL; if (haveControl && withUndo) { - action = new wxRichTextAction(NULL, _("Renumber List"), wxRICHTEXT_CHANGE_STYLE, & GetRichTextCtrl()->GetBuffer(), GetRichTextCtrl()); + action = new wxRichTextAction(NULL, _("Renumber List"), wxRICHTEXT_CHANGE_STYLE, buffer, this, buffer->GetRichTextCtrl()); action->SetRange(range); - action->SetPosition(GetRichTextCtrl()->GetCaretPosition()); + action->SetPosition(buffer->GetRichTextCtrl()->GetCaretPosition()); } wxRichTextObjectList::compatibility_iterator node = m_children.GetFirst(); while (node) { wxRichTextParagraph* para = wxDynamicCast(node->GetData(), wxRichTextParagraph); - wxASSERT (para != NULL); + // wxASSERT (para != NULL); if (para && para->GetChildCount() > 0) { @@ -3256,18 +3934,19 @@ bool wxRichTextParagraphLayoutBox::DoNumberList(const wxRichTextRange& range, co // Do action, or delay it until end of batch. if (haveControl && withUndo) - GetRichTextCtrl()->GetBuffer().SubmitAction(action); + buffer->SubmitAction(action); return true; } bool wxRichTextParagraphLayoutBox::NumberList(const wxRichTextRange& range, const wxString& defName, int flags, int startFrom, int specifiedLevel) { - if (GetStyleSheet()) + wxRichTextBuffer* buffer = GetBuffer(); + if (buffer->GetStyleSheet()) { wxRichTextListStyleDefinition* def = NULL; if (!defName.IsEmpty()) - def = GetStyleSheet()->FindListStyle(defName); + def = buffer->GetStyleSheet()->FindListStyle(defName); return NumberList(range, def, flags, startFrom, specifiedLevel); } return false; @@ -3293,11 +3972,12 @@ bool wxRichTextParagraphLayoutBox::PromoteList(int promoteBy, const wxRichTextRa bool wxRichTextParagraphLayoutBox::PromoteList(int promoteBy, const wxRichTextRange& range, const wxString& defName, int flags, int specifiedLevel) { - if (GetStyleSheet()) + wxRichTextBuffer* buffer = GetBuffer(); + if (buffer->GetStyleSheet()) { wxRichTextListStyleDefinition* def = NULL; if (!defName.IsEmpty()) - def = GetStyleSheet()->FindListStyle(defName); + def = buffer->GetStyleSheet()->FindListStyle(defName); return PromoteList(promoteBy, range, def, flags, specifiedLevel); } return false; @@ -3310,7 +3990,8 @@ bool wxRichTextParagraphLayoutBox::FindNextParagraphNumber(wxRichTextParagraph* if (!previousParagraph->GetAttributes().HasFlag(wxTEXT_ATTR_BULLET_STYLE) || previousParagraph->GetAttributes().GetBulletStyle() == wxTEXT_ATTR_BULLET_STYLE_NONE) return false; - wxRichTextStyleSheet* styleSheet = GetStyleSheet(); + wxRichTextBuffer* buffer = GetBuffer(); + wxRichTextStyleSheet* styleSheet = buffer->GetStyleSheet(); if (styleSheet && !previousParagraph->GetAttributes().GetListStyleName().IsEmpty()) { wxRichTextListStyleDefinition* def = styleSheet->FindListStyle(previousParagraph->GetAttributes().GetListStyleName()); @@ -3363,19 +4044,19 @@ bool wxRichTextParagraphLayoutBox::FindNextParagraphNumber(wxRichTextParagraph* * This object represents a single paragraph (or in a straight text editor, a line). */ -IMPLEMENT_DYNAMIC_CLASS(wxRichTextParagraph, wxRichTextBox) +IMPLEMENT_DYNAMIC_CLASS(wxRichTextParagraph, wxRichTextCompositeObject) wxArrayInt wxRichTextParagraph::sm_defaultTabs; wxRichTextParagraph::wxRichTextParagraph(wxRichTextObject* parent, wxRichTextAttr* style): - wxRichTextBox(parent) + wxRichTextCompositeObject(parent) { if (style) SetAttributes(*style); } wxRichTextParagraph::wxRichTextParagraph(const wxString& text, wxRichTextObject* parent, wxRichTextAttr* paraStyle, wxRichTextAttr* charStyle): - wxRichTextBox(parent) + wxRichTextCompositeObject(parent) { if (paraStyle) SetAttributes(*paraStyle); @@ -3389,8 +4070,18 @@ wxRichTextParagraph::~wxRichTextParagraph() } /// Draw the item -bool wxRichTextParagraph::Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextRange& selectionRange, const wxRect& rect, int WXUNUSED(descent), int style) +bool wxRichTextParagraph::Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int WXUNUSED(descent), int style) { + if (!IsShown()) + return true; + + // Currently we don't merge these attributes with the parent, but we + // should consider whether we should (e.g. if we set a border colour + // for all paragraphs). But generally box attributes are likely to be + // different for different objects. + wxRect paraRect = GetRect(); + DrawBoxAttributes(dc, GetBuffer(), GetAttributes(), paraRect); + wxRichTextAttr attr = GetCombinedAttributes(); // Draw the bullet, if any @@ -3493,21 +4184,29 @@ bool wxRichTextParagraph::Draw(wxDC& dc, const wxRichTextRange& range, const wxR objectRange.LimitTo(lineRange); wxSize objectSize; -#if wxRICHTEXT_USE_OPTIMIZED_LINE_DRAWING && wxRICHTEXT_USE_PARTIAL_TEXT_EXTENTS - if (i < (int) line->GetObjectSizes().GetCount()) + if (child->IsTopLevel()) { - objectSize.x = line->GetObjectSizes()[(size_t) i]; + objectSize = child->GetCachedSize(); + objectRange = child->GetOwnRange(); } else -#endif { - int descent = 0; - child->GetRangeSize(objectRange, objectSize, descent, dc, wxRICHTEXT_UNFORMATTED, objectPosition); +#if wxRICHTEXT_USE_OPTIMIZED_LINE_DRAWING && wxRICHTEXT_USE_PARTIAL_TEXT_EXTENTS + if (i < (int) line->GetObjectSizes().GetCount()) + { + objectSize.x = line->GetObjectSizes()[(size_t) i]; + } + else +#endif + { + int descent = 0; + child->GetRangeSize(objectRange, objectSize, descent, dc, wxRICHTEXT_UNFORMATTED, objectPosition); + } } // Use the child object's width, but the whole line's height wxRect childRect(objectPosition, wxSize(objectSize.x, line->GetSize().y)); - child->Draw(dc, objectRange, selectionRange, childRect, maxDescent, style); + child->Draw(dc, objectRange, selection, childRect, maxDescent, style); objectPosition.x += objectSize.x; i ++; @@ -3578,7 +4277,6 @@ bool wxRichTextParagraph::Layout(wxDC& dc, const wxRect& rect, int style) // Start position for each line relative to the paragraph int startPositionFirstLine = leftIndent; int startPositionSubsequentLines = leftIndent + leftSubIndent; - wxRect availableRect; // If we have a bullet in this paragraph, the start position for the first line's text // is actually leftIndent + leftSubIndent. @@ -3594,6 +4292,7 @@ bool wxRichTextParagraph::Layout(wxDC& dc, const wxRect& rect, int style) wxPoint currentPosition(0, spaceBeforePara); // We will calculate lines relative to paragraph int lineHeight = 0; int maxWidth = 0; + int maxHeight = currentPosition.y; int maxAscent = 0; int maxDescent = 0; int lineCount = 0; @@ -3603,6 +4302,25 @@ bool wxRichTextParagraph::Layout(wxDC& dc, const wxRect& rect, int style) wxRichTextObjectList::compatibility_iterator node; #if wxRICHTEXT_USE_PARTIAL_TEXT_EXTENTS +#if 0 + node = m_children.GetFirst(); + while (node) + { + wxRichTextObject* child = node->GetData(); + if (child->IsTopLevel()) + { + //child->SetCachedSize(wxDefaultSize); + wxRect availableChildRect = AdjustAvailableSpace(dc, GetBuffer(), GetAttributes(), child->GetAttributes(), rect); + + // Hm, can't do this here, we surely need to take into account indents, margins, floating images etc. + // So need to call layout lower down. + child->Layout(dc, availableChildRect, style); + } + + node = node->GetNext(); + } +#endif + wxUnusedVar(style); wxArrayInt partialExtents; @@ -3617,7 +4335,7 @@ bool wxRichTextParagraph::Layout(wxDC& dc, const wxRect& rect, int style) { wxRichTextObject* child = node->GetData(); - child->SetCachedSize(wxDefaultSize); + //child->SetCachedSize(wxDefaultSize); child->Layout(dc, rect, style); node = node->GetNext(); @@ -3631,13 +4349,19 @@ bool wxRichTextParagraph::Layout(wxDC& dc, const wxRect& rect, int style) // find the child corresponding to the start position of the string, and // continue. + wxRect availableRect; + node = m_children.GetFirst(); while (node) { wxRichTextObject* child = node->GetData(); // If floating, ignore. We already laid out floats. - if (child->IsFloating() || child->GetRange().GetLength() == 0) + // Also ignore if empty object, except if we haven't got any + // size yet. + if (child->IsFloating() || !child->IsShown() || + (child->GetRange().GetLength() == 0 && maxHeight > spaceBeforePara) + ) { node = node->GetNext(); continue; @@ -3664,6 +4388,37 @@ bool wxRichTextParagraph::Layout(wxDC& dc, const wxRect& rect, int style) wxSize childSize; int childDescent = 0; + int startOffset = (lineCount == 0 ? startPositionFirstLine : startPositionSubsequentLines); + availableRect = wxRect(rect.x + startOffset, rect.y + currentPosition.y, + rect.width - startOffset - rightIndent, rect.height); + + if (child->IsTopLevel()) + { + wxSize oldSize = child->GetCachedSize(); + + child->Invalidate(wxRICHTEXT_ALL); + child->SetPosition(wxPoint(0, 0)); + + // 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 + // The position will be determined by its location in its line, + // and not by the child's actual position. + child->LayoutToBestSize(dc, GetBuffer(), + GetAttributes(), child->GetAttributes(), availableRect, style); + + if (oldSize != child->GetCachedSize()) + { + partialExtents.Clear(); + + // Recalculate the partial text extents since the child object changed size + GetRangeSize(GetRange(), paraSize, paraDescent, dc, wxRICHTEXT_UNFORMATTED|wxRICHTEXT_CACHE_SIZE, wxPoint(0,0), & partialExtents); + } + } + + // Problem: we need to layout composites here for which we need the available width, + // but we can't get the available width without using the float collector which + // needs to know the object height. + if ((nextBreakPos == -1) && (lastEndPos == child->GetRange().GetStart() - 1)) // i.e. we want to get the whole thing { childSize = child->GetCachedSize(); @@ -3680,36 +4435,113 @@ bool wxRichTextParagraph::Layout(wxDC& dc, const wxRect& rect, int style) #endif } - // Available width depends on the floating objects and the line height - // Note: the floating objects may be placed vertically along the two side of - // buffer, so we may have different available line width with different - // [startY, endY]. So, we should can't determine how wide the available - // space is until we know the exact line height. - lineDescent = wxMax(childDescent, maxDescent); - lineAscent = wxMax(childSize.y-childDescent, maxAscent); - lineHeight = lineDescent + lineAscent; - availableRect = collector->GetAvailableRect(rect.y + currentPosition.y, rect.y + currentPosition.y + lineHeight); + bool doLoop = true; + int loopIterations = 0; - currentPosition.x = (lineCount == 0 ? availableRect.x + startPositionFirstLine : availableRect.x + startPositionSubsequentLines); + // If there are nested objects that need to lay themselves out, we have to do this in a + // loop because the height of the object may well depend on the available width. + // And because of floating object positioning, the available width depends on the + // height of the object and whether it will clash with the floating objects. + // So, we see whether the available width changes due to the presence of floating images. + // If it does, then we'll use the new restricted width to find the object height again. + // If this causes another restriction in the available width, we'll try again, until + // either we lose patience or the available width settles down. + do + { + loopIterations ++; + + 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 + // 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. + lineDescent = wxMax(childDescent, maxDescent); + lineAscent = wxMax(childSize.y-childDescent, maxAscent); + 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. + + if (floatAvailableRect.x + startOffset > availableRect.x) + { + int newX = floatAvailableRect.x + startOffset; + int newW = availableRect.width - (newX - availableRect.x); + availableRect.x = newX; + availableRect.width = newW; + } + + if (floatAvailableRect.width < availableRect.width) + availableRect.width = floatAvailableRect.width; + + currentPosition.x = availableRect.x - rect.x; + + if (child->IsTopLevel() && loopIterations <= 20) + { + if (availableRect != oldAvailableRect) + { + 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); + child->LayoutToBestSize(dc, GetBuffer(), + GetAttributes(), child->GetAttributes(), availableRect, style); + childSize = child->GetCachedSize(); + childDescent = child->GetDescent(); + //child->SetPosition(availableRect.GetPosition()); + + if (oldSize != child->GetCachedSize()) + { + partialExtents.Clear(); + + // Recalculate the partial text extents since the child object changed size + GetRangeSize(GetRange(), paraSize, paraDescent, dc, wxRICHTEXT_UNFORMATTED|wxRICHTEXT_CACHE_SIZE, wxPoint(0,0), & partialExtents); + } + + // Go around the loop finding the available rect for the given floating objects + } + else + doLoop = false; + } + else + doLoop = false; + } + while (doLoop); // Cases: // 1) There was a line break BEFORE the natural break // 2) There was a line break AFTER the natural break - // 3) The child still fits (carry on) + // 3) It's the last line + // 4) The child still fits (carry on) - 'else' clause - if ((lineBreakInThisObject && (childSize.x + currentWidth <= availableRect.width)) || - (childSize.x + currentWidth > availableRect.width)) + if ((lineBreakInThisObject && (childSize.x + currentWidth <= availableRect.width)) + || + (childSize.x + currentWidth > availableRect.width) + || + ((childSize.x + currentWidth <= availableRect.width) && !node->GetNext()) + + ) { - long wrapPosition = 0; + if (child->IsTopLevel()) + { + // We can move it to the correct position at this point + child->Move(GetPosition() + wxPoint(currentWidth, currentPosition.y)); + } + + long wrapPosition = 0; + if ((childSize.x + currentWidth <= availableRect.width) && !node->GetNext() && !lineBreakInThisObject) + wrapPosition = child->GetRange().GetEnd(); + else - int indent = lineCount == 0 ? startPositionFirstLine : startPositionSubsequentLines; - indent += rightIndent; // Find a place to wrap. This may walk back to previous children, // for example if a word spans several objects. // Note: one object must contains only one wxTextAtrr, so the line height will not // change inside one object. Thus, we can pass the remain line width to the // FindWrapPosition function. - if (!FindWrapPosition(wxRichTextRange(lastCompletedEndPos+1, child->GetRange().GetEnd()), dc, availableRect.width - indent, wrapPosition, & partialExtents)) + if (!FindWrapPosition(wxRichTextRange(lastCompletedEndPos+1, child->GetRange().GetEnd()), dc, availableRect.width, wrapPosition, & partialExtents)) { // If the function failed, just cut it off at the end of this child. wrapPosition = child->GetRange().GetEnd(); @@ -3719,6 +4551,10 @@ bool wxRichTextParagraph::Layout(wxDC& dc, const wxRect& rect, int style) if (wrapPosition <= lastCompletedEndPos) wrapPosition = wxMax(lastCompletedEndPos+1,child->GetRange().GetEnd()); + // Line end position shouldn't be the same as the end, or greater. + if (wrapPosition >= GetRange().GetEnd()) + wrapPosition = GetRange().GetEnd()-1; + // wxLogDebug(wxT("Split at %ld"), wrapPosition); // Let's find the actual size of the current line now @@ -3730,18 +4566,34 @@ bool wxRichTextParagraph::Layout(wxDC& dc, const wxRect& rect, int style) childDescent = maxDescent; #if wxRICHTEXT_USE_PARTIAL_TEXT_EXTENTS - // Get height only, then the width using the partial extents - GetRangeSize(actualRange, actualSize, childDescent, dc, wxRICHTEXT_UNFORMATTED|wxRICHTEXT_HEIGHT_ONLY); - actualSize.x = wxRichTextGetRangeWidth(*this, actualRange, partialExtents); -#else - GetRangeSize(actualRange, actualSize, childDescent, dc, wxRICHTEXT_UNFORMATTED); + if (!child->IsEmpty()) + { + // Get height only, then the width using the partial extents + GetRangeSize(actualRange, actualSize, childDescent, dc, wxRICHTEXT_UNFORMATTED|wxRICHTEXT_HEIGHT_ONLY); + actualSize.x = wxRichTextGetRangeWidth(*this, actualRange, partialExtents); + } + else #endif + GetRangeSize(actualRange, actualSize, childDescent, dc, wxRICHTEXT_UNFORMATTED); currentWidth = actualSize.x; maxDescent = wxMax(childDescent, maxDescent); maxAscent = wxMax(actualSize.y-childDescent, maxAscent); lineHeight = maxDescent + maxAscent; + if (lineHeight == 0 && GetBuffer()) + { + wxFont font(GetBuffer()->GetFontTable().FindFont(attr)); + wxCheckSetFont(dc, font); + lineHeight = dc.GetCharHeight(); + } + + if (maxDescent == 0) + { + int w, h; + dc.GetTextExtent(wxT("X"), & w, &h, & maxDescent); + } + // Add a new line wxRichTextLine* line = AllocateLine(lineCount); @@ -3751,30 +4603,40 @@ bool wxRichTextParagraph::Layout(wxDC& dc, const wxRect& rect, int style) line->SetSize(wxSize(currentWidth, lineHeight)); line->SetDescent(maxDescent); + maxHeight = currentPosition.y + lineHeight; + // Now move down a line. TODO: add margins, spacing currentPosition.y += lineHeight; currentPosition.y += lineSpacing; - currentWidth = 0; maxDescent = 0; maxAscent = 0; - maxWidth = wxMax(maxWidth, currentWidth); + maxWidth = wxMax(maxWidth, currentWidth+startOffset); + currentWidth = 0; lineCount ++; // TODO: account for zero-length objects, such as fields - wxASSERT(wrapPosition > lastCompletedEndPos); + // wxASSERT(wrapPosition > lastCompletedEndPos); lastEndPos = wrapPosition; lastCompletedEndPos = lastEndPos; lineHeight = 0; - // May need to set the node back to a previous one, due to searching back in wrapping - wxRichTextObject* childAfterWrapPosition = FindObjectAtPosition(wrapPosition+1); - if (childAfterWrapPosition) - node = m_children.Find(childAfterWrapPosition); + if (wrapPosition < GetRange().GetEnd()-1) + { + // May need to set the node back to a previous one, due to searching back in wrapping + wxRichTextObject* childAfterWrapPosition = FindObjectAtPosition(wrapPosition+1); + if (childAfterWrapPosition) + node = m_children.Find(childAfterWrapPosition); + else + node = node->GetNext(); + } else node = node->GetNext(); + + // Apply paragraph styles such as alignment to the wrapped line + ApplyParagraphStyle(line, attr, availableRect, dc); } else { @@ -3784,18 +4646,21 @@ bool wxRichTextParagraph::Layout(wxDC& dc, const wxRect& rect, int style) maxAscent = wxMax(childSize.y-childDescent, maxAscent); lineHeight = maxDescent + maxAscent; - maxWidth = wxMax(maxWidth, currentWidth); + maxWidth = wxMax(maxWidth, currentWidth+startOffset); lastEndPos = child->GetRange().GetEnd(); node = node->GetNext(); } } + wxASSERT(!(lastCompletedEndPos != -1 && lastCompletedEndPos < GetRange().GetEnd()-1)); + +#if 0 // Add the last line - it's the current pos -> last para pos // Substract -1 because the last position is always the end-paragraph position. if (lastCompletedEndPos <= GetRange().GetEnd()-1) { - currentPosition.x = (lineCount == 0 ? availableRect.x + startPositionFirstLine : availableRect.x + startPositionSubsequentLines); + currentPosition.x = availableRect.x - rect.x; wxRichTextLine* line = AllocateLine(lineCount); @@ -3820,20 +4685,61 @@ bool wxRichTextParagraph::Layout(wxDC& dc, const wxRect& rect, int style) line->SetSize(wxSize(currentWidth, lineHeight)); line->SetDescent(maxDescent); + maxWidth = wxMax(maxWidth, currentWidth+startOffset); currentPosition.y += lineHeight; currentPosition.y += lineSpacing; lineCount ++; } +#endif // Remove remaining unused line objects, if any ClearUnusedLines(lineCount); - // Apply styles to wrapped lines - ApplyParagraphStyle(attr, rect, dc); + // We need to add back the margins etc. + { + wxRect marginRect, borderRect, contentRect, paddingRect, outlineRect; + contentRect = wxRect(wxPoint(0, 0), wxSize(maxWidth, currentPosition.y + spaceAfterPara)); + GetBoxRects(dc, GetBuffer(), GetAttributes(), marginRect, borderRect, contentRect, paddingRect, outlineRect); + SetCachedSize(marginRect.GetSize()); + } - SetCachedSize(wxSize(maxWidth, currentPosition.y + spaceAfterPara)); + // The maximum size is the length of the paragraph stretched out into a line. + // So if there were a single word, or an image, or a fixed-size text box, the object could be shrunk around + // this size. TODO: take into account line breaks. + { + wxRect marginRect, borderRect, contentRect, paddingRect, outlineRect; + contentRect = wxRect(wxPoint(0, 0), wxSize(paraSize.x, currentPosition.y + spaceAfterPara)); + GetBoxRects(dc, GetBuffer(), GetAttributes(), marginRect, borderRect, contentRect, paddingRect, outlineRect); + SetMaxSize(marginRect.GetSize()); + } + + // Find the greatest minimum size. Currently we only look at non-text objects, + // which isn't ideal but it would be slow to find the maximum word width to + // use as the minimum. + { + int minWidth = 0; + node = m_children.GetFirst(); + while (node) + { + wxRichTextObject* child = node->GetData(); + + // If floating, ignore. We already laid out floats. + // Also ignore if empty object, except if we haven't got any + // size yet. + if (!child->IsFloating() && child->GetRange().GetLength() != 0 && !child->IsKindOf(CLASSINFO(wxRichTextPlainText))) + { + if (child->GetCachedSize().x > minWidth) + minWidth = child->GetMinSize().x; + } + node = node->GetNext(); + } + + wxRect marginRect, borderRect, contentRect, paddingRect, outlineRect; + contentRect = wxRect(wxPoint(0, 0), wxSize(minWidth, currentPosition.y + spaceAfterPara)); + GetBoxRects(dc, GetBuffer(), GetAttributes(), marginRect, borderRect, contentRect, paddingRect, outlineRect); + SetMinSize(marginRect.GetSize()); + } - m_dirty = false; #if wxRICHTEXT_USE_PARTIAL_TEXT_EXTENTS #if wxRICHTEXT_USE_OPTIMIZED_LINE_DRAWING @@ -3880,7 +4786,9 @@ bool wxRichTextParagraph::Layout(wxDC& dc, const wxRect& rect, int style) return true; } +#if 0 /// Apply paragraph styles, such as centering, to wrapped lines +/// TODO: take into account box attributes void wxRichTextParagraph::ApplyParagraphStyle(const wxRichTextAttr& attr, const wxRect& rect, wxDC& dc) { if (!attr.HasAlignment()) @@ -3898,19 +4806,49 @@ void wxRichTextParagraph::ApplyParagraphStyle(const wxRichTextAttr& attr, const if (attr.HasAlignment() && GetAttributes().GetAlignment() == wxTEXT_ALIGNMENT_CENTRE) { int rightIndent = ConvertTenthsMMToPixels(dc, attr.GetRightIndent()); - pos.x = (rect.GetWidth() - pos.x - rightIndent - size.x)/2 + pos.x; + // Subtract paragraph position because lines are relative to + // the paragraph. + pos.x = rect.x - GetPosition().x + (rect.GetWidth() - rightIndent - size.x)/2; line->SetPosition(pos); } else if (attr.HasAlignment() && GetAttributes().GetAlignment() == wxTEXT_ALIGNMENT_RIGHT) { int rightIndent = ConvertTenthsMMToPixels(dc, attr.GetRightIndent()); - pos.x = rect.GetWidth() - size.x - rightIndent; + // Subtract paragraph position because lines are relative to + // the paragraph. + pos.x = (rect.x - GetPosition().x) + rect.GetWidth() - size.x - rightIndent; line->SetPosition(pos); } node = node->GetNext(); } } +#endif + +/// Apply paragraph styles, such as centering, to wrapped lines +/// TODO: take into account box attributes, possibly +void wxRichTextParagraph::ApplyParagraphStyle(wxRichTextLine* line, const wxRichTextAttr& attr, const wxRect& rect, wxDC& dc) +{ + if (!attr.HasAlignment()) + return; + + wxPoint pos = line->GetPosition(); + wxSize size = line->GetSize(); + + // centering, right-justification + if (attr.HasAlignment() && GetAttributes().GetAlignment() == wxTEXT_ALIGNMENT_CENTRE) + { + int rightIndent = ConvertTenthsMMToPixels(dc, attr.GetRightIndent()); + pos.x = (rect.GetWidth() - rightIndent - size.x)/2 + pos.x; + line->SetPosition(pos); + } + else if (attr.HasAlignment() && GetAttributes().GetAlignment() == wxTEXT_ALIGNMENT_RIGHT) + { + int rightIndent = ConvertTenthsMMToPixels(dc, attr.GetRightIndent()); + pos.x = pos.x + rect.GetWidth() - size.x - rightIndent; + line->SetPosition(pos); + } +} /// Insert text at the given position bool wxRichTextParagraph::InsertText(long pos, const wxString& text) @@ -4037,50 +4975,79 @@ bool wxRichTextParagraph::GetRangeSize(const wxRichTextRange& range, wxSize& siz } else { - wxSize childSize; + wxSize childSize; - wxRichTextRange rangeToUse = range; - rangeToUse.LimitTo(child->GetRange()); - int childDescent = 0; + wxRichTextRange rangeToUse = range; + rangeToUse.LimitTo(child->GetRange()); +#if 0 + if (child->IsTopLevel()) + rangeToUse = child->GetOwnRange(); +#endif + int childDescent = 0; - // At present wxRICHTEXT_HEIGHT_ONLY is only fast if we're 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) - { - childDescent = child->GetDescent(); - childSize = child->GetCachedSize(); - - sz.y = wxMax(sz.y, childSize.y); - sz.x += childSize.x; - descent = wxMax(descent, childDescent); - } - else if (child->GetRangeSize(rangeToUse, childSize, childDescent, dc, flags, wxPoint(position.x + sz.x, position.y), p)) - { - sz.y = wxMax(sz.y, childSize.y); - sz.x += childSize.x; - descent = wxMax(descent, childDescent); - - if ((flags & wxRICHTEXT_CACHE_SIZE) && (rangeToUse == child->GetRange())) + // At present wxRICHTEXT_HEIGHT_ONLY is only fast if we're 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) { - child->SetCachedSize(childSize); - child->SetDescent(childDescent); + childDescent = child->GetDescent(); + childSize = child->GetCachedSize(); + + sz.y = wxMax(sz.y, childSize.y); + sz.x += childSize.x; + descent = wxMax(descent, childDescent); } - - if (partialExtents) + else if (child->IsTopLevel()) { - int lastSize; - if (partialExtents->GetCount() > 0) - lastSize = (*partialExtents)[partialExtents->GetCount()-1]; - else - lastSize = 0; + childDescent = child->GetDescent(); + childSize = child->GetCachedSize(); - size_t i; - for (i = 0; i < childExtents.GetCount(); i++) + sz.y = wxMax(sz.y, childSize.y); + sz.x += childSize.x; + descent = wxMax(descent, childDescent); + if ((flags & wxRICHTEXT_CACHE_SIZE) && (rangeToUse == child->GetRange())) { - partialExtents->Add(childExtents[i] + lastSize); + child->SetCachedSize(childSize); + child->SetDescent(childDescent); + } + + if (partialExtents) + { + int lastSize; + if (partialExtents->GetCount() > 0) + lastSize = (*partialExtents)[partialExtents->GetCount()-1]; + else + lastSize = 0; + + partialExtents->Add(childSize.x + lastSize); + } + } + else if (child->GetRangeSize(rangeToUse, childSize, childDescent, dc, flags, wxPoint(position.x + sz.x, position.y), p)) + { + sz.y = wxMax(sz.y, childSize.y); + sz.x += childSize.x; + descent = wxMax(descent, childDescent); + + if ((flags & wxRICHTEXT_CACHE_SIZE) && (rangeToUse == child->GetRange())) + { + child->SetCachedSize(childSize); + child->SetDescent(childDescent); + } + + if (partialExtents) + { + int lastSize; + if (partialExtents->GetCount() > 0) + lastSize = (*partialExtents)[partialExtents->GetCount()-1]; + else + lastSize = 0; + + size_t i; + for (i = 0; i < childExtents.GetCount(); i++) + { + partialExtents->Add(childExtents[i] + lastSize); + } } } - } } if (p) @@ -4121,6 +5088,8 @@ bool wxRichTextParagraph::GetRangeSize(const wxRichTextRange& range, wxSize& siz { wxRichTextRange rangeToUse = lineRange; rangeToUse.LimitTo(child->GetRange()); + if (child->IsTopLevel()) + rangeToUse = child->GetOwnRange(); wxSize childSize; int childDescent = 0; @@ -4241,8 +5210,43 @@ bool wxRichTextParagraph::FindPosition(wxDC& dc, long index, wxPoint& pt, int* h /// Hit-testing: returns a flag indicating hit test details, plus /// information about position -int wxRichTextParagraph::HitTest(wxDC& dc, const wxPoint& pt, long& textPosition) +int wxRichTextParagraph::HitTest(wxDC& dc, const wxPoint& pt, long& textPosition, wxRichTextObject** obj, wxRichTextObject** contextObj, int flags) { + if (!IsShown()) + return wxRICHTEXT_HITTEST_NONE; + + // If we're in the top-level container, then we can return + // a suitable hit test code even if the point is outside the container area, + // so that we can position the caret sensibly even if we don't + // click on valid content. If we're not at the top-level, and the point + // is not within this paragraph object, then we don't want to stop more + // precise hit-testing from working prematurely, so return immediately. + // NEW STRATEGY: use the parent boundary to test whether we're in the + // right region, not the paragraph, since the paragraph may be positioned + // some way in from where the user clicks. + { + long tmpPos; + wxRichTextObject* tempObj, *tempContextObj; + if (GetParent() && GetParent()->wxRichTextObject::HitTest(dc, pt, tmpPos, & tempObj, & tempContextObj, flags) == wxRICHTEXT_HITTEST_NONE) + return wxRICHTEXT_HITTEST_NONE; + } + + wxRichTextObjectList::compatibility_iterator objNode = m_children.GetFirst(); + while (objNode) + { + wxRichTextObject* child = objNode->GetData(); + if (child->IsTopLevel() && ((flags & wxRICHTEXT_HITTEST_NO_NESTED_OBJECTS) == 0)) + { + { + int hitTest = child->HitTest(dc, pt, textPosition, obj, contextObj); + if (hitTest != wxRICHTEXT_HITTEST_NONE) + return hitTest; + } + } + + objNode = objNode->GetNext(); + } + wxPoint paraPos = GetPosition(); wxRichTextLineList::compatibility_iterator node = m_cachedLines.GetFirst(); @@ -4258,11 +5262,15 @@ int wxRichTextParagraph::HitTest(wxDC& dc, const wxPoint& pt, long& textPosition if (pt.x < linePos.x) { textPosition = lineRange.GetStart(); + *obj = FindObjectAtPosition(textPosition); + *contextObj = GetContainer(); return wxRICHTEXT_HITTEST_BEFORE|wxRICHTEXT_HITTEST_OUTSIDE; } else if (pt.x >= (linePos.x + lineSize.x)) { textPosition = lineRange.GetEnd(); + *obj = FindObjectAtPosition(textPosition); + *contextObj = GetContainer(); return wxRICHTEXT_HITTEST_AFTER|wxRICHTEXT_HITTEST_OUTSIDE; } else @@ -4286,6 +5294,9 @@ int wxRichTextParagraph::HitTest(wxDC& dc, const wxPoint& pt, long& textPosition { textPosition = i + lineRange.GetStart(); // minus 1? + *obj = FindObjectAtPosition(textPosition); + *contextObj = GetContainer(); + // So now we know it's between i-1 and i. // Let's see if we can be more precise about // which side of the position it's on. @@ -4317,6 +5328,9 @@ int wxRichTextParagraph::HitTest(wxDC& dc, const wxPoint& pt, long& textPosition { textPosition = i; + *obj = FindObjectAtPosition(textPosition); + *contextObj = GetContainer(); + // So now we know it's between i-1 and i. // Let's see if we can be more precise about // which side of the position it's on. @@ -4443,7 +5457,9 @@ wxRichTextObject* wxRichTextParagraph::FindObjectAtPosition(long position) while (node) { wxRichTextObject* obj = node->GetData(); - if (obj->GetRange().Contains(position)) + if (obj->GetRange().Contains(position) || + obj->GetRange().GetStart() == position || + obj->GetRange().GetEnd() == position) return obj; node = node->GetNext(); @@ -4718,13 +5734,22 @@ bool wxRichTextParagraph::ClearUnusedLines(int lineCount) /// Get combined attributes of the base style, paragraph style and character style. We use this to dynamically /// retrieve the actual style. -wxRichTextAttr wxRichTextParagraph::GetCombinedAttributes(const wxRichTextAttr& contentStyle) const +wxRichTextAttr wxRichTextParagraph::GetCombinedAttributes(const wxRichTextAttr& contentStyle, bool includingBoxAttr) const { wxRichTextAttr attr; - wxRichTextBuffer* buf = wxDynamicCast(GetParent(), wxRichTextBuffer); + wxRichTextParagraphLayoutBox* buf = wxDynamicCast(GetParent(), wxRichTextParagraphLayoutBox); if (buf) { attr = buf->GetBasicStyle(); + if (!includingBoxAttr) + { + attr.GetTextBoxAttr().Reset(); + // The background colour will be painted by the container, and we don't + // want to unnecessarily overwrite the background when we're drawing text + // because this may erase the guideline (which appears just under the text + // if there's no padding). + attr.SetFlags(attr.GetFlags() & ~wxTEXT_ATTR_BACKGROUND_COLOUR); + } wxRichTextApplyStyle(attr, GetAttributes()); } else @@ -4735,13 +5760,15 @@ wxRichTextAttr wxRichTextParagraph::GetCombinedAttributes(const wxRichTextAttr& } /// Get combined attributes of the base style and paragraph style. -wxRichTextAttr wxRichTextParagraph::GetCombinedAttributes() const +wxRichTextAttr wxRichTextParagraph::GetCombinedAttributes(bool includingBoxAttr) const { wxRichTextAttr attr; - wxRichTextBuffer* buf = wxDynamicCast(GetParent(), wxRichTextBuffer); + wxRichTextParagraphLayoutBox* buf = wxDynamicCast(GetParent(), wxRichTextParagraphLayoutBox); if (buf) { attr = buf->GetBasicStyle(); + if (!includingBoxAttr) + attr.GetTextBoxAttr().Reset(); wxRichTextApplyStyle(attr, GetAttributes()); } else @@ -4750,7 +5777,7 @@ wxRichTextAttr wxRichTextParagraph::GetCombinedAttributes() const return attr; } -/// Create default tabstop array +// Create default tabstop array void wxRichTextParagraph::InitDefaultTabs() { // create a default tab list at 10 mm each. @@ -4760,7 +5787,7 @@ void wxRichTextParagraph::InitDefaultTabs() } } -/// Clear default tabstop array +// Clear default tabstop array void wxRichTextParagraph::ClearDefaultTabs() { sm_defaultTabs.Clear(); @@ -4779,7 +5806,7 @@ void wxRichTextParagraph::LayoutFloat(wxDC& dc, const wxRect& rect, int style, w anchored->GetRangeSize(anchored->GetRange(), size, descent, dc, style); int offsetY = 0; - if (anchored->GetAttributes().GetTextBoxAttr().GetTop().IsPresent()) + if (anchored->GetAttributes().GetTextBoxAttr().GetTop().IsValid()) { offsetY = anchored->GetAttributes().GetTextBoxAttr().GetTop().GetValue(); if (anchored->GetAttributes().GetTextBoxAttr().GetTop().GetUnits() == wxTEXT_ATTR_UNITS_TENTHS_MM) @@ -4800,9 +5827,9 @@ void wxRichTextParagraph::LayoutFloat(wxDC& dc, const wxRect& rect, int style, w } if (anchored->GetAttributes().GetTextBoxAttr().GetFloatMode() == wxTEXT_BOX_ATTR_FLOAT_LEFT) - x = 0; + x = rect.x; else if (anchored->GetAttributes().GetTextBoxAttr().GetFloatMode() == wxTEXT_BOX_ATTR_FLOAT_RIGHT) - x = rect.width - size.x; + x = rect.x + rect.width - size.x; anchored->SetPosition(wxPoint(x, pos)); anchored->SetCachedSize(size); @@ -4813,7 +5840,7 @@ void wxRichTextParagraph::LayoutFloat(wxDC& dc, const wxRect& rect, int style, w } } -/// Get the first position from pos that has a line break character. +// Get the first position from pos that has a line break character. long wxRichTextParagraph::GetFirstLineBreakPosition(long pos) { wxRichTextObjectList::compatibility_iterator node = m_children.GetFirst(); @@ -4905,12 +5932,27 @@ wxRichTextPlainText::wxRichTextPlainText(const wxString& text, wxRichTextObject* #define WIDTH_FOR_DEFAULT_TABS 50 /// Draw the item -bool wxRichTextPlainText::Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextRange& selectionRange, const wxRect& rect, int descent, int WXUNUSED(style)) +bool wxRichTextPlainText::Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int descent, int WXUNUSED(style)) { wxRichTextParagraph* para = wxDynamicCast(GetParent(), wxRichTextParagraph); wxASSERT (para != NULL); - wxRichTextAttr textAttr(para ? para->GetCombinedAttributes(GetAttributes()) : GetAttributes()); + wxRichTextAttr textAttr(para ? para->GetCombinedAttributes(GetAttributes(), false /* no box attributes */) : GetAttributes()); + + // Let's make the assumption for now that for content in a paragraph, including + // text, we never have a discontinuous selection. So we only deal with a + // single range. + wxRichTextRange selectionRange; + if (selection.IsValid()) + { + wxRichTextRangeArray selectionRanges = selection.GetSelectionForObject(this); + if (selectionRanges.GetCount() > 0) + selectionRange = selectionRanges[0]; + else + selectionRange = wxRICHTEXT_NO_SELECTION; + } + else + selectionRange = wxRICHTEXT_NO_SELECTION; int offset = GetRange().GetStart(); @@ -4963,6 +6005,8 @@ bool wxRichTextPlainText::Draw(wxDC& dc, const wxRichTextRange& range, const wxR y = rect.y + (rect.height - charHeight - (descent - m_descent)); } + // TODO: new selection code + // (a) All selected. if (selectionRange.GetStart() <= range.GetStart() && selectionRange.GetEnd() >= range.GetEnd()) { @@ -5195,7 +6239,9 @@ bool wxRichTextPlainText::Layout(wxDC& dc, const wxRect& WXUNUSED(rect), int WXU // Only lay out if we haven't already cached the size if (m_size.x == -1) GetRangeSize(GetRange(), m_size, m_descent, dc, 0, wxPoint(0, 0)); - + m_maxSize = m_size; + // Eventually we want to have a reasonable estimate of minimum size. + m_minSize = wxSize(0, 0); return true; } @@ -5216,6 +6262,7 @@ bool wxRichTextPlainText::GetRangeSize(const wxRichTextRange& range, wxSize& siz wxRichTextParagraph* para = wxDynamicCast(GetParent(), wxRichTextParagraph); wxASSERT (para != NULL); + int relativeX = position.x - GetParent()->GetPosition().x; wxRichTextAttr textAttr(para ? para->GetCombinedAttributes(GetAttributes()) : GetAttributes()); @@ -5311,7 +6358,7 @@ bool wxRichTextPlainText::GetRangeSize(const wxRichTextRange& range, wxSize& siz { dc.GetTextExtent(stringFragment, & w, & h); width += w; - absoluteWidth = width + position.x; + absoluteWidth = width + relativeX; haveDescent = true; } @@ -5556,6 +6603,7 @@ void wxRichTextBuffer::Copy(const wxRichTextBuffer& obj) delete m_batchedCommand; m_batchedCommand = NULL; m_suppressUndo = obj.m_suppressUndo; + m_invalidRange = obj.m_invalidRange; } /// Push style sheet to top of stack @@ -5587,15 +6635,21 @@ wxRichTextStyleSheet* wxRichTextBuffer::PopStyleSheet() /// Submit command to insert paragraphs bool wxRichTextBuffer::InsertParagraphsWithUndo(long pos, const wxRichTextParagraphLayoutBox& paragraphs, wxRichTextCtrl* ctrl, int flags) { - wxRichTextAction* action = new wxRichTextAction(NULL, _("Insert Text"), wxRICHTEXT_INSERT, this, ctrl, false); + return ctrl->GetFocusObject()->InsertParagraphsWithUndo(pos, paragraphs, ctrl, this, flags); +} - wxRichTextAttr attr(GetDefaultStyle()); +/// Submit command to insert paragraphs +bool wxRichTextParagraphLayoutBox::InsertParagraphsWithUndo(long pos, const wxRichTextParagraphLayoutBox& paragraphs, wxRichTextCtrl* ctrl, wxRichTextBuffer* buffer, int flags) +{ + wxRichTextAction* action = new wxRichTextAction(NULL, _("Insert Text"), wxRICHTEXT_INSERT, buffer, this, ctrl, false); + + wxRichTextAttr attr(buffer->GetDefaultStyle()); wxRichTextAttr* p = NULL; wxRichTextAttr paraAttr; if (flags & wxRICHTEXT_INSERT_WITH_PREVIOUS_PARAGRAPH_STYLE) { - paraAttr = GetStyleForNewParagraph(pos); + paraAttr = GetStyleForNewParagraph(buffer, pos); if (!paraAttr.IsDefault()) p = & paraAttr; } @@ -5615,14 +6669,14 @@ bool wxRichTextBuffer::InsertParagraphsWithUndo(long pos, const wxRichTextParagr action->SetPosition(pos); - wxRichTextRange range = wxRichTextRange(pos, pos + paragraphs.GetRange().GetEnd() - 1); + wxRichTextRange range = wxRichTextRange(pos, pos + paragraphs.GetOwnRange().GetEnd() - 1); if (!paragraphs.GetPartialParagraph()) range.SetEnd(range.GetEnd()+1); // Set the range we'll need to delete in Undo action->SetRange(range); - SubmitAction(action); + buffer->SubmitAction(action); return true; } @@ -5630,21 +6684,27 @@ bool wxRichTextBuffer::InsertParagraphsWithUndo(long pos, const wxRichTextParagr /// Submit command to insert the given text bool wxRichTextBuffer::InsertTextWithUndo(long pos, const wxString& text, wxRichTextCtrl* ctrl, int flags) { - wxRichTextAction* action = new wxRichTextAction(NULL, _("Insert Text"), wxRICHTEXT_INSERT, this, ctrl, false); + return ctrl->GetFocusObject()->InsertTextWithUndo(pos, text, ctrl, this, flags); +} + +/// Submit command to insert the given text +bool wxRichTextParagraphLayoutBox::InsertTextWithUndo(long pos, const wxString& text, wxRichTextCtrl* ctrl, wxRichTextBuffer* buffer, int flags) +{ + wxRichTextAction* action = new wxRichTextAction(NULL, _("Insert Text"), wxRICHTEXT_INSERT, buffer, this, ctrl, false); wxRichTextAttr* p = NULL; wxRichTextAttr paraAttr; if (flags & wxRICHTEXT_INSERT_WITH_PREVIOUS_PARAGRAPH_STYLE) { // Get appropriate paragraph style - paraAttr = GetStyleForNewParagraph(pos, false, false); + paraAttr = GetStyleForNewParagraph(buffer, pos, false, false); if (!paraAttr.IsDefault()) p = & paraAttr; } action->GetNewParagraphs().AddParagraphs(text, p); - int length = action->GetNewParagraphs().GetRange().GetLength(); + int length = action->GetNewParagraphs().GetOwnRange().GetLength(); if (text.length() > 0 && text.Last() != wxT('\n')) { @@ -5660,7 +6720,7 @@ bool wxRichTextBuffer::InsertTextWithUndo(long pos, const wxString& text, wxRich // Set the range we'll need to delete in Undo action->SetRange(wxRichTextRange(pos, pos + length - 1)); - SubmitAction(action); + buffer->SubmitAction(action); return true; } @@ -5668,18 +6728,24 @@ bool wxRichTextBuffer::InsertTextWithUndo(long pos, const wxString& text, wxRich /// Submit command to insert the given text bool wxRichTextBuffer::InsertNewlineWithUndo(long pos, wxRichTextCtrl* ctrl, int flags) { - wxRichTextAction* action = new wxRichTextAction(NULL, _("Insert Text"), wxRICHTEXT_INSERT, this, ctrl, false); + return ctrl->GetFocusObject()->InsertNewlineWithUndo(pos, ctrl, this, flags); +} + +/// Submit command to insert the given text +bool wxRichTextParagraphLayoutBox::InsertNewlineWithUndo(long pos, wxRichTextCtrl* ctrl, wxRichTextBuffer* buffer, int flags) +{ + wxRichTextAction* action = new wxRichTextAction(NULL, _("Insert Text"), wxRICHTEXT_INSERT, buffer, this, ctrl, false); wxRichTextAttr* p = NULL; wxRichTextAttr paraAttr; if (flags & wxRICHTEXT_INSERT_WITH_PREVIOUS_PARAGRAPH_STYLE) { - paraAttr = GetStyleForNewParagraph(pos, false, true /* look for next paragraph style */); + paraAttr = GetStyleForNewParagraph(buffer, pos, false, true /* look for next paragraph style */); if (!paraAttr.IsDefault()) p = & paraAttr; } - wxRichTextAttr attr(GetDefaultStyle()); + wxRichTextAttr attr(buffer->GetDefaultStyle()); wxRichTextParagraph* newPara = new wxRichTextParagraph(wxEmptyString, this, & attr); action->GetNewParagraphs().AppendChild(newPara); @@ -5709,15 +6775,15 @@ bool wxRichTextBuffer::InsertNewlineWithUndo(long pos, wxRichTextCtrl* ctrl, int // Use the default character style // Use the default character style - if (!GetDefaultStyle().IsDefault() && newPara->GetChildren().GetFirst()) + if (!buffer->GetDefaultStyle().IsDefault() && newPara->GetChildren().GetFirst()) { // Check whether the default style merely reflects the paragraph/basic style, // in which case don't apply it. - wxRichTextAttr defaultStyle(GetDefaultStyle()); + wxRichTextAttr defaultStyle(buffer->GetDefaultStyle()); wxRichTextAttr toApply; if (para) { - wxRichTextAttr combinedAttr = para->GetCombinedAttributes(); + wxRichTextAttr combinedAttr = para->GetCombinedAttributes(true /* include box attributes */); wxRichTextAttr newAttr; // This filters out attributes that are accounted for by the current // paragraph/basic style @@ -5733,7 +6799,7 @@ bool wxRichTextBuffer::InsertNewlineWithUndo(long pos, wxRichTextCtrl* ctrl, int // Set the range we'll need to delete in Undo action->SetRange(wxRichTextRange(pos1, pos1)); - SubmitAction(action); + buffer->SubmitAction(action); return true; } @@ -5742,18 +6808,26 @@ bool wxRichTextBuffer::InsertNewlineWithUndo(long pos, wxRichTextCtrl* ctrl, int bool wxRichTextBuffer::InsertImageWithUndo(long pos, const wxRichTextImageBlock& imageBlock, wxRichTextCtrl* ctrl, int flags, const wxRichTextAttr& textAttr) { - wxRichTextAction* action = new wxRichTextAction(NULL, _("Insert Image"), wxRICHTEXT_INSERT, this, ctrl, false); + return ctrl->GetFocusObject()->InsertImageWithUndo(pos, imageBlock, ctrl, this, flags, textAttr); +} + +/// Submit command to insert the given image +bool wxRichTextParagraphLayoutBox::InsertImageWithUndo(long pos, const wxRichTextImageBlock& imageBlock, + wxRichTextCtrl* ctrl, wxRichTextBuffer* buffer, int flags, + const wxRichTextAttr& textAttr) +{ + wxRichTextAction* action = new wxRichTextAction(NULL, _("Insert Image"), wxRICHTEXT_INSERT, buffer, this, ctrl, false); wxRichTextAttr* p = NULL; wxRichTextAttr paraAttr; if (flags & wxRICHTEXT_INSERT_WITH_PREVIOUS_PARAGRAPH_STYLE) { - paraAttr = GetStyleForNewParagraph(pos); + paraAttr = GetStyleForNewParagraph(buffer, pos); if (!paraAttr.IsDefault()) p = & paraAttr; } - wxRichTextAttr attr(GetDefaultStyle()); + wxRichTextAttr attr(buffer->GetDefaultStyle()); wxRichTextParagraph* newPara = new wxRichTextParagraph(this, & attr); if (p) @@ -5772,26 +6846,32 @@ bool wxRichTextBuffer::InsertImageWithUndo(long pos, const wxRichTextImageBlock& // Set the range we'll need to delete in Undo action->SetRange(wxRichTextRange(pos, pos)); - SubmitAction(action); + buffer->SubmitAction(action); return true; } // Insert an object with no change of it -bool wxRichTextBuffer::InsertObjectWithUndo(long pos, wxRichTextObject *object, wxRichTextCtrl* ctrl, int flags) +wxRichTextObject* wxRichTextBuffer::InsertObjectWithUndo(long pos, wxRichTextObject *object, wxRichTextCtrl* ctrl, int flags) { - wxRichTextAction* action = new wxRichTextAction(NULL, _("Insert object"), wxRICHTEXT_INSERT, this, ctrl, false); + return ctrl->GetFocusObject()->InsertObjectWithUndo(pos, object, ctrl, this, flags); +} + +// Insert an object with no change of it +wxRichTextObject* wxRichTextParagraphLayoutBox::InsertObjectWithUndo(long pos, wxRichTextObject *object, wxRichTextCtrl* ctrl, wxRichTextBuffer* buffer, int flags) +{ + wxRichTextAction* action = new wxRichTextAction(NULL, _("Insert Object"), wxRICHTEXT_INSERT, buffer, this, ctrl, false); wxRichTextAttr* p = NULL; wxRichTextAttr paraAttr; if (flags & wxRICHTEXT_INSERT_WITH_PREVIOUS_PARAGRAPH_STYLE) { - paraAttr = GetStyleForNewParagraph(pos); + paraAttr = GetStyleForNewParagraph(buffer, pos); if (!paraAttr.IsDefault()) p = & paraAttr; } - wxRichTextAttr attr(GetDefaultStyle()); + wxRichTextAttr attr(buffer->GetDefaultStyle()); wxRichTextParagraph* newPara = new wxRichTextParagraph(this, & attr); if (p) @@ -5808,14 +6888,16 @@ bool wxRichTextBuffer::InsertObjectWithUndo(long pos, wxRichTextObject *object, // Set the range we'll need to delete in Undo action->SetRange(wxRichTextRange(pos, pos)); - SubmitAction(action); + buffer->SubmitAction(action); - return true; + wxRichTextObject* obj = GetLeafObjectAtPosition(pos); + 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. -wxRichTextAttr wxRichTextBuffer::GetStyleForNewParagraph(long pos, bool caretPosition, bool lookUpNewParaStyle) const +wxRichTextAttr wxRichTextParagraphLayoutBox::GetStyleForNewParagraph(wxRichTextBuffer* buffer, long pos, bool caretPosition, bool lookUpNewParaStyle) const { wxRichTextParagraph* para = GetParagraphAtPosition(pos, caretPosition); if (para) @@ -5824,19 +6906,19 @@ wxRichTextAttr wxRichTextBuffer::GetStyleForNewParagraph(long pos, bool caretPos bool foundAttributes = false; // Look for a matching paragraph style - if (lookUpNewParaStyle && !para->GetAttributes().GetParagraphStyleName().IsEmpty() && GetStyleSheet()) + if (lookUpNewParaStyle && !para->GetAttributes().GetParagraphStyleName().IsEmpty() && buffer->GetStyleSheet()) { - wxRichTextParagraphStyleDefinition* paraDef = GetStyleSheet()->FindParagraphStyle(para->GetAttributes().GetParagraphStyleName()); + wxRichTextParagraphStyleDefinition* paraDef = buffer->GetStyleSheet()->FindParagraphStyle(para->GetAttributes().GetParagraphStyleName()); if (paraDef) { // If we're not at the end of the paragraph, then we apply THIS style, and not the designated next style. if (para->GetRange().GetEnd() == pos && !paraDef->GetNextStyle().IsEmpty()) { - wxRichTextParagraphStyleDefinition* nextParaDef = GetStyleSheet()->FindParagraphStyle(paraDef->GetNextStyle()); + wxRichTextParagraphStyleDefinition* nextParaDef = buffer->GetStyleSheet()->FindParagraphStyle(paraDef->GetNextStyle()); if (nextParaDef) { foundAttributes = true; - attr = nextParaDef->GetStyleMergedWithBase(GetStyleSheet()); + attr = nextParaDef->GetStyleMergedWithBase(buffer->GetStyleSheet()); } } @@ -5844,22 +6926,22 @@ wxRichTextAttr wxRichTextBuffer::GetStyleForNewParagraph(long pos, bool caretPos if (!foundAttributes) { foundAttributes = true; - attr = paraDef->GetStyleMergedWithBase(GetStyleSheet()); + attr = paraDef->GetStyleMergedWithBase(buffer->GetStyleSheet()); } } } // Also apply list style if present - if (lookUpNewParaStyle && !para->GetAttributes().GetListStyleName().IsEmpty() && GetStyleSheet()) + if (lookUpNewParaStyle && !para->GetAttributes().GetListStyleName().IsEmpty() && buffer->GetStyleSheet()) { - wxRichTextListStyleDefinition* listDef = GetStyleSheet()->FindListStyle(para->GetAttributes().GetListStyleName()); + wxRichTextListStyleDefinition* listDef = buffer->GetStyleSheet()->FindListStyle(para->GetAttributes().GetListStyleName()); if (listDef) { int thisIndent = para->GetAttributes().GetLeftIndent(); int thisLevel = para->GetAttributes().HasOutlineLevel() ? para->GetAttributes().GetOutlineLevel() : listDef->FindLevelForIndent(thisIndent); // Apply the overall list style, and item style for this level - wxRichTextAttr listStyle(listDef->GetCombinedStyleForLevel(thisLevel, GetStyleSheet())); + wxRichTextAttr listStyle(listDef->GetCombinedStyleForLevel(thisLevel, buffer->GetStyleSheet())); wxRichTextApplyStyle(attr, listStyle); attr.SetOutlineLevel(thisLevel); if (para->GetAttributes().HasBulletNumber()) @@ -5888,7 +6970,13 @@ wxRichTextAttr wxRichTextBuffer::GetStyleForNewParagraph(long pos, bool caretPos /// Submit command to delete this range bool wxRichTextBuffer::DeleteRangeWithUndo(const wxRichTextRange& range, wxRichTextCtrl* ctrl) { - wxRichTextAction* action = new wxRichTextAction(NULL, _("Delete"), wxRICHTEXT_DELETE, this, ctrl); + return ctrl->GetFocusObject()->DeleteRangeWithUndo(range, ctrl, this); +} + +/// Submit command to delete this range +bool wxRichTextParagraphLayoutBox::DeleteRangeWithUndo(const wxRichTextRange& range, wxRichTextCtrl* ctrl, wxRichTextBuffer* buffer) +{ + wxRichTextAction* action = new wxRichTextAction(NULL, _("Delete"), wxRICHTEXT_DELETE, buffer, this, ctrl); action->SetPosition(ctrl->GetCaretPosition()); @@ -5914,7 +7002,7 @@ bool wxRichTextBuffer::DeleteRangeWithUndo(const wxRichTextRange& range, wxRichT } } - SubmitAction(action); + buffer->SubmitAction(action); return true; } @@ -6472,6 +7560,10 @@ bool wxRichTextBuffer::SaveFile(wxOutputStream& stream, wxRichTextFileType type) bool wxRichTextBuffer::CopyToClipboard(const wxRichTextRange& range) { bool success = false; + wxRichTextParagraphLayoutBox* container = this; + if (GetRichTextCtrl()) + container = GetRichTextCtrl()->GetFocusObject(); + #if wxUSE_CLIPBOARD && wxUSE_DATAOBJ if (!wxTheClipboard->IsOpened() && wxTheClipboard->Open()) @@ -6483,7 +7575,7 @@ bool wxRichTextBuffer::CopyToClipboard(const wxRichTextRange& range) wxDataObjectComposite* compositeObject = new wxDataObjectComposite(); { - wxString text = GetTextForRange(range); + wxString text = container->GetTextForRange(range); #ifdef __WXMSW__ text = wxTextFile::Translate(text, wxTextFileType_Dos); @@ -6497,7 +7589,7 @@ bool wxRichTextBuffer::CopyToClipboard(const wxRichTextRange& range) if (FindHandler(wxRICHTEXT_TYPE_XML)) { wxRichTextBuffer* richTextBuf = new wxRichTextBuffer; - CopyFragment(range, *richTextBuf); + container->CopyFragment(range, *richTextBuf); compositeObject->Add(new wxRichTextBufferDataObject(richTextBuf), true /* preferred */); } @@ -6518,6 +7610,10 @@ bool wxRichTextBuffer::CopyToClipboard(const wxRichTextRange& range) bool wxRichTextBuffer::PasteFromClipboard(long position) { bool success = false; + wxRichTextParagraphLayoutBox* container = this; + if (GetRichTextCtrl()) + container = GetRichTextCtrl()->GetFocusObject(); + #if wxUSE_CLIPBOARD && wxUSE_DATAOBJ if (CanPasteFromClipboard()) { @@ -6530,16 +7626,16 @@ bool wxRichTextBuffer::PasteFromClipboard(long position) wxRichTextBuffer* richTextBuffer = data.GetRichTextBuffer(); if (richTextBuffer) { - InsertParagraphsWithUndo(position+1, *richTextBuffer, GetRichTextCtrl(), 0); + container->InsertParagraphsWithUndo(position+1, *richTextBuffer, GetRichTextCtrl(), this, 0); if (GetRichTextCtrl()) - GetRichTextCtrl()->ShowPosition(position + richTextBuffer->GetRange().GetEnd()); + GetRichTextCtrl()->ShowPosition(position + richTextBuffer->GetOwnRange().GetEnd()); delete richTextBuffer; } } else if (wxTheClipboard->IsSupported(wxDF_TEXT) -#if wxUSE_UNICODE - || wxTheClipboard->IsSupported(wxDF_UNICODETEXT) -#endif // wxUSE_UNICODE + #if wxUSE_UNICODE + || wxTheClipboard->IsSupported(wxDF_UNICODETEXT) + #endif ) { wxTextDataObject data; @@ -6558,7 +7654,7 @@ bool wxRichTextBuffer::PasteFromClipboard(long position) #else wxString text2 = text; #endif - InsertTextWithUndo(position+1, text2, GetRichTextCtrl(), wxRICHTEXT_INSERT_WITH_PREVIOUS_PARAGRAPH_STYLE); + container->InsertTextWithUndo(position+1, text2, GetRichTextCtrl(), this, wxRICHTEXT_INSERT_WITH_PREVIOUS_PARAGRAPH_STYLE); if (GetRichTextCtrl()) GetRichTextCtrl()->ShowPosition(position + text2.Length()); @@ -6572,7 +7668,7 @@ bool wxRichTextBuffer::PasteFromClipboard(long position) wxBitmap bitmap(data.GetBitmap()); wxImage image(bitmap.ConvertToImage()); - wxRichTextAction* action = new wxRichTextAction(NULL, _("Insert Image"), wxRICHTEXT_INSERT, this, GetRichTextCtrl(), false); + wxRichTextAction* action = new wxRichTextAction(NULL, _("Insert Image"), wxRICHTEXT_INSERT, this, container, GetRichTextCtrl(), false); action->GetNewParagraphs().AddImage(image); @@ -6606,10 +7702,10 @@ bool wxRichTextBuffer::CanPasteFromClipboard() const { if (wxTheClipboard->IsSupported(wxDF_TEXT) #if wxUSE_UNICODE - || wxTheClipboard->IsSupported(wxDF_UNICODETEXT) -#endif // wxUSE_UNICODE - || wxTheClipboard->IsSupported(wxDataFormat(wxRichTextBufferDataObject::GetRichTextBufferFormatId())) - || wxTheClipboard->IsSupported(wxDF_BITMAP)) + || wxTheClipboard->IsSupported(wxDF_UNICODETEXT) +#endif + || wxTheClipboard->IsSupported(wxDataFormat(wxRichTextBufferDataObject::GetRichTextBufferFormatId())) || + wxTheClipboard->IsSupported(wxDF_BITMAP)) { canPaste = true; } @@ -6690,6 +7786,7 @@ bool wxRichTextBuffer::SetStyleSheetAndNotify(wxRichTextStyleSheet* sheet) wxRichTextEvent event(wxEVT_COMMAND_RICHTEXT_STYLESHEET_REPLACING, id); event.SetEventObject(GetRichTextCtrl()); + event.SetContainer(GetRichTextCtrl()->GetFocusObject()); event.SetOldStyleSheet(oldSheet); event.SetNewStyleSheet(sheet); event.Allow(); @@ -6722,6 +7819,24 @@ void wxRichTextBuffer::SetRenderer(wxRichTextRenderer* renderer) sm_renderer = renderer; } +/// Hit-testing: returns a flag indicating hit test details, plus +/// information about position +int wxRichTextBuffer::HitTest(wxDC& dc, const wxPoint& pt, long& textPosition, wxRichTextObject** obj, wxRichTextObject** contextObj, int flags) +{ + int ret = wxRichTextParagraphLayoutBox::HitTest(dc, pt, textPosition, obj, contextObj, flags); + if (ret != wxRICHTEXT_HITTEST_NONE) + { + return ret; + } + else + { + textPosition = m_ownRange.GetEnd()-1; + *obj = this; + *contextObj = this; + return wxRICHTEXT_HITTEST_AFTER|wxRICHTEXT_HITTEST_OUTSIDE; + } +} + bool wxRichTextStdRenderer::DrawStandardBullet(wxRichTextParagraph* paragraph, wxDC& dc, const wxRichTextAttr& bulletAttr, const wxRect& rect) { if (bulletAttr.GetTextColour().Ok()) @@ -6789,6 +7904,11 @@ bool wxRichTextStdRenderer::DrawStandardBullet(wxRichTextParagraph* paragraph, w dc.DrawPolygon(3, pts); } + else if (bulletAttr.GetBulletName() == wxT("standard/circle-outline")) + { + wxCheckSetBrush(dc, *wxTRANSPARENT_BRUSH); + dc.DrawEllipse(x, y, bulletWidth, bulletHeight); + } else // "standard/circle", and catch-all { dc.DrawEllipse(x, y, bulletWidth, bulletHeight); @@ -6860,6 +7980,7 @@ bool wxRichTextStdRenderer::DrawBitmapBullet(wxRichTextParagraph* WXUNUSED(parag bool wxRichTextStdRenderer::EnumerateStandardBulletNames(wxArrayString& bulletNames) { bulletNames.Add(wxTRANSLATE("standard/circle")); + bulletNames.Add(wxTRANSLATE("standard/circle-outline")); bulletNames.Add(wxTRANSLATE("standard/square")); bulletNames.Add(wxTRANSLATE("standard/diamond")); bulletNames.Add(wxTRANSLATE("standard/triangle")); @@ -6871,59 +7992,1208 @@ bool wxRichTextStdRenderer::EnumerateStandardBulletNames(wxArrayString& bulletNa * wxRichTextBox */ -IMPLEMENT_DYNAMIC_CLASS(wxRichTextBox, wxRichTextCompositeObject) +IMPLEMENT_DYNAMIC_CLASS(wxRichTextBox, wxRichTextParagraphLayoutBox) wxRichTextBox::wxRichTextBox(wxRichTextObject* parent): - wxRichTextCompositeObject(parent) + wxRichTextParagraphLayoutBox(parent) { } /// Draw the item -bool wxRichTextBox::Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextRange& selectionRange, const wxRect& WXUNUSED(rect), int descent, int style) +bool wxRichTextBox::Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int descent, int style) { - wxRichTextObjectList::compatibility_iterator node = m_children.GetFirst(); - while (node) - { - wxRichTextObject* child = node->GetData(); - - wxRect childRect = wxRect(child->GetPosition(), child->GetCachedSize()); - child->Draw(dc, range, selectionRange, childRect, descent, style); - - node = node->GetNext(); - } - return true; -} - -/// Lay the item out -bool wxRichTextBox::Layout(wxDC& dc, const wxRect& rect, int style) -{ - wxRichTextObjectList::compatibility_iterator node = m_children.GetFirst(); - while (node) - { - wxRichTextObject* child = node->GetData(); - child->Layout(dc, rect, style); - - node = node->GetNext(); - } - m_dirty = false; - return true; + if (!IsShown()) + return true; + // TODO: if the active object in the control, draw an indication. + // We need to add the concept of active object, and not just focus object, + // so we can apply commands (properties, delete, ...) to objects such as text boxes and images. + // Ultimately we would like to be able to interactively resize an active object + // using drag handles. + return wxRichTextParagraphLayoutBox::Draw(dc, range, selection, rect, descent, style); } /// Copy void wxRichTextBox::Copy(const wxRichTextBox& obj) { - wxRichTextCompositeObject::Copy(obj); + wxRichTextParagraphLayoutBox::Copy(obj); } -/// Get/set the size for the given range. Assume only has one child. -bool wxRichTextBox::GetRangeSize(const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, int flags, wxPoint position, wxArrayInt* partialExtents) const +// Edit properties via a GUI +bool wxRichTextBox::EditProperties(wxWindow* parent, wxRichTextBuffer* buffer) { - wxRichTextObjectList::compatibility_iterator node = m_children.GetFirst(); - if (node) + wxRichTextObjectPropertiesDialog boxDlg(this, wxGetTopLevelParent(parent), wxID_ANY, _("Box Properties")); + boxDlg.SetAttributes(GetAttributes()); + + if (boxDlg.ShowModal() == wxID_OK) { - wxRichTextObject* child = node->GetData(); - return child->GetRangeSize(range, size, descent, dc, flags, position, partialExtents); + // By passing wxRICHTEXT_SETSTYLE_RESET, indeterminate attributes set by the user will be set as + // indeterminate in the object. + boxDlg.ApplyStyle(buffer->GetRichTextCtrl(), wxRICHTEXT_SETSTYLE_WITH_UNDO|wxRICHTEXT_SETSTYLE_RESET); + return true; + } + else + return false; +} + +IMPLEMENT_DYNAMIC_CLASS(wxRichTextCell, wxRichTextBox) + +wxRichTextCell::wxRichTextCell(wxRichTextObject* parent): + wxRichTextBox(parent) +{ +} + +/// Draw the item +bool wxRichTextCell::Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int descent, int style) +{ + return wxRichTextBox::Draw(dc, range, selection, rect, descent, style); +} + +/// Copy +void wxRichTextCell::Copy(const wxRichTextCell& obj) +{ + wxRichTextBox::Copy(obj); +} + +// Edit properties via a GUI +bool wxRichTextCell::EditProperties(wxWindow* parent, wxRichTextBuffer* buffer) +{ + // We need to gather common attributes for all selected cells. + + wxRichTextTable* table = wxDynamicCast(GetParent(), wxRichTextTable); + bool multipleCells = false; + wxRichTextAttr attr; + + if (table && buffer && buffer->GetRichTextCtrl() && buffer->GetRichTextCtrl()->GetSelection().IsValid() && + buffer->GetRichTextCtrl()->GetSelection().GetContainer() == GetParent()) + { + wxRichTextAttr clashingAttr, absentAttr; + const wxRichTextSelection& sel = buffer->GetRichTextCtrl()->GetSelection(); + size_t i; + int selectedCellCount = 0; + for (i = 0; i < sel.GetCount(); i++) + { + const wxRichTextRange& range = sel[i]; + wxRichTextCell* cell = table->GetCell(range.GetStart()); + if (cell) + { + wxRichTextAttr cellStyle = cell->GetAttributes(); + + CollectStyle(attr, cellStyle, clashingAttr, absentAttr); + + selectedCellCount ++; + } + } + multipleCells = selectedCellCount > 1; + } + else + { + attr = GetAttributes(); + } + + wxString caption; + if (multipleCells) + caption = _("Multiple Cell Properties"); + else + caption = _("Cell Properties"); + + wxRichTextObjectPropertiesDialog cellDlg(this, wxGetTopLevelParent(parent), wxID_ANY, caption); + cellDlg.SetAttributes(attr); + + wxRichTextSizePage* sizePage = wxDynamicCast(cellDlg.FindPage(CLASSINFO(wxRichTextSizePage)), wxRichTextSizePage); + if (sizePage) + { + // We don't want position and floating controls for a cell. + sizePage->ShowPositionControls(false); + sizePage->ShowFloatingControls(false); + } + + if (cellDlg.ShowModal() == wxID_OK) + { + if (multipleCells) + { + const wxRichTextSelection& sel = buffer->GetRichTextCtrl()->GetSelection(); + // Apply the style; we interpret indeterminate attributes as 'don't touch this attribute' + // since it may represent clashing attributes across multiple objects. + table->SetCellStyle(sel, attr); + } + else + // For a single object, indeterminate attributes set by the user should be reflected in the + // actual object style, so pass the wxRICHTEXT_SETSTYLE_RESET flag to assign + // the style directly instead of applying (which ignores indeterminate attributes, + // leaving them as they were). + cellDlg.ApplyStyle(buffer->GetRichTextCtrl(), wxRICHTEXT_SETSTYLE_WITH_UNDO|wxRICHTEXT_SETSTYLE_RESET); + return true; + } + else + return false; +} + +WX_DEFINE_OBJARRAY(wxRichTextObjectPtrArrayArray) + +IMPLEMENT_DYNAMIC_CLASS(wxRichTextTable, wxRichTextBox) + +wxRichTextTable::wxRichTextTable(wxRichTextObject* parent): wxRichTextBox(parent) +{ + m_rowCount = 0; + m_colCount = 0; +} + +// Draws the object. +bool wxRichTextTable::Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int descent, int style) +{ + return wxRichTextBox::Draw(dc, range, selection, rect, descent, style); +} + +WX_DECLARE_OBJARRAY(wxRect, wxRichTextRectArray); +WX_DEFINE_OBJARRAY(wxRichTextRectArray); + +// Lays the object out. rect is the space available for layout. Often it will +// be the specified overall space for this object, if trying to constrain +// layout to a particular size, or it could be the total space available in the +// parent. rect is the overall size, so we must subtract margins and padding. +// to get the actual available space. +bool wxRichTextTable::Layout(wxDC& dc, const wxRect& rect, int style) +{ + SetPosition(rect.GetPosition()); + + // TODO: the meaty bit. Calculate sizes of all cells and rows. Try to use + // minimum size if within alloted size, then divide up remaining size + // between rows/cols. + + double scale = 1.0; + wxRichTextBuffer* buffer = GetBuffer(); + if (buffer) scale = buffer->GetScale(); + + wxRect availableSpace = GetAvailableContentArea(dc, rect); + wxTextAttrDimensionConverter converter(dc, scale, availableSpace.GetSize()); + + // If we have no fixed table size, and assuming we're not pushed for + // space, then we don't have to try to stretch the table to fit the contents. + bool stretchToFitTableWidth = false; + + int tableWidth = rect.width; + if (GetAttributes().GetTextBoxAttr().GetWidth().IsValid()) + { + tableWidth = converter.GetPixels(GetAttributes().GetTextBoxAttr().GetWidth()); + + // Fixed table width, so we do want to stretch columns out if necessary. + stretchToFitTableWidth = true; + + // Shouldn't be able to exceed the size passed to this function + tableWidth = wxMin(rect.width, tableWidth); + } + + // Get internal padding + int paddingLeft = 0, paddingRight = 0, paddingTop = 0, paddingBottom = 0; + if (GetAttributes().GetTextBoxAttr().GetPadding().GetLeft().IsValid()) + paddingLeft = converter.GetPixels(GetAttributes().GetTextBoxAttr().GetPadding().GetLeft()); + if (GetAttributes().GetTextBoxAttr().GetPadding().GetRight().IsValid()) + paddingRight = converter.GetPixels(GetAttributes().GetTextBoxAttr().GetPadding().GetRight()); + if (GetAttributes().GetTextBoxAttr().GetPadding().GetTop().IsValid()) + paddingTop = converter.GetPixels(GetAttributes().GetTextBoxAttr().GetPadding().GetTop()); + if (GetAttributes().GetTextBoxAttr().GetPadding().GetLeft().IsValid()) + paddingBottom = converter.GetPixels(GetAttributes().GetTextBoxAttr().GetPadding().GetBottom()); + + // Assume that left and top padding are also used for inter-cell padding. + int paddingX = paddingLeft; + int paddingY = paddingTop; + + int totalLeftMargin = 0, totalRightMargin = 0, totalTopMargin = 0, totalBottomMargin = 0; + GetTotalMargin(dc, buffer, GetAttributes(), totalLeftMargin, totalRightMargin, totalTopMargin, totalBottomMargin); + + // Internal table width - the area for content + int internalTableWidth = tableWidth - totalLeftMargin - totalRightMargin; + + int rowCount = m_cells.GetCount(); + if (m_colCount == 0 || rowCount == 0) + { + wxRect overallRect(rect.x, rect.y, totalLeftMargin + totalRightMargin, totalTopMargin + totalBottomMargin); + SetCachedSize(overallRect.GetSize()); + + // Zero content size + SetMinSize(overallRect.GetSize()); + SetMaxSize(GetMinSize()); + return true; + } + + // The final calculated widths + wxArrayInt colWidths(m_colCount); + + wxArrayInt absoluteColWidths(m_colCount); + // wxArrayInt absoluteColWidthsSpanning(m_colCount); + wxArrayInt percentageColWidths(m_colCount); + // wxArrayInt percentageColWidthsSpanning(m_colCount); + // These are only relevant when the first column contains spanning information. + // wxArrayInt columnSpans(m_colCount); // Each contains 1 for non-spanning cell, > 1 for spanning cell. + wxArrayInt maxColWidths(m_colCount); + wxArrayInt minColWidths(m_colCount); + + wxSize tableSize(tableWidth, 0); + + int i, j, k; + + for (i = 0; i < m_colCount; i++) + { + absoluteColWidths[i] = 0; + // absoluteColWidthsSpanning[i] = 0; + percentageColWidths[i] = -1; + // percentageColWidthsSpanning[i] = -1; + colWidths[i] = 0; + maxColWidths[i] = 0; + minColWidths[i] = 0; + // columnSpans[i] = 1; + } + + // (0) Determine which cells are visible according to spans + // 1 2 3 4 5 + // __________________ + // | | | | | 1 + // |------| |----| + // |------| | | 2 + // |------| | | 3 + // |------------------| + // |__________________| 4 + + // To calculate cell visibility: + // First find all spanning cells. Build an array of span records with start x, y and end x, y. + // Then for each cell, test whether we're within one of those cells, and unless we're at the start of + // that cell, hide the cell. + + // We can also use this array to match the size of spanning cells to the grid. Or just do + // this when we iterate through all cells. + + // 0.1: add spanning cells to an array + wxRichTextRectArray rectArray; + for (j = 0; j < m_rowCount; j++) + { + for (i = 0; i < m_colCount; i++) + { + wxRichTextBox* cell = GetCell(j, i); + int colSpan = 1, rowSpan = 1; + if (cell->GetProperties().HasProperty(wxT("colspan"))) + colSpan = cell->GetProperties().GetPropertyLong(wxT("colspan")); + if (cell->GetProperties().HasProperty(wxT("rowspan"))) + rowSpan = cell->GetProperties().GetPropertyLong(wxT("rowspan")); + if (colSpan > 1 || rowSpan > 1) + { + rectArray.Add(wxRect(i, j, colSpan, rowSpan)); + } + } + } + // 0.2: find which cells are subsumed by a spanning cell + for (j = 0; j < m_rowCount; j++) + { + for (i = 0; i < m_colCount; i++) + { + wxRichTextBox* cell = GetCell(j, i); + if (rectArray.GetCount() == 0) + { + cell->Show(true); + } + else + { + int colSpan = 1, rowSpan = 1; + if (cell->GetProperties().HasProperty(wxT("colspan"))) + colSpan = cell->GetProperties().GetPropertyLong(wxT("colspan")); + if (cell->GetProperties().HasProperty(wxT("rowspan"))) + rowSpan = cell->GetProperties().GetPropertyLong(wxT("rowspan")); + if (colSpan > 1 || rowSpan > 1) + { + // Assume all spanning cells are shown + cell->Show(true); + } + else + { + bool shown = true; + for (k = 0; k < (int) rectArray.GetCount(); k++) + { + if (rectArray[k].Contains(wxPoint(i, j))) + { + shown = false; + break; + } + } + cell->Show(shown); + } + } + } + } + + // TODO: find the first spanned cell in each row that spans the most columns and doesn't + // overlap with a spanned cell starting at a previous column position. + // This means we need to keep an array of rects so we can check. However + // it does also mean that some spans simply may not be taken into account + // where there are different spans happening on different rows. In these cases, + // they will simply be as wide as their constituent columns. + + // (1) Do an initial layout for all cells to get minimum and maximum size, and get + // the absolute or percentage width of each column. + + for (j = 0; j < m_rowCount; j++) + { + // First get the overall margins so we can calculate percentage widths based on + // the available content space for all cells on the row + + int overallRowContentMargin = 0; + int visibleCellCount = 0; + + for (i = 0; i < m_colCount; i++) + { + wxRichTextBox* cell = GetCell(j, i); + if (cell->IsShown()) + { + int cellTotalLeftMargin = 0, cellTotalRightMargin = 0, cellTotalTopMargin = 0, cellTotalBottomMargin = 0; + GetTotalMargin(dc, buffer, cell->GetAttributes(), cellTotalLeftMargin, cellTotalRightMargin, cellTotalTopMargin, cellTotalBottomMargin); + + overallRowContentMargin += (cellTotalLeftMargin + cellTotalRightMargin); + visibleCellCount ++; + } + } + + // Add in inter-cell padding + overallRowContentMargin += ((visibleCellCount-1) * paddingX); + + int rowContentWidth = internalTableWidth - overallRowContentMargin; + wxSize rowTableSize(rowContentWidth, 0); + wxTextAttrDimensionConverter converter(dc, scale, rowTableSize); + + for (i = 0; i < m_colCount; i++) + { + wxRichTextBox* cell = GetCell(j, i); + if (cell->IsShown()) + { + int colSpan = 1; + if (cell->GetProperties().HasProperty(wxT("colspan"))) + colSpan = cell->GetProperties().GetPropertyLong(wxT("colspan")); + + // Lay out cell to find min/max widths + cell->Invalidate(wxRICHTEXT_ALL); + cell->Layout(dc, availableSpace, style); + + if (colSpan == 1) + { + int absoluteCellWidth = -1; + int percentageCellWidth = -1; + + // I think we need to calculate percentages from the internal table size, + // minus the padding between cells which we'll need to calculate from the + // (number of VISIBLE cells - 1)*paddingX. Then percentages that add up to 100% + // will add up to 100%. In CSS, the width specifies the cell's content rect width, + // so if we want to conform to that we'll need to add in the overall cell margins. + // However, this will make it difficult to specify percentages that add up to + // 100% and still fit within the table width. + // Let's say two cells have 50% width. They have 10 pixels of overall margin each. + // The table content rect is 500 pixels and the inter-cell padding is 20 pixels. + // If we're using internal content size for the width, we would calculate the + // the overall cell width for n cells as: + // (500 - 20*(n-1) - overallCellMargin1 - overallCellMargin2 - ...) * percentage / 100 + // + thisOverallCellMargin + // = 500 - 20 - 10 - 10) * 0.5 + 10 = 240 pixels overall cell width. + // Adding this back, we get 240 + 240 + 20 = 500 pixels. + + if (cell->GetAttributes().GetTextBoxAttr().GetWidth().IsValid()) + { + int w = converter.GetPixels(cell->GetAttributes().GetTextBoxAttr().GetWidth()); + if (cell->GetAttributes().GetTextBoxAttr().GetWidth().GetUnits() == wxTEXT_ATTR_UNITS_PERCENTAGE) + { + percentageCellWidth = w; + } + else + { + absoluteCellWidth = w; + } + // Override absolute width with minimum width if necessary + if (cell->GetMinSize().x > 0 && absoluteCellWidth !=1 && cell->GetMinSize().x > absoluteCellWidth) + absoluteCellWidth = cell->GetMinSize().x; + } + + if (absoluteCellWidth != -1) + { + if (absoluteCellWidth > absoluteColWidths[i]) + absoluteColWidths[i] = absoluteCellWidth; + } + + if (percentageCellWidth != -1) + { + if (percentageCellWidth > percentageColWidths[i]) + percentageColWidths[i] = percentageCellWidth; + } + + if (colSpan == 1 && cell->GetMinSize().x && cell->GetMinSize().x > minColWidths[i]) + minColWidths[i] = cell->GetMinSize().x; + if (colSpan == 1 && cell->GetMaxSize().x && cell->GetMaxSize().x > maxColWidths[i]) + maxColWidths[i] = cell->GetMaxSize().x; + } + } + } + } + + // (2) Allocate initial column widths from minimum widths, absolute values and proportions + // TODO: simply merge this into (1). + for (i = 0; i < m_colCount; i++) + { + if (absoluteColWidths[i] > 0) + { + colWidths[i] = absoluteColWidths[i]; + } + else if (percentageColWidths[i] > 0) + { + colWidths[i] = percentageColWidths[i]; + + // This is rubbish - we calculated the absolute widths from percentages, so + // we can't do it again here. + //colWidths[i] = (int) (double(percentageColWidths[i]) * double(tableWidth) / 100.0 + 0.5); + } + } + + // (3) Process absolute or proportional widths of spanning columns, + // now that we know what our fixed column widths are going to be. + // Spanned cells will try to adjust columns so the span will fit. + // Even existing fixed column widths can be expanded if necessary. + // Actually, currently fixed columns widths aren't adjusted; instead, + // the algorithm favours earlier rows and adjusts unspecified column widths + // the first time only. After that, we can't know whether the column has been + // specified explicitly or not. (We could make a note if necessary.) + for (j = 0; j < m_rowCount; j++) + { + // First get the overall margins so we can calculate percentage widths based on + // the available content space for all cells on the row + + int overallRowContentMargin = 0; + int visibleCellCount = 0; + + for (i = 0; i < m_colCount; i++) + { + wxRichTextBox* cell = GetCell(j, i); + if (cell->IsShown()) + { + int cellTotalLeftMargin = 0, cellTotalRightMargin = 0, cellTotalTopMargin = 0, cellTotalBottomMargin = 0; + GetTotalMargin(dc, buffer, cell->GetAttributes(), cellTotalLeftMargin, cellTotalRightMargin, cellTotalTopMargin, cellTotalBottomMargin); + + overallRowContentMargin += (cellTotalLeftMargin + cellTotalRightMargin); + visibleCellCount ++; + } + } + + // Add in inter-cell padding + overallRowContentMargin += ((visibleCellCount-1) * paddingX); + + int rowContentWidth = internalTableWidth - overallRowContentMargin; + wxSize rowTableSize(rowContentWidth, 0); + wxTextAttrDimensionConverter converter(dc, scale, rowTableSize); + + for (i = 0; i < m_colCount; i++) + { + wxRichTextBox* cell = GetCell(j, i); + if (cell->IsShown()) + { + int colSpan = 1; + if (cell->GetProperties().HasProperty(wxT("colspan"))) + colSpan = cell->GetProperties().GetPropertyLong(wxT("colspan")); + + if (colSpan > 1) + { + int spans = wxMin(colSpan, m_colCount - i); + int cellWidth = 0; + if (spans > 0) + { + if (cell->GetAttributes().GetTextBoxAttr().GetWidth().IsValid()) + { + cellWidth = converter.GetPixels(cell->GetAttributes().GetTextBoxAttr().GetWidth()); + // Override absolute width with minimum width if necessary + if (cell->GetMinSize().x > 0 && cellWidth !=1 && cell->GetMinSize().x > cellWidth) + cellWidth = cell->GetMinSize().x; + } + else + { + // Do we want to do this? It's the only chance we get to + // use the cell's min/max sizes, so we need to work out + // how we're going to balance the unspecified spanning cell + // width with the possibility more-constrained constituent cell widths. + // Say there's a tiny bitmap giving it a max width of 10 pixels. We + // don't want to constraint all the spanned columns to fit into this cell. + // OK, let's say that if any of the constituent columns don't fit, + // then we simply stop constraining the columns; instead, we'll just fit the spanning + // cells to the columns later. + cellWidth = cell->GetMinSize().x; + if (cell->GetMaxSize().x > cellWidth) + cellWidth = cell->GetMaxSize().x; + } + + // Subtract the padding between cells + int spanningWidth = cellWidth; + spanningWidth -= paddingX * (spans-1); + + if (spanningWidth > 0) + { + // Now share the spanning width between columns within that span + // TODO: take into account min widths of columns within the span + int spanningWidthLeft = spanningWidth; + int stretchColCount = 0; + for (k = i; k < (i+spans); k++) + { + if (colWidths[k] > 0) // absolute or proportional width has been specified + spanningWidthLeft -= colWidths[k]; + else + stretchColCount ++; + } + // Now divide what's left between the remaining columns + int colShare = 0; + if (stretchColCount > 0) + colShare = spanningWidthLeft / stretchColCount; + int colShareRemainder = spanningWidthLeft - (colShare * stretchColCount); + + // If fixed-width columns are currently too big, then we'll later + // stretch the spanned cell to fit. + + if (spanningWidthLeft > 0) + { + for (k = i; k < (i+spans); k++) + { + if (colWidths[k] <= 0) // absolute or proportional width has not been specified + { + int newWidth = colShare; + if (k == (i+spans-1)) + newWidth += colShareRemainder; // ensure all pixels are filled + colWidths[k] = newWidth; + } + } + } + } + } + } + } + } + } + + // (4) Next, share any remaining space out between columns that have not yet been calculated. + // TODO: take into account min widths of columns within the span + int tableWidthMinusPadding = internalTableWidth - (m_colCount-1)*paddingX; + int widthLeft = tableWidthMinusPadding; + int stretchColCount = 0; + for (i = 0; i < m_colCount; i++) + { + // TODO: we need to take into account min widths. + // Subtract min width from width left, then + // add the colShare to the min width + if (colWidths[i] > 0) // absolute or proportional width has been specified + widthLeft -= colWidths[i]; + else + { + if (minColWidths[i] > 0) + widthLeft -= minColWidths[i]; + + stretchColCount ++; + } + } + + // Now divide what's left between the remaining columns + int colShare = 0; + if (stretchColCount > 0) + colShare = widthLeft / stretchColCount; + int colShareRemainder = widthLeft - (colShare * stretchColCount); + + // Check we don't have enough space, in which case shrink all columns, overriding + // any absolute/proportional widths + // TODO: actually we would like to divide up the shrinkage according to size. + // How do we calculate the proportions that will achieve this? + // Could first choose an arbitrary value for stretching cells, and then calculate + // factors to multiply each width by. + // TODO: want to record this fact and pass to an iteration that tries e.g. min widths + if (widthLeft < 0 || (stretchToFitTableWidth && (stretchColCount == 0))) + { + colShare = tableWidthMinusPadding / m_colCount; + colShareRemainder = tableWidthMinusPadding - (colShare * m_colCount); + for (i = 0; i < m_colCount; i++) + { + colWidths[i] = 0; + minColWidths[i] = 0; + } + } + + // We have to adjust the columns if either we need to shrink the + // table to fit the parent/table width, or we explicitly set the + // table width and need to stretch out the table. + if (widthLeft < 0 || stretchToFitTableWidth) + { + for (i = 0; i < m_colCount; i++) + { + if (colWidths[i] <= 0) // absolute or proportional width has not been specified + { + if (minColWidths[i] > 0) + colWidths[i] = minColWidths[i] + colShare; + else + colWidths[i] = colShare; + if (i == (m_colCount-1)) + colWidths[i] += colShareRemainder; // ensure all pixels are filled + } + } + } + + // TODO: if spanned cells have no specified or max width, make them the + // as big as the columns they span. Do this for all spanned cells in all + // rows, of course. Size any spanned cells left over at the end - even if they + // have width > 0, make sure they're limited to the appropriate column edge. + + +/* + Sort out confusion between content width + and overall width later. For now, assume we specify overall width. + + So, now we've laid out the table to fit into the given space + and have used specified widths and minimum widths. + + Now we need to consider how we will try to take maximum width into account. + +*/ + + // (??) TODO: take max width into account + + // (6) Lay out all cells again with the current values + + int maxRight = 0; + int y = availableSpace.y; + for (j = 0; j < m_rowCount; j++) + { + int x = availableSpace.x; // TODO: take into account centering etc. + int maxCellHeight = 0; + int maxSpecifiedCellHeight = 0; + + wxArrayInt actualWidths(m_colCount); + + wxTextAttrDimensionConverter converter(dc, scale); + for (i = 0; i < m_colCount; i++) + { + wxRichTextCell* cell = GetCell(j, i); + if (cell->IsShown()) + { + wxASSERT(colWidths[i] > 0); + + // Get max specified cell height + // Don't handle percentages for height + if (cell->GetAttributes().GetTextBoxAttr().GetHeight().IsValid() && cell->GetAttributes().GetTextBoxAttr().GetHeight().GetUnits() != wxTEXT_ATTR_UNITS_PERCENTAGE) + { + int h = converter.GetPixels(cell->GetAttributes().GetTextBoxAttr().GetHeight()); + if (h > maxSpecifiedCellHeight) + maxSpecifiedCellHeight = h; + } + + if (colWidths[i] > 0) // absolute or proportional width has been specified + { + int colSpan = 1; + if (cell->GetProperties().HasProperty(wxT("colspan"))) + colSpan = cell->GetProperties().GetPropertyLong(wxT("colspan")); + + wxRect availableCellSpace; + + // TODO: take into acount spans + if (colSpan > 1) + { + // Calculate the size of this spanning cell from its constituent columns + int xx = x; + int spans = wxMin(colSpan, m_colCount - i); + for (k = i; k < spans; k++) + { + if (k != i) + xx += paddingX; + xx += colWidths[k]; + } + availableCellSpace = wxRect(x, y, xx, -1); + } + else + availableCellSpace = wxRect(x, y, colWidths[i], -1); + + // Store actual width so we can force cell to be the appropriate width on the final loop + actualWidths[i] = availableCellSpace.GetWidth(); + + // Lay out cell + cell->Invalidate(wxRICHTEXT_ALL); + cell->Layout(dc, availableCellSpace, style); + + // TODO: use GetCachedSize().x to compute 'natural' size + + x += (availableCellSpace.GetWidth() + paddingX); + if (cell->GetCachedSize().y > maxCellHeight) + maxCellHeight = cell->GetCachedSize().y; + } + } + } + + maxCellHeight = wxMax(maxCellHeight, maxSpecifiedCellHeight); + + for (i = 0; i < m_colCount; i++) + { + wxRichTextCell* cell = GetCell(j, i); + if (cell->IsShown()) + { + wxRect availableCellSpace = wxRect(cell->GetPosition(), wxSize(actualWidths[i], maxCellHeight)); + // Lay out cell with new height + cell->Invalidate(wxRICHTEXT_ALL); + cell->Layout(dc, availableCellSpace, style); + + // Make sure the cell size really is the appropriate size, + // not the calculated box size + cell->SetCachedSize(wxSize(actualWidths[i], maxCellHeight)); + + maxRight = wxMax(maxRight, cell->GetPosition().x + cell->GetCachedSize().x); + } + } + + y += maxCellHeight; + if (j < (m_rowCount-1)) + y += paddingY; + } + + // We need to add back the margins etc. + { + wxRect marginRect, borderRect, contentRect, paddingRect, outlineRect; + contentRect = wxRect(wxPoint(0, 0), wxSize(maxRight - availableSpace.x, y - availableSpace.y)); + GetBoxRects(dc, GetBuffer(), GetAttributes(), marginRect, borderRect, contentRect, paddingRect, outlineRect); + SetCachedSize(marginRect.GetSize()); + } + + // TODO: calculate max size + { + SetMaxSize(GetCachedSize()); + } + + // TODO: calculate min size + { + SetMinSize(GetCachedSize()); + } + + // TODO: currently we use either a fixed table width or the parent's size. + // We also want to be able to calculate the table width from its content, + // whether using fixed column widths or cell content min/max width. + // Probably need a boolean flag to say whether we need to stretch cells + // to fit the table width, or to simply use min/max cell widths. The + // trouble with this is that if cell widths are not specified, they + // will be tiny; we could use arbitrary defaults but this seems unsatisfactory. + // Anyway, ignoring that problem, we probably need to factor layout into a function + // that can can calculate the maximum unconstrained layout in case table size is + // not specified. Then LayoutToBestSize() can choose to use either parent size to + // constrain Layout(), or the previously-calculated max size to constraint layout. + + return true; +} + +// Finds the absolute position and row height for the given character position +bool wxRichTextTable::FindPosition(wxDC& dc, long index, wxPoint& pt, int* height, bool forceLineStart) +{ + wxRichTextCell* child = GetCell(index+1); + if (child) + { + // Find the position at the start of the child cell, since the table doesn't + // have any caret position of its own. + return child->FindPosition(dc, -1, pt, height, forceLineStart); + } + else + return false; +} + +// Get the cell at the given character position (in the range of the table). +wxRichTextCell* wxRichTextTable::GetCell(long pos) const +{ + int row = 0, col = 0; + if (GetCellRowColumnPosition(pos, row, col)) + { + return GetCell(row, col); + } + else + return NULL; +} + +// Get the row/column for a given character position +bool wxRichTextTable::GetCellRowColumnPosition(long pos, int& row, int& col) const +{ + if (m_colCount == 0 || m_rowCount == 0) + return false; + + row = (int) (pos / m_colCount); + col = pos - (row * m_colCount); + + wxASSERT(row < m_rowCount && col < m_colCount); + + if (row < m_rowCount && col < m_colCount) + return true; + else + return false; +} + +// Calculate range, taking row/cell ordering into account instead of relying +// on list ordering. +void wxRichTextTable::CalculateRange(long start, long& end) +{ + long current = start; + long lastEnd = current; + + if (IsTopLevel()) + { + current = 0; + lastEnd = 0; + } + + int i, j; + for (i = 0; i < m_rowCount; i++) + { + for (j = 0; j < m_colCount; j++) + { + wxRichTextCell* child = GetCell(i, j); + if (child) + { + long childEnd = 0; + + child->CalculateRange(current, childEnd); + + lastEnd = childEnd; + current = childEnd + 1; + } + } + } + + // A top-level object always has a range of size 1, + // because its children don't count at this level. + end = start; + m_range.SetRange(start, start); + + // An object with no children has zero length + if (m_children.GetCount() == 0) + lastEnd --; + m_ownRange.SetRange(0, lastEnd); +} + +// Gets the range size. +bool wxRichTextTable::GetRangeSize(const wxRichTextRange& range, wxSize& size, int& descent, wxDC& dc, int flags, wxPoint position, wxArrayInt* partialExtents) const +{ + return wxRichTextBox::GetRangeSize(range, size, descent, dc, flags, position, partialExtents); +} + +// Deletes content in the given range. +bool wxRichTextTable::DeleteRange(const wxRichTextRange& WXUNUSED(range)) +{ + // TODO: implement deletion of cells + return true; +} + +// Gets any text in this object for the given range. +wxString wxRichTextTable::GetTextForRange(const wxRichTextRange& range) const +{ + return wxRichTextBox::GetTextForRange(range); +} + +// Copies this object. +void wxRichTextTable::Copy(const wxRichTextTable& obj) +{ + wxRichTextBox::Copy(obj); + + ClearTable(); + + m_rowCount = obj.m_rowCount; + m_colCount = obj.m_colCount; + + m_cells.Add(wxRichTextObjectPtrArray(), m_rowCount); + + int i, j; + for (i = 0; i < m_rowCount; i++) + { + wxRichTextObjectPtrArray& colArray = m_cells[i]; + for (j = 0; j < m_colCount; j++) + { + wxRichTextCell* cell = wxDynamicCast(obj.GetCell(i, j)->Clone(), wxRichTextCell); + AppendChild(cell); + + colArray.Add(cell); + } + } +} + +void wxRichTextTable::ClearTable() +{ + m_cells.Clear(); + DeleteChildren(); +} + +bool wxRichTextTable::CreateTable(int rows, int cols) +{ + ClearTable(); + + m_rowCount = rows; + m_colCount = cols; + + m_cells.Add(wxRichTextObjectPtrArray(), rows); + + int i, j; + for (i = 0; i < rows; i++) + { + wxRichTextObjectPtrArray& colArray = m_cells[i]; + for (j = 0; j < cols; j++) + { + wxRichTextCell* cell = new wxRichTextCell; + AppendChild(cell); + cell->AddParagraph(wxEmptyString); + + colArray.Add(cell); + } + } + + return true; +} + +wxRichTextCell* wxRichTextTable::GetCell(int row, int col) const +{ + wxASSERT(row < m_rowCount); + wxASSERT(col < m_colCount); + + if (row < m_rowCount && col < m_colCount) + { + wxRichTextObjectPtrArray& colArray = m_cells[row]; + wxRichTextObject* obj = colArray[col]; + return wxDynamicCast(obj, wxRichTextCell); + } + else + return false; +} + +// Returns a selection object specifying the selections between start and end character positions. +// For example, a table would deduce what cells (of range length 1) are selected when dragging across the table. +wxRichTextSelection wxRichTextTable::GetSelection(long start, long end) const +{ + wxRichTextSelection selection; + selection.SetContainer((wxRichTextTable*) this); + + if (start > end) + { + long tmp = end; + end = start; + start = tmp; + } + + wxASSERT( start >= 0 && end < (m_colCount * m_rowCount)); + + if (end >= (m_colCount * m_rowCount)) + return selection; + + // We need to find the rectangle of cells that is described by the rectangle + // with start, end as the diagonal. Make sure we don't add cells that are + // not currenty visible because they are overlapped by spanning cells. +/* + -------------------------- + | 0 | 1 | 2 | 3 | 4 | + -------------------------- + | 5 | 6 | 7 | 8 | 9 | + -------------------------- + | 10 | 11 | 12 | 13 | 14 | + -------------------------- + | 15 | 16 | 17 | 18 | 19 | + -------------------------- + + Let's say we select 6 -> 18. + + Left and right edge cols of rectangle are 1 and 3 inclusive. Find least/greatest to find + which is left and which is right. + + Top and bottom edge rows are 1 and 3 inclusive. Again, find least/greatest to find top and bottom. + + Now go through rows from 1 to 3 and only add cells that are (a) within above column range + and (b) shown. + + +*/ + + int leftCol = start - m_colCount * int(start/m_colCount); + int rightCol = end - m_colCount * int(end/m_colCount); + + int topRow = int(start/m_colCount); + int bottomRow = int(end/m_colCount); + + if (leftCol > rightCol) + { + int tmp = rightCol; + rightCol = leftCol; + leftCol = tmp; + } + + if (topRow > bottomRow) + { + int tmp = bottomRow; + bottomRow = topRow; + topRow = tmp; + } + + int i, j; + for (i = topRow; i <= bottomRow; i++) + { + for (j = leftCol; j <= rightCol; j++) + { + wxRichTextCell* cell = GetCell(i, j); + if (cell && cell->IsShown()) + selection.Add(cell->GetRange()); + } + } + + return selection; +} + +// Sets the attributes for the cells specified by the selection. +bool wxRichTextTable::SetCellStyle(const wxRichTextSelection& selection, const wxRichTextAttr& style, int flags) +{ + if (selection.GetContainer() != this) + return false; + + wxRichTextBuffer* buffer = GetBuffer(); + bool haveControl = (buffer && buffer->GetRichTextCtrl() != NULL); + bool withUndo = haveControl && ((flags & wxRICHTEXT_SETSTYLE_WITH_UNDO) != 0); + + if (withUndo) + buffer->BeginBatchUndo(_("Set Cell Style")); + + wxRichTextObjectList::compatibility_iterator node = m_children.GetFirst(); + while (node) + { + wxRichTextCell* cell = wxDynamicCast(node->GetData(), wxRichTextCell); + if (cell && selection.WithinSelection(cell->GetRange().GetStart())) + SetStyle(cell, style, flags); + node = node->GetNext(); + } + + // Do action, or delay it until end of batch. + if (withUndo) + buffer->EndBatchUndo(); + + return true; +} + +bool wxRichTextTable::DeleteRows(int startRow, int noRows) +{ + wxASSERT((startRow + noRows) < m_rowCount); + if ((startRow + noRows) >= m_rowCount) + return false; + + int i, j; + for (i = startRow; i < (startRow+noRows); i++) + { + wxRichTextObjectPtrArray& colArray = m_cells[startRow]; + for (j = 0; j < (int) colArray.GetCount(); j++) + { + wxRichTextObject* cell = colArray[j]; + RemoveChild(cell, true); + } + + // Keep deleting at the same position, since we move all + // the others up + m_cells.RemoveAt(startRow); + } + + m_rowCount = m_rowCount - noRows; + + return true; +} + +bool wxRichTextTable::DeleteColumns(int startCol, int noCols) +{ + wxASSERT((startCol + noCols) < m_colCount); + if ((startCol + noCols) >= m_colCount) + return false; + + bool deleteRows = (noCols == m_colCount); + + int i, j; + for (i = 0; i < m_rowCount; i++) + { + wxRichTextObjectPtrArray& colArray = m_cells[deleteRows ? 0 : i]; + for (j = startCol; j < (startCol+noCols); j++) + { + wxRichTextObject* cell = colArray[j]; + RemoveChild(cell, true); + } + + if (deleteRows) + m_cells.RemoveAt(0); + } + + if (deleteRows) + m_rowCount = 0; + m_colCount = m_colCount - noCols; + + return true; +} + +bool wxRichTextTable::AddRows(int startRow, int noRows, const wxRichTextAttr& attr) +{ + wxASSERT(startRow <= m_rowCount); + if (startRow > m_rowCount) + return false; + + int i, j; + for (i = 0; i < noRows; i++) + { + int idx; + if (startRow == m_rowCount) + { + m_cells.Add(wxRichTextObjectPtrArray()); + idx = m_cells.GetCount() - 1; + } + else + { + m_cells.Insert(wxRichTextObjectPtrArray(), startRow+i); + idx = startRow+i; + } + + wxRichTextObjectPtrArray& colArray = m_cells[idx]; + for (j = 0; j < m_colCount; j++) + { + wxRichTextCell* cell = new wxRichTextCell; + cell->GetAttributes() = attr; + + AppendChild(cell); + colArray.Add(cell); + } + } + + m_rowCount = m_rowCount + noRows; + return true; +} + +bool wxRichTextTable::AddColumns(int startCol, int noCols, const wxRichTextAttr& attr) +{ + wxASSERT(startCol <= m_colCount); + if (startCol > m_colCount) + return false; + + int i, j; + for (i = 0; i < m_rowCount; i++) + { + wxRichTextObjectPtrArray& colArray = m_cells[i]; + for (j = 0; j < noCols; j++) + { + wxRichTextCell* cell = new wxRichTextCell; + cell->GetAttributes() = attr; + + AppendChild(cell); + + if (startCol == m_colCount) + colArray.Add(cell); + else + colArray.Insert(cell, startCol+j); + } + } + + m_colCount = m_colCount + noCols; + + return true; +} + +// Edit properties via a GUI +bool wxRichTextTable::EditProperties(wxWindow* parent, wxRichTextBuffer* buffer) +{ + wxRichTextObjectPropertiesDialog boxDlg(this, wxGetTopLevelParent(parent), wxID_ANY, _("Table Properties")); + boxDlg.SetAttributes(GetAttributes()); + + if (boxDlg.ShowModal() == wxID_OK) + { + boxDlg.ApplyStyle(buffer->GetRichTextCtrl(), wxRICHTEXT_SETSTYLE_WITH_UNDO|wxRICHTEXT_SETSTYLE_RESET); + return true; } else return false; @@ -6975,9 +9245,9 @@ void wxRichTextModuleInit() */ wxRichTextCommand::wxRichTextCommand(const wxString& name, wxRichTextCommandId id, wxRichTextBuffer* buffer, - wxRichTextCtrl* ctrl, bool ignoreFirstTime): wxCommand(true, name) + wxRichTextParagraphLayoutBox* container, wxRichTextCtrl* ctrl, bool ignoreFirstTime): wxCommand(true, name) { - /* wxRichTextAction* action = */ new wxRichTextAction(this, name, id, buffer, ctrl, ignoreFirstTime); + /* wxRichTextAction* action = */ new wxRichTextAction(this, name, id, buffer, container, ctrl, ignoreFirstTime); } wxRichTextCommand::wxRichTextCommand(const wxString& name): wxCommand(true, name) @@ -7027,10 +9297,13 @@ void wxRichTextCommand::ClearActions() * */ -wxRichTextAction::wxRichTextAction(wxRichTextCommand* cmd, const wxString& name, wxRichTextCommandId id, wxRichTextBuffer* buffer, - wxRichTextCtrl* ctrl, bool ignoreFirstTime) +wxRichTextAction::wxRichTextAction(wxRichTextCommand* cmd, const wxString& name, wxRichTextCommandId id, + wxRichTextBuffer* buffer, wxRichTextParagraphLayoutBox* container, + wxRichTextCtrl* ctrl, bool ignoreFirstTime) { m_buffer = buffer; + m_object = NULL; + m_containerAddress.Create(buffer, container); m_ignoreThis = ignoreFirstTime; m_cmdId = id; m_position = -1; @@ -7044,28 +9317,43 @@ wxRichTextAction::wxRichTextAction(wxRichTextCommand* cmd, const wxString& name, wxRichTextAction::~wxRichTextAction() { + if (m_object) + delete m_object; } +// Returns the container that this action refers to, using the container address and top-level buffer. +wxRichTextParagraphLayoutBox* wxRichTextAction::GetContainer() const +{ + wxRichTextParagraphLayoutBox* container = wxDynamicCast(GetContainerAddress().GetObject(m_buffer), wxRichTextParagraphLayoutBox); + return container; +} + + void wxRichTextAction::CalculateRefreshOptimizations(wxArrayInt& optimizationLineCharPositions, wxArrayInt& optimizationLineYPositions) { // Store a list of line start character and y positions so we can figure out which area // we need to refresh #if wxRICHTEXT_USE_OPTIMIZED_DRAWING + wxRichTextParagraphLayoutBox* container = GetContainer(); + wxASSERT(container != NULL); + if (!container) + return; + // NOTE: we're assuming that the buffer is laid out correctly at this point. // If we had several actions, which only invalidate and leave layout until the // paint handler is called, then this might not be true. So we may need to switch // optimisation on only when we're simply adding text and not simultaneously // deleting a selection, for example. Or, we make sure the buffer is laid out correctly // first, but of course this means we'll be doing it twice. - if (!m_buffer->GetDirty() && m_ctrl) // can only do optimisation if the buffer is already laid out correctly + if (!m_buffer->IsDirty() && m_ctrl) // can only do optimisation if the buffer is already laid out correctly { wxSize clientSize = m_ctrl->GetClientSize(); wxPoint firstVisiblePt = m_ctrl->GetFirstVisiblePoint(); int lastY = firstVisiblePt.y + clientSize.y; - wxRichTextParagraph* para = m_buffer->GetParagraphAtPosition(GetRange().GetStart()); - wxRichTextObjectList::compatibility_iterator node = m_buffer->GetChildren().Find(para); + wxRichTextParagraph* para = container->GetParagraphAtPosition(GetRange().GetStart()); + wxRichTextObjectList::compatibility_iterator node = container->GetChildren().Find(para); while (node) { wxRichTextParagraph* child = (wxRichTextParagraph*) node->GetData(); @@ -7102,6 +9390,11 @@ bool wxRichTextAction::Do() { m_buffer->Modify(true); + wxRichTextParagraphLayoutBox* container = GetContainer(); + wxASSERT(container != NULL); + if (!container) + return false; + switch (m_cmdId) { case wxRICHTEXT_INSERT: @@ -7115,11 +9408,14 @@ bool wxRichTextAction::Do() CalculateRefreshOptimizations(optimizationLineCharPositions, optimizationLineYPositions); #endif - m_buffer->InsertFragment(GetRange().GetStart(), m_newParagraphs); - m_buffer->UpdateRanges(); - m_buffer->Invalidate(wxRichTextRange(wxMax(0, GetRange().GetStart()-1), GetRange().GetEnd())); + container->InsertFragment(GetRange().GetStart(), m_newParagraphs); + container->UpdateRanges(); - long newCaretPosition = GetPosition() + m_newParagraphs.GetRange().GetLength(); + // 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(wxMax(0, GetRange().GetStart()-1), GetRange().GetEnd())); + + long newCaretPosition = GetPosition() + m_newParagraphs.GetOwnRange().GetLength(); // Character position to caret position newCaretPosition --; @@ -7135,7 +9431,7 @@ bool wxRichTextAction::Do() newCaretPosition --; } - newCaretPosition = wxMin(newCaretPosition, (m_buffer->GetRange().GetEnd()-1)); + newCaretPosition = wxMin(newCaretPosition, (container->GetOwnRange().GetEnd()-1)); UpdateAppearance(newCaretPosition, true /* send update event */, & optimizationLineCharPositions, & optimizationLineYPositions, true /* do */); @@ -7145,6 +9441,7 @@ bool wxRichTextAction::Do() cmdEvent.SetEventObject(m_ctrl ? (wxObject*) m_ctrl : (wxObject*) m_buffer); cmdEvent.SetRange(GetRange()); cmdEvent.SetPosition(GetRange().GetStart()); + cmdEvent.SetContainer(container); m_buffer->SendEvent(cmdEvent); @@ -7159,12 +9456,14 @@ bool wxRichTextAction::Do() CalculateRefreshOptimizations(optimizationLineCharPositions, optimizationLineYPositions); #endif - m_buffer->DeleteRange(GetRange()); - m_buffer->UpdateRanges(); - m_buffer->Invalidate(wxRichTextRange(GetRange().GetStart(), GetRange().GetStart())); + 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())); long caretPos = GetRange().GetStart()-1; - if (caretPos >= m_buffer->GetRange().GetEnd()) + if (caretPos >= container->GetOwnRange().GetEnd()) caretPos --; UpdateAppearance(caretPos, true /* send update event */, & optimizationLineCharPositions, & optimizationLineYPositions, true /* do */); @@ -7175,6 +9474,7 @@ bool wxRichTextAction::Do() cmdEvent.SetEventObject(m_ctrl ? (wxObject*) m_ctrl : (wxObject*) m_buffer); cmdEvent.SetRange(GetRange()); cmdEvent.SetPosition(GetRange().GetStart()); + cmdEvent.SetContainer(container); m_buffer->SendEvent(cmdEvent); @@ -7183,7 +9483,10 @@ bool wxRichTextAction::Do() case wxRICHTEXT_CHANGE_STYLE: { ApplyParagraphs(GetNewParagraphs()); - m_buffer->Invalidate(GetRange()); + + // 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()); UpdateAppearance(GetPosition()); @@ -7193,9 +9496,63 @@ bool wxRichTextAction::Do() cmdEvent.SetEventObject(m_ctrl ? (wxObject*) m_ctrl : (wxObject*) m_buffer); cmdEvent.SetRange(GetRange()); cmdEvent.SetPosition(GetRange().GetStart()); + cmdEvent.SetContainer(container); m_buffer->SendEvent(cmdEvent); + break; + } + case wxRICHTEXT_CHANGE_ATTRIBUTES: + { + wxRichTextObject* obj = m_objectAddress.GetObject(m_buffer); // container->GetChildAtPosition(GetRange().GetStart()); + if (obj) + { + wxRichTextAttr oldAttr = obj->GetAttributes(); + obj->GetAttributes() = m_attributes; + m_attributes = oldAttr; + } + + // 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()); + + UpdateAppearance(GetPosition()); + + wxRichTextEvent cmdEvent( + wxEVT_COMMAND_RICHTEXT_STYLE_CHANGED, + m_ctrl ? m_ctrl->GetId() : -1); + cmdEvent.SetEventObject(m_ctrl ? (wxObject*) m_ctrl : (wxObject*) m_buffer); + cmdEvent.SetRange(GetRange()); + cmdEvent.SetPosition(GetRange().GetStart()); + cmdEvent.SetContainer(container); + + m_buffer->SendEvent(cmdEvent); + + break; + } + case wxRICHTEXT_CHANGE_OBJECT: + { + wxRichTextObject* obj = m_objectAddress.GetObject(m_buffer); + // wxRichTextObject* obj = container->GetChildAtPosition(GetRange().GetStart()); + if (obj && m_object) + { + wxRichTextObjectList::compatibility_iterator node = container->GetChildren().Find(obj); + if (node) + { + wxRichTextObject* obj = node->GetData(); + node->SetData(m_object); + m_object = obj; + } + } + + // 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()); + + UpdateAppearance(GetPosition()); + + // TODO: send new kind of modification event + break; } default: @@ -7209,6 +9566,11 @@ bool wxRichTextAction::Undo() { m_buffer->Modify(true); + wxRichTextParagraphLayoutBox* container = GetContainer(); + wxASSERT(container != NULL); + if (!container) + return false; + switch (m_cmdId) { case wxRICHTEXT_INSERT: @@ -7220,9 +9582,11 @@ bool wxRichTextAction::Undo() CalculateRefreshOptimizations(optimizationLineCharPositions, optimizationLineYPositions); #endif - m_buffer->DeleteRange(GetRange()); - m_buffer->UpdateRanges(); - m_buffer->Invalidate(wxRichTextRange(GetRange().GetStart(), GetRange().GetStart())); + 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())); long newCaretPosition = GetPosition() - 1; @@ -7234,6 +9598,7 @@ bool wxRichTextAction::Undo() cmdEvent.SetEventObject(m_ctrl ? (wxObject*) m_ctrl : (wxObject*) m_buffer); cmdEvent.SetRange(GetRange()); cmdEvent.SetPosition(GetRange().GetStart()); + cmdEvent.SetContainer(container); m_buffer->SendEvent(cmdEvent); @@ -7248,9 +9613,11 @@ bool wxRichTextAction::Undo() CalculateRefreshOptimizations(optimizationLineCharPositions, optimizationLineYPositions); #endif - m_buffer->InsertFragment(GetRange().GetStart(), m_oldParagraphs); - m_buffer->UpdateRanges(); - m_buffer->Invalidate(GetRange()); + 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()); UpdateAppearance(GetPosition(), true, /* send update event */ & optimizationLineCharPositions, & optimizationLineYPositions, false /* undo */); @@ -7260,6 +9627,7 @@ bool wxRichTextAction::Undo() cmdEvent.SetEventObject(m_ctrl ? (wxObject*) m_ctrl : (wxObject*) m_buffer); cmdEvent.SetRange(GetRange()); cmdEvent.SetPosition(GetRange().GetStart()); + cmdEvent.SetContainer(container); m_buffer->SendEvent(cmdEvent); @@ -7268,7 +9636,9 @@ bool wxRichTextAction::Undo() case wxRICHTEXT_CHANGE_STYLE: { ApplyParagraphs(GetOldParagraphs()); - m_buffer->Invalidate(GetRange()); + // 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()); UpdateAppearance(GetPosition()); @@ -7278,11 +9648,17 @@ bool wxRichTextAction::Undo() cmdEvent.SetEventObject(m_ctrl ? (wxObject*) m_ctrl : (wxObject*) m_buffer); cmdEvent.SetRange(GetRange()); cmdEvent.SetPosition(GetRange().GetStart()); + cmdEvent.SetContainer(container); m_buffer->SendEvent(cmdEvent); break; } + case wxRICHTEXT_CHANGE_ATTRIBUTES: + case wxRICHTEXT_CHANGE_OBJECT: + { + return Do(); + } default: break; } @@ -7291,20 +9667,144 @@ bool wxRichTextAction::Undo() } /// Update the control appearance -void wxRichTextAction::UpdateAppearance(long caretPosition, bool sendUpdateEvent, wxArrayInt* WXUNUSED(optimizationLineCharPositions), wxArrayInt* WXUNUSED(optimizationLineYPositions), bool WXUNUSED(isDoCmd)) +void wxRichTextAction::UpdateAppearance(long caretPosition, bool sendUpdateEvent, wxArrayInt* optimizationLineCharPositions, wxArrayInt* optimizationLineYPositions, bool isDoCmd) { + wxRichTextParagraphLayoutBox* container = GetContainer(); + wxASSERT(container != NULL); + if (!container) + return; + if (m_ctrl) { + m_ctrl->SetFocusObject(container); m_ctrl->SetCaretPosition(caretPosition); + if (!m_ctrl->IsFrozen()) { - m_ctrl->LayoutContent(); - // TODO Refresh the whole client area now - m_ctrl->Refresh(false); + wxRect containerRect = container->GetRect(); -#if wxRICHTEXT_USE_OWN_CARET - m_ctrl->PositionCaret(); + m_ctrl->LayoutContent(); + + // Refresh everything if there were floating objects or the container changed size + // (we can't yet optimize in these cases, since more complex interaction with other content occurs) + if (container->GetFloatingObjectCount() > 0 || (container->GetParent() && containerRect != container->GetRect())) + { + m_ctrl->Refresh(false); + } + else + +#if wxRICHTEXT_USE_OPTIMIZED_DRAWING + // Find refresh rectangle if we are in a position to optimise refresh + if ((m_cmdId == wxRICHTEXT_INSERT || m_cmdId == wxRICHTEXT_DELETE) && optimizationLineCharPositions) + { + size_t i; + + wxSize clientSize = m_ctrl->GetClientSize(); + wxPoint firstVisiblePt = m_ctrl->GetFirstVisiblePoint(); + + // Start/end positions + int firstY = 0; + int lastY = firstVisiblePt.y + clientSize.y; + + bool foundEnd = false; + + // position offset - how many characters were inserted + int positionOffset = GetRange().GetLength(); + + // Determine whether this is Do or Undo, and adjust positionOffset accordingly + if ((m_cmdId == wxRICHTEXT_DELETE && isDoCmd) || (m_cmdId == wxRICHTEXT_INSERT && !isDoCmd)) + positionOffset = - positionOffset; + + // find the first line which is being drawn at the same position as it was + // before. Since we're talking about a simple insertion, we can assume + // that the rest of the window does not need to be redrawn. + + wxRichTextParagraph* para = container->GetParagraphAtPosition(GetPosition()); + // Since we support floating layout, we should redraw the whole para instead of just + // the first line touching the invalid range. + if (para) + { + firstY = para->GetPosition().y; + } + + wxRichTextObjectList::compatibility_iterator node = container->GetChildren().Find(para); + while (node) + { + wxRichTextParagraph* child = (wxRichTextParagraph*) node->GetData(); + wxRichTextLineList::compatibility_iterator node2 = child->GetLines().GetFirst(); + while (node2) + { + wxRichTextLine* line = node2->GetData(); + wxPoint pt = line->GetAbsolutePosition(); + wxRichTextRange range = line->GetAbsoluteRange(); + + // we want to find the first line that is in the same position + // as before. This will mean we're at the end of the changed text. + + if (pt.y > lastY) // going past the end of the window, no more info + { + node2 = wxRichTextLineList::compatibility_iterator(); + node = wxRichTextObjectList::compatibility_iterator(); + } + // Detect last line in the buffer + else if (!node2->GetNext() && para->GetRange().Contains(container->GetOwnRange().GetEnd())) + { + // If deleting text, make sure we refresh below as well as above + if (positionOffset >= 0) + { + foundEnd = true; + lastY = pt.y + line->GetSize().y; + } + + node2 = wxRichTextLineList::compatibility_iterator(); + node = wxRichTextObjectList::compatibility_iterator(); + + break; + } + else + { + // search for this line being at the same position as before + for (i = 0; i < optimizationLineCharPositions->GetCount(); i++) + { + if (((*optimizationLineCharPositions)[i] + positionOffset == range.GetStart()) && + ((*optimizationLineYPositions)[i] == pt.y)) + { + // Stop, we're now the same as we were + foundEnd = true; + + lastY = pt.y; + + node2 = wxRichTextLineList::compatibility_iterator(); + node = wxRichTextObjectList::compatibility_iterator(); + + break; + } + } + } + + if (node2) + node2 = node2->GetNext(); + } + + if (node) + node = node->GetNext(); + } + + firstY = wxMax(firstVisiblePt.y, firstY); + if (!foundEnd) + lastY = firstVisiblePt.y + clientSize.y; + + // Convert to device coordinates + wxRect rect(m_ctrl->GetPhysicalPoint(wxPoint(firstVisiblePt.x, firstY)), wxSize(clientSize.x, lastY - firstY)); + m_ctrl->RefreshRect(rect); + } + else #endif + m_ctrl->Refresh(false); + + m_ctrl->PositionCaret(); + m_ctrl->SetDefaultStyleToCursorStyle(); + if (sendUpdateEvent) wxTextCtrl::SendTextUpdatedEvent(m_ctrl); } @@ -7314,6 +9814,11 @@ void wxRichTextAction::UpdateAppearance(long caretPosition, bool sendUpdateEvent /// Replace the buffer paragraphs with the new ones. void wxRichTextAction::ApplyParagraphs(const wxRichTextParagraphLayoutBox& fragment) { + wxRichTextParagraphLayoutBox* container = GetContainer(); + wxASSERT(container != NULL); + if (!container) + return; + wxRichTextObjectList::compatibility_iterator node = fragment.GetChildren().GetFirst(); while (node) { @@ -7324,14 +9829,14 @@ void wxRichTextAction::ApplyParagraphs(const wxRichTextParagraphLayoutBox& fragm // delete its node data, and setting a copy as the new node data. // TODO: make more efficient by simply swapping old and new paragraph objects. - wxRichTextParagraph* existingPara = m_buffer->GetParagraphAtPosition(para->GetRange().GetStart()); + wxRichTextParagraph* existingPara = container->GetParagraphAtPosition(para->GetRange().GetStart()); if (existingPara) { - wxRichTextObjectList::compatibility_iterator bufferParaNode = m_buffer->GetChildren().Find(existingPara); + wxRichTextObjectList::compatibility_iterator bufferParaNode = container->GetChildren().Find(existingPara); if (bufferParaNode) { wxRichTextParagraph* newPara = new wxRichTextParagraph(*para); - newPara->SetParent(m_buffer); + newPara->SetParent(container); bufferParaNode->SetData(newPara); @@ -7349,6 +9854,8 @@ void wxRichTextAction::ApplyParagraphs(const wxRichTextParagraphLayoutBox& fragm * This stores beginning and end positions for a range of data. */ +WX_DEFINE_OBJARRAY(wxRichTextRangeArray); + /// Limit this range to be within 'range' bool wxRichTextRange::LimitTo(const wxRichTextRange& range) { @@ -7400,14 +9907,14 @@ bool wxRichTextImage::LoadImageCache(wxDC& dc, bool resetCache) int width = image.GetWidth(); int height = image.GetHeight(); - if (GetAttributes().GetTextBoxAttr().GetWidth().IsPresent() && GetAttributes().GetTextBoxAttr().GetWidth().GetValue() > 0) + if (GetAttributes().GetTextBoxAttr().GetWidth().IsValid() && GetAttributes().GetTextBoxAttr().GetWidth().GetValue() > 0) { if (GetAttributes().GetTextBoxAttr().GetWidth().GetUnits() == wxTEXT_ATTR_UNITS_TENTHS_MM) width = ConvertTenthsMMToPixels(dc, GetAttributes().GetTextBoxAttr().GetWidth().GetValue()); else width = GetAttributes().GetTextBoxAttr().GetWidth().GetValue(); } - if (GetAttributes().GetTextBoxAttr().GetHeight().IsPresent() && GetAttributes().GetTextBoxAttr().GetHeight().GetValue() > 0) + if (GetAttributes().GetTextBoxAttr().GetHeight().IsValid() && GetAttributes().GetTextBoxAttr().GetHeight().GetValue() > 0) { if (GetAttributes().GetTextBoxAttr().GetHeight().GetUnits() == wxTEXT_ATTR_UNITS_TENTHS_MM) height = ConvertTenthsMMToPixels(dc, GetAttributes().GetTextBoxAttr().GetHeight().GetValue()); @@ -7439,23 +9946,37 @@ bool wxRichTextImage::LoadImageCache(wxDC& dc, bool resetCache) } /// Draw the item -bool wxRichTextImage::Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextRange& selectionRange, const wxRect& rect, int WXUNUSED(descent), int WXUNUSED(style)) +bool wxRichTextImage::Draw(wxDC& dc, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int WXUNUSED(descent), int WXUNUSED(style)) { + if (!IsShown()) + return true; + // Don't need cached size AFAIK // wxSize size = GetCachedSize(); if (!LoadImageCache(dc)) return false; + DrawBoxAttributes(dc, GetBuffer(), GetAttributes(), wxRect(GetPosition(), GetCachedSize())); + +#if 0 int y = rect.y + (rect.height - m_imageCache.GetHeight()); dc.DrawBitmap(m_imageCache, rect.x, y, true); +#endif - if (selectionRange.Contains(range.GetStart())) + wxSize imageSize(m_imageCache.GetWidth(), m_imageCache.GetHeight()); + wxRect marginRect, borderRect, contentRect, paddingRect, outlineRect; + marginRect = rect; // outer rectangle, will calculate contentRect + GetBoxRects(dc, GetBuffer(), GetAttributes(), marginRect, borderRect, contentRect, paddingRect, outlineRect); + + dc.DrawBitmap(m_imageCache, contentRect.x, contentRect.y, true); + + if (selection.WithinSelection(range.GetStart(), this)) { wxCheckSetBrush(dc, *wxBLACK_BRUSH); wxCheckSetPen(dc, *wxBLACK_PEN); dc.SetLogicalFunction(wxINVERT); - dc.DrawRectangle(rect); + dc.DrawRectangle(contentRect); dc.SetLogicalFunction(wxCOPY); } @@ -7468,7 +9989,16 @@ bool wxRichTextImage::Layout(wxDC& dc, const wxRect& rect, int WXUNUSED(style)) if (!LoadImageCache(dc)) return false; - SetCachedSize(wxSize(m_imageCache.GetWidth(), m_imageCache.GetHeight())); + wxSize imageSize(m_imageCache.GetWidth(), m_imageCache.GetHeight()); + wxRect marginRect, borderRect, contentRect, paddingRect, outlineRect; + contentRect = wxRect(wxPoint(0,0), imageSize); + GetBoxRects(dc, GetBuffer(), GetAttributes(), marginRect, borderRect, contentRect, paddingRect, outlineRect); + + wxSize overallSize = marginRect.GetSize(); + + SetCachedSize(overallSize); + SetMaxSize(overallSize); + SetMinSize(overallSize); SetPosition(rect.GetPosition()); return true; @@ -7489,18 +10019,35 @@ bool wxRichTextImage::GetRangeSize(const wxRichTextRange& range, wxSize& size, i return false; } - int width = m_imageCache.GetWidth(); - int height = m_imageCache.GetHeight(); + wxSize imageSize(m_imageCache.GetWidth(), m_imageCache.GetHeight()); + wxRect marginRect, borderRect, contentRect, paddingRect, outlineRect; + contentRect = wxRect(wxPoint(0,0), imageSize); + GetBoxRects(dc, GetBuffer(), GetAttributes(), marginRect, borderRect, contentRect, paddingRect, outlineRect); + + wxSize overallSize = marginRect.GetSize(); if (partialExtents) - partialExtents->Add(width); + partialExtents->Add(overallSize.x); - size.x = width; - size.y = height; + size = overallSize; return true; } +// Get the 'natural' size for an object. For an image, it would be the +// image size. +wxTextAttrSize wxRichTextImage::GetNaturalSize() const +{ + wxTextAttrSize size; + if (GetImageCache().IsOk()) + { + size.SetWidth(GetImageCache().GetWidth(), wxTEXT_ATTR_UNITS_PIXELS); + size.SetHeight(GetImageCache().GetHeight(), wxTEXT_ATTR_UNITS_PIXELS); + } + return size; +} + + /// Copy void wxRichTextImage::Copy(const wxRichTextImage& obj) { @@ -7512,12 +10059,14 @@ void wxRichTextImage::Copy(const wxRichTextImage& obj) /// Edit properties via a GUI bool wxRichTextImage::EditProperties(wxWindow* parent, wxRichTextBuffer* buffer) { - wxRichTextImageDialog imageDlg(wxGetTopLevelParent(parent)); - imageDlg.SetImageObject(this, buffer); + wxRichTextObjectPropertiesDialog imageDlg(this, wxGetTopLevelParent(parent), wxID_ANY, _("Picture Properties")); + imageDlg.SetAttributes(GetAttributes()); if (imageDlg.ShowModal() == wxID_OK) { - imageDlg.ApplyImageAttr(); + // By passing wxRICHTEXT_SETSTYLE_RESET, indeterminate attributes set by the user will be set as + // indeterminate in the object. + imageDlg.ApplyStyle(buffer->GetRichTextCtrl(), wxRICHTEXT_SETSTYLE_WITH_UNDO|wxRICHTEXT_SETSTYLE_RESET); return true; } else @@ -8222,16 +10771,16 @@ void wxRichTextFontTable::Clear() void wxTextBoxAttr::Reset() { m_flags = 0; - m_floatMode = 0; - m_clearMode = 0; - m_collapseMode = 0; + m_floatMode = wxTEXT_BOX_ATTR_FLOAT_NONE; + m_clearMode = wxTEXT_BOX_ATTR_CLEAR_NONE; + m_collapseMode = wxTEXT_BOX_ATTR_COLLAPSE_NONE; + m_verticalAlignment = wxTEXT_BOX_ATTR_VERTICAL_ALIGNMENT_NONE; m_margins.Reset(); m_padding.Reset(); m_position.Reset(); - m_width.Reset(); - m_height.Reset(); + m_size.Reset(); m_border.Reset(); m_outline.Reset(); @@ -8245,13 +10794,13 @@ bool wxTextBoxAttr::operator== (const wxTextBoxAttr& attr) const m_floatMode == attr.m_floatMode && m_clearMode == attr.m_clearMode && m_collapseMode == attr.m_collapseMode && + m_verticalAlignment == attr.m_verticalAlignment && m_margins == attr.m_margins && m_padding == attr.m_padding && m_position == attr.m_position && - m_width == attr.m_width && - m_height == attr.m_height && + m_size == attr.m_size && m_border == attr.m_border && m_outline == attr.m_outline @@ -8270,6 +10819,9 @@ bool wxTextBoxAttr::EqPartial(const wxTextBoxAttr& attr) const if (attr.HasCollapseBorders() && HasCollapseBorders() && (attr.GetCollapseBorders() != GetCollapseBorders())) return false; + if (attr.HasVerticalAlignment() && HasVerticalAlignment() && (attr.GetVerticalAlignment() != GetVerticalAlignment())) + return false; + // Position if (!m_position.EqPartial(attr.m_position)) @@ -8318,15 +10870,20 @@ bool wxTextBoxAttr::Apply(const wxTextBoxAttr& attr, const wxTextBoxAttr* compar if (attr.HasCollapseBorders()) { if (!(compareWith && compareWith->HasCollapseBorders() && compareWith->GetCollapseBorders() == attr.GetCollapseBorders())) - SetCollapseBorders(true); + SetCollapseBorders(attr.GetCollapseBorders()); + } + + if (attr.HasVerticalAlignment()) + { + if (!(compareWith && compareWith->HasVerticalAlignment() && compareWith->GetVerticalAlignment() == attr.GetVerticalAlignment())) + SetVerticalAlignment(attr.GetVerticalAlignment()); } m_margins.Apply(attr.m_margins, compareWith ? (& attr.m_margins) : (const wxTextAttrDimensions*) NULL); m_padding.Apply(attr.m_padding, compareWith ? (& attr.m_padding) : (const wxTextAttrDimensions*) NULL); m_position.Apply(attr.m_position, compareWith ? (& attr.m_position) : (const wxTextAttrDimensions*) NULL); - m_width.Apply(attr.m_width, compareWith ? (& attr.m_width) : (const wxTextAttrDimension*) NULL); - m_height.Apply(attr.m_height, compareWith ? (& attr.m_height) : (const wxTextAttrDimension*) NULL); + m_size.Apply(attr.m_size, compareWith ? (& attr.m_size) : (const wxTextAttrSize*) NULL); m_border.Apply(attr.m_border, compareWith ? (& attr.m_border) : (const wxTextAttrBorders*) NULL); m_outline.Apply(attr.m_outline, compareWith ? (& attr.m_outline) : (const wxTextAttrBorders*) NULL); @@ -8346,14 +10903,14 @@ bool wxTextBoxAttr::RemoveStyle(const wxTextBoxAttr& attr) if (attr.HasCollapseBorders()) RemoveFlag(wxTEXT_BOX_ATTR_COLLAPSE_BORDERS); + if (attr.HasVerticalAlignment()) + RemoveFlag(wxTEXT_BOX_ATTR_VERTICAL_ALIGNMENT); + m_margins.RemoveStyle(attr.m_margins); m_padding.RemoveStyle(attr.m_padding); m_position.RemoveStyle(attr.m_position); - if (attr.m_width.IsPresent()) - m_width.Reset(); - if (attr.m_height.IsPresent()) - m_height.Reset(); + m_size.RemoveStyle(attr.m_size); m_border.RemoveStyle(attr.m_border); m_outline.RemoveStyle(attr.m_outline); @@ -8422,12 +10979,30 @@ void wxTextBoxAttr::CollectCommonAttributes(const wxTextBoxAttr& attr, wxTextBox else absentAttr.AddFlag(wxTEXT_BOX_ATTR_COLLAPSE_BORDERS); + if (attr.HasVerticalAlignment()) + { + if (!clashingAttr.HasVerticalAlignment() && !absentAttr.HasVerticalAlignment()) + { + if (HasVerticalAlignment()) + { + if (GetVerticalAlignment() != attr.GetVerticalAlignment()) + { + clashingAttr.AddFlag(wxTEXT_BOX_ATTR_VERTICAL_ALIGNMENT); + RemoveFlag(wxTEXT_BOX_ATTR_VERTICAL_ALIGNMENT); + } + } + else + SetVerticalAlignment(attr.GetVerticalAlignment()); + } + } + else + absentAttr.AddFlag(wxTEXT_BOX_ATTR_VERTICAL_ALIGNMENT); + m_margins.CollectCommonAttributes(attr.m_margins, clashingAttr.m_margins, absentAttr.m_margins); m_padding.CollectCommonAttributes(attr.m_padding, clashingAttr.m_padding, absentAttr.m_padding); m_position.CollectCommonAttributes(attr.m_position, clashingAttr.m_position, absentAttr.m_position); - m_width.CollectCommonAttributes(attr.m_width, clashingAttr.m_width, absentAttr.m_width); - m_height.CollectCommonAttributes(attr.m_height, clashingAttr.m_height, absentAttr.m_height); + m_size.CollectCommonAttributes(attr.m_size, clashingAttr.m_size, absentAttr.m_size); m_border.CollectCommonAttributes(attr.m_border, clashingAttr.m_border, absentAttr.m_border); m_outline.CollectCommonAttributes(attr.m_outline, clashingAttr.m_outline, absentAttr.m_outline); @@ -8656,7 +11231,7 @@ void wxTextAttrBorders::SetWidth(const wxTextAttrDimension& width) // Partial equality test bool wxTextAttrDimension::EqPartial(const wxTextAttrDimension& dim) const { - if (dim.IsPresent() && IsPresent() && !((*this) == dim)) + if (dim.IsValid() && IsValid() && !((*this) == dim)) return false; else return true; @@ -8664,7 +11239,7 @@ bool wxTextAttrDimension::EqPartial(const wxTextAttrDimension& dim) const bool wxTextAttrDimension::Apply(const wxTextAttrDimension& dim, const wxTextAttrDimension* compareWith) { - if (dim.IsPresent()) + if (dim.IsValid()) { if (!(compareWith && dim == (*compareWith))) (*this) = dim; @@ -8677,16 +11252,16 @@ bool wxTextAttrDimension::Apply(const wxTextAttrDimension& dim, const wxTextAttr // which attributes are absent in some objects and which clash in some objects. void wxTextAttrDimension::CollectCommonAttributes(const wxTextAttrDimension& attr, wxTextAttrDimension& clashingAttr, wxTextAttrDimension& absentAttr) { - if (attr.IsPresent()) + if (attr.IsValid()) { - if (!clashingAttr.IsPresent() && !absentAttr.IsPresent()) + if (!clashingAttr.IsValid() && !absentAttr.IsValid()) { - if (IsPresent()) + if (IsValid()) { if (!((*this) == attr)) { - clashingAttr.SetPresent(true); - SetPresent(false); + clashingAttr.SetValid(true); + SetValid(false); } } else @@ -8694,7 +11269,7 @@ void wxTextAttrDimension::CollectCommonAttributes(const wxTextAttrDimension& att } } else - absentAttr.SetPresent(true); + absentAttr.SetValid(true); } wxTextAttrDimensionConverter::wxTextAttrDimensionConverter(wxDC& dc, double scale, const wxSize& parentSize) @@ -8783,13 +11358,13 @@ bool wxTextAttrDimensions::Apply(const wxTextAttrDimensions& dims, const wxTextA // Remove specified attributes from this object bool wxTextAttrDimensions::RemoveStyle(const wxTextAttrDimensions& attr) { - if (attr.m_left.IsPresent()) + if (attr.m_left.IsValid()) m_left.Reset(); - if (attr.m_right.IsPresent()) + if (attr.m_right.IsValid()) m_right.Reset(); - if (attr.m_top.IsPresent()) + if (attr.m_top.IsValid()) m_top.Reset(); - if (attr.m_bottom.IsPresent()) + if (attr.m_bottom.IsValid()) m_bottom.Reset(); return true; @@ -8805,6 +11380,46 @@ void wxTextAttrDimensions::CollectCommonAttributes(const wxTextAttrDimensions& a m_bottom.CollectCommonAttributes(attr.m_bottom, clashingAttr.m_bottom, absentAttr.m_bottom); } +// Partial equality test +bool wxTextAttrSize::EqPartial(const wxTextAttrSize& size) const +{ + if (!m_width.EqPartial(size.m_width)) + return false; + + if (!m_height.EqPartial(size.m_height)) + return false; + + return true; +} + +// Apply border to 'this', but not if the same as compareWith +bool wxTextAttrSize::Apply(const wxTextAttrSize& size, const wxTextAttrSize* compareWith) +{ + m_width.Apply(size.m_width, compareWith ? (& compareWith->m_width) : (const wxTextAttrDimension*) NULL); + m_height.Apply(size.m_height, compareWith ? (& compareWith->m_height): (const wxTextAttrDimension*) NULL); + + return true; +} + +// Remove specified attributes from this object +bool wxTextAttrSize::RemoveStyle(const wxTextAttrSize& attr) +{ + if (attr.m_width.IsValid()) + m_width.Reset(); + if (attr.m_height.IsValid()) + m_height.Reset(); + + return true; +} + +// Collects the attributes that are common to a range of content, building up a note of +// which attributes are absent in some objects and which clash in some objects. +void wxTextAttrSize::CollectCommonAttributes(const wxTextAttrSize& attr, wxTextAttrSize& clashingAttr, wxTextAttrSize& absentAttr) +{ + m_width.CollectCommonAttributes(attr.m_width, clashingAttr.m_width, absentAttr.m_width); + m_height.CollectCommonAttributes(attr.m_height, clashingAttr.m_height, absentAttr.m_height); +} + // Collects the attributes that are common to a range of content, building up a note of // which attributes are absent in some objects and which clash in some objects. void wxTextAttrCollectCommonAttributes(wxTextAttr& currentStyle, const wxTextAttr& attr, wxTextAttr& clashingAttr, wxTextAttr& absentAttr) @@ -9361,5 +11976,152 @@ void wxRichTextProperties::SetProperty(const wxString& name, bool value) SetProperty(name, wxVariant(value, name)); } +wxRichTextObject* wxRichTextObjectAddress::GetObject(wxRichTextParagraphLayoutBox* topLevelContainer) const +{ + if (m_address.GetCount() == 0) + return topLevelContainer; + + wxRichTextCompositeObject* p = topLevelContainer; + size_t i = 0; + while (p && i < m_address.GetCount()) + { + int pos = m_address[i]; + wxASSERT(pos >= 0 && pos < (int) p->GetChildren().GetCount()); + if (pos < 0 || pos >= (int) p->GetChildren().GetCount()) + return NULL; + + wxRichTextObject* p1 = p->GetChild(pos); + if (i == (m_address.GetCount()-1)) + return p1; + + p = wxDynamicCast(p1, wxRichTextCompositeObject); + i ++; + } + return NULL; +} + +bool wxRichTextObjectAddress::Create(wxRichTextParagraphLayoutBox* topLevelContainer, wxRichTextObject* obj) +{ + m_address.Clear(); + + if (topLevelContainer == obj) + return true; + + wxRichTextObject* o = obj; + while (o) + { + wxRichTextCompositeObject* p = wxDynamicCast(o->GetParent(), wxRichTextCompositeObject); + if (!p) + return false; + + int pos = p->GetChildren().IndexOf(o); + if (pos == -1) + return false; + + m_address.Insert(pos, 0); + + if (p == topLevelContainer) + return true; + + o = p; + } + return false; +} + +// Equality test +bool wxRichTextSelection::operator==(const wxRichTextSelection& sel) const +{ + if (m_container != sel.m_container) + return false; + if (m_ranges.GetCount() != sel.m_ranges.GetCount()) + return false; + size_t i; + for (i = 0; i < m_ranges.GetCount(); i++) + if (!(m_ranges[i] == sel.m_ranges[i])) + return false; + return true; +} + +// Get the selections appropriate to the specified object, if any; returns wxRICHTEXT_NO_SELECTION if none +// or none at the level of the object's container. +wxRichTextRangeArray wxRichTextSelection::GetSelectionForObject(wxRichTextObject* obj) const +{ + if (IsValid()) + { + wxRichTextParagraphLayoutBox* container = obj->GetParentContainer(); + + if (container == m_container) + return m_ranges; + + container = obj->GetContainer(); + while (container) + { + if (container->GetParent()) + { + // If we found that our object's container is within the range of + // a selection higher up, then assume the whole original object + // is also selected. + wxRichTextParagraphLayoutBox* parentContainer = container->GetParentContainer(); + if (parentContainer == m_container) + { + if (WithinSelection(container->GetRange().GetStart(), m_ranges)) + { + wxRichTextRangeArray ranges; + ranges.Add(obj->GetRange()); + return ranges; + } + } + + container = parentContainer; + } + else + { + container = NULL; + break; + } + } + } + return wxRichTextRangeArray(); +} + +// Is the given position within the selection? +bool wxRichTextSelection::WithinSelection(long pos, wxRichTextObject* obj) const +{ + if (!IsValid()) + return false; + else + { + wxRichTextRangeArray selectionRanges = GetSelectionForObject(obj); + return WithinSelection(pos, selectionRanges); + } +} + +// Is the given position within the selection range? +bool wxRichTextSelection::WithinSelection(long pos, const wxRichTextRangeArray& ranges) +{ + size_t i; + for (i = 0; i < ranges.GetCount(); i++) + { + const wxRichTextRange& range = ranges[i]; + if (pos >= range.GetStart() && pos <= range.GetEnd()) + return true; + } + return false; +} + +// Is the given range completely within the selection range? +bool wxRichTextSelection::WithinSelection(const wxRichTextRange& range, const wxRichTextRangeArray& ranges) +{ + size_t i; + for (i = 0; i < ranges.GetCount(); i++) + { + const wxRichTextRange& eachRange = ranges[i]; + if (range.IsWithin(eachRange)) + return true; + } + return false; +} + + #endif // wxUSE_RICHTEXT diff --git a/src/richtext/richtextbulletspage.cpp b/src/richtext/richtextbulletspage.cpp index c62e3c3b53..9e0f30ea61 100644 --- a/src/richtext/richtextbulletspage.cpp +++ b/src/richtext/richtextbulletspage.cpp @@ -20,13 +20,13 @@ * wxRichTextBulletsPage type definition */ -IMPLEMENT_DYNAMIC_CLASS( wxRichTextBulletsPage, wxPanel ) +IMPLEMENT_DYNAMIC_CLASS( wxRichTextBulletsPage, wxRichTextDialogPage ) /*! * wxRichTextBulletsPage event table definition */ -BEGIN_EVENT_TABLE( wxRichTextBulletsPage, wxPanel ) +BEGIN_EVENT_TABLE( wxRichTextBulletsPage, wxRichTextDialogPage ) ////@begin wxRichTextBulletsPage event table entries EVT_LISTBOX( ID_RICHTEXTBULLETSPAGE_STYLELISTBOX, wxRichTextBulletsPage::OnStylelistboxSelected ) @@ -73,6 +73,8 @@ BEGIN_EVENT_TABLE( wxRichTextBulletsPage, wxPanel ) END_EVENT_TABLE() +IMPLEMENT_HELP_PROVISION(wxRichTextBulletsPage) + /*! * wxRichTextBulletsPage constructors */ @@ -120,7 +122,7 @@ void wxRichTextBulletsPage::Init() bool wxRichTextBulletsPage::Create( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) { ////@begin wxRichTextBulletsPage creation - wxPanel::Create( parent, id, pos, size, style ); + wxRichTextDialogPage::Create( parent, id, pos, size, style ); CreateControls(); if (GetSizer()) @@ -139,10 +141,10 @@ bool wxRichTextBulletsPage::Create( wxWindow* parent, wxWindowID id, const wxPoi void wxRichTextBulletsPage::CreateControls() { ////@begin wxRichTextBulletsPage content construction - wxRichTextBulletsPage* itemPanel1 = this; + wxRichTextBulletsPage* itemRichTextDialogPage1 = this; wxBoxSizer* itemBoxSizer2 = new wxBoxSizer(wxVERTICAL); - itemPanel1->SetSizer(itemBoxSizer2); + itemRichTextDialogPage1->SetSizer(itemBoxSizer2); wxBoxSizer* itemBoxSizer3 = new wxBoxSizer(wxVERTICAL); itemBoxSizer2->Add(itemBoxSizer3, 1, wxGROW|wxALL, 5); @@ -153,11 +155,11 @@ void wxRichTextBulletsPage::CreateControls() wxBoxSizer* itemBoxSizer5 = new wxBoxSizer(wxVERTICAL); itemBoxSizer4->Add(itemBoxSizer5, 0, wxGROW, 5); - wxStaticText* itemStaticText6 = new wxStaticText( itemPanel1, wxID_STATIC, _("&Bullet style:"), wxDefaultPosition, wxDefaultSize, 0 ); + wxStaticText* itemStaticText6 = new wxStaticText( itemRichTextDialogPage1, wxID_STATIC, _("&Bullet style:"), wxDefaultPosition, wxDefaultSize, 0 ); itemBoxSizer5->Add(itemStaticText6, 0, wxALIGN_LEFT|wxLEFT|wxRIGHT|wxTOP, 5); wxArrayString m_styleListBoxStrings; - m_styleListBox = new wxListBox( itemPanel1, ID_RICHTEXTBULLETSPAGE_STYLELISTBOX, wxDefaultPosition, wxSize(-1, 90), m_styleListBoxStrings, wxLB_SINGLE ); + m_styleListBox = new wxListBox( itemRichTextDialogPage1, ID_RICHTEXTBULLETSPAGE_STYLELISTBOX, wxDefaultPosition, wxSize(-1, 90), m_styleListBoxStrings, wxLB_SINGLE ); m_styleListBox->SetHelpText(_("The available bullet styles.")); if (wxRichTextBulletsPage::ShowToolTips()) m_styleListBox->SetToolTip(_("The available bullet styles.")); @@ -166,21 +168,21 @@ void wxRichTextBulletsPage::CreateControls() wxBoxSizer* itemBoxSizer8 = new wxBoxSizer(wxHORIZONTAL); itemBoxSizer5->Add(itemBoxSizer8, 0, wxGROW, 5); - m_periodCtrl = new wxCheckBox( itemPanel1, ID_RICHTEXTBULLETSPAGE_PERIODCTRL, _("Peri&od"), wxDefaultPosition, wxDefaultSize, 0 ); + m_periodCtrl = new wxCheckBox( itemRichTextDialogPage1, ID_RICHTEXTBULLETSPAGE_PERIODCTRL, _("Peri&od"), wxDefaultPosition, wxDefaultSize, 0 ); m_periodCtrl->SetValue(false); m_periodCtrl->SetHelpText(_("Check to add a period after the bullet.")); if (wxRichTextBulletsPage::ShowToolTips()) m_periodCtrl->SetToolTip(_("Check to add a period after the bullet.")); itemBoxSizer8->Add(m_periodCtrl, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); - m_parenthesesCtrl = new wxCheckBox( itemPanel1, ID_RICHTEXTBULLETSPAGE_PARENTHESESCTRL, _("(*)"), wxDefaultPosition, wxDefaultSize, 0 ); + m_parenthesesCtrl = new wxCheckBox( itemRichTextDialogPage1, ID_RICHTEXTBULLETSPAGE_PARENTHESESCTRL, _("(*)"), wxDefaultPosition, wxDefaultSize, 0 ); m_parenthesesCtrl->SetValue(false); m_parenthesesCtrl->SetHelpText(_("Check to enclose the bullet in parentheses.")); if (wxRichTextBulletsPage::ShowToolTips()) m_parenthesesCtrl->SetToolTip(_("Check to enclose the bullet in parentheses.")); itemBoxSizer8->Add(m_parenthesesCtrl, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); - m_rightParenthesisCtrl = new wxCheckBox( itemPanel1, ID_RICHTEXTBULLETSPAGE_RIGHTPARENTHESISCTRL, _("*)"), wxDefaultPosition, wxDefaultSize, 0 ); + m_rightParenthesisCtrl = new wxCheckBox( itemRichTextDialogPage1, ID_RICHTEXTBULLETSPAGE_RIGHTPARENTHESISCTRL, _("*)"), wxDefaultPosition, wxDefaultSize, 0 ); m_rightParenthesisCtrl->SetValue(false); m_rightParenthesisCtrl->SetHelpText(_("Check to add a right parenthesis.")); if (wxRichTextBulletsPage::ShowToolTips()) @@ -189,14 +191,14 @@ void wxRichTextBulletsPage::CreateControls() itemBoxSizer5->Add(5, 5, 0, wxALIGN_CENTER_HORIZONTAL, 5); - wxStaticText* itemStaticText13 = new wxStaticText( itemPanel1, wxID_STATIC, _("Bullet &Alignment:"), wxDefaultPosition, wxDefaultSize, 0 ); + wxStaticText* itemStaticText13 = new wxStaticText( itemRichTextDialogPage1, wxID_STATIC, _("Bullet &Alignment:"), wxDefaultPosition, wxDefaultSize, 0 ); itemBoxSizer5->Add(itemStaticText13, 0, wxALIGN_LEFT|wxLEFT|wxRIGHT|wxTOP, 5); wxArrayString m_bulletAlignmentCtrlStrings; m_bulletAlignmentCtrlStrings.Add(_("Left")); m_bulletAlignmentCtrlStrings.Add(_("Centre")); m_bulletAlignmentCtrlStrings.Add(_("Right")); - m_bulletAlignmentCtrl = new wxComboBox( itemPanel1, ID_RICHTEXTBULLETSPAGE_BULLETALIGNMENTCTRL, _("Left"), wxDefaultPosition, wxSize(60, -1), m_bulletAlignmentCtrlStrings, wxCB_READONLY ); + m_bulletAlignmentCtrl = new wxComboBox( itemRichTextDialogPage1, ID_RICHTEXTBULLETSPAGE_BULLETALIGNMENTCTRL, _("Left"), wxDefaultPosition, wxSize(60, -1), m_bulletAlignmentCtrlStrings, wxCB_READONLY ); m_bulletAlignmentCtrl->SetStringSelection(_("Left")); m_bulletAlignmentCtrl->SetHelpText(_("The bullet character.")); if (wxRichTextBulletsPage::ShowToolTips()) @@ -205,7 +207,7 @@ void wxRichTextBulletsPage::CreateControls() itemBoxSizer4->Add(2, 1, 1, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM, 5); - wxStaticLine* itemStaticLine16 = new wxStaticLine( itemPanel1, wxID_STATIC, wxDefaultPosition, wxDefaultSize, wxLI_VERTICAL ); + wxStaticLine* itemStaticLine16 = new wxStaticLine( itemRichTextDialogPage1, wxID_STATIC, wxDefaultPosition, wxDefaultSize, wxLI_VERTICAL ); itemBoxSizer4->Add(itemStaticLine16, 0, wxGROW|wxLEFT|wxRIGHT, 5); itemBoxSizer4->Add(2, 1, 1, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM, 5); @@ -216,17 +218,17 @@ void wxRichTextBulletsPage::CreateControls() wxBoxSizer* itemBoxSizer19 = new wxBoxSizer(wxHORIZONTAL); itemBoxSizer18->Add(itemBoxSizer19, 0, wxGROW, 5); - wxStaticText* itemStaticText20 = new wxStaticText( itemPanel1, ID_RICHTEXTBULLETSPAGE_SYMBOLSTATIC, _("&Symbol:"), wxDefaultPosition, wxDefaultSize, 0 ); + wxStaticText* itemStaticText20 = new wxStaticText( itemRichTextDialogPage1, ID_RICHTEXTBULLETSPAGE_SYMBOLSTATIC, _("&Symbol:"), wxDefaultPosition, wxDefaultSize, 0 ); itemBoxSizer19->Add(itemStaticText20, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); wxArrayString m_symbolCtrlStrings; - m_symbolCtrl = new wxComboBox( itemPanel1, ID_RICHTEXTBULLETSPAGE_SYMBOLCTRL, wxT(""), wxDefaultPosition, wxSize(60, -1), m_symbolCtrlStrings, wxCB_DROPDOWN ); + m_symbolCtrl = new wxComboBox( itemRichTextDialogPage1, ID_RICHTEXTBULLETSPAGE_SYMBOLCTRL, wxEmptyString, wxDefaultPosition, wxSize(60, -1), m_symbolCtrlStrings, wxCB_DROPDOWN ); m_symbolCtrl->SetHelpText(_("The bullet character.")); if (wxRichTextBulletsPage::ShowToolTips()) m_symbolCtrl->SetToolTip(_("The bullet character.")); itemBoxSizer19->Add(m_symbolCtrl, 0, wxALIGN_CENTER_VERTICAL|wxALL|wxFIXED_MINSIZE, 5); - wxButton* itemButton22 = new wxButton( itemPanel1, ID_RICHTEXTBULLETSPAGE_CHOOSE_SYMBOL, _("Ch&oose..."), wxDefaultPosition, wxDefaultSize, 0 ); + wxButton* itemButton22 = new wxButton( itemRichTextDialogPage1, ID_RICHTEXTBULLETSPAGE_CHOOSE_SYMBOL, _("Ch&oose..."), wxDefaultPosition, wxDefaultSize, 0 ); itemButton22->SetHelpText(_("Click to browse for a symbol.")); if (wxRichTextBulletsPage::ShowToolTips()) itemButton22->SetToolTip(_("Click to browse for a symbol.")); @@ -234,11 +236,11 @@ void wxRichTextBulletsPage::CreateControls() itemBoxSizer18->Add(5, 5, 0, wxALIGN_CENTER_HORIZONTAL, 5); - wxStaticText* itemStaticText24 = new wxStaticText( itemPanel1, ID_RICHTEXTBULLETSPAGE_SYMBOLSTATIC, _("Symbol &font:"), wxDefaultPosition, wxDefaultSize, 0 ); + wxStaticText* itemStaticText24 = new wxStaticText( itemRichTextDialogPage1, ID_RICHTEXTBULLETSPAGE_SYMBOLSTATIC, _("Symbol &font:"), wxDefaultPosition, wxDefaultSize, 0 ); itemBoxSizer18->Add(itemStaticText24, 0, wxALIGN_LEFT|wxLEFT|wxRIGHT|wxTOP, 5); wxArrayString m_symbolFontCtrlStrings; - m_symbolFontCtrl = new wxComboBox( itemPanel1, ID_RICHTEXTBULLETSPAGE_SYMBOLFONTCTRL, wxT(""), wxDefaultPosition, wxDefaultSize, m_symbolFontCtrlStrings, wxCB_DROPDOWN ); + m_symbolFontCtrl = new wxComboBox( itemRichTextDialogPage1, ID_RICHTEXTBULLETSPAGE_SYMBOLFONTCTRL, wxEmptyString, wxDefaultPosition, wxDefaultSize, m_symbolFontCtrlStrings, wxCB_DROPDOWN ); m_symbolFontCtrl->SetHelpText(_("Available fonts.")); if (wxRichTextBulletsPage::ShowToolTips()) m_symbolFontCtrl->SetToolTip(_("Available fonts.")); @@ -246,11 +248,11 @@ void wxRichTextBulletsPage::CreateControls() itemBoxSizer18->Add(5, 5, 1, wxALIGN_CENTER_HORIZONTAL, 5); - wxStaticText* itemStaticText27 = new wxStaticText( itemPanel1, ID_RICHTEXTBULLETSPAGE_NAMESTATIC, _("S&tandard bullet name:"), wxDefaultPosition, wxDefaultSize, 0 ); + wxStaticText* itemStaticText27 = new wxStaticText( itemRichTextDialogPage1, ID_RICHTEXTBULLETSPAGE_NAMESTATIC, _("S&tandard bullet name:"), wxDefaultPosition, wxDefaultSize, 0 ); itemBoxSizer18->Add(itemStaticText27, 0, wxALIGN_LEFT|wxLEFT|wxRIGHT|wxTOP, 5); wxArrayString m_bulletNameCtrlStrings; - m_bulletNameCtrl = new wxComboBox( itemPanel1, ID_RICHTEXTBULLETSPAGE_NAMECTRL, wxT(""), wxDefaultPosition, wxDefaultSize, m_bulletNameCtrlStrings, wxCB_DROPDOWN ); + m_bulletNameCtrl = new wxComboBox( itemRichTextDialogPage1, ID_RICHTEXTBULLETSPAGE_NAMECTRL, wxEmptyString, wxDefaultPosition, wxDefaultSize, m_bulletNameCtrlStrings, wxCB_DROPDOWN ); m_bulletNameCtrl->SetHelpText(_("A standard bullet name.")); if (wxRichTextBulletsPage::ShowToolTips()) m_bulletNameCtrl->SetToolTip(_("A standard bullet name.")); @@ -258,10 +260,10 @@ void wxRichTextBulletsPage::CreateControls() itemBoxSizer18->Add(5, 5, 1, wxALIGN_CENTER_HORIZONTAL, 5); - wxStaticText* itemStaticText30 = new wxStaticText( itemPanel1, ID_RICHTEXTBULLETSPAGE_NUMBERSTATIC, _("&Number:"), wxDefaultPosition, wxDefaultSize, 0 ); + wxStaticText* itemStaticText30 = new wxStaticText( itemRichTextDialogPage1, ID_RICHTEXTBULLETSPAGE_NUMBERSTATIC, _("&Number:"), wxDefaultPosition, wxDefaultSize, 0 ); itemBoxSizer18->Add(itemStaticText30, 0, wxALIGN_LEFT|wxLEFT|wxRIGHT|wxTOP, 5); - m_numberCtrl = new wxSpinCtrl( itemPanel1, ID_RICHTEXTBULLETSPAGE_NUMBERCTRL, wxT("0"), wxDefaultPosition, wxSize(50, -1), wxSP_ARROW_KEYS, 0, 100000, 0 ); + m_numberCtrl = new wxSpinCtrl( itemRichTextDialogPage1, ID_RICHTEXTBULLETSPAGE_NUMBERCTRL, _T("0"), wxDefaultPosition, wxSize(50, -1), wxSP_ARROW_KEYS, 0, 100000, 0 ); m_numberCtrl->SetHelpText(_("The list item number.")); if (wxRichTextBulletsPage::ShowToolTips()) m_numberCtrl->SetToolTip(_("The list item number.")); @@ -269,7 +271,7 @@ void wxRichTextBulletsPage::CreateControls() itemBoxSizer3->Add(5, 5, 0, wxALIGN_CENTER_HORIZONTAL, 5); - m_previewCtrl = new wxRichTextCtrl( itemPanel1, ID_RICHTEXTBULLETSPAGE_PREVIEW_CTRL, wxEmptyString, wxDefaultPosition, wxSize(350, 100), wxVSCROLL|wxTE_READONLY ); + m_previewCtrl = new wxRichTextCtrl( itemRichTextDialogPage1, ID_RICHTEXTBULLETSPAGE_PREVIEW_CTRL, wxEmptyString, wxDefaultPosition, wxSize(350, 100), wxVSCROLL|wxTE_READONLY ); m_previewCtrl->SetHelpText(_("Shows a preview of the bullet settings.")); if (wxRichTextBulletsPage::ShowToolTips()) m_previewCtrl->SetToolTip(_("Shows a preview of the bullet settings.")); @@ -318,11 +320,24 @@ bool wxRichTextBulletsPage::TransferDataFromWindow() wxRichTextAttr* attr = GetAttributes(); + int index = m_styleListBox->GetSelection(); + if (index < 1) + { + m_hasBulletStyle = false; + m_hasBulletNumber = false; + m_hasBulletSymbol = false; + attr->SetBulletStyle(wxTEXT_ATTR_BULLET_STYLE_NONE); + attr->SetFlags(attr->GetFlags() & ~(wxTEXT_ATTR_BULLET_STYLE|wxTEXT_ATTR_BULLET_NUMBER|wxTEXT_ATTR_BULLET_TEXT|wxTEXT_ATTR_BULLET_NAME)); + } + else + { + m_hasBulletStyle = true; + } + if (m_hasBulletStyle) { long bulletStyle = wxRICHTEXT_BULLETINDEX_NONE; - int index = m_styleListBox->GetSelection(); if (index == wxRICHTEXT_BULLETINDEX_ARABIC) bulletStyle |= wxTEXT_ATTR_BULLET_STYLE_ARABIC; diff --git a/src/richtext/richtextctrl.cpp b/src/richtext/richtextctrl.cpp index 2e3c42366e..dcb37f5227 100644 --- a/src/richtext/richtextctrl.cpp +++ b/src/richtext/richtextctrl.cpp @@ -57,6 +57,7 @@ wxDEFINE_EVENT( wxEVT_COMMAND_RICHTEXT_CONTENT_DELETED, wxRichTextEvent ); wxDEFINE_EVENT( wxEVT_COMMAND_RICHTEXT_STYLE_CHANGED, wxRichTextEvent ); wxDEFINE_EVENT( wxEVT_COMMAND_RICHTEXT_SELECTION_CHANGED, wxRichTextEvent ); wxDEFINE_EVENT( wxEVT_COMMAND_RICHTEXT_BUFFER_RESET, wxRichTextEvent ); +wxDEFINE_EVENT( wxEVT_COMMAND_RICHTEXT_FOCUS_OBJECT_CHANGED, wxRichTextEvent ); #if wxRICHTEXT_USE_OWN_CARET @@ -180,6 +181,16 @@ BEGIN_EVENT_TABLE( wxRichTextCtrl, wxControl ) EVT_MENU(wxID_SELECTALL, wxRichTextCtrl::OnSelectAll) EVT_UPDATE_UI(wxID_SELECTALL, wxRichTextCtrl::OnUpdateSelectAll) + + EVT_MENU(wxID_RICHTEXT_PROPERTIES1, wxRichTextCtrl::OnProperties) + EVT_UPDATE_UI(wxID_RICHTEXT_PROPERTIES1, wxRichTextCtrl::OnUpdateProperties) + + EVT_MENU(wxID_RICHTEXT_PROPERTIES2, wxRichTextCtrl::OnProperties) + EVT_UPDATE_UI(wxID_RICHTEXT_PROPERTIES2, wxRichTextCtrl::OnUpdateProperties) + + EVT_MENU(wxID_RICHTEXT_PROPERTIES3, wxRichTextCtrl::OnProperties) + EVT_UPDATE_UI(wxID_RICHTEXT_PROPERTIES3, wxRichTextCtrl::OnUpdateProperties) + END_EVENT_TABLE() /*! @@ -238,9 +249,12 @@ bool wxRichTextCtrl::Create( wxWindow* parent, wxWindowID id, const wxString& va attributes.SetLineSpacing(10); attributes.SetParagraphSpacingAfter(10); attributes.SetParagraphSpacingBefore(0); - + SetBasicStyle(attributes); + int margin = 5; + SetMargins(margin, margin); + // The default attributes will be merged with base attributes, so // can be empty to begin with wxRichTextAttr defaultAttributes; @@ -299,22 +313,16 @@ bool wxRichTextCtrl::Create( wxWindow* parent, wxWindowID id, const wxString& va m_contextMenu->Append(wxID_CLEAR, _("&Delete")); m_contextMenu->AppendSeparator(); m_contextMenu->Append(wxID_SELECTALL, _("Select &All")); - - long ids = wxWindow::NewControlId(); m_contextMenu->AppendSeparator(); - m_contextMenu->Append(ids, _("&Properties")); + m_contextMenu->Append(wxID_RICHTEXT_PROPERTIES1, _("&Properties")); - Connect(ids, wxEVT_UPDATE_UI, wxUpdateUIEventHandler(wxRichTextCtrl::OnUpdateImage)); - Connect(ids, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(wxRichTextCtrl::OnImage)); - m_imagePropertyId = ids; return true; } wxRichTextCtrl::~wxRichTextCtrl() { + SetFocusObject(& GetBuffer(), false); GetBuffer().RemoveEventHandler(this); - Disconnect(m_imagePropertyId, wxEVT_UPDATE_UI, wxUpdateUIEventHandler(wxRichTextCtrl::OnUpdateImage)); - Disconnect(m_imagePropertyId, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(wxRichTextCtrl::OnImage)); delete m_contextMenu; } @@ -325,8 +333,9 @@ void wxRichTextCtrl::Init() m_contextMenu = NULL; m_caret = NULL; m_caretPosition = -1; - m_selectionRange.SetRange(-2, -2); m_selectionAnchor = -2; + m_selectionAnchorObject = NULL; + m_selectionState = wxRichTextCtrlSelectionState_Normal; m_editable = true; m_caretAtLineStart = false; m_dragging = false; @@ -335,12 +344,12 @@ void wxRichTextCtrl::Init() m_fullLayoutSavedPosition = 0; m_delayedLayoutThreshold = wxRICHTEXT_DEFAULT_DELAYED_LAYOUT_THRESHOLD; m_caretPositionForDefaultStyle = -2; - m_currentObject = NULL; + m_focusObject = & m_buffer; } void wxRichTextCtrl::DoThaw() { - if (GetBuffer().GetDirty()) + if (GetBuffer().IsDirty()) LayoutContent(); else SetupScrollbars(); @@ -351,12 +360,21 @@ void wxRichTextCtrl::DoThaw() /// Clear all text void wxRichTextCtrl::Clear() { - m_buffer.ResetAndClearCommands(); - m_buffer.SetDirty(true); + if (GetFocusObject() == & GetBuffer()) + { + m_buffer.ResetAndClearCommands(); + m_buffer.Invalidate(wxRICHTEXT_ALL); + } + else + { + GetFocusObject()->Reset(); + } + m_caretPosition = -1; m_caretPositionForDefaultStyle = -2; m_caretAtLineStart = false; - m_selectionRange.SetRange(-2, -2); + m_selection.Reset(); + m_selectionState = wxRichTextCtrlSelectionState_Normal; Scroll(0,0); @@ -400,10 +418,10 @@ void wxRichTextCtrl::OnPaint(wxPaintEvent& WXUNUSED(event)) drawingArea.SetPosition(GetLogicalPoint(drawingArea.GetPosition())); wxRect availableSpace(GetClientSize()); - if (GetBuffer().GetDirty()) + if (GetBuffer().IsDirty()) { GetBuffer().Layout(dc, availableSpace, wxRICHTEXT_FIXED_WIDTH|wxRICHTEXT_VARIABLE_HEIGHT); - GetBuffer().SetDirty(false); + GetBuffer().Invalidate(wxRICHTEXT_NONE); SetupScrollbars(); } @@ -415,7 +433,11 @@ void wxRichTextCtrl::OnPaint(wxPaintEvent& WXUNUSED(event)) clipRect.SetPosition(GetLogicalPoint(clipRect.GetPosition())); dc.SetClippingRegion(clipRect); - GetBuffer().Draw(dc, GetBuffer().GetRange(), GetInternalSelectionRange(), drawingArea, 0 /* descent */, 0 /* flags */); + int flags = 0; + if ((GetExtraStyle() & wxRICHTEXT_EX_NO_GUIDELINES) == 0) + flags |= wxRICHTEXT_DRAW_GUIDELINES; + + GetBuffer().Draw(dc, GetBuffer().GetOwnRange(), GetSelection(), drawingArea, 0 /* descent */, flags); dc.DestroyClippingRegion(); @@ -480,6 +502,33 @@ void wxRichTextCtrl::OnCaptureLost(wxMouseCaptureLostEvent& WXUNUSED(event)) m_dragging = false; } +// Set up the caret for the given position and container, after a mouse click +bool wxRichTextCtrl::SetCaretPositionAfterClick(wxRichTextParagraphLayoutBox* container, long position, int hitTestFlags, bool extendSelection) +{ + bool caretAtLineStart = false; + + if (hitTestFlags & wxRICHTEXT_HITTEST_BEFORE) + { + // If we're at the start of a line (but not first in para) + // then we should keep the caret showing at the start of the line + // by showing the m_caretAtLineStart flag. + wxRichTextParagraph* para = container->GetParagraphAtPosition(position); + wxRichTextLine* line = container->GetLineAtPosition(position); + + if (line && para && line->GetAbsoluteRange().GetStart() == position && para->GetRange().GetStart() != position) + caretAtLineStart = true; + position --; + } + + if (extendSelection && (m_caretPosition != position)) + ExtendSelection(m_caretPosition, position, wxRICHTEXT_SHIFT_DOWN); + + MoveCaret(position, caretAtLineStart); + SetDefaultStyleToCursorStyle(); + + return true; +} + /// Left-click void wxRichTextCtrl::OnLeftClick(wxMouseEvent& event) { @@ -489,38 +538,33 @@ void wxRichTextCtrl::OnLeftClick(wxMouseEvent& event) PrepareDC(dc); dc.SetFont(GetFont()); + // TODO: detect change of focus object long position = 0; - int hit = GetBuffer().HitTest(dc, event.GetLogicalPosition(dc), position); + wxRichTextObject* hitObj = NULL; + wxRichTextObject* contextObj = NULL; + int hit = GetBuffer().HitTest(dc, event.GetLogicalPosition(dc), position, & hitObj, & contextObj); - if (hit != wxRICHTEXT_HITTEST_NONE) + if (hit != wxRICHTEXT_HITTEST_NONE && hitObj) { + wxRichTextParagraphLayoutBox* oldFocusObject = GetFocusObject(); + wxRichTextParagraphLayoutBox* container = wxDynamicCast(contextObj, wxRichTextParagraphLayoutBox); + if (container && container != GetFocusObject() && container->AcceptsFocus()) + { + SetFocusObject(container, false /* don't set caret position yet */); + } + m_dragStart = event.GetLogicalPosition(dc); m_dragging = true; CaptureMouse(); - bool caretAtLineStart = false; - - if (hit & wxRICHTEXT_HITTEST_BEFORE) - { - // If we're at the start of a line (but not first in para) - // then we should keep the caret showing at the start of the line - // by showing the m_caretAtLineStart flag. - wxRichTextParagraph* para = GetBuffer().GetParagraphAtPosition(position); - wxRichTextLine* line = GetBuffer().GetLineAtPosition(position); - - if (line && para && line->GetAbsoluteRange().GetStart() == position && para->GetRange().GetStart() != position) - caretAtLineStart = true; - position --; - } - long oldCaretPos = m_caretPosition; - MoveCaret(position, caretAtLineStart); - SetDefaultStyleToCursorStyle(); + SetCaretPositionAfterClick(container, position, hit); - if (event.ShiftDown()) + // For now, don't handle shift-click when we're selecting multiple objects. + if (event.ShiftDown() && GetFocusObject() == oldFocusObject && m_selectionState == wxRichTextCtrlSelectionState_Normal) { - if (m_selectionRange.GetStart() == -2) + if (!m_selection.IsValid()) ExtendSelection(oldCaretPos, m_caretPosition, wxRICHTEXT_SHIFT_DOWN); else ExtendSelection(m_caretPosition, m_caretPosition, wxRICHTEXT_SHIFT_DOWN); @@ -548,7 +592,10 @@ void wxRichTextCtrl::OnLeftUp(wxMouseEvent& event) long position = 0; wxPoint logicalPt = event.GetLogicalPosition(dc); - int hit = GetBuffer().HitTest(dc, logicalPt, position); + wxRichTextObject* hitObj = NULL; + wxRichTextObject* contextObj = NULL; + // Only get objects at this level, not nested, because otherwise we couldn't swipe text at a single level. + int hit = GetFocusObject()->HitTest(dc, logicalPt, position, & hitObj, & contextObj, wxRICHTEXT_HITTEST_NO_NESTED_OBJECTS); if ((hit != wxRICHTEXT_HITTEST_NONE) && !(hit & wxRICHTEXT_HITTEST_OUTSIDE)) { @@ -556,7 +603,9 @@ void wxRichTextCtrl::OnLeftUp(wxMouseEvent& event) wxEVT_COMMAND_RICHTEXT_LEFT_CLICK, GetId()); cmdEvent.SetEventObject(this); - cmdEvent.SetPosition(m_caretPosition+1); + cmdEvent.SetPosition(position); + if (hitObj) + cmdEvent.SetContainer(hitObj->GetContainer()); if (!GetEventHandler()->ProcessEvent(cmdEvent)) { @@ -571,7 +620,7 @@ void wxRichTextCtrl::OnLeftUp(wxMouseEvent& event) wxMouseEvent mouseEvent(event); long startPos = 0, endPos = 0; - wxRichTextObject* obj = GetBuffer().GetLeafObjectAtPosition(position); + wxRichTextObject* obj = GetFocusObject()->GetLeafObjectAtPosition(position); if (obj) { startPos = obj->GetRange().GetStart(); @@ -601,15 +650,29 @@ void wxRichTextCtrl::OnMoveMouse(wxMouseEvent& event) long position = 0; wxPoint logicalPt = event.GetLogicalPosition(dc); - int hit = GetBuffer().HitTest(dc, logicalPt, position); - + wxRichTextObject* hitObj = NULL; + wxRichTextObject* contextObj = NULL; + + int flags = 0; + + // If we're dragging, let's only consider positions at this level; otherwise + // selecting a range is not going to work. + wxRichTextParagraphLayoutBox* container = & GetBuffer(); + if (m_dragging) + { + flags = wxRICHTEXT_HITTEST_NO_NESTED_OBJECTS; + container = GetFocusObject(); + } + int hit = container->HitTest(dc, logicalPt, position, & hitObj, & contextObj, flags); + // See if we need to change the cursor { - if (hit != wxRICHTEXT_HITTEST_NONE && !(hit & wxRICHTEXT_HITTEST_OUTSIDE)) + if (hit != wxRICHTEXT_HITTEST_NONE && !(hit & wxRICHTEXT_HITTEST_OUTSIDE) && hitObj) { + wxRichTextParagraphLayoutBox* actualContainer = wxDynamicCast(contextObj, wxRichTextParagraphLayoutBox); wxRichTextAttr attr; - if (GetStyle(position, attr)) + if (actualContainer && GetStyle(position, attr, actualContainer)) { if (attr.HasFlag(wxTEXT_ATTR_URL)) { @@ -630,33 +693,84 @@ void wxRichTextCtrl::OnMoveMouse(wxMouseEvent& event) event.Skip(); return; } + + if (m_dragging) + { + wxRichTextParagraphLayoutBox* commonAncestor = NULL; + wxRichTextParagraphLayoutBox* otherContainer = NULL; + wxRichTextParagraphLayoutBox* firstContainer = NULL; - if (m_dragging && hit != wxRICHTEXT_HITTEST_NONE) + // Check for dragging across multiple containers + long position2 = 0; + wxRichTextObject* hitObj2 = NULL, *contextObj2 = NULL; + int hit2 = GetBuffer().HitTest(dc, logicalPt, position2, & hitObj2, & contextObj2, 0); + if (hit2 != wxRICHTEXT_HITTEST_NONE && !(hit2 & wxRICHTEXT_HITTEST_OUTSIDE) && hitObj2 && hitObj != hitObj2) + { + // See if we can find a common ancestor + if (m_selectionState == wxRichTextCtrlSelectionState_Normal) + { + firstContainer = GetFocusObject(); + commonAncestor = wxDynamicCast(firstContainer->GetParent(), wxRichTextParagraphLayoutBox); + } + else + { + firstContainer = wxDynamicCast(m_selectionAnchorObject, wxRichTextParagraphLayoutBox); + //commonAncestor = GetFocusObject(); // when the selection state is not normal, the focus object (e.g. table) + // is the common ancestor. + commonAncestor = wxDynamicCast(firstContainer->GetParent(), wxRichTextParagraphLayoutBox); + } + + if (commonAncestor && commonAncestor->HandlesChildSelections()) + { + wxRichTextObject* p = hitObj2; + while (p) + { + if (p->GetParent() == commonAncestor) + { + otherContainer = wxDynamicCast(p, wxRichTextParagraphLayoutBox); + break; + } + p = p->GetParent(); + } + } + + if (commonAncestor && firstContainer && otherContainer) + { + // We have now got a second container that shares a parent with the current or anchor object. + if (m_selectionState == wxRichTextCtrlSelectionState_Normal) + { + // Don't go into common-ancestor selection mode if we still have the same + // container. + if (otherContainer != firstContainer) + { + m_selectionState = wxRichTextCtrlSelectionState_CommonAncestor; + m_selectionAnchorObject = firstContainer; + m_selectionAnchor = firstContainer->GetRange().GetStart(); + + // The common ancestor, such as a table, returns the cell selection + // between the anchor and current position. + m_selection = commonAncestor->GetSelection(m_selectionAnchor, otherContainer->GetRange().GetStart()); + } + } + else + { + m_selection = commonAncestor->GetSelection(m_selectionAnchor, otherContainer->GetRange().GetStart()); + } + + Refresh(); + + if (otherContainer->AcceptsFocus()) + SetFocusObject(otherContainer, false /* don't set caret and clear selection */); + MoveCaret(-1, false); + SetDefaultStyleToCursorStyle(); + } + } + } + + if (hitObj && m_dragging && hit != wxRICHTEXT_HITTEST_NONE && m_selectionState == wxRichTextCtrlSelectionState_Normal) { // TODO: test closeness - - bool caretAtLineStart = false; - - if (hit & wxRICHTEXT_HITTEST_BEFORE) - { - // If we're at the start of a line (but not first in para) - // then we should keep the caret showing at the start of the line - // by showing the m_caretAtLineStart flag. - wxRichTextParagraph* para = GetBuffer().GetParagraphAtPosition(position); - wxRichTextLine* line = GetBuffer().GetLineAtPosition(position); - - if (line && para && line->GetAbsoluteRange().GetStart() == position && para->GetRange().GetStart() != position) - caretAtLineStart = true; - position --; - } - - if (m_caretPosition != position) - { - ExtendSelection(m_caretPosition, position, wxRICHTEXT_SHIFT_DOWN); - - MoveCaret(position, caretAtLineStart); - SetDefaultStyleToCursorStyle(); - } + SetCaretPositionAfterClick(container, position, hit, true /* extend selection */); } } @@ -664,12 +778,34 @@ void wxRichTextCtrl::OnMoveMouse(wxMouseEvent& event) void wxRichTextCtrl::OnRightClick(wxMouseEvent& event) { SetFocus(); + + wxClientDC dc(this); + PrepareDC(dc); + dc.SetFont(GetFont()); + + long position = 0; + wxPoint logicalPt = event.GetLogicalPosition(dc); + wxRichTextObject* hitObj = NULL; + wxRichTextObject* contextObj = NULL; + int hit = GetFocusObject()->HitTest(dc, logicalPt, position, & hitObj, & contextObj); + + if (hitObj && hitObj->GetContainer() != GetFocusObject()) + { + wxRichTextParagraphLayoutBox* actualContainer = wxDynamicCast(contextObj, wxRichTextParagraphLayoutBox); + if (actualContainer && actualContainer->AcceptsFocus()) + { + SetFocusObject(actualContainer, false /* don't set caret position yet */); + SetCaretPositionAfterClick(actualContainer, position, hit); + } + } wxRichTextEvent cmdEvent( wxEVT_COMMAND_RICHTEXT_RIGHT_CLICK, GetId()); cmdEvent.SetEventObject(this); - cmdEvent.SetPosition(m_caretPosition+1); + cmdEvent.SetPosition(position); + if (hitObj) + cmdEvent.SetContainer(hitObj->GetContainer()); if (!GetEventHandler()->ProcessEvent(cmdEvent)) event.Skip(); @@ -683,6 +819,7 @@ void wxRichTextCtrl::OnLeftDClick(wxMouseEvent& WXUNUSED(event)) GetId()); cmdEvent.SetEventObject(this); cmdEvent.SetPosition(m_caretPosition+1); + cmdEvent.SetContainer(GetFocusObject()); if (!GetEventHandler()->ProcessEvent(cmdEvent)) { @@ -698,6 +835,7 @@ void wxRichTextCtrl::OnMiddleClick(wxMouseEvent& event) GetId()); cmdEvent.SetEventObject(this); cmdEvent.SetPosition(m_caretPosition+1); + cmdEvent.SetContainer(GetFocusObject()); if (!GetEventHandler()->ProcessEvent(cmdEvent)) event.Skip(); @@ -819,20 +957,20 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event) long pos = wxRichTextCtrl::FindNextWordPosition(-1); if (pos < newPos) { - GetBuffer().DeleteRangeWithUndo(wxRichTextRange(pos+1, newPos), this); + GetFocusObject()->DeleteRangeWithUndo(wxRichTextRange(pos+1, newPos), this, & GetBuffer()); processed = true; } } if (!processed) - GetBuffer().DeleteRangeWithUndo(wxRichTextRange(newPos, newPos), this); + GetFocusObject()->DeleteRangeWithUndo(wxRichTextRange(newPos, newPos), this, & GetBuffer()); } EndBatchUndo(); if (GetLastPosition() == -1) { - GetBuffer().Reset(); + GetFocusObject()->Reset(); m_caretPosition = -1; PositionCaret(); @@ -847,6 +985,7 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event) cmdEvent.SetEventObject(this); cmdEvent.SetFlags(flags); cmdEvent.SetPosition(m_caretPosition+1); + cmdEvent.SetContainer(GetFocusObject()); GetEventHandler()->ProcessEvent(cmdEvent); Update(); @@ -877,12 +1016,12 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event) { wxString text; text = wxRichTextLineBreakChar; - GetBuffer().InsertTextWithUndo(newPos+1, text, this); + GetFocusObject()->InsertTextWithUndo(newPos+1, text, this, & GetBuffer()); m_caretAtLineStart = true; PositionCaret(); } else - GetBuffer().InsertNewlineWithUndo(newPos+1, this, wxRICHTEXT_INSERT_WITH_PREVIOUS_PARAGRAPH_STYLE|wxRICHTEXT_INSERT_INTERACTIVE); + GetFocusObject()->InsertNewlineWithUndo(newPos+1, this, & GetBuffer(), wxRICHTEXT_INSERT_WITH_PREVIOUS_PARAGRAPH_STYLE|wxRICHTEXT_INSERT_INTERACTIVE); EndBatchUndo(); SetDefaultStyleToCursorStyle(); @@ -895,6 +1034,7 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event) cmdEvent.SetEventObject(this); cmdEvent.SetFlags(flags); cmdEvent.SetPosition(newPos+1); + cmdEvent.SetContainer(GetFocusObject()); if (!GetEventHandler()->ProcessEvent(cmdEvent)) { @@ -923,20 +1063,20 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event) long pos = wxRichTextCtrl::FindNextWordPosition(-1); if (pos < newPos) { - GetBuffer().DeleteRangeWithUndo(wxRichTextRange(pos+1, newPos), this); + GetFocusObject()->DeleteRangeWithUndo(wxRichTextRange(pos+1, newPos), this, & GetBuffer()); processed = true; } } if (!processed) - GetBuffer().DeleteRangeWithUndo(wxRichTextRange(newPos, newPos), this); + GetFocusObject()->DeleteRangeWithUndo(wxRichTextRange(newPos, newPos), this, & GetBuffer()); } EndBatchUndo(); if (GetLastPosition() == -1) { - GetBuffer().Reset(); + GetFocusObject()->Reset(); m_caretPosition = -1; PositionCaret(); @@ -951,6 +1091,7 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event) cmdEvent.SetEventObject(this); cmdEvent.SetFlags(flags); cmdEvent.SetPosition(m_caretPosition+1); + cmdEvent.SetContainer(GetFocusObject()); GetEventHandler()->ProcessEvent(cmdEvent); Update(); @@ -964,27 +1105,27 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event) bool processed = DeleteSelectedContent(& newPos); // Submit range in character positions, which are greater than caret positions, - if (newPos < GetBuffer().GetRange().GetEnd()+1) + if (newPos < GetFocusObject()->GetOwnRange().GetEnd()+1) { if (event.CmdDown()) { long pos = wxRichTextCtrl::FindNextWordPosition(1); if (pos != -1 && (pos > newPos)) { - GetBuffer().DeleteRangeWithUndo(wxRichTextRange(newPos+1, pos), this); + GetFocusObject()->DeleteRangeWithUndo(wxRichTextRange(newPos+1, pos), this, & GetBuffer()); processed = true; } } if (!processed && newPos < (GetLastPosition()-1)) - GetBuffer().DeleteRangeWithUndo(wxRichTextRange(newPos+1, newPos+1), this); + GetFocusObject()->DeleteRangeWithUndo(wxRichTextRange(newPos+1, newPos+1), this, & GetBuffer()); } EndBatchUndo(); if (GetLastPosition() == -1) { - GetBuffer().Reset(); + GetFocusObject()->Reset(); m_caretPosition = -1; PositionCaret(); @@ -997,6 +1138,7 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event) cmdEvent.SetEventObject(this); cmdEvent.SetFlags(flags); cmdEvent.SetPosition(m_caretPosition+1); + cmdEvent.SetContainer(GetFocusObject()); GetEventHandler()->ProcessEvent(cmdEvent); Update(); @@ -1036,13 +1178,14 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event) cmdEvent.SetCharacter((wxChar) keycode); #endif cmdEvent.SetPosition(m_caretPosition+1); + cmdEvent.SetContainer(GetFocusObject()); if (keycode == wxT('\t')) { // See if we need to promote or demote the selection or paragraph at the cursor // position, instead of inserting a tab. long pos = GetAdjustedCaretPosition(GetCaretPosition()); - wxRichTextParagraph* para = GetBuffer().GetParagraphAtPosition(pos); + wxRichTextParagraph* para = GetFocusObject()->GetParagraphAtPosition(pos); if (para && para->GetRange().GetStart() == pos && para->GetAttributes().HasListStyleName()) { wxRichTextRange range; @@ -1071,7 +1214,7 @@ void wxRichTextCtrl::OnChar(wxKeyEvent& event) #else wxString str = (wxChar) event.GetKeyCode(); #endif - GetBuffer().InsertTextWithUndo(newPos+1, str, this, 0); + GetFocusObject()->InsertTextWithUndo(newPos+1, str, this, & GetBuffer(), 0); EndBatchUndo(); @@ -1091,8 +1234,8 @@ bool wxRichTextCtrl::DeleteSelectedContent(long* newPos) { if (HasSelection()) { - long pos = m_selectionRange.GetStart(); - wxRichTextRange range = m_selectionRange; + long pos = m_selection.GetRange().GetStart(); + wxRichTextRange range = m_selection.GetRange(); // SelectAll causes more to be selected than doing it interactively, // and causes a new paragraph to be inserted. So for multiline buffers, @@ -1100,8 +1243,9 @@ bool wxRichTextCtrl::DeleteSelectedContent(long* newPos) if (range.GetEnd() == GetLastPosition() && GetNumberOfLines() > 0) range.SetEnd(range.GetEnd()-1); - GetBuffer().DeleteRangeWithUndo(range, this); - m_selectionRange.SetRange(-2, -2); + GetFocusObject()->DeleteRangeWithUndo(range, this, & GetBuffer()); + m_selection.Reset(); + m_selectionState = wxRichTextCtrlSelectionState_Normal; if (newPos) *newPos = pos-1; @@ -1214,33 +1358,44 @@ bool wxRichTextCtrl::ExtendSelection(long oldPos, long newPos, int flags) if (oldPos == newPos) return false; - wxRichTextRange oldSelection = m_selectionRange; + wxRichTextSelection oldSelection = m_selection; + + m_selection.SetContainer(GetFocusObject()); + + wxRichTextRange oldRange; + if (m_selection.IsValid()) + oldRange = m_selection.GetRange(); + else + oldRange = wxRICHTEXT_NO_SELECTION; + wxRichTextRange newRange; // If not currently selecting, start selecting - if (m_selectionRange.GetStart() == -2) + if (oldRange.GetStart() == -2) { m_selectionAnchor = oldPos; if (oldPos > newPos) - m_selectionRange.SetRange(newPos+1, oldPos); + newRange.SetRange(newPos+1, oldPos); else - m_selectionRange.SetRange(oldPos+1, newPos); + newRange.SetRange(oldPos+1, newPos); } else { // Always ensure that the selection range start is greater than // the end. if (newPos > m_selectionAnchor) - m_selectionRange.SetRange(m_selectionAnchor+1, newPos); + newRange.SetRange(m_selectionAnchor+1, newPos); else if (newPos == m_selectionAnchor) - m_selectionRange = wxRichTextRange(-2, -2); + newRange = wxRichTextRange(-2, -2); else - m_selectionRange.SetRange(newPos+1, m_selectionAnchor); + newRange.SetRange(newPos+1, m_selectionAnchor); } + + m_selection.SetRange(newRange); - RefreshForSelectionChange(oldSelection, m_selectionRange); + RefreshForSelectionChange(oldSelection, m_selection); - if (m_selectionRange.GetStart() > m_selectionRange.GetEnd()) + if (newRange.GetStart() > newRange.GetEnd()) { wxLogDebug(wxT("Strange selection range")); } @@ -1279,7 +1434,16 @@ bool wxRichTextCtrl::ScrollIntoView(long position, int keyCode) bool scrolled = false; wxSize clientSize = GetClientSize(); - clientSize.y -= GetBuffer().GetBottomMargin(); + + int leftMargin, rightMargin, topMargin, bottomMargin; + + { + wxClientDC dc(this); + wxRichTextObject::GetTotalMargin(dc, & GetBuffer(), GetBuffer().GetAttributes(), leftMargin, rightMargin, + topMargin, bottomMargin); + } +// clientSize.y -= GetBuffer().GetBottomMargin(); + clientSize.y -= bottomMargin; if (GetWindowStyle() & wxRE_CENTRE_CARET) { @@ -1418,13 +1582,13 @@ void wxRichTextCtrl::SetCaretPosition(long position, bool showAtLineStart) /// to the start of the next, which may be the exact same caret position. void wxRichTextCtrl::MoveCaretForward(long oldPosition) { - wxRichTextParagraph* para = GetBuffer().GetParagraphAtPosition(oldPosition); + wxRichTextParagraph* para = GetFocusObject()->GetParagraphAtPosition(oldPosition); // Only do the check if we're not at the end of the paragraph (where things work OK // anyway) if (para && (oldPosition != para->GetRange().GetEnd() - 1)) { - wxRichTextLine* line = GetBuffer().GetLineAtPosition(oldPosition); + wxRichTextLine* line = GetFocusObject()->GetLineAtPosition(oldPosition); if (line) { @@ -1463,13 +1627,13 @@ void wxRichTextCtrl::MoveCaretForward(long oldPosition) /// to the start of the next, which may be the exact same caret position. void wxRichTextCtrl::MoveCaretBack(long oldPosition) { - wxRichTextParagraph* para = GetBuffer().GetParagraphAtPosition(oldPosition); + wxRichTextParagraph* para = GetFocusObject()->GetParagraphAtPosition(oldPosition); // Only do the check if we're not at the start of the paragraph (where things work OK // anyway) if (para && (oldPosition != para->GetRange().GetStart())) { - wxRichTextLine* line = GetBuffer().GetLineAtPosition(oldPosition); + wxRichTextLine* line = GetFocusObject()->GetLineAtPosition(oldPosition); if (line) { @@ -1511,7 +1675,7 @@ void wxRichTextCtrl::MoveCaretBack(long oldPosition) /// Move right bool wxRichTextCtrl::MoveRight(int noPositions, int flags) { - long endPos = GetBuffer().GetRange().GetEnd(); + long endPos = GetFocusObject()->GetOwnRange().GetEnd(); if (m_caretPosition + noPositions < endPos) { @@ -1568,6 +1732,40 @@ bool wxRichTextCtrl::MoveLeft(int noPositions, int flags) return false; } +// Find the caret position for the combination of hit-test flags and character position. +// Returns the caret position and also an indication of where to place the caret (caretLineStart) +// since this is ambiguous (same position used for end of line and start of next). +long wxRichTextCtrl::FindCaretPositionForCharacterPosition(long position, int hitTestFlags, wxRichTextParagraphLayoutBox* container, + bool& caretLineStart) +{ + // If end of previous line, and hitTest is wxRICHTEXT_HITTEST_BEFORE, + // we want to be at the end of the last line but with m_caretAtLineStart set to true, + // so we view the caret at the start of the line. + caretLineStart = false; + long caretPosition = position; + + if (hitTestFlags & wxRICHTEXT_HITTEST_BEFORE) + { + wxRichTextLine* thisLine = container->GetLineAtPosition(position-1); + wxRichTextRange lineRange; + if (thisLine) + lineRange = thisLine->GetAbsoluteRange(); + + if (thisLine && (position-1) == lineRange.GetEnd()) + { + caretPosition --; + caretLineStart = true; + } + else + { + wxRichTextParagraph* para = container->GetParagraphAtPosition(position); + if (para && para->GetRange().GetStart() == position) + caretPosition --; + } + } + return caretPosition; +} + /// Move up bool wxRichTextCtrl::MoveUp(int noLines, int flags) { @@ -1580,74 +1778,90 @@ bool wxRichTextCtrl::MoveDown(int noLines, int flags) if (!GetCaret()) return false; - long lineNumber = GetBuffer().GetVisibleLineNumber(m_caretPosition, true, m_caretAtLineStart); + long lineNumber = GetFocusObject()->GetVisibleLineNumber(m_caretPosition, true, m_caretAtLineStart); wxPoint pt = GetCaret()->GetPosition(); - long newLine = lineNumber + noLines; + long newLine = lineNumber + noLines; + bool notInThisObject = false; if (lineNumber != -1) { if (noLines > 0) { - long lastLine = GetBuffer().GetVisibleLineNumber(GetBuffer().GetRange().GetEnd()); - + long lastLine = GetFocusObject()->GetVisibleLineNumber(GetFocusObject()->GetOwnRange().GetEnd()); if (newLine > lastLine) - return false; + notInThisObject = true; } else { if (newLine < 0) - return false; + notInThisObject = true; } } + + wxRichTextParagraphLayoutBox* container = GetFocusObject(); + int hitTestFlags = wxRICHTEXT_HITTEST_NO_NESTED_OBJECTS; - wxRichTextLine* lineObj = GetBuffer().GetLineForVisibleLineNumber(newLine); - if (lineObj) + if (notInThisObject) { - pt.y = lineObj->GetAbsolutePosition().y + 2; + // If we know we're navigating out of the current object, + // try to find an object anywhere in the buffer at the new position (up or down a bit) + container = & GetBuffer(); + hitTestFlags = 0; + + if (noLines > 0) // going down + { + pt.y = GetFocusObject()->GetPosition().y + GetFocusObject()->GetCachedSize().y + 2; + } + else // going up + { + pt.y = GetFocusObject()->GetPosition().y - 2; + } } else - return false; + { + wxRichTextLine* lineObj = GetFocusObject()->GetLineForVisibleLineNumber(newLine); + if (lineObj) + pt.y = lineObj->GetAbsolutePosition().y + 2; + else + return false; + } long newPos = 0; wxClientDC dc(this); PrepareDC(dc); dc.SetFont(GetFont()); - int hitTest = GetBuffer().HitTest(dc, pt, newPos); + wxRichTextObject* hitObj = NULL; + wxRichTextObject* contextObj = NULL; + int hitTest = container->HitTest(dc, pt, newPos, & hitObj, & contextObj, hitTestFlags); - if (hitTest != wxRICHTEXT_HITTEST_NONE) + if (hitTest != wxRICHTEXT_HITTEST_NONE && hitObj) { - // If end of previous line, and hitTest is wxRICHTEXT_HITTEST_BEFORE, - // we want to be at the end of the last line but with m_caretAtLineStart set to true, - // so we view the caret at the start of the line. - bool caretLineStart = false; - if (hitTest & wxRICHTEXT_HITTEST_BEFORE) + if (notInThisObject) { - wxRichTextLine* thisLine = GetBuffer().GetLineAtPosition(newPos-1); - wxRichTextRange lineRange; - if (thisLine) - lineRange = thisLine->GetAbsoluteRange(); - - if (thisLine && (newPos-1) == lineRange.GetEnd()) + wxRichTextParagraphLayoutBox* actualContainer = wxDynamicCast(contextObj, wxRichTextParagraphLayoutBox); + if (actualContainer && actualContainer != GetFocusObject() && actualContainer->AcceptsFocus()) { - newPos --; - caretLineStart = true; - } - else - { - wxRichTextParagraph* para = GetBuffer().GetParagraphAtPosition(newPos); - if (para && para->GetRange().GetStart() == newPos) - newPos --; + SetFocusObject(actualContainer, false /* don't set caret position yet */); + + container = actualContainer; } } + + bool caretLineStart = true; + long caretPosition = FindCaretPositionForCharacterPosition(newPos, hitTest, container, caretLineStart); + long newSelEnd = caretPosition; + bool extendSel; - long newSelEnd = newPos; + if (notInThisObject) + extendSel = false; + else + extendSel = ExtendSelection(m_caretPosition, newSelEnd, flags); - bool extendSel = ExtendSelection(m_caretPosition, newSelEnd, flags); if (!extendSel) SelectNone(); - SetCaretPosition(newPos, caretLineStart); + SetCaretPosition(caretPosition, caretLineStart); PositionCaret(); SetDefaultStyleToCursorStyle(); @@ -1660,7 +1874,7 @@ bool wxRichTextCtrl::MoveDown(int noLines, int flags) /// Move to the end of the paragraph bool wxRichTextCtrl::MoveToParagraphEnd(int flags) { - wxRichTextParagraph* para = GetBuffer().GetParagraphAtPosition(m_caretPosition, true); + wxRichTextParagraph* para = GetFocusObject()->GetParagraphAtPosition(m_caretPosition, true); if (para) { long newPos = para->GetRange().GetEnd() - 1; @@ -1681,7 +1895,7 @@ bool wxRichTextCtrl::MoveToParagraphEnd(int flags) /// Move to the start of the paragraph bool wxRichTextCtrl::MoveToParagraphStart(int flags) { - wxRichTextParagraph* para = GetBuffer().GetParagraphAtPosition(m_caretPosition, true); + wxRichTextParagraph* para = GetFocusObject()->GetParagraphAtPosition(m_caretPosition, true); if (para) { long newPos = para->GetRange().GetStart() - 1; @@ -1735,7 +1949,7 @@ bool wxRichTextCtrl::MoveToLineStart(int flags) if (!extendSel) SelectNone(); - wxRichTextParagraph* para = GetBuffer().GetParagraphForLine(line); + wxRichTextParagraph* para = GetFocusObject()->GetParagraphForLine(line); SetCaretPosition(newPos, para->GetRange().GetStart() != lineRange.GetStart()); PositionCaret(); @@ -1769,7 +1983,7 @@ bool wxRichTextCtrl::MoveHome(int flags) /// Move to the end of the buffer bool wxRichTextCtrl::MoveEnd(int flags) { - long endPos = GetBuffer().GetRange().GetEnd()-1; + long endPos = GetFocusObject()->GetOwnRange().GetEnd()-1; if (m_caretPosition != endPos) { @@ -1803,14 +2017,14 @@ bool wxRichTextCtrl::PageDown(int noPages, int flags) wxSize clientSize = GetClientSize(); int newY = line->GetAbsolutePosition().y + noPages*clientSize.y; - wxRichTextLine* newLine = GetBuffer().GetLineAtYPosition(newY); + wxRichTextLine* newLine = GetFocusObject()->GetLineAtYPosition(newY); if (newLine) { wxRichTextRange lineRange = newLine->GetAbsoluteRange(); long pos = lineRange.GetStart()-1; if (pos != m_caretPosition) { - wxRichTextParagraph* para = GetBuffer().GetParagraphForLine(newLine); + wxRichTextParagraph* para = GetFocusObject()->GetParagraphForLine(newLine); bool extendSel = ExtendSelection(m_caretPosition, pos, flags); if (!extendSel) @@ -1836,7 +2050,7 @@ static bool wxRichTextCtrlIsWhitespace(const wxString& str) // Finds the caret position for the next word long wxRichTextCtrl::FindNextWordPosition(int direction) const { - long endPos = GetBuffer().GetRange().GetEnd(); + long endPos = GetFocusObject()->GetOwnRange().GetEnd(); if (direction > 0) { @@ -1846,8 +2060,8 @@ long wxRichTextCtrl::FindNextWordPosition(int direction) const while (i < endPos && i > -1) { // i is in character, not caret positions - wxString text = GetBuffer().GetTextForRange(wxRichTextRange(i, i)); - wxRichTextLine* line = GetBuffer().GetLineAtPosition(i, false); + wxString text = GetFocusObject()->GetTextForRange(wxRichTextRange(i, i)); + wxRichTextLine* line = GetFocusObject()->GetLineAtPosition(i, false); if (line && (i == line->GetAbsoluteRange().GetEnd())) { break; @@ -1862,8 +2076,8 @@ long wxRichTextCtrl::FindNextWordPosition(int direction) const while (i < endPos && i > -1) { // i is in character, not caret positions - wxString text = GetBuffer().GetTextForRange(wxRichTextRange(i, i)); - wxRichTextLine* line = GetBuffer().GetLineAtPosition(i, false); + wxString text = GetFocusObject()->GetTextForRange(wxRichTextRange(i, i)); + wxRichTextLine* line = GetFocusObject()->GetLineAtPosition(i, false); if (line && (i == line->GetAbsoluteRange().GetEnd())) return wxMax(-1, i); @@ -1889,8 +2103,8 @@ long wxRichTextCtrl::FindNextWordPosition(int direction) const while (i < endPos && i > -1) { // i is in character, not caret positions - wxString text = GetBuffer().GetTextForRange(wxRichTextRange(i, i)); - wxRichTextLine* line = GetBuffer().GetLineAtPosition(i, false); + wxString text = GetFocusObject()->GetTextForRange(wxRichTextRange(i, i)); + wxRichTextLine* line = GetFocusObject()->GetLineAtPosition(i, false); if (text.empty() || (line && (i == line->GetAbsoluteRange().GetStart()))) // End of paragraph, or maybe an image break; @@ -1903,8 +2117,8 @@ long wxRichTextCtrl::FindNextWordPosition(int direction) const while (i < endPos && i > -1) { // i is in character, not caret positions - wxString text = GetBuffer().GetTextForRange(wxRichTextRange(i, i)); - wxRichTextLine* line = GetBuffer().GetLineAtPosition(i, false); + wxString text = GetFocusObject()->GetTextForRange(wxRichTextRange(i, i)); + wxRichTextLine* line = GetFocusObject()->GetLineAtPosition(i, false); if (line && line->GetAbsoluteRange().GetStart() == i) return i-1; @@ -1927,7 +2141,7 @@ bool wxRichTextCtrl::WordLeft(int WXUNUSED(n), int flags) long pos = FindNextWordPosition(-1); if (pos != m_caretPosition) { - wxRichTextParagraph* para = GetBuffer().GetParagraphAtPosition(pos, true); + wxRichTextParagraph* para = GetFocusObject()->GetParagraphAtPosition(pos, true); bool extendSel = ExtendSelection(m_caretPosition, pos, flags); if (!extendSel) @@ -1949,7 +2163,7 @@ bool wxRichTextCtrl::WordRight(int WXUNUSED(n), int flags) long pos = FindNextWordPosition(1); if (pos != m_caretPosition) { - wxRichTextParagraph* para = GetBuffer().GetParagraphAtPosition(pos, true); + wxRichTextParagraph* para = GetFocusObject()->GetParagraphAtPosition(pos, true); bool extendSel = ExtendSelection(m_caretPosition, pos, flags); if (!extendSel) @@ -1969,7 +2183,7 @@ bool wxRichTextCtrl::WordRight(int WXUNUSED(n), int flags) void wxRichTextCtrl::OnSize(wxSizeEvent& event) { // Only do sizing optimization for large buffers - if (GetBuffer().GetRange().GetEnd() > m_delayedLayoutThreshold) + if (GetBuffer().GetOwnRange().GetEnd() > m_delayedLayoutThreshold) { m_fullLayoutRequired = true; m_fullLayoutTime = wxGetLocalTimeMillis(); @@ -2176,7 +2390,7 @@ bool wxRichTextCtrl::DoSaveFile(const wxString& filename, int fileType) /// Add a new paragraph of text to the end of the buffer wxRichTextRange wxRichTextCtrl::AddParagraph(const wxString& text) { - wxRichTextRange range = GetBuffer().AddParagraph(text); + wxRichTextRange range = GetFocusObject()->AddParagraph(text); LayoutContent(); return range; } @@ -2184,7 +2398,7 @@ wxRichTextRange wxRichTextCtrl::AddParagraph(const wxString& text) /// Add an image wxRichTextRange wxRichTextCtrl::AddImage(const wxImage& image) { - wxRichTextRange range = GetBuffer().AddImage(image); + wxRichTextRange range = GetFocusObject()->AddImage(image); LayoutContent(); return range; } @@ -2201,15 +2415,17 @@ void wxRichTextCtrl::SelectAll() /// Select none void wxRichTextCtrl::SelectNone() { - if (!(GetSelectionRange() == wxRichTextRange(-2, -2))) + if (m_selection.IsValid()) { - wxRichTextRange oldSelection = m_selectionRange; + wxRichTextSelection oldSelection = m_selection; - m_selectionRange = wxRichTextRange(-2, -2); + m_selection.Reset(); - RefreshForSelectionChange(oldSelection, m_selectionRange); + RefreshForSelectionChange(oldSelection, m_selection); } m_selectionAnchor = -2; + m_selectionAnchorObject = NULL; + m_selectionState = wxRichTextCtrlSelectionState_Normal; } static bool wxIsWordDelimiter(const wxString& text) @@ -2220,10 +2436,10 @@ static bool wxIsWordDelimiter(const wxString& text) /// Select the word at the given character position bool wxRichTextCtrl::SelectWord(long position) { - if (position < 0 || position > GetBuffer().GetRange().GetEnd()) + if (position < 0 || position > GetFocusObject()->GetOwnRange().GetEnd()) return false; - wxRichTextParagraph* para = GetBuffer().GetParagraphAtPosition(position); + wxRichTextParagraph* para = GetFocusObject()->GetParagraphAtPosition(position); if (!para) return false; @@ -2235,7 +2451,7 @@ bool wxRichTextCtrl::SelectWord(long position) for (positionStart = position; positionStart >= para->GetRange().GetStart(); positionStart --) { - wxString text = GetBuffer().GetTextForRange(wxRichTextRange(positionStart, positionStart)); + wxString text = GetFocusObject()->GetTextForRange(wxRichTextRange(positionStart, positionStart)); if (wxIsWordDelimiter(text)) { positionStart ++; @@ -2247,7 +2463,7 @@ bool wxRichTextCtrl::SelectWord(long position) for (positionEnd = position; positionEnd < para->GetRange().GetEnd(); positionEnd ++) { - wxString text = GetBuffer().GetTextForRange(wxRichTextRange(positionEnd, positionEnd)); + wxString text = GetFocusObject()->GetTextForRange(wxRichTextRange(positionEnd, positionEnd)); if (wxIsWordDelimiter(text)) { positionEnd --; @@ -2311,7 +2527,9 @@ wxRichTextCtrl::HitTest(const wxPoint& pt, // so convert wxPoint pt2 = GetLogicalPoint(pt); - int hit = ((wxRichTextCtrl*)this)->GetBuffer().HitTest(dc, pt2, *pos); + wxRichTextObject* hitObj = NULL; + wxRichTextObject* contextObj = NULL; + int hit = ((wxRichTextCtrl*)this)->GetFocusObject()->HitTest(dc, pt2, *pos, & hitObj, & contextObj, wxRICHTEXT_HITTEST_NO_NESTED_OBJECTS); if ((hit & wxRICHTEXT_HITTEST_BEFORE) && (hit & wxRICHTEXT_HITTEST_OUTSIDE)) return wxTE_HT_BEFORE; @@ -2335,18 +2553,19 @@ wxString wxRichTextCtrl::DoGetValue() const wxString wxRichTextCtrl::GetRange(long from, long to) const { // Public API for range is different from internals - return GetBuffer().GetTextForRange(wxRichTextRange(from, to-1)); + return GetFocusObject()->GetTextForRange(wxRichTextRange(from, to-1)); } void wxRichTextCtrl::DoSetValue(const wxString& value, int flags) { // Don't call Clear here, since it always sends a text updated event m_buffer.ResetAndClearCommands(); - m_buffer.SetDirty(true); + m_buffer.Invalidate(wxRICHTEXT_ALL); m_caretPosition = -1; m_caretPositionForDefaultStyle = -2; m_caretAtLineStart = false; - m_selectionRange.SetRange(-2, -2); + m_selection.Reset(); + m_selectionState = wxRichTextCtrlSelectionState_Normal; Scroll(0,0); @@ -2383,7 +2602,7 @@ void wxRichTextCtrl::DoWriteText(const wxString& value, int flags) { wxString valueUnix = wxTextFile::Translate(value, wxTextFileType_Unix); - GetBuffer().InsertTextWithUndo(m_caretPosition+1, valueUnix, this, wxRICHTEXT_INSERT_WITH_PREVIOUS_PARAGRAPH_STYLE); + GetFocusObject()->InsertTextWithUndo(m_caretPosition+1, valueUnix, this, & GetBuffer(), wxRICHTEXT_INSERT_WITH_PREVIOUS_PARAGRAPH_STYLE); if ( flags & SetValue_SendEvent ) wxTextCtrl::SendTextUpdatedEvent(this); @@ -2421,7 +2640,7 @@ bool wxRichTextCtrl::WriteImage(const wxString& filename, wxBitmapType bitmapTyp bool wxRichTextCtrl::WriteImage(const wxRichTextImageBlock& imageBlock, const wxRichTextAttr& textAttr) { - return GetBuffer().InsertImageWithUndo(m_caretPosition+1, imageBlock, this, NULL, textAttr); + return GetFocusObject()->InsertImageWithUndo(m_caretPosition+1, imageBlock, this, & GetBuffer(), 0, textAttr); } bool wxRichTextCtrl::WriteImage(const wxBitmap& bitmap, wxBitmapType bitmapType, const wxRichTextAttr& textAttr) @@ -2438,10 +2657,59 @@ bool wxRichTextCtrl::WriteImage(const wxBitmap& bitmap, wxBitmapType bitmapType, return false; } +// Write a text box at the current insertion point. +wxRichTextBox* wxRichTextCtrl::WriteTextBox(const wxRichTextAttr& textAttr) +{ + wxRichTextBox* textBox = new wxRichTextBox; + textBox->SetAttributes(textAttr); + textBox->SetParent(& GetBuffer()); // set parent temporarily for AddParagraph to use correct style + textBox->AddParagraph(wxEmptyString); + textBox->SetParent(NULL); + + // The object returned is the one actually inserted into the buffer, + // while the original one is deleted. + wxRichTextObject* obj = GetFocusObject()->InsertObjectWithUndo(m_caretPosition+1, textBox, this, & GetBuffer(), wxRICHTEXT_INSERT_WITH_PREVIOUS_PARAGRAPH_STYLE); + wxRichTextBox* box = wxDynamicCast(obj, wxRichTextBox); + return box; +} + +// Write a table at the current insertion point, returning the table. +wxRichTextTable* wxRichTextCtrl::WriteTable(int rows, int cols, const wxRichTextAttr& tableAttr, const wxRichTextAttr& cellAttr) +{ + wxASSERT(rows > 0 && cols > 0); + + if (rows <= 0 || cols <= 0) + return NULL; + + wxRichTextTable* table = new wxRichTextTable; + table->SetAttributes(tableAttr); + table->SetParent(& GetBuffer()); // set parent temporarily for AddParagraph to use correct style + + table->CreateTable(rows, cols); + + table->SetParent(NULL); + + int i, j; + for (j = 0; j < rows; j++) + { + for (i = 0; i < cols; i++) + { + table->GetCell(j, i)->GetAttributes() = cellAttr; + } + } + + // The object returned is the one actually inserted into the buffer, + // while the original one is deleted. + wxRichTextObject* obj = GetFocusObject()->InsertObjectWithUndo(m_caretPosition+1, table, this, & GetBuffer(), wxRICHTEXT_INSERT_WITH_PREVIOUS_PARAGRAPH_STYLE); + wxRichTextTable* tableResult = wxDynamicCast(obj, wxRichTextTable); + return tableResult; +} + + /// Insert a newline (actually paragraph) at the current insertion point. bool wxRichTextCtrl::Newline() { - return GetBuffer().InsertNewlineWithUndo(m_caretPosition+1, this, wxRICHTEXT_INSERT_WITH_PREVIOUS_PARAGRAPH_STYLE); + return GetFocusObject()->InsertNewlineWithUndo(m_caretPosition+1, this, & GetBuffer(), wxRICHTEXT_INSERT_WITH_PREVIOUS_PARAGRAPH_STYLE); } /// Insert a line break at the current insertion point. @@ -2449,7 +2717,7 @@ bool wxRichTextCtrl::LineBreak() { wxString text; text = wxRichTextLineBreakChar; - return GetBuffer().InsertTextWithUndo(m_caretPosition+1, text, this); + return GetFocusObject()->InsertTextWithUndo(m_caretPosition+1, text, this, & GetBuffer()); } // ---------------------------------------------------------------------------- @@ -2503,7 +2771,12 @@ void wxRichTextCtrl::DeleteSelection() bool wxRichTextCtrl::HasSelection() const { - return m_selectionRange.GetStart() != -2 && m_selectionRange.GetEnd() != -2; + return (m_selection.IsValid() && m_selection.GetContainer() == GetFocusObject()); +} + +bool wxRichTextCtrl::HasUnfocusedSelection() const +{ + return m_selection.IsValid(); } bool wxRichTextCtrl::CanCopy() const @@ -2571,17 +2844,24 @@ long wxRichTextCtrl::GetInsertionPoint() const wxTextPos wxRichTextCtrl::GetLastPosition() const { - return GetBuffer().GetRange().GetEnd(); + return GetFocusObject()->GetOwnRange().GetEnd(); } // If the return values from and to are the same, there is no // selection. void wxRichTextCtrl::GetSelection(long* from, long* to) const { - *from = m_selectionRange.GetStart(); - *to = m_selectionRange.GetEnd(); - if ((*to) != -1 && (*to) != -2) + if (m_selection.IsValid()) + { + *from = m_selection.GetRange().GetStart(); + *to = m_selection.GetRange().GetEnd(); (*to) ++; + } + else + { + *from = -2; + *to = -2; + } } bool wxRichTextCtrl::IsEditable() const @@ -2609,13 +2889,15 @@ void wxRichTextCtrl::SetSelection(long from, long to) } else { - wxRichTextRange oldSelection = m_selectionRange; + wxRichTextSelection oldSelection = m_selection; + m_selectionAnchor = from-1; - m_selectionRange.SetRange(from, to-1); + m_selectionAnchorObject = NULL; + m_selection.Set(wxRichTextRange(from, to-1), GetFocusObject()); m_caretPosition = wxMax(-1, to-1); - RefreshForSelectionChange(oldSelection, m_selectionRange); + RefreshForSelectionChange(oldSelection, m_selection); PositionCaret(); } } @@ -2640,7 +2922,7 @@ void wxRichTextCtrl::Remove(long from, long to) { SelectNone(); - GetBuffer().DeleteRangeWithUndo(wxRichTextRange(from, to-1), this); + GetFocusObject()->DeleteRangeWithUndo(wxRichTextRange(from, to-1), this, & GetBuffer()); LayoutContent(); if (!IsFrozen()) @@ -2666,7 +2948,7 @@ void wxRichTextCtrl::DiscardEdits() int wxRichTextCtrl::GetNumberOfLines() const { - return GetBuffer().GetParagraphCount(); + return GetFocusObject()->GetParagraphCount(); } // ---------------------------------------------------------------------------- @@ -2675,12 +2957,12 @@ int wxRichTextCtrl::GetNumberOfLines() const long wxRichTextCtrl::XYToPosition(long x, long y) const { - return GetBuffer().XYToPosition(x, y); + return GetFocusObject()->XYToPosition(x, y); } bool wxRichTextCtrl::PositionToXY(long pos, long *x, long *y) const { - return GetBuffer().PositionToXY(pos, x, y); + return GetFocusObject()->PositionToXY(pos, x, y); } // ---------------------------------------------------------------------------- @@ -2695,12 +2977,12 @@ void wxRichTextCtrl::ShowPosition(long pos) int wxRichTextCtrl::GetLineLength(long lineNo) const { - return GetBuffer().GetParagraphLength(lineNo); + return GetFocusObject()->GetParagraphLength(lineNo); } wxString wxRichTextCtrl::GetLineText(long lineNo) const { - return GetBuffer().GetParagraphText(lineNo); + return GetFocusObject()->GetParagraphText(lineNo); } // ---------------------------------------------------------------------------- @@ -2834,16 +3116,23 @@ void wxRichTextCtrl::OnUpdateSelectAll(wxUpdateUIEvent& event) event.Enable(GetLastPosition() > 0); } -void wxRichTextCtrl::OnImage(wxCommandEvent& WXUNUSED(event)) +void wxRichTextCtrl::OnProperties(wxCommandEvent& event) { - if (GetCurrentObject() && GetCurrentObject()->CanEditProperties()) - GetCurrentObject()->EditProperties(this, & GetBuffer()); - SetCurrentObject(NULL); + int idx = event.GetId() - wxID_RICHTEXT_PROPERTIES1; + if (idx >= 0 && idx < m_contextMenuPropertiesInfo.GetCount()) + { + wxRichTextObject* obj = m_contextMenuPropertiesInfo.GetObject(idx); + if (obj && obj->CanEditProperties()) + obj->EditProperties(this, & GetBuffer()); + + m_contextMenuPropertiesInfo.Clear(); + } } -void wxRichTextCtrl::OnUpdateImage(wxUpdateUIEvent& event) +void wxRichTextCtrl::OnUpdateProperties(wxUpdateUIEvent& event) { - event.Enable(GetCurrentObject() != NULL && GetCurrentObject()->CanEditProperties()); + int idx = event.GetId() - wxID_RICHTEXT_PROPERTIES1; + event.Enable(idx >= 0 && idx < m_contextMenuPropertiesInfo.GetCount()); } void wxRichTextCtrl::OnContextMenu(wxContextMenuEvent& event) @@ -2861,44 +3150,63 @@ void wxRichTextCtrl::OnContextMenu(wxContextMenuEvent& event) long position = 0; wxPoint pt = event.GetPosition(); wxPoint logicalPt = GetLogicalPoint(ScreenToClient(pt)); - int hit = GetBuffer().HitTest(dc, logicalPt, position); + wxRichTextObject* hitObj = NULL; + wxRichTextObject* contextObj = NULL; + int hit = GetFocusObject()->HitTest(dc, logicalPt, position, & hitObj, & contextObj); + + m_contextMenuPropertiesInfo.Clear(); + if (hit == wxRICHTEXT_HITTEST_ON || hit == wxRICHTEXT_HITTEST_BEFORE || hit == wxRICHTEXT_HITTEST_AFTER) { - m_currentObject = GetBuffer().GetLeafObjectAtPosition(position); + wxRichTextParagraphLayoutBox* actualContainer = wxDynamicCast(contextObj, wxRichTextParagraphLayoutBox); + if (hitObj && actualContainer) + { + if (actualContainer->AcceptsFocus()) + { + SetFocusObject(actualContainer, false /* don't set caret position yet */); + SetCaretPositionAfterClick(actualContainer, position, hit); + } + + m_contextMenuPropertiesInfo.AddItems(actualContainer, hitObj); + } + else + m_contextMenuPropertiesInfo.AddItems(GetFocusObject(), NULL); } else { - m_currentObject = NULL; + m_contextMenuPropertiesInfo.AddItems(GetFocusObject(), NULL); } if (m_contextMenu) + { + m_contextMenuPropertiesInfo.AddMenuItems(m_contextMenu); PopupMenu(m_contextMenu); - return; + } } bool wxRichTextCtrl::SetStyle(long start, long end, const wxTextAttr& style) { - return GetBuffer().SetStyle(wxRichTextRange(start, end-1), wxRichTextAttr(style)); + return GetFocusObject()->SetStyle(wxRichTextRange(start, end-1), wxRichTextAttr(style)); } bool wxRichTextCtrl::SetStyle(long start, long end, const wxRichTextAttr& style) { - return GetBuffer().SetStyle(wxRichTextRange(start, end-1), style); + return GetFocusObject()->SetStyle(wxRichTextRange(start, end-1), style); } bool wxRichTextCtrl::SetStyle(const wxRichTextRange& range, const wxTextAttr& style) { - return GetBuffer().SetStyle(range.ToInternal(), wxRichTextAttr(style)); + return GetFocusObject()->SetStyle(range.ToInternal(), wxRichTextAttr(style)); } bool wxRichTextCtrl::SetStyle(const wxRichTextRange& range, const wxRichTextAttr& style) { - return GetBuffer().SetStyle(range.ToInternal(), style); + return GetFocusObject()->SetStyle(range.ToInternal(), style); } -void wxRichTextCtrl::SetImageStyle(wxRichTextImage *image, const wxRichTextAttr& textAttr) +void wxRichTextCtrl::SetStyle(wxRichTextObject *obj, const wxRichTextAttr& textAttr) { - GetBuffer().SetImageStyle(image, textAttr); + GetFocusObject()->SetStyle(obj, textAttr); } // extended style setting operation with flags including: @@ -2907,7 +3215,7 @@ void wxRichTextCtrl::SetImageStyle(wxRichTextImage *image, const wxRichTextAttr& bool wxRichTextCtrl::SetStyleEx(const wxRichTextRange& range, const wxRichTextAttr& style, int flags) { - return GetBuffer().SetStyle(range.ToInternal(), style, flags); + return GetFocusObject()->SetStyle(range.ToInternal(), style, flags); } bool wxRichTextCtrl::SetDefaultStyle(const wxTextAttr& style) @@ -2917,7 +3225,9 @@ bool wxRichTextCtrl::SetDefaultStyle(const wxTextAttr& style) bool wxRichTextCtrl::SetDefaultStyle(const wxRichTextAttr& style) { - return GetBuffer().SetDefaultStyle(style); + wxRichTextAttr attr1(style); + attr1.GetTextBoxAttr().Reset(); + return GetBuffer().SetDefaultStyle(attr1); } const wxRichTextAttr& wxRichTextCtrl::GetDefaultStyleEx() const @@ -2928,7 +3238,7 @@ const wxRichTextAttr& wxRichTextCtrl::GetDefaultStyleEx() const bool wxRichTextCtrl::GetStyle(long position, wxTextAttr& style) { wxRichTextAttr attr; - if (GetBuffer().GetStyle(position, attr)) + if (GetFocusObject()->GetStyle(position, attr)) { style = attr; return true; @@ -2939,14 +3249,26 @@ bool wxRichTextCtrl::GetStyle(long position, wxTextAttr& style) bool wxRichTextCtrl::GetStyle(long position, wxRichTextAttr& style) { - return GetBuffer().GetStyle(position, style); + return GetFocusObject()->GetStyle(position, style); +} + +bool wxRichTextCtrl::GetStyle(long position, wxRichTextAttr& style, wxRichTextParagraphLayoutBox* container) +{ + wxRichTextAttr attr; + if (container->GetStyle(position, attr)) + { + style = attr; + return true; + } + else + return false; } // get the common set of styles for the range bool wxRichTextCtrl::GetStyleForRange(const wxRichTextRange& range, wxTextAttr& style) { wxRichTextAttr attr; - if (GetBuffer().GetStyleForRange(range.ToInternal(), attr)) + if (GetFocusObject()->GetStyleForRange(range.ToInternal(), attr)) { style = attr; return true; @@ -2957,13 +3279,24 @@ bool wxRichTextCtrl::GetStyleForRange(const wxRichTextRange& range, wxTextAttr& bool wxRichTextCtrl::GetStyleForRange(const wxRichTextRange& range, wxRichTextAttr& style) { - return GetBuffer().GetStyleForRange(range.ToInternal(), style); + return GetFocusObject()->GetStyleForRange(range.ToInternal(), style); +} + +bool wxRichTextCtrl::GetStyleForRange(const wxRichTextRange& range, wxRichTextAttr& style, wxRichTextParagraphLayoutBox* container) +{ + return container->GetStyleForRange(range.ToInternal(), style); } /// Get the content (uncombined) attributes for this position. bool wxRichTextCtrl::GetUncombinedStyle(long position, wxRichTextAttr& style) { - return GetBuffer().GetUncombinedStyle(position, style); + return GetFocusObject()->GetUncombinedStyle(position, style); +} + +/// Get the content (uncombined) attributes for this position. +bool wxRichTextCtrl::GetUncombinedStyle(long position, wxRichTextAttr& style, wxRichTextParagraphLayoutBox* container) +{ + return container->GetUncombinedStyle(position, style); } /// Set font, and also the buffer attributes @@ -3000,7 +3333,7 @@ wxPoint wxRichTextCtrl::GetLogicalPoint(const wxPoint& ptPhysical) const } /// Position the caret -void wxRichTextCtrl::PositionCaret() +void wxRichTextCtrl::PositionCaret(wxRichTextParagraphLayoutBox* container) { if (!GetCaret()) return; @@ -3008,7 +3341,7 @@ void wxRichTextCtrl::PositionCaret() //wxLogDebug(wxT("PositionCaret")); wxRect caretRect; - if (GetCaretPositionForIndex(GetCaretPosition(), caretRect)) + if (GetCaretPositionForIndex(GetCaretPosition(), caretRect, container)) { wxPoint newPt = caretRect.GetPosition(); wxSize newSz = caretRect.GetSize(); @@ -3022,7 +3355,10 @@ void wxRichTextCtrl::PositionCaret() int halfSize = newSz.y/2; // If the caret is beyond the margin, hide it by moving it out of the way if (((pt.y + halfSize) < GetBuffer().GetTopMargin()) || ((pt.y + halfSize) > (GetClientSize().y - GetBuffer().GetBottomMargin()))) + { + pt.x = -200; pt.y = -200; + } GetCaret()->Move(pt); GetCaret()->Show(); @@ -3031,7 +3367,7 @@ void wxRichTextCtrl::PositionCaret() } /// Get the caret height and position for the given character position -bool wxRichTextCtrl::GetCaretPositionForIndex(long position, wxRect& rect) +bool wxRichTextCtrl::GetCaretPositionForIndex(long position, wxRect& rect, wxRichTextParagraphLayoutBox* container) { wxClientDC dc(this); dc.SetFont(GetFont()); @@ -3040,8 +3376,11 @@ bool wxRichTextCtrl::GetCaretPositionForIndex(long position, wxRect& rect) wxPoint pt; int height = 0; + + if (!container) + container = GetFocusObject(); - if (GetBuffer().FindPosition(dc, position, pt, & height, m_caretAtLineStart)) + if (container->FindPosition(dc, position, pt, & height, m_caretAtLineStart)) { // Caret height can't be zero if (height == 0) @@ -3060,8 +3399,8 @@ bool wxRichTextCtrl::GetCaretPositionForIndex(long position, wxRect& rect) /// if this is the case. wxRichTextLine* wxRichTextCtrl::GetVisibleLineForCaretPosition(long caretPosition) const { - wxRichTextLine* line = GetBuffer().GetLineAtPosition(caretPosition, true); - wxRichTextParagraph* para = GetBuffer().GetParagraphAtPosition(caretPosition, true); + wxRichTextLine* line = GetFocusObject()->GetLineAtPosition(caretPosition, true); + wxRichTextParagraph* para = GetFocusObject()->GetParagraphAtPosition(caretPosition, true); if (line) { wxRichTextRange lineRange = line->GetAbsoluteRange(); @@ -3069,7 +3408,7 @@ wxRichTextLine* wxRichTextCtrl::GetVisibleLineForCaretPosition(long caretPositio (para->GetRange().GetStart() != lineRange.GetStart())) { if (!m_caretAtLineStart) - line = GetBuffer().GetLineAtPosition(caretPosition-1, true); + line = GetFocusObject()->GetLineAtPosition(caretPosition-1, true); } } return line; @@ -3077,16 +3416,19 @@ wxRichTextLine* wxRichTextCtrl::GetVisibleLineForCaretPosition(long caretPositio /// Move the caret to the given character position -bool wxRichTextCtrl::MoveCaret(long pos, bool showAtLineStart) +bool wxRichTextCtrl::MoveCaret(long pos, bool showAtLineStart, wxRichTextParagraphLayoutBox* container) { - if (GetBuffer().GetDirty()) + if (GetBuffer().IsDirty()) LayoutContent(); - if (pos <= GetBuffer().GetRange().GetEnd()) + if (!container) + container = GetFocusObject(); + + if (pos <= container->GetOwnRange().GetEnd()) { SetCaretPosition(pos, showAtLineStart); - PositionCaret(); + PositionCaret(container); return true; } @@ -3098,7 +3440,7 @@ bool wxRichTextCtrl::MoveCaret(long pos, bool showAtLineStart) /// setting the caret position. bool wxRichTextCtrl::LayoutContent(bool onlyVisibleRect) { - if (GetBuffer().GetDirty() || onlyVisibleRect) + if (GetBuffer().IsDirty() || onlyVisibleRect) { wxRect availableSpace(GetClientSize()); if (availableSpace.width == 0) @@ -3121,7 +3463,7 @@ bool wxRichTextCtrl::LayoutContent(bool onlyVisibleRect) GetBuffer().Defragment(); GetBuffer().UpdateRanges(); // If items were deleted, ranges need recalculation GetBuffer().Layout(dc, availableSpace, flags); - GetBuffer().SetDirty(false); + GetBuffer().Invalidate(wxRICHTEXT_NONE); if (!IsFrozen()) SetupScrollbars(); @@ -3298,7 +3640,7 @@ bool wxRichTextCtrl::ApplyAlignmentToSelection(wxTextAttrAlignment alignment) return SetStyle(GetSelectionRange(), attr); else { - wxRichTextParagraph* para = GetBuffer().GetParagraphAtPosition(GetCaretPosition()+1); + wxRichTextParagraph* para = GetFocusObject()->GetParagraphAtPosition(GetCaretPosition()+1); if (para) return SetStyleEx(para->GetRange().FromInternal(), attr, wxRICHTEXT_SETSTYLE_WITH_UNDO|wxRICHTEXT_SETSTYLE_OPTIMIZE|wxRICHTEXT_SETSTYLE_PARAGRAPHS_ONLY); } @@ -3367,7 +3709,7 @@ bool wxRichTextCtrl::ApplyStyle(wxRichTextStyleDefinition* def) if (isPara) { long pos = GetAdjustedCaretPosition(GetCaretPosition()); - wxRichTextParagraph* para = GetBuffer().GetParagraphAtPosition(pos); + wxRichTextParagraph* para = GetFocusObject()->GetParagraphAtPosition(pos); if (para) { return SetStyleEx(para->GetRange().FromInternal(), attr, flags); @@ -3416,7 +3758,7 @@ bool wxRichTextCtrl::SetDefaultStyleToCursorStyle() /// Returns the first visible position in the current view long wxRichTextCtrl::GetFirstVisiblePosition() const { - wxRichTextLine* line = GetBuffer().GetLineAtYPosition(GetLogicalPoint(wxPoint(0, 0)).y); + wxRichTextLine* line = GetFocusObject()->GetLineAtYPosition(GetLogicalPoint(wxPoint(0, 0)).y); if (line) return line->GetAbsoluteRange().GetStart(); else @@ -3440,7 +3782,7 @@ wxPoint wxRichTextCtrl::GetFirstVisiblePoint() const /// style information should be taken from the next position, not current one. long wxRichTextCtrl::GetAdjustedCaretPosition(long caretPos) const { - wxRichTextParagraph* para = GetBuffer().GetParagraphAtPosition(caretPos+1); + wxRichTextParagraph* para = GetFocusObject()->GetParagraphAtPosition(caretPos+1); if (para && (caretPos+1 == para->GetRange().GetStart())) caretPos ++; @@ -3466,46 +3808,46 @@ void wxRichTextCtrl::SetSelectionRange(const wxRichTextRange& range) /// Set list style bool wxRichTextCtrl::SetListStyle(const wxRichTextRange& range, wxRichTextListStyleDefinition* def, int flags, int startFrom, int specifiedLevel) { - return GetBuffer().SetListStyle(range.ToInternal(), def, flags, startFrom, specifiedLevel); + return GetFocusObject()->SetListStyle(range.ToInternal(), def, flags, startFrom, specifiedLevel); } bool wxRichTextCtrl::SetListStyle(const wxRichTextRange& range, const wxString& defName, int flags, int startFrom, int specifiedLevel) { - return GetBuffer().SetListStyle(range.ToInternal(), defName, flags, startFrom, specifiedLevel); + return GetFocusObject()->SetListStyle(range.ToInternal(), defName, flags, startFrom, specifiedLevel); } /// Clear list for given range bool wxRichTextCtrl::ClearListStyle(const wxRichTextRange& range, int flags) { - return GetBuffer().ClearListStyle(range.ToInternal(), flags); + return GetFocusObject()->ClearListStyle(range.ToInternal(), flags); } /// Number/renumber any list elements in the given range bool wxRichTextCtrl::NumberList(const wxRichTextRange& range, wxRichTextListStyleDefinition* def, int flags, int startFrom, int specifiedLevel) { - return GetBuffer().NumberList(range.ToInternal(), def, flags, startFrom, specifiedLevel); + return GetFocusObject()->NumberList(range.ToInternal(), def, flags, startFrom, specifiedLevel); } bool wxRichTextCtrl::NumberList(const wxRichTextRange& range, const wxString& defName, int flags, int startFrom, int specifiedLevel) { - return GetBuffer().NumberList(range.ToInternal(), defName, flags, startFrom, specifiedLevel); + return GetFocusObject()->NumberList(range.ToInternal(), defName, flags, startFrom, specifiedLevel); } /// Promote the list items within the given range. promoteBy can be a positive or negative number, e.g. 1 or -1 bool wxRichTextCtrl::PromoteList(int promoteBy, const wxRichTextRange& range, wxRichTextListStyleDefinition* def, int flags, int specifiedLevel) { - return GetBuffer().PromoteList(promoteBy, range.ToInternal(), def, flags, specifiedLevel); + return GetFocusObject()->PromoteList(promoteBy, range.ToInternal(), def, flags, specifiedLevel); } bool wxRichTextCtrl::PromoteList(int promoteBy, const wxRichTextRange& range, const wxString& defName, int flags, int specifiedLevel) { - return GetBuffer().PromoteList(promoteBy, range.ToInternal(), defName, flags, specifiedLevel); + return GetFocusObject()->PromoteList(promoteBy, range.ToInternal(), defName, flags, specifiedLevel); } /// Deletes the content in the given range bool wxRichTextCtrl::Delete(const wxRichTextRange& range) { - return GetBuffer().DeleteRangeWithUndo(range.ToInternal(), this); + return GetFocusObject()->DeleteRangeWithUndo(range.ToInternal(), this, & GetBuffer()); } const wxArrayString& wxRichTextCtrl::GetAvailableFontNames() @@ -3536,32 +3878,53 @@ void wxRichTextCtrl::OnSysColourChanged(wxSysColourChangedEvent& WXUNUSED(event) } // Refresh the area affected by a selection change -bool wxRichTextCtrl::RefreshForSelectionChange(const wxRichTextRange& oldSelection, const wxRichTextRange& newSelection) +bool wxRichTextCtrl::RefreshForSelectionChange(const wxRichTextSelection& oldSelection, const wxRichTextSelection& newSelection) { + // If the selection is not part of the focus object, or we have multiple ranges, then the chances are that + // the selection contains whole containers rather than just text, so refresh everything + // for now as it would be hard to compute the rectangle bounding all selections. + // TODO: improve on this. + if ((oldSelection.IsValid() && (oldSelection.GetContainer() != GetFocusObject() || oldSelection.GetCount() > 1)) || + (newSelection.IsValid() && (newSelection.GetContainer() != GetFocusObject() || newSelection.GetCount() > 1))) + { + Refresh(false); + return true; + } + + wxRichTextRange oldRange, newRange; + if (oldSelection.IsValid()) + oldRange = oldSelection.GetRange(); + else + oldRange = wxRICHTEXT_NO_SELECTION; + if (newSelection.IsValid()) + newRange = newSelection.GetRange(); + else + newRange = wxRICHTEXT_NO_SELECTION; + // Calculate the refresh rectangle - just the affected lines long firstPos, lastPos; - if (oldSelection.GetStart() == -2 && newSelection.GetStart() != -2) + if (oldRange.GetStart() == -2 && newRange.GetStart() != -2) { - firstPos = newSelection.GetStart(); - lastPos = newSelection.GetEnd(); + firstPos = newRange.GetStart(); + lastPos = newRange.GetEnd(); } - else if (oldSelection.GetStart() != -2 && newSelection.GetStart() == -2) + else if (oldRange.GetStart() != -2 && newRange.GetStart() == -2) { - firstPos = oldSelection.GetStart(); - lastPos = oldSelection.GetEnd(); + firstPos = oldRange.GetStart(); + lastPos = oldRange.GetEnd(); } - else if (oldSelection.GetStart() == -2 && newSelection.GetStart() == -2) + else if (oldRange.GetStart() == -2 && newRange.GetStart() == -2) { return false; } else { - firstPos = wxMin(oldSelection.GetStart(), newSelection.GetStart()); - lastPos = wxMax(oldSelection.GetEnd(), newSelection.GetEnd()); + firstPos = wxMin(oldRange.GetStart(), newRange.GetStart()); + lastPos = wxMax(oldRange.GetEnd(), newRange.GetEnd()); } - wxRichTextLine* firstLine = GetBuffer().GetLineAtPosition(firstPos); - wxRichTextLine* lastLine = GetBuffer().GetLineAtPosition(lastPos); + wxRichTextLine* firstLine = GetFocusObject()->GetLineAtPosition(firstPos); + wxRichTextLine* lastLine = GetFocusObject()->GetLineAtPosition(lastPos); if (firstLine && lastLine) { @@ -3583,6 +3946,62 @@ bool wxRichTextCtrl::RefreshForSelectionChange(const wxRichTextRange& oldSelecti return true; } +// margins functions +bool wxRichTextCtrl::DoSetMargins(const wxPoint& pt) +{ + GetBuffer().GetAttributes().GetTextBoxAttr().GetMargins().GetLeft().SetValue(pt.x, wxTEXT_ATTR_UNITS_PIXELS); + GetBuffer().GetAttributes().GetTextBoxAttr().GetMargins().GetRight().SetValue(pt.x, wxTEXT_ATTR_UNITS_PIXELS); + GetBuffer().GetAttributes().GetTextBoxAttr().GetMargins().GetTop().SetValue(pt.y, wxTEXT_ATTR_UNITS_PIXELS); + GetBuffer().GetAttributes().GetTextBoxAttr().GetMargins().GetBottom().SetValue(pt.y, wxTEXT_ATTR_UNITS_PIXELS); + + return true; +} + +wxPoint wxRichTextCtrl::DoGetMargins() const +{ + return wxPoint(GetBuffer().GetAttributes().GetTextBoxAttr().GetMargins().GetLeft().GetValue(), + GetBuffer().GetAttributes().GetTextBoxAttr().GetMargins().GetTop().GetValue()); +} + +bool wxRichTextCtrl::SetFocusObject(wxRichTextParagraphLayoutBox* obj, bool setCaretPosition) +{ + if (obj && !obj->AcceptsFocus()) + return false; + + wxRichTextParagraphLayoutBox* oldContainer = GetFocusObject(); + bool changingContainer = (m_focusObject != obj); + + m_focusObject = obj; + + if (!obj) + m_focusObject = & m_buffer; + + if (setCaretPosition && changingContainer) + { + m_selection.Reset(); + m_selectionAnchor = -2; + m_selectionAnchorObject = NULL; + m_selectionState = wxRichTextCtrlSelectionState_Normal; + + long pos = -1; + + m_caretAtLineStart = false; + MoveCaret(pos, m_caretAtLineStart); + SetDefaultStyleToCursorStyle(); + + wxRichTextEvent cmdEvent( + wxEVT_COMMAND_RICHTEXT_FOCUS_OBJECT_CHANGED, + GetId()); + cmdEvent.SetEventObject(this); + cmdEvent.SetPosition(m_caretPosition+1); + cmdEvent.SetOldContainer(oldContainer); + cmdEvent.SetContainer(m_focusObject); + + GetEventHandler()->ProcessEvent(cmdEvent); + } + return true; +} + #if wxRICHTEXT_USE_OWN_CARET // ---------------------------------------------------------------------------- @@ -3724,5 +4143,107 @@ void wxRichTextCaretTimer::Notify() #endif // wxRICHTEXT_USE_OWN_CARET +// Add an item +bool wxRichTextContextMenuPropertiesInfo::AddItem(const wxString& label, wxRichTextObject* obj) +{ + if (GetCount() < 3) + { + m_labels.Add(label); + m_objects.Add(obj); + return true; + } + else + return false; +} + +// Returns number of menu items were added. +int wxRichTextContextMenuPropertiesInfo::AddMenuItems(wxMenu* menu, int startCmd) const +{ + wxMenuItem* item = menu->FindItem(startCmd); + // If none of the standard properties identifiers are in the menu, assume it's + // a custom menu without properties commands, and don't add them. + if (item) + { + // If no items, to add just set the text to something generic + if (GetCount() == 0) + { + menu->SetLabel(startCmd, _("&Properties")); + + // Delete the others if necessary + int i; + for (i = startCmd+1; i < startCmd+3; i++) + { + if (menu->FindItem(i)) + { + menu->Delete(i); + } + } + } + else + { + int i; + int pos = -1; + // Find the position of the first properties item + for (i = 0; i < (int) menu->GetMenuItemCount(); i++) + { + wxMenuItem* item = menu->FindItemByPosition(i); + if (item && item->GetId() == startCmd) + { + pos = i; + break; + } + } + + if (pos != -1) + { + int insertBefore = pos+1; + for (i = startCmd; i < startCmd+GetCount(); i++) + { + if (menu->FindItem(i)) + { + menu->SetLabel(i, m_labels[i - startCmd]); + } + else + { + if (insertBefore >= (int) menu->GetMenuItemCount()) + menu->Append(i, m_labels[i - startCmd]); + else + menu->Insert(insertBefore, i, m_labels[i - startCmd]); + } + insertBefore ++; + } + + // Delete any old items still left on the menu + for (i = startCmd + GetCount(); i < startCmd+3; i++) + { + if (menu->FindItem(i)) + { + menu->Delete(i); + } + } + } + } + } + + return GetCount(); +} + +// Add appropriate menu items for the current container and clicked on object +// (and container's parent, if appropriate). +int wxRichTextContextMenuPropertiesInfo::AddItems(wxRichTextObject* container, wxRichTextObject* obj) +{ + Clear(); + if (obj && obj->CanEditProperties()) + AddItem(obj->GetPropertiesMenuLabel(), obj); + + if (container && container != obj && container->CanEditProperties() && m_labels.Index(container->GetPropertiesMenuLabel()) == wxNOT_FOUND) + AddItem(container->GetPropertiesMenuLabel(), container); + + if (container && container->GetParent() && container->GetParent()->CanEditProperties() && m_labels.Index(container->GetParent()->GetPropertiesMenuLabel()) == wxNOT_FOUND) + AddItem(container->GetParent()->GetPropertiesMenuLabel(), container->GetParent()); + + return GetCount(); +} + #endif // wxUSE_RICHTEXT diff --git a/src/richtext/richtextdialogs.pjd b/src/richtext/richtextdialogs.pjd index 0811abab63..d41fafa388 100644 --- a/src/richtext/richtextdialogs.pjd +++ b/src/richtext/richtextdialogs.pjd @@ -23,7 +23,7 @@ 0 0 "<All platforms>" - "<Any>" + "2.9.0" "Standard" "///////////////////////////////////////////////////////////////////////////// // Name: %HEADER-FILENAME% @@ -61,16 +61,9 @@ ///////////////////////////////////////////////////////////////////////////// " - "#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) -#pragma interface "%HEADER-FILENAME%" -#endif - + " " - "#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) -#pragma implementation "%HEADER-FILENAME%" -#endif - -// For compilers that support precompilation, includes "wx/wx.h". + "// For compilers that support precompilation, includes "wx/wx.h". #include "wx/wxprec.h" #ifdef __BORLANDC__ @@ -243,7 +236,7 @@ "ID_RICHTEXTFONTPAGE" 10000 "wxRichTextFontPage" - "wxPanel" + "wxRichTextDialogPage" "wxPanel" "richtextfontpage.cpp" "../../include/wx/richtext/richtextfontpage.h" @@ -2165,7 +2158,7 @@ "ID_RICHTEXTINDENTSSPACINGPAGE" 10100 "wxRichTextIndentsSpacingPage" - "wxPanel" + "wxRichTextDialogPage" "wxPanel" "richtextindentspage.cpp" "../../include/wx/richtext/richtextindentspage.h" @@ -4697,7 +4690,7 @@ "ID_RICHTEXTTABSPAGE" 10200 "wxRichTextTabsPage" - "wxPanel" + "wxRichTextDialogPage" "wxPanel" "richtexttabspage.cpp" "../../include/wx/richtext/richtexttabspage.h" @@ -5439,7 +5432,7 @@ "ID_RICHTEXTBULLETSPAGE" 10300 "wxRichTextBulletsPage" - "wxPanel" + "wxRichTextDialogPage" "wxPanel" "richtextbulletspage.cpp" "../../include/wx/richtext/richtextbulletspage.h" @@ -7127,7 +7120,7 @@ "ID_RICHTEXTSTYLEPAGE" 10403 "wxRichTextStylePage" - "wxPanel" + "wxRichTextDialogPage" "wxPanel" "richtextstylepage.cpp" "../../include/wx/richtext/richtextstylepage.h" @@ -7248,7 +7241,7 @@ "wbBoxSizerProxy" "Horizontal" "" - "Centre" + "Expand" "Centre" 0 5 @@ -7275,7 +7268,7 @@ "" "Centre" "Expand" - 0 + 1 5 0 0 @@ -7560,7 +7553,7 @@ "" -1 -1 - -1 + 300 -1 "Expand" "Centre" @@ -7697,7 +7690,7 @@ "" -1 -1 - -1 + 300 -1 "Expand" "Centre" @@ -8744,7 +8737,7 @@ - "wxBoxSizer H" + "wxStdDialogButtonSizer" "dialog-control-document" "" "sizer" @@ -8752,38 +8745,83 @@ 1 0 0 - "28/11/2007" - "wbBoxSizerProxy" - "Horizontal" - "" + "wbStdDialogButtonSizerProxy" + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 0 + "m_stdButtonSizer" "Expand" "Centre" 0 5 0 0 - 0 - 0 + 1 + 1 0 0 0 "<Any platform>" - "Spacer" + "wxButton: wxID_OK" "dialog-control-document" "" - "spacer" + "dialogcontrol" 0 1 0 - 0 - "28/11/2007" - "wbSpacerProxy" - 5 - 5 + 1 + "wbButtonProxy" + "wxEVT_UPDATE_UI|OnOkUpdate|NONE||wxSymbolPickerDialog" + "wxID_OK" + 5100 + "" + "wxButton" + "wxButton" + 1 + 0 + "" + "" + "" + "Insert" + 1 + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + -1 + -1 "Centre" "Centre" - 1 + 0 5 1 1 @@ -8792,173 +8830,138 @@ 0 0 0 - "<Any platform>" + "" + "" - "wxStdDialogButtonSizer" + "wxButton: wxID_CANCEL" "dialog-control-document" "" - "sizer" + "dialogcontrol" 0 1 0 - 0 - "28/11/2007" - "wbStdDialogButtonSizerProxy" - 1 - 1 - 0 - 0 - 0 - 0 - 0 - 0 + 1 + "wbButtonProxy" + "wxID_CANCEL" + 5101 + "" + "wxButton" + "wxButton" + 1 + 0 + "" + "" "" + "Close" + 0 + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + -1 + -1 "Centre" "Centre" 0 5 - 0 - 0 + 1 + 1 1 1 0 0 0 + "" + "" + + + "wxButton: wxID_HELP" + "dialog-control-document" + "" + "dialogcontrol" + 0 + 1 + 0 + 1 + "wbButtonProxy" + "wxID_HELP" + 5009 + "" + "wxButton" + "wxButton" + 1 + 0 + "" + "" + "" + "&Help" + 0 + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + 0 + 1 "<Any platform>" - - "wxButton: wxID_OK" - "dialog-control-document" - "" - "dialogcontrol" - 0 - 1 - 0 - 1 - "28/11/2007" - "wbButtonProxy" - "wxEVT_UPDATE_UI|OnOkUpdate|NONE||wxSymbolPickerDialog" - "wxID_OK" - 5100 - "" - "wxButton" - "wxButton" - 1 - 0 - "" - "" - "" - "Insert" - 1 - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - 0 - 1 - "<Any platform>" - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - "" - -1 - -1 - -1 - -1 - "Centre" - "Centre" - 0 - 5 - 1 - 1 - 1 - 1 - 0 - 0 - 0 - "" - "" - - - "wxButton: wxID_CANCEL" - "dialog-control-document" - "" - "dialogcontrol" - 0 - 1 - 0 - 1 - "28/11/2007" - "wbButtonProxy" - "wxID_CANCEL" - 5101 - "" - "wxButton" - "wxButton" - 1 - 0 - "" - "" - "" - "Close" - 0 - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - 0 - 1 - "<Any platform>" - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - "" - -1 - -1 - -1 - -1 - "Centre" - "Centre" - 0 - 5 - 1 - 1 - 1 - 1 - 0 - 0 - 0 - "" - "" - + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + -1 + -1 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" @@ -10236,18 +10239,24 @@ "" - "Spacer" + "wxStdDialogButtonSizer" "dialog-control-document" "" - "spacer" + "sizer" 0 1 0 0 - "18/10/2006" - "wbSpacerProxy" - 5 - 5 + "wbStdDialogButtonSizerProxy" + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 0 + "m_stdButtonSizer" "Centre" "Centre" 1 @@ -10260,138 +10269,201 @@ 0 0 "<Any platform>" - - - "wxButton: wxID_OK" - "dialog-control-document" - "" - "dialogcontrol" - 0 - 1 - 0 - 0 - "18/10/2006" - "wbButtonProxy" - "wxID_OK" - 5100 - "" - "wxButton" - "wxButton" - 1 - 0 - "" - "" - "m_okButton" - "OK" - 1 - "Click to confirm your selection." - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - 0 - 1 - "<Any platform>" - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - "" - -1 - -1 - -1 - -1 - "Expand" - "Centre" - 0 - 5 - 1 - 1 - 1 - 1 - 0 - 0 - 0 - "" - "" - - - "wxButton: wxID_CANCEL" - "dialog-control-document" - "" - "dialogcontrol" - 0 - 1 - 0 - 0 - "18/10/2006" - "wbButtonProxy" - "wxID_CANCEL" - 5101 - "" - "wxButton" - "wxButton" - 1 - 0 - "" - "" - "m_cancelButton" - "Cancel" - 0 - "Click to cancel this window." - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - 0 - 1 - "<Any platform>" - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - "" - -1 - -1 - -1 - -1 - "Expand" - "Centre" - 0 - 5 - 1 - 1 - 1 - 1 - 0 - 0 - 0 - "" - "" + + "wxButton: wxID_OK" + "dialog-control-document" + "" + "dialogcontrol" + 0 + 1 + 0 + 1 + "wbButtonProxy" + "wxID_OK" + 5100 + "" + "wxButton" + "wxButton" + 1 + 0 + "" + "" + "m_okButton" + "OK" + 0 + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + -1 + -1 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "wxButton: wxID_CANCEL" + "dialog-control-document" + "" + "dialogcontrol" + 0 + 1 + 0 + 1 + "wbButtonProxy" + "wxID_CANCEL" + 5101 + "" + "wxButton" + "wxButton" + 1 + 0 + "" + "" + "m_cancelButton" + "Cancel" + 0 + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + -1 + -1 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "wxButton: wxID_HELP" + "dialog-control-document" + "" + "dialogcontrol" + 0 + 1 + 0 + 1 + "wbButtonProxy" + "wxID_HELP" + 5009 + "" + "wxButton" + "wxButton" + 1 + 0 + "" + "" + "" + "&Help" + 0 + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + -1 + -1 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + @@ -10419,7 +10491,7 @@ "ID_RICHTEXTLISTSTYLEPAGE" 10616 "wxRichTextListStylePage" - "wxPanel" + "wxRichTextDialogPage" "wxPanel" "richtextliststylepage.cpp" "../../include/wx/richtext/richtextliststylepage.h" @@ -14600,7 +14672,7 @@ - "wxRichTextImageDialog" + "wxRichTextObjectPropertiesDialog" "dialog-document" "" "dialog" @@ -14609,7 +14681,7 @@ 0 0 "wbDialogProxy" - 10000 + 10650 0 "" 0 @@ -14617,15 +14689,15 @@ "Standard" 0 0 - "ID_WXRICHTEXTIMAGEPAGE" - 10015 - "wxRichTextImageDialog" - "wxDialog" + "ID_RICHTEXTOBJECTPROPERTIESDIALOG" + 10650 + "wxRichTextObjectPropertiesDialog" + "wxRichTextFormattingDialog" "wxDialog" "richtextimagedlg.cpp" "../../include/wx/richtext/richtextimagedlg.h" "" - "Image Properties" + "Object Properties" 1 "" 0 @@ -14678,6 +14750,111 @@ 300 0 "" + + "wxBoxSizer V" + "dialog-control-document" + "" + "sizer" + 0 + 1 + 0 + 0 + "wbBoxSizerProxy" + "Vertical" + "" + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "<Any platform>" + + + + "wxRichTextSizePage" + "dialog-document" + "" + "dialog" + 0 + 1 + 0 + 0 + "wbDialogProxy" + 10700 + 0 + "" + 0 + "" + "Standard" + 0 + 0 + "ID_WXRICHTEXTSIZEPAGE" + 10700 + "wxRichTextSizePage" + "wxRichTextDialogPage" + "wxPanel" + "richtextsizepage.cpp" + "../../include/wx/richtext/richtextsizepage.h" + "" + "" + 1 + "" + 0 + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "Tiled" + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + "" + 0 + 1 + -1 + -1 + 400 + 300 + 0 + "" "wxBoxSizer V" "dialog-control-document" @@ -14695,7 +14872,7 @@ 0 "<Any platform>" - "wxBoxSizer H" + "wxBoxSizer V" "dialog-control-document" "" "sizer" @@ -14704,8 +14881,8 @@ 0 0 "wbBoxSizerProxy" - "Horizontal" - "" + "Vertical" + "m_parentSizer" "Expand" "Centre" 0 @@ -14719,7 +14896,7 @@ 0 "<Any platform>" - "wxFlexGridSizer" + "wxBoxSizer V" "dialog-control-document" "" "sizer" @@ -14727,230 +14904,21 @@ 1 0 0 - "wbFlexGridSizerProxy" - "" - "" - 2 - 0 - 0 - 0 - "" - "<Any platform>" - "Centre" - "Top" + "wbBoxSizerProxy" + "Vertical" + "m_floatingControls" + "Expand" + "Centre" 0 5 0 - 1 + 0 0 0 0 0 0 - - "wxStaticText: wxID_STATIC" - "dialog-control-document" - "" - "statictext" - 0 - 1 - 0 - 0 - "wbStaticTextProxy" - "wxID_STATIC" - 5105 - "" - "wxStaticText" - "wxStaticText" - 1 - 0 - "" - "" - "" - "&Floating mode:" - -1 - "" - "" - "" - "" - "" - 0 - 1 - "<Any platform>" - "" - "" - "" - "" - "" - "" - "" - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - "" - -1 - -1 - -1 - -1 - "Right" - "Centre" - 0 - 5 - 1 - 1 - 1 - 1 - 0 - 0 - 0 - "" - "" - - - "wxComboBox: ID_RICHTEXTIMAGEDIALOG_FLOATING_MODE" - "dialog-control-document" - "" - "combobox" - 0 - 1 - 0 - 0 - "wbComboBoxProxy" - "ID_RICHTEXTIMAGEDIALOG_FLOATING_MODE" - 10017 - "" - "wxComboBox" - "wxComboBox" - 1 - 0 - "" - "" - "m_float" - "None|Left|Right" - "None" - "How the image will float relative to the text." - "" - "" - "" - "" - 0 - 1 - "<Any platform>" - "" - "" - "" - "" - "" - "" - "" - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 0 - "" - -1 - -1 - 80 - -1 - "Left" - "Centre" - 0 - 5 - 1 - 1 - 1 - 1 - 0 - 0 - 0 - "" - "" - - - "wxStaticText: wxID_STATIC" - "dialog-control-document" - "" - "statictext" - 0 - 1 - 0 - 0 - "wbStaticTextProxy" - "wxID_STATIC" - 5105 - "" - "wxStaticText" - "wxStaticText" - 1 - 0 - "" - "" - "" - "&Width:" - -1 - "" - "" - "" - "" - "" - 0 - 1 - "<Any platform>" - "" - "" - "" - "" - "" - "" - "" - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - "" - -1 - -1 - -1 - -1 - "Right" - "Centre" - 0 - 5 - 1 - 1 - 1 - 1 - 0 - 0 - 0 - "" - "" - + "<Any platform>" "wxBoxSizer H" "dialog-control-document" @@ -14963,7 +14931,7 @@ "wbBoxSizerProxy" "Horizontal" "" - "Left" + "Expand" "Centre" 0 5 @@ -14976,753 +14944,35 @@ 0 "<Any platform>" - "wxTextCtrl: ID_RICHTEXTIMAGEDIALOG_WIDTH" + "wxStaticText: wxID_STATIC" "dialog-control-document" "" - "textctrl" + "statictext" 0 1 0 0 - "wbTextCtrlProxy" - "ID_RICHTEXTIMAGEDIALOG_WIDTH" - 10018 + "wbStaticTextProxy" + "wxID_STATIC" + 5105 "" - "wxTextCtrl" - "wxTextCtrl" - 1 - 0 - "" - "" - "m_width" - "" - 0 - "The image width to be shown - does not change the source image width." - "" - "" - "" - "" - 0 - 1 - "<Any platform>" - "" - "" - "" - "" - "" - "" - "" - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - "" - -1 - -1 - 65 - -1 - "Left" - "Centre" - 0 - 5 - 1 - 1 - 1 - 1 - 0 - 0 - 0 - "" - "" - - - "wxComboBox: ID_RICHTEXTIMAGEDIALOG_UNITS_W" - "dialog-control-document" - "" - "combobox" - 0 - 1 - 0 - 0 - "wbComboBoxProxy" - "ID_RICHTEXTIMAGEDIALOG_UNITS_W" - 10019 - "" - "wxComboBox" - "wxComboBox" - 1 - 0 - "" - "" - "m_unitsW" - "px|cm" - "px" - "Units for the image width." - "" - "" - "" - "" - 0 - 1 - "<Any platform>" - "" - "" - "" - "" - "" - "" - "" - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 0 - "" - -1 - -1 - 60 - -1 - "Centre" - "Centre" - 0 - 5 - 1 - 1 - 1 - 1 - 0 - 0 - 0 - "" - "" - - - - "wxStaticText: wxID_STATIC" - "dialog-control-document" - "" - "statictext" - 0 - 1 - 0 - 0 - "wbStaticTextProxy" - "wxID_STATIC" - 5105 - "" - "wxStaticText" - "wxStaticText" - 1 - 0 - "" - "" - "" - "&Height:" - -1 - "" - "" - "" - "" - "" - 0 - 1 - "<Any platform>" - "" - "" - "" - "" - "" - "" - "" - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - "" - -1 - -1 - -1 - -1 - "Right" - "Centre" - 0 - 5 - 1 - 1 - 1 - 1 - 0 - 0 - 0 - "" - "" - - - "wxBoxSizer H" - "dialog-control-document" - "" - "sizer" - 0 - 1 - 0 - 0 - "wbBoxSizerProxy" - "Horizontal" - "" - "Left" - "Centre" - 0 - 5 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - "<Any platform>" - - "wxTextCtrl: ID_RICHTEXTIMAGEDIALOG_HEIGHT" - "dialog-control-document" - "" - "textctrl" - 0 - 1 - 0 - 0 - "wbTextCtrlProxy" - "ID_RICHTEXTIMAGEDIALOG_HEIGHT" - 10020 - "" - "wxTextCtrl" - "wxTextCtrl" - 1 - 0 - "" - "" - "m_height" - "" - 0 - "The image height to be shown - does not change the source image height." - "" - "" - "" - "" - 0 - 1 - "<Any platform>" - "" - "" - "" - "" - "" - "" - "" - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - "" - -1 - -1 - 65 - -1 - "Left" - "Centre" - 0 - 5 - 1 - 1 - 1 - 1 - 0 - 0 - 0 - "" - "" - - - "wxComboBox: ID_RICHTEXTIMAGEDIALOG_UNITS_H" - "dialog-control-document" - "" - "combobox" - 0 - 1 - 0 - 0 - "wbComboBoxProxy" - "ID_RICHTEXTIMAGEDIALOG_UNITS_H" - 10021 - "" - "wxComboBox" - "wxComboBox" - 1 - 0 - "" - "" - "m_unitsH" - "px|cm" - "px" - "Units for the image height." - "" - "" - "" - "" - 0 - 1 - "<Any platform>" - "" - "" - "" - "" - "" - "" - "" - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 0 - "" - -1 - -1 - 60 - -1 - "Centre" - "Centre" - 0 - 5 - 1 - 1 - 1 - 1 - 0 - 0 - 0 - "" - "" - - - - "wxStaticText: wxID_STATIC" - "dialog-control-document" - "" - "statictext" - 0 - 1 - 0 - 0 - "wbStaticTextProxy" - "wxID_STATIC" - 5105 - "" - "wxStaticText" - "wxStaticText" - 1 - 0 - "" - "" - "" - "Image Vertical &Offset:" - -1 - "" - "" - "" - "" - "" - 0 - 1 - "<Any platform>" - "" - "" - "" - "" - "" - "" - "" - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - "" - -1 - -1 - -1 - -1 - "Right" - "Centre" - 0 - 5 - 1 - 1 - 1 - 1 - 0 - 0 - 0 - "" - "" - - - "wxBoxSizer H" - "dialog-control-document" - "" - "sizer" - 0 - 1 - 0 - 0 - "wbBoxSizerProxy" - "Horizontal" - "" - "Left" - "Centre" - 1 - 5 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - "<Any platform>" - - "wxTextCtrl: ID_RICHTEXTIMAGEDIALOG_OFFSET" - "dialog-control-document" - "" - "textctrl" - 0 - 1 - 0 - 0 - "wbTextCtrlProxy" - "ID_RICHTEXTIMAGEDIALOG_OFFSET" - 10022 - "" - "wxTextCtrl" - "wxTextCtrl" - 1 - 0 - "" - "" - "m_offset" - "" - 10 - "The vertical offset relative to the paragraph." - "" - "" - "" - "" - 0 - 1 - "<Any platform>" - "" - "" - "" - "" - "" - "" - "" - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - "" - -1 - -1 - 65 - -1 - "Centre" - "Centre" - 0 - 5 - 1 - 1 - 1 - 1 - 0 - 0 - 0 - "" - "" - - - "wxComboBox: ID_RICHTEXTIMAGEDIALOG_OFFSET_UNITS" - "dialog-control-document" - "" - "combobox" - 0 - 1 - 0 - 0 - "wbComboBoxProxy" - "ID_RICHTEXTIMAGEDIALOG_OFFSET_UNITS" - 10023 - "" - "wxComboBox" - "wxComboBox" - 1 - 0 - "" - "" - "m_unitsOffset" - "px|cm" - "px" - "Units for the image offset." - "" - "" - "" - "" - 0 - 1 - "<Any platform>" - "" - "" - "" - "" - "" - "" - "" - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 0 - "" - -1 - -1 - 60 - -1 - "Centre" - "Centre" - 0 - 5 - 1 - 1 - 1 - 1 - 0 - 0 - 0 - "" - "" - - - - "wxStaticText: wxID_STATIC" - "dialog-control-document" - "" - "statictext" - 0 - 1 - 0 - 0 - "wbStaticTextProxy" - "wxID_STATIC" - 5105 - "" - "wxStaticText" - "wxStaticText" - 1 - 0 - "" - "" - "" - "&Move the image to:" - -1 - "" - "" - "" - "" - "" - 0 - 1 - "<Any platform>" - "" - "" - "" - "" - "" - "" - "" - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - "" - -1 - -1 - -1 - -1 - "Right" - "Centre" - 0 - 5 - 1 - 1 - 1 - 1 - 0 - 0 - 0 - "" - "" - - - "wxBoxSizer H" - "dialog-control-document" - "" - "sizer" - 0 - 1 - 0 - 0 - "wbBoxSizerProxy" - "Horizontal" - "" - "Left" - "Centre" - 0 - 5 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - "<Any platform>" - - "wxButton: ID_RICHTEXTIMAGEDIALOG_PARA_UP" - "dialog-control-document" - "" - "dialogcontrol" - 0 - 1 - 0 - 0 - "wbButtonProxy" - "wxEVT_COMMAND_BUTTON_CLICKED|OnRichtextimagedialogParaUpClick|NONE||wxRichTextImageDialog" - "ID_RICHTEXTIMAGEDIALOG_PARA_UP" - 10024 - "" - "wxButton" - "wxButton" + "wxStaticText" + "wxStaticText" 1 0 "" "" "" - "&Previous Paragraph" - 0 - "Moves the image to the previous paragraph." + "Floating" + -1 + "" "" + "" + "" + "wxSYS_DEFAULT_GUI_FONT:default,default,default, wxBOLD, false" + 0 + 1 + "<Any platform>" "" "" "" @@ -15730,18 +14980,17 @@ "" "" "" - "" - "" - "" - 0 - 1 - "<Any platform>" - 0 - 0 - 0 - 0 - 0 + 0 + 0 + 0 + 0 0 + 0 + 0 + 0 + 0 + 0 + 0 0 0 0 @@ -15765,49 +15014,40 @@ "" - "wxButton: ID_RICHTEXTIMAGEDIALOG_DOWN" + "wxStaticLine: wxID_STATIC" "dialog-control-document" "" - "dialogcontrol" + "staticline" 0 1 0 0 - "wbButtonProxy" - "wxEVT_COMMAND_BUTTON_CLICKED|OnRichtextimagedialogDownClick|NONE||wxRichTextImageDialog" - "ID_RICHTEXTIMAGEDIALOG_DOWN" - 10025 + "wbStaticLineProxy" + "wxID_STATIC" + 5105 "" - "wxButton" - "wxButton" + "wxStaticLine" + "wxStaticLine" 1 0 "" "" "" - "&Next Paragraph" - 0 - "Moves the image to the next paragraph." - "" - "" - "" - "" - "" - "" - "" - "" "" "" "" 0 1 "<Any platform>" - 0 - 0 - 0 - 0 - 0 + 1 + 0 0 + 0 + 0 + 0 + 0 + 0 + 0 0 0 0 @@ -15818,10 +15058,1277 @@ -1 "Centre" "Centre" + 1 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + + + + "wxBoxSizer H" + "dialog-control-document" + "" + "sizer" + 0 + 1 + 0 + 0 + "wbBoxSizerProxy" + "Horizontal" + "" + "Expand" + "Centre" + 0 + 5 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "<Any platform>" + + "Spacer" + "dialog-control-document" + "" + "spacer" + 0 + 1 + 0 + 0 + "wbSpacerProxy" + 5 + 5 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "<Any platform>" + + + "wxFlexGridSizer" + "dialog-control-document" + "" + "sizer" + 0 + 1 + 0 + 0 + "wbFlexGridSizerProxy" + "" + "" + 2 + 0 + 0 + 0 + "" + "<Any platform>" + "Expand" + "Centre" 0 5 0 1 + 0 + 0 + 0 + 0 + 0 + + "wxStaticText: wxID_STATIC" + "dialog-control-document" + "" + "statictext" + 0 + 1 + 0 + 0 + "wbStaticTextProxy" + "wxID_STATIC" + 5105 + "" + "wxStaticText" + "wxStaticText" + 1 + 0 + "" + "" + "" + "&Floating mode:" + -1 + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + -1 + -1 + "Right" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "wxComboBox: ID_RICHTEXT_FLOATING_MODE" + "dialog-control-document" + "" + "combobox" + 0 + 1 + 0 + 0 + "wbComboBoxProxy" + "ID_RICHTEXT_FLOATING_MODE" + 10701 + "" + "wxComboBox" + "wxComboBox" + 1 + 0 + "" + "" + "m_float" + "None|Left|Right" + "None" + "How the object will float relative to the text." + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + 80 + -1 + "Left" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + + + + "wxBoxSizer H" + "dialog-control-document" + "" + "sizer" + 0 + 1 + 0 + 0 + "wbBoxSizerProxy" + "Horizontal" + "" + "Expand" + "Centre" + 0 + 5 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "<Any platform>" + + "wxStaticText: wxID_STATIC" + "dialog-control-document" + "" + "statictext" + 0 + 1 + 0 + 0 + "wbStaticTextProxy" + "wxID_STATIC" + 5105 + "" + "wxStaticText" + "wxStaticText" + 1 + 0 + "" + "" + "" + "Size" + -1 + "" + "" + "" + "" + "wxSYS_DEFAULT_GUI_FONT:default,default,default, wxBOLD, false" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + -1 + -1 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "wxStaticLine: wxID_STATIC" + "dialog-control-document" + "" + "staticline" + 0 + 1 + 0 + 0 + "wbStaticLineProxy" + "wxID_STATIC" + 5105 + "" + "wxStaticLine" + "wxStaticLine" + 1 + 0 + "" + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + -1 + -1 + "Centre" + "Centre" + 1 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + + + + "wxBoxSizer H" + "dialog-control-document" + "" + "sizer" + 0 + 1 + 0 + 0 + "wbBoxSizerProxy" + "Horizontal" + "" + "Expand" + "Centre" + 0 + 5 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "<Any platform>" + + "Spacer" + "dialog-control-document" + "" + "spacer" + 0 + 1 + 0 + 0 + "wbSpacerProxy" + 5 + 5 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "<Any platform>" + + + "wxFlexGridSizer" + "dialog-control-document" + "" + "sizer" + 0 + 1 + 0 + 0 + "wbFlexGridSizerProxy" + "" + "" + 2 + 0 + 0 + 0 + "" + "<Any platform>" + "Expand" + "Centre" + 0 + 5 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + "wxCheckBox: ID_RICHTEXT_WIDTH_CHECKBOX" + "dialog-control-document" + "" + "checkbox" + 0 + 1 + 0 + 0 + "wbCheckBoxProxy" + "ID_RICHTEXT_WIDTH_CHECKBOX" + 10702 + "" + "wxCheckBox" + "wxCheckBox" + 1 + 0 + "" + "" + "m_widthCheckbox" + "&Width:" + 0 + "Enable the width value." + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + -1 + -1 + "Centre" + "Centre" + 0 + 5 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "wxBoxSizer H" + "dialog-control-document" + "" + "sizer" + 0 + 1 + 0 + 0 + "wbBoxSizerProxy" + "Horizontal" + "" + "Left" + "Centre" + 0 + 5 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "<Any platform>" + + "wxTextCtrl: ID_RICHTEXT_WIDTH" + "dialog-control-document" + "" + "textctrl" + 0 + 1 + 0 + 0 + "wbTextCtrlProxy" + "wxEVT_UPDATE_UI|OnRichtextWidthUpdate|NONE||wxRichTextSizePage" + "ID_RICHTEXT_WIDTH" + 10703 + "" + "wxTextCtrl" + "wxTextCtrl" + 1 + 0 + "" + "" + "m_width" + "" + 0 + "The object width." + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + 65 + -1 + "Left" + "Centre" + 0 + 5 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "wxComboBox: ID_RICHTEXT_UNITS_W" + "dialog-control-document" + "" + "combobox" + 0 + 1 + 0 + 0 + "wbComboBoxProxy" + "wxEVT_UPDATE_UI|OnRichtextWidthUpdate|NONE||wxRichTextSizePage" + "ID_RICHTEXT_UNITS_W" + 10704 + "" + "wxComboBox" + "wxComboBox" + 1 + 0 + "" + "" + "m_unitsW" + "px|cm" + "px" + "Units for the object width." + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + 60 + -1 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + + "wxCheckBox: ID_RICHTEXT_HEIGHT_CHECKBOX" + "dialog-control-document" + "" + "checkbox" + 0 + 1 + 0 + 0 + "wbCheckBoxProxy" + "ID_RICHTEXT_HEIGHT_CHECKBOX" + 10705 + "" + "wxCheckBox" + "wxCheckBox" + 1 + 0 + "" + "" + "m_heightCheckbox" + "&Height:" + 0 + "Enable the height value." + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + -1 + -1 + "Centre" + "Centre" + 0 + 5 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "wxBoxSizer H" + "dialog-control-document" + "" + "sizer" + 0 + 1 + 0 + 0 + "wbBoxSizerProxy" + "Horizontal" + "" + "Left" + "Centre" + 0 + 5 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "<Any platform>" + + "wxTextCtrl: ID_RICHTEXT_HEIGHT" + "dialog-control-document" + "" + "textctrl" + 0 + 1 + 0 + 0 + "wbTextCtrlProxy" + "wxEVT_UPDATE_UI|OnRichtextHeightUpdate|NONE||wxRichTextSizePage" + "ID_RICHTEXT_HEIGHT" + 10706 + "" + "wxTextCtrl" + "wxTextCtrl" + 1 + 0 + "" + "" + "m_height" + "" + 0 + "The object height." + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + 65 + -1 + "Left" + "Centre" + 0 + 5 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "wxComboBox: ID_RICHTEXT_UNITS_H" + "dialog-control-document" + "" + "combobox" + 0 + 1 + 0 + 0 + "wbComboBoxProxy" + "wxEVT_UPDATE_UI|OnRichtextHeightUpdate|NONE||wxRichTextSizePage" + "ID_RICHTEXT_UNITS_H" + 10707 + "" + "wxComboBox" + "wxComboBox" + 1 + 0 + "" + "" + "m_unitsH" + "px|cm" + "px" + "Units for the object height." + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + 60 + -1 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + + + + "wxBoxSizer V" + "dialog-control-document" + "" + "sizer" + 0 + 1 + 0 + 0 + "wbBoxSizerProxy" + "Vertical" + "m_alignmentControls" + "Expand" + "Centre" + 0 + 5 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "<Any platform>" + + "wxBoxSizer H" + "dialog-control-document" + "" + "sizer" + 0 + 1 + 0 + 0 + "wbBoxSizerProxy" + "Horizontal" + "" + "Expand" + "Centre" + 0 + 5 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "<Any platform>" + + "wxStaticText: wxID_STATIC" + "dialog-control-document" + "" + "statictext" + 0 + 1 + 0 + 0 + "wbStaticTextProxy" + "wxID_STATIC" + 5105 + "" + "wxStaticText" + "wxStaticText" + 1 + 0 + "" + "" + "" + "Alignment" + -1 + "" + "" + "" + "" + "wxSYS_DEFAULT_GUI_FONT:default,default,default, wxBOLD, false" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + -1 + -1 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "wxStaticLine: wxID_STATIC" + "dialog-control-document" + "" + "staticline" + 0 + 1 + 0 + 0 + "wbStaticLineProxy" + "wxID_STATIC" + 5105 + "" + "wxStaticLine" + "wxStaticLine" + 1 + 0 + "" + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + -1 + -1 + "Centre" + "Centre" + 1 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + + + + "wxBoxSizer H" + "dialog-control-document" + "" + "sizer" + 0 + 1 + 0 + 0 + "wbBoxSizerProxy" + "Horizontal" + "" + "Expand" + "Centre" + 0 + 5 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "<Any platform>" + + "Spacer" + "dialog-control-document" + "" + "spacer" + 0 + 1 + 0 + 0 + "wbSpacerProxy" + 5 + 5 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "<Any platform>" + + + "wxCheckBox: ID_RICHTEXT_VERTICAL_ALIGNMENT_CHECKBOX" + "dialog-control-document" + "" + "checkbox" + 0 + 1 + 0 + 0 + "wbCheckBoxProxy" + "ID_RICHTEXT_VERTICAL_ALIGNMENT_CHECKBOX" + 10708 + "" + "wxCheckBox" + "wxCheckBox" + 1 + 0 + "" + "" + "m_verticalAlignmentCheckbox" + "&Vertical alignment:" + 0 + "Enable vertical alignment." + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + -1 + -1 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "wxComboBox: ID_RICHTEXT_VERTICAL_ALIGNMENT_COMBOBOX" + "dialog-control-document" + "" + "combobox" + 0 + 1 + 0 + 0 + "wbComboBoxProxy" + "wxEVT_UPDATE_UI|OnRichtextVerticalAlignmentComboboxUpdate|NONE||wxRichTextSizePage" + "ID_RICHTEXT_VERTICAL_ALIGNMENT_COMBOBOX" + 10709 + "" + "wxComboBox" + "wxComboBox" + 1 + 0 + "" + "" + "m_verticalAlignmentComboBox" + "Top|Centred|Bottom" + "Top" + "Vertical alignment." + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + -1 + -1 + "Centre" + "Centre" + 0 + 5 + 1 + 1 1 1 0 @@ -15832,64 +16339,827 @@ + + "wxBoxSizer V" + "dialog-control-document" + "" + "sizer" + 0 + 1 + 0 + 0 + "wbBoxSizerProxy" + "Vertical" + "m_positionControls" + "Expand" + "Centre" + 0 + 5 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "<Any platform>" + + "wxBoxSizer H" + "dialog-control-document" + "" + "sizer" + 0 + 1 + 0 + 0 + "wbBoxSizerProxy" + "Horizontal" + "" + "Expand" + "Centre" + 0 + 5 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "<Any platform>" + + "wxStaticText: wxID_STATIC" + "dialog-control-document" + "" + "statictext" + 0 + 1 + 0 + 0 + "wbStaticTextProxy" + "wxID_STATIC" + 5105 + "" + "wxStaticText" + "wxStaticText" + 1 + 0 + "" + "" + "" + "Position" + -1 + "" + "" + "" + "" + "wxSYS_DEFAULT_GUI_FONT:default,default,default, wxBOLD, false" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + -1 + -1 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "wxStaticLine: wxID_STATIC" + "dialog-control-document" + "" + "staticline" + 0 + 1 + 0 + 0 + "wbStaticLineProxy" + "wxID_STATIC" + 5105 + "" + "wxStaticLine" + "wxStaticLine" + 1 + 0 + "" + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + -1 + -1 + "Centre" + "Centre" + 1 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + + + + "wxBoxSizer H" + "dialog-control-document" + "" + "sizer" + 0 + 1 + 0 + 0 + "wbBoxSizerProxy" + "Horizontal" + "" + "Expand" + "Centre" + 0 + 5 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "<Any platform>" + + "Spacer" + "dialog-control-document" + "" + "spacer" + 0 + 1 + 0 + 0 + "wbSpacerProxy" + 5 + 5 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "<Any platform>" + + + "wxBoxSizer V" + "dialog-control-document" + "" + "sizer" + 0 + 1 + 0 + 0 + "wbBoxSizerProxy" + "Vertical" + "m_moveObjectParentSizer" + "Centre" + "Top" + 0 + 5 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "<Any platform>" + + "wxBoxSizer H" + "dialog-control-document" + "" + "sizer" + 0 + 1 + 0 + 0 + "wbBoxSizerProxy" + "Horizontal" + "" + "Expand" + "Centre" + 0 + 5 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "<Any platform>" + + "wxCheckBox: ID_RICHTEXT_OFFSET_CHECKBOX" + "dialog-control-document" + "" + "checkbox" + 0 + 1 + 0 + 0 + "wbCheckBoxProxy" + "ID_RICHTEXT_OFFSET_CHECKBOX" + 10710 + "" + "wxCheckBox" + "wxCheckBox" + 1 + 0 + "" + "" + "m_offsetYCheckbox" + "Vertical &Offset:" + 0 + "Enable vertical offset." + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + -1 + -1 + "Centre" + "Centre" + 0 + 5 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "wxTextCtrl: ID_RICHTEXT_OFFSET" + "dialog-control-document" + "" + "textctrl" + 0 + 1 + 0 + 0 + "wbTextCtrlProxy" + "wxEVT_UPDATE_UI|OnRichtextOffsetUpdate|NONE||wxRichTextSizePage" + "ID_RICHTEXT_OFFSET" + 10711 + "" + "wxTextCtrl" + "wxTextCtrl" + 1 + 0 + "" + "" + "m_offset" + "" + 10 + "The vertical offset relative to the paragraph." + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + 65 + -1 + "Centre" + "Centre" + 0 + 5 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "wxComboBox: ID_RICHTEXT_OFFSET_UNITS" + "dialog-control-document" + "" + "combobox" + 0 + 1 + 0 + 0 + "wbComboBoxProxy" + "wxEVT_UPDATE_UI|OnRichtextOffsetUpdate|NONE||wxRichTextSizePage" + "ID_RICHTEXT_OFFSET_UNITS" + 10712 + "" + "wxComboBox" + "wxComboBox" + 1 + 0 + "" + "" + "m_unitsOffset" + "px|cm" + "px" + "Units for the object offset." + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + 60 + -1 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + + "wxBoxSizer H" + "dialog-control-document" + "" + "sizer" + 0 + 1 + 0 + 0 + "wbBoxSizerProxy" + "Horizontal" + "m_moveObjectSizer" + "Expand" + "Centre" + 0 + 5 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "<Any platform>" + + "wxStaticText: wxID_STATIC" + "dialog-control-document" + "" + "statictext" + 0 + 1 + 0 + 0 + "wbStaticTextProxy" + "wxID_STATIC" + 5105 + "" + "wxStaticText" + "wxStaticText" + 1 + 0 + "" + "" + "" + "&Move the object to:" + -1 + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + -1 + -1 + "Right" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "wxButton: ID_RICHTEXT_PARA_UP" + "dialog-control-document" + "" + "dialogcontrol" + 0 + 1 + 0 + 0 + "wbButtonProxy" + "wxEVT_COMMAND_BUTTON_CLICKED|OnRichtextParaUpClick|NONE||wxRichTextSizePage" + "ID_RICHTEXT_PARA_UP" + 10713 + "" + "wxButton" + "wxButton" + 1 + 0 + "" + "" + "" + "&Previous Paragraph" + 0 + "Moves the object to the previous paragraph." + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + -1 + -1 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "wxButton: ID_RICHTEXT_PARA_DOWN" + "dialog-control-document" + "" + "dialogcontrol" + 0 + 1 + 0 + 0 + "wbButtonProxy" + "wxEVT_COMMAND_BUTTON_CLICKED|OnRichtextParaDownClick|NONE||wxRichTextSizePage" + "ID_RICHTEXT_PARA_DOWN" + 10714 + "" + "wxButton" + "wxButton" + 1 + 0 + "" + "" + "" + "&Next Paragraph" + 0 + "Moves the object to the next paragraph." + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + -1 + -1 + "Centre" + "Centre" + 0 + 5 + 0 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + + + + + + + "wxRichTextMarginsPage" + "dialog-document" + "" + "dialog" + 0 + 1 + 0 + 0 + "wbDialogProxy" + 10750 + 0 + "" + 0 + "" + "Standard" + 0 + 0 + "ID_WXRICHTEXTMARGINSPAGE" + 10750 + "wxRichTextMarginsPage" + "wxRichTextDialogPage" + "wxPanel" + "richtextmarginspage.cpp" + "../../include/wx/richtext/richtextmarginspage.h" + "" + "" + 1 + "" + 0 + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "Tiled" + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + "" + 0 + 1 + -1 + -1 + 400 + 300 + 0 + "" + + "wxBoxSizer V" + "dialog-control-document" + "" + "sizer" + 0 + 1 + 0 + 0 + "wbBoxSizerProxy" + "Vertical" + "" + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "<Any platform>" - "wxStaticLine: wxID_STATIC" - "dialog-control-document" - "" - "staticline" - 0 - 1 - 0 - 0 - "wbStaticLineProxy" - "wxID_STATIC" - 5105 - "" - "wxStaticLine" - "wxStaticLine" - 1 - 0 - "" - "" - "" - "" - "" - "" - 0 - 1 - "<Any platform>" - 1 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - "" - -1 - -1 - -1 - -1 - "Expand" - "Centre" - 0 - 5 - 1 - 1 - 1 - 1 - 0 - 0 - 0 - - - "wxStdDialogButtonSizer" + "wxBoxSizer V" "dialog-control-document" "" "sizer" @@ -15897,19 +17167,12 @@ 1 0 0 - "wbStdDialogButtonSizerProxy" - 1 - 1 - 0 - 0 - 0 - 0 - 0 - 0 + "wbBoxSizerProxy" + "Vertical" "" "Expand" "Centre" - 0 + 1 5 1 1 @@ -15920,94 +17183,2612 @@ 0 "<Any platform>" - "wxButton: wxID_OK" + "wxBoxSizer H" "dialog-control-document" "" - "dialogcontrol" + "sizer" 0 1 0 - 1 - "wbButtonProxy" - "wxID_OK" - 5100 - "" - "wxButton" - "wxButton" - 1 - 0 - "" - "" - "m_saveButton" - "OK" - 0 - "Click to confirm your changes." - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - 0 - 1 - "<Any platform>" - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - "" - -1 - -1 - -1 - -1 - "Centre" + 0 + "wbBoxSizerProxy" + "Horizontal" + "" + "Expand" "Centre" 0 5 - 1 - 1 - 1 - 1 + 0 + 0 + 0 + 0 0 0 0 - "" - "" + "<Any platform>" + + "wxStaticText: wxID_STATIC" + "dialog-control-document" + "" + "statictext" + 0 + 1 + 0 + 0 + "wbStaticTextProxy" + "wxID_STATIC" + 5105 + "" + "wxStaticText" + "wxStaticText" + 1 + 0 + "" + "" + "" + "Margins" + -1 + "" + "" + "" + "" + "wxSYS_DEFAULT_GUI_FONT:default,default,default, wxBOLD, false" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + -1 + -1 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "wxStaticLine: wxID_STATIC" + "dialog-control-document" + "" + "staticline" + 0 + 1 + 0 + 0 + "wbStaticLineProxy" + "wxID_STATIC" + 5105 + "" + "wxStaticLine" + "wxStaticLine" + 1 + 0 + "" + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + -1 + -1 + "Centre" + "Centre" + 1 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + - "wxButton: wxID_CANCEL" + "wxBoxSizer H" "dialog-control-document" "" - "dialogcontrol" + "sizer" 0 1 0 - 1 - "wbButtonProxy" - "wxID_CANCEL" - 5101 + 0 + "wbBoxSizerProxy" + "Horizontal" + "" + "Expand" + "Centre" + 0 + 5 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "<Any platform>" + + "Spacer" + "dialog-control-document" + "" + "spacer" + 0 + 1 + 0 + 0 + "wbSpacerProxy" + 5 + 5 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "<Any platform>" + + + "wxFlexGridSizer" + "dialog-control-document" + "" + "sizer" + 0 + 1 + 0 + 0 + "wbFlexGridSizerProxy" + "" + "" + 4 + 0 + 0 + 0 + "" + "<Any platform>" + "Expand" + "Centre" + 0 + 5 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + "wxCheckBox: ID_RICHTEXT_LEFT_MARGIN_CHECKBOX" + "dialog-control-document" + "" + "checkbox" + 0 + 1 + 0 + 0 + "wbCheckBoxProxy" + "ID_RICHTEXT_LEFT_MARGIN_CHECKBOX" + 10751 + "" + "wxCheckBox" + "wxCheckBox" + 1 + 0 + "" + "" + "m_leftMarginCheckbox" + "&Left:" + 0 + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + -1 + -1 + "Left" + "Centre" + 0 + 5 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "wxBoxSizer H" + "dialog-control-document" + "" + "sizer" + 0 + 1 + 0 + 0 + "wbBoxSizerProxy" + "Horizontal" + "" + "Left" + "Centre" + 0 + 5 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "<Any platform>" + + "wxTextCtrl: ID_RICHTEXT_LEFT_MARGIN" + "dialog-control-document" + "" + "textctrl" + 0 + 1 + 0 + 0 + "wbTextCtrlProxy" + "wxEVT_UPDATE_UI|OnRichtextLeftMarginUpdate|NONE||wxRichTextMarginsPage" + "ID_RICHTEXT_LEFT_MARGIN" + 10752 + "" + "wxTextCtrl" + "wxTextCtrl" + 1 + 0 + "" + "" + "m_marginLeft" + "" + 0 + "The left margin size." + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + 65 + -1 + "Left" + "Centre" + 0 + 5 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "wxComboBox: ID_RICHTEXT_LEFT_MARGIN_UNITS" + "dialog-control-document" + "" + "combobox" + 0 + 1 + 0 + 0 + "wbComboBoxProxy" + "wxEVT_UPDATE_UI|OnRichtextLeftMarginUpdate|NONE||wxRichTextMarginsPage" + "ID_RICHTEXT_LEFT_MARGIN_UNITS" + 10753 + "" + "wxComboBox" + "wxComboBox" + 1 + 0 + "" + "" + "m_unitsMarginLeft" + "px|cm" + "px" + "Units for the left margin." + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + 60 + -1 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "Spacer" + "dialog-control-document" + "" + "spacer" + 0 + 1 + 0 + 0 + "wbSpacerProxy" + 5 + 5 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "<Any platform>" + + + + "wxCheckBox: ID_RICHTEXT_RIGHT_MARGIN_CHECKBOX" + "dialog-control-document" + "" + "checkbox" + 0 + 1 + 0 + 0 + "wbCheckBoxProxy" + "ID_RICHTEXT_RIGHT_MARGIN_CHECKBOX" + 10754 + "" + "wxCheckBox" + "wxCheckBox" + 1 + 0 + "" + "" + "m_rightMarginCheckbox" + "&Right:" + 0 + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + -1 + -1 + "Left" + "Centre" + 0 + 5 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "wxBoxSizer H" + "dialog-control-document" + "" + "sizer" + 0 + 1 + 0 + 0 + "wbBoxSizerProxy" + "Horizontal" + "" + "Left" + "Centre" + 0 + 5 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "<Any platform>" + + "wxTextCtrl: ID_RICHTEXT_RIGHT_MARGIN" + "dialog-control-document" + "" + "textctrl" + 0 + 1 + 0 + 0 + "wbTextCtrlProxy" + "wxEVT_UPDATE_UI|OnRichtextRightMarginUpdate|NONE||wxRichTextMarginsPage" + "ID_RICHTEXT_RIGHT_MARGIN" + 10755 + "" + "wxTextCtrl" + "wxTextCtrl" + 1 + 0 + "" + "" + "m_marginRight" + "" + 0 + "The right margin size." + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + 65 + -1 + "Left" + "Centre" + 0 + 5 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "wxComboBox: ID_RICHTEXT_RIGHT_MARGIN_UNITS" + "dialog-control-document" + "" + "combobox" + 0 + 1 + 0 + 0 + "wbComboBoxProxy" + "wxEVT_UPDATE_UI|OnRichtextRightMarginUpdate|NONE||wxRichTextMarginsPage" + "ID_RICHTEXT_RIGHT_MARGIN_UNITS" + 10756 + "" + "wxComboBox" + "wxComboBox" + 1 + 0 + "" + "" + "m_unitsMarginRight" + "px|cm" + "px" + "Units for the right margin." + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + 60 + -1 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + + "wxCheckBox: ID_RICHTEXT_TOP_MARGIN_CHECKBOX" + "dialog-control-document" + "" + "checkbox" + 0 + 1 + 0 + 0 + "wbCheckBoxProxy" + "ID_RICHTEXT_TOP_MARGIN_CHECKBOX" + 10757 + "" + "wxCheckBox" + "wxCheckBox" + 1 + 0 + "" + "" + "m_topMarginCheckbox" + "&Top:" + 0 + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + -1 + -1 + "Left" + "Centre" + 0 + 5 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "wxBoxSizer H" + "dialog-control-document" + "" + "sizer" + 0 + 1 + 0 + 0 + "wbBoxSizerProxy" + "Horizontal" + "" + "Left" + "Centre" + 0 + 5 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "<Any platform>" + + "wxTextCtrl: ID_RICHTEXT_TOP_MARGIN" + "dialog-control-document" + "" + "textctrl" + 0 + 1 + 0 + 0 + "wbTextCtrlProxy" + "wxEVT_UPDATE_UI|OnRichtextTopMarginUpdate|NONE||wxRichTextMarginsPage" + "ID_RICHTEXT_TOP_MARGIN" + 10758 + "" + "wxTextCtrl" + "wxTextCtrl" + 1 + 0 + "" + "" + "m_marginTop" + "" + 0 + "The top margin size." + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + 65 + -1 + "Left" + "Centre" + 0 + 5 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "wxComboBox: ID_RICHTEXT_TOP_MARGIN_UNITS" + "dialog-control-document" + "" + "combobox" + 0 + 1 + 0 + 0 + "wbComboBoxProxy" + "wxEVT_UPDATE_UI|OnRichtextTopMarginUpdate|NONE||wxRichTextMarginsPage" + "ID_RICHTEXT_TOP_MARGIN_UNITS" + 10759 + "" + "wxComboBox" + "wxComboBox" + 1 + 0 + "" + "" + "m_unitsMarginTop" + "px|cm" + "px" + "Units for the top margin." + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + 60 + -1 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "Spacer" + "dialog-control-document" + "" + "spacer" + 0 + 1 + 0 + 0 + "wbSpacerProxy" + 5 + 5 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "<Any platform>" + + + + "wxCheckBox: ID_RICHTEXT_BOTTOM_MARGIN_CHECKBOX" + "dialog-control-document" + "" + "checkbox" + 0 + 1 + 0 + 0 + "wbCheckBoxProxy" + "ID_RICHTEXT_BOTTOM_MARGIN_CHECKBOX" + 10760 + "" + "wxCheckBox" + "wxCheckBox" + 1 + 0 + "" + "" + "m_bottomMarginCheckbox" + "&Bottom:" + 0 + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + -1 + -1 + "Left" + "Centre" + 0 + 5 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "wxBoxSizer H" + "dialog-control-document" + "" + "sizer" + 0 + 1 + 0 + 0 + "wbBoxSizerProxy" + "Horizontal" + "" + "Left" + "Centre" + 0 + 5 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "<Any platform>" + + "wxTextCtrl: ID_RICHTEXT_BOTTOM_MARGIN" + "dialog-control-document" + "" + "textctrl" + 0 + 1 + 0 + 0 + "wbTextCtrlProxy" + "wxEVT_UPDATE_UI|OnRichtextBottomMarginUpdate|NONE||wxRichTextMarginsPage" + "ID_RICHTEXT_BOTTOM_MARGIN" + 10761 + "" + "wxTextCtrl" + "wxTextCtrl" + 1 + 0 + "" + "" + "m_marginBottom" + "" + 0 + "The bottom margin size." + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + 65 + -1 + "Left" + "Centre" + 0 + 5 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "wxComboBox: ID_RICHTEXT_BOTTOM_MARGIN_UNITS" + "dialog-control-document" + "" + "combobox" + 0 + 1 + 0 + 0 + "wbComboBoxProxy" + "wxEVT_UPDATE_UI|OnRichtextBottomMarginUpdate|NONE||wxRichTextMarginsPage" + "ID_RICHTEXT_BOTTOM_MARGIN_UNITS" + 10762 + "" + "wxComboBox" + "wxComboBox" + 1 + 0 + "" + "" + "m_unitsMarginBottom" + "px|cm" + "px" + "Units for the bottom margin." + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + 60 + -1 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + + + + "wxBoxSizer H" + "dialog-control-document" + "" + "sizer" + 0 + 1 + 0 + 0 + "wbBoxSizerProxy" + "Horizontal" + "" + "Expand" + "Centre" + 0 + 5 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "<Any platform>" + + "wxStaticText: wxID_STATIC" + "dialog-control-document" + "" + "statictext" + 0 + 1 + 0 + 0 + "wbStaticTextProxy" + "wxID_STATIC" + 5105 + "" + "wxStaticText" + "wxStaticText" + 1 + 0 + "" + "" + "" + "Padding" + -1 + "" + "" + "" + "" + "wxSYS_DEFAULT_GUI_FONT:default,default,default, wxBOLD, false" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + -1 + -1 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "wxStaticLine: wxID_STATIC" + "dialog-control-document" + "" + "staticline" + 0 + 1 + 0 + 0 + "wbStaticLineProxy" + "wxID_STATIC" + 5105 + "" + "wxStaticLine" + "wxStaticLine" + 1 + 0 + "" + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + -1 + -1 + "Centre" + "Centre" + 1 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + + + + "wxBoxSizer H" + "dialog-control-document" + "" + "sizer" + 0 + 1 + 0 + 0 + "wbBoxSizerProxy" + "Horizontal" + "" + "Expand" + "Centre" + 0 + 5 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "<Any platform>" + + "Spacer" + "dialog-control-document" + "" + "spacer" + 0 + 1 + 0 + 0 + "wbSpacerProxy" + 5 + 5 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "<Any platform>" + + + "wxFlexGridSizer" + "dialog-control-document" + "" + "sizer" + 0 + 1 + 0 + 0 + "wbFlexGridSizerProxy" + "" + "" + 4 + 0 + 0 + 0 + "" + "<Any platform>" + "Expand" + "Centre" + 0 + 5 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + "wxCheckBox: ID_RICHTEXT_LEFT_PADDING_CHECKBOX" + "dialog-control-document" + "" + "checkbox" + 0 + 1 + 0 + 0 + "wbCheckBoxProxy" + "ID_RICHTEXT_LEFT_PADDING_CHECKBOX" + 10763 + "" + "wxCheckBox" + "wxCheckBox" + 1 + 0 + "" + "" + "m_leftPaddingCheckbox" + "&Left:" + 0 + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + -1 + -1 + "Left" + "Centre" + 0 + 5 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "wxBoxSizer H" + "dialog-control-document" + "" + "sizer" + 0 + 1 + 0 + 0 + "wbBoxSizerProxy" + "Horizontal" + "" + "Left" + "Centre" + 0 + 5 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "<Any platform>" + + "wxTextCtrl: ID_RICHTEXT_LEFT_PADDING" + "dialog-control-document" + "" + "textctrl" + 0 + 1 + 0 + 0 + "wbTextCtrlProxy" + "wxEVT_UPDATE_UI|OnRichtextLeftPaddingUpdate|NONE||wxRichTextMarginsPage" + "ID_RICHTEXT_LEFT_PADDING" + 10764 + "" + "wxTextCtrl" + "wxTextCtrl" + 1 + 0 + "" + "" + "m_paddingLeft" + "" + 0 + "The left padding size." + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + 65 + -1 + "Left" + "Centre" + 0 + 5 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "wxComboBox: ID_RICHTEXT_LEFT_PADDING_UNITS" + "dialog-control-document" + "" + "combobox" + 0 + 1 + 0 + 0 + "wbComboBoxProxy" + "wxEVT_UPDATE_UI|OnRichtextLeftPaddingUpdate|NONE||wxRichTextMarginsPage" + "ID_RICHTEXT_LEFT_PADDING_UNITS" + 10765 + "" + "wxComboBox" + "wxComboBox" + 1 + 0 + "" + "" + "m_unitsPaddingLeft" + "px|cm" + "px" + "Units for the left padding." + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + 60 + -1 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "Spacer" + "dialog-control-document" + "" + "spacer" + 0 + 1 + 0 + 0 + "wbSpacerProxy" + 5 + 5 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "<Any platform>" + + + + "wxCheckBox: ID_RICHTEXT_RIGHT_PADDING_CHECKBOX" + "dialog-control-document" + "" + "checkbox" + 0 + 1 + 0 + 0 + "wbCheckBoxProxy" + "ID_RICHTEXT_RIGHT_PADDING_CHECKBOX" + 10766 + "" + "wxCheckBox" + "wxCheckBox" + 1 + 0 + "" + "" + "m_rightPaddingCheckbox" + "&Right:" + 0 + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + -1 + -1 + "Left" + "Centre" + 0 + 5 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "wxBoxSizer H" + "dialog-control-document" + "" + "sizer" + 0 + 1 + 0 + 0 + "wbBoxSizerProxy" + "Horizontal" + "" + "Left" + "Centre" + 0 + 5 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "<Any platform>" + + "wxTextCtrl: ID_RICHTEXT_RIGHT_PADDING" + "dialog-control-document" + "" + "textctrl" + 0 + 1 + 0 + 0 + "wbTextCtrlProxy" + "wxEVT_UPDATE_UI|OnRichtextRightPaddingUpdate|NONE||wxRichTextMarginsPage" + "ID_RICHTEXT_RIGHT_PADDING" + 10767 + "" + "wxTextCtrl" + "wxTextCtrl" + 1 + 0 + "" + "" + "m_paddingRight" + "" + 0 + "The right padding size." + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + 65 + -1 + "Left" + "Centre" + 0 + 5 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "wxComboBox: ID_RICHTEXT_RIGHT_PADDING_UNITS" + "dialog-control-document" + "" + "combobox" + 0 + 1 + 0 + 0 + "wbComboBoxProxy" + "wxEVT_UPDATE_UI|OnRichtextRightPaddingUpdate|NONE||wxRichTextMarginsPage" + "ID_RICHTEXT_RIGHT_PADDING_UNITS" + 10768 + "" + "wxComboBox" + "wxComboBox" + 1 + 0 + "" + "" + "m_unitsPaddingRight" + "px|cm" + "px" + "Units for the right padding." + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + 60 + -1 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + + "wxCheckBox: ID_RICHTEXT_TOP_PADDING_CHECKBOX" + "dialog-control-document" + "" + "checkbox" + 0 + 1 + 0 + 0 + "wbCheckBoxProxy" + "ID_RICHTEXT_TOP_PADDING_CHECKBOX" + 10769 + "" + "wxCheckBox" + "wxCheckBox" + 1 + 0 + "" + "" + "m_topPaddingCheckbox" + "&Top:" + 0 + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + -1 + -1 + "Left" + "Centre" + 0 + 5 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "wxBoxSizer H" + "dialog-control-document" + "" + "sizer" + 0 + 1 + 0 + 0 + "wbBoxSizerProxy" + "Horizontal" + "" + "Left" + "Centre" + 0 + 5 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "<Any platform>" + + "wxTextCtrl: ID_RICHTEXT_TOP_PADDING" + "dialog-control-document" + "" + "textctrl" + 0 + 1 + 0 + 0 + "wbTextCtrlProxy" + "wxEVT_UPDATE_UI|OnRichtextTopPaddingUpdate|NONE||wxRichTextMarginsPage" + "ID_RICHTEXT_TOP_PADDING" + 10770 + "" + "wxTextCtrl" + "wxTextCtrl" + 1 + 0 + "" + "" + "m_paddingTop" + "" + 0 + "The top padding size." + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + 65 + -1 + "Left" + "Centre" + 0 + 5 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "wxComboBox: ID_RICHTEXT_TOP_PADDING_UNITS" + "dialog-control-document" + "" + "combobox" + 0 + 1 + 0 + 0 + "wbComboBoxProxy" + "wxEVT_UPDATE_UI|OnRichtextTopPaddingUpdate|NONE||wxRichTextMarginsPage" + "ID_RICHTEXT_TOP_PADDING_UNITS" + 10771 + "" + "wxComboBox" + "wxComboBox" + 1 + 0 + "" + "" + "m_unitsPaddingTop" + "px|cm" + "px" + "Units for the top padding." + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + 60 + -1 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "Spacer" + "dialog-control-document" + "" + "spacer" + 0 + 1 + 0 + 0 + "wbSpacerProxy" + 5 + 5 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "<Any platform>" + + + + "wxCheckBox: ID_RICHTEXT_BOTTOM_PADDING_CHECKBOX" + "dialog-control-document" + "" + "checkbox" + 0 + 1 + 0 + 0 + "wbCheckBoxProxy" + "ID_RICHTEXT_BOTTOM_PADDING_CHECKBOX" + 10772 + "" + "wxCheckBox" + "wxCheckBox" + 1 + 0 + "" + "" + "m_bottomPaddingCheckbox" + "&Bottom:" + 0 + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + -1 + -1 + "Left" + "Centre" + 0 + 5 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "wxBoxSizer H" + "dialog-control-document" + "" + "sizer" + 0 + 1 + 0 + 0 + "wbBoxSizerProxy" + "Horizontal" + "" + "Left" + "Centre" + 0 + 5 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "<Any platform>" + + "wxTextCtrl: ID_RICHTEXT_BOTTOM_PADDING" + "dialog-control-document" + "" + "textctrl" + 0 + 1 + 0 + 0 + "wbTextCtrlProxy" + "wxEVT_UPDATE_UI|OnRichtextBottomPaddingUpdate|NONE||wxRichTextMarginsPage" + "ID_RICHTEXT_BOTTOM_PADDING" + 10773 + "" + "wxTextCtrl" + "wxTextCtrl" + 1 + 0 + "" + "" + "m_paddingBottom" + "" + 0 + "The bottom padding size." + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + 65 + -1 + "Left" + "Centre" + 0 + 5 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "wxComboBox: ID_RICHTEXT_BOTTOM_PADDING_UNITS" + "dialog-control-document" + "" + "combobox" + 0 + 1 + 0 + 0 + "wbComboBoxProxy" + "wxEVT_UPDATE_UI|OnRichtextBottomPaddingUpdate|NONE||wxRichTextMarginsPage" + "ID_RICHTEXT_BOTTOM_PADDING_UNITS" + 10774 + "" + "wxComboBox" + "wxComboBox" + 1 + 0 + "" + "" + "m_unitsPaddingBottom" + "px|cm" + "px" + "Units for the bottom padding." + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + 60 + -1 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + + + + + + + "wxRichTextBordersPage" + "dialog-document" + "" + "dialog" + 0 + 1 + 0 + 0 + "wbDialogProxy" + 10800 + 0 + "" + 0 + "" + "Standard" + 0 + 0 + "ID_RICHTEXTBORDERSPAGE" + 10800 + "wxRichTextBordersPage" + "wxRichTextDialogPage" + "wxPanel" + "richtextborderspage.cpp" + "../../include/wx/richtext/richtextborderspage.h" + "" + "" + 1 + "" + 0 + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "Tiled" + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 0 + 0 + "" + 0 + 1 + -1 + -1 + 400 + 300 + 0 + "" + + "wxBoxSizer V" + "dialog-control-document" + "" + "sizer" + 0 + 1 + 0 + 0 + "wbBoxSizerProxy" + "Vertical" + "" + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "<Any platform>" + + "wxBoxSizer V" + "dialog-control-document" + "" + "sizer" + 0 + 1 + 0 + 0 + "wbBoxSizerProxy" + "Vertical" + "" + "Expand" + "Centre" + 1 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "<Any platform>" + + "wxNotebook: ID_RICHTEXTBORDERSPAGE_NOTEBOOK" + "dialog-control-document" + "" + "notebook" + 0 + 1 + 0 + 0 + "wbNotebookProxy" + "ID_RICHTEXTBORDERSPAGE_NOTEBOOK" + 10801 "" - "wxButton" - "wxButton" + "wxNotebook" + "wxNotebook" 1 0 "" "" - "m_cancelButton" - "Cancel" - 0 - "Click to discard your changes." + "" + 0 + "" "" + "" + "" + "" + 0 + 1 + "<Any platform>" "" "" "" @@ -16015,27 +19796,33 @@ "" "" "" - "" - "" - "" - 0 - 1 - "<Any platform>" - 0 - 0 - 0 - 0 - 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 0 + 0 + 0 + 0 + 0 + 0 + 0 0 0 0 + 0 + 1 "" -1 -1 -1 -1 - "Centre" + "Expand" "Centre" 0 5 @@ -16048,6 +19835,4636 @@ 0 "" "" + + "wxPanel: ID_RICHTEXTBORDERSPAGE_BORDERS" + "dialog-control-document" + "" + "panel" + 0 + 1 + 0 + 0 + "wbPanelProxy" + "ID_RICHTEXTBORDERSPAGE_BORDERS" + 10802 + "" + "wxPanel" + "wxPanel" + 1 + 0 + "" + "" + "" + "Border" + "" + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "Tiled" + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 1 + 0 + "" + 1 + -1 + -1 + -1 + -1 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + "" + 0 + + "wxBoxSizer V" + "dialog-control-document" + "" + "sizer" + 0 + 1 + 0 + 0 + "wbBoxSizerProxy" + "Vertical" + "" + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "<Any platform>" + + "wxBoxSizer V" + "dialog-control-document" + "" + "sizer" + 0 + 1 + 0 + 0 + "wbBoxSizerProxy" + "Vertical" + "" + "Expand" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "<Any platform>" + + "wxBoxSizer H" + "dialog-control-document" + "" + "sizer" + 0 + 1 + 0 + 0 + "wbBoxSizerProxy" + "Horizontal" + "" + "Expand" + "Centre" + 0 + 5 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "<Any platform>" + + "wxStaticText: wxID_STATIC" + "dialog-control-document" + "" + "statictext" + 0 + 1 + 0 + 0 + "wbStaticTextProxy" + "wxID_STATIC" + 5105 + "" + "wxStaticText" + "wxStaticText" + 1 + 0 + "" + "" + "" + "Border" + -1 + "" + "" + "" + "" + "wxSYS_DEFAULT_GUI_FONT:default,default,default, wxBOLD, false" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + -1 + -1 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "wxStaticLine: wxID_STATIC" + "dialog-control-document" + "" + "staticline" + 0 + 1 + 0 + 0 + "wbStaticLineProxy" + "wxID_STATIC" + 5105 + "" + "wxStaticLine" + "wxStaticLine" + 1 + 0 + "" + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + -1 + -1 + "Centre" + "Centre" + 1 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + + + + "wxBoxSizer H" + "dialog-control-document" + "" + "sizer" + 0 + 1 + 0 + 0 + "wbBoxSizerProxy" + "Horizontal" + "" + "Expand" + "Centre" + 0 + 5 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "<Any platform>" + + "Spacer" + "dialog-control-document" + "" + "spacer" + 0 + 1 + 0 + 0 + "wbSpacerProxy" + 5 + 5 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "<Any platform>" + + + "wxFlexGridSizer" + "dialog-control-document" + "" + "sizer" + 0 + 1 + 0 + 0 + "wbFlexGridSizerProxy" + "" + "" + 2 + 0 + 0 + 0 + "" + "<Any platform>" + "Centre" + "Expand" + 0 + 5 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + "wxCheckBox: ID_RICHTEXT_BORDER_LEFT_CHECKBOX" + "dialog-control-document" + "" + "checkbox" + 0 + 1 + 0 + 0 + "wbCheckBoxProxy" + "wxEVT_COMMAND_CHECKBOX_CLICKED|OnRichtextBorderCheckboxClick|NONE||wxRichTextBordersPage" + "ID_RICHTEXT_BORDER_LEFT_CHECKBOX" + 10803 + "" + "wxCheckBox" + "wxCheckBox" + 1 + 0 + "" + "" + "m_leftBorderCheckbox" + "&Left:" + 0 + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + 0 + 0 + 1 + 1 + 0 + 0 + 0 + "" + -1 + -1 + -1 + -1 + "Left" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "wxBoxSizer H" + "dialog-control-document" + "" + "sizer" + 0 + 1 + 0 + 0 + "wbBoxSizerProxy" + "Horizontal" + "" + "Expand" + "Centre" + 0 + 5 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "<Any platform>" + + "wxTextCtrl: ID_RICHTEXT_BORDER_LEFT" + "dialog-control-document" + "" + "textctrl" + 0 + 1 + 0 + 0 + "wbTextCtrlProxy" + "wxEVT_UPDATE_UI|OnRichtextBorderLeftUpdate|NONE||wxRichTextBordersPage" + "ID_RICHTEXT_BORDER_LEFT" + 10804 + "" + "wxTextCtrl" + "wxTextCtrl" + 1 + 0 + "" + "" + "m_leftBorderWidth" + "" + 0 + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + 50 + -1 + "Centre" + "Centre" + 0 + 5 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "wxComboBox: ID_RICHTEXT_BORDER_LEFT_UNITS" + "dialog-control-document" + "" + "combobox" + 0 + 1 + 0 + 0 + "wbComboBoxProxy" + "wxEVT_UPDATE_UI|OnRichtextBorderLeftUpdate|NONE||wxRichTextBordersPage" + "ID_RICHTEXT_BORDER_LEFT_UNITS" + 10805 + "" + "wxComboBox" + "wxComboBox" + 1 + 0 + "" + "" + "m_leftBorderWidthUnits" + "px|cm" + "px" + "Units for the left border width." + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + 60 + -1 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "Spacer" + "dialog-control-document" + "" + "spacer" + 0 + 1 + 0 + 0 + "wbSpacerProxy" + 2 + 5 + "Centre" + "Centre" + 0 + 2 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "<Any platform>" + + + "wxComboBox: ID_RICHTEXT_BORDER_LEFT_STYLE" + "dialog-control-document" + "" + "combobox" + 0 + 1 + 0 + 0 + "wbComboBoxProxy" + "wxEVT_UPDATE_UI|OnRichtextBorderLeftUpdate|NONE||wxRichTextBordersPage" + "ID_RICHTEXT_BORDER_LEFT_STYLE" + 10806 + "" + "wxComboBox" + "wxComboBox" + 1 + 0 + "" + "" + "m_leftBorderStyle" + "" + "" + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + -1 + -1 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "Spacer" + "dialog-control-document" + "" + "spacer" + 0 + 1 + 0 + 0 + "wbSpacerProxy" + 2 + 5 + "Centre" + "Centre" + 0 + 2 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "<Any platform>" + + + "wxRichTextColourSwatchCtrl: ID_RICHTEXT_BORDER_LEFT_COLOUR" + "dialog-control-document" + "" + "foreign" + 0 + 1 + 0 + 0 + "wbForeignCtrlProxy" + "wxEVT_UPDATE_UI|OnRichtextBorderLeftUpdate|NONE||wxRichTextBordersPage" + "ID_RICHTEXT_BORDER_LEFT_COLOUR" + 10807 + "" + "wxRichTextColourSwatchCtrl" + "wxWindow" + 1 + 0 + "" + "" + "m_leftBorderColour" + 1 + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + 40 + 20 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + "" + + + + "wxCheckBox: ID_RICHTEXT_BORDER_RIGHT_CHECKBOX" + "dialog-control-document" + "" + "checkbox" + 0 + 1 + 0 + 0 + "wbCheckBoxProxy" + "wxEVT_COMMAND_CHECKBOX_CLICKED|OnRichtextBorderCheckboxClick|NONE||wxRichTextBordersPage" + "ID_RICHTEXT_BORDER_RIGHT_CHECKBOX" + 10808 + "" + "wxCheckBox" + "wxCheckBox" + 1 + 0 + "" + "" + "m_rightBorderCheckbox" + "&Right:" + 0 + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + 0 + 0 + 1 + 1 + 0 + 0 + 0 + "" + -1 + -1 + -1 + -1 + "Left" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "wxBoxSizer H" + "dialog-control-document" + "" + "sizer" + 0 + 1 + 0 + 0 + "wbBoxSizerProxy" + "Horizontal" + "" + "Expand" + "Centre" + 0 + 5 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "<Any platform>" + + "wxTextCtrl: ID_RICHTEXT_BORDER_RIGHT" + "dialog-control-document" + "" + "textctrl" + 0 + 1 + 0 + 0 + "wbTextCtrlProxy" + "wxEVT_UPDATE_UI|OnRichtextBorderRightUpdate|NONE||wxRichTextBordersPage" + "ID_RICHTEXT_BORDER_RIGHT" + 10809 + "" + "wxTextCtrl" + "wxTextCtrl" + 1 + 0 + "" + "" + "m_rightBorderWidth" + "" + 0 + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + 50 + -1 + "Centre" + "Centre" + 0 + 5 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "wxComboBox: ID_RICHTEXT_BORDER_RIGHT_UNITS" + "dialog-control-document" + "" + "combobox" + 0 + 1 + 0 + 0 + "wbComboBoxProxy" + "wxEVT_UPDATE_UI|OnRichtextBorderRightUpdate|NONE||wxRichTextBordersPage" + "ID_RICHTEXT_BORDER_RIGHT_UNITS" + 10810 + "" + "wxComboBox" + "wxComboBox" + 1 + 0 + "" + "" + "m_rightBorderWidthUnits" + "px|cm" + "px" + "Units for the right border width." + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + 60 + -1 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "Spacer" + "dialog-control-document" + "" + "spacer" + 0 + 1 + 0 + 0 + "wbSpacerProxy" + 2 + 5 + "Centre" + "Centre" + 0 + 2 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "<Any platform>" + + + "wxComboBox: ID_RICHTEXT_BORDER_RIGHT_STYLE" + "dialog-control-document" + "" + "combobox" + 0 + 1 + 0 + 0 + "wbComboBoxProxy" + "wxEVT_UPDATE_UI|OnRichtextBorderRightUpdate|NONE||wxRichTextBordersPage" + "ID_RICHTEXT_BORDER_RIGHT_STYLE" + 10811 + "" + "wxComboBox" + "wxComboBox" + 1 + 0 + "" + "" + "m_rightBorderStyle" + "" + "" + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + -1 + -1 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "Spacer" + "dialog-control-document" + "" + "spacer" + 0 + 1 + 0 + 0 + "wbSpacerProxy" + 2 + 5 + "Centre" + "Centre" + 0 + 2 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "<Any platform>" + + + "wxRichTextColourSwatchCtrl: ID_RICHTEXT_BORDER_RIGHT_COLOUR" + "dialog-control-document" + "" + "foreign" + 0 + 1 + 0 + 0 + "wbForeignCtrlProxy" + "wxEVT_UPDATE_UI|OnRichtextBorderRightUpdate|NONE||wxRichTextBordersPage" + "ID_RICHTEXT_BORDER_RIGHT_COLOUR" + 10812 + "" + "wxRichTextColourSwatchCtrl" + "wxWindow" + 1 + 0 + "" + "" + "m_rightBorderColour" + 1 + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + 40 + 20 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + "" + + + + "wxCheckBox: ID_RICHTEXT_BORDER_TOP_CHECKBOX" + "dialog-control-document" + "" + "checkbox" + 0 + 1 + 0 + 0 + "wbCheckBoxProxy" + "wxEVT_COMMAND_CHECKBOX_CLICKED|OnRichtextBorderCheckboxClick|NONE||wxRichTextBordersPage" + "ID_RICHTEXT_BORDER_TOP_CHECKBOX" + 10813 + "" + "wxCheckBox" + "wxCheckBox" + 1 + 0 + "" + "" + "m_topBorderCheckbox" + "&Top:" + 0 + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + 0 + 0 + 1 + 1 + 0 + 0 + 0 + "" + -1 + -1 + -1 + -1 + "Left" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "wxBoxSizer H" + "dialog-control-document" + "" + "sizer" + 0 + 1 + 0 + 0 + "wbBoxSizerProxy" + "Horizontal" + "" + "Expand" + "Centre" + 0 + 5 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "<Any platform>" + + "wxTextCtrl: ID_RICHTEXT_BORDER_TOP" + "dialog-control-document" + "" + "textctrl" + 0 + 1 + 0 + 0 + "wbTextCtrlProxy" + "wxEVT_UPDATE_UI|OnRichtextBorderTopUpdate|NONE||wxRichTextBordersPage" + "ID_RICHTEXT_BORDER_TOP" + 10814 + "" + "wxTextCtrl" + "wxTextCtrl" + 1 + 0 + "" + "" + "m_topBorderWidth" + "" + 0 + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + 50 + -1 + "Centre" + "Centre" + 0 + 5 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "wxComboBox: ID_RICHTEXT_BORDER_TOP_UNITS" + "dialog-control-document" + "" + "combobox" + 0 + 1 + 0 + 0 + "wbComboBoxProxy" + "wxEVT_UPDATE_UI|OnRichtextBorderTopUpdate|NONE||wxRichTextBordersPage" + "ID_RICHTEXT_BORDER_TOP_UNITS" + 10815 + "" + "wxComboBox" + "wxComboBox" + 1 + 0 + "" + "" + "m_topBorderWidthUnits" + "px|cm" + "px" + "Units for the top border width." + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + 60 + -1 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "Spacer" + "dialog-control-document" + "" + "spacer" + 0 + 1 + 0 + 0 + "wbSpacerProxy" + 2 + 5 + "Centre" + "Centre" + 0 + 2 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "<Any platform>" + + + "wxComboBox: ID_RICHTEXT_BORDER_TOP_STYLE" + "dialog-control-document" + "" + "combobox" + 0 + 1 + 0 + 0 + "wbComboBoxProxy" + "wxEVT_UPDATE_UI|OnRichtextBorderTopUpdate|NONE||wxRichTextBordersPage" + "ID_RICHTEXT_BORDER_TOP_STYLE" + 10816 + "" + "wxComboBox" + "wxComboBox" + 1 + 0 + "" + "" + "m_topBorderStyle" + "" + "" + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + -1 + -1 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "Spacer" + "dialog-control-document" + "" + "spacer" + 0 + 1 + 0 + 0 + "wbSpacerProxy" + 2 + 5 + "Centre" + "Centre" + 0 + 2 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "<Any platform>" + + + "wxRichTextColourSwatchCtrl: ID_RICHTEXT_BORDER_TOP_COLOUR" + "dialog-control-document" + "" + "foreign" + 0 + 1 + 0 + 0 + "wbForeignCtrlProxy" + "wxEVT_UPDATE_UI|OnRichtextBorderTopUpdate|NONE||wxRichTextBordersPage" + "ID_RICHTEXT_BORDER_TOP_COLOUR" + 10817 + "" + "wxRichTextColourSwatchCtrl" + "wxWindow" + 1 + 0 + "" + "" + "m_topBorderColour" + 1 + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + 40 + 20 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + "" + + + + "wxCheckBox: ID_RICHTEXT_BORDER_BOTTOM_CHECKBOX" + "dialog-control-document" + "" + "checkbox" + 0 + 1 + 0 + 0 + "wbCheckBoxProxy" + "wxEVT_COMMAND_CHECKBOX_CLICKED|OnRichtextBorderCheckboxClick|NONE||wxRichTextBordersPage" + "ID_RICHTEXT_BORDER_BOTTOM_CHECKBOX" + 10818 + "" + "wxCheckBox" + "wxCheckBox" + 1 + 0 + "" + "" + "m_bottomBorderCheckbox" + "&Bottom:" + 0 + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + 0 + 0 + 1 + 1 + 0 + 0 + 0 + "" + -1 + -1 + -1 + -1 + "Left" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "wxBoxSizer H" + "dialog-control-document" + "" + "sizer" + 0 + 1 + 0 + 0 + "wbBoxSizerProxy" + "Horizontal" + "" + "Expand" + "Centre" + 0 + 5 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "<Any platform>" + + "wxTextCtrl: ID_RICHTEXT_BORDER_BOTTOM" + "dialog-control-document" + "" + "textctrl" + 0 + 1 + 0 + 0 + "wbTextCtrlProxy" + "wxEVT_UPDATE_UI|OnRichtextBorderBottomUpdate|NONE||wxRichTextBordersPage" + "ID_RICHTEXT_BORDER_BOTTOM" + 10819 + "" + "wxTextCtrl" + "wxTextCtrl" + 1 + 0 + "" + "" + "m_bottomBorderWidth" + "" + 0 + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + 50 + -1 + "Centre" + "Centre" + 0 + 5 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "wxComboBox: ID_RICHTEXT_BORDER_BOTTOM_UNITS" + "dialog-control-document" + "" + "combobox" + 0 + 1 + 0 + 0 + "wbComboBoxProxy" + "wxEVT_UPDATE_UI|OnRichtextBorderBottomUpdate|NONE||wxRichTextBordersPage" + "ID_RICHTEXT_BORDER_BOTTOM_UNITS" + 10820 + "" + "wxComboBox" + "wxComboBox" + 1 + 0 + "" + "" + "m_bottomBorderWidthUnits" + "px|cm" + "px" + "Units for the bottom border width." + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + 60 + -1 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "Spacer" + "dialog-control-document" + "" + "spacer" + 0 + 1 + 0 + 0 + "wbSpacerProxy" + 2 + 5 + "Centre" + "Centre" + 0 + 2 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "<Any platform>" + + + "wxComboBox: ID_RICHTEXT_BORDER_BOTTOM_STYLE" + "dialog-control-document" + "" + "combobox" + 0 + 1 + 0 + 0 + "wbComboBoxProxy" + "wxEVT_UPDATE_UI|OnRichtextBorderBottomUpdate|NONE||wxRichTextBordersPage" + "ID_RICHTEXT_BORDER_BOTTOM_STYLE" + 10821 + "" + "wxComboBox" + "wxComboBox" + 1 + 0 + "" + "" + "m_bottomBorderStyle" + "" + "" + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + -1 + -1 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "Spacer" + "dialog-control-document" + "" + "spacer" + 0 + 1 + 0 + 0 + "wbSpacerProxy" + 2 + 5 + "Centre" + "Centre" + 0 + 2 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "<Any platform>" + + + "wxRichTextColourSwatchCtrl: ID_RICHTEXT_BORDER_BOTTOM_COLOUR" + "dialog-control-document" + "" + "foreign" + 0 + 1 + 0 + 0 + "wbForeignCtrlProxy" + "wxEVT_UPDATE_UI|OnRichtextBorderBottomUpdate|NONE||wxRichTextBordersPage" + "ID_RICHTEXT_BORDER_BOTTOM_COLOUR" + 10822 + "" + "wxRichTextColourSwatchCtrl" + "wxWindow" + 1 + 0 + "" + "" + "m_bottomBorderColour" + 1 + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + 40 + 20 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + "" + + + + + + + + + "wxPanel: ID_RICHTEXTBORDERSPAGE_OUTLINE" + "dialog-control-document" + "" + "panel" + 0 + 1 + 0 + 0 + "wbPanelProxy" + "ID_RICHTEXTBORDERSPAGE_OUTLINE" + 10823 + "" + "wxPanel" + "wxPanel" + 1 + 0 + "" + "" + "" + "Outline" + "" + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "Tiled" + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 1 + 0 + "" + 1 + -1 + -1 + -1 + -1 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + "" + 0 + + "wxBoxSizer V" + "dialog-control-document" + "" + "sizer" + 0 + 1 + 0 + 0 + "wbBoxSizerProxy" + "Vertical" + "" + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "<Any platform>" + + "wxBoxSizer V" + "dialog-control-document" + "" + "sizer" + 0 + 1 + 0 + 0 + "wbBoxSizerProxy" + "Vertical" + "" + "Expand" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "<Any platform>" + + "wxBoxSizer H" + "dialog-control-document" + "" + "sizer" + 0 + 1 + 0 + 0 + "wbBoxSizerProxy" + "Horizontal" + "" + "Expand" + "Centre" + 0 + 5 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "<Any platform>" + + "wxStaticText: wxID_STATIC" + "dialog-control-document" + "" + "statictext" + 0 + 1 + 0 + 0 + "wbStaticTextProxy" + "wxID_STATIC" + 5105 + "" + "wxStaticText" + "wxStaticText" + 1 + 0 + "" + "" + "" + "Outline" + -1 + "" + "" + "" + "" + "wxSYS_DEFAULT_GUI_FONT:default,default,default, wxBOLD, false" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + -1 + -1 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "wxStaticLine: wxID_STATIC" + "dialog-control-document" + "" + "staticline" + 0 + 1 + 0 + 0 + "wbStaticLineProxy" + "wxID_STATIC" + 5105 + "" + "wxStaticLine" + "wxStaticLine" + 1 + 0 + "" + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + -1 + -1 + "Centre" + "Centre" + 1 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + + + + "wxBoxSizer H" + "dialog-control-document" + "" + "sizer" + 0 + 1 + 0 + 0 + "wbBoxSizerProxy" + "Horizontal" + "" + "Expand" + "Centre" + 0 + 5 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "<Any platform>" + + "Spacer" + "dialog-control-document" + "" + "spacer" + 0 + 1 + 0 + 0 + "wbSpacerProxy" + 5 + 5 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "<Any platform>" + + + "wxFlexGridSizer" + "dialog-control-document" + "" + "sizer" + 0 + 1 + 0 + 0 + "wbFlexGridSizerProxy" + "" + "" + 2 + 0 + 0 + 0 + "" + "<Any platform>" + "Centre" + "Expand" + 0 + 5 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + "wxCheckBox: ID_RICHTEXT_OUTLINE_LEFT_CHECKBOX" + "dialog-control-document" + "" + "checkbox" + 0 + 1 + 0 + 0 + "wbCheckBoxProxy" + "wxEVT_COMMAND_CHECKBOX_CLICKED|OnRichtextBorderCheckboxClick|NONE||wxRichTextBordersPage" + "ID_RICHTEXT_OUTLINE_LEFT_CHECKBOX" + 10824 + "" + "wxCheckBox" + "wxCheckBox" + 1 + 0 + "" + "" + "m_leftOutlineCheckbox" + "&Left:" + 0 + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + 0 + 0 + 1 + 1 + 0 + 0 + 0 + "" + -1 + -1 + -1 + -1 + "Left" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "wxBoxSizer H" + "dialog-control-document" + "" + "sizer" + 0 + 1 + 0 + 0 + "wbBoxSizerProxy" + "Horizontal" + "" + "Expand" + "Centre" + 0 + 5 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "<Any platform>" + + "wxTextCtrl: ID_RICHTEXT_OUTLINE_LEFT" + "dialog-control-document" + "" + "textctrl" + 0 + 1 + 0 + 0 + "wbTextCtrlProxy" + "wxEVT_UPDATE_UI|OnRichtextOutlineLeftUpdate|NONE||wxRichTextBordersPage" + "ID_RICHTEXT_OUTLINE_LEFT" + 10825 + "" + "wxTextCtrl" + "wxTextCtrl" + 1 + 0 + "" + "" + "m_leftOutlineWidth" + "" + 0 + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + 50 + -1 + "Centre" + "Centre" + 0 + 5 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "wxComboBox: ID_RICHTEXT_OUTLINE_LEFT_UNITS" + "dialog-control-document" + "" + "combobox" + 0 + 1 + 0 + 0 + "wbComboBoxProxy" + "wxEVT_UPDATE_UI|OnRichtextOutlineLeftUpdate|NONE||wxRichTextBordersPage" + "ID_RICHTEXT_OUTLINE_LEFT_UNITS" + 10826 + "" + "wxComboBox" + "wxComboBox" + 1 + 0 + "" + "" + "m_leftOutlineWidthUnits" + "px|cm" + "px" + "Units for the left outline width." + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + 60 + -1 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "Spacer" + "dialog-control-document" + "" + "spacer" + 0 + 1 + 0 + 0 + "wbSpacerProxy" + 2 + 5 + "Centre" + "Centre" + 0 + 2 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "<Any platform>" + + + "wxComboBox: ID_RICHTEXT_OUTLINE_LEFT_STYLE" + "dialog-control-document" + "" + "combobox" + 0 + 1 + 0 + 0 + "wbComboBoxProxy" + "wxEVT_UPDATE_UI|OnRichtextOutlineLeftUpdate|NONE||wxRichTextBordersPage" + "ID_RICHTEXT_OUTLINE_LEFT_STYLE" + 10827 + "" + "wxComboBox" + "wxComboBox" + 1 + 0 + "" + "" + "m_leftOutlineStyle" + "" + "" + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + -1 + -1 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "Spacer" + "dialog-control-document" + "" + "spacer" + 0 + 1 + 0 + 0 + "wbSpacerProxy" + 2 + 5 + "Centre" + "Centre" + 0 + 2 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "<Any platform>" + + + "wxRichTextColourSwatchCtrl: ID_RICHTEXT_OUTLINE_LEFT_COLOUR" + "dialog-control-document" + "" + "foreign" + 0 + 1 + 0 + 0 + "wbForeignCtrlProxy" + "wxEVT_UPDATE_UI|OnRichtextOutlineLeftUpdate|NONE||wxRichTextBordersPage" + "ID_RICHTEXT_OUTLINE_LEFT_COLOUR" + 10828 + "" + "wxRichTextColourSwatchCtrl" + "wxWindow" + 1 + 0 + "" + "" + "m_leftOutlineColour" + 1 + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + 40 + 20 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + "" + + + + "wxCheckBox: ID_RICHTEXT_OUTLINE_RIGHT_CHECKBOX" + "dialog-control-document" + "" + "checkbox" + 0 + 1 + 0 + 0 + "wbCheckBoxProxy" + "wxEVT_COMMAND_CHECKBOX_CLICKED|OnRichtextBorderCheckboxClick|NONE||wxRichTextBordersPage" + "ID_RICHTEXT_OUTLINE_RIGHT_CHECKBOX" + 10829 + "" + "wxCheckBox" + "wxCheckBox" + 1 + 0 + "" + "" + "m_rightOutlineCheckbox" + "&Right:" + 0 + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + 0 + 0 + 1 + 1 + 0 + 0 + 0 + "" + -1 + -1 + -1 + -1 + "Left" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "wxBoxSizer H" + "dialog-control-document" + "" + "sizer" + 0 + 1 + 0 + 0 + "wbBoxSizerProxy" + "Horizontal" + "" + "Expand" + "Centre" + 0 + 5 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "<Any platform>" + + "wxTextCtrl: ID_RICHTEXT_OUTLINE_RIGHT" + "dialog-control-document" + "" + "textctrl" + 0 + 1 + 0 + 0 + "wbTextCtrlProxy" + "wxEVT_UPDATE_UI|OnRichtextOutlineRightUpdate|NONE||wxRichTextBordersPage" + "ID_RICHTEXT_OUTLINE_RIGHT" + 10830 + "" + "wxTextCtrl" + "wxTextCtrl" + 1 + 0 + "" + "" + "m_rightOutlineWidth" + "" + 0 + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + 50 + -1 + "Centre" + "Centre" + 0 + 5 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "wxComboBox: ID_RICHTEXT_OUTLINE_RIGHT_UNITS" + "dialog-control-document" + "" + "combobox" + 0 + 1 + 0 + 0 + "wbComboBoxProxy" + "wxEVT_UPDATE_UI|OnRichtextOutlineRightUpdate|NONE||wxRichTextBordersPage" + "ID_RICHTEXT_OUTLINE_RIGHT_UNITS" + 10831 + "" + "wxComboBox" + "wxComboBox" + 1 + 0 + "" + "" + "m_rightOutlineWidthUnits" + "px|cm" + "px" + "Units for the right outline width." + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + 60 + -1 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "Spacer" + "dialog-control-document" + "" + "spacer" + 0 + 1 + 0 + 0 + "wbSpacerProxy" + 2 + 5 + "Centre" + "Centre" + 0 + 2 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "<Any platform>" + + + "wxComboBox: ID_RICHTEXT_OUTLINE_RIGHT_STYLE" + "dialog-control-document" + "" + "combobox" + 0 + 1 + 0 + 0 + "wbComboBoxProxy" + "wxEVT_UPDATE_UI|OnRichtextOutlineRightUpdate|NONE||wxRichTextBordersPage" + "ID_RICHTEXT_OUTLINE_RIGHT_STYLE" + 10832 + "" + "wxComboBox" + "wxComboBox" + 1 + 0 + "" + "" + "m_rightOutlineStyle" + "" + "" + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + -1 + -1 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "Spacer" + "dialog-control-document" + "" + "spacer" + 0 + 1 + 0 + 0 + "wbSpacerProxy" + 2 + 5 + "Centre" + "Centre" + 0 + 2 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "<Any platform>" + + + "wxRichTextColourSwatchCtrl: ID_RICHTEXT_OUTLINE_RIGHT_COLOUR" + "dialog-control-document" + "" + "foreign" + 0 + 1 + 0 + 0 + "wbForeignCtrlProxy" + "wxEVT_UPDATE_UI|OnRichtextOutlineRightUpdate|NONE||wxRichTextBordersPage" + "ID_RICHTEXT_OUTLINE_RIGHT_COLOUR" + 10833 + "" + "wxRichTextColourSwatchCtrl" + "wxWindow" + 1 + 0 + "" + "" + "m_rightOutlineColour" + 1 + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + 40 + 20 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + "" + + + + "wxCheckBox: ID_RICHTEXT_OUTLINE_TOP_CHECKBOX" + "dialog-control-document" + "" + "checkbox" + 0 + 1 + 0 + 0 + "wbCheckBoxProxy" + "wxEVT_COMMAND_CHECKBOX_CLICKED|OnRichtextBorderCheckboxClick|NONE||wxRichTextBordersPage" + "ID_RICHTEXT_OUTLINE_TOP_CHECKBOX" + 10834 + "" + "wxCheckBox" + "wxCheckBox" + 1 + 0 + "" + "" + "m_topOutlineCheckbox" + "&Top:" + 0 + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + 0 + 0 + 1 + 1 + 0 + 0 + 0 + "" + -1 + -1 + -1 + -1 + "Left" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "wxBoxSizer H" + "dialog-control-document" + "" + "sizer" + 0 + 1 + 0 + 0 + "wbBoxSizerProxy" + "Horizontal" + "" + "Expand" + "Centre" + 0 + 5 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "<Any platform>" + + "wxTextCtrl: ID_RICHTEXT_OUTLINE_TOP" + "dialog-control-document" + "" + "textctrl" + 0 + 1 + 0 + 0 + "wbTextCtrlProxy" + "wxEVT_UPDATE_UI|OnRichtextOutlineTopUpdate|NONE||wxRichTextBordersPage" + "ID_RICHTEXT_OUTLINE_TOP" + 10835 + "" + "wxTextCtrl" + "wxTextCtrl" + 1 + 0 + "" + "" + "m_topOutlineWidth" + "" + 0 + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + 50 + -1 + "Centre" + "Centre" + 0 + 5 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "wxComboBox: ID_RICHTEXT_OUTLINE_TOP_UNITS" + "dialog-control-document" + "" + "combobox" + 0 + 1 + 0 + 0 + "wbComboBoxProxy" + "wxEVT_UPDATE_UI|OnRichtextOutlineTopUpdate|NONE||" + "ID_RICHTEXT_OUTLINE_TOP_UNITS" + 10836 + "" + "wxComboBox" + "wxComboBox" + 1 + 0 + "" + "" + "m_topOutlineWidthUnits" + "px|cm" + "px" + "Units for the top outline width." + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + 60 + -1 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "Spacer" + "dialog-control-document" + "" + "spacer" + 0 + 1 + 0 + 0 + "wbSpacerProxy" + 2 + 5 + "Centre" + "Centre" + 0 + 2 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "<Any platform>" + + + "wxComboBox: ID_RICHTEXT_OUTLINE_TOP_STYLE" + "dialog-control-document" + "" + "combobox" + 0 + 1 + 0 + 0 + "wbComboBoxProxy" + "wxEVT_UPDATE_UI|OnRichtextOutlineTopUpdate|NONE||wxRichTextBordersPage" + "ID_RICHTEXT_OUTLINE_TOP_STYLE" + 10837 + "" + "wxComboBox" + "wxComboBox" + 1 + 0 + "" + "" + "m_topOutlineStyle" + "" + "" + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + -1 + -1 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "Spacer" + "dialog-control-document" + "" + "spacer" + 0 + 1 + 0 + 0 + "wbSpacerProxy" + 2 + 5 + "Centre" + "Centre" + 0 + 2 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "<Any platform>" + + + "wxRichTextColourSwatchCtrl: ID_RICHTEXT_OUTLINE_TOP_COLOUR" + "dialog-control-document" + "" + "foreign" + 0 + 1 + 0 + 0 + "wbForeignCtrlProxy" + "wxEVT_UPDATE_UI|OnRichtextOutlineTopUpdate|NONE||wxRichTextBordersPage" + "ID_RICHTEXT_OUTLINE_TOP_COLOUR" + 10838 + "" + "wxRichTextColourSwatchCtrl" + "wxWindow" + 1 + 0 + "" + "" + "m_topOutlineColour" + 1 + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + 40 + 20 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + "" + + + + "wxCheckBox: ID_RICHTEXT_OUTLINE_BOTTOM_CHECKBOX" + "dialog-control-document" + "" + "checkbox" + 0 + 1 + 0 + 0 + "wbCheckBoxProxy" + "wxEVT_COMMAND_CHECKBOX_CLICKED|OnRichtextBorderCheckboxClick|NONE||wxRichTextBordersPage" + "ID_RICHTEXT_OUTLINE_BOTTOM_CHECKBOX" + 10839 + "" + "wxCheckBox" + "wxCheckBox" + 1 + 0 + "" + "" + "m_bottomOutlineCheckbox" + "&Bottom:" + 0 + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + 0 + 0 + 1 + 1 + 0 + 0 + 0 + "" + -1 + -1 + -1 + -1 + "Left" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "wxBoxSizer H" + "dialog-control-document" + "" + "sizer" + 0 + 1 + 0 + 0 + "wbBoxSizerProxy" + "Horizontal" + "" + "Expand" + "Centre" + 0 + 5 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "<Any platform>" + + "wxTextCtrl: ID_RICHTEXT_OUTLINE_BOTTOM" + "dialog-control-document" + "" + "textctrl" + 0 + 1 + 0 + 0 + "wbTextCtrlProxy" + "wxEVT_UPDATE_UI|OnRichtextOutlineBottomUpdate|NONE||wxRichTextBordersPage" + "ID_RICHTEXT_OUTLINE_BOTTOM" + 10840 + "" + "wxTextCtrl" + "wxTextCtrl" + 1 + 0 + "" + "" + "m_bottomOutlineWidth" + "" + 0 + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + 50 + -1 + "Centre" + "Centre" + 0 + 5 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "wxComboBox: ID_RICHTEXT_OUTLINE_BOTTOM_UNITS" + "dialog-control-document" + "" + "combobox" + 0 + 1 + 0 + 0 + "wbComboBoxProxy" + "wxEVT_UPDATE_UI|OnRichtextOutlineBottomUpdate|NONE||wxRichTextBordersPage" + "ID_RICHTEXT_OUTLINE_BOTTOM_UNITS" + 10841 + "" + "wxComboBox" + "wxComboBox" + 1 + 0 + "" + "" + "m_bottomOutlineWidthUnits" + "px|cm" + "px" + "Units for the bottom outline width." + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + 60 + -1 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "Spacer" + "dialog-control-document" + "" + "spacer" + 0 + 1 + 0 + 0 + "wbSpacerProxy" + 2 + 5 + "Centre" + "Centre" + 0 + 2 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "<Any platform>" + + + "wxComboBox: ID_RICHTEXT_OUTLINE_BOTTOM_STYLE" + "dialog-control-document" + "" + "combobox" + 0 + 1 + 0 + 0 + "wbComboBoxProxy" + "wxEVT_UPDATE_UI|OnRichtextOutlineBottomUpdate|NONE||wxRichTextBordersPage" + "ID_RICHTEXT_OUTLINE_BOTTOM_STYLE" + 10842 + "" + "wxComboBox" + "wxComboBox" + 1 + 0 + "" + "" + "m_bottomOutlineStyle" + "" + "" + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + -1 + -1 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "Spacer" + "dialog-control-document" + "" + "spacer" + 0 + 1 + 0 + 0 + "wbSpacerProxy" + 2 + 5 + "Centre" + "Centre" + 0 + 2 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "<Any platform>" + + + "wxRichTextColourSwatchCtrl: ID_RICHTEXT_OUTLINE_BOTTOM_COLOUR" + "dialog-control-document" + "" + "foreign" + 0 + 1 + 0 + 0 + "wbForeignCtrlProxy" + "wxEVT_UPDATE_UI|OnRichtextOutlineBottomUpdate|NONE||wxRichTextBordersPage" + "ID_RICHTEXT_OUTLINE_BOTTOM_COLOUR" + 10843 + "" + "wxRichTextColourSwatchCtrl" + "wxWindow" + 1 + 0 + "" + "" + "m_bottomOutlineColour" + 1 + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + 40 + 20 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + "" + + + + + + + + + + "wxRichTextBorderPreviewCtrl: ID_RICHTEXT_BORDER_PREVIEW" + "dialog-control-document" + "" + "foreign" + 0 + 1 + 0 + 0 + "wbForeignCtrlProxy" + "ID_RICHTEXT_BORDER_PREVIEW" + 10844 + "" + "wxRichTextBorderPreviewCtrl" + "wxWindow" + 1 + 0 + "" + "" + "m_borderPreviewCtrl" + 1 + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + 60 + 60 + "Expand" + "Centre" + 1 + 5 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + "" + "" + "" + + + + + + "wxRichTextBackgroundPage" + "dialog-document" + "" + "dialog" + 0 + 1 + 0 + 0 + "wbDialogProxy" + 10840 + 0 + "" + 0 + "" + "Standard" + 0 + 0 + "ID_RICHTEXTBACKGROUNDPAGE" + 10845 + "wxRichTextBackgroundPage" + "wxRichTextDialogPage" + "wxPanel" + "richtextbackgroundpage.cpp" + "../../include/wx/richtext/richtextbackgroundpage.h" + "" + "" + 1 + "" + 0 + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "Tiled" + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 0 + 0 + "" + 0 + 1 + -1 + -1 + 400 + 300 + 0 + "" + + "wxBoxSizer V" + "dialog-control-document" + "" + "sizer" + 0 + 1 + 0 + 0 + "wbBoxSizerProxy" + "Vertical" + "" + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "<Any platform>" + + "wxBoxSizer V" + "dialog-control-document" + "" + "sizer" + 0 + 1 + 0 + 0 + "wbBoxSizerProxy" + "Vertical" + "" + "Expand" + "Centre" + 1 + 5 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "<Any platform>" + + "wxBoxSizer H" + "dialog-control-document" + "" + "sizer" + 0 + 1 + 0 + 0 + "wbBoxSizerProxy" + "Horizontal" + "" + "Expand" + "Centre" + 0 + 5 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "<Any platform>" + + "wxStaticText: wxID_STATIC" + "dialog-control-document" + "" + "statictext" + 0 + 1 + 0 + 0 + "wbStaticTextProxy" + "wxID_STATIC" + 5105 + "" + "wxStaticText" + "wxStaticText" + 1 + 0 + "" + "" + "" + "Background" + -1 + "" + "" + "" + "" + "wxSYS_DEFAULT_GUI_FONT:default,default,default, wxBOLD, false" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + -1 + -1 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "wxStaticLine: wxID_STATIC" + "dialog-control-document" + "" + "staticline" + 0 + 1 + 0 + 0 + "wbStaticLineProxy" + "wxID_STATIC" + 5105 + "" + "wxStaticLine" + "wxStaticLine" + 1 + 0 + "" + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + -1 + -1 + "Centre" + "Centre" + 1 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + + + + "wxBoxSizer H" + "dialog-control-document" + "" + "sizer" + 0 + 1 + 0 + 0 + "wbBoxSizerProxy" + "Horizontal" + "" + "Expand" + "Centre" + 0 + 5 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "<Any platform>" + + "Spacer" + "dialog-control-document" + "" + "spacer" + 0 + 1 + 0 + 0 + "wbSpacerProxy" + 5 + 5 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "<Any platform>" + + + "wxCheckBox: ID_RICHTEXT_BACKGROUND_COLOUR_CHECKBOX" + "dialog-control-document" + "" + "checkbox" + 0 + 1 + 0 + 0 + "wbCheckBoxProxy" + "ID_RICHTEXT_BACKGROUND_COLOUR_CHECKBOX" + 10846 + "" + "wxCheckBox" + "wxCheckBox" + 1 + 0 + "" + "" + "m_backgroundColourCheckBox" + "Background &colour:" + 0 + "Enables a background colour." + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + -1 + -1 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "wxRichTextColourSwatchCtrl: ID_RICHTEXT_BACKGROUND_COLOUR_SWATCH" + "dialog-control-document" + "" + "foreign" + 0 + 1 + 0 + 0 + "wbForeignCtrlProxy" + "wxEVT_UPDATE_UI|OnRichtextOutlineTopUpdate|NONE||wxRichTextBordersPage" + "ID_RICHTEXT_BACKGROUND_COLOUR_SWATCH" + 10847 + "" + "wxRichTextColourSwatchCtrl" + "wxWindow" + 1 + 0 + "" + "" + "m_backgroundColourSwatch" + 1 + "The background colour." + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" + "" + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + 80 + 20 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + "" + diff --git a/src/richtext/richtextfontpage.cpp b/src/richtext/richtextfontpage.cpp index caf10cad36..08b6854967 100644 --- a/src/richtext/richtextfontpage.cpp +++ b/src/richtext/richtextfontpage.cpp @@ -15,13 +15,13 @@ * wxRichTextFontPage type definition */ -IMPLEMENT_DYNAMIC_CLASS( wxRichTextFontPage, wxPanel ) +IMPLEMENT_DYNAMIC_CLASS( wxRichTextFontPage, wxRichTextDialogPage ) /*! * wxRichTextFontPage event table definition */ -BEGIN_EVENT_TABLE( wxRichTextFontPage, wxPanel ) +BEGIN_EVENT_TABLE( wxRichTextFontPage, wxRichTextDialogPage ) EVT_LISTBOX( ID_RICHTEXTFONTPAGE_FACELISTBOX, wxRichTextFontPage::OnFaceListBoxSelected ) EVT_BUTTON( ID_RICHTEXTFONTPAGE_COLOURCTRL, wxRichTextFontPage::OnColourClicked ) EVT_BUTTON( ID_RICHTEXTFONTPAGE_BGCOLOURCTRL, wxRichTextFontPage::OnColourClicked ) @@ -51,6 +51,7 @@ BEGIN_EVENT_TABLE( wxRichTextFontPage, wxPanel ) END_EVENT_TABLE() +IMPLEMENT_HELP_PROVISION(wxRichTextFontPage) /*! * wxRichTextFontPage constructors */ @@ -101,7 +102,7 @@ void wxRichTextFontPage::Init() bool wxRichTextFontPage::Create( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) { ////@begin wxRichTextFontPage creation - wxPanel::Create( parent, id, pos, size, style ); + wxRichTextDialogPage::Create( parent, id, pos, size, style ); CreateControls(); if (GetSizer()) @@ -120,10 +121,10 @@ bool wxRichTextFontPage::Create( wxWindow* parent, wxWindowID id, const wxPoint& void wxRichTextFontPage::CreateControls() { ////@begin wxRichTextFontPage content construction - wxRichTextFontPage* itemPanel1 = this; + wxRichTextFontPage* itemRichTextDialogPage1 = this; wxBoxSizer* itemBoxSizer2 = new wxBoxSizer(wxVERTICAL); - itemPanel1->SetSizer(itemBoxSizer2); + itemRichTextDialogPage1->SetSizer(itemBoxSizer2); wxBoxSizer* itemBoxSizer3 = new wxBoxSizer(wxVERTICAL); itemBoxSizer2->Add(itemBoxSizer3, 1, wxGROW|wxALL, 5); @@ -134,16 +135,16 @@ void wxRichTextFontPage::CreateControls() wxBoxSizer* itemBoxSizer5 = new wxBoxSizer(wxVERTICAL); itemBoxSizer4->Add(itemBoxSizer5, 1, wxGROW, 5); - wxStaticText* itemStaticText6 = new wxStaticText( itemPanel1, wxID_STATIC, _("&Font:"), wxDefaultPosition, wxDefaultSize, 0 ); + wxStaticText* itemStaticText6 = new wxStaticText( itemRichTextDialogPage1, wxID_STATIC, _("&Font:"), wxDefaultPosition, wxDefaultSize, 0 ); itemBoxSizer5->Add(itemStaticText6, 0, wxALIGN_LEFT|wxLEFT|wxRIGHT|wxTOP, 5); - m_faceTextCtrl = new wxTextCtrl( itemPanel1, ID_RICHTEXTFONTPAGE_FACETEXTCTRL, wxT(""), wxDefaultPosition, wxDefaultSize, 0 ); + m_faceTextCtrl = new wxTextCtrl( itemRichTextDialogPage1, ID_RICHTEXTFONTPAGE_FACETEXTCTRL, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); m_faceTextCtrl->SetHelpText(_("Type a font name.")); if (wxRichTextFontPage::ShowToolTips()) m_faceTextCtrl->SetToolTip(_("Type a font name.")); itemBoxSizer5->Add(m_faceTextCtrl, 0, wxGROW|wxLEFT|wxRIGHT|wxTOP, 5); - m_faceListBox = new wxRichTextFontListBox( itemPanel1, ID_RICHTEXTFONTPAGE_FACELISTBOX, wxDefaultPosition, wxSize(200, 100), 0 ); + m_faceListBox = new wxRichTextFontListBox( itemRichTextDialogPage1, ID_RICHTEXTFONTPAGE_FACELISTBOX, wxDefaultPosition, wxSize(200, 100), 0 ); m_faceListBox->SetHelpText(_("Lists the available fonts.")); if (wxRichTextFontPage::ShowToolTips()) m_faceListBox->SetToolTip(_("Lists the available fonts.")); @@ -152,17 +153,17 @@ void wxRichTextFontPage::CreateControls() wxBoxSizer* itemBoxSizer9 = new wxBoxSizer(wxVERTICAL); itemBoxSizer4->Add(itemBoxSizer9, 0, wxGROW, 5); - wxStaticText* itemStaticText10 = new wxStaticText( itemPanel1, wxID_STATIC, _("&Size:"), wxDefaultPosition, wxDefaultSize, 0 ); + wxStaticText* itemStaticText10 = new wxStaticText( itemRichTextDialogPage1, wxID_STATIC, _("&Size:"), wxDefaultPosition, wxDefaultSize, 0 ); itemBoxSizer9->Add(itemStaticText10, 0, wxALIGN_LEFT|wxLEFT|wxRIGHT|wxTOP, 5); - m_sizeTextCtrl = new wxTextCtrl( itemPanel1, ID_RICHTEXTFONTPAGE_SIZETEXTCTRL, wxT(""), wxDefaultPosition, wxSize(50, -1), 0 ); + m_sizeTextCtrl = new wxTextCtrl( itemRichTextDialogPage1, ID_RICHTEXTFONTPAGE_SIZETEXTCTRL, wxEmptyString, wxDefaultPosition, wxSize(50, -1), 0 ); m_sizeTextCtrl->SetHelpText(_("Type a size in points.")); if (wxRichTextFontPage::ShowToolTips()) m_sizeTextCtrl->SetToolTip(_("Type a size in points.")); itemBoxSizer9->Add(m_sizeTextCtrl, 0, wxGROW|wxLEFT|wxRIGHT|wxTOP, 5); wxArrayString m_sizeListBoxStrings; - m_sizeListBox = new wxListBox( itemPanel1, ID_RICHTEXTFONTPAGE_SIZELISTBOX, wxDefaultPosition, wxSize(50, -1), m_sizeListBoxStrings, wxLB_SINGLE ); + m_sizeListBox = new wxListBox( itemRichTextDialogPage1, ID_RICHTEXTFONTPAGE_SIZELISTBOX, wxDefaultPosition, wxSize(50, -1), m_sizeListBoxStrings, wxLB_SINGLE ); m_sizeListBox->SetHelpText(_("Lists font sizes in points.")); if (wxRichTextFontPage::ShowToolTips()) m_sizeListBox->SetToolTip(_("Lists font sizes in points.")); @@ -174,11 +175,11 @@ void wxRichTextFontPage::CreateControls() wxBoxSizer* itemBoxSizer14 = new wxBoxSizer(wxVERTICAL); itemBoxSizer13->Add(itemBoxSizer14, 0, wxGROW, 5); - wxStaticText* itemStaticText15 = new wxStaticText( itemPanel1, wxID_STATIC, _("Font st&yle:"), wxDefaultPosition, wxDefaultSize, 0 ); + wxStaticText* itemStaticText15 = new wxStaticText( itemRichTextDialogPage1, wxID_STATIC, _("Font st&yle:"), wxDefaultPosition, wxDefaultSize, 0 ); itemBoxSizer14->Add(itemStaticText15, 0, wxALIGN_LEFT|wxLEFT|wxRIGHT|wxTOP, 5); wxArrayString m_styleCtrlStrings; - m_styleCtrl = new wxComboBox( itemPanel1, ID_RICHTEXTFONTPAGE_STYLECTRL, wxT(""), wxDefaultPosition, wxSize(110, -1), m_styleCtrlStrings, wxCB_READONLY ); + m_styleCtrl = new wxComboBox( itemRichTextDialogPage1, ID_RICHTEXTFONTPAGE_STYLECTRL, wxEmptyString, wxDefaultPosition, wxSize(110, -1), m_styleCtrlStrings, wxCB_READONLY ); m_styleCtrl->SetHelpText(_("Select regular or italic style.")); if (wxRichTextFontPage::ShowToolTips()) m_styleCtrl->SetToolTip(_("Select regular or italic style.")); @@ -187,11 +188,11 @@ void wxRichTextFontPage::CreateControls() wxBoxSizer* itemBoxSizer17 = new wxBoxSizer(wxVERTICAL); itemBoxSizer13->Add(itemBoxSizer17, 0, wxGROW, 5); - wxStaticText* itemStaticText18 = new wxStaticText( itemPanel1, wxID_STATIC, _("Font &weight:"), wxDefaultPosition, wxDefaultSize, 0 ); + wxStaticText* itemStaticText18 = new wxStaticText( itemRichTextDialogPage1, wxID_STATIC, _("Font &weight:"), wxDefaultPosition, wxDefaultSize, 0 ); itemBoxSizer17->Add(itemStaticText18, 0, wxALIGN_LEFT|wxLEFT|wxRIGHT|wxTOP, 5); wxArrayString m_weightCtrlStrings; - m_weightCtrl = new wxComboBox( itemPanel1, ID_RICHTEXTFONTPAGE_WEIGHTCTRL, wxT(""), wxDefaultPosition, wxSize(110, -1), m_weightCtrlStrings, wxCB_READONLY ); + m_weightCtrl = new wxComboBox( itemRichTextDialogPage1, ID_RICHTEXTFONTPAGE_WEIGHTCTRL, wxEmptyString, wxDefaultPosition, wxSize(110, -1), m_weightCtrlStrings, wxCB_READONLY ); m_weightCtrl->SetHelpText(_("Select regular or bold.")); if (wxRichTextFontPage::ShowToolTips()) m_weightCtrl->SetToolTip(_("Select regular or bold.")); @@ -200,11 +201,11 @@ void wxRichTextFontPage::CreateControls() wxBoxSizer* itemBoxSizer20 = new wxBoxSizer(wxVERTICAL); itemBoxSizer13->Add(itemBoxSizer20, 0, wxGROW, 5); - wxStaticText* itemStaticText21 = new wxStaticText( itemPanel1, wxID_STATIC, _("&Underlining:"), wxDefaultPosition, wxDefaultSize, 0 ); + wxStaticText* itemStaticText21 = new wxStaticText( itemRichTextDialogPage1, wxID_STATIC, _("&Underlining:"), wxDefaultPosition, wxDefaultSize, 0 ); itemBoxSizer20->Add(itemStaticText21, 0, wxALIGN_LEFT|wxLEFT|wxRIGHT|wxTOP, 5); wxArrayString m_underliningCtrlStrings; - m_underliningCtrl = new wxComboBox( itemPanel1, ID_RICHTEXTFONTPAGE_UNDERLINING_CTRL, wxT(""), wxDefaultPosition, wxSize(110, -1), m_underliningCtrlStrings, wxCB_READONLY ); + m_underliningCtrl = new wxComboBox( itemRichTextDialogPage1, ID_RICHTEXTFONTPAGE_UNDERLINING_CTRL, wxEmptyString, wxDefaultPosition, wxSize(110, -1), m_underliningCtrlStrings, wxCB_READONLY ); m_underliningCtrl->SetHelpText(_("Select underlining or no underlining.")); if (wxRichTextFontPage::ShowToolTips()) m_underliningCtrl->SetToolTip(_("Select underlining or no underlining.")); @@ -215,10 +216,10 @@ void wxRichTextFontPage::CreateControls() wxBoxSizer* itemBoxSizer24 = new wxBoxSizer(wxVERTICAL); itemBoxSizer13->Add(itemBoxSizer24, 0, wxGROW, 5); - wxStaticText* itemStaticText25 = new wxStaticText( itemPanel1, wxID_STATIC, _("&Colour:"), wxDefaultPosition, wxDefaultSize, 0 ); + wxStaticText* itemStaticText25 = new wxStaticText( itemRichTextDialogPage1, wxID_STATIC, _("&Colour:"), wxDefaultPosition, wxDefaultSize, 0 ); itemBoxSizer24->Add(itemStaticText25, 0, wxALIGN_LEFT|wxLEFT|wxRIGHT|wxTOP, 5); - m_colourCtrl = new wxRichTextColourSwatchCtrl( itemPanel1, ID_RICHTEXTFONTPAGE_COLOURCTRL, wxDefaultPosition, wxSize(40, 20), 0 ); + m_colourCtrl = new wxRichTextColourSwatchCtrl( itemRichTextDialogPage1, ID_RICHTEXTFONTPAGE_COLOURCTRL, wxDefaultPosition, wxSize(40, 20), 0 ); m_colourCtrl->SetHelpText(_("Click to change the text colour.")); if (wxRichTextFontPage::ShowToolTips()) m_colourCtrl->SetToolTip(_("Click to change the text colour.")); @@ -227,10 +228,10 @@ void wxRichTextFontPage::CreateControls() wxBoxSizer* itemBoxSizer27 = new wxBoxSizer(wxVERTICAL); itemBoxSizer13->Add(itemBoxSizer27, 0, wxGROW, 5); - wxStaticText* itemStaticText28 = new wxStaticText( itemPanel1, wxID_STATIC, _("&Bg colour:"), wxDefaultPosition, wxDefaultSize, 0 ); + wxStaticText* itemStaticText28 = new wxStaticText( itemRichTextDialogPage1, wxID_STATIC, _("&Bg colour:"), wxDefaultPosition, wxDefaultSize, 0 ); itemBoxSizer27->Add(itemStaticText28, 0, wxALIGN_LEFT|wxLEFT|wxRIGHT|wxTOP, 5); - m_bgColourCtrl = new wxRichTextColourSwatchCtrl( itemPanel1, ID_RICHTEXTFONTPAGE_BGCOLOURCTRL, wxDefaultPosition, wxSize(40, 20), 0 ); + m_bgColourCtrl = new wxRichTextColourSwatchCtrl( itemRichTextDialogPage1, ID_RICHTEXTFONTPAGE_BGCOLOURCTRL, wxDefaultPosition, wxSize(40, 20), 0 ); m_bgColourCtrl->SetHelpText(_("Click to change the text background colour.")); if (wxRichTextFontPage::ShowToolTips()) m_bgColourCtrl->SetToolTip(_("Click to change the text background colour.")); @@ -239,28 +240,28 @@ void wxRichTextFontPage::CreateControls() wxBoxSizer* itemBoxSizer30 = new wxBoxSizer(wxHORIZONTAL); itemBoxSizer3->Add(itemBoxSizer30, 0, wxGROW, 5); - m_strikethroughCtrl = new wxCheckBox( itemPanel1, ID_RICHTEXTFONTPAGE_STRIKETHROUGHCTRL, _("&Strikethrough"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE ); + m_strikethroughCtrl = new wxCheckBox( itemRichTextDialogPage1, ID_RICHTEXTFONTPAGE_STRIKETHROUGHCTRL, _("&Strikethrough"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE ); m_strikethroughCtrl->SetValue(false); m_strikethroughCtrl->SetHelpText(_("Check to show a line through the text.")); if (wxRichTextFontPage::ShowToolTips()) m_strikethroughCtrl->SetToolTip(_("Check to show a line through the text.")); itemBoxSizer30->Add(m_strikethroughCtrl, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); - m_capitalsCtrl = new wxCheckBox( itemPanel1, ID_RICHTEXTFONTPAGE_CAPSCTRL, _("Ca&pitals"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE ); + m_capitalsCtrl = new wxCheckBox( itemRichTextDialogPage1, ID_RICHTEXTFONTPAGE_CAPSCTRL, _("Ca&pitals"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE ); m_capitalsCtrl->SetValue(false); m_capitalsCtrl->SetHelpText(_("Check to show the text in capitals.")); if (wxRichTextFontPage::ShowToolTips()) m_capitalsCtrl->SetToolTip(_("Check to show the text in capitals.")); itemBoxSizer30->Add(m_capitalsCtrl, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); - m_superscriptCtrl = new wxCheckBox( itemPanel1, ID_RICHTEXTFONTPAGE_SUPERSCRIPT, _("Supe&rscript"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE ); + m_superscriptCtrl = new wxCheckBox( itemRichTextDialogPage1, ID_RICHTEXTFONTPAGE_SUPERSCRIPT, _("Supe&rscript"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE ); m_superscriptCtrl->SetValue(false); m_superscriptCtrl->SetHelpText(_("Check to show the text in superscript.")); if (wxRichTextFontPage::ShowToolTips()) m_superscriptCtrl->SetToolTip(_("Check to show the text in superscript.")); itemBoxSizer30->Add(m_superscriptCtrl, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); - m_subscriptCtrl = new wxCheckBox( itemPanel1, ID_RICHTEXTFONTPAGE_SUBSCRIPT, _("Subscrip&t"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE ); + m_subscriptCtrl = new wxCheckBox( itemRichTextDialogPage1, ID_RICHTEXTFONTPAGE_SUBSCRIPT, _("Subscrip&t"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE ); m_subscriptCtrl->SetValue(false); m_subscriptCtrl->SetHelpText(_("Check to show the text in subscript.")); if (wxRichTextFontPage::ShowToolTips()) @@ -269,7 +270,7 @@ void wxRichTextFontPage::CreateControls() itemBoxSizer3->Add(5, 5, 0, wxALIGN_CENTER_HORIZONTAL, 5); - m_previewCtrl = new wxRichTextFontPreviewCtrl( itemPanel1, ID_RICHTEXTFONTPAGE_PREVIEWCTRL, wxDefaultPosition, wxSize(100, 60), 0 ); + m_previewCtrl = new wxRichTextFontPreviewCtrl( itemRichTextDialogPage1, ID_RICHTEXTFONTPAGE_PREVIEWCTRL, wxDefaultPosition, wxSize(100, 60), 0 ); m_previewCtrl->SetHelpText(_("Shows a preview of the font settings.")); if (wxRichTextFontPage::ShowToolTips()) m_previewCtrl->SetToolTip(_("Shows a preview of the font settings.")); @@ -306,13 +307,10 @@ bool wxRichTextFontPage::TransferDataFromWindow() wxRichTextAttr* attr = GetAttributes(); - if (m_faceListBox->GetSelection() != wxNOT_FOUND) + if (!m_faceTextCtrl->GetValue().IsEmpty()) { - wxString faceName = m_faceListBox->GetFaceName(m_faceListBox->GetSelection()); - if (!faceName.IsEmpty()) - { - attr->SetFontFaceName(faceName); - } + wxString faceName = m_faceTextCtrl->GetValue(); + attr->SetFontFaceName(faceName); } else attr->SetFlags(attr->GetFlags() & (~ wxTEXT_ATTR_FONT_FACE)); diff --git a/src/richtext/richtextformatdlg.cpp b/src/richtext/richtextformatdlg.cpp index 6ae7671452..c440a7736b 100644 --- a/src/richtext/richtextformatdlg.cpp +++ b/src/richtext/richtextformatdlg.cpp @@ -52,11 +52,19 @@ #include "../../src/richtext/richtextbulletspage.cpp" #include "../../src/richtext/richtextstylepage.cpp" #include "../../src/richtext/richtextliststylepage.cpp" +#include "../../src/richtext/richtextsizepage.cpp" +#include "../../src/richtext/richtextmarginspage.cpp" +#include "../../src/richtext/richtextborderspage.cpp" +#include "../../src/richtext/richtextbackgroundpage.cpp" #else #include "richtextfontpage.cpp" #include "richtextindentspage.cpp" #include "richtexttabspage.cpp" #include "richtextbulletspage.cpp" +#include "richtextmarginspage.cpp" +#include "richtextsizepage.cpp" +#include "richtextborderspage.cpp" +#include "richtextbackgroundpage.cpp" // Digital Mars can't cope with this much code #ifndef __DMC__ #include "richtextliststylepage.cpp" @@ -76,8 +84,12 @@ IMPLEMENT_CLASS(wxRichTextFormattingDialog, wxPropertySheetDialog) BEGIN_EVENT_TABLE(wxRichTextFormattingDialog, wxPropertySheetDialog) EVT_BOOKCTRL_PAGE_CHANGED(wxID_ANY, wxRichTextFormattingDialog::OnTabChanged) + EVT_BUTTON(wxID_HELP, wxRichTextFormattingDialog::OnHelp) + EVT_UPDATE_UI(wxID_HELP, wxRichTextFormattingDialog::OnUpdateHelp) END_EVENT_TABLE() +IMPLEMENT_HELP_PROVISION(wxRichTextFormattingDialog) + wxRichTextFormattingDialogFactory* wxRichTextFormattingDialog::ms_FormattingDialogFactory = NULL; void wxRichTextFormattingDialog::Init() @@ -85,6 +97,7 @@ void wxRichTextFormattingDialog::Init() m_imageList = NULL; m_styleDefinition = NULL; m_styleSheet = NULL; + m_object = NULL; } wxRichTextFormattingDialog::~wxRichTextFormattingDialog() @@ -117,7 +130,7 @@ bool wxRichTextFormattingDialog::Create(long flags, wxWindow* parent, const wxSt /// Get attributes from the given range bool wxRichTextFormattingDialog::GetStyle(wxRichTextCtrl* ctrl, const wxRichTextRange& range) { - if (ctrl->GetBuffer().GetStyleForRange(range.ToInternal(), m_attributes)) + if (ctrl->GetFocusObject()->GetStyleForRange(range.ToInternal(), m_attributes)) return UpdateDisplay(); else return false; @@ -129,6 +142,20 @@ bool wxRichTextFormattingDialog::ApplyStyle(wxRichTextCtrl* ctrl, const wxRichTe return ctrl->SetStyleEx(range, m_attributes, flags); } +// Apply attributes to the object being edited, if any +bool wxRichTextFormattingDialog::ApplyStyle(wxRichTextCtrl* WXUNUSED(ctrl), int flags) +{ + if (GetObject()) + { + wxRichTextParagraphLayoutBox* parentContainer = GetObject()->GetParentContainer(); + if (parentContainer) + parentContainer->SetStyle(GetObject(), m_attributes, flags); + return true; + } + else + return false; +} + /// Set the attributes and optionally update the display bool wxRichTextFormattingDialog::SetStyle(const wxRichTextAttr& style, bool update) { @@ -212,12 +239,19 @@ void wxRichTextFormattingDialog::OnHelp(wxCommandEvent& event) int selPage = GetBookCtrl()->GetSelection(); if (selPage != wxNOT_FOUND) { - int pageId = m_pageIds[selPage]; + int pageId = -1; + if (selPage < (int) m_pageIds.GetCount()) + pageId = m_pageIds[selPage]; if (!GetFormattingDialogFactory()->ShowHelp(pageId, this)) event.Skip(); } } +void wxRichTextFormattingDialog::OnUpdateHelp(wxUpdateUIEvent& event) +{ + event.Enable(true); +} + void wxRichTextFormattingDialog::SetFormattingDialogFactory(wxRichTextFormattingDialogFactory* factory) { if (ms_FormattingDialogFactory) @@ -225,6 +259,20 @@ void wxRichTextFormattingDialog::SetFormattingDialogFactory(wxRichTextFormatting ms_FormattingDialogFactory = factory; } +// Find a page by class +wxWindow* wxRichTextFormattingDialog::FindPage(wxClassInfo* info) const +{ + size_t i; + for (i = 0; i < GetBookCtrl()->GetPageCount(); i++) + { + wxWindow* w = GetBookCtrl()->GetPage(i); + if (w && w->GetClassInfo() == info) + return w; + } + return NULL; +} + + /*! * Factory for formatting dialog */ @@ -301,6 +349,30 @@ wxPanel* wxRichTextFormattingDialogFactory::CreatePage(int page, wxString& title return page; } #endif + else if (page == wxRICHTEXT_FORMAT_SIZE) + { + wxRichTextSizePage* page = new wxRichTextSizePage(dialog->GetBookCtrl(), wxID_ANY); + title = _("Size"); + return page; + } + else if (page == wxRICHTEXT_FORMAT_MARGINS) + { + wxRichTextMarginsPage* page = new wxRichTextMarginsPage(dialog->GetBookCtrl(), wxID_ANY); + title = _("Margins"); + return page; + } + else if (page == wxRICHTEXT_FORMAT_BORDERS) + { + wxRichTextBordersPage* page = new wxRichTextBordersPage(dialog->GetBookCtrl(), wxID_ANY); + title = _("Borders"); + return page; + } + else if (page == wxRICHTEXT_FORMAT_BACKGROUND) + { + wxRichTextBackgroundPage* page = new wxRichTextBackgroundPage(dialog->GetBookCtrl(), wxID_ANY); + title = _("Background"); + return page; + } else return NULL; } @@ -314,9 +386,14 @@ int wxRichTextFormattingDialogFactory::GetPageId(int i) const wxRICHTEXT_FORMAT_INDENTS_SPACING, wxRICHTEXT_FORMAT_BULLETS, wxRICHTEXT_FORMAT_TABS, - wxRICHTEXT_FORMAT_LIST_STYLE }; + wxRICHTEXT_FORMAT_LIST_STYLE, + wxRICHTEXT_FORMAT_SIZE, + wxRICHTEXT_FORMAT_MARGINS, + wxRICHTEXT_FORMAT_BORDERS, + wxRICHTEXT_FORMAT_BACKGROUND + }; - if (i < 0 || i > 5) + if (i < 0 || i >= GetPageIdCount()) return -1; return pages[i]; @@ -326,9 +403,9 @@ int wxRichTextFormattingDialogFactory::GetPageId(int i) const int wxRichTextFormattingDialogFactory::GetPageIdCount() const { #ifdef __DMC__ - return 5; + return 9; #else - return 6; + return 10; #endif } @@ -370,6 +447,28 @@ bool wxRichTextFormattingDialogFactory::CreateButtons(wxRichTextFormattingDialog return true; } +// Invoke help for the dialog +bool wxRichTextFormattingDialogFactory::ShowHelp(int WXUNUSED(page), wxRichTextFormattingDialog* dialog) +{ + wxRichTextDialogPage* window = NULL; + int sel = dialog->GetBookCtrl()->GetSelection(); + if (sel != -1) + window = wxDynamicCast(dialog->GetBookCtrl()->GetPage(sel), wxRichTextDialogPage); + if (window && window->GetHelpId() != -1) + { + if (window->GetUICustomization()) + return window->GetUICustomization()->ShowHelp(dialog, window->GetHelpId()); + else if (dialog->GetUICustomization()) + return dialog->GetUICustomization()->ShowHelp(dialog, window->GetHelpId()); + else + return false; + } + else if (dialog->GetHelpId() != -1 && dialog->GetUICustomization()) + return dialog->ShowHelp(dialog); + else + return false; +} + /* * Module to initialise and clean up handlers */ @@ -460,7 +559,6 @@ wxRichTextFormattingDialog* wxRichTextFormattingDialog::GetDialog(wxWindow* win) return dialog; } - // Helper for pages to get the attributes wxRichTextAttr* wxRichTextFormattingDialog::GetDialogAttributes(wxWindow* win) { @@ -471,6 +569,18 @@ wxRichTextAttr* wxRichTextFormattingDialog::GetDialogAttributes(wxWindow* win) return NULL; } +#if 0 +// Helper for pages to get the attributes to reset +wxRichTextAttr* wxRichTextFormattingDialog::GetDialogResetAttributes(wxWindow* win) +{ + wxRichTextFormattingDialog* dialog = GetDialog(win); + if (dialog) + return & dialog->GetResetAttributes(); + else + return NULL; +} +#endif + // Helper for pages to get the style wxRichTextStyleDefinition* wxRichTextFormattingDialog::GetDialogStyleDefinition(wxWindow* win) { @@ -481,6 +591,88 @@ wxRichTextStyleDefinition* wxRichTextFormattingDialog::GetDialogStyleDefinition( return NULL; } +void wxRichTextFormattingDialog::SetDimensionValue(wxTextAttrDimension& dim, wxTextCtrl* valueCtrl, wxComboBox* unitsCtrl, wxCheckBox* checkBox) +{ + int unitsIdx = 0; + + if (!dim.IsValid()) + { + checkBox->SetValue(false); + valueCtrl->SetValue(wxT("0")); + unitsCtrl->SetSelection(0); +#if 0 + dim.SetValue(0); + dim.SetUnits(wxTEXT_ATTR_UNITS_PIXELS); +#endif + } + else + { + checkBox->SetValue(true); + if (dim.GetUnits() == wxTEXT_ATTR_UNITS_TENTHS_MM) + { + unitsIdx = 1; + float value = float(dim.GetValue()) / 10.0; + valueCtrl->SetValue(wxString::Format(wxT("%.2f"), value)); + } + else + { + unitsIdx = 0; + valueCtrl->SetValue(wxString::Format(wxT("%d"), (int) dim.GetValue())); + } + + unitsCtrl->SetSelection(unitsIdx); + } +} + +void wxRichTextFormattingDialog::GetDimensionValue(wxTextAttrDimension& dim, wxTextCtrl* valueCtrl, wxComboBox* unitsCtrl, wxCheckBox* checkBox) +{ + if (!checkBox->GetValue()) + { + dim.Reset(); + } + else + { + if (unitsCtrl->GetSelection() == 1) + dim.SetUnits(wxTEXT_ATTR_UNITS_TENTHS_MM); + else + dim.SetUnits(wxTEXT_ATTR_UNITS_PIXELS); + + int value = 0; + if (ConvertFromString(valueCtrl->GetValue(), value, dim.GetUnits())) + dim.SetValue(value); + } +} + +bool wxRichTextFormattingDialog::ConvertFromString(const wxString& string, int& ret, int scale) +{ + const wxChar* chars = string.GetData(); + int remain = 2; + bool dot = false; + ret = 0; + + for (unsigned int i = 0; i < string.Len() && remain; i++) + { + if (!(chars[i] >= wxT('0') && chars[i] <= wxT('9')) && !(scale == wxTEXT_ATTR_UNITS_TENTHS_MM && chars[i] == wxT('.'))) + return false; + + if (chars[i] == wxT('.')) + { + dot = true; + continue; + } + + if (dot) + remain--; + + ret = ret * 10 + chars[i] - wxT('0'); + } + + while (remain-- > 0 && scale == wxTEXT_ATTR_UNITS_TENTHS_MM) + ret *= 10; + + return true; +} + /* * A control for displaying a small preview of a colour or bitmap */ diff --git a/src/richtext/richtextimagedlg.cpp b/src/richtext/richtextimagedlg.cpp index 982df5ecf2..939b51b37e 100644 --- a/src/richtext/richtextimagedlg.cpp +++ b/src/richtext/richtextimagedlg.cpp @@ -2,10 +2,10 @@ // Name: src/richtext/richtextimagedlg.cpp // Purpose: // Author: Mingquan Yang -// Modified by: +// Modified by: Julian Smart // Created: Wed 02 Jun 2010 11:27:23 CST // RCS-ID: -// Copyright: (c) Mingquan Yang +// Copyright: (c) Mingquan Yang, Julian Smart // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// @@ -16,7 +16,6 @@ #pragma hdrstop #endif - #if wxUSE_RICHTEXT #ifndef WX_PRECOMP @@ -37,41 +36,37 @@ /*! - * wxRichTextImageDialog type definition + * wxRichTextObjectPropertiesDialog type definition */ -IMPLEMENT_DYNAMIC_CLASS( wxRichTextImageDialog, wxDialog ) +IMPLEMENT_DYNAMIC_CLASS( wxRichTextObjectPropertiesDialog, wxRichTextFormattingDialog ) /*! - * wxRichTextImageDialog event table definition + * wxRichTextObjectPropertiesDialog event table definition */ -BEGIN_EVENT_TABLE( wxRichTextImageDialog, wxDialog ) +BEGIN_EVENT_TABLE( wxRichTextObjectPropertiesDialog, wxRichTextFormattingDialog ) -////@begin wxRichTextImageDialog event table entries - EVT_BUTTON( ID_RICHTEXTIMAGEDIALOG_PARA_UP, wxRichTextImageDialog::OnRichtextimagedialogParaUpClick ) - - EVT_BUTTON( ID_RICHTEXTIMAGEDIALOG_DOWN, wxRichTextImageDialog::OnRichtextimagedialogDownClick ) - -////@end wxRichTextImageDialog event table entries +////@begin wxRichTextObjectPropertiesDialog event table entries +////@end wxRichTextObjectPropertiesDialog event table entries END_EVENT_TABLE() /*! - * wxRichTextImageDialog constructors + * wxRichTextObjectPropertiesDialog constructors */ -wxRichTextImageDialog::wxRichTextImageDialog() +wxRichTextObjectPropertiesDialog::wxRichTextObjectPropertiesDialog() { Init(); } -wxRichTextImageDialog::wxRichTextImageDialog( wxWindow* parent, wxWindowID id, const wxString& caption, const wxPoint& pos, const wxSize& size, long style ) +wxRichTextObjectPropertiesDialog::wxRichTextObjectPropertiesDialog( wxRichTextObject* obj, wxWindow* parent, wxWindowID id, const wxString& caption, const wxPoint& pos, const wxSize& size, long style ) { Init(); - Create(parent, id, caption, pos, size, style); + Create(obj, parent, id, caption, pos, size, style); } @@ -79,31 +74,27 @@ wxRichTextImageDialog::wxRichTextImageDialog( wxWindow* parent, wxWindowID id, c * wxRichTextImageDlg creator */ -bool wxRichTextImageDialog::Create( wxWindow* parent, wxWindowID id, const wxString& caption, const wxPoint& pos, const wxSize& size, long style ) +bool wxRichTextObjectPropertiesDialog::Create( wxRichTextObject* obj, wxWindow* parent, wxWindowID id, const wxString& caption, const wxPoint& pos, const wxSize& size, long style ) { -////@begin wxRichTextImageDialog creation + SetObject(obj); SetExtraStyle(wxDIALOG_EX_CONTEXTHELP); - wxDialog::Create( parent, id, caption, pos, size, style ); + long flags = wxRICHTEXT_FORMAT_SIZE|wxRICHTEXT_FORMAT_MARGINS|wxRICHTEXT_FORMAT_BORDERS|wxRICHTEXT_FORMAT_BACKGROUND; + wxRichTextFormattingDialog::Create( flags, parent, caption, id, pos, size, style ); CreateControls(); - if (GetSizer()) - { - GetSizer()->SetSizeHints(this); - } - Centre(); -////@end wxRichTextImageDialog creation + return true; } /*! - * wxRichTextImageDialog destructor + * wxRichTextObjectPropertiesDialog destructor */ -wxRichTextImageDialog::~wxRichTextImageDialog() +wxRichTextObjectPropertiesDialog::~wxRichTextObjectPropertiesDialog() { -////@begin wxRichTextImageDialog destruction -////@end wxRichTextImageDialog destruction +////@begin wxRichTextObjectPropertiesDialog destruction +////@end wxRichTextObjectPropertiesDialog destruction } @@ -111,19 +102,10 @@ wxRichTextImageDialog::~wxRichTextImageDialog() * Member initialisation */ -void wxRichTextImageDialog::Init() +void wxRichTextObjectPropertiesDialog::Init() { -////@begin wxRichTextImageDialog member initialisation - m_float = NULL; - m_width = NULL; - m_unitsW = NULL; - m_height = NULL; - m_unitsH = NULL; - m_offset = NULL; - m_unitsOffset = NULL; - m_saveButton = NULL; - m_cancelButton = NULL; -////@end wxRichTextImageDialog member initialisation +////@begin wxRichTextObjectPropertiesDialog member initialisation +////@end wxRichTextObjectPropertiesDialog member initialisation } @@ -131,144 +113,8 @@ void wxRichTextImageDialog::Init() * Control creation for wxRichTextImageDlg */ -void wxRichTextImageDialog::CreateControls() +void wxRichTextObjectPropertiesDialog::CreateControls() { -#ifdef __WXMAC__ - SetWindowVariant(wxWINDOW_VARIANT_SMALL); -#endif - -////@begin wxRichTextImageDialog content construction - wxRichTextImageDialog* itemDialog1 = this; - - wxBoxSizer* itemBoxSizer2 = new wxBoxSizer(wxVERTICAL); - itemDialog1->SetSizer(itemBoxSizer2); - - wxBoxSizer* itemBoxSizer3 = new wxBoxSizer(wxHORIZONTAL); - itemBoxSizer2->Add(itemBoxSizer3, 0, wxGROW|wxALL, 5); - - wxFlexGridSizer* itemFlexGridSizer4 = new wxFlexGridSizer(0, 2, 0, 0); - itemBoxSizer3->Add(itemFlexGridSizer4, 0, wxALIGN_TOP|wxRIGHT, 5); - - wxStaticText* itemStaticText5 = new wxStaticText( itemDialog1, wxID_STATIC, _("&Floating mode:"), wxDefaultPosition, wxDefaultSize, 0 ); - itemFlexGridSizer4->Add(itemStaticText5, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL, 5); - - wxArrayString m_floatStrings; - m_floatStrings.Add(_("None")); - m_floatStrings.Add(_("Left")); - m_floatStrings.Add(_("Right")); - m_float = new wxComboBox( itemDialog1, ID_RICHTEXTIMAGEDIALOG_FLOATING_MODE, _("None"), wxDefaultPosition, wxSize(80, -1), m_floatStrings, wxCB_READONLY ); - m_float->SetStringSelection(_("None")); - m_float->SetHelpText(_("How the image will float relative to the text.")); - if (wxRichTextImageDialog::ShowToolTips()) - m_float->SetToolTip(_("How the image will float relative to the text.")); - itemFlexGridSizer4->Add(m_float, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxALL, 5); - - wxStaticText* itemStaticText7 = new wxStaticText( itemDialog1, wxID_STATIC, _("&Width:"), wxDefaultPosition, wxDefaultSize, 0 ); - itemFlexGridSizer4->Add(itemStaticText7, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL, 5); - - wxBoxSizer* itemBoxSizer8 = new wxBoxSizer(wxHORIZONTAL); - itemFlexGridSizer4->Add(itemBoxSizer8, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 5); - - m_width = new wxTextCtrl( itemDialog1, ID_RICHTEXTIMAGEDIALOG_WIDTH, wxEmptyString, wxDefaultPosition, wxSize(65, -1), 0 ); - m_width->SetHelpText(_("The image width to be shown - does not change the source image width.")); - if (wxRichTextImageDialog::ShowToolTips()) - m_width->SetToolTip(_("The image width to be shown - does not change the source image width.")); - itemBoxSizer8->Add(m_width, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); - - wxArrayString m_unitsWStrings; - m_unitsWStrings.Add(_("px")); - m_unitsWStrings.Add(_("cm")); - m_unitsW = new wxComboBox( itemDialog1, ID_RICHTEXTIMAGEDIALOG_UNITS_W, _("px"), wxDefaultPosition, wxSize(60, -1), m_unitsWStrings, wxCB_READONLY ); - m_unitsW->SetStringSelection(_("px")); - m_unitsW->SetHelpText(_("Units for the image width.")); - if (wxRichTextImageDialog::ShowToolTips()) - m_unitsW->SetToolTip(_("Units for the image width.")); - itemBoxSizer8->Add(m_unitsW, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); - - wxStaticText* itemStaticText11 = new wxStaticText( itemDialog1, wxID_STATIC, _("&Height:"), wxDefaultPosition, wxDefaultSize, 0 ); - itemFlexGridSizer4->Add(itemStaticText11, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL, 5); - - wxBoxSizer* itemBoxSizer12 = new wxBoxSizer(wxHORIZONTAL); - itemFlexGridSizer4->Add(itemBoxSizer12, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 5); - - m_height = new wxTextCtrl( itemDialog1, ID_RICHTEXTIMAGEDIALOG_HEIGHT, wxEmptyString, wxDefaultPosition, wxSize(65, -1), 0 ); - m_height->SetHelpText(_("The image height to be shown - does not change the source image height.")); - if (wxRichTextImageDialog::ShowToolTips()) - m_height->SetToolTip(_("The image height to be shown - does not change the source image height.")); - itemBoxSizer12->Add(m_height, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); - - wxArrayString m_unitsHStrings; - m_unitsHStrings.Add(_("px")); - m_unitsHStrings.Add(_("cm")); - m_unitsH = new wxComboBox( itemDialog1, ID_RICHTEXTIMAGEDIALOG_UNITS_H, _("px"), wxDefaultPosition, wxSize(60, -1), m_unitsHStrings, wxCB_READONLY ); - m_unitsH->SetStringSelection(_("px")); - m_unitsH->SetHelpText(_("Units for the image height.")); - if (wxRichTextImageDialog::ShowToolTips()) - m_unitsH->SetToolTip(_("Units for the image height.")); - itemBoxSizer12->Add(m_unitsH, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); - - wxStaticText* itemStaticText15 = new wxStaticText( itemDialog1, wxID_STATIC, _("Image Vertical &Offset:"), wxDefaultPosition, wxDefaultSize, 0 ); - itemFlexGridSizer4->Add(itemStaticText15, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL, 5); - - wxBoxSizer* itemBoxSizer16 = new wxBoxSizer(wxHORIZONTAL); - itemFlexGridSizer4->Add(itemBoxSizer16, 1, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 5); - - m_offset = new wxTextCtrl( itemDialog1, ID_RICHTEXTIMAGEDIALOG_OFFSET, wxEmptyString, wxDefaultPosition, wxSize(65, -1), 0 ); - m_offset->SetMaxLength(10); - m_offset->SetHelpText(_("The vertical offset relative to the paragraph.")); - if (wxRichTextImageDialog::ShowToolTips()) - m_offset->SetToolTip(_("The vertical offset relative to the paragraph.")); - itemBoxSizer16->Add(m_offset, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); - - wxArrayString m_unitsOffsetStrings; - m_unitsOffsetStrings.Add(_("px")); - m_unitsOffsetStrings.Add(_("cm")); - m_unitsOffset = new wxComboBox( itemDialog1, ID_RICHTEXTIMAGEDIALOG_OFFSET_UNITS, _("px"), wxDefaultPosition, wxSize(60, -1), m_unitsOffsetStrings, wxCB_READONLY ); - m_unitsOffset->SetStringSelection(_("px")); - m_unitsOffset->SetHelpText(_("Units for the image offset.")); - if (wxRichTextImageDialog::ShowToolTips()) - m_unitsOffset->SetToolTip(_("Units for the image offset.")); - itemBoxSizer16->Add(m_unitsOffset, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); - - wxStaticText* itemStaticText19 = new wxStaticText( itemDialog1, wxID_STATIC, _("&Move the image to:"), wxDefaultPosition, wxDefaultSize, 0 ); - itemFlexGridSizer4->Add(itemStaticText19, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL, 5); - - wxBoxSizer* itemBoxSizer20 = new wxBoxSizer(wxHORIZONTAL); - itemFlexGridSizer4->Add(itemBoxSizer20, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 5); - - wxButton* itemButton21 = new wxButton( itemDialog1, ID_RICHTEXTIMAGEDIALOG_PARA_UP, _("&Previous Paragraph"), wxDefaultPosition, wxDefaultSize, 0 ); - itemButton21->SetHelpText(_("Moves the image to the previous paragraph.")); - if (wxRichTextImageDialog::ShowToolTips()) - itemButton21->SetToolTip(_("Moves the image to the previous paragraph.")); - itemBoxSizer20->Add(itemButton21, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); - - wxButton* itemButton22 = new wxButton( itemDialog1, ID_RICHTEXTIMAGEDIALOG_DOWN, _("&Next Paragraph"), wxDefaultPosition, wxDefaultSize, 0 ); - itemButton22->SetHelpText(_("Moves the image to the next paragraph.")); - if (wxRichTextImageDialog::ShowToolTips()) - itemButton22->SetToolTip(_("Moves the image to the next paragraph.")); - itemBoxSizer20->Add(itemButton22, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxTOP|wxBOTTOM, 5); - - wxStaticLine* itemStaticLine23 = new wxStaticLine( itemDialog1, wxID_STATIC, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); - itemBoxSizer2->Add(itemStaticLine23, 0, wxGROW|wxALL, 5); - - wxStdDialogButtonSizer* itemStdDialogButtonSizer24 = new wxStdDialogButtonSizer; - - itemBoxSizer2->Add(itemStdDialogButtonSizer24, 0, wxGROW|wxALL, 5); - m_saveButton = new wxButton( itemDialog1, wxID_OK, _("OK"), wxDefaultPosition, wxDefaultSize, 0 ); - m_saveButton->SetHelpText(_("Click to confirm your changes.")); - if (wxRichTextImageDialog::ShowToolTips()) - m_saveButton->SetToolTip(_("Click to confirm your changes.")); - itemStdDialogButtonSizer24->AddButton(m_saveButton); - - m_cancelButton = new wxButton( itemDialog1, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); - m_cancelButton->SetHelpText(_("Click to discard your changes.")); - if (wxRichTextImageDialog::ShowToolTips()) - m_cancelButton->SetToolTip(_("Click to discard your changes.")); - itemStdDialogButtonSizer24->AddButton(m_cancelButton); - - itemStdDialogButtonSizer24->Realize(); - -////@end wxRichTextImageDialog content construction } @@ -276,7 +122,7 @@ void wxRichTextImageDialog::CreateControls() * Should we show tooltips? */ -bool wxRichTextImageDialog::ShowToolTips() +bool wxRichTextObjectPropertiesDialog::ShowToolTips() { return true; } @@ -285,173 +131,36 @@ bool wxRichTextImageDialog::ShowToolTips() * Get bitmap resources */ -wxBitmap wxRichTextImageDialog::GetBitmapResource( const wxString& name ) +wxBitmap wxRichTextObjectPropertiesDialog::GetBitmapResource( const wxString& name ) { // Bitmap retrieval -////@begin wxRichTextImageDialog bitmap retrieval +////@begin wxRichTextObjectPropertiesDialog bitmap retrieval wxUnusedVar(name); return wxNullBitmap; -////@end wxRichTextImageDialog bitmap retrieval +////@end wxRichTextObjectPropertiesDialog bitmap retrieval } /*! * Get icon resources */ -wxIcon wxRichTextImageDialog::GetIconResource( const wxString& name ) +wxIcon wxRichTextObjectPropertiesDialog::GetIconResource( const wxString& name ) { // Icon retrieval -////@begin wxRichTextImageDialog icon retrieval +////@begin wxRichTextObjectPropertiesDialog icon retrieval wxUnusedVar(name); return wxNullIcon; -////@end wxRichTextImageDialog icon retrieval +////@end wxRichTextObjectPropertiesDialog icon retrieval } -/*! - * Set the image attribute - */ -void wxRichTextImageDialog::SetImageAttr(const wxRichTextAttr& textAttr) -{ - m_textAttr = textAttr; - - TransferDataToWindow(); -} - -/*! - * Apply the new style - */ -wxRichTextImage* wxRichTextImageDialog::ApplyImageAttr() -{ - wxRichTextImage* image = wxDynamicCast(m_image, wxRichTextImage); - - TransferDataFromWindow(); - if (m_buffer->GetRichTextCtrl()) - { - m_buffer->GetRichTextCtrl()->SetImageStyle(image, m_textAttr); - } - return image; -} - -void wxRichTextImageDialog::SetImageObject(wxRichTextImage* image, wxRichTextBuffer* buffer) -{ - wxRichTextObject* parent = image->GetParent(); - - m_buffer = buffer; - m_image = image; - m_parent = parent; - SetImageAttr(image->GetAttributes()); - if (image->GetImageCache().IsOk()) - { - if (!m_textAttr.GetTextBoxAttr().GetWidth().IsPresent() || m_textAttr.GetTextBoxAttr().GetWidth().GetValue() <= 0) - { - m_textAttr.GetTextBoxAttr().GetWidth().SetValue(image->GetImageCache().GetWidth()); - m_textAttr.GetTextBoxAttr().GetWidth().SetUnits(wxTEXT_ATTR_UNITS_PIXELS); - } - if (!m_textAttr.GetTextBoxAttr().GetHeight().IsPresent() || m_textAttr.GetTextBoxAttr().GetHeight().GetValue() <= 0) - { - m_textAttr.GetTextBoxAttr().GetHeight().SetValue(image->GetImageCache().GetHeight()); - m_textAttr.GetTextBoxAttr().GetHeight().SetUnits(wxTEXT_ATTR_UNITS_PIXELS); - } - } -} - -void wxRichTextImageDialog::SetDimensionValue(wxTextAttrDimension& dim, wxTextCtrl* valueCtrl, wxComboBox* unitsCtrl) -{ - int unitsIdx = 0; - - if (!dim.IsPresent()) - { - dim.SetValue(0); - dim.SetUnits(wxTEXT_ATTR_UNITS_PIXELS); - } - - if (dim.GetUnits() == wxTEXT_ATTR_UNITS_TENTHS_MM) - { - unitsIdx = 1; - float value = float(dim.GetValue()) / 10.0; - valueCtrl->SetValue(wxString::Format(wxT("%.2f"), value)); - } - else - { - unitsIdx = 0; - valueCtrl->SetValue(wxString::Format(wxT("%d"), (int) dim.GetValue())); - } - - unitsCtrl->SetSelection(unitsIdx); -} - -void wxRichTextImageDialog::GetDimensionValue(wxTextAttrDimension& dim, wxTextCtrl* valueCtrl, wxComboBox* unitsCtrl) -{ - if (unitsCtrl->GetSelection() == 1) - dim.SetUnits(wxTEXT_ATTR_UNITS_TENTHS_MM); - else - dim.SetUnits(wxTEXT_ATTR_UNITS_PIXELS); - - int value = 0; - if (ConvertFromString(valueCtrl->GetValue(), value, dim.GetUnits())) - dim.SetValue(value); -} - -bool wxRichTextImageDialog::TransferDataToWindow() -{ - m_float->SetSelection(m_textAttr.GetTextBoxAttr().GetFloatMode()); - - SetDimensionValue(m_textAttr.GetTextBoxAttr().GetWidth(), m_width, m_unitsW); - SetDimensionValue(m_textAttr.GetTextBoxAttr().GetHeight(), m_height, m_unitsH); - SetDimensionValue(m_textAttr.GetTextBoxAttr().GetTop(), m_offset, m_unitsOffset); - - return true; -} - -bool wxRichTextImageDialog::TransferDataFromWindow() -{ - m_textAttr.GetTextBoxAttr().SetFloatMode(m_float->GetSelection()); - - GetDimensionValue(m_textAttr.GetTextBoxAttr().GetWidth(), m_width, m_unitsW); - GetDimensionValue(m_textAttr.GetTextBoxAttr().GetHeight(), m_height, m_unitsH); - GetDimensionValue(m_textAttr.GetTextBoxAttr().GetTop(), m_offset, m_unitsOffset); - - return true; -} - -bool wxRichTextImageDialog::ConvertFromString(const wxString& string, int& ret, int scale) -{ - const wxChar* chars = string.GetData(); - int remain = 2; - bool dot = false; - ret = 0; - - for (unsigned int i = 0; i < string.Len() && remain; i++) - { - if (!(chars[i] >= '0' && chars[i] <= '9') && !(scale == wxTEXT_ATTR_UNITS_TENTHS_MM && chars[i] == '.')) - return false; - - if (chars[i] == '.') - { - dot = true; - continue; - } - - if (dot) - remain--; - - ret = ret * 10 + chars[i] - '0'; - } - - while (remain-- > 0 && scale == wxTEXT_ATTR_UNITS_TENTHS_MM) - ret *= 10; - - return true; -} - - +#if 0 /*! * wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_BUTTON_PARA_UP */ -void wxRichTextImageDialog::OnRichtextimagedialogParaUpClick( wxCommandEvent& WXUNUSED(event)) +void wxRichTextObjectPropertiesDialog::OnRichtextParaUpClick( wxCommandEvent& WXUNUSED(event)) { // Before editing this code, remove the block markers. - wxRichTextRange range = m_image->GetRange(); + wxRichTextRange range = m_object->GetRange(); wxRichTextObjectList::compatibility_iterator iter = m_buffer->GetChildren().GetFirst(); if (!iter) return; @@ -469,12 +178,12 @@ void wxRichTextImageDialog::OnRichtextimagedialogParaUpClick( wxCommandEvent& WX wxRichTextObject *obj = iter->GetData(); wxRichTextRange rg = obj->GetRange(); - m_image = m_image->Clone(); + m_object = m_object->Clone(); m_buffer->DeleteRangeWithUndo(range, m_buffer->GetRichTextCtrl()); - m_buffer->InsertObjectWithUndo(rg.GetEnd(), m_image, m_buffer->GetRichTextCtrl(), 0); + m_buffer->InsertObjectWithUndo(rg.GetEnd(), m_object, m_buffer->GetRichTextCtrl(), 0); m_parent = obj; - m_image->SetRange(wxRichTextRange(rg.GetEnd(), rg.GetEnd())); + m_object->SetRange(wxRichTextRange(rg.GetEnd(), rg.GetEnd())); } @@ -482,10 +191,10 @@ void wxRichTextImageDialog::OnRichtextimagedialogParaUpClick( wxCommandEvent& WX * wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_BUTTON_PARA_DOWN */ -void wxRichTextImageDialog::OnRichtextimagedialogDownClick( wxCommandEvent& WXUNUSED(event)) +void wxRichTextObjectPropertiesDialog::OnRichtextDownClick( wxCommandEvent& WXUNUSED(event)) { // Before editing this code, remove the block markers. - wxRichTextRange range = m_image->GetRange(); + wxRichTextRange range = m_object->GetRange(); wxRichTextObjectList::compatibility_iterator iter = m_buffer->GetChildren().GetFirst(); if (!iter) return; @@ -503,12 +212,15 @@ void wxRichTextImageDialog::OnRichtextimagedialogDownClick( wxCommandEvent& WXUN wxRichTextObject *obj = iter->GetData(); wxRichTextRange rg = obj->GetRange(); - m_image = m_image->Clone(); + m_object = m_object->Clone(); m_buffer->DeleteRangeWithUndo(range, m_buffer->GetRichTextCtrl()); - m_buffer->InsertObjectWithUndo(rg.GetEnd(), m_image, m_buffer->GetRichTextCtrl(), 0); + m_buffer->InsertObjectWithUndo(rg.GetEnd(), m_object, m_buffer->GetRichTextCtrl(), 0); m_parent = obj; - m_image->SetRange(wxRichTextRange(rg.GetEnd(), rg.GetEnd())); + m_object->SetRange(wxRichTextRange(rg.GetEnd(), rg.GetEnd())); } #endif + +#endif + // wxUSE_RICHTEXT diff --git a/src/richtext/richtextindentspage.cpp b/src/richtext/richtextindentspage.cpp index 2605a9885b..2caf0c61c0 100644 --- a/src/richtext/richtextindentspage.cpp +++ b/src/richtext/richtextindentspage.cpp @@ -17,13 +17,13 @@ * wxRichTextIndentsSpacingPage type definition */ -IMPLEMENT_DYNAMIC_CLASS( wxRichTextIndentsSpacingPage, wxPanel ) +IMPLEMENT_DYNAMIC_CLASS( wxRichTextIndentsSpacingPage, wxRichTextDialogPage ) /*! * wxRichTextIndentsSpacingPage event table definition */ -BEGIN_EVENT_TABLE( wxRichTextIndentsSpacingPage, wxPanel ) +BEGIN_EVENT_TABLE( wxRichTextIndentsSpacingPage, wxRichTextDialogPage ) ////@begin wxRichTextIndentsSpacingPage event table entries EVT_RADIOBUTTON( ID_RICHTEXTINDENTSSPACINGPAGE_ALIGNMENT_LEFT, wxRichTextIndentsSpacingPage::OnAlignmentLeftSelected ) @@ -54,6 +54,8 @@ BEGIN_EVENT_TABLE( wxRichTextIndentsSpacingPage, wxPanel ) END_EVENT_TABLE() +IMPLEMENT_HELP_PROVISION(wxRichTextIndentsSpacingPage) + /*! * wxRichTextIndentsSpacingPage constructors */ @@ -102,7 +104,7 @@ void wxRichTextIndentsSpacingPage::Init() bool wxRichTextIndentsSpacingPage::Create( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) { ////@begin wxRichTextIndentsSpacingPage creation - wxPanel::Create( parent, id, pos, size, style ); + wxRichTextDialogPage::Create( parent, id, pos, size, style ); CreateControls(); if (GetSizer()) @@ -121,10 +123,10 @@ bool wxRichTextIndentsSpacingPage::Create( wxWindow* parent, wxWindowID id, cons void wxRichTextIndentsSpacingPage::CreateControls() { ////@begin wxRichTextIndentsSpacingPage content construction - wxRichTextIndentsSpacingPage* itemPanel1 = this; + wxRichTextIndentsSpacingPage* itemRichTextDialogPage1 = this; wxBoxSizer* itemBoxSizer2 = new wxBoxSizer(wxVERTICAL); - itemPanel1->SetSizer(itemBoxSizer2); + itemRichTextDialogPage1->SetSizer(itemBoxSizer2); wxBoxSizer* itemBoxSizer3 = new wxBoxSizer(wxVERTICAL); itemBoxSizer2->Add(itemBoxSizer3, 1, wxGROW|wxALL, 5); @@ -135,7 +137,7 @@ void wxRichTextIndentsSpacingPage::CreateControls() wxBoxSizer* itemBoxSizer5 = new wxBoxSizer(wxVERTICAL); itemBoxSizer4->Add(itemBoxSizer5, 0, wxGROW, 5); - wxStaticText* itemStaticText6 = new wxStaticText( itemPanel1, wxID_STATIC, _("&Alignment"), wxDefaultPosition, wxDefaultSize, 0 ); + wxStaticText* itemStaticText6 = new wxStaticText( itemRichTextDialogPage1, wxID_STATIC, _("&Alignment"), wxDefaultPosition, wxDefaultSize, 0 ); itemBoxSizer5->Add(itemStaticText6, 0, wxALIGN_LEFT|wxLEFT|wxRIGHT|wxTOP, 5); wxBoxSizer* itemBoxSizer7 = new wxBoxSizer(wxHORIZONTAL); @@ -146,35 +148,35 @@ void wxRichTextIndentsSpacingPage::CreateControls() wxBoxSizer* itemBoxSizer9 = new wxBoxSizer(wxVERTICAL); itemBoxSizer7->Add(itemBoxSizer9, 0, wxALIGN_CENTER_VERTICAL|wxTOP, 5); - m_alignmentLeft = new wxRadioButton( itemPanel1, ID_RICHTEXTINDENTSSPACINGPAGE_ALIGNMENT_LEFT, _("&Left"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP ); + m_alignmentLeft = new wxRadioButton( itemRichTextDialogPage1, ID_RICHTEXTINDENTSSPACINGPAGE_ALIGNMENT_LEFT, _("&Left"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP ); m_alignmentLeft->SetValue(false); m_alignmentLeft->SetHelpText(_("Left-align text.")); if (wxRichTextIndentsSpacingPage::ShowToolTips()) m_alignmentLeft->SetToolTip(_("Left-align text.")); itemBoxSizer9->Add(m_alignmentLeft, 0, wxALIGN_LEFT|wxALL, 5); - m_alignmentRight = new wxRadioButton( itemPanel1, ID_RICHTEXTINDENTSSPACINGPAGE_ALIGNMENT_RIGHT, _("&Right"), wxDefaultPosition, wxDefaultSize, 0 ); + m_alignmentRight = new wxRadioButton( itemRichTextDialogPage1, ID_RICHTEXTINDENTSSPACINGPAGE_ALIGNMENT_RIGHT, _("&Right"), wxDefaultPosition, wxDefaultSize, 0 ); m_alignmentRight->SetValue(false); m_alignmentRight->SetHelpText(_("Right-align text.")); if (wxRichTextIndentsSpacingPage::ShowToolTips()) m_alignmentRight->SetToolTip(_("Right-align text.")); itemBoxSizer9->Add(m_alignmentRight, 0, wxALIGN_LEFT|wxALL, 5); - m_alignmentJustified = new wxRadioButton( itemPanel1, ID_RICHTEXTINDENTSSPACINGPAGE_ALIGNMENT_JUSTIFIED, _("&Justified"), wxDefaultPosition, wxDefaultSize, 0 ); + m_alignmentJustified = new wxRadioButton( itemRichTextDialogPage1, ID_RICHTEXTINDENTSSPACINGPAGE_ALIGNMENT_JUSTIFIED, _("&Justified"), wxDefaultPosition, wxDefaultSize, 0 ); m_alignmentJustified->SetValue(false); m_alignmentJustified->SetHelpText(_("Justify text left and right.")); if (wxRichTextIndentsSpacingPage::ShowToolTips()) m_alignmentJustified->SetToolTip(_("Justify text left and right.")); itemBoxSizer9->Add(m_alignmentJustified, 0, wxALIGN_LEFT|wxALL, 5); - m_alignmentCentred = new wxRadioButton( itemPanel1, ID_RICHTEXTINDENTSSPACINGPAGE_ALIGNMENT_CENTRED, _("Cen&tred"), wxDefaultPosition, wxDefaultSize, 0 ); + m_alignmentCentred = new wxRadioButton( itemRichTextDialogPage1, ID_RICHTEXTINDENTSSPACINGPAGE_ALIGNMENT_CENTRED, _("Cen&tred"), wxDefaultPosition, wxDefaultSize, 0 ); m_alignmentCentred->SetValue(false); m_alignmentCentred->SetHelpText(_("Centre text.")); if (wxRichTextIndentsSpacingPage::ShowToolTips()) m_alignmentCentred->SetToolTip(_("Centre text.")); itemBoxSizer9->Add(m_alignmentCentred, 0, wxALIGN_LEFT|wxALL, 5); - m_alignmentIndeterminate = new wxRadioButton( itemPanel1, ID_RICHTEXTINDENTSSPACINGPAGE_ALIGNMENT_INDETERMINATE, _("&Indeterminate"), wxDefaultPosition, wxDefaultSize, 0 ); + m_alignmentIndeterminate = new wxRadioButton( itemRichTextDialogPage1, ID_RICHTEXTINDENTSSPACINGPAGE_ALIGNMENT_INDETERMINATE, _("&Indeterminate"), wxDefaultPosition, wxDefaultSize, 0 ); m_alignmentIndeterminate->SetValue(false); m_alignmentIndeterminate->SetHelpText(_("Use the current alignment setting.")); if (wxRichTextIndentsSpacingPage::ShowToolTips()) @@ -183,7 +185,7 @@ void wxRichTextIndentsSpacingPage::CreateControls() itemBoxSizer4->Add(2, 1, 1, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM, 5); - wxStaticLine* itemStaticLine16 = new wxStaticLine( itemPanel1, wxID_STATIC, wxDefaultPosition, wxDefaultSize, wxLI_VERTICAL ); + wxStaticLine* itemStaticLine16 = new wxStaticLine( itemRichTextDialogPage1, wxID_STATIC, wxDefaultPosition, wxDefaultSize, wxLI_VERTICAL ); itemBoxSizer4->Add(itemStaticLine16, 0, wxGROW|wxLEFT|wxBOTTOM, 5); itemBoxSizer4->Add(2, 1, 1, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM, 5); @@ -191,7 +193,7 @@ void wxRichTextIndentsSpacingPage::CreateControls() wxBoxSizer* itemBoxSizer18 = new wxBoxSizer(wxVERTICAL); itemBoxSizer4->Add(itemBoxSizer18, 0, wxGROW, 5); - wxStaticText* itemStaticText19 = new wxStaticText( itemPanel1, wxID_STATIC, _("&Indentation (tenths of a mm)"), wxDefaultPosition, wxDefaultSize, 0 ); + wxStaticText* itemStaticText19 = new wxStaticText( itemRichTextDialogPage1, wxID_STATIC, _("&Indentation (tenths of a mm)"), wxDefaultPosition, wxDefaultSize, 0 ); itemBoxSizer18->Add(itemStaticText19, 0, wxALIGN_LEFT|wxLEFT|wxRIGHT|wxTOP, 5); wxBoxSizer* itemBoxSizer20 = new wxBoxSizer(wxHORIZONTAL); @@ -202,43 +204,43 @@ void wxRichTextIndentsSpacingPage::CreateControls() wxFlexGridSizer* itemFlexGridSizer22 = new wxFlexGridSizer(4, 2, 0, 0); itemBoxSizer20->Add(itemFlexGridSizer22, 0, wxALIGN_CENTER_VERTICAL, 5); - wxStaticText* itemStaticText23 = new wxStaticText( itemPanel1, wxID_STATIC, _("&Left:"), wxDefaultPosition, wxDefaultSize, 0 ); + wxStaticText* itemStaticText23 = new wxStaticText( itemRichTextDialogPage1, wxID_STATIC, _("&Left:"), wxDefaultPosition, wxDefaultSize, 0 ); itemFlexGridSizer22->Add(itemStaticText23, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL, 5); wxBoxSizer* itemBoxSizer24 = new wxBoxSizer(wxHORIZONTAL); itemFlexGridSizer22->Add(itemBoxSizer24, 0, wxGROW|wxALIGN_CENTER_VERTICAL, 5); - m_indentLeft = new wxTextCtrl( itemPanel1, ID_RICHTEXTINDENTSSPACINGPAGE_INDENT_LEFT, wxEmptyString, wxDefaultPosition, wxSize(50, -1), 0 ); + m_indentLeft = new wxTextCtrl( itemRichTextDialogPage1, ID_RICHTEXTINDENTSSPACINGPAGE_INDENT_LEFT, wxEmptyString, wxDefaultPosition, wxSize(50, -1), 0 ); m_indentLeft->SetHelpText(_("The left indent.")); if (wxRichTextIndentsSpacingPage::ShowToolTips()) m_indentLeft->SetToolTip(_("The left indent.")); itemBoxSizer24->Add(m_indentLeft, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5); - wxStaticText* itemStaticText26 = new wxStaticText( itemPanel1, wxID_STATIC, _("Left (&first line):"), wxDefaultPosition, wxDefaultSize, 0 ); + wxStaticText* itemStaticText26 = new wxStaticText( itemRichTextDialogPage1, wxID_STATIC, _("Left (&first line):"), wxDefaultPosition, wxDefaultSize, 0 ); itemFlexGridSizer22->Add(itemStaticText26, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL, 5); wxBoxSizer* itemBoxSizer27 = new wxBoxSizer(wxHORIZONTAL); itemFlexGridSizer22->Add(itemBoxSizer27, 0, wxGROW|wxALIGN_CENTER_VERTICAL, 5); - m_indentLeftFirst = new wxTextCtrl( itemPanel1, ID_RICHTEXTINDENTSSPACINGPAGE_INDENT_LEFT_FIRST, wxEmptyString, wxDefaultPosition, wxSize(50, -1), 0 ); + m_indentLeftFirst = new wxTextCtrl( itemRichTextDialogPage1, ID_RICHTEXTINDENTSSPACINGPAGE_INDENT_LEFT_FIRST, wxEmptyString, wxDefaultPosition, wxSize(50, -1), 0 ); m_indentLeftFirst->SetHelpText(_("The first line indent.")); if (wxRichTextIndentsSpacingPage::ShowToolTips()) m_indentLeftFirst->SetToolTip(_("The first line indent.")); itemBoxSizer27->Add(m_indentLeftFirst, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5); - wxStaticText* itemStaticText29 = new wxStaticText( itemPanel1, wxID_STATIC, _("&Right:"), wxDefaultPosition, wxDefaultSize, 0 ); + wxStaticText* itemStaticText29 = new wxStaticText( itemRichTextDialogPage1, wxID_STATIC, _("&Right:"), wxDefaultPosition, wxDefaultSize, 0 ); itemFlexGridSizer22->Add(itemStaticText29, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL, 5); wxBoxSizer* itemBoxSizer30 = new wxBoxSizer(wxHORIZONTAL); itemFlexGridSizer22->Add(itemBoxSizer30, 0, wxGROW|wxALIGN_CENTER_VERTICAL, 5); - m_indentRight = new wxTextCtrl( itemPanel1, ID_RICHTEXTINDENTSSPACINGPAGE_INDENT_RIGHT, wxEmptyString, wxDefaultPosition, wxSize(50, -1), 0 ); + m_indentRight = new wxTextCtrl( itemRichTextDialogPage1, ID_RICHTEXTINDENTSSPACINGPAGE_INDENT_RIGHT, wxEmptyString, wxDefaultPosition, wxSize(50, -1), 0 ); m_indentRight->SetHelpText(_("The right indent.")); if (wxRichTextIndentsSpacingPage::ShowToolTips()) m_indentRight->SetToolTip(_("The right indent.")); itemBoxSizer30->Add(m_indentRight, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5); - wxStaticText* itemStaticText32 = new wxStaticText( itemPanel1, wxID_STATIC, _("&Outline level:"), wxDefaultPosition, wxDefaultSize, 0 ); + wxStaticText* itemStaticText32 = new wxStaticText( itemRichTextDialogPage1, wxID_STATIC, _("&Outline level:"), wxDefaultPosition, wxDefaultSize, 0 ); itemFlexGridSizer22->Add(itemStaticText32, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL, 5); wxArrayString m_outlineLevelCtrlStrings; @@ -252,7 +254,7 @@ void wxRichTextIndentsSpacingPage::CreateControls() m_outlineLevelCtrlStrings.Add(_("7")); m_outlineLevelCtrlStrings.Add(_("8")); m_outlineLevelCtrlStrings.Add(_("9")); - m_outlineLevelCtrl = new wxComboBox( itemPanel1, ID_RICHTEXTINDENTSSPACINGPAGE_OUTLINELEVEL, _("Normal"), wxDefaultPosition, wxSize(90, -1), m_outlineLevelCtrlStrings, wxCB_READONLY ); + m_outlineLevelCtrl = new wxComboBox( itemRichTextDialogPage1, ID_RICHTEXTINDENTSSPACINGPAGE_OUTLINELEVEL, _("Normal"), wxDefaultPosition, wxSize(90, -1), m_outlineLevelCtrlStrings, wxCB_READONLY ); m_outlineLevelCtrl->SetStringSelection(_("Normal")); m_outlineLevelCtrl->SetHelpText(_("The outline level.")); if (wxRichTextIndentsSpacingPage::ShowToolTips()) @@ -261,7 +263,7 @@ void wxRichTextIndentsSpacingPage::CreateControls() itemBoxSizer4->Add(2, 1, 1, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM, 5); - wxStaticLine* itemStaticLine35 = new wxStaticLine( itemPanel1, wxID_STATIC, wxDefaultPosition, wxDefaultSize, wxLI_VERTICAL ); + wxStaticLine* itemStaticLine35 = new wxStaticLine( itemRichTextDialogPage1, wxID_STATIC, wxDefaultPosition, wxDefaultSize, wxLI_VERTICAL ); itemBoxSizer4->Add(itemStaticLine35, 0, wxGROW|wxTOP|wxBOTTOM, 5); itemBoxSizer4->Add(2, 1, 1, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM, 5); @@ -269,7 +271,7 @@ void wxRichTextIndentsSpacingPage::CreateControls() wxBoxSizer* itemBoxSizer37 = new wxBoxSizer(wxVERTICAL); itemBoxSizer4->Add(itemBoxSizer37, 0, wxGROW, 5); - wxStaticText* itemStaticText38 = new wxStaticText( itemPanel1, wxID_STATIC, _("&Spacing (tenths of a mm)"), wxDefaultPosition, wxDefaultSize, 0 ); + wxStaticText* itemStaticText38 = new wxStaticText( itemRichTextDialogPage1, wxID_STATIC, _("&Spacing (tenths of a mm)"), wxDefaultPosition, wxDefaultSize, 0 ); itemBoxSizer37->Add(itemStaticText38, 0, wxALIGN_LEFT|wxLEFT|wxRIGHT|wxTOP, 5); wxBoxSizer* itemBoxSizer39 = new wxBoxSizer(wxHORIZONTAL); @@ -281,30 +283,30 @@ void wxRichTextIndentsSpacingPage::CreateControls() itemFlexGridSizer41->AddGrowableCol(1); itemBoxSizer39->Add(itemFlexGridSizer41, 0, wxALIGN_CENTER_VERTICAL, 5); - wxStaticText* itemStaticText42 = new wxStaticText( itemPanel1, wxID_STATIC, _("&Before a paragraph:"), wxDefaultPosition, wxDefaultSize, 0 ); + wxStaticText* itemStaticText42 = new wxStaticText( itemRichTextDialogPage1, wxID_STATIC, _("&Before a paragraph:"), wxDefaultPosition, wxDefaultSize, 0 ); itemFlexGridSizer41->Add(itemStaticText42, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL, 5); wxBoxSizer* itemBoxSizer43 = new wxBoxSizer(wxHORIZONTAL); itemFlexGridSizer41->Add(itemBoxSizer43, 0, wxGROW|wxALIGN_CENTER_VERTICAL, 5); - m_spacingBefore = new wxTextCtrl( itemPanel1, ID_RICHTEXTINDENTSSPACINGPAGE_SPACING_BEFORE, wxEmptyString, wxDefaultPosition, wxSize(50, -1), 0 ); + m_spacingBefore = new wxTextCtrl( itemRichTextDialogPage1, ID_RICHTEXTINDENTSSPACINGPAGE_SPACING_BEFORE, wxEmptyString, wxDefaultPosition, wxSize(50, -1), 0 ); m_spacingBefore->SetHelpText(_("The spacing before the paragraph.")); if (wxRichTextIndentsSpacingPage::ShowToolTips()) m_spacingBefore->SetToolTip(_("The spacing before the paragraph.")); itemBoxSizer43->Add(m_spacingBefore, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5); - wxStaticText* itemStaticText45 = new wxStaticText( itemPanel1, wxID_STATIC, _("&After a paragraph:"), wxDefaultPosition, wxDefaultSize, 0 ); + wxStaticText* itemStaticText45 = new wxStaticText( itemRichTextDialogPage1, wxID_STATIC, _("&After a paragraph:"), wxDefaultPosition, wxDefaultSize, 0 ); itemFlexGridSizer41->Add(itemStaticText45, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL, 5); wxBoxSizer* itemBoxSizer46 = new wxBoxSizer(wxHORIZONTAL); itemFlexGridSizer41->Add(itemBoxSizer46, 1, wxGROW|wxALIGN_CENTER_VERTICAL, 5); - m_spacingAfter = new wxTextCtrl( itemPanel1, ID_RICHTEXTINDENTSSPACINGPAGE_SPACING_AFTER, wxEmptyString, wxDefaultPosition, wxSize(50, -1), 0 ); + m_spacingAfter = new wxTextCtrl( itemRichTextDialogPage1, ID_RICHTEXTINDENTSSPACINGPAGE_SPACING_AFTER, wxEmptyString, wxDefaultPosition, wxSize(50, -1), 0 ); if (wxRichTextIndentsSpacingPage::ShowToolTips()) m_spacingAfter->SetToolTip(_("The spacing after the paragraph.")); itemBoxSizer46->Add(m_spacingAfter, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5); - wxStaticText* itemStaticText48 = new wxStaticText( itemPanel1, wxID_STATIC, _("L&ine spacing:"), wxDefaultPosition, wxDefaultSize, 0 ); + wxStaticText* itemStaticText48 = new wxStaticText( itemRichTextDialogPage1, wxID_STATIC, _("L&ine spacing:"), wxDefaultPosition, wxDefaultSize, 0 ); itemFlexGridSizer41->Add(itemStaticText48, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL, 5); wxBoxSizer* itemBoxSizer49 = new wxBoxSizer(wxHORIZONTAL); @@ -322,7 +324,7 @@ void wxRichTextIndentsSpacingPage::CreateControls() m_spacingLineStrings.Add(_("1.8")); m_spacingLineStrings.Add(_("1.9")); m_spacingLineStrings.Add(_("2")); - m_spacingLine = new wxComboBox( itemPanel1, ID_RICHTEXTINDENTSSPACINGPAGE_SPACING_LINE, _("Single"), wxDefaultPosition, wxSize(90, -1), m_spacingLineStrings, wxCB_READONLY ); + m_spacingLine = new wxComboBox( itemRichTextDialogPage1, ID_RICHTEXTINDENTSSPACINGPAGE_SPACING_LINE, _("Single"), wxDefaultPosition, wxSize(90, -1), m_spacingLineStrings, wxCB_READONLY ); m_spacingLine->SetStringSelection(_("Single")); m_spacingLine->SetHelpText(_("The line spacing.")); if (wxRichTextIndentsSpacingPage::ShowToolTips()) @@ -331,7 +333,7 @@ void wxRichTextIndentsSpacingPage::CreateControls() itemBoxSizer3->Add(5, 5, 0, wxALIGN_CENTER_HORIZONTAL, 5); - m_previewCtrl = new wxRichTextCtrl( itemPanel1, ID_RICHTEXTINDENTSSPACINGPAGE_PREVIEW_CTRL, wxEmptyString, wxDefaultPosition, wxSize(350, 100), wxVSCROLL|wxTE_READONLY ); + m_previewCtrl = new wxRichTextCtrl( itemRichTextDialogPage1, ID_RICHTEXTINDENTSSPACINGPAGE_PREVIEW_CTRL, wxEmptyString, wxDefaultPosition, wxSize(350, 100), wxVSCROLL|wxTE_READONLY ); m_previewCtrl->SetHelpText(_("Shows a preview of the paragraph settings.")); if (wxRichTextIndentsSpacingPage::ShowToolTips()) m_previewCtrl->SetToolTip(_("Shows a preview of the paragraph settings.")); diff --git a/src/richtext/richtextliststylepage.cpp b/src/richtext/richtextliststylepage.cpp index ca89d6628a..914334e362 100644 --- a/src/richtext/richtextliststylepage.cpp +++ b/src/richtext/richtextliststylepage.cpp @@ -18,13 +18,13 @@ * wxRichTextListStylePage type definition */ -IMPLEMENT_DYNAMIC_CLASS( wxRichTextListStylePage, wxPanel ) +IMPLEMENT_DYNAMIC_CLASS( wxRichTextListStylePage, wxRichTextDialogPage ) /*! * wxRichTextListStylePage event table definition */ -BEGIN_EVENT_TABLE( wxRichTextListStylePage, wxPanel ) +BEGIN_EVENT_TABLE( wxRichTextListStylePage, wxRichTextDialogPage ) ////@begin wxRichTextListStylePage event table entries EVT_SPINCTRL( ID_RICHTEXTLISTSTYLEPAGE_LEVEL, wxRichTextListStylePage::OnLevelUpdated ) @@ -93,6 +93,8 @@ BEGIN_EVENT_TABLE( wxRichTextListStylePage, wxPanel ) END_EVENT_TABLE() +IMPLEMENT_HELP_PROVISION(wxRichTextListStylePage) + /*! * wxRichTextListStylePage constructors */ @@ -115,7 +117,7 @@ wxRichTextListStylePage::wxRichTextListStylePage( wxWindow* parent, wxWindowID i bool wxRichTextListStylePage::Create( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) { ////@begin wxRichTextListStylePage creation - wxPanel::Create( parent, id, pos, size, style ); + wxRichTextDialogPage::Create( parent, id, pos, size, style ); CreateControls(); if (GetSizer()) @@ -168,10 +170,10 @@ void wxRichTextListStylePage::Init() void wxRichTextListStylePage::CreateControls() { ////@begin wxRichTextListStylePage content construction - wxRichTextListStylePage* itemPanel1 = this; + wxRichTextListStylePage* itemRichTextDialogPage1 = this; wxBoxSizer* itemBoxSizer2 = new wxBoxSizer(wxVERTICAL); - itemPanel1->SetSizer(itemBoxSizer2); + itemRichTextDialogPage1->SetSizer(itemBoxSizer2); wxBoxSizer* itemBoxSizer3 = new wxBoxSizer(wxVERTICAL); itemBoxSizer2->Add(itemBoxSizer3, 1, wxGROW|wxALL, 5); @@ -179,10 +181,10 @@ void wxRichTextListStylePage::CreateControls() wxBoxSizer* itemBoxSizer4 = new wxBoxSizer(wxHORIZONTAL); itemBoxSizer3->Add(itemBoxSizer4, 0, wxALIGN_CENTER_HORIZONTAL, 5); - wxStaticText* itemStaticText5 = new wxStaticText( itemPanel1, wxID_STATIC, _("&List level:"), wxDefaultPosition, wxDefaultSize, 0 ); + wxStaticText* itemStaticText5 = new wxStaticText( itemRichTextDialogPage1, wxID_STATIC, _("&List level:"), wxDefaultPosition, wxDefaultSize, 0 ); itemBoxSizer4->Add(itemStaticText5, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); - m_levelCtrl = new wxSpinCtrl( itemPanel1, ID_RICHTEXTLISTSTYLEPAGE_LEVEL, wxT("1"), wxDefaultPosition, wxSize(60, -1), wxSP_ARROW_KEYS, 1, 10, 1 ); + m_levelCtrl = new wxSpinCtrl( itemRichTextDialogPage1, ID_RICHTEXTLISTSTYLEPAGE_LEVEL, _T("1"), wxDefaultPosition, wxSize(60, -1), wxSP_ARROW_KEYS, 1, 10, 1 ); m_levelCtrl->SetHelpText(_("Selects the list level to edit.")); if (wxRichTextListStylePage::ShowToolTips()) m_levelCtrl->SetToolTip(_("Selects the list level to edit.")); @@ -190,13 +192,13 @@ void wxRichTextListStylePage::CreateControls() itemBoxSizer4->Add(5, 5, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); - wxButton* itemButton8 = new wxButton( itemPanel1, ID_RICHTEXTLISTSTYLEPAGE_CHOOSE_FONT, _("&Font for Level..."), wxDefaultPosition, wxDefaultSize, 0 ); + wxButton* itemButton8 = new wxButton( itemRichTextDialogPage1, ID_RICHTEXTLISTSTYLEPAGE_CHOOSE_FONT, _("&Font for Level..."), wxDefaultPosition, wxDefaultSize, 0 ); itemButton8->SetHelpText(_("Click to choose the font for this level.")); if (wxRichTextListStylePage::ShowToolTips()) itemButton8->SetToolTip(_("Click to choose the font for this level.")); itemBoxSizer4->Add(itemButton8, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); - wxNotebook* itemNotebook9 = new wxNotebook( itemPanel1, ID_RICHTEXTLISTSTYLEPAGE_NOTEBOOK, wxDefaultPosition, wxDefaultSize, wxNB_DEFAULT|wxNB_TOP ); + wxNotebook* itemNotebook9 = new wxNotebook( itemRichTextDialogPage1, ID_RICHTEXTLISTSTYLEPAGE_NOTEBOOK, wxDefaultPosition, wxDefaultSize, wxBK_DEFAULT|wxBK_TOP ); wxPanel* itemPanel10 = new wxPanel( itemNotebook9, ID_RICHTEXTLISTSTYLEPAGE_BULLETS, wxDefaultPosition, wxDefaultSize, wxNO_BORDER|wxTAB_TRAVERSAL ); wxBoxSizer* itemBoxSizer11 = new wxBoxSizer(wxVERTICAL); @@ -270,7 +272,7 @@ void wxRichTextListStylePage::CreateControls() wxBoxSizer* itemBoxSizer28 = new wxBoxSizer(wxHORIZONTAL); itemBoxSizer26->Add(itemBoxSizer28, 0, wxGROW, 5); wxArrayString m_symbolCtrlStrings; - m_symbolCtrl = new wxComboBox( itemPanel10, ID_RICHTEXTLISTSTYLEPAGE_SYMBOLCTRL, wxT(""), wxDefaultPosition, wxSize(60, -1), m_symbolCtrlStrings, wxCB_DROPDOWN ); + m_symbolCtrl = new wxComboBox( itemPanel10, ID_RICHTEXTLISTSTYLEPAGE_SYMBOLCTRL, wxEmptyString, wxDefaultPosition, wxSize(60, -1), m_symbolCtrlStrings, wxCB_DROPDOWN ); m_symbolCtrl->SetHelpText(_("The bullet character.")); if (wxRichTextListStylePage::ShowToolTips()) m_symbolCtrl->SetToolTip(_("The bullet character.")); @@ -288,7 +290,7 @@ void wxRichTextListStylePage::CreateControls() itemBoxSizer26->Add(itemStaticText32, 0, wxALIGN_LEFT|wxLEFT|wxRIGHT|wxTOP, 5); wxArrayString m_symbolFontCtrlStrings; - m_symbolFontCtrl = new wxComboBox( itemPanel10, ID_RICHTEXTLISTSTYLEPAGE_SYMBOLFONTCTRL, wxT(""), wxDefaultPosition, wxDefaultSize, m_symbolFontCtrlStrings, wxCB_DROPDOWN ); + m_symbolFontCtrl = new wxComboBox( itemPanel10, ID_RICHTEXTLISTSTYLEPAGE_SYMBOLFONTCTRL, wxEmptyString, wxDefaultPosition, wxDefaultSize, m_symbolFontCtrlStrings, wxCB_DROPDOWN ); if (wxRichTextListStylePage::ShowToolTips()) m_symbolFontCtrl->SetToolTip(_("Available fonts.")); itemBoxSizer26->Add(m_symbolFontCtrl, 0, wxGROW|wxALL, 5); @@ -299,7 +301,7 @@ void wxRichTextListStylePage::CreateControls() itemBoxSizer26->Add(itemStaticText35, 0, wxALIGN_LEFT|wxLEFT|wxRIGHT|wxTOP, 5); wxArrayString m_bulletNameCtrlStrings; - m_bulletNameCtrl = new wxComboBox( itemPanel10, ID_RICHTEXTLISTSTYLEPAGE_NAMECTRL, wxT(""), wxDefaultPosition, wxDefaultSize, m_bulletNameCtrlStrings, wxCB_DROPDOWN ); + m_bulletNameCtrl = new wxComboBox( itemPanel10, ID_RICHTEXTLISTSTYLEPAGE_NAMECTRL, wxEmptyString, wxDefaultPosition, wxDefaultSize, m_bulletNameCtrlStrings, wxCB_DROPDOWN ); m_bulletNameCtrl->SetHelpText(_("A standard bullet name.")); if (wxRichTextListStylePage::ShowToolTips()) m_bulletNameCtrl->SetToolTip(_("A standard bullet name.")); @@ -382,7 +384,7 @@ void wxRichTextListStylePage::CreateControls() wxBoxSizer* itemBoxSizer59 = new wxBoxSizer(wxHORIZONTAL); itemFlexGridSizer57->Add(itemBoxSizer59, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); - m_indentLeft = new wxTextCtrl( itemPanel37, ID_RICHTEXTLISTSTYLEPAGE_INDENTLEFT, wxT(""), wxDefaultPosition, wxSize(50, -1), 0 ); + m_indentLeft = new wxTextCtrl( itemPanel37, ID_RICHTEXTLISTSTYLEPAGE_INDENTLEFT, wxEmptyString, wxDefaultPosition, wxSize(50, -1), 0 ); m_indentLeft->SetHelpText(_("The left indent.")); if (wxRichTextListStylePage::ShowToolTips()) m_indentLeft->SetToolTip(_("The left indent.")); @@ -393,7 +395,7 @@ void wxRichTextListStylePage::CreateControls() wxBoxSizer* itemBoxSizer62 = new wxBoxSizer(wxHORIZONTAL); itemFlexGridSizer57->Add(itemBoxSizer62, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); - m_indentLeftFirst = new wxTextCtrl( itemPanel37, ID_RICHTEXTLISTSTYLEPAGE_INDENTFIRSTLINE, wxT(""), wxDefaultPosition, wxSize(50, -1), 0 ); + m_indentLeftFirst = new wxTextCtrl( itemPanel37, ID_RICHTEXTLISTSTYLEPAGE_INDENTFIRSTLINE, wxEmptyString, wxDefaultPosition, wxSize(50, -1), 0 ); m_indentLeftFirst->SetHelpText(_("The first line indent.")); if (wxRichTextListStylePage::ShowToolTips()) m_indentLeftFirst->SetToolTip(_("The first line indent.")); @@ -404,7 +406,7 @@ void wxRichTextListStylePage::CreateControls() wxBoxSizer* itemBoxSizer65 = new wxBoxSizer(wxHORIZONTAL); itemFlexGridSizer57->Add(itemBoxSizer65, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); - m_indentRight = new wxTextCtrl( itemPanel37, ID_RICHTEXTLISTSTYLEPAGE_INDENTRIGHT, wxT(""), wxDefaultPosition, wxSize(50, -1), 0 ); + m_indentRight = new wxTextCtrl( itemPanel37, ID_RICHTEXTLISTSTYLEPAGE_INDENTRIGHT, wxEmptyString, wxDefaultPosition, wxSize(50, -1), 0 ); m_indentRight->SetHelpText(_("The right indent.")); if (wxRichTextListStylePage::ShowToolTips()) m_indentRight->SetToolTip(_("The right indent.")); @@ -433,7 +435,7 @@ void wxRichTextListStylePage::CreateControls() wxBoxSizer* itemBoxSizer76 = new wxBoxSizer(wxHORIZONTAL); itemFlexGridSizer74->Add(itemBoxSizer76, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); - m_spacingBefore = new wxTextCtrl( itemPanel37, ID_RICHTEXTLISTSTYLEPAGE_SPACINGBEFORE, wxT(""), wxDefaultPosition, wxSize(50, -1), 0 ); + m_spacingBefore = new wxTextCtrl( itemPanel37, ID_RICHTEXTLISTSTYLEPAGE_SPACINGBEFORE, wxEmptyString, wxDefaultPosition, wxSize(50, -1), 0 ); m_spacingBefore->SetHelpText(_("The spacing before the paragraph.")); if (wxRichTextListStylePage::ShowToolTips()) m_spacingBefore->SetToolTip(_("The spacing before the paragraph.")); @@ -444,7 +446,7 @@ void wxRichTextListStylePage::CreateControls() wxBoxSizer* itemBoxSizer79 = new wxBoxSizer(wxHORIZONTAL); itemFlexGridSizer74->Add(itemBoxSizer79, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5); - m_spacingAfter = new wxTextCtrl( itemPanel37, ID_RICHTEXTLISTSTYLEPAGE_SPACINGAFTER, wxT(""), wxDefaultPosition, wxSize(50, -1), 0 ); + m_spacingAfter = new wxTextCtrl( itemPanel37, ID_RICHTEXTLISTSTYLEPAGE_SPACINGAFTER, wxEmptyString, wxDefaultPosition, wxSize(50, -1), 0 ); m_spacingAfter->SetHelpText(_("The spacing after the paragraph.")); if (wxRichTextListStylePage::ShowToolTips()) m_spacingAfter->SetToolTip(_("The spacing after the paragraph.")); @@ -470,7 +472,7 @@ void wxRichTextListStylePage::CreateControls() itemBoxSizer3->Add(itemNotebook9, 0, wxGROW|wxALL, 5); - m_previewCtrl = new wxRichTextCtrl( itemPanel1, ID_RICHTEXTLISTSTYLEPAGE_RICHTEXTCTRL, wxEmptyString, wxDefaultPosition, wxSize(350, 180), wxSUNKEN_BORDER|wxVSCROLL|wxTE_READONLY ); + m_previewCtrl = new wxRichTextCtrl( itemRichTextDialogPage1, ID_RICHTEXTLISTSTYLEPAGE_RICHTEXTCTRL, wxEmptyString, wxDefaultPosition, wxSize(350, 180), wxSUNKEN_BORDER|wxVSCROLL|wxTE_READONLY ); m_previewCtrl->SetHelpText(_("Shows a preview of the bullet settings.")); if (wxRichTextListStylePage::ShowToolTips()) m_previewCtrl->SetToolTip(_("Shows a preview of the bullet settings.")); diff --git a/src/richtext/richtextmarginspage.cpp b/src/richtext/richtextmarginspage.cpp new file mode 100644 index 0000000000..c0d68e2fdc --- /dev/null +++ b/src/richtext/richtextmarginspage.cpp @@ -0,0 +1,563 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: richtextmarginspage.cpp +// Purpose: +// Author: Julian Smart +// Modified by: +// Created: 20/10/2010 10:27:34 +// RCS-ID: +// Copyright: (c) Julian Smart +// Licence: +///////////////////////////////////////////////////////////////////////////// + +// For compilers that support precompilation, includes "wx/wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +////@begin includes +////@end includes + +#include "wx/richtext/richtextmarginspage.h" + +////@begin XPM images +////@end XPM images + + +/*! + * wxRichTextMarginsPage type definition + */ + +IMPLEMENT_DYNAMIC_CLASS( wxRichTextMarginsPage, wxRichTextDialogPage ) + + +/*! + * wxRichTextMarginsPage event table definition + */ + +BEGIN_EVENT_TABLE( wxRichTextMarginsPage, wxRichTextDialogPage ) + +////@begin wxRichTextMarginsPage event table entries + EVT_UPDATE_UI( ID_RICHTEXT_LEFT_MARGIN, wxRichTextMarginsPage::OnRichtextLeftMarginUpdate ) + + EVT_UPDATE_UI( ID_RICHTEXT_LEFT_MARGIN_UNITS, wxRichTextMarginsPage::OnRichtextLeftMarginUpdate ) + + EVT_UPDATE_UI( ID_RICHTEXT_RIGHT_MARGIN, wxRichTextMarginsPage::OnRichtextRightMarginUpdate ) + + EVT_UPDATE_UI( ID_RICHTEXT_RIGHT_MARGIN_UNITS, wxRichTextMarginsPage::OnRichtextRightMarginUpdate ) + + EVT_UPDATE_UI( ID_RICHTEXT_TOP_MARGIN, wxRichTextMarginsPage::OnRichtextTopMarginUpdate ) + + EVT_UPDATE_UI( ID_RICHTEXT_TOP_MARGIN_UNITS, wxRichTextMarginsPage::OnRichtextTopMarginUpdate ) + + EVT_UPDATE_UI( ID_RICHTEXT_BOTTOM_MARGIN, wxRichTextMarginsPage::OnRichtextBottomMarginUpdate ) + + EVT_UPDATE_UI( ID_RICHTEXT_BOTTOM_MARGIN_UNITS, wxRichTextMarginsPage::OnRichtextBottomMarginUpdate ) + + EVT_UPDATE_UI( ID_RICHTEXT_LEFT_PADDING, wxRichTextMarginsPage::OnRichtextLeftPaddingUpdate ) + + EVT_UPDATE_UI( ID_RICHTEXT_LEFT_PADDING_UNITS, wxRichTextMarginsPage::OnRichtextLeftPaddingUpdate ) + + EVT_UPDATE_UI( ID_RICHTEXT_RIGHT_PADDING, wxRichTextMarginsPage::OnRichtextRightPaddingUpdate ) + + EVT_UPDATE_UI( ID_RICHTEXT_RIGHT_PADDING_UNITS, wxRichTextMarginsPage::OnRichtextRightPaddingUpdate ) + + EVT_UPDATE_UI( ID_RICHTEXT_TOP_PADDING, wxRichTextMarginsPage::OnRichtextTopPaddingUpdate ) + + EVT_UPDATE_UI( ID_RICHTEXT_TOP_PADDING_UNITS, wxRichTextMarginsPage::OnRichtextTopPaddingUpdate ) + + EVT_UPDATE_UI( ID_RICHTEXT_BOTTOM_PADDING, wxRichTextMarginsPage::OnRichtextBottomPaddingUpdate ) + + EVT_UPDATE_UI( ID_RICHTEXT_BOTTOM_PADDING_UNITS, wxRichTextMarginsPage::OnRichtextBottomPaddingUpdate ) + +////@end wxRichTextMarginsPage event table entries + +END_EVENT_TABLE() + +IMPLEMENT_HELP_PROVISION(wxRichTextMarginsPage) + +/*! + * wxRichTextMarginsPage constructors + */ + +wxRichTextMarginsPage::wxRichTextMarginsPage() +{ + Init(); +} + +wxRichTextMarginsPage::wxRichTextMarginsPage( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) +{ + Init(); + Create(parent, id, pos, size, style); +} + + +/*! + * wxRichTextMarginsPage creator + */ + +bool wxRichTextMarginsPage::Create( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) +{ +////@begin wxRichTextMarginsPage creation + wxRichTextDialogPage::Create( parent, id, pos, size, style ); + + CreateControls(); + if (GetSizer()) + { + GetSizer()->SetSizeHints(this); + } + Centre(); +////@end wxRichTextMarginsPage creation + return true; +} + + +/*! + * wxRichTextMarginsPage destructor + */ + +wxRichTextMarginsPage::~wxRichTextMarginsPage() +{ +////@begin wxRichTextMarginsPage destruction +////@end wxRichTextMarginsPage destruction +} + + +/*! + * Member initialisation + */ + +void wxRichTextMarginsPage::Init() +{ + m_ignoreUpdates = false; + +////@begin wxRichTextMarginsPage member initialisation + m_leftMarginCheckbox = NULL; + m_marginLeft = NULL; + m_unitsMarginLeft = NULL; + m_rightMarginCheckbox = NULL; + m_marginRight = NULL; + m_unitsMarginRight = NULL; + m_topMarginCheckbox = NULL; + m_marginTop = NULL; + m_unitsMarginTop = NULL; + m_bottomMarginCheckbox = NULL; + m_marginBottom = NULL; + m_unitsMarginBottom = NULL; + m_leftPaddingCheckbox = NULL; + m_paddingLeft = NULL; + m_unitsPaddingLeft = NULL; + m_rightPaddingCheckbox = NULL; + m_paddingRight = NULL; + m_unitsPaddingRight = NULL; + m_topPaddingCheckbox = NULL; + m_paddingTop = NULL; + m_unitsPaddingTop = NULL; + m_bottomPaddingCheckbox = NULL; + m_paddingBottom = NULL; + m_unitsPaddingBottom = NULL; +////@end wxRichTextMarginsPage member initialisation +} + + +/*! + * Control creation for wxRichTextMarginsPage + */ + +void wxRichTextMarginsPage::CreateControls() +{ +////@begin wxRichTextMarginsPage content construction + wxRichTextMarginsPage* itemRichTextDialogPage1 = this; + + wxBoxSizer* itemBoxSizer2 = new wxBoxSizer(wxVERTICAL); + itemRichTextDialogPage1->SetSizer(itemBoxSizer2); + + wxBoxSizer* itemBoxSizer3 = new wxBoxSizer(wxVERTICAL); + itemBoxSizer2->Add(itemBoxSizer3, 1, wxGROW|wxALL, 5); + + wxBoxSizer* itemBoxSizer4 = new wxBoxSizer(wxHORIZONTAL); + itemBoxSizer3->Add(itemBoxSizer4, 0, wxGROW, 5); + + wxStaticText* itemStaticText5 = new wxStaticText( itemRichTextDialogPage1, wxID_STATIC, _("Margins"), wxDefaultPosition, wxDefaultSize, 0 ); + itemStaticText5->SetFont(wxFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).GetPointSize(), wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).GetFamily(), wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).GetStyle(), wxBOLD, false, wxT(""))); + itemBoxSizer4->Add(itemStaticText5, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + wxStaticLine* itemStaticLine6 = new wxStaticLine( itemRichTextDialogPage1, wxID_STATIC, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); + itemBoxSizer4->Add(itemStaticLine6, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + wxBoxSizer* itemBoxSizer7 = new wxBoxSizer(wxHORIZONTAL); + itemBoxSizer3->Add(itemBoxSizer7, 0, wxGROW, 5); + + itemBoxSizer7->Add(5, 5, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + wxFlexGridSizer* itemFlexGridSizer9 = new wxFlexGridSizer(0, 4, 0, 0); + itemBoxSizer7->Add(itemFlexGridSizer9, 0, wxALIGN_CENTER_VERTICAL, 5); + + m_leftMarginCheckbox = new wxCheckBox( itemRichTextDialogPage1, ID_RICHTEXT_LEFT_MARGIN_CHECKBOX, _("&Left:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_leftMarginCheckbox->SetValue(false); + itemFlexGridSizer9->Add(m_leftMarginCheckbox, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP|wxBOTTOM, 5); + + wxBoxSizer* itemBoxSizer11 = new wxBoxSizer(wxHORIZONTAL); + itemFlexGridSizer9->Add(itemBoxSizer11, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 5); + + m_marginLeft = new wxTextCtrl( itemRichTextDialogPage1, ID_RICHTEXT_LEFT_MARGIN, wxEmptyString, wxDefaultPosition, wxSize(65, -1), 0 ); + m_marginLeft->SetHelpText(_("The left margin size.")); + if (wxRichTextMarginsPage::ShowToolTips()) + m_marginLeft->SetToolTip(_("The left margin size.")); + itemBoxSizer11->Add(m_marginLeft, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP|wxBOTTOM, 5); + + wxArrayString m_unitsMarginLeftStrings; + m_unitsMarginLeftStrings.Add(_("px")); + m_unitsMarginLeftStrings.Add(_("cm")); + m_unitsMarginLeft = new wxComboBox( itemRichTextDialogPage1, ID_RICHTEXT_LEFT_MARGIN_UNITS, _("px"), wxDefaultPosition, wxSize(60, -1), m_unitsMarginLeftStrings, wxCB_READONLY ); + m_unitsMarginLeft->SetStringSelection(_("px")); + m_unitsMarginLeft->SetHelpText(_("Units for the left margin.")); + if (wxRichTextMarginsPage::ShowToolTips()) + m_unitsMarginLeft->SetToolTip(_("Units for the left margin.")); + itemBoxSizer11->Add(m_unitsMarginLeft, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + itemBoxSizer11->Add(5, 5, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + m_rightMarginCheckbox = new wxCheckBox( itemRichTextDialogPage1, ID_RICHTEXT_RIGHT_MARGIN_CHECKBOX, _("&Right:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_rightMarginCheckbox->SetValue(false); + itemFlexGridSizer9->Add(m_rightMarginCheckbox, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP|wxBOTTOM, 5); + + wxBoxSizer* itemBoxSizer16 = new wxBoxSizer(wxHORIZONTAL); + itemFlexGridSizer9->Add(itemBoxSizer16, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 5); + + m_marginRight = new wxTextCtrl( itemRichTextDialogPage1, ID_RICHTEXT_RIGHT_MARGIN, wxEmptyString, wxDefaultPosition, wxSize(65, -1), 0 ); + m_marginRight->SetHelpText(_("The right margin size.")); + if (wxRichTextMarginsPage::ShowToolTips()) + m_marginRight->SetToolTip(_("The right margin size.")); + itemBoxSizer16->Add(m_marginRight, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP|wxBOTTOM, 5); + + wxArrayString m_unitsMarginRightStrings; + m_unitsMarginRightStrings.Add(_("px")); + m_unitsMarginRightStrings.Add(_("cm")); + m_unitsMarginRight = new wxComboBox( itemRichTextDialogPage1, ID_RICHTEXT_RIGHT_MARGIN_UNITS, _("px"), wxDefaultPosition, wxSize(60, -1), m_unitsMarginRightStrings, wxCB_READONLY ); + m_unitsMarginRight->SetStringSelection(_("px")); + m_unitsMarginRight->SetHelpText(_("Units for the right margin.")); + if (wxRichTextMarginsPage::ShowToolTips()) + m_unitsMarginRight->SetToolTip(_("Units for the right margin.")); + itemBoxSizer16->Add(m_unitsMarginRight, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + m_topMarginCheckbox = new wxCheckBox( itemRichTextDialogPage1, ID_RICHTEXT_TOP_MARGIN_CHECKBOX, _("&Top:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_topMarginCheckbox->SetValue(false); + itemFlexGridSizer9->Add(m_topMarginCheckbox, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP|wxBOTTOM, 5); + + wxBoxSizer* itemBoxSizer20 = new wxBoxSizer(wxHORIZONTAL); + itemFlexGridSizer9->Add(itemBoxSizer20, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 5); + + m_marginTop = new wxTextCtrl( itemRichTextDialogPage1, ID_RICHTEXT_TOP_MARGIN, wxEmptyString, wxDefaultPosition, wxSize(65, -1), 0 ); + m_marginTop->SetHelpText(_("The top margin size.")); + if (wxRichTextMarginsPage::ShowToolTips()) + m_marginTop->SetToolTip(_("The top margin size.")); + itemBoxSizer20->Add(m_marginTop, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP|wxBOTTOM, 5); + + wxArrayString m_unitsMarginTopStrings; + m_unitsMarginTopStrings.Add(_("px")); + m_unitsMarginTopStrings.Add(_("cm")); + m_unitsMarginTop = new wxComboBox( itemRichTextDialogPage1, ID_RICHTEXT_TOP_MARGIN_UNITS, _("px"), wxDefaultPosition, wxSize(60, -1), m_unitsMarginTopStrings, wxCB_READONLY ); + m_unitsMarginTop->SetStringSelection(_("px")); + m_unitsMarginTop->SetHelpText(_("Units for the top margin.")); + if (wxRichTextMarginsPage::ShowToolTips()) + m_unitsMarginTop->SetToolTip(_("Units for the top margin.")); + itemBoxSizer20->Add(m_unitsMarginTop, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + itemBoxSizer20->Add(5, 5, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + m_bottomMarginCheckbox = new wxCheckBox( itemRichTextDialogPage1, ID_RICHTEXT_BOTTOM_MARGIN_CHECKBOX, _("&Bottom:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_bottomMarginCheckbox->SetValue(false); + itemFlexGridSizer9->Add(m_bottomMarginCheckbox, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP|wxBOTTOM, 5); + + wxBoxSizer* itemBoxSizer25 = new wxBoxSizer(wxHORIZONTAL); + itemFlexGridSizer9->Add(itemBoxSizer25, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 5); + + m_marginBottom = new wxTextCtrl( itemRichTextDialogPage1, ID_RICHTEXT_BOTTOM_MARGIN, wxEmptyString, wxDefaultPosition, wxSize(65, -1), 0 ); + m_marginBottom->SetHelpText(_("The bottom margin size.")); + if (wxRichTextMarginsPage::ShowToolTips()) + m_marginBottom->SetToolTip(_("The bottom margin size.")); + itemBoxSizer25->Add(m_marginBottom, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP|wxBOTTOM, 5); + + wxArrayString m_unitsMarginBottomStrings; + m_unitsMarginBottomStrings.Add(_("px")); + m_unitsMarginBottomStrings.Add(_("cm")); + m_unitsMarginBottom = new wxComboBox( itemRichTextDialogPage1, ID_RICHTEXT_BOTTOM_MARGIN_UNITS, _("px"), wxDefaultPosition, wxSize(60, -1), m_unitsMarginBottomStrings, wxCB_READONLY ); + m_unitsMarginBottom->SetStringSelection(_("px")); + m_unitsMarginBottom->SetHelpText(_("Units for the bottom margin.")); + if (wxRichTextMarginsPage::ShowToolTips()) + m_unitsMarginBottom->SetToolTip(_("Units for the bottom margin.")); + itemBoxSizer25->Add(m_unitsMarginBottom, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + wxBoxSizer* itemBoxSizer28 = new wxBoxSizer(wxHORIZONTAL); + itemBoxSizer3->Add(itemBoxSizer28, 0, wxGROW, 5); + + wxStaticText* itemStaticText29 = new wxStaticText( itemRichTextDialogPage1, wxID_STATIC, _("Padding"), wxDefaultPosition, wxDefaultSize, 0 ); + itemStaticText29->SetFont(wxFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).GetPointSize(), wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).GetFamily(), wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).GetStyle(), wxBOLD, false, wxT(""))); + itemBoxSizer28->Add(itemStaticText29, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + wxStaticLine* itemStaticLine30 = new wxStaticLine( itemRichTextDialogPage1, wxID_STATIC, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); + itemBoxSizer28->Add(itemStaticLine30, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + wxBoxSizer* itemBoxSizer31 = new wxBoxSizer(wxHORIZONTAL); + itemBoxSizer3->Add(itemBoxSizer31, 0, wxGROW, 5); + + itemBoxSizer31->Add(5, 5, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + wxFlexGridSizer* itemFlexGridSizer33 = new wxFlexGridSizer(0, 4, 0, 0); + itemBoxSizer31->Add(itemFlexGridSizer33, 0, wxALIGN_CENTER_VERTICAL, 5); + + m_leftPaddingCheckbox = new wxCheckBox( itemRichTextDialogPage1, ID_RICHTEXT_LEFT_PADDING_CHECKBOX, _("&Left:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_leftPaddingCheckbox->SetValue(false); + itemFlexGridSizer33->Add(m_leftPaddingCheckbox, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP|wxBOTTOM, 5); + + wxBoxSizer* itemBoxSizer35 = new wxBoxSizer(wxHORIZONTAL); + itemFlexGridSizer33->Add(itemBoxSizer35, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 5); + + m_paddingLeft = new wxTextCtrl( itemRichTextDialogPage1, ID_RICHTEXT_LEFT_PADDING, wxEmptyString, wxDefaultPosition, wxSize(65, -1), 0 ); + m_paddingLeft->SetHelpText(_("The left padding size.")); + if (wxRichTextMarginsPage::ShowToolTips()) + m_paddingLeft->SetToolTip(_("The left padding size.")); + itemBoxSizer35->Add(m_paddingLeft, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP|wxBOTTOM, 5); + + wxArrayString m_unitsPaddingLeftStrings; + m_unitsPaddingLeftStrings.Add(_("px")); + m_unitsPaddingLeftStrings.Add(_("cm")); + m_unitsPaddingLeft = new wxComboBox( itemRichTextDialogPage1, ID_RICHTEXT_LEFT_PADDING_UNITS, _("px"), wxDefaultPosition, wxSize(60, -1), m_unitsPaddingLeftStrings, wxCB_READONLY ); + m_unitsPaddingLeft->SetStringSelection(_("px")); + m_unitsPaddingLeft->SetHelpText(_("Units for the left padding.")); + if (wxRichTextMarginsPage::ShowToolTips()) + m_unitsPaddingLeft->SetToolTip(_("Units for the left padding.")); + itemBoxSizer35->Add(m_unitsPaddingLeft, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + itemBoxSizer35->Add(5, 5, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + m_rightPaddingCheckbox = new wxCheckBox( itemRichTextDialogPage1, ID_RICHTEXT_RIGHT_PADDING_CHECKBOX, _("&Right:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_rightPaddingCheckbox->SetValue(false); + itemFlexGridSizer33->Add(m_rightPaddingCheckbox, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP|wxBOTTOM, 5); + + wxBoxSizer* itemBoxSizer40 = new wxBoxSizer(wxHORIZONTAL); + itemFlexGridSizer33->Add(itemBoxSizer40, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 5); + + m_paddingRight = new wxTextCtrl( itemRichTextDialogPage1, ID_RICHTEXT_RIGHT_PADDING, wxEmptyString, wxDefaultPosition, wxSize(65, -1), 0 ); + m_paddingRight->SetHelpText(_("The right padding size.")); + if (wxRichTextMarginsPage::ShowToolTips()) + m_paddingRight->SetToolTip(_("The right padding size.")); + itemBoxSizer40->Add(m_paddingRight, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP|wxBOTTOM, 5); + + wxArrayString m_unitsPaddingRightStrings; + m_unitsPaddingRightStrings.Add(_("px")); + m_unitsPaddingRightStrings.Add(_("cm")); + m_unitsPaddingRight = new wxComboBox( itemRichTextDialogPage1, ID_RICHTEXT_RIGHT_PADDING_UNITS, _("px"), wxDefaultPosition, wxSize(60, -1), m_unitsPaddingRightStrings, wxCB_READONLY ); + m_unitsPaddingRight->SetStringSelection(_("px")); + m_unitsPaddingRight->SetHelpText(_("Units for the right padding.")); + if (wxRichTextMarginsPage::ShowToolTips()) + m_unitsPaddingRight->SetToolTip(_("Units for the right padding.")); + itemBoxSizer40->Add(m_unitsPaddingRight, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + m_topPaddingCheckbox = new wxCheckBox( itemRichTextDialogPage1, ID_RICHTEXT_TOP_PADDING_CHECKBOX, _("&Top:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_topPaddingCheckbox->SetValue(false); + itemFlexGridSizer33->Add(m_topPaddingCheckbox, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP|wxBOTTOM, 5); + + wxBoxSizer* itemBoxSizer44 = new wxBoxSizer(wxHORIZONTAL); + itemFlexGridSizer33->Add(itemBoxSizer44, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 5); + + m_paddingTop = new wxTextCtrl( itemRichTextDialogPage1, ID_RICHTEXT_TOP_PADDING, wxEmptyString, wxDefaultPosition, wxSize(65, -1), 0 ); + m_paddingTop->SetHelpText(_("The top padding size.")); + if (wxRichTextMarginsPage::ShowToolTips()) + m_paddingTop->SetToolTip(_("The top padding size.")); + itemBoxSizer44->Add(m_paddingTop, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP|wxBOTTOM, 5); + + wxArrayString m_unitsPaddingTopStrings; + m_unitsPaddingTopStrings.Add(_("px")); + m_unitsPaddingTopStrings.Add(_("cm")); + m_unitsPaddingTop = new wxComboBox( itemRichTextDialogPage1, ID_RICHTEXT_TOP_PADDING_UNITS, _("px"), wxDefaultPosition, wxSize(60, -1), m_unitsPaddingTopStrings, wxCB_READONLY ); + m_unitsPaddingTop->SetStringSelection(_("px")); + m_unitsPaddingTop->SetHelpText(_("Units for the top padding.")); + if (wxRichTextMarginsPage::ShowToolTips()) + m_unitsPaddingTop->SetToolTip(_("Units for the top padding.")); + itemBoxSizer44->Add(m_unitsPaddingTop, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + itemBoxSizer44->Add(5, 5, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + m_bottomPaddingCheckbox = new wxCheckBox( itemRichTextDialogPage1, ID_RICHTEXT_BOTTOM_PADDING_CHECKBOX, _("&Bottom:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_bottomPaddingCheckbox->SetValue(false); + itemFlexGridSizer33->Add(m_bottomPaddingCheckbox, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP|wxBOTTOM, 5); + + wxBoxSizer* itemBoxSizer49 = new wxBoxSizer(wxHORIZONTAL); + itemFlexGridSizer33->Add(itemBoxSizer49, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 5); + + m_paddingBottom = new wxTextCtrl( itemRichTextDialogPage1, ID_RICHTEXT_BOTTOM_PADDING, wxEmptyString, wxDefaultPosition, wxSize(65, -1), 0 ); + m_paddingBottom->SetHelpText(_("The bottom padding size.")); + if (wxRichTextMarginsPage::ShowToolTips()) + m_paddingBottom->SetToolTip(_("The bottom padding size.")); + itemBoxSizer49->Add(m_paddingBottom, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP|wxBOTTOM, 5); + + wxArrayString m_unitsPaddingBottomStrings; + m_unitsPaddingBottomStrings.Add(_("px")); + m_unitsPaddingBottomStrings.Add(_("cm")); + m_unitsPaddingBottom = new wxComboBox( itemRichTextDialogPage1, ID_RICHTEXT_BOTTOM_PADDING_UNITS, _("px"), wxDefaultPosition, wxSize(60, -1), m_unitsPaddingBottomStrings, wxCB_READONLY ); + m_unitsPaddingBottom->SetStringSelection(_("px")); + m_unitsPaddingBottom->SetHelpText(_("Units for the bottom padding.")); + if (wxRichTextMarginsPage::ShowToolTips()) + m_unitsPaddingBottom->SetToolTip(_("Units for the bottom padding.")); + itemBoxSizer49->Add(m_unitsPaddingBottom, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + +////@end wxRichTextMarginsPage content construction +} + +wxRichTextAttr* wxRichTextMarginsPage::GetAttributes() +{ + return wxRichTextFormattingDialog::GetDialogAttributes(this); +} + +/*! + * Should we show tooltips? + */ + +bool wxRichTextMarginsPage::ShowToolTips() +{ + return true; +} + +bool wxRichTextMarginsPage::TransferDataToWindow() +{ + // Margins + wxRichTextFormattingDialog::SetDimensionValue(GetAttributes()->GetTextBoxAttr().GetMargins().GetLeft(), m_marginLeft, m_unitsMarginLeft, m_leftMarginCheckbox); + wxRichTextFormattingDialog::SetDimensionValue(GetAttributes()->GetTextBoxAttr().GetMargins().GetTop(), m_marginTop, m_unitsMarginTop, m_topMarginCheckbox); + wxRichTextFormattingDialog::SetDimensionValue(GetAttributes()->GetTextBoxAttr().GetMargins().GetRight(), m_marginRight, m_unitsMarginRight, m_rightMarginCheckbox); + wxRichTextFormattingDialog::SetDimensionValue(GetAttributes()->GetTextBoxAttr().GetMargins().GetBottom(), m_marginBottom, m_unitsMarginBottom, m_bottomMarginCheckbox); + + // Padding + wxRichTextFormattingDialog::SetDimensionValue(GetAttributes()->GetTextBoxAttr().GetPadding().GetLeft(), m_paddingLeft, m_unitsPaddingLeft, m_leftPaddingCheckbox); + wxRichTextFormattingDialog::SetDimensionValue(GetAttributes()->GetTextBoxAttr().GetPadding().GetTop(), m_paddingTop, m_unitsPaddingTop, m_topPaddingCheckbox); + wxRichTextFormattingDialog::SetDimensionValue(GetAttributes()->GetTextBoxAttr().GetPadding().GetRight(), m_paddingRight, m_unitsPaddingRight, m_rightPaddingCheckbox); + wxRichTextFormattingDialog::SetDimensionValue(GetAttributes()->GetTextBoxAttr().GetPadding().GetBottom(), m_paddingBottom, m_unitsPaddingBottom, m_bottomPaddingCheckbox); + + return true; +} + +bool wxRichTextMarginsPage::TransferDataFromWindow() +{ + // Margins + wxRichTextFormattingDialog::GetDimensionValue(GetAttributes()->GetTextBoxAttr().GetMargins().GetLeft(), m_marginLeft, m_unitsMarginLeft, m_leftMarginCheckbox); + wxRichTextFormattingDialog::GetDimensionValue(GetAttributes()->GetTextBoxAttr().GetMargins().GetTop(), m_marginTop, m_unitsMarginTop, m_topMarginCheckbox); + wxRichTextFormattingDialog::GetDimensionValue(GetAttributes()->GetTextBoxAttr().GetMargins().GetRight(), m_marginRight, m_unitsMarginRight, m_rightMarginCheckbox); + wxRichTextFormattingDialog::GetDimensionValue(GetAttributes()->GetTextBoxAttr().GetMargins().GetBottom(), m_marginBottom, m_unitsMarginBottom, m_bottomMarginCheckbox); + + // Padding + wxRichTextFormattingDialog::GetDimensionValue(GetAttributes()->GetTextBoxAttr().GetPadding().GetLeft(), m_paddingLeft, m_unitsPaddingLeft, m_leftPaddingCheckbox); + wxRichTextFormattingDialog::GetDimensionValue(GetAttributes()->GetTextBoxAttr().GetPadding().GetTop(), m_paddingTop, m_unitsPaddingTop, m_topPaddingCheckbox); + wxRichTextFormattingDialog::GetDimensionValue(GetAttributes()->GetTextBoxAttr().GetPadding().GetRight(), m_paddingRight, m_unitsPaddingRight, m_rightPaddingCheckbox); + wxRichTextFormattingDialog::GetDimensionValue(GetAttributes()->GetTextBoxAttr().GetPadding().GetBottom(), m_paddingBottom, m_unitsPaddingBottom, m_bottomPaddingCheckbox); + + return true; +} + +/*! + * Get bitmap resources + */ + +wxBitmap wxRichTextMarginsPage::GetBitmapResource( const wxString& name ) +{ + // Bitmap retrieval +////@begin wxRichTextMarginsPage bitmap retrieval + wxUnusedVar(name); + return wxNullBitmap; +////@end wxRichTextMarginsPage bitmap retrieval +} + +/*! + * Get icon resources + */ + +wxIcon wxRichTextMarginsPage::GetIconResource( const wxString& name ) +{ + // Icon retrieval +////@begin wxRichTextMarginsPage icon retrieval + wxUnusedVar(name); + return wxNullIcon; +////@end wxRichTextMarginsPage icon retrieval +} + + +/*! + * wxEVT_UPDATE_UI event handler for ID_RICHTEXT_LEFT_MARGIN + */ + +void wxRichTextMarginsPage::OnRichtextLeftMarginUpdate( wxUpdateUIEvent& event ) +{ + event.Enable(m_leftMarginCheckbox->GetValue()); +} + + +/*! + * wxEVT_UPDATE_UI event handler for ID_RICHTEXT_RIGHT_MARGIN + */ + +void wxRichTextMarginsPage::OnRichtextRightMarginUpdate( wxUpdateUIEvent& event ) +{ + event.Enable(m_rightMarginCheckbox->GetValue()); +} + +/*! + * wxEVT_UPDATE_UI event handler for ID_RICHTEXT_TOP_MARGIN + */ + +void wxRichTextMarginsPage::OnRichtextTopMarginUpdate( wxUpdateUIEvent& event ) +{ + event.Enable(m_topMarginCheckbox->GetValue()); +} + +/*! + * wxEVT_UPDATE_UI event handler for ID_RICHTEXT_BOTTOM_MARGIN + */ + +void wxRichTextMarginsPage::OnRichtextBottomMarginUpdate( wxUpdateUIEvent& event ) +{ + event.Enable(m_bottomMarginCheckbox->GetValue()); +} + + +/*! + * wxEVT_UPDATE_UI event handler for ID_RICHTEXT_LEFT_PADDING + */ + +void wxRichTextMarginsPage::OnRichtextLeftPaddingUpdate( wxUpdateUIEvent& event ) +{ + event.Enable(m_leftPaddingCheckbox->GetValue()); +} + + +/*! + * wxEVT_UPDATE_UI event handler for ID_RICHTEXT_RIGHT_PADDING + */ + +void wxRichTextMarginsPage::OnRichtextRightPaddingUpdate( wxUpdateUIEvent& event ) +{ + event.Enable(m_rightPaddingCheckbox->GetValue()); +} + + +/*! + * wxEVT_UPDATE_UI event handler for ID_RICHTEXT_TOP_PADDING + */ + +void wxRichTextMarginsPage::OnRichtextTopPaddingUpdate( wxUpdateUIEvent& event ) +{ + event.Enable(m_topPaddingCheckbox->GetValue()); +} + +/*! + * wxEVT_UPDATE_UI event handler for ID_RICHTEXT_BOTTOM_PADDING + */ + +void wxRichTextMarginsPage::OnRichtextBottomPaddingUpdate( wxUpdateUIEvent& event ) +{ + event.Enable(m_bottomPaddingCheckbox->GetValue()); +} diff --git a/src/richtext/richtextprint.cpp b/src/richtext/richtextprint.cpp index 2efffa46a5..9855d57966 100644 --- a/src/richtext/richtextprint.cpp +++ b/src/richtext/richtextprint.cpp @@ -54,6 +54,7 @@ void wxRichTextPrintout::OnPreparePrinting() m_pageBreaksStart.Clear(); m_pageBreaksEnd.Clear(); + m_pageYOffsets.Clear(); int lastStartPos = 0; @@ -80,57 +81,69 @@ void wxRichTextPrintout::OnPreparePrinting() // child is a paragraph wxRichTextParagraph* child = wxDynamicCast(node->GetData(), wxRichTextParagraph); wxASSERT (child != NULL); - - wxRichTextLineList::compatibility_iterator node2 = child->GetLines().GetFirst(); - while (node2) + if (child) { - wxRichTextLine* line = node2->GetData(); - - // Set the line to the page-adjusted position - line->SetPosition(wxPoint(line->GetPosition().x, line->GetPosition().y - yOffset)); - - int lineY = child->GetPosition().y + line->GetPosition().y; - - // Break the page if either we're going off the bottom, or this paragraph specifies - // an explicit page break - - if (((lineY + line->GetSize().y) > rect.GetBottom()) || - ((node2 == child->GetLines().GetFirst()) && child->GetAttributes().HasPageBreak())) + wxRichTextLineList::compatibility_iterator node2 = child->GetLines().GetFirst(); + while (node2) { - // New page starting at this line - int newY = rect.y; + wxRichTextLine* line = node2->GetData(); - // We increase the offset by the difference between new and old positions + int lineY = child->GetPosition().y + line->GetPosition().y - yOffset; + bool hasHardPageBreak = ((node2 == child->GetLines().GetFirst()) && child->GetAttributes().HasPageBreak()); - int increaseOffsetBy = lineY - newY; - yOffset += increaseOffsetBy; + // Break the page if either we're going off the bottom, or this paragraph specifies + // an explicit page break - line->SetPosition(wxPoint(line->GetPosition().x, newY - child->GetPosition().y)); + if (((lineY + line->GetSize().y) > rect.GetBottom()) || hasHardPageBreak) + { + // New page starting at this line + int newY = rect.y; - if (!lastLine) + // We increase the offset by the difference between new and old positions + + int increaseOffsetBy = lineY - newY; + yOffset += increaseOffsetBy; + + if (!lastLine) + lastLine = line; + + m_pageBreaksStart.Add(lastStartPos); + m_pageBreaksEnd.Add(lastLine->GetAbsoluteRange().GetEnd()); + m_pageYOffsets.Add(yOffset); + + lastStartPos = line->GetAbsoluteRange().GetStart(); lastLine = line; - m_pageBreaksStart.Add(lastStartPos); - m_pageBreaksEnd.Add(lastLine->GetAbsoluteRange().GetEnd()); + m_numPages ++; + + // Now create page breaks for the rest of the line, if it's larger than the page height + int contentLeft = line->GetSize().y - rect.GetHeight(); + while (contentLeft >= 0) + { + yOffset += rect.GetHeight(); + contentLeft -= rect.GetHeight(); + + m_pageBreaksStart.Add(lastStartPos); + m_pageBreaksEnd.Add(lastLine->GetAbsoluteRange().GetEnd()); + m_pageYOffsets.Add(yOffset); + } + } - lastStartPos = line->GetAbsoluteRange().GetStart(); + lastLine = line; - m_numPages ++; + node2 = node2->GetNext(); } - - lastLine = line; - - node2 = node2->GetNext(); } node = node->GetNext(); } // Closing page break - if (m_pageBreaksStart.GetCount() == 0 || (m_pageBreaksEnd[m_pageBreaksEnd.GetCount()-1] < (GetRichTextBuffer()->GetRange().GetEnd()-1))) + if (m_pageBreaksStart.GetCount() == 0 || (m_pageBreaksEnd[m_pageBreaksEnd.GetCount()-1] < (GetRichTextBuffer()->GetOwnRange().GetEnd()-1))) { m_pageBreaksStart.Add(lastStartPos); - m_pageBreaksEnd.Add(GetRichTextBuffer()->GetRange().GetEnd()); + m_pageBreaksEnd.Add(GetRichTextBuffer()->GetOwnRange().GetEnd()); + m_pageYOffsets.Add(yOffset); } } } @@ -273,8 +286,26 @@ void wxRichTextPrintout::RenderPage(wxDC *dc, int page) } wxRichTextRange rangeToDraw(m_pageBreaksStart[page-1], m_pageBreaksEnd[page-1]); + + wxPoint oldOrigin = dc->GetLogicalOrigin(); + double scaleX, scaleY; + dc->GetUserScale(& scaleX, & scaleY); - GetRichTextBuffer()->Draw(*dc, rangeToDraw, wxRichTextRange(-1,-1), textRect, 0 /* descent */, wxRICHTEXT_DRAW_IGNORE_CACHE /* flags */); + int yOffset = 0; + if (page > 1) + yOffset = m_pageYOffsets[page-2]; + + if (yOffset != oldOrigin.y) + dc->SetLogicalOrigin(oldOrigin.x, oldOrigin.y + yOffset); + + dc->SetClippingRegion(wxRect(textRect.x, textRect.y + yOffset, textRect.width, textRect.height)); + + GetRichTextBuffer()->Draw(*dc, rangeToDraw, wxRichTextSelection(), textRect, 0 /* descent */, wxRICHTEXT_DRAW_IGNORE_CACHE|wxRICHTEXT_DRAW_PRINT /* flags */); + + dc->DestroyClippingRegion(); + + if (yOffset != oldOrigin.y) + dc->SetLogicalOrigin(oldOrigin.x, oldOrigin.y); } void wxRichTextPrintout::SetMargins(int top, int bottom, int left, int right) @@ -312,7 +343,7 @@ void wxRichTextPrintout::CalculateScaling(wxDC* dc, wxRect& textRect, wxRect& he // The dimensions used for indentation etc. have to be unscaled // during printing to be correct when scaling is applied. - if (!IsPreview()) + // if (!IsPreview()) m_richTextBuffer->SetScale(scale); // Calculate margins diff --git a/src/richtext/richtextsizepage.cpp b/src/richtext/richtextsizepage.cpp new file mode 100644 index 0000000000..33a4b051b4 --- /dev/null +++ b/src/richtext/richtextsizepage.cpp @@ -0,0 +1,639 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: richtextsizepage.cpp +// Purpose: +// Author: Julian Smart +// Modified by: +// Created: 20/10/2010 10:23:24 +// RCS-ID: +// Copyright: (c) Julian Smart +// Licence: +///////////////////////////////////////////////////////////////////////////// + +// For compilers that support precompilation, includes "wx/wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +////@begin includes +////@end includes + +#include "wx/richtext/richtextsizepage.h" + +////@begin XPM images +////@end XPM images + + +/*! + * wxRichTextSizePage type definition + */ + +IMPLEMENT_DYNAMIC_CLASS( wxRichTextSizePage, wxRichTextDialogPage ) + + +/*! + * wxRichTextSizePage event table definition + */ + +BEGIN_EVENT_TABLE( wxRichTextSizePage, wxRichTextDialogPage ) + +////@begin wxRichTextSizePage event table entries + EVT_UPDATE_UI( ID_RICHTEXT_WIDTH, wxRichTextSizePage::OnRichtextWidthUpdate ) + + EVT_UPDATE_UI( ID_RICHTEXT_UNITS_W, wxRichTextSizePage::OnRichtextWidthUpdate ) + + EVT_UPDATE_UI( ID_RICHTEXT_HEIGHT, wxRichTextSizePage::OnRichtextHeightUpdate ) + + EVT_UPDATE_UI( ID_RICHTEXT_UNITS_H, wxRichTextSizePage::OnRichtextHeightUpdate ) + + EVT_UPDATE_UI( ID_RICHTEXT_VERTICAL_ALIGNMENT_COMBOBOX, wxRichTextSizePage::OnRichtextVerticalAlignmentComboboxUpdate ) + + EVT_UPDATE_UI( ID_RICHTEXT_OFFSET, wxRichTextSizePage::OnRichtextOffsetUpdate ) + + EVT_UPDATE_UI( ID_RICHTEXT_OFFSET_UNITS, wxRichTextSizePage::OnRichtextOffsetUpdate ) + + EVT_BUTTON( ID_RICHTEXT_PARA_UP, wxRichTextSizePage::OnRichtextParaUpClick ) + + EVT_BUTTON( ID_RICHTEXT_PARA_DOWN, wxRichTextSizePage::OnRichtextParaDownClick ) + +////@end wxRichTextSizePage event table entries + +END_EVENT_TABLE() + +IMPLEMENT_HELP_PROVISION(wxRichTextSizePage) + +/*! + * wxRichTextSizePage constructors + */ + +wxRichTextSizePage::wxRichTextSizePage() +{ + Init(); +} + +wxRichTextSizePage::wxRichTextSizePage( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) +{ + Init(); + Create(parent, id, pos, size, style); +} + + +/*! + * wxRichTextSizePage creator + */ + +bool wxRichTextSizePage::Create( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) +{ +////@begin wxRichTextSizePage creation + wxRichTextDialogPage::Create( parent, id, pos, size, style ); + + CreateControls(); + if (GetSizer()) + { + GetSizer()->SetSizeHints(this); + } + Centre(); +////@end wxRichTextSizePage creation + return true; +} + + +/*! + * wxRichTextSizePage destructor + */ + +wxRichTextSizePage::~wxRichTextSizePage() +{ +////@begin wxRichTextSizePage destruction +////@end wxRichTextSizePage destruction +} + + +/*! + * Member initialisation + */ + +void wxRichTextSizePage::Init() +{ +////@begin wxRichTextSizePage member initialisation + m_parentSizer = NULL; + m_floatingControls = NULL; + m_float = NULL; + m_widthCheckbox = NULL; + m_width = NULL; + m_unitsW = NULL; + m_heightCheckbox = NULL; + m_height = NULL; + m_unitsH = NULL; + m_alignmentControls = NULL; + m_verticalAlignmentCheckbox = NULL; + m_verticalAlignmentComboBox = NULL; + m_positionControls = NULL; + m_moveObjectParentSizer = NULL; + m_offsetYCheckbox = NULL; + m_offset = NULL; + m_unitsOffset = NULL; + m_moveObjectSizer = NULL; +////@end wxRichTextSizePage member initialisation +} + + +/*! + * Control creation for wxRichTextSizePage + */ + +void wxRichTextSizePage::CreateControls() +{ +////@begin wxRichTextSizePage content construction + wxRichTextSizePage* itemRichTextDialogPage1 = this; + + wxBoxSizer* itemBoxSizer2 = new wxBoxSizer(wxVERTICAL); + itemRichTextDialogPage1->SetSizer(itemBoxSizer2); + + m_parentSizer = new wxBoxSizer(wxVERTICAL); + itemBoxSizer2->Add(m_parentSizer, 0, wxGROW|wxALL, 5); + + m_floatingControls = new wxBoxSizer(wxVERTICAL); + m_parentSizer->Add(m_floatingControls, 0, wxGROW, 5); + + wxBoxSizer* itemBoxSizer5 = new wxBoxSizer(wxHORIZONTAL); + m_floatingControls->Add(itemBoxSizer5, 0, wxGROW, 5); + + wxStaticText* itemStaticText6 = new wxStaticText( itemRichTextDialogPage1, wxID_STATIC, _("Floating"), wxDefaultPosition, wxDefaultSize, 0 ); + itemStaticText6->SetFont(wxFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).GetPointSize(), wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).GetFamily(), wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).GetStyle(), wxBOLD, false, wxT(""))); + itemBoxSizer5->Add(itemStaticText6, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + wxStaticLine* itemStaticLine7 = new wxStaticLine( itemRichTextDialogPage1, wxID_STATIC, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); + itemBoxSizer5->Add(itemStaticLine7, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + wxBoxSizer* itemBoxSizer8 = new wxBoxSizer(wxHORIZONTAL); + m_floatingControls->Add(itemBoxSizer8, 0, wxGROW, 5); + + itemBoxSizer8->Add(5, 5, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + wxFlexGridSizer* itemFlexGridSizer10 = new wxFlexGridSizer(0, 2, 0, 0); + itemBoxSizer8->Add(itemFlexGridSizer10, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5); + + wxStaticText* itemStaticText11 = new wxStaticText( itemRichTextDialogPage1, wxID_STATIC, _("&Floating mode:"), wxDefaultPosition, wxDefaultSize, 0 ); + itemFlexGridSizer10->Add(itemStaticText11, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL, 5); + + wxArrayString m_floatStrings; + m_floatStrings.Add(_("None")); + m_floatStrings.Add(_("Left")); + m_floatStrings.Add(_("Right")); + m_float = new wxComboBox( itemRichTextDialogPage1, ID_RICHTEXT_FLOATING_MODE, _("None"), wxDefaultPosition, wxSize(80, -1), m_floatStrings, wxCB_READONLY ); + m_float->SetStringSelection(_("None")); + m_float->SetHelpText(_("How the object will float relative to the text.")); + if (wxRichTextSizePage::ShowToolTips()) + m_float->SetToolTip(_("How the object will float relative to the text.")); + itemFlexGridSizer10->Add(m_float, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxALL, 5); + + wxBoxSizer* itemBoxSizer13 = new wxBoxSizer(wxHORIZONTAL); + m_parentSizer->Add(itemBoxSizer13, 0, wxGROW, 5); + + wxStaticText* itemStaticText14 = new wxStaticText( itemRichTextDialogPage1, wxID_STATIC, _("Size"), wxDefaultPosition, wxDefaultSize, 0 ); + itemStaticText14->SetFont(wxFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).GetPointSize(), wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).GetFamily(), wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).GetStyle(), wxBOLD, false, wxT(""))); + itemBoxSizer13->Add(itemStaticText14, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + wxStaticLine* itemStaticLine15 = new wxStaticLine( itemRichTextDialogPage1, wxID_STATIC, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); + itemBoxSizer13->Add(itemStaticLine15, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + wxBoxSizer* itemBoxSizer16 = new wxBoxSizer(wxHORIZONTAL); + m_parentSizer->Add(itemBoxSizer16, 0, wxGROW, 5); + + itemBoxSizer16->Add(5, 5, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + wxFlexGridSizer* itemFlexGridSizer18 = new wxFlexGridSizer(0, 2, 0, 0); + itemBoxSizer16->Add(itemFlexGridSizer18, 0, wxALIGN_CENTER_VERTICAL, 5); + + m_widthCheckbox = new wxCheckBox( itemRichTextDialogPage1, ID_RICHTEXT_WIDTH_CHECKBOX, _("&Width:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_widthCheckbox->SetValue(false); + m_widthCheckbox->SetHelpText(_("Enable the width value.")); + if (wxRichTextSizePage::ShowToolTips()) + m_widthCheckbox->SetToolTip(_("Enable the width value.")); + itemFlexGridSizer18->Add(m_widthCheckbox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP|wxBOTTOM, 5); + + wxBoxSizer* itemBoxSizer20 = new wxBoxSizer(wxHORIZONTAL); + itemFlexGridSizer18->Add(itemBoxSizer20, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 5); + + m_width = new wxTextCtrl( itemRichTextDialogPage1, ID_RICHTEXT_WIDTH, wxEmptyString, wxDefaultPosition, wxSize(65, -1), 0 ); + m_width->SetHelpText(_("The object width.")); + if (wxRichTextSizePage::ShowToolTips()) + m_width->SetToolTip(_("The object width.")); + itemBoxSizer20->Add(m_width, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP|wxBOTTOM, 5); + + wxArrayString m_unitsWStrings; + m_unitsWStrings.Add(_("px")); + m_unitsWStrings.Add(_("cm")); + m_unitsW = new wxComboBox( itemRichTextDialogPage1, ID_RICHTEXT_UNITS_W, _("px"), wxDefaultPosition, wxSize(60, -1), m_unitsWStrings, wxCB_READONLY ); + m_unitsW->SetStringSelection(_("px")); + m_unitsW->SetHelpText(_("Units for the object width.")); + if (wxRichTextSizePage::ShowToolTips()) + m_unitsW->SetToolTip(_("Units for the object width.")); + itemBoxSizer20->Add(m_unitsW, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + m_heightCheckbox = new wxCheckBox( itemRichTextDialogPage1, ID_RICHTEXT_HEIGHT_CHECKBOX, _("&Height:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_heightCheckbox->SetValue(false); + m_heightCheckbox->SetHelpText(_("Enable the height value.")); + if (wxRichTextSizePage::ShowToolTips()) + m_heightCheckbox->SetToolTip(_("Enable the height value.")); + itemFlexGridSizer18->Add(m_heightCheckbox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP|wxBOTTOM, 5); + + wxBoxSizer* itemBoxSizer24 = new wxBoxSizer(wxHORIZONTAL); + itemFlexGridSizer18->Add(itemBoxSizer24, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 5); + + m_height = new wxTextCtrl( itemRichTextDialogPage1, ID_RICHTEXT_HEIGHT, wxEmptyString, wxDefaultPosition, wxSize(65, -1), 0 ); + m_height->SetHelpText(_("The object height.")); + if (wxRichTextSizePage::ShowToolTips()) + m_height->SetToolTip(_("The object height.")); + itemBoxSizer24->Add(m_height, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP|wxBOTTOM, 5); + + wxArrayString m_unitsHStrings; + m_unitsHStrings.Add(_("px")); + m_unitsHStrings.Add(_("cm")); + m_unitsH = new wxComboBox( itemRichTextDialogPage1, ID_RICHTEXT_UNITS_H, _("px"), wxDefaultPosition, wxSize(60, -1), m_unitsHStrings, wxCB_READONLY ); + m_unitsH->SetStringSelection(_("px")); + m_unitsH->SetHelpText(_("Units for the object height.")); + if (wxRichTextSizePage::ShowToolTips()) + m_unitsH->SetToolTip(_("Units for the object height.")); + itemBoxSizer24->Add(m_unitsH, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + m_alignmentControls = new wxBoxSizer(wxVERTICAL); + m_parentSizer->Add(m_alignmentControls, 0, wxGROW, 5); + + wxBoxSizer* itemBoxSizer28 = new wxBoxSizer(wxHORIZONTAL); + m_alignmentControls->Add(itemBoxSizer28, 0, wxGROW, 5); + + wxStaticText* itemStaticText29 = new wxStaticText( itemRichTextDialogPage1, wxID_STATIC, _("Alignment"), wxDefaultPosition, wxDefaultSize, 0 ); + itemStaticText29->SetFont(wxFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).GetPointSize(), wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).GetFamily(), wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).GetStyle(), wxBOLD, false, wxT(""))); + itemBoxSizer28->Add(itemStaticText29, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + wxStaticLine* itemStaticLine30 = new wxStaticLine( itemRichTextDialogPage1, wxID_STATIC, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); + itemBoxSizer28->Add(itemStaticLine30, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + wxBoxSizer* itemBoxSizer31 = new wxBoxSizer(wxHORIZONTAL); + m_alignmentControls->Add(itemBoxSizer31, 0, wxGROW, 5); + + itemBoxSizer31->Add(5, 5, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + m_verticalAlignmentCheckbox = new wxCheckBox( itemRichTextDialogPage1, ID_RICHTEXT_VERTICAL_ALIGNMENT_CHECKBOX, _("&Vertical alignment:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_verticalAlignmentCheckbox->SetValue(false); + m_verticalAlignmentCheckbox->SetHelpText(_("Enable vertical alignment.")); + if (wxRichTextSizePage::ShowToolTips()) + m_verticalAlignmentCheckbox->SetToolTip(_("Enable vertical alignment.")); + itemBoxSizer31->Add(m_verticalAlignmentCheckbox, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + wxArrayString m_verticalAlignmentComboBoxStrings; + m_verticalAlignmentComboBoxStrings.Add(_("Top")); + m_verticalAlignmentComboBoxStrings.Add(_("Centred")); + m_verticalAlignmentComboBoxStrings.Add(_("Bottom")); + m_verticalAlignmentComboBox = new wxComboBox( itemRichTextDialogPage1, ID_RICHTEXT_VERTICAL_ALIGNMENT_COMBOBOX, _("Top"), wxDefaultPosition, wxDefaultSize, m_verticalAlignmentComboBoxStrings, wxCB_READONLY ); + m_verticalAlignmentComboBox->SetStringSelection(_("Top")); + m_verticalAlignmentComboBox->SetHelpText(_("Vertical alignment.")); + if (wxRichTextSizePage::ShowToolTips()) + m_verticalAlignmentComboBox->SetToolTip(_("Vertical alignment.")); + itemBoxSizer31->Add(m_verticalAlignmentComboBox, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + m_positionControls = new wxBoxSizer(wxVERTICAL); + m_parentSizer->Add(m_positionControls, 0, wxGROW, 5); + + wxBoxSizer* itemBoxSizer36 = new wxBoxSizer(wxHORIZONTAL); + m_positionControls->Add(itemBoxSizer36, 0, wxGROW, 5); + + wxStaticText* itemStaticText37 = new wxStaticText( itemRichTextDialogPage1, wxID_STATIC, _("Position"), wxDefaultPosition, wxDefaultSize, 0 ); + itemStaticText37->SetFont(wxFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).GetPointSize(), wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).GetFamily(), wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).GetStyle(), wxBOLD, false, wxT(""))); + itemBoxSizer36->Add(itemStaticText37, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + wxStaticLine* itemStaticLine38 = new wxStaticLine( itemRichTextDialogPage1, wxID_STATIC, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); + itemBoxSizer36->Add(itemStaticLine38, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + wxBoxSizer* itemBoxSizer39 = new wxBoxSizer(wxHORIZONTAL); + m_positionControls->Add(itemBoxSizer39, 0, wxGROW, 5); + + itemBoxSizer39->Add(5, 5, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + m_moveObjectParentSizer = new wxBoxSizer(wxVERTICAL); + itemBoxSizer39->Add(m_moveObjectParentSizer, 0, wxALIGN_TOP, 5); + + wxBoxSizer* itemBoxSizer42 = new wxBoxSizer(wxHORIZONTAL); + m_moveObjectParentSizer->Add(itemBoxSizer42, 0, wxGROW, 5); + + m_offsetYCheckbox = new wxCheckBox( itemRichTextDialogPage1, ID_RICHTEXT_OFFSET_CHECKBOX, _("Vertical &Offset:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_offsetYCheckbox->SetValue(false); + m_offsetYCheckbox->SetHelpText(_("Enable vertical offset.")); + if (wxRichTextSizePage::ShowToolTips()) + m_offsetYCheckbox->SetToolTip(_("Enable vertical offset.")); + itemBoxSizer42->Add(m_offsetYCheckbox, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP|wxBOTTOM, 5); + + m_offset = new wxTextCtrl( itemRichTextDialogPage1, ID_RICHTEXT_OFFSET, wxEmptyString, wxDefaultPosition, wxSize(65, -1), 0 ); + m_offset->SetMaxLength(10); + m_offset->SetHelpText(_("The vertical offset relative to the paragraph.")); + if (wxRichTextSizePage::ShowToolTips()) + m_offset->SetToolTip(_("The vertical offset relative to the paragraph.")); + itemBoxSizer42->Add(m_offset, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP|wxBOTTOM, 5); + + wxArrayString m_unitsOffsetStrings; + m_unitsOffsetStrings.Add(_("px")); + m_unitsOffsetStrings.Add(_("cm")); + m_unitsOffset = new wxComboBox( itemRichTextDialogPage1, ID_RICHTEXT_OFFSET_UNITS, _("px"), wxDefaultPosition, wxSize(60, -1), m_unitsOffsetStrings, wxCB_READONLY ); + m_unitsOffset->SetStringSelection(_("px")); + m_unitsOffset->SetHelpText(_("Units for the object offset.")); + if (wxRichTextSizePage::ShowToolTips()) + m_unitsOffset->SetToolTip(_("Units for the object offset.")); + itemBoxSizer42->Add(m_unitsOffset, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + m_moveObjectSizer = new wxBoxSizer(wxHORIZONTAL); + m_moveObjectParentSizer->Add(m_moveObjectSizer, 0, wxGROW, 5); + + wxStaticText* itemStaticText47 = new wxStaticText( itemRichTextDialogPage1, wxID_STATIC, _("&Move the object to:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_moveObjectSizer->Add(itemStaticText47, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + wxButton* itemButton48 = new wxButton( itemRichTextDialogPage1, ID_RICHTEXT_PARA_UP, _("&Previous Paragraph"), wxDefaultPosition, wxDefaultSize, 0 ); + itemButton48->SetHelpText(_("Moves the object to the previous paragraph.")); + if (wxRichTextSizePage::ShowToolTips()) + itemButton48->SetToolTip(_("Moves the object to the previous paragraph.")); + m_moveObjectSizer->Add(itemButton48, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + wxButton* itemButton49 = new wxButton( itemRichTextDialogPage1, ID_RICHTEXT_PARA_DOWN, _("&Next Paragraph"), wxDefaultPosition, wxDefaultSize, 0 ); + itemButton49->SetHelpText(_("Moves the object to the next paragraph.")); + if (wxRichTextSizePage::ShowToolTips()) + itemButton49->SetToolTip(_("Moves the object to the next paragraph.")); + m_moveObjectSizer->Add(itemButton49, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxTOP|wxBOTTOM, 5); + +////@end wxRichTextSizePage content construction +} + +wxRichTextAttr* wxRichTextSizePage::GetAttributes() +{ + return wxRichTextFormattingDialog::GetDialogAttributes(this); +} + +/*! + * Should we show tooltips? + */ + +bool wxRichTextSizePage::ShowToolTips() +{ + return true; +} + +bool wxRichTextSizePage::TransferDataToWindow() +{ + m_float->SetSelection(GetAttributes()->GetTextBoxAttr().GetFloatMode()); + m_verticalAlignmentCheckbox->SetValue(GetAttributes()->GetTextBoxAttr().HasVerticalAlignment()); + if (GetAttributes()->GetTextBoxAttr().HasVerticalAlignment()) + { + if ((int) GetAttributes()->GetTextBoxAttr().GetVerticalAlignment() > 0 && + (int) GetAttributes()->GetTextBoxAttr().GetVerticalAlignment() < 4) + { + m_verticalAlignmentComboBox->SetSelection(((int) GetAttributes()->GetTextBoxAttr().GetVerticalAlignment() - 1)); + } + else + m_verticalAlignmentComboBox->SetSelection(0); + } + + wxRichTextFormattingDialog* dialog = wxRichTextFormattingDialog::GetDialog(this); + + if (dialog) + { + // Only show the Move Object controls if there's an object. + if (!dialog->GetObject()) + { + m_moveObjectParentSizer->Show(m_moveObjectSizer, false); + GetSizer()->Layout(); + } + } + + if (dialog && dialog->GetObject()) + { + wxTextAttrSize size = dialog->GetObject()->GetNaturalSize(); + if (size.GetWidth().IsValid() && size.GetHeight().IsValid()) + { + if (!GetAttributes()->GetTextBoxAttr().GetWidth().IsValid() || GetAttributes()->GetTextBoxAttr().GetWidth().GetValue() <= 0) + { + GetAttributes()->GetTextBoxAttr().GetWidth() = size.GetWidth(); + } + + if (!GetAttributes()->GetTextBoxAttr().GetHeight().IsValid() || GetAttributes()->GetTextBoxAttr().GetHeight().GetValue() <= 0) + { + GetAttributes()->GetTextBoxAttr().GetHeight() = size.GetHeight(); + } + } + } + + wxRichTextFormattingDialog::SetDimensionValue(GetAttributes()->GetTextBoxAttr().GetWidth(), m_width, m_unitsW, m_widthCheckbox); + wxRichTextFormattingDialog::SetDimensionValue(GetAttributes()->GetTextBoxAttr().GetHeight(), m_height, m_unitsH, m_heightCheckbox); + wxRichTextFormattingDialog::SetDimensionValue(GetAttributes()->GetTextBoxAttr().GetTop(), m_offset, m_unitsOffset, m_offsetYCheckbox); + + return true; +} + +bool wxRichTextSizePage::TransferDataFromWindow() +{ + GetAttributes()->GetTextBoxAttr().SetFloatMode((wxTextBoxAttrFloatStyle) m_float->GetSelection()); + if (m_float->GetSelection() == 0) + GetAttributes()->GetTextBoxAttr().RemoveFlag(wxTEXT_BOX_ATTR_FLOAT); + + if (m_verticalAlignmentCheckbox->GetValue()) + GetAttributes()->GetTextBoxAttr().SetVerticalAlignment((wxTextBoxAttrVerticalAlignment) (m_verticalAlignmentComboBox->GetSelection() + 1)); + else + { + GetAttributes()->GetTextBoxAttr().SetVerticalAlignment(wxTEXT_BOX_ATTR_VERTICAL_ALIGNMENT_NONE); + GetAttributes()->GetTextBoxAttr().RemoveFlag(wxTEXT_BOX_ATTR_VERTICAL_ALIGNMENT); + } + + wxRichTextFormattingDialog::GetDimensionValue(GetAttributes()->GetTextBoxAttr().GetWidth(), m_width, m_unitsW, m_widthCheckbox); + wxRichTextFormattingDialog::GetDimensionValue(GetAttributes()->GetTextBoxAttr().GetHeight(), m_height, m_unitsH, m_heightCheckbox); + wxRichTextFormattingDialog::GetDimensionValue(GetAttributes()->GetTextBoxAttr().GetTop(), m_offset, m_unitsOffset, m_offsetYCheckbox); + + return true; +} + +// Show/hide position controls +void wxRichTextSizePage::ShowPositionControls(bool show) +{ + if (m_parentSizer) + { + m_parentSizer->Show(m_positionControls, show); + Layout(); + } +} + +// Show/hide floating controls +void wxRichTextSizePage::ShowFloatingControls(bool show) +{ + if (m_parentSizer) + { + m_parentSizer->Show(m_floatingControls, show); + Layout(); + } +} + + +/*! + * Get bitmap resources + */ + +wxBitmap wxRichTextSizePage::GetBitmapResource( const wxString& name ) +{ + // Bitmap retrieval +////@begin wxRichTextSizePage bitmap retrieval + wxUnusedVar(name); + return wxNullBitmap; +////@end wxRichTextSizePage bitmap retrieval +} + +/*! + * Get icon resources + */ + +wxIcon wxRichTextSizePage::GetIconResource( const wxString& name ) +{ + // Icon retrieval +////@begin wxRichTextSizePage icon retrieval + wxUnusedVar(name); + return wxNullIcon; +////@end wxRichTextSizePage icon retrieval +} + + +/*! + * wxEVT_UPDATE_UI event handler for ID_RICHTEXT_WIDTH + */ + +void wxRichTextSizePage::OnRichtextWidthUpdate( wxUpdateUIEvent& event ) +{ + event.Enable(m_widthCheckbox->GetValue()); +} + +/*! + * wxEVT_UPDATE_UI event handler for ID_RICHTEXT_HEIGHT + */ + +void wxRichTextSizePage::OnRichtextHeightUpdate( wxUpdateUIEvent& event ) +{ + event.Enable(m_heightCheckbox->GetValue()); +} + +/*! + * wxEVT_UPDATE_UI event handler for ID_RICHTEXT_OFFSET + */ + +void wxRichTextSizePage::OnRichtextOffsetUpdate( wxUpdateUIEvent& event ) +{ + event.Enable(m_offsetYCheckbox->GetValue()); +} + + +/*! + * wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_RICHTEXT_PARA_UP + */ + +void wxRichTextSizePage::OnRichtextParaUpClick( wxCommandEvent& WXUNUSED(event) ) +{ + wxRichTextFormattingDialog* dialog = wxRichTextFormattingDialog::GetDialog(this); + if (!dialog || !dialog->GetObject()) + return; + + // Make sure object attributes are up-to-date + dialog->TransferDataFromWindow(); + + wxRichTextBuffer* buffer = dialog->GetObject()->GetBuffer(); + wxRichTextParagraphLayoutBox* container = dialog->GetObject()->GetParentContainer(); + wxRichTextObject* parent = dialog->GetObject()->GetParent(); + if (!container || !parent || !buffer) + return; + + wxRichTextRange range = dialog->GetObject()->GetRange(); + wxRichTextObjectList::compatibility_iterator iter = container->GetChildren().GetFirst(); + if (!iter) + return; + + while (iter) + { + if (iter->GetData() == parent) + break; + iter = iter->GetNext(); + } + if (!iter) + return; + iter = iter->GetPrevious(); + if (!iter) + return; + + wxRichTextObject *obj = iter->GetData(); + wxRichTextRange rg = obj->GetRange(); + // tempObj will be deleted along with the undo object, and a clone of it will be + // returned by InsertObjectWithUndo + wxRichTextObject* tempObj = dialog->GetObject()->Clone(); + + container->DeleteRangeWithUndo(range, buffer->GetRichTextCtrl(), buffer); + + wxRichTextObject* obj2 = container->InsertObjectWithUndo(rg.GetStart(), tempObj, buffer->GetRichTextCtrl(), buffer, 0); + dialog->SetObject(obj2); +} + +/*! + * wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_RICHTEXT_DOWN + */ + +void wxRichTextSizePage::OnRichtextParaDownClick( wxCommandEvent& WXUNUSED(event) ) +{ + wxRichTextFormattingDialog* dialog = wxRichTextFormattingDialog::GetDialog(this); + if (!dialog || !dialog->GetObject()) + return; + + // Make sure object attributes are up-to-date + dialog->TransferDataFromWindow(); + + wxRichTextBuffer* buffer = dialog->GetObject()->GetBuffer(); + wxRichTextParagraphLayoutBox* container = dialog->GetObject()->GetParentContainer(); + wxRichTextObject* parent = dialog->GetObject()->GetParent(); + if (!container || !parent || !buffer) + return; + + wxRichTextRange range = dialog->GetObject()->GetRange(); + + wxRichTextObjectList::compatibility_iterator iter = buffer->GetChildren().GetFirst(); + if (!iter) + return; + + while (iter) + { + if (iter->GetData() == parent) + break; + iter = iter->GetNext(); + } + + iter = iter->GetNext(); + if (!iter) + return; + + wxRichTextObject *obj = iter->GetData(); + wxRichTextRange rg = obj->GetRange(); + // tempObj will be deleted along with the undo object, and a clone of it will be + // returned by InsertObjectWithUndo + wxRichTextObject* tempObj = dialog->GetObject()->Clone(); + + container->DeleteRangeWithUndo(range, buffer->GetRichTextCtrl(), buffer); + + // Minus one because we deleted an object + wxRichTextObject* obj2 = container->InsertObjectWithUndo(rg.GetStart()-1, tempObj, buffer->GetRichTextCtrl(), buffer, 0); + dialog->SetObject(obj2); +} + + +/*! + * wxEVT_UPDATE_UI event handler for ID_RICHTEXT_VERTICAL_ALIGNMENT_COMBOBOX + */ + +void wxRichTextSizePage::OnRichtextVerticalAlignmentComboboxUpdate( wxUpdateUIEvent& event ) +{ + event.Enable(m_verticalAlignmentCheckbox->GetValue()); +} + diff --git a/src/richtext/richtextstyledlg.cpp b/src/richtext/richtextstyledlg.cpp index 0c663345dc..6979d66f9e 100644 --- a/src/richtext/richtextstyledlg.cpp +++ b/src/richtext/richtextstyledlg.cpp @@ -67,6 +67,8 @@ BEGIN_EVENT_TABLE( wxRichTextStyleOrganiserDialog, wxDialog ) END_EVENT_TABLE() +IMPLEMENT_HELP_PROVISION(wxRichTextStyleOrganiserDialog) + /*! * wxRichTextStyleOrganiserDialog constructors */ @@ -110,6 +112,7 @@ void wxRichTextStyleOrganiserDialog::Init() m_closeButton = NULL; m_bottomButtonSizer = NULL; m_restartNumberingCtrl = NULL; + m_stdButtonSizer = NULL; m_okButton = NULL; m_cancelButton = NULL; ////@end wxRichTextStyleOrganiserDialog member initialisation @@ -277,23 +280,29 @@ void wxRichTextStyleOrganiserDialog::CreateControls() m_restartNumberingCtrl->SetToolTip(_("Check to restart numbering.")); m_bottomButtonSizer->Add(m_restartNumberingCtrl, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); - m_bottomButtonSizer->Add(5, 5, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5); + m_stdButtonSizer = new wxStdDialogButtonSizer; + m_bottomButtonSizer->Add(m_stdButtonSizer, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5); m_okButton = new wxButton( itemDialog1, wxID_OK, _("OK"), wxDefaultPosition, wxDefaultSize, 0 ); - m_okButton->SetDefault(); - m_okButton->SetHelpText(_("Click to confirm your selection.")); - if (wxRichTextStyleOrganiserDialog::ShowToolTips()) - m_okButton->SetToolTip(_("Click to confirm your selection.")); - m_bottomButtonSizer->Add(m_okButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + m_stdButtonSizer->AddButton(m_okButton); m_cancelButton = new wxButton( itemDialog1, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); - m_cancelButton->SetHelpText(_("Click to cancel this window.")); - if (wxRichTextStyleOrganiserDialog::ShowToolTips()) - m_cancelButton->SetToolTip(_("Click to cancel this window.")); - m_bottomButtonSizer->Add(m_cancelButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + m_stdButtonSizer->AddButton(m_cancelButton); + + wxButton* itemButton28 = new wxButton( itemDialog1, wxID_HELP, _("&Help"), wxDefaultPosition, wxDefaultSize, 0 ); + m_stdButtonSizer->AddButton(itemButton28); + + m_stdButtonSizer->Realize(); ////@end wxRichTextStyleOrganiserDialog content construction + if (GetHelpId() == -1) + { + wxWindow* button = FindWindowById(wxID_HELP); + if (button) + m_stdButtonSizer->Show(button, false); + } + if ((m_flags & wxRICHTEXT_ORGANISER_CREATE_STYLES) == 0) { m_buttonSizer->Show(m_newCharacter, false); @@ -323,8 +332,8 @@ void wxRichTextStyleOrganiserDialog::CreateControls() if ((m_flags & wxRICHTEXT_ORGANISER_OK_CANCEL) == 0) { - m_bottomButtonSizer->Show(m_okButton, false); - m_bottomButtonSizer->Show(m_cancelButton, false); + m_stdButtonSizer->Show(m_okButton, false); + m_stdButtonSizer->Show(m_cancelButton, false); } else { diff --git a/src/richtext/richtextstylepage.cpp b/src/richtext/richtextstylepage.cpp index 5dde2fe7ee..7dedcd1783 100644 --- a/src/richtext/richtextstylepage.cpp +++ b/src/richtext/richtextstylepage.cpp @@ -17,13 +17,13 @@ * wxRichTextStylePage type definition */ -IMPLEMENT_DYNAMIC_CLASS( wxRichTextStylePage, wxPanel ) +IMPLEMENT_DYNAMIC_CLASS( wxRichTextStylePage, wxRichTextDialogPage ) /*! * wxRichTextStylePage event table definition */ -BEGIN_EVENT_TABLE( wxRichTextStylePage, wxPanel ) +BEGIN_EVENT_TABLE( wxRichTextStylePage, wxRichTextDialogPage ) ////@begin wxRichTextStylePage event table entries EVT_UPDATE_UI( ID_RICHTEXTSTYLEPAGE_NEXT_STYLE, wxRichTextStylePage::OnNextStyleUpdate ) @@ -32,6 +32,8 @@ BEGIN_EVENT_TABLE( wxRichTextStylePage, wxPanel ) END_EVENT_TABLE() +IMPLEMENT_HELP_PROVISION(wxRichTextStylePage) + /*! * wxRichTextStylePage constructors */ @@ -67,7 +69,7 @@ void wxRichTextStylePage::Init() bool wxRichTextStylePage::Create( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) { ////@begin wxRichTextStylePage creation - wxPanel::Create( parent, id, pos, size, style ); + wxRichTextDialogPage::Create( parent, id, pos, size, style ); CreateControls(); if (GetSizer()) @@ -86,44 +88,44 @@ bool wxRichTextStylePage::Create( wxWindow* parent, wxWindowID id, const wxPoint void wxRichTextStylePage::CreateControls() { ////@begin wxRichTextStylePage content construction - wxRichTextStylePage* itemPanel1 = this; + wxRichTextStylePage* itemRichTextDialogPage1 = this; wxBoxSizer* itemBoxSizer2 = new wxBoxSizer(wxVERTICAL); - itemPanel1->SetSizer(itemBoxSizer2); + itemRichTextDialogPage1->SetSizer(itemBoxSizer2); wxBoxSizer* itemBoxSizer3 = new wxBoxSizer(wxVERTICAL); itemBoxSizer2->Add(itemBoxSizer3, 1, wxGROW|wxALL, 5); wxBoxSizer* itemBoxSizer4 = new wxBoxSizer(wxHORIZONTAL); - itemBoxSizer3->Add(itemBoxSizer4, 0, wxALIGN_CENTER_HORIZONTAL, 5); + itemBoxSizer3->Add(itemBoxSizer4, 0, wxGROW, 5); wxBoxSizer* itemBoxSizer5 = new wxBoxSizer(wxVERTICAL); - itemBoxSizer4->Add(itemBoxSizer5, 0, wxGROW, 5); + itemBoxSizer4->Add(itemBoxSizer5, 1, wxGROW, 5); - wxStaticText* itemStaticText6 = new wxStaticText( itemPanel1, wxID_STATIC, _("&Style:"), wxDefaultPosition, wxDefaultSize, 0 ); + wxStaticText* itemStaticText6 = new wxStaticText( itemRichTextDialogPage1, wxID_STATIC, _("&Style:"), wxDefaultPosition, wxDefaultSize, 0 ); itemBoxSizer5->Add(itemStaticText6, 0, wxALIGN_LEFT|wxLEFT|wxRIGHT|wxTOP, 5); - m_styleName = new wxTextCtrl( itemPanel1, ID_RICHTEXTSTYLEPAGE_STYLE_NAME, wxT(""), wxDefaultPosition, wxSize(300, -1), wxTE_READONLY ); + m_styleName = new wxTextCtrl( itemRichTextDialogPage1, ID_RICHTEXTSTYLEPAGE_STYLE_NAME, wxEmptyString, wxDefaultPosition, wxSize(300, -1), wxTE_READONLY ); m_styleName->SetHelpText(_("The style name.")); if (wxRichTextStylePage::ShowToolTips()) m_styleName->SetToolTip(_("The style name.")); itemBoxSizer5->Add(m_styleName, 0, wxGROW|wxALL, 5); - wxStaticText* itemStaticText8 = new wxStaticText( itemPanel1, wxID_STATIC, _("&Based on:"), wxDefaultPosition, wxDefaultSize, 0 ); + wxStaticText* itemStaticText8 = new wxStaticText( itemRichTextDialogPage1, wxID_STATIC, _("&Based on:"), wxDefaultPosition, wxDefaultSize, 0 ); itemBoxSizer5->Add(itemStaticText8, 0, wxALIGN_LEFT|wxLEFT|wxRIGHT|wxTOP, 5); wxArrayString m_basedOnStrings; - m_basedOn = new wxComboBox( itemPanel1, ID_RICHTEXTSTYLEPAGE_BASED_ON, wxT(""), wxDefaultPosition, wxDefaultSize, m_basedOnStrings, wxCB_DROPDOWN ); + m_basedOn = new wxComboBox( itemRichTextDialogPage1, ID_RICHTEXTSTYLEPAGE_BASED_ON, wxEmptyString, wxDefaultPosition, wxSize(300, -1), m_basedOnStrings, wxCB_DROPDOWN ); m_basedOn->SetHelpText(_("The style on which this style is based.")); if (wxRichTextStylePage::ShowToolTips()) m_basedOn->SetToolTip(_("The style on which this style is based.")); itemBoxSizer5->Add(m_basedOn, 0, wxGROW|wxALL, 5); - wxStaticText* itemStaticText10 = new wxStaticText( itemPanel1, wxID_STATIC, _("&Next style:"), wxDefaultPosition, wxDefaultSize, 0 ); + wxStaticText* itemStaticText10 = new wxStaticText( itemRichTextDialogPage1, wxID_STATIC, _("&Next style:"), wxDefaultPosition, wxDefaultSize, 0 ); itemBoxSizer5->Add(itemStaticText10, 0, wxALIGN_LEFT|wxLEFT|wxRIGHT|wxTOP, 5); wxArrayString m_nextStyleStrings; - m_nextStyle = new wxComboBox( itemPanel1, ID_RICHTEXTSTYLEPAGE_NEXT_STYLE, wxT(""), wxDefaultPosition, wxDefaultSize, m_nextStyleStrings, wxCB_DROPDOWN ); + m_nextStyle = new wxComboBox( itemRichTextDialogPage1, ID_RICHTEXTSTYLEPAGE_NEXT_STYLE, wxEmptyString, wxDefaultPosition, wxSize(300, -1), m_nextStyleStrings, wxCB_DROPDOWN ); m_nextStyle->SetHelpText(_("The default style for the next paragraph.")); if (wxRichTextStylePage::ShowToolTips()) m_nextStyle->SetToolTip(_("The default style for the next paragraph.")); @@ -156,14 +158,18 @@ bool wxRichTextStylePage::TransferDataFromWindow() bool wxRichTextStylePage::TransferDataToWindow() { wxPanel::TransferDataToWindow(); - + wxRichTextStyleDefinition* def = wxRichTextFormattingDialog::GetDialogStyleDefinition(this); if (def) { + m_basedOn->Freeze(); + m_nextStyle->Freeze(); + wxRichTextParagraphStyleDefinition* paraDef = wxDynamicCast(def, wxRichTextParagraphStyleDefinition); wxRichTextListStyleDefinition* listDef = wxDynamicCast(def, wxRichTextListStyleDefinition); - // wxRichTextCharacterStyleDefinition* charDef = wxDynamicCast(def, wxRichTextCharacterStyleDefinition); + wxRichTextCharacterStyleDefinition* charDef = wxDynamicCast(def, wxRichTextCharacterStyleDefinition); wxRichTextStyleSheet* sheet = wxRichTextFormattingDialog::GetDialog(this)->GetStyleSheet(); + wxRichTextBoxStyleDefinition* boxDef = wxDynamicCast(def, wxRichTextBoxStyleDefinition); m_styleName->SetValue(def->GetName()); @@ -226,7 +232,17 @@ bool wxRichTextStylePage::TransferDataToWindow() m_basedOn->Append(p->GetName()); } } - else + else if (boxDef) + { + size_t i; + for (i = 0; i < sheet->GetBoxStyleCount(); i++) + { + wxRichTextBoxStyleDefinition* p = wxDynamicCast(sheet->GetBoxStyle(i), wxRichTextBoxStyleDefinition); + if (p) + m_basedOn->Append(p->GetName()); + } + } + else if (charDef) { size_t i; for (i = 0; i < sheet->GetCharacterStyleCount(); i++) @@ -240,6 +256,9 @@ bool wxRichTextStylePage::TransferDataToWindow() } m_basedOn->SetValue(def->GetBaseStyle()); + + m_nextStyle->Thaw(); + m_basedOn->Thaw(); } return true; diff --git a/src/richtext/richtextstyles.cpp b/src/richtext/richtextstyles.cpp index 649a2a11c3..af2c0f4f37 100644 --- a/src/richtext/richtextstyles.cpp +++ b/src/richtext/richtextstyles.cpp @@ -35,6 +35,7 @@ IMPLEMENT_CLASS(wxRichTextStyleDefinition, wxObject) IMPLEMENT_CLASS(wxRichTextCharacterStyleDefinition, wxRichTextStyleDefinition) IMPLEMENT_CLASS(wxRichTextParagraphStyleDefinition, wxRichTextStyleDefinition) IMPLEMENT_CLASS(wxRichTextListStyleDefinition, wxRichTextParagraphStyleDefinition) +IMPLEMENT_CLASS(wxRichTextBoxStyleDefinition, wxRichTextStyleDefinition) /*! * A definition @@ -103,6 +104,20 @@ bool wxRichTextParagraphStyleDefinition::operator ==(const wxRichTextParagraphSt return (Eq(def) && m_nextStyle == def.m_nextStyle); } +/*! + * Box style definition + */ + +void wxRichTextBoxStyleDefinition::Copy(const wxRichTextBoxStyleDefinition& def) +{ + wxRichTextStyleDefinition::Copy(def); +} + +bool wxRichTextBoxStyleDefinition::operator ==(const wxRichTextBoxStyleDefinition& def) const +{ + return (Eq(def)); +} + /*! * List style definition */ @@ -315,6 +330,8 @@ bool wxRichTextStyleSheet::RemoveStyle(wxRichTextStyleDefinition* def, bool dele return true; if (RemoveListStyle(def, deleteStyle)) return true; + if (RemoveBoxStyle(def, deleteStyle)) + return true; return false; } @@ -340,6 +357,7 @@ void wxRichTextStyleSheet::DeleteStyles() WX_CLEAR_LIST(wxList, m_characterStyleDefinitions); WX_CLEAR_LIST(wxList, m_paragraphStyleDefinitions); WX_CLEAR_LIST(wxList, m_listStyleDefinitions); + WX_CLEAR_LIST(wxList, m_boxStyleDefinitions); } /// Insert into list of style sheets @@ -405,6 +423,13 @@ bool wxRichTextStyleSheet::AddListStyle(wxRichTextListStyleDefinition* def) return AddStyle(m_listStyleDefinitions, def); } +/// Add a definition to the box style list +bool wxRichTextStyleSheet::AddBoxStyle(wxRichTextBoxStyleDefinition* def) +{ + def->GetStyle().SetParagraphStyleName(def->GetName()); + return AddStyle(m_boxStyleDefinitions, def); +} + /// Add a definition to the appropriate style list bool wxRichTextStyleSheet::AddStyle(wxRichTextStyleDefinition* def) { @@ -420,6 +445,10 @@ bool wxRichTextStyleSheet::AddStyle(wxRichTextStyleDefinition* def) if (charDef) return AddCharacterStyle(charDef); + wxRichTextBoxStyleDefinition* boxDef = wxDynamicCast(def, wxRichTextBoxStyleDefinition); + if (boxDef) + return AddBoxStyle(boxDef); + return false; } @@ -438,6 +467,10 @@ wxRichTextStyleDefinition* wxRichTextStyleSheet::FindStyle(const wxString& name, if (charDef) return charDef; + wxRichTextBoxStyleDefinition* boxDef = FindBoxStyle(name, recurse); + if (boxDef) + return boxDef; + return NULL; } @@ -466,6 +499,12 @@ void wxRichTextStyleSheet::Copy(const wxRichTextStyleSheet& sheet) AddListStyle(new wxRichTextListStyleDefinition(*def)); } + for (node = sheet.m_boxStyleDefinitions.GetFirst(); node; node = node->GetNext()) + { + wxRichTextBoxStyleDefinition* def = (wxRichTextBoxStyleDefinition*) node->GetData(); + AddBoxStyle(new wxRichTextBoxStyleDefinition(*def)); + } + SetName(sheet.GetName()); SetDescription(sheet.GetDescription()); } @@ -560,6 +599,11 @@ void wxRichTextStyleListBox::UpdateStyles() for (i = 0; i < GetStyleSheet()->GetListStyleCount(); i++) m_styleNames.Add(GetStyleSheet()->GetListStyle(i)->GetName()); } + if (GetStyleType() == wxRICHTEXT_STYLE_ALL || GetStyleType() == wxRICHTEXT_STYLE_BOX) + { + for (i = 0; i < GetStyleSheet()->GetBoxStyleCount(); i++) + m_styleNames.Add(GetStyleSheet()->GetBoxStyle(i)->GetName()); + } m_styleNames.Sort(); SetItemCount(m_styleNames.GetCount()); @@ -817,6 +861,13 @@ wxString wxRichTextStyleListBox::GetStyleToShowInIdleTime(wxRichTextCtrl* ctrl, else if ((styleType == wxRICHTEXT_STYLE_ALL || styleType == wxRICHTEXT_STYLE_LIST) && !attr.GetListStyleName().IsEmpty()) styleName = attr.GetListStyleName(); + // TODO: when we have a concept of focused object (text box), we'll + // use the paragraph style name of the focused object as the frame style name. +#if 0 + else if ((styleType == wxRICHTEXT_STYLE_ALL || styleType == wxRICHTEXT_STYLE_BOX) && + !attr.GetBoxStyleName().IsEmpty()) + styleName = attr.GetBoxStyleName(); +#endif } else if ((styleType == wxRICHTEXT_STYLE_ALL || styleType == wxRICHTEXT_STYLE_CHARACTER) && !attr.GetCharacterStyleName().IsEmpty()) @@ -923,6 +974,7 @@ bool wxRichTextStyleListCtrl::Create(wxWindow* parent, wxWindowID id, const wxPo choices.Add(_("Paragraph styles")); choices.Add(_("Character styles")); choices.Add(_("List styles")); + choices.Add(_("Box styles")); m_styleChoice = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, choices); @@ -997,6 +1049,10 @@ int wxRichTextStyleListCtrl::StyleTypeToIndex(wxRichTextStyleListBox::wxRichText { return 3; } + else if (styleType == wxRichTextStyleListBox::wxRICHTEXT_STYLE_BOX) + { + return 4; + } return 0; } @@ -1009,6 +1065,8 @@ wxRichTextStyleListBox::wxRichTextStyleType wxRichTextStyleListCtrl::StyleIndexT return wxRichTextStyleListBox::wxRICHTEXT_STYLE_CHARACTER; else if (i == 3) return wxRichTextStyleListBox::wxRICHTEXT_STYLE_LIST; + else if (i == 4) + return wxRichTextStyleListBox::wxRICHTEXT_STYLE_BOX; return wxRichTextStyleListBox::wxRICHTEXT_STYLE_ALL; } diff --git a/src/richtext/richtextsymboldlg.cpp b/src/richtext/richtextsymboldlg.cpp index c19891efcd..d26d6419e0 100644 --- a/src/richtext/richtextsymboldlg.cpp +++ b/src/richtext/richtextsymboldlg.cpp @@ -309,6 +309,8 @@ BEGIN_EVENT_TABLE( wxSymbolPickerDialog, wxDialog ) END_EVENT_TABLE() +IMPLEMENT_HELP_PROVISION(wxSymbolPickerDialog) + /*! * wxSymbolPickerDialog constructors */ @@ -366,6 +368,7 @@ void wxSymbolPickerDialog::Init() #if defined(__UNICODE__) m_fromUnicodeCtrl = NULL; #endif + m_stdButtonSizer = NULL; ////@end wxSymbolPickerDialog member initialisation m_dontUpdate = false; } @@ -460,25 +463,29 @@ void wxSymbolPickerDialog::CreateControls() #endif - wxBoxSizer* itemBoxSizer20 = new wxBoxSizer(wxHORIZONTAL); - itemBoxSizer3->Add(itemBoxSizer20, 0, wxGROW, 5); + m_stdButtonSizer = new wxStdDialogButtonSizer; - itemBoxSizer20->Add(5, 5, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5); + itemBoxSizer3->Add(m_stdButtonSizer, 0, wxGROW|wxTOP|wxBOTTOM, 5); + wxButton* itemButton21 = new wxButton( itemDialog1, wxID_OK, _("Insert"), wxDefaultPosition, wxDefaultSize, 0 ); + itemButton21->SetDefault(); + m_stdButtonSizer->AddButton(itemButton21); - wxStdDialogButtonSizer* itemStdDialogButtonSizer22 = new wxStdDialogButtonSizer; + wxButton* itemButton22 = new wxButton( itemDialog1, wxID_CANCEL, _("Close"), wxDefaultPosition, wxDefaultSize, 0 ); + m_stdButtonSizer->AddButton(itemButton22); - itemBoxSizer20->Add(itemStdDialogButtonSizer22, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM, 5); - wxButton* itemButton23 = new wxButton( itemDialog1, wxID_OK, _("Insert"), wxDefaultPosition, wxDefaultSize, 0 ); - itemButton23->SetDefault(); - itemStdDialogButtonSizer22->AddButton(itemButton23); + wxButton* itemButton23 = new wxButton( itemDialog1, wxID_HELP, _("&Help"), wxDefaultPosition, wxDefaultSize, 0 ); + m_stdButtonSizer->AddButton(itemButton23); - wxButton* itemButton24 = new wxButton( itemDialog1, wxID_CANCEL, _("Close"), wxDefaultPosition, wxDefaultSize, 0 ); - itemStdDialogButtonSizer22->AddButton(itemButton24); - - itemStdDialogButtonSizer22->Realize(); + m_stdButtonSizer->Realize(); ////@end wxSymbolPickerDialog content construction + if (GetHelpId() == -1) + { + wxWindow* button = FindWindowById(wxID_HELP); + if (button) + m_stdButtonSizer->Show(button, false); + } } /// Data transfer diff --git a/src/richtext/richtexttabspage.cpp b/src/richtext/richtexttabspage.cpp index 78006682df..2c433f9f83 100644 --- a/src/richtext/richtexttabspage.cpp +++ b/src/richtext/richtexttabspage.cpp @@ -17,13 +17,13 @@ * wxRichTextTabsPage type definition */ -IMPLEMENT_DYNAMIC_CLASS( wxRichTextTabsPage, wxPanel ) +IMPLEMENT_DYNAMIC_CLASS( wxRichTextTabsPage, wxRichTextDialogPage ) /*! * wxRichTextTabsPage event table definition */ -BEGIN_EVENT_TABLE( wxRichTextTabsPage, wxPanel ) +BEGIN_EVENT_TABLE( wxRichTextTabsPage, wxRichTextDialogPage ) ////@begin wxRichTextTabsPage event table entries EVT_LISTBOX( ID_RICHTEXTTABSPAGE_TABLIST, wxRichTextTabsPage::OnTablistSelected ) @@ -41,6 +41,8 @@ BEGIN_EVENT_TABLE( wxRichTextTabsPage, wxPanel ) END_EVENT_TABLE() +IMPLEMENT_HELP_PROVISION(wxRichTextTabsPage) + /*! * wxRichTextTabsPage constructors */ @@ -77,7 +79,7 @@ void wxRichTextTabsPage::Init() bool wxRichTextTabsPage::Create( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) { ////@begin wxRichTextTabsPage creation - wxPanel::Create( parent, id, pos, size, style ); + wxRichTextDialogPage::Create( parent, id, pos, size, style ); CreateControls(); if (GetSizer()) @@ -96,10 +98,10 @@ bool wxRichTextTabsPage::Create( wxWindow* parent, wxWindowID id, const wxPoint& void wxRichTextTabsPage::CreateControls() { ////@begin wxRichTextTabsPage content construction - wxRichTextTabsPage* itemPanel1 = this; + wxRichTextTabsPage* itemRichTextDialogPage1 = this; wxBoxSizer* itemBoxSizer2 = new wxBoxSizer(wxVERTICAL); - itemPanel1->SetSizer(itemBoxSizer2); + itemRichTextDialogPage1->SetSizer(itemBoxSizer2); wxBoxSizer* itemBoxSizer3 = new wxBoxSizer(wxVERTICAL); itemBoxSizer2->Add(itemBoxSizer3, 1, wxGROW|wxALL, 5); @@ -110,10 +112,10 @@ void wxRichTextTabsPage::CreateControls() wxBoxSizer* itemBoxSizer5 = new wxBoxSizer(wxVERTICAL); itemBoxSizer4->Add(itemBoxSizer5, 0, wxGROW, 5); - wxStaticText* itemStaticText6 = new wxStaticText( itemPanel1, wxID_STATIC, _("&Position (tenths of a mm):"), wxDefaultPosition, wxDefaultSize, 0 ); + wxStaticText* itemStaticText6 = new wxStaticText( itemRichTextDialogPage1, wxID_STATIC, _("&Position (tenths of a mm):"), wxDefaultPosition, wxDefaultSize, 0 ); itemBoxSizer5->Add(itemStaticText6, 0, wxALIGN_LEFT|wxLEFT|wxRIGHT|wxTOP, 5); - m_tabEditCtrl = new wxTextCtrl( itemPanel1, ID_RICHTEXTTABSPAGE_TABEDIT, wxT(""), wxDefaultPosition, wxDefaultSize, 0 ); + m_tabEditCtrl = new wxTextCtrl( itemRichTextDialogPage1, ID_RICHTEXTTABSPAGE_TABEDIT, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); m_tabEditCtrl->SetHelpText(_("The tab position.")); if (wxRichTextTabsPage::ShowToolTips()) m_tabEditCtrl->SetToolTip(_("The tab position.")); @@ -121,7 +123,7 @@ void wxRichTextTabsPage::CreateControls() wxArrayString m_tabListCtrlStrings; m_tabListCtrlStrings.Add(_("The tab positions.")); - m_tabListCtrl = new wxListBox( itemPanel1, ID_RICHTEXTTABSPAGE_TABLIST, wxDefaultPosition, wxSize(80, 200), m_tabListCtrlStrings, wxLB_SINGLE ); + m_tabListCtrl = new wxListBox( itemRichTextDialogPage1, ID_RICHTEXTTABSPAGE_TABLIST, wxDefaultPosition, wxSize(80, 200), m_tabListCtrlStrings, wxLB_SINGLE ); itemBoxSizer5->Add(m_tabListCtrl, 1, wxGROW|wxLEFT|wxRIGHT|wxBOTTOM, 5); itemBoxSizer4->Add(2, 1, 1, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM, 5); @@ -129,22 +131,22 @@ void wxRichTextTabsPage::CreateControls() wxBoxSizer* itemBoxSizer10 = new wxBoxSizer(wxVERTICAL); itemBoxSizer4->Add(itemBoxSizer10, 0, wxGROW, 5); - wxStaticText* itemStaticText11 = new wxStaticText( itemPanel1, wxID_STATIC, wxT(""), wxDefaultPosition, wxDefaultSize, 0 ); + wxStaticText* itemStaticText11 = new wxStaticText( itemRichTextDialogPage1, wxID_STATIC, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); itemBoxSizer10->Add(itemStaticText11, 0, wxALIGN_CENTER_HORIZONTAL|wxBOTTOM, 5); - wxButton* itemButton12 = new wxButton( itemPanel1, ID_RICHTEXTTABSPAGE_NEW_TAB, _("&New"), wxDefaultPosition, wxDefaultSize, 0 ); + wxButton* itemButton12 = new wxButton( itemRichTextDialogPage1, ID_RICHTEXTTABSPAGE_NEW_TAB, _("&New"), wxDefaultPosition, wxDefaultSize, 0 ); itemButton12->SetHelpText(_("Click to create a new tab position.")); if (wxRichTextTabsPage::ShowToolTips()) itemButton12->SetToolTip(_("Click to create a new tab position.")); itemBoxSizer10->Add(itemButton12, 0, wxGROW|wxALL, 5); - wxButton* itemButton13 = new wxButton( itemPanel1, ID_RICHTEXTTABSPAGE_DELETE_TAB, _("&Delete"), wxDefaultPosition, wxDefaultSize, 0 ); + wxButton* itemButton13 = new wxButton( itemRichTextDialogPage1, ID_RICHTEXTTABSPAGE_DELETE_TAB, _("&Delete"), wxDefaultPosition, wxDefaultSize, 0 ); itemButton13->SetHelpText(_("Click to delete the selected tab position.")); if (wxRichTextTabsPage::ShowToolTips()) itemButton13->SetToolTip(_("Click to delete the selected tab position.")); itemBoxSizer10->Add(itemButton13, 0, wxGROW|wxLEFT|wxRIGHT|wxBOTTOM, 5); - wxButton* itemButton14 = new wxButton( itemPanel1, ID_RICHTEXTTABSPAGE_DELETE_ALL_TABS, _("Delete A&ll"), wxDefaultPosition, wxDefaultSize, 0 ); + wxButton* itemButton14 = new wxButton( itemRichTextDialogPage1, ID_RICHTEXTTABSPAGE_DELETE_ALL_TABS, _("Delete A&ll"), wxDefaultPosition, wxDefaultSize, 0 ); itemButton14->SetHelpText(_("Click to delete all tab positions.")); if (wxRichTextTabsPage::ShowToolTips()) itemButton14->SetToolTip(_("Click to delete all tab positions.")); diff --git a/src/richtext/richtextxml.cpp b/src/richtext/richtextxml.cpp index 54842f4768..5f2f84cbe9 100644 --- a/src/richtext/richtextxml.cpp +++ b/src/richtext/richtextxml.cpp @@ -166,6 +166,12 @@ wxRichTextObject* wxRichTextXMLHandler::CreateObjectForXMLName(wxRichTextObject* return new wxRichTextParagraph; else if (name == wxT("paragraphlayout")) return new wxRichTextParagraphLayoutBox; + else if (name == wxT("textbox")) + return new wxRichTextBox; + else if (name == wxT("cell")) + return new wxRichTextBox; + else if (name == wxT("table")) + return new wxRichTextBox; else return NULL; } @@ -173,39 +179,18 @@ wxRichTextObject* wxRichTextXMLHandler::CreateObjectForXMLName(wxRichTextObject* /// Recursively import an object bool wxRichTextXMLHandler::ImportXML(wxRichTextBuffer* buffer, wxRichTextObject* obj, wxXmlNode* node) { - obj->ImportFromXML(buffer, node, this); + bool recurse = false; + obj->ImportFromXML(buffer, node, this, & recurse); + + // TODO: how to control whether to import children. wxRichTextCompositeObject* compositeParent = wxDynamicCast(obj, wxRichTextCompositeObject); - if (compositeParent) + if (recurse && compositeParent) { wxXmlNode* child = node->GetChildren(); while (child) { - if (child->GetName() == wxT("stylesheet")) - { - if (GetFlags() & wxRICHTEXT_HANDLER_INCLUDE_STYLESHEET) - { - wxRichTextStyleSheet* sheet = new wxRichTextStyleSheet; - wxString sheetName = child->GetAttribute(wxT("name"), wxEmptyString); - wxString sheetDescription = child->GetAttribute(wxT("description"), wxEmptyString); - sheet->SetName(sheetName); - sheet->SetDescription(sheetDescription); - - wxXmlNode* child2 = child->GetChildren(); - while (child2) - { - ImportStyleDefinition(sheet, child2); - - child2 = child2->GetNext(); - } - - // Notify that styles have changed. If this is vetoed by the app, - // the new sheet will be deleted. If it is not vetoed, the - // old sheet will be deleted and replaced with the new one. - buffer->SetStyleSheetAndNotify(sheet); - } - } - else + if (child->GetName() != wxT("stylesheet")) { wxRichTextObject* childObj = CreateObjectForXMLName(obj, child->GetName()); if (childObj) @@ -301,6 +286,26 @@ bool wxRichTextXMLHandler::ImportStyleDefinition(wxRichTextStyleSheet* sheet, wx sheet->AddParagraphStyle(def); } + else if (styleType == wxT("boxstyle")) + { + wxRichTextBoxStyleDefinition* def = new wxRichTextBoxStyleDefinition(styleName); + + def->SetBaseStyle(baseStyleName); + + wxXmlNode* child = node->GetChildren(); + while (child) + { + if (child->GetName() == wxT("style")) + { + wxRichTextAttr attr; + ImportStyle(attr, child, true); + def->SetStyle(attr); + } + child = child->GetNext(); + } + + sheet->AddBoxStyle(def); + } else if (styleType == wxT("liststyle")) { wxRichTextListStyleDefinition* def = new wxRichTextListStyleDefinition(styleName); @@ -399,6 +404,17 @@ wxString wxRichTextXMLHandler::GetText(wxXmlNode *node, const wxString& param, b return str1; } +wxXmlNode* wxRichTextXMLHandler::FindNode(wxXmlNode* node, const wxString& name) +{ + wxXmlNode* child = node->GetChildren(); + while (child) + { + if (child->GetName() == name) + return child; + } + return NULL; +} + // For use with earlier versions of wxWidgets #ifndef WXUNUSED_IN_UNICODE #if wxUSE_UNICODE @@ -611,7 +627,7 @@ static inline void AddAttribute(wxString& str, const wxString& name, const wxCol static inline void AddAttribute(wxString& str, const wxString& name, const wxTextAttrDimension& dim) { - if (dim.IsPresent()) + if (dim.IsValid()) { wxString value = MakeString(dim.GetValue()) + wxT(",") + MakeString((int) dim.GetFlags()); str << wxT(" ") << name << wxT("=\""); @@ -622,13 +638,13 @@ static inline void AddAttribute(wxString& str, const wxString& name, const wxTex static inline void AddAttribute(wxString& str, const wxString& rootName, const wxTextAttrDimensions& dims) { - if (dims.GetLeft().IsPresent()) + if (dims.GetLeft().IsValid()) AddAttribute(str, rootName + wxString(wxT("-left")), dims.GetLeft()); - if (dims.GetRight().IsPresent()) + if (dims.GetRight().IsValid()) AddAttribute(str, rootName + wxString(wxT("-right")), dims.GetRight()); - if (dims.GetTop().IsPresent()) + if (dims.GetTop().IsValid()) AddAttribute(str, rootName + wxString(wxT("-top")), dims.GetTop()); - if (dims.GetBottom().IsPresent()) + if (dims.GetBottom().IsValid()) AddAttribute(str, rootName + wxString(wxT("-bottom")), dims.GetBottom()); } @@ -682,7 +698,7 @@ static inline void AddAttribute(wxXmlNode* node, const wxString& name, const wxC static inline void AddAttribute(wxXmlNode* node, const wxString& name, const wxTextAttrDimension& dim) { - if (dim.IsPresent()) + if (dim.IsValid()) { wxString value = MakeString(dim.GetValue()) + wxT(",") + MakeString(dim.GetFlags()); AddAttribute(node, name, value); @@ -691,13 +707,13 @@ static inline void AddAttribute(wxXmlNode* node, const wxString& name, const wxT static inline void AddAttribute(wxXmlNode* node, const wxString& rootName, const wxTextAttrDimensions& dims) { - if (dims.GetLeft().IsPresent()) + if (dims.GetLeft().IsValid()) AddAttribute(node, rootName + wxString(wxT("-left")), dims.GetLeft()); - if (dims.GetRight().IsPresent()) + if (dims.GetRight().IsValid()) AddAttribute(node, rootName + wxString(wxT("-right")), dims.GetRight()); - if (dims.GetTop().IsPresent()) + if (dims.GetTop().IsValid()) AddAttribute(node, rootName + wxString(wxT("-top")), dims.GetTop()); - if (dims.GetBottom().IsPresent()) + if (dims.GetBottom().IsValid()) AddAttribute(node, rootName + wxString(wxT("-bottom")), dims.GetBottom()); } @@ -809,6 +825,12 @@ bool wxRichTextXMLHandler::DoSaveFile(wxRichTextBuffer *buffer, wxOutputStream& wxRichTextListStyleDefinition* def = buffer->GetStyleSheet()->GetListStyle(i); ExportStyleDefinition(styleSheetNode, def); } + + for (i = 0; i < (int) buffer->GetStyleSheet()->GetBoxStyleCount(); i++) + { + wxRichTextBoxStyleDefinition* def = buffer->GetStyleSheet()->GetBoxStyle(i); + ExportStyleDefinition(styleSheetNode, def); + } } bool success = ExportXML(rootNode, *buffer); #if wxRICHTEXT_USE_OUTPUT_TIMINGS @@ -878,6 +900,12 @@ bool wxRichTextXMLHandler::DoSaveFile(wxRichTextBuffer *buffer, wxOutputStream& ExportStyleDefinition(stream, def, level + 1); } + for (i = 0; i < (int) buffer->GetStyleSheet()->GetBoxStyleCount(); i++) + { + wxRichTextBoxStyleDefinition* def = buffer->GetStyleSheet()->GetBoxStyle(i); + ExportStyleDefinition(stream, def, level + 1); + } + OutputIndentation(stream, level); OutputString(stream, wxT("")); } @@ -912,6 +940,7 @@ bool wxRichTextXMLHandler::ExportStyleDefinition(wxOutputStream& stream, wxRichT wxRichTextCharacterStyleDefinition* charDef = wxDynamicCast(def, wxRichTextCharacterStyleDefinition); wxRichTextParagraphStyleDefinition* paraDef = wxDynamicCast(def, wxRichTextParagraphStyleDefinition); wxRichTextListStyleDefinition* listDef = wxDynamicCast(def, wxRichTextListStyleDefinition); + wxRichTextBoxStyleDefinition* boxDef = wxDynamicCast(def, wxRichTextBoxStyleDefinition); wxString baseStyle = def->GetBaseStyle(); wxString baseStyleProp; @@ -995,7 +1024,7 @@ bool wxRichTextXMLHandler::ExportStyleDefinition(wxOutputStream& stream, wxRichT level ++; - wxString style = AddAttributes(def->GetStyle(), false); + wxString style = AddAttributes(def->GetStyle(), true); OutputIndentation(stream, level); OutputString(stream, wxT("")); + + level --; + + OutputIndentation(stream, level); + OutputString(stream, wxT("")); + } + return true; } @@ -1233,6 +1284,7 @@ bool wxRichTextXMLHandler::ExportStyleDefinition(wxXmlNode* parent, wxRichTextSt { wxRichTextCharacterStyleDefinition* charDef = wxDynamicCast(def, wxRichTextCharacterStyleDefinition); wxRichTextParagraphStyleDefinition* paraDef = wxDynamicCast(def, wxRichTextParagraphStyleDefinition); + wxRichTextBoxStyleDefinition* boxDef = wxDynamicCast(def, wxRichTextBoxStyleDefinition); wxRichTextListStyleDefinition* listDef = wxDynamicCast(def, wxRichTextListStyleDefinition); wxString baseStyle = def->GetBaseStyle(); @@ -1275,6 +1327,12 @@ bool wxRichTextXMLHandler::ExportStyleDefinition(wxXmlNode* parent, wxRichTextSt } } } + else if (boxDef) + { + defNode->SetName(wxT("boxstyle")); + + AddAttributes(styleNode, def->GetStyle(), true); + } else if (paraDef) { defNode->SetName(wxT("paragraphstyle")); @@ -1777,7 +1835,7 @@ bool wxRichTextXMLHandler::ImportStyle(wxRichTextAttr& attr, wxXmlNode* node, bo attr.GetTextBoxAttr().SetClearMode(wxTEXT_BOX_ATTR_CLEAR_NONE); } else if (name == wxT("collapse-borders")) - attr.GetTextBoxAttr().SetCollapseBorders(value == wxT("1")); + attr.GetTextBoxAttr().SetCollapseBorders((wxTextBoxAttrCollapseMode) wxAtoi(value)); else if (name.Contains(wxT("border-"))) { @@ -1882,10 +1940,12 @@ bool wxRichTextXMLHandler::ImportStyle(wxRichTextAttr& attr, wxXmlNode* node, bo // wxUSE_STREAMS // Import this object from XML -bool wxRichTextObject::ImportFromXML(wxRichTextBuffer* WXUNUSED(buffer), wxXmlNode* node, wxRichTextXMLHandler* handler) +bool wxRichTextObject::ImportFromXML(wxRichTextBuffer* WXUNUSED(buffer), wxXmlNode* node, wxRichTextXMLHandler* handler, bool* recurse) { handler->ImportProperties(this, node); handler->ImportStyle(GetAttributes(), node, UsesParagraphAttributes()); + + *recurse = false; return true; } @@ -1948,9 +2008,9 @@ bool wxRichTextObject::ExportXML(wxXmlNode* parent, wxRichTextXMLHandler* handle // Import this object from XML -bool wxRichTextPlainText::ImportFromXML(wxRichTextBuffer* buffer, wxXmlNode* node, wxRichTextXMLHandler* handler) +bool wxRichTextPlainText::ImportFromXML(wxRichTextBuffer* buffer, wxXmlNode* node, wxRichTextXMLHandler* handler, bool* recurse) { - wxRichTextObject::ImportFromXML(buffer, node, handler); + wxRichTextObject::ImportFromXML(buffer, node, handler, recurse); if (node->GetName() == wxT("text")) { @@ -2212,9 +2272,9 @@ bool wxRichTextPlainText::ExportXML(wxXmlNode* parent, wxRichTextXMLHandler* han // Import this object from XML -bool wxRichTextImage::ImportFromXML(wxRichTextBuffer* buffer, wxXmlNode* node, wxRichTextXMLHandler* handler) +bool wxRichTextImage::ImportFromXML(wxRichTextBuffer* buffer, wxXmlNode* node, wxRichTextXMLHandler* handler, bool* recurse) { - wxRichTextObject::ImportFromXML(buffer, node, handler); + wxRichTextObject::ImportFromXML(buffer, node, handler, recurse); wxBitmapType imageType = wxBITMAP_TYPE_PNG; wxString value = node->GetAttribute(wxT("imagetype"), wxEmptyString); @@ -2361,14 +2421,39 @@ bool wxRichTextImage::ExportXML(wxXmlNode* parent, wxRichTextXMLHandler* handler // Import this object from XML -bool wxRichTextParagraphLayoutBox::ImportFromXML(wxRichTextBuffer* buffer, wxXmlNode* node, wxRichTextXMLHandler* handler) +bool wxRichTextParagraphLayoutBox::ImportFromXML(wxRichTextBuffer* buffer, wxXmlNode* node, wxRichTextXMLHandler* handler, bool* recurse) { - wxRichTextObject::ImportFromXML(buffer, node, handler); + wxRichTextObject::ImportFromXML(buffer, node, handler, recurse); + + *recurse = true; wxString partial = node->GetAttribute(wxT("partialparagraph"), wxEmptyString); if (partial == wxT("true")) SetPartialParagraph(true); + wxXmlNode* child = wxRichTextXMLHandler::FindNode(node, wxT("stylesheet")); + if (child && (handler->GetFlags() & wxRICHTEXT_HANDLER_INCLUDE_STYLESHEET)) + { + wxRichTextStyleSheet* sheet = new wxRichTextStyleSheet; + wxString sheetName = child->GetAttribute(wxT("name"), wxEmptyString); + wxString sheetDescription = child->GetAttribute(wxT("description"), wxEmptyString); + sheet->SetName(sheetName); + sheet->SetDescription(sheetDescription); + + wxXmlNode* child2 = child->GetChildren(); + while (child2) + { + handler->ImportStyleDefinition(sheet, child2); + + child2 = child2->GetNext(); + } + + // Notify that styles have changed. If this is vetoed by the app, + // the new sheet will be deleted. If it is not vetoed, the + // old sheet will be deleted and replaced with the new one. + buffer->SetStyleSheetAndNotify(sheet); + } + return true; } @@ -2377,7 +2462,8 @@ bool wxRichTextParagraphLayoutBox::ImportFromXML(wxRichTextBuffer* buffer, wxXml bool wxRichTextParagraphLayoutBox::ExportXML(wxOutputStream& stream, int indent, wxRichTextXMLHandler* handler) { ::OutputIndentation(stream, indent); - ::OutputString(stream, wxT("GetConvMem(), handler->GetConvFile()); + wxString nodeName = GetXMLNodeName(); + ::OutputString(stream, wxT("<") + nodeName, handler->GetConvMem(), handler->GetConvFile()); wxString style = handler->AddAttributes(GetAttributes(), true); @@ -2399,7 +2485,7 @@ bool wxRichTextParagraphLayoutBox::ExportXML(wxOutputStream& stream, int indent, } ::OutputIndentation(stream, indent); - ::OutputString(stream, wxT(""), handler->GetConvMem(), handler->GetConvFile()); + ::OutputString(stream, wxT(""), handler->GetConvMem(), handler->GetConvFile()); return true; } #endif @@ -2408,7 +2494,7 @@ bool wxRichTextParagraphLayoutBox::ExportXML(wxOutputStream& stream, int indent, // Export this object to the given parent node, usually creating at least one child node. bool wxRichTextParagraphLayoutBox::ExportXML(wxXmlNode* parent, wxRichTextXMLHandler* handler) { - wxXmlNode* elementNode = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("paragraphlayout")); + wxXmlNode* elementNode = new wxXmlNode(wxXML_ELEMENT_NODE, GetXMLNodeName()); parent->AddChild(elementNode); handler->AddAttributes(elementNode, GetAttributes(), true); handler->WriteProperties(elementNode, GetProperties()); @@ -2427,6 +2513,112 @@ bool wxRichTextParagraphLayoutBox::ExportXML(wxXmlNode* parent, wxRichTextXMLHan } #endif +// Import this object from XML +bool wxRichTextTable::ImportFromXML(wxRichTextBuffer* buffer, wxXmlNode* node, wxRichTextXMLHandler* handler, bool* recurse) +{ + wxRichTextBox::ImportFromXML(buffer, node, handler, recurse); + + *recurse = false; + + m_rowCount = wxAtoi(node->GetAttribute(wxT("rows"), wxEmptyString)); + m_colCount = wxAtoi(node->GetAttribute(wxT("cols"), wxEmptyString)); + + wxXmlNode* child = node->GetChildren(); + while (child) + { + wxRichTextObject* childObj = handler->CreateObjectForXMLName(this, child->GetName()); + if (childObj) + { + AppendChild(childObj); + handler->ImportXML(buffer, childObj, child); + } + child = child->GetNext(); + } + + m_cells.Add(wxRichTextObjectPtrArray(), m_rowCount); + int i, j; + for (i = 0; i < m_rowCount; i++) + { + wxRichTextObjectPtrArray& colArray = m_cells[i]; + for (j = 0; j < m_colCount; j++) + { + int idx = i * m_colCount + j; + if (idx < (int) GetChildren().GetCount()) + { + wxRichTextCell* cell = wxDynamicCast(GetChildren().Item(idx)->GetData(), wxRichTextCell); + if (cell) + colArray.Add(cell); + } + } + } + + return true; +} + +#if wxRICHTEXT_HAVE_DIRECT_OUTPUT +// Export this object directly to the given stream. +bool wxRichTextTable::ExportXML(wxOutputStream& stream, int indent, wxRichTextXMLHandler* handler) +{ + ::OutputIndentation(stream, indent); + wxString nodeName = GetXMLNodeName(); + ::OutputString(stream, wxT("<") + nodeName, handler->GetConvMem(), handler->GetConvFile()); + + wxString style = handler->AddAttributes(GetAttributes(), true); + + style << wxT(" rows=\"") << m_rowCount << wxT("\""); + style << wxT(" cols=\"") << m_colCount << wxT("\""); + + ::OutputString(stream, style + wxT(">"), handler->GetConvMem(), handler->GetConvFile()); + + if (GetProperties().GetCount() > 0) + { + handler->WriteProperties(stream, GetProperties(), indent); + } + + int i, j; + for (i = 0; i < m_rowCount; i++) + { + for (j = 0; j < m_colCount; j ++) + { + wxRichTextCell* cell = GetCell(i, j); + cell->ExportXML(stream, indent+1, handler); + } + } + + ::OutputIndentation(stream, indent); + ::OutputString(stream, wxT(""), handler->GetConvMem(), handler->GetConvFile()); + + return true; +} +#endif + +#if wxRICHTEXT_HAVE_XMLDOCUMENT_OUTPUT +// Export this object to the given parent node, usually creating at least one child node. +bool wxRichTextTable::ExportXML(wxXmlNode* parent, wxRichTextXMLHandler* handler) +{ + wxXmlNode* elementNode = new wxXmlNode(wxXML_ELEMENT_NODE, GetXMLNodeName()); + parent->AddChild(elementNode); + handler->AddAttributes(elementNode, GetAttributes(), true); + handler->WriteProperties(elementNode, GetProperties()); + + elementNode->AddAttribute(wxT("rows"), wxString::Format(wxT("%d"), m_rowCount)); + elementNode->AddAttribute(wxT("cols"), wxString::Format(wxT("%d"), m_colCount)); + + int i, j; + for (i = 0; i < m_rowCount; i++) + { + for (j = 0; j < m_colCount; j ++) + { + wxRichTextCell* cell = GetCell(i, j); + cell->ExportXML(elementNode, handler); + } + } + + return true; +} +#endif + + #endif // wxUSE_RICHTEXT && wxUSE_XML