class WXDLLIMPEXP_RICHTEXT wxRichTextFileHandler;
class WXDLLIMPEXP_RICHTEXT wxRichTextStyleSheet;
class WXDLLIMPEXP_RICHTEXT wxTextAttrEx;
+class WXDLLIMPEXP_RICHTEXT wxRichTextListStyleDefinition;
/*!
* Flags determining the available space, passed to Layout
#define wxRICHTEXT_UNFORMATTED 0x02
/*!
- * Flags for SetStyle
+ * Flags for SetStyle/SetListStyle
*/
#define wxRICHTEXT_SETSTYLE_NONE 0x00
// preserved independently from that of e.g. a named paragraph style.
#define wxRICHTEXT_SETSTYLE_CHARACTERS_ONLY 0x08
+// For SetListStyle only: specifies starting from the given number, otherwise
+// deduces number from existing attributes
+#define wxRICHTEXT_SETSTYLE_RENUMBER 0x10
+
+// For SetListStyle only: specifies the list level for all paragraphs, otherwise
+// the current indentation will be used
+#define wxRICHTEXT_SETSTYLE_SPECIFY_LEVEL 0x20
+
/*!
* Flags for text insertion
*/
#define wxTEXT_ATTR_BULLET_STYLE 0x00010000
#define wxTEXT_ATTR_BULLET_NUMBER 0x00020000
#define wxTEXT_ATTR_BULLET_SYMBOL 0x00040000
+#define wxTEXT_ATTR_LIST_STYLE_NAME 0x00080000
/*!
* Styles for wxTextAttrEx::SetBulletStyle
wxTextAttrEx(const wxTextAttr& attr) { Init(); (*this) = attr; }
wxTextAttrEx() { Init(); }
- // Initialise this object.
+ // Initialise this object
void Init();
// Assignment from a wxTextAttrEx object
void operator= (const wxTextAttrEx& attr);
- // Assignment from a wxTextAttr object.
+ // Assignment from a wxTextAttr object
void operator= (const wxTextAttr& attr);
+ // Equality test
+ bool operator== (const wxTextAttrEx& attr) const;
+
// setters
void SetCharacterStyleName(const wxString& name) { m_characterStyleName = name; SetFlags(GetFlags() | wxTEXT_ATTR_CHARACTER_STYLE_NAME); }
void SetParagraphStyleName(const wxString& name) { m_paragraphStyleName = name; SetFlags(GetFlags() | wxTEXT_ATTR_PARAGRAPH_STYLE_NAME); }
+ void SetListStyleName(const wxString& name) { m_listStyleName = name; SetFlags(GetFlags() | wxTEXT_ATTR_LIST_STYLE_NAME); }
void SetParagraphSpacingAfter(int spacing) { m_paragraphSpacingAfter = spacing; SetFlags(GetFlags() | wxTEXT_ATTR_PARA_SPACING_AFTER); }
void SetParagraphSpacingBefore(int spacing) { m_paragraphSpacingBefore = spacing; SetFlags(GetFlags() | wxTEXT_ATTR_PARA_SPACING_BEFORE); }
void SetLineSpacing(int spacing) { m_lineSpacing = spacing; SetFlags(GetFlags() | wxTEXT_ATTR_LINE_SPACING); }
const wxString& GetCharacterStyleName() const { return m_characterStyleName; }
const wxString& GetParagraphStyleName() const { return m_paragraphStyleName; }
+ const wxString& GetListStyleName() const { return m_listStyleName; }
int GetParagraphSpacingAfter() const { return m_paragraphSpacingAfter; }
int GetParagraphSpacingBefore() const { return m_paragraphSpacingBefore; }
int GetLineSpacing() const { return m_lineSpacing; }
bool HasLineSpacing() const { return HasFlag(wxTEXT_ATTR_LINE_SPACING); }
bool HasCharacterStyleName() const { return HasFlag(wxTEXT_ATTR_CHARACTER_STYLE_NAME) || !m_characterStyleName.IsEmpty(); }
bool HasParagraphStyleName() const { return HasFlag(wxTEXT_ATTR_PARAGRAPH_STYLE_NAME) || !m_paragraphStyleName.IsEmpty(); }
+ bool HasListStyleName() const { return HasFlag(wxTEXT_ATTR_LIST_STYLE_NAME) || !m_listStyleName.IsEmpty(); }
bool HasBulletStyle() const { return HasFlag(wxTEXT_ATTR_BULLET_STYLE); }
bool HasBulletNumber() const { return HasFlag(wxTEXT_ATTR_BULLET_NUMBER); }
bool HasBulletSymbol() const { return HasFlag(wxTEXT_ATTR_BULLET_SYMBOL); }
return !HasTextColour() && !HasBackgroundColour() && !HasFont() && !HasAlignment() &&
!HasTabs() && !HasLeftIndent() && !HasRightIndent() &&
!HasParagraphSpacingAfter() && !HasParagraphSpacingBefore() && !HasLineSpacing() &&
- !HasCharacterStyleName() && !HasParagraphStyleName() && !HasBulletNumber() && !HasBulletStyle() && !HasBulletSymbol();
+ !HasCharacterStyleName() && !HasParagraphStyleName() && !HasListStyleName() &&
+ !HasBulletNumber() && !HasBulletStyle() && !HasBulletSymbol();
}
// return the attribute having the valid font and colours: it uses the
// Paragraph style
wxString m_paragraphStyleName;
+
+ // List style
+ wxString m_listStyleName;
};
/*!
void SetCharacterStyleName(const wxString& name) { m_characterStyleName = name; m_flags |= wxTEXT_ATTR_CHARACTER_STYLE_NAME; }
void SetParagraphStyleName(const wxString& name) { m_paragraphStyleName = name; m_flags |= wxTEXT_ATTR_PARAGRAPH_STYLE_NAME; }
+ void SetListStyleName(const wxString& name) { m_listStyleName = name; SetFlags(GetFlags() | wxTEXT_ATTR_LIST_STYLE_NAME); }
void SetParagraphSpacingAfter(int spacing) { m_paragraphSpacingAfter = spacing; m_flags |= wxTEXT_ATTR_PARA_SPACING_AFTER; }
void SetParagraphSpacingBefore(int spacing) { m_paragraphSpacingBefore = spacing; m_flags |= wxTEXT_ATTR_PARA_SPACING_BEFORE; }
void SetLineSpacing(int spacing) { m_lineSpacing = spacing; m_flags |= wxTEXT_ATTR_LINE_SPACING; }
const wxString& GetCharacterStyleName() const { return m_characterStyleName; }
const wxString& GetParagraphStyleName() const { return m_paragraphStyleName; }
+ const wxString& GetListStyleName() const { return m_listStyleName; }
int GetParagraphSpacingAfter() const { return m_paragraphSpacingAfter; }
int GetParagraphSpacingBefore() const { return m_paragraphSpacingBefore; }
int GetLineSpacing() const { return m_lineSpacing; }
bool HasLineSpacing() const { return (m_flags & wxTEXT_ATTR_LINE_SPACING) != 0; }
bool HasCharacterStyleName() const { return (m_flags & wxTEXT_ATTR_CHARACTER_STYLE_NAME) != 0 || !m_characterStyleName.IsEmpty(); }
bool HasParagraphStyleName() const { return (m_flags & wxTEXT_ATTR_PARAGRAPH_STYLE_NAME) != 0 || !m_paragraphStyleName.IsEmpty(); }
+ bool HasListStyleName() const { return HasFlag(wxTEXT_ATTR_LIST_STYLE_NAME) || !m_listStyleName.IsEmpty(); }
bool HasBulletStyle() const { return (m_flags & wxTEXT_ATTR_BULLET_STYLE) != 0; }
bool HasBulletNumber() const { return (m_flags & wxTEXT_ATTR_BULLET_NUMBER) != 0; }
bool HasBulletSymbol() const { return (m_flags & wxTEXT_ATTR_BULLET_SYMBOL) != 0; }
return !HasTextColour() && !HasBackgroundColour() && !HasFont() && !HasAlignment() &&
!HasTabs() && !HasLeftIndent() && !HasRightIndent() &&
!HasParagraphSpacingAfter() && !HasParagraphSpacingBefore() && !HasLineSpacing() &&
- !HasCharacterStyleName() && !HasParagraphStyleName() && !HasBulletNumber() && !HasBulletStyle() && !HasBulletSymbol();
+ !HasCharacterStyleName() && !HasParagraphStyleName() && !HasListStyleName() &&
+ !HasBulletNumber() && !HasBulletStyle() && !HasBulletSymbol();
}
// return the attribute having the valid font and colours: it uses the
// Paragraph style
wxString m_paragraphStyleName;
+
+ // List style
+ wxString m_listStyleName;
};
#define wxTEXT_ATTR_CHARACTER (wxTEXT_ATTR_FONT | wxTEXT_ATTR_BACKGROUND_COLOUR | wxTEXT_ATTR_TEXT_COLOUR | wxTEXT_ATTR_CHARACTER_STYLE_NAME)
#define wxTEXT_ATTR_PARAGRAPH (wxTEXT_ATTR_ALIGNMENT|wxTEXT_ATTR_LEFT_INDENT|wxTEXT_ATTR_RIGHT_INDENT|wxTEXT_ATTR_TABS|\
wxTEXT_ATTR_PARA_SPACING_BEFORE|wxTEXT_ATTR_PARA_SPACING_AFTER|wxTEXT_ATTR_LINE_SPACING|\
- wxTEXT_ATTR_BULLET_STYLE|wxTEXT_ATTR_BULLET_NUMBER|wxTEXT_ATTR_BULLET_SYMBOL|wxTEXT_ATTR_PARAGRAPH_STYLE_NAME)
+ wxTEXT_ATTR_BULLET_STYLE|wxTEXT_ATTR_BULLET_NUMBER|wxTEXT_ATTR_BULLET_SYMBOL|wxTEXT_ATTR_PARAGRAPH_STYLE_NAME|wxTEXT_ATTR_LIST_STYLE_NAME)
#define wxTEXT_ATTR_ALL (wxTEXT_ATTR_CHARACTER|wxTEXT_ATTR_PARAGRAPH)
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; }
+
// Operations
/// Initialize the object.
/// content.
bool CollectStyle(wxTextAttrEx& currentStyle, const wxTextAttrEx& style, long& multipleStyleAttributes);
+ /// Set list style
+ virtual bool SetListStyle(const wxRichTextRange& range, wxRichTextListStyleDefinition* def, int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO, int startFrom = 1, int specifiedLevel = -1);
+ virtual bool SetListStyle(const wxRichTextRange& range, const wxString& defName, int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO, int startFrom = 1, int specifiedLevel = -1);
+
+ /// Clear list for given range
+ virtual bool ClearListStyle(const wxRichTextRange& range, int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO);
+
+ /// Number/renumber any list elements in the given range.
+ /// def/defName can be NULL/empty to indicate that the existing list style should be used.
+ virtual bool NumberList(const wxRichTextRange& range, wxRichTextListStyleDefinition* def, int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO, int startFrom = 1, int specifiedLevel = -1);
+ virtual bool NumberList(const wxRichTextRange& range, const wxString& defName, int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO, int startFrom = 1, int specifiedLevel = -1);
+
+ /// Promote the list items within the given range. promoteBy can be a positive or negative number, e.g. 1 or -1
+ /// def/defName can be NULL/empty to indicate that the existing list style should be used.
+ virtual bool PromoteList(int promoteBy, const wxRichTextRange& range, wxRichTextListStyleDefinition* def, int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO, int specifiedLevel = -1);
+ virtual bool PromoteList(int promoteBy, const wxRichTextRange& range, const wxString& defName, int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO, int specifiedLevel = -1);
+
+ /// Helper for NumberList and PromoteList, that does renumbering and promotion simultaneously
+ /// def/defName can be NULL/empty to indicate that the existing list style should be used.
+ virtual bool DoNumberList(const wxRichTextRange& range, const wxRichTextRange& promotionRange, int promoteBy, wxRichTextListStyleDefinition* def, int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO, int startFrom = 1, int specifiedLevel = -1);
+
/// Test if this whole range has character attributes of the specified kind. If any
/// of the attributes are different within the range, the test fails. You
/// can use this to implement, for example, bold button updating. style must have
/// Set style sheet, if any.
void SetStyleSheet(wxRichTextStyleSheet* styleSheet) { m_styleSheet = styleSheet; }
- wxRichTextStyleSheet* GetStyleSheet() const { return m_styleSheet; }
+ virtual wxRichTextStyleSheet* GetStyleSheet() const { return m_styleSheet; }
+
+ /// Push style sheet to top of stack
+ bool PushStyleSheet(wxRichTextStyleSheet* styleSheet);
+
+ /// Pop style sheet from top of stack
+ wxRichTextStyleSheet* PopStyleSheet();
// Operations
virtual const wxTextAttrEx& GetDefaultStyleEx() const;
virtual const wxTextAttr& GetDefaultStyle() const;
+ /// Set list style
+ virtual bool SetListStyle(const wxRichTextRange& range, wxRichTextListStyleDefinition* def, int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO, int startFrom = 1, int specifiedLevel = -1);
+ virtual bool SetListStyle(const wxRichTextRange& range, const wxString& defName, int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO, int startFrom = 1, int specifiedLevel = -1);
+
+ /// Clear list for given range
+ virtual bool ClearListStyle(const wxRichTextRange& range, int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO);
+
+ /// Number/renumber any list elements in the given range
+ /// def/defName can be NULL/empty to indicate that the existing list style should be used.
+ virtual bool NumberList(const wxRichTextRange& range, wxRichTextListStyleDefinition* def, int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO, int startFrom = 1, int specifiedLevel = -1);
+ virtual bool NumberList(const wxRichTextRange& range, const wxString& defName, int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO, int startFrom = 1, int specifiedLevel = -1);
+
+ /// Promote the list items within the given range. promoteBy can be a positive or negative number, e.g. 1 or -1
+ /// def/defName can be NULL/empty to indicate that the existing list style should be used.
+ virtual bool PromoteList(int promoteBy, const wxRichTextRange& range, wxRichTextListStyleDefinition* def, int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO, int specifiedLevel = -1);
+ virtual bool PromoteList(int promoteBy, const wxRichTextRange& range, const wxString& defName, int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO, int specifiedLevel = -1);
+
// translate between the position (which is just an index in the text ctrl
// considering all its contents as a single strings) and (x, y) coordinates
// which represent column and line.
/// Apply a named style to the selection
virtual bool ApplyStyle(wxRichTextStyleDefinition* def);
- /// Set style sheet, if any.
+ /// Set style sheet, if any
void SetStyleSheet(wxRichTextStyleSheet* styleSheet) { GetBuffer().SetStyleSheet(styleSheet); }
wxRichTextStyleSheet* GetStyleSheet() const { return GetBuffer().GetStyleSheet(); }
+ /// Push style sheet to top of stack
+ bool PushStyleSheet(wxRichTextStyleSheet* styleSheet) { return GetBuffer().PushStyleSheet(styleSheet); }
+
+ /// Pop style sheet from top of stack
+ wxRichTextStyleSheet* PopStyleSheet() { return GetBuffer().PopStyleSheet(); }
+
/// Apply the style sheet to the buffer, for example if the styles have changed.
bool ApplyStyleSheet(wxRichTextStyleSheet* styleSheet = NULL);
#include "wx/combo.h"
#endif
+#include "wx/choice.h"
+
/*!
* Forward declarations
*/
DECLARE_CLASS(wxRichTextStyleDefinition)
public:
-// Constructors
-
+ /// Copy constructors
wxRichTextStyleDefinition(const wxRichTextStyleDefinition& def)
: wxObject()
{
+ Init();
Copy(def);
}
+
+ /// Default constructor
wxRichTextStyleDefinition(const wxString& name = wxEmptyString) { Init(); m_name = name; }
+
+ /// Destructor
virtual ~wxRichTextStyleDefinition() {}
+ /// Initialises members
void Init() {}
+
+ /// Copies from def
void Copy(const wxRichTextStyleDefinition& def);
+
+ /// Equality test
bool Eq(const wxRichTextStyleDefinition& def) const;
+
+ /// Assignment operator
void operator =(const wxRichTextStyleDefinition& def) { Copy(def); }
+
+ /// Equality operator
bool operator ==(const wxRichTextStyleDefinition& def) const { return Eq(def); }
+
+ /// Override to clone the object
virtual wxRichTextStyleDefinition* Clone() const = 0;
- /// The name of the style.
+ /// Sets and gets the name of the style
void SetName(const wxString& name) { m_name = name; }
const wxString& GetName() const { return m_name; }
- /// The name of the style that this style is based on.
+ /// Sets and gets the name of the style that this style is based on
void SetBaseStyle(const wxString& name) { m_baseStyle = name; }
const wxString& GetBaseStyle() const { return m_baseStyle; }
- /// The style.
+ /// Sets the style
void SetStyle(const wxRichTextAttr& style) { m_style = style; }
const wxRichTextAttr& GetStyle() const { return m_style; }
wxRichTextAttr& GetStyle() { return m_style; }
DECLARE_DYNAMIC_CLASS(wxRichTextCharacterStyleDefinition)
public:
-// Constructors
-
+ /// Copy constructor
wxRichTextCharacterStyleDefinition(const wxRichTextCharacterStyleDefinition& def): wxRichTextStyleDefinition(def) {}
+
+ /// Default constructor
wxRichTextCharacterStyleDefinition(const wxString& name = wxEmptyString):
wxRichTextStyleDefinition(name) {}
+
+ /// Destructor
virtual ~wxRichTextCharacterStyleDefinition() {}
+ /// Clones the object
virtual wxRichTextStyleDefinition* Clone() const { return new wxRichTextCharacterStyleDefinition(*this); }
protected:
DECLARE_DYNAMIC_CLASS(wxRichTextParagraphStyleDefinition)
public:
-// Constructors
-
+ /// Copy constructor
wxRichTextParagraphStyleDefinition(const wxRichTextParagraphStyleDefinition& def): wxRichTextStyleDefinition(def) { m_nextStyle = def.m_nextStyle; }
+
+ /// Default constructor
wxRichTextParagraphStyleDefinition(const wxString& name = wxEmptyString):
wxRichTextStyleDefinition(name) {}
+
+ // Destructor
virtual ~wxRichTextParagraphStyleDefinition() {}
- /// The next style.
+ /// Sets and gets the next style
void SetNextStyle(const wxString& name) { m_nextStyle = name; }
const wxString& GetNextStyle() const { return m_nextStyle; }
+ /// Copies from def
void Copy(const wxRichTextParagraphStyleDefinition& def);
+
+ /// Assignment operator
void operator =(const wxRichTextParagraphStyleDefinition& def) { Copy(def); }
+
+ /// Equality operator
bool operator ==(const wxRichTextParagraphStyleDefinition& def) const;
+ /// Clones the object
virtual wxRichTextStyleDefinition* Clone() const { return new wxRichTextParagraphStyleDefinition(*this); }
protected:
wxString m_nextStyle;
};
+/*!
+ * wxRichTextListStyleDefinition class declaration
+ */
+
+class WXDLLIMPEXP_RICHTEXT wxRichTextListStyleDefinition: public wxRichTextParagraphStyleDefinition
+{
+ DECLARE_DYNAMIC_CLASS(wxRichTextListStyleDefinition)
+public:
+
+ /// Copy constructor
+ wxRichTextListStyleDefinition(const wxRichTextListStyleDefinition& def): wxRichTextParagraphStyleDefinition(def) { Init(); Copy(def); }
+
+ /// Default constructor
+ wxRichTextListStyleDefinition(const wxString& name = wxEmptyString):
+ wxRichTextParagraphStyleDefinition(name) { Init(); }
+
+ /// Destructor
+ virtual ~wxRichTextListStyleDefinition() {}
+
+ /// Copies from def
+ void Copy(const wxRichTextListStyleDefinition& def);
+
+ /// Assignment operator
+ void operator =(const wxRichTextListStyleDefinition& def) { Copy(def); }
+
+ /// Equality operator
+ bool operator ==(const wxRichTextListStyleDefinition& def) const;
+
+ /// Clones the object
+ virtual wxRichTextStyleDefinition* Clone() const { return new wxRichTextListStyleDefinition(*this); }
+
+ /// Sets/gets the attributes for the given level
+ void SetLevelAttributes(int i, const wxTextAttrEx& attr);
+ wxTextAttrEx* GetLevelAttributes(int i);
+ const wxTextAttrEx* GetLevelAttributes(int i) const;
+
+ /// Convenience function for setting the major attributes for a list level specification
+ void SetAttributes(int i, int leftIndent, int leftSubIndent, int bulletStyle, const wxString& bulletSymbol = wxEmptyString);
+
+ /// Finds the level corresponding to the given indentation
+ int FindLevelForIndent(int indent) const;
+
+ /// Combine the base and list style with a paragraph style, using the given indent (from which
+ /// an appropriate level is found)
+ wxTextAttrEx CombineWithParagraphStyle(int indent, const wxTextAttrEx& paraStyle);
+
+ /// Combine the base and list style, using the given indent (from which
+ /// an appropriate level is found)
+ wxTextAttrEx GetCombinedStyle(int indent);
+
+ /// Combine the base and list style, using the given level from which
+ /// an appropriate level is found)
+ wxTextAttrEx GetCombinedStyleForLevel(int level);
+
+ /// Gets the number of available levels
+ int GetLevelCount() const { return 10; }
+
+ /// Is this a numbered list?
+ bool IsNumbered(int i) const;
+
+protected:
+
+ /// The styles for each level (up to 10)
+ wxTextAttrEx m_levelStyles[10];
+};
+
/*!
* The style sheet
*/
Copy(sheet);
}
wxRichTextStyleSheet() { Init(); }
- virtual ~wxRichTextStyleSheet() { DeleteStyles(); }
+ virtual ~wxRichTextStyleSheet();
/// Initialisation
void Init();
/// Add a definition to the paragraph style list
bool AddParagraphStyle(wxRichTextParagraphStyleDefinition* def);
+ /// Add a definition to the list style list
+ bool AddListStyle(wxRichTextListStyleDefinition* def);
+
/// Remove a character style
bool RemoveCharacterStyle(wxRichTextStyleDefinition* def, bool deleteStyle = false) { return RemoveStyle(m_characterStyleDefinitions, def, deleteStyle); }
/// Remove a paragraph style
bool RemoveParagraphStyle(wxRichTextStyleDefinition* def, bool deleteStyle = false) { return RemoveStyle(m_paragraphStyleDefinitions, def, deleteStyle); }
+ /// Remove a list style
+ bool RemoveListStyle(wxRichTextStyleDefinition* def, bool deleteStyle = false) { return RemoveStyle(m_listStyleDefinitions, def, deleteStyle); }
+
/// Find a character definition by name
- wxRichTextCharacterStyleDefinition* FindCharacterStyle(const wxString& name) const { return (wxRichTextCharacterStyleDefinition*) FindStyle(m_characterStyleDefinitions, name); }
+ wxRichTextCharacterStyleDefinition* FindCharacterStyle(const wxString& name, bool recurse = true) const { return (wxRichTextCharacterStyleDefinition*) FindStyle(m_characterStyleDefinitions, name, recurse); }
/// Find a paragraph definition by name
- wxRichTextParagraphStyleDefinition* FindParagraphStyle(const wxString& name) const { return (wxRichTextParagraphStyleDefinition*) FindStyle(m_paragraphStyleDefinitions, name); }
+ wxRichTextParagraphStyleDefinition* FindParagraphStyle(const wxString& name, bool recurse = true) const { return (wxRichTextParagraphStyleDefinition*) FindStyle(m_paragraphStyleDefinitions, name, recurse); }
- /// Return the number of character styes.
+ /// Find a list definition by name
+ wxRichTextListStyleDefinition* FindListStyle(const wxString& name, bool recurse = true) const { return (wxRichTextListStyleDefinition*) FindStyle(m_listStyleDefinitions, name, recurse); }
+
+ /// Return the number of character styles
size_t GetCharacterStyleCount() const { return m_characterStyleDefinitions.GetCount(); }
- /// Return the number of paragraph styes.
+ /// Return the number of paragraph styles
size_t GetParagraphStyleCount() const { return m_paragraphStyleDefinitions.GetCount(); }
+ /// Return the number of list styles
+ size_t GetListStyleCount() const { return m_listStyleDefinitions.GetCount(); }
+
/// Return the nth character style
wxRichTextCharacterStyleDefinition* GetCharacterStyle(size_t n) const { return (wxRichTextCharacterStyleDefinition*) m_characterStyleDefinitions.Item(n)->GetData(); }
/// Return the nth paragraph style
wxRichTextParagraphStyleDefinition* GetParagraphStyle(size_t n) const { return (wxRichTextParagraphStyleDefinition*) m_paragraphStyleDefinitions.Item(n)->GetData(); }
+ /// Return the nth list style
+ wxRichTextListStyleDefinition* GetListStyle(size_t n) const { return (wxRichTextListStyleDefinition*) m_listStyleDefinitions.Item(n)->GetData(); }
+
/// Delete all styles
void DeleteStyles();
+ /// Insert into list of style sheets
+ bool InsertSheet(wxRichTextStyleSheet* before);
+
+ /// Append to list of style sheets
+ bool AppendSheet(wxRichTextStyleSheet* after);
+
+ /// Unlink from the list of style sheets
+ void Unlink();
+
+ /// Get/set next sheet
+ wxRichTextStyleSheet* GetNextSheet() const { return m_nextSheet; }
+ void SetNextSheet(wxRichTextStyleSheet* sheet) { m_nextSheet = sheet; }
+
+ /// Get/set previous sheet
+ wxRichTextStyleSheet* GetPreviousSheet() const { return m_previousSheet; }
+ void SetPreviousSheet(wxRichTextStyleSheet* sheet) { m_previousSheet = sheet; }
+
/// Implementation
/// Add a definition to one of the style lists
bool RemoveStyle(wxList& list, wxRichTextStyleDefinition* def, bool deleteStyle);
/// Find a definition by name
- wxRichTextStyleDefinition* FindStyle(const wxList& list, const wxString& name) const;
+ wxRichTextStyleDefinition* FindStyle(const wxList& list, const wxString& name, bool recurse = true) const;
protected:
wxList m_characterStyleDefinitions;
wxList m_paragraphStyleDefinitions;
+ wxList m_listStyleDefinitions;
+
+ wxRichTextStyleSheet* m_previousSheet;
+ wxRichTextStyleSheet* m_nextSheet;
};
#if wxUSE_HTML
DECLARE_EVENT_TABLE()
public:
+ /// Which type of style definition is currently showing?
+ enum wxRichTextStyleType
+ {
+ wxRICHTEXT_STYLE_ALL,
+ wxRICHTEXT_STYLE_PARAGRAPH,
+ wxRICHTEXT_STYLE_CHARACTER,
+ wxRICHTEXT_STYLE_LIST
+ };
+
wxRichTextStyleListBox()
{
Init();
{
m_styleSheet = NULL;
m_richTextCtrl = NULL;
- m_applyOnSelection = true;
+ m_applyOnSelection = false;
+ m_styleType = wxRICHTEXT_STYLE_PARAGRAPH;
}
bool Create(wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition,
/// Left click
void OnLeftDown(wxMouseEvent& event);
+ /// Left double-click
+ void OnLeftDoubleClick(wxMouseEvent& event);
+
/// Auto-select from style under caret in idle time
void OnIdle(wxIdleEvent& event);
-#if 0
- virtual wxColour GetSelectedTextColour(const wxColour& colFg) const;
- virtual wxColour GetSelectedTextBgColour(const wxColour& colBg) const;
-#endif
-
/// Convert units in tends of a millimetre to device units
int ConvertTenthsMMToPixels(wxDC& dc, int units) const;
void SetApplyOnSelection(bool applyOnSel) { m_applyOnSelection = applyOnSel; }
bool GetApplyOnSelection() const { return m_applyOnSelection; }
+ /// Set the style type to display
+ void SetStyleType(wxRichTextStyleType styleType) { m_styleType = styleType; UpdateStyles(); }
+ wxRichTextStyleType GetStyleType() const { return m_styleType; }
+
+ /// Helper for listbox and combo control
+ static wxString GetStyleToShowInIdleTime(wxRichTextCtrl* ctrl, wxRichTextStyleType styleType);
+
protected:
/// Returns the HTML for this item
virtual wxString OnGetItem(size_t n) const;
wxRichTextStyleSheet* m_styleSheet;
wxRichTextCtrl* m_richTextCtrl;
bool m_applyOnSelection; // if true, applies style on selection
+ wxRichTextStyleType m_styleType; // style type to display
+};
+
+/*!
+ * wxRichTextStyleListCtrl class declaration
+ * This is a container for the list control plus a combobox to switch between
+ * style types.
+ */
+
+class WXDLLIMPEXP_RICHTEXT wxRichTextStyleListCtrl: public wxControl
+{
+ DECLARE_CLASS(wxRichTextStyleListCtrl)
+ DECLARE_EVENT_TABLE()
+
+public:
+
+ /// Constructors
+ wxRichTextStyleListCtrl()
+ {
+ Init();
+ }
+
+ wxRichTextStyleListCtrl(wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition,
+ const wxSize& size = wxDefaultSize, long style = 0);
+
+ /// Constructors
+ virtual ~wxRichTextStyleListCtrl();
+
+ /// Member initialisation
+ void Init()
+ {
+ m_styleListBox = NULL;
+ m_styleChoice = NULL;
+ m_dontUpdate = false;
+ }
+
+ /// Creates the windows
+ bool Create(wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition,
+ const wxSize& size = wxDefaultSize, long style = 0);
+
+ /// Associates the control with a style manager
+ void SetStyleSheet(wxRichTextStyleSheet* styleSheet);
+ wxRichTextStyleSheet* GetStyleSheet() const;
+
+ /// Associates the control with a wxRichTextCtrl
+ void SetRichTextCtrl(wxRichTextCtrl* ctrl);
+ wxRichTextCtrl* GetRichTextCtrl() const;
+
+ /// Updates the style list box
+ void UpdateStyles();
+
+ /// Set/get the style type to display
+ void SetStyleType(wxRichTextStyleListBox::wxRichTextStyleType styleType);
+ wxRichTextStyleListBox::wxRichTextStyleType GetStyleType() const;
+
+ /// Get the choice index for style type
+ int StyleTypeToIndex(wxRichTextStyleListBox::wxRichTextStyleType styleType);
+
+ /// Get the style type for choice index
+ wxRichTextStyleListBox::wxRichTextStyleType StyleIndexToType(int i);
+
+ /// Get the listbox
+ wxRichTextStyleListBox* GetStyleListBox() const { return m_styleListBox; }
+
+ /// Get the choice
+ wxChoice* GetStyleChoice() const { return m_styleChoice; }
+
+ /// React to style type choice
+ void OnChooseType(wxCommandEvent& event);
+
+ /// Lay out the controls
+ void OnSize(wxSizeEvent& event);
+
+private:
+
+ wxRichTextStyleListBox* m_styleListBox;
+ wxChoice* m_styleChoice;
+ bool m_dontUpdate;
};
#if wxUSE_COMBOCTRL
}
else
newPara = para;
-
+
if (paragraphStyle && !charactersOnly)
{
if (applyMinimal)
currentStyle.SetParagraphStyleName(style.GetParagraphStyleName());
}
+ if (style.HasListStyleName() && !wxHasStyle(multipleStyleAttributes, wxTEXT_ATTR_LIST_STYLE_NAME))
+ {
+ if (currentStyle.HasListStyleName())
+ {
+ if (currentStyle.HasListStyleName() != style.HasListStyleName())
+ {
+ // Clash of style - mark as such
+ multipleStyleAttributes |= wxTEXT_ATTR_LIST_STYLE_NAME;
+ currentStyle.SetFlags(currentStyle.GetFlags() & ~wxTEXT_ATTR_LIST_STYLE_NAME);
+ }
+ }
+ else
+ currentStyle.SetListStyleName(style.GetListStyleName());
+ }
+
if (style.HasBulletStyle() && !wxHasStyle(multipleStyleAttributes, wxTEXT_ATTR_BULLET_STYLE))
{
if (currentStyle.HasBulletStyle())
if (para)
{
- if (!para->GetAttributes().GetParagraphStyleName().IsEmpty())
+ // Combine paragraph and list styles. If there is a list style in the original attributes,
+ // the current indentation overrides anything else and is used to find the item indentation.
+ // Also, for applying paragraph styles, consider having 2 modes: (1) we merge with what we have,
+ // thereby taking into account all user changes, (2) reset the style completely (except for indentation/list
+ // exception as above).
+ // Problem: when changing from one list style to another, there's a danger that the level info will get lost.
+ // So when changing a list style interactively, could retrieve level based on current style, then
+ // set appropriate indent and apply new style.
+
+ if (!para->GetAttributes().GetParagraphStyleName().IsEmpty() && !para->GetAttributes().GetListStyleName().IsEmpty())
+ {
+ int currentIndent = para->GetAttributes().GetLeftIndent();
+
+ wxRichTextParagraphStyleDefinition* paraDef = styleSheet->FindParagraphStyle(para->GetAttributes().GetParagraphStyleName());
+ wxRichTextListStyleDefinition* listDef = styleSheet->FindListStyle(para->GetAttributes().GetListStyleName());
+ if (paraDef && !listDef)
+ {
+ para->GetAttributes() = paraDef->GetStyle();
+ foundCount ++;
+ }
+ else if (listDef && !paraDef)
+ {
+ // Set overall style defined for the list style definition
+ para->GetAttributes() = listDef->GetStyle();
+
+ // Apply the style for this level
+ wxRichTextApplyStyle(para->GetAttributes(), * listDef->GetLevelAttributes(listDef->FindLevelForIndent(currentIndent)));
+ foundCount ++;
+ }
+ else if (listDef && paraDef)
+ {
+ // Combines overall list style, style for level, and paragraph style
+ para->GetAttributes() = listDef->CombineWithParagraphStyle(currentIndent, paraDef->GetStyle());
+ foundCount ++;
+ }
+ }
+ else if (para->GetAttributes().GetParagraphStyleName().IsEmpty() && !para->GetAttributes().GetListStyleName().IsEmpty())
+ {
+ int currentIndent = para->GetAttributes().GetLeftIndent();
+
+ wxRichTextListStyleDefinition* listDef = styleSheet->FindListStyle(para->GetAttributes().GetListStyleName());
+
+ // Overall list definition style
+ para->GetAttributes() = listDef->GetStyle();
+
+ // Style for this level
+ wxRichTextApplyStyle(para->GetAttributes(), * listDef->GetLevelAttributes(listDef->FindLevelForIndent(currentIndent)));
+
+ foundCount ++;
+ }
+ else if (!para->GetAttributes().GetParagraphStyleName().IsEmpty() && para->GetAttributes().GetListStyleName().IsEmpty())
{
wxRichTextParagraphStyleDefinition* def = styleSheet->FindParagraphStyle(para->GetAttributes().GetParagraphStyleName());
if (def)
return foundCount != 0;
}
+/// Set list style
+bool wxRichTextParagraphLayoutBox::SetListStyle(const wxRichTextRange& range, wxRichTextListStyleDefinition* def, int flags, int startFrom, int specifiedLevel)
+{
+ bool withUndo = ((flags & wxRICHTEXT_SETSTYLE_WITH_UNDO) != 0);
+ // bool applyMinimal = ((flags & wxRICHTEXT_SETSTYLE_OPTIMIZE) != 0);
+ bool specifyLevel = ((flags & wxRICHTEXT_SETSTYLE_SPECIFY_LEVEL) != 0);
+ bool renumber = ((flags & wxRICHTEXT_SETSTYLE_RENUMBER) != 0);
+
+ // Current number, if numbering
+ int n = startFrom;
+
+ wxASSERT (!specifyLevel || (specifyLevel && (specifiedLevel >= 0)));
+
+ // If we are associated with a control, make undoable; otherwise, apply immediately
+ // to the data.
+
+ bool haveControl = (GetRichTextCtrl() != NULL);
+
+ wxRichTextAction* action = NULL;
+
+ if (haveControl && withUndo)
+ {
+ action = new wxRichTextAction(NULL, _("Change List Style"), wxRICHTEXT_CHANGE_STYLE, & GetRichTextCtrl()->GetBuffer(), GetRichTextCtrl());
+ action->SetRange(range);
+ action->SetPosition(GetRichTextCtrl()->GetCaretPosition());
+ }
+
+ wxRichTextObjectList::compatibility_iterator node = m_children.GetFirst();
+ while (node)
+ {
+ wxRichTextParagraph* para = wxDynamicCast(node->GetData(), wxRichTextParagraph);
+ wxASSERT (para != NULL);
+
+ if (para && para->GetChildCount() > 0)
+ {
+ // Stop searching if we're beyond the range of interest
+ if (para->GetRange().GetStart() > range.GetEnd())
+ break;
+
+ if (!para->GetRange().IsOutside(range))
+ {
+ // We'll be using a copy of the paragraph to make style changes,
+ // not updating the buffer directly.
+ wxRichTextParagraph* newPara wxDUMMY_INITIALIZE(NULL);
+
+ if (haveControl && withUndo)
+ {
+ newPara = new wxRichTextParagraph(*para);
+ action->GetNewParagraphs().AppendChild(newPara);
+
+ // Also store the old ones for Undo
+ action->GetOldParagraphs().AppendChild(new wxRichTextParagraph(*para));
+ }
+ else
+ newPara = para;
+
+ if (def)
+ {
+ int thisIndent = newPara->GetAttributes().GetLeftIndent();
+ int thisLevel = specifyLevel ? specifiedLevel : def->FindLevelForIndent(thisIndent);
+
+ // How is numbering going to work?
+ // If we are renumbering, or numbering for the first time, we need to keep
+ // track of the number for each level. But we might be simply applying a different
+ // list style.
+ // In Word, applying a style to several paragraphs, even if at different levels,
+ // reverts the level back to the same one. So we could do the same here.
+ // Renumbering will need to be done when we promote/demote a paragraph.
+
+ // Apply the overall list style, and item style for this level
+ wxTextAttrEx listStyle(def->GetCombinedStyleForLevel(thisLevel));
+ wxRichTextApplyStyle(newPara->GetAttributes(), listStyle);
+
+ // Now we need to check numbering
+ if (renumber)
+ {
+ newPara->GetAttributes().SetBulletNumber(n);
+ }
+
+ n ++;
+ }
+ else if (!newPara->GetAttributes().GetListStyleName().IsEmpty())
+ {
+ // if def is NULL, remove list style, applying any associated paragraph style
+ // to restore the attributes
+
+ newPara->GetAttributes().SetListStyleName(wxEmptyString);
+ newPara->GetAttributes().SetLeftIndent(0, 0);
+
+ // Eliminate the main list-related attributes
+ newPara->GetAttributes().SetFlags(newPara->GetAttributes().GetFlags() & ~wxTEXT_ATTR_LEFT_INDENT & ~wxTEXT_ATTR_BULLET_STYLE & ~wxTEXT_ATTR_BULLET_NUMBER & ~wxTEXT_ATTR_BULLET_SYMBOL & wxTEXT_ATTR_LIST_STYLE_NAME);
+
+ wxRichTextStyleSheet* styleSheet = GetStyleSheet();
+ if (styleSheet && !newPara->GetAttributes().GetParagraphStyleName().IsEmpty())
+ {
+ wxRichTextParagraphStyleDefinition* def = styleSheet->FindParagraphStyle(newPara->GetAttributes().GetParagraphStyleName());
+ if (def)
+ {
+ newPara->GetAttributes() = def->GetStyle();
+ }
+ }
+ }
+ }
+ }
+
+ node = node->GetNext();
+ }
+
+ // Do action, or delay it until end of batch.
+ if (haveControl && withUndo)
+ GetRichTextCtrl()->GetBuffer().SubmitAction(action);
+
+ return true;
+}
+
+bool wxRichTextParagraphLayoutBox::SetListStyle(const wxRichTextRange& range, const wxString& defName, int flags, int startFrom, int specifiedLevel)
+{
+ if (GetStyleSheet())
+ {
+ wxRichTextListStyleDefinition* def = GetStyleSheet()->FindListStyle(defName);
+ if (def)
+ return SetListStyle(range, def, flags, startFrom, specifiedLevel);
+ }
+ return false;
+}
+
+/// Clear list for given range
+bool wxRichTextParagraphLayoutBox::ClearListStyle(const wxRichTextRange& range, int flags)
+{
+ return SetListStyle(range, NULL, flags);
+}
+
+/// Number/renumber any list elements in the given range
+bool wxRichTextParagraphLayoutBox::NumberList(const wxRichTextRange& range, wxRichTextListStyleDefinition* def, int flags, int startFrom, int specifiedLevel)
+{
+ return DoNumberList(range, range, 0, def, flags, startFrom, specifiedLevel);
+}
+
+/// Number/renumber any list elements in the given range. Also do promotion or demotion of items, if specified
+bool wxRichTextParagraphLayoutBox::DoNumberList(const wxRichTextRange& range, const wxRichTextRange& promotionRange, int promoteBy,
+ wxRichTextListStyleDefinition* def, int flags, int startFrom, int specifiedLevel)
+{
+ bool withUndo = ((flags & wxRICHTEXT_SETSTYLE_WITH_UNDO) != 0);
+ // bool applyMinimal = ((flags & wxRICHTEXT_SETSTYLE_OPTIMIZE) != 0);
+ bool specifyLevel = ((flags & wxRICHTEXT_SETSTYLE_SPECIFY_LEVEL) != 0);
+
+ bool renumber = ((flags & wxRICHTEXT_SETSTYLE_RENUMBER) != 0);
+
+ // Max number of levels
+ const int maxLevels = 10;
+
+ // The level we're looking at now
+ int currentLevel = -1;
+
+ // The item number for each level
+ int levels[maxLevels];
+ int i;
+
+ // Reset all numbering
+ for (i = 0; i < maxLevels; i++)
+ {
+ if (startFrom != -1)
+ levels[i] = startFrom;
+ else if (renumber) // start again
+ levels[i] = 1;
+ else
+ levels[i] = -1; // start from the number we found, if any
+ }
+
+ wxASSERT(!specifyLevel || (specifyLevel && (specifiedLevel >= 0)));
+
+ // If we are associated with a control, make undoable; otherwise, apply immediately
+ // to the data.
+
+ bool haveControl = (GetRichTextCtrl() != NULL);
+
+ wxRichTextAction* action = NULL;
+
+ if (haveControl && withUndo)
+ {
+ action = new wxRichTextAction(NULL, _("Renumber List"), wxRICHTEXT_CHANGE_STYLE, & GetRichTextCtrl()->GetBuffer(), GetRichTextCtrl());
+ action->SetRange(range);
+ action->SetPosition(GetRichTextCtrl()->GetCaretPosition());
+ }
+
+ wxRichTextObjectList::compatibility_iterator node = m_children.GetFirst();
+ while (node)
+ {
+ wxRichTextParagraph* para = wxDynamicCast(node->GetData(), wxRichTextParagraph);
+ wxASSERT (para != NULL);
+
+ if (para && para->GetChildCount() > 0)
+ {
+ // Stop searching if we're beyond the range of interest
+ if (para->GetRange().GetStart() > range.GetEnd())
+ break;
+
+ if (!para->GetRange().IsOutside(range))
+ {
+ // We'll be using a copy of the paragraph to make style changes,
+ // not updating the buffer directly.
+ wxRichTextParagraph* newPara wxDUMMY_INITIALIZE(NULL);
+
+ if (haveControl && withUndo)
+ {
+ newPara = new wxRichTextParagraph(*para);
+ action->GetNewParagraphs().AppendChild(newPara);
+
+ // Also store the old ones for Undo
+ action->GetOldParagraphs().AppendChild(new wxRichTextParagraph(*para));
+ }
+ else
+ newPara = para;
+
+ wxRichTextListStyleDefinition* defToUse = def;
+ if (!defToUse)
+ {
+ wxRichTextStyleSheet* sheet = GetStyleSheet();
+
+ if (sheet && !newPara->GetAttributes().GetListStyleName().IsEmpty())
+ defToUse = sheet->FindListStyle(newPara->GetAttributes().GetListStyleName());
+ }
+
+ if (defToUse)
+ {
+ int thisIndent = newPara->GetAttributes().GetLeftIndent();
+ int thisLevel = defToUse->FindLevelForIndent(thisIndent);
+
+ // If the paragraph doesn't have an indent, or we've specified a level to apply to all,
+ // change the level.
+ if (thisIndent == 0 || specifiedLevel != -1)
+ thisLevel = specifiedLevel;
+
+ // Do promotion if specified
+ if ((promoteBy != 0) && !para->GetRange().IsOutside(promotionRange))
+ {
+ thisLevel = thisLevel - promoteBy;
+ if (thisLevel < 0)
+ thisLevel = 0;
+ if (thisLevel > 9)
+ thisLevel = 9;
+ }
+
+ // Apply the overall list style, and item style for this level
+ wxTextAttrEx listStyle(defToUse->GetCombinedStyleForLevel(thisLevel));
+ wxRichTextApplyStyle(newPara->GetAttributes(), listStyle);
+
+ // OK, we've (re)applied the style, now let's get the numbering right.
+
+ if (currentLevel == -1)
+ currentLevel = thisLevel;
+
+ // Same level as before, do nothing except increment level's number afterwards
+ if (currentLevel == thisLevel)
+ {
+ }
+ // A deeper level: start renumbering all levels after current level
+ else if (thisLevel > currentLevel)
+ {
+ for (i = currentLevel+1; i <= thisLevel; i++)
+ {
+ levels[i] = 1;
+ }
+ currentLevel = thisLevel;
+ }
+ else if (thisLevel < currentLevel)
+ {
+ currentLevel = thisLevel;
+ }
+
+ // Use the current numbering if -1 and we have a bullet number already
+ if (levels[currentLevel] == -1)
+ {
+ if (newPara->GetAttributes().HasBulletNumber())
+ levels[currentLevel] = newPara->GetAttributes().GetBulletNumber();
+ else
+ levels[currentLevel] = 1;
+ }
+
+ newPara->GetAttributes().SetBulletNumber(levels[currentLevel]);
+
+ levels[currentLevel] ++;
+ }
+ }
+ }
+
+ node = node->GetNext();
+ }
+
+ // Do action, or delay it until end of batch.
+ if (haveControl && withUndo)
+ GetRichTextCtrl()->GetBuffer().SubmitAction(action);
+
+ return true;
+}
+
+bool wxRichTextParagraphLayoutBox::NumberList(const wxRichTextRange& range, const wxString& defName, int flags, int startFrom, int specifiedLevel)
+{
+ if (GetStyleSheet())
+ {
+ wxRichTextListStyleDefinition* def = NULL;
+ if (!defName.IsEmpty())
+ def = GetStyleSheet()->FindListStyle(defName);
+ return NumberList(range, def, flags, startFrom, specifiedLevel);
+ }
+ return false;
+}
+
+/// Promote the list items within the given range. promoteBy can be a positive or negative number, e.g. 1 or -1
+bool wxRichTextParagraphLayoutBox::PromoteList(int promoteBy, const wxRichTextRange& range, wxRichTextListStyleDefinition* def, int flags, int specifiedLevel)
+{
+ // TODO
+ // One strategy is to first work out the range within which renumbering must occur. Then could pass these two ranges
+ // to NumberList with a flag indicating promotion is required within one of the ranges.
+ // Find first and last paragraphs in range. Then for first, calculate new indentation and look back until we find
+ // a paragraph that either has no list style, or has one that is different or whose indentation is less.
+ // We start renumbering from the para after that different para we found. We specify that the numbering of that
+ // list position will start from 1.
+ // Similarly, we look after the last para in the promote range for an indentation that is less (or no list style).
+ // We can end the renumbering at this point.
+
+ // For now, only renumber within the promotion range.
+
+ return DoNumberList(range, range, promoteBy, def, flags, 1, specifiedLevel);
+}
+
+bool wxRichTextParagraphLayoutBox::PromoteList(int promoteBy, const wxRichTextRange& range, const wxString& defName, int flags, int specifiedLevel)
+{
+ if (GetStyleSheet())
+ {
+ wxRichTextListStyleDefinition* def = NULL;
+ if (!defName.IsEmpty())
+ def = GetStyleSheet()->FindListStyle(defName);
+ return PromoteList(promoteBy, range, def, flags, specifiedLevel);
+ }
+ return false;
+}
+
/*!
* wxRichTextParagraph
* This object represents a single paragraph (or in a straight text editor, a line).
m_suppressUndo = obj.m_suppressUndo;
}
+/// Push style sheet to top of stack
+bool wxRichTextBuffer::PushStyleSheet(wxRichTextStyleSheet* styleSheet)
+{
+ if (m_styleSheet)
+ styleSheet->InsertSheet(m_styleSheet);
+
+ SetStyleSheet(styleSheet);
+
+ return true;
+}
+
+/// Pop style sheet from top of stack
+wxRichTextStyleSheet* wxRichTextBuffer::PopStyleSheet()
+{
+ if (m_styleSheet)
+ {
+ wxRichTextStyleSheet* oldSheet = m_styleSheet;
+ m_styleSheet = oldSheet->GetNextSheet();
+ oldSheet->Unlink();
+
+ return oldSheet;
+ }
+ else
+ return NULL;
+}
+
/// Submit command to insert paragraphs
bool wxRichTextBuffer::InsertParagraphsWithUndo(long pos, const wxRichTextParagraphLayoutBox& paragraphs, wxRichTextCtrl* ctrl, int flags)
{
/// Compare two attribute objects
bool wxTextAttrEq(const wxTextAttrEx& attr1, const wxTextAttrEx& attr2)
{
- return (
- attr1.GetTextColour() == attr2.GetTextColour() &&
- attr1.GetBackgroundColour() == attr2.GetBackgroundColour() &&
- attr1.GetFont() == attr2.GetFont() &&
- attr1.GetAlignment() == attr2.GetAlignment() &&
- attr1.GetLeftIndent() == attr2.GetLeftIndent() &&
- attr1.GetRightIndent() == attr2.GetRightIndent() &&
- attr1.GetLeftSubIndent() == attr2.GetLeftSubIndent() &&
- wxRichTextTabsEq(attr1.GetTabs(), attr2.GetTabs()) &&
- attr1.GetLineSpacing() == attr2.GetLineSpacing() &&
- attr1.GetParagraphSpacingAfter() == attr2.GetParagraphSpacingAfter() &&
- attr1.GetParagraphSpacingBefore() == attr2.GetParagraphSpacingBefore() &&
- attr1.GetBulletStyle() == attr2.GetBulletStyle() &&
- attr1.GetBulletNumber() == attr2.GetBulletNumber() &&
- attr1.GetBulletSymbol() == attr2.GetBulletSymbol() &&
- attr1.GetBulletFont() == attr2.GetBulletFont() &&
- attr1.GetCharacterStyleName() == attr2.GetCharacterStyleName() &&
- attr1.GetParagraphStyleName() == attr2.GetParagraphStyleName());
+ return (attr1 == attr2);
}
bool wxTextAttrEq(const wxTextAttrEx& attr1, const wxRichTextAttr& attr2)
attr1.GetBulletSymbol() == attr2.GetBulletSymbol() &&
attr1.GetBulletFont() == attr2.GetBulletFont() &&
attr1.GetCharacterStyleName() == attr2.GetCharacterStyleName() &&
- attr1.GetParagraphStyleName() == attr2.GetParagraphStyleName());
+ attr1.GetParagraphStyleName() == attr2.GetParagraphStyleName() &&
+ attr1.GetListStyleName() == attr2.GetListStyleName());
}
/// Compare two attribute objects, but take into account the flags
(attr1.GetParagraphStyleName() != attr2.GetParagraphStyleName()))
return false;
+ if ((flags & wxTEXT_ATTR_LIST_STYLE_NAME) &&
+ (attr1.GetListStyleName() != attr2.GetListStyleName()))
+ return false;
+
if ((flags & wxTEXT_ATTR_BULLET_STYLE) &&
(attr1.GetBulletStyle() != attr2.GetBulletStyle()))
return false;
(attr1.GetParagraphStyleName() != attr2.GetParagraphStyleName()))
return false;
+ if ((flags & wxTEXT_ATTR_LIST_STYLE_NAME) &&
+ (attr1.GetListStyleName() != attr2.GetListStyleName()))
+ return false;
+
if ((flags & wxTEXT_ATTR_BULLET_STYLE) &&
(attr1.GetBulletStyle() != attr2.GetBulletStyle()))
return false;
if (style.HasParagraphStyleName())
destStyle.SetParagraphStyleName(style.GetParagraphStyleName());
+ if (style.HasListStyleName())
+ destStyle.SetListStyleName(style.GetListStyleName());
+
if (style.HasBulletStyle())
{
destStyle.SetBulletStyle(style.GetBulletStyle());
destStyle.SetParagraphStyleName(style.GetParagraphStyleName());
}
+ if (style.HasListStyleName())
+ {
+ if (!(compareWith && compareWith->HasListStyleName() && compareWith->GetListStyleName() == style.GetListStyleName()))
+ destStyle.SetListStyleName(style.GetListStyleName());
+ }
+
if (style.HasBulletStyle())
{
if (!(compareWith && compareWith->HasBulletStyle() && compareWith->GetBulletStyle() == style.GetBulletStyle()))
m_lineSpacing = attr.m_lineSpacing;
m_characterStyleName = attr.m_characterStyleName;
m_paragraphStyleName = attr.m_paragraphStyleName;
+ m_listStyleName = attr.m_listStyleName;
m_bulletStyle = attr.m_bulletStyle;
m_bulletNumber = attr.m_bulletNumber;
m_bulletSymbol = attr.m_bulletSymbol;
m_lineSpacing = attr.GetLineSpacing();
m_characterStyleName = attr.GetCharacterStyleName();
m_paragraphStyleName = attr.GetParagraphStyleName();
+ m_listStyleName = attr.GetListStyleName();
m_bulletStyle = attr.GetBulletStyle();
m_bulletNumber = attr.GetBulletNumber();
m_bulletSymbol = attr.GetBulletSymbol();
GetLineSpacing() == attr.GetLineSpacing() &&
GetCharacterStyleName() == attr.GetCharacterStyleName() &&
GetParagraphStyleName() == attr.GetParagraphStyleName() &&
+ GetListStyleName() == attr.GetListStyleName() &&
GetBulletStyle() == attr.GetBulletStyle() &&
GetBulletSymbol() == attr.GetBulletSymbol() &&
attr.SetBulletFont(m_bulletFont);
attr.SetCharacterStyleName(m_characterStyleName);
attr.SetParagraphStyleName(m_paragraphStyleName);
+ attr.SetListStyleName(m_listStyleName);
attr.SetFlags(GetFlags()); // Important: set after SetFont and others, since they set flags
}
if (attr.HasParagraphStyleName())
newAttr.SetParagraphStyleName(attr.GetParagraphStyleName());
+ if (attr.HasListStyleName())
+ newAttr.SetListStyleName(attr.GetListStyleName());
+
if (attr.HasBulletStyle())
newAttr.SetBulletStyle(attr.GetBulletStyle());
m_lineSpacing = attr.m_lineSpacing;
m_paragraphStyleName = attr.m_paragraphStyleName;
m_characterStyleName = attr.m_characterStyleName;
+ m_listStyleName = attr.m_listStyleName;
m_bulletStyle = attr.m_bulletStyle;
m_bulletNumber = attr.m_bulletNumber;
m_bulletSymbol = attr.m_bulletSymbol;
m_lineSpacing = attr.m_lineSpacing;
m_characterStyleName = attr.m_characterStyleName;
m_paragraphStyleName = attr.m_paragraphStyleName;
+ m_listStyleName = attr.m_listStyleName;
m_bulletStyle = attr.m_bulletStyle;
m_bulletNumber = attr.m_bulletNumber;
m_bulletSymbol = attr.m_bulletSymbol;
wxTextAttr::operator= (attr);
}
+// Equality test
+bool wxTextAttrEx::operator== (const wxTextAttrEx& attr) const
+{
+ return (
+ GetTextColour() == attr.GetTextColour() &&
+ GetBackgroundColour() == attr.GetBackgroundColour() &&
+ GetFont() == attr.GetFont() &&
+ GetAlignment() == attr.GetAlignment() &&
+ GetLeftIndent() == attr.GetLeftIndent() &&
+ GetRightIndent() == attr.GetRightIndent() &&
+ GetLeftSubIndent() == attr.GetLeftSubIndent() &&
+ wxRichTextTabsEq(GetTabs(), attr.GetTabs()) &&
+ GetLineSpacing() == attr.GetLineSpacing() &&
+ GetParagraphSpacingAfter() == attr.GetParagraphSpacingAfter() &&
+ GetParagraphSpacingBefore() == attr.GetParagraphSpacingBefore() &&
+ GetBulletStyle() == attr.GetBulletStyle() &&
+ GetBulletNumber() == attr.GetBulletNumber() &&
+ GetBulletSymbol() == attr.GetBulletSymbol() &&
+ GetBulletFont() == attr.GetBulletFont() &&
+ GetCharacterStyleName() == attr.GetCharacterStyleName() &&
+ GetParagraphStyleName() == attr.GetParagraphStyleName() &&
+ GetListStyleName() == attr.GetListStyleName());
+}
+
wxTextAttrEx wxTextAttrEx::CombineEx(const wxTextAttrEx& attr,
const wxTextAttrEx& attrDef,
const wxTextCtrlBase *text)
if (attr.HasParagraphStyleName())
newAttr.SetParagraphStyleName(attr.GetParagraphStyleName());
+ if (attr.HasListStyleName())
+ newAttr.SetListStyleName(attr.GetListStyleName());
+
if (attr.HasBulletStyle())
newAttr.SetBulletStyle(attr.GetBulletStyle());
int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO|wxRICHTEXT_SETSTYLE_OPTIMIZE;
+ if (def->IsKindOf(CLASSINFO(wxRichTextListStyleDefinition)))
+ {
+ flags |= wxRICHTEXT_SETSTYLE_PARAGRAPHS_ONLY;
+
+ wxRichTextRange range;
+
+ if (HasSelection())
+ range = GetSelectionRange();
+ else
+ {
+ long pos = GetAdjustedCaretPosition(GetCaretPosition());
+ range = wxRichTextRange(pos, pos+1);
+ }
+
+ return SetListStyle(range, (wxRichTextListStyleDefinition*) def, flags);
+ }
+
// Make sure the attr has the style name
if (def->IsKindOf(CLASSINFO(wxRichTextParagraphStyleDefinition)))
{
attr.SetParagraphStyleName(def->GetName());
// If applying a paragraph style, we only want the paragraph nodes to adopt these
- // attributes, and not the leaf nodes. This will allow the context (e.g. text)
+ // attributes, and not the leaf nodes. This will allow the content (e.g. text)
// to change its style independently.
flags |= wxRICHTEXT_SETSTYLE_PARAGRAPHS_ONLY;
}
SetInternalSelectionRange(range1);
}
+/// 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);
+}
+
+bool wxRichTextCtrl::SetListStyle(const wxRichTextRange& range, const wxString& defName, int flags, int startFrom, int specifiedLevel)
+{
+ return GetBuffer().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);
+}
+
+/// 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);
+}
+
+bool wxRichTextCtrl::NumberList(const wxRichTextRange& range, const wxString& defName, int flags, int startFrom, int specifiedLevel)
+{
+ return GetBuffer().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);
+}
+
+bool wxRichTextCtrl::PromoteList(int promoteBy, const wxRichTextRange& range, const wxString& defName, int flags, int specifiedLevel)
+{
+ return GetBuffer().PromoteList(promoteBy, range.ToInternal(), defName, flags, specifiedLevel);
+}
+
#endif
// wxUSE_RICHTEXT
#include "wx/filename.h"
#include "wx/clipbrd.h"
#include "wx/wfstream.h"
+#include "wx/settings.h"
#include "wx/richtext/richtextctrl.h"
IMPLEMENT_CLASS(wxRichTextStyleDefinition, wxObject)
IMPLEMENT_CLASS(wxRichTextCharacterStyleDefinition, wxRichTextStyleDefinition)
IMPLEMENT_CLASS(wxRichTextParagraphStyleDefinition, wxRichTextStyleDefinition)
+IMPLEMENT_CLASS(wxRichTextListStyleDefinition, wxRichTextParagraphStyleDefinition)
/*!
* A definition
return (Eq(def) && m_nextStyle == def.m_nextStyle);
}
+/*!
+ * List style definition
+ */
+
+void wxRichTextListStyleDefinition::Copy(const wxRichTextListStyleDefinition& def)
+{
+ wxRichTextParagraphStyleDefinition::Copy(def);
+
+ int i;
+ for (i = 0; i < 10; i++)
+ m_levelStyles[i] = def.m_levelStyles[i];
+}
+
+bool wxRichTextListStyleDefinition::operator ==(const wxRichTextListStyleDefinition& def) const
+{
+ if (!Eq(def))
+ return false;
+ int i;
+ for (i = 0; i < 10; i++)
+ if (!(m_levelStyles[i] == def.m_levelStyles[i]))
+ return false;
+
+ return true;
+}
+
+/// Sets/gets the attributes for the given level
+void wxRichTextListStyleDefinition::SetLevelAttributes(int i, const wxTextAttrEx& attr)
+{
+ wxASSERT( (i >= 0 && i < 10) );
+ if (i >= 0 && i < 10)
+ m_levelStyles[i] = attr;
+}
+
+const wxTextAttrEx* wxRichTextListStyleDefinition::GetLevelAttributes(int i) const
+{
+ wxASSERT( (i >= 0 && i < 10) );
+ if (i >= 0 && i < 10)
+ return & m_levelStyles[i];
+ else
+ return NULL;
+}
+
+wxTextAttrEx* wxRichTextListStyleDefinition::GetLevelAttributes(int i)
+{
+ wxASSERT( (i >= 0 && i < 10) );
+ if (i >= 0 && i < 10)
+ return & m_levelStyles[i];
+ else
+ return NULL;
+}
+
+/// Convenience function for setting the major attributes for a list level specification
+void wxRichTextListStyleDefinition::SetAttributes(int i, int leftIndent, int leftSubIndent, int bulletStyle, const wxString& bulletSymbol)
+{
+ wxASSERT( (i >= 0 && i < 10) );
+ if (i >= 0 && i < 10)
+ {
+ wxTextAttrEx attr;
+
+ attr.SetBulletStyle(bulletStyle);
+ attr.SetLeftIndent(leftIndent, leftSubIndent);
+
+ if (!bulletSymbol.IsEmpty())
+ attr.SetBulletSymbol(bulletSymbol[0]);
+
+ m_levelStyles[i] = attr;
+ }
+}
+
+/// Finds the level corresponding to the given indentation
+int wxRichTextListStyleDefinition::FindLevelForIndent(int indent) const
+{
+ int i;
+ for (i = 0; i < 10; i++)
+ {
+ if (indent < m_levelStyles[i].GetLeftIndent())
+ {
+ if (i > 0)
+ return i - 1;
+ else
+ return 0;
+ }
+ }
+ return 9;
+}
+
+/// Combine the list style with a paragraph style, using the given indent (from which
+/// an appropriate level is found)
+wxTextAttrEx wxRichTextListStyleDefinition::CombineWithParagraphStyle(int indent, const wxTextAttrEx& paraStyle)
+{
+ int listLevel = FindLevelForIndent(indent);
+
+ wxTextAttrEx attr(*GetLevelAttributes(listLevel));
+ int oldLeftIndent = attr.GetLeftIndent();
+ int oldLeftSubIndent = attr.GetLeftSubIndent();
+
+ // First apply the overall paragraph style, if any
+ wxRichTextApplyStyle(attr, GetStyle());
+
+ // Then apply paragraph style, e.g. from paragraph style definition
+ wxRichTextApplyStyle(attr, paraStyle);
+
+ // We override the indents according to the list definition
+ attr.SetLeftIndent(oldLeftIndent, oldLeftSubIndent);
+
+ return attr;
+}
+
+/// Combine the base and list style, using the given indent (from which
+/// an appropriate level is found)
+wxTextAttrEx wxRichTextListStyleDefinition::GetCombinedStyle(int indent)
+{
+ int listLevel = FindLevelForIndent(indent);
+ return GetCombinedStyleForLevel(listLevel);
+}
+
+/// Combine the base and list style, using the given indent (from which
+/// an appropriate level is found)
+wxTextAttrEx wxRichTextListStyleDefinition::GetCombinedStyleForLevel(int listLevel)
+{
+ wxTextAttrEx attr(*GetLevelAttributes(listLevel));
+ int oldLeftIndent = attr.GetLeftIndent();
+ int oldLeftSubIndent = attr.GetLeftSubIndent();
+
+ // Apply the overall paragraph style, if any
+ wxRichTextApplyStyle(attr, GetStyle());
+
+ // We override the indents according to the list definition
+ attr.SetLeftIndent(oldLeftIndent, oldLeftSubIndent);
+
+ return attr;
+}
+
+/// Is this a numbered list?
+bool wxRichTextListStyleDefinition::IsNumbered(int i) const
+{
+ return (0 != (GetLevelAttributes(i)->GetFlags() &
+ (wxTEXT_ATTR_BULLET_STYLE_ARABIC|wxTEXT_ATTR_BULLET_STYLE_LETTERS_UPPER|wxTEXT_ATTR_BULLET_STYLE_LETTERS_LOWER|
+ wxTEXT_ATTR_BULLET_STYLE_ROMAN_UPPER|wxTEXT_ATTR_BULLET_STYLE_ROMAN_LOWER)));
+}
+
/*!
* The style manager
*/
IMPLEMENT_CLASS(wxRichTextStyleSheet, wxObject)
+wxRichTextStyleSheet::~wxRichTextStyleSheet()
+{
+ DeleteStyles();
+
+ if (m_nextSheet)
+ m_nextSheet->m_previousSheet = m_previousSheet;
+
+ if (m_previousSheet)
+ m_previousSheet->m_nextSheet = m_nextSheet;
+
+ m_previousSheet = NULL;
+ m_nextSheet = NULL;
+}
+
/// Initialisation
void wxRichTextStyleSheet::Init()
{
+ m_previousSheet = NULL;
+ m_nextSheet = NULL;
}
/// Add a definition to one of the style lists
}
/// Find a definition by name
-wxRichTextStyleDefinition* wxRichTextStyleSheet::FindStyle(const wxList& list, const wxString& name) const
+wxRichTextStyleDefinition* wxRichTextStyleSheet::FindStyle(const wxList& list, const wxString& name, bool recurse) const
{
for (wxList::compatibility_iterator node = list.GetFirst(); node; node = node->GetNext())
{
if (def->GetName().Lower() == name.Lower())
return def;
}
+
+ if (m_nextSheet && recurse)
+ return m_nextSheet->FindStyle(list, name, recurse);
+
return NULL;
}
{
WX_CLEAR_LIST(wxList, m_characterStyleDefinitions);
WX_CLEAR_LIST(wxList, m_paragraphStyleDefinitions);
+ WX_CLEAR_LIST(wxList, m_listStyleDefinitions);
+}
+
+/// Insert into list of style sheets
+bool wxRichTextStyleSheet::InsertSheet(wxRichTextStyleSheet* before)
+{
+ m_previousSheet = before->m_previousSheet;
+ m_nextSheet = before;
+
+ before->m_previousSheet = this;
+ return true;
+}
+
+/// Append to list of style sheets
+bool wxRichTextStyleSheet::AppendSheet(wxRichTextStyleSheet* after)
+{
+ wxRichTextStyleSheet* last = after;
+ while (last && last->m_nextSheet)
+ {
+ last = last->m_nextSheet;
+ }
+
+ if (last)
+ {
+ m_previousSheet = last;
+ last->m_nextSheet = this;
+
+ return true;
+ }
+ else
+ return false;
+}
+
+/// Unlink from the list of style sheets
+void wxRichTextStyleSheet::Unlink()
+{
+ if (m_previousSheet)
+ m_previousSheet->m_nextSheet = m_nextSheet;
+ if (m_nextSheet)
+ m_nextSheet->m_previousSheet = m_previousSheet;
+
+ m_previousSheet = NULL;
+ m_nextSheet = NULL;
}
/// Add a definition to the character style list
return AddStyle(m_paragraphStyleDefinitions, def);
}
+/// Add a definition to the list style list
+bool wxRichTextStyleSheet::AddListStyle(wxRichTextListStyleDefinition* def)
+{
+ def->GetStyle().SetListStyleName(def->GetName());
+ return AddStyle(m_listStyleDefinitions, def);
+}
+
/// Copy
void wxRichTextStyleSheet::Copy(const wxRichTextStyleSheet& sheet)
{
wxRichTextParagraphStyleDefinition* def = (wxRichTextParagraphStyleDefinition*) node->GetData();
AddParagraphStyle(new wxRichTextParagraphStyleDefinition(*def));
}
+
+ for (node = sheet.m_listStyleDefinitions.GetFirst(); node; node = node->GetNext())
+ {
+ wxRichTextListStyleDefinition* def = (wxRichTextListStyleDefinition*) node->GetData();
+ AddListStyle(new wxRichTextListStyleDefinition(*def));
+ }
}
/// Equality
#if wxUSE_HTML
/*!
- * wxRichTextStyleListBox class declaration
- * A listbox to display styles.
+ * wxRichTextStyleListBox: a listbox to display styles.
*/
IMPLEMENT_CLASS(wxRichTextStyleListBox, wxHtmlListBox)
BEGIN_EVENT_TABLE(wxRichTextStyleListBox, wxHtmlListBox)
EVT_LISTBOX(wxID_ANY, wxRichTextStyleListBox::OnSelect)
EVT_LEFT_DOWN(wxRichTextStyleListBox::OnLeftDown)
+ EVT_LEFT_DCLICK(wxRichTextStyleListBox::OnLeftDoubleClick)
EVT_IDLE(wxRichTextStyleListBox::OnIdle)
END_EVENT_TABLE()
{
if (!GetStyleSheet())
return wxEmptyString;
+
+ wxRichTextStyleDefinition* def = GetStyle(n);
+ if (def)
+ return CreateHTML(def);
- // First paragraph styles, then character
- if (n < GetStyleSheet()->GetParagraphStyleCount())
- {
- wxRichTextParagraphStyleDefinition* def = GetStyleSheet()->GetParagraphStyle(n);
-
- wxString str = CreateHTML(def);
- return str;
- }
-
- if ((n - GetStyleSheet()->GetParagraphStyleCount()) < GetStyleSheet()->GetCharacterStyleCount())
- {
- wxRichTextCharacterStyleDefinition* def = GetStyleSheet()->GetCharacterStyle(n - GetStyleSheet()->GetParagraphStyleCount());
-
- wxString str = CreateHTML(def);
- return str;
- }
return wxEmptyString;
}
if (!GetStyleSheet())
return NULL;
- // First paragraph styles, then character
- if (i < GetStyleSheet()->GetParagraphStyleCount())
- return GetStyleSheet()->GetParagraphStyle(i);
+ if (GetStyleType() == wxRICHTEXT_STYLE_ALL)
+ {
+ // First paragraph styles, then character, then list
+ if (i < GetStyleSheet()->GetParagraphStyleCount())
+ return GetStyleSheet()->GetParagraphStyle(i);
- if ((i - GetStyleSheet()->GetParagraphStyleCount()) < GetStyleSheet()->GetCharacterStyleCount())
- return GetStyleSheet()->GetCharacterStyle(i - GetStyleSheet()->GetParagraphStyleCount());
+ if ((i - GetStyleSheet()->GetParagraphStyleCount()) < GetStyleSheet()->GetCharacterStyleCount())
+ return GetStyleSheet()->GetCharacterStyle(i - GetStyleSheet()->GetParagraphStyleCount());
+
+ if ((i - GetStyleSheet()->GetParagraphStyleCount() - GetStyleSheet()->GetCharacterStyleCount()) < GetStyleSheet()->GetListStyleCount())
+ return GetStyleSheet()->GetListStyle(i - GetStyleSheet()->GetParagraphStyleCount() - GetStyleSheet()->GetCharacterStyleCount());
+ }
+ else if ((GetStyleType() == wxRICHTEXT_STYLE_PARAGRAPH) && (i < GetStyleSheet()->GetParagraphStyleCount()))
+ {
+ return GetStyleSheet()->GetParagraphStyle(i);
+ }
+ else if ((GetStyleType() == wxRICHTEXT_STYLE_CHARACTER) && (i < GetStyleSheet()->GetCharacterStyleCount()))
+ {
+ return GetStyleSheet()->GetCharacterStyle(i);
+ }
+ else if ((GetStyleType() == wxRICHTEXT_STYLE_LIST) && (i < GetStyleSheet()->GetListStyleCount()))
+ {
+ return GetStyleSheet()->GetListStyle(i);
+ }
return NULL;
}
{
if (GetStyleSheet())
{
- SetItemCount(GetStyleSheet()->GetParagraphStyleCount()+GetStyleSheet()->GetCharacterStyleCount());
+ if (GetStyleType() == wxRICHTEXT_STYLE_ALL)
+ SetItemCount(GetStyleSheet()->GetParagraphStyleCount()+GetStyleSheet()->GetCharacterStyleCount()+GetStyleSheet()->GetListStyleCount());
+ else if (GetStyleType() == wxRICHTEXT_STYLE_PARAGRAPH)
+ SetItemCount(GetStyleSheet()->GetParagraphStyleCount());
+ else if (GetStyleType() == wxRICHTEXT_STYLE_CHARACTER)
+ SetItemCount(GetStyleSheet()->GetCharacterStyleCount());
+ else if (GetStyleType() == wxRICHTEXT_STYLE_LIST)
+ SetItemCount(GetStyleSheet()->GetListStyleCount());
Refresh();
}
}
{
if (GetStyleSheet())
{
+ int count = GetItemCount();
+
int i;
- for (i = 0; i < (int) GetStyleSheet()->GetParagraphStyleCount(); i++)
+ for (i = 0; i < (int) count; i++)
{
- wxRichTextParagraphStyleDefinition* def = GetStyleSheet()->GetParagraphStyle(i);
+ wxRichTextStyleDefinition* def = GetStyle(i);
if (def->GetName() == name)
return i;
}
- for (i = 0; i < (int) GetStyleSheet()->GetCharacterStyleCount(); i++)
- {
- wxRichTextCharacterStyleDefinition* def = GetStyleSheet()->GetCharacterStyle(i);
- if (def->GetName() == name)
- return i + (int) GetStyleSheet()->GetParagraphStyleCount();
- }
}
return -1;
}
/// Creates a suitable HTML fragment for a definition
wxString wxRichTextStyleListBox::CreateHTML(wxRichTextStyleDefinition* def) const
{
+ // TODO: indicate list format for list style types
+
wxString str(wxT("<table><tr>"));
if (def->GetStyle().GetLeftIndent() > 0)
{
wxClientDC dc((wxWindow*) this);
- str << wxT("<td width=") << ConvertTenthsMMToPixels(dc, def->GetStyle().GetLeftIndent()) << wxT("></td>");
+ str << wxT("<td width=") << (ConvertTenthsMMToPixels(dc, def->GetStyle().GetLeftIndent())/2) << wxT("></td>");
}
str << wxT("<td nowrap>");
- int size = 5;
+ int size = 4;
// Standard size is 12, say
- size += 12 - def->GetStyle().GetFontSize();
+ size += (def->GetStyle().HasFont() ? def->GetStyle().GetFontSize() : 12) - 12;
str += wxT("<font");
ApplyStyle(item);
}
-/// Auto-select from style under caret in idle time
-void wxRichTextStyleListBox::OnIdle(wxIdleEvent& event)
+void wxRichTextStyleListBox::OnLeftDoubleClick(wxMouseEvent& event)
{
- if (CanAutoSetSelection() && GetRichTextCtrl())
- {
- int adjustedCaretPos = GetRichTextCtrl()->GetAdjustedCaretPosition(GetRichTextCtrl()->GetCaretPosition());
+ wxVListBox::OnLeftDown(event);
- wxRichTextParagraph* para = GetRichTextCtrl()->GetBuffer().GetParagraphAtPosition(adjustedCaretPos);
- wxRichTextObject* obj = GetRichTextCtrl()->GetBuffer().GetLeafObjectAtPosition(adjustedCaretPos);
+ int item = HitTest(event.GetPosition());
+ if (item != wxNOT_FOUND && !GetApplyOnSelection())
+ ApplyStyle(item);
+}
- wxString styleName;
+/// Helper for listbox and combo control
+wxString wxRichTextStyleListBox::GetStyleToShowInIdleTime(wxRichTextCtrl* ctrl, wxRichTextStyleType styleType)
+{
+ int adjustedCaretPos = ctrl->GetAdjustedCaretPosition(ctrl->GetCaretPosition());
- // Take into account current default style just chosen by user
- if (GetRichTextCtrl()->IsDefaultStyleShowing())
- {
- if (!GetRichTextCtrl()->GetDefaultStyleEx().GetCharacterStyleName().IsEmpty())
- styleName = GetRichTextCtrl()->GetDefaultStyleEx().GetCharacterStyleName();
- else if (!GetRichTextCtrl()->GetDefaultStyleEx().GetParagraphStyleName().IsEmpty())
- styleName = GetRichTextCtrl()->GetDefaultStyleEx().GetParagraphStyleName();
- }
- else if (obj && !obj->GetAttributes().GetCharacterStyleName().IsEmpty())
- {
- styleName = obj->GetAttributes().GetCharacterStyleName();
- }
- else if (para && !para->GetAttributes().GetParagraphStyleName().IsEmpty())
- {
- styleName = para->GetAttributes().GetParagraphStyleName();
- }
+ wxRichTextParagraph* para = ctrl->GetBuffer().GetParagraphAtPosition(adjustedCaretPos);
+ wxRichTextObject* obj = ctrl->GetBuffer().GetLeafObjectAtPosition(adjustedCaretPos);
+
+ wxString styleName;
+
+ // Take into account current default style just chosen by user
+ if (ctrl->IsDefaultStyleShowing())
+ {
+ if ((styleType == wxRICHTEXT_STYLE_ALL || styleType == wxRICHTEXT_STYLE_CHARACTER) &&
+ !ctrl->GetDefaultStyleEx().GetCharacterStyleName().IsEmpty())
+ styleName = ctrl->GetDefaultStyleEx().GetCharacterStyleName();
+ else if ((styleType == wxRICHTEXT_STYLE_ALL || styleType == wxRICHTEXT_STYLE_PARAGRAPH) &&
+ !ctrl->GetDefaultStyleEx().GetParagraphStyleName().IsEmpty())
+ styleName = ctrl->GetDefaultStyleEx().GetParagraphStyleName();
+ else if ((styleType == wxRICHTEXT_STYLE_ALL || styleType == wxRICHTEXT_STYLE_LIST) &&
+ !ctrl->GetDefaultStyleEx().GetListStyleName().IsEmpty())
+ styleName = ctrl->GetDefaultStyleEx().GetListStyleName();
+ }
+ else if (obj && (styleType == wxRICHTEXT_STYLE_ALL || styleType == wxRICHTEXT_STYLE_CHARACTER) &&
+ !obj->GetAttributes().GetCharacterStyleName().IsEmpty())
+ {
+ styleName = obj->GetAttributes().GetCharacterStyleName();
+ }
+ else if (para && (styleType == wxRICHTEXT_STYLE_ALL || styleType == wxRICHTEXT_STYLE_PARAGRAPH) &&
+ !para->GetAttributes().GetParagraphStyleName().IsEmpty())
+ {
+ styleName = para->GetAttributes().GetParagraphStyleName();
+ }
+ else if (para && (styleType == wxRICHTEXT_STYLE_ALL || styleType == wxRICHTEXT_STYLE_LIST) &&
+ !para->GetAttributes().GetListStyleName().IsEmpty())
+ {
+ styleName = para->GetAttributes().GetListStyleName();
+ }
+
+ return styleName;
+}
+
+/// Auto-select from style under caret in idle time
+void wxRichTextStyleListBox::OnIdle(wxIdleEvent& event)
+{
+ if (CanAutoSetSelection() && GetRichTextCtrl() && wxWindow::FindFocus() != this)
+ {
+ wxString styleName = GetStyleToShowInIdleTime(GetRichTextCtrl(), GetStyleType());
int sel = GetSelection();
if (!styleName.IsEmpty())
}
}
-#if 0
-wxColour wxRichTextStyleListBox::GetSelectedTextColour(const wxColour& colFg) const
+/*!
+ * wxRichTextStyleListCtrl class: manages a listbox and a choice control to
+ * switch shown style types
+ */
+
+IMPLEMENT_CLASS(wxRichTextStyleListCtrl, wxControl)
+
+BEGIN_EVENT_TABLE(wxRichTextStyleListCtrl, wxControl)
+ EVT_CHOICE(wxID_ANY, wxRichTextStyleListCtrl::OnChooseType)
+ EVT_SIZE(wxRichTextStyleListCtrl::OnSize)
+END_EVENT_TABLE()
+
+wxRichTextStyleListCtrl::wxRichTextStyleListCtrl(wxWindow* parent, wxWindowID id, const wxPoint& pos,
+ const wxSize& size, long style)
{
- return *wxBLACK;
+ Init();
+ Create(parent, id, pos, size, style);
}
-wxColour wxRichTextStyleListBox::GetSelectedTextBgColour(const wxColour& colBg) const
+bool wxRichTextStyleListCtrl::Create(wxWindow* parent, wxWindowID id, const wxPoint& pos,
+ const wxSize& size, long style)
{
- return *wxWHITE;
+ wxControl::Create(parent, id, pos, size, style);
+
+ SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
+
+ m_styleListBox = new wxRichTextStyleListBox(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSIMPLE_BORDER);
+
+ wxArrayString choices;
+ choices.Add(_("All styles"));
+ choices.Add(_("Paragraph styles"));
+ choices.Add(_("Character styles"));
+ choices.Add(_("List styles"));
+
+ m_styleChoice = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, choices);
+
+ wxBoxSizer* boxSizer = new wxBoxSizer(wxVERTICAL);
+ boxSizer->Add(m_styleListBox, 1, wxALL|wxEXPAND, 5);
+ boxSizer->Add(m_styleChoice, 0, wxALL|wxEXPAND, 5);
+
+ SetSizer(boxSizer);
+
+ m_dontUpdate = true;
+
+ int i = StyleTypeToIndex(m_styleListBox->GetStyleType());
+ m_styleChoice->SetSelection(i);
+
+ m_dontUpdate = false;
+
+ return true;
+}
+
+wxRichTextStyleListCtrl::~wxRichTextStyleListCtrl()
+{
+}
+
+/// React to style type choice
+void wxRichTextStyleListCtrl::OnChooseType(wxCommandEvent& event)
+{
+ if (event.GetEventObject() != m_styleChoice)
+ event.Skip();
+ else
+ {
+ if (m_dontUpdate)
+ return;
+
+ wxRichTextStyleListBox::wxRichTextStyleType styleType = StyleIndexToType(event.GetSelection());
+ m_styleListBox->SetStyleType(styleType);
+ }
+}
+
+/// Lay out the controls
+void wxRichTextStyleListCtrl::OnSize(wxSizeEvent& WXUNUSED(event))
+{
+ if (GetAutoLayout())
+ Layout();
+}
+
+/// Get the choice index for style type
+int wxRichTextStyleListCtrl::StyleTypeToIndex(wxRichTextStyleListBox::wxRichTextStyleType styleType)
+{
+ if (styleType == wxRichTextStyleListBox::wxRICHTEXT_STYLE_ALL)
+ {
+ return 0;
+ }
+ else if (styleType == wxRichTextStyleListBox::wxRICHTEXT_STYLE_PARAGRAPH)
+ {
+ return 1;
+ }
+ else if (styleType == wxRichTextStyleListBox::wxRICHTEXT_STYLE_CHARACTER)
+ {
+ return 2;
+ }
+ else if (styleType == wxRichTextStyleListBox::wxRICHTEXT_STYLE_LIST)
+ {
+ return 3;
+ }
+ return 0;
+}
+
+/// Get the style type for choice index
+wxRichTextStyleListBox::wxRichTextStyleType wxRichTextStyleListCtrl::StyleIndexToType(int i)
+{
+ if (i == 1)
+ return wxRichTextStyleListBox::wxRICHTEXT_STYLE_PARAGRAPH;
+ else if (i == 2)
+ return wxRichTextStyleListBox::wxRICHTEXT_STYLE_CHARACTER;
+ else if (i == 3)
+ return wxRichTextStyleListBox::wxRICHTEXT_STYLE_LIST;
+
+ return wxRichTextStyleListBox::wxRICHTEXT_STYLE_ALL;
+}
+
+/// Associates the control with a style manager
+void wxRichTextStyleListCtrl::SetStyleSheet(wxRichTextStyleSheet* styleSheet)
+{
+ if (m_styleListBox)
+ m_styleListBox->SetStyleSheet(styleSheet);
+}
+
+wxRichTextStyleSheet* wxRichTextStyleListCtrl::GetStyleSheet() const
+{
+ if (m_styleListBox)
+ return m_styleListBox->GetStyleSheet();
+ else
+ return NULL;
+}
+
+/// Associates the control with a wxRichTextCtrl
+void wxRichTextStyleListCtrl::SetRichTextCtrl(wxRichTextCtrl* ctrl)
+{
+ if (m_styleListBox)
+ m_styleListBox->SetRichTextCtrl(ctrl);
+}
+
+wxRichTextCtrl* wxRichTextStyleListCtrl::GetRichTextCtrl() const
+{
+ if (m_styleListBox)
+ return m_styleListBox->GetRichTextCtrl();
+ else
+ return NULL;
+}
+
+/// Set/get the style type to display
+void wxRichTextStyleListCtrl::SetStyleType(wxRichTextStyleListBox::wxRichTextStyleType styleType)
+{
+ if (m_styleListBox)
+ m_styleListBox->SetStyleType(styleType);
+
+ m_dontUpdate = true;
+
+ if (m_styleChoice)
+ {
+ int i = StyleTypeToIndex(m_styleListBox->GetStyleType());
+ m_styleChoice->SetSelection(i);
+ }
+
+ m_dontUpdate = false;
+}
+
+wxRichTextStyleListBox::wxRichTextStyleType wxRichTextStyleListCtrl::GetStyleType() const
+{
+ if (m_styleListBox)
+ return m_styleListBox->GetStyleType();
+ else
+ return wxRichTextStyleListBox::wxRICHTEXT_STYLE_ALL;
+}
+
+/// Updates the style list box
+void wxRichTextStyleListCtrl::UpdateStyles()
+{
+ if (m_styleListBox)
+ m_styleListBox->UpdateStyles();
}
-#endif
#if wxUSE_COMBOCTRL
void wxRichTextStyleComboCtrl::OnIdle(wxIdleEvent& event)
{
- if (GetRichTextCtrl() && !IsPopupShown())
+ if (GetRichTextCtrl() && !IsPopupShown() && m_stylePopup && wxWindow::FindFocus() != this)
{
- int adjustedCaretPos = GetRichTextCtrl()->GetAdjustedCaretPosition(GetRichTextCtrl()->GetCaretPosition());
-
- wxRichTextParagraph* para = GetRichTextCtrl()->GetBuffer().GetParagraphAtPosition(adjustedCaretPos);
- wxRichTextObject* obj = GetRichTextCtrl()->GetBuffer().GetLeafObjectAtPosition(adjustedCaretPos);
-
- wxString styleName;
-
- // Take into account current default style just chosen by user
- if (GetRichTextCtrl()->IsDefaultStyleShowing())
- {
- if (!GetRichTextCtrl()->GetDefaultStyleEx().GetCharacterStyleName().IsEmpty())
- styleName = GetRichTextCtrl()->GetDefaultStyleEx().GetCharacterStyleName();
- else if (!GetRichTextCtrl()->GetDefaultStyleEx().GetParagraphStyleName().IsEmpty())
- styleName = GetRichTextCtrl()->GetDefaultStyleEx().GetParagraphStyleName();
- }
- else if (obj && !obj->GetAttributes().GetCharacterStyleName().IsEmpty())
- {
- styleName = obj->GetAttributes().GetCharacterStyleName();
- }
- else if (para && !para->GetAttributes().GetParagraphStyleName().IsEmpty())
- {
- styleName = para->GetAttributes().GetParagraphStyleName();
- }
-
+ wxString styleName = wxRichTextStyleListBox::GetStyleToShowInIdleTime(GetRichTextCtrl(), m_stylePopup->GetStyleType());
+
wxString currentValue = GetValue();
if (!styleName.IsEmpty())
{
#endif
// wxUSE_RICHTEXT
+