From efedfae6a340bac4ad49843c178ae1b45a92352c Mon Sep 17 00:00:00 2001 From: Thorsten Behrens Date: Thu, 20 Jun 2024 23:38:43 +0200 Subject: Revert attempted clipboard fixes on branch This is a squashed revert, consisting of: * Revert "tdf#161054: drop support of last empty span as paragraph mark format" * Revert "tdf#161023: Empty spans may only define paragraph marks in text documents" * Revert "This block seems obsolete now, try to drop it" * Revert "Make sure to export autostyles from inside frames anchored to page" * Revert "tdf#160253: fix list identifier export decision code" --- xmloff/source/text/txtparae.cxx | 208 ++++++++++++++++++++++++++++++---------- 1 file changed, 160 insertions(+), 48 deletions(-) (limited to 'xmloff/source/text/txtparae.cxx') diff --git a/xmloff/source/text/txtparae.cxx b/xmloff/source/text/txtparae.cxx index b7101765368d..f55ee1055825 100644 --- a/xmloff/source/text/txtparae.cxx +++ b/xmloff/source/text/txtparae.cxx @@ -39,7 +39,6 @@ #include #include #include -#include #include #include #include @@ -1335,14 +1334,12 @@ struct XMLTextParagraphExport::DocumentListNodes { struct NodeData { - std::ptrdiff_t order; sal_Int32 index; // see SwNode::GetIndex and SwNodeOffset sal_uInt64 style_id; // actually a pointer to NumRule OUString list_id; }; std::vector docListNodes; - DocumentListNodes(const css::uno::Reference& xModel, - const std::vector& aDocumentNodeOrder) + DocumentListNodes(const css::uno::Reference& xModel) { // Sequence of nodes, each of them represented by three-element sequence, // corresponding to NodeData members @@ -1364,18 +1361,12 @@ struct XMLTextParagraphExport::DocumentListNodes for (const auto& node : nodes) { assert(node.getLength() == 3); - sal_Int32 nodeIndex = node[0].get(); - auto nodeOrder = std::distance( - aDocumentNodeOrder.begin(), - std::find(aDocumentNodeOrder.begin(), aDocumentNodeOrder.end(), nodeIndex)); - docListNodes.push_back({ .order = nodeOrder, - .index = nodeIndex, - .style_id = node[1].get(), - .list_id = node[2].get() }); + docListNodes.push_back({ node[0].get(), node[1].get(), + node[2].get() }); } std::sort(docListNodes.begin(), docListNodes.end(), - [](const NodeData& lhs, const NodeData& rhs) { return lhs.order < rhs.order; }); + [](const NodeData& lhs, const NodeData& rhs) { return lhs.index < rhs.index; }); } bool ShouldSkipListId(const Reference& xTextContent) const { @@ -1396,9 +1387,10 @@ struct XMLTextParagraphExport::DocumentListNodes return false; } - auto it = std::find_if(docListNodes.begin(), docListNodes.end(), - [index](const NodeData& el) { return el.index == index; }); - if (it == docListNodes.end()) + auto it = std::lower_bound(docListNodes.begin(), docListNodes.end(), index, + [](const NodeData& lhs, sal_Int32 rhs) + { return lhs.index < rhs; }); + if (it == docListNodes.end() || it->index != index) return false; // We need to write the id, when there will be continuation of the list either with @@ -1626,7 +1618,9 @@ const enum XMLTokenEnum lcl_XmlReferenceElements[] = { const enum XMLTokenEnum lcl_XmlBookmarkElements[] = { XML_BOOKMARK, XML_BOOKMARK_START, XML_BOOKMARK_END }; -void XMLTextParagraphExport::collectTextAutoStylesAndNodeExportOrder(bool bIsProgress) +// This function replaces the text portion iteration during auto style +// collection. +void XMLTextParagraphExport::collectTextAutoStylesOptimized( bool bIsProgress ) { GetExport().GetShapeExport(); // make sure the graphics styles family is added @@ -1634,13 +1628,62 @@ void XMLTextParagraphExport::collectTextAutoStylesAndNodeExportOrder(bool bIsPro return; const bool bAutoStyles = true; - const bool bExportContent = true; + const bool bExportContent = false; + + // Export AutoStyles: + Reference< XAutoStylesSupplier > xAutoStylesSupp( GetExport().GetModel(), UNO_QUERY ); + if ( xAutoStylesSupp.is() ) + { + Reference< XAutoStyles > xAutoStyleFamilies = xAutoStylesSupp->getAutoStyles(); + const auto collectFamily = [this, &xAutoStyleFamilies](const OUString& sName, + XmlStyleFamily nFamily) { + Any aAny = xAutoStyleFamilies->getByName( sName ); + Reference< XAutoStyleFamily > xAutoStyles = *o3tl::doAccess>(aAny); + Reference < XEnumeration > xAutoStylesEnum( xAutoStyles->createEnumeration() ); + + while ( xAutoStylesEnum->hasMoreElements() ) + { + aAny = xAutoStylesEnum->nextElement(); + Reference< XAutoStyle > xAutoStyle = *o3tl::doAccess>(aAny); + Reference < XPropertySet > xPSet( xAutoStyle, uno::UNO_QUERY ); + Add( nFamily, xPSet, {}, true ); + } + }; + collectFamily("CharacterStyles", XmlStyleFamily::TEXT_TEXT); + collectFamily("RubyStyles", XmlStyleFamily::TEXT_RUBY); + collectFamily("ParagraphStyles", XmlStyleFamily::TEXT_PARAGRAPH); + } - if (auto xTextDocument = GetExport().GetModel().query()) + // Export Field AutoStyles: + Reference< XTextFieldsSupplier > xTextFieldsSupp( GetExport().GetModel(), UNO_QUERY ); + if ( xTextFieldsSupp.is() ) { - bInDocumentNodeOrderCollection = true; - collectTextAutoStyles(xTextDocument->getText(), bIsProgress); - bInDocumentNodeOrderCollection = false; + Reference< XEnumerationAccess > xTextFields = xTextFieldsSupp->getTextFields(); + Reference < XEnumeration > xTextFieldsEnum( xTextFields->createEnumeration() ); + + while ( xTextFieldsEnum->hasMoreElements() ) + { + Any aAny = xTextFieldsEnum->nextElement(); + Reference< XTextField > xTextField = *o3tl::doAccess>(aAny); + exportTextField( xTextField, bAutoStyles, bIsProgress, + !xAutoStylesSupp.is(), nullptr ); + try + { + Reference < XPropertySet > xSet( xTextField, UNO_QUERY ); + Reference < XText > xText; + Any a = xSet->getPropertyValue("TextRange"); + a >>= xText; + if ( xText.is() ) + { + exportText( xText, true, bIsProgress, bExportContent ); + GetExport().GetTextParagraphExport() + ->collectTextAutoStyles( xText ); + } + } + catch (Exception&) + { + } + } } // Export text frames: @@ -1687,6 +1730,85 @@ void XMLTextParagraphExport::collectTextAutoStylesAndNodeExportOrder(bool bIsPro } } + sal_Int32 nCount; + // AutoStyles for sections + Reference< XTextSectionsSupplier > xSectionsSupp( GetExport().GetModel(), UNO_QUERY ); + if ( xSectionsSupp.is() ) + { + Reference< XIndexAccess > xSections( xSectionsSupp->getTextSections(), UNO_QUERY ); + if ( xSections.is() ) + { + nCount = xSections->getCount(); + for( sal_Int32 i = 0; i < nCount; ++i ) + { + Any aAny = xSections->getByIndex( i ); + Reference< XTextSection > xSection = *o3tl::doAccess>(aAny); + Reference < XPropertySet > xPSet( xSection, uno::UNO_QUERY ); + Add( XmlStyleFamily::TEXT_SECTION, xPSet ); + } + } + } + + // AutoStyles for tables (Note: suppress autostyle collection for paragraphs in exportTable) + Reference< XTextTablesSupplier > xTablesSupp( GetExport().GetModel(), UNO_QUERY ); + if ( xTablesSupp.is() ) + { + Reference< XIndexAccess > xTables( xTablesSupp->getTextTables(), UNO_QUERY ); + if ( xTables.is() ) + { + nCount = xTables->getCount(); + for( sal_Int32 i = 0; i < nCount; ++i ) + { + Any aAny = xTables->getByIndex( i ); + Reference< XTextTable > xTable = *o3tl::doAccess>(aAny); + exportTable( xTable, true, true ); + } + } + } + + Reference< XNumberingRulesSupplier > xNumberingRulesSupp( GetExport().GetModel(), UNO_QUERY ); + if ( xNumberingRulesSupp.is() ) + { + Reference< XIndexAccess > xNumberingRules = xNumberingRulesSupp->getNumberingRules(); + nCount = xNumberingRules->getCount(); + // Custom outline assignment lost after re-importing sxw (#i73361#) + for( sal_Int32 i = 0; i < nCount; ++i ) + { + Reference< XIndexReplace > xNumRule( xNumberingRules->getByIndex( i ), UNO_QUERY ); + if( xNumRule.is() && xNumRule->getCount() ) + { + Reference < XNamed > xNamed( xNumRule, UNO_QUERY ); + OUString sName; + if( xNamed.is() ) + sName = xNamed->getName(); + bool bAdd = sName.isEmpty(); + if( !bAdd ) + { + Reference < XPropertySet > xNumPropSet( xNumRule, + UNO_QUERY ); + if( xNumPropSet.is() && + xNumPropSet->getPropertySetInfo() + ->hasPropertyByName( "IsAutomatic" ) ) + { + bAdd = *o3tl::doAccess(xNumPropSet->getPropertyValue( "IsAutomatic" )); + // Check on outline style (#i73361#) + if ( bAdd && + xNumPropSet->getPropertySetInfo() + ->hasPropertyByName( "NumberingIsOutline" ) ) + { + bAdd = !(*o3tl::doAccess(xNumPropSet->getPropertyValue( "NumberingIsOutline" ))); + } + } + else + { + bAdd = true; + } + } + if( bAdd ) + maListAutoPool.Add( xNumRule ); + } + } + } mbCollected = true; } @@ -1774,36 +1896,14 @@ bool XMLTextParagraphExport::ExportListId() const && GetExport().getSaneDefaultVersion() >= SvtSaveOptions::ODFSVER_012; } -void XMLTextParagraphExport::RecordNodeIndex(const css::uno::Reference& xTextContent) -{ - if (!bInDocumentNodeOrderCollection) - return; - if (auto xPropSet = xTextContent.query()) - { - try - { - sal_Int32 index = 0; - // See SwXParagraph::Impl::GetPropertyValues_Impl - xPropSet->getPropertyValue("ODFExport_NodeIndex") >>= index; - assert(std::find(maDocumentNodeOrder.begin(), maDocumentNodeOrder.end(), index) - == maDocumentNodeOrder.end()); - maDocumentNodeOrder.push_back(index); - } - catch (css::beans::UnknownPropertyException&) - { - // That's absolutely fine! - } - } -} - bool XMLTextParagraphExport::ShouldSkipListId(const Reference& xTextContent) { if (!mpDocumentListNodes) { if (ExportListId()) - mpDocumentListNodes.reset(new DocumentListNodes(GetExport().GetModel(), maDocumentNodeOrder)); + mpDocumentListNodes.reset(new DocumentListNodes(GetExport().GetModel())); else - mpDocumentListNodes.reset(new DocumentListNodes({}, {})); + mpDocumentListNodes.reset(new DocumentListNodes({})); } return mpDocumentListNodes->ShouldSkipListId(xTextContent); @@ -1854,7 +1954,6 @@ void XMLTextParagraphExport::exportTextContentEnumeration( { if( bAutoStyles ) { - RecordNodeIndex(xTxtCntnt); exportListAndSectionChange( xCurrentTextSection, xTxtCntnt, aPrevNumInfo, aNextNumInfo, bAutoStyles ); @@ -2226,6 +2325,7 @@ void XMLTextParagraphExport::exportParagraph( Reference < XEnumerationAccess > xEA( rTextContent, UNO_QUERY ); Reference < XEnumeration > xTextEnum = xEA->createEnumeration(); + const bool bHasPortions = xTextEnum.is(); Reference < XEnumeration> xContentEnum; Reference < XContentEnumerationAccess > xCEA( rTextContent, UNO_QUERY ); @@ -2259,10 +2359,22 @@ void XMLTextParagraphExport::exportParagraph( bool bPrevCharIsSpace(true); // true because whitespace at start is ignored + if( bAutoStyles ) + { + if( bHasContentEnum ) + exportTextContentEnumeration( + xContentEnum, bAutoStyles, xSection, + bIsProgress ); + if ( bHasPortions ) + { + exportTextRangeEnumeration(xTextEnum, bAutoStyles, bIsProgress, bPrevCharIsSpace); + } + } + else { enum XMLTokenEnum eElem = 0 < nOutlineLevel ? XML_H : XML_P; - SvXMLElementExport aElem( GetExport(), !bAutoStyles, eExtensionNS == TextPNS::EXTENSION ? XML_NAMESPACE_LO_EXT : XML_NAMESPACE_TEXT, eElem, + SvXMLElementExport aElem( GetExport(), eExtensionNS == TextPNS::EXTENSION ? XML_NAMESPACE_LO_EXT : XML_NAMESPACE_TEXT, eElem, true, false ); if( bHasContentEnum ) { -- cgit