OSDN Git Service

swiftlint 'line_length'の警告を修正
[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     private lazy var historyWindowController: HistoryWindowController = {
76         HistoryWindowController()
77     }()
78     private lazy var slotItemWindowController: SlotItemWindowController = {
79         SlotItemWindowController()
80     }()
81     private lazy var preferencePanelController: PreferencePanelController = {
82         PreferencePanelController()
83     }()
84     private lazy var upgradableShipWindowController: UpgradableShipsWindowController = {
85         UpgradableShipsWindowController()
86     }()
87     private lazy var airBaseWindowController: AirBaseWindowController = {
88         AirBaseWindowController()
89     }()
90     private lazy var browserContentAdjuster: BrowserContentAdjuster = {
91         BrowserContentAdjuster()
92     }()
93     private(set) lazy var screenshotListWindowController: ScreenshotListWindowController = {
94         let wc = ScreenshotListWindowController()
95         let _ = wc.window
96         return wc
97     }()
98     
99     private lazy var shipWindowController: ShipWindowController = {
100         ShipWindowController()
101     }()
102     private lazy var shipMDWindowController: ShipMasterDetailWindowController = {
103         ShipMasterDetailWindowController()
104     } ()
105     private lazy var equipmentWindowController: EquipmentWindowController = {
106         EquipmentWindowController()
107     }()
108     private lazy var mapWindowController: MapWindowController = {
109         MapWindowController()
110     }()
111     
112     private var browserWindowControllers: [ExternalBrowserWindowController] = []
113     private var updaters: [() -> Void] = []
114     private 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         return browser
179     }
180     
181     func fire(_ timer: Timer) {
182         updaters.forEach { $0() }
183     }
184     
185     // MARK: - IBActions
186     private func isFrontMostWindow(_ window: NSWindow) -> Bool {
187         return window.isVisible && window.isMainWindow
188     }
189     private func makeFrontOrOrderOut(_ window: NSWindow?) {
190         guard let window = window else { return }
191         isFrontMostWindow(window) ? window.orderOut(nil) : window.makeKeyAndOrderFront(nil)
192     }
193     @IBAction func showHideHistory(_ sender: AnyObject?) {
194         makeFrontOrOrderOut(historyWindowController.window)
195     }
196     @IBAction func showHideSlotItemWindow(_ sender: AnyObject?) {
197         makeFrontOrOrderOut(slotItemWindowController.window)
198     }
199     @IBAction func showHideUpgradableShipWindow(_ sender: AnyObject?) {
200         makeFrontOrOrderOut(upgradableShipWindowController.window)
201     }
202     @IBAction func showHideScreenshotListWindow(_ sender: AnyObject?) {
203         makeFrontOrOrderOut(screenshotListWindowController.window)
204     }
205     @IBAction func showHideAirBaseInfoWindow(_ sender: AnyObject?) {
206         makeFrontOrOrderOut(airBaseWindowController.window)
207     }
208     @IBAction func showHidePreferencePanle(_ sender: AnyObject?) {
209         makeFrontOrOrderOut(preferencePanelController.window)
210     }
211     @IBAction func showWindowAduster(_ sender: AnyObject?) {
212         browserContentAdjuster.showWindow(nil)
213     }
214     @IBAction func openNewBrowser(_ sender: AnyObject?) {
215         let _ = createNewBrowser()
216     }
217     @IBAction func selectBookmark(_ sender: AnyObject?) {
218         let b = createNewBrowser()
219         b.selectBookmark(sender)
220     }
221     @IBAction func removeDatabaseFile(_ sender: AnyObject?) {
222         guard let path = Bundle.main.path(forResource: "RemoveDatabaseFileAndRestart", ofType: "app")
223             else { return print("Can not find RemoveDatabaseFileAndRestart.app") }
224         let process = Process()
225         process.launchPath = "/usr/bin/open"
226         process.arguments = [path]
227         process.launch()
228     }
229     @IBAction func showMainBrowser(_ sender: AnyObject?) {
230         browserWindowController.showWindow(nil)
231     }
232     
233     @IBAction func showShipWindow(_ sender: AnyObject?) {
234         shipWindowController.showWindow(nil)
235     }
236     @IBAction func showEquipmentWindow(_ sender: AnyObject?) {
237         equipmentWindowController.showWindow(nil)
238     }
239     @IBAction func showMapWindow(_ sender: AnyObject?) {
240         mapWindowController.showWindow(nil)
241     }
242     @IBAction func showOwnershipShipWindow(_ sender: AnyObject?) {
243         shipMDWindowController.showWindow(nil)
244     }
245     
246     @IBAction func saveLocalData(_ sender: AnyObject?) {
247         TSVSupport().save()
248     }
249     @IBAction func loadLocalData(_ sender: AnyObject?) {
250         TSVSupport().load()
251     }
252     
253     @IBAction func saveDocument(_ sender: AnyObject?) {
254         let panel = NSSavePanel()
255         panel.allowedFileTypes = ["plist"]
256         panel.prompt = "Save Panel"
257         panel.title = "Save Panel"
258         panel.begin {
259             guard $0 == NSModalResponseOK,
260                 let url = panel.url,
261                 let array = self.jsonViewWindowController?.commands
262                 else { return }
263             let data = NSKeyedArchiver.archivedData(withRootObject: array)
264             do {
265                 try data.write(to: url)
266             } catch { print("Can not write to \(url)") }
267         }
268     }
269     @IBAction func openDocument(_ sender: AnyObject?) {
270         let panel = NSOpenPanel()
271         panel.allowedFileTypes = ["plist"]
272         panel.allowsMultipleSelection = false
273         panel.prompt = "Open log"
274         panel.title = "Open log"
275         panel.begin {
276             guard $0 == NSModalResponseOK,
277             let url = panel.url
278             else { return }
279             do {
280                 let data = try Data(contentsOf: url)
281                 let array = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data as NSData)
282                 guard let commands = array as? [[String: Any]]
283                     else { return }
284                 
285                 self.logedJSONViewWindowController = JSONViewWindowController()
286                 self.logedJSONViewWindowController?.commands = commands
287                 self.logedJSONViewWindowController?.window?.title = "SAVED LOG FILE VIEWER"
288                 self.logedJSONViewWindowController?.showWindow(nil)
289             } catch { print("Can not load \(url)") }
290         }
291     }
292     
293     private func setTitle(_ menuItem: NSMenuItem,
294                           _ window: NSWindow?,
295                           _ showLabel: String,
296                           _ hideLabel: String) {
297         guard let window = window else { return }
298         if isFrontMostWindow(window) {
299             menuItem.title = hideLabel
300         } else {
301             menuItem.title = showLabel
302         }
303     }
304     // swiftlint:disable function_body_length
305     override func validateMenuItem(_ menuItem: NSMenuItem) -> Bool {
306         guard let action = menuItem.action else { return false }
307         switch action {
308         case Selector.showHideHistory:
309             setTitle(menuItem,
310                      historyWindowController.window,
311                      NSLocalizedString("Show History", comment: "Show History"),
312                      NSLocalizedString("Hide History", comment: "Hide History"))
313             return true
314         case Selector.showHideSlotItemWindow:
315             setTitle(menuItem,
316                      slotItemWindowController.window,
317                      NSLocalizedString("Show Slot Item", comment: "Show Slot Item"),
318                      NSLocalizedString("Hide Slot Item", comment: "Hide Slot Item"))
319             return true
320         case Selector.showHideUpgradableShipWindow:
321             setTitle(menuItem,
322                      upgradableShipWindowController.window,
323                      NSLocalizedString("Show Upgradable Ships", comment: "Show Upgradable Ships"),
324                      NSLocalizedString("Hide Upgradable Ships", comment: "Hide Upgradable Ships"))
325             return true
326         case Selector.showHideScreenshotListWindow:
327             setTitle(menuItem,
328                      screenshotListWindowController.window,
329                      NSLocalizedString("Show Screenshot List", comment: "Show Screenshot List"),
330                      NSLocalizedString("Hide Screenshot List", comment: "Hide Screenshot List"))
331             return true
332         case Selector.showHideAirBaseInfoWindow:
333             setTitle(menuItem,
334                      airBaseWindowController.window,
335                      NSLocalizedString("Show Air Base Info", comment: "Show Air Base Info"),
336                      NSLocalizedString("Hide Air Base Info", comment: "Hide Air Base Info"))
337             return true
338         case Selector.saveLocalData, Selector.loadLocalData:
339             return true
340         case Selector.showHidePreferencePanle:
341             return true
342         case Selector.openNewBrowser:
343             return true
344         case Selector.selectBookmark:
345             return true
346         case Selector.showWindowAduster:
347             return true
348         case Selector.saveDocument, Selector.openDocument:
349             return jsonViewWindowController != nil
350         case Selector.removeDatabaseFile:
351             return true
352         case Selector.showShipWindow, Selector.showEquipmentWindow,
353              Selector.showMapWindow, Selector.showOwnershipShipWindow:
354             return true
355         default:
356             return false
357         }
358     }
359 }
360
361 extension AppDelegate: NSApplicationDelegate {
362     func applicationWillFinishLaunching(_ notification: Notification) {
363         NSUserNotificationCenter.default.delegate = self
364         Timer.scheduledTimer(timeInterval: 0.33,
365                              target: self,
366                              selector: .fireInAppDelegate,
367                              userInfo: nil,
368                              repeats: true)
369     }
370     func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
371         return true
372     }
373 }
374
375 extension AppDelegate: NSUserNotificationCenterDelegate {
376     func userNotificationCenter(_ center: NSUserNotificationCenter,
377                                 shouldPresent notification: NSUserNotification) -> Bool {
378         return true
379     }
380 }
381
382 @available(OSX 10.12.2, *)
383 fileprivate var objectForTouchBar: [Int: NSTouchBar] = [:]
384
385 @available(OSX 10.12.2, *)
386 extension AppDelegate: NSTouchBarProvider {
387     @IBOutlet var mainTouchBar: NSTouchBar? {
388         get {
389             return objectForTouchBar[hash]
390         }
391         set {
392             objectForTouchBar[hash] = newValue
393         }
394     }
395     
396     var touchBar: NSTouchBar? {
397         get {
398             let mainWindow = NSApplication.shared().mainWindow
399             if mainWindow == self.browserWindowController.window { return nil }
400             if let _ = mainTouchBar {
401                 return mainTouchBar
402             }
403             var topLevel: NSArray = []
404             Bundle.main.loadNibNamed("MainTouchBar",
405                                      owner: self,
406                                      topLevelObjects: &topLevel)
407             return mainTouchBar
408         }
409         set {}
410     }
411 }