CompareViewController.swift 9.0 KB

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