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 ) throw(RuntimeException) 204 { 205 return LocaleData().getOutlineNumberingLevels( rLocale ); 206 } 207 208 Sequence< Sequence<beans::PropertyValue> > 209 DefaultNumberingProvider::getDefaultContinuousNumberingLevels( const Locale& rLocale ) throw(RuntimeException) 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 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 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 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 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 ---------------------------------------------------------------------------*/ 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 ---------------------------------------------------------------------------*/ 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 ---------------------------------------------------------------------------*/ 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"; 871 OUString DefaultNumberingProvider::getImplementationName(void) 872 throw( RuntimeException ) 873 { 874 return OUString::createFromAscii(cDefaultNumberingProvider); 875 } 876 /* -----------------------------05.07.01 13:34-------------------------------- 877 878 ---------------------------------------------------------------------------*/ 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 ---------------------------------------------------------------------------*/ 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