OSDN Git Service

swiftlint 'colon' の警告を修正
[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
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 { try data.write(to: url) }
243             catch { print("Can not write to \(url)") }
244         }
245     }
246     @IBAction func openDocument(_ sender: AnyObject?) {
247         let panel = NSOpenPanel()
248         panel.allowedFileTypes = ["plist"]
249         panel.allowsMultipleSelection = false
250         panel.prompt = "Open log"
251         panel.title = "Open log"
252         panel.begin {
253             guard $0 == NSModalResponseOK,
254             let url = panel.url
255             else { return }
256             do {
257                 let data = try Data(contentsOf: url)
258                 let array = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data as NSData)
259                 
260                 self.logedJSONViewWindowController = JSONViewWindowController()
261                 self.logedJSONViewWindowController?.commands = array as! NSMutableArray
262                 self.logedJSONViewWindowController?.window?.title = "SAVED LOG FILE VIEWER"
263                 self.logedJSONViewWindowController?.showWindow(nil)
264             }
265             catch { print("Can not load \(url)") }
266         }
267     }
268     
269     private func setTitle(_ menuItem: NSMenuItem,
270                           _ window: NSWindow?,
271                           _ showLabel: String,
272                           _ hideLabel: String) {
273         guard let window = window else { return }
274         if isFrontMostWindow(window) {
275             menuItem.title = hideLabel
276         } else {
277             menuItem.title = showLabel
278         }
279     }
280     override func validateMenuItem(_ menuItem: NSMenuItem) -> Bool {
281         guard let action = menuItem.action else { return false }
282         switch action {
283         case Selector.showHideHistory:
284             setTitle(menuItem,
285                      historyWindowController.window,
286                      NSLocalizedString("Show History", comment: "Show History"),
287                      NSLocalizedString("Hide History", comment: "Hide History"))
288             return true
289         case Selector.showHideSlotItemWindow:
290             setTitle(menuItem,
291                      slotItemWindowController.window,
292                      NSLocalizedString("Show Slot Item", comment: "Show Slot Item"),
293                      NSLocalizedString("Hide Slot Item", comment: "Hide Slot Item"))
294             return true
295         case Selector.showHideUpgradableShipWindow:
296             setTitle(menuItem,
297                      upgradableShipWindowController.window,
298                      NSLocalizedString("Show Upgradable Ships", comment: "Show Upgradable Ships"),
299                      NSLocalizedString("Hide Upgradable Ships", comment: "Hide Upgradable Ships"))
300             return true
301         case Selector.showHideScreenshotListWindow:
302             setTitle(menuItem,
303                      screenshotListWindowController.window,
304                      NSLocalizedString("Show Screenshot List", comment: "Show Screenshot List"),
305                      NSLocalizedString("Hide Screenshot List", comment: "Hide Screenshot List"))
306             return true
307         case Selector.showHideAirBaseInfoWindow:
308             setTitle(menuItem,
309                      airBaseWindowController.window,
310                      NSLocalizedString("Show Air Base Info", comment: "Show Air Base Info"),
311                      NSLocalizedString("Hide Air Base Info", comment: "Hide Air Base Info"))
312             return true
313         case Selector.saveLocalData, Selector.loadLocalData:
314             return true
315         case Selector.showHidePreferencePanle:
316             return true
317         case Selector.openNewBrowser:
318             return true
319         case Selector.selectBookmark:
320             return true
321         case Selector.showWindowAduster:
322             return true
323         case Selector.saveDocument, Selector.openDocument:
324             return jsonViewWindowController != nil
325         case Selector.removeDatabaseFile:
326             return true
327         case Selector.showShipWindow, Selector.showEquipmentWindow,
328              Selector.showMapWindow, Selector.showOwnershipShipWindow:
329             return true
330         default:
331             return false
332         }
333     }
334 }
335
336 extension AppDelegate: NSApplicationDelegate {
337     func applicationWillFinishLaunching(_ notification: Notification) {
338         NSUserNotificationCenter.default.delegate = self
339         Timer.scheduledTimer(timeInterval: 0.33,
340                              target: self,
341                              selector: .fireInAppDelegate,
342                              userInfo: nil,
343                              repeats: true)
344     }
345     func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
346         return true
347     }
348 }
349
350 extension AppDelegate: NSUserNotificationCenterDelegate {
351     func userNotificationCenter(_ center: NSUserNotificationCenter, shouldPresent notification: NSUserNotification) -> Bool {
352         return true
353     }
354 }
355
356 @available(OSX 10.12.2, *)
357 fileprivate var objectForTouchBar: [Int: NSTouchBar] = [:]
358
359 @available(OSX 10.12.2, *)
360 extension AppDelegate: NSTouchBarProvider {
361     @IBOutlet var mainTouchBar: NSTouchBar? {
362         get {
363             return objectForTouchBar[hash]
364         }
365         set {
366             objectForTouchBar[hash] = newValue
367         }
368     }
369     
370     var touchBar: NSTouchBar? {
371         get {
372             let mainWindow = NSApplication.shared().mainWindow
373             if mainWindow == self.browserWindowController.window { return nil }
374             if let _ = mainTouchBar {
375                 return mainTouchBar
376             }
377             var topLevel: NSArray = []
378             Bundle.main.loadNibNamed("MainTouchBar",
379                                      owner: self,
380                                      topLevelObjects: &topLevel)
381             return mainTouchBar
382         }
383         set {}
384     }
385 }