/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* Copyright (C) 2005 Takuro Ashie
* Copyright (C) 2012 CSSlayer
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <string.h>
#include "kana.h"
#include "factory.h"
#include "imengine.h"
#include "default_tables.h"
#include "utils.h"
static bool
has_voiced_consonant (std::string str)
{
VoicedConsonantRule *table = fcitx_anthy_voiced_consonant_table;
for (unsigned int i = 0; table[i].string; i++) {
if (!strcmp (str.c_str (), table[i].string) &&
table[i].voiced && *table[i].voiced)
{
return true;
}
}
return false;
}
static bool
has_half_voiced_consonant (std::string str)
{
VoicedConsonantRule *table = fcitx_anthy_voiced_consonant_table;
for (unsigned int i = 0; table[i].string; i++) {
if (!strcmp (str.c_str (), table[i].string) &&
table[i].half_voiced && *table[i].half_voiced)
{
return true;
}
}
return false;
}
std::string
to_voiced_consonant (std::string str)
{
VoicedConsonantRule *table = fcitx_anthy_voiced_consonant_table;
for (unsigned int i = 0; table[i].string; i++) {
if (!strcmp (str.c_str (), table[i].string))
return std::string (table[i].voiced);
}
return str;
}
std::string
to_half_voiced_consonant (std::string str)
{
VoicedConsonantRule *table = fcitx_anthy_voiced_consonant_table;
for (unsigned int i = 0; table[i].string; i++) {
if (!strcmp (str.c_str (), table[i].string))
return std::string (table[i].half_voiced);
}
return str;
}
KanaConvertor::KanaConvertor (AnthyInstance &anthy)
: m_anthy (anthy)
{
}
KanaConvertor::~KanaConvertor ()
{
}
bool
KanaConvertor::can_append (const KeyEvent & key,
bool ignore_space)
{
// ignore key release.
if (key.is_release)
return false;
// ignore short cut keys of apllication.
if ((key.state & FcitxKeyState_Ctrl) ||
(key.state & FcitxKeyState_Alt) ||
(key.state & FcitxKeyState_Super))
{
return false;
}
if (key.sym == FcitxKey_overline ||
(key.sym >= FcitxKey_kana_fullstop &&
key.sym <= FcitxKey_semivoicedsound))
{
return true;
}
#if 0
if (key.code == SCIM_KEY_KP_Equal ||
(key.code >= SCIM_KEY_KP_Multiply &&
key.code <= SCIM_KEY_KP_9))
{
return true;
}
#endif
return false;
}
bool
KanaConvertor::append (const KeyEvent & key,
std::string & result,
std::string & pending,
std::string &raw)
{
KeyCodeToCharRule *table = fcitx_anthy_keypad_table;
// handle keypad code
if (key.sym == FcitxKey_KP_Equal ||
(key.sym >= FcitxKey_KP_Multiply &&
key.sym <= FcitxKey_KP_9))
{
TenKeyType ten_key_type = m_anthy.get_config()->m_ten_key_type;
for (unsigned int i = 0; table[i].code; i++) {
if (table[i].code == key.sym) {
if (ten_key_type == FCITX_ANTHY_TEN_KEY_TYPE_WIDE)
util_convert_to_wide (result, table[i].kana);
else
result = table[i].kana;
raw = table[i].kana;
return false;
}
}
}
table = fcitx_anthy_kana_table;
// handle voiced sound
if (key.sym == FcitxKey_voicedsound &&
!m_pending.empty () && has_voiced_consonant (m_pending))
{
result = to_voiced_consonant (m_pending);
raw = key.get_ascii_code ();
m_pending = std::string ();
return false;
}
// handle semi voiced sound
if (key.sym == FcitxKey_semivoicedsound &&
!m_pending.empty () && has_half_voiced_consonant (m_pending))
{
result = to_half_voiced_consonant (m_pending);
raw = key.get_ascii_code ();
m_pending = std::string ();
return false;
}
// kana key code
for (unsigned int i = 0; table[i].code; i++) {
if (table[i].code == key.sym) {
bool retval = m_pending.empty () ? false : true;
if (has_voiced_consonant (table[i].kana)) {
result = std::string ();
pending = table[i].kana;
m_pending = table[i].kana;
} else {
result = table[i].kana;
m_pending = std::string ();
}
raw = key.get_ascii_code ();
return retval;
}
}
std::string s;
s += key.get_ascii_code ();
raw = s;
return append (raw, result, pending);
}
bool
KanaConvertor::append (const std::string & str,
std::string & result,
std::string & pending)
{
result = str;
m_pending = std::string ();
return false;
}
void
KanaConvertor::clear (void)
{
m_pending = std::string ();
}
bool
KanaConvertor::is_pending (void)
{
return !m_pending.empty ();
}
std::string
KanaConvertor::get_pending (void)
{
return std::string (m_pending);
}
std::string
KanaConvertor::flush_pending (void)
{
return std::string ();
}
void
KanaConvertor::reset_pending (const std::string &result, const std::string &raw)
{
m_pending = std::string ();
if (has_voiced_consonant (result))
m_pending = result;
}
/*
vi:ts=4:nowrap:ai:expandtab
*/