Tomotaka SUWA
t-suw****@users*****
2006年 3月 6日 (月) 21:03:00 JST
Index: AquaSKK/CandidatesFrame.h diff -u AquaSKK/CandidatesFrame.h:1.2.2.2 AquaSKK/CandidatesFrame.h:1.2.2.3 --- AquaSKK/CandidatesFrame.h:1.2.2.2 Sun Feb 19 13:50:54 2006 +++ AquaSKK/CandidatesFrame.h Mon Mar 6 21:03:00 2006 @@ -1,5 +1,5 @@ /* -*- objc -*- - $Id: CandidatesFrame.h,v 1.2.2.2 2006/02/19 04:50:54 t-suwa Exp $ + $Id: CandidatesFrame.h,v 1.2.2.3 2006/03/06 12:03:00 t-suwa Exp $ MacOS X implementation of the SKK input method. @@ -26,9 +26,11 @@ // t[®« @interface FrameAttribute : NSObject { NSString* labels_; // ANZX¶ + int candidatesCount_; // óâ NSString* entry_; // PêÌóâ NSString* caption_; // [cè nnn] - NSDictionary* attributes_; // tHg®« + NSDictionary* normalFontAttributes_; // óâ\¦pÌtHg®« + NSDictionary* indexFontAttributes_; // CfbNXpÌtHg®« NSSize viewSize_; // r [é` NSSize marginSize_; // }[W @@ -43,7 +45,8 @@ - (NSString*)labels; - (NSString*)caption; -- (NSDictionary*)fontAttributes; +- (NSDictionary*)normalFontAttributes; +- (NSDictionary*)indexFontAttributes; - (NSSize)viewSize; - (NSSize)marginSize; - (NSSize)itemSize; @@ -66,8 +69,7 @@ } - (bool)addCandidate:(NSString*)str; -- (void)setRemain:(int)remains; - (unsigned)count; -- (void)drawRect:(NSRect)rect; +- (void)drawRect:(NSRect)rect range:(NSRange)range; @end Index: AquaSKK/CandidatesFrame.m diff -u AquaSKK/CandidatesFrame.m:1.4.2.2 AquaSKK/CandidatesFrame.m:1.4.2.3 --- AquaSKK/CandidatesFrame.m:1.4.2.2 Sun Feb 19 13:50:54 2006 +++ AquaSKK/CandidatesFrame.m Mon Mar 6 21:03:00 2006 @@ -1,5 +1,5 @@ /* - $Id: CandidatesFrame.m,v 1.4.2.2 2006/02/19 04:50:54 t-suwa Exp $ + $Id: CandidatesFrame.m,v 1.4.2.3 2006/03/06 12:03:00 t-suwa Exp $ MacOS X implementation of the SKK input method. @@ -33,19 +33,17 @@ labels_ = @"ASDFJKL"; // PêÌGg - char* data = " A ¿"; + char* data = " A ¿ "; NSData* sjis = [[NSData alloc] initWithBytes:data length:strlen(data)]; entry_ = [[NSString alloc] initWithData:sjis encoding:NSShiftJISStringEncoding]; [sjis release]; - // [cè n] - data = "cè"; - sjis = [[NSData alloc] initWithBytes:data length:strlen(data)]; - caption_ = [[NSString alloc] initWithData:sjis encoding:NSShiftJISStringEncoding]; - [sjis release]; + // CfbNXtHg®« + indexFontAttributes_ = [NSDictionary dictionaryWithObject:[NSFont toolTipsFontOfSize:0] + forKey:NSFontAttributeName]; // ]ðßé - marginSize_ = NSMakeSize(8, 8); + marginSize_ = NSMakeSize(8, 6); spaceWidth_ = marginSize_.width * 2; [self refresh]; @@ -69,21 +67,24 @@ NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; NSFont* font = [NSFont fontWithName:[defaults stringForKey:KEY_candidates_font_name] size:[defaults floatForKey:KEY_candidates_font_size]]; - attributes_ = [NSDictionary dictionaryWithObject:font forKey:NSFontAttributeName]; + normalFontAttributes_ = [NSDictionary dictionaryWithObject:font forKey:NSFontAttributeName]; + + // óâðæ¾ + candidatesCount_ = [defaults integerForKey:KEY_candidates_count]; // ÚÌTCYðæ¾ - NSMutableAttributedString* tmp = [[NSMutableAttributedString alloc] initWithString:entry_ attributes:attributes_]; + NSMutableAttributedString* tmp = [[NSMutableAttributedString alloc] initWithString:entry_ + attributes:normalFontAttributes_]; itemSize_ = [tmp size]; [tmp release]; - // [cè n] ÌTCYðæ¾ - NSString* formatedStr = [NSString stringWithFormat:@"[%@ 000]", caption_]; - tmp = [[NSMutableAttributedString alloc] initWithString:formatedStr attributes:attributes_]; + // nnn / mmm ÌTCYðæ¾ + tmp = [[NSMutableAttributedString alloc] initWithString:@"8888 / 8888" attributes:indexFontAttributes_]; NSSize remainSize = [tmp size]; [tmp release]; // Ï·óâð`æ·éGAÌTCY - itemAreaSize_ = NSMakeSize([labels_ length] * (itemSize_.width + spaceWidth_), itemSize_.height); + itemAreaSize_ = NSMakeSize(candidatesCount_ * (itemSize_.width + spaceWidth_), itemSize_.height); // r [SÌÌTCY viewSize_ = NSMakeSize(marginSize_.width * 2 + itemAreaSize_.width + remainSize.width, @@ -91,15 +92,19 @@ } - (NSString*)labels { - return labels_; + return [labels_ substringWithRange:NSMakeRange(0, candidatesCount_)]; } - (NSString*)caption { return caption_; } -- (NSDictionary*)fontAttributes { - return attributes_; +- (NSDictionary*)normalFontAttributes { + return normalFontAttributes_; +} + +- (NSDictionary*)indexFontAttributes { + return indexFontAttributes_; } - (NSSize)viewSize { @@ -158,7 +163,7 @@ // ®«t«¶ñðìé NSMutableAttributedString* entry = [[NSMutableAttributedString alloc] initWithString:tmpstr - attributes:[attr fontAttributes]]; + attributes:[attr normalFontAttributes]]; // x̶FÆwiFðÝè [entry addAttribute:NSBackgroundColorAttributeName @@ -201,15 +206,50 @@ return false; } -- (void)setRemain:(int)remains { - remainCandidates_ = remains; -} - - (unsigned)count { return [candidates_ count]; } -- (void)drawRect:(NSRect)rect { +- (void)drawPage:(NSRange)range { + FrameAttribute* attr = [FrameAttribute sharedFrameAttribute]; + + // nnn / mmm ð`æ + NSString* tmpstr = [NSString stringWithFormat:@"%3d / %-3d", range.location, range.length]; + NSMutableAttributedString* page = [[NSMutableAttributedString alloc] initWithString:tmpstr + attributes:[attr indexFontAttributes]]; + + [[NSColor gridColor] setFill]; + [page addAttribute:NSBackgroundColorAttributeName + value:[NSColor gridColor] range:NSMakeRange(0, [tmpstr length])]; + [page addAttribute:NSForegroundColorAttributeName + value:[NSColor whiteColor] range:NSMakeRange(0, [tmpstr length])]; + + float radius = 0.5 * [page size].height; + NSRect rc = NSMakeRect([attr itemAreaSize].width + [attr marginSize].width + radius, + [attr marginSize].height, + [page size].width, + [page size].height); + + NSPoint topleft = NSMakePoint(NSMinX(rc), NSMaxY(rc)); + NSPoint bottomleft = NSMakePoint(NSMinX(rc), NSMinY(rc)); + NSPoint bottomright = NSMakePoint(NSMaxX(rc), NSMinY(rc)); + + NSBezierPath* oval = [NSBezierPath bezierPath]; + [oval moveToPoint:bottomleft]; + [oval lineToPoint:bottomright]; + [oval appendBezierPathWithArcWithCenter:NSMakePoint(bottomright.x, bottomright.y + radius) + radius:radius startAngle:270 endAngle:90]; + [oval lineToPoint:topleft]; + [oval appendBezierPathWithArcWithCenter:NSMakePoint(topleft.x, topleft.y - radius) + radius:radius startAngle:90 endAngle:270]; + [oval closePath]; + [oval fill]; + + [page drawAtPoint:bottomleft]; + [page release]; +} + +- (void)drawRect:(NSRect)rect range:(NSRange)range { FrameAttribute* attr = [FrameAttribute sharedFrameAttribute]; // ú»³êĢȢH @@ -235,13 +275,8 @@ } } - // [cè n] ð`æ - NSAttributedString* remain = [[NSAttributedString alloc] - initWithString:[NSString stringWithFormat:@"[%@ %d]", - [attr caption], remainCandidates_] - attributes:[attr fontAttributes]]; - [remain drawAtPoint:NSMakePoint([attr marginSize].width + [attr itemAreaSize].width, [attr marginSize].height)]; - [remain release]; + // nnn / mmm ð`æ + [self drawPage:range]; [view_ unlockFocus]; } Index: AquaSKK/CandidatesView.mm diff -u AquaSKK/CandidatesView.mm:1.2.2.1 AquaSKK/CandidatesView.mm:1.2.2.2 --- AquaSKK/CandidatesView.mm:1.2.2.1 Sun Feb 19 13:50:54 2006 +++ AquaSKK/CandidatesView.mm Mon Mar 6 21:03:00 2006 @@ -1,5 +1,5 @@ /* -*- objc -*- - $Id: CandidatesView.mm,v 1.2.2.1 2006/02/19 04:50:54 t-suwa Exp $ + $Id: CandidatesView.mm,v 1.2.2.2 2006/03/06 12:03:00 t-suwa Exp $ MacOS X implementation of the SKK input method. @@ -44,8 +44,7 @@ for(i = 0; i < [cands count]; ++ i) { // ±Ìt[ɱêÈãÍÇÁÅ«È¢H if(![tmpFrame addCandidate:[cands objectAtIndex:i]]) { - // ucèvÌðZbgµÄAzñÉÇÁ - [tmpFrame setRemain:[cands count] - i]; + // zñÉÇÁ [frames addObject:tmpFrame]; [tmpFrame release]; @@ -76,7 +75,7 @@ - (void)drawRect:(NSRect)rect { - [[frames objectAtIndex:current_frame] drawRect:rect]; + [[frames objectAtIndex:current_frame] drawRect:rect range:NSMakeRange(current_frame + 1, [frames count])]; } - (void)showNextFrame Index: AquaSKK/ChangeLog diff -u AquaSKK/ChangeLog:1.20.2.10 AquaSKK/ChangeLog:1.20.2.11 --- AquaSKK/ChangeLog:1.20.2.10 Sat Feb 25 16:27:32 2006 +++ AquaSKK/ChangeLog Mon Mar 6 21:03:00 2006 @@ -1,3 +1,25 @@ +2006-03-06 Tomotaka SUWA <t.suw****@mac*****> + + * skkserv.cpp: I¹ðæèÀSÉC³B + + * UserDefaults.plist: candidates_count ÝèðÇÁB + + * SKKDictionary.*: SKKAutoUpdateDictionary NXðÇÁB + + * PreferencesController.mm: KEY_candidates_count ðÇÁB + + * PreferenceKeys.h: KEY_candidates_count ðÇÁBóâEBhEÉ\ + ¦·éóâB + + * DictionarySet.cpp: d¡·éóâðíéÉߪðOBSKK ©® + XV«Æ Proxy «ÉÎB + + * Dictionary.h: SKKEntryConverter NXðÇÁB + + * ProxyDictionary.*: VKÇÁBO skkserv «B + + * Mutex.h: VKÇÁB + 2006-02-25 Tomotaka SUWA <t.suw****@mac*****> * AquaSKK.pbproj/project.pbxproj: Panther pÉC³B Index: AquaSKK/Dictionary.h diff -u AquaSKK/Dictionary.h:1.3.2.3 AquaSKK/Dictionary.h:1.3.2.4 --- AquaSKK/Dictionary.h:1.3.2.3 Sat Feb 18 02:20:38 2006 +++ AquaSKK/Dictionary.h Mon Mar 6 21:03:00 2006 @@ -1,5 +1,5 @@ /* - $Id: Dictionary.h,v 1.3.2.3 2006/02/17 17:20:38 t-suwa Exp $ + $Id: Dictionary.h,v 1.3.2.4 2006/03/06 12:03:00 t-suwa Exp $ MacOS X implementation of the SKK input method. @@ -21,7 +21,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#pragma once +#ifndef INC__Dictionary__ +#define INC__Dictionary__ #include <vector> #include <string> @@ -72,6 +73,8 @@ } }; +#pragma mark -- Utility -- + // ª¶ñðԵĢPÈp[T class SKKEntryParser { const std::string& target_; @@ -433,3 +436,37 @@ return Key() + " " + Candidate(); } }; + +class SKKEntryConverter { +public: + // SKKEntry ¨ std::vector<OkuriganaEntry> Ï· + static std::vector<OkuriganaEntry> OkuriAri(const SKKEntry& entry) { + // ܸqgîñ©çÇÁ·é + std::vector<OkuriganaEntry> result; + for(SKKOkuriHint hint = entry.FirstHint(); !hint.IsEmpty(); hint = entry.NextHint()) { + OkuriganaEntry okuri; + + 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); + } + + // É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); + + return result; + } + + // SKKEntry ¨ std::vector<CppCFString> Ï· + static std::vector<CppCFString> OkuriNasi(const SKKEntry& entry) { + return CppCFString(entry.Candidate().c_str(), kCFStringEncodingEUC_JP).split('/'); + } +}; + +#endif // INC__Dictionary__ Index: AquaSKK/DictionarySet.cpp diff -u AquaSKK/DictionarySet.cpp:1.1.2.4 AquaSKK/DictionarySet.cpp:1.1.2.5 --- AquaSKK/DictionarySet.cpp:1.1.2.4 Sat Feb 25 16:27:32 2006 +++ AquaSKK/DictionarySet.cpp Mon Mar 6 21:03:00 2006 @@ -1,5 +1,5 @@ /* - $Id: DictionarySet.cpp,v 1.1.2.4 2006/02/25 07:27:32 t-suwa Exp $ + $Id: DictionarySet.cpp,v 1.1.2.5 2006/03/06 12:03:00 t-suwa Exp $ MacOS X implementation of the SKK input method. @@ -28,6 +28,7 @@ #include "Dictionary.h" #include "SKKDictionary.h" #include "KotoeriDictionary.h" +#include "ProxyDictionary.h" #include "DictionarySet.h" #include "SkkConfig.h" @@ -46,9 +47,14 @@ std::vector<CppCFString> result; for(std::vector<CppCFString>::iterator iter = candidates.begin(); iter != candidates.end(); ++ iter) { - if(check.find(*iter) == check.end()) { - check.insert(check.lower_bound(*iter), *iter); - result.push_back(*iter); + // ߪÍärµÈ¢ + std::string str = iter->toStdString(); + std::string::size_type pos = str.find_first_of(';'); + CppCFString target(str.substr(0, pos).c_str(), kCFStringEncodingEUC_JP); + + if(check.find(target) == check.end()) { + check.insert(check.lower_bound(target), target); + result.push_back(target); } } result.swap(candidates); @@ -104,14 +110,14 @@ case SKKDictionaryType: dict = new SKKDictionary(); break; - case SKKAutoUpdateDictionaryType: // ¢À - dict = new NullDictionary(); + case SKKAutoUpdateDictionaryType: + dict = new SKKAutoUpdateDictionary(); break; case KotoeriDictionaryType: dict = new KotoeriDictionary(); break; - case ProxyDictionaryType: // ¢À - dict = new NullDictionary(); + case ProxyDictionaryType: + dict = new ProxyDictionary(); break; case GroupingDictionaryType: dict = new NullDictionary(); Index: AquaSKK/Mutex.h diff -u /dev/null AquaSKK/Mutex.h:1.1.2.1 --- /dev/null Mon Mar 6 21:03:00 2006 +++ AquaSKK/Mutex.h Mon Mar 6 21:03:00 2006 @@ -0,0 +1,59 @@ +/* + $Id: Mutex.h,v 1.1.2.1 2006/03/06 12:03:00 t-suwa Exp $ + + MacOS X implementation of the SKK input method. + + Copyright (C) 2006 Tomotaka SUWA <t.suw****@mac*****> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef INC__Mutex__ +#define INC__Mutex__ + +#include <pthread.h> + +class Mutex { + friend class Guard; + pthread_mutex_t mutex_; + void lock() { + pthread_mutex_lock(&mutex_); + } + void unlock() { + pthread_mutex_unlock(&mutex_); + } + +public: + Mutex() { + pthread_mutex_init(&mutex_, NULL); + } + ~Mutex() { + pthread_mutex_destroy(&mutex_); + } +}; + +class Guard { + Mutex& mutex_; + +public: + Guard(Mutex& ref) : mutex_(ref) { + mutex_.lock(); + } + ~Guard() { + mutex_.unlock(); + } +}; + +#endif Index: AquaSKK/PreferenceKeys.h diff -u AquaSKK/PreferenceKeys.h:1.1.2.3 AquaSKK/PreferenceKeys.h:1.1.2.4 --- AquaSKK/PreferenceKeys.h:1.1.2.3 Sat Feb 25 16:27:32 2006 +++ AquaSKK/PreferenceKeys.h Mon Mar 6 21:03:00 2006 @@ -1,5 +1,5 @@ /* -*- objc -*- - $Id: PreferenceKeys.h,v 1.1.2.3 2006/02/25 07:27:32 t-suwa Exp $ + $Id: PreferenceKeys.h,v 1.1.2.4 2006/03/06 12:03:00 t-suwa Exp $ MacOS X implementation of the SKK input method. @@ -30,6 +30,7 @@ extern NSString* KEY_force_ascii_mode_startup; extern NSString* KEY_keyboard_layout_id; +extern NSString* KEY_candidates_count; extern NSString* KEY_candidates_font_name; extern NSString* KEY_candidates_font_size; extern NSString* KEY_candidates_window_color; Index: AquaSKK/PreferencesController.mm diff -u AquaSKK/PreferencesController.mm:1.6.2.9 AquaSKK/PreferencesController.mm:1.6.2.10 --- AquaSKK/PreferencesController.mm:1.6.2.9 Sat Feb 25 16:27:32 2006 +++ AquaSKK/PreferencesController.mm Mon Mar 6 21:03:00 2006 @@ -1,5 +1,5 @@ /* -*- objc -*- - $Id: PreferencesController.mm,v 1.6.2.9 2006/02/25 07:27:32 t-suwa Exp $ + $Id: PreferencesController.mm,v 1.6.2.10 2006/03/06 12:03:00 t-suwa Exp $ MacOS X implementation of the SKK input method. @@ -37,6 +37,7 @@ NSString* KEY_numkeypad_use_halfwidth = @"numkeypad_use_halfwidth"; NSString* KEY_force_ascii_mode_startup = @"force_ascii_mode_startup"; +NSString* KEY_candidates_count = @"candidates_count"; NSString* KEY_candidates_font_name = @"candidates_font_name"; NSString* KEY_candidates_font_size = @"candidates_font_size"; NSString* KEY_candidates_window_color = @"candidates_window_color"; Index: AquaSKK/ProxyDictionary.cpp diff -u /dev/null AquaSKK/ProxyDictionary.cpp:1.1.2.1 --- /dev/null Mon Mar 6 21:03:00 2006 +++ AquaSKK/ProxyDictionary.cpp Mon Mar 6 21:03:00 2006 @@ -0,0 +1,110 @@ +/* + $Id: ProxyDictionary.cpp,v 1.1.2.1 2006/03/06 12:03:00 t-suwa Exp $ + + MacOS X implementation of the SKK input method. + + Copyright (C) 2006 Tomotaka SUWA <t.suw****@mac*****> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include <sstream> +#include "CppCFString.h" +#include "OkuriganaEntry.h" +#include "ProxyDictionary.h" + +ProxyDictionary::ProxyDictionary() : host_("localhost"), port_(1178), active_(false) { + // empty +} + +ProxyDictionary::~ProxyDictionary() { + session_.close(); +} + +void ProxyDictionary::load(const std::string& path) { + // path Íuhost:portv`® + std::string::size_type pos = path.find_first_of(":"); + if(pos != std::string::npos) { + host_ = path.substr(0, pos); + std::stringstream buf(path.substr(pos + 1)); + buf >> port_; + } else { + if(!path.empty()) { + host_ = path; + } + } + + std::cerr << "Proxy Dictionary(" << host_ << ":" << port_ << ")" << std::endl << std::endl; +} + +int ProxyDictionary::countOkuriAri() { + return 0; +} + +int ProxyDictionary::countOkuriNasi() { + return 0; +} + +std::vector<OkuriganaEntry> ProxyDictionary::findOkuriAri(const CppCFString& str) { + std::string key(str.toStdString()); + std::string response; + + // qbgµ½H + if(search(key, response)) { + return SKKEntryConverter::OkuriAri(SKKEntry::ParseOkuriAri(key, response)); + } + + return std::vector<OkuriganaEntry>(); +} + +std::vector<CppCFString> ProxyDictionary::findOkuriNasi(const CppCFString& str) { + std::string key(str.toStdString()); + std::string response; + + // qbgµ½H + if(search(key, response)) { + return SKKEntryConverter::OkuriNasi(SKKEntry::ParseOkuriNasi(key, response)); + } + + return std::vector<CppCFString>(); +} + +bool ProxyDictionary::search(const std::string& str, std::string& response) { + // Ú±·é + if(!session_) { + session_.open(host_.c_str(), port_); + if(!session_) return false; + } + + // ÄüÅ[v·éÌðh® + if(active_) return false; + active_ = true; + + // NGM + session_ << "1" << str << " "; + session_.flush(); + + // ÊóM + getline(session_, response); + + active_ = false; + + if(response[0] == '1') { + response = response.substr(1); + return true; + } else { + return false; + } +} Index: AquaSKK/ProxyDictionary.h diff -u /dev/null AquaSKK/ProxyDictionary.h:1.1.2.1 --- /dev/null Mon Mar 6 21:03:00 2006 +++ AquaSKK/ProxyDictionary.h Mon Mar 6 21:03:00 2006 @@ -0,0 +1,54 @@ +/* + $Id: ProxyDictionary.h,v 1.1.2.1 2006/03/06 12:03:00 t-suwa Exp $ + + MacOS X implementation of the SKK input method. + + Copyright (C) 2006 Tomotaka SUWA <t.suw****@mac*****> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef INC__ProxyDictionary__ +#define INC__ProxyDictionary__ + +#include "Dictionary.h" +#include "socketstream.h" + +class OkuriganaEntry; +class CppCFString; + +// O skkserv « +class ProxyDictionary: public Dictionary { + socket_stream session_; + std::string host_; + unsigned short port_; + bool active_; + + bool search(const std::string& key, std::string& response); + +public: + ProxyDictionary(); + virtual ~ProxyDictionary(); + + virtual void load(const std::string& path); + + virtual int countOkuriAri(); + virtual int countOkuriNasi(); + + virtual std::vector<OkuriganaEntry> findOkuriAri(const CppCFString& query); + virtual std::vector<CppCFString> findOkuriNasi(const CppCFString& query); +}; + +#endif Index: AquaSKK/SKKDictionary.cpp diff -u AquaSKK/SKKDictionary.cpp:1.6.2.2 AquaSKK/SKKDictionary.cpp:1.6.2.3 --- AquaSKK/SKKDictionary.cpp:1.6.2.2 Sat Feb 18 02:20:38 2006 +++ AquaSKK/SKKDictionary.cpp Mon Mar 6 21:03:00 2006 @@ -1,5 +1,5 @@ /* - $Id: SKKDictionary.cpp,v 1.6.2.2 2006/02/17 17:20:38 t-suwa Exp $ + $Id: SKKDictionary.cpp,v 1.6.2.3 2006/03/06 12:03:00 t-suwa Exp $ MacOS X implementation of the SKK input method. @@ -29,11 +29,13 @@ #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> +#include <pthread.h> #include "CppCFString.h" #include "OkuriganaEntry.h" #include "Dictionary.h" #include "SKKDictionary.h" -#include "SKKConfig.h" +#include "SkkConfig.h" +#include "socketstream.h" #pragma mark --- SKK common functions --- @@ -117,35 +119,6 @@ ofs_ << pair.first << " " << pair.second << std::endl; } }; - - // 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; - - 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); - } - - // É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); - - return result; - } - - // SKKEntry ¨ std::vector<CppCFString> Ï· - std::vector<CppCFString> ConvertOkuriNasi(const SKKEntry& entry) { - return CppCFString(entry.Candidate().c_str(), kCFStringEncodingEUC_JP).split('/'); - } }; #pragma mark --- SKKDictionary --- @@ -158,14 +131,12 @@ // empty } -void SKKDictionary::load(const std::string& path) { +void SKKDictionary::initializeContainer(EntryContainer& okuriAri, EntryContainer& okuriNasi) { std::string line; std::string index; std::string entry; std::ifstream dic; - path_ = path; - if(!skkdic::OpenAndSeek(path_, dic)) { return; } @@ -178,7 +149,7 @@ if(skkdic::OkuriNasiMark.find(line) != std::string::npos) break; // èȵGgÍ~Å\[g³êÄ¢é͸ - okuriAri_.push_front(SKKPair(index, line)); + okuriAri.push_front(SKKPair(index, line)); } while(1) { @@ -188,8 +159,15 @@ std::getline(dic, line); // è èGg͸Å\[g³êÄ¢é͸ - okuriNasi_.push_back(SKKPair(index, line)); + okuriNasi.push_back(SKKPair(index, line)); } +} + +void SKKDictionary::load(const std::string& path) { + path_ = path; + + // «ð[h + initializeContainer(okuriAri_, okuriNasi_); // Ggð\[g·é std::sort(okuriAri_.begin(), okuriAri_.end(), skkdic::EntryCompare()); @@ -218,7 +196,7 @@ EntryIterator i = std::lower_bound(okuriAri_.begin(), okuriAri_.end(), index, skkdic::EntryCompare()); - return skkdic::ConvertOkuriAri(SKKEntry::ParseOkuriAri(i->first, i->second)); + return SKKEntryConverter::OkuriAri(SKKEntry::ParseOkuriAri(i->first, i->second)); } std::vector<CppCFString> SKKDictionary::findOkuriNasi(const CppCFString& query) { @@ -231,7 +209,121 @@ EntryIterator i = std::lower_bound(okuriNasi_.begin(), okuriNasi_.end(), index, skkdic::EntryCompare()); - return skkdic::ConvertOkuriNasi(SKKEntry::ParseOkuriNasi(i->first, i->second)); + return SKKEntryConverter::OkuriNasi(SKKEntry::ParseOkuriNasi(i->first, i->second)); +} + +#pragma mark --- SKKAutoUpdateDictionary --- + +SKKAutoUpdateDictionary::SKKAutoUpdateDictionary() { + // empty +} + +SKKAutoUpdateDictionary::~SKKAutoUpdateDictionary() { + // empty +} + +void SKKAutoUpdateDictionary::load(const std::string& path) { + std::string::size_type pos = path.find_first_of('/'); + host_ = path.substr(0, pos); + url_ = path.substr(pos); + + pos = path.find_last_of('/'); + path_ = SkkConfig::home() + "/Library/AquaSKK" + path.substr(pos); + initializeContainer(okuriAri_, okuriNasi_); + + std::cerr << "SKK AutoUpdate Dictionary(" << path_ << ")" << std::endl + << " okuri-ari: " << countOkuriAri() << " entries." << std::endl + << " okuri-nasi: " << countOkuriNasi() << " entries." << std::endl << std::endl; + + // _E[hpÌXbhðç¹é + pthread_t pth = 0; + if(pthread_create(&pth, NULL, SKKAutoUpdateDictionary::download, this) == 0) { + pthread_detach(pth); + } else { + std::cerr << "pthread_create() failed: " << errno << std::endl; + } +} + +int SKKAutoUpdateDictionary::countOkuriAri() { + Guard g(mutex_); + return SKKDictionary::countOkuriAri(); +} + +int SKKAutoUpdateDictionary::countOkuriNasi() { + Guard g(mutex_); + return SKKDictionary::countOkuriNasi(); +} + +std::vector<OkuriganaEntry> SKKAutoUpdateDictionary::findOkuriAri(const CppCFString& query) { + Guard g(mutex_); + return SKKDictionary::findOkuriAri(query); +} + +std::vector<CppCFString> SKKAutoUpdateDictionary::findOkuriNasi(const CppCFString& query) { + Guard g(mutex_); + return SKKDictionary::findOkuriNasi(query); +} + +void* SKKAutoUpdateDictionary::download(void* param) { + SKKAutoUpdateDictionary* obj = static_cast<SKKAutoUpdateDictionary*>(param); + + socket_stream session(obj->host_.c_str(), 80); + if(!session) { + std::cerr << "can't connect to [" << obj->host_ << "]" << std::endl; + return NULL; + } + + while(true) { + // «ÌXVútðæ¾ + char timestamp[64]; + struct stat st; + if(stat(obj->path_.c_str(), &st) != 0) { + st.st_mtime = 0; + } + strftime(timestamp, sizeof(timestamp), "%a, %d %b %Y %T %Z", gmtime(&st.st_mtime)); + + // NGXg + session << "GET " << obj->url_ << " HTTP/1.1" << std::endl; + session << "Host: " << obj->host_ << std::endl; + session << "If-Modified-Since: " << timestamp << std::endl; + session << "Connection: close" << std::endl << std::endl; + + // X|X + std::string response; + bool modified = false; + while(true) { + getline(session, response); + if(response.find("200 OK") != std::string::npos) { + modified = true; + } + if(response == "\r") break; + } + + if(modified) { + // Û¶ + std::ofstream ofs(obj->path_.c_str()); + while(true) { + getline(session, response); + if(response.empty()) break; + ofs << response << std::endl; + } + + // [h + EntryContainer tmpOkuriAri; + EntryContainer tmpOkuriNasi; + obj->initializeContainer(tmpOkuriAri, tmpOkuriNasi); + + // u«·¦ + Guard g(obj->mutex_); + tmpOkuriAri.swap(obj->okuriAri_); + tmpOkuriNasi.swap(obj->okuriNasi_); + + std::cerr << "SKK AutoUpdate Dictionary(" << obj->path_ << ") updated" << std::endl; + } + + // 6 ÔÒ + sleep(60 * 60 * 6); + } } #pragma mark --- SKKUserDictionary --- @@ -295,7 +387,7 @@ return std::vector<OkuriganaEntry>(); } - return skkdic::ConvertOkuriAri(SKKEntry::ParseOkuriAri(i->first, i->second)); + return SKKEntryConverter::OkuriAri(SKKEntry::ParseOkuriAri(i->first, i->second)); } std::vector<CppCFString> SKKUserDictionary::findOkuriNasi(const CppCFString& query) { @@ -306,7 +398,7 @@ return std::vector<CppCFString>(); } - return skkdic::ConvertOkuriNasi(SKKEntry::ParseOkuriNasi(i->first, i->second)); + return SKKEntryConverter::OkuriNasi(SKKEntry::ParseOkuriNasi(i->first, i->second)); } std::vector<CppCFString> SKKUserDictionary::findCompletions(const CppCFString& query) { Index: AquaSKK/SKKDictionary.h diff -u AquaSKK/SKKDictionary.h:1.5.2.2 AquaSKK/SKKDictionary.h:1.5.2.3 --- AquaSKK/SKKDictionary.h:1.5.2.2 Sat Feb 18 02:20:38 2006 +++ AquaSKK/SKKDictionary.h Mon Mar 6 21:03:00 2006 @@ -1,5 +1,5 @@ /* - $Id: SKKDictionary.h,v 1.5.2.2 2006/02/17 17:20:38 t-suwa Exp $ + $Id: SKKDictionary.h,v 1.5.2.3 2006/03/06 12:03:00 t-suwa Exp $ MacOS X implementation of the SKK input method. @@ -25,6 +25,7 @@ #include <deque> #include "Dictionary.h" +#include "Mutex.h" class OkuriganaEntry; class CppCFString; @@ -38,10 +39,13 @@ // SKK ¤L« class SKKDictionary: public Dictionary { +protected: std::string path_; EntryContainer okuriAri_; EntryContainer okuriNasi_; + void initializeContainer(EntryContainer& okuriAri, EntryContainer& okuriNasi); + public: SKKDictionary(); virtual ~SKKDictionary(); @@ -53,8 +57,27 @@ virtual std::vector<OkuriganaEntry> findOkuriAri(const CppCFString& query); virtual std::vector<CppCFString> findOkuriNasi(const CppCFString& query); +}; + +// SKK ©®XV« +class SKKAutoUpdateDictionary: public SKKDictionary { + std::string host_; + std::string url_; + Mutex mutex_; + + static void* download(void* param); - void changeDictionaryFile(const std::string& fpath); +public: + SKKAutoUpdateDictionary(); + virtual ~SKKAutoUpdateDictionary(); + + virtual void load(const std::string& path); + + virtual int countOkuriAri(); + virtual int countOkuriNasi(); + + virtual std::vector<OkuriganaEntry> findOkuriAri(const CppCFString& query); + virtual std::vector<CppCFString> findOkuriNasi(const CppCFString& query); }; // SKK [U[« Index: AquaSKK/UserDefaults.plist diff -u AquaSKK/UserDefaults.plist:1.1.2.3 AquaSKK/UserDefaults.plist:1.1.2.4 --- AquaSKK/UserDefaults.plist:1.1.2.3 Sat Feb 25 16:27:32 2006 +++ AquaSKK/UserDefaults.plist Mon Mar 6 21:03:00 2006 @@ -2,6 +2,8 @@ <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> + <key>candidates_count</key> + <integer>7</integer> <key>candidates_font_name</key> <string>LucidaGrande</string> <key>candidates_font_size</key> Index: AquaSKK/skkserv.cpp diff -u AquaSKK/skkserv.cpp:1.1.2.5 AquaSKK/skkserv.cpp:1.1.2.6 --- AquaSKK/skkserv.cpp:1.1.2.5 Sat Feb 25 16:27:32 2006 +++ AquaSKK/skkserv.cpp Mon Mar 6 21:03:00 2006 @@ -1,5 +1,5 @@ /* -*- c++ -*- - $Id: skkserv.cpp,v 1.1.2.5 2006/02/25 07:27:32 t-suwa Exp $ + $Id: skkserv.cpp,v 1.1.2.6 2006/03/06 12:03:00 t-suwa Exp $ MacOS X implementation of the SKK input method. @@ -53,12 +53,12 @@ } void skkserv::stop() { + server_.close(); if(pth_) { pthread_cancel(pth_); pthread_join(pth_, NULL); pth_ = 0; } - server_.close(); } void* skkserv::engine(void* param) { @@ -102,9 +102,8 @@ // ©Â©Á½H if(reply.length() > 0) { - char* reply_c = reply.toCString(kCFStringEncodingEUC_JP); - sock << "1" << reply_c << "\n"; - delete[] reply_c; + std::string candidates = reply.toStdString(); + sock << "1" << candidates << "\n"; } else { sock << "4" << word << "\n"; } @@ -116,7 +115,7 @@ sock.flush(); break; case '3': // zXgîñ - sock << ip_address::getsockname(sock.socket()) << "::" << std::endl; + sock << ip_address::getsockname(sock.socket()) << ":0.0.0.0:" << std::endl; sock.flush(); break; default: // ³øÈR}h