#ifndef WX_PRECOMP
#include "wx/intl.h"
#include "wx/module.h"
+ #include "wx/log.h"
#endif
#include "wx/filename.h"
if (name == wxT("paragraphlayout"))
{
- wxString partial = node->GetPropVal(wxT("partialparagraph"), wxEmptyString);
+ wxString partial = node->GetAttribute(wxT("partialparagraph"), wxEmptyString);
if (partial == wxT("true"))
buffer->SetPartialParagraph(true);
}
}
else if (childName == wxT("image"))
{
- int imageType = wxBITMAP_TYPE_PNG;
- wxString value = node->GetPropVal(wxT("imagetype"), wxEmptyString);
+ wxBitmapType imageType = wxBITMAP_TYPE_PNG;
+ wxString value = child->GetAttribute(wxT("imagetype"), wxEmptyString);
if (!value.empty())
- imageType = wxAtoi(value);
+ {
+ 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;
if (!data.empty())
{
wxRichTextImage* imageObj = new wxRichTextImage(para);
+ GetStyle(imageObj->GetAttributes(), child, false);
para->AppendChild(imageObj);
wxStringInputStream strStream(data);
if (GetFlags() & wxRICHTEXT_HANDLER_INCLUDE_STYLESHEET)
{
wxRichTextStyleSheet* sheet = new wxRichTextStyleSheet;
- wxString sheetName = node->GetPropVal(wxT("name"), wxEmptyString);
- wxString sheetDescription = node->GetPropVal(wxT("description"), wxEmptyString);
+ wxString sheetName = node->GetAttribute(wxT("name"), wxEmptyString);
+ wxString sheetDescription = node->GetAttribute(wxT("description"), wxEmptyString);
sheet->SetName(sheetName);
sheet->SetDescription(sheetDescription);
bool wxRichTextXMLHandler::ImportStyleDefinition(wxRichTextStyleSheet* sheet, wxXmlNode* node)
{
wxString styleType = node->GetName();
- wxString styleName = node->GetPropVal(wxT("name"), wxEmptyString);
- wxString baseStyleName = node->GetPropVal(wxT("basestyle"), wxEmptyString);
+ wxString styleName = node->GetAttribute(wxT("name"), wxEmptyString);
+ wxString baseStyleName = node->GetAttribute(wxT("basestyle"), wxEmptyString);
if (styleName.IsEmpty())
return false;
{
if (child->GetName() == wxT("style"))
{
- wxTextAttrEx attr;
+ wxTextAttr attr;
GetStyle(attr, child, false);
def->SetStyle(attr);
}
{
wxRichTextParagraphStyleDefinition* def = new wxRichTextParagraphStyleDefinition(styleName);
- wxString nextStyleName = node->GetPropVal(wxT("nextstyle"), wxEmptyString);
+ wxString nextStyleName = node->GetAttribute(wxT("nextstyle"), wxEmptyString);
def->SetNextStyle(nextStyleName);
def->SetBaseStyle(baseStyleName);
{
if (child->GetName() == wxT("style"))
{
- wxTextAttrEx attr;
+ wxTextAttr attr;
GetStyle(attr, child, false);
def->SetStyle(attr);
}
{
wxRichTextListStyleDefinition* def = new wxRichTextListStyleDefinition(styleName);
- wxString nextStyleName = node->GetPropVal(wxT("nextstyle"), wxEmptyString);
+ wxString nextStyleName = node->GetAttribute(wxT("nextstyle"), wxEmptyString);
def->SetNextStyle(nextStyleName);
def->SetBaseStyle(baseStyleName);
{
if (child->GetName() == wxT("style"))
{
- wxTextAttrEx attr;
+ wxTextAttr attr;
GetStyle(attr, child, false);
- wxString styleLevel = child->GetPropVal(wxT("level"), wxEmptyString);
+ wxString styleLevel = child->GetAttribute(wxT("level"), wxEmptyString);
if (styleLevel.IsEmpty())
{
def->SetStyle(attr);
OutputString(stream, str.Mid(last, i - last), convMem, convFile);
wxString s(wxT("&#"));
+#if wxUSE_UNICODE
s << (int) c;
+#else
+ s << (int) wxUChar(c);
+#endif
s << wxT(";");
OutputString(stream, s, NULL, NULL);
last = i + 1;
OutputString(stream, str.Mid(last, i - last), convMem, convFile);
}
+static wxString 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;
+}
+
inline static void OutputIndentation(wxOutputStream& stream, int indent)
{
wxString str = wxT("\n");
wxString s ;
s.Printf(wxT("<?xml version=\"%s\" encoding=\"%s\"?>\n"),
- (const wxChar*) version, (const wxChar*) fileEncoding );
+ version, fileEncoding);
OutputString(stream, s, NULL, NULL);
OutputString(stream, wxT("<richtext version=\"1.0.0.0\" xmlns=\"http://www.wxwidgets.org\">") , NULL, NULL);
int last = 0;
const wxString& text = textObj.GetText();
int len = (int) text.Length();
- for (i = 0; i < len; i++)
+
+ if (len == 0)
+ {
+ i = 0;
+ OutputIndentation(stream, indent);
+ OutputString(stream, wxT("<") + objectName, convMem, convFile);
+ OutputString(stream, style + wxT(">"), convMem, convFile);
+ OutputString(stream, wxT("</text>"), convMem, convFile);
+ }
+ else for (i = 0; i < len; i++)
{
+#if wxUSE_UNICODE
int c = (int) text[i];
- if (c < 32 && c != 9 && c != 10 && c != 13)
+#else
+ int c = (int) wxUChar(text[i]);
+#endif
+ if ((c < 32 || c == 34) && /* c != 9 && */ c != 10 && c != 13)
{
if (i > 0)
{
- OutputIndentation(stream, indent);
- OutputString(stream, wxT("<") + objectName, convMem, convFile);
-
- OutputString(stream, style + wxT(">"), convMem, convFile);
-
wxString fragment(text.Mid(last, i-last));
- if (!fragment.empty() && (fragment[0] == wxT(' ') || fragment[fragment.length()-1] == wxT(' ')))
+ if (!fragment.IsEmpty())
{
- OutputString(stream, wxT("\""), convMem, convFile);
- OutputStringEnt(stream, fragment, convMem, convFile);
- OutputString(stream, wxT("\""), convMem, convFile);
+ OutputIndentation(stream, indent);
+ OutputString(stream, wxT("<") + objectName, convMem, convFile);
+
+ OutputString(stream, style + wxT(">"), convMem, convFile);
+
+ if (!fragment.empty() && (fragment[0] == wxT(' ') || fragment[fragment.length()-1] == wxT(' ')))
+ {
+ OutputString(stream, wxT("\""), convMem, convFile);
+ OutputStringEnt(stream, fragment, convMem, convFile);
+ OutputString(stream, wxT("\""), convMem, convFile);
+ }
+ else
+ OutputStringEnt(stream, fragment, convMem, convFile);
+
+ OutputString(stream, wxT("</text>"), convMem, convFile);
}
- else
- OutputStringEnt(stream, fragment, convMem, convFile);
-
- OutputString(stream, wxT("</text>"), convMem, convFile);
}
// Output this character as a number in a separate tag, because XML can't cope
- // with entities below 32 except for 9, 10 and 13
+ // with entities below 32 except for 10 and 13
last = i + 1;
OutputIndentation(stream, indent);
OutputString(stream, wxT("<symbol"), convMem, convFile);
{
wxRichTextImage& imageObj = (wxRichTextImage&) obj;
+ wxString style = CreateStyle(obj.GetAttributes(), false);
+
if (imageObj.GetImage().Ok() && !imageObj.GetImageBlock().Ok())
imageObj.MakeBlock();
if (!imageObj.GetImageBlock().Ok())
{
// No data
- OutputString(stream, wxT(">"), convMem, convFile);
+ OutputString(stream, style + wxT(">"), convMem, convFile);
}
else
{
- OutputString(stream, wxString::Format(wxT(" imagetype=\"%d\">"), (int) imageObj.GetImageBlock().GetImageType()));
+ OutputString(stream, wxString::Format(wxT(" imagetype=\"%d\"") + style + wxT(">"), (int) imageObj.GetImageBlock().GetImageType()));
}
OutputIndentation(stream, indent+1);
int i;
for (i = 0; i < 10; i ++)
{
- wxRichTextAttr* levelAttr = listDef->GetLevelAttributes(i);
+ wxTextAttr* levelAttr = listDef->GetLevelAttributes(i);
if (levelAttr)
{
wxString style = CreateStyle(def->GetStyle(), false);
}
/// Create style parameters
-wxString wxRichTextXMLHandler::CreateStyle(const wxTextAttrEx& attr, bool isPara)
+wxString wxRichTextXMLHandler::CreateStyle(const wxTextAttr& attr, bool isPara)
{
wxString str;
if (attr.HasTextColour() && attr.GetTextColour().Ok())
str << wxT(" bgcolor=\"#") << ColourToHexString(attr.GetBackgroundColour()) << wxT("\"");
}
- if (attr.GetFont().Ok())
- {
- if (attr.HasFontSize())
- str << wxT(" fontsize=\"") << attr.GetFont().GetPointSize() << wxT("\"");
+ if (attr.HasFontSize())
+ str << wxT(" fontsize=\"") << attr.GetFontSize() << wxT("\"");
- //if (attr.HasFontFamily())
- // str << wxT(" fontfamily=\"") << attr.GetFont().GetFamily() << wxT("\"");
+ if (attr.HasFontFamily())
+ str << wxT(" fontfamily=\"") << attr.GetFont().GetFamily() << wxT("\"");
- if (attr.HasFontItalic())
- str << wxT(" fontstyle=\"") << attr.GetFont().GetStyle() << wxT("\"");
+ if (attr.HasFontItalic())
+ str << wxT(" fontstyle=\"") << attr.GetFontStyle() << wxT("\"");
- if (attr.HasFontWeight())
- str << wxT(" fontweight=\"") << attr.GetFont().GetWeight() << wxT("\"");
+ if (attr.HasFontWeight())
+ str << wxT(" fontweight=\"") << attr.GetFontWeight() << wxT("\"");
- if (attr.HasFontUnderlined())
- str << wxT(" fontunderlined=\"") << (int) attr.GetFont().GetUnderlined() << wxT("\"");
+ if (attr.HasFontUnderlined())
+ str << wxT(" fontunderlined=\"") << (int) attr.GetFontUnderlined() << wxT("\"");
- if (attr.HasFontFaceName())
- str << wxT(" fontface=\"") << attr.GetFont().GetFaceName() << wxT("\"");
- }
+ if (attr.HasFontFaceName())
+ str << wxT(" fontface=\"") << attr.GetFontFaceName() << wxT("\"");
if (attr.HasTextEffects())
{
if (!attr.GetCharacterStyleName().empty())
str << wxT(" characterstyle=\"") << wxString(attr.GetCharacterStyleName()) << wxT("\"");
+ if (attr.HasURL())
+ str << wxT(" url=\"") << AttributeToXML(attr.GetURL()) << wxT("\"");
+
if (isPara)
{
if (attr.HasAlignment())
if (attr.HasBulletName())
str << wxT(" bulletname=\"") << attr.GetBulletName() << wxT("\"");
- if (attr.HasURL())
- str << wxT(" url=\"") << attr.GetURL() << wxT("\"");
-
if (!attr.GetParagraphStyleName().empty())
str << wxT(" parstyle=\"") << wxString(attr.GetParagraphStyleName()) << wxT("\"");
return str;
}
+/// Replace face name with current name for platform.
+/// TODO: introduce a virtual function or settable table to
+/// do this comprehensively.
+bool wxRichTextFixFaceName(wxString& facename)
+{
+ if (facename.IsEmpty())
+ 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
+}
+
/// Get style parameters
-bool wxRichTextXMLHandler::GetStyle(wxTextAttrEx& attr, wxXmlNode* node, bool isPara)
+bool wxRichTextXMLHandler::GetStyle(wxTextAttr& attr, wxXmlNode* node, bool isPara)
{
wxString fontFacename;
int fontSize = 12;
- int fontFamily = wxDEFAULT;
- int fontWeight = wxNORMAL;
- int fontStyle = wxNORMAL;
+ wxFontFamily fontFamily = wxFONTFAMILY_DEFAULT;
+ wxFontWeight fontWeight = wxFONTWEIGHT_NORMAL;
+ wxFontStyle fontStyle = wxFONTSTYLE_NORMAL;
bool fontUnderlined = false;
- int fontFlags = 0;
+ // int fontFlags = 0;
- fontFacename = node->GetPropVal(wxT("fontface"), wxEmptyString);
+ fontFacename = node->GetAttribute(wxT("fontface"), wxEmptyString);
if (!fontFacename.IsEmpty())
- fontFlags |= wxTEXT_ATTR_FONT_FACE;
+ {
+ attr.SetFontFaceName(fontFacename);
+ if (GetFlags() & wxRICHTEXT_HANDLER_CONVERT_FACENAMES)
+ wxRichTextFixFaceName(fontFacename);
+ }
wxString value;
- //value = node->GetPropVal(wxT("fontfamily"), wxEmptyString);
- //if (!value.empty())
- // fontFamily = wxAtoi(value);
+ value = node->GetAttribute(wxT("fontfamily"), wxEmptyString);
+ if (!value.empty())
+ {
+ fontFamily = (wxFontFamily)wxAtoi(value);
+ attr.SetFontFamily(fontFamily);
+ }
- value = node->GetPropVal(wxT("fontstyle"), wxEmptyString);
+ value = node->GetAttribute(wxT("fontstyle"), wxEmptyString);
if (!value.empty())
{
- fontStyle = wxAtoi(value);
- fontFlags |= wxTEXT_ATTR_FONT_ITALIC;
+ fontStyle = (wxFontStyle)wxAtoi(value);
+ attr.SetFontStyle(fontStyle);
}
- value = node->GetPropVal(wxT("fontsize"), wxEmptyString);
+ value = node->GetAttribute(wxT("fontsize"), wxEmptyString);
if (!value.empty())
{
fontSize = wxAtoi(value);
- fontFlags |= wxTEXT_ATTR_FONT_SIZE;
+ attr.SetFontSize(fontSize);
}
- value = node->GetPropVal(wxT("fontweight"), wxEmptyString);
+ value = node->GetAttribute(wxT("fontweight"), wxEmptyString);
if (!value.empty())
{
- fontWeight = wxAtoi(value);
- fontFlags |= wxTEXT_ATTR_FONT_WEIGHT;
+ fontWeight = (wxFontWeight)wxAtoi(value);
+ attr.SetFontWeight(fontWeight);
}
- value = node->GetPropVal(wxT("fontunderlined"), wxEmptyString);
+ value = node->GetAttribute(wxT("fontunderlined"), wxEmptyString);
if (!value.empty())
{
fontUnderlined = wxAtoi(value) != 0;
- fontFlags |= wxTEXT_ATTR_FONT_UNDERLINE;
+ attr.SetFontUnderlined(fontUnderlined);
}
- attr.SetFlags(fontFlags);
-
- if (attr.HasFlag(wxTEXT_ATTR_FONT))
- 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->GetAttribute(wxT("textcolor"), wxEmptyString);
if (!value.empty())
{
if (value[0] == wxT('#'))
attr.SetTextColour(value);
}
- value = node->GetPropVal(wxT("backgroundcolor"), wxEmptyString);
+ value = node->GetAttribute(wxT("bgcolor"), wxEmptyString);
if (!value.empty())
{
if (value[0] == wxT('#'))
attr.SetBackgroundColour(value);
}
- value = node->GetPropVal(wxT("characterstyle"), wxEmptyString);
+ value = node->GetAttribute(wxT("characterstyle"), wxEmptyString);
if (!value.empty())
attr.SetCharacterStyleName(value);
- value = node->GetPropVal(wxT("texteffects"), wxEmptyString);
+ value = node->GetAttribute(wxT("texteffects"), wxEmptyString);
if (!value.IsEmpty())
{
attr.SetTextEffects(wxAtoi(value));
}
- value = node->GetPropVal(wxT("texteffectflags"), wxEmptyString);
+ value = node->GetAttribute(wxT("texteffectflags"), wxEmptyString);
if (!value.IsEmpty())
{
attr.SetTextEffectFlags(wxAtoi(value));
}
+ value = node->GetAttribute(wxT("url"), wxEmptyString);
+ if (!value.empty())
+ attr.SetURL(value);
+
// Set paragraph attributes
if (isPara)
{
- value = node->GetPropVal(wxT("alignment"), wxEmptyString);
+ value = node->GetAttribute(wxT("alignment"), wxEmptyString);
if (!value.empty())
attr.SetAlignment((wxTextAttrAlignment) wxAtoi(value));
int leftIndent = 0;
bool hasLeftIndent = false;
- value = node->GetPropVal(wxT("leftindent"), wxEmptyString);
+ value = node->GetAttribute(wxT("leftindent"), wxEmptyString);
if (!value.empty())
{
leftIndent = wxAtoi(value);
hasLeftIndent = true;
}
- value = node->GetPropVal(wxT("leftsubindent"), wxEmptyString);
+ value = node->GetAttribute(wxT("leftsubindent"), wxEmptyString);
if (!value.empty())
{
leftSubIndent = wxAtoi(value);
if (hasLeftIndent)
attr.SetLeftIndent(leftIndent, leftSubIndent);
- value = node->GetPropVal(wxT("rightindent"), wxEmptyString);
+ value = node->GetAttribute(wxT("rightindent"), wxEmptyString);
if (!value.empty())
attr.SetRightIndent(wxAtoi(value));
- value = node->GetPropVal(wxT("parspacingbefore"), wxEmptyString);
+ value = node->GetAttribute(wxT("parspacingbefore"), wxEmptyString);
if (!value.empty())
attr.SetParagraphSpacingBefore(wxAtoi(value));
- value = node->GetPropVal(wxT("parspacingafter"), wxEmptyString);
+ value = node->GetAttribute(wxT("parspacingafter"), wxEmptyString);
if (!value.empty())
attr.SetParagraphSpacingAfter(wxAtoi(value));
- value = node->GetPropVal(wxT("linespacing"), wxEmptyString);
+ value = node->GetAttribute(wxT("linespacing"), wxEmptyString);
if (!value.empty())
attr.SetLineSpacing(wxAtoi(value));
- value = node->GetPropVal(wxT("bulletstyle"), wxEmptyString);
+ value = node->GetAttribute(wxT("bulletstyle"), wxEmptyString);
if (!value.empty())
attr.SetBulletStyle(wxAtoi(value));
- value = node->GetPropVal(wxT("bulletnumber"), wxEmptyString);
+ value = node->GetAttribute(wxT("bulletnumber"), wxEmptyString);
if (!value.empty())
attr.SetBulletNumber(wxAtoi(value));
- value = node->GetPropVal(wxT("bulletsymbol"), wxEmptyString);
+ value = node->GetAttribute(wxT("bulletsymbol"), wxEmptyString);
if (!value.empty())
{
wxChar ch = wxAtoi(value);
attr.SetBulletText(s);
}
- value = node->GetPropVal(wxT("bullettext"), wxEmptyString);
+ value = node->GetAttribute(wxT("bullettext"), wxEmptyString);
if (!value.empty())
attr.SetBulletText(value);
- value = node->GetPropVal(wxT("bulletfont"), wxEmptyString);
+ value = node->GetAttribute(wxT("bulletfont"), wxEmptyString);
if (!value.empty())
attr.SetBulletFont(value);
- value = node->GetPropVal(wxT("bulletname"), wxEmptyString);
+ value = node->GetAttribute(wxT("bulletname"), wxEmptyString);
if (!value.empty())
attr.SetBulletName(value);
- value = node->GetPropVal(wxT("url"), wxEmptyString);
- if (!value.empty())
- attr.SetURL(value);
-
- value = node->GetPropVal(wxT("parstyle"), wxEmptyString);
+ value = node->GetAttribute(wxT("parstyle"), wxEmptyString);
if (!value.empty())
attr.SetParagraphStyleName(value);
- value = node->GetPropVal(wxT("liststyle"), wxEmptyString);
+ value = node->GetAttribute(wxT("liststyle"), wxEmptyString);
if (!value.empty())
attr.SetListStyleName(value);
- value = node->GetPropVal(wxT("tabs"), wxEmptyString);
+ value = node->GetAttribute(wxT("tabs"), wxEmptyString);
if (!value.empty())
{
wxArrayInt tabs;
attr.SetTabs(tabs);
}
- value = node->GetPropVal(wxT("pagebreak"), wxEmptyString);
+ value = node->GetAttribute(wxT("pagebreak"), wxEmptyString);
if (!value.IsEmpty())
{
attr.SetPageBreak(wxAtoi(value) != 0);
}
- value = node->GetPropVal(wxT("outlinelevel"), wxEmptyString);
+ value = node->GetAttribute(wxT("outlinelevel"), wxEmptyString);
if (!value.IsEmpty())
{
- attr.SetOutlineLevel(wxAtoi(value) != 0);
+ attr.SetOutlineLevel(wxAtoi(value));
}
}