Tomotaka SUWA
t-suw****@users*****
2006年 2月 15日 (水) 00:12:44 JST
Index: AquaSKK/DMDictionary.cpp diff -u AquaSKK/DMDictionary.cpp:1.4 AquaSKK/DMDictionary.cpp:1.4.2.1 --- AquaSKK/DMDictionary.cpp:1.4 Tue Nov 15 00:37:13 2005 +++ AquaSKK/DMDictionary.cpp Wed Feb 15 00:12:44 2006 @@ -1,10 +1,10 @@ /* - $Id: DMDictionary.cpp,v 1.4 2005/11/14 15:37:13 t-suwa Exp $ + $Id: DMDictionary.cpp,v 1.4.2.1 2006/02/14 15:12:44 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 @@ -35,9 +35,8 @@ static OSErr FilePathToFSSpec(CFStringRef filePath, FSSpec* apSpec); -DMDictionary::KotoeriDictionary::KotoeriDictionary(const CFStringRef path) - : path_(0), isRegistered_(false), id_(0) { - path_ = CFStringCreateCopy(kCFAllocatorDefault, path); +KotoeriDictionary::KotoeriDictionary(const std::string path) : path_(0), isRegistered_(false), id_(0) { + path_ = CFStringCreateWithCString(kCFAllocatorDefault, path.c_str(), kCFStringEncodingEUC_JP); if(!path_) { std::cerr << "KotoeriDictionary: CFStringCreateCopy() failed" << std::endl; return; @@ -56,9 +55,16 @@ } isRegistered_ = true; } + + char buf[1024]; + CFStringGetCString(path_, buf, sizeof(buf), kCFStringEncodingUTF8); + std::cerr << "Kotoeri Dictionary(" << buf << ")" << std::endl + << " okuri-ari: 0 entries." << std::endl + << " okuri-nasi: " << countOkuriNasi() << " entries." + << std::endl << std::endl; } -DMDictionary::KotoeriDictionary::~KotoeriDictionary() { +KotoeriDictionary::~KotoeriDictionary() { if(isRegistered_) { DCMUnregisterDictionary(id_); } @@ -68,38 +74,11 @@ } } -bool DMDictionary::KotoeriDictionary::Find(const CFStringRef key, - DCMFoundRecordIterator* iterator) { - DCMDictionaryRef ref; - if(DCMOpenDictionary(id_, 0, NULL, &ref) != noErr) { - std::cerr << "DCMOpenDictionary() failed" << std::endl; - return false; - } - - // R[hðõ - OSStatus status; - DCMFieldTag dataFieldTagList[] = { kDCMJapaneseHyokiTag }; - ByteCount length = CFStringGetLength(key) * sizeof(UniChar); - status = DCMFindRecords(ref, // Dictionary reference - kDCMJapaneseYomiTag, // key field tag - length, // key data length - CFStringGetCharactersPtr(key), // key data - kDCMFindMethodExactMatch, // find method - 1, // number of data field - dataFieldTagList, // data field tag list - 0, 0, // search all records - iterator); // found result - - DCMCloseDictionary(ref); - - return (status == noErr); -} - -const bool DMDictionary::KotoeriDictionary::IsGood() const { - return (id_ != 0); +int KotoeriDictionary::countOkuriAri() { + return 0; } -const int DMDictionary::KotoeriDictionary::Count() const { +int KotoeriDictionary::countOkuriNasi() { ItemCount numItems; if(DCMCountRecord(id_, &numItems) == noErr) { return numItems; @@ -108,145 +87,96 @@ return 0; } -const void DMDictionary::KotoeriDictionary::Description() const { - char buf[1024]; - CFStringGetCString(path_, buf, sizeof(buf), kCFStringEncodingUTF8); - std::cerr << "Kotoeri Dictionary(" << buf << ")" << std::endl - << " okuri-ari: 0 entries." << std::endl - << " okuri-nasi: " << Count() << " entries." - << std::endl << std::endl; -} - -// ------------------------------------------------------------------ - -DMDictionary::DMDictionary(const std::vector<CppCFString>& kotoeri_dic_file) { - load(kotoeri_dic_file); -} - -DMDictionary::~DMDictionary() { - unload(); -} - -int DMDictionary::countOkuriAri() { - return 0; -} - -int DMDictionary::countOkuriNasi() { - int result = 0; - - for(KotoeriDictionaryIterator i = dics_.begin(); i != dics_.end(); ++ i) { - result += (*i)->Count(); - } - - return result; -} - -std::vector<OkuriganaEntry> DMDictionary::findOkuriAri(const CppCFString& str) { +std::vector<OkuriganaEntry> KotoeriDictionary::findOkuriAri(const CppCFString& str) { // ±Æ¦è«ÉÍuè èvͶݵȢ return std::vector<OkuriganaEntry>(); } -std::vector<CppCFString> DMDictionary::findOkuriNasi(const CppCFString& str) { +std::vector<CppCFString> KotoeriDictionary::findOkuriNasi(const CppCFString& str) { OSStatus status; std::vector<CppCFString> result; - for(KotoeriDictionaryIterator i = dics_.begin(); i != dics_.end(); ++ i) { - DCMFoundRecordIterator iterator; - if(!(*i)->Find(str.getString(), &iterator)) continue; - - while(true) { - ByteCount keySize; - char foundKeyStr[kMaxKanjiLengthInAppleJapaneseDictionary]; - DCMUniqueID uniqueID; - AERecord dataList; - - // Get one record from result list - status = DCMIterateFoundRecord(iterator, // found result - kMaxKanjiLengthInAppleJapaneseDictionary, // key buffer size - &keySize, // actual found key size - foundKeyStr, // found key data - &uniqueID, // j[NID - &dataList); // AERecordf[^ - - if(status != noErr) break; - - DescType actualType; - char dataBuffer[kMaxKanjiLengthInAppleJapaneseDictionary]; - Size actualSize; - - // Get one data from AERecord - status = AEGetKeyPtr(&dataList, - kDCMJapaneseHyokiTag, - 'utxt', - &actualType, - dataBuffer, - kMaxKanjiLengthInAppleJapaneseDictionary, - &actualSize); - - // Dispose data AERecord - AEDisposeDesc(&dataList); - - if(status != noErr) break; - - // ÊÉÇÁ·é - result.push_back(CppCFData(dataBuffer, actualSize).getData()); - } - DCMDisposeRecordIterator(iterator); + DCMFoundRecordIterator iterator; + if(!find(str.getString(), &iterator)) { + return result; + } + + while(true) { + ByteCount keySize; + char foundKeyStr[kMaxKanjiLengthInAppleJapaneseDictionary]; + DCMUniqueID uniqueID; + AERecord dataList; + + // Get one record from result list + status = DCMIterateFoundRecord(iterator, // found result + kMaxKanjiLengthInAppleJapaneseDictionary, // key buffer size + &keySize, // actual found key size + foundKeyStr, // found key data + &uniqueID, // j[NID + &dataList); // AERecordf[^ + + if(status != noErr) break; + + DescType actualType; + char dataBuffer[kMaxKanjiLengthInAppleJapaneseDictionary]; + Size actualSize; + + // Get one data from AERecord + status = AEGetKeyPtr(&dataList, + kDCMJapaneseHyokiTag, + 'utxt', + &actualType, + dataBuffer, + kMaxKanjiLengthInAppleJapaneseDictionary, + &actualSize); + + // Dispose data AERecord + AEDisposeDesc(&dataList); + + if(status != noErr) break; + + // ÊÉÇÁ·é + result.push_back(CppCFData(dataBuffer, actualSize).getData()); } + DCMDisposeRecordIterator(iterator); return result; } -void DMDictionary::changeDictionaryFile(const std::vector<CppCFString>& dics) { - unload(); - load(dics); -} - -bool DMDictionary::checkDictionary(const CFStringRef path) { - return KotoeriDictionary(path).IsGood(); -} - -// ------------------------------------------------------------------ - -void DMDictionary::load(const std::vector<CppCFString>& dics) { - for(std::vector<CppCFString>::const_iterator ite = dics.begin(); - ite != dics.end(); ++ ite) { - KotoeriDictionary* dic = new KotoeriDictionary(ite->getString()); - if(dic->IsGood()) { - dics_.push_back(dic); - dic->Description(); - } else { - delete dic; - } +bool KotoeriDictionary::find(const CFStringRef key, DCMFoundRecordIterator* iterator) { + DCMDictionaryRef ref; + if(DCMOpenDictionary(id_, 0, NULL, &ref) != noErr) { + std::cerr << "DCMOpenDictionary() failed" << std::endl; + return false; } -} -void DMDictionary::unload() { - struct local { - static void DeleteObject(const KotoeriDictionary* ptr) { - delete ptr; - } - }; - std::for_each(dics_.begin(), dics_.end(), local::DeleteObject); - dics_.clear(); + // R[hðõ + OSStatus status; + DCMFieldTag dataFieldTagList[] = { kDCMJapaneseHyokiTag }; + ByteCount length = CFStringGetLength(key) * sizeof(UniChar); + status = DCMFindRecords(ref, // Dictionary reference + kDCMJapaneseYomiTag, // key field tag + length, // key data length + CFStringGetCharactersPtr(key), // key data + kDCMFindMethodExactMatch, // find method + 1, // number of data field + dataFieldTagList, // data field tag list + 0, 0, // search all records + iterator); // found result + + DCMCloseDictionary(ref); + + return (status == noErr); } static OSErr FilePathToFSSpec(CFStringRef filePath, FSSpec* apSpec) { FSRef fileRef; OSErr err = !noErr; - CFURLRef cfUrl = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, - filePath, - kCFURLPOSIXPathStyle, - false); - if(CFURLGetFSRef(cfUrl, &fileRef)) { - err = FSGetCatalogInfo(&fileRef, - kFSCatInfoNone, - NULL, - NULL, - apSpec, - NULL); + CFURLRef url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, filePath, kCFURLPOSIXPathStyle, false); + if(CFURLGetFSRef(url, &fileRef)) { + err = FSGetCatalogInfo(&fileRef, kFSCatInfoNone, NULL, NULL, apSpec, NULL); } - CFRelease(cfUrl); + if(url) CFRelease(url); return err; } Index: AquaSKK/DMDictionary.h diff -u AquaSKK/DMDictionary.h:1.4 AquaSKK/DMDictionary.h:1.4.2.1 --- AquaSKK/DMDictionary.h:1.4 Tue Nov 15 00:37:13 2005 +++ AquaSKK/DMDictionary.h Wed Feb 15 00:12:44 2006 @@ -1,10 +1,10 @@ /* - $Id: DMDictionary.h,v 1.4 2005/11/14 15:37:13 t-suwa Exp $ + $Id: DMDictionary.h,v 1.4.2.1 2006/02/14 15:12:44 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 @@ -32,37 +32,19 @@ class OkuriganaEntry; class CppCFString; -class DMDictionary: public Dictionary { - class KotoeriDictionary { - CFStringRef path_; - bool isRegistered_; - DCMDictionaryID id_; - - public: - KotoeriDictionary(const CFStringRef path); - ~KotoeriDictionary(); - - bool Find(const CFStringRef key, DCMFoundRecordIterator* iterator); - const bool IsGood() const; - const int Count() const; - const void Description() const; - }; - typedef std::vector<KotoeriDictionary*> KotoeriDictionaryContainer; - typedef KotoeriDictionaryContainer::iterator KotoeriDictionaryIterator; - KotoeriDictionaryContainer dics_; +class KotoeriDictionary: public Dictionary { + CFStringRef path_; + bool isRegistered_; + DCMDictionaryID id_; - void load(const std::vector<CppCFString>& dicFiles); - void unload(); + bool find(const CFStringRef key, DCMFoundRecordIterator* iterator); public: - DMDictionary(const std::vector<CppCFString>& kotoeri_dic_file); - virtual ~DMDictionary(); + KotoeriDictionary(const std::string path); + virtual ~KotoeriDictionary(); virtual int countOkuriAri(); virtual int countOkuriNasi(); - virtual std::vector<OkuriganaEntry> findOkuriAri(const CppCFString& root); - virtual std::vector<CppCFString> findOkuriNasi(const CppCFString& query); - - void changeDictionaryFile(const std::vector<CppCFString>& kotoeri_dic_file); - bool checkDictionary(const CFStringRef fpath); + virtual std::vector<OkuriganaEntry> findOkuriAri(const CppCFString& str); + virtual std::vector<CppCFString> findOkuriNasi(const CppCFString& str); }; Index: AquaSKK/DictArrayController.h diff -u /dev/null AquaSKK/DictArrayController.h:1.1.2.1 --- /dev/null Wed Feb 15 00:12:44 2006 +++ AquaSKK/DictArrayController.h Wed Feb 15 00:12:44 2006 @@ -0,0 +1,42 @@ +/* -*- objc -*- + $Id: DictArrayController.h,v 1.1.2.1 2006/02/14 15:12:44 t-suwa Exp $ + + MacOS X implementation of the SKK input method. + + Copyright (C) 2006 Tomotaka SUWA <t.suw****@mac*****> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#import <Cocoa/Cocoa.h> + + @ interface DictArrayController : NSArrayController +{ + IBOutlet NSWindow* prefView; + IBOutlet NSTableView* tableView; +} + +- (IBAction)browseLocation:(id)sender; +- (BOOL)tableView:(NSTableView *)tableView writeRows:(NSArray*)rows toPasteboard:(NSPasteboard*)pboard; +- (NSDragOperation)tableView:(NSTableView*)tableView + validateDrop:(id <NSDraggingInfo>)info + proposedRow:(int)row + proposedDropOperation:(NSTableViewDropOperation)op; +- (BOOL)tableView:(NSTableView*)tableView + acceptDrop:(id <NSDraggingInfo>)info + row:(int)row + dropOperation:(NSTableViewDropOperation)op; + + @ end Index: AquaSKK/DictArrayController.m diff -u /dev/null AquaSKK/DictArrayController.m:1.1.2.1 --- /dev/null Wed Feb 15 00:12:44 2006 +++ AquaSKK/DictArrayController.m Wed Feb 15 00:12:44 2006 @@ -0,0 +1,170 @@ +/* -*- objc -*- + $Id: DictArrayController.m,v 1.1.2.1 2006/02/14 15:12:44 t-suwa Exp $ + + MacOS X implementation of the SKK input method. + + Copyright (C) 2006 Tomotaka SUWA <t.suw****@mac*****> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#import "DictArrayController.h" + +// ドラッグ & ドロップ用 +static NSString* DictionaryRowsType = @"DictionaryRowsType"; + +// 辞書テーブル用 +static NSString* DictActiveKey = @"active"; +static NSString* DictTypeKey = @"type"; +static NSString* DictLocationKey = @"location"; + + @ implementation DictArrayController + +- (void)moveObjectsInArrangedObjectsFromIndexes:(NSIndexSet*)indexSet toIndex:(unsigned int)insertIndex { + NSArray* objects = [self arrangedObjects]; + unsigned int idx = [indexSet lastIndex]; + int aboveInsertIndexCount = 0; + int removeIndex; + + while(NSNotFound != idx) { + if(idx >= insertIndex) { + removeIndex = idx + aboveInsertIndexCount; + aboveInsertIndexCount += 1; + } else { + removeIndex = idx; + insertIndex -= 1; + } + + id object = [[objects objectAtIndex:removeIndex] retain]; + [self removeObjectAtArrangedObjectIndex:removeIndex]; + [self insertObject:object atArrangedObjectIndex:insertIndex]; + [object release]; + + idx = [indexSet indexLessThanIndex:idx]; + } +} + +- (NSIndexSet *)indexSetFromRows:(NSArray*)rows { + NSMutableIndexSet* indexSet = [NSMutableIndexSet indexSet]; + NSEnumerator* rowEnumerator = [rows objectEnumerator]; + NSNumber* idx; + + while((idx = [rowEnumerator nextObject])) { + [indexSet addIndex:[idx intValue]]; + } + + return indexSet; +} + +- (int)rowsAboveRow:(int)row inIndexSet:(NSIndexSet*)indexSet { + int currentIndex = [indexSet firstIndex]; + int i = 0; + + while(currentIndex != NSNotFound) { + if(currentIndex < row) { + ++ i; + } + currentIndex = [indexSet indexGreaterThanIndex:currentIndex]; + } + + return i; +} + +- (void)awakeFromNib { + [tableView registerForDraggedTypes:[NSArray arrayWithObjects:DictionaryRowsType, nil]]; + [super awakeFromNib]; +} + +- (id)newObject { + id obj = [super newObject]; + + // 新規のエントリを初期化する + if(obj) { + [obj setValue:[NSNumber numberWithBool:YES] forKey:DictActiveKey]; + [obj setValue:[NSNumber numberWithInt:10] forKey:DictTypeKey]; + [obj setValue:@"" forKey:DictLocationKey]; + } + + return obj; +} + +- (IBAction)browseLocation:(id)sender { + NSOpenPanel* panel = [NSOpenPanel openPanel]; + + [panel beginSheetForDirectory:nil file:nil types:nil modalForWindow:prefView modalDelegate:self + didEndSelector:@selector(browsePanelDidEnd:returnCode:contextInfo:) contextInfo:nil]; +} + +- (void)browsePanelDidEnd:(NSOpenPanel*)openPanel returnCode:(int)returnCode contextInfo:(void*)contextInfo { + if(returnCode != NSOKButton) { + return; + } + + [[self selection] setValue:[openPanel filename] forKey:DictLocationKey]; +} + +- (BOOL)tableView:(NSTableView *)tableView writeRows:(NSArray*)rows toPasteboard:(NSPasteboard*)pboard { + NSArray* typesArray = [NSArray arrayWithObjects:DictionaryRowsType, nil]; + + [pboard declareTypes:typesArray owner:self]; + [pboard setPropertyList:rows forType:DictionaryRowsType]; + + return YES; +} + +- (NSDragOperation)tableView:(NSTableView*)tv + validateDrop:(id <NSDraggingInfo>)info + proposedRow:(int)row + proposedDropOperation:(NSTableViewDropOperation)op { + NSDragOperation dragOp = NSDragOperationCopy; + + // ドラッグ元が同じなら、移動 + if([info draggingSource] == tableView) { + dragOp = NSDragOperationMove; + } + + [tv setDropRow:row dropOperation:NSTableViewDropAbove]; + + return dragOp; +} + +- (BOOL)tableView:(NSTableView*)tv + acceptDrop:(id <NSDraggingInfo>)info + row:(int)row + dropOperation:(NSTableViewDropOperation)op { + if(row < 0) { + row = 0; + } + + // ドラッグ元以外なら、何もしない + if([info draggingSource] != tableView) { + return NO; + } + + NSArray* rows = [[info draggingPasteboard] propertyListForType:DictionaryRowsType]; + NSIndexSet* indexSet = [self indexSetFromRows:rows]; + + [self moveObjectsInArrangedObjectsFromIndexes:indexSet toIndex:row]; + + int rowsAbove = [self rowsAboveRow:row inIndexSet:indexSet]; + + NSRange range = NSMakeRange(row - rowsAbove, [indexSet count]); + indexSet = [NSIndexSet indexSetWithIndexesInRange:range]; + [self setSelectionIndexes:indexSet]; + + return YES; +} + + @ end Index: AquaSKK/Dictionary.h diff -u AquaSKK/Dictionary.h:1.3.2.1 AquaSKK/Dictionary.h:1.3.2.2 --- AquaSKK/Dictionary.h:1.3.2.1 Sun Jan 8 16:15:30 2006 +++ AquaSKK/Dictionary.h Wed Feb 15 00:12:44 2006 @@ -1,5 +1,5 @@ /* - $Id: Dictionary.h,v 1.3.2.1 2006/01/08 07:15:30 t-suwa Exp $ + $Id: Dictionary.h,v 1.3.2.2 2006/02/14 15:12:44 t-suwa Exp $ MacOS X implementation of the SKK input method. @@ -40,10 +40,8 @@ virtual int countOkuriNasi() = 0; // õ - virtual std::vector<OkuriganaEntry> - findOkuriAri(const CppCFString& query) = 0; - virtual std::vector<CppCFString> - findOkuriNasi(const CppCFString& query) = 0; + virtual std::vector<OkuriganaEntry> findOkuriAri(const CppCFString& query) = 0; + virtual std::vector<CppCFString> findOkuriNasi(const CppCFString& query) = 0; }; // Û[U[«NX @@ -52,21 +50,15 @@ virtual ~UserDictionary() {}; // ©oµêÌâ® - virtual std::vector<CppCFString> - findCompletions(const CppCFString& query) = 0; + virtual std::vector<CppCFString> findCompletions(const CppCFString& query) = 0; // Pêo^ - virtual void registerOkuriAri(const CppCFString& index, - const CppCFString& okuri, - const CppCFString& kanji) = 0; - virtual void registerOkuriNasi(const CppCFString& index, - const CppCFString& kanji) = 0; + virtual void registerOkuriAri(const CppCFString& index, const CppCFString& okuri, const CppCFString& kanji) = 0; + virtual void registerOkuriNasi(const CppCFString& index, const CppCFString& kanji) = 0; // Pêí - virtual void removeOkuriAri(const CppCFString& index, - const CppCFString& kanji) = 0; - virtual void removeOkuriNasi(const CppCFString& index, - const CppCFString& kanji) = 0; + virtual void removeOkuriAri(const CppCFString& index, const CppCFString& kanji) = 0; + virtual void removeOkuriNasi(const CppCFString& index, const CppCFString& kanji) = 0; }; // IuWFNgðA·ét@N^ Index: AquaSKK/Foundation.mm diff -u AquaSKK/Foundation.mm:1.3.2.1 AquaSKK/Foundation.mm:1.3.2.2 --- AquaSKK/Foundation.mm:1.3.2.1 Sat Jan 14 20:01:58 2006 +++ AquaSKK/Foundation.mm Wed Feb 15 00:12:44 2006 @@ -1,5 +1,5 @@ /* -*- objc -*- - $Id: Foundation.mm,v 1.3.2.1 2006/01/14 11:01:58 t-suwa Exp $ + $Id: Foundation.mm,v 1.3.2.2 2006/02/14 15:12:44 t-suwa Exp $ MacOS X implementation of the SKK input method. @@ -21,37 +21,22 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#import <AppKit/AppKit.h> -#import "Foundation.h" -#import "PreferencesController.h" - -#include <Carbon/Carbon.h> -#include <vector> +#include <AppKit/AppKit.h> +#include "Foundation.h" +#include "PreferencesController.h" +#include "SKKServer.h" #include "BIMClientServer.h" -#include "CppCFString.h" -#include "CppCFData.h" -#include "PrivateRunLoop.h" -#include "CppMessagePortServer.h" #include "ServerMessageReceiver.h" -#include "SKKServer.h" -#include "net/Socket.h" #include "Skkserv.h" @implementation Foundation - (void)applicationDidFinishLaunching:(NSNotification*)aNotification { - // ±Æ¦è«ÌpXðæ¾ + // vt@Xðæ¾ PreferencesController* pref = [PreferencesController sharedController]; - std::vector<CppCFString> vec; - for(unsigned i = 0 ; i < [[pref path] count] ; ++ i) { - vec.push_back((CFStringRef)[[pref path] objectAtIndex:i]); - } // «T[o[ðN®·é - SKKServer::sharedServer([[pref getPathToMainDic] cString], - [[pref getPathToSubDic] cString], - [[pref getPathToUserDic] cString], - vec); + SKKServer::sharedServer(); // bZ[WnhðN®·é ServerMessageReceiver::start(kAquaSKKServerRunLoopMode); Index: AquaSKK/PreferencesController.h diff -u AquaSKK/PreferencesController.h:1.6.2.2 AquaSKK/PreferencesController.h:1.6.2.3 --- AquaSKK/PreferencesController.h:1.6.2.2 Sun Jan 8 16:15:30 2006 +++ AquaSKK/PreferencesController.h Wed Feb 15 00:12:44 2006 @@ -1,5 +1,5 @@ /* -*- objc -*- - $Id: PreferencesController.h,v 1.6.2.2 2006/01/08 07:15:30 t-suwa Exp $ + $Id: PreferencesController.h,v 1.6.2.3 2006/02/14 15:12:44 t-suwa Exp $ MacOS X implementation of the SKK input method. @@ -39,32 +39,16 @@ IBOutlet id winColor; IBOutlet id winTransparent; - // SKK « - IBOutlet NSTextField *maindic_path; - IBOutlet NSTextField *subdic_path; - - // ±Æ¦è« - IBOutlet id addKotoeriBtn; - IBOutlet id kotoeriDicTable; - IBOutlet id removeKotoeriBtn; - // skkserv IBOutlet NSButton *skkserv_enabled; IBOutlet NSTextField *skkserv_port; IBOutlet NSButton *skkserv_local_only; - NSString* path_to_main_dic; - NSString* path_to_sub_dic; - NSMutableArray *dicPath; - NSFont *font; NSFontPanel* fontPanel; NSMenu* kbdLayoutMenu; } + (PreferencesController*)sharedController; -- (NSString*)getPathToMainDic; -- (NSString*)getPathToSubDic; -- (NSString*)getPathToUserDic; - init; @@ -84,15 +68,7 @@ - (BOOL)isAsciiModeStartup; - (IBAction)asciiModeStartup:(id)sender; -- (NSArray *)path; - -- (IBAction)selectMainDic:(id)sender; -- (IBAction)selectSubDic:(id)sender; - -- (IBAction)addKotoeriDic:(id)sender; -- (IBAction)removeKotoeriDic:(id)sender; - (IBAction)saveUserDefault:(id)sender; -- (void)controlSetting; - (BOOL)isSkkservEnabled; - (int)skkservPort; Index: AquaSKK/PreferencesController.mm diff -u AquaSKK/PreferencesController.mm:1.6.2.4 AquaSKK/PreferencesController.mm:1.6.2.5 --- AquaSKK/PreferencesController.mm:1.6.2.4 Sat Jan 14 20:01:58 2006 +++ AquaSKK/PreferencesController.mm Wed Feb 15 00:12:44 2006 @@ -1,5 +1,5 @@ /* -*- objc -*- - $Id: PreferencesController.mm,v 1.6.2.4 2006/01/14 11:01:58 t-suwa Exp $ + $Id: PreferencesController.mm,v 1.6.2.5 2006/02/14 15:12:44 t-suwa Exp $ MacOS X implementation of the SKK input method. @@ -47,11 +47,6 @@ static NSString* WindowAlphaKey = @"dic.WindowAlpha.kotoeri"; static NSString* ShowCandsLimitKey = @"dic.showCandsWindowAfterNthCand"; -static NSString* MainDictPathKey = @"dic.path.main"; -static NSString* SubDictPathKey = @"dic.path.sub"; - -static NSString* KotoeriDictPathKey = @"dic.path.kotoeri"; - static NSString* SKKServEnabledKey = @"pref.skkserv.enabled"; static NSString* SKKServPortKey = @"pref.skkserv.port"; static NSString* SKKServLocalOnlyKey = @"pref.skkserv.local-only"; @@ -167,9 +162,6 @@ [templateDefaults setObject:[NSArchiver archivedDataWithRootObject:color] forKey:WindowColorKey]; [templateDefaults setObject:@"1.0" forKey:WindowAlphaKey]; [templateDefaults setObject:@"5" forKey:ShowCandsLimitKey]; - [templateDefaults setObject:@"~/Library/AquaSKK/SKK-JISYO.L" forKey:MainDictPathKey]; - [templateDefaults setObject:@"~/.skk-jisyo" forKey:SubDictPathKey]; - [templateDefaults setObject:[NSMutableArray array] forKey:KotoeriDictPathKey]; [templateDefaults setObject:@"NO" forKey:SKKServEnabledKey]; [templateDefaults setObject:@"1178" forKey:SKKServPortKey]; [templateDefaults setObject:@"YES" forKey:SKKServLocalOnlyKey]; @@ -195,12 +187,7 @@ [winColor setColor:[NSUnarchiver unarchiveObjectWithData:[defaults objectForKey:WindowColorKey]]]; [winTransparent setDoubleValue:[defaults floatForKey:WindowAlphaKey]]; - // SKK « - path_to_main_dic = [[NSString alloc] initWithString:[defaults stringForKey:MainDictPathKey]]; - path_to_sub_dic = [[NSString alloc] initWithString:[defaults stringForKey:SubDictPathKey]]; - - // ±Æ¦è« - dicPath = [[NSMutableArray alloc] initWithArray:[defaults arrayForKey:KotoeriDictPathKey]]; + // « // skkserv [skkserv_enabled setState:[defaults boolForKey:SKKServEnabledKey]]; @@ -225,10 +212,7 @@ [defaults setObject:[NSArchiver archivedDataWithRootObject:[winColor color]] forKey:WindowColorKey]; [defaults setFloat:[winTransparent doubleValue] forKey:WindowAlphaKey]; - // SKK « - - // ±Æ¦è« - [defaults setObject:dicPath forKey:KotoeriDictPathKey]; + // « // skkserv [defaults setBool:[skkserv_enabled state] forKey:SKKServEnabledKey]; @@ -302,24 +286,7 @@ [self setState:kBasicMessageIsAsciiModeStartup state:[sender state]]; } -// SKK« - -- (NSString*)getPathToMainDic { - return [path_to_main_dic stringByExpandingTildeInPath]; -} - -- (NSString*)getPathToSubDic { - return [path_to_sub_dic stringByExpandingTildeInPath]; -} - -- (NSString*)getPathToUserDic { - return [@"~/Library/AquaSKK/skk-user-dic" stringByExpandingTildeInPath]; -} - - (IBAction)showWindow:(id)sender { - [maindic_path setStringValue:path_to_main_dic]; - [subdic_path setStringValue:path_to_sub_dic]; - [NSApp activateIgnoringOtherApps:YES]; [[self window] makeKeyAndOrderFront:nil]; @@ -329,32 +296,8 @@ - (BOOL)windowShouldClose:(NSNotification *)aNotification { NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; - if(![[[maindic_path stringValue] stringByAbbreviatingWithTildeInPath] isEqualToString:path_to_main_dic]) { - // C«ÌêªÏíÁ½ - [path_to_main_dic release]; - path_to_main_dic = [[[maindic_path stringValue] stringByAbbreviatingWithTildeInPath] retain]; - - [defaults setObject:path_to_main_dic forKey:MainDictPathKey]; - - SKKServer::sharedServer().getBaseDic().changeDictionaryFile([[self getPathToMainDic] cString]); - } - - if(![[[subdic_path stringValue] stringByAbbreviatingWithTildeInPath] isEqualToString:path_to_sub_dic]) { - // Tu«ÌêªÏíÁ½ - [path_to_sub_dic release]; - path_to_sub_dic = [[[subdic_path stringValue] stringByAbbreviatingWithTildeInPath] retain]; - - [defaults setObject:path_to_sub_dic forKey:SubDictPathKey]; - - SKKServer::sharedServer().getSubDic().changeDictionaryFile([[self getPathToSubDic] cString]); - } - - // ±Æ¦è«ð[h·é - std::vector<CppCFString> vec; - for(unsigned i = 0 ; i < [[self path] count] ; ++ i) { - vec.push_back((CFStringRef)[[self path] objectAtIndex:i]); - } - SKKServer::sharedServer().getKotoeriDic().changeDictionaryFile(vec); + // «T[o[ðÄú»·é + SKKServer::sharedServer().reload(); Skkserv& skkserv = Skkserv::sharedServer(); skkserv.setLocalOnly([skkserv_local_only state] == YES ? true : false); @@ -382,81 +325,6 @@ return TRUE; } -- (IBAction)selectMainDic:(id)sender { - // empty -} - -- (IBAction)selectSubDic:(id)sender { - // empty -} - -// ±Æ¦è« - -- (IBAction)addKotoeriDic:(id)sender { - NSOpenPanel *op = [NSOpenPanel openPanel]; - - [op beginSheetForDirectory:NSHomeDirectory() - file:nil - types:nil - modalForWindow:[self window] - modalDelegate:self - didEndSelector:@selector(openPanelDidEnd:returnCode:contextInfo:) - contextInfo:NULL]; - - [kotoeriDicTable reloadData]; -} - -- (void)openPanelDidEnd:(NSOpenPanel *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo { - if(returnCode == NSOKButton) { - if([dicPath containsObject:[sheet filename]] == YES) { - NSBeep(); - return; - } - - if(SKKServer::sharedServer().getKotoeriDic().checkDictionary((CFStringRef)[sheet filename]) == false) { - NSBeep(); - return; - } - - [dicPath addObject:[sheet filename]]; - [self controlSetting]; - [kotoeriDicTable reloadData]; - } -} - -- (IBAction)removeKotoeriDic:(id)sender { - int selected = [kotoeriDicTable selectedRow]; - if(selected == -1) { - return; - } - - [dicPath removeObjectAtIndex:selected]; - [self controlSetting]; - [kotoeriDicTable reloadData]; -} - -- (void)controlSetting { - [addKotoeriBtn setEnabled:( [dicPath count] == 10 ) ? NO : YES ]; - [removeKotoeriBtn setEnabled:( [dicPath count] == 0 ) ? NO : YES ]; -} - -- (int)numberOfRowsInTableView:(NSTableView *)aTableView { - return [dicPath count]; -} - -- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex { - // Second column - if([[aTableColumn identifier] isEqualToString:@"name"]) - return [dicPath objectAtIndex:rowIndex]; - - // Not reach this statement - return nil; -} - -- (NSArray *)path { - return dicPath; -} - // skkserv - (BOOL)isSkkservEnabled { return [skkserv_enabled state]; Index: AquaSKK/SKKServer.cpp diff -u AquaSKK/SKKServer.cpp:1.4.2.1 AquaSKK/SKKServer.cpp:1.4.2.2 --- AquaSKK/SKKServer.cpp:1.4.2.1 Mon Jan 9 11:11:05 2006 +++ AquaSKK/SKKServer.cpp Wed Feb 15 00:12:44 2006 @@ -1,5 +1,5 @@ /* - $Id: SKKServer.cpp,v 1.4.2.1 2006/01/09 02:11:05 t-suwa Exp $ + $Id: SKKServer.cpp,v 1.4.2.2 2006/02/14 15:12:44 t-suwa Exp $ MacOS X implementation of the SKK input method. @@ -21,17 +21,15 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include <Carbon/Carbon.h> #include <iostream> -#include <string> -#include <vector> -#include <map> +#include <sstream> #include "CppCFString.h" #include "OkuriganaEntry.h" #include "Dictionary.h" -#include "DMDictionary.h" #include "SKKDictionary.h" +#include "DMDictionary.h" #include "SKKServer.h" +#include "SkkConfig.h" #if 0 # define D_PRINTF printf @@ -39,69 +37,160 @@ # define D_PRINTF if(0)printf #endif +// èÈÇ +const char* SKK_USER_DICT_PATH = "/Library/AquaSKK/skk-user-dic"; + +// [eBeB static void removeRedundantItems(std::vector<CppCFString>& candidates); -static SKKServer* _shared_instance = NULL; +// Null « +class NullDictionary: public Dictionary { +public: + NullDictionary(const std::string& location) { + // empty + } + virtual ~NullDictionary() { + // empty + } + virtual int countOkuriAri() { + return 0; + } + virtual int countOkuriNasi() { + return 0; + } + virtual std::vector<OkuriganaEntry> findOkuriAri(const CppCFString& query) { + return std::vector<OkuriganaEntry>(); + } + virtual std::vector<CppCFString> findOkuriNasi(const CppCFString& query) { + return std::vector<CppCFString>(); + } +}; + +// t@Ng\bh +Dictionary* SKKServer::createDictionary(const DictionaryPref& pref) const { + switch(pref.type) { + case SKKDictionaryType: + return new SKKDictionary(pref.location); + break; + case SKKAutoUpdateDictionaryType: + return new NullDictionary(pref.location); + break; + case KotoeriDictionaryType: + return new KotoeriDictionary(pref.location); + break; + case ProxyDictionaryType: + return new NullDictionary(pref.location); + break; + case GroupingDictionaryType: + return new NullDictionary(pref.location); + break; + default: + std::cerr << "SKKServer::createDictionary(): unknown type[" << pref.type << "]" << std::endl; + break; + } -SKKServer& SKKServer::sharedServer() { - return *_shared_instance; + return new NullDictionary(pref.location); +} + +// map L[¶¬ +std::string SKKServer::generateID(const DictionaryPref& pref) const { + std::stringstream id; + + // «Ì ID 𶬷é + id << pref.type << ":" << pref.location; + + return id.str(); +} + +void SKKServer::load() { + CFArrayRef arrayRef = (CFArrayRef)CFPreferencesCopyAppValue(CFSTR("DictionaryInfo"), + kCFPreferencesCurrentApplication); + if(arrayRef == NULL) { + return; + } + + // âîñðNA·é + prefs_.clear(); + + // Âl«ðæªÉüêé + DictionaryPref entry; + entry.active = true; + entry.type = SKKDictionaryType; + entry.location = SkkConfig::home() + SKK_USER_DICT_PATH; + prefs_.push_back(entry); + if(dicts_.find(generateID(entry)) == dicts_.end()) { + dicts_[generateID(entry)] = userdict_; + } + + // LøÈ«ðSÄ[h·é + for(CFIndex index = 0; index < CFArrayGetCount(arrayRef); ++ index) { + CFDictionaryRef dictRef = (CFDictionaryRef)CFRetain(CFArrayGetValueAtIndex(arrayRef, index)); + + // DictionaryPref ðìé + entry.active = ((CFBooleanRef)CFDictionaryGetValue(dictRef, CFSTR("active")) == kCFBooleanTrue); + CFNumberGetValue((CFNumberRef)CFDictionaryGetValue(dictRef, CFSTR("type")), kCFNumberIntType, &entry.type); + CFStringRef str = (CFStringRef)CFDictionaryGetValue(dictRef, CFSTR("location")); + if(str) { + char buf[2048]; + CFStringGetCString(str, buf, sizeof(buf), kCFStringEncodingEUC_JP); + entry.location = buf; + } else { + entry.location = ""; + } + + // ì¬ÏÝÌ«ª êÎA澵Ĩ + DictionaryIterator iter = dicts_.find(generateID(entry)); + + // Lø©H + if(entry.active) { + prefs_.push_back(entry); + + // ©Â©çȯêÎAÇÁµÄ¨ + if(iter == dicts_.end()) { + dicts_[generateID(entry)] = createDictionary(entry); + } + } else { + // ì¬ÏÝųøɳ꽫ÍÁ· + if(iter != dicts_.end()) { + delete iter->second; + dicts_.erase(generateID(entry)); + } + } + CFRelease(dictRef); + } + CFRelease(arrayRef); } -SKKServer& -SKKServer::sharedServer(const std::string& base_dic_file, - const std::string& sub_dic_file, - const std::string& user_dic_file, - const std::vector<CppCFString>& kotoeri_dic_file) { - if(_shared_instance == NULL) { - _shared_instance = new SKKServer(base_dic_file, sub_dic_file, - user_dic_file, kotoeri_dic_file); - } - - return *_shared_instance; -} - -SKKServer::SKKServer(const std::string& base_dic_file, - const std::string& sub_dic_file, - const std::string& user_dic_file, - const std::vector<CppCFString>& kotoeri_dic_file) { - base_dic = new SKKDictionary(base_dic_file); - sub_dic = new SKKDictionary(sub_dic_file); - user_dic = new SKKUserDictionary(user_dic_file); - kotoeri_dic = new DMDictionary(kotoeri_dic_file); - - all_dics.push_back(user_dic); - all_dics.push_back(sub_dic); - all_dics.push_back(base_dic); - all_dics.push_back(kotoeri_dic); +SKKServer::SKKServer() { + userdict_ = new SKKUserDictionary(SkkConfig::home() + SKK_USER_DICT_PATH); + load(); } SKKServer::~SKKServer() { terminate(); } +SKKServer& SKKServer::sharedServer() { + static SKKServer obj; + return obj; +} + +void SKKServer::reload() { + // «ð[hµ¼· + load(); +} + void SKKServer::terminate() { struct local { - static void DeleteDictionary(Dictionary* ptr) { - delete ptr; - ptr = NULL; + static void DeleteDictionary(std::pair<std::string, Dictionary*> entry) { + delete entry.second; + entry.second = NULL; } }; // SÄÌ«ðí·é - std::for_each(all_dics.begin(), all_dics.end(), local::DeleteDictionary); - all_dics.clear(); -} - -SKKDictionary& SKKServer::getBaseDic() { - return *dynamic_cast<SKKDictionary*>(base_dic); -} - -SKKDictionary& SKKServer::getSubDic() { - return *dynamic_cast<SKKDictionary*>(sub_dic); -} - -DMDictionary& SKKServer::getKotoeriDic() { - return *dynamic_cast<DMDictionary*>(kotoeri_dic); + std::for_each(dicts_.begin(), dicts_.end(), local::DeleteDictionary); + dicts_.clear(); } CppCFString SKKServer::skkserv_style_search(const CppCFString& query) { @@ -113,34 +202,33 @@ } // èï¼ÍLé©H - if(query[0] > 0xff && - query[query.length()-1] >= 'a' && query[query.length()-1] <= 'z') { + if(query[0] > 0xff && query[query.length() - 1] >= 'a' && query[query.length() - 1] <= 'z') { // OkuriganaEntry.kana => OkuriganaEntry std::map<CppCFString, OkuriganaEntry> cands; - for(std::vector<Dictionary*>::const_iterator dic = all_dics.begin(); - dic != all_dics.end(); ++ dic) { + for(DictionaryPrefIterator iter = prefs_.begin(); iter != prefs_.end(); ++ iter) { + // O[v«ÌêAùÉó⪩©ÁÄ¢êÎõðâßé + if(iter->type == GroupingDictionaryType && !cands.empty()) { + break; + } - std::vector<OkuriganaEntry> vec_okuri = (*dic)->findOkuriAri(query); - if(vec_okuri.empty()) { + Dictionary* dict = dicts_[generateID(*iter)]; + std::vector<OkuriganaEntry> okuriEntries = dict->findOkuriAri(query); + if(okuriEntries.empty()) { continue; } - for(std::vector<OkuriganaEntry>::iterator e = vec_okuri.begin(); - e != vec_okuri.end(); ++ e) { + for(std::vector<OkuriganaEntry>::iterator e = okuriEntries.begin(); e != okuriEntries.end(); ++ e) { OkuriganaEntry& entry = cands[e->getKana()]; entry.setKana(e->getKana()); - entry.getCandidates().insert( - entry.getCandidates().begin(), - e->getCandidates().begin(), - e->getCandidates().end()); + entry.getCandidates().insert(entry.getCandidates().begin(), + e->getCandidates().begin(), e->getCandidates().end()); } } // SÄÌGgÉ¢ÄAd¡µÄîéàÌðíµÈªçAv // Cðg§ÄéB CppCFString reply; - for(std::map<CppCFString, OkuriganaEntry>::iterator e = cands.begin(); - e != cands.end(); ++ e) { + for(std::map<CppCFString, OkuriganaEntry>::iterator e = cands.begin(); e != cands.end(); ++ e) { OkuriganaEntry& entry = e->second; entry.removeRedundantItems(); if(entry.isWild()) { @@ -158,14 +246,16 @@ // èJ³¢B std::vector<CppCFString> cands; - for(std::vector<Dictionary*>::const_iterator ite = all_dics.begin(); - ite != all_dics.end(); ++ ite) { + for(DictionaryPrefIterator iter = prefs_.begin(); iter != prefs_.end(); ++ iter) { + // O[v«ÌêAùÉó⪩©ÁÄ¢êÎõðâßé + if(iter->type == GroupingDictionaryType && !cands.empty()) { + break; + } - std::vector<CppCFString> cand_for_one = (*ite)->findOkuriNasi(query); - if(cand_for_one.size() > 0) { - cands.insert(cands.end(), - cand_for_one.begin(), - cand_for_one.end()); + Dictionary* dict = dicts_[generateID(*iter)]; + std::vector<CppCFString> result = dict->findOkuriNasi(query); + if(!result.empty()) { + cands.insert(cands.end(), result.begin(), result.end()); } } @@ -195,36 +285,33 @@ std::vector<CppCFString> cand_strictly_matched; std::vector<CppCFString> cand_unstrictly_matched; - for(std::vector<Dictionary*>::const_iterator dic = all_dics.begin(); - dic != all_dics.end(); ++ dic) { - std::vector<OkuriganaEntry> vec_okuri = (*dic)->findOkuriAri(root); - if(vec_okuri.empty()) continue; - - for(std::vector<OkuriganaEntry>::const_iterator - okuri_entry = vec_okuri.begin(); - okuri_entry != vec_okuri.end(); ++ okuri_entry) { - // ±ÌOkuriganaEntryÌ©oµÆokuriªêvµÄ¢½ç - // cand_strictly_matchedÉüêAêvµÄ¢È¯êÎ - // cand_unstrictly_matchedÉüêéB - if(okuri_entry->getKana() == okuri) { - cand_strictly_matched.insert( - cand_strictly_matched.end(), - okuri_entry->getCandidates().begin(), - okuri_entry->getCandidates().end()); + + for(DictionaryPrefIterator iter = prefs_.begin(); iter != prefs_.end(); ++ iter) { + // O[v«ÌêAùÉó⪩©ÁÄ¢êÎõðâßé + if(iter->type == GroupingDictionaryType && + (!cand_strictly_matched.empty() || !cand_unstrictly_matched.empty())) { + break; + } + + Dictionary* dict = dicts_[generateID(*iter)]; + std::vector<OkuriganaEntry> okuriEntries = dict->findOkuriAri(root); + if(okuriEntries.empty()) { + continue; + } + + for(std::vector<OkuriganaEntry>::iterator e = okuriEntries.begin(); e != okuriEntries.end(); ++ e) { + if(e->getKana() == okuri) { + cand_strictly_matched.insert(cand_strictly_matched.end(), + e->getCandidates().begin(), e->getCandidates().end()); } else { - cand_unstrictly_matched.insert( - cand_unstrictly_matched.end(), - okuri_entry->getCandidates().begin(), - okuri_entry->getCandidates().end()); + cand_unstrictly_matched.insert(cand_unstrictly_matched.end(), + e->getCandidates().begin(), e->getCandidates().end()); } } } std::vector<CppCFString> candidates = cand_strictly_matched; - candidates.insert( - candidates.end(), - cand_unstrictly_matched.begin(), - cand_unstrictly_matched.end()); + candidates.insert(candidates.end(), cand_unstrictly_matched.begin(), cand_unstrictly_matched.end()); // candidatesÌd¡ð`FbNBd¡µÄ¢½çãÉ éàÌðíB removeRedundantItems(candidates); @@ -232,8 +319,7 @@ // ±Ì_ÅcandidatesÉüÁÄ¢éÌͿ̪¾¯ÈÌÅA // SÄÌvfÉè¼¼ðt¯éB¯ÉXy[Xð[20]ÉÏ·B // ߪt¢Ä¢êÎAí·éB(bè) - for(std::vector<CppCFString>::iterator ite = candidates.begin(); - ite != candidates.end(); ++ ite) { + for(std::vector<CppCFString>::iterator ite = candidates.begin(); ite != candidates.end(); ++ ite) { const int semicolon_pos = ite->indexOf(';'); if(semicolon_pos != -1) { ite->erase(semicolon_pos, ite->length()); @@ -245,12 +331,20 @@ return join(' ', candidates); } else { std::vector<CppCFString> candidates; - for(std::vector<Dictionary*>::const_iterator ite = all_dics.begin(); - ite != all_dics.end(); ++ ite) { - std::vector<CppCFString> cand_for_one = (*ite)->findOkuriNasi(query_str); - if(cand_for_one.size() > 0) - candidates.insert(candidates.end(), - cand_for_one.begin(), cand_for_one.end()); + + for(DictionaryPrefIterator iter = prefs_.begin(); iter != prefs_.end(); ++ iter) { + // O[v«ÌêAùÉó⪩©ÁÄ¢êÎõðâßé + if(iter->type == GroupingDictionaryType && !candidates.empty()) { + break; + } + + Dictionary* dict = dicts_[generateID(*iter)]; + std::vector<CppCFString> result = dict->findOkuriNasi(query_str); + if(result.empty()) { + continue; + } + + candidates.insert(candidates.end(), result.begin(), result.end()); } // candidatesÌd¡ð`FbNBd¡µÄ¢½çãÉ éàÌðíB @@ -258,8 +352,7 @@ // candidatesÌSÄÌÚÌXy[Xð[20]ÉÏ·B // ߪt¢Ä¢êÎAí·éB(bè) - for(std::vector<CppCFString>::iterator ite = candidates.begin(); - ite != candidates.end(); ++ ite) { + for(std::vector<CppCFString>::iterator ite = candidates.begin(); ite != candidates.end(); ++ ite) { const int semicolon_pos = ite->indexOf(';'); if(semicolon_pos != -1) { ite->erase(semicolon_pos, ite->length()); @@ -295,7 +388,7 @@ << index.length() << " okuri:" << okuri.length() << " kanji:" << kanji.length() << " (len)" << std::endl; } else { - user_dic->registerOkuriAri(index, okuri, kanji); + userdict_->registerOkuriAri(index, okuri, kanji); } } else { // è¼¼³µBu-©È ¼¼v @@ -310,7 +403,7 @@ << index.length() << " kanji:" << kanji.length() << " (len)" << std::endl; } else { - user_dic->registerOkuriNasi(index, kanji); + userdict_->registerOkuriNasi(index, kanji); } } } @@ -338,7 +431,7 @@ << index.length() << " okuri:" << okuri.length() << " kanji:" << kanji.length() << " (len)" << std::endl; } else { - user_dic->removeOkuriAri(index, kanji); + userdict_->removeOkuriAri(index, kanji); } } else { // è¼¼³µBu-©È ¼¼v @@ -353,7 +446,7 @@ << index.length() << " kanji:" << kanji.length() << " (len)" << std::endl; } else { - user_dic->removeOkuriNasi(index, kanji); + userdict_->removeOkuriNasi(index, kanji); } } } @@ -365,7 +458,7 @@ D_PRINTF("COMPLETE: %s\n", query.toCString(kCFStringEncodingEUC_JP)); CppCFString head = query.replaceClone(nbsp, space); - std::vector<CppCFString> result = user_dic->findCompletions(head); + std::vector<CppCFString> result = userdict_->findCompletions(head); D_PRINTF("REPLY: %s\n", join(' ',result).toCString(kCFStringEncodingEUC_JP)); Index: AquaSKK/SKKServer.h diff -u AquaSKK/SKKServer.h:1.3 AquaSKK/SKKServer.h:1.3.2.1 --- AquaSKK/SKKServer.h:1.3 Wed Nov 9 00:02:24 2005 +++ AquaSKK/SKKServer.h Wed Feb 15 00:12:44 2006 @@ -1,11 +1,10 @@ /* -*- c++ -*- - $Id: SKKServer.h,v 1.3 2005/11/08 15:02:24 t-suwa Exp $ - --------- - + $Id: SKKServer.h,v 1.3.2.1 2006/02/14 15:12:44 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 @@ -26,44 +25,51 @@ #include <string> #include <vector> +#include <map> class CppCFString; class Dictionary; class UserDictionary; -class SKKDictionary; -class DMDictionary; - -/* - ú»ðKvÆ·éSingletonÅ éB - gp·éOÉsharedServer(string,string,string)ðÄÎÈÄÍÈçÈ¢B - - c»Ì¤¿C³µÜ·B©ÍÅ«Ìêðæ¾·é̪³µ¢Æv¤c -*/ class SKKServer { - Dictionary* base_dic; - Dictionary* sub_dic; - UserDictionary* user_dic; - Dictionary* kotoeri_dic; - std::vector<Dictionary*> all_dics; - - SKKServer(const std::string& base_dic_file, - const std::string& sub_dic_file, - const std::string& user_dic_file, - const std::vector<CppCFString>& kotoeri_dic_file); - virtual ~SKKServer(); + // «ÌíÞ + enum DictionaryTypes { + SKKDictionaryType = 10, + SKKAutoUpdateDictionaryType = 11, + KotoeriDictionaryType = 20, + ProxyDictionaryType = 30, + GroupingDictionaryType = 90, + }; + + // «ÌÝè + struct DictionaryPref { + bool active; + int type; + std::string location; + }; + typedef std::vector<DictionaryPref> DictionaryPrefContainer; + typedef DictionaryPrefContainer::iterator DictionaryPrefIterator; + typedef std::map<std::string, Dictionary*> DictionaryContainer; + typedef DictionaryContainer::iterator DictionaryIterator; + + // [U[« + UserDictionary* userdict_; + + DictionaryPrefContainer prefs_; + DictionaryContainer dicts_; + + Dictionary* createDictionary(const DictionaryPref& pref) const; + std::string generateID(const DictionaryPref& pref) const; + void load(); + + SKKServer(); + ~SKKServer(); public: - static SKKServer& sharedServer(const std::string& base_dic_file, - const std::string& sub_dic_file, - const std::string& user_dic_file, - const std::vector<CppCFString>& kotoeri_dic_file); static SKKServer& sharedServer(); - void terminate(); - SKKDictionary& getBaseDic(); - SKKDictionary& getSubDic(); - DMDictionary& getKotoeriDic(); + void reload(); + void terminate(); CppCFString skkserv_style_search(const CppCFString& query); // NOT FOUNDÈçó̶ñðÔ·B CppCFString search(const CppCFString& query); // NOT FOUNDÈçó̶ñðÔ·B