+ handler->GetHelper().OutputString(stream, wxT("\""));
+ handler->GetHelper().OutputStringEnt(stream, fragment);
+ handler->GetHelper().OutputString(stream, wxT("\""));
+ }
+ else
+ handler->GetHelper().OutputStringEnt(stream, fragment);
+
+ handler->GetHelper().OutputString(stream, wxT("</text>"));
+ }
+ return true;
+}
+#endif
+
+#if wxRICHTEXT_HAVE_XMLDOCUMENT_OUTPUT
+// Export this object to the given parent node, usually creating at least one child node.
+bool wxRichTextPlainText::ExportXML(wxXmlNode* parent, wxRichTextXMLHandler* handler)
+{
+ int i;
+ int last = 0;
+ const wxString& text = GetText();
+ int len = (int) text.Length();
+
+ if (len == 0)
+ {
+ i = 0;
+
+ wxXmlNode* elementNode = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("text"));
+ parent->AddChild(elementNode);
+
+ handler->GetHelper().AddAttributes(elementNode, GetAttributes(), false);
+ handler->GetHelper().WriteProperties(elementNode, GetProperties());
+ }
+ else for (i = 0; i < len; i++)
+ {
+#if wxUSE_UNICODE
+ int c = (int) text[i];
+#else
+ int c = (int) wxUChar(text[i]);
+#endif
+ if ((c < 32 || c == 34) && c != 10 && c != 13)
+ {
+ if (i > 0)
+ {
+ wxString fragment(text.Mid(last, i-last));
+ if (!fragment.empty())
+ {
+ // TODO: I'm assuming wxXmlDocument will output quotes if necessary
+ wxXmlNode* elementNode = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("text"));
+ parent->AddChild(elementNode);
+ handler->GetHelper().AddAttributes(elementNode, GetAttributes(), false);
+ handler->GetHelper().WriteProperties(elementNode, GetProperties());
+
+ wxXmlNode* textNode = new wxXmlNode(wxXML_TEXT_NODE, wxT("text"));
+ elementNode->AddChild(textNode);
+
+ if (fragment[0] == wxT(' ') || fragment[fragment.length()-1] == wxT(' '))
+ fragment = wxT("\"") + fragment + wxT("\"");
+
+ textNode->SetContent(fragment);
+ }
+ }
+
+ // Output this character as a number in a separate tag, because XML can't cope
+ // with entities below 32 except for 10 and 13
+
+ wxXmlNode* elementNode = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("symbol"));
+ parent->AddChild(elementNode);
+
+ handler->GetHelper().AddAttributes(elementNode, GetAttributes(), false);
+ handler->GetHelper().WriteProperties(elementNode, GetProperties());
+
+ wxXmlNode* textNode = new wxXmlNode(wxXML_TEXT_NODE, wxT("text"));
+ elementNode->AddChild(textNode);
+ textNode->SetContent(wxString::Format(wxT("%d"), c));
+
+ last = i + 1;
+ }
+ }
+
+ wxString fragment;
+ if (last == 0)
+ fragment = text;
+ else
+ fragment = text.Mid(last, i-last);
+
+ if (last < len)
+ {
+ wxXmlNode* elementNode = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("text"));
+ parent->AddChild(elementNode);
+ handler->GetHelper().AddAttributes(elementNode, GetAttributes(), false);
+
+ wxXmlNode* textNode = new wxXmlNode(wxXML_TEXT_NODE, wxT("text"));
+ elementNode->AddChild(textNode);
+
+ if (fragment[0] == wxT(' ') || fragment[fragment.length()-1] == wxT(' '))
+ fragment = wxT("\"") + fragment + wxT("\"");
+
+ textNode->SetContent(fragment);
+ }
+ return true;
+}
+#endif
+
+// Import this object from XML
+bool wxRichTextImage::ImportFromXML(wxRichTextBuffer* buffer, wxXmlNode* node, wxRichTextXMLHandler* handler, bool* recurse)
+{
+ wxRichTextObject::ImportFromXML(buffer, node, handler, recurse);
+
+ wxBitmapType imageType = wxBITMAP_TYPE_PNG;
+ wxString value = node->GetAttribute(wxT("imagetype"), wxEmptyString);
+ if (!value.empty())
+ {
+ int type = wxAtoi(value);
+
+ // note: 0 == wxBITMAP_TYPE_INVALID
+ if (type <= 0 || type >= wxBITMAP_TYPE_MAX)
+ {
+ wxLogWarning("Invalid bitmap type specified for <image> tag: %d", type);
+ }
+ else
+ {
+ imageType = (wxBitmapType)type;
+ }
+ }
+
+ wxString data;
+
+ wxXmlNode* imageChild = node->GetChildren();
+ while (imageChild)
+ {
+ wxString childName = imageChild->GetName();
+ if (childName == wxT("data"))
+ {
+ wxXmlNode* dataChild = imageChild->GetChildren();
+ while (dataChild)
+ {
+ data = dataChild->GetContent();
+ // wxLogDebug(data);
+ dataChild = dataChild->GetNext();
+ }
+
+ }
+ imageChild = imageChild->GetNext();
+ }
+
+ if (!data.empty())
+ {
+ wxStringInputStream strStream(data);
+
+ GetImageBlock().ReadHex(strStream, data.length(), imageType);
+
+ return true;
+ }
+ else
+ return false;
+}
+
+#if wxRICHTEXT_HAVE_DIRECT_OUTPUT
+// Export this object directly to the given stream.
+bool wxRichTextImage::ExportXML(wxOutputStream& stream, int indent, wxRichTextXMLHandler* handler)
+{
+ wxString style = handler->GetHelper().AddAttributes(GetAttributes(), false);
+
+ handler->GetHelper().OutputIndentation(stream, indent);
+ handler->GetHelper().OutputString(stream, wxT("<image"));
+ if (!GetImageBlock().IsOk())
+ {
+ // No data
+ handler->GetHelper().OutputString(stream, style + wxT(">"));
+ }
+ else
+ {
+ handler->GetHelper().OutputString(stream, wxString::Format(wxT(" imagetype=\"%d\""), (int) GetImageBlock().GetImageType()) + style + wxT(">"));
+ }
+ if (GetProperties().GetCount() > 0)
+ {
+ handler->GetHelper().WriteProperties(stream, GetProperties(), indent);
+ handler->GetHelper().OutputIndentation(stream, indent);
+ }
+
+ handler->GetHelper().OutputIndentation(stream, indent+1);
+ handler->GetHelper().OutputString(stream, wxT("<data>"));
+
+ // wxStopWatch stopwatch;
+
+ GetImageBlock().WriteHex(stream);
+
+ // wxLogDebug(wxT("Image conversion to hex took %ldms"), stopwatch.Time());
+
+ handler->GetHelper().OutputString(stream, wxT("</data>\n"));
+ handler->GetHelper().OutputIndentation(stream, indent);
+ handler->GetHelper().OutputString(stream, wxT("</image>"));
+ return true;
+}
+#endif
+
+#if wxRICHTEXT_HAVE_XMLDOCUMENT_OUTPUT
+// Export this object to the given parent node, usually creating at least one child node.
+bool wxRichTextImage::ExportXML(wxXmlNode* parent, wxRichTextXMLHandler* handler)
+{
+ wxXmlNode* elementNode = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("image"));
+ parent->AddChild(elementNode);
+
+ if (GetImageBlock().IsOk())
+ elementNode->AddAttribute(wxT("imagetype"), wxRichTextXMLHelper::MakeString((int) GetImageBlock().GetImageType()));
+
+ handler->GetHelper().AddAttributes(elementNode, GetAttributes(), false);
+ handler->GetHelper().WriteProperties(elementNode, GetProperties());
+
+ wxXmlNode* dataNode = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("data"));
+ elementNode->AddChild(dataNode);
+ wxXmlNode* textNode = new wxXmlNode(wxXML_TEXT_NODE, wxT("text"));
+ dataNode->AddChild(textNode);
+
+ wxString strData;
+#if 1
+ {
+ wxMemoryOutputStream stream;
+ if (GetImageBlock().WriteHex(stream))
+ {
+ if (stream.GetSize() > 0)
+ {
+ int size = stream.GetSize();
+#ifdef __WXDEBUG__
+ int size2 = stream.GetOutputStreamBuffer()->GetIntPosition();
+ wxASSERT(size == size2);
+#endif
+ unsigned char* data = new unsigned char[size];
+ stream.CopyTo(data, size);
+ strData = wxString((const char*) data, wxConvUTF8, size);
+ delete[] data;
+ }
+ else
+ strData = wxEmptyString;
+ }
+
+ }
+#else
+ {
+ wxStringOutputStream strStream(& strData);
+ GetImageBlock().WriteHex(strStream);
+ }
+#endif
+
+ textNode->SetContent(strData);
+#if wxCHECK_VERSION(2,9,0)
+ textNode->SetNoConversion(true); // optimize speed
+#endif
+
+ return true;
+}
+#endif
+
+// Import this object from XML
+bool wxRichTextParagraphLayoutBox::ImportFromXML(wxRichTextBuffer* buffer, wxXmlNode* node, wxRichTextXMLHandler* handler, bool* recurse)
+{
+ wxRichTextObject::ImportFromXML(buffer, node, handler, recurse);
+
+ *recurse = true;
+
+ wxString partial = node->GetAttribute(wxT("partialparagraph"), wxEmptyString);
+ if (partial == wxT("true"))
+ SetPartialParagraph(true);
+
+ wxXmlNode* child = handler->GetHelper().FindNode(node, wxT("stylesheet"));
+ if (child && (handler->GetFlags() & wxRICHTEXT_HANDLER_INCLUDE_STYLESHEET))
+ {
+ wxRichTextStyleSheet* sheet = new wxRichTextStyleSheet;
+ wxString sheetName = child->GetAttribute(wxT("name"), wxEmptyString);
+ wxString sheetDescription = child->GetAttribute(wxT("description"), wxEmptyString);
+ sheet->SetName(sheetName);
+ sheet->SetDescription(sheetDescription);
+
+ wxXmlNode* child2 = child->GetChildren();
+ while (child2)
+ {
+ handler->GetHelper().ImportStyleDefinition(sheet, child2);
+
+ child2 = child2->GetNext();
+ }
+ handler->GetHelper().ImportProperties(sheet->GetProperties(), child);
+
+ // Notify that styles have changed. If this is vetoed by the app,
+ // the new sheet will be deleted. If it is not vetoed, the
+ // old sheet will be deleted and replaced with the new one.
+ buffer->SetStyleSheetAndNotify(sheet);
+ }
+
+ return true;
+}
+
+#if wxRICHTEXT_HAVE_DIRECT_OUTPUT
+// Export this object directly to the given stream.
+bool wxRichTextParagraphLayoutBox::ExportXML(wxOutputStream& stream, int indent, wxRichTextXMLHandler* handler)
+{
+ handler->GetHelper().OutputIndentation(stream, indent);
+ wxString nodeName = GetXMLNodeName();
+ handler->GetHelper().OutputString(stream, wxT("<") + nodeName);
+
+ wxString style = handler->GetHelper().AddAttributes(GetAttributes(), true);
+
+ if (GetPartialParagraph())
+ style << wxT(" partialparagraph=\"true\"");
+
+ handler->GetHelper().OutputString(stream, style + wxT(">"));
+
+ if (GetProperties().GetCount() > 0)
+ {
+ handler->GetHelper().WriteProperties(stream, GetProperties(), indent);
+ }
+
+ size_t i;
+ for (i = 0; i < GetChildCount(); i++)
+ {
+ wxRichTextObject* child = GetChild(i);
+ child->ExportXML(stream, indent+1, handler);
+ }
+
+ handler->GetHelper().OutputIndentation(stream, indent);
+ handler->GetHelper().OutputString(stream, wxT("</") + nodeName + wxT(">"));
+ return true;
+}
+#endif
+
+#if wxRICHTEXT_HAVE_XMLDOCUMENT_OUTPUT
+// Export this object to the given parent node, usually creating at least one child node.
+bool wxRichTextParagraphLayoutBox::ExportXML(wxXmlNode* parent, wxRichTextXMLHandler* handler)
+{
+ wxXmlNode* elementNode = new wxXmlNode(wxXML_ELEMENT_NODE, GetXMLNodeName());
+ parent->AddChild(elementNode);
+ handler->GetHelper().AddAttributes(elementNode, GetAttributes(), true);
+ handler->GetHelper().WriteProperties(elementNode, GetProperties());
+
+ if (GetPartialParagraph())
+ elementNode->AddAttribute(wxT("partialparagraph"), wxT("true"));
+
+ size_t i;
+ for (i = 0; i < GetChildCount(); i++)
+ {
+ wxRichTextObject* child = GetChild(i);
+ child->ExportXML(elementNode, handler);
+ }
+
+ return true;
+}
+#endif
+
+// Import this object from XML
+bool wxRichTextTable::ImportFromXML(wxRichTextBuffer* buffer, wxXmlNode* node, wxRichTextXMLHandler* handler, bool* recurse)
+{
+ wxRichTextBox::ImportFromXML(buffer, node, handler, recurse);
+
+ *recurse = false;
+
+ m_rowCount = wxAtoi(node->GetAttribute(wxT("rows"), wxEmptyString));
+ m_colCount = wxAtoi(node->GetAttribute(wxT("cols"), wxEmptyString));
+
+ wxXmlNode* child = node->GetChildren();
+ while (child)
+ {
+ wxRichTextObject* childObj = handler->CreateObjectForXMLName(this, child->GetName());
+ if (childObj)
+ {
+ AppendChild(childObj);
+ handler->ImportXML(buffer, childObj, child);
+ }
+ child = child->GetNext();
+ }
+
+ m_cells.Add(wxRichTextObjectPtrArray(), m_rowCount);
+ int i, j;
+ for (i = 0; i < m_rowCount; i++)
+ {
+ wxRichTextObjectPtrArray& colArray = m_cells[i];
+ for (j = 0; j < m_colCount; j++)
+ {
+ int idx = i * m_colCount + j;
+ if (idx < (int) GetChildren().GetCount())
+ {
+ wxRichTextCell* cell = wxDynamicCast(GetChildren().Item(idx)->GetData(), wxRichTextCell);
+ if (cell)
+ colArray.Add(cell);
+ }
+ }
+ }
+
+ return true;
+}
+
+#if wxRICHTEXT_HAVE_DIRECT_OUTPUT
+// Export this object directly to the given stream.
+bool wxRichTextTable::ExportXML(wxOutputStream& stream, int indent, wxRichTextXMLHandler* handler)
+{
+ handler->GetHelper().OutputIndentation(stream, indent);
+ wxString nodeName = GetXMLNodeName();
+ handler->GetHelper().OutputString(stream, wxT("<") + nodeName);
+
+ wxString style = handler->GetHelper().AddAttributes(GetAttributes(), true);
+
+ style << wxT(" rows=\"") << m_rowCount << wxT("\"");
+ style << wxT(" cols=\"") << m_colCount << wxT("\"");
+
+ handler->GetHelper().OutputString(stream, style + wxT(">"));
+
+ if (GetProperties().GetCount() > 0)
+ {
+ handler->GetHelper().WriteProperties(stream, GetProperties(), indent);
+ }
+
+ int i, j;
+ for (i = 0; i < m_rowCount; i++)
+ {
+ for (j = 0; j < m_colCount; j ++)
+ {
+ wxRichTextCell* cell = GetCell(i, j);
+ cell->ExportXML(stream, indent+1, handler);
+ }
+ }
+
+ handler->GetHelper().OutputIndentation(stream, indent);
+ handler->GetHelper().OutputString(stream, wxT("</") + nodeName + wxT(">"));
+
+ return true;
+}
+#endif
+
+#if wxRICHTEXT_HAVE_XMLDOCUMENT_OUTPUT
+// Export this object to the given parent node, usually creating at least one child node.
+bool wxRichTextTable::ExportXML(wxXmlNode* parent, wxRichTextXMLHandler* handler)
+{
+ wxXmlNode* elementNode = new wxXmlNode(wxXML_ELEMENT_NODE, GetXMLNodeName());
+ parent->AddChild(elementNode);
+ handler->GetHelper().AddAttributes(elementNode, GetAttributes(), true);
+ handler->GetHelper().WriteProperties(elementNode, GetProperties());
+
+ elementNode->AddAttribute(wxT("rows"), wxString::Format(wxT("%d"), m_rowCount));
+ elementNode->AddAttribute(wxT("cols"), wxString::Format(wxT("%d"), m_colCount));
+
+ int i, j;
+ for (i = 0; i < m_rowCount; i++)
+ {
+ for (j = 0; j < m_colCount; j ++)
+ {
+ wxRichTextCell* cell = GetCell(i, j);
+ cell->ExportXML(elementNode, handler);
+ }
+ }
+
+ return true;
+}
+#endif
+
+wxRichTextXMLHelper::~wxRichTextXMLHelper()
+{
+ Clear();
+}
+
+void wxRichTextXMLHelper::Init()
+{
+#if wxRICHTEXT_HAVE_DIRECT_OUTPUT
+ m_deleteConvFile = false;
+ m_convMem = NULL;
+ m_convFile = NULL;
+#endif
+ m_flags = 0;
+}
+
+void wxRichTextXMLHelper::Clear()
+{
+#if wxRICHTEXT_HAVE_DIRECT_OUTPUT
+ if (m_deleteConvFile)
+ delete m_convFile;
+ m_convFile = NULL;
+ m_convMem = NULL;
+ m_deleteConvFile = false;
+#endif
+ m_fileEncoding = wxEmptyString;
+}
+
+void wxRichTextXMLHelper::SetupForSaving(const wxString& enc)
+{
+ Clear();
+
+#if wxUSE_UNICODE
+ m_fileEncoding = wxT("UTF-8");
+#if wxRICHTEXT_HAVE_DIRECT_OUTPUT
+ m_convFile = & wxConvUTF8;
+#endif
+#else
+ m_fileEncoding = wxT("ISO-8859-1");
+#if wxRICHTEXT_HAVE_DIRECT_OUTPUT
+ m_convFile = & wxConvISO8859_1;
+#endif
+#endif
+
+ // If we pass an explicit encoding, change the output encoding.
+ if (!enc.empty() && enc.Lower() != m_fileEncoding.Lower())
+ {
+ if (enc == wxT("<System>"))
+ {
+#if wxUSE_INTL
+ m_fileEncoding = wxLocale::GetSystemEncodingName();
+ // if !wxUSE_INTL, we fall back to UTF-8 or ISO-8859-1 below
+#endif
+ }
+ else
+ {
+ m_fileEncoding = enc;
+ }
+
+ // GetSystemEncodingName may not have returned a name
+ if (m_fileEncoding.empty())
+#if wxUSE_UNICODE
+ m_fileEncoding = wxT("UTF-8");
+#else
+ m_fileEncoding = wxT("ISO-8859-1");
+#endif
+#if wxRICHTEXT_HAVE_DIRECT_OUTPUT
+ m_convFile = new wxCSConv(m_fileEncoding);
+ m_deleteConvFile = true;
+#endif
+ }
+
+#if wxRICHTEXT_HAVE_DIRECT_OUTPUT
+#if !wxUSE_UNICODE
+ m_convMem = wxConvCurrent;
+#else
+ m_convMem = NULL;
+#endif
+#endif
+}
+
+// Convert a colour to a 6-digit hex string
+wxString wxRichTextXMLHelper::ColourToHexString(const wxColour& col)
+{
+ wxString hex;
+
+ hex += wxDecToHex(col.Red());
+ hex += wxDecToHex(col.Green());
+ hex += wxDecToHex(col.Blue());
+
+ return hex;
+}
+
+// Convert 6-digit hex string to a colour
+wxColour wxRichTextXMLHelper::HexStringToColour(const wxString& hex)
+{
+ unsigned char r = (unsigned char)wxHexToDec(hex.Mid(0, 2));
+ unsigned char g = (unsigned char)wxHexToDec(hex.Mid(2, 2));
+ unsigned char b = (unsigned char)wxHexToDec(hex.Mid(4, 2));
+
+ return wxColour(r, g, b);
+}
+
+//-----------------------------------------------------------------------------
+// xml support routines
+//-----------------------------------------------------------------------------
+
+bool wxRichTextXMLHelper::HasParam(wxXmlNode* node, const wxString& param)
+{
+ return (GetParamNode(node, param) != NULL);
+}
+
+wxXmlNode *wxRichTextXMLHelper::GetParamNode(wxXmlNode* node, const wxString& param)
+{
+ wxCHECK_MSG(node, NULL, wxT("You can't access node data before it was initialized!"));
+
+ wxXmlNode *n = node->GetChildren();
+
+ while (n)
+ {
+ if (n->GetType() == wxXML_ELEMENT_NODE && n->GetName() == param)
+ return n;
+ n = n->GetNext();
+ }
+ return NULL;
+}
+
+wxString wxRichTextXMLHelper::GetNodeContent(wxXmlNode *node)
+{
+ wxXmlNode *n = node;
+ if (n == NULL) return wxEmptyString;
+ n = n->GetChildren();
+
+ while (n)
+ {
+ if (n->GetType() == wxXML_TEXT_NODE ||
+ n->GetType() == wxXML_CDATA_SECTION_NODE)
+ return n->GetContent();
+ n = n->GetNext();
+ }
+ return wxEmptyString;
+}
+
+wxString wxRichTextXMLHelper::GetParamValue(wxXmlNode *node, const wxString& param)
+{
+ if (param.empty())
+ return GetNodeContent(node);
+ else
+ return GetNodeContent(GetParamNode(node, param));
+}
+
+wxString wxRichTextXMLHelper::GetText(wxXmlNode *node, const wxString& param)
+{
+ wxXmlNode *parNode = GetParamNode(node, param);
+ if (!parNode)
+ parNode = node;
+ wxString str1(GetNodeContent(parNode));
+ return str1;
+}
+
+wxXmlNode* wxRichTextXMLHelper::FindNode(wxXmlNode* node, const wxString& name)
+{
+ if (node->GetName() == name && name == wxT("stylesheet"))
+ return node;
+
+ wxXmlNode* child = node->GetChildren();
+ while (child)
+ {
+ if (child->GetName() == name)
+ return child;
+ child = child->GetNext();
+ }
+ return NULL;
+}
+
+wxString wxRichTextXMLHelper::AttributeToXML(const wxString& str)
+{
+ wxString str1;
+ size_t i, last, len;
+ wxChar c;
+
+ len = str.Len();
+ last = 0;
+ for (i = 0; i < len; i++)
+ {
+ c = str.GetChar(i);
+
+ // Original code excluded "&" but we _do_ want to convert
+ // the ampersand beginning & because otherwise when read in,
+ // the original "&" becomes "&".
+
+ if (c == wxT('<') || c == wxT('>') || c == wxT('"') ||
+ (c == wxT('&') /* && (str.Mid(i+1, 4) != wxT("amp;")) */ ))
+ {
+ str1 += str.Mid(last, i - last);
+ switch (c)
+ {
+ case wxT('<'):
+ str1 += wxT("<");
+ break;
+ case wxT('>'):
+ str1 += wxT(">");
+ break;
+ case wxT('&'):
+ str1 += wxT("&");
+ break;
+ case wxT('"'):
+ str1 += wxT(""");
+ break;
+ default: break;
+ }
+ last = i + 1;
+ }
+ else if (wxUChar(c) > 127)
+ {
+ str1 += str.Mid(last, i - last);
+
+ wxString s(wxT("&#"));
+#if wxUSE_UNICODE
+ s << (int) c;
+#else
+ s << (int) wxUChar(c);
+#endif
+ s << wxT(";");
+ str1 += s;
+ last = i + 1;
+ }
+ }
+ str1 += str.Mid(last, i - last);
+ return str1;
+}
+
+// Make a string from the given property. This can be overridden for custom variants.
+wxString wxRichTextXMLHelper::MakeStringFromProperty(const wxVariant& var)
+{
+ return var.MakeString();
+}
+
+// Create a proprty from the string read from the XML file.
+wxVariant wxRichTextXMLHelper::MakePropertyFromString(const wxString& name, const wxString& value, const wxString& WXUNUSED(type))
+{
+ wxVariant var(value, name);
+ // TODO: use type to create using common types
+ return var;
+}
+
+/// Replace face name with current name for platform.
+/// TODO: introduce a virtual function or settable table to
+/// do this comprehensively.
+bool wxRichTextXMLHelper::RichTextFixFaceName(wxString& facename)
+{
+ if (facename.empty())
+ return false;
+
+#ifdef __WXMSW__
+ if (facename == wxT("Times"))
+ {
+ facename = wxT("Times New Roman");
+ return true;
+ }
+ else if (facename == wxT("Helvetica"))
+ {
+ facename = wxT("Arial");
+ return true;
+ }
+ else if (facename == wxT("Courier"))
+ {
+ facename = wxT("Courier New");
+ return true;
+ }
+ else
+ return false;
+#else
+ if (facename == wxT("Times New Roman"))
+ {
+ facename = wxT("Times");
+ return true;
+ }
+ else if (facename == wxT("Arial"))
+ {
+ facename = wxT("Helvetica");
+ return true;
+ }
+ else if (facename == wxT("Courier New"))
+ {
+ facename = wxT("Courier");
+ return true;
+ }
+ else
+ return false;
+#endif
+}
+
+long wxRichTextXMLHelper::ColourStringToLong(const wxString& colStr)
+{
+ if (!colStr.IsEmpty())
+ {
+ wxColour col(colStr);
+#if wxCHECK_VERSION(2,9,0)
+ return col.GetRGB();
+#else
+ return (col.Red() | (col.Green() << 8) | (col.Blue() << 16));
+#endif
+ }
+ else
+ return 0;
+}
+
+wxTextAttrDimension wxRichTextXMLHelper::ParseDimension(const wxString& dimStr)
+{
+ wxString valuePart = dimStr.BeforeFirst(wxT(','));
+ wxString flagsPart;
+ if (dimStr.Contains(wxT(",")))
+ flagsPart = dimStr.AfterFirst(wxT(','));
+ wxTextAttrDimension dim;
+ dim.SetValue(wxAtoi(valuePart));
+ dim.SetFlags(wxAtoi(flagsPart));
+
+ return dim;
+}
+
+/// Import style parameters
+bool wxRichTextXMLHelper::ImportStyle(wxRichTextAttr& attr, wxXmlNode* node, bool isPara)
+{
+ wxXmlAttribute* xmlAttr = node->GetAttributes();
+ bool found;
+ while (xmlAttr)
+ {
+ const wxString& name = xmlAttr->GetName();
+ const wxString& value = xmlAttr->GetValue();
+ found = true;
+
+ if (name == wxT("fontface"))
+ {
+ if (!value.empty())
+ {
+ wxString v = value;
+ if (GetFlags() & wxRICHTEXT_HANDLER_CONVERT_FACENAMES)
+ RichTextFixFaceName(v);
+ attr.SetFontFaceName(v);
+ }
+ }
+ else if (name == wxT("fontfamily"))
+ {
+ if (!value.empty())
+ attr.SetFontFamily((wxFontFamily)wxAtoi(value));
+ }
+ else if (name == wxT("fontstyle"))
+ {
+ if (!value.empty())
+ attr.SetFontStyle((wxFontStyle)wxAtoi(value));
+ }
+ else if (name == wxT("fontsize") || name == wxT("fontpointsize"))
+ {
+ if (!value.empty())
+ attr.SetFontPointSize(wxAtoi(value));
+ }
+ else if (name == wxT("fontpixelsize"))
+ {
+ if (!value.empty())
+ attr.SetFontPixelSize(wxAtoi(value));
+ }
+ else if (name == wxT("fontweight"))
+ {
+ if (!value.empty())
+ attr.SetFontWeight((wxFontWeight) wxAtoi(value));
+ }
+ else if (name == wxT("fontunderlined"))
+ {
+ if (!value.empty())
+ attr.SetFontUnderlined(wxAtoi(value) != 0);
+ }
+ else if (name == wxT("textcolor"))
+ {
+ if (!value.empty())
+ {
+ if (value[0] == wxT('#'))
+ attr.SetTextColour(HexStringToColour(value.Mid(1)));
+ else
+ attr.SetTextColour(value);
+ }
+ }
+ else if (name == wxT("bgcolor"))
+ {
+ if (!value.empty())
+ {
+ if (value[0] == wxT('#'))
+ attr.SetBackgroundColour(HexStringToColour(value.Mid(1)));
+ else
+ attr.SetBackgroundColour(value);
+ }
+ }
+ else if (name == wxT("characterstyle"))
+ {
+ if (!value.empty())
+ attr.SetCharacterStyleName(value);
+ }
+ else if (name == wxT("texteffects"))
+ {
+ if (!value.empty())
+ attr.SetTextEffects(wxAtoi(value));
+ }
+ else if (name == wxT("texteffectflags"))
+ {
+ if (!value.empty())
+ attr.SetTextEffectFlags(wxAtoi(value));
+ }
+ else if (name == wxT("url"))
+ {
+ if (!value.empty())
+ attr.SetURL(value);
+ }
+ else if (isPara)
+ {
+ if (name == wxT("alignment"))
+ {
+ if (!value.empty())
+ attr.SetAlignment((wxTextAttrAlignment) wxAtoi(value));
+ }
+ else if (name == wxT("leftindent"))
+ {
+ if (!value.empty())
+ attr.SetLeftIndent(wxAtoi(value), attr.GetLeftSubIndent());
+ }
+ else if (name == wxT("leftsubindent"))
+ {
+ if (!value.empty())
+ attr.SetLeftIndent(attr.GetLeftIndent(), wxAtoi(value));
+ }
+ else if (name == wxT("rightindent"))
+ {
+ if (!value.empty())
+ attr.SetRightIndent(wxAtoi(value));
+ }
+ else if (name == wxT("parspacingbefore"))
+ {
+ if (!value.empty())
+ attr.SetParagraphSpacingBefore(wxAtoi(value));
+ }
+ else if (name == wxT("parspacingafter"))
+ {
+ if (!value.empty())
+ attr.SetParagraphSpacingAfter(wxAtoi(value));
+ }
+ else if (name == wxT("linespacing"))
+ {
+ if (!value.empty())
+ attr.SetLineSpacing(wxAtoi(value));
+ }
+ else if (name == wxT("bulletstyle"))
+ {
+ if (!value.empty())
+ attr.SetBulletStyle(wxAtoi(value));
+ }
+ else if (name == wxT("bulletnumber"))
+ {
+ if (!value.empty())
+ attr.SetBulletNumber(wxAtoi(value));
+ }
+ else if (name == wxT("bulletsymbol"))
+ {
+ if (!value.empty())
+ {
+ wxChar ch = wxAtoi(value);
+ wxString s;
+ s << ch;
+ attr.SetBulletText(s);
+ }
+ }
+ else if (name == wxT("bullettext"))
+ {
+ if (!value.empty())
+ {
+ attr.SetBulletText(value);
+ }
+ }
+ else if (name == wxT("bulletfont"))
+ {
+ if (!value.empty())
+ {
+ attr.SetBulletFont(value);
+ }
+ }
+ else if (name == wxT("bulletname"))
+ {
+ if (!value.empty())
+ {
+ attr.SetBulletName(value);
+ }
+ }
+ else if (name == wxT("parstyle"))