merged tag ooo/OOO330_m14
[LibreOffice.git] / i18npool / source / defaultnumberingprovider / defaultnumberingprovider.cxx
blob751116160ebe403493826a73f4022a37dfeb4c13
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_i18npool.hxx"
30 #include <defaultnumberingprovider.hxx>
31 #include <com/sun/star/style/NumberingType.hpp>
32 #include <com/sun/star/beans/PropertyValue.hpp>
33 #include <com/sun/star/text/HoriOrientation.hpp>
34 #include <localedata.hxx>
35 #include <nativenumbersupplier.hxx>
36 #include <stdio.h>
37 #include <string.h>
39 // Cyrillic upper case
40 #define C_CYR_A "\xD0\x90"
41 #define C_CYR_B "\xD0\x91"
42 // Cyrillic lower case
43 #define S_CYR_A "\xD0\xB0"
44 #define S_CYR_B "\xD0\xB1"
46 #include <math.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;
59 using namespace ::rtl;
61 namespace com { namespace sun { namespace star { namespace i18n {
63 static 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 sal_Unicode table_Alphabet_th[] = {
71 0x0E01, 0x0E02, 0x0E04, 0x0E07,
72 0x0E08, 0x0E09, 0x0E0A, 0x0E0B, 0x0E0C, 0x0E0D, 0x0E0E, 0x0E0F,
73 0x0E10, 0x0E11, 0x0E12, 0x0E13, 0x0E14, 0x0E15, 0x0E16, 0x0E17,
74 0x0E18, 0x0E19, 0x0E1A, 0x0E1B, 0x0E1C, 0x0E1D, 0x0E1E, 0x0E1F,
75 0x0E20, 0x0E21, 0x0E22, 0x0E23, 0x0E24, 0x0E25, 0x0E26, 0x0E27,
76 0x0E28, 0x0E29, 0x0E2A, 0x0E2B, 0x0E2C, 0x0E2D, 0x0E2E
79 static sal_Unicode table_Alphabet_he[] = {
80 0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7,
81 0x05D8, 0x05D9, 0x05DB, 0x05DC, 0x05DE, 0x05E0, 0x05E1, 0x05E2,
82 0x05E4, 0x05E6, 0x05E7, 0x05E8, 0x05E9, 0x05EA
85 static sal_Unicode table_Alphabet_ne[] = {
86 0x0915, 0x0916, 0x0917, 0x0918, 0x0919, 0x091A, 0x091B, 0x091C,
87 0x091D, 0x091E, 0x091F, 0x0920, 0x0921, 0x0922, 0x0923, 0x0924,
88 0x0925, 0x0926, 0x0927, 0x0928, 0x092A, 0x092B, 0x092C, 0x092D,
89 0x092E, 0x092F, 0x0930, 0x0932, 0x0935, 0x0936, 0x0937, 0x0938,
90 0x0939
93 static sal_Unicode table_Alphabet_km[] = {
94 0x1780, 0x1781, 0x1782, 0x1783, 0x1784, 0x1785, 0x1786, 0x1787,
95 0x1788, 0x1789, 0x178A, 0x178B, 0x178C, 0x178D, 0x178E, 0x178F,
96 0x1790, 0x1791, 0x1792, 0x1793, 0x1794, 0x1795, 0x1796, 0x1797,
97 0x1798, 0x1799, 0x179A, 0x179B, 0x179C, 0x179F,
98 0x17A0, 0x17A1, 0x17A2
101 static sal_Unicode table_Alphabet_lo[] = {
102 0x0E81, 0x0E82, 0x0E84, 0x0E87, 0x0E88, 0x0E8A, 0x0E8D, 0x0E94,
103 0x0E95, 0x0E96, 0x0E97, 0x0E99, 0x0E9A, 0x0E9B, 0x0E9C,
104 0x0E9D, 0x0E9E, 0x0E9F, 0x0EA1, 0x0EA2, 0x0EA3, 0x0EA5, 0x0EA7,
105 0x0EAA, 0x0EAB, 0x0EAD, 0x0EAE, 0x0EAF, 0x0EAE, 0x0EDC, 0x0EDD
108 static sal_Unicode table_Alphabet_dz[] = {
109 0x0F40, 0x0F41, 0x0F42, 0x0F44, 0x0F45, 0x0F46, 0x0F47, 0x0F49,
110 0x0F4F, 0x0F50, 0x0F51, 0x0F53, 0x0F54, 0x0F55, 0x0F56, 0x0F58,
111 0x0F59, 0x0F5A, 0x0F5B, 0x0F5D, 0x0F5E, 0x0F5F, 0x0F60, 0x0F61,
112 0x0F62, 0x0F63, 0x0F64, 0x0F66, 0x0F67, 0x0F68
115 static sal_Unicode table_Alphabet_my[] = {
116 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006, 0x1007,
117 0x1008,/*0x1009,*/0x100A, 0x100B, 0x100C, 0x100D, 0x100E, 0x100F,
118 0x1010, 0x1011, 0x1012, 0x1013, 0x1014, 0x1015, 0x1016, 0x1017,
119 0x1018, 0x1019, 0x101A, 0x101B, 0x101C, 0x101D, 0x101E, 0x101F,
120 0x1020, 0x1021
123 // Bulgarian Cyrillic upper case letters
124 static sal_Unicode table_CyrillicUpperLetter_bg[] = {
125 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418,
126 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, 0x0420, 0x0421, 0x0422,
127 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042E,
128 0x042F
131 // Bulgarian cyrillic lower case letters
132 static sal_Unicode table_CyrillicLowerLetter_bg[] = {
133 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438,
134 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F, 0x0440, 0x0441, 0x0442,
135 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044E,
136 0x044F
139 // Russian Cyrillic upper letters
140 static sal_Unicode table_CyrillicUpperLetter_ru[] = {
141 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
142 0x0418, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, 0x0420,
143 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428,
144 0x0429, 0x042B, 0x042D, 0x042E, 0x042F
147 // Russian cyrillic lower letters
148 static sal_Unicode table_CyrillicLowerLetter_ru[] = {
149 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
150 0x0438, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F, 0x0440,
151 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448,
152 0x0449, 0x044B, 0x044D, 0x044E, 0x044F
155 // Serbian Cyrillic upper letters
156 static sal_Unicode table_CyrillicUpperLetter_sr[] = {
157 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0402, 0x0415, 0x0416,
158 0x0417, 0x0418, 0x0408, 0x041A, 0x041B, 0x0409, 0x041C, 0x041D,
159 0x040A, 0x041E, 0x041F, 0x0420, 0x0421, 0x0422, 0x040B, 0x0423,
160 0x0424, 0x0425, 0x0426, 0x0427, 0x040F, 0x0428
163 // Serbian cyrillic lower letters
164 static sal_Unicode table_CyrillicLowerLetter_sr[] = {
165 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0452, 0x0435, 0x0436,
166 0x0437, 0x0438, 0x0458, 0x043A, 0x043B, 0x0459, 0x043C, 0x043D,
167 0x045A, 0x043E, 0x043F, 0x0440, 0x0441, 0x0442, 0x045B, 0x0443,
168 0x0444, 0x0445, 0x0446, 0x0447, 0x045F, 0x0448
171 static sal_Unicode table_Alphabet_fa[] = {
172 0x0622, 0x0628, 0x067E, 0x062A, 0x062B, 0x062C, 0x0686, 0x062D,
173 0x062E, 0x062F, 0x0630, 0x0631, 0x0632, 0x0698, 0x0633, 0x0634,
174 0x0635, 0x0636, 0x0637, 0x0638, 0x0639, 0x0640, 0x0641, 0x0642,
175 0x06A9, 0x06AF, 0x0644, 0x0645, 0x0646, 0x0648, 0x0647, 0x06CC
178 static sal_Unicode upperLetter[] = {
179 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
180 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52,
181 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A
184 static sal_Unicode lowerLetter[] = {
185 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
186 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72,
187 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A
190 DefaultNumberingProvider::DefaultNumberingProvider( const Reference < XMultiServiceFactory >& xMSF ) : xSMgr(xMSF),translit(NULL)
195 DefaultNumberingProvider::~DefaultNumberingProvider()
197 delete translit;
200 void DefaultNumberingProvider::impl_loadTranslit()
202 if ( !translit )
203 translit = new TransliterationImpl(xSMgr);
206 Sequence< Reference<container::XIndexAccess> >
207 DefaultNumberingProvider::getDefaultOutlineNumberings(const Locale& rLocale ) throw(RuntimeException)
209 return LocaleData().getOutlineNumberingLevels( rLocale );
212 Sequence< Sequence<beans::PropertyValue> >
213 DefaultNumberingProvider::getDefaultContinuousNumberingLevels( const Locale& rLocale ) throw(RuntimeException)
215 return LocaleData().getContinuousNumberingLevels( rLocale );
218 OUString toRoman( sal_Int32 n )
221 // i, ii, iii, iv, v, vi, vii, vii, viii, ix
222 // (Dummy),1000,500,100,50,10,5,1
223 static const sal_Char coRomanArr[] = "MDCLXVI--"; // +2 Dummy entries !!
224 const sal_Char* cRomanStr = coRomanArr;
225 sal_uInt16 nMask = 1000;
226 sal_uInt32 nOver1000 = n / nMask;
227 n -= ( nOver1000 * nMask );
229 OUStringBuffer sTmp;
230 while(nOver1000--)
231 sTmp.append(sal_Unicode(*coRomanArr));
233 while( nMask )
235 sal_uInt8 nZahl = sal_uInt8( n / nMask );
236 sal_uInt8 nDiff = 1;
237 n %= nMask;
239 if( 5 < nZahl )
241 if( nZahl < 9 )
242 sTmp.append(sal_Unicode(*(cRomanStr-1)));
243 ++nDiff;
244 nZahl -= 5;
246 switch( nZahl )
248 case 3: sTmp.append(sal_Unicode(*cRomanStr)); //no break!
249 case 2: sTmp.append(sal_Unicode(*cRomanStr)); //no break!
250 case 1: sTmp.append(sal_Unicode(*cRomanStr)); break;
251 case 4: sTmp.append(sal_Unicode(*cRomanStr)).append(sal_Unicode(*(cRomanStr-nDiff))); break;
252 case 5: sTmp.append(sal_Unicode(*(cRomanStr-nDiff))); break;
255 nMask /= 10; // to the next decade
256 cRomanStr += 2;
258 return sTmp.makeStringAndClear();
261 // not used:
262 #if 0
264 static
265 const char* expected_name( int i, int last )
267 if(0);
268 else if( i==0 ) return "Prefix";
269 else if( i==1 ) return "NumberingType";
270 else if( i==2 ) return "Suffix";
271 else if( i==last ) return "Value";
272 else { OSL_ASSERT(0); return ""; }
274 static
275 const char* expected_type( int i, int last )
277 if(0);
278 else if( i==0 ) return "OUString";
279 else if( i==1 ) return "sal_Int16";
280 else if( i==2 ) return "OUString";
281 else if( i==last ) return "sal_Int32";
282 else { OSL_ASSERT(0); return ""; }
284 static
285 void failedToConvert( int i, int last )
287 throw IllegalArgumentException();
290 #endif
292 static
293 void lcl_formatChars( sal_Unicode table[], int tableSize, int n, OUString& s )
295 // string representation of n is appended to s.
296 // if A=='A' then 0=>A, 1=>B, ..., 25=>Z, 26=>AA, 27=>AB, ...
297 // if A=='a' then 0=>a, 1=>b, ..., 25=>z, 26=>aa, 27=>ab, ...
299 if( n>=tableSize ) lcl_formatChars( table, tableSize, (n-tableSize)/tableSize, s );
301 s += OUString::valueOf( table[ n % tableSize ] );
304 static
305 void lcl_formatChars1( sal_Unicode table[], int tableSize, int n, OUString& s )
307 // string representation of n is appended to s.
308 // if A=='A' then 0=>A, 1=>B, ..., 25=>Z, 26=>AA, 27=>BB, ...
309 // if A=='a' then 0=>a, 1=>b, ..., 25=>z, 26=>aa, 27=>bb, ...
311 int repeat_count = n / tableSize + 1;
313 for( int i=0; i<repeat_count; i++ )
314 s += OUString::valueOf( table[ n%tableSize ] );
317 static
318 void lcl_formatChars2( sal_Unicode table_capital[], sal_Unicode table_small[], int tableSize, int n, OUString& s )
320 // string representation of n is appended to s.
321 // if A=='A' then 0=>A, 1=>B, ..., 25=>Z, 26=>Aa, 27=>Ab, ...
323 if( n>=tableSize )
325 lcl_formatChars2( table_capital, table_small, tableSize, (n-tableSize)/tableSize, s );
326 s += OUString::valueOf( table_small[ n % tableSize ] );
327 } else
328 s += OUString::valueOf( table_capital[ n % tableSize ] );
331 static
332 void lcl_formatChars3( sal_Unicode table_capital[], sal_Unicode table_small[], int tableSize, int n, OUString& s )
334 // string representation of n is appended to s.
335 // if A=='A' then 0=>A, 1=>B, ..., 25=>Z, 26=>Aa, 27=>Bb, ...
337 int repeat_count = n / tableSize + 1;
338 s += OUString::valueOf( table_capital[ n%tableSize ] );
340 for( int i=1; i<repeat_count; i++ )
341 s += OUString::valueOf( table_small[ n%tableSize ] );
344 static
345 int should_ignore( OUString s )
347 // return true if blank or null
348 return s.compareToAscii(" ")==0 || (s.getLength()>0 && s[0]==0);
351 static
352 Any getPropertyByName( const Sequence<beans::PropertyValue>& aProperties,
353 const char* name, sal_Bool bRequired )
355 for( int i=0; i<aProperties.getLength(); i++ )
356 if( aProperties[i].Name.equalsAscii(name) )
357 return aProperties[i].Value;
358 if(bRequired)
359 throw IllegalArgumentException();
360 return Any();
363 //XNumberingFormatter
364 OUString
365 DefaultNumberingProvider::makeNumberingString( const Sequence<beans::PropertyValue>& aProperties,
366 const Locale& aLocale )
367 throw( IllegalArgumentException, RuntimeException )
369 // the Sequence of PropertyValues is expected to have at least 4 elements:
370 // elt Name Type purpose
371 // -----------------------------------------------------------------
373 // 0. "Prefix" OUString
374 // 1. "NumberingType" sal_Int16 type of formatting from style::NumberingType (roman, arabic, etc)
375 // 2. "Suffix" OUString
376 // ... ... ...
377 // n. "Value" sal_Int32 the number to be formatted
378 // example:
379 // given the Sequence { '(', NumberingType::ROMAN_UPPER, ')', ..., 7 }
380 // makeNumberingString() returns the string "(VII)".
382 // Q: why is the type of numType sal_Int16 instead of style::NumberingType?
383 // A: an Any can't hold a style::NumberingType for some reason.
384 // add.: style::NumberingType holds constants of type sal_Int16, it's not an enum type
386 sal_Int16 natNum = 0;
387 sal_Int16 tableSize = 0;
388 sal_Unicode *table = NULL; // initialize to avoid compiler warning
389 sal_Bool recycleSymbol = sal_False;
390 Locale locale;
392 OUString prefix;
393 sal_Int16 numType = -1; // type of formatting from style::NumberingType (roman, arabic, etc)
394 OUString suffix;
395 sal_Int32 number = -12345; // the number that needs to be formatted.
397 // int nProperties = aProperties.getLength();
398 // int last = nProperties-1;
400 try {
401 getPropertyByName(aProperties, "Prefix", sal_False) >>=prefix;
402 } catch (Exception&) {
403 //prefix _must_ be empty here!
405 try {
406 getPropertyByName(aProperties, "Suffix", sal_False) >>=suffix;
407 } catch (Exception&) {
408 //suffix _must_ be empty here!
410 try {
411 getPropertyByName(aProperties, "NumberingType", sal_True) >>=numType;
412 } catch (Exception& ) {
413 numType = -1;
415 try {
416 getPropertyByName(aProperties, "Value", sal_True) >>=number;
417 } catch (Exception& ) {
418 number = -1;
421 if( number <= 0 )
422 throw IllegalArgumentException();
424 // start empty
425 OUString result;
427 // append prefix
428 if( !should_ignore(prefix) ) result += prefix;
430 // append formatted number
431 using namespace style::NumberingType;
432 switch( numType )
434 case CHARS_UPPER_LETTER:
435 lcl_formatChars( upperLetter, 26, number-1, result ); // 1=>A, 2=>B, ..., 26=>Z, 27=>AA, 28=>AB, ...
436 break;
437 case CHARS_LOWER_LETTER:
438 lcl_formatChars( lowerLetter, 26, number-1, result );
439 break;
440 case ROMAN_UPPER:
441 result += toRoman( number );
442 break;
443 case ROMAN_LOWER:
444 result += toRoman( number ).toAsciiLowerCase();
445 break;
446 case ARABIC:
447 result += OUString::valueOf( number );
448 break;
449 case NUMBER_NONE:
450 return OUString::createFromAscii(""); // ignore prefix and suffix
451 case CHAR_SPECIAL:
452 // apparently, we're supposed to return an empty string in this case...
453 return OUString::createFromAscii(""); // ignore prefix and suffix
454 case PAGE_DESCRIPTOR:
455 case BITMAP:
456 OSL_ASSERT(0);
457 throw IllegalArgumentException();
458 case CHARS_UPPER_LETTER_N:
459 lcl_formatChars1( upperLetter, 26, number-1, result ); // 1=>A, 2=>B, ..., 26=>Z, 27=>AA, 28=>BB, ...
460 break;
461 case CHARS_LOWER_LETTER_N:
462 lcl_formatChars1( lowerLetter, 26, number-1, result ); // 1=>A, 2=>B, ..., 26=>Z, 27=>AA, 28=>BB, ...
463 break;
464 case TRANSLITERATION:
465 try {
466 const OUString &tmp = OUString::valueOf( number );
467 OUString transliteration;
468 getPropertyByName(aProperties, "Transliteration", sal_True) >>= transliteration;
469 impl_loadTranslit();
470 translit->loadModuleByImplName(transliteration, aLocale);
471 result += translit->transliterateString2String(tmp, 0, tmp.getLength());
472 } catch (Exception& ) {
473 // When translteration property is missing, return default number (bug #101141#)
474 result += OUString::valueOf( number );
475 // OSL_ASSERT(0);
476 // throw IllegalArgumentException();
478 break;
479 case NATIVE_NUMBERING:
480 natNum = NativeNumberMode::NATNUM1;
481 locale = aLocale;
482 break;
483 case FULLWIDTH_ARABIC:
484 natNum = NativeNumberMode::NATNUM3;
485 locale = aLocale;
486 break;
487 case NUMBER_LOWER_ZH:
488 natNum = NativeNumberMode::NATNUM7;
489 locale.Language = OUString::createFromAscii("zh");
490 break;
491 case NUMBER_UPPER_ZH_TW:
492 locale.Country = OUString::createFromAscii("TW");
493 case NUMBER_UPPER_ZH:
494 natNum = NativeNumberMode::NATNUM8;
495 locale.Language = OUString::createFromAscii("zh");
496 break;
497 case NUMBER_TRADITIONAL_JA:
498 natNum = NativeNumberMode::NATNUM8;
499 locale.Language = OUString::createFromAscii("ja");
500 break;
501 case NUMBER_UPPER_KO:
502 natNum = NativeNumberMode::NATNUM8;
503 locale.Language = OUString::createFromAscii("ko");
504 break;
505 case NUMBER_HANGUL_KO:
506 natNum = NativeNumberMode::NATNUM11;
507 locale.Language = OUString::createFromAscii("ko");
508 break;
510 case CIRCLE_NUMBER:
511 table = table_CircledNumber;
512 tableSize = sizeof(table_CircledNumber) / sizeof(sal_Unicode);
513 break;
514 case TIAN_GAN_ZH:
515 table = table_TianGan_zh;
516 tableSize = sizeof(table_TianGan_zh) / sizeof(sal_Unicode);
517 break;
518 case DI_ZI_ZH:
519 table = table_DiZi_zh;
520 tableSize = sizeof(table_DiZi_zh) / sizeof(sal_Unicode);
521 break;
522 case AIU_FULLWIDTH_JA:
523 table = table_AIUFullWidth_ja_JP;
524 tableSize = sizeof(table_AIUFullWidth_ja_JP) / sizeof(sal_Unicode);
525 recycleSymbol = sal_True;
526 break;
527 case AIU_HALFWIDTH_JA:
528 table = table_AIUHalfWidth_ja_JP;
529 tableSize = sizeof(table_AIUHalfWidth_ja_JP) / sizeof(sal_Unicode);
530 recycleSymbol = sal_True;
531 break;
532 case IROHA_FULLWIDTH_JA:
533 table = table_IROHAFullWidth_ja_JP;
534 tableSize = sizeof(table_IROHAFullWidth_ja_JP) / sizeof(sal_Unicode);
535 recycleSymbol = sal_True;
536 break;
537 case IROHA_HALFWIDTH_JA:
538 table = table_IROHAHalfWidth_ja_JP;
539 tableSize = sizeof(table_IROHAHalfWidth_ja_JP) / sizeof(sal_Unicode);
540 recycleSymbol = sal_True;
541 break;
542 case HANGUL_JAMO_KO:
543 table = table_HangulJamo_ko;
544 tableSize = sizeof(table_HangulJamo_ko) / sizeof(sal_Unicode);
545 recycleSymbol = sal_True;
546 break;
547 case HANGUL_SYLLABLE_KO:
548 table = table_HangulSyllable_ko;
549 tableSize = sizeof(table_HangulSyllable_ko) / sizeof(sal_Unicode);
550 recycleSymbol = sal_True;
551 break;
552 case HANGUL_CIRCLED_JAMO_KO:
553 table = table_HangulCircledJamo_ko;
554 tableSize = sizeof(table_HangulCircledJamo_ko) / sizeof(sal_Unicode);
555 recycleSymbol = sal_True;
556 break;
557 case HANGUL_CIRCLED_SYLLABLE_KO:
558 table = table_HangulCircledSyllable_ko;
559 tableSize = sizeof(table_HangulCircledSyllable_ko) / sizeof(sal_Unicode);
560 recycleSymbol = sal_True;
561 break;
562 case CHARS_ARABIC:
563 lcl_formatChars(table_Alphabet_ar, sizeof(table_Alphabet_ar) / sizeof(sal_Unicode), number - 1, result);
564 break;
565 case CHARS_THAI:
566 lcl_formatChars(table_Alphabet_th, sizeof(table_Alphabet_th) / sizeof(sal_Unicode), number - 1, result);
567 break;
568 case CHARS_HEBREW:
569 lcl_formatChars(table_Alphabet_he, sizeof(table_Alphabet_he) / sizeof(sal_Unicode), number - 1, result);
570 break;
571 case CHARS_NEPALI:
572 lcl_formatChars(table_Alphabet_ne, sizeof(table_Alphabet_ne) / sizeof(sal_Unicode), number - 1, result);
573 break;
574 case CHARS_KHMER:
575 lcl_formatChars(table_Alphabet_km, sizeof(table_Alphabet_km) / sizeof(sal_Unicode), number - 1, result);
576 break;
577 case CHARS_LAO:
578 lcl_formatChars(table_Alphabet_lo, sizeof(table_Alphabet_lo) / sizeof(sal_Unicode), number - 1, result);
579 break;
580 case CHARS_MYANMAR:
581 lcl_formatChars(table_Alphabet_my, sizeof(table_Alphabet_my) / sizeof(sal_Unicode), number - 1, result);
582 break;
583 case CHARS_TIBETAN:
584 lcl_formatChars(table_Alphabet_dz, sizeof(table_Alphabet_dz) / sizeof(sal_Unicode), number - 1, result);
585 break;
586 case CHARS_CYRILLIC_UPPER_LETTER_BG:
587 lcl_formatChars2( table_CyrillicUpperLetter_bg,
588 table_CyrillicLowerLetter_bg,
589 sizeof(table_CyrillicLowerLetter_bg) /
590 sizeof(table_CyrillicLowerLetter_bg[0]), number-1,
591 result); // 1=>a, 2=>b, ..., 28=>z, 29=>Aa, 30=>Ab, ...
592 break;
593 case CHARS_CYRILLIC_LOWER_LETTER_BG:
594 lcl_formatChars( table_CyrillicLowerLetter_bg,
595 sizeof(table_CyrillicLowerLetter_bg) /
596 sizeof(table_CyrillicLowerLetter_bg[0]), number-1,
597 result); // 1=>a, 2=>b, ..., 28=>z, 29=>aa, 30=>ab, ...
598 break;
599 case CHARS_CYRILLIC_UPPER_LETTER_N_BG:
600 lcl_formatChars3( table_CyrillicUpperLetter_bg,
601 table_CyrillicLowerLetter_bg,
602 sizeof(table_CyrillicLowerLetter_bg) /
603 sizeof(table_CyrillicLowerLetter_bg[0]), number-1,
604 result); // 1=>a, 2=>b, ..., 28=>z, 29=>Aa, 30=>Bb, ...
605 break;
606 case CHARS_CYRILLIC_LOWER_LETTER_N_BG:
607 lcl_formatChars1( table_CyrillicLowerLetter_bg,
608 sizeof(table_CyrillicLowerLetter_bg) /
609 sizeof(table_CyrillicLowerLetter_bg[0]), number-1,
610 result); // 1=>a, 2=>b, ..., 28=>z, 29=>aa, 30=>bb, ...
611 break;
612 case CHARS_CYRILLIC_UPPER_LETTER_RU:
613 lcl_formatChars2( table_CyrillicUpperLetter_ru,
614 table_CyrillicLowerLetter_ru,
615 sizeof(table_CyrillicLowerLetter_ru) /
616 sizeof(table_CyrillicLowerLetter_ru[0]), number-1,
617 result); // 1=>a, 2=>b, ..., 27=>z, 28=>Aa, 29=>Ab, ...
618 break;
619 case CHARS_CYRILLIC_LOWER_LETTER_RU:
620 lcl_formatChars( table_CyrillicLowerLetter_ru,
621 sizeof(table_CyrillicLowerLetter_ru) /
622 sizeof(table_CyrillicLowerLetter_ru[0]), number-1,
623 result); // 1=>a, 2=>b, ..., 27=>z, 28=>aa, 29=>ab, ...
624 break;
625 case CHARS_CYRILLIC_UPPER_LETTER_N_RU:
626 lcl_formatChars3( table_CyrillicUpperLetter_ru,
627 table_CyrillicLowerLetter_ru,
628 sizeof(table_CyrillicLowerLetter_ru) /
629 sizeof(table_CyrillicLowerLetter_ru[0]), number-1,
630 result); // 1=>a, 2=>b, ..., 27=>z, 28=>Aa, 29=>Bb, ...
631 break;
632 case CHARS_CYRILLIC_LOWER_LETTER_N_RU:
633 lcl_formatChars1( table_CyrillicLowerLetter_ru,
634 sizeof(table_CyrillicLowerLetter_ru) /
635 sizeof(table_CyrillicLowerLetter_ru[0]), number-1,
636 result); // 1=>a, 2=>b, ..., 27=>z, 28=>aa, 29=>bb, ...
637 break;
638 case CHARS_CYRILLIC_UPPER_LETTER_SR:
639 lcl_formatChars2( table_CyrillicUpperLetter_sr,
640 table_CyrillicLowerLetter_sr,
641 sizeof(table_CyrillicLowerLetter_sr) /
642 sizeof(table_CyrillicLowerLetter_sr[0]), number-1,
643 result); // 1=>a, 2=>b, ..., 27=>z, 28=>Aa, 29=>Ab, ...
644 break;
645 case CHARS_CYRILLIC_LOWER_LETTER_SR:
646 lcl_formatChars( table_CyrillicLowerLetter_sr,
647 sizeof(table_CyrillicLowerLetter_sr) /
648 sizeof(table_CyrillicLowerLetter_sr[0]), number-1,
649 result); // 1=>a, 2=>b, ..., 27=>z, 28=>aa, 29=>ab, ...
650 break;
651 case CHARS_CYRILLIC_UPPER_LETTER_N_SR:
652 lcl_formatChars3( table_CyrillicUpperLetter_sr,
653 table_CyrillicLowerLetter_sr,
654 sizeof(table_CyrillicLowerLetter_sr) /
655 sizeof(table_CyrillicLowerLetter_sr[0]), number-1,
656 result); // 1=>a, 2=>b, ..., 27=>z, 28=>Aa, 29=>Bb, ...
657 break;
658 case CHARS_CYRILLIC_LOWER_LETTER_N_SR:
659 lcl_formatChars1( table_CyrillicLowerLetter_sr,
660 sizeof(table_CyrillicLowerLetter_sr) /
661 sizeof(table_CyrillicLowerLetter_sr[0]), number-1,
662 result); // 1=>a, 2=>b, ..., 27=>z, 28=>aa, 29=>bb, ...
663 break;
664 case CHARS_PERSIAN:
665 lcl_formatChars(table_Alphabet_fa, sizeof(table_Alphabet_fa) / sizeof(sal_Unicode), number - 1, result);
666 break;
668 default:
669 OSL_ASSERT(0);
670 throw IllegalArgumentException();
673 if (natNum) {
674 NativeNumberSupplier sNatNum;
675 result += sNatNum.getNativeNumberString(OUString::valueOf( number ), locale, natNum);
676 } else if (tableSize) {
677 if ( number > tableSize && !recycleSymbol)
678 result += OUString::valueOf( number);
679 else
680 result += OUString(&table[--number % tableSize], 1);
683 // append suffix
684 if( !should_ignore(suffix) ) result += suffix;
686 return result;
688 /* -----------------------------21.02.01 15:57--------------------------------
690 ---------------------------------------------------------------------------*/
692 #define LANG_ALL (1 << 0)
693 #define LANG_CJK (1 << 1)
694 #define LANG_CTL (1 << 2)
696 struct Supported_NumberingType
698 sal_Int16 nType;
699 const sal_Char* cSymbol;
700 sal_Int16 langOption;
702 static const Supported_NumberingType aSupportedTypes[] =
704 {style::NumberingType::CHARS_UPPER_LETTER, "A", LANG_ALL},
705 {style::NumberingType::CHARS_LOWER_LETTER, "a", LANG_ALL},
706 {style::NumberingType::ROMAN_UPPER, "I", LANG_ALL},
707 {style::NumberingType::ROMAN_LOWER, "i", LANG_ALL},
708 {style::NumberingType::ARABIC, "1", LANG_ALL},
709 {style::NumberingType::NUMBER_NONE, "''", LANG_ALL},
710 {style::NumberingType::CHAR_SPECIAL, "Bullet", LANG_ALL},
711 {style::NumberingType::PAGE_DESCRIPTOR, "Page", LANG_ALL},
712 {style::NumberingType::BITMAP, "Bitmap", LANG_ALL},
713 {style::NumberingType::CHARS_UPPER_LETTER_N, "AAA", LANG_ALL},
714 {style::NumberingType::CHARS_LOWER_LETTER_N, "aaa", LANG_ALL},
715 {style::NumberingType::NATIVE_NUMBERING, "Native Numbering", LANG_CJK|LANG_CTL},
716 {style::NumberingType::FULLWIDTH_ARABIC, NULL, LANG_CJK},
717 {style::NumberingType::CIRCLE_NUMBER, NULL, LANG_CJK},
718 {style::NumberingType::NUMBER_LOWER_ZH, NULL, LANG_CJK},
719 {style::NumberingType::NUMBER_UPPER_ZH, NULL, LANG_CJK},
720 {style::NumberingType::NUMBER_UPPER_ZH_TW, NULL, LANG_CJK},
721 {style::NumberingType::TIAN_GAN_ZH, NULL, LANG_CJK},
722 {style::NumberingType::DI_ZI_ZH, NULL, LANG_CJK},
723 {style::NumberingType::NUMBER_TRADITIONAL_JA, NULL, LANG_CJK},
724 {style::NumberingType::AIU_FULLWIDTH_JA, NULL, LANG_CJK},
725 {style::NumberingType::AIU_HALFWIDTH_JA, NULL, LANG_CJK},
726 {style::NumberingType::IROHA_FULLWIDTH_JA, NULL, LANG_CJK},
727 {style::NumberingType::IROHA_HALFWIDTH_JA, NULL, LANG_CJK},
728 {style::NumberingType::NUMBER_UPPER_KO, NULL, LANG_CJK},
729 {style::NumberingType::NUMBER_HANGUL_KO, NULL, LANG_CJK},
730 {style::NumberingType::HANGUL_JAMO_KO, NULL, LANG_CJK},
731 {style::NumberingType::HANGUL_SYLLABLE_KO, NULL, LANG_CJK},
732 {style::NumberingType::HANGUL_CIRCLED_JAMO_KO, NULL, LANG_CJK},
733 {style::NumberingType::HANGUL_CIRCLED_SYLLABLE_KO, NULL, LANG_CJK},
734 {style::NumberingType::CHARS_ARABIC, NULL, LANG_CTL},
735 {style::NumberingType::CHARS_THAI, NULL, LANG_CTL},
736 {style::NumberingType::CHARS_HEBREW, NULL, LANG_CTL},
737 {style::NumberingType::CHARS_NEPALI, NULL, LANG_CTL},
738 {style::NumberingType::CHARS_KHMER, NULL, LANG_CTL},
739 {style::NumberingType::CHARS_LAO, NULL, LANG_CTL},
740 {style::NumberingType::CHARS_MYANMAR, NULL, LANG_CTL},
741 {style::NumberingType::CHARS_TIBETAN, NULL, LANG_CTL},
742 {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},
743 {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},
744 {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},
745 {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},
746 {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},
747 {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},
748 {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},
749 {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},
750 {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},
751 {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},
752 {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},
753 {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},
754 {style::NumberingType::CHARS_PERSIAN, NULL, LANG_CTL},
756 static const sal_Int32 nSupported_NumberingTypes = sizeof(aSupportedTypes) / sizeof(Supported_NumberingType);
757 /* -----------------------------21.02.01 15:57--------------------------------
759 ---------------------------------------------------------------------------*/
761 OUString DefaultNumberingProvider::makeNumberingIdentifier(sal_Int16 index)
762 throw(RuntimeException)
764 if (aSupportedTypes[index].cSymbol)
765 return OUString(aSupportedTypes[index].cSymbol, strlen(aSupportedTypes[index].cSymbol), RTL_TEXTENCODING_UTF8);
766 // return OUString::createFromAscii(aSupportedTypes[index].cSymbol);
767 else {
768 OUString result;
769 Locale aLocale(OUString::createFromAscii("en"), OUString(), OUString());
770 Sequence<beans::PropertyValue> aProperties(2);
771 aProperties[0].Name = OUString::createFromAscii("NumberingType");
772 aProperties[0].Value <<= aSupportedTypes[index].nType;
773 aProperties[1].Name = OUString::createFromAscii("Value");
774 for (sal_Int32 j = 1; j <= 3; j++) {
775 aProperties[1].Value <<= j;
776 result += makeNumberingString( aProperties, aLocale );
777 result += OUString::createFromAscii(", ");
779 result += OUString::createFromAscii("...");
780 return result;
784 sal_Bool SAL_CALL
785 DefaultNumberingProvider::isScriptFlagEnabled(const OUString& aName) throw(RuntimeException)
787 if (! xHierarchicalNameAccess.is()) {
788 Reference< XInterface > xInterface;
790 xInterface = xSMgr->createInstance(OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider"));
791 Reference< XMultiServiceFactory > xConfigProvider =
792 Reference< XMultiServiceFactory >(xInterface, UNO_QUERY );
794 if (! xConfigProvider.is())
795 throw RuntimeException();
797 Sequence< Any > aArgs(1);
798 beans::PropertyValue aPath;
799 aPath.Name = OUString::createFromAscii("nodepath");
800 aPath.Value <<= OUString::createFromAscii("/org.openoffice.Office.Common/I18N"),
801 aArgs[0] <<= aPath;
803 xInterface = xConfigProvider->createInstanceWithArguments(
804 OUString::createFromAscii("com.sun.star.configuration.ConfigurationAccess"), aArgs);
806 xHierarchicalNameAccess.set(xInterface, UNO_QUERY);
808 if (! xHierarchicalNameAccess.is())
809 throw RuntimeException();
812 Any aEnabled = xHierarchicalNameAccess->getByHierarchicalName(aName);
814 sal_Bool enabled = sal_False;
816 aEnabled >>= enabled;
818 return enabled;
821 Sequence< sal_Int16 > DefaultNumberingProvider::getSupportedNumberingTypes( )
822 throw(RuntimeException)
824 Sequence< sal_Int16 > aRet(nSupported_NumberingTypes );
825 sal_Int16* pArray = aRet.getArray();
827 sal_Bool cjkEnabled = isScriptFlagEnabled(OUString::createFromAscii("CJK/CJKFont"));
828 sal_Bool ctlEnabled = isScriptFlagEnabled(OUString::createFromAscii("CTL/CTLFont"));
830 for(sal_Int16 i = 0; i < nSupported_NumberingTypes; i++) {
831 if ( (aSupportedTypes[i].langOption & LANG_ALL) ||
832 ((aSupportedTypes[i].langOption & LANG_CJK) && cjkEnabled) ||
833 ((aSupportedTypes[i].langOption & LANG_CTL) && ctlEnabled) )
834 pArray[i] = aSupportedTypes[i].nType;
836 return aRet;
838 /* -----------------------------21.02.01 15:57--------------------------------
840 ---------------------------------------------------------------------------*/
841 sal_Int16 DefaultNumberingProvider::getNumberingType( const OUString& rNumberingIdentifier )
842 throw(RuntimeException)
844 for(sal_Int16 i = 0; i < nSupported_NumberingTypes; i++)
845 if(rNumberingIdentifier.equals(makeNumberingIdentifier(i)))
846 return aSupportedTypes[i].nType;
847 throw RuntimeException();
849 /* -----------------------------21.02.01 15:57--------------------------------
851 ---------------------------------------------------------------------------*/
852 sal_Bool DefaultNumberingProvider::hasNumberingType( const OUString& rNumberingIdentifier )
853 throw(RuntimeException)
855 for(sal_Int16 i = 0; i < nSupported_NumberingTypes; i++)
856 if(rNumberingIdentifier.equals(makeNumberingIdentifier(i)))
857 return sal_True;
858 return sal_False;
860 /* -----------------------------21.02.01 15:57--------------------------------
862 ---------------------------------------------------------------------------*/
863 OUString DefaultNumberingProvider::getNumberingIdentifier( sal_Int16 nNumberingType )
864 throw(RuntimeException)
866 for(sal_Int16 i = 0; i < nSupported_NumberingTypes; i++)
867 if(nNumberingType == aSupportedTypes[i].nType)
868 return makeNumberingIdentifier(i);
869 return OUString();
871 /* -----------------------------05.07.01 13:34--------------------------------
873 ---------------------------------------------------------------------------*/
874 const sal_Char cDefaultNumberingProvider[] = "com.sun.star.text.DefaultNumberingProvider";
875 OUString DefaultNumberingProvider::getImplementationName(void)
876 throw( RuntimeException )
878 return OUString::createFromAscii(cDefaultNumberingProvider);
880 /* -----------------------------05.07.01 13:34--------------------------------
882 ---------------------------------------------------------------------------*/
883 sal_Bool DefaultNumberingProvider::supportsService(const rtl::OUString& rServiceName)
884 throw( RuntimeException )
886 return rServiceName.equalsAscii(cDefaultNumberingProvider);
888 /* -----------------------------05.07.01 13:34--------------------------------
890 ---------------------------------------------------------------------------*/
891 Sequence< OUString > DefaultNumberingProvider::getSupportedServiceNames(void)
892 throw( RuntimeException )
894 Sequence< OUString > aRet(1);
895 aRet[0] = OUString::createFromAscii(cDefaultNumberingProvider);
896 return aRet;
899 } } } }