OSDN Git Service

b1b6813811059e43e1ccee08ea42b1126e2fafd1
[kcd/KCD.git] / KCD / HMAppDelegate.m
1 //
2 //  HMAppDelegate.m
3 //  KCD
4 //
5 //  Created by Hori,Masaki on 2013/12/31.
6 //  Copyright (c) 2013年 Hori,Masaki. All rights reserved.
7 //
8
9 #import "HMAppDelegate.h"
10
11 #import "HMUserDefaults.h"
12 #import "HMBroserWindowController.h"
13 #import "HMHistoryWindowController.h"
14 #import "HMSlotItemWindowController.h"
15 #import "HMPreferencePanelController.h"
16 #import "HMUpgradableShipsWindowController.h"
17 #import "HMScreenshotListWindowController.h"
18 #import "HMShipMasterDetailWindowController.h"
19
20 #import "HMExternalBrowserWindowController.h"
21 #import "HMBrowserContentAdjuster.h"
22
23 #import "HMFleetManager.h"
24
25 #import "HMPeriodicNotifier.h"
26 #import "HMHistoryItemCleaner.h"
27
28 #import "HMTSVSupport.h"
29
30 #import "CustomHTTPProtocol.h"
31
32
33 #ifdef DEBUG
34 #import "HMShipWindowController.h"
35 #import "HMEquipmentWindowController.h"
36 #import "HMMapWindowController.h"
37
38 #import "HMUITestWindowController.h"
39 #endif
40
41 #ifndef UI_TEST
42 #       define UI_TEST 1
43 #endif
44
45 //@interface NSObject (HMM_NSUserNotificationCenterPrivateMethods)
46 //- (void)_removeDisplayedNotification:(id)obj;
47 //@end
48
49 @interface HMAppDelegate () <NSUserNotificationCenterDelegate>
50
51 @property (strong) HMBroserWindowController *browserWindowController;
52 @property (strong) HMHistoryWindowController *historyWindowController;
53 @property (strong) HMSlotItemWindowController *slotItemWindowController;
54 @property (strong) HMPreferencePanelController *preferencePanelController;
55 @property (strong) HMUpgradableShipsWindowController *upgradableShipWindowController;
56
57 //@property (strong) HMExternalBrowserWindowController *externalBrowserWindowController;
58 @property (strong) HMBrowserContentAdjuster *browserContentAdjuster;
59
60 @property (strong) NSMutableArray *browserWindowControllers;
61
62 @property (strong) NSMutableArray *updaters;
63
64 @property (strong) HMFleetManager *fleetManager;
65
66 @property (strong) HMPeriodicNotifier *historyCleanNotifer;
67
68 #ifdef DEBUG
69 @property (strong) HMShipWindowController *shipWindowController;
70 @property (strong) HMShipMasterDetailWindowController *shipMDWindowController;
71 @property (strong) HMEquipmentWindowController *equipmentWindowController;
72 @property (strong) HMMapWindowController *mapWindowController;
73 #endif
74
75 #if UI_TEST
76 @property (strong) HMUITestWindowController *uiTestWindowController;
77 #endif
78 #if ENABLE_JSON_LOG
79 @property (strong) HMJSONViewWindowController *logedJSONViewWindowController;
80 #endif
81 @end
82
83 @implementation HMAppDelegate
84
85 @synthesize screenshotListWindowController = _screenshotListWindowController;
86
87 - (void)logLineReturn:(NSString *)format, ...
88 {
89         @synchronized (self) {
90                 va_list ap;
91                 va_start(ap, format);
92                 NSString *str = [[NSString alloc] initWithFormat:format arguments:ap];
93                 fprintf(stderr, "%s\n", [str UTF8String]);
94                 va_end(ap);
95         }
96 }
97 - (void)log:(NSString *)format, ...
98 {
99         @synchronized (self) {
100                 va_list ap;
101                 va_start(ap, format);
102                 NSString *str = [[NSString alloc] initWithFormat:format arguments:ap];
103                 fprintf(stderr, "%s", [str UTF8String]);
104                 va_end(ap);
105         }
106 }
107
108 - (instancetype)init
109 {
110         self = [super init];
111         if(self) {
112                 self.updaters = [NSMutableArray new];
113                 _fleetManager = [HMFleetManager new];
114         }
115         return self;
116 }
117
118 - (void)applicationDidFinishLaunching:(NSNotification *)aNotification
119 {
120         [CustomHTTPProtocol setupCache];
121         
122         NSUserNotificationCenter *unc = [NSUserNotificationCenter defaultUserNotificationCenter];
123         [unc setDelegate:self];
124         
125         self.browserWindowControllers = [NSMutableArray new];
126         
127         [NSTimer scheduledTimerWithTimeInterval:0.33
128                                                                          target:self
129                                                                    selector:@selector(fire:)
130                                                                    userInfo:nil
131                                                                         repeats:YES];
132 }
133
134 - (void)awakeFromNib
135 {
136         self.browserWindowController = [HMBroserWindowController new];
137         [self.browserWindowController showWindow:nil];
138         
139 #if ENABLE_JSON_LOG
140         self.jsonViewWindowController = [HMJSONViewWindowController new];
141         [self.jsonViewWindowController showWindow:nil];
142 #endif
143
144 #if UI_TEST
145         self.uiTestWindowController = [HMUITestWindowController new];
146         [self.uiTestWindowController showWindow:nil];
147 #endif
148         if(!HMStandardDefaults.showsDebugMenu) {
149                 [self.debugMenuItem setHidden:YES];
150         }
151         
152         NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
153         _historyCleanNotifer = [HMPeriodicNotifier periodicNotifierWithHour:0 minutes:7];
154         [nc addObserverForName:HMPeriodicNotification
155                                         object:_historyCleanNotifer
156                                          queue:nil
157                                 usingBlock:^(NSNotification * _Nonnull note) {
158                                         HMHistoryItemCleaner *historyItemCleaner = [HMHistoryItemCleaner new];
159                                         [historyItemCleaner cleanOldHistoryItems];
160                                 }];
161 }
162
163 - (void)addCounterUpdateBlock:(void(^)())updater
164 {
165         [self.updaters addObject:updater];
166 }
167 - (void)fire:(NSTimer *)timer
168 {
169         for(void (^updater)() in self.updaters) {
170                 updater();
171         }
172 }
173
174 - (void)clearCache
175 {
176         [CustomHTTPProtocol clearCache];
177 }
178
179 - (HMScreenshotListWindowController *)screenshotListWindowController
180 {
181         if(_screenshotListWindowController) return _screenshotListWindowController;
182         _screenshotListWindowController = [HMScreenshotListWindowController new];
183         return _screenshotListWindowController;
184 }
185
186 - (NSArray *)shipTypeCategories
187 {
188         static NSArray *categories = nil;
189         
190         if(categories) return categories;
191         
192         categories = @[
193                                    @[@(0)],     // dummy
194                                    @[@2],       // destoryer
195                                    @[@3, @4],   // leght cruiser
196                                    @[@5,@6],    // heavy crusier
197                                    @[@7, @11, @16, @18],        // aircraft carrier
198                                    @[@8, @9, @10, @12], // battle ship
199                                    @[@13, @14], // submarine
200                                    @[@1, @15, @17, @19]
201                                    ];
202         return categories;
203 }
204 - (NSPredicate *)predicateForShipType:(HMShipType)shipType
205 {
206         NSPredicate *predicate = nil;
207         NSArray *categories = [self shipTypeCategories];
208         switch (shipType) {
209                 case kHMAllType:
210                         predicate = nil;
211                         break;
212                 case kHMDestroyer:
213                 case kHMLightCruiser:
214                 case kHMHeavyCruiser:
215                 case kHMAircraftCarrier:
216                 case kHMBattleShip:
217                 case kHMSubmarine:
218                         predicate = [NSPredicate predicateWithFormat:@"master_ship.stype.id IN %@", categories[shipType]];
219                         break;
220                         
221                 case kHMOtherType:
222                 {
223                         NSMutableArray *ommitTypes = [NSMutableArray new];
224                         for(int i = kHMDestroyer; i < kHMOtherType; i++) {
225                                 [ommitTypes addObjectsFromArray:categories[i]];
226                         }
227                         predicate = [NSPredicate predicateWithFormat:@"NOT master_ship.stype.id IN %@", ommitTypes];
228                 }
229                         break;
230         }
231         
232         return predicate;
233 }
234
235 - (void)setScreenShotSaveDirectory:(NSString *)screenShotSaveDirectory
236 {
237         HMStandardDefaults.screenShotSaveDirectory = screenShotSaveDirectory;
238 }
239 - (NSString *)screenShotSaveDirectory
240 {
241         NSString *path = HMStandardDefaults.screenShotSaveDirectory;
242         if(!path) {
243                 path = [[self picturesDirectory] path];
244         }
245         
246         return path;
247 }
248 - (NSURL *)documentsFilesDirectory
249 {
250     NSFileManager *fileManager = [NSFileManager defaultManager];
251         return [[fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
252 }
253 - (NSURL *)picturesDirectory
254 {
255         NSFileManager *fileManager = [NSFileManager defaultManager];
256         return [[fileManager URLsForDirectory:NSPicturesDirectory inDomains:NSUserDomainMask] lastObject];
257 }
258 - (NSURL *)supportDirectory
259 {
260         NSFileManager *fileManager = [NSFileManager defaultManager];
261         NSURL *appSupportURL = [[fileManager URLsForDirectory:NSApplicationSupportDirectory inDomains:NSUserDomainMask] lastObject];
262         NSURL *ownAppSuportURL = [appSupportURL URLByAppendingPathComponent:@"com.masakih.KCD"];
263         return ownAppSuportURL;
264 }
265
266
267 - (NSString *)appNameForUserAgent
268 {
269         return @"Version/9.0.3 Safari/601.4.4";
270 }
271
272 - (NSFont *)monospaceSystemFont11
273 {
274         NSFont *font11 = nil;
275         if([NSFont respondsToSelector:@selector(monospacedDigitSystemFontOfSize:weight:)]) {
276                 font11 = [NSFont monospacedDigitSystemFontOfSize:11 weight:NSFontWeightRegular];
277         } else {
278                 font11 = [NSFont systemFontOfSize:11];
279         }
280         
281         return font11;
282 }
283 - (NSFont *)monospaceSystemFont12
284 {
285         NSFont *font12 = nil;
286         if([NSFont respondsToSelector:@selector(monospacedDigitSystemFontOfSize:weight:)]) {
287                 font12 = [NSFont monospacedDigitSystemFontOfSize:12 weight:NSFontWeightRegular];
288         } else {
289                 font12 = [NSFont systemFontOfSize:12];
290         }
291         
292         return font12;
293 }
294 - (NSFont *)monospaceSystemFont13
295 {
296         NSFont *font13 = nil;
297         if([NSFont respondsToSelector:@selector(monospacedDigitSystemFontOfSize:weight:)]) {
298                 font13 = [NSFont monospacedDigitSystemFontOfSize:13 weight:NSFontWeightRegular];
299         } else {
300                 font13 = [NSFont systemFontOfSize:13];
301         }
302         
303         return font13;
304 }
305
306
307 - (BOOL)validateMenuItem:(NSMenuItem *)menuItem
308 {
309         SEL action = [menuItem action];
310         if(action == @selector(showHideHistory:)) {
311                 NSWindow *window = self.historyWindowController.window;
312                 if(!window.isVisible || !window.isMainWindow) {
313                         [menuItem setTitle:NSLocalizedString(@"Show History", @"")];
314                 } else {
315                         [menuItem setTitle:NSLocalizedString(@"Hide History", @"")];
316                 }
317                 return YES;
318         } else if(action == @selector(showHideSlotItemWindow:)) {
319                 NSWindow *window = self.slotItemWindowController.window;
320                 if(!window.isVisible || !window.isMainWindow) {
321                         [menuItem setTitle:NSLocalizedString(@"Show Slot Item", @"")];
322                 } else {
323                         [menuItem setTitle:NSLocalizedString(@"Hide Slot Item", @"")];
324                 }
325                 return YES;
326         } else if(action == @selector(showHideUpgradableShipWindow:)) {
327                 NSWindow *window = self.upgradableShipWindowController.window;
328                 if(!window.isVisible || !window.isMainWindow) {
329                         [menuItem setTitle:NSLocalizedString(@"Show Upgradable Ships", @"")];
330                 } else {
331                         [menuItem setTitle:NSLocalizedString(@"Hide Upgradable Ships", @"")];
332                 }
333                 return YES;
334         } else if(action == @selector(showHideScreenshotListWindow:)) {
335                 NSWindow *window = self.screenshotListWindowController.window;
336                 if(!window.isVisible || !window.isMainWindow) {
337                         [menuItem setTitle:NSLocalizedString(@"Show Screenshot List", @"")];
338                 } else {
339                         [menuItem setTitle:NSLocalizedString(@"Hide Screenshot List", @"")];
340                 }
341                 return YES;
342         } else if(action == @selector(saveLocalData:) || action == @selector(loadLocalData:)) {
343                 return YES;
344         } else if(action == @selector(showHidePreferencePanle:)) {
345                 return YES;
346         } else if(action == @selector(openNewBrowser:) || action == @selector(selectBookmark:)) {
347                 return YES;
348         } else if(action == @selector(showWindowAduster:)) {
349                 return YES;
350         }
351 #if ENABLE_JSON_LOG
352         else if(action == @selector(saveDocument:) || action == @selector(openDocument:)) {
353                 return YES;
354         } else if(action == @selector(removeDatabaseFile:)) {
355                 return YES;
356         }
357 #endif
358 #ifdef DEBUG
359         else if(action == @selector(showShipWindow:) || action == @selector(showEquipmentWindow:)
360                         || action == @selector(showMapWindow:) || action == @selector(showOwnershipShipWindow:) ) {
361                 return YES;
362         }
363 #endif
364         return NO;
365 }
366
367 - (IBAction)showHideHistory:(id)sender
368 {
369         if(!self.historyWindowController) {
370                 self.historyWindowController = [HMHistoryWindowController new];
371         }
372         
373         NSWindow *window = self.historyWindowController.window;
374         if(!window.isVisible || !window.isMainWindow) {
375                 [window makeKeyAndOrderFront:nil];
376         } else {
377                 [window orderOut:nil];
378         }
379 }
380
381 - (IBAction)showHideSlotItemWindow:(id)sender
382 {
383         if(!self.slotItemWindowController) {
384                 self.slotItemWindowController = [HMSlotItemWindowController new];
385         }
386         
387         NSWindow *window = self.slotItemWindowController.window;
388         if(!window.isVisible || !window.isMainWindow) {
389                 [window makeKeyAndOrderFront:nil];
390         } else {
391                 [window orderOut:nil];
392         }
393 }
394
395 - (IBAction)showHidePreferencePanle:(id)sender
396 {
397         if(!self.preferencePanelController) {
398                 self.preferencePanelController = [HMPreferencePanelController new];
399         }
400         
401         NSWindow *window = self.preferencePanelController.window;
402         if(!window.isVisible || !window.isMainWindow) {
403                 [window makeKeyAndOrderFront:nil];
404         } else {
405                 [window orderOut:nil];
406         }
407 }
408
409 - (IBAction)showHideUpgradableShipWindow:(id)sender
410 {
411         if(!self.upgradableShipWindowController) {
412                 self.upgradableShipWindowController = [HMUpgradableShipsWindowController new];
413         }
414         
415         NSWindow *window = self.upgradableShipWindowController.window;
416         if(!window.isVisible || !window.isMainWindow) {
417                 [window makeKeyAndOrderFront:nil];
418         } else {
419                 [window orderOut:nil];
420         }
421 }
422
423 - (IBAction)showHideScreenshotListWindow:(id)sender
424 {
425         NSWindow *window = self.screenshotListWindowController.window;
426         if(!window.isVisible || !window.isMainWindow) {
427                 [window makeKeyAndOrderFront:nil];
428         } else {
429                 [window orderOut:nil];
430         }
431 }
432
433 - (IBAction)openNewBrowser:(id)sender
434 {
435         [self createNewBrowser];
436 }
437 - (IBAction)selectBookmark:(id)sender
438 {
439         HMExternalBrowserWindowController *browser = [self createNewBrowser];
440         
441         [browser selectBookmark:sender];
442 }
443 - (HMExternalBrowserWindowController *)createNewBrowser
444 {
445         HMExternalBrowserWindowController *browser = [HMExternalBrowserWindowController new];
446         [self.browserWindowControllers addObject:browser];
447         [browser.window makeKeyAndOrderFront:nil];
448         
449         NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
450         [nc addObserver:self
451                    selector:@selector(windowWillClose:)
452                            name:NSWindowWillCloseNotification
453                          object:browser.window];
454         
455         return browser;
456 }
457 - (IBAction)showWindowAduster:(id)sender
458 {
459         if(! self.browserContentAdjuster) {
460                 self.browserContentAdjuster = [HMBrowserContentAdjuster new];
461         }
462         [self.browserContentAdjuster showWindow:nil];
463 }
464
465 - (void)windowWillClose:(NSNotification *)notification
466 {
467         id object = [notification object];
468         if([self.browserWindowControllers containsObject:object]) {
469                 [self.browserWindowControllers removeObject:object];
470                 [[NSNotificationCenter defaultCenter] removeObserver:self
471                                                                                                                 name:NSWindowWillCloseNotification
472                                                                                                           object:object];
473                 [self.browserWindowControllers removeObject:object];
474         }
475 }
476
477 - (IBAction)removeDatabaseFile:(id)sender
478 {
479         NSBundle *mainBundle = [NSBundle mainBundle];
480         NSString *appleScriptPath = [mainBundle pathForResource:@"RemoveDatabaseFileAndRestart"
481                                                                                                          ofType:@"app"];
482         NSTask *task = [NSTask new];
483         task.launchPath = @"/usr/bin/open";
484         task.arguments = @[appleScriptPath];
485         [task launch];
486 }
487
488 #ifdef DEBUG
489
490 - (IBAction)showShipWindow:(id)sender
491 {
492         if(!_shipWindowController) {
493                 self.shipWindowController = [HMShipWindowController new];
494         }
495         [self.shipWindowController showWindow:nil];
496 }
497 - (IBAction)showEquipmentWindow:(id)sender
498 {
499         if(!_equipmentWindowController) {
500                 self.equipmentWindowController = [HMEquipmentWindowController new];
501         }
502         [self.equipmentWindowController showWindow:nil];
503 }
504 - (IBAction)showMapWindow:(id)sender
505 {
506         if(!_mapWindowController) {
507                 self.mapWindowController = [HMMapWindowController new];
508         }
509         [self.mapWindowController showWindow:nil];
510 }
511 - (IBAction)showOwnershipShipWindow:(id)sender
512 {
513         if(!_shipMDWindowController) {
514                 self.shipMDWindowController = [HMShipMasterDetailWindowController new];
515         }
516         [self.shipMDWindowController showWindow:nil];
517 }
518 #endif
519
520 #pragma mark - NSApplicationDelegate
521 - (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender
522 {
523         return YES;
524 }
525
526 #pragma mark - NSUserNotificationCenterDelegate
527 //- (void)removeUserNotification:(NSDictionary *)dict
528 //{
529 //      NSUserNotificationCenter *center = [dict objectForKey:@"center"];
530 //      NSUserNotification *notification = [dict objectForKey:@"notification"];
531 //      [center removeDeliveredNotification:notification];
532 //      //      [center _removeDisplayedNotification:notification];
533 //}
534
535 - (BOOL)userNotificationCenter:(NSUserNotificationCenter *)center shouldPresentNotification:(NSUserNotification *)notification
536 {
537         return YES;
538 }
539
540 //- (void)userNotificationCenter:(NSUserNotificationCenter *)center didDeliverNotification:(NSUserNotification *)notification
541 //{
542 //      [self performSelector:@selector(removeUserNotification:)
543 //                         withObject:@{@"center":center, @"notification":notification}
544 //                         afterDelay:3];
545 //}
546 //- (void)userNotificationCenter:(NSUserNotificationCenter *)center didActivateNotification:(NSUserNotification *)notification
547 //{
548 //      [center removeDeliveredNotification:notification];
549 //}
550 #if ENABLE_JSON_LOG
551 - (IBAction)saveDocument:(id)sender
552 {
553         NSSavePanel *panel = [NSSavePanel savePanel];
554         [panel setAllowedFileTypes:@[@"plist"]];
555         [panel setPrompt:@"Save log"];
556         [panel setTitle:@"Save log"];
557         [panel beginWithCompletionHandler:^(NSInteger result) {
558                 if(result == NSModalResponseOK) {
559                         NSArray *array = [self.jsonViewWindowController.commands copy];
560                         NSData *data = [NSKeyedArchiver archivedDataWithRootObject:array];
561                         if(!data) {
562                                 NSLog(@"can not convert log.");
563                                 return;
564                         }
565                         NSError *error = nil;
566                         [data writeToURL:panel.URL
567                                          options:NSDataWritingAtomic
568                                            error:&error];
569                         if(error) {
570                                 NSLog(@"can not save property list.: %@", error);
571                         }
572                 }
573         }];
574 }
575
576 - (IBAction)openDocument:(id)sender
577 {
578         NSOpenPanel *panel = [NSOpenPanel openPanel];
579         [panel setAllowedFileTypes:@[@"plist"]];
580         [panel setAllowsMultipleSelection:NO];
581         [panel setPrompt:@"Open log"];
582         [panel setTitle:@"Open log"];
583         [panel beginWithCompletionHandler:^(NSInteger result) {
584                 if(result == NSModalResponseOK) {
585                         NSData *data = [NSData dataWithContentsOfURL:panel.URL];
586                         id array = [NSKeyedUnarchiver unarchiveObjectWithData:data];
587                         if(!array || ![array isKindOfClass:[NSArray class]]) {
588                                 NSLog(@"Can not convert data to log.");
589                                 return;
590                         }
591                         
592                         self.logedJSONViewWindowController = [HMJSONViewWindowController new];
593                         [self.logedJSONViewWindowController setCommandArray:array];
594                         [[self.logedJSONViewWindowController window] setTitle:@"SAVED LOG FILE VIEWER"];
595                         
596                         [self.logedJSONViewWindowController showWindow:nil];
597                 }
598         }];
599 }
600 #endif
601
602 - (IBAction)saveLocalData:(id)sender
603 {
604         [[HMTSVSupport new] save:sender];
605 }
606 - (IBAction)loadLocalData:(id)sender
607 {
608         [[HMTSVSupport new] load:sender];
609 }
610
611 @end