123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327 |
- //
- // KMPDFRedactViewController.swift
- // PDF Reader Pro
- //
- // Created by tangchao on 2023/12/18.
- //
- import Cocoa
- class KMPDFRedactViewController: NSViewController {
-
- var scaleFactor: CGFloat = 0 {
- didSet {
- self.redactPdfView.scaleFactor = scaleFactor
- }
- }
-
- var callback: ((Bool, Int, Bool, URL?)->Void)?
- var titleBack: ((String)->Void)?
-
- @IBOutlet var redactPdfView: KMRedactPDFView!
-
- @IBOutlet weak var redactTipLabel: NSTextField!
- @IBOutlet weak var propertiesLabel: NSTextField!
- @IBOutlet weak var redactTextLabel: NSTextField!
- @IBOutlet weak var exitBox: KMBox!
- @IBOutlet weak var applyBox: KMBox!
- @IBOutlet weak var exitButton: NSButton!
- @IBOutlet weak var applyButton: NSButton!
- @IBOutlet weak var toolView: NSView!
- @IBOutlet weak var redactTextBox: NSBox!
- @IBOutlet weak var propertiesBox: NSBox!
-
- @IBOutlet weak var redactTextButton: KMCustomButton!
- @IBOutlet weak var propertiesButton: KMCustomButton!
-
- @IBOutlet weak var whiteOutBox: NSBox!
- @IBOutlet weak var whiteOutLabel: NSTextField!
- @IBOutlet weak var whiteOutButton: KMCustomButton!
-
- private var _url: URL?
- private var url: URL? {
- get {
- return self._url
- }
- }
- private var _password: String?
- private var _indicator: NSProgressIndicator?
-
- private var isWhiteOut_ = false
- deinit {
- KMPrint("KMPDFRedactViewController deinit.")
-
- NotificationCenter.default.removeObserver(self)
- self.redactPdfView.delegate = nil
- }
-
- convenience init(url: URL, password: String?) {
- self.init()
-
- self._url = url
- self._password = password
- }
-
- override func loadView() {
- super.loadView()
- self.isWhiteOut_ = false
-
- self.propertiesBox.wantsLayer = true
- self.redactTextBox.wantsLayer = true
- self.redactTextBox.fillColor = KMAppearance.Layout.w30Color()
- self.redactTextBox.layer?.cornerRadius = 6
- self.redactTextLabel.textColor = KMAppearance.Layout.w0Color()
- self.propertiesLabel.textColor = KMAppearance.Layout.w0Color()
- self.redactTextLabel.stringValue = KMLocalizedString("Redact Text")
- self.propertiesLabel.stringValue = KMLocalizedString("Properties")
-
- self.propertiesButton.mouseMoveCallback = { [weak self] mouseEntered in
- self?.propertiesBox.layer?.cornerRadius = 6
- if mouseEntered {
- self?.propertiesBox.fillColor = KMAppearance.Layout.w30Color()
- } else {
- self?.propertiesBox.fillColor = .clear
- }
- }
-
- self.whiteOutBox.wantsLayer = true
- // self.whiteOutBox.fillColor = KMAppearance.Layout.w30Color()
- self.whiteOutBox.layer?.cornerRadius = 6
- self.whiteOutLabel.textColor = KMAppearance.Layout.w0Color()
- self.whiteOutLabel.stringValue = NSLocalizedString("White Out PDF", comment: "")
-
- self.redactTextButton.target = self
- self.redactTextButton.action = #selector(redactButtonAction)
- self.whiteOutButton.target = self
- self.whiteOutButton.action = #selector(whiteOutButtonAction)
-
- // Do view setup here.
- self.redactTipLabel.stringValue = KMLocalizedString("You are under redact mode")
- self.applyButton.title = KMLocalizedString("Apply")
- self.exitButton.toolTip = KMLocalizedString("Exit")
- self.exitBox.fillColor = .clear
- self.exitBox.borderColor = KMAppearance.Layout.w70Color()
- self.exitBox.borderWidth = 1.0
- self.exitButton.title = KMLocalizedString("Exit")
- self.exitButton.setTitleColor(KMAppearance.Layout.w0Color())
-
- self.applyButton.setTitleColor(KMAppearance.Interactive.a0Color())
- self.applyButton.wantsLayer = true
-
- self.applyBox.downCallback = { [weak self] downEntered, mouseBox, event in
- if downEntered {
- self?.apply_button(nil)
- }
- }
-
- self.exitBox.downCallback = { [weak self] downEntered, mouseBox, event in
- if downEntered {
- self?.exit_button(nil)
- }
- }
- self.toolView.wantsLayer = true
- self.toolView.layer?.backgroundColor = KMAppearance.Interactive.a0Color().cgColor
-
- let document = CPDFDocument(url: self.url!)
- if let pwd = self._password, pwd.isEmpty == false {
- document?.unlock(withPassword: pwd)
- }
- self.redactPdfView.document = document
- // self.redactPdfView.scaleFactor = self.scaleFactor;
- self.redactPdfView.autoScales = true
- self.redactPdfView.delegate = self
- // self.redactPdfView.toolMode = .redactToolMode
- self.redactPdfView.operationType = .redact
-
- // [self.redactPdfView layoutDocumentView];
- let frame = NSMakeRect((self.redactPdfView.frame.size.width-32)/2.0, (self.redactPdfView.frame.size.height-32)/2.0, 32, 32)
- self._indicator = NSProgressIndicator(frame: frame)
- self._indicator?.autoresizingMask = [.minXMargin, .maxXMargin, .minYMargin, .maxYMargin]
- self._indicator?.style = .spinning
- self._indicator?.controlSize = .regular
- self._indicator?.isIndeterminate = true
- self._indicator?.startAnimation(nil)
- self.redactPdfView.addSubview(self._indicator!)
- self._indicator?.isHidden = true
- }
-
- override func viewDidLoad() {
- super.viewDidLoad()
-
- NotificationCenter.default.addObserver(self, selector: #selector(showCurrentRedactAnnotationProperties), name: KMRedactPDFView.showCurrentRedactAnnotationNotificationName, object: nil)
- NotificationCenter.default.addObserver(self, selector: #selector(apply), name: KMRedactPDFView.redactAnnotationApplyNotificationName, object: nil)
- NotificationCenter.default.addObserver(self, selector: #selector(across), name: KMRedactPDFView.redactAnnotationAcrossNotificationName, object: nil)
- }
-
- func setCurrentPageIndex(_ currentPageIndex: Int) {
- self.redactPdfView.go(toPageIndex: currentPageIndex, animated: false)
- }
-
- // MARK: - Button Actions
- @IBAction func showProperties_button(_ sender: AnyObject?) {
- FMTrackEventManager.defaultManager.trackEvent(event: "SubTbr_RedactText", withProperties: ["SubTbr_Btn": "Btn_SubTbr_RedactText_Properties"])
-
- let properties = KMRedactPropertiesWindowController()
- self.km_beginSheet(windowC: properties)
- properties.callback = { annotation in
-
- }
- }
- @IBAction func apply_button(_ sender: AnyObject?) {
- var isApply = false
- for i in 0 ..< self.redactPdfView.document.pageCount {
- let page = self.redactPdfView.document.page(at: i)
- for anno in page?.annotations ?? [] {
- if anno.isKind(of: CPDFRedactAnnotation.self) {
- isApply = true
- }
- }
- }
- if(self.redactPdfView.newAddAnnotation.count == 0 && !isApply) {
- return
- }
- 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."), buttons: [KMLocalizedString("Apply"), KMLocalizedString("Cancel")])
- if returnCode == .alertFirstButtonReturn {
- DispatchQueue.main.async {
- self.saveAsPath()
- }
- }
- }
-
- @IBAction func exit_button(_ sender: AnyObject?) {
- guard let block = self.callback else {
- return
- }
- block(false, self.redactPdfView.currentPageIndex, false, nil)
- }
- func saveAsPath() {
- let saveAccessCtr = KMSavePanelAccessoryController()
- var fileName = self.redactPdfView.document.documentURL.deletingPathExtension().lastPathComponent
- fileName = String(format: "%@_%@.pdf", fileName, "Redact")
- let outputSavePanel = NSSavePanel()
- outputSavePanel.allowedFileTypes = ["pdf"]
- outputSavePanel.nameFieldStringValue = fileName
- outputSavePanel.accessoryView = saveAccessCtr.view
- outputSavePanel.beginSheetModal(for: NSApp.mainWindow!) { result in
- if result == .OK {
- self.redactPdfView.document.applyRedactions()
- self._indicator?.isHidden = false
- self._indicator?.startAnimation(nil)
- let savePDFPath = outputSavePanel.url!.path
- let isSuccess = self.redactPdfView.document.write(toFile: savePDFPath)
- if (isSuccess) {
- // [self.redactPdfView.newAddAnnotation removeAllObjects];
- if (saveAccessCtr.openAutomaticButton.state == .on) {
- NSDocumentController.shared.km_safe_openDocument(withContentsOf: outputSavePanel.url!, display: true) { _, _, _ in
-
- }
- } else {
- KMTools.viewFile(at: savePDFPath)
- }
- }
- self._indicator?.stopAnimation(nil)
- self._indicator?.isHidden = true
- guard let block = self.callback else {
- return
- }
- block(true, self.redactPdfView.currentPageIndex, false, outputSavePanel.url)
- }
- }
- }
- // MARK: - Button notice
-
- @objc func showCurrentRedactAnnotationProperties(_ notice: NSNotification) {
- guard let pdfview = notice.object as? KMRedactPDFView else {
- return
- }
- if(pdfview == self.redactPdfView) {
- let properties = KMRedactPropertiesWindowController()
- properties.readactAnnotation = self.redactPdfView.currentAnnotation
- // __block KMPDFRedactViewController *weak_self = self;
- self.km_beginSheet(windowC: properties)
- properties.callback = { [weak self] annotation in
- if let page = self?.redactPdfView.currentAnnotation?.page {
- if let anno = annotation {
- self?.redactPdfView.newAddAnnotation.append(anno)
- }
- self?.redactPdfView.setNeedsDisplayAnnotationViewFor(page)
- }
- }
- }
- }
-
- @objc func apply(_ notice: NSNotification) {
- guard let pdfview = notice.object as? KMRedactPDFView else {
- return
- }
- if(pdfview == self.redactPdfView) {
- self.apply_button(nil)
- }
- }
-
- @objc func across(_ notice: NSNotification) {
- guard let pdfview = notice.object as? KMRedactPDFView else {
- return
- }
-
- if(pdfview == self.redactPdfView) {
- let pagesWindowController = KMRedactSelectPagesWindowController(document: self.redactPdfView.document)
- self.km_beginSheet(windowC: pagesWindowController)
- pagesWindowController.callback = { [unowned self] pages in
- if pages.count > 0 {
- self.redactPdfView.acrossAddAnnotations(pages)
- }
- }
- }
- }
-
- @objc func redactButtonAction(sender : NSButton) {
- FMTrackEventManager.defaultManager.trackEvent(event: "SubTbr_RedactText", withProperties: ["SubTbr_Btn": "Btn_SubTbr_RedactText_RedactPDF"])
-
- self.isWhiteOut_ = false
- self.redactPdfView.isWhiteOut = false
- self.updateButtonsState()
- }
-
- @objc func whiteOutButtonAction(sender: NSButton) {
- FMTrackEventManager.defaultManager.trackEvent(event: "SubTbr_RedactText", withProperties: ["SubTbr_Btn": "Btn_SubTbr_RedactText_WhiteOutPDF"])
-
- self.isWhiteOut_ = true
- self.redactPdfView.isWhiteOut = true
- self.updateButtonsState()
- }
-
- // MARK: - Private Methods
-
- private func updateButtonsState() {
- if self.isWhiteOut_ {
- self.whiteOutBox.fillColor = KMAppearance.Layout.w30Color()
- self.redactTextBox.fillColor = .clear
- } else {
- self.redactTextBox.fillColor = KMAppearance.Layout.w30Color()
- self.whiteOutBox.fillColor = .clear
- }
- }
-
- }
- extension KMPDFRedactViewController: CPDFViewDelegate {
- func pdfViewCurrentPageDidChanged(_ pdfView: CPDFView!) {
- let fileName = pdfView.document.documentURL.deletingLastPathComponent().lastPathComponent
- let title = String(format: KMLocalizedString("%@ (page %ld / %ld)"), fileName, pdfView.currentPageIndex+1, pdfView.document.pageCount)
- if(self.titleBack != nil) {
- self.titleBack!(title)
- }
- }
- }
|