CompareViewController.swift 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. //
  2. // CompareViewController.swift
  3. // KdanAuto
  4. //
  5. // Created by 朱东勇 on 2023/2/2.
  6. //
  7. import Foundation
  8. import AppKit
  9. import PDFKit
  10. class CompareViewController: NSViewController, NSTableViewDataSource, NSTableViewDelegate, NSPopoverDelegate {
  11. @IBOutlet var listView : NSTableView!
  12. @IBOutlet var filterBtn : NSButton!
  13. @IBOutlet var closeBtn : NSButton!
  14. @IBOutlet var progressIndicator : NSProgressIndicator!
  15. var _files : NSArray!
  16. var _showFiles : NSMutableArray!
  17. var _popover: NSPopover!
  18. static var sharedCViewController : CompareViewController? = nil
  19. class func shared() -> CompareViewController {
  20. if nil == sharedCViewController {
  21. var objects : NSArray!
  22. Bundle.main.loadNibNamed("CompareViewController", owner: nil, topLevelObjects: &objects)
  23. for tView in objects {
  24. if let tv = tView as? CompareViewController {
  25. sharedCViewController = tv
  26. }
  27. }
  28. }
  29. return sharedCViewController!
  30. }
  31. override func viewDidLoad() {
  32. self.listView.register(NSNib.init(nibNamed: NSNib.Name.init(NSString(string: "ImageCompareCellView")),
  33. bundle: Bundle.main), forIdentifier: NSUserInterfaceItemIdentifier.init("ImageCompareCellView"))
  34. }
  35. // IBAction
  36. @IBAction func filterSimilarItemAction(_ sender:NSButton) {
  37. self.setFiles(_files);
  38. }
  39. @IBAction func exportAction(_ sender:NSButton) {
  40. if (_files.count == 0) {
  41. let alert = NSAlert.init()
  42. alert.messageText = "无测试对比项导出";
  43. alert.runModal();
  44. return
  45. }else if (_showFiles.count == 0) {
  46. let alert = NSAlert.init()
  47. alert.messageText = "所有对比项均无差异";
  48. alert.runModal();
  49. return
  50. }
  51. let savePanel = NSSavePanel.init();
  52. let checkBox = NSButton(checkboxWithTitle: "过滤无差异项", target: self, action: nil);
  53. checkBox.state = self.filterBtn.state;
  54. checkBox.frame = CGRectMake(0, 0, 150, 45);
  55. if #available(macOS 11.0, *) {
  56. savePanel.allowedContentTypes = [.pdf]
  57. } else {
  58. savePanel.allowedFileTypes = ["pdf", "PDF"]
  59. }
  60. savePanel.accessoryView = checkBox
  61. if (savePanel.runModal() == .OK) {
  62. var exportFiles = NSMutableArray()
  63. if (checkBox.state == .on) {
  64. for tfile in NSArray(array: _files) {
  65. let file = tfile as! NSMutableDictionary;
  66. let degree = file.degree()
  67. if (fabs(degree - 100) > 0) {
  68. exportFiles.add(file);
  69. }
  70. }
  71. if (exportFiles.count == 0) {
  72. let alert = NSAlert.init()
  73. alert.messageText = "所有对比项均无差异";
  74. alert.runModal();
  75. return
  76. }
  77. }else {
  78. exportFiles = NSMutableArray(array: _files)
  79. }
  80. let url = savePanel.url!;
  81. NSLog("\(url)")
  82. let pdf = PDFDocument.init();
  83. let needFilter = checkBox.state == .on
  84. self.progressIndicator.isHidden = false;
  85. self.progressIndicator.doubleValue = 0;
  86. processNextImages(pdf, index: 0, files:exportFiles, url: url, needFilter: needFilter)
  87. }
  88. }
  89. // Save PDF
  90. func processNextImages(_ pdf:PDFDocument, index:Int32, files:NSMutableArray, url:URL, needFilter:Bool) -> Void {
  91. let file = files[Int(index)] as! NSMutableDictionary
  92. // NSLog("处理第\(index)页")
  93. // 所有文档均导出
  94. let cell = ImageCompareCellView.shared()
  95. cell?.frame = CGRectMake(0, 0, CGRectGetWidth(self.listView.frame), 900);
  96. cell?.setFileInfo(file);
  97. self.closeBtn.isEnabled = false;
  98. DispatchQueue.global().async {
  99. autoreleasepool {
  100. let image = cell?.processCompareImage()
  101. if (image != nil) {
  102. let page = PDFPage.init(image: image!)
  103. let nPage = page?.copy() as! PDFPage
  104. pdf.insert(nPage, at: pdf.pageCount)
  105. }
  106. }
  107. let degree = file.degree()
  108. if (abs(degree - 100) > 0) {
  109. autoreleasepool {
  110. let image = cell?.processCoverImage()
  111. if (image != nil) {
  112. let page = PDFPage.init(image: image!)
  113. let nPage = page?.copy() as! PDFPage
  114. pdf.insert(nPage, at: pdf.pageCount)
  115. }
  116. }
  117. }
  118. if ((index+1) < files.count) {
  119. DispatchQueue.main.asyncAfter(deadline: DispatchTime.init(uptimeNanoseconds: 100)) {
  120. self.progressIndicator.doubleValue = Double(Int(index) * 100/files.count);
  121. self.processNextImages(pdf, index: index+1, files: files, url: url, needFilter: needFilter);
  122. };
  123. }else {
  124. DispatchQueue.global().async {
  125. autoreleasepool {
  126. pdf.write(to: url)
  127. DispatchQueue.main.async {
  128. self.progressIndicator.isHidden = true;
  129. self.progressIndicator.doubleValue = 100.0;
  130. self.closeBtn.isEnabled = true;
  131. NSWorkspace.shared.activateFileViewerSelecting([url])
  132. }
  133. }
  134. }
  135. }
  136. }
  137. }
  138. // Show
  139. func showIn(_ view:NSView, rect:NSRect) {
  140. if _popover == nil {
  141. _popover = NSPopover.init()
  142. _popover.contentViewController = self;
  143. _popover.delegate = self
  144. }
  145. _popover.contentSize = self.view.frame.size
  146. _popover.show(relativeTo: rect, of: view, preferredEdge: NSRectEdge.minY)
  147. }
  148. // Getter & Setter
  149. func setFiles(_ files:NSArray) {
  150. _files = files
  151. if (self.filterBtn.state == .on) {
  152. _showFiles = NSMutableArray()
  153. for tfile in NSArray(array: _files) {
  154. let file = tfile as! NSMutableDictionary;
  155. let degree = file.degree()
  156. if (fabs(degree - 100) > 0) {
  157. _showFiles.add(file);
  158. }
  159. }
  160. }else {
  161. _showFiles = NSMutableArray (array: _files);
  162. }
  163. listView.reloadData()
  164. }
  165. // IBAction
  166. @IBAction func closeAction(_ sender: NSButton) {
  167. _popover.close()
  168. }
  169. // TableView Delegate
  170. func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
  171. return autoreleasepool {
  172. var cellView = tableView.makeView(withIdentifier: .init("ImageCompareCellView"), owner: nil) as! ImageCompareCellView?
  173. if (nil == cellView) {
  174. cellView = ImageCompareCellView.shared() ?? nil
  175. }
  176. if (_showFiles.count >= row) {
  177. let fileInfo = _showFiles[row] as! NSMutableDictionary
  178. cellView?.setFileInfo(fileInfo)
  179. }
  180. return cellView
  181. }
  182. }
  183. func selectionShouldChange(in tableView: NSTableView) -> Bool {
  184. return true
  185. }
  186. func tableView(_ tableView: NSTableView, shouldSelectRow row: Int) -> Bool {
  187. return false
  188. }
  189. func tableView(_ tableView: NSTableView, shouldSelect tableColumn: NSTableColumn?) -> Bool {
  190. return false
  191. }
  192. func tableView(_ tableView: NSTableView, mouseDownInHeaderOf tableColumn: NSTableColumn) {
  193. }
  194. func tableView(_ tableView: NSTableView, didClick tableColumn: NSTableColumn) {
  195. }
  196. func tableView(_ tableView: NSTableView, didDrag tableColumn: NSTableColumn) {
  197. }
  198. func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat {
  199. return 900
  200. }
  201. func tableView(_ tableView: NSTableView, isGroupRow row: Int) -> Bool {
  202. return false
  203. }
  204. func tableView(_ tableView: NSTableView, sizeToFitWidthOfColumn column: Int) -> CGFloat {
  205. return tableView.frame.width
  206. }
  207. func tableView(_ tableView: NSTableView, rowActionsForRow row: Int, edge: NSTableView.RowActionEdge) -> [NSTableViewRowAction] {
  208. return []
  209. }
  210. func tableViewSelectionDidChange(_ notification: Notification) {
  211. }
  212. // TableView Data Source
  213. func numberOfRows(in tableView: NSTableView) -> Int {
  214. if nil == _showFiles {
  215. return 0
  216. }
  217. return _showFiles.count
  218. }
  219. //
  220. func popoverShouldClose(_ popover: NSPopover) -> Bool {
  221. return true
  222. }
  223. }