Bug Summary

File:home/maarten/src/libreoffice/core/include/tools/ref.hxx
Warning:line 56, column 30
Use of memory after it is freed

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name NumberingManager.cxx -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/11.0.0 -isystem /usr/include/libxml2 -D BOOST_ERROR_CODE_HEADER_ONLY -D BOOST_SYSTEM_NO_DEPRECATED -D CPPU_ENV=gcc3 -D LINUX -D OSL_DEBUG_LEVEL=1 -D SAL_LOG_INFO -D SAL_LOG_WARN -D UNIX -D UNX -D X86_64 -D _PTHREADS -D _REENTRANT -D SYSTEM_LIBXML -D EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/i18n -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/common -I /home/maarten/src/libreoffice/core/external/boost/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost -I /home/maarten/src/libreoffice/core/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include/linux -I /home/maarten/src/libreoffice/core/config_host -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/officecfg/registry -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/oox/generated -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/writerfilter/source -I /home/maarten/src/libreoffice/core/writerfilter/inc -I /home/maarten/src/libreoffice/core/writerfilter/source -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/udkapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/offapi/normal -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/x86_64-redhat-linux -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/11.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wno-missing-braces -std=c++17 -fdeprecated-macro -fdebug-compilation-dir /home/maarten/src/libreoffice/core -ferror-limit 19 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -debug-info-kind=constructor -analyzer-output=html -faddrsig -o /home/maarten/tmp/wis/scan-build-libreoffice/output/report/2020-10-07-141433-9725-1 -x c++ /home/maarten/src/libreoffice/core/writerfilter/source/dmapper/NumberingManager.cxx

/home/maarten/src/libreoffice/core/writerfilter/source/dmapper/NumberingManager.cxx

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 <sal/config.h>
21
22#include "ConversionHelper.hxx"
23#include "NumberingManager.hxx"
24#include "StyleSheetTable.hxx"
25#include "PropertyIds.hxx"
26
27#include <ooxml/resourceids.hxx>
28
29#include <com/sun/star/lang/XMultiServiceFactory.hpp>
30#include <com/sun/star/container/XNameContainer.hpp>
31#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
32#include <com/sun/star/style/NumberingType.hpp>
33#include <com/sun/star/text/HoriOrientation.hpp>
34#include <com/sun/star/text/PositionAndSpaceMode.hpp>
35#include <com/sun/star/text/XChapterNumberingSupplier.hpp>
36#include <com/sun/star/graphic/XGraphic.hpp>
37#include <com/sun/star/awt/XBitmap.hpp>
38
39#include <osl/diagnose.h>
40#include <rtl/ustring.hxx>
41#include <sal/log.hxx>
42#include <tools/diagnose_ex.h>
43#include <tools/UnitConversion.hxx>
44#include <comphelper/sequence.hxx>
45#include <comphelper/propertyvalue.hxx>
46#include <comphelper/string.hxx>
47
48using namespace com::sun::star;
49
50namespace writerfilter::dmapper {
51
52//--------------------------------------------------- Utility functions
53template <typename T>
54static beans::PropertyValue lcl_makePropVal(PropertyIds nNameID, T const & aValue)
55{
56 return {getPropertyName(nNameID), 0, uno::makeAny(aValue), beans::PropertyState_DIRECT_VALUE};
57}
58
59static sal_Int32 lcl_findProperty( const uno::Sequence< beans::PropertyValue >& aProps, const OUString& sName )
60{
61 sal_Int32 i = 0;
62 sal_Int32 nLen = aProps.getLength( );
63 sal_Int32 nPos = -1;
64
65 while ( nPos == -1 && i < nLen )
66 {
67 if ( aProps[i].Name == sName )
68 nPos = i;
69 else
70 i++;
71 }
72
73 return nPos;
74}
75
76static void lcl_mergeProperties( const uno::Sequence< beans::PropertyValue >& aSrc,
77 uno::Sequence< beans::PropertyValue >& aDst )
78{
79 for ( const auto& rProp : aSrc )
80 {
81 // Look for the same property in aDst
82 sal_Int32 nPos = lcl_findProperty( aDst, rProp.Name );
83 if ( nPos >= 0 )
84 {
85 // Replace the property value by the one in aSrc
86 aDst[nPos] = rProp;
87 }
88 else
89 {
90 // Simply add the new value
91 aDst.realloc( aDst.getLength( ) + 1 );
92 aDst[ aDst.getLength( ) - 1 ] = rProp;
93 }
94 }
95}
96
97//-------------------------------------------- ListLevel implementation
98void ListLevel::SetValue( Id nId, sal_Int32 nValue )
99{
100 switch( nId )
101 {
102 case NS_ooxml::LN_CT_Lvl_start:
103 m_nIStartAt = nValue;
104 break;
105 case NS_ooxml::LN_CT_NumLvl_startOverride:
106 m_nStartOverride = nValue;
107 break;
108 case NS_ooxml::LN_CT_NumFmt_val:
109 m_nNFC = nValue;
110 break;
111 case NS_ooxml::LN_CT_Lvl_isLgl:
112 break;
113 case NS_ooxml::LN_CT_Lvl_legacy:
114 break;
115 case NS_ooxml::LN_CT_Lvl_suff:
116 m_nXChFollow = nValue;
117 break;
118 case NS_ooxml::LN_CT_TabStop_pos:
119 if (nValue < 0)
120 {
121 SAL_INFO("writerfilter",do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "writerfilter")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break
; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "unsupported list tab stop position "
<< nValue) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("writerfilter"), ("/home/maarten/src/libreoffice/core/writerfilter/source/dmapper/NumberingManager.cxx"
":" "122" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "unsupported list tab stop position " <<
nValue), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "unsupported list tab stop position "
<< nValue; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("writerfilter"), ("/home/maarten/src/libreoffice/core/writerfilter/source/dmapper/NumberingManager.cxx"
":" "122" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "unsupported list tab stop position " << nValue
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("writerfilter"
), ("/home/maarten/src/libreoffice/core/writerfilter/source/dmapper/NumberingManager.cxx"
":" "122" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "unsupported list tab stop position " <<
nValue), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "unsupported list tab stop position "
<< nValue; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("writerfilter"), ("/home/maarten/src/libreoffice/core/writerfilter/source/dmapper/NumberingManager.cxx"
":" "122" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
122 "unsupported list tab stop position " << nValue)do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "writerfilter")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break
; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "unsupported list tab stop position "
<< nValue) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("writerfilter"), ("/home/maarten/src/libreoffice/core/writerfilter/source/dmapper/NumberingManager.cxx"
":" "122" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "unsupported list tab stop position " <<
nValue), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "unsupported list tab stop position "
<< nValue; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("writerfilter"), ("/home/maarten/src/libreoffice/core/writerfilter/source/dmapper/NumberingManager.cxx"
":" "122" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "unsupported list tab stop position " << nValue
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("writerfilter"
), ("/home/maarten/src/libreoffice/core/writerfilter/source/dmapper/NumberingManager.cxx"
":" "122" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "unsupported list tab stop position " <<
nValue), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "unsupported list tab stop position "
<< nValue; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("writerfilter"), ("/home/maarten/src/libreoffice/core/writerfilter/source/dmapper/NumberingManager.cxx"
":" "122" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
123 }
124 else
125 m_nTabstop = nValue;
126 break;
127 default:
128 OSL_FAIL( "this line should never be reached")do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/writerfilter/source/dmapper/NumberingManager.cxx"
":" "128" ": "), "%s", "this line should never be reached");
} } while (false)
;
129 }
130 m_bHasValues = true;
131}
132
133void ListLevel::SetCustomNumberFormat(const OUString& rValue) { m_aCustomNumberFormat = rValue; }
134
135bool ListLevel::HasValues() const
136{
137 return m_bHasValues;
138}
139
140void ListLevel::SetParaStyle( const tools::SvRef< StyleSheetEntry >& pStyle )
141{
142 if (!pStyle)
143 return;
144 m_pParaStyle = pStyle;
145 // AFAICT .docx spec does not identify which numberings or paragraph
146 // styles are actually the ones to be used for outlines (chapter numbering),
147 // it only kind of says somewhere that they should be named Heading1 to Heading9.
148 const OUString styleId= pStyle->sConvertedStyleName;
149 m_outline = ( styleId.getLength() == RTL_CONSTASCII_LENGTH( "Heading 1" )((sal_Int32)((sizeof(sal_n_array_size("Heading 1")))-1))
150 && styleId.match( "Heading ", 0 )
151 && styleId[ RTL_CONSTASCII_LENGTH( "Heading " )((sal_Int32)((sizeof(sal_n_array_size("Heading ")))-1)) ] >= '1'
152 && styleId[ RTL_CONSTASCII_LENGTH( "Heading " )((sal_Int32)((sizeof(sal_n_array_size("Heading ")))-1)) ] <= '9' );
153}
154
155uno::Sequence<beans::PropertyValue> ListLevel::GetProperties(bool bDefaults)
156{
157 uno::Sequence<beans::PropertyValue> aLevelProps = GetLevelProperties(bDefaults);
158 if (m_pParaStyle)
159 AddParaProperties( &aLevelProps );
160 return aLevelProps;
161}
162
163static bool IgnoreForCharStyle(const OUString& aStr, const bool bIsSymbol)
164{
165 //Names found in PropertyIds.cxx, Lines 56-396
166 return (aStr=="Adjust" || aStr=="IndentAt" || aStr=="FirstLineIndent"
167 || aStr=="FirstLineOffset" || aStr=="LeftMargin"
168 || aStr=="CharInteropGrabBag" || aStr=="ParaInteropGrabBag" ||
169 // We need font names when they are different for the bullet and for the text.
170 // But leave symbols alone, we only want to keep the font style for letters and numbers.
171 (bIsSymbol && aStr=="CharFontName")
172 );
173}
174uno::Sequence< beans::PropertyValue > ListLevel::GetCharStyleProperties( )
175{
176 PropertyValueVector_t rProperties;
177
178 uno::Sequence< beans::PropertyValue > vPropVals = PropertyMap::GetPropertyValues();
179 beans::PropertyValue* aValIter = vPropVals.begin();
180 beans::PropertyValue* aEndIter = vPropVals.end();
181 const bool bIsSymbol(m_sBulletChar.getLength() <= 1);
182 for( ; aValIter != aEndIter; ++aValIter )
183 if (! IgnoreForCharStyle(aValIter->Name, bIsSymbol))
184 rProperties.emplace_back(aValIter->Name, 0, aValIter->Value, beans::PropertyState_DIRECT_VALUE);
185
186 return comphelper::containerToSequence(rProperties);
187}
188
189uno::Sequence<beans::PropertyValue> ListLevel::GetLevelProperties(bool bDefaults)
190{
191 std::vector<beans::PropertyValue> aNumberingProperties;
192
193 if (m_nIStartAt >= 0)
194 aNumberingProperties.push_back(lcl_makePropVal<sal_Int16>(PROP_START_WITH, m_nIStartAt) );
195 else if (bDefaults)
196 aNumberingProperties.push_back(lcl_makePropVal<sal_Int16>(PROP_START_WITH, 0));
197
198 sal_Int16 nNumberFormat = -1;
199 if (m_nNFC == NS_ooxml::LN_Value_ST_NumberFormat_custom)
200 {
201 nNumberFormat = ConversionHelper::ConvertCustomNumberFormat(m_aCustomNumberFormat);
202 }
203 else
204 {
205 nNumberFormat = ConversionHelper::ConvertNumberingType(m_nNFC);
206 }
207 if( m_nNFC >= 0)
208 {
209 if (m_xGraphicBitmap.is())
210 nNumberFormat = style::NumberingType::BITMAP;
211 aNumberingProperties.push_back(lcl_makePropVal(PROP_NUMBERING_TYPE, nNumberFormat));
212 }
213
214 // todo: this is not the bullet char
215 if( nNumberFormat == style::NumberingType::CHAR_SPECIAL )
216 {
217 if (!m_sBulletChar.isEmpty())
218 {
219 aNumberingProperties.push_back(lcl_makePropVal(PROP_BULLET_CHAR, m_sBulletChar.copy(0, 1)));
220 }
221 else
222 {
223 // If w:lvlText's value is null - set bullet char to zero.
224 aNumberingProperties.push_back(lcl_makePropVal<sal_Unicode>(PROP_BULLET_CHAR, 0));
225 }
226 }
227 if (m_xGraphicBitmap.is())
228 {
229 aNumberingProperties.push_back(lcl_makePropVal(PROP_GRAPHIC_BITMAP, m_xGraphicBitmap));
230 aNumberingProperties.push_back(lcl_makePropVal(PROP_GRAPHIC_SIZE, m_aGraphicSize));
231 }
232
233 if (m_nTabstop.has_value())
234 aNumberingProperties.push_back(lcl_makePropVal(PROP_LISTTAB_STOP_POSITION, *m_nTabstop));
235 else if (bDefaults)
236 aNumberingProperties.push_back(lcl_makePropVal<sal_Int16>(PROP_LISTTAB_STOP_POSITION, 0));
237
238 //TODO: handling of nFLegal?
239 //TODO: nFNoRestart lower levels do not restart when higher levels are incremented, like:
240 //1.
241 //1.1
242 //2.2
243 //2.3
244 //3.4
245
246// TODO: sRGBXchNums; array of inherited numbers
247
248// nXChFollow; following character 0 - tab, 1 - space, 2 - nothing
249 if (bDefaults || m_nXChFollow != SvxNumberFormat::LISTTAB)
250 aNumberingProperties.push_back(lcl_makePropVal(PROP_LEVEL_FOLLOW, m_nXChFollow));
251
252 PropertyIds const aReadIds[] =
253 {
254 PROP_ADJUST, PROP_INDENT_AT, PROP_FIRST_LINE_INDENT,
255 PROP_FIRST_LINE_OFFSET, PROP_LEFT_MARGIN
256 };
257 for(PropertyIds const & rReadId : aReadIds) {
258 std::optional<PropertyMap::Property> aProp = getProperty(rReadId);
259 if (aProp)
260 aNumberingProperties.emplace_back( getPropertyName(aProp->first), 0, aProp->second, beans::PropertyState_DIRECT_VALUE );
261 else if (rReadId == PROP_FIRST_LINE_INDENT && bDefaults)
262 // Writer default is -360 twips, Word default seems to be 0.
263 aNumberingProperties.emplace_back("FirstLineIndent", 0, uno::makeAny(static_cast<sal_Int32>(0)), beans::PropertyState_DIRECT_VALUE);
264 else if (rReadId == PROP_INDENT_AT && bDefaults)
265 // Writer default is 720 twips, Word default seems to be 0.
266 aNumberingProperties.emplace_back("IndentAt", 0,
267 uno::makeAny(static_cast<sal_Int32>(0)),
268 beans::PropertyState_DIRECT_VALUE);
269 }
270
271 std::optional<PropertyMap::Property> aPropFont = getProperty(PROP_CHAR_FONT_NAME);
272 if(aPropFont && !isOutlineNumbering())
273 aNumberingProperties.emplace_back( getPropertyName(PROP_BULLET_FONT_NAME), 0, aPropFont->second, beans::PropertyState_DIRECT_VALUE );
274
275 return comphelper::containerToSequence(aNumberingProperties);
276}
277
278// Add the properties only if they do not already exist in the sequence.
279void ListLevel::AddParaProperties( uno::Sequence< beans::PropertyValue >* props )
280{
281 uno::Sequence< beans::PropertyValue >& aProps = *props;
282
283 OUString sFirstLineIndent = getPropertyName(
284 PROP_FIRST_LINE_INDENT );
285 OUString sIndentAt = getPropertyName(
286 PROP_INDENT_AT );
287
288 bool hasFirstLineIndent = lcl_findProperty( aProps, sFirstLineIndent );
289 bool hasIndentAt = lcl_findProperty( aProps, sIndentAt );
290
291 if( hasFirstLineIndent && hasIndentAt )
292 return; // has them all, nothing to add
293
294 const uno::Sequence< beans::PropertyValue > aParaProps = m_pParaStyle->pProperties->GetPropertyValues( );
295
296 // ParaFirstLineIndent -> FirstLineIndent
297 // ParaLeftMargin -> IndentAt
298
299 OUString sParaIndent = getPropertyName(
300 PROP_PARA_FIRST_LINE_INDENT );
301 OUString sParaLeftMargin = getPropertyName(
302 PROP_PARA_LEFT_MARGIN );
303
304 for ( const auto& rParaProp : aParaProps )
305 {
306 if ( !hasFirstLineIndent && rParaProp.Name == sParaIndent )
307 {
308 aProps.realloc( aProps.getLength() + 1 );
309 aProps[aProps.getLength( ) - 1] = rParaProp;
310 aProps[aProps.getLength( ) - 1].Name = sFirstLineIndent;
311 }
312 else if ( !hasIndentAt && rParaProp.Name == sParaLeftMargin )
313 {
314 aProps.realloc( aProps.getLength() + 1 );
315 aProps[aProps.getLength( ) - 1] = rParaProp;
316 aProps[aProps.getLength( ) - 1].Name = sIndentAt;
317 }
318
319 }
320}
321
322NumPicBullet::NumPicBullet()
323 : m_nId(0)
324{
325}
326
327NumPicBullet::~NumPicBullet()
328{
329}
330
331void NumPicBullet::SetId(sal_Int32 nId)
332{
333 m_nId = nId;
334}
335
336void NumPicBullet::SetShape(uno::Reference<drawing::XShape> const& xShape)
337{
338 m_xShape = xShape;
339}
340
341
342//--------------------------------------- AbstractListDef implementation
343
344AbstractListDef::AbstractListDef( ) :
345 m_nId( -1 )
346{
347}
348
349AbstractListDef::~AbstractListDef( )
350{
351}
352
353void AbstractListDef::SetValue( sal_uInt32 nSprmId )
354{
355 switch( nSprmId )
356 {
357 case NS_ooxml::LN_CT_AbstractNum_tmpl:
358 break;
359 default:
360 OSL_FAIL( "this line should never be reached")do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/writerfilter/source/dmapper/NumberingManager.cxx"
":" "360" ": "), "%s", "this line should never be reached");
} } while (false)
;
361 }
362}
363
364ListLevel::Pointer AbstractListDef::GetLevel( sal_uInt16 nLvl )
365{
366 ListLevel::Pointer pLevel;
367 if ( m_aLevels.size( ) > nLvl )
368 pLevel = m_aLevels[ nLvl ];
369 return pLevel;
370}
371
372void AbstractListDef::AddLevel( sal_uInt16 nLvl )
373{
374 if ( nLvl >= m_aLevels.size() )
375 m_aLevels.resize( nLvl+1 );
376
377 ListLevel::Pointer pLevel( new ListLevel );
378 m_pCurrentLevel = pLevel;
379 m_aLevels[nLvl] = pLevel;
380}
381
382uno::Sequence<uno::Sequence<beans::PropertyValue>> AbstractListDef::GetPropertyValues(bool bDefaults)
383{
384 uno::Sequence< uno::Sequence< beans::PropertyValue > > result( sal_Int32( m_aLevels.size( ) ) );
385 uno::Sequence< beans::PropertyValue >* aResult = result.getArray( );
386
387 int nLevels = m_aLevels.size( );
388 for ( int i = 0; i < nLevels; i++ )
389 {
390 if (m_aLevels[i])
391 aResult[i] = m_aLevels[i]->GetProperties(bDefaults);
392 }
393
394 return result;
395}
396
397const OUString& AbstractListDef::MapListId(OUString const& rId)
398{
399 if (!m_oListId)
400 {
401 m_oListId = rId;
402 }
403 return *m_oListId;
404}
405
406//---------------------------------------------- ListDef implementation
407
408ListDef::ListDef( ) : AbstractListDef( )
409{
410 m_nDefaultParentLevels = WW_OUTLINE_MAXsal_Int16( 9 ) + 1;
411}
412
413ListDef::~ListDef( )
414{
415}
416
417OUString ListDef::GetStyleName(sal_Int32 const nId,
418 uno::Reference<container::XNameContainer> const& xStyles)
419{
420 if (xStyles.is())
421 {
422 OUString sStyleName = "WWNum" + OUString::number( nId );
423
424 while (xStyles->hasByName(sStyleName)) // unique
425 {
426 sStyleName += "a";
427 }
428
429 m_StyleName = sStyleName;
430 }
431 else
432 {
433// fails in rtftok test assert(!m_StyleName.isEmpty()); // must be inited first
434 }
435
436 return m_StyleName;
437}
438
439uno::Sequence<uno::Sequence<beans::PropertyValue>> ListDef::GetMergedPropertyValues()
440{
441 if (!m_pAbstractDef)
442 return uno::Sequence< uno::Sequence< beans::PropertyValue > >();
443
444 // [1] Call the same method on the abstract list
445 uno::Sequence<uno::Sequence<beans::PropertyValue>> aAbstract
446 = m_pAbstractDef->GetPropertyValues(/*bDefaults=*/true);
447
448 // [2] Call the upper class method
449 uno::Sequence<uno::Sequence<beans::PropertyValue>> aThis
450 = AbstractListDef::GetPropertyValues(/*bDefaults=*/false);
451
452 // Merge the results of [2] in [1]
453 sal_Int32 nThisCount = aThis.getLength( );
454 sal_Int32 nAbstractCount = aAbstract.getLength( );
455 for ( sal_Int32 i = 0; i < nThisCount && i < nAbstractCount; i++ )
456 {
457 uno::Sequence< beans::PropertyValue > level = aThis[i];
458 if (level.hasElements() && GetLevel(i)->HasValues())
459 {
460 // If the element contains something, merge it, but ignore stub overrides.
461 lcl_mergeProperties( level, aAbstract[i] );
462 }
463 }
464
465 return aAbstract;
466}
467
468static uno::Reference< container::XNameContainer > lcl_getUnoNumberingStyles(
469 uno::Reference<lang::XMultiServiceFactory> const& xFactory)
470{
471 uno::Reference< container::XNameContainer > xStyles;
472
473 try
474 {
475 uno::Reference< style::XStyleFamiliesSupplier > xFamilies( xFactory, uno::UNO_QUERY_THROW );
476 uno::Any oFamily = xFamilies->getStyleFamilies( )->getByName("NumberingStyles");
477
478 oFamily >>= xStyles;
479 }
480 catch ( const uno::Exception & )
481 {
482 }
483
484 return xStyles;
485}
486
487void ListDef::CreateNumberingRules( DomainMapper& rDMapper,
488 uno::Reference<lang::XMultiServiceFactory> const& xFactory)
489{
490 // Get the UNO Numbering styles
491 uno::Reference< container::XNameContainer > xStyles = lcl_getUnoNumberingStyles( xFactory );
492
493 // Do the whole thing
494 if( !(!m_xNumRules.is() && xFactory.is() && xStyles.is( )) )
495 return;
496
497 try
498 {
499 // Create the numbering style
500 uno::Reference< beans::XPropertySet > xStyle (
501 xFactory->createInstance("com.sun.star.style.NumberingStyle"),
502 uno::UNO_QUERY_THROW );
503
504 OUString sStyleName = GetStyleName(GetId(), xStyles);
505
506 xStyles->insertByName( sStyleName, makeAny( xStyle ) );
507
508 uno::Any oStyle = xStyles->getByName( sStyleName );
509 xStyle.set( oStyle, uno::UNO_QUERY_THROW );
510
511 // Get the default OOo Numbering style rules
512 uno::Any aRules = xStyle->getPropertyValue( getPropertyName( PROP_NUMBERING_RULES ) );
513 aRules >>= m_xNumRules;
514
515 uno::Sequence<uno::Sequence<beans::PropertyValue>> aProps = GetMergedPropertyValues();
516
517 sal_Int32 nAbstLevels = m_pAbstractDef ? m_pAbstractDef->Size() : 0;
518 sal_Int32 nLevel = 0;
519 while ( nLevel < nAbstLevels )
520 {
521 ListLevel::Pointer pAbsLevel = m_pAbstractDef->GetLevel( nLevel );
522 ListLevel::Pointer pLevel = GetLevel( nLevel );
523
524 // Get the merged level properties
525 auto aLvlProps = comphelper::sequenceToContainer< std::vector<beans::PropertyValue> >(aProps[nLevel]);
526
527 // Get the char style
528 auto aAbsCharStyleProps = pAbsLevel
529 ? pAbsLevel->GetCharStyleProperties()
530 : uno::Sequence<beans::PropertyValue>();
531 if ( pLevel )
532 {
533 uno::Sequence< beans::PropertyValue >& rAbsCharStyleProps = aAbsCharStyleProps;
534 uno::Sequence< beans::PropertyValue > aCharStyleProps =
535 pLevel->GetCharStyleProperties( );
536 uno::Sequence< beans::PropertyValue >& rCharStyleProps = aCharStyleProps;
537 lcl_mergeProperties( rAbsCharStyleProps, rCharStyleProps );
538 }
539
540 if( aAbsCharStyleProps.hasElements() )
541 {
542 // Change the sequence into a vector
543 auto aStyleProps = comphelper::sequenceToContainer<PropertyValueVector_t>(aAbsCharStyleProps);
544
545 //create (or find) a character style containing the character
546 // attributes of the symbol and apply it to the numbering level
547 OUString sStyle = rDMapper.getOrCreateCharStyle( aStyleProps, /*bAlwaysCreate=*/true );
548 aLvlProps.push_back(comphelper::makePropertyValue(getPropertyName(PROP_CHAR_STYLE_NAME), sStyle));
549 }
550
551 // Get the prefix / suffix / Parent numbering
552 // and add them to the level properties
553 OUString sText = pAbsLevel
554 ? pAbsLevel->GetBulletChar()
555 : OUString();
556 // Inherit <w:lvlText> from the abstract level in case the override would be empty.
557 if (pLevel && !pLevel->GetBulletChar().isEmpty())
558 sText = pLevel->GetBulletChar( );
559
560 aLvlProps.push_back(comphelper::makePropertyValue(getPropertyName(PROP_PREFIX), OUString("")));
561 aLvlProps.push_back(comphelper::makePropertyValue(getPropertyName(PROP_SUFFIX), OUString("")));
562 aLvlProps.push_back(comphelper::makePropertyValue(getPropertyName(PROP_LIST_FORMAT), sText));
563
564 // Total count of replacement holders is determining amount of required parent numbering to include
565 // TODO: not sure how "%" symbol is escaped. This is not supported yet
566 sal_Int16 nParentNum = comphelper::string::getTokenCount(sText, '%');
567 aLvlProps.push_back(comphelper::makePropertyValue(getPropertyName(PROP_PARENT_NUMBERING), nParentNum));
568
569 aLvlProps.push_back(comphelper::makePropertyValue(getPropertyName(PROP_POSITION_AND_SPACE_MODE), sal_Int16(text::PositionAndSpaceMode::LABEL_ALIGNMENT)));
570
571 // Replace the numbering rules for the level
572 m_xNumRules->replaceByIndex(nLevel, uno::makeAny(comphelper::containerToSequence(aLvlProps)));
573
574 // Handle the outline level here
575 if (pAbsLevel && pAbsLevel->isOutlineNumbering())
576 {
577 uno::Reference< text::XChapterNumberingSupplier > xOutlines (
578 xFactory, uno::UNO_QUERY_THROW );
579 uno::Reference< container::XIndexReplace > xOutlineRules =
580 xOutlines->getChapterNumberingRules( );
581
582 StyleSheetEntryPtr pParaStyle = pAbsLevel->GetParaStyle( );
583 aLvlProps.push_back(comphelper::makePropertyValue(getPropertyName(PROP_HEADING_STYLE_NAME), pParaStyle->sConvertedStyleName));
584
585 xOutlineRules->replaceByIndex(nLevel, uno::makeAny(comphelper::containerToSequence(aLvlProps)));
586 }
587
588 if (pAbsLevel)
589 {
590 // first level without default outline paragraph style
591 const tools::SvRef< StyleSheetEntry >& aParaStyle = pAbsLevel->GetParaStyle();
592 if ( WW_OUTLINE_MAXsal_Int16( 9 ) + 1 == m_nDefaultParentLevels && ( !aParaStyle ||
593 aParaStyle->sConvertedStyleName.getLength() != RTL_CONSTASCII_LENGTH( "Heading 1" )((sal_Int32)((sizeof(sal_n_array_size("Heading 1")))-1)) ||
594 !aParaStyle->sConvertedStyleName.startsWith("Heading ") ||
595 aParaStyle->sConvertedStyleName[ RTL_CONSTASCII_LENGTH( "Heading " )((sal_Int32)((sizeof(sal_n_array_size("Heading ")))-1)) ] - u'1' != nLevel ) )
596 {
597 m_nDefaultParentLevels = nLevel;
598 }
599 }
600
601 nLevel++;
602 }
603
604 // Create the numbering style for these rules
605 OUString sNumRulesName = getPropertyName( PROP_NUMBERING_RULES );
606 xStyle->setPropertyValue( sNumRulesName, uno::makeAny( m_xNumRules ) );
607 }
608 catch( const lang::IllegalArgumentException& )
609 {
610 TOOLS_WARN_EXCEPTION( "writerfilter", "" )do { css::uno::Any tools_warn_exception( DbgGetCaughtException
() ); do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "writerfilter")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break
; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "" << " " <<
exceptionToString(tools_warn_exception)) == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("writerfilter"), ("/home/maarten/src/libreoffice/core/writerfilter/source/dmapper/NumberingManager.cxx"
":" "610" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "" << " " << exceptionToString
(tools_warn_exception)), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "" << " " << exceptionToString
(tools_warn_exception); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("writerfilter"), ("/home/maarten/src/libreoffice/core/writerfilter/source/dmapper/NumberingManager.cxx"
":" "610" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "" << " " << exceptionToString(tools_warn_exception
)) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), (
"writerfilter"), ("/home/maarten/src/libreoffice/core/writerfilter/source/dmapper/NumberingManager.cxx"
":" "610" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "" << " " << exceptionToString
(tools_warn_exception)), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "" << " " << exceptionToString
(tools_warn_exception); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("writerfilter"), ("/home/maarten/src/libreoffice/core/writerfilter/source/dmapper/NumberingManager.cxx"
":" "610" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false); } while (false)
;
611 assert( !"Incorrect argument to UNO call" )(static_cast <bool> (!"Incorrect argument to UNO call")
? void (0) : __assert_fail ("!\"Incorrect argument to UNO call\""
, "/home/maarten/src/libreoffice/core/writerfilter/source/dmapper/NumberingManager.cxx"
, 611, __extension__ __PRETTY_FUNCTION__))
;
612 }
613 catch( const uno::RuntimeException& )
614 {
615 TOOLS_WARN_EXCEPTION( "writerfilter", "" )do { css::uno::Any tools_warn_exception( DbgGetCaughtException
() ); do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "writerfilter")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break
; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "" << " " <<
exceptionToString(tools_warn_exception)) == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("writerfilter"), ("/home/maarten/src/libreoffice/core/writerfilter/source/dmapper/NumberingManager.cxx"
":" "615" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "" << " " << exceptionToString
(tools_warn_exception)), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "" << " " << exceptionToString
(tools_warn_exception); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("writerfilter"), ("/home/maarten/src/libreoffice/core/writerfilter/source/dmapper/NumberingManager.cxx"
":" "615" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "" << " " << exceptionToString(tools_warn_exception
)) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), (
"writerfilter"), ("/home/maarten/src/libreoffice/core/writerfilter/source/dmapper/NumberingManager.cxx"
":" "615" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "" << " " << exceptionToString
(tools_warn_exception)), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "" << " " << exceptionToString
(tools_warn_exception); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("writerfilter"), ("/home/maarten/src/libreoffice/core/writerfilter/source/dmapper/NumberingManager.cxx"
":" "615" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false); } while (false)
;
616 assert( !"Incorrect argument to UNO call" )(static_cast <bool> (!"Incorrect argument to UNO call")
? void (0) : __assert_fail ("!\"Incorrect argument to UNO call\""
, "/home/maarten/src/libreoffice/core/writerfilter/source/dmapper/NumberingManager.cxx"
, 616, __extension__ __PRETTY_FUNCTION__))
;
617 }
618 catch( const uno::Exception& )
619 {
620 TOOLS_WARN_EXCEPTION( "writerfilter", "" )do { css::uno::Any tools_warn_exception( DbgGetCaughtException
() ); do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "writerfilter")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break
; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "" << " " <<
exceptionToString(tools_warn_exception)) == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("writerfilter"), ("/home/maarten/src/libreoffice/core/writerfilter/source/dmapper/NumberingManager.cxx"
":" "620" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "" << " " << exceptionToString
(tools_warn_exception)), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "" << " " << exceptionToString
(tools_warn_exception); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("writerfilter"), ("/home/maarten/src/libreoffice/core/writerfilter/source/dmapper/NumberingManager.cxx"
":" "620" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "" << " " << exceptionToString(tools_warn_exception
)) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), (
"writerfilter"), ("/home/maarten/src/libreoffice/core/writerfilter/source/dmapper/NumberingManager.cxx"
":" "620" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "" << " " << exceptionToString
(tools_warn_exception)), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "" << " " << exceptionToString
(tools_warn_exception); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("writerfilter"), ("/home/maarten/src/libreoffice/core/writerfilter/source/dmapper/NumberingManager.cxx"
":" "620" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false); } while (false)
;
621 }
622
623}
624
625//------------------------------------- NumberingManager implementation
626
627
628ListsManager::ListsManager(DomainMapper& rDMapper,
629 const uno::Reference<lang::XMultiServiceFactory> & xFactory)
630 : LoggedProperties("ListsManager")
631 , LoggedTable("ListsManager")
632 , m_rDMapper(rDMapper)
633 , m_xFactory(xFactory)
634{
635}
636
637ListsManager::~ListsManager( )
638{
639 DisposeNumPicBullets();
640}
641
642void ListsManager::DisposeNumPicBullets( )
643{
644 uno::Reference<drawing::XShape> xShape;
645 for (const auto& rNumPicBullet : m_aNumPicBullets)
646 {
647 xShape = rNumPicBullet->GetShape();
648 if (xShape.is())
649 {
650 uno::Reference<lang::XComponent> xShapeComponent(xShape, uno::UNO_QUERY);
651 xShapeComponent->dispose();
652 }
653 }
654}
655
656void ListsManager::lcl_attribute( Id nName, Value& rVal )
657{
658 ListLevel::Pointer pCurrentLvl;
659
660 if (nName != NS_ooxml::LN_CT_NumPicBullet_numPicBulletId)
661 {
662 OSL_ENSURE( m_pCurrentDefinition, "current entry has to be set here")do { if (true && (!(m_pCurrentDefinition))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/writerfilter/source/dmapper/NumberingManager.cxx"
":" "662" ": "), "%s", "current entry has to be set here"); }
} while (false)
;
663 if(!m_pCurrentDefinition)
664 return ;
665 pCurrentLvl = m_pCurrentDefinition->GetCurrentLevel( );
666 }
667 else
668 {
669 SAL_WARN_IF(!m_pCurrentNumPicBullet, "writerfilter", "current entry has to be set here")do { if (true && (!m_pCurrentNumPicBullet)) { switch (
sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN, "writerfilter"
)) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "current entry has to be set here") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("writerfilter"), ("/home/maarten/src/libreoffice/core/writerfilter/source/dmapper/NumberingManager.cxx"
":" "669" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "current entry has to be set here"), 0
); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "current entry has to be set here"; ::sal::detail::
log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("writerfilter"), ("/home/maarten/src/libreoffice/core/writerfilter/source/dmapper/NumberingManager.cxx"
":" "669" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "current entry has to be set here") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("writerfilter"), ("/home/maarten/src/libreoffice/core/writerfilter/source/dmapper/NumberingManager.cxx"
":" "669" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "current entry has to be set here"), 0
); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "current entry has to be set here"; ::sal::detail::
log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("writerfilter"), ("/home/maarten/src/libreoffice/core/writerfilter/source/dmapper/NumberingManager.cxx"
":" "669" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
670 if (!m_pCurrentNumPicBullet)
671 return;
672 }
673 int nIntValue = rVal.getInt();
674
675
676 switch(nName)
677 {
678 case NS_ooxml::LN_CT_LevelText_val:
679 {
680 //this strings contains the definition of the level
681 //the level number is marked as %n
682 //these numbers can be mixed randomly together with separators pre- and suffixes
683 //the Writer supports only a number of upper levels to show, separators is always a dot
684 //and each level can have a prefix and a suffix
685 if(pCurrentLvl)
686 {
687 //if the BulletChar is a soft-hyphen (0xad)
688 //replace it with a hard-hyphen (0x2d)
689 //-> this fixes missing hyphen export in PDF etc.
690 // see tdf#101626
691 pCurrentLvl->SetBulletChar( rVal.getString().replace( 0xad, 0x2d ) );
692 }
693 }
694 break;
695 case NS_ooxml::LN_CT_Lvl_start:
696 case NS_ooxml::LN_CT_Lvl_numFmt:
697 case NS_ooxml::LN_CT_NumFmt_format:
698 case NS_ooxml::LN_CT_NumFmt_val:
699 case NS_ooxml::LN_CT_Lvl_isLgl:
700 case NS_ooxml::LN_CT_Lvl_legacy:
701 if ( pCurrentLvl )
702 {
703 if (nName == NS_ooxml::LN_CT_NumFmt_format)
704 {
705 pCurrentLvl->SetCustomNumberFormat(rVal.getString());
706 }
707 else
708 {
709 pCurrentLvl->SetValue(nName, sal_Int32(nIntValue));
710 }
711 }
712 break;
713 case NS_ooxml::LN_CT_Num_numId:
714 m_pCurrentDefinition->SetId( rVal.getString().toInt32( ) );
715 break;
716 case NS_ooxml::LN_CT_AbstractNum_nsid:
717 m_pCurrentDefinition->SetId( nIntValue );
718 break;
719 case NS_ooxml::LN_CT_AbstractNum_tmpl:
720 AbstractListDef::SetValue( nName );
721 break;
722 case NS_ooxml::LN_CT_NumLvl_ilvl:
723 //add a new level to the level vector and make it the current one
724 m_pCurrentDefinition->AddLevel(rVal.getString().toUInt32());
725 break;
726 case NS_ooxml::LN_CT_Lvl_ilvl:
727 m_pCurrentDefinition->AddLevel(rVal.getString().toUInt32());
728 break;
729 case NS_ooxml::LN_CT_AbstractNum_abstractNumId:
730 {
731 // This one corresponds to the AbstractNum Id definition
732 // The reference to the abstract num is in the sprm method
733 sal_Int32 nVal = rVal.getString().toInt32();
734 m_pCurrentDefinition->SetId( nVal );
735 }
736 break;
737 case NS_ooxml::LN_CT_Ind_start:
738 case NS_ooxml::LN_CT_Ind_left:
739 if ( pCurrentLvl )
740 pCurrentLvl->Insert(
741 PROP_INDENT_AT, uno::makeAny( ConversionHelper::convertTwipToMM100( nIntValue ) ));
742 break;
743 case NS_ooxml::LN_CT_Ind_hanging:
744 if ( pCurrentLvl )
745 pCurrentLvl->Insert(
746 PROP_FIRST_LINE_INDENT, uno::makeAny( - ConversionHelper::convertTwipToMM100( nIntValue ) ));
747 break;
748 case NS_ooxml::LN_CT_Ind_firstLine:
749 if ( pCurrentLvl )
750 pCurrentLvl->Insert(
751 PROP_FIRST_LINE_INDENT, uno::makeAny( ConversionHelper::convertTwipToMM100( nIntValue ) ));
752 break;
753 case NS_ooxml::LN_CT_Lvl_tplc: //template code - unsupported
754 case NS_ooxml::LN_CT_Lvl_tentative: //marks level as unused in the document - unsupported
755 break;
756 case NS_ooxml::LN_CT_TabStop_pos:
757 {
758 //no paragraph attributes in ListTable char style sheets
759 if ( pCurrentLvl )
760 pCurrentLvl->SetValue( nName,
761 ConversionHelper::convertTwipToMM100( nIntValue ) );
762 }
763 break;
764 case NS_ooxml::LN_CT_TabStop_val:
765 {
766 // TODO Do something of that
767 }
768 break;
769 case NS_ooxml::LN_CT_NumPicBullet_numPicBulletId:
770 m_pCurrentNumPicBullet->SetId(rVal.getString().toInt32());
771 break;
772 default:
773 SAL_WARN("writerfilter", "ListsManager::lcl_attribute: unhandled token: " << nName)do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "writerfilter")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break
; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "ListsManager::lcl_attribute: unhandled token: "
<< nName) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("writerfilter"), ("/home/maarten/src/libreoffice/core/writerfilter/source/dmapper/NumberingManager.cxx"
":" "773" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "ListsManager::lcl_attribute: unhandled token: "
<< nName), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "ListsManager::lcl_attribute: unhandled token: "
<< nName; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("writerfilter"), ("/home/maarten/src/libreoffice/core/writerfilter/source/dmapper/NumberingManager.cxx"
":" "773" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "ListsManager::lcl_attribute: unhandled token: " <<
nName) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("writerfilter"), ("/home/maarten/src/libreoffice/core/writerfilter/source/dmapper/NumberingManager.cxx"
":" "773" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "ListsManager::lcl_attribute: unhandled token: "
<< nName), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "ListsManager::lcl_attribute: unhandled token: "
<< nName; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("writerfilter"), ("/home/maarten/src/libreoffice/core/writerfilter/source/dmapper/NumberingManager.cxx"
":" "773" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
774 }
775}
776
777void ListsManager::lcl_sprm( Sprm& rSprm )
778{
779 //fill the attributes of the style sheet
780 sal_uInt32 nSprmId = rSprm.getId();
781 if( !(m_pCurrentDefinition ||
1
Taking false branch
782 nSprmId == NS_ooxml::LN_CT_Numbering_abstractNum ||
783 nSprmId == NS_ooxml::LN_CT_Numbering_num ||
784 (nSprmId == NS_ooxml::LN_CT_NumPicBullet_pict && m_pCurrentNumPicBullet) ||
785 nSprmId == NS_ooxml::LN_CT_Numbering_numPicBullet))
786 return;
787
788 static bool bIsStartVisited = false;
789 sal_Int32 nIntValue = rSprm.getValue()->getInt();
790 switch( nSprmId )
2
Control jumps to the 'default' case at line 1076
791 {
792 case NS_ooxml::LN_CT_Numbering_abstractNum:
793 {
794 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
795 if(pProperties)
796 {
797 //create a new Abstract list entry
798 OSL_ENSURE( !m_pCurrentDefinition, "current entry has to be NULL here")do { if (true && (!(!m_pCurrentDefinition))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/writerfilter/source/dmapper/NumberingManager.cxx"
":" "798" ": "), "%s", "current entry has to be NULL here");
} } while (false)
;
799 m_pCurrentDefinition = new AbstractListDef;
800 pProperties->resolve( *this );
801 //append it to the table
802 m_aAbstractLists.push_back( m_pCurrentDefinition );
803 m_pCurrentDefinition = AbstractListDef::Pointer();
804 }
805 }
806 break;
807 case NS_ooxml::LN_CT_Numbering_num:
808 {
809 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
810 if(pProperties)
811 {
812 // Create a new list entry
813 OSL_ENSURE( !m_pCurrentDefinition, "current entry has to be NULL here")do { if (true && (!(!m_pCurrentDefinition))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/writerfilter/source/dmapper/NumberingManager.cxx"
":" "813" ": "), "%s", "current entry has to be NULL here");
} } while (false)
;
814 ListDef::Pointer listDef( new ListDef );
815 m_pCurrentDefinition = listDef.get();
816 pProperties->resolve( *this );
817 //append it to the table
818 m_aLists.push_back( listDef );
819
820 m_pCurrentDefinition = AbstractListDef::Pointer();
821 }
822 }
823 break;
824 case NS_ooxml::LN_CT_Numbering_numPicBullet:
825 {
826 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
827 if (pProperties)
828 {
829 NumPicBullet::Pointer numPicBullet(new NumPicBullet());
830 m_pCurrentNumPicBullet = numPicBullet;
831 pProperties->resolve(*this);
832 m_aNumPicBullets.push_back(numPicBullet);
833 m_pCurrentNumPicBullet = NumPicBullet::Pointer();
834 }
835 }
836 break;
837 case NS_ooxml::LN_CT_NumPicBullet_pict:
838 {
839 uno::Reference<drawing::XShape> xShape = m_rDMapper.PopPendingShape();
840
841 m_pCurrentNumPicBullet->SetShape(xShape);
842 }
843 break;
844 case NS_ooxml::LN_CT_Lvl_lvlPicBulletId:
845 if (ListLevel::Pointer pCurrentLevel = m_pCurrentDefinition->GetCurrentLevel())
846 {
847 uno::Reference<drawing::XShape> xShape;
848 for (const auto& rNumPicBullet : m_aNumPicBullets)
849 {
850 if (rNumPicBullet->GetId() == nIntValue)
851 {
852 xShape = rNumPicBullet->GetShape();
853 break;
854 }
855 }
856 if (xShape.is())
857 {
858 uno::Reference<beans::XPropertySet> xPropertySet(xShape, uno::UNO_QUERY);
859 try
860 {
861 uno::Any aAny = xPropertySet->getPropertyValue("Graphic");
862 if (aAny.has<uno::Reference<graphic::XGraphic>>() && pCurrentLevel)
863 {
864 auto xGraphic = aAny.get<uno::Reference<graphic::XGraphic>>();
865 if (xGraphic.is())
866 {
867 uno::Reference<awt::XBitmap> xBitmap(xGraphic, uno::UNO_QUERY);
868 pCurrentLevel->SetGraphicBitmap(xBitmap);
869 }
870 }
871 }
872 catch (const beans::UnknownPropertyException&)
873 {}
874
875 // Respect only the aspect ratio of the picture, not its size.
876 awt::Size aPrefSize = xShape->getSize();
877 if ( aPrefSize.Height * aPrefSize.Width != 0 )
878 {
879 // See SwDefBulletConfig::InitFont(), default height is 14.
880 const int nFontHeight = 14;
881 // Point -> mm100.
882 const int nHeight = nFontHeight * 35;
883 int nWidth = (nHeight * aPrefSize.Width) / aPrefSize.Height;
884
885 awt::Size aSize( convertMm100ToTwip(nWidth), convertMm100ToTwip(nHeight) );
886 pCurrentLevel->SetGraphicSize( aSize );
887 }
888 else
889 {
890 awt::Size aSize( convertMm100ToTwip(aPrefSize.Width), convertMm100ToTwip(aPrefSize.Height) );
891 pCurrentLevel->SetGraphicSize( aSize );
892 }
893 }
894 }
895 break;
896 case NS_ooxml::LN_CT_Num_abstractNumId:
897 {
898 sal_Int32 nAbstractNumId = rSprm.getValue()->getInt();
899 ListDef* pListDef = dynamic_cast< ListDef* >( m_pCurrentDefinition.get( ) );
900 if ( pListDef != nullptr )
901 {
902 // The current def should be a ListDef
903 pListDef->SetAbstractDefinition(
904 GetAbstractList( nAbstractNumId ) );
905 }
906 }
907 break;
908 case NS_ooxml::LN_CT_AbstractNum_multiLevelType:
909 break;
910 case NS_ooxml::LN_CT_AbstractNum_tmpl:
911 AbstractListDef::SetValue( nSprmId );
912 break;
913 case NS_ooxml::LN_CT_AbstractNum_lvl:
914 {
915 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
916 if(pProperties)
917 pProperties->resolve(*this);
918 }
919 break;
920 case NS_ooxml::LN_CT_Lvl_start:
921 if (ListLevel::Pointer pCurrentLevel = m_pCurrentDefinition->GetCurrentLevel())
922 pCurrentLevel->SetValue( nSprmId, nIntValue );
923 bIsStartVisited = true;
924 break;
925 case NS_ooxml::LN_CT_Lvl_numFmt:
926 {
927 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
928 if (pProperties)
929 {
930 pProperties->resolve(*this);
931 }
932 if (ListLevel::Pointer pCurrentLevel = m_pCurrentDefinition->GetCurrentLevel())
933 {
934 if( !bIsStartVisited )
935 {
936 pCurrentLevel->SetValue( NS_ooxml::LN_CT_Lvl_start, 0 );
937 bIsStartVisited = true;
938 }
939 }
940 }
941 break;
942 case NS_ooxml::LN_CT_Lvl_isLgl:
943 case NS_ooxml::LN_CT_Lvl_legacy:
944 if (ListLevel::Pointer pCurrentLevel = m_pCurrentDefinition->GetCurrentLevel())
945 {
946 pCurrentLevel->SetValue(nSprmId, nIntValue);
947 }
948 break;
949 case NS_ooxml::LN_CT_Lvl_suff:
950 {
951 if (ListLevel::Pointer pCurrentLevel = m_pCurrentDefinition->GetCurrentLevel())
952 {
953 SvxNumberFormat::LabelFollowedBy value = SvxNumberFormat::LISTTAB;
954 if( rSprm.getValue()->getString() == "tab" )
955 value = SvxNumberFormat::LISTTAB;
956 else if( rSprm.getValue()->getString() == "space" )
957 value = SvxNumberFormat::SPACE;
958 else if( rSprm.getValue()->getString() == "nothing" )
959 value = SvxNumberFormat::NOTHING;
960 else
961 SAL_WARN( "writerfilter", "Unknown ST_LevelSuffix value "do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "writerfilter")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break
; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "Unknown ST_LevelSuffix value "
<< rSprm.getValue()->getString()) == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("writerfilter"), ("/home/maarten/src/libreoffice/core/writerfilter/source/dmapper/NumberingManager.cxx"
":" "962" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "Unknown ST_LevelSuffix value " <<
rSprm.getValue()->getString()), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "Unknown ST_LevelSuffix value "
<< rSprm.getValue()->getString(); ::sal::detail::log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("writerfilter"), ("/home/maarten/src/libreoffice/core/writerfilter/source/dmapper/NumberingManager.cxx"
":" "962" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Unknown ST_LevelSuffix value " << rSprm.getValue
()->getString()) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("writerfilter"), ("/home/maarten/src/libreoffice/core/writerfilter/source/dmapper/NumberingManager.cxx"
":" "962" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "Unknown ST_LevelSuffix value " <<
rSprm.getValue()->getString()), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "Unknown ST_LevelSuffix value "
<< rSprm.getValue()->getString(); ::sal::detail::log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("writerfilter"), ("/home/maarten/src/libreoffice/core/writerfilter/source/dmapper/NumberingManager.cxx"
":" "962" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
962 << rSprm.getValue()->getString())do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "writerfilter")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break
; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "Unknown ST_LevelSuffix value "
<< rSprm.getValue()->getString()) == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("writerfilter"), ("/home/maarten/src/libreoffice/core/writerfilter/source/dmapper/NumberingManager.cxx"
":" "962" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "Unknown ST_LevelSuffix value " <<
rSprm.getValue()->getString()), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "Unknown ST_LevelSuffix value "
<< rSprm.getValue()->getString(); ::sal::detail::log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("writerfilter"), ("/home/maarten/src/libreoffice/core/writerfilter/source/dmapper/NumberingManager.cxx"
":" "962" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Unknown ST_LevelSuffix value " << rSprm.getValue
()->getString()) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("writerfilter"), ("/home/maarten/src/libreoffice/core/writerfilter/source/dmapper/NumberingManager.cxx"
":" "962" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "Unknown ST_LevelSuffix value " <<
rSprm.getValue()->getString()), 0); } else { ::std::ostringstream
sal_detail_stream; sal_detail_stream << "Unknown ST_LevelSuffix value "
<< rSprm.getValue()->getString(); ::sal::detail::log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("writerfilter"), ("/home/maarten/src/libreoffice/core/writerfilter/source/dmapper/NumberingManager.cxx"
":" "962" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
963 pCurrentLevel->SetValue( nSprmId, value );
964 }
965 }
966 break;
967 case NS_ooxml::LN_CT_Lvl_lvlText:
968 case NS_ooxml::LN_CT_Lvl_rPr : //contains LN_EG_RPrBase_rFonts
969 {
970 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
971 if(pProperties)
972 pProperties->resolve(*this);
973 }
974 break;
975 case NS_ooxml::LN_CT_NumLvl_lvl:
976 {
977 // overwrite level
978 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
979 if(pProperties)
980 pProperties->resolve(*this);
981 }
982 break;
983 case NS_ooxml::LN_CT_Lvl_lvlJc:
984 {
985 sal_Int16 nValue = text::HoriOrientation::NONE;
986 switch (nIntValue)
987 {
988 case NS_ooxml::LN_Value_ST_Jc_left:
989 case NS_ooxml::LN_Value_ST_Jc_start:
990 nValue = text::HoriOrientation::LEFT;
991 break;
992 case NS_ooxml::LN_Value_ST_Jc_center:
993 nValue = text::HoriOrientation::CENTER;
994 break;
995 case NS_ooxml::LN_Value_ST_Jc_right:
996 case NS_ooxml::LN_Value_ST_Jc_end:
997 nValue = text::HoriOrientation::RIGHT;
998 break;
999 }
1000
1001 if (nValue != text::HoriOrientation::NONE)
1002 {
1003 if (ListLevel::Pointer pLevel = m_pCurrentDefinition->GetCurrentLevel())
1004 {
1005 pLevel->Insert(
1006 PROP_ADJUST, uno::makeAny( nValue ) );
1007 }
1008 }
1009 }
1010 break;
1011 case NS_ooxml::LN_CT_Lvl_pPr:
1012 case NS_ooxml::LN_CT_PPrBase_ind:
1013 {
1014 //todo: how to handle paragraph properties within numbering levels (except LeftIndent and FirstLineIndent)?
1015 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
1016 if(pProperties)
1017 pProperties->resolve(*this);
1018 }
1019 break;
1020 case NS_ooxml::LN_CT_PPrBase_tabs:
1021 case NS_ooxml::LN_CT_Tabs_tab:
1022 {
1023 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
1024 if(pProperties)
1025 pProperties->resolve(*this);
1026 }
1027 break;
1028 case NS_ooxml::LN_CT_Lvl_pStyle:
1029 {
1030 OUString sStyleName = rSprm.getValue( )->getString( );
1031 if (ListLevel::Pointer pLevel = m_pCurrentDefinition->GetCurrentLevel())
1032 {
1033 StyleSheetTablePtr pStylesTable = m_rDMapper.GetStyleSheetTable( );
1034 const StyleSheetEntryPtr pStyle = pStylesTable->FindStyleSheetByISTD( sStyleName );
1035 pLevel->SetParaStyle( pStyle );
1036 }
1037 }
1038 break;
1039 case NS_ooxml::LN_CT_Num_lvlOverride:
1040 {
1041 writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
1042 if (pProperties)
1043 pProperties->resolve(*this);
1044 }
1045 break;
1046 case NS_ooxml::LN_CT_NumLvl_startOverride:
1047 {
1048 if(m_pCurrentDefinition)
1049 {
1050 if (ListLevel::Pointer pCurrentLevel = m_pCurrentDefinition->GetCurrentLevel())
1051 {
1052 pCurrentLevel->SetValue(NS_ooxml::LN_CT_NumLvl_startOverride, nIntValue);
1053 }
1054 }
1055 }
1056 break;
1057 case NS_ooxml::LN_CT_AbstractNum_numStyleLink:
1058 {
1059 OUString sStyleName = rSprm.getValue( )->getString( );
1060 m_pCurrentDefinition->SetNumStyleLink(sStyleName);
1061 }
1062 break;
1063 case NS_ooxml::LN_CT_AbstractNum_styleLink:
1064 {
1065 OUString sStyleName = rSprm.getValue()->getString();
1066 m_pCurrentDefinition->SetStyleLink(sStyleName);
1067 }
1068 break;
1069 case NS_ooxml::LN_EG_RPrBase_rFonts: //contains font properties
1070 case NS_ooxml::LN_EG_RPrBase_color:
1071 case NS_ooxml::LN_EG_RPrBase_u:
1072 case NS_ooxml::LN_EG_RPrBase_sz:
1073 case NS_ooxml::LN_EG_RPrBase_lang:
1074 case NS_ooxml::LN_EG_RPrBase_eastAsianLayout:
1075 //no break!
1076 default:
1077 if (ListLevel::Pointer pCurrentLevel = m_pCurrentDefinition->GetCurrentLevel())
3
Taking true branch
1078 {
1079 m_rDMapper.PushListProperties(pCurrentLevel.get());
4
Calling '~SvRef'
14
Returning from '~SvRef'
1080 m_rDMapper.sprm( rSprm );
1081 m_rDMapper.PopListProperties();
1082 }
15
Calling '~SvRef'
1083 }
1084}
1085
1086void ListsManager::lcl_entry(writerfilter::Reference<Properties>::Pointer_t ref )
1087{
1088 if( m_rDMapper.IsOOXMLImport() || m_rDMapper.IsRTFImport() )
1089 {
1090 ref->resolve(*this);
1091 }
1092 else
1093 {
1094 // Create AbstractListDef's
1095 OSL_ENSURE( !m_pCurrentDefinition, "current entry has to be NULL here")do { if (true && (!(!m_pCurrentDefinition))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/writerfilter/source/dmapper/NumberingManager.cxx"
":" "1095" ": "), "%s", "current entry has to be NULL here")
; } } while (false)
;
1096 m_pCurrentDefinition = new AbstractListDef( );
1097 ref->resolve(*this);
1098 //append it to the table
1099 m_aAbstractLists.push_back( m_pCurrentDefinition );
1100 m_pCurrentDefinition = AbstractListDef::Pointer();
1101 }
1102}
1103
1104AbstractListDef::Pointer ListsManager::GetAbstractList( sal_Int32 nId )
1105{
1106 for (const auto& listDef : m_aAbstractLists)
1107 {
1108 if (listDef->GetId( ) == nId)
1109 {
1110 if (listDef->GetNumStyleLink().getLength() > 0)
1111 {
1112 // If the abstract num has a style linked, check the linked style's number id.
1113 StyleSheetTablePtr pStylesTable = m_rDMapper.GetStyleSheetTable( );
1114
1115 const StyleSheetEntryPtr pStyleSheetEntry =
1116 pStylesTable->FindStyleSheetByISTD(listDef->GetNumStyleLink() );
1117
1118 const StyleSheetPropertyMap* pStyleSheetProperties =
1119 dynamic_cast<const StyleSheetPropertyMap*>(pStyleSheetEntry ? pStyleSheetEntry->pProperties.get() : nullptr);
1120
1121 if( pStyleSheetProperties && pStyleSheetProperties->GetListId() >= 0 )
1122 {
1123 ListDef::Pointer pList = GetList( pStyleSheetProperties->GetListId() );
1124 if ( pList!=nullptr )
1125 return pList->GetAbstractDefinition();
1126 }
1127
1128 // In stylesheet we did not found anything useful. Try to find base abstractnum having this stylelink
1129 for (const auto & baseListDef : m_aAbstractLists)
1130 {
1131 if (baseListDef->GetStyleLink() == listDef->GetNumStyleLink())
1132 {
1133 return baseListDef;
1134 }
1135 }
1136 }
1137
1138 // Standalone abstract list
1139 return listDef;
1140 }
1141 }
1142
1143 return nullptr;
1144}
1145
1146ListDef::Pointer ListsManager::GetList( sal_Int32 nId )
1147{
1148 ListDef::Pointer pList;
1149
1150 int nLen = m_aLists.size( );
1151 int i = 0;
1152 while ( !pList && i < nLen )
1153 {
1154 if ( m_aLists[i]->GetId( ) == nId )
1155 pList = m_aLists[i];
1156 i++;
1157 }
1158
1159 return pList;
1160}
1161
1162void ListsManager::CreateNumberingRules( )
1163{
1164 // Loop over the definitions
1165 for ( const auto& rList : m_aLists )
1166 {
1167 rList->CreateNumberingRules( m_rDMapper, m_xFactory );
1168 }
1169 m_rDMapper.GetStyleSheetTable()->ApplyNumberingStyleNameToParaStyles();
1170}
1171
1172}
1173
1174/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/tools/ref.hxx

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#ifndef INCLUDED_TOOLS_REF_HXX
20#define INCLUDED_TOOLS_REF_HXX
21
22#include <sal/config.h>
23#include <cassert>
24#include <tools/toolsdllapi.h>
25#include <utility>
26
27/**
28 This implements similar functionality to boost::intrusive_ptr
29*/
30
31namespace tools {
32
33/** T must be a class that extends SvRefBase */
34template<typename T> class SAL_DLLPUBLIC_RTTI__attribute__ ((type_visibility("default"))) SvRef final {
35public:
36 SvRef(): pObj(nullptr) {}
37
38 SvRef(SvRef&& rObj) noexcept
39 {
40 pObj = rObj.pObj;
41 rObj.pObj = nullptr;
42 }
43
44 SvRef(SvRef const & rObj): pObj(rObj.pObj)
45 {
46 if (pObj != nullptr) pObj->AddNextRef();
47 }
48
49 SvRef(T * pObjP): pObj(pObjP)
50 {
51 if (pObj != nullptr) pObj->AddFirstRef();
52 }
53
54 ~SvRef()
55 {
56 if (pObj != nullptr) pObj->ReleaseRef();
5
Taking true branch
6
Calling 'SvRefBase::ReleaseRef'
13
Returning; memory was released
16
Taking true branch
17
Use of memory after it is freed
57 }
58
59 void clear()
60 {
61 if (pObj != nullptr) {
62 T * pRefObj = pObj;
63 pObj = nullptr;
64 pRefObj->ReleaseRef();
65 }
66 }
67
68 SvRef & operator =(SvRef const & rObj)
69 {
70 if (rObj.pObj != nullptr) {
71 rObj.pObj->AddNextRef();
72 }
73 T * pRefObj = pObj;
74 pObj = rObj.pObj;
75 if (pRefObj != nullptr) {
76 pRefObj->ReleaseRef();
77 }
78 return *this;
79 }
80
81 SvRef & operator =(SvRef && rObj)
82 {
83 if (pObj != nullptr) {
84 pObj->ReleaseRef();
85 }
86 pObj = rObj.pObj;
87 rObj.pObj = nullptr;
88 return *this;
89 }
90
91 bool is() const { return pObj != nullptr; }
92
93 explicit operator bool() const { return is(); }
94
95 T * get() const { return pObj; }
96
97 T * operator ->() const { assert(pObj != nullptr)(static_cast <bool> (pObj != nullptr) ? void (0) : __assert_fail
("pObj != nullptr", "/home/maarten/src/libreoffice/core/include/tools/ref.hxx"
, 97, __extension__ __PRETTY_FUNCTION__))
; return pObj; }
98
99 T & operator *() const { assert(pObj != nullptr)(static_cast <bool> (pObj != nullptr) ? void (0) : __assert_fail
("pObj != nullptr", "/home/maarten/src/libreoffice/core/include/tools/ref.hxx"
, 99, __extension__ __PRETTY_FUNCTION__))
; return *pObj; }
100
101 bool operator ==(const SvRef<T> &rhs) const { return pObj == rhs.pObj; }
102 bool operator !=(const SvRef<T> &rhs) const { return !(*this == rhs); }
103
104private:
105 T * pObj;
106};
107
108/**
109 * This implements similar functionality to std::make_shared.
110 */
111template<typename T, typename... Args>
112SvRef<T> make_ref(Args&& ... args)
113{
114 return SvRef<T>(new T(std::forward<Args>(args)...));
115}
116
117}
118
119/** Classes that want to be referenced-counted via SvRef<T>, should extend this base class */
120class TOOLS_DLLPUBLIC__attribute__ ((visibility("default"))) SvRefBase
121{
122 // work around a clang 3.5 optimization bug: if the bNoDelete is *first*
123 // it mis-compiles "if (--nRefCount == 0)" and never deletes any object
124 unsigned int nRefCount : 31;
125 // the only reason this is not bool is because MSVC cannot handle mixed type bitfields
126 unsigned int bNoDelete : 1;
127
128protected:
129 virtual ~SvRefBase() COVERITY_NOEXCEPT_FALSE;
130
131public:
132 SvRefBase() : nRefCount(0), bNoDelete(1) {}
133 SvRefBase(const SvRefBase &) : nRefCount(0), bNoDelete(1) {}
134
135 SvRefBase & operator=(const SvRefBase &) { return *this; }
136
137 void RestoreNoDelete()
138 { bNoDelete = 1; }
139
140 void AddNextRef()
141 {
142 assert( nRefCount < (1 << 30) && "Do not add refs to dead objects" )(static_cast <bool> (nRefCount < (1 << 30) &&
"Do not add refs to dead objects") ? void (0) : __assert_fail
("nRefCount < (1 << 30) && \"Do not add refs to dead objects\""
, "/home/maarten/src/libreoffice/core/include/tools/ref.hxx",
142, __extension__ __PRETTY_FUNCTION__))
;
143 ++nRefCount;
144 }
145
146 void AddFirstRef()
147 {
148 assert( nRefCount < (1 << 30) && "Do not add refs to dead objects" )(static_cast <bool> (nRefCount < (1 << 30) &&
"Do not add refs to dead objects") ? void (0) : __assert_fail
("nRefCount < (1 << 30) && \"Do not add refs to dead objects\""
, "/home/maarten/src/libreoffice/core/include/tools/ref.hxx",
148, __extension__ __PRETTY_FUNCTION__))
;
149 if( bNoDelete )
150 bNoDelete = 0;
151 ++nRefCount;
152 }
153
154 void ReleaseRef()
155 {
156 assert( nRefCount >= 1)(static_cast <bool> (nRefCount >= 1) ? void (0) : __assert_fail
("nRefCount >= 1", "/home/maarten/src/libreoffice/core/include/tools/ref.hxx"
, 156, __extension__ __PRETTY_FUNCTION__))
;
7
Assuming field 'nRefCount' is >= 1
8
'?' condition is true
157 if( --nRefCount == 0 && !bNoDelete)
9
Assuming the condition is true
10
Assuming field 'bNoDelete' is 0
11
Taking true branch
158 {
159 // I'm not sure about the original purpose of this line, but right now
160 // it serves the purpose that anything that attempts to do an AddRef()
161 // after an object is deleted will trip an assert.
162 nRefCount = 1 << 30;
163 delete this;
12
Memory is released
164 }
165 }
166
167 unsigned int GetRefCount() const
168 { return nRefCount; }
169};
170
171template<typename T>
172class SvCompatWeakBase;
173
174/** SvCompatWeakHdl acts as an intermediary between SvCompatWeakRef<T> and T.
175*/
176template<typename T>
177class SvCompatWeakHdl final : public SvRefBase
178{
179 friend class SvCompatWeakBase<T>;
180 T* _pObj;
181
182 SvCompatWeakHdl( T* pObj ) : _pObj( pObj ) {}
183
184public:
185 void ResetWeakBase( ) { _pObj = nullptr; }
186 T* GetObj() { return _pObj; }
187};
188
189/** We only have one place that extends this, in include/sfx2/frame.hxx, class SfxFrame.
190 Its function is to notify the SvCompatWeakHdl when an SfxFrame object is deleted.
191*/
192template<typename T>
193class SvCompatWeakBase
194{
195 tools::SvRef< SvCompatWeakHdl<T> > _xHdl;
196
197public:
198 /** Does not use initializer due to compiler warnings,
199 because the lifetime of the _xHdl object can exceed the lifetime of this class.
200 */
201 SvCompatWeakBase( T* pObj ) { _xHdl = new SvCompatWeakHdl<T>( pObj ); }
202
203 ~SvCompatWeakBase() { _xHdl->ResetWeakBase(); }
204
205 SvCompatWeakHdl<T>* GetHdl() { return _xHdl.get(); }
206};
207
208/** We only have one weak reference in LO, in include/sfx2/frame.hxx, class SfxFrameWeak.
209*/
210template<typename T>
211class SAL_WARN_UNUSED__attribute__((warn_unused)) SvCompatWeakRef
212{
213 tools::SvRef< SvCompatWeakHdl<T> > _xHdl;
214public:
215 SvCompatWeakRef( ) {}
216 SvCompatWeakRef( T* pObj )
217 { if( pObj ) _xHdl = pObj->GetHdl(); }
218#if defined(__COVERITY__)
219 ~SvCompatWeakRef() COVERITY_NOEXCEPT_FALSE {}
220#endif
221 SvCompatWeakRef& operator = ( T * pObj )
222 { _xHdl = pObj ? pObj->GetHdl() : nullptr; return *this; }
223 bool is() const
224 { return _xHdl.is() && _xHdl->GetObj(); }
225 explicit operator bool() const { return is(); }
226 T* operator -> () const
227 { return _xHdl.is() ? _xHdl->GetObj() : nullptr; }
228 operator T* () const
229 { return _xHdl.is() ? _xHdl->GetObj() : nullptr; }
230};
231
232#endif
233
234/* vim:set shiftwidth=4 softtabstop=4 expandtab: */