From 603f702b4a0e19ffa27cffc52872efaac1aa8c54 Mon Sep 17 00:00:00 2001 From: Julian Smart Date: Fri, 14 Jan 2011 11:57:44 +0000 Subject: [PATCH] Implemented text boxes and tables, and further editing pages for backgrounds, borders and margins. wxRTC functions now operate on the currently focused object, which by default is the whole buffer. Up to three property commands are now shown on the context menu, depending on available objects in the current hierarchy. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@66680 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/richtext/richtextbackgroundpage.h | 110 + include/wx/richtext/richtextborderspage.h | 251 + include/wx/richtext/richtextbuffer.h | 1075 ++- include/wx/richtext/richtextbulletspage.h | 7 +- include/wx/richtext/richtextctrl.h | 205 +- include/wx/richtext/richtextdialogpage.h | 41 + include/wx/richtext/richtextfontpage.h | 7 +- include/wx/richtext/richtextformatdlg.h | 42 +- include/wx/richtext/richtextimagedlg.h | 238 +- include/wx/richtext/richtextindentspage.h | 5 +- include/wx/richtext/richtextliststylepage.h | 7 +- include/wx/richtext/richtextmarginspage.h | 179 + include/wx/richtext/richtextprint.h | 1 + include/wx/richtext/richtextsizepage.h | 159 + include/wx/richtext/richtextstyledlg.h | 5 + include/wx/richtext/richtextstylepage.h | 7 +- include/wx/richtext/richtextstyles.h | 53 +- include/wx/richtext/richtextsymboldlg.h | 4 + include/wx/richtext/richtexttabspage.h | 7 +- include/wx/richtext/richtextuicustomization.h | 123 + include/wx/richtext/richtextxml.h | 1 + samples/richtext/richtext.cpp | 74 +- src/richtext/richtextbackgroundpage.cpp | 239 + src/richtext/richtextborderspage.cpp | 923 ++ src/richtext/richtextbuffer.cpp | 4136 +++++++-- src/richtext/richtextbulletspage.cpp | 63 +- src/richtext/richtextctrl.cpp | 1015 ++- src/richtext/richtextdialogs.pjd | 11051 +++++++++++++++++++++--- src/richtext/richtextfontpage.cpp | 62 +- src/richtext/richtextformatdlg.cpp | 208 +- src/richtext/richtextimagedlg.cpp | 740 +- src/richtext/richtextindentspage.cpp | 62 +- src/richtext/richtextliststylepage.cpp | 38 +- src/richtext/richtextmarginspage.cpp | 563 ++ src/richtext/richtextprint.cpp | 97 +- src/richtext/richtextsizepage.cpp | 639 ++ src/richtext/richtextstyledlg.cpp | 33 +- src/richtext/richtextstylepage.cpp | 51 +- src/richtext/richtextstyles.cpp | 58 + src/richtext/richtextsymboldlg.cpp | 31 +- src/richtext/richtexttabspage.cpp | 26 +- src/richtext/richtextxml.cpp | 290 +- 42 files changed, 19526 insertions(+), 3400 deletions(-) create mode 100644 include/wx/richtext/richtextbackgroundpage.h create mode 100644 include/wx/richtext/richtextborderspage.h create mode 100644 include/wx/richtext/richtextdialogpage.h rewrite include/wx/richtext/richtextimagedlg.h (73%) create mode 100644 include/wx/richtext/richtextmarginspage.h create mode 100644 include/wx/richtext/richtextsizepage.h create mode 100644 include/wx/richtext/richtextuicustomization.h create mode 100644 src/richtext/richtextbackgroundpage.cpp create mode 100644 src/richtext/richtextborderspage.cpp rewrite src/richtext/richtextimagedlg.cpp (84%) create mode 100644 src/richtext/richtextmarginspage.cpp create mode 100644 src/richtext/richtextsizepage.cpp diff --git a/include/wx/richtext/richtextbackgroundpage.h b/include/wx/richtext/richtextbackgroundpage.h new file mode 100644 index 0000000..f2b1cc8 --- /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 0000000..4452d78 --- /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 0c80994..c58edf7 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 beafe36..88ea4eb 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 f2d976a..6456ef9 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 -/*! - * Forward declarations +/* Identifiers */ +#define wxID_RICHTEXT_PROPERTIES1 (wxID_HIGHEST + 1) +#define wxID_RICHTEXT_PROPERTIES2 (wxID_HIGHEST + 2) +#define wxID_RICHTEXT_PROPERTIES3 (wxID_HIGHEST + 3) /*! - * wxRichTextItem class declaration + * Forward declarations */ +#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); + + /// 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); + + /// 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() + WX_FORWARD_TO_SCROLL_HELPER() - // implement wxTextEntry methods - virtual wxString DoGetValue() const; + // 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 0000000..694cb56 --- /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 b43f5f2..28e005d 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 ea3a34a..1f22c14 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 dissimilarity index 73% index 10b0ddc..d80725a 100644 --- a/include/wx/richtext/richtextimagedlg.h +++ b/include/wx/richtext/richtextimagedlg.h @@ -1,143 +1,95 @@ -///////////////////////////////////////////////////////////////////////////// -// Name: wx/richtext/richtextimagedlg.h -// Purpose: -// Author: Mingquan Yang -// Modified by: -// Created: Wed 02 Jun 2010 11:27:23 CST -// RCS-ID: -// Copyright: (c) Mingquan Yang -// Licence: wxWindows licence -///////////////////////////////////////////////////////////////////////////// - -#include "wx/dialog.h" - -#ifndef _RICHTEXTIMAGEDLG_H_ -#define _RICHTEXTIMAGEDLG_H_ - -/*! - * Includes - */ -#include "wx/richtext/richtextbuffer.h" - -/*! - * Forward declarations - */ - -class WXDLLIMPEXP_FWD_CORE wxButton; -class WXDLLIMPEXP_FWD_CORE wxComboBox; -class WXDLLIMPEXP_FWD_CORE wxTextCtrl; - -/*! - * Control identifiers - */ - -////@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 -////@end control identifiers - - -/*! - * wxRichTextImageDialog class declaration - */ - -class WXDLLIMPEXP_RICHTEXT wxRichTextImageDialog: public wxDialog -{ - DECLARE_DYNAMIC_CLASS( wxRichTextImageDialog ) - 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 ); - - /// 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 ); - - /// Destructor - ~wxRichTextImageDialog(); - - /// Initialises member variables - void Init(); - - /// Creates the controls and sizers - void CreateControls(); - - /// Set the dimension into the value and units controls - void SetDimensionValue(wxTextAttrDimension& dim, wxTextCtrl* valueCtrl, wxComboBox* unitsCtrl); - - /// Get the dimension from the value and units controls - void GetDimensionValue(wxTextAttrDimension& dim, wxTextCtrl* valueCtrl, wxComboBox* unitsCtrl); - -////@begin wxRichTextImageDialog 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 - - /// Retrieves bitmap resources - wxBitmap GetBitmapResource( const wxString& name ); - - /// Retrieves icon resources - wxIcon GetIconResource( const wxString& name ); -////@end wxRichTextImageDialog 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; - /// 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 - }; -////@end wxRichTextImageDialog member variables - - wxRichTextBuffer* m_buffer; - wxRichTextObject* m_image; - wxRichTextObject* m_parent; -}; - -#endif - // _RICHTEXTIMAGEDLG_H_ +///////////////////////////////////////////////////////////////////////////// +// Name: wx/richtext/richtextimagedlg.h +// Purpose: +// Author: Mingquan Yang +// Modified by: Julian Smart +// Created: Wed 02 Jun 2010 11:27:23 CST +// RCS-ID: +// Copyright: (c) Mingquan Yang, Julian Smart +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +#include "wx/dialog.h" + +#ifndef _RICHTEXTIMAGEDLG_H_ +#define _RICHTEXTIMAGEDLG_H_ + +/*! + * Includes + */ + +#include "wx/richtext/richtextbuffer.h" +#include "wx/richtext/richtextformatdlg.h" + +/*! + * Forward declarations + */ + +class WXDLLIMPEXP_FWD_CORE wxButton; +class WXDLLIMPEXP_FWD_CORE wxComboBox; +class WXDLLIMPEXP_FWD_CORE wxTextCtrl; + +/*! + * Control identifiers + */ + +////@begin control identifiers +#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 + +/*! + * wxRichTextObjectPropertiesDialog class declaration + */ + +class WXDLLIMPEXP_RICHTEXT wxRichTextObjectPropertiesDialog: public wxRichTextFormattingDialog +{ + DECLARE_DYNAMIC_CLASS( wxRichTextObjectPropertiesDialog ) + DECLARE_EVENT_TABLE() + +public: + /// Constructors + 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( 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 + ~wxRichTextObjectPropertiesDialog(); + + /// Initialises member variables + void Init(); + + /// Creates the controls and sizers + void CreateControls(); + +////@begin wxRichTextObjectPropertiesDialog event handler declarations + +////@end wxRichTextObjectPropertiesDialog event handler declarations + +////@begin wxRichTextObjectPropertiesDialog member function declarations + + /// Retrieves bitmap resources + wxBitmap GetBitmapResource( const wxString& name ); + + /// Retrieves icon resources + wxIcon GetIconResource( const wxString& name ); +////@end wxRichTextObjectPropertiesDialog member function declarations + + /// Should we show tooltips? + static bool ShowToolTips(); + +////@begin wxRichTextObjectPropertiesDialog member variables + /// Control identifiers + enum { + ID_RICHTEXTOBJECTPROPERTIESDIALOG = 10650 + }; +////@end wxRichTextObjectPropertiesDialog member variables +}; + +#endif + // _RICHTEXTIMAGEDLG_H_ diff --git a/include/wx/richtext/richtextindentspage.h b/include/wx/richtext/richtextindentspage.h index 1d77ca7..0e734de 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 92b7c67..4eedafa 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 0000000..b05f385 --- /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 dc7b0c2..29b8694 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 0000000..ba2fb76 --- /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 403b180..3dc8528 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 f947830..0d6457a 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 022f81e..4ebcede 100644 --- a/include/wx/richtext/richtextstyles.h +++ b/include/wx/richtext/richtextstyles.h @@ -241,6 +241,40 @@ protected: }; /*! + * 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 2099281..c77884d 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 1626012..1495c66 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 0000000..ea20a60 --- /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 a14e397..baf52c7 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 1f72878..6868d5a 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 0000000..1530fdf --- /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 0000000..b7c9f74 --- /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 04a62fa..83c74a0 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); + + DrawBorder(dc, buffer, editBorderAttr.GetTextBoxAttr().GetBorder(), borderRect, flags); + } + + if (attr.GetTextBoxAttr().GetBorder().IsValid()) + DrawBorder(dc, buffer, attr.GetTextBoxAttr().GetBorder(), borderRect); - if (attr.GetTextBoxAttr().GetOutline().HasBorder()) - DrawBorder(dc, attr.GetTextBoxAttr().GetOutline(), outlineRect); + 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,72 +1419,212 @@ void wxRichTextCompositeObject::Dump(wxTextOutputStream& stream) } } -/*! - * wxRichTextParagraphLayoutBox - * This box knows how to lay out paragraphs. - */ +/// 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; -IMPLEMENT_DYNAMIC_CLASS(wxRichTextParagraphLayoutBox, wxRichTextCompositeObject) + wxSize sz; -wxRichTextParagraphLayoutBox::wxRichTextParagraphLayoutBox(wxRichTextObject* parent): - wxRichTextCompositeObject(parent) -{ - Init(); -} + wxArrayInt childExtents; + wxArrayInt* p; + if (partialExtents) + p = & childExtents; + else + p = NULL; -wxRichTextParagraphLayoutBox::~wxRichTextParagraphLayoutBox() -{ - if (m_floatCollector) + wxRichTextObjectList::compatibility_iterator node = m_children.GetFirst(); + while (node) { - delete m_floatCollector; - m_floatCollector = NULL; - } -} + 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; -/// Initialize the object. -void wxRichTextParagraphLayoutBox::Init() -{ - m_ctrl = NULL; + partialExtents->Add(0 /* zero size */ + lastSize); + } + } + else + { + wxSize childSize; - // For now, assume is the only box and has no initial size. - m_range = wxRichTextRange(0, -1); + wxRichTextRange rangeToUse = range; + rangeToUse.LimitTo(child->GetRange()); + if (child->IsTopLevel()) + rangeToUse = child->GetOwnRange(); - m_invalidRange.SetRange(-1, -1); - m_leftMargin = 4; - m_rightMargin = 4; - m_topMargin = 4; - m_bottomMargin = 4; - m_partialParagraph = false; - m_floatCollector = NULL; -} + int childDescent = 0; -void wxRichTextParagraphLayoutBox::Clear() -{ - DeleteChildren(); + // 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(); - if (m_floatCollector) - delete m_floatCollector; - m_floatCollector = NULL; - m_partialParagraph = false; -} + 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); -/// Copy -void wxRichTextParagraphLayoutBox::Copy(const wxRichTextParagraphLayoutBox& obj) -{ - Clear(); + if ((flags & wxRICHTEXT_CACHE_SIZE) && (rangeToUse == child->GetRange() || child->IsTopLevel())) + { + child->SetCachedSize(childSize); + child->SetDescent(childDescent); + } - wxRichTextCompositeObject::Copy(obj); + if (partialExtents) + { + int lastSize; + if (partialExtents->GetCount() > 0) + lastSize = (*partialExtents)[partialExtents->GetCount()-1]; + else + lastSize = 0; - m_partialParagraph = obj.m_partialParagraph; - m_defaultAttributes = obj.m_defaultAttributes; + 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. + */ + +IMPLEMENT_DYNAMIC_CLASS(wxRichTextParagraphLayoutBox, wxRichTextCompositeObject) + +wxRichTextParagraphLayoutBox::wxRichTextParagraphLayoutBox(wxRichTextObject* parent): + wxRichTextCompositeObject(parent) +{ + Init(); +} + +wxRichTextParagraphLayoutBox::~wxRichTextParagraphLayoutBox() +{ + if (m_floatCollector) + { + delete m_floatCollector; + m_floatCollector = NULL; + } +} + +/// Initialize the object. +void wxRichTextParagraphLayoutBox::Init() +{ + m_ctrl = NULL; + + // For now, assume is the only box and has no initial size. + m_range = wxRichTextRange(0, -1); + m_ownRange = wxRichTextRange(0, -1); + + m_invalidRange = wxRICHTEXT_ALL; + + SetMargins(4); + m_partialParagraph = false; + m_floatCollector = NULL; +} + +void wxRichTextParagraphLayoutBox::Clear() +{ + DeleteChildren(); + + if (m_floatCollector) + delete m_floatCollector; + m_floatCollector = NULL; + m_partialParagraph = false; +} + +/// Copy +void wxRichTextParagraphLayoutBox::Copy(const wxRichTextParagraphLayoutBox& obj) +{ + Clear(); + + wxRichTextCompositeObject::Copy(obj); + + m_partialParagraph = obj.m_partialParagraph; + m_defaultAttributes = obj.m_defaultAttributes; } // 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; } +// 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) +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); + // 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)) ) + { + // 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); + + // 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); + + // 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)); - // Layout must set the cached size - availableSpace.y += child->GetCachedSize().y; - maxWidth = wxMax(maxWidth, child->GetCachedSize().x); + availableSpace.y += child->GetCachedSize().y; + maxWidth = wxMax(maxWidth, child->GetCachedSize().x); + maxMinWidth = wxMax(maxMinWidth, child->GetMinSize().x); + maxMaxWidth = wxMax(maxMaxWidth, child->GetMaxSize().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; + node = node->GetNext(); + } + break; + } } - 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; + node = node->GetNext(); + } + + 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) - { - if (child->GetLines().GetCount() == 0) - child->Layout(dc, availableSpace, style); - else - child->SetPosition(wxPoint(child->GetPosition().x, child->GetPosition().y + inc)); - - availableSpace.y += child->GetCachedSize().y; - maxWidth = wxMax(maxWidth, child->GetCachedSize().x); - } + child->Move(wxPoint(child->GetPosition().x, child->GetPosition().y + yOffset)); node = node->GetNext(); } - break; } - - node = node->GetNext(); } - SetCachedSize(wxSize(maxWidth, availableSpace.y)); - - 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(); - lineCount ++; + 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; + } - 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); - - wxRichTextRange thisRange = obj->GetRange(); - wxRichTextAttr thisAttr = obj->GetAttributes(); + // Delete the range in each paragraph - // 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(); - } + { + // We're ending at the end of the paragraph, so merge the _next_ paragraph. + if (next) + nextParagraph = wxDynamicCast(next->GetData(), wxRichTextParagraph); + } - if (firstPara && nextParagraph && firstPara != nextParagraph) - { - // Move the objects to the previous para - wxRichTextObjectList::compatibility_iterator node1 = nextParagraph->GetChildren().GetFirst(); + 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(); + } - while (node1) + if (firstPara && nextParagraph && firstPara != nextParagraph) { - wxRichTextObject* obj1 = node1->GetData(); + // Move the objects to the previous para + wxRichTextObjectList::compatibility_iterator node1 = nextParagraph->GetChildren().GetFirst(); - firstPara->AppendChild(obj1); + while (node1) + { + wxRichTextObject* obj1 = node1->GetData(); - wxRichTextObjectList::compatibility_iterator next1 = node1->GetNext(); - nextParagraph->GetChildren().Erase(node1); + firstPara->AppendChild(obj1); - node1 = next1; - } + wxRichTextObjectList::compatibility_iterator next1 = node1->GetNext(); + nextParagraph->GetChildren().Erase(node1); - // Delete the paragraph - RemoveChild(nextParagraph, true); - } + node1 = next1; + } - // Avoid empty paragraphs - if (firstPara && firstPara->GetChildren().GetCount() == 0) - { - wxRichTextPlainText* text = new wxRichTextPlainText(wxEmptyString); - firstPara->AppendChild(text); - } + // Delete the paragraph + RemoveChild(nextParagraph, true); + } - if (applyFinalParagraphStyle) - firstPara->SetAttributes(nextParaAttr); + // Avoid empty paragraphs + if (firstPara && firstPara->GetChildren().GetCount() == 0) + { + wxRichTextPlainText* text = new wxRichTextPlainText(wxEmptyString); + firstPara->AppendChild(text); + } - return true; + 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; + + // 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); + } - currentPosition.x = (lineCount == 0 ? availableRect.x + startPositionFirstLine : availableRect.x + startPositionSubsequentLines); + // 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()) + + ) { + 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()); + } + + // 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(); + } - SetCachedSize(wxSize(maxWidth, currentPosition.y + spaceAfterPara)); + 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,54 +4975,83 @@ bool wxRichTextParagraph::GetRangeSize(const wxRichTextRange& range, wxSize& siz } else { - wxSize childSize; - - wxRichTextRange rangeToUse = range; - rangeToUse.LimitTo(child->GetRange()); - 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(); + wxSize childSize; - 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); + wxRichTextRange rangeToUse = range; + rangeToUse.LimitTo(child->GetRange()); +#if 0 + if (child->IsTopLevel()) + rangeToUse = child->GetOwnRange(); +#endif + int childDescent = 0; - 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(); - if (partialExtents) + sz.y = wxMax(sz.y, childSize.y); + sz.x += childSize.x; + descent = wxMax(descent, childDescent); + } + 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 (p) - p->Clear(); + 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) + p->Clear(); } node = node->GetNext(); @@ -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); +} + +/// 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(GetDefaultStyle()); + 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) +{ + 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, this, ctrl, false); + 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(); + if (!IsShown()) + return true; - wxRect childRect = wxRect(child->GetPosition(), child->GetCachedSize()); - child->Draw(dc, range, selectionRange, childRect, descent, style); + // 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); +} - node = node->GetNext(); +/// Copy +void wxRichTextBox::Copy(const wxRichTextBox& obj) +{ + wxRichTextParagraphLayoutBox::Copy(obj); +} + +// Edit properties via a GUI +bool wxRichTextBox::EditProperties(wxWindow* parent, wxRichTextBuffer* buffer) +{ + wxRichTextObjectPropertiesDialog boxDlg(this, wxGetTopLevelParent(parent), wxID_ANY, _("Box Properties")); + boxDlg.SetAttributes(GetAttributes()); + + if (boxDlg.ShowModal() == wxID_OK) + { + // 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; } - return true; + else + return false; } -/// Lay the item out -bool wxRichTextBox::Layout(wxDC& dc, const wxRect& rect, int style) +IMPLEMENT_DYNAMIC_CLASS(wxRichTextCell, wxRichTextBox) + +wxRichTextCell::wxRichTextCell(wxRichTextObject* parent): + wxRichTextBox(parent) { - wxRichTextObjectList::compatibility_iterator node = m_children.GetFirst(); - while (node) +} + +/// 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()) { - wxRichTextObject* child = node->GetData(); - child->Layout(dc, rect, style); + 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(); - node = node->GetNext(); + CollectStyle(attr, cellStyle, clashingAttr, absentAttr); + + selectedCellCount ++; + } + } + multipleCells = selectedCellCount > 1; } - m_dirty = false; - return true; + 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); } -/// Copy -void wxRichTextBox::Copy(const wxRichTextBox& obj) +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) { - wxRichTextCompositeObject::Copy(obj); + 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; } -/// 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 wxRichTextTable::EditProperties(wxWindow* parent, wxRichTextBuffer* buffer) { - wxRichTextObjectList::compatibility_iterator node = m_children.GetFirst(); - if (node) + wxRichTextObjectPropertiesDialog boxDlg(this, wxGetTopLevelParent(parent), wxID_ANY, _("Table Properties")); + boxDlg.SetAttributes(GetAttributes()); + + if (boxDlg.ShowModal() == wxID_OK) { - wxRichTextObject* child = node->GetData(); - return child->GetRangeSize(range, size, descent, dc, flags, position, partialExtents); + 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(); + + // 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.GetRange().GetLength(); + 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,38 @@ 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()); + + 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_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()); @@ -7193,11 +9524,37 @@ 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_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: break; } @@ -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()) { + wxRect containerRect = container->GetRect(); + m_ctrl->LayoutContent(); - // TODO Refresh the whole client area now - m_ctrl->Refresh(false); -#if wxRICHTEXT_USE_OWN_CARET - m_ctrl->PositionCaret(); + // 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 + + 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 (selectionRange.Contains(range.GetStart())) + 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 c62e3c3..9e0f30e 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 2e3c423..dcb37f5 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,46 +693,119 @@ void wxRichTextCtrl::OnMoveMouse(wxMouseEvent& event) event.Skip(); return; } - - if (m_dragging && hit != wxRICHTEXT_HITTEST_NONE) + + if (m_dragging) { - // TODO: test closeness + wxRichTextParagraphLayoutBox* commonAncestor = NULL; + wxRichTextParagraphLayoutBox* otherContainer = NULL; + wxRichTextParagraphLayoutBox* firstContainer = NULL; + + // 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(); + } + } - bool caretAtLineStart = false; + 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(); - 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 --; - } + // 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()); + } - if (m_caretPosition != position) - { - ExtendSelection(m_caretPosition, position, wxRICHTEXT_SHIFT_DOWN); + Refresh(); - MoveCaret(position, caretAtLineStart); - SetDefaultStyleToCursorStyle(); + 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 + SetCaretPositionAfterClick(container, position, hit, true /* extend selection */); + } } /// Right-click 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()) - { - newPos --; - caretLineStart = true; - } - else + wxRichTextParagraphLayoutBox* actualContainer = wxDynamicCast(contextObj, wxRichTextParagraphLayoutBox); + if (actualContainer && actualContainer != GetFocusObject() && actualContainer->AcceptsFocus()) { - 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; + + if (notInThisObject) + extendSel = false; + else + extendSel = ExtendSelection(m_caretPosition, newSelEnd, flags); - long newSelEnd = newPos; - - 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 0811aba..d41fafa 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,188 +10269,251 @@ 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 - "" - "" - - - - - - - "wxRichTextListStylePage" - "dialog-document" - "" - "dialog" - 0 - 1 - 0 - 0 - "18/10/2006" - "wbDialogProxy" - 10600 - 0 - "" - 0 - "" - "Standard" - 0 - 0 - "ID_RICHTEXTLISTSTYLEPAGE" - 10616 - "wxRichTextListStylePage" - "wxPanel" - "wxPanel" - "richtextliststylepage.cpp" - "../../include/wx/richtext/richtextliststylepage.h" - "" - "" - 1 - "" - 0 - "" - "" - "" - "" - "" - 0 - 1 - "<Any platform>" - "" - "" - "" - "" - "" - "" + + "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 + "" + "" + + + + + + + + "wxRichTextListStylePage" + "dialog-document" + "" + "dialog" + 0 + 1 + 0 + 0 + "18/10/2006" + "wbDialogProxy" + 10600 + 0 + "" + 0 + "" + "Standard" + 0 + 0 + "ID_RICHTEXTLISTSTYLEPAGE" + 10616 + "wxRichTextListStylePage" + "wxRichTextDialogPage" + "wxPanel" + "richtextliststylepage.cpp" + "../../include/wx/richtext/richtextliststylepage.h" + "" + "" + 1 + "" + 0 + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" + "" + "" + "" + "" + "" "Tiled" 0 0 @@ -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 @@ -14690,22 +14762,127 @@ "wbBoxSizerProxy" "Vertical" "" + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 0 0 0 "<Any platform>" - - "wxBoxSizer H" - "dialog-control-document" - "" - "sizer" - 0 - 1 - 0 - 0 - "wbBoxSizerProxy" - "Horizontal" - "" + + + + "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" + "" + "sizer" + 0 + 1 + 0 + 0 + "wbBoxSizerProxy" + "Vertical" + "" + 0 + 0 + 0 + "<Any platform>" + + "wxBoxSizer V" + "dialog-control-document" + "" + "sizer" + 0 + 1 + 0 + 0 + "wbBoxSizerProxy" + "Vertical" + "m_parentSizer" "Expand" "Centre" 0 @@ -14719,7 +14896,7 @@ 0 "<Any platform>" - "wxFlexGridSizer" + "wxBoxSizer V" "dialog-control-document" "" "sizer" @@ -14727,281 +14904,72 @@ 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 + "<Any platform>" - "wxStaticText: wxID_STATIC" + "wxBoxSizer H" "dialog-control-document" "" - "statictext" + "sizer" 0 1 0 0 - "wbStaticTextProxy" - "wxID_STATIC" - 5105 - "" - "wxStaticText" - "wxStaticText" - 1 - 0 - "" - "" + "wbBoxSizerProxy" + "Horizontal" "" - "&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" + "Expand" "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 - "" - "" - - - "wxBoxSizer H" - "dialog-control-document" - "" - "sizer" - 0 - 1 - 0 - 0 - "wbBoxSizerProxy" - "Horizontal" - "" - "Left" - "Centre" - 0 - 5 - 0 - 0 - 0 - 0 + 0 + 0 + 0 + 0 0 0 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" + "wxStaticText" + "wxStaticText" 1 0 "" "" - "m_width" - "" - 0 - "The image width to be shown - does not change the source image width." + "" + "Floating" + -1 + "" "" "" "" - "" + "wxSYS_DEFAULT_GUI_FONT:default,default,default, wxBOLD, false" 0 1 "<Any platform>" @@ -15012,22 +14980,10 @@ "" "" "" - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 + 0 + 0 + 0 + 0 0 0 0 @@ -15041,9 +14997,9 @@ "" -1 -1 - 65 + -1 -1 - "Left" + "Centre" "Centre" 0 5 @@ -15058,58 +15014,51 @@ "" - "wxComboBox: ID_RICHTEXTIMAGEDIALOG_UNITS_W" + "wxStaticLine: wxID_STATIC" "dialog-control-document" "" - "combobox" + "staticline" 0 1 0 0 - "wbComboBoxProxy" - "ID_RICHTEXTIMAGEDIALOG_UNITS_W" - 10019 + "wbStaticLineProxy" + "wxID_STATIC" + 5105 "" - "wxComboBox" - "wxComboBox" + "wxStaticLine" + "wxStaticLine" 1 0 "" "" - "m_unitsW" - "px|cm" - "px" - "Units for the image width." - "" + "" "" "" "" 0 1 "<Any platform>" - "" - "" - "" - "" - "" - "" - "" - 0 - 0 - 1 - 0 - 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 0 0 0 "" -1 -1 - 60 + -1 -1 "Centre" "Centre" - 0 + 1 5 1 1 @@ -15118,81 +15067,9 @@ 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" "" @@ -15204,7 +15081,7 @@ "wbBoxSizerProxy" "Horizontal" "" - "Left" + "Expand" "Centre" 0 5 @@ -15217,152 +15094,220 @@ 0 "<Any platform>" - "wxTextCtrl: ID_RICHTEXTIMAGEDIALOG_HEIGHT" + "Spacer" "dialog-control-document" "" - "textctrl" + "spacer" 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 + "wbSpacerProxy" + 5 + 5 + "Centre" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 "<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" + "wxFlexGridSizer" "dialog-control-document" "" - "combobox" + "sizer" 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 + "wbFlexGridSizerProxy" + "" + "" + 2 + 0 + 0 + 0 + "" "<Any platform>" - "" - "" - "" - "" - "" - "" - "" - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 0 - "" - -1 - -1 - 60 - -1 - "Centre" + "Expand" "Centre" 0 5 - 1 + 0 1 - 1 - 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" @@ -15383,13 +15328,13 @@ "" "" "" - "Image Vertical &Offset:" + "Size" -1 "" "" "" "" - "" + "wxSYS_DEFAULT_GUI_FONT:default,default,default, wxBOLD, false" 0 1 "<Any platform>" @@ -15419,7 +15364,7 @@ -1 -1 -1 - "Right" + "Centre" "Centre" 0 5 @@ -15434,217 +15379,33 @@ "" - "wxBoxSizer H" + "wxStaticLine: wxID_STATIC" "dialog-control-document" "" - "sizer" + "staticline" 0 1 0 0 - "wbBoxSizerProxy" - "Horizontal" + "wbStaticLineProxy" + "wxID_STATIC" + 5105 + "" + "wxStaticLine" + "wxStaticLine" + 1 + 0 + "" + "" "" - "Left" - "Centre" - 1 - 5 - 0 - 0 - 0 - 0 - 0 - 0 - 0 + "" + "" + "" + 0 + 1 "<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 + 1 + 0 0 0 0 @@ -15660,7 +15421,56 @@ -1 -1 -1 - "Right" + "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 @@ -15671,11 +15481,10 @@ 0 0 0 - "" - "" + "<Any platform>" - "wxBoxSizer H" + "wxFlexGridSizer" "dialog-control-document" "" "sizer" @@ -15683,10 +15492,16 @@ 1 0 0 - "wbBoxSizerProxy" - "Horizontal" + "wbFlexGridSizerProxy" + "" + "" + 2 + 0 + 0 + 0 "" - "Left" + "<Any platform>" + "Expand" "Centre" 0 5 @@ -15697,31 +15512,29 @@ 0 0 0 - "<Any platform>" - "wxButton: ID_RICHTEXTIMAGEDIALOG_PARA_UP" + "wxCheckBox: ID_RICHTEXT_WIDTH_CHECKBOX" "dialog-control-document" "" - "dialogcontrol" + "checkbox" 0 1 0 0 - "wbButtonProxy" - "wxEVT_COMMAND_BUTTON_CLICKED|OnRichtextimagedialogParaUpClick|NONE||wxRichTextImageDialog" - "ID_RICHTEXTIMAGEDIALOG_PARA_UP" - 10024 + "wbCheckBoxProxy" + "ID_RICHTEXT_WIDTH_CHECKBOX" + 10702 "" - "wxButton" - "wxButton" + "wxCheckBox" + "wxCheckBox" 1 0 "" "" - "" - "&Previous Paragraph" - 0 - "Moves the image to the previous paragraph." + "m_widthCheckbox" + "&Width:" + 0 + "Enable the width value." "" "" "" @@ -15736,12 +15549,10 @@ 0 1 "<Any platform>" - 0 - 0 - 0 - 0 - 0 - 0 + 0 + 0 + 0 + 0 0 0 0 @@ -15755,7 +15566,7 @@ 0 5 1 - 1 + 0 1 1 0 @@ -15765,29 +15576,201 @@ "" - "wxButton: ID_RICHTEXTIMAGEDIALOG_DOWN" + "wxBoxSizer H" "dialog-control-document" "" - "dialogcontrol" + "sizer" 0 1 0 0 - "wbButtonProxy" - "wxEVT_COMMAND_BUTTON_CLICKED|OnRichtextimagedialogDownClick|NONE||wxRichTextImageDialog" - "ID_RICHTEXTIMAGEDIALOG_DOWN" - 10025 - "" - "wxButton" - "wxButton" - 1 - 0 - "" - "" + "wbBoxSizerProxy" + "Horizontal" "" - "&Next Paragraph" - 0 - "Moves the image to the next paragraph." + "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." "" "" "" @@ -15802,12 +15785,10 @@ 0 1 "<Any platform>" - 0 - 0 - 0 - 0 - 0 - 0 + 0 + 0 + 0 + 0 0 0 0 @@ -15820,8 +15801,8 @@ "Centre" 0 5 - 0 - 1 + 1 + 0 1 1 0 @@ -15830,224 +15811,8660 @@ "" "" - - - - - "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" - "dialog-control-document" - "" - "sizer" - 0 - 1 - 0 - 0 - "wbStdDialogButtonSizerProxy" - 1 - 1 - 0 - 0 - 0 - 0 - 0 - 0 - "" - "Expand" - "Centre" - 0 - 5 - 1 - 1 - 1 - 1 - 0 - 0 - 0 - "<Any platform>" - - "wxButton: wxID_OK" - "dialog-control-document" - "" - "dialogcontrol" - 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" - "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 - "Click to discard your changes." - "" - "" + + "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 + 0 + 0 + "" + "" + + + + + "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>" + + "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>" + + "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 + "" + "" + "" + "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 + + + + "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_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 + "" + "wxNotebook" + "wxNotebook" + 1 + 0 + "" + "" + "" + 0 + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + "" "" "" "" "" "" "" + 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 + "Expand" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 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 - 0 - 0 + "" + "" + "" + "" + "" + "" + "" 0 + 0 + 0 + 1 + 0 + 0 + 0 0 - 0 + 1 0 + 0 + 0 + 0 + 0 "" -1 -1 - -1 - -1 - "Centre" + 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 - 1 - 1 - 1 - 1 + 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 caf10ca..08b6854 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 6ae7671..c440a77 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 }; - - if (i < 0 || i > 5) + wxRICHTEXT_FORMAT_LIST_STYLE, + wxRICHTEXT_FORMAT_SIZE, + wxRICHTEXT_FORMAT_MARGINS, + wxRICHTEXT_FORMAT_BORDERS, + wxRICHTEXT_FORMAT_BACKGROUND + }; + + 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 dissimilarity index 84% index 982df5e..939b51b 100644 --- a/src/richtext/richtextimagedlg.cpp +++ b/src/richtext/richtextimagedlg.cpp @@ -1,514 +1,226 @@ -///////////////////////////////////////////////////////////////////////////// -// Name: src/richtext/richtextimagedlg.cpp -// Purpose: -// Author: Mingquan Yang -// Modified by: -// Created: Wed 02 Jun 2010 11:27:23 CST -// RCS-ID: -// Copyright: (c) Mingquan Yang -// Licence: wxWindows licence -///////////////////////////////////////////////////////////////////////////// - -// For compilers that support precompilation, includes "wx/wx.h". -#include "wx/wxprec.h" - -#ifdef __BORLANDC__ -#pragma hdrstop -#endif - - -#if wxUSE_RICHTEXT - -#ifndef WX_PRECOMP - #include "wx/button.h" - #include "wx/combobox.h" - #include "wx/sizer.h" - #include "wx/stattext.h" - #include "wx/textctrl.h" -#endif - -#include "wx/statline.h" - -#include "wx/richtext/richtextimagedlg.h" -#include "wx/richtext/richtextctrl.h" - -////@begin XPM images -////@end XPM images - - -/*! - * wxRichTextImageDialog type definition - */ - -IMPLEMENT_DYNAMIC_CLASS( wxRichTextImageDialog, wxDialog ) - - -/*! - * wxRichTextImageDialog event table definition - */ - -BEGIN_EVENT_TABLE( wxRichTextImageDialog, wxDialog ) - -////@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 - -END_EVENT_TABLE() - - -/*! - * wxRichTextImageDialog constructors - */ - -wxRichTextImageDialog::wxRichTextImageDialog() -{ - Init(); -} - -wxRichTextImageDialog::wxRichTextImageDialog( wxWindow* parent, wxWindowID id, const wxString& caption, const wxPoint& pos, const wxSize& size, long style ) -{ - Init(); - Create(parent, id, caption, pos, size, style); -} - - -/*! - * wxRichTextImageDlg creator - */ - -bool wxRichTextImageDialog::Create( wxWindow* parent, wxWindowID id, const wxString& caption, const wxPoint& pos, const wxSize& size, long style ) -{ -////@begin wxRichTextImageDialog creation - SetExtraStyle(wxDIALOG_EX_CONTEXTHELP); - wxDialog::Create( parent, id, caption, pos, size, style ); - - CreateControls(); - if (GetSizer()) - { - GetSizer()->SetSizeHints(this); - } - Centre(); -////@end wxRichTextImageDialog creation - return true; -} - - -/*! - * wxRichTextImageDialog destructor - */ - -wxRichTextImageDialog::~wxRichTextImageDialog() -{ -////@begin wxRichTextImageDialog destruction -////@end wxRichTextImageDialog destruction -} - - -/*! - * Member initialisation - */ - -void wxRichTextImageDialog::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 -} - - -/*! - * Control creation for wxRichTextImageDlg - */ - -void wxRichTextImageDialog::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 -} - - -/*! - * Should we show tooltips? - */ - -bool wxRichTextImageDialog::ShowToolTips() -{ - return true; -} - -/*! - * Get bitmap resources - */ - -wxBitmap wxRichTextImageDialog::GetBitmapResource( const wxString& name ) -{ - // Bitmap retrieval -////@begin wxRichTextImageDialog bitmap retrieval - wxUnusedVar(name); - return wxNullBitmap; -////@end wxRichTextImageDialog bitmap retrieval -} - -/*! - * Get icon resources - */ - -wxIcon wxRichTextImageDialog::GetIconResource( const wxString& name ) -{ - // Icon retrieval -////@begin wxRichTextImageDialog icon retrieval - wxUnusedVar(name); - return wxNullIcon; -////@end wxRichTextImageDialog 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; -} - - -/*! - * wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_BUTTON_PARA_UP - */ -void wxRichTextImageDialog::OnRichtextimagedialogParaUpClick( wxCommandEvent& WXUNUSED(event)) -{ - // Before editing this code, remove the block markers. - wxRichTextRange range = m_image->GetRange(); - wxRichTextObjectList::compatibility_iterator iter = m_buffer->GetChildren().GetFirst(); - if (!iter) - return; - - while (iter) - { - if (iter->GetData() == m_parent) - break; - iter = iter->GetNext(); - } - - iter = iter->GetPrevious(); - if (!iter) - return; - - wxRichTextObject *obj = iter->GetData(); - wxRichTextRange rg = obj->GetRange(); - m_image = m_image->Clone(); - - m_buffer->DeleteRangeWithUndo(range, m_buffer->GetRichTextCtrl()); - m_buffer->InsertObjectWithUndo(rg.GetEnd(), m_image, m_buffer->GetRichTextCtrl(), 0); - m_parent = obj; - m_image->SetRange(wxRichTextRange(rg.GetEnd(), rg.GetEnd())); -} - - -/*! - * wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_BUTTON_PARA_DOWN - */ - -void wxRichTextImageDialog::OnRichtextimagedialogDownClick( wxCommandEvent& WXUNUSED(event)) -{ - // Before editing this code, remove the block markers. - wxRichTextRange range = m_image->GetRange(); - wxRichTextObjectList::compatibility_iterator iter = m_buffer->GetChildren().GetFirst(); - if (!iter) - return; - - while (iter) - { - if (iter->GetData() == m_parent) - break; - iter = iter->GetNext(); - } - - iter = iter->GetNext(); - if (!iter) - return; - - wxRichTextObject *obj = iter->GetData(); - wxRichTextRange rg = obj->GetRange(); - m_image = m_image->Clone(); - - m_buffer->DeleteRangeWithUndo(range, m_buffer->GetRichTextCtrl()); - m_buffer->InsertObjectWithUndo(rg.GetEnd(), m_image, m_buffer->GetRichTextCtrl(), 0); - m_parent = obj; - m_image->SetRange(wxRichTextRange(rg.GetEnd(), rg.GetEnd())); -} - -#endif +///////////////////////////////////////////////////////////////////////////// +// Name: src/richtext/richtextimagedlg.cpp +// Purpose: +// Author: Mingquan Yang +// Modified by: Julian Smart +// Created: Wed 02 Jun 2010 11:27:23 CST +// RCS-ID: +// Copyright: (c) Mingquan Yang, Julian Smart +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +// For compilers that support precompilation, includes "wx/wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#if wxUSE_RICHTEXT + +#ifndef WX_PRECOMP + #include "wx/button.h" + #include "wx/combobox.h" + #include "wx/sizer.h" + #include "wx/stattext.h" + #include "wx/textctrl.h" +#endif + +#include "wx/statline.h" + +#include "wx/richtext/richtextimagedlg.h" +#include "wx/richtext/richtextctrl.h" + +////@begin XPM images +////@end XPM images + + +/*! + * wxRichTextObjectPropertiesDialog type definition + */ + +IMPLEMENT_DYNAMIC_CLASS( wxRichTextObjectPropertiesDialog, wxRichTextFormattingDialog ) + + +/*! + * wxRichTextObjectPropertiesDialog event table definition + */ + +BEGIN_EVENT_TABLE( wxRichTextObjectPropertiesDialog, wxRichTextFormattingDialog ) + +////@begin wxRichTextObjectPropertiesDialog event table entries +////@end wxRichTextObjectPropertiesDialog event table entries + +END_EVENT_TABLE() + + +/*! + * wxRichTextObjectPropertiesDialog constructors + */ + +wxRichTextObjectPropertiesDialog::wxRichTextObjectPropertiesDialog() +{ + Init(); +} + +wxRichTextObjectPropertiesDialog::wxRichTextObjectPropertiesDialog( wxRichTextObject* obj, wxWindow* parent, wxWindowID id, const wxString& caption, const wxPoint& pos, const wxSize& size, long style ) +{ + Init(); + Create(obj, parent, id, caption, pos, size, style); +} + + +/*! + * wxRichTextImageDlg creator + */ + +bool wxRichTextObjectPropertiesDialog::Create( wxRichTextObject* obj, wxWindow* parent, wxWindowID id, const wxString& caption, const wxPoint& pos, const wxSize& size, long style ) +{ + SetObject(obj); + SetExtraStyle(wxDIALOG_EX_CONTEXTHELP); + long flags = wxRICHTEXT_FORMAT_SIZE|wxRICHTEXT_FORMAT_MARGINS|wxRICHTEXT_FORMAT_BORDERS|wxRICHTEXT_FORMAT_BACKGROUND; + wxRichTextFormattingDialog::Create( flags, parent, caption, id, pos, size, style ); + + CreateControls(); + + return true; +} + + +/*! + * wxRichTextObjectPropertiesDialog destructor + */ + +wxRichTextObjectPropertiesDialog::~wxRichTextObjectPropertiesDialog() +{ +////@begin wxRichTextObjectPropertiesDialog destruction +////@end wxRichTextObjectPropertiesDialog destruction +} + + +/*! + * Member initialisation + */ + +void wxRichTextObjectPropertiesDialog::Init() +{ +////@begin wxRichTextObjectPropertiesDialog member initialisation +////@end wxRichTextObjectPropertiesDialog member initialisation +} + + +/*! + * Control creation for wxRichTextImageDlg + */ + +void wxRichTextObjectPropertiesDialog::CreateControls() +{ +} + + +/*! + * Should we show tooltips? + */ + +bool wxRichTextObjectPropertiesDialog::ShowToolTips() +{ + return true; +} + +/*! + * Get bitmap resources + */ + +wxBitmap wxRichTextObjectPropertiesDialog::GetBitmapResource( const wxString& name ) +{ + // Bitmap retrieval +////@begin wxRichTextObjectPropertiesDialog bitmap retrieval + wxUnusedVar(name); + return wxNullBitmap; +////@end wxRichTextObjectPropertiesDialog bitmap retrieval +} + +/*! + * Get icon resources + */ + +wxIcon wxRichTextObjectPropertiesDialog::GetIconResource( const wxString& name ) +{ + // Icon retrieval +////@begin wxRichTextObjectPropertiesDialog icon retrieval + wxUnusedVar(name); + return wxNullIcon; +////@end wxRichTextObjectPropertiesDialog icon retrieval +} + +#if 0 +/*! + * wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_BUTTON_PARA_UP + */ +void wxRichTextObjectPropertiesDialog::OnRichtextParaUpClick( wxCommandEvent& WXUNUSED(event)) +{ + // Before editing this code, remove the block markers. + wxRichTextRange range = m_object->GetRange(); + wxRichTextObjectList::compatibility_iterator iter = m_buffer->GetChildren().GetFirst(); + if (!iter) + return; + + while (iter) + { + if (iter->GetData() == m_parent) + break; + iter = iter->GetNext(); + } + + iter = iter->GetPrevious(); + if (!iter) + return; + + wxRichTextObject *obj = iter->GetData(); + wxRichTextRange rg = obj->GetRange(); + m_object = m_object->Clone(); + + m_buffer->DeleteRangeWithUndo(range, m_buffer->GetRichTextCtrl()); + m_buffer->InsertObjectWithUndo(rg.GetEnd(), m_object, m_buffer->GetRichTextCtrl(), 0); + m_parent = obj; + m_object->SetRange(wxRichTextRange(rg.GetEnd(), rg.GetEnd())); +} + + +/*! + * wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_BUTTON_PARA_DOWN + */ + +void wxRichTextObjectPropertiesDialog::OnRichtextDownClick( wxCommandEvent& WXUNUSED(event)) +{ + // Before editing this code, remove the block markers. + wxRichTextRange range = m_object->GetRange(); + wxRichTextObjectList::compatibility_iterator iter = m_buffer->GetChildren().GetFirst(); + if (!iter) + return; + + while (iter) + { + if (iter->GetData() == m_parent) + break; + iter = iter->GetNext(); + } + + iter = iter->GetNext(); + if (!iter) + return; + + wxRichTextObject *obj = iter->GetData(); + wxRichTextRange rg = obj->GetRange(); + m_object = m_object->Clone(); + + m_buffer->DeleteRangeWithUndo(range, m_buffer->GetRichTextCtrl()); + m_buffer->InsertObjectWithUndo(rg.GetEnd(), m_object, m_buffer->GetRichTextCtrl(), 0); + m_parent = obj; + 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 2605a98..2caf0c6 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 ca89d66..914334e 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 0000000..c0d68e2 --- /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 2efffa4..9855d57 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(); + wxRichTextLineList::compatibility_iterator node2 = child->GetLines().GetFirst(); + while (node2) + { + 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 - yOffset; + bool hasHardPageBreak = ((node2 == child->GetLines().GetFirst()) && child->GetAttributes().HasPageBreak()); - 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 - // 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()) || hasHardPageBreak) + { + // New page starting at this line + int newY = rect.y; - if (((lineY + line->GetSize().y) > rect.GetBottom()) || - ((node2 == child->GetLines().GetFirst()) && child->GetAttributes().HasPageBreak())) - { - // New page starting at this line - int newY = rect.y; + // We increase the offset by the difference between new and old positions - // We increase the offset by the difference between new and old positions + int increaseOffsetBy = lineY - newY; + yOffset += increaseOffsetBy; - int increaseOffsetBy = lineY - newY; - yOffset += increaseOffsetBy; + if (!lastLine) + lastLine = line; - line->SetPosition(wxPoint(line->GetPosition().x, newY - child->GetPosition().y)); + m_pageBreaksStart.Add(lastStartPos); + m_pageBreaksEnd.Add(lastLine->GetAbsoluteRange().GetEnd()); + m_pageYOffsets.Add(yOffset); - if (!lastLine) + lastStartPos = line->GetAbsoluteRange().GetStart(); lastLine = line; - m_pageBreaksStart.Add(lastStartPos); - m_pageBreaksEnd.Add(lastLine->GetAbsoluteRange().GetEnd()); - - lastStartPos = line->GetAbsoluteRange().GetStart(); - - m_numPages ++; + 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); + } + } + + lastLine = line; + + 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); + + 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(); - GetRichTextBuffer()->Draw(*dc, rangeToDraw, wxRichTextRange(-1,-1), textRect, 0 /* descent */, wxRICHTEXT_DRAW_IGNORE_CACHE /* flags */); + 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 0000000..33a4b05 --- /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 0c66334..6979d66 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 5dde2fe..7dedcd1 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 649a2a1..af2c0f4 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 @@ -104,6 +105,20 @@ bool wxRichTextParagraphStyleDefinition::operator ==(const wxRichTextParagraphSt } /*! + * 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 c19891e..d26d641 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); - - itemBoxSizer20->Add(5, 5, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5); + m_stdButtonSizer = new wxStdDialogButtonSizer; - wxStdDialogButtonSizer* itemStdDialogButtonSizer22 = new wxStdDialogButtonSizer; + 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); - 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* itemButton22 = new wxButton( itemDialog1, wxID_CANCEL, _("Close"), wxDefaultPosition, wxDefaultSize, 0 ); + m_stdButtonSizer->AddButton(itemButton22); - wxButton* itemButton24 = new wxButton( itemDialog1, wxID_CANCEL, _("Close"), wxDefaultPosition, wxDefaultSize, 0 ); - itemStdDialogButtonSizer22->AddButton(itemButton24); + wxButton* itemButton23 = new wxButton( itemDialog1, wxID_HELP, _("&Help"), wxDefaultPosition, wxDefaultSize, 0 ); + m_stdButtonSizer->AddButton(itemButton23); - 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 7800668..2c433f9 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 54842f4..5f2f84c 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 -- 2.7.4