///////////////////////////////////////////////////////////////////////////// // Name: wx/richtext/richtextxml.h // Purpose: XML and HTML I/O for wxRichTextCtrl // Author: Julian Smart // Modified by: // Created: 2005-09-30 // Copyright: (c) Julian Smart // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// #ifndef _WX_RICHTEXTXML_H_ #define _WX_RICHTEXTXML_H_ /*! * Includes */ #include "wx/hashmap.h" #include "wx/richtext/richtextbuffer.h" #include "wx/richtext/richtextstyles.h" #if wxUSE_RICHTEXT && wxUSE_XML /*! @class wxRichTextXMLHelper A utility class to help with XML import/export, that can be used outside saving a buffer if needed. */ class WXDLLIMPEXP_RICHTEXT wxRichTextXMLHelper: public wxObject { public: wxRichTextXMLHelper() { Init(); } wxRichTextXMLHelper(const wxString& enc) { Init(); SetupForSaving(enc); } ~wxRichTextXMLHelper(); void Init(); void SetupForSaving(const wxString& enc); void Clear(); void SetFileEncoding(const wxString& encoding) { m_fileEncoding = encoding; } const wxString& GetFileEncoding() const { return m_fileEncoding; } // Convert a colour to a 6-digit hex string static wxString ColourToHexString(const wxColour& col); // Convert 6-digit hex string to a colour static wxColour HexStringToColour(const wxString& hex); static wxString MakeString(const int& v) { return wxString::Format(wxT("%d"), v); } static wxString MakeString(const long& v) { return wxString::Format(wxT("%ld"), v); } static wxString MakeString(const double& v) { return wxString::Format(wxS("%.2f"), v); } static wxString MakeString(const wxString& s) { return s; } static wxString MakeString(const wxColour& col) { return wxT("#") + ColourToHexString(col); } static bool HasParam(wxXmlNode* node, const wxString& param); static wxXmlNode *GetParamNode(wxXmlNode* node, const wxString& param); static wxString GetNodeContent(wxXmlNode *node); static wxString GetParamValue(wxXmlNode *node, const wxString& param); static wxString GetText(wxXmlNode *node, const wxString& param = wxEmptyString); static wxXmlNode* FindNode(wxXmlNode* node, const wxString& name); static wxString AttributeToXML(const wxString& str); static bool RichTextFixFaceName(wxString& facename); static long ColourStringToLong(const wxString& colStr); static wxTextAttrDimension ParseDimension(const wxString& dimStr); // Make a string from the given property. This can be overridden for custom variants. virtual wxString MakeStringFromProperty(const wxVariant& var); // Create a proprty from the string read from the XML file. virtual wxVariant MakePropertyFromString(const wxString& name, const wxString& value, const wxString& type); // Import properties virtual bool ImportProperties(wxRichTextProperties& properties, wxXmlNode* node); virtual bool ImportStyle(wxRichTextAttr& attr, wxXmlNode* node, bool isPara = false); virtual bool ImportStyleDefinition(wxRichTextStyleSheet* sheet, wxXmlNode* node); // Get flags, as per handler flags int GetFlags() const { return m_flags; } void SetFlags(int flags) { m_flags = flags; } #if wxRICHTEXT_HAVE_DIRECT_OUTPUT // write string to output static void OutputString(wxOutputStream& stream, const wxString& str, wxMBConv *convMem, wxMBConv *convFile); static void OutputIndentation(wxOutputStream& stream, int indent); // Same as above, but create entities first. // Translates '<' to "<", '>' to ">" and '&' to "&" static void OutputStringEnt(wxOutputStream& stream, const wxString& str, wxMBConv *convMem, wxMBConv *convFile); void OutputString(wxOutputStream& stream, const wxString& str); void OutputStringEnt(wxOutputStream& stream, const wxString& str); static void AddString(wxString& str, const int& v) { str << wxString::Format(wxT("%d"), v); } static void AddString(wxString& str, const long& v) { str << wxString::Format(wxT("%ld"), v); } static void AddString(wxString& str, const double& v) { str << wxString::Format(wxS("%.2f"), v); } static void AddString(wxString& str, const wxChar* s) { str << s; } static void AddString(wxString& str, const wxString& s) { str << s; } static void AddString(wxString& str, const wxColour& col) { str << wxT("#") << ColourToHexString(col); } static void AddAttribute(wxString& str, const wxString& name, const int& v); static void AddAttribute(wxString& str, const wxString& name, const long& v); static void AddAttribute(wxString& str, const wxString& name, const double& v); static void AddAttribute(wxString& str, const wxString& name, const wxChar* s); static void AddAttribute(wxString& str, const wxString& name, const wxString& s); static void AddAttribute(wxString& str, const wxString& name, const wxColour& col); static void AddAttribute(wxString& str, const wxString& name, const wxTextAttrDimension& dim); static void AddAttribute(wxString& str, const wxString& rootName, const wxTextAttrDimensions& dims); static void AddAttribute(wxString& str, const wxString& rootName, const wxTextAttrBorder& border); static void AddAttribute(wxString& str, const wxString& rootName, const wxTextAttrBorders& borders); /// Create a string containing style attributes static wxString AddAttributes(const wxRichTextAttr& attr, bool isPara = false); /// Create a string containing style attributes, plus further object 'attributes' (shown, id) static wxString AddAttributes(wxRichTextObject* obj, bool isPara = false); virtual bool ExportStyleDefinition(wxOutputStream& stream, wxRichTextStyleDefinition* def, int level); virtual bool WriteProperties(wxOutputStream& stream, const wxRichTextProperties& properties, int level); #endif #if wxRICHTEXT_HAVE_XMLDOCUMENT_OUTPUT static void AddAttribute(wxXmlNode* node, const wxString& name, const int& v); static void AddAttribute(wxXmlNode* node, const wxString& name, const long& v); static void AddAttribute(wxXmlNode* node, const wxString& name, const double& v); static void AddAttribute(wxXmlNode* node, const wxString& name, const wxString& s); static void AddAttribute(wxXmlNode* node, const wxString& name, const wxColour& col); static void AddAttribute(wxXmlNode* node, const wxString& name, const wxTextAttrDimension& dim); static void AddAttribute(wxXmlNode* node, const wxString& rootName, const wxTextAttrDimensions& dims); static void AddAttribute(wxXmlNode* node, const wxString& rootName, const wxTextAttrBorder& border); static void AddAttribute(wxXmlNode* node, const wxString& rootName, const wxTextAttrBorders& borders); static bool AddAttributes(wxXmlNode* node, wxRichTextAttr& attr, bool isPara = false); static bool AddAttributes(wxXmlNode* node, wxRichTextObject* obj, bool isPara = false); virtual bool ExportStyleDefinition(wxXmlNode* parent, wxRichTextStyleDefinition* def); // Write the properties virtual bool WriteProperties(wxXmlNode* node, const wxRichTextProperties& properties); #endif public: #if wxRICHTEXT_HAVE_DIRECT_OUTPUT // Used during saving wxMBConv* m_convMem; wxMBConv* m_convFile; bool m_deleteConvFile; #endif wxString m_fileEncoding; int m_flags; }; /*! @class wxRichTextXMLHandler Implements XML loading and saving. Two methods of saving are included: writing directly to a text stream, and populating an wxXmlDocument before writing it. The former method is considerably faster, so we favour that one, even though the code is a little less elegant. */ class WXDLLIMPEXP_FWD_XML wxXmlNode; class WXDLLIMPEXP_FWD_XML wxXmlDocument; class WXDLLIMPEXP_RICHTEXT wxRichTextXMLHandler: public wxRichTextFileHandler { wxDECLARE_DYNAMIC_CLASS(wxRichTextXMLHandler); public: wxRichTextXMLHandler(const wxString& name = wxT("XML"), const wxString& ext = wxT("xml"), int type = wxRICHTEXT_TYPE_XML) : wxRichTextFileHandler(name, ext, type) { Init(); } void Init(); #if wxUSE_STREAMS #if wxRICHTEXT_HAVE_DIRECT_OUTPUT /// Recursively export an object bool ExportXML(wxOutputStream& stream, wxRichTextObject& obj, int level); #endif #if wxRICHTEXT_HAVE_XMLDOCUMENT_OUTPUT bool ExportXML(wxXmlNode* parent, wxRichTextObject& obj); #endif /// Recursively import an object bool ImportXML(wxRichTextBuffer* buffer, wxRichTextObject* obj, wxXmlNode* node); #endif /// Creates an object given an XML element name virtual wxRichTextObject* CreateObjectForXMLName(wxRichTextObject* parent, const wxString& name) const; /// Can we save using this handler? virtual bool CanSave() const wxOVERRIDE { return true; } /// Can we load using this handler? virtual bool CanLoad() const wxOVERRIDE { return true; } /// Returns the XML helper object, implementing functionality /// that can be reused elsewhere. wxRichTextXMLHelper& GetHelper() { return m_helper; } // Implementation /** Call with XML node name, C++ class name so that wxRTC can read in the node. If you add a custom object, call this. */ static void RegisterNodeName(const wxString& nodeName, const wxString& className) { sm_nodeNameToClassMap[nodeName] = className; } /** Cleans up the mapping between node name and C++ class. */ static void ClearNodeToClassMap() { sm_nodeNameToClassMap.clear(); } protected: #if wxUSE_STREAMS virtual bool DoLoadFile(wxRichTextBuffer *buffer, wxInputStream& stream) wxOVERRIDE; virtual bool DoSaveFile(wxRichTextBuffer *buffer, wxOutputStream& stream) wxOVERRIDE; #endif wxRichTextXMLHelper m_helper; static wxStringToStringHashMap sm_nodeNameToClassMap; }; #endif // wxUSE_RICHTEXT && wxUSE_XML #endif // _WX_RICHTEXTXML_H_