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