Tomotaka SUWA
t-suw****@users*****
2006年 6月 3日 (土) 10:23:18 JST
Index: AquaSKK/AsciiConversionMode.cpp diff -u AquaSKK/AsciiConversionMode.cpp:1.5 AquaSKK/AsciiConversionMode.cpp:1.6 --- AquaSKK/AsciiConversionMode.cpp:1.5 Wed May 17 01:13:10 2006 +++ AquaSKK/AsciiConversionMode.cpp Sat Jun 3 10:23:18 2006 @@ -1,5 +1,5 @@ /* - $Id: AsciiConversionMode.cpp,v 1.5 2006/05/16 16:13:10 t-suwa Exp $ + $Id: AsciiConversionMode.cpp,v 1.6 2006/06/03 01:23:18 t-suwa Exp $ MacOS X implementation of the SKK input method. @@ -252,9 +252,15 @@ sendCurrentCandidateToServerToRegister(); // û³êÈ¢ªA§IÉmè³¹éB - parent->fix(candidates[current_candidate_index]); + if(ClientConfiguration::theInstance().useNumericConversion()) { + parent->fix(numconv_.Apply(candidates[current_candidate_index])); + } else { + parent->fix(candidates[current_candidate_index]); + } + parent->setEnabledAsciiConversionMode(false); initialize(); + parent->handleInput(skkchar); } else if(status == STATUS_BLACK_WITH_WINDOW) { @@ -311,6 +317,9 @@ // »ÝÌóâðmèµÄ©çÅã̶ðíB // »µÄú»µÄI¹B CppCFString str_to_fix(candidates[current_candidate_index]); + if(ClientConfiguration::theInstance().useNumericConversion()) { + str_to_fix = numconv_.Apply(str_to_fix); + } str_to_fix.eraseLast(1); // IÉM @@ -401,7 +410,11 @@ sendCurrentCandidateToServerToRegister(); // »ÝÌóâðmèB - parent->fix(candidates[current_candidate_index]); + if(ClientConfiguration::theInstance().useNumericConversion()) { + parent->fix(numconv_.Apply(candidates[current_candidate_index])); + } else { + parent->fix(candidates[current_candidate_index]); + } if(status == STATUS_BLACK_WITH_WINDOW) { // EChEð¶éB @@ -540,8 +553,12 @@ return CppCFString().append(0x25bd).append(index); } else if(status == STATUS_BLACK || status == STATUS_BLACK_WITH_WINDOW) { + CppCFString str = candidates[current_candidate_index]; + if(ClientConfiguration::theInstance().useNumericConversion()) { + str = numconv_.Apply(str); + } // ¥»ÝÌóâ - return CppCFString().append(0x25bc).append(candidates[current_candidate_index]); + return CppCFString().append(0x25bc).append(str); } else if(status == STATUS_PROMPT) { // [vvg][üÍ] @@ -558,16 +575,22 @@ } else if(status == STATUS_BLACK) { result = candidates[current_candidate_index]; - + if(ClientConfiguration::theInstance().useNumericConversion()) { + result = numconv_.Apply(candidates[current_candidate_index]); + } + // IÉM sendCurrentCandidateToServerToRegister(); } else if(status == STATUS_BLACK_WITH_WINDOW) { result = candidates[current_candidate_index]; - + if(ClientConfiguration::theInstance().useNumericConversion()) { + result = numconv_.Apply(result); + } + // IÉM sendCurrentCandidateToServerToRegister(); - + // EChEð¶éB closeCandidatesWindow(); } @@ -594,12 +617,28 @@ } void AsciiConversionMode::askServerTheCandidates() { + CppCFString str('-'); + + str.append(index); + // ahya@¨@-ahya CppCFData query; - query.own(CppCFString().append('-').append(index).toCFData()); + query.own(str.toCFData()); current_candidate_index = 0; - ::askServerTheCandidates(query,candidates); + ::askServerTheCandidates(query, candidates); + + // lÏ·ªLø©H + if(ClientConfiguration::theInstance().useNumericConversion() && numconv_.Setup(str)) { + std::vector<CppCFString> result; + CppCFData cfdata; + + cfdata.own(numconv_.NormalizedKey().toCFData()); + + ::askServerTheCandidates(cfdata, result); + + candidates.insert(candidates.end(), result.begin(), result.end()); + } } void AsciiConversionMode::askServerTheCompletions() { @@ -631,7 +670,11 @@ std::vector<CppCFString> cands; std::vector<CppCFString>::const_iterator ite; for(ite = candidates.begin() + (show_cands_window_after_Nth_cand - 1); ite != candidates.end(); ++ ite) { - cands.push_back(*ite); + if(ClientConfiguration::theInstance().useNumericConversion()) { + cands.push_back(numconv_.Apply(*ite)); + } else { + cands.push_back(*ite); + } } ::openCandidatesWindow(join(SKK_MSG_DELIMITER, cands), Index: AquaSKK/AsciiConversionMode.h diff -u AquaSKK/AsciiConversionMode.h:1.4 AquaSKK/AsciiConversionMode.h:1.5 --- AquaSKK/AsciiConversionMode.h:1.4 Wed May 17 01:13:10 2006 +++ AquaSKK/AsciiConversionMode.h Sat Jun 3 10:23:18 2006 @@ -1,5 +1,5 @@ /* - $Id: AsciiConversionMode.h,v 1.4 2006/05/16 16:13:10 t-suwa Exp $ + $Id: AsciiConversionMode.h,v 1.5 2006/06/03 01:23:18 t-suwa Exp $ MacOS X implementation of the SKK input method. @@ -28,12 +28,14 @@ #include "ChildInputMode.h" #include "RegistrationStarter.h" #include "CppCFString.h" +#include "NumericConverter.h" class ParentInputMode; class WordRegisterMode; class AsciiConversionMode : public ChildInputMode , public RegistrationStarter { bool handleInputChar(SKKChar skkchar); + NumericConverter numconv_; protected: static const int STATUS_NULL = 0; // AXL[Ï·[hÉÈÁĢȢóÔBæªÉ¤à¥à³¢B Index: AquaSKK/BIMClientServer.h diff -u AquaSKK/BIMClientServer.h:1.5 AquaSKK/BIMClientServer.h:1.6 --- AquaSKK/BIMClientServer.h:1.5 Fri May 5 00:27:02 2006 +++ AquaSKK/BIMClientServer.h Sat Jun 3 10:23:18 2006 @@ -1,5 +1,5 @@ /* - $Id: BIMClientServer.h,v 1.5 2006/05/04 15:27:02 t-suwa Exp $ + $Id: BIMClientServer.h,v 1.6 2006/06/03 01:23:18 t-suwa Exp $ MacOS X implementation of the SKK input method. @@ -110,7 +110,8 @@ kBasicMessageIsSkkEggLikeNewline = 500, // kBasicMessageIsNumericKeypad_HalfWidth = 501, kBasicMessageIsAsciiModeStartup = 502, - kBasicMessageKbdLayoutId = 503, + kBasicMessageUseNumericConversion = 503, + kBasicMessageKbdLayoutId = 504, }; // T[o[©çNCAgÖÌÊmbZ[W Index: AquaSKK/BIMComponent.cpp diff -u AquaSKK/BIMComponent.cpp:1.5 AquaSKK/BIMComponent.cpp:1.6 --- AquaSKK/BIMComponent.cpp:1.5 Wed Apr 26 22:36:12 2006 +++ AquaSKK/BIMComponent.cpp Sat Jun 3 10:23:18 2006 @@ -1,5 +1,5 @@ /* - $Id: BIMComponent.cpp,v 1.5 2006/04/26 13:36:12 t-suwa Exp $ + $Id: BIMComponent.cpp,v 1.6 2006/06/03 01:23:18 t-suwa Exp $ MacOS X implementation of the SKK input method. @@ -52,12 +52,51 @@ static ComponentResult CallBIMFunctionWithStorage(Handle inStorage, ComponentParameters* inParams, ProcPtr inProcPtr, SInt32 inProcInfo); +static const char* componentDescription(int what) { + switch(what) { + case kComponentOpenSelect: + return "kComponentOpenSelect"; + case kComponentCloseSelect: + return "kComponentCloseSelect"; + case kComponentCanDoSelect: + return "kComponentCanDoSelect"; + case kComponentVersionSelect: + return "kComponentVersionSelect"; + case kCMGetScriptLangSupport: + return "kCMGetScriptLangSupport"; + case kCMInitiateTextService: + return "kCMInitiateTextService"; + case kCMTerminateTextService: + return "kCMTerminateTextService"; + case kCMActivateTextService: + return "kCMActivateTextService"; + case kCMDeactivateTextService: + return "kCMDeactivateTextService"; + case kCMTextServiceEvent: + return "kCMTextServiceEvent"; + case kCMGetTextServiceMenu: + return "kCMGetTextServiceMenu"; + case kCMFixTextService: + return "kCMFixTextService"; + case kCMHidePaletteWindows: + return "kCMHidePaletteWindows"; + case kCMCopyTextServiceInputModeList: + return "kCMCopyTextServiceInputModeList"; + case kCMSetTextServiceProperty: + return "kCMSetTextServiceProperty"; + default: + return "*** Unknown ***"; + } +} + // R|[lgÌGg|CgBextern "C"·×«©Ç¤©Íè©ÅÈ¢ªA껤µÄ¨B extern "C" pascal ComponentResult BIMComponentDispatch(ComponentParameters* inParams, Handle inSessionHandle) { ComponentResult result; result = noErr; + //std::cerr << "Component Dispatch: " << componentDescription(inParams->what) << std::endl; + switch(inParams->what) { // Component Manager©çÌwß case kComponentOpenSelect: Index: AquaSKK/ChangeLog diff -u AquaSKK/ChangeLog:1.25 AquaSKK/ChangeLog:1.26 --- AquaSKK/ChangeLog:1.25 Tue May 23 23:47:01 2006 +++ AquaSKK/ChangeLog Sat Jun 3 10:23:18 2006 @@ -1,3 +1,20 @@ +2006-06-03 Tomotaka SUWA <t.suw****@mac*****> + + * NumericConverter.h, NumericConverter.cpp: VKÇÁBlÏ·ðT + |[g·éNXB + + * AsciiConversionMode.*, KanjiConversionMode.*: lÏ·ÌT|[g + ðÇÁB + + * BIMClientServer.h: kBasicMessageUseNumericConversion ðÇÁB + + * ClientConfiguration.*: lÏ·pÌIvVÉÎB + + * ServerMessageReceiver.mm: lÏ·pÌIvVÉÎB + + * skkserv.cpp: ÊMÌZbVªØf³ê½êA³À[vµÄµ + ܤsïðC³B + 2006-05-23 Tomotaka SUWA <t.suw****@mac*****> * Japanese.lproj/Preferences.nib/keyedobjects.nib: lÏ·pÌIv Index: AquaSKK/ClientConfiguration.cpp diff -u AquaSKK/ClientConfiguration.cpp:1.4 AquaSKK/ClientConfiguration.cpp:1.5 --- AquaSKK/ClientConfiguration.cpp:1.4 Wed Apr 26 22:36:12 2006 +++ AquaSKK/ClientConfiguration.cpp Sat Jun 3 10:23:18 2006 @@ -1,5 +1,5 @@ /* - $Id: ClientConfiguration.cpp,v 1.4 2006/04/26 13:36:12 t-suwa Exp $ + $Id: ClientConfiguration.cpp,v 1.5 2006/06/03 01:23:18 t-suwa Exp $ MacOS X implementation of the SKK input method. @@ -41,7 +41,8 @@ void ClientConfiguration::load() { skkEggLikeNewline = getOption(kBasicMessageIsSkkEggLikeNewline); numericKeypad_HalfWidth = getOption(kBasicMessageIsNumericKeypad_HalfWidth); - asciiModeStartup_ = getOption(kBasicMessageIsAsciiModeStartup); + asciiModeStartup_ = getOption(kBasicMessageIsAsciiModeStartup); + useNumericConversion_ = getOption(kBasicMessageUseNumericConversion); kbdLayoutId_ = getOption(kBasicMessageKbdLayoutId); } @@ -72,6 +73,11 @@ return asciiModeStartup_; } +bool ClientConfiguration::useNumericConversion() const { + return useNumericConversion_; +} + int ClientConfiguration::kbdLayoutId() const { return kbdLayoutId_; } + Index: AquaSKK/ClientConfiguration.h diff -u AquaSKK/ClientConfiguration.h:1.4 AquaSKK/ClientConfiguration.h:1.5 --- AquaSKK/ClientConfiguration.h:1.4 Wed Apr 26 22:36:12 2006 +++ AquaSKK/ClientConfiguration.h Sat Jun 3 10:23:18 2006 @@ -1,10 +1,10 @@ /* - $Id: ClientConfiguration.h,v 1.4 2006/04/26 13:36:12 t-suwa Exp $ + $Id: ClientConfiguration.h,v 1.5 2006/06/03 01:23:18 t-suwa Exp $ MacOS X implementation of the SKK input method. Copyright (C) 2002 phonohawk - Copyright (C) 2005 Tomotaka SUWA <t.suw****@mac*****> + Copyright (C) 2005-2006 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 @@ -21,7 +21,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#pragma once +#ifndef INC__ClientConfiguration__ +#define INC__ClientConfiguration__ /* ±ÌNXÍNCAgÌÝèðÛ·éSingletonÅ·B @@ -38,6 +39,7 @@ bool skkEggLikeNewline; bool numericKeypad_HalfWidth; bool asciiModeStartup_; + bool useNumericConversion_; int kbdLayoutId_; ClientConfiguration(); @@ -53,5 +55,8 @@ bool isSkkEggLikeNewline() const; bool isNumericKeypad_HalfWidth() const; bool isAsciiModeStartup() const; + bool useNumericConversion() const; int kbdLayoutId() const; }; + +#endif // INC__ClientConfiguration__ Index: AquaSKK/Info-AquaSKKInputMethod.plist diff -u AquaSKK/Info-AquaSKKInputMethod.plist:1.6 AquaSKK/Info-AquaSKKInputMethod.plist:1.7 --- AquaSKK/Info-AquaSKKInputMethod.plist:1.6 Wed Apr 26 23:36:39 2006 +++ AquaSKK/Info-AquaSKKInputMethod.plist Sat Jun 3 10:23:18 2006 @@ -19,11 +19,11 @@ <key>CFBundlePackageType</key> <string>thng</string> <key>CFBundleShortVersionString</key> - <string>3.0</string> + <string>3.1</string> <key>CFBundleSignature</key> <string>askk</string> <key>CFBundleVersion</key> - <string>2006-04-27</string> + <string>2006-06-03</string> <key>CSResourcesFileMapped</key> <true/> <key>tsInputMethodIconFileKey</key> Index: AquaSKK/Info-AquaSKKServer.plist diff -u AquaSKK/Info-AquaSKKServer.plist:1.6 AquaSKK/Info-AquaSKKServer.plist:1.7 --- AquaSKK/Info-AquaSKKServer.plist:1.6 Wed Apr 26 23:36:39 2006 +++ AquaSKK/Info-AquaSKKServer.plist Sat Jun 3 10:23:18 2006 @@ -19,11 +19,11 @@ <key>CFBundlePackageType</key> <string>APPL</string> <key>CFBundleShortVersionString</key> - <string>3.0</string> + <string>3.1</string> <key>CFBundleSignature</key> <string>askk</string> <key>CFBundleVersion</key> - <string>2006-04-27</string> + <string>2006-06-03</string> <key>NSMainNibFile</key> <string>Principal</string> <key>NSPrincipalClass</key> Index: AquaSKK/KanjiConversionMode.cpp diff -u AquaSKK/KanjiConversionMode.cpp:1.5 AquaSKK/KanjiConversionMode.cpp:1.6 --- AquaSKK/KanjiConversionMode.cpp:1.5 Wed May 17 01:13:10 2006 +++ AquaSKK/KanjiConversionMode.cpp Sat Jun 3 10:23:18 2006 @@ -1,5 +1,5 @@ /* - $Id: KanjiConversionMode.cpp,v 1.5 2006/05/16 16:13:10 t-suwa Exp $ + $Id: KanjiConversionMode.cpp,v 1.6 2006/06/03 01:23:18 t-suwa Exp $ MacOS X implementation of the SKK input method. @@ -406,7 +406,11 @@ sendCurrentCandidateToServerToRegister(); // mè - parent->fix(candidates[current_candidate_index]); + if(ClientConfiguration::theInstance().useNumericConversion()) { + parent->fix(numconv_.Apply(candidates[current_candidate_index])); + } else { + parent->fix(candidates[current_candidate_index]); + } initialize(); return handleInput(skkchar); // ÄËü @@ -470,7 +474,11 @@ sendCurrentCandidateToServerToRegister(); // §³êÈ¢ªA§IÉmè³¹éB - parent->fix(candidates[current_candidate_index]); + if(ClientConfiguration::theInstance().useNumericConversion()) { + parent->fix(numconv_.Apply(candidates[current_candidate_index])); + } else { + parent->fix(candidates[current_candidate_index]); + } parent->setEnabledKanjiMode(false); initialize(); @@ -576,6 +584,9 @@ // »ÝÌóâðmèµÄ©çÅã̶ðíB // »µÄú»µÄI¹B CppCFString str_to_fix(candidates[current_candidate_index]); + if(ClientConfiguration::theInstance().useNumericConversion()) { + str_to_fix = numconv_.Apply(str_to_fix); + } str_to_fix.eraseLast(1); // IÉM @@ -584,7 +595,6 @@ // Ìè parent->fix(str_to_fix); parent->display(CppCFString()); - parent->setEnabledKanjiMode(false); initialize(); } @@ -682,7 +692,11 @@ sendCurrentCandidateToServerToRegister(); // »ÝÌóâðmèB - parent->fix(candidates[current_candidate_index]); + if(ClientConfiguration::theInstance().useNumericConversion()) { + parent->fix(numconv_.Apply(candidates[current_candidate_index])); + } else { + parent->fix(candidates[current_candidate_index]); + } if (status == STATUS_BLACK_WITH_WINDOW) { // EChEð¶éB @@ -873,8 +887,12 @@ return CppCFString().append(0x25bd).append(root_to_display).append('*').append(okuri_to_display); } else if (status == STATUS_BLACK || status == STATUS_BLACK_WITH_WINDOW) { + CppCFString str = candidates[current_candidate_index]; + if(ClientConfiguration::theInstance().useNumericConversion()) { + str = numconv_.Apply(str); + } // ¥»ÝÌóâ - return CppCFString().append(0x25bc).append(candidates[current_candidate_index]); + return CppCFString().append(0x25bc).append(str); } else if (status == STATUS_PROMPT) { // [vvg][üÍ] @@ -895,16 +913,22 @@ } else if (status == STATUS_BLACK) { result = candidates[current_candidate_index]; - + if(ClientConfiguration::theInstance().useNumericConversion()) { + result = numconv_.Apply(candidates[current_candidate_index]); + } + // IÉM sendCurrentCandidateToServerToRegister(); } else if (status == STATUS_BLACK_WITH_WINDOW) { result = candidates[current_candidate_index]; - + if(ClientConfiguration::theInstance().useNumericConversion()) { + result = numconv_.Apply(result); + } + // IÉM sendCurrentCandidateToServerToRegister(); - + // EChEð¶éB closeCandidatesWindow(); } @@ -984,6 +1008,18 @@ current_candidate_index = 0; ::askServerTheCandidates(cfdata_query, candidates); + + // lÏ·ªLø©H + if(ClientConfiguration::theInstance().useNumericConversion() && numconv_.Setup(query)) { + std::vector<CppCFString> result; + CppCFData cfdata; + + cfdata.own(numconv_.NormalizedKey().toCFData()); + + ::askServerTheCandidates(cfdata, result); + + candidates.insert(candidates.end(), result.begin(), result.end()); + } } // ño @@ -1064,8 +1100,16 @@ void sendWordToServerToRegister(const CppCFString& index,const CppCFString& kanji) { CppCFData query; + CppCFString str; + NumericConverter conv; - query.own(CppCFString().append('-').append(index).append(SKK_MSG_DELIMITER).append(kanji.encode()).toCFData()); + if(ClientConfiguration::theInstance().useNumericConversion() && conv.Setup(index)) { + str = conv.NormalizedKey(); + } else { + str = index; + } + + query.own(CppCFString().append('-').append(str).append(SKK_MSG_DELIMITER).append(kanji.encode()).toCFData()); ServerConnectionFactory::theInstance().newConnection().send(kSKKRegisterThisToUserDic, query); } @@ -1081,7 +1125,11 @@ } else { for(std::vector<CppCFString>::const_iterator ite = candidates.begin() + (show_cands_window_after_Nth_cand - 1); ite != candidates.end(); ++ ite) { - cands_without_okuri.push_back(*ite); + if(ClientConfiguration::theInstance().useNumericConversion()) { + cands_without_okuri.push_back(numconv_.Apply(*ite)); + } else { + cands_without_okuri.push_back(*ite); + } } } Index: AquaSKK/KanjiConversionMode.h diff -u AquaSKK/KanjiConversionMode.h:1.4 AquaSKK/KanjiConversionMode.h:1.5 --- AquaSKK/KanjiConversionMode.h:1.4 Wed May 17 01:13:10 2006 +++ AquaSKK/KanjiConversionMode.h Sat Jun 3 10:23:18 2006 @@ -1,5 +1,5 @@ /* - $Id: KanjiConversionMode.h,v 1.4 2006/05/16 16:13:10 t-suwa Exp $ + $Id: KanjiConversionMode.h,v 1.5 2006/06/03 01:23:18 t-suwa Exp $ MacOS X implementation of the SKK input method. @@ -28,6 +28,7 @@ #include "ChildInputMode.h" #include "RegistrationStarter.h" #include "CppCFString.h" +#include "NumericConverter.h" class CppCFData; class ParentInputMode; @@ -35,6 +36,7 @@ class KanjiConversionMode: public ChildInputMode, public RegistrationStarter { bool handleInputChar(SKKChar skkchar); + NumericConverter numconv_; protected: static const int STATUS_NULL = 0; // ¿Ï·[hÉÈÁĢȢóÔBæªÉ¤à¥à³¢B @@ -44,7 +46,7 @@ static const int STATUS_BLACK_WITH_WINDOW = 4; // ¥[hÅAóâIðEChEªJ¢Ä¢éB static const int STATUS_PROMPT = 5; // vvgðoµÄ¢éB - class WordRegisterMode* word_register_mode; // NULLÅÈ¢ÍPêo^[hªN®B + WordRegisterMode* word_register_mode; // NULLÅÈ¢ÍPêo^[hªN®B int status; CppCFString root; // 輼̳¢ªBáFuèvÈçu¨v Index: AquaSKK/NumericConverter.cpp diff -u /dev/null AquaSKK/NumericConverter.cpp:1.1 --- /dev/null Sat Jun 3 10:23:18 2006 +++ AquaSKK/NumericConverter.cpp Sat Jun 3 10:23:18 2006 @@ -0,0 +1,302 @@ +/* + $Id: NumericConverter.cpp,v 1.1 2006/06/03 01:23:18 t-suwa Exp $ + + MacOS X implementation of the SKK input method. + + Copyright (C) 2006 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 <sstream> +#include "NumericConverter.h" + +// ====================================================================== +// 数値変換を実装するユーティリティ関数 +// ====================================================================== + +// 1024 → 1024 +std::string ConvertType1(const std::string& src) { + std::string result; + + for(unsigned i = 0; i < src.size(); ++ i) { + result += 0xa3; + result += (src[i] + 0x80); + } + + return result; +} + +// 1024 → 一〇二四 +std::string ConvertType2(const std::string& src) { + std::string result; + + for(unsigned i = 0; i < src.size(); ++ i) { + switch(src[i]) { + case '0': + result += "〇"; + break; + case '1': + result += "一"; + break; + case '2': + result += "二"; + break; + case '3': + result += "三"; + break; + case '4': + result += "四"; + break; + case '5': + result += "五"; + break; + case '6': + result += "六"; + break; + case '7': + result += "七"; + break; + case '8': + result += "八"; + break; + case '9': + result += "九"; + break; + } + } + + return result; +} + +// 1024 → 千二十四 +std::string ConvertType3(const std::string& src) { + const char* unit1[] = { "", "万", "億", "兆", "京", "垓" }; + const char* unit2[] = { "十", "百", "千" }; + std::string result; + + if(src.size() == 1 && src[0] == '0') { + return "〇"; + } + + for(unsigned i = src.find_first_not_of("0"); i < src.size(); ++ i) { + switch(src[i]) { + case '2': + result += "二"; + break; + case '3': + result += "三"; + break; + case '4': + result += "四"; + break; + case '5': + result += "五"; + break; + case '6': + result += "六"; + break; + case '7': + result += "七"; + break; + case '8': + result += "八"; + break; + case '9': + result += "九"; + break; + } + + int distance = src.size() - i; + + // 「十、百、千」以外の位 + if(distance > 4 && (distance - 1) % 4 == 0) { + if(src[i] == '1') { + result += "一"; + } + result += unit1[(distance - 1) / 4]; + } else { + // 十の位以上 + if(distance > 1) { + if(src[i] != '0') { + // 「一千万」の処理 + if(src[i] == '1' && distance > 4 && (distance - 2) % 4 == 2) { + result += "一"; + } + result += unit2[(distance - 2) % 4]; + } + } else { + // 一の位 + if(src[i] == '1') { + result += "一"; + } + } + } + } + + return result; +} + +// 数値再変換(AquaSKK では無視) +std::string ConvertType4(const std::string& src) { + return src; +} + +// 1024 → 壱阡弐拾四 +std::string ConvertType5(const std::string& src) { + const char* unit1[] = { "", "萬", "億", "兆", "京", "垓" }; + const char* unit2[] = { "拾", "百", "阡" }; + std::string result; + + if(src.size() == 1 && src[0] == '0') { + return "零"; + } + + for(unsigned i = src.find_first_not_of("0"); i < src.size(); ++ i) { + switch(src[i]) { + case '1': + result += "壱"; + break; + case '2': + result += "弐"; + break; + case '3': + result += "参"; + break; + case '4': + result += "四"; + break; + case '5': + result += "伍"; + break; + case '6': + result += "六"; + break; + case '7': + result += "七"; + break; + case '8': + result += "八"; + break; + case '9': + result += "九"; + break; + } + + int distance = src.size() - i; + + // 「十、百、千」以外の位 + if(distance > 4 && (distance - 1) % 4 == 0) { + result += unit1[(distance - 1) / 4]; + } else { + // 十の位以上 + if(distance > 1) { + if(src[i] != '0') { + result += unit2[(distance - 2) % 4]; + } + } + } + } + + return result; +} + +// 34 → 3四 +std::string ConvertType9(const std::string& src) { + return ConvertType1(src.substr(0, 1)) + ConvertType2(src.substr(1, 1)); +} + +// ====================================================================== +// クラスインタフェース +// ====================================================================== + +// 検索キーの正規化 +bool NumericConverter::Setup(const CppCFString& query) { + params_.clear(); + original_ = query; + + const char* numbers = "0123456789"; + std::string src(query.toStdString()); + std::string::size_type from = src.find_first_of(numbers); + + // 連続した数値を見つけたら vector に格納し、"#" に正規化 + while(from != std::string::npos) { + std::string::size_type to = src.find_first_not_of(numbers, from); + params_.push_back(src.substr(from, to - from)); + src.replace(from, to - from, "#"); + + from = src.find_first_of(numbers, to); + } + + normalized_ = CppCFString(src.c_str(), kCFStringEncodingEUC_JP); + + return !params_.empty(); +} + +// オリジナルのキー +CppCFString NumericConverter::OriginalKey() const { + return original_; +} + +// 正規化されたキー +CppCFString NumericConverter::NormalizedKey() const { + if(params_.empty()) return original_; + + return normalized_; +} + +// 数値変換を適用する +CppCFString NumericConverter::Apply(const CppCFString& candidate) const { + if(params_.empty()) return candidate; + + const char* numbers = "0123459"; + std::string result; + std::string src(candidate.toStdString()); + std::string::size_type pos = 0; + int index = 0; + + do { + pos = src.find_first_of(numbers, pos); + if(0 < pos && src[pos - 1] == '#') { + switch(src[pos]) { + case '0': // 無変換 + src.replace(pos - 1, 2, params_[index]); + break; + case '1': // 半角→全角変換 + src.replace(pos - 1, 2, ConvertType1(params_[index])); + break; + case '2': // 漢数字位取りなし + src.replace(pos - 1, 2, ConvertType2(params_[index])); + break; + case '3': // 漢数字位取りあり + src.replace(pos - 1, 2, ConvertType3(params_[index])); + break; + case '4': // 数値再変換(AquaSKK では無変換) + src.replace(pos - 1, 2, ConvertType4(params_[index])); + break; + case '5': // 小切手・手形 + src.replace(pos - 1, 2, ConvertType5(params_[index])); + break; + case '9': // 棋譜入力用 + src.replace(pos - 1, 2, ConvertType9(params_[index])); + break; + } + pos += params_[index].size(); + ++ index; + } + } while(pos != std::string::npos); + + return CppCFString(src.c_str(), kCFStringEncodingEUC_JP); +} Index: AquaSKK/NumericConverter.h diff -u /dev/null AquaSKK/NumericConverter.h:1.1 --- /dev/null Sat Jun 3 10:23:18 2006 +++ AquaSKK/NumericConverter.h Sat Jun 3 10:23:18 2006 @@ -0,0 +1,45 @@ +/* -*- c++ -*- + $Id: NumericConverter.h,v 1.1 2006/06/03 01:23:18 t-suwa Exp $ + + MacOS X implementation of the SKK input method. + + Copyright (C) 2006 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__NumericConverter__ +#define INC__NumericConverter__ + +#include <vector> +#include <string> +#include "CppCFString.h" + +// 数値変換をサポートするユーティリティ + +class NumericConverter { + CppCFString original_; + CppCFString normalized_; + std::vector<std::string> params_; + +public: + bool Setup(const CppCFString& query); + + CppCFString OriginalKey() const; + CppCFString NormalizedKey() const; + CppCFString Apply(const CppCFString& candidate) const; +}; + +#endif // INC__NumericConverter__ Index: AquaSKK/ServerMessageReceiver.mm diff -u AquaSKK/ServerMessageReceiver.mm:1.5 AquaSKK/ServerMessageReceiver.mm:1.6 --- AquaSKK/ServerMessageReceiver.mm:1.5 Wed Apr 26 22:36:12 2006 +++ AquaSKK/ServerMessageReceiver.mm Sat Jun 3 10:23:18 2006 @@ -1,5 +1,5 @@ /* -*- objc -*- - $Id: ServerMessageReceiver.mm,v 1.5 2006/04/26 13:36:12 t-suwa Exp $ + $Id: ServerMessageReceiver.mm,v 1.6 2006/06/03 01:23:18 t-suwa Exp $ MacOS X implementation of the SKK input method. @@ -118,13 +118,16 @@ break; case kBasicMessageIsNumericKeypad_HalfWidth: reply = valueForKey(KEY_numkeypad_use_halfwidth); - break; + break; case kBasicMessageIsAsciiModeStartup: reply = valueForKey(KEY_force_ascii_mode_startup); - break; + break; + case kBasicMessageUseNumericConversion: + reply = valueForKey(KEY_use_numeric_conversion); + break; case kBasicMessageKbdLayoutId: reply = valueForKey(KEY_keyboard_layout_id); - break; + break; default: break; } Index: AquaSKK/skkserv.cpp diff -u AquaSKK/skkserv.cpp:1.2 AquaSKK/skkserv.cpp:1.3 --- AquaSKK/skkserv.cpp:1.2 Wed Apr 26 22:36:12 2006 +++ AquaSKK/skkserv.cpp Sat Jun 3 10:23:18 2006 @@ -1,5 +1,5 @@ /* -*- c++ -*- - $Id: skkserv.cpp,v 1.2 2006/04/26 13:36:12 t-suwa Exp $ + $Id: skkserv.cpp,v 1.3 2006/06/03 01:23:18 t-suwa Exp $ MacOS X implementation of the SKK input method. @@ -122,7 +122,7 @@ fprintf(stderr, "AquaSKK(skkserv): Unknown command[0x%02x]\n", cmd); break; } - } while(cmd != '0'); + } while(sock.good() && cmd != '0'); sock.close(); std::cerr << "AquaSKK(skkserv): session closed[" << peer << "]" << std::endl;