LibreOffice Module i18npool (master) 1
defaultnumberingprovider.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
22#include <com/sun/star/i18n/NativeNumberMode.hpp>
23#include <com/sun/star/lang/IllegalArgumentException.hpp>
24#include <com/sun/star/style/NumberingType.hpp>
25#include <com/sun/star/beans/PropertyValue.hpp>
26#include <com/sun/star/configuration/theDefaultProvider.hpp>
27#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
28#include <osl/diagnose.h>
29#include <rtl/ref.hxx>
30#include <localedata.hxx>
32#include <string.h>
35
36// Cyrillic upper case
37#define C_CYR_A "\xD0\x90"
38#define C_CYR_B "\xD0\x91"
39// Cyrillic lower case
40#define S_CYR_A "\xD0\xB0"
41#define S_CYR_B "\xD0\xB1"
42
43//Greek upper case
44#define C_GR_A "\xCE\x91"
45#define C_GR_B "\xCE\x92"
46//Greek lower case
47#define S_GR_A "\xCE\xB1"
48#define S_GR_B "\xCE\xB2"
49
50//Hebrew
51#define S_HE_ALEPH "\xD7\x90"
52#define S_HE_YOD "\xD7\x99"
53#define S_HE_QOF "\xD7\xA7"
54
55//Arabic-Indic
56#define S_AR_ONE "\xd9\xa1"
57#define S_AR_TWO "\xd9\xa2"
58#define S_AR_THREE "\xd9\xa3"
59
60// East Arabic-Indic
61#define S_FA_ONE "\xDB\xB1"
62#define S_FA_TWO "\xDB\xB2"
63#define S_FA_THREE "\xDB\xB3"
64
65// Indic Devanagari
66#define S_HI_ONE "\xE0\xA5\xA7"
67#define S_HI_TWO "\xE0\xA5\xA8"
68#define S_HI_THREE "\xE0\xA5\xA9"
69
70// Chicago footnote symbols
71#define S_DAGGER "\xE2\x80\xA0"
72#define S_DBL_DAGGER "\xE2\x80\xA1"
73#define S_SECTION "\xC2\xA7"
74
75#include <sal/macros.h>
76#include <rtl/ustring.hxx>
77#include <rtl/ustrbuf.hxx>
78
79#include <bullet.h>
80
81using namespace com::sun::star;
82using namespace com::sun::star::uno;
83using namespace ::com::sun::star::i18n;
84using namespace com::sun::star::lang;
85
86namespace i18npool {
87
89 0x0623, 0x0628, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E,
90 0x062F, 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635,
91 0x0636, 0x0637, 0x0638, 0x0639, 0x063A, 0x0641, 0x0642,
92 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649
93};
94
96 0x0627, 0x0628, 0x062c, 0x062f, 0x0647, 0x0648, 0x0632, 0x062d,
97 0x0637, 0x064a, 0x0643, 0x0644, 0x0645, 0x0646, 0x0633, 0x0639,
98 0x0641, 0x0635, 0x0642, 0x0631, 0x0634, 0x062a, 0x062b, 0x062e,
99 0x0630, 0x0636, 0x0638, 0x063a
100};
101
103 0x0E01, 0x0E02, 0x0E04, 0x0E07,
104 0x0E08, 0x0E09, 0x0E0A, 0x0E0B, 0x0E0C, 0x0E0D, 0x0E0E, 0x0E0F,
105 0x0E10, 0x0E11, 0x0E12, 0x0E13, 0x0E14, 0x0E15, 0x0E16, 0x0E17,
106 0x0E18, 0x0E19, 0x0E1A, 0x0E1B, 0x0E1C, 0x0E1D, 0x0E1E, 0x0E1F,
107 0x0E20, 0x0E21, 0x0E22, 0x0E23, 0x0E24, 0x0E25, 0x0E26, 0x0E27,
108 0x0E28, 0x0E29, 0x0E2A, 0x0E2B, 0x0E2C, 0x0E2D, 0x0E2E
109};
110
112 0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7,
113 0x05D8, 0x05D9, 0x05DB, 0x05DC, 0x05DE, 0x05E0, 0x05E1, 0x05E2,
114 0x05E4, 0x05E6, 0x05E7, 0x05E8, 0x05E9, 0x05EA
115};
116
118 0x0915, 0x0916, 0x0917, 0x0918, 0x0919, 0x091A, 0x091B, 0x091C,
119 0x091D, 0x091E, 0x091F, 0x0920, 0x0921, 0x0922, 0x0923, 0x0924,
120 0x0925, 0x0926, 0x0927, 0x0928, 0x092A, 0x092B, 0x092C, 0x092D,
121 0x092E, 0x092F, 0x0930, 0x0932, 0x0935, 0x0936, 0x0937, 0x0938,
122 0x0939
123};
124
126 0x1780, 0x1781, 0x1782, 0x1783, 0x1784, 0x1785, 0x1786, 0x1787,
127 0x1788, 0x1789, 0x178A, 0x178B, 0x178C, 0x178D, 0x178E, 0x178F,
128 0x1790, 0x1791, 0x1792, 0x1793, 0x1794, 0x1795, 0x1796, 0x1797,
129 0x1798, 0x1799, 0x179A, 0x179B, 0x179C, 0x179F,
130 0x17A0, 0x17A1, 0x17A2
131};
132
134 0x0E81, 0x0E82, 0x0E84, 0x0E87, 0x0E88, 0x0E8A, 0x0E8D, 0x0E94,
135 0x0E95, 0x0E96, 0x0E97, 0x0E99, 0x0E9A, 0x0E9B, 0x0E9C,
136 0x0E9D, 0x0E9E, 0x0E9F, 0x0EA1, 0x0EA2, 0x0EA3, 0x0EA5, 0x0EA7,
137 0x0EAA, 0x0EAB, 0x0EAD, 0x0EAE, 0x0EAF, 0x0EAE, 0x0EDC, 0x0EDD
138};
139
141 0x0F40, 0x0F41, 0x0F42, 0x0F44, 0x0F45, 0x0F46, 0x0F47, 0x0F49,
142 0x0F4F, 0x0F50, 0x0F51, 0x0F53, 0x0F54, 0x0F55, 0x0F56, 0x0F58,
143 0x0F59, 0x0F5A, 0x0F5B, 0x0F5D, 0x0F5E, 0x0F5F, 0x0F60, 0x0F61,
144 0x0F62, 0x0F63, 0x0F64, 0x0F66, 0x0F67, 0x0F68
145};
146
148 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006, 0x1007,
149 0x1008,/*0x1009,*/0x100A, 0x100B, 0x100C, 0x100D, 0x100E, 0x100F,
150 0x1010, 0x1011, 0x1012, 0x1013, 0x1014, 0x1015, 0x1016, 0x1017,
151 0x1018, 0x1019, 0x101A, 0x101B, 0x101C, 0x101D, 0x101E, 0x101F,
152 0x1020, 0x1021
153};
154
155// Bulgarian Cyrillic upper case letters
157 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418,
158 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, 0x0420, 0x0421, 0x0422,
159 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042E,
160 0x042F
161};
162
163// Bulgarian cyrillic lower case letters
165 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438,
166 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F, 0x0440, 0x0441, 0x0442,
167 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044E,
168 0x044F
169};
170
171// Russian Cyrillic upper letters
173 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
174 0x0418, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, 0x0420,
175 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428,
176 0x0429, 0x042B, 0x042D, 0x042E, 0x042F
177};
178
179// Russian cyrillic lower letters
181 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
182 0x0438, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F, 0x0440,
183 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448,
184 0x0449, 0x044B, 0x044D, 0x044E, 0x044F
185};
186
187// Serbian Cyrillic upper letters
189 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0402, 0x0415, 0x0416,
190 0x0417, 0x0418, 0x0408, 0x041A, 0x041B, 0x0409, 0x041C, 0x041D,
191 0x040A, 0x041E, 0x041F, 0x0420, 0x0421, 0x0422, 0x040B, 0x0423,
192 0x0424, 0x0425, 0x0426, 0x0427, 0x040F, 0x0428
193};
194
195// Serbian cyrillic lower letters
197 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0452, 0x0435, 0x0436,
198 0x0437, 0x0438, 0x0458, 0x043A, 0x043B, 0x0459, 0x043C, 0x043D,
199 0x045A, 0x043E, 0x043F, 0x0440, 0x0441, 0x0442, 0x045B, 0x0443,
200 0x0444, 0x0445, 0x0446, 0x0447, 0x045F, 0x0448
201};
202
204 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x03DB, 0x0396, 0x0397, 0x0398,
205 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0, 0x03DF,
206 0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, 0x03E0
207};
208
210 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03DB, 0x03B6, 0x03B7, 0x03B8,
211 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, 0x03DF,
212 0x03C1, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8, 0x03C9, 0x03E1
213};
214
216 0x0622, 0x0628, 0x067E, 0x062A, 0x062B, 0x062C, 0x0686, 0x062D,
217 0x062E, 0x062F, 0x0630, 0x0631, 0x0632, 0x0698, 0x0633, 0x0634,
218 0x0635, 0x0636, 0x0637, 0x0638, 0x0639, 0x0640, 0x0641, 0x0642,
219 0x06A9, 0x06AF, 0x0644, 0x0645, 0x0646, 0x0648, 0x0647, 0x06CC
220};
221
223 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
224 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52,
225 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A
226};
227
229 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
230 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72,
231 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A
232};
233
235 0x002a, 0x2020, 0x2021, 0x00a7
236};
237
238// Tables used for numbering in persian words
240 {0}, // 0
241 {0x06cc, 0x06a9, 0}, // 1
242 {0x062f, 0x0648, 0}, // 2
243 {0x0633, 0x0647, 0}, // 3
244 {0x0686, 0x0647, 0x0627, 0x0631, 0}, // 4
245 {0x067e, 0x0646, 0x062c, 0}, // 5
246 {0x0634, 0x0634, 0}, // 6
247 {0x0647, 0x0641, 0x062a, 0}, // 7
248 {0x0647, 0x0634, 0x062a, 0}, // 8
249 {0x0646, 0x0647, 0}, // 9
250 {0x062f, 0x0647, 0}, // 10
251 {0x06cc, 0x0627, 0x0632, 0x062f, 0x0647, 0}, // 11
252 {0x062f, 0x0648, 0x0627, 0x0632, 0x062f, 0x0647, 0}, // 12
253 {0x0633, 0x06cc, 0x0632, 0x062f, 0x0647, 0}, // 13
254 {0x0686, 0x0647, 0x0627, 0x0631, 0x062f, 0x0647, 0}, // 14
255 {0x067e, 0x0627, 0x0646, 0x0632, 0x062f, 0x0647, 0}, // 15
256 {0x0634, 0x0627, 0x0646, 0x0632, 0x062f, 0x0647, 0}, // 16
257 {0x0647, 0x0641, 0x062f, 0x0647, 0}, // 17
258 {0x0647, 0x062c, 0x062f, 0x0647, 0}, // 18
259 {0x0646, 0x0648, 0x0632, 0x062f, 0x0647, 0} // 19
260};
261
263 {0x0628, 0x06cc, 0x0633, 0x062a, 0}, // 20
264 {0x0633, 0x06cc, 0}, // 30
265 {0x0686, 0x0647, 0x0644, 0}, // 40
266 {0x067e, 0x0646, 0x062c, 0x0627, 0x0647, 0}, // 50
267 {0x0634, 0x0635, 0x062a, 0}, // 60
268 {0x0647, 0x0641, 0x062a, 0x0627, 0x062f, 0}, // 70
269 {0x0647, 0x0634, 0x062a, 0x0627, 0x062f, 0}, // 80
270 {0x0646, 0x0648, 0x062f, 0} // 90
271};
272
274 {0x0635, 0x062f, 0}, // 100
275 {0x062f, 0x0648, 0x06cc, 0x0633, 0x062a, 0}, // 200
276 {0x0633, 0x06cc, 0x0635, 0x062f, 0}, // 300
277 {0x0686, 0x0647, 0x0627, 0x0631, 0x0635, 0x062f, 0}, // 400
278 {0x067e, 0x0627, 0x0646, 0x0635, 0x062f, 0}, // 500
279 {0x0634, 0x0635, 0x062f, 0}, // 600
280 {0x0647, 0x0641, 0x062a, 0x0635, 0x062f, 0}, // 700
281 {0x0647, 0x0634, 0x062a, 0x0635, 0x062f, 0}, // 800
282 {0x0646, 0x0647, 0x0635, 0x062f, 0} // 900
283};
284
286 {0x0647, 0x0632, 0x0627, 0x0631, 0}, // 1000
287 {0x0645, 0x06cc, 0x0644, 0x06cc, 0x0648, 0x0646, 0}, // 1000000
288 {0x0645, 0x06cc, 0x0644, 0x06cc, 0x0627, 0x0631, 0x062f, 0} // 1000000000
289};
290
292 {0xd558, 0xb098, 0}, // 1
293 {0xb458, 0}, // 2
294 {0xc14b, 0}, // 3
295 {0xb137, 0}, // 4
296 {0xb2e4, 0xc12f, 0}, // 5
297 {0xc5ec, 0xc12f, 0}, // 6
298 {0xc77c, 0xacf1, 0}, // 7
299 {0xc5ec, 0xb35f, 0}, // 8
300 {0xc544, 0xd649, 0} // 9
301};
302
304 {0xc5f4, 0}, // 10
305 {0xc2a4, 0xbb3c, 0}, // 20
306 {0xc11c, 0xb978, 0}, // 30
307 {0xb9c8, 0xd754, 0}, // 40
308 {0xc270, 0}, // 50
309 {0xc608, 0xc21c, 0}, // 60
310 {0xc77c, 0xd754, 0}, // 70
311 {0xc5ec, 0xb4e0, 0}, // 80
312 {0xc544, 0xd754, 0} // 90
313};
314
316{
317
318}
319
321{
322}
323
326{
327 return LocaleDataImpl::get()->getOutlineNumberingLevels( rLocale );
328}
329
332{
333 return LocaleDataImpl::get()->getContinuousNumberingLevels( rLocale );
334}
335
336static OUString toRoman( sal_Int32 n )
337{
338
339// i, ii, iii, iv, v, vi, vii, vii, viii, ix
340// (Dummy),1000,500,100,50,10,5,1
341 static const char coRomanArr[] = "MDCLXVI--"; // +2 Dummy entries !!
342 const char* cRomanStr = coRomanArr;
343 sal_uInt16 nMask = 1000;
344 sal_uInt32 nOver1000 = n / nMask;
345 n -= ( nOver1000 * nMask );
346
347 OUStringBuffer sTmp;
348 while(nOver1000--)
349 sTmp.append(*coRomanArr);
350
351 while( nMask )
352 {
353 sal_uInt8 nNumber = sal_uInt8( n / nMask );
354 sal_uInt8 nDiff = 1;
355 n %= nMask;
356
357 if( 5 < nNumber )
358 {
359 if( nNumber < 9 )
360 sTmp.append(*(cRomanStr-1));
361 ++nDiff;
362 nNumber -= 5;
363 }
364 switch( nNumber )
365 {
366 case 3: sTmp.append(*cRomanStr); [[fallthrough]];
367 case 2: sTmp.append(*cRomanStr); [[fallthrough]];
368 case 1: sTmp.append(*cRomanStr); break;
369 case 4: sTmp.append(*cRomanStr).append(*(cRomanStr-nDiff)); break;
370 case 5: sTmp.append(*(cRomanStr-nDiff)); break;
371 }
372
373 nMask /= 10; // to the next decade
374 cRomanStr += 2;
375 }
376 return sTmp.makeStringAndClear();
377}
378
379// not used:
380
381static
382void lcl_formatChars( const sal_Unicode table[], int tableSize, int n, OUString& s )
383{
384 // string representation of n is appended to s.
385 // if A=='A' then 0=>A, 1=>B, ..., 25=>Z, 26=>AA, 27=>AB, ...
386 // if A=='a' then 0=>a, 1=>b, ..., 25=>z, 26=>aa, 27=>ab, ...
387
388 if( n>=tableSize ) lcl_formatChars( table, tableSize, (n-tableSize)/tableSize, s );
389
390 s += OUStringChar( table[ n % tableSize ] );
391}
392
393static
394void lcl_formatChars1( const sal_Unicode table[], int tableSize, int n, OUString& s )
395{
396 // string representation of n is appended to s.
397 // if A=='A' then 0=>A, 1=>B, ..., 25=>Z, 26=>AA, 27=>BB, ...
398 // if A=='a' then 0=>a, 1=>b, ..., 25=>z, 26=>aa, 27=>bb, ...
399
400 int repeat_count = n / tableSize + 1;
401
402 for( int i=0; i<repeat_count; i++ )
403 s += OUStringChar( table[ n%tableSize ] );
404}
405
406static
407void lcl_formatChars2( const sal_Unicode table_capital[], const sal_Unicode table_small[], int tableSize, int n, OUString& s )
408{
409 // string representation of n is appended to s.
410 // if A=='A' then 0=>A, 1=>B, ..., 25=>Z, 26=>Aa, 27=>Ab, ...
411
412 if( n>=tableSize )
413 {
414 lcl_formatChars2( table_capital, table_small, tableSize, (n-tableSize)/tableSize, s );
415 s += OUStringChar( table_small[ n % tableSize ] );
416 } else
417 s += OUStringChar( table_capital[ n % tableSize ] );
418}
419
420static
421void lcl_formatChars3( const sal_Unicode table_capital[], const sal_Unicode table_small[], int tableSize, int n, OUString& s )
422{
423 // string representation of n is appended to s.
424 // if A=='A' then 0=>A, 1=>B, ..., 25=>Z, 26=>Aa, 27=>Bb, ...
425
426 int repeat_count = n / tableSize + 1;
427 s += OUStringChar( table_capital[ n%tableSize ] );
428
429 for( int i=1; i<repeat_count; i++ )
430 s += OUStringChar( table_small[ n%tableSize ] );
431}
432
433
441static
442void lcl_formatPersianWord( sal_Int32 nNumber, OUString& rsResult )
443{
444 OUStringBuffer aTemp(64);
445 static constexpr OUStringLiteral asPersianWord_conjunction_data = u" \u0648 ";
446 OUString asPersianWord_conjunction( asPersianWord_conjunction_data );
447 unsigned char nSection = 0;
448
449 while (int nPart = nNumber % 1000)
450 {
451 if (nSection)
452 {
454 throw IllegalArgumentException(); // does not happen with sal_Int32
455 aTemp.insert( 0, asPersianWord_conjunction).insert( 0, table_PersianWord_decadeX[nSection-1]);
456 }
457
458 unsigned int nDigit;
459 if ((nDigit = nPart % 100) < 20)
460 {
461 if (!aTemp.isEmpty())
462 aTemp.insert( 0, u' ');
463 aTemp.insert( 0, table_PersianWord_decade1[nDigit]);
464 }
465 else
466 {
467 if ((nDigit = nPart % 10) != 0)
468 {
469 if (!aTemp.isEmpty())
470 aTemp.insert( 0, asPersianWord_conjunction);
471 aTemp.insert( 0, table_PersianWord_decade1[nDigit]);
472 }
473 if ((nDigit = (nPart / 10) % 10) != 0)
474 {
475 if (!aTemp.isEmpty())
476 aTemp.insert( 0, asPersianWord_conjunction);
477 aTemp.insert( 0, table_PersianWord_decade2[nDigit-2]);
478 }
479 }
480
481 if ((nDigit = nPart / 100) != 0)
482 {
483 if (!aTemp.isEmpty())
484 aTemp.insert( 0, asPersianWord_conjunction);
485 aTemp.insert( 0, table_PersianWord_decade3[nDigit-1]);
486 }
487
488 nNumber /= 1000;
489 nSection++;
490 }
491 rsResult += aTemp;
492}
493
494static void lcl_formatKoreanLegalWord(sal_Int32 nNumber, OUString& rsResult) {
495 OUStringBuffer aTemp(64);
496 int digit1 = nNumber % 10;
497 int digit2 = nNumber / 10;
498 if (digit1 > 0)
499 aTemp.insert(0, (table_KoreanLegalWord_decade1[digit1 - 1]));
500 if (digit2 > 0)
501 aTemp.insert(0, (table_KoreanLegalWord_decade2[digit2 - 1]));
502 rsResult += aTemp;
503}
504
505// Greek Letter Numbering
506
507// KERAIA separates numerals from other text
508#define STIGMA u'\x03DB'
509#define LEFT_KERAIA u'\x0375'
510#define MYRIAD_SYM u'\x039C'
511#define DOT_SYM u'.'
512#define SIGMA_OFFSET 19
513#define TAU_OFFSET 20
514#define MYRIAD 10000
515
516/*
517* Return the 1-999999 number's representation in the Greek numbering system.
518* Adding a "left keraia" to represent numbers in the range 10000 ... 999999 is
519* not orthodox, so it's better to use the myriad notation and call this method
520* only for numbers up to 9999.
521*/
522static
523OUString gr_smallNum(const sal_Unicode table[], int n)
524{
525 if (n > 9999)
526 throw IllegalArgumentException();
527
528 int i = 0;
529 OUStringBuffer sb;
530 for (int v = n; v > 0; v /= 10, i++) {
531 int digit = v % 10;
532 if (digit == 0)
533 continue;
534
535 sal_Unicode sign = table[(digit - 1) + 9 * (i % 3)];
536 if (sign == STIGMA) {
537 sb.insert(0, table[TAU_OFFSET]);
538 sb.insert(0, table[SIGMA_OFFSET]);
539 } else {
540 sb.insert(0, sign);
541 }
542
543 if (i > 2)
544 sb.insert(0, LEFT_KERAIA);
545 }
546
547 return sb.makeStringAndClear();
548}
549
550static
551void lcl_formatCharsGR(const sal_Unicode table[], int n, OUString& s )
552{
553 OUStringBuffer sb;
554 int myriadPower = 2;
555
556 for (int divisor = MYRIAD * MYRIAD; divisor > 1; divisor /= MYRIAD, myriadPower--) {
557 if (n > divisor - 1) {
558 /*
559 * Follow the Diophantus representation of:
560 * A myriad sign, M(10000) as many times as the power
561 * followed by the multiplier for the myriad
562 * followed by a dot
563 * followed by the rest
564 * This is enough for 32-bit integers
565 */
566 for (int i = 0; i < myriadPower; i++)
567 sb.append(MYRIAD_SYM);
568
569 sb.append(gr_smallNum(table, n/divisor));
570 n %= divisor;
571
572 if (n > 0)
573 sb.append(DOT_SYM);
574 }
575 }
576 sb.append(gr_smallNum(table,n));
577
578 s += sb;
579}
580
581static
582bool should_ignore( std::u16string_view s )
583{
584 // return true if blank or null
585 return s == u" " || (!s.empty() && s[0]==0);
586}
587
592static OUString lcl_formatArabicZero(sal_Int32 nNumber, sal_Int32 nLimit)
593{
594 OUString aRet = OUString::number(nNumber);
595 sal_Int32 nDiff = nLimit - aRet.getLength();
596
597 if (nDiff <= 0)
598 {
599 return aRet;
600 }
601
602 OUStringBuffer aBuffer;
603 aBuffer.setLength(nDiff);
604 for (sal_Int32 i = 0; i < nDiff; ++i)
605 {
606 aBuffer[i] = '0';
607 }
608 aBuffer.append(aRet);
609 return aBuffer.makeStringAndClear();
610}
611
612static
614 const char* name )
615{
616 auto pProp = std::find_if(aProperties.begin(), aProperties.end(),
617 [&name](const beans::PropertyValue& rProp) { return rProp.Name.equalsAscii(name); });
618 if (pProp != aProperties.end())
619 return pProp->Value;
620 throw IllegalArgumentException();
621}
622
623//XNumberingFormatter
624OUString
626 const Locale& aLocale )
627{
628 // the Sequence of PropertyValues is expected to have at least 4 elements:
629 // elt Name Type purpose
630
631
632 // 0. "Prefix" OUString
633 // 1. "NumberingType" sal_Int16 type of formatting from style::NumberingType (roman, arabic, etc)
634 // 2. "Suffix" OUString
635 // ... ... ...
636 // n. "Value" sal_Int32 the number to be formatted
637 // example:
638 // given the Sequence { '(', NumberingType::ROMAN_UPPER, ')', ..., 7 }
639 // makeNumberingString() returns the string "(VII)".
640
641 // Q: why is the type of numType sal_Int16 instead of style::NumberingType?
642 // A: an Any can't hold a style::NumberingType for some reason.
643 // add.: style::NumberingType holds constants of type sal_Int16, it's not an enum type
644
645 sal_Int16 natNum = 0;
646 sal_Int16 tableSize = 0;
647 const sal_Unicode *table = nullptr; // initialize to avoid compiler warning
648 bool bRecycleSymbol = false;
649 OUString sNatNumParams;
650 Locale locale;
651
652 OUString prefix;
653 sal_Int16 numType = -1; // type of formatting from style::NumberingType (roman, arabic, etc)
654 OUString suffix;
655 sal_Int32 number = -1; // the number that needs to be formatted.
656
657// int nProperties = aProperties.getLength();
658// int last = nProperties-1;
659
660 for (auto const & prop : aProperties)
661 {
662 if (prop.Name == "Prefix")
663 prop.Value >>= prefix;
664 else if (prop.Name == "Suffix")
665 prop.Value >>= suffix;
666 else if (prop.Name == "NumberingType")
667 prop.Value >>= numType;
668 else if (prop.Name == "Value")
669 prop.Value >>= number;
670 }
671
672 if( number <= 0 )
673 throw IllegalArgumentException();
674
675 // start empty
676 OUString result;
677
678 // append prefix
680
681 // append formatted number
682 using namespace style::NumberingType;
683 switch( numType )
684 {
685 case CHARS_UPPER_LETTER:
686 lcl_formatChars( upperLetter, 26, number-1, result ); // 1=>A, 2=>B, ..., 26=>Z, 27=>AA, 28=>AB, ...
687 break;
688 case CHARS_LOWER_LETTER:
689 lcl_formatChars( lowerLetter, 26, number-1, result );
690 break;
691 case TEXT_NUMBER: // ordinal indicators (1st, 2nd, 3rd, ...)
692 natNum = NativeNumberMode::NATNUM12;
693 sNatNumParams = "capitalize ordinal-number";
694 locale = aLocale;
695 break;
696 case TEXT_CARDINAL: // cardinal number names (One, Two, Three, ...)
697 natNum = NativeNumberMode::NATNUM12;
698 sNatNumParams = "capitalize";
699 locale = aLocale;
700 break;
701 case TEXT_ORDINAL: // ordinal number names (First, Second, Third, ...)
702 natNum = NativeNumberMode::NATNUM12;
703 sNatNumParams = "capitalize ordinal";
704 locale = aLocale;
705 break;
706 case ROMAN_UPPER:
707 result += toRoman( number );
708 break;
709 case ROMAN_LOWER:
710 result += toRoman( number ).toAsciiLowerCase();
711 break;
712 case ARABIC:
713 result += OUString::number( number );
714 break;
715 case NUMBER_NONE:
716 return OUString(); // ignore prefix and suffix
717 case CHAR_SPECIAL:
718 // apparently, we're supposed to return an empty string in this case...
719 return OUString(); // ignore prefix and suffix
720 case PAGE_DESCRIPTOR:
721 case BITMAP:
722 OSL_ASSERT(false);
723 throw IllegalArgumentException();
724 case CHARS_UPPER_LETTER_N:
725 lcl_formatChars1( upperLetter, 26, number-1, result ); // 1=>A, 2=>B, ..., 26=>Z, 27=>AA, 28=>BB, ...
726 break;
727 case CHARS_LOWER_LETTER_N:
728 lcl_formatChars1( lowerLetter, 26, number-1, result ); // 1=>A, 2=>B, ..., 26=>Z, 27=>AA, 28=>BB, ...
729 break;
730 case TRANSLITERATION:
731 try {
732 const OUString &tmp = OUString::number( number );
733 OUString transliteration;
734 getPropertyByName(aProperties, "Transliteration") >>= transliteration;
735 if ( !translit )
737 translit->loadModuleByImplName(transliteration, aLocale);
738 result += translit->transliterateString2String(tmp, 0, tmp.getLength());
739 } catch (Exception& ) {
740 // When transliteration property is missing, return default number (bug #101141#)
741 result += OUString::number( number );
742 // OSL_ASSERT(0);
743 // throw IllegalArgumentException();
744 }
745 break;
746 case NATIVE_NUMBERING:
747 natNum = NativeNumberMode::NATNUM1;
748 locale = aLocale;
749 break;
750 case FULLWIDTH_ARABIC:
751 natNum = NativeNumberMode::NATNUM3;
752 locale = aLocale;
753 break;
754 case NUMBER_LOWER_ZH:
755 natNum = NativeNumberMode::NATNUM12;
756 locale.Language = "zh";
757 break;
758 case NUMBER_UPPER_ZH:
759 natNum = NativeNumberMode::NATNUM5;
760 locale.Language = "zh";
761 break;
762 case NUMBER_UPPER_ZH_TW:
763 natNum = NativeNumberMode::NATNUM5;
764 locale.Language = "zh";
765 locale.Country = "TW";
766 break;
767 case NUMBER_TRADITIONAL_JA:
768 natNum = NativeNumberMode::NATNUM8;
769 locale.Language = "ja";
770 break;
771 case NUMBER_UPPER_KO:
772 natNum = NativeNumberMode::NATNUM8;
773 locale.Language = "ko";
774 break;
775 case NUMBER_HANGUL_KO:
776 natNum = NativeNumberMode::NATNUM11;
777 locale.Language = "ko";
778 break;
779 case NUMBER_DIGITAL_KO:
780 natNum = NativeNumberMode::NATNUM9;
781 locale.Language = "ko";
782 break;
783 case NUMBER_DIGITAL2_KO:
784 natNum = NativeNumberMode::NATNUM1;
785 locale.Language = "ko";
786 break;
787 case NUMBER_LEGAL_KO:
788 if (number < 1 || number >= 100)
789 {
790 natNum = NativeNumberMode::NATNUM11;
791 locale.Language = "ko";
792 }
793 else
794 {
796 }
797 break;
798
799 case CIRCLE_NUMBER:
802 break;
803 case TIAN_GAN_ZH:
805 tableSize = SAL_N_ELEMENTS(table_TianGan_zh);
806 break;
807 case DI_ZI_ZH:
809 tableSize = SAL_N_ELEMENTS(table_DiZi_zh);
810 break;
811 case AIU_FULLWIDTH_JA:
814 bRecycleSymbol = true;
815 break;
816 case AIU_HALFWIDTH_JA:
819 bRecycleSymbol = true;
820 break;
821 case IROHA_FULLWIDTH_JA:
824 bRecycleSymbol = true;
825 break;
826 case IROHA_HALFWIDTH_JA:
829 bRecycleSymbol = true;
830 break;
831 case HANGUL_JAMO_KO:
834 bRecycleSymbol = true;
835 break;
836 case HANGUL_SYLLABLE_KO:
839 bRecycleSymbol = true;
840 break;
841 case HANGUL_CIRCLED_JAMO_KO:
844 bRecycleSymbol = true;
845 break;
846 case HANGUL_CIRCLED_SYLLABLE_KO:
849 bRecycleSymbol = true;
850 break;
851 case CHARS_ARABIC:
853 break;
854 case CHARS_ARABIC_ABJAD:
856 break;
857 case NUMBER_ARABIC_INDIC:
858 natNum = NativeNumberMode::NATNUM1;
859 locale.Language = "ar";
860 break;
861 case NUMBER_EAST_ARABIC_INDIC:
862 natNum = NativeNumberMode::NATNUM1;
863 locale.Language = "fa";
864 break;
865 case NUMBER_INDIC_DEVANAGARI:
866 natNum = NativeNumberMode::NATNUM1;
867 locale.Language = "hi";
868 break;
869 case CHARS_THAI:
871 break;
872 case CHARS_HEBREW:
874 break;
875 case NUMBER_HEBREW:
876 natNum = NativeNumberMode::NATNUM1;
877 locale.Language = "he";
878 break;
879 case CHARS_NEPALI:
881 break;
882 case CHARS_KHMER:
884 break;
885 case CHARS_LAO:
887 break;
888 case CHARS_MYANMAR:
890 break;
891 case CHARS_TIBETAN:
893 break;
894 case CHARS_CYRILLIC_UPPER_LETTER_BG:
898 result); // 1=>a, 2=>b, ..., 28=>z, 29=>Aa, 30=>Ab, ...
899 break;
900 case CHARS_CYRILLIC_LOWER_LETTER_BG:
903 result); // 1=>a, 2=>b, ..., 28=>z, 29=>aa, 30=>ab, ...
904 break;
905 case CHARS_CYRILLIC_UPPER_LETTER_N_BG:
909 result); // 1=>a, 2=>b, ..., 28=>z, 29=>Aa, 30=>Bb, ...
910 break;
911 case CHARS_CYRILLIC_LOWER_LETTER_N_BG:
914 result); // 1=>a, 2=>b, ..., 28=>z, 29=>aa, 30=>bb, ...
915 break;
916 case CHARS_CYRILLIC_UPPER_LETTER_RU:
920 result); // 1=>a, 2=>b, ..., 27=>z, 28=>Aa, 29=>Ab, ...
921 break;
922 case CHARS_CYRILLIC_LOWER_LETTER_RU:
925 result); // 1=>a, 2=>b, ..., 27=>z, 28=>aa, 29=>ab, ...
926 break;
927 case CHARS_CYRILLIC_UPPER_LETTER_N_RU:
931 result); // 1=>a, 2=>b, ..., 27=>z, 28=>Aa, 29=>Bb, ...
932 break;
933 case CHARS_CYRILLIC_LOWER_LETTER_N_RU:
936 result); // 1=>a, 2=>b, ..., 27=>z, 28=>aa, 29=>bb, ...
937 break;
938 case CHARS_CYRILLIC_UPPER_LETTER_SR:
942 result); // 1=>a, 2=>b, ..., 27=>z, 28=>Aa, 29=>Ab, ...
943 break;
944 case CHARS_CYRILLIC_LOWER_LETTER_SR:
947 result); // 1=>a, 2=>b, ..., 27=>z, 28=>aa, 29=>ab, ...
948 break;
949 case CHARS_CYRILLIC_UPPER_LETTER_N_SR:
953 result); // 1=>a, 2=>b, ..., 27=>z, 28=>Aa, 29=>Bb, ...
954 break;
955 case CHARS_CYRILLIC_LOWER_LETTER_N_SR:
958 result); // 1=>a, 2=>b, ..., 27=>z, 28=>aa, 29=>bb, ...
959 break;
960
961 case CHARS_GREEK_LOWER_LETTER:
963 break;
964
965 case CHARS_GREEK_UPPER_LETTER:
967 break;
968
969 case CHARS_PERSIAN:
971 break;
972
973 case CHARS_PERSIAN_WORD:
975 break;
976
977 case SYMBOL_CHICAGO:
978 lcl_formatChars1( table_Chicago, 4, number-1, result ); // *, +, |, S, **, ++, ...
979 break;
980
981 case ARABIC_ZERO:
982 result += lcl_formatArabicZero(number, 2);
983 break;
984
985 case ARABIC_ZERO3:
986 result += lcl_formatArabicZero(number, 3);
987 break;
988
989 case ARABIC_ZERO4:
990 result += lcl_formatArabicZero(number, 4);
991 break;
992
993 case ARABIC_ZERO5:
994 result += lcl_formatArabicZero(number, 5);
995 break;
996
997 case SZEKELY_ROVAS: // Old Hungarian
998 natNum = NativeNumberMode::NATNUM12;
999 locale.Language = "hu-Hung";
1000 break;
1001
1002 default:
1003 OSL_ASSERT(false);
1004 throw IllegalArgumentException();
1005 }
1006
1007 if (natNum) {
1008 if (!mxNatNum)
1010 result += mxNatNum->getNativeNumberStringParams(OUString::number(number), locale,
1011 natNum, sNatNumParams);
1012 } else if (tableSize) {
1013 if ( number > tableSize && !bRecycleSymbol)
1014 result += OUString::number( number);
1015 else
1016 result += OUStringChar(table[--number % tableSize]);
1017 }
1018
1019 // append suffix
1020 if( !should_ignore(suffix) ) result += suffix;
1021
1022 return result;
1023}
1024
1025#define LANG_ALL (1 << 0)
1026#define LANG_CJK (1 << 1)
1027#define LANG_CTL (1 << 2)
1028
1030{
1031 const char* cSymbol;
1032 sal_Int16 nType;
1033 sal_Int16 langOption;
1034 Supported_NumberingType(sal_Int16 nType_, const char* pSymbol, sal_Int16 opt)
1035 : cSymbol(pSymbol), nType(nType_), langOption(opt) {}
1036};
1038{
1039 {style::NumberingType::CHARS_UPPER_LETTER, "A", LANG_ALL},
1040 {style::NumberingType::CHARS_LOWER_LETTER, "a", LANG_ALL},
1041 {style::NumberingType::ROMAN_UPPER, "I", LANG_ALL},
1042 {style::NumberingType::ROMAN_LOWER, "i", LANG_ALL},
1043 {style::NumberingType::ARABIC, "1", LANG_ALL},
1044 {style::NumberingType::NUMBER_NONE, "''", LANG_ALL},
1045 {style::NumberingType::CHAR_SPECIAL, "Bullet", LANG_ALL},
1046 {style::NumberingType::PAGE_DESCRIPTOR, "Page", LANG_ALL},
1047 {style::NumberingType::BITMAP, "Bitmap", LANG_ALL},
1048 {style::NumberingType::SYMBOL_CHICAGO, "*, " S_DAGGER ", " S_DBL_DAGGER ", " S_SECTION ", **, " S_DAGGER S_DAGGER ", ...", LANG_ALL},
1049 {style::NumberingType::TEXT_NUMBER, "1st", LANG_ALL},
1050 {style::NumberingType::TEXT_CARDINAL, "One", LANG_ALL},
1051 {style::NumberingType::TEXT_ORDINAL, "First", LANG_ALL},
1052 {style::NumberingType::CHARS_UPPER_LETTER_N, "AAA", LANG_ALL},
1053 {style::NumberingType::CHARS_LOWER_LETTER_N, "aaa", LANG_ALL},
1054 {style::NumberingType::NATIVE_NUMBERING, "Native Numbering", LANG_CJK|LANG_CTL},
1055 {style::NumberingType::FULLWIDTH_ARABIC, nullptr, LANG_CJK},
1056 {style::NumberingType::CIRCLE_NUMBER, nullptr, LANG_CJK},
1057 // The cSymbol is defined here for compatibility with files created by old releases.
1058 // Otherwise if nullptr, these 3 digits may change as NATNUM12 depends on 3rd-party lib.
1059 {style::NumberingType::NUMBER_LOWER_ZH, "一, 二, 三, ...", LANG_CJK},
1060 {style::NumberingType::NUMBER_UPPER_ZH, nullptr, LANG_CJK},
1061 {style::NumberingType::NUMBER_UPPER_ZH_TW, nullptr, LANG_CJK},
1062 {style::NumberingType::TIAN_GAN_ZH, nullptr, LANG_CJK},
1063 {style::NumberingType::DI_ZI_ZH, nullptr, LANG_CJK},
1064 {style::NumberingType::NUMBER_TRADITIONAL_JA, nullptr, LANG_CJK},
1065 {style::NumberingType::AIU_FULLWIDTH_JA, nullptr, LANG_CJK},
1066 {style::NumberingType::AIU_HALFWIDTH_JA, nullptr, LANG_CJK},
1067 {style::NumberingType::IROHA_FULLWIDTH_JA, nullptr, LANG_CJK},
1068 {style::NumberingType::IROHA_HALFWIDTH_JA, nullptr, LANG_CJK},
1069 {style::NumberingType::NUMBER_UPPER_KO, nullptr, LANG_CJK},
1070 {style::NumberingType::NUMBER_HANGUL_KO, nullptr, LANG_CJK},
1071 {style::NumberingType::HANGUL_JAMO_KO, nullptr, LANG_CJK},
1072 {style::NumberingType::HANGUL_SYLLABLE_KO, nullptr, LANG_CJK},
1073 {style::NumberingType::HANGUL_CIRCLED_JAMO_KO, nullptr, LANG_CJK},
1074 {style::NumberingType::HANGUL_CIRCLED_SYLLABLE_KO, nullptr, LANG_CJK},
1075 {style::NumberingType::NUMBER_LEGAL_KO, nullptr, LANG_CJK},
1076 {style::NumberingType::NUMBER_DIGITAL_KO, nullptr, LANG_CJK},
1077 {style::NumberingType::NUMBER_DIGITAL2_KO, nullptr, LANG_CJK},
1078 {style::NumberingType::CHARS_ARABIC, nullptr, LANG_CTL},
1079 {style::NumberingType::CHARS_ARABIC_ABJAD, nullptr, LANG_CTL},
1080 {style::NumberingType::NUMBER_ARABIC_INDIC, S_AR_ONE ", " S_AR_TWO ", " S_AR_THREE ", ...", LANG_CTL},
1081 {style::NumberingType::NUMBER_EAST_ARABIC_INDIC, S_FA_ONE ", " S_FA_TWO ", " S_FA_THREE ", ...", LANG_CTL},
1082 {style::NumberingType::NUMBER_INDIC_DEVANAGARI, S_HI_ONE ", " S_HI_TWO ", " S_HI_THREE ", ...", LANG_CTL},
1083 {style::NumberingType::CHARS_THAI, nullptr, LANG_CTL},
1084 {style::NumberingType::CHARS_HEBREW, nullptr, LANG_CTL},
1085 {style::NumberingType::NUMBER_HEBREW, S_HE_ALEPH ", " S_HE_YOD ", " S_HE_QOF ", ...", LANG_CTL},
1086 {style::NumberingType::CHARS_NEPALI, nullptr, LANG_CTL},
1087 {style::NumberingType::CHARS_KHMER, nullptr, LANG_CTL},
1088 {style::NumberingType::CHARS_LAO, nullptr, LANG_CTL},
1089 {style::NumberingType::CHARS_MYANMAR, nullptr, LANG_CTL},
1090 {style::NumberingType::CHARS_TIBETAN, nullptr, LANG_CTL},
1091 {style::NumberingType::CHARS_CYRILLIC_UPPER_LETTER_BG, C_CYR_A ", " C_CYR_B ", .., " C_CYR_A S_CYR_A ", " C_CYR_A S_CYR_B ", ... (bg)", LANG_ALL},
1092 {style::NumberingType::CHARS_CYRILLIC_LOWER_LETTER_BG, S_CYR_A ", " S_CYR_B ", .., " S_CYR_A S_CYR_A ", " S_CYR_A S_CYR_B ", ... (bg)", LANG_ALL},
1093 {style::NumberingType::CHARS_CYRILLIC_UPPER_LETTER_N_BG, C_CYR_A ", " C_CYR_B ", .., " C_CYR_A S_CYR_A ", " C_CYR_B S_CYR_B ", ... (bg)", LANG_ALL},
1094 {style::NumberingType::CHARS_CYRILLIC_LOWER_LETTER_N_BG, S_CYR_A ", " S_CYR_B ", .., " S_CYR_A S_CYR_A ", " S_CYR_B S_CYR_B ", ... (bg)", LANG_ALL},
1095 {style::NumberingType::CHARS_CYRILLIC_UPPER_LETTER_RU, C_CYR_A ", " C_CYR_B ", .., " C_CYR_A S_CYR_A ", " C_CYR_A S_CYR_B ", ... (ru)", LANG_ALL},
1096 {style::NumberingType::CHARS_CYRILLIC_LOWER_LETTER_RU, S_CYR_A ", " S_CYR_B ", .., " S_CYR_A S_CYR_A ", " S_CYR_A S_CYR_B ", ... (ru)", LANG_ALL},
1097 {style::NumberingType::CHARS_CYRILLIC_UPPER_LETTER_N_RU, C_CYR_A ", " C_CYR_B ", .., " C_CYR_A S_CYR_A ", " C_CYR_B S_CYR_B ", ... (ru)", LANG_ALL},
1098 {style::NumberingType::CHARS_CYRILLIC_LOWER_LETTER_N_RU, S_CYR_A ", " S_CYR_B ", .., " S_CYR_A S_CYR_A ", " S_CYR_B S_CYR_B ", ... (ru)", LANG_ALL},
1099 {style::NumberingType::CHARS_CYRILLIC_UPPER_LETTER_SR, C_CYR_A ", " C_CYR_B ", .., " C_CYR_A S_CYR_A ", " C_CYR_A S_CYR_B ", ... (sr)", LANG_ALL},
1100 {style::NumberingType::CHARS_CYRILLIC_LOWER_LETTER_SR, S_CYR_A ", " S_CYR_B ", .., " S_CYR_A S_CYR_A ", " S_CYR_A S_CYR_B ", ... (sr)", LANG_ALL},
1101 {style::NumberingType::CHARS_CYRILLIC_UPPER_LETTER_N_SR, C_CYR_A ", " C_CYR_B ", .., " C_CYR_A S_CYR_A ", " C_CYR_B S_CYR_B ", ... (sr)", LANG_ALL},
1102 {style::NumberingType::CHARS_CYRILLIC_LOWER_LETTER_N_SR, S_CYR_A ", " S_CYR_B ", .., " S_CYR_A S_CYR_A ", " S_CYR_B S_CYR_B ", ... (sr)", LANG_ALL},
1103 {style::NumberingType::CHARS_PERSIAN, nullptr, LANG_CTL},
1104 {style::NumberingType::CHARS_PERSIAN_WORD, nullptr, LANG_CTL},
1105 {style::NumberingType::SZEKELY_ROVAS, nullptr, LANG_CTL},
1106 {style::NumberingType::CHARS_GREEK_UPPER_LETTER, C_GR_A ", " C_GR_B ", ... (gr)", LANG_ALL},
1107 {style::NumberingType::CHARS_GREEK_LOWER_LETTER, S_GR_A ", " S_GR_B ", ... (gr)", LANG_ALL},
1108 {style::NumberingType::ARABIC_ZERO, "01, 02, 03, ...", LANG_ALL},
1109 {style::NumberingType::ARABIC_ZERO3, "001, 002, 003, ...", LANG_ALL},
1110 {style::NumberingType::ARABIC_ZERO4, "0001, 0002, 0003, ...", LANG_ALL},
1111 {style::NumberingType::ARABIC_ZERO5, "00001, 00002, 00003, ...", LANG_ALL},
1112};
1114
1116{
1117 if (index < 0 || index >= nSupported_NumberingTypes)
1118 throw RuntimeException();
1119
1120 if (aSupportedTypes[index].cSymbol)
1121 return OUString(aSupportedTypes[index].cSymbol, strlen(aSupportedTypes[index].cSymbol), RTL_TEXTENCODING_UTF8);
1122 else {
1123 OUStringBuffer result;
1124 Locale aLocale("en", OUString(), OUString());
1126 auto aPropertiesRange = asNonConstRange(aProperties);
1127 aPropertiesRange[0].Name = "NumberingType";
1128 aPropertiesRange[0].Value <<= aSupportedTypes[index].nType;
1129 aPropertiesRange[1].Name = "Value";
1130 for (sal_Int32 j = 1; j <= 3; j++) {
1131 aPropertiesRange[1].Value <<= j;
1132 result.append( makeNumberingString( aProperties, aLocale ) );
1133 result.append(", ");
1134 }
1135 result.append("...");
1136 // Make known duplicate generated identifiers unique.
1137 // Note this alone works only for newly added numberings, if duplicates
1138 // are in the wild further handling is needed when loading documents
1139 // and asking for numberings.
1140 switch (aSupportedTypes[index].nType)
1141 {
1142 case css::style::NumberingType::NUMBER_DIGITAL_KO:
1143 // Duplicate of NUMBER_HANGUL_KO.
1144 result.append(" (ko-x-digital)");
1145 break;
1146 case css::style::NumberingType::NUMBER_DIGITAL2_KO:
1147 // Duplicate of NUMBER_LOWER_ZH.
1148 result.append(" (ko)");
1149 break;
1150 default:
1151 ; // nothing
1152 }
1153 return result.makeStringAndClear();
1154 }
1155}
1156
1157bool
1159{
1160 if (! xHierarchicalNameAccess.is()) {
1161 Reference< XMultiServiceFactory > xConfigProvider =
1162 configuration::theDefaultProvider::get(m_xContext);
1163
1164 if (! xConfigProvider.is())
1165 throw RuntimeException();
1166
1167 uno::Sequence<uno::Any> aArgs(comphelper::InitAnyPropertySequence(
1168 {
1169 {"nodepath", uno::Any(OUString("/org.openoffice.Office.Common/I18N"))}
1170 }));
1171
1172 Reference<XInterface> xInterface = xConfigProvider->createInstanceWithArguments(
1173 "com.sun.star.configuration.ConfigurationAccess", aArgs);
1174
1175 xHierarchicalNameAccess.set(xInterface, UNO_QUERY_THROW);
1176 }
1177
1178 Any aEnabled = xHierarchicalNameAccess->getByHierarchicalName(aName);
1179
1180 bool enabled = false;
1181
1182 aEnabled >>= enabled;
1183
1184 return enabled;
1185}
1186
1188{
1190 sal_Int16* pArray = aRet.getArray();
1191
1192 bool cjkEnabled = isScriptFlagEnabled("CJK/CJKFont");
1193 bool ctlEnabled = isScriptFlagEnabled("CTL/CTLFont");
1194
1195 for(sal_Int16 i = 0; i < nSupported_NumberingTypes; i++) {
1196 if ( (aSupportedTypes[i].langOption & LANG_ALL) ||
1197 ((aSupportedTypes[i].langOption & LANG_CJK) && cjkEnabled) ||
1198 ((aSupportedTypes[i].langOption & LANG_CTL) && ctlEnabled) )
1199 pArray[i] = aSupportedTypes[i].nType;
1200 }
1201 return aRet;
1202}
1203
1204sal_Int16 DefaultNumberingProvider::getNumberingType( const OUString& rNumberingIdentifier )
1205{
1206 auto it = maSupportedTypesCache.find(rNumberingIdentifier);
1207 if (it != maSupportedTypesCache.end())
1208 return it->second->nType;
1209 for(sal_Int16 i = 0; i < nSupported_NumberingTypes; i++)
1210 if(rNumberingIdentifier == makeNumberingIdentifier(i))
1211 {
1212 maSupportedTypesCache.emplace(rNumberingIdentifier, &aSupportedTypes[i]);
1213 return aSupportedTypes[i].nType;
1214 }
1215 throw RuntimeException();
1216}
1217
1218sal_Bool DefaultNumberingProvider::hasNumberingType( const OUString& rNumberingIdentifier )
1219{
1220 auto it = maSupportedTypesCache.find(rNumberingIdentifier);
1221 if (it != maSupportedTypesCache.end())
1222 return true;
1223 for(sal_Int16 i = 0; i < nSupported_NumberingTypes; i++)
1224 if(rNumberingIdentifier == makeNumberingIdentifier(i))
1225 {
1226 maSupportedTypesCache.emplace(rNumberingIdentifier, &aSupportedTypes[i]);
1227 return true;
1228 }
1229 return false;
1230}
1231
1232OUString DefaultNumberingProvider::getNumberingIdentifier( sal_Int16 nNumberingType )
1233{
1234 for(sal_Int16 i = 0; i < nSupported_NumberingTypes; i++)
1235 if(nNumberingType == aSupportedTypes[i].nType)
1236 return makeNumberingIdentifier(i);
1237 return OUString();
1238}
1239
1241{
1242 return "com.sun.star.text.DefaultNumberingProvider";
1243}
1244
1246{
1247 return cppu::supportsService(this, rServiceName);
1248}
1249
1251{
1252 Sequence< OUString > aRet { "com.sun.star.text.DefaultNumberingProvider" };
1253 return aRet;
1254}
1255
1256}
1257
1258extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
1260 css::uno::XComponentContext *context,
1261 css::uno::Sequence<css::uno::Any> const &)
1262{
1263 return cppu::acquire(new i18npool::DefaultNumberingProvider(context));
1264}
1265
1266/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Reference< XComponentContext > m_xContext
PropertiesInfo aProperties
std::map< OUString, const Supported_NumberingType * > maSupportedTypesCache
virtual css::uno::Sequence< sal_Int16 > SAL_CALL getSupportedNumberingTypes() override
virtual OUString SAL_CALL getNumberingIdentifier(sal_Int16 NumberingType) override
bool isScriptFlagEnabled(const OUString &aName)
virtual sal_Bool SAL_CALL hasNumberingType(const OUString &NumberingIdentifier) override
virtual sal_Bool SAL_CALL supportsService(const OUString &ServiceName) override
css::uno::Reference< css::uno::XComponentContext > m_xContext
css::uno::Reference< css::container::XHierarchicalNameAccess > xHierarchicalNameAccess
DefaultNumberingProvider(const css::uno::Reference< css::uno::XComponentContext > &rxContext)
virtual sal_Int16 SAL_CALL getNumberingType(const OUString &NumberingIdentifier) override
rtl::Reference< TransliterationImpl > translit
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
rtl::Reference< NativeNumberSupplierService > mxNatNum
virtual css::uno::Sequence< css::uno::Reference< css::container::XIndexAccess > > SAL_CALL getDefaultOutlineNumberings(const css::lang::Locale &aLocale) override
virtual OUString SAL_CALL makeNumberingString(const css::uno::Sequence< css::beans::PropertyValue > &aProperties, const css::lang::Locale &aLocale) override
virtual OUString SAL_CALL getImplementationName() override
virtual css::uno::Sequence< css::uno::Sequence< css::beans::PropertyValue > > SAL_CALL getDefaultContinuousNumberingLevels(const css::lang::Locale &aLocale) override
static rtl::Reference< LocaleDataImpl > get()
Definition: localedata.hxx:77
#define S_DAGGER
#define S_DBL_DAGGER
#define STIGMA
#define S_HE_YOD
#define DOT_SYM
#define MYRIAD
#define S_CYR_B
#define C_GR_A
#define C_CYR_B
#define S_SECTION
#define S_HE_ALEPH
#define S_GR_B
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * com_sun_star_text_DefaultNumberingProvider_get_implementation(css::uno::XComponentContext *context, css::uno::Sequence< css::uno::Any > const &)
#define C_CYR_A
#define S_GR_A
#define C_GR_B
#define S_FA_TWO
#define S_HI_THREE
#define S_FA_THREE
#define S_AR_TWO
#define SIGMA_OFFSET
#define LANG_CTL
#define S_HE_QOF
#define S_CYR_A
#define S_FA_ONE
#define S_AR_ONE
#define S_HI_ONE
#define LEFT_KERAIA
#define TAU_OFFSET
#define MYRIAD_SYM
#define S_HI_TWO
#define LANG_CJK
#define S_AR_THREE
#define LANG_ALL
float v
float u
const char * name
OUString aName
sal_Int64 n
#define SAL_N_ELEMENTS(arr)
@ table
@ Exception
css::uno::Sequence< css::uno::Any > InitAnyPropertySequence(::std::initializer_list< ::std::pair< OUString, css::uno::Any > > vInit)
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
int i
Constant values shared between i18npool and, for example, the number formatter.
static void lcl_formatChars1(const sal_Unicode table[], int tableSize, int n, OUString &s)
const sal_Unicode lowerLetter[]
const sal_Unicode table_PersianWord_decade2[][6]
const sal_Unicode table_PersianWord_decadeX[][8]
const sal_Unicode table_CyrillicLowerLetter_sr[]
const sal_Unicode table_HangulCircledJamo_ko[]
Definition: bullet.h:314
const sal_Unicode table_CyrillicLowerLetter_ru[]
const Supported_NumberingType aSupportedTypes[]
const sal_Unicode table_Alphabet_my[]
static void lcl_formatChars3(const sal_Unicode table_capital[], const sal_Unicode table_small[], int tableSize, int n, OUString &s)
const sal_Unicode table_HangulCircledSyllable_ko[]
Definition: bullet.h:332
const sal_Unicode table_Alphabet_fa[]
const sal_Unicode table_TianGan_zh[]
Definition: bullet.h:349
const sal_Unicode table_CyrillicUpperLetter_ru[]
const sal_Unicode table_GreekUpperLetter[]
const sal_Unicode table_IROHAFullWidth_ja_JP[]
Definition: bullet.h:124
static bool should_ignore(std::u16string_view s)
const sal_Unicode table_AIUHalfWidth_ja_JP[]
Definition: bullet.h:75
const sal_Unicode table_Alphabet_lo[]
static OUString toRoman(sal_Int32 n)
const sal_Unicode table_HangulJamo_ko[]
Definition: bullet.h:279
const sal_Unicode table_Alphabet_ar[]
const sal_Unicode table_KoreanLegalWord_decade1[][3]
const sal_Unicode table_PersianWord_decade1[][7]
const sal_Unicode table_KoreanLegalWord_decade2[][3]
const sal_Unicode table_AIUFullWidth_ja_JP[]
Definition: bullet.h:26
const sal_Unicode table_PersianWord_decade3[][7]
const sal_Int32 nSupported_NumberingTypes
const sal_Unicode table_Alphabet_he[]
static void lcl_formatChars(const sal_Unicode table[], int tableSize, int n, OUString &s)
const sal_Unicode table_Alphabet_km[]
const sal_Unicode table_Alphabet_ne[]
static void lcl_formatPersianWord(sal_Int32 nNumber, OUString &rsResult)
Returns number's representation in persian words up to 999999999999 respectively limited by sal_Int32...
const sal_Unicode table_HangulSyllable_ko[]
Definition: bullet.h:296
const sal_Unicode table_CyrillicUpperLetter_sr[]
const sal_Unicode table_CyrillicLowerLetter_bg[]
static void lcl_formatCharsGR(const sal_Unicode table[], int n, OUString &s)
static OUString lcl_formatArabicZero(sal_Int32 nNumber, sal_Int32 nLimit)
Turn nNumber into a string and pad the result to nLimit by inserting zero characters at the start.
static void lcl_formatChars2(const sal_Unicode table_capital[], const sal_Unicode table_small[], int tableSize, int n, OUString &s)
static OUString gr_smallNum(const sal_Unicode table[], int n)
const sal_Unicode table_Alphabet_dz[]
const sal_Unicode upperLetter[]
const sal_Unicode table_Alphabet_ar_abjad[]
const sal_Unicode table_IROHAHalfWidth_ja_JP[]
Definition: bullet.h:175
const sal_Unicode table_DiZi_zh[]
Definition: bullet.h:353
const sal_Unicode table_GreekLowerLetter[]
static void lcl_formatKoreanLegalWord(sal_Int32 nNumber, OUString &rsResult)
const sal_Unicode table_Alphabet_th[]
const sal_Unicode table_CircledNumber[]
Definition: bullet.h:226
const sal_Unicode table_Chicago[]
const sal_Unicode table_CyrillicUpperLetter_bg[]
static Any getPropertyByName(const Sequence< beans::PropertyValue > &aProperties, const char *name)
index
ARABIC
QPRO_FUNC_TYPE nType
Supported_NumberingType(sal_Int16 nType_, const char *pSymbol, sal_Int16 opt)
unsigned char sal_uInt8
unsigned char sal_Bool
sal_uInt16 sal_Unicode
Any result
std::unique_ptr< char[]> aBuffer