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 186 DefaultNumberingProvider::DefaultNumberingProvider( const Reference < XMultiServiceFactory >& xMSF ) : xSMgr(xMSF),translit(NULL) 187 { 188 189 } 190 191 DefaultNumberingProvider::~DefaultNumberingProvider() 192 { 193 delete translit; 194 } 195 196 void DefaultNumberingProvider::impl_loadTranslit() 197 { 198 if ( !translit ) 199 translit = new TransliterationImpl(xSMgr); 200 } 201 202 Sequence< Reference<container::XIndexAccess> > 203 DefaultNumberingProvider::getDefaultOutlineNumberings(const Locale& rLocale ) 204 { 205 return LocaleData().getOutlineNumberingLevels( rLocale ); 206 } 207 208 Sequence< Sequence<beans::PropertyValue> > 209 DefaultNumberingProvider::getDefaultContinuousNumberingLevels( const Locale& rLocale ) 210 { 211 return LocaleData().getContinuousNumberingLevels( rLocale ); 212 } 213 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 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 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 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 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 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 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 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 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 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 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 ---------------------------------------------------------------------------*/ 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 ---------------------------------------------------------------------------*/ 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 ---------------------------------------------------------------------------*/ 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"; 865 OUString DefaultNumberingProvider::getImplementationName(void) 866 { 867 return OUString::createFromAscii(cDefaultNumberingProvider); 868 } 869 /* -----------------------------05.07.01 13:34-------------------------------- 870 871 ---------------------------------------------------------------------------*/ 872 sal_Bool DefaultNumberingProvider::supportsService(const rtl::OUString& rServiceName) 873 { 874 return rServiceName.equalsAscii(cDefaultNumberingProvider); 875 } 876 /* -----------------------------05.07.01 13:34-------------------------------- 877 878 ---------------------------------------------------------------------------*/ 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