OSDN Git Service

Doutaku を 1.0 にアップデート
[kcd/KCD.git] / KCD / HistoryTableViewController.swift
1 //
2 //  HistoryTableViewController.swift
3 //  KCD
4 //
5 //  Created by Hori,Masaki on 2017/03/10.
6 //  Copyright © 2017年 Hori,Masaki. All rights reserved.
7 //
8
9 import Cocoa
10 import Doutaku
11
12 private protocol Markable {
13     
14     var mark: Bool { get set }
15 }
16
17 private protocol HistoryObject {
18     
19     var date: Date { get }
20 }
21
22 extension DropShipHistory: Markable, HistoryObject {}
23 extension KenzoHistory: Markable, HistoryObject {}
24 extension KaihatuHistory: Markable, HistoryObject {}
25
26 enum MenuItemTag: Int {
27     
28     case delete = 314
29     
30     case addMark = 50000
31 }
32
33 class HistoryTableViewController: NSViewController {
34     
35     // Subbclass MUST override these.
36     var predicateFormat: String { fatalError("Subbclass MUST implement.") }
37     func objects(of predicate: Predicate?, in store: LocalDataStore) throws -> [NSManagedObject] {
38         
39         fatalError("Subbclass MUST implement.")
40     }
41     
42     @IBOutlet private(set) var controller: NSArrayController!
43     @IBOutlet private(set) var tableView: NSTableView!
44     
45     @IBAction func delete(_ sender: AnyObject?) {
46         
47         let store = LocalDataStore.oneTimeEditor()
48         
49         guard let controller = controller else {
50             
51             return
52         }
53         guard let selection = controller.selectedObjects as? [NSManagedObject] else {
54             
55             return
56         }
57         
58         let selectedIndex = controller.selectionIndex
59         store.sync {
60             
61             selection
62                 .compactMap(store.exchange)
63                 .forEach(store.delete)
64         }
65         
66         if selectedIndex > 1 {
67             
68             controller.setSelectionIndex(selectedIndex - 1)
69         }
70     }
71     
72     @IBAction func addMark(_ sender: AnyObject?) {
73         
74         guard let clickedRow = tableView?.clickedRow else {
75             
76             return
77         }
78         guard let items = controller?.arrangedObjects as? [HistoryObject] else {
79             
80             return
81         }
82         guard case 0..<items.count = clickedRow else {
83             
84             return
85         }
86         
87         let clickedObject = items[clickedRow]
88         let predicate = Predicate(\KenzoMark.date, equalTo: clickedObject.date)
89         
90         let store = LocalDataStore.oneTimeEditor()
91         store.sync {
92             
93             if let items = try? self.objects(of: predicate, in: store),
94                 var history = items.first as? Markable {
95                 
96                 let currentMark = history.mark
97                 history.mark = !currentMark
98             }
99             
100             store.save()
101         }
102     }
103     
104     override func validateMenuItem(_ menuItem: NSMenuItem) -> Bool {
105         
106         guard let itemTag = MenuItemTag(rawValue: menuItem.tag) else {
107             
108             return false
109         }
110         
111         switch itemTag {
112             
113         case .delete:
114             
115             return controller.selectionIndex != -1
116             
117         case .addMark:
118             
119             menuItem.isEnabled = false
120             guard let clickedRow = tableView?.clickedRow else {
121                 
122                 return false
123             }
124             guard let items = controller?.arrangedObjects as? [Markable] else {
125                 
126                 return false
127             }
128             guard case 0..<items.count = clickedRow else {
129                 
130                 return false
131             }
132             
133             menuItem.isEnabled = true
134             if items[clickedRow].mark {
135                 
136                 menuItem.title = LocalizedStrings.removeMark.string
137                 
138             } else {
139                 
140                 menuItem.title = LocalizedStrings.addMark.string
141             }
142         }
143         
144         return true
145     }
146 }
147
148 extension HistoryTableViewController: NSTableViewDelegate {
149     
150     func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
151         
152         return tableColumn
153             .flatMap { $0.identifier }
154             .flatMap { tableView.makeView(withIdentifier: $0, owner: nil) }
155     }
156 }
157
158 final class KaihatsuHistoryTableViewController: HistoryTableViewController {
159     
160     override var predicateFormat: String { return "name contains $value" }
161     override func objects(of predicate: Predicate?, in store: LocalDataStore) throws -> [NSManagedObject] {
162         
163         return try store.objects(of: KaihatuHistory.self, predicate: predicate)
164     }
165 }
166
167 final class KenzoHistoryTableViewController: HistoryTableViewController {
168     
169     override var predicateFormat: String { return "name contains $value" }
170     override func objects(of predicate: Predicate?, in store: LocalDataStore) throws -> [NSManagedObject] {
171         
172         return try store.objects(of: KenzoHistory.self, predicate: predicate)
173     }
174 }
175
176 final class DropShipHistoryTableViewController: HistoryTableViewController {
177     
178     override var predicateFormat: String { return "shipName contains $value" }
179     override func objects(of predicate: Predicate?, in store: LocalDataStore) throws -> [NSManagedObject] {
180         
181         return try store.objects(of: DropShipHistory.self, predicate: predicate)
182     }
183 }