/* -*- 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 .
*/
// do not clear items directly from item set and only clear to be kept // attributes, if no deletion item set is found. constbool bKeepAttributes =
!pPara || !pPara->pDelSet || pPara->pDelSet->Count() == 0; if ( bKeepAttributes )
{
pNode->ResetAttr( aClearWhichIds );
}
// Special case: if the Cursor is located within a URL attribute, we take over it's area
SwTextAttr const*const pURLAttr(
pTextNd->GetTextAttrAt(rSt.GetContentIndex(), RES_TXTATR_INETFMT)); if (pURLAttr && !pURLAttr->GetINetFormat().GetValue().isEmpty())
{
nMkPos = pURLAttr->GetStart();
nPtPos = *pURLAttr->End();
} else
{
assert(g_pBreakIt && g_pBreakIt->GetBreakIter().is());
Boundary aBndry = g_pBreakIt->GetBreakIter()->getWordBoundary(
pTextNd->GetText(), nPtPos,
g_pBreakIt->GetLocale( pTextNd->GetLang( nPtPos ) ),
WordType::ANY_WORD /*ANYWORD_IGNOREWHITESPACES*/, true);
/// Set the rsid of the next nLen symbols of rRg to the current session number void SwDoc::UpdateRsid( const SwPaM &rRg, const sal_Int32 nLen )
{ if (!SwModule::get()->GetModuleConfig()->IsStoreRsid()) return;
if (bRet && GetIDocumentUndoRedo().DoesUndo())
{
SwUndo *const pLastUndo = GetUndoManager().GetLastUndo();
SwUndoInsert *const pUndoInsert(dynamic_cast<SwUndoInsert*>(pLastUndo)); // this function is called after Insert so expects to find SwUndoInsert
assert(pUndoInsert); if (pUndoInsert)
{
pUndoInsert->SetWithRsid();
}
}
}
/// Set the attribute according to the stated format. /// If Undo is enabled, the old values is added to the Undo history. void SwDoc::SetAttr( const SfxPoolItem& rAttr, SwFormat& rFormat )
{
SfxItemSet aSet( GetAttrPool(), rAttr.Which(), rAttr.Which() );
aSet.Put( rAttr );
SetAttr( aSet, rFormat );
}
/// Set the attribute according to the stated format. /// If Undo is enabled, the old values is added to the Undo history. void SwDoc::SetAttr( const SfxItemSet& rSet, SwFormat& rFormat )
{ if (GetIDocumentUndoRedo().DoesUndo())
{
SwUndoFormatAttrHelper aTmp( rFormat );
rFormat.SetFormatAttr( rSet ); if ( aTmp.GetUndo() )
{
GetIDocumentUndoRedo().AppendUndo( aTmp.ReleaseUndo() );
} else
{
GetIDocumentUndoRedo().ClearRedo();
}
} else
{
rFormat.SetFormatAttr( rSet );
}
// If the format is a shape, and it has a textbox, sync. auto pShapeFormat = dynamic_cast<SwFrameFormat*>(&rFormat); if (pShapeFormat && SwTextBoxHelper::isTextBox(pShapeFormat, RES_DRAWFRMFMT))
{ if (auto pObj = pShapeFormat->FindRealSdrObject())
{
SwTextBoxHelper::syncFlyFrameAttr(*pShapeFormat, rSet, pObj);
SwTextBoxHelper::changeAnchor(pShapeFormat, pObj);
}
}
if ( bAttrReset )
{ if ( pUndo )
{
GetIDocumentUndoRedo().AppendUndo( std::move(pUndo) );
}
getIDocumentState().SetModified();
}
}
staticbool lcl_SetNewDefTabStops( SwTwips nOldWidth, SwTwips nNewWidth,
SvxTabStopItem& rChgTabStop )
{ // Set the default values of all TabStops to the new value. // Attention: we always work with the PoolAttribute here, so that // we don't calculate the same value on the same TabStop (pooled!) for all sets. // We send a FormatChg to modify.
// Find the default's beginning
sal_uInt16 n; for( n = nOldCnt; n ; --n ) if( SvxTabAdjust::Default != rChgTabStop[n - 1].GetAdjustment() ) break;
++n; if( n < nOldCnt ) // delete the DefTabStops
rChgTabStop.Remove( n, nOldCnt - n ); returntrue;
}
/// Set the attribute as new default attribute in this document. /// If Undo is enabled, the old value is added to the Undo history. void SwDoc::SetDefault( const SfxPoolItem& rAttr )
{
SfxItemSet aSet( GetAttrPool(), rAttr.Which(), rAttr.Which() );
aSet.Put( rAttr );
SetDefault( aSet );
}
const SvxTabStopItem* pTmpItem = aNew.GetItemIfSet( RES_PARATR_TABSTOP, false ); if( pTmpItem && pTmpItem->Count() )
{ // Set the default values of all TabStops to the new value. // Attention: we always work with the PoolAttribute here, so that // we don't calculate the same value on the same TabStop (pooled!) for all sets. // We send a FormatChg to modify.
SwTwips nNewWidth = (*pTmpItem)[ 0 ].GetTabPos(),
nOldWidth = aOld.Get(RES_PARATR_TABSTOP)[ 0 ].GetTabPos();
bool bChg = false;
ForEachParaAtrTabStopItem([&bChg, &nOldWidth, &nNewWidth](const SvxTabStopItem& rTabStopItem) -> bool { // pItem2 and thus pTabStopItem is a evtl. shared & RefCounted // Item and *should* not be changed that way. lcl_SetNewDefTabStops // seems to change pTabStopItem (!). This may need to be changed // to use iterateItemSurrogates and a defined write cycle.
bChg |= lcl_SetNewDefTabStops( nOldWidth, nNewWidth, const_cast<SvxTabStopItem&>(rTabStopItem) ); returntrue;
});
void SwDoc::DelFrameFormat( SwFrameFormat *pFormat, bool bBroadcast )
{
assert(pFormat && "ContainsFormat will always deref pFormat"); if( dynamic_cast<const SwTableBoxFormat*>( pFormat) != nullptr || dynamic_cast<const SwTableLineFormat*>( pFormat) != nullptr )
{
OSL_ENSURE( false, "Format is not in the DocArray any more, " "so it can be deleted with delete" ); delete pFormat;
} else
{ // The format has to be in the one or the other, we'll see in which one. if (mpFrameFormatTable->ContainsFormat(pFormat))
{ if (bBroadcast)
BroadcastStyleOperation(pFormat->GetName(),
SfxStyleFamily::Frame,
SfxHintId::StyleSheetErased);
if (GetIDocumentUndoRedo().DoesUndo())
{
GetIDocumentUndoRedo().AppendUndo(
std::make_unique<SwUndoFrameFormatDelete>(pFormat, *this));
}
// Who has the to-be-deleted as their Next?
SwTextFormatColl *pDel = (*mpTextFormatCollTable)[nFormatColl]; if( mpDfltTextFormatColl.get() == pDel ) return; // never delete default!
if (bBroadcast)
BroadcastStyleOperation(pDel->GetName(), SfxStyleFamily::Para,
SfxHintId::StyleSheetErased);
if (GetIDocumentUndoRedo().DoesUndo())
{
std::unique_ptr<SwUndoTextFormatCollDelete> pUndo; if (RES_CONDTXTFMTCOLL == pDel->Which())
{
pUndo.reset(new SwUndoCondTextFormatCollDelete(pDel, *this));
} else
{
pUndo.reset(new SwUndoTextFormatCollDelete(pDel, *this));
}
// #i62675# check, if paragraph style has changed if ( pPara->bResetListAttrs &&
(pPara->bResetAllCharAttrs || pFormat != pCNd->GetFormatColl())
&& pCNd->GetTextNode()->IsInList() )
{ // Check, if the list style of the paragraph will change. bool bChangeOfListStyleAtParagraph( true );
SwTextNode& rTNd(*pCNd->GetTextNode());
{
SwNumRule* pNumRuleAtParagraph(rTNd.GetNumRule()); if ( pNumRuleAtParagraph )
{ const SwNumRuleItem& rNumRuleItemAtParagraphStyle = pFormat->GetNumRule(); if ( rNumRuleItemAtParagraphStyle.GetValue() ==
pNumRuleAtParagraph->GetName() )
{
bChangeOfListStyleAtParagraph = false;
}
}
}
std::optional<SwRegHistory> oRegH; if (pPara->pHistory)
oRegH.emplace(&rTNd, rTNd, pPara->pHistory);
if ( bChangeOfListStyleAtParagraph )
{
pCNd->ResetAttr( RES_PARATR_NUMRULE );
// reset all list attributes
pCNd->ResetAttr( RES_PARATR_LIST_LEVEL );
pCNd->ResetAttr( RES_PARATR_LIST_ISRESTART );
pCNd->ResetAttr( RES_PARATR_LIST_RESTARTVALUE );
pCNd->ResetAttr( RES_PARATR_LIST_ISCOUNTED );
pCNd->ResetAttr( RES_PARATR_LIST_ID );
} else
{ // The List Level must be applied as direct formatting. The spec says: // 19.495 The style:list-level attribute specifies the list level value // of a list style that may be applied to any paragraph style. // It does not directly specify the paragraph's list level value, // but consumers can change the paragraph's list level value to the specified value // when the paragraph style is applied.
pCNd->SetAttr(pFormat->GetFormatAttr(RES_PARATR_LIST_LEVEL));
}
}
}
// add to History so that old data is saved, if necessary if( pPara->pHistory )
pPara->pHistory->AddColl(pCNd->GetFormatColl(), pCNd->GetIndex(),
SwNodeType::Text );
/// Copy the formats to itself
SwFormat* SwDoc::CopyFormat( const SwFormat& rFormat, const SwFormatsBase& rFormatArr,
FNCopyFormat fnCopyFormat, const SwFormat& rDfltFormat )
{ // It's no autoformat, default format or collection format, // then search for it. if( !rFormat.IsAuto() || !rFormat.GetRegisteredIn() ) for( size_t n = 0; n < rFormatArr.GetFormatCount(); ++n )
{ // Does the Doc already contain the template? if( rFormatArr.GetFormat(n)->GetName()==rFormat.GetName() ) return rFormatArr.GetFormat(n);
}
// Search for the "parent" first
SwFormat* pParent = const_cast<SwFormat*>(&rDfltFormat); if( rFormat.DerivedFrom() && pParent != rFormat.DerivedFrom() )
pParent = CopyFormat( *rFormat.DerivedFrom(), rFormatArr,
fnCopyFormat, rDfltFormat );
// Create the format and copy the attributes // #i40550#
SwFormat* pNewFormat = (this->*fnCopyFormat)( rFormat.GetName(), pParent, true );
pNewFormat->SetAuto( rFormat.IsAuto() );
pNewFormat->CopyAttrs( rFormat ); // copy the attributes
if( RES_CONDTXTFMTCOLL == pSrc->Which() )
{ if (pDstColl->Which() != RES_CONDTXTFMTCOLL)
{ // Target already had a style with a matching name, but it's not a conditional // style, then don't copy the conditions. continue;
}
// Copy the conditions, but delete the old ones first! static_cast<SwConditionTextFormatColl*>(pDstColl)->SetConditions( static_cast<SwConditionTextFormatColl*>(pSrc)->GetCondColls() );
}
}
}
}
void SwDoc::CopyPageDescHeaderFooterImpl( bool bCpyHeader, const SwFrameFormat& rSrcFormat, SwFrameFormat& rDestFormat )
{ // Treat the header and footer attributes in the right way: // Copy content nodes across documents!
sal_uInt16 nAttr = bCpyHeader ? sal_uInt16(RES_HEADER) : sal_uInt16(RES_FOOTER); const SfxPoolItem* pItem; if( SfxItemState::SET != rSrcFormat.GetAttrSet().GetItemState( nAttr, false, &pItem )) return ;
// The header only contains the reference to the format from the other document!
std::unique_ptr<SfxPoolItem> pNewItem(pItem->Clone());
// the header and footer attributes are copied separately // the content sections have to be copied in their entirety
{
SfxItemSet aAttrSet( rSrcDesc.GetMaster().GetAttrSet() );
aAttrSet.ClearItem( RES_HEADER );
aAttrSet.ClearItem( RES_FOOTER );
// If foot notes change the pages have to be triggered if( !(rDstDesc.GetFootnoteInfo() == rSrcDesc.GetFootnoteInfo()) )
{
sw::PageFootnoteHint aHint;
rDstDesc.SetFootnoteInfo( rSrcDesc.GetFootnoteInfo() );
rDstDesc.GetMaster().CallSwClientNotify(aHint);
rDstDesc.GetLeft().CallSwClientNotify(aHint);
rDstDesc.GetFirstMaster().CallSwClientNotify(aHint);
rDstDesc.GetFirstLeft().CallSwClientNotify(aHint);
}
// Copy the stashed formats as well between the page descriptors... for (bool bFirst : { true, false })
{ for (bool bLeft : { true, false })
{ for (bool bHeader : { true, false })
{ if (!bLeft && !bFirst) continue;
// Copy format only if it exists if (auto pStashedFormatSrc = rSrcDesc.GetStashedFrameFormat(bHeader, bLeft, bFirst))
{ if (&pStashedFormatSrc->GetDoc() != this)
{
SwFrameFormat newFormat(GetAttrPool(), UIName(u"CopyDesc"_ustr), GetDfltFrameFormat());
//To-Do: // a) in sd rtf import (View::InsertData) don't use // a super-fragile test for mere presence of \trowd to // indicate import of rtf into a table // b) then drop use of bIncludePageStyles if (bIncludePageStyles)
{ // and now the page templates
SwPageDescs::size_type nCnt = rSource.m_PageDescs.size(); if( nCnt )
{ // a different Doc -> Number formatter needs to be merged
SwTableNumFormatMerge aTNFM( rSource, *this );
// 2nd step: Copy all attributes, set the right parents for (SwPageDescs::size_type i = rSource.m_PageDescs.size(); i; )
{ const SwPageDesc &rSrc = *rSource.m_PageDescs[ --i ];
SwPageDesc* pDesc = FindPageDesc( rSrc.GetName() );
CopyPageDesc( rSrc, *pDesc);
}
}
}
// then there are the numbering templates const SwNumRuleTable::size_type nCnt = rSource.GetNumRuleTable().size(); if( nCnt )
{ const SwNumRuleTable& rArr = rSource.GetNumRuleTable(); for( SwNumRuleTable::size_type n = 0; n < nCnt; ++n )
{ const SwNumRule& rR = *rArr[ n ];
SwNumRule* pNew = FindNumRulePtr( rR.GetName()); if( pNew )
pNew->CopyNumRule(*this, rR); else
{ if( !rR.IsAutoRule() )
MakeNumRule( rR.GetName(), &rR ); else
{ // as we reset all styles, there shouldn't be any unknown // automatic SwNumRules, because all should have been // created by the style copying! // So just warn and ignore.
SAL_WARN( "sw.core", "Found unknown auto SwNumRule during reset!" );
}
}
}
}
if (undoGuard.UndoWasEnabled())
{ // nodes array was modified!
GetIDocumentUndoRedo().DelAllUndoObj();
}
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.