sw: floating table split
The problem is that the Table Split feature on a floating table results in 2 tables inside 1 frame, which then cannot be exported to DOCX as a floating table. Split the fly frame in this case, and add an anchor node because every floating table needs its own anchor node. Change-Id: I7444a75a953fcea60ffc92c2fa7eaca1b044f54b Reviewed-on: https://gerrit.libreoffice.org/c/core/+/190009 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com> Reviewed-by: Miklos Vajna <vmiklos@collabora.com> (cherry picked from commit 6f55b9a74f8fdd8609e1aa72388a5f8b97dfcea0) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/190075 Tested-by: Jenkins
This commit is contained in:
committed by
Miklos Vajna
parent
0f393e0c1d
commit
fc53ab8e76
+6
-1
@@ -26,6 +26,7 @@
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <tuple>
|
||||
|
||||
#include "bparr.hxx"
|
||||
#include "ndtyp.hxx"
|
||||
@@ -38,6 +39,7 @@ class SwAttrSet;
|
||||
class SfxItemSet;
|
||||
class SwContentNode;
|
||||
class SwDoc;
|
||||
class SwFrameFormat;
|
||||
class SwGrfFormatColl;
|
||||
class SwGrfNode;
|
||||
class SwNode;
|
||||
@@ -301,11 +303,14 @@ public:
|
||||
Is the flag bCalcNewSize set to TRUE, the new SSize for both
|
||||
tables is calculated from the Maximum of the boxes, provided
|
||||
SSize is set "absolute" (LONG_MAX).
|
||||
(Momentarily this is needed only for the RTF-parser.) */
|
||||
*/
|
||||
SwTableNode* SplitTable( SwNode& rPos, bool bAfter = true,
|
||||
bool bCalcNewSize = false );
|
||||
void SplitFloatingTableFrame(SwTableNode & rNewTableNode,
|
||||
::std::tuple<SwStartNode &, SwFrameFormat &, SwTextNode &> floatingFrame);
|
||||
/// Two Tables that are following one another are merged.
|
||||
bool MergeTable( SwNode& rPos, bool bWithPrev = true );
|
||||
void MergeFloatingTableFrame(SwNodeOffset nEndOfOldFlyIndex);
|
||||
|
||||
/// Insert a new SwSection.
|
||||
SwSectionNode* InsertTextSection(SwNode& rNd,
|
||||
|
||||
Binary file not shown.
@@ -271,6 +271,154 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf159377)
|
||||
CPPUNIT_ASSERT_EQUAL(SwNodeOffset(28), pDoc->GetNodes().Count());
|
||||
}
|
||||
|
||||
CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testSplitFloatingTable)
|
||||
{
|
||||
createSwDoc("floattable-split.docx");
|
||||
|
||||
SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
|
||||
|
||||
{
|
||||
xmlDocUniquePtr pXmlDoc = parseLayoutDump();
|
||||
// apparently follow fly is on the text frame of page 1 even though
|
||||
// positioned on page 2...
|
||||
assertXPath(pXmlDoc, "/root/page[1]/body/txt[2]/anchored/fly", 2);
|
||||
assertXPath(pXmlDoc, "/root/page[1]/body/txt[2]/anchored/fly/txt", 0);
|
||||
assertXPath(pXmlDoc,
|
||||
"/root/page[1]/body/txt[2]/anchored/fly[infos/bounds/@top < "
|
||||
"/root/page[2]/infos/bounds/@top]/tab",
|
||||
1);
|
||||
assertXPath(pXmlDoc,
|
||||
"/root/page[1]/body/txt[2]/anchored/fly[infos/bounds/@top > "
|
||||
"/root/page[2]/infos/bounds/@top]/tab",
|
||||
1);
|
||||
assertXPath(pXmlDoc,
|
||||
"/root/page[1]/body/txt[2]/anchored/fly[infos/bounds/@top < "
|
||||
"/root/page[2]/infos/bounds/@top]/tab/row",
|
||||
5);
|
||||
assertXPath(pXmlDoc,
|
||||
"/root/page[1]/body/txt[2]/anchored/fly[infos/bounds/@top > "
|
||||
"/root/page[2]/infos/bounds/@top]/tab/row",
|
||||
4);
|
||||
}
|
||||
|
||||
pWrtShell->GotoFly(UIName{ u"Frame1"_ustr });
|
||||
pWrtShell->Down(/*bSelect=*/false, 3);
|
||||
|
||||
pWrtShell->SplitTable(SplitTable_HeadlineOption::BorderCopy);
|
||||
|
||||
{
|
||||
xmlDocUniquePtr pXmlDoc = parseLayoutDump();
|
||||
assertXPath(pXmlDoc, "/root/page[1]/body/txt[2]/anchored/fly", 1);
|
||||
assertXPath(pXmlDoc, "/root/page[1]/body/txt[2]/anchored/fly/txt", 0);
|
||||
assertXPath(pXmlDoc, "/root/page[1]/body/txt[2]/anchored/fly/tab", 1);
|
||||
assertXPath(pXmlDoc, "/root/page[1]/body/txt[2]/anchored/fly/tab/row", 3);
|
||||
assertXPath(pXmlDoc, "/root/page[1]/body/txt[3]/anchored/fly", 2);
|
||||
|
||||
assertXPath(pXmlDoc, "/root/page[1]/body/txt[3]/anchored/fly/txt", 0);
|
||||
assertXPath(pXmlDoc,
|
||||
"/root/page[1]/body/txt[3]/anchored/fly[infos/bounds/@top < "
|
||||
"/root/page[2]/infos/bounds/@top]/tab",
|
||||
1);
|
||||
assertXPath(pXmlDoc,
|
||||
"/root/page[1]/body/txt[3]/anchored/fly[infos/bounds/@top > "
|
||||
"/root/page[2]/infos/bounds/@top]/tab",
|
||||
1);
|
||||
assertXPath(pXmlDoc,
|
||||
"/root/page[1]/body/txt[3]/anchored/fly[infos/bounds/@top < "
|
||||
"/root/page[2]/infos/bounds/@top]/tab/row",
|
||||
2);
|
||||
assertXPath(pXmlDoc,
|
||||
"/root/page[1]/body/txt[3]/anchored/fly[infos/bounds/@top > "
|
||||
"/root/page[2]/infos/bounds/@top]/tab/row",
|
||||
4);
|
||||
}
|
||||
|
||||
pWrtShell->Do(SwWrtShell::UNDO);
|
||||
|
||||
{
|
||||
xmlDocUniquePtr pXmlDoc = parseLayoutDump();
|
||||
// apparently follow fly is on the text frame of page 1 even though
|
||||
// positioned on page 2...
|
||||
assertXPath(pXmlDoc, "/root/page[1]/body/txt[2]/anchored/fly", 2);
|
||||
assertXPath(pXmlDoc, "/root/page[1]/body/txt[2]/anchored/fly/txt", 0);
|
||||
assertXPath(pXmlDoc,
|
||||
"/root/page[1]/body/txt[2]/anchored/fly[infos/bounds/@top < "
|
||||
"/root/page[2]/infos/bounds/@top]/tab",
|
||||
1);
|
||||
assertXPath(pXmlDoc,
|
||||
"/root/page[1]/body/txt[2]/anchored/fly[infos/bounds/@top > "
|
||||
"/root/page[2]/infos/bounds/@top]/tab",
|
||||
1);
|
||||
assertXPath(pXmlDoc,
|
||||
"/root/page[1]/body/txt[2]/anchored/fly[infos/bounds/@top < "
|
||||
"/root/page[2]/infos/bounds/@top]/tab/row",
|
||||
5);
|
||||
assertXPath(pXmlDoc,
|
||||
"/root/page[1]/body/txt[2]/anchored/fly[infos/bounds/@top > "
|
||||
"/root/page[2]/infos/bounds/@top]/tab/row",
|
||||
4);
|
||||
}
|
||||
|
||||
pWrtShell->Do(SwWrtShell::REDO);
|
||||
|
||||
{
|
||||
xmlDocUniquePtr pXmlDoc = parseLayoutDump();
|
||||
assertXPath(pXmlDoc, "/root/page[1]/body/txt[2]/anchored/fly", 1);
|
||||
assertXPath(pXmlDoc, "/root/page[1]/body/txt[2]/anchored/fly/txt", 0);
|
||||
assertXPath(pXmlDoc, "/root/page[1]/body/txt[2]/anchored/fly/tab", 1);
|
||||
assertXPath(pXmlDoc, "/root/page[1]/body/txt[2]/anchored/fly/tab/row", 3);
|
||||
assertXPath(pXmlDoc, "/root/page[1]/body/txt[3]/anchored/fly", 2);
|
||||
|
||||
assertXPath(pXmlDoc, "/root/page[1]/body/txt[3]/anchored/fly/txt", 0);
|
||||
assertXPath(pXmlDoc,
|
||||
"/root/page[1]/body/txt[3]/anchored/fly[infos/bounds/@top < "
|
||||
"/root/page[2]/infos/bounds/@top]/tab",
|
||||
1);
|
||||
assertXPath(pXmlDoc,
|
||||
"/root/page[1]/body/txt[3]/anchored/fly[infos/bounds/@top > "
|
||||
"/root/page[2]/infos/bounds/@top]/tab",
|
||||
1);
|
||||
assertXPath(pXmlDoc,
|
||||
"/root/page[1]/body/txt[3]/anchored/fly[infos/bounds/@top < "
|
||||
"/root/page[2]/infos/bounds/@top]/tab/row",
|
||||
2);
|
||||
assertXPath(pXmlDoc,
|
||||
"/root/page[1]/body/txt[3]/anchored/fly[infos/bounds/@top > "
|
||||
"/root/page[2]/infos/bounds/@top]/tab/row",
|
||||
4);
|
||||
}
|
||||
|
||||
// now check that these round-trip as floating tables
|
||||
saveAndReload(u"Office Open XML Text"_ustr);
|
||||
|
||||
{
|
||||
xmlDocUniquePtr pXmlDoc = parseLayoutDump();
|
||||
assertXPath(pXmlDoc, "/root/page[1]/body/txt[2]/anchored/fly", 1);
|
||||
assertXPath(pXmlDoc, "/root/page[1]/body/txt[2]/anchored/fly/txt", 0);
|
||||
assertXPath(pXmlDoc, "/root/page[1]/body/txt[2]/anchored/fly/tab", 1);
|
||||
assertXPath(pXmlDoc, "/root/page[1]/body/txt[2]/anchored/fly/tab/row", 3);
|
||||
assertXPath(pXmlDoc, "/root/page[1]/body/txt[3]/anchored/fly", 2);
|
||||
|
||||
assertXPath(pXmlDoc, "/root/page[1]/body/txt[3]/anchored/fly/txt", 0);
|
||||
assertXPath(pXmlDoc,
|
||||
"/root/page[1]/body/txt[3]/anchored/fly[infos/bounds/@top < "
|
||||
"/root/page[2]/infos/bounds/@top]/tab",
|
||||
1);
|
||||
assertXPath(pXmlDoc,
|
||||
"/root/page[1]/body/txt[3]/anchored/fly[infos/bounds/@top > "
|
||||
"/root/page[2]/infos/bounds/@top]/tab",
|
||||
1);
|
||||
assertXPath(pXmlDoc,
|
||||
"/root/page[1]/body/txt[3]/anchored/fly[infos/bounds/@top < "
|
||||
"/root/page[2]/infos/bounds/@top]/tab/row",
|
||||
2);
|
||||
assertXPath(pXmlDoc,
|
||||
"/root/page[1]/body/txt[3]/anchored/fly[infos/bounds/@top > "
|
||||
"/root/page[2]/infos/bounds/@top]/tab/row",
|
||||
4);
|
||||
}
|
||||
}
|
||||
|
||||
CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testPasteTableInMiddleOfParagraph)
|
||||
{
|
||||
createSwDoc();
|
||||
|
||||
@@ -28,10 +28,12 @@
|
||||
#include <svl/stritem.hxx>
|
||||
#include <editeng/shaditem.hxx>
|
||||
#include <fmtfsize.hxx>
|
||||
#include <formatflysplit.hxx>
|
||||
#include <fmtornt.hxx>
|
||||
#include <fmtfordr.hxx>
|
||||
#include <fmtpdsc.hxx>
|
||||
#include <fmtanchr.hxx>
|
||||
#include <fmtcntnt.hxx>
|
||||
#include <fmtlsplt.hxx>
|
||||
#include <frmatr.hxx>
|
||||
#include <cellfrm.hxx>
|
||||
@@ -80,6 +82,7 @@
|
||||
#include <strings.hrc>
|
||||
#include <docsh.hxx>
|
||||
#include <unochart.hxx>
|
||||
#include <unoframe.hxx>
|
||||
#include <node.hxx>
|
||||
#include <ndtxt.hxx>
|
||||
#include <cstdlib>
|
||||
@@ -3174,6 +3177,118 @@ void sw_BoxSetSplitBoxFormats( SwTableBox* pBox, SwCollectTableLineBoxes* pSplPa
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
::std::optional<::std::tuple<SwStartNode &, SwFrameFormat &, SwTextNode &>>
|
||||
FindFloatingTable(SwTableNode & rTableNode)
|
||||
{
|
||||
SwStartNode *const pStartNode{rTableNode.GetNodes()[rTableNode.GetIndex()-1]->GetStartNode()};
|
||||
if (pStartNode
|
||||
&& pStartNode->GetStartNodeType() == SwFlyStartNode
|
||||
&& pStartNode->EndOfSectionIndex()-1 == rTableNode.EndOfSectionIndex())
|
||||
{
|
||||
SwFrameFormat *const pFormat{rTableNode.GetFlyFormat()};
|
||||
if (pFormat && pFormat->GetFlySplit().GetValue())
|
||||
{
|
||||
SwFormatAnchor const& rAnchor{pFormat->GetAnchor()};
|
||||
SwNode *const pNode{rAnchor.GetAnchorNode()};
|
||||
if (pNode && pNode->IsTextNode() // cannot work for at-fly, at-page
|
||||
&& rAnchor.GetAnchorId() != RndStdIds::FLY_AS_CHAR)
|
||||
{
|
||||
return {{*pStartNode, *pFormat, *pNode->GetTextNode()}};
|
||||
}
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void SwNodes::MergeFloatingTableFrame(SwNodeOffset const nEndOfOldFlyIndex)
|
||||
{
|
||||
SwEndNode *const pFrameEndNode{(*this)[nEndOfOldFlyIndex]->GetEndNode()};
|
||||
assert(pFrameEndNode);
|
||||
SwStartNode *const pFrameStartNode{pFrameEndNode->StartOfSectionNode()};
|
||||
assert(pFrameStartNode && pFrameStartNode->GetStartNodeType() == SwFlyStartNode);
|
||||
SwStartNode *const pNewFrameStartNode{(*this)[nEndOfOldFlyIndex+1]->GetStartNode()};
|
||||
assert(pNewFrameStartNode && pNewFrameStartNode->GetStartNodeType() == SwFlyStartNode);
|
||||
SwTableNode *const pNewTableNode{(*this)[nEndOfOldFlyIndex+2]->GetTableNode()};
|
||||
assert(pNewTableNode);
|
||||
assert(pNewTableNode->StartOfSectionNode() == pNewFrameStartNode);
|
||||
SwTableNode *const pOldTableNode{(*this)[pFrameStartNode->GetIndex()+1]->GetTableNode()};
|
||||
assert(pOldTableNode);
|
||||
assert(pOldTableNode->StartOfSectionNode() == pFrameStartNode);
|
||||
|
||||
SwFrameFormat *const pNewFlyFormat{pNewTableNode->GetFlyFormat()};
|
||||
pNewFlyFormat->DelFrames();
|
||||
|
||||
// reset anchor item
|
||||
SwFrameFormat & rFlyFormat{*pOldTableNode->GetFlyFormat()};
|
||||
SwFormatAnchor anchor{rFlyFormat.GetAnchor()};
|
||||
SwNodeIndex const newAnchor(*(*this)[anchor.GetAnchorNode()->GetIndex()]);
|
||||
SwTextNode *const pOldAnchorNode{(*this)[anchor.GetAnchorNode()->GetIndex()+1]->GetTextNode()};
|
||||
assert(pOldAnchorNode);
|
||||
SwPosition const pos{*pOldAnchorNode};
|
||||
anchor.SetAnchor(&pos);
|
||||
rFlyFormat.SetFormatAttr(anchor);
|
||||
|
||||
// delete inserted anchor node
|
||||
{
|
||||
SwPaM pamToCorr(newAnchor);
|
||||
SwPaM pamSafe(newAnchor);
|
||||
bool const success = pamSafe.Move(fnMoveForward, GoInContent);
|
||||
assert(success); (void) success; // must move to old anchor node
|
||||
::PaMCorrAbs(pamToCorr, *pamSafe.GetPoint());
|
||||
}
|
||||
Delete(newAnchor);
|
||||
|
||||
// delete new format (also deletes its SdrObject)
|
||||
m_rMyDoc.DelFrameFormat(pNewFlyFormat);
|
||||
|
||||
// merge fly nodes/delete inserted nodes
|
||||
pFrameStartNode->m_pEndOfSection = pNewFrameStartNode->EndOfSectionNode();
|
||||
pFrameStartNode->EndOfSectionNode()->m_pStartOfSection = pFrameStartNode;
|
||||
pNewTableNode->m_pStartOfSection = pFrameStartNode;
|
||||
DelNodes(SwNodeIndex(*pFrameEndNode), SwNodeOffset(2));
|
||||
}
|
||||
|
||||
void SwNodes::SplitFloatingTableFrame(SwTableNode & rNewTableNode,
|
||||
::std::tuple<SwStartNode &, SwFrameFormat &, SwTextNode &> const floatingFrame)
|
||||
{
|
||||
auto const [rFrameStartNode, rFlyFormat, rAnchorNode]{floatingFrame};
|
||||
SwEndNode *const pOldFrameEndNode{rFrameStartNode.EndOfSectionNode()->GetEndNode()};
|
||||
assert(pOldFrameEndNode);
|
||||
|
||||
// insert new fly nodes between tables
|
||||
new SwEndNode(rNewTableNode, rFrameStartNode);
|
||||
SwStartNode *const pNewFrameStartNode{new SwStartNode{rNewTableNode, SwNodeType::Start, SwFlyStartNode}};
|
||||
pOldFrameEndNode->m_pStartOfSection = pNewFrameStartNode;
|
||||
pNewFrameStartNode->m_pEndOfSection = pOldFrameEndNode;
|
||||
rNewTableNode.m_pStartOfSection = pNewFrameStartNode;
|
||||
|
||||
// relevant part of DocumentLayoutManager::CopyLayoutFormat()
|
||||
auto const newName{m_rMyDoc.GetUniqueFrameName()};
|
||||
SwFlyFrameFormat *const pNewFlyFormat{m_rMyDoc.MakeFlyFrameFormat(newName,
|
||||
static_cast<SwFrameFormat *>(rFlyFormat.GetRegisteredIn()))};
|
||||
SwXFrame::GetOrCreateSdrObject(*pNewFlyFormat);
|
||||
pNewFlyFormat->CopyAttrs(rFlyFormat);
|
||||
pNewFlyFormat->ResetFormatAttr(RES_CHAIN);
|
||||
|
||||
// deleting existing frames for anchor change should not be necessary, and
|
||||
// crashes because it was already added to mpFlyDestroy by FndBox_::DelFrames()
|
||||
|
||||
// create new anchor node *before* existing one
|
||||
SwTextNode *const pNewAnchorNode{MakeTextNode(rAnchorNode,
|
||||
m_rMyDoc.getIDocumentStylePoolAccess().GetTextCollFromPool(RES_POOLCOLL_TEXT))};
|
||||
SwFormatAnchor anchor{rFlyFormat.GetAnchor()};
|
||||
SwPosition const pos{*pNewAnchorNode};
|
||||
anchor.SetAnchor(&pos);
|
||||
rFlyFormat.SetFormatAttr(anchor);
|
||||
pNewFlyFormat->SetFormatAttr(SwFormatContent{pNewFrameStartNode});
|
||||
|
||||
pNewFlyFormat->MakeFrames();
|
||||
}
|
||||
|
||||
/**
|
||||
* Splits a Table in the top-level Line which contains the Index.
|
||||
* All succeeding top-level Lines go into a new Table/Node.
|
||||
@@ -3220,7 +3335,9 @@ void SwDoc::SplitTable( const SwPosition& rPos, SplitTable_HeadlineOption eHdlnM
|
||||
aFndBox.SetTableLines( rTable );
|
||||
aFndBox.DelFrames( rTable );
|
||||
|
||||
SwTableNode* pNew = GetNodes().SplitTable( rPos.GetNode(), false, bCalcNewSize );
|
||||
auto const oFloatingFrame{FindFloatingTable(*pTNd)};
|
||||
|
||||
SwTableNode* pNew = GetNodes().SplitTable(rPos.GetNode(), false, bCalcNewSize);
|
||||
|
||||
if( pNew )
|
||||
{
|
||||
@@ -3228,8 +3345,12 @@ void SwDoc::SplitTable( const SwPosition& rPos, SplitTable_HeadlineOption eHdlnM
|
||||
SwUndoSplitTable* pUndo = nullptr;
|
||||
if (GetIDocumentUndoRedo().DoesUndo())
|
||||
{
|
||||
pUndo = new SwUndoSplitTable(
|
||||
*pNew, std::move(pSaveRowSp), eHdlnMode, bCalcNewSize);
|
||||
pUndo = new SwUndoSplitTable(*pNew, std::move(pSaveRowSp),
|
||||
eHdlnMode, bCalcNewSize, oFloatingFrame
|
||||
? ::std::get<0>(*oFloatingFrame).GetIndex() < ::std::get<2>(*oFloatingFrame).GetIndex()
|
||||
? SwUndoSplitTable::FloatingMode::FloatingAnchoredAfter
|
||||
: SwUndoSplitTable::FloatingMode::FloatingAnchoredBefore
|
||||
: SwUndoSplitTable::FloatingMode::Not);
|
||||
GetIDocumentUndoRedo().AppendUndo(std::unique_ptr<SwUndo>(pUndo));
|
||||
if( aHistory.Count() )
|
||||
pUndo->SaveFormula( aHistory );
|
||||
@@ -3289,12 +3410,18 @@ void SwDoc::SplitTable( const SwPosition& rPos, SplitTable_HeadlineOption eHdlnM
|
||||
break;
|
||||
}
|
||||
|
||||
// And insert Frames
|
||||
pNew->MakeOwnFrames();
|
||||
if (oFloatingFrame)
|
||||
{
|
||||
GetNodes().SplitFloatingTableFrame(*pNew, *oFloatingFrame);
|
||||
}
|
||||
else
|
||||
{
|
||||
pNew->MakeOwnFrames();
|
||||
|
||||
// Insert a paragraph between the Table
|
||||
GetNodes().MakeTextNode( *pNew,
|
||||
// Insert a paragraph between the tables
|
||||
GetNodes().MakeTextNode( *pNew,
|
||||
getIDocumentStylePoolAccess().GetTextCollFromPool( RES_POOLCOLL_TEXT ) );
|
||||
}
|
||||
}
|
||||
|
||||
// Update Layout
|
||||
|
||||
@@ -319,7 +319,12 @@ public:
|
||||
|
||||
class SwUndoSplitTable final : public SwUndo
|
||||
{
|
||||
public:
|
||||
enum class FloatingMode { Not, FloatingAnchoredAfter, FloatingAnchoredBefore };
|
||||
|
||||
private:
|
||||
SwNodeOffset m_nTableNode, m_nOffset;
|
||||
FloatingMode m_eFloatingMode;
|
||||
std::unique_ptr<SwSaveRowSpan> mpSaveRowSpan; // stores row span values at the splitting row
|
||||
std::unique_ptr<SaveTable> m_pSavedTable;
|
||||
std::unique_ptr<SwHistory> m_pHistory;
|
||||
@@ -329,7 +334,7 @@ class SwUndoSplitTable final : public SwUndo
|
||||
|
||||
public:
|
||||
SwUndoSplitTable( const SwTableNode& rTableNd, std::unique_ptr<SwSaveRowSpan> pRowSp,
|
||||
SplitTable_HeadlineOption nMode, bool bCalcNewSize );
|
||||
SplitTable_HeadlineOption nMode, bool bCalcNewSize, FloatingMode eMode);
|
||||
|
||||
virtual ~SwUndoSplitTable() override;
|
||||
|
||||
|
||||
@@ -2822,9 +2822,13 @@ void SwUndoCpyTable::RedoImpl(::sw::UndoRedoContext & rContext)
|
||||
}
|
||||
|
||||
SwUndoSplitTable::SwUndoSplitTable( const SwTableNode& rTableNd,
|
||||
std::unique_ptr<SwSaveRowSpan> pRowSp, SplitTable_HeadlineOption eMode, bool bNewSize )
|
||||
: SwUndo( SwUndoId::SPLIT_TABLE, rTableNd.GetDoc() ),
|
||||
m_nTableNode( rTableNd.GetIndex() ), m_nOffset( 0 ), mpSaveRowSpan( std::move(pRowSp) ),
|
||||
std::unique_ptr<SwSaveRowSpan> pRowSp, SplitTable_HeadlineOption const eMode,
|
||||
bool const bNewSize, FloatingMode const eFloatingMode)
|
||||
: SwUndo( SwUndoId::SPLIT_TABLE, rTableNd.GetDoc() )
|
||||
, m_nTableNode( rTableNd.GetIndex() )
|
||||
, m_nOffset( 0 )
|
||||
, m_eFloatingMode(eFloatingMode)
|
||||
, mpSaveRowSpan( std::move(pRowSp) ),
|
||||
m_nMode( eMode ), m_nFormulaEnd( 0 ), m_bCalcNewSize( bNewSize )
|
||||
{
|
||||
switch( m_nMode )
|
||||
@@ -2853,10 +2857,20 @@ void SwUndoSplitTable::UndoImpl(::sw::UndoRedoContext & rContext)
|
||||
SwPaM *const pPam(& rContext.GetCursorSupplier().CreateNewShellCursor());
|
||||
|
||||
SwPosition& rPtPos = *pPam->GetPoint();
|
||||
rPtPos.Assign( m_nTableNode + m_nOffset );
|
||||
assert(rPtPos.GetNode().GetContentNode()->Len() == 0); // empty para inserted
|
||||
|
||||
if (m_eFloatingMode != FloatingMode::Not)
|
||||
{
|
||||
// index members are *before* frame-split
|
||||
auto const nEndOfOldFlyIndex{m_nTableNode + m_nOffset
|
||||
+ (m_eFloatingMode == FloatingMode::FloatingAnchoredBefore ? 1 : 0)};
|
||||
rDoc.GetNodes().MergeFloatingTableFrame(nEndOfOldFlyIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
rPtPos.Assign(m_nTableNode + m_nOffset);
|
||||
assert(rPtPos.GetNode().IsTextNode()); // inserted text node
|
||||
assert(rPtPos.GetNode().GetContentNode()->Len() == 0); // empty para inserted
|
||||
|
||||
// avoid asserts from ~SwContentIndexReg
|
||||
SwNodeIndex const idx(rDoc.GetNodes(), m_nTableNode + m_nOffset);
|
||||
{
|
||||
@@ -2871,6 +2885,7 @@ void SwUndoSplitTable::UndoImpl(::sw::UndoRedoContext & rContext)
|
||||
|
||||
rPtPos.Assign( m_nTableNode + m_nOffset );
|
||||
SwTableNode* pTableNd = rPtPos.GetNode().GetTableNode();
|
||||
assert(pTableNd);
|
||||
SwTable& rTable = pTableNd->GetTable();
|
||||
rTable.SwitchFormulasToInternalRepresentation();
|
||||
|
||||
|
||||
@@ -392,7 +392,7 @@ typedef bool (SwWrtShell::*FNSimpleMove)();
|
||||
|
||||
enum class FieldDialogPressedButton { NONE, Previous, Next };
|
||||
|
||||
void Do(DoType eDoType, sal_uInt16 nCnt = 1, sal_uInt16 nOffset = 0);
|
||||
SW_DLLPUBLIC void Do(DoType eDoType, sal_uInt16 nCnt = 1, sal_uInt16 nOffset = 0);
|
||||
OUString GetDoString( DoType eDoType ) const;
|
||||
OUString GetRepeatString() const;
|
||||
void GetDoStrings( DoType eDoType, SfxStringListItem& rStrLstItem ) const;
|
||||
|
||||
Reference in New Issue
Block a user