LibreOffice Module sw (master) 1
number.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <memory>
21#include <hintids.hxx>
22
23#include <utility>
24#include <vcl/font.hxx>
25#include <editeng/brushitem.hxx>
26#include <editeng/numitem.hxx>
27#include <svl/grabbagitem.hxx>
28#include <fmtornt.hxx>
29#include <doc.hxx>
30#include <charfmt.hxx>
31#include <ndtxt.hxx>
32#include <docary.hxx>
33#include <SwStyleNameMapper.hxx>
34
35// Needed to load default bullet list configuration
38
39#include <numrule.hxx>
40#include <SwNodeNum.hxx>
41
42#include <list.hxx>
43
44#include <algorithm>
45#include <unordered_map>
46#include <libxml/xmlwriter.h>
47
48#include <rtl/ustrbuf.hxx>
50#include <unotools/saveopt.hxx>
51#include <osl/diagnose.h>
52
55#include <IDocumentState.hxx>
56
57#include <com/sun/star/beans/PropertyValue.hpp>
58#include <wrtsh.hxx>
59
60using namespace ::com::sun::star;
61
62sal_uInt16 SwNumRule::snRefCount = 0;
64 {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr } };
65
67 {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr } };
68
69const sal_uInt16 SwNumRule::saDefNumIndents[ MAXLEVEL ] = {
80};
81
83{
84 return "Outline";
85}
86
87const SwNumFormat& SwNumRule::Get( sal_uInt16 i ) const
88{
89 assert( i < MAXLEVEL && meRuleType < RULE_END );
90 return maFormats[ i ]
91 ? *maFormats[ i ]
95}
96
97const SwNumFormat* SwNumRule::GetNumFormat( sal_uInt16 i ) const
98{
99 const SwNumFormat * pResult = nullptr;
100
101 assert( i < MAXLEVEL && meRuleType < RULE_END );
102 if ( i < MAXLEVEL && meRuleType < RULE_END)
103 {
104 pResult = maFormats[ i ].get();
105 }
106
107 return pResult;
108}
109
110// #i91400#
111void SwNumRule::SetName( const OUString & rName,
112 IDocumentListsAccess& rDocListAccess)
113{
114 if ( msName == rName )
115 return;
116
117 if (mpNumRuleMap)
118 {
119 mpNumRuleMap->erase(msName);
120 (*mpNumRuleMap)[rName] = this;
121
122 if ( !GetDefaultListId().isEmpty() )
123 {
124 rDocListAccess.trackChangeOfListStyleName( msName, rName );
125 }
126 }
127
128 msName = rName;
129}
130
132{
133 rTextNodeList = maTextNodeList;
134}
135
136SwNumRule::tTextNodeList::size_type SwNumRule::GetTextNodeListSize() const
137{
138 return maTextNodeList.size();
139}
140
142{
143 tTextNodeList::iterator aIter =
144 std::find( maTextNodeList.begin(), maTextNodeList.end(), &rTextNode );
145
146 if ( aIter == maTextNodeList.end() )
147 {
148 maTextNodeList.push_back( &rTextNode );
149 }
150}
151
153{
154 tTextNodeList::iterator aIter =
155 std::find( maTextNodeList.begin(), maTextNodeList.end(), &rTextNode );
156
157 if ( aIter != maTextNodeList.end() )
158 {
159 maTextNodeList.erase( aIter );
160 }
161}
162
163void SwNumRule::SetNumRuleMap(std::unordered_map<OUString, SwNumRule *> *
164 pNumRuleMap)
165{
166 mpNumRuleMap = pNumRuleMap;
167}
168
170{
171 OSL_ENSURE( MAXLEVEL > nLvl, "NumLevel is out of range" );
172 return saDefNumIndents[ nLvl ];
173}
174
176{
177 OSL_ENSURE( MAXLEVEL > nLvl, "NumLevel is out of range" );
178 return saDefNumIndents[ nLvl ];
179}
180
181static void lcl_SetRuleChgd( SwTextNode& rNd, sal_uInt8 nLevel )
182{
183 if( rNd.GetActualListLevel() == nLevel )
184 rNd.NumRuleChgd();
185}
186
189 SwClient( nullptr ),
190 m_aVertOrient( 0, text::VertOrientation::NONE )
191 ,m_cGrfBulletCP(USHRT_MAX)//For i120928,record the cp info of graphic within bullet
192{
193}
194
196 SvxNumberFormat(rFormat),
197 SwClient( rFormat.GetRegisteredInNonConst() ),
198 m_aVertOrient( 0, rFormat.GetVertOrient() )
199 ,m_cGrfBulletCP(rFormat.m_cGrfBulletCP)//For i120928,record the cp info of graphic within bullet
200{
201 sal_Int16 eMyVertOrient = rFormat.GetVertOrient();
202 SetGraphicBrush( rFormat.GetBrush(), &rFormat.GetGraphicSize(),
203 &eMyVertOrient);
204}
205
207 : SvxNumberFormat(rNumFormat)
208 , m_aVertOrient( 0, rNumFormat.GetVertOrient() )
209 , m_cGrfBulletCP(USHRT_MAX)
210{
211 sal_Int16 eMyVertOrient = rNumFormat.GetVertOrient();
212 SetGraphicBrush( rNumFormat.GetBrush(), &rNumFormat.GetGraphicSize(),
213 &eMyVertOrient);
214 const OUString rCharStyleName = rNumFormat.SvxNumberFormat::GetCharFormatName();
215 if( !rCharStyleName.isEmpty() )
216 {
217 SwCharFormat* pCFormat = pDoc->FindCharFormatByName( rCharStyleName );
218 if( !pCFormat )
219 {
220 sal_uInt16 nId = SwStyleNameMapper::GetPoolIdFromUIName( rCharStyleName,
222 pCFormat = nId != USHRT_MAX
224 : pDoc->MakeCharFormat( rCharStyleName, nullptr );
225 }
226 pCFormat->Add( this );
227 }
228 else
230}
231
233{
234}
235
236// #i22362#
238{
239 // #i30655# native numbering did not work any longer
240 // using this code. Therefore HBRINKM and I agreed upon defining
241 // IsEnumeration() as !IsItemize()
242 return !IsItemize();
243}
244
246{
247 bool bResult;
248
249 switch(GetNumberingType())
250 {
252 case SVX_NUM_BITMAP:
253 bResult = true;
254
255 break;
256
257 default:
258 bResult = false;
259 }
260
261 return bResult;
262
263}
264
266{
267 SvxNumberFormat::operator=(rNumFormat);
269 //For i120928,record the cp info of graphic within bullet
270 m_cGrfBulletCP = rNumFormat.m_cGrfBulletCP;
271 return *this;
272}
273
274bool SwNumFormat::operator==( const SwNumFormat& rNumFormat) const
275{
276 bool bRet = SvxNumberFormat::operator==(rNumFormat) &&
277 GetRegisteredIn() == rNumFormat.GetRegisteredIn();
278 return bRet;
279}
280
282{
283 if( pChFormat )
284 pChFormat->Add( this );
285 else
287}
288
290{
291 if (rHint.GetId() != SfxHintId::SwLegacyModify)
292 return;
293 auto pLegacy = static_cast<const sw::LegacyModifyHint*>(&rHint);
294 // Look for the NumRules object in the Doc where this NumFormat is set.
295 // The format does not need to exist!
296 const SwCharFormat* pFormat = nullptr;
297 switch(pLegacy->GetWhich())
298 {
299 case RES_ATTRSET_CHG:
300 case RES_FMT_CHG:
301 pFormat = GetCharFormat();
302 break;
303 }
304
305 if(pFormat && !pFormat->GetDoc()->IsInDtor())
306 UpdateNumNodes(*const_cast<SwDoc*>(pFormat->GetDoc()));
307 else
308 CheckRegistration(pLegacy->m_pOld);
309}
310
312{
313 if(static_cast<const SwCharFormat*>(GetRegisteredIn()))
314 return static_cast<const SwCharFormat*>(GetRegisteredIn())->GetName();
315
316 return OUString();
317}
318
319void SwNumFormat::SetGraphicBrush( const SvxBrushItem* pBrushItem, const Size* pSize,
320 const sal_Int16* pOrient)
321{
322 if(pOrient)
323 m_aVertOrient.SetVertOrient( *pOrient );
324 SvxNumberFormat::SetGraphicBrush( pBrushItem, pSize, pOrient);
325}
326
328{
329 bool bDocIsModified = rDoc.getIDocumentState().IsModified();
330 bool bFnd = false;
331 for( SwNumRuleTable::size_type n = rDoc.GetNumRuleTable().size(); !bFnd && n; )
332 {
333 const SwNumRule* pRule = rDoc.GetNumRuleTable()[ --n ];
334 for( sal_uInt8 i = 0; i < MAXLEVEL; ++i )
335 if( pRule->GetNumFormat( i ) == this )
336 {
337 SwNumRule::tTextNodeList aTextNodeList;
338 pRule->GetTextNodeList( aTextNodeList );
339 for ( auto& rpTextNode : aTextNodeList )
340 {
341 lcl_SetRuleChgd( *rpTextNode, i );
342 }
343 bFnd = true;
344 break;
345 }
346 }
347
348 if( bFnd && !bDocIsModified )
350}
351
353{
354 sal_Int16 eOrient = SvxNumberFormat::GetVertOrient();
355 if(text::VertOrientation::NONE == eOrient)
356 return nullptr;
357 else
358 {
359 const_cast<SwFormatVertOrient&>(m_aVertOrient).SetVertOrient(eOrient);
360 return &m_aVertOrient;
361 }
362}
363
365 const SvxNumberFormat::SvxNumPositionAndSpaceMode eDefaultNumberFormatPositionAndSpaceMode,
366 SwNumRuleType eType )
367 : mpNumRuleMap(nullptr),
368 msName( std::move(aNm) ),
369 meRuleType( eType ),
370 mnPoolFormatId( USHRT_MAX ),
371 mnPoolHelpId( USHRT_MAX ),
372 mnPoolHlpFileId( UCHAR_MAX ),
373 mbAutoRuleFlag( true ),
374 mbInvalidRuleFlag( true ),
375 mbContinusNum( false ),
376 mbAbsSpaces( false ),
377 mbHidden( false ),
378 mbCountPhantoms( true ),
379 mbUsedByRedline( false ),
380 meDefaultNumberFormatPositionAndSpaceMode( eDefaultNumberFormatPositionAndSpaceMode )
381{
382 if( !snRefCount++ ) // for the first time, initialize
383 {
384 SwNumFormat* pFormat;
385 sal_uInt8 n;
386
387 // numbering:
388 // position-and-space mode LABEL_WIDTH_AND_POSITION:
389 for( n = 0; n < MAXLEVEL; ++n )
390 {
391 pFormat = new SwNumFormat;
392 pFormat->SetIncludeUpperLevels( 1 );
393 pFormat->SetStart( 1 );
396 pFormat->SetListFormat("%" + OUString::number(n + 1) + "%.");
398 SwNumRule::saBaseFormats[ NUM_RULE ][ n ] = pFormat;
399 }
400 // position-and-space mode LABEL_ALIGNMENT
401 // first line indent of general numbering in inch: -0,25 inch
402 const tools::Long cFirstLineIndent = o3tl::toTwips(-0.25, o3tl::Length::in);
403 // indent values of general numbering in inch:
404 const tools::Long cIndentAt[ MAXLEVEL ] = {
415 };
416 for( n = 0; n < MAXLEVEL; ++n )
417 {
418 pFormat = new SwNumFormat;
419 pFormat->SetIncludeUpperLevels( 1 );
420 pFormat->SetStart( 1 );
423 pFormat->SetListtabPos( cIndentAt[ n ] );
424 pFormat->SetFirstLineIndent( cFirstLineIndent );
425 pFormat->SetIndentAt( cIndentAt[ n ] );
426 pFormat->SetListFormat( "%" + OUString::number(n + 1) + "%.");
429 }
430
431 // outline:
432 // position-and-space mode LABEL_WIDTH_AND_POSITION:
433 for( n = 0; n < MAXLEVEL; ++n )
434 {
435 pFormat = new SwNumFormat;
438 pFormat->SetStart( 1 );
442 }
443 // position-and-space mode LABEL_ALIGNMENT:
444 for( n = 0; n < MAXLEVEL; ++n )
445 {
446 pFormat = new SwNumFormat;
449 pFormat->SetStart( 1 );
453 }
454 }
455 OSL_ENSURE( !msName.isEmpty(), "NumRule without a name!" );
456}
457
459 : mpNumRuleMap(nullptr),
460 msName( rNumRule.msName ),
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 )
474{
475 ++snRefCount;
476 for( sal_uInt16 n = 0; n < MAXLEVEL; ++n )
477 if( rNumRule.maFormats[ n ] )
478 Set( n, *rNumRule.maFormats[ n ] );
479}
480
482{
483 for (auto & i : maFormats)
484 i.reset();
485
486 if (mpNumRuleMap)
487 {
488 mpNumRuleMap->erase(GetName());
489 }
490
491 if( !--snRefCount ) // the last one closes the door (?)
492 {
493 // Numbering:
494 SwNumFormat** ppFormats = &SwNumRule::saBaseFormats[0][0];
495 int n;
496
497 for( n = 0; n < MAXLEVEL; ++n, ++ppFormats )
498 {
499 delete *ppFormats;
500 *ppFormats = nullptr;
501 }
502
503 // Outline:
504 for( n = 0; n < MAXLEVEL; ++n, ++ppFormats )
505 {
506 delete *ppFormats;
507 *ppFormats = nullptr;
508 }
509
511 for( n = 0; n < MAXLEVEL; ++n, ++ppFormats )
512 {
513 delete *ppFormats;
514 *ppFormats = nullptr;
515 }
516 for( n = 0; n < MAXLEVEL; ++n, ++ppFormats )
517 {
518 delete *ppFormats;
519 *ppFormats = nullptr;
520 }
521 }
522
523 maTextNodeList.clear();
524 maParagraphStyleList.clear();
525}
526
528{
529 for(auto& rpNumFormat : maFormats)
530 {
531 if( rpNumFormat )
532 {
533 SwCharFormat* pFormat = rpNumFormat->GetCharFormat();
534 if( pFormat && pFormat->GetDoc() != &rDoc )
535 {
536 // copy
537 SwNumFormat* pNew = new SwNumFormat( *rpNumFormat );
538 pNew->SetCharFormat( rDoc.CopyCharFormat( *pFormat ) );
539 rpNumFormat.reset(pNew);
540 }
541 }
542 }
543}
544
546{
547 if( this != &rNumRule )
548 {
549 for( sal_uInt16 n = 0; n < MAXLEVEL; ++n )
550 Set( n, rNumRule.maFormats[ n ].get() );
551
552 meRuleType = rNumRule.meRuleType;
553 msName = rNumRule.msName;
555 mbInvalidRuleFlag = true;
556 mbContinusNum = rNumRule.mbContinusNum;
557 mbAbsSpaces = rNumRule.mbAbsSpaces;
558 mbHidden = rNumRule.mbHidden;
559 mnPoolFormatId = rNumRule.GetPoolFormatId();
560 mnPoolHelpId = rNumRule.GetPoolHelpId();
562 }
563 return *this;
564}
565
566void SwNumRule::Reset( const OUString& rName )
567{
568 for( sal_uInt16 n = 0; n < MAXLEVEL; ++n )
569 Set( n, nullptr);
570
572 msName = rName;
573 mbAutoRuleFlag = true;
574 mbInvalidRuleFlag = true;
575 mbContinusNum = false;
576 mbAbsSpaces = false;
577 mbHidden = false;
578 mnPoolFormatId = USHRT_MAX;
579 mnPoolHelpId = USHRT_MAX;
580 mnPoolHlpFileId = UCHAR_MAX;
581}
582
583bool SwNumRule::operator==( const SwNumRule& rRule ) const
584{
585 bool bRet = meRuleType == rRule.meRuleType &&
586 msName == rRule.msName &&
588 mbContinusNum == rRule.mbContinusNum &&
589 mbAbsSpaces == rRule.mbAbsSpaces &&
590 mnPoolFormatId == rRule.GetPoolFormatId() &&
591 mnPoolHelpId == rRule.GetPoolHelpId() &&
593 if( bRet )
594 {
595 for( sal_uInt8 n = 0; n < MAXLEVEL; ++n )
596 if( rRule.Get( n ) != Get( n ) )
597 {
598 bRet = false;
599 break;
600 }
601 }
602 return bRet;
603}
604
605void SwNumRule::Set( sal_uInt16 i, const SwNumFormat& rNumFormat )
606{
607 OSL_ENSURE( i < MAXLEVEL, "Serious defect" );
608 if( i < MAXLEVEL )
609 {
610 if( !maFormats[ i ] || (rNumFormat != Get( i )) )
611 {
612 maFormats[ i ].reset(new SwNumFormat( rNumFormat ));
613 mbInvalidRuleFlag = true;
614 }
615 }
616}
617
618void SwNumRule::Set( sal_uInt16 i, const SwNumFormat* pNumFormat )
619{
620 OSL_ENSURE( i < MAXLEVEL, "Serious defect" );
621 if( i >= MAXLEVEL )
622 return;
623 if( !maFormats[ i ] )
624 {
625 if( pNumFormat )
626 {
627 maFormats[ i ].reset(new SwNumFormat( *pNumFormat ));
628 mbInvalidRuleFlag = true;
629 }
630 }
631 else if( !pNumFormat )
632 {
633 maFormats[ i ].reset();
634 mbInvalidRuleFlag = true;
635 }
636 else if( *maFormats[i] != *pNumFormat )
637 {
638 *maFormats[ i ] = *pNumFormat;
639 mbInvalidRuleFlag = true;
640 }
641}
642
643OUString SwNumRule::MakeNumString( const SwNodeNum& rNum, bool bInclStrings ) const
644{
645 if (rNum.IsCounted())
646 return MakeNumString(rNum.GetNumberVector(), bInclStrings);
647
648 return OUString();
649}
650
652 const bool bInclStrings,
653 const unsigned int _nRestrictToThisLevel,
654 SwNumRule::Extremities* pExtremities,
655 LanguageType nLang ) const
656{
657 OUStringBuffer aStr;
658
659 SwNumberTree::tNumberVector::size_type nLevel = rNumVector.size() - 1;
660
661 if ( pExtremities )
662 pExtremities->nPrefixChars = pExtremities->nSuffixChars = 0;
663
664 if ( nLevel > _nRestrictToThisLevel )
665 {
666 nLevel = _nRestrictToThisLevel;
667 }
668
669 assert(nLevel < MAXLEVEL);
670
671 const SwNumFormat& rMyNFormat = Get( o3tl::narrowing<sal_uInt16>(nLevel) );
672
673 if (rMyNFormat.GetNumberingType() == SVX_NUM_NUMBER_NONE)
674 {
675 if (!rMyNFormat.HasListFormat())
676 return bInclStrings ? rMyNFormat.GetPrefix() + rMyNFormat.GetSuffix() : OUString();
677
678 // If numbering is disabled for this level we should emit just prefix/suffix
679 // Remove everything between first %1% and last %n% (including markers)
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"");
685 return sLevelFormat;
686 }
687
688 css::lang::Locale aLocale( LanguageTag::convertToLocale(nLang));
689
690 if (rMyNFormat.HasListFormat())
691 {
692 OUString sLevelFormat = rMyNFormat.GetListFormat(bInclStrings);
693
694 // In this case we are ignoring GetIncludeUpperLevels: we put all
695 // level numbers requested by level format
696 for (SwNumberTree::tNumberVector::size_type i=0; i <= nLevel; ++i)
697 {
698 OUString sReplacement;
699 const SwNumFormat& rNFormat = Get(i);
700 if (rNFormat.GetNumberingType() == SVX_NUM_NUMBER_NONE)
701 {
702 // Numbering disabled - replacement is empty
703 // And we should skip all level string content until next level marker:
704 // so %1%.%2%.%3% with second level as NONE will result 1.1, not 1..1
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)
709 {
710 sLevelFormat = sLevelFormat.replaceAt(nPositionToken, nPositionNextToken - nPositionToken, u"");
711 }
712 }
713 else if (rNumVector[i])
714 sReplacement = Get(i).GetNumStr(rNumVector[i], aLocale, rMyNFormat.GetIsLegal());
715 else
716 sReplacement = "0"; // all 0 level are a 0
717
718 OUString sFind("%" + OUString::number(i + 1) + "%");
719 sal_Int32 nPosition = sLevelFormat.indexOf(sFind);
720 if (nPosition >= 0)
721 sLevelFormat = sLevelFormat.replaceAt(nPosition, sFind.getLength(), sReplacement);
722 }
723
724 aStr = sLevelFormat;
725 }
726 else
727 {
728 // Fallback case: level format is not defined
729 // So use old way with levels joining by dot "."
730 SwNumberTree::tNumberVector::size_type i = nLevel;
731
732 if (!IsContinusNum() &&
733 // - do not include upper levels, if level isn't numbered.
734 rMyNFormat.GetNumberingType() != SVX_NUM_NUMBER_NONE &&
735 rMyNFormat.GetIncludeUpperLevels()) // Just the own level?
736 {
737 sal_uInt8 n = rMyNFormat.GetIncludeUpperLevels();
738 if (1 < n)
739 {
740 if (i + 1 >= n)
741 i -= n - 1;
742 else
743 i = 0;
744 }
745 }
746
747 for (; i <= nLevel; ++i)
748 {
749 const SwNumFormat& rNFormat = Get(i);
750 if (SVX_NUM_NUMBER_NONE == rNFormat.GetNumberingType())
751 {
752 // Should 1.1.1 --> 2. NoNum --> 1..1 or 1.1 ??
753 // if( i != rNum.nMyLevel )
754 // aStr += ".";
755 continue;
756 }
757
758 if (rNumVector[i])
759 aStr.append(rNFormat.GetNumStr(rNumVector[i], aLocale, rMyNFormat.GetIsLegal()));
760 else
761 aStr.append("0"); // all 0 level are a 0
762 if (i != nLevel && !aStr.isEmpty())
763 aStr.append(".");
764 }
765
766 // The type doesn't have any number, so don't append
767 // the post-/prefix string
768 if (bInclStrings &&
769 SVX_NUM_CHAR_SPECIAL != rMyNFormat.GetNumberingType() &&
770 SVX_NUM_BITMAP != rMyNFormat.GetNumberingType())
771 {
772 const OUString& sPrefix = rMyNFormat.GetPrefix();
773 const OUString& sSuffix = rMyNFormat.GetSuffix();
774
775 aStr.insert(0, sPrefix);
776 aStr.append(sSuffix);
777 if (pExtremities)
778 {
779 pExtremities->nPrefixChars = sPrefix.getLength();
780 pExtremities->nSuffixChars = sSuffix.getLength();
781 }
782 }
783 }
784
785 return aStr.makeStringAndClear();
786}
787
788OUString SwNumRule::MakeRefNumString( const SwNodeNum& rNodeNum,
789 const bool bInclSuperiorNumLabels,
790 const int nRestrictInclToThisLevel ) const
791{
792 OUString aRefNumStr;
793
794 if ( rNodeNum.GetLevelInListTree() >= 0 )
795 {
796 bool bOldHadPrefix = true;
797
798 const SwNodeNum* pWorkingNodeNum( &rNodeNum );
799 do
800 {
801 bool bMakeNumStringForPhantom( false );
802 if ( pWorkingNodeNum->IsPhantom() )
803 {
804 int nListLevel = pWorkingNodeNum->GetLevelInListTree();
805
806 if (nListLevel < 0)
807 nListLevel = 0;
808
809 if (nListLevel >= MAXLEVEL)
810 nListLevel = MAXLEVEL - 1;
811
812 SwNumFormat aFormat( Get( o3tl::narrowing<sal_uInt16>(nListLevel) ) );
813 bMakeNumStringForPhantom = aFormat.IsEnumeration() &&
815
816 }
817 if ( bMakeNumStringForPhantom ||
818 ( !pWorkingNodeNum->IsPhantom() &&
819 pWorkingNodeNum->GetTextNode() &&
820 pWorkingNodeNum->GetTextNode()->HasNumber() ) )
821 {
822 Extremities aExtremities;
823 OUString aPrevStr = MakeNumString( pWorkingNodeNum->GetNumberVector(),
824 true, MAXLEVEL,
825 &aExtremities);
826 sal_Int32 nStrip = 0;
827 while ( nStrip < aExtremities.nPrefixChars )
828 {
829 const sal_Unicode c = aPrevStr[nStrip];
830 if ( c!='\t' && c!=' ')
831 break;
832 ++nStrip;
833 }
834
835 if (nStrip)
836 {
837 aPrevStr = aPrevStr.copy( nStrip );
838 aExtremities.nPrefixChars -= nStrip;
839 }
840
841 if (bOldHadPrefix &&
842 aExtremities.nSuffixChars &&
843 !aExtremities.nPrefixChars
844 )
845 {
846 aPrevStr = aPrevStr.copy(0,
847 aPrevStr.getLength() - aExtremities.nSuffixChars);
848 }
849
850 bOldHadPrefix = ( aExtremities.nPrefixChars > 0);
851
852 aRefNumStr = aPrevStr + aRefNumStr;
853 }
854
855 if ( bInclSuperiorNumLabels && pWorkingNodeNum->GetLevelInListTree() > 0 )
856 {
857 sal_uInt8 n = Get( o3tl::narrowing<sal_uInt16>(pWorkingNodeNum->GetLevelInListTree()) ).GetIncludeUpperLevels();
858 pWorkingNodeNum = dynamic_cast<SwNodeNum*>(pWorkingNodeNum->GetParent());
859 // skip parents, whose list label is already contained in the actual list label.
860 while ( pWorkingNodeNum && n > 1 )
861 {
862 pWorkingNodeNum = dynamic_cast<SwNodeNum*>(pWorkingNodeNum->GetParent());
863 --n;
864 }
865 }
866 else
867 {
868 break;
869 }
870 } while ( pWorkingNodeNum &&
871 pWorkingNodeNum->GetLevelInListTree() >= 0 &&
872 pWorkingNodeNum->GetLevelInListTree() >= nRestrictInclToThisLevel );
873 }
874
875 if (aRefNumStr.endsWith("."))
876 {
877 // tdf#144563: looks like a special case for refs by MS Word: if numbering is ending with dot, this dot is removed
878 aRefNumStr = aRefNumStr.copy(0, aRefNumStr.getLength() - 1);
879 }
880
881 return aRefNumStr;
882}
883
885{
886 OUString aParagraphStyleListString;
887 for (const auto& rParagraphStyle : maParagraphStyleList)
888 {
889 if (!aParagraphStyleListString.isEmpty())
890 aParagraphStyleListString += ", ";
891 aParagraphStyleListString += rParagraphStyle->GetName();
892 }
893 return aParagraphStyleListString;
894}
895
902{
903 for( sal_uInt16 n = 0; n < MAXLEVEL; ++n )
904 {
905 Set( n, rNumRule.maFormats[ n ].get() );
906 if( maFormats[ n ] && maFormats[ n ]->GetCharFormat() &&
907 !rDoc.GetCharFormats()->ContainsFormat(maFormats[n]->GetCharFormat()))
908 {
909 // If we copy across different Documents, then copy the
910 // corresponding CharFormat into the new Document.
911 maFormats[n]->SetCharFormat( rDoc.CopyCharFormat( *maFormats[n]->
912 GetCharFormat() ) );
913 }
914 }
915 meRuleType = rNumRule.meRuleType;
916 msName = rNumRule.msName;
918 mnPoolFormatId = rNumRule.GetPoolFormatId();
919 mnPoolHelpId = rNumRule.GetPoolHelpId();
921 mbInvalidRuleFlag = true;
922 return *this;
923}
924
925void SwNumRule::SetSvxRule(const SvxNumRule& rNumRule, SwDoc* pDoc)
926{
927 for( sal_uInt16 n = 0; n < MAXLEVEL; ++n )
928 {
929 const SvxNumberFormat* pSvxFormat = rNumRule.Get(n);
930 maFormats[n].reset( pSvxFormat ? new SwNumFormat(*pSvxFormat, pDoc) : nullptr );
931 }
932
933 mbInvalidRuleFlag = true;
935}
936
938{
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 );
943 for( sal_uInt16 n = 0; n < MAXLEVEL; ++n )
944 {
945 const SwNumFormat & rNumFormat = Get(n);
946 if(rNumFormat.GetCharFormat())
947 {
948 SwNumFormat aNewFormat = rNumFormat;
949 aNewFormat.SetCharFormatName(rNumFormat.GetCharFormat()->GetName());
950 aRule.SetLevel(n, aNewFormat, maFormats[n] != nullptr);
951 }
952 else
953 aRule.SetLevel(n, rNumFormat, maFormats[n] != nullptr);
954 }
955 return aRule;
956}
957
959{
960 if (mbInvalidRuleFlag == bFlag)
961 return;
962
963 if (bFlag)
964 {
966 for ( const SwTextNode* pTextNode : maTextNodeList )
967 {
968 // #i111681# - applying patch from cmc
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.");
971 if ( pList )
972 {
973 aLists.insert( pList );
974 }
975 }
976 for ( auto aList : aLists )
977 aList->InvalidateListTree();
978 }
979
980 mbInvalidRuleFlag = bFlag;
981}
982
984void SwNumRule::ChangeIndent( const sal_Int32 nDiff )
985{
986 for ( sal_uInt16 i = 0; i < MAXLEVEL; ++i )
987 {
988 SwNumFormat aTmpNumFormat( Get(i) );
989
990 const SvxNumberFormat::SvxNumPositionAndSpaceMode ePosAndSpaceMode(
991 aTmpNumFormat.GetPositionAndSpaceMode() );
992 if ( ePosAndSpaceMode == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
993 {
994 auto nNewIndent = nDiff +
995 aTmpNumFormat.GetAbsLSpace();
996 if ( nNewIndent < 0 )
997 {
998 nNewIndent = 0;
999 }
1000 aTmpNumFormat.SetAbsLSpace( nNewIndent );
1001 }
1002 else if ( ePosAndSpaceMode == SvxNumberFormat::LABEL_ALIGNMENT )
1003 {
1004 // adjust also the list tab position, if a list tab stop is applied
1005 if ( aTmpNumFormat.GetLabelFollowedBy() == SvxNumberFormat::LISTTAB )
1006 {
1007 const tools::Long nNewListTab = aTmpNumFormat.GetListtabPos() + nDiff;
1008 aTmpNumFormat.SetListtabPos( nNewListTab );
1009 }
1010
1011 const tools::Long nNewIndent = nDiff +
1012 aTmpNumFormat.GetIndentAt();
1013 aTmpNumFormat.SetIndentAt( nNewIndent );
1014 }
1015
1016 Set( i, aTmpNumFormat );
1017 }
1018
1019 SetInvalidRule( true );
1020}
1021
1023void SwNumRule::SetIndent( const short nNewIndent,
1024 const sal_uInt16 nListLevel )
1025{
1026 SwNumFormat aTmpNumFormat( Get(nListLevel) );
1027
1028 const SvxNumberFormat::SvxNumPositionAndSpaceMode ePosAndSpaceMode(
1029 aTmpNumFormat.GetPositionAndSpaceMode() );
1030 if ( ePosAndSpaceMode == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
1031 {
1032 aTmpNumFormat.SetAbsLSpace( nNewIndent );
1033 }
1034 else if ( ePosAndSpaceMode == SvxNumberFormat::LABEL_ALIGNMENT )
1035 {
1036 // adjust also the list tab position, if a list tab stop is applied
1037 if ( aTmpNumFormat.GetLabelFollowedBy() == SvxNumberFormat::LISTTAB )
1038 {
1039 const tools::Long nNewListTab = aTmpNumFormat.GetListtabPos() +
1040 ( nNewIndent - aTmpNumFormat.GetIndentAt() );
1041 aTmpNumFormat.SetListtabPos( nNewListTab );
1042 }
1043
1044 aTmpNumFormat.SetIndentAt( nNewIndent );
1045 }
1046
1047 SetInvalidRule( true );
1048}
1049
1053{
1054 SwNumFormat aTmpNumFormat( Get(0) );
1055
1056 sal_Int32 nDiff( 0 );
1057 const SvxNumberFormat::SvxNumPositionAndSpaceMode ePosAndSpaceMode(
1058 aTmpNumFormat.GetPositionAndSpaceMode() );
1059 if ( ePosAndSpaceMode == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
1060 {
1061 nDiff = nNewIndent
1062 - aTmpNumFormat.GetFirstLineOffset()
1063 - aTmpNumFormat.GetAbsLSpace();
1064 }
1065 else if ( ePosAndSpaceMode == SvxNumberFormat::LABEL_ALIGNMENT )
1066 {
1067 nDiff = nNewIndent - aTmpNumFormat.GetIndentAt();
1068 }
1069 if ( nDiff != 0 )
1070 {
1071 ChangeIndent( nDiff );
1072 }
1073}
1074
1076{
1078 for ( const SwTextNode* pTextNode : maTextNodeList )
1079 {
1080 aLists.insert( pTextNode->GetDoc().getIDocumentListsAccess().getListByName( pTextNode->GetListId() ) );
1081 }
1082 for ( auto aList : aLists )
1083 aList->ValidateListTree(rDoc);
1084
1085 SetInvalidRule(false);
1086}
1087
1088void SwNumRule::SetCountPhantoms(bool bCountPhantoms)
1089{
1090 mbCountPhantoms = bCountPhantoms;
1091}
1092
1093SwNumRule::tParagraphStyleList::size_type SwNumRule::GetParagraphStyleListSize() const
1094{
1095 return maParagraphStyleList.size();
1096}
1097
1099{
1100 tParagraphStyleList::iterator aIter =
1101 std::find( maParagraphStyleList.begin(), maParagraphStyleList.end(), &rTextFormatColl );
1102
1103 if ( aIter == maParagraphStyleList.end() )
1104 {
1105 maParagraphStyleList.push_back( &rTextFormatColl );
1106 }
1107}
1108
1110{
1111 tParagraphStyleList::iterator aIter =
1112 std::find( maParagraphStyleList.begin(), maParagraphStyleList.end(), &rTextFormatColl );
1113
1114 if ( aIter != maParagraphStyleList.end() )
1115 {
1116 maParagraphStyleList.erase( aIter );
1117 }
1118}
1119
1121{
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()));
1126
1127 for (const auto& pFormat : maFormats)
1128 {
1129 if (!pFormat)
1130 {
1131 continue;
1132 }
1133
1134 pFormat->dumpAsXml(pWriter);
1135 }
1136
1137 (void)xmlTextWriterEndElement(pWriter);
1138}
1139
1141{
1142 if (mpGrabBagItem)
1143 mpGrabBagItem->QueryValue(rVal);
1144 else
1145 rVal <<= uno::Sequence<beans::PropertyValue>();
1146}
1147
1149{
1150 if (!mpGrabBagItem)
1151 mpGrabBagItem = std::make_shared<SfxGrabBagItem>();
1152
1153 mpGrabBagItem->PutValue(rVal, 0);
1154}
1155
1156namespace numfunc
1157{
1158 namespace {
1159
1161 class SwDefBulletConfig : private utl::ConfigItem
1162 {
1163 public:
1164 static SwDefBulletConfig& getInstance();
1165
1166 const OUString& GetFontname() const
1167 {
1168 return msFontname;
1169 }
1170
1171 bool IsFontnameUserDefined() const
1172 {
1173 return mbUserDefinedFontname;
1174 }
1175
1176 const vcl::Font& GetFont() const
1177 {
1178 return *mpFont;
1179 }
1180
1181 sal_Unicode GetChar( sal_uInt8 p_nListLevel ) const
1182 {
1183 if (p_nListLevel >= MAXLEVEL)
1184 {
1185 p_nListLevel = MAXLEVEL - 1;
1186 }
1187
1188 return mnLevelChars[p_nListLevel];
1189 }
1190
1191 SwDefBulletConfig();
1192
1193 private:
1195 void SetToDefault();
1196
1198 static uno::Sequence<OUString> GetPropNames();
1199
1202 void LoadConfig();
1203
1205 void InitFont();
1206
1208 virtual void Notify( const uno::Sequence<OUString>& aPropertyNames ) override;
1209 virtual void ImplCommit() override;
1210
1211 // default bullet list configuration data
1212 OUString msFontname;
1217
1218 // default bullet list font instance
1219 std::optional<vcl::Font> mpFont;
1220 };
1221
1222 }
1223
1224 SwDefBulletConfig& SwDefBulletConfig::getInstance()
1225 {
1226 static SwDefBulletConfig theSwDefBulletConfig;
1227 return theSwDefBulletConfig;
1228 }
1229
1230 SwDefBulletConfig::SwDefBulletConfig()
1231 : ConfigItem( "Office.Writer/Numbering/DefaultBulletList" ),
1232 // default bullet font is now OpenSymbol
1233 msFontname( OUString("OpenSymbol") ),
1234 mbUserDefinedFontname( false ),
1237 {
1238 SetToDefault();
1239 LoadConfig();
1240 InitFont();
1241
1242 // enable notification for changes on default bullet configuration change
1243 EnableNotification( GetPropNames() );
1244 }
1245
1246 void SwDefBulletConfig::SetToDefault()
1247 {
1248 msFontname = "OpenSymbol";
1249 mbUserDefinedFontname = false;
1252
1253 mnLevelChars[0] = 0x2022;
1254 mnLevelChars[1] = 0x25e6;
1255 mnLevelChars[2] = 0x25aa;
1256 mnLevelChars[3] = 0x2022;
1257 mnLevelChars[4] = 0x25e6;
1258 mnLevelChars[5] = 0x25aa;
1259 mnLevelChars[6] = 0x2022;
1260 mnLevelChars[7] = 0x25e6;
1261 mnLevelChars[8] = 0x25aa;
1262 mnLevelChars[9] = 0x2022;
1263 }
1264
1265 uno::Sequence<OUString> SwDefBulletConfig::GetPropNames()
1266 {
1267 uno::Sequence<OUString> aPropNames(13);
1268 OUString* pNames = aPropNames.getArray();
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";
1282
1283 return aPropNames;
1284 }
1285
1286 void SwDefBulletConfig::LoadConfig()
1287 {
1288 uno::Sequence<OUString> aPropNames = GetPropNames();
1289 uno::Sequence<uno::Any> aValues = GetProperties( aPropNames );
1290 const uno::Any* pValues = aValues.getConstArray();
1291 OSL_ENSURE( aValues.getLength() == aPropNames.getLength(),
1292 "<SwDefBulletConfig::SwDefBulletConfig()> - GetProperties failed");
1293 if ( aValues.getLength() != aPropNames.getLength() )
1294 return;
1295
1296 for ( int nProp = 0; nProp < aPropNames.getLength(); ++nProp )
1297 {
1298 if ( pValues[nProp].hasValue() )
1299 {
1300 switch ( nProp )
1301 {
1302 case 0:
1303 {
1304 OUString aStr;
1305 pValues[nProp] >>= aStr;
1306 msFontname = aStr;
1307 mbUserDefinedFontname = true;
1308 }
1309 break;
1310 case 1:
1311 case 2:
1312 {
1313 sal_Int16 nTmp = 0;
1314 pValues[nProp] >>= nTmp;
1315 if ( nProp == 1 )
1316 meFontWeight = static_cast<FontWeight>(nTmp);
1317 else if ( nProp == 2 )
1318 meFontItalic = static_cast<FontItalic>(nTmp);
1319 }
1320 break;
1321 case 3:
1322 case 4:
1323 case 5:
1324 case 6:
1325 case 7:
1326 case 8:
1327 case 9:
1328 case 10:
1329 case 11:
1330 case 12:
1331 {
1332 sal_Unicode cChar = sal_Unicode();
1333 pValues[nProp] >>= cChar;
1334 mnLevelChars[nProp-3] = cChar;
1335 }
1336 break;
1337 }
1338 }
1339 }
1340
1341 }
1342
1343 void SwDefBulletConfig::InitFont()
1344 {
1345 mpFont.emplace( msFontname, OUString(), Size( 0, 14 ) );
1346 mpFont->SetWeight( meFontWeight );
1347 mpFont->SetItalic( meFontItalic );
1348 mpFont->SetCharSet( RTL_TEXTENCODING_SYMBOL );
1349 }
1350
1351 void SwDefBulletConfig::Notify( const uno::Sequence<OUString>& )
1352 {
1353 SetToDefault();
1354 LoadConfig();
1355 InitFont();
1356 }
1357
1358 void SwDefBulletConfig::ImplCommit()
1359 {
1360 }
1361
1362 OUString const & GetDefBulletFontname()
1363 {
1364 return SwDefBulletConfig::getInstance().GetFontname();
1365 }
1366
1368 {
1369 return SwDefBulletConfig::getInstance().IsFontnameUserDefined();
1370 }
1371
1373 {
1374 return SwDefBulletConfig::getInstance().GetFont();
1375 }
1376
1378 {
1379 return SwDefBulletConfig::getInstance().GetChar( nLevel );
1380 }
1381
1382 namespace {
1383
1389 class SwNumberingUIBehaviorConfig : private utl::ConfigItem
1390 {
1391 public:
1392 static SwNumberingUIBehaviorConfig& getInstance();
1393
1395 {
1397 }
1398
1399 SwNumberingUIBehaviorConfig();
1400
1401 private:
1402
1404 void SetToDefault();
1405
1407 static css::uno::Sequence<OUString> GetPropNames();
1408
1410 void LoadConfig();
1411
1413 virtual void Notify( const css::uno::Sequence<OUString>& aPropertyNames ) override;
1414 virtual void ImplCommit() override;
1415
1416 // configuration data
1418 };
1419
1420 }
1421
1422 SwNumberingUIBehaviorConfig& SwNumberingUIBehaviorConfig::getInstance()
1423 {
1424 static SwNumberingUIBehaviorConfig theSwNumberingUIBehaviorConfig;
1425 return theSwNumberingUIBehaviorConfig;
1426 }
1427
1428 SwNumberingUIBehaviorConfig::SwNumberingUIBehaviorConfig()
1429 : ConfigItem( "Office.Writer/Numbering/UserInterfaceBehavior" ),
1431 {
1432 SetToDefault();
1433 LoadConfig();
1434
1435 // enable notification for changes on configuration change
1436 EnableNotification( GetPropNames() );
1437 }
1438
1439 void SwNumberingUIBehaviorConfig::SetToDefault()
1440 {
1442 }
1443
1444 css::uno::Sequence<OUString> SwNumberingUIBehaviorConfig::GetPropNames()
1445 {
1446 css::uno::Sequence<OUString> aPropNames { "ChangeIndentOnTabAtFirstPosOfFirstListItem" };
1447
1448 return aPropNames;
1449 }
1450
1451 void SwNumberingUIBehaviorConfig::ImplCommit() {}
1452
1453 void SwNumberingUIBehaviorConfig::LoadConfig()
1454 {
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() )
1461 return;
1462
1463 for ( int nProp = 0; nProp < aPropNames.getLength(); ++nProp )
1464 {
1465 if ( pValues[nProp].hasValue() )
1466 {
1467 switch ( nProp )
1468 {
1469 case 0:
1470 {
1472 }
1473 break;
1474 default:
1475 {
1476 OSL_FAIL( "<SwNumberingUIBehaviorConfig::LoadConfig()> - unknown configuration property");
1477 }
1478 }
1479 }
1480 }
1481 }
1482
1483 void SwNumberingUIBehaviorConfig::Notify( const css::uno::Sequence<OUString>& )
1484 {
1485 SetToDefault();
1486 LoadConfig();
1487 }
1488
1490 {
1491 return SwNumberingUIBehaviorConfig::getInstance().ChangeIndentOnTabAtFirstPosOfFirstListItem();
1492 }
1493
1495 {
1496 SwPaM* pCursor = rShell.GetCursor();
1497 if (!pCursor)
1498 {
1499 return true;
1500 }
1501
1502 SwTextNode* pTextNode = pCursor->GetPointNode().GetTextNode();
1503 if (!pTextNode)
1504 {
1505 return true;
1506 }
1507
1508 const SwNumRule* pNumRule = pTextNode->GetNumRule();
1509 if (!pNumRule)
1510 {
1511 return true;
1512 }
1513
1514 int nOldLevel = pTextNode->GetActualListLevel();
1515 int nNewLevel = nOldLevel + 1;
1516 if (nNewLevel >= MAXLEVEL)
1517 {
1518 return true;
1519 }
1520
1521 const SwNumFormat& rOldFormat = pNumRule->Get(nOldLevel);
1522 if (rOldFormat.GetNumberingType() != SVX_NUM_NUMBER_NONE)
1523 {
1524 return true;
1525 }
1526
1527 const SwNumFormat& rNewFormat = pNumRule->Get(nNewLevel);
1528 if (rNewFormat.GetNumberingType() != SVX_NUM_NUMBER_NONE)
1529 {
1530 return true;
1531 }
1532
1533 // This is the case when the numbering levels don't differ, so changing between them is not
1534 // a better alternative to inserting a tab character.
1535 return rOldFormat.GetIndentAt() != rNewFormat.GetIndentAt();
1536 }
1537
1539 {
1542
1544 switch (GetODFSaneDefaultVersion())
1545 {
1548 {
1550 }
1551 break;
1552 default: // >= ODFSVER_012
1553 {
1554 ePosAndSpaceMode = SvxNumberFormat::LABEL_ALIGNMENT;
1555 }
1556 }
1557
1558 return ePosAndSpaceMode;
1559 }
1560}
1561
1563{
1564 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwNumRuleTable"));
1565 for (SwNumRule* pNumRule : *this)
1566 pNumRule->dumpAsXml(pWriter);
1567 (void)xmlTextWriterEndElement(pWriter);
1568}
1569
1570/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
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)
SfxHintId GetId() const
const SvxNumberFormat * Get(sal_uInt16 nLevel) const
bool IsContinuousNumbering() const
void SetLevel(sal_uInt16 nLevel, const SvxNumberFormat &rFmt, bool bIsValid=true)
void SetStart(sal_uInt16 nSet)
tools::Long GetIndentAt() const
void SetAbsLSpace(sal_Int32 nSet)
virtual void SetGraphicBrush(const SvxBrushItem *pBrushItem, const Size *pSize=nullptr, const sal_Int16 *pOrient=nullptr)
void SetPositionAndSpaceMode(SvxNumPositionAndSpaceMode ePositionAndSpaceMode)
void SetFirstLineIndent(const tools::Long nFirstLineIndent)
sal_uInt8 GetIncludeUpperLevels() const
const SvxBrushItem * GetBrush() const
bool operator==(const SvxNumberFormat &) const
OUString GetListFormat(bool bIncludePrefixSuffix=true) const
sal_Int32 GetFirstLineOffset() const
void SetCharTextDistance(short nSet)
const Size & GetGraphicSize() const
sal_Int32 GetAbsLSpace() const
LabelFollowedBy GetLabelFollowedBy() const
void SetListFormat(const OUString &rPrefix, const OUString &rSuffix, int nLevel)
bool GetIsLegal() const
tools::Long GetListtabPos() const
void SetIncludeUpperLevels(sal_uInt8 nSet)
void SetIndentAt(const tools::Long nIndentAt)
bool HasListFormat() const
void SetFirstLineOffset(sal_Int32 nSet)
SvxNumPositionAndSpaceMode GetPositionAndSpaceMode() const
SvxNumberFormat & operator=(const SvxNumberFormat &)
void SetBulletChar(sal_UCS4 cSet)
const OUString & GetPrefix() const
void SetLabelFollowedBy(const LabelFollowedBy eLabelFollowedBy)
void SetListtabPos(const tools::Long nListtabPos)
const OUString & GetSuffix() const
sal_Int16 GetVertOrient() const
void SetNumberingType(SvxNumType nSet)
SvxNumType GetNumberingType() const
OUString GetNumStr(sal_Int32 nNo) const
Represents the style of a text portion.
Definition: charfmt.hxx:27
bool ContainsFormat(const SwCharFormat *pFormat) const
fast check if given format is contained here @precond pFormat must not have been deleted
Definition: chrfmt.cxx:127
const SwModify * GetRegisteredIn() const
Definition: calbck.hxx:166
void EndListeningAll()
Definition: calbck.cxx:136
void StartListeningToSameModifyAs(const SwClient &)
Definition: calbck.cxx:128
std::optional< sw::ModifyChangedHint > CheckRegistration(const SfxPoolItem *pOldValue)
Definition: calbck.cxx:77
SwCursor * GetCursor(bool bMakeTableCursor=true) const
Return pointer to the current shell cursor.
Definition: crsrsh.cxx:194
Definition: doc.hxx:197
IDocumentState const & getIDocumentState() const
Definition: doc.cxx:408
bool IsInDtor() const
Definition: doc.hxx:417
const SwNumRuleTable & GetNumRuleTable() const
Definition: doc.hxx:1081
SwCharFormat * FindCharFormatByName(const OUString &rName) const
Definition: doc.hxx:786
const SwCharFormats * GetCharFormats() const
Definition: doc.hxx:755
SwCharFormat * CopyCharFormat(const SwCharFormat &)
copy the char format
Definition: docfmt.cxx:1184
IDocumentStylePoolAccess const & getIDocumentStylePoolAccess() const
Definition: doc.cxx:440
SwCharFormat * MakeCharFormat(const OUString &rFormatName, SwCharFormat *pDerivedFrom, bool bBroadcast=false)
Definition: docfmt.cxx:863
Defines the vertical position of a fly frame.
Definition: fmtornt.hxx:37
void SetVertOrient(sal_Int16 eNew)
Definition: fmtornt.hxx:59
const SwDoc * GetDoc() const
The document is set in SwAttrPool now, therefore you always can access it.
Definition: format.hxx:139
const OUString & GetName() const
Definition: format.hxx:131
Definition: list.hxx:40
SwTextNode * GetTextNode() const
Definition: SwNodeNum.hxx:40
virtual bool IsCounted() const override
Return if this node is counted.
Definition: SwNodeNum.cxx:170
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:901
bool IsEnumeration() const
Definition: number.cxx:237
virtual OUString GetCharFormatName() const override
Definition: number.cxx:311
SwCharFormat * GetCharFormat() const
Definition: numrule.hxx:74
virtual void SwClientNotify(const SwModify &, const SfxHint &) override
Definition: number.cxx:289
sal_Unicode m_cGrfBulletCP
Definition: numrule.hxx:54
void SetCharFormat(SwCharFormat *)
Definition: number.cxx:281
SwNumFormat & operator=(const SwNumFormat &)
Definition: number.cxx:265
const SwFormatVertOrient * GetGraphicOrientation() const
Definition: number.cxx:352
bool operator==(const SwNumFormat &) const
Definition: number.cxx:274
SAL_DLLPRIVATE void UpdateNumNodes(SwDoc &rDoc)
Definition: number.cxx:327
SwFormatVertOrient m_aVertOrient
Definition: numrule.hxx:52
virtual void SetGraphicBrush(const SvxBrushItem *pBrushItem, const Size *pSize=nullptr, const sal_Int16 *pOrient=nullptr) override
Definition: number.cxx:319
virtual ~SwNumFormat() override
Definition: number.cxx:232
void SetCharFormatName(const OUString &rSet)
bool IsItemize() const
Definition: number.cxx:245
void dumpAsXml(xmlTextWriterPtr pWriter) const
Definition: number.cxx:1562
sal_uInt16 mnPoolFormatId
Id-for NumRules created "automatically".
Definition: numrule.hxx:128
OUString MakeRefNumString(const SwNodeNum &rNodeNum, const bool bInclSuperiorNumLabels, const int nRestrictInclToThisLevel) const
Definition: number.cxx:788
bool operator==(const SwNumRule &) const
Definition: number.cxx:583
void dumpAsXml(xmlTextWriterPtr w) const
Definition: number.cxx:1120
SwNumRule(OUString aNm, const SvxNumberFormat::SvxNumPositionAndSpaceMode eDefaultNumberFormatPositionAndSpaceMode, SwNumRuleType=NUM_RULE)
add parameter <eDefaultNumberFormatPositionAndSpaceMode>
Definition: number.cxx:364
void AddParagraphStyle(SwTextFormatColl &rTextFormatColl)
Definition: number.cxx:1098
static SwNumFormat * saBaseFormats[RULE_END][MAXLEVEL]
Definition: numrule.hxx:109
sal_uInt16 mnPoolHelpId
HelpId for this Pool-style.
Definition: numrule.hxx:129
void RemoveParagraphStyle(SwTextFormatColl &rTextFormatColl)
Definition: number.cxx:1109
SvxNumberFormat::SvxNumPositionAndSpaceMode meDefaultNumberFormatPositionAndSpaceMode
it needs to export as part of tracked numbering change
Definition: numrule.hxx:139
sal_uInt8 GetPoolHlpFileId() const
Definition: numrule.hxx:256
std::unique_ptr< SwNumFormat > maFormats[MAXLEVEL]
Definition: numrule.hxx:115
void SetNumRuleMap(std::unordered_map< OUString, SwNumRule * > *pNumRuleMap)
Register this rule in a "name->numrule" map.
Definition: number.cxx:163
SwNumRule::tParagraphStyleList::size_type GetParagraphStyleListSize() const
Definition: number.cxx:1093
void SetSvxRule(const SvxNumRule &, SwDoc *pDoc)
Definition: number.cxx:925
SwNumRule::tTextNodeList::size_type GetTextNodeListSize() const
Definition: number.cxx:136
bool mbAutoRuleFlag
Definition: numrule.hxx:131
~SwNumRule()
Definition: number.cxx:481
static sal_uInt16 GetBullIndent(sal_uInt8 nLvl)
Definition: number.cxx:175
const SwNumFormat * GetNumFormat(sal_uInt16 i) const
Definition: number.cxx:97
void ChangeIndent(const sal_Int32 nDiff)
change indent of all list levels by given difference
Definition: number.cxx:984
void SetName(const OUString &rNm, IDocumentListsAccess &rDocListAccess)
Definition: number.cxx:111
void SetIndentOfFirstListLevelAndChangeOthers(const short nNewIndent)
set indent of first list level to given value and change other list level's indents accordingly
Definition: number.cxx:1052
bool IsContinusNum() const
Definition: numrule.hxx:235
void SetCountPhantoms(bool bCountPhantoms)
Definition: number.cxx:1088
bool mbContinusNum
Continuous numbering without levels.
Definition: numrule.hxx:133
const OUString & GetDefaultListId() const
Definition: numrule.hxx:194
static const sal_uInt16 saDefNumIndents[MAXLEVEL]
Definition: numrule.hxx:110
const SwNumFormat & Get(sal_uInt16 i) const
Definition: number.cxx:87
void RemoveTextNode(SwTextNode &rTextNode)
Definition: number.cxx:152
void Set(sal_uInt16 i, const SwNumFormat *)
Definition: number.cxx:618
void SetInvalidRule(bool bFlag)
Definition: number.cxx:958
const OUString & GetName() const
Definition: numrule.hxx:224
static OUString GetOutlineRuleName()
Definition: number.cxx:82
sal_uInt16 GetPoolFormatId() const
Query and set PoolFormat IDs.
Definition: numrule.hxx:250
static SwNumFormat * saLabelAlignmentBaseFormats[RULE_END][MAXLEVEL]
default list level properties for position-and-space mode LABEL_ALIGNMENT
Definition: numrule.hxx:112
static sal_uInt16 snRefCount
Definition: numrule.hxx:113
std::unordered_map< OUString, SwNumRule * > * mpNumRuleMap
unordered_map containing "name->rule" relation
Definition: numrule.hxx:124
void SetIndent(const short nNewIndent, const sal_uInt16 nListLevel)
set indent of certain list level to given value
Definition: number.cxx:1023
SvxNumRule MakeSvxNumRule() const
Definition: number.cxx:937
std::vector< SwTextNode * > tTextNodeList
Definition: numrule.hxx:97
OUString MakeNumString(const SwNodeNum &, bool bInclStrings=true) const
Definition: number.cxx:643
SwNumRule & operator=(const SwNumRule &)
Definition: number.cxx:545
void AddTextNode(SwTextNode &rTextNode)
Definition: number.cxx:141
void Validate(const SwDoc &rDoc)
Definition: number.cxx:1075
sal_uInt8 mnPoolHlpFileId
FilePos at Doc on style helps.
Definition: numrule.hxx:130
void GetGrabBagItem(css::uno::Any &rVal) const
Definition: number.cxx:1140
void SetGrabBagItem(const css::uno::Any &rVal)
Definition: number.cxx:1148
OUString MakeParagraphStyleListString() const
Definition: number.cxx:884
OUString msName
Definition: numrule.hxx:126
static sal_uInt16 GetNumIndent(sal_uInt8 nLvl)
Definition: number.cxx:169
void Reset(const OUString &rName)
Definition: number.cxx:566
tParagraphStyleList maParagraphStyleList
container for associated paragraph styles
Definition: numrule.hxx:121
bool mbHidden
Is the numbering rule to be hidden in the UI?
Definition: numrule.hxx:135
bool mbCountPhantoms
Definition: numrule.hxx:136
void CheckCharFormats(SwDoc &rDoc)
Tests whether the CharFormats are from the given doc and copies them if appropriate.
Definition: number.cxx:527
sal_uInt16 GetPoolHelpId() const
Query and set Help-IDs for document styles.
Definition: numrule.hxx:254
SwNumRuleType meRuleType
Definition: numrule.hxx:127
bool mbAbsSpaces
Levels represent absolute indents.
Definition: numrule.hxx:134
tTextNodeList maTextNodeList
container for associated text nodes
Definition: numrule.hxx:118
bool mbInvalidRuleFlag
Definition: numrule.hxx:132
void GetTextNodeList(SwNumRule::tTextNodeList &rTextNodeList) const
Definition: number.cxx:131
SwNumRule & CopyNumRule(SwDoc &, const SwNumRule &)
A kind of copy-constructor to make sure the num formats are attached to the correctCharFormats of a d...
Definition: number.cxx:901
std::shared_ptr< SfxGrabBagItem > mpGrabBagItem
Style InteropGrabBag.
Definition: numrule.hxx:141
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.
Definition: pam.hxx:188
SwNode & GetPointNode() const
Definition: pam.hxx:275
static SW_DLLPUBLIC sal_uInt16 GetPoolIdFromUIName(const OUString &rName, SwGetPoolIdFromName)
Represents the style of a paragraph.
Definition: fmtcol.hxx:61
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:112
SwNumRule * GetNumRule(bool bInParent=true) const
Returns numbering rule of this text node.
Definition: ndtxt.cxx:2921
bool HasNumber(SwRootFrame const *pLayout=nullptr) const
Returns if this text node has a number.
Definition: ndtxt.cxx:3213
int GetActualListLevel(SwListRedlineType eRedline=SwListRedlineType::SHOW) const
Returns the actual list level of this text node, when it is a list item.
Definition: ndtxt.cxx:4248
void NumRuleChgd()
Notify this textnode that its numbering rule has changed.
Definition: ndtxt.cxx:2961
std::vector< SwNumRule * >::size_type size_type
Definition: docary.hxx:67
size_t size() const
Definition: docary.hxx:88
Used by the UI to modify the document model.
Definition: wrtsh.hxx:97
std::pair< const_iterator, bool > insert(Value &&x)
static bool IsFuzzing()
struct _xmlTextWriter * xmlTextWriterPtr
virtual OUString GetName() const override
float u
DocumentType eType
FontItalic
ITALIC_NONE
WEIGHT_DONTKNOW
void Notify(SwFlyFrame *pFly, SwPageFrame *pOld, const SwRect &rOld, const SwRect *pOldRect=nullptr)
Notify the background based on the difference between old and new rectangle.
Definition: frmtool.cxx:3254
constexpr TypedWhichId< SwAttrSetChg > RES_ATTRSET_CHG(169)
constexpr TypedWhichId< SwFormatChg > RES_FMT_CHG(168)
sal_Int64 n
OUString sSuffix
OUString sPrefix
aStr
def text(shape, orig_st)
std::vector< tSwNumTreeNumber > tNumberVector
int i
namespace for static functions and methods for numbering and bullets
Definition: number.cxx:1157
bool IsDefBulletFontUserDefined()
determine if default bullet font is user defined
Definition: number.cxx:1367
SvxNumberFormat::SvxNumPositionAndSpaceMode GetDefaultPositionAndSpaceMode()
Definition: number.cxx:1538
bool ChangeIndentOnTabAtFirstPosOfFirstListItem()
configuration, if at first position of the first list item the <TAB>-key increased the indent of the ...
Definition: number.cxx:1489
sal_Unicode GetBulletChar(sal_uInt8 nLevel)
retrieve unicode of character used for the default bullet list for the given list level
Definition: number.cxx:1377
bool NumDownChangesIndent(const SwWrtShell &rShell)
Decides if increasing ("downing") the numbering level will change the amount of indentation or not.
Definition: number.cxx:1494
OUString const & GetDefBulletFontname()
retrieve font family name used for the default bullet list characters
Definition: number.cxx:1362
const vcl::Font & GetDefBulletFont()
retrieve font used for the default bullet list characters
Definition: number.cxx:1372
constexpr auto toTwips(N number, Length from)
FontWeight
long Long
vcl::Font GetFont(vcl::Font const &rFont, DrawModeFlags nDrawMode, StyleSettings const &rStyleSettings)
std::optional< vcl::Font > mpFont
Definition: number.cxx:1219
bool mbChangeIndentOnTabAtFirstPosOfFirstListItem
Definition: number.cxx:1417
OUString msFontname
Definition: number.cxx:1212
bool mbUserDefinedFontname
Definition: number.cxx:1213
sal_Unicode mnLevelChars[MAXLEVEL]
Definition: number.cxx:1216
FontWeight meFontWeight
Definition: number.cxx:1214
FontItalic meFontItalic
Definition: number.cxx:1215
static void lcl_SetRuleChgd(SwTextNode &rNd, sal_uInt8 nLevel)
Definition: number.cxx:181
SwNumRuleType
Definition: numrule.hxx:92
@ OUTLINE_RULE
Definition: numrule.hxx:92
@ NUM_RULE
Definition: numrule.hxx:92
@ RULE_END
Definition: numrule.hxx:92
sal_Int16 nId
const PropertyStruct aPropNames[]
UNOTOOLS_DLLPUBLIC SvtSaveOptions::ODFSaneDefaultVersion GetODFSaneDefaultVersion()
static LanguageType nLang
Definition: srtdlg.cxx:51
sal_uInt16 nSuffixChars
Definition: numrule.hxx:103
sal_uInt16 nPrefixChars
Definition: numrule.hxx:102
SVX_NUM_NUMBER_NONE
SVX_NUM_ARABIC
SVX_NUM_BITMAP
SVX_NUM_CHAR_SPECIAL
constexpr sal_uInt16 lNumberIndent
Definition: swtypes.hxx:100
constexpr short lNumberFirstLineOffset
Definition: swtypes.hxx:101
constexpr short lOutlineMinTextDistance
Definition: swtypes.hxx:102
constexpr sal_uInt8 MAXLEVEL
Definition: swtypes.hxx:92
OUString msName
unsigned char sal_uInt8
sal_uInt16 sal_Unicode