0 | 0 |
/* vim:set et sts=4: */
|
1 | 1 |
|
|
2 |
#include <locale.h>
|
|
3 |
#include <libintl.h>
|
2 | 4 |
#include "engine.h"
|
3 | 5 |
#include "array.h"
|
4 | |
|
|
6 |
#include "config.h"
|
|
7 |
|
|
8 |
#define _(String) gettext(String)
|
5 | 9 |
#define ARRAY_SHORT_CODE_EMPTY_STRING "⎔"
|
6 | 10 |
|
7 | 11 |
typedef struct _IBusArrayEngine IBusArrayEngine;
|
8 | 12 |
typedef struct _IBusArrayEngineClass IBusArrayEngineClass;
|
9 | 13 |
|
10 | |
struct _IBusArrayEngine {
|
|
14 |
struct _IBusArrayEngine
|
|
15 |
{
|
11 | 16 |
IBusEngine parent;
|
12 | 17 |
|
13 | 18 |
/* members */
|
|
19 | 24 |
IBusPropList *prop_list;
|
20 | 25 |
};
|
21 | 26 |
|
22 | |
struct _IBusArrayEngineClass {
|
|
27 |
struct _IBusArrayEngineClass
|
|
28 |
{
|
23 | 29 |
IBusEngineClass parent;
|
24 | 30 |
};
|
25 | 31 |
|
|
67 | 73 |
static void ibus_array_engine_show_special_code(IBusArrayEngine *arrayeng);
|
68 | 74 |
static void ibus_array_engine_show_special_code_for_char(IBusArrayEngine *arrayeng, gchar *ch);
|
69 | 75 |
|
70 | |
static void ibus_config_value_changed (IBusConfig *config, const gchar *section, const gchar *name,
|
71 | |
#if IBUS_CHECK_VERSION(1,3,99)
|
72 | |
GVariant *value,
|
73 | |
#else
|
74 | |
GValue *value,
|
75 | |
#endif /* !IBUS_CHECK_VERSION(1,3,99) */
|
76 | |
gpointer user_data);
|
77 | |
|
78 | |
static gboolean config_get_string (IBusConfig *config, const gchar *section, const gchar *name, gchar **result);
|
|
76 |
static void ibus_config_value_changed_cb (IBusConfig *config, const gchar *section, const gchar *name, GVariant *value, gpointer unused);
|
79 | 77 |
|
80 | 78 |
static IBusEngineClass *parent_class = NULL;
|
81 | 79 |
static IBusConfig *config = NULL;
|
82 | 80 |
static gboolean is_special_notify;
|
83 | 81 |
static gboolean is_special_only;
|
84 | 82 |
static gboolean is_aux_shown = FALSE;
|
85 | |
|
86 | 83 |
static ArrayContext *array_context = NULL;
|
87 | 84 |
|
88 | |
GType
|
89 | |
ibus_array_engine_get_type (void)
|
|
85 |
GType ibus_array_engine_get_type (void)
|
90 | 86 |
{
|
91 | 87 |
static GType type = 0;
|
92 | 88 |
|
|
103 | 99 |
};
|
104 | 100 |
|
105 | 101 |
if (type == 0)
|
106 | |
{
|
107 | 102 |
type = g_type_register_static (IBUS_TYPE_ENGINE, "IBusArrayEngine", &type_info, (GTypeFlags) 0);
|
108 | |
}
|
109 | 103 |
|
110 | 104 |
return type;
|
111 | 105 |
}
|
|
113 | 107 |
void ibus_array_init (IBusBus *bus)
|
114 | 108 |
{
|
115 | 109 |
gboolean res;
|
116 | |
gchar *str;
|
117 | 110 |
|
118 | 111 |
array_context = array_create_context();
|
119 | 112 |
|
120 | 113 |
config = ibus_bus_get_config (bus);
|
|
114 |
if (config)
|
|
115 |
g_object_ref_sink (config);
|
121 | 116 |
|
122 | 117 |
is_special_notify = FALSE;
|
123 | 118 |
is_special_only = FALSE;
|
124 | 119 |
|
125 | |
str = NULL;
|
126 | |
res = config_get_string (config, "engine/Array", "SpecialNotify", &str);
|
127 | |
if (res)
|
128 | |
{
|
129 | |
if (g_strcmp0(str, "1") == 0)
|
130 | |
is_special_notify = TRUE;
|
131 | |
g_free (str);
|
132 | |
}
|
133 | |
|
134 | |
res = config_get_string (config, "engine/Array", "SpecialOnly", &str);
|
135 | |
if (res)
|
136 | |
{
|
137 | |
if (g_strcmp0(str, "1") == 0)
|
138 | |
is_special_only = TRUE;
|
139 | |
g_free (str);
|
140 | |
}
|
|
120 |
/* load config */
|
|
121 |
GVariant* value;
|
|
122 |
|
|
123 |
value = ibus_config_get_value (config, "engine/Array", "SpecialNotify");
|
|
124 |
if (value && g_variant_classify(value) == G_VARIANT_CLASS_BOOLEAN)
|
|
125 |
is_special_notify = g_variant_get_boolean(value);
|
|
126 |
|
|
127 |
value = ibus_config_get_value (config, "engine/Array", "SpecialOnly");
|
|
128 |
if (value && g_variant_classify(value) == G_VARIANT_CLASS_BOOLEAN)
|
|
129 |
is_special_only = g_variant_get_boolean(value);
|
|
130 |
|
|
131 |
/* gettext preparation */
|
|
132 |
setlocale (LC_ALL, "");
|
|
133 |
bindtextdomain (PACKAGE, LOCALEDIR);
|
|
134 |
textdomain (PACKAGE);
|
141 | 135 |
}
|
142 | 136 |
|
143 | 137 |
void ibus_array_exit (void)
|
|
146 | 140 |
|
147 | 141 |
if (g_object_is_floating (config))
|
148 | 142 |
g_object_unref(config);
|
149 | |
config = NULL;
|
150 | 143 |
}
|
151 | 144 |
|
152 | 145 |
static void ibus_array_engine_class_init (IBusArrayEngineClass *klass)
|
|
182 | 175 |
|
183 | 176 |
arrayeng->table = ibus_lookup_table_new (10, 0, FALSE, TRUE);
|
184 | 177 |
g_object_ref_sink (arrayeng->table);
|
185 | |
setup_label = ibus_text_new_from_string("Setup");
|
186 | |
setup_tooltip = ibus_text_new_from_string("Configure Array 30 engine");
|
|
178 |
setup_label = ibus_text_new_from_string (_("Setup"));
|
|
179 |
setup_tooltip = ibus_text_new_from_string (_("Configure Array 30 engine"));
|
187 | 180 |
setup_prop = ibus_property_new("setup", PROP_TYPE_NORMAL, setup_label, "gtk-preferences", setup_tooltip, TRUE, TRUE, 0, NULL);
|
188 | 181 |
g_object_ref_sink (setup_prop);
|
189 | 182 |
|
|
192 | 185 |
|
193 | 186 |
ibus_prop_list_append(arrayeng->prop_list, setup_prop);
|
194 | 187 |
|
195 | |
g_signal_connect (config, "value-changed", G_CALLBACK(ibus_config_value_changed), arrayeng);
|
|
188 |
g_signal_connect (config, "value-changed", G_CALLBACK(ibus_config_value_changed_cb), NULL);
|
196 | 189 |
}
|
197 | 190 |
|
198 | 191 |
static void ibus_array_engine_destroy (IBusArrayEngine *arrayeng)
|
|
201 | 194 |
g_object_unref(arrayeng->prop_list);
|
202 | 195 |
arrayeng->prop_list = NULL;
|
203 | 196 |
}
|
|
197 |
|
204 | 198 |
if (arrayeng->preedit) {
|
205 | 199 |
g_string_free (arrayeng->preedit, TRUE);
|
206 | 200 |
arrayeng->preedit = NULL;
|
|
220 | 214 |
g_string_assign (arrayeng->preedit, "");
|
221 | 215 |
arrayeng->cursor_pos = 0;
|
222 | 216 |
arrayeng->space_press_count = 0;
|
|
217 |
|
223 | 218 |
ibus_array_engine_update_preedit (arrayeng);
|
224 | 219 |
ibus_engine_hide_lookup_table (engine);
|
225 | 220 |
ibus_engine_hide_auxiliary_text (engine);
|
226 | |
|
227 | 221 |
parent_class->reset(engine);
|
228 | 222 |
}
|
229 | 223 |
|
|
240 | 234 |
static void ibus_array_engine_focus_in (IBusEngine *engine)
|
241 | 235 |
{
|
242 | 236 |
IBusArrayEngine *arrayeng = (IBusArrayEngine*)engine;
|
243 | |
|
244 | 237 |
ibus_engine_register_properties (engine, arrayeng->prop_list);
|
245 | |
|
246 | 238 |
parent_class->focus_in (engine);
|
247 | 239 |
}
|
248 | 240 |
|
|
267 | 259 |
GArray *candidates = NULL;
|
268 | 260 |
|
269 | 261 |
if (arrayeng->preedit->len <= 2 && arrayeng->space_press_count == 0)
|
270 | |
{
|
271 | 262 |
candidates = array_get_candidates_from_short(array_context, arrayeng->preedit->str);
|
272 | |
}
|
273 | 263 |
else
|
274 | |
{
|
275 | 264 |
candidates = array_get_candidates_from_main(array_context, arrayeng->preedit->str);
|
276 | |
}
|
277 | 265 |
|
278 | 266 |
if (candidates == NULL)
|
279 | 267 |
{
|
|
288 | 276 |
}
|
289 | 277 |
|
290 | 278 |
for (i = 0; i < candidates->len; i++)
|
291 | |
{
|
292 | 279 |
ibus_lookup_table_append_candidate (arrayeng->table, ibus_text_new_from_string (g_array_index(candidates, gchar*, i)));
|
293 | |
}
|
294 | 280 |
|
295 | 281 |
array_release_candidates(candidates);
|
296 | 282 |
|
|
315 | 301 |
{
|
316 | 302 |
retval = 0;
|
317 | 303 |
if (retval != 0)
|
318 | |
{
|
319 | |
ibus_attr_list_append (text->attrs,
|
320 | |
ibus_attr_foreground_new (0xff0000, 0, array_preedit->len));
|
321 | |
}
|
|
304 |
ibus_attr_list_append (text->attrs, ibus_attr_foreground_new (0xff0000, 0, array_preedit->len));
|
322 | 305 |
}
|
323 | 306 |
|
324 | 307 |
ibus_engine_update_preedit_text ((IBusEngine *)arrayeng, text, array_preedit->len, TRUE);
|
|
308 |
|
325 | 309 |
if (G_IS_OBJECT (text) && g_object_is_floating (text))
|
326 | 310 |
g_object_unref (text);
|
327 | 311 |
|
|
358 | 342 |
}
|
359 | 343 |
|
360 | 344 |
for (i = 0; i < candidates->len; i++)
|
361 | |
{
|
362 | 345 |
ibus_lookup_table_append_candidate (arrayeng->table, ibus_text_new_from_string (g_array_index(candidates, gchar*, i)));
|
363 | |
}
|
364 | 346 |
|
365 | 347 |
array_release_candidates(candidates);
|
366 | 348 |
|
|
388 | 370 |
if (check_special)
|
389 | 371 |
{
|
390 | 372 |
if (is_special_notify)
|
391 | |
{
|
392 | 373 |
ibus_array_engine_show_special_code_for_char (arrayeng, text->text);
|
393 | |
}
|
394 | |
if (is_special_only) {
|
|
374 |
|
|
375 |
if (is_special_only)
|
395 | 376 |
return FALSE;
|
396 | |
}
|
397 | 377 |
}
|
398 | 378 |
}
|
399 | 379 |
ibus_engine_commit_text((IBusEngine*)arrayeng, text);
|
|
401 | 381 |
ibus_array_engine_reset((IBusEngine*)arrayeng);
|
402 | 382 |
|
403 | 383 |
if (is_special_notify && check_special)
|
404 | |
{
|
405 | 384 |
ibus_array_engine_show_special_code_for_char(arrayeng, temptext);
|
406 | |
}
|
407 | 385 |
|
408 | 386 |
g_free(temptext);
|
409 | 387 |
|
|
440 | 418 |
|
441 | 419 |
if (g_strcmp0(arrayeng->preedit->str, "w") == 0)
|
442 | 420 |
{
|
443 | |
ibus_array_engine_update_auxiliary_text(arrayeng, "1.標點 2.括弧 3.符號 4.數學 5.方向 6.單位 7.圖表 8.羅馬 9.希臘 0.注音");
|
|
421 |
ibus_array_engine_update_auxiliary_text(arrayeng, _("1.comma 2.bracket 3.symbol 4.math 5.arrow 6.unit 7.table 8.roman 9.greek 0.bopomo"));
|
444 | 422 |
is_aux_shown = TRUE;
|
445 | 423 |
}
|
446 | 424 |
else if (is_aux_shown)
|
|
460 | 438 |
return FALSE;
|
461 | 439 |
|
462 | 440 |
|
463 | |
switch (keyval) {
|
|
441 |
switch (keyval)
|
|
442 |
{
|
464 | 443 |
case IBUS_space:
|
465 | 444 |
if (arrayeng->preedit->len == 0)
|
466 | 445 |
return FALSE;
|
467 | 446 |
ibus_array_engine_space_press(arrayeng);
|
468 | 447 |
return TRUE;
|
|
448 |
|
469 | 449 |
case IBUS_Return:
|
470 | 450 |
if (arrayeng->preedit->len == 0)
|
471 | 451 |
return FALSE;
|
|
523 | 503 |
|
524 | 504 |
if (is_alpha (keyval) || keyval == IBUS_period || keyval == IBUS_comma || keyval == IBUS_slash || keyval == IBUS_semicolon)
|
525 | 505 |
{
|
526 | |
if (arrayeng->space_press_count == 1) {
|
|
506 |
if (arrayeng->space_press_count == 1)
|
527 | 507 |
if (arrayeng->table->candidates->len > 0)
|
528 | 508 |
{
|
529 | 509 |
gboolean commit_rev;
|
|
534 | 514 |
} else {
|
535 | 515 |
ibus_array_engine_reset((IBusEngine*)arrayeng);
|
536 | 516 |
}
|
537 | |
}
|
538 | 517 |
|
539 | 518 |
if (arrayeng->preedit->len >= 5)
|
540 | |
{
|
541 | 519 |
return TRUE;
|
542 | |
}
|
543 | 520 |
|
544 | 521 |
g_string_insert_c (arrayeng->preedit, arrayeng->cursor_pos, keyval);
|
545 | 522 |
|
|
611 | 588 |
|
612 | 589 |
if (arrayeng->table->candidates->len > 0)
|
613 | 590 |
{
|
614 | |
|
615 | 591 |
ibus_lookup_table_set_cursor_pos (arrayeng->table, 0);
|
616 | |
|
617 | 592 |
commit_rev = ibus_array_engine_commit_current_candidate(arrayeng);
|
618 | 593 |
}
|
619 | 594 |
else
|
620 | |
{
|
621 | 595 |
ibus_array_engine_reset((IBusEngine*)arrayeng);
|
622 | |
}
|
623 | 596 |
}
|
624 | 597 |
}
|
625 | 598 |
|
|
631 | 604 |
{
|
632 | 605 |
text = ibus_text_new_from_string(aux_string);
|
633 | 606 |
ibus_engine_update_auxiliary_text((IBusEngine*)arrayeng, text, TRUE);
|
634 | |
|
635 | |
if (g_object_is_floating (text))
|
636 | |
g_object_unref (text);
|
637 | 607 |
}
|
638 | 608 |
}
|
639 | 609 |
|
|
660 | 630 |
g_string_free(keystr, TRUE);
|
661 | 631 |
g_free(show_str);
|
662 | 632 |
}
|
663 | |
else {
|
|
633 |
else
|
664 | 634 |
ibus_engine_hide_auxiliary_text((IBusEngine*)arrayeng);
|
665 | |
}
|
666 | 635 |
|
667 | 636 |
array_release_candidates(candidates);
|
668 | 637 |
}
|
|
687 | 656 |
g_free(show_str);
|
688 | 657 |
}
|
689 | 658 |
else
|
690 | |
{
|
691 | 659 |
ibus_engine_hide_auxiliary_text((IBusEngine*)arrayeng);
|
692 | |
}
|
693 | 660 |
|
694 | 661 |
array_release_candidates(candidates);
|
695 | 662 |
}
|
|
716 | 683 |
}
|
717 | 684 |
}
|
718 | 685 |
|
719 | |
static gboolean config_get_string (IBusConfig *config, const gchar *section, const gchar *name, gchar **result)
|
720 | |
{
|
721 | |
#if IBUS_CHECK_VERSION(1,3,99)
|
722 | |
GVariant *value = NULL;
|
723 | |
|
724 | |
g_return_val_if_fail (result != NULL, FALSE);
|
725 | |
|
726 | |
value = ibus_config_get_value (config, section, name);
|
727 | |
if (value)
|
728 | |
{
|
729 | |
*result = g_strdup (g_variant_get_string (value, NULL));
|
730 | |
g_variant_unref (value);
|
731 | |
return TRUE;
|
732 | |
}
|
733 | |
return FALSE;
|
734 | |
#else
|
735 | |
GValue value = { 0 };
|
736 | |
|
737 | |
g_return_val_if_fail (result != NULL, FALSE);
|
738 | |
|
739 | |
if (ibus_config_get_value (config, section, name, &value)) {
|
740 | |
*result = g_strdup (g_value_get_string (&value));
|
741 | |
g_value_unset (&value);
|
742 | |
return TRUE;
|
743 | |
}
|
744 | |
return FALSE;
|
745 | |
#endif /* !IBUS_CHECK_VERSION(1,3,99) */
|
746 | |
}
|
747 | |
|
748 | |
#if IBUS_CHECK_VERSION(1,3,99)
|
749 | |
#define _g_variant_get_string g_variant_get_string
|
750 | |
#else
|
751 | |
#define _g_variant_get_string(value, length) g_value_get_string(value)
|
752 | |
#endif /* !IBUS_CHECK_VERSION(1,3,99) */
|
753 | |
|
754 | |
static void ibus_config_value_changed (IBusConfig *config, const gchar *section, const gchar *name,
|
755 | |
#if IBUS_CHECK_VERSION(1,3,99)
|
756 | |
GVariant *value,
|
757 | |
#else
|
758 | |
GValue *value,
|
759 | |
#endif /* !IBUS_CHECK_VERSION(1,3,99) */
|
760 | |
gpointer user_data)
|
761 | |
{
|
762 | |
IBusArrayEngine *arrayeng = (IBusArrayEngine*)user_data;
|
763 | |
|
764 | |
if (g_strcmp0(section, "engine/Array") == 0)
|
765 | |
{
|
766 | |
if (g_strcmp0(name, "SpecialNotify") == 0) {
|
767 | |
const gchar* str = _g_variant_get_string(value, NULL);
|
768 | |
if (g_strcmp0(str, "1") == 0) {
|
769 | |
is_special_notify = TRUE;
|
770 | |
}
|
771 | |
else {
|
772 | |
is_special_notify = FALSE;
|
773 | |
}
|
774 | |
}
|
775 | |
else if (g_strcmp0(name, "SpecialOnly") == 0) {
|
776 | |
const gchar* str = _g_variant_get_string(value, NULL);
|
777 | |
if (g_strcmp0(str, "1") == 0) {
|
778 | |
is_special_only = TRUE;
|
779 | |
}
|
780 | |
else {
|
781 | |
is_special_only = FALSE;
|
782 | |
}
|
783 | |
}
|
784 | |
}
|
785 | |
}
|
|
686 |
static void ibus_config_value_changed_cb (IBusConfig *config, const gchar *section, const gchar *name, GVariant *value, gpointer unused)
|
|
687 |
{
|
|
688 |
if (g_strcmp0(section, "engine/array") == 0)
|
|
689 |
if (g_strcmp0(name, "specialnotify") == 0)
|
|
690 |
is_special_notify = g_variant_get_boolean (value);
|
|
691 |
else if (g_strcmp0(name, "specialonly") == 0)
|
|
692 |
is_special_only = g_variant_get_boolean (value);
|
|
693 |
}
|
|
694 |
|