Tizen 2.1 base
[framework/uifw/ise-engine-anthy.git] / src / scim_anthy_kana.cpp
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  *  Copyright (C) 2005 Takuro Ashie
4  *
5  *  This program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2, or (at your option)
8  *  any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program; if not, write to the Free Software
17  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18  */
19
20 #include <string.h>
21
22 #include "scim_anthy_kana.h"
23 #include "scim_anthy_factory.h"
24 #include "scim_anthy_imengine.h"
25 #include "scim_anthy_default_tables.h"
26 #include "scim_anthy_utils.h"
27
28 using namespace scim_anthy;
29
30 static bool
31 has_voiced_consonant (String str)
32 {
33     VoicedConsonantRule *table = scim_anthy_voiced_consonant_table;
34
35     for (unsigned int i = 0; table[i].string; i++) {
36         if (!strcmp (str.c_str (), table[i].string) &&
37             table[i].voiced && *table[i].voiced)
38         {
39             return true;
40         }
41     }
42
43     return false;
44 }
45
46 static bool
47 has_half_voiced_consonant (String str)
48 {
49     VoicedConsonantRule *table = scim_anthy_voiced_consonant_table;
50
51     for (unsigned int i = 0; table[i].string; i++) {
52         if (!strcmp (str.c_str (), table[i].string) &&
53             table[i].half_voiced && *table[i].half_voiced)
54         {
55             return true;
56         }
57     }
58
59     return false;
60 }
61
62 String
63 to_voiced_consonant (String str)
64 {
65     VoicedConsonantRule *table = scim_anthy_voiced_consonant_table;
66
67     for (unsigned int i = 0; table[i].string; i++) {
68         if (!strcmp (str.c_str (), table[i].string))
69             return String (table[i].voiced);
70     }
71
72     return str;
73 }
74
75 String
76 to_half_voiced_consonant (String str)
77 {
78     VoicedConsonantRule *table = scim_anthy_voiced_consonant_table;
79
80     for (unsigned int i = 0; table[i].string; i++) {
81         if (!strcmp (str.c_str (), table[i].string))
82             return String (table[i].half_voiced);
83     }
84
85     return str;
86 }
87
88 KanaConvertor::KanaConvertor (AnthyInstance &anthy)
89     : m_anthy (anthy)
90 {
91 }
92
93 KanaConvertor::~KanaConvertor ()
94 {
95 }
96
97 bool
98 KanaConvertor::can_append (const KeyEvent & key,
99                            bool             ignore_space)
100 {
101     // ignore key release.
102     if (key.is_key_release ())
103         return false;
104
105     // ignore short cut keys of apllication.
106     if (key.mask & SCIM_KEY_ControlMask ||
107         key.mask & SCIM_KEY_AltMask)
108     {
109         return false;
110     }
111
112     if (key.code == SCIM_KEY_overline ||
113         (key.code >= SCIM_KEY_kana_fullstop &&
114          key.code <= SCIM_KEY_semivoicedsound))
115     {
116         return true;
117     }
118
119 #if 0
120     if (key.code == SCIM_KEY_KP_Equal ||
121         (key.code >= SCIM_KEY_KP_Multiply &&
122          key.code <= SCIM_KEY_KP_9))
123     {
124         return true;
125     }
126 #endif
127
128     return false;
129 }
130
131 bool
132 KanaConvertor::append (const KeyEvent & key,
133                        WideString & result,
134                        WideString & pending,
135                        String &raw)
136 {
137     KeyCodeToCharRule *table = scim_anthy_keypad_table;
138
139     // handle keypad code
140     if (key.code == SCIM_KEY_KP_Equal ||
141         (key.code >= SCIM_KEY_KP_Multiply &&
142          key.code <= SCIM_KEY_KP_9))
143     {
144         String ten_key_type = m_anthy.get_factory()->m_ten_key_type;
145
146         for (unsigned int i = 0; table[i].code; i++) {
147             if (table[i].code == key.code) {
148                 if (ten_key_type == "Wide")
149                     util_convert_to_wide (result, table[i].kana);
150                 else
151                     result = utf8_mbstowcs (table[i].kana);
152                 raw = table[i].kana;
153
154                 return false;
155             }
156         }
157     }
158
159     table = scim_anthy_kana_table;
160
161     // handle voiced sound
162     if (key.code == SCIM_KEY_voicedsound &&
163         !m_pending.empty () && has_voiced_consonant (m_pending))
164     {
165         result = utf8_mbstowcs (to_voiced_consonant (m_pending));
166         raw    = key.get_ascii_code ();
167         m_pending = String ();
168         return false;
169     }
170
171     // handle semi voiced sound
172     if (key.code == SCIM_KEY_semivoicedsound &&
173         !m_pending.empty () && has_half_voiced_consonant (m_pending))
174     {
175         result = utf8_mbstowcs (to_half_voiced_consonant (m_pending));
176         raw    = key.get_ascii_code ();
177         m_pending = String ();
178         return false;
179     }
180
181     // kana key code
182     for (unsigned int i = 0; table[i].code; i++) {
183         if (table[i].code == key.code) {
184             bool retval = m_pending.empty () ? false : true;
185
186             if (has_voiced_consonant (table[i].kana)) {
187                 result = WideString ();
188                 pending = utf8_mbstowcs (table[i].kana);
189                 m_pending = table[i].kana;
190             } else {
191                 result = utf8_mbstowcs (table[i].kana);
192                 m_pending = String ();
193             }
194             raw = key.get_ascii_code ();
195
196             return retval;
197         }
198     }
199
200     String s;
201     s += key.get_ascii_code ();
202     raw    = s;
203
204     return append (raw, result, pending);
205 }
206
207 bool
208 KanaConvertor::append (const String & str,
209                        WideString   & result,
210                        WideString   & pending)
211 {
212     result = utf8_mbstowcs (str);
213     m_pending = String ();
214
215     return false;
216 }
217
218 void
219 KanaConvertor::clear (void)
220 {
221     m_pending = String ();
222 }
223
224 bool
225 KanaConvertor::is_pending (void)
226 {
227     return !m_pending.empty ();
228 }
229
230 WideString
231 KanaConvertor::get_pending (void)
232 {
233     return WideString (utf8_mbstowcs (m_pending));
234 }
235
236 WideString
237 KanaConvertor::flush_pending (void)
238 {
239     return WideString ();
240 }
241
242 void
243 KanaConvertor::reset_pending (const WideString &result, const String &raw)
244 {
245     m_pending = String ();
246     if (has_voiced_consonant (utf8_wcstombs (result)))
247         m_pending = utf8_wcstombs (result);
248 }
249 /*
250 vi:ts=4:nowrap:ai:expandtab
251 */