47#include <osl/diagnose.h>
50#define CHECK_TABLE(t) (t).CheckConsistency();
95 DeleteSel( pDoc, rBoxes, &rMerged,
nullptr,
true,
true );
129 OSL_FAIL(
"Box out of table line" );
135 for(
size_t nCurrBox = 0; nCurrBox < nCheck; ++nCurrBox )
138 OSL_ENSURE( pBox,
"Missing table box" );
143 if( bSet || nNew > rMax )
146 if( bSet || nNew < rMin )
169 for(
size_t nCurrBox = 0; nCurrBox <
nCount; ++nCurrBox )
172 OSL_ENSURE( pBox,
"Missing table box" );
177 OSL_FAIL(
"Box not found in own upper?" );
203 for(
size_t nCurrBox = 0; nCurrBox <
nCount; ++nCurrBox )
206 OSL_ENSURE( pBox,
"Missing table box" );
209 if( nCurrLeft == nLeft )
214 if(
std::abs( nCurrLeft - nLeft ) <= ( nLeft / 1000 ))
216 if( nCurrLeft >= nLeft )
218 SAL_WARN(
"sw.core",
"Possibly wrong box found" );
224 OSL_FAIL(
"Didn't find wished box" );
258 sal_uInt16 nRowIdx,
const bool bSingle )
262 OSL_ENSURE( !bSingle || nDiff > 0,
"Don't set bSingle when deleting lines!" );
276 const size_t nBoxCount = pLine->
GetTabBoxes().size();
277 for(
size_t nCurrBox = 0; nCurrBox < nBoxCount; ++nCurrBox )
279 sal_Int32 nRowSpan = pLine->
GetTabBoxes()[nCurrBox]->getRowSpan();
280 sal_Int32 nAbsSpan = nRowSpan > 0 ? nRowSpan : -nRowSpan;
283 if( nAbsSpan > nDistance )
300 if( nRowSpan - nDistance > -nDiff )
303 nRowSpan = nDistance + 1;
307 if( nRowSpan + nDistance < nDiff )
310 nRowSpan = -nDistance - 1;
314 pLine->
GetTabBoxes()[ nCurrBox ]->setRowSpan( nRowSpan );
331 OSL_ENSURE(
m_bNewModel,
"Don't call me for old tables" );
336 if( !pStartNd || !pEndNd || pStartNd == pEndNd )
344 for(
size_t nRow = 0; nFound < 2 && nRow < nLines; ++nRow )
347 OSL_ENSURE( pLine,
"Missing table line" );
349 for(
size_t nCol = 0; nCol < nCols; ++nCol )
352 OSL_ENSURE( pBox,
"Missing table box" );
363 else if( pBox->
GetSttNd() == pStartNd )
377 std::optional<SwBoxSelection> pRet(std::in_place);
378 std::vector< std::pair< SwTableBox*, tools::Long > > aNewWidthVector;
379 size_t nCheckBottom = nBottom;
384 for(
size_t nRow = nTop; nRow <= nBottom && bOkay && nRow < nLines; ++nRow )
387 OSL_ENSURE( pLine,
"Missing table line" );
391 for(
size_t nCurrBox = 0; nCurrBox <
nCount; ++nCurrBox )
394 OSL_ENSURE( pBox,
"Missing table box" );
400 if( nRight == nMin && nLeftSpanCnt )
411 if( nRight >= nMid || nRight + nLeft >= nMin + nMin )
418 nDiff = nMin - nLeft;
424 nDiff2 = nRight - nMax;
429 else if( nRightSpanCnt && nRight == nMax )
435 else if( nCurrBox+1 <
nCount )
439 nDiff = nMin - nRight;
444 else if( nRight <= nMax )
447 if( nRow == nTop && nRowSpan < 0 )
452 if( nRowSpan > 1 && nRow + nRowSpan - 1 > nBottom )
453 nBottom = nRow + nRowSpan - 1;
454 if( nRowSpan < -1 && nRow - nRowSpan - 1 > nBottom )
455 nBottom = nRow - nRowSpan - 1;
456 if( nRightSpanCnt && nRight == nMax )
459 else if( nLeft < nMax )
461 if( nLeft <= nMid || nRight + nLeft <= nMax )
468 nDiff = nRight - nMax;
477 nDiff = nLeft - nMax;
486 if( nRow == nBottom )
490 nBottom += nTmpSpan - 1;
491 else if( nTmpSpan < -1 )
492 nBottom -= nTmpSpan + 1;
502 size_t nCheck = nRow;
512 if( pOuterBox == pLeftBox )
514 if( !nLeftSpanCnt || nMin - nDiff != nLeftSpan )
519 if( !nRightSpanCnt || nMax + nDiff != nRightSpan )
525 if( pOuterBox == pLeftBox )
529 nLeftSpan = nMin - nDiff;
530 nLeftSpanCnt = nOutSpan;
536 nRightSpan = nMax + nDiff;
537 nRightSpanCnt = nOutSpan;
540 nCheck += nOutSpan - 1;
541 if( nCheck > nCheckBottom )
542 nCheckBottom = nCheck;
544 else if( ( nLeftSpanCnt && pLeftBox == pOuterBox ) ||
545 ( nRightSpanCnt && pRightBox == pOuterBox ) )
547 std::pair< SwTableBox*, long > aTmp;
548 aTmp.first = pInnerBox;
549 aTmp.second = -nDiff;
550 aNewWidthVector.push_back(aTmp);
551 aTmp.first = pOuterBox;
553 aNewWidthVector.push_back(aTmp);
555 pOuterBox = pOuterBox == pRightBox ? nullptr : pRightBox;
558 }
while( pOuterBox );
565 pRet->push_back(aBoxes);
567 if( nCheckBottom > nBottom )
571 pRet->mnMergeWidth = nMax - nMin;
572 for (
auto const& newWidth : aNewWidthVector)
594 if( pCell->GetTabBox() == &rBox )
596 pCell->InvalidateSize();
611 sal_Int32 nAddWidth = 0;
613 for (
size_t j = 0; j < rBoxes.
size(); ++j)
617 tools::Long nWidth = rBoxes[j]->GetFrameFormat()->GetFrameSize().GetWidth();
619 sal_uInt16 nCurrBox = pLine->
GetBoxPos( pBox );
621 OSL_ENSURE( nCurrLine != USHRT_MAX,
"Time to say Good-Bye.." );
622 if( rInsPos[ nCurrLine ] == USHRT_MAX )
624 rInsPos[ nCurrLine ] = nCurrBox;
627 else if( ( rInsPos[ nCurrLine ] > nCurrBox ) == !bBehind )
628 rInsPos[ nCurrLine ] = nCurrBox;
654 sal_uInt16 nCnt,
bool bBehind )
661 std::vector< sal_uInt16 > aInsPos(
m_aLines.
size(), USHRT_MAX );
663 sal_uInt64 nTableWidth = 0;
665 nTableWidth +=
m_aLines[0]->GetTabBoxes()[
i]->GetFrameFormat()->GetFrameSize().GetWidth();
677 sal_uInt64 nResultingWidth = nAddWidth + nTableWidth;
678 if( !nResultingWidth )
680 nAddWidth = (nAddWidth * nTableWidth) / nResultingWidth;
682 nAddWidth = nNewBoxWidth * nCnt;
683 if( !nAddWidth || nAddWidth >= nTableWidth )
688 FndBox_ aFndBox(
nullptr,
nullptr );
693 std::vector<SwTableBoxFormat*> aInsFormat( nCnt,
nullptr );
694 size_t nLastLine = SAL_MAX_SIZE;
695 sal_Int32 nLastRowSpan = 1;
700 sal_uInt16 nInsPos = aInsPos[
i];
701 assert(nInsPos != USHRT_MAX);
706 ::InsTableBox( rDoc, pTableNd, pLine, pBoxFrameFormat, pBox, nInsPos, nCnt );
709 bool bNewSpan =
false;
710 if( nLastLine != SAL_MAX_SIZE && nDiff <= nLastRowSpan &&
711 nRowSpan != nDiff - nLastRowSpan )
714 while( nLastLine <
i )
717 sal_uInt16 nTmpPos = aInsPos[nLastLine];
720 for( sal_uInt16 j = 0; j < nCnt; ++j )
721 pTmpLine->
GetTabBoxes()[nTmpPos+j]->setRowSpan( nDiff );
734 nLastRowSpan = -nRowSpan;
736 nLastRowSpan = nRowSpan;
739 std::unique_ptr<SvxBoxItem> pNoRightBorder;
742 pNoRightBorder.reset(
new SvxBoxItem( aSelBoxItem ));
743 pNoRightBorder->
SetLine(
nullptr, SvxBoxItemLine::RIGHT );
745 for( sal_uInt16 j = 0; j < nCnt; ++j )
755 if( pNoRightBorder && ( !bBehind || j+1 < nCnt ) )
762 if( bBehind && pNoRightBorder )
770#if OSL_DEBUG_LEVEL > 0
774 for(
size_t i = 0;
i < rTabBoxes.size(); ++
i )
776 OSL_ENSURE( nNewWidth > 0,
"Very small" );
815 return rBoxes.
size() > 1;
820 if (!pSel || pSel->isEmpty())
826 const SwSelBoxes& rFirstBoxes = pSel->maBoxes[0];
827 if (rFirstBoxes.
empty())
832 (*ppMergeBox) = pMergeBox;
842 SwPaM aChkPam( aInsPos );
844 const size_t nLineCount = pSel->maBoxes.size();
846 sal_Int32 nRowSpan =
static_cast<tools::Long>(nLineCount);
852 for(
size_t nCurrLine = 0; nCurrLine < nLineCount; ++nCurrLine )
855 const SwSelBoxes& rLineBoxes = pSel->maBoxes[nCurrLine];
856 size_t nColCount = rLineBoxes.
size();
858 for (
size_t nCurrCol = 0; nCurrCol < nColCount; ++nCurrCol)
870 if( nCurrLine + 1 == nLineCount )
875 bool bDoMerge = pBox != pMergeBox && pBox->
getRowSpan() > 0;
878 if( nCurrCol+1 == nColCount && pBox->
getRowSpan() > 0 )
888 SwPaM aPam( aInsPos );
920 nRowSpan = -nRowSpan;
931 for(
size_t nCurrLine = 0; nCurrLine < nLineCount; ++nCurrLine )
933 const SwSelBoxes& rLineBoxes = pSel->maBoxes[nCurrLine];
934 size_t nColCount = rLineBoxes.
size();
935 for (
size_t nCurrCol = 0; nCurrCol < nColCount; ++nCurrCol)
974 (*ppMergeBox)->GetFrameFormat()->SetFormatAttr( aBox );
990 if( !pFirstLn || !pLastLn )
994 pFirstLn = rBoxes[0]->GetUpper();
995 pLastLn = rBoxes.
back()->GetUpper();
999 for( sal_uInt16 nRow = nFirstLn; nRow <= nLastLn; ++nRow )
1002 OSL_ENSURE( pLine,
"Missing table line" );
1004 bool bSuperfl =
true;
1005 for(
size_t nCol = 0; nCol < nCols; ++nCol )
1009 rBoxes.
end() == rBoxes.
find( pBox ) )
1017 for(
size_t nCol = 0; nCol < nCols; ++nCol )
1047 }
while( nLine && --nMaxStep && pNext && pBox->
getRowSpan() < 1 );
1061 nAbsSpan = -nAbsSpan;
1062 if( nAbsSpan == 1 || !nMaxStep )
1065 if( nMaxStep > --nAbsSpan )
1066 nMaxStep = o3tl::narrowing<sal_uInt16>(nAbsSpan);
1069 nMaxStep = nLine + nMaxStep;
1095 while( ++nLine < nCount && pBox && pBox->getRowSpan() != -1 )
1117 std::unique_ptr<size_t[]>
const pSplitIdx(
new size_t[nCnt]);
1120 std::unique_ptr<SwTwips[]>
const pHeights(
new SwTwips[
nCount]);
1127 nHeight += pHeights[
i ];
1131 for (
size_t i = 1;
i <= nCnt; ++
i)
1133 SwTwips nSplit = (
i * nHeight ) / nCnt;
1134 while( nSumH < nSplit && nIdx <
nCount )
1135 nSumH += pHeights[ nIdx++ ];
1136 pSplitIdx[
i - 1 ] = nIdx;
1141 for (
size_t i = 1;
i <= nCnt; ++
i)
1143 pSplitIdx[
i - 1 ] = (
i *
nCount ) / nCnt;
1147 for (
size_t i = 0;
i < nCnt; ++
i)
1149 size_t nNextIdx = pSplitIdx[
i ];
1150 aBoxes[ nIdx ]->setRowSpan( nNextIdx - nIdx );
1152 while( ++nIdx < nNextIdx )
1153 aBoxes[ nIdx ]->setRowSpan( nIdx - nNextIdx );
1162 const size_t nBoxCount = rLine.
GetTabBoxes().size();
1163 for(
size_t i = 0;
i < nBoxCount; ++
i )
1174 OSL_ENSURE( nCnt && nRowIdx <
GetTabLines().
size(),
"Wrong call of InsertSpannedRow" );
1189 const size_t nBoxCount = rLine.
GetTabBoxes().size();
1190 for( sal_uInt16
n = 0;
n < nCnt; ++
n )
1193 for(
size_t nCurrBox = 0; nCurrBox < nBoxCount; ++nCurrBox )
1195 sal_Int32 nRowSpan = rLine.
GetTabBoxes()[nCurrBox]->getRowSpan();
1197 nRowSpan = - nRowSpan;
1198 pNewLine->
GetTabBoxes()[ nCurrBox ]->setRowSpan( nRowSpan -
n );
1222 std::list< SwLineOffset > aBoxes;
1224 for (
size_t i = 0;
i < rBoxes.
size(); ++
i)
1226 const SwTableBox &rBox = rBoxes[
i ]->FindStartOfRowSpan( rTable );
1227 OSL_ENSURE( rBox.
getRowSpan() > 0,
"Didn't I say 'StartOfRowSpan' ??" );
1231 const sal_uInt16 nEnd = sal_uInt16( rBox.
getRowSpan() +
1234 if( aLnOfs.first != nEnd || aLnOfs.second != rBox.
getRowSpan() )
1236 aLnOfs.first = nEnd;
1237 aLnOfs.second = sal_uInt16( rBox.
getRowSpan() );
1238 aBoxes.insert( aBoxes.end(), aLnOfs );
1245 sal_uInt16 nSum = 1;
1246 while( !aBoxes.empty() )
1250 std::list< SwLineOffset >::iterator pCurr = aBoxes.begin();
1252 while( ++pCurr != aBoxes.end() )
1254 if( aLnOfs.first > pCurr->first )
1256 aLnOfs.first = pCurr->first;
1257 aLnOfs.second = pCurr->second;
1259 else if( aLnOfs.first == pCurr->first &&
1260 aLnOfs.second < pCurr->second )
1261 aLnOfs.second = pCurr->second;
1263 OSL_ENSURE( aLnOfs.second < nCnt,
"Clean-up failed" );
1264 aLnOfs.second = nCnt - aLnOfs.second;
1265 rArr.emplace_back( aLnOfs.first - nSum, aLnOfs.second );
1268 nSum = nSum + aLnOfs.second;
1270 pCurr = aBoxes.begin();
1271 while( pCurr != aBoxes.end() )
1273 if( pCurr->first == aLnOfs.first )
1276 pCurr = aBoxes.erase(pCurr);
1280 bool bBefore = ( pCurr->first - pCurr->second < aLnOfs.first );
1283 pCurr->first = pCurr->first + aLnOfs.second;
1287 pCurr->second = pCurr->second + aLnOfs.second;
1288 if( pCurr->second >= nCnt )
1291 pCurr = aBoxes.erase(pCurr);
1314 std::vector< SwLineOffset > aBoxes;
1316 sal_uInt16 nFirst = USHRT_MAX;
1317 sal_uInt16 nLast = 0;
1318 for (
size_t i = 0;
i < rBoxes.
size(); ++
i)
1320 const SwTableBox &rBox = rBoxes[
i ]->FindStartOfRowSpan( rTable );
1321 OSL_ENSURE( rBox.
getRowSpan() > 0,
"Didn't I say 'StartOfRowSpan' ??" );
1324 const sal_uInt16 nEnd = sal_uInt16( rBox.
getRowSpan() + nStart - 1 );
1326 if( aLnOfs.first != nStart || aLnOfs.second != nEnd )
1328 aLnOfs.first = nStart;
1329 aLnOfs.second = nEnd;
1330 aBoxes.push_back( aLnOfs );
1331 if( nStart < nFirst )
1338 if (nFirst == USHRT_MAX)
1340 assert(aBoxes.empty());
1345 std::unique_ptr<SwTwips[]> pLines(
new SwTwips[ nLast + 1 - nFirst ]);
1346 for( sal_uInt16
i = nFirst;
i <= nLast; ++
i )
1348 bool bLayoutAvailable =
false;
1349 nHeight += rTable.
GetTabLines()[
i ]->GetTableLineHeight( bLayoutAvailable );
1350 rCurr.
insert( rCurr.end(), nHeight );
1351 pLines[
i - nFirst ] = nHeight;
1353 for(
const auto& rSplit : aBoxes )
1355 SwTwips nBase = rSplit.first <= nFirst ? 0 :
1356 pLines[ rSplit.first - nFirst - 1 ];
1357 SwTwips nDiff = pLines[ rSplit.second - nFirst ] - nBase;
1358 for( sal_uInt16
i = 1;
i < nCnt; ++
i )
1360 SwTwips nSplit = nBase + (
i * nDiff ) / nCnt;
1361 rNew.insert( nSplit );
1374 sal_uInt16 nDirect = USHRT_MAX;
1375 sal_uInt16 nSpan = USHRT_MAX;
1376 for (
size_t i = 0;
i < rBoxes.
size(); ++
i)
1381 if( USHRT_MAX !=
nPos )
1385 if(
nPos > nDirect || nDirect == USHRT_MAX )
1392 sal_uInt16 nEndOfRowSpan = o3tl::narrowing<sal_uInt16>(
nPos + nRowSpan - 1);
1393 if( nEndOfRowSpan > nSpan || nSpan == USHRT_MAX )
1394 nSpan = nEndOfRowSpan;
1397 else if(
nPos < nDirect )
1401 if( nSpan && nSpan < USHRT_MAX )
1414 FndBox_ aFndBox(
nullptr,
nullptr );
1422 *
this, rBoxes, nCnt );
1425 SwSplitLines::iterator pSplit = aSplitLines.begin();
1426 for(
const auto& rCurr : aRowLines )
1428 while( pSplit != aSplitLines.end() && *pSplit < rCurr )
1441 if( pSplit != aSplitLines.end() && rCurr == *pSplit )
1456 bSameHeight =
false;
1462 SwLineOffsetArray::reverse_iterator pCurr( aLineOffs.rbegin() );
1463 while( pCurr != aLineOffs.rend() )
1470 std::set<size_t> aIndices;
1471 for (
size_t i = 0;
i < rBoxes.
size(); ++
i)
1473 OSL_ENSURE( rBoxes[
i]->getRowSpan() != 1,
"Forgot to split?" );
1474 if( rBoxes[
i]->getRowSpan() > 1 )
1475 aIndices.insert(
i );
1478 for(
const auto& rCurrBox : aIndices )
1479 lcl_UnMerge( *
this, *rBoxes[rCurrBox], nCnt, bSameHeight );
1493 sal_uInt16 nCnt,
bool bBehind )
1499 sal_uInt16 nRowIdx =
lcl_LineIndex( *
this, rBoxes, bBehind );
1500 if( nRowIdx < USHRT_MAX )
1502 FndBox_ aFndBox(
nullptr,
nullptr );
1510 InsertRow_( pDoc, aLineBoxes, nCnt, bBehind );
1511 const size_t nBoxCount = pLine->
GetTabBoxes().size();
1512 sal_uInt16 nOfs = bBehind ? 0 : 1;
1513 for( sal_uInt16
n = 0;
n < nCnt; ++
n )
1516 for(
size_t nCurrBox = 0; nCurrBox < nBoxCount; ++nCurrBox )
1518 sal_Int32 nRowSpan = pLine->
GetTabBoxes()[nCurrBox]->getRowSpan();
1521 if( nRowSpan == 1 || nRowSpan == -1 )
1523 else if( nRowSpan > 1 )
1525 nRowSpan = - nRowSpan;
1547 pNewLine->
GetTabBoxes()[ nCurrBox ]->setRowSpan( nRowSpan -
n );
1560 bRet =
InsertRow_( pDoc, rBoxes, nCnt, bBehind );
1573 for (
size_t i = 0;
i < rBoxes.
size(); ++
i)
1582 OSL_ENSURE( nLinePos < USHRT_MAX,
"Box/table mismatch" );
1589 OSL_ENSURE( pBox,
"RowSpan irritation I" );
1594 else if( nLinePos > 0 )
1600 OSL_ENSURE( pBox,
"RowSpan irritation II" );
1616 while( nRowSpan < 0 && nLinePos > 0 );
1627 SwTableLine& rLine,
bool bChkProtected,
bool bColumn )
1633 for(
size_t nCurrBox = 0; nCurrBox <
nCount; ++nCurrBox )
1636 OSL_ENSURE( pBox,
"Missing table box" );
1642 if( nRight <= nMax )
1643 bAdd = nLeft >= nMin || nRight >= nMid ||
1644 nRight - nMin > nMin - nLeft;
1646 bAdd = nLeft <= nMid || nRight - nMax < nMax - nLeft;
1652 size_t const nOldCnt = rBoxes.
size();
1654 if( bColumn && nRowSpan != 1 && nOldCnt < rBoxes.
size() )
1662 if( nRight >= nMax )
1673 const SearchType eSearch,
bool bChkProtected )
const
1675 OSL_ENSURE(
m_bNewModel,
"Don't call me for old tables" );
1680 if( !pStartNd || !pEndNd )
1706 for(
size_t nRow = 0; nFound < 2 && nRow < nLines; ++nRow )
1709 OSL_ENSURE( pLine,
"Missing table line" );
1711 for(
size_t nCol = 0; nCol < nCols; ++nCol )
1714 OSL_ENSURE( pBox,
"Missing table box" );
1717 if( !bChkProtected ||
1733 if( pEndNd == pStartNd )
1736 nLowerMin = nUpperMin;
1737 nLowerMax = nUpperMax;
1751 for(
size_t nRow = nTop; nRow <= nBottom; ++nRow )
1754 OSL_ENSURE( pLine,
"Missing table line" );
1756 for(
size_t nCurrBox = 0; nCurrBox <
nCount; ++nCurrBox )
1759 OSL_ENSURE( pBox,
"Missing table box" );
1760 if( pBox->
getRowSpan() > 0 && ( !bChkProtected ||
1767 bool bCombine = nTop == nBottom;
1772 if( nMinWidth > nTmp )
1774 nTmp =
std::min(nLowerMax, nUpperMax);
1775 nTmp -= ( nLowerMin < nUpperMin ) ? nUpperMin : nLowerMin;
1779 bCombine = ( nTmp + nTmp < nMinWidth );
1783 if( nUpperMin < nLowerMin )
1784 nLowerMin = nUpperMin;
1786 nUpperMin = nLowerMin;
1787 if( nUpperMax > nLowerMax )
1788 nLowerMax = nUpperMax;
1790 nUpperMax = nLowerMax;
1795 for(
size_t i = 0;
i < nTop; ++
i )
1802 tools::Long nMax = nUpperMax < nLowerMax ? nLowerMax : nUpperMax;
1803 for(
size_t i = nTop;
i <= nBottom; ++
i )
1805 bChkProtected, bColumn );
1809 for(
size_t i = nBottom + 1;
i < nLines; ++
i )
1811 bChkProtected,
true );
1821 OSL_ENSURE(
m_bNewModel,
"Don't call me for old tables" );
1828 const size_t nBoxCnt = rBoxes.
size();
1830 for(
size_t nRow = 0; nRow < nLineCnt && nBox < nBoxCnt; ++nRow )
1833 OSL_ENSURE( pLine,
"Missing table line" );
1835 for(
size_t nCol = 0; nCol < nCols; ++nCol )
1838 OSL_ENSURE( pBox,
"Missing table box" );
1839 if( pBox == rBoxes[nBox] )
1842 if( ++nBox >= nBoxCnt )
1847 for(
size_t nRow = 0; nRow < nLineCnt; ++nRow )
1852 for(
size_t nCurrBox = 0; nCurrBox < nCols; ++nCurrBox )
1857 if( nLeft >= rMin && nRight <= rMax )
1868 OSL_ENSURE(
m_bNewModel,
"Don't call me for old tables" );
1871 tools::Long nMid = nMin ? ( nMin + nMax ) / 2 : 0;
1876 for(
size_t nRow = 0; nRow < nLineCnt; ++nRow )
1881 for(
size_t nCurrBox = 0; nCurrBox < nCols; ++nCurrBox )
1893 if( nRight <= nMax )
1894 nNewWidth = nMid - nLeft;
1896 else if( nRight > nMax )
1897 nNewWidth = nRight - nMid;
1900 if( nNewWidth >= 0 )
1917 for (
size_t i = 0;
i < rBoxes.
size(); ++
i)
1936 OSL_ENSURE(
IsNewModel(),
"Don't call me for old tables" );
1938 OSL_ENSURE( nLineIdx <
GetTabLines().
size(),
"Start line out of range" );
1939 bool bChange =
true;
1946 const size_t nCols = rpLine->
GetTabBoxes().size();
1947 for(
size_t nCol = 0; !bChange && nCol < nCols; ++nCol )
1972 const size_t nCols = rpLine->
GetTabBoxes().size();
1973 for(
size_t nCol = 0; !bChange && nCol < nCols; ++nCol )
1982 if( nLineIdx >= nMaxLine )
1997 : mnSplitLine( nSplitLn )
1999 bool bDontSave =
true;
2000 const size_t nColCount = rBoxes.size();
2001 OSL_ENSURE( nColCount,
"Empty Table Line" );
2003 for(
size_t nCurrCol = 0; nCurrCol < nColCount; ++nCurrCol )
2006 OSL_ENSURE( pBox,
"Missing Table Box" );
2027 OSL_ENSURE( rSave.
mnSplitLine < nLineCount,
"Restore behind last line?" );
2032 const size_t nColCount = pLine->
GetTabBoxes().size();
2033 OSL_ENSURE( nColCount,
"Empty Table Line" );
2034 OSL_ENSURE( nColCount == rSave.
mnRowSpans.size(),
"Wrong row span store" );
2038 for(
size_t nCurrCol = 0; nCurrCol < nColCount; ++nCurrCol )
2041 OSL_ENSURE( pBox,
"Missing Table Box" );
2045 OSL_ENSURE( -nRowSp == rSave.
mnRowSpans[ nCurrCol ],
"Pardon me?!" );
2046 OSL_ENSURE( rSave.
mnRowSpans[ nCurrCol ] < 0,
"Pardon me?!" );
2070 }
while( nLine && pNext );
2081 if( pRet->mnRowSpans.empty() )
2092 const size_t nColCount = pLine->
GetTabBoxes().size();
2093 OSL_ENSURE( nColCount,
"Empty Table Line" );
2094 for(
size_t nCurrCol = 0; nCurrCol < nColCount; ++nCurrCol )
2097 OSL_ENSURE( pBox,
"Missing Table Box" );
2104 o3tl::narrowing<sal_uInt16>(nLastLine),
false );
2204 pSourceBox, j+k, 1);
2239 sal_uInt16
const nInsPos(j < nBox ? j : j + pSubLine->GetTabBoxes().
size() - 1);
2242 pSourceBox, nInsPos, 1);
2249 sal_Int32 newSourceRowSpan(pSourceBox->
getRowSpan());
2250 sal_Int32 newBoxRowSpan;
2251 if (newSourceRowSpan < 0)
2254 newBoxRowSpan = newSourceRowSpan +
i;
2259 newBoxRowSpan = -(newSourceRowSpan - sal::static_int_cast<tools::Long>(
i));
2261 pNewLine->
GetTabBoxes()[nInsPos]->setRowSpan(newBoxRowSpan);
2274 for (
size_t j = pSubLine->
GetTabBoxes().size(); 0 < j; --j)
2277 DeleteBox_(*
this, pBox,
nullptr,
false,
false,
nullptr);
2290 bool haveSubtable(
false);
2291 for (
SwTableBox const*
const pBox : pLine->GetTabBoxes())
2297 if (!pBox->GetTabLines().empty())
2303 haveSubtable =
true;
2304 bool haveNonFixedInnerLine(
false);
2305 for (
SwTableLine const*
const pInnerLine : pBox->GetTabLines())
2308 SwFrameFormat const& rRowFormat(*pInnerLine->GetFrameFormat());
2311 if (pBrush->GetGraphicObject() !=
nullptr)
2316 if (1 < pInnerLine->GetTabBoxes().size())
2325 haveNonFixedInnerLine =
true;
2330 haveNonFixedInnerLine =
true;
2332 for (
SwTableBox const*
const pInnerBox : pInnerLine->GetTabBoxes())
2334 if (!pInnerBox->GetTabLines().empty())
2340 if (haveNonFixedInnerLine)
2360 std::vector<SwFormatField*> vFields;
2362 if (!vFields.empty())
2381 temp.
Assign(*pStartNode->EndOfSectionNode(), +1);
2388 FndBox_ all(
nullptr,
nullptr);
2397 if (!rInnerLines.
empty())
2440 std::list< RowSpanCheck > aRowSpanCells;
2441 std::list< RowSpanCheck >::iterator aIter = aRowSpanCells.end();
2444 for(
size_t nCurrLine = 0; nCurrLine < nLineCount; ++nCurrLine )
2448 SAL_WARN_IF( !pLine,
"sw.core",
"Missing Table Line" );
2449 const size_t nColCount = pLine->
GetTabBoxes().size();
2450 SAL_WARN_IF( !nColCount,
"sw.core",
"Empty Table Line" );
2451 for(
size_t nCurrCol = 0; nCurrCol < nColCount; ++nCurrCol )
2456 SAL_WARN_IF(!
index.GetNode().IsStartNode(),
"sw.core",
"No box start node");
2464 "sw.core",
"Missing master box");
2465 if (aIter != aRowSpanCells.end())
2467 SAL_WARN_IF( aIter->nLeft != nWidth || aIter->nRight != nNewWidth,
2468 "sw.core",
"Wrong position/size of overlapped table box");
2469 --(aIter->nRowSpan);
2470 SAL_WARN_IF( aIter->nRowSpan != -nRowSp,
"sw.core",
2471 "Wrong row span value" );
2474 aIter = aRowSpanCells.erase(aIter);
2480 else if( nRowSp != 1 )
2482 SAL_WARN_IF( !nRowSp,
"sw.core",
"Zero row span?!" );
2483 RowSpanCheck aEntry;
2484 aEntry.nLeft = nWidth;
2485 aEntry.nRight = nNewWidth;
2486 aEntry.nRowSpan = nRowSp;
2487 aRowSpanCells.insert( aIter, aEntry );
2494 "Different Line Widths: first: " <<
nLineWidth
2495 <<
" current [" << nCurrLine <<
"]: " << nWidth);
2497 "Line width differs from table width: " <<
nTabSize
2498 <<
" current [" << nCurrLine <<
"]: " << nWidth);
2499 SAL_WARN_IF( nWidth < 0 || nWidth > USHRT_MAX,
"sw.core",
2500 "Width out of range [" << nCurrLine <<
"]: " << nWidth);
2501 SAL_WARN_IF( aIter != aRowSpanCells.end(),
"sw.core",
2502 "Missing overlapped box" );
2503 aIter = aRowSpanCells.begin();
2505 bool bEmpty = aRowSpanCells.empty();
2506 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 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
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
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 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)