From bb8f130fb94108cb1fa6863d14e1b2cd165a1594 Mon Sep 17 00:00:00 2001 From: Peng Huang Date: Sun, 16 May 2010 09:33:59 +0800 Subject: Add MODE_PUNCT in BopomofoEngine --- src/PunctEditor.cc | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 src/PunctEditor.cc (limited to 'src/PunctEditor.cc') diff --git a/src/PunctEditor.cc b/src/PunctEditor.cc new file mode 100644 index 0000000..5b22ce5 --- /dev/null +++ b/src/PunctEditor.cc @@ -0,0 +1,60 @@ +#include "PunctEditor.h" + +namespace PY { + +PunctEditor::PunctEditor (PinyinProperties & props) + : Editor (props) +{ +} + +gboolean +PunctEditor::processKeyEvent (guint keyval, guint keycode, guint modifiers) +{ + return Editor::processKeyEvent (keyval, keycode, modifiers); +} + +void +PunctEditor::pageUp (void) +{ + Editor::pageUp (); +} + +void +PunctEditor::pageDown (void) +{ + Editor::pageDown (); +} + +void +PunctEditor::cursorUp (void) +{ + Editor::cursorUp (); +} + +void +PunctEditor::cursorDown (void) +{ + Editor::cursorDown (); +} + +void +PunctEditor::update (void) +{ + Editor::update (); +} + +void +PunctEditor::reset (void) +{ + Editor::reset (); +} + +void +PunctEditor::candidateClicked (guint index, guint button, guint state) +{ + Editor::candidateClicked (index, button, state); +} + +}; + + -- cgit From 40b35c83033ba26a661731f44405280ed91bd48a Mon Sep 17 00:00:00 2001 From: Peng Huang Date: Sun, 16 May 2010 12:42:22 +0800 Subject: Add PunctTable.h --- src/PunctEditor.cc | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/PunctEditor.cc') diff --git a/src/PunctEditor.cc b/src/PunctEditor.cc index 5b22ce5..45c7dba 100644 --- a/src/PunctEditor.cc +++ b/src/PunctEditor.cc @@ -2,6 +2,8 @@ namespace PY { +#include "PunctTable.h" + PunctEditor::PunctEditor (PinyinProperties & props) : Editor (props) { -- cgit From 8df3e417526b436fadfb7eeced6bde5cc24577e0 Mon Sep 17 00:00:00 2001 From: BYVoid Date: Sun, 16 May 2010 23:02:07 +0800 Subject: implement PunctEditor for BopomofoEngine --- src/PunctEditor.cc | 444 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 434 insertions(+), 10 deletions(-) (limited to 'src/PunctEditor.cc') diff --git a/src/PunctEditor.cc b/src/PunctEditor.cc index 45c7dba..5304b74 100644 --- a/src/PunctEditor.cc +++ b/src/PunctEditor.cc @@ -1,60 +1,484 @@ #include "PunctEditor.h" +#include + +#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" PunctEditor::PunctEditor (PinyinProperties & props) - : Editor (props) + : Editor (props), + m_punct_mode (FALSE), + m_lookup_table (Config::pageSize ()) +{ +} + +gboolean +PunctEditor::insert (gchar ch) { + m_text.insert (m_cursor++, ch); + update (); + return TRUE; +} + +inline gboolean +PunctEditor::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 +PunctEditor::processPunct (guint keyval, guint keycode, guint modifiers) +{ + if (CMSHM_FILTER (modifiers) != 0) + return TRUE; + + if (m_punct_mode == FALSE) { + if (keyval == IBUS_grave) { + m_punct_mode = TRUE; + return insert('`'); + } + return FALSE; + } + + switch (keyval) { + case IBUS_grave: /* ` */ + case IBUS_asciitilde: /* ~ */ + case IBUS_exclam: /* ~ */ + case IBUS_at: /* @ */ + case IBUS_numbersign: /* # */ + case IBUS_dollar: /* $ */ + case IBUS_percent: /* % */ + case IBUS_asciicircum: /* ^ */ + case IBUS_ampersand: /* & */ + case IBUS_asterisk: /* * */ + case IBUS_parenleft: /* ( */ + case IBUS_parenright: /* ) */ + case IBUS_minus: /* - */ + case IBUS_underscore: /* _ */ + case IBUS_equal: /* = */ + case IBUS_plus: /* + */ + case IBUS_bracketleft: /* [ */ + case IBUS_bracketright: /* ] */ + case IBUS_braceleft: /* { */ + case IBUS_braceright: /* } */ + case IBUS_backslash: /* \ */ + case IBUS_bar: /* | */ + case IBUS_colon: /* : */ + case IBUS_semicolon: /* ; */ + case IBUS_apostrophe: /* ' */ + case IBUS_quotedbl: /* " */ + case IBUS_comma: /* , */ + case IBUS_period: /* . */ + case IBUS_less: /* < */ + case IBUS_greater: /* > */ + case IBUS_slash: /* / */ + case IBUS_question: /* ? */ + case IBUS_0...IBUS_9: + case IBUS_a...IBUS_z: + case IBUS_A...IBUS_Z: + return insert(keyval); + default: + return FALSE; + } } gboolean PunctEditor::processKeyEvent (guint keyval, guint keycode, guint modifiers) { - return Editor::processKeyEvent (keyval, keycode, modifiers); + modifiers &= (IBUS_SHIFT_MASK | + IBUS_CONTROL_MASK | + IBUS_MOD1_MASK | + IBUS_SUPER_MASK | + IBUS_HYPER_MASK | + IBUS_META_MASK | + IBUS_LOCK_MASK); + + printf("%d %d %d\n",keyval,keycode,modifiers); + + if (processPunct(keyval,keycode,modifiers) == TRUE) + return TRUE; + + switch (keyval) { + case IBUS_space: + return processSpace (keyval, keycode, modifiers); + + case IBUS_Return: + case IBUS_KP_Enter: + commit (); + return TRUE; + + case IBUS_BackSpace: + removeCharBefore (); + return TRUE; + + case IBUS_Delete: + case IBUS_KP_Delete: + removeCharAfter (); + return TRUE; + + case IBUS_Left: + case IBUS_KP_Left: + moveCursorLeft (); + return TRUE; + + case IBUS_Right: + case IBUS_KP_Right: + moveCursorRight (); + return TRUE; + + case IBUS_Home: + case IBUS_KP_Home: + moveCursorToBegin (); + return TRUE; + + case IBUS_End: + case IBUS_KP_End: + 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; + default: + return Editor::processKeyEvent (keyval, keycode, modifiers); + } } void PunctEditor::pageUp (void) { - Editor::pageUp (); + if (G_LIKELY (m_lookup_table.pageUp ())) { + updateLookupTableFast (m_lookup_table, TRUE); + updatePreeditText (); + updateAuxiliaryText (); + } } void PunctEditor::pageDown (void) { - Editor::pageDown (); + if (G_LIKELY( + (m_lookup_table.pageDown ()) || + (fillLookupTableByPage () && m_lookup_table.pageDown ()))) { + updateLookupTableFast (m_lookup_table, TRUE); + updatePreeditText (); + updateAuxiliaryText (); + } } void PunctEditor::cursorUp (void) { - Editor::cursorUp (); + if (G_LIKELY (m_lookup_table.cursorUp ())) { + updateLookupTableFast (m_lookup_table, TRUE); + updatePreeditText (); + updateAuxiliaryText (); + } } void PunctEditor::cursorDown (void) { - Editor::cursorDown (); + 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 -PunctEditor::update (void) +gboolean +PunctEditor::moveCursorLeft (void) +{ + if (G_UNLIKELY (m_cursor == 0)) + return FALSE; + m_cursor --; + update(); + return TRUE; +} + +gboolean +PunctEditor::moveCursorRight (void) { - Editor::update (); + if (G_UNLIKELY (m_cursor == m_text.length ())) + return FALSE; + m_cursor ++; + update(); + return TRUE; +} + +gboolean +PunctEditor::moveCursorToBegin (void) +{ + if (G_UNLIKELY (m_cursor == 0)) + return FALSE; + m_cursor = 0; + update (); + return TRUE; +} + +gboolean +PunctEditor::moveCursorToEnd (void) +{ + if (G_UNLIKELY (m_cursor == m_text.length ())) + return FALSE; + m_cursor = m_text.length (); + update(); + return TRUE; +} + +gboolean +PunctEditor::removeCharBefore (void) +{ + if (G_UNLIKELY (m_cursor == 0)) + return FALSE; + + m_cursor --; + m_text.erase (m_cursor, 1); + if (m_text.empty()) + m_punct_mode = FALSE; + + update(); + + return TRUE; +} + +gboolean +PunctEditor::removeCharAfter (void) +{ + if (G_UNLIKELY (m_cursor == m_text.length ())) + return FALSE; + + m_text.erase (m_cursor, 1); + if (m_text.empty()) + m_punct_mode = FALSE; + + update(); + + return TRUE; } void PunctEditor::reset (void) { + m_punct_mode = FALSE; Editor::reset (); } void PunctEditor::candidateClicked (guint index, guint button, guint state) { - Editor::candidateClicked (index, button, state); + selectCandidateInPage(index); +} + +inline void +PunctEditor::commit (const gchar *str) +{ + StaticText text(str); + commitText (text); +} + +void +PunctEditor::commit (void) +{ + commit ((const gchar *)m_text); + reset(); +} + +inline gboolean +PunctEditor::selectCandidate (guint i) +{ + m_buffer.clear (); + m_buffer << m_punct_candidates[i]; + reset(); + commit ((const gchar *) m_buffer); + return FALSE; +} + +inline gboolean +PunctEditor::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); +} + +void +PunctEditor::update (void) +{ + updateLookupTable (); + updatePreeditText (); + updateAuxiliaryText (); +} + +void +PunctEditor::updateLookupTable (void) +{ + 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 (); + } +} + +static int +punct_cmp (const void *p1, const void *p2) +{ + const gchar *s1 = (gchar *) p1; + const gchar *s2 = **(gchar ***) p2; + return strcmp(s1,s2); +} + +void +PunctEditor::getPunctCandidates (void) +{ + const gchar *** brs; + const gchar ** res; + m_punct_candidates.clear(); + + if (m_text.empty()) + return; + + brs = (const gchar ***) std::bsearch (m_text.c_str() + 1, punct_table, + G_N_ELEMENTS (punct_table), + sizeof(punct_table[0]), + punct_cmp); + if (brs == NULL) + return; + + for (res = (*brs) + 1 ;*res != NULL; ++res ) { + m_punct_candidates.push_back(*res); + } +} + +gboolean +PunctEditor::fillLookupTableByPage (void) +{ + guint filled_nr = m_lookup_table.size (); + guint page_size = m_lookup_table.pageSize (); + guint candidates_count; + + getPunctCandidates(); + candidates_count = m_punct_candidates.size(); + + guint need_nr = MIN (page_size, candidates_count - filled_nr); + g_assert (need_nr >= 0); + if (need_nr == 0) { + return FALSE; + } + + for (guint i = filled_nr; i < filled_nr + need_nr; i++) { + Text text (m_punct_candidates[i]); + text.appendAttribute (IBUS_ATTR_TYPE_FOREGROUND, 0x004466, 0, -1); + m_lookup_table.appendCandidate (text); + } + + return TRUE; +} + +void +PunctEditor::updateAuxiliaryText (void) +{ + if (G_UNLIKELY (m_punct_mode == FALSE)) { + hideAuxiliaryText (); + return; + } + + m_buffer.clear(); + for (String::iterator i = m_text.begin(); i!=m_text.end(); ++i) { + if (i - m_text.begin() == m_cursor) + m_buffer << '|'; + m_buffer << *i; + } + if (m_text.end() - m_text.begin() == m_cursor) + m_buffer << '|'; + + StaticText aux_text (m_buffer); + Editor::updateAuxiliaryText (aux_text, TRUE); +} + +void +PunctEditor::updatePreeditText (void) +{ + if (G_UNLIKELY (m_punct_mode == FALSE )) { + hidePreeditText (); + return; + } + + guint edit_begin = 0; + guint edit_end = 0; + + m_buffer.clear (); + if (m_lookup_table.size() != 0) { + guint cursor = m_lookup_table.cursorPos (); + m_buffer << m_punct_candidates[cursor]; + } + + StaticText preedit_text (m_buffer); + /* underline */ + preedit_text.appendAttribute (IBUS_ATTR_TYPE_UNDERLINE, IBUS_ATTR_UNDERLINE_SINGLE, 0, -1); + + /* candidate */ + if (edit_begin < edit_end) { + preedit_text.appendAttribute (IBUS_ATTR_TYPE_FOREGROUND, 0x00000000, + edit_begin, edit_end); + preedit_text.appendAttribute (IBUS_ATTR_TYPE_BACKGROUND, 0x00c8c8f0, + edit_begin, edit_end); + } + Editor::updatePreeditText (preedit_text, edit_begin, TRUE); } }; -- cgit From acf0cdaca6d0c75359f90f4a888c6c99fc47c49b Mon Sep 17 00:00:00 2001 From: Peng Huang Date: Mon, 17 May 2010 07:12:59 +0800 Subject: Fix the order of punct_table --- src/PunctEditor.cc | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'src/PunctEditor.cc') diff --git a/src/PunctEditor.cc b/src/PunctEditor.cc index 5304b74..22467bd 100644 --- a/src/PunctEditor.cc +++ b/src/PunctEditor.cc @@ -113,8 +113,6 @@ PunctEditor::processKeyEvent (guint keyval, guint keycode, guint modifiers) IBUS_META_MASK | IBUS_LOCK_MASK); - printf("%d %d %d\n",keyval,keycode,modifiers); - if (processPunct(keyval,keycode,modifiers) == TRUE) return TRUE; @@ -379,7 +377,7 @@ punct_cmp (const void *p1, const void *p2) { const gchar *s1 = (gchar *) p1; const gchar *s2 = **(gchar ***) p2; - return strcmp(s1,s2); + return std::strcmp (s1, s2); } void @@ -439,11 +437,11 @@ PunctEditor::updateAuxiliaryText (void) m_buffer.clear(); for (String::iterator i = m_text.begin(); i!=m_text.end(); ++i) { - if (i - m_text.begin() == m_cursor) + if (i - m_text.begin() == (gint) m_cursor) m_buffer << '|'; m_buffer << *i; } - if (m_text.end() - m_text.begin() == m_cursor) + if (m_text.end() - m_text.begin() == (gint) m_cursor) m_buffer << '|'; StaticText aux_text (m_buffer); -- cgit From 9e4631290f6c40a74ba1403644b8536fe065ca91 Mon Sep 17 00:00:00 2001 From: Peng Huang Date: Mon, 17 May 2010 07:17:20 +0800 Subject: Refine some code. --- src/PunctEditor.cc | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) (limited to 'src/PunctEditor.cc') diff --git a/src/PunctEditor.cc b/src/PunctEditor.cc index 22467bd..254943e 100644 --- a/src/PunctEditor.cc +++ b/src/PunctEditor.cc @@ -1,5 +1,5 @@ -#include "PunctEditor.h" #include +#include "PunctEditor.h" #define CMSHM_MASK \ (IBUS_CONTROL_MASK | \ @@ -192,9 +192,7 @@ PunctEditor::pageUp (void) void PunctEditor::pageDown (void) { - if (G_LIKELY( - (m_lookup_table.pageDown ()) || - (fillLookupTableByPage () && m_lookup_table.pageDown ()))) { + if (G_LIKELY (m_lookup_table.pageDown ())) { updateLookupTableFast (m_lookup_table, TRUE); updatePreeditText (); updateAuxiliaryText (); @@ -214,12 +212,6 @@ PunctEditor::cursorUp (void) void PunctEditor::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 (); @@ -397,7 +389,7 @@ PunctEditor::getPunctCandidates (void) if (brs == NULL) return; - for (res = (*brs) + 1 ;*res != NULL; ++res ) { + for (res = (*brs) + 1; *res != NULL; ++res) { m_punct_candidates.push_back(*res); } } @@ -436,7 +428,7 @@ PunctEditor::updateAuxiliaryText (void) } m_buffer.clear(); - for (String::iterator i = m_text.begin(); i!=m_text.end(); ++i) { + for (String::iterator i = m_text.begin(); i != m_text.end(); ++i) { if (i - m_text.begin() == (gint) m_cursor) m_buffer << '|'; m_buffer << *i; -- cgit From 70c8b03d0e5112fc1fcd9fcc557ff5714767c8bd Mon Sep 17 00:00:00 2001 From: Peng Huang Date: Mon, 17 May 2010 07:23:36 +0800 Subject: Do not allow input chars more than 2 --- src/PunctEditor.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/PunctEditor.cc') diff --git a/src/PunctEditor.cc b/src/PunctEditor.cc index 254943e..d73b990 100644 --- a/src/PunctEditor.cc +++ b/src/PunctEditor.cc @@ -60,6 +60,9 @@ PunctEditor::processPunct (guint keyval, guint keycode, guint modifiers) return FALSE; } + if (m_text.length () >= 2) + return TRUE; + switch (keyval) { case IBUS_grave: /* ` */ case IBUS_asciitilde: /* ~ */ @@ -113,9 +116,6 @@ PunctEditor::processKeyEvent (guint keyval, guint keycode, guint modifiers) IBUS_META_MASK | IBUS_LOCK_MASK); - if (processPunct(keyval,keycode,modifiers) == TRUE) - return TRUE; - switch (keyval) { case IBUS_space: return processSpace (keyval, keycode, modifiers); @@ -175,7 +175,7 @@ PunctEditor::processKeyEvent (guint keyval, guint keycode, guint modifiers) pageDown (); return TRUE; default: - return Editor::processKeyEvent (keyval, keycode, modifiers); + return processPunct(keyval, keycode, modifiers); } } -- cgit From 90bb72d5cea0f36397d477251e89ef7e6f627ddc Mon Sep 17 00:00:00 2001 From: Peng Huang Date: Mon, 17 May 2010 09:53:55 +0800 Subject: Reset PunctEditor when press Esc --- src/PunctEditor.cc | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/PunctEditor.cc') diff --git a/src/PunctEditor.cc b/src/PunctEditor.cc index d73b990..02958df 100644 --- a/src/PunctEditor.cc +++ b/src/PunctEditor.cc @@ -125,6 +125,10 @@ PunctEditor::processKeyEvent (guint keyval, guint keycode, guint modifiers) commit (); return TRUE; + case IBUS_Escape: + reset (); + return TRUE; + case IBUS_BackSpace: removeCharBefore (); return TRUE; -- cgit