Coverage Report

Created: 2026-07-10 11:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/oox/source/helper/propertymap.cxx
Line
Count
Source
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 <oox/helper/propertymap.hxx>
21
22
#if OSL_DEBUG_LEVEL > 0
23
# include <cstdio>
24
# include <com/sun/star/style/LineSpacing.hpp>
25
# include <com/sun/star/text/WritingMode.hpp>
26
using ::com::sun::star::style::LineSpacing;
27
using ::com::sun::star::text::WritingMode;
28
#include <comphelper/anytostring.hxx>
29
#include <iostream>
30
#endif
31
32
#include <com/sun/star/beans/PropertyValue.hpp>
33
#include <com/sun/star/beans/XPropertySet.hpp>
34
#include <com/sun/star/beans/XPropertySetInfo.hpp>
35
#include <com/sun/star/container/XIndexReplace.hpp>
36
#include <com/sun/star/awt/Rectangle.hpp>
37
#include <com/sun/star/awt/Size.hpp>
38
#include <com/sun/star/drawing/TextHorizontalAdjust.hpp>
39
#include <com/sun/star/drawing/TextVerticalAdjust.hpp>
40
#include <com/sun/star/drawing/EnhancedCustomShapeAdjustmentValue.hpp>
41
#include <com/sun/star/drawing/EnhancedCustomShapeSegment.hpp>
42
#include <com/sun/star/drawing/EnhancedCustomShapeTextFrame.hpp>
43
#include <com/sun/star/drawing/EnhancedCustomShapeParameterPair.hpp>
44
#include <com/sun/star/drawing/EnhancedCustomShapeParameterType.hpp>
45
#include <com/sun/star/drawing/HomogenMatrix3.hpp>
46
#include <cppuhelper/implbase.hxx>
47
#include <osl/diagnose.h>
48
#include <mutex>
49
#include <sal/log.hxx>
50
#include <oox/token/properties.hxx>
51
#include <oox/token/propertynames.hxx>
52
using ::com::sun::star::uno::Any;
53
using ::com::sun::star::uno::Reference;
54
using ::com::sun::star::uno::Sequence;
55
using ::com::sun::star::beans::Property;
56
using ::com::sun::star::beans::PropertyValue;
57
using ::com::sun::star::beans::UnknownPropertyException;
58
using ::com::sun::star::beans::XPropertyChangeListener;
59
using ::com::sun::star::beans::XPropertySet;
60
using ::com::sun::star::beans::XPropertySetInfo;
61
using ::com::sun::star::beans::XVetoableChangeListener;
62
using ::com::sun::star::container::XIndexReplace;
63
64
#if OSL_DEBUG_LEVEL > 0
65
#define USS(x) OUStringToOString( x, RTL_TEXTENCODING_UTF8 ).getStr()
66
using namespace ::com::sun::star;
67
using namespace ::com::sun::star::drawing;
68
using namespace ::com::sun::star::uno;
69
using ::com::sun::star::style::LineSpacing;
70
using ::com::sun::star::text::WritingMode;
71
using ::com::sun::star::drawing::TextHorizontalAdjust;
72
using ::com::sun::star::drawing::TextVerticalAdjust;
73
#endif
74
75
namespace oox {
76
77
using namespace ::com::sun::star::beans;
78
using namespace ::com::sun::star::lang;
79
using namespace ::com::sun::star::drawing;
80
using namespace ::com::sun::star::uno;
81
82
namespace {
83
84
/** This class implements a generic XPropertySet.
85
86
    Properties of all names and types can be set and later retrieved.
87
    TODO: move this to comphelper or better find an existing implementation
88
 */
89
class GenericPropertySet : public ::cppu::WeakImplHelper< XPropertySet, XPropertySetInfo >
90
{
91
public:
92
    explicit            GenericPropertySet( const PropertyMap& rPropMap );
93
94
    // XPropertySet
95
    virtual Reference< XPropertySetInfo > SAL_CALL getPropertySetInfo() override;
96
    virtual void SAL_CALL setPropertyValue( const OUString& aPropertyName, const Any& aValue ) override;
97
    virtual Any SAL_CALL getPropertyValue( const OUString& PropertyName ) override;
98
    virtual void SAL_CALL addPropertyChangeListener( const OUString& aPropertyName, const Reference< XPropertyChangeListener >& xListener ) override;
99
    virtual void SAL_CALL removePropertyChangeListener( const OUString& aPropertyName, const Reference< XPropertyChangeListener >& aListener ) override;
100
    virtual void SAL_CALL addVetoableChangeListener( const OUString& PropertyName, const Reference< XVetoableChangeListener >& aListener ) override;
101
    virtual void SAL_CALL removeVetoableChangeListener( const OUString& PropertyName, const Reference< XVetoableChangeListener >& aListener ) override;
102
103
    // XPropertySetInfo
104
    virtual Sequence< Property > SAL_CALL getProperties() override;
105
    virtual Property SAL_CALL getPropertyByName( const OUString& aName ) override;
106
    virtual sal_Bool SAL_CALL hasPropertyByName( const OUString& Name ) override;
107
108
private:
109
    std::mutex mMutex;
110
    PropertyNameMap     maPropMap;
111
};
112
113
GenericPropertySet::GenericPropertySet( const PropertyMap& rPropMap )
114
5.43k
{
115
5.43k
    rPropMap.fillPropertyNameMap(maPropMap);
116
5.43k
}
117
118
Reference< XPropertySetInfo > SAL_CALL GenericPropertySet::getPropertySetInfo()
119
5.43k
{
120
5.43k
    return this;
121
5.43k
}
122
123
void SAL_CALL GenericPropertySet::setPropertyValue( const OUString& rPropertyName, const Any& rValue )
124
0
{
125
0
    std::scoped_lock aGuard( mMutex );
126
0
    maPropMap[ rPropertyName ] = rValue;
127
0
}
128
129
Any SAL_CALL GenericPropertySet::getPropertyValue( const OUString& rPropertyName )
130
16.5k
{
131
16.5k
    PropertyNameMap::iterator aIt = maPropMap.find( rPropertyName );
132
16.5k
    if( aIt == maPropMap.end() )
133
0
        throw UnknownPropertyException(rPropertyName);
134
16.5k
    return aIt->second;
135
16.5k
}
136
137
// listeners are not supported by this implementation
138
0
void SAL_CALL GenericPropertySet::addPropertyChangeListener( const OUString& , const Reference< XPropertyChangeListener >& ) {}
139
0
void SAL_CALL GenericPropertySet::removePropertyChangeListener( const OUString& , const Reference< XPropertyChangeListener >&  ) {}
140
0
void SAL_CALL GenericPropertySet::addVetoableChangeListener( const OUString& , const Reference< XVetoableChangeListener >&  ) {}
141
0
void SAL_CALL GenericPropertySet::removeVetoableChangeListener( const OUString& , const Reference< XVetoableChangeListener >&  ) {}
142
143
// XPropertySetInfo
144
Sequence< Property > SAL_CALL GenericPropertySet::getProperties()
145
0
{
146
0
    Sequence< Property > aSeq( static_cast< sal_Int32 >( maPropMap.size() ) );
147
0
    Property* pProperty = aSeq.getArray();
148
0
    for (auto const& prop : maPropMap)
149
0
    {
150
0
        pProperty->Name = prop.first;
151
0
        pProperty->Handle = 0;
152
0
        pProperty->Type = prop.second.getValueType();
153
0
        pProperty->Attributes = 0;
154
0
        ++pProperty;
155
0
    }
156
0
    return aSeq;
157
0
}
158
159
Property SAL_CALL GenericPropertySet::getPropertyByName( const OUString& rPropertyName )
160
0
{
161
0
    PropertyNameMap::iterator aIt = maPropMap.find( rPropertyName );
162
0
    if( aIt == maPropMap.end() )
163
0
        throw UnknownPropertyException(rPropertyName);
164
0
    Property aProperty;
165
0
    aProperty.Name = aIt->first;
166
0
    aProperty.Handle = 0;
167
0
    aProperty.Type = aIt->second.getValueType();
168
0
    aProperty.Attributes = 0;
169
0
    return aProperty;
170
0
}
171
172
sal_Bool SAL_CALL GenericPropertySet::hasPropertyByName( const OUString& rPropertyName )
173
173k
{
174
173k
    return maPropMap.contains(rPropertyName);
175
173k
}
176
177
} // namespace
178
179
PropertyMap::PropertyMap() :
180
25.0M
    mpPropNames( &GetPropertyNameVector() ) // pointer instead reference to get compiler generated copy c'tor and operator=
181
25.0M
{
182
25.0M
}
183
184
bool PropertyMap::hasProperty( sal_Int32 nPropId ) const
185
595k
{
186
595k
    return maProperties.contains(nPropId);
187
595k
}
188
189
bool PropertyMap::setAnyProperty( sal_Int32 nPropId, const Any& rValue )
190
573k
{
191
573k
    if( nPropId < 0 )
192
0
        return false;
193
194
573k
    maProperties[ nPropId ] = rValue;
195
573k
    return true;
196
573k
}
197
198
Any PropertyMap::getProperty( sal_Int32 nPropId ) const
199
380k
{
200
380k
    auto it = maProperties.find(nPropId);
201
380k
    if (it != maProperties.end())
202
144k
        return it->second;
203
236k
    return Any();
204
380k
}
205
206
void PropertyMap::erase( sal_Int32 nPropId )
207
661
{
208
661
    maProperties.erase(nPropId);
209
661
}
210
211
bool PropertyMap::empty() const
212
1.19M
{
213
1.19M
    return maProperties.empty();
214
1.19M
}
215
216
void PropertyMap::assignUsed( const PropertyMap& rPropMap )
217
9.45M
{
218
9.45M
    maProperties.insert(rPropMap.maProperties.begin(), rPropMap.maProperties.end());
219
9.45M
}
220
221
const OUString& PropertyMap::getPropertyName( sal_Int32 nPropId )
222
2.34M
{
223
2.34M
    OSL_ENSURE( (0 <= nPropId) && (nPropId < PROP_COUNT), "PropertyMap::getPropertyName - invalid property identifier" );
224
2.34M
    return GetPropertyNameVector()[ nPropId ];
225
2.34M
}
226
227
void PropertyMap::assignAll( const PropertyMap& rPropMap )
228
8.57M
{
229
8.57M
    for (auto const& prop : rPropMap.maProperties)
230
7.71M
        maProperties[prop.first] = prop.second;
231
8.57M
}
232
233
Sequence< PropertyValue > PropertyMap::makePropertyValueSequence() const
234
178k
{
235
178k
    Sequence< PropertyValue > aSeq( static_cast< sal_Int32 >( maProperties.size() ) );
236
178k
    PropertyValue* pValues = aSeq.getArray();
237
178k
    for (auto const& prop : maProperties)
238
1.12M
    {
239
1.12M
        OSL_ENSURE( (0 <= prop.first) && (prop.first < PROP_COUNT), "PropertyMap::makePropertyValueSequence - invalid property identifier" );
240
1.12M
        pValues->Name = (*mpPropNames)[ prop.first ];
241
1.12M
        pValues->Value = prop.second;
242
1.12M
        pValues->State = PropertyState_DIRECT_VALUE;
243
1.12M
        ++pValues;
244
1.12M
    }
245
178k
    return aSeq;
246
178k
}
247
248
void PropertyMap::fillSequences( Sequence< OUString >& rNames, Sequence< Any >& rValues ) const
249
719k
{
250
719k
    rNames.realloc( static_cast< sal_Int32 >( maProperties.size() ) );
251
719k
    rValues.realloc( static_cast< sal_Int32 >( maProperties.size() ) );
252
719k
    if( maProperties.empty() )
253
0
        return;
254
255
719k
    OUString* pNames = rNames.getArray();
256
719k
    Any* pValues = rValues.getArray();
257
719k
    for (auto const& prop : maProperties)
258
11.5M
    {
259
11.5M
        OSL_ENSURE( (0 <= prop.first) && (prop.first < PROP_COUNT), "PropertyMap::fillSequences - invalid property identifier" );
260
11.5M
        *pNames = (*mpPropNames)[ prop.first ];
261
11.5M
        *pValues = prop.second;
262
11.5M
        ++pNames;
263
11.5M
        ++pValues;
264
11.5M
    }
265
719k
}
266
267
void PropertyMap::fillPropertyNameMap(PropertyNameMap& rMap) const
268
5.43k
{
269
5.43k
    for (auto const& prop : maProperties)
270
16.5k
    {
271
16.5k
        rMap.insert(std::pair<OUString, Any>((*mpPropNames)[prop.first], prop.second));
272
16.5k
    }
273
5.43k
}
274
275
Reference< XPropertySet > PropertyMap::makePropertySet() const
276
5.43k
{
277
5.43k
    return new GenericPropertySet( *this );
278
5.43k
}
279
280
#if OSL_DEBUG_LEVEL > 0
281
static void lclDumpAnyValue( const Any& value)
282
{
283
    OUString strValue;
284
    Sequence< OUString > strArray;
285
    Sequence< Any > anyArray;
286
    Sequence< PropertyValue > propArray;
287
    Sequence< Sequence< PropertyValue > > propArrayArray;
288
    Sequence< EnhancedCustomShapeAdjustmentValue > adjArray;
289
    Sequence< EnhancedCustomShapeSegment > segArray;
290
    Sequence< EnhancedCustomShapeParameterPair > ppArray;
291
    EnhancedCustomShapeSegment segment;
292
    EnhancedCustomShapeParameterPair pp;
293
    EnhancedCustomShapeParameter par;
294
    HomogenMatrix3 aMatrix;
295
    sal_Int32 intValue = 0;
296
    sal_uInt32 uintValue = 0;
297
    sal_Int16 int16Value = 0;
298
    sal_uInt16 uint16Value = 0;
299
    float floatValue = 0;
300
    bool boolValue = false;
301
    LineSpacing spacing;
302
//         RectanglePoint pointValue;
303
    WritingMode aWritingMode;
304
    TextVerticalAdjust aTextVertAdj;
305
    TextHorizontalAdjust aTextHorizAdj;
306
    Reference< XIndexReplace > xNumRule;
307
308
    if( value >>= strValue )
309
            fprintf (stderr,"\"%s\"\n", USS( strValue ) );
310
    else if( value >>= strArray ) {
311
            fprintf (stderr,"%s\n", USS(value.getValueTypeName()));
312
            for( int i=0; i<strArray.getLength(); i++ )
313
                fprintf (stderr,"\t\t\t[%3d] \"%s\"\n", i, USS( strArray[i] ) );
314
    } else if( value >>= propArray ) {
315
            fprintf (stderr,"%s\n", USS(value.getValueTypeName()));
316
            for( int i=0; i<propArray.getLength(); i++ ) {
317
                fprintf (stderr,"\t\t\t[%3d] %s (%s) ", i, USS( propArray[i].Name ), USS(propArray[i].Value.getValueTypeName()) );
318
                lclDumpAnyValue( propArray[i].Value );
319
            }
320
    } else if( value >>= propArrayArray ) {
321
            fprintf (stderr,"%s\n", USS(value.getValueTypeName()));
322
            for( int i=0; i<propArrayArray.getLength(); i++ ) {
323
                fprintf (stderr,"\t\t\t[%3d] ", i);
324
                lclDumpAnyValue( Any (propArrayArray[i]) );
325
            }
326
    } else if( value >>= anyArray ) {
327
            fprintf (stderr,"%s\n", USS(value.getValueTypeName()));
328
            for( int i=0; i<anyArray.getLength(); i++ ) {
329
                fprintf (stderr,"\t\t\t[%3d] (%s) ", i, USS(value.getValueTypeName()) );
330
                lclDumpAnyValue( anyArray[i] );
331
            }
332
    } else if( value >>= adjArray ) {
333
            fprintf (stderr,"%s\n", USS(value.getValueTypeName()));
334
            for( int i=0; i<adjArray.getLength(); i++ ) {
335
                fprintf (stderr,"\t\t\t[%3d] (%s) ", i, USS(adjArray[i].Value.getValueTypeName()) );
336
                lclDumpAnyValue( adjArray[i].Value );
337
            }
338
    } else if( value >>= segArray ) {
339
            fprintf (stderr,"%s\n", USS(value.getValueTypeName()));
340
            for( int i=0; i<segArray.getLength(); i++ ) {
341
                fprintf (stderr,"\t\t\t[%3d] ", i );
342
                lclDumpAnyValue( Any( segArray[i] ) );
343
            }
344
    } else if( value >>= ppArray ) {
345
            fprintf (stderr,"%s\n", USS(value.getValueTypeName()));
346
            for( int i=0; i<ppArray.getLength(); i++ ) {
347
                fprintf (stderr,"\t\t\t[%3d] ", i );
348
                lclDumpAnyValue( Any( ppArray[i] ) );
349
            }
350
    } else if( value >>= segment ) {
351
            fprintf (stderr,"Command: %d Count: %d\n", segment.Command, segment.Count);
352
    } else if( value >>= pp ) {
353
            fprintf (stderr,"First: ");
354
            lclDumpAnyValue( Any (pp.First) );
355
            fprintf (stderr,"\t\t\t      Second: ");
356
            lclDumpAnyValue( Any (pp.Second) );
357
    } else if( value >>= par ) {
358
            fprintf (stderr,"Parameter (%s): ", USS(par.Value.getValueTypeName()));
359
            lclDumpAnyValue( par.Value );
360
    } else if( value >>= aMatrix ) {
361
            fprintf (stderr,"Matrix\n%f %f %f\n%f %f %f\n%f %f %f\n", aMatrix.Line1.Column1, aMatrix.Line1.Column2, aMatrix.Line1.Column3, aMatrix.Line2.Column1, aMatrix.Line2.Column2, aMatrix.Line2.Column3, aMatrix.Line3.Column1, aMatrix.Line3.Column2, aMatrix.Line3.Column3);
362
    } else if( value >>= intValue )
363
            fprintf (stderr,"%-10" SAL_PRIdINT32 "  (hex: %" SAL_PRIxUINT32 ")\n", intValue, intValue);
364
    else if( value >>= uintValue )
365
            fprintf (stderr,"%-10" SAL_PRIuUINT32 "  (hex: %" SAL_PRIxUINT32 ")\n", uintValue, uintValue);
366
    else if( value >>= int16Value )
367
            fprintf (stderr,"%-10d  (hex: %x)\n", int16Value, int16Value);
368
    else if( value >>= uint16Value )
369
            fprintf (stderr,"%-10d  (hex: %x)\n", uint16Value, uint16Value);
370
    else if( value >>= floatValue )
371
            fprintf (stderr,"%f\n", floatValue);
372
    else if( value >>= boolValue )
373
            fprintf (stderr,"%-10d  (bool)\n", boolValue);
374
    else if( value >>= xNumRule ) {
375
            fprintf (stderr, "XIndexReplace\n");
376
            if (xNumRule.is()) {
377
                for (int k=0; k<xNumRule->getCount(); k++) {
378
                    Sequence< PropertyValue > aBulletPropSeq;
379
                    fprintf (stderr, "level %d\n", k);
380
                    if (xNumRule->getByIndex (k) >>= aBulletPropSeq) {
381
                        for (const PropertyValue& rProp : aBulletPropSeq) {
382
                            fprintf(stderr, "%46s = ", USS (rProp.Name));
383
                            lclDumpAnyValue (rProp.Value);
384
                        }
385
                    }
386
                }
387
            } else {
388
                fprintf (stderr, "empty reference\n");
389
            }
390
    } else if( value >>= aWritingMode )
391
            fprintf(stderr, "%d writing mode\n", static_cast<int>(aWritingMode));
392
    else if( value >>= aTextVertAdj ) {
393
            const char* s = "unknown";
394
            switch( aTextVertAdj ) {
395
            case TextVerticalAdjust_TOP:
396
                s = "top";
397
                break;
398
            case TextVerticalAdjust_CENTER:
399
                s = "center";
400
                break;
401
            case TextVerticalAdjust_BOTTOM:
402
                s = "bottom";
403
                break;
404
            case TextVerticalAdjust_BLOCK:
405
                s = "block";
406
                break;
407
            case TextVerticalAdjust::TextVerticalAdjust_MAKE_FIXED_SIZE:
408
                s = "make_fixed_size";
409
                break;
410
            }
411
            fprintf (stderr, "%s\n", s);
412
    } else if( value >>= aTextHorizAdj ) {
413
        const char* s = "unknown";
414
        switch( aTextHorizAdj ) {
415
            case TextHorizontalAdjust_LEFT:
416
                s = "left";
417
                break;
418
            case TextHorizontalAdjust_CENTER:
419
                s = "center";
420
                break;
421
            case TextHorizontalAdjust_RIGHT:
422
                s = "right";
423
                break;
424
            case TextHorizontalAdjust_BLOCK:
425
                s = "block";
426
                break;
427
            case TextHorizontalAdjust::TextHorizontalAdjust_MAKE_FIXED_SIZE:
428
                s = "make_fixed_size";
429
                break;
430
        }
431
        fprintf (stderr, "%s\n", s);
432
    } else if( value >>= spacing ) {
433
        fprintf (stderr, "mode: %d value: %d\n", spacing.Mode, spacing.Height);
434
    } else if( value.isExtractableTo(::cppu::UnoType<sal_Int32>::get())) {
435
        fprintf (stderr,"is extractable to int32\n");
436
    }
437
//         else if( value >>= pointValue )
438
//             fprintf (stderr,"%d            (RectanglePoint)\n", pointValue);
439
        else
440
      fprintf (stderr,"???           <unhandled type %s>\n", USS(value.getValueTypeName()));
441
}
442
443
#ifdef DBG_UTIL
444
void PropertyMap::dump( const Reference< XPropertySet >& rXPropSet )
445
{
446
    Reference< XPropertySetInfo > info = rXPropSet->getPropertySetInfo ();
447
    const Sequence< Property > props = info->getProperties ();
448
449
    SAL_INFO("oox", "dump props, len: " << props.getLength ());
450
451
    for (Property const & prop : props) {
452
        OString name = OUStringToOString( prop.Name, RTL_TEXTENCODING_UTF8);
453
        fprintf (stderr,"%30s = ", name.getStr() );
454
455
        try {
456
            lclDumpAnyValue (rXPropSet->getPropertyValue( prop.Name ));
457
        } catch (const Exception&) {
458
            fprintf (stderr,"unable to get '%s' value\n", USS(prop.Name));
459
        }
460
    }
461
}
462
#endif
463
464
static void printLevel (int level)
465
{
466
    for (int i=0; i<level; i++)
467
        fprintf (stderr, "    ");
468
}
469
470
static const char *lclGetEnhancedParameterType( sal_uInt16 nType )
471
{
472
    const char* type;
473
    switch (nType) {
474
    case EnhancedCustomShapeParameterType::NORMAL:
475
        type = "EnhancedCustomShapeParameterType::NORMAL";
476
        break;
477
    case EnhancedCustomShapeParameterType::EQUATION:
478
        type = "EnhancedCustomShapeParameterType::EQUATION";
479
        break;
480
    case EnhancedCustomShapeParameterType::ADJUSTMENT:
481
        type = "EnhancedCustomShapeParameterType::ADJUSTMENT";
482
        break;
483
    case EnhancedCustomShapeParameterType::LEFT:
484
        type = "EnhancedCustomShapeParameterType::LEFT";
485
        break;
486
    case EnhancedCustomShapeParameterType::TOP:
487
        type = "EnhancedCustomShapeParameterType::TOP";
488
        break;
489
    case EnhancedCustomShapeParameterType::RIGHT:
490
        type = "EnhancedCustomShapeParameterType::RIGHT";
491
        break;
492
    case EnhancedCustomShapeParameterType::BOTTOM:
493
        type = "EnhancedCustomShapeParameterType::BOTTOM";
494
        break;
495
    case EnhancedCustomShapeParameterType::XSTRETCH:
496
        type = "EnhancedCustomShapeParameterType::XSTRETCH";
497
        break;
498
    case EnhancedCustomShapeParameterType::YSTRETCH:
499
        type = "EnhancedCustomShapeParameterType::YSTRETCH";
500
        break;
501
    case EnhancedCustomShapeParameterType::HASSTROKE:
502
        type = "EnhancedCustomShapeParameterType::HASSTROKE";
503
        break;
504
    case EnhancedCustomShapeParameterType::HASFILL:
505
        type = "EnhancedCustomShapeParameterType::HASFILL";
506
        break;
507
    case EnhancedCustomShapeParameterType::WIDTH:
508
        type = "EnhancedCustomShapeParameterType::WIDTH";
509
        break;
510
    case EnhancedCustomShapeParameterType::HEIGHT:
511
        type = "EnhancedCustomShapeParameterType::HEIGHT";
512
        break;
513
    case EnhancedCustomShapeParameterType::LOGWIDTH:
514
        type = "EnhancedCustomShapeParameterType::LOGWIDTH";
515
        break;
516
    case EnhancedCustomShapeParameterType::LOGHEIGHT:
517
        type = "EnhancedCustomShapeParameterType::LOGHEIGHT";
518
        break;
519
    default:
520
        type = "unknown";
521
        break;
522
    }
523
    return type;
524
}
525
526
static void printParameterPairData(int level, EnhancedCustomShapeParameterPair const &pp)
527
{
528
    // These are always sal_Int32s so let's depend on that for our packing...
529
    sal_Int32 nFirstValue = {};
530
    sal_Int32 nSecondValue = {}; // spurious -Werror=maybe-uninitialized
531
    if (!(pp.First.Value >>= nFirstValue))
532
        assert (false);
533
    if (!(pp.Second.Value >>= nSecondValue))
534
        assert (false);
535
536
    printLevel (level);
537
    fprintf (stderr, "{\n");
538
    printLevel (level + 1);
539
    fprintf (stderr, "%s,\n", lclGetEnhancedParameterType(pp.First.Type));
540
    printLevel (level + 1);
541
    fprintf (stderr, "%s,\n", lclGetEnhancedParameterType(pp.Second.Type));
542
    printLevel (level + 1);
543
    fprintf (stderr, "%d, %d\n", static_cast<int>(nFirstValue), static_cast<int>(nSecondValue));
544
    printLevel (level);
545
    fprintf (stderr, "}");
546
}
547
548
static const char* lclDumpAnyValueCode( const Any& value, int level)
549
{
550
    OUString strValue;
551
    Sequence< OUString > strArray;
552
    Sequence< Any > anyArray;
553
    Sequence< awt::Size > sizeArray;
554
    Sequence< PropertyValue > propArray;
555
    Sequence< Sequence< PropertyValue > > propArrayArray;
556
    Sequence< EnhancedCustomShapeAdjustmentValue > adjArray;
557
    Sequence< EnhancedCustomShapeTextFrame > segTextFrame;
558
    Sequence< EnhancedCustomShapeSegment > segArray;
559
    Sequence< EnhancedCustomShapeParameterPair > ppArray;
560
    EnhancedCustomShapeSegment segment;
561
    EnhancedCustomShapeTextFrame textFrame;
562
    EnhancedCustomShapeParameterPair pp;
563
    EnhancedCustomShapeParameter par;
564
    awt::Rectangle rect;
565
    awt::Size size;
566
    sal_Int32 intValue;
567
    sal_uInt32 uintValue;
568
    sal_Int16 int16Value;
569
    sal_uInt16 uint16Value;
570
    sal_Int64 int64Value;
571
    float floatValue = 0;
572
    bool boolValue;
573
    LineSpacing spacing;
574
//         RectanglePoint pointValue;
575
    WritingMode aWritingMode;
576
    TextVerticalAdjust aTextVertAdj;
577
    TextHorizontalAdjust aTextHorizAdj;
578
    Reference< XIndexReplace > xNumRule;
579
580
    if( value >>= strValue )
581
    {
582
        printLevel (level);
583
        fprintf (stderr,"OUString str = \"%s\";\n", USS( strValue ) );
584
        return "Any (str)";
585
    }
586
    else if( value >>= strArray )
587
    {
588
        if (strArray.getLength() == 0)
589
            return "Sequence< OUString >(0)";
590
591
        printLevel (level);
592
        fprintf (stderr,"static const char *aStrings[] = {\n");
593
        for( int i=0; i<strArray.getLength(); i++ ) {
594
            printLevel (level + 1);
595
            fprintf (stderr,"\"%s\"%s\n", USS( strArray[i] ), i < strArray.getLength() - 1 ? "," : "" );
596
        }
597
        printLevel (level);
598
        fprintf (stderr,"};\n");
599
        return "createStringSequence( SAL_N_ELEMENTS( aStrings ), aStrings )";
600
    }
601
    else if( value >>= propArray )
602
    {
603
        printLevel (level);
604
        fprintf (stderr,"Sequence< PropertyValue > aPropSequence (%" SAL_PRIdINT32 ");\n", propArray.getLength());
605
        for( int i=0; i<propArray.getLength(); i++ ) {
606
            printLevel (level);
607
            fprintf (stderr, "{\n");
608
            printLevel (level + 1);
609
            fprintf (stderr, "aPropSequence [%d].Name = \"%s\";\n", i, USS( propArray[i].Name ));
610
            const char *var = lclDumpAnyValueCode( propArray[i].Value, level + 1 );
611
            printLevel (level + 1);
612
            fprintf (stderr, "aPropSequence [%d].Value = makeAny (%s);\n", i, var);
613
            printLevel (level);
614
            fprintf (stderr, "}\n");
615
        }
616
        return "aPropSequence";
617
    }
618
    else if( value >>= sizeArray )
619
    {
620
        printLevel (level);
621
        fprintf (stderr, "Sequence< awt::Size > aSizeSequence (%" SAL_PRIdINT32 ");\n", sizeArray.getLength());
622
        for( int i=0; i<sizeArray.getLength(); i++ ) {
623
            printLevel (level);
624
            fprintf (stderr, "{\n");
625
            const char *var = lclDumpAnyValueCode (Any (sizeArray[i]), level + 1);
626
            printLevel (level + 1);
627
            fprintf (stderr, "aSizeSequence [%d] = %s;\n", i, var);
628
            printLevel (level);
629
            fprintf (stderr, "}\n");
630
        }
631
        return "aSizeSequence";
632
    }
633
    else if( value >>= propArrayArray )
634
    {
635
        printLevel (level);
636
        fprintf (stderr,"Sequence< Sequence < PropertyValue > > aPropSequenceSequence (%" SAL_PRIdINT32 ");\n", propArrayArray.getLength());
637
        for( int i=0; i<propArrayArray.getLength(); i++ ) {
638
            printLevel (level);
639
            fprintf (stderr, "{\n");
640
            const char *var = lclDumpAnyValueCode( Any (propArrayArray[i]), level + 1 );
641
            printLevel (level + 1);
642
            fprintf (stderr, "aPropSequenceSequence [%d] = %s;\n", i, var);
643
            printLevel (level);
644
            fprintf (stderr, "}\n");
645
        }
646
        return "aPropSequenceSequence";
647
    }
648
    else if( value >>= anyArray )
649
    {
650
        fprintf (stderr,"%s\n", USS(value.getValueTypeName()));
651
        for( int i=0; i<anyArray.getLength(); i++ ) {
652
            fprintf (stderr,"\t\t\t[%3d] (%s) ", i, USS(value.getValueTypeName()) );
653
            lclDumpAnyValue( anyArray[i] );
654
        }
655
    }
656
    else if( value >>= adjArray )
657
    {
658
        printLevel (level);
659
        fprintf (stderr,"Sequence< EnhancedCustomShapeAdjustmentValue > aAdjSequence (%" SAL_PRIdINT32 ");\n", adjArray.getLength());
660
        for( int i=0; i<adjArray.getLength(); i++ ) {
661
            printLevel (level);
662
            fprintf (stderr, "{\n");
663
            const char *var = lclDumpAnyValueCode( adjArray[i].Value, level + 1 );
664
            printLevel (level + 1);
665
            fprintf (stderr, "aAdjSequence [%d].Value = %s;\n", i, var);
666
            if (adjArray[i].Name.getLength() > 0) {
667
                printLevel (level + 1);
668
                fprintf (stderr, "aAdjSequence [%d].Name = \"%s\";\n", i, USS (adjArray[i].Name));
669
            }
670
            printLevel (level);
671
            fprintf (stderr, "}\n");
672
        }
673
        return "aAdjSequence";
674
    }
675
    else if( value >>= segArray )
676
    {
677
        if (segArray.getLength() == 0)
678
            return "Sequence< EnhancedCustomShapeSegment >(0)";
679
680
        printLevel (level);
681
        fprintf (stderr,"static const sal_uInt16 nValues[] = {\n");
682
        printLevel (level);
683
        fprintf (stderr,"// Command, Count\n");
684
        for( int i = 0; i < segArray.getLength(); i++ ) {
685
            printLevel (level + 1);
686
            fprintf (stderr,"%d,%d%s\n", segArray[i].Command,
687
                    segArray[i].Count, i < segArray.getLength() - 1 ? "," : "");
688
        }
689
        printLevel (level);
690
        fprintf (stderr,"};\n");
691
        return "createSegmentSequence( SAL_N_ELEMENTS( nValues ), nValues )";
692
    }
693
    else if( value >>= segTextFrame )
694
    {
695
        printLevel (level);
696
        fprintf (stderr, "Sequence< EnhancedCustomShapeTextFrame > aTextFrameSeq (%" SAL_PRIdINT32 ");\n", segTextFrame.getLength());
697
        for( int i=0; i<segTextFrame.getLength(); i++ ) {
698
            printLevel (level);
699
            fprintf (stderr, "{\n");
700
            const char *var = lclDumpAnyValueCode (Any (segTextFrame[i]), level + 1);
701
            printLevel (level + 1);
702
            fprintf (stderr, "aTextFrameSeq [%d] = %s;\n", i, var);
703
            printLevel (level);
704
            fprintf (stderr, "}\n");
705
        }
706
        return "aTextFrameSeq";
707
    }
708
    else if( value >>= ppArray )
709
    {
710
        printLevel (level);
711
        if (ppArray.getLength() == 0)
712
            return "Sequence< EnhancedCustomShapeParameterPair >(0)";
713
714
        fprintf (stderr, "static const CustomShapeProvider::ParameterPairData aData[] = {\n");
715
        for( int i = 0; i < ppArray.getLength(); i++ ) {
716
            printParameterPairData(level + 1, ppArray[i]);
717
            fprintf (stderr,"%s\n", i < ppArray.getLength() - 1 ? "," : "");
718
        }
719
        printLevel (level);
720
        fprintf (stderr,"};\n");
721
722
        return "createParameterPairSequence(SAL_N_ELEMENTS(aData), aData)";
723
    }
724
    else if( value >>= segment )
725
    {
726
        printLevel (level);
727
        fprintf (stderr, "EnhancedCustomShapeSegment aSegment;\n");
728
        printLevel (level);
729
        // TODO: use EnhancedCustomShapeSegmentCommand constants
730
        fprintf (stderr, "aSegment.Command = %d;\n", segment.Command);
731
        printLevel (level);
732
        fprintf (stderr, "aSegment.Count = %d;\n", segment.Count);
733
        return "aSegment";
734
    }
735
    else if( value >>= textFrame )
736
    {
737
        printLevel (level);
738
        fprintf (stderr, "EnhancedCustomShapeTextFrame aTextFrame;\n");
739
        printLevel (level);
740
        fprintf (stderr, "{\n");
741
        {
742
            const char* var = lclDumpAnyValueCode( Any (textFrame.TopLeft), level + 1 );
743
            printLevel (level + 1);
744
            fprintf (stderr, "aTextFrame.TopLeft = %s;\n", var);
745
        }
746
        printLevel (level);
747
        fprintf (stderr, "}\n");
748
749
        printLevel (level);
750
        fprintf (stderr, "{\n");
751
        {
752
            const char* var = lclDumpAnyValueCode( Any (textFrame.BottomRight), level + 1 );
753
            printLevel (level + 1);
754
            fprintf (stderr, "aTextFrame.BottomRight = %s;\n", var);
755
        }
756
        printLevel (level);
757
        fprintf (stderr, "}\n");
758
759
        return "aTextFrame";
760
    }
761
    else if( value >>= pp )
762
    {
763
        printLevel (level);
764
        fprintf (stderr, "static const CustomShapeProvider::ParameterPairData aData =\n");
765
        printParameterPairData(level, pp);
766
        fprintf (stderr, ";\n");
767
768
        return "createParameterPair(&aData)";
769
    }
770
    else if( value >>= par )
771
    {
772
        printLevel (level);
773
        fprintf (stderr,"EnhancedCustomShapeParameter aParameter;\n");
774
        const char* var = lclDumpAnyValueCode( par.Value, level );
775
        printLevel (level);
776
        fprintf (stderr,"aParameter.Value = %s;\n", var);
777
        printLevel (level);
778
        fprintf (stderr,"aParameter.Type = %s;\n",
779
                lclGetEnhancedParameterType(par.Type));
780
        return "aParameter";
781
    }
782
    else if( value >>= int64Value )
783
    {
784
        printLevel (level);
785
        fprintf (stderr,"Any aAny ((sal_Int64) %" SAL_PRIdINT64 ");\n", int64Value);
786
        return "aAny";
787
    }
788
    else if( value >>= intValue )
789
        fprintf (stderr,"%" SAL_PRIdINT32 "            (hex: %" SAL_PRIxUINT32 ")\n", intValue, intValue);
790
    else if( value >>= uintValue )
791
        fprintf (stderr,"%" SAL_PRIdINT32 "            (hex: %" SAL_PRIxUINT32 ")\n", uintValue, uintValue);
792
    else if( value >>= int16Value )
793
        fprintf (stderr,"%d            (hex: %x)\n", int16Value, int16Value);
794
    else if( value >>= uint16Value )
795
        fprintf (stderr,"%d            (hex: %x)\n", uint16Value, uint16Value);
796
    else if( value >>= floatValue )
797
        fprintf (stderr,"%f\n", floatValue);
798
    else if( value >>= boolValue ) {
799
        if (boolValue)
800
            return "(sal_Bool) sal_True";
801
        else
802
            return "(sal_Bool) sal_False";
803
    }
804
    else if( value >>= xNumRule ) {
805
        fprintf (stderr, "XIndexReplace\n");
806
        for (int k=0; k<xNumRule->getCount(); k++) {
807
            Sequence< PropertyValue > aBulletPropSeq;
808
            fprintf (stderr, "level %d\n", k);
809
            if (xNumRule->getByIndex (k) >>= aBulletPropSeq) {
810
                for (const PropertyValue& rProp : aBulletPropSeq) {
811
                    fprintf(stderr, "%46s = ", USS (rProp.Name));
812
                    lclDumpAnyValue (rProp.Value);
813
                }
814
            }
815
        }
816
    }
817
    else if( value >>= aWritingMode )
818
        fprintf (stderr, "%d writing mode\n", static_cast<int>(aWritingMode));
819
    else if( value >>= aTextVertAdj ) {
820
        const char* s = "unknown";
821
        switch( aTextVertAdj ) {
822
            case TextVerticalAdjust_TOP:
823
                s = "top";
824
                break;
825
            case TextVerticalAdjust_CENTER:
826
                s = "center";
827
                break;
828
            case TextVerticalAdjust_BOTTOM:
829
                s = "bottom";
830
                break;
831
            case TextVerticalAdjust_BLOCK:
832
                s = "block";
833
                break;
834
            case TextVerticalAdjust::TextVerticalAdjust_MAKE_FIXED_SIZE:
835
                s = "make_fixed_size";
836
                break;
837
        }
838
        fprintf (stderr, "%s\n", s);
839
    }
840
    else if( value >>= aTextHorizAdj ) {
841
        const char* s = "unknown";
842
        switch( aTextHorizAdj ) {
843
            case TextHorizontalAdjust_LEFT:
844
                s = "left";
845
                break;
846
            case TextHorizontalAdjust_CENTER:
847
                s = "center";
848
                break;
849
            case TextHorizontalAdjust_RIGHT:
850
                s = "right";
851
                break;
852
            case TextHorizontalAdjust_BLOCK:
853
                s = "block";
854
                break;
855
            case TextHorizontalAdjust::TextHorizontalAdjust_MAKE_FIXED_SIZE:
856
                s = "make_fixed_size";
857
                break;
858
        }
859
        fprintf (stderr, "%s\n", s);
860
    }
861
    else if( value >>= spacing ) {
862
        fprintf (stderr, "mode: %d value: %d\n", spacing.Mode, spacing.Height);
863
    }
864
    else if( value >>= rect ) {
865
        printLevel (level);
866
        fprintf (stderr, "awt::Rectangle aRectangle;\n");
867
        printLevel (level);
868
        fprintf (stderr, "aRectangle.X = %" SAL_PRIdINT32 ";\n", rect.X);
869
        printLevel (level);
870
        fprintf (stderr, "aRectangle.Y = %" SAL_PRIdINT32 ";\n", rect.Y);
871
        printLevel (level);
872
        fprintf (stderr, "aRectangle.Width = %" SAL_PRIdINT32 ";\n", rect.Width);
873
        printLevel (level);
874
        fprintf (stderr, "aRectangle.Height = %" SAL_PRIdINT32 ";\n", rect.Height);
875
        return "aRectangle";
876
    }
877
    else if( value >>= size ) {
878
        printLevel (level);
879
        fprintf (stderr, "awt::Size aSize;\n");
880
        printLevel (level);
881
        fprintf (stderr, "aSize.Width = %" SAL_PRIdINT32 ";\n", size.Width);
882
        printLevel (level);
883
        fprintf (stderr, "aSize.Height = %" SAL_PRIdINT32 ";\n", size.Height);
884
        return "aSize";
885
    }
886
    else if( value.isExtractableTo(::cppu::UnoType<sal_Int32>::get())) {
887
        fprintf (stderr,"is extractable to int32\n");
888
    }
889
    else
890
        fprintf (stderr,"???           <unhandled type %s>\n", USS(value.getValueTypeName()));
891
892
    return "";
893
}
894
895
void PropertyMap::dumpCode( const Reference< XPropertySet >& rXPropSet )
896
{
897
    Reference< XPropertySetInfo > info = rXPropSet->getPropertySetInfo ();
898
    const Sequence< Property > props = info->getProperties ();
899
    static constexpr OUStringLiteral sType = u"Type";
900
901
    for (const Property& rProp : props) {
902
903
        // ignore Type, it is set elsewhere
904
        if (rProp.Name == sType)
905
            continue;
906
907
        OString name = OUStringToOString( rProp.Name, RTL_TEXTENCODING_UTF8);
908
909
        try {
910
            int level = 1;
911
            printLevel (level);
912
            fprintf (stderr, "{\n");
913
            const char* var = lclDumpAnyValueCode (rXPropSet->getPropertyValue (rProp.Name), level + 1);
914
            printLevel (level + 1);
915
            fprintf (stderr,"aPropertyMap.setProperty(PROP_%s, %s);\n", name.getStr(), var);
916
            printLevel (level);
917
            fprintf (stderr, "}\n");
918
        } catch (const Exception&) {
919
            fprintf (stderr,"unable to get '%s' value\n", USS(rProp.Name));
920
        }
921
    }
922
}
923
924
void PropertyMap::dumpData(const Reference<XPropertySet>& xPropertySet)
925
{
926
    Reference<XPropertySetInfo> xPropertySetInfo = xPropertySet->getPropertySetInfo();
927
    const Sequence<Property> aProperties = xPropertySetInfo->getProperties();
928
929
    for (const Property& rProp : aProperties)
930
    {
931
        std::cerr << rProp.Name << std::endl;
932
        std::cerr << comphelper::anyToString(xPropertySet->getPropertyValue(rProp.Name)) << std::endl;
933
    }
934
}
935
936
#endif
937
938
} // namespace oox
939
940
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */