Added rich text buffer clipboard support.
Added double-left-click word selection support. Now saves only the active attributes to XML. Eliminated wxRichTextFragment class to allow wxRichTextBuffer to be used where wxRichTextFragment was used. Fixed AddParagraph virtual function hiding warning. Miscellaneous small wxRichTextCtrl bug fixes and cleanup. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@41542 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -102,6 +102,10 @@
|
|||||||
#include "wx/cmdproc.h"
|
#include "wx/cmdproc.h"
|
||||||
#include "wx/txtstrm.h"
|
#include "wx/txtstrm.h"
|
||||||
|
|
||||||
|
#if wxUSE_DATAOBJ
|
||||||
|
#include "wx/dataobj.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
// Experimental dynamic styles to avoid user-specific character styles from being
|
// Experimental dynamic styles to avoid user-specific character styles from being
|
||||||
// overwritten by paragraph styles.
|
// overwritten by paragraph styles.
|
||||||
#define wxRICHTEXT_USE_DYNAMIC_STYLES 1
|
#define wxRICHTEXT_USE_DYNAMIC_STYLES 1
|
||||||
@@ -127,7 +131,6 @@ class WXDLLIMPEXP_RICHTEXT wxRichTextCacheObject;
|
|||||||
class WXDLLIMPEXP_RICHTEXT wxRichTextObjectList;
|
class WXDLLIMPEXP_RICHTEXT wxRichTextObjectList;
|
||||||
class WXDLLIMPEXP_RICHTEXT wxRichTextLine;
|
class WXDLLIMPEXP_RICHTEXT wxRichTextLine;
|
||||||
class WXDLLIMPEXP_RICHTEXT wxRichTextParagraph;
|
class WXDLLIMPEXP_RICHTEXT wxRichTextParagraph;
|
||||||
class WXDLLIMPEXP_RICHTEXT wxRichTextFragment;
|
|
||||||
class WXDLLIMPEXP_RICHTEXT wxRichTextFileHandler;
|
class WXDLLIMPEXP_RICHTEXT wxRichTextFileHandler;
|
||||||
class WXDLLIMPEXP_RICHTEXT wxRichTextStyleSheet;
|
class WXDLLIMPEXP_RICHTEXT wxRichTextStyleSheet;
|
||||||
class WXDLLIMPEXP_RICHTEXT wxTextAttrEx;
|
class WXDLLIMPEXP_RICHTEXT wxTextAttrEx;
|
||||||
@@ -757,6 +760,9 @@ public:
|
|||||||
/// Copy
|
/// Copy
|
||||||
void Copy(const wxRichTextCompositeObject& obj);
|
void Copy(const wxRichTextCompositeObject& obj);
|
||||||
|
|
||||||
|
/// Assignment
|
||||||
|
void operator= (const wxRichTextCompositeObject& obj) { Copy(obj); }
|
||||||
|
|
||||||
/// Append a child, returning the position
|
/// Append a child, returning the position
|
||||||
size_t AppendChild(wxRichTextObject* child) ;
|
size_t AppendChild(wxRichTextObject* child) ;
|
||||||
|
|
||||||
@@ -827,7 +833,7 @@ public:
|
|||||||
// Constructors
|
// Constructors
|
||||||
|
|
||||||
wxRichTextParagraphLayoutBox(wxRichTextObject* parent = NULL);
|
wxRichTextParagraphLayoutBox(wxRichTextObject* parent = NULL);
|
||||||
wxRichTextParagraphLayoutBox(const wxRichTextParagraphLayoutBox& obj):wxRichTextBox() { Init(); Copy(obj); }
|
wxRichTextParagraphLayoutBox(const wxRichTextParagraphLayoutBox& obj): wxRichTextBox() { Init(); Copy(obj); }
|
||||||
|
|
||||||
// Overrideables
|
// Overrideables
|
||||||
|
|
||||||
@@ -855,6 +861,10 @@ public:
|
|||||||
/// Get the associated control.
|
/// Get the associated control.
|
||||||
wxRichTextCtrl* GetRichTextCtrl() const { return m_ctrl; }
|
wxRichTextCtrl* GetRichTextCtrl() const { return m_ctrl; }
|
||||||
|
|
||||||
|
/// Get/set whether the last paragraph is partial or complete
|
||||||
|
void SetPartialParagraph(bool partialPara) { m_partialParagraph = partialPara; }
|
||||||
|
bool GetPartialParagraph() const { return m_partialParagraph; }
|
||||||
|
|
||||||
// Operations
|
// Operations
|
||||||
|
|
||||||
/// Initialize the object.
|
/// Initialize the object.
|
||||||
@@ -962,10 +972,10 @@ public:
|
|||||||
/// Insert fragment into this box at the given position. If partialParagraph is true,
|
/// Insert fragment into this box at the given position. If partialParagraph is true,
|
||||||
/// it is assumed that the last (or only) paragraph is just a piece of data with no paragraph
|
/// it is assumed that the last (or only) paragraph is just a piece of data with no paragraph
|
||||||
/// marker.
|
/// marker.
|
||||||
virtual bool InsertFragment(long position, wxRichTextFragment& fragment);
|
virtual bool InsertFragment(long position, wxRichTextParagraphLayoutBox& fragment);
|
||||||
|
|
||||||
/// Make a copy of the fragment corresponding to the given range, putting it in 'fragment'.
|
/// Make a copy of the fragment corresponding to the given range, putting it in 'fragment'.
|
||||||
virtual bool CopyFragment(const wxRichTextRange& range, wxRichTextFragment& fragment);
|
virtual bool CopyFragment(const wxRichTextRange& range, wxRichTextParagraphLayoutBox& fragment);
|
||||||
|
|
||||||
/// Apply the style sheet to the buffer, for example if the styles have changed.
|
/// Apply the style sheet to the buffer, for example if the styles have changed.
|
||||||
virtual bool ApplyStyleSheet(wxRichTextStyleSheet* styleSheet);
|
virtual bool ApplyStyleSheet(wxRichTextStyleSheet* styleSheet);
|
||||||
@@ -973,6 +983,9 @@ public:
|
|||||||
/// Copy
|
/// Copy
|
||||||
void Copy(const wxRichTextParagraphLayoutBox& obj);
|
void Copy(const wxRichTextParagraphLayoutBox& obj);
|
||||||
|
|
||||||
|
/// Assignment
|
||||||
|
void operator= (const wxRichTextParagraphLayoutBox& obj) { Copy(obj); }
|
||||||
|
|
||||||
/// Calculate ranges
|
/// Calculate ranges
|
||||||
virtual void UpdateRanges() { long end; CalculateRange(0, end); }
|
virtual void UpdateRanges() { long end; CalculateRange(0, end); }
|
||||||
|
|
||||||
@@ -1005,43 +1018,6 @@ protected:
|
|||||||
|
|
||||||
/// The invalidated range that will need full layout
|
/// The invalidated range that will need full layout
|
||||||
wxRichTextRange m_invalidRange;
|
wxRichTextRange m_invalidRange;
|
||||||
};
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* wxRichTextFragment class declaration
|
|
||||||
* This is a lind of paragraph layout box used for storing
|
|
||||||
* paragraphs for Undo/Redo, for example.
|
|
||||||
*/
|
|
||||||
|
|
||||||
class WXDLLIMPEXP_RICHTEXT wxRichTextFragment: public wxRichTextParagraphLayoutBox
|
|
||||||
{
|
|
||||||
DECLARE_DYNAMIC_CLASS(wxRichTextFragment)
|
|
||||||
public:
|
|
||||||
// Constructors
|
|
||||||
|
|
||||||
wxRichTextFragment() { Init(); }
|
|
||||||
wxRichTextFragment(const wxRichTextFragment& obj):wxRichTextParagraphLayoutBox() { Init(); Copy(obj); }
|
|
||||||
|
|
||||||
// Accessors
|
|
||||||
|
|
||||||
/// Get/set whether the last paragraph is partial or complete
|
|
||||||
void SetPartialParagraph(bool partialPara) { m_partialParagraph = partialPara; }
|
|
||||||
bool GetPartialParagraph() const { return m_partialParagraph; }
|
|
||||||
|
|
||||||
// Overrideables
|
|
||||||
|
|
||||||
// Operations
|
|
||||||
|
|
||||||
/// Initialise
|
|
||||||
void Init();
|
|
||||||
|
|
||||||
/// Copy
|
|
||||||
void Copy(const wxRichTextFragment& obj);
|
|
||||||
|
|
||||||
/// Clone
|
|
||||||
virtual wxRichTextObject* Clone() const { return new wxRichTextFragment(*this); }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
// Is the last paragraph partial or complete?
|
// Is the last paragraph partial or complete?
|
||||||
bool m_partialParagraph;
|
bool m_partialParagraph;
|
||||||
@@ -1143,7 +1119,7 @@ public:
|
|||||||
wxRichTextParagraph(wxRichTextObject* parent = NULL, wxTextAttrEx* style = NULL);
|
wxRichTextParagraph(wxRichTextObject* parent = NULL, wxTextAttrEx* style = NULL);
|
||||||
wxRichTextParagraph(const wxString& text, wxRichTextObject* parent = NULL, wxTextAttrEx* style = NULL);
|
wxRichTextParagraph(const wxString& text, wxRichTextObject* parent = NULL, wxTextAttrEx* style = NULL);
|
||||||
virtual ~wxRichTextParagraph();
|
virtual ~wxRichTextParagraph();
|
||||||
wxRichTextParagraph(const wxRichTextParagraph& obj):wxRichTextBox() { Copy(obj); }
|
wxRichTextParagraph(const wxRichTextParagraph& obj): wxRichTextBox() { Copy(obj); }
|
||||||
|
|
||||||
// Overrideables
|
// Overrideables
|
||||||
|
|
||||||
@@ -1245,7 +1221,7 @@ public:
|
|||||||
// Constructors
|
// Constructors
|
||||||
|
|
||||||
wxRichTextPlainText(const wxString& text = wxEmptyString, wxRichTextObject* parent = NULL, wxTextAttrEx* style = NULL);
|
wxRichTextPlainText(const wxString& text = wxEmptyString, wxRichTextObject* parent = NULL, wxTextAttrEx* style = NULL);
|
||||||
wxRichTextPlainText(const wxRichTextPlainText& obj):wxRichTextObject() { Copy(obj); }
|
wxRichTextPlainText(const wxRichTextPlainText& obj): wxRichTextObject() { Copy(obj); }
|
||||||
|
|
||||||
// Overrideables
|
// Overrideables
|
||||||
|
|
||||||
@@ -1397,10 +1373,10 @@ class WXDLLIMPEXP_RICHTEXT wxRichTextImage: public wxRichTextObject
|
|||||||
public:
|
public:
|
||||||
// Constructors
|
// Constructors
|
||||||
|
|
||||||
wxRichTextImage(wxRichTextObject* parent = NULL):wxRichTextObject(parent) { }
|
wxRichTextImage(wxRichTextObject* parent = NULL): wxRichTextObject(parent) { }
|
||||||
wxRichTextImage(const wxImage& image, wxRichTextObject* parent = NULL);
|
wxRichTextImage(const wxImage& image, wxRichTextObject* parent = NULL);
|
||||||
wxRichTextImage(const wxRichTextImageBlock& imageBlock, wxRichTextObject* parent = NULL);
|
wxRichTextImage(const wxRichTextImageBlock& imageBlock, wxRichTextObject* parent = NULL);
|
||||||
wxRichTextImage(const wxRichTextImage& obj):wxRichTextObject() { Copy(obj); }
|
wxRichTextImage(const wxRichTextImage& obj): wxRichTextObject() { Copy(obj); }
|
||||||
|
|
||||||
// Overrideables
|
// Overrideables
|
||||||
|
|
||||||
@@ -1465,7 +1441,7 @@ public:
|
|||||||
// Constructors
|
// Constructors
|
||||||
|
|
||||||
wxRichTextBuffer() { Init(); }
|
wxRichTextBuffer() { Init(); }
|
||||||
wxRichTextBuffer(const wxRichTextBuffer& obj):wxRichTextParagraphLayoutBox() { Init(); Copy(obj); }
|
wxRichTextBuffer(const wxRichTextBuffer& obj): wxRichTextParagraphLayoutBox() { Init(); Copy(obj); }
|
||||||
virtual ~wxRichTextBuffer() ;
|
virtual ~wxRichTextBuffer() ;
|
||||||
|
|
||||||
// Accessors
|
// Accessors
|
||||||
@@ -1501,7 +1477,7 @@ public:
|
|||||||
virtual bool SaveFile(wxOutputStream& stream, int type = wxRICHTEXT_TYPE_ANY);
|
virtual bool SaveFile(wxOutputStream& stream, int type = wxRICHTEXT_TYPE_ANY);
|
||||||
|
|
||||||
/// Convenience function to add a paragraph of text
|
/// Convenience function to add a paragraph of text
|
||||||
virtual wxRichTextRange AddParagraph(const wxString& text) { Modify(); return wxRichTextParagraphLayoutBox::AddParagraph(text); }
|
virtual wxRichTextRange AddParagraph(const wxString& text, wxTextAttrEx* paraStyle = NULL) { Modify(); return wxRichTextParagraphLayoutBox::AddParagraph(text, paraStyle); }
|
||||||
|
|
||||||
/// Begin collapsing undo/redo commands. Note that this may not work properly
|
/// Begin collapsing undo/redo commands. Note that this may not work properly
|
||||||
/// if combining commands that delete or insert content, changing ranges for
|
/// if combining commands that delete or insert content, changing ranges for
|
||||||
@@ -1649,11 +1625,14 @@ public:
|
|||||||
// Implementation
|
// Implementation
|
||||||
|
|
||||||
/// Copy
|
/// Copy
|
||||||
void Copy(const wxRichTextBuffer& obj) { wxRichTextBox::Copy(obj); }
|
void Copy(const wxRichTextBuffer& obj);
|
||||||
|
|
||||||
/// Clone
|
/// Clone
|
||||||
virtual wxRichTextObject* Clone() const { return new wxRichTextBuffer(*this); }
|
virtual wxRichTextObject* Clone() const { return new wxRichTextBuffer(*this); }
|
||||||
|
|
||||||
|
/// Submit command to insert paragraphs
|
||||||
|
bool InsertParagraphsWithUndo(long pos, const wxRichTextParagraphLayoutBox& paragraphs, wxRichTextCtrl* ctrl, int flags = 0);
|
||||||
|
|
||||||
/// Submit command to insert the given text
|
/// Submit command to insert the given text
|
||||||
bool InsertTextWithUndo(long pos, const wxString& text, wxRichTextCtrl* ctrl, int flags = 0);
|
bool InsertTextWithUndo(long pos, const wxString& text, wxRichTextCtrl* ctrl, int flags = 0);
|
||||||
|
|
||||||
@@ -1807,11 +1786,11 @@ public:
|
|||||||
void UpdateAppearance(long caretPosition, bool sendUpdateEvent = false);
|
void UpdateAppearance(long caretPosition, bool sendUpdateEvent = false);
|
||||||
|
|
||||||
/// Replace the buffer paragraphs with the given fragment.
|
/// Replace the buffer paragraphs with the given fragment.
|
||||||
void ApplyParagraphs(const wxRichTextFragment& fragment);
|
void ApplyParagraphs(const wxRichTextParagraphLayoutBox& fragment);
|
||||||
|
|
||||||
/// Get the fragments
|
/// Get the fragments
|
||||||
wxRichTextFragment& GetNewParagraphs() { return m_newParagraphs; }
|
wxRichTextParagraphLayoutBox& GetNewParagraphs() { return m_newParagraphs; }
|
||||||
wxRichTextFragment& GetOldParagraphs() { return m_oldParagraphs; }
|
wxRichTextParagraphLayoutBox& GetOldParagraphs() { return m_oldParagraphs; }
|
||||||
|
|
||||||
/// Set/get the position used for e.g. insertion
|
/// Set/get the position used for e.g. insertion
|
||||||
void SetPosition(long pos) { m_position = pos; }
|
void SetPosition(long pos) { m_position = pos; }
|
||||||
@@ -1835,10 +1814,10 @@ protected:
|
|||||||
wxRichTextCtrl* m_ctrl;
|
wxRichTextCtrl* m_ctrl;
|
||||||
|
|
||||||
// Stores the new paragraphs
|
// Stores the new paragraphs
|
||||||
wxRichTextFragment m_newParagraphs;
|
wxRichTextParagraphLayoutBox m_newParagraphs;
|
||||||
|
|
||||||
// Stores the old paragraphs
|
// Stores the old paragraphs
|
||||||
wxRichTextFragment m_oldParagraphs;
|
wxRichTextParagraphLayoutBox m_oldParagraphs;
|
||||||
|
|
||||||
// The affected range
|
// The affected range
|
||||||
wxRichTextRange m_range;
|
wxRichTextRange m_range;
|
||||||
@@ -1947,6 +1926,48 @@ protected:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if wxUSE_DATAOBJ
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* The data object for a wxRichTextBuffer
|
||||||
|
*/
|
||||||
|
|
||||||
|
class wxRichTextBufferDataObject: public wxDataObjectSimple
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// ctor doesn't copy the pointer, so it shouldn't go away while this object
|
||||||
|
// is alive
|
||||||
|
wxRichTextBufferDataObject(wxRichTextBuffer* richTextBuffer = (wxRichTextBuffer*) NULL);
|
||||||
|
virtual ~wxRichTextBufferDataObject();
|
||||||
|
|
||||||
|
// after a call to this function, the buffer is owned by the caller and it
|
||||||
|
// is responsible for deleting it
|
||||||
|
wxRichTextBuffer* GetRichTextBuffer();
|
||||||
|
|
||||||
|
// Returns the id for the new data format
|
||||||
|
static const wxChar* GetRichTextBufferFormatId() { return ms_richTextBufferFormatId; }
|
||||||
|
|
||||||
|
// base class pure virtuals
|
||||||
|
|
||||||
|
virtual wxDataFormat GetPreferredFormat(Direction dir) const;
|
||||||
|
virtual size_t GetDataSize() const;
|
||||||
|
virtual bool GetDataHere(void *pBuf) const;
|
||||||
|
virtual bool SetData(size_t len, const void *buf);
|
||||||
|
|
||||||
|
// prevent warnings
|
||||||
|
|
||||||
|
virtual size_t GetDataSize(const wxDataFormat&) const { return GetDataSize(); }
|
||||||
|
virtual bool GetDataHere(const wxDataFormat&, void *buf) const { return GetDataHere(buf); }
|
||||||
|
virtual bool SetData(const wxDataFormat&, size_t len, const void *buf) { return SetData(len, buf); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
wxDataFormat m_formatRichTextBuffer; // our custom format
|
||||||
|
wxRichTextBuffer* m_richTextBuffer; // our data
|
||||||
|
static const wxChar* ms_richTextBufferFormatId; // our format id
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Utilities
|
* Utilities
|
||||||
*
|
*
|
||||||
|
@@ -390,6 +390,9 @@ public:
|
|||||||
/// Clear the selection
|
/// Clear the selection
|
||||||
virtual void SelectNone();
|
virtual void SelectNone();
|
||||||
|
|
||||||
|
/// Select the word at the given character position
|
||||||
|
virtual bool SelectWord(long position);
|
||||||
|
|
||||||
/// Get/set the selection range in character positions. -1, -1 means no selection.
|
/// Get/set the selection range in character positions. -1, -1 means no selection.
|
||||||
/// The range is in API convention, i.e. a single character selection is denoted
|
/// The range is in API convention, i.e. a single character selection is denoted
|
||||||
/// by (n, n+1)
|
/// by (n, n+1)
|
||||||
|
@@ -33,6 +33,7 @@
|
|||||||
#include "wx/wfstream.h"
|
#include "wx/wfstream.h"
|
||||||
#include "wx/mstream.h"
|
#include "wx/mstream.h"
|
||||||
#include "wx/sstream.h"
|
#include "wx/sstream.h"
|
||||||
|
#include "wx/textfile.h"
|
||||||
|
|
||||||
#include "wx/richtext/richtextctrl.h"
|
#include "wx/richtext/richtextctrl.h"
|
||||||
#include "wx/richtext/richtextstyles.h"
|
#include "wx/richtext/richtextstyles.h"
|
||||||
@@ -491,6 +492,7 @@ void wxRichTextParagraphLayoutBox::Init()
|
|||||||
m_rightMargin = 4;
|
m_rightMargin = 4;
|
||||||
m_topMargin = 4;
|
m_topMargin = 4;
|
||||||
m_bottomMargin = 4;
|
m_bottomMargin = 4;
|
||||||
|
m_partialParagraph = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Draw the item
|
/// Draw the item
|
||||||
@@ -659,6 +661,8 @@ bool wxRichTextParagraphLayoutBox::Layout(wxDC& dc, const wxRect& rect, int styl
|
|||||||
void wxRichTextParagraphLayoutBox::Copy(const wxRichTextParagraphLayoutBox& obj)
|
void wxRichTextParagraphLayoutBox::Copy(const wxRichTextParagraphLayoutBox& obj)
|
||||||
{
|
{
|
||||||
wxRichTextBox::Copy(obj);
|
wxRichTextBox::Copy(obj);
|
||||||
|
|
||||||
|
m_partialParagraph = obj.m_partialParagraph;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get/set the size for the given range.
|
/// Get/set the size for the given range.
|
||||||
@@ -924,21 +928,36 @@ wxRichTextRange wxRichTextParagraphLayoutBox::AddParagraphs(const wxString& text
|
|||||||
wxRichTextParagraph* lastPara = NULL;
|
wxRichTextParagraph* lastPara = NULL;
|
||||||
|
|
||||||
wxRichTextRange range(-1, -1);
|
wxRichTextRange range(-1, -1);
|
||||||
|
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
size_t len = text.length();
|
size_t len = text.length();
|
||||||
wxString line;
|
wxString line;
|
||||||
|
wxRichTextParagraph* para = new wxRichTextParagraph(wxT(""), this, & style);
|
||||||
|
if (paraStyle)
|
||||||
|
para->SetAttributes(*paraStyle);
|
||||||
|
|
||||||
|
AppendChild(para);
|
||||||
|
|
||||||
|
firstPara = para;
|
||||||
|
lastPara = para;
|
||||||
|
|
||||||
while (i < len)
|
while (i < len)
|
||||||
{
|
{
|
||||||
wxChar ch = text[i];
|
wxChar ch = text[i];
|
||||||
if (ch == wxT('\n') || ch == wxT('\r'))
|
if (ch == wxT('\n') || ch == wxT('\r'))
|
||||||
{
|
{
|
||||||
wxRichTextParagraph* para = new wxRichTextParagraph(line, this, & style);
|
wxRichTextPlainText* plainText = (wxRichTextPlainText*) para->GetChildren().GetFirst()->GetData();
|
||||||
|
plainText->SetText(line);
|
||||||
|
|
||||||
|
para = new wxRichTextParagraph(wxT(""), this, & style);
|
||||||
if (paraStyle)
|
if (paraStyle)
|
||||||
para->SetAttributes(*paraStyle);
|
para->SetAttributes(*paraStyle);
|
||||||
|
|
||||||
AppendChild(para);
|
AppendChild(para);
|
||||||
if (!firstPara)
|
|
||||||
firstPara = para;
|
//if (!firstPara)
|
||||||
|
// firstPara = para;
|
||||||
|
|
||||||
lastPara = para;
|
lastPara = para;
|
||||||
line = wxEmptyString;
|
line = wxEmptyString;
|
||||||
}
|
}
|
||||||
@@ -947,16 +966,14 @@ wxRichTextRange wxRichTextParagraphLayoutBox::AddParagraphs(const wxString& text
|
|||||||
|
|
||||||
i ++;
|
i ++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!line.empty())
|
if (!line.empty())
|
||||||
{
|
{
|
||||||
lastPara = new wxRichTextParagraph(line, this, & style);
|
wxRichTextPlainText* plainText = (wxRichTextPlainText*) para->GetChildren().GetFirst()->GetData();
|
||||||
if (paraStyle)
|
plainText->SetText(line);
|
||||||
lastPara->SetAttributes(*paraStyle);
|
|
||||||
|
|
||||||
//wxLogDebug("Para Face = %s", lastPara->GetAttributes().GetFont().GetFaceName());
|
|
||||||
AppendChild(lastPara);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
if (firstPara)
|
if (firstPara)
|
||||||
range.SetStart(firstPara->GetRange().GetStart());
|
range.SetStart(firstPara->GetRange().GetStart());
|
||||||
else if (lastPara)
|
else if (lastPara)
|
||||||
@@ -966,11 +983,13 @@ wxRichTextRange wxRichTextParagraphLayoutBox::AddParagraphs(const wxString& text
|
|||||||
range.SetEnd(lastPara->GetRange().GetEnd());
|
range.SetEnd(lastPara->GetRange().GetEnd());
|
||||||
else if (firstPara)
|
else if (firstPara)
|
||||||
range.SetEnd(firstPara->GetRange().GetEnd());
|
range.SetEnd(firstPara->GetRange().GetEnd());
|
||||||
|
*/
|
||||||
|
|
||||||
UpdateRanges();
|
UpdateRanges();
|
||||||
|
|
||||||
SetDirty(false);
|
SetDirty(false);
|
||||||
|
|
||||||
return GetRange();
|
return wxRichTextRange(firstPara->GetRange().GetStart(), lastPara->GetRange().GetEnd());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convenience function to add an image
|
/// Convenience function to add an image
|
||||||
@@ -1009,7 +1028,7 @@ wxRichTextRange wxRichTextParagraphLayoutBox::AddImage(const wxImage& image, wxT
|
|||||||
/// TODO: if fragment is inserted inside styled fragment, must apply that style to
|
/// TODO: if fragment is inserted inside styled fragment, must apply that style to
|
||||||
/// to the data (if it has a default style, anyway).
|
/// to the data (if it has a default style, anyway).
|
||||||
|
|
||||||
bool wxRichTextParagraphLayoutBox::InsertFragment(long position, wxRichTextFragment& fragment)
|
bool wxRichTextParagraphLayoutBox::InsertFragment(long position, wxRichTextParagraphLayoutBox& fragment)
|
||||||
{
|
{
|
||||||
SetDirty(true);
|
SetDirty(true);
|
||||||
|
|
||||||
@@ -1174,7 +1193,7 @@ bool wxRichTextParagraphLayoutBox::InsertFragment(long position, wxRichTextFragm
|
|||||||
|
|
||||||
/// Make a copy of the fragment corresponding to the given range, putting it in 'fragment'.
|
/// Make a copy of the fragment corresponding to the given range, putting it in 'fragment'.
|
||||||
/// If there was an incomplete paragraph at the end, partialParagraph is set to true.
|
/// If there was an incomplete paragraph at the end, partialParagraph is set to true.
|
||||||
bool wxRichTextParagraphLayoutBox::CopyFragment(const wxRichTextRange& range, wxRichTextFragment& fragment)
|
bool wxRichTextParagraphLayoutBox::CopyFragment(const wxRichTextRange& range, wxRichTextParagraphLayoutBox& fragment)
|
||||||
{
|
{
|
||||||
wxRichTextObjectList::compatibility_iterator i = GetChildren().GetFirst();
|
wxRichTextObjectList::compatibility_iterator i = GetChildren().GetFirst();
|
||||||
while (i)
|
while (i)
|
||||||
@@ -1977,29 +1996,6 @@ bool wxRichTextParagraphLayoutBox::ApplyStyleSheet(wxRichTextStyleSheet* styleSh
|
|||||||
return foundCount != 0;
|
return foundCount != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* wxRichTextFragment class declaration
|
|
||||||
* This is a lind of paragraph layout box used for storing
|
|
||||||
* paragraphs for Undo/Redo, for example.
|
|
||||||
*/
|
|
||||||
|
|
||||||
IMPLEMENT_DYNAMIC_CLASS(wxRichTextFragment, wxRichTextParagraphLayoutBox)
|
|
||||||
|
|
||||||
/// Initialise
|
|
||||||
void wxRichTextFragment::Init()
|
|
||||||
{
|
|
||||||
m_partialParagraph = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Copy
|
|
||||||
void wxRichTextFragment::Copy(const wxRichTextFragment& obj)
|
|
||||||
{
|
|
||||||
wxRichTextParagraphLayoutBox::Copy(obj);
|
|
||||||
|
|
||||||
m_partialParagraph = obj.m_partialParagraph;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* wxRichTextParagraph
|
* wxRichTextParagraph
|
||||||
* This object represents a single paragraph (or in a straight text editor, a line).
|
* This object represents a single paragraph (or in a straight text editor, a line).
|
||||||
@@ -2586,8 +2582,6 @@ bool wxRichTextParagraph::FindPosition(wxDC& dc, long index, wxPoint& pt, int* h
|
|||||||
if (line)
|
if (line)
|
||||||
pt = pt + line->GetPosition();
|
pt = pt + line->GetPosition();
|
||||||
|
|
||||||
*height = dc.GetCharHeight();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3543,6 +3537,49 @@ void wxRichTextBuffer::Reset()
|
|||||||
Invalidate(wxRICHTEXT_ALL);
|
Invalidate(wxRICHTEXT_ALL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wxRichTextBuffer::Copy(const wxRichTextBuffer& obj)
|
||||||
|
{
|
||||||
|
wxRichTextParagraphLayoutBox::Copy(obj);
|
||||||
|
|
||||||
|
m_styleSheet = obj.m_styleSheet;
|
||||||
|
m_modified = obj.m_modified;
|
||||||
|
m_batchedCommandDepth = obj.m_batchedCommandDepth;
|
||||||
|
m_batchedCommand = obj.m_batchedCommand;
|
||||||
|
m_suppressUndo = obj.m_suppressUndo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Submit command to insert paragraphs
|
||||||
|
bool wxRichTextBuffer::InsertParagraphsWithUndo(long pos, const wxRichTextParagraphLayoutBox& paragraphs, wxRichTextCtrl* ctrl, int flags)
|
||||||
|
{
|
||||||
|
wxRichTextAction* action = new wxRichTextAction(NULL, _("Insert Text"), wxRICHTEXT_INSERT, this, ctrl, false);
|
||||||
|
|
||||||
|
wxTextAttrEx* p = NULL;
|
||||||
|
wxTextAttrEx paraAttr;
|
||||||
|
if (flags & wxRICHTEXT_INSERT_WITH_PREVIOUS_PARAGRAPH_STYLE)
|
||||||
|
{
|
||||||
|
paraAttr = GetStyleForNewParagraph(pos);
|
||||||
|
if (!paraAttr.IsDefault())
|
||||||
|
p = & paraAttr;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if wxRICHTEXT_USE_DYNAMIC_STYLES
|
||||||
|
wxTextAttrEx attr(GetDefaultStyle());
|
||||||
|
#else
|
||||||
|
wxTextAttrEx attr(GetBasicStyle());
|
||||||
|
wxRichTextApplyStyle(attr, GetDefaultStyle());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
action->GetNewParagraphs() = paragraphs;
|
||||||
|
action->SetPosition(pos);
|
||||||
|
|
||||||
|
// Set the range we'll need to delete in Undo
|
||||||
|
action->SetRange(wxRichTextRange(pos, pos + paragraphs.GetRange().GetEnd() - 1));
|
||||||
|
|
||||||
|
SubmitAction(action);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/// Submit command to insert the given text
|
/// Submit command to insert the given text
|
||||||
bool wxRichTextBuffer::InsertTextWithUndo(long pos, const wxString& text, wxRichTextCtrl* ctrl, int flags)
|
bool wxRichTextBuffer::InsertTextWithUndo(long pos, const wxString& text, wxRichTextCtrl* ctrl, int flags)
|
||||||
{
|
{
|
||||||
@@ -3565,13 +3602,20 @@ bool wxRichTextBuffer::InsertTextWithUndo(long pos, const wxString& text, wxRich
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
action->GetNewParagraphs().AddParagraphs(text, p);
|
action->GetNewParagraphs().AddParagraphs(text, p);
|
||||||
if (action->GetNewParagraphs().GetChildCount() == 1 && text.Find(wxT("\n")) == wxNOT_FOUND)
|
|
||||||
|
int length = action->GetNewParagraphs().GetRange().GetLength();
|
||||||
|
|
||||||
|
if (text.length() > 0 && text.Last() != wxT('\n'))
|
||||||
|
{
|
||||||
|
// Don't count the newline when undoing
|
||||||
|
length --;
|
||||||
action->GetNewParagraphs().SetPartialParagraph(true);
|
action->GetNewParagraphs().SetPartialParagraph(true);
|
||||||
|
}
|
||||||
|
|
||||||
action->SetPosition(pos);
|
action->SetPosition(pos);
|
||||||
|
|
||||||
// Set the range we'll need to delete in Undo
|
// Set the range we'll need to delete in Undo
|
||||||
action->SetRange(wxRichTextRange(pos, pos + text.length() - 1));
|
action->SetRange(wxRichTextRange(pos, pos + length - 1));
|
||||||
|
|
||||||
SubmitAction(action);
|
SubmitAction(action);
|
||||||
|
|
||||||
@@ -4062,12 +4106,14 @@ wxRichTextFileHandler *wxRichTextBuffer::FindHandlerFilenameOrType(const wxStrin
|
|||||||
{
|
{
|
||||||
if (imageType != wxRICHTEXT_TYPE_ANY)
|
if (imageType != wxRICHTEXT_TYPE_ANY)
|
||||||
return FindHandler(imageType);
|
return FindHandler(imageType);
|
||||||
else
|
else if (!filename.IsEmpty())
|
||||||
{
|
{
|
||||||
wxString path, file, ext;
|
wxString path, file, ext;
|
||||||
wxSplitPath(filename, & path, & file, & ext);
|
wxSplitPath(filename, & path, & file, & ext);
|
||||||
return FindHandler(ext, imageType);
|
return FindHandler(ext, imageType);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -4234,12 +4280,41 @@ bool wxRichTextBuffer::CopyToClipboard(const wxRichTextRange& range)
|
|||||||
{
|
{
|
||||||
bool success = false;
|
bool success = false;
|
||||||
#if wxUSE_CLIPBOARD && wxUSE_DATAOBJ
|
#if wxUSE_CLIPBOARD && wxUSE_DATAOBJ
|
||||||
wxString text = GetTextForRange(range);
|
|
||||||
if (!wxTheClipboard->IsOpened() && wxTheClipboard->Open())
|
if (!wxTheClipboard->IsOpened() && wxTheClipboard->Open())
|
||||||
{
|
{
|
||||||
success = wxTheClipboard->SetData(new wxTextDataObject(text));
|
wxTheClipboard->Clear();
|
||||||
|
|
||||||
|
// Add composite object
|
||||||
|
|
||||||
|
wxDataObjectComposite* compositeObject = new wxDataObjectComposite();
|
||||||
|
|
||||||
|
{
|
||||||
|
wxString text = GetTextForRange(range);
|
||||||
|
|
||||||
|
#ifdef __WXMSW__
|
||||||
|
text = wxTextFile::Translate(text, wxTextFileType_Dos);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
compositeObject->Add(new wxTextDataObject(text), false /* not preferred */);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add rich text buffer data object. This needs the XML handler to be present.
|
||||||
|
|
||||||
|
if (FindHandler(wxRICHTEXT_TYPE_XML))
|
||||||
|
{
|
||||||
|
wxRichTextBuffer* richTextBuf = new wxRichTextBuffer;
|
||||||
|
CopyFragment(range, *richTextBuf);
|
||||||
|
|
||||||
|
compositeObject->Add(new wxRichTextBufferDataObject(richTextBuf), true /* preferred */);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wxTheClipboard->SetData(compositeObject))
|
||||||
|
success = true;
|
||||||
|
|
||||||
wxTheClipboard->Close();
|
wxTheClipboard->Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
wxUnusedVar(range);
|
wxUnusedVar(range);
|
||||||
#endif
|
#endif
|
||||||
@@ -4255,7 +4330,18 @@ bool wxRichTextBuffer::PasteFromClipboard(long position)
|
|||||||
{
|
{
|
||||||
if (wxTheClipboard->Open())
|
if (wxTheClipboard->Open())
|
||||||
{
|
{
|
||||||
if (wxTheClipboard->IsSupported(wxDF_TEXT))
|
if (wxTheClipboard->IsSupported(wxDataFormat(wxRichTextBufferDataObject::GetRichTextBufferFormatId())))
|
||||||
|
{
|
||||||
|
wxRichTextBufferDataObject data;
|
||||||
|
wxTheClipboard->GetData(data);
|
||||||
|
wxRichTextBuffer* richTextBuffer = data.GetRichTextBuffer();
|
||||||
|
if (richTextBuffer)
|
||||||
|
{
|
||||||
|
InsertParagraphsWithUndo(position+1, *richTextBuffer, GetRichTextCtrl(), wxRICHTEXT_INSERT_WITH_PREVIOUS_PARAGRAPH_STYLE);
|
||||||
|
delete richTextBuffer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (wxTheClipboard->IsSupported(wxDF_TEXT) || wxTheClipboard->IsSupported(wxDF_UNICODETEXT))
|
||||||
{
|
{
|
||||||
wxTextDataObject data;
|
wxTextDataObject data;
|
||||||
wxTheClipboard->GetData(data);
|
wxTheClipboard->GetData(data);
|
||||||
@@ -4305,7 +4391,9 @@ bool wxRichTextBuffer::CanPasteFromClipboard() const
|
|||||||
#if wxUSE_CLIPBOARD && wxUSE_DATAOBJ
|
#if wxUSE_CLIPBOARD && wxUSE_DATAOBJ
|
||||||
if (!wxTheClipboard->IsOpened() && wxTheClipboard->Open())
|
if (!wxTheClipboard->IsOpened() && wxTheClipboard->Open())
|
||||||
{
|
{
|
||||||
if (wxTheClipboard->IsSupported(wxDF_TEXT) || wxTheClipboard->IsSupported(wxDF_BITMAP))
|
if (wxTheClipboard->IsSupported(wxDF_TEXT) || wxTheClipboard->IsSupported(wxDF_UNICODETEXT) ||
|
||||||
|
wxTheClipboard->IsSupported(wxDataFormat(wxRichTextBufferDataObject::GetRichTextBufferFormatId())) ||
|
||||||
|
wxTheClipboard->IsSupported(wxDF_BITMAP))
|
||||||
{
|
{
|
||||||
canPaste = true;
|
canPaste = true;
|
||||||
}
|
}
|
||||||
@@ -4434,10 +4522,17 @@ bool wxRichTextAction::Do()
|
|||||||
m_buffer->UpdateRanges();
|
m_buffer->UpdateRanges();
|
||||||
m_buffer->Invalidate(GetRange());
|
m_buffer->Invalidate(GetRange());
|
||||||
|
|
||||||
long newCaretPosition = GetPosition() + m_newParagraphs.GetRange().GetLength() - 1;
|
long newCaretPosition = GetPosition() + m_newParagraphs.GetRange().GetLength();
|
||||||
|
|
||||||
|
// Character position to caret position
|
||||||
|
newCaretPosition --;
|
||||||
|
|
||||||
|
// Don't take into account the last newline
|
||||||
if (m_newParagraphs.GetPartialParagraph())
|
if (m_newParagraphs.GetPartialParagraph())
|
||||||
newCaretPosition --;
|
newCaretPosition --;
|
||||||
|
|
||||||
|
newCaretPosition = wxMin(newCaretPosition, (m_buffer->GetRange().GetEnd()-1));
|
||||||
|
|
||||||
UpdateAppearance(newCaretPosition, true /* send update event */);
|
UpdateAppearance(newCaretPosition, true /* send update event */);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -4533,7 +4628,7 @@ void wxRichTextAction::UpdateAppearance(long caretPosition, bool sendUpdateEvent
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Replace the buffer paragraphs with the new ones.
|
/// Replace the buffer paragraphs with the new ones.
|
||||||
void wxRichTextAction::ApplyParagraphs(const wxRichTextFragment& fragment)
|
void wxRichTextAction::ApplyParagraphs(const wxRichTextParagraphLayoutBox& fragment)
|
||||||
{
|
{
|
||||||
wxRichTextObjectList::compatibility_iterator node = fragment.GetChildren().GetFirst();
|
wxRichTextObjectList::compatibility_iterator node = fragment.GetChildren().GetFirst();
|
||||||
while (node)
|
while (node)
|
||||||
@@ -5817,7 +5912,7 @@ bool wxRichTextImageBlock::Load(wxImage& image)
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Read in the image.
|
// Read in the image.
|
||||||
#if 1
|
#if wxUSE_STREAMS
|
||||||
wxMemoryInputStream mstream(m_data, m_dataSize);
|
wxMemoryInputStream mstream(m_data, m_dataSize);
|
||||||
bool success = image.LoadFile(mstream, GetImageType());
|
bool success = image.LoadFile(mstream, GetImageType());
|
||||||
#else
|
#else
|
||||||
@@ -5877,7 +5972,6 @@ bool wxRichTextImageBlock::ReadHex(wxInputStream& stream, int length, int imageT
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Allocate and read from stream as a block of memory
|
// Allocate and read from stream as a block of memory
|
||||||
unsigned char* wxRichTextImageBlock::ReadBlock(wxInputStream& stream, size_t size)
|
unsigned char* wxRichTextImageBlock::ReadBlock(wxInputStream& stream, size_t size)
|
||||||
{
|
{
|
||||||
@@ -5917,5 +6011,123 @@ bool wxRichTextImageBlock::WriteBlock(const wxString& filename, unsigned char* b
|
|||||||
return WriteBlock(outStream, block, size);
|
return WriteBlock(outStream, block, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if wxUSE_DATAOBJ
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* The data object for a wxRichTextBuffer
|
||||||
|
*/
|
||||||
|
|
||||||
|
const wxChar *wxRichTextBufferDataObject::ms_richTextBufferFormatId = wxT("wxShape");
|
||||||
|
|
||||||
|
wxRichTextBufferDataObject::wxRichTextBufferDataObject(wxRichTextBuffer* richTextBuffer)
|
||||||
|
{
|
||||||
|
m_richTextBuffer = richTextBuffer;
|
||||||
|
|
||||||
|
// this string should uniquely identify our format, but is otherwise
|
||||||
|
// arbitrary
|
||||||
|
m_formatRichTextBuffer.SetId(GetRichTextBufferFormatId());
|
||||||
|
|
||||||
|
SetFormat(m_formatRichTextBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
wxRichTextBufferDataObject::~wxRichTextBufferDataObject()
|
||||||
|
{
|
||||||
|
delete m_richTextBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
// after a call to this function, the richTextBuffer is owned by the caller and it
|
||||||
|
// is responsible for deleting it!
|
||||||
|
wxRichTextBuffer* wxRichTextBufferDataObject::GetRichTextBuffer()
|
||||||
|
{
|
||||||
|
wxRichTextBuffer* richTextBuffer = m_richTextBuffer;
|
||||||
|
m_richTextBuffer = NULL;
|
||||||
|
|
||||||
|
return richTextBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxDataFormat wxRichTextBufferDataObject::GetPreferredFormat(Direction WXUNUSED(dir)) const
|
||||||
|
{
|
||||||
|
return m_formatRichTextBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t wxRichTextBufferDataObject::GetDataSize() const
|
||||||
|
{
|
||||||
|
if (!m_richTextBuffer)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
wxString bufXML;
|
||||||
|
|
||||||
|
{
|
||||||
|
wxStringOutputStream stream(& bufXML);
|
||||||
|
if (!m_richTextBuffer->SaveFile(stream, wxRICHTEXT_TYPE_XML))
|
||||||
|
{
|
||||||
|
wxLogError(wxT("Could not write the buffer to an XML stream.\nYou may have forgotten to add the XML file handler."));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if wxUSE_UNICODE
|
||||||
|
wxCharBuffer buffer = bufXML.mb_str(wxConvUTF8);
|
||||||
|
return strlen(buffer) + 1;
|
||||||
|
#else
|
||||||
|
return bufXML.Length()+1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxRichTextBufferDataObject::GetDataHere(void *pBuf) const
|
||||||
|
{
|
||||||
|
if (!pBuf || !m_richTextBuffer)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
wxString bufXML;
|
||||||
|
|
||||||
|
{
|
||||||
|
wxStringOutputStream stream(& bufXML);
|
||||||
|
if (!m_richTextBuffer->SaveFile(stream, wxRICHTEXT_TYPE_XML))
|
||||||
|
{
|
||||||
|
wxLogError(wxT("Could not write the buffer to an XML stream.\nYou may have forgotten to add the XML file handler."));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if wxUSE_UNICODE
|
||||||
|
wxCharBuffer buffer = bufXML.mb_str(wxConvUTF8);
|
||||||
|
size_t len = strlen(buffer);
|
||||||
|
memcpy((char*) pBuf, (const char*) buffer, len);
|
||||||
|
((char*) pBuf)[len] = 0;
|
||||||
|
#else
|
||||||
|
size_t len = bufXML.Length();
|
||||||
|
memcpy((char*) pBuf, (const char*) bufXML.c_str(), len);
|
||||||
|
((char*) pBuf)[len] = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxRichTextBufferDataObject::SetData(size_t WXUNUSED(len), const void *buf)
|
||||||
|
{
|
||||||
|
delete m_richTextBuffer;
|
||||||
|
m_richTextBuffer = NULL;
|
||||||
|
|
||||||
|
wxString bufXML((const char*) buf, wxConvUTF8);
|
||||||
|
|
||||||
|
m_richTextBuffer = new wxRichTextBuffer;
|
||||||
|
|
||||||
|
wxStringInputStream stream(bufXML);
|
||||||
|
if (!m_richTextBuffer->LoadFile(stream, wxRICHTEXT_TYPE_XML))
|
||||||
|
{
|
||||||
|
wxLogError(wxT("Could not read the buffer from an XML stream.\nYou may have forgotten to add the XML file handler."));
|
||||||
|
|
||||||
|
delete m_richTextBuffer;
|
||||||
|
m_richTextBuffer = NULL;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
// wxUSE_DATAOBJ
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
// wxUSE_RICHTEXT
|
// wxUSE_RICHTEXT
|
||||||
|
@@ -329,19 +329,6 @@ void wxRichTextCtrl::OnLeftClick(wxMouseEvent& event)
|
|||||||
|
|
||||||
MoveCaret(position, caretAtLineStart);
|
MoveCaret(position, caretAtLineStart);
|
||||||
SetDefaultStyleToCursorStyle();
|
SetDefaultStyleToCursorStyle();
|
||||||
|
|
||||||
#if 0
|
|
||||||
wxWindow* p = GetParent();
|
|
||||||
while (p && !p->IsKindOf(CLASSINFO(wxFrame)))
|
|
||||||
p = p->GetParent();
|
|
||||||
|
|
||||||
wxFrame* frame = wxDynamicCast(p, wxFrame);
|
|
||||||
if (frame)
|
|
||||||
{
|
|
||||||
wxString msg = wxString::Format(wxT("Found position %ld"), position);
|
|
||||||
frame->SetStatusText(msg, 1);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
event.Skip();
|
event.Skip();
|
||||||
@@ -417,6 +404,7 @@ void wxRichTextCtrl::OnRightClick(wxMouseEvent& event)
|
|||||||
/// Left-double-click
|
/// Left-double-click
|
||||||
void wxRichTextCtrl::OnLeftDClick(wxMouseEvent& event)
|
void wxRichTextCtrl::OnLeftDClick(wxMouseEvent& event)
|
||||||
{
|
{
|
||||||
|
SelectWord(GetCaretPosition()+1);
|
||||||
event.Skip();
|
event.Skip();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1620,6 +1608,60 @@ void wxRichTextCtrl::SelectNone()
|
|||||||
m_selectionAnchor = -2;
|
m_selectionAnchor = -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool wxIsWordDelimiter(const wxString& text)
|
||||||
|
{
|
||||||
|
static wxString delimiters = wxT(" ,.:;!?-\"'~<7E>$%^&*()_+-=`<60>{}[]@#<>/\\|");
|
||||||
|
return !text.IsEmpty() && delimiters.Find(text) != wxNOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Select the word at the given character position
|
||||||
|
bool wxRichTextCtrl::SelectWord(long position)
|
||||||
|
{
|
||||||
|
if (position < 0 || position > GetBuffer().GetRange().GetEnd())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
wxRichTextParagraph* para = GetBuffer().GetParagraphAtPosition(position);
|
||||||
|
if (!para)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
long positionStart = position;
|
||||||
|
long positionEnd = position;
|
||||||
|
|
||||||
|
for (positionStart = position; positionStart >= para->GetRange().GetStart(); positionStart --)
|
||||||
|
{
|
||||||
|
wxString text = GetBuffer().GetTextForRange(wxRichTextRange(positionStart, positionStart));
|
||||||
|
if (wxIsWordDelimiter(text))
|
||||||
|
{
|
||||||
|
positionStart ++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (positionStart < para->GetRange().GetStart())
|
||||||
|
positionStart = para->GetRange().GetStart();
|
||||||
|
|
||||||
|
for (positionEnd = position; positionEnd < para->GetRange().GetEnd(); positionEnd ++)
|
||||||
|
{
|
||||||
|
wxString text = GetBuffer().GetTextForRange(wxRichTextRange(positionEnd, positionEnd));
|
||||||
|
if (wxIsWordDelimiter(text))
|
||||||
|
{
|
||||||
|
positionEnd --;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (positionEnd >= para->GetRange().GetEnd())
|
||||||
|
positionEnd = para->GetRange().GetEnd();
|
||||||
|
|
||||||
|
SetSelection(positionStart, positionEnd+1);
|
||||||
|
|
||||||
|
if (positionStart >= 0)
|
||||||
|
{
|
||||||
|
MoveCaret(positionStart-1, true);
|
||||||
|
SetDefaultStyleToCursorStyle();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
wxString wxRichTextCtrl::GetStringSelection() const
|
wxString wxRichTextCtrl::GetStringSelection() const
|
||||||
{
|
{
|
||||||
long from, to;
|
long from, to;
|
||||||
@@ -1743,9 +1785,9 @@ void wxRichTextCtrl::WriteText(const wxString& value)
|
|||||||
|
|
||||||
void wxRichTextCtrl::DoWriteText(const wxString& value, bool WXUNUSED(selectionOnly))
|
void wxRichTextCtrl::DoWriteText(const wxString& value, bool WXUNUSED(selectionOnly))
|
||||||
{
|
{
|
||||||
wxString valueDos = wxTextFile::Translate(value, wxTextFileType_Unix);
|
wxString valueUnix = wxTextFile::Translate(value, wxTextFileType_Unix);
|
||||||
|
|
||||||
GetBuffer().InsertTextWithUndo(m_caretPosition+1, valueDos, this);
|
GetBuffer().InsertTextWithUndo(m_caretPosition+1, valueUnix, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxRichTextCtrl::AppendText(const wxString& text)
|
void wxRichTextCtrl::AppendText(const wxString& text)
|
||||||
@@ -1951,6 +1993,7 @@ void wxRichTextCtrl::DoSetSelection(long from, long to, bool WXUNUSED(scrollCare
|
|||||||
{
|
{
|
||||||
m_selectionAnchor = from;
|
m_selectionAnchor = from;
|
||||||
m_selectionRange.SetRange(from, to-1);
|
m_selectionRange.SetRange(from, to-1);
|
||||||
|
|
||||||
Refresh(false);
|
Refresh(false);
|
||||||
PositionCaret();
|
PositionCaret();
|
||||||
}
|
}
|
||||||
@@ -2598,22 +2641,16 @@ bool wxRichTextCtrl::ApplyUnderlineToSelection()
|
|||||||
/// Is all of the selection aligned according to the specified flag?
|
/// Is all of the selection aligned according to the specified flag?
|
||||||
bool wxRichTextCtrl::IsSelectionAligned(wxTextAttrAlignment alignment)
|
bool wxRichTextCtrl::IsSelectionAligned(wxTextAttrAlignment alignment)
|
||||||
{
|
{
|
||||||
|
wxRichTextRange range;
|
||||||
if (HasSelection())
|
if (HasSelection())
|
||||||
{
|
range = GetInternalSelectionRange();
|
||||||
wxRichTextRange range = GetInternalSelectionRange();
|
else
|
||||||
|
range = wxRichTextRange(GetCaretPosition()+1, GetCaretPosition()+1);
|
||||||
|
|
||||||
wxRichTextAttr attr;
|
wxRichTextAttr attr;
|
||||||
attr.SetAlignment(alignment);
|
attr.SetAlignment(alignment);
|
||||||
|
|
||||||
return HasParagraphAttributes(range, attr);
|
return HasParagraphAttributes(range, attr);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// If no selection, then we need to get information from the current paragraph.
|
|
||||||
wxRichTextParagraph* para = GetBuffer().GetParagraphAtPosition(GetCaretPosition()+1);
|
|
||||||
if (para)
|
|
||||||
return para->GetAttributes().GetAlignment() == alignment;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Apply alignment to the selection
|
/// Apply alignment to the selection
|
||||||
|
@@ -30,6 +30,7 @@
|
|||||||
#include "wx/wfstream.h"
|
#include "wx/wfstream.h"
|
||||||
#include "wx/sstream.h"
|
#include "wx/sstream.h"
|
||||||
#include "wx/txtstrm.h"
|
#include "wx/txtstrm.h"
|
||||||
|
#include "wx/tokenzr.h"
|
||||||
#include "wx/xml/xml.h"
|
#include "wx/xml/xml.h"
|
||||||
|
|
||||||
IMPLEMENT_DYNAMIC_CLASS(wxRichTextXMLHandler, wxRichTextFileHandler)
|
IMPLEMENT_DYNAMIC_CLASS(wxRichTextXMLHandler, wxRichTextFileHandler)
|
||||||
@@ -98,6 +99,9 @@ bool wxRichTextXMLHandler::ImportXML(wxRichTextBuffer* buffer, wxXmlNode* node)
|
|||||||
|
|
||||||
if (name == wxT("paragraphlayout"))
|
if (name == wxT("paragraphlayout"))
|
||||||
{
|
{
|
||||||
|
wxString partial = node->GetPropVal(wxT("partialparagraph"), wxEmptyString);
|
||||||
|
if (partial == wxT("true"))
|
||||||
|
buffer->SetPartialParagraph(true);
|
||||||
}
|
}
|
||||||
else if (name == wxT("paragraph"))
|
else if (name == wxT("paragraph"))
|
||||||
{
|
{
|
||||||
@@ -506,6 +510,9 @@ bool wxRichTextXMLHandler::ExportXML(wxOutputStream& stream, wxMBConv* convMem,
|
|||||||
|
|
||||||
wxString style = CreateStyle(obj.GetAttributes(), isPara);
|
wxString style = CreateStyle(obj.GetAttributes(), isPara);
|
||||||
|
|
||||||
|
if (objectName == wxT("paragraphlayout") && ((wxRichTextParagraphLayoutBox&) obj).GetPartialParagraph())
|
||||||
|
style << wxT(" partialparagraph=\"true\"");
|
||||||
|
|
||||||
OutputString(stream, style + wxT(">"), convMem, convFile);
|
OutputString(stream, style + wxT(">"), convMem, convFile);
|
||||||
|
|
||||||
wxRichTextCompositeObject& composite = (wxRichTextCompositeObject&) obj;
|
wxRichTextCompositeObject& composite = (wxRichTextCompositeObject&) obj;
|
||||||
@@ -529,22 +536,33 @@ bool wxRichTextXMLHandler::ExportXML(wxOutputStream& stream, wxMBConv* convMem,
|
|||||||
wxString wxRichTextXMLHandler::CreateStyle(const wxTextAttrEx& attr, bool isPara)
|
wxString wxRichTextXMLHandler::CreateStyle(const wxTextAttrEx& attr, bool isPara)
|
||||||
{
|
{
|
||||||
wxString str;
|
wxString str;
|
||||||
if (attr.GetTextColour().Ok())
|
if (attr.HasTextColour() && attr.GetTextColour().Ok())
|
||||||
{
|
{
|
||||||
str << wxT(" textcolor=\"#") << ColourToHexString(attr.GetTextColour()) << wxT("\"");
|
str << wxT(" textcolor=\"#") << ColourToHexString(attr.GetTextColour()) << wxT("\"");
|
||||||
}
|
}
|
||||||
if (attr.GetBackgroundColour().Ok())
|
if (attr.HasBackgroundColour() && attr.GetBackgroundColour().Ok())
|
||||||
{
|
{
|
||||||
str << wxT(" bgcolor=\"#") << ColourToHexString(attr.GetBackgroundColour()) << wxT("\"");
|
str << wxT(" bgcolor=\"#") << ColourToHexString(attr.GetBackgroundColour()) << wxT("\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attr.GetFont().Ok())
|
if (attr.GetFont().Ok())
|
||||||
{
|
{
|
||||||
|
if (attr.HasSize())
|
||||||
str << wxT(" fontsize=\"") << attr.GetFont().GetPointSize() << wxT("\"");
|
str << wxT(" fontsize=\"") << attr.GetFont().GetPointSize() << wxT("\"");
|
||||||
str << wxT(" fontfamily=\"") << attr.GetFont().GetFamily() << wxT("\"");
|
|
||||||
|
//if (attr.HasFamily())
|
||||||
|
// str << wxT(" fontfamily=\"") << attr.GetFont().GetFamily() << wxT("\"");
|
||||||
|
|
||||||
|
if (attr.HasItalic())
|
||||||
str << wxT(" fontstyle=\"") << attr.GetFont().GetStyle() << wxT("\"");
|
str << wxT(" fontstyle=\"") << attr.GetFont().GetStyle() << wxT("\"");
|
||||||
|
|
||||||
|
if (attr.HasWeight())
|
||||||
str << wxT(" fontweight=\"") << attr.GetFont().GetWeight() << wxT("\"");
|
str << wxT(" fontweight=\"") << attr.GetFont().GetWeight() << wxT("\"");
|
||||||
|
|
||||||
|
if (attr.HasUnderlined())
|
||||||
str << wxT(" fontunderlined=\"") << (int) attr.GetFont().GetUnderlined() << wxT("\"");
|
str << wxT(" fontunderlined=\"") << (int) attr.GetFont().GetUnderlined() << wxT("\"");
|
||||||
|
|
||||||
|
if (attr.HasFaceName())
|
||||||
str << wxT(" fontface=\"") << attr.GetFont().GetFaceName() << wxT("\"");
|
str << wxT(" fontface=\"") << attr.GetFont().GetFaceName() << wxT("\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -553,19 +571,51 @@ wxString wxRichTextXMLHandler::CreateStyle(const wxTextAttrEx& attr, bool isPara
|
|||||||
|
|
||||||
if (isPara)
|
if (isPara)
|
||||||
{
|
{
|
||||||
|
if (attr.HasAlignment())
|
||||||
str << wxT(" alignment=\"") << (int) attr.GetAlignment() << wxT("\"");
|
str << wxT(" alignment=\"") << (int) attr.GetAlignment() << wxT("\"");
|
||||||
|
|
||||||
|
if (attr.HasLeftIndent())
|
||||||
|
{
|
||||||
str << wxT(" leftindent=\"") << (int) attr.GetLeftIndent() << wxT("\"");
|
str << wxT(" leftindent=\"") << (int) attr.GetLeftIndent() << wxT("\"");
|
||||||
str << wxT(" leftsubindent=\"") << (int) attr.GetLeftSubIndent() << wxT("\"");
|
str << wxT(" leftsubindent=\"") << (int) attr.GetLeftSubIndent() << wxT("\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attr.HasRightIndent())
|
||||||
str << wxT(" rightindent=\"") << (int) attr.GetRightIndent() << wxT("\"");
|
str << wxT(" rightindent=\"") << (int) attr.GetRightIndent() << wxT("\"");
|
||||||
|
|
||||||
|
if (attr.HasParagraphSpacingAfter())
|
||||||
str << wxT(" parspacingafter=\"") << (int) attr.GetParagraphSpacingAfter() << wxT("\"");
|
str << wxT(" parspacingafter=\"") << (int) attr.GetParagraphSpacingAfter() << wxT("\"");
|
||||||
|
|
||||||
|
if (attr.HasParagraphSpacingBefore())
|
||||||
str << wxT(" parspacingbefore=\"") << (int) attr.GetParagraphSpacingBefore() << wxT("\"");
|
str << wxT(" parspacingbefore=\"") << (int) attr.GetParagraphSpacingBefore() << wxT("\"");
|
||||||
|
|
||||||
|
if (attr.HasLineSpacing())
|
||||||
str << wxT(" linespacing=\"") << (int) attr.GetLineSpacing() << wxT("\"");
|
str << wxT(" linespacing=\"") << (int) attr.GetLineSpacing() << wxT("\"");
|
||||||
|
|
||||||
|
if (attr.HasBulletStyle())
|
||||||
str << wxT(" bulletstyle=\"") << (int) attr.GetBulletStyle() << wxT("\"");
|
str << wxT(" bulletstyle=\"") << (int) attr.GetBulletStyle() << wxT("\"");
|
||||||
|
|
||||||
|
if (attr.HasBulletNumber())
|
||||||
str << wxT(" bulletnumber=\"") << (int) attr.GetBulletNumber() << wxT("\"");
|
str << wxT(" bulletnumber=\"") << (int) attr.GetBulletNumber() << wxT("\"");
|
||||||
|
|
||||||
|
if (attr.HasBulletSymbol())
|
||||||
str << wxT(" bulletsymbol=\"") << wxString(attr.GetBulletSymbol()) << wxT("\"");
|
str << wxT(" bulletsymbol=\"") << wxString(attr.GetBulletSymbol()) << wxT("\"");
|
||||||
|
|
||||||
if (!attr.GetParagraphStyleName().empty())
|
if (!attr.GetParagraphStyleName().empty())
|
||||||
str << wxT(" parstyle=\"") << wxString(attr.GetParagraphStyleName()) << wxT("\"");
|
str << wxT(" parstyle=\"") << wxString(attr.GetParagraphStyleName()) << wxT("\"");
|
||||||
|
|
||||||
|
if (attr.HasTabs())
|
||||||
|
{
|
||||||
|
str << wxT(" tabs=\"");
|
||||||
|
size_t i;
|
||||||
|
for (i = 0; i < attr.GetTabs().GetCount(); i++)
|
||||||
|
{
|
||||||
|
if (i > 0)
|
||||||
|
str << wxT(",");
|
||||||
|
str << attr.GetTabs()[i];
|
||||||
|
}
|
||||||
|
str << wxT("\"");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return str;
|
return str;
|
||||||
@@ -581,30 +631,53 @@ bool wxRichTextXMLHandler::GetStyle(wxTextAttrEx& attr, wxXmlNode* node, bool is
|
|||||||
int fontStyle = wxNORMAL;
|
int fontStyle = wxNORMAL;
|
||||||
bool fontUnderlined = false;
|
bool fontUnderlined = false;
|
||||||
|
|
||||||
fontFacename = node->GetPropVal(wxT("fontface"), wxEmptyString);
|
int fontFlags = 0;
|
||||||
|
|
||||||
wxString value = node->GetPropVal(wxT("fontfamily"), wxEmptyString);
|
fontFacename = node->GetPropVal(wxT("fontface"), wxEmptyString);
|
||||||
if (!value.empty())
|
if (!fontFacename.IsEmpty())
|
||||||
fontFamily = wxAtoi(value);
|
fontFlags |= wxTEXT_ATTR_FONT_FACE;
|
||||||
|
|
||||||
|
wxString value;
|
||||||
|
//value = node->GetPropVal(wxT("fontfamily"), wxEmptyString);
|
||||||
|
//if (!value.empty())
|
||||||
|
// fontFamily = wxAtoi(value);
|
||||||
|
|
||||||
value = node->GetPropVal(wxT("fontstyle"), wxEmptyString);
|
value = node->GetPropVal(wxT("fontstyle"), wxEmptyString);
|
||||||
if (!value.empty())
|
if (!value.empty())
|
||||||
|
{
|
||||||
fontStyle = wxAtoi(value);
|
fontStyle = wxAtoi(value);
|
||||||
|
fontFlags |= wxTEXT_ATTR_FONT_ITALIC;
|
||||||
|
}
|
||||||
|
|
||||||
value = node->GetPropVal(wxT("fontsize"), wxEmptyString);
|
value = node->GetPropVal(wxT("fontsize"), wxEmptyString);
|
||||||
if (!value.empty())
|
if (!value.empty())
|
||||||
|
{
|
||||||
fontSize = wxAtoi(value);
|
fontSize = wxAtoi(value);
|
||||||
|
fontFlags |= wxTEXT_ATTR_FONT_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
value = node->GetPropVal(wxT("fontweight"), wxEmptyString);
|
value = node->GetPropVal(wxT("fontweight"), wxEmptyString);
|
||||||
if (!value.empty())
|
if (!value.empty())
|
||||||
|
{
|
||||||
fontWeight = wxAtoi(value);
|
fontWeight = wxAtoi(value);
|
||||||
|
fontFlags |= wxTEXT_ATTR_FONT_WEIGHT;
|
||||||
|
}
|
||||||
|
|
||||||
value = node->GetPropVal(wxT("fontunderlined"), wxEmptyString);
|
value = node->GetPropVal(wxT("fontunderlined"), wxEmptyString);
|
||||||
if (!value.empty())
|
if (!value.empty())
|
||||||
|
{
|
||||||
fontUnderlined = wxAtoi(value) != 0;
|
fontUnderlined = wxAtoi(value) != 0;
|
||||||
|
fontFlags |= wxTEXT_ATTR_FONT_UNDERLINE;
|
||||||
|
}
|
||||||
|
|
||||||
|
attr.SetFlags(fontFlags);
|
||||||
|
|
||||||
|
if (attr.HasFlag(wxTEXT_ATTR_FONT))
|
||||||
attr.SetFont(* wxTheFontList->FindOrCreateFont(fontSize, fontFamily, fontStyle, fontWeight, fontUnderlined, fontFacename));
|
attr.SetFont(* wxTheFontList->FindOrCreateFont(fontSize, fontFamily, fontStyle, fontWeight, fontUnderlined, fontFacename));
|
||||||
|
|
||||||
|
// Restore correct font flags
|
||||||
|
attr.SetFlags(fontFlags);
|
||||||
|
|
||||||
value = node->GetPropVal(wxT("textcolor"), wxEmptyString);
|
value = node->GetPropVal(wxT("textcolor"), wxEmptyString);
|
||||||
if (!value.empty())
|
if (!value.empty())
|
||||||
{
|
{
|
||||||
@@ -636,12 +709,23 @@ bool wxRichTextXMLHandler::GetStyle(wxTextAttrEx& attr, wxXmlNode* node, bool is
|
|||||||
|
|
||||||
int leftSubIndent = 0;
|
int leftSubIndent = 0;
|
||||||
int leftIndent = 0;
|
int leftIndent = 0;
|
||||||
|
bool hasLeftIndent = false;
|
||||||
|
|
||||||
value = node->GetPropVal(wxT("leftindent"), wxEmptyString);
|
value = node->GetPropVal(wxT("leftindent"), wxEmptyString);
|
||||||
if (!value.empty())
|
if (!value.empty())
|
||||||
|
{
|
||||||
leftIndent = wxAtoi(value);
|
leftIndent = wxAtoi(value);
|
||||||
|
hasLeftIndent = true;
|
||||||
|
}
|
||||||
|
|
||||||
value = node->GetPropVal(wxT("leftsubindent"), wxEmptyString);
|
value = node->GetPropVal(wxT("leftsubindent"), wxEmptyString);
|
||||||
if (!value.empty())
|
if (!value.empty())
|
||||||
|
{
|
||||||
leftSubIndent = wxAtoi(value);
|
leftSubIndent = wxAtoi(value);
|
||||||
|
hasLeftIndent = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasLeftIndent)
|
||||||
attr.SetLeftIndent(leftIndent, leftSubIndent);
|
attr.SetLeftIndent(leftIndent, leftSubIndent);
|
||||||
|
|
||||||
value = node->GetPropVal(wxT("rightindent"), wxEmptyString);
|
value = node->GetPropVal(wxT("rightindent"), wxEmptyString);
|
||||||
@@ -675,6 +759,19 @@ bool wxRichTextXMLHandler::GetStyle(wxTextAttrEx& attr, wxXmlNode* node, bool is
|
|||||||
value = node->GetPropVal(wxT("parstyle"), wxEmptyString);
|
value = node->GetPropVal(wxT("parstyle"), wxEmptyString);
|
||||||
if (!value.empty())
|
if (!value.empty())
|
||||||
attr.SetParagraphStyleName(value);
|
attr.SetParagraphStyleName(value);
|
||||||
|
|
||||||
|
value = node->GetPropVal(wxT("tabs"), wxEmptyString);
|
||||||
|
if (!value.empty())
|
||||||
|
{
|
||||||
|
wxArrayInt tabs;
|
||||||
|
wxStringTokenizer tkz(value, wxT(","));
|
||||||
|
while (tkz.HasMoreTokens())
|
||||||
|
{
|
||||||
|
wxString token = tkz.GetNextToken();
|
||||||
|
tabs.Add(wxAtoi(token));
|
||||||
|
}
|
||||||
|
attr.SetTabs(tabs);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
Reference in New Issue
Block a user