123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429 |
- //
- // CustomStampWindowController.swift
- // PDF Reader Pro
- //
- // Created by Niehaoyu on 2024/6/19.
- //
- import Cocoa
- class CustomStampWindowController: NSWindowController, CPDFViewDelegate, CPDFListViewDelegate, NSWindowDelegate {
- @IBOutlet var contendView: NSView!
- @IBOutlet var leftContendView: NSView!
- @IBOutlet var pdfContendView: NSView!
- @IBOutlet var rightContendView: NSView!
- @IBOutlet var topContendView: NSView!
-
- @IBOutlet var cancelButton: NSButton!
- @IBOutlet var addStampButton: NSButton!
-
- var topToolbar: CustomStampTopToolbar!
- var leftToolbar: CustomStampLeftToolbar!
- var pdfView: CPDFListView!
- var rightToolbar: CustomStampRightToolbar!
-
- var eventMonitor: Any?
-
- static var currentWindowController: CustomStampWindowController!
-
- var stampListWC: CSStampListWindowController!
-
- var clickHandle: ((_ windowVC: CustomStampWindowController, _ actionType: Int, _ resultImage: NSImage?)->Void)?
-
- @objc static func currentWC() -> CustomStampWindowController {
- if currentWindowController != nil {
- return currentWindowController
- } else {
- let configWC: CustomStampWindowController = CustomStampWindowController.init(windowNibName: "CustomStampWindowController")
- currentWindowController = configWC;
- return currentWindowController
- }
- }
-
- deinit {
- NotificationCenter.default.removeObserver(self)
- print("\(self.className) deinit")
- }
-
- override func windowDidLoad() {
- super.windowDidLoad()
- // Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
-
- self.window?.delegate = self
- self.window?.title = NSLocalizedString("Create Custom Stamp", comment: "")
-
- self.addEventMonitor()
-
- self.configPDFContendView()
-
- self.configTopToolbar()
- self.configLeftToolbar()
- self.configRightToolbar()
-
- self.cancelButton.title = NSLocalizedString("Cancel", comment: "")
- self.addStampButton.title = NSLocalizedString("Add Stamp", comment: "")
-
- self.updateViewColor()
-
- self.window?.makeFirstResponder(self.pdfView)
- }
-
- func reloadData() {
-
- self.topToolbar.reloadData()
- self.leftToolbar.reloadData()
- self.rightToolbar.reloadData()
-
- self.updateRightToolBarInfo()
- }
-
-
- func configPDFContendView() {
-
- let pdfDocument = CPDFDocument()
- pdfDocument?.insertBlankPage(pageSize: NSSize(width: 250, height: 200), at: 0)
-
- self.pdfView = CPDFListView(frame: self.pdfContendView.bounds)
- self.pdfView.autoresizingMask = [.width, .height]
- self.pdfView.document = pdfDocument
- self.pdfView.delegate = self
- self.pdfView.pdfListViewDelegate = self
- self.pdfView.autoScales = false
- self.pdfView.scaleFactor = 1
- self.pdfView.isCustomStampType = "1"
-
- self.pdfContendView.wantsLayer = true
- self.pdfContendView.layer?.cornerRadius = 4
- self.pdfContendView.layer?.masksToBounds = true
- self.pdfContendView.layer?.borderWidth = 1
- self.pdfContendView.addSubview(self.pdfView)
-
-
- NotificationCenter.default.addObserver(self, selector: #selector(CPDFListViewActiveAnnotationsChangeNotification), name: NSNotification.Name.init(rawValue: "CPDFListViewActiveAnnotationsChangeNotification"), object: nil)
- }
-
- func configTopToolbar() {
- self.topToolbar = CustomStampTopToolbar.createFromNib()
- self.topToolbar.frame = self.topContendView.bounds
- self.topToolbar.autoresizingMask = [.width, .height]
- self.topToolbar.pdfView = self.pdfView
-
- self.topContendView.addSubview(self.topToolbar)
-
- }
-
- func configLeftToolbar() {
- self.leftToolbar = CustomStampLeftToolbar.createFromNib()
- self.leftToolbar.frame = self.leftContendView.bounds
- self.leftToolbar.autoresizingMask = [.width, .height]
- self.leftToolbar.clickHandle = {[weak self] view , toolbarType, string in
-
- self?.pdfView.customStampAnnotationType = String(toolbarType.rawValue)
-
- if toolbarType == .move {
- self?.pdfView.annotationType = .unkown
- }else if toolbarType == .text ||
- toolbarType == .dateText ||
- toolbarType == .idText {
- self?.pdfView.toolMode = .noteToolMode
- self?.pdfView.annotationType = .freeText
- if string.isEmpty == false {
- self?.pdfView.customStampTextValue = string
- }
- } else if toolbarType == .image {
- self?.pdfView.toolMode = .noteToolMode
- self?.pdfView.annotationType = .stamp
- self?.chooseImage()
- } else if toolbarType == .stamp {
- self?.pdfView.toolMode = .noteToolMode
- self?.chooseStamp()
- }
-
-
- }
-
- self.leftContendView.addSubview(self.leftToolbar)
-
- }
-
- func configRightToolbar() {
- self.rightToolbar = CustomStampRightToolbar.createFromNib()
- self.rightToolbar.frame = self.rightContendView.bounds
- self.rightToolbar.autoresizingMask = [.width, .height]
- self.rightToolbar.pdfView = self.pdfView
- self.rightToolbar.delegate = self
-
- self.rightContendView.addSubview(self.rightToolbar)
- }
-
- func updateViewColor() {
-
- if KMAppearance.isDarkMode() {
- self.window?.backgroundColor = NSColor(red: 38/255, green: 40/255, blue: 43/255, alpha: 1)
- self.pdfContendView.layer?.borderColor = NSColor.white.withAlphaComponent(0.05).cgColor
- self.pdfView.backgroundColor = NSColor(red: 47/255, green: 49/255, blue: 51/255, alpha: 1)
-
- } else {
- self.window?.backgroundColor = NSColor.white
- self.pdfContendView.layer?.borderColor = NSColor.black.withAlphaComponent(0.06).cgColor
- self.pdfView.backgroundColor = NSColor(red: 245/255, green: 245/255, blue: 245/255, alpha: 1)
-
- }
- }
-
- private func addEventMonitor() {
- if (self.eventMonitor != nil) {
- self.removeEventMonitor()
- }
-
- DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.3) {
- KMPrint("已添加事件监听")
- self.eventMonitor = NSEvent.addLocalMonitorForEvents(matching: [.scrollWheel, .leftMouseDown]) { [weak self] event in
- if (event.type == .scrollWheel && event.modifierFlags.contains(.option)) { // Alt + 鼠标滚轮
- self?.pdfView.magnifyWheel(event)
- return nil
- }
- return event
- }
- }
- }
-
- private func removeEventMonitor() {
- if (self.eventMonitor != nil) {
- KMPrint("已移除事件监听")
-
- NSEvent.removeMonitor(self.eventMonitor as Any)
- self.eventMonitor = nil
- }
- }
-
- func clear() {
- self.removeEventMonitor()
- CustomStampWindowController.currentWindowController = nil
- NotificationCenter.default.removeObserver(self)
- }
-
- //MARK: Private Method
- func chooseImage() {
- let accessoryCtr = KMImageAccessoryController()
- let openPanel = NSOpenPanel()
- openPanel.allowedFileTypes = KMImageAccessoryController.supportedImageTypes()
- openPanel.allowsMultipleSelection = false
- openPanel.accessoryView = accessoryCtr.view
- openPanel.canSelectHiddenExtension = true
- openPanel.beginSheetModal(for: self.window!) { [weak self] (result) in
- if result == .OK {
- guard let url = openPanel.url else {
- return
- }
- let filePath = url.path
- if filePath.pathExtension.lowercased() == "pdf" {
- if let pdf = PDFDocument(url: url), pdf.isEncrypted {
- NSSound.beep()
- return
- }
- }
-
- let stamp = CStampObject(imageStampFilePath: filePath)
- stamp.nameString = ""
- self?.pdfView.setAddStamp(stamp, keepToolModel: true)
- self?.updateRightToolBarInfo()
- } else {
- self?.leftToolbar.toolbarType = .move
- self?.leftToolbar.reloadData()
- }
- }
- }
-
- func chooseStamp() {
- self.stampListWC = CSStampListWindowController.currentWC()
- self.stampListWC.clickHandle = {[weak self] view , actionType, filePath in
- if actionType == 0 {
- self?.leftToolbar.toolbarType = .move
- self?.leftToolbar.reloadData()
- } else if actionType == 1 {
-
- self?.pdfView.annotationType = .stamp
- let stamp = CStampObject(imageStampFilePath: filePath!)
- stamp.nameString = ""
- self?.pdfView.setAddStamp(stamp, keepToolModel: true)
-
- self?.updateRightToolBarInfo()
-
- }
- self?.window?.endSheet(view.window!)
- }
-
- self.window!.beginSheet(self.stampListWC.window!, completionHandler: {[weak self] response in
- self?.stampListWC.reloadData()
- })
-
- }
-
- func updateRightToolBarInfo() {
- if self.pdfView?.activeAnnotations.count == 0 {
- self.rightToolbar.currentAnnotation = nil
- } else {
- self.rightToolbar.currentAnnotation = self.pdfView.activeAnnotation
- }
-
- let page = self.pdfView?.document?.page(at: 0)
- if page?.annotations.isEmpty == false {
- self.addStampButton.isEnabled = true
- self.addStampButton.bezelColor = NSColor.controlAccentColor
- } else {
- self.addStampButton.isEnabled = false
- self.addStampButton.bezelColor = self.cancelButton.bezelColor
- }
-
- }
-
- @objc func cropCurrentPage() {
- var rect = NSIntegralRect(self.pdfView.currentSelectionRect())
- var page: CPDFPage?
- if let data = self.pdfView.currentSelectionPage() {
- page = data
- } else {
- page = self.pdfView.currentPage()
- }
- if (NSIsEmptyRect(rect)) {
- rect = KMCropTools.getPageForegroundBox(page!)
- }
-
- let index: UInt = (page?.pageIndex()) ?? 0
- self._cropPage(at: index, in: rect)
- }
-
- @objc private func _cropPage(at index: UInt, in rect: NSRect) {
- let oldRect = self.pdfView?.document?.page(at: index)?.bounds(for: .cropBox) ?? .zero
- let undoManager = self.pdfView.undoManager
- (undoManager?.prepare(withInvocationTarget: self) as? AnyObject)?._cropPage(at: index, in: oldRect)
-
- let page = self.pdfView.document.page(at: index)
- let newRect = NSIntersectionRect(rect, (page?.bounds(for: .mediaBox)) ?? .zero)
- page?.setBounds(newRect, for: .cropBox)
-
- /// 刷新预览视图
- self.pdfView.layoutDocumentView()
- self.pdfView.displayBox = .cropBox
- }
-
- //MARK: IBAction
- @IBAction func cancelAction(_ sender: Any) {
- guard let callBack = self.clickHandle else {
- return
- }
- callBack(self, 0, nil)
- }
-
- @IBAction func addStampAction(_ sender: Any) {
- guard let page = self.pdfView.document.page(at: 0) else {
- return
- }
- for anno in page.annotations ?? [] {
- self.pdfView.setNeedsDisplay(anno)
- }
-
- self.cropCurrentPage()
-
- let image = page.thumbnail(of: CGSizeMake(page.size.width*4, page.size.height*4))
- guard let callBack = self.clickHandle else {
- return
- }
- callBack(self, 1, image)
- }
-
- //MARK: CPDFListViewDelegate & Notification
-
- func pdfViewScaleDidChanged(_ pdfView: CPDFView!) {
-
- self.topToolbar?.pdfViewScaleChanged()
-
- }
-
- @objc func CPDFListViewActiveAnnotationsChangeNotification(notification: NSNotification) {
- if notification.object is CPDFListView {
- let listView : CPDFListView = notification.object as! CPDFListView
- if listView.isEqual(self.pdfView) {
- self.updateRightToolBarInfo()
- }
- }
- }
-
- func pdfListViewAddAnnotations(_ pdfListView: CPDFListView!, forAdd annotations: [CPDFAnnotation]!, in pdfPage: CPDFPage!) {
- if self.leftToolbar.toolbarType != .move {
- self.leftToolbar.toolbarType = .move
- self.leftToolbar.reloadData()
- }
-
- }
-
- override func showWindow(_ sender: Any?) {
- super.showWindow(sender)
-
- }
-
- override func close() {
- super.close()
-
- self.removeEventMonitor()
- CustomStampWindowController.currentWindowController = nil
- NotificationCenter.default.removeObserver(self)
-
- }
-
- func windowShouldClose(_ sender: NSWindow) -> Bool {
-
- self.removeEventMonitor()
- CustomStampWindowController.currentWindowController = nil
- NotificationCenter.default.removeObserver(self)
-
- return true
- }
- }
- extension CustomStampWindowController: CSRightToolbarDelegate {
- func csRightToolbar(_ toolbar: CustomStampRightToolbar, didAnnotationUpdate annotation: CPDFAnnotation?) {
-
- }
-
- func csRightToolbar(_ toolbar: CustomStampRightToolbar, didDeleteAnnotation annotation: CPDFAnnotation?) {
- self.pdfView.remove(annotation)
- self.reloadData()
- }
-
- func csRightToolbar(_ toolbar: CustomStampRightToolbar, didAnnotationClear annotation: CPDFAnnotation?) {
- let page = self.pdfView?.document?.page(at: 0)
- page?.removeAllAnnotations()
- self.pdfView?.setNeedsDisplayForVisiblePages()
-
- self.reloadData()
- }
-
- func csRightToolbar(didPDFClip toolbar: CustomStampRightToolbar) {
- guard let page = self.pdfView.document.page(at: 0) else {
- return
- }
- for anno in page.annotations ?? [] {
- if anno is CPDFFreeTextAnnotation {
- let newAnnotation = (anno as! CPDFFreeTextAnnotation)
- if self.pdfView.isEdit(withCurrentFreeText: newAnnotation) {
- self.pdfView.commitEditAnnotationFreeText(newAnnotation)
- self.pdfView.annotationType = .unkown
- }
- }
- self.pdfView.setNeedsDisplay(anno)
- }
-
- self.cropCurrentPage()
-
- }
-
-
- }
|