summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
Diffstat (limited to 'sw')
-rw-r--r--sw/inc/doc.hxx2
-rw-r--r--sw/inc/swtable.hxx2
-rw-r--r--sw/inc/unoprnms.hxx1
-rw-r--r--sw/qa/extras/uiwriter/uiwriter2.cxx77
-rw-r--r--sw/source/core/bastyp/init.cxx2
-rw-r--r--sw/source/core/doc/DocumentRedlineManager.cxx34
-rw-r--r--sw/source/core/docnode/ndtbl1.cxx26
-rw-r--r--sw/source/core/frmedt/fetab.cxx30
-rw-r--r--sw/source/core/table/swtable.cxx15
-rw-r--r--sw/source/core/unocore/unomap.cxx1
-rw-r--r--sw/source/filter/html/htmltab.cxx17
11 files changed, 191 insertions, 16 deletions
diff --git a/sw/inc/doc.hxx b/sw/inc/doc.hxx
index 08510f634569..19a2b6af64b1 100644
--- a/sw/inc/doc.hxx
+++ b/sw/inc/doc.hxx
@@ -1489,6 +1489,8 @@ public:
bool BalanceRowHeight( const SwCursor& rCursor, bool bTstOnly, const bool bOptimize );
void SetRowBackground( const SwCursor& rCursor, const SvxBrushItem &rNew );
static bool GetRowBackground( const SwCursor& rCursor, std::unique_ptr<SvxBrushItem>& rToFill );
+ /// rNotTracked = false means that the row was deleted or inserted with its tracked cell content
+ void SetRowNotTracked( const SwCursor& rCursor, const SvxPrintItem &rNotTracked );
void SetTabBorders( const SwCursor& rCursor, const SfxItemSet& rSet );
void SetTabLineStyle( const SwCursor& rCursor,
const Color* pColor, bool bSetLine,
diff --git a/sw/inc/swtable.hxx b/sw/inc/swtable.hxx
index 5432a24d60e4..6696c94d6cfc 100644
--- a/sw/inc/swtable.hxx
+++ b/sw/inc/swtable.hxx
@@ -444,6 +444,8 @@ public:
void RemoveFromTable();
const SwStartNode *GetSttNd() const { return m_pStartNode; }
sal_uLong GetSttIdx() const;
+ // it doesn't contain box content
+ bool IsEmpty() const;
// Search next/previous box with content.
SwTableBox* FindNextBox( const SwTable&, const SwTableBox*,
diff --git a/sw/inc/unoprnms.hxx b/sw/inc/unoprnms.hxx
index 9cceac0f8d0f..317ad79fa8ed 100644
--- a/sw/inc/unoprnms.hxx
+++ b/sw/inc/unoprnms.hxx
@@ -736,6 +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_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 02d8163cc95e..d1323c8104d5 100644
--- a/sw/qa/extras/uiwriter/uiwriter2.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter2.cxx
@@ -3666,6 +3666,83 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf118311)
assertXPath(pXmlDoc, "//page[1]//body/tab", 0);
}
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testRedlineTableRowDeletion)
+{
+ // 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
+ dispatchCommand(mxComponent, ".uno:DeleteRows", {});
+
+ // This was deleted without change tracking
+ discardDumpedLayout();
+ pXmlDoc = parseLayoutDump();
+ assertXPath(pXmlDoc, "//page[1]//body/tab");
+
+ // 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
+ discardDumpedLayout();
+ pXmlDoc = parseLayoutDump();
+ assertXPath(pXmlDoc, "//page[1]//body/tab");
+
+ // accept last redline
+ pEditShell->AcceptRedline(0);
+
+ // table row (and the 1-row table) was deleted finally
+ discardDumpedLayout();
+ pXmlDoc = parseLayoutDump();
+ assertXPath(pXmlDoc, "//page[1]//body/tab", 0);
+
+ // Undo, and delete the row without change tracking
+
+ dispatchCommand(mxComponent, ".uno:Undo", {});
+ dispatchCommand(mxComponent, ".uno:Undo", {});
+ dispatchCommand(mxComponent, ".uno:Undo", {});
+
+ // table exists again
+ discardDumpedLayout();
+ pXmlDoc = parseLayoutDump();
+ assertXPath(pXmlDoc, "//page[1]//body/tab");
+
+ // disable change tracking
+ pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::ShowDelete
+ | RedlineFlags::ShowInsert);
+
+ CPPUNIT_ASSERT_MESSAGE("redlining should be off",
+ !pDoc->getIDocumentRedlineAccess().IsRedlineOn());
+
+ // delete table row without change tracking
+ dispatchCommand(mxComponent, ".uno:DeleteRows", {});
+
+ // the table (row) was deleted
+ 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 19d2f12d9a3a..f1b86f8dfdc0 100644
--- a/sw/source/core/bastyp/init.cxx
+++ b/sw/source/core/bastyp/init.cxx
@@ -206,6 +206,8 @@ sal_uInt16 const aTableSetRange[] = {
sal_uInt16 const aTableLineSetRange[] = {
RES_FILL_ORDER, RES_FRM_SIZE,
+ // IsNotTracked
+ RES_PRINT, RES_PRINT,
RES_LR_SPACE, RES_UL_SPACE,
RES_BACKGROUND, RES_SHADOW,
RES_ROW_SPLIT, RES_ROW_SPLIT,
diff --git a/sw/source/core/doc/DocumentRedlineManager.cxx b/sw/source/core/doc/DocumentRedlineManager.cxx
index 1c63619a8e1b..0e92f16034a5 100644
--- a/sw/source/core/doc/DocumentRedlineManager.cxx
+++ b/sw/source/core/doc/DocumentRedlineManager.cxx
@@ -38,6 +38,7 @@
#include <strings.hrc>
#include <swmodule.hxx>
#include <osl/diagnose.h>
+#include <editeng/prntitem.hxx>
using namespace com::sun::star;
@@ -430,6 +431,36 @@ namespace
return nullptr;
}
+ // delete the empty tracked table row (i.e. if it's last tracked deletion was accepted)
+ void lcl_DeleteTrackedTableRow ( SwPosition* pPos )
+ {
+ if ( const SwTableBox* pBox = pPos->nNode.GetNode().GetTableBox() )
+ {
+ const SwTableLine* pLine = pBox->GetUpper();
+ const SvxPrintItem *pIsNoTrackedProp =
+ pLine->GetFrameFormat()->GetAttrSet().GetItem<SvxPrintItem>(RES_PRINT);
+ // table row property "IsNotTracked" is set and its value is false
+ if ( pIsNoTrackedProp && !pIsNoTrackedProp->GetValue() )
+ {
+ bool bEmptyLine = true;
+ const SwTableBoxes & rBoxes = pLine->GetTabBoxes();
+ for (size_t nBox = 0; nBox < rBoxes.size(); ++nBox)
+ {
+ if ( !rBoxes[nBox]->IsEmpty() )
+ {
+ bEmptyLine = false;
+ break;
+ }
+ }
+ if ( bEmptyLine )
+ {
+ SwCursor aCursor( *pPos, nullptr );
+ pPos->GetDoc().DeleteRow( aCursor );
+ }
+ }
+ }
+ }
+
bool lcl_AcceptRedline( SwRedlineTable& rArr, SwRedlineTable::size_type& rPos,
bool bCallDelete,
const SwPosition* pSttRng = nullptr,
@@ -565,7 +596,10 @@ namespace
rDoc.getIDocumentRedlineAccess().SetRedlineFlags_intern( eOld & ~RedlineFlags(RedlineFlags::On | RedlineFlags::Ignore));
if( pCSttNd && pCEndNd )
+ {
rDoc.getIDocumentContentOperations().DeleteAndJoin( aPam );
+ lcl_DeleteTrackedTableRow( aPam.End() );
+ }
else if (pCSttNd && !pCEndNd)
{
aPam.GetBound().nContent.Assign( nullptr, 0 );
diff --git a/sw/source/core/docnode/ndtbl1.cxx b/sw/source/core/docnode/ndtbl1.cxx
index 6d2a677712be..9a4f80ee995a 100644
--- a/sw/source/core/docnode/ndtbl1.cxx
+++ b/sw/source/core/docnode/ndtbl1.cxx
@@ -536,6 +536,32 @@ bool SwDoc::GetRowBackground( const SwCursor& rCursor, std::unique_ptr<SvxBrushI
return bRet;
}
+void SwDoc::SetRowNotTracked( const SwCursor& rCursor, const SvxPrintItem &rNew )
+{
+ SwTableNode* pTableNd = rCursor.GetPoint()->nNode.GetNode().FindTableNode();
+ if( !pTableNd )
+ return;
+
+ std::vector<SwTableLine*> aRowArr; // For Lines collecting
+ ::lcl_CollectLines( aRowArr, rCursor, true );
+
+ if( aRowArr.empty() )
+ return;
+
+ if (GetIDocumentUndoRedo().DoesUndo())
+ {
+ GetIDocumentUndoRedo().AppendUndo(std::make_unique<SwUndoAttrTable>(*pTableNd));
+ }
+
+ std::vector<std::unique_ptr<SwTableFormatCmp>> aFormatCmp;
+ aFormatCmp.reserve( std::max( 255, static_cast<int>(aRowArr.size()) ) );
+
+ for( auto pLn : aRowArr )
+ ::lcl_ProcessRowAttr( aFormatCmp, pLn, rNew );
+
+ getIDocumentState().SetModified();
+}
+
static void InsertCell( std::vector<SwCellFrame*>& rCellArr, SwCellFrame* pCellFrame )
{
if( rCellArr.end() == std::find( rCellArr.begin(), rCellArr.end(), pCellFrame ) )
diff --git a/sw/source/core/frmedt/fetab.cxx b/sw/source/core/frmedt/fetab.cxx
index 1a44707f43c3..bf7f1d2d618e 100644
--- a/sw/source/core/frmedt/fetab.cxx
+++ b/sw/source/core/frmedt/fetab.cxx
@@ -32,7 +32,9 @@
#include <fmtornt.hxx>
#include <frmatr.hxx>
#include <fesh.hxx>
+#include <wrtsh.hxx>
#include <doc.hxx>
+#include <docsh.hxx>
#include <IDocumentState.hxx>
#include <IDocumentLayoutAccess.hxx>
#include <cntfrm.hxx>
@@ -325,6 +327,34 @@ bool SwFEShell::DeleteRow(bool bCompleteTable)
}
CurrShell aCurr( this );
+
+ // tracked deletion: remove only textbox content,
+ // and set IsNoTracked table line property to false
+ if ( GetDoc()->GetDocShell()->IsChangeRecording() )
+ {
+ StartUndo(bCompleteTable ? SwUndoId::UI_TABLE_DELETE : SwUndoId::ROW_DELETE);
+ StartAllAction();
+
+ SvxPrintItem aNotTracked(RES_PRINT, false);
+ GetDoc()->SetRowNotTracked( *getShellCursor( false ), aNotTracked );
+
+ if ( SwWrtShell* pWrtShell = dynamic_cast<SwWrtShell*>(this) )
+ pWrtShell->SelectTableRow();
+
+ SwEditShell* pEditShell = GetDoc()->GetEditShell();
+ SwRedlineTable::size_type nPrev = pEditShell->GetRedlineCount();
+ pEditShell->Delete();
+
+ EndAllActionAndCall();
+ EndUndo(bCompleteTable ? SwUndoId::UI_TABLE_DELETE : SwUndoId::ROW_DELETE);
+
+ // track row 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 for boxes via the layout
diff --git a/sw/source/core/table/swtable.cxx b/sw/source/core/table/swtable.cxx
index 65f39748fd34..fda4da0b85d9 100644
--- a/sw/source/core/table/swtable.cxx
+++ b/sw/source/core/table/swtable.cxx
@@ -1868,6 +1868,21 @@ sal_uLong SwTableBox::GetSttIdx() const
return m_pStartNode ? m_pStartNode->GetIndex() : 0;
}
+bool SwTableBox::IsEmpty() const
+{
+ const SwStartNode *pSttNd = GetSttNd();
+ if( pSttNd &&
+ pSttNd->GetIndex() + 2 == pSttNd->EndOfSectionIndex() )
+ {
+ const SwContentNode *pCNd =
+ pSttNd->GetNodes()[pSttNd->GetIndex()+1]->GetContentNode();
+ if( pCNd && !pCNd->Len() )
+ return true;
+ }
+
+ return false;
+}
+
// retrieve information from the client
bool SwTable::GetInfo( SfxPoolItem& rInfo ) const
{
diff --git a/sw/source/core/unocore/unomap.cxx b/sw/source/core/unocore/unomap.cxx
index 247f3d84ece5..55b948a1eafe 100644
--- a/sw/source/core/unocore/unomap.cxx
+++ b/sw/source/core/unocore/unomap.cxx
@@ -542,6 +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_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/html/htmltab.cxx b/sw/source/filter/html/htmltab.cxx
index b56a016e8d74..5149640c6bdd 100644
--- a/sw/source/filter/html/htmltab.cxx
+++ b/sw/source/filter/html/htmltab.cxx
@@ -1226,21 +1226,6 @@ const SwStartNode* HTMLTable::GetPrevBoxStartNode( sal_uInt16 nRow, sal_uInt16 n
return pTable->GetPrevBoxStartNode(USHRT_MAX, USHRT_MAX);
}
-static bool IsBoxEmpty( const SwTableBox *pBox )
-{
- const SwStartNode *pSttNd = pBox->GetSttNd();
- if( pSttNd &&
- pSttNd->GetIndex() + 2 == pSttNd->EndOfSectionIndex() )
- {
- const SwContentNode *pCNd =
- pSttNd->GetNodes()[pSttNd->GetIndex()+1]->GetContentNode();
- if( pCNd && !pCNd->Len() )
- return true;
- }
-
- return false;
-}
-
sal_uInt16 HTMLTable::GetTopCellSpace( sal_uInt16 nRow ) const
{
sal_uInt16 nSpace = m_nCellPadding;
@@ -1413,7 +1398,7 @@ void HTMLTable::FixFrameFormat( SwTableBox *pBox,
pFrameFormat->ResetFormatAttr( RES_BACKGROUND );
// Only set format if there's a value or the box is empty
- if( bHasNumFormat && (bHasValue || IsBoxEmpty(pBox)) )
+ if( bHasNumFormat && (bHasValue || pBox->IsEmpty()) )
{
bool bLock = pFrameFormat->GetDoc()->GetNumberFormatter()
->IsTextFormat( nNumFormat );