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