OSDN Git Service

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