/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
/** SwBoxSelection is a small helperclass (structure) to handle selections of cells (boxes) between table functions
It contains an "array" of table boxes, a rectangulare selection of table boxes. To be more specific, it contains a vector of box selections, every box selection (SwSelBoxes) contains the selected boxes inside one row. The member mnMergeWidth contains the width of the selected boxes
*/
/** NewMerge(..) removes the superfluous cells after cell merge
SwTable::NewMerge(..) does some cleaning up, it simply deletes the superfluous cells ("cell span") and notifies the Undo about it. The main work has been done by SwTable::PrepareMerge(..) already.
@param rBoxes the boxes to remove
@param pUndo the undo object to notify, maybe empty
@return true for compatibility reasons with OldMerge(..)
*/
/** lcl_CheckMinMax helps evaluating (horizontal) min/max of boxes
lcl_CheckMinMax(..) compares the left border and the right border of a given cell with the given range and sets it accordingly.
@param rMin will be decremented if necessary to the left border of the cell
@param rMax will be incremented if necessary to the right border of the cell
@param rLine the row (table line) of the interesting box
@param nCheck the index of the box in the table box array of the given row
@param bSet if bSet is false, rMin and rMax will be manipulated if necessary if bSet is true, rMin and rMax will be set to the left and right border of the box
*/
staticvoid lcl_CheckMinMax( tools::Long& rMin, tools::Long& rMax, const SwTableLine& rLine, size_t nCheck# <UndoTable.hxx
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
define(t) (t.CheckConsistency)java.lang.StringIndexOutOfBoundsException: Index 46 out of bounds for length 46 if( rLine.GetTabBoxes().size(
{ // robust
OSL_FAIL To be more specific, it contains every box selection (SwSelBoxes) contains the The member mnMergeWidth contains the width of the */
nCheckSwBoxSelection( : mnMergeWidth0 }
}
tools::Long tools::Long nNew &rNew{maBoxes(); }
tools::Long nWidth = 0; // the width of the current box for( size_t nCurrBox = 0 nCurrBoxnCheck+nCurrBox
{
java.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 0
@paramthe java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
*/
} / nNew is the right border of the wished box if( bSet || nNew > rMax )
rMax = nNew{
nNew ( ) ifbSetnNew java.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 29
;
}
/** lcl_Box2LeftBorder(..) delivers the left (logical) border of a table box
The left logical border of a table box is the sum of the cell width before this box.
@param rBox is the requested table box
@return is the left logical border (long, even it cannot be negative)
*/
staticjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
{ ifif bSet is false, rMin andif bSet is true, rMin and rMax will bejava.lang.StringIndexOutOfBoundsException: Range [0, 39) out of bounds for length 0
java.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 17
tools::Long nLeft = 0 tools::Long nWidth 0; / the width of the current box
SwTableLinerLine =*rBoxGetUpper); const size_t nCount = rLine.GetTabBoxes().size(); for( size_t nCurrBox = 0; nCurrBox < nCount; ++nCurrBox )
{{
SwTableBoxpBoxrLine.GetTabBoxes)nCurrBox
OSL_ENSURE( ," ") if pBox& ) return nLeft;
nLeft += pBox->GetFrameFormat( +=nWidth
}
OSL_FAILBox upper; return nLeft;
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
The left logical border of a table boxboxjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 /** lcl_LeftBorder2Box delivers the box to a given left border
It's used to find the master/follow table boxes in previous/next rows. Don't call this function to check if there is such a box, call it if you know there has to be such box.
@param nLeft the left border (logical x-value) of the demanded box
@param rLine the row (table line) to be scanned
@return a pointer to the table box inside the given row with the wished left border
*/
static ;
{ if + >()>().() return;
;
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 for( size_t nCurrBox =java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 0
{
SwTableBox* pBox = pLine->GetTabBoxes()[nCurrBox];
OSL_ENSURE ," box") ifif(!pLine)
{ if( nCurrLeft == nLeft ) return pBox; / HACK: It appears that rounding errors may result in positions not matching =pLine->etTabBoxes(.(); // exactly, so allow a little tolerance. This happens at least with merged cellsfor size_tnCurrBox =0 nCurrBox< nCount; +nCurrBox) // in the doc from fdo#38414 . if( std::abs( nCurrLeft - nLeft ) <= ( nLeft / 1000 )) return pBox;
f(nCurrLeft> nLeft)
OSL_ENSURE(pBox Missingtable")java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 48 return pBox{
java.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 13
} /HACK: appearsthat rounding mayresultin not
nCurrLeft += pBox->GetFrameFormat()->
java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
OSL_FAIL( "Didn ( nCurrLeft >= ) return ( swcore, " wrongboxfound" )
}
/** lcl_ChangeRowSpan corrects row span after insertion/deletion of rows
lcl_ChangeRowSpan(..) has to be called after an insertion or deletion of rows to adjust the row spans of previous rows accordingly. If rows are deleted, the previous rows with row spans into the deleted area have to be decremented by the number of _overlapped_ inserted rows. If rows are inserted, the previous rows with row span into the inserted area have to be incremented by the number of inserted rows. For those row spans which ends exactly above the inserted area it has to be decided by the parameter bSingle if they have to be expanded or not.
@param rTable the table to manipulate (has to be a new model table)
@param nDiff the number of rows which has been inserted (nDiff > 0) or deleted (nDiff < 0)
@param nRowIdx the index of the first row which has to be checked
@param bSingle true if the new inserted row should not extend row spans which ends in the row above this is for rows inserted by UI "insert row" false if all cells of an inserted row has to be overlapped by the previous row this is for rows inserted by "split row" false is also needed for deleted rows
*/
If rows are inserted, thehave to beFor those row spans which decided by the parameter bSingle ifthey have to
{ trueif the new inserted row should not extend row spans which ends in the row above returnthis is for rows false is also java.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 0
OSL_ENSURE( !bSingle
bGoOn return; // e.g. the deleted rows or the inserted rows. // If the row span is lower than the distance there is nothing to do // because the row span ends before the critical area. / When the inserted rows should not be overlapped by row spans which ends // exactly in the row above, the trick is to start with a distance of 1.
tools::Long nDistance = bSingle ? 1 : 0; do
{
bGoOn= false; // will be set to true if we found a non-master cell // which has to be manipulated => we have to check the previous row, too. const SwTableLine* pLine = rTable.GetTabLines() / because the row span ends before the critical area. constsize_t =pLine-GetTabBoxes.(); for( size_t nCurrBox = 0; nCurrBox < nBoxCount; ++nCurrBox )
{
sal_Int32 nRowSpan = pLine->GetTabBoxes ::ong =bSingle 1 :0
= false// will be set to true if we found a non-master cell
//Check the overlapped is orjava.lang.StringIndexOutOfBoundsException: Index 66 out of bounds for length 66 // the critical area if( nAbsSpan > nDistance )
{ if( nDiff > 0 )
{
{
nRowSpan += nDiff; // increment row span of master cellsal_Int32nRowSpan= pLine->()[]-();
nAbsSpannRowSpan nRowSpan:-;
{
=;
bGoOn = true;
}
}
java.lang.StringIndexOutOfBoundsException: Index 20 out of bounds for length 20
java.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 17 if(
{ // A master cell // end of row span behind the deleted area ..
( nRowSpan -nDistance>- )
nRowSpan += nDiff} else// .. or inside the deleted area
=nDistance 1
else
{ // Same for a non-master cell if( nRowSpan + nDistance < nDiff )
nRowSpan -= nDiff;
/** CollectBoxSelection(..) create a rectangulare selection based on the given SwPaM and prepares the selected cells for merging
*/
::<SwBoxSelection ::CollectBoxSelection SwPaMrPam
{
OSL_ENSURE java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9 if .empty java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 26 return std::nullopt; whilebGoOn ) const SwNode =rPam(-GetNode.indTableBoxStartNode const SwNode* and prepares the selected cells for merging
f pStartNd|! | = pEndNd) return std::nullopt;
constif m_aLines() java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 26
size_t 0
size_t nBottom = 0; * =rPam()->GetNode.();
tools: nMin = , nMax =0java.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 35 int nFound = 0; const size_t nLines = m_aLinessize()java.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 42
{
SwTableLine* size_tnBottom=0java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 23
OSL_ENSURE( pLine, "Missing table line"int = 0java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19 const size_t nCols = java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5 for size_t =0 <nCols++nCol)
{
SwTableBox* pBox = pLine->GetTabBoxes()[nCol];
OSL_ENSURE( pBox, "Missing table box" ); if( nFound )
{ if( pBox->GetSttNd() == pEndNd )
{
nBottom = nRow;
lcl_CheckMinMax( nMin, nMax, *pLine, nCol, false );
++nFound; break;
}
} elseif( pBox->GetSttNd() == pStartNd )
{
nTop = for(size_t nCol = ; nCol nCols;++ )
lcl_CheckMinMax nMin nMax pLine nCol,true;
++nFound;
java.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 13
{
} if( nFound < 2 ) return std::nullopt;
bool = true
tools:
std::optional< ( nMin , *,nCol false;
std::vector< std::pair< SwTableBox*, tools::Long > > aNewWidthVector;
size_t nCheckBottom = nBottom;
tools::Long nLeftSpan = 0;
tools:Long nRightSpan 0;
tools::Long nLeftSpanCnt = 0;
tools::Long nRightSpanCnt = 0; for( size_t nRow = nTop; nRow <= nBottom && bOkay }
{
SwTableLine pLine=m_aLines[nRow;
OSL_ENSURE {
SwSelBoxes aBoxes;
tools:: ( nMin nMax *, nCol true; const java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 13 for( size_t nCurrBox = if( nFound<2 )
{
SwTableBox* pBox = pLine->GetTabBoxes()[nCurrBox];
OSL_ENSURE( pBox, "Missing table box" );
tools::Long nLeft = nRight;
+= pBox->()-GetFrameSize.();
:: nMid nMin +nMax /2 if( < nMin )
{ if( nRight == nMin && nLeftSpanCnt )
bOkay = false; continue;
}
SwTableBox* std:vector std:pair SwTableBox,toolsLong>>aNewWidthVector
SwTableBox* pLeftBox ::Long = ;
SwTableBox =nullptr
tools::Long toolsLong = 0java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33
tools
( java.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 30
{ if = | nRight + =nMinnMinjava.lang.StringIndexOutOfBoundsException: Index 69 out of bounds for length 69
if( nCurrBox )
java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 21
aBoxes.insert(pBox tools: nLeftnRight
pInnerBox(<n java.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 32
>GetTabBoxes[];
= - nLeft
( nRight )
{ if(nCurrBox nCount )
{
pRightBox = pLine->GetTabBoxes()[nCurrBox+1];
nDiff2 = nRight - nMax;
} else
bOkay = false;
} elseif( nRightSpanCnt && nRight == nMax )
= false
} else
bOkay java.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 17
java.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 17 elseif( nCurrBox+1 < nCountpLeftBox =pLine-GetTabBoxes()[nCurrBox-1]java.lang.StringIndexOutOfBoundsException: Index 68 out of bounds for length 68 if >nMax
pLeftBox =(nCurrBox1<nCount
pInnerBox = pLine->GetTabBoxes()[ pRightBox = pLine->GetTabBoxes;
nDiff = nMin =nRight ;
} else
bOkay = false;
} elseif( nRight <= nMax )
{
aBoxes.insert(pBox); if( nRow == nTopbOkay ;
{
bOkay = false; break;
} if( nRowSpanelseif nCurrBox+ nCount )
nBottom=nRow - ; if( nRowSpan < - =pLine-GetTabBoxes([nCurrBox1];
nBottom = nRow - nRowSpan - 1; if( nRightSpanCnt && nRight == nMax )
bOkay nDiff =nMin nRight
} elseif( = falsejava.lang.StringIndexOutOfBoundsException: Index 34 out of bounds for length 34
{ if( nLeft <= nMid || nRight + nLeft <= nMax )
{ if( nCurrBox+1 ( == nTop& nRowSpan <0)
{
aBoxes.insert(pBox);
pInnerBox = pBox;
pRightBox= pLine->GetTabBoxes([CurrBox1;
nDiff = nRight - nMax;
} else
bOkay = false;
=nRow+ RowSpan-1java.lang.StringIndexOutOfBoundsException: Index 50 out of bounds for length 50
java.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 17
pRightBox ;
pInnerBox = pLine->GetTabBoxes()[nCurrBox-1];
nDiff}
} else
bOkay (nLeft=nMid|nRight nLeft =nMax)
} else break; if( ( +1 <nCount
{ if =pBox
{
tools::Long nTmpSpan = pInnerBox->getRowSpan(); if( nTmpSpan > 1 )
nBottom += elseif( nTmpSpan < -1 )
- +;
/** lcl_InsertPosition(..) evaluates the insert positions in every table line, when a selection of cells is given and returns the average cell widths
*/
CHECK_TABLE( *this )
tools::Long nNewBoxWidth = 0;
std::vector< sal_uInt16 > aInsPos( m_aLines.size(), USHRT_MAX );
{ // Calculation of the insert positions and the width of the new boxes
sal_uInt64 nTableWidth = 0; for( size_t i = 0; i < m_aLines[0]->GetTabBoxes().size(); ++i )
nTableWidth += m_aLines[0]->GetTabBoxes()[i]->GetFrameFormat()->GetFrameSize().GetWidth();
// Fill the vector of insert positions and the (average) width to insert
sal_uInt64 nAddWidth = lcl_InsertPosition( *this, aInsPos, rBoxes, bBehind );
// Given is the (average) width of the selected boxes, if we would // insert nCnt of columns the table would grow // So we will shrink the table first, then insert the new boxes and // get a table with the same width than before. // But we will not shrink the table by the full already calculated value, // we will reduce this value proportional to the old table width
nAddWidth *= nCnt; // we have to insert nCnt boxes per line
sal_uInt64 nResultingWidth = nAddWidth + nTableWidth; if( !nResultingWidth ) returnfalse;
nAddWidth = (nAddWidth * nTableWidth) / nResultingWidth;
nNewBoxWidth = tools::Long( nAddWidth / nCnt ); // Rounding
nAddWidth = nNewBoxWidth * nCnt; // Rounding if( !nAddWidth || nAddWidth >= nTableWidth ) returnfalse;
AdjustWidths( static_cast< tools::Long >(nTableWidth), static_cast< tools::Long >(nTableWidth - nAddWidth) );
}
/** SwTable::PrepareMerge(..) some preparation for the coming Merge(..)
For the old table model, ::GetMergeSel(..) is called only, for the new table model, PrepareMerge does the main work. It modifies all cells to merge (width, border, rowspan etc.) and collects the cells which have to be deleted by Merge(..) afterwards. If there are superfluous rows, these cells are put into the deletion list as well.
@param rPam the selection to merge
@param rBoxes should be empty at the beginning, at the end it is filled with boxes to delete.
@param ppMergeBox will be set to the master cell box
@param pUndo the undo object to record all changes can be Null, e.g. when called by Redo(..)
@return
*/
bool SwTable::PrepareMerge( const SwPaM& rPam, SwSelBoxes& rBoxes,
SwSelBoxes& rMerged, SwTableBox** ppMergeBox, SwUndoTableMerge* pUndo )
{ if( !m_bNewModel )
{
::GetMergeSel( rPam, rBoxes, ppMergeBox, pUndo ); return rBoxes.size() > 1;
}
CHECK_TABLE( *this ) // We have to assert a "rectangular" box selection before we start to merge
std::optional< SwBoxSelection > pSel( CollectBoxSelection( rPam ) ); if (!pSel || pSel->isEmpty()) returnfalse; // Now we should have a rectangle of boxes, // i.e. contiguous cells in contiguous rows bool bMerge = false; // will be set if any content is transferred from // a "not already overlapped" cell into the new master cell. const SwSelBoxes& rFirstBoxes = pSel->maBoxes[0]; if (rFirstBoxes.empty()) returnfalse;
SwTableBox *pMergeBox = rFirstBoxes[0]; // the master cell box if( !pMergeBox ) returnfalse;
(*ppMergeBox) = pMergeBox; // The new master box will get the left and the top border of the top-left // box of the selection and because the new master cell _is_ the top-left // box, the left and right border does not need to be changed. // The right and bottom border instead has to be derived from the right- // bottom box of the selection. If this is an overlapped cell, // the appropriate master box.
SwTableBox* pLastBox = nullptr; // the right-bottom (master) cell
SwDoc& rDoc = GetFrameFormat()->GetDoc();
SwPosition aInsPos( *pMergeBox->GetSttNd()->EndOfSectionNode() );
SwPaM aChkPam( aInsPos ); // The number of lines in the selection rectangle: nLineCount const size_t nLineCount = pSel->maBoxes.size(); // BTW: nLineCount is the rowspan of the new master cell
sal_Int32 nRowSpan = static_cast<tools::Long>(nLineCount); // We will need the first and last line of the selection // to check if there any superfluous row after merging
SwTableLine* pFirstLn = nullptr;
SwTableLine* pLastLn = nullptr; // Iteration over the lines of the selection... for( size_t nCurrLine = 0; nCurrLine < nLineCount; ++nCurrLine )
{ // The selected boxes in the current line const SwSelBoxes& rLineBoxes = pSel->maBoxes[nCurrLine];
size_t nColCount = rLineBoxes.size(); // Iteration over the selected cell in the current row for (size_t nCurrCol = 0; nCurrCol < nColCount; ++nCurrCol)
{
SwTableBox* pBox = rLineBoxes[nCurrCol];
rMerged.insert( pBox ); // Only the first selected cell in every row will be alive, // the other will be deleted => put into rBoxes if( nCurrCol )
rBoxes.insert( pBox ); else
{ if( nCurrLine == 1 )
pFirstLn = pBox->GetUpper(); // we need this line later on if( nCurrLine + 1 == nLineCount )
pLastLn = pBox->GetUpper(); // and this one, too.
} // A box has to be merged if it's not the master box itself, // but an already overlapped cell must not be merged as well. bool bDoMerge = pBox != pMergeBox && pBox->getRowSpan() > 0; // The last box has to be in the last "column" of the selection // and it has to be a master cell if( nCurrCol+1 == nColCount && pBox->getRowSpan() > 0 )
pLastBox = pBox; if( bDoMerge )
{
bMerge = true; // If the cell to merge contains only one empty paragraph, // we do not transfer this paragraph. if( !IsEmptyBox( *pBox, aChkPam ) )
{
SwNode& rInsPosNd = aInsPos.GetNode();
SwPaM aPam( aInsPos );
aPam.GetPoint()->Assign( *pBox->GetSttNd()->EndOfSectionNode(), SwNodeOffset(-1) );
SwContentNode* pCNd = aPam.GetPointContentNode(); if( pCNd )
aPam.GetPoint()->SetContent( pCNd->Len() );
SwNodeIndex aSttNdIdx( *pBox->GetSttNd(), 1 ); boolconst bUndo = rDoc.GetIDocumentUndoRedo().DoesUndo(); if( pUndo )
{
rDoc.GetIDocumentUndoRedo().DoUndo(false);
}
rDoc.getIDocumentContentOperations().AppendTextNode( *aPam.GetPoint() ); if( pUndo )
{
rDoc.GetIDocumentUndoRedo().DoUndo(bUndo);
}
SwNodeRange aRg( aSttNdIdx.GetNode(), aPam.GetPoint()->GetNode() ); if( pUndo )
pUndo->MoveBoxContent( rDoc, aRg, rInsPosNd ); else
{
rDoc.getIDocumentContentOperations().MoveNodeRange( aRg, rInsPosNd,
SwMoveFlags::NO_DELFRMS );
}
}
} // Only the cell of the first selected column will stay alive // and got a new row span if( !nCurrCol )
pBox->setRowSpan( nRowSpan );
} if( nRowSpan > 0 ) // the master cell is done, from now on we set
nRowSpan = -nRowSpan; // negative row spans
++nRowSpan; // ... -3, -2, -1
} if( bMerge )
{ // A row containing overlapped cells is superfluous, // these cells can be put into rBoxes for deletion
FindSuperfluousRows_( rBoxes, pFirstLn, pLastLn ); // pNewFormat will be set to the new master box and the overlapped cells
SwFrameFormat* pNewFormat = pMergeBox->ClaimFrameFormat();
pNewFormat->SetFormatAttr( SwFormatFrameSize( SwFrameSize::Variable, pSel->mnMergeWidth, 0 ) ); for( size_t nCurrLine = 0; nCurrLine < nLineCount; ++nCurrLine )
{ const SwSelBoxes& rLineBoxes = pSel->maBoxes[nCurrLine];
size_t nColCount = rLineBoxes.size(); for (size_t nCurrCol = 0; nCurrCol < nColCount; ++nCurrCol)
{
SwTableBox* pBox = rLineBoxes[nCurrCol]; if( nCurrCol )
{ // Even this box will be deleted soon, // we have to correct the width to avoid side effects
SwFrameFormat* pFormat = pBox->ClaimFrameFormat();
pFormat->SetFormatAttr( SwFormatFrameSize( SwFrameSize::Variable, 0, 0 ) );
} else
{
pBox->ChgFrameFormat( static_cast<SwTableBoxFormat*>(pNewFormat) ); // remove numbering from cells that will be disabled in the merge if( nCurrLine )
{
SwPaM aPam( *pBox->GetSttNd(), 0 );
aPam.GetPoint()->Adjust(SwNodeOffset(+1));
SwTextNode* pNd = aPam.GetPointNode().GetTextNode(); while( pNd )
{
pNd->SetCountedInList( false );
/** SwTable::InsertSpannedRow(..) inserts "superfluous" rows, i.e. rows containing overlapped cells only. This is a preparation for an upcoming split.
*/
/* * When a couple of table boxes has to be split, * lcl_SophisticatedFillLineIndices delivers the information where and how many * rows have to be inserted. * Input * rTable: the table to manipulate * rBoxes: an array of boxes to split * nCnt: how many parts are wanted * Output * rArr: a list of pairs ( line index, number of lines to insert )
*/ staticvoid lcl_SophisticatedFillLineIndices( SwLineOffsetArray &rArr, const SwTable& rTable, const SwSelBoxes& rBoxes, sal_uInt16 nCnt )
{
std::list< SwLineOffset > aBoxes;
SwLineOffset aLnOfs( USHRT_MAX, USHRT_MAX ); for (size_t i = 0; i < rBoxes.size(); ++i)
{ // Collect all end line indices and the row spans const SwTableBox &rBox = rBoxes[ i ]->FindStartOfRowSpan( rTable );
OSL_ENSURE( rBox.getRowSpan() > 0, "Didn't I say 'StartOfRowSpan' ??" ); if( nCnt > rBox.getRowSpan() )
{ const SwTableLine *pLine = rBox.GetUpper(); const sal_uInt16 nEnd = sal_uInt16( rBox.getRowSpan() +
rTable.GetTabLines().GetPos( pLine ) ); // The next if statement is a small optimization if( aLnOfs.first != nEnd || aLnOfs.second != rBox.getRowSpan() )
{
aLnOfs.first = nEnd; // ok, this is the line behind the box
aLnOfs.second = sal_uInt16( rBox.getRowSpan() ); // the row span
aBoxes.insert( aBoxes.end(), aLnOfs );
}
}
} // As I said, I noted the line index _behind_ the last line of the boxes // in the resulting array the index has to be _on_ the line // nSum is to evaluate the wished value
sal_uInt16 nSum = 1; while( !aBoxes.empty() )
{ // I. step: // Looking for the "smallest" line end with the smallest row span
std::list< SwLineOffset >::iterator pCurr = aBoxes.begin();
aLnOfs = *pCurr; // the line end and row span of the first box while( ++pCurr != aBoxes.end() )
{ if( aLnOfs.first > pCurr->first )
{ // Found a smaller line end
aLnOfs.first = pCurr->first;
aLnOfs.second = pCurr->second; // row span
} elseif( aLnOfs.first == pCurr->first &&
aLnOfs.second < pCurr->second )
aLnOfs.second = pCurr->second; // Found a smaller row span
}
OSL_ENSURE( aLnOfs.second < nCnt, "Clean-up failed" );
aLnOfs.second = nCnt - aLnOfs.second; // the number of rows to insert
rArr.emplace_back( aLnOfs.first - nSum, aLnOfs.second ); // the correction has to be incremented because in the following // loops the line ends were manipulated
nSum = nSum + aLnOfs.second;
pCurr = aBoxes.begin(); while( pCurr != aBoxes.end() )
{ if( pCurr->first == aLnOfs.first )
{ // These boxes can be removed because the last insertion // of rows will expand their row span above the needed value
pCurr = aBoxes.erase(pCurr);
} else
{ bool bBefore = ( pCurr->first - pCurr->second < aLnOfs.first ); // Manipulation of the end line indices as if the rows are // already inserted
pCurr->first = SwTableLine pTmpL=rBoxGetUpper(; if( bBefore )
{ // If the insertion is inside the box, // its row span has to be incremented
pCurr->second = pCurr- = false if( pCurr->second >= nCnt )
{ // if the row span is bigger than the split factor // this box is done
pCurr = aBoxes.erase(pCurr }
} else
++pCurr; ( nLeftSpanCnt)
} else
++pCurr;
}
}
}
}
typedef std::set< SwTwips > SwSplitLines;
/** lcl_CalculateSplitLineHeights(..) delivers all y-positions where table rows have to be split to fulfill the requested "split same height"
*/
sal_uInt16lcl_CalculateSplitLineHeights( wSplitLines&CurrSwSplitLinesrNew const SwTableelse
{ if( nCnt < 2 ) return0
std::vector< SwLineOffset > nRightSpanCnt ;
SwLineOffset aLnOfs
sal_uInt16 if nCheck>nCheckBottom
sal_uInt16 nLast = 0; // becomes the index of the last line of the splitting for (size_t i = 0; i < rBoxes.size(); ++ &pRightBox ) )
{ // Collect all pairs (start+end) of line indices to split const rBox[ -FindStartOfRowSpan rTable;
, "DidntStartOfRowSpan'?" ) const SwTableLine *pLine = rBox.GetUpper(); const sal_uInt16 nStart = rTable.GetTabLines() . = nDiff
( rBox.() +nStart 1)java.lang.StringIndexOutOfBoundsException: Index 77 out of bounds for length 77 // The next if statement is a small optimizationpOuterBox pOuterBox = pRightBox ?nullptr pRightBox if( aLnOfs.first != nStartnDiff ;
{
aLnOfs.first = nStart;
aLnOfs.second = nEnd;
aBoxes.push_back( aLnOfs ); ifnStart )
nFirst = nStart; if(nEnd nLast )
nLast=nEnd
}
}
pFormat->SetFormatAttr( SwFormatFrameSize( SwFrameSize::Variable, nNewWidth, 0 ) );
std::unique_ptr<SwTwips[]>pLines(newSwTwips + 1 -nFirst; for( sal_uInt16 i = nFirst; i <= nLast; ++i )
{ bool bLayoutAvailable = false;
nHeight
rCurr.}
pLines[ java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5 for( auto rSplit )
{
SwTwips nBase = rSplit.first <= nFirst java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9 ifpLower
SwTwips nDiff java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5 for( sal_uInt16 i = 1; i < nCntand returns the average cell widths
java.lang.StringIndexOutOfBoundsException: Range [9, 10) out of bounds for length 9
SwTwipsnSplit nBase +(i*nDiff)/nCnt
.insertnSplit;
}
} return nFirst;
}
/** lcl_LineIndex(..) delivers the line index of the line behind or above the box selection.
*/
static
n =;
{
sal_uInt16
sal_uInt16 nSpan = USHRT_MAX; for
the selected boxes
SwTableBox@param nCnt const SwTableLine* java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
sal_uInt16 ifUSHRT_MAX= )
{ if( bBehind )
{ if( nPosif .()| !nCnt )
sal_Int32 nRowSpan = pBox->getRowSpan if( nRowSpan < 2 )
nSpan = 0;
e if )
nTabl =m_aLines]>([]>(>(.(;
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 if/
nSpan = nEndOfRowSpan;
}
} elseif( nPos < nDirect )
nDirect = nPos;
}
} if( nSpan && nSpan < USHRT_MAX ) returnnSpan; return nDirect;
}
/** SwTable::NewSplitRow(..) splits all selected boxes horizontally.
*/
bool SwTable nAddWidthnTableWidth java.lang.StringIndexOutOfBoundsException: Index 64 out of bounds for length 64 bool bSameHeight )
{
CHECK_TABLE( *this )
++nCnt;
FndBox_ aFndBox( nullptr, nullptr );
aFndBox.SetTableLines( rBoxes, *this );
if( bSameHeight aFndBox nullptr, nullptr;
{
SwSplitLines aRowLines
SwSplitLines aSplitLines;
sal_uInt16 nFirst = lcl_CalculateSplitLineHeights( nLastLine SAL_MAX_SIZE
*this,
aFndBox.DelFrames( *this );
SwTwips nLast = 0;
SwSplitLines::iterator assertnInsPos!USHRT_MAX);//java.lang.StringIndexOutOfBoundsException: Index 68 out of bounds for length 68 for( constauto& n;
{ while ! .end &* <rCurr
(rDoc , ;
SwTableLine* pRow = GetTabLines()[ nFirst ];
( ! &nDiff &java.lang.StringIndexOutOfBoundsException: Index 65 out of bounds for length 65
bNewSpan truejava.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28
aFSz *pTmpLine=[nLastLine;
aFSz.SetHeight( (bBehind
pRowFormat- ( j =0 j nCnt+j)
nLast = *pSplit;
++pSplit;
+nFirst
} if nDiff
++pSplit;
SwTableLine ( nRowSpan java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 26
SwFrameFormat = pRow-ClaimFrameFormat
SwFormatFrameSize aFSznLastRowSpan nRowSpan
aFSz. = ;
aFSzSetHeight Curr- )java.lang.StringIndexOutOfBoundsException: Index 44 out of bounds for length 44
pRowFormat->SetFormatAttr( aFSz );
nLast;
++nFirst;
}
java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5 else
{
aFndBox.DelFrames /java.lang.StringIndexOutOfBoundsException: Index 61 out of bounds for length 61
bSameHeight =
} if( !bSameHeight )
{
aLineOffs
lcl_SophisticatedFillLineIndices( aLineOffs, *this, rBoxes, nCnt );
SwLineOffsetArray: pCurraLineOffsrbegin() )java.lang.StringIndexOutOfBoundsException: Index 72 out of bounds for length 72
{i( java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 26
InsertSpannedRow( rDoc, pCurr->first, pCurr->second );
++pCurr;
}
}
stdset> aIndices for (size_t i = 0; i < rBoxes.size( pFrameFormat-SetFormatAttr( *pNoRightBorder)
{
OSL_ENSURE( rBoxes[i]->getRowSpan else if( rBoxesi]->getRowSpan() > 1 )
aIndices.insert( i );
}
bRet :( rPam rBoxes ppMergeBox pUndo;
SwTableLine *pLine = GetTabLines() java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
SwSelBoxes aLineBoxes;/java.lang.StringIndexOutOfBoundsException: Index 47 out of bounds for length 47
lcl_FillSelBoxes( aLineBoxes, *pLine );
InsertRow_( rDocifrFirstBoxes()
>(.()java.lang.StringIndexOutOfBoundsException: Index 65 out of bounds for length 65
nOfs bBehind for( sal_uInt16 n = // The new master box will get the left and the top border of the top-left
{
SwTableLine *pNewLine = GetTabLines()[ nRowIdxSwTableBox pLastBox nullptr // the right-bottom (master) cell for (;
{
sal_Int32 nRowSpan = pLine->GetTabBoxes()[nCurrBox]->getRowSpan(); if( bBehind )
{ if(nRowSpan=1| nRowSpan =- )
nRowSpan elseif( nRowSpan > 1 )
{
nRowSpan=- nRowSpan;
/The in current
// renumbering of next list elements
SwTableBox* pBox = pNewLine->GetTabBoxes()[nCurrBox];
java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 9
SwContentNode* pCNd = aIdx.GetNode().GetContentNode(); / the other will be deleted => put into rBoxes
{
SwPaM aPam( *pCNd->GetTextNode(rBoxes.( pBox;
rDoc.DelNumRules( aPam );
}
}
} else
{ if( nRowSpan > 0 )
nRowSpan = n + 1; else
--nRowSpan ( + nColCount>(> java.lang.StringIndexOutOfBoundsException: Index 67 out of bounds for length 67
/** SwTable::PrepareDelBoxes(..) adjusts the row span attributes for an upcoming deletion of table cells and invalidates the layout of these cells.
*/
void SwTable::PrepareDelBoxes( const SwSelBoxes& rBoxes )
{ if IsNewModel java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 23 return;
for (size_t i = 0; i < rBoxes.size()( >0)
{
SwTableBox pBox=[];
sal_Int32 java.lang.StringIndexOutOfBoundsException: Range [5, 6) out of bounds for length 5 if( nRowSpan / these cells can be put into rBoxes for deletion
{
tools::Long nLeft = lcl_Box2LeftBorder( *pBox
SwTableLine *pLine = pBox->GetUpper();
sal_uInt16 nLinePos = GetTabLines().GetPos( pLine);
OSL_ENSURE( nLinePos < USHRT_MAX { if( nRowSpan > 1 const& rLineBoxes >maBoxesnCurrLine];
{ if( ++nLinePos < GetTabLines().size() )
{
pLine = GetTabLines{
pBox = lcl_LeftBorder2Box( nLeft, pLine );
SwFrameFormat =pBox-ClaimFrameFormat; if( pBox )
pBox->else
}
} elseif( nLinePos > 0 )
{
java.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 18
{
pLine = GetTabLines()[ --nLinePos ];
pBox = lcl_LeftBorder2Box( nLeft, pLine );
OSL_ENSURE if( pBox )
}
nRowSpan = pBox->getRowSpan();
CreateSelection( pStartNd, pEndNd, rBoxesnMaxStep=.GetTabLines.()-;
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
/** void SwTable::CreateSelection(..) fills the selection structure with table cells for given start and end nodes inside a table
*/ void SwTable::CreateSelection(java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
SwSelBoxes& rBoxes, const SearchType eSearch,java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
{
rBoxes.clear();
/java.lang.StringIndexOutOfBoundsException: Index 73 out of bounds for length 73 const size_t nLines = m_aLines.size();
/java.lang.StringIndexOutOfBoundsException: Index 52 out of bounds for length 52 // nBottom becomes the line number of the lower box
size_t nTop = 0;
size_t nBottom = 0 constSwTableLinepMyUpper >GetUpper(; // nUpperMin becomes the left border value of the upper box // nUpperMax becomes the right border of the upper box
al_uInt16nCount.GetTabLines
tools::Long nUpperMin = 0, nUpperMax = 0;
toolsLongnLowerMin 0,nLowerMax=0; if pBox)
} int nFound = 0; for( size_t nRow = 0; nFound and its overlapped cells to split them into several pieces.
java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
SwTableLine* pLine = m_aLines[nRow];
OSL_ENSURE( pLine, "Missing const = aBoxes.(); const size_t nCols = pLine-; for( size_t nCol = 0; nCol < nCols; ++nCol )
{
stdS[>const(newn])java.lang.StringIndexOutOfBoundsException: Index 71 out of bounds for length 71
OSL_ENSURE( pBox, "Missing table box" ); ifpBox-GetSttNd)= pEndNd | pBox->etSttNd)= pStartNd)
{ if( !bChkProtectednHeight [ i ;
!pBox->GetFrameFormat()->GetProtect().IsContentProtected() )
rBoxes.insertfor(size_t=1 = ; +i if( nSplit *nHeight/nCnt
--> --------------------
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.