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