OSDN Git Service

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