include/xmloff/txtparae.hxx | 45 ++ sw/source/core/unocore/unomapproperties.hxx | 4 sw/source/filter/xml/xmlexp.cxx | 4 xmloff/source/text/XMLRedlineExport.cxx | 132 ++++++ xmloff/source/text/XMLRedlineExport.hxx | 17 xmloff/source/text/txtparae.cxx | 552 +++++++++++++++++++++++++++- 6 files changed, 741 insertions(+), 13 deletions(-)
New commits: commit 79651457952e910786474c9751178077ca121c06 Author: Rosemary Sebastian <rosemarys...@gmail.com> Date: Wed Jun 22 14:37:36 2016 +0530 Implement export of insertion and deletion changes Change-Id: I6a8b580dc43c744bb181961ff26c95acd10207cb diff --git a/include/xmloff/txtparae.hxx b/include/xmloff/txtparae.hxx index 5e445bd..ce851f8 100644 --- a/include/xmloff/txtparae.hxx +++ b/include/xmloff/txtparae.hxx @@ -92,6 +92,7 @@ class XMLOFF_DLLPUBLIC XMLTextParagraphExport : public XMLStyleExport /// may be NULL (if no redlines should be exported; e.g. in block mode) XMLRedlineExport *pRedlineExport; + sal_uInt32 nParaIdx; bool bProgress; @@ -246,6 +247,11 @@ public: const css::uno::Reference< css::beans::XPropertyState > & rPropState, const css::uno::Reference< css::beans::XPropertySetInfo > & rPropSetInfo ); + void exportUndoTextRangeEnumeration( + const css::uno::Reference< css::container::XEnumeration > & rRangeEnum, + const sal_uInt32& rParaIdx, + bool bAutoStyles, bool bProgress, + bool bPrvChrIsSpc = true ); void exportTextRangeEnumeration( const css::uno::Reference< css::container::XEnumeration > & rRangeEnum, bool bAutoStyles, bool bProgress, @@ -268,6 +274,11 @@ protected: void exportNumStyles( bool bUsed ); + void exportUndoText( + const css::uno::Reference < + css::text::XText > & rText, + bool bAutoStyles, bool bProgress, bool bExportParagraph, TextPNS eExtensionNS = TextPNS::ODF ); + void exportText( const css::uno::Reference < css::text::XText > & rText, @@ -278,6 +289,15 @@ protected: const css::uno::Reference< css::text::XTextSection > & rBaseSection, bool bAutoStyles, bool bProgress, bool bExportParagraph, TextPNS eExtensionNS = TextPNS::ODF ); + bool exportUndoTextContentEnumeration( + const css::uno::Reference< css::container::XEnumeration > & rContentEnum, + bool bAutoStyles, + const css::uno::Reference< css::text::XTextSection > & rBaseSection, + bool bProgress, + bool bExportParagraph = true, + const css::uno::Reference< css::beans::XPropertySet > *pRangePropSet = nullptr, + bool bExportLevels = true, + TextPNS eExtensionNS = TextPNS::ODF); bool exportTextContentEnumeration( const css::uno::Reference< css::container::XEnumeration > & rContentEnum, bool bAutoStyles, @@ -287,6 +307,13 @@ protected: const css::uno::Reference< css::beans::XPropertySet > *pRangePropSet = nullptr, bool bExportLevels = true, TextPNS eExtensionNS = TextPNS::ODF); + void exportUndoParagraph( + const css::uno::Reference< css::text::XTextContent > & rTextContent, + const sal_uInt32& rParaIdx, + bool bAutoStyles, bool bProgress, + bool bExportParagraph, + MultiPropertySetHelper& rPropSetHelper, + TextPNS eExtensionNS = TextPNS::ODF); void exportParagraph( const css::uno::Reference< css::text::XTextContent > & rTextContent, bool bAutoStyles, bool bProgress, @@ -531,7 +558,25 @@ public: void exportTitleAndDescription( const css::uno::Reference< css::beans::XPropertySet > & rPropSet, const css::uno::Reference< css::beans::XPropertySetInfo > & rPropSetInfo ); + void setParaIdx(sal_uInt32 rParaIdx) + { + nParaIdx = rParaIdx; + } + + sal_uInt32 getParaIdx() + { + return nParaIdx; + } + // This method exports the given XText + void exportUndoText( + const css::uno::Reference< css::text::XText > & rText, + bool bIsProgress = false, + bool bExportParagraph = true, TextPNS eExtensionNS = TextPNS::ODF) + { + exportUndoText( rText, false, bIsProgress, bExportParagraph, eExtensionNS ); + } + void exportText( const css::uno::Reference< css::text::XText > & rText, bool bIsProgress = false, diff --git a/sw/source/core/unocore/unomapproperties.hxx b/sw/source/core/unocore/unomapproperties.hxx index e10b7d8..8edcb3b 100644 --- a/sw/source/core/unocore/unomapproperties.hxx +++ b/sw/source/core/unocore/unomapproperties.hxx @@ -74,8 +74,8 @@ {OUString(UNO_NAME_IS_IN_HEADER_FOOTER), 0, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},\ {OUString(UNO_NAME_REDLINE_TEXT), 0, cppu::UnoType<css::text::XText>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},\ {OUString(UNO_NAME_MERGE_LAST_PARA), 0, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},\ - {OUString(UNO_NAME_REDLINE_UNDO_START), 0, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},\ - {OUString(UNO_NAME_REDLINE_UNDO_END), 0, cppu::UnoType<bool>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0}, + {OUString(UNO_NAME_REDLINE_UNDO_START), 0, cppu::UnoType<sal_uInt32>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},\ + {OUString(UNO_NAME_REDLINE_UNDO_END), 0, cppu::UnoType<sal_uInt32>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0}, #define COMMON_CRSR_PARA_PROPERTIES_FN_ONLY \ { OUString(UNO_NAME_PARA_STYLE_NAME), FN_UNO_PARA_STYLE, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, 0}, \ { OUString(UNO_NAME_PAGE_STYLE_NAME), FN_UNO_PAGE_STYLE, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0}, \ diff --git a/sw/source/filter/xml/xmlexp.cxx b/sw/source/filter/xml/xmlexp.cxx index 75e2cd0..2812ec5 100644 --- a/sw/source/filter/xml/xmlexp.cxx +++ b/sw/source/filter/xml/xmlexp.cxx @@ -495,7 +495,9 @@ void SwXMLExport::ExportUndo_() { SvXMLElementExport aElem( *this, XML_NAMESPACE_OFFICE, XML_UNDO, true, true ); - GetTextParagraphExport()->exportTrackedChanges( false ); + Reference < XTextDocument > xTextDoc( GetModel(), UNO_QUERY ); + Reference < XText > xText = xTextDoc->getText(); + GetTextParagraphExport()->exportUndoText( xText, bShowProgress ); } namespace diff --git a/xmloff/source/text/XMLRedlineExport.cxx b/xmloff/source/text/XMLRedlineExport.cxx index 4226e4a..aaf776b 100644 --- a/xmloff/source/text/XMLRedlineExport.cxx +++ b/xmloff/source/text/XMLRedlineExport.cxx @@ -102,6 +102,17 @@ XMLRedlineExport::~XMLRedlineExport() aChangeMap.clear(); } +void XMLRedlineExport::ExportUndoChange( + const Reference<XPropertySet> & rPropSet, + const sal_uInt32& rParaIdx, + bool bAutoStyle) +{ + if (!bAutoStyle) + { + ExportUndoChangeInfo(rPropSet, rParaIdx); + } + +} void XMLRedlineExport::ExportChange( const Reference<XPropertySet> & rPropSet, @@ -119,6 +130,11 @@ void XMLRedlineExport::ExportChange( if (pCurrentChangesList != nullptr) ExportChangeAutoStyle(rPropSet); } + else + { + ExportChangeInline(rPropSet); + } + } @@ -199,7 +215,6 @@ void XMLRedlineExport::SetCurrentXText() pCurrentChangesList = nullptr; } - void XMLRedlineExport::ExportChangesListElements() { // get redlines (aka tracked changes) from the model @@ -324,15 +339,106 @@ void XMLRedlineExport::ExportChangesListAutoStyles() } } +void XMLRedlineExport::ExportUndoChangeInline( + const Reference<XPropertySet> & rPropSet, const sal_uInt32& rParaIdx) +{ + // determine element name (depending on collapsed, start/end) + { + { + Any aAny; + aAny = rPropSet->getPropertyValue(sRedlineType); + OUString sType; + aAny >>= sType; + + sal_uInt32 nParagraphIdx = rParaIdx, nCharStart, nCharEnd; + rPropSet->getPropertyValue(sRedlineUndoStart) >>= nCharStart; + rPropSet->getPropertyValue(sRedlineUndoEnd) >>= nCharEnd; + if(sType == sDelete) + nParagraphIdx++; + + XMLTokenEnum eUndoType = XML_PARAGRAPH; + OUString sUndoType; + aAny = rPropSet->getPropertyValue(sRedlineUndoType); + aAny >>= sUndoType; + + if( sUndoType == "text" ) + eUndoType = XML_TEXT; + if(eUndoType == XML_PARAGRAPH) + { + rExport.AddAttribute(XML_NAMESPACE_C, XML_START, "/" + rtl::OUString::number(nParagraphIdx)); + rExport.AddAttribute(XML_NAMESPACE_DC, XML_TYPE, XML_PARAGRAPH); + } + else + { + rExport.AddAttribute(XML_NAMESPACE_C, XML_START, "/" + rtl::OUString::number(nParagraphIdx) + "/" + rtl::OUString::number(nCharStart)); + if( sType == sInsert || sType == sFormat ) + rExport.AddAttribute(XML_NAMESPACE_C, XML_END, "/" + rtl::OUString::number(nParagraphIdx) + "/" + rtl::OUString::number(nCharEnd)); + rExport.AddAttribute(XML_NAMESPACE_DC, XML_TYPE, eUndoType); + } + SvXMLElementExport aChange(rExport, XML_NAMESPACE_TEXT, + ConvertTypeName(sType), true, true); + + // get XText from the redline and export (if the XText exists) + aAny = rPropSet->getPropertyValue(sRedlineText); + Reference<XText> xText; + aAny >>= xText; + if (xText.is()) + { + rExport.GetTextParagraphExport()->exportText(xText); + // default parameters: bProgress, bExportParagraph ??? + } + } + } +} + +void XMLRedlineExport::ExportChangeInline( + const Reference<XPropertySet> & rPropSet) +{ + // determine element name (depending on collapsed, start/end) + enum XMLTokenEnum eElement = XML_TOKEN_INVALID; + Any aAny = rPropSet->getPropertyValue(sIsCollapsed); + bool bCollapsed = *static_cast<sal_Bool const *>(aAny.getValue()); + if (bCollapsed) + { + eElement = XML_CHANGE; + } + else + { + aAny = rPropSet->getPropertyValue(sIsStart); + const bool bStart = *static_cast<sal_Bool const *>(aAny.getValue()); + eElement = bStart ? XML_CHANGE_START : XML_CHANGE_END; + } + + if (XML_TOKEN_INVALID != eElement) + { + // we always need the ID + rExport.AddAttribute(XML_NAMESPACE_TEXT, XML_CHANGE_ID, + GetRedlineID(rPropSet)); + + // export the element (no whitespace because we're in the text body) + SvXMLElementExport aChangeElem(rExport, XML_NAMESPACE_TEXT, + eElement, false, false); + } +} + + void XMLRedlineExport::ExportChangedRegion( const Reference<XPropertySet> & rPropSet) { + // Redline-ID + rExport.AddAttributeIdLegacy(XML_NAMESPACE_TEXT, GetRedlineID(rPropSet)); + // merge-last-paragraph Any aAny = rPropSet->getPropertyValue(sMergeLastPara); if( ! *static_cast<sal_Bool const *>(aAny.getValue()) ) rExport.AddAttribute(XML_NAMESPACE_TEXT, XML_MERGE_LAST_PARAGRAPH, XML_FALSE); + // export change region element + SvXMLElementExport aChangedRegion(rExport, XML_NAMESPACE_TEXT, + XML_CHANGED_REGION, true, true); + + // scope for (first) change element { aAny = rPropSet->getPropertyValue(sRedlineType); @@ -441,6 +547,30 @@ const OUString XMLRedlineExport::GetRedlineID( return sBuf.makeStringAndClear(); } +void XMLRedlineExport::ExportUndoChangeInfo( + const Reference<XPropertySet> & rPropSet, const sal_uInt32& rParaIdx) +{ + { + Any aAny = rPropSet->getPropertyValue(sRedlineAuthor); + OUString sAuthor; + aAny >>= sAuthor; + if (!sAuthor.isEmpty()) + { + rExport.AddAttribute(XML_NAMESPACE_DC, XML_CREATOR, sAuthor); + } + + aAny = rPropSet->getPropertyValue(sRedlineDateTime); + util::DateTime aDateTime; + aAny >>= aDateTime; + OUStringBuffer sBuf; + ::sax::Converter::convertDateTime(sBuf, aDateTime, nullptr); + rExport.AddAttribute(XML_NAMESPACE_DC, XML_DATE, sBuf.makeStringAndClear()); + + SvXMLElementExport aChange(rExport, XML_NAMESPACE_OFFICE, + XML_CHANGE, true, true); + ExportUndoChangeInline(rPropSet, rParaIdx); + } +} void XMLRedlineExport::ExportChangeInfo( const Reference<XPropertySet> & rPropSet) diff --git a/xmloff/source/text/XMLRedlineExport.hxx b/xmloff/source/text/XMLRedlineExport.hxx index 1ece917..bac2901 100644 --- a/xmloff/source/text/XMLRedlineExport.hxx +++ b/xmloff/source/text/XMLRedlineExport.hxx @@ -103,6 +103,12 @@ public: ~XMLRedlineExport(); /// export a change + void ExportUndoChange( + /// PropertySet of RedlinePortion + const css::uno::Reference<css::beans::XPropertySet> & rPropSet, + const sal_uInt32& rParaIdx, + bool bAutoStyle); + void ExportChange( /// PropertySet of RedlinePortion const css::uno::Reference<css::beans::XPropertySet> & rPropSet, @@ -145,6 +151,14 @@ public: bool bStart); private: + /// export the change mark contained in the text body + void ExportUndoChangeInline( + /// PropertySet of RedlinePortion + const css::uno::Reference<css::beans::XPropertySet> & rPropSet, const sal_uInt32& rParaIdx); + + void ExportChangeInline( + /// PropertySet of RedlinePortion + const css::uno::Reference<css::beans::XPropertySet> & rPropSet); /// export the auto styles used in this change void ExportChangeAutoStyle( @@ -162,6 +176,9 @@ private: const css::uno::Reference<css::beans::XPropertySet> & rPropSet); /// export an change-info element (from a PropertySet) + void ExportUndoChangeInfo( + const css::uno::Reference<css::beans::XPropertySet> & rPropSet, const sal_uInt32& rParaIdx); + void ExportChangeInfo( const css::uno::Reference<css::beans::XPropertySet> & rPropSet); diff --git a/xmloff/source/text/txtparae.cxx b/xmloff/source/text/txtparae.cxx index d64165e..73bc313 100644 --- a/xmloff/source/text/txtparae.cxx +++ b/xmloff/source/text/txtparae.cxx @@ -1162,6 +1162,7 @@ XMLTextParagraphExport::XMLTextParagraphExport( pSectionExport( nullptr ), pIndexMarkExport( nullptr ), pRedlineExport( nullptr ), + nParaIdx(0), bProgress( false ), bBlock( false ), bOpenRuby( false ), @@ -1628,6 +1629,67 @@ bool XMLTextParagraphExport::collectTextAutoStylesOptimized( bool bIsProgress ) return true; } +void XMLTextParagraphExport::exportUndoText( + const Reference < XText > & rText, + bool bAutoStyles, + bool bIsProgress, + bool bExportParagraph, + TextPNS eExtensionNS) +{ + if( bAutoStyles ) + GetExport().GetShapeExport(); // make sure the graphics styles family + // is added + Reference < XEnumerationAccess > xEA( rText, UNO_QUERY ); + Reference < XEnumeration > xParaEnum(xEA->createEnumeration()); + Reference < XPropertySet > xPropertySet( rText, UNO_QUERY ); + Reference < XTextSection > xBaseSection; + + // #97718# footnotes don't supply paragraph enumerations in some cases + // This is always a bug, but at least we don't want to crash. + DBG_ASSERT( xParaEnum.is(), "We need a paragraph enumeration" ); + if( ! xParaEnum.is() ) + return; + + bool bExportLevels = true; + + if (xPropertySet.is()) + { + Reference < XPropertySetInfo > xInfo ( xPropertySet->getPropertySetInfo() ); + + if( xInfo.is() ) + { + if (xInfo->hasPropertyByName( sTextSection )) + { + xPropertySet->getPropertyValue(sTextSection) >>= xBaseSection ; + } + +/* #i35937# + // for applications that use the outliner we need to check if + // the current text object needs the level information exported + if( !bAutoStyles ) + { + // fixme: move string to class member, couldn't do now because + // of no incompatible build + OUString sHasLevels( "HasLevels" ); + if (xInfo->hasPropertyByName( sHasLevels ) ) + { + xPropertySet->getPropertyValue(sHasLevels) >>= bExportLevels; + } + } +*/ + } + } + + // #96530# Export redlines at start & end of XText before & after + // exporting the text content enumeration + if( !bAutoStyles && (pRedlineExport != nullptr) ) + pRedlineExport->ExportStartOrEndRedline( xPropertySet, true ); + exportUndoTextContentEnumeration( xParaEnum, bAutoStyles, xBaseSection, + bIsProgress, bExportParagraph, nullptr, bExportLevels, eExtensionNS ); + if( !bAutoStyles && (pRedlineExport != nullptr) ) + pRedlineExport->ExportStartOrEndRedline( xPropertySet, false ); +} + void XMLTextParagraphExport::exportText( const Reference < XText > & rText, bool bAutoStyles, @@ -1721,6 +1783,175 @@ void XMLTextParagraphExport::exportText( pRedlineExport->ExportStartOrEndRedline( xPropertySet, false ); } +bool XMLTextParagraphExport::exportUndoTextContentEnumeration( + const Reference < XEnumeration > & rContEnum, + bool bAutoStyles, + const Reference < XTextSection > & rBaseSection, + bool bIsProgress, + bool bExportParagraph, + const Reference < XPropertySet > *pRangePropSet, + bool bExportLevels, TextPNS eExtensionNS ) +{ + DBG_ASSERT( rContEnum.is(), "No enumeration to export!" ); + bool bHasMoreElements = rContEnum->hasMoreElements(); + if( !bHasMoreElements ) + return false; + + XMLTextNumRuleInfo aPrevNumInfo; + XMLTextNumRuleInfo aNextNumInfo; + + bool bHasContent = false; + Reference<XTextSection> xCurrentTextSection(rBaseSection); + + MultiPropertySetHelper aPropSetHelper( + bAutoStyles ? aParagraphPropertyNamesAuto : + aParagraphPropertyNames ); + + bool bHoldElement = false; + Reference < XTextContent > xTxtCntnt; + while( bHoldElement || bHasMoreElements ) + { + if (bHoldElement) + { + bHoldElement = false; + } + else + { + xTxtCntnt.set(rContEnum->nextElement(), uno::UNO_QUERY); + + aPropSetHelper.resetValues(); + + } + + Reference<XServiceInfo> xServiceInfo( xTxtCntnt, UNO_QUERY ); + if( xServiceInfo->supportsService( sParagraphService ) ) + { + if( bExportLevels ) + { + if( bAutoStyles ) + { + exportListAndSectionChange( xCurrentTextSection, xTxtCntnt, + aPrevNumInfo, aNextNumInfo, + bAutoStyles ); + } + else + { + /* Pass list auto style pool to <XMLTextNumRuleInfo> instance + Pass info about request to export <text:number> element + to <XMLTextNumRuleInfo> instance (#i69627#) + */ + aNextNumInfo.Set( xTxtCntnt, + GetExport().writeOutlineStyleAsNormalListStyle(), + GetListAutoStylePool(), + GetExport().exportTextNumberElement() ); + + exportListAndSectionChange( xCurrentTextSection, aPropSetHelper, + TEXT_SECTION, xTxtCntnt, + aPrevNumInfo, aNextNumInfo, + bAutoStyles ); + } + } + + // if we found a mute section: skip all section content + if (pSectionExport->IsMuteSection(xCurrentTextSection)) + { + // Make sure headings are exported anyway. + if( !bAutoStyles ) + pSectionExport->ExportMasterDocHeadingDummies(); + + while (rContEnum->hasMoreElements() && + pSectionExport->IsInSection( xCurrentTextSection, + xTxtCntnt, true )) + { + xTxtCntnt.set(rContEnum->nextElement(), uno::UNO_QUERY); + aPropSetHelper.resetValues(); + aNextNumInfo.Reset(); + } + // the first non-mute element still needs to be processed + bHoldElement = + ! pSectionExport->IsInSection( xCurrentTextSection, + xTxtCntnt, false ); + } + else + { + setParaIdx(getParaIdx() + 1); + exportUndoParagraph( xTxtCntnt, getParaIdx(), bAutoStyles, bIsProgress, + bExportParagraph, aPropSetHelper, eExtensionNS ); + } + bHasContent = true; + } + else if( xServiceInfo->supportsService( sTableService ) ) + { + if( !bAutoStyles ) + { + aNextNumInfo.Reset(); + } + + exportListAndSectionChange( xCurrentTextSection, xTxtCntnt, + aPrevNumInfo, aNextNumInfo, + bAutoStyles ); + + if (! pSectionExport->IsMuteSection(xCurrentTextSection)) + { + // export start + end redlines (for wholly redlined tables) + if ((! bAutoStyles) && (nullptr != pRedlineExport)) + pRedlineExport->ExportStartOrEndRedline(xTxtCntnt, true); + + exportTable( xTxtCntnt, bAutoStyles, bIsProgress ); + + if ((! bAutoStyles) && (nullptr != pRedlineExport)) + pRedlineExport->ExportStartOrEndRedline(xTxtCntnt, false); + } + else if( !bAutoStyles ) + { + // Make sure headings are exported anyway. + pSectionExport->ExportMasterDocHeadingDummies(); + } + + bHasContent = true; + } + else if( xServiceInfo->supportsService( sTextFrameService ) ) + { + exportTextFrame( xTxtCntnt, bAutoStyles, bIsProgress, true, pRangePropSet ); + } + else if( xServiceInfo->supportsService( sTextGraphicService ) ) + { + exportTextGraphic( xTxtCntnt, bAutoStyles, pRangePropSet ); + } + else if( xServiceInfo->supportsService( sTextEmbeddedService ) ) + { + exportTextEmbedded( xTxtCntnt, bAutoStyles, pRangePropSet ); + } + else if( xServiceInfo->supportsService( sShapeService ) ) + { + exportShape( xTxtCntnt, bAutoStyles, pRangePropSet ); + } + else + { + DBG_ASSERT( !xTxtCntnt.is(), "unknown text content" ); + } + + if( !bAutoStyles ) + { + aPrevNumInfo = aNextNumInfo; + } + + bHasMoreElements = rContEnum->hasMoreElements(); + } + + if( bExportLevels && bHasContent && !bAutoStyles ) + { + aNextNumInfo.Reset(); + + // close open lists and sections; no new styles + exportListAndSectionChange( xCurrentTextSection, rBaseSection, + aPrevNumInfo, aNextNumInfo, + bAutoStyles ); + } + + return true; +} + bool XMLTextParagraphExport::exportTextContentEnumeration( const Reference < XEnumeration > & rContEnum, bool bAutoStyles, @@ -1811,8 +2042,10 @@ bool XMLTextParagraphExport::exportTextContentEnumeration( xTxtCntnt, false ); } else + { exportParagraph( xTxtCntnt, bAutoStyles, bIsProgress, - bExportParagraph, aPropSetHelper, eExtensionNS ); + bExportParagraph, aPropSetHelper, eExtensionNS ); + } bHasContent = true; } else if( xServiceInfo->supportsService( sTableService ) ) @@ -1887,8 +2120,8 @@ bool XMLTextParagraphExport::exportTextContentEnumeration( return true; } -void XMLTextParagraphExport::exportParagraph( - const Reference < XTextContent > & rTextContent, +void XMLTextParagraphExport::exportUndoParagraph( + const Reference < XTextContent > & rTextContent, const sal_uInt32& rParaIdx, bool bAutoStyles, bool bIsProgress, bool bExportParagraph, MultiPropertySetHelper& rPropSetHelper, TextPNS eExtensionNS) { @@ -2125,28 +2358,329 @@ void XMLTextParagraphExport::exportParagraph( if( bAutoStyles ) { if( bHasContentEnum ) - exportTextContentEnumeration( + exportUndoTextContentEnumeration( xContentEnum, bAutoStyles, xSection, bIsProgress ); if ( bHasPortions ) - exportTextRangeEnumeration( xTextEnum, bAutoStyles, bIsProgress ); + exportUndoTextRangeEnumeration( xTextEnum, rParaIdx, bAutoStyles, bIsProgress ); } else { bool bPrevCharIsSpace = true; enum XMLTokenEnum eElem = 0 < nOutlineLevel ? XML_H : XML_P; - SvXMLElementExport aElem( GetExport(), eExtensionNS == TextPNS::EXTENSION ? XML_NAMESPACE_LO_EXT : XML_NAMESPACE_TEXT, eElem, - true, false ); if( bHasContentEnum ) - bPrevCharIsSpace = !exportTextContentEnumeration( + bPrevCharIsSpace = !exportUndoTextContentEnumeration( xContentEnum, bAutoStyles, xSection, bIsProgress ); - exportTextRangeEnumeration( xTextEnum, bAutoStyles, bIsProgress, + exportUndoTextRangeEnumeration( xTextEnum, rParaIdx, bAutoStyles, bIsProgress, bPrevCharIsSpace ); } } +void XMLTextParagraphExport::exportParagraph( + const Reference < XTextContent > & rTextContent, + bool bAutoStyles, bool bIsProgress, bool bExportParagraph, + MultiPropertySetHelper& rPropSetHelper, TextPNS eExtensionNS) +{ + sal_Int16 nOutlineLevel = -1; + + if( bIsProgress ) + { + ProgressBarHelper *pProgress = GetExport().GetProgressBarHelper(); + pProgress->SetValue( pProgress->GetValue()+1 ); + } + + // get property set or multi property set and initialize helper + Reference<XMultiPropertySet> xMultiPropSet( rTextContent, UNO_QUERY ); + Reference<XPropertySet> xPropSet( rTextContent, UNO_QUERY ); + + // check for supported properties + if( !rPropSetHelper.checkedProperties() ) + rPropSetHelper.hasProperties( xPropSet->getPropertySetInfo() ); + +// if( xMultiPropSet.is() ) +// rPropSetHelper.getValues( xMultiPropSet ); +// else +// rPropSetHelper.getValues( xPropSet ); + + if( bExportParagraph ) + { + if( bAutoStyles ) + { + Add( XML_STYLE_FAMILY_TEXT_PARAGRAPH, rPropSetHelper, xPropSet ); + } + else + { + // xml:id for RDF metadata + GetExport().AddAttributeXmlId(rTextContent); + GetExport().AddAttributesRDFa(rTextContent); + + OUString sStyle; + if( rPropSetHelper.hasProperty( PARA_STYLE_NAME ) ) + { + if( xMultiPropSet.is() ) + rPropSetHelper.getValue( PARA_STYLE_NAME, + xMultiPropSet ) >>= sStyle; + else + rPropSetHelper.getValue( PARA_STYLE_NAME, + xPropSet ) >>= sStyle; + } + + if( rTextContent.is() ) + { + const OUString& rIdentifier = GetExport().getInterfaceToIdentifierMapper().getIdentifier( rTextContent ); + if( !rIdentifier.isEmpty() ) + { + // FIXME: this is just temporary until EditEngine + // paragraphs implement XMetadatable. + // then that must be used and not the mapper, because + // when both can be used we get two xml:id! + uno::Reference<rdf::XMetadatable> const xMeta(rTextContent, + uno::UNO_QUERY); + OSL_ENSURE(!xMeta.is(), "paragraph that implements " + "XMetadatable used in interfaceToIdentifierMapper?"); + GetExport().AddAttributeIdLegacy(XML_NAMESPACE_TEXT, + rIdentifier); + } + } + + OUString sAutoStyle( sStyle ); + sAutoStyle = Find( XML_STYLE_FAMILY_TEXT_PARAGRAPH, xPropSet, sStyle ); + if( !sAutoStyle.isEmpty() ) + GetExport().AddAttribute( XML_NAMESPACE_TEXT, XML_STYLE_NAME, + GetExport().EncodeStyleName( sAutoStyle ) ); + + if( rPropSetHelper.hasProperty( PARA_CONDITIONAL_STYLE_NAME ) ) + { + OUString sCondStyle; + if( xMultiPropSet.is() ) + rPropSetHelper.getValue( PARA_CONDITIONAL_STYLE_NAME, + xMultiPropSet ) >>= sCondStyle; + else + rPropSetHelper.getValue( PARA_CONDITIONAL_STYLE_NAME, + xPropSet ) >>= sCondStyle; + if( sCondStyle != sStyle ) + { + sCondStyle = Find( XML_STYLE_FAMILY_TEXT_PARAGRAPH, xPropSet, + sCondStyle ); + if( !sCondStyle.isEmpty() ) + GetExport().AddAttribute( XML_NAMESPACE_TEXT, + XML_COND_STYLE_NAME, + GetExport().EncodeStyleName( sCondStyle ) ); + } + } + + if( rPropSetHelper.hasProperty( PARA_OUTLINE_LEVEL ) ) + { + if( xMultiPropSet.is() ) + rPropSetHelper.getValue( PARA_OUTLINE_LEVEL, + xMultiPropSet ) >>= nOutlineLevel; + else + rPropSetHelper.getValue( PARA_OUTLINE_LEVEL, + xPropSet ) >>= nOutlineLevel; + + if( 0 < nOutlineLevel ) + { + OUStringBuffer sTmp; + sTmp.append( sal_Int32( nOutlineLevel) ); + GetExport().AddAttribute( XML_NAMESPACE_TEXT, + XML_OUTLINE_LEVEL, + sTmp.makeStringAndClear() ); + + if( rPropSetHelper.hasProperty( NUMBERING_IS_NUMBER ) ) + { + bool bIsNumber = false; + if( xMultiPropSet.is() ) + rPropSetHelper.getValue( + NUMBERING_IS_NUMBER, xMultiPropSet ) >>= bIsNumber; + else + rPropSetHelper.getValue( + NUMBERING_IS_NUMBER, xPropSet ) >>= bIsNumber; + + OUString sListStyleName; + if( xMultiPropSet.is() ) + rPropSetHelper.getValue( + PARA_NUMBERING_STYLENAME, xMultiPropSet ) >>= sListStyleName; + else + rPropSetHelper.getValue( + PARA_NUMBERING_STYLENAME, xPropSet ) >>= sListStyleName; + + bool bAssignedtoOutlineStyle = false; + { + Reference< XChapterNumberingSupplier > xCNSupplier( GetExport().GetModel(), UNO_QUERY ); + + OUString sOutlineName; + if (xCNSupplier.is()) + { + Reference< XIndexReplace > xNumRule ( xCNSupplier->getChapterNumberingRules() ); + DBG_ASSERT( xNumRule.is(), "no chapter numbering rules" ); + + if (xNumRule.is()) + { + Reference< XPropertySet > xNumRulePropSet( xNumRule, UNO_QUERY ); + xNumRulePropSet->getPropertyValue( + "Name" ) >>= sOutlineName; + bAssignedtoOutlineStyle = ( sListStyleName == sOutlineName ); + } + } + } + + if( ! bIsNumber && bAssignedtoOutlineStyle ) + GetExport().AddAttribute( XML_NAMESPACE_TEXT, + XML_IS_LIST_HEADER, + XML_TRUE ); + } + + { + bool bIsRestartNumbering = false; + + Reference< XPropertySetInfo > + xPropSetInfo(xMultiPropSet.is() ? + xMultiPropSet->getPropertySetInfo(): + xPropSet->getPropertySetInfo()); + + if (xPropSetInfo-> + hasPropertyByName("ParaIsNumberingRestart")) + { + xPropSet->getPropertyValue("ParaIsNumberingRestart") + >>= bIsRestartNumbering; + } + + if (bIsRestartNumbering) + { + GetExport().AddAttribute(XML_NAMESPACE_TEXT, + XML_RESTART_NUMBERING, + XML_TRUE); + + if (xPropSetInfo-> + hasPropertyByName("NumberingStartValue")) + { + sal_Int32 nStartValue = 0; + + xPropSet->getPropertyValue("NumberingStartValue") + >>= nStartValue; + + OUStringBuffer sTmpStartValue; + + sTmpStartValue.append(nStartValue); + + GetExport(). + AddAttribute(XML_NAMESPACE_TEXT, + XML_START_VALUE, + sTmpStartValue. + makeStringAndClear()); + } + } + } + } + } + } + } + + Reference < XEnumerationAccess > xEA( rTextContent, UNO_QUERY ); + Reference < XEnumeration > xTextEnum; + xTextEnum = xEA->createEnumeration(); + const bool bHasPortions = xTextEnum.is(); + + Reference < XEnumeration> xContentEnum; + Reference < XContentEnumerationAccess > xCEA( rTextContent, UNO_QUERY ); + if( xCEA.is() ) + xContentEnum.set(xCEA->createContentEnumeration( sTextContentService )); + const bool bHasContentEnum = xContentEnum.is() && + xContentEnum->hasMoreElements(); + + Reference < XTextSection > xSection; + if( bHasContentEnum ) + { + // For the auto styles, the multi property set helper is only used + // if hard attributes are existing. Therefore, it seems to be a better + // strategy to have the TextSection property separate, because otherwise + // we always retrieve the style names even if they are not required. + if( bAutoStyles ) + { + if( xPropSet->getPropertySetInfo()->hasPropertyByName( sTextSection ) ) + { + xSection.set(xPropSet->getPropertyValue( sTextSection ), uno::UNO_QUERY); + } + } + else + { + if( rPropSetHelper.hasProperty( TEXT_SECTION ) ) + { + xSection.set(rPropSetHelper.getValue( TEXT_SECTION ), uno::UNO_QUERY); + } + } + } + + if( bAutoStyles ) + { + if( bHasContentEnum ) + exportTextContentEnumeration( + xContentEnum, bAutoStyles, xSection, + bIsProgress ); + if ( bHasPortions ) + exportTextRangeEnumeration( xTextEnum, bAutoStyles, bIsProgress ); + } + else + { + bool bPrevCharIsSpace = true; + enum XMLTokenEnum eElem = + 0 < nOutlineLevel ? XML_H : XML_P; + SvXMLElementExport aElem( GetExport(), eExtensionNS == TextPNS::EXTENSION ? XML_NAMESPACE_LO_EXT : XML_NAMESPACE_TEXT, eElem, + true, false ); + if( bHasContentEnum ) + bPrevCharIsSpace = !exportTextContentEnumeration( + xContentEnum, bAutoStyles, xSection, + bIsProgress ); + exportTextRangeEnumeration( xTextEnum, bAutoStyles, bIsProgress, + bPrevCharIsSpace ); + } +} + +void XMLTextParagraphExport::exportUndoTextRangeEnumeration( + const Reference < XEnumeration > & rTextEnum, + const sal_uInt32& rParaIdx, + bool bAutoStyles, bool bIsProgress, + bool bPrvChrIsSpc ) +{ + static const char sMeta[] = "InContentMetadata"; + static const char sFieldMarkName[] = "__FieldMark_"; + static const char sAnnotation[] = "Annotation"; + static const char sAnnotationEnd[] = "AnnotationEnd"; + + bool bPrevCharIsSpace = bPrvChrIsSpc; + + /* This is used for exporting to strict OpenDocument 1.2, in which case traditional + * bookmarks are used instead of fieldmarks. */ + FieldmarkType openFieldMark = NONE; + + while( rTextEnum->hasMoreElements() ) + { + Reference<XPropertySet> xPropSet(rTextEnum->nextElement(), UNO_QUERY); + Reference < XTextRange > xTxtRange(xPropSet, uno::UNO_QUERY); + Reference<XPropertySetInfo> xPropInfo(xPropSet->getPropertySetInfo()); + + if (xPropInfo->hasPropertyByName(sTextPortionType)) + { + OUString sType; + xPropSet->getPropertyValue(sTextPortionType) >>= sType; + + if (sType.equals(sRedline)) + { + if (nullptr != pRedlineExport) + pRedlineExport->ExportUndoChange(xPropSet, rParaIdx, bAutoStyles); + } + else { + OSL_FAIL("unknown text portion type"); + } + } + } + +// now that there are nested enumerations for meta(-field), this may be valid! +// DBG_ASSERT( !bOpenRuby, "Red Alert: Ruby still open!" ); +} + void XMLTextParagraphExport::exportTextRangeEnumeration( const Reference < XEnumeration > & rTextEnum, bool bAutoStyles, bool bIsProgress, _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits