1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 3 * 4 * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. 5 * 6 * The contents of this file are subject to the terms of either the GNU Lesser 7 * General Public License Version 2.1 only ("LGPL") or the Common Development and 8 * Distribution License ("CDDL")(collectively, the "License"). You may not use this 9 * file except in compliance with the License. You can obtain a copy of the CDDL at 10 * http://www.opensource.org/licenses/cddl1.php and a copy of the LGPLv2.1 at 11 * http://www.opensource.org/licenses/lgpl-license.php. See the License for the 12 * specific language governing permissions and limitations under the License. When 13 * distributing the software, include this License Header Notice in each file and 14 * include the full text of the License in the License file as well as the 15 * following notice: 16 * 17 * NOTICE PURSUANT TO SECTION 9 OF THE COMMON DEVELOPMENT AND DISTRIBUTION LICENSE 18 * (CDDL) 19 * For Covered Software in this distribution, this License shall be governed by the 20 * laws of the State of California (excluding conflict-of-law provisions). 21 * Any litigation relating to this License shall be subject to the jurisdiction of 22 * the Federal Courts of the Northern District of California and the state courts 23 * of the State of California, with venue lying in Santa Clara County, California. 24 * 25 * Contributor(s): 26 * 27 * If you wish your version of this file to be governed by only the CDDL or only 28 * the LGPL Version 2.1, indicate your decision by adding "[Contributor]" elects to 29 * include this software in this distribution under the [CDDL or LGPL Version 2.1] 30 * license." If you don't indicate a single choice of license, a recipient has the 31 * option to distribute your version of this file under either the CDDL or the LGPL 32 * Version 2.1, or to extend the choice of license to its licensees as provided 33 * above. However, if you add LGPL Version 2.1 code and therefore, elected the LGPL 34 * Version 2 license, then the option applies only if the new code is made subject 35 * to such option by the copyright holder. 36 */ 37 38 #include <sys/stat.h> 39 #import "imi_view.h" 40 #import "SunPinyinApplicationDelegate.h" 41 #import <Sparkle/Sparkle.h> 42 43 static NSString* get_history_path (); 44 static bool save_history (CICHistory*); 45 static bool load_history (CICHistory*); 46 static bool load_preferences (CSunpinyinOptions*); 47 48 @implementation SunPinyinApplicationDelegate 49 50 //this method is added so that our controllers can access the shared NSMenu. 51 -(NSMenu*)menu 52 { 53 return _menu; 54 } 55 56 -(CandidateWindow*)candiWin 57 { 58 return _candiWin; 59 } 60 61 //this method is to return a CIMIData instance which loads the language model and lexicon file 62 -(CIMIData*)sysData 63 { 64 if (_data == NULL) { 65 _data = new CIMIData(); 66 const char * res_path = [[[NSBundle mainBundle] resourcePath] UTF8String]; 67 char slm_path[512], pydict_path[512]; 68 snprintf (slm_path, sizeof(slm_path), "%s/%s", res_path, "lm_sc.t3g"); 69 snprintf (pydict_path, sizeof(pydict_path), "%s/%s", res_path, "pydict_sc.bin"); 70 if (_data->loadResource(slm_path, pydict_path)) 71 return _data; 72 73 delete _data; 74 _data = NULL; 75 } 76 77 return _data; 78 } 79 80 -(CBigramHistory*)history 81 { 82 if (_history == nil) { 83 _history = new CBigramHistory(); 84 load_history(_history); 85 } 86 return _history; 87 } 88 89 -(void)saveHistory 90 { 91 save_history(_history); 92 } 93 94 -(CSunpinyinOptions*)preferences 95 { 96 if (_pref == nil) { 97 _pref = new CSunpinyinOptions(); 98 load_preferences (_pref); 99 } 100 101 return _pref; 102 } 103 104 -(void)preferencesChanged:(NSNotification *)notification 105 { 106 if (_pref) 107 load_preferences (_pref); 108 109 NSUserDefaults* pref = [NSUserDefaults standardUserDefaults]; 110 111 //setting full/half puncts and symbols 112 _inputChinesePuncts = [pref boolForKey:@"inputChinesePuncts"]; 113 _inputFullSymbols = [pref boolForKey:@"inputFullSymbols"]; 114 _switchingPolicy = (SwitchingPolicies) [pref integerForKey:@"switchingPolicy"]; 115 _usingUSKbLayout = [pref boolForKey:@"usingUSKbLayout"]; 116 117 //setting background color 118 NSData *data = [pref dataForKey:@"bgColor"]; 119 NSColor *color = data? (NSColor*) [NSUnarchiver unarchiveObjectWithData:data]: 120 [NSColor orangeColor]; 121 122 float alpha = [pref floatForKey:@"alpha"]/100.0; 123 NSColor *bgColor = [color colorWithAlphaComponent:alpha]; 124 [_ftTxtField setBackgroundColor:color]; 125 [_candiWin setBgColor:bgColor]; 126 127 data = [pref dataForKey:@"fgColor"]; 128 color = data? (NSColor*) [NSUnarchiver unarchiveObjectWithData:data]: 129 [NSColor whiteColor]; 130 [_ftTxtField setTextColor:color]; 131 [_candiWin setFgColor:color]; 132 133 data = [pref dataForKey:@"hlColor"]; 134 color = data? (NSColor*) [NSUnarchiver unarchiveObjectWithData:data]: 135 [NSColor blueColor]; 136 [_candiWin setHlColor:color]; 137 138 //setting font 139 NSString *ftname = [pref stringForKey:@"fontName"]; 140 float ftsize = [pref floatForKey:@"fontSize"]; 141 NSFont *font = [NSFont fontWithName:ftname size:ftsize]; 142 NSString* text = [NSString stringWithFormat:@"%@ %.0f",ftname,ftsize]; 143 [_ftTxtField setFont:font]; 144 [_ftTxtField setStringValue:text]; 145 [_candiWin setFont:font]; 146 } 147 148 //add an awakeFromNib item so that we can set the action method. Note that 149 //any menuItems without an action will be disabled when displayed in the Text 150 //Input Menud. 151 -(void)awakeFromNib 152 { 153 NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; 154 [center addObserver:self 155 selector:@selector(preferencesChanged:) 156 name:NSUserDefaultsDidChangeNotification 157 object:nil]; 158 159 [GrowlApplicationBridge setGrowlDelegate: self]; 160 } 161 162 //though we specified the showPrefPanel: in SunPinyinApplicationDelegate as the 163 //action receiver, the IMKInputController will actually receive the event. 164 -(IBAction)showPrefPanel:(id)sender 165 { 166 [_prefPanel makeKeyAndOrderFront:sender]; 167 } 168 169 -(IBAction)showFontPanel:(id)sender 170 { 171 NSFont *oldFont = [_candiWin font]; 172 NSFontPanel* ftDlg = [NSFontPanel sharedFontPanel]; 173 [ftDlg setDelegate:self]; 174 [ftDlg setPanelFont:oldFont isMultiple:NO]; 175 [ftDlg makeKeyAndOrderFront:sender]; 176 } 177 178 -(IBAction)checkForUpdate:(id)sender 179 { 180 SUUpdater *updater = [SUUpdater sharedUpdater]; 181 182 [updater checkForUpdates: sender]; 183 } 184 185 -(void) changeFont:(id)sender 186 { 187 NSFont *oldFont =[_candiWin font]; 188 NSFont *newFont = [sender convertFont:oldFont]; 189 190 NSUserDefaults* pref = [NSUserDefaults standardUserDefaults]; 191 NSString* ftname = [newFont familyName]; 192 float ftsize = [newFont pointSize]; 193 [pref setObject:ftname forKey:@"fontName"]; 194 [pref setFloat:ftsize forKey:@"fontSize"]; 195 } 196 197 -(void) changeAttributes:(id)sender 198 { 199 NSColor *fgColor = [_candiWin fgColor]; 200 NSDictionary *oldAttributes = [NSDictionary dictionaryWithObject:fgColor forKey:@"NSColor"]; 201 NSDictionary *newAttributes = [sender convertAttributes: oldAttributes]; 202 203 fgColor = [newAttributes objectForKey:@"NSColor"]; 204 [_ftTxtField setTextColor:fgColor]; 205 206 NSUserDefaults* pref = [NSUserDefaults standardUserDefaults]; 207 NSData *data=[NSArchiver archivedDataWithRootObject:fgColor]; 208 [pref setObject:data forKey:@"fgColor"]; 209 } 210 211 -(IBAction)toggleChinesePuncts:(id)sender 212 { 213 NSMenuItem *item = [_menu itemWithTag:0]; 214 _inputChinesePuncts = ![item state]; 215 [[NSUserDefaults standardUserDefaults] setBool:_inputChinesePuncts 216 forKey:@"inputChinesePuncts"]; 217 } 218 219 -(bool)inputChinesePuncts 220 { 221 return _inputChinesePuncts; 222 } 223 224 -(IBAction)toggleFullSymbols:(id)sender 225 { 226 NSMenuItem *item = [_menu itemWithTag:1]; 227 _inputFullSymbols = ![item state]; 228 [[NSUserDefaults standardUserDefaults] setBool:_inputFullSymbols 229 forKey:@"inputFullSymbols"]; 230 } 231 232 -(bool)inputFullSymbols 233 { 234 return _inputFullSymbols; 235 } 236 237 -(SwitchingPolicies)switchingPolicy 238 { 239 return _switchingPolicy; 240 } 241 242 -(bool)usingUSKbLayout 243 { 244 return _usingUSKbLayout; 245 } 246 247 -(void)dealloc 248 { 249 delete _data; 250 delete _history; 251 delete _pref; 252 [[NSNotificationCenter defaultCenter] removeObserver:self]; 253 [super dealloc]; 254 } 255 256 -(NSDictionary *)registrationDictionaryForGrowl 257 { 258 NSArray *notifications; 259 notifications = [NSArray arrayWithObject: @"SunPinyin"]; 260 261 NSDictionary *dict; 262 dict = [NSDictionary dictionaryWithObjectsAndKeys: 263 notifications, GROWL_NOTIFICATIONS_ALL, 264 notifications, GROWL_NOTIFICATIONS_DEFAULT, nil]; 265 266 return (dict); 267 } 268 269 -(void)messageNotify:(NSString*)msg 270 { 271 [GrowlApplicationBridge notifyWithTitle: @"SunPinyin" 272 description: msg 273 notificationName: @"SunPinyin" 274 iconData: [NSData dataWithData:[[NSImage imageNamed:@"SunPinyin"] TIFFRepresentation]] 275 priority: 0 276 isSticky: NO 277 clickContext: nil]; 278 } 279 280 @end 281 282 //this method is to return the path to history cache file. 283 static NSString* get_history_path () 284 { 285 NSString* path = [NSHomeDirectory() stringByAppendingPathComponent:@"Library/SunPinyin"]; 286 NSFileManager* fm = [NSFileManager defaultManager]; 287 if(![fm fileExistsAtPath:path]) 288 [fm createDirectoryAtPath:path attributes:nil]; 289 290 return [path stringByAppendingPathComponent:@"history"]; 291 } 292 293 static bool save_history (CICHistory* history) 294 { 295 bool suc = NO; 296 size_t sz = 0; 297 void* buf = NULL; 298 NSString* path = get_history_path (); 299 300 if (history->bufferize(&buf, &sz) && buf) { 301 FILE* fp = fopen ([path UTF8String], "w+b"); 302 if (fp) { 303 suc = (fwrite(buf, 1, sz, fp) == sz); 304 fclose(fp); 305 } 306 free(buf); 307 } 308 309 return suc; 310 } 311 312 static bool load_history (CICHistory* history) 313 { 314 bool suc = NO; 315 316 NSString* path = get_history_path (); 317 FILE* fp = fopen([path UTF8String], "rb"); 318 319 if (fp) { 320 struct stat info; 321 fstat(fileno(fp), &info); 322 void* buf = malloc(info.st_size); 323 if (buf) { 324 fread(buf, info.st_size, 1, fp); 325 suc = history->loadFromBuffer(buf, info.st_size); 326 free(buf); 327 } 328 fclose(fp); 329 } 330 331 return suc; 332 } 333 334 static bool load_preferences (CSunpinyinOptions* opts) 335 { 336 NSUserDefaults* pref = [NSUserDefaults standardUserDefaults]; 337 opts->m_ViewType = [pref integerForKey: @"inputStyle"]? 338 CIMIViewFactory::SVT_CLASSIC: 339 CIMIViewFactory::SVT_MODERN; 340 opts->m_MinusAsPageUp = [pref boolForKey:@"pagingByMinusAndEqual"]; 341 opts->m_BracketAsPageUp = [pref boolForKey:@"pagingByBrackets"]; 342 opts->m_CommaAsPageUp = [pref boolForKey:@"pagingByCommaAndDot"]; 343 opts->m_CandiWindowSize = [pref integerForKey:@"candiNumbers"]; 344 opts->m_GBK = [[pref stringForKey:@"charset"] isEqualToString:@"GBK"]; 345 346 return YES; 347 } 348 349