1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <defaultnumberingprovider.hxx>
21 #include <transliterationImpl.hxx>
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>
31 #include <nativenumbersupplier.hxx>
33 #include <comphelper/propertysequence.hxx>
34 #include <cppuhelper/supportsservice.hxx>
35 #include <officecfg/Office/Common.hxx>
37 // Cyrillic upper case
38 #define C_CYR_A "\xD0\x90"
39 #define C_CYR_B "\xD0\x91"
40 // Cyrillic lower case
41 #define S_CYR_A "\xD0\xB0"
42 #define S_CYR_B "\xD0\xB1"
45 #define C_GR_A "\xCE\x91"
46 #define C_GR_B "\xCE\x92"
48 #define S_GR_A "\xCE\xB1"
49 #define S_GR_B "\xCE\xB2"
52 #define S_HE_ALEPH "\xD7\x90"
53 #define S_HE_YOD "\xD7\x99"
54 #define S_HE_QOF "\xD7\xA7"
57 #define S_AR_ONE "\xd9\xa1"
58 #define S_AR_TWO "\xd9\xa2"
59 #define S_AR_THREE "\xd9\xa3"
62 #define S_FA_ONE "\xDB\xB1"
63 #define S_FA_TWO "\xDB\xB2"
64 #define S_FA_THREE "\xDB\xB3"
67 #define S_HI_ONE "\xE0\xA5\xA7"
68 #define S_HI_TWO "\xE0\xA5\xA8"
69 #define S_HI_THREE "\xE0\xA5\xA9"
71 // Chicago footnote symbols
72 #define S_DAGGER "\xE2\x80\xA0"
73 #define S_DBL_DAGGER "\xE2\x80\xA1"
74 #define S_SECTION "\xC2\xA7"
76 #include <sal/macros.h>
77 #include <rtl/ustring.hxx>
78 #include <rtl/ustrbuf.hxx>
82 using namespace com::sun::star
;
83 using namespace com::sun::star::uno
;
84 using namespace ::com::sun::star::i18n
;
85 using namespace com::sun::star::lang
;
89 constexpr sal_Unicode table_Alphabet_ar
[] = {
90 0x0623, 0x0628, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E,
91 0x062F, 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635,
92 0x0636, 0x0637, 0x0638, 0x0639, 0x063A, 0x0641, 0x0642,
93 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649
96 constexpr sal_Unicode table_Alphabet_ar_abjad
[] = {
97 0x0627, 0x0628, 0x062c, 0x062f, 0x0647, 0x0648, 0x0632, 0x062d,
98 0x0637, 0x064a, 0x0643, 0x0644, 0x0645, 0x0646, 0x0633, 0x0639,
99 0x0641, 0x0635, 0x0642, 0x0631, 0x0634, 0x062a, 0x062b, 0x062e,
100 0x0630, 0x0636, 0x0638, 0x063a
103 constexpr sal_Unicode table_Alphabet_th
[] = {
104 0x0E01, 0x0E02, 0x0E04, 0x0E07,
105 0x0E08, 0x0E09, 0x0E0A, 0x0E0B, 0x0E0C, 0x0E0D, 0x0E0E, 0x0E0F,
106 0x0E10, 0x0E11, 0x0E12, 0x0E13, 0x0E14, 0x0E15, 0x0E16, 0x0E17,
107 0x0E18, 0x0E19, 0x0E1A, 0x0E1B, 0x0E1C, 0x0E1D, 0x0E1E, 0x0E1F,
108 0x0E20, 0x0E21, 0x0E22, 0x0E23, 0x0E24, 0x0E25, 0x0E26, 0x0E27,
109 0x0E28, 0x0E29, 0x0E2A, 0x0E2B, 0x0E2C, 0x0E2D, 0x0E2E
112 constexpr sal_Unicode table_Alphabet_he
[] = {
113 0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7,
114 0x05D8, 0x05D9, 0x05DB, 0x05DC, 0x05DE, 0x05E0, 0x05E1, 0x05E2,
115 0x05E4, 0x05E6, 0x05E7, 0x05E8, 0x05E9, 0x05EA
118 constexpr sal_Unicode table_Alphabet_ne
[] = {
119 0x0915, 0x0916, 0x0917, 0x0918, 0x0919, 0x091A, 0x091B, 0x091C,
120 0x091D, 0x091E, 0x091F, 0x0920, 0x0921, 0x0922, 0x0923, 0x0924,
121 0x0925, 0x0926, 0x0927, 0x0928, 0x092A, 0x092B, 0x092C, 0x092D,
122 0x092E, 0x092F, 0x0930, 0x0932, 0x0935, 0x0936, 0x0937, 0x0938,
126 constexpr sal_Unicode table_Alphabet_km
[] = {
127 0x1780, 0x1781, 0x1782, 0x1783, 0x1784, 0x1785, 0x1786, 0x1787,
128 0x1788, 0x1789, 0x178A, 0x178B, 0x178C, 0x178D, 0x178E, 0x178F,
129 0x1790, 0x1791, 0x1792, 0x1793, 0x1794, 0x1795, 0x1796, 0x1797,
130 0x1798, 0x1799, 0x179A, 0x179B, 0x179C, 0x179F,
131 0x17A0, 0x17A1, 0x17A2
134 constexpr sal_Unicode table_Alphabet_lo
[] = {
135 0x0E81, 0x0E82, 0x0E84, 0x0E87, 0x0E88, 0x0E8A, 0x0E8D, 0x0E94,
136 0x0E95, 0x0E96, 0x0E97, 0x0E99, 0x0E9A, 0x0E9B, 0x0E9C,
137 0x0E9D, 0x0E9E, 0x0E9F, 0x0EA1, 0x0EA2, 0x0EA3, 0x0EA5, 0x0EA7,
138 0x0EAA, 0x0EAB, 0x0EAD, 0x0EAE, 0x0EAF, 0x0EAE, 0x0EDC, 0x0EDD
141 constexpr sal_Unicode table_Alphabet_dz
[] = {
142 0x0F40, 0x0F41, 0x0F42, 0x0F44, 0x0F45, 0x0F46, 0x0F47, 0x0F49,
143 0x0F4F, 0x0F50, 0x0F51, 0x0F53, 0x0F54, 0x0F55, 0x0F56, 0x0F58,
144 0x0F59, 0x0F5A, 0x0F5B, 0x0F5D, 0x0F5E, 0x0F5F, 0x0F60, 0x0F61,
145 0x0F62, 0x0F63, 0x0F64, 0x0F66, 0x0F67, 0x0F68
148 constexpr sal_Unicode table_Alphabet_my
[] = {
149 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006, 0x1007,
150 0x1008,/*0x1009,*/0x100A, 0x100B, 0x100C, 0x100D, 0x100E, 0x100F,
151 0x1010, 0x1011, 0x1012, 0x1013, 0x1014, 0x1015, 0x1016, 0x1017,
152 0x1018, 0x1019, 0x101A, 0x101B, 0x101C, 0x101D, 0x101E, 0x101F,
156 // Bulgarian Cyrillic upper case letters
157 constexpr sal_Unicode table_CyrillicUpperLetter_bg
[] = {
158 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418,
159 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, 0x0420, 0x0421, 0x0422,
160 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042E,
164 // Bulgarian cyrillic lower case letters
165 constexpr sal_Unicode table_CyrillicLowerLetter_bg
[] = {
166 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438,
167 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F, 0x0440, 0x0441, 0x0442,
168 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044E,
172 // Russian Cyrillic upper letters
173 constexpr sal_Unicode table_CyrillicUpperLetter_ru
[] = {
174 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
175 0x0418, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, 0x0420,
176 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428,
177 0x0429, 0x042B, 0x042D, 0x042E, 0x042F
180 // Russian cyrillic lower letters
181 constexpr sal_Unicode table_CyrillicLowerLetter_ru
[] = {
182 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
183 0x0438, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F, 0x0440,
184 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448,
185 0x0449, 0x044B, 0x044D, 0x044E, 0x044F
188 // Serbian Cyrillic upper letters
189 constexpr sal_Unicode table_CyrillicUpperLetter_sr
[] = {
190 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0402, 0x0415, 0x0416,
191 0x0417, 0x0418, 0x0408, 0x041A, 0x041B, 0x0409, 0x041C, 0x041D,
192 0x040A, 0x041E, 0x041F, 0x0420, 0x0421, 0x0422, 0x040B, 0x0423,
193 0x0424, 0x0425, 0x0426, 0x0427, 0x040F, 0x0428
196 // Serbian cyrillic lower letters
197 constexpr sal_Unicode table_CyrillicLowerLetter_sr
[] = {
198 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0452, 0x0435, 0x0436,
199 0x0437, 0x0438, 0x0458, 0x043A, 0x043B, 0x0459, 0x043C, 0x043D,
200 0x045A, 0x043E, 0x043F, 0x0440, 0x0441, 0x0442, 0x045B, 0x0443,
201 0x0444, 0x0445, 0x0446, 0x0447, 0x045F, 0x0448
204 // Ukrainian Cyrillic upper letters
205 constexpr sal_Unicode table_CyrillicUpperLetter_uk
[] = {
206 0x0410, 0x0411, 0x0412, 0x0413, 0x0490, 0x0414, 0x0415, 0x0404,
207 0x0416, 0x0417, 0x0418, 0x0406, 0x0407, 0x0419, 0x041A, 0x041B,
208 0x041C, 0x041D, 0x041E, 0x041F, 0x0420, 0x0421, 0x0422, 0x0423,
209 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042C, 0x042E,
213 // Ukrainian cyrillic lower letters
214 constexpr sal_Unicode table_CyrillicLowerLetter_uk
[] = {
215 0x0430, 0x0431, 0x0432, 0x0433, 0x0491, 0x0434, 0x0435, 0x0454,
216 0x0436, 0x0437, 0x0438, 0x0456, 0x0457, 0x0439, 0x043A, 0x043B,
217 0x043C, 0x043D, 0x043E, 0x043F, 0x0440, 0x0441, 0x0442, 0x0443,
218 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044C, 0x044E,
222 constexpr sal_Unicode table_GreekUpperLetter
[] = {
223 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x03DB, 0x0396, 0x0397, 0x0398,
224 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0, 0x03DF,
225 0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, 0x03E0
228 constexpr sal_Unicode table_GreekLowerLetter
[] = {
229 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03DB, 0x03B6, 0x03B7, 0x03B8,
230 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, 0x03DF,
231 0x03C1, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8, 0x03C9, 0x03E1
234 constexpr sal_Unicode table_Alphabet_fa
[] = {
235 0x0622, 0x0628, 0x067E, 0x062A, 0x062B, 0x062C, 0x0686, 0x062D,
236 0x062E, 0x062F, 0x0630, 0x0631, 0x0632, 0x0698, 0x0633, 0x0634,
237 0x0635, 0x0636, 0x0637, 0x0638, 0x0639, 0x0640, 0x0641, 0x0642,
238 0x06A9, 0x06AF, 0x0644, 0x0645, 0x0646, 0x0648, 0x0647, 0x06CC
241 constexpr sal_Unicode upperLetter
[] = {
242 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
243 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52,
244 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A
247 constexpr sal_Unicode lowerLetter
[] = {
248 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
249 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72,
250 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A
253 constexpr sal_Unicode table_Chicago
[] = {
254 0x002a, 0x2020, 0x2021, 0x00a7
257 // Tables used for numbering in persian words
258 constexpr sal_Unicode table_PersianWord_decade1
[][7]={
260 {0x06cc, 0x06a9, 0}, // 1
261 {0x062f, 0x0648, 0}, // 2
262 {0x0633, 0x0647, 0}, // 3
263 {0x0686, 0x0647, 0x0627, 0x0631, 0}, // 4
264 {0x067e, 0x0646, 0x062c, 0}, // 5
265 {0x0634, 0x0634, 0}, // 6
266 {0x0647, 0x0641, 0x062a, 0}, // 7
267 {0x0647, 0x0634, 0x062a, 0}, // 8
268 {0x0646, 0x0647, 0}, // 9
269 {0x062f, 0x0647, 0}, // 10
270 {0x06cc, 0x0627, 0x0632, 0x062f, 0x0647, 0}, // 11
271 {0x062f, 0x0648, 0x0627, 0x0632, 0x062f, 0x0647, 0}, // 12
272 {0x0633, 0x06cc, 0x0632, 0x062f, 0x0647, 0}, // 13
273 {0x0686, 0x0647, 0x0627, 0x0631, 0x062f, 0x0647, 0}, // 14
274 {0x067e, 0x0627, 0x0646, 0x0632, 0x062f, 0x0647, 0}, // 15
275 {0x0634, 0x0627, 0x0646, 0x0632, 0x062f, 0x0647, 0}, // 16
276 {0x0647, 0x0641, 0x062f, 0x0647, 0}, // 17
277 {0x0647, 0x062c, 0x062f, 0x0647, 0}, // 18
278 {0x0646, 0x0648, 0x0632, 0x062f, 0x0647, 0} // 19
281 constexpr sal_Unicode table_PersianWord_decade2
[][6]={
282 {0x0628, 0x06cc, 0x0633, 0x062a, 0}, // 20
283 {0x0633, 0x06cc, 0}, // 30
284 {0x0686, 0x0647, 0x0644, 0}, // 40
285 {0x067e, 0x0646, 0x062c, 0x0627, 0x0647, 0}, // 50
286 {0x0634, 0x0635, 0x062a, 0}, // 60
287 {0x0647, 0x0641, 0x062a, 0x0627, 0x062f, 0}, // 70
288 {0x0647, 0x0634, 0x062a, 0x0627, 0x062f, 0}, // 80
289 {0x0646, 0x0648, 0x062f, 0} // 90
292 constexpr sal_Unicode table_PersianWord_decade3
[][7]={
293 {0x0635, 0x062f, 0}, // 100
294 {0x062f, 0x0648, 0x06cc, 0x0633, 0x062a, 0}, // 200
295 {0x0633, 0x06cc, 0x0635, 0x062f, 0}, // 300
296 {0x0686, 0x0647, 0x0627, 0x0631, 0x0635, 0x062f, 0}, // 400
297 {0x067e, 0x0627, 0x0646, 0x0635, 0x062f, 0}, // 500
298 {0x0634, 0x0635, 0x062f, 0}, // 600
299 {0x0647, 0x0641, 0x062a, 0x0635, 0x062f, 0}, // 700
300 {0x0647, 0x0634, 0x062a, 0x0635, 0x062f, 0}, // 800
301 {0x0646, 0x0647, 0x0635, 0x062f, 0} // 900
304 constexpr sal_Unicode table_PersianWord_decadeX
[][8]={
305 {0x0647, 0x0632, 0x0627, 0x0631, 0}, // 1000
306 {0x0645, 0x06cc, 0x0644, 0x06cc, 0x0648, 0x0646, 0}, // 1000000
307 {0x0645, 0x06cc, 0x0644, 0x06cc, 0x0627, 0x0631, 0x062f, 0} // 1000000000
310 constexpr sal_Unicode table_KoreanLegalWord_decade1
[][3] = {
311 {0xd558, 0xb098, 0}, // 1
315 {0xb2e4, 0xc12f, 0}, // 5
316 {0xc5ec, 0xc12f, 0}, // 6
317 {0xc77c, 0xacf1, 0}, // 7
318 {0xc5ec, 0xb35f, 0}, // 8
319 {0xc544, 0xd649, 0} // 9
322 constexpr sal_Unicode table_KoreanLegalWord_decade2
[][3] = {
324 {0xc2a4, 0xbb3c, 0}, // 20
325 {0xc11c, 0xb978, 0}, // 30
326 {0xb9c8, 0xd754, 0}, // 40
328 {0xc608, 0xc21c, 0}, // 60
329 {0xc77c, 0xd754, 0}, // 70
330 {0xc5ec, 0xb4e0, 0}, // 80
331 {0xc544, 0xd754, 0} // 90
334 DefaultNumberingProvider::DefaultNumberingProvider( const Reference
< XComponentContext
>& rxContext
) : m_xContext(rxContext
)
339 DefaultNumberingProvider::~DefaultNumberingProvider()
343 Sequence
< Reference
<container::XIndexAccess
> >
344 DefaultNumberingProvider::getDefaultOutlineNumberings(const Locale
& rLocale
)
346 return LocaleDataImpl::get()->getOutlineNumberingLevels( rLocale
);
349 Sequence
< Sequence
<beans::PropertyValue
> >
350 DefaultNumberingProvider::getDefaultContinuousNumberingLevels( const Locale
& rLocale
)
352 return LocaleDataImpl::get()->getContinuousNumberingLevels( rLocale
);
355 static OUString
toRoman( sal_Int32 n
)
358 // i, ii, iii, iv, v, vi, vii, vii, viii, ix
359 // (Dummy),1000,500,100,50,10,5,1
360 static const char coRomanArr
[] = "MDCLXVI--"; // +2 Dummy entries !!
361 const char* cRomanStr
= coRomanArr
;
362 sal_uInt16 nMask
= 1000;
363 sal_uInt32 nOver1000
= n
/ nMask
;
364 n
-= ( nOver1000
* nMask
);
368 sTmp
.append(*coRomanArr
);
372 sal_uInt8 nNumber
= sal_uInt8( n
/ nMask
);
379 sTmp
.append(*(cRomanStr
-1));
385 case 3: sTmp
.append(*cRomanStr
); [[fallthrough
]];
386 case 2: sTmp
.append(*cRomanStr
); [[fallthrough
]];
387 case 1: sTmp
.append(*cRomanStr
); break;
388 case 4: sTmp
.append(OUStringChar(*cRomanStr
) + OUStringChar(*(cRomanStr
-nDiff
))); break;
389 case 5: sTmp
.append(*(cRomanStr
-nDiff
)); break;
392 nMask
/= 10; // to the next decade
395 return sTmp
.makeStringAndClear();
401 void lcl_formatChars( const sal_Unicode table
[], int tableSize
, int n
, OUString
& s
)
403 // string representation of n is appended to s.
404 // if A=='A' then 0=>A, 1=>B, ..., 25=>Z, 26=>AA, 27=>AB, ...
405 // if A=='a' then 0=>a, 1=>b, ..., 25=>z, 26=>aa, 27=>ab, ...
407 if( n
>=tableSize
) lcl_formatChars( table
, tableSize
, (n
-tableSize
)/tableSize
, s
);
409 s
+= OUStringChar( table
[ n
% tableSize
] );
413 void lcl_formatChars1( const sal_Unicode table
[], int tableSize
, int n
, OUString
& s
)
415 // string representation of n is appended to s.
416 // if A=='A' then 0=>A, 1=>B, ..., 25=>Z, 26=>AA, 27=>BB, ...
417 // if A=='a' then 0=>a, 1=>b, ..., 25=>z, 26=>aa, 27=>bb, ...
419 int repeat_count
= n
/ tableSize
+ 1;
421 for( int i
=0; i
<repeat_count
; i
++ )
422 s
+= OUStringChar( table
[ n
%tableSize
] );
426 void lcl_formatChars2( const sal_Unicode table_capital
[], const sal_Unicode table_small
[], int tableSize
, int n
, OUString
& s
)
428 // string representation of n is appended to s.
429 // if A=='A' then 0=>A, 1=>B, ..., 25=>Z, 26=>Aa, 27=>Ab, ...
433 lcl_formatChars2( table_capital
, table_small
, tableSize
, (n
-tableSize
)/tableSize
, s
);
434 s
+= OUStringChar( table_small
[ n
% tableSize
] );
436 s
+= OUStringChar( table_capital
[ n
% tableSize
] );
440 void lcl_formatChars3( const sal_Unicode table_capital
[], const sal_Unicode table_small
[], int tableSize
, int n
, OUString
& s
)
442 // string representation of n is appended to s.
443 // if A=='A' then 0=>A, 1=>B, ..., 25=>Z, 26=>Aa, 27=>Bb, ...
445 int repeat_count
= n
/ tableSize
+ 1;
446 s
+= OUStringChar( table_capital
[ n
%tableSize
] );
448 for( int i
=1; i
<repeat_count
; i
++ )
449 s
+= OUStringChar( table_small
[ n
%tableSize
] );
453 /** Returns number's representation in persian words up to 999999999999
454 respectively limited by sal_Int32 >=0.
455 The caller assures that nNumber is not negative.
457 @throws IllegalArgumentException
458 @throws RuntimeException
461 void lcl_formatPersianWord( sal_Int32 nNumber
, OUString
& rsResult
)
463 OUStringBuffer
aTemp(64);
464 OUString asPersianWord_conjunction
= u
" \u0648 "_ustr
;
465 unsigned char nSection
= 0;
467 while (int nPart
= nNumber
% 1000)
471 if (nSection
> std::size( table_PersianWord_decadeX
))
472 throw IllegalArgumentException(); // does not happen with sal_Int32
473 aTemp
.insert( 0, table_PersianWord_decadeX
[nSection
-1] + asPersianWord_conjunction
);
477 if ((nDigit
= nPart
% 100) < 20)
479 if (!aTemp
.isEmpty())
480 aTemp
.insert( 0, u
' ');
481 aTemp
.insert( 0, table_PersianWord_decade1
[nDigit
]);
485 if ((nDigit
= nPart
% 10) != 0)
487 if (!aTemp
.isEmpty())
488 aTemp
.insert( 0, asPersianWord_conjunction
);
489 aTemp
.insert( 0, table_PersianWord_decade1
[nDigit
]);
491 if ((nDigit
= (nPart
/ 10) % 10) != 0)
493 if (!aTemp
.isEmpty())
494 aTemp
.insert( 0, asPersianWord_conjunction
);
495 aTemp
.insert( 0, table_PersianWord_decade2
[nDigit
-2]);
499 if ((nDigit
= nPart
/ 100) != 0)
501 if (!aTemp
.isEmpty())
502 aTemp
.insert( 0, asPersianWord_conjunction
);
503 aTemp
.insert( 0, table_PersianWord_decade3
[nDigit
-1]);
512 static void lcl_formatKoreanLegalWord(sal_Int32 nNumber
, OUString
& rsResult
) {
513 OUStringBuffer
aTemp(64);
514 int digit1
= nNumber
% 10;
515 int digit2
= nNumber
/ 10;
517 aTemp
.insert(0, (table_KoreanLegalWord_decade1
[digit1
- 1]));
519 aTemp
.insert(0, (table_KoreanLegalWord_decade2
[digit2
- 1]));
523 // Greek Letter Numbering
525 // KERAIA separates numerals from other text
526 #define STIGMA u'\x03DB'
527 #define LEFT_KERAIA u'\x0375'
528 #define MYRIAD_SYM u'\x039C'
530 #define SIGMA_OFFSET 19
531 #define TAU_OFFSET 20
535 * Return the 1-999999 number's representation in the Greek numbering system.
536 * Adding a "left keraia" to represent numbers in the range 10000 ... 999999 is
537 * not orthodox, so it's better to use the myriad notation and call this method
538 * only for numbers up to 9999.
541 OUString
gr_smallNum(const sal_Unicode table
[], int n
)
544 throw IllegalArgumentException();
548 for (int v
= n
; v
> 0; v
/= 10, i
++) {
553 sal_Unicode sign
= table
[(digit
- 1) + 9 * (i
% 3)];
554 if (sign
== STIGMA
) {
555 sb
.insert(0, table
[TAU_OFFSET
]);
556 sb
.insert(0, table
[SIGMA_OFFSET
]);
562 sb
.insert(0, LEFT_KERAIA
);
565 return sb
.makeStringAndClear();
569 void lcl_formatCharsGR(const sal_Unicode table
[], int n
, OUString
& s
)
574 for (int divisor
= MYRIAD
* MYRIAD
; divisor
> 1; divisor
/= MYRIAD
, myriadPower
--) {
575 if (n
> divisor
- 1) {
577 * Follow the Diophantus representation of:
578 * A myriad sign, M(10000) as many times as the power
579 * followed by the multiplier for the myriad
581 * followed by the rest
582 * This is enough for 32-bit integers
584 for (int i
= 0; i
< myriadPower
; i
++)
585 sb
.append(MYRIAD_SYM
);
587 sb
.append(gr_smallNum(table
, n
/divisor
));
594 sb
.append(gr_smallNum(table
,n
));
600 bool should_ignore( std::u16string_view s
)
602 // return true if blank or null
603 return s
== u
" " || (!s
.empty() && s
[0]==0);
607 * Turn nNumber into a string and pad the result to nLimit by inserting zero characters at the
610 static OUString
lcl_formatArabicZero(sal_Int32 nNumber
, sal_Int32 nLimit
)
612 OUString aRet
= OUString::number(nNumber
);
613 sal_Int32 nDiff
= nLimit
- aRet
.getLength();
620 OUStringBuffer aBuffer
;
621 aBuffer
.setLength(nDiff
);
622 for (sal_Int32 i
= 0; i
< nDiff
; ++i
)
626 aBuffer
.append(aRet
);
627 return aBuffer
.makeStringAndClear();
631 Any
getPropertyByName( const Sequence
<beans::PropertyValue
>& aProperties
,
634 auto pProp
= std::find_if(aProperties
.begin(), aProperties
.end(),
635 [&name
](const beans::PropertyValue
& rProp
) { return rProp
.Name
.equalsAscii(name
); });
636 if (pProp
!= aProperties
.end())
638 throw IllegalArgumentException();
641 //XNumberingFormatter
643 DefaultNumberingProvider::makeNumberingString( const Sequence
<beans::PropertyValue
>& aProperties
,
644 const Locale
& aLocale
)
646 // the Sequence of PropertyValues is expected to have at least 4 elements:
647 // elt Name Type purpose
650 // 0. "Prefix" OUString
651 // 1. "NumberingType" sal_Int16 type of formatting from style::NumberingType (roman, arabic, etc)
652 // 2. "Suffix" OUString
654 // n. "Value" sal_Int32 the number to be formatted
656 // given the Sequence { '(', NumberingType::ROMAN_UPPER, ')', ..., 7 }
657 // makeNumberingString() returns the string "(VII)".
659 // Q: why is the type of numType sal_Int16 instead of style::NumberingType?
660 // A: an Any can't hold a style::NumberingType for some reason.
661 // add.: style::NumberingType holds constants of type sal_Int16, it's not an enum type
663 sal_Int16 natNum
= 0;
664 sal_Int16 tableSize
= 0;
665 const sal_Unicode
*table
= nullptr; // initialize to avoid compiler warning
666 bool bRecycleSymbol
= false;
667 OUString sNatNumParams
;
671 sal_Int16 numType
= -1; // type of formatting from style::NumberingType (roman, arabic, etc)
673 sal_Int32 number
= -1; // the number that needs to be formatted.
675 // int nProperties = aProperties.getLength();
676 // int last = nProperties-1;
678 for (auto const & prop
: aProperties
)
680 if (prop
.Name
== "Prefix")
681 prop
.Value
>>= prefix
;
682 else if (prop
.Name
== "Suffix")
683 prop
.Value
>>= suffix
;
684 else if (prop
.Name
== "NumberingType")
685 prop
.Value
>>= numType
;
686 else if (prop
.Name
== "Value")
687 prop
.Value
>>= number
;
691 throw IllegalArgumentException();
697 if( !should_ignore(prefix
) ) result
+= prefix
;
699 // append formatted number
700 using namespace style::NumberingType
;
703 case CHARS_UPPER_LETTER
:
704 lcl_formatChars( upperLetter
, 26, number
-1, result
); // 1=>A, 2=>B, ..., 26=>Z, 27=>AA, 28=>AB, ...
706 case CHARS_LOWER_LETTER
:
707 lcl_formatChars( lowerLetter
, 26, number
-1, result
);
709 case TEXT_NUMBER
: // ordinal indicators (1st, 2nd, 3rd, ...)
710 natNum
= NativeNumberMode::NATNUM12
;
711 sNatNumParams
= "capitalize ordinal-number";
714 case TEXT_CARDINAL
: // cardinal number names (One, Two, Three, ...)
715 natNum
= NativeNumberMode::NATNUM12
;
716 sNatNumParams
= "capitalize";
719 case TEXT_ORDINAL
: // ordinal number names (First, Second, Third, ...)
720 natNum
= NativeNumberMode::NATNUM12
;
721 sNatNumParams
= "capitalize ordinal";
725 result
+= toRoman( number
);
728 result
+= toRoman( number
).toAsciiLowerCase();
731 result
+= OUString::number( number
);
734 return OUString(); // ignore prefix and suffix
736 // apparently, we're supposed to return an empty string in this case...
737 return OUString(); // ignore prefix and suffix
738 case PAGE_DESCRIPTOR
:
741 throw IllegalArgumentException();
742 case CHARS_UPPER_LETTER_N
:
743 lcl_formatChars1( upperLetter
, 26, number
-1, result
); // 1=>A, 2=>B, ..., 26=>Z, 27=>AA, 28=>BB, ...
745 case CHARS_LOWER_LETTER_N
:
746 lcl_formatChars1( lowerLetter
, 26, number
-1, result
); // 1=>A, 2=>B, ..., 26=>Z, 27=>AA, 28=>BB, ...
748 case TRANSLITERATION
:
750 const OUString tmp
= OUString::number( number
);
751 OUString transliteration
;
752 getPropertyByName(aProperties
, "Transliteration") >>= transliteration
;
754 translit
= new TransliterationImpl(m_xContext
);
755 translit
->loadModuleByImplName(transliteration
, aLocale
);
756 result
+= translit
->transliterateString2String(tmp
, 0, tmp
.getLength());
757 } catch (Exception
& ) {
758 // When transliteration property is missing, return default number (bug #101141#)
759 result
+= OUString::number( number
);
761 // throw IllegalArgumentException();
764 case NATIVE_NUMBERING
:
765 natNum
= NativeNumberMode::NATNUM1
;
768 case FULLWIDTH_ARABIC
:
769 natNum
= NativeNumberMode::NATNUM3
;
772 case NUMBER_LOWER_ZH
:
773 natNum
= NativeNumberMode::NATNUM12
;
774 locale
.Language
= "zh";
776 case NUMBER_UPPER_ZH
:
777 natNum
= NativeNumberMode::NATNUM5
;
778 locale
.Language
= "zh";
780 case NUMBER_UPPER_ZH_TW
:
781 natNum
= NativeNumberMode::NATNUM5
;
782 locale
.Language
= "zh";
783 locale
.Country
= "TW";
785 case NUMBER_TRADITIONAL_JA
:
786 natNum
= NativeNumberMode::NATNUM8
;
787 locale
.Language
= "ja";
789 case NUMBER_UPPER_KO
:
790 natNum
= NativeNumberMode::NATNUM8
;
791 locale
.Language
= "ko";
793 case NUMBER_HANGUL_KO
:
794 natNum
= NativeNumberMode::NATNUM11
;
795 locale
.Language
= "ko";
797 case NUMBER_DIGITAL_KO
:
798 natNum
= NativeNumberMode::NATNUM9
;
799 locale
.Language
= "ko";
801 case NUMBER_DIGITAL2_KO
:
802 natNum
= NativeNumberMode::NATNUM1
;
803 locale
.Language
= "ko";
805 case NUMBER_LEGAL_KO
:
806 if (number
< 1 || number
>= 100)
808 natNum
= NativeNumberMode::NATNUM11
;
809 locale
.Language
= "ko";
813 lcl_formatKoreanLegalWord(number
, result
);
818 table
= table_CircledNumber
;
819 tableSize
= std::size(table_CircledNumber
);
822 table
= table_TianGan_zh
;
823 tableSize
= std::size(table_TianGan_zh
);
826 table
= table_DiZi_zh
;
827 tableSize
= std::size(table_DiZi_zh
);
829 case AIU_FULLWIDTH_JA
:
830 table
= table_AIUFullWidth_ja_JP
;
831 tableSize
= std::size(table_AIUFullWidth_ja_JP
);
832 bRecycleSymbol
= true;
834 case AIU_HALFWIDTH_JA
:
835 table
= table_AIUHalfWidth_ja_JP
;
836 tableSize
= std::size(table_AIUHalfWidth_ja_JP
);
837 bRecycleSymbol
= true;
839 case IROHA_FULLWIDTH_JA
:
840 table
= table_IROHAFullWidth_ja_JP
;
841 tableSize
= std::size(table_IROHAFullWidth_ja_JP
);
842 bRecycleSymbol
= true;
844 case IROHA_HALFWIDTH_JA
:
845 table
= table_IROHAHalfWidth_ja_JP
;
846 tableSize
= std::size(table_IROHAHalfWidth_ja_JP
);
847 bRecycleSymbol
= true;
850 table
= table_HangulJamo_ko
;
851 tableSize
= std::size(table_HangulJamo_ko
);
852 bRecycleSymbol
= true;
854 case HANGUL_SYLLABLE_KO
:
855 table
= table_HangulSyllable_ko
;
856 tableSize
= std::size(table_HangulSyllable_ko
);
857 bRecycleSymbol
= true;
859 case HANGUL_CIRCLED_JAMO_KO
:
860 table
= table_HangulCircledJamo_ko
;
861 tableSize
= std::size(table_HangulCircledJamo_ko
);
862 bRecycleSymbol
= true;
864 case HANGUL_CIRCLED_SYLLABLE_KO
:
865 table
= table_HangulCircledSyllable_ko
;
866 tableSize
= std::size(table_HangulCircledSyllable_ko
);
867 bRecycleSymbol
= true;
870 lcl_formatChars(table_Alphabet_ar
, std::size(table_Alphabet_ar
), number
- 1, result
);
872 case CHARS_ARABIC_ABJAD
:
873 lcl_formatChars(table_Alphabet_ar_abjad
, std::size(table_Alphabet_ar_abjad
), number
- 1, result
);
875 case NUMBER_ARABIC_INDIC
:
876 natNum
= NativeNumberMode::NATNUM1
;
877 locale
.Language
= "ar";
879 case NUMBER_EAST_ARABIC_INDIC
:
880 natNum
= NativeNumberMode::NATNUM1
;
881 locale
.Language
= "fa";
883 case NUMBER_INDIC_DEVANAGARI
:
884 natNum
= NativeNumberMode::NATNUM1
;
885 locale
.Language
= "hi";
888 lcl_formatChars(table_Alphabet_th
, std::size(table_Alphabet_th
), number
- 1, result
);
891 lcl_formatChars(table_Alphabet_he
, std::size(table_Alphabet_he
), number
- 1, result
);
894 natNum
= NativeNumberMode::NATNUM1
;
895 locale
.Language
= "he";
898 lcl_formatChars(table_Alphabet_ne
, std::size(table_Alphabet_ne
), number
- 1, result
);
901 lcl_formatChars(table_Alphabet_km
, std::size(table_Alphabet_km
), number
- 1, result
);
904 lcl_formatChars(table_Alphabet_lo
, std::size(table_Alphabet_lo
), number
- 1, result
);
907 lcl_formatChars(table_Alphabet_my
, std::size(table_Alphabet_my
), number
- 1, result
);
910 lcl_formatChars(table_Alphabet_dz
, std::size(table_Alphabet_dz
), number
- 1, result
);
912 case CHARS_CYRILLIC_UPPER_LETTER_BG
:
913 lcl_formatChars2( table_CyrillicUpperLetter_bg
,
914 table_CyrillicLowerLetter_bg
,
915 std::size(table_CyrillicLowerLetter_bg
), number
-1,
916 result
); // 1=>a, 2=>b, ..., 28=>z, 29=>Aa, 30=>Ab, ...
918 case CHARS_CYRILLIC_LOWER_LETTER_BG
:
919 lcl_formatChars( table_CyrillicLowerLetter_bg
,
920 std::size(table_CyrillicLowerLetter_bg
), number
-1,
921 result
); // 1=>a, 2=>b, ..., 28=>z, 29=>aa, 30=>ab, ...
923 case CHARS_CYRILLIC_UPPER_LETTER_N_BG
:
924 lcl_formatChars3( table_CyrillicUpperLetter_bg
,
925 table_CyrillicLowerLetter_bg
,
926 std::size(table_CyrillicLowerLetter_bg
), number
-1,
927 result
); // 1=>a, 2=>b, ..., 28=>z, 29=>Aa, 30=>Bb, ...
929 case CHARS_CYRILLIC_LOWER_LETTER_N_BG
:
930 lcl_formatChars1( table_CyrillicLowerLetter_bg
,
931 std::size(table_CyrillicLowerLetter_bg
), number
-1,
932 result
); // 1=>a, 2=>b, ..., 28=>z, 29=>aa, 30=>bb, ...
934 case CHARS_CYRILLIC_UPPER_LETTER_RU
:
935 lcl_formatChars2( table_CyrillicUpperLetter_ru
,
936 table_CyrillicLowerLetter_ru
,
937 std::size(table_CyrillicLowerLetter_ru
), number
-1,
938 result
); // 1=>a, 2=>b, ..., 27=>z, 28=>Aa, 29=>Ab, ...
940 case CHARS_CYRILLIC_LOWER_LETTER_RU
:
941 lcl_formatChars( table_CyrillicLowerLetter_ru
,
942 std::size(table_CyrillicLowerLetter_ru
), number
-1,
943 result
); // 1=>a, 2=>b, ..., 27=>z, 28=>aa, 29=>ab, ...
945 case CHARS_CYRILLIC_UPPER_LETTER_N_RU
:
946 lcl_formatChars3( table_CyrillicUpperLetter_ru
,
947 table_CyrillicLowerLetter_ru
,
948 std::size(table_CyrillicLowerLetter_ru
), number
-1,
949 result
); // 1=>a, 2=>b, ..., 27=>z, 28=>Aa, 29=>Bb, ...
951 case CHARS_CYRILLIC_LOWER_LETTER_N_RU
:
952 lcl_formatChars1( table_CyrillicLowerLetter_ru
,
953 std::size(table_CyrillicLowerLetter_ru
), number
-1,
954 result
); // 1=>a, 2=>b, ..., 27=>z, 28=>aa, 29=>bb, ...
956 case CHARS_CYRILLIC_UPPER_LETTER_SR
:
957 lcl_formatChars2( table_CyrillicUpperLetter_sr
,
958 table_CyrillicLowerLetter_sr
,
959 std::size(table_CyrillicLowerLetter_sr
), number
-1,
960 result
); // 1=>a, 2=>b, ..., 27=>z, 28=>Aa, 29=>Ab, ...
962 case CHARS_CYRILLIC_LOWER_LETTER_SR
:
963 lcl_formatChars( table_CyrillicLowerLetter_sr
,
964 std::size(table_CyrillicLowerLetter_sr
), number
-1,
965 result
); // 1=>a, 2=>b, ..., 27=>z, 28=>aa, 29=>ab, ...
967 case CHARS_CYRILLIC_UPPER_LETTER_N_SR
:
968 lcl_formatChars3( table_CyrillicUpperLetter_sr
,
969 table_CyrillicLowerLetter_sr
,
970 std::size(table_CyrillicLowerLetter_sr
), number
-1,
971 result
); // 1=>a, 2=>b, ..., 27=>z, 28=>Aa, 29=>Bb, ...
973 case CHARS_CYRILLIC_LOWER_LETTER_N_SR
:
974 lcl_formatChars1( table_CyrillicLowerLetter_sr
,
975 std::size(table_CyrillicLowerLetter_sr
), number
-1,
976 result
); // 1=>a, 2=>b, ..., 27=>z, 28=>aa, 29=>bb, ...
979 case CHARS_CYRILLIC_UPPER_LETTER_UK
:
980 lcl_formatChars2( table_CyrillicUpperLetter_uk
,
981 table_CyrillicLowerLetter_uk
,
982 std::size(table_CyrillicLowerLetter_uk
), number
-1,
985 case CHARS_CYRILLIC_LOWER_LETTER_UK
:
986 lcl_formatChars( table_CyrillicLowerLetter_uk
,
987 std::size(table_CyrillicLowerLetter_uk
), number
-1,
990 case CHARS_CYRILLIC_UPPER_LETTER_N_UK
:
991 lcl_formatChars3( table_CyrillicUpperLetter_uk
,
992 table_CyrillicLowerLetter_uk
,
993 std::size(table_CyrillicLowerLetter_uk
), number
-1,
996 case CHARS_CYRILLIC_LOWER_LETTER_N_UK
:
997 lcl_formatChars1( table_CyrillicLowerLetter_uk
,
998 std::size(table_CyrillicLowerLetter_uk
), number
-1,
1002 case CHARS_GREEK_LOWER_LETTER
:
1003 lcl_formatCharsGR( table_GreekLowerLetter
, number
, result
);
1006 case CHARS_GREEK_UPPER_LETTER
:
1007 lcl_formatCharsGR( table_GreekUpperLetter
, number
, result
);
1011 lcl_formatChars(table_Alphabet_fa
, std::size(table_Alphabet_fa
), number
- 1, result
);
1014 case CHARS_PERSIAN_WORD
:
1015 lcl_formatPersianWord(number
, result
);
1018 case SYMBOL_CHICAGO
:
1019 lcl_formatChars1( table_Chicago
, 4, number
-1, result
); // *, +, |, S, **, ++, ...
1023 result
+= lcl_formatArabicZero(number
, 2);
1027 result
+= lcl_formatArabicZero(number
, 3);
1031 result
+= lcl_formatArabicZero(number
, 4);
1035 result
+= lcl_formatArabicZero(number
, 5);
1038 case SZEKELY_ROVAS
: // Old Hungarian
1039 natNum
= NativeNumberMode::NATNUM12
;
1040 locale
.Language
= "hu-Hung";
1045 throw IllegalArgumentException();
1050 mxNatNum
.set(new NativeNumberSupplierService
);
1051 result
+= mxNatNum
->getNativeNumberStringParams(OUString::number(number
), locale
,
1052 natNum
, sNatNumParams
);
1053 } else if (tableSize
) {
1054 if ( number
> tableSize
&& !bRecycleSymbol
)
1055 result
+= OUString::number( number
);
1057 result
+= OUStringChar(table
[--number
% tableSize
]);
1061 if( !should_ignore(suffix
) ) result
+= suffix
;
1066 #define LANG_ALL (1 << 0)
1067 #define LANG_CJK (1 << 1)
1068 #define LANG_CTL (1 << 2)
1070 struct Supported_NumberingType
1072 const char* cSymbol
;
1074 sal_Int16 langOption
;
1075 Supported_NumberingType(sal_Int16 nType_
, const char* pSymbol
, sal_Int16 opt
)
1076 : cSymbol(pSymbol
), nType(nType_
), langOption(opt
) {}
1078 const Supported_NumberingType aSupportedTypes
[] =
1080 {style::NumberingType::CHARS_UPPER_LETTER
, "A", LANG_ALL
},
1081 {style::NumberingType::CHARS_LOWER_LETTER
, "a", LANG_ALL
},
1082 {style::NumberingType::ROMAN_UPPER
, "I", LANG_ALL
},
1083 {style::NumberingType::ROMAN_LOWER
, "i", LANG_ALL
},
1084 {style::NumberingType::ARABIC
, "1", LANG_ALL
},
1085 {style::NumberingType::NUMBER_NONE
, "''", LANG_ALL
},
1086 {style::NumberingType::CHAR_SPECIAL
, "Bullet", LANG_ALL
},
1087 {style::NumberingType::PAGE_DESCRIPTOR
, "Page", LANG_ALL
},
1088 {style::NumberingType::BITMAP
, "Bitmap", LANG_ALL
},
1089 {style::NumberingType::SYMBOL_CHICAGO
, "*, " S_DAGGER
", " S_DBL_DAGGER
", " S_SECTION
", **, " S_DAGGER S_DAGGER
", ...", LANG_ALL
},
1090 {style::NumberingType::TEXT_NUMBER
, "1st", LANG_ALL
},
1091 {style::NumberingType::TEXT_CARDINAL
, "One", LANG_ALL
},
1092 {style::NumberingType::TEXT_ORDINAL
, "First", LANG_ALL
},
1093 {style::NumberingType::CHARS_UPPER_LETTER_N
, "AAA", LANG_ALL
},
1094 {style::NumberingType::CHARS_LOWER_LETTER_N
, "aaa", LANG_ALL
},
1095 {style::NumberingType::NATIVE_NUMBERING
, "Native Numbering", LANG_CJK
|LANG_CTL
},
1096 {style::NumberingType::FULLWIDTH_ARABIC
, nullptr, LANG_CJK
},
1097 {style::NumberingType::CIRCLE_NUMBER
, nullptr, LANG_CJK
},
1098 // The cSymbol is defined here for compatibility with files created by old releases.
1099 // Otherwise if nullptr, these 3 digits may change as NATNUM12 depends on 3rd-party lib.
1100 {style::NumberingType::NUMBER_LOWER_ZH
, "一, 二, 三, ...", LANG_CJK
},
1101 {style::NumberingType::NUMBER_UPPER_ZH
, nullptr, LANG_CJK
},
1102 {style::NumberingType::NUMBER_UPPER_ZH_TW
, nullptr, LANG_CJK
},
1103 {style::NumberingType::TIAN_GAN_ZH
, nullptr, LANG_CJK
},
1104 {style::NumberingType::DI_ZI_ZH
, nullptr, LANG_CJK
},
1105 {style::NumberingType::NUMBER_TRADITIONAL_JA
, nullptr, LANG_CJK
},
1106 {style::NumberingType::AIU_FULLWIDTH_JA
, nullptr, LANG_CJK
},
1107 {style::NumberingType::AIU_HALFWIDTH_JA
, nullptr, LANG_CJK
},
1108 {style::NumberingType::IROHA_FULLWIDTH_JA
, nullptr, LANG_CJK
},
1109 {style::NumberingType::IROHA_HALFWIDTH_JA
, nullptr, LANG_CJK
},
1110 {style::NumberingType::NUMBER_UPPER_KO
, nullptr, LANG_CJK
},
1111 {style::NumberingType::NUMBER_HANGUL_KO
, nullptr, LANG_CJK
},
1112 {style::NumberingType::HANGUL_JAMO_KO
, nullptr, LANG_CJK
},
1113 {style::NumberingType::HANGUL_SYLLABLE_KO
, nullptr, LANG_CJK
},
1114 {style::NumberingType::HANGUL_CIRCLED_JAMO_KO
, nullptr, LANG_CJK
},
1115 {style::NumberingType::HANGUL_CIRCLED_SYLLABLE_KO
, nullptr, LANG_CJK
},
1116 {style::NumberingType::NUMBER_LEGAL_KO
, nullptr, LANG_CJK
},
1117 {style::NumberingType::NUMBER_DIGITAL_KO
, nullptr, LANG_CJK
},
1118 {style::NumberingType::NUMBER_DIGITAL2_KO
, nullptr, LANG_CJK
},
1119 {style::NumberingType::CHARS_ARABIC
, nullptr, LANG_CTL
},
1120 {style::NumberingType::CHARS_ARABIC_ABJAD
, nullptr, LANG_CTL
},
1121 {style::NumberingType::NUMBER_ARABIC_INDIC
, S_AR_ONE
", " S_AR_TWO
", " S_AR_THREE
", ...", LANG_CTL
},
1122 {style::NumberingType::NUMBER_EAST_ARABIC_INDIC
, S_FA_ONE
", " S_FA_TWO
", " S_FA_THREE
", ...", LANG_CTL
},
1123 {style::NumberingType::NUMBER_INDIC_DEVANAGARI
, S_HI_ONE
", " S_HI_TWO
", " S_HI_THREE
", ...", LANG_CTL
},
1124 {style::NumberingType::CHARS_THAI
, nullptr, LANG_CTL
},
1125 {style::NumberingType::CHARS_HEBREW
, nullptr, LANG_CTL
},
1126 {style::NumberingType::NUMBER_HEBREW
, S_HE_ALEPH
", " S_HE_YOD
", " S_HE_QOF
", ...", LANG_CTL
},
1127 {style::NumberingType::CHARS_NEPALI
, nullptr, LANG_CTL
},
1128 {style::NumberingType::CHARS_KHMER
, nullptr, LANG_CTL
},
1129 {style::NumberingType::CHARS_LAO
, nullptr, LANG_CTL
},
1130 {style::NumberingType::CHARS_MYANMAR
, nullptr, LANG_CTL
},
1131 {style::NumberingType::CHARS_TIBETAN
, nullptr, LANG_CTL
},
1132 {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
},
1133 {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
},
1134 {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
},
1135 {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
},
1136 {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
},
1137 {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
},
1138 {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
},
1139 {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
},
1140 {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
},
1141 {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
},
1142 {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
},
1143 {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
},
1144 {style::NumberingType::CHARS_CYRILLIC_UPPER_LETTER_UK
, C_CYR_A
", " C_CYR_B
", .., " C_CYR_A S_CYR_A
", " C_CYR_A S_CYR_B
", ... (uk)", LANG_ALL
},
1145 {style::NumberingType::CHARS_CYRILLIC_LOWER_LETTER_UK
, S_CYR_A
", " S_CYR_B
", .., " S_CYR_A S_CYR_A
", " S_CYR_A S_CYR_B
", ... (uk)", LANG_ALL
},
1146 {style::NumberingType::CHARS_CYRILLIC_UPPER_LETTER_N_UK
, C_CYR_A
", " C_CYR_B
", .., " C_CYR_A S_CYR_A
", " C_CYR_B S_CYR_B
", ... (uk)", LANG_ALL
},
1147 {style::NumberingType::CHARS_CYRILLIC_LOWER_LETTER_N_UK
, S_CYR_A
", " S_CYR_B
", .., " S_CYR_A S_CYR_A
", " S_CYR_B S_CYR_B
", ... (uk)", LANG_ALL
},
1148 {style::NumberingType::CHARS_PERSIAN
, nullptr, LANG_CTL
},
1149 {style::NumberingType::CHARS_PERSIAN_WORD
, nullptr, LANG_CTL
},
1150 {style::NumberingType::SZEKELY_ROVAS
, nullptr, LANG_CTL
},
1151 {style::NumberingType::CHARS_GREEK_UPPER_LETTER
, C_GR_A
", " C_GR_B
", ... (gr)", LANG_ALL
},
1152 {style::NumberingType::CHARS_GREEK_LOWER_LETTER
, S_GR_A
", " S_GR_B
", ... (gr)", LANG_ALL
},
1153 {style::NumberingType::ARABIC_ZERO
, "01, 02, 03, ...", LANG_ALL
},
1154 {style::NumberingType::ARABIC_ZERO3
, "001, 002, 003, ...", LANG_ALL
},
1155 {style::NumberingType::ARABIC_ZERO4
, "0001, 0002, 0003, ...", LANG_ALL
},
1156 {style::NumberingType::ARABIC_ZERO5
, "00001, 00002, 00003, ...", LANG_ALL
},
1158 const sal_Int32 nSupported_NumberingTypes
= std::size(aSupportedTypes
);
1160 OUString
DefaultNumberingProvider::makeNumberingIdentifier(sal_Int16 index
)
1162 if (index
< 0 || index
>= nSupported_NumberingTypes
)
1163 throw RuntimeException();
1165 if (aSupportedTypes
[index
].cSymbol
)
1166 return OUString(aSupportedTypes
[index
].cSymbol
, strlen(aSupportedTypes
[index
].cSymbol
), RTL_TEXTENCODING_UTF8
);
1168 OUStringBuffer result
;
1169 Locale
aLocale(u
"en"_ustr
, OUString(), OUString());
1170 Sequence
<beans::PropertyValue
> aProperties(2);
1171 auto aPropertiesRange
= asNonConstRange(aProperties
);
1172 aPropertiesRange
[0].Name
= "NumberingType";
1173 aPropertiesRange
[0].Value
<<= aSupportedTypes
[index
].nType
;
1174 aPropertiesRange
[1].Name
= "Value";
1175 for (sal_Int32 j
= 1; j
<= 3; j
++) {
1176 aPropertiesRange
[1].Value
<<= j
;
1177 result
.append( makeNumberingString( aProperties
, aLocale
) + ", " );
1179 result
.append("...");
1180 // Make known duplicate generated identifiers unique.
1181 // Note this alone works only for newly added numberings, if duplicates
1182 // are in the wild further handling is needed when loading documents
1183 // and asking for numberings.
1184 switch (aSupportedTypes
[index
].nType
)
1186 case css::style::NumberingType::NUMBER_DIGITAL_KO
:
1187 // Duplicate of NUMBER_HANGUL_KO.
1188 result
.append(" (ko-x-digital)");
1190 case css::style::NumberingType::NUMBER_DIGITAL2_KO
:
1191 // Duplicate of NUMBER_LOWER_ZH.
1192 result
.append(" (ko)");
1197 return result
.makeStringAndClear();
1202 DefaultNumberingProvider::isScriptFlagEnabled(const OUString
& aName
)
1204 if (! xHierarchicalNameAccess
.is())
1205 xHierarchicalNameAccess
= officecfg::Office::Common::I18N::get();
1207 Any aEnabled
= xHierarchicalNameAccess
->getByHierarchicalName(aName
);
1209 bool enabled
= false;
1211 aEnabled
>>= enabled
;
1216 Sequence
< sal_Int16
> DefaultNumberingProvider::getSupportedNumberingTypes( )
1218 Sequence
< sal_Int16
> aRet(nSupported_NumberingTypes
);
1219 sal_Int16
* pArray
= aRet
.getArray();
1221 bool cjkEnabled
= isScriptFlagEnabled(u
"CJK/CJKFont"_ustr
);
1222 bool ctlEnabled
= isScriptFlagEnabled(u
"CTL/CTLFont"_ustr
);
1224 for(sal_Int16 i
= 0; i
< nSupported_NumberingTypes
; i
++) {
1225 if ( (aSupportedTypes
[i
].langOption
& LANG_ALL
) ||
1226 ((aSupportedTypes
[i
].langOption
& LANG_CJK
) && cjkEnabled
) ||
1227 ((aSupportedTypes
[i
].langOption
& LANG_CTL
) && ctlEnabled
) )
1228 pArray
[i
] = aSupportedTypes
[i
].nType
;
1233 sal_Int16
DefaultNumberingProvider::getNumberingType( const OUString
& rNumberingIdentifier
)
1235 auto it
= maSupportedTypesCache
.find(rNumberingIdentifier
);
1236 if (it
!= maSupportedTypesCache
.end())
1237 return it
->second
->nType
;
1238 for(sal_Int16 i
= 0; i
< nSupported_NumberingTypes
; i
++)
1239 if(rNumberingIdentifier
== makeNumberingIdentifier(i
))
1241 maSupportedTypesCache
.emplace(rNumberingIdentifier
, &aSupportedTypes
[i
]);
1242 return aSupportedTypes
[i
].nType
;
1244 throw RuntimeException();
1247 sal_Bool
DefaultNumberingProvider::hasNumberingType( const OUString
& rNumberingIdentifier
)
1249 auto it
= maSupportedTypesCache
.find(rNumberingIdentifier
);
1250 if (it
!= maSupportedTypesCache
.end())
1252 for(sal_Int16 i
= 0; i
< nSupported_NumberingTypes
; i
++)
1253 if(rNumberingIdentifier
== makeNumberingIdentifier(i
))
1255 maSupportedTypesCache
.emplace(rNumberingIdentifier
, &aSupportedTypes
[i
]);
1261 OUString
DefaultNumberingProvider::getNumberingIdentifier( sal_Int16 nNumberingType
)
1263 for(sal_Int16 i
= 0; i
< nSupported_NumberingTypes
; i
++)
1264 if(nNumberingType
== aSupportedTypes
[i
].nType
)
1265 return makeNumberingIdentifier(i
);
1269 OUString
DefaultNumberingProvider::getImplementationName()
1271 return u
"com.sun.star.text.DefaultNumberingProvider"_ustr
;
1274 sal_Bool
DefaultNumberingProvider::supportsService(const OUString
& rServiceName
)
1276 return cppu::supportsService(this, rServiceName
);
1279 Sequence
< OUString
> DefaultNumberingProvider::getSupportedServiceNames()
1281 Sequence
< OUString
> aRet
{ u
"com.sun.star.text.DefaultNumberingProvider"_ustr
};
1287 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
1288 com_sun_star_text_DefaultNumberingProvider_get_implementation(
1289 css::uno::XComponentContext
*context
,
1290 css::uno::Sequence
<css::uno::Any
> const &)
1292 return cppu::acquire(new i18npool::DefaultNumberingProvider(context
));
1295 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */