// // CompareViewController.swift // KdanAuto // // Created by 朱东勇 on 2023/2/2. // import Foundation import AppKit import PDFKit class CompareViewController: NSViewController, NSTableViewDataSource, NSTableViewDelegate, NSPopoverDelegate { @IBOutlet var listView : NSTableView! @IBOutlet var filterBtn : NSButton! @IBOutlet var closeBtn : NSButton! @IBOutlet var progressIndicator : NSProgressIndicator! var _files : NSArray! var _showFiles : NSMutableArray! var _popover: NSPopover! static var sharedCViewController : CompareViewController? = nil class func shared() -> CompareViewController { if nil == sharedCViewController { var objects : NSArray! Bundle.main.loadNibNamed("CompareViewController", owner: nil, topLevelObjects: &objects) for tView in objects { if let tv = tView as? CompareViewController { sharedCViewController = tv } } } return sharedCViewController! } override func viewDidLoad() { self.listView.register(NSNib.init(nibNamed: NSNib.Name.init(NSString(string: "ImageCompareCellView")), bundle: Bundle.main), forIdentifier: NSUserInterfaceItemIdentifier.init("ImageCompareCellView")) } // IBAction @IBAction func filterSimilarItemAction(_ sender:NSButton) { self.setFiles(_files); } @IBAction func exportAction(_ sender:NSButton) { if (_files.count == 0) { let alert = NSAlert.init() alert.messageText = "无测试对比项导出"; alert.runModal(); return }else if (_showFiles.count == 0) { let alert = NSAlert.init() alert.messageText = "所有对比项均无差异"; alert.runModal(); return } let savePanel = NSSavePanel.init(); let checkBox = NSButton(checkboxWithTitle: "过滤无差异项", target: self, action: nil); checkBox.state = self.filterBtn.state; checkBox.frame = CGRectMake(0, 0, 150, 45); if #available(macOS 11.0, *) { savePanel.allowedContentTypes = [.pdf] } else { savePanel.allowedFileTypes = ["pdf", "PDF"] } savePanel.accessoryView = checkBox if (savePanel.runModal() == .OK) { var exportFiles = NSMutableArray() if (checkBox.state == .on) { for tfile in NSArray(array: _files) { let file = tfile as! NSMutableDictionary; let degree = file.degree() if (fabs(degree - 100) > 0) { exportFiles.add(file); } } if (exportFiles.count == 0) { let alert = NSAlert.init() alert.messageText = "所有对比项均无差异"; alert.runModal(); return } }else { exportFiles = NSMutableArray(array: _files) } let url = savePanel.url!; NSLog("\(url)") let pdf = PDFDocument.init(); let needFilter = checkBox.state == .on self.progressIndicator.isHidden = false; self.progressIndicator.doubleValue = 0; processNextImages(pdf, index: 0, files:exportFiles, url: url, needFilter: needFilter) } } // Save PDF func processNextImages(_ pdf:PDFDocument, index:Int32, files:NSMutableArray, url:URL, needFilter:Bool) -> Void { let file = files[Int(index)] as! NSMutableDictionary // NSLog("处理第\(index)页") // 所有文档均导出 let cell = ImageCompareCellView.shared() cell?.frame = CGRectMake(0, 0, CGRectGetWidth(self.listView.frame), 900); cell?.setFileInfo(file); self.closeBtn.isEnabled = false; DispatchQueue.global().async { autoreleasepool { let image = cell?.processCompareImage() if (image != nil) { let page = PDFPage.init(image: image!) let nPage = page?.copy() as! PDFPage pdf.insert(nPage, at: pdf.pageCount) } } let degree = file.degree() if (abs(degree - 100) > 0) { autoreleasepool { let image = cell?.processCoverImage() if (image != nil) { let page = PDFPage.init(image: image!) let nPage = page?.copy() as! PDFPage pdf.insert(nPage, at: pdf.pageCount) } } } if ((index+1) < files.count) { DispatchQueue.main.asyncAfter(deadline: DispatchTime.init(uptimeNanoseconds: 100)) { self.progressIndicator.doubleValue = Double(Int(index) * 100/files.count); self.processNextImages(pdf, index: index+1, files: files, url: url, needFilter: needFilter); }; }else { DispatchQueue.global().async { autoreleasepool { pdf.write(to: url) DispatchQueue.main.async { self.progressIndicator.isHidden = true; self.progressIndicator.doubleValue = 100.0; self.closeBtn.isEnabled = true; NSWorkspace.shared.activateFileViewerSelecting([url]) } } } } } } // Show func showIn(_ view:NSView, rect:NSRect) { if _popover == nil { _popover = NSPopover.init() _popover.contentViewController = self; _popover.delegate = self } _popover.contentSize = self.view.frame.size _popover.show(relativeTo: CGRectMake(rect.origin.x, rect.origin.y - rect.size.height, rect.size.width, rect.size.height/2), of: view, preferredEdge: NSRectEdge.minY) } // Getter & Setter func setFiles(_ files:NSArray) { _files = files if (self.filterBtn.state == .on) { _showFiles = NSMutableArray() for tfile in NSArray(array: _files) { let file = tfile as! NSMutableDictionary; let degree = file.degree() if (fabs(degree - 100) > 0) { _showFiles.add(file); } } }else { _showFiles = NSMutableArray (array: _files); } listView.reloadData() } // IBAction @IBAction func closeAction(_ sender: NSButton) { _popover.close() } // TableView Delegate func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? { return autoreleasepool { var cellView = tableView.makeView(withIdentifier: .init("ImageCompareCellView"), owner: nil) as! ImageCompareCellView? if (nil == cellView) { cellView = ImageCompareCellView.shared() ?? nil } if (_showFiles.count >= row) { let fileInfo = _showFiles[row] as! NSMutableDictionary cellView?.setFileInfo(fileInfo) } return cellView } } func selectionShouldChange(in tableView: NSTableView) -> Bool { return true } func tableView(_ tableView: NSTableView, shouldSelectRow row: Int) -> Bool { return false } func tableView(_ tableView: NSTableView, shouldSelect tableColumn: NSTableColumn?) -> Bool { return false } func tableView(_ tableView: NSTableView, mouseDownInHeaderOf tableColumn: NSTableColumn) { } func tableView(_ tableView: NSTableView, didClick tableColumn: NSTableColumn) { } func tableView(_ tableView: NSTableView, didDrag tableColumn: NSTableColumn) { } func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat { return 900 } func tableView(_ tableView: NSTableView, isGroupRow row: Int) -> Bool { return false } func tableView(_ tableView: NSTableView, sizeToFitWidthOfColumn column: Int) -> CGFloat { return tableView.frame.width } func tableView(_ tableView: NSTableView, rowActionsForRow row: Int, edge: NSTableView.RowActionEdge) -> [NSTableViewRowAction] { return [] } func tableViewSelectionDidChange(_ notification: Notification) { } // TableView Data Source func numberOfRows(in tableView: NSTableView) -> Int { if nil == _showFiles { return 0 } return _showFiles.count } // func popoverShouldClose(_ popover: NSPopover) -> Bool { return true } }