1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * Copyright (C) 2004-2005 Takuro Ashie
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 #include "scim_anthy_factory.h"
27 #include "scim_anthy_imengine.h"
28 #include "scim_anthy_preedit.h"
29 #include "scim_anthy_utils.h"
31 using namespace scim_anthy;
33 static ConvRule *get_period_rule (TypingMethod method,
35 static ConvRule *get_comma_rule (TypingMethod method,
38 Preedit::Preedit (AnthyInstance &anthy)
40 //m_key2kana_tables (tables),
42 m_conversion (m_anthy, m_reading),
43 m_input_mode (SCIM_ANTHY_MODE_HIRAGANA)
56 Preedit::get_length (void)
59 return m_conversion.get_length ();
61 return m_reading.get_length ();
67 Preedit::get_string (void)
69 if (is_converting ()) {
70 return m_conversion.get ();
71 } else if (!m_source.empty ()) {
75 switch (m_input_mode) {
76 case SCIM_ANTHY_MODE_KATAKANA:
77 util_convert_to_katakana (widestr, m_reading.get ());
80 case SCIM_ANTHY_MODE_HALF_KATAKANA:
81 util_convert_to_katakana (widestr, m_reading.get (), true);
84 case SCIM_ANTHY_MODE_LATIN:
85 return utf8_mbstowcs (m_reading.get_raw ());
87 case SCIM_ANTHY_MODE_WIDE_LATIN:
88 util_convert_to_wide (widestr, m_reading.get_raw ());
91 case SCIM_ANTHY_MODE_HIRAGANA:
93 return m_reading.get ();
101 Preedit::get_attribute_list (void)
103 if (is_converting ())
105 return m_conversion.get_attribute_list ();
108 util_create_attributes (attrs, 0, get_length (),
109 m_anthy.get_factory()->m_preedit_style,
110 m_anthy.get_factory()->m_preedit_fg_color,
111 m_anthy.get_factory()->m_preedit_bg_color);
117 Preedit::get_reading (void)
123 Preedit::is_preediting (void)
125 if (m_reading.get_length () > 0 ||
126 m_conversion.is_converting () ||
136 Preedit::is_converting (void)
138 return m_conversion.is_converting ();
142 Preedit::is_predicting (void)
144 return m_conversion.is_predicting ();
148 Preedit::is_reconverting (void)
150 return !m_source.empty ();
155 * manipulating the preedit string
158 Preedit::can_process_key_event (const KeyEvent & key)
160 return m_reading.can_process_key_event (key);
164 Preedit::process_key_event (const KeyEvent & key)
166 if (!m_reading.can_process_key_event (key))
169 bool retval = m_reading.process_key_event (key);
171 if (m_input_mode == SCIM_ANTHY_MODE_LATIN ||
172 m_input_mode == SCIM_ANTHY_MODE_WIDE_LATIN)
178 unsigned int len = m_reading.get_length ();
181 str = m_reading.get_raw (len - 1, 1);
182 if (is_comma_or_period (str)) {
183 if (m_anthy.get_factory()->m_behavior_on_period == "Convert" &&
187 } else if (m_anthy.get_factory()->m_behavior_on_period == "Commit") {
197 Preedit::append (const KeyEvent & key,
198 const String & string)
200 return m_reading.append (key, string);
204 Preedit::erase (bool backward)
206 if (m_reading.get_length () <= 0)
213 TypingMethod method = get_typing_method ();
215 = method == SCIM_ANTHY_TYPING_METHOD_ROMAJI &&
216 m_anthy.get_factory()->m_romaji_allow_split;
217 if (backward && m_reading.get_caret_pos () == 0)
219 if (!backward && m_reading.get_caret_pos () >= m_reading.get_length ())
222 m_reading.move_caret (-1, allow_split);
223 m_reading.erase (m_reading.get_caret_pos (), 1, allow_split);
227 Preedit::finish (void)
234 * manipulating conversion string
237 Preedit::convert (CandidateType type, bool single_segment)
239 if (m_source.empty ())
240 m_conversion.convert (type, single_segment);
242 m_conversion.convert (m_source, single_segment);
246 Preedit::convert (const WideString &source, bool single_segment)
248 m_conversion.convert (source, single_segment);
253 Preedit::revert (void)
255 m_conversion.clear ();
259 Preedit::commit (int segment_id, bool learn)
261 if (m_conversion.is_converting ())
262 m_conversion.commit (segment_id, learn);
263 if (!m_conversion.is_converting ())
268 Preedit::get_nr_segments (void)
270 return m_conversion.get_nr_segments ();
274 Preedit::get_segment_string (int segment_id)
276 return m_conversion.get_segment_string (segment_id);
280 Preedit::get_selected_segment (void)
282 return m_conversion.get_selected_segment ();
286 Preedit::select_segment (int segment_id)
288 m_conversion.select_segment (segment_id);
292 Preedit::get_segment_size (int segment_id)
294 return m_conversion.get_segment_size (segment_id);
298 Preedit::resize_segment (int relative_size, int segment_id)
300 m_conversion.resize_segment (relative_size, segment_id);
305 * candidates for a segment
308 Preedit::get_candidates (CommonLookupTable &table, int segment_id)
310 m_conversion.get_candidates (table, segment_id);
314 Preedit::get_selected_candidate (int segment_id)
316 return m_conversion.get_selected_candidate (segment_id);
320 Preedit::select_candidate (int candidate_id, int segment_id)
322 m_conversion.select_candidate (candidate_id, segment_id);
327 * manipulating the caret
330 Preedit::get_caret_pos (void)
332 if (is_converting ()) {
333 return m_conversion.get_segment_position ();
335 if (get_input_mode () == SCIM_ANTHY_MODE_HALF_KATAKANA) {
336 // FIXME! It's ad-hoc
338 substr = m_reading.get (0, m_reading.get_caret_pos (),
339 SCIM_ANTHY_STRING_HALF_KATAKANA);
340 return substr.length ();
342 return m_reading.get_caret_pos ();
348 Preedit::set_caret_pos (unsigned int pos)
350 if (is_converting ())
353 m_reading.set_caret_pos (pos);
357 Preedit::move_caret (int step)
359 if (is_converting ())
362 TypingMethod method = get_typing_method ();
364 = method == SCIM_ANTHY_TYPING_METHOD_ROMAJI &&
365 m_anthy.get_factory()->m_romaji_allow_split;
367 m_reading.move_caret (step, allow_split);
371 Preedit::predict (void)
373 m_conversion.predict ();
381 Preedit::clear (int segment_id)
383 // FIXME! We should add implementation not only for conversion string but
384 // also for reading string.
386 if (!is_converting ()) {
388 m_conversion.clear ();
389 m_source = WideString ();
393 m_conversion.clear (segment_id);
394 if (m_conversion.get_nr_segments () <= 0) {
396 m_source = WideString ();
405 Preedit::set_input_mode (InputMode mode)
411 Preedit::get_input_mode (void)
417 Preedit::set_typing_method (TypingMethod method)
419 m_reading.set_typing_method (method);
423 Preedit::get_typing_method (void)
425 return m_reading.get_typing_method ();
429 Preedit::set_period_style (PeriodStyle style)
431 m_reading.set_period_style (style);
435 Preedit::get_period_style (void)
437 return m_reading.get_period_style ();
441 Preedit::set_comma_style (CommaStyle style)
443 m_reading.set_comma_style (style);
447 Preedit::get_comma_style (void)
449 return m_reading.get_comma_style ();
453 Preedit::set_bracket_style (BracketStyle style)
455 m_reading.set_bracket_style (style);
459 Preedit::get_bracket_style (void)
461 return m_reading.get_bracket_style ();
465 Preedit::set_slash_style (SlashStyle style)
467 m_reading.set_slash_style (style);
471 Preedit::get_slash_style (void)
473 return m_reading.get_slash_style ();
477 Preedit::set_symbol_width (bool half)
479 m_reading.set_symbol_width (half);
483 Preedit::get_symbol_width (void)
485 return m_reading.get_symbol_width ();
489 Preedit::set_number_width (bool half)
491 m_reading.set_number_width (half);
495 Preedit::get_number_width (void)
497 return m_reading.get_number_width ();
501 Preedit::set_pseudo_ascii_mode (int mode)
503 m_reading.set_pseudo_ascii_mode (mode);
507 Preedit::is_pseudo_ascii_mode (void)
509 return m_reading.is_pseudo_ascii_mode ();
513 Preedit::reset_pseudo_ascii_mode (void)
515 m_reading.reset_pseudo_ascii_mode ();
519 Preedit::set_dict_encoding (String type)
521 m_conversion.set_dict_encoding (type);
525 Preedit::is_comma_or_period (const String & str)
527 TypingMethod typing = get_typing_method ();
528 PeriodStyle period = get_period_style ();
529 CommaStyle comma = get_comma_style ();
531 ConvRule *period_rule = get_period_rule (typing, period);
532 ConvRule *comma_rule = get_comma_rule (typing, comma);
534 for (unsigned int i = 0; period_rule && period_rule[i].string; i++) {
535 if (period_rule[i].string &&
536 !strcmp (period_rule[i].string, str.c_str ()))
541 for (unsigned int i = 0; comma_rule && comma_rule[i].string; i++) {
542 if (comma_rule[i].string &&
543 !strcmp (comma_rule[i].string, str.c_str ()))
557 get_period_rule (TypingMethod method, PeriodStyle period)
560 case SCIM_ANTHY_TYPING_METHOD_KANA:
562 case SCIM_ANTHY_PERIOD_WIDE:
563 return scim_anthy_kana_wide_period_rule;
564 case SCIM_ANTHY_PERIOD_HALF:
565 return scim_anthy_kana_half_period_rule;
566 case SCIM_ANTHY_PERIOD_JAPANESE:
568 return scim_anthy_kana_ja_period_rule;
572 case SCIM_ANTHY_TYPING_METHOD_ROMAJI:
575 case SCIM_ANTHY_PERIOD_WIDE:
576 return scim_anthy_romaji_wide_period_rule;
577 case SCIM_ANTHY_PERIOD_HALF:
578 return scim_anthy_romaji_half_period_rule;
579 case SCIM_ANTHY_PERIOD_JAPANESE:
581 return scim_anthy_romaji_ja_period_rule;
590 get_comma_rule (TypingMethod method, CommaStyle period)
593 case SCIM_ANTHY_TYPING_METHOD_KANA:
595 case SCIM_ANTHY_PERIOD_WIDE:
596 return scim_anthy_kana_wide_comma_rule;
597 case SCIM_ANTHY_PERIOD_HALF:
598 return scim_anthy_kana_half_comma_rule;
599 case SCIM_ANTHY_PERIOD_JAPANESE:
601 return scim_anthy_kana_ja_comma_rule;
605 case SCIM_ANTHY_TYPING_METHOD_ROMAJI:
608 case SCIM_ANTHY_PERIOD_WIDE:
609 return scim_anthy_romaji_wide_comma_rule;
610 case SCIM_ANTHY_PERIOD_HALF:
611 return scim_anthy_romaji_half_comma_rule;
612 case SCIM_ANTHY_PERIOD_JAPANESE:
614 return scim_anthy_romaji_ja_comma_rule;
622 vi:ts=4:nowrap:ai:expandtab