OSDN Git Service

88e7894b9934ce6458a7b7197d0a9dd63a6a3f37
[kcd/KCD.git] / KCD / AppDelegate.swift
1 //
2 //  AppDelegate.swift
3 //  KCD
4 //
5 //  Created by Hori,Masaki on 2017/02/03.
6 //  Copyright © 2017年 Hori,Masaki. All rights reserved.
7 //
8
9 import Cocoa
10
11 fileprivate extension Selector {
12     static let fireInAppDelegate = #selector(AppDelegate.fire(_:))
13     
14     static let showHideHistory = #selector(AppDelegate.showHideHistory(_:))
15     static let showHideSlotItemWindow = #selector(AppDelegate.showHideSlotItemWindow(_:))
16     static let showHideUpgradableShipWindow = #selector(AppDelegate.showHideUpgradableShipWindow(_:))
17     static let showHideScreenshotListWindow = #selector(AppDelegate.showHideScreenshotListWindow(_:))
18     static let showHideAirBaseInfoWindow = #selector(AppDelegate.showHideAirBaseInfoWindow(_:))
19     static let saveLocalData = #selector(AppDelegate.saveLocalData(_:))
20     static let loadLocalData = #selector(AppDelegate.loadLocalData(_:))
21     static let showHidePreferencePanle = #selector(AppDelegate.showHidePreferencePanle(_:))
22     static let openNewBrowser = #selector(AppDelegate.openNewBrowser(_:))
23     static let selectBookmark = #selector(AppDelegate.selectBookmark(_:))
24     static let showWindowAduster = #selector(AppDelegate.showWindowAduster(_:))
25     
26     static let saveDocument = #selector(AppDelegate.saveDocument(_:))
27     static let openDocument = #selector(AppDelegate.openDocument(_:))
28     static let removeDatabaseFile = #selector(AppDelegate.removeDatabaseFile(_:))
29     static let showShipWindow = #selector(AppDelegate.showShipWindow(_:))
30     static let showEquipmentWindow = #selector(AppDelegate.showEquipmentWindow(_:))
31     static let showMapWindow = #selector(AppDelegate.showMapWindow(_:))
32     static let showOwnershipShipWindow = #selector(AppDelegate.showOwnershipShipWindow(_:))
33 }
34
35 @NSApplicationMain
36 class AppDelegate: NSObject {
37     let appNameForUserAgent: String = "Version/9.1.2 Safari/601.7.7"
38     let fleetManager: FleetManager = FleetManager()
39     
40     private let historyCleanNotifer = PeriodicNotifier(hour: 0, minutes: 7)
41     private let jsonTracker = JSONTracker()
42     private let timeSignalNotifier = TimeSignalNotifier()
43     private let resourceHistory = ResourceHistoryManager()
44     
45     fileprivate let browserWindowController = BroserWindowController()
46     
47     #if ENABLE_JSON_LOG
48     let jsonViewWindowController: JSONViewWindowController? = {
49         let vc = JSONViewWindowController()
50         vc.showWindow(nil)
51         return vc
52     }()
53     #else
54     private let jsonViewWindowController: JSONViewWindowController? = nil
55     #endif
56     
57     #if UI_TEST
58     private let uiTestWindowController: UITestWindowController? = {
59         let vc = UITestWindowController()
60         vc.showWindow(nil)
61         return vc
62     }()
63     #else
64     private let uiTestWindowController: UITestWindowController? = nil
65     #endif
66     
67     
68     // MARK: - Variable
69     @IBOutlet var debugMenuItem: NSMenuItem!
70     @IBOutlet var billingWindowMenuItem: NSMenuItem!
71     
72     private lazy var historyWindowController: HistoryWindowController = { HistoryWindowController() }()
73     private lazy var slotItemWindowController: SlotItemWindowController = { SlotItemWindowController() }()
74     private lazy var preferencePanelController: PreferencePanelController = { PreferencePanelController() }()
75     private lazy var upgradableShipWindowController: UpgradableShipsWindowController = { UpgradableShipsWindowController() }()
76     private lazy var airBaseWindowController: AirBaseWindowController = { AirBaseWindowController() }()
77     private lazy var browserContentAdjuster: BrowserContentAdjuster = { BrowserContentAdjuster() }()
78     private(set) lazy var screenshotListWindowController: ScreenshotListWindowController = {
79         let wc = ScreenshotListWindowController()
80         let _ = wc.window
81         return wc
82     }()
83     
84     private lazy var shipWindowController: ShipWindowController = { ShipWindowController() }()
85     private lazy var shipMDWindowController: ShipMasterDetailWindowController = { ShipMasterDetailWindowController() } ()
86     private lazy var equipmentWindowController: EquipmentWindowController = { EquipmentWindowController() }()
87     private lazy var mapWindowController: MapWindowController = { MapWindowController() }()
88     
89     private var browserWindowControllers: [ExternalBrowserWindowController] = []
90     private var updaters: [() -> Void] = []
91     private var logedJSONViewWindowController: JSONViewWindowController?
92     private var isLoadedMainMenu = false
93     
94     var screenShotSaveDirectory: String {
95         get {
96             return UserDefaults.standard.screenShotSaveDirectory ?? ApplicationDirecrories.pictures.path
97         }
98         set {
99             UserDefaults.standard.screenShotSaveDirectory = newValue
100         }
101     }
102     var screenShotSaveDirectoryURL: URL {
103         return URL(fileURLWithPath: screenShotSaveDirectory)
104     }
105     dynamic var monospaceSystemFont11: NSFont {
106         return NSFont.monospacedDigitSystemFont(ofSize: 11, weight: NSFontWeightRegular)
107     }
108     dynamic var monospaceSystemFont12: NSFont {
109         return NSFont.monospacedDigitSystemFont(ofSize: 12, weight: NSFontWeightRegular)
110     }
111     dynamic var monospaceSystemFont13: NSFont {
112         return NSFont.monospacedDigitSystemFont(ofSize: 13, weight: NSFontWeightRegular)
113     }
114     
115     // MARK: - Function
116     override func awakeFromNib() {
117         if isLoadedMainMenu { return }
118         isLoadedMainMenu = true
119         
120         ValueTransformerRegister.registerAll()
121         UserDefaults.registerAllDefaults()
122         CustomHTTPProtocol.start()
123         CommandRegister.register()
124         
125         let _ = BookmarkManager.shared()
126         let _ = screenshotListWindowController
127         browserWindowController.showWindow(nil)
128         if !UserDefaults.standard.showsDebugMenu { debugMenuItem.isHidden = true }
129         NotificationCenter.default
130         .addObserver(forName: .Periodic, object: historyCleanNotifer, queue: nil) { _ in
131             HistoryItemCleaner().cleanOldHistoryItems()
132         }
133     }
134     
135     func addCounterUpdate(_ updater: @escaping () -> Void) {
136         updaters.append(updater)
137     }
138     func clearCache() {
139         CustomHTTPProtocol.clearCache()
140     }
141     func createNewBrowser() -> ExternalBrowserWindowController {
142         let browser = ExternalBrowserWindowController()
143         browserWindowControllers.append(browser)
144         browser.window?.makeKeyAndOrderFront(nil)
145         var token: NSObjectProtocol! = nil
146         token = NotificationCenter.default
147             .addObserver(forName: .NSWindowWillClose, object: browser.window, queue: nil) { [unowned self] notification in
148                 NotificationCenter.default.removeObserver(token)
149                 if let obj = notification.object as? NSWindow,
150                     let index = self.browserWindowControllers.index(where: { $0.window == obj })
151                 { self.browserWindowControllers.remove(at: index) }
152         }
153         return browser
154     }
155     
156     func fire(_ timer: Timer) {
157         updaters.forEach { $0() }
158     }
159     
160     // MARK: - IBActions
161     private func isFrontMostWindow(_ window: NSWindow) -> Bool {
162         return window.isVisible && window.isMainWindow
163     }
164     private func makeFrontOrOrderOut(_ window: NSWindow?) {
165         guard let window = window else { return }
166         isFrontMostWindow(window) ? window.orderOut(nil) : window.makeKeyAndOrderFront(nil)
167     }
168     @IBAction func showHideHistory(_ sender: AnyObject?) {
169         makeFrontOrOrderOut(historyWindowController.window)
170     }
171     @IBAction func showHideSlotItemWindow(_ sender: AnyObject?) {
172         makeFrontOrOrderOut(slotItemWindowController.window)
173     }
174     @IBAction func showHideUpgradableShipWindow(_ sender: AnyObject?) {
175         makeFrontOrOrderOut(upgradableShipWindowController.window)
176     }
177     @IBAction func showHideScreenshotListWindow(_ sender: AnyObject?) {
178         makeFrontOrOrderOut(screenshotListWindowController.window)
179     }
180     @IBAction func showHideAirBaseInfoWindow(_ sender: AnyObject?) {
181         makeFrontOrOrderOut(airBaseWindowController.window)
182     }
183     @IBAction func showHidePreferencePanle(_ sender: AnyObject?) {
184         makeFrontOrOrderOut(preferencePanelController.window)
185     }
186     @IBAction func showWindowAduster(_ sender: AnyObject?) {
187         browserContentAdjuster.showWindow(nil)
188     }
189     @IBAction func openNewBrowser(_ sender: AnyObject?) {
190         let _ = createNewBrowser()
191     }
192     @IBAction func selectBookmark(_ sender: AnyObject?) {
193         let b = createNewBrowser()
194         b.selectBookmark(sender)
195     }
196     @IBAction func removeDatabaseFile(_ sender: AnyObject?) {
197         guard let path = Bundle.main.path(forResource: "RemoveDatabaseFileAndRestart", ofType: "app")
198             else { return print("Can not find RemoveDatabaseFileAndRestart.app") }
199         let process = Process()
200         process.launchPath = "/usr/bin/open"
201         process.arguments = [path]
202         process.launch()
203     }
204     @IBAction func showMainBrowser(_ sender: AnyObject?) {
205         browserWindowController.showWindow(nil)
206     }
207     
208     @IBAction func showShipWindow(_ sender: AnyObject?) {
209         shipWindowController.showWindow(nil)
210     }
211     @IBAction func showEquipmentWindow(_ sender: AnyObject?) {
212         equipmentWindowController.showWindow(nil)
213     }
214     @IBAction func showMapWindow(_ sender: AnyObject?) {
215         mapWindowController.showWindow(nil)
216     }
217     @IBAction func showOwnershipShipWindow(_ sender: AnyObject?) {
218         shipMDWindowController.showWindow(nil)
219     }
220     
221     @IBAction func saveLocalData(_ sender: AnyObject?) {
222         TSVSupport().save()
223     }
224     @IBAction func loadLocalData(_ sender: AnyObject?) {
225         TSVSupport().load()
226     }
227     
228     @IBAction func saveDocument(_ sender: AnyObject?) {
229         let panel = NSSavePanel()
230         panel.allowedFileTypes = ["plist"]
231         panel.prompt = "Save Panel"
232         panel.title = "Save Panel"
233         panel.begin {
234             guard $0 == NSModalResponseOK,
235                 let url = panel.url,
236                 let array = self.jsonViewWindowController?.commands
237                 else { return }
238             let data = NSKeyedArchiver.archivedData(withRootObject: array)
239             do { try data.write(to: url) }
240             catch { print("Can not write to \(url)") }
241         }
242     }
243     @IBAction func openDocument(_ sender: AnyObject?) {
244         let panel = NSOpenPanel()
245         panel.allowedFileTypes = ["plist"]
246         panel.allowsMultipleSelection = false
247         panel.prompt = "Open log"
248         panel.title = "Open log"
249         panel.begin {
250             guard $0 == NSModalResponseOK,
251             let url = panel.url
252             else { return }
253             do {
254                 let data = try Data(contentsOf: url)
255                 let array = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data as NSData)
256                 
257                 self.logedJSONViewWindowController = JSONViewWindowController()
258                 self.logedJSONViewWindowController?.commands = array as! NSMutableArray
259                 self.logedJSONViewWindowController?.window?.title = "SAVED LOG FILE VIEWER"
260                 self.logedJSONViewWindowController?.showWindow(nil)
261             }
262             catch { print("Can not load \(url)") }
263         }
264     }
265     
266     private func setTitle(_ menuItem: NSMenuItem,
267                           _ window: NSWindow?,
268                           _ showLabel: String,
269                           _ hideLabel: String) {
270         guard let window = window else { return }
271         if isFrontMostWindow(window) {
272             menuItem.title = hideLabel
273         } else {
274             menuItem.title = showLabel
275         }
276     }
277     override func validateMenuItem(_ menuItem: NSMenuItem) -> Bool {
278         guard let action = menuItem.action else { return false }
279         switch action {
280         case Selector.showHideHistory:
281             setTitle(menuItem,
282                      historyWindowController.window,
283                      NSLocalizedString("Show History", comment: "Show History"),
284                      NSLocalizedString("Hide History", comment: "Hide History"))
285             return true
286         case Selector.showHideSlotItemWindow:
287             setTitle(menuItem,
288                      slotItemWindowController.window,
289                      NSLocalizedString("Show Slot Item", comment: "Show Slot Item"),
290                      NSLocalizedString("Hide Slot Item", comment: "Hide Slot Item"))
291             return true
292         case Selector.showHideUpgradableShipWindow:
293             setTitle(menuItem,
294                      upgradableShipWindowController.window,
295                      NSLocalizedString("Show Upgradable Ships", comment: "Show Upgradable Ships"),
296                      NSLocalizedString("Hide Upgradable Ships", comment: "Hide Upgradable Ships"))
297             return true
298         case Selector.showHideScreenshotListWindow:
299             setTitle(menuItem,
300                      screenshotListWindowController.window,
301                      NSLocalizedString("Show Screenshot List", comment: "Show Screenshot List"),
302                      NSLocalizedString("Hide Screenshot List", comment: "Hide Screenshot List"))
303             return true
304         case Selector.showHideAirBaseInfoWindow:
305             setTitle(menuItem,
306                      airBaseWindowController.window,
307                      NSLocalizedString("Show Air Base Info", comment: "Show Air Base Info"),
308                      NSLocalizedString("Hide Air Base Info", comment: "Hide Air Base Info"))
309             return true
310         case Selector.saveLocalData, Selector.loadLocalData:
311             return true
312         case Selector.showHidePreferencePanle:
313             return true
314         case Selector.openNewBrowser:
315             return true
316         case Selector.selectBookmark:
317             return true
318         case Selector.showWindowAduster:
319             return true
320         case Selector.saveDocument, Selector.openDocument:
321             return jsonViewWindowController != nil
322         case Selector.removeDatabaseFile:
323             return true
324         case Selector.showShipWindow, Selector.showEquipmentWindow,
325              Selector.showMapWindow, Selector.showOwnershipShipWindow:
326             return true
327         default:
328             return false
329         }
330     }
331 }
332
333 extension AppDelegate: NSApplicationDelegate {
334     func applicationWillFinishLaunching(_ notification: Notification) {
335         NSUserNotificationCenter.default.delegate = self
336         Timer.scheduledTimer(timeInterval: 0.33,
337                              target: self,
338                              selector: .fireInAppDelegate,
339                              userInfo: nil,
340                              repeats: true)
341     }
342     func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
343         return true
344     }
345 }
346
347 extension AppDelegate: NSUserNotificationCenterDelegate {
348     func userNotificationCenter(_ center: NSUserNotificationCenter, shouldPresent notification: NSUserNotification) -> Bool {
349         return true
350     }
351 }
352
353 @available(OSX 10.12.2, *)
354 fileprivate var objectForTouchBar:[Int: NSTouchBar] = [:]
355
356 @available(OSX 10.12.2, *)
357 extension AppDelegate: NSTouchBarProvider {
358     @IBOutlet var mainTouchBar: NSTouchBar? {
359         get {
360             return objectForTouchBar[hash]
361         }
362         set {
363             objectForTouchBar[hash] = newValue
364         }
365     }
366     
367     var touchBar: NSTouchBar? {
368         get {
369             let mainWindow = NSApplication.shared().mainWindow
370             if mainWindow == self.browserWindowController.window { return nil }
371             if let _ = mainTouchBar {
372                 return mainTouchBar
373             }
374             var topLevel: NSArray = []
375             Bundle.main.loadNibNamed("MainTouchBar",
376                                      owner: self,
377                                      topLevelObjects: &topLevel)
378             return mainTouchBar
379         }
380         set {}
381     }
382 }