diff options
author | László Németh <nemeth@numbertext.org> | 2021-05-26 16:31:15 +0200 |
---|---|---|
committer | László Németh <nemeth@numbertext.org> | 2021-05-27 15:25:06 +0200 |
commit | 48898a72066ff9982feafebb26708c4e779fd460 (patch) | |
tree | 638f750030a78be80f84f00c2772b861fd09808d | |
parent | f3e4c05ce6feaebebb269f1c984a92c1175061a4 (diff) |
tdf#60382 sw xmloff: import/export tracked table/row deletion
to OpenDocument format using
<style:table-row-properties loext:text-changes-only="false"/>
Rename also com::sun::star::text::TextTableRow::IsNotTracked
to com::sun::star::text::TextTableRow::HasTextChangesOnly.
Follow-up to commit 05366b8e6683363688de8708a3d88cf144c7a2bf
"tdf#60382 sw offapi: add change tracking of table/row deletion".
Change-Id: Iefb0d4095af0983fdd15697d5b80073d18d21bd7
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/116212
Tested-by: Jenkins
Reviewed-by: László Németh <nemeth@numbertext.org>
-rw-r--r-- | include/xmloff/xmltoken.hxx | 1 | ||||
-rw-r--r-- | offapi/com/sun/star/text/TextTableRow.idl | 2 | ||||
-rw-r--r-- | schema/libreoffice/OpenDocument-schema-v1.3+libreoffice.rng | 9 | ||||
-rw-r--r-- | sw/inc/unoprnms.hxx | 2 | ||||
-rw-r--r-- | sw/qa/extras/uiwriter/uiwriter2.cxx | 63 | ||||
-rw-r--r-- | sw/source/core/bastyp/init.cxx | 2 | ||||
-rw-r--r-- | sw/source/core/doc/DocumentRedlineManager.cxx | 6 | ||||
-rw-r--r-- | sw/source/core/unocore/unomap.cxx | 2 | ||||
-rw-r--r-- | sw/source/filter/xml/xmlexpit.cxx | 12 | ||||
-rw-r--r-- | sw/source/filter/xml/xmlimpit.cxx | 17 | ||||
-rw-r--r-- | sw/source/filter/xml/xmliteme.cxx | 29 | ||||
-rw-r--r-- | sw/source/filter/xml/xmlitemm.cxx | 3 | ||||
-rw-r--r-- | sw/source/filter/xml/xmltble.cxx | 25 | ||||
-rw-r--r-- | xmloff/source/core/xmltoken.cxx | 1 | ||||
-rw-r--r-- | xmloff/source/token/tokens.txt | 1 |
15 files changed, 163 insertions, 12 deletions
diff --git a/include/xmloff/xmltoken.hxx b/include/xmloff/xmltoken.hxx index b75907d8cba4..68efdb41ee02 100644 --- a/include/xmloff/xmltoken.hxx +++ b/include/xmloff/xmltoken.hxx @@ -1914,6 +1914,7 @@ namespace xmloff::token { XML_TEXT_BACKGROUND_COLOR, XML_TEXT_BLINKING, XML_TEXT_BOX, + XML_TEXT_CHANGES_ONLY, XML_TEXT_COLOR, XML_TEXT_COMBINE, XML_TEXT_COMBINE_END_CHAR, diff --git a/offapi/com/sun/star/text/TextTableRow.idl b/offapi/com/sun/star/text/TextTableRow.idl index e418fbbf9366..dcecda3f25c7 100644 --- a/offapi/com/sun/star/text/TextTableRow.idl +++ b/offapi/com/sun/star/text/TextTableRow.idl @@ -111,7 +111,7 @@ published service TextTableRow @since LibreOffice 7.2 */ - [optional, property] boolean IsNotTracked; + [optional, property] boolean HasTextChangesOnly; }; diff --git a/schema/libreoffice/OpenDocument-schema-v1.3+libreoffice.rng b/schema/libreoffice/OpenDocument-schema-v1.3+libreoffice.rng index a50316edd093..a4d359c5a3a9 100644 --- a/schema/libreoffice/OpenDocument-schema-v1.3+libreoffice.rng +++ b/schema/libreoffice/OpenDocument-schema-v1.3+libreoffice.rng @@ -2651,4 +2651,13 @@ xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1. </rng:optional> </rng:define> + <!-- TODO no proposal --> + <rng:define name="style-table-row-properties-attlist" combine="interleave"> + <rng:optional> + <rng:attribute name="loext:text-changes-only"> + <rng:ref name="boolean"/> + </rng:attribute> + </rng:optional> + </rng:define> + </rng:grammar> diff --git a/sw/inc/unoprnms.hxx b/sw/inc/unoprnms.hxx index 317ad79fa8ed..a6fe2dba18df 100644 --- a/sw/inc/unoprnms.hxx +++ b/sw/inc/unoprnms.hxx @@ -736,7 +736,7 @@ #define UNO_NAME_ITEMS "Items" #define UNO_NAME_SELITEM "SelectedItem" #define UNO_NAME_IS_SPLIT_ALLOWED "IsSplitAllowed" -#define UNO_NAME_IS_NOT_TRACKED "IsNotTracked" +#define UNO_NAME_HAS_TEXT_CHANGES_ONLY "HasTextChangesOnly" #define UNO_NAME_CHAR_HIDDEN "CharHidden" #define UNO_NAME_IS_FOLLOWING_TEXT_FLOW "IsFollowingTextFlow" #define UNO_NAME_WIDTH_TYPE "WidthType" diff --git a/sw/qa/extras/uiwriter/uiwriter2.cxx b/sw/qa/extras/uiwriter/uiwriter2.cxx index 3da57c948a43..2453f3afcb60 100644 --- a/sw/qa/extras/uiwriter/uiwriter2.cxx +++ b/sw/qa/extras/uiwriter/uiwriter2.cxx @@ -3690,7 +3690,7 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testRedlineTableRowDeletion) assertXPath(pXmlDoc, "//page[1]//body/tab"); // delete table row with enabled change tracking - // (IsNotTracked property of the row will be false) + // (HasTextChangesOnly property of the row will be false) dispatchCommand(mxComponent, ".uno:DeleteRows", {}); // This was deleted without change tracking @@ -3717,7 +3717,7 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testRedlineTableRowDeletion) assertXPath(pXmlDoc, "//page[1]//body/tab", 0); // Undo, and repeat the previous test, but only with deletion of the text content of the cells - // (IsNotTracked property will be removed by Undo) + // (HasTextChangesOnly property will be removed by Undo) dispatchCommand(mxComponent, ".uno:Undo", {}); dispatchCommand(mxComponent, ".uno:Undo", {}); @@ -3750,7 +3750,7 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testRedlineTableRowDeletion) pEditShell->AcceptRedline(0); // table row (and the 1-row table) still exists - // (IsNotTracked property wasn't set for table row deletion) + // (HasTextChangesOnly property wasn't set for table row deletion) discardDumpedLayout(); pXmlDoc = parseLayoutDump(); assertXPath(pXmlDoc, "//page[1]//body/tab"); @@ -3782,6 +3782,63 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testRedlineTableRowDeletion) assertXPath(pXmlDoc, "//page[1]//body/tab", 0); } +CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testRedlineTableRowDeletionWithExport) +{ + // load a 1-row table, and delete the row with enabled change tracking: + // now the row is not deleted silently, but keeps the deleted cell contents, + // and only accepting all of them will result the deletion of the table row. + SwDoc* pDoc = createDoc("tdf118311.fodt"); + + SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get()); + CPPUNIT_ASSERT(pTextDoc); + + // turn on red-lining and show changes + pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On | RedlineFlags::ShowDelete + | RedlineFlags::ShowInsert); + CPPUNIT_ASSERT_MESSAGE("redlining should be on", + pDoc->getIDocumentRedlineAccess().IsRedlineOn()); + CPPUNIT_ASSERT_MESSAGE( + "redlines should be visible", + IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags())); + + // check table + xmlDocUniquePtr pXmlDoc = parseLayoutDump(); + assertXPath(pXmlDoc, "//page[1]//body/tab"); + + // delete table row with enabled change tracking + // (HasTextChangesOnly property of the row will be false) + dispatchCommand(mxComponent, ".uno:DeleteRows", {}); + + // Deleted text content with change tracking, + // but not table deletion + discardDumpedLayout(); + pXmlDoc = parseLayoutDump(); + assertXPath(pXmlDoc, "//page[1]//body/tab"); + + // Save it and load it back. + reload("writer8", "tdf60382_tracked_table_deletion.odt"); + pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get()); + pDoc = pTextDoc->GetDocShell()->GetWrtShell()->GetDoc(); + + // accept the deletion of the content of the first cell + SwEditShell* const pEditShell(pDoc->GetEditShell()); + CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type>(2), pEditShell->GetRedlineCount()); + pEditShell->AcceptRedline(0); + + // table row was still not deleted + pXmlDoc = parseLayoutDump(); + assertXPath(pXmlDoc, "//page[1]//body/tab"); + + // accept last redline + pEditShell->AcceptRedline(0); + + // table row (and the 1-row table) was deleted finally + // (working export/import of HasTextChangesOnly) + discardDumpedLayout(); + pXmlDoc = parseLayoutDump(); + assertXPath(pXmlDoc, "//page[1]//body/tab", 0); +} + CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf128335) { // Load the bugdoc, which has 3 textboxes. diff --git a/sw/source/core/bastyp/init.cxx b/sw/source/core/bastyp/init.cxx index f1b86f8dfdc0..1acc4bfe4f59 100644 --- a/sw/source/core/bastyp/init.cxx +++ b/sw/source/core/bastyp/init.cxx @@ -206,7 +206,7 @@ sal_uInt16 const aTableSetRange[] = { sal_uInt16 const aTableLineSetRange[] = { RES_FILL_ORDER, RES_FRM_SIZE, - // IsNotTracked + // HasTextChangesOnly RES_PRINT, RES_PRINT, RES_LR_SPACE, RES_UL_SPACE, RES_BACKGROUND, RES_SHADOW, diff --git a/sw/source/core/doc/DocumentRedlineManager.cxx b/sw/source/core/doc/DocumentRedlineManager.cxx index 0e92f16034a5..6d2332418441 100644 --- a/sw/source/core/doc/DocumentRedlineManager.cxx +++ b/sw/source/core/doc/DocumentRedlineManager.cxx @@ -437,10 +437,10 @@ namespace if ( const SwTableBox* pBox = pPos->nNode.GetNode().GetTableBox() ) { const SwTableLine* pLine = pBox->GetUpper(); - const SvxPrintItem *pIsNoTrackedProp = + const SvxPrintItem *pHasTextChangesOnlyProp = pLine->GetFrameFormat()->GetAttrSet().GetItem<SvxPrintItem>(RES_PRINT); - // table row property "IsNotTracked" is set and its value is false - if ( pIsNoTrackedProp && !pIsNoTrackedProp->GetValue() ) + // table row property "HasTextChangesOnly" is set and its value is false + if ( pHasTextChangesOnlyProp && !pHasTextChangesOnlyProp->GetValue() ) { bool bEmptyLine = true; const SwTableBoxes & rBoxes = pLine->GetTabBoxes(); diff --git a/sw/source/core/unocore/unomap.cxx b/sw/source/core/unocore/unomap.cxx index 55b948a1eafe..0cb439336ae8 100644 --- a/sw/source/core/unocore/unomap.cxx +++ b/sw/source/core/unocore/unomap.cxx @@ -542,7 +542,7 @@ const SfxItemPropertyMapEntry* SwUnoPropertyMapProvider::GetPropertyMapEntries(s { u"" UNO_NAME_SIZE_TYPE, RES_FRM_SIZE, cppu::UnoType<sal_Int16>::get() , PROPERTY_NONE, MID_FRMSIZE_SIZE_TYPE }, { u"" UNO_NAME_WIDTH_TYPE, RES_FRM_SIZE, cppu::UnoType<sal_Int16>::get() , PROPERTY_NONE, MID_FRMSIZE_WIDTH_TYPE }, { u"" UNO_NAME_IS_SPLIT_ALLOWED, RES_ROW_SPLIT, cppu::UnoType<bool>::get() , PropertyAttribute::MAYBEVOID, 0}, - { u"" UNO_NAME_IS_NOT_TRACKED, RES_PRINT, cppu::UnoType<bool>::get() , PropertyAttribute::MAYBEVOID, 0}, + { u"" UNO_NAME_HAS_TEXT_CHANGES_ONLY, RES_PRINT, cppu::UnoType<bool>::get() , PropertyAttribute::MAYBEVOID, 0}, { u"" UNO_NAME_ROW_INTEROP_GRAB_BAG, RES_FRMATR_GRABBAG, cppu::UnoType< cppu::UnoSequenceType<css::beans::PropertyValue> >::get(), PROPERTY_NONE, 0 }, { u"", 0, css::uno::Type(), 0, 0 } }; diff --git a/sw/source/filter/xml/xmlexpit.cxx b/sw/source/filter/xml/xmlexpit.cxx index 4ab794cc8a9c..b0fdfe589635 100644 --- a/sw/source/filter/xml/xmlexpit.cxx +++ b/sw/source/filter/xml/xmlexpit.cxx @@ -46,6 +46,7 @@ #include <editeng/keepitem.hxx> #include <editeng/brushitem.hxx> #include <editeng/frmdiritem.hxx> +#include <editeng/prntitem.hxx> #include <fmtpdsc.hxx> #include <fmtornt.hxx> #include <fmtfsize.hxx> @@ -871,6 +872,17 @@ bool SvXMLExportItemMapper::QueryXMLValue( } break; + case RES_PRINT: + { + const SvxPrintItem* pHasTextChangesOnly = dynamic_cast<const SvxPrintItem*>( &rItem ); + if (pHasTextChangesOnly && !pHasTextChangesOnly->GetValue()) + { + aOut.append( "false" ); + bOk = true; + } + } + break; + case RES_BACKGROUND: { const SvxBrushItem& rBrush = dynamic_cast<const SvxBrushItem&>(rItem); diff --git a/sw/source/filter/xml/xmlimpit.cxx b/sw/source/filter/xml/xmlimpit.cxx index 4d849810afb1..d09221ba2eb6 100644 --- a/sw/source/filter/xml/xmlimpit.cxx +++ b/sw/source/filter/xml/xmlimpit.cxx @@ -856,6 +856,23 @@ bool SvXMLImportItemMapper::PutXMLValue( } break; + case RES_PRINT: + { + SfxBoolItem& rHasTextChangesOnly = dynamic_cast<SfxBoolItem&>(rItem); + + if( IsXMLToken( rValue, XML_TRUE ) ) + { + rHasTextChangesOnly.SetValue( true ); + bOk = true; + } + else if( IsXMLToken( rValue, XML_FALSE ) ) + { + rHasTextChangesOnly.SetValue( false ); + bOk = true; + } + } + break; + case RES_HORI_ORIENT: { SwFormatHoriOrient& rHoriOrient = dynamic_cast<SwFormatHoriOrient&>(rItem); diff --git a/sw/source/filter/xml/xmliteme.cxx b/sw/source/filter/xml/xmliteme.cxx index 8594c75bf4df..61a8205064ff 100644 --- a/sw/source/filter/xml/xmliteme.cxx +++ b/sw/source/filter/xml/xmliteme.cxx @@ -33,6 +33,8 @@ #include <frmfmt.hxx> #include "xmlexp.hxx" #include <editeng/memberids.h> +#include <editeng/prntitem.hxx> +#include <xmloff/xmlnamespace.hxx> using namespace ::com::sun::star; using namespace ::com::sun::star::uno; @@ -105,6 +107,33 @@ void SwXMLTableItemMapper_Impl::handleSpecialItem( { switch( rEntry.nWhichId ) { + + case RES_PRINT: + { + const SfxPoolItem *pItem; + if( pSet && + SfxItemState::SET == pSet->GetItemState( RES_PRINT, true, + &pItem ) ) + { + bool bHasTextChangesOnly = + static_cast<const SvxPrintItem *>(pItem)->GetValue(); + if ( !bHasTextChangesOnly ) + { + OUString sValue; + sal_uInt16 nMemberId = + static_cast<sal_uInt16>( rEntry.nMemberId & MID_SW_FLAG_MASK ); + + if( SvXMLExportItemMapper::QueryXMLValue( + rItem, sValue, nMemberId, rUnitConverter ) ) + { + AddAttribute( rEntry.nNameSpace, rEntry.eLocalName, + sValue, rNamespaceMap, rAttrList ); + } + } + } + } + break; + case RES_LR_SPACE: { const SfxPoolItem *pItem; diff --git a/sw/source/filter/xml/xmlitemm.cxx b/sw/source/filter/xml/xmlitemm.cxx index 66001b1de5fb..6464149d766e 100644 --- a/sw/source/filter/xml/xmlitemm.cxx +++ b/sw/source/filter/xml/xmlitemm.cxx @@ -151,7 +151,8 @@ SvXMLItemMapEntry const aXMLTableRowItemMap[] = // RES_FOOTER // not required // RES_PRINT - // not required + // M_E_SE( STYLE, TEXT_CHANGES_ONLY, RES_PRINT, 0 ), + M_E_SE( LO_EXT, TEXT_CHANGES_ONLY, RES_PRINT, 0 ), // RES_OPAQUE // not required // RES_PROTECT diff --git a/sw/source/filter/xml/xmltble.cxx b/sw/source/filter/xml/xmltble.cxx index b4ba4c9a8c85..492eb5f7520a 100644 --- a/sw/source/filter/xml/xmltble.cxx +++ b/sw/source/filter/xml/xmltble.cxx @@ -32,6 +32,7 @@ #include <xmloff/numehelp.hxx> #include <editeng/brushitem.hxx> #include <editeng/boxitem.hxx> +#include <editeng/prntitem.hxx> #include <editeng/xmlcnitm.hxx> #include <fmtrowsplt.hxx> #include <editeng/frmdiritem.hxx> @@ -197,6 +198,7 @@ bool SwXMLTableFrameFormatsSort_Impl::AddRow( SwFrameFormat& rFrameFormat, const SwFormatFrameSize *pFrameSize = nullptr; const SwFormatRowSplit* pRowSplit = nullptr; const SvxBrushItem *pBrush = nullptr; + const SvxPrintItem *pHasTextChangesOnly = nullptr; const SfxItemSet& rItemSet = rFrameFormat.GetAttrSet(); const SfxPoolItem *pItem; @@ -209,8 +211,11 @@ bool SwXMLTableFrameFormatsSort_Impl::AddRow( SwFrameFormat& rFrameFormat, if( SfxItemState::SET == rItemSet.GetItemState( RES_BACKGROUND, false, &pItem ) ) pBrush = static_cast<const SvxBrushItem *>(pItem); + if( SfxItemState::SET == rItemSet.GetItemState( RES_PRINT, false, &pItem ) ) + pHasTextChangesOnly = static_cast<const SvxPrintItem *>(pItem); + // empty styles have not to be exported - if( !pFrameSize && !pBrush && !pRowSplit ) + if( !pFrameSize && !pBrush && !pRowSplit && !pHasTextChangesOnly ) return false; // order is: -/brush, size/-, size/brush @@ -221,6 +226,7 @@ bool SwXMLTableFrameFormatsSort_Impl::AddRow( SwFrameFormat& rFrameFormat, const SwFormatFrameSize *pTestFrameSize = nullptr; const SwFormatRowSplit* pTestRowSplit = nullptr; const SvxBrushItem *pTestBrush = nullptr; + const SvxPrintItem *pTestHasTextChangesOnly = nullptr; const SwFrameFormat *pTestFormat = *i; const SfxItemSet& rTestSet = pTestFormat->GetAttrSet(); if( SfxItemState::SET == rTestSet.GetItemState( RES_FRM_SIZE, false, @@ -265,6 +271,20 @@ bool SwXMLTableFrameFormatsSort_Impl::AddRow( SwFrameFormat& rFrameFormat, continue; } + if( SfxItemState::SET == rTestSet.GetItemState( RES_PRINT, false, + &pItem ) ) + { + if( !pHasTextChangesOnly ) + break; + + pTestHasTextChangesOnly = static_cast<const SvxPrintItem *>(pItem); + } + else + { + if( pHasTextChangesOnly ) + continue; + } + if( pFrameSize && ( pFrameSize->GetHeightSizeType() != pTestFrameSize->GetHeightSizeType() || pFrameSize->GetHeight() != pTestFrameSize->GetHeight() ) ) @@ -276,6 +296,9 @@ bool SwXMLTableFrameFormatsSort_Impl::AddRow( SwFrameFormat& rFrameFormat, if( pRowSplit && (!pRowSplit->GetValue() != !pTestRowSplit->GetValue()) ) continue; + if( pHasTextChangesOnly && (!pHasTextChangesOnly->GetValue() != !pTestHasTextChangesOnly->GetValue()) ) + continue; + // found! rFrameFormat.SetName( pTestFormat->GetName() ); bInsert = false; diff --git a/xmloff/source/core/xmltoken.cxx b/xmloff/source/core/xmltoken.cxx index f557d0e8102b..4334f52a74ac 100644 --- a/xmloff/source/core/xmltoken.cxx +++ b/xmloff/source/core/xmltoken.cxx @@ -1920,6 +1920,7 @@ namespace xmloff::token { TOKEN( "text-background-color", XML_TEXT_BACKGROUND_COLOR ), TOKEN( "text-blinking", XML_TEXT_BLINKING ), TOKEN( "text-box", XML_TEXT_BOX ), + TOKEN( "text-changes-only", XML_TEXT_CHANGES_ONLY ), TOKEN( "text-color", XML_TEXT_COLOR ), TOKEN( "text-combine", XML_TEXT_COMBINE ), TOKEN( "text-combine-end-char", XML_TEXT_COMBINE_END_CHAR ), diff --git a/xmloff/source/token/tokens.txt b/xmloff/source/token/tokens.txt index 53b2f76cbde8..de859d508fb8 100644 --- a/xmloff/source/token/tokens.txt +++ b/xmloff/source/token/tokens.txt @@ -1827,6 +1827,7 @@ text-autospace text-background-color text-blinking text-box +text-changes-only text-color text-combine text-combine-end-char |