22#include <osl/diagnose.h>
66 typedef std::vector< BoxSpanInfo > BoxStructure;
67 typedef std::vector< BoxStructure > LineStructure;
68 typedef std::deque< sal_uLong > ColumnStructure;
76 typedef std::vector< SubBox > SubLine;
77 typedef std::vector< SubLine > SubTable;
82 LineStructure maLines;
83 ColumnStructure maCols;
84 sal_uInt16 mnStartCol;
89 sal_uLong &rnB, sal_uInt16 &rnC, ColumnStructure::iterator& rpCl,
90 BoxStructure::iterator& rpSel,
bool &rbSel,
bool bCover );
91 void incColSpan( sal_uInt16 nLine, sal_uInt16 nCol );
92 explicit TableStructure(
const SwTable& rTable );
95 LineStructure::size_type nMinSize );
96 LineStructure::size_type getLineCount()
const
97 {
return maLines.size(); }
98 void moreLines(
const SwTable& rTable );
99 void assignBoxes(
const TableStructure &rSource );
104 SubTable::iterator insertSubLine( SubTable& rSubTable,
SwTableLine& rLine,
105 const SubTable::iterator& pStartLn );
107 SubTable::iterator insertSubBox( SubTable& rSubTable,
SwTableBox& rBox,
108 SubTable::iterator pStartLn,
const SubTable::iterator& pEndLn )
112 SubTable::size_type nSize =
static_cast<SubTable::size_type
>(std::distance( pStartLn, pEndLn ));
116 for(
const auto& rSubBox : *pStartLn )
119 aSub.mpBox = rSubBox.mpBox;
120 aSub.mbCovered =
true;
121 aSubLine.push_back( aSub );
125 rSubTable.insert( pEndLn, aSubLine );
129 pStartLn = insertSubLine( rSubTable, *pLine, pStartLn );
130 OSL_ENSURE( pStartLn == pEndLn,
"Sub line confusion" );
136 aSub.mbCovered =
false;
137 while( pStartLn != pEndLn )
139 pStartLn->push_back( aSub );
140 aSub.mbCovered =
true;
147 SubTable::iterator insertSubLine( SubTable& rSubTable,
SwTableLine& rLine,
148 const SubTable::iterator& pStartLn )
150 SubTable::iterator pMax = pStartLn;
152 SubTable::difference_type nMax = 1;
155 SubTable::iterator pTmp = insertSubBox( rSubTable, *pBox, pStartLn, pMax );
156 SubTable::difference_type nTmp = std::distance( pStartLn, pTmp );
166 TableStructure::TableStructure(
const SwTable& rTable ) :
167 maLines( rTable.GetTabLines().
size() ), mnStartCol(USHRT_MAX),
170 maCols.push_front(0);
173 addLine( nCnt, pLine->GetTabBoxes(),
nullptr, rTable.
IsNewModel() );
176 TableStructure::TableStructure(
const SwTable& rTable,
178 LineStructure::size_type nMinSize )
179 : mnStartCol(USHRT_MAX), mnAddLine(0)
184 bool bNoSelection = rSelBoxes.
size() < 2;
186 maCols.push_front(0);
187 const SwTableLine* pLine = rFndLines.front()->GetLine();
190 if( rFndLines.size() > 1 )
192 pLine = rFndLines.back()->GetLine();
195 if( nStartLn < USHRT_MAX && nEndLn < USHRT_MAX )
198 if( bNoSelection && nMinSize > nEndLn - nStartLn + 1 )
201 if( nNewEndLn >= rLines.
size() )
203 mnAddLine = nNewEndLn - rLines.
size() + 1;
204 nNewEndLn = rLines.
size() - 1;
206 while( nEndLn < nNewEndLn )
211 pInsLine->
GetBoxes().insert(pInsLine->
GetBoxes().begin(), std::make_unique<FndBox_>(pTmpBox, pInsLine));
212 rFndLines.push_back(std::unique_ptr<FndLine_>(pInsLine));
215 maLines.resize( nEndLn - nStartLn + 1 );
220 addLine( nCnt, rLines[nLine]->GetTabBoxes(),
226 if( bNoSelection && mnStartCol < USHRT_MAX )
228 sal_uInt16 nIdx =
std::min(mnStartCol, o3tl::narrowing<sal_uInt16>(maLines[0].
size()));
229 mnStartCol = std::accumulate(maLines[0].
begin(), maLines[0].
begin() + nIdx, sal_uInt16(0),
230 [](sal_uInt16 sum,
const BoxSpanInfo& rInfo) {
return sum + rInfo.mnColSpan; });
233 mnStartCol = USHRT_MAX;
236 void TableStructure::addLine( sal_uInt16 &rLine,
const SwTableBoxes& rBoxes,
239 bool bComplex =
false;
241 for( SwTableBoxes::size_type nBox = 0; !bComplex && nBox < rBoxes.size(); ++nBox )
242 bComplex = !rBoxes[nBox]->GetTabLines().empty();
247 aSubTable.push_back( aSubLine );
248 SubTable::iterator pStartLn = aSubTable.begin();
249 SubTable::iterator pEndLn = aSubTable.end();
250 for(
auto pBox : rBoxes )
251 insertSubBox( aSubTable, *pBox, pStartLn, pEndLn );
252 SubTable::size_type nSize = aSubTable.size();
255 maLines.resize( maLines.size() + nSize - 1 );
256 while( pStartLn != pEndLn )
258 bool bSelected =
false;
261 maLines[rLine].reserve( pStartLn->size() );
262 BoxStructure::iterator pSel = maLines[rLine].end();
263 ColumnStructure::iterator pCol = maCols.begin();
264 for(
const auto& rBox : *pStartLn )
266 addBox( rLine, pSelBoxes, rBox.mpBox, nBorder, nCol,
267 pCol, pSel, bSelected, rBox.mbCovered );
276 bool bSelected =
false;
279 maLines[rLine].reserve( rBoxes.size() );
280 ColumnStructure::iterator pCol = maCols.begin();
281 BoxStructure::iterator pSel = maLines[rLine].end();
282 for(
auto pBox : rBoxes )
283 addBox( rLine, pSelBoxes, pBox, nBorder, nCol,
284 pCol, pSel, bSelected,
false );
289 void TableStructure::addBox( sal_uInt16 nLine,
const SwSelBoxes* pSelBoxes,
291 ColumnStructure::iterator& rpCol, BoxStructure::iterator& rpSel,
292 bool &rbSelected,
bool bCovered )
296 pSelBoxes->
end() != pSelBoxes->
find( pBox ) )
298 aInfo.mbSelected =
true;
299 if( mnStartCol == USHRT_MAX )
301 mnStartCol = o3tl::narrowing<sal_uInt16>(maLines[nLine].
size());
302 if( pSelBoxes->
size() < 2 )
305 aInfo.mbSelected =
false;
310 aInfo.mbSelected =
false;
312 const sal_uInt16 nLeftCol = rnCol;
313 while( rpCol != maCols.end() && *rpCol < rnBorder )
318 if( rpCol == maCols.end() || *rpCol > rnBorder )
320 rpCol = maCols.insert( rpCol, rnBorder );
321 incColSpan( nLine, rnCol );
323 aInfo.mnColSpan = rnCol - nLeftCol;
324 aInfo.mpCopy =
nullptr;
325 aInfo.mpBox = bCovered ? nullptr : pBox;
326 maLines[nLine].push_back( aInfo );
327 if( !aInfo.mbSelected )
332 while( rpSel != maLines[nLine].
end() )
334 rpSel->mbSelected =
true;
340 rpSel = maLines[nLine].end();
346 void TableStructure::moreLines(
const SwTable& rTable )
352 const sal_uInt16 nLineCount = rLines.
size();
353 if( nLineCount < mnAddLine )
354 mnAddLine = nLineCount;
355 sal_uInt16 nLine = o3tl::narrowing<sal_uInt16>(maLines.size());
356 maLines.resize( nLine + mnAddLine );
359 SwTableLine *pLine = rLines[ nLineCount - mnAddLine ];
365 void TableStructure::incColSpan( sal_uInt16 nLineMax, sal_uInt16 nNewCol )
367 for( sal_uInt16 nLine = 0; nLine < nLineMax; ++nLine )
369 BoxStructure::iterator pInfo = maLines[nLine].begin();
370 BoxStructure::iterator pEnd = maLines[nLine].end();
372 while( nNewCol > nCol && ++pInfo != pEnd )
373 nCol += pInfo->mnColSpan;
375 ++(pInfo->mnColSpan);
379 void TableStructure::assignBoxes(
const TableStructure &rSource )
381 LineStructure::const_iterator pFirstLine = rSource.maLines.begin();
382 LineStructure::const_iterator pLastLine = rSource.maLines.end();
383 if( pFirstLine == pLastLine )
385 LineStructure::const_iterator pCurrLine = pFirstLine;
386 LineStructure::size_type nLineCount = maLines.size();
387 sal_uInt16 nFirstStartCol = 0;
389 BoxStructure::const_iterator pFirstBox = pFirstLine->begin();
390 if( pFirstBox != pFirstLine->end() && pFirstBox->mpBox &&
391 pFirstBox->mpBox->getDummyFlag() )
392 nFirstStartCol = pFirstBox->mnColSpan;
394 for( LineStructure::size_type nLine = 0; nLine < nLineCount; ++nLine )
396 BoxStructure::const_iterator pFirstBox = pCurrLine->begin();
397 BoxStructure::const_iterator pLastBox = pCurrLine->end();
398 sal_uInt16 nCurrStartCol = mnStartCol;
399 if( pFirstBox != pLastBox )
401 BoxStructure::const_iterator pTmpBox = pLastBox;
403 if( pTmpBox->mpBox && pTmpBox->mpBox->getDummyFlag() )
405 if( pFirstBox != pLastBox && pFirstBox->mpBox &&
406 pFirstBox->mpBox->getDummyFlag() )
408 if( nCurrStartCol < USHRT_MAX )
410 if( pFirstBox->mnColSpan > nFirstStartCol )
411 nCurrStartCol += pFirstBox->mnColSpan - nFirstStartCol;
416 if( pFirstBox != pLastBox )
418 BoxStructure::const_iterator pCurrBox = pFirstBox;
419 BoxStructure &rBox = maLines[nLine];
420 BoxStructure::size_type nBoxCount = rBox.size();
422 for( BoxStructure::size_type nBox = 0; nBox < nBoxCount; ++nBox )
424 BoxSpanInfo& rInfo = rBox[nBox];
425 nCol += rInfo.mnColSpan;
426 if( rInfo.mbSelected || nCol > nCurrStartCol )
428 rInfo.mpCopy = pCurrBox->mpBox;
429 if( rInfo.mbSelected && rInfo.mpCopy->getDummyFlag() )
432 if( pCurrBox == pLastBox )
434 pCurrBox = pFirstBox;
435 if( pCurrBox->mpBox->getDummyFlag() )
438 rInfo.mpCopy = pCurrBox->mpBox;
441 if( pCurrBox == pLastBox )
443 if( rInfo.mbSelected )
444 pCurrBox = pFirstBox;
447 rInfo.mbSelected = rInfo.mpCopy ==
nullptr;
451 rInfo.mbSelected = rInfo.mpCopy ==
nullptr;
456 if( pCurrLine == pLastLine )
457 pCurrLine = pFirstLine;
461 void TableStructure::copyBoxes(
const SwTable& rSource,
SwTable& rDstTable,
464 LineStructure::size_type nLineCount = maLines.size();
465 for( LineStructure::size_type nLine = 0; nLine < nLineCount; ++nLine )
467 const BoxStructure &rBox = maLines[nLine];
468 BoxStructure::size_type nBoxCount = rBox.size();
469 for( BoxStructure::size_type nBox = 0; nBox < nBoxCount; ++nBox )
471 const BoxSpanInfo& rInfo = rBox[nBox];
472 if( ( rInfo.mpCopy && !rInfo.mpCopy->getDummyFlag() )
473 || rInfo.mbSelected )
477 lcl_CpyBox( rSource, rInfo.mpCopy, rDstTable, pBox,
495 "No content in this Box" );
502 std::unique_ptr< SwNodeRange > pRg( pCpyBox ?
527 bool bReplaceColl =
true;
528 if( bDelContent && !bUndoRedline )
548 ((RndStdIds::FLY_AT_PARA == pAnchor->
GetAnchorId()) ||
549 (RndStdIds::FLY_AT_CHAR == pAnchor->
GetAnchorId())) &&
550 aInsIdx <= *pAnchorNode && *pAnchorNode <= aEndNdIdx.
GetNode() )
571 bReplaceColl =
false;
579 pUndo->
AddBoxAfter( *pDstBox, aInsIdx, bDelContent );
595 o3tl::narrowing<sal_uInt16>(
601 SwPaM aPam( aSavePos );
623 if( !aBoxAttrSet.
Count() )
633 if( nNewIdx != nOldIdx )
648 TableStructure aCopyStruct( rCpyTable );
651 FndBox_ aFndBox(
nullptr,
nullptr );
653 FndPara aPara( rSelBoxes, &aFndBox );
656 TableStructure aTarget( *
this, aFndBox, rSelBoxes, aCopyStruct.getLineCount() );
664 pUndo->
InsertRow( *
this, aBoxes, aTarget.mnAddLine );
666 InsertRow( pDoc, aBoxes, aTarget.mnAddLine,
true );
668 aTarget.moreLines( *
this );
673 aTarget.assignBoxes( aCopyStruct );
686 aTarget.copyBoxes( rCpyTable, *
this, pUndo );
714 OSL_ENSURE( pMyBox,
"Index is not in a Box in this Table" );
717 FndBox_ aFndBox(
nullptr,
nullptr );
726 bool bDelContent =
true;
739 lcl_CpyBox( rCpyTable, pCpyBox, *
this, pMyBox, bDelContent, pUndo );
741 pTmp = pCpyBox->
FindNextBox( rCpyTable, pCpyBox,
false );
746 pTmp = pMyBox->
FindNextBox( *
this, pMyBox,
false );
780 OSL_ENSURE( !rSelBoxes.
empty(),
"Missing selection" );
795 FndBox_ aFndBox(
nullptr,
nullptr );
798 FndPara aPara( rSelBoxes, &aFndBox );
808 const FndLines_t::size_type nFndCnt = aFndBox.
GetLines().size();
814 pFLine = aFndBox.
GetLines().front().get();
826 if( 1 < rSelBoxes.
size() )
836 const SwTableBoxes::size_type nSttBox = pFLine->
GetLine()->
GetBoxPos( pSttBox );
848 for( SwTableBoxes::size_type nBx = 0; nBx < pCpyLn->
GetTabBoxes().
size(); ++nBx )
849 if( !pLastLn->
GetTabBoxes()[ nSttBox + nBx ]->GetSttNd() )
855 OSL_ENSURE( pInsBox && pInsBox->
GetSttNd(),
856 "no ContentBox or it's not in this Table" );
863 aBoxes ), nNewLns,
true ) )
877 pFLine = aFndBox.
GetLines()[ nLn % nFndCnt ].get();
880 const SwTableBoxes::size_type nSttBox = pLine->
GetBoxPos( pSttBox );
881 std::unique_ptr<FndLine_> pInsFLine;
887 pLine = pInsFLine->GetLine();
903 for (FndBoxes_t::size_type nBx = 0; nBx < pFLine->
GetBoxes().
size(); ++nBx)
911 pFndBox =
new FndBox_( pTmpBox, pInsFLine.get() );
912 pInsFLine->GetBoxes().insert( pInsFLine->GetBoxes().begin() + nBx,
913 std::unique_ptr<FndBox_>(pFndBox));
915 aFndBox.
GetLines().insert( aFndBox.
GetLines().begin() + nLn, std::move(pInsFLine));
917 else if( pFLine->
GetBoxes().size() == 1 )
925 for( SwTableBoxes::size_type nBx = 0; nBx < pCpyLn->
GetTabBoxes().
size(); ++nBx )
931 if( nBx == pFLine->
GetBoxes().size() )
933 pFndBox =
new FndBox_( pTmpBox, pFLine );
935 std::unique_ptr<FndBox_>(pFndBox));
943 if( 0 != ( pFLine->
GetBoxes().size() %
948 for (
auto &rpBox : pFLine->
GetBoxes())
950 if (!rpBox->GetBox()->GetSttNd())
972 for (
size_t n = 0;
n < rSelBoxes.
size(); ++
n)
975 rSelBoxes[
n],
true, pUndo );
979 for (FndLines_t::size_type nLn = 0; nLn < aFndBox.
GetLines().
size(); ++nLn)
981 pFLine = aFndBox.
GetLines()[ nLn ].get();
984 for (FndBoxes_t::size_type nBx = 0; nBx < pFLine->
GetBoxes().
size(); ++nBx)
989 *
this, pFLine->
GetBoxes()[nBx]->GetBox(),
true, pUndo );
sal_uInt32 GetValue() const
void SetTableLines(const SwSelBoxes &rBoxes, const SwTable &rTable)
const FndLines_t & GetLines() const
void MakeFrames(SwTable &rTable)
void DelFrames(SwTable &rTable)
const FndBoxes_t & GetBoxes() const
const SwTableLine * GetLine() const
virtual void DelLayoutFormat(SwFrameFormat *pFormat)=0
static bool IsRedlineOn(const RedlineFlags eM)
virtual SwTextFormatColl * GetTextCollFromPool(sal_uInt16 nId, bool bRegardLanguage=true)=0
Return "Auto-Collection with ID.
const T * GetItemIfSet(TypedWhichId< T > nWhich, bool bSrchInParent=true) const
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
tools::Long GetWidth() const
SwFormatColl * GetFormatColl() const
virtual sal_Int32 Len() const
void CorrAbs(const SwNode &rOldNode, const SwPosition &rNewPos, const sal_Int32 nOffset=0, bool bMoveCursor=false)
static SwTableNode * IsIdxInTable(const SwNodeIndex &rIdx)
IDocumentUndoRedo & GetIDocumentUndoRedo()
IDocumentRedlineAccess const & getIDocumentRedlineAccess() const
IDocumentLayoutAccess const & getIDocumentLayoutAccess() const
IDocumentStylePoolAccess const & getIDocumentStylePoolAccess() const
::sw::DocumentContentOperationsManager const & GetDocumentContentOperationsManager() const
const SwTextFormatColl * GetDfltTextFormatColl() const
const SwAttrPool & GetAttrPool() const
const sw::FrameFormats< sw::SpzFrameFormat * > * GetSpzFrameFormats() const
bool SetTextFormatColl(const SwPaM &rRg, SwTextFormatColl *pFormat, const bool bReset=true, const bool bResetListAttrs=false, SwRootFrame const *pLayout=nullptr)
Add 4th optional parameter <bResetListAttrs>.
SvNumberFormatter * GetNumberFormatter(bool bCreate=true)
Marks a node in the document model.
SwNodeOffset GetIndex() const
Base class of the Writer document model elements.
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
SwNodeOffset GetIndex() const
const SwStartNode * FindTableBoxStartNode() const
SwNodeOffset EndOfSectionIndex() const
SwContentNode * GetContentNode()
const SwEndNode * EndOfSectionNode() const
SwTextNode * MakeTextNode(SwNode &rWhere, SwTextFormatColl *pColl, bool bNewFrames=true)
Implementations of "Make...Node" are in the given .cxx-files.
void Delete(const SwNodeIndex &rPos, SwNodeOffset nNodes=SwNodeOffset(1))
static SwContentNode * GoPrevious(SwNodeIndex *)
SwContentNode * GoNext(SwNodeIndex *) const
PaM is Point and Mark: a selection of the document model.
virtual void SetMark()
Unless this is called, the getter method of Mark will return Point.
bool Move(SwMoveFnCollection const &fnMove=fnMoveForward, SwGoInDoc fnGo=GoInContent)
Movement of cursor.
SwTableBox is one table cell in the document model.
sal_Int32 getRowSpan() const
SwNodeOffset GetSttIdx() const
SwFrameFormat * GetFrameFormat()
SwTableLines & GetTabLines()
const SwStartNode * GetSttNd() const
SwTableBox * FindNextBox(const SwTable &, const SwTableBox *, bool bOvrTableLns=true) const
SwFrameFormat * ClaimFrameFormat()
SwTableLine is one table row in the document model.
SwTableBoxes & GetTabBoxes()
sal_uInt16 GetBoxPos(const SwTableBox *pBox) const
SwTableLine * back() const
SwTableLine * front() const
std::vector< SwTableLine * >::size_type size_type
sal_uInt16 GetPos(const SwTableLine *pBox) const
const SwTable & GetTable() const
SwTable is one table in the document model, containing rows (which contain cells).
void SetHTMLTableLayout(std::shared_ptr< SwHTMLTableLayout > const &r)
bool InsNewTable(const SwTable &rCpyTable, const SwSelBoxes &, SwUndoTableCpyTable *pUndo)
SwTableLines & GetTabLines()
SwTableFormat * GetFrameFormat()
bool IsTableComplex() const
void SwitchFormulasToRelativeRepresentation()
bool InsertRow(SwDoc *, const SwSelBoxes &rBoxes, sal_uInt16 nCnt, bool bBehind)
SwTable::InsertRow(..) inserts one or more rows before or behind the selected boxes.
const SwTableBox * GetTableBox(const OUString &rName, const bool bPerformValidCheck=false) const
bool InsTable(const SwTable &rCpyTable, const SwNodeIndex &, SwUndoTableCpyTable *pUndo)
Copy Table into this Box.
SwTableSortBoxes & GetTabSortBoxes()
static SwSelBoxes & SelLineFromBox(const SwTableBox *pBox, SwSelBoxes &rBoxes, bool bToTop=true)
Represents the style of a paragraph.
SwTextNode is a paragraph in the document model.
SwTextFormatColl * GetTextColl() const
void AddBoxAfter(const SwTableBox &rBox, const SwNodeIndex &rIdx, bool bDelContent)
bool InsertRow(SwTable &rTable, const SwSelBoxes &rBoxes, sal_uInt16 nCnt)
void AddBoxBefore(const SwTableBox &rBox, bool bDelContent)
const_iterator find(const Value &x) const
const_iterator end() const
std::pair< const_iterator, bool > insert(Value &&x)
void CopyWithFlyInFly(const SwNodeRange &rRg, SwNode &rInsPos, const std::pair< const SwPaM &, const SwPosition & > *pCopiedPaM=nullptr, bool bMakeNewFrames=true, bool bDelRedlines=true, bool bCopyFlyAtFly=false, SwCopyFlags flags=SwCopyFlags::Default) const
note: rRg/rInsPos exclude a partially selected start text node; pCopiedPaM includes a partially selec...
constexpr TypedWhichId< SwTableBoxValue > RES_BOXATR_VALUE(158)
constexpr TypedWhichId< SwTableBoxFormula > RES_BOXATR_FORMULA(157)
constexpr TypedWhichId< SwTableBoxNumFormat > RES_BOXATR_FORMAT(RES_BOXATR_BEGIN)
tools::Long const nBorder
enumrange< T >::Iterator begin(enumrange< T >)
SwNodeOffset min(const SwNodeOffset &a, const SwNodeOffset &b)
bool GoInSection(SwPaM &rPam, SwMoveFnCollection const &fnMove)
SwMoveFnCollection const & fnMoveForward
SwPam::Move()/Find() default argument.
@ RES_POOLCOLL_TABLE
Subgroup table.
@ RES_POOLCOLL_TABLE_HDLN
Table of Contents - heading.
Marks a position in the document model.
void SetContent(sal_Int32 nContentIndex)
Set content index, only valid to call this if the position points to a SwContentNode subclass.
std::vector< SwTableBox * > SwTableBoxes
static void FndContentBox(const SwTableBox *pBox, SwSelBoxes *pPara)
static void FndContentLine(const SwTableLine *pLine, SwSelBoxes *pPara)
static void lcl_CpyBox(const SwTable &rCpyTable, const SwTableBox *pCpyBox, SwTable &rDstTable, SwTableBox *pDstBox, bool bDelContent, SwUndoTableCpyTable *pUndo)
Copy Table into this Box.
void ForEach_FndLineCopyCol(SwTableLines &rLines, FndPara *pFndPara)
This creates a structure mirroring the SwTable structure that contains all rows and non-leaf boxes (a...
std::vector< std::unique_ptr< FndLine_ > > FndLines_t