update emoji autocorrect entries from po-files
[LibreOffice.git] / i18npool / source / defaultnumberingprovider / defaultnumberingprovider.cxx
bloba38cb75c05c1b20b488987d5fff542817604c44f
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 <com/sun/star/style/NumberingType.hpp>
22 #include <com/sun/star/beans/PropertyValue.hpp>
23 #include <com/sun/star/configuration/theDefaultProvider.hpp>
24 #include <com/sun/star/text/HoriOrientation.hpp>
25 #include <osl/diagnose.h>
26 #include <localedata.hxx>
27 #include <nativenumbersupplier.hxx>
28 #include <stdio.h>
29 #include <string.h>
30 #include <cppuhelper/supportsservice.hxx>
32 // Cyrillic upper case
33 #define C_CYR_A "\xD0\x90"
34 #define C_CYR_B "\xD0\x91"
35 // Cyrillic lower case
36 #define S_CYR_A "\xD0\xB0"
37 #define S_CYR_B "\xD0\xB1"
39 //Greek upper case
40 #define C_GR_A "\xCE\x91"
41 #define C_GR_B "\xCE\x92"
42 //Greek lower case
43 #define S_GR_A "\xCE\xB1"
44 #define S_GR_B "\xCE\xB2"
46 #include <math.h>
47 #include <sal/macros.h>
48 #include <rtl/ustring.hxx>
49 #include <rtl/ustrbuf.hxx>
50 #include <com/sun/star/i18n/XTransliteration.hpp>
51 #include <com/sun/star/i18n/TransliterationType.hpp>
52 #include <com/sun/star/i18n/TransliterationModulesNew.hpp>
53 #include <com/sun/star/i18n/XLocaleData.hpp>
55 #include <bullet.h>
57 using namespace com::sun::star;
58 using namespace com::sun::star::uno;
59 using namespace com::sun::star::lang;
61 namespace com { namespace sun { namespace star { namespace i18n {
63 static const sal_Unicode table_Alphabet_ar[] = {
64 0x0623, 0x0628, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E,
65 0x062F, 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635,
66 0x0636, 0x0637, 0x0638, 0x0639, 0x063A, 0x0641, 0x0642,
67 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649
70 static const sal_Unicode table_Alphabet_ar_abjad[] = {
71 0x0627, 0x0628, 0x062c, 0x062f, 0x0647, 0x0648, 0x0632, 0x062d,
72 0x0637, 0x064a, 0x0643, 0x0644, 0x0645, 0x0646, 0x0633, 0x0639,
73 0x0641, 0x0635, 0x0642, 0x0631, 0x0634, 0x062a, 0x062b, 0x062e,
74 0x0630, 0x0636, 0x0638, 0x063a
77 static const sal_Unicode table_Alphabet_th[] = {
78 0x0E01, 0x0E02, 0x0E04, 0x0E07,
79 0x0E08, 0x0E09, 0x0E0A, 0x0E0B, 0x0E0C, 0x0E0D, 0x0E0E, 0x0E0F,
80 0x0E10, 0x0E11, 0x0E12, 0x0E13, 0x0E14, 0x0E15, 0x0E16, 0x0E17,
81 0x0E18, 0x0E19, 0x0E1A, 0x0E1B, 0x0E1C, 0x0E1D, 0x0E1E, 0x0E1F,
82 0x0E20, 0x0E21, 0x0E22, 0x0E23, 0x0E24, 0x0E25, 0x0E26, 0x0E27,
83 0x0E28, 0x0E29, 0x0E2A, 0x0E2B, 0x0E2C, 0x0E2D, 0x0E2E
86 static const sal_Unicode table_Alphabet_he[] = {
87 0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7,
88 0x05D8, 0x05D9, 0x05DB, 0x05DC, 0x05DE, 0x05E0, 0x05E1, 0x05E2,
89 0x05E4, 0x05E6, 0x05E7, 0x05E8, 0x05E9, 0x05EA
92 static const sal_Unicode table_Alphabet_ne[] = {
93 0x0915, 0x0916, 0x0917, 0x0918, 0x0919, 0x091A, 0x091B, 0x091C,
94 0x091D, 0x091E, 0x091F, 0x0920, 0x0921, 0x0922, 0x0923, 0x0924,
95 0x0925, 0x0926, 0x0927, 0x0928, 0x092A, 0x092B, 0x092C, 0x092D,
96 0x092E, 0x092F, 0x0930, 0x0932, 0x0935, 0x0936, 0x0937, 0x0938,
97 0x0939
100 static const sal_Unicode table_Alphabet_km[] = {
101 0x1780, 0x1781, 0x1782, 0x1783, 0x1784, 0x1785, 0x1786, 0x1787,
102 0x1788, 0x1789, 0x178A, 0x178B, 0x178C, 0x178D, 0x178E, 0x178F,
103 0x1790, 0x1791, 0x1792, 0x1793, 0x1794, 0x1795, 0x1796, 0x1797,
104 0x1798, 0x1799, 0x179A, 0x179B, 0x179C, 0x179F,
105 0x17A0, 0x17A1, 0x17A2
108 static const sal_Unicode table_Alphabet_lo[] = {
109 0x0E81, 0x0E82, 0x0E84, 0x0E87, 0x0E88, 0x0E8A, 0x0E8D, 0x0E94,
110 0x0E95, 0x0E96, 0x0E97, 0x0E99, 0x0E9A, 0x0E9B, 0x0E9C,
111 0x0E9D, 0x0E9E, 0x0E9F, 0x0EA1, 0x0EA2, 0x0EA3, 0x0EA5, 0x0EA7,
112 0x0EAA, 0x0EAB, 0x0EAD, 0x0EAE, 0x0EAF, 0x0EAE, 0x0EDC, 0x0EDD
115 static const sal_Unicode table_Alphabet_dz[] = {
116 0x0F40, 0x0F41, 0x0F42, 0x0F44, 0x0F45, 0x0F46, 0x0F47, 0x0F49,
117 0x0F4F, 0x0F50, 0x0F51, 0x0F53, 0x0F54, 0x0F55, 0x0F56, 0x0F58,
118 0x0F59, 0x0F5A, 0x0F5B, 0x0F5D, 0x0F5E, 0x0F5F, 0x0F60, 0x0F61,
119 0x0F62, 0x0F63, 0x0F64, 0x0F66, 0x0F67, 0x0F68
122 static const sal_Unicode table_Alphabet_my[] = {
123 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006, 0x1007,
124 0x1008,/*0x1009,*/0x100A, 0x100B, 0x100C, 0x100D, 0x100E, 0x100F,
125 0x1010, 0x1011, 0x1012, 0x1013, 0x1014, 0x1015, 0x1016, 0x1017,
126 0x1018, 0x1019, 0x101A, 0x101B, 0x101C, 0x101D, 0x101E, 0x101F,
127 0x1020, 0x1021
130 // Bulgarian Cyrillic upper case letters
131 static const sal_Unicode table_CyrillicUpperLetter_bg[] = {
132 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418,
133 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, 0x0420, 0x0421, 0x0422,
134 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042E,
135 0x042F
138 // Bulgarian cyrillic lower case letters
139 static const sal_Unicode table_CyrillicLowerLetter_bg[] = {
140 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438,
141 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F, 0x0440, 0x0441, 0x0442,
142 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044E,
143 0x044F
146 // Russian Cyrillic upper letters
147 static const sal_Unicode table_CyrillicUpperLetter_ru[] = {
148 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
149 0x0418, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, 0x0420,
150 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428,
151 0x0429, 0x042B, 0x042D, 0x042E, 0x042F
154 // Russian cyrillic lower letters
155 static const sal_Unicode table_CyrillicLowerLetter_ru[] = {
156 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
157 0x0438, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F, 0x0440,
158 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448,
159 0x0449, 0x044B, 0x044D, 0x044E, 0x044F
162 // Serbian Cyrillic upper letters
163 static const sal_Unicode table_CyrillicUpperLetter_sr[] = {
164 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0402, 0x0415, 0x0416,
165 0x0417, 0x0418, 0x0408, 0x041A, 0x041B, 0x0409, 0x041C, 0x041D,
166 0x040A, 0x041E, 0x041F, 0x0420, 0x0421, 0x0422, 0x040B, 0x0423,
167 0x0424, 0x0425, 0x0426, 0x0427, 0x040F, 0x0428
170 // Serbian cyrillic lower letters
171 static const sal_Unicode table_CyrillicLowerLetter_sr[] = {
172 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0452, 0x0435, 0x0436,
173 0x0437, 0x0438, 0x0458, 0x043A, 0x043B, 0x0459, 0x043C, 0x043D,
174 0x045A, 0x043E, 0x043F, 0x0440, 0x0441, 0x0442, 0x045B, 0x0443,
175 0x0444, 0x0445, 0x0446, 0x0447, 0x045F, 0x0448
178 static const sal_Unicode table_GreekUpperLetter[] = {
179 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x03DB, 0x0396, 0x0397, 0x0398,
180 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0, 0x03DF,
181 0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, 0x03E0
184 static const sal_Unicode table_GreekLowerLetter[] = {
185 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03DB, 0x03B6, 0x03B7, 0x03B8,
186 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, 0x03DF,
187 0x03C1, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8, 0x03C9, 0x03E1
190 static const sal_Unicode table_Alphabet_fa[] = {
191 0x0622, 0x0628, 0x067E, 0x062A, 0x062B, 0x062C, 0x0686, 0x062D,
192 0x062E, 0x062F, 0x0630, 0x0631, 0x0632, 0x0698, 0x0633, 0x0634,
193 0x0635, 0x0636, 0x0637, 0x0638, 0x0639, 0x0640, 0x0641, 0x0642,
194 0x06A9, 0x06AF, 0x0644, 0x0645, 0x0646, 0x0648, 0x0647, 0x06CC
197 static const sal_Unicode upperLetter[] = {
198 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
199 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52,
200 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A
203 static const sal_Unicode lowerLetter[] = {
204 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
205 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72,
206 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A
209 // Tables used for numbering in persian words
210 static const sal_Unicode table_PersianWord_decade1[][7]={
211 {0}, // 0
212 {0x06cc, 0x06a9, 0}, // 1
213 {0x062f, 0x0648, 0}, // 2
214 {0x0633, 0x0647, 0}, // 3
215 {0x0686, 0x0647, 0x0627, 0x0631, 0}, // 4
216 {0x067e, 0x0646, 0x062c, 0}, // 5
217 {0x0634, 0x0634, 0}, // 6
218 {0x0647, 0x0641, 0x062a, 0}, // 7
219 {0x0647, 0x0634, 0x062a, 0}, // 8
220 {0x0646, 0x0647, 0}, // 9
221 {0x062f, 0x0647, 0}, // 10
222 {0x06cc, 0x0627, 0x0632, 0x062f, 0x0647, 0}, // 11
223 {0x062f, 0x0648, 0x0627, 0x0632, 0x062f, 0x0647, 0}, // 12
224 {0x0633, 0x06cc, 0x0632, 0x062f, 0x0647, 0}, // 13
225 {0x0686, 0x0647, 0x0627, 0x0631, 0x062f, 0x0647, 0}, // 14
226 {0x067e, 0x0627, 0x0646, 0x0632, 0x062f, 0x0647, 0}, // 15
227 {0x0634, 0x0627, 0x0646, 0x0632, 0x062f, 0x0647, 0}, // 16
228 {0x0647, 0x0641, 0x062f, 0x0647, 0}, // 17
229 {0x0647, 0x062c, 0x062f, 0x0647, 0}, // 18
230 {0x0646, 0x0648, 0x0632, 0x062f, 0x0647, 0} // 19
233 static const sal_Unicode table_PersianWord_decade2[][6]={
234 {0x0628, 0x06cc, 0x0633, 0x062a, 0}, // 20
235 {0x0633, 0x06cc, 0}, // 30
236 {0x0686, 0x0647, 0x0644, 0}, // 40
237 {0x067e, 0x0646, 0x062c, 0x0627, 0x0647, 0}, // 50
238 {0x0634, 0x0635, 0x062a, 0}, // 60
239 {0x0647, 0x0641, 0x062a, 0x0627, 0x062f, 0}, // 70
240 {0x0647, 0x0634, 0x062a, 0x0627, 0x062f, 0}, // 80
241 {0x0646, 0x0648, 0x062f, 0} // 90
244 static const sal_Unicode table_PersianWord_decade3[][7]={
245 {0x0635, 0x062f, 0}, // 100
246 {0x062f, 0x0648, 0x06cc, 0x0633, 0x062a, 0}, // 200
247 {0x0633, 0x06cc, 0x0635, 0x062f, 0}, // 300
248 {0x0686, 0x0647, 0x0627, 0x0631, 0x0635, 0x062f, 0}, // 400
249 {0x067e, 0x0627, 0x0646, 0x0635, 0x062f, 0}, // 500
250 {0x0634, 0x0635, 0x062f, 0}, // 600
251 {0x0647, 0x0641, 0x062a, 0x0635, 0x062f, 0}, // 700
252 {0x0647, 0x0634, 0x062a, 0x0635, 0x062f, 0}, // 800
253 {0x0646, 0x0647, 0x0635, 0x062f, 0} // 900
256 static const sal_Unicode table_PersianWord_decadeX[][8]={
257 {0x0647, 0x0632, 0x0627, 0x0631, 0}, // 1000
258 {0x0645, 0x06cc, 0x0644, 0x06cc, 0x0648, 0x0646, 0}, // 1000000
259 {0x0645, 0x06cc, 0x0644, 0x06cc, 0x0627, 0x0631, 0x062f, 0} // 1000000000
263 DefaultNumberingProvider::DefaultNumberingProvider( const Reference < XComponentContext >& rxContext ) : m_xContext(rxContext),translit(NULL)
268 DefaultNumberingProvider::~DefaultNumberingProvider()
270 delete translit;
273 void DefaultNumberingProvider::impl_loadTranslit()
275 if ( !translit )
276 translit = new TransliterationImpl(m_xContext);
279 Sequence< Reference<container::XIndexAccess> >
280 DefaultNumberingProvider::getDefaultOutlineNumberings(const Locale& rLocale ) throw(RuntimeException, std::exception)
282 return LocaleDataImpl().getOutlineNumberingLevels( rLocale );
285 Sequence< Sequence<beans::PropertyValue> >
286 DefaultNumberingProvider::getDefaultContinuousNumberingLevels( const Locale& rLocale ) throw(RuntimeException, std::exception)
288 return LocaleDataImpl().getContinuousNumberingLevels( rLocale );
291 OUString toRoman( sal_Int32 n )
294 // i, ii, iii, iv, v, vi, vii, vii, viii, ix
295 // (Dummy),1000,500,100,50,10,5,1
296 static const sal_Char coRomanArr[] = "MDCLXVI--"; // +2 Dummy entries !!
297 const sal_Char* cRomanStr = coRomanArr;
298 sal_uInt16 nMask = 1000;
299 sal_uInt32 nOver1000 = n / nMask;
300 n -= ( nOver1000 * nMask );
302 OUStringBuffer sTmp;
303 while(nOver1000--)
304 sTmp.append(*coRomanArr);
306 while( nMask )
308 sal_uInt8 nZahl = sal_uInt8( n / nMask );
309 sal_uInt8 nDiff = 1;
310 n %= nMask;
312 if( 5 < nZahl )
314 if( nZahl < 9 )
315 sTmp.append(*(cRomanStr-1));
316 ++nDiff;
317 nZahl -= 5;
319 switch( nZahl )
321 case 3: sTmp.append(*cRomanStr); //no break!
322 case 2: sTmp.append(*cRomanStr); //no break!
323 case 1: sTmp.append(*cRomanStr); break;
324 case 4: sTmp.append(*cRomanStr).append(*(cRomanStr-nDiff)); break;
325 case 5: sTmp.append(*(cRomanStr-nDiff)); break;
328 nMask /= 10; // to the next decade
329 cRomanStr += 2;
331 return sTmp.makeStringAndClear();
334 // not used:
336 static
337 void lcl_formatChars( const sal_Unicode table[], int tableSize, int n, OUString& s )
339 // string representation of n is appended to s.
340 // if A=='A' then 0=>A, 1=>B, ..., 25=>Z, 26=>AA, 27=>AB, ...
341 // if A=='a' then 0=>a, 1=>b, ..., 25=>z, 26=>aa, 27=>ab, ...
343 if( n>=tableSize ) lcl_formatChars( table, tableSize, (n-tableSize)/tableSize, s );
345 s += OUString( table[ n % tableSize ] );
348 static
349 void lcl_formatChars1( const sal_Unicode table[], int tableSize, int n, OUString& s )
351 // string representation of n is appended to s.
352 // if A=='A' then 0=>A, 1=>B, ..., 25=>Z, 26=>AA, 27=>BB, ...
353 // if A=='a' then 0=>a, 1=>b, ..., 25=>z, 26=>aa, 27=>bb, ...
355 int repeat_count = n / tableSize + 1;
357 for( int i=0; i<repeat_count; i++ )
358 s += OUString( table[ n%tableSize ] );
361 static
362 void lcl_formatChars2( const sal_Unicode table_capital[], const sal_Unicode table_small[], int tableSize, int n, OUString& s )
364 // string representation of n is appended to s.
365 // if A=='A' then 0=>A, 1=>B, ..., 25=>Z, 26=>Aa, 27=>Ab, ...
367 if( n>=tableSize )
369 lcl_formatChars2( table_capital, table_small, tableSize, (n-tableSize)/tableSize, s );
370 s += OUString( table_small[ n % tableSize ] );
371 } else
372 s += OUString( table_capital[ n % tableSize ] );
375 static
376 void lcl_formatChars3( const sal_Unicode table_capital[], const sal_Unicode table_small[], int tableSize, int n, OUString& s )
378 // string representation of n is appended to s.
379 // if A=='A' then 0=>A, 1=>B, ..., 25=>Z, 26=>Aa, 27=>Bb, ...
381 int repeat_count = n / tableSize + 1;
382 s += OUString( table_capital[ n%tableSize ] );
384 for( int i=1; i<repeat_count; i++ )
385 s += OUString( table_small[ n%tableSize ] );
389 /** Returns number's representation in persian words up to 999999999999
390 respectively limited by sal_Int32 >=0.
391 The caller assures that nNumber is not negative.
393 static
394 void lcl_formatPersianWord( sal_Int32 nNumber, OUString& rsResult )
395 throw( IllegalArgumentException, RuntimeException )
397 OUStringBuffer aTemp(64);
398 static const sal_Unicode asPersianWord_conjunction_data[] = {0x20,0x0648,0x20,0};
399 OUString asPersianWord_conjunction( asPersianWord_conjunction_data );
400 unsigned char nSection = 0;
402 while (int nPart = nNumber % 1000)
404 if (nSection)
406 if (nSection > SAL_N_ELEMENTS( table_PersianWord_decadeX))
407 throw IllegalArgumentException(); // does not happen with sal_Int32
408 aTemp.insert( 0, asPersianWord_conjunction).insert( 0, table_PersianWord_decadeX[nSection-1]);
411 unsigned int nDigit;
412 if ((nDigit = nPart % 100) < 20)
414 if (!aTemp.isEmpty())
415 aTemp.insert( 0, sal_Unicode(0x0020));
416 aTemp.insert( 0, table_PersianWord_decade1[nDigit]);
418 else
420 if ((nDigit = nPart % 10) != 0)
422 if (!aTemp.isEmpty())
423 aTemp.insert( 0, asPersianWord_conjunction);
424 aTemp.insert( 0, table_PersianWord_decade1[nDigit]);
426 if ((nDigit = (nPart / 10) % 10) != 0)
428 if (!aTemp.isEmpty())
429 aTemp.insert( 0, asPersianWord_conjunction);
430 aTemp.insert( 0, table_PersianWord_decade2[nDigit-2]);
434 if ((nDigit = nPart / 100) != 0)
436 if (!aTemp.isEmpty())
437 aTemp.insert( 0, asPersianWord_conjunction);
438 aTemp.insert( 0, table_PersianWord_decade3[nDigit-1]);
441 nNumber /= 1000;
442 nSection++;
444 rsResult += aTemp.makeStringAndClear();
448 // Greek Letter Numbering
450 // KERAIA separates numerals from other text
451 #define STIGMA (sal_Unicode) 0x03DB
452 #define LEFT_KERAIA (sal_Unicode) 0x0375
453 #define MYRIAD_SYM (sal_Unicode) 0x039C
454 #define DOT_SYM (sal_Unicode) 0x002E
455 #define SIGMA_OFFSET 19
456 #define TAU_OFFSET 20
457 #define MYRIAD 10000
460 * Return the 1-999999 number's representation in the Greek numbering system.
461 * Adding a "left keraia" to represent numbers in the range 10000 ... 999999 is
462 * not orthodox, so it's better to use the myriad notation and call this method
463 * only for numbers up to 9999.
465 static
466 OUString gr_smallNum(const sal_Unicode table[], int n)
468 if (n > 9999)
469 throw IllegalArgumentException();
471 int i = 0;
472 OUStringBuffer sb;
473 for (int v = n; v > 0; v /= 10, i++) {
474 int digit = v % 10;
475 if (digit == 0)
476 continue;
478 sal_Unicode sign = table[(digit - 1) + 9 * (i % 3)];
479 if (sign == STIGMA) {
480 sb.insert(0, table[TAU_OFFSET]);
481 sb.insert(0, table[SIGMA_OFFSET]);
482 } else {
483 sb.insert(0, sign);
486 if (i > 2)
487 sb.insert(0, LEFT_KERAIA);
490 return sb.makeStringAndClear();
493 static
494 void lcl_formatCharsGR(const sal_Unicode table[], int n, OUString& s )
496 OUStringBuffer sb;
497 int myriadPower = 2;
499 for (int divisor = MYRIAD * MYRIAD; divisor > 1; divisor /= MYRIAD, myriadPower--) {
500 if (n > divisor - 1) {
502 * Follow the Diophantus representation of:
503 * A myriad sign, M(10000) as many times as the power
504 * followed by the multiplier for the myriad
505 * followed by a dot
506 * followed by the rest
507 * This is enough for 32-bit integers
509 for (int i = 0; i < myriadPower; i++)
510 sb.append(MYRIAD_SYM);
512 sb.append(gr_smallNum(table, n/divisor));
513 n %= divisor;
515 if (n > 0)
516 sb.append(DOT_SYM);
519 sb.append(gr_smallNum(table,n));
521 s += sb.makeStringAndClear();
524 static
525 bool should_ignore( const OUString& s )
527 // return true if blank or null
528 return s == " " || (!s.isEmpty() && s[0]==0);
531 static
532 Any getPropertyByName( const Sequence<beans::PropertyValue>& aProperties,
533 const char* name, bool bRequired )
535 for( int i=0; i<aProperties.getLength(); i++ )
536 if( aProperties[i].Name.equalsAscii(name) )
537 return aProperties[i].Value;
538 if(bRequired)
539 throw IllegalArgumentException();
540 return Any();
543 //XNumberingFormatter
544 OUString
545 DefaultNumberingProvider::makeNumberingString( const Sequence<beans::PropertyValue>& aProperties,
546 const Locale& aLocale )
547 throw( IllegalArgumentException, RuntimeException, std::exception )
549 // the Sequence of PropertyValues is expected to have at least 4 elements:
550 // elt Name Type purpose
553 // 0. "Prefix" OUString
554 // 1. "NumberingType" sal_Int16 type of formatting from style::NumberingType (roman, arabic, etc)
555 // 2. "Suffix" OUString
556 // ... ... ...
557 // n. "Value" sal_Int32 the number to be formatted
558 // example:
559 // given the Sequence { '(', NumberingType::ROMAN_UPPER, ')', ..., 7 }
560 // makeNumberingString() returns the string "(VII)".
562 // Q: why is the type of numType sal_Int16 instead of style::NumberingType?
563 // A: an Any can't hold a style::NumberingType for some reason.
564 // add.: style::NumberingType holds constants of type sal_Int16, it's not an enum type
566 sal_Int16 natNum = 0;
567 sal_Int16 tableSize = 0;
568 const sal_Unicode *table = NULL; // initialize to avoid compiler warning
569 bool recycleSymbol = false;
570 Locale locale;
572 OUString prefix;
573 sal_Int16 numType = -1; // type of formatting from style::NumberingType (roman, arabic, etc)
574 OUString suffix;
575 sal_Int32 number = -12345; // the number that needs to be formatted.
577 // int nProperties = aProperties.getLength();
578 // int last = nProperties-1;
580 try {
581 getPropertyByName(aProperties, "Prefix", false) >>=prefix;
582 } catch (Exception&) {
583 //prefix _must_ be empty here!
585 try {
586 getPropertyByName(aProperties, "Suffix", false) >>=suffix;
587 } catch (Exception&) {
588 //suffix _must_ be empty here!
590 try {
591 getPropertyByName(aProperties, "NumberingType", true) >>=numType;
592 } catch (Exception& ) {
593 numType = -1;
595 try {
596 getPropertyByName(aProperties, "Value", true) >>=number;
597 } catch (Exception& ) {
598 number = -1;
601 if( number <= 0 )
602 throw IllegalArgumentException();
604 // start empty
605 OUString result;
607 // append prefix
608 if( !should_ignore(prefix) ) result += prefix;
610 // append formatted number
611 using namespace style::NumberingType;
612 switch( numType )
614 case CHARS_UPPER_LETTER:
615 lcl_formatChars( upperLetter, 26, number-1, result ); // 1=>A, 2=>B, ..., 26=>Z, 27=>AA, 28=>AB, ...
616 break;
617 case CHARS_LOWER_LETTER:
618 lcl_formatChars( lowerLetter, 26, number-1, result );
619 break;
620 case ROMAN_UPPER:
621 result += toRoman( number );
622 break;
623 case ROMAN_LOWER:
624 result += toRoman( number ).toAsciiLowerCase();
625 break;
626 case ARABIC:
627 result += OUString::number( number );
628 break;
629 case NUMBER_NONE:
630 return OUString(""); // ignore prefix and suffix
631 case CHAR_SPECIAL:
632 // apparently, we're supposed to return an empty string in this case...
633 return OUString(""); // ignore prefix and suffix
634 case PAGE_DESCRIPTOR:
635 case BITMAP:
636 OSL_ASSERT(false);
637 throw IllegalArgumentException();
638 case CHARS_UPPER_LETTER_N:
639 lcl_formatChars1( upperLetter, 26, number-1, result ); // 1=>A, 2=>B, ..., 26=>Z, 27=>AA, 28=>BB, ...
640 break;
641 case CHARS_LOWER_LETTER_N:
642 lcl_formatChars1( lowerLetter, 26, number-1, result ); // 1=>A, 2=>B, ..., 26=>Z, 27=>AA, 28=>BB, ...
643 break;
644 case TRANSLITERATION:
645 try {
646 const OUString &tmp = OUString::number( number );
647 OUString transliteration;
648 getPropertyByName(aProperties, "Transliteration", true) >>= transliteration;
649 impl_loadTranslit();
650 translit->loadModuleByImplName(transliteration, aLocale);
651 result += translit->transliterateString2String(tmp, 0, tmp.getLength());
652 } catch (Exception& ) {
653 // When translteration property is missing, return default number (bug #101141#)
654 result += OUString::number( number );
655 // OSL_ASSERT(0);
656 // throw IllegalArgumentException();
658 break;
659 case NATIVE_NUMBERING:
660 natNum = NativeNumberMode::NATNUM1;
661 locale = aLocale;
662 break;
663 case FULLWIDTH_ARABIC:
664 natNum = NativeNumberMode::NATNUM3;
665 locale = aLocale;
666 break;
667 case NUMBER_LOWER_ZH:
668 natNum = NativeNumberMode::NATNUM7;
669 locale.Language = "zh";
670 break;
671 case NUMBER_UPPER_ZH:
672 natNum = NativeNumberMode::NATNUM8;
673 locale.Language = "zh";
674 break;
675 case NUMBER_UPPER_ZH_TW:
676 natNum = NativeNumberMode::NATNUM8;
677 locale.Language = "zh";
678 locale.Country = "TW";
679 break;
680 case NUMBER_TRADITIONAL_JA:
681 natNum = NativeNumberMode::NATNUM8;
682 locale.Language = "ja";
683 break;
684 case NUMBER_UPPER_KO:
685 natNum = NativeNumberMode::NATNUM8;
686 locale.Language = "ko";
687 break;
688 case NUMBER_HANGUL_KO:
689 natNum = NativeNumberMode::NATNUM11;
690 locale.Language = "ko";
691 break;
693 case CIRCLE_NUMBER:
694 table = table_CircledNumber;
695 tableSize = SAL_N_ELEMENTS(table_CircledNumber);
696 break;
697 case TIAN_GAN_ZH:
698 table = table_TianGan_zh;
699 tableSize = SAL_N_ELEMENTS(table_TianGan_zh);
700 break;
701 case DI_ZI_ZH:
702 table = table_DiZi_zh;
703 tableSize = SAL_N_ELEMENTS(table_DiZi_zh);
704 break;
705 case AIU_FULLWIDTH_JA:
706 table = table_AIUFullWidth_ja_JP;
707 tableSize = SAL_N_ELEMENTS(table_AIUFullWidth_ja_JP);
708 recycleSymbol = true;
709 break;
710 case AIU_HALFWIDTH_JA:
711 table = table_AIUHalfWidth_ja_JP;
712 tableSize = SAL_N_ELEMENTS(table_AIUHalfWidth_ja_JP);
713 recycleSymbol = true;
714 break;
715 case IROHA_FULLWIDTH_JA:
716 table = table_IROHAFullWidth_ja_JP;
717 tableSize = SAL_N_ELEMENTS(table_IROHAFullWidth_ja_JP);
718 recycleSymbol = true;
719 break;
720 case IROHA_HALFWIDTH_JA:
721 table = table_IROHAHalfWidth_ja_JP;
722 tableSize = SAL_N_ELEMENTS(table_IROHAHalfWidth_ja_JP);
723 recycleSymbol = true;
724 break;
725 case HANGUL_JAMO_KO:
726 table = table_HangulJamo_ko;
727 tableSize = SAL_N_ELEMENTS(table_HangulJamo_ko);
728 recycleSymbol = true;
729 break;
730 case HANGUL_SYLLABLE_KO:
731 table = table_HangulSyllable_ko;
732 tableSize = SAL_N_ELEMENTS(table_HangulSyllable_ko);
733 recycleSymbol = true;
734 break;
735 case HANGUL_CIRCLED_JAMO_KO:
736 table = table_HangulCircledJamo_ko;
737 tableSize = SAL_N_ELEMENTS(table_HangulCircledJamo_ko);
738 recycleSymbol = true;
739 break;
740 case HANGUL_CIRCLED_SYLLABLE_KO:
741 table = table_HangulCircledSyllable_ko;
742 tableSize = SAL_N_ELEMENTS(table_HangulCircledSyllable_ko);
743 recycleSymbol = true;
744 break;
745 case CHARS_ARABIC:
746 lcl_formatChars(table_Alphabet_ar, SAL_N_ELEMENTS(table_Alphabet_ar), number - 1, result);
747 break;
748 case CHARS_ARABIC_ABJAD:
749 lcl_formatChars(table_Alphabet_ar_abjad, SAL_N_ELEMENTS(table_Alphabet_ar_abjad), number - 1, result);
750 break;
751 case CHARS_THAI:
752 lcl_formatChars(table_Alphabet_th, SAL_N_ELEMENTS(table_Alphabet_th), number - 1, result);
753 break;
754 case CHARS_HEBREW:
755 lcl_formatChars(table_Alphabet_he, SAL_N_ELEMENTS(table_Alphabet_he), number - 1, result);
756 break;
757 case CHARS_NEPALI:
758 lcl_formatChars(table_Alphabet_ne, SAL_N_ELEMENTS(table_Alphabet_ne), number - 1, result);
759 break;
760 case CHARS_KHMER:
761 lcl_formatChars(table_Alphabet_km, SAL_N_ELEMENTS(table_Alphabet_km), number - 1, result);
762 break;
763 case CHARS_LAO:
764 lcl_formatChars(table_Alphabet_lo, SAL_N_ELEMENTS(table_Alphabet_lo), number - 1, result);
765 break;
766 case CHARS_MYANMAR:
767 lcl_formatChars(table_Alphabet_my, SAL_N_ELEMENTS(table_Alphabet_my), number - 1, result);
768 break;
769 case CHARS_TIBETAN:
770 lcl_formatChars(table_Alphabet_dz, SAL_N_ELEMENTS(table_Alphabet_dz), number - 1, result);
771 break;
772 case CHARS_CYRILLIC_UPPER_LETTER_BG:
773 lcl_formatChars2( table_CyrillicUpperLetter_bg,
774 table_CyrillicLowerLetter_bg,
775 SAL_N_ELEMENTS(table_CyrillicLowerLetter_bg), number-1,
776 result); // 1=>a, 2=>b, ..., 28=>z, 29=>Aa, 30=>Ab, ...
777 break;
778 case CHARS_CYRILLIC_LOWER_LETTER_BG:
779 lcl_formatChars( table_CyrillicLowerLetter_bg,
780 SAL_N_ELEMENTS(table_CyrillicLowerLetter_bg), number-1,
781 result); // 1=>a, 2=>b, ..., 28=>z, 29=>aa, 30=>ab, ...
782 break;
783 case CHARS_CYRILLIC_UPPER_LETTER_N_BG:
784 lcl_formatChars3( table_CyrillicUpperLetter_bg,
785 table_CyrillicLowerLetter_bg,
786 SAL_N_ELEMENTS(table_CyrillicLowerLetter_bg), number-1,
787 result); // 1=>a, 2=>b, ..., 28=>z, 29=>Aa, 30=>Bb, ...
788 break;
789 case CHARS_CYRILLIC_LOWER_LETTER_N_BG:
790 lcl_formatChars1( table_CyrillicLowerLetter_bg,
791 SAL_N_ELEMENTS(table_CyrillicLowerLetter_bg), number-1,
792 result); // 1=>a, 2=>b, ..., 28=>z, 29=>aa, 30=>bb, ...
793 break;
794 case CHARS_CYRILLIC_UPPER_LETTER_RU:
795 lcl_formatChars2( table_CyrillicUpperLetter_ru,
796 table_CyrillicLowerLetter_ru,
797 SAL_N_ELEMENTS(table_CyrillicLowerLetter_ru), number-1,
798 result); // 1=>a, 2=>b, ..., 27=>z, 28=>Aa, 29=>Ab, ...
799 break;
800 case CHARS_CYRILLIC_LOWER_LETTER_RU:
801 lcl_formatChars( table_CyrillicLowerLetter_ru,
802 SAL_N_ELEMENTS(table_CyrillicLowerLetter_ru), number-1,
803 result); // 1=>a, 2=>b, ..., 27=>z, 28=>aa, 29=>ab, ...
804 break;
805 case CHARS_CYRILLIC_UPPER_LETTER_N_RU:
806 lcl_formatChars3( table_CyrillicUpperLetter_ru,
807 table_CyrillicLowerLetter_ru,
808 SAL_N_ELEMENTS(table_CyrillicLowerLetter_ru), number-1,
809 result); // 1=>a, 2=>b, ..., 27=>z, 28=>Aa, 29=>Bb, ...
810 break;
811 case CHARS_CYRILLIC_LOWER_LETTER_N_RU:
812 lcl_formatChars1( table_CyrillicLowerLetter_ru,
813 SAL_N_ELEMENTS(table_CyrillicLowerLetter_ru), number-1,
814 result); // 1=>a, 2=>b, ..., 27=>z, 28=>aa, 29=>bb, ...
815 break;
816 case CHARS_CYRILLIC_UPPER_LETTER_SR:
817 lcl_formatChars2( table_CyrillicUpperLetter_sr,
818 table_CyrillicLowerLetter_sr,
819 SAL_N_ELEMENTS(table_CyrillicLowerLetter_sr), number-1,
820 result); // 1=>a, 2=>b, ..., 27=>z, 28=>Aa, 29=>Ab, ...
821 break;
822 case CHARS_CYRILLIC_LOWER_LETTER_SR:
823 lcl_formatChars( table_CyrillicLowerLetter_sr,
824 SAL_N_ELEMENTS(table_CyrillicLowerLetter_sr), number-1,
825 result); // 1=>a, 2=>b, ..., 27=>z, 28=>aa, 29=>ab, ...
826 break;
827 case CHARS_CYRILLIC_UPPER_LETTER_N_SR:
828 lcl_formatChars3( table_CyrillicUpperLetter_sr,
829 table_CyrillicLowerLetter_sr,
830 SAL_N_ELEMENTS(table_CyrillicLowerLetter_sr), number-1,
831 result); // 1=>a, 2=>b, ..., 27=>z, 28=>Aa, 29=>Bb, ...
832 break;
833 case CHARS_CYRILLIC_LOWER_LETTER_N_SR:
834 lcl_formatChars1( table_CyrillicLowerLetter_sr,
835 SAL_N_ELEMENTS(table_CyrillicLowerLetter_sr), number-1,
836 result); // 1=>a, 2=>b, ..., 27=>z, 28=>aa, 29=>bb, ...
837 break;
839 case CHARS_GREEK_LOWER_LETTER:
840 lcl_formatCharsGR( table_GreekLowerLetter, number, result);
841 break;
843 case CHARS_GREEK_UPPER_LETTER:
844 lcl_formatCharsGR( table_GreekUpperLetter, number, result);
845 break;
847 case CHARS_PERSIAN:
848 lcl_formatChars(table_Alphabet_fa, SAL_N_ELEMENTS(table_Alphabet_fa), number - 1, result);
849 break;
851 case CHARS_PERSIAN_WORD:
852 lcl_formatPersianWord(number, result);
853 break;
855 default:
856 OSL_ASSERT(false);
857 throw IllegalArgumentException();
860 if (natNum) {
861 NativeNumberSupplierService sNatNum;
862 result += sNatNum.getNativeNumberString(OUString::number( number ), locale, natNum);
863 } else if (tableSize) {
864 if ( number > tableSize && !recycleSymbol)
865 result += OUString::number( number);
866 else
867 result += OUString(&table[--number % tableSize], 1);
870 // append suffix
871 if( !should_ignore(suffix) ) result += suffix;
873 return result;
876 #define LANG_ALL (1 << 0)
877 #define LANG_CJK (1 << 1)
878 #define LANG_CTL (1 << 2)
880 struct Supported_NumberingType
882 sal_Int16 nType;
883 const sal_Char* cSymbol;
884 sal_Int16 langOption;
886 static const Supported_NumberingType aSupportedTypes[] =
888 {style::NumberingType::CHARS_UPPER_LETTER, "A", LANG_ALL},
889 {style::NumberingType::CHARS_LOWER_LETTER, "a", LANG_ALL},
890 {style::NumberingType::ROMAN_UPPER, "I", LANG_ALL},
891 {style::NumberingType::ROMAN_LOWER, "i", LANG_ALL},
892 {style::NumberingType::ARABIC, "1", LANG_ALL},
893 {style::NumberingType::NUMBER_NONE, "''", LANG_ALL},
894 {style::NumberingType::CHAR_SPECIAL, "Bullet", LANG_ALL},
895 {style::NumberingType::PAGE_DESCRIPTOR, "Page", LANG_ALL},
896 {style::NumberingType::BITMAP, "Bitmap", LANG_ALL},
897 {style::NumberingType::CHARS_UPPER_LETTER_N, "AAA", LANG_ALL},
898 {style::NumberingType::CHARS_LOWER_LETTER_N, "aaa", LANG_ALL},
899 {style::NumberingType::NATIVE_NUMBERING, "Native Numbering", LANG_CJK|LANG_CTL},
900 {style::NumberingType::FULLWIDTH_ARABIC, NULL, LANG_CJK},
901 {style::NumberingType::CIRCLE_NUMBER, NULL, LANG_CJK},
902 {style::NumberingType::NUMBER_LOWER_ZH, NULL, LANG_CJK},
903 {style::NumberingType::NUMBER_UPPER_ZH, NULL, LANG_CJK},
904 {style::NumberingType::NUMBER_UPPER_ZH_TW, NULL, LANG_CJK},
905 {style::NumberingType::TIAN_GAN_ZH, NULL, LANG_CJK},
906 {style::NumberingType::DI_ZI_ZH, NULL, LANG_CJK},
907 {style::NumberingType::NUMBER_TRADITIONAL_JA, NULL, LANG_CJK},
908 {style::NumberingType::AIU_FULLWIDTH_JA, NULL, LANG_CJK},
909 {style::NumberingType::AIU_HALFWIDTH_JA, NULL, LANG_CJK},
910 {style::NumberingType::IROHA_FULLWIDTH_JA, NULL, LANG_CJK},
911 {style::NumberingType::IROHA_HALFWIDTH_JA, NULL, LANG_CJK},
912 {style::NumberingType::NUMBER_UPPER_KO, NULL, LANG_CJK},
913 {style::NumberingType::NUMBER_HANGUL_KO, NULL, LANG_CJK},
914 {style::NumberingType::HANGUL_JAMO_KO, NULL, LANG_CJK},
915 {style::NumberingType::HANGUL_SYLLABLE_KO, NULL, LANG_CJK},
916 {style::NumberingType::HANGUL_CIRCLED_JAMO_KO, NULL, LANG_CJK},
917 {style::NumberingType::HANGUL_CIRCLED_SYLLABLE_KO, NULL, LANG_CJK},
918 {style::NumberingType::CHARS_ARABIC, NULL, LANG_CTL},
919 {style::NumberingType::CHARS_ARABIC_ABJAD, NULL, LANG_CTL},
920 {style::NumberingType::CHARS_THAI, NULL, LANG_CTL},
921 {style::NumberingType::CHARS_HEBREW, NULL, LANG_CTL},
922 {style::NumberingType::CHARS_NEPALI, NULL, LANG_CTL},
923 {style::NumberingType::CHARS_KHMER, NULL, LANG_CTL},
924 {style::NumberingType::CHARS_LAO, NULL, LANG_CTL},
925 {style::NumberingType::CHARS_MYANMAR, NULL, LANG_CTL},
926 {style::NumberingType::CHARS_TIBETAN, NULL, LANG_CTL},
927 {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},
928 {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},
929 {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},
930 {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},
931 {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},
932 {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},
933 {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},
934 {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},
935 {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},
936 {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},
937 {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},
938 {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},
939 {style::NumberingType::CHARS_PERSIAN, NULL, LANG_CTL},
940 {style::NumberingType::CHARS_PERSIAN_WORD, NULL, LANG_CTL},
941 {style::NumberingType::CHARS_GREEK_UPPER_LETTER, C_GR_A ", " C_GR_B ", ... (gr)", LANG_ALL},
942 {style::NumberingType::CHARS_GREEK_LOWER_LETTER, S_GR_A ", " S_GR_B ", ... (gr)", LANG_ALL},
944 static const sal_Int32 nSupported_NumberingTypes = sizeof(aSupportedTypes) / sizeof(Supported_NumberingType);
946 OUString DefaultNumberingProvider::makeNumberingIdentifier(sal_Int16 index)
947 throw(RuntimeException)
949 if (aSupportedTypes[index].cSymbol)
950 return OUString(aSupportedTypes[index].cSymbol, strlen(aSupportedTypes[index].cSymbol), RTL_TEXTENCODING_UTF8);
951 // return OUString::createFromAscii(aSupportedTypes[index].cSymbol);
952 else {
953 OUString result;
954 Locale aLocale(OUString("en"), OUString(), OUString());
955 Sequence<beans::PropertyValue> aProperties(2);
956 aProperties[0].Name = "NumberingType";
957 aProperties[0].Value <<= aSupportedTypes[index].nType;
958 aProperties[1].Name = "Value";
959 for (sal_Int32 j = 1; j <= 3; j++) {
960 aProperties[1].Value <<= j;
961 result += makeNumberingString( aProperties, aLocale );
962 result += ", ";
964 result += "...";
965 return result;
969 bool SAL_CALL
970 DefaultNumberingProvider::isScriptFlagEnabled(const OUString& aName) throw(RuntimeException)
972 if (! xHierarchicalNameAccess.is()) {
973 Reference< XMultiServiceFactory > xConfigProvider =
974 configuration::theDefaultProvider::get(m_xContext);
976 if (! xConfigProvider.is())
977 throw RuntimeException();
979 Sequence< Any > aArgs(1);
980 beans::PropertyValue aPath;
981 aPath.Name = "nodepath";
982 aPath.Value <<= OUString("/org.openoffice.Office.Common/I18N"),
983 aArgs[0] <<= aPath;
985 Reference<XInterface> xInterface = xConfigProvider->createInstanceWithArguments(
986 OUString("com.sun.star.configuration.ConfigurationAccess"), aArgs);
988 xHierarchicalNameAccess.set(xInterface, UNO_QUERY);
990 if (! xHierarchicalNameAccess.is())
991 throw RuntimeException();
994 Any aEnabled = xHierarchicalNameAccess->getByHierarchicalName(aName);
996 bool enabled = false;
998 aEnabled >>= enabled;
1000 return enabled;
1003 Sequence< sal_Int16 > DefaultNumberingProvider::getSupportedNumberingTypes( )
1004 throw(RuntimeException, std::exception)
1006 Sequence< sal_Int16 > aRet(nSupported_NumberingTypes );
1007 sal_Int16* pArray = aRet.getArray();
1009 bool cjkEnabled = isScriptFlagEnabled(OUString("CJK/CJKFont"));
1010 bool ctlEnabled = isScriptFlagEnabled(OUString("CTL/CTLFont"));
1012 for(sal_Int16 i = 0; i < nSupported_NumberingTypes; i++) {
1013 if ( (aSupportedTypes[i].langOption & LANG_ALL) ||
1014 ((aSupportedTypes[i].langOption & LANG_CJK) && cjkEnabled) ||
1015 ((aSupportedTypes[i].langOption & LANG_CTL) && ctlEnabled) )
1016 pArray[i] = aSupportedTypes[i].nType;
1018 return aRet;
1021 sal_Int16 DefaultNumberingProvider::getNumberingType( const OUString& rNumberingIdentifier )
1022 throw(RuntimeException, std::exception)
1024 for(sal_Int16 i = 0; i < nSupported_NumberingTypes; i++)
1025 if(rNumberingIdentifier.equals(makeNumberingIdentifier(i)))
1026 return aSupportedTypes[i].nType;
1027 throw RuntimeException();
1030 sal_Bool DefaultNumberingProvider::hasNumberingType( const OUString& rNumberingIdentifier )
1031 throw(RuntimeException, std::exception)
1033 for(sal_Int16 i = 0; i < nSupported_NumberingTypes; i++)
1034 if(rNumberingIdentifier.equals(makeNumberingIdentifier(i)))
1035 return sal_True;
1036 return sal_False;
1039 OUString DefaultNumberingProvider::getNumberingIdentifier( sal_Int16 nNumberingType )
1040 throw(RuntimeException, std::exception)
1042 for(sal_Int16 i = 0; i < nSupported_NumberingTypes; i++)
1043 if(nNumberingType == aSupportedTypes[i].nType)
1044 return makeNumberingIdentifier(i);
1045 return OUString();
1048 OUString DefaultNumberingProvider::getImplementationName()
1049 throw( RuntimeException, std::exception )
1051 return OUString("com.sun.star.text.DefaultNumberingProvider");
1054 sal_Bool DefaultNumberingProvider::supportsService(const OUString& rServiceName)
1055 throw( RuntimeException, std::exception )
1057 return cppu::supportsService(this, rServiceName);
1060 Sequence< OUString > DefaultNumberingProvider::getSupportedServiceNames()
1061 throw( RuntimeException, std::exception )
1063 Sequence< OUString > aRet(1);
1064 aRet[0] = "com.sun.star.text.DefaultNumberingProvider";
1065 return aRet;
1068 } } } }
1070 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
1071 com_sun_star_text_DefaultNumberingProvider_get_implementation(
1072 css::uno::XComponentContext *context,
1073 css::uno::Sequence<css::uno::Any> const &)
1075 return cppu::acquire(new css::i18n::DefaultNumberingProvider(context));
1078 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */