OSDN Git Service

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