Browse Source

【2025】【Crop】裁剪模式补充相关操作

dinglingui 2 months ago
parent
commit
3a402e4538
26 changed files with 762 additions and 9 deletions
  1. 3 0
      PDF Office/PDF Master/Class/PDFWindowController/PDFListView/CPDFListView.h
  2. 7 0
      PDF Office/PDF Master/Class/PDFWindowController/PDFListView/CPDFListView.m
  3. 64 4
      PDF Office/PDF Master/KMClass/KMPDFViewController/KMMainViewController.swift
  4. 3 3
      PDF Office/PDF Master/KMClass/KMPDFViewController/KMMainViewController.xib
  5. 6 0
      PDF Office/PDF Master/KMClass/PDFListView/KMNListviewPopImage.xcassets/crop/Contents.json
  6. 22 0
      PDF Office/PDF Master/KMClass/PDFListView/KMNListviewPopImage.xcassets/crop/KMNImageNameListViewCropAdd.imageset/Contents.json
  7. BIN
      PDF Office/PDF Master/KMClass/PDFListView/KMNListviewPopImage.xcassets/crop/KMNImageNameListViewCropAdd.imageset/copy.pdf
  8. BIN
      PDF Office/PDF Master/KMClass/PDFListView/KMNListviewPopImage.xcassets/crop/KMNImageNameListViewCropAdd.imageset/icon_prefix 1.pdf
  9. 22 0
      PDF Office/PDF Master/KMClass/PDFListView/KMNListviewPopImage.xcassets/crop/KMNImageNameListViewCropClose.imageset/Contents.json
  10. BIN
      PDF Office/PDF Master/KMClass/PDFListView/KMNListviewPopImage.xcassets/crop/KMNImageNameListViewCropClose.imageset/icon_prefix 1.pdf
  11. BIN
      PDF Office/PDF Master/KMClass/PDFListView/KMNListviewPopImage.xcassets/crop/KMNImageNameListViewCropClose.imageset/icon_prefix.pdf
  12. 22 0
      PDF Office/PDF Master/KMClass/PDFListView/KMNListviewPopImage.xcassets/crop/KMNImageNameListViewCropExport.imageset/Contents.json
  13. BIN
      PDF Office/PDF Master/KMClass/PDFListView/KMNListviewPopImage.xcassets/crop/KMNImageNameListViewCropExport.imageset/base-placeholder 1.pdf
  14. BIN
      PDF Office/PDF Master/KMClass/PDFListView/KMNListviewPopImage.xcassets/crop/KMNImageNameListViewCropExport.imageset/base-placeholder.pdf
  15. 22 0
      PDF Office/PDF Master/KMClass/PDFListView/KMNListviewPopImage.xcassets/crop/KMNImageNameListViewCropPrint.imageset/Contents.json
  16. BIN
      PDF Office/PDF Master/KMClass/PDFListView/KMNListviewPopImage.xcassets/crop/KMNImageNameListViewCropPrint.imageset/icon_prefix 1.pdf
  17. BIN
      PDF Office/PDF Master/KMClass/PDFListView/KMNListviewPopImage.xcassets/crop/KMNImageNameListViewCropPrint.imageset/icon_prefix.pdf
  18. 22 0
      PDF Office/PDF Master/KMClass/PDFListView/KMNListviewPopImage.xcassets/crop/KMNImageNameListViewCropRest.imageset/Contents.json
  19. BIN
      PDF Office/PDF Master/KMClass/PDFListView/KMNListviewPopImage.xcassets/crop/KMNImageNameListViewCropRest.imageset/icon_prefix 1.pdf
  20. BIN
      PDF Office/PDF Master/KMClass/PDFListView/KMNListviewPopImage.xcassets/crop/KMNImageNameListViewCropRest.imageset/icon_prefix.pdf
  21. 17 1
      PDF Office/PDF Master/KMClass/PDFListView/WindowController/KMNPopAnnotationWindowController.swift
  22. 16 0
      PDF Office/PDF Master/KMClass/PDFListView/WindowController/KMNPopContentEditWindowController.swift
  23. 1 1
      PDF Office/PDF Master/KMClass/PDFListView/WindowController/KMNPopContentEditWindowController.xib
  24. 354 0
      PDF Office/PDF Master/KMClass/PDFListView/WindowController/KMNPopOperationWindowController.swift
  25. 165 0
      PDF Office/PDF Master/KMClass/PDFListView/WindowController/KMNPopOperationWindowController.xib
  26. 16 0
      PDF Office/PDF Reader Pro.xcodeproj/project.pbxproj

+ 3 - 0
PDF Office/PDF Master/Class/PDFWindowController/PDFListView/CPDFListView.h

@@ -265,6 +265,9 @@ enum {
 
 - (NSRect)currentSelectionRect;
 
+- (CPDFPage *)currentSelectionPage;
+
+
 // Scale the page to the specified range
 
 - (void)zoomToRect:(NSRect)rect onPage:(CPDFPage *)page;

+ 7 - 0
PDF Office/PDF Master/Class/PDFWindowController/PDFListView/CPDFListView.m

@@ -475,6 +475,13 @@ void CPDFListViewOCDrawLineHandles(CGContextRef context, CGRect rect, CGFloat ra
     return NSZeroRect;
 }
 
+- (CPDFPage *)currentSelectionPage {
+    if (self.selectionPageIndex != NSNotFound) {
+        return [self.document pageAtIndex:self.selectionPageIndex];
+    }
+    return nil;
+}
+
 - (CPDFAnnotation *)activeAnnotation {
     return self.activeAnnotations.lastObject;
 }

+ 64 - 4
PDF Office/PDF Master/KMClass/KMPDFViewController/KMMainViewController.swift

@@ -1283,13 +1283,25 @@ struct KMNMWCFlags {
     
     //MARK: - PopUI
     func reloadPopUIWindow() {
-        if(listView.isEditing() == false) {
+        if listView.toolMode == .selectToolMode {
+            let pageRect = listView.currentSelectionRect()
+            let page:CPDFPage? = listView.currentSelectionPage()
+            
+            if listView.selectionRect != CGRectZero  && page != nil {
+                let positioningRect = listView.convert(pageRect, from: page)
+                if (CGRectIntersectsRect(positioningRect, listView.frame)) {
+                    reloadPopUIOperation()
+                    return
+                }
+            }
+            toggleClosePopUIWindow()
+        } else if(listView.isEditing() == false) {
             let activeAnnotations:[CPDFAnnotation] = listView.activeAnnotations as! [CPDFAnnotation]
             if(activeAnnotations.count > 0) {
                 if let page = activeAnnotations.first?.page {
                     let pageRect = listView.selectionMultipleBounds(with: activeAnnotations)
                     let positioningRect = listView.convert(pageRect, from: page)
-                    if CGRectGetMinY(positioningRect) > 0 && CGRectGetMaxY(positioningRect) < listView.frame.height {
+                    if (CGRectIntersectsRect(positioningRect, listView.frame)) {
                         reloadPopUIActiveAnnotations(activeAnnotations: activeAnnotations)
                         return
                     }
@@ -1302,7 +1314,7 @@ struct KMNMWCFlags {
                 if let page = editAreas.first?.page {
                     let pageRect = listView.selectionMultipleBounds(withEditArea: editAreas)
                     let positioningRect = listView.convert(pageRect, from: page)
-                    if CGRectGetMinY(positioningRect) > 0 && CGRectGetMaxY(positioningRect) < listView.frame.height {
+                    if (CGRectIntersectsRect(positioningRect, listView.frame)) {
                         reloadPopUIContentEdits(editAreas: editAreas)
                         return
                     }
@@ -1321,6 +1333,11 @@ struct KMNMWCFlags {
         if editPopWindow.window?.isVisible  == true {
             closePopContentEditWindow()
         }
+        
+        let operationWindow = KMNPopOperationWindowController.shared
+        if operationWindow.window?.isVisible  == true {
+            closePopOperationWindow()
+        }
     }
     
     func closeAnnotationPopWindow() {
@@ -1331,6 +1348,38 @@ struct KMNMWCFlags {
         KMNPopContentEditWindowController.shared.closeWindow(listView: listView)
     }
     
+    func closePopOperationWindow() {
+        KMNPopOperationWindowController.shared.closeWindow(listView: listView)
+    }
+    
+    func reloadPopUIOperation() {
+        if listView.selectionRect != CGRectZero {
+            let popWindow = KMNPopOperationWindowController.shared
+
+            if popWindow.window?.isVisible == false {
+                listView.window?.addChildWindow(popWindow.window ?? NSWindow(), ordered: .above)
+            }
+            popWindow.listView = listView
+            if listView.toolMode == .selectToolMode {
+                popWindow.popType = .crop
+            }
+            updatePopOperationPopWinodwFrame()
+            popWindow.updatePDFViewCallback = {[weak self] in
+                self?.closePopOperationWindow()
+                self?.listView.setNeedsDisplayForVisiblePages()
+            }
+            
+            popWindow.cropCurrentCallback = {[weak self] in
+                let rect = self?.listView.currentSelectionRect() ?? CGRect.zero
+                let orgPage : CPDFPage = self?.listView.currentSelectionPage() ?? CPDFPage()
+                self?.cropPages(atIndexs: [orgPage.pageIndex()], to: [rect])
+                self?.closePopOperationWindow()
+            }
+        } else {
+            closePopOperationWindow()
+        }
+    }
+    
     func reloadPopUIActiveAnnotations(activeAnnotations:[CPDFAnnotation]) {
         let annotationMode = KMNAnnotationPopMode(pdfAnnotations: activeAnnotations )
         let popWindow = KMNPopAnnotationWindowController.shared
@@ -1398,6 +1447,13 @@ struct KMNMWCFlags {
         }
     }
     
+    func updatePopOperationPopWinodwFrame() {
+        let popWindow = KMNPopOperationWindowController.shared
+        if popWindow.window?.isVisible == true {
+            popWindow.updateFrame(listView: listView,page: listView.currentSelectionPage())
+        }
+    }
+
     //MARK: - Background背景
     func showBackgroundController() {
         
@@ -3336,6 +3392,10 @@ extension KMMainViewController: CPDFViewDelegate,CPDFListViewDelegate {
     
     //MARK: - CPDFListViewDelegate
     
+    func pdfListViewChangedToolMode(_ pdfListView: CPDFListView!, for toolMode: CToolMode) {
+        reloadPopUIWindow()
+    }
+    
     func pdfListViewChangeatioActiveAnnotations(_ pdfListView: CPDFListView!, forActiveAnnotations annotations: [CPDFAnnotation]!, isRightMenu: Bool) {
         self.view.window?.makeFirstResponder(self.listView)
         
@@ -3453,7 +3513,7 @@ extension KMMainViewController: CPDFViewDelegate,CPDFListViewDelegate {
         if (self.listView.toolMode != .selectToolMode) {
             return
         }
-        
+        reloadPopUIWindow()
     }
     
     func pdfListViewEventMarkupColor(with annotation: CPDFAnnotation!) -> [NSColor]! {

+ 3 - 3
PDF Office/PDF Master/KMClass/KMPDFViewController/KMMainViewController.xib

@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22505" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="21507" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
     <dependencies>
         <deployment identifier="macosx"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22505"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21507"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
     <objects>
@@ -63,7 +63,7 @@
                                                 <constraint firstAttribute="width" constant="44" id="d0h-VA-7VV"/>
                                             </constraints>
                                         </box>
-                                        <splitView dividerStyle="thin" vertical="YES" translatesAutoresizingMaskIntoConstraints="NO" id="0yW-dC-XWa">
+                                        <splitView dividerStyle="thin" vertical="YES" translatesAutoresizingMaskIntoConstraints="NO" id="0yW-dC-XWa" customClass="KMSplitView" customModule="PDF_Reader_Pro" customModuleProvider="target">
                                             <rect key="frame" x="44" y="0.0" width="762" height="361"/>
                                             <subviews>
                                                 <customView fixedFrame="YES" id="Rjd-la-yXL">

+ 6 - 0
PDF Office/PDF Master/KMClass/PDFListView/KMNListviewPopImage.xcassets/crop/Contents.json

@@ -0,0 +1,6 @@
+{
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

+ 22 - 0
PDF Office/PDF Master/KMClass/PDFListView/KMNListviewPopImage.xcassets/crop/KMNImageNameListViewCropAdd.imageset/Contents.json

@@ -0,0 +1,22 @@
+{
+  "images" : [
+    {
+      "filename" : "icon_prefix 1.pdf",
+      "idiom" : "universal"
+    },
+    {
+      "appearances" : [
+        {
+          "appearance" : "luminosity",
+          "value" : "dark"
+        }
+      ],
+      "filename" : "copy.pdf",
+      "idiom" : "universal"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
PDF Office/PDF Master/KMClass/PDFListView/KMNListviewPopImage.xcassets/crop/KMNImageNameListViewCropAdd.imageset/copy.pdf


BIN
PDF Office/PDF Master/KMClass/PDFListView/KMNListviewPopImage.xcassets/crop/KMNImageNameListViewCropAdd.imageset/icon_prefix 1.pdf


+ 22 - 0
PDF Office/PDF Master/KMClass/PDFListView/KMNListviewPopImage.xcassets/crop/KMNImageNameListViewCropClose.imageset/Contents.json

@@ -0,0 +1,22 @@
+{
+  "images" : [
+    {
+      "filename" : "icon_prefix 1.pdf",
+      "idiom" : "universal"
+    },
+    {
+      "appearances" : [
+        {
+          "appearance" : "luminosity",
+          "value" : "dark"
+        }
+      ],
+      "filename" : "icon_prefix.pdf",
+      "idiom" : "universal"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
PDF Office/PDF Master/KMClass/PDFListView/KMNListviewPopImage.xcassets/crop/KMNImageNameListViewCropClose.imageset/icon_prefix 1.pdf


BIN
PDF Office/PDF Master/KMClass/PDFListView/KMNListviewPopImage.xcassets/crop/KMNImageNameListViewCropClose.imageset/icon_prefix.pdf


+ 22 - 0
PDF Office/PDF Master/KMClass/PDFListView/KMNListviewPopImage.xcassets/crop/KMNImageNameListViewCropExport.imageset/Contents.json

@@ -0,0 +1,22 @@
+{
+  "images" : [
+    {
+      "filename" : "base-placeholder.pdf",
+      "idiom" : "universal"
+    },
+    {
+      "appearances" : [
+        {
+          "appearance" : "luminosity",
+          "value" : "dark"
+        }
+      ],
+      "filename" : "base-placeholder 1.pdf",
+      "idiom" : "universal"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
PDF Office/PDF Master/KMClass/PDFListView/KMNListviewPopImage.xcassets/crop/KMNImageNameListViewCropExport.imageset/base-placeholder 1.pdf


BIN
PDF Office/PDF Master/KMClass/PDFListView/KMNListviewPopImage.xcassets/crop/KMNImageNameListViewCropExport.imageset/base-placeholder.pdf


+ 22 - 0
PDF Office/PDF Master/KMClass/PDFListView/KMNListviewPopImage.xcassets/crop/KMNImageNameListViewCropPrint.imageset/Contents.json

@@ -0,0 +1,22 @@
+{
+  "images" : [
+    {
+      "filename" : "icon_prefix 1.pdf",
+      "idiom" : "universal"
+    },
+    {
+      "appearances" : [
+        {
+          "appearance" : "luminosity",
+          "value" : "dark"
+        }
+      ],
+      "filename" : "icon_prefix.pdf",
+      "idiom" : "universal"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
PDF Office/PDF Master/KMClass/PDFListView/KMNListviewPopImage.xcassets/crop/KMNImageNameListViewCropPrint.imageset/icon_prefix 1.pdf


BIN
PDF Office/PDF Master/KMClass/PDFListView/KMNListviewPopImage.xcassets/crop/KMNImageNameListViewCropPrint.imageset/icon_prefix.pdf


+ 22 - 0
PDF Office/PDF Master/KMClass/PDFListView/KMNListviewPopImage.xcassets/crop/KMNImageNameListViewCropRest.imageset/Contents.json

@@ -0,0 +1,22 @@
+{
+  "images" : [
+    {
+      "filename" : "icon_prefix 1.pdf",
+      "idiom" : "universal"
+    },
+    {
+      "appearances" : [
+        {
+          "appearance" : "luminosity",
+          "value" : "dark"
+        }
+      ],
+      "filename" : "icon_prefix.pdf",
+      "idiom" : "universal"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
PDF Office/PDF Master/KMClass/PDFListView/KMNListviewPopImage.xcassets/crop/KMNImageNameListViewCropRest.imageset/icon_prefix 1.pdf


BIN
PDF Office/PDF Master/KMClass/PDFListView/KMNListviewPopImage.xcassets/crop/KMNImageNameListViewCropRest.imageset/icon_prefix.pdf


+ 17 - 1
PDF Office/PDF Master/KMClass/PDFListView/WindowController/KMNPopAnnotationWindowController.swift

@@ -773,7 +773,7 @@ class KMNPopAnnotationWindowController: KMNBaseWindowController {
         if(page != nil) {
             let pageRect = listView.selectionMultipleBounds(with: activeAnnotations)
             let positioningRect = listView.convert(pageRect, from: page!)
-            if CGRectGetMinY(positioningRect) > 0 && CGRectGetMaxY(positioningRect) < listView.frame.height {
+            if (CGRectIntersectsRect(positioningRect, listView.frame)) {
                 let view: NSView? = nil
                 let position = listView.convert(positioningRect, to: view)
                 var positionNew = position.origin
@@ -785,6 +785,22 @@ class KMNPopAnnotationWindowController: KMNBaseWindowController {
                 positionRect.origin.x = positionNew.x - positionRect.width/2
                 positionRect.origin.y = positionNew.y + popOffSet
                 
+                var listViewWindRect = listView.convert(listView.frame, to: view)
+                listViewWindRect.origin.x += windowFram.origin.x
+                listViewWindRect.origin.y += windowFram.origin.y
+
+                if CGRectGetMaxY(positionRect) > CGRectGetMaxY(listViewWindRect) {
+                    positionRect.origin.y = CGRectGetMaxY(listViewWindRect)
+                }
+                
+                if CGRectGetMinX(positionRect) < CGRectGetMinX(listViewWindRect) {
+                    positionRect.origin.x = CGRectGetMinX(listViewWindRect)
+                }
+
+                if CGRectGetMaxX(positionRect) > CGRectGetMaxX(listViewWindRect) {
+                    positionRect.origin.x = CGRectGetMaxX(listViewWindRect) - positionRect.width
+                }
+                
                 self.window?.setFrame(positionRect, display: true)
                 
                 updateUILanguage()

+ 16 - 0
PDF Office/PDF Master/KMClass/PDFListView/WindowController/KMNPopContentEditWindowController.swift

@@ -673,6 +673,22 @@ class KMNPopContentEditWindowController: KMNBaseWindowController {
             positionRect.origin.x = positionNew.x - positionRect.width/2
             positionRect.origin.y = positionNew.y + popOffSet + CGFloat(truncating: listView.editingConfig().editAreaMargin)
             
+            var listViewWindRect = listView.convert(listView.frame, to: view)
+            listViewWindRect.origin.x += windowFram.origin.x
+            listViewWindRect.origin.y += windowFram.origin.y
+
+            if CGRectGetMaxY(positionRect) > CGRectGetMaxY(listViewWindRect) {
+                positionRect.origin.y = CGRectGetMaxY(listViewWindRect)
+            }
+            
+            if CGRectGetMinX(positionRect) < CGRectGetMinX(listViewWindRect) {
+                positionRect.origin.x = CGRectGetMinX(listViewWindRect)
+            }
+
+            if CGRectGetMaxX(positionRect) > CGRectGetMaxX(listViewWindRect) {
+                positionRect.origin.x = CGRectGetMaxX(listViewWindRect) - positionRect.width
+            }
+            
             self.window?.setFrame(positionRect, display: true)
             
             updateUILanguage()

+ 1 - 1
PDF Office/PDF Master/KMClass/PDFListView/WindowController/KMNPopContentEditWindowController.xib

@@ -48,7 +48,7 @@
             <windowStyleMask key="styleMask" fullSizeContentView="YES"/>
             <windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
             <rect key="contentRect" x="196" y="240" width="480" height="270"/>
-            <rect key="screenRect" x="0.0" y="0.0" width="2560" height="1415"/>
+            <rect key="screenRect" x="0.0" y="0.0" width="1512" height="944"/>
             <view key="contentView" id="se5-gp-TjO">
                 <rect key="frame" x="0.0" y="0.0" width="522" height="42"/>
                 <autoresizingMask key="autoresizingMask"/>

+ 354 - 0
PDF Office/PDF Master/KMClass/PDFListView/WindowController/KMNPopOperationWindowController.swift

@@ -0,0 +1,354 @@
+//
+//  KMNPopOperationWindowController.swift
+//  PDF Reader Pro
+//
+//  Created by 丁林圭 on 2024/12/12.
+//
+
+import Cocoa
+
+import KMComponentLibrary
+
+@objc public enum OperationType: Int, CaseIterable{
+    case crop = 0
+    case ocr
+    case operationNone
+}
+
+typealias OperaCropCallback = () -> ()
+
+class KMNPopOperationWindowController: KMNBaseWindowController {
+    
+    @IBOutlet weak var contentBox: NSBox!
+    @IBOutlet weak var operationBox: NSBox!
+    @IBOutlet weak var operationWidthConstraint: NSLayoutConstraint!
+    
+    @IBOutlet var cropView: NSView!
+    @IBOutlet var closeButton: ComponentButton!
+    @IBOutlet var printButton: ComponentButton!
+    @IBOutlet var extractSelect: ComponentCSelector!
+    @IBOutlet var resetButton: ComponentButton!
+    @IBOutlet var addButton: ComponentButton!
+    
+    @IBOutlet var ocrView: NSView!
+    @IBOutlet var cancelButton: ComponentButton!
+    @IBOutlet var ocrButton: ComponentButton!
+    @IBOutlet weak var cancelWidthConstraint: NSLayoutConstraint!
+    @IBOutlet weak var ocrWidthConstraint: NSLayoutConstraint!
+    
+    private var extractGroupView: ComponentGroup?
+    
+    static let shared: KMNPopOperationWindowController = {
+        let windowC = KMNPopOperationWindowController(windowNibName: "KMNPopOperationWindowController")
+        return windowC
+    }()
+    
+    var cropCurrentCallback: OperaCropCallback?
+    
+    var updatePDFViewCallback: UpdatePDFViewCallback?
+    
+    weak var listView:CPDFListView?
+    
+    public var popType:OperationType = .operationNone {
+        didSet {
+            
+            switch popType {
+            case .ocr :
+                ocrView.layoutSubtreeIfNeeded()
+                operationWidthConstraint.constant = ocrView.bounds.width
+                self.window?.display() //需刷新约束才会有值,不然会变化
+                operationBox.contentView = ocrView
+                break
+            case .crop:
+                cropView.layoutSubtreeIfNeeded()
+                
+                operationWidthConstraint.constant = cropView.bounds.width
+                self.window?.display() //需刷新约束才会有值,不然会变化
+                operationBox.contentView = cropView
+                break
+            case .operationNone:
+                break
+                
+            }
+        }
+    }
+    
+    override func windowDidLoad() {
+        super.windowDidLoad()
+    }
+    
+    override func initContentView() {
+        super.initContentView()
+        
+        extractSelect.properties = ComponentCSelectorProperty(iconImage:NSImage(named: "KMNImageNameListViewCropExport"))
+        extractSelect.setTarget(self, action: #selector(extractButtonClicked(_ :)))
+        
+        closeButton.properties = ComponentButtonProperty(type: .text_gray,
+                                                         size: .s,
+                                                         state: .normal,
+                                                         onlyIcon: true,
+                                                         icon:NSImage(named: "KMNImageNameListViewCropClose"),
+                                                         keepPressState: false)
+        closeButton.setTarget(self, action: #selector(closeButtonClicked(_ :)))
+        
+        printButton.properties = ComponentButtonProperty(type: .text_gray,
+                                                         size: .s,
+                                                         state: .normal,
+                                                         onlyIcon: true,
+                                                         icon:NSImage(named: "KMNImageNameListViewCropPrint"),
+                                                         keepPressState: false)
+        printButton.setTarget(self, action: #selector(printButtonClicked(_ :)))
+        
+        addButton.properties = ComponentButtonProperty(type: .text_gray,
+                                                       size: .s,
+                                                       state: .normal,
+                                                       onlyIcon: true,
+                                                       icon:NSImage(named: "KMNImageNameListViewCropAdd"),keepPressState: false)
+        addButton.setTarget(self, action: #selector(addButtonClicked(_ :)))
+        
+        resetButton.properties = ComponentButtonProperty(type: .text_gray,
+                                                         size: .s,
+                                                         state: .normal,
+                                                         onlyIcon: true,
+                                                         icon:NSImage(named: "KMNImageNameListViewCropRest"),
+                                                         keepPressState: false)
+        resetButton.setTarget(self, action: #selector(restButtonClicked(_ :)))
+    }
+    
+    override func updateUIThemeColor() {
+        super.updateUIThemeColor()
+        
+        contentBox.fillColor = ComponentLibrary.shared.getComponentColorFromKey("colorBg/popup")
+        contentBox.borderColor = ComponentLibrary.shared.getComponentColorFromKey("colorBorder/3-default")
+    }
+    
+    override func updateUILanguage() {
+        super.updateUILanguage()
+        
+        cancelButton.properties = ComponentButtonProperty(type: .default_tertiary,
+                                                          size: .s,
+                                                          state: .normal,
+                                                          buttonText: KMLocalizedString("Cancel"))
+        cancelButton.setTarget(self, action: #selector(cancelButtonClicked(_ :)))
+        
+        ocrButton.properties = ComponentButtonProperty(type: .primary,
+                                                       size: .s,
+                                                       state: .normal,
+                                                       buttonText: KMLocalizedString("OCR"))
+        ocrButton.setTarget(self, action: #selector(ocrButtonClicked(_ :)))
+        
+        ocrWidthConstraint.constant = ocrButton.properties.propertyInfo.viewWidth
+        cancelWidthConstraint.constant = cancelButton.properties.propertyInfo.viewWidth
+        
+    }
+    
+    func removeGroupView() {
+        if extractGroupView != nil {
+            extractGroupView?.removeFromSuperview()
+        }
+        extractSelect.properties.state = .normal
+        extractSelect.reloadData()
+    }
+    
+    //MARK: - Public
+    public func updateFrame(listView:CPDFListView?,page:CPDFPage?) {
+        let windowFram = listView?.window?.frame ?? CGRectZero
+        
+        let pageRect = listView?.currentSelectionRect() ?? NSRect.zero
+        
+        if page != nil {
+            let positioningRect = listView?.convert(pageRect, from: page!) ?? NSRect.zero
+            if (CGRectIntersectsRect(positioningRect, listView?.frame ?? CGRectZero)) {
+                let view: NSView? = nil
+                let position = listView?.convert(positioningRect, to: view) ?? NSRect.zero
+                var positionNew = position.origin
+                
+                positionNew.x += windowFram.origin.x + position.width
+                positionNew.y += windowFram.origin.y
+                
+                var positionRect = self.window?.frame ?? CGRectZero
+                positionRect.origin.x = positionNew.x - positionRect.width
+                positionRect.origin.y = positionNew.y - popOffSet - positionRect.height
+                
+                var listViewWindRect = listView?.convert(listView?.frame ?? CGRect.zero, to: view) ?? CGRect.zero
+                listViewWindRect.origin.x += windowFram.origin.x
+                listViewWindRect.origin.y += windowFram.origin.y
+                
+                if CGRectGetMinY(positionRect) < CGRectGetMinY(listViewWindRect) {
+                    positionRect.origin.y = positionNew.y + popOffSet + position.height
+                }
+                
+                if CGRectGetMinX(positionRect) < CGRectGetMinX(listViewWindRect) {
+                    positionRect.origin.x = CGRectGetMinX(listViewWindRect)
+                }
+                
+                if CGRectGetMaxX(positionRect) > CGRectGetMaxX(listViewWindRect) {
+                    positionRect.origin.x = CGRectGetMaxX(listViewWindRect) - positionRect.width
+                }
+                self.window?.setFrame(positionRect, display: true)
+                
+                updateUILanguage()
+            }
+        }
+        
+    }
+    
+    public func closeWindow(listView:CPDFListView?) {
+        if self.window?.isVisible == true {
+            listView?.window?.removeChildWindow(self.window ?? NSWindow())
+            self.window?.close()
+        }
+    }
+    
+    
+    //MARK: - Action
+    @objc func cancelButtonClicked(_ sender: NSView) {
+    }
+    
+    @objc func ocrButtonClicked(_ sender: NSView) {
+    }
+    
+    @objc func addButtonClicked(_ sender: NSView) {
+        let rect = NSIntegralRect(listView?.currentSelectionRect() ?? CGRect.zero)
+        let orgPage : CPDFPage = listView?.currentSelectionPage() ?? CPDFPage()
+        
+        if let page : CPDFPage = orgPage.copy() as? CPDFPage {
+            page.setBounds(rect, for: .cropBox)
+            let image = page.thumbnail(of: rect.size) ?? NSImage()
+            let data = image.tiffRepresentation
+            let imageItem = NSPasteboardItem()
+            imageItem.setData(data ?? Data(), forType: .tiff)
+            let pboard = NSPasteboard.general
+            pboard.clearContents()
+
+            pboard.writeObjects([imageItem])
+        }
+    }
+    
+    @objc func printButtonClicked(_ sender: NSView) {
+        let rect = listView?.currentSelectionRect() ?? CGRect.zero
+        let page = listView?.currentPage()
+        if page != nil {
+            let copyPage : CPDFPage = page!.copy() as! CPDFPage
+            copyPage.setBounds(rect, for: .cropBox)
+            let image : NSImage = copyPage.thumbnail(of:(copyPage.bounds(for: .cropBox)).size)
+            KMPrintWindowController.printImage(image: image)
+        }
+    }
+    
+    @objc func restButtonClicked(_ sender: NSView) {
+        cropCurrentCallback?()
+    }
+    
+    @objc func extractButtonClicked(_ sender: NSView) {
+        if extractGroupView?.superview != nil {
+            removeGroupView()
+        } else {
+            var viewHeight: CGFloat = 8
+            var menuItemArr: [ComponentMenuitemProperty] = []
+            for i in ["jpg", "png", "pdf"] {
+                let properties_Menuitem: ComponentMenuitemProperty = ComponentMenuitemProperty(multipleSelect: false,
+                                                                                               itemSelected: false,
+                                                                                               isDisabled: false,
+                                                                                               keyEquivalent: nil,
+                                                                                               text: KMLocalizedString(i))
+                menuItemArr.append(properties_Menuitem)
+                viewHeight += 36
+            }
+            
+            if extractGroupView == nil {
+                extractGroupView = ComponentGroup.createFromNib(in: ComponentLibrary.shared.componentBundle())
+            }
+            extractGroupView?.groupDelegate = self
+            extractGroupView?.frame = CGRectMake(310, 0, 72, viewHeight)
+            extractGroupView?.updateGroupInfo(menuItemArr)
+            
+            let point = CGPoint(x: sender.frame.origin.x + sender.frame.size.width/2, y: CGRectGetMinY(sender.frame) - viewHeight)
+            extractGroupView?.showWithPoint(point, relativeTo: self.window?.contentView)
+            
+            extractSelect.properties.state = .pressed
+            extractSelect.reloadData()
+        }
+    }
+    
+    @objc func closeButtonClicked(_ sender: NSView) {
+        listView?.selectionRect = NSZeroRect
+        listView?.selectionPageIndex = UInt(NSNotFound)
+        updatePDFViewCallback?()
+    }
+}
+
+extension KMNPopOperationWindowController: ComponentGroupDelegate {
+    func componentGroupDidDismiss(group: ComponentGroup?) {
+        removeGroupView()
+        
+        extractSelect.properties.state = .normal
+        extractSelect.reloadData()
+    }
+    
+    func componentGroupDidSelect(group: ComponentGroup?, menuItemProperty: ComponentMenuitemProperty?) {
+        if group == extractGroupView {
+            let rect = NSIntegralRect(listView?.currentSelectionRect() ?? CGRect.zero)
+            let orgPage : CPDFPage = listView?.currentSelectionPage() ?? CPDFPage()
+            
+            if let page : CPDFPage = orgPage.copy() as? CPDFPage {
+                page.setBounds(rect, for: .cropBox)
+                let image = page.thumbnail(of: rect.size) ?? NSImage()
+                let data = image.tiffRepresentation
+                guard let data = data else { return }
+                let imageRep : NSBitmapImageRep = NSBitmapImageRep(data: data) ?? NSBitmapImageRep()
+                imageRep.size = rect.size
+                
+                let savePanel = NSSavePanel()
+                if let selItem = menuItemProperty {
+                    let index = group?.menuItemArr.firstIndex(of: selItem)
+                    if index == 0 {
+                        savePanel.allowedFileTypes = ["jpg"]
+                        
+                        let imageData : Data = imageRep.representation(using: NSBitmapImageRep.FileType.jpeg, properties: [:])!
+                        savePanel.beginSheetModal(for: listView?.window ?? NSWindow()) { response in
+                            if (response != .OK) {
+                                return
+                            }
+                            if NSData(data: imageData).write(to: savePanel.url!, atomically: true) {
+                                NSWorkspace.shared.selectFile(savePanel.url?.path, inFileViewerRootedAtPath: "");
+                            }
+                        }
+                    } else if index == 1 {
+                        savePanel.allowedFileTypes = ["png"]
+                        
+                        let imageData : Data = imageRep.representation(using: NSBitmapImageRep.FileType.png, properties: [:])!
+                        savePanel.beginSheetModal(for: listView?.window ?? NSWindow()) { response in
+                            if (response != .OK) {
+                                return
+                            }
+                            if NSData(data: imageData).write(to: savePanel.url!, atomically: true) {
+                                NSWorkspace.shared.selectFile(savePanel.url?.path, inFileViewerRootedAtPath: "");
+                            }
+                        }
+                        
+                    } else if index == 2 {
+                        savePanel.allowedFileTypes = ["pdf"]
+                        
+                        let pdfdocument = CPDFDocument()
+                        let signatureImagePath = NSSearchPathForDirectoriesInDomains(.applicationSupportDirectory, .userDomainMask, true).first?.stringByAppendingPathComponent("signatureImage.png")
+                        let imageData : Data = imageRep.representation(using: NSBitmapImageRep.FileType.jpeg, properties: [:])!
+                        if NSData(data: imageData).write(to: URL(fileURLWithPath: signatureImagePath!), atomically: true) {
+                            pdfdocument?.insertPage(image.size, withImage: signatureImagePath, at: 0)
+                            
+                            savePanel.beginSheetModal(for: listView?.window ?? NSWindow()) { response in
+                                if (response != .OK) {
+                                    return
+                                }
+                                if pdfdocument!.write(to: savePanel.url!) {
+                                    NSWorkspace.shared.selectFile(savePanel.url?.path, inFileViewerRootedAtPath: "");
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
+

+ 165 - 0
PDF Office/PDF Master/KMClass/PDFListView/WindowController/KMNPopOperationWindowController.xib

@@ -0,0 +1,165 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="21507" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
+    <dependencies>
+        <deployment identifier="macosx"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21507"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <customObject id="-2" userLabel="File's Owner" customClass="KMNPopOperationWindowController" customModule="PDF_Reader_Pro" customModuleProvider="target">
+            <connections>
+                <outlet property="addButton" destination="PBX-i1-e6g" id="91X-bM-ugQ"/>
+                <outlet property="cancelButton" destination="MMF-Xu-ewX" id="jyK-hF-rmo"/>
+                <outlet property="cancelWidthConstraint" destination="htL-pp-zyB" id="5lb-yf-pmF"/>
+                <outlet property="closeButton" destination="Aub-bK-nQW" id="NWJ-J5-OpN"/>
+                <outlet property="contentBox" destination="yhB-Bi-Ro3" id="Mec-Dl-aBN"/>
+                <outlet property="cropView" destination="X21-U7-7U1" id="dpq-kI-dG0"/>
+                <outlet property="extractSelect" destination="zWf-eJ-tuk" id="64Q-dJ-YiA"/>
+                <outlet property="ocrButton" destination="Vkh-ex-bd4" id="8q3-9S-md1"/>
+                <outlet property="ocrView" destination="ra5-zP-zkh" id="4wG-Dg-WeB"/>
+                <outlet property="ocrWidthConstraint" destination="aDV-jG-7wI" id="sAr-QM-WSm"/>
+                <outlet property="operationBox" destination="5OK-yK-3wT" id="BaR-68-Dqe"/>
+                <outlet property="operationWidthConstraint" destination="eVG-8t-niH" id="3Bj-LQ-leU"/>
+                <outlet property="printButton" destination="UJL-SM-aZ0" id="lRe-Pj-0ou"/>
+                <outlet property="resetButton" destination="POE-RM-2eD" id="oGb-pg-JYK"/>
+                <outlet property="window" destination="F0z-JX-Cv5" id="gIp-Ho-8D9"/>
+            </connections>
+        </customObject>
+        <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
+        <customObject id="-3" userLabel="Application" customClass="NSObject"/>
+        <window allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" titlebarAppearsTransparent="YES" id="F0z-JX-Cv5" customClass="KMNPopOperationWindow" customModule="PDF_Reader_Pro" customModuleProvider="target">
+            <windowStyleMask key="styleMask" titled="YES" fullSizeContentView="YES"/>
+            <windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
+            <rect key="contentRect" x="196" y="240" width="480" height="270"/>
+            <rect key="screenRect" x="0.0" y="0.0" width="1512" height="944"/>
+            <view key="contentView" id="se5-gp-TjO">
+                <rect key="frame" x="0.0" y="0.0" width="470" height="42"/>
+                <autoresizingMask key="autoresizingMask"/>
+                <subviews>
+                    <box boxType="custom" cornerRadius="4" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="yhB-Bi-Ro3">
+                        <rect key="frame" x="0.0" y="0.0" width="470" height="42"/>
+                        <view key="contentView" id="DQm-Zl-I4t">
+                            <rect key="frame" x="1" y="1" width="468" height="40"/>
+                            <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                            <subviews>
+                                <box boxType="custom" borderWidth="0.0" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="5OK-yK-3wT">
+                                    <rect key="frame" x="8" y="3" width="452" height="34"/>
+                                    <view key="contentView" id="EbK-s7-nRj">
+                                        <rect key="frame" x="0.0" y="0.0" width="452" height="34"/>
+                                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                                    </view>
+                                    <constraints>
+                                        <constraint firstAttribute="width" constant="452" id="eVG-8t-niH"/>
+                                        <constraint firstAttribute="height" constant="34" id="uno-eF-wiz"/>
+                                    </constraints>
+                                </box>
+                            </subviews>
+                            <constraints>
+                                <constraint firstAttribute="bottom" secondItem="5OK-yK-3wT" secondAttribute="bottom" constant="3" id="1h9-C6-Mcj"/>
+                                <constraint firstItem="5OK-yK-3wT" firstAttribute="top" secondItem="DQm-Zl-I4t" secondAttribute="top" constant="3" id="mCM-IY-1NW"/>
+                                <constraint firstItem="5OK-yK-3wT" firstAttribute="leading" secondItem="DQm-Zl-I4t" secondAttribute="leading" constant="8" id="pXS-WS-T18"/>
+                                <constraint firstAttribute="trailing" secondItem="5OK-yK-3wT" secondAttribute="trailing" constant="8" id="rRY-Xe-OH7"/>
+                            </constraints>
+                        </view>
+                    </box>
+                </subviews>
+                <constraints>
+                    <constraint firstAttribute="trailing" secondItem="yhB-Bi-Ro3" secondAttribute="trailing" id="XAH-WR-5gZ"/>
+                    <constraint firstItem="yhB-Bi-Ro3" firstAttribute="top" secondItem="se5-gp-TjO" secondAttribute="top" id="arh-I2-joD"/>
+                    <constraint firstItem="yhB-Bi-Ro3" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" id="hSt-6g-nOX"/>
+                    <constraint firstAttribute="bottom" secondItem="yhB-Bi-Ro3" secondAttribute="bottom" id="wbq-jo-KQu"/>
+                </constraints>
+            </view>
+            <connections>
+                <outlet property="delegate" destination="-2" id="0bl-1N-AYu"/>
+            </connections>
+            <point key="canvasLocation" x="31" y="-102"/>
+        </window>
+        <customView id="X21-U7-7U1">
+            <rect key="frame" x="0.0" y="0.0" width="176" height="34"/>
+            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
+            <subviews>
+                <customView translatesAutoresizingMaskIntoConstraints="NO" id="PBX-i1-e6g" customClass="ComponentButton" customModule="KMComponentLibrary">
+                    <rect key="frame" x="0.0" y="0.0" width="32" height="34"/>
+                    <constraints>
+                        <constraint firstAttribute="width" constant="32" id="IHh-Ly-WbP"/>
+                        <constraint firstAttribute="height" constant="34" id="kOQ-dn-X40"/>
+                    </constraints>
+                </customView>
+                <customView translatesAutoresizingMaskIntoConstraints="NO" id="zWf-eJ-tuk" customClass="ComponentCSelector" customModule="KMComponentLibrary">
+                    <rect key="frame" x="36" y="0.0" width="32" height="34"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="34" id="F9k-UA-UOt"/>
+                        <constraint firstAttribute="width" constant="32" id="Gpi-Sv-9L0"/>
+                    </constraints>
+                </customView>
+                <customView translatesAutoresizingMaskIntoConstraints="NO" id="POE-RM-2eD" customClass="ComponentButton" customModule="KMComponentLibrary">
+                    <rect key="frame" x="72" y="0.0" width="32" height="34"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="34" id="aHx-l7-WEl"/>
+                        <constraint firstAttribute="width" constant="32" id="nLY-Oh-RBU"/>
+                    </constraints>
+                </customView>
+                <customView translatesAutoresizingMaskIntoConstraints="NO" id="UJL-SM-aZ0" customClass="ComponentButton" customModule="KMComponentLibrary">
+                    <rect key="frame" x="108" y="0.0" width="32" height="34"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="34" id="j8v-tP-JUV"/>
+                        <constraint firstAttribute="width" constant="32" id="sGU-zS-I0o"/>
+                    </constraints>
+                </customView>
+                <customView translatesAutoresizingMaskIntoConstraints="NO" id="Aub-bK-nQW" customClass="ComponentButton" customModule="KMComponentLibrary">
+                    <rect key="frame" x="144" y="0.0" width="32" height="34"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="34" id="bun-56-f21"/>
+                        <constraint firstAttribute="width" constant="32" id="qbJ-oi-Dae"/>
+                    </constraints>
+                </customView>
+            </subviews>
+            <constraints>
+                <constraint firstItem="POE-RM-2eD" firstAttribute="leading" secondItem="zWf-eJ-tuk" secondAttribute="trailing" constant="4" id="4bQ-Qg-672"/>
+                <constraint firstItem="zWf-eJ-tuk" firstAttribute="leading" secondItem="PBX-i1-e6g" secondAttribute="trailing" constant="4" id="Cc3-9h-HPk"/>
+                <constraint firstAttribute="trailing" secondItem="Aub-bK-nQW" secondAttribute="trailing" id="JH2-X8-Ltg"/>
+                <constraint firstItem="POE-RM-2eD" firstAttribute="centerY" secondItem="X21-U7-7U1" secondAttribute="centerY" id="Tf5-CZ-KL4"/>
+                <constraint firstItem="Aub-bK-nQW" firstAttribute="leading" secondItem="UJL-SM-aZ0" secondAttribute="trailing" constant="4" id="VJL-r0-ae5"/>
+                <constraint firstAttribute="bottom" secondItem="PBX-i1-e6g" secondAttribute="bottom" id="cxI-48-aFa"/>
+                <constraint firstItem="Aub-bK-nQW" firstAttribute="centerY" secondItem="X21-U7-7U1" secondAttribute="centerY" id="g34-IK-erN"/>
+                <constraint firstItem="UJL-SM-aZ0" firstAttribute="leading" secondItem="POE-RM-2eD" secondAttribute="trailing" constant="4" id="jOk-Ct-8ly"/>
+                <constraint firstItem="UJL-SM-aZ0" firstAttribute="centerY" secondItem="X21-U7-7U1" secondAttribute="centerY" id="nO6-KN-1my"/>
+                <constraint firstItem="zWf-eJ-tuk" firstAttribute="centerY" secondItem="X21-U7-7U1" secondAttribute="centerY" id="suK-fX-sYg"/>
+                <constraint firstItem="PBX-i1-e6g" firstAttribute="top" secondItem="X21-U7-7U1" secondAttribute="top" id="xIb-6l-bY5"/>
+                <constraint firstItem="PBX-i1-e6g" firstAttribute="leading" secondItem="X21-U7-7U1" secondAttribute="leading" id="yum-Nd-AbN"/>
+            </constraints>
+            <point key="canvasLocation" x="58" y="349"/>
+        </customView>
+        <customView id="ra5-zP-zkh">
+            <rect key="frame" x="0.0" y="0.0" width="160" height="34"/>
+            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
+            <subviews>
+                <customView translatesAutoresizingMaskIntoConstraints="NO" id="MMF-Xu-ewX" customClass="ComponentButton" customModule="KMComponentLibrary">
+                    <rect key="frame" x="0.0" y="0.0" width="80" height="34"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="34" id="YIm-aB-ucy"/>
+                        <constraint firstAttribute="width" constant="80" id="htL-pp-zyB"/>
+                    </constraints>
+                </customView>
+                <customView translatesAutoresizingMaskIntoConstraints="NO" id="Vkh-ex-bd4" customClass="ComponentButton" customModule="KMComponentLibrary">
+                    <rect key="frame" x="80" y="0.0" width="80" height="34"/>
+                    <constraints>
+                        <constraint firstAttribute="width" constant="80" id="aDV-jG-7wI"/>
+                    </constraints>
+                </customView>
+            </subviews>
+            <constraints>
+                <constraint firstAttribute="bottom" secondItem="MMF-Xu-ewX" secondAttribute="bottom" id="3fI-V2-55f"/>
+                <constraint firstItem="Vkh-ex-bd4" firstAttribute="leading" secondItem="MMF-Xu-ewX" secondAttribute="trailing" id="BeC-k4-rws"/>
+                <constraint firstItem="MMF-Xu-ewX" firstAttribute="top" secondItem="ra5-zP-zkh" secondAttribute="top" id="Krz-V0-uy6"/>
+                <constraint firstItem="Vkh-ex-bd4" firstAttribute="top" secondItem="ra5-zP-zkh" secondAttribute="top" id="PKf-Yt-au6"/>
+                <constraint firstItem="MMF-Xu-ewX" firstAttribute="leading" secondItem="ra5-zP-zkh" secondAttribute="leading" id="Q8J-hV-0zj"/>
+                <constraint firstItem="Vkh-ex-bd4" firstAttribute="top" secondItem="ra5-zP-zkh" secondAttribute="top" id="Zn6-8f-gNc"/>
+                <constraint firstAttribute="trailing" secondItem="Vkh-ex-bd4" secondAttribute="trailing" id="fEL-VV-CfD"/>
+                <constraint firstAttribute="bottom" secondItem="Vkh-ex-bd4" secondAttribute="bottom" id="tDP-6k-Jsk"/>
+            </constraints>
+            <point key="canvasLocation" x="73" y="528"/>
+        </customView>
+    </objects>
+</document>

+ 16 - 0
PDF Office/PDF Reader Pro.xcodeproj/project.pbxproj

@@ -5198,6 +5198,12 @@
 		F337CC482CC7EEE100D46AF4 /* KMNPDFInsertPDFWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = F337CC442CC7EEE100D46AF4 /* KMNPDFInsertPDFWindowController.xib */; };
 		F337CC492CC7EEE100D46AF4 /* KMNPDFInsertPDFWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = F337CC442CC7EEE100D46AF4 /* KMNPDFInsertPDFWindowController.xib */; };
 		F337CC4A2CC7EEE100D46AF4 /* KMNPDFInsertPDFWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = F337CC442CC7EEE100D46AF4 /* KMNPDFInsertPDFWindowController.xib */; };
+		F33B30472D0B22410073DD1B /* KMNPopOperationWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F33B30452D0B22410073DD1B /* KMNPopOperationWindowController.swift */; };
+		F33B30482D0B22410073DD1B /* KMNPopOperationWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F33B30452D0B22410073DD1B /* KMNPopOperationWindowController.swift */; };
+		F33B30492D0B22410073DD1B /* KMNPopOperationWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F33B30452D0B22410073DD1B /* KMNPopOperationWindowController.swift */; };
+		F33B304A2D0B22410073DD1B /* KMNPopOperationWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = F33B30462D0B22410073DD1B /* KMNPopOperationWindowController.xib */; };
+		F33B304B2D0B22410073DD1B /* KMNPopOperationWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = F33B30462D0B22410073DD1B /* KMNPopOperationWindowController.xib */; };
+		F33B304C2D0B22410073DD1B /* KMNPopOperationWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = F33B30462D0B22410073DD1B /* KMNPopOperationWindowController.xib */; };
 		F34BF926295303E8002C25A2 /* NSCursor+PDFListView.m in Sources */ = {isa = PBXBuildFile; fileRef = F34BF925295303E8002C25A2 /* NSCursor+PDFListView.m */; };
 		F34BF927295303E8002C25A2 /* NSCursor+PDFListView.m in Sources */ = {isa = PBXBuildFile; fileRef = F34BF925295303E8002C25A2 /* NSCursor+PDFListView.m */; };
 		F34BF928295303E8002C25A2 /* NSCursor+PDFListView.m in Sources */ = {isa = PBXBuildFile; fileRef = F34BF925295303E8002C25A2 /* NSCursor+PDFListView.m */; };
@@ -7583,6 +7589,8 @@
 		F337CC3E2CC78B9400D46AF4 /* KMNThumbnailImage.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = KMNThumbnailImage.xcassets; sourceTree = "<group>"; };
 		F337CC432CC7EEE100D46AF4 /* KMNPDFInsertPDFWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMNPDFInsertPDFWindowController.swift; sourceTree = "<group>"; };
 		F337CC442CC7EEE100D46AF4 /* KMNPDFInsertPDFWindowController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = KMNPDFInsertPDFWindowController.xib; sourceTree = "<group>"; };
+		F33B30452D0B22410073DD1B /* KMNPopOperationWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMNPopOperationWindowController.swift; sourceTree = "<group>"; };
+		F33B30462D0B22410073DD1B /* KMNPopOperationWindowController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = KMNPopOperationWindowController.xib; sourceTree = "<group>"; };
 		F34BF924295303E8002C25A2 /* NSCursor+PDFListView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSCursor+PDFListView.h"; sourceTree = "<group>"; };
 		F34BF925295303E8002C25A2 /* NSCursor+PDFListView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSCursor+PDFListView.m"; sourceTree = "<group>"; };
 		F34BF93329530708002C25A2 /* NSImage+PDFListView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSImage+PDFListView.h"; sourceTree = "<group>"; };
@@ -14159,6 +14167,8 @@
 				F367D4DE2CFD62DB00B0BB4E /* KMNPopAnnotationWindowController.xib */,
 				F30619BE2CFDF5E60047E288 /* KMNPopContentEditWindowController.swift */,
 				F30619BF2CFDF5E60047E288 /* KMNPopContentEditWindowController.xib */,
+				F33B30452D0B22410073DD1B /* KMNPopOperationWindowController.swift */,
+				F33B30462D0B22410073DD1B /* KMNPopOperationWindowController.xib */,
 			);
 			path = WindowController;
 			sourceTree = "<group>";
@@ -14904,6 +14914,7 @@
 				BB99ACD2292E2AEF0048AFD9 /* KMMergeCollectionViewItem.xib in Resources */,
 				9FF94F1429A7476000B1EF69 /* KMDesignPropertySelector.xib in Resources */,
 				BB8810882B4F7C2200AFA63E /* KMVerificationAlertViewController.xib in Resources */,
+				F33B304A2D0B22410073DD1B /* KMNPopOperationWindowController.xib in Resources */,
 				BBA2109429ACC10F00E6B346 /* signlist_add.pdf in Resources */,
 				BB1969D12B2833FF00922736 /* KMProgressWindowController.xib in Resources */,
 				ADE86A7B2B0221E100414DFA /* KMSecurityWindowController.xib in Resources */,
@@ -15323,6 +15334,7 @@
 				BBD922342B50D61200DB9585 /* KMRateWindowController.xib in Resources */,
 				BBE7888B2CBD2463008086E2 /* SidebarDemoVC.xib in Resources */,
 				ADBC373829CA975B00D93208 /* KMCompatative.xcassets in Resources */,
+				F33B304B2D0B22410073DD1B /* KMNPopOperationWindowController.xib in Resources */,
 				BB4EEF3129763EE7003A3537 /* KMRedactBaseWindowController.xib in Resources */,
 				BB19A7372CB79D77008204DC /* KMHomeRecommondView.xib in Resources */,
 				BB1B0B082B4FC6E900889528 /* KMGuideCoverView.xib in Resources */,
@@ -15892,6 +15904,7 @@
 				9F1F82E82934D5240092C4B4 /* KMHomeExtractActionViewController.xib in Resources */,
 				ADDF83612B391A5C00A81A4E /* DSignatureCertifyDetailViewController.xib in Resources */,
 				BBA9222A2B4E96450061057A /* KMPurchaseCompareWindowController.xib in Resources */,
+				F33B304C2D0B22410073DD1B /* KMNPopOperationWindowController.xib in Resources */,
 				F3B7DF9F2948565000333201 /* CPDFListHoverAnnotationViewController.xib in Resources */,
 				BB5A9D322CB6520100F64C1F /* KMNHomeViewController.xib in Resources */,
 				AD3AAD292B0B6FB100DE5FE7 /* KMCompareContentView.xib in Resources */,
@@ -16413,6 +16426,7 @@
 				BB67EE172B54FFEF00573BF0 /* ASIDataCompressor.m in Sources */,
 				BB8F4565295AA3ED0037EA22 /* KMHeaderFooterManager.swift in Sources */,
 				F34BF926295303E8002C25A2 /* NSCursor+PDFListView.m in Sources */,
+				F33B30472D0B22410073DD1B /* KMNPopOperationWindowController.swift in Sources */,
 				9F705F8D291E579F005199AD /* KMHistoryFileTableView.swift in Sources */,
 				BB003035298D356E002DD1A0 /* KMPreferenceMarkupColorView.swift in Sources */,
 				ADE614AC29779C5200F62ED7 /* KMImageTitleButton.swift in Sources */,
@@ -18693,6 +18707,7 @@
 				9F1FE4A329406E4700E952CA /* CTToolbarController.m in Sources */,
 				BB6719FA2AD2CC05003D44D5 /* CPDFSignatureWidgetAnnotation+PDFListView.swift in Sources */,
 				BB1E7F312B511079002D9785 /* SKInspectPublicTool.swift in Sources */,
+				F33B30482D0B22410073DD1B /* KMNPopOperationWindowController.swift in Sources */,
 				BB2EDF71296ECE17003BCF58 /* KMPageEditThumbnailView.swift in Sources */,
 				BB3A668D2B06FD0100575343 /* KMBotaEnum.swift in Sources */,
 				BB65A0792AF8E2F2003A27A0 /* KMSyncPreferences.swift in Sources */,
@@ -19746,6 +19761,7 @@
 				AD1CA41B2A061CE10070541F /* KMAnnotationScreenTypeViewItem.swift in Sources */,
 				BB8AA53A2CC65C900084F183 /* KMNAlignmentController.swift in Sources */,
 				BBE0689C2CDDF137000512BC /* KMBatesTemplateController.swift in Sources */,
+				F33B30492D0B22410073DD1B /* KMNPopOperationWindowController.swift in Sources */,
 				BB276A4E2B03760000AB5578 /* KMOperationQueue.swift in Sources */,
 				9F94617F2BD643720076574B /* KMTableAnnotation.m in Sources */,
 				AD055E552B73220A0035F824 /* KMBookmarkManager.swift in Sources */,