/* -*- 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 .
*/
// The following type will be used by table copy functions to describe // the structure of tables (or parts of tables). // It's for new table model only.
/** Copy Table into this Box. Copy all Boxes of a Line into the corresponding Boxes. The old content is deleted by doing this. If no Box is left the remaining content goes to the Box of a "BaseLine".
If there's no Line anymore, put it also into the last Box of a "BaseLine". */ staticvoid lcl_CpyBox( const SwTable& rCpyTable, const SwTableBox* pCpyBox,
SwTable& rDstTable, SwTableBox* pDstBox, bool bDelContent, SwUndoTableCpyTable* pUndo )
{
OSL_ENSURE( ( !pCpyBox || pCpyBox->GetSttNd() ) && pDstBox->GetSttNd(), "No content in this Box" );
// First copy the new content and then delete the old one. // Do not create empty Sections, otherwise they will be deleted!
std::unique_ptr< SwNodeRange > pRg( pCpyBox ? new SwNodeRange ( *pCpyBox->GetSttNd(), SwNodeOffset(1),
*pCpyBox->GetSttNd()->EndOfSectionNode() ) : nullptr );
// If we still have FlyFrames hanging around, delete them too for(sw::SpzFrameFormat* pFly: *rDoc.GetSpzFrameFormats())
{
SwFormatAnchor const*const pAnchor = &pFly->GetAnchor();
SwNode const*const pAnchorNode = pAnchor->GetAnchorNode(); if (pAnchorNode &&
((RndStdIds::FLY_AT_PARA == pAnchor->GetAnchorId()) ||
(RndStdIds::FLY_AT_CHAR == pAnchor->GetAnchorId())) &&
aInsIdx <= *pAnchorNode && *pAnchorNode <= aEndNdIdx.GetNode() )
{
rDoc.getIDocumentLayoutAccess().DelLayoutFormat( pFly );
}
}
// If DestBox is a Headline Box and has Table style set, then // DO NOT automatically set the TableHeadline style! if( 1 < rDstTable.GetTabLines().size() &&
pLine == rDstTable.GetTabLines().front() )
{
SwContentNode* pCNd = aInsIdx.GetNode().GetContentNode(); if( !pCNd )
{
SwNodeIndex aTmp( aInsIdx );
pCNd = SwNodes::GoNext(&aTmp);
}
/** Copy Table into this Box. Copy all Boxes of a Line into the corresponding Boxes. The old content is deleted by doing this. If no Box is left the remaining content goes to the Box of a "BaseLine".
If there's no Line anymore, put it also into the last Box of a "BaseLine". */ bool SwTable::InsTable( const SwTable& rCpyTable, const SwNodeIndex& rSttBox,
SwUndoTableCpyTable* pUndo )
{
SetHTMLTableLayout(std::shared_ptr<SwHTMLTableLayout>()); // Delete HTML Layout
for( auto pLine : rCpyTable.GetTabLines() )
{ // Get the first from the CopyLine const SwTableBox* pCpyBox = pLine->GetTabBoxes().front(); while( !pCpyBox->GetTabLines().empty() )
pCpyBox = pCpyBox->GetTabLines().front()->GetTabBoxes().front();
do { // First copy the new content and then delete the old one. // Do not create empty Sections, otherwise they will be deleted!
lcl_CpyBox( rCpyTable, pCpyBox, *this, pMyBox, bDelContent, pUndo );
pTmp = pCpyBox->FindNextBox( rCpyTable, pCpyBox, false ); if( !pTmp ) break; // no more Boxes
pCpyBox = pTmp;
// Check if we have enough space for all Lines and Boxes
SwTableLines::size_type nTstLns = 0;
pFLine = aFndBox.GetLines().front().get();
sal_uInt16 nSttLine = GetTabLines().GetPos( pFLine->GetLine() ); // Do we have as many rows, actually? if( 1 == nFndCnt )
{ // Is there still enough space in the Table? if( (GetTabLines().size() - nSttLine ) <
rCpyTable.GetTabLines().size() )
{ // If we don't have enough Lines, then see if we can insert // new ones to reach our goal. But only if the SSelection // contains a Box! if( 1 < rSelBoxes.size() ) returnfalse;
// Test for nesting for( SwTableBoxes::size_type nBx = 0; nBx < pCpyLn->GetTabBoxes().size(); ++nBx ) if( !pLastLn->GetTabBoxes()[ nSttBox + nBx ]->GetSttNd() ) returnfalse;
} // We have enough space for the to-be-copied, so insert new // rows accordingly.
SwTableBox* pInsBox = pLastLn->GetTabBoxes()[ nSttBox ];
OSL_ENSURE( pInsBox && pInsBox->GetSttNd(), "no ContentBox or it's not in this Table" );
SwSelBoxes aBoxes;
nTstLns = rCpyTable.GetTabLines().size(); // copy this many
} elseif( 0 == (nFndCnt % rCpyTable.GetTabLines().size()) )
nTstLns = nFndCnt; else returnfalse; // not enough space for the rows
for( SwTableLines::size_type nLn = 0; nLn < nTstLns; ++nLn )
{ // We have enough rows, so check the Boxes per row
pFLine = aFndBox.GetLines()[ nLn % nFndCnt ].get();
SwTableLine* pLine = pFLine->GetLine();
SwTableBox* pSttBox = pFLine->GetBoxes()[0]->GetBox(); const SwTableBoxes::size_type nSttBox = pLine->GetBoxPos( pSttBox );
std::unique_ptr<FndLine_> pInsFLine; if( nLn >= nFndCnt )
{ // We have more rows in the ClipBoard than we have selected
pInsFLine.reset(new FndLine_( GetTabLines()[ nSttLine + nLn ],
&aFndBox ));
pLine = pInsFLine->GetLine();
}
SwTableLine* pCpyLn = rCpyTable.GetTabLines()[ nLn %
rCpyTable.GetTabLines().size() ];
// Selected too few rows? if( pInsFLine )
{ // We insert a new row into the FndBox if( pLine->GetTabBoxes().size() < nSttBox ||
pLine->GetTabBoxes().size() - nSttBox < pFLine->GetBoxes().size() )
{ returnfalse;
}
// Test for nesting for (FndBoxes_t::size_type nBx = 0; nBx < pFLine->GetBoxes().size(); ++nBx)
{
SwTableBox *pTmpBox = pLine->GetTabBoxes()[ nSttBox + nBx ]; if( !pTmpBox->GetSttNd() )
{ returnfalse;
} // if Ok, insert the Box into the FndLine
pFndBox = new FndBox_( pTmpBox, pInsFLine.get() );
pInsFLine->GetBoxes().insert( pInsFLine->GetBoxes().begin() + nBx,
std::unique_ptr<FndBox_>(pFndBox));
}
aFndBox.GetLines().insert( aFndBox.GetLines().begin() + nLn, std::move(pInsFLine));
} elseif( pFLine->GetBoxes().size() == 1 )
{ if( pLine->GetTabBoxes().size() < nSttBox ||
( pLine->GetTabBoxes().size() - nSttBox ) <
pCpyLn->GetTabBoxes().size() ) returnfalse;
// Test for nesting for( SwTableBoxes::size_type nBx = 0; nBx < pCpyLn->GetTabBoxes().size(); ++nBx )
{
SwTableBox *pTmpBox = pLine->GetTabBoxes()[ nSttBox + nBx ]; if( !pTmpBox->GetSttNd() ) returnfalse; // if Ok, insert the Box into the FndLine if( nBx == pFLine->GetBoxes().size() )
{
pFndBox = new FndBox_( pTmpBox, pFLine );
pFLine->GetBoxes().insert(pFLine->GetBoxes().begin() + nBx,
std::unique_ptr<FndBox_>(pFndBox));
}
}
} else
{ // Match the selected Boxes with the ones in the Clipboard // (n times) if( 0 != ( pFLine->GetBoxes().size() %
pCpyLn->GetTabBoxes().size() )) returnfalse;
// Test for nesting for (auto &rpBox : pFLine->GetBoxes())
{ if (!rpBox->GetBox()->GetSttNd()) returnfalse;
}
}
}
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.