fixes compile
[platform/upstream/ibus-libpinyin.git] / src / PYFallbackEditor.cc
1 /* vim:set et ts=4 sts=4:
2  *
3  * ibus-libpinyin - Intelligent Pinyin engine based on libpinyin for IBus
4  *
5  * Copyright (c) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2, or (at your option)
10  * any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20  */
21 #include "PYFallbackEditor.h"
22 #include "PYHalfFullConverter.h"
23 #include "PYPinyinProperties.h"
24
25 namespace PY {
26
27 inline gboolean
28 FallbackEditor::processPunctForSimplifiedChinese (guint keyval, guint keycode, guint modifiers)
29 {
30     switch (keyval) {
31     case '`':
32         commit ("·"); return TRUE;
33     case '~':
34         commit ("~"); return TRUE;
35     case '!':
36         commit ("!"); return TRUE;
37     // case '@':
38     // case '#':
39     case '$':
40         commit ("¥"); return TRUE;
41     // case '%':
42     case '^':
43         commit ("……"); return TRUE;
44     // case '&':
45     // case '*':
46     case '(':
47         commit ("("); return TRUE;
48     case ')':
49         commit (")"); return TRUE;
50     // case '-':
51     case '_':
52         commit ("——"); return TRUE;
53     // case '=':
54     // case '+':
55     case '[':
56         commit ("【"); return TRUE;
57     case ']':
58         commit ("】"); return TRUE;
59     case '{':
60         commit ("『"); return TRUE;
61     case '}':
62         commit ("』"); return TRUE;
63     case '\\':
64         commit ("、"); return TRUE;
65     // case '|':
66     case ';':
67         commit (";"); return TRUE;
68     case ':':
69         commit (":"); return TRUE;
70     case '\'':
71         commit (m_quote ? "‘" : "’");
72         m_quote = !m_quote;
73         return TRUE;
74     case '"':
75         commit (m_double_quote ? "“" : "”");
76         m_double_quote = !m_double_quote;
77         return TRUE;
78     case ',':
79         commit (","); return TRUE;
80     case '.':
81         if (m_prev_committed_char >= '0' && m_prev_committed_char <= '9')
82             commit (keyval);
83         else
84             commit ("。");
85         return TRUE;
86     case '<':
87         commit ("《"); return TRUE;
88     case '>':
89         commit ("》"); return TRUE;
90     // case '/':
91     case '?':
92         commit ("?"); return TRUE;
93     }
94     return FALSE;
95 }
96
97 inline gboolean
98 FallbackEditor::processPunctForTraditionalChinese (guint keyval, guint keycode, guint modifiers)
99 {
100     switch (keyval) {
101     case '~':
102         commit ("~"); return TRUE;
103     case '!':
104         commit ("!"); return TRUE;
105     // case '@':
106     // case '#':
107     case '$':
108         commit ("¥"); return TRUE;
109     // case '%':
110     case '^':
111         commit ("……"); return TRUE;
112     // case '&':
113     // case '*':
114     case '(':
115         commit ("("); return TRUE;
116     case ')':
117         commit (")"); return TRUE;
118     // case '-':
119     case '_':
120         commit ("——"); return TRUE;
121     // case '=':
122     // case '+':
123     case '[':
124         commit ("「"); return TRUE;
125     case ']':
126         commit ("」"); return TRUE;
127     case '{':
128         commit ("『"); return TRUE;
129     case '}':
130         commit ("』"); return TRUE;
131     case '\\':
132         commit ("、"); return TRUE;
133     // case '|':
134     case ';':
135         commit (";"); return TRUE;
136     case ':':
137         commit (":"); return TRUE;
138     case '\'':
139         commit (m_quote ? "‘" : "’");
140         m_quote = !m_quote;
141         return TRUE;
142     case '"':
143         commit (m_double_quote ? "“" : "”");
144         m_double_quote = !m_double_quote;
145         return TRUE;
146     case ',':
147         commit (","); return TRUE;
148     case '.':
149         if (m_prev_committed_char >= '0' && m_prev_committed_char <= '9')
150             commit (keyval);
151         else
152             commit ("。");
153         return TRUE;
154     case '<':
155         commit (","); return TRUE;
156     case '>':
157         commit ("。"); return TRUE;
158     case '?':
159         commit ("?"); return TRUE;
160     }
161     return FALSE;
162 }
163
164 inline gboolean
165 FallbackEditor::processPunct (guint keyval, guint keycode, guint modifiers)
166 {
167     guint cmshm_modifiers = cmshm_filter (modifiers);
168
169     if (G_UNLIKELY (keyval == IBUS_period && cmshm_modifiers == IBUS_CONTROL_MASK)) {
170         m_props.toggleModeFullPunct ();
171         return TRUE;
172     }
173
174     /* check ctrl, alt, hyper, supper masks */
175     if (cmshm_modifiers != 0)
176         return FALSE;
177
178     /* English mode */
179     if (G_UNLIKELY (!m_props.modeChinese ())) {
180         if (G_UNLIKELY (m_props.modeFull ()))
181             commit (HalfFullConverter::toFull (keyval));
182         else
183             commit (keyval);
184         return TRUE;
185     }
186     else {
187         /* Chinese mode */
188         if (m_props.modeFullPunct ()) {
189             if (m_props.modeSimp ()) {
190                 if (processPunctForSimplifiedChinese (keyval, keycode, modifiers))
191                     return TRUE;
192             }
193             else {
194                 if (processPunctForTraditionalChinese (keyval, keycode, modifiers))
195                     return TRUE;
196             }
197         }
198         commit (m_props.modeFull () ? HalfFullConverter::toFull (keyval) : keyval);
199     }
200     return TRUE;
201 }
202
203 gboolean
204 FallbackEditor::processKeyEvent (guint keyval, guint keycode, guint modifiers)
205 {
206     gboolean retval = FALSE;
207
208     modifiers &= (IBUS_SHIFT_MASK |
209                   IBUS_CONTROL_MASK |
210                   IBUS_MOD1_MASK |
211                   IBUS_SUPER_MASK |
212                   IBUS_HYPER_MASK |
213                   IBUS_META_MASK);
214
215     switch (keyval) {
216         /* numbers */
217         case IBUS_KP_0 ... IBUS_KP_9:
218             keyval = keyval - IBUS_KP_0 + IBUS_0;
219         case IBUS_0 ... IBUS_9:
220         /* letters */
221         case IBUS_a ... IBUS_z:
222         case IBUS_A ... IBUS_Z:
223             if (modifiers == 0) {
224                 commit (m_props.modeFull () ? HalfFullConverter::toFull (keyval) : keyval);
225                 retval = TRUE;
226             }
227             break;
228         /* punct */
229         case IBUS_exclam ... IBUS_slash:
230         case IBUS_colon ... IBUS_at:
231         case IBUS_bracketleft ... IBUS_quoteleft:
232         case IBUS_braceleft ... IBUS_asciitilde:
233             retval = processPunct (keyval, keycode, modifiers);
234             break;
235         case IBUS_KP_Equal:
236             retval = processPunct ('=', keycode, modifiers);
237             break;
238         case IBUS_KP_Multiply:
239             retval = processPunct ('*', keycode, modifiers);
240             break;
241         case IBUS_KP_Add:
242             retval = processPunct ('+', keycode, modifiers);
243             break;
244         #if 0
245         case IBUS_KP_Separator:
246             retval = processPunct (IBUS_separator, keycode, modifiers);
247             break;
248         #endif
249         case IBUS_KP_Subtract:
250             retval = processPunct ('-', keycode, modifiers);
251             break;
252         case IBUS_KP_Decimal:
253             retval = processPunct ('.', keycode, modifiers);
254             break;
255         case IBUS_KP_Divide:
256             retval = processPunct ('/', keycode, modifiers);
257             break;
258         /* space */
259         case IBUS_KP_Space:
260             keyval = IBUS_space;
261         case IBUS_space:
262             if (modifiers == 0) {
263                 commit (m_props.modeFull () ? " " : " ");
264                 retval = TRUE;
265             }
266             break;
267         /* others */
268         default:
269             break;
270     }
271     return retval;
272 }
273
274 void
275 FallbackEditor::reset (void) {
276     m_quote = TRUE;
277     m_double_quote = TRUE;
278     m_prev_committed_char = 0;
279 }
280
281 };