X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/db3a1ef576c163e353e57ac4a3f2a55923773267..1ae30333bc929731802800694f85e6275986cd0a:/src/richtext/richtextxml.cpp diff --git a/src/richtext/richtextxml.cpp b/src/richtext/richtextxml.cpp index 4184e2fa3c..9a22fd4292 100644 --- a/src/richtext/richtextxml.cpp +++ b/src/richtext/richtextxml.cpp @@ -41,6 +41,7 @@ bool wxRichTextXMLHandler::DoLoadFile(wxRichTextBuffer *buffer, wxInputStream& s if (!stream.IsOk()) return false; + buffer->ResetAndClearCommands(); buffer->Clear(); wxXmlDocument* xmlDoc = new wxXmlDocument; @@ -55,6 +56,7 @@ bool wxRichTextXMLHandler::DoLoadFile(wxRichTextBuffer *buffer, wxInputStream& s if (!xmlDoc->Load(stream, encoding)) { + buffer->ResetAndClearCommands(); success = false; } else @@ -210,6 +212,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->GetPropVal(wxT("name"), wxEmptyString); + wxString sheetDescription = node->GetPropVal(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 +251,94 @@ bool wxRichTextXMLHandler::ImportXML(wxRichTextBuffer* buffer, wxXmlNode* node) return true; } +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); + + 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")) + { + wxTextAttrEx 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->GetPropVal(wxT("nextstyle"), wxEmptyString); + def->SetNextStyle(nextStyleName); + def->SetBaseStyle(baseStyleName); + + wxXmlNode* child = node->GetChildren(); + while (child) + { + if (child->GetName() == wxT("style")) + { + wxTextAttrEx 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->GetPropVal(wxT("nextstyle"), wxEmptyString); + def->SetNextStyle(nextStyleName); + def->SetBaseStyle(baseStyleName); + + wxXmlNode* child = node->GetChildren(); + while (child) + { + if (child->GetName() == wxT("style")) + { + wxTextAttrEx attr; + GetStyle(attr, child, false); + + wxString styleLevel = child->GetPropVal(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 @@ -460,8 +575,44 @@ bool wxRichTextXMLHandler::DoSaveFile(wxRichTextBuffer *buffer, wxOutputStream& OutputString(stream, wxT("") , NULL, NULL); int level = 1; - bool success = ExportXML(stream, convMem, convFile, *buffer, level); + 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); OutputString(stream, wxT("\n"), NULL, NULL); @@ -622,6 +773,111 @@ 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 ++) + { + wxRichTextAttr* 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 (!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); + + level --; + + OutputIndentation(stream, level); + OutputString(stream, wxT(""), convMem, convFile); + } + + return true; +} + /// Create style parameters wxString wxRichTextXMLHandler::CreateStyle(const wxTextAttrEx& attr, bool isPara) { @@ -656,6 +912,17 @@ wxString wxRichTextXMLHandler::CreateStyle(const wxTextAttrEx& attr, bool isPara str << wxT(" fontface=\"") << attr.GetFont().GetFaceName() << 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(" characterstyle=\"") << wxString(attr.GetCharacterStyleName()) << wxT("\""); @@ -688,15 +955,24 @@ 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.HasURL()) + str << wxT(" url=\"") << attr.GetURL() << wxT("\""); + if (!attr.GetParagraphStyleName().empty()) str << wxT(" parstyle=\"") << wxString(attr.GetParagraphStyleName()) << wxT("\""); @@ -715,6 +991,15 @@ wxString wxRichTextXMLHandler::CreateStyle(const wxTextAttrEx& attr, bool isPara } str << wxT("\""); } + + if (attr.HasPageBreak()) + { + str << wxT(" pagebreak=\"1\""); + } + + if (attr.HasOutlineLevel()) + str << wxT(" outlinelevel=\"") << (int) attr.GetOutlineLevel() << wxT("\""); + } return str; @@ -799,6 +1084,18 @@ bool wxRichTextXMLHandler::GetStyle(wxTextAttrEx& attr, wxXmlNode* node, bool is if (!value.empty()) attr.SetCharacterStyleName(value); + value = node->GetPropVal(wxT("texteffects"), wxEmptyString); + if (!value.IsEmpty()) + { + attr.SetTextEffects(wxAtoi(value)); + } + + value = node->GetPropVal(wxT("texteffectflags"), wxEmptyString); + if (!value.IsEmpty()) + { + attr.SetTextEffectFlags(wxAtoi(value)); + } + // Set paragraph attributes if (isPara) { @@ -853,7 +1150,16 @@ bool wxRichTextXMLHandler::GetStyle(wxTextAttrEx& attr, wxXmlNode* node, bool is value = node->GetPropVal(wxT("bulletsymbol"), wxEmptyString); if (!value.empty()) - attr.SetBulletSymbol(wxChar(wxAtoi(value))); + { + wxChar ch = wxAtoi(value); + wxString s; + s << ch; + attr.SetBulletText(s); + } + + value = node->GetPropVal(wxT("bullettext"), wxEmptyString); + if (!value.empty()) + attr.SetBulletText(value); value = node->GetPropVal(wxT("bulletfont"), wxEmptyString); if (!value.empty()) @@ -863,6 +1169,10 @@ bool wxRichTextXMLHandler::GetStyle(wxTextAttrEx& attr, wxXmlNode* node, bool is if (!value.empty()) attr.SetBulletName(value); + value = node->GetPropVal(wxT("url"), wxEmptyString); + if (!value.empty()) + attr.SetURL(value); + value = node->GetPropVal(wxT("parstyle"), wxEmptyString); if (!value.empty()) attr.SetParagraphStyleName(value); @@ -883,6 +1193,18 @@ bool wxRichTextXMLHandler::GetStyle(wxTextAttrEx& attr, wxXmlNode* node, bool is } attr.SetTabs(tabs); } + + value = node->GetPropVal(wxT("pagebreak"), wxEmptyString); + if (!value.IsEmpty()) + { + attr.SetPageBreak(wxAtoi(value) != 0); + } + + value = node->GetPropVal(wxT("outlinelevel"), wxEmptyString); + if (!value.IsEmpty()) + { + attr.SetOutlineLevel(wxAtoi(value) != 0); + } } return true;