Version 3.6.0.2, tag libreoffice-3.6.0.2
[LibreOffice.git] / i18npool / source / defaultnumberingprovider / defaultnumberingprovider.cxx
blob8679b67db20b85ccc3d0fad88c3936e65ef62858
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 #include <defaultnumberingprovider.hxx>
30 #include <com/sun/star/style/NumberingType.hpp>
31 #include <com/sun/star/beans/PropertyValue.hpp>
32 #include <com/sun/star/text/HoriOrientation.hpp>
33 #include <localedata.hxx>
34 #include <nativenumbersupplier.hxx>
35 #include <stdio.h>
36 #include <string.h>
38 // Cyrillic upper case
39 #define C_CYR_A "\xD0\x90"
40 #define C_CYR_B "\xD0\x91"
41 // Cyrillic lower case
42 #define S_CYR_A "\xD0\xB0"
43 #define S_CYR_B "\xD0\xB1"
45 //Greek upper case
46 #define C_GR_A "\xCE\x91"
47 #define C_GR_B "\xCE\x92"
48 //Greek lower case
49 #define S_GR_A "\xCE\xB1"
50 #define S_GR_B "\xCE\xB2"
52 #include <math.h>
53 #include <sal/macros.h>
54 #include <rtl/ustring.hxx>
55 #include <rtl/ustrbuf.hxx>
56 #include <com/sun/star/i18n/XTransliteration.hpp>
57 #include <com/sun/star/i18n/TransliterationType.hpp>
58 #include <com/sun/star/i18n/TransliterationModulesNew.hpp>
59 #include <com/sun/star/i18n/XLocaleData.hpp>
61 #include <bullet.h>
63 using namespace com::sun::star;
64 using namespace com::sun::star::uno;
65 using namespace com::sun::star::lang;
66 using namespace ::rtl;
68 namespace com { namespace sun { namespace star { namespace i18n {
70 static sal_Unicode table_Alphabet_ar[] = {
71 0x0623, 0x0628, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E,
72 0x062F, 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635,
73 0x0636, 0x0637, 0x0638, 0x0639, 0x063A, 0x0641, 0x0642,
74 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649
77 static sal_Unicode table_Alphabet_ar_abjad[] = {
78 0x0627, 0x0628, 0x062c, 0x062f, 0x0647, 0x0648, 0x0632, 0x062d,
79 0x0637, 0x064a, 0x0643, 0x0644, 0x0645, 0x0646, 0x0633, 0x0639,
80 0x0641, 0x0635, 0x0642, 0x0631, 0x0634, 0x062a, 0x062b, 0x062e,
81 0x0630, 0x0636, 0x0638, 0x063a
84 static sal_Unicode table_Alphabet_th[] = {
85 0x0E01, 0x0E02, 0x0E04, 0x0E07,
86 0x0E08, 0x0E09, 0x0E0A, 0x0E0B, 0x0E0C, 0x0E0D, 0x0E0E, 0x0E0F,
87 0x0E10, 0x0E11, 0x0E12, 0x0E13, 0x0E14, 0x0E15, 0x0E16, 0x0E17,
88 0x0E18, 0x0E19, 0x0E1A, 0x0E1B, 0x0E1C, 0x0E1D, 0x0E1E, 0x0E1F,
89 0x0E20, 0x0E21, 0x0E22, 0x0E23, 0x0E24, 0x0E25, 0x0E26, 0x0E27,
90 0x0E28, 0x0E29, 0x0E2A, 0x0E2B, 0x0E2C, 0x0E2D, 0x0E2E
93 static sal_Unicode table_Alphabet_he[] = {
94 0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7,
95 0x05D8, 0x05D9, 0x05DB, 0x05DC, 0x05DE, 0x05E0, 0x05E1, 0x05E2,
96 0x05E4, 0x05E6, 0x05E7, 0x05E8, 0x05E9, 0x05EA
99 static sal_Unicode table_Alphabet_ne[] = {
100 0x0915, 0x0916, 0x0917, 0x0918, 0x0919, 0x091A, 0x091B, 0x091C,
101 0x091D, 0x091E, 0x091F, 0x0920, 0x0921, 0x0922, 0x0923, 0x0924,
102 0x0925, 0x0926, 0x0927, 0x0928, 0x092A, 0x092B, 0x092C, 0x092D,
103 0x092E, 0x092F, 0x0930, 0x0932, 0x0935, 0x0936, 0x0937, 0x0938,
104 0x0939
107 static sal_Unicode table_Alphabet_km[] = {
108 0x1780, 0x1781, 0x1782, 0x1783, 0x1784, 0x1785, 0x1786, 0x1787,
109 0x1788, 0x1789, 0x178A, 0x178B, 0x178C, 0x178D, 0x178E, 0x178F,
110 0x1790, 0x1791, 0x1792, 0x1793, 0x1794, 0x1795, 0x1796, 0x1797,
111 0x1798, 0x1799, 0x179A, 0x179B, 0x179C, 0x179F,
112 0x17A0, 0x17A1, 0x17A2
115 static sal_Unicode table_Alphabet_lo[] = {
116 0x0E81, 0x0E82, 0x0E84, 0x0E87, 0x0E88, 0x0E8A, 0x0E8D, 0x0E94,
117 0x0E95, 0x0E96, 0x0E97, 0x0E99, 0x0E9A, 0x0E9B, 0x0E9C,
118 0x0E9D, 0x0E9E, 0x0E9F, 0x0EA1, 0x0EA2, 0x0EA3, 0x0EA5, 0x0EA7,
119 0x0EAA, 0x0EAB, 0x0EAD, 0x0EAE, 0x0EAF, 0x0EAE, 0x0EDC, 0x0EDD
122 static sal_Unicode table_Alphabet_dz[] = {
123 0x0F40, 0x0F41, 0x0F42, 0x0F44, 0x0F45, 0x0F46, 0x0F47, 0x0F49,
124 0x0F4F, 0x0F50, 0x0F51, 0x0F53, 0x0F54, 0x0F55, 0x0F56, 0x0F58,
125 0x0F59, 0x0F5A, 0x0F5B, 0x0F5D, 0x0F5E, 0x0F5F, 0x0F60, 0x0F61,
126 0x0F62, 0x0F63, 0x0F64, 0x0F66, 0x0F67, 0x0F68
129 static sal_Unicode table_Alphabet_my[] = {
130 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006, 0x1007,
131 0x1008,/*0x1009,*/0x100A, 0x100B, 0x100C, 0x100D, 0x100E, 0x100F,
132 0x1010, 0x1011, 0x1012, 0x1013, 0x1014, 0x1015, 0x1016, 0x1017,
133 0x1018, 0x1019, 0x101A, 0x101B, 0x101C, 0x101D, 0x101E, 0x101F,
134 0x1020, 0x1021
137 // Bulgarian Cyrillic upper case letters
138 static sal_Unicode table_CyrillicUpperLetter_bg[] = {
139 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418,
140 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, 0x0420, 0x0421, 0x0422,
141 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042E,
142 0x042F
145 // Bulgarian cyrillic lower case letters
146 static sal_Unicode table_CyrillicLowerLetter_bg[] = {
147 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438,
148 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F, 0x0440, 0x0441, 0x0442,
149 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044E,
150 0x044F
153 // Russian Cyrillic upper letters
154 static sal_Unicode table_CyrillicUpperLetter_ru[] = {
155 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
156 0x0418, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, 0x0420,
157 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428,
158 0x0429, 0x042B, 0x042D, 0x042E, 0x042F
161 // Russian cyrillic lower letters
162 static sal_Unicode table_CyrillicLowerLetter_ru[] = {
163 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
164 0x0438, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F, 0x0440,
165 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448,
166 0x0449, 0x044B, 0x044D, 0x044E, 0x044F
169 // Serbian Cyrillic upper letters
170 static sal_Unicode table_CyrillicUpperLetter_sr[] = {
171 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0402, 0x0415, 0x0416,
172 0x0417, 0x0418, 0x0408, 0x041A, 0x041B, 0x0409, 0x041C, 0x041D,
173 0x040A, 0x041E, 0x041F, 0x0420, 0x0421, 0x0422, 0x040B, 0x0423,
174 0x0424, 0x0425, 0x0426, 0x0427, 0x040F, 0x0428
177 // Serbian cyrillic lower letters
178 static sal_Unicode table_CyrillicLowerLetter_sr[] = {
179 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0452, 0x0435, 0x0436,
180 0x0437, 0x0438, 0x0458, 0x043A, 0x043B, 0x0459, 0x043C, 0x043D,
181 0x045A, 0x043E, 0x043F, 0x0440, 0x0441, 0x0442, 0x045B, 0x0443,
182 0x0444, 0x0445, 0x0446, 0x0447, 0x045F, 0x0448
185 static sal_Unicode table_GreekUpperLetter[] = {
186 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x03DB, 0x0396, 0x0397, 0x0398,
187 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0, 0x03DF,
188 0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, 0x03E0
191 static sal_Unicode table_GreekLowerLetter[] = {
192 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03DB, 0x03B6, 0x03B7, 0x03B8,
193 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, 0x03DF,
194 0x03C1, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8, 0x03C9, 0x03E1
197 static sal_Unicode table_Alphabet_fa[] = {
198 0x0622, 0x0628, 0x067E, 0x062A, 0x062B, 0x062C, 0x0686, 0x062D,
199 0x062E, 0x062F, 0x0630, 0x0631, 0x0632, 0x0698, 0x0633, 0x0634,
200 0x0635, 0x0636, 0x0637, 0x0638, 0x0639, 0x0640, 0x0641, 0x0642,
201 0x06A9, 0x06AF, 0x0644, 0x0645, 0x0646, 0x0648, 0x0647, 0x06CC
204 static sal_Unicode upperLetter[] = {
205 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
206 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52,
207 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A
210 static sal_Unicode lowerLetter[] = {
211 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
212 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72,
213 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A
216 // Tables used for numbering in persian words
217 static sal_Unicode table_PersianWord_decade1[][7]={
218 {0}, // 0
219 {0x06cc, 0x06a9, 0}, // 1
220 {0x062f, 0x0648, 0}, // 2
221 {0x0633, 0x0647, 0}, // 3
222 {0x0686, 0x0647, 0x0627, 0x0631, 0}, // 4
223 {0x067e, 0x0646, 0x062c, 0}, // 5
224 {0x0634, 0x0634, 0}, // 6
225 {0x0647, 0x0641, 0x062a, 0}, // 7
226 {0x0647, 0x0634, 0x062a, 0}, // 8
227 {0x0646, 0x0647, 0}, // 9
228 {0x062f, 0x0647, 0}, // 10
229 {0x06cc, 0x0627, 0x0632, 0x062f, 0x0647, 0}, // 11
230 {0x062f, 0x0648, 0x0627, 0x0632, 0x062f, 0x0647, 0}, // 12
231 {0x0633, 0x06cc, 0x0632, 0x062f, 0x0647, 0}, // 13
232 {0x0686, 0x0647, 0x0627, 0x0631, 0x062f, 0x0647, 0}, // 14
233 {0x067e, 0x0627, 0x0646, 0x0632, 0x062f, 0x0647, 0}, // 15
234 {0x0634, 0x0627, 0x0646, 0x0632, 0x062f, 0x0647, 0}, // 16
235 {0x0647, 0x0641, 0x062f, 0x0647, 0}, // 17
236 {0x0647, 0x062c, 0x062f, 0x0647, 0}, // 18
237 {0x0646, 0x0648, 0x0632, 0x062f, 0x0647, 0} // 19
240 static sal_Unicode table_PersianWord_decade2[][6]={
241 {0x0628, 0x06cc, 0x0633, 0x062a, 0}, // 20
242 {0x0633, 0x06cc, 0}, // 30
243 {0x0686, 0x0647, 0x0644, 0}, // 40
244 {0x067e, 0x0646, 0x062c, 0x0627, 0x0647, 0}, // 50
245 {0x0634, 0x0635, 0x062a, 0}, // 60
246 {0x0647, 0x0641, 0x062a, 0x0627, 0x062f, 0}, // 70
247 {0x0647, 0x0634, 0x062a, 0x0627, 0x062f, 0}, // 80
248 {0x0646, 0x0648, 0x062f, 0} // 90
251 static sal_Unicode table_PersianWord_decade3[][7]={
252 {0x0635, 0x062f, 0}, // 100
253 {0x062f, 0x0648, 0x06cc, 0x0633, 0x062a, 0}, // 200
254 {0x0633, 0x06cc, 0x0635, 0x062f, 0}, // 300
255 {0x0686, 0x0647, 0x0627, 0x0631, 0x0635, 0x062f, 0}, // 400
256 {0x067e, 0x0627, 0x0646, 0x0635, 0x062f, 0}, // 500
257 {0x0634, 0x0635, 0x062f, 0}, // 600
258 {0x0647, 0x0641, 0x062a, 0x0635, 0x062f, 0}, // 700
259 {0x0647, 0x0634, 0x062a, 0x0635, 0x062f, 0}, // 800
260 {0x0646, 0x0647, 0x0635, 0x062f, 0} // 900
263 static sal_Unicode table_PersianWord_decadeX[][8]={
264 {0x0647, 0x0632, 0x0627, 0x0631, 0}, // 1000
265 {0x0645, 0x06cc, 0x0644, 0x06cc, 0x0648, 0x0646, 0}, // 1000000
266 {0x0645, 0x06cc, 0x0644, 0x06cc, 0x0627, 0x0631, 0x062f, 0} // 1000000000
270 DefaultNumberingProvider::DefaultNumberingProvider( const Reference < XMultiServiceFactory >& xMSF ) : xSMgr(xMSF),translit(NULL)
275 DefaultNumberingProvider::~DefaultNumberingProvider()
277 delete translit;
280 void DefaultNumberingProvider::impl_loadTranslit()
282 if ( !translit )
283 translit = new TransliterationImpl(xSMgr);
286 Sequence< Reference<container::XIndexAccess> >
287 DefaultNumberingProvider::getDefaultOutlineNumberings(const Locale& rLocale ) throw(RuntimeException)
289 return LocaleData().getOutlineNumberingLevels( rLocale );
292 Sequence< Sequence<beans::PropertyValue> >
293 DefaultNumberingProvider::getDefaultContinuousNumberingLevels( const Locale& rLocale ) throw(RuntimeException)
295 return LocaleData().getContinuousNumberingLevels( rLocale );
298 OUString toRoman( sal_Int32 n )
301 // i, ii, iii, iv, v, vi, vii, vii, viii, ix
302 // (Dummy),1000,500,100,50,10,5,1
303 static const sal_Char coRomanArr[] = "MDCLXVI--"; // +2 Dummy entries !!
304 const sal_Char* cRomanStr = coRomanArr;
305 sal_uInt16 nMask = 1000;
306 sal_uInt32 nOver1000 = n / nMask;
307 n -= ( nOver1000 * nMask );
309 OUStringBuffer sTmp;
310 while(nOver1000--)
311 sTmp.append(sal_Unicode(*coRomanArr));
313 while( nMask )
315 sal_uInt8 nZahl = sal_uInt8( n / nMask );
316 sal_uInt8 nDiff = 1;
317 n %= nMask;
319 if( 5 < nZahl )
321 if( nZahl < 9 )
322 sTmp.append(sal_Unicode(*(cRomanStr-1)));
323 ++nDiff;
324 nZahl -= 5;
326 switch( nZahl )
328 case 3: sTmp.append(sal_Unicode(*cRomanStr)); //no break!
329 case 2: sTmp.append(sal_Unicode(*cRomanStr)); //no break!
330 case 1: sTmp.append(sal_Unicode(*cRomanStr)); break;
331 case 4: sTmp.append(sal_Unicode(*cRomanStr)).append(sal_Unicode(*(cRomanStr-nDiff))); break;
332 case 5: sTmp.append(sal_Unicode(*(cRomanStr-nDiff))); break;
335 nMask /= 10; // to the next decade
336 cRomanStr += 2;
338 return sTmp.makeStringAndClear();
341 // not used:
343 static
344 void lcl_formatChars( sal_Unicode table[], int tableSize, int n, OUString& s )
346 // string representation of n is appended to s.
347 // if A=='A' then 0=>A, 1=>B, ..., 25=>Z, 26=>AA, 27=>AB, ...
348 // if A=='a' then 0=>a, 1=>b, ..., 25=>z, 26=>aa, 27=>ab, ...
350 if( n>=tableSize ) lcl_formatChars( table, tableSize, (n-tableSize)/tableSize, s );
352 s += OUString::valueOf( table[ n % tableSize ] );
355 static
356 void lcl_formatChars1( sal_Unicode table[], int tableSize, int n, OUString& s )
358 // string representation of n is appended to s.
359 // if A=='A' then 0=>A, 1=>B, ..., 25=>Z, 26=>AA, 27=>BB, ...
360 // if A=='a' then 0=>a, 1=>b, ..., 25=>z, 26=>aa, 27=>bb, ...
362 int repeat_count = n / tableSize + 1;
364 for( int i=0; i<repeat_count; i++ )
365 s += OUString::valueOf( table[ n%tableSize ] );
368 static
369 void lcl_formatChars2( sal_Unicode table_capital[], sal_Unicode table_small[], int tableSize, int n, OUString& s )
371 // string representation of n is appended to s.
372 // if A=='A' then 0=>A, 1=>B, ..., 25=>Z, 26=>Aa, 27=>Ab, ...
374 if( n>=tableSize )
376 lcl_formatChars2( table_capital, table_small, tableSize, (n-tableSize)/tableSize, s );
377 s += OUString::valueOf( table_small[ n % tableSize ] );
378 } else
379 s += OUString::valueOf( table_capital[ n % tableSize ] );
382 static
383 void lcl_formatChars3( sal_Unicode table_capital[], sal_Unicode table_small[], int tableSize, int n, OUString& s )
385 // string representation of n is appended to s.
386 // if A=='A' then 0=>A, 1=>B, ..., 25=>Z, 26=>Aa, 27=>Bb, ...
388 int repeat_count = n / tableSize + 1;
389 s += OUString::valueOf( table_capital[ n%tableSize ] );
391 for( int i=1; i<repeat_count; i++ )
392 s += OUString::valueOf( table_small[ n%tableSize ] );
396 /** Returns number's representation in persian words up to 999999999999
397 respectively limited by sal_Int32 >=0.
398 The caller assures that nNumber is not negative.
400 static
401 void lcl_formatPersianWord( sal_Int32 nNumber, OUString& rsResult )
402 throw( IllegalArgumentException, RuntimeException )
404 OUStringBuffer aTemp(64);
405 unsigned int nDigit;
406 sal_Unicode asPersianWord_conjunction_data[] = {0x20,0x0648,0x20,0};
407 OUString asPersianWord_conjunction( asPersianWord_conjunction_data );
408 unsigned char nSection = 0;
410 while (int nPart = nNumber % 1000)
412 if (nSection)
414 if (nSection > SAL_N_ELEMENTS( table_PersianWord_decadeX))
415 throw IllegalArgumentException(); // does not happen with sal_Int32
416 aTemp.insert( 0, asPersianWord_conjunction).insert( 0, table_PersianWord_decadeX[nSection-1]);
419 if ((nDigit = nPart % 100) < 20)
421 if (aTemp.getLength())
422 aTemp.insert( 0, sal_Unicode(0x0020));
423 aTemp.insert( 0, table_PersianWord_decade1[nDigit]);
425 else
427 if ((nDigit = nPart % 10) != 0)
429 if (aTemp.getLength())
430 aTemp.insert( 0, asPersianWord_conjunction);
431 aTemp.insert( 0, table_PersianWord_decade1[nDigit]);
433 if ((nDigit = (nPart / 10) % 10) != 0)
435 if (aTemp.getLength())
436 aTemp.insert( 0, asPersianWord_conjunction);
437 aTemp.insert( 0, table_PersianWord_decade2[nDigit-2]);
441 if ((nDigit = nPart / 100) != 0)
443 if (aTemp.getLength())
444 aTemp.insert( 0, asPersianWord_conjunction);
445 aTemp.insert( 0, table_PersianWord_decade3[nDigit-1]);
448 nNumber /= 1000;
449 nSection++;
451 rsResult += aTemp.makeStringAndClear();
455 // Greek Letter Numbering
457 // KERAIA separates numerals from other text
458 #define STIGMA (sal_Unicode) 0x03DB
459 #define LEFT_KERAIA (sal_Unicode) 0x0375
460 #define MYRIAD_SYM (sal_Unicode) 0x039C
461 #define DOT_SYM (sal_Unicode) 0x002E
462 #define SIGMA_OFFSET 19
463 #define TAU_OFFSET 20
464 #define MYRIAD 10000
467 * Return the 1-999999 number's representation in the Greek numbering system.
468 * Adding a "left keraia" to represent numbers in the range 10000 ... 999999 is
469 * not orthodox, so it's better to use the myriad notation and call this method
470 * only for numbers up to 9999.
472 static
473 OUString gr_smallNum(sal_Unicode table[], int n)
475 if (n > 9999)
476 throw IllegalArgumentException();
478 int i = 0;
479 OUStringBuffer sb;
480 for (int v = n; v > 0; v /= 10, i++) {
481 int digit = v % 10;
482 if (digit == 0)
483 continue;
485 sal_Unicode sign = table[(digit - 1) + 9 * (i % 3)];
486 if (sign == STIGMA) {
487 sb.insert(0, table[TAU_OFFSET]);
488 sb.insert(0, table[SIGMA_OFFSET]);
489 } else {
490 sb.insert(0, sign);
493 if (i > 2)
494 sb.insert(0, LEFT_KERAIA);
497 return sb.makeStringAndClear();
500 static
501 void lcl_formatCharsGR( sal_Unicode table[], int n, OUString& s )
503 OUStringBuffer sb;
504 int myriadPower = 2;
506 for (int divisor = MYRIAD * MYRIAD; divisor > 1; divisor /= MYRIAD, myriadPower--) {
507 if (n > divisor - 1) {
509 * Follow the Diophantus representation of:
510 * A myriad sign, M(10000) as many times as the power
511 * followed by the multiplier for the myriad
512 * followed by a dot
513 * followed by the rest
514 * This is enough for 32-bit integers
516 for (int i = 0; i < myriadPower; i++)
517 sb.append(MYRIAD_SYM);
519 sb.append(gr_smallNum(table, n/divisor));
520 n %= divisor;
522 if (n > 0)
523 sb.append(DOT_SYM);
526 sb.append(gr_smallNum(table,n));
528 s += sb.makeStringAndClear();
531 static
532 int should_ignore( OUString s )
534 // return true if blank or null
535 return s.compareToAscii(" ")==0 || (!s.isEmpty() && s[0]==0);
538 static
539 Any getPropertyByName( const Sequence<beans::PropertyValue>& aProperties,
540 const char* name, sal_Bool bRequired )
542 for( int i=0; i<aProperties.getLength(); i++ )
543 if( aProperties[i].Name.equalsAscii(name) )
544 return aProperties[i].Value;
545 if(bRequired)
546 throw IllegalArgumentException();
547 return Any();
550 //XNumberingFormatter
551 OUString
552 DefaultNumberingProvider::makeNumberingString( const Sequence<beans::PropertyValue>& aProperties,
553 const Locale& aLocale )
554 throw( IllegalArgumentException, RuntimeException )
556 // the Sequence of PropertyValues is expected to have at least 4 elements:
557 // elt Name Type purpose
558 // -----------------------------------------------------------------
560 // 0. "Prefix" OUString
561 // 1. "NumberingType" sal_Int16 type of formatting from style::NumberingType (roman, arabic, etc)
562 // 2. "Suffix" OUString
563 // ... ... ...
564 // n. "Value" sal_Int32 the number to be formatted
565 // example:
566 // given the Sequence { '(', NumberingType::ROMAN_UPPER, ')', ..., 7 }
567 // makeNumberingString() returns the string "(VII)".
569 // Q: why is the type of numType sal_Int16 instead of style::NumberingType?
570 // A: an Any can't hold a style::NumberingType for some reason.
571 // add.: style::NumberingType holds constants of type sal_Int16, it's not an enum type
573 sal_Int16 natNum = 0;
574 sal_Int16 tableSize = 0;
575 sal_Unicode *table = NULL; // initialize to avoid compiler warning
576 sal_Bool recycleSymbol = sal_False;
577 Locale locale;
579 OUString prefix;
580 sal_Int16 numType = -1; // type of formatting from style::NumberingType (roman, arabic, etc)
581 OUString suffix;
582 sal_Int32 number = -12345; // the number that needs to be formatted.
584 // int nProperties = aProperties.getLength();
585 // int last = nProperties-1;
587 try {
588 getPropertyByName(aProperties, "Prefix", sal_False) >>=prefix;
589 } catch (Exception&) {
590 //prefix _must_ be empty here!
592 try {
593 getPropertyByName(aProperties, "Suffix", sal_False) >>=suffix;
594 } catch (Exception&) {
595 //suffix _must_ be empty here!
597 try {
598 getPropertyByName(aProperties, "NumberingType", sal_True) >>=numType;
599 } catch (Exception& ) {
600 numType = -1;
602 try {
603 getPropertyByName(aProperties, "Value", sal_True) >>=number;
604 } catch (Exception& ) {
605 number = -1;
608 if( number <= 0 )
609 throw IllegalArgumentException();
611 // start empty
612 OUString result;
614 // append prefix
615 if( !should_ignore(prefix) ) result += prefix;
617 // append formatted number
618 using namespace style::NumberingType;
619 switch( numType )
621 case CHARS_UPPER_LETTER:
622 lcl_formatChars( upperLetter, 26, number-1, result ); // 1=>A, 2=>B, ..., 26=>Z, 27=>AA, 28=>AB, ...
623 break;
624 case CHARS_LOWER_LETTER:
625 lcl_formatChars( lowerLetter, 26, number-1, result );
626 break;
627 case ROMAN_UPPER:
628 result += toRoman( number );
629 break;
630 case ROMAN_LOWER:
631 result += toRoman( number ).toAsciiLowerCase();
632 break;
633 case ARABIC:
634 result += OUString::valueOf( number );
635 break;
636 case NUMBER_NONE:
637 return OUString(""); // ignore prefix and suffix
638 case CHAR_SPECIAL:
639 // apparently, we're supposed to return an empty string in this case...
640 return OUString(""); // ignore prefix and suffix
641 case PAGE_DESCRIPTOR:
642 case BITMAP:
643 OSL_ASSERT(0);
644 throw IllegalArgumentException();
645 case CHARS_UPPER_LETTER_N:
646 lcl_formatChars1( upperLetter, 26, number-1, result ); // 1=>A, 2=>B, ..., 26=>Z, 27=>AA, 28=>BB, ...
647 break;
648 case CHARS_LOWER_LETTER_N:
649 lcl_formatChars1( lowerLetter, 26, number-1, result ); // 1=>A, 2=>B, ..., 26=>Z, 27=>AA, 28=>BB, ...
650 break;
651 case TRANSLITERATION:
652 try {
653 const OUString &tmp = OUString::valueOf( number );
654 OUString transliteration;
655 getPropertyByName(aProperties, "Transliteration", sal_True) >>= transliteration;
656 impl_loadTranslit();
657 translit->loadModuleByImplName(transliteration, aLocale);
658 result += translit->transliterateString2String(tmp, 0, tmp.getLength());
659 } catch (Exception& ) {
660 // When translteration property is missing, return default number (bug #101141#)
661 result += OUString::valueOf( number );
662 // OSL_ASSERT(0);
663 // throw IllegalArgumentException();
665 break;
666 case NATIVE_NUMBERING:
667 natNum = NativeNumberMode::NATNUM1;
668 locale = aLocale;
669 break;
670 case FULLWIDTH_ARABIC:
671 natNum = NativeNumberMode::NATNUM3;
672 locale = aLocale;
673 break;
674 case NUMBER_LOWER_ZH:
675 natNum = NativeNumberMode::NATNUM7;
676 locale.Language = OUString("zh");
677 break;
678 case NUMBER_UPPER_ZH_TW:
679 locale.Country = OUString("TW");
680 case NUMBER_UPPER_ZH:
681 natNum = NativeNumberMode::NATNUM8;
682 locale.Language = OUString("zh");
683 break;
684 case NUMBER_TRADITIONAL_JA:
685 natNum = NativeNumberMode::NATNUM8;
686 locale.Language = OUString("ja");
687 break;
688 case NUMBER_UPPER_KO:
689 natNum = NativeNumberMode::NATNUM8;
690 locale.Language = OUString("ko");
691 break;
692 case NUMBER_HANGUL_KO:
693 natNum = NativeNumberMode::NATNUM11;
694 locale.Language = OUString("ko");
695 break;
697 case CIRCLE_NUMBER:
698 table = table_CircledNumber;
699 tableSize = SAL_N_ELEMENTS(table_CircledNumber);
700 break;
701 case TIAN_GAN_ZH:
702 table = table_TianGan_zh;
703 tableSize = SAL_N_ELEMENTS(table_TianGan_zh);
704 break;
705 case DI_ZI_ZH:
706 table = table_DiZi_zh;
707 tableSize = SAL_N_ELEMENTS(table_DiZi_zh);
708 break;
709 case AIU_FULLWIDTH_JA:
710 table = table_AIUFullWidth_ja_JP;
711 tableSize = SAL_N_ELEMENTS(table_AIUFullWidth_ja_JP);
712 recycleSymbol = sal_True;
713 break;
714 case AIU_HALFWIDTH_JA:
715 table = table_AIUHalfWidth_ja_JP;
716 tableSize = SAL_N_ELEMENTS(table_AIUHalfWidth_ja_JP);
717 recycleSymbol = sal_True;
718 break;
719 case IROHA_FULLWIDTH_JA:
720 table = table_IROHAFullWidth_ja_JP;
721 tableSize = SAL_N_ELEMENTS(table_IROHAFullWidth_ja_JP);
722 recycleSymbol = sal_True;
723 break;
724 case IROHA_HALFWIDTH_JA:
725 table = table_IROHAHalfWidth_ja_JP;
726 tableSize = SAL_N_ELEMENTS(table_IROHAHalfWidth_ja_JP);
727 recycleSymbol = sal_True;
728 break;
729 case HANGUL_JAMO_KO:
730 table = table_HangulJamo_ko;
731 tableSize = SAL_N_ELEMENTS(table_HangulJamo_ko);
732 recycleSymbol = sal_True;
733 break;
734 case HANGUL_SYLLABLE_KO:
735 table = table_HangulSyllable_ko;
736 tableSize = SAL_N_ELEMENTS(table_HangulSyllable_ko);
737 recycleSymbol = sal_True;
738 break;
739 case HANGUL_CIRCLED_JAMO_KO:
740 table = table_HangulCircledJamo_ko;
741 tableSize = SAL_N_ELEMENTS(table_HangulCircledJamo_ko);
742 recycleSymbol = sal_True;
743 break;
744 case HANGUL_CIRCLED_SYLLABLE_KO:
745 table = table_HangulCircledSyllable_ko;
746 tableSize = SAL_N_ELEMENTS(table_HangulCircledSyllable_ko);
747 recycleSymbol = sal_True;
748 break;
749 case CHARS_ARABIC:
750 lcl_formatChars(table_Alphabet_ar, SAL_N_ELEMENTS(table_Alphabet_ar), number - 1, result);
751 break;
752 case CHARS_ARABIC_ABJAD:
753 lcl_formatChars(table_Alphabet_ar_abjad, SAL_N_ELEMENTS(table_Alphabet_ar_abjad), number - 1, result);
754 break;
755 case CHARS_THAI:
756 lcl_formatChars(table_Alphabet_th, SAL_N_ELEMENTS(table_Alphabet_th), number - 1, result);
757 break;
758 case CHARS_HEBREW:
759 lcl_formatChars(table_Alphabet_he, SAL_N_ELEMENTS(table_Alphabet_he), number - 1, result);
760 break;
761 case CHARS_NEPALI:
762 lcl_formatChars(table_Alphabet_ne, SAL_N_ELEMENTS(table_Alphabet_ne), number - 1, result);
763 break;
764 case CHARS_KHMER:
765 lcl_formatChars(table_Alphabet_km, SAL_N_ELEMENTS(table_Alphabet_km), number - 1, result);
766 break;
767 case CHARS_LAO:
768 lcl_formatChars(table_Alphabet_lo, SAL_N_ELEMENTS(table_Alphabet_lo), number - 1, result);
769 break;
770 case CHARS_MYANMAR:
771 lcl_formatChars(table_Alphabet_my, SAL_N_ELEMENTS(table_Alphabet_my), number - 1, result);
772 break;
773 case CHARS_TIBETAN:
774 lcl_formatChars(table_Alphabet_dz, SAL_N_ELEMENTS(table_Alphabet_dz), number - 1, result);
775 break;
776 case CHARS_CYRILLIC_UPPER_LETTER_BG:
777 lcl_formatChars2( table_CyrillicUpperLetter_bg,
778 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_LOWER_LETTER_BG:
783 lcl_formatChars( table_CyrillicLowerLetter_bg,
784 SAL_N_ELEMENTS(table_CyrillicLowerLetter_bg), number-1,
785 result); // 1=>a, 2=>b, ..., 28=>z, 29=>aa, 30=>ab, ...
786 break;
787 case CHARS_CYRILLIC_UPPER_LETTER_N_BG:
788 lcl_formatChars3( table_CyrillicUpperLetter_bg,
789 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_LOWER_LETTER_N_BG:
794 lcl_formatChars1( table_CyrillicLowerLetter_bg,
795 SAL_N_ELEMENTS(table_CyrillicLowerLetter_bg), number-1,
796 result); // 1=>a, 2=>b, ..., 28=>z, 29=>aa, 30=>bb, ...
797 break;
798 case CHARS_CYRILLIC_UPPER_LETTER_RU:
799 lcl_formatChars2( table_CyrillicUpperLetter_ru,
800 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_LOWER_LETTER_RU:
805 lcl_formatChars( table_CyrillicLowerLetter_ru,
806 SAL_N_ELEMENTS(table_CyrillicLowerLetter_ru), number-1,
807 result); // 1=>a, 2=>b, ..., 27=>z, 28=>aa, 29=>ab, ...
808 break;
809 case CHARS_CYRILLIC_UPPER_LETTER_N_RU:
810 lcl_formatChars3( table_CyrillicUpperLetter_ru,
811 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_LOWER_LETTER_N_RU:
816 lcl_formatChars1( table_CyrillicLowerLetter_ru,
817 SAL_N_ELEMENTS(table_CyrillicLowerLetter_ru), number-1,
818 result); // 1=>a, 2=>b, ..., 27=>z, 28=>aa, 29=>bb, ...
819 break;
820 case CHARS_CYRILLIC_UPPER_LETTER_SR:
821 lcl_formatChars2( table_CyrillicUpperLetter_sr,
822 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_LOWER_LETTER_SR:
827 lcl_formatChars( table_CyrillicLowerLetter_sr,
828 SAL_N_ELEMENTS(table_CyrillicLowerLetter_sr), number-1,
829 result); // 1=>a, 2=>b, ..., 27=>z, 28=>aa, 29=>ab, ...
830 break;
831 case CHARS_CYRILLIC_UPPER_LETTER_N_SR:
832 lcl_formatChars3( table_CyrillicUpperLetter_sr,
833 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;
837 case CHARS_CYRILLIC_LOWER_LETTER_N_SR:
838 lcl_formatChars1( table_CyrillicLowerLetter_sr,
839 SAL_N_ELEMENTS(table_CyrillicLowerLetter_sr), number-1,
840 result); // 1=>a, 2=>b, ..., 27=>z, 28=>aa, 29=>bb, ...
841 break;
843 case CHARS_GREEK_LOWER_LETTER:
844 lcl_formatCharsGR( table_GreekLowerLetter, number, result);
845 break;
847 case CHARS_GREEK_UPPER_LETTER:
848 lcl_formatCharsGR( table_GreekUpperLetter, number, result);
849 break;
851 case CHARS_PERSIAN:
852 lcl_formatChars(table_Alphabet_fa, SAL_N_ELEMENTS(table_Alphabet_fa), number - 1, result);
853 break;
855 case CHARS_PERSIAN_WORD:
856 lcl_formatPersianWord(number, result);
857 break;
859 default:
860 OSL_ASSERT(0);
861 throw IllegalArgumentException();
864 if (natNum) {
865 NativeNumberSupplier sNatNum;
866 result += sNatNum.getNativeNumberString(OUString::valueOf( number ), locale, natNum);
867 } else if (tableSize) {
868 if ( number > tableSize && !recycleSymbol)
869 result += OUString::valueOf( number);
870 else
871 result += OUString(&table[--number % tableSize], 1);
874 // append suffix
875 if( !should_ignore(suffix) ) result += suffix;
877 return result;
880 #define LANG_ALL (1 << 0)
881 #define LANG_CJK (1 << 1)
882 #define LANG_CTL (1 << 2)
884 struct Supported_NumberingType
886 sal_Int16 nType;
887 const sal_Char* cSymbol;
888 sal_Int16 langOption;
890 static const Supported_NumberingType aSupportedTypes[] =
892 {style::NumberingType::CHARS_UPPER_LETTER, "A", LANG_ALL},
893 {style::NumberingType::CHARS_LOWER_LETTER, "a", LANG_ALL},
894 {style::NumberingType::ROMAN_UPPER, "I", LANG_ALL},
895 {style::NumberingType::ROMAN_LOWER, "i", LANG_ALL},
896 {style::NumberingType::ARABIC, "1", LANG_ALL},
897 {style::NumberingType::NUMBER_NONE, "''", LANG_ALL},
898 {style::NumberingType::CHAR_SPECIAL, "Bullet", LANG_ALL},
899 {style::NumberingType::PAGE_DESCRIPTOR, "Page", LANG_ALL},
900 {style::NumberingType::BITMAP, "Bitmap", LANG_ALL},
901 {style::NumberingType::CHARS_UPPER_LETTER_N, "AAA", LANG_ALL},
902 {style::NumberingType::CHARS_LOWER_LETTER_N, "aaa", LANG_ALL},
903 {style::NumberingType::NATIVE_NUMBERING, "Native Numbering", LANG_CJK|LANG_CTL},
904 {style::NumberingType::FULLWIDTH_ARABIC, NULL, LANG_CJK},
905 {style::NumberingType::CIRCLE_NUMBER, NULL, LANG_CJK},
906 {style::NumberingType::NUMBER_LOWER_ZH, NULL, LANG_CJK},
907 {style::NumberingType::NUMBER_UPPER_ZH, NULL, LANG_CJK},
908 {style::NumberingType::NUMBER_UPPER_ZH_TW, NULL, LANG_CJK},
909 {style::NumberingType::TIAN_GAN_ZH, NULL, LANG_CJK},
910 {style::NumberingType::DI_ZI_ZH, NULL, LANG_CJK},
911 {style::NumberingType::NUMBER_TRADITIONAL_JA, NULL, LANG_CJK},
912 {style::NumberingType::AIU_FULLWIDTH_JA, NULL, LANG_CJK},
913 {style::NumberingType::AIU_HALFWIDTH_JA, NULL, LANG_CJK},
914 {style::NumberingType::IROHA_FULLWIDTH_JA, NULL, LANG_CJK},
915 {style::NumberingType::IROHA_HALFWIDTH_JA, NULL, LANG_CJK},
916 {style::NumberingType::NUMBER_UPPER_KO, NULL, LANG_CJK},
917 {style::NumberingType::NUMBER_HANGUL_KO, NULL, LANG_CJK},
918 {style::NumberingType::HANGUL_JAMO_KO, NULL, LANG_CJK},
919 {style::NumberingType::HANGUL_SYLLABLE_KO, NULL, LANG_CJK},
920 {style::NumberingType::HANGUL_CIRCLED_JAMO_KO, NULL, LANG_CJK},
921 {style::NumberingType::HANGUL_CIRCLED_SYLLABLE_KO, NULL, LANG_CJK},
922 {style::NumberingType::CHARS_ARABIC, NULL, LANG_CTL},
923 {style::NumberingType::CHARS_ARABIC_ABJAD, NULL, LANG_CTL},
924 {style::NumberingType::CHARS_THAI, NULL, LANG_CTL},
925 {style::NumberingType::CHARS_HEBREW, NULL, LANG_CTL},
926 {style::NumberingType::CHARS_NEPALI, NULL, LANG_CTL},
927 {style::NumberingType::CHARS_KHMER, NULL, LANG_CTL},
928 {style::NumberingType::CHARS_LAO, NULL, LANG_CTL},
929 {style::NumberingType::CHARS_MYANMAR, NULL, LANG_CTL},
930 {style::NumberingType::CHARS_TIBETAN, NULL, LANG_CTL},
931 {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},
932 {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},
933 {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},
934 {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},
935 {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},
936 {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},
937 {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},
938 {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},
939 {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},
940 {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},
941 {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},
942 {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},
943 {style::NumberingType::CHARS_PERSIAN, NULL, LANG_CTL},
944 {style::NumberingType::CHARS_PERSIAN_WORD, NULL, LANG_CTL},
945 {style::NumberingType::CHARS_GREEK_LOWER_LETTER, C_GR_A ", " C_GR_B ", ... (gr)", LANG_ALL},
946 {style::NumberingType::CHARS_GREEK_UPPER_LETTER, S_GR_A ", " S_GR_B ", ... (gr)", LANG_ALL},
948 static const sal_Int32 nSupported_NumberingTypes = sizeof(aSupportedTypes) / sizeof(Supported_NumberingType);
950 OUString DefaultNumberingProvider::makeNumberingIdentifier(sal_Int16 index)
951 throw(RuntimeException)
953 if (aSupportedTypes[index].cSymbol)
954 return OUString(aSupportedTypes[index].cSymbol, strlen(aSupportedTypes[index].cSymbol), RTL_TEXTENCODING_UTF8);
955 // return OUString::createFromAscii(aSupportedTypes[index].cSymbol);
956 else {
957 OUString result;
958 Locale aLocale(OUString("en"), OUString(), OUString());
959 Sequence<beans::PropertyValue> aProperties(2);
960 aProperties[0].Name = OUString("NumberingType");
961 aProperties[0].Value <<= aSupportedTypes[index].nType;
962 aProperties[1].Name = OUString("Value");
963 for (sal_Int32 j = 1; j <= 3; j++) {
964 aProperties[1].Value <<= j;
965 result += makeNumberingString( aProperties, aLocale );
966 result += OUString(", ");
968 result += OUString("...");
969 return result;
973 sal_Bool SAL_CALL
974 DefaultNumberingProvider::isScriptFlagEnabled(const OUString& aName) throw(RuntimeException)
976 if (! xHierarchicalNameAccess.is()) {
977 Reference< XInterface > xInterface;
979 xInterface = xSMgr->createInstance(OUString("com.sun.star.configuration.ConfigurationProvider"));
980 Reference< XMultiServiceFactory > xConfigProvider =
981 Reference< XMultiServiceFactory >(xInterface, UNO_QUERY );
983 if (! xConfigProvider.is())
984 throw RuntimeException();
986 Sequence< Any > aArgs(1);
987 beans::PropertyValue aPath;
988 aPath.Name = OUString("nodepath");
989 aPath.Value <<= OUString("/org.openoffice.Office.Common/I18N"),
990 aArgs[0] <<= aPath;
992 xInterface = xConfigProvider->createInstanceWithArguments(
993 OUString("com.sun.star.configuration.ConfigurationAccess"), aArgs);
995 xHierarchicalNameAccess.set(xInterface, UNO_QUERY);
997 if (! xHierarchicalNameAccess.is())
998 throw RuntimeException();
1001 Any aEnabled = xHierarchicalNameAccess->getByHierarchicalName(aName);
1003 sal_Bool enabled = sal_False;
1005 aEnabled >>= enabled;
1007 return enabled;
1010 Sequence< sal_Int16 > DefaultNumberingProvider::getSupportedNumberingTypes( )
1011 throw(RuntimeException)
1013 Sequence< sal_Int16 > aRet(nSupported_NumberingTypes );
1014 sal_Int16* pArray = aRet.getArray();
1016 sal_Bool cjkEnabled = isScriptFlagEnabled(OUString("CJK/CJKFont"));
1017 sal_Bool ctlEnabled = isScriptFlagEnabled(OUString("CTL/CTLFont"));
1019 for(sal_Int16 i = 0; i < nSupported_NumberingTypes; i++) {
1020 if ( (aSupportedTypes[i].langOption & LANG_ALL) ||
1021 ((aSupportedTypes[i].langOption & LANG_CJK) && cjkEnabled) ||
1022 ((aSupportedTypes[i].langOption & LANG_CTL) && ctlEnabled) )
1023 pArray[i] = aSupportedTypes[i].nType;
1025 return aRet;
1028 sal_Int16 DefaultNumberingProvider::getNumberingType( const OUString& rNumberingIdentifier )
1029 throw(RuntimeException)
1031 for(sal_Int16 i = 0; i < nSupported_NumberingTypes; i++)
1032 if(rNumberingIdentifier.equals(makeNumberingIdentifier(i)))
1033 return aSupportedTypes[i].nType;
1034 throw RuntimeException();
1037 sal_Bool DefaultNumberingProvider::hasNumberingType( const OUString& rNumberingIdentifier )
1038 throw(RuntimeException)
1040 for(sal_Int16 i = 0; i < nSupported_NumberingTypes; i++)
1041 if(rNumberingIdentifier.equals(makeNumberingIdentifier(i)))
1042 return sal_True;
1043 return sal_False;
1046 OUString DefaultNumberingProvider::getNumberingIdentifier( sal_Int16 nNumberingType )
1047 throw(RuntimeException)
1049 for(sal_Int16 i = 0; i < nSupported_NumberingTypes; i++)
1050 if(nNumberingType == aSupportedTypes[i].nType)
1051 return makeNumberingIdentifier(i);
1052 return OUString();
1055 const sal_Char cDefaultNumberingProvider[] = "com.sun.star.text.DefaultNumberingProvider";
1056 OUString DefaultNumberingProvider::getImplementationName(void)
1057 throw( RuntimeException )
1059 return OUString::createFromAscii(cDefaultNumberingProvider);
1062 sal_Bool DefaultNumberingProvider::supportsService(const rtl::OUString& rServiceName)
1063 throw( RuntimeException )
1065 return rServiceName.equalsAscii(cDefaultNumberingProvider);
1068 Sequence< OUString > DefaultNumberingProvider::getSupportedServiceNames(void)
1069 throw( RuntimeException )
1071 Sequence< OUString > aRet(1);
1072 aRet[0] = OUString::createFromAscii(cDefaultNumberingProvider);
1073 return aRet;
1076 } } } }
1078 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */