LEFT | RIGHT |
1 /* vim:set et sts=4 sw=4: | 1 /* vim:set et sts=4 sw=4: |
2 * | 2 * |
3 * ibus - The Input Bus | 3 * ibus - The Input Bus |
4 * | 4 * |
5 * Copyright (c) 2017 Takao Fujiwara <takao.fujiwara1@gmail.com> | 5 * Copyright (c) 2017 Takao Fujiwara <takao.fujiwara1@gmail.com> |
6 * | 6 * |
7 * This library is free software; you can redistribute it and/or | 7 * This library is free software; you can redistribute it and/or |
8 * modify it under the terms of the GNU Lesser General Public | 8 * modify it under the terms of the GNU Lesser General Public |
9 * License as published by the Free Software Foundation; either | 9 * License as published by the Free Software Foundation; either |
10 * version 2.1 of the License, or (at your option) any later version. | 10 * version 2.1 of the License, or (at your option) any later version. |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
121 public override void get_preferred_height(out int minimum_height, | 121 public override void get_preferred_height(out int minimum_height, |
122 out int natural_height) { | 122 out int natural_height) { |
123 get_preferred_size_with_hb(null, null, | 123 get_preferred_size_with_hb(null, null, |
124 out minimum_height, | 124 out minimum_height, |
125 out natural_height); | 125 out natural_height); |
126 } | 126 } |
127 public override bool draw(Cairo.Context cr) { | 127 public override bool draw(Cairo.Context cr) { |
128 if (m_fontset == null) | 128 if (m_fontset == null) |
129 return true; | 129 return true; |
130 if (m_requisition == null) | 130 if (m_requisition == null) |
131 return true; | 131 return true; |
132 if (m_requisition.cairo_lines == null) | 132 if (m_requisition.cairo_lines == null) |
133 return true; | 133 return true; |
134 var style_context = get_style_context(); | 134 var style_context = get_style_context(); |
135 Gtk.Allocation allocation; | 135 Gtk.Allocation allocation; |
136 get_allocation(out allocation); | 136 get_allocation(out allocation); |
137 style_context.render_background(cr, | 137 style_context.render_background(cr, |
138 0, 0, | 138 0, 0, |
139 allocation.width, | 139 allocation.width, |
140 allocation.height); | 140 allocation.height); |
141 Gdk.RGBA *normal_fg = null; | 141 Gdk.RGBA *normal_fg = null; |
142 style_context.get(Gtk.StateFlags.NORMAL, | 142 style_context.get(Gtk.StateFlags.NORMAL, |
143 "color", | 143 "color", |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
345 m_favorite_annotations = {}; | 345 m_favorite_annotations = {}; |
346 | 346 |
347 Gdk.Display display = Gdk.Display.get_default(); | 347 Gdk.Display display = Gdk.Display.get_default(); |
348 Gdk.Screen screen = (display != null) ? | 348 Gdk.Screen screen = (display != null) ? |
349 display.get_default_screen() : null; | 349 display.get_default_screen() : null; |
350 | 350 |
351 if (screen == null) { | 351 if (screen == null) { |
352 warning("Could not open display."); | 352 warning("Could not open display."); |
353 return; | 353 return; |
354 } | 354 } |
| 355 // Set en locale because de_DE's decimal_point is ',' instead of '.' |
| 356 string? backup_locale = |
| 357 Intl.setlocale(LocaleCategory.NUMERIC, null).dup(); |
| 358 if (Intl.setlocale(LocaleCategory.NUMERIC, "en_US.UTF-8") == null) { |
| 359 if (Intl.setlocale(LocaleCategory.NUMERIC, "C.UTF-8") == null) { |
| 360 if (Intl.setlocale(LocaleCategory.NUMERIC, "C") == null) { |
| 361 warning("You don't install either en_US.UTF-8 or C.UTF-8 " + |
| 362 "or C locale"); |
| 363 } |
| 364 } |
| 365 } |
355 m_rgba = new ThemedRGBA(this); | 366 m_rgba = new ThemedRGBA(this); |
356 uint bg_red = (uint)(m_rgba.normal_bg.red * 255); | 367 uint bg_red = (uint)(m_rgba.normal_bg.red * 255); |
357 uint bg_green = (uint)(m_rgba.normal_bg.green * 255); | 368 uint bg_green = (uint)(m_rgba.normal_bg.green * 255); |
358 uint bg_blue = (uint)(m_rgba.normal_bg.blue * 255); | 369 uint bg_blue = (uint)(m_rgba.normal_bg.blue * 255); |
359 double bg_alpha = m_rgba.normal_bg.alpha; | 370 double bg_alpha = m_rgba.normal_bg.alpha; |
360 string data = | 371 string data = |
361 "#IBusEmojierWhiteLabel { background-color: " + | 372 "#IBusEmojierWhiteLabel { background-color: " + |
362 "rgba(%u, %u, %u, %lf); ".printf( | 373 "rgba(%u, %u, %u, %lf); ".printf( |
363 bg_red, bg_green, bg_blue, bg_alpha) + | 374 bg_red, bg_green, bg_blue, bg_alpha) + |
364 "font-family: %s; font-size: %dpt; ".printf( | 375 "font-family: %s; font-size: %dpt; ".printf( |
(...skipping 25 matching lines...) Expand all Loading... |
390 "background-color: #b09c5f; " + | 401 "background-color: #b09c5f; " + |
391 "border-width: 4px; border-radius: 3px; }"; | 402 "border-width: 4px; border-radius: 3px; }"; |
392 | 403 |
393 Gtk.CssProvider css_provider = new Gtk.CssProvider(); | 404 Gtk.CssProvider css_provider = new Gtk.CssProvider(); |
394 try { | 405 try { |
395 css_provider.load_from_data(data, -1); | 406 css_provider.load_from_data(data, -1); |
396 } catch (GLib.Error e) { | 407 } catch (GLib.Error e) { |
397 warning("Failed css_provider_from_data: %s", e.message); | 408 warning("Failed css_provider_from_data: %s", e.message); |
398 return; | 409 return; |
399 } | 410 } |
| 411 if (backup_locale != null) |
| 412 Intl.setlocale(LocaleCategory.NUMERIC, backup_locale); |
| 413 else |
| 414 Intl.setlocale(LocaleCategory.NUMERIC, ""); |
400 | 415 |
401 Gtk.StyleContext.add_provider_for_screen( | 416 Gtk.StyleContext.add_provider_for_screen( |
402 screen, | 417 screen, |
403 css_provider, | 418 css_provider, |
404 Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); | 419 Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); |
405 | 420 |
406 m_title = new ETitleLabelBox(_("Emoji Choice")); | 421 m_title = new ETitleLabelBox(_("Emoji Choice")); |
407 set_titlebar(m_title); | 422 set_titlebar(m_title); |
408 m_vbox = new Gtk.Box(Gtk.Orientation.VERTICAL, 0); | 423 m_vbox = new Gtk.Box(Gtk.Orientation.VERTICAL, 0); |
409 add(m_vbox); | 424 add(m_vbox); |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
493 m_emoji_max_seq_len = annotation.length; | 508 m_emoji_max_seq_len = annotation.length; |
494 } | 509 } |
495 } | 510 } |
496 | 511 |
497 | 512 |
498 private static void update_annotation_to_emojis_dict(IBus.EmojiData data) { | 513 private static void update_annotation_to_emojis_dict(IBus.EmojiData data) { |
499 string emoji = data.get_emoji(); | 514 string emoji = data.get_emoji(); |
500 unowned GLib.SList<string> annotations = data.get_annotations(); | 515 unowned GLib.SList<string> annotations = data.get_annotations(); |
501 foreach (string annotation in annotations) { | 516 foreach (string annotation in annotations) { |
502 bool has_emoji = false; | 517 bool has_emoji = false; |
503 unowned GLib.SList<string> hits = | 518 GLib.SList<string> hits = |
504 m_annotation_to_emojis_dict.lookup(annotation); | 519 m_annotation_to_emojis_dict.lookup(annotation).copy_deep( |
| 520 GLib.strdup); |
505 foreach (string hit_emoji in hits) { | 521 foreach (string hit_emoji in hits) { |
506 if (hit_emoji == emoji) { | 522 if (hit_emoji == emoji) { |
507 has_emoji = true; | 523 has_emoji = true; |
508 break; | 524 break; |
509 } | 525 } |
510 } | 526 } |
511 if (!has_emoji) { | 527 if (!has_emoji) { |
512 hits.append(emoji); | 528 hits.append(emoji); |
513 m_annotation_to_emojis_dict.replace( | 529 m_annotation_to_emojis_dict.replace( |
514 annotation, | 530 annotation, |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
554 } | 570 } |
555 str = str.next_char(); | 571 str = str.next_char(); |
556 } | 572 } |
557 return buff.str; | 573 return buff.str; |
558 } | 574 } |
559 | 575 |
560 | 576 |
561 private static void | 577 private static void |
562 update_annotations_with_description (IBus.EmojiData data, | 578 update_annotations_with_description (IBus.EmojiData data, |
563 string description) { | 579 string description) { |
564 unowned GLib.SList<string> annotations = data.get_annotations(); | 580 GLib.SList<string> annotations = |
| 581 data.get_annotations().copy_deep(GLib.strdup); |
565 bool update_annotations = false; | 582 bool update_annotations = false; |
566 string former = null; | 583 string former = null; |
567 string later = null; | 584 string later = null; |
568 int index = description.index_of(": "); | 585 int index = description.index_of(": "); |
569 if (index > 0) { | 586 if (index > 0) { |
570 former = description.substring(0, index); | 587 former = description.substring(0, index); |
571 if (annotations.find_custom(former, GLib.strcmp) == null) { | 588 if (annotations.find_custom(former, GLib.strcmp) == null) { |
572 annotations.append(former); | 589 annotations.append(former); |
573 update_annotations = true; | 590 update_annotations = true; |
574 } | 591 } |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
627 | 644 |
628 private static void update_category_to_emojis_dict(IBus.EmojiData data, | 645 private static void update_category_to_emojis_dict(IBus.EmojiData data, |
629 string lang) { | 646 string lang) { |
630 string emoji = data.get_emoji(); | 647 string emoji = data.get_emoji(); |
631 string category = data.get_category(); | 648 string category = data.get_category(); |
632 if (category == "") | 649 if (category == "") |
633 category = EMOJI_CATEGORY_OTHERS; | 650 category = EMOJI_CATEGORY_OTHERS; |
634 if (lang == "en") { | 651 if (lang == "en") { |
635 bool has_variant = false; | 652 bool has_variant = false; |
636 foreach (unichar ch in EMOJI_VARIANT_LIST) { | 653 foreach (unichar ch in EMOJI_VARIANT_LIST) { |
637 if (emoji.chr(-1, ch) != null) { | 654 if (emoji.index_of_char(ch) >= 0) { |
638 has_variant = true; | 655 has_variant = true; |
639 break; | 656 break; |
640 } | 657 } |
641 } | 658 } |
642 // If emoji includes variants (skin colors and items), | 659 // If emoji includes variants (skin colors and items), |
643 // it's escaped in m_emoji_to_emoji_variants_dict and | 660 // it's escaped in m_emoji_to_emoji_variants_dict and |
644 // not shown by default. | 661 // not shown by default. |
645 if (has_variant) { | 662 if (has_variant) { |
646 unichar base_ch = emoji.get_char(); | 663 unichar base_ch = emoji.get_char(); |
647 string base_emoji = base_ch.to_string(); | 664 string base_emoji = base_ch.to_string(); |
648 var buff = new GLib.StringBuilder(); | 665 var buff = new GLib.StringBuilder(); |
649 buff.append_unichar(base_ch); | 666 buff.append_unichar(base_ch); |
650 buff.append_unichar(0xfe0f); | 667 buff.append_unichar(0xfe0f); |
651 if (m_emoji_to_data_dict.lookup(buff.str) != null) | 668 if (m_emoji_to_data_dict.lookup(buff.str) != null) |
652 base_emoji = buff.str; | 669 base_emoji = buff.str; |
653 unowned GLib.SList<string>? variants = | 670 GLib.SList<string>? variants = |
654 m_emoji_to_emoji_variants_dict.lookup(base_emoji); | 671 m_emoji_to_emoji_variants_dict.lookup( |
| 672 base_emoji).copy_deep(GLib.strdup); |
655 if (variants.find_custom(emoji, GLib.strcmp) == null) { | 673 if (variants.find_custom(emoji, GLib.strcmp) == null) { |
656 if (variants == null) | 674 if (variants == null) |
657 variants.append(base_emoji); | 675 variants.append(base_emoji); |
658 variants.append(emoji); | 676 variants.append(emoji); |
659 m_emoji_to_emoji_variants_dict.replace( | 677 m_emoji_to_emoji_variants_dict.replace( |
660 base_emoji, | 678 base_emoji, |
661 variants.copy_deep(GLib.strdup)); | 679 variants.copy_deep(GLib.strdup)); |
662 } | 680 } |
663 return; | 681 return; |
664 } | 682 } |
665 bool has_emoji = false; | 683 bool has_emoji = false; |
666 unowned GLib.SList<string> hits = | 684 GLib.SList<string> hits = |
667 m_category_to_emojis_dict.lookup(category); | 685 m_category_to_emojis_dict.lookup(category).copy_deep( |
| 686 GLib.strdup); |
668 foreach (string hit_emoji in hits) { | 687 foreach (string hit_emoji in hits) { |
669 if (hit_emoji == emoji) { | 688 if (hit_emoji == emoji) { |
670 has_emoji = true; | 689 has_emoji = true; |
671 break; | 690 break; |
672 } | 691 } |
673 } | 692 } |
674 if (!has_emoji) { | 693 if (!has_emoji) { |
675 hits.append(emoji); | 694 hits.append(emoji); |
676 m_category_to_emojis_dict.replace(category, | 695 m_category_to_emojis_dict.replace(category, |
677 hits.copy_deep(GLib.strdup)); | 696 hits.copy_deep(GLib.strdup)); |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
832 buttons_hbox.pack_start(prev_button, false, false, 0); | 851 buttons_hbox.pack_start(prev_button, false, false, 0); |
833 buttons_hbox.pack_start(next_button, false, false, 0); | 852 buttons_hbox.pack_start(next_button, false, false, 0); |
834 m_vbox.pack_start(buttons_hbox, false, false, 0); | 853 m_vbox.pack_start(buttons_hbox, false, false, 0); |
835 buttons_hbox.show_all(); | 854 buttons_hbox.show_all(); |
836 } | 855 } |
837 | 856 |
838 | 857 |
839 private bool check_unicode_point() { | 858 private bool check_unicode_point() { |
840 string annotation = m_entry.get_text(); | 859 string annotation = m_entry.get_text(); |
841 m_unicode_point = null; | 860 m_unicode_point = null; |
842 var buff = new GLib.StringBuilder(); | 861 // Add "0x" because uint64.ascii_strtoull() is not accessible |
| 862 // and need to use uint64.parse() |
| 863 var buff = new GLib.StringBuilder("0x"); |
843 var retval = new GLib.StringBuilder(); | 864 var retval = new GLib.StringBuilder(); |
844 for (int i = 0; i < annotation.char_count(); i++) { | 865 for (int i = 0; i < annotation.char_count(); i++) { |
845 unichar ch = annotation.get_char(i); | 866 unichar ch = annotation.get_char(i); |
846 if (ch == 0) | 867 if (ch == 0) |
847 return false; | 868 return false; |
848 if (ch.isspace()) { | 869 if (ch.isspace()) { |
849 unichar code = (unichar)buff.str.to_ulong(null, 16); | 870 unichar code = (unichar)uint64.parse(buff.str); |
850 buff.erase(); | 871 buff.assign("0x"); |
851 if (!code.validate()) | 872 if (!code.validate()) |
852 return false; | 873 return false; |
853 retval.append(code.to_string()); | 874 retval.append(code.to_string()); |
854 continue; | 875 continue; |
855 } | 876 } |
856 if (!ch.isxdigit()) | 877 if (!ch.isxdigit()) |
857 return false; | 878 return false; |
858 buff.append_unichar(ch); | 879 buff.append_unichar(ch); |
859 } | 880 } |
860 unichar code = (unichar)buff.str.to_ulong(null, 16); | 881 unichar code = (unichar)uint64.parse(buff.str); |
861 if (!code.validate()) | 882 if (!code.validate()) |
862 return false; | 883 return false; |
863 retval.append(code.to_string()); | 884 retval.append(code.to_string()); |
864 m_unicode_point = retval.str; | 885 m_unicode_point = retval.str; |
865 if (m_unicode_point == null) | 886 if (m_unicode_point == null) |
866 return true; | 887 return true; |
867 IBus.Text text = new IBus.Text.from_string(m_unicode_point); | 888 IBus.Text text = new IBus.Text.from_string(m_unicode_point); |
868 m_lookup_table.append_candidate(text); | 889 m_lookup_table.append_candidate(text); |
869 return true; | 890 return true; |
870 } | 891 } |
(...skipping 13 matching lines...) Expand all Loading... |
884 switch(m_partial_match_condition) { | 905 switch(m_partial_match_condition) { |
885 case 0: | 906 case 0: |
886 if (key.has_prefix(annotation)) | 907 if (key.has_prefix(annotation)) |
887 matched = true; | 908 matched = true; |
888 break; | 909 break; |
889 case 1: | 910 case 1: |
890 if (key.has_suffix(annotation)) | 911 if (key.has_suffix(annotation)) |
891 matched = true; | 912 matched = true; |
892 break; | 913 break; |
893 case 2: | 914 case 2: |
894 if (key.str(annotation) != null) | 915 if (key.index_of(annotation) >= 0) |
895 matched = true; | 916 matched = true; |
896 break; | 917 break; |
897 default: | 918 default: |
898 break; | 919 break; |
899 } | 920 } |
900 if (!matched) | 921 if (!matched) |
901 continue; | 922 continue; |
902 sub_emojis = m_annotation_to_emojis_dict.lookup(key); | 923 sub_emojis = m_annotation_to_emojis_dict.lookup(key); |
903 foreach (unowned string emoji in sub_emojis) { | 924 foreach (unowned string emoji in sub_emojis) { |
904 if (total_emojis.find_custom(emoji, GLib.strcmp) == null) { | 925 if (total_emojis.find_custom(emoji, GLib.strcmp) == null) { |
(...skipping 731 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1636 | 1657 |
1637 public void reset() { | 1658 public void reset() { |
1638 m_input_context_path = ""; | 1659 m_input_context_path = ""; |
1639 m_result = null; | 1660 m_result = null; |
1640 } | 1661 } |
1641 | 1662 |
1642 | 1663 |
1643 public void present_centralize(Gdk.Event event) { | 1664 public void present_centralize(Gdk.Event event) { |
1644 Gtk.Allocation allocation; | 1665 Gtk.Allocation allocation; |
1645 get_allocation(out allocation); | 1666 get_allocation(out allocation); |
| 1667 Gdk.Rectangle monitor_area; |
| 1668 #if VALA_0_34 |
| 1669 Gdk.Display display = Gdk.Display.get_default(); |
| 1670 Gdk.Monitor monitor = display.get_monitor_at_window(this.get_window()); |
| 1671 monitor_area = monitor.get_geometry(); |
| 1672 #else |
1646 Gdk.Screen screen = Gdk.Screen.get_default(); | 1673 Gdk.Screen screen = Gdk.Screen.get_default(); |
1647 int monitor_num = screen.get_monitor_at_window(get_window()); | 1674 int monitor_num = screen.get_monitor_at_window(this.get_window()); |
1648 Gdk.Rectangle monitor_area; | |
1649 screen.get_monitor_geometry(monitor_num, out monitor_area); | 1675 screen.get_monitor_geometry(monitor_num, out monitor_area); |
| 1676 #endif |
1650 int x = (monitor_area.x + monitor_area.width - allocation.width)/2; | 1677 int x = (monitor_area.x + monitor_area.width - allocation.width)/2; |
1651 int y = (monitor_area.y + monitor_area.height | 1678 int y = (monitor_area.y + monitor_area.height |
1652 - allocation.height)/2; | 1679 - allocation.height)/2; |
1653 move(x, y); | 1680 move(x, y); |
1654 | 1681 |
1655 uint32 timestamp = event.get_time(); | 1682 uint32 timestamp = event.get_time(); |
1656 present_with_time(timestamp); | 1683 present_with_time(timestamp); |
1657 m_entry.set_activates_default(true); | 1684 m_entry.set_activates_default(true); |
1658 } | 1685 } |
1659 | 1686 |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1739 m_favorites += favorite; | 1766 m_favorites += favorite; |
1740 } | 1767 } |
1741 for(int i = 0; i < unowned_favorite_annotations.length; i++) { | 1768 for(int i = 0; i < unowned_favorite_annotations.length; i++) { |
1742 string? favorite_annotation = unowned_favorite_annotations[i]; | 1769 string? favorite_annotation = unowned_favorite_annotations[i]; |
1743 GLib.return_if_fail(favorite_annotation != null); | 1770 GLib.return_if_fail(favorite_annotation != null); |
1744 m_favorite_annotations += favorite_annotation; | 1771 m_favorite_annotations += favorite_annotation; |
1745 } | 1772 } |
1746 update_favorite_emoji_dict(); | 1773 update_favorite_emoji_dict(); |
1747 } | 1774 } |
1748 } | 1775 } |
LEFT | RIGHT |