// // CompareViewController.swift // KdanAuto // // Created by 朱东勇 on 2023/2/2. // import Foundation import AppKit import PDFKit class StringCompareViewController: 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 sharedSCViewController : StringCompareViewController? = nil class func shared() -> StringCompareViewController { if nil == sharedSCViewController { var objects : NSArray! Bundle.main.loadNibNamed("StringCompareViewController", owner: nil, topLevelObjects: &objects) for tView in objects { if let tv = tView as? StringCompareViewController { sharedSCViewController = tv } } } return sharedSCViewController! } override func viewDidLoad() { self.listView.register(NSNib.init(nibNamed: NSNib.Name.init(NSString(string: "StringCompareCellView")), bundle: Bundle.main), forIdentifier: NSUserInterfaceItemIdentifier.init("StringCompareCellView")) } // 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 = [.rtf] } else { savePanel.allowedFileTypes = ["rtf", "rrtf"] } 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 attString = NSMutableAttributedString(string: ""); let needFilter = checkBox.state == .on self.progressIndicator.isHidden = false; self.progressIndicator.doubleValue = 0; processNextImages(attString, index: 0, files:exportFiles, url: url, needFilter: needFilter) } } // Save PDF func processNextImages(_ attString:NSMutableAttributedString, index:Int32, files:NSMutableArray, url:URL, needFilter:Bool) -> Void { let file = files[Int(index)] as! NSMutableDictionary let resultPath = NSString(string: file.resultPath()).appendingPathExtension("rtf")! let checkData = NSData.init(contentsOfFile: resultPath as String)! as Data var documentAttributes:NSDictionary! let tAttString = NSAttributedString.init(rtf: checkData, documentAttributes: &documentAttributes) if (tAttString != nil) { attString.append(NSMutableAttributedString(string: "\n\n")); attString.append(tAttString!) } self.closeBtn.isEnabled = false; DispatchQueue.global().async { if ((index+1) < files.count) { DispatchQueue.main.asyncAfter(deadline: DispatchTime.init(uptimeNanoseconds: 100)) { self.progressIndicator.doubleValue = Double(Int(index) * 100/files.count); self.processNextImages(attString, index: index+1, files: files, url: url, needFilter: needFilter); }; }else { DispatchQueue.global().async { autoreleasepool { // 写入文件 do { let rtfData = try? attString.data(from: .init(location: 0, length: attString.length), documentAttributes: [.documentType: NSAttributedString.DocumentType.rtf]) let path = NSString(string: resultPath).appendingPathExtension("rtf") try? FileManager.default.removeItem(at: url) try? rtfData?.write(to: url) } catch { } 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: rect, 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("StringCompareCellView"), owner: nil) as! StringCompareCellView? if (nil == cellView) { cellView = StringCompareCellView.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 { if (_showFiles.count > row) { let fileInfo = _showFiles[row] as! NSMutableDictionary return StringCompareCellView.heightFor(fileInfo) } return 0 } 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 } }