#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)
- : PinyinEditor (props),
+ : PhoneticEditor (props),
m_select_mode (FALSE)
{
}
BopomofoEditor::reset (void)
{
m_select_mode = FALSE;
- PinyinEditor::reset ();
+ PhoneticEditor::reset ();
}
gboolean
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)
{
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)
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:
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);
}
}
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) {
if (m_cursor == m_text.length ())
m_buffer << '|';
- updateAuxiliaryTextAfter (m_buffer);
-
StaticText aux_text (m_buffer);
Editor::updateAuxiliaryText (aux_text, TRUE);
}
void
BopomofoEditor::commit (void)
{
- if (G_UNLIKELY (empty ()))
+ if (G_UNLIKELY (m_buffer.empty ()))
return;
m_buffer.clear ();
m_phrase_editor.commit ();
reset ();
- PinyinEditor::commit ((const gchar *)m_buffer);
+ PhoneticEditor::commit ((const gchar *)m_buffer);
}
void
Editor::updatePreeditText (preedit_text, edit_begin, TRUE);
}
+void
+BopomofoEditor::updateLookupTable ()
+{
+ m_lookup_table.setPageSize (Config::pageSize ());
+ m_lookup_table.setOrientation (Config::orientation ());
+ PhoneticEditor::updateLookupTable ();
+}
+
static int
keyboard_cmp (const void *p1, const void *p2)
{
#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);
~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);
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);
-
-
};
};
#include "RawEditor.h"
#include "PunctEditor.h"
#include "ExtEditor.h"
-#include "FullPinyinEditor.h"
-#include "DoublePinyinEditor.h"
#include "BopomofoEditor.h"
#include "BopomofoEngine.h"
#include "HalfFullConverter.h"
{
}
-
-#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)
{
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 */
}
}
-#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)
{
#include "Text.h"
#include "LookupTable.h"
#include "PinyinProperties.h"
+#include "Util.h"
namespace PY {
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)
{
FullPinyinEditor.cc \
HalfFullConverter.cc \
Main.cc \
+ PhoneticEditor.cc \
PhraseEditor.cc \
PinyinEditor.cc \
PinyinEngine.cc \
HalfFullConverter.h \
LookupTable.h \
Object.h \
+ PhoneticEditor.h \
Phrase.h \
PhraseArray.h \
PhraseEditor.h \
--- /dev/null
+/* 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)
+ : Editor (props),
+ m_pinyin (MAX_PHRASE_LEN),
+ m_pinyin_len (0),
+ m_buffer (64),
+ m_lookup_table (Config::pageSize ()),
+ m_phrase_editor (props)
+{
+}
+
+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 () || !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);
+}
+
+};
+
--- /dev/null
+/* 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);
+
+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
namespace PY {
-#define MAX_PINYIN_LEN 64
-
/* init static members */
PinyinEditor::PinyinEditor (PinyinProperties & props)
- : Editor (props),
- m_pinyin (MAX_PHRASE_LEN),
- m_pinyin_len (0),
- m_buffer (64),
- m_lookup_table (Config::pageSize ()),
- m_phrase_editor (props)
+ : PhoneticEditor (props)
{
}
-#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
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);
}
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 ())
}
inline gboolean
-PinyinEditor::processOthers (guint keyval, guint keycode, guint modifiers)
+PinyinEditor::processFunctionKey (guint keyval, guint keycode, guint modifiers)
{
if (m_text.empty ())
return FALSE;
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
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 ())) {
}
void
-PinyinEditor::updateAuxiliaryText (void)
+PinyinEditor::updateAuxiliaryText ()
{
/* clear pinyin array */
if (G_UNLIKELY (m_text.empty () ||
Editor::updateAuxiliaryText (aux_text, TRUE);
}
+
void
-PinyinEditor::updateLookupTable (void)
+PinyinEditor::updateLookupTable ()
{
- m_lookup_table.clear ();
m_lookup_table.setPageSize (Config::pageSize ());
m_lookup_table.setOrientation (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 () || !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 ();
}
};
#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 {
class SpecialPhraseTable;
-class PinyinEditor : public Editor {
+class PinyinEditor : public PhoneticEditor {
public:
PinyinEditor (PinyinProperties & props);
-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
#include "ExtEditor.h"
#include "FullPinyinEditor.h"
#include "DoublePinyinEditor.h"
-#include "BopomofoEditor.h"
#include "PinyinEngine.h"
#include "HalfFullConverter.h"
#include "Config.h"
{
}
-
-#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)
{
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) {
#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"
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) {