void SwColumnFrame::DestroyImpl()
{
SwFrameFormat *pFormat = GetFormat();
SwDoc& rDoc = pFormat->GetDoc(); if ( !rDoc.IsInDtor() && pFormat->HasOnlyOneListener() )
{ //I'm the only one, delete the format. //Get default format before, so the base class can cope with it.
rDoc.GetDfltFrameFormat()->Add(*this); // tdf#134009, like #i32968# avoid SwUndoFrameFormatDelete creation, // the format is owned by the SwColumnFrame, see lcl_AddColumns()
::sw::UndoGuard const ug(rDoc.GetIDocumentUndoRedo());
rDoc.DelFrameFormat( pFormat );
}
SwColumnFrame *pColumn = static_cast<SwColumnFrame*>(pLower);
sw_RemoveFootnotes( pColumn, true, true ); while ( pColumn->GetNext() )
{
OSL_ENSURE( pColumn->GetNext()->IsColumnFrame(), "neighbor of ColumnFrame is no ColumnFrame." );
pColumn = static_cast<SwColumnFrame*>(pColumn->GetNext());
} for ( sal_uInt16 i = 0; i < nCnt; ++i )
{
SwColumnFrame *pTmp = static_cast<SwColumnFrame*>(pColumn->GetPrev());
pColumn->Cut();
SwFrame::DestroyFrame(pColumn); //format is going to be destroyed in the DTor if needed.
pColumn = pTmp;
}
}
//Formats should be shared whenever possible. If a neighbour already has //the same column settings we can add them to the same format. //The neighbour can be searched using the format, however the owner of the //attribute depends on the frame type.
SwLayoutFrame *pAttrOwner = pCont; if ( pCont->IsBodyFrame() )
pAttrOwner = pCont->FindPageFrame();
SwLayoutFrame *pNeighbourCol = nullptr;
SwIterator<SwLayoutFrame,SwFormat> aIter( *pAttrOwner->GetFormat() );
SwLayoutFrame *pNeighbour = aIter.First();
//Setting the column width is only needed for new formats. bool bAdjustAttributes = nOldNum != rOld.GetNumCols();
//The content is saved and restored if the column count is different.
SwFrame *pSave = nullptr; if( nOldNum != nNewNum || bChgFootnote )
{
SwDoc& rDoc = GetFormat()->GetDoc(); // SaveContent would also suck up the content of the footnote container // and store it within the normal text flow. if( IsPageBodyFrame() )
rDoc.getIDocumentLayoutAccess().GetCurrentLayout()->RemoveFootnotes( static_cast<SwPageFrame*>(GetUpper()) );
pSave = ::SaveContent( this );
//If columns exist, they get deleted if a column count of 0 or 1 is requested. if ( nNewNum == 1 && !bAtEnd )
{
::lcl_RemoveColumns( *this, nOldNum ); if ( IsBodyFrame() )
SetFrameFormat( rDoc.GetDfltFrameFormat() ); else
GetFormat()->SetFormatAttr( SwFormatFillOrder() ); if ( pSave )
::RestoreContent( pSave, this, nullptr ); return;
} if ( nOldNum == 1 )
{ if ( IsBodyFrame() )
SetFrameFormat( rDoc.GetColumnContFormat() ); else
GetFormat()->SetFormatAttr( SwFormatFillOrder( ATT_LEFT_TO_RIGHT ) ); if( !Lower() || !Lower()->IsColumnFrame() )
--nOldNum;
} if ( nOldNum > nNewNum )
{
::lcl_RemoveColumns( *this, nOldNum - nNewNum );
bAdjustAttributes = true;
} elseif( nOldNum < nNewNum )
{
sal_uInt16 nAdd = nNewNum - nOldNum;
bAdjustAttributes = lcl_AddColumns( this, nAdd );
}
}
if ( !bAdjustAttributes )
{ if ( rOld.GetLineWidth() != rNew.GetLineWidth() ||
rOld.GetWishWidth() != rNew.GetWishWidth() ||
rOld.IsOrtho() != rNew.IsOrtho() )
bAdjustAttributes = true; else
{ const size_t nCount = std::min( rNew.GetColumns().size(), rOld.GetColumns().size() ); for ( size_t i = 0; i < nCount; ++i ) if ( !(rOld.GetColumns()[i] == rNew.GetColumns()[i]) )
{
bAdjustAttributes = true; break;
}
}
}
//The columns can now be easily adjusted.
AdjustColumns( &rNew, bAdjustAttributes );
//Don't restore the content before. An earlier restore would trigger useless //actions during setup. if ( pSave )
{
SwFrame* pLower = Lower();
assert(pLower && pLower->IsLayoutFrame());
SwFrame* pLowerLower = static_cast<SwLayoutFrame*>(pLower)->Lower();
assert(pLowerLower && pLowerLower->IsLayoutFrame() && "no column body."); // ColumnFrames contain BodyFrames
::RestoreContent( pSave, static_cast<SwLayoutFrame*>(pLowerLower), nullptr );
}
}
//If we have a pointer or we have to configure an attribute, we set the //column widths in any case. Otherwise we check if a configuration is needed. if ( !pAttr )
{
pAttr = &GetFormat()->GetCol(); if ( !bAdjustAttributes )
{
tools::Long nAvail = fnRect.GetWidth(getFramePrintArea()); for ( SwLayoutFrame *pCol = static_cast<SwLayoutFrame*>(pLower);
pCol;
pCol = static_cast<SwLayoutFrame*>(pCol->GetNext()) )
nAvail -= fnRect.GetWidth(pCol->getFrameArea()); if ( !nAvail ) return;
}
}
//The columns can now be easily adjusted. //The widths get counted so we can give the reminder to the last one.
SwTwips nAvail = fnRect.GetWidth(getFramePrintArea()); constbool bLine = pAttr->GetLineAdj() != COLADJ_NONE; const sal_uInt16 nMin = bLine ? sal_uInt16( 20 + ( pAttr->GetLineWidth() / 2) ) : 0;
// #i27399# // bOrtho means we have to adjust the column frames manually. Otherwise // we may use the values returned by CalcColWidth: constbool bOrtho = pAttr->IsOrtho() && pAttr->GetNumCols() > 0;
tools::Long nGutter = 0;
for ( sal_uInt16 i = 0; i < pAttr->GetNumCols() && pCol; ++i ) //i118878, value returned by GetNumCols() can't be trusted
{ if( !bOrtho )
{ const SwTwips nWidth = i == (pAttr->GetNumCols() - 1) ?
nAvail :
pAttr->CalcColWidth( i, sal_uInt16( fnRect.GetWidth(getFramePrintArea()) ) );
// With this, the ColumnBodyFrames from page columns gets adjusted and // their bFixHeight flag is set so they won't shrink/grow. // Don't use the flag with frame columns because BodyFrames in frame // columns can grow/shrink. if( IsBodyFrame() ) static_cast<SwLayoutFrame*>(pCol)->Lower()->ChgSize( aColSz );
//In order to have enough space for the separation lines, we have to //take them into account here. Every time two columns meet we //calculate a clearance of 20 + half the pen width on the left or //right side, respectively. const sal_uInt16 nLeft = pC->GetLeft(); const sal_uInt16 nRight = pC->GetRight();
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.