KMPDFRedactViewController.swift 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. //
  2. // KMPDFRedactViewController.swift
  3. // PDF Master
  4. //
  5. // Created by tangchao on 2023/12/18.
  6. //
  7. import Cocoa
  8. class KMPDFRedactViewController: NSViewController {
  9. var scaleFactor: CGFloat = 0
  10. var callback: ((Bool, Int, Bool, URL?)->Void)?
  11. var titleBack: ((String)->Void)?
  12. @IBOutlet var redactPdfView: KMRedactPDFView!
  13. @IBOutlet weak var redactTipLabel: NSTextField!
  14. @IBOutlet weak var propertiesLabel: NSTextField!
  15. @IBOutlet weak var redactTextLabel: NSTextField!
  16. @IBOutlet weak var exitBox: NSBox!
  17. @IBOutlet weak var applyBox: NSBox!
  18. @IBOutlet weak var exitButton: NSButton!
  19. @IBOutlet weak var applyButton: NSButton!
  20. @IBOutlet weak var toolView: NSView!
  21. @IBOutlet weak var redactTextBox: NSBox!
  22. @IBOutlet weak var propertiesBox: NSBox!
  23. @IBOutlet weak var redactTextButton: KMCustomButton!
  24. @IBOutlet weak var propertiesButton: KMCustomButton!
  25. private var _url: URL?
  26. private var url: URL? {
  27. get {
  28. return self._url
  29. }
  30. }
  31. private var _password: String?
  32. private var _indicator: NSProgressIndicator?
  33. deinit {
  34. KMPrint("KMPDFRedactViewController deinit.")
  35. NotificationCenter.default.removeObserver(self)
  36. self.redactPdfView.delegate = nil
  37. }
  38. convenience init(url: URL, password: String?) {
  39. self.init()
  40. self._url = url
  41. self._password = password
  42. }
  43. override func loadView() {
  44. super.loadView()
  45. self.propertiesBox.wantsLayer = true
  46. self.redactTextBox.wantsLayer = true
  47. self.redactTextBox.fillColor = KMAppearance.Layout.w30Color()
  48. self.redactTextBox.layer?.cornerRadius = 6
  49. self.redactTextLabel.textColor = KMAppearance.Layout.w0Color()
  50. self.propertiesLabel.textColor = KMAppearance.Layout.w0Color()
  51. self.redactTextLabel.stringValue = KMLocalizedString("Redact Text", nil)
  52. self.propertiesLabel.stringValue = KMLocalizedString("Properties", nil)
  53. self.propertiesButton.mouseMoveCallback = { [unowned self] mouseEntered in
  54. if mouseEntered {
  55. self.propertiesBox.fillColor = KMAppearance.Layout.w30Color()
  56. } else {
  57. self.propertiesBox.fillColor = .clear
  58. }
  59. }
  60. // Do view setup here.
  61. self.redactTipLabel.stringValue = KMLocalizedString("You are under redact mode", nil)
  62. self.applyButton.title = KMLocalizedString("Apply", nil)
  63. self.exitButton.toolTip = KMLocalizedString("Exit", nil)
  64. self.exitBox.fillColor = .clear
  65. self.exitBox.borderColor = KMAppearance.Layout.w70Color()
  66. self.exitBox.borderWidth = 1.0
  67. self.exitButton.title = KMLocalizedString("Exit", nil)
  68. self.exitButton.setTitleColor(KMAppearance.Layout.w0Color())
  69. self.applyButton.setTitleColor(KMAppearance.Interactive.a0Color())
  70. self.applyButton.wantsLayer = true
  71. self.toolView.wantsLayer = true
  72. self.toolView.layer?.backgroundColor = KMAppearance.Interactive.a0Color().cgColor
  73. let document = CPDFDocument(url: self.url!)
  74. if let pwd = self._password, pwd.isEmpty == false {
  75. document?.unlock(withPassword: pwd)
  76. }
  77. self.redactPdfView.document = document
  78. // self.redactPdfView.scaleFactor = self.scaleFactor;
  79. self.redactPdfView.autoScales = true
  80. self.redactPdfView.delegate = self
  81. self.redactPdfView.toolMode = .redactToolMode
  82. self.redactPdfView.operationType = .redact
  83. // [self.redactPdfView layoutDocumentView];
  84. let frame = CGRectMake((self.redactPdfView.frame.size.width-32)/2.0, (self.redactPdfView.frame.size.height-32)/2.0, 32, 32)
  85. self._indicator = NSProgressIndicator(frame: frame)
  86. self._indicator?.autoresizingMask = [.minXMargin, .maxXMargin, .minYMargin, .maxYMargin]
  87. self._indicator?.style = .spinning
  88. self._indicator?.controlSize = .regular
  89. self._indicator?.isIndeterminate = true
  90. self._indicator?.startAnimation(nil)
  91. self.redactPdfView.addSubview(self._indicator!)
  92. self._indicator?.isHidden = true
  93. }
  94. override func viewDidLoad() {
  95. super.viewDidLoad()
  96. // NotificationCenter.default.addObserver(self, selector: #selector(showCurrentRedactAnnotationProperties), name: KMPDFViewShowCurrentRedactAnnotation, object: nil)
  97. // NotificationCenter.default.addObserver(self, selector: #selector(apply), name: KMPDFViewRedactAnnotationApply, object: nil)
  98. // NotificationCenter.default.addObserver(self, selector: #selector(across), name: KMPDFViewRedactAnnotationAcross, object: nil)
  99. }
  100. func setCurrentPageIndex(_ currentPageIndex: Int) {
  101. self.redactPdfView.go(toPageIndex: currentPageIndex, animated: false)
  102. }
  103. // MARK: - Button Actions
  104. @IBAction func showProperties_button(_ sender: AnyObject?) {
  105. // KMRedactPropertiesWindowController *properties = [[ alloc] init];
  106. let properties = KMRedactPropertiesWindowController(windowNibName: "KMRedactPropertiesWindowController")
  107. self.km_beginSheet(windowC: properties)
  108. // [properties beginSheetModalForWindow:self.view.window completionHandler:^(CPDFRedactAnnotation *annotation) {
  109. //
  110. // }];
  111. }
  112. @IBAction func apply_button(_ sender: AnyObject?) {
  113. var isApply = false
  114. for i in 0 ..< self.redactPdfView.document.pageCount {
  115. let page = self.redactPdfView.document.page(at: i)
  116. for anno in page?.annotations ?? [] {
  117. if anno.isKind(of: CPDFRedactAnnotation.self) {
  118. isApply = true
  119. }
  120. }
  121. }
  122. // if(self.redactPdfView.newAddAnnotation.count == 0 && !isApply) return;
  123. if !isApply {
  124. return
  125. }
  126. let returnCode = KMAlertTool.runModelForMainThread_r(message: "", informative: KMLocalizedString("This will permanently remove the redacted information from this document. Once you save this document, you won’t be able to retrieve the redacted information.", nil), buttons: [KMLocalizedString("Apply", nil), KMLocalizedString("Cancel", nil)])
  127. if returnCode == .alertFirstButtonReturn {
  128. self.saveAsPath()
  129. }
  130. }
  131. @IBAction func exit_button(_ sender: AnyObject?) {
  132. guard let block = self.callback else {
  133. return
  134. }
  135. block(false, self.redactPdfView.currentPageIndex, false, nil)
  136. }
  137. func saveAsPath() {
  138. let saveAccessCtr = KMSavePanelAccessoryController()
  139. var fileName = self.redactPdfView.document.documentURL.deletingLastPathComponent().lastPathComponent
  140. fileName = String(format: "%@_%@.pdf", fileName, "Redact")
  141. let outputSavePanel = NSSavePanel()
  142. outputSavePanel.allowedFileTypes = ["pdf"]
  143. outputSavePanel.nameFieldStringValue = fileName
  144. outputSavePanel.accessoryView = saveAccessCtr.view
  145. outputSavePanel.beginSheetModal(for: NSApp.mainWindow!) { result in
  146. if result == .OK {
  147. self.redactPdfView.document.applyRedactions()
  148. self._indicator?.isHidden = false
  149. self._indicator?.startAnimation(nil)
  150. let savePDFPath = outputSavePanel.url!.path
  151. let isSuccess = self.redactPdfView.document.write(toFile: savePDFPath)
  152. if (isSuccess) {
  153. // [self.redactPdfView.newAddAnnotation removeAllObjects];
  154. if (saveAccessCtr.openAutomaticButton.state == .on) {
  155. NSDocumentController.shared.km_safe_openDocument(withContentsOf: outputSavePanel.url!, display: true) { _, _, _ in
  156. }
  157. } else {
  158. KMTools.viewFile(at: savePDFPath)
  159. }
  160. }
  161. self._indicator?.stopAnimation(nil)
  162. self._indicator?.isHidden = true
  163. guard let block = self.callback else {
  164. return
  165. }
  166. block(true, self.redactPdfView.currentPageIndex, false, outputSavePanel.url)
  167. }
  168. }
  169. }
  170. /*
  171. #pragma mark - Button notice
  172. - (void)showCurrentRedactAnnotationProperties:(NSNotification *)notice {
  173. KMRedactPDFView *pdfview = notice.object;
  174. if(pdfview && pdfview == self.redactPdfView) {
  175. KMRedactPropertiesWindowController *properties = [[KMRedactPropertiesWindowController alloc] init];
  176. properties.readactAnnotation = self.redactPdfView.currentAnnotation;
  177. __block KMPDFRedactViewController *weak_self = self;
  178. [properties beginSheetModalForWindow:self.view.window completionHandler:^(CPDFRedactAnnotation *annotation) {
  179. CPDFPage *page = [[weak_self.redactPdfView.currentAnnotation page] retain];
  180. [weak_self.redactPdfView.newAddAnnotation addObject:annotation];
  181. [weak_self.redactPdfView setNeedsDisplayAnnotationViewForPage:page];
  182. }];
  183. }
  184. }
  185. - (void)apply:(NSNotification *)notice {
  186. KMRedactPDFView *pdfview = notice.object;
  187. if(pdfview && pdfview == self.redactPdfView) {
  188. [self apply_button:nil];
  189. }
  190. }
  191. - (void)across:(NSNotification *)notice {
  192. KMRedactPDFView *pdfview = notice.object;
  193. if(pdfview && pdfview == self.redactPdfView) {
  194. __block KMPDFRedactViewController *weak_self = self;
  195. KMRedactSelectPagesWindowController *pagesWindowController = [[KMRedactSelectPagesWindowController alloc] initWithDocument:self.redactPdfView.document];
  196. [pagesWindowController beginSheetModalForWindow:self.view.window completionHandler:^(NSMutableArray * _Nonnull pages) {
  197. if(pages.count > 0) {
  198. [weak_self.redactPdfView acrossAddAnnotations:pages];
  199. }
  200. }];
  201. }
  202. }
  203. */
  204. }
  205. extension KMPDFRedactViewController: CPDFViewDelegate {
  206. func pdfViewCurrentPageDidChanged(_ pdfView: CPDFView!) {
  207. let fileName = pdfView.document.documentURL.deletingLastPathComponent().lastPathComponent
  208. let title = String(format: KMLocalizedString("%@ (page %ld / %ld)", "Window title format"), fileName, pdfView.currentPageIndex+1, pdfView.document.pageCount)
  209. if(self.titleBack != nil) {
  210. self.titleBack!(title)
  211. }
  212. }
  213. }