CompareViewController.swift 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  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. savePanel.allowedContentTypes = [.pdf]
  56. savePanel.accessoryView = checkBox
  57. if (savePanel.runModal() == .OK) {
  58. var exportFiles = NSMutableArray()
  59. if (checkBox.state == .on) {
  60. for tfile in NSArray(array: _files) {
  61. let file = tfile as! NSMutableDictionary;
  62. let degree = file.degree()
  63. if (fabs(degree - 100) > 0) {
  64. exportFiles.add(file);
  65. }
  66. }
  67. if (exportFiles.count == 0) {
  68. let alert = NSAlert.init()
  69. alert.messageText = "所有对比项均无差异";
  70. alert.runModal();
  71. return
  72. }
  73. }else {
  74. exportFiles = NSMutableArray(array: _files)
  75. }
  76. let url = savePanel.url!;
  77. NSLog("\(url)")
  78. let pdf = PDFDocument.init();
  79. let needFilter = checkBox.state == .on
  80. self.progressIndicator.isHidden = false;
  81. self.progressIndicator.doubleValue = 0;
  82. processNextImages(pdf, index: 0, files:exportFiles, url: url, needFilter: needFilter)
  83. }
  84. }
  85. // Save PDF
  86. func processNextImages(_ pdf:PDFDocument, index:Int32, files:NSMutableArray, url:URL, needFilter:Bool) -> Void {
  87. let file = files[Int(index)] as! NSMutableDictionary
  88. NSLog("处理第\(index)页")
  89. // 所有文档均导出
  90. let cell = ImageCompareCellView.shared()
  91. cell?.frame = CGRectMake(0, 0, CGRectGetWidth(self.listView.frame), 900);
  92. cell?.setFileInfo(file);
  93. self.closeBtn.isEnabled = false;
  94. DispatchQueue.global().async {
  95. autoreleasepool {
  96. let image = cell?.processCompareImage()
  97. if (image != nil) {
  98. let page = PDFPage.init(image: image!)
  99. let nPage = page?.copy() as! PDFPage
  100. pdf.insert(nPage, at: pdf.pageCount)
  101. }
  102. }
  103. let degree = file.degree()
  104. if (abs(degree - 100) > 0) {
  105. autoreleasepool {
  106. let image = cell?.processCoverImage()
  107. if (image != nil) {
  108. let page = PDFPage.init(image: image!)
  109. let nPage = page?.copy() as! PDFPage
  110. pdf.insert(nPage, at: pdf.pageCount)
  111. }
  112. }
  113. }
  114. if ((index+1) < files.count) {
  115. DispatchQueue.main.asyncAfter(deadline: DispatchTime.init(uptimeNanoseconds: 100)) {
  116. self.progressIndicator.doubleValue = Double(Int(index) * 100/files.count);
  117. self.processNextImages(pdf, index: index+1, files: files, url: url, needFilter: needFilter);
  118. };
  119. }else {
  120. DispatchQueue.global().async {
  121. autoreleasepool {
  122. pdf.write(to: url)
  123. DispatchQueue.main.async {
  124. self.progressIndicator.isHidden = true;
  125. self.progressIndicator.doubleValue = 100.0;
  126. self.closeBtn.isEnabled = true;
  127. NSWorkspace.shared.activateFileViewerSelecting([url])
  128. }
  129. }
  130. }
  131. }
  132. }
  133. }
  134. // Show
  135. func showIn(_ view:NSView, rect:NSRect) {
  136. if _popover == nil {
  137. _popover = NSPopover.init()
  138. _popover.contentViewController = self;
  139. _popover.delegate = self
  140. }
  141. _popover.contentSize = self.view.frame.size
  142. _popover.show(relativeTo: rect, of: view, preferredEdge: NSRectEdge.minY)
  143. }
  144. // Getter & Setter
  145. func setFiles(_ files:NSArray) {
  146. _files = files
  147. if (self.filterBtn.state == .on) {
  148. _showFiles = NSMutableArray()
  149. for tfile in NSArray(array: _files) {
  150. let file = tfile as! NSMutableDictionary;
  151. let degree = file.degree()
  152. if (fabs(degree - 100) > 0) {
  153. _showFiles.add(file);
  154. }
  155. }
  156. }else {
  157. _showFiles = NSMutableArray (array: _files);
  158. }
  159. listView.reloadData()
  160. }
  161. // IBAction
  162. @IBAction func closeAction(_ sender: NSButton) {
  163. _popover.close()
  164. }
  165. // TableView Delegate
  166. func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
  167. return autoreleasepool {
  168. var cellView = tableView.makeView(withIdentifier: .init("ImageCompareCellView"), owner: nil) as! ImageCompareCellView?
  169. if (nil == cellView) {
  170. cellView = ImageCompareCellView.shared() ?? nil
  171. }
  172. if (_showFiles.count >= row) {
  173. let fileInfo = _showFiles[row] as! NSMutableDictionary
  174. cellView?.setFileInfo(fileInfo)
  175. }
  176. return cellView
  177. }
  178. }
  179. func selectionShouldChange(in tableView: NSTableView) -> Bool {
  180. return true
  181. }
  182. func tableView(_ tableView: NSTableView, shouldSelectRow row: Int) -> Bool {
  183. return false
  184. }
  185. func tableView(_ tableView: NSTableView, shouldSelect tableColumn: NSTableColumn?) -> Bool {
  186. return false
  187. }
  188. func tableView(_ tableView: NSTableView, mouseDownInHeaderOf tableColumn: NSTableColumn) {
  189. }
  190. func tableView(_ tableView: NSTableView, didClick tableColumn: NSTableColumn) {
  191. }
  192. func tableView(_ tableView: NSTableView, didDrag tableColumn: NSTableColumn) {
  193. }
  194. func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat {
  195. return 900
  196. }
  197. func tableView(_ tableView: NSTableView, isGroupRow row: Int) -> Bool {
  198. return false
  199. }
  200. func tableView(_ tableView: NSTableView, sizeToFitWidthOfColumn column: Int) -> CGFloat {
  201. return tableView.frame.width
  202. }
  203. func tableView(_ tableView: NSTableView, rowActionsForRow row: Int, edge: NSTableView.RowActionEdge) -> [NSTableViewRowAction] {
  204. return []
  205. }
  206. func tableViewSelectionDidChange(_ notification: Notification) {
  207. }
  208. // TableView Data Source
  209. func numberOfRows(in tableView: NSTableView) -> Int {
  210. if nil == _showFiles {
  211. return 0
  212. }
  213. return _showFiles.count
  214. }
  215. //
  216. func popoverShouldClose(_ popover: NSPopover) -> Bool {
  217. return true
  218. }
  219. }