Coverage Report

Created: 2026-03-31 11:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/oox/source/drawingml/chart/objectformatter.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 <drawingml/chart/objectformatter.hxx>
21
22
#include <com/sun/star/chart2/XChartDocument.hpp>
23
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
24
#include <com/sun/star/util/XNumberFormatsSupplier.hpp>
25
#include <com/sun/star/util/XNumberFormatTypes.hpp>
26
#include <comphelper/diagnose_ex.hxx>
27
#include <comphelper/sequenceashashmap.hxx>
28
#include <osl/thread.h>
29
#include <osl/diagnose.h>
30
#include <rtl/strbuf.hxx>
31
#include <oox/core/xmlfilterbase.hxx>
32
#include <drawingml/fillproperties.hxx>
33
#include <drawingml/lineproperties.hxx>
34
#include <oox/drawingml/shapepropertymap.hxx>
35
#include <drawingml/textbody.hxx>
36
#include <drawingml/textparagraph.hxx>
37
#include <oox/drawingml/theme.hxx>
38
#include <drawingml/chart/chartspacemodel.hxx>
39
#include <oox/helper/modelobjecthelper.hxx>
40
#include <oox/helper/graphichelper.hxx>
41
#include <oox/token/properties.hxx>
42
#include <oox/token/tokens.hxx>
43
44
#include <unotools/mediadescriptor.hxx>
45
46
namespace oox::drawingml::chart {
47
48
using namespace ::com::sun::star::chart2;
49
using namespace ::com::sun::star::lang;
50
using namespace ::com::sun::star::uno;
51
using namespace ::com::sun::star::util;
52
53
using ::oox::core::XmlFilterBase;
54
55
namespace {
56
57
struct AutoFormatPatternEntry
58
{
59
    sal_Int32           mnColorToken;       /// Theme color token.
60
    sal_Int32           mnModToken;         /// Color modification token.
61
    sal_Int32           mnModValue;         /// Color modification value.
62
};
63
64
#define AUTOFORMAT_PATTERN_COLOR( color_token ) \
65
    { color_token, XML_TOKEN_INVALID, 0 }
66
67
#define AUTOFORMAT_PATTERN_COLORMOD( color_token, mod_token, mod_value ) \
68
    { color_token, mod_token, mod_value }
69
70
#define AUTOFORMAT_PATTERN_END() \
71
    AUTOFORMAT_PATTERN_COLOR( XML_TOKEN_INVALID )
72
73
const AutoFormatPatternEntry spAutoFormatPattern1[] =
74
{
75
    AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint, 88500 ),
76
    AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint, 55000 ),
77
    AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint, 78000 ),
78
    AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint, 92500 ),
79
    AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint, 70000 ),
80
    AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint, 30000 ),
81
    AUTOFORMAT_PATTERN_END()
82
};
83
84
const AutoFormatPatternEntry spAutoFormatPattern2[] =
85
{
86
    AUTOFORMAT_PATTERN_COLOR( XML_accent1 ),
87
    AUTOFORMAT_PATTERN_COLOR( XML_accent2 ),
88
    AUTOFORMAT_PATTERN_COLOR( XML_accent3 ),
89
    AUTOFORMAT_PATTERN_COLOR( XML_accent4 ),
90
    AUTOFORMAT_PATTERN_COLOR( XML_accent5 ),
91
    AUTOFORMAT_PATTERN_COLOR( XML_accent6 ),
92
    AUTOFORMAT_PATTERN_END()
93
};
94
95
const AutoFormatPatternEntry spAutoFormatPattern3[] =
96
{
97
    AUTOFORMAT_PATTERN_COLORMOD( XML_accent1, XML_shade, 50000 ),
98
    AUTOFORMAT_PATTERN_COLORMOD( XML_accent2, XML_shade, 50000 ),
99
    AUTOFORMAT_PATTERN_COLORMOD( XML_accent3, XML_shade, 50000 ),
100
    AUTOFORMAT_PATTERN_COLORMOD( XML_accent4, XML_shade, 50000 ),
101
    AUTOFORMAT_PATTERN_COLORMOD( XML_accent5, XML_shade, 50000 ),
102
    AUTOFORMAT_PATTERN_COLORMOD( XML_accent6, XML_shade, 50000 ),
103
    AUTOFORMAT_PATTERN_END()
104
};
105
106
const AutoFormatPatternEntry spAutoFormatPattern4[] =
107
{
108
    AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint,  5000 ),
109
    AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint, 55000 ),
110
    AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint, 78000 ),
111
    AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint, 15000 ),
112
    AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint, 70000 ),
113
    AUTOFORMAT_PATTERN_COLORMOD( XML_dk1, XML_tint, 30000 ),
114
    AUTOFORMAT_PATTERN_END()
115
};
116
117
#undef AUTOFORMAT_PATTERN_COLOR
118
#undef AUTOFORMAT_PATTERN_COLORMOD
119
#undef AUTOFORMAT_PATTERN_END
120
121
struct AutoFormatEntry
122
{
123
    sal_Int32           mnFirstStyleIdx;    /// First chart style index.
124
    sal_Int32           mnLastStyleIdx;     /// Last chart style index.
125
    sal_Int32           mnThemedIdx;        /// Themed style index.
126
    sal_Int32           mnColorToken;       /// Theme color token.
127
    sal_Int32           mnModToken;         /// Color modification token.
128
    sal_Int32           mnModValue;         /// Color modification value.
129
    sal_Int32           mnRelLineWidth;     /// Relative line width (percent).
130
    const AutoFormatPatternEntry* mpPattern;/// Color cycling pattern for data series.
131
    bool                mbFadedColor;       /// True = Faded color for data series.
132
};
133
134
#define AUTOFORMAT_COLOR( first, last, themed_style, color_token ) \
135
    { first, last, themed_style, color_token, XML_TOKEN_INVALID, 0, 100, nullptr, false }
136
137
#define AUTOFORMAT_COLORMOD( first, last, themed_style, color_token, mod_token, mod_value ) \
138
    { first, last, themed_style, color_token, mod_token, mod_value, 100, nullptr, false }
139
140
#define AUTOFORMAT_ACCENTSMOD( first, themed_style, mod_token, mod_value ) \
141
    AUTOFORMAT_COLORMOD( first,     first,     themed_style, XML_accent1, mod_token, mod_value ), \
142
    AUTOFORMAT_COLORMOD( first + 1, first + 1, themed_style, XML_accent2, mod_token, mod_value ), \
143
    AUTOFORMAT_COLORMOD( first + 2, first + 2, themed_style, XML_accent3, mod_token, mod_value ), \
144
    AUTOFORMAT_COLORMOD( first + 3, first + 3, themed_style, XML_accent4, mod_token, mod_value ), \
145
    AUTOFORMAT_COLORMOD( first + 4, first + 4, themed_style, XML_accent5, mod_token, mod_value ), \
146
    AUTOFORMAT_COLORMOD( first + 5, first + 5, themed_style, XML_accent6, mod_token, mod_value )
147
148
#define AUTOFORMAT_PATTERN( first, last, themed_style, line_width, pattern ) \
149
    { first, last, themed_style, XML_TOKEN_INVALID, XML_TOKEN_INVALID, 0, line_width, pattern, false }
150
151
#define AUTOFORMAT_FADED( first, last, themed_style, color_token, line_width ) \
152
    { first, last, themed_style, color_token, XML_TOKEN_INVALID, 0, line_width, nullptr, true }
153
154
#define AUTOFORMAT_FADEDACCENTS( first, themed_style, line_width ) \
155
    AUTOFORMAT_FADED( first,     first,     themed_style, XML_accent1, line_width ), \
156
    AUTOFORMAT_FADED( first + 1, first + 1, themed_style, XML_accent2, line_width ), \
157
    AUTOFORMAT_FADED( first + 2, first + 2, themed_style, XML_accent3, line_width ), \
158
    AUTOFORMAT_FADED( first + 3, first + 3, themed_style, XML_accent4, line_width ), \
159
    AUTOFORMAT_FADED( first + 4, first + 4, themed_style, XML_accent5, line_width ), \
160
    AUTOFORMAT_FADED( first + 5, first + 5, themed_style, XML_accent6, line_width )
161
162
#define AUTOFORMAT_INVISIBLE( first, last ) \
163
    AUTOFORMAT_COLOR( first, last, -1, XML_TOKEN_INVALID )
164
165
#define AUTOFORMAT_END() \
166
    AUTOFORMAT_INVISIBLE( -1, -1 )
167
168
const AutoFormatEntry spNoFormats[] =
169
{
170
    AUTOFORMAT_INVISIBLE( 1, 48 ),
171
    AUTOFORMAT_END()
172
};
173
174
const AutoFormatEntry spChartSpaceFill[] =
175
{
176
    AUTOFORMAT_COLOR( 1, 32, THEMED_STYLE_SUBTLE, XML_bg1 ),
177
    AUTOFORMAT_COLOR( 33, 40, THEMED_STYLE_SUBTLE, XML_lt1 ),
178
    AUTOFORMAT_COLOR( 41, 48, THEMED_STYLE_SUBTLE, XML_dk1 ),
179
    AUTOFORMAT_END()
180
};
181
182
const AutoFormatEntry spDataTableLines[] =
183
{
184
    AUTOFORMAT_COLORMOD(  1, 32, THEMED_STYLE_SUBTLE, XML_tx1, XML_tint, 75000 ),
185
    AUTOFORMAT_COLORMOD( 33, 40, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 75000 ),
186
    // 41...48: no line, same as Chart2
187
    AUTOFORMAT_END()
188
};
189
190
const AutoFormatEntry spPlotArea2dFills[] =
191
{
192
    AUTOFORMAT_COLOR(       1, 32, THEMED_STYLE_SUBTLE, XML_bg1 ),
193
    AUTOFORMAT_COLORMOD(   33, 34, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 20000 ),
194
    AUTOFORMAT_ACCENTSMOD( 35,     THEMED_STYLE_SUBTLE,          XML_tint, 20000 ), // tint not documented!?
195
    AUTOFORMAT_COLORMOD(   41, 48, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 95000 ),
196
    AUTOFORMAT_END()
197
};
198
199
const AutoFormatEntry spWallFloorLines[] =
200
{
201
    AUTOFORMAT_COLORMOD(  1, 32, THEMED_STYLE_SUBTLE, XML_tx1, XML_tint, 75000 ),
202
    AUTOFORMAT_COLORMOD( 33, 40, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 75000 ),
203
    // 41...48: no line, same as Chart2
204
    AUTOFORMAT_END()
205
};
206
207
const AutoFormatEntry spWallFloorFills[] =
208
{
209
    AUTOFORMAT_INVISIBLE(   1, 32 ),
210
    AUTOFORMAT_COLORMOD(   33, 34, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 20000 ),
211
    AUTOFORMAT_ACCENTSMOD( 35,     THEMED_STYLE_SUBTLE,          XML_tint, 20000 ), // tint not documented!?
212
    AUTOFORMAT_COLORMOD(   41, 48, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 95000 ),
213
    AUTOFORMAT_END()
214
};
215
216
const AutoFormatEntry spAxisLines[] =
217
{
218
    AUTOFORMAT_COLORMOD(  1, 32, THEMED_STYLE_SUBTLE, XML_tx1, XML_tint, 75000 ),   // tint not documented!?
219
    AUTOFORMAT_COLORMOD( 33, 48, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 75000 ),   // tint not documented!?
220
    AUTOFORMAT_END()
221
};
222
223
const AutoFormatEntry spMajorGridLines[] =
224
{
225
    AUTOFORMAT_COLORMOD(  1, 32, THEMED_STYLE_SUBTLE, XML_tx1, XML_tint, 75000 ),   // tint not documented!?
226
    AUTOFORMAT_COLORMOD( 33, 48, THEMED_STYLE_SUBTLE, XML_dk1, XML_tint, 75000 ),   // tint not documented!?
227
    AUTOFORMAT_END()
228
};
229
230
const AutoFormatEntry spMinorGridLines[] =
231
{
232
    AUTOFORMAT_COLORMOD(  1, 40, THEMED_STYLE_SUBTLE, XML_tx1, XML_tint, 50000 ),
233
    AUTOFORMAT_COLORMOD( 41, 48, THEMED_STYLE_SUBTLE, XML_tx1, XML_tint, 90000 ),
234
    AUTOFORMAT_END()
235
};
236
237
const AutoFormatEntry spOtherLines[] =
238
{
239
    AUTOFORMAT_COLOR(     1, 32, THEMED_STYLE_SUBTLE, XML_tx1 ),
240
    AUTOFORMAT_COLOR(    33, 34, THEMED_STYLE_SUBTLE, XML_dk1 ),
241
    AUTOFORMAT_COLORMOD( 35, 40, THEMED_STYLE_SUBTLE, XML_dk1, XML_shade, 25000 ),
242
    AUTOFORMAT_COLOR(    41, 48, THEMED_STYLE_SUBTLE, XML_lt1 ),
243
    AUTOFORMAT_END()
244
};
245
246
const AutoFormatEntry spLinearSeriesLines[] =
247
{
248
    AUTOFORMAT_PATTERN(       1,  1, THEMED_STYLE_SUBTLE, 300, spAutoFormatPattern1 ),
249
    AUTOFORMAT_PATTERN(       2,  2, THEMED_STYLE_SUBTLE, 300, spAutoFormatPattern2 ),
250
    AUTOFORMAT_FADEDACCENTS(  3,     THEMED_STYLE_SUBTLE, 300 ),
251
    AUTOFORMAT_PATTERN(       9,  9, THEMED_STYLE_SUBTLE, 500, spAutoFormatPattern1 ),
252
    AUTOFORMAT_PATTERN(      10, 10, THEMED_STYLE_SUBTLE, 500, spAutoFormatPattern2 ),
253
    AUTOFORMAT_FADEDACCENTS( 11,     THEMED_STYLE_SUBTLE, 500 ),
254
    AUTOFORMAT_PATTERN(      17, 17, THEMED_STYLE_SUBTLE, 500, spAutoFormatPattern1 ),
255
    AUTOFORMAT_PATTERN(      18, 18, THEMED_STYLE_SUBTLE, 500, spAutoFormatPattern2 ),
256
    AUTOFORMAT_FADEDACCENTS( 19,     THEMED_STYLE_SUBTLE, 500 ),
257
    AUTOFORMAT_PATTERN(      25, 25, THEMED_STYLE_SUBTLE, 700, spAutoFormatPattern1 ),
258
    AUTOFORMAT_PATTERN(      26, 26, THEMED_STYLE_SUBTLE, 700, spAutoFormatPattern2 ),
259
    AUTOFORMAT_FADEDACCENTS( 27,     THEMED_STYLE_SUBTLE, 700 ),
260
    AUTOFORMAT_PATTERN(      33, 33, THEMED_STYLE_SUBTLE, 500, spAutoFormatPattern1 ),
261
    AUTOFORMAT_PATTERN(      34, 34, THEMED_STYLE_SUBTLE, 500, spAutoFormatPattern2 ),
262
    AUTOFORMAT_FADEDACCENTS( 35,     THEMED_STYLE_SUBTLE, 500 ),
263
    AUTOFORMAT_PATTERN(      41, 42, THEMED_STYLE_SUBTLE, 500, spAutoFormatPattern4 ),
264
    AUTOFORMAT_PATTERN(      42, 42, THEMED_STYLE_SUBTLE, 500, spAutoFormatPattern2 ),
265
    AUTOFORMAT_FADEDACCENTS( 43,     THEMED_STYLE_SUBTLE, 500 ),
266
    AUTOFORMAT_END()
267
};
268
269
const AutoFormatEntry spFilledSeriesLines[] =
270
{
271
    AUTOFORMAT_INVISIBLE(   1,  8 ),
272
    AUTOFORMAT_COLOR(       9, 16, THEMED_STYLE_SUBTLE, XML_lt1 ),
273
    AUTOFORMAT_INVISIBLE(  17, 32 ),
274
    AUTOFORMAT_COLORMOD(   33, 33, THEMED_STYLE_SUBTLE, XML_dk1, XML_shade, 50000 ),
275
    AUTOFORMAT_PATTERN(    34, 34, THEMED_STYLE_SUBTLE, 100, spAutoFormatPattern3 ),
276
    AUTOFORMAT_ACCENTSMOD( 35,     THEMED_STYLE_SUBTLE,          XML_shade, 50000 ),
277
    AUTOFORMAT_INVISIBLE(  41, 48 ),
278
    AUTOFORMAT_END()
279
};
280
281
const AutoFormatEntry spFilledSeries2dFills[] =
282
{
283
    AUTOFORMAT_PATTERN(       1,  1, THEMED_STYLE_SUBTLE,  100, spAutoFormatPattern1 ),
284
    AUTOFORMAT_PATTERN(       2,  2, THEMED_STYLE_SUBTLE,  100, spAutoFormatPattern2 ),
285
    AUTOFORMAT_FADEDACCENTS(  3,     THEMED_STYLE_SUBTLE,  100 ),
286
    AUTOFORMAT_PATTERN(       9,  9, THEMED_STYLE_SUBTLE,  100, spAutoFormatPattern1 ),
287
    AUTOFORMAT_PATTERN(      10, 10, THEMED_STYLE_SUBTLE,  100, spAutoFormatPattern2 ),
288
    AUTOFORMAT_FADEDACCENTS( 11,     THEMED_STYLE_SUBTLE,  100 ),
289
    AUTOFORMAT_PATTERN(      17, 17, THEMED_STYLE_INTENSE, 100, spAutoFormatPattern1 ),
290
    AUTOFORMAT_PATTERN(      18, 18, THEMED_STYLE_INTENSE, 100, spAutoFormatPattern2 ),
291
    AUTOFORMAT_FADEDACCENTS( 19,     THEMED_STYLE_INTENSE, 100 ),
292
    AUTOFORMAT_PATTERN(      25, 25, THEMED_STYLE_INTENSE, 100, spAutoFormatPattern1 ),
293
    AUTOFORMAT_PATTERN(      26, 26, THEMED_STYLE_INTENSE, 100, spAutoFormatPattern2 ),
294
    AUTOFORMAT_FADEDACCENTS( 27,     THEMED_STYLE_INTENSE, 100 ),
295
    AUTOFORMAT_PATTERN(      33, 33, THEMED_STYLE_SUBTLE,  100, spAutoFormatPattern1 ),
296
    AUTOFORMAT_PATTERN(      34, 34, THEMED_STYLE_SUBTLE,  100, spAutoFormatPattern2 ),
297
    AUTOFORMAT_FADEDACCENTS( 35,     THEMED_STYLE_SUBTLE,  100 ),
298
    AUTOFORMAT_PATTERN(      41, 42, THEMED_STYLE_INTENSE, 100, spAutoFormatPattern4 ),
299
    AUTOFORMAT_PATTERN(      42, 42, THEMED_STYLE_INTENSE, 100, spAutoFormatPattern2 ),
300
    AUTOFORMAT_FADEDACCENTS( 43,     THEMED_STYLE_INTENSE, 100 ),
301
    AUTOFORMAT_END()
302
};
303
304
const AutoFormatEntry spFilledSeries3dFills[] =
305
{
306
    AUTOFORMAT_PATTERN(       1,  1, THEMED_STYLE_SUBTLE,  100, spAutoFormatPattern1 ),
307
    AUTOFORMAT_PATTERN(       2,  2, THEMED_STYLE_SUBTLE,  100, spAutoFormatPattern2 ),
308
    AUTOFORMAT_FADEDACCENTS(  3,     THEMED_STYLE_SUBTLE,  100 ),
309
    AUTOFORMAT_PATTERN(       9,  9, THEMED_STYLE_SUBTLE,  100, spAutoFormatPattern1 ),
310
    AUTOFORMAT_PATTERN(      10, 10, THEMED_STYLE_SUBTLE,  100, spAutoFormatPattern2 ),
311
    AUTOFORMAT_FADEDACCENTS( 11,     THEMED_STYLE_SUBTLE,  100 ),
312
    AUTOFORMAT_PATTERN(      17, 17, THEMED_STYLE_SUBTLE,  100, spAutoFormatPattern1 ),
313
    AUTOFORMAT_PATTERN(      18, 18, THEMED_STYLE_INTENSE, 100, spAutoFormatPattern2 ),
314
    AUTOFORMAT_FADEDACCENTS( 19,     THEMED_STYLE_SUBTLE,  100 ),
315
    AUTOFORMAT_PATTERN(      25, 25, THEMED_STYLE_SUBTLE,  100, spAutoFormatPattern1 ),
316
    AUTOFORMAT_PATTERN(      26, 26, THEMED_STYLE_INTENSE, 100, spAutoFormatPattern2 ),
317
    AUTOFORMAT_FADEDACCENTS( 27,     THEMED_STYLE_SUBTLE,  100 ),
318
    AUTOFORMAT_PATTERN(      33, 33, THEMED_STYLE_SUBTLE,  100, spAutoFormatPattern1 ),
319
    AUTOFORMAT_PATTERN(      34, 34, THEMED_STYLE_SUBTLE,  100, spAutoFormatPattern2 ),
320
    AUTOFORMAT_FADEDACCENTS( 35,     THEMED_STYLE_SUBTLE,  100 ),
321
    AUTOFORMAT_PATTERN(      41, 42, THEMED_STYLE_SUBTLE,  100, spAutoFormatPattern4 ),
322
    AUTOFORMAT_PATTERN(      42, 42, THEMED_STYLE_INTENSE, 100, spAutoFormatPattern2 ),
323
    AUTOFORMAT_FADEDACCENTS( 43,     THEMED_STYLE_SUBTLE,  100 ),
324
    AUTOFORMAT_END()
325
};
326
327
const AutoFormatEntry spUpDownBarLines[] =
328
{
329
    AUTOFORMAT_COLOR(       1, 16, THEMED_STYLE_SUBTLE, XML_tx1 ),
330
    AUTOFORMAT_INVISIBLE(  17, 32 ),
331
    AUTOFORMAT_COLOR(      33, 34, THEMED_STYLE_SUBTLE, XML_dk1 ),
332
    AUTOFORMAT_ACCENTSMOD( 35,     THEMED_STYLE_SUBTLE, XML_shade, 25000 ),
333
    AUTOFORMAT_INVISIBLE(  41, 48 ),
334
    AUTOFORMAT_END()
335
};
336
337
const AutoFormatEntry spUpBarFills[] =
338
{
339
    AUTOFORMAT_COLORMOD(    1,  1, THEMED_STYLE_SUBTLE,  XML_dk1, XML_tint, 25000 ),
340
    AUTOFORMAT_COLORMOD(    2,  2, THEMED_STYLE_SUBTLE,  XML_dk1, XML_tint,  5000 ),
341
    AUTOFORMAT_ACCENTSMOD(  3,     THEMED_STYLE_SUBTLE,           XML_tint, 25000 ),
342
    AUTOFORMAT_COLORMOD(    9,  9, THEMED_STYLE_SUBTLE,  XML_dk1, XML_tint, 25000 ),
343
    AUTOFORMAT_COLORMOD(   10, 10, THEMED_STYLE_SUBTLE,  XML_dk1, XML_tint,  5000 ),
344
    AUTOFORMAT_ACCENTSMOD( 11,     THEMED_STYLE_SUBTLE,           XML_tint, 25000 ),
345
    AUTOFORMAT_COLORMOD(   17, 17, THEMED_STYLE_INTENSE, XML_dk1, XML_tint, 25000 ),
346
    AUTOFORMAT_COLORMOD(   18, 18, THEMED_STYLE_INTENSE, XML_dk1, XML_tint,  5000 ),
347
    AUTOFORMAT_ACCENTSMOD( 19,     THEMED_STYLE_INTENSE,          XML_tint, 25000 ),
348
    AUTOFORMAT_COLORMOD(   25, 25, THEMED_STYLE_INTENSE, XML_dk1, XML_tint, 25000 ),
349
    AUTOFORMAT_COLORMOD(   26, 26, THEMED_STYLE_INTENSE, XML_dk1, XML_tint,  5000 ),
350
    AUTOFORMAT_ACCENTSMOD( 27,     THEMED_STYLE_INTENSE,          XML_tint, 25000 ),
351
    AUTOFORMAT_COLOR(      33, 40, THEMED_STYLE_SUBTLE,  XML_lt1 ),
352
    AUTOFORMAT_COLORMOD(   41, 41, THEMED_STYLE_INTENSE, XML_dk1, XML_tint, 25000 ),
353
    AUTOFORMAT_COLOR(      42, 42, THEMED_STYLE_INTENSE, XML_lt1 ),
354
    AUTOFORMAT_ACCENTSMOD( 43,     THEMED_STYLE_INTENSE,          XML_tint, 25000 ),
355
    AUTOFORMAT_END()
356
};
357
358
const AutoFormatEntry spDownBarFills[] =
359
{
360
    AUTOFORMAT_COLORMOD(    1,  1, THEMED_STYLE_SUBTLE,  XML_dk1, XML_tint,  85000 ),
361
    AUTOFORMAT_COLORMOD(    2,  2, THEMED_STYLE_SUBTLE,  XML_dk1, XML_tint,  95000 ),
362
    AUTOFORMAT_ACCENTSMOD(  3,     THEMED_STYLE_SUBTLE,           XML_shade, 25000 ),
363
    AUTOFORMAT_COLORMOD(    9,  9, THEMED_STYLE_SUBTLE,  XML_dk1, XML_tint,  85000 ),
364
    AUTOFORMAT_COLORMOD(   10, 10, THEMED_STYLE_SUBTLE,  XML_dk1, XML_tint,  95000 ),
365
    AUTOFORMAT_ACCENTSMOD( 11,     THEMED_STYLE_SUBTLE,           XML_shade, 25000 ),
366
    AUTOFORMAT_COLORMOD(   17, 17, THEMED_STYLE_INTENSE, XML_dk1, XML_tint,  85000 ),
367
    AUTOFORMAT_COLORMOD(   18, 18, THEMED_STYLE_INTENSE, XML_dk1, XML_tint,  95000 ),
368
    AUTOFORMAT_ACCENTSMOD( 19,     THEMED_STYLE_INTENSE,          XML_shade, 25000 ),
369
    AUTOFORMAT_COLORMOD(   25, 25, THEMED_STYLE_INTENSE, XML_dk1, XML_tint,  85000 ),
370
    AUTOFORMAT_COLORMOD(   26, 26, THEMED_STYLE_INTENSE, XML_dk1, XML_tint,  95000 ),
371
    AUTOFORMAT_ACCENTSMOD( 27,     THEMED_STYLE_INTENSE,          XML_shade, 25000 ),
372
    AUTOFORMAT_COLORMOD(   33, 33, THEMED_STYLE_SUBTLE,  XML_dk1, XML_tint,  85000 ),
373
    AUTOFORMAT_COLORMOD(   34, 34, THEMED_STYLE_SUBTLE,  XML_dk1, XML_tint,  95000 ),
374
    AUTOFORMAT_ACCENTSMOD( 35,     THEMED_STYLE_SUBTLE,           XML_shade, 25000 ),
375
    AUTOFORMAT_COLORMOD(   41, 41, THEMED_STYLE_INTENSE, XML_dk1, XML_tint,  85000 ),
376
    AUTOFORMAT_COLOR(      42, 42, THEMED_STYLE_INTENSE, XML_dk1 ),
377
    AUTOFORMAT_ACCENTSMOD( 43,     THEMED_STYLE_INTENSE,          XML_shade, 25000 ),
378
    AUTOFORMAT_END()
379
};
380
381
#undef AUTOFORMAT_COLOR
382
#undef AUTOFORMAT_COLORMOD
383
#undef AUTOFORMAT_ACCENTSMOD
384
#undef AUTOFORMAT_PATTERN
385
#undef AUTOFORMAT_FADED
386
#undef AUTOFORMAT_FADEDACCENTS
387
#undef AUTOFORMAT_INVISIBLE
388
#undef AUTOFORMAT_END
389
390
const AutoFormatEntry* lclGetAutoFormatEntry( const AutoFormatEntry* pEntries, sal_Int32 nStyle )
391
0
{
392
0
    for( ; pEntries && (pEntries->mnFirstStyleIdx >= 0); ++pEntries )
393
0
        if( (pEntries->mnFirstStyleIdx <= nStyle) && (nStyle <= pEntries->mnLastStyleIdx) )
394
0
            return pEntries;
395
0
    return nullptr;
396
0
}
397
398
struct AutoTextEntry
399
{
400
    sal_Int32           mnFirstStyleIdx;    /// First chart style index.
401
    sal_Int32           mnLastStyleIdx;     /// Last chart style index.
402
    sal_Int32           mnThemedFont;       /// Themed font (minor/major).
403
    sal_Int32           mnColorToken;       /// Theme color token.
404
    sal_Int32           mnDefFontSize;      /// Default font size (1/100 points).
405
    sal_Int32           mnRelFontSize;      /// Font size relative to chart global font (percent).
406
    bool                mbBold;             /// True = bold font.
407
};
408
409
#define AUTOTEXT_COLOR( first, last, themed_font, color_token, def_font_size, rel_font_size, bold ) \
410
    { first, last, themed_font, color_token, def_font_size, rel_font_size, bold }
411
412
#define AUTOTEXT_END() \
413
    AUTOTEXT_COLOR( -1, -1, XML_none, XML_TOKEN_INVALID, 1000, 100, false )
414
415
const AutoTextEntry spChartTitleTexts[] =
416
{
417
    AUTOTEXT_COLOR(  1, 40, XML_minor, XML_tx1, 1800, 120, true ),
418
    AUTOTEXT_COLOR( 41, 48, XML_minor, XML_lt1, 1800, 120, true ),
419
    AUTOTEXT_END()
420
};
421
422
const AutoTextEntry spAxisTitleTexts[] =
423
{
424
    AUTOTEXT_COLOR(  1, 40, XML_minor, XML_tx1, 1000, 100, true ),
425
    AUTOTEXT_COLOR( 41, 48, XML_minor, XML_lt1, 1000, 100, true ),
426
    AUTOTEXT_END()
427
};
428
429
const AutoTextEntry spOtherTexts[] =
430
{
431
    AUTOTEXT_COLOR(  1, 40, XML_minor, XML_tx1, 1000, 100, false ),
432
    AUTOTEXT_COLOR( 41, 48, XML_minor, XML_lt1, 1000, 100, false ),
433
    AUTOTEXT_END()
434
};
435
436
#undef AUTOTEXT_COLOR
437
#undef AUTOTEXT_END
438
439
const AutoTextEntry* lclGetAutoTextEntry( const AutoTextEntry* pEntries, sal_Int32 nStyle )
440
0
{
441
0
    for( ; pEntries && (pEntries->mnFirstStyleIdx >= 0); ++pEntries )
442
0
        if( (pEntries->mnFirstStyleIdx <= nStyle) && (nStyle <= pEntries->mnLastStyleIdx) )
443
0
            return pEntries;
444
0
    return nullptr;
445
0
}
446
447
// These PropIds arrays will be indexed into using a ShapeProperty enum
448
449
const ShapePropertyIds spnCommonPropIds =
450
{
451
    PROP_LineStyle, PROP_LineWidth, PROP_LineColor, PROP_LineTransparence, PROP_LineDashName,
452
    PROP_LineCap, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID,
453
    PROP_FillStyle, PROP_FillColor, PROP_FillTransparence, PROP_FillTransparenceGradientName, PROP_FillGradientName,
454
    PROP_FillBitmapName, PROP_FillBitmapMode, PROP_FillBitmapSizeX, PROP_FillBitmapSizeY,
455
    PROP_FillBitmapPositionOffsetX, PROP_FillBitmapPositionOffsetY, PROP_FillBitmapRectanglePoint,
456
    PROP_FillHatchName, PROP_FillBackground,
457
    PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID
458
};
459
460
const ShapePropertyIds spnLinearPropIds =
461
{
462
    PROP_LineStyle, PROP_LineWidth, PROP_Color, PROP_Transparency, PROP_LineDashName,
463
    PROP_LineCap, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID,
464
    PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID,
465
    PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID,
466
    PROP_INVALID, PROP_INVALID, PROP_INVALID,
467
    PROP_INVALID, PROP_INVALID,
468
    PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID
469
};
470
471
const ShapePropertyIds spnFilledPropIds =
472
{
473
    PROP_BorderStyle,
474
    PROP_BorderWidth,
475
    PROP_BorderColor,
476
    PROP_BorderTransparency,
477
    PROP_BorderDashName,
478
    PROP_LineCap,
479
    PROP_INVALID,
480
    PROP_INVALID,
481
    PROP_INVALID,
482
    PROP_INVALID,
483
    PROP_INVALID,
484
    PROP_INVALID,
485
    PROP_INVALID,
486
    PROP_FillStyle,
487
    PROP_Color,
488
    PROP_Transparency,
489
    PROP_FillTransparenceGradientName,
490
    PROP_GradientName,
491
    PROP_FillBitmapName,
492
    PROP_FillBitmapMode,
493
    PROP_FillBitmapSizeX,
494
    PROP_FillBitmapSizeY,
495
    PROP_FillBitmapPositionOffsetX,
496
    PROP_FillBitmapPositionOffsetY,
497
    PROP_FillBitmapRectanglePoint,
498
    PROP_HatchName,
499
    PROP_FillBackground,
500
    PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID
501
};
502
503
/** Property info for common chart objects, to be used in ShapePropertyMap. */
504
const ShapePropertyInfo saCommonPropInfo( spnCommonPropIds, false, true, true, true, true );
505
/** Property info for linear data series, to be used in ShapePropertyMap. */
506
const ShapePropertyInfo saLinearPropInfo( spnLinearPropIds, false, true, true, true, true );
507
/** Property info for filled data series, to be used in ShapePropertyMap. */
508
const ShapePropertyInfo saFilledPropInfo( spnFilledPropIds, false, true, true, true, true );
509
510
/** Contains information about formatting of a specific chart object type. */
511
struct ObjectTypeFormatEntry
512
{
513
    ObjectType          meObjType;          /// Object type for automatic format.
514
    const ShapePropertyInfo& mrPropInfo;    /// Property info for the ShapePropertyMap class.
515
    const AutoFormatEntry* mpAutoLines;     /// Automatic line formatting for all chart styles.
516
    const AutoFormatEntry* mpAutoFills;     /// Automatic fill formatting for all chart styles.
517
    const AutoTextEntry* mpAutoTexts;       /// Automatic text attributes for all chart styles.
518
    bool                mbIsFrame;          /// True = object is a frame, false = object is a line.
519
    ObjectTypeFormatEntry(ObjectType eObjType, const ShapePropertyInfo& rPropInfo,
520
                                 const AutoFormatEntry* pAutoLines,
521
                                 const AutoFormatEntry* pAutoFills,
522
                                 const AutoTextEntry* pAutoTexts,
523
                                 bool bIsFrame)
524
1.35k
        :meObjType(eObjType), mrPropInfo(rPropInfo), mpAutoLines(pAutoLines)
525
1.35k
        ,mpAutoFills(pAutoFills), mpAutoTexts(pAutoTexts), mbIsFrame(bIsFrame)
526
1.35k
    {} // prevent creation of implicit default ctor which fails in MSVC
527
};
528
529
#define TYPEFORMAT_FRAME( obj_type, prop_type, auto_texts, auto_lines, auto_fills ) \
530
    { obj_type, prop_type, auto_lines, auto_fills, auto_texts, true }
531
532
#define TYPEFORMAT_LINE( obj_type, prop_type, auto_texts, auto_lines ) \
533
    { obj_type, prop_type, auto_lines, nullptr,  auto_texts, false }
534
535
const ObjectTypeFormatEntry spObjTypeFormatEntries[] =
536
{
537
    //                object type                property info      auto text          auto line            auto fill
538
    TYPEFORMAT_FRAME( OBJECTTYPE_CHARTSPACE,     saCommonPropInfo, nullptr,                 spNoFormats,         spChartSpaceFill ),
539
    TYPEFORMAT_FRAME( OBJECTTYPE_CHARTTITLE,     saCommonPropInfo, spChartTitleTexts, nullptr /* eq to Ch2 */,   nullptr /* eq to Ch2 */),
540
    TYPEFORMAT_FRAME( OBJECTTYPE_LEGEND,         saCommonPropInfo, spOtherTexts,      spNoFormats,         spNoFormats ),
541
    TYPEFORMAT_FRAME( OBJECTTYPE_PLOTAREA2D,     saCommonPropInfo, nullptr,                 nullptr /* eq to Ch2 */,   spPlotArea2dFills ),
542
    TYPEFORMAT_FRAME( OBJECTTYPE_PLOTAREA3D,     saCommonPropInfo, nullptr,                 nullptr /* eq to Ch2 */,   nullptr /* eq to Ch2 */ ),
543
    TYPEFORMAT_FRAME( OBJECTTYPE_WALL,           saCommonPropInfo, nullptr,                 spWallFloorLines,    spWallFloorFills ),
544
    TYPEFORMAT_FRAME( OBJECTTYPE_FLOOR,          saCommonPropInfo, nullptr,                 spWallFloorLines,    spWallFloorFills ),
545
    TYPEFORMAT_LINE(  OBJECTTYPE_AXIS,           saCommonPropInfo, spOtherTexts,      spAxisLines ),
546
    TYPEFORMAT_FRAME( OBJECTTYPE_AXISTITLE,      saCommonPropInfo, spAxisTitleTexts,  nullptr /* eq to Ch2 */,   nullptr /* eq to Ch2 */ ),
547
    TYPEFORMAT_FRAME( OBJECTTYPE_AXISUNIT,       saCommonPropInfo, spAxisTitleTexts,  nullptr /* eq in Ch2 */,   nullptr /* eq in Ch2 */ ),
548
    TYPEFORMAT_LINE(  OBJECTTYPE_MAJORGRIDLINE,  saCommonPropInfo, nullptr,                 spMajorGridLines ),
549
    TYPEFORMAT_LINE(  OBJECTTYPE_MINORGRIDLINE,  saCommonPropInfo, nullptr,                 spMinorGridLines ),
550
    TYPEFORMAT_LINE(  OBJECTTYPE_LINEARSERIES2D, saLinearPropInfo, nullptr,                 spLinearSeriesLines ),
551
    TYPEFORMAT_FRAME( OBJECTTYPE_FILLEDSERIES2D, saFilledPropInfo, nullptr,                 spFilledSeriesLines, spFilledSeries2dFills ),
552
    TYPEFORMAT_FRAME( OBJECTTYPE_FILLEDSERIES3D, saFilledPropInfo, nullptr,                 spFilledSeriesLines, spFilledSeries3dFills ),
553
    TYPEFORMAT_FRAME( OBJECTTYPE_DATALABEL,      saCommonPropInfo, spOtherTexts,      nullptr /* eq to Ch2 */,   nullptr /* eq to Ch2 */ ),
554
    TYPEFORMAT_LINE(  OBJECTTYPE_TRENDLINE,      saCommonPropInfo, nullptr,                 spOtherLines ),
555
    TYPEFORMAT_FRAME( OBJECTTYPE_TRENDLINELABEL, saCommonPropInfo, spOtherTexts,      nullptr /* eq to Ch2 */,   nullptr /* eq to Ch2 */ ),
556
    TYPEFORMAT_LINE(  OBJECTTYPE_ERRORBAR,       saCommonPropInfo, nullptr,                 spOtherLines ),
557
    TYPEFORMAT_LINE(  OBJECTTYPE_SERLINE,        saCommonPropInfo, nullptr,                 spOtherLines ),
558
    TYPEFORMAT_LINE(  OBJECTTYPE_LEADERLINE,     saCommonPropInfo, nullptr,                 spOtherLines ),
559
    TYPEFORMAT_LINE(  OBJECTTYPE_DROPLINE,       saCommonPropInfo, nullptr,                 spOtherLines ),
560
    TYPEFORMAT_LINE(  OBJECTTYPE_HILOLINE,       saLinearPropInfo, nullptr,                 spOtherLines ),
561
    TYPEFORMAT_FRAME( OBJECTTYPE_UPBAR,          saCommonPropInfo, nullptr,                 spUpDownBarLines,    spUpBarFills ),
562
    TYPEFORMAT_FRAME( OBJECTTYPE_DOWNBAR,        saCommonPropInfo, nullptr,                 spUpDownBarLines,    spDownBarFills ),
563
    TYPEFORMAT_FRAME( OBJECTTYPE_DATATABLE,      saCommonPropInfo, spOtherTexts,      spDataTableLines, nullptr )
564
};
565
566
#undef TYPEFORMAT_FRAME
567
#undef TYPEFORMAT_LINE
568
569
void lclConvertPictureOptions( FillProperties& orFillProps, const PictureOptionsModel& rPicOptions )
570
0
{
571
0
    bool bStacked = (rPicOptions.mnPictureFormat == XML_stack) || (rPicOptions.mnPictureFormat == XML_stackScale);
572
0
    orFillProps.maBlipProps.moBitmapMode = bStacked ? XML_tile : XML_stretch;
573
0
}
574
575
} // namespace
576
577
struct ObjectFormatterData;
578
579
namespace {
580
581
class DetailFormatterBase
582
{
583
public:
584
    explicit            DetailFormatterBase(
585
                            ObjectFormatterData& rData,
586
                            const AutoFormatEntry* pAutoFormatEntry );
587
    explicit            DetailFormatterBase(
588
                            ObjectFormatterData& rData,
589
                            const AutoTextEntry* pAutoTextEntry );
590
591
protected:
592
    /** Returns the placeholder color which may depend on the passed series index. */
593
    ::Color         getPhColor( sal_Int32 nSeriesIdx ) const;
594
595
private:
596
    /** Resolves and returns the scheme color with the passed transformation. */
597
    ::Color         getSchemeColor( sal_Int32 nColorToken, sal_Int32 nModToken, sal_Int32 nModValue ) const;
598
599
protected:
600
    typedef ::std::vector< ::Color > ColorPatternVec;
601
602
    ObjectFormatterData& mrData;            /// Shared formatter data.
603
    ::Color             mnPhClr;            /// RGB placeholder color for themed style.
604
    ColorPatternVec     maColorPattern;     /// Different cycling colors for data series.
605
};
606
607
class LineFormatter : public DetailFormatterBase
608
{
609
public:
610
    explicit            LineFormatter(
611
                            ObjectFormatterData& rData,
612
                            const AutoFormatEntry* pAutoFormatEntry,
613
                            const ObjectType eObjType );
614
615
    /** Converts line formatting to the passed property set. */
616
    void                convertFormatting(
617
                            ShapePropertyMap& rPropMap,
618
                            const ModelRef< Shape >& rxShapeProp,
619
                            sal_Int32 nSeriesIdx );
620
621
private:
622
    LinePropertiesPtr   mxAutoLine;         /// Automatic line properties.
623
};
624
625
class FillFormatter : public DetailFormatterBase
626
{
627
public:
628
    explicit            FillFormatter(
629
                            ObjectFormatterData& rData,
630
                            const AutoFormatEntry* pAutoFormatEntry,
631
                            const ObjectType eObjType );
632
633
    /** Converts area formatting to the passed property set. */
634
    void                convertFormatting(
635
                            ShapePropertyMap& rPropMap,
636
                            const ModelRef< Shape >& rxShapeProp,
637
                            const PictureOptionsModel* pPicOptions,
638
                            sal_Int32 nSeriesIdx );
639
640
    void                setAutoFill(sal_Int32 nAutoFill);
641
642
private:
643
    FillPropertiesPtr   mxAutoFill;         /// Automatic fill properties.
644
};
645
646
class TextFormatter : public DetailFormatterBase
647
{
648
public:
649
    explicit            TextFormatter(
650
                            ObjectFormatterData& rData,
651
                            const AutoTextEntry* pAutoTextEntry,
652
                            const ModelRef< TextBody >& rxGlobalTextProp );
653
654
    /** Converts text formatting to the passed property set. */
655
    void                convertFormatting(
656
                            PropertySet& rPropSet,
657
                            const TextCharacterProperties* pTextProps );
658
    /** Converts text formatting to the passed property set. */
659
    void                convertFormatting(
660
                            PropertySet& rPropSet,
661
                            const ModelRef< TextBody >& rxTextProp );
662
663
private:
664
    TextCharacterPropertiesPtr mxAutoText;  /// Automatic text properties.
665
};
666
667
/** Formatter for a specific object type. */
668
class ObjectTypeFormatter
669
{
670
public:
671
    explicit            ObjectTypeFormatter(
672
                            ObjectFormatterData& rData,
673
                            const ObjectTypeFormatEntry& rEntry,
674
                            const ChartSpaceModel& rChartSpace,
675
                            const ObjectType eObjType );
676
677
    /** Sets frame formatting properties to the passed property set. */
678
    void                convertFrameFormatting(
679
                            PropertySet& rPropSet,
680
                            const ModelRef< Shape >& rxShapeProp,
681
                            const PictureOptionsModel* pPicOptions,
682
                            sal_Int32 nSeriesIdx );
683
684
    /** Sets text formatting properties to the passed property set. */
685
    void                convertTextFormatting(
686
                            PropertySet& rPropSet,
687
                            const ModelRef< TextBody >& rxTextProp );
688
689
    /** Sets frame/text formatting properties to the passed property set. */
690
    void                convertFormatting(
691
                            PropertySet& rPropSet,
692
                            const ModelRef< Shape >& rxShapeProp,
693
                            const ModelRef< TextBody >& rxTextProp );
694
695
    /** Sets text formatting properties to the passed property set. */
696
    void                convertTextFormatting(
697
                            PropertySet& rPropSet,
698
                            const TextCharacterProperties& rTextProps );
699
700
    /** Sets automatic fill properties to the passed property set. */
701
    void                convertAutomaticFill(
702
                            PropertySet& rPropSet,
703
                            sal_Int32 nSeriesIdx );
704
705
private:
706
    LineFormatter       maLineFormatter;    /// Converter for line formatting.
707
    FillFormatter       maFillFormatter;    /// Converter for fill formatting.
708
    TextFormatter       maTextFormatter;    /// Converter for text formatting.
709
    ModelObjectHelper&  mrModelObjHelper;   /// Helper for named drawing formatting.
710
    const ObjectTypeFormatEntry& mrEntry;   /// Additional settings.
711
};
712
713
}
714
715
struct ObjectFormatterData
716
{
717
    typedef RefMap< ObjectType, ObjectTypeFormatter > ObjectTypeFormatterMap;
718
719
    const XmlFilterBase& mrFilter;              /// Base filter object.
720
    ObjectTypeFormatterMap maTypeFormatters;    /// Formatters for all types of objects in a chart.
721
    ModelObjectHelper   maModelObjHelper;       /// Helper for named drawing formatting (dashes, gradients, bitmaps).
722
    Reference< XNumberFormats > mxNumFmts;      /// Number formats collection of container document.
723
    Reference< XNumberFormatTypes > mxNumTypes; /// Number format types collection of container document.
724
    Locale              maEnUsLocale;           /// Locale struct containing en-US.
725
    Locale              maFromLocale;           /// Empty locale struct.
726
    sal_Int32           mnMaxSeriesIdx;         /// Maximum series index used for color cycling/fading.
727
728
    explicit            ObjectFormatterData(
729
                            const XmlFilterBase& rFilter,
730
                            const Reference< XChartDocument >& rxChartDoc,
731
                            const ChartSpaceModel& rChartSpace );
732
733
    ObjectTypeFormatter* getTypeFormatter( ObjectType eObjType );
734
};
735
736
DetailFormatterBase::DetailFormatterBase( ObjectFormatterData& rData, const AutoFormatEntry* pAutoFormatEntry ) :
737
0
    mrData( rData ),
738
0
    mnPhClr( ColorTransparency, 0xffffffff )
739
0
{
740
0
    if( !pAutoFormatEntry )
741
0
        return;
742
743
0
    if( pAutoFormatEntry->mpPattern )
744
0
    {
745
        // prepare multi-color pattern
746
0
        for( const AutoFormatPatternEntry* pPatternEntry = pAutoFormatEntry->mpPattern; pPatternEntry->mnColorToken != XML_TOKEN_INVALID; ++pPatternEntry )
747
0
            maColorPattern.push_back( getSchemeColor( pPatternEntry->mnColorToken, pPatternEntry->mnModToken, pPatternEntry->mnModValue ) );
748
0
    }
749
0
    else if( pAutoFormatEntry->mnColorToken != XML_TOKEN_INVALID )
750
0
    {
751
        // prepare color or single-color pattern (color fading)
752
0
        mnPhClr = getSchemeColor( pAutoFormatEntry->mnColorToken, pAutoFormatEntry->mnModToken, pAutoFormatEntry->mnModValue );
753
0
        if( pAutoFormatEntry->mbFadedColor )
754
0
            maColorPattern.push_back( mnPhClr );
755
0
    }
756
0
}
757
758
DetailFormatterBase::DetailFormatterBase( ObjectFormatterData& rData, const AutoTextEntry* pAutoTextEntry ) :
759
0
    mrData( rData ),
760
0
    mnPhClr( ColorTransparency, 0xffffffff )
761
0
{
762
0
    if( pAutoTextEntry && (pAutoTextEntry->mnColorToken != XML_TOKEN_INVALID) )
763
0
        mnPhClr = getSchemeColor( pAutoTextEntry->mnColorToken, XML_TOKEN_INVALID, 0 );
764
0
}
765
766
::Color DetailFormatterBase::getPhColor( sal_Int32 nSeriesIdx ) const
767
0
{
768
0
    if( maColorPattern.empty() || (mrData.mnMaxSeriesIdx < 0) || (nSeriesIdx < 0) )
769
0
        return mnPhClr;
770
771
    /*  Apply tint/shade depending on the cycle index. The colors of leading
772
        series are darkened (color shade), the colors of trailing series are
773
        lightened (color tint). Shade/tint is applied in an exclusive range of
774
        -70% to 70%.
775
776
        Example 1: 3 data series using single-color shading with accent color 1
777
        (e.g. automatic chart style #3). Shade/tint is applied per series.
778
        Shade/tint changes in steps of 140%/(<series_count+1) = 140%/4 = 35%,
779
        starting at -70%:
780
            Step 1: -70% -> Not used.
781
            Step 2: -35% -> Series 1 has 35% shade of accent color 1.
782
            Step 3:   0% -> Series 2 has pure accent color 1.
783
            Step 4:  35% -> Series 3 has 35% tint of accent color 1.
784
            Step 5:  70% -> Not used.
785
786
        Example 2: 20 data series using accent color pattern (e.g. automatic
787
        chart style #2). Each color cycle has a size of 6 series (accent colors
788
        1 to 6). Shade/tint is applied per color cycle.
789
            Cycle #1: Series 1...6 are based on accent colors 1 to 6.
790
            Cycle #2: Series 7...12 are based on accent colors 1 to 6.
791
            Cycle #3: Series 13...18 are based on accent colors 1 to 6.
792
            Cycle #4: Series 19...20 are based on accent colors 1 to 2.
793
        Shade/tint changes in steps of 140%/(cycle_count+1) = 140%/5 = 28%,
794
        starting at -70%:
795
            Step 1: -70% -> Not used.
796
            Step 2: -42% -> Cycle #1 has 42% shade of accent colors 1...6
797
            step 3: -14% -> Cycle #2 has 14% shade of accent colors 1...6
798
            step 4:  14% -> Cycle #3 has 14% tint of accent colors 1...6
799
            step 5:  42% -> Cycle #4 has 42% tint of accent colors 1...6
800
            step 6:  70% -> Not used.
801
     */
802
0
    ::Color nPhClr = maColorPattern[ static_cast< size_t >( nSeriesIdx % maColorPattern.size() ) ];
803
0
    size_t nCycleIdx = static_cast< size_t >( nSeriesIdx / maColorPattern.size() );
804
0
    size_t nMaxCycleIdx = static_cast< size_t >( mrData.mnMaxSeriesIdx / maColorPattern.size() );
805
0
    double fShadeTint = static_cast< double >( nCycleIdx + 1 ) / (nMaxCycleIdx + 2) * 1.4 - 0.7;
806
0
    if( fShadeTint != 0.0 )
807
0
    {
808
0
        Color aColor;
809
0
        aColor.setSrgbClr( nPhClr );
810
0
        aColor.addChartTintTransformation( fShadeTint );
811
0
        nPhClr = aColor.getColor( mrData.mrFilter.getGraphicHelper() );
812
0
    }
813
814
0
    return nPhClr;
815
0
}
816
817
::Color DetailFormatterBase::getSchemeColor( sal_Int32 nColorToken, sal_Int32 nModToken, sal_Int32 nModValue ) const
818
0
{
819
0
    Color aColor;
820
0
    aColor.setSchemeClr( nColorToken );
821
0
    if( nModToken != XML_TOKEN_INVALID )
822
0
        aColor.addTransformation( nModToken, nModValue );
823
0
    return aColor.getColor( mrData.mrFilter.getGraphicHelper() );
824
0
}
825
826
LineFormatter::LineFormatter( ObjectFormatterData& rData, const AutoFormatEntry* pAutoFormatEntry, const ObjectType eObjType ) :
827
0
   DetailFormatterBase(rData, pAutoFormatEntry)
828
0
{
829
0
    if( !pAutoFormatEntry )
830
0
        return;
831
832
0
    mxAutoLine = std::make_shared<LineProperties>();
833
0
    mxAutoLine->maLineFill.moFillType = XML_noFill;
834
0
    if( const Theme* pTheme = mrData.mrFilter.getCurrentTheme() )
835
0
        if( const LineProperties* pLineProps = pTheme->getLineStyle( pAutoFormatEntry->mnThemedIdx ) )
836
0
            *mxAutoLine = *pLineProps;
837
    // set automatic border property for chartarea, because of tdf#81437 and tdf#82217, except for Impress (tdf#150176)
838
0
    if ( eObjType == OBJECTTYPE_CHARTSPACE )
839
0
    {
840
0
        OUString aFilterName;
841
0
        rData.mrFilter.getMediaDescriptor()[utl::MediaDescriptor::PROP_FILTERNAME] >>= aFilterName;
842
0
        if (!aFilterName.startsWithIgnoreAsciiCase("Impress"))
843
0
        {
844
0
            mxAutoLine->maLineFill.moFillType = oox::GraphicHelper::getDefaultChartAreaLineStyle();
845
0
            mxAutoLine->moLineWidth = oox::GraphicHelper::getDefaultChartAreaLineWidth();
846
            // this value is what MSO 2016 use as a default color for chartspace border
847
0
            mxAutoLine->maLineFill.maFillColor.setSrgbClr(0xD9D9D9);
848
0
        }
849
0
    }
850
    // change line width according to chart auto style
851
0
    if( mxAutoLine->moLineWidth.has_value() )
852
0
        mxAutoLine->moLineWidth = mxAutoLine->moLineWidth.value() * pAutoFormatEntry->mnRelLineWidth / 100;
853
0
}
854
855
void LineFormatter::convertFormatting( ShapePropertyMap& rPropMap, const ModelRef< Shape >& rxShapeProp, sal_Int32 nSeriesIdx )
856
0
{
857
0
    LineProperties aLineProps;
858
0
    if( mxAutoLine )
859
0
        aLineProps.assignUsed( *mxAutoLine );
860
0
    if( rxShapeProp.is() )
861
0
        aLineProps.assignUsed( rxShapeProp->getLineProperties() );
862
0
    aLineProps.pushToPropMap( rPropMap, mrData.mrFilter.getGraphicHelper(), getPhColor( nSeriesIdx ) );
863
0
}
864
865
FillFormatter::FillFormatter( ObjectFormatterData& rData, const AutoFormatEntry* pAutoFormatEntry, const ObjectType eObjType ) :
866
0
    DetailFormatterBase( rData, pAutoFormatEntry )
867
0
{
868
0
    if( !pAutoFormatEntry )
869
0
        return;
870
871
0
    mxAutoFill = std::make_shared<FillProperties>();
872
0
    if( eObjType != OBJECTTYPE_CHARTSPACE )
873
0
        mxAutoFill->moFillType = XML_noFill;
874
0
    if( const Theme* pTheme = mrData.mrFilter.getCurrentTheme() )
875
0
        if( const FillProperties* pFillProps = pTheme->getFillStyle( pAutoFormatEntry->mnThemedIdx ) )
876
0
            *mxAutoFill = *pFillProps;
877
0
}
878
879
void FillFormatter::convertFormatting( ShapePropertyMap& rPropMap, const ModelRef< Shape >& rxShapeProp, const PictureOptionsModel* pPicOptions, sal_Int32 nSeriesIdx )
880
0
{
881
0
    FillProperties aFillProps;
882
0
    if( mxAutoFill )
883
0
        aFillProps.assignUsed( *mxAutoFill );
884
0
    if (rxShapeProp)
885
0
        aFillProps.assignUsed( rxShapeProp->getFillProperties() );
886
0
    if( pPicOptions )
887
0
        lclConvertPictureOptions( aFillProps, *pPicOptions );
888
0
    aFillProps.pushToPropMap( rPropMap, mrData.mrFilter.getGraphicHelper(), 0, getPhColor( nSeriesIdx ) );
889
0
}
890
891
void FillFormatter::setAutoFill(sal_Int32 nFillStyle)
892
0
{
893
0
    mxAutoFill->moFillType = nFillStyle;
894
0
}
895
896
namespace {
897
898
const TextCharacterProperties* lclGetTextProperties( const ModelRef< TextBody >& rxTextProp )
899
0
{
900
0
    return (rxTextProp.is() && !rxTextProp->getParagraphs().empty()) ?
901
0
        &rxTextProp->getParagraphs().front()->getProperties().getTextCharacterProperties() : nullptr;
902
0
}
903
904
} // namespace
905
906
TextFormatter::TextFormatter( ObjectFormatterData& rData, const AutoTextEntry* pAutoTextEntry, const ModelRef< TextBody >& rxGlobalTextProp ) :
907
0
    DetailFormatterBase( rData, pAutoTextEntry )
908
0
{
909
0
    if( !pAutoTextEntry )
910
0
        return;
911
912
0
    mxAutoText = std::make_shared<TextCharacterProperties>();
913
0
    if( const Theme* pTheme = mrData.mrFilter.getCurrentTheme() )
914
0
        if( const TextCharacterProperties* pTextProps = pTheme->getFontStyle( pAutoTextEntry->mnThemedFont ) )
915
0
            *mxAutoText = *pTextProps;
916
0
    ::Color nTextColor = getPhColor( -1 );
917
0
    if( sal_Int32(nTextColor) >= 0 ) {
918
0
        mxAutoText->maFillProperties.maFillColor.setSrgbClr( nTextColor );
919
0
        mxAutoText->maFillProperties.moFillType = XML_solidFill;
920
0
    }
921
0
    mxAutoText->moHeight = pAutoTextEntry->mnDefFontSize;
922
0
    mxAutoText->moBold = pAutoTextEntry->mbBold;
923
924
0
    if( const TextCharacterProperties* pTextProps = lclGetTextProperties( rxGlobalTextProp ) )
925
0
    {
926
0
        mxAutoText->assignUsed( *pTextProps );
927
0
        if( pTextProps->moHeight.has_value() )
928
0
            mxAutoText->moHeight = pTextProps->moHeight.value() * pAutoTextEntry->mnRelFontSize / 100;
929
0
    }
930
0
}
931
932
void TextFormatter::convertFormatting( PropertySet& rPropSet, const TextCharacterProperties* pTextProps )
933
0
{
934
0
    TextCharacterProperties aTextProps;
935
0
    if( mxAutoText )
936
0
        aTextProps.assignUsed( *mxAutoText );
937
0
    if( pTextProps )
938
0
        aTextProps.assignUsed( *pTextProps );
939
0
    aTextProps.pushToPropSet( rPropSet, mrData.mrFilter );
940
0
}
941
942
void TextFormatter::convertFormatting( PropertySet& rPropSet, const ModelRef< TextBody >& rxTextProp )
943
0
{
944
0
    convertFormatting( rPropSet, lclGetTextProperties( rxTextProp ) );
945
0
}
946
947
ObjectTypeFormatter::ObjectTypeFormatter( ObjectFormatterData& rData, const ObjectTypeFormatEntry& rEntry, const ChartSpaceModel& rChartSpace, const ObjectType eObjType ) :
948
0
    maLineFormatter(   rData, lclGetAutoFormatEntry( rEntry.mpAutoLines,   rChartSpace.mnStyle ), eObjType ),
949
0
    maFillFormatter(   rData, lclGetAutoFormatEntry( rEntry.mpAutoFills,   rChartSpace.mnStyle ), eObjType ),
950
0
    maTextFormatter(   rData, lclGetAutoTextEntry(   rEntry.mpAutoTexts,   rChartSpace.mnStyle ), rChartSpace.mxTextProp ),
951
0
    mrModelObjHelper( rData.maModelObjHelper ),
952
0
    mrEntry( rEntry )
953
0
{
954
    // this seems to be an undocumented quirk in the OOXML spec. Only for pptx files the first 32 theme entries
955
    // force a transparent background
956
0
    if (rChartSpace.mnStyle <= 32 && (eObjType == OBJECTTYPE_CHARTSPACE || eObjType == OBJECTTYPE_PLOTAREA2D))
957
0
    {
958
0
        maFillFormatter.setAutoFill(rData.mrFilter.getGraphicHelper().getDefaultChartAreaFillStyle());
959
0
    }
960
0
}
961
962
void ObjectTypeFormatter::convertFrameFormatting( PropertySet& rPropSet, const ModelRef< Shape >& rxShapeProp, const PictureOptionsModel* pPicOptions, sal_Int32 nSeriesIdx )
963
0
{
964
0
    ShapePropertyMap aPropMap( mrModelObjHelper, mrEntry.mrPropInfo );
965
0
    maLineFormatter.convertFormatting( aPropMap, rxShapeProp, nSeriesIdx );
966
0
    if( mrEntry.mbIsFrame )
967
0
        maFillFormatter.convertFormatting( aPropMap, rxShapeProp, pPicOptions, nSeriesIdx );
968
0
    rPropSet.setProperties( aPropMap );
969
0
}
970
971
void ObjectTypeFormatter::convertTextFormatting( PropertySet& rPropSet, const ModelRef< TextBody >& rxTextProp )
972
0
{
973
0
    maTextFormatter.convertFormatting( rPropSet, rxTextProp );
974
0
}
975
976
void ObjectTypeFormatter::convertFormatting( PropertySet& rPropSet, const ModelRef< Shape >& rxShapeProp, const ModelRef< TextBody >& rxTextProp )
977
0
{
978
0
    convertFrameFormatting( rPropSet, rxShapeProp, nullptr, -1 );
979
0
    convertTextFormatting( rPropSet, rxTextProp );
980
0
}
981
982
void ObjectTypeFormatter::convertTextFormatting( PropertySet& rPropSet, const TextCharacterProperties& rTextProps )
983
0
{
984
0
    maTextFormatter.convertFormatting( rPropSet, &rTextProps );
985
0
}
986
987
void ObjectTypeFormatter::convertAutomaticFill( PropertySet& rPropSet, sal_Int32 nSeriesIdx )
988
0
{
989
0
    ShapePropertyMap aPropMap( mrModelObjHelper, mrEntry.mrPropInfo );
990
0
    ModelRef< Shape > xShapeProp;
991
0
    maFillFormatter.convertFormatting( aPropMap, xShapeProp, nullptr, nSeriesIdx );
992
0
    rPropSet.setProperties( aPropMap );
993
0
}
994
995
ObjectFormatterData::ObjectFormatterData( const XmlFilterBase& rFilter, const Reference< XChartDocument >& rxChartDoc, const ChartSpaceModel& rChartSpace ) :
996
0
    mrFilter( rFilter ),
997
0
    maModelObjHelper( Reference< XMultiServiceFactory >( rxChartDoc, UNO_QUERY ) ),
998
0
    maEnUsLocale( u"en"_ustr, u"US"_ustr, OUString() ),
999
0
    mnMaxSeriesIdx( -1 )
1000
0
{
1001
0
    for(auto const &rEntry : spObjTypeFormatEntries)
1002
0
        maTypeFormatters[ rEntry.meObjType ] = std::make_shared<ObjectTypeFormatter>( *this, rEntry, rChartSpace, rEntry.meObjType );
1003
1004
0
    try
1005
0
    {
1006
0
        Reference< XNumberFormatsSupplier > xNumFmtsSupp( rxChartDoc, UNO_QUERY_THROW );
1007
0
        mxNumFmts = xNumFmtsSupp->getNumberFormats();
1008
0
        mxNumTypes.set( mxNumFmts, UNO_QUERY );
1009
0
    }
1010
0
    catch( Exception& )
1011
0
    {
1012
0
    }
1013
0
    OSL_ENSURE( mxNumFmts.is() && mxNumTypes.is(), "ObjectFormatterData::ObjectFormatterData - cannot get number formats" );
1014
0
}
1015
1016
ObjectTypeFormatter* ObjectFormatterData::getTypeFormatter( ObjectType eObjType )
1017
0
{
1018
0
    OSL_ENSURE( maTypeFormatters.has( eObjType ), "ObjectFormatterData::getTypeFormatter - unknown object type" );
1019
0
    return maTypeFormatters.get( eObjType ).get();
1020
0
}
1021
1022
ObjectFormatter::ObjectFormatter( const XmlFilterBase& rFilter, const Reference< XChartDocument >& rxChartDoc, const ChartSpaceModel& rChartSpace ) :
1023
0
    mxData( std::make_shared<ObjectFormatterData>( rFilter, rxChartDoc, rChartSpace ) )
1024
0
{
1025
0
}
1026
1027
ObjectFormatter::~ObjectFormatter()
1028
0
{
1029
0
}
1030
1031
void ObjectFormatter::setMaxSeriesIndex( sal_Int32 nMaxSeriesIdx )
1032
0
{
1033
0
    mxData->mnMaxSeriesIdx = nMaxSeriesIdx;
1034
0
}
1035
1036
sal_Int32 ObjectFormatter::getMaxSeriesIndex() const
1037
0
{
1038
0
    return mxData->mnMaxSeriesIdx;
1039
0
}
1040
1041
void ObjectFormatter::convertFrameFormatting( PropertySet& rPropSet, const ModelRef< Shape >& rxShapeProp, ObjectType eObjType, sal_Int32 nSeriesIdx )
1042
0
{
1043
0
    if( ObjectTypeFormatter* pFormat = mxData->getTypeFormatter( eObjType ) )
1044
0
        pFormat->convertFrameFormatting( rPropSet, rxShapeProp, nullptr, nSeriesIdx );
1045
0
}
1046
1047
void ObjectFormatter::convertFrameFormatting( PropertySet& rPropSet, const ModelRef< Shape >& rxShapeProp, const PictureOptionsModel& rPicOptions, ObjectType eObjType, sal_Int32 nSeriesIdx )
1048
0
{
1049
0
    if( ObjectTypeFormatter* pFormat = mxData->getTypeFormatter( eObjType ) )
1050
0
        pFormat->convertFrameFormatting( rPropSet, rxShapeProp, &rPicOptions, nSeriesIdx );
1051
0
}
1052
1053
void ObjectFormatter::convertTextFormatting( PropertySet& rPropSet, const ModelRef< TextBody >& rxTextProp, ObjectType eObjType )
1054
0
{
1055
0
    if( ObjectTypeFormatter* pFormat = mxData->getTypeFormatter( eObjType ) )
1056
0
        pFormat->convertTextFormatting( rPropSet, rxTextProp );
1057
0
}
1058
1059
void ObjectFormatter::convertFormatting( PropertySet& rPropSet, const ModelRef< Shape >& rxShapeProp, const ModelRef< TextBody >& rxTextProp, ObjectType eObjType )
1060
0
{
1061
0
    if( ObjectTypeFormatter* pFormat = mxData->getTypeFormatter( eObjType ) )
1062
0
        pFormat->convertFormatting( rPropSet, rxShapeProp, rxTextProp );
1063
0
}
1064
1065
void ObjectFormatter::convertTextFormatting( PropertySet& rPropSet, const TextCharacterProperties& rTextProps, ObjectType eObjType )
1066
0
{
1067
0
    if( ObjectTypeFormatter* pFormat = mxData->getTypeFormatter( eObjType ) )
1068
0
        pFormat->convertTextFormatting( rPropSet, rTextProps );
1069
0
}
1070
1071
void ObjectFormatter::convertTextRotation( PropertySet& rPropSet, const ModelRef< TextBody >& rxTextProp, bool bSupportsStacked, sal_Int32 nDefaultRotation )
1072
0
{
1073
0
    if( !rxTextProp.is() )
1074
0
        return;
1075
1076
0
    bool bStacked = false;
1077
0
    if( bSupportsStacked )
1078
0
    {
1079
0
        sal_Int32 nVert = rxTextProp->getTextProperties().moVert.value_or( XML_horz );
1080
0
        bStacked = (nVert == XML_wordArtVert) || (nVert == XML_wordArtVertRtl);
1081
0
        rPropSet.setProperty( PROP_StackCharacters, bStacked );
1082
0
    }
1083
1084
    /*  Chart2 expects rotation angle as double value in range of [0,360).
1085
        OOXML counts clockwise, Chart2 counts counterclockwise. */
1086
0
    double fAngle = static_cast< double >( bStacked ? 0 : rxTextProp->getTextProperties().moTextAreaRotation.value_or( nDefaultRotation ) );
1087
    // MS Office UI allows values only in range of [-90,90].
1088
0
    if ( fAngle < -5400000.0 || fAngle > 5400000.0 )
1089
0
    {
1090
0
        fAngle = 0.0;
1091
0
    }
1092
0
    fAngle = getDoubleIntervalValue< double >( -fAngle / 60000.0, 0.0, 360.0 );
1093
0
    rPropSet.setProperty( PROP_TextRotation, fAngle );
1094
0
}
1095
1096
void ObjectFormatter::convertTextWrap( PropertySet& rPropSet, const ModelRef< TextBody >& rxTextProp )
1097
0
{
1098
0
    if( !rxTextProp.is() )
1099
0
    {
1100
        // set default value (in OOXML the default value is true)
1101
0
        rPropSet.setProperty( PROP_TextWordWrap, true );
1102
0
        return;
1103
0
    }
1104
1105
0
    PropertyMap& aPropMap = rxTextProp->getTextProperties().maPropertyMap;
1106
0
    if( aPropMap.hasProperty(PROP_TextWordWrap) )
1107
0
    {
1108
0
        Any aValue = aPropMap.getProperty( PROP_TextWordWrap );
1109
0
        if( aValue.hasValue() )
1110
0
        {
1111
0
            bool bValue = false;
1112
0
            aValue >>= bValue;
1113
0
            rPropSet.setProperty( PROP_TextWordWrap, bValue );
1114
0
        }
1115
0
    }
1116
0
}
1117
1118
void ObjectFormatter::convertNumberFormat( PropertySet& rPropSet, const NumberFormat& rNumberFormat, bool bAxis, bool bShowPercent )
1119
0
{
1120
0
    if( !mxData->mxNumFmts.is() )
1121
0
        return;
1122
1123
0
    const bool bGeneral = rNumberFormat.maFormatCode.equalsIgnoreAsciiCase("general");
1124
0
    const bool bPercent = !bAxis && bShowPercent && !rNumberFormat.mbSourceLinked;
1125
0
    sal_Int32 nPropId = bPercent ? PROP_PercentageNumberFormat : PROP_NumberFormat;
1126
0
    OUString sFormatCode(rNumberFormat.maFormatCode);
1127
0
    if (bPercent && bGeneral)
1128
0
        sFormatCode = "0%";
1129
0
    try
1130
0
    {
1131
0
        sal_Int32 nIndex = bGeneral && !bPercent ?
1132
0
            mxData->mxNumTypes->getStandardIndex( mxData->maFromLocale ) :
1133
0
            mxData->mxNumFmts->addNewConverted( sFormatCode, mxData->maEnUsLocale, mxData->maFromLocale );
1134
0
        if( nIndex >= 0 )
1135
0
            rPropSet.setProperty( nPropId, nIndex );
1136
0
    }
1137
0
    catch( Exception& )
1138
0
    {
1139
0
        OSL_FAIL( OStringBuffer( "ObjectFormatter::convertNumberFormat - cannot create number format '" +
1140
0
                OUStringToOString( rNumberFormat.maFormatCode, osl_getThreadTextEncoding() )  + "'" ).getStr() );
1141
0
    }
1142
1143
    // Setting "LinkNumberFormatToSource" does not really work, at least not for axis :-/
1144
0
    if (!bAxis)
1145
0
        rPropSet.setProperty(PROP_LinkNumberFormatToSource, Any(rNumberFormat.mbSourceLinked));
1146
0
    else
1147
0
        rPropSet.setProperty(PROP_LinkNumberFormatToSource, Any(rNumberFormat.maFormatCode.isEmpty()));
1148
0
}
1149
1150
void ObjectFormatter::convertAutomaticFill( PropertySet& rPropSet, ObjectType eObjType, sal_Int32 nSeriesIdx )
1151
0
{
1152
0
    if( ObjectTypeFormatter* pFormat = mxData->getTypeFormatter( eObjType ) )
1153
0
        pFormat->convertAutomaticFill( rPropSet, nSeriesIdx );
1154
0
}
1155
1156
bool ObjectFormatter::isAutomaticFill( const ModelRef< Shape >& rxShapeProp )
1157
0
{
1158
0
    return !rxShapeProp || !rxShapeProp->getFillProperties().moFillType.has_value();
1159
0
}
1160
1161
sal_Int32 ObjectFormatter::getNumberFormatKey(const OUString& sNumberFormat)
1162
0
{
1163
0
    if (!mxData->mxNumFmts.is() || sNumberFormat.isEmpty())
1164
0
        return -1;
1165
1166
0
    sal_Int32 nIndex = -1;
1167
0
    try
1168
0
    {
1169
0
        const bool bGeneral = sNumberFormat.equalsIgnoreAsciiCase("general");
1170
0
        nIndex = bGeneral ? mxData->mxNumTypes->getStandardIndex(mxData->maFromLocale)
1171
0
                          : mxData->mxNumFmts->addNewConverted(sNumberFormat, mxData->maEnUsLocale,
1172
0
                                                               mxData->maFromLocale);
1173
0
    }
1174
0
    catch (Exception&)
1175
0
    {
1176
0
        DBG_UNHANDLED_EXCEPTION("oox.drawingml");
1177
0
    }
1178
1179
0
    return nIndex;
1180
0
}
1181
1182
} // namespace oox
1183
1184
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */