/* -*- 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 .
*/
// just incredibly slow to do this if (comphelper::IsFuzzing()) return;
// Just in case we remove a node after we have marked the rule invalid, but before we have validated the tree if (mbInvalidRuleFlag)
{
SwList* pList = rTextNode.GetDoc().getIDocumentListsAccess().getListByName( rTextNode.GetListId() ); if (pList)
pList->InvalidateListTree();
}
}
// #i22362# bool SwNumFormat::IsEnumeration() const
{ // #i30655# native numbering did not work any longer // using this code. Therefore HBRINKM and I agreed upon defining // IsEnumeration() as !IsItemize() return !IsItemize();
}
void SwNumFormat::SwClientNotify(const SwModify&, const SfxHint& rHint)
{ if (rHint.GetId() == SfxHintId::SwFormatChange)
{ // Look for the NumRules object in the Doc where this NumFormat is set. // The format does not need to exist! const SwCharFormat* pFormat = GetCharFormat(); if(pFormat && !pFormat->GetDoc().IsInDtor())
UpdateNumNodes(const_cast<SwDoc&>(pFormat->GetDoc()));
} elseif (rHint.GetId() == SfxHintId::SwAttrSetChange)
{ // Look for the NumRules object in the Doc where this NumFormat is set. // The format does not need to exist! const SwCharFormat* pFormat = GetCharFormat();
namespace { /// Strip out text that is not a delimiter. Used in STYLEREF for when you /// have chapters labelled "Chapter X.Y" and want to just keep the "X.Y" /// Only used on the prefix/infix/suffix, so the numbers are not modified void StripNonDelimiter(OUString& rText)
{
std::vector<sal_Unicode> charactersToKeep;
for (int i = 0; i < rText.getLength(); i++) { auto character = rText[i];
// tdf#86790# for Word compatibility: I haven't found any better way to determine whether a // character is a delimiter than testing in Word and listing them out. Furthermore, I haven't // found a list so I can't be certain this is the complete set- if there's a compatibility issue // with this in the future, here's the first place to look... if (
character == '.'
|| character == ','
|| character == ':'
|| character == ';'
|| character == '-'
|| character == '('
|| character == ')'
|| character == '['
|| character == ']'
|| character == '{'
|| character == '}'
|| character == '/'
|| character == '\\'
|| character == '|'
)
charactersToKeep.push_back(character);
}
if (rMyNFormat.GetNumberingType() == SVX_NUM_NUMBER_NONE)
{ // since numbering is disabled for this level, // only emit prefix/suffix (unless they are not wanted either) if (!bInclStrings) return OUString();
// In this case we are ignoring GetIncludeUpperLevels: we put all // level numbers requested by level format for (sal_Int32 nPosition{0}; nPosition < sLevelFormat.getLength() - 2;)
{ if (sLevelFormat[nPosition] != '%')
{
++nPosition; continue;
}
SwNumberTree::tNumberVector::size_type nReplaceLevel;
decltype(nPosition) nEndPosition; if (sLevelFormat[nPosition+1] == '1'
&& sLevelFormat[nPosition+2] == '0'
&& (nPosition+3) < sLevelFormat.getLength()
&& sLevelFormat[nPosition+3] == '%')
{
nReplaceLevel = 9; // special case %10%
nEndPosition = nPosition + 4;
} elseif (sLevelFormat[nPosition+2] == '%'
&& '1' <= sLevelFormat[nPosition+1]
&& sLevelFormat[nPosition+1] <= '9')
{
nReplaceLevel = sLevelFormat[nPosition+1] - '1'; // need to subtract 1
nEndPosition = nPosition + 3;
} else
{
++nPosition; continue; // ignore it
} if (nLevel < nReplaceLevel)
{
nPosition = nEndPosition; // there is no number to insert - in this case Word 2013 continue; // shows no label at all, we just skip it
}
SwNumFormat const& rNFormat{Get(nReplaceLevel)};
if (rNFormat.GetNumberingType() == SVX_NUM_NUMBER_NONE)
{ // Numbering disabled - replacement is empty // And we should skip all level string content until next level marker: // so %1%.%2%.%3% with second level as NONE will result 1.1, not 1..1
// NOTE: if changed, fix MSWordExportBase::NumberingLevel to match new behaviour.
OUString sReplacement; if (rNumVector[nReplaceLevel])
sReplacement = rNFormat.GetNumStr(rNumVector[nReplaceLevel], aLocale, rMyNFormat.GetIsLegal()); else
sReplacement = "0"; // all 0 level are a 0
aStr = sLevelFormat;
} else
{ // Fallback case: level format is not defined // So use old way with levels joining by dot "."
SwNumberTree::tNumberVector::size_type i = nLevel;
if (!IsContinusNum() && // - do not include upper levels, if level isn't numbered.
rMyNFormat.GetNumberingType() != SVX_NUM_NUMBER_NONE &&
rMyNFormat.GetIncludeUpperLevels()) // Just the own level?
{
sal_uInt8 n = rMyNFormat.GetIncludeUpperLevels(); if (1 < n)
{ if (i + 1 >= n)
i -= n - 1; else
i = 0;
}
}
for (; i <= nLevel; ++i)
{ const SwNumFormat& rNFormat = Get(i); if (SVX_NUM_NUMBER_NONE == rNFormat.GetNumberingType())
{ // Should 1.1.1 --> 2. NoNum --> 1..1 or 1.1 ?? // if( i != rNum.nMyLevel ) // aStr += "."; continue;
}
if (rNumVector[i])
aStr.append(rNFormat.GetNumStr(rNumVector[i], aLocale, rMyNFormat.GetIsLegal())); else
aStr.append("0"); // all 0 level are a 0 if (i != nLevel && !aStr.isEmpty())
aStr.append(".");
}
// The type doesn't have any number, so don't append // the post-/prefix string if (bInclStrings &&
SVX_NUM_CHAR_SPECIAL != rMyNFormat.GetNumberingType() &&
SVX_NUM_BITMAP != rMyNFormat.GetNumberingType())
{
OUString sPrefix = rMyNFormat.GetPrefix();
OUString sSuffix = rMyNFormat.GetSuffix();
if (bHideNonNumerical) {
StripNonDelimiter(sPrefix);
StripNonDelimiter(sSuffix);
}
if ( bInclSuperiorNumLabels && pWorkingNodeNum->GetLevelInListTree() > 0 )
{
sal_uInt8 n = Get( o3tl::narrowing<sal_uInt16>(pWorkingNodeNum->GetLevelInListTree()) ).GetIncludeUpperLevels();
pWorkingNodeNum = dynamic_cast<SwNodeNum*>(pWorkingNodeNum->GetParent()); // skip parents, whose list label is already contained in the actual list label. while ( pWorkingNodeNum && n > 1 )
{
pWorkingNodeNum = dynamic_cast<SwNodeNum*>(pWorkingNodeNum->GetParent());
--n;
}
} else
{ break;
}
} while ( pWorkingNodeNum &&
pWorkingNodeNum->GetLevelInListTree() >= 0 &&
pWorkingNodeNum->GetLevelInListTree() >= nRestrictInclToThisLevel );
}
if (aRefNumStr.endsWith("."))
{ // tdf#144563: looks like a special case for refs by MS Word: if numbering is ending with dot, this dot is removed
aRefNumStr = aRefNumStr.copy(0, aRefNumStr.getLength() - 1);
}
A kind of copy constructor, so that the num formats are attached to the right CharFormats of a Document.
Copies the NumFormats and returns itself. */
SwNumRule& SwNumRule::CopyNumRule( SwDoc& rDoc, const SwNumRule& rNumRule )
{ for( sal_uInt16 n = 0; n < MAXLEVEL; ++n )
{
Set( n, rNumRule.maFormats[ n ].get() ); if( maFormats[ n ] && maFormats[ n ]->GetCharFormat() &&
!rDoc.GetCharFormats()->ContainsFormat(maFormats[n]->GetCharFormat()))
{ // If we copy across different Documents, then copy the // corresponding CharFormat into the new Document.
maFormats[n]->SetCharFormat( rDoc.CopyCharFormat( *maFormats[n]->
GetCharFormat() ) );
}
}
meRuleType = rNumRule.meRuleType;
msName = rNumRule.msName;
mbAutoRuleFlag = rNumRule.mbAutoRuleFlag;
mnPoolFormatId = rNumRule.GetPoolFormatId();
mnPoolHelpId = rNumRule.GetPoolHelpId();
mnPoolHlpFileId = rNumRule.GetPoolHlpFileId();
mbInvalidRuleFlag = true; return *this;
}
/// change indent of all list levels by given difference void SwNumRule::ChangeIndent( const sal_Int32 nDiff )
{ for ( sal_uInt16 i = 0; i < MAXLEVEL; ++i )
{
SwNumFormat aTmpNumFormat( Get(i) );
const SvxNumberFormat::SvxNumPositionAndSpaceMode ePosAndSpaceMode(
aTmpNumFormat.GetPositionAndSpaceMode() ); if ( ePosAndSpaceMode == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
{ auto nNewIndent = nDiff +
aTmpNumFormat.GetAbsLSpace(); if ( nNewIndent < 0 )
{
nNewIndent = 0;
}
aTmpNumFormat.SetAbsLSpace( nNewIndent );
} elseif ( ePosAndSpaceMode == SvxNumberFormat::LABEL_ALIGNMENT )
{ // adjust also the list tab position, if a list tab stop is applied if ( aTmpNumFormat.GetLabelFollowedBy() == SvxNumberFormat::LISTTAB )
{ const tools::Long nNewListTab = aTmpNumFormat.GetListtabPos() + nDiff;
aTmpNumFormat.SetListtabPos( nNewListTab );
}
/// set indent of certain list level to given value void SwNumRule::SetIndent( constshort nNewIndent, const sal_uInt16 nListLevel )
{
SwNumFormat aTmpNumFormat( Get(nListLevel) );
const SvxNumberFormat::SvxNumPositionAndSpaceMode ePosAndSpaceMode(
aTmpNumFormat.GetPositionAndSpaceMode() ); if ( ePosAndSpaceMode == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
{
aTmpNumFormat.SetAbsLSpace( nNewIndent );
} elseif ( ePosAndSpaceMode == SvxNumberFormat::LABEL_ALIGNMENT )
{ // adjust also the list tab position, if a list tab stop is applied if ( aTmpNumFormat.GetLabelFollowedBy() == SvxNumberFormat::LISTTAB )
{ const tools::Long nNewListTab = aTmpNumFormat.GetListtabPos() +
( nNewIndent - aTmpNumFormat.GetIndentAt() );
aTmpNumFormat.SetListtabPos( nNewListTab );
}
aTmpNumFormat.SetIndentAt( nNewIndent );
}
mbInvalidRuleFlag = true;
}
/// set indent of first list level to given value and change other list level's /// indents accordingly void SwNumRule::SetIndentOfFirstListLevelAndChangeOthers( constshort nNewIndent )
{
SwNumFormat aTmpNumFormat( Get(0) );
void SwNumRule::SetGrabBagItem(const uno::Any& rVal)
{ if (!mpGrabBagItem)
mpGrabBagItem = std::make_shared<SfxGrabBagItem>();
mpGrabBagItem->PutValue(rVal, 0);
}
namespace numfunc
{ namespace {
/** class containing default bullet list configuration data */ class SwDefBulletConfig : private utl::ConfigItem
{ public: static SwDefBulletConfig& getInstance();
/** class containing configuration data about user interface behavior regarding lists and list items. configuration item about behavior of <TAB>/<SHIFT-TAB>-key at first position of first list item
*/ class SwNumberingUIBehaviorConfig : private utl::ConfigItem
{ public: static SwNumberingUIBehaviorConfig& getInstance();
// This is the case when the numbering levels don't differ, so changing between them is not // a better alternative to inserting a tab character. return rOldFormat.GetIndentAt() != rNewFormat.GetIndentAt();
}
SvxNumberFormat::SvxNumPositionAndSpaceMode GetDefaultPositionAndSpaceMode()
{ if (comphelper::IsFuzzing()) return SvxNumberFormat::LABEL_ALIGNMENT;
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.