1 /* vim:set et ts=4 sts=4:
3 * ibus-libpinyin - Intelligent Pinyin engine based on libpinyin for IBus
5 * Copyright (c) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
6 * Copyright (c) 2010 BYVoid <byvoid1@gmail.com>
7 * Copyright (c) 2011 Peng Wu <alexepico@gmail.com>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2, or (at your option)
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 #include "PYPBopomofoEngine.h"
25 #include "PYPunctEditor.h"
26 #include "PYPBopomofoEditor.h"
27 #include "PYFallbackEditor.h"
29 #include "PYPConfig.h"
34 LibPinyinBopomofoEngine::LibPinyinBopomofoEngine (IBusEngine *engine)
36 m_props (LibPinyinBopomofoConfig::instance ()),
37 m_prev_pressed_key (IBUS_VoidSymbol),
38 m_input_mode (MODE_INIT),
39 m_fallback_editor (new FallbackEditor (m_props, LibPinyinBopomofoConfig::instance()))
44 m_editors[MODE_INIT].reset (new LibPinyinBopomofoEditor (m_props, LibPinyinBopomofoConfig::instance ()));
45 m_editors[MODE_PUNCT].reset (new PunctEditor (m_props, LibPinyinBopomofoConfig::instance ()));
47 m_props.signalUpdateProperty ().connect
48 (std::bind (&LibPinyinBopomofoEngine::updateProperty, this, _1));
50 for (i = MODE_INIT; i < MODE_LAST; i++) {
51 connectEditorSignals (m_editors[i]);
54 connectEditorSignals (m_fallback_editor);
58 LibPinyinBopomofoEngine::~LibPinyinBopomofoEngine (void)
63 LibPinyinBopomofoEngine::processKeyEvent (guint keyval, guint keycode, guint modifiers)
65 gboolean retval = FALSE;
67 /* check Shift or Ctrl + Release hotkey,
68 * and then ignore other Release key event */
69 if (modifiers & IBUS_RELEASE_MASK) {
70 /* press and release keyval are same,
71 * and no other key event between the press and release key event */
72 gboolean triggered = FALSE;
74 if (m_prev_pressed_key == keyval) {
75 if (LibPinyinBopomofoConfig::instance ().ctrlSwitch ()) {
76 if (keyval == IBUS_Control_L || keyval == IBUS_Control_R)
79 if (keyval == IBUS_Shift_L || keyval == IBUS_Shift_R)
85 if (!m_editors[MODE_INIT]->text ().empty ())
86 m_editors[MODE_INIT]->reset ();
87 m_props.toggleModeChinese ();
91 if (m_input_mode == MODE_INIT &&
92 m_editors[MODE_INIT]->text ().empty ()) {
93 /* If it is init mode, and no any previous input text,
94 * we will let client applications to handle release key event */
101 /* Toggle simp/trad Chinese Mode when hotkey Ctrl + Shift + F pressed */
102 if (keyval == IBUS_F && scmshm_test (modifiers, (IBUS_SHIFT_MASK | IBUS_CONTROL_MASK))) {
103 m_props.toggleModeSimp();
104 m_prev_pressed_key = IBUS_F;
108 if (m_props.modeChinese ()) {
109 if (G_UNLIKELY (m_input_mode == MODE_INIT &&
110 m_editors[MODE_INIT]->text ().empty () &&
111 cmshm_filter (modifiers) == 0 &&
112 keyval == IBUS_grave)){
113 /* if BopomofoEditor is empty and get a grave key,
114 * switch current editor to PunctEditor */
115 m_input_mode = MODE_PUNCT;
118 retval = m_editors[m_input_mode]->processKeyEvent (keyval, keycode, modifiers);
119 if (G_UNLIKELY (retval &&
120 m_input_mode != MODE_INIT &&
121 m_editors[m_input_mode]->text ().empty ()))
122 m_input_mode = MODE_INIT;
125 if (G_UNLIKELY (!retval))
126 retval = m_fallback_editor->processKeyEvent (keyval, keycode, modifiers);
128 /* store ignored key event by editors */
129 m_prev_pressed_key = retval ? IBUS_VoidSymbol : keyval;
135 LibPinyinBopomofoEngine::focusIn (void)
137 registerProperties (m_props.properties ());
141 LibPinyinBopomofoEngine::focusOut (void)
147 LibPinyinBopomofoEngine::reset (void)
149 m_prev_pressed_key = IBUS_VoidSymbol;
150 m_input_mode = MODE_INIT;
151 for (gint i = 0; i < MODE_LAST; i++) {
152 m_editors[i]->reset ();
154 m_fallback_editor->reset ();
158 LibPinyinBopomofoEngine::enable (void)
164 LibPinyinBopomofoEngine::disable (void)
169 LibPinyinBopomofoEngine::pageUp (void)
171 m_editors[m_input_mode]->pageUp ();
175 LibPinyinBopomofoEngine::pageDown (void)
177 m_editors[m_input_mode]->pageDown ();
181 LibPinyinBopomofoEngine::cursorUp (void)
183 m_editors[m_input_mode]->cursorUp ();
187 LibPinyinBopomofoEngine::cursorDown (void)
189 m_editors[m_input_mode]->cursorDown ();
193 LibPinyinBopomofoEngine::showSetupDialog (void)
195 g_spawn_command_line_async
196 (LIBEXECDIR"/ibus-setup-libpinyin bopomofo", NULL);
200 LibPinyinBopomofoEngine::propertyActivate (const gchar *prop_name,
203 const static std::string setup ("setup");
204 if (m_props.propertyActivate (prop_name, prop_state)) {
207 else if (setup == prop_name) {
215 LibPinyinBopomofoEngine::candidateClicked (guint index,
219 m_editors[m_input_mode]->candidateClicked (index, button, state);
223 LibPinyinBopomofoEngine::commitText (Text & text)
225 Engine::commitText (text);
226 if (m_input_mode != MODE_INIT)
227 m_input_mode = MODE_INIT;
229 /* handle "<num>+.<num>+" here */
231 static_cast<FallbackEditor*> (m_fallback_editor.get ())->setPrevCommittedChar (*text.text ());
233 static_cast<FallbackEditor*> (m_fallback_editor.get ())->setPrevCommittedChar (0);
238 LibPinyinBopomofoEngine::connectEditorSignals (EditorPtr editor)
240 editor->signalCommitText ().connect (
241 std::bind (&LibPinyinBopomofoEngine::commitText, this, _1));
243 editor->signalUpdatePreeditText ().connect (
244 std::bind (&LibPinyinBopomofoEngine::updatePreeditText, this, _1, _2, _3));
245 editor->signalShowPreeditText ().connect (
246 std::bind (&LibPinyinBopomofoEngine::showPreeditText, this));
247 editor->signalHidePreeditText ().connect (
248 std::bind (&LibPinyinBopomofoEngine::hidePreeditText, this));
250 editor->signalUpdateAuxiliaryText ().connect (
251 std::bind (&LibPinyinBopomofoEngine::updateAuxiliaryText, this, _1, _2));
252 editor->signalShowAuxiliaryText ().connect (
253 std::bind (&LibPinyinBopomofoEngine::showAuxiliaryText, this));
254 editor->signalHideAuxiliaryText ().connect (
255 std::bind (&LibPinyinBopomofoEngine::hideAuxiliaryText, this));
257 editor->signalUpdateLookupTable ().connect (
258 std::bind (&LibPinyinBopomofoEngine::updateLookupTable, this, _1, _2));
259 editor->signalUpdateLookupTableFast ().connect (
260 std::bind (&LibPinyinBopomofoEngine::updateLookupTableFast, this, _1, _2));
261 editor->signalShowLookupTable ().connect (
262 std::bind (&LibPinyinBopomofoEngine::showLookupTable, this));
263 editor->signalHideLookupTable ().connect (
264 std::bind (&LibPinyinBopomofoEngine::hideLookupTable, this));