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