Forráskód Böngészése

Merge branch 'develop_2025' of git.kdan.cc:Mac_PDF/PDF_Office into develop_2025

tangchao 20 órája
szülő
commit
31c3a555bc

+ 1 - 0
PDF Office/KMComponentLibrary/KMComponentLibrary/View/Dropdown/ComponentDropdownTool/ComponentDropdownTool.swift

@@ -211,6 +211,7 @@ public class ComponentDropdownTool: ComponentBaseXibView {
             } else if item.type == .divider {
                 viewHeight += 8
             }
+            item.itemSelected = false
         }
         
         var point = convert(contendBox.frame.origin, to: window?.contentView)

+ 4 - 1
PDF Office/KMComponentLibrary/KMComponentLibrary/View/Dropdown/ComponentDropdownTool/ComponentDropdownToolProperty.swift

@@ -18,6 +18,7 @@ public class ComponentDropdownToolProperty: NSObject {
     public var leftIcon: NSImage? //左侧icon
     public var isDisabled: Bool = false //禁用状态
     public var arrowIcon: NSImage?
+    public var identifier: String = ""
     
     public var propertyInfo = DropDownPropertyInfo()
     
@@ -28,7 +29,8 @@ public class ComponentDropdownToolProperty: NSObject {
                 disabled: Bool = false,
                 leftIcon: NSImage? = nil,
                 showDropdown: Bool = false,
-                arrowIcon: NSImage? = nil) {
+                arrowIcon: NSImage? = nil,
+                identifier: String = "") {
         
         self.state = state
         self.text = text
@@ -36,6 +38,7 @@ public class ComponentDropdownToolProperty: NSObject {
         self.leftIcon = leftIcon
         self.showDropdown = showDropdown
         self.arrowIcon = arrowIcon
+        self.identifier = identifier
         
     }
 }

+ 0 - 226
PDF Office/PDF Master/Class/PDFWindowController/ViewController/KMMainViewController+Action.swift

@@ -1950,214 +1950,6 @@ extension KMMainViewController {
         }
     }
     
-    @objc private func shareDocument(sender:KMToolbarViewController, limit: Bool = false) {
-        if (limit) {
-            let document = self.listView.document ?? CPDFDocument()
-            if  document?.documentURL == nil {
-                return
-            }
-            var doucumentURL : URL = self.listView.document.documentURL
-            if doucumentURL.path.count > 0 {
-                let docDir = NSTemporaryDirectory()
-                let documentName : String = doucumentURL.path.lastPathComponent
-                let path = docDir.stringByAppendingPathComponent(documentName)
-                let data = KMTools.saveWatermarkDocument(document: self.listView.document, to: URL(fileURLWithPath: path), secureOptions: self.secureOptions, removePWD: self.removeSecureFlag)
-                let writeSuccess = data != nil
-                if writeSuccess == false {
-                    __NSBeep()
-                    return;
-                }
-                doucumentURL = URL(fileURLWithPath: path)
-            }
-            let array = [doucumentURL]
-            let picker = NSSharingServicePicker.init(items: array)
-            if sender.shareButton.window != nil {
-                picker.show(relativeTo: sender.shareButton.bounds, of: sender.shareButton, preferredEdge: NSRectEdge.minY)
-            } else {
-                picker.show(relativeTo: NSRect(x: (self.view.window?.contentView?.frame.size.width)!, y: (self.view.window?.contentView?.frame.size.height ?? 0)-8, width: 0, height: 0), of: self.view.window?.contentView ?? NSView(), preferredEdge: NSRectEdge.minY)
-            }
-            
-            return
-        }
-        
-        
-        let document = self.listView.document ?? CPDFDocument()
-        if  document?.documentURL == nil {
-            return
-        }
-        var doucumentURL : URL = self.listView.document.documentURL
-        if doucumentURL.path.count > 0 {
-            let docDir = NSTemporaryDirectory()
-            let documentName : String = doucumentURL.path.lastPathComponent
-            let path = docDir.stringByAppendingPathComponent(documentName)
-            let writeSuccess = self.listView.document.write(to: URL(fileURLWithPath: path))
-            if writeSuccess == false {
-                __NSBeep()
-                return;
-            }
-            doucumentURL = URL(fileURLWithPath: path)
-        }
-        let array = [doucumentURL]
-        let picker = NSSharingServicePicker.init(items: array)
-        if sender.shareButton.window != nil {
-            picker.show(relativeTo: sender.shareButton.bounds, of: sender.shareButton, preferredEdge: NSRectEdge.minY)
-        } else {
-            picker.show(relativeTo: NSRect(x: (self.view.window?.contentView?.frame.size.width)!, y: (self.view.window?.contentView?.frame.size.height ?? 0)-8, width: 0, height: 0), of: self.view.window?.contentView ?? NSView(), preferredEdge: NSRectEdge.minY)
-        }
-    }
-    
-    @objc private func shareFlatten(sender:KMToolbarViewController, limit: Bool = false) {
-        if (limit) {
-            let document = self.listView.document ?? CPDFDocument()
-            var path: String?
-            if  document?.documentURL != nil {
-                path = document?.documentURL.path ?? ""
-            }
-            if path?.count ?? 0 > 0 {
-                let docDir = NSTemporaryDirectory()
-                let documentName : String = path?.lastPathComponent ?? ""
-                path = docDir.stringByAppendingPathComponent(documentName)
-            }
-            let pathFolder = path?.fileURL.deletingLastPathComponent().path
-            var tfileName = path?.deletingPathExtension.lastPathComponent
-            let tStdFileSuffix = "_flatten"
-            tfileName = (tfileName ?? "") + tStdFileSuffix + ".pdf"
-            path = (pathFolder ?? "") + "/" + (tfileName ?? "")
-            
-            let data = KMTools.saveWatermarkDocumentForFlatten(document: document!, to: URL(fileURLWithPath: path ?? ""))
-            let success = data != nil
-            if success {
-                let url = URL(fileURLWithPath: path ?? "")
-                let picker = NSSharingServicePicker.init(items: [url])
-                if sender.shareButton.window != nil {
-                    picker.show(relativeTo: sender.shareButton.bounds, of: sender.shareButton, preferredEdge: NSRectEdge.minY)
-                } else {
-                    picker.show(relativeTo: NSRect(x: (self.view.window?.contentView?.frame.size.width)!, y: (self.view.window?.contentView?.frame.size.height ?? 0)-8, width: 0, height: 0), of: self.view.window?.contentView ?? NSView(), preferredEdge: NSRectEdge.minY)
-                }
-            }
-            return
-        }
-        
-        let document = self.listView.document ?? CPDFDocument()
-        var path: String?
-        if  document?.documentURL != nil {
-            path = document?.documentURL.path ?? ""
-        }
-        if path?.count ?? 0 > 0 {
-            let docDir = NSTemporaryDirectory()
-            let documentName : String = path?.lastPathComponent ?? ""
-            path = docDir.stringByAppendingPathComponent(documentName)
-        }
-        let pathFolder = path?.fileURL.deletingLastPathComponent().path
-        var tfileName = path?.deletingPathExtension.lastPathComponent
-        let tStdFileSuffix = "_flatten"
-        tfileName = (tfileName ?? "") + tStdFileSuffix + ".pdf"
-        path = (pathFolder ?? "") + "/" + (tfileName ?? "")
-        let success : Bool = document?.writeFlatten(to: URL(fileURLWithPath: path ?? "")) ?? false
-        if success {
-            let url = URL(fileURLWithPath: path ?? "")
-            let picker = NSSharingServicePicker.init(items: [url])
-            if sender.shareButton.window != nil {
-                picker.show(relativeTo: sender.shareButton.bounds, of: sender.shareButton, preferredEdge: NSRectEdge.minY)
-            } else {
-                picker.show(relativeTo: NSRect(x: (self.view.window?.contentView?.frame.size.width)!, y: (self.view.window?.contentView?.frame.size.height ?? 0)-8, width: 0, height: 0), of: self.view.window?.contentView ?? NSView(), preferredEdge: NSRectEdge.minY)
-            }
-        }
-    }
-    @objc private func shareOriginalPDF(sender:KMToolbarViewController, limit: Bool = false) {
-        guard let pdfDoc = self.listView.document else {
-            NSSound.beep()
-            return
-        }
-        if !pdfDoc.allowsCopying || !pdfDoc.allowsPrinting {
-            let alert = NSAlert()
-            alert.alertStyle = .critical
-            alert.messageText = NSLocalizedString("This is a secured document. Editing is not permitted.", comment: "")
-            alert.runModal()
-            return
-        }
-        
-        if (limit) {
-            let document = self.listView.document ?? CPDFDocument()
-            var path: String?
-            if  document?.documentURL != nil {
-                path = document?.documentURL.path ?? ""
-            }
-            if path?.count ?? 0 > 0{
-                let docDir = NSTemporaryDirectory()
-                let documentName : String = path?.lastPathComponent ?? ""
-                path = docDir.stringByAppendingPathComponent(documentName)
-            }
-            let data = KMTools.saveWatermarkDocument(document: document!, to: URL(fileURLWithPath: path ?? ""), secureOptions: self.secureOptions, removePWD: self.removeSecureFlag)
-            var writeSuccess = data != nil
-            if writeSuccess == false {
-                __NSBeep()
-                return;
-            }
-            let newDocument = CPDFDocument(url: URL(fileURLWithPath: path ?? ""))
-            let cnt = newDocument?.pageCount ?? 0
-            for i in 0 ..< cnt {
-                let page = newDocument?.page(at: i)
-                var annotations : [CPDFAnnotation] = []
-                for annotation in page!.annotations {
-                    annotations.append(annotation)
-                }
-                for annotation in annotations {
-                    annotation.page.removeAnnotation(annotation)
-                }
-            }
-            writeSuccess = newDocument?.write(to:URL(fileURLWithPath: path ?? "")) ?? false
-            if writeSuccess {
-                let url = URL(fileURLWithPath: path ?? "")
-                let picker = NSSharingServicePicker.init(items: [url])
-                if sender.shareButton.window != nil {
-                    picker.show(relativeTo: sender.shareButton.bounds, of: sender.shareButton, preferredEdge: NSRectEdge.minY)
-                } else {
-                    picker.show(relativeTo: NSRect(x: (self.view.window?.contentView?.frame.size.width)!, y: (self.view.window?.contentView?.frame.size.height ?? 0)-8, width: 0, height: 0), of: self.view.window?.contentView ?? NSView(), preferredEdge: NSRectEdge.minY)
-                }
-            }
-            return
-        }
-        
-        let document = self.listView.document ?? CPDFDocument()
-        var path: String?
-        if  document?.documentURL != nil {
-            path = document?.documentURL.path ?? ""
-        }
-        if path?.count ?? 0 > 0 {
-            let docDir = NSTemporaryDirectory()
-            let documentName : String = path?.lastPathComponent ?? ""
-            path = docDir.stringByAppendingPathComponent(documentName)
-        }
-        var writeSuccess = document?.write(to: URL(fileURLWithPath: path ?? ""))
-        if writeSuccess == false {
-            __NSBeep()
-            return;
-        }
-        let newDocument = CPDFDocument(url: URL(fileURLWithPath: path ?? ""))
-        
-        let cnt = newDocument?.pageCount ?? 0
-        for i in 0 ..< cnt {
-            let page = newDocument!.page(at: i)
-            var annotations : [CPDFAnnotation] = []
-            for annotation in page!.annotations {
-                annotations.append(annotation)
-            }
-            for annotation in annotations {
-                annotation.page.removeAnnotation(annotation)
-            }
-        }
-        writeSuccess = newDocument?.write(to:URL(fileURLWithPath: path ?? ""))
-        if writeSuccess ?? false {
-            let url = URL(fileURLWithPath: path ?? "")
-            let picker = NSSharingServicePicker.init(items: [url])
-            if sender.shareButton.window != nil {
-                picker.show(relativeTo: sender.shareButton.bounds, of: sender.shareButton, preferredEdge: NSRectEdge.minY)
-            } else {
-                picker.show(relativeTo: NSRect(x: (self.view.window?.contentView?.frame.size.width)!, y: (self.view.window?.contentView?.frame.size.height ?? 0)-8, width: 0, height: 0), of: self.view.window?.contentView ?? NSView(), preferredEdge: NSRectEdge.minY)
-            }
-        }
-    }
     
     // 开启/关闭左边栏
     @objc func toggleLeftPane() -> Void {
@@ -3072,24 +2864,6 @@ extension KMMainViewController : KMToolbarViewControllerDelegate {
         self.trackEvent_share()
     }
     
-    func toolbarViewController(_ viewController: KMToolbarViewController, shareDocument item: NSMenuItem) {
-        self.shareDocument(sender: viewController)
-    }
-    
-    func toolbarViewController(_ viewController: KMToolbarViewController, shareFlatten item: NSMenuItem) {
-        if IAPProductsManager.default().isAvailableAllFunction() == false {
-            let winC = KMPurchaseCompareWindowController.sharedInstance()
-            winC?.kEventName = "Reading_Flatten_BuyNow"
-            winC?.showWindow(nil)
-            return
-        }
-        self.shareFlatten(sender: viewController)
-    }
-    
-    func toolbarViewController(_ viewController: KMToolbarViewController, shareOriginalPDF item: NSMenuItem) {
-        self.shareOriginalPDF(sender: viewController)
-    }
-    
     func toolbarViewController(_ viewController: KMToolbarViewController, scanOCRModel selectedTag: Int) {
         if(0 == selectedTag) {
         } else {

+ 1 - 38
PDF Office/PDF Master/Class/PDFWindowController/ViewController/KMMainViewController+UI.swift

@@ -485,44 +485,7 @@ extension KMMainViewController {
         //增加判断,如果是正在滚动,就停止,否则就开始滚动
         self.listView.autoFlow()
     }
-    @objc func shareFromService(sender: NSMenuItem) {
-        if ((NSApp.mainWindow?.windowController is KMBrowserWindowController) == false) {
-            return
-        }
-        
-        var string = ""
-        if let freeTextAnnotation = listView.activeAnnotation as? CPDFFreeTextAnnotation {
-            string = freeTextAnnotation.contents ?? ""
-        } else if let markupAnnotation = listView.activeAnnotation as? CPDFMarkupAnnotation {
-            if let page = markupAnnotation.page {
-                if let selection = page.selection(for: markupAnnotation.bounds) {
-                    string = selection.string() ?? ""
-                }
-            }
-        } else {
-            string = listView.currentSelection?.string() ?? ""
-        }
-        
-        let windowControler = NSApp.mainWindow?.windowController as! KMBrowserWindowController
-        let model = windowControler.browser?.tabStripModel
-        if let cnt = model?.count(), cnt <= 0 {
-            return
-        }
-        
-        if let data = model?.activeTabContents().isHome, data {
-            return
-        }
-        
-        let document: KMMainDocument = model?.activeTabContents() as! KMMainDocument
-        if string.count > 0 {
-            let represent : NSSharingService = sender.representedObject as! NSSharingService
-            represent.perform(withItems: [string])
-            return
-        }
-
-        let represent = sender.representedObject as? NSSharingService
-        represent?.perform(withItems: [string])
-    }
+    
     
     @objc func cutAction(sender: NSMenuItem) {
         

+ 1 - 1
PDF Office/PDF Master/KMClass/KMHomeViewController/Views/KMHomeRightView/HistoryFile.swift

@@ -62,7 +62,7 @@ class HistoryFile: NSObject {
                 string.setString(fileUrl.path.deletingLastPathComponent)
             }
             
-            let image = NSImage.previewForFile(path: fileUrl, ofSize: self.iconSize, asIcon: true) ?? NSImage()
+            let image = KMFileThumbManager.manager.getFileThumb(fileUrl) ?? NSImage()
             
             self.image = image
             self.name = fileUrl.path.lastPathComponent

PDF Office/PDF Master/KMClass/KMHomeViewController/Views/KMHomeRightView/HistoryFilesManager.swift → PDF Office/PDF Master/KMClass/KMHomeViewController/HistoryFilesManager/HistoryFilesManager.swift


+ 117 - 0
PDF Office/PDF Master/KMClass/KMHomeViewController/HistoryFilesManager/KMFileThumbManager.swift

@@ -0,0 +1,117 @@
+//
+//  KMFileThumbManager.swift
+//  PDF Reader Pro
+//
+//  Created by Niehaoyu on 2024/11/22.
+//
+
+import Cocoa
+import CryptoKit
+
+class KMFileThumbManager: NSObject {
+    
+    let thumbFolderPath = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.applicationSupportDirectory, FileManager.SearchPathDomainMask.userDomainMask, true).last?.stringByAppendingPathComponent(Bundle.main.bundleIdentifier!).stringByAppendingPathComponent("thumb")
+    
+    @objc public static let manager = KMFileThumbManager()
+    
+    private var iconSize: CGSize = CGSizeMake(126*3, 168*3)
+    
+    override init() {
+        super.init()
+        
+        if (!FileManager.default.fileExists(atPath: thumbFolderPath!)) {
+            try?FileManager.default.createDirectory(atPath: thumbFolderPath!, withIntermediateDirectories: true, attributes: nil)
+        }
+        
+        refreshData()
+    }
+    
+    private func refreshData() {
+        let urls: Array<URL> = NSDocumentController.shared.recentDocumentURLs
+        
+        var fileNames: [String] = []
+        for url in urls {
+            let filePath = url.path
+            let fileName = filePath.getLastComponentDeleteExtension
+            
+            let resultPath = thumbFolderPath?.stringByAppendingPathComponent((fileName + ".png"))
+            if (!FileManager.default.fileExists(atPath: resultPath!)) {
+                updateFile(url, iconSize)
+            }
+            fileNames.append((fileName + ".png"))
+        }
+        
+        if let contents = try?FileManager.default.contentsOfDirectory(atPath: thumbFolderPath!) {
+            for name in contents {
+                if name != ".DS_Store" {
+                    if let index = fileNames.firstIndex(of: name) {
+                        
+                    } else {
+                        if let path = thumbFolderPath?.stringByAppendingPathComponent(name) {
+                            try?FileManager.default.removeItem(atPath: path)
+                        }
+                    }
+                }
+            }
+        }
+    }
+    
+    private func generateThumbnail(for pdfURL: URL, _ size: NSSize) -> NSImage? {
+        guard let pdfDocument = CGPDFDocument(pdfURL as CFURL),
+              let pdfPage = pdfDocument.page(at: 1) else {
+            
+            return nil
+        }
+        
+        let pageRect = pdfPage.getBoxRect(.mediaBox)
+        
+        // 创建图形上下文
+        let bitsPerComponent = 8
+        let bitmapInfo = CGImageAlphaInfo.premultipliedLast.rawValue
+        let context = CGContext(data: nil, width: Int(size.width), height: Int(size.height), bitsPerComponent: bitsPerComponent, bytesPerRow: 0, space: CGColorSpaceCreateDeviceRGB(), bitmapInfo: bitmapInfo)
+        
+        // 绘制PDF页面
+        //        context?.saveGState()
+        //        context?.translateBy(x: 0, y: size.height)
+        //        context?.scaleBy(x: 1.0, y: -1.0) // 反转坐标系
+        context?.scaleBy(x: size.width / pageRect.width, y: size.height / pageRect.height) // 缩放
+        context?.drawPDFPage(pdfPage)
+        context?.restoreGState()
+        
+        // 创建NSImage
+        if let cgImage = context?.makeImage() {
+            return NSImage(cgImage: cgImage, size: NSSize(width: size.width, height: size.height))
+        }
+        return nil
+    }
+    
+    public func updateFile(_ fileURL: URL, _ iconSize: CGSize) {
+        let filePath = fileURL.path
+        let fileName = filePath.getLastComponentDeleteExtension
+        
+        if let resultPath: String = thumbFolderPath?.stringByAppendingPathComponent((fileName + ".png")) {
+            if let image = generateThumbnail(for: fileURL, iconSize) {
+                guard let data = image.tiffRepresentation else {
+                    return
+                }
+                let imageRep = NSBitmapImageRep(data: data)
+                imageRep?.size = image.size
+                if let imageData = imageRep?.representation(using: .png, properties: [:]) {
+                    try?imageData.write(to: URL(fileURLWithPath: resultPath))
+                }
+            }
+        }
+    }
+    
+    public func getFileThumb(_ fileURL: URL) -> NSImage? {
+        let filePath = fileURL.path
+        let fileName = filePath.getLastComponentDeleteExtension
+        
+        if let resultPath: String = thumbFolderPath?.stringByAppendingPathComponent((fileName + ".png")) {
+            return NSImage(contentsOf: URL(fileURLWithPath: resultPath))
+        }
+        return nil
+    } 
+    
+    
+}

+ 1 - 0
PDF Office/PDF Master/KMClass/KMPDFViewController/EditTool/Crop/KMCropController.swift

@@ -69,6 +69,7 @@ class KMCropController: NSViewController {
         
         documentPreview.pdfView.toolMode = .selectToolMode
         documentPreview.pdfView.selectionRect = bounds
+        documentPreview.pdfView.setNeedsDisplayForVisiblePages()
      
         propertyController.pdfView = documentPreview.pdfView
         propertyController.reloadData()

+ 40 - 5
PDF Office/PDF Master/KMClass/KMPDFViewController/EditTool/Crop/Views/KMCropPropertyController.swift

@@ -149,8 +149,7 @@ class KMCropPropertyController: NSViewController {
         pageRangeLabel.textColor = ComponentLibrary.shared.getComponentColorFromKey("colorText/2")
         pageRangeLabel.font = ComponentLibrary.shared.getFontFromKey("mac/body-s-medium")
         
-        
-        
+         
         cropButton.properties = ComponentButtonProperty(type: .primary, size: .m, buttonText: KMLocalizedString("Apply"), keepPressState: false)
         
     }
@@ -197,8 +196,7 @@ class KMCropPropertyController: NSViewController {
         pageBottomInput.reloadData()
         
         //PageRange
-        
-        print(selectionRect)
+         
         
     }
     
@@ -214,11 +212,48 @@ class KMCropPropertyController: NSViewController {
         sizeSyncButton.reloadData()
     }
     
+    @objc func cropButtonClicked(_ sender: ComponentButton) {
+        
+    }
+    
 }
 
 //MARK: - ComponentInputNumberDelegate
 extension KMCropPropertyController: ComponentInputNumberDelegate {
-    
+    func componentInputNumberDidValueChanged(inputNumber: ComponentInputNumber?) {
+        guard let pdfView = self.pdfView else {
+            return
+        }
+        
+        guard let page = pdfView.currentSelectionPage() else {
+            return
+        }
+        let pageBounds = page.bounds
+        
+        var value: CGFloat = 0
+        if let text = inputNumber?.properties.text {
+            value = text.stringToCGFloat()
+        }
+  
+        var rect = pdfView.selectionRect
+        if inputNumber == sizeWidthInput {
+            rect.size.width = value
+        } else if inputNumber == sizeHeightInput {
+            rect.size.height = value
+        } else if inputNumber == pageLeftInput {
+            rect.origin.x = value
+        } else if inputNumber == pageRightInput {
+            rect.size.width = pageBounds.size.width - rect.origin.x - value
+        } else if inputNumber == pageTopInput {
+            rect.size.height = pageBounds.size.height - rect.origin.y - value
+        } else if inputNumber == pageBottomInput {
+            rect.origin.y = value
+        }
+        pdfView.selectionRect = rect
+        pdfView.setNeedsDisplayForVisiblePages()
+        
+        reloadData()
+    }
 }
 
 //MARK: - ComponentSelectDelegate

+ 159 - 0
PDF Office/PDF Master/KMClass/KMPDFViewController/KMMainViewController.swift

@@ -1178,6 +1178,153 @@ import KMComponentLibrary
         
     }
     
+    //MARK: - Share
+    @objc private func shareDocument(sender: NSView) {
+        let document = self.listView.document ?? CPDFDocument()
+        if  document?.documentURL == nil {
+            return
+        }
+        var doucumentURL : URL = self.listView.document.documentURL
+        if doucumentURL.path.count > 0 {
+            let docDir = NSTemporaryDirectory()
+            let documentName : String = doucumentURL.path.lastPathComponent
+            let path = docDir.stringByAppendingPathComponent(documentName)
+            let writeSuccess = self.listView.document.write(to: URL(fileURLWithPath: path))
+            if writeSuccess == false {
+                __NSBeep()
+                return;
+            }
+            doucumentURL = URL(fileURLWithPath: path)
+        }
+        let array = [doucumentURL]
+        let picker = NSSharingServicePicker.init(items: array)
+        if sender.window != nil {
+            picker.show(relativeTo: sender.bounds, of: sender, preferredEdge: NSRectEdge.minY)
+        } else {
+            picker.show(relativeTo: NSRect(x: (self.view.window?.contentView?.frame.size.width)!, y: (self.view.window?.contentView?.frame.size.height ?? 0)-8, width: 0, height: 0), of: self.view.window?.contentView ?? NSView(), preferredEdge: NSRectEdge.minY)
+        }
+    }
+    
+    @objc private func shareFlatten(sender: NSView) {
+        let document = self.listView.document ?? CPDFDocument()
+        var path: String?
+        if  document?.documentURL != nil {
+            path = document?.documentURL.path ?? ""
+        }
+        if path?.count ?? 0 > 0 {
+            let docDir = NSTemporaryDirectory()
+            let documentName : String = path?.lastPathComponent ?? ""
+            path = docDir.stringByAppendingPathComponent(documentName)
+        }
+        let pathFolder = path?.fileURL.deletingLastPathComponent().path
+        var tfileName = path?.deletingPathExtension.lastPathComponent
+        let tStdFileSuffix = "_flatten"
+        tfileName = (tfileName ?? "") + tStdFileSuffix + ".pdf"
+        path = (pathFolder ?? "") + "/" + (tfileName ?? "")
+        let success : Bool = document?.writeFlatten(to: URL(fileURLWithPath: path ?? "")) ?? false
+        if success {
+            let url = URL(fileURLWithPath: path ?? "")
+            let picker = NSSharingServicePicker.init(items: [url])
+            if sender.window != nil {
+                picker.show(relativeTo: sender.bounds, of: sender, preferredEdge: NSRectEdge.minY)
+            } else {
+                picker.show(relativeTo: NSRect(x: (self.view.window?.contentView?.frame.size.width)!, y: (self.view.window?.contentView?.frame.size.height ?? 0)-8, width: 0, height: 0), of: self.view.window?.contentView ?? NSView(), preferredEdge: NSRectEdge.minY)
+            }
+        }
+    }
+    
+    @objc private func shareOriginalPDF(sender: NSView) {
+        guard let pdfDoc = self.listView.document else {
+            NSSound.beep()
+            return
+        }
+        if !pdfDoc.allowsCopying || !pdfDoc.allowsPrinting {
+            let alert = NSAlert()
+            alert.alertStyle = .critical
+            alert.messageText = NSLocalizedString("This is a secured document. Editing is not permitted.", comment: "")
+            alert.runModal()
+            return
+        }
+        
+        let document = self.listView.document ?? CPDFDocument()
+        var path: String?
+        if  document?.documentURL != nil {
+            path = document?.documentURL.path ?? ""
+        }
+        if path?.count ?? 0 > 0 {
+            let docDir = NSTemporaryDirectory()
+            let documentName : String = path?.lastPathComponent ?? ""
+            path = docDir.stringByAppendingPathComponent(documentName)
+        }
+        var writeSuccess = document?.write(to: URL(fileURLWithPath: path ?? ""))
+        if writeSuccess == false {
+            __NSBeep()
+            return;
+        }
+        let newDocument = CPDFDocument(url: URL(fileURLWithPath: path ?? ""))
+        
+        let cnt = newDocument?.pageCount ?? 0
+        for i in 0 ..< cnt {
+            let page = newDocument!.page(at: i)
+            var annotations : [CPDFAnnotation] = []
+            for annotation in page!.annotations {
+                annotations.append(annotation)
+            }
+            for annotation in annotations {
+                annotation.page.removeAnnotation(annotation)
+            }
+        }
+        writeSuccess = newDocument?.write(to:URL(fileURLWithPath: path ?? ""))
+        if writeSuccess ?? false {
+            let url = URL(fileURLWithPath: path ?? "")
+            let picker = NSSharingServicePicker.init(items: [url])
+            if sender.window != nil {
+                picker.show(relativeTo: sender.bounds, of: sender, preferredEdge: NSRectEdge.minY)
+            } else {
+                picker.show(relativeTo: NSRect(x: (self.view.window?.contentView?.frame.size.width)!, y: (self.view.window?.contentView?.frame.size.height ?? 0)-8, width: 0, height: 0), of: self.view.window?.contentView ?? NSView(), preferredEdge: NSRectEdge.minY)
+            }
+        }
+    }
+    
+    @objc func shareFromService(sender: NSMenuItem) {
+        if ((NSApp.mainWindow?.windowController is KMBrowserWindowController) == false) {
+            return
+        }
+        
+        var string = ""
+        if let freeTextAnnotation = listView.activeAnnotation as? CPDFFreeTextAnnotation {
+            string = freeTextAnnotation.contents ?? ""
+        } else if let markupAnnotation = listView.activeAnnotation as? CPDFMarkupAnnotation {
+            if let page = markupAnnotation.page {
+                if let selection = page.selection(for: markupAnnotation.bounds) {
+                    string = selection.string() ?? ""
+                }
+            }
+        } else {
+            string = listView.currentSelection?.string() ?? ""
+        }
+        
+        let windowControler = NSApp.mainWindow?.windowController as! KMBrowserWindowController
+        let model = windowControler.browser?.tabStripModel
+        if let cnt = model?.count(), cnt <= 0 {
+            return
+        }
+        
+        if let data = model?.activeTabContents().isHome, data {
+            return
+        }
+        
+        let document: KMMainDocument = model?.activeTabContents() as! KMMainDocument
+        if string.count > 0 {
+            let represent : NSSharingService = sender.representedObject as! NSSharingService
+            represent.perform(withItems: [string])
+            return
+        }
+
+        let represent = sender.representedObject as? NSSharingService
+        represent?.perform(withItems: [string])
+    }
+    
 }
 
 //MARK: - NSSplitViewDelegate
@@ -1462,6 +1609,18 @@ extension KMMainViewController: KMPDFToolbarControllerDelegate {
             listView.undoManager?.undo()
         } else if(itemIdentifier == KMPDFToolbar_redo_Identifier) {
             listView.undoManager?.redo()
+        } else if(itemIdentifier == KMPDFToolbar_share_PDF_Identifier) {
+            if let view = controller.findViewWith(KMPDFToolbar_share_Identifier) {
+                shareDocument(sender: view)
+            }
+        } else if(itemIdentifier == KMPDFToolbar_share_Flattened_Identifier) {
+            if let view = controller.findViewWith(KMPDFToolbar_share_Identifier) {
+                shareFlatten(sender: view)
+            }
+        } else if(itemIdentifier == KMPDFToolbar_share_Original_Identifier) {
+            if let view = controller.findViewWith(KMPDFToolbar_share_Identifier) {
+                shareOriginalPDF(sender: view)
+            }
         } else {
             print("click else")
         }

+ 35 - 0
PDF Office/PDF Master/KMClass/KMPDFViewController/Toolbar/KMPDFToolbarController.swift

@@ -486,6 +486,37 @@ class KMPDFToolbarController: NSViewController {
         }
     }
     
+    //MARK: - 查找
+    func findViewWith(_ identify: String) -> NSView? {
+
+        //左侧
+        
+        //中间
+        
+        //右侧
+        if true {
+            let views = rightToolsView.subviews
+            for view in views {
+                if view is ComponentButton {
+                    if (view as! ComponentButton).properties.identifier == identify {
+                        return view
+                    }
+                } else if view is ComponentDropdownTool {
+                    if (view as! ComponentDropdownTool).properties.identifier == identify {
+                        return view
+                    }
+                    for item in (view as! ComponentDropdownTool).properties.menuItemArr ?? [] {
+                        if item.identifier == identify {
+                            return view
+                        }
+                    }
+                }
+            }
+        }
+        
+        return nil
+    }
+    
     //MARK: - reloadData
     func reloadData() {
         reloadLeftIconView()
@@ -737,6 +768,10 @@ extension KMPDFToolbarController: ComponentDropdownToolDelegate {
             viewManager.viewToolsType = .Magnify
         } else if menuItem == toolbarManager.tools_areaProperty {
             viewManager.viewToolsType = .AreaZoom
+        } else if menuItem == toolbarManager.share_PDF_Property ||
+                    menuItem == toolbarManager.share_Flatted_Property ||
+                    menuItem == toolbarManager.share_Original_Property {
+            delegate?.kmPDFToolbarControllerDidToolbarItemClicked?(self, menuItem?.identifier ?? "")
         }
         reloadToolsView()
     }

+ 1 - 0
PDF Office/PDF Master/KMClass/KMPDFViewController/Toolbar/Model/KMPDFToolbarConfig.swift

@@ -76,6 +76,7 @@ let KMPDFToolbar_tts_Identifier                    = "KMPDFToolbar_tts_Identifie
 let KMPDFToolbar_ppt_Identifier                    = "KMPDFToolbar_ppt_Identifier"
 let KMPDFToolbar_print_Identifier                  = "KMPDFToolbar_print_Identifier"
 
+let KMPDFToolbar_share_Identifier                  = "KMPDFToolbar_share_Identifier"
 let KMPDFToolbar_share_PDF_Identifier              = "KMPDFToolbar_share_PDF_Identifier"
 let KMPDFToolbar_share_Flattened_Identifier        = "KMPDFToolbar_share_Flattened_Identifier"
 let KMPDFToolbar_share_Original_Identifier         = "KMPDFToolbar_share_Original_Identifier"

+ 1 - 1
PDF Office/PDF Master/KMClass/KMPDFViewController/Toolbar/Model/KMPDFToolbarManager.swift

@@ -77,7 +77,7 @@ class KMPDFToolbarManager: NSObject {
     var pptProperty: ComponentButtonProperty = ComponentButtonProperty(type: .text_gray_opacity, size: .xs, onlyIcon: true, icon: NSImage(named: "toolbar_ppt"), keepPressState: false,identifier: KMPDFToolbar_ppt_Identifier)
     var printProperty: ComponentButtonProperty = ComponentButtonProperty(type: .text_gray_opacity, size: .xs, onlyIcon: true, icon: NSImage(named: "toolbar_print"), keepPressState: false, identifier: KMPDFToolbar_print_Identifier)
     
-    var shareProperty: ComponentDropdownToolProperty = ComponentDropdownToolProperty(state: .normal, leftIcon: NSImage(named: "toolbar_share"))
+    var shareProperty: ComponentDropdownToolProperty = ComponentDropdownToolProperty(state: .normal, leftIcon: NSImage(named: "toolbar_share"), identifier: KMPDFToolbar_share_Identifier)
     var share_PDF_Property: ComponentMenuitemProperty = ComponentMenuitemProperty(text: KMLocalizedString("PDF"), identifier: KMPDFToolbar_share_PDF_Identifier)
     var share_Flatted_Property: ComponentMenuitemProperty = ComponentMenuitemProperty(text: KMLocalizedString("Flattened Copy"), identifier: KMPDFToolbar_share_Flattened_Identifier)
     var share_Original_Property: ComponentMenuitemProperty = ComponentMenuitemProperty(text: KMLocalizedString("Original PDF"), identifier: KMPDFToolbar_share_Original_Identifier)

+ 18 - 2
PDF Office/PDF Reader Pro.xcodeproj/project.pbxproj

@@ -3936,6 +3936,9 @@
 		BB7929F52CEF342D006FFD5D /* KMPageRangeSelectView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB7929F42CEF342D006FFD5D /* KMPageRangeSelectView.swift */; };
 		BB7929F62CEF342D006FFD5D /* KMPageRangeSelectView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB7929F42CEF342D006FFD5D /* KMPageRangeSelectView.swift */; };
 		BB7929F72CEF342D006FFD5D /* KMPageRangeSelectView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB7929F42CEF342D006FFD5D /* KMPageRangeSelectView.swift */; };
+		BB792A042CF0280E006FFD5D /* KMFileThumbManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB792A032CF0280E006FFD5D /* KMFileThumbManager.swift */; };
+		BB792A052CF0280E006FFD5D /* KMFileThumbManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB792A032CF0280E006FFD5D /* KMFileThumbManager.swift */; };
+		BB792A062CF0280E006FFD5D /* KMFileThumbManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB792A032CF0280E006FFD5D /* KMFileThumbManager.swift */; };
 		BB79E7192CE617CB0052CAD5 /* KMEditImageController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB79E7172CE617CB0052CAD5 /* KMEditImageController.swift */; };
 		BB79E71A2CE617CB0052CAD5 /* KMEditImageController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB79E7172CE617CB0052CAD5 /* KMEditImageController.swift */; };
 		BB79E71B2CE617CB0052CAD5 /* KMEditImageController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB79E7172CE617CB0052CAD5 /* KMEditImageController.swift */; };
@@ -7334,6 +7337,7 @@
 		BB77C85E2BD506BE0065AFF2 /* CPDFAnnotation+KMExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CPDFAnnotation+KMExtension.swift"; sourceTree = "<group>"; };
 		BB78EAA92B561F9700121691 /* KMFullScreenWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMFullScreenWindow.swift; sourceTree = "<group>"; };
 		BB7929F42CEF342D006FFD5D /* KMPageRangeSelectView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMPageRangeSelectView.swift; sourceTree = "<group>"; };
+		BB792A032CF0280E006FFD5D /* KMFileThumbManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMFileThumbManager.swift; sourceTree = "<group>"; };
 		BB79E7172CE617CB0052CAD5 /* KMEditImageController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMEditImageController.swift; sourceTree = "<group>"; };
 		BB79E7182CE617CB0052CAD5 /* KMEditImageController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = KMEditImageController.xib; sourceTree = "<group>"; };
 		BB79FAB02CDC65BA00BF7B39 /* KMBGTemplateController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMBGTemplateController.swift; sourceTree = "<group>"; };
@@ -12818,6 +12822,7 @@
 				BB5A9D292CB6520100F64C1F /* home.xcassets */,
 				BB5A9D2E2CB6520100F64C1F /* KMNHomeViewController.swift */,
 				BB5A9D282CB6520100F64C1F /* KMNHomeViewController.xib */,
+				BB792A012CF027C1006FFD5D /* HistoryFilesManager */,
 				BBB2A99A2CB65C580066560B /* KMURLCreatePDFWindowController */,
 				BBB2A9992CB65C440066560B /* Views */,
 			);
@@ -12827,8 +12832,6 @@
 		BB5A9D272CB6520100F64C1F /* KMHomeRightView */ = {
 			isa = PBXGroup;
 			children = (
-				BB19A7492CB7C2C6008204DC /* HistoryFilesManager.swift */,
-				BBE3709C2CB8BD3700390884 /* HistoryFile.swift */,
 				BB19A7392CB7B4C9008204DC /* KMHomeRightView.swift */,
 				BB19A73D2CB7B4D1008204DC /* KMHomeRightView.xib */,
 				9F1F82C2292F113A0092C4B4 /* KMHomeDragView.swift */,
@@ -13205,6 +13208,16 @@
 			path = CustomViews;
 			sourceTree = "<group>";
 		};
+		BB792A012CF027C1006FFD5D /* HistoryFilesManager */ = {
+			isa = PBXGroup;
+			children = (
+				BB19A7492CB7C2C6008204DC /* HistoryFilesManager.swift */,
+				BBE3709C2CB8BD3700390884 /* HistoryFile.swift */,
+				BB792A032CF0280E006FFD5D /* KMFileThumbManager.swift */,
+			);
+			path = HistoryFilesManager;
+			sourceTree = "<group>";
+		};
 		BB7F7BFD29AA585E00A3E4E7 /* images */ = {
 			isa = PBXGroup;
 			children = (
@@ -17816,6 +17829,7 @@
 				ADE86AE62B0AF50B00414DFA /* KMCompareCoveringSettingWindowController.swift in Sources */,
 				BB1B0AF22B4FC6E900889528 /* KMFunctionGuideNameItemView.swift in Sources */,
 				BBBC08832B2AC863009B237F /* KMSnapshotModel.swift in Sources */,
+				BB792A042CF0280E006FFD5D /* KMFileThumbManager.swift in Sources */,
 				BB4F7E792B0C45BB0077EC8C /* KMNoteOutlineFilterViewController.swift in Sources */,
 				ADD1B6C72942E83000C3FFF7 /* KMPrintBottomView.swift in Sources */,
 				9F0CB4D12986550B00007028 /* KMDesignToken+Width.swift in Sources */,
@@ -18643,6 +18657,7 @@
 				ADDF83362B391A5C00A81A4E /* CPDFListViewConfig.m in Sources */,
 				AD867FB429DFBB2700F00440 /* KMAnnotationOutlineSectionView.swift in Sources */,
 				BBEC00A9295BDECF00A26C98 /* KMHeaderFooterContentInfoView.swift in Sources */,
+				BB792A052CF0280E006FFD5D /* KMFileThumbManager.swift in Sources */,
 				9F8539BF2943085A00DF644E /* KMBrowser.swift in Sources */,
 				9F0CB4E62986557F00007028 /* KMDesignToken+PaddingRight.swift in Sources */,
 				BB7FF5082A60E84400901C2D /* KMEnumExtensions.swift in Sources */,
@@ -20273,6 +20288,7 @@
 				BBFE6E89293210AB00142C01 /* KMCompressCellView.swift in Sources */,
 				ADDEEA702AD3E16100EF675D /* KMSigntureViewItem.swift in Sources */,
 				9FF0D0552B6A3EE40018A732 /* CPDFListView+Form.swift in Sources */,
+				BB792A062CF0280E006FFD5D /* KMFileThumbManager.swift in Sources */,
 				BB853C7F2AF8B5D6009C20C1 /* KMBatchOperateAddPasswordViewController.swift in Sources */,
 				AD3AAD252B0B6F9E00DE5FE7 /* KMCompareContentView.swift in Sources */,
 				BB147040299DC0D200784A6A /* OIDEndSessionResponse.m in Sources */,