Tomotaka SUWA
t-suw****@users*****
2006年 1月 8日 (日) 16:15:31 JST
Index: AquaSKK/BIM.cpp diff -u AquaSKK/BIM.cpp:1.11.2.1 AquaSKK/BIM.cpp:1.11.2.2 --- AquaSKK/BIM.cpp:1.11.2.1 Sat Jan 7 16:22:28 2006 +++ AquaSKK/BIM.cpp Sun Jan 8 16:15:30 2006 @@ -1,5 +1,5 @@ /* - $Id: BIM.cpp,v 1.11.2.1 2006/01/07 07:22:28 t-suwa Exp $ + $Id: BIM.cpp,v 1.11.2.2 2006/01/08 07:15:30 t-suwa Exp $ MacOS X implementation of the SKK input method. @@ -23,8 +23,6 @@ #define TARGET_API_MAC_CARBON 1 -#define kMENU_Pencil (kBaseResourceID + 1) - #include <Carbon/Carbon.h> #include <vector> #include <map> @@ -33,7 +31,6 @@ #include "BIM.h" #include "BIMInputEvents.h" #include "BIMClientServer.h" -#include "BIMScript.h" #include "CppCFString.h" #include "CppCFData.h" #include "InputMode.h" Index: AquaSKK/BIM.r diff -u AquaSKK/BIM.r:1.3 AquaSKK/BIM.r:1.3.4.1 --- AquaSKK/BIM.r:1.3 Tue Sep 6 10:25:12 2005 +++ AquaSKK/BIM.r Sun Jan 8 16:15:30 2006 @@ -1,105 +1,111 @@ /* - $Id: BIM.r,v 1.3 2005/09/06 01:25:12 t-suwa Exp $ - --------- - - MacOS X implementation of the SKK input method. - Copyright (C) 2002 phonohawk - - 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 + $Id: BIM.r,v 1.3.4.1 2006/01/08 07:15:30 t-suwa Exp $ + + MacOS X implementation of the SKK input method. + + Copyright (C) 2002 phonohawk + 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 */ -#define UseExtendedThingResource 1 -#include <Carbon/Carbon.r> -#include "BIMScript.h" +#define thng_RezTemplateVersion 1 -data 'cbnm' (0) { - // "org.ccm-software.AquaSKKInputMethod" Ì pascal ¶ñ - $"236f 7267 2e63 636d 2d73 6f66 7477 6172" - $"652e 4171 7561 534b 4b49 6e70 7574 4d65" - $"7468 6f64" -}; +#include <Carbon/Carbon.r> -resource 'thng' (128) -{ - 'tsvc', // R|[lg^CvBTextServiceÈÌÅ'tsvc' - 'inpm', // R|[lgTu^CvBInputMethodÈÌÅ'inpm' - 'askk', // j[NÈx_[R[hB - 0x8000 + kBIMScript * 0x100 + kBIMLanguage, // ¾êÝè - kAnyComponentFlagsMask, // kAnyComponentFlagsMaskÅȯêÎÈçÈ¢B - 'dlle', kBaseResourceID, // Gg|CgÌ¼Ì - 'STR ', kBaseResourceID, // IMÌ¼Ì - 'STR ', kBaseResourceID, // IM̼ÌiÇ¿çªÇÌæ¤Égíêé©ÍmçÈ¢j - 'ICON', kBaseResourceID, - 0x00010000, - componentHasMultiplePlatforms, - 15872 + kBIMScript * 0x200, - { - 0x8000 + kBIMScript * 0x100 + kBIMLanguage, // ¾êÝè - 'dlle', kBaseResourceID, 1000 - } -}; +#ifdef ppc_YES + #define TARGET_REZ_MAC_PPC 1 +#endif + +#ifdef i386_YES + #define TARGET_REZ_MAC_X86 1 +#endif + +#if !defined(TARGET_REZ_MAC_X86) + #define TARGET_REZ_MAC_X86 0 +#endif + +#if !(TARGET_REZ_MAC_PPC || TARGET_REZ_MAC_X86) + #if TARGET_CPU_X86 + #undef TARGET_REZ_MAC_X86 + #define TARGET_REZ_MAC_X86 1 + #elif TARGET_CPU_PPC + #undef TARGET_REZ_MAC_PPC + #define TARGET_REZ_MAC_PPC 1 + #endif +#endif + +#if TARGET_REZ_MAC_PPC && TARGET_REZ_MAC_X86 + #define TARGET_REZ_UNIVERSAL_COMPONENTS 1 + #define Target_PlatformType platformPowerPCNativeEntryPoint + #define Target_SecondPlatformType platformIA32NativeEntryPoint +#elif TARGET_REZ_MAC_X86 + #define Target_PlatformType platformIA32NativeEntryPoint +#else + #define Target_PlatformType platformPowerPCNativeEntryPoint +#endif -resource 'dlle' (kBaseResourceID) { - "BIMComponentDispatch" -}; +#define kAquaSKKBaseResouceID 16384 +#define kAquaSKKComponentFlags 0x8000 + smJapanese * 0x100 + langJapanese -resource 'MENU' (kBaseResourceID + 1) -{ - kBaseResourceID, - textMenuProc, - allEnabled, - enabled, - "00000", - { - "Show Keyboard Palette", noIcon, "K", noMark, plain, - "Show Send Event Palette", noIcon, "D", noMark, plain, - "-", noIcon, noKey, noMark, plain, - "Convert To Lowercase", noIcon, "L", noMark, plain, - "Convert To Uppercase", noIcon, "U", noMark, plain - } +// "org.ccm-software.AquaSKKInputMethod" Ì pascal ¶ñ +data 'cbnm' (0) { + $"236f 7267 2e63 636d 2d73 6f66 7477 6172" + $"652e 4171 7561 534b 4b49 6e70 7574 4d65" + $"7468 6f64" +}; + +resource 'thng' (kAquaSKKBaseResouceID) { + 'tsvc', // type + 'inpm', // subtype + 'askk', // manufacturer + 0, // component flags + 0, // component flags mask + 0, // code type + 0, // code ID + 'STR ', // name type + kAquaSKKBaseResouceID, // name ID + 'STR ', // info type + kAquaSKKBaseResouceID + 1, // info ID + 0, // icon type + 0, // icon ID + 0x00010000, // version + componentHasMultiplePlatforms, // registration flags + 0, // resource ID of icon family + { // component platform information + kAquaSKKComponentFlags, + 'dlle', + kAquaSKKBaseResouceID, + Target_PlatformType, +#if TARGET_REZ_UNIVERSAL_COMPONENTS + kAquaSKKComponentFlags, + 'dlle', + kAquaSKKBaseResouceID, + Target_SecondPlatformType +#endif + }; }; -resource 'xmnu' (kBaseResourceID + 1) -{ - versionZero - { - { - dataItem {'SHKP', kMenuShiftModifier + kMenuControlModifier + kMenuNoCommandModifier, - currScript, 0, 0, noHierID, sysFont, naturalGlyph}, - dataItem {'SHDP', kMenuShiftModifier + kMenuControlModifier + kMenuNoCommandModifier, - currScript, 0, 0, noHierID, sysFont, naturalGlyph}, - skipItem {}, - dataItem {'CLOW', kMenuShiftModifier + kMenuControlModifier + kMenuNoCommandModifier, - currScript, 0, 0, noHierID, sysFont, naturalGlyph}, - dataItem {'CUPP', kMenuShiftModifier + kMenuControlModifier + kMenuNoCommandModifier, - currScript, 0, 0, noHierID, sysFont, naturalGlyph} - } - } +resource 'dlle' (kAquaSKKBaseResouceID) { + "BIMComponentDispatch" }; -resource 'STR ' (kBaseResourceID) -{ +resource 'STR ' (kAquaSKKBaseResouceID) { "AquaSKK" }; -resource 'STR#' (kBaseResourceID + 1) -{ - { - "Show Keyboard Palette", - "Hide Keyboard Palette", - "Show Send Event Palette", - "Hide Send Event Palette" - } +resource 'STR ' (kAquaSKKBaseResouceID + 1) { + "AquaSKK Input Method for Mac OS X" }; Index: AquaSKK/BIMComponent.cpp diff -u AquaSKK/BIMComponent.cpp:1.4.2.1 AquaSKK/BIMComponent.cpp:1.4.2.2 --- AquaSKK/BIMComponent.cpp:1.4.2.1 Sat Jan 7 16:22:28 2006 +++ AquaSKK/BIMComponent.cpp Sun Jan 8 16:15:30 2006 @@ -1,23 +1,24 @@ /* - $Id: BIMComponent.cpp,v 1.4.2.1 2006/01/07 07:22:28 t-suwa Exp $ - --------- - - MacOS X implementation of the SKK input method. - Copyright (C) 2002 phonohawk + $Id: BIMComponent.cpp,v 1.4.2.2 2006/01/08 07:15:30 t-suwa Exp $ + + MacOS X implementation of the SKK input method. - 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 + Copyright (C) 2002 phonohawk + 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 */ #define TARGET_API_MAC_CARBON 1 @@ -26,7 +27,6 @@ #include "BIM.h" #include "BIMClientServer.h" #include "BIMComponent.h" -#include "BIMScript.h" #include "CppCFString.h" #include "CppCFData.h" #include "InputMode.h" @@ -43,116 +43,84 @@ #include "ParentInputMode.h" #include "IMSessionInputMode.h" -extern "C" pascal ComponentResult BIMComponentDispatch( ComponentParameters *inParams, Handle inSessionHandle ); +extern "C" pascal ComponentResult BIMComponentDispatch(ComponentParameters* inParams, Handle inSessionHandle); static long gInstanceRefCount = 0; static MenuRef gTextServiceMenu = NULL; -static ComponentResult CallBIMFunction( ComponentParameters *inParams, ProcPtr inProcPtr, - SInt32 inProcInfo ); -static ComponentResult CallBIMFunctionWithStorage( Handle inStorage, - ComponentParameters *inParams, - ProcPtr inProcPtr, SInt32 inProcInfo ); +static ComponentResult CallBIMFunction(ComponentParameters* inParams, ProcPtr inProcPtr, SInt32 inProcInfo); +static ComponentResult CallBIMFunctionWithStorage(Handle inStorage, ComponentParameters* inParams, ProcPtr inProcPtr, + SInt32 inProcInfo); // R|[lgÌGg|CgBextern "C"·×«©Ç¤©Íè©ÅÈ¢ªA껤µÄ¨B -extern "C" pascal ComponentResult BIMComponentDispatch( ComponentParameters *inParams, Handle inSessionHandle) -{ +extern "C" pascal ComponentResult BIMComponentDispatch(ComponentParameters* inParams, Handle inSessionHandle) { ComponentResult result; result = noErr; - switch (inParams->what) - { - // Component Manager©çÌwß - case kComponentOpenSelect: - result = CallBIMFunction( inParams, (ProcPtr) BIMOpenComponent, - uppOpenComponentProcInfo ); - break; - - case kComponentCloseSelect: - result = CallBIMFunctionWithStorage( inSessionHandle, inParams, - (ProcPtr) BIMCloseComponent, - uppCloseComponentProcInfo ); - break; - - case kComponentCanDoSelect: - result = CallBIMFunction( inParams, (ProcPtr) BIMCanDo, uppCanDoProcInfo ); - break; - - case kComponentVersionSelect: - result = CallBIMFunction( inParams, (ProcPtr) BIMGetVersion, uppGetVersionProcInfo ); - break; - - // TSM©çÌwß - case kCMGetScriptLangSupport: - result = CallBIMFunctionWithStorage( inSessionHandle, inParams, - (ProcPtr) BIMGetScriptLangSupport, - uppGetScriptLangSupportProcInfo ); - break; - - case kCMInitiateTextService: - result = CallBIMFunctionWithStorage( inSessionHandle, inParams, - (ProcPtr) BIMInitiateTextService, - uppInitiateTextServiceProcInfo ); - break; - - case kCMTerminateTextService: - result = CallBIMFunctionWithStorage( inSessionHandle, inParams, - (ProcPtr) BIMTerminateTextService, - uppTerminateTextServiceProcInfo ); - break; - - case kCMActivateTextService: - result = CallBIMFunctionWithStorage( inSessionHandle, inParams, - (ProcPtr) BIMActivateTextService, - uppActivateTextServiceProcInfo ); - break; - - case kCMDeactivateTextService: - result = CallBIMFunctionWithStorage( inSessionHandle, inParams, - (ProcPtr) BIMDeactivateTextService, - uppDeactivateTextServiceProcInfo ); - break; - - case kCMTextServiceEvent: - result = CallBIMFunctionWithStorage( inSessionHandle, inParams, - (ProcPtr) BIMTextServiceEventRef, - uppTextServiceEventRefProcInfo ); - break; - - case kCMGetTextServiceMenu: - result = CallBIMFunctionWithStorage( inSessionHandle, inParams, - (ProcPtr) BIMGetTextServiceMenu, - uppGetTextServiceMenuProcInfo ); - break; - - case kCMFixTextService: - result = CallBIMFunctionWithStorage( inSessionHandle, inParams, - (ProcPtr) BIMFixTextService, - uppFixTextServiceProcInfo ); - break; - - case kCMHidePaletteWindows: - result = CallBIMFunctionWithStorage( inSessionHandle, inParams, - (ProcPtr) BIMHidePaletteWindows, - uppHidePaletteWindowsProcInfo ); - break; - - case kCMCopyTextServiceInputModeList: - result = CallBIMFunctionWithStorage( inSessionHandle, inParams, - (ProcPtr) BIMCopyTextServiceInputModeList, - uppCopyTextServiceInputModeListInfo ); - break; - - case kCMSetTextServiceProperty: - result = CallBIMFunctionWithStorage( inSessionHandle, inParams, - (ProcPtr) BIMSetTextServiceProperty, - uppSetTextServicePropertyInfo); - break; - - default: - result = badComponentSelector; - break; + switch(inParams->what) { + // Component Manager©çÌwß + case kComponentOpenSelect: + result = CallBIMFunction(inParams, (ProcPtr)BIMOpenComponent, uppOpenComponentProcInfo); + break; + case kComponentCloseSelect: + result = CallBIMFunctionWithStorage(inSessionHandle, inParams, (ProcPtr)BIMCloseComponent, + uppCloseComponentProcInfo); + break; + case kComponentCanDoSelect: + result = CallBIMFunction(inParams, (ProcPtr)BIMCanDo, uppCanDoProcInfo); + break; + case kComponentVersionSelect: + result = CallBIMFunction(inParams, (ProcPtr)BIMGetVersion, uppGetVersionProcInfo); + break; + // TSM©çÌwß + case kCMGetScriptLangSupport: + result = CallBIMFunctionWithStorage(inSessionHandle, inParams, (ProcPtr)BIMGetScriptLangSupport, + uppGetScriptLangSupportProcInfo); + break; + case kCMInitiateTextService: + result = CallBIMFunctionWithStorage(inSessionHandle, inParams, (ProcPtr)BIMInitiateTextService, + uppInitiateTextServiceProcInfo); + break; + case kCMTerminateTextService: + result = CallBIMFunctionWithStorage(inSessionHandle, inParams, (ProcPtr)BIMTerminateTextService, + uppTerminateTextServiceProcInfo); + break; + case kCMActivateTextService: + result = CallBIMFunctionWithStorage(inSessionHandle, inParams, (ProcPtr)BIMActivateTextService, + uppActivateTextServiceProcInfo); + break; + case kCMDeactivateTextService: + result = CallBIMFunctionWithStorage(inSessionHandle, inParams, (ProcPtr)BIMDeactivateTextService, + uppDeactivateTextServiceProcInfo); + break; + case kCMTextServiceEvent: + result = CallBIMFunctionWithStorage(inSessionHandle, inParams, (ProcPtr)BIMTextServiceEventRef, + uppTextServiceEventRefProcInfo); + break; + case kCMGetTextServiceMenu: + result = CallBIMFunctionWithStorage(inSessionHandle, inParams, (ProcPtr)BIMGetTextServiceMenu, + uppGetTextServiceMenuProcInfo); + break; + case kCMFixTextService: + result = CallBIMFunctionWithStorage(inSessionHandle, inParams, (ProcPtr)BIMFixTextService, + uppFixTextServiceProcInfo); + break; + case kCMHidePaletteWindows: + result = CallBIMFunctionWithStorage(inSessionHandle, inParams, (ProcPtr) BIMHidePaletteWindows, + uppHidePaletteWindowsProcInfo); + break; + case kCMCopyTextServiceInputModeList: + result = CallBIMFunctionWithStorage(inSessionHandle, inParams, (ProcPtr)BIMCopyTextServiceInputModeList, + uppCopyTextServiceInputModeListInfo); + break; + case kCMSetTextServiceProperty: + result = CallBIMFunctionWithStorage(inSessionHandle, inParams, (ProcPtr)BIMSetTextServiceProperty, + uppSetTextServicePropertyInfo); + break; + default: + result = badComponentSelector; + break; } return result; @@ -166,8 +134,6 @@ result = noErr; sessionHandle = nil; - BIMLog("Open Component(%d)\n", inComponentInstance); - // ÅÌCX^X¾Á½çO[olàú»B if(gInstanceRefCount == 0) { result = BIMInitialize(inComponentInstance, &gTextServiceMenu); @@ -208,81 +174,73 @@ } // ZN^ªpÂ\©Ç¤©ðÔ·B -pascal ComponentResult BIMCanDo( SInt16 inSelector ) -{ +pascal ComponentResult BIMCanDo(SInt16 inSelector) { Boolean result; - switch( inSelector ) - { - case kComponentOpenSelect: - case kComponentCloseSelect: - case kComponentCanDoSelect: - case kComponentVersionSelect: - result = true; - break; - - case kCMGetScriptLangSupport: - case kCMInitiateTextService: - case kCMTerminateTextService: - case kCMActivateTextService: - case kCMDeactivateTextService: - case kCMTextServiceEvent: - case kCMGetTextServiceMenu: - case kCMFixTextService: - case kCMHidePaletteWindows: - case kCMCopyTextServiceInputModeList: - case kCMSetTextServiceProperty: - result = true; - break; - - default: - result = false; - break; + switch(inSelector) { + case kComponentOpenSelect: + case kComponentCloseSelect: + case kComponentCanDoSelect: + case kComponentVersionSelect: + result = true; + break; + + case kCMGetScriptLangSupport: + case kCMInitiateTextService: + case kCMTerminateTextService: + case kCMActivateTextService: + case kCMDeactivateTextService: + case kCMTextServiceEvent: + case kCMGetTextServiceMenu: + case kCMFixTextService: + case kCMHidePaletteWindows: + case kCMCopyTextServiceInputModeList: + case kCMSetTextServiceProperty: + result = true; + break; + + default: + result = false; + break; } return result; } // »ÝA±ÌÖªÄÎêé±ÆÍÈ¢B -pascal ComponentResult BIMGetVersion( void ) -{ +pascal ComponentResult BIMGetVersion() { return 0x00010000; } // ¾êÌíÞðÔ·B -pascal ComponentResult BIMGetScriptLangSupport( Handle inSessionHandle, - ScriptLanguageSupportHandle *outScriptHandle ) -{ -#pragma unused (inSessionHandle) - +pascal ComponentResult BIMGetScriptLangSupport(Handle inSessionHandle, ScriptLanguageSupportHandle* outScriptHandle) { OSStatus result = noErr; ScriptLanguageRecord scriptLanguageRecord; - if( *outScriptHandle == NULL ) { - *outScriptHandle = (ScriptLanguageSupportHandle) NewHandle ( sizeof( SInt16 ) ); - if( *outScriptHandle == NULL ) + if(*outScriptHandle == NULL) { + *outScriptHandle = (ScriptLanguageSupportHandle)NewHandle(sizeof(SInt16)); + if(*outScriptHandle == NULL) result = memFullErr; } - - if( result == noErr ) { - SetHandleSize( (Handle) *outScriptHandle, sizeof( SInt16 ) ); + + if(result == noErr) { + SetHandleSize((Handle)*outScriptHandle, sizeof(SInt16)); result = MemError(); - if( result == noErr ) - ( **outScriptHandle )->fScriptLanguageCount = 0; + if(result == noErr) + (**outScriptHandle)->fScriptLanguageCount = 0; } // Unicodeðg¤±Æðé¾·éB - if( result == noErr ) { + if(result == noErr) { scriptLanguageRecord.fScript = kTextEncodingUnicodeDefault; - scriptLanguageRecord.fLanguage = kBIMLanguage; - result = PtrAndHand( &scriptLanguageRecord, (Handle) *outScriptHandle, - sizeof( ScriptLanguageRecord ) ); - if( result == noErr ) + scriptLanguageRecord.fLanguage = langJapanese; + result = PtrAndHand(&scriptLanguageRecord, (Handle)*outScriptHandle, sizeof(ScriptLanguageRecord)); + if(result == noErr) (**outScriptHandle)->fScriptLanguageCount++; } - - if( result ){ - if( *outScriptHandle ) { - DisposeHandle( (Handle) *outScriptHandle ); + + if(result) { + if(*outScriptHandle) { + DisposeHandle((Handle)*outScriptHandle ); *outScriptHandle = NULL; } } @@ -302,29 +260,23 @@ } // ±ÌÖÍÄÎêÈ¢B -pascal ComponentResult BIMTerminateTextService( Handle inSessionHandle ) -{ -#pragma unused (inSessionHandle) - +pascal ComponentResult BIMTerminateTextService(Handle inSessionHandle) { return noErr; } // TextServiceªANeBuÉÈéB -pascal ComponentResult BIMActivateTextService( Handle inSessionHandle ) -{ - return BIMSessionActivate( (BIMSessionHandle) inSessionHandle ); +pascal ComponentResult BIMActivateTextService(Handle inSessionHandle) { + return BIMSessionActivate((BIMSessionHandle)inSessionHandle); } // TextServiceªANeBuÅÈÈéB -pascal ComponentResult BIMDeactivateTextService( Handle inSessionHandle ) -{ - return BIMSessionDeactivate( (BIMSessionHandle) inSessionHandle ); +pascal ComponentResult BIMDeactivateTextService(Handle inSessionHandle) { + return BIMSessionDeactivate((BIMSessionHandle)inSessionHandle); } // R|[lgÌCxgnh -pascal ComponentResult BIMTextServiceEventRef( Handle inSessionHandle, EventRef inEventRef ) -{ - return BIMSessionEvent( (BIMSessionHandle) inSessionHandle, inEventRef ); +pascal ComponentResult BIMTextServiceEventRef(Handle inSessionHandle, EventRef inEventRef) { + return BIMSessionEvent((BIMSessionHandle)inSessionHandle, inEventRef); } // Mj [ðÔ·B @@ -335,15 +287,13 @@ } // mè -pascal ComponentResult BIMFixTextService( Handle inSessionHandle ) -{ - return BIMSessionFix( (BIMSessionHandle) inSessionHandle ); +pascal ComponentResult BIMFixTextService(Handle inSessionHandle) { + return BIMSessionFix((BIMSessionHandle)inSessionHandle); } // pbgðB· -pascal ComponentResult BIMHidePaletteWindows( Handle inSessionHandle ) -{ - return BIMSessionHidePalettes( (BIMSessionHandle) inSessionHandle ); +pascal ComponentResult BIMHidePaletteWindows(Handle inSessionHandle) { + return BIMSessionHidePalettes((BIMSessionHandle)inSessionHandle); } // üÍ[hÌêðÔ· @@ -371,17 +321,14 @@ return noErr; } -pascal ComponentResult BIMSetTextServiceProperty( - Handle inSessionHandle, - TextServicePropertyTag tag, TextServicePropertyValue value) -{ +pascal ComponentResult BIMSetTextServiceProperty(Handle inSessionHandle, TextServicePropertyTag tag, + TextServicePropertyValue value) { if(tag != kTextServiceInputModePropertyTag) { BIMLog("Can't SetTextServiceProperty[%d]\n", tag); return tsmComponentPropertyUnsupportedErr; } CFStringRef newMode = (CFStringRef)value; - IMSessionInputMode* inputMode - = (*(BIMSessionHandle)inSessionHandle)->imsession_input_mode; + IMSessionInputMode* inputMode = (*(BIMSessionHandle)inSessionHandle)->imsession_input_mode; // ASCII [hÅú»·é(BIMInitiateTextService àQÆ) if((*(BIMSessionHandle)inSessionHandle)->asciimode_startup) { @@ -396,24 +343,21 @@ } } - if(CFStringCompare(newMode, - kTextServiceInputModeJapaneseKatakana, 0) == 0) { + if(CFStringCompare(newMode, kTextServiceInputModeJapaneseKatakana, 0) == 0) { if(!inputMode->isZenKataInputMode()) { inputMode->goZenKataInputMode(); return noErr; } } - if(CFStringCompare(newMode, - kTextServiceInputModeJapaneseHalfWidthKana, 0) == 0) { + if(CFStringCompare(newMode, kTextServiceInputModeJapaneseHalfWidthKana, 0) == 0) { if(!inputMode->isHanKataInputMode()) { inputMode->goHanKataInputMode(); return noErr; } } - if(CFStringCompare(newMode, - kTextServiceInputModeJapaneseFullWidthRoman, 0) == 0) { + if(CFStringCompare(newMode, kTextServiceInputModeJapaneseFullWidthRoman, 0) == 0) { if(!inputMode->isZenAscInputMode()) { inputMode->goZenAscInputMode(); return noErr; @@ -432,28 +376,25 @@ // UPPð쬵AÄÔB // Carbon«ÅUPPÁÄ{ÉKv éÌ©H -static ComponentResult CallBIMFunction( ComponentParameters *inParams, ProcPtr inProcPtr, - SInt32 inProcInfo ) -{ +static ComponentResult CallBIMFunction(ComponentParameters* inParams, ProcPtr inProcPtr, SInt32 inProcInfo) { ComponentResult result; ComponentFunctionUPP componentFunctionUPP; result = noErr; - componentFunctionUPP = NewComponentFunctionUPP( inProcPtr, inProcInfo ); - result = CallComponentFunction( inParams, componentFunctionUPP ); - DisposeComponentFunctionUPP( componentFunctionUPP ); + componentFunctionUPP = NewComponentFunctionUPP(inProcPtr, inProcInfo); + result = CallComponentFunction(inParams, componentFunctionUPP); + DisposeComponentFunctionUPP(componentFunctionUPP); return result; } -static ComponentResult CallBIMFunctionWithStorage( Handle inStorage, - ComponentParameters *inParams, - ProcPtr inProcPtr, SInt32 inProcInfo ) -{ + +static ComponentResult CallBIMFunctionWithStorage(Handle inStorage, ComponentParameters* inParams, ProcPtr inProcPtr, + SInt32 inProcInfo) { ComponentResult result; ComponentFunctionUPP componentFunctionUPP; result = noErr; - componentFunctionUPP = NewComponentFunctionUPP( inProcPtr, inProcInfo ); - result = CallComponentFunctionWithStorage( inStorage, inParams, componentFunctionUPP ); - DisposeComponentFunctionUPP( componentFunctionUPP ); + componentFunctionUPP = NewComponentFunctionUPP(inProcPtr, inProcInfo); + result = CallComponentFunctionWithStorage(inStorage, inParams, componentFunctionUPP); + DisposeComponentFunctionUPP(componentFunctionUPP); return result; } Index: AquaSKK/CandidatesWindowController.mm diff -u AquaSKK/CandidatesWindowController.mm:1.2 AquaSKK/CandidatesWindowController.mm:1.2.2.1 --- AquaSKK/CandidatesWindowController.mm:1.2 Sat Oct 8 00:08:36 2005 +++ AquaSKK/CandidatesWindowController.mm Sun Jan 8 16:15:30 2006 @@ -1,23 +1,24 @@ /* -*- objc -*- - $Id: CandidatesWindowController.mm,v 1.2 2005/10/07 15:08:36 t-suwa Exp $ - --------- - - MacOS X implementation of the SKK input method. - Copyright (C) 2002 phonohawk - - 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 + $Id: CandidatesWindowController.mm,v 1.2.2.1 2006/01/08 07:15:30 t-suwa Exp $ + + MacOS X implementation of the SKK input method. + + Copyright (C) 2002 phonohawk + 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 */ #import <AppKit/AppKit.h> @@ -27,62 +28,53 @@ @implementation CandidatesWindowController -- initWithCandidates:(NSArray*)cands -{ - self = [super initWithWindowNibName:@"Candidates"]; - [self window]; // load now - - self->candidates = [[NSArray alloc] initWithArray:cands]; - - [[self window] - setBackgroundColor: - [[PreferencesController sharedController] windowColor]]; - - [[self window] - setAlphaValue: - [[PreferencesController sharedController] windowAlpha]]; - - self->candidates_view = [[CandidatesView alloc] initWithCandidates:cands]; - [[self window] setContentSize:[candidates_view bounds].size]; // candidates_viewÌTCYÉÝèB - [[[self window] contentView] addSubview:candidates_view]; // EChEÉuB - - [[self window] setLevel:NSFloatingWindowLevel]; - - return self; -} - -- (NSArray*)getCandidates -{ - return candidates; -} - -- (void)dealloc -{ - [super dealloc]; -} - -- (void)showNextFrame -{ - [candidates_view showNextFrame]; -} - -- (void)showPrevFrame -{ - [candidates_view showPrevFrame]; -} - -- (unsigned)getCandidatesPerFrame -{ - return [candidates_view getCandidatesPerFrame]; -} - -- (unsigned)getNumOfFrames -{ - return [candidates_view getNumOfFrames]; +- initWithCandidates:(NSArray*)cands { + self = [super initWithWindowNibName:@"Candidates"]; + [self window]; // load now + + self->candidates = [[NSArray alloc] initWithArray:cands]; + + // wiF + [[self window] setBackgroundColor: [[PreferencesController sharedController] windowColor]]; + + // s§¾x + [[self window] setAlphaValue: [[PreferencesController sharedController] windowAlpha]]; + + self->candidates_view = [[CandidatesView alloc] initWithCandidates:cands]; + [[self window] setContentSize:[candidates_view bounds].size]; + [[[self window] contentView] addSubview:candidates_view]; + + // EBhEx + [[self window] setLevel:NSFloatingWindowLevel]; + + return self; +} + +- (NSArray*)getCandidates { + return candidates; +} + +- (void)dealloc { + [super dealloc]; +} + +- (void)showNextFrame { + [candidates_view showNextFrame]; +} + +- (void)showPrevFrame { + [candidates_view showPrevFrame]; +} + +- (unsigned)getCandidatesPerFrame { + return [candidates_view getCandidatesPerFrame]; +} + +- (unsigned)getNumOfFrames { + return [candidates_view getNumOfFrames]; } -- (void)setCurrentFrame:(unsigned)frame -{ +- (void)setCurrentFrame:(unsigned)frame { [candidates_view setCurrentFrame:frame]; } Index: AquaSKK/ChangeLog diff -u AquaSKK/ChangeLog:1.20.2.1 AquaSKK/ChangeLog:1.20.2.2 --- AquaSKK/ChangeLog:1.20.2.1 Sat Jan 7 16:22:28 2006 +++ AquaSKK/ChangeLog Sun Jan 8 16:15:30 2006 @@ -1,3 +1,18 @@ +2006-01-08 Tomotaka SUWA <t.suw****@mac*****> + + * BIMScript.h, skkicons.r: íB + + * Info-AquaSKKInputMethod.plist: ACRÌÝèðÇÁB + + * BIM.r: Universal Binary ÉÎB + + * SKKDictionary.*: à\¢ðåÉÏXB«Ì[hÔðZkB + tab Éæéâ®ð{ÆƯ¶®ìÉüPB + + * Dictionary.h: eí[eBeBNXðÇÁB + + * CppCFString.* (toStdString): VKÇÁB + 2006-01-07 Tomotaka SUWA <t.suw****@mac*****> * Japanese.lproj/Preferences.nib/*: eíIvVÌÇÁ Index: AquaSKK/CppCFString.cpp diff -u AquaSKK/CppCFString.cpp:1.3 AquaSKK/CppCFString.cpp:1.3.2.1 --- AquaSKK/CppCFString.cpp:1.3 Wed Nov 9 00:02:24 2005 +++ AquaSKK/CppCFString.cpp Sun Jan 8 16:15:30 2006 @@ -1,10 +1,10 @@ /* - $Id: CppCFString.cpp,v 1.3 2005/11/08 15:02:24 t-suwa Exp $ + $Id: CppCFString.cpp,v 1.3.2.1 2006/01/08 07:15:30 t-suwa Exp $ MacOS X implementation of the SKK input method. Copyright (C) 2002-2004 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 @@ -30,8 +30,7 @@ CppCFString::CppCFString(const CppCFString& cpp_cf_string_src) { // Rs[RXgN^ - cf_string = CFStringCreateMutableCopy(NULL, 0, - cpp_cf_string_src.getString()); + cf_string = CFStringCreateMutableCopy(NULL, 0, cpp_cf_string_src.getString()); } CppCFString::CppCFString(UniChar c) { @@ -127,9 +126,7 @@ CppCFString& CppCFString::eraseLast(const unsigned int n_chars) { // ·³Í`FbNµÈ¢BÓB - CFStringDelete(cf_string, - CFRangeMake(CFStringGetLength(cf_string) - n_chars, - n_chars)); + CFStringDelete(cf_string, CFRangeMake(CFStringGetLength(cf_string) - n_chars, n_chars)); return *this; } @@ -137,8 +134,7 @@ return substring(start_pos, length()); } -CppCFString CppCFString::substring(const unsigned int start_pos, - const unsigned int end_pos) const { +CppCFString CppCFString::substring(const unsigned int start_pos, const unsigned int end_pos) const { // start_posÍÜÞªend_posÍÜÜÈ¢B // «E`FbN͵ȢÌÅÓB const UniChar* unistr = CFStringGetCharactersPtr(cf_string); @@ -209,8 +205,7 @@ return result; } -bool CppCFString::startsWith(const CppCFString& str, - int search_start_pos) const { +bool CppCFString::startsWith(const CppCFString& str, int search_start_pos) const { // ·³ª«èĢȢH if (length() - static_cast<unsigned>(search_start_pos) < str.length()) return false; @@ -218,8 +213,7 @@ return substring(search_start_pos, search_start_pos + str.length()) == str; } -bool CppCFString::endsWith(const CppCFString& str, - int search_start_pos) const { +bool CppCFString::endsWith(const CppCFString& str, int search_start_pos) const { if(search_start_pos == -1) search_start_pos = length() - 1; @@ -227,23 +221,16 @@ if(static_cast<unsigned>(search_start_pos) < str.length() - 1) return false; - return substring(search_start_pos + 1 - str.length(), - search_start_pos + 1) == str; + return substring(search_start_pos + 1 - str.length(), search_start_pos + 1) == str; } -CppCFString& CppCFString::replace(const CppCFString& from, - const CppCFString& to) { - CFStringFindAndReplace(cf_string, - from.getString(), - to.getString(), - CFRangeMake(0, length()), - 0); +CppCFString& CppCFString::replace(const CppCFString& from, const CppCFString& to) { + CFStringFindAndReplace(cf_string, from.getString(), to.getString(), CFRangeMake(0, length()), 0); return *this; } -CppCFString CppCFString::replaceClone(const CppCFString& from, - const CppCFString& to) const { +CppCFString CppCFString::replaceClone(const CppCFString& from, const CppCFString& to) const { return clone().replace(from, to); } @@ -319,6 +306,14 @@ return buf; } +std::string CppCFString::toStdString(CFStringEncoding encoding) const { + char* tmp = toCString(encoding); + std::string str(tmp); + delete[] tmp; + + return str; +} + CppCFString CppCFString::clone() const { return CppCFString(*this); } @@ -327,89 +322,76 @@ const int len = CFStringGetLength(cf_string); UniChar* unistr = const_cast<UniChar*>(CFStringGetCharactersPtr(cf_string)); bool unistr_is_independent = false; - if (unistr == NULL) - { + if(unistr == NULL) { unistr = new UniChar[len]; unistr_is_independent = true; - + CFStringGetCharacters(cf_string,CFRangeMake(0,len),unistr); } std::vector<CppCFString> result; int pos = 0; - while (pos < len) - { - if (unistr[pos] == delim) // f~^¾Á½B - { + while(pos < len) { + // f~^¾Á½ + if(unistr[pos] == delim) { pos++; - } - else // f~^ÅÈ¢¶ª©t©Á½B - { + } else { + // f~^ÅÈ¢¶ª©t©Á½ int blockstart = pos; int blockend = -1; - for (int i = blockstart;i < len;i++) - { + for(int i = blockstart;i < len;i++) { // f~^ðT·B - if (unistr[i] == delim) - { + if(unistr[i] == delim) { blockend = i; break; } } - - if (blockend == -1) // f~^ª©t©çÈ©Á½ - { + + // f~^ª©t©çÈ©Á½ + if(blockend == -1) { blockend = len; // ÅãÜÅðg[NÆ·éB } - + result.push_back(substring(blockstart,blockend)); pos = blockend; } } - if (unistr_is_independent) - { + if(unistr_is_independent) { delete[] unistr; } return result; } // ñoÖQ -CppCFString operator+(const CppCFString& l, const CppCFString& r) -{ +CppCFString operator+(const CppCFString& l, const CppCFString& r) { return CppCFString(l).append(r); } -CppCFString operator+(const CppCFString& l, const UniChar r) -{ +CppCFString operator+(const CppCFString& l, const UniChar r) { return CppCFString(l).append(r); } -CppCFString operator+(const UniChar l, const CppCFString& r) -{ +CppCFString operator+(const UniChar l, const CppCFString& r) { return CppCFString().append(l).append(r); } bool operator==(const CppCFString& l, const CppCFString& r) { - return CFStringCompare(l.getString(), - r.getString(), 0) == kCFCompareEqualTo; + return CFStringCompare(l.getString(), r.getString(), 0) == kCFCompareEqualTo; } bool operator!=(const CppCFString& l, const CppCFString& r) { - return CFStringCompare(l.getString(), - r.getString(), 0) != kCFCompareEqualTo; + return CFStringCompare(l.getString(), r.getString(), 0) != kCFCompareEqualTo; } bool operator<(const CppCFString& l, const CppCFString& r) { - return CFStringCompare(l.getString(), - r.getString(), 0) == kCFCompareLessThan; + return CFStringCompare(l.getString(), r.getString(), 0) == kCFCompareLessThan; } bool operator>(const CppCFString& l, const CppCFString& r) { - return CFStringCompare(l.getString(), - r.getString(), 0) == kCFCompareGreaterThan; + return CFStringCompare(l.getString(), r.getString(), 0) == kCFCompareGreaterThan; } bool operator<=(const CppCFString& l, const CppCFString& r) { @@ -424,9 +406,8 @@ CppCFString join(UniChar delim, const std::vector<CppCFString>& vec) { CppCFString result; - - for(std::vector<CppCFString>::const_iterator ite = vec.begin(); - ite != vec.end(); ++ ite) { + + for(std::vector<CppCFString>::const_iterator ite = vec.begin(); ite != vec.end(); ++ ite) { result += *ite + delim; } @@ -453,7 +434,7 @@ for (;unistr != unistr_end; unistr += sizeof(UniChar)) { result = 5 * result + *unistr; } - + if(unistr_is_independent) delete[] unistr; return result; Index: AquaSKK/CppCFString.h diff -u AquaSKK/CppCFString.h:1.3 AquaSKK/CppCFString.h:1.3.2.1 --- AquaSKK/CppCFString.h:1.3 Wed Nov 9 00:02:24 2005 +++ AquaSKK/CppCFString.h Sun Jan 8 16:15:30 2006 @@ -1,28 +1,31 @@ /* -*- c++ -*- - $Id: CppCFString.h,v 1.3 2005/11/08 15:02:24 t-suwa Exp $ - --------- - - MacOS X implementation of the SKK input method. - Copyright (C) 2002 phonohawk - - 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 + $Id: CppCFString.h,v 1.3.2.1 2006/01/08 07:15:30 t-suwa Exp $ + + MacOS X implementation of the SKK input method. + + Copyright (C) 2002 phonohawk + 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 */ #pragma once +#include <Carbon/Carbon.h> #include <vector> +#include <string> // CFStringÌbp[B // CFMutableStringRefðbvµAstd::stringâjava.lang.StringBufferÌæ¤Éµ¦éæ¤É·éB @@ -75,6 +78,7 @@ virtual UniChar* toUniCharPtr() const; virtual CFMutableDataRef toCFData() const; virtual char* toCString(CFStringEncoding encoding = kCFStringEncodingMacRomanLatin1) const; + virtual std::string toStdString(CFStringEncoding encoding = kCFStringEncodingEUC_JP) const; virtual CppCFString clone() const; virtual std::vector<CppCFString> split(UniChar delim) const; @@ -93,7 +97,6 @@ CppCFString join(UniChar delim, const std::vector<CppCFString>& vec); - class hash_CppCFString { public: size_t operator() (const CppCFString& str) const; Index: AquaSKK/Dictionary.h diff -u AquaSKK/Dictionary.h:1.3 AquaSKK/Dictionary.h:1.3.2.1 --- AquaSKK/Dictionary.h:1.3 Wed Nov 9 00:02:24 2005 +++ AquaSKK/Dictionary.h Sun Jan 8 16:15:30 2006 @@ -1,10 +1,10 @@ /* - $Id: Dictionary.h,v 1.3 2005/11/08 15:02:24 t-suwa Exp $ + $Id: Dictionary.h,v 1.3.2.1 2006/01/08 07:15:30 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 @@ -24,6 +24,8 @@ #pragma once #include <vector> +#include <string> +#include <numeric> class OkuriganaEntry; class CppCFString; @@ -66,3 +68,373 @@ virtual void removeOkuriNasi(const CppCFString& index, const CppCFString& kanji) = 0; }; + +// IuWFNgðA·ét@N^ +struct SKKConcatObject { + template<typename T> + std::string operator()(const std::string& seed, const T& obj) const { + return seed + "/" + obj.Description(); + } +}; + +// ª¶ñðԵĢPÈp[T +class SKKEntryParser { + const std::string& target_; + const bool isOkuriAri_; // ÎÛªuè èv©Ç¤© + + std::string fetch(bool first = false) const { + static std::string::size_type pos1; + static std::string::size_type pos2; + + if(first) { + pos1 = pos2 = 0; + } + + pos1 = target_.find_first_not_of('/', pos2); + pos2 = target_.find_first_of('/', pos1); + + // ©Â©Á½H + if(pos1 != std::string::npos && pos2 != std::string::npos) { + if(!isOkuriAri_ || target_[pos1] != '[') { + return target_.substr(pos1, pos2 - pos1); + } + } + return std::string(); + } + +public: + SKKEntryParser(const std::string& str, bool isOkuriAri = false) : target_(str), isOkuriAri_(isOkuriAri) { + // empty + } + std::string First() const { + return fetch(true); + } + std::string Next() const { + return fetch(); + } +}; + +// PêÌÏ·óâ(/óâ;ß/ ¨ /word_;annotation_/ ¨ Description()) +class SKKCandidate { + std::string word_; + std::string annotation_; + + void setup(const std::string& str) { + std::string::size_type pos = str.find_first_of(';'); + + // ߪ éH + if(pos != std::string::npos) { + annotation_ = str.substr(pos + 1); + } + word_ = str.substr(0, pos); + } + +public: + SKKCandidate() : word_(std::string()), annotation_(std::string()) { + // empty + } + SKKCandidate(const std::string& word, const std::string& annotation) : word_(word), annotation_(annotation) { + // empty + } + SKKCandidate(const std::string& candidate) { + setup(candidate); + } + SKKCandidate(const SKKCandidate& src) : word_(src.word_), annotation_(src.annotation_) { + // empty + } + + bool IsEmpty() const { + return word_.empty(); + } + std::string Word() const { + return word_; + } + std::string Annotation() const { + return annotation_; + } + std::string Description() const { + return Word() + (annotation_.empty() ? "" : (";" + annotation_)); + } + + bool operator==(const SKKCandidate& rhs) const { + // ßÍärµÈ¢ + return word_ == rhs.word_; + } +}; + +typedef std::vector<SKKCandidate> SKKCandidateContainer; +typedef SKKCandidateContainer::iterator SKKCandidateIterator; + +// è èGgÌqgîñ([//~//] ̪) +class SKKOkuriHint { + std::string kana_; + SKKCandidateContainer candidates_; + + void setup(const std::string& str) { + std::string ret; + SKKEntryParser parser(str); + + kana_ = parser.First(); + for(ret = parser.Next(); !ret.empty(); ret = parser.Next()) { + candidates_.push_back(ret); + } + } + + SKKCandidate fetchCandidate(bool first = false) const { + static int i; + if(first) { + i = 0; + } + + if(i < Count()) { + return candidates_[i ++]; + } + return SKKCandidate(); + } + +public: + SKKOkuriHint() { + // empty + } + SKKOkuriHint(const std::string& kana, const SKKCandidate& candidate) : kana_(kana) { + candidates_.push_back(candidate); + } + SKKOkuriHint(const std::string& str) { + setup(str); + } + SKKOkuriHint(const SKKOkuriHint& src) : kana_(src.kana_), candidates_(src.candidates_) { + // empty + } + + bool IsEmpty() const { + return kana_.empty(); + } + std::string Kana() const { + return kana_; + } + void SetKana(const std::string& kana) { + kana_ = kana; + } + + SKKCandidate First() const { + return fetchCandidate(true); + } + SKKCandidate Next() const { + return fetchCandidate(); + } + int Count() const { + return candidates_.size(); + } + + void Add(const SKKCandidate& theCandidate) { + Remove(theCandidate); + candidates_.insert(candidates_.begin(), theCandidate); + } + void Remove(const SKKCandidate& theCandidate) { + candidates_.erase(std::remove(candidates_.begin(), candidates_.end(), theCandidate), candidates_.end()); + } + std::string Description() const { + return '[' + std::accumulate(candidates_.begin(), candidates_.end(), Kana(), SKKConcatObject()) + "/]"; + } + + bool operator==(const SKKOkuriHint& rhs) const { + return (kana_ == rhs.kana_ && candidates_ == rhs.candidates_); + } +}; + +typedef std::vector<SKKOkuriHint> SKKOkuriHintContainer; +typedef SKKOkuriHintContainer::iterator SKKOkuriHintIterator; + +// SKK «Ìêsð\»·éNX +class SKKEntry { + bool isOkuriAri_; // è è©Ç¤© + std::string key_; // ©oµê + SKKCandidateContainer candidates_; // Ï·óâ + SKKOkuriHintContainer hints_; // è èGgÌqgîñ + std::string::size_type pos1_; + std::string::size_type pos2_; + + std::string firstHint(const std::string& str) { + pos1_ = pos2_ = str.find("/["); + return nextHint(str); + } + std::string nextHint(const std::string& str) { + pos1_ = str.find_first_not_of("/[", pos2_ + 1); + pos2_ = str.find_first_of(']', pos1_); + + // ©Â©Á½H + if(pos1_ != std::string::npos && pos2_ != std::string::npos) { + return str.substr(pos1_, pos2_ - pos1_); + } + return std::string(); + } + + void setup(const std::string& str) { + std::string ret; + SKKEntryParser parser(str, isOkuriAri_); + + // ܸÊíÌóâð²«o· + for(ret = parser.First(); !ret.empty(); ret = parser.Next()) { + candidates_.push_back(ret); + } + + if(!isOkuriAri_) return; + + // ÉAè èGgÌqgîñð²«o· + for(ret = firstHint(str); !ret.empty(); ret = nextHint(str)) { + hints_.push_back(ret); + } + } + + SKKCandidate fetchCandidate(bool first = false) const { + static int i; + if(first) { + i = 0; + } + + if(i < Count()) { + return candidates_[i ++]; + } + return SKKCandidate(); + } + SKKOkuriHint fetchHint(bool first = false) const { + static int i; + if(first) { + i = 0; + } + + if(i < HintCount()) { + return hints_[i ++]; + } + return SKKOkuriHint(); + } + + SKKCandidate updateCandidate(const SKKCandidate& theCandidate) { + SKKCandidate target; + + // ßðÜÞ®SÈGgðT· + SKKCandidateIterator i = std::find(candidates_.begin(), candidates_.end(), theCandidate); + // ©Â©Á½H + if(i != candidates_.end()) { + target = *i; + RemoveOkuriNasi(target); + } else { + target = theCandidate; + } + + // æªÉÇÁ + candidates_.insert(candidates_.begin(), target); + + return target; + } + + SKKEntry() {} + + SKKEntry(bool isOkuriAri, const std::string& key, const std::string& cand) : isOkuriAri_(isOkuriAri), key_(key) { + setup(cand); + } + + SKKEntry(bool isOkuriAri, const std::string& key) : isOkuriAri_(isOkuriAri), key_(key) { + // empry + } + +public: + // «ÌGgðp[XµÄGgð쬷é + static SKKEntry ParseOkuriAri(const std::string& key, const std::string& candidate) { + return SKKEntry(true, key, candidate); + } + static SKKEntry ParseOkuriNasi(const std::string& key, const std::string& candidate) { + return SKKEntry(false, key, candidate); + } + + // L[¾¯ÌGgð쬷é + static SKKEntry CreateOkuriAri(const std::string& key) { + return SKKEntry(true, key); + } + static SKKEntry CreateOkuriNasi(const std::string& key) { + return SKKEntry(false, key); + } + + // Rs[RXgN^ + SKKEntry(const SKKEntry& src) : isOkuriAri_(src.isOkuriAri_), key_(src.key_), + candidates_(src.candidates_), hints_(src.hints_), pos1_(src.pos1_), pos2_(src.pos2_) { + // empty + } + + // óâÉÖ·éì + SKKCandidate First() const { + return fetchCandidate(true); + } + SKKCandidate Next() const { + return fetchCandidate(); + } + int Count() const { + return candidates_.size(); + } + + // qgÉÖ·éì + SKKOkuriHint FirstHint() const { + return fetchHint(true); + } + SKKOkuriHint NextHint() const { + return fetchHint(); + } + int HintCount() const { + return hints_.size(); + } + + // è èóâÌÇÁ + void AddOkuriAri(const SKKCandidate& theCandidate, const std::string& okuri) { + SKKCandidate target = updateCandidate(theCandidate); + + // qgª©Â©êÎXV·é + for(SKKOkuriHintIterator i = hints_.begin(); i != hints_.end(); ++ i) { + if(i->Kana() == okuri) { + i->Add(target); + return; + } + } + + // ©Â©çȯêÎVKÌqgðÇÁ + hints_.insert(hints_.begin(), SKKOkuriHint(okuri, target)); + } + // èȵóâÌÇÁ + void AddOkuriNasi(const SKKCandidate& theCandidate) { + updateCandidate(theCandidate); + } + + // è èóâÌí + void RemoveOkuriAri(const SKKCandidate& theCandidate) { + RemoveOkuriNasi(theCandidate); + + // qgàí + for(SKKOkuriHintIterator i = hints_.begin(); i != hints_.end(); /* empty */) { + i->Remove(theCandidate); + if(i->Count() == 0) { + i = hints_.erase(i); + } else { + ++ i; + } + } + } + // èȵóâÌí + void RemoveOkuriNasi(const SKKCandidate& theCandidate) { + candidates_.erase(std::remove(candidates_.begin(), candidates_.end(), theCandidate), candidates_.end()); + } + + std::string Key() const { + return key_; + } + std::string Candidate() const { + std::string ret; + ret = std::accumulate(candidates_.begin(), candidates_.end(), ret, SKKConcatObject()); + if(hints_.empty()) { + return ret + "/"; + } + + return std::accumulate(hints_.begin(), hints_.end(), ret, SKKConcatObject()) + "/"; + } + std::string Description() const { + return Key() + " " + Candidate(); + } +}; Index: AquaSKK/Info-AquaSKKInputMethod.plist diff -u AquaSKK/Info-AquaSKKInputMethod.plist:1.4 AquaSKK/Info-AquaSKKInputMethod.plist:1.4.2.1 --- AquaSKK/Info-AquaSKKInputMethod.plist:1.4 Mon Dec 19 23:46:44 2005 +++ AquaSKK/Info-AquaSKKInputMethod.plist Sun Jan 8 16:15:30 2006 @@ -26,6 +26,8 @@ <string>2005-12-19</string> <key>CSResourcesFileMapped</key> <true/> + <key>tsInputMethodIconFileKey</key> + <string>AquaSKK-InputMethod.tif</string> <key>ComponentInputModeDict</key> <dict> <key>tsInputModeListKey</key> Index: AquaSKK/PreferencesController.h diff -u AquaSKK/PreferencesController.h:1.6.2.1 AquaSKK/PreferencesController.h:1.6.2.2 --- AquaSKK/PreferencesController.h:1.6.2.1 Sat Jan 7 16:22:29 2006 +++ AquaSKK/PreferencesController.h Sun Jan 8 16:15:30 2006 @@ -1,11 +1,10 @@ /* -*- objc -*- - $Id: PreferencesController.h,v 1.6.2.1 2006/01/07 07:22:29 t-suwa Exp $ - --------- - + $Id: PreferencesController.h,v 1.6.2.2 2006/01/08 07:15:30 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 @@ -76,8 +75,6 @@ - (NSColor *)windowColor; - (float)windowAlpha; -- (NSDictionary*)makeKbdDictionary:(KeyboardLayoutRef)kbd; -- (void)initKbdLayoutPopUp; - (int)kbdLayoutId; - (IBAction)changeKbdLayoutId:(id)sender; - (BOOL)isSkkEggLikeNewline; @@ -87,8 +84,6 @@ - (BOOL)isAsciiModeStartup; - (IBAction)asciiModeStartup:(id)sender; -- (void)setState:(SInt32)msgID state:(int)state; - - (NSArray *)path; - (IBAction)selectMainDic:(id)sender; Index: AquaSKK/PreferencesController.mm diff -u AquaSKK/PreferencesController.mm:1.6.2.1 AquaSKK/PreferencesController.mm:1.6.2.2 --- AquaSKK/PreferencesController.mm:1.6.2.1 Sat Jan 7 16:22:29 2006 +++ AquaSKK/PreferencesController.mm Sun Jan 8 16:15:30 2006 @@ -1,10 +1,10 @@ /* -*- objc -*- - $Id: PreferencesController.mm,v 1.6.2.1 2006/01/07 07:22:29 t-suwa Exp $ + $Id: PreferencesController.mm,v 1.6.2.2 2006/01/08 07:15:30 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 @@ -66,6 +66,82 @@ @implementation PreferencesController +- (NSDictionary*)makeKbdDictionary:(KeyboardLayoutRef)kbd { + KeyboardLayoutIdentifier kbdId; + CFStringRef name; + IconRef icon = NULL; + NSImage* image = NULL; + + NSMutableDictionary* kbdDict = [[[NSMutableDictionary alloc] init] autorelease]; + + // L[{[hÌ ID ƼOAACRðæ¾·é + KLGetKeyboardLayoutProperty(kbd, kKLIdentifier, (const void**)&kbdId); + KLGetKeyboardLayoutProperty(kbd, kKLLocalizedName, (const void**)&name); + KLGetKeyboardLayoutProperty(kbd, kKLIcon, (const void**)&icon); + + // IconRef ¨ NSImage Ï· + if(icon) { + IconFamilyHandle iconFamily; + NSData* iconData; + + IconRefToIconFamily(icon, kSelectorAllAvailableData, &iconFamily); + iconData = [NSData dataWithBytes: *iconFamily length: iconFamily[0]->resourceSize]; + image = [[[NSImage alloc] initWithData:iconData] autorelease]; + } + + [kbdDict setObject:[NSNumber numberWithInt:kbdId] forKey:KbdIdKey]; + [kbdDict setObject:(NSString*)name forKey:KbdNameKey]; + [kbdDict setObject:image forKey:KbdIconKey]; + + return kbdDict; +} + +- (void)initKbdLayoutPopUp { + CFIndex count; + KeyboardLayoutRef kbd; + SInt32 groupId; + NSMutableArray* kbdArray = [[[NSMutableArray alloc] init] autorelease]; + + // XNvgª smRoman Å éL[{[hCAEgðSÄæ¾·é + KLGetKeyboardLayoutCount(&count); + for(CFIndex i = 0; i < count; ++ i) { + KLGetKeyboardLayoutAtIndex(i, &kbd); + KLGetKeyboardLayoutProperty(kbd, kKLGroupIdentifier, (const void**)&groupId); + if(groupId != smRoman) continue; + + // ID ƼOÌ«ðÇÁ·é + [kbdArray addObject:[self makeKbdDictionary:kbd]]; + } + + // CAEg¼Å\[g·é + NSSortDescriptor* localizedNameDescriptor = [[NSSortDescriptor alloc] initWithKey:KbdNameKey ascending:YES]; + [localizedNameDescriptor autorelease]; + NSArray* sortDescriptors = [NSArray arrayWithObject:localizedNameDescriptor]; + NSArray* sortedArray = [kbdArray sortedArrayUsingDescriptors:sortDescriptors]; + + // j [ð\zµÄAPopUpButton É\èt¯é + kbdLayoutMenu = [[[NSMenu alloc] initWithTitle:@""] autorelease]; + NSEnumerator* enumerator = [sortedArray objectEnumerator]; + NSDictionary* dict; + while(dict = [enumerator nextObject]) { + [kbdLayoutMenu addItemWithTitle:[dict objectForKey:KbdNameKey] action:nil keyEquivalent:@""]; + NSMenuItem* item = [kbdLayoutMenu itemWithTitle:[dict objectForKey:KbdNameKey]]; + [item setTag:[[dict objectForKey:KbdIdKey] intValue]]; + [item setImage:[dict objectForKey:KbdIconKey]]; + } + [kbdLayoutPopUp setMenu:kbdLayoutMenu]; +} + +- (void)setState:(SInt32)msgID state:(int)state { + bool boolState = state ? true : false; + + CppCFData data(&boolState, sizeof(bool)); + + ClientConnectionFactory::theInstance().newConnection().send(msgID, data); + + [self saveUserDefault:self]; +} + + (PreferencesController*)sharedController { static PreferencesController* _shared_instance = nil; if(_shared_instance == nil) { @@ -79,7 +155,7 @@ [self window]; // xÏXFt[eBO - [[self window] setLevel:NSFloatingWindowLevel]; + //[[self window] setLevel:NSPopUpMenuWindowLevel]; // o×ÝèÌú» NSMutableDictionary* templateDefaults = [NSMutableDictionary dictionary]; @@ -192,72 +268,6 @@ return [winTransparent doubleValue]; } -- (NSDictionary*)makeKbdDictionary:(KeyboardLayoutRef)kbd { - KeyboardLayoutIdentifier kbdId; - CFStringRef name; - IconRef icon = NULL; - NSImage* image = NULL; - - NSMutableDictionary* kbdDict = [[[NSMutableDictionary alloc] init] autorelease]; - - // L[{[hÌ ID ƼOAACRðæ¾·é - KLGetKeyboardLayoutProperty(kbd, kKLIdentifier, (const void**)&kbdId); - KLGetKeyboardLayoutProperty(kbd, kKLLocalizedName, (const void**)&name); - KLGetKeyboardLayoutProperty(kbd, kKLIcon, (const void**)&icon); - - // IconRef ¨ NSImage Ï· - if(icon) { - IconFamilyHandle iconFamily; - NSData* iconData; - - IconRefToIconFamily(icon, kSelectorAllAvailableData, &iconFamily); - iconData = [NSData dataWithBytes: *iconFamily length: iconFamily[0]->resourceSize]; - image = [[[NSImage alloc] initWithData:iconData] autorelease]; - } - - [kbdDict setObject:[NSNumber numberWithInt:kbdId] forKey:KbdIdKey]; - [kbdDict setObject:(NSString*)name forKey:KbdNameKey]; - [kbdDict setObject:image forKey:KbdIconKey]; - - return kbdDict; -} - -- (void)initKbdLayoutPopUp { - CFIndex count; - KeyboardLayoutRef kbd; - SInt32 groupId; - NSMutableArray* kbdArray = [[[NSMutableArray alloc] init] autorelease]; - - // XNvgª smRoman Å éL[{[hCAEgðSÄæ¾·é - KLGetKeyboardLayoutCount(&count); - for(CFIndex i = 0; i < count; ++ i) { - KLGetKeyboardLayoutAtIndex(i, &kbd); - KLGetKeyboardLayoutProperty(kbd, kKLGroupIdentifier, (const void**)&groupId); - if(groupId != smRoman) continue; - - // ID ƼOÌ«ðÇÁ·é - [kbdArray addObject:[self makeKbdDictionary:kbd]]; - } - - // CAEg¼Å\[g·é - NSSortDescriptor* localizedNameDescriptor = [[NSSortDescriptor alloc] initWithKey:KbdNameKey ascending:YES]; - [localizedNameDescriptor autorelease]; - NSArray* sortDescriptors = [NSArray arrayWithObject:localizedNameDescriptor]; - NSArray* sortedArray = [kbdArray sortedArrayUsingDescriptors:sortDescriptors]; - - // j [ð\zµÄAPopUpButton É\èt¯é - kbdLayoutMenu = [[[NSMenu alloc] initWithTitle:@""] autorelease]; - NSEnumerator* enumerator = [sortedArray objectEnumerator]; - NSDictionary* dict; - while(dict = [enumerator nextObject]) { - [kbdLayoutMenu addItemWithTitle:[dict objectForKey:KbdNameKey] action:nil keyEquivalent:@""]; - NSMenuItem* item = [kbdLayoutMenu itemWithTitle:[dict objectForKey:KbdNameKey]]; - [item setTag:[[dict objectForKey:KbdIdKey] intValue]]; - [item setImage:[dict objectForKey:KbdIconKey]]; - } - [kbdLayoutPopUp setMenu:kbdLayoutMenu]; -} - - (int)kbdLayoutId { return [[kbdLayoutPopUp selectedItem] tag]; } @@ -295,16 +305,6 @@ [self setState:kBasicMessageIsAsciiModeStartup state:[sender state]]; } -- (void)setState:(SInt32)msgID state:(int)state { - bool boolState = state ? true : false; - - CppCFData data(&boolState, sizeof(bool)); - - ClientConnectionFactory::theInstance().newConnection().send(msgID, data); - - [self saveUserDefault:self]; -} - // SKK« - (NSString*)getPathToMainDic { Index: AquaSKK/PrivateRunLoop.mm diff -u AquaSKK/PrivateRunLoop.mm:1.2 AquaSKK/PrivateRunLoop.mm:1.2.2.1 --- AquaSKK/PrivateRunLoop.mm:1.2 Sat Oct 8 00:08:36 2005 +++ AquaSKK/PrivateRunLoop.mm Sun Jan 8 16:15:30 2006 @@ -1,9 +1,9 @@ /* -*- objc -*- - $Id: PrivateRunLoop.mm,v 1.2 2005/10/07 15:08:36 t-suwa Exp $ + $Id: PrivateRunLoop.mm,v 1.2.2.1 2006/01/08 07:15:30 t-suwa Exp $ MacOS X implementation of the SKK input method. - 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 @@ -26,10 +26,7 @@ #include <CoreServices/CoreServices.h> #include "PrivateRunLoop.h" -PrivateRunLoop::PrivateRunLoop( - const CFStringRef mode, CFRunLoopSourceRef runLoopSource) - : mode_(mode), runLoop_(0) -{ +PrivateRunLoop::PrivateRunLoop(const CFStringRef mode, CFRunLoopSourceRef runLoopSource) : mode_(mode), runLoop_(0) { // Û runLoopSource_ = (CFRunLoopSourceRef)CFRetain(runLoopSource); @@ -37,18 +34,10 @@ MPCreateQueue(¬ifyQueue_); // ^XNðç¹é - MPCreateTask(PrivateRunLoop::entryPoint, - this, - 0, - notifyQueue_, - NULL, - NULL, - 0, - &taskID_); + MPCreateTask(PrivateRunLoop::entryPoint, this, 0, notifyQueue_, NULL, NULL, 0, &taskID_); } -PrivateRunLoop::~PrivateRunLoop() -{ +PrivateRunLoop::~PrivateRunLoop() { // ^XNð~ßé CFRunLoopStop(runLoop_); @@ -61,29 +50,24 @@ } // ^XN{Ì -OSStatus PrivateRunLoop::entryPoint(void* param) -{ +OSStatus PrivateRunLoop::entryPoint(void* param) { // autorelease pool ðú»µÈ¢ÆA[NµÄµÜ¤ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - PrivateRunLoop* self = (PrivateRunLoop*)param; - self->runLoop_ = CFRunLoopGetCurrent(); + PrivateRunLoop* me = (PrivateRunLoop*)param; + me->runLoop_ = CFRunLoopGetCurrent(); // ÄÎÛðÇÁ - CFRunLoopAddSource(self->runLoop_, - self->runLoopSource_, - self->mode_); + CFRunLoopAddSource(me->runLoop_, me->runLoopSource_, me->mode_); // CFRunLoopStop() ªÄÎêéÜÅCxgð·é SInt32 result; do { - result = CFRunLoopRunInMode(self->mode_, 1, true); + result = CFRunLoopRunInMode(me->mode_, 1, true); } while(result != kCFRunLoopRunStopped); // ãn - CFRunLoopRemoveSource(self->runLoop_, - self->runLoopSource_, - self->mode_); + CFRunLoopRemoveSource(me->runLoop_, me->runLoopSource_, me->mode_); [pool release]; Index: AquaSKK/SKKDictionary.cpp diff -u AquaSKK/SKKDictionary.cpp:1.6 AquaSKK/SKKDictionary.cpp:1.6.2.1 --- AquaSKK/SKKDictionary.cpp:1.6 Tue Nov 15 00:37:13 2005 +++ AquaSKK/SKKDictionary.cpp Sun Jan 8 16:15:30 2006 @@ -1,10 +1,10 @@ /* - $Id: SKKDictionary.cpp,v 1.6 2005/11/14 15:37:13 t-suwa Exp $ + $Id: SKKDictionary.cpp,v 1.6.2.1 2006/01/08 07:15:30 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,567 +21,409 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include <CoreFoundation/CoreFoundation.h> -#include <map> -#include <vector> #include <iostream> #include <fstream> -#include <cerrno> -#include <cstring> +#include <algorithm> +#include <numeric> #include <ctime> -#include <unistd.h> -#include <pthread.h> +#include <sys/types.h> #include <sys/stat.h> +#include <unistd.h> #include "CppCFString.h" #include "OkuriganaEntry.h" #include "Dictionary.h" #include "SKKDictionary.h" +#include "SKKConfig.h" -// àÖ -static void parseOkuriAriEntry(const CppCFString& line, CppCFString& index, - std::vector<OkuriganaEntry>& entries); - -static void parseOkuriNasiEntry(const CppCFString& line, CppCFString& index, - std::vector<CppCFString>& entries); - -SKKDictionary::SKKDictionary(const std::string& fpath) : fpath_(fpath) { - load(); -} - -SKKDictionary::~SKKDictionary() { - close(); -} - -void SKKDictionary::changeDictionaryFile(const std::string& fpath) { - close(); - fpath_ = fpath; - load(); -} +#pragma mark --- SKK common functions --- -void SKKDictionary::load() { - struct stat st; - if(stat(fpath_.c_str(), &st) < 0) { - std::cerr << "AquaSKK: stat(" << fpath_ << ") failed: " - << std::strerror(errno) << std::endl; - return; - } +// SKKDictionary Æ SKKUserDictionary ɤʷéèâì +namespace skkdic { + const std::string OkuriAriMark = ";; okuri-ari entries."; + const std::string OkuriNasiMark = ";; okuri-nasi entries."; + const int SAVE_LIMIT_COUNT = 50; + const int SAVE_TIMEOUT = 10 * 60; // 10 ª - // ÊíÌt@CÅÍÈ¢H - if(!S_ISREG(st.st_mode)) { - std::cerr << "AquaSKK: [" << fpath_ << "] is NOT regular file." - << std::endl; - return; - } + // «t@CðJ¢ÄAokuri-ari ÌæªÜÅV[N·é + bool OpenAndSeek(const std::string& path, std::ifstream& dic) { + // «ÌXe[^Xðæ¾ + struct stat st; + if(stat(path.c_str(), &st) < 0) { + std::cerr << __FUNCTION__ << ": stat() failed" << std::endl; + return false; + } - std::ifstream dic(fpath_.c_str()); - if(!dic) { - return; - } + // M [t@CÈOH + if(!S_ISREG(st.st_mode)) { + std::cerr << __FUNCTION__ << ": [" << path << "] is NOT regular file" << std::endl; + return false; + } - std::string str_line; - while(!dic.eof()) { - std::getline(dic, str_line); - if(str_line == ";; okuri-ari entries.") break; - } + dic.open(path.c_str()); + if(!dic) { + std::cerr << __FUNCTION__ << ": [" << path << "] ifstream.open() failed" << std::endl; + return false; + } - // è èGg - while(!dic.eof()) { - std::getline(dic, str_line); - if(str_line.length() == 0) continue; - if(str_line == ";; okuri-nasi entries.") break; - if(str_line[0] == ';') continue; - - okuri_ari_unparsed.push_back(str_line); - } + // è èGgÌnÜèðT· + std::string line; + while(!dic.eof()) { + std::getline(dic, line); + if(skkdic::OkuriAriMark.find(line) == 0) break; + } - // èȵGg - while(!dic.eof()) { - std::getline(dic, str_line); - if(str_line.length() == 0) continue; - if(str_line[0] == ';') continue; - - okuri_nasi_unparsed.push_back(str_line); + return true; } - // p[TXbhðN®·é - pthread_t parser; - pthread_create(&parser, NULL, SKKDictionary::parserThreadRoutine, this); - pthread_detach(parser); -} + // SKKPair ðär·ét@N^(Effective STL, p.99) + class EntryCompare { + bool keyLess(const SKKPair::first_type& k1, const SKKPair::first_type& k2) const { + return k1 < k2; + } -int SKKDictionary::countOkuriAri() { - return okuri_ari_table.size(); -} + public: + // \[gpärÖ + bool operator()(const SKKPair& lhs, const SKKPair& rhs) const { + return keyLess(lhs.first, rhs.first); + } + // TõpärÖ(»Ì1) + bool operator()(const SKKPair& lhs, const SKKPair::first_type& k) const { + return keyLess(lhs.first, k); + } + // TõpärÖ(»Ì2) + bool operator()(const SKKPair::first_type& k, const SKKPair& rhs) const { + return keyLess(k, rhs.first); + } + }; -int SKKDictionary::countOkuriNasi() { - return okuri_nasi_table.size(); -} + // SKKPair ƶñðär·ét@N^ + class UserEntryCompare: public std::unary_function<SKKPair, bool> { + const std::string str_; -std::vector<OkuriganaEntry> -SKKDictionary::findOkuriAri(const CppCFString& query) { - // ©Â©Á½H - if(okuri_ari_table.find(query) != okuri_ari_table.end()) { - return *okuri_ari_table[query]; - } + public: + UserEntryCompare(const CppCFString& str) : str_(str.toStdString()) {} + bool operator()(const SKKPair& pair) const { + return pair.first == str_; + } + }; - // Gg©Ì¶ÝµÈ¢©Aܾp[X³êĢȢB - for(unsigned i = 0; i < okuri_ari_unparsed.size(); ++ i) { - CppCFString line(okuri_ari_unparsed[i].c_str(), - kCFStringEncodingEUC_JP); // EUC-JP + // «ðÛ¶·ét@N^ + class Store { + std::ofstream& ofs_; - if(line.startsWith(query)) { - CppCFString index; - std::vector<OkuriganaEntry> entries; + public: + Store(std::ofstream& ofs) : ofs_(ofs) {} + void operator()(const SKKPair& pair) { + ofs_ << pair.first << " " << pair.second << std::endl; + } + }; - parseOkuriAriEntry(line, index, entries); + // SKKEntry ¨ std::vector<OkuriganaEntry> Ï· + std::vector<OkuriganaEntry> ConvertOkuriAri(const SKKEntry& entry) { + // ܸqgîñ©çÇÁ·é + std::vector<OkuriganaEntry> result; + for(SKKOkuriHint hint = entry.FirstHint(); !hint.IsEmpty(); hint = entry.NextHint()) { + OkuriganaEntry okuri; - return entries; + okuri.setKana(CppCFString(hint.Kana().c_str(), kCFStringEncodingEUC_JP)); + for(SKKCandidate candidate = hint.First(); !candidate.IsEmpty(); candidate = hint.Next()) { + okuri.add(CppCFString(candidate.Description().c_str(), kCFStringEncodingEUC_JP)); + } + result.push_back(okuri); } - } - // ¶ÝµÈ¯êÎóÌ vector ðÔ· - return std::vector<OkuriganaEntry>(); -} + // ÉAÏ·óâðÇÁ·é + OkuriganaEntry wild; + for(SKKCandidate candidate = entry.First(); !candidate.IsEmpty(); candidate = entry.Next()) { + wild.add(CppCFString(candidate.Description().c_str(), kCFStringEncodingEUC_JP)); + } + result.push_back(wild); -std::vector<CppCFString> -SKKDictionary::findOkuriNasi(const CppCFString& query) { - // ©Â©Á½H - if(okuri_nasi_table.find(query) != okuri_nasi_table.end()) { - return *okuri_nasi_table[query]; + return result; } - // Gg©Ì¶ÝµÈ¢©Aܾp[X³êĢȢ - for(unsigned i = 0; i < okuri_nasi_unparsed.size() ; ++ i) { - CppCFString line(okuri_nasi_unparsed[i].c_str(), - kCFStringEncodingEUC_JP); // EUC-JP + // SKKEntry ¨ std::vector<CppCFString> Ï· + std::vector<CppCFString> ConvertOkuriNasi(const SKKEntry& entry) { + return CppCFString(entry.Candidate().c_str(), kCFStringEncodingEUC_JP).split('/'); + } +}; - if(line.startsWith(query)) { - CppCFString index; - std::vector<CppCFString> entries; +#pragma mark --- SKKDictionary --- - parseOkuriNasiEntry(line, index, entries); +SKKDictionary::SKKDictionary(const std::string& path) : path_(path) { + load(); +} - return entries; - } - } +SKKDictionary::~SKKDictionary() { + // empty +} - // ¶ÝµÈ¯êÎóÌ vector ðÔ· - return std::vector<CppCFString>(); +int SKKDictionary::countOkuriAri() { + return okuriAri_.size(); } -void SKKDictionary::parseAll() { - // @±Ì\bhÍAèLèGgQÆè³µGgQð - // ãë©çê¸Âp[XµÄ¢«AunparsedÌvector©çÍÁµÄsB - // O©çÅÈ¢RÍAOÌÚðÁµ½ÉãëÉ éÚð - // Oɸç³êĵܤ©àmêÈ¢×Å éB¸ç·ÉÍ]vÈÔª©©éB - // @ȨA±Ì\bhÍload()ª®¹·éOÉÄñÅÍÈçÈ¢B - - // èLèGg - for(std::vector<std::string>::iterator ite = okuri_ari_unparsed.end()-1; - okuri_ari_unparsed.size() > 0; ite --) { - CppCFString line(ite->c_str(), kCFStringEncodingEUC_JP); // EUC-JP - CppCFString index; - std::vector<OkuriganaEntry> entries; +int SKKDictionary::countOkuriNasi() { + return okuriNasi_.size(); +} - parseOkuriAriEntry(line, index, entries); +std::vector<OkuriganaEntry> SKKDictionary::findOkuriAri(const CppCFString& query) { + std::string index = query.toStdString(); - std::vector<OkuriganaEntry>* candidates = okuri_ari_table[index]; - if(candidates == NULL) { - candidates = new std::vector<OkuriganaEntry>; - okuri_ari_table[index] = candidates; - } - candidates->insert(candidates->end(), entries.begin(), entries.end()); - okuri_ari_unparsed.erase(ite); + // ©t©çÈ¢H + if(!std::binary_search(okuriAri_.begin(), okuriAri_.end(), index, skkdic::EntryCompare())) { + return std::vector<OkuriganaEntry>(); } - - // è³µGg - for(std::vector<std::string>::iterator ite = okuri_nasi_unparsed.end()-1; - okuri_nasi_unparsed.size() > 0; ite --) { - CppCFString line(ite->c_str(),kCFStringEncodingEUC_JP); // EUC-JP - CppCFString index; - std::vector<CppCFString> entries; - parseOkuriNasiEntry(line, index, entries); + EntryIterator i = std::lower_bound(okuriAri_.begin(), okuriAri_.end(), index, skkdic::EntryCompare()); - std::vector<CppCFString>* candidates = okuri_nasi_table[index]; - if(candidates == NULL) { - candidates = new std::vector<CppCFString>; - okuri_nasi_table[index] = candidates; - } - candidates->insert(candidates->end(), entries.begin(), entries.end()); - okuri_nasi_unparsed.erase(ite); - } - std::cerr << "SKK Dictionary(" << fpath_ << ")" << std::endl - << " okuri-ari: " << countOkuriAri() << " entries." - << std::endl - << " okuri-nasi: " << countOkuriNasi() << " entries." - << std::endl << std::endl; + return skkdic::ConvertOkuriAri(SKKEntry::ParseOkuriAri(i->first, i->second)); } -void SKKDictionary::close() { - std::map<CppCFString, std::vector<OkuriganaEntry>*>::iterator i; - for(i = okuri_ari_table.begin(); i != okuri_ari_table.end(); ++ i) { - delete i->second; - } - std::map<CppCFString, std::vector<CppCFString>*>::iterator j; - for(j = okuri_nasi_table.begin(); j != okuri_nasi_table.end(); ++ j) { - delete j->second; +std::vector<CppCFString> SKKDictionary::findOkuriNasi(const CppCFString& query) { + std::string index = query.toStdString(); + + // ©Â©çÈ¢H + if(!std::binary_search(okuriNasi_.begin(), okuriNasi_.end(), index, skkdic::EntryCompare())) { + return std::vector<CppCFString>(); } - std::map<CppCFString, std::vector<OkuriganaEntry>*>().swap(okuri_ari_table); - std::map<CppCFString, std::vector<CppCFString>*>().swap(okuri_nasi_table); - std::vector<std::string>().swap(okuri_ari_unparsed); - std::vector<std::string>().swap(okuri_nasi_unparsed); -} + EntryIterator i = std::lower_bound(okuriNasi_.begin(), okuriNasi_.end(), index, skkdic::EntryCompare()); -void* SKKDictionary::parserThreadRoutine(void* dic) { - static_cast<SKKDictionary*>(dic)->parseAll(); - return NULL; + return skkdic::ConvertOkuriNasi(SKKEntry::ParseOkuriNasi(i->first, i->second)); } -// ------------------------------------------------------------------ - -// [U[«ðÛ¶·×«XVñÌèl -const int SKK_JISYO_SAVE_COUNT = 50; +void SKKDictionary::changeDictionaryFile(const std::string& path) { + EntryContainer().swap(okuriAri_); + EntryContainer().swap(okuriNasi_); -// [U[«ðÛ¶·×«XVÔuÌèl(10 ª) -const int SKK_JISYO_SAVE_TIMEOUT = 10 * 60; + path_ = path; -SKKUserDictionary::SKKUserDictionary(const std::string& fpath) : fpath_(fpath) { load(); } -SKKUserDictionary::~SKKUserDictionary() { - // §IÉ«ðÛ¶·é - save(true); - - std::map<CppCFString, std::vector<OkuriganaEntry>*>::iterator i; - for(i = okuri_ari_table.begin(); i != okuri_ari_table.end(); ++ i) { - delete i->second; - } - std::map<CppCFString, std::vector<CppCFString>*>::iterator j; - for(j = okuri_nasi_table.begin(); j != okuri_nasi_table.end(); ++ j) { - delete j->second; - } -} +void SKKDictionary::load() { + std::string line; + std::string index; + std::string entry; + std::ifstream dic; -void SKKUserDictionary::load() { - struct stat st; - if(stat(fpath_.c_str(), &st) < 0) { - std::cerr << "AquaSKK: stat(" << fpath_ << ") failed: " - << std::strerror(errno) << std::endl; + if(!skkdic::OpenAndSeek(path_, dic)) { return; } - // ÊíÌt@CÅÍÈ¢H - if(!S_ISREG(st.st_mode)) { - std::cerr << "AquaSKK: [" << fpath_ << "] is NOT regular file." - << std::endl; - return; - } + while(1) { + dic >> index; + if(dic.eof()) break; + dic.ignore(1, ' '); + std::getline(dic, line); + if(skkdic::OkuriNasiMark.find(line) != std::string::npos) break; - std::ifstream dic(fpath_.c_str()); - if(!dic) { - return; + // èȵGgÍ~Å\[g³êÄ¢é͸ + okuriAri_.push_front(SKKPair(index, line)); } - std::string str_line; - while(!dic.eof()) { - std::getline(dic, str_line); - if(str_line == ";; okuri-ari entries.") break; - } + while(1) { + dic >> index; + if(dic.eof()) break; + dic.ignore(1, ' '); + std::getline(dic, line); - // è èGg - while(!dic.eof()) { - std::getline(dic, str_line); - if(str_line.length() == 0) continue; - if(str_line == ";; okuri-nasi entries.") break; - if(str_line[0] == ';') continue; - - okuri_ari_unparsed.push_back(str_line); + // è èGg͸Å\[g³êÄ¢é͸ + okuriNasi_.push_back(SKKPair(index, line)); } - // èȵGg - while(!dic.eof()) { - std::getline(dic, str_line); - if(str_line.length() == 0) continue; - if(str_line[0] == ';') continue; - - okuri_nasi_unparsed.push_back(str_line); - } + // Ggð\[g·é + std::sort(okuriAri_.begin(), okuriAri_.end(), skkdic::EntryCompare()); + std::sort(okuriNasi_.begin(), okuriNasi_.end(), skkdic::EntryCompare()); - // SÄp[X·é - parseAll(); + std::cerr << "SKK Dictionary(" << path_ << ")" << std::endl + << " okuri-ari: " << countOkuriAri() << " entries." << std::endl + << " okuri-nasi: " << countOkuriNasi() << " entries." << std::endl << std::endl; } -int SKKUserDictionary::countOkuriAri() { - return okuri_ari_table.size(); -} +#pragma mark --- SKKUserDictionary --- -int SKKUserDictionary::countOkuriNasi() { - return okuri_nasi_table.size(); +SKKUserDictionary::SKKUserDictionary(const std::string& path) : path_(path) { + load(); } -std::vector<OkuriganaEntry> -SKKUserDictionary::findOkuriAri(const CppCFString& query) { - // ©Â©Á½H - if(okuri_ari_table.find(query) != okuri_ari_table.end()) { - return *okuri_ari_table[query]; - } +SKKUserDictionary::~SKKUserDictionary() { + // §IÉ«ðÛ¶·é + save(true); +} - // Gg©Ì¶ÝµÈ¢©Aܾp[X³êĢȢB - for(unsigned i = 0; i < okuri_ari_unparsed.size(); ++ i) { - CppCFString line(okuri_ari_unparsed[i].c_str(), - kCFStringEncodingEUC_JP); // EUC-JP +int SKKUserDictionary::countOkuriAri() { + return okuriAri_.size(); +} - if(line.startsWith(query)) { - CppCFString index; - std::vector<OkuriganaEntry> entries; +int SKKUserDictionary::countOkuriNasi() { + return okuriNasi_.size(); +} - parseOkuriAriEntry(line, index, entries); +std::vector<OkuriganaEntry> SKKUserDictionary::findOkuriAri(const CppCFString& query) { + EntryIterator i = std::find_if(okuriAri_.begin(), okuriAri_.end(), skkdic::UserEntryCompare(query)); - return entries; - } + // ©Â©çÈ¢H + if(i == okuriAri_.end()) { + return std::vector<OkuriganaEntry>(); } - // ¶ÝµÈ¯êÎóÌ vector ðÔ· - return std::vector<OkuriganaEntry>(); + return skkdic::ConvertOkuriAri(SKKEntry::ParseOkuriAri(i->first, i->second)); } -std::vector<CppCFString> -SKKUserDictionary::findOkuriNasi(const CppCFString& query) { - // ©Â©Á½H - if(okuri_nasi_table.find(query) != okuri_nasi_table.end()) { - return *okuri_nasi_table[query]; - } +std::vector<CppCFString> SKKUserDictionary::findOkuriNasi(const CppCFString& query) { + EntryIterator i = std::find_if(okuriNasi_.begin(), okuriNasi_.end(), skkdic::UserEntryCompare(query)); - // Gg©Ì¶ÝµÈ¢©Aܾp[X³êĢȢ - for(unsigned i = 0; i < okuri_nasi_unparsed.size() ; ++ i) { - CppCFString line(okuri_nasi_unparsed[i].c_str(), - kCFStringEncodingEUC_JP); // EUC-JP - - if(line.startsWith(query)) { - CppCFString index; - std::vector<CppCFString> entries; - - parseOkuriNasiEntry(line, index, entries); - - return entries; - } + // ©Â©çÈ¢H + if(i == okuriNasi_.end()) { + return std::vector<CppCFString>(); } - // ¶ÝµÈ¯êÎóÌ vector ðÔ· - return std::vector<CppCFString>(); + return skkdic::ConvertOkuriNasi(SKKEntry::ParseOkuriNasi(i->first, i->second)); } -std::vector<CppCFString> -SKKUserDictionary::findCompletions(const CppCFString& query) { +std::vector<CppCFString> SKKUserDictionary::findCompletions(const CppCFString& query) { + std::string index = query.toStdString(); std::vector<CppCFString> result; - const unsigned query_len = query.length(); - - // êÂà¶ÝµÈ¯êÎóÌvectorðÔ·B - for(std::map<CppCFString, std::vector<CppCFString>*>::const_iterator ite - = okuri_nasi_table.begin(); ite != okuri_nasi_table.end(); ite ++) { - if(ite->first.length() > query_len && ite->first.startsWith(query)) { - // â®Ìðð½·B - result.push_back(ite->first); + + for(EntryIterator i = okuriNasi_.begin(); i != okuriNasi_.end(); ++ i) { + // 檪ªêvµÄ¢é©H + if(i->first.find(index) == 0) { + result.push_back(CppCFString(i->first.c_str(), kCFStringEncodingEUC_JP)); } } return result; } -void SKKUserDictionary::parseAll() { - // @±Ì\bhÍAèLèGgQÆè³µGgQð - // ãë©çê¸Âp[XµÄ¢«AunparsedÌvector©çÍÁµÄsB - // O©çÅÈ¢RÍAOÌÚðÁµ½ÉãëÉ éÚð - // Oɸç³êĵܤ©àmêÈ¢×Å éB¸ç·ÉÍ]vÈÔª©©éB - // @ȨA±Ì\bhÍload()ª®¹·éOÉÄñÅÍÈçÈ¢B - - // èLèGg - for(std::vector<std::string>::iterator ite = okuri_ari_unparsed.end()-1; - okuri_ari_unparsed.size() > 0; ite --) { - CppCFString line(ite->c_str(), kCFStringEncodingEUC_JP); // EUC-JP - CppCFString index; - std::vector<OkuriganaEntry> entries; - - parseOkuriAriEntry(line, index, entries); - - std::vector<OkuriganaEntry>* candidates = okuri_ari_table[index]; - if(candidates == NULL) { - candidates = new std::vector<OkuriganaEntry>; - okuri_ari_table[index] = candidates; - } - candidates->insert(candidates->end(), entries.begin(), entries.end()); - okuri_ari_unparsed.erase(ite); - } - - // è³µGg - for(std::vector<std::string>::iterator ite = okuri_nasi_unparsed.end() - 1; - okuri_nasi_unparsed.size() > 0; ite --) { - CppCFString line(ite->c_str(),kCFStringEncodingEUC_JP); // EUC-JP - CppCFString index; - std::vector<CppCFString> entries; - - parseOkuriNasiEntry(line, index, entries); - - std::vector<CppCFString>* candidates = okuri_nasi_table[index]; - if(candidates == NULL) { - candidates = new std::vector<CppCFString>; - okuri_nasi_table[index] = candidates; - } - candidates->insert(candidates->end(), entries.begin(), entries.end()); - okuri_nasi_unparsed.erase(ite); - } - std::cerr << "SKK User Dictionary(" << fpath_ << ")" << std::endl - << " okuri-ari: " << countOkuriAri() << " entries." - << std::endl - << " okuri-nasi: " << countOkuriNasi() << " entries." - << std::endl << std::endl; -} - -void SKKUserDictionary::registerOkuriAri(const CppCFString& index, - const CppCFString& okuri, - const CppCFString& kanji) { - // è¼¼LèB - std::vector<OkuriganaEntry>* candidates; - if(okuri_ari_table.find(index) == okuri_ari_table.end()) { - candidates = new std::vector<OkuriganaEntry>; - okuri_ari_table[index] = candidates; - - // ó⪳©Á½êÍChJ[hÉ¿ðêÂüêÄI¹B - OkuriganaEntry entry; - entry.add(kanji); - candidates->push_back(entry); - } else { - candidates = okuri_ari_table[index]; +void SKKUserDictionary::registerOkuriAri(const CppCFString& index, const CppCFString& okuri, const CppCFString& kanji) { + SKKEntry entry = SKKEntry::CreateOkuriAri(index.toStdString()); + EntryIterator i = std::find_if(okuriAri_.begin(), okuriAri_.end(), skkdic::UserEntryCompare(index)); - // ChJ[hÌæªÉ»Ì¿ðÇÁ·éB - for(std::vector<OkuriganaEntry>::iterator ite = candidates->begin(); - ite != candidates->end(); ite ++) { - if(ite->isWild()) { - ite->insert(kanji,0); - ite->removeRedundantItems(); - break; - } - } - - // ¯¶è¼¼ðÂOkuriganaEntryª³¯êÎAGgðìÁÄ - // ¿ðêÂüêÄI¹BùÉ êλÌGgÌæªÉ¿ðÇ - // Áµ½ãA»êðvectorÌæªÉuB - - bool found = false; - for(std::vector<OkuriganaEntry>::iterator ite = candidates->begin(); - ite != candidates->end(); ite ++) { - if(ite->getKana() == okuri) { - found = true; - ite->insert(kanji,0); - ite->removeRedundantItems(); // d¡ðí - - //candidates.swap(candidates.begin(),ite); // æªÌÚÆüêÖ¦éB - OkuriganaEntry entry = *ite; - candidates->erase(ite); - candidates->insert(candidates->begin(),entry); - break; - } - } - - if(!found) { - OkuriganaEntry entry(okuri); - entry.add(kanji); - candidates->insert(candidates->begin(),entry); - } + // ©Â©Á½H + if(i != okuriAri_.end()) { + entry = SKKEntry::ParseOkuriAri(i->first, i->second); + okuriAri_.erase(std::remove(okuriAri_.begin(), okuriAri_.end(), *i), okuriAri_.end()); } - // Û¶ + entry.AddOkuriAri(SKKCandidate(kanji.toStdString()), okuri.toStdString()); + okuriAri_.push_front(SKKPair(entry.Key(), entry.Candidate())); + + // Û¶·é save(); } -void SKKUserDictionary::registerOkuriNasi(const CppCFString& index, - const CppCFString& kanji) { - std::vector<CppCFString>* candidates; - if(okuri_nasi_table.find(index) == okuri_nasi_table.end()) { - candidates = new std::vector<CppCFString>; - okuri_nasi_table[index] = candidates; - } else { - candidates = okuri_nasi_table[index]; - } +void SKKUserDictionary::registerOkuriNasi(const CppCFString& index, const CppCFString& kanji) { + SKKEntry entry = SKKEntry::CreateOkuriNasi(index.toStdString()); + EntryIterator i = std::find_if(okuriNasi_.begin(), okuriNasi_.end(), skkdic::UserEntryCompare(index)); - // ùɱ̿ªo^³êÄ¢êÎA»êðÁ·B - for(std::vector<CppCFString>::iterator ite = candidates->begin(); - ite != candidates->end(); ite ++) { - if(*ite == kanji) { - candidates->erase(ite); - break; - } + // ©Â©Á½H + if(i != okuriNasi_.end()) { + entry = SKKEntry::ParseOkuriNasi(i->first, i->second); + okuriNasi_.erase(std::remove(okuriNasi_.begin(), okuriNasi_.end(), *i), okuriNasi_.end()); } - // æªÉüêéB - candidates->insert(candidates->begin(),kanji); + entry.AddOkuriNasi(SKKCandidate(kanji.toStdString())); + okuriNasi_.push_front(SKKPair(entry.Key(), entry.Candidate())); - // Û¶ + // Û¶·é save(); } -void SKKUserDictionary::removeOkuriAri(const CppCFString& index, - const CppCFString& kanji) { - // è¼¼ è - if(okuri_ari_table.find(index) == okuri_ari_table.end()) { +void SKKUserDictionary::removeOkuriAri(const CppCFString& index, const CppCFString& kanji) { + EntryIterator i = std::find_if(okuriAri_.begin(), okuriAri_.end(), skkdic::UserEntryCompare(index)); + + // ©Â©çÈ¢H + if(i == okuriAri_.end()) { return; } - - std::vector<OkuriganaEntry>* candidates = okuri_ari_table[index]; - // SÄÌOkuriganaEntry©çA¿ªkanjiÅ éàÌðTµÄ»êðÁ·B - for(std::vector<OkuriganaEntry>::iterator entry = candidates->begin(); - entry != candidates->end(); entry ++) { - unsigned n_contents = entry->size(); - for(unsigned i = 0;i < n_contents;i++) { - if((*entry)[i] == kanji) { - entry->remove(i); - i--; - n_contents--; - } - } + SKKEntry entry = SKKEntry::ParseOkuriAri(i->first, i->second); + entry.RemoveOkuriAri(SKKCandidate(kanji.toStdString())); + + // ܾóâªcÁÄ¢éH + if(entry.Count() > 0) { + // ±ÌGgðXV·é + *i = SKKPair(entry.Key(), entry.Candidate()); + } else { + // ±ÌGgðÁµÄµÜ¤ + okuriAri_.erase(std::remove(okuriAri_.begin(), okuriAri_.end(), *i), okuriAri_.end()); } - // Û¶ + // Û¶·é save(); } -void SKKUserDictionary::removeOkuriNasi(const CppCFString& index, - const CppCFString& kanji) { - if(okuri_nasi_table.find(index) == okuri_nasi_table.end()) { +void SKKUserDictionary::removeOkuriNasi(const CppCFString& index, const CppCFString& kanji) { + EntryIterator i = std::find_if(okuriNasi_.begin(), okuriNasi_.end(), skkdic::UserEntryCompare(index)); + + // ©Â©çÈ¢H + if(i == okuriNasi_.end()) { return; } - std::vector<CppCFString>* candidates = okuri_nasi_table[index]; + SKKEntry entry = SKKEntry::ParseOkuriNasi(i->first, i->second); + entry.RemoveOkuriNasi(SKKCandidate(kanji.toStdString())); - unsigned size = candidates->size(); - for(unsigned i = 0;i < size;i++) { - if((*candidates)[i] == kanji) { - candidates->erase(candidates->begin()+i); - i--; - size--; - } + // ܾóâªcÁÄ¢éH + if(entry.Count() > 0) { + // ±ÌGgðXV·é + *i = SKKPair(entry.Key(), entry.Candidate()); + } else { + // ±ÌGgðÁµÄµÜ¤ + okuriNasi_.erase(std::remove(okuriNasi_.begin(), okuriNasi_.end(), *i), okuriNasi_.end()); } - // Û¶ + // Û¶·é save(); } +// ------------------------------------------------------------------ + +void SKKUserDictionary::load() { + std::string line; + std::string index; + std::string entry; + std::ifstream dic; + + if(!skkdic::OpenAndSeek(path_, dic)) { + return; + } + + while(1) { + dic >> index; + if(dic.eof()) break; + dic.ignore(1, ' '); + std::getline(dic, line); + if(skkdic::OkuriNasiMark.find(line) != std::string::npos) break; + okuriAri_.push_back(SKKPair(index, line)); + } + + while(1) { + dic >> index; + if(dic.eof()) break; + dic.ignore(1, ' '); + std::getline(dic, line); + okuriNasi_.push_back(SKKPair(index, line)); + } + + std::cerr << "SKK User Dictionary(" << path_ << ")" << std::endl + << " okuri-ari: " << countOkuriAri() << " entries." << std::endl + << " okuri-nasi: " << countOkuriNasi() << " entries." << std::endl << std::endl; +} + void SKKUserDictionary::save(bool force) { static int updateCount = 0; static std::time_t startOfUpdate = std::time(0); - // XVJE^[ðñ·(SKK_JISYO_SAVE_COUNT ÜÅ¢Æ 0 ÉZbg) - updateCount = (updateCount + 1) % SKK_JISYO_SAVE_COUNT; + // XVJE^[ðñ·(SAVE_LIMIT_COUNT ÜÅ¢Æ 0 Éßé) + updateCount = (updateCount + 1) % skkdic::SAVE_LIMIT_COUNT; // XVJn©çoßµ½ÔðZo - std::time_t elapsedTime = std::time(0) - startOfUpdate; + std::time_t elaspedTime = std::time(0) - startOfUpdate; - // Û¶·é^C~OÅÍÈ¢H - if(!force && updateCount != 0 && elapsedTime < SKK_JISYO_SAVE_TIMEOUT) { + // Û¶·é^C~OÅÍȯêÎA½àµÈ¢ + if(!force && updateCount != 0 && elaspedTime < skkdic::SAVE_TIMEOUT) { return; } @@ -589,134 +431,27 @@ updateCount = 0; startOfUpdate = std::time(0); - std::string dic_tmp_path = fpath_ + ".tmp"; - std::ofstream ofs(dic_tmp_path.c_str()); - if(!ofs) { - std::cerr << "SKKUserDictionary::save(): can't open [" - << dic_tmp_path << "]" << std::endl; + // êt@Cð쬷é + std::string tmpPath = path_ + ".tmp"; + std::ofstream dic(tmpPath.c_str()); + + if(!dic) { + std::cerr << __FUNCTION__ << ": [" << tmpPath << "] can't create." << std::endl; return; } - ofs << ";; okuri-ari entries." << std::endl; - if (okuri_ari_table.size() > 0) { - for(std::map<CppCFString, std::vector<OkuriganaEntry>*>::const_iterator entry = okuri_ari_table.begin(); - entry != okuri_ari_table.end(); entry ++) { - if(entry->second == NULL) continue; - if(entry->second->size() == 0) continue; - - CppCFString line; - line.append(entry->first).append(" /"); - - // ÅÍChJ[hðuB - for(std::vector<OkuriganaEntry>::const_iterator okuri = entry->second->begin(); - okuri != entry->second->end(); okuri ++) { - // ChJ[h© - if(okuri->isWild()) { - line.append(join('/',okuri->getCandidates())).append('/'); - break; - } - } - - // ÉChJ[hÈOðuB - for(std::vector<OkuriganaEntry>::const_iterator okuri = entry->second->begin(); - okuri != entry->second->end(); okuri ++) { - if(okuri->isWild()) continue; - - // ¨k /u/[/u/]/ - line.append('[').append(okuri->getKana()).append('/'); - line.append(join('/',okuri->getCandidates())).append("/]/"); - } - - // EUC-JPÉÏ·µÄ«ÞB - char* line_c = line.toCString(kCFStringEncodingEUC_JP); - ofs << line_c << std::endl; - delete[] line_c; - } - } + // è èGg + dic << skkdic::OkuriAriMark << std::endl; + std::for_each(okuriAri_.begin(), okuriAri_.end(), skkdic::Store(dic)); - ofs << ";; okuri-nasi entries." << std::endl; - if(okuri_nasi_table.size() > 0) { - for(std::map<CppCFString, std::vector<CppCFString>*>::const_iterator entry = okuri_nasi_table.begin(); - entry != okuri_nasi_table.end(); entry ++) { - if(entry->second == NULL) continue; - if(entry->second->size() == 0) continue; - - CppCFString line; - line.append(entry->first).append(" /"); - - // SÄÌÚðuB - line.append(join('/',*(entry->second))).append('/'); - - // EUC-JPÉÏ·µÄ«ÞB - char* line_c = line.toCString(kCFStringEncodingEUC_JP); - ofs << line_c << std::endl; - delete[] line_c; - } - } + // èȵGg + dic << skkdic::OkuriNasiMark << std::endl; + std::for_each(okuriNasi_.begin(), okuriNasi_.end(), skkdic::Store(dic)); // l[·é - if(rename(dic_tmp_path.c_str(), fpath_.c_str()) < 0) { - std::cerr << "SKKUserDictionary::save(): rename() failed[" - << std::strerror(errno) << "]" << std::endl; + if(rename(tmpPath.c_str(), path_.c_str()) < 0) { + std::cerr << __FUNCTION__ << ": rename() failed[" << std::strerror(errno) << "]" << std::endl; } else { std::cerr << "AquaSKK: saved user dictionary." << std::endl; } } - -// ------------------------------------------------------------------ - -// ñoÖQ -static void parseOkuriAriEntry(const CppCFString& line, CppCFString& index, - std::vector<OkuriganaEntry>& entries) { - // ¾s /o/[¹/o/]/[·/o/]/[µ/o/]/ - int pos_space = line.indexOf(' '); - if(pos_space == -1) return; // ÙíÈGg - - index = line.substring(0,pos_space); - CppCFString candidates_str(line.substring(pos_space + 1, line.length())); - - // [ÅnÜéGgð©éÜÅÍChJ[hB - OkuriganaEntry wildcard(CppCFString("")); - const int len = candidates_str.length(); - int pos = 1; - while(pos < len) { - // GgÌnÜè - if(candidates_str[pos] != '[') { - // ChJ[hÌóâ - int blockend = candidates_str.indexOf('/', pos); - wildcard.add(candidates_str.substring(pos,blockend)); - pos = blockend + 1; - } else { - int entry_end_pos = candidates_str.indexOf(']', pos); - OkuriganaEntry entry(CppCFString("")); - // []ÌÅÌکǤ©BÅÌÚª©oµÆÈéB - bool this_is_the_first_element = true; - pos ++; // [Ì©çB - while(pos < entry_end_pos) { - int blockend = candidates_str.indexOf('/',pos); - if(this_is_the_first_element) { - entry.setKana(candidates_str.substring(pos,blockend)); - this_is_the_first_element = false; - } else { - entry.add(candidates_str.substring(pos,blockend)); - } - pos = blockend + 1; - } - entries.push_back(entry); - pos = entry_end_pos+2; - } - } - entries.push_back(wildcard); -} - -static void parseOkuriNasiEntry(const CppCFString& line, CppCFString& index, - std::vector<CppCFString>& entries) { - // ©ª /»w/Èw/ - int pos_space = line.indexOf(' '); - if (pos_space == -1) return; // ÙíÈGg - - index = line.substring(0,pos_space); - CppCFString candidates_str = line.substring(pos_space+1); - - entries = candidates_str.split('/'); -} Index: AquaSKK/SKKDictionary.h diff -u AquaSKK/SKKDictionary.h:1.5 AquaSKK/SKKDictionary.h:1.5.2.1 --- AquaSKK/SKKDictionary.h:1.5 Tue Nov 15 00:37:13 2005 +++ AquaSKK/SKKDictionary.h Sun Jan 8 16:15:30 2006 @@ -1,11 +1,10 @@ /* - $Id: SKKDictionary.h,v 1.5 2005/11/14 15:37:13 t-suwa Exp $ - --------- - + $Id: SKKDictionary.h,v 1.5.2.1 2006/01/08 07:15:30 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 @@ -27,32 +26,35 @@ #include <iostream> #include <string> #include <vector> -#include <map> +#include <deque> #include "Dictionary.h" class OkuriganaEntry; class CppCFString; +// u©oµêvÆuÏ·óâvÌyA(Ï·óâͪð·éOÌóÔ) +typedef std::pair<std::string, std::string> SKKPair; + +// GgÌRei +typedef std::deque<SKKPair> EntryContainer; +typedef EntryContainer::iterator EntryIterator; + // SKK ¤L« class SKKDictionary: public Dictionary { - std::string fpath_; - std::map<CppCFString, std::vector<OkuriganaEntry>*> okuri_ari_table; - std::map<CppCFString, std::vector<CppCFString>*> okuri_nasi_table; - std::vector<std::string> okuri_ari_unparsed; - std::vector<std::string> okuri_nasi_unparsed; + std::string path_; + EntryContainer okuriAri_; + EntryContainer okuriNasi_; void load(); - void close(); - void parseAll(); - static void* parserThreadRoutine(void* dic); public: - SKKDictionary(const std::string& fpath); + SKKDictionary(const std::string& path); virtual ~SKKDictionary(); - + virtual int countOkuriAri(); virtual int countOkuriNasi(); - virtual std::vector<OkuriganaEntry> findOkuriAri(const CppCFString& root); + + virtual std::vector<OkuriganaEntry> findOkuriAri(const CppCFString& query); virtual std::vector<CppCFString> findOkuriNasi(const CppCFString& query); void changeDictionaryFile(const std::string& fpath); @@ -60,34 +62,28 @@ // SKK [U[« class SKKUserDictionary: public UserDictionary { - std::string fpath_; - std::map<CppCFString, std::vector<OkuriganaEntry>*> okuri_ari_table; - std::map<CppCFString, std::vector<CppCFString>*> okuri_nasi_table; - std::vector<std::string> okuri_ari_unparsed; - std::vector<std::string> okuri_nasi_unparsed; + std::string path_; + EntryContainer okuriAri_; + EntryContainer okuriNasi_; void load(); void save(bool force = false); - void parseAll(); public: - SKKUserDictionary(const std::string& fpath); + SKKUserDictionary(const std::string& path); virtual ~SKKUserDictionary(); virtual int countOkuriAri(); virtual int countOkuriNasi(); + virtual std::vector<OkuriganaEntry> findOkuriAri(const CppCFString& query); virtual std::vector<CppCFString> findOkuriNasi(const CppCFString& query); + virtual std::vector<CppCFString> findCompletions(const CppCFString& query); - virtual void registerOkuriAri(const CppCFString& index, - const CppCFString& okuri, - const CppCFString& kanji); - virtual void registerOkuriNasi(const CppCFString& index, - const CppCFString& kanji); - - virtual void removeOkuriAri(const CppCFString& index, - const CppCFString& kanji); - virtual void removeOkuriNasi(const CppCFString& index, - const CppCFString& kanji); + virtual void registerOkuriAri(const CppCFString& index, const CppCFString& okuri, const CppCFString& kanji); + virtual void registerOkuriNasi(const CppCFString& index, const CppCFString& kanji); + + virtual void removeOkuriAri(const CppCFString& index, const CppCFString& kanji); + virtual void removeOkuriNasi(const CppCFString& index, const CppCFString& kanji); };