LibreOffice Module svx (master)  1
nbdtmg.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 #include <svx/nbdtmg.hxx>
20 #include <svx/svxids.hrc>
21 #include <vcl/svapp.hxx>
22 #include <svl/itemset.hxx>
23 #include <sfx2/request.hxx>
24 #include <svl/stritem.hxx>
25 #include <svtools/ctrltool.hxx>
26 #include <sfx2/objsh.hxx>
27 #include <editeng/flstitem.hxx>
28 #include <svl/itempool.hxx>
29 #include <vcl/outdev.hxx>
30 #include <editeng/brushitem.hxx>
31 #include <svx/dialmgr.hxx>
32 #include <svx/strings.hrc>
33 #include <vcl/graph.hxx>
34 #include <vcl/settings.hxx>
35 
37 #include <o3tl/temporary.hxx>
38 #include <tools/debug.hxx>
39 #include <tools/urlobj.hxx>
41 #include <unotools/pathoptions.hxx>
42 #include <editeng/eeitem.hxx>
43 
44 #include <com/sun/star/text/VertOrientation.hpp>
45 #include <com/sun/star/style/NumberingType.hpp>
46 #include <com/sun/star/container/XIndexAccess.hpp>
47 #include <com/sun/star/text/DefaultNumberingProvider.hpp>
48 #include <com/sun/star/beans/PropertyValue.hpp>
50 #include <memory>
51 
52 using namespace com::sun::star;
53 using namespace com::sun::star::uno;
54 using namespace com::sun::star::beans;
55 using namespace com::sun::star::lang;
56 using namespace com::sun::star::text;
57 using namespace com::sun::star::container;
58 using namespace com::sun::star::style;
59 
60 namespace svx::sidebar {
61 
62 namespace {
63 
65 {
66  static vcl::Font aDefBulletFont = [&]()
67  {
68  static vcl::Font tmp("OpenSymbol", "", Size(0, 14));
69  tmp.SetCharSet( RTL_TEXTENCODING_SYMBOL );
70  tmp.SetFamily( FAMILY_DONTKNOW );
71  tmp.SetPitch( PITCH_DONTKNOW );
72  tmp.SetWeight( WEIGHT_DONTKNOW );
73  tmp.SetTransparent( true );
74  return tmp;
75  }();
76  return aDefBulletFont;
77 }
78 
79 const sal_Unicode aDefaultBulletTypes[] =
80 {
81  0x2022,
82  0x25cf,
83  0xe00c,
84  0xe00a,
85  0x2794,
86  0x27a2,
87  0x2717,
88  0x2714
89 };
90 
91 NumSettings_Impl* lcl_CreateNumberingSettingsPtr(const Sequence<PropertyValue>& rLevelProps)
92 {
93  NumSettings_Impl* pNew = new NumSettings_Impl;
94  for(const PropertyValue& rValue : rLevelProps)
95  {
96  if(rValue.Name == "NumberingType")
97  {
98  sal_Int16 nTmp;
99  if (rValue.Value >>= nTmp)
100  pNew->nNumberType = static_cast<SvxNumType>(nTmp);
101  }
102  else if(rValue.Name == "Prefix")
103  rValue.Value >>= pNew->sPrefix;
104  else if(rValue.Name == "Suffix")
105  rValue.Value >>= pNew->sSuffix;
106  else if(rValue.Name == "ParentNumbering")
107  rValue.Value >>= pNew->nParentNumbering;
108  else if(rValue.Name == "BulletChar")
109  rValue.Value >>= pNew->sBulletChar;
110  else if(rValue.Name == "BulletFontName")
111  rValue.Value >>= pNew->sBulletFont;
112  }
113  const sal_Unicode cLocalPrefix = pNew->sPrefix.getLength() ? pNew->sPrefix[0] : 0;
114  const sal_Unicode cLocalSuffix = pNew->sSuffix.getLength() ? pNew->sSuffix[0] : 0;
115  if( cLocalPrefix == ' ') pNew->sPrefix.clear();
116  if( cLocalSuffix == ' ') pNew->sSuffix.clear();
117  return pNew;
118 }
119 
120 }
121 
122 sal_uInt16 NBOTypeMgrBase:: IsSingleLevel(sal_uInt16 nCurLevel)
123 {
124  sal_uInt16 nLv = sal_uInt16(0xFFFF);
125  sal_uInt16 nCount = 0;
126  sal_uInt16 nMask = 1;
127  for( sal_uInt16 i = 0; i < SVX_MAX_NUM; i++ )
128  {
129  if(nCurLevel & nMask)
130  {
131  nCount++;
132  nLv=i;
133  }
134  nMask <<= 1 ;
135  }
136 
137  if ( nCount == 1)
138  return nLv;
139  else
140  return sal_uInt16(0xFFFF);
141 }
142 
143 void NBOTypeMgrBase::SetItems(const SfxItemSet* pArg) {
144  pSet = pArg;
145  if ( !pSet )
146  return;
147 
148  SfxAllItemSet aSet(*pSet);
149 
150  const SfxStringItem* pBulletCharFmt = aSet.GetItem<SfxStringItem>(SID_BULLET_CHAR_FMT, false);
151  if (pBulletCharFmt)
152  aBulletCharFmtName = pBulletCharFmt->GetValue();
153 
154  const SfxStringItem* pNumCharFmt = aSet.GetItem<SfxStringItem>(SID_NUM_CHAR_FMT, false);
155  if (pNumCharFmt)
156  aNumCharFmtName = pNumCharFmt->GetValue();
157 
158  const SfxPoolItem* pItem;
159  SfxItemState eState = pSet->GetItemState(SID_ATTR_NUMBERING_RULE, false, &pItem);
160  if(eState == SfxItemState::SET)
161  {
162  eCoreUnit = pSet->GetPool()->GetMetric(pSet->GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE));
163  } else {
164  //sd use different sid for numbering rule
165  eState = pSet->GetItemState(EE_PARA_NUMBULLET, false, &pItem);
166  if(eState == SfxItemState::SET)
167  {
168  eCoreUnit = pSet->GetPool()->GetMetric(pSet->GetPool()->GetWhich(EE_PARA_NUMBULLET));
169  }
170  }
171 }
172 
173 void NBOTypeMgrBase::ImplLoad(std::u16string_view filename)
174 {
175  bIsLoading = true;
176  MapUnit eOldCoreUnit=eCoreUnit;
177  eCoreUnit = MapUnit::Map100thMM;
178  INetURLObject aFile( SvtPathOptions().GetUserConfigPath() );
179  aFile.Append( filename);
180  std::unique_ptr<SvStream> xIStm(::utl::UcbStreamHelper::CreateStream( aFile.GetMainURL( INetURLObject::DecodeMechanism::NONE ), StreamMode::READ ));
181  if( xIStm ) {
182  sal_uInt32 nVersion = 0;
183  sal_Int32 nNumIndex = 0;
184  xIStm->ReadUInt32( nVersion );
185  if (nVersion==DEFAULT_NUMBERING_CACHE_FORMAT_VERSION) //first version
186  {
187  xIStm->ReadInt32( nNumIndex );
188  while (nNumIndex>=0 && nNumIndex<DEFAULT_NUM_VALUSET_COUNT) {
189  SvxNumRule aNum(*xIStm);
190  //bullet color in font properties is not stored correctly. Need set transparency bits manually
191  for(sal_uInt16 i = 0; i < aNum.GetLevelCount(); i++)
192  {
193  SvxNumberFormat aFmt(aNum.GetLevel(i));
194  if (aFmt.GetBulletFont()) {
195  vcl::Font aFont(*aFmt.GetBulletFont());
196  Color c=aFont.GetColor();
197  c.SetAlpha(0);
198  aFont.SetColor(c);
199  aFmt.SetBulletFont(&aFont);
200  aNum.SetLevel(i, aFmt);
201  }
202  }
203  RelplaceNumRule(aNum,nNumIndex,0x1/*nLevel*/);
204  xIStm->ReadInt32( nNumIndex );
205  }
206  }
207  }
208  eCoreUnit = eOldCoreUnit;
209  bIsLoading = false;
210 }
211 void NBOTypeMgrBase::ImplStore(std::u16string_view filename)
212 {
213  if (bIsLoading) return;
214  MapUnit eOldCoreUnit=eCoreUnit;
215  eCoreUnit = MapUnit::Map100thMM;
216  INetURLObject aFile( SvtPathOptions().GetUserConfigPath() );
217  aFile.Append( filename);
218  std::unique_ptr<SvStream> xOStm(::utl::UcbStreamHelper::CreateStream( aFile.GetMainURL( INetURLObject::DecodeMechanism::NONE ), StreamMode::WRITE ));
219  if( xOStm ) {
220  sal_uInt32 nVersion;
221  sal_Int32 nNumIndex;
223  xOStm->WriteUInt32( nVersion );
224  for(sal_Int32 nItem = 0; nItem < DEFAULT_NUM_VALUSET_COUNT; nItem++ ) {
225  if (IsCustomized(nItem)) {
226  SvxNumRule aDefNumRule( SvxNumRuleFlags::BULLET_REL_SIZE | SvxNumRuleFlags::CONTINUOUS | SvxNumRuleFlags::BULLET_COLOR,
227  10, false,
228  SvxNumRuleType::NUMBERING, SvxNumberFormat::LABEL_ALIGNMENT);
229  xOStm->WriteInt32( nItem );
230  ApplyNumRule(aDefNumRule,nItem,0x1/*nLevel*/,false,true);
231  aDefNumRule.Store(*xOStm);
232  }
233  }
234  nNumIndex = -1;
235  xOStm->WriteInt32( nNumIndex ); //write end flag
236  }
237  eCoreUnit = eOldCoreUnit;
238 }
239 
240 // Character Bullet Type lib
241 BulletsSettings* BulletsTypeMgr::pActualBullets[] ={nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr};
242 sal_Unicode BulletsTypeMgr::aDynamicBulletTypes[]={' ',' ',' ',' ',' ',' ',' ',' '};
243 sal_Unicode BulletsTypeMgr::aDynamicRTLBulletTypes[]={' ',' ',' ',' ',' ',' ',' ',' '};
244 
245 BulletsTypeMgr::BulletsTypeMgr()
246  : NBOTypeMgrBase()
247 {
248  Init();
249 }
250 
252 {
253  static BulletsTypeMgr theBulletsTypeMgr;
254  return theBulletsTypeMgr;
255 }
256 
258 {
259  const vcl::Font& rActBulletFont = lcl_GetDefaultBulletFont();
260 
261  for (sal_uInt16 i=0;i<DEFAULT_BULLET_TYPES;i++)
262  {
264  pActualBullets[i]->cBulletChar = aDefaultBulletTypes[i];
265  pActualBullets[i]->aFont = rActBulletFont;
266  pActualBullets[i]->sDescription = SvxResId( RID_SVXSTR_BULLET_DESCRIPTION_0 + i );
267  }
268 }
269 sal_uInt16 BulletsTypeMgr::GetNBOIndexForNumRule(SvxNumRule& aNum,sal_uInt16 mLevel,sal_uInt16 nFromIndex)
270 {
271  if ( mLevel == sal_uInt16(0xFFFF) || mLevel == 0)
272  return sal_uInt16(0xFFFF);
273  //if ( !lcl_IsNumFmtSet(pNR, mLevel) ) return (sal_uInt16)0xFFFF;
274 
275  sal_uInt16 nActLv = IsSingleLevel(mLevel);
276 
277  if ( nActLv == sal_uInt16(0xFFFF) )
278  return sal_uInt16(0xFFFF);
279 
280  const SvxNumberFormat& aFmt(aNum.GetLevel(nActLv));
281  sal_UCS4 cChar = aFmt.GetBulletChar();
282  for(sal_uInt16 i = nFromIndex; i < DEFAULT_BULLET_TYPES; i++)
283  {
284  if ( (cChar == pActualBullets[i]->cBulletChar) ||
285  (cChar == 9830 && 57356 == pActualBullets[i]->cBulletChar) ||
286  (cChar == 9632 && 57354 == pActualBullets[i]->cBulletChar) )
287  {
288  return i+1;
289  }
290  }
291 
292  return sal_uInt16(0xFFFF);
293 }
294 
295 void BulletsTypeMgr::RelplaceNumRule(SvxNumRule& aNum, sal_uInt16 nIndex, sal_uInt16 mLevel)
296 {
297  if ( mLevel == sal_uInt16(0xFFFF) || mLevel == 0)
298  return;
299 
300  if ( GetNBOIndexForNumRule(aNum,mLevel) != sal_uInt16(0xFFFF) )
301  return;
302 
303  sal_uInt16 nActLv = IsSingleLevel(mLevel);
304 
305  if ( nActLv == sal_uInt16(0xFFFF) )
306  return;
307 
308  SvxNumberFormat aFmt(aNum.GetLevel(nActLv));
309  sal_UCS4 cChar = aFmt.GetBulletChar();
310  const vcl::Font* pFont = aFmt.GetBulletFont();
311  if ( nIndex >= DEFAULT_BULLET_TYPES )
312  return;
313 
314  pActualBullets[nIndex]->cBulletChar = cChar;
315  if ( pFont )
316  pActualBullets[nIndex]->aFont = *pFont;
317  pActualBullets[nIndex]->bIsCustomized = true;
318 }
319 
320 void BulletsTypeMgr::ApplyNumRule(SvxNumRule& aNum, sal_uInt16 nIndex, sal_uInt16 mLevel, bool /*isDefault*/, bool isResetSize)
321 {
322  if ( nIndex >= DEFAULT_BULLET_TYPES )
323  return;
324  sal_UCS4 cChar = pActualBullets[nIndex]->cBulletChar;
325  const vcl::Font& rActBulletFont = pActualBullets[nIndex]->aFont;
326 
327  sal_uInt16 nMask = 1;
328  OUString sBulletCharFormatName = GetBulletCharFmtName();
329  for(sal_uInt16 i = 0; i < aNum.GetLevelCount(); i++)
330  {
331  if(mLevel & nMask)
332  {
333  SvxNumberFormat aFmt(aNum.GetLevel(i));
335  aFmt.SetBulletFont(&rActBulletFont);
336  aFmt.SetBulletChar(cChar);
337  aFmt.SetCharFormatName(sBulletCharFormatName);
338  aFmt.SetListFormat( "" );
339  if (isResetSize) aFmt.SetBulletRelSize(45);
340  aNum.SetLevel(i, aFmt);
341  }
342  nMask <<= 1;
343  }
344 }
345 
346 OUString BulletsTypeMgr::GetDescription(sal_uInt16 nIndex, bool /*isDefault*/)
347 {
348  OUString sRet;
349 
350  if ( nIndex >= DEFAULT_BULLET_TYPES )
351  return sRet;
352  else
353  sRet = pActualBullets[nIndex]->sDescription;
354 
355  return sRet;
356 }
357 
358 bool BulletsTypeMgr::IsCustomized(sal_uInt16 nIndex)
359 {
360  bool bRet = false;
361 
362  if ( nIndex >= DEFAULT_BULLET_TYPES )
363  bRet = false;
364  else
365  bRet = pActualBullets[nIndex]->bIsCustomized;
366 
367  return bRet;
368 }
369 
370 // Numbering Type lib
372  : NBOTypeMgrBase()
373 {
374  Init();
376  ImplLoad(u"standard.syb");
377 }
378 
380 {
381 }
382 
383 static const char* RID_SVXSTR_SINGLENUM_DESCRIPTIONS[] =
384 {
385  RID_SVXSTR_SINGLENUM_DESCRIPTION_0,
386  RID_SVXSTR_SINGLENUM_DESCRIPTION_1,
387  RID_SVXSTR_SINGLENUM_DESCRIPTION_2,
388  RID_SVXSTR_SINGLENUM_DESCRIPTION_3,
389  RID_SVXSTR_SINGLENUM_DESCRIPTION_4,
390  RID_SVXSTR_SINGLENUM_DESCRIPTION_5,
391  RID_SVXSTR_SINGLENUM_DESCRIPTION_6,
392  RID_SVXSTR_SINGLENUM_DESCRIPTION_7
393 };
394 
396 {
397  static NumberingTypeMgr theNumberingTypeMgr;
398  return theNumberingTypeMgr;
399 }
400 
402 {
403  Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();
404  Reference<XDefaultNumberingProvider> xDefNum = DefaultNumberingProvider::create( xContext );
405 
407  Locale aLocale(Application::GetSettings().GetLanguageTag().getLocale());
408  try
409  {
410  aNumberings = xDefNum->getDefaultContinuousNumberingLevels( aLocale );
411 
412  sal_Int32 nLength = aNumberings.getLength();
413 
414  const Sequence<PropertyValue>* pValuesArr = aNumberings.getConstArray();
415  for(sal_Int32 i = 0; i < nLength; i++)
416  {
417  NumSettings_Impl* pNew = lcl_CreateNumberingSettingsPtr(pValuesArr[i]);
418  std::shared_ptr<NumberSettings_Impl> pNumEntry = std::make_shared<NumberSettings_Impl>();
419  pNumEntry->pNumSetting = pNew;
420  if ( i < 8 )
421  pNumEntry->sDescription = SvxResId(RID_SVXSTR_SINGLENUM_DESCRIPTIONS[i]);
422  maNumberSettingsArr.push_back(pNumEntry);
423  }
424  }
425  catch(Exception&)
426  {
427  }
428 }
429 
430 sal_uInt16 NumberingTypeMgr::GetNBOIndexForNumRule(SvxNumRule& aNum,sal_uInt16 mLevel,sal_uInt16 nFromIndex)
431 {
432  if ( mLevel == sal_uInt16(0xFFFF) || mLevel > aNum.GetLevelCount() || mLevel == 0)
433  return sal_uInt16(0xFFFF);
434 
435  sal_uInt16 nActLv = IsSingleLevel(mLevel);
436 
437  if ( nActLv == sal_uInt16(0xFFFF) )
438  return sal_uInt16(0xFFFF);
439 
440  const SvxNumberFormat& aFmt(aNum.GetLevel(nActLv));
441  //sal_Unicode cPrefix = OUString(aFmt.GetPrefix())[0];
442  //sal_Unicode cSuffix = :OUString(aFmt.GetSuffix())[0];
443  const OUString& sPrefix = aFmt.GetPrefix();
444  const OUString& sLclSuffix = aFmt.GetSuffix();
445  sal_Int16 eNumType = aFmt.GetNumberingType();
446 
447  sal_uInt16 nCount = maNumberSettingsArr.size();
448  for(sal_uInt16 i = nFromIndex; i < nCount; ++i)
449  {
450  NumberSettings_Impl* _pSet = maNumberSettingsArr[i].get();
451  sal_Int16 eNType = _pSet->pNumSetting->nNumberType;
452  OUString sLocalPrefix = _pSet->pNumSetting->sPrefix;
453  OUString sLocalSuffix = _pSet->pNumSetting->sSuffix;
454  if (sPrefix == sLocalPrefix &&
455  sLclSuffix == sLocalSuffix &&
456  eNumType == eNType )
457  {
458  return i+1;
459  }
460  }
461 
462 
463  return sal_uInt16(0xFFFF);
464 }
465 
466 void NumberingTypeMgr::RelplaceNumRule(SvxNumRule& aNum, sal_uInt16 nIndex, sal_uInt16 mLevel)
467 {
468  sal_uInt16 nActLv = IsSingleLevel(mLevel);
469 
470  if ( nActLv == sal_uInt16(0xFFFF) )
471  return;
472 
473  const SvxNumberFormat& aFmt(aNum.GetLevel(nActLv));
474  SvxNumType eNumType = aFmt.GetNumberingType();
475 
476  sal_uInt16 nCount = maNumberSettingsArr.size();
477  if ( nIndex >= nCount )
478  return;
479 
480  NumberSettings_Impl* _pSet = maNumberSettingsArr[nIndex].get();
481 
482  _pSet->pNumSetting->sPrefix = aFmt.GetPrefix();
483  _pSet->pNumSetting->sSuffix = aFmt.GetSuffix();
484  _pSet->pNumSetting->nNumberType = eNumType;
485  _pSet->bIsCustomized = true;
486 
487  SvxNumRule aTmpRule1(aNum);
488  SvxNumRule aTmpRule2(aNum);
489  ApplyNumRule(aTmpRule1,nIndex,mLevel,true);
490  ApplyNumRule(aTmpRule2,nIndex,mLevel);
491  if (aTmpRule1==aTmpRule2) _pSet->bIsCustomized=false;
492  if (!_pSet->bIsCustomized) {
493  _pSet->sDescription = GetDescription(nIndex,true);
494  }
495  ImplStore(u"standard.syb");
496 }
497 
498 void NumberingTypeMgr::ApplyNumRule(SvxNumRule& aNum, sal_uInt16 nIndex, sal_uInt16 mLevel, bool isDefault, bool isResetSize)
499 {
500  if(maNumberSettingsArr.size() <= nIndex)
501  return;
502  NumberSettingsArr_Impl* pCurrentNumberSettingsArr = &maNumberSettingsArr;
503  if (isDefault) pCurrentNumberSettingsArr = &maDefaultNumberSettingsArr;
504  NumberSettings_Impl* _pSet = (*pCurrentNumberSettingsArr)[nIndex].get();
505  SvxNumType eNewType = _pSet->pNumSetting->nNumberType;
506 
507  sal_uInt16 nMask = 1;
508  OUString sNumCharFmtName = GetNumCharFmtName();
509  for(sal_uInt16 i = 0; i < aNum.GetLevelCount(); i++)
510  {
511  if(mLevel & nMask)
512  {
513  SvxNumberFormat aFmt(aNum.GetLevel(i));
514  if (eNewType!=aFmt.GetNumberingType()) isResetSize=true;
515  aFmt.SetNumberingType(eNewType);
516  aFmt.SetListFormat(_pSet->pNumSetting->sPrefix, _pSet->pNumSetting->sSuffix, i);
517  aFmt.SetCharFormatName(sNumCharFmtName);
518  if (isResetSize) aFmt.SetBulletRelSize(100);
519  aNum.SetLevel(i, aFmt);
520  }
521  nMask <<= 1 ;
522  }
523 }
524 
525 OUString NumberingTypeMgr::GetDescription(sal_uInt16 nIndex, bool isDefault)
526 {
527  OUString sRet;
528  sal_uInt16 nLength = maNumberSettingsArr.size();
529 
530  if ( nIndex >= nLength )
531  return sRet;
532  else
533  sRet = maNumberSettingsArr[nIndex]->sDescription;
534  if (isDefault) sRet = maDefaultNumberSettingsArr[nIndex]->sDescription;
535 
536  return sRet;
537 }
538 
539 bool NumberingTypeMgr::IsCustomized(sal_uInt16 nIndex)
540 {
541  bool bRet = false;
542  sal_uInt16 nLength = maNumberSettingsArr.size();
543 
544  if ( nIndex >= nLength )
545  bRet = false;
546  else
547  bRet = maNumberSettingsArr[nIndex]->bIsCustomized;
548 
549  return bRet;
550 }
551 // Multi-level /Outline Type lib
553  : NBOTypeMgrBase()
554 {
555  Init();
556  for(sal_Int32 nItem = 0; nItem < DEFAULT_NUM_VALUSET_COUNT; nItem++ )
557  {
559  }
560  //Initial the first time to store the default value. Then do it again for customized value
561  Init();
562  ImplLoad(u"standard.syc");
563 }
564 
566 {
567  static OutlineTypeMgr theOutlineTypeMgr;
568  return theOutlineTypeMgr;
569 }
570 
572 {
573  Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();
574  Reference<XDefaultNumberingProvider> xDefNum = DefaultNumberingProvider::create( xContext );
575 
576  Sequence<Reference<XIndexAccess> > aOutlineAccess;
577  Locale aLocale(Application::GetSettings().GetLanguageTag().getLocale());
578  try
579  {
580  aOutlineAccess = xDefNum->getDefaultOutlineNumberings( aLocale );
581 
582  SvxNumRule aDefNumRule( SvxNumRuleFlags::BULLET_REL_SIZE | SvxNumRuleFlags::CONTINUOUS | SvxNumRuleFlags::BULLET_COLOR,
583  10, false,
584  SvxNumRuleType::NUMBERING, SvxNumberFormat::LABEL_ALIGNMENT);
585 
586  auto nSize = std::min<sal_Int32>(aOutlineAccess.getLength(), DEFAULT_NUM_VALUSET_COUNT);
587  for(sal_Int32 nItem = 0; nItem < nSize; nItem++ )
588  {
590  OutlineSettings_Impl* pItemArr = pOutlineSettingsArrs[ nItem ];
591  pItemArr->sDescription = SvxResId( RID_SVXSTR_OUTLINENUM_DESCRIPTION_0 + nItem );
592  pItemArr->pNumSettingsArr = new NumSettingsArr_Impl;
593  Reference<XIndexAccess> xLevel = aOutlineAccess.getConstArray()[nItem];
594  for(sal_Int32 nLevel = 0; nLevel < xLevel->getCount() && nLevel < 5; nLevel++)
595  {
596  Any aValueAny = xLevel->getByIndex(nLevel);
597  Sequence<PropertyValue> aLevelProps;
598  aValueAny >>= aLevelProps;
599  NumSettings_Impl* pNew = lcl_CreateNumberingSettingsPtr(aLevelProps);
600  const SvxNumberFormat& aNumFmt( aDefNumRule.GetLevel( nLevel) );
601  pNew->eLabelFollowedBy = aNumFmt.GetLabelFollowedBy();
602  pNew->nTabValue = aNumFmt.GetListtabPos();
603  pNew->eNumAlign = aNumFmt.GetNumAdjust();
604  pNew->nNumAlignAt = aNumFmt.GetFirstLineIndent();
605  pNew->nNumIndentAt = aNumFmt.GetIndentAt();
606  pItemArr->pNumSettingsArr->push_back(std::shared_ptr<NumSettings_Impl>(pNew));
607  }
608  }
609  }
610  catch(Exception&)
611  {
612  }
613 }
614 
615 sal_uInt16 OutlineTypeMgr::GetNBOIndexForNumRule(SvxNumRule& aNum,sal_uInt16 /*mLevel*/,sal_uInt16 nFromIndex)
616 {
617  sal_uInt16 const nLength = SAL_N_ELEMENTS(pOutlineSettingsArrs);
618  for(sal_uInt16 iDex = nFromIndex; iDex < nLength; iDex++)
619  {
620  bool bNotMatch = false;
621  OutlineSettings_Impl* pItemArr = pOutlineSettingsArrs[iDex];
622  sal_uInt16 nCount = pItemArr->pNumSettingsArr->size();
623  for (sal_uInt16 iLevel=0;iLevel < nCount;iLevel++)
624  {
625  NumSettings_Impl* _pSet = (*pItemArr->pNumSettingsArr)[iLevel].get();
626  sal_Int16 eNType = _pSet->nNumberType;
627 
628  const SvxNumberFormat& aFmt(aNum.GetLevel(iLevel));
629  const OUString& sPrefix = aFmt.GetPrefix();
630  const OUString& sLclSuffix = aFmt.GetSuffix();
631  sal_Int16 eNumType = aFmt.GetNumberingType();
632  if( eNumType == SVX_NUM_CHAR_SPECIAL)
633  {
634  sal_UCS4 cChar = aFmt.GetBulletChar();
635 
636  sal_UCS4 ccChar
637  = _pSet->sBulletChar.iterateCodePoints(&o3tl::temporary(sal_Int32(0)));
638 
639  if ( !((cChar == ccChar) &&
640  _pSet->eLabelFollowedBy == aFmt.GetLabelFollowedBy() &&
641  _pSet->nTabValue == aFmt.GetListtabPos() &&
642  _pSet->eNumAlign == aFmt.GetNumAdjust() &&
643  _pSet->nNumAlignAt == aFmt.GetFirstLineIndent() &&
644  _pSet->nNumIndentAt == aFmt.GetIndentAt()))
645  {
646  bNotMatch = true;
647  break;
648  }
649  }
650  else if ((eNumType&(~LINK_TOKEN)) == SVX_NUM_BITMAP )
651  {
652  const SvxBrushItem* pBrsh1 = aFmt.GetBrush();
653  const SvxBrushItem* pBrsh2 = _pSet->pBrushItem;
654  bool bIsMatch = false;
655  if (pBrsh1==pBrsh2) bIsMatch = true;
656  if (pBrsh1 && pBrsh2) {
657  const Graphic* pGrf1 = pBrsh1->GetGraphic();
658  const Graphic* pGrf2 = pBrsh2->GetGraphic();
659  if (pGrf1==pGrf2) bIsMatch = true;
660  if (pGrf1 && pGrf2) {
661  if ( pGrf1->GetBitmapEx() == pGrf2->GetBitmapEx() &&
662  _pSet->aSize == aFmt.GetGraphicSize())
663  bIsMatch = true;
664  }
665  }
666  if (!bIsMatch) {
667  bNotMatch = true;
668  break;
669  }
670  }
671  else
672  {
673  if (!(sPrefix == _pSet->sPrefix &&
674  sLclSuffix == _pSet->sSuffix &&
675  eNumType == eNType &&
676  _pSet->eLabelFollowedBy == aFmt.GetLabelFollowedBy() &&
677  _pSet->nTabValue == aFmt.GetListtabPos() &&
678  _pSet->eNumAlign == aFmt.GetNumAdjust() &&
679  _pSet->nNumAlignAt == aFmt.GetFirstLineIndent() &&
680  _pSet->nNumIndentAt == aFmt.GetIndentAt()))
681  {
682  bNotMatch = true;
683  break;
684  }
685  }
686  }
687  if ( !bNotMatch )
688  return iDex+1;
689  }
690 
691 
692  return sal_uInt16(0xFFFF);
693 }
694 
695 void OutlineTypeMgr::RelplaceNumRule(SvxNumRule& aNum, sal_uInt16 nIndex, sal_uInt16 mLevel)
696 {
697  sal_uInt16 const nLength = SAL_N_ELEMENTS(pOutlineSettingsArrs);
698  if ( nIndex >= nLength )
699  return;
700 
701  OutlineSettings_Impl* pItemArr = pOutlineSettingsArrs[nIndex];
702  sal_uInt16 nCount = pItemArr->pNumSettingsArr->size();
703  for (sal_uInt16 iLevel=0;iLevel < nCount;iLevel++)
704  {
705  const SvxNumberFormat& aFmt(aNum.GetLevel(iLevel));
706  SvxNumType eNumType = aFmt.GetNumberingType();
707 
708  NumSettings_Impl* _pSet = (*pItemArr->pNumSettingsArr)[iLevel].get();
709 
710  _pSet->eLabelFollowedBy = aFmt.GetLabelFollowedBy();
711  _pSet->nTabValue = aFmt.GetListtabPos();
712  _pSet->eNumAlign = aFmt.GetNumAdjust();
713  _pSet->nNumAlignAt = aFmt.GetFirstLineIndent();
714  _pSet->nNumIndentAt = aFmt.GetIndentAt();
715 
716  if( eNumType == SVX_NUM_CHAR_SPECIAL)
717  {
718  sal_UCS4 cChar = aFmt.GetBulletChar();
719  OUString sChar(&cChar, 1);
720  _pSet->sBulletChar = sChar;
721  if ( aFmt.GetBulletFont() )
722  _pSet->sBulletFont = aFmt.GetBulletFont()->GetFamilyName();
723  _pSet->nNumberType = eNumType;
724  pItemArr->bIsCustomized = true;
725  }else if ((eNumType&(~LINK_TOKEN)) == SVX_NUM_BITMAP ) {
726  if (_pSet->pBrushItem) {
727  delete _pSet->pBrushItem;
728  _pSet->pBrushItem=nullptr;
729  }
730  if (aFmt.GetBrush())
731  _pSet->pBrushItem = new SvxBrushItem(*aFmt.GetBrush());
732  _pSet->aSize = aFmt.GetGraphicSize();
733  _pSet->nNumberType = eNumType;
734  } else
735  {
736  _pSet->sPrefix = aFmt.GetPrefix();
737  _pSet->sSuffix = aFmt.GetSuffix();
738  _pSet->nNumberType = eNumType;
739  if ( aFmt.GetBulletFont() )
740  _pSet->sBulletFont = aFmt.GetBulletFont()->GetFamilyName();
741  pItemArr->bIsCustomized = true;
742  }
743  }
744  SvxNumRule aTmpRule1(aNum);
745  SvxNumRule aTmpRule2(aNum);
746  ApplyNumRule(aTmpRule1,nIndex,mLevel,true);
747  ApplyNumRule(aTmpRule2,nIndex,mLevel);
748  if (aTmpRule1==aTmpRule2) pItemArr->bIsCustomized=false;
749  if (!pItemArr->bIsCustomized) {
750  pItemArr->sDescription = GetDescription(nIndex,true);
751  }
752  ImplStore(u"standard.syc");
753 }
754 
755 void OutlineTypeMgr::ApplyNumRule(SvxNumRule& aNum, sal_uInt16 nIndex, sal_uInt16 /*mLevel*/, bool isDefault, bool isResetSize)
756 {
757  DBG_ASSERT(DEFAULT_NUM_VALUSET_COUNT > nIndex, "wrong index");
758  if(DEFAULT_NUM_VALUSET_COUNT <= nIndex)
759  return;
760 
761  const FontList* pList = nullptr;
762 
763  OutlineSettings_Impl* pItemArr = pOutlineSettingsArrs[nIndex];
764  if (isDefault) pItemArr=pDefaultOutlineSettingsArrs[nIndex];
765 
766  NumSettingsArr_Impl *pNumSettingsArr=pItemArr->pNumSettingsArr;
767 
768  NumSettings_Impl* pLevelSettings = nullptr;
769  for(sal_uInt16 i = 0; i < aNum.GetLevelCount(); i++)
770  {
771  if(pNumSettingsArr->size() > i)
772  pLevelSettings = (*pNumSettingsArr)[i].get();
773 
774  if(!pLevelSettings)
775  break;
776 
777  SvxNumberFormat aFmt(aNum.GetLevel(i));
778  const vcl::Font& rActBulletFont = lcl_GetDefaultBulletFont();
779  if (pLevelSettings->nNumberType !=aFmt.GetNumberingType()) isResetSize=true;
780  aFmt.SetNumberingType( pLevelSettings->nNumberType );
781  sal_uInt16 nUpperLevelOrChar = static_cast<sal_uInt16>(pLevelSettings->nParentNumbering);
782  if(aFmt.GetNumberingType() == SVX_NUM_CHAR_SPECIAL)
783  {
784  if( pLevelSettings->sBulletFont.getLength() &&
785  pLevelSettings->sBulletFont != rActBulletFont.GetFamilyName() )
786  {
787  //search for the font
788  if(!pList)
789  {
790  SfxObjectShell* pCurDocShell = SfxObjectShell::Current();
791  const SvxFontListItem* pFontListItem = static_cast<const SvxFontListItem*>( pCurDocShell->GetItem( SID_ATTR_CHAR_FONTLIST ) );
792  pList = pFontListItem ? pFontListItem->GetFontList() : nullptr;
793  }
794  if(pList && pList->IsAvailable( pLevelSettings->sBulletFont ) )
795  {
796  FontMetric aFontMetric = pList->Get(pLevelSettings->sBulletFont,WEIGHT_NORMAL, ITALIC_NONE);
797  vcl::Font aFont(aFontMetric);
798  aFmt.SetBulletFont(&aFont);
799  }
800  else
801  {
802  //if it cannot be found then create a new one
803  vcl::Font aCreateFont( pLevelSettings->sBulletFont, OUString(), Size( 0, 14 ) );
804  aCreateFont.SetCharSet( RTL_TEXTENCODING_DONTKNOW );
805  aCreateFont.SetFamily( FAMILY_DONTKNOW );
806  aCreateFont.SetPitch( PITCH_DONTKNOW );
807  aCreateFont.SetWeight( WEIGHT_DONTKNOW );
808  aCreateFont.SetTransparent( true );
809  aFmt.SetBulletFont( &aCreateFont );
810  }
811  }else
812  aFmt.SetBulletFont( &rActBulletFont );
813 
814  sal_UCS4 cChar = 0;
815  if( !pLevelSettings->sBulletChar.isEmpty() )
816  {
817  cChar
818  = pLevelSettings->sBulletChar.iterateCodePoints(&o3tl::temporary(sal_Int32(0)));
819  }
821  {
822  if( 0 == i && cChar == BulletsTypeMgr::aDynamicBulletTypes[5] )
823  cChar = BulletsTypeMgr::aDynamicRTLBulletTypes[5];
824  else if( 1 == i )
825  {
826  const SvxNumberFormat& numberFmt = aNum.GetLevel(0);
827  if( numberFmt.GetBulletChar() == BulletsTypeMgr::aDynamicRTLBulletTypes[5] )
828  cChar = BulletsTypeMgr::aDynamicRTLBulletTypes[4];
829  }
830  }
831 
832  aFmt.SetBulletChar(cChar);
833  aFmt.SetCharFormatName( GetBulletCharFmtName() );
834  if (isResetSize) aFmt.SetBulletRelSize(45);
835  }else if ((aFmt.GetNumberingType()&(~LINK_TOKEN)) == SVX_NUM_BITMAP ) {
836  if (pLevelSettings->pBrushItem) {
837  const Graphic* pGrf = pLevelSettings->pBrushItem->GetGraphic();
838  Size aSize = pLevelSettings->aSize;
839  sal_Int16 eOrient = text::VertOrientation::LINE_CENTER;
840  if (!isResetSize && aFmt.GetGraphicSize()!=Size(0,0))
841  aSize = aFmt.GetGraphicSize();
842  else if (aSize.IsEmpty() && pGrf)
843  aSize = SvxNumberFormat::GetGraphicSizeMM100( pGrf );
844  aSize = OutputDevice::LogicToLogic(aSize, MapMode(MapUnit::Map100thMM), MapMode(GetMapUnit()));
845  aFmt.SetGraphicBrush( pLevelSettings->pBrushItem, &aSize, &eOrient );
846  }
847  } else
848  {
849  aFmt.SetIncludeUpperLevels(sal::static_int_cast< sal_uInt8 >(0 != nUpperLevelOrChar ? aNum.GetLevelCount() : 0));
850  aFmt.SetCharFormatName(GetNumCharFmtName());
851  if (isResetSize) aFmt.SetBulletRelSize(100);
852  }
853  if(pNumSettingsArr->size() > i) {
854  aFmt.SetLabelFollowedBy(pLevelSettings->eLabelFollowedBy);
855  aFmt.SetListtabPos(pLevelSettings->nTabValue);
856  aFmt.SetNumAdjust(pLevelSettings->eNumAlign);
857  aFmt.SetFirstLineIndent(pLevelSettings->nNumAlignAt);
858  aFmt.SetIndentAt(pLevelSettings->nNumIndentAt);
859  }
860  aFmt.SetListFormat(pLevelSettings->sPrefix, pLevelSettings->sSuffix, i);
861  aNum.SetLevel(i, aFmt);
862  }
863 }
864 
865 OUString OutlineTypeMgr::GetDescription(sal_uInt16 nIndex, bool isDefault)
866 {
867  OUString sRet;
868 
869  if ( nIndex >= SAL_N_ELEMENTS(pOutlineSettingsArrs) )
870  return sRet;
871  else
872  {
873  OutlineSettings_Impl* pItemArr = pOutlineSettingsArrs[nIndex];
874  if (isDefault) pItemArr = pDefaultOutlineSettingsArrs[nIndex];
875  if ( pItemArr )
876  {
877  sRet = pItemArr->sDescription;
878  }
879  }
880  return sRet;
881 }
882 
883 bool OutlineTypeMgr::IsCustomized(sal_uInt16 nIndex)
884 {
885  bool bRet = false;
886 
887  if ( nIndex >= SAL_N_ELEMENTS(pOutlineSettingsArrs) )
888  return bRet;
889  else
890  {
891  OutlineSettings_Impl* pItemArr = pOutlineSettingsArrs[nIndex];
892  if ( pItemArr )
893  {
894  bRet = pItemArr->bIsCustomized;
895  }
896  }
897 
898  return bRet;
899 }
900 
901 
902 }
903 
904 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void SetFamily(FontFamily)
virtual void ApplyNumRule(SvxNumRule &aNum, sal_uInt16 nIndex, sal_uInt16 mLevel, bool isDefault=false, bool isResetSize=false) override
Definition: nbdtmg.cxx:320
SvxNumType GetNumberingType() const
#define DEFAULT_BULLET_TYPES
Definition: nbdtmg.hxx:29
static const char * RID_SVXSTR_SINGLENUM_DESCRIPTIONS[]
Definition: nbdtmg.cxx:383
virtual OUString GetDescription(sal_uInt16 nIndex, bool isDefault) override
Definition: nbdtmg.cxx:865
void SetAlpha(sal_uInt8 nAlpha)
sal_UCS4 GetBulletChar() const
virtual sal_uInt16 GetNBOIndexForNumRule(SvxNumRule &aNum, sal_uInt16 mLevel, sal_uInt16 nFromIndex=0) override
Definition: nbdtmg.cxx:615
sal_uInt32 sal_UCS4
SAL_WARN_UNUSED_RESULT Point LogicToLogic(const Point &rPtSource, const MapMode *pMapModeSource, const MapMode *pMapModeDest) const
MapUnit GetMapUnit() const
Definition: nbdtmg.hxx:141
#define DEFAULT_NUM_VALUSET_COUNT
Definition: nbdtmg.hxx:30
FAMILY_DONTKNOW
NumberSettingsArr_Impl maNumberSettingsArr
Definition: nbdtmg.hxx:176
static const AllSettings & GetSettings()
const sal_Unicode cBulletChar
std::vector< std::shared_ptr< NumberSettings_Impl > > NumberSettingsArr_Impl
Definition: nbdtmg.hxx:95
void SetWeight(FontWeight)
static sal_uInt16 IsSingleLevel(sal_uInt16 nCurLevel)
Definition: nbdtmg.cxx:122
NumSettings_Impl * pNumSetting
Definition: nbdtmg.hxx:87
void SetCharSet(rtl_TextEncoding)
static SfxObjectShell * Current()
#define DEFAULT_NUMBERING_CACHE_FORMAT_VERSION
Definition: nbdtmg.hxx:31
virtual void Init() override
Definition: nbdtmg.cxx:257
virtual bool IsCustomized(sal_uInt16 nIndex) override
Definition: nbdtmg.cxx:358
static Size GetGraphicSizeMM100(const Graphic *pGraphic)
bool IsAvailable(const OUString &rName) const
virtual OUString GetDescription(sal_uInt16 nIndex, bool isDefault) override
Definition: nbdtmg.cxx:525
SvxNumType
void Store(SvStream &rStream)
sal_uInt16 sal_Unicode
static OutlineTypeMgr & GetInstance()
Definition: nbdtmg.cxx:565
virtual void Init() override
Definition: nbdtmg.cxx:571
std::vector< std::shared_ptr< NumSettings_Impl > > NumSettingsArr_Impl
Definition: nbdtmg.hxx:69
static std::unique_ptr< SvStream > CreateStream(const OUString &rFileName, StreamMode eOpenMode, css::uno::Reference< css::awt::XWindow > xParentWin=nullptr)
static vcl::Font & lcl_GetDefaultBulletFont()
SvxNumberFormat::LabelFollowedBy eLabelFollowedBy
Definition: nbdtmg.hxx:43
int nCount
FontMetric Get(const OUString &rName, const OUString &rStyleName) const
NumSettingsArr_Impl * pNumSettingsArr
Definition: nbdtmg.hxx:102
const Graphic * GetGraphic(OUString const &referer=OUString()) const
virtual void RelplaceNumRule(SvxNumRule &aNum, sal_uInt16 nIndex, sal_uInt16 mLevel) override
Definition: nbdtmg.cxx:295
virtual sal_uInt16 GetNBOIndexForNumRule(SvxNumRule &aNum, sal_uInt16 mLevel, sal_uInt16 nFromIndex=0) override
Definition: nbdtmg.cxx:430
void SetPitch(FontPitch ePitch)
const OUString & GetNumCharFmtName() const
Definition: nbdtmg.hxx:140
#define SAL_N_ELEMENTS(arr)
SVX_NUM_BITMAP
SVX_NUM_CHAR_SPECIAL
WEIGHT_DONTKNOW
const SfxPoolItem * GetItem(sal_uInt16 nSlotId) const
OUString sPrefix
OUString SvxResId(std::string_view aId)
Definition: dialmgr.cxx:25
bool IsEmpty() const
#define DBG_ASSERT(sCon, aError)
int i
virtual ~NumberingTypeMgr() override
Definition: nbdtmg.cxx:379
const OUString & GetValue() const
WEIGHT_NORMAL
const SvxNumberFormat & GetLevel(sal_uInt16 nLevel) const
sal_uInt16 GetLevelCount() const
float u
static bool GetLayoutRTL()
PITCH_DONTKNOW
virtual sal_uInt16 GetNBOIndexForNumRule(SvxNumRule &aNum, sal_uInt16 mLevel, sal_uInt16 nFromIndex=0) override
Definition: nbdtmg.cxx:269
SvxBrushItem * pBrushItem
Definition: nbdtmg.hxx:52
virtual void ApplyNumRule(SvxNumRule &aNum, sal_uInt16 nIndex, sal_uInt16 mLevel, bool isDefault=false, bool isResetSize=false) override
Definition: nbdtmg.cxx:755
void ImplStore(std::u16string_view filename)
Definition: nbdtmg.cxx:211
BitmapEx GetBitmapEx(const GraphicConversionParameters &rParameters=GraphicConversionParameters()) const
ITALIC_NONE
virtual bool IsCustomized(sal_uInt16 nIndex) override
Definition: nbdtmg.cxx:883
sal_Int16 nVersion
static BulletsSettings * pActualBullets[DEFAULT_BULLET_TYPES]
Definition: nbdtmg.hxx:158
constexpr T & temporary(T &&x)
void SetBulletChar(sal_UCS4 cSet)
const LanguageTag & getLocale()
OUString GetMainURL(DecodeMechanism eMechanism, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
NumberSettingsArr_Impl maDefaultNumberSettingsArr
Definition: nbdtmg.hxx:177
SfxItemState
OutlineSettings_Impl * pOutlineSettingsArrs[DEFAULT_NUM_VALUSET_COUNT]
Definition: nbdtmg.hxx:195
#define LINK_TOKEN
virtual void RelplaceNumRule(SvxNumRule &aNum, sal_uInt16 nIndex, sal_uInt16 mLevel) override
Definition: nbdtmg.cxx:695
void SetTransparent(bool bTransparent)
const OUString & GetBulletCharFmtName() const
Definition: nbdtmg.hxx:139
#define SVX_MAX_NUM
bool Append(std::u16string_view rTheSegment, EncodeMechanism eMechanism=EncodeMechanism::WasEncoded, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8)
static BulletsTypeMgr & GetInstance()
Definition: nbdtmg.cxx:251
virtual void ApplyNumRule(SvxNumRule &aNum, sal_uInt16 nIndex, sal_uInt16 mLevel, bool isDefault=false, bool isResetSize=false) override
Definition: nbdtmg.cxx:498
MapUnit
sal_Int32 nLength
OutlineSettings_Impl * pDefaultOutlineSettingsArrs[DEFAULT_NUM_VALUSET_COUNT]
Definition: nbdtmg.hxx:196
constexpr TypedWhichId< SvxNumBulletItem > EE_PARA_NUMBULLET(EE_PARA_START+5)
virtual OUString GetDescription(sal_uInt16 nIndex, bool isDefault) override
Definition: nbdtmg.cxx:346
const FontList * GetFontList() const
virtual bool IsCustomized(sal_uInt16 nIndex) override
Definition: nbdtmg.cxx:539
void SetNumberingType(SvxNumType nSet)
const SfxPoolItem * GetItem(sal_uInt16 nWhich, bool bSearchInParent=true) const
virtual void RelplaceNumRule(SvxNumRule &aNum, sal_uInt16 nIndex, sal_uInt16 mLevel) override
Definition: nbdtmg.cxx:466
void SetLevel(sal_uInt16 nLevel, const SvxNumberFormat &rFmt, bool bIsValid=true)
static NumberingTypeMgr & GetInstance()
Definition: nbdtmg.cxx:395
void ImplLoad(std::u16string_view filename)
Definition: nbdtmg.cxx:173
virtual void Init() override
Definition: nbdtmg.cxx:401