t-suw****@users*****
t-suw****@users*****
2007年 10月 5日 (金) 23:58:30 JST
Index: AquaSKK/src/statemachine/GenericStateMachine.h diff -u AquaSKK/src/statemachine/GenericStateMachine.h:1.1.2.3 AquaSKK/src/statemachine/GenericStateMachine.h:1.1.2.4 --- AquaSKK/src/statemachine/GenericStateMachine.h:1.1.2.3 Sun Sep 23 23:48:08 2007 +++ AquaSKK/src/statemachine/GenericStateMachine.h Fri Oct 5 23:58:29 2007 @@ -40,6 +40,7 @@ #include <cassert> #include <vector> #include <list> +#include <queue> #include <algorithm> #include <functional> @@ -100,7 +101,8 @@ DEEP_HISTORY, FORWARD, DEEP_FORWARD, - DEFER_EVENT + DEFER_EVENT, + CLEAR_HISTORY }; StateType type_; @@ -123,6 +125,7 @@ bool IsForward() const { return type_ == FORWARD; } bool IsDeepForward() const { return type_ == DEEP_FORWARD; } bool IsDeferEvent() const { return type_ == DEFER_EVENT; } + bool IsClearHistory() const { return type_ == CLEAR_HISTORY; } static GenericState Initial(Handler handler) { return GenericState(INITIAL, handler); } static GenericState Transition(Handler handler) { return GenericState(TRANSITION, handler); } @@ -132,6 +135,7 @@ static GenericState Forward(Handler handler) { return GenericState(FORWARD, handler); } static GenericState DeepForward(Handler handler) { return GenericState(DEEP_FORWARD, handler); } static GenericState DeferEvent() { return GenericState(DEFER_EVENT, 0); } + static GenericState ClearHistory() { return GenericState(CLEAR_HISTORY, 0); } }; // ====================================================================== @@ -139,45 +143,65 @@ // ====================================================================== template <typename Handler> class GenericStateHistory { - typedef std::pair<Handler, Handler> History; - std::vector<Handler> keys_; - std::vector<History> values_; + typedef std::pair<Handler, Handler> ShallowDeepPair; + typedef std::pair<Handler, ShallowDeepPair> Entry; + typedef std::list<Entry> History; + typedef typename History::iterator HistoryIterator; + + History history_; enum HistoryTypes { SHALLOW, DEEP }; - int lookup(const Handler key) const { - typename std::vector<Handler>::const_iterator iter = std::find(keys_.begin(), keys_.end(), key); + class Equal : public std::unary_function<Entry, bool> { + Handler key_; + + public: + Equal(const Handler arg) : key_(arg) {} - if(iter == keys_.end()) return -1; + bool operator()(const Entry& entry) const { + return key_ == entry.first; + } + }; - return iter - keys_.begin(); + HistoryIterator lookup(const Handler key) { + return std::find_if(history_.begin(), history_.end(), Equal(key)); } - const Handler get(Handler key, HistoryTypes type) const { - int pos = lookup(key); + const Handler get(const Handler key, HistoryTypes type) { + HistoryIterator iter = lookup(key); - if(pos < 0) return 0; + if(iter == history_.end()) return 0; - return type == SHALLOW ? values_[pos].first : values_[pos].second; + ShallowDeepPair& pair = iter->second; + + return type == SHALLOW ? pair.first : pair.second; } public: - void Save(Handler key, Handler shallow, Handler deep) { - int pos = lookup(key); + void Save(const Handler key, const Handler shallow, const Handler deep) { + HistoryIterator iter = lookup(key); + ShallowDeepPair pair = std::make_pair(shallow, deep); - if(pos < 0) { - keys_.push_back(key); - values_.push_back(std::make_pair(shallow, deep)); + if(iter != history_.end()) { + iter->second = pair; } else { - values_[pos] = std::make_pair(shallow, deep); + history_.push_front(std::make_pair(key, pair)); } } - const Handler Shallow(Handler key) const { + void Clear(const Handler key) { + HistoryIterator iter = lookup(key); + + if(iter != history_.end()) { + history_.erase(iter); + } + } + + const Handler Shallow(const Handler key) { return get(key, SHALLOW); } - const Handler Deep(Handler key) const { + const Handler Deep(const Handler key) { return get(key, DEEP); } }; @@ -187,34 +211,64 @@ // ====================================================================== template <typename Handler, typename Event> class GenericDeferEvent { - typedef std::pair<Handler, Event> Entry; - std::list<Entry> queue_; + typedef std::queue<Event> Defer; + typedef std::pair<Handler, Defer> Entry; + typedef std::list<Entry> Queue; + typedef typename Queue::iterator QueueIterator; + + Queue arrival_; + Queue departure_; + + class Equal : public std::unary_function<Entry, bool> { + const Handler key_; + + public: + Equal(Handler arg) : key_(arg) {} - struct NotEqual : public std::unary_function<Entry, bool> { - const Handler key; - NotEqual(Handler arg) : key(arg) {} bool operator()(const Entry& entry) const { - return key != entry.first; + return key_ == entry.first; } }; + QueueIterator find(const Handler key, Queue& queue) { + return std::find_if(queue.begin(), queue.end(), Equal(key)); + } + public: void Enqueue(const Handler key, const Event& event) { - queue_.push_back(std::make_pair(key, event)); + QueueIterator iter = find(key, arrival_); + + if(iter == arrival_.end()) { + arrival_.push_front(std::make_pair(key, Defer())); + iter = arrival_.begin(); + } + + iter->second.push(event); } - bool Dequeue(const Handler key, Event& event) { - if(queue_.empty()) return false; + void Transfer(const Handler key) { + QueueIterator iter = find(key, arrival_); + + if(iter != arrival_.end()) { + departure_.push_front(*iter); + arrival_.erase(iter); + } + } - typename std::list<Entry>::iterator iter = std::find_if(queue_.begin(), queue_.end(), NotEqual(key)); + bool Dequeue(const Handler key, Event& event) { + QueueIterator iter = find(key, departure_); - if(iter != queue_.end()) { - event = iter->second; - queue_.erase(iter); - return true; - } + if(iter == departure_.end()) return false; + + if(iter->second.empty()) { + departure_.erase(iter); + return false; + } + + event = iter->second.front(); + iter->second.pop(); - return false; + return true; } }; @@ -229,7 +283,9 @@ // ====================================================================== // state machine // ====================================================================== - template <typename StateContainer, template <typename Handler, typename Event> class Inspector = EmptyInspector> + template <typename StateContainer, + template <typename Handler, typename Event> + class Inspector = EmptyInspector> class GenericStateMachine { public: typedef typename StateContainer::State State; @@ -244,6 +300,7 @@ Handler top_; Handler active_; Handler prior_; + int selfTransitionCount_; GenericStateHistory<Handler> history_; GenericDeferEvent<Handler, Event> queue_; @@ -277,6 +334,8 @@ history_.Save(handler, prior_, active_); } + queue_.Transfer(handler); + prior_ = handler; return result; @@ -330,10 +389,12 @@ // exit to LCA(Least Common Ancestor) and record the path to the target do { + path_.clear(); path_.push_back(target); // (a) self transition if(source == target) { + assert(++ selfTransitionCount_ < 3 && "*** Too many self transitions. ***"); exitAction(source); break; } @@ -428,9 +489,20 @@ State next; + selfTransitionCount_ = 0; for(Handler source = active_; source != 0; source = next) { next = invoke(source, event); + if(next.IsDeferEvent()) { + queue_.Enqueue(source, event); + break; + } + + if(next.IsClearHistory()) { + history_.Clear(source); + break; + } + if(next.IsTransition() || next.IsDeepHistory() || next.IsForward() || next.IsDeepForward()) { if(next.IsDeepHistory() || next.IsDeepForward()) { next = history_.Deep(next); @@ -442,16 +514,11 @@ if(next.IsForward() || next.IsDeepForward()) { continue; - } else { - while(queue_.Dequeue(next, defer_)) { - Dispatch(defer_); // recursion - } } - break; - } - if(next.IsDeferEvent()) { - queue_.Enqueue(next, event); + while(queue_.Dequeue(source, defer_)) { + Dispatch(defer_); // recursion + } break; } @@ -460,6 +527,10 @@ } } + const Handler CurrentState() const { + return active_; + } + const Output& Result() const { return container_.Result(); } Index: AquaSKK/src/statemachine/SKKEngine.h diff -u AquaSKK/src/statemachine/SKKEngine.h:1.1.2.2 AquaSKK/src/statemachine/SKKEngine.h:1.1.2.3 --- AquaSKK/src/statemachine/SKKEngine.h:1.1.2.2 Sun Sep 23 23:48:08 2007 +++ AquaSKK/src/statemachine/SKKEngine.h Fri Oct 5 23:58:29 2007 @@ -1,5 +1,5 @@ /* -*- C++ -*- - $Id: SKKEngine.h,v 1.1.2.2 2007/09/23 14:48:08 t-suwa Exp $ + $Id: SKKEngine.h,v 1.1.2.3 2007/10/05 14:58:29 t-suwa Exp $ MacOS X implementation of the SKK input method. @@ -24,17 +24,20 @@ #define INC__SKKEngine__ #include <iostream> -#include "SKKEnvironment.h" +#include "SKKState.h" template <typename Handler, typename Event> struct DebugInspector { public: void operator()(const Handler handler, const Event& event) { -#define DEFINE_State(arg) { &SKKEnvironment::arg, #arg } + if(event == 0) return; + const static struct { Handler handler; const char* name; } states[] = { +#define DEFINE_State(arg) { &SKKState::arg, "SKKState::" #arg } + DEFINE_State(Direct), DEFINE_State(KanaInput), DEFINE_State(Hirakana), DEFINE_State(Katakana), @@ -44,36 +47,34 @@ DEFINE_State(Jisx0208Latin), DEFINE_State(Compose), DEFINE_State(EntryInput), - DEFINE_State(Japanese), - DEFINE_State(Okuri), - DEFINE_State(Abbreviation), + DEFINE_State(KanaEntry), + DEFINE_State(OkuriEntry), + DEFINE_State(AsciiEntry), DEFINE_State(EntryCompletion), DEFINE_State(SelectCandidate), DEFINE_State(Inline), DEFINE_State(Window), DEFINE_State(EntryRemove), +#undef DEFINE_State(arg) { 0, 0x00 } }; -#undef DEFINE_State(arg) - static char* system_event[] = { "<<EXIT>>", "<<INIT>>", "<<ENTRY>>" }; + static char* system_event[] = { "PROBE", "<<ENTRY>>", "<<INIT>>", "<<EXIT>>" }; - if(event != 0) { - for(int i = 0; states[i].handler != 0; ++ i) { - if(handler == states[i].handler) { - std::cerr << "SKKEnvironment::" << states[i].name << ": "; - if(event < 0) { - std::cerr << system_event[event + 3] << std::endl; - } else { - std::cerr << event.Param().dump() << std::endl; - } - break; + for(int i = 0; states[i].handler != 0; ++ i) { + if(handler == states[i].handler) { + std::cerr << states[i].name << ", "; + if(event < 0) { + std::cerr << system_event[abs(event)] << std::endl; + } else { + std::cerr << event.Param().dump() << std::endl; } + break; } } } }; -typedef GenericStateMachine<SKKEnvironment, DebugInspector> SKKEngine; +typedef GenericStateMachine<SKKState, DebugInspector> SKKEngine; #endif Index: AquaSKK/src/statemachine/SKKEnvironment.cpp diff -u AquaSKK/src/statemachine/SKKEnvironment.cpp:1.1.2.3 AquaSKK/src/statemachine/SKKEnvironment.cpp:removed --- AquaSKK/src/statemachine/SKKEnvironment.cpp:1.1.2.3 Mon Sep 24 18:23:33 2007 +++ AquaSKK/src/statemachine/SKKEnvironment.cpp Fri Oct 5 23:58:29 2007 @@ -1,452 +0,0 @@ -/* -*- C++ -*- - MacOS X implementation of the SKK input method. - - Copyright (C) 2007 Tomotaka SUWA <t.suw****@mac*****> - - 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 of the License, or - 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, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include "SKKEnvironment.h" -#include "SKKController.h" - -typedef SKKEnvironment::Event Event; -typedef SKKEnvironment::State State; -typedef SKKEnvironment::Output Output; - -SKKEnvironment::SKKEnvironment() { - controller_ = new SKKController(); -} - -SKKEnvironment::~SKKEnvironment() { - delete controller_; -} - -// ====================================================================== -// level 1ï¼ããªå ¥å -// ====================================================================== -State SKKEnvironment::KanaInput(const Event& event) { - const SKKEventParam& param = event.Param(); - - switch(event) { - case ENTRY_EVENT: - controller_->ChangeState(SKK::DirectInput); - return 0; - - case INIT_EVENT: - return State::ShallowHistory(&SKKEnvironment::Hirakana); - - case EXIT_EVENT: - return State::SaveHistory(); - - case SKK_JMODE: - return controller_->HandleJmode(); - - case SKK_ENTER: - return controller_->HandleEnter(); - - case SKK_BACKSPACE: - return controller_->HandleBackSpace(); - - case SKK_DELETE: - return controller_->HandleDelete(); - - case SKK_CANCEL: - return controller_->HandleCancel(); - - case SKK_PASTE: - return controller_->HandlePaste(); - - case SKK_LEFT: - return controller_->HandleCursorLeft(); - - case SKK_RIGHT: - return controller_->HandleCursorRight(); - - case SKK_UP: - return controller_->HandleCursorUp(); - - case SKK_DOWN: - return controller_->HandleCursorDown(); - - case SKK_ASCII: - return State::Transition(&SKKEnvironment::Ascii); - - case SKK_JISX0208LATIN: - return State::Transition(&SKKEnvironment::Jisx0208Latin); - - case SKK_CHAR: - return controller_->HandleInput(param); - } - - return &SKKEnvironment::TopState; -} - -// ====================================================================== -// level 2 (sub of KanaInput)ï¼ã²ãã㪠-// ====================================================================== -State SKKEnvironment::Hirakana(const Event& event) { - const SKKEventParam& param = event.Param(); - - switch(event) { - case ENTRY_EVENT: - controller_->SelectInputMode(SKK::Hirakana); - return 0; - - case SKK_KATAKANA: - return State::Transition(&SKKEnvironment::Katakana); - - case SKK_JISX0201KANA: - return State::Transition(&SKKEnvironment::Jisx0201Kana); - - case SKK_CHAR: - if(param.IsToggleKana()) { - return State::Transition(&SKKEnvironment::Katakana); - } - - if(param.IsToggleJisx0201Kana()) { - return State::Transition(&SKKEnvironment::Jisx0201Kana); - } - } - - return &SKKEnvironment::KanaInput; -} - -// ====================================================================== -// level 2 (sub of KanaInput)ï¼ã«ã¿ã«ã -// ====================================================================== -State SKKEnvironment::Katakana(const Event& event) { - const SKKEventParam& param = event.Param(); - - switch(event) { - case ENTRY_EVENT: - controller_->SelectInputMode(SKK::Katakana); - return 0; - - case SKK_HIRAKANA: - return State::Transition(&SKKEnvironment::Hirakana); - - case SKK_JISX0201KANA: - return State::Transition(&SKKEnvironment::Jisx0201Kana); - - case SKK_CHAR: - if(param.IsToggleKana()) { - return State::Transition(&SKKEnvironment::Hirakana); - } - - if(param.IsToggleJisx0201Kana()) { - return State::Transition(&SKKEnvironment::Jisx0201Kana); - } - } - - return &SKKEnvironment::KanaInput; -} - -// ====================================================================== -// level 2 (sub of KanaInput)ï¼åè§ã«ã¿ã«ã -// ====================================================================== -State SKKEnvironment::Jisx0201Kana(const Event& event) { - const SKKEventParam& param = event.Param(); - - switch(event) { - case ENTRY_EVENT: - controller_->SelectInputMode(SKK::Jisx0201Kana); - return 0; - - case SKK_HIRAKANA: - return State::Transition(&SKKEnvironment::Hirakana); - - case SKK_CHAR: - if(param.IsToggleKana() || param.IsToggleJisx0201Kana()) { - return State::Transition(&SKKEnvironment::Hirakana); - } - } - - return &SKKEnvironment::KanaInput; -} - -// ====================================================================== -// level 1ï¼Latin å ¥å -// ====================================================================== -State SKKEnvironment::LatinInput(const Event& event) { - const SKKEventParam& param = event.Param(); - - switch(event) { - case ENTRY_EVENT: - controller_->ChangeState(SKK::DirectInput); - return 0; - - case SKK_JMODE: - case SKK_HIRAKANA: - return State::Transition(&SKKEnvironment::Hirakana); - - case SKK_CHAR: - return controller_->HandleInput(param); - } - - return &SKKEnvironment::TopState; -} - -// ====================================================================== -// level 2 (sub of LatinInput)ï¼ASCII -// ====================================================================== -State SKKEnvironment::Ascii(const Event& event) { - switch(event) { - case ENTRY_EVENT: - controller_->SelectInputMode(SKK::Ascii); - return 0; - } - - return &SKKEnvironment::LatinInput; -} - -// ====================================================================== -// level 2 (sub of LatinInput)ï¼å ¨è§è±æ° -// ====================================================================== -State SKKEnvironment::Jisx0208Latin(const Event& event) { - switch(event) { - case ENTRY_EVENT: - controller_->SelectInputMode(SKK::Jisx0208Latin); - return 0; - } - - return &SKKEnvironment::LatinInput; -} - -// ====================================================================== -// level 1ï¼è¦åºãèªæ§ç¯ -// ====================================================================== -State SKKEnvironment::Compose(const Event& event) { - switch(event) { - case SKK_ENTER: - return controller_->HandleEnter(); - - case SKK_JMODE: - return controller_->HandleJmode(); - - case SKK_TAB: - return controller_->HandleTab(); - - case SKK_BACKSPACE: - return controller_->HandleBackSpace(); - - case SKK_DELETE: - return controller_->HandleDelete(); - - case SKK_LEFT: - return controller_->HandleCursorLeft(); - - case SKK_RIGHT: - return controller_->HandleCursorRight(); - - case SKK_UP: - return controller_->HandleCursorUp(); - - case SKK_DOWN: - return controller_->HandleCursorDown(); - - case SKK_CANCEL: - return controller_->HandleCancel(); - } - - return &SKKEnvironment::TopState; -} - -// ====================================================================== -// level 2 (sub of Compose)ï¼è¦åºãèªå ¥å -// ====================================================================== -State SKKEnvironment::EntryInput(const Event& event) { - const SKKEventParam& param = event.Param(); - - switch(event) { - case EXIT_EVENT: - return State::SaveHistory(); - - case SKK_PASTE: - return controller_->HandlePaste(); - - case SKK_CHAR: - return controller_->HandleInput(param); - } - - return &SKKEnvironment::Compose; -} - -// ====================================================================== -// level 3 (sub of EntryInput)ï¼æ¥æ¬èª -// ====================================================================== -State SKKEnvironment::Japanese(const Event& event) { - switch(event) { - case ENTRY_EVENT: - controller_->ChangeState(SKK::EntryInput); - return 0; - } - - return &SKKEnvironment::EntryInput; -} - -// ====================================================================== -// level 3 (sub of EntryInput)ï¼éã -// ====================================================================== -State SKKEnvironment::Okuri(const Event& event) { - switch(event) { - case ENTRY_EVENT: - controller_->ChangeState(SKK::OkuriInput); - return 0; - } - - return &SKKEnvironment::EntryInput; -} - -// ====================================================================== -// level 3 (sub of EntryInput)ï¼çç¥è¡¨è¨ -// ====================================================================== -State SKKEnvironment::Abbreviation(const Event& event) { - switch(event) { - case ENTRY_EVENT: - controller_->SelectInputMode(SKK::Ascii); - controller_->ChangeState(SKK::AbbrevInput); - return 0; - } - - return &SKKEnvironment::EntryInput; -} - -// ====================================================================== -// level 2 (sub of Compose)ï¼è¦åºãèªè£å® -// ====================================================================== -State SKKEnvironment::EntryCompletion(const Event& event) { - const SKKEventParam& param = event.Param(); - - switch(event) { - case ENTRY_EVENT: - controller_->ChangeState(SKK::Completion); - return 0; - } - - // ã·ã¹ãã ã¤ãã³ãã¨å¤æã¯ç¡è¦ãã - if(event.IsSystem() || - event == SKK_TAB || - (event == SKK_CHAR && (param.IsNextCandidate() || - param.IsNextCompletion() || - param.IsPrevCompletion()))) { - return &SKKEnvironment::Compose; - } - - // è£å®ãã¼ä»¥å¤ãªãå±¥æ´ã«è»¢éãã - return State::DeepForward(&SKKEnvironment::EntryInput); -} - -// ====================================================================== -// level 1ï¼åè£é¸æ -// ====================================================================== -State SKKEnvironment::SelectCandidate(const Event& event) { - switch(event) { - case INIT_EVENT: - return State::ShallowHistory(&SKKEnvironment::Inline); - - case EXIT_EVENT: - return State::SaveHistory(); - - case SKK_ENTER: - return controller_->HandleEnter(); - - case SKK_JMODE: - return controller_->HandleJmode(); - - case SKK_CANCEL: - return State::DeepHistory(&SKKEnvironment::EntryInput); - - case SKK_CHAR: - return State::Forward(&SKKEnvironment::KanaInput); - } - - return &SKKEnvironment::TopState; -} - -// ====================================================================== -// level 2 (sub of SelectCandidate)ï¼ã¤ã³ã©ã¤ã³è¡¨ç¤º -// ====================================================================== -State SKKEnvironment::Inline(const Event& event) { - const SKKEventParam& param = event.Param(); - - switch(event) { - case ENTRY_EVENT: - controller_->ChangeState(SKK::SingleCandidate); - return 0; - - case SKK_BACKSPACE: - return controller_->HandleBackSpace(); - - case SKK_CHAR: - return controller_->HandleInput(param); - } - - return &SKKEnvironment::SelectCandidate; -} - -// ====================================================================== -// level 2 (sub of SelectCandidate)ï¼ã¦ã£ã³ãã¦è¡¨ç¤º -// ====================================================================== -State SKKEnvironment::Window(const Event& event) { - const SKKEventParam& param = event.Param(); - - switch(event) { - case ENTRY_EVENT: - controller_->ChangeState(SKK::MultipleCandidate); - return 0; - - case EXIT_EVENT: - return 0; - - case SKK_BACKSPACE: - return controller_->HandleBackSpace();; - - case SKK_CHAR: - return controller_->HandleInput(param); - } - - return &SKKEnvironment::SelectCandidate; -} - -// ====================================================================== -// level 1ï¼åèªåé¤ -// ====================================================================== -State SKKEnvironment::EntryRemove(const Event& event) { - const SKKEventParam& param = event.Param(); - - switch(event) { - case ENTRY_EVENT: - controller_->ChangeState(SKK::EntryRemove); - return 0; - - case SKK_YES: - return State::Transition(&SKKEnvironment::KanaInput); - - case SKK_CANCEL: - case SKK_NO: - return State::Transition(&SKKEnvironment::Inline); - - case SKK_ENTER: - return controller_->HandleEnter(); - - case SKK_BACKSPACE: - return controller_->HandleBackSpace(); - - case SKK_CHAR: - return controller_->HandleInput(param); - } - - return &SKKEnvironment::TopState; -} Index: AquaSKK/src/statemachine/SKKEnvironment.h diff -u AquaSKK/src/statemachine/SKKEnvironment.h:1.1.2.2 AquaSKK/src/statemachine/SKKEnvironment.h:removed --- AquaSKK/src/statemachine/SKKEnvironment.h:1.1.2.2 Sun Sep 23 23:48:08 2007 +++ AquaSKK/src/statemachine/SKKEnvironment.h Fri Oct 5 23:58:29 2007 @@ -1,81 +0,0 @@ -/* -*- C++ -*- - MacOS X implementation of the SKK input method. - - Copyright (C) 2007 Tomotaka SUWA <t.suw****@mac*****> - - 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 of the License, or - 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, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#ifndef INC__SKKEnvironment__ -#define INC__SKKEnvironment__ - -#include "GenericStateMachine.h" -#include "SKKEventParam.h" - -using namespace statemachinecxx_sourceforge_jp; - -class SKKController; - -// å®è¡ç°å¢ -class SKKEnvironment : public BaseStateContainer<SKKEnvironment, SKKEventParam> { - SKKController* controller_; - -public: - SKKEnvironment(); - ~SKKEnvironment(); - - const Handler InitialState() const { return &SKKEnvironment::KanaInput; } - - // level 1 (initial state) - State KanaInput(const Event& event); - - // level 2 (sub of KanaInput) - State Hirakana(const Event& event); - State Katakana(const Event& event); - State Jisx0201Kana(const Event& event); - - // level 1 - State LatinInput(const Event& event); - - // level2 (sub of LatinInput) - State Ascii(const Event& event); - State Jisx0208Latin(const Event& event); - - // level 1 - State Compose(const Event& event); - - // level 2 (sub of Compose) - State EntryInput(const Event& event); - - // lelvel 3 (sub of EntryInput) - State Japanese(const Event& event); - State Okuri(const Event& event); - State Abbreviation(const Event& event); - - // level 2 (sub of Compose) - State EntryCompletion(const Event& event); - - // level 1 - State SelectCandidate(const Event& event); - - // level 2 (sub of SelectCandidate) - State Inline(const Event& event); - State Window(const Event& event); - - // level 1 - State EntryRemove(const Event& event); -}; - -#endif Index: AquaSKK/src/statemachine/SKKState.cpp diff -u /dev/null AquaSKK/src/statemachine/SKKState.cpp:1.1.2.1 --- /dev/null Fri Oct 5 23:58:29 2007 +++ AquaSKK/src/statemachine/SKKState.cpp Fri Oct 5 23:58:29 2007 @@ -0,0 +1,571 @@ +/* -*- C++ -*- + MacOS X implementation of the SKK input method. + + Copyright (C) 2007 Tomotaka SUWA <t.suw****@mac*****> + + 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 of the License, or + 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, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "SKKState.h" +#include "SKKStateDirectHandler.h" +#include "SKKStateComposeHandler.h" +#include "SKKStateKanaEntryHandler.h" +#include "SKKStateOkuriEntryHandler.h" +#include "SKKStateAsciiEntryHandler.h" +#include "jconv.h" + +typedef SKKState::Event Event; +typedef SKKState::State State; +typedef SKKState::Output Output; + +SKKState::SKKState() { + stack_.push_back(frame(SKKContext(), 0)); +} + +// ====================================================================== +// level 1ï¼ç´æ¥å ¥å +// ====================================================================== +State SKKState::Direct(const Event& event) { + switch(event) { + case INIT_EVENT: + return State::Initial(&SKKState::KanaInput); + + case SKK_ENTER: + return DirectHandler<SKK_ENTER>(); + + case SKK_CANCEL: + return DirectHandler<SKK_CANCEL>(); + + case SKK_BACKSPACE: + return DirectHandler<SKK_BACKSPACE>(); + + case SKK_DELETE: + return DirectHandler<SKK_DELETE>(); + + case SKK_PASTE: + return DirectHandler<SKK_PASTE>(); + + case SKK_LEFT: + return DirectHandler<SKK_LEFT>(); + + case SKK_RIGHT: + return DirectHandler<SKK_RIGHT>(); + + case SKK_UP: + return DirectHandler<SKK_UP>(); + + case SKK_DOWN: + return DirectHandler<SKK_DOWN>(); + + case SKK_CHAR: + return DirectHandler<SKK_CHAR>(event.Param()); + } + + return &SKKState::TopState; +} + +// ====================================================================== +// level 2 (sub of Direct)ï¼ããªå ¥å +// ====================================================================== +State SKKState::KanaInput(const Event& event) { + switch(event) { + case INIT_EVENT: + return State::ShallowHistory(&SKKState::Hirakana); + + case EXIT_EVENT: + return State::SaveHistory(); + + case SKK_ASCII: + return State::Transition(&SKKState::Ascii); + + case SKK_JISX0208LATIN: + return State::Transition(&SKKState::Jisx0208Latin); + } + + return &SKKState::Direct; +} + +// ====================================================================== +// level 3 (sub of KanaInput)ï¼ã²ãã㪠+// ====================================================================== +State SKKState::Hirakana(const Event& event) { + const SKKEventParam& param = event.Param(); + + switch(event) { + case ENTRY_EVENT: + selectInputMode(SKK::Hirakana); + return 0; + + case SKK_KATAKANA: + return State::Transition(&SKKState::Katakana); + + case SKK_JISX0201KANA: + return State::Transition(&SKKState::Jisx0201Kana); + + case SKK_CHAR: + if(param.IsToggleKana()) { + return State::Transition(&SKKState::Katakana); + } + + if(param.IsToggleJisx0201Kana()) { + return State::Transition(&SKKState::Jisx0201Kana); + } + } + + return &SKKState::KanaInput; +} + +// ====================================================================== +// level 3 (sub of KanaInput)ï¼ã«ã¿ã«ã +// ====================================================================== +State SKKState::Katakana(const Event& event) { + const SKKEventParam& param = event.Param(); + + switch(event) { + case ENTRY_EVENT: + selectInputMode(SKK::Katakana); + return 0; + + case SKK_HIRAKANA: + return State::Transition(&SKKState::Hirakana); + + case SKK_JISX0201KANA: + return State::Transition(&SKKState::Jisx0201Kana); + + case SKK_CHAR: + if(param.IsToggleKana()) { + return State::Transition(&SKKState::Hirakana); + } + + if(param.IsToggleJisx0201Kana()) { + return State::Transition(&SKKState::Jisx0201Kana); + } + } + + return &SKKState::KanaInput; +} + +// ====================================================================== +// level 3 (sub of KanaInput)ï¼åè§ã«ã¿ã«ã +// ====================================================================== +State SKKState::Jisx0201Kana(const Event& event) { + const SKKEventParam& param = event.Param(); + + switch(event) { + case ENTRY_EVENT: + selectInputMode(SKK::Jisx0201Kana); + return 0; + + case SKK_HIRAKANA: + return State::Transition(&SKKState::Hirakana); + + case SKK_CHAR: + if(param.IsToggleKana() || param.IsToggleJisx0201Kana()) { + return State::Transition(&SKKState::Hirakana); + } + } + + return &SKKState::KanaInput; +} + +// ====================================================================== +// level 2 (sub of Direct)ï¼Latin å ¥å +// ====================================================================== +State SKKState::LatinInput(const Event& event) { + switch(event) { + case SKK_JMODE: + case SKK_HIRAKANA: + return State::Transition(&SKKState::Hirakana); + } + + return &SKKState::Direct; +} + +// ====================================================================== +// level 2 (sub of LatinInput)ï¼ASCII +// ====================================================================== +State SKKState::Ascii(const Event& event) { + switch(event) { + case ENTRY_EVENT: + selectInputMode(SKK::Ascii); + return 0; + } + + return &SKKState::LatinInput; +} + +// ====================================================================== +// level 2 (sub of LatinInput)ï¼å ¨è§è±æ° +// ====================================================================== +State SKKState::Jisx0208Latin(const Event& event) { + switch(event) { + case ENTRY_EVENT: + selectInputMode(SKK::Jisx0208Latin); + return 0; + } + + return &SKKState::LatinInput; +} + +// ====================================================================== +// level 1ï¼è¦åºãèªæ§ç¯ +// ====================================================================== +State SKKState::Compose(const Event& event) { + switch(event) { + case SKK_ENTER: + return ComposeHandler<SKK_ENTER>(); + + case SKK_JMODE: + return ComposeHandler<SKK_JMODE>(); + + case SKK_CANCEL: + return ComposeHandler<SKK_CANCEL>(); + + case SKK_TAB: + return ComposeHandler<SKK_TAB>(); + + case SKK_BACKSPACE: + return ComposeHandler<SKK_BACKSPACE>(); + + case SKK_DELETE: + return ComposeHandler<SKK_DELETE>(); + + case SKK_LEFT: + return ComposeHandler<SKK_LEFT>(); + + case SKK_RIGHT: + return ComposeHandler<SKK_RIGHT>(); + + case SKK_UP: + return ComposeHandler<SKK_UP>(); + + case SKK_DOWN: + return ComposeHandler<SKK_DOWN>(); + } + + return &SKKState::TopState; +} + +// ====================================================================== +// level 2 (sub of Compose)ï¼è¦åºãèªå ¥å +// ====================================================================== +State SKKState::EntryInput(const Event& event) { + switch(event) { + case EXIT_EVENT: + return State::SaveHistory(); + } + + return &SKKState::Compose; +} + +// ====================================================================== +// level 3 (sub of EntryInput)ï¼æ¥æ¬èª +// ====================================================================== +State SKKState::KanaEntry(const Event& event) { + switch(event) { + case SKK_CHAR: + return KanaEntryHandler<SKK_CHAR>(event.Param()); + } + + return &SKKState::EntryInput; +} + +// ====================================================================== +// level 3 (sub of EntryInput)ï¼éã +// ====================================================================== +State SKKState::OkuriEntry(const Event& event) { + switch(event) { + case SKK_TAB: + case SKK_DELETE: + case SKK_LEFT: + case SKK_RIGHT: + case SKK_UP: + case SKK_DOWN: + return 0; + + case SKK_BACKSPACE: + return OkuriEntryHandler<SKK_BACKSPACE>(); + + case SKK_CHAR: + return OkuriEntryHandler<SKK_CHAR>(event.Param()); + } + + return &SKKState::EntryInput; +} + +// ====================================================================== +// level 3 (sub of EntryInput)ï¼çç¥è¡¨è¨ +// ====================================================================== +State SKKState::AsciiEntry(const Event& event) { + switch(event) { + case ENTRY_EVENT: + selectInputMode(SKK::Ascii); + return 0; + + case SKK_CHAR: + return AsciiEntryHandler<SKK_CHAR>(event.Param()); + } + + return &SKKState::EntryInput; +} + +// ====================================================================== +// level 2 (sub of Compose)ï¼è¦åºãèªè£å® +// ====================================================================== +State SKKState::EntryCompletion(const Event& event) { + const SKKEventParam& param = event.Param(); + + switch(event) { + case ENTRY_EVENT: + //controller_->ChangeState(SKK::Completion); + return 0; + } + + // ã·ã¹ãã ã¤ãã³ãã¨å¤æã¯ç¡è¦ãã + if(event.IsSystem() || + event == SKK_TAB || + (event == SKK_CHAR && (param.IsNextCandidate() || + param.IsNextCompletion() || + param.IsPrevCompletion()))) { + return &SKKState::Compose; + } + + // è£å®ãã¼ä»¥å¤ãªãå±¥æ´ã«è»¢éãã + return State::DeepForward(&SKKState::EntryInput); +} + +// ====================================================================== +// level 1ï¼åè£é¸æ +// ====================================================================== +State SKKState::SelectCandidate(const Event& event) { + switch(event) { + case INIT_EVENT: + return State::ShallowHistory(&SKKState::Inline); + + case EXIT_EVENT: + return State::SaveHistory(); + + case SKK_ENTER: + //return controller_->HandleEnter(); + + case SKK_JMODE: + //return controller_->HandleJmode(); + + case SKK_CANCEL: + return State::DeepHistory(&SKKState::EntryInput); + + case SKK_CHAR: + return State::Forward(&SKKState::KanaInput); + } + + return &SKKState::TopState; +} + +// ====================================================================== +// level 2 (sub of SelectCandidate)ï¼ã¤ã³ã©ã¤ã³è¡¨ç¤º +// ====================================================================== +State SKKState::Inline(const Event& event) { + switch(event) { + case ENTRY_EVENT: + return 0; + + case SKK_BACKSPACE: + + case SKK_CHAR: + break; + } + + return &SKKState::SelectCandidate; +} + +// ====================================================================== +// level 2 (sub of SelectCandidate)ï¼ã¦ã£ã³ãã¦è¡¨ç¤º +// ====================================================================== +State SKKState::Window(const Event& event) { + switch(event) { + case ENTRY_EVENT: + return 0; + + case EXIT_EVENT: + return 0; + + case SKK_BACKSPACE: + + case SKK_CHAR: + break; + } + + return &SKKState::SelectCandidate; +} + +// ====================================================================== +// level 1ï¼åèªåé¤ +// ====================================================================== +State SKKState::EntryRemove(const Event& event) { + switch(event) { + case ENTRY_EVENT: + return 0; + + case SKK_YES: + return State::Transition(&SKKState::KanaInput); + + case SKK_CANCEL: + case SKK_NO: + return State::Transition(&SKKState::Inline); + + case SKK_ENTER: + + case SKK_BACKSPACE: + + case SKK_CHAR: + break; + } + + return &SKKState::TopState; +} + +// ====================================================================== +// private method +// ====================================================================== +SKKContext& SKKState::context() { + return stack_.back().first; +} + +bool SKKState::bottom() const { + return stack_.size() == 1; +} + +void SKKState::selectInputMode(SKK::InputMode mode) { + SKKInputBuffer& buffer = context().InputBuffer(); + SKKOkuriBuffer& okuri = context().OkuriBuffer(); + + buffer.SelectInputMode(mode); + okuri.SelectInputMode(mode); +} + +void SKKState::composeDisplay() { + SKKOutputPort& port = context().OutputPort(); + SKKInputBuffer& input = context().InputBuffer(); + SKKEditBuffer edit(context().EditBuffer()); + + if(!input.IsEmpty()) { + edit.Insert(input.InputString()); + } + + port.DisplayString("â½" + edit.EditString(), 1 + edit.CursorPosition()); +} + +void SKKState::okuriDisplay() { + SKKOutputPort& port = context().OutputPort(); + SKKOkuriBuffer& okuri = context().OkuriBuffer(); + SKKEditBuffer edit(context().EditBuffer()); + + edit.Insert("*" + okuri.KanaString()); + + port.DisplayString("â½" + edit.EditString(), 1 + edit.CursorPosition()); +} + +void SKKState::toggleKana() { + SKKEditBuffer& edit = context().EditBuffer(); + SKKOutputPort& port = context().OutputPort(); + std::string to; + + switch(context().InputBuffer().InputMode()) { + case SKK::Hirakana: + jconv::hirakana_to_katakana(edit.EditString(), to); + break; + + case SKK::Katakana: + jconv::katakana_to_hirakana(edit.EditString(), to); + break; + + case SKK::Jisx0201Kana: + jconv::jisx0201_kana_to_katakana(edit.EditString(), to); + break; + + default: + break; + } + + edit.Clear(); + port.FixString(to); +} + +void SKKState::toggleJisx0201Kana() { + SKKEditBuffer& edit = context().EditBuffer(); + SKKOutputPort& port = context().OutputPort(); + std::string to; + + switch(context().InputBuffer().InputMode()) { + case SKK::Hirakana: + jconv::hirakana_to_jisx0201_kana(edit.EditString(), to); + break; + + case SKK::Katakana: + jconv::katakana_to_jisx0201_kana(edit.EditString(), to); + break; + + case SKK::Jisx0201Kana: + jconv::jisx0201_kana_to_hirakana(edit.EditString(), to); + break; + + case SKK::Ascii: + jconv::ascii_to_jisx0208_latin(edit.EditString(), to); + + default: + break; + } + + edit.Clear(); + port.FixString(to); +} + +void SKKState::beginRegistration(const std::string& prompt, Handler restorePoint) { + stack_.push_back(frame(SKKContext(prompt), restorePoint)); +} + +State SKKState::endRegistration(bool commit) { + if(bottom()) return 0; + + frame current(stack_.back()); + + stack_.pop_back(); + + std::string result; + if(commit) { + result = current.first.Word(); + } + + context().OutputPort().FixString(result); + + // ãã£ã³ã»ã«ãããå ´åã¯å¾©å¸°å ´æã«æ»ã + if(!commit) { + return State::Transition(current.second); + } + + // 確å®ãããããç¾å¨ã®å ¥åã¢ã¼ãã«é·ç§» + switch(context().InputBuffer().InputMode()) { + case SKK::Hirakana: + return State::Transition(&SKKState::Hirakana); + + case SKK::Katakana: + return State::Transition(&SKKState::Katakana); + + case SKK::Jisx0201Kana: + return State::Transition(&SKKState::Jisx0201Kana); + } + + return State::Transition(&SKKState::KanaInput); +} Index: AquaSKK/src/statemachine/SKKState.h diff -u /dev/null AquaSKK/src/statemachine/SKKState.h:1.1.2.1 --- /dev/null Fri Oct 5 23:58:29 2007 +++ AquaSKK/src/statemachine/SKKState.h Fri Oct 5 23:58:29 2007 @@ -0,0 +1,109 @@ +/* -*- C++ -*- + MacOS X implementation of the SKK input method. + + Copyright (C) 2007 Tomotaka SUWA <t.suw****@mac*****> + + 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 of the License, or + 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, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef INC__SKKState__ +#define INC__SKKState__ + +#include "GenericStateMachine.h" +#include "SKKEventParam.h" +#include "SKKContext.h" + +using namespace statemachinecxx_sourceforge_jp; + +// å®è¡ç°å¢ +class SKKState : public BaseStateContainer<SKKState, SKKEventParam> { + typedef std::pair<SKKContext, Handler> frame; + std::vector<frame> stack_; + + SKKContext& context(); + bool bottom() const; + + void selectInputMode(SKK::InputMode mode); + + // ã¤ãã³ããã³ãã© + template <int Signal> State DirectHandler(); + template <int Signal> State DirectHandler(const SKKEventParam& param); + template <int Signal> State ComposeHandler(); + template <int Signal> State KanaEntryHandler(const SKKEventParam& event); + template <int Signal> State OkuriEntryHandler(); + template <int Signal> State OkuriEntryHandler(const SKKEventParam& event); + template <int Signal> State AsciiEntryHandler(const SKKEventParam& event); + + // 表示 + void composeDisplay(); + void okuriDisplay(); + + // ãã°ã«å¤æ + void toggleKana(); + void toggleJisx0201Kana(); + + // åèªç»é² + void beginRegistration(const std::string& prompt, Handler restorePoint); + State endRegistration(bool commit); + +public: + SKKState(); + + const Handler InitialState() const { return &SKKState::Direct; } + + // level 1 + State Direct(const Event& event); + + // level 2 (initial state) + State KanaInput(const Event& event); + + // level 3 (sub of KanaInput) + State Hirakana(const Event& event); + State Katakana(const Event& event); + State Jisx0201Kana(const Event& event); + + // level 2 + State LatinInput(const Event& event); + + // level 3 (sub of LatinInput) + State Ascii(const Event& event); + State Jisx0208Latin(const Event& event); + + // level 1 + State Compose(const Event& event); + + // level 2 (sub of Compose) + State EntryInput(const Event& event); + + // lelvel 3 (sub of EntryInput) + State KanaEntry(const Event& event); + State OkuriEntry(const Event& event); + State AsciiEntry(const Event& event); + + // level 2 (sub of Compose) + State EntryCompletion(const Event& event); + + // level 1 + State SelectCandidate(const Event& event); + + // level 2 (sub of SelectCandidate) + State Inline(const Event& event); + State Window(const Event& event); + + // level 1 + State EntryRemove(const Event& event); +}; + +#endif Index: AquaSKK/src/statemachine/SKKStateAsciiEntryHandler.h diff -u /dev/null AquaSKK/src/statemachine/SKKStateAsciiEntryHandler.h:1.1.2.1 --- /dev/null Fri Oct 5 23:58:29 2007 +++ AquaSKK/src/statemachine/SKKStateAsciiEntryHandler.h Fri Oct 5 23:58:29 2007 @@ -0,0 +1,70 @@ +/* -*- C++ -*- + MacOS X implementation of the SKK input method. + + Copyright (C) 2007 Tomotaka SUWA <t.suw****@mac*****> + + 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 of the License, or + 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, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef INC__SKKStateAsciiEntryHandler__ +#define INC__SKKStateAsciiEntryHandler__ + +#include "SKKState.h" + +typedef SKKState::State State; + +// ====================================================================== +// ASCII è¦åºãèª +// ====================================================================== + +template <> +State SKKState::AsciiEntryHandler<SKK_CHAR>(const SKKEventParam& param) { + SKKInputBuffer& buffer = context().InputBuffer(); + SKKEditBuffer& edit = context().EditBuffer(); + SKKOutputPort& port = context().OutputPort(); + + if(!edit.IsEmpty()) { + State state = 0; + + do { + // ãã°ã«å¤æ #2 + if(param.IsToggleJisx0201Kana()) { + toggleJisx0201Kana(); + state = State::Transition(&SKKState::KanaInput); + break; + } + + // å¤æ + if(param.IsNextCandidate()) { + //std::cerr << "å¤æéå§" << std::endl; + break; + } + } while(0); + + if(state) { + port.Terminate(); + return state; + } + } + + buffer.Input(std::tolower(param.code)); + edit.Insert(buffer.FixedString()); + + composeDisplay(); + + return 0; +} + +#endif Index: AquaSKK/src/statemachine/SKKStateComposeHandler.h diff -u /dev/null AquaSKK/src/statemachine/SKKStateComposeHandler.h:1.1.2.1 --- /dev/null Fri Oct 5 23:58:29 2007 +++ AquaSKK/src/statemachine/SKKStateComposeHandler.h Fri Oct 5 23:58:29 2007 @@ -0,0 +1,170 @@ +/* -*- C++ -*- + MacOS X implementation of the SKK input method. + + Copyright (C) 2007 Tomotaka SUWA <t.suw****@mac*****> + + 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 of the License, or + 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, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef INC__SKKStateComposeHandler__ +#define INC__SKKStateComposeHandler__ + +#include "SKKState.h" + +typedef SKKState::State State; + +// ====================================================================== +// è¦åºãèªæ§ç¯ +// ====================================================================== + +template <> +State SKKState::ComposeHandler<SKK_ENTER>() { + SKKInputBuffer& buffer = context().InputBuffer(); + SKKEditBuffer& edit = context().EditBuffer(); + SKKOutputPort& port = context().OutputPort(); + + // ç¾å¨ã®åè£ã§ç¢ºå® + port.FixString(edit.EditString()); + + edit.Clear(); + buffer.Clear(); + + return State::Transition(&SKKState::KanaInput); +} + +template <> +State SKKState::ComposeHandler<SKK_JMODE>() { + State result = ComposeHandler<SKK_ENTER>(); + + // æ¹è¡ãããã©ããï¼(egg-like-new-line) + return result; +} + +template <> +State SKKState::ComposeHandler<SKK_CANCEL>() { + SKKInputBuffer& buffer = context().InputBuffer(); + SKKEditBuffer& edit = context().EditBuffer(); + SKKOutputPort& port = context().OutputPort(); + + edit.Clear(); + buffer.Clear(); + + // 空ã«ãã + port.Terminate(); + + return State::Transition(&SKKState::KanaInput); +} + +template <> +State SKKState::ComposeHandler<SKK_BACKSPACE>() { + SKKInputBuffer& buffer = context().InputBuffer(); + SKKEditBuffer& edit = context().EditBuffer(); + SKKOutputPort& port = context().OutputPort(); + + if(!buffer.IsEmpty()) { + buffer.BackSpace(); + } else { + if(!edit.IsEmpty()) { + edit.BackSpace(); + } else { + port.Terminate(); + + return State::Transition(&SKKState::KanaInput); + } + } + + composeDisplay(); + + return 0; +} + +template <> +State SKKState::ComposeHandler<SKK_DELETE>() { + SKKInputBuffer& buffer = context().InputBuffer(); + SKKEditBuffer& edit = context().EditBuffer(); + + if(buffer.IsEmpty() && !edit.IsEmpty()) { + edit.Delete(); + } + + composeDisplay(); + + return 0; +} + +template <> +State SKKState::ComposeHandler<SKK_TAB>() { + // æ¤ç´¢ã§ããï¼ + if(0) { + // è£å®ã¢ã¼ã + return State::Transition(&SKKState::EntryCompletion); + } else { + return 0; + } +} + +template <> +State SKKState::ComposeHandler<SKK_PASTE>() { + // ããã¹ããããï¼ + if(0) { + SKKInputBuffer& buffer = context().InputBuffer(); + SKKEditBuffer& edit = context().EditBuffer(); + + buffer.Clear(); + edit.Insert("paste string"); + + composeDisplay(); + } + + return 0; +} + +template <> +State SKKState::ComposeHandler<SKK_LEFT>() { + context().InputBuffer().Clear(); + context().EditBuffer().CursorLeft(); + composeDisplay(); + + return 0; +} + +template <> +State SKKState::ComposeHandler<SKK_RIGHT>() { + context().InputBuffer().Clear(); + context().EditBuffer().CursorRight(); + composeDisplay(); + + return 0; +} + +template <> +State SKKState::ComposeHandler<SKK_UP>() { + context().InputBuffer().Clear(); + context().EditBuffer().CursorUp(); + composeDisplay(); + + return 0; +} + +template <> +State SKKState::ComposeHandler<SKK_DOWN>() { + context().InputBuffer().Clear(); + context().EditBuffer().CursorDown(); + composeDisplay(); + + return 0; +} + +#endif Index: AquaSKK/src/statemachine/SKKStateDirectHandler.h diff -u /dev/null AquaSKK/src/statemachine/SKKStateDirectHandler.h:1.1.2.1 --- /dev/null Fri Oct 5 23:58:29 2007 +++ AquaSKK/src/statemachine/SKKStateDirectHandler.h Fri Oct 5 23:58:29 2007 @@ -0,0 +1,196 @@ +/* -*- C++ -*- + MacOS X implementation of the SKK input method. + + Copyright (C) 2007 Tomotaka SUWA <t.suw****@mac*****> + + 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 of the License, or + 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, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef INC__SKKStateDirectHandler__ +#define INC__SKKStateDirectHandler__ + +#include "SKKState.h" + +typedef SKKState::State State; + +// ====================================================================== +// ç´æ¥å ¥å +// ====================================================================== + +template <> +State SKKState::DirectHandler<SKK_ENTER>() { + return endRegistration(true); +} + +template <> +State SKKState::DirectHandler<SKK_CANCEL>() { + return endRegistration(false); +} + +template <> +State SKKState::DirectHandler<SKK_BACKSPACE>() { + SKKInputBuffer& buffer = context().InputBuffer(); + SKKOutputPort& port = context().OutputPort(); + + if(!buffer.IsEmpty()) { + buffer.BackSpace(); + } else { + if(!bottom()) { + context().WordBuffer().BackSpace(); + } + } + + port.DisplayString(buffer.InputString()); + + return 0; +} + +template <> +State SKKState::DirectHandler<SKK_DELETE>() { + if(bottom()) return 0; + + SKKEditBuffer& word = context().WordBuffer(); + SKKOutputPort& port = context().OutputPort(); + + word.Delete(); + port.DisplayString(""); + + return 0; +} + +template <> +State SKKState::DirectHandler<SKK_PASTE>() { + if(bottom()) return 0; + + if(0) { + // ããã¹ããããã°ãã¼ã¹ã + } + + return 0; +} + +template <> +State SKKState::DirectHandler<SKK_LEFT>() { + if(bottom()) return 0; + + SKKEditBuffer& word = context().WordBuffer(); + SKKOutputPort& port = context().OutputPort(); + + word.CursorLeft(); + port.DisplayString(""); + + return 0; +} + +template <> +State SKKState::DirectHandler<SKK_RIGHT>() { + if(bottom()) return 0; + + SKKEditBuffer& word = context().WordBuffer(); + SKKOutputPort& port = context().OutputPort(); + + word.CursorRight(); + port.DisplayString(""); + + return 0; +} + +template <> +State SKKState::DirectHandler<SKK_UP>() { + if(bottom()) return 0; + + SKKEditBuffer& word = context().WordBuffer(); + SKKOutputPort& port = context().OutputPort(); + + word.CursorUp(); + port.DisplayString(""); + + return 0; +} + +template <> +State SKKState::DirectHandler<SKK_DOWN>() { + if(bottom()) return 0; + + SKKEditBuffer& word = context().WordBuffer(); + SKKOutputPort& port = context().OutputPort(); + + word.CursorDown(); + port.DisplayString(""); + + return 0; +} + +template <> +State SKKState::DirectHandler<SKK_CHAR>(const SKKEventParam& param) { + SKKInputBuffer& buffer = context().InputBuffer(); + SKKOutputPort& port = context().OutputPort(); + + // ç´æ¥å ¥åæåã¯ç¡è¦ãã + if(param.IsDirect()) { + if(bottom()) return 0; + + port.DisplayString(std::string(1, param.code)); + + return 0; + } + + if(!buffer.Input(param.code)) { + State state = 0; + // 確å®ããªãã®ã¯ããªå ¥åæã®ã¿ + do { + if(param.IsSwitchToAscii()) { + state = State::Transition(&SKKState::Ascii); + break; + } + + if(param.IsSwitchToJisx0208Latin()) { + state = State::Transition(&SKKState::Jisx0208Latin); + break; + } + + if(param.IsUpperCases()) { + state = State::Forward(&SKKState::KanaEntry); + break; + } + + if(param.IsEnterJapanese()) { + state = State::Transition(&SKKState::KanaEntry); + break; + } + + if(param.IsEnterAbbrev()) { + state = State::Transition(&SKKState::AsciiEntry); + break; + } + } while(0); + + if(state) { + buffer.Clear(); + port.Terminate(); + return state; + } + } + + if(!buffer.FixedString().empty()) { + port.FixString(buffer.FixedString()); + } + + port.DisplayString(buffer.InputString()); + + return 0; +} + +#endif Index: AquaSKK/src/statemachine/SKKStateKanaEntryHandler.h diff -u /dev/null AquaSKK/src/statemachine/SKKStateKanaEntryHandler.h:1.1.2.1 --- /dev/null Fri Oct 5 23:58:29 2007 +++ AquaSKK/src/statemachine/SKKStateKanaEntryHandler.h Fri Oct 5 23:58:29 2007 @@ -0,0 +1,127 @@ +/* -*- C++ -*- + MacOS X implementation of the SKK input method. + + Copyright (C) 2007 Tomotaka SUWA <t.suw****@mac*****> + + 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 of the License, or + 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, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef INC__SKKStateKanaEntryHandler__ +#define INC__SKKStateKanaEntryHandler__ + +#include "SKKState.h" + +typedef SKKState::State State; + +// ====================================================================== +// ããªè¦åºãèª +// ====================================================================== + +template <> +State SKKState::KanaEntryHandler<SKK_CHAR>(const SKKEventParam& param) { + SKKInputBuffer& buffer = context().InputBuffer(); + SKKEditBuffer& edit = context().EditBuffer(); + SKKOutputPort& port = context().OutputPort(); + + if(!edit.IsEmpty()) { + State state = 0; + + do { + // ãã°ã«å¤æ #1 + if(param.IsToggleKana()) { + toggleKana(); + state = State::Transition(&SKKState::KanaInput); + break; + } + + // ãã°ã«å¤æ #2 + if(param.IsToggleJisx0201Kana()) { + toggleJisx0201Kana(); + state = State::Transition(&SKKState::KanaInput); + break; + } + + // éããã + if(param.IsUpperCases()) { + char code = std::tolower(param.code); + + // å ¥åæåãåç¬ã§å¤æå¯è½ã§ãªããã°ãå¤æã試ã¿ã + // KesSite å¯¾å¿ + SKKInputBuffer tmp; + if(!tmp.Input(code)) { + if(buffer.Input(code)) { + edit.Insert(buffer.FixedString()); + } + } + + // éããããã¡ã®åæå + context().OkuriBuffer().Initialize(code); + state = State::Forward(&SKKState::OkuriEntry); + break; + } + + // å¤æ + if(param.IsNextCandidate()) { + //std::cerr << "å¤æéå§" << std::endl; + break; + } + } while(0); + + if(state) { + port.Terminate(); + return state; + } + } + + if(buffer.Input(std::tolower(param.code))) { + edit.Insert(buffer.FixedString()); + } else { + State state = 0; + + do { + if(param.IsSwitchToAscii()) { + state = State::Transition(&SKKState::Ascii); + break; + } + + if(param.IsSwitchToJisx0208Latin()) { + state = State::Transition(&SKKState::Jisx0208Latin); + break; + } + + if(param.IsEnterJapanese() && !edit.IsEmpty()) { + state = State::Transition(&SKKState::KanaEntry); + break; + } + } while(0); + + if(state) { + port.FixString(edit.EditString()); + edit.Clear(); + buffer.Clear(); + return state; + } + + if(!buffer.FixedString().empty()) { + edit.Insert(buffer.FixedString()); + } + } + + composeDisplay(); + + return 0; +} + +#endif Index: AquaSKK/src/statemachine/SKKStateOkuriEntryHandler.h diff -u /dev/null AquaSKK/src/statemachine/SKKStateOkuriEntryHandler.h:1.1.2.1 --- /dev/null Fri Oct 5 23:58:29 2007 +++ AquaSKK/src/statemachine/SKKStateOkuriEntryHandler.h Fri Oct 5 23:58:29 2007 @@ -0,0 +1,61 @@ +/* -*- C++ -*- + MacOS X implementation of the SKK input method. + + Copyright (C) 2007 Tomotaka SUWA <t.suw****@mac*****> + + 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 of the License, or + 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, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef INC__SKKStateOkuriEntryHandler__ +#define INC__SKKStateOkuriEntryHandler__ + +#include "SKKState.h" + +typedef SKKState::State State; + +// ====================================================================== +// éããã +// ====================================================================== + +template <> +State SKKState::OkuriEntryHandler<SKK_BACKSPACE>() { + SKKOkuriBuffer& okuri = context().OkuriBuffer(); + + if(okuri.IsEmpty()) { + composeDisplay(); + return State::Transition(&SKKState::KanaInput); + } + + okuri.BackSpace(); + okuriDisplay(); + + return 0; +} + +template <> +State SKKState::OkuriEntryHandler<SKK_CHAR>(const SKKEventParam& param) { + SKKOkuriBuffer& okuri = context().OkuriBuffer(); + SKKOutputPort& port = context().OutputPort(); + + if(okuri.Input(std::tolower(param.code)) && okuri.IsEmpty()) { + // å¤æéå§ï¼ + } + + okuriDisplay(); + + return 0; +} + +#endif