1 #define GETTEXT_PACKAGE "gtk20"
2 #include <glib.h>
3 #include <glib/gi18n.h>
4 #include "MakerDialogUtil.h"
5 #include "MakerDialogProperty.h"
6 #include "IBusChewingUtil.h"
7 #include "IBusChewingProperties.h"
8 #include "IBusConfigBackend.h"
9 #ifdef USE_GSETTINGS
10 #include "GSettingsBackend.h"
11 #endif
12 
13 #define PAGE_EDITING  N_("Editing")
14 #define PAGE_SELECTING  N_("Selecting")
15 #define PAGE_KEYBOARD  N_("Keyboard")
16 
17 const gchar *kbType_ids[] = {
18     N_("default"),
19     N_("hsu"),
20     N_("ibm"),
21     N_("gin_yieh"),
22     N_("eten"),
23     N_("eten26"),
24     N_("dvorak"),
25     N_("dvorak_hsu"),
26     N_("dachen_26"),
27     N_("hanyu"),
28     NULL
29 };
30 
31 #define SELKEYS_ARRAY_SIZE 8
32 const gchar *selKeys_array[SELKEYS_ARRAY_SIZE + 1] = {
33     "1234567890",
34     "asdfghjkl;",
35     "asdfzxcv89",
36     "asdfjkl789",
37     "aoeu;qjkix",		/* Dvorak */
38     "aoeuhtnsid",		/* Dvorak */
39     "aoeuidhtns",		/* Dvorak */
40     "1234qweras",
41     NULL
42 };
43 
44 const gchar *propDefaultEnglishLettercase_array[] = {
45     N_("no default"),
46     N_("lowercase"),
47     N_("uppercase"),
48     NULL
49 };
50 
51 const gchar *syncCapsLock_strs[] = {
52     NC_("Sync", "disable"),
53     NC_("Sync", "keyboard"),
54     NC_("Sync", "input method"),
55     NULL
56 };
57 
58 const gchar *outputCharsets[] = {
59     N_("Auto"),
60     N_("Big5"),
61     N_("UTF8"),
62     NULL
63 };
64 
65 MkdgPropertySpec propSpecs[] = {
66     {G_TYPE_STRING, "kb-type", PAGE_KEYBOARD, N_("Keyboard Type"),
67      IBUS_CHEWING_PROPERTIES_SUBSECTION, "default", kbType_ids, NULL, 0, 0,
68      KBType_apply_callback,
69      MKDG_PROPERTY_FLAG_NO_NEW | MKDG_PROPERTY_FLAG_HAS_TRANSLATION,
70      N_("Select Zhuyin keyboard layout"), NULL}
71     ,
72     {G_TYPE_STRING, "sel-keys", PAGE_KEYBOARD, N_("Selection keys"),
73      IBUS_CHEWING_PROPERTIES_SUBSECTION, "1234567890", selKeys_array, NULL,
74      0,
75      0,
76      selKeys_apply_callback,
77      MKDG_PROPERTY_FLAG_NO_NEW,
78      N_
79      ("Keys used to select candidate. For example \"asdfghjkl;\", press 'a' to select the 1st candidate, 's' for 2nd, and so on."),
80      NULL}
81     ,
82     /*== The callback will be handled in IBusChewingEngine.gob ==*/
83     {G_TYPE_BOOLEAN, "show-systray", PAGE_KEYBOARD,
84      N_("Show systray icons"),
85      IBUS_CHEWING_PROPERTIES_SUBSECTION, "1", NULL, NULL, 0, 1,
86      NULL, 0,
87      N_
88      ("On: Show Chinese/English and Full/Half shape status as a systray icon\n"
89       "Off: Do not show the status icon"), NULL}
90     ,
91     {G_TYPE_BOOLEAN, "auto-shift-cur", PAGE_EDITING,
92      N_("Auto move cursor"),
93      IBUS_CHEWING_PROPERTIES_SUBSECTION, "1", NULL, NULL, 0, 1,
94      autoShiftCur_apply_callback, 0,
95      N_("Automatically move cursor to next character"), NULL}
96     ,
97     {G_TYPE_BOOLEAN, "add-phrase-direction", PAGE_EDITING,
98      N_("Add phrases to the front"),
99      IBUS_CHEWING_PROPERTIES_SUBSECTION, "1", NULL, NULL, 0, 1,
100      addPhraseDirection_apply_callback, 0,
101      N_("Add phrases to the front"), NULL}
102     ,
103     {G_TYPE_BOOLEAN, "clean-buffer-focus-out", PAGE_EDITING,
104      N_("Clean pre-edit buffer when focus out"),
105      IBUS_CHEWING_PROPERTIES_SUBSECTION, "0", NULL, NULL, 0, 1,
106      cleanBufferFocusOut_apply_callback, 0,
107      N_
108      ("On: Clean pre-edit buffer when focus out to prevent program crash\n"
109       "Off: Keep what you already type for convenience"), NULL}
110     ,
111     {G_TYPE_BOOLEAN, "easy-symbol-input", PAGE_EDITING,
112      N_("Easy symbol input"),
113      IBUS_CHEWING_PROPERTIES_SUBSECTION, "1", NULL, NULL, 0, 1,
114      easySymbolInput_apply_callback, 0,
115      N_("Press shift to input Chinese punctuation symbols"), NULL}
116     ,
117     {G_TYPE_BOOLEAN, "esc-clean-all-buf", PAGE_EDITING,
118      N_("Esc clean all buffer"),
119      IBUS_CHEWING_PROPERTIES_SUBSECTION, "0", NULL, NULL, 0, 1,
120      escCleanAllBuf_apply_callback, 0,
121      N_("Escape key cleans the text in pre-edit-buffer"), NULL}
122     ,
123     {G_TYPE_INT, "max-chi-symbol-len", PAGE_EDITING,
124      N_("Maximum Chinese characters"),
125      IBUS_CHEWING_PROPERTIES_SUBSECTION, "20", NULL, NULL, 11, 33,
126      maxChiSymbolLen_apply_callback, 0,
127      N_
128      ("Maximum Chinese characters in pre-edit buffer, not including inputing Zhuyin symbols."),
129      NULL}
130     ,
131     /* Sync between CapsLock and IM */
132     {G_TYPE_STRING, "sync-caps-lock", PAGE_EDITING,
133      N_("Sync between CapsLock and IM"),
134      IBUS_CHEWING_PROPERTIES_SUBSECTION, "disable", syncCapsLock_strs,
135      "Sync",
136      0, 1,
137      syncCapsLock_apply_callback,
138      MKDG_PROPERTY_FLAG_NO_NEW | MKDG_PROPERTY_FLAG_HAS_TRANSLATION,
139      N_
140      ("Occasionally, the CapsLock status does not match the IM, this option determines how these status be synchronized. Valid values:\n"
141       "\"disable\": Do nothing\n"
142       "\"keyboard\": IM status follows keyboard status\n"
143       "\"IM\": Keyboard status follows IM status"), NULL}
144     ,
145     {G_TYPE_BOOLEAN, "shift-toggle-chinese", PAGE_EDITING,
146      N_("Shift toggle Chinese Mode"),
147      IBUS_CHEWING_PROPERTIES_SUBSECTION, "1", NULL, NULL, 0, 1,
148      shiftToggleChinese_apply_callback, 0,
149      N_("Shift key to toggle Chinese Mode"), NULL}
150     ,
151     {G_TYPE_BOOLEAN, "capslock-toggle-chinese", PAGE_EDITING,
152      N_("Caps Lock toggles Chinese Mode"),
153      IBUS_CHEWING_PROPERTIES_SUBSECTION, "1", NULL, NULL, 0, 1,
154      capslockToggleChinese_apply_callback, 0,
155      N_("On: Caps Lock toggle Chinese/English\n"
156 	"Off: Caps Lock only affect English letter case"), NULL}
157     ,
158     {
159      G_TYPE_STRING, "default-english-case", PAGE_EDITING,
160      N_("Default English letter case\n"
161 	"  (Only effective when Caps Lock toggles Chinese is ON)"),
162      IBUS_CHEWING_PROPERTIES_SUBSECTION, "lowercase",
163      propDefaultEnglishLettercase_array, NULL, 0, 1,
164      defaultEnglishLetterCase_apply_callback,
165      MKDG_PROPERTY_FLAG_NO_NEW | MKDG_PROPERTY_FLAG_HAS_TRANSLATION,
166      N_("no control: No default letter case. Not recommend if you use multiple keyboards or synergy\n"
167         "lowercase: Default to lowercase, press shift for uppercase.\n"
168 	"uppercase: Default to uppercase, press shift for lowercase."),
169      NULL}
170     ,
171     {
172      G_TYPE_BOOLEAN, "plain-zhuyin", PAGE_SELECTING,
173      N_("Plain Zhuyin mode"),
174      IBUS_CHEWING_PROPERTIES_SUBSECTION, "0", NULL, NULL, 0, 1,
175      plainZhuyin_apply_callback, 0,
176      N_
177      ("In plain Zhuyin mode, automatic candidate selection and related options are disabled or ignored."),
178      NULL}
179     ,
180     {
181      G_TYPE_UINT, "cand-per-page", PAGE_SELECTING,
182      N_("Candidate per page"),
183      IBUS_CHEWING_PROPERTIES_SUBSECTION, "10", NULL, NULL, 8, 10,
184      candPerPage_apply_callback, 0,
185      N_("Number of candidate per page."),
186      NULL}
187     ,
188     {
189      G_TYPE_BOOLEAN, "phrase-choice-from-last", PAGE_SELECTING,
190      N_("Choose phrases from backward"),
191      IBUS_CHEWING_PROPERTIES_SUBSECTION, "1", NULL, NULL, 0, 1,
192      phraseChoiceRearward_apply_callback, 0,
193      N_("Choose phrases from the back, without moving cursor."),
194      NULL}
195     ,
196     {
197      G_TYPE_BOOLEAN, "space-as-selection", PAGE_SELECTING,
198      N_("Space to select"),
199      IBUS_CHEWING_PROPERTIES_SUBSECTION,
200      "0", NULL, NULL, 0, 1,
201      spaceAsSelection_apply_callback, 0,
202      "Press Space to select the candidate.",
203      NULL}
204     ,
205     {
206      G_TYPE_INVALID, "", "", "",
207      IBUS_CHEWING_PROPERTIES_SUBSECTION, "", NULL, NULL, 0, 0,
208      NULL, 0, NULL, NULL}
209     ,
210 };
211 
212 /*============================================
213  * Class methods
214  */
215 
ibus_chewing_properties_new(MkdgBackend * backend,gpointer parent,gpointer auxData)216 IBusChewingProperties *ibus_chewing_properties_new(MkdgBackend * backend,
217 						   gpointer parent,
218 						   gpointer auxData)
219 {
220     IBusChewingProperties *self = g_new0(IBusChewingProperties, 1);
221     self->properties =
222 	mkdg_properties_from_spec_array(propSpecs, backend, parent,
223 					auxData);
224 
225     /* In schema generation, backend is NULL */
226 #ifdef USE_GSETTINGS
227     self->confObjTable = g_hash_table_new(g_str_hash, g_str_equal);
228 #else
229     self->confObjTable = NULL;
230 #endif
231     return self;
232 }
233 
234 #ifdef USE_GSETTINGS
ibus_section_to_schema(const gchar * section)235 static GString *ibus_section_to_schema(const gchar * section)
236 {
237     GString *result = g_string_new("org.freedesktop");
238     gchar **strArr = g_strsplit(section, "/", -1);
239     gint i;
240     for (i = 0; strArr[i] != NULL; i++) {
241 	g_string_append_printf(result, ".%s", strArr[i]);
242     }
243     g_strfreev(strArr);
244     return result;
245 }
246 #endif				/* USE_GSETTINGS */
247 
ibus_chewing_properties_read_general(IBusChewingProperties * self,GValue * value,const gchar * section,const gchar * key,gpointer userData)248 GValue *ibus_chewing_properties_read_general(IBusChewingProperties * self,
249 					     GValue * value,
250 					     const gchar * section,
251 					     const gchar * key,
252 					     gpointer userData)
253 {
254     g_assert(self);
255     g_assert(value);
256 #ifdef USE_GSETTINGS
257     if (STRING_EQUALS(self->properties->backend->id, GSETTINGS_BACKEND_ID)) {
258 	GSettings *confObj;
259 	if (!g_hash_table_contains(self->confObjTable, (gpointer) section)) {
260 	    GString *schemaIdStr = ibus_section_to_schema(section);
261 	    confObj = g_settings_new(schemaIdStr->str);
262 	    g_hash_table_insert(self->confObjTable, (gpointer) section,
263 				(gpointer) confObj);
264 	    g_string_free(schemaIdStr, TRUE);
265 	} else {
266 	    confObj =
267 		(GSettings *) g_hash_table_lookup(self->confObjTable,
268 						  (gconstpointer) section);
269 	}
270 	g_assert(confObj);
271 	return mkdg_g_settings_read_value(confObj, value, key);
272     }
273 #endif				/* USE_GSETTINGS */
274     return mkdg_backend_read(self->properties->backend, value, section,
275 			     key, userData);
276 }
277 
278 gboolean
ibus_chewing_properties_read_boolean_general(IBusChewingProperties * self,const gchar * section,const gchar * key,gpointer userData)279 ibus_chewing_properties_read_boolean_general(IBusChewingProperties
280 					     * self,
281 					     const gchar *
282 					     section,
283 					     const gchar * key,
284 					     gpointer userData)
285 {
286     GValue gValue = { 0 };
287     g_value_init(&gValue, G_TYPE_BOOLEAN);
288     ibus_chewing_properties_read_general(self, &gValue, section, key,
289 					 userData);
290     gboolean result = g_value_get_boolean(&gValue);
291     g_value_unset(&gValue);
292     return result;
293 }
294 
295 gint
ibus_chewing_properties_read_int_general(IBusChewingProperties * self,const gchar * section,const gchar * key,gpointer userData)296 ibus_chewing_properties_read_int_general(IBusChewingProperties * self,
297 					 const gchar * section,
298 					 const gchar * key,
299 					 gpointer userData)
300 {
301     GValue gValue = { 0 };
302     g_value_init(&gValue, G_TYPE_INT);
303     ibus_chewing_properties_read_general(self, &gValue, section, key,
304 					 userData);
305     gint result = g_value_get_int(&gValue);
306     g_value_unset(&gValue);
307     return result;
308 }
309