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 )
204 {
205 return LocaleData().getOutlineNumberingLevels( rLocale );
206 }
207
208 Sequence< Sequence<beans::PropertyValue> >
getDefaultContinuousNumberingLevels(const Locale & rLocale)209 DefaultNumberingProvider::getDefaultContinuousNumberingLevels( const Locale& rLocale )
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 {
364 // the Sequence of PropertyValues is expected to have at least 4 elements:
365 // elt Name Type purpose
366 // -----------------------------------------------------------------
367 //
368 // 0. "Prefix" OUString
369 // 1. "NumberingType" sal_Int16 type of formatting from style::NumberingType (roman, arabic, etc)
370 // 2. "Suffix" OUString
371 // ... ... ...
372 // n. "Value" sal_Int32 the number to be formatted
373 // example:
374 // given the Sequence { '(', NumberingType::ROMAN_UPPER, ')', ..., 7 }
375 // makeNumberingString() returns the string "(VII)".
376
377 // Q: why is the type of numType sal_Int16 instead of style::NumberingType?
378 // A: an Any can't hold a style::NumberingType for some reason.
379 // add.: style::NumberingType holds constants of type sal_Int16, it's not an enum type
380
381 sal_Int16 natNum = 0;
382 sal_Int16 tableSize = 0;
383 sal_Unicode *table = NULL; // initialize to avoid compiler warning
384 sal_Bool recycleSymbol = sal_False;
385 Locale locale;
386
387 OUString prefix;
388 sal_Int16 numType = -1; // type of formatting from style::NumberingType (roman, arabic, etc)
389 OUString suffix;
390 sal_Int32 number = -12345; // the number that needs to be formatted.
391
392 // int nProperties = aProperties.getLength();
393 // int last = nProperties-1;
394
395 try {
396 getPropertyByName(aProperties, "Prefix", sal_False) >>=prefix;
397 } catch (Exception&) {
398 //prefix _must_ be empty here!
399 }
400 try {
401 getPropertyByName(aProperties, "Suffix", sal_False) >>=suffix;
402 } catch (Exception&) {
403 //suffix _must_ be empty here!
404 }
405 try {
406 getPropertyByName(aProperties, "NumberingType", sal_True) >>=numType;
407 } catch (Exception& ) {
408 numType = -1;
409 }
410 try {
411 getPropertyByName(aProperties, "Value", sal_True) >>=number;
412 } catch (Exception& ) {
413 number = -1;
414 }
415
416 if( number <= 0 )
417 throw IllegalArgumentException();
418
419 // start empty
420 OUString result;
421
422 // append prefix
423 if( !should_ignore(prefix) ) result += prefix;
424
425 // append formatted number
426 using namespace style::NumberingType;
427 switch( numType )
428 {
429 case CHARS_UPPER_LETTER:
430 lcl_formatChars( upperLetter, 26, number-1, result ); // 1=>A, 2=>B, ..., 26=>Z, 27=>AA, 28=>AB, ...
431 break;
432 case CHARS_LOWER_LETTER:
433 lcl_formatChars( lowerLetter, 26, number-1, result );
434 break;
435 case ROMAN_UPPER:
436 result += toRoman( number );
437 break;
438 case ROMAN_LOWER:
439 result += toRoman( number ).toAsciiLowerCase();
440 break;
441 case ARABIC:
442 result += OUString::valueOf( number );
443 break;
444 case NUMBER_NONE:
445 return OUString::createFromAscii(""); // ignore prefix and suffix
446 case CHAR_SPECIAL:
447 // apparently, we're supposed to return an empty string in this case...
448 return OUString::createFromAscii(""); // ignore prefix and suffix
449 case PAGE_DESCRIPTOR:
450 case BITMAP:
451 OSL_ASSERT(0);
452 throw IllegalArgumentException();
453 case CHARS_UPPER_LETTER_N:
454 lcl_formatChars1( upperLetter, 26, number-1, result ); // 1=>A, 2=>B, ..., 26=>Z, 27=>AA, 28=>BB, ...
455 break;
456 case CHARS_LOWER_LETTER_N:
457 lcl_formatChars1( lowerLetter, 26, number-1, result ); // 1=>A, 2=>B, ..., 26=>Z, 27=>AA, 28=>BB, ...
458 break;
459 case TRANSLITERATION:
460 try {
461 const OUString &tmp = OUString::valueOf( number );
462 OUString transliteration;
463 getPropertyByName(aProperties, "Transliteration", sal_True) >>= transliteration;
464 impl_loadTranslit();
465 translit->loadModuleByImplName(transliteration, aLocale);
466 result += translit->transliterateString2String(tmp, 0, tmp.getLength());
467 } catch (Exception& ) {
468 // When translteration property is missing, return default number (bug #101141#)
469 result += OUString::valueOf( number );
470 // OSL_ASSERT(0);
471 // throw IllegalArgumentException();
472 }
473 break;
474 case NATIVE_NUMBERING:
475 natNum = NativeNumberMode::NATNUM1;
476 locale = aLocale;
477 break;
478 case FULLWIDTH_ARABIC:
479 natNum = NativeNumberMode::NATNUM3;
480 locale = aLocale;
481 break;
482 case NUMBER_LOWER_ZH:
483 natNum = NativeNumberMode::NATNUM7;
484 locale.Language = OUString::createFromAscii("zh");
485 break;
486 case NUMBER_UPPER_ZH_TW:
487 locale.Country = OUString::createFromAscii("TW");
488 case NUMBER_UPPER_ZH:
489 natNum = NativeNumberMode::NATNUM8;
490 locale.Language = OUString::createFromAscii("zh");
491 break;
492 case NUMBER_TRADITIONAL_JA:
493 natNum = NativeNumberMode::NATNUM8;
494 locale.Language = OUString::createFromAscii("ja");
495 break;
496 case NUMBER_UPPER_KO:
497 natNum = NativeNumberMode::NATNUM8;
498 locale.Language = OUString::createFromAscii("ko");
499 break;
500 case NUMBER_HANGUL_KO:
501 natNum = NativeNumberMode::NATNUM11;
502 locale.Language = OUString::createFromAscii("ko");
503 break;
504
505 case CIRCLE_NUMBER:
506 table = table_CircledNumber;
507 tableSize = sizeof(table_CircledNumber) / sizeof(sal_Unicode);
508 break;
509 case TIAN_GAN_ZH:
510 table = table_TianGan_zh;
511 tableSize = sizeof(table_TianGan_zh) / sizeof(sal_Unicode);
512 break;
513 case DI_ZI_ZH:
514 table = table_DiZi_zh;
515 tableSize = sizeof(table_DiZi_zh) / sizeof(sal_Unicode);
516 break;
517 case AIU_FULLWIDTH_JA:
518 table = table_AIUFullWidth_ja_JP;
519 tableSize = sizeof(table_AIUFullWidth_ja_JP) / sizeof(sal_Unicode);
520 recycleSymbol = sal_True;
521 break;
522 case AIU_HALFWIDTH_JA:
523 table = table_AIUHalfWidth_ja_JP;
524 tableSize = sizeof(table_AIUHalfWidth_ja_JP) / sizeof(sal_Unicode);
525 recycleSymbol = sal_True;
526 break;
527 case IROHA_FULLWIDTH_JA:
528 table = table_IROHAFullWidth_ja_JP;
529 tableSize = sizeof(table_IROHAFullWidth_ja_JP) / sizeof(sal_Unicode);
530 recycleSymbol = sal_True;
531 break;
532 case IROHA_HALFWIDTH_JA:
533 table = table_IROHAHalfWidth_ja_JP;
534 tableSize = sizeof(table_IROHAHalfWidth_ja_JP) / sizeof(sal_Unicode);
535 recycleSymbol = sal_True;
536 break;
537 case HANGUL_JAMO_KO:
538 table = table_HangulJamo_ko;
539 tableSize = sizeof(table_HangulJamo_ko) / sizeof(sal_Unicode);
540 recycleSymbol = sal_True;
541 break;
542 case HANGUL_SYLLABLE_KO:
543 table = table_HangulSyllable_ko;
544 tableSize = sizeof(table_HangulSyllable_ko) / sizeof(sal_Unicode);
545 recycleSymbol = sal_True;
546 break;
547 case HANGUL_CIRCLED_JAMO_KO:
548 table = table_HangulCircledJamo_ko;
549 tableSize = sizeof(table_HangulCircledJamo_ko) / sizeof(sal_Unicode);
550 recycleSymbol = sal_True;
551 break;
552 case HANGUL_CIRCLED_SYLLABLE_KO:
553 table = table_HangulCircledSyllable_ko;
554 tableSize = sizeof(table_HangulCircledSyllable_ko) / sizeof(sal_Unicode);
555 recycleSymbol = sal_True;
556 break;
557 case CHARS_ARABIC:
558 lcl_formatChars(table_Alphabet_ar, sizeof(table_Alphabet_ar) / sizeof(sal_Unicode), number - 1, result);
559 break;
560 case CHARS_THAI:
561 lcl_formatChars(table_Alphabet_th, sizeof(table_Alphabet_th) / sizeof(sal_Unicode), number - 1, result);
562 break;
563 case CHARS_HEBREW:
564 lcl_formatChars(table_Alphabet_he, sizeof(table_Alphabet_he) / sizeof(sal_Unicode), number - 1, result);
565 break;
566 case CHARS_NEPALI:
567 lcl_formatChars(table_Alphabet_ne, sizeof(table_Alphabet_ne) / sizeof(sal_Unicode), number - 1, result);
568 break;
569 case CHARS_KHMER:
570 lcl_formatChars(table_Alphabet_km, sizeof(table_Alphabet_km) / sizeof(sal_Unicode), number - 1, result);
571 break;
572 case CHARS_LAO:
573 lcl_formatChars(table_Alphabet_lo, sizeof(table_Alphabet_lo) / sizeof(sal_Unicode), number - 1, result);
574 break;
575 case CHARS_MYANMAR:
576 lcl_formatChars(table_Alphabet_my, sizeof(table_Alphabet_my) / sizeof(sal_Unicode), number - 1, result);
577 break;
578 case CHARS_TIBETAN:
579 lcl_formatChars(table_Alphabet_dz, sizeof(table_Alphabet_dz) / sizeof(sal_Unicode), number - 1, result);
580 break;
581 case CHARS_CYRILLIC_UPPER_LETTER_BG:
582 lcl_formatChars2( table_CyrillicUpperLetter_bg,
583 table_CyrillicLowerLetter_bg,
584 sizeof(table_CyrillicLowerLetter_bg) /
585 sizeof(table_CyrillicLowerLetter_bg[0]), number-1,
586 result); // 1=>a, 2=>b, ..., 28=>z, 29=>Aa, 30=>Ab, ...
587 break;
588 case CHARS_CYRILLIC_LOWER_LETTER_BG:
589 lcl_formatChars( table_CyrillicLowerLetter_bg,
590 sizeof(table_CyrillicLowerLetter_bg) /
591 sizeof(table_CyrillicLowerLetter_bg[0]), number-1,
592 result); // 1=>a, 2=>b, ..., 28=>z, 29=>aa, 30=>ab, ...
593 break;
594 case CHARS_CYRILLIC_UPPER_LETTER_N_BG:
595 lcl_formatChars3( table_CyrillicUpperLetter_bg,
596 table_CyrillicLowerLetter_bg,
597 sizeof(table_CyrillicLowerLetter_bg) /
598 sizeof(table_CyrillicLowerLetter_bg[0]), number-1,
599 result); // 1=>a, 2=>b, ..., 28=>z, 29=>Aa, 30=>Bb, ...
600 break;
601 case CHARS_CYRILLIC_LOWER_LETTER_N_BG:
602 lcl_formatChars1( table_CyrillicLowerLetter_bg,
603 sizeof(table_CyrillicLowerLetter_bg) /
604 sizeof(table_CyrillicLowerLetter_bg[0]), number-1,
605 result); // 1=>a, 2=>b, ..., 28=>z, 29=>aa, 30=>bb, ...
606 break;
607 case CHARS_CYRILLIC_UPPER_LETTER_RU:
608 lcl_formatChars2( table_CyrillicUpperLetter_ru,
609 table_CyrillicLowerLetter_ru,
610 sizeof(table_CyrillicLowerLetter_ru) /
611 sizeof(table_CyrillicLowerLetter_ru[0]), number-1,
612 result); // 1=>a, 2=>b, ..., 27=>z, 28=>Aa, 29=>Ab, ...
613 break;
614 case CHARS_CYRILLIC_LOWER_LETTER_RU:
615 lcl_formatChars( table_CyrillicLowerLetter_ru,
616 sizeof(table_CyrillicLowerLetter_ru) /
617 sizeof(table_CyrillicLowerLetter_ru[0]), number-1,
618 result); // 1=>a, 2=>b, ..., 27=>z, 28=>aa, 29=>ab, ...
619 break;
620 case CHARS_CYRILLIC_UPPER_LETTER_N_RU:
621 lcl_formatChars3( table_CyrillicUpperLetter_ru,
622 table_CyrillicLowerLetter_ru,
623 sizeof(table_CyrillicLowerLetter_ru) /
624 sizeof(table_CyrillicLowerLetter_ru[0]), number-1,
625 result); // 1=>a, 2=>b, ..., 27=>z, 28=>Aa, 29=>Bb, ...
626 break;
627 case CHARS_CYRILLIC_LOWER_LETTER_N_RU:
628 lcl_formatChars1( table_CyrillicLowerLetter_ru,
629 sizeof(table_CyrillicLowerLetter_ru) /
630 sizeof(table_CyrillicLowerLetter_ru[0]), number-1,
631 result); // 1=>a, 2=>b, ..., 27=>z, 28=>aa, 29=>bb, ...
632 break;
633 case CHARS_CYRILLIC_UPPER_LETTER_SR:
634 lcl_formatChars2( table_CyrillicUpperLetter_sr,
635 table_CyrillicLowerLetter_sr,
636 sizeof(table_CyrillicLowerLetter_sr) /
637 sizeof(table_CyrillicLowerLetter_sr[0]), number-1,
638 result); // 1=>a, 2=>b, ..., 27=>z, 28=>Aa, 29=>Ab, ...
639 break;
640 case CHARS_CYRILLIC_LOWER_LETTER_SR:
641 lcl_formatChars( table_CyrillicLowerLetter_sr,
642 sizeof(table_CyrillicLowerLetter_sr) /
643 sizeof(table_CyrillicLowerLetter_sr[0]), number-1,
644 result); // 1=>a, 2=>b, ..., 27=>z, 28=>aa, 29=>ab, ...
645 break;
646 case CHARS_CYRILLIC_UPPER_LETTER_N_SR:
647 lcl_formatChars3( table_CyrillicUpperLetter_sr,
648 table_CyrillicLowerLetter_sr,
649 sizeof(table_CyrillicLowerLetter_sr) /
650 sizeof(table_CyrillicLowerLetter_sr[0]), number-1,
651 result); // 1=>a, 2=>b, ..., 27=>z, 28=>Aa, 29=>Bb, ...
652 break;
653 case CHARS_CYRILLIC_LOWER_LETTER_N_SR:
654 lcl_formatChars1( table_CyrillicLowerLetter_sr,
655 sizeof(table_CyrillicLowerLetter_sr) /
656 sizeof(table_CyrillicLowerLetter_sr[0]), number-1,
657 result); // 1=>a, 2=>b, ..., 27=>z, 28=>aa, 29=>bb, ...
658 break;
659 case CHARS_PERSIAN:
660 lcl_formatChars(table_Alphabet_fa, sizeof(table_Alphabet_fa) / sizeof(sal_Unicode), number - 1, result);
661 break;
662
663 default:
664 OSL_ASSERT(0);
665 throw IllegalArgumentException();
666 }
667
668 if (natNum) {
669 NativeNumberSupplier sNatNum;
670 result += sNatNum.getNativeNumberString(OUString::valueOf( number ), locale, natNum);
671 } else if (tableSize) {
672 if ( number > tableSize && !recycleSymbol)
673 result += OUString::valueOf( number);
674 else
675 result += OUString(&table[--number % tableSize], 1);
676 }
677
678 // append suffix
679 if( !should_ignore(suffix) ) result += suffix;
680
681 return result;
682 }
683 /* -----------------------------21.02.01 15:57--------------------------------
684
685 ---------------------------------------------------------------------------*/
686
687 #define LANG_ALL (1 << 0)
688 #define LANG_CJK (1 << 1)
689 #define LANG_CTL (1 << 2)
690
691 struct Supported_NumberingType
692 {
693 sal_Int16 nType;
694 const sal_Char* cSymbol;
695 sal_Int16 langOption;
696 };
697 static const Supported_NumberingType aSupportedTypes[] =
698 {
699 {style::NumberingType::CHARS_UPPER_LETTER, "A", LANG_ALL},
700 {style::NumberingType::CHARS_LOWER_LETTER, "a", LANG_ALL},
701 {style::NumberingType::ROMAN_UPPER, "I", LANG_ALL},
702 {style::NumberingType::ROMAN_LOWER, "i", LANG_ALL},
703 {style::NumberingType::ARABIC, "1", LANG_ALL},
704 {style::NumberingType::NUMBER_NONE, "''", LANG_ALL},
705 {style::NumberingType::CHAR_SPECIAL, "Bullet", LANG_ALL},
706 {style::NumberingType::PAGE_DESCRIPTOR, "Page", LANG_ALL},
707 {style::NumberingType::BITMAP, "Bitmap", LANG_ALL},
708 {style::NumberingType::CHARS_UPPER_LETTER_N, "AAA", LANG_ALL},
709 {style::NumberingType::CHARS_LOWER_LETTER_N, "aaa", LANG_ALL},
710 {style::NumberingType::NATIVE_NUMBERING, "Native Numbering", LANG_CJK|LANG_CTL},
711 {style::NumberingType::FULLWIDTH_ARABIC, NULL, LANG_CJK},
712 {style::NumberingType::CIRCLE_NUMBER, NULL, LANG_CJK},
713 {style::NumberingType::NUMBER_LOWER_ZH, NULL, LANG_CJK},
714 {style::NumberingType::NUMBER_UPPER_ZH, NULL, LANG_CJK},
715 {style::NumberingType::NUMBER_UPPER_ZH_TW, NULL, LANG_CJK},
716 {style::NumberingType::TIAN_GAN_ZH, NULL, LANG_CJK},
717 {style::NumberingType::DI_ZI_ZH, NULL, LANG_CJK},
718 {style::NumberingType::NUMBER_TRADITIONAL_JA, NULL, LANG_CJK},
719 {style::NumberingType::AIU_FULLWIDTH_JA, NULL, LANG_CJK},
720 {style::NumberingType::AIU_HALFWIDTH_JA, NULL, LANG_CJK},
721 {style::NumberingType::IROHA_FULLWIDTH_JA, NULL, LANG_CJK},
722 {style::NumberingType::IROHA_HALFWIDTH_JA, NULL, LANG_CJK},
723 {style::NumberingType::NUMBER_UPPER_KO, NULL, LANG_CJK},
724 {style::NumberingType::NUMBER_HANGUL_KO, NULL, LANG_CJK},
725 {style::NumberingType::HANGUL_JAMO_KO, NULL, LANG_CJK},
726 {style::NumberingType::HANGUL_SYLLABLE_KO, NULL, LANG_CJK},
727 {style::NumberingType::HANGUL_CIRCLED_JAMO_KO, NULL, LANG_CJK},
728 {style::NumberingType::HANGUL_CIRCLED_SYLLABLE_KO, NULL, LANG_CJK},
729 {style::NumberingType::CHARS_ARABIC, NULL, LANG_CTL},
730 {style::NumberingType::CHARS_THAI, NULL, LANG_CTL},
731 {style::NumberingType::CHARS_HEBREW, NULL, LANG_CTL},
732 {style::NumberingType::CHARS_NEPALI, NULL, LANG_CTL},
733 {style::NumberingType::CHARS_KHMER, NULL, LANG_CTL},
734 {style::NumberingType::CHARS_LAO, NULL, LANG_CTL},
735 {style::NumberingType::CHARS_MYANMAR, NULL, LANG_CTL},
736 {style::NumberingType::CHARS_TIBETAN, NULL, LANG_CTL},
737 {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},
738 {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},
739 {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},
740 {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},
741 {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},
742 {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},
743 {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},
744 {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},
745 {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},
746 {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},
747 {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},
748 {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},
749 {style::NumberingType::CHARS_PERSIAN, NULL, LANG_CTL},
750 };
751 static const sal_Int32 nSupported_NumberingTypes = sizeof(aSupportedTypes) / sizeof(Supported_NumberingType);
752 /* -----------------------------21.02.01 15:57--------------------------------
753
754 ---------------------------------------------------------------------------*/
755
makeNumberingIdentifier(sal_Int16 index)756 OUString DefaultNumberingProvider::makeNumberingIdentifier(sal_Int16 index)
757 {
758 if (aSupportedTypes[index].cSymbol)
759 return OUString(aSupportedTypes[index].cSymbol, strlen(aSupportedTypes[index].cSymbol), RTL_TEXTENCODING_UTF8);
760 // return OUString::createFromAscii(aSupportedTypes[index].cSymbol);
761 else {
762 OUString result;
763 Locale aLocale(OUString::createFromAscii("en"), OUString(), OUString());
764 Sequence<beans::PropertyValue> aProperties(2);
765 aProperties[0].Name = OUString::createFromAscii("NumberingType");
766 aProperties[0].Value <<= aSupportedTypes[index].nType;
767 aProperties[1].Name = OUString::createFromAscii("Value");
768 for (sal_Int32 j = 1; j <= 3; j++) {
769 aProperties[1].Value <<= j;
770 result += makeNumberingString( aProperties, aLocale );
771 result += OUString::createFromAscii(", ");
772 }
773 result += OUString::createFromAscii("...");
774 return result;
775 }
776 }
777
778 sal_Bool SAL_CALL
isScriptFlagEnabled(const OUString & aName)779 DefaultNumberingProvider::isScriptFlagEnabled(const OUString& aName)
780 {
781 if (! xHierarchicalNameAccess.is()) {
782 Reference< XInterface > xInterface;
783
784 xInterface = xSMgr->createInstance(OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider"));
785 Reference< XMultiServiceFactory > xConfigProvider =
786 Reference< XMultiServiceFactory >(xInterface, UNO_QUERY );
787
788 if (! xConfigProvider.is())
789 throw RuntimeException();
790
791 Sequence< Any > aArgs(1);
792 beans::PropertyValue aPath;
793 aPath.Name = OUString::createFromAscii("nodepath");
794 aPath.Value <<= OUString::createFromAscii("/org.openoffice.Office.Common/I18N"),
795 aArgs[0] <<= aPath;
796
797 xInterface = xConfigProvider->createInstanceWithArguments(
798 OUString::createFromAscii("com.sun.star.configuration.ConfigurationAccess"), aArgs);
799
800 xHierarchicalNameAccess.set(xInterface, UNO_QUERY);
801
802 if (! xHierarchicalNameAccess.is())
803 throw RuntimeException();
804 }
805
806 Any aEnabled = xHierarchicalNameAccess->getByHierarchicalName(aName);
807
808 sal_Bool enabled = sal_False;
809
810 aEnabled >>= enabled;
811
812 return enabled;
813 }
814
getSupportedNumberingTypes()815 Sequence< sal_Int16 > DefaultNumberingProvider::getSupportedNumberingTypes( )
816 {
817 Sequence< sal_Int16 > aRet(nSupported_NumberingTypes );
818 sal_Int16* pArray = aRet.getArray();
819
820 sal_Bool cjkEnabled = isScriptFlagEnabled(OUString::createFromAscii("CJK/CJKFont"));
821 sal_Bool ctlEnabled = isScriptFlagEnabled(OUString::createFromAscii("CTL/CTLFont"));
822
823 for(sal_Int16 i = 0; i < nSupported_NumberingTypes; i++) {
824 if ( (aSupportedTypes[i].langOption & LANG_ALL) ||
825 ((aSupportedTypes[i].langOption & LANG_CJK) && cjkEnabled) ||
826 ((aSupportedTypes[i].langOption & LANG_CTL) && ctlEnabled) )
827 pArray[i] = aSupportedTypes[i].nType;
828 }
829 return aRet;
830 }
831 /* -----------------------------21.02.01 15:57--------------------------------
832
833 ---------------------------------------------------------------------------*/
getNumberingType(const OUString & rNumberingIdentifier)834 sal_Int16 DefaultNumberingProvider::getNumberingType( const OUString& rNumberingIdentifier )
835 {
836 for(sal_Int16 i = 0; i < nSupported_NumberingTypes; i++)
837 if(rNumberingIdentifier.equals(makeNumberingIdentifier(i)))
838 return aSupportedTypes[i].nType;
839 throw RuntimeException();
840 }
841 /* -----------------------------21.02.01 15:57--------------------------------
842
843 ---------------------------------------------------------------------------*/
hasNumberingType(const OUString & rNumberingIdentifier)844 sal_Bool DefaultNumberingProvider::hasNumberingType( const OUString& rNumberingIdentifier )
845 {
846 for(sal_Int16 i = 0; i < nSupported_NumberingTypes; i++)
847 if(rNumberingIdentifier.equals(makeNumberingIdentifier(i)))
848 return sal_True;
849 return sal_False;
850 }
851 /* -----------------------------21.02.01 15:57--------------------------------
852
853 ---------------------------------------------------------------------------*/
getNumberingIdentifier(sal_Int16 nNumberingType)854 OUString DefaultNumberingProvider::getNumberingIdentifier( sal_Int16 nNumberingType )
855 {
856 for(sal_Int16 i = 0; i < nSupported_NumberingTypes; i++)
857 if(nNumberingType == aSupportedTypes[i].nType)
858 return makeNumberingIdentifier(i);
859 return OUString();
860 }
861 /* -----------------------------05.07.01 13:34--------------------------------
862
863 ---------------------------------------------------------------------------*/
864 const sal_Char cDefaultNumberingProvider[] = "com.sun.star.text.DefaultNumberingProvider";
getImplementationName(void)865 OUString DefaultNumberingProvider::getImplementationName(void)
866 {
867 return OUString::createFromAscii(cDefaultNumberingProvider);
868 }
869 /* -----------------------------05.07.01 13:34--------------------------------
870
871 ---------------------------------------------------------------------------*/
supportsService(const rtl::OUString & rServiceName)872 sal_Bool DefaultNumberingProvider::supportsService(const rtl::OUString& rServiceName)
873 {
874 return rServiceName.equalsAscii(cDefaultNumberingProvider);
875 }
876 /* -----------------------------05.07.01 13:34--------------------------------
877
878 ---------------------------------------------------------------------------*/
getSupportedServiceNames(void)879 Sequence< OUString > DefaultNumberingProvider::getSupportedServiceNames(void)
880 {
881 Sequence< OUString > aRet(1);
882 aRet[0] = OUString::createFromAscii(cDefaultNumberingProvider);
883 return aRet;
884 }
885
886 } } } }
887