1
/* vim:set et ts=4 sts=4:
3
* ibus-pinyin - The Chinese PinYin engine for IBus
5
* Copyright (c) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
6
* Copyright (c) 2010 BYVoid <byvoid1@gmail.com>
8
* This program is free software; you can redistribute it and/or modify
9
* it under the terms of the GNU General Public License as published by
10
* the Free Software Foundation; either version 2, or (at your option)
13
* This program is distributed in the hope that it will be useful,
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
* GNU General Public License for more details.
18
* You should have received a copy of the GNU General Public License
19
* along with this program; if not, write to the Free Software
20
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23
#include "PYPunctEditor.h"
27
#include "PYPunctTable.h"
29
PunctEditor::PunctEditor (PinyinProperties & props, Config & config)
30
: Editor (props, config),
31
m_punct_mode (MODE_DISABLE),
32
m_lookup_table (m_config.pageSize ())
37
PunctEditor::insert (gchar ch)
39
switch (m_punct_mode) {
42
g_assert (ch == IBUS_grave);
43
g_assert (m_cursor == 0);
44
m_text.insert (m_cursor++, ch);
45
m_punct_mode = MODE_INIT;
46
updatePunctCandidates (0);
47
m_selected_puncts.clear ();
48
m_selected_puncts.insert (m_selected_puncts.begin (), m_punct_candidates[0]);
55
m_selected_puncts.clear ();
60
m_text.insert (m_cursor, ch);
61
updatePunctCandidates (ch);
62
m_punct_mode = MODE_NORMAL;
63
if (m_punct_candidates.size () > 0) {
64
m_selected_puncts.insert (m_selected_puncts.begin () + m_cursor, m_punct_candidates[0]);
71
g_assert_not_reached ();
78
PunctEditor::processSpace (guint keyval, guint keycode, guint modifiers)
80
if (m_punct_mode != MODE_INIT && m_punct_mode != MODE_NORMAL)
82
if (cmshm_filter (modifiers) != 0)
89
PunctEditor::processPunct (guint keyval, guint keycode, guint modifiers)
91
if (cmshm_filter (modifiers) != 0)
94
if (m_punct_mode == MODE_DISABLE) {
95
if (keyval == IBUS_grave) {
101
g_assert (m_punct_mode == MODE_INIT || m_punct_mode == MODE_NORMAL);
104
case IBUS_grave: /* ` */
105
case IBUS_asciitilde: /* ~ */
106
case IBUS_exclam: /* ~ */
107
case IBUS_at: /* @ */
108
case IBUS_numbersign: /* # */
109
case IBUS_dollar: /* $ */
110
case IBUS_percent: /* % */
111
case IBUS_asciicircum: /* ^ */
112
case IBUS_ampersand: /* & */
113
case IBUS_asterisk: /* * */
114
case IBUS_parenleft: /* ( */
115
case IBUS_parenright: /* ) */
116
case IBUS_minus: /* - */
117
case IBUS_underscore: /* _ */
118
case IBUS_equal: /* = */
119
case IBUS_plus: /* + */
120
case IBUS_bracketleft: /* [ */
121
case IBUS_bracketright: /* ] */
122
case IBUS_braceleft: /* { */
123
case IBUS_braceright: /* } */
124
case IBUS_backslash: /* \ */
125
case IBUS_bar: /* | */
126
case IBUS_colon: /* : */
127
case IBUS_semicolon: /* ; */
128
case IBUS_apostrophe: /* ' */
129
case IBUS_quotedbl: /* " */
130
case IBUS_comma: /* , */
131
case IBUS_period: /* . */
132
case IBUS_less: /* < */
133
case IBUS_greater: /* > */
134
case IBUS_slash: /* / */
135
case IBUS_question: /* ? */
136
case IBUS_0...IBUS_9:
137
case IBUS_a...IBUS_z:
138
case IBUS_A...IBUS_Z:
139
return insert (keyval);
146
PunctEditor::processKeyEvent (guint keyval, guint keycode, guint modifiers)
148
modifiers &= (IBUS_SHIFT_MASK |
158
return processSpace (keyval, keycode, modifiers);
190
moveCursorToBegin ();
209
case IBUS_KP_Page_Up:
214
case IBUS_KP_Page_Down:
219
return processPunct(keyval, keycode, modifiers);
224
PunctEditor::pageUp (void)
226
if (G_LIKELY (m_lookup_table.pageUp ())) {
227
m_selected_puncts[m_cursor - 1] = m_punct_candidates[m_lookup_table.cursorPos ()];
228
updateLookupTableFast (m_lookup_table, TRUE);
229
updatePreeditText ();
230
updateAuxiliaryText ();
235
PunctEditor::pageDown (void)
237
if (G_LIKELY (m_lookup_table.pageDown ())) {
238
m_selected_puncts[m_cursor - 1] = m_punct_candidates[m_lookup_table.cursorPos ()];
239
updateLookupTableFast (m_lookup_table, TRUE);
240
updatePreeditText ();
241
updateAuxiliaryText ();
246
PunctEditor::cursorUp (void)
248
if (G_LIKELY (m_lookup_table.cursorUp ())) {
249
m_selected_puncts[m_cursor - 1] = m_punct_candidates[m_lookup_table.cursorPos ()];
250
updateLookupTableFast (m_lookup_table, TRUE);
251
updatePreeditText ();
252
updateAuxiliaryText ();
257
PunctEditor::cursorDown (void)
259
if (G_LIKELY (m_lookup_table.cursorDown ())) {
260
m_selected_puncts[m_cursor - 1] = m_punct_candidates[m_lookup_table.cursorPos ()];
261
updateLookupTableFast (m_lookup_table, TRUE);
262
updatePreeditText ();
263
updateAuxiliaryText ();
268
PunctEditor::moveCursorLeft (void)
270
if (G_UNLIKELY (m_cursor == 0))
274
m_punct_candidates.clear ();
278
updatePunctCandidates (m_text[m_cursor - 1]);
279
/* restore cursor pos */
280
std::vector<const gchar *>::iterator it;
281
it = std::find (m_punct_candidates.begin (),
282
m_punct_candidates.end (),
283
m_selected_puncts[m_cursor - 1]);
284
g_assert (it != m_punct_candidates.end ());
285
m_lookup_table.setCursorPos (it - m_punct_candidates.begin ());
292
PunctEditor::moveCursorRight (void)
294
if (G_UNLIKELY (m_cursor == m_text.length ()))
297
updatePunctCandidates (m_text[m_cursor - 1]);
299
/* restore cursor pos */
300
std::vector<const gchar *>::iterator it;
301
it = std::find (m_punct_candidates.begin (),
302
m_punct_candidates.end (),
303
m_selected_puncts[m_cursor - 1]);
304
g_assert (it != m_punct_candidates.end ());
305
m_lookup_table.setCursorPos (it - m_punct_candidates.begin ());
312
PunctEditor::moveCursorToBegin (void)
314
if (G_UNLIKELY (m_cursor == 0))
317
g_assert (m_punct_mode == MODE_NORMAL);
319
m_punct_candidates.clear ();
327
PunctEditor::moveCursorToEnd (void)
329
if (G_UNLIKELY (m_cursor == m_text.length ()))
332
g_assert (m_punct_mode == MODE_NORMAL);
333
m_cursor = m_text.length ();
334
updatePunctCandidates (m_text[m_cursor - 1]);
336
/* restore cursor pos */
337
std::vector<const gchar *>::iterator it;
338
it = std::find (m_punct_candidates.begin (),
339
m_punct_candidates.end (),
340
m_selected_puncts[m_cursor - 1]);
341
g_assert (it != m_punct_candidates.end ());
342
m_lookup_table.setCursorPos (it - m_punct_candidates.begin ());
349
PunctEditor::removeCharBefore (void)
351
if (G_UNLIKELY (m_cursor == 0))
355
m_selected_puncts.erase (m_selected_puncts.begin () + m_cursor);
356
m_text.erase (m_cursor, 1);
357
if (m_text.empty()) {
363
updatePunctCandidates (m_text[m_cursor - 1]);
364
/* restore cursor pos */
365
std::vector<const gchar *>::iterator it;
366
it = std::find (m_punct_candidates.begin (),
367
m_punct_candidates.end (),
368
m_selected_puncts[m_cursor - 1]);
369
g_assert (it != m_punct_candidates.end ());
370
m_lookup_table.setCursorPos (it - m_punct_candidates.begin ());
373
m_punct_candidates.clear ();
384
PunctEditor::removeCharAfter (void)
386
if (G_UNLIKELY (m_cursor == m_text.length ()))
388
m_selected_puncts.erase (m_selected_puncts.begin () + m_cursor);
389
m_text.erase (m_cursor, 1);
390
if (m_text.empty()) {
400
PunctEditor::reset (void)
402
m_punct_mode = MODE_DISABLE;
403
m_selected_puncts.clear ();
404
m_punct_candidates.clear ();
410
PunctEditor::candidateClicked (guint index, guint button, guint state)
412
selectCandidateInPage(index);
416
PunctEditor::commit (const gchar *str)
418
StaticText text(str);
424
PunctEditor::commit (void)
427
for (std::vector<const gchar *>::iterator it = m_selected_puncts.begin ();
428
it != m_selected_puncts.end (); it++) {
436
PunctEditor::selectCandidate (guint i)
438
switch (m_punct_mode) {
441
g_assert (m_cursor == 1);
442
m_lookup_table.setCursorPos (i);
443
m_selected_puncts[m_cursor - 1] = m_punct_candidates[i];
449
m_lookup_table.setCursorPos (i);
450
m_selected_puncts[m_cursor - 1] = m_punct_candidates[i];
452
/* if it is the last punct, commit the result */
453
if (m_cursor == m_text.length ()) {
462
g_assert_not_reached ();
469
PunctEditor::selectCandidateInPage (guint i)
471
guint page_size = m_lookup_table.pageSize ();
472
guint cursor_pos = m_lookup_table.cursorPos ();
474
if (G_UNLIKELY (i >= page_size))
477
i += (cursor_pos / page_size) * page_size;
479
return selectCandidate (i);
483
PunctEditor::update (void)
485
updateLookupTable ();
486
updatePreeditText ();
487
updateAuxiliaryText ();
491
PunctEditor::fillLookupTable (void)
493
m_lookup_table.clear ();
494
m_lookup_table.setPageSize (m_config.pageSize ());
495
m_lookup_table.setOrientation (m_config.orientation ());
497
for (std::vector<const gchar *>::iterator it = m_punct_candidates.begin ();
498
it != m_punct_candidates.end (); it++) {
499
StaticText text (*it);
500
// text.appendAttribute (IBUS_ATTR_TYPE_FOREGROUND, 0x004466, 0, -1);
501
m_lookup_table.appendCandidate (text);
506
PunctEditor::updateLookupTable (void)
508
if (m_lookup_table.size ()) {
509
Editor::updateLookupTable (m_lookup_table, TRUE);
517
punct_cmp (const void *p1, const void *p2)
519
const gint s1 = (gint)(glong) p1;
520
const gchar *s2 = **(gchar ***) p2;
525
PunctEditor::updatePunctCandidates (gchar ch)
530
m_punct_candidates.clear();
532
brs = (const gchar ***) std::bsearch ((void *) ch,
534
G_N_ELEMENTS (punct_table),
535
sizeof(punct_table[0]),
538
for (res = (*brs) + 1; *res != NULL; ++res) {
539
m_punct_candidates.push_back (*res);
546
PunctEditor::updateAuxiliaryText (void)
548
switch (m_punct_mode) {
550
hideAuxiliaryText ();
555
StaticText aux_text (m_buffer);
556
Editor::updateAuxiliaryText (aux_text, TRUE);
562
hideAuxiliaryText ();
566
for (String::iterator i = m_text.begin (); i != m_text.end (); ++i) {
567
if (i - m_text.begin () == (gint) m_cursor)
571
if (m_text.end () - m_text.begin () == (gint) m_cursor)
574
StaticText aux_text (m_buffer);
575
Editor::updateAuxiliaryText (aux_text, TRUE);
580
g_assert_not_reached ();
585
PunctEditor::updatePreeditText (void)
587
switch (m_punct_mode) {
593
m_buffer = m_punct_candidates[m_lookup_table.cursorPos ()];
594
StaticText preedit_text (m_buffer);
596
preedit_text.appendAttribute (IBUS_ATTR_TYPE_UNDERLINE, IBUS_ATTR_UNDERLINE_SINGLE, 0, -1);
597
Editor::updatePreeditText (preedit_text, m_cursor, TRUE);
603
for (std::vector<const gchar *>::iterator it = m_selected_puncts.begin ();
604
it != m_selected_puncts.end (); it++) {
607
StaticText preedit_text (m_buffer);
609
preedit_text.appendAttribute (IBUS_ATTR_TYPE_UNDERLINE, IBUS_ATTR_UNDERLINE_SINGLE, 0, -1);
610
Editor::updatePreeditText (preedit_text, m_cursor, TRUE);
614
g_assert_not_reached ();