1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.dialer.smartdial.map; 18 19 import android.support.v4.util.SimpleArrayMap; 20 import com.android.dialer.dialpadview.DialpadCharMappings; 21 import com.google.common.base.Optional; 22 23 /** A {@link SmartDialMap} for the Latin alphabet, which is for T9 dialpad searching. */ 24 @SuppressWarnings("Guava") 25 final class LatinSmartDialMap extends SmartDialMap { 26 27 private static LatinSmartDialMap instance; 28 getInstance()29 static LatinSmartDialMap getInstance() { 30 if (instance == null) { 31 instance = new LatinSmartDialMap(); 32 } 33 34 return instance; 35 } 36 LatinSmartDialMap()37 private LatinSmartDialMap() {} 38 39 /* 40 * The switch statement in this function was generated using the python code: 41 * from unidecode import unidecode 42 * for i in range(192, 564): 43 * char = unichr(i) 44 * decoded = unidecode(char) 45 * # Unicode characters that decompose into multiple characters i.e. 46 * # into ss are not supported for now 47 * if (len(decoded) == 1 and decoded.isalpha()): 48 * print "case '" + char + "': return Optional.of('" + unidecode(char) + "');" 49 * 50 * This gives us a way to map characters containing accents/diacritics to their 51 * alphabetic equivalents. The unidecode library can be found at: 52 * http://pypi.python.org/pypi/Unidecode/0.04.1 53 * 54 * Also remaps all upper case latin characters to their lower case equivalents. 55 */ 56 @Override normalizeCharacter(char ch)57 Optional<Character> normalizeCharacter(char ch) { 58 if (isValidDialpadAlphabeticChar(ch)) { 59 return Optional.of(ch); 60 } 61 62 switch (ch) { 63 case 'À': 64 return Optional.of('a'); 65 case 'Á': 66 return Optional.of('a'); 67 case 'Â': 68 return Optional.of('a'); 69 case 'Ã': 70 return Optional.of('a'); 71 case 'Ä': 72 return Optional.of('a'); 73 case 'Å': 74 return Optional.of('a'); 75 case 'Ç': 76 return Optional.of('c'); 77 case 'È': 78 return Optional.of('e'); 79 case 'É': 80 return Optional.of('e'); 81 case 'Ê': 82 return Optional.of('e'); 83 case 'Ë': 84 return Optional.of('e'); 85 case 'Ì': 86 return Optional.of('i'); 87 case 'Í': 88 return Optional.of('i'); 89 case 'Î': 90 return Optional.of('i'); 91 case 'Ï': 92 return Optional.of('i'); 93 case 'Ð': 94 return Optional.of('d'); 95 case 'Ñ': 96 return Optional.of('n'); 97 case 'Ò': 98 return Optional.of('o'); 99 case 'Ó': 100 return Optional.of('o'); 101 case 'Ô': 102 return Optional.of('o'); 103 case 'Õ': 104 return Optional.of('o'); 105 case 'Ö': 106 return Optional.of('o'); 107 case '×': 108 return Optional.of('x'); 109 case 'Ø': 110 return Optional.of('o'); 111 case 'Ù': 112 return Optional.of('u'); 113 case 'Ú': 114 return Optional.of('u'); 115 case 'Û': 116 return Optional.of('u'); 117 case 'Ü': 118 return Optional.of('u'); 119 case 'Ý': 120 return Optional.of('u'); 121 case 'à': 122 return Optional.of('a'); 123 case 'á': 124 return Optional.of('a'); 125 case 'â': 126 return Optional.of('a'); 127 case 'ã': 128 return Optional.of('a'); 129 case 'ä': 130 return Optional.of('a'); 131 case 'å': 132 return Optional.of('a'); 133 case 'ç': 134 return Optional.of('c'); 135 case 'è': 136 return Optional.of('e'); 137 case 'é': 138 return Optional.of('e'); 139 case 'ê': 140 return Optional.of('e'); 141 case 'ë': 142 return Optional.of('e'); 143 case 'ì': 144 return Optional.of('i'); 145 case 'í': 146 return Optional.of('i'); 147 case 'î': 148 return Optional.of('i'); 149 case 'ï': 150 return Optional.of('i'); 151 case 'ð': 152 return Optional.of('d'); 153 case 'ñ': 154 return Optional.of('n'); 155 case 'ò': 156 return Optional.of('o'); 157 case 'ó': 158 return Optional.of('o'); 159 case 'ô': 160 return Optional.of('o'); 161 case 'õ': 162 return Optional.of('o'); 163 case 'ö': 164 return Optional.of('o'); 165 case 'ø': 166 return Optional.of('o'); 167 case 'ù': 168 return Optional.of('u'); 169 case 'ú': 170 return Optional.of('u'); 171 case 'û': 172 return Optional.of('u'); 173 case 'ü': 174 return Optional.of('u'); 175 case 'ý': 176 return Optional.of('y'); 177 case 'ÿ': 178 return Optional.of('y'); 179 case 'Ā': 180 return Optional.of('a'); 181 case 'ā': 182 return Optional.of('a'); 183 case 'Ă': 184 return Optional.of('a'); 185 case 'ă': 186 return Optional.of('a'); 187 case 'Ą': 188 return Optional.of('a'); 189 case 'ą': 190 return Optional.of('a'); 191 case 'Ć': 192 return Optional.of('c'); 193 case 'ć': 194 return Optional.of('c'); 195 case 'Ĉ': 196 return Optional.of('c'); 197 case 'ĉ': 198 return Optional.of('c'); 199 case 'Ċ': 200 return Optional.of('c'); 201 case 'ċ': 202 return Optional.of('c'); 203 case 'Č': 204 return Optional.of('c'); 205 case 'č': 206 return Optional.of('c'); 207 case 'Ď': 208 return Optional.of('d'); 209 case 'ď': 210 return Optional.of('d'); 211 case 'Đ': 212 return Optional.of('d'); 213 case 'đ': 214 return Optional.of('d'); 215 case 'Ē': 216 return Optional.of('e'); 217 case 'ē': 218 return Optional.of('e'); 219 case 'Ĕ': 220 return Optional.of('e'); 221 case 'ĕ': 222 return Optional.of('e'); 223 case 'Ė': 224 return Optional.of('e'); 225 case 'ė': 226 return Optional.of('e'); 227 case 'Ę': 228 return Optional.of('e'); 229 case 'ę': 230 return Optional.of('e'); 231 case 'Ě': 232 return Optional.of('e'); 233 case 'ě': 234 return Optional.of('e'); 235 case 'Ĝ': 236 return Optional.of('g'); 237 case 'ĝ': 238 return Optional.of('g'); 239 case 'Ğ': 240 return Optional.of('g'); 241 case 'ğ': 242 return Optional.of('g'); 243 case 'Ġ': 244 return Optional.of('g'); 245 case 'ġ': 246 return Optional.of('g'); 247 case 'Ģ': 248 return Optional.of('g'); 249 case 'ģ': 250 return Optional.of('g'); 251 case 'Ĥ': 252 return Optional.of('h'); 253 case 'ĥ': 254 return Optional.of('h'); 255 case 'Ħ': 256 return Optional.of('h'); 257 case 'ħ': 258 return Optional.of('h'); 259 case 'Ĩ': 260 return Optional.of('i'); 261 case 'ĩ': 262 return Optional.of('i'); 263 case 'Ī': 264 return Optional.of('i'); 265 case 'ī': 266 return Optional.of('i'); 267 case 'Ĭ': 268 return Optional.of('i'); 269 case 'ĭ': 270 return Optional.of('i'); 271 case 'Į': 272 return Optional.of('i'); 273 case 'į': 274 return Optional.of('i'); 275 case 'İ': 276 return Optional.of('i'); 277 case 'ı': 278 return Optional.of('i'); 279 case 'Ĵ': 280 return Optional.of('j'); 281 case 'ĵ': 282 return Optional.of('j'); 283 case 'Ķ': 284 return Optional.of('k'); 285 case 'ķ': 286 return Optional.of('k'); 287 case 'ĸ': 288 return Optional.of('k'); 289 case 'Ĺ': 290 return Optional.of('l'); 291 case 'ĺ': 292 return Optional.of('l'); 293 case 'Ļ': 294 return Optional.of('l'); 295 case 'ļ': 296 return Optional.of('l'); 297 case 'Ľ': 298 return Optional.of('l'); 299 case 'ľ': 300 return Optional.of('l'); 301 case 'Ŀ': 302 return Optional.of('l'); 303 case 'ŀ': 304 return Optional.of('l'); 305 case 'Ł': 306 return Optional.of('l'); 307 case 'ł': 308 return Optional.of('l'); 309 case 'Ń': 310 return Optional.of('n'); 311 case 'ń': 312 return Optional.of('n'); 313 case 'Ņ': 314 return Optional.of('n'); 315 case 'ņ': 316 return Optional.of('n'); 317 case 'Ň': 318 return Optional.of('n'); 319 case 'ň': 320 return Optional.of('n'); 321 case 'Ō': 322 return Optional.of('o'); 323 case 'ō': 324 return Optional.of('o'); 325 case 'Ŏ': 326 return Optional.of('o'); 327 case 'ŏ': 328 return Optional.of('o'); 329 case 'Ő': 330 return Optional.of('o'); 331 case 'ő': 332 return Optional.of('o'); 333 case 'Ŕ': 334 return Optional.of('r'); 335 case 'ŕ': 336 return Optional.of('r'); 337 case 'Ŗ': 338 return Optional.of('r'); 339 case 'ŗ': 340 return Optional.of('r'); 341 case 'Ř': 342 return Optional.of('r'); 343 case 'ř': 344 return Optional.of('r'); 345 case 'Ś': 346 return Optional.of('s'); 347 case 'ś': 348 return Optional.of('s'); 349 case 'Ŝ': 350 return Optional.of('s'); 351 case 'ŝ': 352 return Optional.of('s'); 353 case 'Ş': 354 return Optional.of('s'); 355 case 'ş': 356 return Optional.of('s'); 357 case 'Š': 358 return Optional.of('s'); 359 case 'š': 360 return Optional.of('s'); 361 case 'Ţ': 362 return Optional.of('t'); 363 case 'ţ': 364 return Optional.of('t'); 365 case 'Ť': 366 return Optional.of('t'); 367 case 'ť': 368 return Optional.of('t'); 369 case 'Ŧ': 370 return Optional.of('t'); 371 case 'ŧ': 372 return Optional.of('t'); 373 case 'Ũ': 374 return Optional.of('u'); 375 case 'ũ': 376 return Optional.of('u'); 377 case 'Ū': 378 return Optional.of('u'); 379 case 'ū': 380 return Optional.of('u'); 381 case 'Ŭ': 382 return Optional.of('u'); 383 case 'ŭ': 384 return Optional.of('u'); 385 case 'Ů': 386 return Optional.of('u'); 387 case 'ů': 388 return Optional.of('u'); 389 case 'Ű': 390 return Optional.of('u'); 391 case 'ű': 392 return Optional.of('u'); 393 case 'Ų': 394 return Optional.of('u'); 395 case 'ų': 396 return Optional.of('u'); 397 case 'Ŵ': 398 return Optional.of('w'); 399 case 'ŵ': 400 return Optional.of('w'); 401 case 'Ŷ': 402 return Optional.of('y'); 403 case 'ŷ': 404 return Optional.of('y'); 405 case 'Ÿ': 406 return Optional.of('y'); 407 case 'Ź': 408 return Optional.of('z'); 409 case 'ź': 410 return Optional.of('z'); 411 case 'Ż': 412 return Optional.of('z'); 413 case 'ż': 414 return Optional.of('z'); 415 case 'Ž': 416 return Optional.of('z'); 417 case 'ž': 418 return Optional.of('z'); 419 case 'ſ': 420 return Optional.of('s'); 421 case 'ƀ': 422 return Optional.of('b'); 423 case 'Ɓ': 424 return Optional.of('b'); 425 case 'Ƃ': 426 return Optional.of('b'); 427 case 'ƃ': 428 return Optional.of('b'); 429 case 'Ɔ': 430 return Optional.of('o'); 431 case 'Ƈ': 432 return Optional.of('c'); 433 case 'ƈ': 434 return Optional.of('c'); 435 case 'Ɖ': 436 return Optional.of('d'); 437 case 'Ɗ': 438 return Optional.of('d'); 439 case 'Ƌ': 440 return Optional.of('d'); 441 case 'ƌ': 442 return Optional.of('d'); 443 case 'ƍ': 444 return Optional.of('d'); 445 case 'Ɛ': 446 return Optional.of('e'); 447 case 'Ƒ': 448 return Optional.of('f'); 449 case 'ƒ': 450 return Optional.of('f'); 451 case 'Ɠ': 452 return Optional.of('g'); 453 case 'Ɣ': 454 return Optional.of('g'); 455 case 'Ɩ': 456 return Optional.of('i'); 457 case 'Ɨ': 458 return Optional.of('i'); 459 case 'Ƙ': 460 return Optional.of('k'); 461 case 'ƙ': 462 return Optional.of('k'); 463 case 'ƚ': 464 return Optional.of('l'); 465 case 'ƛ': 466 return Optional.of('l'); 467 case 'Ɯ': 468 return Optional.of('w'); 469 case 'Ɲ': 470 return Optional.of('n'); 471 case 'ƞ': 472 return Optional.of('n'); 473 case 'Ɵ': 474 return Optional.of('o'); 475 case 'Ơ': 476 return Optional.of('o'); 477 case 'ơ': 478 return Optional.of('o'); 479 case 'Ƥ': 480 return Optional.of('p'); 481 case 'ƥ': 482 return Optional.of('p'); 483 case 'ƫ': 484 return Optional.of('t'); 485 case 'Ƭ': 486 return Optional.of('t'); 487 case 'ƭ': 488 return Optional.of('t'); 489 case 'Ʈ': 490 return Optional.of('t'); 491 case 'Ư': 492 return Optional.of('u'); 493 case 'ư': 494 return Optional.of('u'); 495 case 'Ʊ': 496 return Optional.of('y'); 497 case 'Ʋ': 498 return Optional.of('v'); 499 case 'Ƴ': 500 return Optional.of('y'); 501 case 'ƴ': 502 return Optional.of('y'); 503 case 'Ƶ': 504 return Optional.of('z'); 505 case 'ƶ': 506 return Optional.of('z'); 507 case 'ƿ': 508 return Optional.of('w'); 509 case 'Ǎ': 510 return Optional.of('a'); 511 case 'ǎ': 512 return Optional.of('a'); 513 case 'Ǐ': 514 return Optional.of('i'); 515 case 'ǐ': 516 return Optional.of('i'); 517 case 'Ǒ': 518 return Optional.of('o'); 519 case 'ǒ': 520 return Optional.of('o'); 521 case 'Ǔ': 522 return Optional.of('u'); 523 case 'ǔ': 524 return Optional.of('u'); 525 case 'Ǖ': 526 return Optional.of('u'); 527 case 'ǖ': 528 return Optional.of('u'); 529 case 'Ǘ': 530 return Optional.of('u'); 531 case 'ǘ': 532 return Optional.of('u'); 533 case 'Ǚ': 534 return Optional.of('u'); 535 case 'ǚ': 536 return Optional.of('u'); 537 case 'Ǜ': 538 return Optional.of('u'); 539 case 'ǜ': 540 return Optional.of('u'); 541 case 'Ǟ': 542 return Optional.of('a'); 543 case 'ǟ': 544 return Optional.of('a'); 545 case 'Ǡ': 546 return Optional.of('a'); 547 case 'ǡ': 548 return Optional.of('a'); 549 case 'Ǥ': 550 return Optional.of('g'); 551 case 'ǥ': 552 return Optional.of('g'); 553 case 'Ǧ': 554 return Optional.of('g'); 555 case 'ǧ': 556 return Optional.of('g'); 557 case 'Ǩ': 558 return Optional.of('k'); 559 case 'ǩ': 560 return Optional.of('k'); 561 case 'Ǫ': 562 return Optional.of('o'); 563 case 'ǫ': 564 return Optional.of('o'); 565 case 'Ǭ': 566 return Optional.of('o'); 567 case 'ǭ': 568 return Optional.of('o'); 569 case 'ǰ': 570 return Optional.of('j'); 571 case 'Dz': 572 return Optional.of('d'); 573 case 'Ǵ': 574 return Optional.of('g'); 575 case 'ǵ': 576 return Optional.of('g'); 577 case 'Ƿ': 578 return Optional.of('w'); 579 case 'Ǹ': 580 return Optional.of('n'); 581 case 'ǹ': 582 return Optional.of('n'); 583 case 'Ǻ': 584 return Optional.of('a'); 585 case 'ǻ': 586 return Optional.of('a'); 587 case 'Ǿ': 588 return Optional.of('o'); 589 case 'ǿ': 590 return Optional.of('o'); 591 case 'Ȁ': 592 return Optional.of('a'); 593 case 'ȁ': 594 return Optional.of('a'); 595 case 'Ȃ': 596 return Optional.of('a'); 597 case 'ȃ': 598 return Optional.of('a'); 599 case 'Ȅ': 600 return Optional.of('e'); 601 case 'ȅ': 602 return Optional.of('e'); 603 case 'Ȇ': 604 return Optional.of('e'); 605 case 'ȇ': 606 return Optional.of('e'); 607 case 'Ȉ': 608 return Optional.of('i'); 609 case 'ȉ': 610 return Optional.of('i'); 611 case 'Ȋ': 612 return Optional.of('i'); 613 case 'ȋ': 614 return Optional.of('i'); 615 case 'Ȍ': 616 return Optional.of('o'); 617 case 'ȍ': 618 return Optional.of('o'); 619 case 'Ȏ': 620 return Optional.of('o'); 621 case 'ȏ': 622 return Optional.of('o'); 623 case 'Ȑ': 624 return Optional.of('r'); 625 case 'ȑ': 626 return Optional.of('r'); 627 case 'Ȓ': 628 return Optional.of('r'); 629 case 'ȓ': 630 return Optional.of('r'); 631 case 'Ȕ': 632 return Optional.of('u'); 633 case 'ȕ': 634 return Optional.of('u'); 635 case 'Ȗ': 636 return Optional.of('u'); 637 case 'ȗ': 638 return Optional.of('u'); 639 case 'Ș': 640 return Optional.of('s'); 641 case 'ș': 642 return Optional.of('s'); 643 case 'Ț': 644 return Optional.of('t'); 645 case 'ț': 646 return Optional.of('t'); 647 case 'Ȝ': 648 return Optional.of('y'); 649 case 'ȝ': 650 return Optional.of('y'); 651 case 'Ȟ': 652 return Optional.of('h'); 653 case 'ȟ': 654 return Optional.of('h'); 655 case 'Ȥ': 656 return Optional.of('z'); 657 case 'ȥ': 658 return Optional.of('z'); 659 case 'Ȧ': 660 return Optional.of('a'); 661 case 'ȧ': 662 return Optional.of('a'); 663 case 'Ȩ': 664 return Optional.of('e'); 665 case 'ȩ': 666 return Optional.of('e'); 667 case 'Ȫ': 668 return Optional.of('o'); 669 case 'ȫ': 670 return Optional.of('o'); 671 case 'Ȭ': 672 return Optional.of('o'); 673 case 'ȭ': 674 return Optional.of('o'); 675 case 'Ȯ': 676 return Optional.of('o'); 677 case 'ȯ': 678 return Optional.of('o'); 679 case 'Ȱ': 680 return Optional.of('o'); 681 case 'ȱ': 682 return Optional.of('o'); 683 case 'Ȳ': 684 return Optional.of('y'); 685 case 'ȳ': 686 return Optional.of('y'); 687 case 'A': 688 return Optional.of('a'); 689 case 'B': 690 return Optional.of('b'); 691 case 'C': 692 return Optional.of('c'); 693 case 'D': 694 return Optional.of('d'); 695 case 'E': 696 return Optional.of('e'); 697 case 'F': 698 return Optional.of('f'); 699 case 'G': 700 return Optional.of('g'); 701 case 'H': 702 return Optional.of('h'); 703 case 'I': 704 return Optional.of('i'); 705 case 'J': 706 return Optional.of('j'); 707 case 'K': 708 return Optional.of('k'); 709 case 'L': 710 return Optional.of('l'); 711 case 'M': 712 return Optional.of('m'); 713 case 'N': 714 return Optional.of('n'); 715 case 'O': 716 return Optional.of('o'); 717 case 'P': 718 return Optional.of('p'); 719 case 'Q': 720 return Optional.of('q'); 721 case 'R': 722 return Optional.of('r'); 723 case 'S': 724 return Optional.of('s'); 725 case 'T': 726 return Optional.of('t'); 727 case 'U': 728 return Optional.of('u'); 729 case 'V': 730 return Optional.of('v'); 731 case 'W': 732 return Optional.of('w'); 733 case 'X': 734 return Optional.of('x'); 735 case 'Y': 736 return Optional.of('y'); 737 case 'Z': 738 return Optional.of('z'); 739 default: 740 return Optional.absent(); 741 } 742 } 743 744 @Override getCharToKeyMap()745 SimpleArrayMap<Character, Character> getCharToKeyMap() { 746 return DialpadCharMappings.getDefaultCharToKeyMap(); 747 } 748 } 749