X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/7b907278efbf53a35ab9eb0645f4ceb553aa02de..b5a9b87e1620e52f1f13d2619b4677f2b365c93f:/src/richtext/richtextxml.cpp diff --git a/src/richtext/richtextxml.cpp b/src/richtext/richtextxml.cpp index 1df105a391..feb26567ae 100644 --- a/src/richtext/richtextxml.cpp +++ b/src/richtext/richtextxml.cpp @@ -23,6 +23,7 @@ #ifndef WX_PRECOMP #include "wx/intl.h" #include "wx/module.h" + #include "wx/log.h" #endif #include "wx/filename.h" @@ -41,6 +42,7 @@ bool wxRichTextXMLHandler::DoLoadFile(wxRichTextBuffer *buffer, wxInputStream& s if (!stream.IsOk()) return false; + buffer->ResetAndClearCommands(); buffer->Clear(); wxXmlDocument* xmlDoc = new wxXmlDocument; @@ -55,6 +57,7 @@ bool wxRichTextXMLHandler::DoLoadFile(wxRichTextBuffer *buffer, wxInputStream& s if (!xmlDoc->Load(stream, encoding)) { + buffer->ResetAndClearCommands(); success = false; } else @@ -99,7 +102,7 @@ bool wxRichTextXMLHandler::ImportXML(wxRichTextBuffer* buffer, wxXmlNode* node) 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); } @@ -159,7 +162,7 @@ bool wxRichTextXMLHandler::ImportXML(wxRichTextBuffer* buffer, wxXmlNode* node) } textChild = textChild->GetNext(); } - + wxString actualText; actualText << (wxChar) wxAtoi(text); @@ -170,10 +173,22 @@ bool wxRichTextXMLHandler::ImportXML(wxRichTextBuffer* buffer, wxXmlNode* node) } 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 tag: %d", type); + } + else + { + imageType = (wxBitmapType)type; + } + } wxString data; @@ -198,6 +213,7 @@ bool wxRichTextXMLHandler::ImportXML(wxRichTextBuffer* buffer, wxXmlNode* node) if (!data.empty()) { wxRichTextImage* imageObj = new wxRichTextImage(para); + GetStyle(imageObj->GetAttributes(), child, false); para->AppendChild(imageObj); wxStringInputStream strStream(data); @@ -210,6 +226,31 @@ bool wxRichTextXMLHandler::ImportXML(wxRichTextBuffer* buffer, wxXmlNode* node) doneChildren = true; } + else if (name == wxT("stylesheet")) + { + if (GetFlags() & wxRICHTEXT_HANDLER_INCLUDE_STYLESHEET) + { + wxRichTextStyleSheet* sheet = new wxRichTextStyleSheet; + wxString sheetName = node->GetAttribute(wxT("name"), wxEmptyString); + wxString sheetDescription = node->GetAttribute(wxT("description"), wxEmptyString); + sheet->SetName(sheetName); + sheet->SetDescription(sheetDescription); + + wxXmlNode* child = node->GetChildren(); + while (child) + { + ImportStyleDefinition(sheet, child); + + child = child->GetNext(); + } + + // 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); + } + doneChildren = true; + } if (!doneChildren) { @@ -224,6 +265,94 @@ bool wxRichTextXMLHandler::ImportXML(wxRichTextBuffer* buffer, wxXmlNode* node) return true; } +bool wxRichTextXMLHandler::ImportStyleDefinition(wxRichTextStyleSheet* sheet, wxXmlNode* node) +{ + wxString styleType = node->GetName(); + wxString styleName = node->GetAttribute(wxT("name"), wxEmptyString); + wxString baseStyleName = node->GetAttribute(wxT("basestyle"), wxEmptyString); + + if (styleName.IsEmpty()) + return false; + + if (styleType == wxT("characterstyle")) + { + wxRichTextCharacterStyleDefinition* def = new wxRichTextCharacterStyleDefinition(styleName); + def->SetBaseStyle(baseStyleName); + + wxXmlNode* child = node->GetChildren(); + while (child) + { + if (child->GetName() == wxT("style")) + { + wxTextAttr attr; + GetStyle(attr, child, false); + def->SetStyle(attr); + } + child = child->GetNext(); + } + + sheet->AddCharacterStyle(def); + } + else if (styleType == wxT("paragraphstyle")) + { + wxRichTextParagraphStyleDefinition* def = new wxRichTextParagraphStyleDefinition(styleName); + + wxString nextStyleName = node->GetAttribute(wxT("nextstyle"), wxEmptyString); + def->SetNextStyle(nextStyleName); + def->SetBaseStyle(baseStyleName); + + wxXmlNode* child = node->GetChildren(); + while (child) + { + if (child->GetName() == wxT("style")) + { + wxTextAttr attr; + GetStyle(attr, child, false); + def->SetStyle(attr); + } + child = child->GetNext(); + } + + sheet->AddParagraphStyle(def); + } + else if (styleType == wxT("liststyle")) + { + wxRichTextListStyleDefinition* def = new wxRichTextListStyleDefinition(styleName); + + wxString nextStyleName = node->GetAttribute(wxT("nextstyle"), wxEmptyString); + def->SetNextStyle(nextStyleName); + def->SetBaseStyle(baseStyleName); + + wxXmlNode* child = node->GetChildren(); + while (child) + { + if (child->GetName() == wxT("style")) + { + wxTextAttr attr; + GetStyle(attr, child, false); + + wxString styleLevel = child->GetAttribute(wxT("level"), wxEmptyString); + if (styleLevel.IsEmpty()) + { + def->SetStyle(attr); + } + else + { + int level = wxAtoi(styleLevel); + if (level > 0 && level <= 10) + { + def->SetLevelAttributes(level-1, attr); + } + } + } + child = child->GetNext(); + } + + sheet->AddListStyle(def); + } + + return true; +} //----------------------------------------------------------------------------- // xml support routines @@ -361,7 +490,7 @@ static void OutputStringEnt(wxOutputStream& stream, const wxString& str, } last = i + 1; } - else if (c > 127) + else if (wxUChar(c) > 127) { OutputString(stream, str.Mid(last, i - last), convMem, convFile); @@ -375,6 +504,59 @@ static void OutputStringEnt(wxOutputStream& stream, const wxString& str, 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("&#")); + s << (int) c; + 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"); @@ -429,7 +611,10 @@ bool wxRichTextXMLHandler::DoSaveFile(wxRichTextBuffer *buffer, wxOutputStream& { if (m_encoding == wxT("")) { +#if wxUSE_INTL fileEncoding = wxLocale::GetSystemEncodingName(); + // if !wxUSE_INTL, we fall back to UTF-8 or ISO-8859-1 below +#endif } else { @@ -455,11 +640,47 @@ bool wxRichTextXMLHandler::DoSaveFile(wxRichTextBuffer *buffer, wxOutputStream& wxString s ; s.Printf(wxT("\n"), - (const wxChar*) version, (const wxChar*) fileEncoding ); + version, fileEncoding); OutputString(stream, s, NULL, NULL); OutputString(stream, wxT("") , NULL, NULL); int level = 1; + + if (buffer->GetStyleSheet() && (GetFlags() & wxRICHTEXT_HANDLER_INCLUDE_STYLESHEET)) + { + OutputIndentation(stream, level); + wxString nameAndDescr; + if (!buffer->GetStyleSheet()->GetName().IsEmpty()) + nameAndDescr << wxT(" name=\"") << buffer->GetStyleSheet()->GetName() << wxT("\""); + if (!buffer->GetStyleSheet()->GetDescription().IsEmpty()) + nameAndDescr << wxT(" description=\"") << buffer->GetStyleSheet()->GetDescription() << wxT("\""); + OutputString(stream, wxString(wxT(""), convMem, convFile); + + int i; + + for (i = 0; i < (int) buffer->GetStyleSheet()->GetCharacterStyleCount(); i++) + { + wxRichTextCharacterStyleDefinition* def = buffer->GetStyleSheet()->GetCharacterStyle(i); + ExportStyleDefinition(stream, convMem, convFile, def, level + 1); + } + + for (i = 0; i < (int) buffer->GetStyleSheet()->GetParagraphStyleCount(); i++) + { + wxRichTextParagraphStyleDefinition* def = buffer->GetStyleSheet()->GetParagraphStyle(i); + ExportStyleDefinition(stream, convMem, convFile, def, level + 1); + } + + for (i = 0; i < (int) buffer->GetStyleSheet()->GetListStyleCount(); i++) + { + wxRichTextListStyleDefinition* def = buffer->GetStyleSheet()->GetListStyle(i); + ExportStyleDefinition(stream, convMem, convFile, def, level + 1); + } + + OutputIndentation(stream, level); + OutputString(stream, wxT(""), convMem, convFile); + } + + bool success = ExportXML(stream, convMem, convFile, *buffer, level); OutputString(stream, wxT("\n") , NULL, NULL); @@ -485,23 +706,32 @@ bool wxRichTextXMLHandler::ExportXML(wxOutputStream& stream, wxMBConv* convMem, objectName = wxT("image"); else objectName = wxT("object"); - + bool terminateTag = true; if (obj.IsKindOf(CLASSINFO(wxRichTextPlainText))) { wxRichTextPlainText& textObj = (wxRichTextPlainText&) obj; - + wxString style = CreateStyle(obj.GetAttributes(), false); - + int i; 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(""), convMem, convFile); + } + else for (i = 0; i < len; i++) { int c = (int) text[i]; - if (c < 32 && c != 9 && c != 10 && c != 13) + if ((c < 32 || c == 34) && c != 9 && c != 10 && c != 13) { if (i > 0) { @@ -521,22 +751,22 @@ bool wxRichTextXMLHandler::ExportXML(wxOutputStream& stream, wxMBConv* convMem, OutputStringEnt(stream, fragment, convMem, convFile); OutputString(stream, wxT(""), 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 9, 10 and 13 last = i + 1; OutputIndentation(stream, indent); OutputString(stream, wxT(""), convMem, convFile); - OutputString(stream, wxString::Format(wxT("%d"), c), convMem, convFile); + OutputString(stream, wxString::Format(wxT("%d"), c), convMem, convFile); OutputString(stream, wxT(""), convMem, convFile); } } - + wxString fragment; if (last == 0) fragment = text; @@ -566,6 +796,8 @@ bool wxRichTextXMLHandler::ExportXML(wxOutputStream& stream, wxMBConv* convMem, { wxRichTextImage& imageObj = (wxRichTextImage&) obj; + wxString style = CreateStyle(obj.GetAttributes(), false); + if (imageObj.GetImage().Ok() && !imageObj.GetImageBlock().Ok()) imageObj.MakeBlock(); @@ -574,11 +806,11 @@ bool wxRichTextXMLHandler::ExportXML(wxOutputStream& stream, wxMBConv* convMem, 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); @@ -598,7 +830,7 @@ bool wxRichTextXMLHandler::ExportXML(wxOutputStream& stream, wxMBConv* convMem, isPara = true; wxString style = CreateStyle(obj.GetAttributes(), isPara); - + if (objectName == wxT("paragraphlayout") && ((wxRichTextParagraphLayoutBox&) obj).GetPartialParagraph()) style << wxT(" partialparagraph=\"true\""); @@ -622,8 +854,113 @@ bool wxRichTextXMLHandler::ExportXML(wxOutputStream& stream, wxMBConv* convMem, return true; } +bool wxRichTextXMLHandler::ExportStyleDefinition(wxOutputStream& stream, wxMBConv* convMem, wxMBConv* convFile, wxRichTextStyleDefinition* def, int level) +{ + wxRichTextCharacterStyleDefinition* charDef = wxDynamicCast(def, wxRichTextCharacterStyleDefinition); + wxRichTextParagraphStyleDefinition* paraDef = wxDynamicCast(def, wxRichTextParagraphStyleDefinition); + wxRichTextListStyleDefinition* listDef = wxDynamicCast(def, wxRichTextListStyleDefinition); + + wxString baseStyle = def->GetBaseStyle(); + wxString baseStyleProp; + if (!baseStyle.IsEmpty()) + baseStyleProp = wxT(" basestyle=\"") + baseStyle + wxT("\""); + + wxString descr = def->GetDescription(); + wxString descrProp; + if (!descr.IsEmpty()) + descrProp = wxT(" description=\"") + descr + wxT("\""); + + if (charDef) + { + OutputIndentation(stream, level); + OutputString(stream, wxT(""), convMem, convFile); + + level ++; + + wxString style = CreateStyle(def->GetStyle(), false); + + OutputIndentation(stream, level); + OutputString(stream, wxT(""), convMem, convFile); + + level --; + + OutputIndentation(stream, level); + OutputString(stream, wxT(""), convMem, convFile); + } + else if (listDef) + { + OutputIndentation(stream, level); + + if (!listDef->GetNextStyle().IsEmpty()) + baseStyleProp << wxT(" basestyle=\"") << listDef->GetNextStyle() << wxT("\""); + + OutputString(stream, wxT(""), convMem, convFile); + + level ++; + + wxString style = CreateStyle(def->GetStyle(), false); + + OutputIndentation(stream, level); + OutputString(stream, wxT(""), convMem, convFile); + + int i; + for (i = 0; i < 10; i ++) + { + wxTextAttr* levelAttr = listDef->GetLevelAttributes(i); + if (levelAttr) + { + wxString style = CreateStyle(def->GetStyle(), false); + wxString levelStr = wxString::Format(wxT(" level=\"%d\" "), (i+1)); + + OutputIndentation(stream, level); + OutputString(stream, wxT(""), convMem, convFile); + } + } + + level --; + + OutputIndentation(stream, level); + OutputString(stream, wxT(""), convMem, convFile); + } + else if (paraDef) + { + OutputIndentation(stream, level); + + if (!paraDef->GetNextStyle().IsEmpty()) + baseStyleProp << wxT(" basestyle=\"") << paraDef->GetNextStyle() << wxT("\""); + + OutputString(stream, wxT(""), convMem, convFile); + + level ++; + + wxString style = CreateStyle(def->GetStyle(), false); + + OutputIndentation(stream, level); + OutputString(stream, wxT(""), convMem, convFile); + + level --; + + OutputIndentation(stream, level); + OutputString(stream, wxT(""), convMem, convFile); + } + + return true; +} + /// 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()) @@ -635,29 +972,40 @@ wxString wxRichTextXMLHandler::CreateStyle(const wxTextAttrEx& attr, bool isPara str << wxT(" bgcolor=\"#") << ColourToHexString(attr.GetBackgroundColour()) << wxT("\""); } - if (attr.GetFont().Ok()) - { - if (attr.HasSize()) - str << wxT(" fontsize=\"") << attr.GetFont().GetPointSize() << wxT("\""); - - //if (attr.HasFamily()) - // str << wxT(" fontfamily=\"") << attr.GetFont().GetFamily() << wxT("\""); + if (attr.HasFontSize()) + str << wxT(" fontsize=\"") << attr.GetFontSize() << wxT("\""); + + if (attr.HasFontFamily()) + str << wxT(" fontfamily=\"") << attr.GetFont().GetFamily() << wxT("\""); - if (attr.HasItalic()) - str << wxT(" fontstyle=\"") << attr.GetFont().GetStyle() << wxT("\""); + if (attr.HasFontItalic()) + str << wxT(" fontstyle=\"") << attr.GetFontStyle() << wxT("\""); - if (attr.HasWeight()) - str << wxT(" fontweight=\"") << attr.GetFont().GetWeight() << wxT("\""); + if (attr.HasFontWeight()) + str << wxT(" fontweight=\"") << attr.GetFontWeight() << wxT("\""); - if (attr.HasUnderlined()) - str << wxT(" fontunderlined=\"") << (int) attr.GetFont().GetUnderlined() << wxT("\""); + if (attr.HasFontUnderlined()) + str << wxT(" fontunderlined=\"") << (int) attr.GetFontUnderlined() << wxT("\""); - if (attr.HasFaceName()) - str << wxT(" fontface=\"") << attr.GetFont().GetFaceName() << wxT("\""); + if (attr.HasFontFaceName()) + str << wxT(" fontface=\"") << attr.GetFontFaceName() << wxT("\""); + + if (attr.HasTextEffects()) + { + str << wxT(" texteffects=\""); + str << attr.GetTextEffects(); + str << wxT("\""); + + str << wxT(" texteffectflags=\""); + str << attr.GetTextEffectFlags(); + str << wxT("\""); } if (!attr.GetCharacterStyleName().empty()) - str << wxT(" charactertyle=\"") << wxString(attr.GetCharacterStyleName()) << wxT("\""); + str << wxT(" characterstyle=\"") << wxString(attr.GetCharacterStyleName()) << wxT("\""); + + if (attr.HasURL()) + str << wxT(" url=\"") << AttributeToXML(attr.GetURL()) << wxT("\""); if (isPara) { @@ -688,15 +1036,27 @@ wxString wxRichTextXMLHandler::CreateStyle(const wxTextAttrEx& attr, bool isPara if (attr.HasBulletNumber()) str << wxT(" bulletnumber=\"") << (int) attr.GetBulletNumber() << wxT("\""); - if (attr.HasBulletSymbol()) + if (attr.HasBulletText()) { - str << wxT(" bulletsymbol=\"") << (int) (attr.GetBulletSymbol()) << wxT("\""); + // If using a bullet symbol, convert to integer in case it's a non-XML-friendly character. + // Otherwise, assume it's XML-friendly text such as outline numbering, e.g. 1.2.3.1 + if (!attr.GetBulletText().IsEmpty() && (attr.GetBulletStyle() & wxTEXT_ATTR_BULLET_STYLE_SYMBOL)) + str << wxT(" bulletsymbol=\"") << (int) (attr.GetBulletText()[0]) << wxT("\""); + else + str << wxT(" bullettext=\"") << attr.GetBulletText() << wxT("\""); + str << wxT(" bulletfont=\"") << attr.GetBulletFont() << wxT("\""); } + if (attr.HasBulletName()) + str << wxT(" bulletname=\"") << attr.GetBulletName() << wxT("\""); + if (!attr.GetParagraphStyleName().empty()) str << wxT(" parstyle=\"") << wxString(attr.GetParagraphStyleName()) << wxT("\""); - + + if (!attr.GetListStyleName().empty()) + str << wxT(" liststyle=\"") << wxString(attr.GetListStyleName()) << wxT("\""); + if (attr.HasTabs()) { str << wxT(" tabs=\""); @@ -707,71 +1067,126 @@ wxString wxRichTextXMLHandler::CreateStyle(const wxTextAttrEx& attr, bool isPara str << wxT(","); str << attr.GetTabs()[i]; } - str << wxT("\""); + str << wxT("\""); } + + if (attr.HasPageBreak()) + { + str << wxT(" pagebreak=\"1\""); + } + + if (attr.HasOutlineLevel()) + str << wxT(" outlinelevel=\"") << (int) attr.GetOutlineLevel() << 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; - fontFacename = node->GetPropVal(wxT("fontface"), wxEmptyString); + // int fontFlags = 0; + + 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.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); + attr.SetFontUnderlined(fontUnderlined); + } + + value = node->GetAttribute(wxT("textcolor"), wxEmptyString); if (!value.empty()) { if (value[0] == wxT('#')) @@ -780,7 +1195,7 @@ bool wxRichTextXMLHandler::GetStyle(wxTextAttrEx& attr, wxXmlNode* node, bool is attr.SetTextColour(value); } - value = node->GetPropVal(wxT("backgroundcolor"), wxEmptyString); + value = node->GetAttribute(wxT("bgcolor"), wxEmptyString); if (!value.empty()) { if (value[0] == wxT('#')) @@ -789,29 +1204,45 @@ bool wxRichTextXMLHandler::GetStyle(wxTextAttrEx& attr, wxXmlNode* node, bool is attr.SetBackgroundColour(value); } - value = node->GetPropVal(wxT("characterstyle"), wxEmptyString); + value = node->GetAttribute(wxT("characterstyle"), wxEmptyString); if (!value.empty()) attr.SetCharacterStyleName(value); + value = node->GetAttribute(wxT("texteffects"), wxEmptyString); + if (!value.IsEmpty()) + { + attr.SetTextEffects(wxAtoi(value)); + } + + 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 leftSubIndent = 0; 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); @@ -821,43 +1252,60 @@ bool wxRichTextXMLHandler::GetStyle(wxTextAttrEx& attr, wxXmlNode* node, bool is 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); + wxString s; + s << ch; + attr.SetBulletText(s); + } + + value = node->GetAttribute(wxT("bullettext"), wxEmptyString); if (!value.empty()) - attr.SetBulletSymbol(wxAtoi(value)); + 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("parstyle"), wxEmptyString); + value = node->GetAttribute(wxT("bulletname"), wxEmptyString); + if (!value.empty()) + attr.SetBulletName(value); + + value = node->GetAttribute(wxT("parstyle"), wxEmptyString); if (!value.empty()) attr.SetParagraphStyleName(value); - - value = node->GetPropVal(wxT("tabs"), wxEmptyString); + + value = node->GetAttribute(wxT("liststyle"), wxEmptyString); + if (!value.empty()) + attr.SetListStyleName(value); + + value = node->GetAttribute(wxT("tabs"), wxEmptyString); if (!value.empty()) { wxArrayInt tabs; @@ -869,6 +1317,18 @@ bool wxRichTextXMLHandler::GetStyle(wxTextAttrEx& attr, wxXmlNode* node, bool is } attr.SetTabs(tabs); } + + value = node->GetAttribute(wxT("pagebreak"), wxEmptyString); + if (!value.IsEmpty()) + { + attr.SetPageBreak(wxAtoi(value) != 0); + } + + value = node->GetAttribute(wxT("outlinelevel"), wxEmptyString); + if (!value.IsEmpty()) + { + attr.SetOutlineLevel(wxAtoi(value)); + } } return true;