]> git.saurik.com Git - wxWidgets.git/commitdiff
Added list style to text attributes, independent from paragraph style
authorJulian Smart <julian@anthemion.co.uk>
Tue, 17 Oct 2006 14:09:14 +0000 (14:09 +0000)
committerJulian Smart <julian@anthemion.co.uk>
Tue, 17 Oct 2006 14:09:14 +0000 (14:09 +0000)
Added list style definition
Added SetListStyle, ClearListStyle, NumberList, PromoteList to
buffer and control classes
Changed style listbox so double-click applies style instead of
single click. This allows for multiple items to be applicable,
and also in future to edit styles from this listbox without
accidentally applying the style to content.
Added wxRichTextStyleListCtrl which also shows a wxChoice for
selecting the type of style to display.
Style sheets can form a chain to allow inheritance from current
style sheet (not yet supported by style list controls).
Added PushStyleSheet/PopStyleSheet.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@42075 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/richtext/richtextbuffer.h
include/wx/richtext/richtextctrl.h
include/wx/richtext/richtextstyles.h
src/richtext/richtextbuffer.cpp
src/richtext/richtextctrl.cpp
src/richtext/richtextstyles.cpp

index ed0da6c2c15c7982b51819a293c3da30ee0ec0f7..18833e8aef4623b471ff7963b4300131e1a56731 100644 (file)
@@ -98,6 +98,7 @@ class WXDLLIMPEXP_RICHTEXT wxRichTextParagraph;
 class WXDLLIMPEXP_RICHTEXT wxRichTextFileHandler;
 class WXDLLIMPEXP_RICHTEXT wxRichTextStyleSheet;
 class WXDLLIMPEXP_RICHTEXT wxTextAttrEx;
+class WXDLLIMPEXP_RICHTEXT wxRichTextListStyleDefinition;
 
 /*!
  * Flags determining the available space, passed to Layout
@@ -133,7 +134,7 @@ class WXDLLIMPEXP_RICHTEXT wxTextAttrEx;
 #define wxRICHTEXT_UNFORMATTED      0x02
 
 /*!
- * Flags for SetStyle
+ * Flags for SetStyle/SetListStyle
  */
 
 #define wxRICHTEXT_SETSTYLE_NONE            0x00
@@ -155,6 +156,14 @@ class WXDLLIMPEXP_RICHTEXT wxTextAttrEx;
 // 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
  */
@@ -174,6 +183,7 @@ class WXDLLIMPEXP_RICHTEXT wxTextAttrEx;
 #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
@@ -274,18 +284,22 @@ public:
     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); }
@@ -296,6 +310,7 @@ public:
 
     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; }
@@ -315,6 +330,7 @@ public:
     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); }
@@ -331,7 +347,8 @@ public:
         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
@@ -356,6 +373,9 @@ private:
 
     // Paragraph style
     wxString            m_paragraphStyleName;
+
+    // List style
+    wxString            m_listStyleName;
 };
 
 /*!
@@ -415,6 +435,7 @@ public:
 
     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; }
@@ -440,6 +461,7 @@ public:
 
     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; }
@@ -467,6 +489,7 @@ public:
     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; }
@@ -485,7 +508,8 @@ public:
         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
@@ -528,13 +552,16 @@ private:
 
     // 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)
 
@@ -858,6 +885,10 @@ 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; }
+
 // Operations
 
     /// Initialize the object.
@@ -953,6 +984,27 @@ public:
     /// 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
@@ -1465,7 +1517,13 @@ public:
 
     /// 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
 
index 1e0e289712675fb0e3ccc7ab5b3a7c2c0018624a..cf57742c59703e397635f8154e56497c8da5db26 100644 (file)
@@ -196,6 +196,23 @@ public:
     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.
@@ -530,10 +547,16 @@ public:
     /// 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);
 
index d903fccb863d0ab8edf18078d89dc5dc7e15c82c..f16a3b6cf1a509d47801ae52f67c6d63eb1fe849 100644 (file)
@@ -30,6 +30,8 @@
 #include "wx/combo.h"
 #endif
 
+#include "wx/choice.h"
+
 /*!
  * Forward declarations
  */
@@ -47,32 +49,47 @@ class WXDLLIMPEXP_RICHTEXT wxRichTextStyleDefinition: public wxObject
     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; }
@@ -92,13 +109,17 @@ class WXDLLIMPEXP_RICHTEXT wxRichTextCharacterStyleDefinition: public wxRichText
     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:
@@ -113,21 +134,30 @@ class WXDLLIMPEXP_RICHTEXT wxRichTextParagraphStyleDefinition: public wxRichText
     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:
@@ -136,6 +166,72 @@ 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
  */
@@ -152,7 +248,7 @@ public:
         Copy(sheet);
     }
     wxRichTextStyleSheet() { Init(); }
-    virtual ~wxRichTextStyleSheet() { DeleteStyles(); }
+    virtual ~wxRichTextStyleSheet();
 
     /// Initialisation
     void Init();
@@ -172,33 +268,65 @@ public:
     /// 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
@@ -208,12 +336,16 @@ public:
     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
@@ -228,6 +360,15 @@ class WXDLLIMPEXP_RICHTEXT wxRichTextStyleListBox: public wxHtmlListBox
     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();
@@ -240,7 +381,8 @@ public:
     {
         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,
@@ -278,14 +420,12 @@ public:
     /// 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;
 
@@ -297,6 +437,13 @@ public:
     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;
@@ -306,6 +453,84 @@ private:
     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
index 263152bc9be8289f90ef220e1271755e77a0c326..d186fd8af3e21d2d7c0aed498700b24ab707cf36 100644 (file)
@@ -1617,7 +1617,7 @@ bool wxRichTextParagraphLayoutBox::SetStyle(const wxRichTextRange& range, const
                 }
                 else
                     newPara = para;
-
+                
                 if (paragraphStyle && !charactersOnly)
                 {
                     if (applyMinimal)
@@ -2108,6 +2108,21 @@ bool wxRichTextParagraphLayoutBox::CollectStyle(wxTextAttrEx& currentStyle, cons
             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())
@@ -2410,7 +2425,57 @@ bool wxRichTextParagraphLayoutBox::ApplyStyleSheet(wxRichTextStyleSheet* styleSh
 
         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)
@@ -2426,6 +2491,344 @@ bool wxRichTextParagraphLayoutBox::ApplyStyleSheet(wxRichTextStyleSheet* styleSh
     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).
@@ -4027,6 +4430,32 @@ void wxRichTextBuffer::Copy(const wxRichTextBuffer& obj)
     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)
 {
@@ -5304,24 +5733,7 @@ void wxRichTextImage::Copy(const wxRichTextImage& obj)
 /// 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)
@@ -5347,7 +5759,8 @@ 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
@@ -5411,6 +5824,10 @@ bool wxTextAttrEqPartial(const wxTextAttrEx& attr1, const wxTextAttrEx& attr2, i
         (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;
@@ -5496,6 +5913,10 @@ bool wxTextAttrEqPartial(const wxTextAttrEx& attr1, const wxRichTextAttr& attr2,
         (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;
@@ -5618,6 +6039,9 @@ bool wxRichTextApplyStyle(wxTextAttrEx& destStyle, const wxTextAttrEx& style)
     if (style.HasParagraphStyleName())
         destStyle.SetParagraphStyleName(style.GetParagraphStyleName());
 
+    if (style.HasListStyleName())
+        destStyle.SetListStyleName(style.GetListStyleName());
+
     if (style.HasBulletStyle())
     {
         destStyle.SetBulletStyle(style.GetBulletStyle());
@@ -5795,6 +6219,12 @@ bool wxRichTextApplyStyle(wxTextAttrEx& destStyle, const wxRichTextAttr& style,
             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()))
@@ -5950,6 +6380,7 @@ void wxRichTextAttr::operator= (const wxRichTextAttr& attr)
     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;
@@ -5973,6 +6404,7 @@ void wxRichTextAttr::operator= (const wxTextAttrEx& attr)
     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();
@@ -6009,6 +6441,7 @@ bool wxRichTextAttr::operator== (const wxRichTextAttr& attr) const
             GetLineSpacing() == attr.GetLineSpacing() &&
             GetCharacterStyleName() == attr.GetCharacterStyleName() &&
             GetParagraphStyleName() == attr.GetParagraphStyleName() &&
+            GetListStyleName() == attr.GetListStyleName() &&
 
             GetBulletStyle() == attr.GetBulletStyle() &&
             GetBulletSymbol() == attr.GetBulletSymbol() &&
@@ -6042,6 +6475,7 @@ void wxRichTextAttr::CopyTo(wxTextAttrEx& attr) const
     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
 }
@@ -6147,6 +6581,9 @@ wxRichTextAttr wxRichTextAttr::Combine(const wxRichTextAttr& attr,
     if (attr.HasParagraphStyleName())
         newAttr.SetParagraphStyleName(attr.GetParagraphStyleName());
 
+    if (attr.HasListStyleName())
+        newAttr.SetListStyleName(attr.GetListStyleName());
+
     if (attr.HasBulletStyle())
         newAttr.SetBulletStyle(attr.GetBulletStyle());
 
@@ -6173,6 +6610,7 @@ wxTextAttrEx::wxTextAttrEx(const wxTextAttrEx& attr): wxTextAttr(attr)
     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;
@@ -6201,6 +6639,7 @@ void wxTextAttrEx::operator= (const wxTextAttrEx& attr)
     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;
@@ -6213,6 +6652,30 @@ void wxTextAttrEx::operator= (const wxTextAttr& attr)
     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)
@@ -6340,6 +6803,9 @@ wxTextAttrEx wxTextAttrEx::CombineEx(const wxTextAttrEx& attr,
     if (attr.HasParagraphStyleName())
         newAttr.SetParagraphStyleName(attr.GetParagraphStyleName());
 
+    if (attr.HasListStyleName())
+        newAttr.SetListStyleName(attr.GetListStyleName());
+
     if (attr.HasBulletStyle())
         newAttr.SetBulletStyle(attr.GetBulletStyle());
 
index 4c3664423b09b3d943afd4f777d96705d33d37ce..3ff5366e308d524fd18a7bf7fd68ddeeb541c046 100644 (file)
@@ -2746,13 +2746,30 @@ bool wxRichTextCtrl::ApplyStyle(wxRichTextStyleDefinition* def)
 
     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;
     }
@@ -2852,6 +2869,45 @@ void wxRichTextCtrl::SetSelectionRange(const wxRichTextRange& range)
     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
 
index e0bad0c3adca78d507d9679fb4ad0534d4c87ee4..86ac5b074d25a9f9b78c930d27a5526eacce6616 100644 (file)
 #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
@@ -66,15 +68,172 @@ bool wxRichTextParagraphStyleDefinition::operator ==(const wxRichTextParagraphSt
     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
@@ -102,7 +261,7 @@ bool wxRichTextStyleSheet::RemoveStyle(wxList& list, wxRichTextStyleDefinition*
 }
 
 /// 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())
     {
@@ -110,6 +269,10 @@ wxRichTextStyleDefinition* wxRichTextStyleSheet::FindStyle(const wxList& list, c
         if (def->GetName().Lower() == name.Lower())
             return def;
     }
+    
+    if (m_nextSheet && recurse)
+        return m_nextSheet->FindStyle(list, name, recurse);
+
     return NULL;
 }
 
@@ -118,6 +281,49 @@ void wxRichTextStyleSheet::DeleteStyles()
 {
     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
@@ -134,6 +340,13 @@ bool wxRichTextStyleSheet::AddParagraphStyle(wxRichTextParagraphStyleDefinition*
     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)
 {
@@ -152,6 +365,12 @@ 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
@@ -164,8 +383,7 @@ bool wxRichTextStyleSheet::operator==(const wxRichTextStyleSheet& WXUNUSED(sheet
 
 #if wxUSE_HTML
 /*!
- * wxRichTextStyleListBox class declaration
- * A listbox to display styles.
+ * wxRichTextStyleListBox: a listbox to display styles.
  */
 
 IMPLEMENT_CLASS(wxRichTextStyleListBox, wxHtmlListBox)
@@ -173,6 +391,7 @@ 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()
 
@@ -198,23 +417,11 @@ wxString wxRichTextStyleListBox::OnGetItem(size_t n) const
 {
     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;
 }
 
@@ -224,12 +431,30 @@ wxRichTextStyleDefinition* wxRichTextStyleListBox::GetStyle(size_t i) const
     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;
 }
@@ -239,7 +464,14 @@ void wxRichTextStyleListBox::UpdateStyles()
 {
     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();
     }
 }
@@ -249,19 +481,15 @@ int wxRichTextStyleListBox::GetIndexForStyle(const wxString& name) const
 {
     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;
 }
@@ -290,21 +518,23 @@ static wxString ColourToHexString(const wxColour& col)
 /// 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");
 
@@ -384,34 +614,63 @@ void wxRichTextStyleListBox::OnLeftDown(wxMouseEvent& event)
         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())
@@ -442,17 +701,180 @@ void wxRichTextStyleListBox::ApplyStyle(int item)
     }
 }
 
-#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
 
@@ -556,32 +978,10 @@ bool wxRichTextStyleComboCtrl::Create(wxWindow* parent, wxWindowID id, const wxP
 
 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())
         {
@@ -605,3 +1005,4 @@ void wxRichTextStyleComboCtrl::OnIdle(wxIdleEvent& event)
 
 #endif
     // wxUSE_RICHTEXT
+