24#include <vcl/font.hxx>
45#include <unordered_map>
46#include <libxml/xmlwriter.h>
48#include <rtl/ustrbuf.hxx>
51#include <osl/diagnose.h>
57#include <com/sun/star/beans/PropertyValue.hpp>
64 {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr } };
67 {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr } };
120 (*mpNumRuleMap)[rName] =
this;
143 tTextNodeList::iterator aIter =
154 tTextNodeList::iterator aIter =
171 OSL_ENSURE(
MAXLEVEL > nLvl,
"NumLevel is out of range" );
177 OSL_ENSURE(
MAXLEVEL > nLvl,
"NumLevel is out of range" );
190 m_aVertOrient( 0,
text::VertOrientation::
NONE )
191 ,m_cGrfBulletCP(USHRT_MAX)
197 SwClient( rFormat.GetRegisteredInNonConst() ),
198 m_aVertOrient( 0, rFormat.GetVertOrient() )
199 ,m_cGrfBulletCP(rFormat.m_cGrfBulletCP)
208 , m_aVertOrient( 0, rNumFormat.GetVertOrient() )
209 , m_cGrfBulletCP(USHRT_MAX)
214 const OUString rCharStyleName = rNumFormat.SvxNumberFormat::GetCharFormatName();
215 if( !rCharStyleName.isEmpty() )
222 pCFormat =
nId != USHRT_MAX
226 pCFormat->Add(
this );
284 pChFormat->Add(
this );
291 if (rHint.
GetId() != SfxHintId::SwLegacyModify)
297 switch(pLegacy->GetWhich())
320 const sal_Int16* pOrient)
339 for (
auto& rpTextNode : aTextNodeList )
348 if( bFnd && !bDocIsModified )
367 : mpNumRuleMap(nullptr),
370 mnPoolFormatId( USHRT_MAX ),
371 mnPoolHelpId( USHRT_MAX ),
372 mnPoolHlpFileId( UCHAR_MAX ),
373 mbAutoRuleFlag( true ),
374 mbInvalidRuleFlag( true ),
375 mbContinusNum( false ),
376 mbAbsSpaces( false ),
378 mbCountPhantoms( true ),
379 mbUsedByRedline( false ),
380 meDefaultNumberFormatPositionAndSpaceMode( eDefaultNumberFormatPositionAndSpaceMode )
455 OSL_ENSURE( !
msName.isEmpty(),
"NumRule without a name!" );
459 : mpNumRuleMap(nullptr),
461 meRuleType( rNumRule.meRuleType ),
462 mnPoolFormatId( rNumRule.GetPoolFormatId() ),
463 mnPoolHelpId( rNumRule.GetPoolHelpId() ),
464 mnPoolHlpFileId( rNumRule.GetPoolHlpFileId() ),
465 mbAutoRuleFlag( rNumRule.mbAutoRuleFlag ),
466 mbInvalidRuleFlag( true ),
467 mbContinusNum( rNumRule.mbContinusNum ),
468 mbAbsSpaces( rNumRule.mbAbsSpaces ),
469 mbHidden( rNumRule.mbHidden ),
470 mbCountPhantoms( true ),
471 mbUsedByRedline( false ),
472 meDefaultNumberFormatPositionAndSpaceMode( rNumRule.meDefaultNumberFormatPositionAndSpaceMode ),
473 msDefaultListId( rNumRule.msDefaultListId )
500 *ppFormats =
nullptr;
507 *ppFormats =
nullptr;
514 *ppFormats =
nullptr;
519 *ppFormats =
nullptr;
534 if( pFormat && pFormat->
GetDoc() != &rDoc )
539 rpNumFormat.reset(pNew);
547 if(
this != &rNumRule )
607 OSL_ENSURE(
i <
MAXLEVEL,
"Serious defect" );
620 OSL_ENSURE(
i <
MAXLEVEL,
"Serious defect" );
631 else if( !pNumFormat )
652 const bool bInclStrings,
653 const unsigned int _nRestrictToThisLevel,
659 SwNumberTree::tNumberVector::size_type nLevel = rNumVector.size() - 1;
664 if ( nLevel > _nRestrictToThisLevel )
666 nLevel = _nRestrictToThisLevel;
671 const SwNumFormat& rMyNFormat =
Get( o3tl::narrowing<sal_uInt16>(nLevel) );
680 OUString sLevelFormat = rMyNFormat.
GetListFormat(bInclStrings);
681 sal_Int32 nFirstPosition = sLevelFormat.indexOf(
"%");
682 sal_Int32 nLastPosition = sLevelFormat.lastIndexOf(
"%");
683 if (nFirstPosition >= 0 && nLastPosition >= nFirstPosition)
684 sLevelFormat = sLevelFormat.replaceAt(nFirstPosition, nLastPosition - nFirstPosition + 1,
u"");
692 OUString sLevelFormat = rMyNFormat.
GetListFormat(bInclStrings);
696 for (SwNumberTree::tNumberVector::size_type
i=0;
i <= nLevel; ++
i)
698 OUString sReplacement;
705 OUString sFind(
"%" + OUString::number(
i + 1) +
"%");
706 sal_Int32 nPositionToken = sLevelFormat.indexOf(sFind);
707 sal_Int32 nPositionNextToken = sLevelFormat.indexOf(
'%', nPositionToken + sFind.getLength());
708 if (nPositionToken >= 0 && nPositionNextToken >= nPositionToken)
710 sLevelFormat = sLevelFormat.replaceAt(nPositionToken, nPositionNextToken - nPositionToken,
u"");
713 else if (rNumVector[
i])
718 OUString sFind(
"%" + OUString::number(
i + 1) +
"%");
719 sal_Int32 nPosition = sLevelFormat.indexOf(sFind);
721 sLevelFormat = sLevelFormat.replaceAt(nPosition, sFind.getLength(), sReplacement);
730 SwNumberTree::tNumberVector::size_type
i = nLevel;
747 for (;
i <= nLevel; ++
i)
762 if (
i != nLevel && !
aStr.isEmpty())
785 return aStr.makeStringAndClear();
789 const bool bInclSuperiorNumLabels,
790 const int nRestrictInclToThisLevel )
const
796 bool bOldHadPrefix =
true;
798 const SwNodeNum* pWorkingNodeNum( &rNodeNum );
801 bool bMakeNumStringForPhantom(
false );
812 SwNumFormat aFormat(
Get( o3tl::narrowing<sal_uInt16>(nListLevel) ) );
817 if ( bMakeNumStringForPhantom ||
826 sal_Int32 nStrip = 0;
830 if ( c!=
'\t' && c!=
' ')
837 aPrevStr = aPrevStr.copy( nStrip );
846 aPrevStr = aPrevStr.copy(0,
852 aRefNumStr = aPrevStr + aRefNumStr;
860 while ( pWorkingNodeNum &&
n > 1 )
870 }
while ( pWorkingNodeNum &&
875 if (aRefNumStr.endsWith(
"."))
878 aRefNumStr = aRefNumStr.copy(0, aRefNumStr.getLength() - 1);
886 OUString aParagraphStyleListString;
889 if (!aParagraphStyleListString.isEmpty())
890 aParagraphStyleListString +=
", ";
891 aParagraphStyleListString += rParagraphStyle->GetName();
893 return aParagraphStyleListString;
939 SvxNumRule aRule(SvxNumRuleFlags::CONTINUOUS | SvxNumRuleFlags::CHAR_STYLE |
940 SvxNumRuleFlags::ENABLE_LINKED_BMP | SvxNumRuleFlags::ENABLE_EMBEDDED_BMP,
942 meRuleType ==
NUM_RULE ? SvxNumRuleType::NUMBERING : SvxNumRuleType::OUTLINE_NUMBERING );
969 SwList* pList = pTextNode->GetDoc().getIDocumentListsAccess().getListByName( pTextNode->GetListId() );
970 OSL_ENSURE( pList,
"<SwNumRule::SetInvalidRule(..)> - list at which the text node is registered at does not exist. This is a serious issue.");
976 for (
auto aList : aLists )
977 aList->InvalidateListTree();
994 auto nNewIndent = nDiff +
996 if ( nNewIndent < 0 )
1016 Set(
i, aTmpNumFormat );
1024 const sal_uInt16 nListLevel )
1056 sal_Int32 nDiff( 0 );
1080 aLists.
insert( pTextNode->GetDoc().getIDocumentListsAccess().getListByName( pTextNode->GetListId() ) );
1082 for (
auto aList : aLists )
1083 aList->ValidateListTree(rDoc);
1100 tParagraphStyleList::iterator aIter =
1111 tParagraphStyleList::iterator aIter =
1122 (void)xmlTextWriterStartElement(pWriter, BAD_CAST(
"SwNumRule"));
1123 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST(
"msName"), BAD_CAST(
msName.toUtf8().getStr()));
1124 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST(
"mnPoolFormatId"), BAD_CAST(OString::number(
mnPoolFormatId).getStr()));
1125 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST(
"mbAutoRuleFlag"), BAD_CAST(OString::boolean(
mbAutoRuleFlag).getStr()));
1134 pFormat->dumpAsXml(pWriter);
1137 (void)xmlTextWriterEndElement(pWriter);
1145 rVal <<= uno::Sequence<beans::PropertyValue>();
1164 static SwDefBulletConfig& getInstance();
1166 const OUString& GetFontname()
const
1171 bool IsFontnameUserDefined()
const
1191 SwDefBulletConfig();
1195 void SetToDefault();
1198 static uno::Sequence<OUString> GetPropNames();
1208 virtual void Notify(
const uno::Sequence<OUString>& aPropertyNames )
override;
1209 virtual void ImplCommit()
override;
1224 SwDefBulletConfig& SwDefBulletConfig::getInstance()
1226 static SwDefBulletConfig theSwDefBulletConfig;
1227 return theSwDefBulletConfig;
1230 SwDefBulletConfig::SwDefBulletConfig()
1231 : ConfigItem(
"Office.Writer/Numbering/DefaultBulletList" ),
1243 EnableNotification( GetPropNames() );
1246 void SwDefBulletConfig::SetToDefault()
1265 uno::Sequence<OUString> SwDefBulletConfig::GetPropNames()
1269 pNames[0] =
"BulletFont/FontFamilyname";
1270 pNames[1] =
"BulletFont/FontWeight";
1271 pNames[2] =
"BulletFont/FontItalic";
1272 pNames[3] =
"BulletCharLvl1";
1273 pNames[4] =
"BulletCharLvl2";
1274 pNames[5] =
"BulletCharLvl3";
1275 pNames[6] =
"BulletCharLvl4";
1276 pNames[7] =
"BulletCharLvl5";
1277 pNames[8] =
"BulletCharLvl6";
1278 pNames[9] =
"BulletCharLvl7";
1279 pNames[10] =
"BulletCharLvl8";
1280 pNames[11] =
"BulletCharLvl9";
1281 pNames[12] =
"BulletCharLvl10";
1286 void SwDefBulletConfig::LoadConfig()
1288 uno::Sequence<OUString>
aPropNames = GetPropNames();
1289 uno::Sequence<uno::Any> aValues = GetProperties( aPropNames );
1291 OSL_ENSURE( aValues.getLength() ==
aPropNames.getLength(),
1292 "<SwDefBulletConfig::SwDefBulletConfig()> - GetProperties failed");
1293 if ( aValues.getLength() !=
aPropNames.getLength() )
1296 for (
int nProp = 0; nProp <
aPropNames.getLength(); ++nProp )
1298 if ( pValues[nProp].hasValue() )
1317 else if ( nProp == 2 )
1343 void SwDefBulletConfig::InitFont()
1348 mpFont->SetCharSet( RTL_TEXTENCODING_SYMBOL );
1358 void SwDefBulletConfig::ImplCommit()
1364 return SwDefBulletConfig::getInstance().GetFontname();
1369 return SwDefBulletConfig::getInstance().IsFontnameUserDefined();
1374 return SwDefBulletConfig::getInstance().GetFont();
1379 return SwDefBulletConfig::getInstance().GetChar( nLevel );
1392 static SwNumberingUIBehaviorConfig& getInstance();
1399 SwNumberingUIBehaviorConfig();
1404 void SetToDefault();
1407 static css::uno::Sequence<OUString> GetPropNames();
1413 virtual void Notify(
const css::uno::Sequence<OUString>& aPropertyNames )
override;
1414 virtual void ImplCommit()
override;
1422 SwNumberingUIBehaviorConfig& SwNumberingUIBehaviorConfig::getInstance()
1424 static SwNumberingUIBehaviorConfig theSwNumberingUIBehaviorConfig;
1425 return theSwNumberingUIBehaviorConfig;
1428 SwNumberingUIBehaviorConfig::SwNumberingUIBehaviorConfig()
1429 : ConfigItem(
"Office.Writer/Numbering/UserInterfaceBehavior" ),
1436 EnableNotification( GetPropNames() );
1439 void SwNumberingUIBehaviorConfig::SetToDefault()
1444 css::uno::Sequence<OUString> SwNumberingUIBehaviorConfig::GetPropNames()
1446 css::uno::Sequence<OUString>
aPropNames {
"ChangeIndentOnTabAtFirstPosOfFirstListItem" };
1451 void SwNumberingUIBehaviorConfig::ImplCommit() {}
1453 void SwNumberingUIBehaviorConfig::LoadConfig()
1455 css::uno::Sequence<OUString>
aPropNames = GetPropNames();
1456 css::uno::Sequence<css::uno::Any> aValues = GetProperties( aPropNames );
1457 const css::uno::Any*
pValues = aValues.getConstArray();
1458 OSL_ENSURE( aValues.getLength() ==
aPropNames.getLength(),
1459 "<SwNumberingUIBehaviorConfig::LoadConfig()> - GetProperties failed");
1460 if ( aValues.getLength() !=
aPropNames.getLength() )
1463 for (
int nProp = 0; nProp <
aPropNames.getLength(); ++nProp )
1465 if ( pValues[nProp].hasValue() )
1476 OSL_FAIL(
"<SwNumberingUIBehaviorConfig::LoadConfig()> - unknown configuration property");
1491 return SwNumberingUIBehaviorConfig::getInstance().ChangeIndentOnTabAtFirstPosOfFirstListItem();
1515 int nNewLevel = nOldLevel + 1;
1558 return ePosAndSpaceMode;
1564 (void)xmlTextWriterStartElement(pWriter, BAD_CAST(
"SwNumRuleTable"));
1567 (void)xmlTextWriterEndElement(pWriter);
const PropertyValue * pValues
Provides access to the lists of a document.
virtual void trackChangeOfListStyleName(const OUString &rListStyleName, const OUString &rNewListStyleName)=0
virtual void ResetModified()=0
virtual bool IsModified() const =0
Changes of document?
virtual SwCharFormat * GetCharFormatFromPool(sal_uInt16 nId)=0
static css::lang::Locale convertToLocale(LanguageType nLangID, bool bResolveSystem=true)
const SvxNumberFormat * Get(sal_uInt16 nLevel) const
bool IsContinuousNumbering() const
void SetLevel(sal_uInt16 nLevel, const SvxNumberFormat &rFmt, bool bIsValid=true)
void SetNumberingType(SvxNumType nSet)
SvxNumType GetNumberingType() const
OUString GetNumStr(sal_Int32 nNo) const
const SwModify * GetRegisteredIn() const
void StartListeningToSameModifyAs(const SwClient &)
std::optional< sw::ModifyChangedHint > CheckRegistration(const SfxPoolItem *pOldValue)
SwCursor * GetCursor(bool bMakeTableCursor=true) const
Return pointer to the current shell cursor.
IDocumentState const & getIDocumentState() const
const SwNumRuleTable & GetNumRuleTable() const
SwCharFormat * FindCharFormatByName(const OUString &rName) const
const SwCharFormats * GetCharFormats() const
SwCharFormat * CopyCharFormat(const SwCharFormat &)
copy the char format
IDocumentStylePoolAccess const & getIDocumentStylePoolAccess() const
SwCharFormat * MakeCharFormat(const OUString &rFormatName, SwCharFormat *pDerivedFrom, bool bBroadcast=false)
SwTextNode * GetTextNode() const
virtual bool IsCounted() const override
Return if this node is counted.
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
void dumpAsXml(xmlTextWriterPtr pWriter) const
sal_uInt16 mnPoolFormatId
Id-for NumRules created "automatically".
OUString MakeRefNumString(const SwNodeNum &rNodeNum, const bool bInclSuperiorNumLabels, const int nRestrictInclToThisLevel) const
bool operator==(const SwNumRule &) const
void dumpAsXml(xmlTextWriterPtr w) const
SwNumRule(OUString aNm, const SvxNumberFormat::SvxNumPositionAndSpaceMode eDefaultNumberFormatPositionAndSpaceMode, SwNumRuleType=NUM_RULE)
add parameter <eDefaultNumberFormatPositionAndSpaceMode>
void AddParagraphStyle(SwTextFormatColl &rTextFormatColl)
static SwNumFormat * saBaseFormats[RULE_END][MAXLEVEL]
sal_uInt16 mnPoolHelpId
HelpId for this Pool-style.
void RemoveParagraphStyle(SwTextFormatColl &rTextFormatColl)
SvxNumberFormat::SvxNumPositionAndSpaceMode meDefaultNumberFormatPositionAndSpaceMode
it needs to export as part of tracked numbering change
sal_uInt8 GetPoolHlpFileId() const
std::unique_ptr< SwNumFormat > maFormats[MAXLEVEL]
void SetNumRuleMap(std::unordered_map< OUString, SwNumRule * > *pNumRuleMap)
Register this rule in a "name->numrule" map.
SwNumRule::tParagraphStyleList::size_type GetParagraphStyleListSize() const
void SetSvxRule(const SvxNumRule &, SwDoc *pDoc)
SwNumRule::tTextNodeList::size_type GetTextNodeListSize() const
static sal_uInt16 GetBullIndent(sal_uInt8 nLvl)
const SwNumFormat * GetNumFormat(sal_uInt16 i) const
void ChangeIndent(const sal_Int32 nDiff)
change indent of all list levels by given difference
void SetName(const OUString &rNm, IDocumentListsAccess &rDocListAccess)
void SetIndentOfFirstListLevelAndChangeOthers(const short nNewIndent)
set indent of first list level to given value and change other list level's indents accordingly
bool IsContinusNum() const
void SetCountPhantoms(bool bCountPhantoms)
bool mbContinusNum
Continuous numbering without levels.
const OUString & GetDefaultListId() const
static const sal_uInt16 saDefNumIndents[MAXLEVEL]
const SwNumFormat & Get(sal_uInt16 i) const
void RemoveTextNode(SwTextNode &rTextNode)
void Set(sal_uInt16 i, const SwNumFormat *)
void SetInvalidRule(bool bFlag)
const OUString & GetName() const
static OUString GetOutlineRuleName()
sal_uInt16 GetPoolFormatId() const
Query and set PoolFormat IDs.
static SwNumFormat * saLabelAlignmentBaseFormats[RULE_END][MAXLEVEL]
default list level properties for position-and-space mode LABEL_ALIGNMENT
static sal_uInt16 snRefCount
std::unordered_map< OUString, SwNumRule * > * mpNumRuleMap
unordered_map containing "name->rule" relation
void SetIndent(const short nNewIndent, const sal_uInt16 nListLevel)
set indent of certain list level to given value
SvxNumRule MakeSvxNumRule() const
std::vector< SwTextNode * > tTextNodeList
OUString MakeNumString(const SwNodeNum &, bool bInclStrings=true) const
SwNumRule & operator=(const SwNumRule &)
void AddTextNode(SwTextNode &rTextNode)
void Validate(const SwDoc &rDoc)
sal_uInt8 mnPoolHlpFileId
FilePos at Doc on style helps.
void GetGrabBagItem(css::uno::Any &rVal) const
void SetGrabBagItem(const css::uno::Any &rVal)
OUString MakeParagraphStyleListString() const
static sal_uInt16 GetNumIndent(sal_uInt8 nLvl)
void Reset(const OUString &rName)
tParagraphStyleList maParagraphStyleList
container for associated paragraph styles
bool mbHidden
Is the numbering rule to be hidden in the UI?
void CheckCharFormats(SwDoc &rDoc)
Tests whether the CharFormats are from the given doc and copies them if appropriate.
sal_uInt16 GetPoolHelpId() const
Query and set Help-IDs for document styles.
bool mbAbsSpaces
Levels represent absolute indents.
tTextNodeList maTextNodeList
container for associated text nodes
void GetTextNodeList(SwNumRule::tTextNodeList &rTextNodeList) const
SwNumRule & CopyNumRule(SwDoc &, const SwNumRule &)
A kind of copy-constructor to make sure the num formats are attached to the correctCharFormats of a d...
std::shared_ptr< SfxGrabBagItem > mpGrabBagItem
Style InteropGrabBag.
bool IsPhantom() const
Return if this node is a phantom.
int GetLevelInListTree() const
Return level of this node.
SwNumberTree::tNumberVector GetNumberVector() const
Returns level numbers of this node.
SwNumberTreeNode * GetParent() const
Returns the parent of this node.
PaM is Point and Mark: a selection of the document model.
SwNode & GetPointNode() const
static SW_DLLPUBLIC sal_uInt16 GetPoolIdFromUIName(const OUString &rName, SwGetPoolIdFromName)
Represents the style of a paragraph.
SwTextNode is a paragraph in the document model.
SwNumRule * GetNumRule(bool bInParent=true) const
Returns numbering rule of this text node.
bool HasNumber(SwRootFrame const *pLayout=nullptr) const
Returns if this text node has a number.
int GetActualListLevel(SwListRedlineType eRedline=SwListRedlineType::SHOW) const
Returns the actual list level of this text node, when it is a list item.
void NumRuleChgd()
Notify this textnode that its numbering rule has changed.
std::vector< SwNumRule * >::size_type size_type
Used by the UI to modify the document model.
std::pair< const_iterator, bool > insert(Value &&x)
struct _xmlTextWriter * xmlTextWriterPtr
virtual OUString GetName() const override
constexpr TypedWhichId< SwAttrSetChg > RES_ATTRSET_CHG(169)
constexpr TypedWhichId< SwFormatChg > RES_FMT_CHG(168)
std::vector< tSwNumTreeNumber > tNumberVector
namespace for static functions and methods for numbering and bullets
bool IsDefBulletFontUserDefined()
determine if default bullet font is user defined
SvxNumberFormat::SvxNumPositionAndSpaceMode GetDefaultPositionAndSpaceMode()
bool ChangeIndentOnTabAtFirstPosOfFirstListItem()
configuration, if at first position of the first list item the <TAB>-key increased the indent of the ...
sal_Unicode GetBulletChar(sal_uInt8 nLevel)
retrieve unicode of character used for the default bullet list for the given list level
bool NumDownChangesIndent(const SwWrtShell &rShell)
Decides if increasing ("downing") the numbering level will change the amount of indentation or not.
OUString const & GetDefBulletFontname()
retrieve font family name used for the default bullet list characters
const vcl::Font & GetDefBulletFont()
retrieve font used for the default bullet list characters
constexpr auto toTwips(N number, Length from)
vcl::Font GetFont(vcl::Font const &rFont, DrawModeFlags nDrawMode, StyleSettings const &rStyleSettings)
std::optional< vcl::Font > mpFont
bool mbChangeIndentOnTabAtFirstPosOfFirstListItem
bool mbUserDefinedFontname
sal_Unicode mnLevelChars[MAXLEVEL]
static void lcl_SetRuleChgd(SwTextNode &rNd, sal_uInt8 nLevel)
const PropertyStruct aPropNames[]
UNOTOOLS_DLLPUBLIC SvtSaveOptions::ODFSaneDefaultVersion GetODFSaneDefaultVersion()
static LanguageType nLang
constexpr sal_uInt16 lNumberIndent
constexpr short lNumberFirstLineOffset
constexpr short lOutlineMinTextDistance
constexpr sal_uInt8 MAXLEVEL