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