49#include <osl/diagnose.h>
52#define CHECK_TABLE(t) (t).CheckConsistency();
97 DeleteSel( pDoc, rBoxes, &rMerged,
nullptr,
true,
true );
131 OSL_FAIL(
"Box out of table line" );
137 for(
size_t nCurrBox = 0; nCurrBox < nCheck; ++nCurrBox )
140 OSL_ENSURE( pBox,
"Missing table box" );
145 if( bSet || nNew > rMax )
148 if( bSet || nNew < rMin )
171 for(
size_t nCurrBox = 0; nCurrBox <
nCount; ++nCurrBox )
174 OSL_ENSURE( pBox,
"Missing table box" );
179 OSL_FAIL(
"Box not found in own upper?" );
205 for(
size_t nCurrBox = 0; nCurrBox <
nCount; ++nCurrBox )
208 OSL_ENSURE( pBox,
"Missing table box" );
211 if( nCurrLeft == nLeft )
216 if(
std::abs( nCurrLeft - nLeft ) <= ( nLeft / 1000 ))
218 if( nCurrLeft >= nLeft )
220 SAL_WARN(
"sw.core",
"Possibly wrong box found" );
226 OSL_FAIL(
"Didn't find wished box" );
260 sal_uInt16 nRowIdx,
const bool bSingle )
264 OSL_ENSURE( !bSingle || nDiff > 0,
"Don't set bSingle when deleting lines!" );
278 const size_t nBoxCount = pLine->
GetTabBoxes().size();
279 for(
size_t nCurrBox = 0; nCurrBox < nBoxCount; ++nCurrBox )
281 sal_Int32 nRowSpan = pLine->
GetTabBoxes()[nCurrBox]->getRowSpan();
282 sal_Int32 nAbsSpan = nRowSpan > 0 ? nRowSpan : -nRowSpan;
285 if( nAbsSpan > nDistance )
302 if( nRowSpan - nDistance > -nDiff )
305 nRowSpan = nDistance + 1;
309 if( nRowSpan + nDistance < nDiff )
312 nRowSpan = -nDistance - 1;
316 pLine->
GetTabBoxes()[ nCurrBox ]->setRowSpan( nRowSpan );
333 OSL_ENSURE(
m_bNewModel,
"Don't call me for old tables" );
338 if( !pStartNd || !pEndNd || pStartNd == pEndNd )
346 for(
size_t nRow = 0; nFound < 2 && nRow < nLines; ++nRow )
349 OSL_ENSURE( pLine,
"Missing table line" );
351 for(
size_t nCol = 0; nCol < nCols; ++nCol )
354 OSL_ENSURE( pBox,
"Missing table box" );
365 else if( pBox->
GetSttNd() == pStartNd )
379 std::optional<SwBoxSelection> pRet(std::in_place);
380 std::vector< std::pair< SwTableBox*, tools::Long > > aNewWidthVector;
381 size_t nCheckBottom = nBottom;
386 for(
size_t nRow = nTop; nRow <= nBottom && bOkay && nRow < nLines; ++nRow )
389 OSL_ENSURE( pLine,
"Missing table line" );
393 for(
size_t nCurrBox = 0; nCurrBox <
nCount; ++nCurrBox )
396 OSL_ENSURE( pBox,
"Missing table box" );
402 if( nRight == nMin && nLeftSpanCnt )
413 if( nRight >= nMid || nRight + nLeft >= nMin + nMin )
420 nDiff = nMin - nLeft;
426 nDiff2 = nRight - nMax;
431 else if( nRightSpanCnt && nRight == nMax )
437 else if( nCurrBox+1 <
nCount )
441 nDiff = nMin - nRight;
446 else if( nRight <= nMax )
449 if( nRow == nTop && nRowSpan < 0 )
454 if( nRowSpan > 1 && nRow + nRowSpan - 1 > nBottom )
455 nBottom = nRow + nRowSpan - 1;
456 if( nRowSpan < -1 && nRow - nRowSpan - 1 > nBottom )
457 nBottom = nRow - nRowSpan - 1;
458 if( nRightSpanCnt && nRight == nMax )
461 else if( nLeft < nMax )
463 if( nLeft <= nMid || nRight + nLeft <= nMax )
470 nDiff = nRight - nMax;
479 nDiff = nLeft - nMax;
488 if( nRow == nBottom )
492 nBottom += nTmpSpan - 1;
493 else if( nTmpSpan < -1 )
494 nBottom -= nTmpSpan + 1;
504 size_t nCheck = nRow;
514 if( pOuterBox == pLeftBox )
516 if( !nLeftSpanCnt || nMin - nDiff != nLeftSpan )
521 if( !nRightSpanCnt || nMax + nDiff != nRightSpan )
527 if( pOuterBox == pLeftBox )
531 nLeftSpan = nMin - nDiff;
532 nLeftSpanCnt = nOutSpan;
538 nRightSpan = nMax + nDiff;
539 nRightSpanCnt = nOutSpan;
542 nCheck += nOutSpan - 1;
543 if( nCheck > nCheckBottom )
544 nCheckBottom = nCheck;
546 else if( ( nLeftSpanCnt && pLeftBox == pOuterBox ) ||
547 ( nRightSpanCnt && pRightBox == pOuterBox ) )
549 std::pair< SwTableBox*, long > aTmp;
550 aTmp.first = pInnerBox;
551 aTmp.second = -nDiff;
552 aNewWidthVector.push_back(aTmp);
553 aTmp.first = pOuterBox;
555 aNewWidthVector.push_back(aTmp);
557 pOuterBox = pOuterBox == pRightBox ? nullptr : pRightBox;
560 }
while( pOuterBox );
567 pRet->push_back(aBoxes);
569 if( nCheckBottom > nBottom )
573 pRet->mnMergeWidth = nMax - nMin;
574 for (
auto const& newWidth : aNewWidthVector)
596 if( pCell->GetTabBox() == &rBox )
598 pCell->InvalidateSize();
613 sal_Int32 nAddWidth = 0;
615 for (
size_t j = 0; j < rBoxes.
size(); ++j)
619 tools::Long nWidth = rBoxes[j]->GetFrameFormat()->GetFrameSize().GetWidth();
621 sal_uInt16 nCurrBox = pLine->
GetBoxPos( pBox );
623 OSL_ENSURE( nCurrLine != USHRT_MAX,
"Time to say Good-Bye.." );
624 if( rInsPos[ nCurrLine ] == USHRT_MAX )
626 rInsPos[ nCurrLine ] = nCurrBox;
629 else if( ( rInsPos[ nCurrLine ] > nCurrBox ) == !bBehind )
630 rInsPos[ nCurrLine ] = nCurrBox;
656 sal_uInt16 nCnt,
bool bBehind )
663 std::vector< sal_uInt16 > aInsPos(
m_aLines.
size(), USHRT_MAX );
665 sal_uInt64 nTableWidth = 0;
667 nTableWidth +=
m_aLines[0]->GetTabBoxes()[
i]->GetFrameFormat()->GetFrameSize().GetWidth();
679 sal_uInt64 nResultingWidth = nAddWidth + nTableWidth;
680 if( !nResultingWidth )
682 nAddWidth = (nAddWidth * nTableWidth) / nResultingWidth;
684 nAddWidth = nNewBoxWidth * nCnt;
685 if( !nAddWidth || nAddWidth >= nTableWidth )
690 FndBox_ aFndBox(
nullptr,
nullptr );
695 std::vector<SwTableBoxFormat*> aInsFormat( nCnt,
nullptr );
696 size_t nLastLine = SAL_MAX_SIZE;
697 sal_Int32 nLastRowSpan = 1;
702 sal_uInt16 nInsPos = aInsPos[
i];
703 assert(nInsPos != USHRT_MAX);
708 ::InsTableBox( rDoc, pTableNd, pLine, pBoxFrameFormat, pBox, nInsPos, nCnt );
711 bool bNewSpan =
false;
712 if( nLastLine != SAL_MAX_SIZE && nDiff <= nLastRowSpan &&
713 nRowSpan != nDiff - nLastRowSpan )
716 while( nLastLine <
i )
719 sal_uInt16 nTmpPos = aInsPos[nLastLine];
722 for( sal_uInt16 j = 0; j < nCnt; ++j )
723 pTmpLine->
GetTabBoxes()[nTmpPos+j]->setRowSpan( nDiff );
736 nLastRowSpan = -nRowSpan;
738 nLastRowSpan = nRowSpan;
741 std::unique_ptr<SvxBoxItem> pNoRightBorder;
744 pNoRightBorder.reset(
new SvxBoxItem( aSelBoxItem ));
745 pNoRightBorder->
SetLine(
nullptr, SvxBoxItemLine::RIGHT );
747 for( sal_uInt16 j = 0; j < nCnt; ++j )
757 SwPaM aPaM(aInsDummyPos);
761 rDoc.
SetBoxAttr( aCursor, aHasTextChangesOnly );
771 if( pNoRightBorder && ( !bBehind || j+1 < nCnt ) )
778 if( bBehind && pNoRightBorder )
786#if OSL_DEBUG_LEVEL > 0
790 for(
size_t i = 0;
i < rTabBoxes.size(); ++
i )
792 OSL_ENSURE( nNewWidth > 0,
"Very small" );
831 return rBoxes.
size() > 1;
836 if (!pSel || pSel->isEmpty())
842 const SwSelBoxes& rFirstBoxes = pSel->maBoxes[0];
843 if (rFirstBoxes.
empty())
848 (*ppMergeBox) = pMergeBox;
858 SwPaM aChkPam( aInsPos );
860 const size_t nLineCount = pSel->maBoxes.size();
862 sal_Int32 nRowSpan =
static_cast<tools::Long>(nLineCount);
868 for(
size_t nCurrLine = 0; nCurrLine < nLineCount; ++nCurrLine )
871 const SwSelBoxes& rLineBoxes = pSel->maBoxes[nCurrLine];
872 size_t nColCount = rLineBoxes.
size();
874 for (
size_t nCurrCol = 0; nCurrCol < nColCount; ++nCurrCol)
886 if( nCurrLine + 1 == nLineCount )
891 bool bDoMerge = pBox != pMergeBox && pBox->
getRowSpan() > 0;
894 if( nCurrCol+1 == nColCount && pBox->
getRowSpan() > 0 )
904 SwPaM aPam( aInsPos );
936 nRowSpan = -nRowSpan;
947 for(
size_t nCurrLine = 0; nCurrLine < nLineCount; ++nCurrLine )
949 const SwSelBoxes& rLineBoxes = pSel->maBoxes[nCurrLine];
950 size_t nColCount = rLineBoxes.
size();
951 for (
size_t nCurrCol = 0; nCurrCol < nColCount; ++nCurrCol)
990 (*ppMergeBox)->GetFrameFormat()->SetFormatAttr( aBox );
1006 if( !pFirstLn || !pLastLn )
1008 if( rBoxes.
empty() )
1010 pFirstLn = rBoxes[0]->GetUpper();
1011 pLastLn = rBoxes.
back()->GetUpper();
1015 for( sal_uInt16 nRow = nFirstLn; nRow <= nLastLn; ++nRow )
1018 OSL_ENSURE( pLine,
"Missing table line" );
1020 bool bSuperfl =
true;
1021 for(
size_t nCol = 0; nCol < nCols; ++nCol )
1025 rBoxes.
end() == rBoxes.
find( pBox ) )
1033 for(
size_t nCol = 0; nCol < nCols; ++nCol )
1063 }
while( nLine && --nMaxStep && pNext && pBox->
getRowSpan() < 1 );
1077 nAbsSpan = -nAbsSpan;
1078 if( nAbsSpan == 1 || !nMaxStep )
1081 if( nMaxStep > --nAbsSpan )
1082 nMaxStep = o3tl::narrowing<sal_uInt16>(nAbsSpan);
1085 nMaxStep = nLine + nMaxStep;
1111 while( ++nLine < nCount && pBox && pBox->getRowSpan() != -1 )
1133 std::unique_ptr<size_t[]>
const pSplitIdx(
new size_t[nCnt]);
1136 std::unique_ptr<SwTwips[]>
const pHeights(
new SwTwips[
nCount]);
1143 nHeight += pHeights[
i ];
1147 for (
size_t i = 1;
i <= nCnt; ++
i)
1149 SwTwips nSplit = (
i * nHeight ) / nCnt;
1150 while( nSumH < nSplit && nIdx <
nCount )
1151 nSumH += pHeights[ nIdx++ ];
1152 pSplitIdx[
i - 1 ] = nIdx;
1157 for (
size_t i = 1;
i <= nCnt; ++
i)
1159 pSplitIdx[
i - 1 ] = (
i *
nCount ) / nCnt;
1163 for (
size_t i = 0;
i < nCnt; ++
i)
1165 size_t nNextIdx = pSplitIdx[
i ];
1166 aBoxes[ nIdx ]->setRowSpan( nNextIdx - nIdx );
1168 while( ++nIdx < nNextIdx )
1169 aBoxes[ nIdx ]->setRowSpan( nIdx - nNextIdx );
1178 const size_t nBoxCount = rLine.
GetTabBoxes().size();
1179 for(
size_t i = 0;
i < nBoxCount; ++
i )
1190 OSL_ENSURE( nCnt && nRowIdx <
GetTabLines().
size(),
"Wrong call of InsertSpannedRow" );
1205 const size_t nBoxCount = rLine.
GetTabBoxes().size();
1206 for( sal_uInt16
n = 0;
n < nCnt; ++
n )
1209 for(
size_t nCurrBox = 0; nCurrBox < nBoxCount; ++nCurrBox )
1211 sal_Int32 nRowSpan = rLine.
GetTabBoxes()[nCurrBox]->getRowSpan();
1213 nRowSpan = - nRowSpan;
1214 pNewLine->
GetTabBoxes()[ nCurrBox ]->setRowSpan( nRowSpan -
n );
1238 std::list< SwLineOffset > aBoxes;
1240 for (
size_t i = 0;
i < rBoxes.
size(); ++
i)
1242 const SwTableBox &rBox = rBoxes[
i ]->FindStartOfRowSpan( rTable );
1243 OSL_ENSURE( rBox.
getRowSpan() > 0,
"Didn't I say 'StartOfRowSpan' ??" );
1247 const sal_uInt16 nEnd = sal_uInt16( rBox.
getRowSpan() +
1250 if( aLnOfs.first != nEnd || aLnOfs.second != rBox.
getRowSpan() )
1252 aLnOfs.first = nEnd;
1253 aLnOfs.second = sal_uInt16( rBox.
getRowSpan() );
1254 aBoxes.insert( aBoxes.end(), aLnOfs );
1261 sal_uInt16 nSum = 1;
1262 while( !aBoxes.empty() )
1266 std::list< SwLineOffset >::iterator pCurr = aBoxes.begin();
1268 while( ++pCurr != aBoxes.end() )
1270 if( aLnOfs.first > pCurr->first )
1272 aLnOfs.first = pCurr->first;
1273 aLnOfs.second = pCurr->second;
1275 else if( aLnOfs.first == pCurr->first &&
1276 aLnOfs.second < pCurr->second )
1277 aLnOfs.second = pCurr->second;
1279 OSL_ENSURE( aLnOfs.second < nCnt,
"Clean-up failed" );
1280 aLnOfs.second = nCnt - aLnOfs.second;
1281 rArr.emplace_back( aLnOfs.first - nSum, aLnOfs.second );
1284 nSum = nSum + aLnOfs.second;
1286 pCurr = aBoxes.begin();
1287 while( pCurr != aBoxes.end() )
1289 if( pCurr->first == aLnOfs.first )
1292 pCurr = aBoxes.erase(pCurr);
1296 bool bBefore = ( pCurr->first - pCurr->second < aLnOfs.first );
1299 pCurr->first = pCurr->first + aLnOfs.second;
1303 pCurr->second = pCurr->second + aLnOfs.second;
1304 if( pCurr->second >= nCnt )
1307 pCurr = aBoxes.erase(pCurr);
1330 std::vector< SwLineOffset > aBoxes;
1332 sal_uInt16 nFirst = USHRT_MAX;
1333 sal_uInt16 nLast = 0;
1334 for (
size_t i = 0;
i < rBoxes.
size(); ++
i)
1336 const SwTableBox &rBox = rBoxes[
i ]->FindStartOfRowSpan( rTable );
1337 OSL_ENSURE( rBox.
getRowSpan() > 0,
"Didn't I say 'StartOfRowSpan' ??" );
1340 const sal_uInt16 nEnd = sal_uInt16( rBox.
getRowSpan() + nStart - 1 );
1342 if( aLnOfs.first != nStart || aLnOfs.second != nEnd )
1344 aLnOfs.first = nStart;
1345 aLnOfs.second = nEnd;
1346 aBoxes.push_back( aLnOfs );
1347 if( nStart < nFirst )
1354 if (nFirst == USHRT_MAX)
1356 assert(aBoxes.empty());
1361 std::unique_ptr<SwTwips[]> pLines(
new SwTwips[ nLast + 1 - nFirst ]);
1362 for( sal_uInt16
i = nFirst;
i <= nLast; ++
i )
1364 bool bLayoutAvailable =
false;
1365 nHeight += rTable.
GetTabLines()[
i ]->GetTableLineHeight( bLayoutAvailable );
1366 rCurr.
insert( rCurr.end(), nHeight );
1367 pLines[
i - nFirst ] = nHeight;
1369 for(
const auto& rSplit : aBoxes )
1371 SwTwips nBase = rSplit.first <= nFirst ? 0 :
1372 pLines[ rSplit.first - nFirst - 1 ];
1373 SwTwips nDiff = pLines[ rSplit.second - nFirst ] - nBase;
1374 for( sal_uInt16
i = 1;
i < nCnt; ++
i )
1376 SwTwips nSplit = nBase + (
i * nDiff ) / nCnt;
1377 rNew.insert( nSplit );
1390 sal_uInt16 nDirect = USHRT_MAX;
1391 sal_uInt16 nSpan = USHRT_MAX;
1392 for (
size_t i = 0;
i < rBoxes.
size(); ++
i)
1397 if( USHRT_MAX !=
nPos )
1401 if(
nPos > nDirect || nDirect == USHRT_MAX )
1408 sal_uInt16 nEndOfRowSpan = o3tl::narrowing<sal_uInt16>(
nPos + nRowSpan - 1);
1409 if( nEndOfRowSpan > nSpan || nSpan == USHRT_MAX )
1410 nSpan = nEndOfRowSpan;
1413 else if(
nPos < nDirect )
1417 if( nSpan && nSpan < USHRT_MAX )
1430 FndBox_ aFndBox(
nullptr,
nullptr );
1438 *
this, rBoxes, nCnt );
1441 SwSplitLines::iterator pSplit = aSplitLines.begin();
1442 for(
const auto& rCurr : aRowLines )
1444 while( pSplit != aSplitLines.end() && *pSplit < rCurr )
1457 if( pSplit != aSplitLines.end() && rCurr == *pSplit )
1472 bSameHeight =
false;
1478 SwLineOffsetArray::reverse_iterator pCurr( aLineOffs.rbegin() );
1479 while( pCurr != aLineOffs.rend() )
1486 std::set<size_t> aIndices;
1487 for (
size_t i = 0;
i < rBoxes.
size(); ++
i)
1489 OSL_ENSURE( rBoxes[
i]->getRowSpan() != 1,
"Forgot to split?" );
1490 if( rBoxes[
i]->getRowSpan() > 1 )
1491 aIndices.insert(
i );
1494 for(
const auto& rCurrBox : aIndices )
1495 lcl_UnMerge( *
this, *rBoxes[rCurrBox], nCnt, bSameHeight );
1509 sal_uInt16 nCnt,
bool bBehind )
1515 sal_uInt16 nRowIdx =
lcl_LineIndex( *
this, rBoxes, bBehind );
1516 if( nRowIdx < USHRT_MAX )
1518 FndBox_ aFndBox(
nullptr,
nullptr );
1526 InsertRow_( pDoc, aLineBoxes, nCnt, bBehind );
1527 const size_t nBoxCount = pLine->
GetTabBoxes().size();
1528 sal_uInt16 nOfs = bBehind ? 0 : 1;
1529 for( sal_uInt16
n = 0;
n < nCnt; ++
n )
1532 for(
size_t nCurrBox = 0; nCurrBox < nBoxCount; ++nCurrBox )
1534 sal_Int32 nRowSpan = pLine->
GetTabBoxes()[nCurrBox]->getRowSpan();
1537 if( nRowSpan == 1 || nRowSpan == -1 )
1539 else if( nRowSpan > 1 )
1541 nRowSpan = - nRowSpan;
1563 pNewLine->
GetTabBoxes()[ nCurrBox ]->setRowSpan( nRowSpan -
n );
1576 bRet =
InsertRow_( pDoc, rBoxes, nCnt, bBehind );
1589 for (
size_t i = 0;
i < rBoxes.
size(); ++
i)
1598 OSL_ENSURE( nLinePos < USHRT_MAX,
"Box/table mismatch" );
1605 OSL_ENSURE( pBox,
"RowSpan irritation I" );
1610 else if( nLinePos > 0 )
1616 OSL_ENSURE( pBox,
"RowSpan irritation II" );
1632 while( nRowSpan < 0 && nLinePos > 0 );
1643 SwTableLine& rLine,
bool bChkProtected,
bool bColumn )
1649 for(
size_t nCurrBox = 0; nCurrBox <
nCount; ++nCurrBox )
1652 OSL_ENSURE( pBox,
"Missing table box" );
1658 if( nRight <= nMax )
1659 bAdd = nLeft >= nMin || nRight >= nMid ||
1660 nRight - nMin > nMin - nLeft;
1662 bAdd = nLeft <= nMid || nRight - nMax < nMax - nLeft;
1668 size_t const nOldCnt = rBoxes.
size();
1670 if( bColumn && nRowSpan != 1 && nOldCnt < rBoxes.
size() )
1678 if( nRight >= nMax )
1689 const SearchType eSearch,
bool bChkProtected )
const
1691 OSL_ENSURE(
m_bNewModel,
"Don't call me for old tables" );
1696 if( !pStartNd || !pEndNd )
1722 for(
size_t nRow = 0; nFound < 2 && nRow < nLines; ++nRow )
1725 OSL_ENSURE( pLine,
"Missing table line" );
1727 for(
size_t nCol = 0; nCol < nCols; ++nCol )
1730 OSL_ENSURE( pBox,
"Missing table box" );
1733 if( !bChkProtected ||
1749 if( pEndNd == pStartNd )
1752 nLowerMin = nUpperMin;
1753 nLowerMax = nUpperMax;
1767 for(
size_t nRow = nTop; nRow <= nBottom; ++nRow )
1770 OSL_ENSURE( pLine,
"Missing table line" );
1772 for(
size_t nCurrBox = 0; nCurrBox <
nCount; ++nCurrBox )
1775 OSL_ENSURE( pBox,
"Missing table box" );
1776 if( pBox->
getRowSpan() > 0 && ( !bChkProtected ||
1783 bool bCombine = nTop == nBottom;
1788 if( nMinWidth > nTmp )
1790 nTmp =
std::min(nLowerMax, nUpperMax);
1791 nTmp -= ( nLowerMin < nUpperMin ) ? nUpperMin : nLowerMin;
1795 bCombine = ( nTmp + nTmp < nMinWidth );
1799 if( nUpperMin < nLowerMin )
1800 nLowerMin = nUpperMin;
1802 nUpperMin = nLowerMin;
1803 if( nUpperMax > nLowerMax )
1804 nLowerMax = nUpperMax;
1806 nUpperMax = nLowerMax;
1811 for(
size_t i = 0;
i < nTop; ++
i )
1818 tools::Long nMax = nUpperMax < nLowerMax ? nLowerMax : nUpperMax;
1819 for(
size_t i = nTop;
i <= nBottom; ++
i )
1821 bChkProtected, bColumn );
1825 for(
size_t i = nBottom + 1;
i < nLines; ++
i )
1827 bChkProtected,
true );
1837 OSL_ENSURE(
m_bNewModel,
"Don't call me for old tables" );
1844 const size_t nBoxCnt = rBoxes.
size();
1846 for(
size_t nRow = 0; nRow < nLineCnt && nBox < nBoxCnt; ++nRow )
1849 OSL_ENSURE( pLine,
"Missing table line" );
1851 for(
size_t nCol = 0; nCol < nCols; ++nCol )
1854 OSL_ENSURE( pBox,
"Missing table box" );
1855 if( pBox == rBoxes[nBox] )
1858 if( ++nBox >= nBoxCnt )
1863 for(
size_t nRow = 0; nRow < nLineCnt; ++nRow )
1868 for(
size_t nCurrBox = 0; nCurrBox < nCols; ++nCurrBox )
1873 if( nLeft >= rMin && nRight <= rMax )
1884 OSL_ENSURE(
m_bNewModel,
"Don't call me for old tables" );
1887 tools::Long nMid = nMin ? ( nMin + nMax ) / 2 : 0;
1892 for(
size_t nRow = 0; nRow < nLineCnt; ++nRow )
1897 for(
size_t nCurrBox = 0; nCurrBox < nCols; ++nCurrBox )
1909 if( nRight <= nMax )
1910 nNewWidth = nMid - nLeft;
1912 else if( nRight > nMax )
1913 nNewWidth = nRight - nMid;
1916 if( nNewWidth >= 0 )
1933 for (
size_t i = 0;
i < rBoxes.
size(); ++
i)
1952 OSL_ENSURE(
IsNewModel(),
"Don't call me for old tables" );
1954 OSL_ENSURE( nLineIdx <
GetTabLines().
size(),
"Start line out of range" );
1955 bool bChange =
true;
1962 const size_t nCols = rpLine->
GetTabBoxes().size();
1963 for(
size_t nCol = 0; !bChange && nCol < nCols; ++nCol )
1988 const size_t nCols = rpLine->
GetTabBoxes().size();
1989 for(
size_t nCol = 0; !bChange && nCol < nCols; ++nCol )
1998 if( nLineIdx >= nMaxLine )
2013 : mnSplitLine( nSplitLn )
2015 bool bDontSave =
true;
2016 const size_t nColCount = rBoxes.size();
2017 OSL_ENSURE( nColCount,
"Empty Table Line" );
2019 for(
size_t nCurrCol = 0; nCurrCol < nColCount; ++nCurrCol )
2022 OSL_ENSURE( pBox,
"Missing Table Box" );
2043 OSL_ENSURE( rSave.
mnSplitLine < nLineCount,
"Restore behind last line?" );
2048 const size_t nColCount = pLine->
GetTabBoxes().size();
2049 OSL_ENSURE( nColCount,
"Empty Table Line" );
2050 OSL_ENSURE( nColCount == rSave.
mnRowSpans.size(),
"Wrong row span store" );
2054 for(
size_t nCurrCol = 0; nCurrCol < nColCount; ++nCurrCol )
2057 OSL_ENSURE( pBox,
"Missing Table Box" );
2061 OSL_ENSURE( -nRowSp == rSave.
mnRowSpans[ nCurrCol ],
"Pardon me?!" );
2062 OSL_ENSURE( rSave.
mnRowSpans[ nCurrCol ] < 0,
"Pardon me?!" );
2086 }
while( nLine && pNext );
2097 if( pRet->mnRowSpans.empty() )
2108 const size_t nColCount = pLine->
GetTabBoxes().size();
2109 OSL_ENSURE( nColCount,
"Empty Table Line" );
2110 for(
size_t nCurrCol = 0; nCurrCol < nColCount; ++nCurrCol )
2113 OSL_ENSURE( pBox,
"Missing Table Box" );
2120 o3tl::narrowing<sal_uInt16>(nLastLine),
false );
2220 pSourceBox, j+k, 1);
2255 sal_uInt16
const nInsPos(j < nBox ? j : j + pSubLine->GetTabBoxes().
size() - 1);
2258 pSourceBox, nInsPos, 1);
2265 sal_Int32 newSourceRowSpan(pSourceBox->
getRowSpan());
2266 sal_Int32 newBoxRowSpan;
2267 if (newSourceRowSpan < 0)
2270 newBoxRowSpan = newSourceRowSpan +
i;
2275 newBoxRowSpan = -(newSourceRowSpan - sal::static_int_cast<tools::Long>(
i));
2277 pNewLine->
GetTabBoxes()[nInsPos]->setRowSpan(newBoxRowSpan);
2290 for (
size_t j = pSubLine->
GetTabBoxes().size(); 0 < j; --j)
2293 DeleteBox_(*
this, pBox,
nullptr,
false,
false,
nullptr);
2306 bool haveSubtable(
false);
2307 for (
SwTableBox const*
const pBox : pLine->GetTabBoxes())
2313 if (!pBox->GetTabLines().empty())
2319 haveSubtable =
true;
2320 bool haveNonFixedInnerLine(
false);
2321 for (
SwTableLine const*
const pInnerLine : pBox->GetTabLines())
2324 SwFrameFormat const& rRowFormat(*pInnerLine->GetFrameFormat());
2327 if (pBrush->GetGraphicObject() !=
nullptr)
2332 if (1 < pInnerLine->GetTabBoxes().size())
2341 haveNonFixedInnerLine =
true;
2346 haveNonFixedInnerLine =
true;
2348 for (
SwTableBox const*
const pInnerBox : pInnerLine->GetTabBoxes())
2350 if (!pInnerBox->GetTabLines().empty())
2356 if (haveNonFixedInnerLine)
2376 std::vector<SwFormatField*> vFields;
2378 if (!vFields.empty())
2397 temp.
Assign(*pStartNode->EndOfSectionNode(), +1);
2404 FndBox_ all(
nullptr,
nullptr);
2413 if (!rInnerLines.
empty())
2456 std::list< RowSpanCheck > aRowSpanCells;
2457 std::list< RowSpanCheck >::iterator aIter = aRowSpanCells.end();
2460 for(
size_t nCurrLine = 0; nCurrLine < nLineCount; ++nCurrLine )
2464 SAL_WARN_IF( !pLine,
"sw.core",
"Missing Table Line" );
2465 const size_t nColCount = pLine->
GetTabBoxes().size();
2466 SAL_WARN_IF( !nColCount,
"sw.core",
"Empty Table Line" );
2467 for(
size_t nCurrCol = 0; nCurrCol < nColCount; ++nCurrCol )
2472 SAL_WARN_IF(!
index.GetNode().IsStartNode(),
"sw.core",
"No box start node");
2480 "sw.core",
"Missing master box");
2481 if (aIter != aRowSpanCells.end())
2483 SAL_WARN_IF( aIter->nLeft != nWidth || aIter->nRight != nNewWidth,
2484 "sw.core",
"Wrong position/size of overlapped table box");
2485 --(aIter->nRowSpan);
2486 SAL_WARN_IF( aIter->nRowSpan != -nRowSp,
"sw.core",
2487 "Wrong row span value" );
2490 aIter = aRowSpanCells.erase(aIter);
2496 else if( nRowSp != 1 )
2498 SAL_WARN_IF( !nRowSp,
"sw.core",
"Zero row span?!" );
2499 RowSpanCheck aEntry;
2500 aEntry.nLeft = nWidth;
2501 aEntry.nRight = nNewWidth;
2502 aEntry.nRowSpan = nRowSp;
2503 aRowSpanCells.insert( aIter, aEntry );
2510 "Different Line Widths: first: " <<
nLineWidth
2511 <<
" current [" << nCurrLine <<
"]: " << nWidth);
2513 "Line width differs from table width: " <<
nTabSize
2514 <<
" current [" << nCurrLine <<
"]: " << nWidth);
2515 SAL_WARN_IF( nWidth < 0 || nWidth > USHRT_MAX,
"sw.core",
2516 "Width out of range [" << nCurrLine <<
"]: " << nWidth);
2517 SAL_WARN_IF( aIter != aRowSpanCells.end(),
"sw.core",
2518 "Missing overlapped box" );
2519 aIter = aRowSpanCells.begin();
2521 bool bEmpty = aRowSpanCells.empty();
2522 SAL_WARN_IF( !bEmpty,
"sw.core",
"Open row span detected" );
void SetTableLines(const SwSelBoxes &rBoxes, const SwTable &rTable)
void MakeFrames(SwTable &rTable)
void DelFrames(SwTable &rTable)
virtual bool AppendTextNode(SwPosition &rPos)=0
virtual bool MoveNodeRange(SwNodeRange &, SwNode &, SwMoveFlags)=0
virtual bool InsertString(const SwPaM &rRg, const OUString &, const SwInsertFlags nInsertMode=SwInsertFlags::EMPTYEXPAND)=0
Insert string into existing text node at position rRg.Point().
virtual SwFieldType * GetFieldType(SwFieldIds nResId, const OUString &rName, bool bDbFieldMatching) const =0
virtual const SwViewShell * GetCurrentViewShell() const =0
Returns the layout set at the document.
virtual void assureSortedMarkContainers() const =0
static bool IsRedlineOn(const RedlineFlags eM)
virtual const SwRedlineTable & GetRedlineTable() const =0
sal_uInt32 GetItemCount2(sal_uInt16 nWhich) const
const editeng::SvxBorderLine * GetTop() const
const editeng::SvxBorderLine * GetRight() const
void SetLine(const editeng::SvxBorderLine *pNew, SvxBoxItemLine nLine)
const editeng::SvxBorderLine * GetLeft() const
const editeng::SvxBorderLine * GetBottom() const
bool IsContentProtected() const
tools::Long GetHeight() const
tools::Long GetWidth() const
void SetHeight(tools::Long n)
void SetWidth(tools::Long n)
SwBoxSelection is a small helperclass (structure) to handle selections of cells (boxes) between table...
std::vector< SwSelBoxes > maBoxes
void push_back(const SwSelBoxes &rNew)
SwCellFrame is one table cell in the document layout.
virtual sal_Int32 Len() const
IDocumentContentOperations const & getIDocumentContentOperations() const
IDocumentUndoRedo & GetIDocumentUndoRedo()
IDocumentFieldsAccess const & getIDocumentFieldsAccess() const
IDocumentRedlineAccess const & getIDocumentRedlineAccess() const
void DelNumRules(const SwPaM &, SwRootFrame const *pLayout=nullptr)
IDocumentLayoutAccess const & getIDocumentLayoutAccess() const
SwFootnoteIdxs & GetFootnoteIdxs()
IDocumentMarkAccess * getIDocumentMarkAccess()
const SwTextFormatColl * GetDfltTextFormatColl() const
const SwAttrPool & GetAttrPool() const
void SetBoxAttr(const SwCursor &rCursor, const SfxPoolItem &rNew)
Instances of SwFields and those derived from it occur 0 to n times.
void GatherFields(std::vector< SwFormatField * > &rvFormatFields, bool bCollectOnlyInDocNodes=true) const
Base class of the Writer layout elements.
Marks a node in the document model.
SwNodeIndex & Assign(SwNodes const &rNds, SwNodeOffset nIdx)
Base class of the Writer document model elements.
SwStartNode * GetStartNode()
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
const SwStartNode * FindTableBoxStartNode() const
const SwStartNode * StartOfSectionNode() const
SwOLENode * GetOLENode()
Inline methods from Node.hxx.
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.
SwNode & GetEndOfAutotext() const
Section for all Flys/Header/Footers.
bool MoveNodes(const SwNodeRange &, SwNodes &rNodes, SwNode &rPos, bool bNewFrames=true)
move the node pointer
void Delete(const SwNodeIndex &rPos, SwNodeOffset nNodes=SwNodeOffset(1))
const OUString & GetChartTableName() const
PaM is Point and Mark: a selection of the document model.
const SwPosition * GetMark() const
SwNode & GetPointNode() const
SwContentNode * GetPointContentNode() const
const SwPosition * End() const
const SwPosition * GetPoint() const
const SwPosition * Start() const
Starts a section of nodes in the document model.
SwTableBox is one table cell in the document model.
sal_Int32 getRowSpan() const
SwTableBox & FindStartOfRowSpan(const SwTable &, sal_uInt16 nMaxStep=USHRT_MAX)
SwTableBox::FindStartOfRowSpan(..) returns the "master" cell, the cell which overlaps the given cell,...
SwNodeOffset GetSttIdx() const
void setRowSpan(sal_Int32 nNewRowSpan)
SwFrameFormat * GetFrameFormat()
SwTableLines & GetTabLines()
const SwStartNode * GetSttNd() const
void ChgFrameFormat(SwTableBoxFormat *pNewFormat, bool bNeedToReregister=true)
SwTableBox & FindEndOfRowSpan(const SwTable &, sal_uInt16 nMaxStep)
SwTableBox::FindEndOfRowSpan(..) returns the last overlapped cell if there is any.
SwFrameFormat * ClaimFrameFormat()
SwTableLine is one table row in the document model.
SwFrameFormat * GetFrameFormat()
SwFrameFormat * ClaimFrameFormat()
SwTableBoxes & GetTabBoxes()
sal_uInt16 GetBoxPos(const SwTableBox *pBox) const
iterator insert(iterator aIt, SwTableLine *pLine)
sal_uInt16 GetPos(const SwTableLine *pBox) const
SwTable is one table in the document model, containing rows (which contain cells).
SwTableNode * GetTableNode() const
void PrepareDelBoxes(const SwSelBoxes &rBoxes)
SwTable::PrepareDelBoxes(..) adjusts the row span attributes for an upcoming deletion of table cells ...
void InsertSpannedRow(SwDoc &rDoc, sal_uInt16 nIdx, sal_uInt16 nCnt)
SwTable::InsertSpannedRow(..) inserts "superfluous" rows, i.e.
void CleanUpBottomRowSpan(sal_uInt16 nDelLines)
void CheckRowSpan(SwTableLine *&rpLine, bool bUp) const
SwTable::CheckRowSpan(..) looks for the next line without an overlapping to the previous line.
void CreateSelection(const SwPaM &rPam, SwSelBoxes &rBoxes, const SearchType eSearchType, bool bProtect) const
void SwTable::CreateSelection(..) fills the selection structure with table cells for a given SwPaM,...
bool CanConvertSubtables() const
void AdjustWidths(const tools::Long nOld, const tools::Long nNew)
SwTableLines & GetTabLines()
void FindSuperfluousRows_(SwSelBoxes &rBoxes, SwTableLine *, SwTableLine *)
SwTable::FindSuperfluousRows_(..) is looking for superfluous rows, i.e.
SwTableFormat * GetFrameFormat()
bool DeleteSel(SwDoc *, const SwSelBoxes &rBoxes, const SwSelBoxes *pMerged, SwUndo *pUndo, const bool bDelMakeFrames, const bool bCorrBorder)
bool NewSplitRow(SwDoc &, const SwSelBoxes &, sal_uInt16, bool)
SwTable::NewSplitRow(..) splits all selected boxes horizontally.
std::unique_ptr< SwSaveRowSpan > CleanUpTopRowSpan(sal_uInt16 nSplitLine)
bool InsertRow(SwDoc *, const SwSelBoxes &rBoxes, sal_uInt16 nCnt, bool bBehind)
SwTable::InsertRow(..) inserts one or more rows before or behind the selected boxes.
bool NewInsertCol(SwDoc &, const SwSelBoxes &rBoxes, sal_uInt16 nCnt, bool)
SwTable::NewInsertCol(..) insert new column(s) into a table.
void ExpandSelection(SwSelBoxes &rBoxes) const
SwTable::ExpandSelection(..) adds all boxes to the box selections which are overlapped by it.
void RestoreRowSpan(const SwSaveRowSpan &)
bool PrepareMerge(const SwPaM &rPam, SwSelBoxes &rBoxes, SwSelBoxes &rMerged, SwTableBox **ppMergeBox, SwUndoTableMerge *pUndo)
SwTable::PrepareMerge(..) some preparation for the coming Merge(..)
std::optional< SwBoxSelection > CollectBoxSelection(const SwPaM &rPam) const
CollectBoxSelection(..) create a rectangulare selection based on the given SwPaM and prepares the sel...
void ConvertSubtableBox(sal_uInt16 const nRow, sal_uInt16 const nBox)
This is kind of similar to InsertSpannedRow()/InsertRow() but that one would recursively copy subtabl...
void PrepareDeleteCol(tools::Long nMin, tools::Long nMax)
SwTable::PrepareDeleteCol(..) adjusts the widths of the neighbour cells of a cell selection for an up...
void CheckConsistency() const
bool InsertRow_(SwDoc *, const SwSelBoxes &, sal_uInt16 nCnt, bool bBehind)
void ExpandColumnSelection(SwSelBoxes &rBoxes, tools::Long &rMin, tools::Long &rMax) const
void SwTable::ExpandColumnSelection(..) adds cell to the give selection to assure that at least one c...
bool NewMerge(SwDoc *, const SwSelBoxes &, const SwSelBoxes &rMerged, SwUndoTableMerge *)
NewMerge(..) removes the superfluous cells after cell merge.
SwTextNode is a paragraph in the document model.
void SetCountedInList(bool bCounted)
SwNumRule * GetNumRule(bool bInParent=true) const
Returns numbering rule of this text node.
void SetSelBoxes(const SwSelBoxes &rBoxes)
void MoveBoxContent(SwDoc &rDoc, SwNodeRange &rRg, SwNode &rPos)
void AddNewBox(SwNodeOffset nSttNdIdx)
const Value & back() const
const_iterator find(const Value &x) const
const_iterator end() const
std::pair< const_iterator, bool > insert(Value &&x)
virtual OUString GetName() const override
@ Fixed
Frame cannot be moved in Var-direction.
@ Variable
Frame is variable in Var-direction.
@ Minimum
Value in Var-direction gives minimum (can be exceeded but not be less).
constexpr TypedWhichId< SwFormatFrameSize > RES_FRM_SIZE(89)
constexpr TypedWhichId< SvxBrushItem > RES_BACKGROUND(111)
constexpr TypedWhichId< SwTableBoxFormula > RES_BOXATR_FORMULA(157)
#define CH_TXT_TRACKED_DUMMY_CHAR
constexpr TypedWhichId< SvxPrintItem > RES_PRINT(104)
#define SAL_WARN_IF(condition, area, stream)
#define SAL_WARN(area, stream)
enumrange< T >::Iterator begin(enumrange< T >)
o3tl::strong_int< sal_Int32, struct Tag_SwNodeOffset > SwNodeOffset
SwNodeOffset min(const SwNodeOffset &a, const SwNodeOffset &b)
SwNodeOffset abs(const SwNodeOffset &a)
Marks a position in the document model.
void Adjust(SwNodeOffset nDelta)
Adjust node position, and resets content position to zero.
void Assign(const SwNode &rNd, SwNodeOffset nDelta, sal_Int32 nContentOffset=0)
These all set both nNode and nContent.
void SetContent(sal_Int32 nContentIndex)
Set content index, only valid to call this if the position points to a SwContentNode subclass.
This structure is needed by Undo to restore row span attributes when a table has been split into two ...
SwSaveRowSpan(SwTableBoxes &rBoxes, sal_uInt16 nSplitLn)
std::vector< tools::Long > mnRowSpans
static void lcl_UnMerge(const SwTable &rTable, SwTableBox &rBox, size_t nCnt, bool bSameHeight)
lcl_UnMerge(..) manipulates the row span attribute of a given master cell and its overlapped cells to...
static sal_uInt16 lcl_LineIndex(const SwTable &rTable, const SwSelBoxes &rBoxes, bool bBehind)
lcl_LineIndex(..) delivers the line index of the line behind or above the box selection.
static void lcl_InvalidateCellFrame(const SwTableBox &rBox)
lcl_InvalidateCellFrame(..) invalidates all layout representations of a given cell to initiate a refo...
static sal_uInt16 lcl_CalculateSplitLineHeights(SwSplitLines &rCurr, SwSplitLines &rNew, const SwTable &rTable, const SwSelBoxes &rBoxes, sal_uInt16 nCnt)
lcl_CalculateSplitLineHeights(..) delivers all y-positions where table rows have to be split to fulfi...
static void lcl_SophisticatedFillLineIndices(SwLineOffsetArray &rArr, const SwTable &rTable, const SwSelBoxes &rBoxes, sal_uInt16 nCnt)
static SwTableBox * lcl_LeftBorder2Box(tools::Long nLeft, const SwTableLine *pLine)
lcl_LeftBorder2Box delivers the box to a given left border
static tools::Long lcl_InsertPosition(SwTable &rTable, std::vector< sal_uInt16 > &rInsPos, const SwSelBoxes &rBoxes, bool bBehind)
lcl_InsertPosition(..) evaluates the insert positions in every table line, when a selection of cells ...
static void lcl_CheckMinMax(tools::Long &rMin, tools::Long &rMax, const SwTableLine &rLine, size_t nCheck, bool bSet)
lcl_CheckMinMax helps evaluating (horizontal) min/max of boxes
static void lcl_ChangeRowSpan(const SwTable &rTable, const tools::Long nDiff, sal_uInt16 nRowIdx, const bool bSingle)
lcl_ChangeRowSpan corrects row span after insertion/deletion of rows
static void lcl_SearchSelBox(const SwTable &rTable, SwSelBoxes &rBoxes, tools::Long nMin, tools::Long nMax, SwTableLine &rLine, bool bChkProtected, bool bColumn)
lcl_SearchSelBox(..) adds cells of a given table row to the selection structure if it overlaps with t...
std::set< SwTwips > SwSplitLines
static void lcl_getAllMergedBoxes(const SwTable &rTable, SwSelBoxes &rBoxes, SwTableBox &rBox)
lcl_getAllMergedBoxes(..) collects all overlapped boxes to a given (master) box
static tools::Long lcl_Box2LeftBorder(const SwTableBox &rBox)
lcl_Box2LeftBorder(..) delivers the left (logical) border of a table box
std::vector< SwLineOffset > SwLineOffsetArray
static void lcl_FillSelBoxes(SwSelBoxes &rBoxes, SwTableLine &rLine)
lcl_FillSelBoxes(..) puts all boxes of a given line into the selection structure
std::pair< sal_uInt16, sal_uInt16 > SwLineOffset
std::vector< SwTableBox * > SwTableBoxes
void DeleteBox_(SwTable &rTable, SwTableBox *pBox, SwUndo *pUndo, bool bCalcNewSize, const bool bCorrBorder, SwShareBoxFormats *pShareFormats)
void InsTableBox(SwDoc &rDoc, SwTableNode *pTableNd, SwTableLine *pLine, SwTableBoxFormat *pBoxFrameFormat, SwTableBox *pBox, sal_uInt16 nInsPos, sal_uInt16 nCnt=1)
void GetMergeSel(const SwPaM &rPam, SwSelBoxes &rBoxes, SwTableBox **ppMergeBox, SwUndoTableMerge *pUndo)
bool IsEmptyBox(const SwTableBox &rBox, SwPaM &rPam)