47 #include <osl/diagnose.h>
50 #define CHECK_TABLE(t) (t).CheckConsistency();
52 #define CHECK_TABLE(t)
70 bool isEmpty()
const {
return maBoxes.empty(); }
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 auto pRet(std::make_unique<SwBoxSelection>());
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;
421 if( nCurrBox+1 < nCount )
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 )
463 if( nCurrBox+1 < nCount )
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)
592 for(
SwCellFrame* pCell = aIter.First(); pCell; pCell = aIter.Next() )
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.." );
624 rInsPos[ nCurrLine ] = nCurrBox;
627 else if( ( rInsPos[ nCurrLine ] > nCurrBox ) == !bBehind )
628 rInsPos[ nCurrLine ] = nCurrBox;
654 sal_uInt16 nCnt,
bool bBehind )
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 )
685 AdjustWidths( static_cast< tools::Long >(nTableWidth), static_cast< tools::Long >(nTableWidth - nAddWidth) );
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];
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 );
919 nRowSpan = -nRowSpan;
930 for(
size_t nCurrLine = 0; nCurrLine < nLineCount; ++nCurrLine )
932 const SwSelBoxes& rLineBoxes = pSel->maBoxes[nCurrLine];
933 size_t nColCount = rLineBoxes.
size();
934 for (
size_t nCurrCol = 0; nCurrCol < nColCount; ++nCurrCol)
946 pBox->
ChgFrameFormat( static_cast<SwTableBoxFormat*>(pNewFormat) );
957 aPam.GetPoint()->nNode++;
968 bool bOld = aBox.
GetRight() || aBox.GetBottom();
971 aBox.SetLine( rBox.
GetBottom(), SvxBoxItemLine::BOTTOM );
972 if( bOld || aBox.GetLeft() || aBox.GetTop() || aBox.GetRight() || aBox.GetBottom() )
973 (*ppMergeBox)->GetFrameFormat()->SetFormatAttr( aBox );
989 if( !pFirstLn || !pLastLn )
993 pFirstLn = rBoxes[0]->GetUpper();
998 for( sal_uInt16 nRow = nFirstLn; nRow <= nLastLn; ++nRow )
1001 OSL_ENSURE( pLine,
"Missing table line" );
1003 bool bSuperfl =
true;
1004 for(
size_t nCol = 0; nCol < nCols; ++nCol )
1008 rBoxes.
end() == rBoxes.
find( pBox ) )
1016 for(
size_t nCol = 0; nCol < nCols; ++nCol )
1046 }
while( nLine && --nMaxStep && pNext && pBox->
getRowSpan() < 1 );
1060 nAbsSpan = -nAbsSpan;
1061 if( nAbsSpan == 1 || !nMaxStep )
1064 if( nMaxStep > --nAbsSpan )
1065 nMaxStep =
static_cast<sal_uInt16
>(nAbsSpan);
1068 nMaxStep = nLine + nMaxStep;
1094 while( ++nLine < nCount && pBox && pBox->getRowSpan() != -1 )
1116 std::unique_ptr<size_t[]>
const pSplitIdx(
new size_t[nCnt]);
1119 std::unique_ptr<SwTwips[]>
const pHeights(
new SwTwips[nCount]);
1121 for (
size_t i = 0;
i < nCount; ++
i)
1126 nHeight += pHeights[
i ];
1130 for (
size_t i = 1;
i <= nCnt; ++
i)
1132 SwTwips nSplit = (
i * nHeight ) / nCnt;
1133 while( nSumH < nSplit && nIdx < nCount )
1134 nSumH += pHeights[ nIdx++ ];
1135 pSplitIdx[
i - 1 ] = nIdx;
1140 for (
size_t i = 1;
i <= nCnt; ++
i)
1142 pSplitIdx[
i - 1 ] = (
i * nCount ) / nCnt;
1146 for (
size_t i = 0;
i < nCnt; ++
i)
1148 size_t nNextIdx = pSplitIdx[
i ];
1149 aBoxes[ nIdx ]->setRowSpan( nNextIdx - nIdx );
1151 while( ++nIdx < nNextIdx )
1152 aBoxes[ nIdx ]->setRowSpan( nIdx - nNextIdx );
1161 const size_t nBoxCount = rLine.
GetTabBoxes().size();
1162 for(
size_t i = 0;
i < nBoxCount; ++
i )
1173 OSL_ENSURE( nCnt && nRowIdx <
GetTabLines().
size(),
"Wrong call of InsertSpannedRow" );
1181 tools::Long nNewHeight = aFSz.GetHeight() / ( nCnt + 1 );
1184 aFSz.SetHeight( nNewHeight );
1188 const size_t nBoxCount = rLine.
GetTabBoxes().size();
1189 for( sal_uInt16
n = 0;
n < nCnt; ++
n )
1192 for(
size_t nCurrBox = 0; nCurrBox < nBoxCount; ++nCurrBox )
1194 sal_Int32 nRowSpan = rLine.
GetTabBoxes()[nCurrBox]->getRowSpan();
1196 nRowSpan = - nRowSpan;
1197 pNewLine->
GetTabBoxes()[ nCurrBox ]->setRowSpan( nRowSpan -
n );
1221 std::list< SwLineOffset > aBoxes;
1223 for (
size_t i = 0;
i < rBoxes.
size(); ++
i)
1225 const SwTableBox &rBox = rBoxes[
i ]->FindStartOfRowSpan( rTable );
1226 OSL_ENSURE( rBox.
getRowSpan() > 0,
"Didn't I say 'StartOfRowSpan' ??" );
1230 const sal_uInt16 nEnd = sal_uInt16( rBox.
getRowSpan() +
1233 if( aLnOfs.first != nEnd || aLnOfs.second != rBox.
getRowSpan() )
1235 aLnOfs.first = nEnd;
1236 aLnOfs.second = sal_uInt16( rBox.
getRowSpan() );
1237 aBoxes.insert( aBoxes.end(), aLnOfs );
1244 sal_uInt16 nSum = 1;
1245 while( !aBoxes.empty() )
1249 std::list< SwLineOffset >::iterator pCurr = aBoxes.begin();
1251 while( ++pCurr != aBoxes.end() )
1253 if( aLnOfs.first > pCurr->first )
1255 aLnOfs.first = pCurr->first;
1256 aLnOfs.second = pCurr->second;
1258 else if( aLnOfs.first == pCurr->first &&
1259 aLnOfs.second < pCurr->second )
1260 aLnOfs.second = pCurr->second;
1262 OSL_ENSURE( aLnOfs.second < nCnt,
"Clean-up failed" );
1263 aLnOfs.second = nCnt - aLnOfs.second;
1264 rArr.emplace_back( aLnOfs.first - nSum, aLnOfs.second );
1267 nSum = nSum + aLnOfs.second;
1269 pCurr = aBoxes.begin();
1270 while( pCurr != aBoxes.end() )
1272 if( pCurr->first == aLnOfs.first )
1275 pCurr = aBoxes.erase(pCurr);
1279 bool bBefore = ( pCurr->first - pCurr->second < aLnOfs.first );
1282 pCurr->first = pCurr->first + aLnOfs.second;
1286 pCurr->second = pCurr->second + aLnOfs.second;
1287 if( pCurr->second >= nCnt )
1290 pCurr = aBoxes.erase(pCurr);
1313 std::vector< SwLineOffset > aBoxes;
1316 sal_uInt16 nLast = 0;
1317 for (
size_t i = 0;
i < rBoxes.
size(); ++
i)
1319 const SwTableBox &rBox = rBoxes[
i ]->FindStartOfRowSpan( rTable );
1320 OSL_ENSURE( rBox.
getRowSpan() > 0,
"Didn't I say 'StartOfRowSpan' ??" );
1323 const sal_uInt16 nEnd = sal_uInt16( rBox.
getRowSpan() + nStart - 1 );
1325 if( aLnOfs.first != nStart || aLnOfs.second != nEnd )
1327 aLnOfs.first = nStart;
1328 aLnOfs.second = nEnd;
1329 aBoxes.push_back( aLnOfs );
1330 if( nStart < nFirst )
1344 std::unique_ptr<SwTwips[]> pLines(
new SwTwips[ nLast + 1 - nFirst ]);
1345 for( sal_uInt16
i = nFirst;
i <= nLast; ++
i )
1347 bool bLayoutAvailable =
false;
1348 nHeight += rTable.
GetTabLines()[
i ]->GetTableLineHeight( bLayoutAvailable );
1349 rCurr.
insert( rCurr.end(), nHeight );
1350 pLines[
i - nFirst ] = nHeight;
1352 for(
const auto& rSplit : aBoxes )
1354 SwTwips nBase = rSplit.first <= nFirst ? 0 :
1355 pLines[ rSplit.first - nFirst - 1 ];
1356 SwTwips nDiff = pLines[ rSplit.second - nFirst ] - nBase;
1357 for( sal_uInt16
i = 1;
i < nCnt; ++
i )
1359 SwTwips nSplit = nBase + (
i * nDiff ) / nCnt;
1360 rNew.insert( nSplit );
1375 for (
size_t i = 0;
i < rBoxes.
size(); ++
i)
1384 if( nPos > nDirect || nDirect ==
USHRT_MAX )
1391 sal_uInt16 nEndOfRowSpan =
static_cast<sal_uInt16
>(nPos + nRowSpan - 1);
1392 if( nEndOfRowSpan > nSpan || nSpan ==
USHRT_MAX )
1393 nSpan = nEndOfRowSpan;
1396 else if( nPos < nDirect )
1413 FndBox_ aFndBox(
nullptr,
nullptr );
1421 *
this, rBoxes, nCnt );
1424 SwSplitLines::iterator pSplit = aSplitLines.begin();
1425 for(
const auto& rCurr : aRowLines )
1427 while( pSplit != aSplitLines.end() && *pSplit < rCurr )
1434 aFSz.SetHeight( *pSplit - nLast );
1440 if( pSplit != aSplitLines.end() && rCurr == *pSplit )
1446 aFSz.SetHeight( rCurr - nLast );
1455 bSameHeight =
false;
1461 SwLineOffsetArray::reverse_iterator pCurr( aLineOffs.rbegin() );
1462 while( pCurr != aLineOffs.rend() )
1469 std::set<size_t> aIndices;
1470 for (
size_t i = 0;
i < rBoxes.
size(); ++
i)
1472 OSL_ENSURE( rBoxes[
i]->getRowSpan() != 1,
"Forgot to split?" );
1473 if( rBoxes[
i]->getRowSpan() > 1 )
1474 aIndices.insert(
i );
1477 for(
const auto& rCurrBox : aIndices )
1478 lcl_UnMerge( *
this, *rBoxes[rCurrBox], nCnt, bSameHeight );
1492 sal_uInt16 nCnt,
bool bBehind )
1498 sal_uInt16 nRowIdx =
lcl_LineIndex( *
this, rBoxes, bBehind );
1501 FndBox_ aFndBox(
nullptr,
nullptr );
1509 InsertRow_( pDoc, aLineBoxes, nCnt, bBehind );
1510 const size_t nBoxCount = pLine->
GetTabBoxes().size();
1511 sal_uInt16 nOfs = bBehind ? 0 : 1;
1512 for( sal_uInt16
n = 0;
n < nCnt; ++
n )
1515 for(
size_t nCurrBox = 0; nCurrBox < nBoxCount; ++nCurrBox )
1517 sal_Int32 nRowSpan = pLine->
GetTabBoxes()[nCurrBox]->getRowSpan();
1520 if( nRowSpan == 1 || nRowSpan == -1 )
1522 else if( nRowSpan > 1 )
1524 nRowSpan = - nRowSpan;
1532 if( pCNd && pCNd->IsTextNode() && pCNd->GetTextNode()->GetNumRule() )
1535 SwPaM aPam( aPos, aPos );
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 )
1801 tools::Long nMin = std::min(nUpperMin, nLowerMin);
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;
1873 if( nTabSize == nMax )
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 static_cast<sal_uInt16>(nLastLine),
false );
2133 assert(!pSubTableBox->GetTabLines().empty());
2139 SwFrameFormat const& rSubLineFormat(*pSubTableBox->GetTabLines()[0]->GetFrameFormat());
2141 reinterpret_cast<SfxPoolItem const**>(&pSize)) == SfxItemState::SET)
2152 for (
size_t i = 1;
i < pSubTableBox->GetTabLines().size(); ++
i)
2154 SwTableLine *
const pSubLine(pSubTableBox->GetTabLines()[
i]);
2157 pSourceLine->
GetTabBoxes().size() - 1 + pSubLine->GetTabBoxes().size(),
2159 SwFrameFormat const& rSubLineFormat(*pSubLine->GetFrameFormat());
2162 reinterpret_cast<SfxPoolItem const**>(&pSize)) == SfxItemState::SET)
2164 pNewLine->ClaimFrameFormat();
2165 pNewLine->GetFrameFormat()->SetFormatAttr(*pSize);
2168 minHeights += pSize->GetHeight();
2172 if (
i == pSubTableBox->GetTabLines().size() - 1
2174 && minHeights < outerSize.GetHeight())
2177 lastSize.
SetHeight(lastSize.GetHeight() + outerSize.GetHeight() - minHeights);
2182 pNewLine->GetFrameFormat()->SetFormatAttr(lastSize);
2187 for (
size_t j = 0; j < pSourceLine->
GetTabBoxes().size(); ++j)
2191 for (
size_t k = 0; k < pSubLine->GetTabBoxes().size(); ++k)
2194 SwTableBox *
const pSourceBox(pSubLine->GetTabBoxes()[k]);
2195 assert(pSourceBox->getRowSpan() == 1);
2197 assert(pSourceBox->GetFrameFormat()->GetFrameSize().GetWidthPercent() == 0);
2199 static_cast<SwTableBoxFormat*>(pSourceBox->GetFrameFormat()),
2200 pSourceBox, j+k, 1);
2206 *pSourceBox->GetSttNd()->EndOfSectionNode());
2207 SwTableBox *
const pNewBox(pNewLine->GetTabBoxes()[j+k]);
2221 if (pNewBox->GetFrameFormat()->GetItemState(
RES_BACKGROUND,
true, &pCellBrush) != SfxItemState::SET)
2223 pNewBox->ClaimFrameFormat();
2224 pNewBox->GetFrameFormat()->SetFormatAttr(*pRowBrush);
2235 assert(pSourceBox->GetTabLines().empty());
2236 sal_uInt16
const nInsPos(j < nBox ? j : j + pSubLine->GetTabBoxes().
size() - 1);
2238 static_cast<SwTableBoxFormat*>(pSourceBox->GetFrameFormat()),
2239 pSourceBox, nInsPos, 1);
2246 sal_Int32 newSourceRowSpan(pSourceBox->getRowSpan());
2247 sal_Int32 newBoxRowSpan;
2248 if (newSourceRowSpan < 0)
2250 newSourceRowSpan -= pSubTableBox->GetTabLines().size() - 1;
2251 newBoxRowSpan = newSourceRowSpan +
i;
2255 newSourceRowSpan += pSubTableBox->GetTabLines().size() - 1;
2256 newBoxRowSpan = -(newSourceRowSpan - sal::static_int_cast<
tools::Long>(
i));
2258 pNewLine->GetTabBoxes()[nInsPos]->setRowSpan(newBoxRowSpan);
2259 if (
i == pSubTableBox->GetTabLines().size() - 1)
2261 pSourceBox->setRowSpan(newSourceRowSpan);
2267 while (1 < pSubTableBox->GetTabLines().size())
2270 SwTableLine *
const pSubLine(pSubTableBox->GetTabLines()[1]);
2271 for (
size_t j = pSubLine->GetTabBoxes().size(); 0 < j; --j)
2273 SwTableBox *
const pBox(pSubLine->GetTabBoxes()[0]);
2274 DeleteBox_(*
this, pBox,
nullptr,
false,
false,
nullptr);
2278 lcl_ChangeRowSpan(*
this, pSubTableBox->GetTabLines().size() - 1, nRow - 1,
false);
2287 bool haveSubtable(
false);
2288 for (
SwTableBox const*
const pBox : pLine->GetTabBoxes())
2294 if (!pBox->GetTabLines().empty())
2300 haveSubtable =
true;
2301 for (
SwTableLine const*
const pInnerLine : pBox->GetTabLines())
2304 SwFrameFormat const& rRowFormat(*pInnerLine->GetFrameFormat());
2305 std::unique_ptr<SvxBrushItem> pBrush(rRowFormat.makeBackgroundBrushItem());
2307 if (pBrush->GetGraphicObject() !=
nullptr)
2312 if (1 < pInnerLine->GetTabBoxes().size())
2317 for (
SwTableBox const*
const pInnerBox : pInnerLine->GetTabBoxes())
2319 if (!pInnerBox->GetTabLines().empty())
2334 std::vector<SwFormatField*> vFields;
2336 if (!vFields.empty())
2349 SwOLENode const*
const pOLENode(temp.GetNode().GetOLENode());
2350 if (pOLENode && tableName == pOLENode->GetChartTableName())
2355 temp.Assign(*pStartNode->EndOfSectionNode(), +1);
2365 for (
size_t j = 0; j < pLine->
GetTabBoxes().size(); ++j)
2369 if (!rInnerLines.empty())
2411 std::list< RowSpanCheck > aRowSpanCells;
2412 std::list< RowSpanCheck >::iterator aIter = aRowSpanCells.end();
2415 for(
size_t nCurrLine = 0; nCurrLine < nLineCount; ++nCurrLine )
2419 SAL_WARN_IF( !pLine,
"sw.core",
"Missing Table Line" );
2420 const size_t nColCount = pLine->
GetTabBoxes().size();
2421 SAL_WARN_IF( !nColCount,
"sw.core",
"Empty Table Line" );
2422 for(
size_t nCurrCol = 0; nCurrCol < nColCount; ++nCurrCol )
2435 "sw.core",
"Missing master box");
2436 if (aIter != aRowSpanCells.end())
2438 SAL_WARN_IF( aIter->nLeft != nWidth || aIter->nRight != nNewWidth,
2439 "sw.core",
"Wrong position/size of overlapped table box");
2440 --(aIter->nRowSpan);
2441 SAL_WARN_IF( aIter->nRowSpan != -nRowSp,
"sw.core",
2442 "Wrong row span value" );
2445 aIter = aRowSpanCells.erase(aIter);
2451 else if( nRowSp != 1 )
2453 SAL_WARN_IF( !nRowSp,
"sw.core",
"Zero row span?!" );
2454 RowSpanCheck aEntry;
2455 aEntry.nLeft = nWidth;
2456 aEntry.nRight = nNewWidth;
2457 aEntry.nRowSpan = nRowSp;
2458 aRowSpanCells.insert( aIter, aEntry );
2463 nLineWidth = nWidth;
2465 "Different Line Widths: first: " << nLineWidth
2466 <<
" current [" << nCurrLine <<
"]: " << nWidth);
2467 SAL_WARN_IF( std::abs(nWidth - nTabSize) > 1 ,
"sw.core",
2468 "Line width differs from table width: " << nTabSize
2469 <<
" current [" << nCurrLine <<
"]: " << nWidth);
2471 "Width out of range [" << nCurrLine <<
"]: " << nWidth);
2472 SAL_WARN_IF( aIter != aRowSpanCells.end(),
"sw.core",
2473 "Missing overlapped box" );
2474 aIter = aRowSpanCells.begin();
2476 bool bEmpty = aRowSpanCells.empty();
2477 SAL_WARN_IF( !bEmpty,
"sw.core",
"Open row span detected" );
Instances of SwFields and those derived from it occur 0 to n times.
const SwEndNode * EndOfSectionNode() const
Starts a section of nodes in the document model.
Base class of the Writer layout elements.
virtual sal_Int32 Len() const
tools::Long GetWidth() const
std::vector< SwSelBoxes > maBoxes
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...
SwNode & GetEndOfAutotext() const
Section for all Flys/Header/Footers.
const Value & back() const
Marks a position in the document model.
void SetHeight(tools::Long n)
sal_uLong GetSttIdx() const
virtual SwFieldType * GetFieldType(SwFieldIds nResId, const OUString &rName, bool bDbFieldMatching) const =0
SwSaveRowSpan(SwTableBoxes &rBoxes, sal_uInt16 nSplitLn)
constexpr TypedWhichId< SwFormatFrameSize > RES_FRM_SIZE(89)
std::pair< sal_uInt16, sal_uInt16 > SwLineOffset
const SwPosition * GetMark() const
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...
std::vector< SwLineOffset > SwLineOffsetArray
SwFrameFormat * ClaimFrameFormat()
void DelFrames(SwTable &rTable)
void GetMergeSel(const SwPaM &rPam, SwSelBoxes &rBoxes, SwTableBox **ppMergeBox, SwUndoTableMerge *pUndo)
const_iterator find(const Value &x) const
SwTableLine is one table row in the document model.
void PrepareDeleteCol(tools::Long nMin, tools::Long nMax)
SwTable::PrepareDeleteCol(..) adjusts the widths of the neighbour cells of a cell selection for an up...
virtual void assureSortedMarkContainers() const =0
static SwTableBox * lcl_LeftBorder2Box(tools::Long nLeft, const SwTableLine *pLine)
lcl_LeftBorder2Box delivers the box to a given left border
IDocumentMarkAccess * getIDocumentMarkAccess()
IDocumentUndoRedo & GetIDocumentUndoRedo()
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 editeng::SvxBorderLine * GetRight() const
IDocumentContentOperations const & getIDocumentContentOperations() const
void CheckRowSpan(SwTableLine *&rpLine, bool bUp) const
SwTable::CheckRowSpan(..) looks for the next line without an overlapping to the previous line...
SwTableFormat * GetFrameFormat()
Value in Var-direction gives minimum (can be exceeded but not be less).
bool PrepareMerge(const SwPaM &rPam, SwSelBoxes &rBoxes, SwSelBoxes &rMerged, SwTableBox **ppMergeBox, SwUndoTableMerge *pUndo)
SwTable::PrepareMerge(..) some preparation for the coming Merge(..)
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_SophisticatedFillLineIndices(SwLineOffsetArray &rArr, const SwTable &rTable, const SwSelBoxes &rBoxes, sal_uInt16 nCnt)
std::set< SwTwips > SwSplitLines
void GatherFields(std::vector< SwFormatField * > &rvFormatFields, bool bCollectOnlyInDocNodes=true) const
sal_Int32 getRowSpan() const
SwContentNode * GetContentNode(bool bPoint=true) const
IDocumentFieldsAccess const & getIDocumentFieldsAccess() const
void Delete(const SwNodeIndex &rPos, sal_uLong nNodes=1)
delete nodes
sal_uInt32 GetItemCount2(sal_uInt16 nWhich) const
bool IsEmptyBox(const SwTableBox &rBox, SwPaM &rPam)
std::vector< tools::Long > mnRowSpans
enumrange< T >::Iterator begin(enumrange< T >)
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
const SwTextFormatColl * GetDfltTextFormatColl() const
static void lcl_FillSelBoxes(SwSelBoxes &rBoxes, SwTableLine &rLine)
lcl_FillSelBoxes(..) puts all boxes of a given line into the selection structure
void AdjustWidths(const tools::Long nOld, const tools::Long nNew)
sal_uLong GetIndex() const
This structure is needed by Undo to restore row span attributes when a table has been split into two ...
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...
virtual void DoUndo(bool const bDoUndo)=0
Enable/Disable Undo.
iterator insert(iterator aIt, SwTableLine *pLine)
void InsertSpannedRow(SwDoc &rDoc, sal_uInt16 nIdx, sal_uInt16 nCnt)
SwTable::InsertSpannedRow(..) inserts "superfluous" rows, i.e.
void SetCountedInList(bool bCounted)
virtual bool DoesUndo() const =0
Is Undo enabled?
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...
void MakeFrames(SwTable &rTable)
void InsTableBox(SwDoc &rDoc, SwTableNode *pTableNd, SwTableLine *pLine, SwTableBoxFormat *pBoxFrameFormat, SwTableBox *pBox, sal_uInt16 nInsPos, sal_uInt16 nCnt=1)
void DelNumRules(const SwPaM &, SwRootFrame const *pLayout=nullptr)
bool NewMerge(SwDoc *, const SwSelBoxes &, const SwSelBoxes &rMerged, SwUndoTableMerge *)
NewMerge(..) removes the superfluous cells after cell merge.
PaM is Point and Mark: a selection of the document model.
void RestoreRowSpan(const SwSaveRowSpan &)
void SetTableLines(const SwSelBoxes &rBoxes, const SwTable &rTable)
const SwStartNode * StartOfSectionNode() const
const SwPosition * GetPoint() const
bool DeleteSel(SwDoc *, const SwSelBoxes &rBoxes, const SwSelBoxes *pMerged, SwUndo *pUndo, const bool bDelMakeFrames, const bool bCorrBorder)
SwIndex & Assign(SwIndexReg *, sal_Int32)
void CheckConsistency() const
void MoveBoxContent(SwDoc &rDoc, SwNodeRange &rRg, SwNodeIndex &rPos)
SwContentNode * GetContentNode()
void SetSelBoxes(const SwSelBoxes &rBoxes)
bool CanConvertSubtables() const
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...
SwFrameFormat * GetFrameFormat()
void push_back(const SwSelBoxes &rNew)
bool IsContentProtected() const
Marks a node in the document model.
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
SwFrameFormat * GetFrameFormat()
void FindSuperfluousRows_(SwSelBoxes &rBoxes, SwTableLine *, SwTableLine *)
SwTable::FindSuperfluousRows_(..) is looking for superfluous rows, i.e.
static void lcl_getAllMergedBoxes(const SwTable &rTable, SwSelBoxes &rBoxes, SwTableBox &rBox)
lcl_getAllMergedBoxes(..) collects all overlapped boxes to a given (master) box
const_iterator end() const
tools::Long GetHeight() const
SwStartNode * GetStartNode()
sal_uInt16 GetBoxPos(const SwTableBox *pBox) const
virtual bool MoveNodeRange(SwNodeRange &, SwNodeIndex &, SwMoveFlags)=0
SwTableLines & GetTabLines()
IDocumentLayoutAccess const & getIDocumentLayoutAccess() const
SwTable is one table in the document model, containing rows (which contain cells).
const SwPosition * Start() const
void SetWidth(tools::Long n)
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 ...
std::unique_ptr< SwBoxSelection > CollectBoxSelection(const SwPaM &rPam) const
CollectBoxSelection(..) create a rectangulare selection based on the given SwPaM and prepares the sel...
SwTextNode is a paragraph in the document model.
SwTableBoxes & GetTabBoxes()
IDocumentRedlineAccess const & getIDocumentRedlineAccess() const
std::vector< SwTableBox * > SwTableBoxes
constexpr TypedWhichId< SwTableBoxFormula > RES_BOXATR_FORMULA(149)
const SwStartNode * GetSttNd() const
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...
constexpr TypedWhichId< SvxBrushItem > RES_BACKGROUND(105)
void ChgFrameFormat(SwTableBoxFormat *pNewFormat, bool bNeedToReregister=true)
SwTableBox & FindStartOfRowSpan(const SwTable &, sal_uInt16 nMaxStep=USHRT_MAX)
SwTableBox::FindStartOfRowSpan(..) returns the "master" cell, the cell which overlaps the given cell...
#define SAL_WARN_IF(condition, area, stream)
virtual const SwViewShell * GetCurrentViewShell() const =0
Returns the layout set at the document.
std::unique_ptr< SwSaveRowSpan > CleanUpTopRowSpan(sal_uInt16 nSplitLine)
const o3tl::enumarray< SvxAdjust, unsigned short > aSvxToUnoAdjust USHRT_MAX
void CleanUpBottomRowSpan(sal_uInt16 nDelLines)
const SwPosition * End() const
SwTableBox & FindEndOfRowSpan(const SwTable &, sal_uInt16 nMaxStep)
SwTableBox::FindEndOfRowSpan(..) returns the last overlapped cell if there is any.
SwTableBox is one table cell in the document model.
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.
SwFrameFormat * ClaimFrameFormat()
virtual bool AppendTextNode(SwPosition &rPos)=0
const SwStartNode * FindTableBoxStartNode() const
void DeleteBox_(SwTable &rTable, SwTableBox *pBox, SwUndo *pUndo, bool bCalcNewSize, const bool bCorrBorder, SwShareBoxFormats *pShareFormats)
SwFootnoteIdxs & GetFootnoteIdxs()
#define SAL_WARN(area, stream)
void setRowSpan(sal_Int32 nNewRowSpan)
sal_uInt16 GetPos(const SwTableLine *pBox) const
bool NewSplitRow(SwDoc &, const SwSelBoxes &, sal_uInt16, bool)
SwTable::NewSplitRow(..) splits all selected boxes horizontally.
static tools::Long lcl_Box2LeftBorder(const SwTableBox &rBox)
lcl_Box2LeftBorder(..) delivers the left (logical) border of a table box
void AddNewBox(sal_uLong nSttNdIdx)
Frame is variable in Var-direction.
virtual const SwRedlineTable & GetRedlineTable() const =0
std::pair< const_iterator, bool > insert(Value &&x)
SwBoxSelection is a small helperclass (structure) to handle selections of cells (boxes) between table...
void PrepareDelBoxes(const SwSelBoxes &rBoxes)
SwTable::PrepareDelBoxes(..) adjusts the row span attributes for an upcoming deletion of table cells ...
bool InsertRow_(SwDoc *, const SwSelBoxes &, sal_uInt16 nCnt, bool bBehind)
const editeng::SvxBorderLine * GetBottom() const
static void lcl_InvalidateCellFrame(const SwTableBox &rBox)
lcl_InvalidateCellFrame(..) invalidates all layout representations of a given cell to initiate a refo...
bool NewInsertCol(SwDoc &, const SwSelBoxes &rBoxes, sal_uInt16 nCnt, bool)
SwTable::NewInsertCol(..) insert new column(s) into a table.
SwCellFrame is one table cell in the document layout.
const SwAttrPool & GetAttrPool() const
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
SwTextNode * MakeTextNode(const SwNodeIndex &rWhere, SwTextFormatColl *pColl, bool bNewFrames=true)
Implementations of "Make...Node" are in the given .cxx-files.
bool MoveNodes(const SwNodeRange &, SwNodes &rNodes, const SwNodeIndex &, bool bNewFrames=true)
move the node pointer
SwNodeIndex & Assign(SwNodes const &rNds, sal_uLong)
SwTableNode * GetTableNode() const
void SetLine(const editeng::SvxBorderLine *pNew, SvxBoxItemLine nLine)
void ExpandSelection(SwSelBoxes &rBoxes) const
SwTable::ExpandSelection(..) adds all boxes to the box selections which are overlapped by it...
Base class of the Writer document model elements.