123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335 |
- //
- // KMSignatureViewController.swift
- // PDF Reader Pro
- //
- // Created by lxy on 2022/11/17.
- //
- import Cocoa
- @objc protocol KMSignatureViewControllerDelegate {
- @objc optional func removeDocumentSignatues(signatures:[CPDFSignature])
- }
- class KMSignatureViewController: NSViewController {
- @IBOutlet weak var sigOutlineView: KMOutlineView!
-
- @IBOutlet weak var deleteButton: NSButton!
- @IBOutlet weak var validationButton: NSButton!
- @IBOutlet weak var tipTextField: NSTextField!
- @IBOutlet weak var emptyLabel: NSTextField!
- @IBOutlet weak var emptyView: NSView!
- var listView : CPDFListView!
- var signatures : [CPDFSignature] = []
- open weak var delete: KMSignatureViewControllerDelegate?
-
- override func viewDidLoad() {
- super.viewDidLoad()
- // Do view setup here.
- self.view.wantsLayer = true
- self.view.layer?.backgroundColor = NSColor.yellow.cgColor
- self.tipTextField.stringValue = NSLocalizedString("Digitally Sign", comment: "");
- self.deleteButton.toolTip = NSLocalizedString("Delete", comment: "");
- self.validationButton.toolTip = NSLocalizedString("Validate All Signatures", comment: "");
- self.emptyLabel.stringValue = NSLocalizedString("No digital signature was added", comment: "");
- let signatures : [CPDFSignature] = self.listView.document.signatures() ?? []
- var mSignatures : [CPDFSignature] = []
- for sign in signatures {
- if sign.signers.count > 0 {
- mSignatures.append(sign)
- }
- }
- self.signatures = mSignatures
-
- self.sigOutlineView.delegate = self
- self.sigOutlineView.dataSource = self
- let menu = NSMenu()
- menu.delegate = self
- self.sigOutlineView.menu = menu
-
- self.sigOutlineView.doubleAction = #selector(tableViewAction)
- }
-
- //MAAK: Accessors
- public func reloadData() {
- self.sigOutlineView.reloadData()
- }
-
- private func outlineForItem(item:Any) -> [Any] {
- var itemChildren : [Any] = []
- if (item is String) && ((item as! String) == "") {
- if self.signatures.count > 0 {
- let lastSignates : CPDFSignature = self.signatures.last ?? CPDFSignature()
- if (lastSignates.permissions > 0) {
- var mutableArr : [Any] = self.signatures
- mutableArr.append(" \(NSLocalizedString("Already locked by", comment: ""))\(String(describing: lastSignates.fieldName))")
- itemChildren = mutableArr
- } else {
- itemChildren = self.signatures
- }
- } else {
- itemChildren = self.signatures
- }
- } else if (item is CPDFSignature) {
- itemChildren = (item as! CPDFSignature).numberOfChildren(document: self.listView.document)
- } else if (item is [String:Any]) {
- let key = (item as! [String:Any]).keys.first ?? ""
- itemChildren = (item as! [String:Any])[key] as! [Any]
- }
- return itemChildren
- }
-
- @IBAction func deleteButtonAction(_ sender: Any) {
- let alert = NSAlert()
- alert.alertStyle = .critical
- alert.messageText = NSLocalizedString("Are you sure you want to clear all signature fields in this document?", comment: "")
- alert.informativeText = NSLocalizedString("You cannot undo this operation.", comment: "")
- alert.addButton(withTitle: NSLocalizedString("Yes", comment: ""))
- alert.addButton(withTitle: NSLocalizedString("No", comment: ""))
- alert.beginSheetModal(for: self.view.window!, completionHandler: { result in
- if result != .OK {
-
- }
- })
- }
-
- @IBAction func validationButtonAction(_ sender: Any) {
-
- }
-
- @IBAction func jumpItemAction(item: NSMenuItem) {
- let indexSet : NSIndexSet = item.representedObject as! NSIndexSet
- let outlineItem = self.sigOutlineView.item(atRow: indexSet.firstIndex)
- if outlineItem is CPDFSignature {
- let index: Int = Int((outlineItem as! CPDFSignature).pageIndex(with: listView.document))
- if self.listView.currentPageIndex != index {
- self.listView.go(toPageIndex: index, animated: true)
- }
- }
- }
-
- @IBAction func removeItemAction(item:NSMenuItem) {
- let index : NSIndexSet = item.representedObject as! NSIndexSet
- let outlineItem = self.sigOutlineView.item(atRow: index.firstIndex)
- if outlineItem is CPDFSignature {
- let index: Int = Int((outlineItem as! CPDFSignature).pageIndex(with: listView.document))
- if self.listView.currentPageIndex != index {
- self.delete?.removeDocumentSignatues?(signatures: [outlineItem as! CPDFSignature])
- }
- }
- }
-
- @IBAction func validateItemAction(item:NSMenuItem) {
- let index : NSIndexSet = item.representedObject as! NSIndexSet
- let outlineItem = self.sigOutlineView.item(atRow: index.firstIndex)
- if outlineItem is CPDFSignature {
-
- }
- }
- @IBAction func showItemAction(item:NSMenuItem) {
- let index : NSIndexSet = item.representedObject as! NSIndexSet
- let outlineItem = self.sigOutlineView.item(atRow: index.firstIndex)
- if outlineItem is CPDFSignature {
- let index: Int = Int((outlineItem as! CPDFSignature).pageIndex(with: listView.document))
- if self.listView.currentPageIndex != index {
-
- }
- }
- }
-
- @IBAction func tableViewAction(sender:Any) {
- let row = self.sigOutlineView.clickedRow
- if (row >= 0) && (row < self.signatures.count) {
- let outlineItem : CPDFSignature = self.sigOutlineView.item(atRow: row) as! CPDFSignature
- let index: Int = Int((outlineItem).pageIndex(with: listView.document))
- if self.listView.currentPageIndex != index {
-
- if self.listView.currentPageIndex != index {
- self.listView.go(toPageIndex: index, animated: true)
- }
- }
- }
- }
-
- }
- extension KMSignatureViewController : NSOutlineViewDelegate,NSOutlineViewDataSource {
- func outlineView(_ outlineView: NSOutlineView, numberOfChildrenOfItem item: Any?) -> Int {
- var count = self.outlineForItem(item: item ?? "").count
- if case Optional<Any>.none = item {
- if count > 0 {
- self.emptyView.isHidden = true
- self.deleteButton.isEnabled = true
- self.validationButton.isEnabled = true
- } else {
- self.emptyView.isHidden = false
- self.deleteButton.isEnabled = false
- self.validationButton.isEnabled = false
- }
- } else if item is [String:Any] {
- count = 1
- }
- return count
- }
-
- func outlineView(_ outlineView: NSOutlineView, child index: Int, ofItem item: Any?) -> Any {
- return self.outlineForItem(item: item ?? "")[index]
- }
-
- func outlineView(_ outlineView: NSOutlineView, isItemExpandable item: Any) -> Bool {
- return self.outlineForItem(item: item).count > 0
- }
-
- func outlineView(_ outlineView: NSOutlineView, shouldShowOutlineCellForItem item: Any) -> Bool {
- return true
- }
-
- func outlineView(_ outlineView: NSOutlineView, viewFor tableColumn: NSTableColumn?, item: Any) -> NSView? {
- let cell : KMSignatureCellView = outlineView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "KMSignatureCellView"), owner: self) as! KMSignatureCellView
- var contentString = ""
- if item is CPDFSignature {
- let signer : CPDFSigner = (item as! CPDFSignature).signers.first ?? CPDFSigner()
- contentString = "\(NSLocalizedString("Signature by", comment: ""))\(signer.timestampSignature.name ?? "")"
- if signer.isSignVerified && signer.isCertTrusted {
- cell.signatureImageView.image = NSImage(named: "KMImageNameSigntureVerifySuccess")
- } else if signer.isSignVerified && !signer.isCertTrusted {
- cell.signatureImageView.image = NSImage(named: "KMImageNameSigntureVerifySuccess")
- } else {
- cell.signatureImageView.image = NSImage(named: "KMImageNameSigntureVerifySuccess")
- }
- cell.signatureImageView.isHidden = false
- cell.leftOffset.constant = 36
- cell.contenLabel.font = NSFont.systemFont(ofSize: 13)
- } else if item is String {
- cell.signatureImageView.isHidden = true
- cell.leftOffset.constant = 4
- cell.contenLabel.font = NSFont.systemFont(ofSize: 12)
- contentString = item as! String
- } else if item is [String:Any] {
- cell.signatureImageView.isHidden = true
- cell.leftOffset.constant = 4
- cell.contenLabel.font = NSFont.systemFont(ofSize: 12)
- contentString = (item as! [String:Any]).keys.first ?? ""
- }
- cell.contenLabel.stringValue = contentString
- return cell
- }
-
- func outlineView(_ outlineView: NSOutlineView, rowViewForItem item: Any) -> NSTableRowView? {
- let rowView = KMCustomTableRowView()
- return rowView
- }
-
- func outlineView(_ outlineView: NSOutlineView, heightOfRowByItem item: Any) -> CGFloat {
- var contentString = ""
- var font = NSFont.systemFont(ofSize: 12)
- if item is CPDFSignature {
- let signer = (item as! CPDFSignature).signers.first
- contentString = "\(NSLocalizedString("Signature by", comment: ""))\(String(describing: signer?.timestampSignature.name))"
- font = NSFont.systemFont(ofSize: 13)
- } else if (item is String){
- contentString = item as! String
- } else if (item is [String : Any]) {
- contentString = (item as! [String:Any]).keys.first ?? ""
- }
-
- let paragraphStyle = NSMutableParagraphStyle()
- paragraphStyle.lineBreakMode = .byWordWrapping
- var attribute = [NSAttributedString.Key.font : font, NSAttributedString.Key.paragraphStyle : paragraphStyle]
- let rect = NSString(string: contentString).boundingRect(with: NSSize(width: outlineView.frame.size.width-20, height:CGFloat(MAXFLOAT)),options: NSString.DrawingOptions(rawValue: 3), attributes: attribute).size
- if(rect.height < 40) {
- return 40
- } else {
- return rect.height
- }
- }
-
- func outlineView(_ outlineView: NSOutlineView, shouldSelect tableColumn: NSTableColumn?) -> Bool {
-
- return true
- }
- }
- //MARK: NSMenuDelegate
- extension KMSignatureViewController : NSMenuDelegate {
- func menuNeedsUpdate(_ menu: NSMenu) {
- menu.removeAllItems()
- let clickedRow = self.sigOutlineView.clickedRow
- let item = self.sigOutlineView.item(atRow: clickedRow)
- if clickedRow > 0 && (item is CPDFSignature) {
- var item = NSMenuItem()
- item = menu.addItem(withTitle: NSLocalizedString("Jump To The Signature Field", comment: ""), action: #selector(jumpItemAction), target: self)!
- item.representedObject = NSIndexSet(index: clickedRow)
- menu.addItem(NSMenuItem.separator())
- item = menu.addItem(withTitle: NSLocalizedString("Remove Signature", comment: ""), action: #selector(removeItemAction), target: self)!
- item.representedObject = NSIndexSet(index: clickedRow)
- item = menu.addItem(withTitle: NSLocalizedString("Remove Signature", comment: ""), action: #selector(validateItemAction), target: self)!
- item.representedObject = NSIndexSet(index: clickedRow)
- menu.addItem(NSMenuItem.separator())
- item = menu.addItem(withTitle: NSLocalizedString("Show Signature Properties…", comment: ""), action: #selector(showItemAction), target: self)!
- item.representedObject = NSIndexSet(index: clickedRow)
- }
- }
- }
- //MARK: CPDFSignature
- extension CPDFSignature {
- func numberOfChildren(document:CPDFDocument) -> [Any] {
- var datas : [Any] = []
- let signer = self.signers.first
-
- var validString = ""
- if signer?.isSignVerified != nil {
- validString = NSLocalizedString("Signature is valid", comment: "")
- } else {
- validString = NSLocalizedString("Signature is invalid", comment: "")
- }
-
- var certTrusted = ""
- if signer?.isCertTrusted != nil {
- certTrusted = NSLocalizedString("Signer's identity is valid", comment: "")
- } else {
- certTrusted = NSLocalizedString("Signer's identity is invalid", comment: "")
- }
-
- var timestampSigners = ""
- if signer?.timestampSignature.signers != nil {
- let tSign = signer?.timestampSignature.signers.first
- if tSign?.isSignVerified != nil && tSign?.isSignVerified != nil {
- timestampSigners = NSLocalizedString("The signature includes an embedded timestamp.", comment: "")
- } else {
- timestampSigners = NSLocalizedString("The signature includes an embedded timestamp but it could not be verified.", comment: "")
- }
- }
-
- var str3 = "\(validString)\n\n \(certTrusted)"
- if timestampSigners.lengthOfBytes(using: String.Encoding(rawValue: String.Encoding.utf16.rawValue)) > 0 {
- str3 = "\(str3)\n\n \(timestampSigners)"
- }
- datas.append(str3)
-
- var dic : [String:Any] = [:]
- let array = [NSLocalizedString("Certificate Details...", comment: ""),signer ?? CPDFSigner()] as [Any]
- dic[NSLocalizedString("Signature Details...", comment: "")] = array
- datas.append(dic)
- if signer?.timestampSignature.signers != nil && signer?.timestampSignature.signers.first?.authenDate != nil{
- var dateFormatter = DateFormatter()
- dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
- let strDate = dateFormatter.string(from: signer?.timestampSignature.signers.first?.authenDate ?? Date())
- datas.append("\(NSLocalizedString("Last Checked:", comment: ""))\(strDate)")
- } else {
- datas.append("\(NSLocalizedString("Last Checked:", comment: ""))\(NSLocalizedString("Never", comment: ""))")
- }
- let pageIndex = self.pageIndex(with: document)
- datas.append("\(NSLocalizedString("Field:", comment: ""))\(self.fieldName.description)\(NSLocalizedString("on Page", comment: ""))\(pageIndex+1)")
- return datas
- }
- }
|