/* PopupController.m - app controller class for Popup.app Copyright (C) 2003, 2004 Bjorn Gohla, Rob Burns 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 (at your option) 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., 675 Mass Ave, Cambridge, MA 02111, USA. */ #include "PopupController.h" #include "CStackDocument.h" #include "EditorWindowController.h" #include "QuizController.h" #include "SpellingQuizController.h" #include "PreferencesController.h" #include "CardInspectorController.h" #include "Constants.h" @implementation PopupController // *************** // Private methods // *************** #ifndef __APPLE__ NSStringEncoding enc[] = {NSASCIIStringEncoding, NSUnicodeStringEncoding, NSUTF8StringEncoding, NSISOLatin1StringEncoding, NSISOLatin2StringEncoding, NSWindowsCP1251StringEncoding, NSWindowsCP1252StringEncoding, NSWindowsCP1253StringEncoding, NSWindowsCP1254StringEncoding, NSWindowsCP1250StringEncoding, NSISO2022JPStringEncoding, NSMacOSRomanStringEncoding, NSKOI8RStringEncoding, NSISOLatin3StringEncoding, NSISOLatin4StringEncoding, NSISOCyrillicStringEncoding, NSISOArabicStringEncoding, NSISOGreekStringEncoding, NSISOHebrewStringEncoding, NSISOLatin5StringEncoding, NSISOLatin6StringEncoding, NSISOThaiStringEncoding, NSISOLatin7StringEncoding, NSISOLatin8StringEncoding, NSISOLatin9StringEncoding, NSGB2312StringEncoding, NSUTF7StringEncoding, NSBIG5StringEncoding, NSJapaneseEUCStringEncoding, NSKoreanEUCStringEncoding, 0}; #else NSStringEncoding enc[] = {NSUTF8StringEncoding, NSUnicodeStringEncoding, NSISOLatin1StringEncoding, NSISOLatin2StringEncoding, NSASCIIStringEncoding, NSWindowsCP1251StringEncoding, NSWindowsCP1252StringEncoding, NSWindowsCP1253StringEncoding, NSWindowsCP1254StringEncoding, NSWindowsCP1250StringEncoding, NSISO2022JPStringEncoding, NSMacOSRomanStringEncoding, 0x80000a02 /*KOI8_R*/, 0x80000203 /*ISOLatin3*/, 0x80000204 /* ISOLatin4 */, 0x80000205 /*ISOLatinCyrillic*/, 0x80000206 /*ISOLatinArabic*/, 0x80000207 /*ISOLatinGreek*/, 0x80000208 /*ISOLatinHebrew*/, 0x80000209 /*ISOLatin5*/, 0x8000020a /*ISOLatin6*/, 0x8000020b /*ISOLatinThai*/, 0x8000020d /*ISOLatin7*/, 0x8000020e /*ISOLatin8*/, 0x8000020f /*ISOLatin9*/, 0x80000630 /*GS2312*/, 0x80000a03 /*BIG5*/, NSJapaneseEUCStringEncoding, 0x80000940 /*EUC_KR*/, 0}; #endif - (NSString *) _stringForData: (NSData *)data { NSPopUpButton *but = [importAcc viewWithTag: 1]; NSString *str; int i; if( [but indexOfSelectedItem] > 0 ) return AUTORELEASE([[NSString alloc] initWithData: data encoding:[[[but selectedItem] representedObject] intValue]]); else for( i=0; enc[i]!=0; i++ ) if( (str = AUTORELEASE([[NSString alloc] initWithData: data encoding: enc[i]])) != nil ) {NSLog([NSString localizedNameOfStringEncoding: enc[i]]); return str;} return 0; } - (NSArray *) _parseForImport: (NSString *)string { NSScanner *scanner = [NSScanner scannerWithString: string]; NSCharacterSet *cSet = [NSCharacterSet characterSetWithCharactersInString: @"\t\n\r"]; NSString *tempS = [NSString string]; NSMutableArray *cards = [NSMutableArray arrayWithCapacity: 1]; NSMutableDictionary *tempD = [NSMutableDictionary dictionaryWithCapacity: 1]; [scanner setScanLocation: 0]; [scanner setCharactersToBeSkipped: cSet]; while( ![scanner isAtEnd] ) { [scanner scanUpToString: @"\n" intoString: &tempS]; tempD = [NSMutableDictionary dictionaryWithObject: tempS forKey: @"Front"]; [scanner setScanLocation: [scanner scanLocation]+1]; [scanner scanUpToString: @"\n" intoString: &tempS]; [tempD setObject: tempS forKey: @"Back"]; [cards addObject: tempD]; [scanner setScanLocation: [scanner scanLocation]+1]; } return cards; } // ************** // Public methods // ************** + (void) initialize { NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; NSDictionary *appDefaults = [NSDictionary dictionaryWithObjectsAndKeys: @"YES", @"Sound", nil]; [defaults registerDefaults:appDefaults]; } - (void) awakeFromNib { importAcc = RETAIN([importAcc contentView]); if([[[NSUserDefaults standardUserDefaults] objectForKey: @"Sound"] isEqualToString: @"YES"]) { [[[[[NSApp mainMenu] itemWithTag: 5] submenu] itemWithTag: 55] setTitle: _(@"Turn Sound Off")]; } else { [[[[[NSApp mainMenu] itemWithTag: 5] submenu] itemWithTag: 55] setTitle: _(@"Turn Sound On")]; } [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(editStack:) name: @"EditStackNotification" object: nil]; showingInspector = NO; } - (NSView *) importAccessoryView { NSPopUpButton *but = [importAcc viewWithTag: 1]; int i; [but removeAllItems]; [but addItemWithTitle: _(@"Automatic")]; [[but itemAtIndex: 0] setRepresentedObject: [NSNumber numberWithInt: -3]]; for( i=0; enc[i]!=0; i++ ) { [but addItemWithTitle: [NSString localizedNameOfStringEncoding: enc[i]]]; [[but itemAtIndex: i+1] setRepresentedObject: [NSNumber numberWithInt: enc[i]]]; } return importAcc; } - (void) showPrefs: (id)sender { PreferencesController *prefs; prefs = [PreferencesController sharedPreferences]; [[prefs window] makeKeyAndOrderFront: self]; } - (void) showInspector: (id)sender { CardInspectorController *inspector; if( [[[[NSApp keyWindow] windowController] className] isEqual: @"EditorWindowController"] ) { [[[NSApp keyWindow] windowController] showInspector: self]; } else { inspector = [CardInspectorController sharedInspector]; [[inspector window] makeKeyAndOrderFront: self]; } } - (void) showHelp: (id)sender { #ifdef GNUSTEP NSBundle *mb = [NSBundle mainBundle]; NSString *file = [mb pathForResource: @"Popup" ofType: @"help"]; if (file) { [[NSWorkspace sharedWorkspace] openFile: file]; return; } NSBeep(); #endif } // the senders tag determines what type of quiz // to begin. The tags have this relationship: // // flashcard quiz - 51 // multiple choice quiz - 52 // spelling quiz - 53 - (void) startQuiz: (id) sender { CStackDocument *cur = [[NSDocumentController sharedDocumentController] currentDocument]; if( [[[[NSApp keyWindow] windowController] className] isEqual: @"EditorWindowController"]) { switch( [sender tag] ) { case 51: [cur startCardQuizWithMethod: SHOWONCE_QUIZ_METHOD]; break; case 52: [cur startChoiceQuizWithMethod: SHOWONCE_QUIZ_METHOD]; break; case 53: [cur startSpellingQuizWithMethod: SHOWONCE_QUIZ_METHOD]; break; default: [cur startDefaultQuizWithMethod: SHOWONCE_QUIZ_METHOD]; break; } } } - (void) startPractice: (id) sender { CStackDocument *cur = [[NSDocumentController sharedDocumentController] currentDocument]; if( [[[[NSApp keyWindow] windowController] className] isEqual: @"EditorWindowController"]) { switch( [sender tag] ) { case 51: [cur startCardQuizWithMethod: REPETITION_QUIZ_METHOD]; break; case 52: [cur startChoiceQuizWithMethod: REPETITION_QUIZ_METHOD]; break; case 53: [cur startSpellingQuizWithMethod: REPETITION_QUIZ_METHOD]; break; default: [cur startDefaultQuizWithMethod: REPETITION_QUIZ_METHOD]; break; } } } - (void) editStack: (NSNotification *) notification { [[[NSDocumentController sharedDocumentController] currentDocument] editStack]; } - (void) setSound: (id) sender { if([[sender title] isEqualToString: _(@"Turn Sound Off")]) { [[NSUserDefaults standardUserDefaults] setObject: @"NO" forKey: @"Sound"]; [sender setTitle: _(@"Turn Sound On")]; } else if([[sender title] isEqualToString: _(@"Turn Sound On")]) { [[NSUserDefaults standardUserDefaults] setObject: @"YES" forKey: @"Sound"]; [sender setTitle: _(@"Turn Sound Off")]; } } - (void) importFile: (id)sender { NSOpenPanel *oPanel = [NSOpenPanel openPanel]; NSDocumentController *dc = [NSDocumentController sharedDocumentController]; NSString *stringData; NSData *data; NSArray *cards; NSString *name; int i=0; [oPanel setAllowsMultipleSelection: YES]; [oPanel setCanChooseDirectories: NO]; [oPanel setCanChooseFiles: YES]; [oPanel setTitle: _(@"Import")]; [oPanel setPrompt: _(@"Import")]; [oPanel setAccessoryView: [self importAccessoryView]]; if( [oPanel runModalForTypes: nil] == NSOKButton ) { for( i=0; i<[[oPanel filenames] count]; i++ ) { data = [NSData dataWithContentsOfFile: [[oPanel filenames] objectAtIndex: i]]; stringData = [self _stringForData: data]; if( stringData != nil ) { NS_DURING cards = [self _parseForImport: stringData]; NS_HANDLER NSRunAlertPanel(_(@"Parse Error"), _(@"An error occured while trying to parse %@\n\n%@"), @"OK", nil, nil, [[[oPanel filenames] objectAtIndex: i] lastPathComponent], localException); continue; NS_ENDHANDLER if( cards != nil ) { [dc newDocument: self]; [[dc currentDocument] insertImportedCards: cards]; } } else { name = [[oPanel filename] lastPathComponent]; NSRunInformationalAlertPanel(_(@"Import Error"), [NSString stringWithFormat: _(@"An error occured while trying to import %@"), name], nil,nil,@"OK"); } } } } // ********************** // NSApp delegate methods // ********************** - (BOOL) validateMenuItem: (id )menuitem { if( [menuitem tag] >= 51 && [menuitem tag] <=54 ) { if( [[[[NSApp keyWindow] windowController] className] isEqualToString: @"EditorWindowController"] ) { return [(EditorWindowController*)[[NSApp keyWindow] windowController] validateMenuItem: menuitem]; } else return NO; } return YES; } @end