23
23
import Cocoa
24
24
import Syntax_Highlight_XPC_Service
25
25
26
+ enum UTISupported {
27
+ case unknown
28
+ case no
29
+ case yes
30
+ case highlight
31
+ }
32
+
33
+ class UTIStatus {
34
+ let UTI : UTI
35
+ var supported : UTISupported = . unknown
36
+ let standard : Bool
37
+ init ( UTI: UTI , standard: Bool ) {
38
+ self . UTI = UTI
39
+ self . standard = standard
40
+ }
41
+ }
42
+
26
43
class DropView : NSView {
27
44
weak var dropDelegate : DropViewDelegate ?
28
45
@@ -48,112 +65,122 @@ class DropView: NSView {
48
65
49
66
override func draggingEntered( _ sender: NSDraggingInfo ) -> NSDragOperation {
50
67
self . layer? . borderColor = NSColor . selectedControlColor. cgColor
68
+ self . dropDelegate? . enterDrag ( sender)
51
69
return . every
52
70
}
53
71
54
72
override func draggingExited( _ sender: NSDraggingInfo ? ) {
55
73
self . layer? . borderColor = NSColor . gridColor. cgColor
74
+ self . dropDelegate? . exitDrag ( sender)
56
75
}
57
76
58
77
override func draggingEnded( _ sender: NSDraggingInfo ) {
59
- if let fileUrl = sender. draggingPasteboard. pasteboardItems? . first? . propertyList ( forType: . fileURL) as? String , let url = URL ( string: fileUrl) {
60
-
61
- do {
62
- let v = try url. resourceValues ( forKeys: [ URLResourceKey . typeIdentifierKey] )
63
- if let uti = v. typeIdentifier {
64
- let u = UTI ( uti)
65
- dropDelegate? . setUTI ( u)
66
- } else {
67
- dropDelegate? . setUTI ( nil )
68
- }
69
- } catch {
70
- dropDelegate? . setUTI ( nil )
71
- }
72
- } else {
73
- dropDelegate? . setUTI ( nil )
74
- }
78
+ self . dropDelegate? . endDrag ( sender)
75
79
self . layer? . borderColor = NSColor . gridColor. cgColor
76
80
}
77
81
}
78
82
79
83
protocol DropViewDelegate : class {
80
- func setUTI( _ type: UTI ? )
84
+ func enterDrag( _ sender: NSDraggingInfo )
85
+ func exitDrag( _ sender: NSDraggingInfo ? )
86
+ func endDrag( _ sender: NSDraggingInfo )
81
87
}
82
88
83
- class CustomTypeViewController : NSViewController , DropViewDelegate {
89
+ class CustomTypeViewController : NSViewController , DropViewDelegate , NSTableViewDelegate , NSTableViewDataSource {
84
90
@IBOutlet weak var dropView : DropView !
85
91
@IBOutlet weak var labelView : NSTextField !
86
- @IBOutlet weak var warningLabel : NSTextField !
87
- @IBOutlet weak var warningImage : NSImageView !
92
+
93
+ @IBOutlet weak var tableView : NSTableView !
94
+ @IBOutlet weak var scrollView : NSScrollView !
95
+
96
+ @IBOutlet weak var handledLegend : NSStackView !
97
+ @IBOutlet weak var notHandledLegend : NSStackView !
98
+ @IBOutlet weak var supportedLegend : NSStackView !
99
+
100
+ private var firstDrop = true
88
101
89
102
var service : SCSHXPCServiceProtocol ? {
90
103
return ( NSApplication . shared. delegate as? AppDelegate ) ? . service
91
104
}
92
105
93
106
var handledUTIs : [ UTIDesc ] = [ ]
94
107
95
- var UTI : UTI ? {
108
+ var UTIs : [ UTIStatus ] = [ ] {
96
109
didSet {
97
- warningLabel. isHidden = true
98
- warningImage. isHidden = true
99
- isUTIValid = false
100
-
101
- if let uti = self . UTI {
102
- let s = NSMutableAttributedString ( )
103
- var label : String = uti. description
104
- if uti. extensions. count > 0 {
105
- label += ( label. isEmpty ? " " : " " ) + " [. \( uti. extensions. joined ( separator: " , . " ) ) ] "
106
- }
107
-
108
- let style = NSMutableParagraphStyle ( )
109
- style. alignment = . center
110
-
111
- if !label. isEmpty {
112
- s. append ( NSAttributedString ( string: label + " \n " , attributes: [ NSAttributedString . Key. paragraphStyle: style] ) )
113
- }
114
- s. append ( NSAttributedString ( string: uti. UTI, attributes: [ NSAttributedString . Key. font : NSFont . systemFont ( ofSize: NSFont . systemFontSize ( for: NSControl . ControlSize. small) ) , NSAttributedString . Key. paragraphStyle: style] ) )
115
-
116
- labelView. attributedStringValue = s
117
-
118
- if let _ = handledUTIs. first ( where: { $0. uti == uti } ) {
119
- self . warningLabel. stringValue = " Format recognized by the extension. "
120
- self . warningImage. image = NSImage ( named: NSImage . statusAvailableName)
121
-
122
- self . warningLabel. isHidden = false
123
- self . warningImage. isHidden = false
124
-
125
- return
126
- } else {
127
- service? . areSomeSyntaxSupported ( uti. extensions, overrideSettings: nil , reply: { ( state) in
128
- self . warningLabel. stringValue = state ? " Format handled by highlight but not by the extension. " : " Format not supported by highlight. "
129
- self . warningImage. image = NSImage ( named: state ? NSImage . statusPartiallyAvailableName : NSImage . statusUnavailableName)
130
- self . warningLabel. isHidden = false
131
- self . warningImage. isHidden = false
132
-
133
- self . isUTIValid = state
134
- } )
110
+ self . handledLegend. isHidden = true
111
+ self . notHandledLegend. isHidden = true
112
+ self . supportedLegend. isHidden = true
113
+ if ( self . UTIs. count > 0 ) {
114
+ for (i, uti) in self . UTIs. enumerated ( ) {
115
+ if let _ = handledUTIs. first ( where: { $0. uti == uti. UTI } ) {
116
+ uti. supported = . yes
117
+ self . handledLegend. isHidden = false
118
+ } else {
119
+ service? . areSomeSyntaxSupported ( uti. UTI. extensions, overrideSettings: nil , reply: { ( state) in
120
+ self . notHandledLegend. isHidden = state
121
+ self . supportedLegend. isHidden = !state
122
+ uti. supported = state ? . highlight : . no
123
+ let c = self . tableView. column ( withIdentifier: NSUserInterfaceItemIdentifier ( " status " ) )
124
+ self . tableView. reloadData ( forRowIndexes: IndexSet ( integer: i) , columnIndexes: IndexSet ( integer: c) )
125
+ } )
126
+ }
135
127
}
136
- } else {
137
- labelView. stringValue = " Drag a file here "
138
128
}
129
+
130
+ self . tableView. reloadData ( )
139
131
}
140
132
}
141
-
142
- fileprivate( set) var isUTIValid : Bool = false
143
-
133
+
144
134
override func viewDidLoad( ) {
145
135
self . dropView. dropDelegate = self
146
136
147
- self . warningLabel. isHidden = true
148
- self . warningImage. isHidden = true
149
-
150
137
handledUTIs = ( NSApplication . shared. delegate as? AppDelegate ) ? . fetchHandledUTIs ( ) ?? [ ]
138
+
139
+ self . handledLegend. isHidden = true
140
+ self . notHandledLegend. isHidden = true
141
+ self . supportedLegend. isHidden = true
151
142
}
152
143
153
- func setUTI( _ type: UTI ? ) {
154
- self . UTI = type
144
+ func enterDrag( _ sender: NSDraggingInfo ) {
145
+ self . scrollView. isHidden = true
146
+ }
147
+ func exitDrag( _ sender: NSDraggingInfo ? ) {
148
+ self . scrollView. isHidden = firstDrop
149
+ }
150
+ func endDrag( _ sender: NSDraggingInfo ) {
151
+ if let fileUrl = sender. draggingPasteboard. pasteboardItems? . first? . propertyList ( forType: . fileURL) as? String , let url = URL ( string: fileUrl) {
152
+
153
+ var UTIs : [ UTIStatus ] = [ ]
154
+
155
+ do {
156
+ let v = try url. resourceValues ( forKeys: [ URLResourceKey . typeIdentifierKey] )
157
+ if let uti = v. typeIdentifier {
158
+ UTIs . append ( UTIStatus ( UTI: UTI ( uti) , standard: true ) )
159
+ }
160
+ } catch {
161
+ }
162
+
163
+ let ext = url. pathExtension
164
+ if !ext. isEmpty {
165
+ let tags = UTTypeCreateAllIdentifiersForTag ( kUTTagClassFilenameExtension, ext as CFString , nil )
166
+ if let t = tags? . takeRetainedValue ( ) as? [ String ] {
167
+ for u in t {
168
+ if UTIs . first ( where: { $0. UTI. UTI == u } ) == nil {
169
+ UTIs . append ( UTIStatus ( UTI: UTI ( u) , standard: false ) )
170
+ }
171
+ }
172
+ }
173
+ }
174
+ self . UTIs = UTIs
175
+ self . scrollView. isHidden = false
176
+ firstDrop = false
177
+ } else {
178
+ self . UTIs = [ ]
179
+ self . scrollView. isHidden = true
180
+ }
155
181
}
156
182
183
+ /*
157
184
@IBAction func doSave(_ sender: Any) {
158
185
if isUTIValid, let url = (NSApplication.shared.delegate as? AppDelegate)?.getQLAppexUrl(), let bundle = Bundle(url: url) {
159
186
@@ -190,4 +217,40 @@ class CustomTypeViewController: NSViewController, DropViewDelegate {
190
217
}
191
218
dismiss(sender)
192
219
}
220
+ */
221
+
222
+ func numberOfRows( in tableView: NSTableView ) -> Int {
223
+ return self . UTIs. count
224
+ }
225
+
226
+ func tableView( _ tableView: NSTableView , objectValueFor tableColumn: NSTableColumn ? , row: Int ) -> Any ? {
227
+ let uti = self . UTIs [ row]
228
+ let font : NSFont
229
+
230
+ if uti. standard {
231
+ font = NSFont . boldSystemFont ( ofSize: NSFont . systemFontSize)
232
+ } else {
233
+ font = NSFont . labelFont ( ofSize: NSFont . systemFontSize)
234
+ }
235
+ if tableColumn? . identifier == NSUserInterfaceItemIdentifier ( " description " ) {
236
+ return NSAttributedString ( string: uti. UTI. description, attributes: [ NSAttributedString . Key. font: font] )
237
+ } else if tableColumn? . identifier == NSUserInterfaceItemIdentifier ( " UTI " ) {
238
+ return NSAttributedString ( string: uti. UTI. UTI, attributes: [ NSAttributedString . Key. font: font] )
239
+ } else if tableColumn? . identifier == NSUserInterfaceItemIdentifier ( " status " ) {
240
+ switch ( uti. supported) {
241
+ case . yes:
242
+ return NSImage ( named: NSImage . statusAvailableName)
243
+ case . no:
244
+ return NSImage ( named: NSImage . statusUnavailableName)
245
+ case . highlight:
246
+ return NSImage ( named: NSImage . statusPartiallyAvailableName)
247
+ case . unknown:
248
+ return NSImage ( named: NSImage . statusNoneName)
249
+ }
250
+ } else if tableColumn? . identifier == NSUserInterfaceItemIdentifier ( " ext " ) {
251
+ return uti. UTI. extensions. joined ( separator: " , " )
252
+ }
253
+
254
+ return nil
255
+ }
193
256
}
0 commit comments