summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeng Huang <shawn.p.huang@gmail.com>2010-02-07 13:25:35 +0800
committerPeng Huang <shawn.p.huang@gmail.com>2010-02-10 11:18:02 +0800
commita6ec9cf51f8ddcf3f295ebe8f74b1c3a53248fae (patch)
tree4caa0e549bd1827da503af9ff490ab2709eb73f0
parentefa0c8f199b0e058b3cc5f88f0d6e20c382570b3 (diff)
downloadibus-libpinyin-a6ec9cf51f8ddcf3f295ebe8f74b1c3a53248fae.tar.gz
ibus-libpinyin-a6ec9cf51f8ddcf3f295ebe8f74b1c3a53248fae.tar.xz
ibus-libpinyin-a6ec9cf51f8ddcf3f295ebe8f74b1c3a53248fae.zip
Refactory classes, and use sigc++ to make code clear.
-rw-r--r--configure.ac5
-rw-r--r--src/DoublePinyinEditor.cc39
-rw-r--r--src/DoublePinyinEditor.h4
-rw-r--r--src/Editor.cc136
-rw-r--r--src/Editor.h106
-rw-r--r--src/FullPinyinEditor.cc39
-rw-r--r--src/FullPinyinEditor.h13
-rw-r--r--src/Makefile.am28
-rw-r--r--src/PhraseEditor.cc30
-rw-r--r--src/PhraseEditor.h17
-rw-r--r--src/PinyinArray.h2
-rw-r--r--src/PinyinEditor.cc566
-rw-r--r--src/PinyinEditor.h58
-rw-r--r--src/PinyinEngine.cc1133
-rw-r--r--src/PinyinEngine.h67
-rw-r--r--src/PinyinProperties.cc152
-rw-r--r--src/PinyinProperties.h58
-rw-r--r--src/RawEditor.h76
-rw-r--r--src/Text.h1
19 files changed, 1428 insertions, 1102 deletions
diff --git a/configure.ac b/configure.ac
index 6825d8a..af39dfd 100644
--- a/configure.ac
+++ b/configure.ac
@@ -65,6 +65,11 @@ PKG_CHECK_MODULES(UUID, [
uuid
])
+# check uuid
+PKG_CHECK_MODULES(SIGC, [
+ sigc++-2.0
+])
+
# check env
AC_PATH_PROG(ENV, env)
AC_SUBST(ENV)
diff --git a/src/DoublePinyinEditor.cc b/src/DoublePinyinEditor.cc
index 1bbfff1..6970815 100644
--- a/src/DoublePinyinEditor.cc
+++ b/src/DoublePinyinEditor.cc
@@ -5,7 +5,8 @@ namespace PY {
#include "DoublePinyinTable.h"
-DoublePinyinEditor::DoublePinyinEditor (void)
+DoublePinyinEditor::DoublePinyinEditor (PinyinProperties & props)
+ : PinyinEditor (props)
{
}
@@ -46,19 +47,19 @@ gboolean
DoublePinyinEditor::insert (gint ch)
{
/* is full */
- if (G_UNLIKELY (m_text.length () >= MAX_PINYIN_LEN))
+ if (G_UNLIKELY (m_buffer.length () >= MAX_PINYIN_LEN))
return FALSE;
gint id = char_to_id (ch);
if (id < 0)
return FALSE;
- m_text.insert (m_cursor++, ch);
+ m_buffer.insert (m_cursor++, ch);
if (m_cursor != m_pinyin_len + 2)
return TRUE;
- const Pinyin *pinyin = isPinyin (m_text[m_cursor - 2], ch);
+ const Pinyin *pinyin = isPinyin (m_buffer[m_cursor - 2], ch);
if (pinyin == NULL)
return TRUE;
m_pinyin.append (pinyin, m_pinyin_len, 2);
@@ -73,7 +74,7 @@ DoublePinyinEditor::removeCharBefore (void)
return FALSE;
m_cursor --;
- m_text.erase (m_cursor, 1);
+ m_buffer.erase (m_cursor, 1);
if (m_cursor < m_pinyin_len) {
m_pinyin.pop ();
@@ -86,10 +87,10 @@ DoublePinyinEditor::removeCharBefore (void)
gboolean
DoublePinyinEditor::removeCharAfter (void)
{
- if (G_UNLIKELY (m_cursor == m_text.length ()))
+ if (G_UNLIKELY (m_cursor == m_buffer.length ()))
return FALSE;
- m_text.erase (m_cursor, 1);
+ m_buffer.erase (m_cursor, 1);
return TRUE;
}
@@ -111,7 +112,7 @@ DoublePinyinEditor::removeWordBefore (void)
m_pinyin_len -= 2;
}
- m_text.erase (cursor, m_cursor - cursor);
+ m_buffer.erase (cursor, m_cursor - cursor);
m_cursor = cursor;
return TRUE;
}
@@ -119,10 +120,10 @@ DoublePinyinEditor::removeWordBefore (void)
gboolean
DoublePinyinEditor::removeWordAfter (void)
{
- if (G_UNLIKELY (m_cursor == m_text.length ()))
+ if (G_UNLIKELY (m_cursor == m_buffer.length ()))
return FALSE;
- m_text.erase (m_cursor, -1);
+ m_buffer.erase (m_cursor, -1);
return TRUE;
}
@@ -144,7 +145,7 @@ DoublePinyinEditor::moveCursorLeft (void)
gboolean
DoublePinyinEditor::moveCursorRight (void)
{
- if (G_UNLIKELY (m_cursor == m_text.length ()))
+ if (G_UNLIKELY (m_cursor == m_buffer.length ()))
return FALSE;
m_cursor ++;
@@ -192,16 +193,16 @@ DoublePinyinEditor::moveCursorToBegin (void)
gboolean
DoublePinyinEditor::moveCursorToEnd (void)
{
- if (G_UNLIKELY (m_cursor == m_text.length ()))
+ if (G_UNLIKELY (m_cursor == m_buffer.length ()))
return FALSE;
- m_cursor = m_text.length ();
+ m_cursor = m_buffer.length ();
updatePinyin ();
return TRUE;
}
-gboolean
+void
DoublePinyinEditor::reset (void)
{
gboolean retval = FALSE;
@@ -210,22 +211,20 @@ DoublePinyinEditor::reset (void)
retval = TRUE;
}
- if (m_text.length () != 0) {
- m_text.truncate (0);
+ if (m_buffer.length () != 0) {
+ m_buffer.truncate (0);
retval = TRUE;
}
if (retval)
updatePinyin ();
-
- return retval;
}
void
DoublePinyinEditor::updatePinyin (void)
{
- if (G_UNLIKELY (m_text.isEmpty ())) {
+ if (G_UNLIKELY (m_buffer.isEmpty ())) {
m_pinyin.removeAll ();
m_pinyin_len = 0;
return;
@@ -234,7 +233,7 @@ DoublePinyinEditor::updatePinyin (void)
m_pinyin.removeAll ();
m_pinyin_len = 0;
for (guint i = 0; i + 1 < m_cursor; i+= 2) {
- const Pinyin *pinyin = isPinyin (m_text[i], m_text[i + 1]);
+ const Pinyin *pinyin = isPinyin (m_buffer[i], m_buffer[i + 1]);
if (pinyin == NULL)
break;
m_pinyin.append (pinyin, m_pinyin_len, 2);
diff --git a/src/DoublePinyinEditor.h b/src/DoublePinyinEditor.h
index 75d419a..69cd980 100644
--- a/src/DoublePinyinEditor.h
+++ b/src/DoublePinyinEditor.h
@@ -8,7 +8,7 @@ namespace PY {
class DoublePinyinEditor : public PinyinEditor {
public:
- DoublePinyinEditor (void);
+ DoublePinyinEditor (PinyinProperties & props);
gboolean insert (gint ch);
@@ -24,7 +24,7 @@ public:
gboolean moveCursorToBegin (void);
gboolean moveCursorToEnd (void);
- gboolean reset (void);
+ void reset (void);
private:
void updatePinyin (void);
const Pinyin *isPinyin (gchar i, gchar j);
diff --git a/src/Editor.cc b/src/Editor.cc
new file mode 100644
index 0000000..86aae8c
--- /dev/null
+++ b/src/Editor.cc
@@ -0,0 +1,136 @@
+#include "Editor.h"
+
+namespace PY {
+
+Editor::Editor (PinyinProperties & props)
+ : m_text (128),
+ m_cursor (0),
+ m_props (props)
+{
+}
+
+Editor::~Editor (void)
+{
+}
+
+gboolean
+Editor::processKeyEvent (guint keyval, guint keycode, guint modifiers)
+{
+ /* ignore release key events */
+ if (modifiers & IBUS_RELEASE_MASK)
+ return FALSE;
+
+ modifiers &= (IBUS_SHIFT_MASK |
+ IBUS_CONTROL_MASK |
+ IBUS_MOD1_MASK |
+ IBUS_SUPER_MASK |
+ IBUS_HYPER_MASK |
+ IBUS_META_MASK);
+ /* ignore key events with some masks */
+ if (modifiers != 0)
+ return TRUE;
+
+ if (keyval >= IBUS_exclam && keyval <= IBUS_asciitilde) {
+ /* char key */
+ m_text.insert (m_cursor++, keyval);
+ update ();
+ return TRUE;
+ }
+ else {
+ /* control key */
+ if (!m_text)
+ return FALSE;
+ }
+
+ switch (keyval) {
+ case IBUS_BackSpace:
+ if (m_cursor > 0) {
+ m_text.erase (--m_cursor, 1);
+ update ();
+ }
+ return TRUE;
+ case IBUS_Delete:
+ case IBUS_KP_Delete:
+ if (m_cursor < m_text.length ()) {
+ m_text.erase (m_cursor, 1);
+ update ();
+ }
+ return TRUE;
+ case IBUS_Left:
+ case IBUS_KP_Left:
+ if (!m_text)
+ return FALSE;
+ if (m_cursor > 0) {
+ m_cursor --;
+ update ();
+ }
+ return TRUE;
+ case IBUS_Right:
+ case IBUS_KP_Right:
+ if (m_cursor < m_text.length ()) {
+ m_cursor ++;
+ update ();
+ }
+ return TRUE;
+ case IBUS_Return:
+ case IBUS_KP_Enter:
+ {
+ StaticText text (m_text);
+ commitText (text);
+ reset ();
+ }
+ return TRUE;
+ case IBUS_Escape:
+ reset ();
+ return TRUE;
+ default:
+ g_debug ("Unknown keyval %d", keyval);
+ return TRUE;
+ }
+}
+
+void
+Editor::reset (void)
+{
+ gboolean need_update = (m_cursor != 0 || m_text);
+ m_cursor = 0;
+ m_text = "";
+ if (need_update)
+ update ();
+}
+
+void
+Editor::pageUp (void)
+{
+}
+
+void
+Editor::pageDown (void)
+{
+}
+
+void
+Editor::cursorUp (void)
+{
+}
+
+void
+Editor::cursorDown (void)
+{
+}
+
+void
+Editor::update (void)
+{
+ if (m_text) {
+ StaticText text (m_text);
+ text.appendAttribute (IBUS_ATTR_TYPE_UNDERLINE, IBUS_ATTR_UNDERLINE_SINGLE, 0, -1);
+ updatePreeditText (text, m_cursor, TRUE);
+ }
+ else {
+ hidePreeditText ();
+ }
+}
+
+};
+
diff --git a/src/Editor.h b/src/Editor.h
new file mode 100644
index 0000000..205cba7
--- /dev/null
+++ b/src/Editor.h
@@ -0,0 +1,106 @@
+#ifndef __PY_EDITOR_H_
+#define __PY_EDITOR_H_
+
+#include <glib.h>
+#include <sigc++/sigc++.h>
+#include "Text.h"
+#include "LookupTable.h"
+#include "PinyinProperties.h"
+
+namespace PY {
+
+class Editor {
+public:
+ Editor (PinyinProperties & prop);
+ virtual ~Editor (void);
+
+ 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);
+
+ /* signals */
+ sigc::signal <void, Text &> signalCommitText (void) { return m_signal_commit_text; }
+ sigc::signal <void, Text &, guint, gboolean> signalUpdatePreeditText (void) { return m_signal_update_preedit_text; }
+ sigc::signal <void> signalShowPreeditText (void) { return m_signal_show_preedit_text; }
+ sigc::signal <void> signalHidePreeditText (void) { return m_signal_hide_preedit_text; }
+ sigc::signal <void, Text &, gboolean> signalUpdateAuxiliaryText (void) { return m_signal_update_auxiliary_text; }
+ sigc::signal <void> signalShowAuxiliaryText (void) { return m_signal_show_auxiliary_text; }
+ sigc::signal <void> signalHideAuxiliaryText (void) { return m_signal_hide_auxiliary_text; }
+ sigc::signal <void, LookupTable &, gboolean> signalUpdateLookupTable (void) { return m_signal_update_lookup_table; }
+ sigc::signal <void, LookupTable &, gboolean> signalUpdateLookupTableFast (void) { return m_signal_update_lookup_table_fast; }
+ sigc::signal <void> signalShowLookupTable (void) { return m_signal_show_lookup_table; }
+ sigc::signal <void> signalHideLookupTable (void) { return m_signal_hide_lookup_table; }
+
+protected:
+ /* methods */
+ void commitText (Text & text) {
+ m_signal_commit_text.emit (text);
+ }
+
+ void updatePreeditText (Text & text, guint cursor, gboolean visible) {
+ m_signal_update_preedit_text.emit (text, cursor, visible);
+ }
+
+ void showPreeditText (void) {
+ m_signal_show_preedit_text.emit ();
+ }
+
+ void hidePreeditText (void) {
+ m_signal_hide_preedit_text.emit ();
+ }
+
+ void updateAuxiliaryText (Text & text, gboolean visible) {
+ m_signal_update_auxiliary_text.emit (text, visible);
+ }
+
+ void showAuxiliaryText (void) {
+ m_signal_show_auxiliary_text.emit ();
+ }
+
+ void hideAuxiliaryText (void) {
+ m_signal_hide_auxiliary_text.emit ();
+ }
+
+ void updateLookupTable (LookupTable & table, gboolean visible) {
+ m_signal_update_lookup_table.emit (table, visible);
+ }
+
+ void updateLookupTableFast (LookupTable & table, gboolean visible) {
+ m_signal_update_lookup_table_fast.emit (table, visible);
+ }
+
+ void showLookupTable (void) {
+ m_signal_show_lookup_table.emit ();
+ }
+
+ void hideLookupTable (void) {
+ m_signal_hide_lookup_table.emit ();
+ }
+
+protected:
+ /* signals */
+ sigc::signal <void, Text &> m_signal_commit_text;
+ sigc::signal <void, Text &, guint, gboolean> m_signal_update_preedit_text;
+ sigc::signal <void> m_signal_show_preedit_text;
+ sigc::signal <void> m_signal_hide_preedit_text;
+ sigc::signal <void, Text &, gboolean> m_signal_update_auxiliary_text;
+ sigc::signal <void> m_signal_show_auxiliary_text;
+ sigc::signal <void> m_signal_hide_auxiliary_text;
+ sigc::signal <void, LookupTable &, gboolean> m_signal_update_lookup_table;
+ sigc::signal <void, LookupTable &, gboolean> m_signal_update_lookup_table_fast;
+ sigc::signal <void> m_signal_show_lookup_table;
+ sigc::signal <void> m_signal_hide_lookup_table;
+
+protected:
+ String m_text;
+ guint m_cursor;
+ PinyinProperties & m_props;
+};
+
+};
+
+#endif
diff --git a/src/FullPinyinEditor.cc b/src/FullPinyinEditor.cc
index f1de074..ede35a9 100644
--- a/src/FullPinyinEditor.cc
+++ b/src/FullPinyinEditor.cc
@@ -3,12 +3,16 @@
namespace PY {
+FullPinyinEditor::FullPinyinEditor (PinyinProperties & props)
+ : PinyinEditor (props)
+{
+}
-FullPinyinEditor::FullPinyinEditor (void)
+FullPinyinEditor::~FullPinyinEditor (void)
{
}
-gboolean
+void
FullPinyinEditor::reset (void)
{
gboolean retval = FALSE;
@@ -22,10 +26,10 @@ FullPinyinEditor::reset (void)
retval = TRUE;
}
- if (retval)
+ if (retval) {
updatePinyin ();
-
- return retval;
+ update ();
+ }
}
gboolean
@@ -47,6 +51,7 @@ FullPinyinEditor::insert (gint ch)
updatePinyin ();
}
}
+ update ();
return TRUE;
}
@@ -60,6 +65,7 @@ FullPinyinEditor::removeCharBefore (void)
m_text.erase (m_cursor, 1);
updatePinyin ();
+ update ();
return TRUE;
}
@@ -71,6 +77,7 @@ FullPinyinEditor::removeCharAfter (void)
return FALSE;
m_text.erase (m_cursor, 1);
+ update ();
return TRUE;
}
@@ -95,6 +102,8 @@ FullPinyinEditor::removeWordBefore (void)
m_text.erase (cursor, m_cursor - cursor);
m_cursor = cursor;
+ updatePhraseEditor ();
+ update ();
return TRUE;
}
@@ -105,6 +114,7 @@ FullPinyinEditor::removeWordAfter (void)
return FALSE;
m_text.erase (m_cursor, -1);
+ update ();
return TRUE;
}
@@ -116,7 +126,7 @@ FullPinyinEditor::moveCursorLeft (void)
m_cursor --;
updatePinyin ();
-
+ update ();
return TRUE;
}
@@ -128,6 +138,7 @@ FullPinyinEditor::moveCursorRight (void)
m_cursor ++;
updatePinyin ();
+ update ();
return TRUE;
}
@@ -147,6 +158,8 @@ FullPinyinEditor::moveCursorLeftByWord (void)
m_cursor -= p.len;
m_pinyin_len -= p.len;
m_pinyin.pop ();
+ updatePhraseEditor ();
+ update ();
return TRUE;
}
@@ -166,6 +179,8 @@ FullPinyinEditor::moveCursorToBegin (void)
m_cursor = 0;
m_pinyin.removeAll ();
m_pinyin_len = 0;
+ updatePhraseEditor ();
+ update ();
return TRUE;
}
@@ -178,6 +193,7 @@ FullPinyinEditor::moveCursorToEnd (void)
m_cursor = m_text.length ();
updatePinyin ();
+ update ();
return TRUE;
}
@@ -196,8 +212,15 @@ FullPinyinEditor::updatePinyin (void)
m_pinyin, // result
MAX_PHRASE_LEN); // max result length
}
-}
-};
+ updatePhraseEditor ();
+}
+#if 0
+gboolean
+FullPinyinEditor::processKeyEvent (guint keyval, guint keycode, guint modifiers)
+{
+}
+#endif
+};
diff --git a/src/FullPinyinEditor.h b/src/FullPinyinEditor.h
index 81e6e1f..9e95fa8 100644
--- a/src/FullPinyinEditor.h
+++ b/src/FullPinyinEditor.h
@@ -8,8 +8,17 @@ namespace PY {
class FullPinyinEditor : public PinyinEditor {
public:
- FullPinyinEditor (void);
+ FullPinyinEditor (PinyinProperties & props);
+ ~FullPinyinEditor (void);
+public:
+ /* virtual functions */
+#if 0
+ virtual gboolean processKeyEvent (guint keyval, guint keycode, guint modifiers);
+#endif
+ virtual void reset (void);
+
+protected:
gboolean insert (gint ch);
gboolean removeCharBefore (void);
@@ -24,8 +33,6 @@ public:
gboolean moveCursorToBegin (void);
gboolean moveCursorToEnd (void);
- gboolean reset (void);
-
private:
void updatePinyin (void);
diff --git a/src/Makefile.am b/src/Makefile.am
index dfcc153..08f578c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -20,17 +20,17 @@
# @MAINTAINER_MODE_FALSE@skip_gentable=test -f $@ ||
-AM_CFLAGS = \
- @IBUS_CFLAGS@ \
- @SQLITE_CFLAGS@ \
- -DPKGDATADIR=\"$(pkgdatadir)\" \
- $(NULL)
-AM_LDADD = \
- @IBUS_LIBS@ \
- @SQLITE_LIBS@ \
- $(NULL)
-
-AM_CXXFLAGS = $(AM_CFLAGS)
+# AM_CFLAGS = \
+# @IBUS_CFLAGS@ \
+# @SQLITE_CFLAGS@ \
+# -DPKGDATADIR=\"$(pkgdatadir)\" \
+# $(NULL)
+# AM_CXXFLAGS = $(AM_CFLAGS)
+# AM_LDADD = \
+# @IBUS_LIBS@ \
+# @SQLITE_LIBS@ \
+# $(NULL)
+#
libexec_PROGRAMS = ibus-engine-pinyin
ibus_engine_c_sources = \
@@ -38,6 +38,7 @@ ibus_engine_c_sources = \
CustomPhrase.cc \
Database.cc \
DoublePinyinEditor.cc \
+ Editor.cc \
Engine.cc \
FullPinyinEditor.cc \
HalfFullConverter.cc \
@@ -46,6 +47,7 @@ ibus_engine_c_sources = \
PinyinEditor.cc \
PinyinEngine.cc \
PinyinParser.cc \
+ PinyinProperties.cc \
SimpTradConverter.cc \
SpecialTable.cc \
$(NULL)
@@ -61,6 +63,7 @@ ibus_engine_h_sources = \
Database.h \
DoublePinyinEditor.h \
DoublePinyinTable.h \
+ Editor.h \
Engine.h \
FullPinyinEditor.h \
HalfFullConverter.h \
@@ -74,6 +77,7 @@ ibus_engine_h_sources = \
PinyinEngine.h \
PinyinParser.h \
PinyinParserTable.h \
+ PinyinProperties.h \
Pointer.h \
RawEditor.h \
Regex.h \
@@ -97,6 +101,7 @@ ibus_engine_pinyin_CXXFLAGS = \
@IBUS_CFLAGS@ \
@SQLITE_CFLAGS@ \
@UUID_CFLAGS@ \
+ @SIGC_CFLAGS@ \
-DGETTEXT_PACKAGE=\"@GETTEXT_PACKAGE@\" \
-DPKGDATADIR=\"$(pkgdatadir)\" \
-DLIBEXECDIR=\"$(libexecdir)\" \
@@ -105,6 +110,7 @@ ibus_engine_pinyin_LDADD = \
@IBUS_LIBS@ \
@SQLITE_LIBS@ \
@UUID_LIBS@ \
+ @SIGC_LIBS@ \
$(NULL)
BUILT_SOURCES = \
diff --git a/src/PhraseEditor.cc b/src/PhraseEditor.cc
index 6248ab5..81bf249 100644
--- a/src/PhraseEditor.cc
+++ b/src/PhraseEditor.cc
@@ -4,17 +4,16 @@
namespace PY {
-/* init static members */
Database PhraseEditor::m_database;
-PhraseEditor::PhraseEditor (void)
+PhraseEditor::PhraseEditor (PinyinProperties & props)
: m_candidates (32),
m_selected_phrases (8),
m_selected_string (32),
m_candidate_0_phrases (8),
m_pinyin (16),
m_cursor (0),
- m_mode_simp (Config::initSimpChinese ())
+ m_props (props)
{
}
@@ -22,12 +21,12 @@ PhraseEditor::~PhraseEditor (void)
{
}
-void
+gboolean
PhraseEditor::update (const PinyinArray &pinyin)
{
/* the length of pinyin must not bigger than MAX_PHRASE_LEN */
g_assert (pinyin.length () <= MAX_PHRASE_LEN);
-
+#if 0
gboolean diff = FALSE;
if (m_cursor > pinyin.length ()) {
@@ -42,16 +41,19 @@ PhraseEditor::update (const PinyinArray &pinyin)
}
}
- m_pinyin = pinyin;
-
- if (diff) {
- /* FIXME, should not remove all phrases1 */
- m_selected_phrases.removeAll ();
- m_selected_string.truncate (0);
- m_cursor = 0;
+ if (diff == FALSE){
+ return FALSE;
}
+#endif
+
+ m_pinyin = pinyin;
+ m_cursor = 0;
+ /* FIXME, should not remove all phrases1 */
+ m_selected_phrases.removeAll ();
+ m_selected_string.truncate (0);
updateCandidates ();
+ return TRUE;
}
gboolean
@@ -71,7 +73,7 @@ PhraseEditor::selectCandidate (guint i)
if (G_LIKELY (i == 0)) {
m_selected_phrases << m_candidate_0_phrases;
- if (G_LIKELY (m_mode_simp))
+ if (G_LIKELY (m_props.modeSimp ()))
m_selected_string << m_candidates[0].phrase;
else
SimpTradConverter::simpToTrad (m_candidates[0].phrase, m_selected_string);
@@ -79,7 +81,7 @@ PhraseEditor::selectCandidate (guint i)
}
else {
m_selected_phrases << m_candidates[i];
- if (G_LIKELY (m_mode_simp))
+ if (G_LIKELY (m_props.modeSimp ()))
m_selected_string << m_candidates[i].phrase;
else
SimpTradConverter::simpToTrad (m_candidates[i].phrase, m_selected_string);
diff --git a/src/PhraseEditor.h b/src/PhraseEditor.h
index b7051c0..313d408 100644
--- a/src/PhraseEditor.h
+++ b/src/PhraseEditor.h
@@ -4,13 +4,14 @@
#include "String.h"
#include "Database.h"
#include "PhraseArray.h"
+#include "PinyinProperties.h"
namespace PY {
class PhraseEditor {
public:
- PhraseEditor(void);
- ~PhraseEditor(void);
+ PhraseEditor (PinyinProperties & props);
+ ~PhraseEditor (void);
const String & selectedString (void) const { return m_selected_string; }
const PinyinArray & pinyin (void) const { return m_pinyin; }
@@ -41,15 +42,7 @@ public:
m_cursor = 0;
}
- gboolean modeSimp (void) const {
- return m_mode_simp;
- }
-
- void setModeSimp (gboolean mode) {
- m_mode_simp = mode;
- }
-
- void update (const PinyinArray &pinyin);
+ gboolean update (const PinyinArray &pinyin);
gboolean selectCandidate (guint i);
gboolean resetCandidate (guint i);
void commit (void) {
@@ -77,7 +70,7 @@ private:
PhraseArray m_candidate_0_phrases; // the first candidate in phrase array format
PinyinArray m_pinyin;
guint m_cursor;
- gboolean m_mode_simp;
+ PinyinProperties & m_props;
private:
static Database m_database;
diff --git a/src/PinyinArray.h b/src/PinyinArray.h
index a3c1bba..c02c5d6 100644
--- a/src/PinyinArray.h
+++ b/src/PinyinArray.h
@@ -33,7 +33,7 @@ struct PinyinSegment {
class PinyinArray: public Array<PinyinSegment> {
public:
- PinyinArray (guint init_size) : Array<PinyinSegment> (init_size) {}
+ PinyinArray (guint init_size = 0) : Array<PinyinSegment> (init_size) {}
void append (const Pinyin *pinyin, guint begin, guint len) {
push_back (PinyinSegment (pinyin, begin, len));
}
diff --git a/src/PinyinEditor.cc b/src/PinyinEditor.cc
index fd4760c..3992db8 100644
--- a/src/PinyinEditor.cc
+++ b/src/PinyinEditor.cc
@@ -1,19 +1,573 @@
#include "Config.h"
#include "PinyinEditor.h"
+#include "SimpTradConverter.h"
+#include "HalfFullConverter.h"
namespace PY {
#define MAX_PINYIN_LEN 64
-
+/* init static members */
PinyinParser PinyinEditor::m_parser;
-PinyinEditor::PinyinEditor (void)
- : m_text (MAX_PINYIN_LEN),
- m_cursor (0),
- m_pinyin (MAX_PHRASE_LEN),
- m_pinyin_len (0)
+PinyinEditor::PinyinEditor (PinyinProperties & props)
+ : m_pinyin (MAX_PHRASE_LEN),
+ m_pinyin_len (0),
+ m_buffer (64),
+ m_lookup_table (Config::pageSize ()),
+ m_phrase_editor (props),
+ Editor (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))
+ return m_text ? TRUE : FALSE;
+
+ insert (keyval);
+ return TRUE;
+}
+
+/**
+ * process numbers
+ */
+inline gboolean
+PinyinEditor::processNumber (guint keyval, guint keycode, guint modifiers)
+{
+ guint i;
+
+ if (!m_text)
+ return FALSE;
+
+ switch (keyval) {
+ case IBUS_0:
+ case IBUS_KP_0:
+ i = 9;
+ break;
+ case IBUS_1 ... IBUS_9:
+ i = keyval - IBUS_1;
+ break;
+ case IBUS_KP_1 ... IBUS_KP_9:
+ i = keyval - IBUS_KP_1;
+ break;
+ default:
+ g_return_val_if_reached (FALSE);
+ }
+ if (modifiers == 0)
+ selectCandidateInPage (i);
+ else if ((modifiers & ~ IBUS_LOCK_MASK) == IBUS_CONTROL_MASK)
+ resetCandidateInPage (i);
+ return TRUE;
+}
+
+inline gboolean
+PinyinEditor::processSpace (guint keyval, guint keycode, guint modifiers)
+{
+ if (!m_text)
+ return FALSE;
+ if (CMSHM_FILTER (modifiers) != 0)
+ return TRUE;
+
+ if (m_phrase_editor.pinyinExistsAfterCursor ()) {
+ selectCandidate (m_lookup_table.cursorPos ());
+ }
+ else {
+ commit ();
+ }
+ return TRUE;
+}
+
+inline gboolean
+PinyinEditor::processPunct (guint keyval, guint keycode, guint modifiers)
+{
+ return TRUE;
+}
+
+inline gboolean
+PinyinEditor::processOthers (guint keyval, guint keycode, guint modifiers)
{
+ if (m_text.isEmpty ())
+ return FALSE;
+
+ /* ignore numlock */
+ modifiers = CMSHM_FILTER (modifiers);
+
+ if (modifiers != 0 && modifiers != IBUS_CONTROL_MASK)
+ return TRUE;
+
+
+ /* process some cursor control keys */
+ gboolean _update = FALSE;
+ if (modifiers == 0) {
+ switch (keyval) {
+ case IBUS_Shift_L:
+ if (Config::shiftSelectCandidate ()) {
+ selectCandidateInPage (1);
+ }
+ break;
+
+ case IBUS_Shift_R:
+ if (Config::shiftSelectCandidate ()) {
+ selectCandidateInPage (2);
+ }
+ break;
+
+ case IBUS_Return:
+ case IBUS_KP_Enter:
+ commit ();
+ break;
+
+ case IBUS_BackSpace:
+ removeCharBefore ();
+ break;
+
+ case IBUS_Delete:
+ case IBUS_KP_Delete:
+ removeCharAfter ();
+ break;
+
+ case IBUS_Left:
+ case IBUS_KP_Left:
+ moveCursorLeft ();
+ break;
+
+ case IBUS_Right:
+ case IBUS_KP_Right:
+ moveCursorRight ();
+ break;
+
+ case IBUS_Home:
+ case IBUS_KP_Home:
+ moveCursorToBegin ();
+ break;
+
+ case IBUS_End:
+ case IBUS_KP_End:
+ moveCursorToEnd ();
+ break;
+
+ case IBUS_Up:
+ case IBUS_KP_Up:
+ cursorUp (); break;
+
+ case IBUS_Down:
+ case IBUS_KP_Down:
+ cursorDown (); break;
+
+ case IBUS_Page_Up:
+ case IBUS_KP_Page_Up:
+ pageUp (); break;
+
+ case IBUS_Page_Down:
+ case IBUS_KP_Page_Down:
+ pageDown (); break;
+
+ case IBUS_Escape:
+ reset (); break;
+ default:
+ break;
+ }
+ }
+ else {
+ switch (keyval) {
+ case IBUS_BackSpace:
+ removeWordBefore ();
+ break;
+
+ case IBUS_Delete:
+ case IBUS_KP_Delete:
+ removeWordAfter ();
+ break;
+
+ case IBUS_Left:
+ case IBUS_KP_Left:
+ moveCursorLeftByWord ();
+ break;
+
+ case IBUS_Right:
+ case IBUS_KP_Right:
+ moveCursorToEnd ();
+ break;
+
+ default:
+ break;
+ };
+ }
+ return TRUE;
+}
+
+gboolean
+PinyinEditor::processKeyEvent (guint keyval, guint keycode, guint modifiers)
+{
+ gboolean result = FALSE;
+
+ if (modifiers & IBUS_RELEASE_MASK) {
+ return m_text.isEmpty () ? FALSE : TRUE;
+ }
+
+ modifiers &= (IBUS_SHIFT_MASK |
+ IBUS_CONTROL_MASK |
+ IBUS_MOD1_MASK |
+ IBUS_SUPER_MASK |
+ IBUS_HYPER_MASK |
+ IBUS_META_MASK |
+ IBUS_LOCK_MASK);
+
+ switch (keyval) {
+ /* letters */
+ case IBUS_a ... IBUS_z:
+ return processPinyin (keyval, keycode, modifiers);
+ case IBUS_0 ... IBUS_9:
+ case IBUS_KP_0 ... IBUS_KP_9:
+ return processNumber (keyval, keycode, modifiers);
+ /* space */
+ case IBUS_space:
+ return processSpace (keyval, keycode, modifiers);
+ /* others */
+ default:
+ return processOthers (keyval, keycode, modifiers);
+ }
+}
+
+void
+PinyinEditor::updatePreeditText (void)
+{
+ /* preedit text = selected phrases + highlight candidate + rest text */
+ if (G_UNLIKELY (m_phrase_editor.isEmpty () && m_text.isEmpty ())) {
+ hidePreeditText ();
+ return;
+ }
+
+ if (m_cursor == m_text.length ())
+ updatePreeditTextInTypingMode ();
+ else
+ updatePreeditTextInEditingMode ();
+}
+
+void
+PinyinEditor::updatePreeditTextInTypingMode (void)
+{
+ m_buffer.truncate (0);
+
+ /* add select phrases */
+ if (G_UNLIKELY (m_phrase_editor.selectedString ())) {
+ m_buffer << m_phrase_editor.selectedString ();
+ }
+
+ /* add highlight candidate */
+ guint candidate_begin = m_buffer.utf8Length ();
+ guint candidate_length = 0;
+ if (m_phrase_editor.candidates ().length () > 0) {
+ if (m_lookup_table.cursorPos () == 0 && !m_props.modeSimp ()) {
+ const PhraseArray & phrases = m_phrase_editor.candidate0 ();
+ candidate_length = 0;
+ for (guint i = 0; i < phrases.length (); i++) {
+ candidate_length += phrases[i].len;
+ SimpTradConverter::simpToTrad (phrases[i], m_buffer);
+ }
+ }
+ else {
+ const Phrase & candidate = m_phrase_editor.candidate (m_lookup_table.cursorPos ());
+ candidate_length = candidate.len;
+ if (m_props.modeSimp ())
+ m_buffer << candidate;
+ else
+ SimpTradConverter::simpToTrad (candidate, m_buffer);
+ }
+ }
+
+ /* add rest text */
+ const PinyinArray & pinyin = m_phrase_editor.pinyin ();
+ if (candidate_begin + candidate_length < pinyin.length ())
+ m_buffer << ((const gchar *) textAfterPinyin (
+ candidate_begin + candidate_length));
+ else
+ m_buffer << ((const gchar *) textAfterPinyin ());
+
+ StaticText preedit_text (m_buffer);
+ /* underline */
+ preedit_text.appendAttribute (IBUS_ATTR_TYPE_UNDERLINE, IBUS_ATTR_UNDERLINE_SINGLE, 0, -1);
+
+ /* candidate */
+ if (candidate_length != 0) {
+ preedit_text.appendAttribute (IBUS_ATTR_TYPE_FOREGROUND, 0x00000000,
+ candidate_begin, candidate_begin + candidate_length);
+ preedit_text.appendAttribute (IBUS_ATTR_TYPE_BACKGROUND, 0x00c8c8f0,
+ candidate_begin, candidate_begin + candidate_length);
+ }
+ // ibus_engine_update_preedit_text (m_engine, preedit_text, m_buffer.utf8Length (), TRUE);
+ Editor::updatePreeditText (preedit_text, candidate_begin, TRUE);
+}
+
+void
+PinyinEditor::updatePreeditTextInEditingMode (void)
+{
+ m_buffer.truncate (0);
+
+ /* add select phrases */
+ if (G_UNLIKELY (m_phrase_editor.selectedString ())) {
+ m_buffer << m_phrase_editor.selectedString ();
+ }
+
+ /* add highlight candidate */
+ const PinyinArray & pinyin = m_phrase_editor.pinyin ();
+ guint candidate_begin = m_buffer.utf8Length ();
+ guint candidate_length = 0;
+ guint candidate_pinyin_end = 0;
+ if (m_phrase_editor.candidates ().length () > 0) {
+ const Phrase & candidate = m_phrase_editor.candidate (m_lookup_table.cursorPos ());
+ candidate_length = candidate.len;
+
+ m_buffer << pinyin[candidate_begin]->sheng << pinyin[candidate_begin]->yun;
+
+ for (guint i = 1; i < candidate_length; i++) {
+ m_buffer << ' ' << pinyin[candidate_begin + i]->sheng << pinyin[candidate_begin + i]->yun;
+ }
+ candidate_pinyin_end = m_buffer.utf8Length ();
+ }
+
+ /* add rest text */
+ if (candidate_begin + candidate_length < pinyin.length ()) {
+ if (m_buffer)
+ m_buffer << ' ' ;
+ m_buffer << textAfterPinyin (candidate_begin + candidate_length);
+ }
+ else {
+ const gchar * p = textAfterPinyin ();
+ if (*p != '\0') {
+ if (m_buffer)
+ m_buffer << ' ';
+ m_buffer << p;
+ }
+ }
+
+ StaticText preedit_text (m_buffer);
+ /* underline */
+ preedit_text.appendAttribute (IBUS_ATTR_TYPE_UNDERLINE, IBUS_ATTR_UNDERLINE_SINGLE, 0, -1);
+
+ /* candidate */
+ if (candidate_length != 0) {
+ preedit_text.appendAttribute (IBUS_ATTR_TYPE_FOREGROUND, 0x00000000,
+ candidate_begin, candidate_pinyin_end);
+ preedit_text.appendAttribute (IBUS_ATTR_TYPE_BACKGROUND, 0x00c8c8f0,
+ candidate_begin, candidate_pinyin_end);
+ }
+ // ibus_engine_update_preedit_text (m_engine, preedit_text, m_buffer.utf8Length (), TRUE);
+ Editor::updatePreeditText (preedit_text, candidate_begin, TRUE);
+}
+
+void
+PinyinEditor::updateAuxiliaryText (void)
+{
+ /* clear pinyin array */
+ if (G_UNLIKELY (m_text.isEmpty () ||
+ m_cursor == m_pinyin.length ())) {
+ hideAuxiliaryText ();
+ return;
+ }
+
+ // guint cursor_pos;
+ m_buffer.truncate (0);
+ for (guint i = m_phrase_editor.cursor (); i < m_pinyin.length (); ++i) {
+ if (G_LIKELY (i != m_phrase_editor.cursor ()))
+ m_buffer << ' ';
+ const Pinyin *p = m_pinyin[i];
+ m_buffer << p->sheng;
+ m_buffer << p->yun;
+ }
+
+ if (G_UNLIKELY (m_pinyin_len == m_cursor)) {
+ /* aux = pinyin + non-pinyin */
+ // cursor_pos = m_buffer.utf8Length ();
+ m_buffer << '|' << textAfterPinyin ();
+ }
+ else {
+ /* aux = pinyin + non-pinyin before cursor + non-pinyin after cursor */
+ m_buffer.append (textAfterPinyin (),
+ m_cursor - m_pinyin_len);
+ // cursor_pos = m_buffer.utf8Length ();
+ m_buffer << '|' << textAfterCursor ();
+ }
+
+ StaticText aux_text (m_buffer);
+ Editor::updateAuxiliaryText (aux_text, TRUE);
+}
+
+void
+PinyinEditor::updateLookupTable (void)
+{
+ m_lookup_table.clear ();
+ m_lookup_table.setPageSize (Config::pageSize ());
+
+ guint candidate_nr = m_phrase_editor.candidates ().length ();
+
+ if (G_UNLIKELY (candidate_nr == 0)) {
+ hideLookupTable ();
+ return;
+ }
+
+ if (G_LIKELY (m_props.modeSimp () || !Config::tradCandidate ())) {
+ for (guint i = 0; i < candidate_nr; i++) {
+ StaticText text (m_phrase_editor.candidate (i));
+ if (m_phrase_editor.candidateIsUserPhease (i))
+ text.appendAttribute (IBUS_ATTR_TYPE_FOREGROUND, 0x000000ef, 0, -1);
+ m_lookup_table.appendCandidate (text);
+ }
+ }
+ else {
+ for (guint i = 0; i < candidate_nr; i++) {
+ m_buffer.truncate (0);
+ SimpTradConverter::simpToTrad (m_phrase_editor.candidate (i), m_buffer);
+ Text text (m_buffer);
+ if (m_phrase_editor.candidateIsUserPhease (i))
+ text.appendAttribute (IBUS_ATTR_TYPE_FOREGROUND, 0x000000ef, 0, -1);
+ m_lookup_table.appendCandidate (text);
+ }
+ }
+
+ updateLookupTableFast (m_lookup_table, TRUE);
+}
+
+void
+PinyinEditor::pageUp (void)
+{
+ if (m_lookup_table.pageUp ()) {
+ updateLookupTableFast (m_lookup_table, TRUE);
+ updatePreeditText ();
+ }
+}
+
+void
+PinyinEditor::pageDown (void)
+{
+ if (m_lookup_table.pageDown ()) {
+ updateLookupTableFast (m_lookup_table, TRUE);
+ updatePreeditText ();
+ }
+}
+
+void
+PinyinEditor::cursorUp (void)
+{
+ if (m_lookup_table.cursorUp ()) {
+ updateLookupTableFast (m_lookup_table, TRUE);
+ updatePreeditText ();
+ }
+}
+
+void
+PinyinEditor::cursorDown (void)
+{
+ if (m_lookup_table.cursorDown ()) {
+ updateLookupTableFast (m_lookup_table, TRUE);
+ updatePreeditText ();
+ }
+}
+
+void
+PinyinEditor::update (void)
+{
+ updatePreeditText ();
+ updateAuxiliaryText ();
+ updateLookupTable ();
+}
+
+void
+PinyinEditor::updatePhraseEditor (void)
+{
+ m_phrase_editor.update (m_pinyin);
+}
+
+inline void
+PinyinEditor::commit (const gchar *str)
+{
+ StaticText text(str);
+ commitText (text);
+}
+
+void
+PinyinEditor::commit (void)
+{
+ if (G_UNLIKELY (isEmpty ()))
+ return;
+
+ m_buffer.truncate (0);
+ m_buffer << m_phrase_editor.selectedString ();
+
+ const gchar *p = textAfterPinyin (m_buffer.utf8Length ());
+ 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 (m_phrase_editor.selectCandidate (i)) {
+ if ((!m_phrase_editor.pinyinExistsAfterCursor ()) &&
+ *textAfterPinyin () == '\0') {
+ commit ();
+ }
+ else
+ update ();
+ return TRUE;
+ }
+ return FALSE;
+}
+
+inline 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)
+{
+ 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);
}
};
diff --git a/src/PinyinEditor.h b/src/PinyinEditor.h
index 457e07f..1b7d609 100644
--- a/src/PinyinEditor.h
+++ b/src/PinyinEditor.h
@@ -2,18 +2,55 @@
#define __PY_PINYIN_EDITOR_H_
#include <glib.h>
-#include "String.h"
+#include "Editor.h"
+#include "Database.h"
#include "PinyinParser.h"
-#include "Regex.h"
+#include "PhraseEditor.h"
+
+namespace PY {
#define MAX_PINYIN_LEN 64
-namespace PY {
+class PinyinEditor : public Editor {
+public:
+ PinyinEditor (PinyinProperties & props);
-class PinyinEditor {
public:
- PinyinEditor (void);
-
+ /* 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);
+#if 0
+ virtual void reset (void);
+#endif
+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);
+
+ void updatePreeditText (void);
+ void updatePreeditTextInTypingMode (void);
+ void updatePreeditTextInEditingMode (void);
+ void updateAuxiliaryText (void);
+ void updateLookupTable (void);
+
+ void updatePhraseEditor (void);
+
+ gboolean selectCandidate (guint i);
+ gboolean selectCandidateInPage (guint i);
+ gboolean resetCandidate (guint i);
+ gboolean resetCandidateInPage (guint i);
+
+ void commit (void);
+ void commit (const gchar *str);
+
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 {
@@ -25,7 +62,7 @@ public:
}
const gchar * textAfterCursor (void) const { return (const gchar *)m_text + m_cursor; }
guint cursor (void) const { return m_cursor; }
- gboolean isEmpty (void) const { return m_text.isEmpty (); }
+ gboolean isEmpty (void) const { return m_buffer.isEmpty (); }
const PinyinArray & pinyin (void) const { return m_pinyin; }
guint pinyinLength (void) const { return m_pinyin_len; }
operator gboolean (void) const { return !isEmpty (); }
@@ -42,18 +79,17 @@ public:
virtual gboolean moveCursorRightByWord (void) = 0;
virtual gboolean moveCursorToBegin (void) = 0;
virtual gboolean moveCursorToEnd (void) = 0;
- virtual gboolean reset (void) = 0;
protected:
- String m_text; // text buffer
- guint m_cursor; // cursor pos in char
PinyinArray m_pinyin; // pinyin array
guint m_pinyin_len; // pinyin length in char
+ String m_buffer; // temp buffer
+ PhraseEditor m_phrase_editor;
+ LookupTable m_lookup_table;
protected:
static PinyinParser m_parser;
};
-
};
#endif
diff --git a/src/PinyinEngine.cc b/src/PinyinEngine.cc
index dd8d6ec..8c0e25c 100644
--- a/src/PinyinEngine.cc
+++ b/src/PinyinEngine.cc
@@ -19,12 +19,7 @@ namespace PY {
/* constructor */
PinyinEngine::PinyinEngine (IBusEngine *engine)
: m_engine (engine),
- m_pinyin_editor (NULL),
m_need_update (0),
- m_lookup_table (Config::pageSize ()),
- m_mode_chinese (Config::initChinese ()),
- m_mode_full (Config::initFull ()),
- m_mode_full_punct (Config::initFullPunct ()),
m_quote (TRUE),
m_double_quote (TRUE),
m_prev_pressed_key (0),
@@ -32,83 +27,30 @@ PinyinEngine::PinyinEngine (IBusEngine *engine)
m_prev_commited_char (0),
m_input_mode (MODE_INIT)
{
- /* */
+ gint i;
+ /* create editors */
if (Config::doublePinyin ())
- m_pinyin_editor = new DoublePinyinEditor ();
+ m_editors[MODE_INIT] = new DoublePinyinEditor (m_props);
else
- m_pinyin_editor = new FullPinyinEditor ();
-
- /* create properties */
- m_prop_chinese = ibus_property_new ("mode.chinese",
- PROP_TYPE_NORMAL,
- StaticText ("CN"),
- m_mode_chinese ?
- PKGDATADIR"/icons/chinese.svg" :
- PKGDATADIR"/icons/english.svg",
- StaticText (_("Chinese")),
- TRUE,
- TRUE,
- PROP_STATE_UNCHECKED,
- NULL);
- m_props.append (m_prop_chinese);
-
- m_prop_full = ibus_property_new ("mode.full",
- PROP_TYPE_NORMAL,
- StaticText (m_mode_full? "Aa" : "Aa"),
- m_mode_full ?
- PKGDATADIR"/icons/full.svg" :
- PKGDATADIR"/icons/half.svg",
- StaticText (_("Full/Half width")),
- TRUE,
- TRUE,
- PROP_STATE_UNCHECKED,
- NULL);
- m_props.append (m_prop_full);
-
- m_prop_full_punct = ibus_property_new ("mode.full_punct",
- PROP_TYPE_NORMAL,
- StaticText (m_mode_full_punct ? ",。" : ",."),
- m_mode_full_punct ?
- PKGDATADIR"/icons/full-punct.svg" :
- PKGDATADIR"/icons/half-punct.svg",
- StaticText (_("Full/Half width punctuation")),
- TRUE,
- TRUE,
- PROP_STATE_UNCHECKED,
- NULL);
- m_props.append (m_prop_full_punct);
-
- m_prop_simp = ibus_property_new ("mode.simp",
- PROP_TYPE_NORMAL,
- StaticText (m_phrase_editor.modeSimp () ? "简" : "繁"),
- m_phrase_editor.modeSimp () ?
- PKGDATADIR"/icons/simp-chinese.svg" :
- PKGDATADIR"/icons/trad-chinese.svg",
- StaticText (_("Simplfied/Traditional Chinese")),
- TRUE,
- TRUE,
- PROP_STATE_UNCHECKED,
- NULL);
- m_props.append (m_prop_simp);
+ m_editors[MODE_INIT] = new FullPinyinEditor (m_props);
+ for (i = MODE_RAW; i < MODE_LAST; i++) {
+ m_editors[i] = new RawEditor (m_props);
+ }
- m_prop_setup = ibus_property_new ("setup",
- PROP_TYPE_NORMAL,
- StaticText (_("Pinyin preferences")),
- "ibus-setup",
- StaticText (_("Pinyin preferences")),
- TRUE,
- TRUE,
- PROP_STATE_UNCHECKED,
- NULL);
- m_props.append (m_prop_setup);
+ m_props.signalUpdateProperty ().connect (sigc::mem_fun (*this, &PinyinEngine::slotUpdateProperty));
+ for (i = MODE_INIT; i < MODE_LAST; i++) {
+ connectEditorSignals (m_editors[i]);
+ }
}
/* destructor */
PinyinEngine::~PinyinEngine (void)
{
- delete m_pinyin_editor;
+ for (gint i = 0; i < MODE_LAST; i++) {
+ delete m_editors[i];
+ }
}
#define CMSHM_MASK \
@@ -121,145 +63,13 @@ PinyinEngine::~PinyinEngine (void)
#define CMSHM_FILTER(modifiers) \
(modifiers & (CMSHM_MASK))
-/**
- * process pinyin
- */
-inline gboolean
-PinyinEngine::processPinyin (guint keyval, guint keycode, guint modifiers)
-{
- if (G_UNLIKELY (CMSHM_FILTER(modifiers) != 0))
- return FALSE;
-
- if (G_UNLIKELY (!m_mode_chinese)) {
- commit (m_mode_full ? HalfFullConverter::toFull (keyval) : (gchar) keyval);
- return TRUE;
- }
-
- if (m_pinyin_editor->insert (keyval)) {
- updatePhraseEditor ();
- updateUI (FALSE);
- }
- return TRUE;
-}
-
-/**
- * process capital letters
- */
-inline gboolean
-PinyinEngine::processCapitalLetter (guint keyval, guint keycode, guint modifiers)
-{
- if (G_UNLIKELY (CMSHM_FILTER (modifiers) != 0))
- return FALSE;
-
- if (modifiers & IBUS_SHIFT_MASK)
- return processPinyin (keyval, keycode, modifiers);
-
- if (m_mode_chinese && ! isEmpty ()) {
- if (!Config::autoCommit ())
- return TRUE;
- if (m_phrase_editor.pinyinExistsAfterCursor ()) {
- selectCandidate (m_lookup_table.cursorPos ());
- }
- commit ();
- }
-
- commit (m_mode_full ? HalfFullConverter::toFull (keyval) : (gchar) keyval);
- return TRUE;
-}
-
-/**
- * process numbers
- */
-inline gboolean
-PinyinEngine::processNumber (guint keyval, guint keycode, guint modifiers)
-{
- guint ch;
-
- switch (keyval) {
- case IBUS_0 ... IBUS_9:
- ch = '0' + keyval - IBUS_0;
- break;
- case IBUS_KP_0 ... IBUS_KP_9:
- ch = '0' + keyval - IBUS_KP_0;
- break;
- default:
- g_return_val_if_reached (FALSE);
- break;
- }
-
- /* English mode */
- if (G_UNLIKELY (!m_mode_chinese)) {
- if (G_UNLIKELY (CMSHM_FILTER (modifiers) != 0))
- return FALSE;
- commit ((gunichar) m_mode_full ? HalfFullConverter::toFull (ch) : ch);
- return TRUE;
- }
-
- /* Chinese mode, if empty */
- if (G_UNLIKELY (isEmpty ())) {
- if (G_UNLIKELY (CMSHM_FILTER (modifiers) != 0))
- return FALSE;
- commit ((gunichar) m_mode_full ? HalfFullConverter::toFull (ch) : ch);
- return TRUE;
- }
-
- /* Chinese mode, if has candidates */
- guint i;
- switch (keyval) {
- case IBUS_0:
- case IBUS_KP_0:
- i = 9;
- break;
- case IBUS_1 ... IBUS_9:
- i = keyval - IBUS_1;
- break;
- case IBUS_KP_1 ... IBUS_KP_9:
- i = keyval - IBUS_KP_1;
- break;
- default:
- g_return_val_if_reached (FALSE);
- }
-
- if (modifiers == 0)
- selectCandidateInPage (i);
- else if ((modifiers & ~ IBUS_LOCK_MASK) == IBUS_CONTROL_MASK)
- resetCandidateInPage (i);
- return TRUE;
-}
-
-inline gboolean
-PinyinEngine::processSpace (guint keyval, guint keycode, guint modifiers)
-{
- if (CMSHM_FILTER (modifiers) != 0)
- return FALSE;
-
- if (G_UNLIKELY (modifiers & IBUS_SHIFT_MASK)) {
- toggleModeFull ();
- return TRUE;
- }
-
- /* Chinese mode */
- if (G_UNLIKELY (m_mode_chinese && !isEmpty ())) {
- if (m_phrase_editor.pinyinExistsAfterCursor ()) {
- selectCandidate (m_lookup_table.cursorPos ());
- }
- else {
- commit ();
- }
- }
- else {
- commit (m_mode_full ? " " : " ");
- }
- return TRUE;
-}
-
inline gboolean
PinyinEngine::processPunct (guint keyval, guint keycode, guint modifiers)
{
guint cmshm_modifiers = CMSHM_FILTER (modifiers);
if (G_UNLIKELY (keyval == IBUS_period && cmshm_modifiers == IBUS_CONTROL_MASK)) {
- toggleModeFullPunct ();
+ m_props.toggleModeFullPunct ();
return TRUE;
}
@@ -268,368 +78,147 @@ PinyinEngine::processPunct (guint keyval, guint keycode, guint modifiers)
return FALSE;
/* English mode */
- if (G_UNLIKELY (!m_mode_chinese)) {
- if (G_UNLIKELY (m_mode_full))
+ if (G_UNLIKELY (!m_props.modeChinese ())) {
+ if (G_UNLIKELY (m_props.modeFull ()))
commit (HalfFullConverter::toFull (keyval));
else
commit (keyval);
return TRUE;
}
-
- /* Chinese mode */
- if (G_UNLIKELY (!isEmpty ())) {
- switch (keyval) {
- case IBUS_apostrophe:
- return processPinyin (keyval, keycode, modifiers);
- case IBUS_comma:
- if (Config::commaPeriodPage ()) {
- pageUp ();
- return TRUE;
- }
- break;
- case IBUS_minus:
- if (Config::minusEqualPage ()) {
- pageUp ();
+ else {
+ /* Chinese mode */
+ if (m_props.modeFullPunct ()) {
+ switch (keyval) {
+ case '`':
+ commit ("·"); return TRUE;
+ case '~':
+ commit ("~"); return TRUE;
+ case '!':
+ commit ("!"); return TRUE;
+ // case '@':
+ // case '#':
+ case '$':
+ commit ("¥"); return TRUE;
+ // case '%':
+ case '^':
+ commit ("……"); return TRUE;
+ // case '&':
+ // case '*':
+ case '(':
+ commit ("("); return TRUE;
+ case ')':
+ commit (")"); return TRUE;
+ // case '-':
+ case '_':
+ commit ("——"); return TRUE;
+ // case '=':
+ // case '+':
+ case '[':
+ commit ("【"); return TRUE;
+ case ']':
+ commit ("】"); return TRUE;
+ case '{':
+ commit ("『"); return TRUE;
+ case '}':
+ commit ("』"); return TRUE;
+ case '\\':
+ commit ("、"); return TRUE;
+ // case '|':
+ case ';':
+ commit (";"); return TRUE;
+ case ':':
+ commit (":"); return TRUE;
+ case '\'':
+ commit (m_quote ? "‘" : "’");
+ m_quote = !m_quote;
return TRUE;
- }
- break;
- case IBUS_period:
- if (Config::commaPeriodPage ()) {
- pageDown ();
+ case '"':
+ commit (m_double_quote ? "“" : "”");
+ m_double_quote = !m_double_quote;
return TRUE;
- }
- break;
- case IBUS_equal:
- if (Config::minusEqualPage ()) {
- pageDown ();
+ case ',':
+ commit (","); return TRUE;
+ case '.':
+ if (m_prev_commited_char >= '0' && m_prev_commited_char <= '9')
+ commit (keyval);
+ else
+ commit ("。");
return TRUE;
+ case '<':
+ commit ("《"); return TRUE;
+ case '>':
+ commit ("》"); return TRUE;
+ // case '/':
+ case '?':
+ commit ("?"); return TRUE;
}
- break;
- case IBUS_semicolon:
- if (G_UNLIKELY (Config::doublePinyin ())) {
- /* double pinyin need process ';' */
- if (processPinyin (keyval, keycode, modifiers))
- return TRUE;
- }
- break;
- }
-
- if (G_LIKELY (!Config::autoCommit ()))
- return TRUE;
-
- if (m_phrase_editor.pinyinExistsAfterCursor ()) {
- selectCandidate (m_lookup_table.cursorPos ());
- }
- commit ();
- }
-
- g_assert (isEmpty ());
-
- if (m_mode_full_punct) {
- switch (keyval) {
- case '`':
- commit ("·"); return TRUE;
- case '~':
- commit ("~"); return TRUE;
- case '!':
- commit ("!"); return TRUE;
- // case '@':
- // case '#':
- case '$':
- commit ("¥"); return TRUE;
- // case '%':
- case '^':
- commit ("……"); return TRUE;
- // case '&':
- // case '*':
- case '(':
- commit ("("); return TRUE;
- case ')':
- commit (")"); return TRUE;
- // case '-':
- case '_':
- commit ("——"); return TRUE;
- // case '=':
- // case '+':
- case '[':
- commit ("【"); return TRUE;
- case ']':
- commit ("】"); return TRUE;
- case '{':
- commit ("『"); return TRUE;
- case '}':
- commit ("』"); return TRUE;
- case '\\':
- commit ("、"); return TRUE;
- // case '|':
- case ';':
- commit (";"); return TRUE;
- case ':':
- commit (":"); return TRUE;
- case '\'':
- commit (m_quote ? "‘" : "’");
- m_quote = !m_quote;
- return TRUE;
- case '"':
- commit (m_double_quote ? "“" : "”");
- m_double_quote = !m_double_quote;
- return TRUE;
- case ',':
- commit (","); return TRUE;
- case '.':
- if (m_prev_commited_char >= '0' && m_prev_commited_char <= '9')
- commit (keyval);
- else
- commit ("。");
- return TRUE;
- case '<':
- commit ("《"); return TRUE;
- case '>':
- commit ("》"); return TRUE;
- // case '/':
- case '?':
- commit ("?"); return TRUE;
}
+ commit (m_props.modeFull () ? HalfFullConverter::toFull (keyval) : keyval);
}
-
- commit (m_mode_full ? HalfFullConverter::toFull (keyval) : keyval);
return TRUE;
}
-inline gboolean
-PinyinEngine::processOthers (guint keyval, guint keycode, guint modifiers)
+gboolean
+PinyinEngine::processKeyEvent (guint keyval, guint keycode, guint modifiers)
{
- if (G_UNLIKELY (isEmpty ()))
- return FALSE;
-
- /* ignore numlock */
- modifiers &= ~IBUS_MOD2_MASK;
-
- /* process some cursor control keys */
- gboolean _update = FALSE;
- switch (keyval) {
- case IBUS_Shift_L:
- if (Config::shiftSelectCandidate () &&
- m_mode_chinese) {
- selectCandidateInPage (1);
- }
- break;
-
- case IBUS_Shift_R:
- if (Config::shiftSelectCandidate () &&
- m_mode_chinese) {
- selectCandidateInPage (2);
- }
- break;
-
- case IBUS_Return:
- case IBUS_KP_Enter:
- commit ();
- break;
-
- case IBUS_BackSpace:
- if (G_LIKELY (modifiers == 0))
- _update = m_pinyin_editor->removeCharBefore ();
- else if (G_LIKELY (modifiers == IBUS_CONTROL_MASK))
- _update = m_pinyin_editor->removeWordBefore ();
- break;
-
- case IBUS_Delete:
- case IBUS_KP_Delete:
- if (G_LIKELY (modifiers == 0))
- _update = m_pinyin_editor->removeCharAfter ();
- else if (G_LIKELY (modifiers == IBUS_CONTROL_MASK))
- _update = m_pinyin_editor->removeWordAfter ();
- break;
-
- case IBUS_Left:
- case IBUS_KP_Left:
- if (G_LIKELY (modifiers == 0)) {
- // move left single char
- _update = m_pinyin_editor->moveCursorLeft ();
- }
- else if (G_LIKELY (modifiers == IBUS_CONTROL_MASK)) {
- // move left one pinyin
- _update = m_pinyin_editor->moveCursorLeftByWord ();
- }
- break;
+ gboolean retval;
- case IBUS_Right:
- case IBUS_KP_Right:
- if (G_LIKELY (modifiers == 0)) {
- // move right single char
- _update = m_pinyin_editor->moveCursorRight ();
- }
- else if (G_LIKELY (modifiers == IBUS_CONTROL_MASK)) {
- // move right to end
- _update = m_pinyin_editor->moveCursorToEnd ();
- }
- break;
+ retval = m_editors[m_input_mode]->processKeyEvent (keyval, keycode, modifiers);
- case IBUS_Home:
- case IBUS_KP_Home:
- if (G_LIKELY (modifiers == 0)) {
- // move to begin
- _update = m_pinyin_editor->moveCursorToBegin ();
- }
- break;
+ if (retval == FALSE) {
+ // ignore release event
+ if (modifiers & IBUS_RELEASE_MASK) {
+ if (m_prev_pressed_key != keyval || m_prev_pressed_key_result != FALSE)
+ return TRUE;
- case IBUS_End:
- case IBUS_KP_End:
- if (G_LIKELY (modifiers == 0)) {
- // move to end
- _update = m_pinyin_editor->moveCursorToEnd ();
+ switch (keyval) {
+ case IBUS_Shift_L:
+ case IBUS_Shift_R:
+ m_props.toggleModeChinese ();
+ return TRUE;
+ default:
+ return TRUE;
+ }
}
- break;
-
- case IBUS_Up:
- case IBUS_KP_Up:
- cursorUp (); break;
- case IBUS_Down:
- case IBUS_KP_Down:
- cursorDown (); break;
- case IBUS_Page_Up:
- case IBUS_KP_Page_Up:
- pageUp (); break;
- case IBUS_Page_Down:
- case IBUS_KP_Page_Down:
- pageDown (); break;
- case IBUS_Escape:
- reset (); break;
- }
- if (G_LIKELY (_update)) {
- updatePhraseEditor ();
- updateUI (FALSE);
- }
- return TRUE;
-}
-
-inline gboolean
-PinyinEngine::processInitMode (guint keyval, guint keycode, guint modifiers)
-{
- gboolean retval = FALSE;
-
- // ignore release event
- if (modifiers & IBUS_RELEASE_MASK) {
- if (m_prev_pressed_key != keyval || m_prev_pressed_key_result != FALSE)
- return TRUE;
+ modifiers &= (IBUS_SHIFT_MASK |
+ IBUS_CONTROL_MASK |
+ IBUS_MOD1_MASK |
+ IBUS_SUPER_MASK |
+ IBUS_HYPER_MASK |
+ IBUS_META_MASK);
switch (keyval) {
- case IBUS_Shift_L:
- case IBUS_Shift_R:
- if (isEmpty ())
- toggleModeChinese ();
- return TRUE;
- default:
- return TRUE;
+ /* letters */
+ case IBUS_a ... IBUS_z:
+ case IBUS_A ... IBUS_Z:
+ /* numbers */
+ case IBUS_0 ... IBUS_9:
+ case IBUS_KP_0 ... IBUS_KP_9:
+ if (modifiers == 0) {
+ commit (m_props.modeFull () ? HalfFullConverter::toFull (keyval) : (gchar) keyval);
+ retval = TRUE;
+ }
+ break;
+ /* punct */
+ case IBUS_exclam ... IBUS_slash:
+ case IBUS_colon ... IBUS_at:
+ case IBUS_bracketleft ... IBUS_quoteleft:
+ case IBUS_braceleft ... IBUS_asciitilde:
+ retval = processPunct (keyval, keycode, modifiers);
+ break;
+ /* space */
+ case IBUS_space:
+ if (modifiers == 0) {
+ commit (m_props.modeFull () ? " " : " ");
+ retval = TRUE;
+ }
+ break;
+ /* others */
+ default:
+ break;
}
}
- modifiers &= (IBUS_SHIFT_MASK |
- IBUS_CONTROL_MASK |
- IBUS_MOD1_MASK |
- IBUS_SUPER_MASK |
- IBUS_HYPER_MASK |
- IBUS_META_MASK |
- IBUS_LOCK_MASK);
-
- switch (keyval) {
- /* letters */
- case IBUS_a ... IBUS_z:
- retval = processPinyin (keyval, keycode, modifiers);
- break;
- case IBUS_A ... IBUS_Z:
- retval = processCapitalLetter (keyval, keycode, modifiers);
- break;
- /* numbers */
- case IBUS_0 ... IBUS_9:
- case IBUS_KP_0 ... IBUS_KP_9:
- retval = processNumber (keyval, keycode, modifiers);
- break;
- /* punct */
- case IBUS_exclam ... IBUS_slash:
- case IBUS_colon ... IBUS_at:
- case IBUS_bracketleft ... IBUS_quoteleft:
- case IBUS_braceleft ... IBUS_asciitilde:
- retval = processPunct (keyval, keycode, modifiers);
- break;
- /* space */
- case IBUS_space:
- retval = processSpace (keyval, keycode, modifiers);
- break;
- /* others */
- default:
- retval = processOthers (keyval, keycode, modifiers);
- break;
- }
-
- return retval;
-}
-
-inline gboolean
-PinyinEngine::processRawMode (guint keyval, guint keycode, guint modifiers)
-{
- gboolean update = TRUE;
- gboolean retval = TRUE;
-
- switch (keyval) {
- case IBUS_Escape:
- reset ();
- break;
- default:
- retval = m_raw_editor.processKeyEvent (keyval, keycode, modifiers, update);
- if (update)
- updatePreeditTextInRawMode ();
- break;
- }
-
- return retval;
-}
-
-inline gboolean
-PinyinEngine::processEnglishMode (guint keyval, guint keycode, guint modifiers)
-{
- return TRUE;
-}
-
-inline gboolean
-PinyinEngine::processStrokeMode (guint keyval, guint keycode, guint modifiers)
-{
- return TRUE;
-}
-
-inline gboolean
-PinyinEngine::processExtensionMode (guint keyval, guint keycode, guint modifiers)
-{
- return TRUE;
-}
-
-gboolean
-PinyinEngine::processKeyEvent (guint keyval, guint keycode, guint modifiers)
-{
- gboolean retval;
-
- switch (m_input_mode) {
- case MODE_INIT:
- retval = processInitMode (keyval, keycode, modifiers);
- break;
- case MODE_RAW:
- retval = processRawMode (keyval, keycode, modifiers);
- break;
- case MODE_ENGLISH:
- retval = processEnglishMode (keyval, keycode, modifiers);
- break;
- case MODE_STROKE:
- retval = processStrokeMode (keyval, keycode, modifiers);
- break;
- case MODE_EXTENSION:
- retval = processExtensionMode (keyval, keycode, modifiers);
- break;
- default:
- g_assert_not_reached ();
- break;
- };
-
m_prev_pressed_key = keyval;
m_prev_pressed_key_result = retval;
return retval;
@@ -640,101 +229,43 @@ PinyinEngine::focusIn (void)
{
/* reset pinyin parser */
if (Config::doublePinyin ()) {
- if (dynamic_cast <DoublePinyinEditor *> (m_pinyin_editor) == NULL)
- delete m_pinyin_editor;
- m_pinyin_editor = new DoublePinyinEditor ();
+ if (dynamic_cast <DoublePinyinEditor *> (m_editors[MODE_INIT]) == NULL)
+ delete m_editors[MODE_INIT];
+ m_editors[MODE_INIT] = new DoublePinyinEditor (m_props);
+ connectEditorSignals (m_editors[MODE_INIT]);
}
else {
- if (dynamic_cast <FullPinyinEditor *> (m_pinyin_editor) == NULL)
- delete m_pinyin_editor;
- m_pinyin_editor = new FullPinyinEditor ();
+ if (dynamic_cast <FullPinyinEditor *> (m_editors[MODE_INIT]) == NULL)
+ delete m_editors[MODE_INIT];
+ m_editors[MODE_INIT] = new FullPinyinEditor (m_props);
+ connectEditorSignals (m_editors[MODE_INIT]);
}
-
- ibus_engine_register_properties (m_engine, m_props);
+ ibus_engine_register_properties (m_engine, m_props.properties ());
}
void
PinyinEngine::pageUp (void)
{
- if (m_lookup_table.pageUp ()) {
- ibus_engine_update_lookup_table_fast (m_engine, m_lookup_table, TRUE);
- updatePreeditText ();
- }
+ m_editors[m_input_mode]->pageUp ();
}
void
PinyinEngine::pageDown (void)
{
- if (m_lookup_table.pageDown ()) {
- ibus_engine_update_lookup_table_fast (m_engine, m_lookup_table, TRUE);
- updatePreeditText ();
- }
+ m_editors[m_input_mode]->pageDown ();
}
void
PinyinEngine::cursorUp (void)
{
- if (m_lookup_table.cursorUp ()) {
- ibus_engine_update_lookup_table_fast (m_engine, m_lookup_table, TRUE);
- updatePreeditText ();
- }
+ m_editors[m_input_mode]->cursorUp ();
}
void
PinyinEngine::cursorDown (void)
{
- if (m_lookup_table.cursorDown ()) {
- ibus_engine_update_lookup_table_fast (m_engine, m_lookup_table, TRUE);
- updatePreeditText ();
- }
-}
-
-inline void
-PinyinEngine::toggleModeChinese (void)
-{
- m_mode_chinese = ! m_mode_chinese;
- m_prop_chinese.setLabel (m_mode_chinese ? "CN" : "EN");
- m_prop_chinese.setIcon (m_mode_chinese ?
- PKGDATADIR"/icons/chinese.svg" :
- PKGDATADIR"/icons/english.svg");
- ibus_engine_update_property (m_engine, m_prop_chinese);
-
- m_prop_full_punct.setSensitive (m_mode_chinese);
- ibus_engine_update_property (m_engine, m_prop_full_punct);
-}
-
-inline void
-PinyinEngine::toggleModeFull (void)
-{
- m_mode_full = !m_mode_full;
- m_prop_full.setLabel (m_mode_full ? "Aa" : "Aa");
- m_prop_full.setIcon (m_mode_full ?
- PKGDATADIR"/icons/full.svg" :
- PKGDATADIR"/icons/half.svg");
- ibus_engine_update_property (m_engine, m_prop_full);
-}
-
-inline void
-PinyinEngine::toggleModeFullPunct (void)
-{
- m_mode_full_punct = !m_mode_full_punct;
- m_prop_full_punct.setLabel (m_mode_full_punct ? ",。" : ",.");
- m_prop_full_punct.setIcon (m_mode_full_punct ?
- PKGDATADIR"/icons/full-punct.svg" :
- PKGDATADIR"/icons/half-punct.svg");
- ibus_engine_update_property (m_engine, m_prop_full_punct);
-}
-
-inline void
-PinyinEngine::toggleModeSimp (void)
-{
- m_phrase_editor.setModeSimp(!m_phrase_editor.modeSimp ());
- m_prop_simp.setLabel (m_phrase_editor.modeSimp () ? "简" : "繁");
- m_prop_simp.setIcon (m_phrase_editor.modeSimp () ?
- PKGDATADIR"/icons/simp-chinese.svg" :
- PKGDATADIR"/icons/trad-chinese.svg");
- ibus_engine_update_property (m_engine, m_prop_simp);
+ m_editors[m_input_mode]->cursorDown ();
}
inline void
@@ -743,365 +274,157 @@ PinyinEngine::showSetupDialog (void)
g_spawn_command_line_async (LIBEXECDIR"/ibus-setup-pinyin", NULL);
}
-void
+gboolean
PinyinEngine::propertyActivate (const gchar *prop_name, guint prop_state)
{
- const static StaticString mode_chinese ("mode.chinese");
- const static StaticString mode_full ("mode.full");
- const static StaticString mode_full_punct ("mode.full_punct");
- const static StaticString mode_simp ("mode.simp");
const static StaticString setup ("setup");
-
- if (mode_chinese == prop_name) {
- toggleModeChinese ();
- }
- else if (mode_full == prop_name) {
- toggleModeFull ();
- }
- else if (mode_full_punct == prop_name) {
- toggleModeFullPunct ();
- }
- else if (mode_simp == prop_name) {
- toggleModeSimp ();
+ if (m_props.propertyActivate (prop_name, prop_state)) {
+ return TRUE;
}
else if (setup == prop_name) {
showSetupDialog ();
+ return TRUE;
}
+ return FALSE;
}
void
PinyinEngine::candidateClicked (guint index, guint button, guint state)
{
+#if 0
selectCandidateInPage (index);
+#endif
}
-void
-PinyinEngine::updatePreeditText (void)
+inline void
+PinyinEngine::commit (gchar ch)
{
- switch (m_input_mode) {
- case MODE_INIT:
- updatePreeditTextInInitMode ();
- break;
- case MODE_RAW:
- updatePreeditTextInRawMode ();
- break;
- default:
- break;
- };
+ gchar str[2] = {ch, 0};
+ ibus_engine_commit_text (m_engine, StaticText (str));
+ m_prev_commited_char = ch;
}
-void
-PinyinEngine::updatePreeditTextInInitMode (void)
+inline void
+PinyinEngine::commit (gunichar ch)
{
- /* preedit text = selected phrases + highlight candidate + rest text */
- if (G_UNLIKELY (m_phrase_editor.isEmpty () && m_pinyin_editor->isEmpty ())) {
- ibus_engine_hide_preedit_text (m_engine);
- return;
- }
-
- if (m_pinyin_editor->cursor () == m_pinyin_editor->text ().length ())
- updatePreeditTextInInitTypingMode ();
- else
- updatePreeditTextInInitEditingMode ();
+ ibus_engine_commit_text (m_engine, Text (ch));
+ m_prev_commited_char = ch;
}
-void
-PinyinEngine::updatePreeditTextInRawMode (void)
+inline void
+PinyinEngine::commit (const gchar *str)
{
- StaticText preedit_text (m_raw_editor);
- preedit_text.appendAttribute (IBUS_ATTR_TYPE_UNDERLINE, IBUS_ATTR_UNDERLINE_SINGLE, 0, -1);
- ibus_engine_update_preedit_text (m_engine, preedit_text, m_raw_editor.cursor (), TRUE);
+ ibus_engine_commit_text (m_engine, StaticText (str));
+ m_prev_commited_char = 0;
}
-void
-PinyinEngine::updatePreeditTextInInitTypingMode (void)
+inline void
+PinyinEngine::commit (const String &str)
{
- m_buffer.truncate (0);
-
- /* add select phrases */
- if (G_UNLIKELY (m_phrase_editor.selectedString ())) {
- m_buffer << m_phrase_editor.selectedString ();
- }
-
- /* add highlight candidate */
- guint candidate_begin = m_buffer.utf8Length ();
- guint candidate_length = 0;
- if (m_phrase_editor.candidates ().length () > 0) {
- if (m_lookup_table.cursorPos () == 0 && !m_phrase_editor.modeSimp ()) {
- const PhraseArray & phrases = m_phrase_editor.candidate0 ();
- candidate_length = 0;
- for (guint i = 0; i < phrases.length (); i++) {
- candidate_length += phrases[i].len;
- SimpTradConverter::simpToTrad (phrases[i], m_buffer);
- }
- }
- else {
- const Phrase & candidate = m_phrase_editor.candidate (m_lookup_table.cursorPos ());
- candidate_length = candidate.len;
- if (m_phrase_editor.modeSimp ())
- m_buffer << candidate;
- else
- SimpTradConverter::simpToTrad (candidate, m_buffer);
- }
- }
-
- /* add rest text */
- const PinyinArray & pinyin = m_phrase_editor.pinyin ();
- if (candidate_begin + candidate_length < pinyin.length ())
- m_buffer << ((const gchar *) m_pinyin_editor->textAfterPinyin (
- candidate_begin + candidate_length));
- else
- m_buffer << ((const gchar *) m_pinyin_editor->textAfterPinyin ());
-
- StaticText preedit_text (m_buffer);
- /* underline */
- preedit_text.appendAttribute (IBUS_ATTR_TYPE_UNDERLINE, IBUS_ATTR_UNDERLINE_SINGLE, 0, -1);
-
- /* candidate */
- if (candidate_length != 0) {
- preedit_text.appendAttribute (IBUS_ATTR_TYPE_FOREGROUND, 0x00000000,
- candidate_begin, candidate_begin + candidate_length);
- preedit_text.appendAttribute (IBUS_ATTR_TYPE_BACKGROUND, 0x00c8c8f0,
- candidate_begin, candidate_begin + candidate_length);
- }
- // ibus_engine_update_preedit_text (m_engine, preedit_text, m_buffer.utf8Length (), TRUE);
- ibus_engine_update_preedit_text (m_engine, preedit_text, candidate_begin, TRUE);
+ commit ((const gchar *)str);
}
void
-PinyinEngine::updatePreeditTextInInitEditingMode (void)
+PinyinEngine::slotCommitText (Text & text)
{
- m_buffer.truncate (0);
-
- /* add select phrases */
- if (G_UNLIKELY (m_phrase_editor.selectedString ())) {
- m_buffer << m_phrase_editor.selectedString ();
- }
-
- /* add highlight candidate */
- const PinyinArray & pinyin = m_phrase_editor.pinyin ();
- guint candidate_begin = m_buffer.utf8Length ();
- guint candidate_length = 0;
- guint candidate_pinyin_end = 0;
- if (m_phrase_editor.candidates ().length () > 0) {
- const Phrase & candidate = m_phrase_editor.candidate (m_lookup_table.cursorPos ());
- candidate_length = candidate.len;
-
- m_buffer << pinyin[candidate_begin]->sheng << pinyin[candidate_begin]->yun;
-
- for (guint i = 1; i < candidate_length; i++) {
- m_buffer << ' ' << pinyin[candidate_begin + i]->sheng << pinyin[candidate_begin + i]->yun;
- }
- candidate_pinyin_end = m_buffer.utf8Length ();
- }
-
- /* add rest text */
- if (candidate_begin + candidate_length < pinyin.length ()) {
- if (m_buffer)
- m_buffer << ' ' ;
- m_buffer << m_pinyin_editor->textAfterPinyin (candidate_begin + candidate_length);
- }
- else {
- const gchar * p = m_pinyin_editor->textAfterPinyin ();
- if (*p != '\0') {
- if (m_buffer)
- m_buffer << ' ';
- m_buffer << p;
- }
- }
-
- StaticText preedit_text (m_buffer);
- /* underline */
- preedit_text.appendAttribute (IBUS_ATTR_TYPE_UNDERLINE, IBUS_ATTR_UNDERLINE_SINGLE, 0, -1);
-
- /* candidate */
- if (candidate_length != 0) {
- preedit_text.appendAttribute (IBUS_ATTR_TYPE_FOREGROUND, 0x00000000,
- candidate_begin, candidate_pinyin_end);
- preedit_text.appendAttribute (IBUS_ATTR_TYPE_BACKGROUND, 0x00c8c8f0,
- candidate_begin, candidate_pinyin_end);
- }
- // ibus_engine_update_preedit_text (m_engine, preedit_text, m_buffer.utf8Length (), TRUE);
- ibus_engine_update_preedit_text (m_engine, preedit_text, candidate_begin, TRUE);
+ ibus_engine_commit_text (m_engine, text);
}
void
-PinyinEngine::updateAuxiliaryText (void)
+PinyinEngine::slotUpdatePreeditText (Text & text, guint cursor, gboolean visible)
{
-
- /* clear pinyin array */
- if (G_UNLIKELY (isEmpty () ||
- m_phrase_editor.cursor () == m_pinyin_editor->pinyin ().length ())) {
- ibus_engine_hide_auxiliary_text (m_engine);
- return;
- }
-
- // guint cursor_pos;
-
- m_buffer.truncate (0);
- for (guint i = m_phrase_editor.cursor (); i < m_pinyin_editor->pinyin().length (); ++i) {
- if (G_LIKELY (i != m_phrase_editor.cursor ()))
- m_buffer << ' ';
- const Pinyin *p = m_pinyin_editor->pinyin()[i];
- m_buffer << p->sheng;
- m_buffer << p->yun;
- }
-
- if (G_UNLIKELY (m_pinyin_editor->pinyinLength () == m_pinyin_editor->cursor ())) {
- /* aux = pinyin + non-pinyin */
- // cursor_pos = m_buffer.utf8Length ();
- m_buffer << '|' << m_pinyin_editor->textAfterPinyin ();
- }
- else {
- /* aux = pinyin + non-pinyin before cursor + non-pinyin after cursor */
- m_buffer.append (m_pinyin_editor->textAfterPinyin (),
- m_pinyin_editor->cursor () - m_pinyin_editor->pinyinLength ());
- // cursor_pos = m_buffer.utf8Length ();
- m_buffer << '|' << m_pinyin_editor->textAfterCursor ();
- }
-
- StaticText aux_text (m_buffer);
- ibus_engine_update_auxiliary_text (m_engine, aux_text, TRUE);
+ ibus_engine_update_preedit_text (m_engine, text, cursor, visible);
}
void
-PinyinEngine::updateLookupTable (void)
+PinyinEngine::slotShowPreeditText (void)
{
- m_lookup_table.clear ();
- m_lookup_table.setPageSize (Config::pageSize ());
-
- guint candidate_nr = m_phrase_editor.candidates ().length ();
-
- if (G_UNLIKELY (candidate_nr == 0)) {
- ibus_engine_hide_lookup_table (m_engine);
- return;
- }
-
- if (G_LIKELY (m_phrase_editor.modeSimp () || !Config::tradCandidate ())) {
- for (guint i = 0; i < candidate_nr; i++) {
- StaticText text (m_phrase_editor.candidate (i));
- if (m_phrase_editor.candidateIsUserPhease (i))
- text.appendAttribute (IBUS_ATTR_TYPE_FOREGROUND, 0x000000ef, 0, -1);
- m_lookup_table.appendCandidate (text);
- }
- }
- else {
- for (guint i = 0; i < candidate_nr; i++) {
- m_buffer.truncate (0);
- SimpTradConverter::simpToTrad (m_phrase_editor.candidate (i), m_buffer);
- Text text (m_buffer);
- if (m_phrase_editor.candidateIsUserPhease (i))
- text.appendAttribute (IBUS_ATTR_TYPE_FOREGROUND, 0x000000ef, 0, -1);
- m_lookup_table.appendCandidate (text);
- }
- }
- ibus_engine_update_lookup_table_fast (m_engine,
- m_lookup_table,
- TRUE);
+ ibus_engine_show_preedit_text (m_engine);
}
void
-PinyinEngine::updatePhraseEditor (void)
+PinyinEngine::slotHidePreeditText (void)
{
- m_phrase_editor.update (m_pinyin_editor->pinyin ());
+ ibus_engine_hide_preedit_text (m_engine);
}
-inline void
-PinyinEngine::commit (gchar ch)
+void
+PinyinEngine::slotUpdateAuxiliaryText (Text & text, gboolean visible)
{
- gchar str[2] = {ch, 0};
- ibus_engine_commit_text (m_engine, StaticText (str));
- m_prev_commited_char = ch;
+ ibus_engine_update_auxiliary_text (m_engine, text, visible);
}
-inline void
-PinyinEngine::commit (gunichar ch)
+void
+PinyinEngine::slotShowAuxiliaryText (void)
{
- ibus_engine_commit_text (m_engine, Text (ch));
- m_prev_commited_char = ch;
+ ibus_engine_show_auxiliary_text (m_engine);
}
-inline void
-PinyinEngine::commit (const gchar *str)
+void
+PinyinEngine::slotHideAuxiliaryText (void)
{
- ibus_engine_commit_text (m_engine, StaticText (str));
- m_prev_commited_char = 0;
+ ibus_engine_hide_auxiliary_text (m_engine);
}
-inline void
-PinyinEngine::commit (const String &str)
+void
+PinyinEngine::slotUpdateLookupTable (LookupTable & table, gboolean visible)
{
- commit ((const gchar *)str);
+ ibus_engine_update_lookup_table (m_engine, table, visible);
}
-inline void
-PinyinEngine::commit (void)
+void
+PinyinEngine::slotUpdateLookupTableFast (LookupTable & table, gboolean visible)
{
- if (G_UNLIKELY (m_pinyin_editor->isEmpty ()))
- return;
-
- m_buffer.truncate (0);
- m_buffer << m_phrase_editor.selectedString ();
-
- const gchar *p = m_pinyin_editor->textAfterPinyin (m_buffer.utf8Length ());
- if (G_UNLIKELY (m_mode_full)) {
- while (*p != '\0') {
- m_buffer.appendUnichar (HalfFullConverter::toFull (*p++));
- }
- }
- else {
- m_buffer << p;
- }
- m_phrase_editor.commit ();
- reset ();
- commit ((const gchar *)m_buffer);
+ ibus_engine_update_lookup_table_fast (m_engine, table, visible);
}
-inline gboolean
-PinyinEngine::selectCandidate (guint i)
+void
+PinyinEngine::slotShowLookupTable (void)
{
- if (m_phrase_editor.selectCandidate (i)) {
- if ((!m_phrase_editor.pinyinExistsAfterCursor ()) &&
- *m_pinyin_editor->textAfterPinyin () == '\0') {
- commit ();
- }
- else
- updateUI ();
- return TRUE;
- }
- return FALSE;
+ ibus_engine_show_lookup_table (m_engine);
}
-inline gboolean
-PinyinEngine::selectCandidateInPage (guint i)
+void
+PinyinEngine::slotHideLookupTable (void)
{
- 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);
+ ibus_engine_hide_lookup_table (m_engine);
}
-inline gboolean
-PinyinEngine::resetCandidate (guint i)
+void
+PinyinEngine::slotUpdateProperty (Property & prop)
{
- if (m_phrase_editor.resetCandidate (i)) {
- updateUI ();
- }
- return TRUE;
+ ibus_engine_update_property (m_engine, prop);
}
-inline gboolean
-PinyinEngine::resetCandidateInPage (guint i)
-{
- guint page_size = m_lookup_table.pageSize ();
- guint cursor_pos = m_lookup_table.cursorPos ();
- i += (cursor_pos / page_size) * page_size;
+void
+PinyinEngine::connectEditorSignals (Editor *editor)
+{
+ editor->signalCommitText ().connect (
+ sigc::mem_fun (*this, &PinyinEngine::slotCommitText));
+
+ editor->signalUpdatePreeditText ().connect (
+ sigc::mem_fun (*this, &PinyinEngine::slotUpdatePreeditText));
+ editor->signalShowPreeditText ().connect (
+ sigc::mem_fun (*this, &PinyinEngine::slotShowPreeditText));
+ editor->signalHidePreeditText ().connect (
+ sigc::mem_fun (*this, &PinyinEngine::slotHidePreeditText));
+
+ editor->signalUpdateAuxiliaryText ().connect (
+ sigc::mem_fun (*this, &PinyinEngine::slotUpdateAuxiliaryText));
+ editor->signalShowAuxiliaryText ().connect (
+ sigc::mem_fun (*this, &PinyinEngine::slotShowAuxiliaryText));
+ editor->signalHideAuxiliaryText ().connect (
+ sigc::mem_fun (*this, &PinyinEngine::slotHideAuxiliaryText));
+
+ editor->signalUpdateLookupTable ().connect (
+ sigc::mem_fun (*this, &PinyinEngine::slotUpdateLookupTable));
+ editor->signalUpdateLookupTableFast ().connect (
+ sigc::mem_fun (*this, &PinyinEngine::slotUpdateLookupTableFast));
+ editor->signalShowLookupTable ().connect (
+ sigc::mem_fun (*this, &PinyinEngine::slotShowLookupTable));
+ editor->signalHideLookupTable ().connect (
+ sigc::mem_fun (*this, &PinyinEngine::slotHideLookupTable));
- return resetCandidate (i);
}
};
diff --git a/src/PinyinEngine.h b/src/PinyinEngine.h
index 2f89dad..1618888 100644
--- a/src/PinyinEngine.h
+++ b/src/PinyinEngine.h
@@ -11,6 +11,8 @@
#include "LookupTable.h"
#include "Property.h"
#include "Config.h"
+#include "Editor.h"
+#include "PinyinProperties.h"
namespace PY {
@@ -28,9 +30,9 @@ public:
void reset (gboolean need_update = TRUE) {
resetQuote ();
m_input_mode = MODE_INIT;
- m_pinyin_editor->reset ();
- m_phrase_editor.reset ();
- m_raw_editor.reset ();
+ for (gint i = 0; i < MODE_LAST; i++) {
+ m_editors[i]->reset ();
+ }
updateUI (need_update);
}
@@ -46,10 +48,11 @@ public:
void cursorUp (void);
void cursorDown (void);
- void propertyActivate (const gchar *prop_name, guint prop_state);
+ gboolean propertyActivate (const gchar *prop_name, guint prop_state);
void candidateClicked (guint index, guint button, guint state);
void updateUI (gboolean now = TRUE) {
+ #if 0
if (G_UNLIKELY (now || m_need_update >= 4)) {
updateLookupTable ();
updateAuxiliaryText ();
@@ -61,23 +64,21 @@ public:
}
m_need_update ++;
}
+ #endif
}
private:
- gboolean processInitMode (guint keyval, guint keycode, guint modifiers);
- gboolean processRawMode (guint keyval, guint keycode, guint modifiers);
- gboolean processEnglishMode (guint keyval, guint keycode, guint modifiers);
- gboolean processStrokeMode (guint keyval, guint keycode, guint modifiers);
- gboolean processExtensionMode (guint keyval, guint keycode, guint modifiers);
+ gboolean processPunct (guint keyval, guint keycode, guint modifiers);
+#if 0
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);
+#endif
private:
- gboolean isEmpty (void) { return m_pinyin_editor->isEmpty (); }
+ // gboolean isEmpty (void) { return m_pinyin_editor->isEmpty (); }
void commit (void);
void commit (gchar ch);
@@ -91,18 +92,6 @@ private:
void toggleModeSimp (void);
void showSetupDialog (void);
- gboolean selectCandidate (guint i);
- gboolean selectCandidateInPage (guint i);
- gboolean resetCandidate (guint i);
- gboolean resetCandidateInPage (guint i);
- void updatePreeditText (void);
- void updatePreeditTextInInitMode (void);
- void updatePreeditTextInRawMode (void);
- void updatePreeditTextInInitEditingMode (void);
- void updatePreeditTextInInitTypingMode (void);
- void updateAuxiliaryText (void);
- void updateLookupTable (void);
- void updatePhraseEditor (void);
static gboolean delayUpdateUIHandler (PinyinEngine *pinyin) {
if (pinyin->m_need_update > 0)
@@ -110,26 +99,31 @@ private:
return FALSE;
}
+ void connectEditorSignals (Editor *editor);
+
+private:
+ void slotCommitText (Text & text);
+ void slotUpdatePreeditText (Text & text, guint cursor, gboolean visible);
+ void slotShowPreeditText (void);
+ void slotHidePreeditText (void);
+ void slotUpdateAuxiliaryText (Text & text, gboolean visible);
+ void slotShowAuxiliaryText (void);
+ void slotHideAuxiliaryText (void);
+ void slotUpdateLookupTable (LookupTable &table, gboolean visible);
+ void slotUpdateLookupTableFast (LookupTable &table, gboolean visible);
+ void slotShowLookupTable (void);
+ void slotHideLookupTable (void);
+ void slotUpdateProperty (Property & prop);
+
private:
Pointer<IBusEngine> m_engine; // engine pointer
- PinyinEditor *m_pinyin_editor; // pinyin editor
- PhraseEditor m_phrase_editor; // phrase editor
String m_buffer; // string buffer
gint m_need_update; // need update preedit, aux, or lookup table
LookupTable m_lookup_table;
- Property m_prop_chinese;
- Property m_prop_full;
- Property m_prop_full_punct;
- Property m_prop_simp;
- Property m_prop_setup;
- PropList m_props;
-
- gboolean m_mode_chinese;
- gboolean m_mode_full;
- gboolean m_mode_full_punct;
+ PinyinProperties m_props;
gboolean m_quote;
gboolean m_double_quote;
@@ -144,9 +138,10 @@ private:
MODE_ENGLISH, // press v into English input mode
MODE_STROKE, // press u into stroke input mode
MODE_EXTENSION, // press i into extension input mode
+ MODE_LAST,
} m_input_mode;
- RawEditor m_raw_editor;
+ Editor *m_editors[MODE_LAST];
};
};
diff --git a/src/PinyinProperties.cc b/src/PinyinProperties.cc
new file mode 100644
index 0000000..c8ceb0e
--- /dev/null
+++ b/src/PinyinProperties.cc
@@ -0,0 +1,152 @@
+#include "Util.h"
+#include "PinyinProperties.h"
+
+namespace PY {
+
+PinyinProperties::PinyinProperties (void)
+ : m_mode_chinese (Config::initChinese ()),
+ m_mode_full (Config::initFull ()),
+ m_mode_full_punct (Config::initFullPunct ()),
+ m_mode_simp (Config::initSimpChinese ())
+{
+ /* create properties */
+ m_prop_chinese = ibus_property_new ("mode.chinese",
+ PROP_TYPE_NORMAL,
+ StaticText ("CN"),
+ m_mode_chinese ?
+ PKGDATADIR"/icons/chinese.svg" :
+ PKGDATADIR"/icons/english.svg",
+ StaticText (_("Chinese")),
+ TRUE,
+ TRUE,
+ PROP_STATE_UNCHECKED,
+ NULL);
+ m_props.append (m_prop_chinese);
+
+ m_prop_full = ibus_property_new ("mode.full",
+ PROP_TYPE_NORMAL,
+ StaticText (m_mode_full? "Aa" : "Aa"),
+ m_mode_full ?
+ PKGDATADIR"/icons/full.svg" :
+ PKGDATADIR"/icons/half.svg",
+ StaticText (_("Full/Half width")),
+ TRUE,
+ TRUE,
+ PROP_STATE_UNCHECKED,
+ NULL);
+ m_props.append (m_prop_full);
+
+ m_prop_full_punct = ibus_property_new ("mode.full_punct",
+ PROP_TYPE_NORMAL,
+ StaticText (m_mode_full_punct ? ",。" : ",."),
+ m_mode_full_punct ?
+ PKGDATADIR"/icons/full-punct.svg" :
+ PKGDATADIR"/icons/half-punct.svg",
+ StaticText (_("Full/Half width punctuation")),
+ TRUE,
+ TRUE,
+ PROP_STATE_UNCHECKED,
+ NULL);
+ m_props.append (m_prop_full_punct);
+
+ m_prop_simp = ibus_property_new ("mode.simp",
+ PROP_TYPE_NORMAL,
+ StaticText (m_mode_simp ? "简" : "繁"),
+ m_mode_simp ?
+ PKGDATADIR"/icons/simp-chinese.svg" :
+ PKGDATADIR"/icons/trad-chinese.svg",
+ StaticText (_("Simplfied/Traditional Chinese")),
+ TRUE,
+ TRUE,
+ PROP_STATE_UNCHECKED,
+ NULL);
+ m_props.append (m_prop_simp);
+
+ m_prop_setup = ibus_property_new ("setup",
+ PROP_TYPE_NORMAL,
+ StaticText (_("Pinyin preferences")),
+ "ibus-setup",
+ StaticText (_("Pinyin preferences")),
+ TRUE,
+ TRUE,
+ PROP_STATE_UNCHECKED,
+ NULL);
+ m_props.append (m_prop_setup);
+
+}
+
+void
+PinyinProperties::toggleModeChinese (void)
+{
+ m_mode_chinese = ! m_mode_chinese;
+ m_prop_chinese.setLabel (m_mode_chinese ? "CN" : "EN");
+ m_prop_chinese.setIcon (m_mode_chinese ?
+ PKGDATADIR"/icons/chinese.svg" :
+ PKGDATADIR"/icons/english.svg");
+ updateProperty (m_prop_chinese);
+
+ m_prop_full_punct.setSensitive (m_mode_chinese);
+ updateProperty (m_prop_full_punct);
+}
+
+void
+PinyinProperties::toggleModeFull (void)
+{
+ m_mode_full = !m_mode_full;
+ m_prop_full.setLabel (m_mode_full ? "Aa" : "Aa");
+ m_prop_full.setIcon (m_mode_full ?
+ PKGDATADIR"/icons/full.svg" :
+ PKGDATADIR"/icons/half.svg");
+ updateProperty (m_prop_full);
+}
+
+void
+PinyinProperties::toggleModeFullPunct (void)
+{
+ m_mode_full_punct = !m_mode_full_punct;
+ m_prop_full_punct.setLabel (m_mode_full_punct ? ",。" : ",.");
+ m_prop_full_punct.setIcon (m_mode_full_punct ?
+ PKGDATADIR"/icons/full-punct.svg" :
+ PKGDATADIR"/icons/half-punct.svg");
+ updateProperty (m_prop_full_punct);
+}
+
+void
+PinyinProperties::toggleModeSimp (void)
+{
+ m_mode_simp = ! m_mode_simp;
+ m_prop_simp.setLabel (m_mode_simp ? "简" : "繁");
+ m_prop_simp.setIcon (m_mode_simp ?
+ PKGDATADIR"/icons/simp-chinese.svg" :
+ PKGDATADIR"/icons/trad-chinese.svg");
+ updateProperty (m_prop_simp);
+}
+
+gboolean
+PinyinProperties::propertyActivate (const gchar *prop_name, guint prop_state) {
+ const static StaticString mode_chinese ("mode.chinese");
+ const static StaticString mode_full ("mode.full");
+ const static StaticString mode_full_punct ("mode.full_punct");
+ const static StaticString mode_simp ("mode.simp");
+
+ if (mode_chinese == prop_name) {
+ toggleModeChinese ();
+ return TRUE;
+ }
+ else if (mode_full == prop_name) {
+ toggleModeFull ();
+ return TRUE;
+ }
+ else if (mode_full_punct == prop_name) {
+ toggleModeFullPunct ();
+ return TRUE;
+ }
+ else if (mode_simp == prop_name) {
+ toggleModeSimp ();
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+};
diff --git a/src/PinyinProperties.h b/src/PinyinProperties.h
new file mode 100644
index 0000000..0466ee8
--- /dev/null
+++ b/src/PinyinProperties.h
@@ -0,0 +1,58 @@
+#ifndef __PY_PINYIN_PROPERTIES_H_
+#define __PY_PINYIN_PROPERTIES_H_
+
+#include <ibus.h>
+#include <sigc++/sigc++.h>
+#include <libintl.h>
+#include "Text.h"
+#include "Property.h"
+#include "Config.h"
+
+#define _(text) (dgettext (GETTEXT_PACKAGE, text))
+
+namespace PY {
+
+class PinyinProperties {
+public:
+ PinyinProperties (void);
+
+ void toggleModeChinese (void);
+ void toggleModeFull (void);
+ void toggleModeFullPunct (void);
+ void toggleModeSimp (void);
+ gboolean propertyActivate (const gchar *prop_name, guint prop_state);
+
+ gboolean modeChinese (void) { return m_mode_chinese; }
+ gboolean modeFull (void) { return m_mode_full; }
+ gboolean modeFullPunct (void) { return m_mode_full_punct; }
+ gboolean modeSimp (void) { return m_mode_simp; }
+ PropList & properties (void) { return m_props; }
+
+ sigc::signal<void, Property &> signalUpdateProperty (void) {
+ return m_signal_update_property;
+ }
+
+private:
+ sigc::signal<void, Property &> m_signal_update_property;
+ void updateProperty (Property & prop) {
+ m_signal_update_property.emit (prop);
+ }
+
+private:
+ gboolean m_mode_chinese;
+ gboolean m_mode_full;
+ gboolean m_mode_full_punct;
+ gboolean m_mode_simp;
+
+ /* properties */
+ Property m_prop_chinese;
+ Property m_prop_full;
+ Property m_prop_full_punct;
+ Property m_prop_simp;
+ Property m_prop_setup;
+ PropList m_props;
+};
+
+};
+
+#endif
diff --git a/src/RawEditor.h b/src/RawEditor.h
index e6e3885..38a158f 100644
--- a/src/RawEditor.h
+++ b/src/RawEditor.h
@@ -3,83 +3,13 @@
#define __PY_RAW_EDITOR__
#include <glib.h>
-#include "String.h"
+#include "Editor.h"
namespace PY {
-class RawEditor {
+class RawEditor : public Editor {
public:
- RawEditor () : m_cursor (0) {}
-
- gboolean processKeyEvent (guint keyval, guint keycode, guint modifiers, gboolean &update) {
- update = FALSE;
- if (modifiers & IBUS_RELEASE_MASK)
- return FALSE;
-
- modifiers &= (IBUS_SHIFT_MASK |
- IBUS_CONTROL_MASK |
- IBUS_MOD1_MASK |
- IBUS_SUPER_MASK |
- IBUS_HYPER_MASK |
- IBUS_META_MASK);
- if (modifiers != 0)
- return TRUE;
-
- switch (keyval) {
- case IBUS_exclam ... IBUS_asciitilde:
- m_text.insert (m_cursor++, keyval);
- update = TRUE;
- return TRUE;
- case IBUS_BackSpace:
- if (m_cursor > 0) {
- m_text.erase (--m_cursor, 1);
- update = TRUE;
- return TRUE;
- }
- return FALSE;
- case IBUS_Delete:
- case IBUS_KP_Delete:
- if (m_cursor < m_text.length ()) {
- m_text.erase (m_cursor, 1);
- update = TRUE;
- return TRUE;
- }
- return FALSE;
- case IBUS_Left:
- case IBUS_KP_Left:
- if (m_cursor > 0) {
- m_cursor --;
- update = TRUE;
- return TRUE;
- }
- return FALSE;
- case IBUS_Right:
- case IBUS_KP_Right:
- if (m_cursor < m_text.length ()) {
- m_cursor ++;
- update = TRUE;
- return TRUE;
- }
- return FALSE;
- default:
- break;
- }
- return TRUE;
- }
-
- void reset (void) {
- m_text.truncate (0);
- m_cursor = 0;
- }
-
- guint cursor (void) const { return m_cursor; }
- operator const String & (void) const {
- return m_text;
- }
-
-protected:
- String m_text;
- guint m_cursor;
+ RawEditor (PinyinProperties &props) : Editor (props) {}
};
};
diff --git a/src/Text.h b/src/Text.h
index 91f5e99..35a0b8b 100644
--- a/src/Text.h
+++ b/src/Text.h
@@ -3,6 +3,7 @@
#include <ibus.h>
#include "Pointer.h"
+#include "String.h"
namespace PY {