diff options
author | Peng Huang <shawn.p.huang@gmail.com> | 2010-05-23 12:48:45 +0800 |
---|---|---|
committer | Peng Huang <shawn.p.huang@gmail.com> | 2010-05-23 12:48:45 +0800 |
commit | b4e80d22b99d42afdc5067738129910877160704 (patch) | |
tree | 4699d76e7050f89a60553437e166e727ef6576dd | |
parent | 163587a5185b137df364194d862a671019e3528c (diff) | |
parent | f9a90e87c0de01909659b5c134bd8d0fc5fd14b1 (diff) | |
download | ibus-libpinyin-b4e80d22b99d42afdc5067738129910877160704.tar.gz ibus-libpinyin-b4e80d22b99d42afdc5067738129910877160704.tar.xz ibus-libpinyin-b4e80d22b99d42afdc5067738129910877160704.zip |
Merge remote branch 'byvoid/PhoneticEditor' into config
Conflicts:
src/BopomofoEditor.cc
src/Editor.h
src/PinyinEditor.cc
-rw-r--r-- | src/BopomofoEditor.cc | 54 | ||||
-rw-r--r-- | src/BopomofoEditor.h | 35 | ||||
-rw-r--r-- | src/BopomofoEngine.cc | 12 | ||||
-rw-r--r-- | src/DoublePinyinEditor.cc | 10 | ||||
-rw-r--r-- | src/Editor.h | 1 | ||||
-rw-r--r-- | src/FallbackEditor.cc | 10 | ||||
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/PhoneticEditor.cc | 438 | ||||
-rw-r--r-- | src/PhoneticEditor.h | 112 | ||||
-rw-r--r-- | src/PinyinEditor.cc | 468 | ||||
-rw-r--r-- | src/PinyinEditor.h | 84 | ||||
-rw-r--r-- | src/PinyinEngine.cc | 11 | ||||
-rw-r--r-- | src/PunctEditor.cc | 10 | ||||
-rw-r--r-- | src/Util.h | 10 |
14 files changed, 647 insertions, 610 deletions
diff --git a/src/BopomofoEditor.cc b/src/BopomofoEditor.cc index 6e18133..167dfdb 100644 --- a/src/BopomofoEditor.cc +++ b/src/BopomofoEditor.cc @@ -22,23 +22,13 @@ #include "BopomofoEditor.h" #include "SimpTradConverter.h" -#define CMSHM_MASK \ - (IBUS_CONTROL_MASK | \ - IBUS_MOD1_MASK | \ - IBUS_SUPER_MASK | \ - IBUS_HYPER_MASK | \ - IBUS_META_MASK) - -#define CMSHM_FILTER(modifiers) \ - (modifiers & (CMSHM_MASK)) - namespace PY { #include "Bopomofo.h" #include "BopomofoKeyboard.h" BopomofoEditor::BopomofoEditor (PinyinProperties & props, Config & config) - : PinyinEditor (props, config), + : PhoneticEditor (props, config), m_select_mode (FALSE) { } @@ -51,7 +41,7 @@ void BopomofoEditor::reset (void) { m_select_mode = FALSE; - PinyinEditor::reset (); + PhoneticEditor::reset (); } gboolean @@ -235,22 +225,6 @@ BopomofoEditor::moveCursorToEnd (void) return TRUE; } -inline gboolean -BopomofoEditor::processSpace (guint keyval, guint keycode, guint modifiers) -{ - if (!m_text) - return FALSE; - if (CMSHM_FILTER (modifiers) != 0) - return TRUE; - if (m_lookup_table.size () != 0) { - selectCandidate (m_lookup_table.cursorPos ()); - } - else { - commit (); - } - return TRUE; -} - gboolean BopomofoEditor::processNumber (guint keyval, guint keycode, guint modifiers) { @@ -336,7 +310,7 @@ BopomofoEditor::processNumberWithShift (guint keyval, guint keycode, guint modif inline gboolean BopomofoEditor::processBopomofo (guint keyval, guint keycode, guint modifiers) { - if (G_UNLIKELY (CMSHM_FILTER(modifiers) != 0)) + if (G_UNLIKELY (CMSHM_FILTER (modifiers) != 0)) return m_text ? TRUE : FALSE; if (keyvalToBopomofo (keyval) == BOPOMOFO_ZERO) @@ -384,7 +358,7 @@ BopomofoEditor::processKeyEvent (guint keyval, guint keycode, guint modifiers) case IBUS_KP_Page_Down: case IBUS_Tab: m_select_mode = TRUE; - return PinyinEditor::processKeyEvent (keyval, keycode, modifiers); + return PhoneticEditor::processFunctionKey (keyval, keycode, modifiers); case IBUS_BackSpace: case IBUS_Delete: @@ -398,10 +372,10 @@ BopomofoEditor::processKeyEvent (guint keyval, guint keycode, guint modifiers) case IBUS_End: case IBUS_KP_End: m_select_mode = FALSE; - return PinyinEditor::processKeyEvent (keyval, keycode, modifiers); + return PhoneticEditor::processFunctionKey (keyval, keycode, modifiers); default: - return PinyinEditor::processKeyEvent (keyval, keycode, modifiers); + return PhoneticEditor::processFunctionKey (keyval, keycode, modifiers); } } @@ -441,8 +415,6 @@ BopomofoEditor::updateAuxiliaryText (void) m_buffer.clear (); - updateAuxiliaryTextBefore (m_buffer); - guint si = 0; guint m_text_len = m_text.length(); for (guint i = m_phrase_editor.cursor (); i < m_pinyin.size (); ++i) { @@ -467,8 +439,6 @@ BopomofoEditor::updateAuxiliaryText (void) if (m_cursor == m_text.length ()) m_buffer << '|'; - updateAuxiliaryTextAfter (m_buffer); - StaticText aux_text (m_buffer); Editor::updateAuxiliaryText (aux_text, TRUE); } @@ -476,7 +446,7 @@ BopomofoEditor::updateAuxiliaryText (void) void BopomofoEditor::commit (void) { - if (G_UNLIKELY (empty ())) + if (G_UNLIKELY (m_buffer.empty ())) return; m_buffer.clear (); @@ -499,7 +469,7 @@ BopomofoEditor::commit (void) m_phrase_editor.commit (); reset (); - PinyinEditor::commit ((const gchar *)m_buffer); + PhoneticEditor::commit ((const gchar *)m_buffer); } void @@ -584,6 +554,14 @@ BopomofoEditor::updatePreeditText (void) Editor::updatePreeditText (preedit_text, edit_begin, TRUE); } +void +BopomofoEditor::updateLookupTable () +{ + m_lookup_table.setPageSize (m_config.pageSize ()); + m_lookup_table.setOrientation (m_config.orientation ()); + PhoneticEditor::updateLookupTable (); +} + static int keyboard_cmp (const void *p1, const void *p2) { diff --git a/src/BopomofoEditor.h b/src/BopomofoEditor.h index 184858e..5191bf5 100644 --- a/src/BopomofoEditor.h +++ b/src/BopomofoEditor.h @@ -22,31 +22,37 @@ #ifndef __PY_BOPOMOFO_EDITOR_H_ #define __PY_BOPOMOFO_EDITOR_H_ -#include "PinyinEditor.h" +#include "PhoneticEditor.h" namespace PY { -class BopomofoEditor : public PinyinEditor { +#define MAX_PINYIN_LEN 64 + +class BopomofoEditor : public PhoneticEditor { public: BopomofoEditor (PinyinProperties & props, Config & config = BopomofoConfig::instance ()); ~BopomofoEditor (void); -public: - /* virtual functions */ - virtual gboolean processKeyEvent (guint keyval, guint keycode, guint modifiers); - virtual void reset (void); - protected: std::wstring bopomofo; gboolean m_select_mode; - virtual void updatePinyin (void); - virtual void updateAuxiliaryText (void); - virtual void updatePreeditText (void); - virtual void commit (void); + gboolean processNumber (guint keyval, guint keycode, guint modifiers); + gboolean processNumberWithShift (guint keyval, guint keycode, guint modifiers); + gboolean processBopomofo (guint keyval, guint keycode, guint modifiers); + gboolean processKeyEvent (guint keyval, guint keycode, guint modifiers); + + void updateAuxiliaryText (); + void updateLookupTable (); + void updatePinyin (); + void updatePreeditText (); + + void commit (); + void reset (); gboolean insert (gint ch); + gint keyvalToBopomofo(gint ch); gboolean removeCharBefore (void); gboolean removeCharAfter (void); @@ -60,13 +66,6 @@ protected: gboolean moveCursorToBegin (void); gboolean moveCursorToEnd (void); - gboolean processSpace (guint keyval, guint keycode, guint modifiers); - gboolean processNumber (guint keyval, guint keycode, guint modifiers); - gboolean processNumberWithShift (guint keyval, guint keycode, guint modifiers); - gboolean processBopomofo (guint keyval, guint keycode, guint modifiers); - gint keyvalToBopomofo(gint ch); - - }; }; diff --git a/src/BopomofoEngine.cc b/src/BopomofoEngine.cc index 30b1d5f..3c9b464 100644 --- a/src/BopomofoEngine.cc +++ b/src/BopomofoEngine.cc @@ -26,8 +26,6 @@ #include "RawEditor.h" #include "PunctEditor.h" #include "ExtEditor.h" -#include "FullPinyinEditor.h" -#include "DoublePinyinEditor.h" #include "BopomofoEditor.h" #include "BopomofoEngine.h" #include "HalfFullConverter.h" @@ -70,14 +68,6 @@ BopomofoEngine::~BopomofoEngine (void) { } - -#define CASHM_MASK \ - (IBUS_CONTROL_MASK | \ - IBUS_MOD1_MASK | \ - IBUS_SUPER_MASK | \ - IBUS_HYPER_MASK | \ - IBUS_META_MASK) - gboolean BopomofoEngine::processKeyEvent (guint keyval, guint keycode, guint modifiers) { @@ -101,7 +91,7 @@ BopomofoEngine::processKeyEvent (guint keyval, guint keycode, guint modifiers) if (m_props.modeChinese ()) { if (G_UNLIKELY (m_input_mode == MODE_INIT && m_editors[MODE_INIT]->text ().empty () && - (modifiers & CASHM_MASK) == 0) && + (CMSHM_FILTER (modifiers)) == 0) && keyval == IBUS_grave) { /* if BopomofoEditor is empty and get a grave key, * switch current editor to PunctEditor */ diff --git a/src/DoublePinyinEditor.cc b/src/DoublePinyinEditor.cc index e27dc72..6ad064e 100644 --- a/src/DoublePinyinEditor.cc +++ b/src/DoublePinyinEditor.cc @@ -468,16 +468,6 @@ DoublePinyinEditor::updateAuxiliaryTextAfter (String &buffer) } } -#define CMSHM_MASK \ - (IBUS_CONTROL_MASK | \ - IBUS_MOD1_MASK | \ - IBUS_SUPER_MASK | \ - IBUS_HYPER_MASK | \ - IBUS_META_MASK) - -#define CMSHM_FILTER(modifiers) \ - (modifiers & (CMSHM_MASK)) - gboolean DoublePinyinEditor::processKeyEvent (guint keyval, guint keycode, guint modifiers) { diff --git a/src/Editor.h b/src/Editor.h index 6e0bbbb..b1e2093 100644 --- a/src/Editor.h +++ b/src/Editor.h @@ -29,6 +29,7 @@ #include "LookupTable.h" #include "PinyinProperties.h" #include "Config.h" +#include "Util.h" namespace PY { diff --git a/src/FallbackEditor.cc b/src/FallbackEditor.cc index 65fd417..e1a0d33 100644 --- a/src/FallbackEditor.cc +++ b/src/FallbackEditor.cc @@ -23,16 +23,6 @@ namespace PY { -#define CMSHM_MASK \ - (IBUS_CONTROL_MASK | \ - IBUS_MOD1_MASK | \ - IBUS_SUPER_MASK | \ - IBUS_HYPER_MASK | \ - IBUS_META_MASK) - -#define CMSHM_FILTER(modifiers) \ - (modifiers & (CMSHM_MASK)) - inline gboolean FallbackEditor::processPunct (guint keyval, guint keycode, guint modifiers) { diff --git a/src/Makefile.am b/src/Makefile.am index 2df1235b..6ec66e8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -46,6 +46,7 @@ ibus_engine_c_sources = \ FullPinyinEditor.cc \ HalfFullConverter.cc \ Main.cc \ + PhoneticEditor.cc \ PhraseEditor.cc \ PinyinEditor.cc \ PinyinEngine.cc \ @@ -80,6 +81,7 @@ ibus_engine_h_sources = \ HalfFullConverter.h \ LookupTable.h \ Object.h \ + PhoneticEditor.h \ Phrase.h \ PhraseArray.h \ PhraseEditor.h \ diff --git a/src/PhoneticEditor.cc b/src/PhoneticEditor.cc new file mode 100644 index 0000000..56f6af8 --- /dev/null +++ b/src/PhoneticEditor.cc @@ -0,0 +1,438 @@ +/* vim:set et ts=4 sts=4: + * + * ibus-pinyin - The Chinese PinYin engine for IBus + * + * Copyright (c) 2008-2010 Peng Huang <shawn.p.huang@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include "Config.h" +#include "PhoneticEditor.h" +#include "SimpTradConverter.h" + +namespace PY { + +/* init static members */ +PhoneticEditor::PhoneticEditor (PinyinProperties & props, Config & config) + : Editor (props, config), + m_pinyin (MAX_PHRASE_LEN), + m_pinyin_len (0), + m_buffer (64), + m_lookup_table (m_config.pageSize ()), + m_phrase_editor (props, config) +{ +} + +gboolean +PhoneticEditor::processSpace (guint keyval, guint keycode, guint modifiers) +{ + if (!m_text) + return FALSE; + if (CMSHM_FILTER (modifiers) != 0) + return TRUE; + if (m_lookup_table.size () != 0) { + selectCandidate (m_lookup_table.cursorPos ()); + } + else { + commit (); + } + return TRUE; +} + +gboolean +PhoneticEditor::processFunctionKey (guint keyval, guint keycode, guint modifiers) +{ + if (m_text.empty ()) + return FALSE; + + /* ignore numlock */ + modifiers = CMSHM_FILTER (modifiers); + + if (modifiers != 0 && modifiers != IBUS_CONTROL_MASK) + return TRUE; + + /* process some cursor control keys */ + if (modifiers == 0) { + switch (keyval) { + case IBUS_Return: + case IBUS_KP_Enter: + commit (); + return TRUE; + + case IBUS_BackSpace: + if (m_phrase_editor.unselectCandidates ()) { + update (); + } + else { + removeCharBefore (); + } + return TRUE; + + case IBUS_Delete: + case IBUS_KP_Delete: + removeCharAfter (); + return TRUE; + + case IBUS_Left: + case IBUS_KP_Left: + if (m_phrase_editor.unselectCandidates ()) { + update (); + } + else { + moveCursorLeft (); + } + return TRUE; + + case IBUS_Right: + case IBUS_KP_Right: + if (m_phrase_editor.unselectCandidates ()) { + update (); + } + else { + moveCursorRight (); + } + return TRUE; + + case IBUS_Home: + case IBUS_KP_Home: + if (m_phrase_editor.unselectCandidates ()) { + update (); + } + else { + moveCursorToBegin (); + } + return TRUE; + + case IBUS_End: + case IBUS_KP_End: + if (m_phrase_editor.unselectCandidates ()) { + update (); + } + else { + moveCursorToEnd (); + } + return TRUE; + + case IBUS_Up: + case IBUS_KP_Up: + cursorUp (); + return TRUE; + + case IBUS_Down: + case IBUS_KP_Down: + cursorDown (); + return TRUE; + + case IBUS_Page_Up: + case IBUS_KP_Page_Up: + pageUp (); + return TRUE; + + case IBUS_Page_Down: + case IBUS_KP_Page_Down: + case IBUS_Tab: + pageDown (); + return TRUE; + + case IBUS_Escape: + reset (); + return TRUE; + default: + return TRUE; + } + } + else { + switch (keyval) { + case IBUS_BackSpace: + if (m_phrase_editor.unselectCandidates ()) { + update (); + } + else { + removeWordBefore (); + } + return TRUE; + + case IBUS_Delete: + case IBUS_KP_Delete: + removeWordAfter (); + return TRUE; + + case IBUS_Left: + case IBUS_KP_Left: + if (m_phrase_editor.unselectCandidates ()) { + update (); + } + else { + moveCursorLeftByWord (); + } + return TRUE; + + case IBUS_Right: + case IBUS_KP_Right: + if (m_phrase_editor.unselectCandidates ()) { + update (); + } + else { + moveCursorToEnd (); + } + return TRUE; + + default: + return TRUE; + }; + } + return TRUE; +} + +gboolean +PhoneticEditor::processKeyEvent (guint keyval, guint keycode, guint modifiers) +{ + return FALSE; +} + +gboolean +PhoneticEditor::updateSpecialPhrases (void) { + if (!m_selected_special_phrase.empty ()) + return FALSE; + + guint size = m_special_phrases.size (); + guint begin = m_phrase_editor.cursorInChar (); + guint end = m_cursor; + + m_special_phrases.clear (); + if (begin < end) { + SpecialPhraseTable::instance ().lookup ( + m_text.substr (begin, m_cursor - begin), + m_special_phrases); + } + + return size != m_special_phrases.size () || size != 0; +} + + + +void +PhoneticEditor::updateLookupTable (void) +{ + m_lookup_table.clear (); + + fillLookupTableByPage (); + if (m_lookup_table.size ()) { + Editor::updateLookupTable (m_lookup_table, TRUE); + } + else { + hideLookupTable (); + } +} + +inline gboolean +PhoneticEditor::fillLookupTableByPage (void) +{ + if (!m_selected_special_phrase.empty ()) { + return FALSE; + } + + guint filled_nr = m_lookup_table.size (); + guint page_size = m_lookup_table.pageSize (); + + if (m_special_phrases.size () + m_phrase_editor.candidates ().size () < filled_nr + page_size) + m_phrase_editor.fillCandidates (); + + guint need_nr = MIN (page_size, m_special_phrases.size () + m_phrase_editor.candidates ().size () - filled_nr); + g_assert (need_nr >= 0); + if (need_nr == 0) { + return FALSE; + } + + for (guint i = filled_nr; i < filled_nr + need_nr; i++) { + if (i < m_special_phrases.size ()) { + Text text (m_special_phrases[i].c_str ()); + text.appendAttribute (IBUS_ATTR_TYPE_FOREGROUND, 0x0000ef00, 0, -1); + m_lookup_table.appendCandidate (text); + } + else { + if (G_LIKELY (m_props.modeSimp () || !m_config.tradCandidate ())) { + Text text (m_phrase_editor.candidate (i - m_special_phrases.size ())); + if (m_phrase_editor.candidateIsUserPhease (i - m_special_phrases.size ())) + text.appendAttribute (IBUS_ATTR_TYPE_FOREGROUND, 0x000000ef, 0, -1); + m_lookup_table.appendCandidate (text); + } + else { + m_buffer.truncate (0); + SimpTradConverter::simpToTrad (m_phrase_editor.candidate (i - m_special_phrases.size ()), m_buffer); + Text text (m_buffer); + if (m_phrase_editor.candidateIsUserPhease (i - m_special_phrases.size ())) + text.appendAttribute (IBUS_ATTR_TYPE_FOREGROUND, 0x000000ef, 0, -1); + m_lookup_table.appendCandidate (text); + } + } + } + + + return TRUE; +} + +void +PhoneticEditor::pageUp (void) +{ + if (G_LIKELY (m_lookup_table.pageUp ())) { + updateLookupTableFast (m_lookup_table, TRUE); + updatePreeditText (); + updateAuxiliaryText (); + } +} + +void +PhoneticEditor::pageDown (void) +{ + if (G_LIKELY( + (m_lookup_table.pageDown ()) || + (fillLookupTableByPage () && m_lookup_table.pageDown ()))) { + updateLookupTableFast (m_lookup_table, TRUE); + updatePreeditText (); + updateAuxiliaryText (); + } +} + +void +PhoneticEditor::cursorUp (void) +{ + if (G_LIKELY (m_lookup_table.cursorUp ())) { + updateLookupTableFast (m_lookup_table, TRUE); + updatePreeditText (); + updateAuxiliaryText (); + } +} + +void +PhoneticEditor::cursorDown (void) +{ + if (G_LIKELY ( + (m_lookup_table.cursorPos () == m_lookup_table.size () - 1) && + (fillLookupTableByPage () == FALSE))) { + return; + } + + if (G_LIKELY (m_lookup_table.cursorDown ())) { + updateLookupTableFast (m_lookup_table, TRUE); + updatePreeditText (); + updateAuxiliaryText (); + } +} + +void +PhoneticEditor::candidateClicked (guint index, guint button, guint state) +{ + selectCandidateInPage (index); +} + +void +PhoneticEditor::reset (void) +{ + m_pinyin.clear (); + m_pinyin_len = 0; + m_lookup_table.clear (); + m_phrase_editor.reset (); + m_special_phrases.clear (); + m_selected_special_phrase.clear (); + + Editor::reset (); +} + +void +PhoneticEditor::update (void) +{ + updateLookupTable (); + updatePreeditText (); + updateAuxiliaryText (); +} + +void +PhoneticEditor::commit (const gchar *str) +{ + StaticText text(str); + commitText (text); +} + +inline gboolean +PhoneticEditor::selectCandidate (guint i) +{ + if (i < m_special_phrases.size ()) { + /* select a special phrase */ + m_selected_special_phrase = m_special_phrases[i]; + if (m_cursor == m_text.size ()) { + m_buffer = m_phrase_editor.selectedString (); + m_buffer << m_selected_special_phrase; + m_phrase_editor.commit (); + reset (); + commit ((const gchar *)m_buffer); + } + else { + updateSpecialPhrases (); + update (); + } + return TRUE; + } + + i -= m_special_phrases.size (); + if (m_phrase_editor.selectCandidate (i)) { + if (m_phrase_editor.pinyinExistsAfterCursor () || + *textAfterPinyin () != '\0') { + updateSpecialPhrases (); + update (); + } + else { + commit (); + } + return TRUE; + } + return FALSE; +} + +gboolean +PhoneticEditor::selectCandidateInPage (guint i) +{ + guint page_size = m_lookup_table.pageSize (); + guint cursor_pos = m_lookup_table.cursorPos (); + + if (G_UNLIKELY (i >= page_size)) + return FALSE; + i += (cursor_pos / page_size) * page_size; + + return selectCandidate (i); +} + +inline gboolean +PhoneticEditor::resetCandidate (guint i) +{ + i -= m_special_phrases.size (); + if (m_phrase_editor.resetCandidate (i)) { + update (); + } + return TRUE; +} + +gboolean +PhoneticEditor::resetCandidateInPage (guint i) +{ + guint page_size = m_lookup_table.pageSize (); + guint cursor_pos = m_lookup_table.cursorPos (); + i += (cursor_pos / page_size) * page_size; + + return resetCandidate (i); +} + +}; + diff --git a/src/PhoneticEditor.h b/src/PhoneticEditor.h new file mode 100644 index 0000000..36178ca --- /dev/null +++ b/src/PhoneticEditor.h @@ -0,0 +1,112 @@ +/* vim:set et ts=4 sts=4: + * + * ibus-pinyin - The Chinese PinYin engine for IBus + * + * Copyright (c) 2008-2010 Peng Huang <shawn.p.huang@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#ifndef __PY_PHONETIC_EDITOR_H_ +#define __PY_PHONETIC_EDITOR_H_ + +#include <glib.h> +#include "Editor.h" +#include "Database.h" +#include "PinyinParser.h" +#include "PhraseEditor.h" +#include "SpecialPhraseTable.h" + +namespace PY { + +class SpecialPhraseTable; + +class PhoneticEditor : public Editor { +public: + PhoneticEditor (PinyinProperties & props, Config & config); + +public: + /* virtual functions */ + virtual void pageUp (void); + virtual void pageDown (void); + virtual void cursorUp (void); + virtual void cursorDown (void); + virtual void update (void); + virtual void reset (void); + virtual void candidateClicked (guint index, guint button, guint state); + virtual gboolean processKeyEvent (guint keyval, guint keycode, guint modifiers); + virtual gboolean processSpace (guint keyval, guint keycode, guint modifiers); + virtual gboolean processFunctionKey (guint keyval, guint keycode, guint modifiers); + virtual void updateLookupTable (); + virtual gboolean fillLookupTableByPage (); + +protected: + + gboolean updateSpecialPhrases (); + gboolean selectCandidate (guint i); + gboolean selectCandidateInPage (guint i); + gboolean resetCandidate (guint i); + gboolean resetCandidateInPage (guint i); + + void commit (const gchar *str); + + /* inline functions */ + void updatePhraseEditor () { + m_phrase_editor.update (m_pinyin); + } + + const gchar * textAfterPinyin () const { + return (const gchar *)m_text + m_pinyin_len; + } + + const gchar * textAfterPinyin (guint i) const { + g_assert (i <= m_pinyin.size ()); + if ( G_UNLIKELY (i == 0)) + return m_text; + i--; + return (const gchar *)m_text + m_pinyin[i].begin + m_pinyin[i].len; + } + + const gchar * textAfterCursor () const { + return (const gchar *)m_text + m_cursor; + } + + /* pure virtual functions */ + virtual gboolean insert (gint ch) = 0; + virtual gboolean removeCharBefore (void) = 0; + virtual gboolean removeCharAfter (void) = 0; + virtual gboolean removeWordBefore (void) = 0; + virtual gboolean removeWordAfter (void) = 0; + virtual gboolean moveCursorLeft (void) = 0; + virtual gboolean moveCursorRight (void) = 0; + virtual gboolean moveCursorLeftByWord (void) = 0; + virtual gboolean moveCursorRightByWord (void) = 0; + virtual gboolean moveCursorToBegin (void) = 0; + virtual gboolean moveCursorToEnd (void) = 0; + virtual void commit (void) = 0; + virtual void updateAuxiliaryText (void) = 0; + virtual void updatePreeditText (void) = 0; + + /* varibles */ + PinyinArray m_pinyin; + guint m_pinyin_len; + String m_buffer; + LookupTable m_lookup_table; + PhraseEditor m_phrase_editor; + std::vector<std::string> m_special_phrases; + std::string m_selected_special_phrase; +}; +}; + +#endif diff --git a/src/PinyinEditor.cc b/src/PinyinEditor.cc index 3064638..fa92282 100644 --- a/src/PinyinEditor.cc +++ b/src/PinyinEditor.cc @@ -24,28 +24,12 @@ namespace PY { -#define MAX_PINYIN_LEN 64 - /* init static members */ PinyinEditor::PinyinEditor (PinyinProperties & props, Config & config) - : Editor (props, config), - m_pinyin (MAX_PHRASE_LEN), - m_pinyin_len (0), - m_buffer (64), - m_lookup_table (m_config.pageSize ()), - m_phrase_editor (props, config) + : PhoneticEditor (props, config) { } -#define CMSHM_MASK \ - (IBUS_CONTROL_MASK | \ - IBUS_MOD1_MASK | \ - IBUS_SUPER_MASK | \ - IBUS_HYPER_MASK | \ - IBUS_META_MASK) - -#define CMSHM_FILTER(modifiers) \ - (modifiers & (CMSHM_MASK)) /** * process pinyin @@ -53,7 +37,7 @@ PinyinEditor::PinyinEditor (PinyinProperties & props, Config & config) inline gboolean PinyinEditor::processPinyin (guint keyval, guint keycode, guint modifiers) { - if (G_UNLIKELY (CMSHM_FILTER(modifiers) != 0)) + if (G_UNLIKELY (CMSHM_FILTER (modifiers) != 0)) return m_text ? TRUE : FALSE; return insert (keyval); @@ -92,22 +76,6 @@ PinyinEditor::processNumber (guint keyval, guint keycode, guint modifiers) } inline gboolean -PinyinEditor::processSpace (guint keyval, guint keycode, guint modifiers) -{ - if (!m_text) - return FALSE; - if (CMSHM_FILTER (modifiers) != 0) - return TRUE; - if (m_lookup_table.size () != 0) { - selectCandidate (m_lookup_table.cursorPos ()); - } - else { - commit (); - } - return TRUE; -} - -inline gboolean PinyinEditor::processPunct (guint keyval, guint keycode, guint modifiers) { if (m_text.empty ()) @@ -156,7 +124,7 @@ PinyinEditor::processPunct (guint keyval, guint keycode, guint modifiers) } inline gboolean -PinyinEditor::processOthers (guint keyval, guint keycode, guint modifiers) +PinyinEditor::processFunctionKey (guint keyval, guint keycode, guint modifiers) { if (m_text.empty ()) return FALSE; @@ -181,135 +149,10 @@ PinyinEditor::processOthers (guint keyval, guint keycode, guint modifiers) return FALSE; selectCandidateInPage (2); return TRUE; - - case IBUS_Return: - case IBUS_KP_Enter: - commit (); - return TRUE; - - case IBUS_BackSpace: - if (m_phrase_editor.unselectCandidates ()) { - update (); - } - else { - removeCharBefore (); - } - return TRUE; - - case IBUS_Delete: - case IBUS_KP_Delete: - removeCharAfter (); - return TRUE; - - case IBUS_Left: - case IBUS_KP_Left: - if (m_phrase_editor.unselectCandidates ()) { - update (); - } - else { - moveCursorLeft (); - } - return TRUE; - - case IBUS_Right: - case IBUS_KP_Right: - if (m_phrase_editor.unselectCandidates ()) { - update (); - } - else { - moveCursorRight (); - } - return TRUE; - - case IBUS_Home: - case IBUS_KP_Home: - if (m_phrase_editor.unselectCandidates ()) { - update (); - } - else { - moveCursorToBegin (); - } - return TRUE; - - case IBUS_End: - case IBUS_KP_End: - if (m_phrase_editor.unselectCandidates ()) { - update (); - } - else { - moveCursorToEnd (); - } - return TRUE; - - case IBUS_Up: - case IBUS_KP_Up: - cursorUp (); - return TRUE; - - case IBUS_Down: - case IBUS_KP_Down: - cursorDown (); - return TRUE; - - case IBUS_Page_Up: - case IBUS_KP_Page_Up: - pageUp (); - return TRUE; - - case IBUS_Page_Down: - case IBUS_KP_Page_Down: - case IBUS_Tab: - pageDown (); - return TRUE; - - case IBUS_Escape: - reset (); - return TRUE; - default: - return TRUE; - } - } - else { - switch (keyval) { - case IBUS_BackSpace: - if (m_phrase_editor.unselectCandidates ()) { - update (); - } - else { - removeWordBefore (); - } - return TRUE; - - case IBUS_Delete: - case IBUS_KP_Delete: - removeWordAfter (); - return TRUE; - - case IBUS_Left: - case IBUS_KP_Left: - if (m_phrase_editor.unselectCandidates ()) { - update (); - } - else { - moveCursorLeftByWord (); - } - return TRUE; - - case IBUS_Right: - case IBUS_KP_Right: - if (m_phrase_editor.unselectCandidates ()) { - update (); - } - else { - moveCursorToEnd (); - } - return TRUE; - - default: - return TRUE; }; } - return TRUE; + + return PhoneticEditor::processFunctionKey (keyval, keycode, modifiers); } gboolean @@ -335,36 +178,48 @@ PinyinEditor::processKeyEvent (guint keyval, guint keycode, guint modifiers) case IBUS_bracketleft ... IBUS_quoteleft: case IBUS_braceleft ... IBUS_asciitilde: return processPunct (keyval, keycode, modifiers); - /* space */ case IBUS_space: return processSpace (keyval, keycode, modifiers); - /* others */ default: - return processOthers (keyval, keycode, modifiers); + return processFunctionKey (keyval, keycode, modifiers); } } -gboolean -PinyinEditor::updateSpecialPhrases (void) { - if (!m_selected_special_phrase.empty ()) - return FALSE; +void +PinyinEditor::commit () +{ + if (G_UNLIKELY (m_buffer.empty ())) + return; + + m_buffer.clear (); - guint size = m_special_phrases.size (); - guint begin = m_phrase_editor.cursorInChar (); - guint end = m_cursor; + m_buffer << m_phrase_editor.selectedString (); - m_special_phrases.clear (); - if (begin < end) { - SpecialPhraseTable::instance ().lookup ( - m_text.substr (begin, m_cursor - begin), - m_special_phrases); + const gchar *p; + + if (m_selected_special_phrase.empty ()) { + p = textAfterPinyin (m_buffer.utf8Length ()); + } + else { + m_buffer << m_selected_special_phrase; + p = textAfterCursor (); } - return size != m_special_phrases.size () || size != 0; + if (G_UNLIKELY (m_props.modeFull ())) { + while (*p != '\0') { + m_buffer.appendUnichar (HalfFullConverter::toFull (*p++)); + } + } + else { + m_buffer << p; + } + m_phrase_editor.commit (); + reset (); + PhoneticEditor::commit ((const gchar *)m_buffer); } void -PinyinEditor::updatePreeditText (void) +PinyinEditor::updatePreeditText () { /* preedit text = selected phrases + highlight candidate + rest text */ if (G_UNLIKELY (m_phrase_editor.empty () && m_text.empty ())) { @@ -444,7 +299,7 @@ PinyinEditor::updatePreeditText (void) } void -PinyinEditor::updateAuxiliaryText (void) +PinyinEditor::updateAuxiliaryText () { /* clear pinyin array */ if (G_UNLIKELY (m_text.empty () || @@ -499,260 +354,13 @@ PinyinEditor::updateAuxiliaryText (void) Editor::updateAuxiliaryText (aux_text, TRUE); } + void -PinyinEditor::updateLookupTable (void) +PinyinEditor::updateLookupTable () { - m_lookup_table.clear (); m_lookup_table.setPageSize (m_config.pageSize ()); m_lookup_table.setOrientation (m_config.orientation ()); - - fillLookupTableByPage (); - if (m_lookup_table.size ()) { - Editor::updateLookupTable (m_lookup_table, TRUE); - } - else { - hideLookupTable (); - } -} - -inline gboolean -PinyinEditor::fillLookupTableByPage (void) -{ - if (!m_selected_special_phrase.empty ()) { - return FALSE; - } - - guint filled_nr = m_lookup_table.size (); - guint page_size = m_lookup_table.pageSize (); - - if (m_special_phrases.size () + m_phrase_editor.candidates ().size () < filled_nr + page_size) - m_phrase_editor.fillCandidates (); - - guint need_nr = MIN (page_size, m_special_phrases.size () + m_phrase_editor.candidates ().size () - filled_nr); - g_assert (need_nr >= 0); - if (need_nr == 0) { - return FALSE; - } - - for (guint i = filled_nr; i < filled_nr + need_nr; i++) { - if (i < m_special_phrases.size ()) { - Text text (m_special_phrases[i].c_str ()); - text.appendAttribute (IBUS_ATTR_TYPE_FOREGROUND, 0x0000ef00, 0, -1); - m_lookup_table.appendCandidate (text); - } - else { - if (G_LIKELY (m_props.modeSimp () || !m_config.tradCandidate ())) { - Text text (m_phrase_editor.candidate (i - m_special_phrases.size ())); - if (m_phrase_editor.candidateIsUserPhease (i - m_special_phrases.size ())) - text.appendAttribute (IBUS_ATTR_TYPE_FOREGROUND, 0x000000ef, 0, -1); - m_lookup_table.appendCandidate (text); - } - else { - m_buffer.truncate (0); - SimpTradConverter::simpToTrad (m_phrase_editor.candidate (i - m_special_phrases.size ()), m_buffer); - Text text (m_buffer); - if (m_phrase_editor.candidateIsUserPhease (i - m_special_phrases.size ())) - text.appendAttribute (IBUS_ATTR_TYPE_FOREGROUND, 0x000000ef, 0, -1); - m_lookup_table.appendCandidate (text); - } - } - } - - - return TRUE; -} - -void -PinyinEditor::pageUp (void) -{ - if (G_LIKELY (m_lookup_table.pageUp ())) { - updateLookupTableFast (m_lookup_table, TRUE); - updatePreeditText (); - updateAuxiliaryText (); - } -} - -void -PinyinEditor::pageDown (void) -{ - if (G_LIKELY( - (m_lookup_table.pageDown ()) || - (fillLookupTableByPage () && m_lookup_table.pageDown ()))) { - updateLookupTableFast (m_lookup_table, TRUE); - updatePreeditText (); - updateAuxiliaryText (); - } -} - -void -PinyinEditor::cursorUp (void) -{ - if (G_LIKELY (m_lookup_table.cursorUp ())) { - updateLookupTableFast (m_lookup_table, TRUE); - updatePreeditText (); - updateAuxiliaryText (); - } -} - -void -PinyinEditor::cursorDown (void) -{ - if (G_LIKELY ( - (m_lookup_table.cursorPos () == m_lookup_table.size () - 1) && - (fillLookupTableByPage () == FALSE))) { - return; - } - - if (G_LIKELY (m_lookup_table.cursorDown ())) { - updateLookupTableFast (m_lookup_table, TRUE); - updatePreeditText (); - updateAuxiliaryText (); - } -} - -void -PinyinEditor::candidateClicked (guint index, guint button, guint state) -{ - selectCandidateInPage (index); -} - -void -PinyinEditor::updateAuxiliaryTextBefore (String &buffer) -{ -} - -void -PinyinEditor::updateAuxiliaryTextAfter (String &buffer) -{ -} - -void -PinyinEditor::reset (void) -{ - m_pinyin.clear (); - m_pinyin_len = 0; - m_lookup_table.clear (); - m_phrase_editor.reset (); - m_special_phrases.clear (); - m_selected_special_phrase.clear (); - - Editor::reset (); -} - -void -PinyinEditor::update (void) -{ - updateLookupTable (); - updatePreeditText (); - updateAuxiliaryText (); -} - -void -PinyinEditor::commit (const gchar *str) -{ - StaticText text(str); - commitText (text); -} - -void -PinyinEditor::commit (void) -{ - if (G_UNLIKELY (empty ())) - return; - - m_buffer.clear (); - - m_buffer << m_phrase_editor.selectedString (); - - const gchar *p; - - if (m_selected_special_phrase.empty ()) { - p = textAfterPinyin (m_buffer.utf8Length ()); - } - else { - m_buffer << m_selected_special_phrase; - p = textAfterCursor (); - } - - if (G_UNLIKELY (m_props.modeFull ())) { - while (*p != '\0') { - m_buffer.appendUnichar (HalfFullConverter::toFull (*p++)); - } - } - else { - m_buffer << p; - } - m_phrase_editor.commit (); - reset (); - commit ((const gchar *)m_buffer); -} - -inline gboolean -PinyinEditor::selectCandidate (guint i) -{ - if (i < m_special_phrases.size ()) { - /* select a special phrase */ - m_selected_special_phrase = m_special_phrases[i]; - if (m_cursor == m_text.size ()) { - m_buffer = m_phrase_editor.selectedString (); - m_buffer << m_selected_special_phrase; - m_phrase_editor.commit (); - reset (); - commit ((const gchar *)m_buffer); - } - else { - updateSpecialPhrases (); - update (); - } - return TRUE; - } - - i -= m_special_phrases.size (); - if (m_phrase_editor.selectCandidate (i)) { - if (m_phrase_editor.pinyinExistsAfterCursor () || - *textAfterPinyin () != '\0') { - updateSpecialPhrases (); - update (); - } - else { - commit (); - } - return TRUE; - } - return FALSE; -} - -gboolean -PinyinEditor::selectCandidateInPage (guint i) -{ - guint page_size = m_lookup_table.pageSize (); - guint cursor_pos = m_lookup_table.cursorPos (); - - if (G_UNLIKELY (i >= page_size)) - return FALSE; - i += (cursor_pos / page_size) * page_size; - - return selectCandidate (i); -} - -inline gboolean -PinyinEditor::resetCandidate (guint i) -{ - i -= m_special_phrases.size (); - if (m_phrase_editor.resetCandidate (i)) { - update (); - } - return TRUE; -} - -inline gboolean -PinyinEditor::resetCandidateInPage (guint i) -{ - guint page_size = m_lookup_table.pageSize (); - guint cursor_pos = m_lookup_table.cursorPos (); - i += (cursor_pos / page_size) * page_size; - - return resetCandidate (i); + PhoneticEditor::updateLookupTable (); } }; diff --git a/src/PinyinEditor.h b/src/PinyinEditor.h index 0f40eb5..d4b81f6 100644 --- a/src/PinyinEditor.h +++ b/src/PinyinEditor.h @@ -21,12 +21,7 @@ #ifndef __PY_PINYIN_EDITOR_H_ #define __PY_PINYIN_EDITOR_H_ -#include <glib.h> -#include "Editor.h" -#include "Database.h" -#include "PinyinParser.h" -#include "PhraseEditor.h" -#include "SpecialPhraseTable.h" +#include "PhoneticEditor.h" namespace PY { @@ -34,84 +29,27 @@ namespace PY { class SpecialPhraseTable; -class PinyinEditor : public Editor { +class PinyinEditor : public PhoneticEditor { public: PinyinEditor (PinyinProperties & props, Config & config = PinyinConfig::instance ()); -public: - /* virtual functions */ - virtual gboolean processKeyEvent (guint keyval, guint keycode, guint modifiers); - virtual void pageUp (void); - virtual void pageDown (void); - virtual void cursorUp (void); - virtual void cursorDown (void); - virtual void update (void); - virtual void reset (void); - virtual void candidateClicked (guint index, guint button, guint state); - virtual void updateAuxiliaryTextBefore (String &buffer); - virtual void updateAuxiliaryTextAfter (String &buffer); protected: - gboolean processPinyin (guint keyval, guint keycode, guint modifiers); - gboolean processCapitalLetter (guint keyval, guint keycode, guint modifiers); gboolean processNumber (guint keyval, guint keycode, guint modifiers); gboolean processPunct (guint keyval, guint keycode, guint modifiers); - gboolean processSpace (guint keyval, guint keycode, guint modifiers); - gboolean processOthers (guint keyval, guint keycode, guint modifiers); - - gboolean fillLookupTableByPage (void); - - void updatePhraseEditor (void) { m_phrase_editor.update (m_pinyin); } - gboolean updateSpecialPhrases (void); - gboolean selectCandidate (guint i); - gboolean selectCandidateInPage (guint i); - gboolean resetCandidate (guint i); - gboolean resetCandidateInPage (guint i); + gboolean processFunctionKey (guint keyval, guint keycode, guint modifiers); - void commit (const gchar *str); + void commit (); - const String & text (void) const { return m_text; } - const gchar * textAfterPinyin (void) const { return (const gchar *)m_text + m_pinyin_len; } - const gchar * textAfterPinyin (guint i) const { - g_assert (i <= m_pinyin.size ()); - if ( G_UNLIKELY (i == 0)) - return m_text; - i--; - return (const gchar *)m_text + m_pinyin[i].begin + m_pinyin[i].len; - } - const gchar * textAfterCursor (void) const { return (const gchar *)m_text + m_cursor; } - guint cursor (void) const { return m_cursor; } - gboolean empty (void) const { return m_buffer.empty (); } - const PinyinArray & pinyin (void) const { return m_pinyin; } - guint pinyinLength (void) const { return m_pinyin_len; } - operator gboolean (void) const { return ! empty (); } + void updateAuxiliaryText (void); + void updateLookupTable (void); + void updatePreeditText (void); - /* virtual functions */ - virtual void updatePreeditText (void); - virtual void updateAuxiliaryText (void); - virtual void updateLookupTable (void); - virtual void commit (void); - virtual gboolean insert (gint ch) = 0; - virtual gboolean removeCharBefore (void) = 0; - virtual gboolean removeCharAfter (void) = 0; - virtual gboolean removeWordBefore (void) = 0; - virtual gboolean removeWordAfter (void) = 0; - virtual gboolean moveCursorLeft (void) = 0; - virtual gboolean moveCursorRight (void) = 0; - virtual gboolean moveCursorLeftByWord (void) = 0; - virtual gboolean moveCursorRightByWord (void) = 0; - virtual gboolean moveCursorToBegin (void) = 0; - virtual gboolean moveCursorToEnd (void) = 0; - -protected: - PinyinArray m_pinyin; // pinyin array - guint m_pinyin_len; // pinyin length in char - String m_buffer; // temp buffer - LookupTable m_lookup_table; - PhraseEditor m_phrase_editor; - std::vector<std::string> m_special_phrases; - std::string m_selected_special_phrase; + virtual gboolean processKeyEvent (guint keyval, guint keycode, guint modifiers); + virtual void updateAuxiliaryTextBefore (String &buffer) {}; + virtual void updateAuxiliaryTextAfter (String &buffer) {}; }; + }; #endif diff --git a/src/PinyinEngine.cc b/src/PinyinEngine.cc index ae3f119..e8c7cb7 100644 --- a/src/PinyinEngine.cc +++ b/src/PinyinEngine.cc @@ -27,7 +27,6 @@ #include "ExtEditor.h" #include "FullPinyinEditor.h" #include "DoublePinyinEditor.h" -#include "BopomofoEditor.h" #include "PinyinEngine.h" #include "HalfFullConverter.h" #include "Config.h" @@ -71,14 +70,6 @@ PinyinEngine::~PinyinEngine (void) { } - -#define CASHM_MASK \ - (IBUS_CONTROL_MASK | \ - IBUS_MOD1_MASK | \ - IBUS_SUPER_MASK | \ - IBUS_HYPER_MASK | \ - IBUS_META_MASK) - gboolean PinyinEngine::processKeyEvent (guint keyval, guint keycode, guint modifiers) { @@ -101,7 +92,7 @@ PinyinEngine::processKeyEvent (guint keyval, guint keycode, guint modifiers) if (m_props.modeChinese ()) { if (m_input_mode == MODE_INIT && - ((modifiers & CASHM_MASK) == 0)) { + ((CMSHM_FILTER (modifiers)) == 0)) { const String & text = m_editors[MODE_INIT]->text (); if (text.empty ()) { switch (keyval) { diff --git a/src/PunctEditor.cc b/src/PunctEditor.cc index 30986e6..d39bcc6 100644 --- a/src/PunctEditor.cc +++ b/src/PunctEditor.cc @@ -22,16 +22,6 @@ #include <cstdio> #include "PunctEditor.h" -#define CMSHM_MASK \ - (IBUS_CONTROL_MASK | \ - IBUS_MOD1_MASK | \ - IBUS_SUPER_MASK | \ - IBUS_HYPER_MASK | \ - IBUS_META_MASK) - -#define CMSHM_FILTER(modifiers) \ - (modifiers & (CMSHM_MASK)) - namespace PY { #include "PunctTable.h" @@ -37,6 +37,16 @@ namespace PY { +#define CMSHM_MASK \ + (IBUS_CONTROL_MASK | \ + IBUS_MOD1_MASK | \ + IBUS_SUPER_MASK | \ + IBUS_HYPER_MASK | \ + IBUS_META_MASK) + +#define CMSHM_FILTER(modifiers) \ + (modifiers & (CMSHM_MASK)) + class UUID { public: UUID (void) { |