summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--offapi/com/sun/star/text/CellProperties.idl6
-rw-r--r--sw/qa/extras/uiwriter/uiwriter5.cxx103
-rw-r--r--sw/source/core/bastyp/init.cxx4
-rw-r--r--sw/source/core/doc/DocumentRedlineManager.cxx28
-rw-r--r--sw/source/core/frmedt/fetab.cxx49
-rw-r--r--sw/source/core/unocore/unomap.cxx1
6 files changed, 185 insertions, 6 deletions
diff --git a/offapi/com/sun/star/text/CellProperties.idl b/offapi/com/sun/star/text/CellProperties.idl
index 2448c25c8439..58c9718c0dc2 100644
--- a/offapi/com/sun/star/text/CellProperties.idl
+++ b/offapi/com/sun/star/text/CellProperties.idl
@@ -130,6 +130,12 @@ published service CellProperties
@since LibreOffice 6.3
*/
[optional, readonly, property] com::sun::star::text::XText ParentText;
+
+ /** If TRUE, the table cell wasn't deleted or inserted with its tracked cell content
+
+ @since LibreOffice 7.6
+ */
+ [optional, property, maybevoid] boolean HasTextChangesOnly;
};
diff --git a/sw/qa/extras/uiwriter/uiwriter5.cxx b/sw/qa/extras/uiwriter/uiwriter5.cxx
index ee7c041b78c5..38fe2143a992 100644
--- a/sw/qa/extras/uiwriter/uiwriter5.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter5.cxx
@@ -2453,6 +2453,109 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest5, testTdf147180_empty_rows)
CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xTables->getCount());
}
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest5, testRedlineTableColumnDeletion)
+{
+ // load a table, and delete the first column with enabled change tracking:
+ // now the column is not deleted silently, but keeps the deleted cell content,
+ // and only accepting it will result the deletion of the table column.
+ createSwDoc("tdf118311.fodt");
+ SwDoc* pDoc = getSwDoc();
+
+ // 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");
+ assertXPath(pXmlDoc, "//page[1]//body/tab/row/cell", 2);
+
+ // delete table column with enabled change tracking
+ // (HasTextChangesOnly property of the cell will be false)
+ dispatchCommand(mxComponent, ".uno:DeleteColumns", {});
+
+ discardDumpedLayout();
+ pXmlDoc = parseLayoutDump();
+ assertXPath(pXmlDoc, "//page[1]//body/tab");
+ // This was 1 (deleted cell without change tracking)
+ assertXPath(pXmlDoc, "//page[1]//body/tab/row/cell", 2);
+
+ // accept the deletion
+ SwEditShell* const pEditShell(pDoc->GetEditShell());
+ CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type>(1), pEditShell->GetRedlineCount());
+ pEditShell->AcceptRedline(0);
+
+ discardDumpedLayout();
+ pXmlDoc = parseLayoutDump();
+ assertXPath(pXmlDoc, "//page[1]//body/tab");
+ // deleted column
+ assertXPath(pXmlDoc, "//page[1]//body/tab/row/cell", 1);
+
+ // Undo, and repeat the previous test, but only with deletion of the text content of the cells
+ // (HasTextChangesOnly property will be removed by Undo)
+
+ dispatchCommand(mxComponent, ".uno:Undo", {});
+ dispatchCommand(mxComponent, ".uno:Undo", {});
+
+ // first column exists again
+ discardDumpedLayout();
+ pXmlDoc = parseLayoutDump();
+ assertXPath(pXmlDoc, "//page[1]//body/tab");
+ assertXPath(pXmlDoc, "//page[1]//body/tab/row/cell", 2);
+
+ // delete table column with enabled change tracking
+ dispatchCommand(mxComponent, ".uno:SelectColumn", {});
+ dispatchCommand(mxComponent, ".uno:Delete", {});
+
+ // Table column still exists
+ discardDumpedLayout();
+ pXmlDoc = parseLayoutDump();
+ assertXPath(pXmlDoc, "//page[1]//body/tab");
+ assertXPath(pXmlDoc, "//page[1]//body/tab/row/cell", 2);
+
+ // accept the deletion of the content of the first cell
+ CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type>(1), pEditShell->GetRedlineCount());
+ pEditShell->AcceptRedline(0);
+
+ // table column was still not deleted
+ discardDumpedLayout();
+ pXmlDoc = parseLayoutDump();
+ assertXPath(pXmlDoc, "//page[1]//body/tab");
+ assertXPath(pXmlDoc, "//page[1]//body/tab/row/cell", 2);
+
+ // Undo, and delete the column without change tracking
+
+ dispatchCommand(mxComponent, ".uno:Undo", {});
+ dispatchCommand(mxComponent, ".uno:Undo", {});
+
+ // table exists again
+ discardDumpedLayout();
+ pXmlDoc = parseLayoutDump();
+ assertXPath(pXmlDoc, "//page[1]//body/tab");
+ assertXPath(pXmlDoc, "//page[1]//body/tab/row/cell", 2);
+
+ // disable change tracking
+ pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::ShowDelete
+ | RedlineFlags::ShowInsert);
+
+ CPPUNIT_ASSERT_MESSAGE("redlining should be off",
+ !pDoc->getIDocumentRedlineAccess().IsRedlineOn());
+
+ // delete table column without change tracking
+ dispatchCommand(mxComponent, ".uno:DeleteColumns", {});
+
+ // the table column was deleted
+ discardDumpedLayout();
+ pXmlDoc = parseLayoutDump();
+ assertXPath(pXmlDoc, "//page[1]//body/tab");
+ assertXPath(pXmlDoc, "//page[1]//body/tab/row/cell", 1);
+}
+
CPPUNIT_TEST_FIXTURE(SwUiWriterTest5, 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 a5bcd736966e..f2a4d974cfa1 100644
--- a/sw/source/core/bastyp/init.cxx
+++ b/sw/source/core/bastyp/init.cxx
@@ -204,8 +204,8 @@ WhichRangesContainer const aTableSetRange(svl::Items<
WhichRangesContainer const aTableLineSetRange(svl::Items<
RES_FILL_ORDER, RES_FRM_SIZE,
- // HasTextChangesOnly
RES_LR_SPACE, RES_UL_SPACE,
+ // HasTextChangesOnly
RES_PRINT, RES_PRINT,
RES_PROTECT, RES_PROTECT,
RES_VERT_ORIENT, RES_VERT_ORIENT,
@@ -218,6 +218,8 @@ WhichRangesContainer const aTableLineSetRange(svl::Items<
WhichRangesContainer const aTableBoxSetRange(svl::Items<
RES_FILL_ORDER, RES_FRM_SIZE,
RES_LR_SPACE, RES_UL_SPACE,
+ // HasTextChangesOnly
+ RES_PRINT, RES_PRINT,
RES_PROTECT, RES_PROTECT,
RES_VERT_ORIENT, RES_VERT_ORIENT,
RES_BACKGROUND, RES_SHADOW,
diff --git a/sw/source/core/doc/DocumentRedlineManager.cxx b/sw/source/core/doc/DocumentRedlineManager.cxx
index 4e9176cc340a..8ce8a4873aab 100644
--- a/sw/source/core/doc/DocumentRedlineManager.cxx
+++ b/sw/source/core/doc/DocumentRedlineManager.cxx
@@ -457,6 +457,30 @@ namespace
if ( !pBox )
return;
+ // tracked column deletion
+
+ const SvxPrintItem *pHasBoxTextChangesOnlyProp =
+ pBox->GetFrameFormat()->GetAttrSet().GetItem<SvxPrintItem>(RES_PRINT);
+ // empty table cell with property "HasTextChangesOnly" = false
+ if ( pHasBoxTextChangesOnlyProp && !pHasBoxTextChangesOnlyProp->GetValue() )
+ {
+ SwCursor aCursor( *pPos, nullptr );
+ if ( pBox->IsEmpty() )
+ {
+ // TODO check the other cells of the column
+ // before removing the column
+ pPos->GetDoc().DeleteCol( aCursor );
+ return;
+ }
+ else
+ {
+ SvxPrintItem aHasTextChangesOnly(RES_PRINT, false);
+ pPos->GetDoc().SetBoxAttr( aCursor, aHasTextChangesOnly );
+ }
+ }
+
+ // tracked row deletion
+
const SwTableLine* pLine = pBox->GetUpper();
const SvxPrintItem *pHasTextChangesOnlyProp =
pLine->GetFrameFormat()->GetAttrSet().GetItem<SvxPrintItem>(RES_PRINT);
@@ -2330,9 +2354,9 @@ DocumentRedlineManager::AppendRedline(SwRangeRedline* pNewRedl, bool const bCall
{
if ( aSttIdx.GetNode().IsTableNode() )
{
- SvxPrintItem aNotTracked(RES_PRINT, false);
+ SvxPrintItem aHasTextChangesOnly(RES_PRINT, false);
SwCursor aCursor( SwPosition(aSttIdx), nullptr );
- m_rDoc.SetRowNotTracked( aCursor, aNotTracked, /*bAll=*/true );
+ m_rDoc.SetRowNotTracked( aCursor, aHasTextChangesOnly, /*bAll=*/true );
}
++aSttIdx;
}
diff --git a/sw/source/core/frmedt/fetab.cxx b/sw/source/core/frmedt/fetab.cxx
index c51413e3ba9b..daca7b86bc9c 100644
--- a/sw/source/core/frmedt/fetab.cxx
+++ b/sw/source/core/frmedt/fetab.cxx
@@ -276,6 +276,49 @@ bool SwFEShell::DeleteCol()
}
CurrShell aCurr( this );
+
+ // tracked deletion: remove only textbox content,
+ // and set IsNoTracked table box property to false
+ if ( GetDoc()->GetDocShell()->IsChangeRecording() )
+ {
+ StartUndo(SwUndoId::COL_DELETE);
+ StartAllAction();
+
+ if ( SwWrtShell* pWrtShell = dynamic_cast<SwWrtShell*>(this) )
+ pWrtShell->SelectTableCol();
+
+ // search boxes via the layout
+ SwSelBoxes aBoxes;
+ GetTableSel( *this, aBoxes, SwTableSearchType::Col );
+
+ TableWait aWait( 20, pFrame, *GetDoc()->GetDocShell(), aBoxes.size() );
+
+ for (size_t i = 0; i < aBoxes.size(); ++i)
+ {
+ SwTableBox *pBox = aBoxes[i];
+ if ( pBox->GetSttNd() )
+ {
+ SwNodeIndex aIdx( *pBox->GetSttNd(), 1 );
+ SwCursor aCursor( SwPosition(aIdx), nullptr );
+ SvxPrintItem aHasTextChangesOnly(RES_PRINT, false);
+ GetDoc()->SetBoxAttr( aCursor, aHasTextChangesOnly );
+ }
+ }
+
+ SwEditShell* pEditShell = GetDoc()->GetEditShell();
+ SwRedlineTable::size_type nPrev = pEditShell->GetRedlineCount();
+ pEditShell->Delete();
+
+ EndAllActionAndCall();
+ EndUndo(SwUndoId::COL_DELETE);
+
+ // track column deletion only if there were tracked text changes
+ // FIXME redline count can be the same in special cases, e.g. adding a
+ // new tracked deletion with removing an own tracked insertion...
+ if ( nPrev != pEditShell->GetRedlineCount() )
+ return true;
+ }
+
StartAllAction();
// search boxes via the layout
@@ -349,11 +392,11 @@ bool SwFEShell::DeleteRow(bool bCompleteTable)
StartAllAction();
// tracked deletion: remove only textbox content,
- // and set IsNoTracked table line property to false
+ // and set HasTextChangesOnly table line property to false
if ( bRecordChanges )
{
- SvxPrintItem aNotTracked(RES_PRINT, false);
- GetDoc()->SetRowNotTracked( *getShellCursor( false ), aNotTracked );
+ SvxPrintItem aHasTextChangesOnly(RES_PRINT, false);
+ GetDoc()->SetRowNotTracked( *getShellCursor( false ), aHasTextChangesOnly );
if ( SwWrtShell* pWrtShell = dynamic_cast<SwWrtShell*>(this) )
pWrtShell->SelectTableRow();
diff --git a/sw/source/core/unocore/unomap.cxx b/sw/source/core/unocore/unomap.cxx
index 40223b34e474..68565eadaf6f 100644
--- a/sw/source/core/unocore/unomap.cxx
+++ b/sw/source/core/unocore/unomap.cxx
@@ -186,6 +186,7 @@ o3tl::span<const SfxItemPropertyMapEntry> SwUnoPropertyMapProvider::GetPropertyM
{ UNO_NAME_ROW_SPAN, FN_UNO_CELL_ROW_SPAN, cppu::UnoType<sal_Int32>::get(), 0, 0 },
{ UNO_NAME_CELL_INTEROP_GRAB_BAG, RES_FRMATR_GRABBAG, cppu::UnoType< cppu::UnoSequenceType<css::beans::PropertyValue> >::get(), PROPERTY_NONE, 0 },
{ UNO_NAME_PARENT_TEXT, FN_UNO_PARENT_TEXT, cppu::UnoType<text::XText>::get(), PropertyAttribute::MAYBEVOID | PropertyAttribute::READONLY, 0 },
+ { UNO_NAME_HAS_TEXT_CHANGES_ONLY, RES_PRINT, cppu::UnoType<bool>::get() , PropertyAttribute::MAYBEVOID, 0},
REDLINE_NODE_PROPERTIES
};
m_aMapEntriesArr[nPropertyId] = aCellMap_Impl;