/* -*- 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 .
*/
sal_uInt32 nIncrease = 0; if (!bHack)
{ // Increase the rsid with a random number smaller than 2^17. This way we // expect to be able to edit a document 2^12 times before rsid overflows. // start from 1 to ensure the new rsid is not the same
nIncrease = comphelper::rng::uniform_uint_distribution(1, (1 << 17) - 1);
}
mnRsid = nVal + nIncrease;
}
/* * Document editing (Doc-SS) to fill the document * by the RTF parser and for the EditShell.
*/ void SwDoc::ChgDBData(const SwDBData& rNewData)
{ if( rNewData != maDBData )
{
maDBData = rNewData;
getIDocumentState().SetModified(); if (m_pDBManager)
m_pDBManager->CommitLastRegistrations();
}
getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::DatabaseName)->UpdateFields();
}
sal_uInt16 PostItField_::GetPageNo( const StringRangeEnumerator &rRangeEnum, const o3tl::sorted_vector< sal_Int32 > &rPossiblePages, /* out */ sal_uInt16& rVirtPgNo, /* out */ sal_Int32& rLineNo )
{ //Problem: If a PostItField is contained in a Node that is represented //by more than one layout instance, //we have to decide whether it should be printed once or n-times. //Probably only once. For the page number we don't select a random one, //but the PostIt's first occurrence in the selected area.
rVirtPgNo = 0;
SwIterator<SwTextFrame, SwTextNode, sw::IteratorMode::UnwrapMulti> aIter(GetTextField()->GetTextNode()); for( SwTextFrame* pFrame = aIter.First(); pFrame; pFrame = aIter.Next() )
{
TextFrameIndex const nPos = pFrame->MapModelToView(
&GetTextField()->GetTextNode(), GetContent()); if( pFrame->GetOffset() > nPos ||
(pFrame->HasFollow() && pFrame->GetFollow()->GetOffset() <= nPos) ) continue;
sal_uInt16 nPgNo = pFrame->GetPhyPageNum(); if( rRangeEnum.hasValue( nPgNo, &rPossiblePages ))
{
rLineNo = o3tl::narrowing<sal_Int32>(pFrame->GetLineCount( nPos ) +
pFrame->GetAllLines() - pFrame->GetThisLines());
rVirtPgNo = pFrame->GetVirtPageNum(); return nPgNo;
}
} return 0;
}
pIDCO->SplitNode( *aPam.GetPoint(), false );
aStr = pField->GetPar2(); #ifdefined(_WIN32) // Throw out all CR in Windows
aStr = aStr.replaceAll("\r", ""); #endif
pIDCO->InsertString( aPam, aStr );
}
/// provide the paper tray to use according to the page style in use, /// but do that only if the respective item is NOT just the default item static sal_Int32 lcl_GetPaperBin( const SwPageFrame *pStartFrame )
{
sal_Int32 nRes = -1;
// properties to take into account when calculating the set of pages // (PDF export UI does not allow for selecting left or right pages only) bool bPrintLeftPages = bIsPDFExport || rOptions.IsPrintLeftPages(); bool bPrintRightPages = bIsPDFExport || rOptions.IsPrintRightPages(); // #i103700# printing selections should not allow for automatic inserting empty pages bool bPrintEmptyPages = !bPrintSelection && rOptions.IsPrintEmptyPages( bIsPDFExport );
// now that we have identified the valid pages for printing according // to the print settings we need to get the PageRange to use and // use both results to get the actual pages to be printed // (post-it settings need to be taken into account later on!)
// get PageRange value to use
OUString aPageRange; // #i116085# - adjusting fix for i113919 if ( !bIsPDFExport )
{ // PageContent : // 0 -> print all pages (default if aPageRange is empty) // 1 -> print range according to PageRange // 2 -> print selection if (1 == nContent)
aPageRange = rOptions.getStringValue( "PageRange" );
if (2 == nContent)
{ // note that printing selections is actually implemented by copying // the selection to a new temporary document and printing all of that one. // Thus for Writer "PrintContent" must never be 2. // See SwXTextDocument::GetRenderDoc for evaluating if a selection is to be // printed and for creating the temporary document.
}
// please note
} if (aPageRange.isEmpty()) // empty string -> print all
{ // set page range to print to 'all pages'
aPageRange = OUString::number( 1 ) + "-" + OUString::number( nDocPageCount );
} else
{ // Convert page numbers from user input to physical page numbers
aPageRange = UIPages2PhyPages(aPageRange, aUIPages2PhyPagesMap);
}
rData.SetPageRange( aPageRange );
// get vector of pages to print according to PageRange and valid pages set from above // (result may be an empty vector, for example if the range string is not correct) // If excluding empty pages, allow range to specify range of printable pages
StringRangeEnumerator::getRangesFromString( aPageRange, rData.GetPagesToPrint(),
1, nDocPageCount, 0, &rData.GetValidPagesSet() );
}
// For mode SwPostItMode::EndPage: // maps a physical page number to the page number in post-it document that holds // the first post-it for that physical page . Needed to relate the correct start frames // from the post-it doc to the physical page of the document
std::map< sal_Int32, sal_Int32 > aPostItLastStartPageNum;
// add all post-its on valid pages within the page range to the // temporary post-it document. // Since the array of post-it fields is sorted by page and line number we will // already get them in the correct order
sal_uInt16 nVirtPg = 0, nLastPageNum = 0, nPhyPageNum = 0;
sal_Int32 nLineNo = 0; bool bIsFirstPostIt = true; for (SetGetExpFields::size_type i = 0; i < nPostItCount; ++i)
{
PostItField_& rPostIt = static_cast<PostItField_&>(*(*rData.m_pPostItFields)[ i ]);
nLastPageNum = nPhyPageNum;
nPhyPageNum = rPostIt.GetPageNo(
aRangeEnum, rData.GetValidPagesSet(), nVirtPg, nLineNo ); if (nPhyPageNum)
{ // need to insert a page break? // In SwPostItMode::EndPage mode for each document page the following // post-it page needs to start on a new page constbool bNewPage = nPostItMode == SwPostItMode::EndPage &&
!bIsFirstPostIt && nPhyPageNum != nLastPageNum;
if (nPostItMode == SwPostItMode::EndPage)
{ // get the correct number of current pages for the post-it document
rData.m_pPostItShell->CalcLayout(); const sal_Int32 nPages = rData.m_pPostItShell->GetPageCount();
aPostItLastStartPageNum[ nPhyPageNum ] = nPages;
}
}
}
// format post-it doc to get correct number of pages
rData.m_pPostItShell->CalcLayout();
SwRootFrame* pPostItRoot = rData.m_pPostItShell->GetLayout(); //tdf#103313 print dialog maxes out cpu as Idles never get to //complete this postitshell's desire to complete formatting
pPostItRoot->ResetIdleFormat();
if (nPostItMode == SwPostItMode::Only || nPostItMode == SwPostItMode::EndDoc)
{ // now add those post-it pages to the vector of pages to print // or replace them if only post-its should be printed
if (nPostItMode == SwPostItMode::Only)
{ // no document page to be printed
rData.GetPagesToPrint().clear();
}
// now we just need to add the post-it pages to be printed to the // end of the vector of pages to print
sal_Int32 nPageNum = 0; const SwPageFrame * pPageFrame = static_cast<SwPageFrame*>(pPostItRoot->Lower()); while( pPageFrame && nPageNum < nPostItDocPageCount )
{
++nPageNum; // negative page number indicates page is from the post-it doc
rData.GetPagesToPrint().push_back( -nPageNum );
pPageFrame = static_cast<const SwPageFrame*>(pPageFrame->GetNext());
}
OSL_ENSURE( nPageNum == nPostItDocPageCount, "unexpected number of pages" );
} elseif (nPostItMode == SwPostItMode::EndPage)
{ // the next step is to find all the pages from the post-it // document that should be printed for a given physical page // of the document
std::vector< sal_Int32 > aTmpPagesToPrint;
sal_Int32 nLastPostItPage(0); const size_t nNum = rData.GetPagesToPrint().size(); for (size_t i = 0 ; i < nNum; ++i)
{ // add the physical page to print from the document const sal_Int32 nPhysPage = rData.GetPagesToPrint()[i];
aTmpPagesToPrint.push_back( nPhysPage );
// add the post-it document pages to print, i.e those // post-it pages that have the data for the above physical page
std::map<sal_Int32, sal_Int32>::const_iterator const iter(
aPostItLastStartPageNum.find(nPhysPage)); if (iter != aPostItLastStartPageNum.end())
{ for (sal_Int32 j = nLastPostItPage + 1;
j <= iter->second; ++j)
{ // negative page number indicates page is from the
aTmpPagesToPrint.push_back(-j); // post-it document
}
nLastPostItPage = iter->second;
}
}
// finally we need to assign those vectors to the resulting ones. // swapping the data should be more efficient than assigning since // we won't need the temporary vectors anymore
rData.GetPagesToPrint().swap( aTmpPagesToPrint );
}
OUString aPageRange; // PageContent : // 0 -> print all pages (default if aPageRange is empty) // 1 -> print range according to PageRange // 2 -> print selection const sal_Int64 nContent = rOptions.getIntValue( "PrintContent", 0 ); if (nContent == 1)
aPageRange = rOptions.getStringValue( "PageRange" ); if (aPageRange.isEmpty()) // empty string -> print all
{ // set page range to print to 'all pages'
aPageRange = OUString::number( 1 ) + "-" + OUString::number( nDocPageCount );
}
StringRangeEnumerator aRange( aPageRange, 1, nDocPageCount, 0 );
if ( aRange.size() <= 0) return;
const SwPageFrame *pStPage = dynamic_cast<const SwPageFrame*>( rLayout.Lower() ); for ( sal_Int32 i = 1; pStPage && i < nDocPageCount; ++i )
pStPage = static_cast<const SwPageFrame*>(pStPage->GetNext()); if ( !pStPage ) // Then it was that return;
// currently for prospect printing all pages are valid to be printed // thus we add them all to the respective map and set for later use
sal_Int32 nPageNum = 0; const SwPageFrame *pPageFrame = dynamic_cast<const SwPageFrame*>( rLayout.Lower() ); while( pPageFrame && nPageNum < nDocPageCount )
{
++nPageNum;
rValidPagesSet.insert( nPageNum );
validStartFrames[ nPageNum ] = pPageFrame;
pPageFrame = static_cast<const SwPageFrame*>(pPageFrame->GetNext());
rPrinterPaperTrays[ nPageNum ] = lcl_GetPaperBin( pStPage );
}
OSL_ENSURE( nPageNum == nDocPageCount, "unexpected number of pages" );
// properties to take into account when calculating the set of pages // Note: here bPrintLeftPages and bPrintRightPages refer to the (virtual) resulting pages // of the prospect! bool bPrintLeftPages = rOptions.IsPrintLeftPages(); bool bPrintRightPages = rOptions.IsPrintRightPages(); bool bPrintProspectRTL = rOptions.getIntValue( "PrintProspectRTL", 0 ) != 0;
// get pages for prospect printing according to the 'PageRange' // (duplicates and any order allowed!)
std::vector< sal_Int32 > aPagesToPrint;
StringRangeEnumerator::getRangesFromString(
aPageRange, aPagesToPrint, 1, nDocPageCount, 0 );
if (aPagesToPrint.empty()) return;
// now fill the vector for calculating the page pairs with the start frames // from the above obtained vector
std::vector< const SwPageFrame * > aVec; for (sal_Int32 nPage : aPagesToPrint)
{ const SwPageFrame *pFrame = validStartFrames[ nPage ];
aVec.push_back( pFrame );
}
// just one page is special ... if ( 1 == aVec.size() )
{
aVec.push_back( nullptr ); // insert a second empty page
} else
{ // now extend the number of pages to fit a multiple of 4 // (4 'normal' pages are needed for a single prospect paper // with back and front) while( aVec.size() & 3 )
aVec.push_back( nullptr );
}
// make sure that all pages are in correct order
std::vector< const SwPageFrame * >::size_type nSPg = 0;
std::vector< const SwPageFrame * >::size_type nEPg = aVec.size();
assert(nEPg >= 2);
sal_Int32 nStep = 1; if ( 0 == (nEPg & 1 )) // there are no uneven ones!
--nEPg;
nSPg = nSPg + nStep;
nEPg = nEPg - nStep;
}
OSL_ENSURE( size_t(nCntPage) == rPagePairs.size(), "size mismatch for number of page pairs" );
// luckily prospect printing does not make use of post-its so far, // thus we are done here.
}
/// @return the reference in the doc for the name const SwFormatRefMark* SwDoc::GetRefMark( const SwMarkName& rName ) const
{ const SwFormatRefMark* pRet = nullptr;
ForEachRefMark(
[&pRet, &rName] (const SwFormatRefMark& rRefMark) -> bool
{ const SwTextRefMark* pTextRef = rRefMark.GetTextRefMark(); if( pTextRef && rName == rRefMark.GetRefName() )
{
pRet = &rRefMark; returnfalse;
} returntrue;
}); return pRet;
}
/// @return the RefMark per index - for Uno const SwFormatRefMark* SwDoc::GetRefMark( sal_uInt16 nIndex ) const
{ const SwFormatRefMark* pRet = nullptr;
/// @return the names of all set references in the Doc //JP 24.06.96: If the array pointer is 0, then just return whether a RefMark is set in the Doc // OS 25.06.96: From now on we always return the reference count
sal_uInt16 SwDoc::GetRefMarks( std::vector<OUString>* pNames ) const
{
sal_uInt16 nCount = 0;
ForEachRefMark(
[&pNames, &nCount] (const SwFormatRefMark& rRefMark) -> bool
{ if( pNames )
{
SwMarkName aTmp(rRefMark.GetRefName());
pNames->insert(pNames->begin() + nCount, aTmp.toString());
}
++nCount; returntrue;
});
/// Iterate over all SvxOverlineItem, if the function returns false, iteration is stopped void SwDoc::ForEachOverlineItem( const std::function<bool(const SvxOverlineItem&)>& rFunc ) const
{
SwNodeOffset nCount = GetNodes().Count(); for (SwNodeOffset i(0); i < nCount; ++i)
{
SwNode* pNode = GetNodes()[i]; if (!pNode->IsTextNode()) continue;
SwTextNode* pTextNode = pNode->GetTextNode(); const SwAttrSet& rAttrSet = pTextNode->GetSwAttrSet(); if (const SvxOverlineItem* pItem = rAttrSet.GetItemIfSet(RES_CHRATR_OVERLINE, false)) if (!rFunc(*pItem)) return; if (pTextNode->HasHints())
{
SwpHints& rHints = pTextNode->GetSwpHints(); for (size_t j = 0; j < rHints.Count(); ++j)
{ const SwTextAttr* pTextAttr = rHints.Get(j); if (pTextAttr->Which() != RES_TXTATR_AUTOFMT) continue; const SwFormatAutoFormat& rAutoFormat = pTextAttr->GetAutoFormat(); const std::shared_ptr<SfxItemSet> & rxItemSet = rAutoFormat.GetStyleHandle(); if (const SvxOverlineItem* pItem = rxItemSet->GetItemIfSet(RES_CHRATR_OVERLINE, false)) if (!rFunc(*pItem)) return;
}
}
} constauto& aTableTemplateMap = SwTableAutoFormat::GetTableTemplateMap(); const SwTableAutoFormatTable& rTableStyles = GetTableStyles(); for (size_t i=0; i < rTableStyles.size(); ++i)
{ const SwTableAutoFormat& rTableStyle = rTableStyles[i]; for (const sal_uInt32 nBoxIndex : aTableTemplateMap)
{ const SwAutoFormatProps& rBoxProps = rTableStyle.GetBoxFormat(nBoxIndex).GetProps(); const SvxOverlineItem rOverlineItem = rBoxProps.GetOverline(); if (!rFunc(rOverlineItem)) return;
}
} const SwCellStyleTable& rCellStyleTable = GetCellStyles(); for (size_t i=0; i < rCellStyleTable.size(); ++i)
{ const SwCellStyleDescriptor aCellStyle = rCellStyleTable[i]; const SwAutoFormatProps& rBoxProps = aCellStyle.GetAutoFormat().GetProps(); const SvxOverlineItem rOverlineItem = rBoxProps.GetOverline(); if (!rFunc(rOverlineItem)) return;
}
}
/// Iterate over all SwFormatField, if the function returns false, iteration is stopped void SwDoc::ForEachFormatField( TypedWhichId<SwFormatField> nWhich, const std::function<bool(const SwFormatField&)>& rFunc ) const
{
SwNodeOffset nCount = GetNodes().Count(); for (SwNodeOffset i(0); i < nCount; ++i)
{
SwNode* pNode = GetNodes()[i]; if (!pNode->IsTextNode()) continue;
SwTextNode* pTextNode = pNode->GetTextNode(); if (!pTextNode->HasHints()) continue;
SwpHints& rHints = pTextNode->GetSwpHints(); for (size_t j = 0; j < rHints.Count(); ++j)
{ const SwTextAttr* pTextAttr = rHints.Get(j); if (pTextAttr->Which() != nWhich) continue; const SwFormatField& rFormatField = pTextAttr->GetFormatField(); if (!rFunc(rFormatField)) return;
}
}
}
/** * Re-trigger spelling in the idle handler. * * @param bInvalid if <true>, the WrongLists in all nodes are invalidated * and the SpellInvalid flag is set on all pages. * @param bOnlyWrong controls whether only the areas with wrong words are * checked or the whole area. * @param bSmartTags ???
*/ void SwDoc::SpellItAgainSam( bool bInvalid, bool bOnlyWrong, bool bSmartTags )
{
o3tl::sorted_vector<SwRootFrame*> aAllLayouts = GetAllLayouts();
assert(getIDocumentLayoutAccess().GetCurrentLayout() && "SpellAgain: Where's my RootFrame?"); if( bInvalid )
{ for ( auto aLayout : aAllLayouts )
{
aLayout->AllInvalidateSmartTagsOrSpelling(bSmartTags);
aLayout->SetNeedGrammarCheck(true);
} if ( bSmartTags )
GetNodes().ForEach( lcl_CheckSmartTagsAgain, &bOnlyWrong );
GetNodes().ForEach( lcl_SpellAndGrammarAgain, &bOnlyWrong );
}
for ( auto aLayout : aAllLayouts )
aLayout->SetIdleFlags();
}
/// Iterate over all SwFormatINetFormat, if the function returns false, iteration is stopped void SwDoc::ForEachINetFormat( const std::function<bool(const SwFormatINetFormat&)>& rFunc ) const
{
SwNodeOffset nCount = GetNodes().Count(); for (SwNodeOffset i(0); i < nCount; ++i)
{
SwNode* pNode = GetNodes()[i]; if (!pNode->IsTextNode()) continue;
SwTextNode* pTextNode = pNode->GetTextNode(); if (!pTextNode->HasHints()) continue;
SwpHints& rHints = pTextNode->GetSwpHints(); for (size_t j = 0; j < rHints.Count(); ++j)
{ const SwTextAttr* pTextAttr = rHints.Get(j); if (pTextAttr->Which() != RES_TXTATR_INETFMT) continue; const SwFormatINetFormat& rFormat = pTextAttr->GetINetFormat(); if (!rFunc(rFormat)) return;
}
}
}
/// Iterate over all SwFormatURL, if the function returns false, iteration is stopped void SwDoc::ForEachFormatURL( const std::function<bool(const SwFormatURL&)>& rFunc ) const
{ for(sw::SpzFrameFormat* pSpz : *GetSpzFrameFormats())
{ if (pSpz->Which() != RES_FLYFRMFMT) continue; auto pFormat = static_cast<SwFlyFrameFormat*>(pSpz); const SwFormatURL& rURLItem = pFormat->GetURL(); if (!rFunc(rURLItem)) return;
}
}
namespace
{ /// Iterate over all pool item of type T, if the function returns false, iteration is stopped template<typename T> void ForEachCharacterItem(const SwDoc* pDoc, TypedWhichId<T> nWhich, const std::function<bool(const T&)>& rFunc )
{ for(SwCharFormat* pFormat : *pDoc->GetCharFormats())
{ const SwAttrSet& rAttrSet = pFormat->GetAttrSet(); if (const T* pColorItem = rAttrSet.GetItemIfSet(nWhich)) if (!rFunc(*pColorItem)) return;
}
std::vector<std::shared_ptr<SfxItemSet>> aStyles; for (auto eFamily : { IStyleAccess::AUTO_STYLE_CHAR, IStyleAccess::AUTO_STYLE_RUBY, IStyleAccess::AUTO_STYLE_PARA, IStyleAccess::AUTO_STYLE_NOTXT })
{ const_cast<SwDoc*>(pDoc)->GetIStyleAccess().getAllStyles(aStyles, eFamily); for (constauto & rxItemSet : aStyles) if (const T* pColorItem = rxItemSet->GetItemIfSet(nWhich)) if (!rFunc(*pColorItem)) return;
}
}
}
/// Iterate over all SwFormatURL, if the function returns false, iteration is stopped void SwDoc::ForEachCharacterBoxItem( const std::function<bool(const SvxBoxItem&)>& rFunc ) const
{
ForEachCharacterItem(this, RES_CHRATR_BOX, rFunc);
}
/// Iterate over all SvxColorItem, if the function returns false, iteration is stopped void SwDoc::ForEachCharacterColorItem( const std::function<bool(const SvxColorItem&)>& rFunc ) const
{
ForEachCharacterItem(this, RES_CHRATR_COLOR, rFunc);
}
/// Iterate over all SvxUnderlineItem, if the function returns false, iteration is stopped void SwDoc::ForEachCharacterUnderlineItem( const std::function<bool(const SvxUnderlineItem&)>& rFunc ) const
{
ForEachCharacterItem(this, RES_CHRATR_UNDERLINE, rFunc);
}
/// Iterate over all RES_CHRATR_BACKGROUND SvxBrushItem, if the function returns false, iteration is stopped void SwDoc::ForEachCharacterBackgroundBrushItem( const std::function<bool(const SvxBrushItem&)>& rFunc ) const
{
ForEachCharacterItem(this, RES_CHRATR_BACKGROUND, rFunc);
}
/// Iterate over all RES_CHRATR_HIGHLIGHT SvxBrushItem, if the function returns false, iteration is stopped void SwDoc::ForEachCharacterHighlightBrushItem( const std::function<bool(const SvxBrushItem&)>& rFunc ) const
{
ForEachCharacterItem(this, RES_CHRATR_HIGHLIGHT, rFunc);
}
/// Iterate over all RES_TXTATR_UNKNOWN_CONTAINER SvXMLAttrContainerItem, if the function returns false, iteration is stopped void SwDoc::ForEachTxtAtrContainerItem(const std::function<bool(const SvXMLAttrContainerItem&)>& rFunc ) const
{
SwNodeOffset nCount = GetNodes().Count(); for (SwNodeOffset i(0); i < nCount; ++i)
{
SwNode* pNode = GetNodes()[i]; if (!pNode->IsTextNode()) continue;
SwTextNode* pTextNode = pNode->GetTextNode(); if (!pTextNode->HasHints()) continue;
SwpHints& rHints = pTextNode->GetSwpHints(); for (size_t j = 0; j < rHints.Count(); ++j)
{ const SwTextAttr* pTextAttr = rHints.Get(j); if (pTextAttr->Which() != RES_TXTATR_AUTOFMT) continue; const SwFormatAutoFormat& rFmt = pTextAttr->GetAutoFormat(); if (const SvXMLAttrContainerItem* pItem = rFmt.GetStyleHandle()->GetItemIfSet(RES_TXTATR_UNKNOWN_CONTAINER)) if (!rFunc(*pItem)) return;
}
}
}
/// Iterate over all RES_CHRATR_FONT/RES_CHRATR_CJK_FONT/RES_CHRATR_CTL_FONT SvxFontItem, if the function returns false, iteration is stopped void SwDoc::ForEachCharacterFontItem(TypedWhichId<SvxFontItem> nWhich, bool bIgnoreAutoStyles, const std::function<bool(const SvxFontItem&)>& rFunc )
{
assert(nWhich == RES_CHRATR_FONT || nWhich == RES_CHRATR_CJK_FONT || nWhich == RES_CHRATR_CTL_FONT); for(const SwCharFormat* pFormat : *GetCharFormats())
{ const SwAttrSet& rAttrSet = pFormat->GetAttrSet(); if (const SvxFontItem* pItem = rAttrSet.GetItemIfSet(nWhich)) if (!rFunc(*pItem)) return;
} for(const SwTextFormatColl* pFormat : *GetTextFormatColls())
{ const SwAttrSet& rAttrSet = pFormat->GetAttrSet(); if (const SvxFontItem* pItem = rAttrSet.GetItemIfSet(nWhich)) if (!rFunc(*pItem)) return;
}
SwNodeOffset nCount = GetNodes().Count(); for (SwNodeOffset i(0); i < nCount; ++i)
{ const SwNode* pNode = GetNodes()[i]; if (pNode->IsContentNode())
{ const SwContentNode* pTextNode = pNode->GetContentNode(); if (pTextNode->HasSwAttrSet()) if (const SvxFontItem* pItem = pTextNode->GetSwAttrSet().GetItemIfSet(nWhich)) if (!rFunc(*pItem)) return;
}
} // ignore auto styles when called from the code that is constructing the auto style pool if (!bIgnoreAutoStyles)
{ // auto styles
std::vector<std::shared_ptr<SfxItemSet>> aStyles;
GetIStyleAccess().getAllStyles(aStyles, IStyleAccess::AUTO_STYLE_CHAR); for (constauto & rxItemSet : aStyles) if (const SvxFontItem* pItem = rxItemSet->GetItemIfSet(nWhich)) if (!rFunc(*pItem)) return;
}
}
/// Iterate over all RES_PARATR_TABSTOP SvxTabStopItem, if the function returns false, iteration is stopped void SwDoc::ForEachParaAtrTabStopItem(const std::function<bool(const SvxTabStopItem&)>& rFunc )
{
SwNodeOffset nCount = GetNodes().Count(); for (SwNodeOffset i(0); i < nCount; ++i)
{ const SwNode* pNode = GetNodes()[i]; if (pNode->IsContentNode())
{ const SwContentNode* pTextNode = pNode->GetContentNode(); if (pTextNode->HasSwAttrSet()) if (const SvxTabStopItem* pItem = pTextNode->GetSwAttrSet().GetItemIfSet(RES_PARATR_TABSTOP)) if (!rFunc(*pItem)) return;
}
} for(const SwTextFormatColl* pFormat : *GetTextFormatColls())
{ const SwAttrSet& rAttrSet = pFormat->GetAttrSet(); if (const SvxTabStopItem* pItem = rAttrSet.GetItemIfSet(RES_PARATR_TABSTOP)) if (!rFunc(*pItem)) return;
}
}
/// Iterate over all RES_UNKNOWNATR_CONTAINER SvXMLAttrContainerItem, if the function returns false, iteration is stopped void SwDoc::ForEachUnknownAtrContainerItem(const std::function<bool(const SvXMLAttrContainerItem&)>& rFunc ) const
{ for(SwFrameFormat* pFormat : *GetFrameFormats())
{ const SwAttrSet& rAttrSet = pFormat->GetAttrSet(); if (const SvXMLAttrContainerItem* pItem = rAttrSet.GetItemIfSet(RES_UNKNOWNATR_CONTAINER)) if (!rFunc(*pItem)) return;
}
}
/// Iterate over all RES_BOX SvxBoxItem, if the function returns false, iteration is stopped void SwDoc::ForEachBoxItem(const std::function<bool(const SvxBoxItem&)>& rFunc ) const
{
SwNodeOffset nCount = GetNodes().Count(); for (SwNodeOffset i(0); i < nCount; ++i)
{ const SwNode* pNode = GetNodes()[i]; if (pNode->IsContentNode())
{ const SwContentNode* pTextNode = pNode->GetContentNode(); if (pTextNode->HasSwAttrSet()) if (const SvxBoxItem* pItem = pTextNode->GetSwAttrSet().GetItemIfSet(RES_BOX)) if (!rFunc(*pItem)) return;
}
}
}
/// Iterate over all RES_SHADOW SvxBoxItem, if the function returns false, iteration is stopped void SwDoc::ForEachShadowItem(const std::function<bool(const SvxShadowItem&)>& rFunc ) const
{
SwNodeOffset nCount = GetNodes().Count(); for (SwNodeOffset i(0); i < nCount; ++i)
{ const SwNode* pNode = GetNodes()[i]; if (pNode->IsContentNode())
{ const SwContentNode* pTextNode = pNode->GetContentNode(); if (pTextNode->HasSwAttrSet()) if (const SvxShadowItem* pItem = pTextNode->GetSwAttrSet().GetItemIfSet(RES_SHADOW)) if (!rFunc(*pItem)) return;
}
}
}
/// Iterate over all RES_BACKGROUND SvxBrushItem, if the function returns false, iteration is stopped void SwDoc::ForEachBackgroundBrushItem(const std::function<bool(const SvxBrushItem&)>& rFunc ) const
{
SwNodeOffset nCount = GetNodes().Count(); for (SwNodeOffset i(0); i < nCount; ++i)
{ const SwNode* pNode = GetNodes()[i]; if (!pNode->IsTableNode()) continue; const SwTableNode* pTableNode = pNode->GetTableNode(); const SwTable& rTable = pTableNode->GetTable(); if (const SwTableFormat* pFormat = rTable.GetFrameFormat())
{ const SwAttrSet& rAttrSet = pFormat->GetAttrSet(); if (const SvxBrushItem* pItem = rAttrSet.GetItemIfSet(RES_BACKGROUND)) if (!rFunc(*pItem)) return;
} for (const SwTableLine* pTableLine : rTable.GetTabLines())
{ if (const SwTableLineFormat* pFormat = pTableLine->GetFrameFormat())
{ const SwAttrSet& rAttrSet = pFormat->GetAttrSet(); if (const SvxBrushItem* pItem = rAttrSet.GetItemIfSet(RES_BACKGROUND)) if (!rFunc(*pItem)) return;
} for (const SwTableBox* pTableBox : pTableLine->GetTabBoxes()) if (SwTableBoxFormat* pFormat = pTableBox->GetFrameFormat())
{ const SwAttrSet& rAttrSet = pFormat->GetAttrSet(); if (const SvxBrushItem* pItem = rAttrSet.GetItemIfSet(RES_BACKGROUND)) if (!rFunc(*pItem)) return;
}
}
}
}
// Remove hidden paragraph or delete contents: // Delete contents if // 1. removing the paragraph would result in an empty section or // 2. if the paragraph is the last paragraph in the section and // there is no paragraph in front of the paragraph: if ((SwNodeOffset(2) == pTextNd->EndOfSectionIndex() - pTextNd->StartOfSectionIndex())
|| (SwNodeOffset(1) == pTextNd->EndOfSectionIndex() - pTextNd->GetIndex()
&& !pTextNd->GetNodes()[pTextNd->GetIndex() - 1]->GetTextNode()))
{
xOperations.DeleteRange(aPam);
} else
{
aPam.DeleteMark();
xOperations.DelFullPara(aPam);
}
} // Returns if the data was actually modified bool HandleHidingField(SwFormatField& rFormatField, const SwNodes& rNodes,
IDocumentContentOperations& xOperations)
{ if( !rFormatField.GetTextField() ) returnfalse;
SwTextNode* pTextNd = rFormatField.GetTextField()->GetpTextNode(); if( pTextNd
&& pTextNd->GetpSwpHints() && pTextNd->IsHiddenByParaField()
&& &pTextNd->GetNodes() == &rNodes)
{
RemoveOrDeleteContents(pTextNd, xOperations); returntrue;
} returnfalse;
}
}
// The greater the returned value, the more weight has this field type on deciding the final // paragraph state int SwDoc::FieldCanHideParaWeight(SwFieldIds eFieldId) const
{ switch (eFieldId)
{ case SwFieldIds::HiddenPara: return 20; case SwFieldIds::Database: return GetDocumentSettingManager().get(DocumentSettingId::EMPTY_DB_FIELD_HIDES_PARA)
? 10
: 0; default: return 0;
}
}
/// Remove the invisible content from the document e.g. hidden areas, hidden paragraphs // Returns if the data was actually modified bool SwDoc::RemoveInvisibleContent()
{ bool bRet = false;
GetIDocumentUndoRedo().StartUndo( SwUndoId::UI_DELETE_INVISIBLECNTNT, nullptr );
{ // Removing some nodes for one SwFieldIds::Database type might remove the type from // document's field types, invalidating iterators. So, we need to create own list of // matching types prior to processing them.
std::vector<sw::WeakBroadcastingPtr<SwFieldType>> aHidingFieldTypes; for (std::unique_ptr<SwFieldType> const & pType : *getIDocumentFieldsAccess().GetFieldTypes())
{ if (FieldCanHideParaWeight(pType->Which()))
aHidingFieldTypes.push_back(pType.get());
} for (constauto& pWeakType : aHidingFieldTypes)
{ if (pWeakType)
{
std::vector<SwFormatField*> vFields;
pWeakType->GatherFields(vFields); for(auto pFormatField: vFields)
bRet |= HandleHidingField(*pFormatField, GetNodes(), getIDocumentContentOperations());
}
}
}
// Remove any hidden paragraph (hidden text attribute) for( SwNodeOffset n = GetNodes().Count(); n; )
{
SwTextNode* pTextNd = GetNodes()[ --n ]->GetTextNode(); if ( pTextNd )
{ bool bRemoved = false; if ( pTextNd->HasHiddenCharAttribute( true ) )
{
bRemoved = true;
bRet = true;
// Footnotes/Frames may have been removed, therefore we have // to reset n: if ( bRemoved )
{ // [n] has to be inside [0 .. GetNodes().Count()] range if (n > GetNodes().Count())
n = GetNodes().Count();
}
}
}
{ // Delete/empty all hidden areas
o3tl::sorted_vector<SwSectionFormat*> aSectFormats;
SwSectionFormats& rSectFormats = GetSections();
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.