/// Get current table of contents Mark.
sal_uInt16 SwDoc::GetCurTOXMark( const SwPosition& rPos,
SwTOXMarks& rArr )
{ // search on Position rPos for all SwTOXMarks
SwTextNode *const pTextNd = rPos.GetNode().GetTextNode(); if( !pTextNd || !pTextNd->GetpSwpHints() ) return0;
for(SwTOXMark* pTOXMark : aMarks)
{ // Item PtrCompare needed here if (areSfxPoolItemPtrsEqual( pTOXMark, &rCurTOXMark )) continue;
pMark = pTOXMark->GetTextTOXMark(); if (!pMark) continue;
SwTextNode const*const pTOXSrc = pMark->GetpTextNd(); if (!pTOXSrc) continue;
Point aPt;
std::pair<Point, bool> const tmp(aPt, false); const SwContentFrame* pCFrame = pTOXSrc->getLayoutFrame(
getIDocumentLayoutAccess().GetCurrentLayout(), nullptr, &tmp); if (!pCFrame) continue;
if ( bInReadOnly || !pCFrame->IsProtected() )
{
CompareNodeContent aAbsNew( pTOXSrc->GetIndex(), pMark->GetStart() ); switch( eDir )
{ // The following (a bit more complicated) statements make it // possible to also travel across Entries on the same (!) // position. If someone has time, please feel free to optimize. case TOX_SAME_PRV: if (pTOXMark->GetText(nullptr) != rCurTOXMark.GetText(nullptr)) break;
[[fallthrough]]; case TOX_PRV: if ( (aAbsNew < aAbsIdx && aAbsNew > aPrevPos) ||
(aAbsIdx == aAbsNew &&
(reinterpret_cast<sal_uLong>(&rCurTOXMark) > reinterpret_cast<sal_uLong>(pTOXMark) &&
(!pNew || aPrevPos < aAbsIdx || reinterpret_cast<sal_uLong>(pNew) < reinterpret_cast<sal_uLong>(pTOXMark) ) )) ||
(aPrevPos == aAbsNew && aAbsIdx != aAbsNew && reinterpret_cast<sal_uLong>(pTOXMark) > reinterpret_cast<sal_uLong>(pNew)) )
{
pNew = pTOXMark;
aPrevPos = aAbsNew; if ( aAbsNew >= aMax )
{
aMax = aAbsNew;
pMax = pTOXMark;
}
} break;
// We couldn't find a successor // Use minimum or maximum if(!pNew)
{ switch(eDir)
{ case TOX_PRV: case TOX_SAME_PRV:
pNew = pMax; break; case TOX_NXT: case TOX_SAME_NXT:
pNew = pMin; break; default:
pNew = &rCurTOXMark;
}
} return *pNew;
}
if( bExpand )
{ // add value for 2nd parameter = true to // indicate, that a creation of a new table of content has to be performed. // Value of 1st parameter = default value.
pNewSection->Update( nullptr, pLayout, true );
} elseif( rTOX.GetTitle().getLength()==1 && IsInReading() ) // insert title of TOX
{ // then insert the headline section
SwNodeIndex aIdx( *pSectNd, +1 );
SwTOXBaseSection *const pNewSection( dynamic_cast<SwTOXBaseSection*>(& pNewSectionNode->GetSection())); if (pNewSection)
pNewSection->SetTOXName(sSectNm); // rTOX may have had no name...
}
/// Get current table of contents
SwTOXBase* SwDoc::GetCurTOX( const SwPosition& rPos )
{
SwNode& rNd = rPos.GetNode();
SwSectionNode* pSectNd = rNd.FindSectionNode(); while( pSectNd )
{
SectionType eT = pSectNd->GetSection().GetType(); if( SectionType::ToxContent == eT )
{
assert( dynamic_cast< const SwTOXBaseSection *>( &pSectNd->GetSection()) && "no TOXBaseSection!" );
SwTOXBaseSection& rTOXSect = static_cast<SwTOXBaseSection&>(
pSectNd->GetSection()); return &rTOXSect;
}
pSectNd = pSectNd->StartOfSectionNode()->FindSectionNode();
} return nullptr;
}
const SwTOXBase* SwDoc::GetDefaultTOXBase( TOXTypes eTyp, bool bCreate )
{
std::unique_ptr<SwTOXBase>* prBase = nullptr; switch(eTyp)
{ case TOX_CONTENT: prBase = &mpDefTOXBases->pContBase; break; case TOX_INDEX: prBase = &mpDefTOXBases->pIdxBase; break; case TOX_USER: prBase = &mpDefTOXBases->pUserBase; break; case TOX_TABLES: prBase = &mpDefTOXBases->pTableBase; break; case TOX_OBJECTS: prBase = &mpDefTOXBases->pObjBase; break; case TOX_ILLUSTRATIONS: prBase = &mpDefTOXBases->pIllBase; break; case TOX_AUTHORITIES: prBase = &mpDefTOXBases->pAuthBase; break; case TOX_BIBLIOGRAPHY: prBase = &mpDefTOXBases->pBiblioBase; break; case TOX_CITATION: /** TODO */break;
} if (!prBase) return nullptr; if(!(*prBase) && bCreate)
{
SwForm aForm(eTyp); const SwTOXType* pType = GetTOXType(eTyp, 0);
prBase->reset(new SwTOXBase(pType, aForm, SwTOXElement::NONE, pType->GetTypeName()));
} return prBase->get();
}
void SwDoc::SetDefaultTOXBase(const SwTOXBase& rBase)
{
std::unique_ptr<SwTOXBase>* prBase = nullptr; switch(rBase.GetType())
{ case TOX_CONTENT: prBase = &mpDefTOXBases->pContBase; break; case TOX_INDEX: prBase = &mpDefTOXBases->pIdxBase; break; case TOX_USER: prBase = &mpDefTOXBases->pUserBase; break; case TOX_TABLES: prBase = &mpDefTOXBases->pTableBase; break; case TOX_OBJECTS: prBase = &mpDefTOXBases->pObjBase; break; case TOX_ILLUSTRATIONS: prBase = &mpDefTOXBases->pIllBase; break; case TOX_AUTHORITIES: prBase = &mpDefTOXBases->pAuthBase; break; case TOX_BIBLIOGRAPHY: prBase = &mpDefTOXBases->pBiblioBase; break; case TOX_CITATION: /** TODO */break;
} if (!prBase) return;
prBase->reset(new SwTOXBase(rBase));
}
/// Delete table of contents bool SwDoc::DeleteTOX( const SwTOXBase& rTOXBase, bool bDelNodes )
{ // We only delete the TOX, not the Nodes bool bRet = false;
assert( dynamic_cast<const SwTOXBaseSection*>( &rTOXBase) && "no TOXBaseSection!" );
const SwTOXBaseSection& rTOXSect = static_cast<const SwTOXBaseSection&>(rTOXBase);
SwSectionFormat const * pFormat = rTOXSect.GetFormat(); /* Save the start node of the TOX' section. */
SwSectionNode const * pMyNode = pFormat ? pFormat->GetSectionNode() : nullptr; if (pMyNode)
{
GetIDocumentUndoRedo().StartUndo( SwUndoId::CLEARTOXRANGE, nullptr );
/* Save start node of section's surrounding. */
SwNode const * pStartNd = pMyNode->StartOfSectionNode();
/* Look for the point where to move the cursors in the area to deleteto.Thisisdonebyfirstsearchingforwardfromthe endoftheTOX'section.Ifnocontentnodeisfoundbehind theTOXoneissearchedbeforeit.Ifthisisnot successful,too,insertnewtextnodebehindtheendof theTOX'section.ThecursorsfromtheTOX'sectionwillbe
moved to the content node found or the new text node. */
/* Set PaM to end of TOX' section and search following content node. aSearchPamwillcontainthepointwheretomovethecursors
to. */
SwPaM aSearchPam(*pMyNode->EndOfSectionNode());
SwPosition aEndPos(*pStartNd->EndOfSectionNode()); if (! aSearchPam.Move() /* no content node found */
|| *aSearchPam.GetPoint() >= aEndPos /* content node found
outside surrounding */
)
{ /* Set PaM to beginning of TOX' section and search previous
content node */
SwPaM aTmpPam(*pMyNode);
aSearchPam = aTmpPam;
SwPosition aStartPos(*pStartNd);
if ( ! aSearchPam.Move(fnMoveBackward) /* no content node found */
|| *aSearchPam.GetPoint() <= aStartPos /* content node foundoutside
surrounding */
)
{ /* There is no content node in the surrounding of
TOX'. Append text node behind TOX' section. */
for( auto pSectionFormat : *mpSectionFormatTable )
{ const SwSectionNode *pSectNd = pSectionFormat->GetSectionNode(); if ( !pSectNd ) continue;
const SwSection& rSect = pSectNd->GetSection(); if (rSect.GetType()==SectionType::ToxContent)
{ const UIName& rNm = rSect.GetSectionName(); if ( rNm.toString().startsWith(aName) )
{ // Calculate number and set the Flag
sal_Int32 nNum = o3tl::toInt32(rNm.toString().subView(nNmLen)) - 1; if (nNum >= 0 && o3tl::make_unsigned(nNum) < mpSectionFormatTable->size())
pSetFlags[ nNum / 8 ] |= (0x01 << ( nNum & 0x07 ));
} if ( bUseChkStr && sChkStr==rNm )
bUseChkStr = false;
}
}
if (bUseChkStr) return sChkStr;
// All Numbers have been flagged accordingly, so get the right Number
SwSectionFormats::size_type nNum = mpSectionFormatTable->size(); for( SwSectionFormats::size_type n = 0; n < nFlagSize; ++n )
{
sal_uInt8 nTmp = pSetFlags[ n ]; if( nTmp != 0xff )
{ // so get the Number
nNum = n * 8; while( nTmp & 1 )
{
++nNum;
nTmp >>= 1;
} break;
}
} return aName + OUString::number( ++nNum );
}
// tdf#153636 - search for outline node only if the index is for the current chapter if (bIsFromChapter) // tdf#151462 - search for outline node containing the current node return pNd->FindOutlineNodeOfLevel(pNd->GetSectionLevel() - 1, pLayout);
}
} return pNd->FindOutlineNodeOfLevel(nLvl, pLayout);
}
// Check if the one asking doesn't precede the page of the specified chapter note
bIsHeadingContained
= pNdFrame && pChptrPgFrame
&& pChptrPgFrame->getFrameArea().Top() <= pNdFrame->getFrameArea().Top(); // Check if the one asking doesn't succeed the specified chapter note if (bIsHeadingContained)
{ const SwNode* aChptrNd = pChptrNd; if (!rONds.Seek_Entry(aChptrNd, &nPos) && nPos)
nPos--; // Search for the next outline node with a larger level than the specified chapter node while (nPos < rONds.size() - 1
&& pChptrNd->GetAttrOutlineLevel()
< rONds[nPos + 1]->GetTextNode()->GetAttrOutlineLevel())
nPos++; // If there exists such an outline node, check if the one asking doesn't succeed // the specified chapter node if (nPos < rONds.size() - 1) {
nPos++; constauto aONdsTxtNd = rONds[nPos]->GetTextNode();
pChptrFrame = aONdsTxtNd->getLayoutFrame(
aONdsTxtNd->GetDoc().getIDocumentLayoutAccess().GetCurrentLayout(), nullptr,
&tmp);
pChptrPgFrame = pChptrFrame ? pChptrFrame->FindPageFrame() : nullptr;
bIsHeadingContained
= pNdFrame && pChptrPgFrame
&& pChptrPgFrame->getFrameArea().Top() >= pNdFrame->getFrameArea().Top();
}
}
} else
{ // Search for the next outline node which lies not within the current chapter node while (nPos > 0
&& pChptrNd->GetAttrOutlineLevel()
< rONds[nPos]->GetTextNode()->GetAttrOutlineLevel())
nPos--;
bIsHeadingContained = pChptrNd == rONds[nPos]->GetTextNode();
}
} else
{ // If there are no outline nodes, consider the heading contained, // otherwise the _XDocumentIndex._update() test fails
bIsHeadingContained = true;
} return bIsHeadingContained;
}
// get current Language
SwTOXInternational aIntl( GetLanguage(),
TOX_INDEX == GetTOXType()->GetType() ?
GetOptions() : SwTOIOptions::NONE,
GetSortAlgorithm() );
m_aSortArr.clear();
// find the first layout node for this TOX, if it only find the content // in his own chapter const SwSectionNode* pChapterSectNd = IsFromChapter() ? pSectNd->FindSectionNode() : nullptr; const SwTextNode* pOwnChapterNode = pChapterSectNd
? ::lcl_FindChapterNode( *pSectNd, pLayout, pChapterSectNd->GetSectionLevel() + 1 )
: nullptr;
if (rDoc.GetIDocumentUndoRedo().DoesUndo())
{ // note: this will first append a SwUndoDelSection from the ctor...
pUndo = new SwUndoUpdateIndex(*this); // tdf#123313 insert Undo *after* all CrossRefBookmark Undos have // been inserted by the Update*() functions
rDoc.GetIDocumentUndoRedo().AppendUndo(std::unique_ptr<SwUndoUpdateIndex>(pUndo));
} else
{
--aEndIdx;
SwPosition aPos( aEndIdx, pFirstEmptyNd, 0 );
SwDoc::CorrAbs( aSttIdx, aEndIdx, aPos, true );
// delete flys in whole range including start node which requires // giving the node before start node as Mark parameter, hence -1. // (flys must be deleted because the anchor nodes are removed)
DelFlyInRange( SwNodeIndex(aSttIdx, -1).GetNode(), aEndIdx.GetNode() );
// Generate: Evaluate Form and insert the place holder for the // page number. If it is a TOX_INDEX and the SwForm IsCommaSeparated() // then a range of entries must be generated into one paragraph
size_t nRange = 1; if(TOX_INDEX == SwTOXBase::GetType() &&
GetTOXForm().IsCommaSeparated() &&
m_aSortArr[nCnt]->GetType() == TOX_SORT_INDEX)
{ const SwTOXMark& rMark = m_aSortArr[nCnt]->pTextMark->GetTOXMark(); const OUString& sPrimKey = rMark.GetPrimaryKey(); const OUString& sSecKey = rMark.GetSecondaryKey(); const SwTOXMark* pNextMark = nullptr; while(m_aSortArr.size() > (nCnt + nRange) &&
m_aSortArr[nCnt + nRange]->GetType() == TOX_SORT_INDEX )
{
pNextMark = &(m_aSortArr[nCnt + nRange]->pTextMark->GetTOXMark()); if( !pNextMark ||
pNextMark->GetPrimaryKey() != sPrimKey ||
pNextMark->GetSecondaryKey() != sSecKey) break;
nRange++;
}
} // pass node index of table-of-content section and default page description // to method <GenerateText(..)>.
::SetProgressState( 0, rDoc.GetDocShell() );
// delete the first dummy node and remove all Cursor into the previous node
aInsPos = *pFirstEmptyNd;
{
SwPaM aCorPam( *pFirstEmptyNd ); if( !aCorPam.Move( fnMoveForward ) )
aCorPam.Move( fnMoveBackward );
SwNodeIndex aEndIdx( aInsPos, 1 );
SwDoc::CorrAbs( aInsPos, aEndIdx, *aCorPam.GetPoint(), true );
// Task 70995 - save and restore PageDesc and Break Attributes if( pFirstEmptyNd->HasSwAttrSet() )
{ if( !GetTitle().isEmpty() )
aEndIdx = *pSectNd; else
aEndIdx = *pFirstEmptyNd;
SwContentNode* pCNd = SwNodes::GoNext(&aEndIdx); if( pCNd ) // Robust against defect documents, e.g. i60336
pCNd->SetAttr( *pFirstEmptyNd->GetpSwAttrSet() );
}
}
// now create the new Frames
SwNodeOffset nIdx = pSectNd->GetIndex(); // don't delete if index is empty if(nIdx + SwNodeOffset(2) < pSectNd->EndOfSectionIndex())
rDoc.GetNodes().Delete( aInsPos );
aN2L.RestoreUpperFrames( rDoc.GetNodes(), nIdx, nIdx + 1 );
o3tl::sorted_vector<SwRootFrame*> aAllLayouts = rDoc.GetAllLayouts(); for ( constauto& rpLayout : aAllLayouts )
{
SwFrame::CheckPageDescs( static_cast<SwPageFrame*>(rpLayout->Lower()) );
} // delay setting tab stops until the layout frames exist, in case the ToX // is in columns or other non-body environment; best way is to check uppers // (what if columns have different widths? no idea what to do about that...) for (auto & it : tabStops)
{
std::vector<SvxTabStop> tabs; for (size_t i = 0; i < it.second.Count(); ++i)
{
tabs.emplace_back(it.second.At(i));
}
it.second.Remove(0, it.second.Count()); for (SvxTabStop & rTab : tabs)
{ if (rTab.GetAdjustment() == SvxTabAdjust::Right)
{
assert(rTab.GetTabPos() == 0);
rTab.GetTabPos() = pTabStopTokenHandler->CalcEndStop(*it.first, pLayout);
}
it.second.Insert(rTab);
}
it.first->SetAttr(it.second);
}
// Do we already have a Delimiter? if( !sDeli.isEmpty() && sLastDeli != sDeli )
{ // We skip all that are less than a small Blank (these are special characters) if( ' ' <= sDeli[0] )
{
std::unique_ptr<SwTOXCustom> pCst(
MakeSwTOXSortTabBase<SwTOXCustom>(nullptr,
TextAndReading(sDeli, OUString()),
FORM_ALPHA_DELIMITER,
rIntl, m_aSortArr[i]->GetLocale() ));
m_aSortArr.insert( m_aSortArr.begin() + i, std::move(pCst));
i++;
}
sLastDeli = sDeli;
}
// Skip until we get to the same or a lower Level do {
i++;
} while (i < m_aSortArr.size() && m_aSortArr[i]->GetLevel() > nLevel);
}
}
/// Evaluate Template
SwTextFormatColl* SwTOXBaseSection::GetTextFormatColl( sal_uInt16 nLevel )
{
SwDoc& rDoc = GetFormat()->GetDoc(); const UIName& rName = GetTOXForm().GetTemplate( nLevel );
SwTextFormatColl* pColl = !rName.isEmpty() ? rDoc.FindTextFormatCollByName(rName) :nullptr; if( !pColl )
{
sal_uInt16 nPoolFormat = 0; const TOXTypes eMyType = SwTOXBase::GetType(); switch( eMyType )
{ case TOX_INDEX: nPoolFormat = RES_POOLCOLL_TOX_IDXH; break; case TOX_USER: if( nLevel < 6 )
nPoolFormat = RES_POOLCOLL_TOX_USERH; else
nPoolFormat = RES_POOLCOLL_TOX_USER6 - 6; break; case TOX_ILLUSTRATIONS: nPoolFormat = RES_POOLCOLL_TOX_ILLUSH; break; case TOX_OBJECTS: nPoolFormat = RES_POOLCOLL_TOX_OBJECTH; break; case TOX_TABLES: nPoolFormat = RES_POOLCOLL_TOX_TABLESH; break; case TOX_AUTHORITIES: case TOX_BIBLIOGRAPHY:
nPoolFormat = RES_POOLCOLL_TOX_AUTHORITIESH; break; case TOX_CITATION: /** TODO */break; case TOX_CONTENT: // There's a jump in the ContentArea! if( nLevel < 6 )
nPoolFormat = RES_POOLCOLL_TOX_CNTNTH; else
nPoolFormat = RES_POOLCOLL_TOX_CNTNT6 - 6; break;
}
// Insert as sorted
std::vector<sal_uInt16>::size_type i; for( i = 0; i < aNums.size() && aNums[i] < nPage; ++i )
;
if( i >= aNums.size() || aNums[ i ] != nPage )
{
aNums.insert(aNums.begin() + i, nPage);
aDescs.insert(aDescs.begin() + i, pCurrentPage->GetPageDesc() );
} // is it a main entry? if(TOX_SORT_INDEX == pSortBase->GetType() &&
rTOXSource.bMainEntry)
{
aMainNums.push_back(nPage);
}
}
} // Insert the PageNumber into the TOC TextNode const SwTOXSortTabBase* pBase = m_aSortArr[ nCnt ].get(); if(pBase->pTOXNd)
{ const SwTextNode* pTextNd = pBase->pTOXNd->GetTextNode();
OSL_ENSURE( pTextNd, "no TextNode, wrong TOC" );
UpdatePageNum_( const_cast<SwTextNode*>(pTextNd), aNums, aDescs, &aMainNums,
aIntl );
}
}
} // Delete the mapping array after setting the right PageNumber
m_aSortArr.clear();
}
/// Replace the PageNumber place holders. Search for the page no. in the array /// of main entry page numbers. staticbool lcl_HasMainEntry( const std::vector<sal_uInt16>* pMainEntryNums, sal_uInt16 nToFind )
{ if (!pMainEntryNums) returnfalse;
for( auto nMainEntry : *pMainEntryNums ) if (nToFind == nMainEntry) returntrue; returnfalse;
}
void SwTOXBaseSection::UpdatePageNum_( SwTextNode* pNd, const std::vector<sal_uInt16>& rNums, const std::vector<SwPageDesc*>& rDescs, const std::vector<sal_uInt16>* pMainEntryNums, const SwTOXInternational& rIntl )
{ // collect starts end ends of main entry character style
std::optional< std::vector<sal_uInt16> > xCharStyleIdx; if (pMainEntryNums)
xCharStyleIdx.emplace();
std::vector<sal_uInt16>::size_type i; for( i = 1; i < rNums.size(); ++i)
{
SvxNumberType aType( rDescs[i]->GetNumType() ); if( TOX_INDEX == SwTOXBase::GetType() )
{ // Summarize for the following // Add up all following // break up if main entry starts or ends and // insert a char style index bool bMainEntryChanges = lcl_HasMainEntry(pMainEntryNums, nOld)
!= lcl_HasMainEntry(pMainEntryNums, rNums[i]);
if(nOld == rNums[i]-1 && !bMainEntryChanges &&
(GetOptions() & (SwTOIOptions::FF|SwTOIOptions::Dash)))
nCount++; else
{ // Flush for the following old values if(GetOptions() & SwTOIOptions::FF)
{ if ( nCount >= 1 )
aNumStr += rIntl.GetFollowingText( nCount > 1 );
} elseif (nCount) //#58127# If nCount == 0, then the only PageNumber is already in aNumStr!
{ if (nCount == 1 )
aNumStr += SwTOXMark::S_PAGE_DELI; else
aNumStr += "-";
aNumStr += aType.GetNumStr( nBeg + nCount );
}
// Create new String
nBeg = rNums[i];
aNumStr += SwTOXMark::S_PAGE_DELI; //the change of the character style must apply after sPageDeli is appended if (xCharStyleIdx && bMainEntryChanges)
{
xCharStyleIdx->push_back(aNumStr.getLength());
}
aNumStr += aType.GetNumStr( nBeg );
nCount = 0;
}
nOld = rNums[i];
} else
{ // Insert all Numbers
aNumStr += aType.GetNumStr( rNums[i] ); if (i+1 != rNums.size())
aNumStr += SwTOXMark::S_PAGE_DELI;
}
} // Flush when ending and the following old values if( TOX_INDEX == SwTOXBase::GetType() )
{ if(GetOptions() & SwTOIOptions::FF)
{ if( nCount >= 1 )
aNumStr += rIntl.GetFollowingText( nCount > 1 );
} else
{ if(nCount >= 2)
aNumStr += "-"; elseif(nCount == 1)
aNumStr += SwTOXMark::S_PAGE_DELI; //#58127# If nCount == 0, then the only PageNumber is already in aNumStr! if(nCount)
aNumStr += rDescs[i-1]->GetNumType().GetNumStr( nBeg+nCount );
}
}
pNd->InsertText( aNumStr, aPos, SwInsertFlags::EMPTYEXPAND | SwInsertFlags::FORCEHINTEXPAND ); if(pPageNoCharFormat)
{
SwFormatCharFormat aCharFormat( pPageNoCharFormat );
pNd->InsertItem(aCharFormat, nStartPos, nStartPos + aNumStr.getLength(), SetAttrMode::DONTEXPAND);
}
// The main entries should get their character style if (!xCharStyleIdx || xCharStyleIdx->empty() || GetMainEntryCharStyle().isEmpty()) return;
// eventually the last index must me appended if (xCharStyleIdx->size()&0x01)
xCharStyleIdx->push_back(aNumStr.getLength());
// find the page numbers in aNumStr and set the character style
sal_Int32 nOffset = pNd->GetText().getLength() - aNumStr.getLength();
SwFormatCharFormat aCharFormat(pCharFormat); for (size_t j = 0; j < xCharStyleIdx->size(); j += 2)
{
sal_Int32 nStartIdx = (*xCharStyleIdx)[j] + nOffset;
sal_Int32 nEndIdx = (*xCharStyleIdx)[j + 1] + nOffset;
pNd->InsertItem(aCharFormat, nStartIdx, nEndIdx, SetAttrMode::DONTEXPAND);
}
}
void SwTOXBaseSection::InsertSorted(std::unique_ptr<SwTOXSortTabBase> pNew)
{
Range aRange(0, m_aSortArr.size()); if( TOX_INDEX == SwTOXBase::GetType() && pNew->pTextMark )
{ const SwTOXMark& rMark = pNew->pTextMark->GetTOXMark(); // Evaluate Key // Calculate the range where to insert if( !(GetOptions() & SwTOIOptions::KeyAsEntry) &&
!rMark.GetPrimaryKey().isEmpty() )
{
aRange = GetKeyRange( rMark.GetPrimaryKey(),
rMark.GetPrimaryKeyReading(),
*pNew, FORM_PRIMARY_KEY, aRange );
if( !rMark.GetSecondaryKey().isEmpty() )
aRange = GetKeyRange( rMark.GetSecondaryKey(),
rMark.GetSecondaryKeyReading(),
*pNew, FORM_SECONDARY_KEY, aRange );
}
} // Search for identical entries and remove the trailing one if(TOX_AUTHORITIES == SwTOXBase::GetType())
{ for(short i = static_cast<short>(aRange.Min()); i < static_cast<short>(aRange.Max()); ++i)
{
SwTOXSortTabBase* pOld = m_aSortArr[i].get(); if (pOld->equivalent(*pNew))
{ if (pOld->sort_lt(*pNew))
{ return;
} else
{ // remove the old content
m_aSortArr.erase( m_aSortArr.begin() + i );
aRange.Max()--; break;
}
}
}
}
// find position and insert
tools::Long i;
for( i = aRange.Min(); i < aRange.Max(); ++i)
{ // Only check for same level
SwTOXSortTabBase* pOld = m_aSortArr[i].get(); if (pOld->equivalent(*pNew))
{ if(TOX_AUTHORITIES != SwTOXBase::GetType())
{ // Own entry for double entries or keywords if( pOld->GetType() == TOX_SORT_CUSTOM &&
SwTOXSortTabBase::GetOptions() & SwTOIOptions::KeyAsEntry) continue;
if(!(SwTOXSortTabBase::GetOptions() & SwTOIOptions::SameEntry))
{ // Own entry
m_aSortArr.insert(m_aSortArr.begin() + i, std::move(pNew)); return;
} // If the own entry is already present, add it to the references list
pOld->aTOXSources.push_back(pNew->aTOXSources[0]);
return;
} #if OSL_DEBUG_LEVEL > 0 else
OSL_FAIL("Bibliography entries cannot be found here"); #endif
} if (pNew->sort_lt(*pOld)) break;
} // Skip SubLevel while( TOX_INDEX == SwTOXBase::GetType() && i < aRange.Max() &&
m_aSortArr[i]->GetLevel() > pNew->GetLevel() )
i++;
// Insert at position i
m_aSortArr.insert(m_aSortArr.begin()+i, std::move(pNew));
}
/// Find Key Range and insert if possible
Range SwTOXBaseSection::GetKeyRange(const OUString& rStr, const OUString& rStrReading, const SwTOXSortTabBase& rNew,
sal_uInt16 nLevel, const Range& rRange )
{ const SwTOXInternational& rIntl = *rNew.pTOXIntl;
TextAndReading aToCompare(rStr, rStrReading);
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.