KMBatchProcessingTableView.swift 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569
  1. //
  2. // KMBatchProcessingTableView.swift
  3. // PDF Master
  4. //
  5. // Created by lizhe on 2022/11/18.
  6. //
  7. import Cocoa
  8. class KMBatchTableView: NSTableView {
  9. var mouseDownAction: (() -> Void)?
  10. // override func mouseDown(with event: NSEvent) {
  11. // super.mouseDown(with: event)
  12. // mouseDownAction?()
  13. // }
  14. }
  15. class KMBatchProcessingTableView: NSView {
  16. @IBOutlet var contentView: NSView!
  17. @IBOutlet weak var tableView: KMBatchTableView!
  18. var orderClickRow = -1
  19. let tableRowPasteboardType: NSPasteboard.PasteboardType = NSPasteboard.PasteboardType(rawValue: "private.table-row")
  20. lazy var presenter: KMBatchProcessingTableViewPresenter! = KMBatchProcessingTableViewPresenter()
  21. weak var delegate: KMBatchProcessingTableViewDelegate?
  22. var selectModels: [KMBatchProcessingTableViewModel] = []
  23. var inputType: KMBatchCollectionViewType = .convertPDF {
  24. didSet {
  25. self.reloadData()
  26. }
  27. }
  28. var isDrag = false
  29. /**
  30. @abstract 外部传入数据
  31. @param inputData 文件路劲
  32. */
  33. var inputData: [URL]! {
  34. didSet {
  35. self.presenter.initPresenter(view: self, data: inputData)
  36. }
  37. }
  38. //内部使用数据
  39. var data: [KMBatchProcessingTableViewModel]?
  40. fileprivate var options: KMBatchProcessingTableViewOptions?
  41. override func draw(_ dirtyRect: NSRect) {
  42. super.draw(dirtyRect)
  43. // Drawing code here.
  44. }
  45. // MARK: 初始化
  46. public required init?(coder decoder: NSCoder) {
  47. super.init(coder: decoder)
  48. initContentView()
  49. setup()
  50. }
  51. override init(frame frameRect: NSRect) {
  52. super.init(frame: frameRect)
  53. initContentView()
  54. setup()
  55. }
  56. private func initContentView() {
  57. //绑定xib
  58. let resource = NSNib(nibNamed: String(describing: self.classForCoder.self),
  59. bundle: Bundle(for: self.classForCoder.self))!
  60. resource.instantiate(withOwner: self, topLevelObjects: nil)
  61. addSubview(contentView)
  62. contentView.translatesAutoresizingMaskIntoConstraints = false
  63. NSLayoutConstraint.activate([
  64. contentView.topAnchor.constraint(equalTo: topAnchor),
  65. contentView.leftAnchor.constraint(equalTo: leftAnchor),
  66. contentView.rightAnchor.constraint(equalTo: rightAnchor),
  67. contentView.bottomAnchor.constraint(equalTo: bottomAnchor)])
  68. contentView.updateConstraintsForSubtreeIfNeeded()
  69. }
  70. func setup() {
  71. self.tableView.dataSource = self
  72. self.tableView.delegate = self
  73. self.tableView.registerForDraggedTypes([NSPasteboard.PasteboardType.string, NSPasteboard.PasteboardType.fileURL, self.tableRowPasteboardType]) //支持拖拽
  74. self.tableView.setDraggingSourceOperationMask([.copy, .delete], forLocal: false)
  75. self.tableView.mouseDownAction = { [unowned self] in
  76. self.cancelAllSelect()
  77. }
  78. self.options = .all
  79. self.presenter.initPresenter(view: self, data: [])
  80. }
  81. func reloadData() {
  82. for _ in self.tableView.tableColumns {
  83. self.tableView.removeTableColumn(self.tableView.tableColumns[0])
  84. }
  85. if inputType == .imageToPDF {
  86. self.options = [.number, .name, .dimension, .size, .state]
  87. } else {
  88. self.options = [.number, .name, .size, .state]
  89. }
  90. if (options!.contains(KMBatchProcessingTableViewOptions.number)) {
  91. let column = NSTableColumn()
  92. column.headerCell = KMBatchProcessingColumnHeaderCell.init()
  93. column.title = NSLocalizedString(" ", comment: "")
  94. column.identifier = NSUserInterfaceItemIdentifier(String(KMBatchProcessingTableViewOptions.number.rawValue))
  95. // column.resizingMask = .userResizingMask
  96. column.width = 40
  97. self.tableView.addTableColumn(column)
  98. }
  99. if (options!.contains(KMBatchProcessingTableViewOptions.name)) {
  100. let column = NSTableColumn()
  101. column.headerCell = KMBatchProcessingColumnHeaderCell.init()
  102. column.title = NSLocalizedString("File Name", comment: "")
  103. column.identifier = NSUserInterfaceItemIdentifier(String(KMBatchProcessingTableViewOptions.name.rawValue))
  104. // column.resizingMask = .userResizingMask
  105. if self.inputType == .imageToPDF {
  106. column.width = 220
  107. } else {
  108. column.width = self.canShowOrder() ? 180 : 344
  109. }
  110. self.tableView.addTableColumn(column)
  111. }
  112. if (options!.contains(KMBatchProcessingTableViewOptions.order) && self.canShowOrder()) {
  113. let column = NSTableColumn()
  114. column.headerCell = KMBatchProcessingColumnHeaderCell.init()
  115. column.title = NSLocalizedString("Page Range", comment: "")
  116. column.identifier = NSUserInterfaceItemIdentifier(String(KMBatchProcessingTableViewOptions.order.rawValue))
  117. column.resizingMask = .userResizingMask
  118. column.width = 164
  119. self.tableView.addTableColumn(column)
  120. }
  121. if (options!.contains(KMBatchProcessingTableViewOptions.dimension)) {
  122. let column = NSTableColumn()
  123. column.headerCell = KMBatchProcessingColumnHeaderCell.init()
  124. column.title = NSLocalizedString("Dimension", comment: "")
  125. column.identifier = NSUserInterfaceItemIdentifier(String(KMBatchProcessingTableViewOptions.dimension.rawValue))
  126. column.resizingMask = .userResizingMask
  127. column.width = 164
  128. self.tableView.addTableColumn(column)
  129. }
  130. if (options!.contains(KMBatchProcessingTableViewOptions.size)) {
  131. let column = NSTableColumn()
  132. column.headerCell = KMBatchProcessingColumnHeaderCell.init()
  133. column.title = NSLocalizedString("Size", comment: "")
  134. column.identifier = NSUserInterfaceItemIdentifier(String(KMBatchProcessingTableViewOptions.size.rawValue))
  135. column.resizingMask = .userResizingMask
  136. column.width = 88
  137. self.tableView.addTableColumn(column)
  138. }
  139. if (options!.contains(KMBatchProcessingTableViewOptions.state)) {
  140. let column = NSTableColumn()
  141. column.headerCell = KMBatchProcessingColumnHeaderCell.init()
  142. column.title = NSLocalizedString("Status", comment: "")
  143. column.identifier = NSUserInterfaceItemIdentifier(String(KMBatchProcessingTableViewOptions.state.rawValue))
  144. column.headerCell.textColor = NSColor.red
  145. column.resizingMask = .userResizingMask
  146. column.width = 56
  147. self.tableView.addTableColumn(column)
  148. }
  149. if (options!.contains(KMBatchProcessingTableViewOptions.delete)) {
  150. let column = NSTableColumn()
  151. column.headerCell = KMBatchProcessingColumnHeaderCell.init()
  152. column.title = NSLocalizedString("", comment: "")
  153. column.identifier = NSUserInterfaceItemIdentifier(String(KMBatchProcessingTableViewOptions.delete.rawValue))
  154. column.resizingMask = .userResizingMask
  155. column.width = 30
  156. self.tableView.addTableColumn(column)
  157. }
  158. self.tableView.reloadData()
  159. }
  160. func canShowOrder() -> Bool {
  161. if (self.inputType == .imageToPDF ||
  162. self.inputType == .security ||
  163. self.inputType == .compress) {
  164. return false
  165. } else {
  166. return true
  167. }
  168. }
  169. }
  170. extension KMBatchProcessingTableView: NSTableViewDelegate {
  171. func numberOfRows(in tableView: NSTableView) -> Int {
  172. return self.data?.count ?? 0
  173. }
  174. func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
  175. var cell: KMBatchProcessingTableCell?
  176. if (tableColumn?.identifier.rawValue == String(KMBatchProcessingTableViewOptions.number.rawValue)) {
  177. cell = KMBatchProcessingNumTableCell.init(frame: CGRect(x: 0, y: 0, width: tableColumn!.width, height:tableView.rowHeight))
  178. } else if (tableColumn?.identifier.rawValue == String(KMBatchProcessingTableViewOptions.name.rawValue)) {
  179. cell = KMBatchProcessingNameTableCell.init(frame: CGRect(x: 0, y: 0, width: tableColumn!.width, height:tableView.rowHeight))
  180. } else if (tableColumn?.identifier.rawValue == String(KMBatchProcessingTableViewOptions.order.rawValue)) {
  181. cell = KMBatchProcessingOrderTableCell.init(frame: CGRect(x: 0, y: 0, width: tableColumn!.width, height:tableView.rowHeight))
  182. if cell != nil {
  183. (cell as? KMBatchProcessingOrderTableCell)!.cellAction = { [weak self] pageRange in
  184. self?.orderClickRow = row
  185. }
  186. }
  187. } else if (tableColumn?.identifier.rawValue == String(KMBatchProcessingTableViewOptions.dimension.rawValue)) {
  188. cell = KMBatchProcessingWidthTableCell.init(frame: CGRect(x: 0, y: 0, width: tableColumn!.width, height:tableView.rowHeight))
  189. } else if (tableColumn?.identifier.rawValue == String(KMBatchProcessingTableViewOptions.size.rawValue)) {
  190. cell = KMBatchProcessingSizeTableCell.init(frame: CGRect(x: 0, y: 0, width: tableColumn!.width, height:tableView.rowHeight))
  191. } else if (tableColumn?.identifier.rawValue == String(KMBatchProcessingTableViewOptions.state.rawValue)) {
  192. cell = KMBatchProcessingStateTableCell.init(frame: CGRect(x: 0, y: 0, width: tableColumn!.width, height:tableView.rowHeight))
  193. } else if (tableColumn?.identifier.rawValue == String(KMBatchProcessingTableViewOptions.delete.rawValue)) {
  194. cell = KMBatchProcessingDeleteTableCell.init(frame: CGRect(x: 0, y: 0, width: tableColumn!.width, height:tableView.rowHeight))
  195. cell?.action = { [unowned self] (view) in
  196. self.presenter.deleteData(model: view.model)
  197. }
  198. }
  199. if(cell != nil) {
  200. if (self.data!.count > row) {
  201. let model = self.data![row]
  202. model.type = self.inputType
  203. cell!.model = model
  204. }
  205. }
  206. return cell
  207. }
  208. func tableView(_ tableView: NSTableView, rowViewForRow row: Int) -> NSTableRowView? {
  209. //悬浮删除
  210. let tableRowView = KMBatchProcessingTableRowView()
  211. tableRowView.selectionHighlightStyle = .none
  212. tableRowView.model = self.data?[row]
  213. tableRowView.hoverCallback = { [unowned self] (mouseEntered, mouseBox) in
  214. if data != nil {
  215. for i in 0...self.data!.count - 1 {
  216. let model = self.data![i]
  217. if model.hover == true {
  218. model.hover = false
  219. let columnIndex = self.tableView.column(withIdentifier: NSUserInterfaceItemIdentifier(KMBatchProcessingTableViewOptions.delete.rawValue.description))
  220. self.tableView.reloadData(forRowIndexes: IndexSet(integer: i), columnIndexes: IndexSet(integer: columnIndex))
  221. if self.tableView.rowView(atRow: i, makeIfNecessary: false) is KMBatchProcessingTableRowView {
  222. let rowView: KMBatchProcessingTableRowView = self.tableView.rowView(atRow: i, makeIfNecessary: false) as! KMBatchProcessingTableRowView
  223. rowView.reloadData()
  224. }
  225. }
  226. if i == row {
  227. if mouseEntered {
  228. model.hover = true
  229. } else {
  230. model.hover = false
  231. }
  232. let columnIndex = self.tableView.column(withIdentifier: NSUserInterfaceItemIdentifier(KMBatchProcessingTableViewOptions.delete.rawValue.description))
  233. self.tableView.reloadData(forRowIndexes: IndexSet(integer: i), columnIndexes: IndexSet(integer: columnIndex))
  234. if self.tableView.rowView(atRow: i, makeIfNecessary: false) is KMBatchProcessingTableRowView {
  235. let rowView: KMBatchProcessingTableRowView = self.tableView.rowView(atRow: i, makeIfNecessary: false) as! KMBatchProcessingTableRowView
  236. rowView.reloadData()
  237. }
  238. }
  239. }
  240. }
  241. }
  242. tableRowView.rightMouseCallback = { [unowned self] (view, event) in
  243. self.didSelectItem(shouldSelectRow: row)
  244. DispatchQueue.main.async {
  245. if self.tableView.rowView(atRow: row, makeIfNecessary: false) != nil {
  246. let rowView = self.tableView.rowView(atRow: row, makeIfNecessary: false)
  247. self.addRightMenu(view: rowView!, event: event)
  248. }
  249. }
  250. }
  251. // tableRowView.mouseDownCallback = { [unowned self] (mouseEntered, mouseBox) in
  252. // if self.canSelect(row: row) {
  253. // for i in 0...self.data!.count - 1 {
  254. // let model = self.data![i]
  255. // if model.select == true {
  256. // model.select = false
  257. // let columnIndex = self.tableView.column(withIdentifier: NSUserInterfaceItemIdentifier(KMBatchProcessingTableViewOptions.delete.rawValue.description))
  258. // self.tableView.reloadData(forRowIndexes: IndexSet(integer: i), columnIndexes: IndexSet(integer: columnIndex))
  259. // if self.tableView.rowView(atRow: i, makeIfNecessary: false) is KMBatchProcessingTableRowView {
  260. // let rowView: KMBatchProcessingTableRowView = self.tableView.rowView(atRow: i, makeIfNecessary: false) as! KMBatchProcessingTableRowView
  261. // rowView.reloadData()
  262. // }
  263. // }
  264. //
  265. // if i == row {
  266. // if mouseEntered {
  267. // model.select = true
  268. // } else {
  269. // model.select = false
  270. // }
  271. // let columnIndex = self.tableView.column(withIdentifier: NSUserInterfaceItemIdentifier(KMBatchProcessingTableViewOptions.delete.rawValue.description))
  272. // self.tableView.reloadData(forRowIndexes: IndexSet(integer: i), columnIndexes: IndexSet(integer: columnIndex))
  273. // if self.tableView.rowView(atRow: i, makeIfNecessary: false) is KMBatchProcessingTableRowView {
  274. // let rowView: KMBatchProcessingTableRowView = self.tableView.rowView(atRow: i, makeIfNecessary: false) as! KMBatchProcessingTableRowView
  275. // rowView.reloadData()
  276. // }
  277. // self.didSelectItem(shouldSelectRow: i)
  278. // }
  279. // }
  280. //
  281. // } else {
  282. // self.orderClickRow = -1
  283. // }
  284. // }
  285. return tableRowView
  286. }
  287. func tableView(_ tableView: NSTableView, shouldSelect tableColumn: NSTableColumn?) -> Bool {
  288. return true
  289. }
  290. func tableView(_ tableView: NSTableView, didClick tableColumn: NSTableColumn) {
  291. }
  292. func tableViewSelectionDidChange(_ notification: Notification) {
  293. let tableView: NSTableView = notification.object as? NSTableView ?? NSTableView()
  294. if tableView == self.tableView {
  295. if self.data != nil {
  296. if (self.tableView?.selectedRow == -1) {
  297. for item in self.data! {
  298. item.select = false
  299. }
  300. self.selectModels.removeAll()
  301. self.tableView.reloadData()
  302. }
  303. }
  304. }
  305. }
  306. func tableView(_ tableView: NSTableView, shouldSelectRow row: Int) -> Bool {
  307. KMPrint("选中")
  308. self.didSelectItem(shouldSelectRow: row)
  309. return true
  310. }
  311. func didSelectItem(shouldSelectRow row: Int) {
  312. if self.data != nil && !self.isDrag {
  313. for item in self.data! {
  314. item.select = false
  315. }
  316. let model = self.data?[row]
  317. if model != nil {
  318. model?.select = true
  319. self.selectModels.removeAll()
  320. self.selectModels.append(model!)
  321. self.tableView.reloadData()
  322. }
  323. }
  324. }
  325. func cancelAllSelect() {
  326. for i in 0...self.data!.count - 1 {
  327. let model = self.data![i]
  328. model.select = false
  329. model.hover = false
  330. let columnIndex = self.tableView.column(withIdentifier: NSUserInterfaceItemIdentifier(KMBatchProcessingTableViewOptions.delete.rawValue.description))
  331. self.tableView.reloadData(forRowIndexes: IndexSet(integer: i), columnIndexes: IndexSet(integer: columnIndex))
  332. if self.tableView.rowView(atRow: i, makeIfNecessary: false) is KMBatchProcessingTableRowView {
  333. let rowView: KMBatchProcessingTableRowView = self.tableView.rowView(atRow: i, makeIfNecessary: false) as! KMBatchProcessingTableRowView
  334. rowView.reloadData()
  335. }
  336. }
  337. }
  338. }
  339. extension KMBatchProcessingTableView: NSTableViewDataSource {
  340. func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat {
  341. if self.inputType == .imageToPDF {
  342. return 80
  343. } else {
  344. return 40
  345. }
  346. }
  347. // func tableView(_ tableView: NSTableView, pasteboardWriterForRow row: Int) -> NSPasteboardWriting? {
  348. // let item: NSPasteboardItem = NSPasteboardItem()
  349. //
  350. // item.setString(String(row), forType: self.tableRowPasteboardType)
  351. //
  352. // return item
  353. // }
  354. func tableView(_ tableView: NSTableView, writeRowsWith rowIndexes: IndexSet, to pboard: NSPasteboard) -> Bool {
  355. //自定义内部拖拽数据
  356. let data: Data = try! NSKeyedArchiver.archivedData(withRootObject: rowIndexes, requiringSecureCoding: true)
  357. pboard.declareTypes([self.tableRowPasteboardType], owner: self)
  358. pboard.setData(data, forType: self.tableRowPasteboardType)
  359. return true
  360. }
  361. func tableView(_ tableView: NSTableView, validateDrop info: NSDraggingInfo, proposedRow row: Int, proposedDropOperation dropOperation: NSTableView.DropOperation) -> NSDragOperation {
  362. guard dropOperation == .above else {
  363. return []
  364. }
  365. self.isDrag = true
  366. self.cancelAllSelect()
  367. if let source = info.draggingSource as? NSTableView, source === tableView {
  368. tableView.draggingDestinationFeedbackStyle = .gap
  369. } else {
  370. tableView.draggingDestinationFeedbackStyle = .regular
  371. }
  372. return .move
  373. }
  374. func tableView(_ tableView: NSTableView, acceptDrop info: NSDraggingInfo, row: Int, dropOperation: NSTableView.DropOperation) -> Bool {
  375. var result: Bool = false;
  376. let pboard: NSPasteboard = info.draggingPasteboard
  377. if ((pboard.availableType(from: [NSPasteboard.PasteboardType.fileURL])) != nil) {
  378. //获取url
  379. var array: [URL] = []
  380. for item: NSPasteboardItem in pboard.pasteboardItems! {
  381. let string: String = item.string(forType: NSPasteboard.PasteboardType.fileURL)!
  382. let url = NSURL(string: string)
  383. array.append(url! as URL)
  384. }
  385. //添加url
  386. self.presenter.insetData(data: array, index: row)
  387. result = true
  388. } else if ((pboard.availableType(from: [self.tableRowPasteboardType])) != nil) {
  389. //获取初始数据
  390. let rowData: Data = pboard.data(forType: self.tableRowPasteboardType)!
  391. let rowIndexes: NSIndexSet = try!NSKeyedUnarchiver.unarchivedObject(ofClass: NSIndexSet.self, from: rowData)!
  392. if info.draggingSource as? NSTableView == tableView {
  393. //移除物件悬浮状态
  394. if data != nil {
  395. let model = self.data![rowIndexes.firstIndex]
  396. model.hover = false
  397. let columnIndex = self.tableView.column(withIdentifier: NSUserInterfaceItemIdentifier(KMBatchProcessingTableViewOptions.delete.rawValue.description))
  398. self.tableView.reloadData(forRowIndexes: rowIndexes as IndexSet, columnIndexes: IndexSet(integer: columnIndex))
  399. }
  400. //数据处理
  401. self.data!.move(with: IndexSet(rowIndexes), to: row)
  402. /**
  403. 数据刷新
  404. */
  405. tableView.beginUpdates()
  406. tableView.reloadData()
  407. tableView.endUpdates()
  408. // tableView.beginUpdates()
  409. // var oldIndexOffset = 0
  410. // var newIndexOffset = 0
  411. //
  412. // for oldIndex in rowIndexes {
  413. // if oldIndex < row {
  414. // tableView.moveRow(at: oldIndex + oldIndexOffset, to: row - 1)
  415. // oldIndexOffset -= 1
  416. // } else {
  417. // tableView.moveRow(at: oldIndex, to: row + newIndexOffset)
  418. // newIndexOffset += 1
  419. // }
  420. // }
  421. // tableView.endUpdates()
  422. }
  423. result = true
  424. }
  425. self.isDrag = false
  426. return result
  427. }
  428. func tableView(_ tableView: NSTableView, draggingSession session: NSDraggingSession, endedAt screenPoint: NSPoint, operation: NSDragOperation) {
  429. // Handle items dragged to Trash
  430. tableView.draggingDestinationFeedbackStyle = .none
  431. // if operation == .delete, let items = session.draggingPasteboard.pasteboardItems {
  432. // let indexes = items.compactMap{ $0.integer(forType: .tableViewIndex) }
  433. //
  434. // for index in indexes.reversed() {
  435. // self.data?.remove(at: index)
  436. // }
  437. // tableView.removeRows(at: IndexSet(indexes), withAnimation: .slideUp)
  438. // }
  439. DispatchQueue.main.async {
  440. self.isDrag = false
  441. }
  442. }
  443. }
  444. extension KMBatchProcessingTableView: KMBatchProcessingTableViewPresenterDelegate {
  445. func showData(presenter: KMBatchProcessingTableViewPresenter, data: [KMBatchProcessingTableViewModel]) {
  446. self.data = data
  447. self.tableView.reloadData()
  448. self.delegate?.reloadData(data: data)
  449. }
  450. }
  451. extension Array {
  452. mutating func move(from start: Index, to end: Index) {
  453. guard (0..<count) ~= start, (0...count) ~= end else { return }
  454. if start == end { return }
  455. let targetIndex = start < end ? end - 1 : end
  456. insert(remove(at: start), at: targetIndex)
  457. }
  458. mutating func move(with indexes: IndexSet, to toIndex: Index) {
  459. let movingData = indexes.map{ self[$0] }
  460. let targetIndex = toIndex - indexes.filter{ $0 < toIndex }.count
  461. for (i, e) in indexes.enumerated() {
  462. remove(at: e - i)
  463. }
  464. insert(contentsOf: movingData, at: targetIndex)
  465. }
  466. }
  467. protocol KMBatchProcessingTableViewDelegate: NSObject {
  468. func reloadData(data: [KMBatchProcessingTableViewModel])
  469. }
  470. extension KMBatchProcessingTableView {
  471. func addRightMenu(view: NSView, event: NSEvent) {
  472. let menus = NSMenu()
  473. menus.addItem(withTitle: NSLocalizedString("Show in Finder", comment: ""), action: #selector(showInFinder), target: self)
  474. menus.addItem(withTitle: NSLocalizedString("Remove", comment: ""), action: #selector(removeItem), target: self)
  475. let point = view.convert(event.locationInWindow, from: nil)
  476. menus.popUp(positioning: nil, at: point, in: view)
  477. }
  478. @objc func showInFinder(sender: KMBatchProcessingTableRowView) {
  479. if self.selectModels.count != 0 {
  480. let model = self.selectModels.first
  481. if FileManager.default.fileExists(atPath: model!.filePath) {
  482. NSWorkspace.shared.activateFileViewerSelecting([URL(fileURLWithPath: model!.filePath)])
  483. }
  484. }
  485. }
  486. @objc func removeItem(sender: KMBatchProcessingTableRowView) {
  487. if self.selectModels.count != 0 {
  488. let model = self.selectModels.first!
  489. self.presenter.deleteData(model: model)
  490. }
  491. }
  492. }
  493. extension KMBatchProcessingTableView{
  494. func canSelect(row: Int) -> Bool {
  495. guard let data = data else { return false }
  496. if !self.isDrag && (self.orderClickRow != row && data[row].pageRange == .custom) {
  497. return true
  498. } else {
  499. return false
  500. }
  501. }
  502. }