Browse Source

【综合】解决冲突

tangchao 1 year ago
parent
commit
8b44f55400
67 changed files with 5438 additions and 196 deletions
  1. 425 0
      PDF Office/PDF Master.xcodeproj/project.pbxproj
  2. 50 69
      PDF Office/PDF Master.xcodeproj/xcuserdata/lizhe.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
  3. 1 1
      PDF Office/PDF Master/AppDelegate.swift
  4. 2 2
      PDF Office/PDF Master/Base.lproj/Main.storyboard
  5. 18 0
      PDF Office/PDF Master/Class/Batch/Catogary/NSArray+Extension.swift
  6. 66 0
      PDF Office/PDF Master/Class/Batch/Catogary/NSButton+CustomAppearance.swift
  7. 53 0
      PDF Office/PDF Master/Class/Batch/Catogary/NSWindow+PopOver.swift
  8. 281 0
      PDF Office/PDF Master/Class/Batch/Data/KMBatchBaseParameter.swift
  9. 149 0
      PDF Office/PDF Master/Class/Batch/Data/KMBatchConvertParameter.swift
  10. 322 0
      PDF Office/PDF Master/Class/Batch/Data/KMBatchOperateFile.swift
  11. 100 0
      PDF Office/PDF Master/Class/Batch/Tools/KMBatchHeader.swift
  12. 14 0
      PDF Office/PDF Master/Class/Batch/Tools/KMImageToPDFMethod.swift
  13. 406 0
      PDF Office/PDF Master/Class/Batch/View/KMBatchTableCellView.swift
  14. 19 0
      PDF Office/PDF Master/Class/Batch/View/KMBatchWindow.swift
  15. 96 0
      PDF Office/PDF Master/Class/Batch/View/KMLongerButton.swift
  16. 58 0
      PDF Office/PDF Master/Class/Batch/View/KMTableHeaderCell.swift
  17. 75 0
      PDF Office/PDF Master/Class/Batch/WindowController/KMAlertWindowController.swift
  18. 86 0
      PDF Office/PDF Master/Class/Batch/WindowController/KMAlertWindowController.xib
  19. 31 0
      PDF Office/PDF Master/Class/Batch/WindowController/KMBatchOperateBaseWindowController.swift
  20. 30 0
      PDF Office/PDF Master/Class/Batch/WindowController/KMBatchOperateBaseWindowController.xib
  21. 786 0
      PDF Office/PDF Master/Class/Batch/WindowController/KMBatchOperateLeftViewController.swift
  22. 334 0
      PDF Office/PDF Master/Class/Batch/WindowController/KMBatchOperateLeftViewController.xib
  23. 12 0
      PDF Office/PDF Master/Class/Batch/WindowController/KMBatchOperateRightViewController.swift
  24. 22 0
      PDF Office/PDF Master/Class/Batch/WindowController/KMBatchOperateRightViewController.xib
  25. 37 0
      PDF Office/PDF Master/Class/Batch/WindowController/KMBatchOperateSplitViewController.swift
  26. 32 0
      PDF Office/PDF Master/Class/Batch/WindowController/KMBatchOperateSplitViewController.xib
  27. 53 0
      PDF Office/PDF Master/Class/Batch/WindowController/KMBatchOperateWindowController.swift
  28. 30 0
      PDF Office/PDF Master/Class/Batch/WindowController/KMBatchOperateWindowController.xib
  29. 19 19
      PDF Office/PDF Master/Class/Common/Category/NSWindow+KMExtension.swift
  30. 282 0
      PDF Office/PDF Master/Class/Home/View/HomeContentView/History/Cell/KMHomeHistoryCollectionItem.swift
  31. 197 0
      PDF Office/PDF Master/Class/Home/View/HomeContentView/History/Cell/KMHomeHistoryCollectionItem.xib
  32. 131 0
      PDF Office/PDF Master/Class/Home/View/HomeContentView/History/KMHomeHistoryListView.swift
  33. 56 0
      PDF Office/PDF Master/Class/Home/View/HomeContentView/History/KMHomeHistoryListView.xib
  34. 75 0
      PDF Office/PDF Master/Class/Home/View/HomeContentView/KMHomeContentView.swift
  35. 252 0
      PDF Office/PDF Master/Class/Home/View/HomeContentView/KMHomeContentView.xib
  36. 18 0
      PDF Office/PDF Master/Class/Home/View/HomeContentView/NoFileView/KMHomeNOFileView.swift
  37. 71 0
      PDF Office/PDF Master/Class/Home/View/HomeContentView/NoFileView/KMHomeNOFileView.xib
  38. 98 0
      PDF Office/PDF Master/Class/Home/View/HomeContentView/QucikTools/KMQucikToolsView.swift
  39. 56 0
      PDF Office/PDF Master/Class/Home/View/HomeContentView/QucikTools/KMQucikToolsView.xib
  40. 116 0
      PDF Office/PDF Master/Class/Home/View/HomeContentView/QucikTools/Model/KMQucikToolsModel.swift
  41. 123 0
      PDF Office/PDF Master/Class/Home/View/HomeContentView/QucikTools/View/KMQucikToolCollectionViewItem.swift
  42. 204 0
      PDF Office/PDF Master/Class/Home/View/HomeContentView/QucikTools/View/KMQucikToolCollectionViewItem.xib
  43. 1 1
      PDF Office/PDF Master/Class/Home/ViewController/KMFastToolCollectionViewItem.swift
  44. 5 5
      PDF Office/PDF Master/Class/Home/ViewController/KMFastToolCollectionViewItem.xib
  45. 9 8
      PDF Office/PDF Master/Class/Home/ViewController/KMHistoryFileCollectionViewItem.xib
  46. 6 6
      PDF Office/PDF Master/Class/Home/ViewController/KMHomeFastToolViewController.xib
  47. 13 13
      PDF Office/PDF Master/Class/Home/ViewController/KMHomeHistoryFileViewController.xib
  48. 6 0
      PDF Office/PDF Master/Class/Home/ViewController/KMHomeViewController.swift
  49. 9 1
      PDF Office/PDF Master/Class/Home/ViewController/KMHomeViewController.xib
  50. 11 10
      PDF Office/PDF Master/Class/Home/WindowController/KMAITranslationConfirmWindowController.xib
  51. 29 28
      PDF Office/PDF Master/Class/Home/WindowController/KMAITranslationWindowController.xib
  52. 4 3
      PDF Office/PDF Master/Class/Home/WindowController/KMHistoryFileDeleteWindowController.xib
  53. 1 1
      PDF Office/PDF Master/Class/Home/WindowController/KMURLToPDFWindowController/KMURLToPDFWindowController.xib
  54. 6 0
      PDF Office/PDF Master/Class/KMAdvertisement/Source/KMAdvertisement.xcassets/Contents.json
  55. 23 0
      PDF Office/PDF Master/Class/KMAdvertisement/Source/KMAdvertisement.xcassets/ad_cancel_button00.imageset/Contents.json
  56. BIN
      PDF Office/PDF Master/Class/KMAdvertisement/Source/KMAdvertisement.xcassets/ad_cancel_button00.imageset/ad_cancel_button00.png
  57. BIN
      PDF Office/PDF Master/Class/KMAdvertisement/Source/KMAdvertisement.xcassets/ad_cancel_button00.imageset/ad_cancel_button00@2x.png
  58. BIN
      PDF Office/PDF Master/Class/KMAdvertisement/Source/KMAdvertisement.xcassets/ad_cancel_button00.imageset/ad_cancel_button00@3x.png
  59. 1 1
      PDF Office/PDF Master/Class/KMAdvertisement/View/Tableview/KMAdvertisementTableView.swift
  60. 2 2
      PDF Office/PDF Master/Class/KMAdvertisement/View/View/KMAdvertisementShowView.swift
  61. 4 4
      PDF Office/PDF Master/Class/KMLightMember/Controller/ComparativeTable/View/ComparativeView/KMComparativeOutlineView.xib
  62. 6 6
      PDF Office/PDF Master/Class/KMLightMember/Controller/ComparativeTable/View/ComparativeView/View/KMComparativeOutlineCell.xib
  63. 7 7
      PDF Office/PDF Master/Class/KMLightMember/Controller/ComparativeTable/View/KMComparativeView/KMComparativeView.xib
  64. 2 2
      PDF Office/PDF Master/Class/KMLightMember/Controller/ComparativeTable/View/KMComparativeView/View/KMComparativeViewCollectionItem.xib
  65. 3 3
      PDF Office/PDF Master/Class/KMLightMember/Controller/ComparativeTable/View/KMComparativeView/View/KMComparativeViewCollectionItemItem.xib
  66. 2 2
      PDF Office/PDF Master/Class/PDFWindowController/Side/LeftSide/Thumbnail/KMThumbnailViewController.xib
  67. 2 2
      PDF Office/PDF Master/Class/PDFWindowController/Toolbar/KMToolbarItemView.swift

File diff suppressed because it is too large
+ 425 - 0
PDF Office/PDF Master.xcodeproj/project.pbxproj


+ 50 - 69
PDF Office/PDF Master.xcodeproj/xcuserdata/lizhe.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist

@@ -8236,7 +8236,7 @@
             endingColumnNumber = "9223372036854775807"
             startingLineNumber = "2035"
             endingLineNumber = "2035"
-            landmarkName = "-annotationChangeNotification:"
+            landmarkName = "-popoverWillClose:"
             landmarkType = "7">
          </BreakpointContent>
       </BreakpointProxy>
@@ -8252,7 +8252,7 @@
             endingColumnNumber = "9223372036854775807"
             startingLineNumber = "2048"
             endingLineNumber = "2048"
-            landmarkName = "-popoverWillShow:"
+            landmarkName = "-km_comboBoxSelectionDidChange:"
             landmarkType = "7">
             <Locations>
                <Location
@@ -8744,7 +8744,7 @@
             endingColumnNumber = "9223372036854775807"
             startingLineNumber = "2109"
             endingLineNumber = "2109"
-            landmarkName = "-km_comboBoxSelectionDidChange:"
+            landmarkName = "-adjustFreetText"
             landmarkType = "7">
             <Locations>
                <Location
@@ -8867,8 +8867,8 @@
             endingColumnNumber = "9223372036854775807"
             startingLineNumber = "2231"
             endingLineNumber = "2231"
-            landmarkName = "-updateTextPresupposition:size:needChangeListView:"
-            landmarkType = "7">
+            landmarkName = "KMGeneralAnnotationViewController(Font)"
+            landmarkType = "3">
             <Locations>
                <Location
                   uuid = "D365958A-3F39-439A-8BDE-F8AAB0F2B2C3 - 8f69d485cd36c7a5"
@@ -8990,7 +8990,7 @@
             endingColumnNumber = "9223372036854775807"
             startingLineNumber = "2224"
             endingLineNumber = "2224"
-            landmarkName = "-updateTextPresupposition:size:needChangeListView:"
+            landmarkName = "-reDefineTextPresuppositionData:"
             landmarkType = "7">
             <Locations>
                <Location
@@ -9113,8 +9113,8 @@
             endingColumnNumber = "9223372036854775807"
             startingLineNumber = "2204"
             endingLineNumber = "2204"
-            landmarkName = "KMGeneralAnnotationViewController(Font)"
-            landmarkType = "3">
+            landmarkName = "-resetTextPresuppositionData"
+            landmarkType = "7">
             <Locations>
                <Location
                   uuid = "6587786D-9FE4-4185-8EBF-43F8E1553692 - a54da4d559a2405"
@@ -9236,7 +9236,7 @@
             endingColumnNumber = "9223372036854775807"
             startingLineNumber = "2195"
             endingLineNumber = "2195"
-            landmarkName = "-updateTextTextPresuppositionState:size:"
+            landmarkName = "-updateTextPresupposition:size:needChangeListView:"
             landmarkType = "7">
             <Locations>
                <Location
@@ -9575,8 +9575,8 @@
             endingColumnNumber = "9223372036854775807"
             startingLineNumber = "1969"
             endingLineNumber = "1969"
-            landmarkName = "KMGeneralAnnotationViewController"
-            landmarkType = "3">
+            landmarkName = "-observeValueForKeyPath:ofObject:change:context:"
+            landmarkType = "7">
             <Locations>
                <Location
                   uuid = "E125D63F-7F74-4267-ACFC-5DCE91770F6E - 4048455193cadab8"
@@ -9667,9 +9667,7 @@
             startingColumnNumber = "9223372036854775807"
             endingColumnNumber = "9223372036854775807"
             startingLineNumber = "2319"
-            endingLineNumber = "2319"
-            landmarkName = "-updateFontSize:needChangeListView:needSave:"
-            landmarkType = "7">
+            endingLineNumber = "2319">
             <Locations>
                <Location
                   uuid = "2DE73B57-6EFC-4BE0-8A79-01EEB1AC4A4B - d8d25c4bf527a931"
@@ -13936,8 +13934,8 @@
             filePath = "PDF Master/Class/Home/ViewController/KMHomeViewController.swift"
             startingColumnNumber = "9223372036854775807"
             endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "628"
-            endingLineNumber = "628"
+            startingLineNumber = "634"
+            endingLineNumber = "634"
             landmarkName = "openPDFAction(_:)"
             landmarkType = "7">
             <Locations>
@@ -13986,6 +13984,21 @@
                   endingLineNumber = "628"
                   offsetFromSymbolStart = "92">
                </Location>
+               <Location
+                  uuid = "9637C1F6-AD48-462A-8BD8-6B448BB2E505 - 904e656a6c1c6e8"
+                  shouldBeEnabled = "Yes"
+                  ignoreCount = "0"
+                  continueAfterRunningActions = "No"
+                  symbolName = "PDF_Master.KMHomeViewController.openPDFAction(PDF_Master.KMBox) -&gt; ()"
+                  moduleName = "PDF Master"
+                  usesParentBreakpointCondition = "Yes"
+                  urlString = "file:///Volumes/Data/Company/kdan/Projects/PDF%20Office/PDF%20Office/PDF%20Master/Class/Home/ViewController/KMHomeViewController.swift"
+                  startingColumnNumber = "9223372036854775807"
+                  endingColumnNumber = "9223372036854775807"
+                  startingLineNumber = "634"
+                  endingLineNumber = "634"
+                  offsetFromSymbolStart = "92">
+               </Location>
             </Locations>
          </BreakpointContent>
       </BreakpointProxy>
@@ -14312,96 +14325,64 @@
       <BreakpointProxy
          BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
          <BreakpointContent
-            uuid = "B0303C64-3696-457E-9368-842A2AFFF854"
+            uuid = "375AF3AF-725A-47A9-99BA-B66039F8E27F"
             shouldBeEnabled = "Yes"
             ignoreCount = "0"
             continueAfterRunningActions = "No"
-            filePath = "PDF Master/Class/KMAdvertisement/View/View/KMAdvertisementShowView.swift"
+            filePath = "PDF Master/Class/Home/View/HomeContentView/History/Cell/KMHomeHistoryCollectionItem.swift"
             startingColumnNumber = "9223372036854775807"
             endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "17"
-            endingLineNumber = "17"
-            landmarkName = "inputData"
-            landmarkType = "24">
-            <Locations>
-               <Location
-                  uuid = "B0303C64-3696-457E-9368-842A2AFFF854 - d71ea3a4d38fe33e"
-                  shouldBeEnabled = "Yes"
-                  ignoreCount = "0"
-                  continueAfterRunningActions = "No"
-                  symbolName = "PDF_Master.KMAdvertisementShowView.inputData.didset : Swift.Optional&lt;PDF_Master.KMAdvertisementContent&gt;"
-                  moduleName = "PDF Master"
-                  usesParentBreakpointCondition = "Yes"
-                  urlString = "file:///Volumes/Data/Company/kdan/Projects/PDF%20Office/PDF%20Office/PDF%20Master/Class/KMAdvertisement/View/View/KMAdvertisementShowView.swift"
-                  startingColumnNumber = "9223372036854775807"
-                  endingColumnNumber = "9223372036854775807"
-                  startingLineNumber = "17"
-                  endingLineNumber = "17"
-                  offsetFromSymbolStart = "24">
-               </Location>
-               <Location
-                  uuid = "B0303C64-3696-457E-9368-842A2AFFF854 - 14bc5f2d09093928"
-                  shouldBeEnabled = "Yes"
-                  ignoreCount = "0"
-                  continueAfterRunningActions = "No"
-                  symbolName = "PDF_Master.KMAdvertisementShowView.inputData.didset : Swift.Optional&lt;PDF_Master.KMAdvertisementItem&gt;"
-                  moduleName = "PDF Master"
-                  usesParentBreakpointCondition = "Yes"
-                  urlString = "file:///Volumes/Data/Company/kdan/Projects/PDF%20Office/PDF%20Office/PDF%20Master/Class/KMAdvertisement/View/View/KMAdvertisementShowView.swift"
-                  startingColumnNumber = "9223372036854775807"
-                  endingColumnNumber = "9223372036854775807"
-                  startingLineNumber = "17"
-                  endingLineNumber = "17"
-                  offsetFromSymbolStart = "24">
-               </Location>
-            </Locations>
+            startingLineNumber = "100"
+            endingLineNumber = "100"
+            landmarkName = "reloadData()"
+            landmarkType = "7">
          </BreakpointContent>
       </BreakpointProxy>
       <BreakpointProxy
          BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
          <BreakpointContent
-            uuid = "C229BA4C-BB97-4FF7-A7F3-1C9134448764"
+            uuid = "BBDB5A98-4262-45F1-BD2E-DA375BB05785"
             shouldBeEnabled = "Yes"
             ignoreCount = "0"
             continueAfterRunningActions = "No"
-            filePath = "PDF Master/Class/KMAdvertisement/Manager/KMAdvertisementManager.swift"
+            filePath = "PDF Master/Class/Home/View/HomeContentView/History/Cell/KMHomeHistoryCollectionItem.swift"
             startingColumnNumber = "9223372036854775807"
             endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "130"
-            endingLineNumber = "130"
-            landmarkName = "parseData(data:isNeedLocalComparison:completion:)"
+            startingLineNumber = "115"
+            endingLineNumber = "115"
+            landmarkName = "updateTypeData()"
             landmarkType = "7">
          </BreakpointContent>
       </BreakpointProxy>
       <BreakpointProxy
          BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
          <BreakpointContent
-            uuid = "33CC0581-290A-41E9-9D5F-6C96830BC4D9"
+            uuid = "23311251-33A9-4056-B359-D813CA74A4E7"
             shouldBeEnabled = "Yes"
             ignoreCount = "0"
             continueAfterRunningActions = "No"
-            filePath = "PDF Master/Class/KMAdvertisement/View/View/KMAdvertisementShowView.swift"
+            filePath = "PDF Master/Class/Home/View/HomeContentView/History/Cell/KMHomeHistoryCollectionItem.swift"
             startingColumnNumber = "9223372036854775807"
             endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "62"
-            endingLineNumber = "62"
-            landmarkName = "reloadData()"
+            startingLineNumber = "128"
+            endingLineNumber = "128"
+            landmarkName = "updateFilesData()"
             landmarkType = "7">
          </BreakpointContent>
       </BreakpointProxy>
       <BreakpointProxy
          BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
          <BreakpointContent
-            uuid = "20B0B1A0-C3E9-4E07-BB48-3F1F4E3E13BA"
+            uuid = "F8D93F2C-326F-4F8B-8530-8BAD4BDB585E"
             shouldBeEnabled = "Yes"
             ignoreCount = "0"
             continueAfterRunningActions = "No"
-            filePath = "PDF Master/Class/KMAdvertisement/View/View/KMAdvertisementShowView.swift"
+            filePath = "PDF Master/Class/Home/View/HomeContentView/History/Cell/KMHomeHistoryCollectionItem.swift"
             startingColumnNumber = "9223372036854775807"
             endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "64"
-            endingLineNumber = "64"
-            landmarkName = "reloadData()"
+            startingLineNumber = "206"
+            endingLineNumber = "206"
+            landmarkName = "updateFilesData()"
             landmarkType = "7">
          </BreakpointContent>
       </BreakpointProxy>

+ 1 - 1
PDF Office/PDF Master/AppDelegate.swift

@@ -51,7 +51,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
         KMAdvertisementManager.manager.debug = true
                 
         // 初版不支持暗黑模式
-        NSApp.appearance = NSAppearance(named: .aqua)
+//        NSApp.appearance = NSAppearance(named: .darkAqua)
         KMAnalytics.configure()
 
         //第一次开启app

+ 2 - 2
PDF Office/PDF Master/Base.lproj/Main.storyboard

@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="22154" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
+<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="22155" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
     <dependencies>
         <deployment identifier="macosx"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22154"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22155"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
     <scenes>

+ 18 - 0
PDF Office/PDF Master/Class/Batch/Catogary/NSArray+Extension.swift

@@ -0,0 +1,18 @@
+//
+//  NSArray+Extension.swift
+//  PDF Master
+//
+//  Created by kdanmobile on 2023/10/27.
+//
+
+import Foundation
+
+
+extension NSArray{
+    func removeObjects(arr:[Any], set: IndexSet) -> [Any] {
+        var newArr: NSMutableArray = arr as! NSMutableArray
+//        let removeA = newArr.objects(at: set)
+        newArr.removeObjects(at: set)
+        return newArr as! [Any]
+    }
+}

+ 66 - 0
PDF Office/PDF Master/Class/Batch/Catogary/NSButton+CustomAppearance.swift

@@ -0,0 +1,66 @@
+//
+//  NSButton+CustomAppearance.swift
+//  PDF Master
+//
+//  Created by kdanmobile on 2023/10/26.
+//
+
+import Foundation
+
+let NSButtonAddHoverKey = "NSButtonAddHoverKey"
+let NSButtonTrackingAreaKey = "NSButtonTrackingAreaKey"
+var placeholderImage: NSImage?
+
+extension NSButton{
+    var addHoverEffect: Bool {
+        get {
+            return (objc_getAssociatedObject(self, NSButtonAddHoverKey) as? NSNumber)?.boolValue ?? false
+        }
+        set {
+            removeTrackingArea(self.neededTrackingArea!)
+            if newValue {
+                addNewTrackingArea()
+            }
+            objc_setAssociatedObject(self, NSButtonAddHoverKey, NSNumber(value: newValue), .OBJC_ASSOCIATION_RETAIN)
+        }
+    }
+    var neededTrackingArea: NSTrackingArea? {
+        get {
+            return objc_getAssociatedObject(self, NSButtonTrackingAreaKey) as? NSTrackingArea
+        }
+        set {
+            objc_setAssociatedObject(self, NSButtonTrackingAreaKey, newValue, .OBJC_ASSOCIATION_RETAIN)
+        }
+    }
+    func addNewTrackingArea() {
+        self.wantsLayer = true
+        let trackingArea = NSTrackingArea(rect: self.bounds, options: [.mouseEnteredAndExited, .inVisibleRect, .activeAlways], owner: self, userInfo: nil)
+        self.addTrackingArea(trackingArea)
+        self.neededTrackingArea = trackingArea
+    }
+    open override func mouseExited(with event: NSEvent) {
+        super.mouseExited(with: event)
+        if self.addHoverEffect {
+            if !self.isEnabled {
+                return
+            }
+            if (self.image != nil) && (self.alternateImage != nil) {
+                self.alternateImage = self.image
+                self.image = placeholderImage
+            }
+        }
+    }
+    
+    open override func mouseEntered(with event: NSEvent) {
+        super.mouseEntered(with: event)
+        if self.addHoverEffect {
+            if !self.isEnabled {
+                return
+            }
+            if (self.image != nil) && (self.alternateImage != nil) {
+                placeholderImage = self.image
+                self.image = self.alternateImage
+            }
+        }
+    }
+}

+ 53 - 0
PDF Office/PDF Master/Class/Batch/Catogary/NSWindow+PopOver.swift

@@ -0,0 +1,53 @@
+//
+//  NSWindow+PopOver.swift
+//  PDF Master
+//
+//  Created by kdanmobile on 2023/10/26.
+//
+
+import Foundation
+
+let KMWindowPopOverKey = "KMWindowPopOverKey"
+let KMWindowPopOverSourcesRectKey = "KMWindowPopOverSourcesRectKey"
+extension NSWindow {
+    var popover: NSPopover? {
+        get {
+            return objc_getAssociatedObject(self,KMWindowPopOverKey) as? NSPopover
+        }
+        set {
+            objc_setAssociatedObject(self, KMWindowPopOverKey, newValue, .OBJC_ASSOCIATION_RETAIN)
+        }
+    }
+    
+    var sourcesRect: CGRect? {
+        get {
+            guard let value = objc_getAssociatedObject(self, KMWindowPopOverSourcesRectKey) as? NSValue else {
+                return nil
+            }
+            return value.rectValue
+        }
+        set {
+            if let newValue = newValue {
+                let value = NSValue(rect: newValue)
+                objc_setAssociatedObject(self, KMWindowPopOverSourcesRectKey, value, .OBJC_ASSOCIATION_RETAIN)
+            } else {
+                objc_setAssociatedObject(self, KMWindowPopOverSourcesRectKey, nil, .OBJC_ASSOCIATION_RETAIN)
+            }
+        }
+    }
+    
+    open override func mouseMoved(with event: NSEvent)  {
+        super.mouseMoved(with: event)
+        let point = event.locationInWindow
+        if NSStringFromClass(event.window!.classForCoder).elementsEqual("_NSPopoverWindow") == false {
+            if !sourcesRect!.contains(point) {
+                if (self.popover != nil) {
+                    NotificationCenter.default.post(name: NSNotification.Name("KMPopOverClosedByWindowNotification"), object: self.popover)
+                    popover!.close()
+                    self.popover = nil
+                    self.sourcesRect = CGRect.null
+                }
+            }
+        }
+    }
+}

+ 281 - 0
PDF Office/PDF Master/Class/Batch/Data/KMBatchBaseParameter.swift

@@ -0,0 +1,281 @@
+//
+//  KMBatchBaseParameter.swift
+//  PDF Master
+//
+//  Created by kdanmobile on 2023/10/25.
+//
+
+import Cocoa
+
+class KMBatchBaseParameter: NSObject{
+    var error: NSError?
+    var operateFile: KMBatchOperateFile?
+    var pageChoice: KMBatchOperatePageChoice? {
+        willSet{
+           
+        }
+        didSet {
+            if pageChoice != oldValue {
+                self.localPagesArray = nil
+            }
+        }
+    }
+    var pageRangeString: String? {
+        willSet{
+           
+        }
+        didSet {
+            if pageRangeString != oldValue {
+                self.localPagesArray = nil
+            }
+        }
+    }
+    var progress: Float?
+    var status: KMBatchOperateStatus?
+    var savePath: String?
+    var outPutPath: String?
+    var pagesArray: [NSNumber]? {
+        if self.localPagesArray == nil {
+            self.localPagesArray = self.fetchUnlimitPagesArray()
+        }
+        return self.localPagesArray
+    }
+    private var localPagesArray: [NSNumber]?
+    
+    init(file:KMBatchOperateFile) {
+        super.init()
+        self.operateFile = file
+    }
+    
+    func fetchUnlimitPagesArray() -> [NSNumber]? {
+        let document = PDFDocument(url: URL(fileURLWithPath: self.operateFile?.filePath ?? ""))
+        let pageNumber = document?.pageCount ?? 0
+        if self.pageChoice == .All {
+            var selectPages: [NSNumber] = []
+            for i in 1...pageNumber {
+                selectPages.append(NSNumber(integerLiteral: i))
+            }
+            return selectPages
+        } else if self.pageChoice == .Odd {
+            var selectPages: [NSNumber] = []
+            for i in stride(from: 1, through: pageNumber, by: 2) {
+                selectPages.append(NSNumber(integerLiteral: i))
+            }
+            return selectPages
+        } else if self.pageChoice == .Even {
+            var selectPages: [NSNumber] = []
+            for i in stride(from: 2, through: pageNumber, by: 2) {
+                selectPages.append(NSNumber(integerLiteral: i))
+            }
+            return selectPages
+        } else {
+            var pageNumbers: [NSNumber] = []
+            var isInvalid = false
+            for c in self.pageRangeString! {
+                if c != "0" && c != "1" && c != "2" && c != "3" && c != "4" && c != "5" && c != "6" && c != "7" && c != "8" && c != "9" && c != "," && c != "-" {
+                    isInvalid = true
+                    break
+                } else {
+                    isInvalid = false
+                }
+            }
+            if !isInvalid {
+                let array = self.pageRangeString!.components(separatedBy: ",")
+                for s in array {
+                    if s.isEmpty {
+                        isInvalid = true
+                        break
+                    } else {
+                        let pages = s.components(separatedBy: "-")
+                        if pages.count > 2 {
+                            isInvalid = true
+                            break
+                        } else if pages.count == 1 {
+                            let p = pages[0]
+                            if p.isEmpty || Int(p)! > pageNumber || Int(p)! == 0 {
+                                isInvalid = true
+                                break
+                            } else {
+                                var isEqual = false
+                                for pageNumber in pageNumbers {
+                                    if pageNumber.intValue == Int(p)! {
+                                        isEqual = true
+                                        isInvalid = true
+                                        break
+                                    }
+                                }
+                                if !isEqual {
+                                    pageNumbers.append(NSNumber(integerLiteral: Int(p)!))
+                                }
+                            }
+                        } else if pages.count == 2 {
+                            let p1 = pages[0]
+                            let p2 = pages[1]
+                            if p1.isEmpty || p2.isEmpty || Int(p1)! >= Int(p2)! || Int(p2)! > pageNumber || Int(p1)! == 0 {
+                                isInvalid = true
+                                break
+                            } else {
+                                var isEqual = false
+                                for i in Int(p1)!...Int(p2)! {
+                                    for pageNumber in pageNumbers {
+                                        if pageNumber.intValue == i {
+                                            isEqual = true
+                                            isInvalid = true
+                                            break
+                                        }
+                                    }
+                                }
+                                if !isEqual {
+                                    for i in Int(p1)!...Int(p2)! {
+                                        pageNumbers.append(NSNumber(integerLiteral: i))
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            if (self.pageRangeString!.isEmpty) {
+                isInvalid = true
+            }
+            if isInvalid {
+                return nil
+            }
+            QuickSort(list: pageNumbers as! NSMutableArray, startIndex: 0, endIndex: pageNumbers.count - 1)
+            return pageNumbers
+        }
+    }
+    
+    func QuickSort(list: NSMutableArray, startIndex: NSInteger, endIndex: NSInteger) {
+        if startIndex >= endIndex {
+            return
+        }
+        let temp = list[startIndex] as! NSNumber
+        var tempIndex = startIndex
+        
+        for i in (startIndex + 1)...endIndex {
+            let t = list[i] as! NSNumber
+            if temp.intValue > t.intValue {
+                tempIndex = tempIndex + 1
+                list.exchangeObject(at: tempIndex, withObjectAt: i)
+            }
+        }
+        
+        list.exchangeObject(at: tempIndex, withObjectAt: startIndex)
+        QuickSort(list: list, startIndex: startIndex, endIndex: tempIndex-1)
+        QuickSort(list: list, startIndex: tempIndex+1, endIndex: endIndex)
+    }
+    
+    func getUniqueFilePath(filePath: String) -> String {
+        var i = 0
+        var isDirectory = ObjCBool(false)
+        var uniqueFilePath = filePath
+        let fileManager = FileManager.default
+        fileManager.fileExists(atPath: uniqueFilePath, isDirectory: &isDirectory)
+        if isDirectory.boolValue {
+            while fileManager.fileExists(atPath: uniqueFilePath) {
+                i += 1
+                uniqueFilePath = "\(filePath)(\(i))"
+            }
+        } else {
+            while fileManager.fileExists(atPath: uniqueFilePath) {
+                i += 1
+                let path = "\(filePath.deletingPathExtension)(\(i))"
+                uniqueFilePath = path.stringByAppendingPathComponent(filePath.extension)
+            }
+        }
+        
+        return uniqueFilePath
+    }
+    
+    func resetState() {
+        status = .Waiting
+        progress = 0
+        error = nil
+        savePath = nil
+        outPutPath = nil
+    }
+    func fetchDestinationFilepath() -> String? {
+        if self.isEqual(self.operateFile?.convertInfo) {
+            // 在子类重写了这个方法,这里永远不会调用,所以不需要写
+        } else if self.isEqual(self.operateFile?.addPasswordInfo) {
+            if ((self.savePath?.isEmpty) == nil) && ((self.operateFile?.filePath.isEmpty) == nil) {
+                var newfileName = self.operateFile!.filePath.lastPathComponent.deletingPathExtension + "_SetPassword"
+                newfileName = newfileName.stringByAppendingPathExtension("pdf")
+                self.outPutPath = self.getUniqueFilePath(filePath: self.savePath!.stringByAppendingPathComponent(newfileName))
+                return self.outPutPath
+            }
+        } else if self.isEqual(self.operateFile?.removePasswordInfo) {
+            if ((self.savePath?.isEmpty) == nil) && ((self.operateFile?.filePath.isEmpty) == nil) {
+                var newfileName = self.operateFile!.filePath.lastPathComponent.deletingPathExtension + "_RemovePassword"
+                newfileName = newfileName.stringByAppendingPathExtension("pdf")
+                self.outPutPath = self.getUniqueFilePath(filePath: self.savePath!.stringByAppendingPathComponent(newfileName))
+                return self.outPutPath
+            }
+        } else if self.isEqual(self.operateFile?.addWatermarkInfo) {
+            if ((self.savePath?.isEmpty) == nil) && ((self.operateFile?.filePath.isEmpty) == nil) {
+                var newfileName = self.operateFile!.filePath.lastPathComponent.deletingPathExtension + "_Watermark"
+                newfileName = newfileName.stringByAppendingPathExtension("pdf")
+                self.outPutPath = self.getUniqueFilePath(filePath: self.savePath!.stringByAppendingPathComponent(newfileName))
+                return self.outPutPath
+            }
+        } else if self.isEqual(self.operateFile?.removeWatermarkInfo) {
+            if ((self.savePath?.isEmpty) == nil) && ((self.operateFile?.filePath.isEmpty) == nil) {
+                var newfileName = self.operateFile!.filePath.lastPathComponent.deletingPathExtension + "_RemoveWatermark"
+                newfileName = newfileName.stringByAppendingPathExtension("pdf")
+                self.outPutPath = self.getUniqueFilePath(filePath: self.savePath!.stringByAppendingPathComponent(newfileName))
+                return self.outPutPath
+            }
+        } else if self.isEqual(self.operateFile?.addBackgroundInfo) {
+            if ((self.savePath?.isEmpty) == nil) && ((self.operateFile?.filePath.isEmpty) == nil) {
+                var newfileName = self.operateFile!.filePath.lastPathComponent.deletingPathExtension + "_AddBackground"
+                newfileName = newfileName.stringByAppendingPathExtension("pdf")
+                self.outPutPath = self.getUniqueFilePath(filePath: self.savePath!.stringByAppendingPathComponent(newfileName))
+                return self.outPutPath
+            }
+        } else if self.isEqual(self.operateFile?.removeBackgroundInfo) {
+            if ((self.savePath?.isEmpty) == nil) && ((self.operateFile?.filePath.isEmpty) == nil) {
+                var newfileName = self.operateFile!.filePath.lastPathComponent.deletingPathExtension + "_RemoveBackground"
+                newfileName = newfileName.stringByAppendingPathExtension("pdf")
+                self.outPutPath = self.getUniqueFilePath(filePath: self.savePath!.stringByAppendingPathComponent(newfileName))
+                return self.outPutPath
+            }
+        } else if self.isEqual(self.operateFile?.addHeaderFooterInfo) {
+            if ((self.savePath?.isEmpty) == nil) && ((self.operateFile?.filePath.isEmpty) == nil) {
+                var newfileName = self.operateFile!.filePath.lastPathComponent.deletingPathExtension + "_AddHeaderFooter"
+                newfileName = newfileName.stringByAppendingPathExtension("pdf")
+                self.outPutPath = self.getUniqueFilePath(filePath: self.savePath!.stringByAppendingPathComponent(newfileName))
+                return self.outPutPath
+            }
+        } else if self.isEqual(self.operateFile?.removeHeaderFooterInfo) {
+            if ((self.savePath?.isEmpty) == nil) && ((self.operateFile?.filePath.isEmpty) == nil) {
+                var newfileName = self.operateFile!.filePath.lastPathComponent.deletingPathExtension + "_RemoveHeaderFooter"
+                newfileName = newfileName.stringByAppendingPathExtension("pdf")
+                self.outPutPath = self.getUniqueFilePath(filePath: self.savePath!.stringByAppendingPathComponent(newfileName))
+                return self.outPutPath
+            }
+        } else if self.isEqual(self.operateFile?.addBatesInfo) {
+            if ((self.savePath?.isEmpty) == nil) && ((self.operateFile?.filePath.isEmpty) == nil) {
+                var newfileName = self.operateFile!.filePath.lastPathComponent.deletingPathExtension + "_AddBates"
+                newfileName = newfileName.stringByAppendingPathExtension("pdf")
+                self.outPutPath = self.getUniqueFilePath(filePath: self.savePath!.stringByAppendingPathComponent(newfileName))
+                return self.outPutPath
+            }
+        } else if self.isEqual(self.operateFile?.removeBatesInfo) {
+            if ((self.savePath?.isEmpty) == nil) && ((self.operateFile?.filePath.isEmpty) == nil) {
+                var newfileName = self.operateFile!.filePath.lastPathComponent.deletingPathExtension + "_RemoveBates"
+                newfileName = newfileName.stringByAppendingPathExtension("pdf")
+                self.outPutPath = self.getUniqueFilePath(filePath: self.savePath!.stringByAppendingPathComponent(newfileName))
+                return self.outPutPath
+            }
+        } else if self.isEqual(self.operateFile?.compressInfo) {
+            if ((self.savePath?.isEmpty) == nil) && ((self.operateFile?.filePath.isEmpty) == nil) {
+                var newfileName = self.operateFile!.filePath.lastPathComponent.deletingPathExtension + "_Compressed"
+                newfileName = newfileName.stringByAppendingPathExtension("pdf")
+                self.outPutPath = self.getUniqueFilePath(filePath: self.savePath!.stringByAppendingPathComponent(newfileName))
+                return self.outPutPath
+            }
+        }
+        return nil
+    }
+}

+ 149 - 0
PDF Office/PDF Master/Class/Batch/Data/KMBatchConvertParameter.swift

@@ -0,0 +1,149 @@
+//
+//  KMBatchConvertParameter.swift
+//  PDF Master
+//
+//  Created by kdanmobile on 2023/10/25.
+//
+
+import Cocoa
+
+class KMBatchConvertParameter: KMBatchBaseParameter {
+    var convertType: KMConvertWithPDFType?
+    var allInOneSheet: Bool? // FP转excel用
+    var isExtreactTabel: Bool? // Com_converter 转excel用
+    var isRetainLayout: Bool? // NO 为流排
+
+    var dpi: Int? // 转图片用
+//    var extensionString: String = "" // FP方式转换需要用到
+    var excelContentOption: CPDFConvertExcelContentOptions?
+    var excelWorksheetOption: CPDFConvertExcelWorksheetOptions?
+    
+    override init(file:KMBatchOperateFile) {
+        super.init(file: file)
+        self.dpi = 150
+    }
+    func extensionString() -> String? {
+        var rtString: String? = nil
+        if self.convertType == .WordStandard || self.convertType == .WordAdvance {
+            rtString = "docx"
+        } else if self.convertType == .Excel {
+            rtString = "xlsx"
+        } else if self.convertType == .PowerPoint {
+            rtString = "pptx"
+        } else if self.convertType == .RTF {
+            rtString = "rtf"
+        } else if self.convertType == .CSV {
+            rtString = "csv"
+        } else if self.convertType == .HTML {
+            rtString = "html"
+        } else if self.convertType == .Text {
+            rtString = "txt"
+        } else if self.convertType == .JPEG {
+            rtString = "jpeg"
+        } else if self.convertType == .JPG {
+            rtString = "jpg"
+        } else if self.convertType == .PNG {
+            rtString = "png"
+        } else if self.convertType == .GIF {
+            rtString = "gif"
+        } else if self.convertType == .TGA {
+            rtString = "tga"
+        } else if self.convertType == .BMP {
+            rtString = "bmp"
+        } else if self.convertType == .TIFF {
+            rtString = "tiff"
+        } else if self.convertType == .JPEG2000 {
+            rtString = "jp2"
+        }
+        return rtString
+    }
+    override func fetchDestinationFilepath() -> String? {
+        if ((self.savePath?.isEmpty) == nil) && ((self.operateFile?.filePath.isEmpty) == nil){
+            if self.convertType == .JPEG || self.convertType == .CSV || self.convertType == .JPG  || self.convertType == .PNG || self.convertType == .GIF || self.convertType == .TIFF || self.convertType == .TGA || self.convertType == .BMP || self.convertType == .JPEG2000{
+                self.outPutPath = self.getUniqueFilePath(filePath: self.savePath!.stringByAppendingPathComponent(self.operateFile!.filePath.lastPathComponent.deletingPathExtension))
+                if self.operateFile?.CSVParameter.isExtreactTabel ?? false {
+                    self.outPutPath = (self.outPutPath! as NSString).appendingPathExtension("zip")
+                    self.outPutPath = self.getUniqueFilePath(filePath: self.outPutPath ?? "")
+                }
+                return self.outPutPath
+            } else if self.convertType == .WordStandard || self.convertType == .WordAdvance || self.convertType == .Excel || self.convertType == .PowerPoint || self.convertType == .RTF || self.convertType == .HTML || self.convertType == .Text {
+                let filePath1 = self.savePath?.stringByAppendingPathComponent(self.operateFile!.filePath.lastPathComponent.deletingPathExtension)
+                self.outPutPath = self.getUniqueFilePath(filePath: filePath1!.stringByAppendingPathExtension(self.extensionString()!))
+                return self.outPutPath
+            }
+        }
+        return nil
+    }
+    func outPutPath() -> String? {
+        let existOutPutPath = super.outPutPath
+        if ((existOutPutPath?.isEmpty) != nil){
+            if ((self.savePath?.isEmpty) == nil) && ((self.operateFile?.filePath.isEmpty) == nil) {
+                if self.convertType == .JPEG || self.convertType == .CSV || self.convertType == .JPG || self.convertType == .PNG || self.convertType == .GIF || self.convertType == .TIFF || self.convertType == .TGA || self.convertType == .BMP || self.convertType == .JPEG2000{
+                    return self.getUniqueFilePath(filePath: self.savePath!.stringByAppendingPathComponent(self.operateFile!.filePath.lastPathComponent.deletingPathExtension))
+                } else if self.convertType == .WordStandard ||
+                            self.convertType == .WordAdvance ||
+                            self.convertType == .Excel ||
+                            self.convertType == .PowerPoint ||
+                            self.convertType == .RTF ||
+                            self.convertType == .HTML ||
+                            self.convertType == .Text {
+                    let filePath1 = self.savePath!.stringByAppendingPathComponent(self.operateFile!.filePath.lastPathComponent.deletingPathExtension)
+                    return self.getUniqueFilePath(filePath: filePath1.stringByAppendingPathExtension(self.extensionString()!))
+                }
+            }
+        }
+        return super.outPutPath
+    }
+
+    override var pagesArray: [NSNumber]? {
+        let fullpagesArray = fetchUnlimitPagesArray()
+        var isLimitConvert = false
+        //    #if VERSION_FREE
+        // 桌机版
+        //        if IAPProductsManager.defaultManager().isAvailableAdvancedPDFToOffice() {
+        //            isLimitConvert = false
+        //        } else {
+        //        if .PNG == self.convertType ||
+        //            .JPEG == self.convertType ||
+        //            .JPG == self.convertType ||
+        //            .HTML == self.convertType ||
+        //            .Text == self.convertType ||
+        //            .WordStandard == self.convertType {
+        //                isLimitConvert = false
+        //            } else {
+        //                isLimitConvert = true
+        //            }
+        //        }
+        //    #else
+        // 付费版
+        //        if IAPProductsManager.defaultManager().isAvailableAdvancedPDFToOffice() {
+        //            isLimitConvert = false
+        //        } else {
+        if .PNG == self.convertType ||
+            .JPEG == self.convertType ||
+            .JPG == self.convertType ||
+            .HTML == self.convertType ||
+            .Text == self.convertType ||
+            .WordStandard == self.convertType {
+            isLimitConvert = false
+        } else {
+            isLimitConvert = true
+        }
+        //        }
+        //    #endif
+        
+        if isLimitConvert {
+            if fullpagesArray!.count  > 10 {
+                var newArr: [NSNumber]?
+                for i in 0...10 {
+                    var item = fullpagesArray?[i]
+                    newArr?.append(item!)
+                }
+                return newArr
+            } else {
+                return fullpagesArray
+            }
+        }
+        return fullpagesArray
+    }
+}

+ 322 - 0
PDF Office/PDF Master/Class/Batch/Data/KMBatchOperateFile.swift

@@ -0,0 +1,322 @@
+//
+//  KMBatchOperateFile.swift
+//  PDF Master
+//
+//  Created by kdanmobile on 2023/10/25.
+//
+
+import Cocoa
+
+class KMBatchOperateFile: NSObject{
+    /**基本信息*/
+    var password: String = ""
+    var filePath: String = ""
+    var outputFilePath: String = ""
+    lazy var sizeString: String = {
+        let attributes = try? FileManager.default.attributesOfItem(atPath: self.filePath)
+        let fileSize = attributes?[FileAttributeKey.size] as? Float ?? 0
+        let _sizeString = self.fileSizeString(fSize: fileSize)
+        return _sizeString
+    }()
+    var fileType: KMBatchOperateFileType?
+    /*当前正在进行的任务状态*/
+    var error: NSError? {
+        return self.currentOperateInfo?.error
+    }
+    var status: KMBatchOperateStatus?{
+        return self.currentOperateInfo?.status
+    }
+    var dpi: Int? {
+        if self.currentOperateType == .Convert{
+            return self.currentConvertParameter?.dpi
+        }
+        return 0
+    }
+    var progress: Float?{
+        return self.currentOperateInfo?.progress
+    }
+    var currentOperateType: KMBatchOperationType?
+    var convertType: KMConvertWithPDFType?
+    /*当前的操作详细信息**/
+    lazy var createPDFInfo: KMBatchBaseParameter = {
+        let info = KMBatchBaseParameter(file: self)
+        return info
+    }()
+    var convertInfo: KMBatchConvertParameter?{
+        return self.currentConvertParameter
+    }
+    lazy var mergeInfo: KMBatchBaseParameter = {
+        let info = KMBatchBaseParameter(file: self)
+        return info
+    }()
+    lazy var compressInfo: KMBatchBaseParameter = {
+        let info = KMBatchBaseParameter(file: self)
+        return info
+    }()
+    lazy var ocrInfo: KMBatchBaseParameter = {
+        let info = KMBatchBaseParameter(file: self)
+        return info
+    }()
+    lazy var addPasswordInfo: KMBatchBaseParameter = {
+        let info = KMBatchBaseParameter(file: self)
+        return info
+    }()
+    lazy var removePasswordInfo: KMBatchBaseParameter = {
+        let info = KMBatchBaseParameter(file: self)
+        return info
+    }()
+    lazy var addWatermarkInfo: KMBatchBaseParameter = {
+        let info = KMBatchBaseParameter(file: self)
+        return info
+    }()
+    lazy var removeWatermarkInfo: KMBatchBaseParameter = {
+        let info = KMBatchBaseParameter(file: self)
+        return info
+    }()
+    lazy var addBackgroundInfo: KMBatchBaseParameter = {
+        let info = KMBatchBaseParameter(file: self)
+        return info
+    }()
+    lazy var removeBackgroundInfo: KMBatchBaseParameter = {
+        let info = KMBatchBaseParameter(file: self)
+        return info
+    }()
+    lazy var addHeaderFooterInfo: KMBatchBaseParameter = {
+        let info = KMBatchBaseParameter(file: self)
+        return info
+    }()
+    lazy var removeHeaderFooterInfo: KMBatchBaseParameter = {
+        let info = KMBatchBaseParameter(file: self)
+        return info
+    }()
+    lazy var addBatesInfo: KMBatchBaseParameter = {
+        let info = KMBatchBaseParameter(file: self)
+        return info
+    }()
+    lazy var removeBatesInfo: KMBatchBaseParameter = {
+        let info = KMBatchBaseParameter(file: self)
+        return info
+    }()
+    var currentOperateInfo: KMBatchBaseParameter?{
+        switch self.currentOperateType {
+        case .CreatePDF:
+            return self.createPDFInfo
+        case .Convert:
+            return self.convertInfo
+        case .Merge:
+            return self.mergeInfo
+        case .Compress:
+            return self.compressInfo
+        case .OCR:
+            return self.ocrInfo
+        case .AddPassword:
+            return self.addPasswordInfo
+        case .RemovePassword:
+            return self.removePasswordInfo
+        case .AddWatermark:
+            return self.addWatermarkInfo
+        case .RemoveWatermark:
+            return self.removeWatermarkInfo
+        case .AddBackground:
+            return self.addBackgroundInfo
+        case .RemoveBackground:
+            return self.removeBackgroundInfo
+        case .AddHeaderFooter:
+            return self.addHeaderFooterInfo
+        case .RemoveHeaderFooter:
+            return self.removeHeaderFooterInfo
+        case .AddBates:
+            return self.addBatesInfo
+        case .RemoveBates:
+            return self.removeBatesInfo
+        case .none:
+            return nil
+        case .some(.NotDetermined):
+            return nil
+        }
+    }
+    /*转换详细信息**/
+    lazy var standardWordParameter: KMBatchConvertParameter = {
+        let paramter = KMBatchConvertParameter(file: self)
+        return paramter
+    }()
+    lazy var advanceWordParameter: KMBatchConvertParameter = {
+        let paramter = KMBatchConvertParameter(file: self)
+        paramter.convertType = .WordAdvance
+        return paramter
+    }()
+    lazy var excelParameter: KMBatchConvertParameter = {
+        let paramter = KMBatchConvertParameter(file: self)
+        paramter.convertType = .Excel
+        return paramter
+    }()
+    lazy var PPTParameter: KMBatchConvertParameter = {
+        let paramter = KMBatchConvertParameter(file: self)
+        paramter.convertType = .PowerPoint
+        return paramter
+    }()
+    lazy var RTFParameter: KMBatchConvertParameter = {
+        let paramter = KMBatchConvertParameter(file: self)
+        paramter.convertType = .RTF
+        return paramter
+    }()
+    lazy var CSVParameter: KMBatchConvertParameter = {
+        let paramter = KMBatchConvertParameter(file: self)
+        paramter.convertType = .CSV
+        return paramter
+    }()
+    lazy var HTMLParameter: KMBatchConvertParameter = {
+        let paramter = KMBatchConvertParameter(file: self)
+        paramter.convertType = .HTML
+        return paramter
+    }()
+    lazy var TXTParameter: KMBatchConvertParameter = {
+        let paramter = KMBatchConvertParameter(file: self)
+        paramter.convertType = .Text
+        return paramter
+    }()
+    lazy var JPEGParameter: KMBatchConvertParameter = {
+        let paramter = KMBatchConvertParameter(file: self)
+        paramter.convertType = .JPEG
+        return paramter
+    }()
+    lazy var JPGParameter: KMBatchConvertParameter = {
+        let paramter = KMBatchConvertParameter(file: self)
+        paramter.convertType = .JPG
+        return paramter
+    }()
+    lazy var PNGParameter: KMBatchConvertParameter = {
+        let paramter = KMBatchConvertParameter(file: self)
+        paramter.convertType = .PNG
+        return paramter
+    }()
+    lazy var GIFParameter: KMBatchConvertParameter = {
+        let paramter = KMBatchConvertParameter(file: self)
+        paramter.convertType = .GIF
+        return paramter
+    }()
+    lazy var TIFFParameter: KMBatchConvertParameter = {
+        let paramter = KMBatchConvertParameter(file: self)
+        paramter.convertType = .TIFF
+        return paramter
+    }()
+    lazy var TGAParameter: KMBatchConvertParameter = {
+        let paramter = KMBatchConvertParameter(file: self)
+        paramter.convertType = .TGA
+        return paramter
+    }()
+    lazy var BMPParameter: KMBatchConvertParameter = {
+        let paramter = KMBatchConvertParameter(file: self)
+        paramter.convertType = .BMP
+        return paramter
+    }()
+    lazy var JPEG2000Parameter: KMBatchConvertParameter = {
+        let paramter = KMBatchConvertParameter(file: self)
+        paramter.convertType = .JPEG2000
+        return paramter
+    }()
+    
+    private init(filePath: String) {
+        super.init()
+        self.filePath = filePath
+        let UTTypeString = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, filePath.extension as NSString, nil)
+        let TypeCFString = UTTypeString as! CFString?
+        if UTTypeConformsTo(TypeCFString!, kUTTypePDF) {
+            self.fileType = .PDF
+        } else if UTTypeConformsTo(TypeCFString!, kUTTypeImage) {
+            self.fileType = .Image
+        } else {
+            self.fileType = .Unknow
+        }
+    }
+    init(filePath: String, type: KMBatchOperationType) {
+        super.init()
+        self.filePath = filePath
+        self.currentOperateType = type
+        let UTTypeString = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (filePath.extension as NSString?)!, nil)
+        let TypeCFString = UTTypeString as! CFString?
+        if UTTypeConformsTo(TypeCFString!, kUTTypePDF) {
+            self.fileType = .PDF
+        } else if UTTypeConformsTo(TypeCFString!, kUTTypeImage) {
+            self.fileType = .Image
+        } else {
+            self.fileType = .Unknow
+        }
+    }
+    override func isEqual(_ other: Any?) -> Bool {
+        if let other = other as? Self {
+            if self.filePath == other.filePath {
+                return true
+            }
+            return false
+        }
+        return false
+    }
+    
+    func pagesArrayIntersect(with anArray: [Any]) -> [Any] {
+        let document = PDFDocument(url: URL(fileURLWithPath: self.filePath))
+        document?.unlock(withPassword: self.password)
+        var pageNumbersArr = [Any]()
+        let count: Int = document?.pageCount ?? 0
+        if count > 0 {
+            for j in 0..<count {
+                pageNumbersArr.append(j+1)
+            }
+        }
+        
+        let set1 = NSMutableSet(array: anArray)
+        let set2 = NSMutableSet(array: pageNumbersArr)
+        set1.intersect(set2 as! Set<AnyHashable>)
+        let setArray = set1.allObjects as [Any]
+        let sortedArray = setArray.sorted { (obj1, obj2) -> Bool in
+            let number1 = obj1 as? NSNumber ?? NSNumber()
+            let number2 = obj2 as? NSNumber ?? NSNumber()
+            return number1.compare(number2) == .orderedAscending
+        }
+        
+        return sortedArray
+    }
+    
+    var currentConvertParameter: KMBatchConvertParameter? {
+        if self.convertType == .WordStandard {
+            return self.standardWordParameter
+        } else if self.convertType == .WordAdvance {
+            return self.advanceWordParameter
+        } else if self.convertType == .Excel {
+            return self.excelParameter
+        } else if self.convertType == .PowerPoint {
+            return self.PPTParameter
+        } else if self.convertType == .RTF {
+            return self.RTFParameter
+        } else if self.convertType == .CSV {
+            return self.CSVParameter
+        } else if self.convertType == .HTML {
+            return self.HTMLParameter
+        } else if self.convertType == .Text {
+            return self.TXTParameter
+        } else if self.convertType == .JPEG {
+            return self.JPEGParameter
+        } else if self.convertType == .JPG {
+            return self.JPGParameter
+        } else if self.convertType == .PNG {
+            return self.PNGParameter
+        } else if self.convertType == .GIF {
+            return self.GIFParameter
+        } else if self.convertType == .TIFF {
+            return self.TIFFParameter
+        } else if self.convertType == .TGA {
+            return self.TGAParameter
+        } else if self.convertType == .BMP {
+            return self.BMPParameter
+        } else if self.convertType == .JPEG2000 {
+            return self.JPEG2000Parameter
+        }
+        return nil
+    }
+    func fileSizeString(fSize: Float) -> String {
+        let fileSize = fSize / 1024 
+        let size = fileSize >= 1024 ? (fileSize < 1048576 ? fileSize/1024.0 : fileSize/1048576.0) : fileSize
+        let unit: Character = fileSize >= 1024 ? (fileSize < 1048576 ? "M" : "G") : "K"
+        return String(format: "%0.1f %c", size, unit as! CVarArg)
+    }
+}

+ 100 - 0
PDF Office/PDF Master/Class/Batch/Tools/KMBatchHeader.swift

@@ -0,0 +1,100 @@
+//
+//  KMBatchHeader.swift
+//  PDF Master
+//
+//  Created by kdanmobile on 2023/10/25.
+//
+
+import Foundation
+
+@objc enum KMConvertWithPDFType: Int {
+    case WordAdvance = 0
+    case WordStandard
+    case Excel
+    case PowerPoint
+    case RTF
+    case CSV
+    case HTML
+    case Text
+    case JPEG
+    case JPG
+    case PNG
+    case GIF
+    case TIFF
+    case TGA
+    case BMP
+    case JPEG2000
+}
+
+@objc enum KMBatchOperationType: Int {
+    case NotDetermined = 0
+    case CreatePDF
+    case Convert
+    case Merge
+    case Compress
+    case OCR
+    case AddPassword
+    case RemovePassword
+    case AddWatermark
+    case RemoveWatermark
+    case AddBackground
+    case RemoveBackground
+    case AddHeaderFooter
+    case RemoveHeaderFooter
+    case AddBates
+    case RemoveBates
+}
+
+@objc enum KMBatchOperateStatus: Int {
+    case Waiting = 0
+    case processing
+    case Success
+    case Failed
+}
+
+@objc enum KMBatchOperatePageChoice: Int {
+    case All = 0
+    case Odd
+    case Even
+    case Input
+}
+
+@objc enum KMBatchOperateFileType: Int {
+    case Unknow = 0
+    case Image
+    case PDF
+}
+
+@objc enum KMWatermarkOperateType: Int {
+    case Edit = 0
+    case Delete
+}
+
+@objc enum KMBackgroundOperateType: Int {
+    case Edit = 0
+    case Delete
+}
+
+@objc enum KMBatchOperateInterfaceStatus: Int {
+    case PrepareProcess = 0
+    case Processing
+}
+
+//@objc enum KMBackgroundType: Int {
+//    case Color = 0
+//    case File
+//}
+
+@objc enum KMBatchHeaderFooterType: Int {
+    case HeaderFooter = 0
+    case Bates
+}
+
+@objc enum KMBatchModifyTemplateType: Int {
+    case Add = 0
+    case Edit
+    case Delete
+    case Use
+}
+
+let kNeedChangePageRangeNotification = "kNeedChangePageRangeNotification"

+ 14 - 0
PDF Office/PDF Master/Class/Batch/Tools/KMImageToPDFMethod.swift

@@ -0,0 +1,14 @@
+//
+//  KMImageToPDFMethod.swift
+//  PDF Master
+//
+//  Created by kdanmobile on 2023/10/26.
+//
+
+import Foundation
+
+class KMImageToPDFMethod: NSObject {
+    static func supportedImageTypes() -> [String] {
+        return ["jpg", "cur", "bmp", "jpeg", "gif", "png", "tiff", "tif", "ico", "icns", "tga", "psd", "eps", "hdr", "jp2", "jpc", "pict", "sgi"]
+    }
+}

+ 406 - 0
PDF Office/PDF Master/Class/Batch/View/KMBatchTableCellView.swift

@@ -0,0 +1,406 @@
+//
+//  KMBatchTableCellView.swift
+//  PDF Master
+//
+//  Created by kdanmobile on 2023/10/27.
+//
+
+import Cocoa
+
+typealias batchTableCellComboboxMouseDownCallback = (_ mouseDown: Bool) -> ()
+typealias batchTableCellRemoveFileCallBack = (_ file: KMBatchOperateFile) -> ()
+
+@objc enum KMBatchTableCellViewType: Int {
+    case Size = 0
+    case PageRange
+    case FileName
+    case Status
+    case DPI
+    case Dimensions
+}
+
+class KMBatchTableCellCombobox: KMComboBox{
+    var mouseDownCallback: batchTableCellComboboxMouseDownCallback?
+    override func mouseDown(with event: NSEvent) {
+        super.mouseDown(with: event)
+        if (self.mouseDownCallback != nil) {
+            self.mouseDownCallback!(true)
+        }
+    }
+}
+
+class KMBatchTableCellView: NSTableCellView,NSComboBoxDelegate{
+    var removeFileCallBack: batchTableCellRemoveFileCallBack?
+    var pageRangeCombobox: KMBatchTableCellCombobox?
+    var errorTextField: NSTextField?
+    var statusView: NSView?
+    var removeButton: KMButton?
+    var progressIndicator: NSProgressIndicator?
+    var type: KMBatchTableCellViewType?
+    var file: KMBatchOperateFile?
+    var DPIComboBox: NSComboBox?
+    var indicateImageView: NSImageView?
+    var comboBoxContent: String?
+
+    convenience init(type: KMBatchTableCellViewType) {
+        self.init()
+        switch type {
+        case .Size:
+            configuUIForSize()
+        case .Dimensions:
+            configuUIForSize()
+        case .PageRange:
+            configuUIForPageRange()
+        case .FileName:
+            configuUIForFileName()
+        case .Status:
+            configuUIForStatus()
+        case .DPI:
+            configuUIForDPI()
+        default:
+            break
+        }
+        DistributedNotificationCenter.default().addObserver(self, selector: #selector(themeChanged(notification:)), name: NSNotification.Name("AppleInterfaceThemeChangedNotification"), object: nil)
+        self.type = type
+    }
+    func configuUIForSize() {
+        self.textField = NSTextField(frame: .zero)
+        self.textField!.isBordered = false
+        self.textField!.drawsBackground = true
+        self.textField!.backgroundColor = NSColor.clear
+        self.textField!.isEditable = false
+        self.addSubview(self.textField!)
+        self.textField!.translatesAutoresizingMaskIntoConstraints = false
+        NSLayoutConstraint.activate([
+            self.textField!.topAnchor.constraint(equalTo: self.topAnchor, constant: 13),
+            self.textField!.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 0)
+            ])
+        self.textField!.textColor = KMAppearance.Layout.h0Color()
+        self.textField!.font = NSFont.systemFont(ofSize: 12)
+    }
+    func configuUIForPageRange() { 
+        self.pageRangeCombobox = KMBatchTableCellCombobox(frame: .zero)
+        self.pageRangeCombobox!.focusRingType = .none
+        self.pageRangeCombobox!.type = .none
+        self.pageRangeCombobox!.wantsLayer = true
+        self.pageRangeCombobox!.layer?.backgroundColor = KMAppearance.Layout.l1Color().cgColor
+        self.pageRangeCombobox!.layer?.borderWidth = 1.0
+        self.pageRangeCombobox!.layer?.borderColor = KMAppearance.Interactive.s0Color().cgColor
+        self.pageRangeCombobox!.layer?.cornerRadius = 1.0
+        self.pageRangeCombobox!.backgroundColor = KMAppearance.Layout.l1Color()
+        self.addSubview(self.pageRangeCombobox!)
+        self.pageRangeCombobox!.translatesAutoresizingMaskIntoConstraints = false
+        NSLayoutConstraint.activate([
+            self.pageRangeCombobox!.leadingAnchor.constraint(equalTo: self.leadingAnchor),
+            self.pageRangeCombobox!.widthAnchor.constraint(equalToConstant: 144),
+            self.pageRangeCombobox!.topAnchor.constraint(equalTo: self.topAnchor, constant: 10)
+        ])
+        let choiceArray = [
+            "  \(NSLocalizedString("All Pages", comment: ""))",
+            "  \(NSLocalizedString("Odd Pages Only", comment: ""))",
+            "  \(NSLocalizedString("Even Pages Only", comment: ""))",
+            "  \(NSLocalizedString("e.g. 1,3-5,10", comment: ""))"
+        ]
+        self.pageRangeCombobox!.addItems(withObjectValues: choiceArray)
+        let placeholderString = "  \(NSLocalizedString("e.g. 1,3-5,10", comment: ""))"
+//        self.pageRangeCombobox!.cell.placeholderString = placeholderString
+        self.pageRangeCombobox!.selectItem(at: 0)
+        self.pageRangeCombobox!.isEditable = false
+        self.pageRangeCombobox!.delegate = self
+        self.comboBoxContent = placeholderString
+
+        self.updateViewColor()
+        weak var weakSelf = self
+        self.pageRangeCombobox!.mouseDownCallback = { mouseDown in
+            let itemIdex = weakSelf!.pageRangeCombobox!.indexOfSelectedItem
+            if itemIdex == 3 {//KMBatchOperatePageChoice.Input
+                if weakSelf?.comboBoxContent == placeholderString {
+                    weakSelf?.pageRangeCombobox!.stringValue = ""
+                } else {
+                    weakSelf?.pageRangeCombobox!.stringValue = (weakSelf?.comboBoxContent)!
+                }
+            }
+        }
+        }
+    func configuUIForFileName() {
+        self.textField = NSTextField(frame: .zero) 
+        self.textField!.isBordered = false
+        self.textField!.drawsBackground = true
+        self.textField!.backgroundColor = NSColor.clear
+        self.textField!.isEditable = false
+        self.textField!.maximumNumberOfLines = 1
+        self.textField!.lineBreakMode = .byTruncatingMiddle
+        self.addSubview(self.textField!)
+        self.textField!.translatesAutoresizingMaskIntoConstraints = false
+        NSLayoutConstraint.activate([
+            self.textField!.topAnchor.constraint(equalTo: self.topAnchor, constant: 13),
+            self.textField!.leadingAnchor.constraint(equalTo: self.leadingAnchor),
+            self.textField!.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -10)
+        ])
+        self.textField!.font = NSFont.systemFont(ofSize: 12)
+        self.textField!.textColor = KMAppearance.Layout.h0Color()
+        self.errorTextField = NSTextField(frame: .zero)
+        self.errorTextField!.isBordered = false
+        self.errorTextField!.drawsBackground = true
+        self.errorTextField!.backgroundColor = NSColor.clear
+        self.errorTextField!.isEditable = false
+        self.errorTextField!.font = NSFont.systemFont(ofSize: 12)
+        self.errorTextField!.textColor = KMAppearance.Status.errColor()
+        self.addSubview(self.errorTextField!)
+        self.errorTextField!.translatesAutoresizingMaskIntoConstraints = false
+        NSLayoutConstraint.activate([
+            self.errorTextField!.topAnchor.constraint(equalTo: self.textField!.bottomAnchor),
+            self.errorTextField!.leadingAnchor.constraint(equalTo: self.leadingAnchor),
+            self.errorTextField!.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -11),
+            self.errorTextField!.trailingAnchor.constraint(equalTo: self.trailingAnchor)
+        ])
+    }
+    func configuUIForStatus() {
+        self.statusView = NSView(frame: .zero)
+        self.statusView!.wantsLayer = true
+        self.addSubview(self.statusView!)
+        self.statusView!.translatesAutoresizingMaskIntoConstraints = false
+        NSLayoutConstraint.activate([
+            self.statusView!.leadingAnchor.constraint(equalTo: self.leadingAnchor),
+            self.statusView!.topAnchor.constraint(equalTo: self.topAnchor, constant: 12),
+            self.statusView!.widthAnchor.constraint(equalToConstant: 16),
+            self.statusView!.heightAnchor.constraint(equalToConstant: 16)
+        ])
+        self.indicateImageView = NSImageView(frame: .zero)
+        self.statusView!.addSubview(self.indicateImageView!)
+        self.indicateImageView!.translatesAutoresizingMaskIntoConstraints = false
+        NSLayoutConstraint.activate([
+            self.indicateImageView!.leadingAnchor.constraint(equalTo: self.statusView!.leadingAnchor),
+            self.indicateImageView!.trailingAnchor.constraint(equalTo: self.statusView!.trailingAnchor), 
+            self.indicateImageView!.topAnchor.constraint(equalTo: self.statusView!.topAnchor),
+            self.indicateImageView!.bottomAnchor.constraint(equalTo: self.statusView!.bottomAnchor)
+        ])
+        self.progressIndicator = NSProgressIndicator(frame: .zero)
+        self.statusView!.addSubview(self.progressIndicator!)
+        self.progressIndicator!.translatesAutoresizingMaskIntoConstraints = false
+        NSLayoutConstraint.activate([
+            self.progressIndicator!.leadingAnchor.constraint(equalTo: self.statusView!.leadingAnchor),
+            self.progressIndicator!.trailingAnchor.constraint(equalTo: self.statusView!.trailingAnchor),
+            self.progressIndicator!.topAnchor.constraint(equalTo: self.statusView!.topAnchor),
+            self.progressIndicator!.bottomAnchor.constraint(equalTo: self.statusView!.bottomAnchor) 
+        ])
+        self.progressIndicator!.maxValue = 1.0 
+        self.progressIndicator!.minValue = 0 
+        self.progressIndicator!.style = .spinning
+        self.progressIndicator!.controlSize = .small
+        self.removeButton = KMButton(image: NSImage(named: KMImageNameUXIconBtnCloseNor)!, target: self, action: #selector(deleteFile(sender:)))
+        self.removeButton!.isBordered = false
+        self.removeButton!.isHidden = true
+        self.addSubview(self.removeButton!)
+        self.removeButton!.translatesAutoresizingMaskIntoConstraints = false
+        NSLayoutConstraint.activate([
+            self.removeButton!.topAnchor.constraint(equalTo: self.topAnchor, constant: 10),
+            self.removeButton!.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -5),
+            self.removeButton!.widthAnchor.constraint(equalToConstant: 20),
+            self.removeButton!.heightAnchor.constraint(equalToConstant: 20)
+        ])
+        weak var weakSelf = self 
+        self.removeButton!.mouseMoveCallback = { mouseEntered in 
+            if mouseEntered {
+                weakSelf?.removeButton!.image = NSImage(named: KMImageNameUXIconBtnCloseHov)
+            } else {
+                weakSelf?.removeButton!.image = NSImage(named: KMImageNameUXIconBtnCloseNor)
+            }
+        }
+    }
+    func configuUIForDPI() {
+        self.DPIComboBox = NSComboBox(frame: .zero)
+        self.addSubview(self.DPIComboBox!)
+        self.DPIComboBox!.translatesAutoresizingMaskIntoConstraints = false
+        let DPIArray = ["50 dpi", "72 dpi", "96 dpi", "150 dpi", "300 dpi", "600 dpi"]
+        self.DPIComboBox!.addItems(withObjectValues: DPIArray)
+        self.DPIComboBox!.selectItem(at: 0)
+        self.DPIComboBox!.isEditable = false
+        self.DPIComboBox!.delegate = self
+        NSLayoutConstraint.activate([
+            self.DPIComboBox!.leadingAnchor.constraint(equalTo: self.leadingAnchor),
+            self.DPIComboBox!.topAnchor.constraint(equalTo: self.topAnchor, constant: 10),
+            self.DPIComboBox!.centerXAnchor.constraint(equalTo: self.centerXAnchor) 
+        ])
+    }
+    @objc func themeChanged(notification: NSNotification) {
+        DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
+            self.updateViewColor()
+        }
+    }
+    @objc func deleteFile(sender: Any) {
+        if (self.removeFileCallBack != nil) {
+            self.removeFileCallBack!(self.file!)
+        }
+    }
+    func updateViewColor() {
+        if KMAppearance.isDarkMode() {
+            self.pageRangeCombobox!.backgroundColor = NSColor(red: 0.224, green: 0.235, blue: 0.243, alpha: 1)
+            self.pageRangeCombobox!.layer!.backgroundColor = NSColor(red: 0.224, green: 0.235, blue: 0.243, alpha: 1).cgColor
+            self.pageRangeCombobox!.layer!.borderColor = NSColor(red: 0.337, green: 0.345, blue: 0.353, alpha: 1).cgColor
+        } else {
+            self.pageRangeCombobox!.backgroundColor = NSColor.white
+            self.pageRangeCombobox!.layer!.backgroundColor = NSColor.white.cgColor
+            self.pageRangeCombobox!.layer!.borderColor = NSColor(red: 0.855, green: 0.859, blue: 0.871, alpha: 1).cgColor
+        }
+    }
+    func updateInterface(_ file: KMBatchOperateFile) {
+        self.file = file
+        if self.type == .Size {
+            self.textField!.stringValue = file.sizeString
+        } else if self.type == .FileName {
+            if (file.error != nil) {
+                self.errorTextField!.stringValue = file.error!.localizedDescription
+                self.errorTextField!.isHidden = false
+            } else {
+                self.errorTextField!.isHidden = true
+            }
+            self.textField!.stringValue = file.filePath.lastPathComponent
+        } else if self.type == .PageRange {
+            self.pageRangeCombobox!.isEnabled = self.file!.status != .processing
+            self.pageRangeCombobox!.delegate = nil
+            self.pageRangeCombobox!.selectItem(at: file.currentOperateInfo!.pageChoice?.rawValue ?? 0)
+            self.pageRangeCombobox!.isEditable = false
+            if file.currentOperateInfo!.pageChoice == .Input {
+                self.pageRangeCombobox!.isEditable = true
+                self.pageRangeCombobox!.stringValue = file.currentOperateInfo!.pageRangeString ?? ""
+            }
+            self.pageRangeCombobox!.delegate = self
+        } else if self.type == .Status {
+            if file.status == .Waiting {
+                self.indicateImageView!.isHidden = false
+                self.progressIndicator!.isHidden = true
+                
+                self.indicateImageView!.image = NSImage(named: KMImageNameUXIconProgressWaiting)
+            } else if file.status == .Success {
+                self.indicateImageView!.isHidden = false
+                self.progressIndicator!.isHidden = true
+                self.indicateImageView!.image = NSImage(named: "KMImageNameUXIconProgressComplete")
+            } else if file.status == .Failed {
+                self.indicateImageView!.isHidden = false
+                self.progressIndicator!.isHidden = true
+                self.indicateImageView!.image = NSImage(named: "KMImageNameUXIconProgressFailure")
+            } else if file.status == .processing {
+                self.indicateImageView!.isHidden = true
+                self.progressIndicator!.isHidden = false
+                self.progressIndicator!.startAnimation(nil)
+            }
+        } else if self.type == .DPI {
+            switch self.file?.dpi {
+            case 50:
+                self.DPIComboBox!.selectItem(at: 0)
+            case 72:
+                self.DPIComboBox!.selectItem(at: 1)
+            case 96:
+                self.DPIComboBox!.selectItem(at: 2)
+            case 150:
+                self.DPIComboBox!.selectItem(at: 3)
+            case 300:
+                self.DPIComboBox!.selectItem(at: 4)
+            case 600:
+                self.DPIComboBox!.selectItem(at: 5)
+            default:
+                break
+            }
+            self.DPIComboBox!.isEnabled = self.file?.status != .processing
+        } else if self.type == .Dimensions {
+            
+        }
+    }
+    func updateInterface( file: KMBatchOperateFile, progress: Float) {
+        updateInterface(file)
+        if progress > 0 && file.status == .processing {
+            self.progressIndicator!.doubleValue = Double(progress)
+            self.progressIndicator!.startAnimation(nil)
+            self.progressIndicator!.isIndeterminate = false
+        }
+    }
+    func updateInterface(isProgress progress: Int) {
+        if progress == -1 {
+            self.indicateImageView!.isHidden = false
+            self.progressIndicator!.isHidden = true
+            self.indicateImageView!.image = NSImage(named: "KMImageNameUXIconProgressFailure")
+        } else if progress == 0 {
+            self.indicateImageView!.isHidden = false
+            self.progressIndicator!.isHidden = true
+            self.indicateImageView!.image = NSImage(named: KMImageNameUXIconProgressWaiting)
+        } else {
+            self.indicateImageView!.isHidden = false
+            self.progressIndicator!.isHidden = true
+            self.indicateImageView!.image = NSImage(named: "KMImageNameUXIconProgressComplete")
+        }
+    }
+    func controlTextDidEndEditing(_ obj: Notification) {
+        if let object = self.pageRangeCombobox?.isEqual(obj.object) {
+            self.file!.currentOperateInfo!.pageRangeString = self.pageRangeCombobox!.stringValue
+            if self.file!.currentOperateInfo?.pagesArray == nil {
+                let alert = NSAlert()
+                alert.addButton(withTitle: NSLocalizedString("OK", comment: ""))
+                alert.alertStyle = .critical
+                alert.messageText = self.file!.filePath.lastPathComponent.lastPathComponent + NSLocalizedString("Invalid page range or the page number is out of range. Please try again.", comment: "")
+                alert.beginSheetModal(for: self.window!, completionHandler: nil)
+                self.pageRangeCombobox?.selectItem(at: 0)
+                self.file?.currentOperateInfo!.pageChoice = .All
+            }
+        }
+    }
+    func controlTextDidChange(_ obj: Notification) {
+        let comboBox: NSComboBox = obj.object as! NSComboBox;
+        if comboBox.isEqual(self.pageRangeCombobox) {
+            self.comboBoxContent = comboBox.stringValue;
+        }
+    }
+    
+    func comboBoxSelectionDidChange(_ notification: Notification) {
+        if notification.object as? NSComboBox == self.pageRangeCombobox {
+            self.pageRangeCombobox!.delegate = nil
+            self.file?.currentOperateInfo!.pageChoice = self.tromsformPageChoice(index: self.pageRangeCombobox?.indexOfSelectedItem ?? 0)
+            if self.pageRangeCombobox?.indexOfSelectedItem == 0 {
+                self.pageRangeCombobox?.isEditable = true
+                self.pageRangeCombobox?.isSelectable = true
+                self.window?.makeFirstResponder(self.pageRangeCombobox)
+            } else {
+                self.pageRangeCombobox?.resignFirstResponder()
+                self.pageRangeCombobox?.isEditable = false
+                self.pageRangeCombobox?.isSelectable = false
+            }
+            self.pageRangeCombobox?.delegate = self
+        } else if notification.object as? NSComboBox == self.DPIComboBox {
+            switch self.DPIComboBox?.indexOfSelectedItem
+            {
+            case 0:
+                self.file?.currentConvertParameter?.dpi = 50
+            case 1:
+                self.file?.currentConvertParameter?.dpi = 72
+            case 2:
+                self.file?.currentConvertParameter?.dpi = 96
+            case 3:
+                self.file?.currentConvertParameter?.dpi = 150
+            case 4:
+                self.file?.currentConvertParameter?.dpi = 300
+            case 5:
+                self.file?.currentConvertParameter?.dpi = 600
+            default:
+                break
+            }
+        }
+    }
+    func tromsformPageChoice(index: Int) -> KMBatchOperatePageChoice {
+        var pageChoice: KMBatchOperatePageChoice?
+        switch index {
+        case 0:
+            pageChoice = .All
+        case 1:
+            pageChoice = .Odd
+        case 2:
+            pageChoice = .Even
+        case 3:
+            pageChoice = .Input
+        default:
+            pageChoice = .All
+        }
+        return pageChoice ?? .All
+    }
+            
+}
+

+ 19 - 0
PDF Office/PDF Master/Class/Batch/View/KMBatchWindow.swift

@@ -0,0 +1,19 @@
+//
+//  KMBatchWindow.swift
+//  PDF Master
+//
+//  Created by kdanmobile on 2023/10/24.
+//
+
+import Cocoa
+import PDFKit
+
+@objcMembers class KMBatchWindow: NSWindow{
+
+    var isBatch: Bool?
+    override func awakeFromNib() {
+        super.awakeFromNib()
+        self.animationBehavior = .alertPanel
+    }
+}
+

+ 96 - 0
PDF Office/PDF Master/Class/Batch/View/KMLongerButton.swift

@@ -0,0 +1,96 @@
+//
+//  KMLongerButton.swift
+//  PDF Master
+//
+//  Created by kdanmobile on 2023/10/26.
+//
+
+import Cocoa
+
+class KMLongerButton: NSButton{
+    var containerViewController: KMBatchOperateLeftViewController?
+    var isImageToPDF = false
+    var popOver: NSPopover?
+    var buttonLayer: CALayer?
+    
+    override func draw(_ dirtyRect: NSRect) {
+        super.draw(dirtyRect)
+    }
+    
+    override var intrinsicContentSize: NSSize {
+        var size = super.intrinsicContentSize 
+        size.width += 20
+        return size
+    }
+    
+    override func awakeFromNib() {
+        super.awakeFromNib()
+        self.newTrackingArea()
+        self.wantsLayer = true
+        self.buttonLayer = CALayer()
+        self.layer?.addSublayer(self.buttonLayer!)
+        self.buttonLayer?.frame = CGRect(x: 0, y: 0, width: CGRectGetWidth(self.bounds), height: CGRectGetHeight(self.bounds))
+        self.buttonLayer?.backgroundColor = KMAppearance.KM_000000_Color5DarkChange01().cgColor
+        self.buttonLayer?.cornerRadius = 1
+        self.buttonLayer?.isHidden = true
+    }
+    
+   func newTrackingArea() {
+        let trackingArea = NSTrackingArea(rect: self.bounds, options: [.mouseEnteredAndExited, .inVisibleRect, .activeAlways], owner: self, userInfo: nil)
+        self.addTrackingArea(trackingArea)
+    }
+    func showPop(sender: NSView) {
+        let menuViewController = KMCustomButtonPopMenuViewController()
+        self.popOver = NSPopover()
+        self.popOver?.contentViewController = menuViewController
+        self.popOver?.animates = false
+        self.popOver?.behavior = .semitransient
+        self.popOver?.contentSize = menuViewController.view.frame.size
+        var sourcesRect = sender.bounds
+        sourcesRect = sender.convert(sourcesRect, to: nil)
+        sourcesRect.origin.y -= 20
+        sourcesRect.size.height += 20
+        self.window!.popover = self.popOver
+        self.window!.sourcesRect = sourcesRect
+        
+        self.popOver?.show(relativeTo: self.bounds.insetBy(dx: 0, dy: 5), of: self, preferredEdge: .maxY)
+    }
+    func closePop() {
+        popOver?.close() 
+        popOver = nil
+        window?.popover = nil
+    }
+    override func mouseEntered(with event: NSEvent) {
+        super.mouseEntered(with: event)
+        self.showPop(sender: self)
+        self.buttonLayer?.isHidden = false
+    }
+    override func mouseExited(with event: NSEvent) {
+        super.mouseExited(with: event)
+        self.buttonLayer?.isHidden = true
+    }
+    override func mouseDown(with event: NSEvent) {
+        super.mouseDown(with: event)
+    }
+    override func mouseUp(with event: NSEvent) {
+        super.mouseUp(with: event)
+    }
+    func customViewButtonPopDidSelectIndex(_ index: Int) {
+        self.closePop()
+        if isImageToPDF {
+            if index == 0 {
+                containerViewController?.chooseFile()
+            } else if index == 1 {
+                containerViewController?.chooseFileFromCamera()
+            } else {
+                containerViewController?.chooseFileFromScanner()
+            }
+        } else {
+            if index == 0 {
+                containerViewController?.chooseFile()
+            } else {
+                containerViewController?.addOpendFile()
+            }
+        }
+    }
+}

+ 58 - 0
PDF Office/PDF Master/Class/Batch/View/KMTableHeaderCell.swift

@@ -0,0 +1,58 @@
+//
+//  KMTableHeaderCell.swift
+//  PDF Master
+//
+//  Created by kdanmobile on 2023/10/26.
+//
+
+import Cocoa
+
+class KMTableHeaderCell: NSTableHeaderCell{
+    override init(textCell string: String) {
+        super.init(textCell: string)
+        self.drawsBackground = false
+    }
+    
+    required init(coder: NSCoder) {
+        super.init(coder: coder)
+    }
+    
+    override func draw(withFrame cellFrame: NSRect, in controlView: NSView) {
+        super.draw(withFrame: cellFrame, in: controlView)
+        cellFrame.fill()
+        KMAppearance.Layout.l_2Color().set()
+        self.drawInterior(withFrame: cellFrame, inView: controlView)
+    }
+    
+    func drawInterior(withFrame cellFrame: NSRect, inView controlView: NSView) {
+        var titleRect = self.titleRect(forBounds: cellFrame)
+        titleRect.fill()
+        KMAppearance.Layout.l_2Color().set()
+        
+        let layoutManager = NSLayoutManager()
+        let lineHeight = layoutManager.defaultLineHeight(for: self.font!)
+        titleRect.origin.y = (titleRect.size.height - lineHeight) / 2.0
+        titleRect.size.height = lineHeight
+        
+        if self.alignment == NSTextAlignment.left {
+            self.attributedStringValue.draw(with: titleRect, options: .usesLineFragmentOrigin)
+        } else if self.alignment == NSTextAlignment.center {
+            let width = self.widthOfString(self.title, withFont: self.font!)
+            titleRect.origin.x += (titleRect.size.width - width) / 2.0
+            titleRect.size.width = width
+            self.attributedStringValue.draw(with: titleRect, options: .usesLineFragmentOrigin)
+        } else {
+            self.attributedStringValue.draw(with: titleRect, options: .usesLineFragmentOrigin)
+        }
+    }
+    func drawSortIndicator(withFrame cellFrame: NSRect, inView controlView: NSView, ascending: Bool, priority: Int) { 
+        
+    }
+    override func sortIndicatorRect(forBounds rect: NSRect) -> NSRect {
+        return NSRect.zero
+    }
+    func widthOfString(_ string: String, withFont font: NSFont) -> CGFloat {
+        let attributes = [NSAttributedString.Key.font: font]
+        return NSAttributedString(string: string, attributes: attributes).size().width
+    }
+}

+ 75 - 0
PDF Office/PDF Master/Class/Batch/WindowController/KMAlertWindowController.swift

@@ -0,0 +1,75 @@
+//
+//  KMAlertWindowController.swift
+//  PDF Master
+//
+//  Created by kdanmobile on 2023/10/27.
+//
+
+import Cocoa
+
+typealias alertConfirmCallback = () -> ()
+
+let kShowRemoveAllFilesHintinterfaceKey = "kShowRemoveAllFilesHintinterfaceKey"
+
+class KMAlertWindowController: NSWindowController{
+    var alertConfirmCallback: alertConfirmCallback?
+    
+    @IBOutlet var titleLabel: NSTextField!
+    
+    @IBOutlet var alertCheckButton: NSButton!
+    
+    @IBOutlet var cancelButton: NSButton!
+    
+    @IBOutlet var actionButton: NSButton!
+    
+    @objc class func swiftLoad() {
+        let dict: NSDictionary = UserDefaults().dictionaryRepresentation() as NSDictionary
+        var X = false
+        for  key  in dict.allKeys {
+            if key as! String == kShowRemoveAllFilesHintinterfaceKey{
+                X = true
+            }
+        }
+        if !X {
+            UserDefaults().set(true, forKey: kShowRemoveAllFilesHintinterfaceKey)
+        }
+    }
+    override func windowDidLoad() {
+        super.windowDidLoad()
+        self.titleLabel.stringValue = NSLocalizedString("Remove All", comment: "")
+        self.alertCheckButton.title = NSLocalizedString("No longer prompt", comment: "")
+        self.cancelButton.title = NSLocalizedString("Cancel", comment: "")
+        self.actionButton.title = NSLocalizedString("Remove All", comment: "")
+    }
+    
+    @IBAction func buttonClicked_Cancel(_ sender: NSButton) {
+        self.setNeedShowRemoveAllFilesHint()
+        self.dismissSheet(sender)
+    }
+    
+    @IBAction func buttonClicked_OK(_ sender: NSButton) {
+        self.setNeedShowRemoveAllFilesHint()
+        setNeedShowRemoveAllFilesHint()
+        self.alertConfirmCallback?()
+        self.dismissSheet(sender)
+    }
+    
+    func setNeedShowRemoveAllFilesHint() {
+        UserDefaults.standard.set(self.alertCheckButton.state == .on ? false : true, forKey: kShowRemoveAllFilesHintinterfaceKey) 
+        UserDefaults.standard.synchronize()
+    }
+    
+    func dismissSheet(_ sender: NSButton) {
+        if #available(macOS 10.13, *) {
+            self.window?.endSheet(sender.window!)
+        } else {
+            NSApp.endSheet(self.window!)
+        }
+        self.window?.orderOut(self)
+    }
+    
+    class func needShowRemoveAllFilesHint() -> Bool {
+        return UserDefaults().bool(forKey: kShowRemoveAllFilesHintinterfaceKey)
+    }
+    
+}

+ 86 - 0
PDF Office/PDF Master/Class/Batch/WindowController/KMAlertWindowController.xib

@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22154" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
+    <dependencies>
+        <deployment identifier="macosx"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22154"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <customObject id="-2" userLabel="File's Owner" customClass="NSAlertWindowController" customModule="PDF_Master" customModuleProvider="target">
+            <connections>
+                <outlet property="actionButton" destination="ysS-2k-HPo" id="qaJ-km-j4F"/>
+                <outlet property="alertCheckButton" destination="Ss5-2o-1Dn" id="QAq-RC-Zd2"/>
+                <outlet property="cancelButton" destination="zsE-FI-kaQ" id="wtU-IL-c6h"/>
+                <outlet property="titleLabel" destination="oE7-Dp-pX1" id="q2v-ya-T4a"/>
+                <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 title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="F0z-JX-Cv5">
+            <windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="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"/>
+            <view key="contentView" id="se5-gp-TjO">
+                <rect key="frame" x="0.0" y="0.0" width="480" height="123"/>
+                <autoresizingMask key="autoresizingMask"/>
+                <subviews>
+                    <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="oE7-Dp-pX1">
+                        <rect key="frame" x="22" y="89" width="40" height="16"/>
+                        <textFieldCell key="cell" lineBreakMode="clipping" title="Label" id="F1Y-TD-Qwj">
+                            <font key="font" metaFont="systemBold"/>
+                            <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
+                            <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
+                        </textFieldCell>
+                    </textField>
+                    <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Ss5-2o-1Dn">
+                        <rect key="frame" x="22" y="52" width="65" height="18"/>
+                        <buttonCell key="cell" type="check" title="Check" bezelStyle="regularSquare" imagePosition="left" inset="2" id="tpt-Dh-7Fl">
+                            <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
+                            <font key="font" metaFont="system"/>
+                        </buttonCell>
+                    </button>
+                    <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="zsE-FI-kaQ">
+                        <rect key="frame" x="323" y="11" width="75" height="32"/>
+                        <buttonCell key="cell" type="push" title="Button" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="qpU-aB-hza">
+                            <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
+                            <font key="font" metaFont="system"/>
+                        </buttonCell>
+                        <connections>
+                            <action selector="buttonClicked_Cancel:" target="-2" id="kba-bs-Qsg"/>
+                        </connections>
+                    </button>
+                    <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="ysS-2k-HPo">
+                        <rect key="frame" x="398" y="11" width="75" height="32"/>
+                        <buttonCell key="cell" type="push" title="Button" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="bUa-ym-CA2">
+                            <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
+                            <font key="font" metaFont="system"/>
+                            <string key="keyEquivalent" base64-UTF8="YES">
+DQ
+</string>
+                        </buttonCell>
+                        <connections>
+                            <action selector="buttonClicked_OK:" target="-2" id="IrN-3B-w5a"/>
+                        </connections>
+                    </button>
+                </subviews>
+                <constraints>
+                    <constraint firstItem="Ss5-2o-1Dn" firstAttribute="leading" secondItem="oE7-Dp-pX1" secondAttribute="leading" id="AYz-zn-Tfh"/>
+                    <constraint firstItem="Ss5-2o-1Dn" firstAttribute="top" secondItem="oE7-Dp-pX1" secondAttribute="bottom" constant="20" id="QuX-dn-jrK"/>
+                    <constraint firstItem="oE7-Dp-pX1" firstAttribute="top" secondItem="se5-gp-TjO" secondAttribute="top" constant="18" id="SRI-Wr-uxY"/>
+                    <constraint firstItem="oE7-Dp-pX1" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="24" id="SSp-26-c91"/>
+                    <constraint firstAttribute="trailing" secondItem="ysS-2k-HPo" secondAttribute="trailing" constant="14" id="V1E-Gh-5w6"/>
+                    <constraint firstItem="zsE-FI-kaQ" firstAttribute="top" secondItem="Ss5-2o-1Dn" secondAttribute="bottom" constant="15" id="e23-IR-hgF"/>
+                    <constraint firstItem="ysS-2k-HPo" firstAttribute="centerY" secondItem="zsE-FI-kaQ" secondAttribute="centerY" id="kaY-5L-ENc"/>
+                    <constraint firstAttribute="bottom" secondItem="ysS-2k-HPo" secondAttribute="bottom" constant="18" id="nOi-GR-wAx"/>
+                    <constraint firstItem="ysS-2k-HPo" firstAttribute="leading" secondItem="zsE-FI-kaQ" secondAttribute="trailing" constant="14" id="xam-1O-CR5"/>
+                </constraints>
+            </view>
+            <connections>
+                <outlet property="delegate" destination="-2" id="0bl-1N-AYu"/>
+            </connections>
+            <point key="canvasLocation" x="-100" y="114"/>
+        </window>
+    </objects>
+</document>

+ 31 - 0
PDF Office/PDF Master/Class/Batch/WindowController/KMBatchOperateBaseWindowController.swift

@@ -0,0 +1,31 @@
+//
+//  KMBatchOperateBaseWindowController.swift
+//  PDF Master
+//
+//  Created by kdanmobile on 2023/10/26.
+//
+
+import Cocoa
+
+class KMBatchOperateBaseWindowController: NSWindowController{
+    var files: [KMBatchOperateFile]?
+    var operateType: KMBatchOperationType?
+    
+    override func windowDidLoad() {
+        super.windowDidLoad()
+        self.configuUI()
+        files = NSMutableArray() as? [KMBatchOperateFile]
+    }
+    func configuUI() {
+        let splitViewController = KMBatchOperateSplitViewController(nibName: "KMBatchOperateSplitViewController", bundle: nil)
+        contentViewController = splitViewController
+    }
+    func switchToOperateType(_ operateType: KMBatchOperationType, files: [KMBatchOperateFile]) {
+//        self.files = files 
+//        (self.contentViewController as? KMBatchOperateSplitViewController)?.switchToOperateType(operateType: operateType, files: files as! NSMutableArray)
+//        self.operateType = operateType
+    }
+}
+
+
+

+ 30 - 0
PDF Office/PDF Master/Class/Batch/WindowController/KMBatchOperateBaseWindowController.xib

@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22154" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
+    <dependencies>
+        <deployment identifier="macosx"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22154"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <customObject id="-2" userLabel="File's Owner" customClass="KMBatchOperateBaseWindowController">
+            <connections>
+                <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 title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="F0z-JX-Cv5" customClass="KMBatchWindow">
+            <windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
+            <rect key="contentRect" x="422" y="270" width="480" height="270"/>
+            <rect key="screenRect" x="0.0" y="0.0" width="2560" height="1415"/>
+            <view key="contentView" id="se5-gp-TjO">
+                <rect key="frame" x="0.0" y="0.0" width="480" height="270"/>
+                <autoresizingMask key="autoresizingMask"/>
+            </view>
+            <connections>
+                <outlet property="delegate" destination="-2" id="0bl-1N-AYu"/>
+            </connections>
+            <point key="canvasLocation" x="-27" y="114"/>
+        </window>
+    </objects>
+</document>

+ 786 - 0
PDF Office/PDF Master/Class/Batch/WindowController/KMBatchOperateLeftViewController.swift

@@ -0,0 +1,786 @@
+//
+//  KMBatchOperateLeftViewController.swift
+//  PDF Master
+//
+//  Created by kdanmobile on 2023/10/26.
+//
+
+import Cocoa
+
+let KMBatchDragType = "KMBatchDragType"
+
+class KMBatchOperateLeftViewController: NSViewController,NSTableViewDelegate,NSTableViewDataSource{
+    
+    @IBOutlet var selectFileButton: KMLongerButton!
+    
+    @IBOutlet var deleteFileButton: NSButton!
+    
+    @IBOutlet var tableView: NSTableView!
+    
+    @IBOutlet var indexTableColumn: NSTableColumn!
+    
+    @IBOutlet var fileNameTableColumn: NSTableColumn!
+    
+    @IBOutlet var pageRangeTableColumn: NSTableColumn!
+    
+    @IBOutlet var sizeTableColumn: NSTableColumn!
+    
+    @IBOutlet var stateTableColumn: NSTableColumn!
+    
+    @IBOutlet var DPIColumn: NSTableColumn!
+    
+    @IBOutlet var dimensionsTableColumn: NSTableColumn!
+    
+    @IBOutlet var headerOperateView: NSView!
+    
+    @IBOutlet var showInFinderMenuItem: NSMenuItem!
+    
+    @IBOutlet var deleteMenuItem: NSMenuItem!
+    
+    @IBOutlet var blankView: KMBlankView!
+    
+    var files: [KMBatchOperateFile] = []
+    var type: KMBatchOperationType?
+    var lockFilePathArr: NSMutableArray?
+    var lockFileIndex: Int = 0
+    var popOver: NSPopover?
+    var progressInt: Int = 0
+    
+    override func viewDidLoad() {
+        super.viewDidLoad()
+        NotificationCenter.default.addObserver(self.tableView!, selector: #selector(self.reloadData), name: NSNotification.Name(kNeedChangePageRangeNotification), object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(imageToPDFSuccessNotification(aNotification:)), name: NSNotification.Name("KMBatchOperateImageToPDFSuccessNotification"), object: nil)
+        DistributedNotificationCenter.default.addObserver(self, selector: #selector(themeChanged(notification:)), name: NSNotification.Name("AppleInterfaceThemeChangedNotification"), object: nil)
+        
+        for i in 0..<self.tableView.tableColumns.count {
+            let column = self.tableView.tableColumns[i]
+            column.headerCell = KMTableHeaderCell(textCell: column.title)
+        }
+        
+        self.deleteFileButton.addHoverEffect = true
+        
+        self.indexTableColumn.resizingMask =  []
+        self.fileNameTableColumn.resizingMask = .autoresizingMask
+        self.pageRangeTableColumn.resizingMask =  []
+        self.sizeTableColumn.resizingMask =  []
+        self.stateTableColumn.resizingMask =  []
+        self.DPIColumn.resizingMask =  []
+        self.dimensionsTableColumn.resizingMask =  []
+        self.tableView.moveColumn(5, toColumn: 2)
+        
+        self.indexTableColumn.title = "  \(NSLocalizedString("Index", comment: ""))"
+        self.fileNameTableColumn.title = NSLocalizedString("File Name", comment: "")
+        self.pageRangeTableColumn.title = NSLocalizedString("Page Range", comment: "")
+        self.sizeTableColumn.title = NSLocalizedString("Size", comment: "")
+        self.stateTableColumn.title = NSLocalizedString("Status", comment: "")
+        self.DPIColumn.title = NSLocalizedString("DPI", comment: "")
+        self.dimensionsTableColumn.title = NSLocalizedString("Dimensions", comment: "")
+        
+        self.DPIColumn.isHidden = true
+        self.tableView.intercellSpacing = CGSize(width: 0, height: 0)
+        self.tableView.backgroundColor = KMAppearance.Layout.bgColor()
+        self.tableView.allowsColumnReordering = false
+        self.tableView.allowsMultipleSelection = true
+        self.tableView.enclosingScrollView?.borderType = .noBorder
+        
+        self.headerOperateView.wantsLayer = true
+        
+        self.tableView.registerForDraggedTypes([NSPasteboard.PasteboardType.string,NSPasteboard.PasteboardType.fileURL]) //[KMBatchDragType,NSFilenamesPboardType]
+        self.lockFilePathArr = NSMutableArray()
+        self.lockFileIndex = 0
+        self.progressInt = 0
+        
+        self.selectFileButton.title = NSLocalizedString("Add Files", comment: "")
+        self.selectFileButton.wantsLayer = true
+        self.selectFileButton.layer?.borderWidth = 1.0
+        self.selectFileButton.layer?.borderColor = KMAppearance.Interactive.m0Color().cgColor
+        self.selectFileButton.layer?.cornerRadius = 1.0
+        self.selectFileButton.setTitleColor(KMAppearance.Layout.mColor())
+        self.selectFileButton.containerViewController = self
+        
+        self.showInFinderMenuItem.title = NSLocalizedString("Show in Finder", comment: "")
+        self.deleteMenuItem.title = NSLocalizedString("Delete", comment: "")
+        self.blankView.wantsLayer = true
+        self.blankView.layer?.backgroundColor = NSColor.clear.cgColor
+        self.blankView.titleLabel.stringValue = NSLocalizedString("Select Files", comment: "")
+        self.blankView.secondTitleLabel.stringValue = NSLocalizedString("Drop files here or Click Add Files at upper left corner. You can drag files to reorder as you need.", comment: "")
+        self.blankView.mouseActionCallBack = { [weak self] mouseType in
+            guard let self = self else { return }
+            if mouseType == .mouseEnter {
+                self.blankView.imageView.image = NSImage(named: "KMImageNameEmptyListHov")
+            } else if mouseType == .mouseExit {
+                self.blankView.imageView.image = NSImage(named: "KMImageNameEmptyListNor")
+            } else if mouseType == .mouseDown {
+                self.blankView.imageView.image = NSImage(named: "KMImageNameEmptyListPre")
+                self.chooseFile()
+            } else if mouseType == .mouseUp {
+                self.blankView.imageView.image = NSImage(named: "KMImageNameEmptyListHov")
+            }
+        }
+        updateViewColor()
+    }
+    @objc func reloadData() {
+        if Thread.isMainThread {
+            tableView.reloadData()
+        } else {
+            DispatchQueue.main.async {
+                self.tableView.reloadData()
+            }
+        }
+    }
+    
+    @objc func imageToPDFSuccessNotification(aNotification: Notification) {
+        guard let dict = aNotification.userInfo, let isSuccess = dict["isSuccess"] as? Bool else { return }
+        if isSuccess {
+            progressInt = 1
+        } else {
+            progressInt = -1
+        }
+        
+        DispatchQueue.main.async {
+            self.tableView.reloadData()
+        }
+    }
+    @objc func themeChanged(notification: Notification) {
+        DispatchQueue.main.asyncAfter(deadline: .now() + 0.3, execute: {
+            self.updateViewColor()
+        })
+    }
+    
+    func updateViewColor() {
+        self.view.wantsLayer = true
+        if KMAppearance.isDarkMode() {
+            self.headerOperateView.layer?.backgroundColor = NSColor(red: 0.055, green: 0.067, blue: 0.078, alpha: 1).cgColor
+        } else {
+            self.headerOperateView.layer?.backgroundColor = NSColor(red: 0.922, green: 0.925, blue: 0.941, alpha: 1).cgColor
+        }
+    }
+    
+    func chooseFile() {
+#if VERSION_FREE 
+        // KMToolCompareWindowController *vc = [KMToolCompareWindowController toolCompareWithType:KMCompareWithToolType_Convert setSelectIndex:1];
+        // [vc showWindow:nil];
+//        if !IAPProductsManager.defaultManager().isAvailableAllFunction() {
+//            if files.count >= 1 {
+//                KMPurchaseCompareWindowController.sharedInstance().showWindow(nil)
+//                return
+//            }
+//        }
+            //展示升级页面
+#endif
+        self.progressInt = 0
+        let panel = NSOpenPanel() 
+        if type == .CreatePDF {
+            panel.allowedFileTypes = KMImageToPDFMethod.supportedImageTypes()
+        } else {
+            panel.allowedFileTypes = ["pdf", "PDF"]
+        }
+//        if IAPProductsManager.defaultManager().isAvailableAllFunction() {
+            panel.allowsMultipleSelection = true
+            panel.canChooseDirectories = true
+//        }
+        panel.canChooseFiles = true
+#if VERSION_FREE
+#else
+        panel.message = NSLocalizedString("To select multiple files press cmd ⌘ button on keyboard and click on the target files one by one.", comment: "")
+#endif
+        panel.beginSheetModal(for: self.view.window!) {
+            (result) in
+            if result.rawValue == NSApplication.ModalResponse.OK.rawValue {
+                var addArray = NSMutableArray()
+                for fileURL in panel.urls {
+                    let filePath = fileURL.path
+                    var isDirectory = ObjCBool(false)
+                    FileManager.default.fileExists(atPath: filePath, isDirectory: &isDirectory)
+                    if isDirectory.boolValue {
+                        let containFiles = self.fetchAvailableFiles(in: filePath)
+                        addArray.add(containFiles)
+                    } else {
+                        let UTTypeString = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, filePath.extension as CFString, nil)
+                        let TypeCFString = UTTypeString as! CFString
+                        if self.type == .CreatePDF {
+                            if UTTypeConformsTo(TypeCFString, kUTTypeImage) {
+                                addArray.add(filePath)
+                            }
+                        } else {
+                            if UTTypeConformsTo(TypeCFString, kUTTypePDF) {
+                                addArray.add(filePath)
+                            }
+                        }
+                    }
+                }
+                self.addFilesToList(addArray: addArray)
+            }
+        }
+    }
+    func fetchAvailableFiles(in folderPath: String) -> [String] {
+        var array = NSMutableArray()
+        let subFileArray = (FileManager.default.subpaths(atPath: folderPath)! as NSArray).mutableCopy() as? NSMutableArray
+        for i in 0..<subFileArray!.count {
+            if let path = (folderPath as NSString).appendingPathComponent(subFileArray!.object(at: i) as! String) as String? {
+                if let UTTypeString = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, path.extension as CFString, nil)?.takeRetainedValue() as String? {
+                    let TypeCFString = UTTypeString as CFString
+                    if self.type == .CreatePDF {
+                        if UTTypeConformsTo(TypeCFString, kUTTypeImage) {
+                            array.add(path)
+                        }
+                    } else {
+                        if UTTypeConformsTo(TypeCFString, kUTTypePDF) {
+                            array.add(path)
+                        }
+                    }
+                }
+            }
+        }
+        return array as! [String]
+    }
+    func addFilesToList(addArray: NSMutableArray) {
+        self.lockFilePathArr!.removeAllObjects()
+        self.lockFileIndex = 0
+        for i in 0..<addArray.count {
+            let filePath = addArray[i] as! String
+            let UTTypeString = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, filePath.extension as CFString, nil)!.takeRetainedValue() as String
+            let TypeCFString = UTTypeString as CFString
+            if UTTypeConformsTo(TypeCFString, kUTTypePDF) {
+                let document = PDFDocument(url: URL(fileURLWithPath: filePath))
+                if document?.isLocked == true {
+                    var isContaint = false
+                    for file in self.files {
+                        if (file as AnyObject).filePath == filePath {
+                            isContaint = true
+                            break
+                        }
+                    }
+                    if !isContaint {
+                        self.lockFilePathArr!.add(filePath)
+                    }
+                } else {
+                    let file = KMBatchOperateFile(filePath: addArray[i] as! String, type: self.type!)
+                    if !self.files.contains(file) {
+                        self.files.append(file)
+                    }
+                }
+            } else {
+                let file = KMBatchOperateFile(filePath: addArray[i] as! String, type: self.type!)
+                if !self.files.contains(file) {
+                    self.files.append(file)
+                }
+            }
+        }
+        self.tableView.reloadData()
+        if self.lockFilePathArr!.count > 0 {
+            DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
+                self.openPasswordWindow()
+            }
+        }
+    }
+    func openPasswordWindow() {
+        
+//        if lockFilePathArr!.count > lockFileIndex {
+//            let filePath = lockFilePathArr![lockFileIndex] as! String
+//            let com = PasswordWindowController(windowNibName: "PasswordWindowController")
+//            com.fileURL = URL(fileURLWithPath: filePath)
+//            com.beginSheetModal
+//            (for: self.view.window!) {
+//                password in
+//                if let password = password {
+//                    let file = KMBatchOperateFile(filePath: filePath, type: self.type)
+//                    file.password = password
+//                    self.files.add(file)
+//                    self.tableView.reloadData()
+//                }
+//                self.lockFileIndex += 1
+//                if self.lockFilePathArr.count > self.lockFileIndex {
+//                    DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
+//                        self.openPasswordWindow()
+//                    }
+//                } else {
+//                    self.tableView.reloadData()
+//                }
+//            }
+//        }
+    }
+    func chooseFileFromCamera() {
+        self.progressInt = 0
+        let vc = KMDeviceBrowserWindowController()
+        vc.type = ICDeviceType.camera
+        vc.importCameraFileCallback = { [weak self](url: NSURL) -> Void in
+            self!.addFilesToList(addArray: [url.path!])
+        }
+        vc.showWindow(nil)
+    }
+    func chooseFileFromScanner() {
+        self.progressInt = 0
+        let vc = KMDeviceBrowserWindowController()
+        vc.type = .scanner
+        vc.importScannerFileCallback = { [weak self](url: NSURL) -> Void in
+            self!.addFilesToList(addArray: [url.path!])
+        }
+    }
+    
+    @IBAction func buttonClicked_SelectFile(_ sender: Any) {
+        
+    }
+    
+    @IBAction func buttonClicked_DeleteFile(_ sender: Any) {
+        let set = self.tableView.selectedRowIndexes
+        let newArr: NSMutableArray = self.files as! NSMutableArray
+        let arr = newArr.objects(at: set)
+        if arr.count > 0 {
+            newArr.removeObjects(in: arr)
+            self.files = newArr as! [KMBatchOperateFile]
+            self.tableView.reloadData()
+        } else {
+            if KMAlertWindowController.needShowRemoveAllFilesHint() {
+                let alert = NSAlert()
+                alert.alertStyle = .critical
+                alert.messageText = NSLocalizedString("Clear All Recents", comment: "")+"?"
+                alert.addButton(withTitle: NSLocalizedString("Delete", comment: ""))
+                alert.addButton(withTitle: NSLocalizedString("Cancel", comment: ""))
+                alert.beginSheetModal(for: self.view.window!) {[weak self] response in
+                    if response == NSApplication.ModalResponse.alertFirstButtonReturn {
+                        self?.files.removeAll()
+                        self?.tableView.reloadData()
+                    }
+                }
+            } else {
+                self.files.removeAll()
+                self.tableView.reloadData()
+            }
+        }
+    }
+    func fetchAvailableFilesInFolder(_ folderPath: String) -> [String] {
+        var array: [String] = []
+        var subFileArray = FileManager().subpaths(atPath: folderPath)
+        for i in 0..<subFileArray!.count {
+            let path = folderPath.stringByAppendingPathComponent(subFileArray![i])
+            let UTTypeString = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, path.extension as CFString, nil)
+            let TypeCFString = UTTypeString as! CFString?
+            if self.type == .CreatePDF {
+                if UTTypeConformsTo(TypeCFString!, kUTTypeImage) {
+                    array.append(path)
+                }
+            } else {
+                if UTTypeConformsTo(TypeCFString!, kUTTypePDF) {
+                    array.append(path)
+                }
+            }
+//            UTTypeString?.release()
+        }
+        return array
+    }
+    func folderContainAvailableFile(_ folderPath: String) -> Bool {
+        var containFile = false
+        let subFileArray = FileManager.default.subpaths(atPath: folderPath) as? NSMutableArray
+        for i in 0..<subFileArray!.count {
+            let path = folderPath.stringByAppendingPathComponent(subFileArray![i] as! String)
+            let UTTypeString = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, path.extension as CFString, nil)
+            let TypeCFString = UTTypeString as! CFString?
+            if type == .CreatePDF {
+                if UTTypeConformsTo(TypeCFString!, kUTTypeImage) {
+                    containFile = true
+                }
+            } else {
+                if UTTypeConformsTo(TypeCFString!, kUTTypePDF) {
+                    containFile = true
+                }
+            }
+//            UTTypeString?.release()
+            if containFile {
+                break
+            }
+        }
+        return containFile
+    }
+    func switchToOperateType(_ type: KMBatchOperationType) {
+        self.type = type
+        self.indexTableColumn.isHidden = false
+        self.fileNameTableColumn.isHidden = false
+        self.pageRangeTableColumn.isHidden = false
+        self.sizeTableColumn.isHidden = false
+        self.stateTableColumn.isHidden = false
+        self.DPIColumn.isHidden = true
+        self.dimensionsTableColumn.isHidden = true
+        if type == .Compress || type == .AddPassword || type == .RemovePassword || type == .RemoveWatermark || type == .RemoveBackground || type == .RemoveHeaderFooter || type == .RemoveBates || type == .CreatePDF {
+            self.pageRangeTableColumn.isHidden = true
+        } else {
+            self.pageRangeTableColumn.isHidden = false
+        }
+        
+        self.selectFileButton.isImageToPDF = type == .CreatePDF
+        if type == .CreatePDF {
+            self.pageRangeTableColumn.isHidden = false
+            self.pageRangeTableColumn.title = NSLocalizedString("Dimensions", comment: "")
+        }
+        
+        for i in 0..<self.files.count {
+            let file = self.files[i]
+            file.currentOperateType = type
+        }
+        self.tableView.sizeToFit()
+        self.tableView.reloadData()
+    }
+    
+    @IBAction func menuItem_ShowInFinder(_ sender: Any) {
+        var row = self.tableView.clickedRow
+        var file: KMBatchOperateFile = self.files[row]
+        if file.currentOperateInfo?.status == .Success {
+            NSWorkspace.shared.activateFileViewerSelecting([URL(fileURLWithPath: file.currentOperateInfo!.outPutPath!)])
+        }else {
+            NSWorkspace.shared.activateFileViewerSelecting([URL(fileURLWithPath: file.filePath)])
+        }
+    }
+    
+    @IBAction func menuItem_Delete(_ sender: Any) {
+        var row = self.tableView.clickedRow
+        self.files.remove(at: row)
+        self.tableView.reloadData()
+    }
+    
+    func validateMenuItem(menuItem: NSMenuItem) -> Bool {
+        let action = menuItem.action
+        if action == #selector(menuItem_ShowInFinder(_:)) || action == #selector(menuItem_Delete(_:)) {
+            if tableView.clickedRow == -1 {
+                return false
+            }
+            return true
+        }
+        return true
+    }
+    func addOpendFile() {
+        let documentArray = NSDocumentController.shared.documents
+        var pdfArray = NSMutableArray()
+        for i in 0..<documentArray.count {
+            let document = documentArray[i]
+            let path = document.fileURL?.path
+            var UTTypeString = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, path!.extension as CFString, nil)
+            let TypeCFString = UTTypeString as! CFString
+            if UTTypeConformsTo(TypeCFString, kUTTypePDF) {
+                pdfArray.add(path as Any)
+//                UTTypeString?.release()
+            } else {
+//                UTTypeString?.release()
+            }
+        }
+//        if !IAPProductsManager.defaultManager.isAvailableAllFunction() {
+            if self.files.count < 1 {
+                pdfArray = [pdfArray.first].compactMap { $0 } as! NSMutableArray
+            } else {
+//                KMPurchaseCompareWindowController.sharedInstance.showWindow(nil)
+//                return
+            }
+//        }
+        addFilesToList(addArray: pdfArray)
+    }
+    func numberOfRows(in tableView: NSTableView) -> Int {
+        NotificationCenter.default.post(name: NSNotification.Name(rawValue: "KMBatchFilesCountNotification"), object: self.files)
+        self.deleteFileButton.isEnabled = self.files.count > 0
+        self.blankView.isHidden = self.files.count > 0
+        return self.files.count;
+    }
+    func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
+        let identifier = tableColumn!.identifier
+        let file = self.files[row]
+      
+        if identifier.rawValue == "index" {
+            var cellView = KMBatchTableCellView(type: .Size)
+            cellView.textField?.stringValue = "(row + 1)";
+            return cellView;
+        } else if identifier.rawValue == "pageRange"{
+            if (file.currentOperateType == .CreatePDF) {
+                var cellView = KMBatchTableCellView(type: .Size)
+                
+                if (file.fileType == .Image) {
+                    var image = NSImage(contentsOfFile: file.filePath)
+                    cellView.textField?.stringValue = "(Int(image.size.width)) x (Int(image.size.height))"
+                }
+             
+                return cellView;
+            } else {
+                var cellView = KMBatchTableCellView(type: .PageRange)
+                cellView.updateInterface(file)
+                return cellView;
+            }
+        } else if identifier.rawValue == "status"{
+            var cellView = KMBatchTableCellView(type: .Status)
+            if (file.currentOperateType == .CreatePDF) {
+                cellView.updateInterface(file: file, progress: file.progress ?? 0)
+            } else {
+                cellView.updateInterface(file: file, progress: file.progress ?? 0)
+            }
+            cellView.removeFileCallBack = { [weak self] file in
+                self?.files.removeObject(file)
+                self?.tableView.reloadData()
+            }
+            return cellView;
+        } else if identifier.rawValue == "size"{
+            var cellView = KMBatchTableCellView(type: .Size)
+            cellView.updateInterface(file)
+            return cellView;
+        } else if identifier.rawValue == "fileName"{
+            var cellView = KMBatchTableCellView(type: .FileName)
+            cellView.updateInterface(file)
+            var rowView = tableView.rowView(atRow: row, makeIfNecessary: true)
+            if ((file.error) != nil) {
+                rowView?.backgroundColor = KMAppearance.Status.errBGColor();
+            }
+            return cellView;
+        } else if identifier.rawValue == "dpi"{
+            var cellView = KMBatchTableCellView(type: .DPI)
+            cellView.updateInterface(file)
+            return cellView;
+        } else if identifier.rawValue == "dimensions"{
+            var cellView = KMBatchTableCellView(type: .Size)
+            
+            if (file.fileType == .Image) {
+                var image = NSImage(contentsOfFile: file.filePath)
+                cellView.textField?.stringValue = "(Int(image.size.width)) x (Int(image.size.height))"
+            }
+         
+            return cellView;
+        }
+        return nil;
+    }
+    func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat {
+        let file = self.files[row]
+        if self.type == .CreatePDF {
+            if (file.error != nil) {
+                return 64
+            } else {
+                return 40
+            }
+        } else {
+            if file.fileType == .PDF {
+                if (file.error != nil) {
+                    return 64
+                } else {
+                    return 40
+                }
+            } else {
+                return 0.0000001
+            }
+        }
+    }
+    func tableView(_ tableView: NSTableView, rowViewForRow row: Int) -> NSTableRowView? {
+        let rowView = KMBatchTableRowView()
+        return rowView
+    }
+    func tableView(_ tableView: NSTableView, writeRowsWith rowIndexes: IndexSet, to pboard: NSPasteboard) -> Bool {
+        let indexSetData = try? NSKeyedArchiver.archivedData(withRootObject: rowIndexes, requiringSecureCoding: true)
+        pboard.declareTypes([NSPasteboard.PasteboardType.string], owner: self)
+        pboard.setData(indexSetData, forType: NSPasteboard.PasteboardType(rawValue: KMBatchDragType) )
+        return true
+    }
+    func tableView(_ tableView: NSTableView, validateDrop info: NSDraggingInfo, proposedRow row: Int, proposedDropOperation dropOperation: NSTableView.DropOperation) -> NSDragOperation {
+        var isCanDrag = false
+        var result: NSDragOperation = []
+        let pboard = info.draggingPasteboard
+        if pboard.availableType(from: [.fileURL]) != nil {
+            if let fileURLs = pboard.propertyList(forType: .fileURL) as? [URL] {
+                for url in fileURLs {
+                    var isDirectory: ObjCBool = false
+                    let fileExists = FileManager.default.fileExists(atPath: url.path, isDirectory: &isDirectory)
+                    if fileExists && isDirectory.boolValue {
+                        let containFile = folderContainAvailableFile(url.path)
+                        if containFile {
+                            isCanDrag = true
+                            break
+                        }
+                    } else {
+                        if let UTType = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, url.pathExtension as CFString, nil)?.takeRetainedValue() as String? {
+                            if self.type == .CreatePDF {
+                                if UTTypeConformsTo(UTType as CFString, kUTTypeImage) {
+                                    isCanDrag = true
+                                }
+                            } else {
+                                if UTTypeConformsTo(UTType as CFString, kUTTypePDF) {
+                                    isCanDrag = true
+                                }
+                            }
+                        }
+                        if isCanDrag {
+                            break
+                        }
+                    }
+                }
+            }
+            if isCanDrag {
+                result = .copy
+            }
+            return result
+        } else {
+            return .move
+        }
+    }
+    func tableView(_ tableView: NSTableView, acceptDrop info: NSDraggingInfo, row: Int, dropOperation: NSTableView.DropOperation) -> Bool {
+        let pboard = info.draggingPasteboard
+        if pboard.availableType(from: [.init(KMBatchDragType)]) != nil {
+            guard let rowData = pboard.data(forType: .init(KMBatchDragType)),
+                  let rowIndexes = NSKeyedUnarchiver.unarchiveObject(with: rowData) as? NSIndexSet else { return false }
+            var backUpArray = self.files
+            var referenceIndex = -1
+            rowIndexes.enumerate(options: .reverse, using: { (idx, stop) in
+                var sortFile = backUpArray[idx]
+                if referenceIndex < 0 {
+                    if idx > row {
+                        self.files.remove(at: idx)
+                        self.files.insert(sortFile, at: row)
+                    } else if idx < row {
+                        if row > self.files.count {
+                            self.files.remove(at: idx)
+                            self.files.append(sortFile)
+                        } else {
+                            self.files.remove(at: idx)
+                            self.files.insert(sortFile, at: row - 1)
+                        }
+                    }
+                    referenceIndex = self.files.firstIndex(of: sortFile) ?? -1
+                } else {
+                    let currentIndex = self.files.firstIndex(of: sortFile) ?? -1
+                    if currentIndex > referenceIndex {
+                        self.files.remove(at: currentIndex)
+                        self.files.insert(sortFile, at: referenceIndex)
+                    } else {
+                        referenceIndex -= 1
+                        self.files.remove(at: currentIndex)
+                        self.files.insert(sortFile, at: referenceIndex)
+                    }
+                }
+            })
+            self.tableView.reloadData()
+            return true
+        } else if pboard.availableType(from: [.fileURL]) != nil {
+            guard let fileNames = pboard.propertyList(forType: .fileURL) as? [String]
+            else {
+                return false
+            }
+            var allFilesArray = NSMutableArray()
+            for path in fileNames {
+                var isFolder = ObjCBool(false)
+                FileManager.default.fileExists(atPath: path, isDirectory: &isFolder)
+                if isFolder.boolValue {
+                    let containFiles = fetchAvailableFilesInFolder(path)
+                    allFilesArray.addObjects(from: containFiles)
+                } else {
+                    var UTTypeString = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, path.extension as CFString, nil)
+                    let TypeCFString = UTTypeString as! CFString
+                    
+                    if self.type == .CreatePDF {
+                        if UTTypeConformsTo(TypeCFString, kUTTypeImage) {
+                            allFilesArray.add(path)
+                        }
+                    } else {
+                        if UTTypeConformsTo(TypeCFString, kUTTypePDF) {
+                            allFilesArray.add(path)
+                        }
+                    }
+                }
+            }
+            var insertArray = NSMutableArray()
+            lockFilePathArr?.removeAllObjects()
+            lockFileIndex = 0
+            for i in 0..<allFilesArray.count {
+                let filePath: String = allFilesArray[i] as! String
+                var UTTypeString = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, filePath.extension as CFString, nil)
+                let TypeCFString = UTTypeString as! CFString
+                if UTTypeConformsTo(TypeCFString, kUTTypePDF) {
+                    let document = PDFDocument(url: URL(fileURLWithPath: filePath))
+                    if let pdf = PDFDocument(url: URL(fileURLWithPath: filePath)) {
+                        if !pdf.allowsPrinting || !pdf.allowsCopying {
+                            let alert = NSAlert()
+                            alert.alertStyle = .critical
+                            alert.messageText = NSLocalizedString("This is a secured document. Editing is not permitted.", comment: "")
+                            alert.runModal()
+                            continue
+                        } else if document?.isLocked ?? false {
+                            lockFilePathArr?.add(filePath)
+                        } else {
+                            let file = KMBatchOperateFile(filePath: filePath, type: self.type!)
+                            if !(self.files.contains(file) ) {
+                                insertArray.add(file)
+                            }
+                        }
+                    }
+                } else {
+                    let file = KMBatchOperateFile(filePath: filePath, type: self.type!)
+                    if !(self.files.contains(file) ) {
+                        insertArray.add(file)
+                    }
+                }
+            }
+            //        if !(IAPProductsManager.defaultManager.isAvailableAllFunction) {
+            if self.files.count < 1 {
+                insertArray = [insertArray.first].compactMap { $0 } as! NSMutableArray
+            } else {
+                //                KMPurchaseCompareWindowController.sharedInstance.showWindow(nil)
+                return false
+            }
+            //        }
+            for i in 0..<insertArray.count {
+                self.files.insert(insertArray[i] as! KMBatchOperateFile, at: row + i)
+            }
+            self.tableView.reloadData()
+            if lockFilePathArr!.count > 0 {
+                DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
+                    self.openPasswordWindow()
+                }
+            }
+            return true
+        }
+        return false
+    }
+    func switchToOperateType(_ operateType: KMBatchOperationType, files: [KMBatchOperateFile]) {
+        switchToOperateType(operateType)
+        self.files = files 
+        self.tableView.reloadData()
+    }
+    func checkNeedPasswordSwitchToOperateType(_ operateType: KMBatchOperationType, files: [KMBatchOperateFile]) {
+        switchToOperateType(operateType)
+        var arr: [String] = []
+        for i in 0..<files.count {
+            let file = files[i]
+            arr.append(file.filePath)
+        }
+        
+        self.files = files
+        self.files.removeAll()
+        addFilesToList(addArray: arr as! NSMutableArray)
+        self.tableView.reloadData()
+    }
+    func reloadFile(_ file: KMBatchOperateFile) {
+        var rowIndexSet = IndexSet()
+        for i in 0..<self.files.count {
+            if file.filePath == self.files[i].filePath {
+                rowIndexSet.insert(i)
+                break
+            }
+        }
+        var columnIndexSet = IndexSet()
+        for i in 0..<self.tableView.numberOfColumns {
+            let identifier = self.tableView.tableColumns[i].identifier
+            if identifier.rawValue == "status" {
+                columnIndexSet.insert(i)
+                break
+            }
+        }
+        
+        if Thread.isMainThread {
+            self.tableView.reloadData(forRowIndexes: rowIndexSet, columnIndexes: columnIndexSet)
+        } else {
+            DispatchQueue.main.async {
+                self.tableView.reloadData(forRowIndexes: rowIndexSet, columnIndexes: columnIndexSet)
+            }
+        }
+    }
+    func refreshConvertProgress(_ progress: CGFloat, file: KMBatchOperateFile) {
+        self.tableView.reloadData()
+    }
+    func reloadConvertInterface(withType type: KMConvertWithPDFType) {
+        if type == .WordAdvance || type == .WordStandard || type == .Excel || type == .PowerPoint || type == .RTF || type == .CSV || type == .HTML || type == .Text {
+            self.DPIColumn.isHidden = true
+        } else {
+            self.DPIColumn.isHidden = false
+        }
+        self.tableView.reloadData()
+    }
+}

+ 334 - 0
PDF Office/PDF Master/Class/Batch/WindowController/KMBatchOperateLeftViewController.xib

@@ -0,0 +1,334 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22154" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
+    <dependencies>
+        <deployment identifier="macosx"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22154"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <customObject id="-2" userLabel="File's Owner" customClass="KMBatchOperateLeftViewController" customModule="PDF_Master" customModuleProvider="target">
+            <connections>
+                <outlet property="DPIColumn" destination="AKG-QZ-eeC" id="S9s-Ib-ZAQ"/>
+                <outlet property="blankView" destination="G6v-if-4fr" id="hL3-ga-3wb"/>
+                <outlet property="deleteFileButton" destination="0F7-Ym-8wO" id="dwe-pv-XiV"/>
+                <outlet property="deleteMenuItem" destination="1Q4-gp-Cqq" id="AfZ-JX-3zI"/>
+                <outlet property="dimensionsTableColumn" destination="BoK-gf-WJ0" id="xYU-E4-XDD"/>
+                <outlet property="fileNameTableColumn" destination="TTZ-qf-vYt" id="EN8-Am-xW8"/>
+                <outlet property="headerOperateView" destination="yD5-qe-EWK" id="72z-5D-Plc"/>
+                <outlet property="indexTableColumn" destination="dvO-PE-2DL" id="wfQ-RQ-ZVA"/>
+                <outlet property="pageRangeTableColumn" destination="1OD-xa-ZwP" id="DZg-xv-How"/>
+                <outlet property="selectFileButton" destination="9ff-Qn-trv" id="cOO-DM-RVW"/>
+                <outlet property="showInFinderMenuItem" destination="pcS-mu-f3A" id="3Lv-9Y-3On"/>
+                <outlet property="sizeTableColumn" destination="Jv9-CS-hrB" id="Eim-DL-Jvf"/>
+                <outlet property="stateTableColumn" destination="vhM-02-bDl" id="IMt-Zu-lND"/>
+                <outlet property="tableView" destination="iqp-fI-b2v" id="kee-7b-Skq"/>
+                <outlet property="view" destination="Hz6-mo-xeY" id="0bl-1N-x8E"/>
+            </connections>
+        </customObject>
+        <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
+        <customObject id="-3" userLabel="Application" customClass="NSObject"/>
+        <customView misplaced="YES" id="Hz6-mo-xeY">
+            <rect key="frame" x="0.0" y="0.0" width="620" height="459"/>
+            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
+            <subviews>
+                <customView translatesAutoresizingMaskIntoConstraints="NO" id="yD5-qe-EWK">
+                    <rect key="frame" x="0.0" y="419" width="793" height="40"/>
+                    <subviews>
+                        <button verticalHuggingPriority="750" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="9ff-Qn-trv" customClass="KMLongerButton">
+                            <rect key="frame" x="20" y="10" width="143" height="18"/>
+                            <buttonCell key="cell" type="square" title="Add File..." bezelStyle="shadowlessSquare" image="KMImageNameUXIconBtnAddHov" imagePosition="left" alignment="center" inset="2" id="GI3-CE-S91" customClass="KMButtomCell">
+                                <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
+                                <font key="font" metaFont="system"/>
+                            </buttonCell>
+                        </button>
+                        <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="0F7-Ym-8wO">
+                            <rect key="frame" x="760" y="12" width="16" height="16"/>
+                            <buttonCell key="cell" type="square" title="Button" bezelStyle="shadowlessSquare" image="KMImageNameUXIconBtnDeletNor" imagePosition="only" alignment="center" alternateImage="KMImageNameUXIconBtnDeletHov" imageScaling="proportionallyDown" inset="2" id="F2E-HK-Xqi">
+                                <behavior key="behavior" lightByContents="YES"/>
+                                <font key="font" metaFont="system"/>
+                            </buttonCell>
+                            <connections>
+                                <action selector="buttonClicked_DeleteFile:" target="-2" id="Lxu-lp-UMe"/>
+                            </connections>
+                        </button>
+                    </subviews>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="40" id="1XQ-Cb-Icy"/>
+                        <constraint firstItem="9ff-Qn-trv" firstAttribute="centerY" secondItem="yD5-qe-EWK" secondAttribute="centerY" id="4Fb-87-EkC"/>
+                        <constraint firstItem="9ff-Qn-trv" firstAttribute="leading" secondItem="yD5-qe-EWK" secondAttribute="leading" constant="16" id="Ubq-az-jty"/>
+                        <constraint firstAttribute="trailing" secondItem="0F7-Ym-8wO" secondAttribute="trailing" constant="17" id="c5D-SY-3Rg"/>
+                        <constraint firstItem="0F7-Ym-8wO" firstAttribute="centerY" secondItem="yD5-qe-EWK" secondAttribute="centerY" id="jCA-77-pec"/>
+                        <constraint firstItem="9ff-Qn-trv" firstAttribute="top" secondItem="yD5-qe-EWK" secondAttribute="top" constant="10" id="ygi-yr-WFR"/>
+                    </constraints>
+                </customView>
+                <scrollView autohidesScrollers="YES" horizontalLineScroll="19" horizontalPageScroll="10" verticalLineScroll="19" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="cSo-1J-C87">
+                    <rect key="frame" x="0.0" y="0.0" width="793" height="419"/>
+                    <clipView key="contentView" ambiguous="YES" id="5QZ-3D-5sN">
+                        <rect key="frame" x="1" y="1" width="791" height="417"/>
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                        <subviews>
+                            <tableView verticalHuggingPriority="750" ambiguous="YES" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnSelection="YES" multipleSelection="NO" autosaveColumns="NO" rowSizeStyle="automatic" headerView="Mlr-rw-6rm" viewBased="YES" id="iqp-fI-b2v">
+                                <rect key="frame" x="0.0" y="0.0" width="791" height="392"/>
+                                <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                                <size key="intercellSpacing" width="3" height="2"/>
+                                <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
+                                <color key="gridColor" red="1" green="0.64784158279075421" blue="0.26014074763814632" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                <tableColumns>
+                                    <tableColumn identifier="index" width="72" minWidth="72" maxWidth="72" id="dvO-PE-2DL">
+                                        <tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="序号">
+                                            <color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
+                                            <color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
+                                        </tableHeaderCell>
+                                        <textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" title="Text Cell" id="czc-3c-yCB">
+                                            <font key="font" metaFont="system"/>
+                                            <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
+                                            <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
+                                        </textFieldCell>
+                                        <tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
+                                        <prototypeCellViews>
+                                            <tableCellView id="mJ1-Fh-j8e">
+                                                <rect key="frame" x="1" y="1" width="77" height="17"/>
+                                                <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                                            </tableCellView>
+                                        </prototypeCellViews>
+                                    </tableColumn>
+                                    <tableColumn identifier="fileName" width="100" minWidth="100" maxWidth="1000" id="TTZ-qf-vYt">
+                                        <tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="文件名">
+                                            <color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
+                                            <color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
+                                        </tableHeaderCell>
+                                        <textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" title="Text Cell" id="ctm-0t-PP7">
+                                            <font key="font" metaFont="system"/>
+                                            <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
+                                            <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
+                                        </textFieldCell>
+                                        <tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
+                                        <prototypeCellViews>
+                                            <tableCellView id="Mgh-hp-ErW">
+                                                <rect key="frame" x="81" y="1" width="100" height="17"/>
+                                                <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                                            </tableCellView>
+                                        </prototypeCellViews>
+                                    </tableColumn>
+                                    <tableColumn identifier="pageRange" width="170" minWidth="170" maxWidth="170" id="1OD-xa-ZwP">
+                                        <tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="页码范围">
+                                            <color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
+                                            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                                        </tableHeaderCell>
+                                        <textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" alignment="left" title="Text Cell" id="LCE-83-k0h">
+                                            <font key="font" metaFont="system"/>
+                                            <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
+                                            <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
+                                        </textFieldCell>
+                                        <prototypeCellViews>
+                                            <tableCellView id="nlT-SK-XE6" customClass="KMBatchTableCellView">
+                                                <rect key="frame" x="184" y="1" width="170" height="17"/>
+                                                <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                                            </tableCellView>
+                                        </prototypeCellViews>
+                                    </tableColumn>
+                                    <tableColumn identifier="size" width="80" minWidth="80" maxWidth="80" id="Jv9-CS-hrB">
+                                        <tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="大小">
+                                            <color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
+                                            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                                        </tableHeaderCell>
+                                        <textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" alignment="left" title="Text Cell" id="1c7-xc-JTb">
+                                            <font key="font" metaFont="system"/>
+                                            <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
+                                            <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
+                                        </textFieldCell>
+                                        <tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
+                                        <prototypeCellViews>
+                                            <tableCellView id="TSm-ys-xdB">
+                                                <rect key="frame" x="357" y="1" width="80" height="17"/>
+                                                <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                                            </tableCellView>
+                                        </prototypeCellViews>
+                                    </tableColumn>
+                                    <tableColumn identifier="status" width="78" minWidth="78" maxWidth="78" id="vhM-02-bDl">
+                                        <tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="状态">
+                                            <color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
+                                            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                                        </tableHeaderCell>
+                                        <textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" alignment="left" title="Text Cell" id="L91-kp-t6V">
+                                            <font key="font" metaFont="system"/>
+                                            <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
+                                            <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
+                                        </textFieldCell>
+                                        <tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
+                                        <prototypeCellViews>
+                                            <tableCellView id="sVm-ab-mJ4">
+                                                <rect key="frame" x="440" y="1" width="78" height="17"/>
+                                                <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                                                <subviews>
+                                                    <customView translatesAutoresizingMaskIntoConstraints="NO" id="QVD-OT-qtp">
+                                                        <rect key="frame" x="0.0" y="0.0" width="78" height="17"/>
+                                                    </customView>
+                                                </subviews>
+                                                <constraints>
+                                                    <constraint firstItem="QVD-OT-qtp" firstAttribute="top" secondItem="sVm-ab-mJ4" secondAttribute="top" id="DUg-iq-yMw"/>
+                                                    <constraint firstAttribute="trailing" secondItem="QVD-OT-qtp" secondAttribute="trailing" id="NLx-yZ-Jn2"/>
+                                                    <constraint firstItem="QVD-OT-qtp" firstAttribute="leading" secondItem="sVm-ab-mJ4" secondAttribute="leading" id="qjh-3z-1lQ"/>
+                                                    <constraint firstAttribute="bottom" secondItem="QVD-OT-qtp" secondAttribute="bottom" id="rqk-AF-SwC"/>
+                                                </constraints>
+                                            </tableCellView>
+                                        </prototypeCellViews>
+                                    </tableColumn>
+                                    <tableColumn identifier="dpi" width="85" minWidth="85" maxWidth="85" id="AKG-QZ-eeC">
+                                        <tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="DPI">
+                                            <color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
+                                            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                                        </tableHeaderCell>
+                                        <textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" alignment="left" title="Text Cell" id="9SD-ap-m6M">
+                                            <font key="font" metaFont="system"/>
+                                            <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
+                                            <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
+                                        </textFieldCell>
+                                        <tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
+                                        <prototypeCellViews>
+                                            <tableCellView id="tdZ-lu-oAc" customClass="KMBatchTableCellView">
+                                                <rect key="frame" x="521" y="1" width="85" height="17"/>
+                                                <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                                            </tableCellView>
+                                        </prototypeCellViews>
+                                    </tableColumn>
+                                    <tableColumn identifier="dimensions" width="100" minWidth="100" maxWidth="100" id="BoK-gf-WJ0">
+                                        <tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="center" title="Dimensions">
+                                            <color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
+                                            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                                        </tableHeaderCell>
+                                        <textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" alignment="left" title="Text Cell" id="w2B-Sb-stM">
+                                            <font key="font" metaFont="system"/>
+                                            <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
+                                            <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
+                                        </textFieldCell>
+                                        <tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
+                                        <prototypeCellViews>
+                                            <tableCellView id="nvT-ce-HBH" customClass="KMBatchTableCellView">
+                                                <rect key="frame" x="609" y="1" width="104" height="17"/>
+                                                <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                                            </tableCellView>
+                                        </prototypeCellViews>
+                                    </tableColumn>
+                                </tableColumns>
+                                <connections>
+                                    <outlet property="dataSource" destination="-2" id="R8X-VN-ypP"/>
+                                    <outlet property="delegate" destination="-2" id="Ie9-A1-7mB"/>
+                                    <outlet property="menu" destination="e6T-xh-hi0" id="ai6-yI-pn2"/>
+                                </connections>
+                            </tableView>
+                        </subviews>
+                    </clipView>
+                    <constraints>
+                        <constraint firstAttribute="height" relation="greaterThanOrEqual" constant="400" id="I8C-3u-ERA"/>
+                        <constraint firstAttribute="width" relation="greaterThanOrEqual" constant="670" id="LUW-2r-W1h"/>
+                    </constraints>
+                    <scroller key="horizontalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="YES" id="RBU-7C-fCt">
+                        <rect key="frame" x="1" y="403" width="768" height="15"/>
+                        <autoresizingMask key="autoresizingMask"/>
+                    </scroller>
+                    <scroller key="verticalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="NO" id="32b-Um-caF">
+                        <rect key="frame" x="224" y="17" width="15" height="102"/>
+                        <autoresizingMask key="autoresizingMask"/>
+                    </scroller>
+                    <tableHeaderView key="headerView" wantsLayer="YES" id="Mlr-rw-6rm" customClass="KMTableHeaderView">
+                        <rect key="frame" x="0.0" y="0.0" width="791" height="25"/>
+                        <autoresizingMask key="autoresizingMask"/>
+                    </tableHeaderView>
+                </scrollView>
+                <customView translatesAutoresizingMaskIntoConstraints="NO" id="G6v-if-4fr" customClass="KMBlankView">
+                    <rect key="frame" x="0.0" y="0.0" width="793" height="419"/>
+                    <subviews>
+                        <customView translatesAutoresizingMaskIntoConstraints="NO" id="9GJ-Lf-bRA">
+                            <rect key="frame" x="259" y="115" width="275" height="190"/>
+                            <subviews>
+                                <imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="aT2-4b-2xG">
+                                    <rect key="frame" x="68" y="50" width="140" height="140"/>
+                                    <constraints>
+                                        <constraint firstAttribute="height" constant="140" id="1br-FU-oB3"/>
+                                        <constraint firstAttribute="width" constant="140" id="Hmk-dG-xR7"/>
+                                    </constraints>
+                                    <imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="KMImageNameEmptyListNor" id="ZKZ-Y3-Edy"/>
+                                </imageView>
+                                <textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="6Hf-rN-RVl">
+                                    <rect key="frame" x="87" y="33" width="102" height="17"/>
+                                    <textFieldCell key="cell" title="Multiline Label" id="ssO-57-xns">
+                                        <font key="font" metaFont="systemSemibold" size="14"/>
+                                        <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
+                                        <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
+                                    </textFieldCell>
+                                </textField>
+                                <textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="tU6-rc-cEb">
+                                    <rect key="frame" x="87" y="8" width="102" height="17"/>
+                                    <textFieldCell key="cell" alignment="center" title="Multiline Label" id="7H4-19-ztf">
+                                        <font key="font" metaFont="system" size="14"/>
+                                        <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
+                                        <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
+                                    </textFieldCell>
+                                </textField>
+                            </subviews>
+                            <constraints>
+                                <constraint firstItem="tU6-rc-cEb" firstAttribute="top" secondItem="6Hf-rN-RVl" secondAttribute="bottom" constant="8" id="0lT-Bd-z3W"/>
+                                <constraint firstItem="aT2-4b-2xG" firstAttribute="top" secondItem="9GJ-Lf-bRA" secondAttribute="top" id="5f3-wl-J3a"/>
+                                <constraint firstAttribute="bottom" secondItem="tU6-rc-cEb" secondAttribute="bottom" constant="8" id="7jP-8F-Yc5"/>
+                                <constraint firstItem="6Hf-rN-RVl" firstAttribute="centerX" secondItem="9GJ-Lf-bRA" secondAttribute="centerX" id="KME-rV-lsa"/>
+                                <constraint firstItem="6Hf-rN-RVl" firstAttribute="top" secondItem="aT2-4b-2xG" secondAttribute="bottom" id="KWr-uj-plt"/>
+                                <constraint firstItem="tU6-rc-cEb" firstAttribute="centerX" secondItem="9GJ-Lf-bRA" secondAttribute="centerX" id="NWN-9j-uqf"/>
+                                <constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="tU6-rc-cEb" secondAttribute="trailing" id="d8X-Ae-XwQ"/>
+                                <constraint firstAttribute="width" constant="275" id="mYh-dT-Msb"/>
+                                <constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="6Hf-rN-RVl" secondAttribute="trailing" id="uRe-aH-NNZ"/>
+                                <constraint firstItem="aT2-4b-2xG" firstAttribute="centerX" secondItem="9GJ-Lf-bRA" secondAttribute="centerX" id="yFN-Mz-HoM"/>
+                            </constraints>
+                        </customView>
+                    </subviews>
+                    <constraints>
+                        <constraint firstItem="9GJ-Lf-bRA" firstAttribute="centerY" secondItem="G6v-if-4fr" secondAttribute="centerY" id="IdB-UE-f2e"/>
+                        <constraint firstItem="9GJ-Lf-bRA" firstAttribute="centerX" secondItem="G6v-if-4fr" secondAttribute="centerX" id="kJE-tO-m7r"/>
+                    </constraints>
+                    <connections>
+                        <outlet property="imageView" destination="aT2-4b-2xG" id="sQG-IE-mUv"/>
+                        <outlet property="secondTitleLabel" destination="tU6-rc-cEb" id="X2z-T7-8wA"/>
+                        <outlet property="titleLabel" destination="6Hf-rN-RVl" id="xFn-Ai-3qy"/>
+                    </connections>
+                </customView>
+            </subviews>
+            <constraints>
+                <constraint firstItem="cSo-1J-C87" firstAttribute="top" secondItem="yD5-qe-EWK" secondAttribute="bottom" id="1E9-OU-iH1"/>
+                <constraint firstItem="G6v-if-4fr" firstAttribute="top" secondItem="yD5-qe-EWK" secondAttribute="bottom" id="BMV-w3-Izh"/>
+                <constraint firstAttribute="bottom" secondItem="cSo-1J-C87" secondAttribute="bottom" id="C10-cX-Uaf"/>
+                <constraint firstAttribute="trailing" secondItem="G6v-if-4fr" secondAttribute="trailing" id="F0T-RF-MT0"/>
+                <constraint firstAttribute="trailing" secondItem="yD5-qe-EWK" secondAttribute="trailing" id="GiE-TH-mjf"/>
+                <constraint firstAttribute="trailing" secondItem="cSo-1J-C87" secondAttribute="trailing" id="LI9-Qj-pnl"/>
+                <constraint firstItem="G6v-if-4fr" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" id="byv-Of-n7n"/>
+                <constraint firstItem="yD5-qe-EWK" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" id="cjX-bE-yQ3"/>
+                <constraint firstItem="cSo-1J-C87" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" id="dk3-8n-swZ"/>
+                <constraint firstAttribute="bottom" secondItem="G6v-if-4fr" secondAttribute="bottom" id="qqx-eK-gkx"/>
+                <constraint firstItem="yD5-qe-EWK" firstAttribute="top" secondItem="Hz6-mo-xeY" secondAttribute="top" id="tcr-Fi-EVL"/>
+            </constraints>
+            <point key="canvasLocation" x="-73" y="561.5"/>
+        </customView>
+        <menu id="e6T-xh-hi0">
+            <items>
+                <menuItem title="Item 1" id="pcS-mu-f3A">
+                    <modifierMask key="keyEquivalentModifierMask"/>
+                    <connections>
+                        <action selector="menuItem_ShowInFinder:" target="-2" id="udx-PH-Uvd"/>
+                    </connections>
+                </menuItem>
+                <menuItem title="Item" id="1Q4-gp-Cqq">
+                    <modifierMask key="keyEquivalentModifierMask"/>
+                    <connections>
+                        <action selector="menuItem_Delete:" target="-2" id="VdT-cI-wgQ"/>
+                    </connections>
+                </menuItem>
+            </items>
+            <point key="canvasLocation" x="-240" y="137"/>
+        </menu>
+    </objects>
+    <resources>
+        <image name="KMImageNameEmptyListNor" width="200" height="200"/>
+        <image name="KMImageNameUXIconBtnAddHov" width="16" height="16"/>
+        <image name="KMImageNameUXIconBtnDeletHov" width="16" height="16"/>
+        <image name="KMImageNameUXIconBtnDeletNor" width="16" height="16"/>
+    </resources>
+</document>

+ 12 - 0
PDF Office/PDF Master/Class/Batch/WindowController/KMBatchOperateRightViewController.swift

@@ -0,0 +1,12 @@
+//
+//  KMBatchOperateRightViewController.swift
+//  PDF Master
+//
+//  Created by kdanmobile on 2023/10/26.
+//
+
+import Cocoa
+
+class KMBatchOperateRightViewController: NSViewController{
+    
+}

+ 22 - 0
PDF Office/PDF Master/Class/Batch/WindowController/KMBatchOperateRightViewController.xib

@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22154" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
+    <dependencies>
+        <deployment identifier="macosx"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22154"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <customObject id="-2" userLabel="File's Owner" customClass="KMBatchOperateRightViewController">
+            <connections>
+                <outlet property="view" destination="Hz6-mo-xeY" id="0bl-1N-x8E"/>
+            </connections>
+        </customObject>
+        <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
+        <customObject id="-3" userLabel="Application" customClass="NSObject"/>
+        <customView id="Hz6-mo-xeY">
+            <rect key="frame" x="0.0" y="0.0" width="480" height="272"/>
+            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
+            <point key="canvasLocation" x="4" y="120"/>
+        </customView>
+    </objects>
+</document>

+ 37 - 0
PDF Office/PDF Master/Class/Batch/WindowController/KMBatchOperateSplitViewController.swift

@@ -0,0 +1,37 @@
+//
+//  KMBatchOperateSplitViewController.swift
+//  PDF Master
+//
+//  Created by kdanmobile on 2023/10/26.
+//
+
+import Cocoa
+
+class KMBatchOperateSplitViewController: NSSplitViewController{
+    var leftFileListViewController: KMBatchOperateLeftViewController?
+    var rightPropertiesViewController: KMBatchOperateRightViewController?
+    
+    override func viewDidLoad() {
+        super.viewDidLoad()
+        self.leftFileListViewController = KMBatchOperateLeftViewController()
+        self.rightPropertiesViewController = KMBatchOperateRightViewController()
+        let item1 = NSSplitViewItem(viewController: self.leftFileListViewController!)
+        let item2 = NSSplitViewItem(viewController: self.rightPropertiesViewController!)
+        item1.minimumThickness = 400
+        item2.minimumThickness = 270
+        item2.maximumThickness = 270
+        self.addSplitViewItem(item1)
+        self.addSplitViewItem(item2)
+        self.addNewTrackingArea()
+    }
+    
+    func addNewTrackingArea() {
+        let trackingArea = NSTrackingArea(rect: self.view.frame, options: [.mouseEnteredAndExited, .inVisibleRect, .activeAlways, .mouseMoved], owner: self, userInfo: nil)
+        self.view.addTrackingArea(trackingArea)
+    }
+    
+//    func switchToOperateType(operateType: KMBatchOperationType, files: NSMutableArray) {
+//        self.leftFileListViewController.switchToOperateType(operateType: operateType, files: files)
+//        self.rightPropertiesViewController.switchToOperateType(operateType: operateType, files: files)
+//    }
+}

+ 32 - 0
PDF Office/PDF Master/Class/Batch/WindowController/KMBatchOperateSplitViewController.xib

@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22154" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
+    <dependencies>
+        <deployment identifier="macosx"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22154"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <customObject id="-2" userLabel="File's Owner" customClass="KMBatchOperateSplitViewController">
+            <connections>
+                <outlet property="view" destination="Hz6-mo-xeY" id="0bl-1N-x8E"/>
+            </connections>
+        </customObject>
+        <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
+        <customObject id="-3" userLabel="Application" customClass="NSObject"/>
+        <customView id="Hz6-mo-xeY">
+            <rect key="frame" x="0.0" y="0.0" width="345" height="77"/>
+            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
+            <point key="canvasLocation" x="54.5" y="21.5"/>
+        </customView>
+        <progressIndicator wantsLayer="YES" maxValue="100" indeterminate="YES" controlSize="small" style="spinning" id="cHA-ap-xhe">
+            <rect key="frame" x="0.0" y="0.0" width="16" height="16"/>
+            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
+            <point key="canvasLocation" x="-88" y="252"/>
+        </progressIndicator>
+        <progressIndicator wantsLayer="YES" maxValue="100" doubleValue="65" controlSize="small" style="spinning" id="4AN-28-vbF">
+            <rect key="frame" x="0.0" y="0.0" width="16" height="16"/>
+            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
+            <point key="canvasLocation" x="45" y="256"/>
+        </progressIndicator>
+    </objects>
+</document>

+ 53 - 0
PDF Office/PDF Master/Class/Batch/WindowController/KMBatchOperateWindowController.swift

@@ -0,0 +1,53 @@
+//
+//  KMBatchOperateWindowController.swift
+//  PDF Master
+//
+//  Created by kdanmobile on 2023/10/24.
+//
+
+import Cocoa
+import PDFKit
+
+class KMBatchOperateWindowController: KMBatchOperateBaseWindowController{
+
+   
+    static let sharedWindowController: KMBatchOperateWindowController = {
+        let wc = KMBatchOperateWindowController(windowNibName: "KMBatchOperateWindowController")
+        let actualWindow = wc.window as! KMBatchWindow
+        actualWindow.isBatch = true
+//        wc.switchToOperateType(operateType: .Convert, files: <#T##KMBatchOperateFile#>)
+        
+//        if IAPProductsManager.defaultManager().isAvailableAdvancedPDFToOffice {
+//            wc.switchToConvertType(.WordAdvance)
+//        } else {
+//            wc.switchToConvertType(.WordStandard)
+//        }
+        wc.updateViewColor()
+        
+        return wc
+    }()
+    
+    func switchToOperateType(operateType: KMBatchOperationType, files:KMBatchOperateFile) {
+        
+    }
+    
+    func updateViewColor() {
+        var color = NSColor(red: 0.149, green: 0.157, blue: 0.169, alpha: 1)
+        if KMAppearance.isDarkMode() {
+            color = NSColor(red: 0.149, green: 0.157, blue: 0.169, alpha: 1)
+        } else {
+            color = NSColor(red: 0.988, green: 0.992, blue: 1.0, alpha: 1)
+        }
+        if let themeView = self.window?.contentView?.superview {
+            for subView in themeView.subviews {
+                if NSStringFromClass(type(of: subView)) == "NSTitlebarContainerView" {
+                    subView.layer?.backgroundColor = color.cgColor 
+                    break
+                }
+            }
+        }
+    }
+}
+
+
+

+ 30 - 0
PDF Office/PDF Master/Class/Batch/WindowController/KMBatchOperateWindowController.xib

@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22154" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
+    <dependencies>
+        <deployment identifier="macosx"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22154"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <customObject id="-2" userLabel="File's Owner" customClass="KMBatchOperateWindowController">
+            <connections>
+                <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 title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="F0z-JX-Cv5" customClass="KMBatchWindow">
+            <windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
+            <rect key="contentRect" x="463" y="248" width="480" height="270"/>
+            <rect key="screenRect" x="0.0" y="0.0" width="2560" height="1415"/>
+            <view key="contentView" id="se5-gp-TjO">
+                <rect key="frame" x="0.0" y="0.0" width="480" height="270"/>
+                <autoresizingMask key="autoresizingMask"/>
+            </view>
+            <connections>
+                <outlet property="delegate" destination="-2" id="0bl-1N-AYu"/>
+            </connections>
+            <point key="canvasLocation" x="49" y="110"/>
+        </window>
+    </objects>
+</document>

+ 19 - 19
PDF Office/PDF Master/Class/Common/Category/NSWindow+KMExtension.swift

@@ -10,38 +10,38 @@ import Foundation
 private var _KMWindowPopOverKey = "KMWindowPopOverKey"
 private var _KMWindowPopOverSourcesRectKey = "KMWindowPopOverSourcesRectKey"
 extension NSWindow {
-    func setPopover(_ popover: NSPopover?) {
+    func km_setPopover(_ popover: NSPopover?) {
         objc_setAssociatedObject(self, &_KMWindowPopOverKey, popover, .OBJC_ASSOCIATION_RETAIN)
     }
     
-    func popover() -> NSPopover? {
+    func km_popover() -> NSPopover? {
         return objc_getAssociatedObject(self, &_KMWindowPopOverKey) as? NSPopover
     }
     
-    func setSourcesRect(_ sourcesRect: NSRect) {
+    func km_setSourcesRect(_ sourcesRect: NSRect) {
         objc_setAssociatedObject(self, &_KMWindowPopOverSourcesRectKey, NSValue(rect: sourcesRect), .OBJC_ASSOCIATION_RETAIN)
     }
     
-    func sourcesRect() -> NSRect {
+    func km_sourcesRect() -> NSRect {
         if let data = objc_getAssociatedObject(self, &_KMWindowPopOverSourcesRectKey) as? NSValue {
             return data.rectValue
         }
         return NSZeroRect
     }
     
-    open override func mouseMoved(with event: NSEvent) {
-        super.mouseMoved(with: event)
-        
-        let point = event.locationInWindow
-        if let data = event.window?.isKind(of: NSClassFromString("_NSPopoverWindow")!), data {
-            if (CGRectContainsPoint(self.sourcesRect(), point)) {
-                if self.popover() != nil {
-                    NotificationCenter.default.post(name: Notification.Name("KMPopOverClosedByWindowNotification"), object: self.popover()!)
-                    self.popover()?.close()
-                    self.setPopover(nil)
-                    self.setSourcesRect(CGRectNull)
-                }
-            }
-        }
-    }
+//    open override func mouseMoved(with event: NSEvent) {
+//        super.mouseMoved(with: event)
+//        
+//        let point = event.locationInWindow
+//        if let data = event.window?.isKind(of: NSClassFromString("_NSPopoverWindow")!), data {
+//            if (CGRectContainsPoint(self.sourcesRect(), point)) {
+//                if self.popover() != nil {
+//                    NotificationCenter.default.post(name: Notification.Name("KMPopOverClosedByWindowNotification"), object: self.popover()!)
+//                    self.popover()?.close()
+//                    self.setPopover(nil)
+//                    self.setSourcesRect(CGRectNull)
+//                }
+//            }
+//        }
+//    }
 }

+ 282 - 0
PDF Office/PDF Master/Class/Home/View/HomeContentView/History/Cell/KMHomeHistoryCollectionItem.swift

@@ -0,0 +1,282 @@
+//
+//  KMHomeHistoryCollectionItem.swift
+//  PDF Master
+//
+//  Created by lizhe on 2023/10/27.
+//
+
+import Cocoa
+
+
+typealias KMHomeHistoryCollectionItemShowPathAction = (_ view: KMHomeHistoryCollectionItem) -> Void
+typealias KMHomeHistoryCollectionItemRemovePathAction = (_ view: KMHomeHistoryCollectionItem) -> Void
+typealias KMHomeHistoryCollectionItemMouseMoveAction = (_ view: KMHomeHistoryCollectionItem, _ enter: Bool) -> Void
+typealias KMHomeHistoryCollectionItemMouseDobleClickAction = (_ view: KMHomeHistoryCollectionItem, _ url: URL) -> Void
+
+class KMHomeHistoryCollectionItem: NSCollectionViewItem {
+
+    @IBOutlet weak var contentBox: KMBox!
+    
+    @IBOutlet weak var horizontalView: NSView!
+    @IBOutlet weak var iconImageView: NSImageView!
+    @IBOutlet weak var horizontalTitleLabel: NSTextField!
+    @IBOutlet weak var sizeLabel: NSTextField!
+    @IBOutlet weak var pathLabel: NSTextField!
+    @IBOutlet weak var handleView: NSView!
+    @IBOutlet weak var showPathButton: KMButton!
+    @IBOutlet weak var removePathButton: KMButton!
+    @IBOutlet weak var timeLabel: NSTextField!
+    
+    //
+    @IBOutlet weak var verticalView: NSView!
+    @IBOutlet weak var verticalTitleLabel: NSTextField!
+    @IBOutlet weak var showImageView: NSImageView!
+    
+    var url: URL? {
+        didSet {
+            self.reloadData()
+        }
+    }
+    var showType: KMHomeHistoryListViewShowType = .horizontal {
+        didSet {
+            self.reloadData()
+        }
+    }
+
+    var showPathAction: KMHomeHistoryCollectionItemShowPathAction?
+    var removeAction: KMHomeHistoryCollectionItemRemovePathAction?
+    var mouseMoveAction: KMHomeHistoryCollectionItemMouseMoveAction?
+    var mouseDobleClickAction: KMHomeHistoryCollectionItemMouseDobleClickAction?
+    
+    
+    override func viewDidLoad() {
+        super.viewDidLoad()
+        // Do view setup here.
+        self.setup()
+    }
+
+    override func viewDidLayout() {
+        self.view.addTrackingRect(self.view.bounds, owner: self, userData: nil, assumeInside: false)
+    }
+    
+    func setup() {
+        self.view.wantsLayer = true;
+        self.view.layer?.cornerRadius = 4.0
+        
+        showPathButton.toolTip = NSLocalizedString("Show in Finder", comment: "")
+        removePathButton.toolTip = NSLocalizedString("Remove from Recents", comment: "")
+        handleView.isHidden = true;
+        
+        horizontalTitleLabel.textColor = KMAppearance.Layout.h0Color()
+        verticalTitleLabel.textColor = KMAppearance.Layout.h0Color()
+        pathLabel.textColor = KMAppearance.Layout.h1Color()
+        sizeLabel.textColor = KMAppearance.Layout.h1Color()
+        timeLabel.textColor = KMAppearance.Layout.h2Color()
+        
+        showPathButton.image = NSImage(named: "KMimageNameUXIconHomeOpenfinderNor")
+        showPathButton.alternateImage = NSImage(named:"KMimageNameUXIconHomeOpenfinderHov")
+        
+        removePathButton.image = NSImage(named: "KMImageNameUXIconHomeRemoveNor")
+        removePathButton.alternateImage = NSImage(named: "KMImageNameUXIconHomeRemoveHov")
+        
+        showPathButton.mouseMoveCallback = { [unowned self] mouseEntered in
+            if (mouseEntered) {
+                showPathButton.image = NSImage(named: "KMimageNameUXIconHomeOpenfinderHov")
+            } else {
+                showPathButton.image = NSImage(named: "KMimageNameUXIconHomeOpenfinderNor")
+            }
+        }
+        
+        removePathButton.mouseMoveCallback = { [unowned self] mouseEntered in
+            if (mouseEntered) {
+                removePathButton.image = NSImage(named: "KMImageNameUXIconHomeRemoveHov")
+            } else {
+                removePathButton.image = NSImage(named: "KMImageNameUXIconHomeRemoveNor")
+            }
+        }
+    }
+    
+    func reloadData() {
+        self.updateTypeData()
+        self.updateFilesData()
+    }
+    
+    override func rightMouseDown(with event: NSEvent) {
+        let point = self.view.convert(event.locationInWindow, from: nil)
+        let menu = NSMenu(title: "")
+        menu.addItem(NSMenuItem(title: NSLocalizedString("Show in Finder", comment: ""), action: #selector(showPathButtonAction), keyEquivalent: ""))
+        menu.addItem(NSMenuItem(title: NSLocalizedString("Remove from Recents", comment: ""), action: #selector(removePathButtonAction), keyEquivalent: ""))
+        menu.popUp(positioning: nil, at: point, in: self.view)
+    }
+}
+
+extension KMHomeHistoryCollectionItem {
+    func updateTypeData() {
+        switch self.showType {
+        case .horizontal:
+            self.verticalView.isHidden = true
+            self.horizontalView.isHidden = false
+        case .vertical:
+            self.verticalView.isHidden = false
+            self.horizontalView.isHidden = true
+        }
+    }
+    
+    func updateFilesData() -> Void {
+        guard let fileUrl = url else { return }
+        
+        let attrib = try? FileManager.default.attributesOfItem(atPath: fileUrl.path) as? Dictionary<FileAttributeKey , Any>
+        if attrib != nil {
+            let dateFormatter: DateFormatter = DateFormatter.init()
+            let fileDate: Date = attrib![FileAttributeKey(rawValue: "NSFileModificationDate")] as! Date
+            var fileTime: String = ""
+            if fileDate.isToday() {
+                dateFormatter.dateFormat = "HH:mm"
+            } else if self.isDateInCurrentWeek(fileDate) {
+                dateFormatter.dateFormat = "EEE, HH:mm"
+            } else {
+                dateFormatter.dateFormat = "MMM d, yyyy"
+            }
+            
+            let fileName = fileUrl.lastPathComponent
+//            let fileType = url.pathExtension.isEmpty ? "" : url.pathExtension
+            let fileType = ""
+            let sizeFloat: Float = attrib![FileAttributeKey(rawValue: "NSFileSize")] as? Float ?? 0.0
+            let fileSize = fileSizeString(sizeFloat).isEmpty ? "" : fileSizeString(sizeFloat)
+            let lastTime = dateFormatter.string(from: fileDate)
+            if fileDate.isToday() {
+                fileTime = String(format: "%@, %@", NSLocalizedString("Today", comment: ""), lastTime)
+            } else if isDateInCurrentWeek(fileDate) {
+                fileTime = lastTime
+            } else {
+                fileTime = lastTime
+            }
+
+            let paragraphStyle = NSMutableParagraphStyle()
+            paragraphStyle.lineSpacing = 22.0
+            horizontalTitleLabel.stringValue = fileName
+            verticalTitleLabel.stringValue = fileName
+            
+            //path
+            let array = fileUrl.path
+                .deletingLastPathComponent
+                .components(separatedBy: "/")
+            let string = NSMutableString()
+
+            if array.count > 4 {
+                string.append(".../")
+                string.append(array[array.count - 3])
+                string.append("/")
+                string.append(array[array.count - 2])
+                string.append("/")
+                string.append(array[array.count - 1])
+            } else {
+                string.setString(fileUrl.path.deletingLastPathComponent)
+            }
+
+            pathLabel.stringValue = string as String
+            
+    //        documentName.attributedStringValue = NSAttributedString(string: fileName, attributes: [NSAttributedString.Key.paragraphStyle: paragraphStyle])
+//            documentType.attributedStringValue = NSAttributedString(string: fileType, attributes: [NSAttributedString.Key.paragraphStyle: paragraphStyle])
+            sizeLabel.attributedStringValue = NSAttributedString(string: fileSize, attributes: [NSAttributedString.Key.paragraphStyle: paragraphStyle])
+            timeLabel.attributedStringValue = NSAttributedString(string: fileTime, attributes: [NSAttributedString.Key.paragraphStyle: paragraphStyle])
+//            mainBox.toolTip = fileName
+//            
+//            if selectUrls.contains(fileUrl) {
+//                isSelect = true
+//                mainBox.fillColor = NSColor.km_init(hex: "#CED0D4", alpha: 0.6)
+//                mainBox.borderWidth = 1.0
+//                mainBox.borderColor = NSColor.km_init(hex: "#CED0D4")
+//                mainBox.cornerRadius = 4.0
+//            } else {
+//                isSelect = false
+//                mainBox.fillColor = .clear
+//                mainBox.borderWidth = 0.0
+//                mainBox.cornerRadius = 0.0
+//            }
+//            documentName.backgroundColor = .clear
+//            documentName.textColor = NSColor.km_init(hex: "#252629")
+//            documentName.font = NSFont(name: "SFProText-Regular", size: 14)
+//            documentType.textColor = NSColor.km_init(hex: "#94989C")
+//            documentSize.textColor = NSColor.km_init(hex: "#94989C")
+//            documentName.backgroundColor = .clear
+//            lastModificationTime.textColor = NSColor.km_init(hex: "#94989C")
+//            lastModificationTime.backgroundColor = .clear
+//            moreButton.image = NSImage(named: "KMHomeMoreTools")
+            let image: NSImage = NSImage.previewForFile(path: fileUrl, ofSize: self.view.bounds.size, asIcon: true) ?? NSImage()
+            showImageView.image = image
+        }
+    }
+    
+    func fileSizeString(_ fSize: Float) -> String {
+        let fileSize = fSize / 1024
+        let size = fileSize >= 1024 ? (fileSize < 1048576 ? fileSize/1024 : fileSize/1048576.0) : fileSize
+        let unit = fileSize >= 1024 ? (fileSize < 1048576 ? "M" : "G") : "K"
+        return String(format: "%0.1f %@", size, unit)
+    }
+    
+    func isSameWeek (withDate date: Date) -> Bool {
+        let currentWeekOfYear = getWeekOfYear(date: Date.init())
+        let targetWeekOfYear = getWeekOfYear(date: date)
+        if targetWeekOfYear == currentWeekOfYear {
+            return false
+        } else {
+            return true
+        }
+    }
+    
+    func isDateInCurrentWeek(_ date: Date) -> Bool {
+        let calendar = Calendar.current
+        // 获取当前日期的星期几
+        let weekday = calendar.component(.weekday, from: Date())
+        // 获取一周的第一天(周日)的日期
+        let firstDayOfWeek = calendar.date(byAdding: .day, value: -weekday, to: Date())!
+        // 获取一周的最后一天(下周的第一天)的日期
+        let lastDayOfWeek = calendar.date(byAdding: .day, value: 7, to: firstDayOfWeek)!
+        // 判断日期是否在当前周的范围内
+        return date > firstDayOfWeek && date < lastDayOfWeek
+    }
+     
+    func getWeekOfYear(date: Date) -> Int {
+        let components = Calendar.current.dateComponents([Calendar.Component.weekOfYear], from: date)
+        return components.weekOfYear ?? 0
+    }
+}
+                     
+extension KMHomeHistoryCollectionItem {
+    @objc @IBAction func showPathButtonAction(_ sender: Any) {
+        guard let callBack = showPathAction else { return }
+        
+        callBack(self)
+    }
+    
+    @objc @IBAction func removePathButtonAction(_ sender: Any) {
+        guard let callBack = removeAction else { return }
+        
+        callBack(self)
+    }
+}
+
+extension KMHomeHistoryCollectionItem {
+    override func mouseEntered(with event: NSEvent) {
+        guard let callBack = mouseMoveAction else { return }
+        
+        callBack(self, true)
+    }
+    
+    override func mouseExited(with event: NSEvent) {
+        guard let callBack = mouseMoveAction else { return }
+        
+        callBack(self, false)
+    }
+    
+    override func mouseDown(with event: NSEvent) {
+        if event.clickCount == 2 {
+            // 处理双击操作
+            guard let callBack = mouseDobleClickAction else { return }
+            callBack(self, self.url!)
+        } else {
+            super.mouseDown(with: event)
+        }
+    }
+}

+ 197 - 0
PDF Office/PDF Master/Class/Home/View/HomeContentView/History/Cell/KMHomeHistoryCollectionItem.xib

@@ -0,0 +1,197 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22155" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
+    <dependencies>
+        <deployment identifier="macosx"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22155"/>
+        <capability name="Named colors" minToolsVersion="9.0"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <customObject id="-2" userLabel="File's Owner" customClass="KMHomeHistoryCollectionItem" customModule="PDF_Master" customModuleProvider="target">
+            <connections>
+                <outlet property="contentBox" destination="gvc-kj-Yeo" id="b05-Yu-1sn"/>
+                <outlet property="handleView" destination="seD-7E-dp2" id="AlN-MY-rLZ"/>
+                <outlet property="horizontalTitleLabel" destination="ddV-aD-Yah" id="xU2-pL-hSt"/>
+                <outlet property="horizontalView" destination="7sk-7M-lCI" id="EpH-GN-k8x"/>
+                <outlet property="iconImageView" destination="0Mh-Sf-3a2" id="uoB-VI-qbq"/>
+                <outlet property="pathLabel" destination="Der-Qi-aoW" id="PuH-jA-osJ"/>
+                <outlet property="removePathButton" destination="TFk-gH-WAn" id="kQT-uV-5d8"/>
+                <outlet property="showImageView" destination="dbA-sb-Xfk" id="GKb-W4-AfQ"/>
+                <outlet property="showPathButton" destination="HSD-uO-oml" id="QsF-AA-vhr"/>
+                <outlet property="sizeLabel" destination="wId-sm-qtO" id="Iod-iK-eyQ"/>
+                <outlet property="timeLabel" destination="WUP-W3-okM" id="zH1-iA-fty"/>
+                <outlet property="verticalTitleLabel" destination="mZL-RM-KzQ" id="llq-zu-fuu"/>
+                <outlet property="verticalView" destination="oc7-Ul-iDs" id="RTc-R1-XAN"/>
+                <outlet property="view" destination="Hz6-mo-xeY" id="0bl-1N-x8E"/>
+            </connections>
+        </customObject>
+        <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
+        <customObject id="-3" userLabel="Application" customClass="NSObject"/>
+        <customView id="Hz6-mo-xeY">
+            <rect key="frame" x="0.0" y="0.0" width="940" height="229"/>
+            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
+            <subviews>
+                <box boxType="custom" borderWidth="0.0" translatesAutoresizingMaskIntoConstraints="NO" id="gvc-kj-Yeo" customClass="KMBox" customModule="PDF_Master" customModuleProvider="target">
+                    <rect key="frame" x="16" y="16" width="908" height="197"/>
+                    <view key="contentView" id="KgU-86-iwk">
+                        <rect key="frame" x="0.0" y="0.0" width="908" height="197"/>
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                    </view>
+                </box>
+                <customView translatesAutoresizingMaskIntoConstraints="NO" id="oc7-Ul-iDs">
+                    <rect key="frame" x="0.0" y="0.0" width="940" height="229"/>
+                    <subviews>
+                        <imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="dbA-sb-Xfk">
+                            <rect key="frame" x="0.0" y="40" width="940" height="189"/>
+                            <imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" id="bdV-B5-oJm"/>
+                        </imageView>
+                        <textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="mZL-RM-KzQ">
+                            <rect key="frame" x="14" y="16" width="912" height="16"/>
+                            <textFieldCell key="cell" alignment="center" id="Nso-Kd-6li">
+                                <font key="font" metaFont="system"/>
+                                <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
+                                <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
+                            </textFieldCell>
+                        </textField>
+                    </subviews>
+                    <constraints>
+                        <constraint firstItem="mZL-RM-KzQ" firstAttribute="leading" secondItem="oc7-Ul-iDs" secondAttribute="leading" constant="16" id="7fg-gh-Ipe"/>
+                        <constraint firstAttribute="trailing" secondItem="dbA-sb-Xfk" secondAttribute="trailing" id="HWM-9v-2Rd"/>
+                        <constraint firstItem="dbA-sb-Xfk" firstAttribute="top" secondItem="oc7-Ul-iDs" secondAttribute="top" id="Sv1-jj-Bfg"/>
+                        <constraint firstItem="mZL-RM-KzQ" firstAttribute="centerX" secondItem="oc7-Ul-iDs" secondAttribute="centerX" id="U8s-bU-U33"/>
+                        <constraint firstAttribute="trailing" secondItem="mZL-RM-KzQ" secondAttribute="trailing" constant="16" id="hy9-aF-hPG"/>
+                        <constraint firstItem="mZL-RM-KzQ" firstAttribute="top" secondItem="dbA-sb-Xfk" secondAttribute="bottom" constant="8" id="jfz-kY-uGx"/>
+                        <constraint firstAttribute="bottom" secondItem="dbA-sb-Xfk" secondAttribute="bottom" constant="40" id="lD8-TX-JUg"/>
+                        <constraint firstItem="dbA-sb-Xfk" firstAttribute="leading" secondItem="oc7-Ul-iDs" secondAttribute="leading" id="xP3-Qp-EQE"/>
+                    </constraints>
+                </customView>
+                <customView translatesAutoresizingMaskIntoConstraints="NO" id="7sk-7M-lCI">
+                    <rect key="frame" x="0.0" y="0.0" width="940" height="229"/>
+                    <subviews>
+                        <imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="0Mh-Sf-3a2">
+                            <rect key="frame" x="16" y="99" width="32" height="32"/>
+                            <constraints>
+                                <constraint firstAttribute="width" constant="32" id="Hwu-re-UBO"/>
+                                <constraint firstAttribute="height" constant="32" id="Wiy-fe-sgF"/>
+                            </constraints>
+                            <imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyUpOrDown" image="KMImageNameUXIconPropertybarFilePdf" id="eLO-Yq-M3q"/>
+                        </imageView>
+                        <textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="ddV-aD-Yah">
+                            <rect key="frame" x="54" y="114" width="40" height="17"/>
+                            <textFieldCell key="cell" lineBreakMode="truncatingMiddle" alignment="left" title="Label" id="AYN-Fy-tcy">
+                                <font key="font" metaFont="system" size="14"/>
+                                <color key="textColor" name="KMGray6Color"/>
+                                <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
+                            </textFieldCell>
+                        </textField>
+                        <textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="WUP-W3-okM">
+                            <rect key="frame" x="817" y="107" width="109" height="15"/>
+                            <textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="2020-08-01 12:39" id="PEF-8C-QEE">
+                                <font key="font" metaFont="cellTitle"/>
+                                <color key="textColor" name="KMGray5Color"/>
+                                <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
+                            </textFieldCell>
+                        </textField>
+                        <textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Der-Qi-aoW">
+                            <rect key="frame" x="93" y="99" width="35" height="15"/>
+                            <textFieldCell key="cell" lineBreakMode="clipping" title="Label" id="2AB-HF-4Ox">
+                                <font key="font" metaFont="cellTitle"/>
+                                <color key="textColor" red="0.39607843139999999" green="0.41176470590000003" blue="0.43921568630000002" alpha="1" colorSpace="calibratedRGB"/>
+                                <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
+                            </textFieldCell>
+                        </textField>
+                        <textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="wId-sm-qtO">
+                            <rect key="frame" x="54" y="99" width="35" height="15"/>
+                            <textFieldCell key="cell" lineBreakMode="clipping" title="Label" id="Pbe-3u-seE">
+                                <font key="font" metaFont="cellTitle"/>
+                                <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
+                                <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
+                            </textFieldCell>
+                        </textField>
+                        <customView translatesAutoresizingMaskIntoConstraints="NO" id="seD-7E-dp2">
+                            <rect key="frame" x="695" y="95" width="100" height="40"/>
+                            <subviews>
+                                <button translatesAutoresizingMaskIntoConstraints="NO" id="HSD-uO-oml" customClass="KMButton" customModule="PDF_Master" customModuleProvider="target">
+                                    <rect key="frame" x="20" y="10" width="20" height="20"/>
+                                    <buttonCell key="cell" type="square" bezelStyle="shadowlessSquare" image="KMimageNameUXIconHomeOpenfinderNor" imagePosition="only" alignment="center" imageScaling="proportionallyUpOrDown" inset="2" id="3fQ-E6-5PX">
+                                        <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
+                                        <font key="font" metaFont="system"/>
+                                    </buttonCell>
+                                    <constraints>
+                                        <constraint firstAttribute="width" constant="20" id="80L-12-LrA"/>
+                                        <constraint firstAttribute="height" constant="20" id="eOT-Uy-uIz"/>
+                                    </constraints>
+                                    <connections>
+                                        <action selector="showPathButtonAction:" target="-2" id="DOu-Nk-4jV"/>
+                                    </connections>
+                                </button>
+                                <button translatesAutoresizingMaskIntoConstraints="NO" id="TFk-gH-WAn" customClass="KMButton" customModule="PDF_Master" customModuleProvider="target">
+                                    <rect key="frame" x="60" y="10" width="20" height="20"/>
+                                    <buttonCell key="cell" type="square" bezelStyle="shadowlessSquare" image="KMImageNameUXIconHomeRemoveNor" imagePosition="overlaps" alignment="center" imageScaling="proportionallyUpOrDown" inset="2" id="4WS-yy-x9P">
+                                        <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
+                                        <font key="font" metaFont="system"/>
+                                    </buttonCell>
+                                    <constraints>
+                                        <constraint firstAttribute="width" constant="20" id="3x6-0t-W2G"/>
+                                        <constraint firstAttribute="height" constant="20" id="Afa-dM-24q"/>
+                                    </constraints>
+                                    <connections>
+                                        <action selector="removePathButtonAction:" target="-2" id="iN4-wh-nGW"/>
+                                    </connections>
+                                </button>
+                            </subviews>
+                            <constraints>
+                                <constraint firstItem="TFk-gH-WAn" firstAttribute="centerY" secondItem="seD-7E-dp2" secondAttribute="centerY" id="1WN-HU-Tbr"/>
+                                <constraint firstItem="HSD-uO-oml" firstAttribute="centerY" secondItem="seD-7E-dp2" secondAttribute="centerY" id="852-42-Het"/>
+                                <constraint firstItem="TFk-gH-WAn" firstAttribute="centerX" secondItem="seD-7E-dp2" secondAttribute="centerX" constant="20" id="Hl6-6Q-t6F"/>
+                                <constraint firstAttribute="height" constant="40" id="bWV-l7-iOY"/>
+                                <constraint firstItem="HSD-uO-oml" firstAttribute="centerX" secondItem="seD-7E-dp2" secondAttribute="centerX" constant="-20" id="eR0-13-eod"/>
+                                <constraint firstAttribute="width" constant="100" id="mmj-xq-JlI"/>
+                            </constraints>
+                        </customView>
+                    </subviews>
+                    <constraints>
+                        <constraint firstItem="Der-Qi-aoW" firstAttribute="leading" secondItem="wId-sm-qtO" secondAttribute="trailing" constant="8" id="3Xx-1N-jxL"/>
+                        <constraint firstItem="WUP-W3-okM" firstAttribute="centerY" secondItem="0Mh-Sf-3a2" secondAttribute="centerY" id="Ek8-FQ-sYA"/>
+                        <constraint firstItem="seD-7E-dp2" firstAttribute="centerY" secondItem="7sk-7M-lCI" secondAttribute="centerY" id="LQm-ap-hCm"/>
+                        <constraint firstItem="0Mh-Sf-3a2" firstAttribute="leading" secondItem="7sk-7M-lCI" secondAttribute="leading" constant="16" id="NLG-Aa-oZ0"/>
+                        <constraint firstItem="wId-sm-qtO" firstAttribute="leading" secondItem="0Mh-Sf-3a2" secondAttribute="trailing" constant="8" id="P6W-HV-B1N"/>
+                        <constraint firstItem="Der-Qi-aoW" firstAttribute="centerY" secondItem="wId-sm-qtO" secondAttribute="centerY" id="WhF-tw-G1U"/>
+                        <constraint firstItem="ddV-aD-Yah" firstAttribute="leading" secondItem="0Mh-Sf-3a2" secondAttribute="trailing" constant="8" id="b6a-Mv-bbk"/>
+                        <constraint firstAttribute="trailing" secondItem="WUP-W3-okM" secondAttribute="trailing" constant="16" id="ffA-da-LAi"/>
+                        <constraint firstItem="0Mh-Sf-3a2" firstAttribute="centerY" secondItem="7sk-7M-lCI" secondAttribute="centerY" id="hSv-e3-grz"/>
+                        <constraint firstItem="wId-sm-qtO" firstAttribute="bottom" secondItem="0Mh-Sf-3a2" secondAttribute="bottom" id="k8G-xK-sUx"/>
+                        <constraint firstItem="WUP-W3-okM" firstAttribute="leading" secondItem="seD-7E-dp2" secondAttribute="trailing" constant="24" id="w23-gi-JHt"/>
+                        <constraint firstItem="ddV-aD-Yah" firstAttribute="top" secondItem="0Mh-Sf-3a2" secondAttribute="top" id="yC7-2n-C7a"/>
+                    </constraints>
+                </customView>
+            </subviews>
+            <constraints>
+                <constraint firstAttribute="bottom" secondItem="7sk-7M-lCI" secondAttribute="bottom" id="1xu-Eu-Gpw"/>
+                <constraint firstItem="oc7-Ul-iDs" firstAttribute="top" secondItem="Hz6-mo-xeY" secondAttribute="top" id="3mN-ui-HOd"/>
+                <constraint firstAttribute="trailing" secondItem="gvc-kj-Yeo" secondAttribute="trailing" constant="16" id="MQ9-mG-dvf"/>
+                <constraint firstItem="gvc-kj-Yeo" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="16" id="QNY-R7-aCn"/>
+                <constraint firstAttribute="trailing" secondItem="oc7-Ul-iDs" secondAttribute="trailing" id="ZvQ-Yb-83f"/>
+                <constraint firstItem="gvc-kj-Yeo" firstAttribute="top" secondItem="Hz6-mo-xeY" secondAttribute="top" constant="16" id="c3K-iJ-GsK"/>
+                <constraint firstAttribute="trailing" secondItem="7sk-7M-lCI" secondAttribute="trailing" id="cqh-JA-THy"/>
+                <constraint firstItem="7sk-7M-lCI" firstAttribute="top" secondItem="Hz6-mo-xeY" secondAttribute="top" id="e4i-JT-Slb"/>
+                <constraint firstItem="7sk-7M-lCI" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" id="ooa-BQ-VTr"/>
+                <constraint firstAttribute="bottom" secondItem="gvc-kj-Yeo" secondAttribute="bottom" constant="16" id="pQn-cm-GgU"/>
+                <constraint firstAttribute="bottom" secondItem="oc7-Ul-iDs" secondAttribute="bottom" id="pjN-VI-SK1"/>
+                <constraint firstItem="oc7-Ul-iDs" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" id="tTF-yE-4ER"/>
+            </constraints>
+            <point key="canvasLocation" x="-77" y="122.5"/>
+        </customView>
+    </objects>
+    <resources>
+        <image name="KMImageNameUXIconHomeRemoveNor" width="20" height="20"/>
+        <image name="KMImageNameUXIconPropertybarFilePdf" width="32" height="33"/>
+        <image name="KMimageNameUXIconHomeOpenfinderNor" width="20" height="20"/>
+        <namedColor name="KMGray5Color">
+            <color red="0.32899999618530273" green="0.32400000095367432" blue="0.4779999852180481" alpha="0.33000001311302185" colorSpace="custom" customColorSpace="sRGB"/>
+        </namedColor>
+        <namedColor name="KMGray6Color">
+            <color red="0.396078431372549" green="0.41176470588235292" blue="0.4392156862745098" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+        </namedColor>
+    </resources>
+</document>

+ 131 - 0
PDF Office/PDF Master/Class/Home/View/HomeContentView/History/KMHomeHistoryListView.swift

@@ -0,0 +1,131 @@
+//
+//  KMHomeHistoryListView.swift
+//  PDF Master
+//
+//  Created by lizhe on 2023/10/27.
+//
+
+import Cocoa
+
+
+enum KMHomeHistoryListViewShowType: Int {
+    case horizontal = 0 //横
+    case vertical //纵
+}
+
+typealias KMHomeHistoryListViewItemDidSelect = (_ view: KMHomeHistoryListView, _ url: URL) -> Void
+class KMHomeHistoryListView: KMBaseXibView {
+    @IBOutlet weak var collectionView: NSCollectionView!
+    
+    var didSelect: KMHomeHistoryListViewItemDidSelect?
+    var data:[URL] = []
+    var showType:KMHomeHistoryListViewShowType = .horizontal {
+        didSet {
+            self.collectionView.reloadData()
+        }
+    }
+    
+    
+    override func draw(_ dirtyRect: NSRect) {
+        if dirtyRect.size.width != self.bounds.size.width {
+            let indexPathsToReload = Set([IndexPath(item: 0, section: 0)/*, IndexPath(item: 1, section: 0)*/]) // 要刷新的单元项的索引路径
+            collectionView.reloadItems(at: indexPathsToReload)
+        }
+        super.draw(dirtyRect)
+
+    }
+    
+    override func setup() {
+        //设置代理
+        self.collectionView.delegate = self
+        self.collectionView.dataSource = self
+        //是否可选中
+        self.collectionView.isSelectable = true
+        //注册cell
+        self.collectionView.register(KMHomeHistoryCollectionItem.self, forItemWithIdentifier: NSUserInterfaceItemIdentifier(rawValue: "KMHomeHistoryCollectionItem"))
+        
+//        self.backgroundColor(KMAppearance.Layout.l0Color())
+    }
+    
+    override func reloadData() {
+        self.data.removeAll()
+        for url in NSDocumentController.shared.recentDocumentURLs {
+            if FileManager.default.fileExists(atPath: url.path) {
+                self.data.append(url)
+            }
+        }
+
+        let fileNumber = KMPreferenceManager.shared.getData(forKey: KMPreference.documentMaximunDisplayNumberKey) as? Int ?? 10
+        if fileNumber <= data.count {
+            let arr1 = data.prefix(fileNumber)
+            self.data = Array(arr1)
+        }
+        
+        self.collectionView.reloadData()
+    }
+}
+
+extension KMHomeHistoryListView: NSCollectionViewDelegate {
+    //当item被选中
+    public func collectionView(_ collectionView: NSCollectionView, didSelectItemsAt indexPaths: Set<IndexPath>) {
+        print("点击")
+        let view = collectionView.item(at: indexPaths.first!) as! KMHomeHistoryCollectionItem
+        
+//        let content = view.model
+        
+//        guard let callBack = didSelect else { return }
+//        
+//        content?.index = indexPaths.first!.item
+//        callBack(self, content!)
+    }
+    
+   //当item取消选中
+    public func collectionView(_ collectionView: NSCollectionView, didDeselectItemsAt indexPaths: Set<IndexPath>) {
+        _ = collectionView.item(at: indexPaths.first!) as! KMHomeHistoryCollectionItem
+    }
+}
+
+extension KMHomeHistoryListView: NSCollectionViewDataSource {
+    public func numberOfSections(in collectionView: NSCollectionView) -> Int {
+        return 1
+    }
+    
+    public func collectionView(_ collectionView: NSCollectionView, numberOfItemsInSection section: Int) -> Int {
+        return self.data.count
+    }
+    
+    //返回对应的item自定义个体
+    public func collectionView(_ collectionView: NSCollectionView, itemForRepresentedObjectAt indexPath: IndexPath) -> NSCollectionViewItem {
+        let view = collectionView.makeItem(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "KMHomeHistoryCollectionItem"), for: indexPath) as! KMHomeHistoryCollectionItem
+        view.showType = self.showType
+        if self.data.count > indexPath.item {
+            view.url = self.data[indexPath.item]
+        }
+        
+        view.mouseDobleClickAction = {[unowned self] view, url in
+            guard let callBack = didSelect else { return }
+            
+            callBack(self, url)
+        }
+        return view
+    }
+}
+
+extension KMHomeHistoryListView: NSCollectionViewDelegateFlowLayout {
+    
+    public func collectionView(_ collectionView: NSCollectionView, layout collectionViewLayout: NSCollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> NSSize {
+        if showType == .horizontal {
+            return NSSize(width: self.contentView.bounds.width, height: 64)
+        } else {
+            return NSSize(width: 136, height: 214)
+        }
+    }
+    
+    public func collectionView(_ collectionView: NSCollectionView, layout collectionViewLayout: NSCollectionViewLayout, insetForSectionAt section: Int) -> NSEdgeInsets {
+        if showType == .horizontal {
+            return NSEdgeInsets(top: 10, left: 0, bottom: 10, right: 0)
+        } else {
+            return NSEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
+        }
+    }
+}

+ 56 - 0
PDF Office/PDF Master/Class/Home/View/HomeContentView/History/KMHomeHistoryListView.xib

@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22155" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
+    <dependencies>
+        <deployment identifier="macosx"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22155"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <customObject id="-2" userLabel="File's Owner" customClass="KMHomeHistoryListView" customModule="PDF_Master" customModuleProvider="target">
+            <connections>
+                <outlet property="collectionView" destination="2YZ-04-yn6" id="VrD-Wg-TzA"/>
+            </connections>
+        </customObject>
+        <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
+        <customObject id="-3" userLabel="Application" customClass="NSObject"/>
+        <customView id="c22-O7-iKe">
+            <rect key="frame" x="0.0" y="0.0" width="480" height="272"/>
+            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
+            <subviews>
+                <scrollView wantsLayer="YES" borderType="none" autohidesScrollers="YES" horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" hasHorizontalScroller="NO" hasVerticalScroller="NO" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="rQW-DN-cJx">
+                    <rect key="frame" x="0.0" y="0.0" width="480" height="272"/>
+                    <clipView key="contentView" drawsBackground="NO" id="hpl-mt-Tmp">
+                        <rect key="frame" x="0.0" y="0.0" width="480" height="272"/>
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                        <subviews>
+                            <collectionView id="2YZ-04-yn6">
+                                <rect key="frame" x="0.0" y="0.0" width="480" height="158"/>
+                                <autoresizingMask key="autoresizingMask" widthSizable="YES"/>
+                                <collectionViewFlowLayout key="collectionViewLayout" minimumInteritemSpacing="10" minimumLineSpacing="10" id="nLD-SM-dF9">
+                                    <size key="itemSize" width="50" height="50"/>
+                                </collectionViewFlowLayout>
+                                <color key="primaryBackgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
+                            </collectionView>
+                        </subviews>
+                        <color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
+                    </clipView>
+                    <scroller key="horizontalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="YES" id="nvA-t1-N9p">
+                        <rect key="frame" x="-100" y="-100" width="233" height="15"/>
+                        <autoresizingMask key="autoresizingMask"/>
+                    </scroller>
+                    <scroller key="verticalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" doubleValue="1" horizontal="NO" id="xme-h7-eh8" customClass="KMToolSetScroller" customModule="PDF_Master" customModuleProvider="target">
+                        <rect key="frame" x="-100" y="-100" width="15" height="143"/>
+                        <autoresizingMask key="autoresizingMask"/>
+                    </scroller>
+                </scrollView>
+            </subviews>
+            <constraints>
+                <constraint firstItem="rQW-DN-cJx" firstAttribute="top" secondItem="c22-O7-iKe" secondAttribute="top" id="0qW-dq-SU7"/>
+                <constraint firstAttribute="trailing" secondItem="rQW-DN-cJx" secondAttribute="trailing" id="5pe-5b-eAE"/>
+                <constraint firstAttribute="bottom" secondItem="rQW-DN-cJx" secondAttribute="bottom" id="bOt-kl-Tq1"/>
+                <constraint firstItem="rQW-DN-cJx" firstAttribute="leading" secondItem="c22-O7-iKe" secondAttribute="leading" id="d0j-Zg-yIC"/>
+            </constraints>
+            <point key="canvasLocation" x="-146" y="54"/>
+        </customView>
+    </objects>
+</document>

+ 75 - 0
PDF Office/PDF Master/Class/Home/View/HomeContentView/KMHomeContentView.swift

@@ -0,0 +1,75 @@
+//
+//  KMHomeContentView.swift
+//  PDF Master
+//
+//  Created by lizhe on 2023/10/27.
+//
+
+import Cocoa
+
+typealias KMHomeContentViewHistoryDidSelect = (_ view: KMHomeContentView, _ url: URL) -> Void
+
+class KMHomeContentView: KMBaseXibView {
+    @IBOutlet weak var qucikToolsLabel: NSTextField!
+    @IBOutlet weak var qucikToolsView: KMQucikToolsView!
+    @IBOutlet weak var leftButton: NSButton!
+    @IBOutlet weak var rightButton: NSButton!
+    @IBOutlet weak var moreButton: KMButton!
+    
+    
+    @IBOutlet weak var recentlyLabel: NSTextField!
+    @IBOutlet weak var historyListView: KMHomeHistoryListView!
+    @IBOutlet weak var horizontalButton: NSButton!
+    @IBOutlet weak var verticalButton: NSButton!
+    @IBOutlet weak var cleanButton: KMButton!
+    
+    var historyDidSelect: KMHomeContentViewHistoryDidSelect?
+    
+    override func draw(_ dirtyRect: NSRect) {
+        super.draw(dirtyRect)
+
+        // Drawing code here.
+        self.setup()
+    }
+    
+    override func setup() {
+        self.historyListViewSetup()
+    }
+}
+
+extension KMHomeContentView {
+    @IBAction func leftButtonAction(_ sender: Any) {
+        
+    }
+    
+    @IBAction func rightButtonAction(_ sender: Any) {
+        
+    }
+    
+    @IBAction func moreButtonAction(_ sender: Any) {
+        
+    }
+}
+
+extension KMHomeContentView {
+    func historyListViewSetup() {
+        self.historyListView.didSelect = { [unowned self] view, url in
+            guard let callBack = historyDidSelect else { return }
+            
+            callBack(self, url)
+        }
+        
+    }
+    
+    @IBAction func horizontalButtonAction(_ sender: Any) {
+        self.historyListView.showType = .horizontal
+    }
+    
+    @IBAction func verticalButtonAction(_ sender: Any) {
+        self.historyListView.showType = .vertical
+    }
+    
+    @IBAction func cleanButtonAction(_ sender: Any) {
+        
+    }
+}

+ 252 - 0
PDF Office/PDF Master/Class/Home/View/HomeContentView/KMHomeContentView.xib

@@ -0,0 +1,252 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22155" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
+    <dependencies>
+        <deployment identifier="macosx"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22155"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <customObject id="-2" userLabel="File's Owner" customClass="KMHomeContentView" customModule="PDF_Master" customModuleProvider="target">
+            <connections>
+                <outlet property="cleanButton" destination="2pe-eQ-jim" id="NzZ-si-Lah"/>
+                <outlet property="historyListView" destination="wMw-AS-5yG" id="HHc-lb-Uau"/>
+                <outlet property="horizontalButton" destination="f8L-dW-OV5" id="2bQ-AH-t3U"/>
+                <outlet property="leftButton" destination="PwG-OP-iJ7" id="eZg-FR-Kro"/>
+                <outlet property="moreButton" destination="YVh-aT-yWA" id="M54-rm-tnw"/>
+                <outlet property="qucikToolsLabel" destination="FaJ-2q-2cQ" id="q0S-ez-pED"/>
+                <outlet property="qucikToolsView" destination="ynU-RA-kWD" id="t4n-b1-mpf"/>
+                <outlet property="recentlyLabel" destination="Jq6-Hl-amd" id="cL6-5Q-9jC"/>
+                <outlet property="rightButton" destination="WPD-Y0-yC2" id="ZEL-I1-FmC"/>
+                <outlet property="verticalButton" destination="oce-zR-GCX" id="DXr-S4-r67"/>
+            </connections>
+        </customObject>
+        <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
+        <customObject id="-3" userLabel="Application" customClass="NSObject"/>
+        <customView id="c22-O7-iKe">
+            <rect key="frame" x="0.0" y="0.0" width="700" height="667"/>
+            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
+            <subviews>
+                <scrollView borderType="none" horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" hasHorizontalScroller="NO" hasVerticalScroller="NO" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="kXR-P8-kEz">
+                    <rect key="frame" x="48" y="48" width="624" height="571"/>
+                    <clipView key="contentView" drawsBackground="NO" id="i44-GZ-Pxj">
+                        <rect key="frame" x="0.0" y="0.0" width="624" height="571"/>
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                        <subviews>
+                            <view id="jlt-dP-sou">
+                                <rect key="frame" x="0.0" y="0.0" width="609" height="556"/>
+                                <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                                <subviews>
+                                    <customView translatesAutoresizingMaskIntoConstraints="NO" id="PAa-wQ-E8L">
+                                        <rect key="frame" x="0.0" y="294" width="609" height="262"/>
+                                        <subviews>
+                                            <customView translatesAutoresizingMaskIntoConstraints="NO" id="69z-SV-dL5">
+                                                <rect key="frame" x="0.0" y="238" width="609" height="24"/>
+                                                <subviews>
+                                                    <textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="FaJ-2q-2cQ">
+                                                        <rect key="frame" x="-2" y="0.0" width="111" height="24"/>
+                                                        <textFieldCell key="cell" lineBreakMode="clipping" title="Qucik Tools" id="uw9-z5-FMe">
+                                                            <font key="font" metaFont="systemSemibold" size="20"/>
+                                                            <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
+                                                            <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
+                                                        </textFieldCell>
+                                                    </textField>
+                                                    <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="YVh-aT-yWA" customClass="KMButton">
+                                                        <rect key="frame" x="589" y="2" width="20" height="20"/>
+                                                        <buttonCell key="cell" type="square" bezelStyle="shadowlessSquare" image="KMImageNameUXIconHomeMoreNor" imagePosition="only" alignment="center" imageScaling="proportionallyUpOrDown" inset="2" id="H4M-FQ-wtf">
+                                                            <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
+                                                            <font key="font" metaFont="system"/>
+                                                        </buttonCell>
+                                                        <connections>
+                                                            <action selector="moreButtonAction:" target="-2" id="4JY-gV-CUq"/>
+                                                        </connections>
+                                                    </button>
+                                                    <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="WPD-Y0-yC2">
+                                                        <rect key="frame" x="557" y="2" width="16" height="21"/>
+                                                        <buttonCell key="cell" type="bevel" bezelStyle="rounded" image="NSTouchBarGoForwardTemplate" imagePosition="overlaps" alignment="center" imageScaling="proportionallyDown" inset="2" id="mRw-z9-Pze">
+                                                            <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
+                                                            <font key="font" metaFont="system"/>
+                                                        </buttonCell>
+                                                        <constraints>
+                                                            <constraint firstAttribute="width" constant="16" id="ASJ-At-7qY"/>
+                                                            <constraint firstAttribute="height" constant="16" id="x37-9K-xk3"/>
+                                                        </constraints>
+                                                        <connections>
+                                                            <action selector="rightButtonAction:" target="-2" id="noR-iP-jsC"/>
+                                                        </connections>
+                                                    </button>
+                                                    <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="PwG-OP-iJ7">
+                                                        <rect key="frame" x="509" y="2" width="16" height="21"/>
+                                                        <buttonCell key="cell" type="square" title="Button" bezelStyle="shadowlessSquare" image="NSTouchBarGoBackTemplate" imagePosition="only" alignment="center" imageScaling="proportionallyDown" inset="2" id="bil-yH-Akb">
+                                                            <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
+                                                            <font key="font" metaFont="system"/>
+                                                        </buttonCell>
+                                                        <constraints>
+                                                            <constraint firstAttribute="height" constant="16" id="Dw9-LS-jOQ"/>
+                                                            <constraint firstAttribute="width" constant="16" id="Wzf-Iv-uw7"/>
+                                                        </constraints>
+                                                        <connections>
+                                                            <action selector="leftButtonAction:" target="-2" id="U2S-eX-FI8"/>
+                                                        </connections>
+                                                    </button>
+                                                </subviews>
+                                                <constraints>
+                                                    <constraint firstItem="WPD-Y0-yC2" firstAttribute="centerY" secondItem="69z-SV-dL5" secondAttribute="centerY" id="1mQ-di-yW2"/>
+                                                    <constraint firstItem="WPD-Y0-yC2" firstAttribute="leading" secondItem="PwG-OP-iJ7" secondAttribute="trailing" constant="32" id="2o2-jt-hDj"/>
+                                                    <constraint firstAttribute="trailing" secondItem="YVh-aT-yWA" secondAttribute="trailing" id="C9W-JG-W8s"/>
+                                                    <constraint firstItem="FaJ-2q-2cQ" firstAttribute="leading" secondItem="69z-SV-dL5" secondAttribute="leading" id="UZc-nM-Aqt"/>
+                                                    <constraint firstAttribute="height" constant="24" id="VF5-NT-Dua"/>
+                                                    <constraint firstItem="FaJ-2q-2cQ" firstAttribute="centerY" secondItem="69z-SV-dL5" secondAttribute="centerY" id="e4G-eL-brO"/>
+                                                    <constraint firstItem="YVh-aT-yWA" firstAttribute="leading" secondItem="WPD-Y0-yC2" secondAttribute="trailing" constant="16" id="sIP-zf-cQy"/>
+                                                    <constraint firstItem="YVh-aT-yWA" firstAttribute="centerY" secondItem="69z-SV-dL5" secondAttribute="centerY" id="u3H-Ys-UG6"/>
+                                                    <constraint firstItem="PwG-OP-iJ7" firstAttribute="centerY" secondItem="69z-SV-dL5" secondAttribute="centerY" id="ygX-nH-XYo"/>
+                                                </constraints>
+                                            </customView>
+                                            <customView translatesAutoresizingMaskIntoConstraints="NO" id="ynU-RA-kWD" customClass="KMQucikToolsView" customModule="PDF_Master" customModuleProvider="target">
+                                                <rect key="frame" x="0.0" y="0.0" width="609" height="238"/>
+                                            </customView>
+                                        </subviews>
+                                        <constraints>
+                                            <constraint firstItem="69z-SV-dL5" firstAttribute="leading" secondItem="PAa-wQ-E8L" secondAttribute="leading" id="CXA-Yf-S6n"/>
+                                            <constraint firstAttribute="trailing" secondItem="69z-SV-dL5" secondAttribute="trailing" id="R3o-AV-ca6"/>
+                                            <constraint firstItem="69z-SV-dL5" firstAttribute="top" secondItem="PAa-wQ-E8L" secondAttribute="top" id="T3r-CJ-twO"/>
+                                            <constraint firstAttribute="height" constant="262" id="TWz-4G-1dS"/>
+                                            <constraint firstAttribute="trailing" secondItem="ynU-RA-kWD" secondAttribute="trailing" id="ah7-Yb-qGV"/>
+                                            <constraint firstItem="ynU-RA-kWD" firstAttribute="top" secondItem="69z-SV-dL5" secondAttribute="bottom" id="iUL-0f-b1G"/>
+                                            <constraint firstAttribute="bottom" secondItem="ynU-RA-kWD" secondAttribute="bottom" id="lil-Ek-8bs"/>
+                                            <constraint firstItem="ynU-RA-kWD" firstAttribute="leading" secondItem="PAa-wQ-E8L" secondAttribute="leading" id="sYF-gW-xax"/>
+                                        </constraints>
+                                    </customView>
+                                    <customView translatesAutoresizingMaskIntoConstraints="NO" id="lCh-WA-G58">
+                                        <rect key="frame" x="0.0" y="0.0" width="609" height="246"/>
+                                        <subviews>
+                                            <customView translatesAutoresizingMaskIntoConstraints="NO" id="Q84-po-tiv">
+                                                <rect key="frame" x="0.0" y="222" width="609" height="24"/>
+                                                <subviews>
+                                                    <textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Jq6-Hl-amd">
+                                                        <rect key="frame" x="-2" y="0.0" width="85" height="24"/>
+                                                        <textFieldCell key="cell" lineBreakMode="clipping" title="Recently" id="ify-Mu-nbZ">
+                                                            <font key="font" metaFont="systemSemibold" size="20"/>
+                                                            <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
+                                                            <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
+                                                        </textFieldCell>
+                                                    </textField>
+                                                    <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="2pe-eQ-jim" customClass="KMButton">
+                                                        <rect key="frame" x="589" y="2" width="20" height="20"/>
+                                                        <buttonCell key="cell" type="square" title="Button" bezelStyle="shadowlessSquare" image="KMImageNameHomeDeletNor" imagePosition="only" alignment="center" imageScaling="proportionallyDown" inset="2" id="unN-7z-cUu">
+                                                            <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
+                                                            <font key="font" metaFont="system"/>
+                                                        </buttonCell>
+                                                        <constraints>
+                                                            <constraint firstAttribute="width" constant="20" id="68J-F8-nVR"/>
+                                                            <constraint firstAttribute="height" constant="20" id="hf5-uR-HfC"/>
+                                                        </constraints>
+                                                        <connections>
+                                                            <action selector="cleanButtonAction:" target="-2" id="4Ja-7N-Avc"/>
+                                                        </connections>
+                                                    </button>
+                                                    <box horizontalHuggingPriority="750" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="mDv-HL-Jso">
+                                                        <rect key="frame" x="567" y="2" width="5" height="20"/>
+                                                        <constraints>
+                                                            <constraint firstAttribute="width" constant="1" id="SGq-bD-tlk"/>
+                                                            <constraint firstAttribute="height" constant="20" id="kQu-ie-pMw"/>
+                                                        </constraints>
+                                                    </box>
+                                                    <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="oce-zR-GCX">
+                                                        <rect key="frame" x="529" y="2" width="20" height="20"/>
+                                                        <buttonCell key="cell" type="square" bezelStyle="shadowlessSquare" image="KMImageNameUXIconHomeViewthumbnailNor" imagePosition="overlaps" alignment="center" imageScaling="proportionallyDown" inset="2" id="0s5-A7-lRz">
+                                                            <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
+                                                            <font key="font" metaFont="system"/>
+                                                        </buttonCell>
+                                                        <constraints>
+                                                            <constraint firstAttribute="height" constant="20" id="HDg-pn-2rE"/>
+                                                            <constraint firstAttribute="width" constant="20" id="Kyx-GP-dbb"/>
+                                                        </constraints>
+                                                        <connections>
+                                                            <action selector="verticalButtonAction:" target="-2" id="Tsa-n6-92q"/>
+                                                        </connections>
+                                                    </button>
+                                                    <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="f8L-dW-OV5">
+                                                        <rect key="frame" x="493" y="2" width="20" height="20"/>
+                                                        <buttonCell key="cell" type="square" bezelStyle="shadowlessSquare" image="KMImageNameUXIconHomeViewlistNor" imagePosition="overlaps" alignment="center" imageScaling="proportionallyDown" inset="2" id="fSg-GB-X16">
+                                                            <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
+                                                            <font key="font" metaFont="system"/>
+                                                        </buttonCell>
+                                                        <constraints>
+                                                            <constraint firstAttribute="width" constant="20" id="Hx5-iJ-u9m"/>
+                                                            <constraint firstAttribute="height" constant="20" id="Xzr-w7-vMu"/>
+                                                        </constraints>
+                                                        <connections>
+                                                            <action selector="horizontalButtonAction:" target="-2" id="ffd-Qv-P2i"/>
+                                                        </connections>
+                                                    </button>
+                                                </subviews>
+                                                <constraints>
+                                                    <constraint firstAttribute="height" constant="24" id="3cL-Mi-izd"/>
+                                                    <constraint firstItem="f8L-dW-OV5" firstAttribute="centerY" secondItem="Q84-po-tiv" secondAttribute="centerY" id="Cf9-QY-3at"/>
+                                                    <constraint firstItem="mDv-HL-Jso" firstAttribute="centerY" secondItem="Q84-po-tiv" secondAttribute="centerY" id="EBA-r9-ef4"/>
+                                                    <constraint firstItem="Jq6-Hl-amd" firstAttribute="leading" secondItem="Q84-po-tiv" secondAttribute="leading" id="Gpg-oa-r8n"/>
+                                                    <constraint firstAttribute="trailing" secondItem="2pe-eQ-jim" secondAttribute="trailing" id="JSL-Us-Bp2"/>
+                                                    <constraint firstItem="Jq6-Hl-amd" firstAttribute="centerY" secondItem="Q84-po-tiv" secondAttribute="centerY" id="Nvb-BH-krU"/>
+                                                    <constraint firstItem="oce-zR-GCX" firstAttribute="centerY" secondItem="Q84-po-tiv" secondAttribute="centerY" id="Xl6-TG-izL"/>
+                                                    <constraint firstItem="2pe-eQ-jim" firstAttribute="leading" secondItem="mDv-HL-Jso" secondAttribute="trailing" constant="19" id="Zqb-KP-jZ6"/>
+                                                    <constraint firstItem="oce-zR-GCX" firstAttribute="leading" secondItem="f8L-dW-OV5" secondAttribute="trailing" constant="16" id="aN0-Rr-nPu"/>
+                                                    <constraint firstItem="2pe-eQ-jim" firstAttribute="centerY" secondItem="Q84-po-tiv" secondAttribute="centerY" id="bjw-iR-IQZ"/>
+                                                    <constraint firstItem="mDv-HL-Jso" firstAttribute="leading" secondItem="oce-zR-GCX" secondAttribute="trailing" constant="20" id="soy-3d-rtd"/>
+                                                </constraints>
+                                            </customView>
+                                            <customView translatesAutoresizingMaskIntoConstraints="NO" id="wMw-AS-5yG" customClass="KMHomeHistoryListView" customModule="PDF_Master" customModuleProvider="target">
+                                                <rect key="frame" x="0.0" y="0.0" width="609" height="222"/>
+                                            </customView>
+                                        </subviews>
+                                        <constraints>
+                                            <constraint firstItem="wMw-AS-5yG" firstAttribute="top" secondItem="Q84-po-tiv" secondAttribute="bottom" id="9Vd-no-qV4"/>
+                                            <constraint firstItem="Q84-po-tiv" firstAttribute="leading" secondItem="lCh-WA-G58" secondAttribute="leading" id="Xua-gM-k6t"/>
+                                            <constraint firstAttribute="trailing" secondItem="Q84-po-tiv" secondAttribute="trailing" id="YLW-A7-bBV"/>
+                                            <constraint firstAttribute="trailing" secondItem="wMw-AS-5yG" secondAttribute="trailing" id="d3N-SN-uuz"/>
+                                            <constraint firstItem="Q84-po-tiv" firstAttribute="top" secondItem="lCh-WA-G58" secondAttribute="top" id="dc9-9O-prs"/>
+                                            <constraint firstItem="wMw-AS-5yG" firstAttribute="leading" secondItem="lCh-WA-G58" secondAttribute="leading" id="tJ1-Wi-nBZ"/>
+                                            <constraint firstAttribute="bottom" secondItem="wMw-AS-5yG" secondAttribute="bottom" id="xuF-zv-5TH"/>
+                                        </constraints>
+                                    </customView>
+                                </subviews>
+                                <constraints>
+                                    <constraint firstItem="PAa-wQ-E8L" firstAttribute="top" secondItem="jlt-dP-sou" secondAttribute="top" id="3iE-Hv-fU7"/>
+                                    <constraint firstItem="lCh-WA-G58" firstAttribute="top" secondItem="PAa-wQ-E8L" secondAttribute="bottom" constant="48" id="Ark-gU-B5L"/>
+                                    <constraint firstAttribute="trailing" secondItem="lCh-WA-G58" secondAttribute="trailing" id="Bus-kI-RRx"/>
+                                    <constraint firstItem="lCh-WA-G58" firstAttribute="leading" secondItem="jlt-dP-sou" secondAttribute="leading" id="Q0h-pJ-4eR"/>
+                                    <constraint firstItem="PAa-wQ-E8L" firstAttribute="leading" secondItem="jlt-dP-sou" secondAttribute="leading" id="mj5-r1-2md"/>
+                                    <constraint firstAttribute="bottom" secondItem="lCh-WA-G58" secondAttribute="bottom" id="sNd-yf-uit"/>
+                                    <constraint firstAttribute="trailing" secondItem="PAa-wQ-E8L" secondAttribute="trailing" id="z8Z-dx-yGz"/>
+                                </constraints>
+                            </view>
+                        </subviews>
+                        <color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
+                    </clipView>
+                    <scroller key="horizontalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="YES" id="lJa-LQ-t6a">
+                        <rect key="frame" x="-100" y="-100" width="685" height="15"/>
+                        <autoresizingMask key="autoresizingMask"/>
+                    </scroller>
+                    <scroller key="verticalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" doubleValue="1" horizontal="NO" id="JGk-Uc-9sS">
+                        <rect key="frame" x="-100" y="-100" width="15" height="667"/>
+                        <autoresizingMask key="autoresizingMask"/>
+                    </scroller>
+                </scrollView>
+            </subviews>
+            <constraints>
+                <constraint firstItem="kXR-P8-kEz" firstAttribute="top" secondItem="c22-O7-iKe" secondAttribute="top" constant="48" id="K7m-qE-Cbe"/>
+                <constraint firstAttribute="trailing" secondItem="kXR-P8-kEz" secondAttribute="trailing" constant="28" id="VPd-ma-QBA"/>
+                <constraint firstItem="kXR-P8-kEz" firstAttribute="leading" secondItem="c22-O7-iKe" secondAttribute="leading" constant="48" id="WjW-AJ-53t"/>
+                <constraint firstAttribute="bottom" secondItem="kXR-P8-kEz" secondAttribute="bottom" constant="48" id="dAS-Gt-Pni"/>
+            </constraints>
+            <point key="canvasLocation" x="-436" y="281.5"/>
+        </customView>
+    </objects>
+    <resources>
+        <image name="KMImageNameHomeDeletNor" width="20" height="20"/>
+        <image name="KMImageNameUXIconHomeMoreNor" width="20" height="20"/>
+        <image name="KMImageNameUXIconHomeViewlistNor" width="20" height="20"/>
+        <image name="KMImageNameUXIconHomeViewthumbnailNor" width="20" height="20"/>
+        <image name="NSTouchBarGoBackTemplate" width="12" height="17"/>
+        <image name="NSTouchBarGoForwardTemplate" width="12" height="17"/>
+    </resources>
+</document>

+ 18 - 0
PDF Office/PDF Master/Class/Home/View/HomeContentView/NoFileView/KMHomeNOFileView.swift

@@ -0,0 +1,18 @@
+//
+//  KMHomeNOFileView.swift
+//  PDF Master
+//
+//  Created by lizhe on 2023/10/30.
+//
+
+import Cocoa
+
+class KMHomeNOFileView: NSView {
+
+    override func draw(_ dirtyRect: NSRect) {
+        super.draw(dirtyRect)
+
+        // Drawing code here.
+    }
+    
+}

+ 71 - 0
PDF Office/PDF Master/Class/Home/View/HomeContentView/NoFileView/KMHomeNOFileView.xib

@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22155" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
+    <dependencies>
+        <deployment identifier="macosx"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22155"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <customObject id="-2" userLabel="File's Owner"/>
+        <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
+        <customObject id="-3" userLabel="Application" customClass="NSObject"/>
+        <customView id="c22-O7-iKe">
+            <rect key="frame" x="0.0" y="0.0" width="260" height="215"/>
+            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
+            <subviews>
+                <customView translatesAutoresizingMaskIntoConstraints="NO" id="Rqu-VJ-nd2">
+                    <rect key="frame" x="0.0" y="0.0" width="260" height="215"/>
+                    <subviews>
+                        <textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="EpA-iG-2fX">
+                            <rect key="frame" x="-2" y="42" width="264" height="17"/>
+                            <textFieldCell key="cell" alignment="center" title="No recently opened file" id="jxf-2m-h5S">
+                                <font key="font" metaFont="systemSemibold" size="14"/>
+                                <color key="textColor" red="0.59999999999999998" green="0.59999999999999998" blue="0.59999999999999998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
+                            </textFieldCell>
+                        </textField>
+                        <imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="kgz-YX-oag">
+                            <rect key="frame" x="60" y="75" width="140" height="140"/>
+                            <constraints>
+                                <constraint firstAttribute="width" constant="140" id="BKm-Q1-YeQ"/>
+                                <constraint firstAttribute="height" constant="140" id="Gbg-Xa-qLe"/>
+                            </constraints>
+                            <imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="KMImageNameUXIconImgEmpthHome" id="aSM-Nq-t67"/>
+                        </imageView>
+                        <textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="1Gc-Xd-aZe">
+                            <rect key="frame" x="-2" y="0.0" width="264" height="34"/>
+                            <textFieldCell key="cell" alignment="center" title="Click Add files or drag-and-drop files here to open them" id="NHF-rt-7Js">
+                                <font key="font" metaFont="system" size="14"/>
+                                <color key="textColor" red="0.59999999999999998" green="0.59999999999999998" blue="0.59999999999999998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
+                            </textFieldCell>
+                        </textField>
+                    </subviews>
+                    <constraints>
+                        <constraint firstItem="EpA-iG-2fX" firstAttribute="leading" secondItem="Rqu-VJ-nd2" secondAttribute="leading" id="0NT-wi-bcZ"/>
+                        <constraint firstAttribute="trailing" secondItem="EpA-iG-2fX" secondAttribute="trailing" id="0pK-A5-6rf"/>
+                        <constraint firstItem="1Gc-Xd-aZe" firstAttribute="top" secondItem="EpA-iG-2fX" secondAttribute="bottom" constant="8" id="8jo-O3-gaQ"/>
+                        <constraint firstItem="kgz-YX-oag" firstAttribute="centerX" secondItem="Rqu-VJ-nd2" secondAttribute="centerX" id="Gep-uT-FZ0"/>
+                        <constraint firstItem="EpA-iG-2fX" firstAttribute="top" secondItem="kgz-YX-oag" secondAttribute="bottom" constant="16" id="Jvc-cu-Cr5"/>
+                        <constraint firstItem="1Gc-Xd-aZe" firstAttribute="leading" secondItem="Rqu-VJ-nd2" secondAttribute="leading" id="M6N-2l-Shn"/>
+                        <constraint firstAttribute="trailing" secondItem="1Gc-Xd-aZe" secondAttribute="trailing" id="Vo0-Pq-pLX"/>
+                        <constraint firstAttribute="trailing" secondItem="kgz-YX-oag" secondAttribute="trailing" constant="60" id="Zrc-C2-nxF"/>
+                        <constraint firstAttribute="bottom" secondItem="1Gc-Xd-aZe" secondAttribute="bottom" id="bA8-JM-AxD"/>
+                        <constraint firstItem="kgz-YX-oag" firstAttribute="top" secondItem="Rqu-VJ-nd2" secondAttribute="top" id="eac-A1-5Qr"/>
+                        <constraint firstItem="kgz-YX-oag" firstAttribute="leading" secondItem="Rqu-VJ-nd2" secondAttribute="leading" constant="60" id="lJC-gg-ouc"/>
+                    </constraints>
+                </customView>
+            </subviews>
+            <constraints>
+                <constraint firstItem="Rqu-VJ-nd2" firstAttribute="top" secondItem="c22-O7-iKe" secondAttribute="top" id="Cgz-Ps-JpD"/>
+                <constraint firstAttribute="bottom" secondItem="Rqu-VJ-nd2" secondAttribute="bottom" id="IAk-5A-JSN"/>
+                <constraint firstAttribute="trailing" secondItem="Rqu-VJ-nd2" secondAttribute="trailing" id="IE3-rQ-cTx"/>
+                <constraint firstItem="Rqu-VJ-nd2" firstAttribute="leading" secondItem="c22-O7-iKe" secondAttribute="leading" id="QS4-UF-nef"/>
+            </constraints>
+            <point key="canvasLocation" x="-54" y="108"/>
+        </customView>
+    </objects>
+    <resources>
+        <image name="KMImageNameUXIconImgEmpthHome" width="140" height="141"/>
+    </resources>
+</document>

+ 98 - 0
PDF Office/PDF Master/Class/Home/View/HomeContentView/QucikTools/KMQucikToolsView.swift

@@ -0,0 +1,98 @@
+//
+//  KMQucikToolsView.swift
+//  PDF Master
+//
+//  Created by lizhe on 2023/10/27.
+//
+
+import Cocoa
+
+class KMQucikToolsView: KMBaseXibView {
+    @IBOutlet weak var collectionView: NSCollectionView!
+    
+    var data: [KMQucikToolsModel] = []
+    override func draw(_ dirtyRect: NSRect) {
+        super.draw(dirtyRect)
+
+        // Drawing code here.
+    }
+    
+    override func setup() {
+        //设置代理
+        let layout = NSCollectionViewFlowLayout()
+        layout.scrollDirection = .horizontal
+        layout.minimumLineSpacing = 10
+        layout.minimumInteritemSpacing = 10
+        // 设置布局到 NSCollectionView
+        self.collectionView.collectionViewLayout = layout
+        
+        self.collectionView.delegate = self
+        self.collectionView.dataSource = self
+        //是否可选中
+        self.collectionView.isSelectable = true
+        //注册cell
+        self.collectionView.register(KMQucikToolCollectionViewItem.self, forItemWithIdentifier: NSUserInterfaceItemIdentifier(rawValue: "KMQucikToolCollectionViewItem"))
+        
+//        self.backgroundColor(KMAppearance.Layout.l0Color())
+    }
+    
+    override func reloadData() {
+        self.data.removeAll()
+        
+        for type in KMQucikToolsModel.allType() {
+            self.data.append(KMQucikToolsModel.init(type: type))
+        }
+        self.collectionView.reloadData()
+    }
+}
+
+extension KMQucikToolsView: NSCollectionViewDelegate {
+    //当item被选中
+    public func collectionView(_ collectionView: NSCollectionView, didSelectItemsAt indexPaths: Set<IndexPath>) {
+        print("点击")
+        let view = collectionView.item(at: indexPaths.first!) as! KMQucikToolCollectionViewItem
+        
+//        let content = view.model
+        
+//        guard let callBack = didSelect else { return }
+//        
+//        content?.index = indexPaths.first!.item
+//        callBack(self, content!)
+    }
+    
+   //当item取消选中
+    public func collectionView(_ collectionView: NSCollectionView, didDeselectItemsAt indexPaths: Set<IndexPath>) {
+        _ = collectionView.item(at: indexPaths.first!) as! KMQucikToolCollectionViewItem
+    }
+}
+
+extension KMQucikToolsView: NSCollectionViewDataSource {
+    public func numberOfSections(in collectionView: NSCollectionView) -> Int {
+        return 1
+    }
+    
+    public func collectionView(_ collectionView: NSCollectionView, numberOfItemsInSection section: Int) -> Int {
+        return self.data.count
+    }
+    
+    //返回对应的item自定义个体
+    public func collectionView(_ collectionView: NSCollectionView, itemForRepresentedObjectAt indexPath: IndexPath) -> NSCollectionViewItem {
+        let view = collectionView.makeItem(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "KMQucikToolCollectionViewItem"), for: indexPath) as! KMQucikToolCollectionViewItem
+        if self.data.count > indexPath.item {
+            view.model = self.data[indexPath.item]
+        }
+        return view
+    }
+    
+}
+
+extension KMQucikToolsView: NSCollectionViewDelegateFlowLayout {
+    
+    public func collectionView(_ collectionView: NSCollectionView, layout collectionViewLayout: NSCollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> NSSize {
+        return NSSize(width: 216, height: 96)
+    }
+    
+    public func collectionView(_ collectionView: NSCollectionView, layout collectionViewLayout: NSCollectionViewLayout, insetForSectionAt section: Int) -> NSEdgeInsets {
+        return NSEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
+    }
+}

+ 56 - 0
PDF Office/PDF Master/Class/Home/View/HomeContentView/QucikTools/KMQucikToolsView.xib

@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22155" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
+    <dependencies>
+        <deployment identifier="macosx"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22155"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <customObject id="-2" userLabel="File's Owner" customClass="KMQucikToolsView" customModule="PDF_Master" customModuleProvider="target">
+            <connections>
+                <outlet property="collectionView" destination="yOH-Gk-DXG" id="HWt-h6-8Wn"/>
+            </connections>
+        </customObject>
+        <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
+        <customObject id="-3" userLabel="Application" customClass="NSObject"/>
+        <customView id="c22-O7-iKe">
+            <rect key="frame" x="0.0" y="0.0" width="621" height="175"/>
+            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
+            <subviews>
+                <scrollView wantsLayer="YES" borderType="none" horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" hasHorizontalScroller="NO" hasVerticalScroller="NO" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="kBd-Wh-qT6">
+                    <rect key="frame" x="0.0" y="0.0" width="621" height="175"/>
+                    <clipView key="contentView" drawsBackground="NO" id="bai-5O-0kt">
+                        <rect key="frame" x="0.0" y="0.0" width="621" height="175"/>
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                        <subviews>
+                            <collectionView id="yOH-Gk-DXG">
+                                <rect key="frame" x="0.0" y="0.0" width="621" height="158"/>
+                                <autoresizingMask key="autoresizingMask" widthSizable="YES"/>
+                                <collectionViewFlowLayout key="collectionViewLayout" minimumInteritemSpacing="10" minimumLineSpacing="10" id="Boi-ZL-7EE">
+                                    <size key="itemSize" width="50" height="50"/>
+                                </collectionViewFlowLayout>
+                                <color key="primaryBackgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
+                            </collectionView>
+                        </subviews>
+                        <color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
+                    </clipView>
+                    <scroller key="horizontalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="YES" id="iOy-A9-wuo" customClass="KMToolSetScroller" customModule="PDF_Master" customModuleProvider="target">
+                        <rect key="frame" x="-100" y="-100" width="233" height="15"/>
+                        <autoresizingMask key="autoresizingMask"/>
+                    </scroller>
+                    <scroller key="verticalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" doubleValue="1" horizontal="NO" id="ASj-Kc-swn">
+                        <rect key="frame" x="-100" y="-100" width="15" height="143"/>
+                        <autoresizingMask key="autoresizingMask"/>
+                    </scroller>
+                </scrollView>
+            </subviews>
+            <constraints>
+                <constraint firstItem="kBd-Wh-qT6" firstAttribute="leading" secondItem="c22-O7-iKe" secondAttribute="leading" id="KAN-eN-rGv"/>
+                <constraint firstItem="kBd-Wh-qT6" firstAttribute="top" secondItem="c22-O7-iKe" secondAttribute="top" id="KAb-VE-iHG"/>
+                <constraint firstAttribute="trailing" secondItem="kBd-Wh-qT6" secondAttribute="trailing" id="Qhy-st-hr6"/>
+                <constraint firstAttribute="bottom" secondItem="kBd-Wh-qT6" secondAttribute="bottom" id="nEX-md-hgZ"/>
+            </constraints>
+            <point key="canvasLocation" x="392.5" y="168.5"/>
+        </customView>
+    </objects>
+</document>

+ 116 - 0
PDF Office/PDF Master/Class/Home/View/HomeContentView/QucikTools/Model/KMQucikToolsModel.swift

@@ -0,0 +1,116 @@
+//
+//  KMQucikToolsModel.swift
+//  PDF Master
+//
+//  Created by lizhe on 2023/10/30.
+//
+
+import Cocoa
+
+class KMQucikToolsModel: NSObject {
+    init(type: DataNavigationViewButtonActionType? = nil) {
+        self.type = type
+    }
+    
+    var type: DataNavigationViewButtonActionType?
+    
+    static func allType() -> [DataNavigationViewButtonActionType] {
+        let array: [DataNavigationViewButtonActionType] = [.Batch, .ConvertPDF, .PDFToWord, .PDFToExcel, .FileCompare, .PDFToPPT, .ImageToPDF, .OCR, .PageEdit, .MergePDF, .BreakUp, .Insert, .Compression, .Security, .Watermark, .Background, .HeaderAndFooter, .BatesCode, .Print, .Print, .Print]
+        return array
+    }
+    
+    func titleString() -> String {
+        var string = ""
+        
+        switch self.type {
+        case .ConvertPDF: string = "Convert PDF"
+        case .PDFToWord: string = "PDF To Word"
+        case .PDFToExcel: string = "PDF To Excel"
+        case .PDFToPPT: string = "PDF To PPT"
+        case .ImageToPDF: string = "Image To PDF"
+        case .OCR: string = "OCR"
+        case .PageEdit: string = "Page Edit"
+        case .MergePDF: string = "Merge"
+        case .BreakUp: string = "Split"
+        case .Insert: string = "Insert"
+        case .Compression: string = "Compress"
+        case .Security: string = "Security"
+        case .Watermark: string = "Watermark"
+        case .Background: string = "Background"
+        case .HeaderAndFooter: string = "Header & Footer"
+        case .BatesCode: string = "Bates Numbers"
+//        case .Print: string = "Poster"
+//        case .Print: string = "Multiple"
+//        case .Print: string = "Booklet"
+        case .Batch: string = "Batch"
+        case .FileCompare: string = "Compare Files"
+        default: string = ""
+        }
+            
+        return string
+    }
+    
+    func subTitleString() -> String {
+        var string = ""
+        
+        switch self.type {
+        case .ConvertPDF: string = "Convert PDFs to Word/HTML/TXT/JPEG/PNG files"
+        case .PDFToWord: string = "Convert PDFs to Word, Fonts & formatting get converted"
+        case .PDFToExcel: string = "Turn PDF table into a formatted Excel file"
+        case .PDFToPPT: string = "Turn your PDF into a formatted PPT file that you can edit"
+        case .ImageToPDF: string = "Convert JPEG/JPG/PNG/TIFF/BMP/PSD files to PDFs"
+        case .OCR: string = "Recognize text from images or scanned PDF with OCR"
+        case .PageEdit: string = "Insert/delete/extract/rotate/reposition/replace PDF pages"
+        case .MergePDF: string = "Combine multiple documents into a new PDF file"
+        case .BreakUp: string = "Split and save selected PDF pages as a new document"
+        case .Insert: string = "Inserting pages into an existing PDF"
+        case .Compression: string = "Reduce files size to make sure you can easily send them by email."
+        case .Security: string = "Easily batch encrypt PDFs or decrypt the protected files"
+        case .Watermark: string = "Protect PDFs with image/text watermarks from plagiarism"
+        case .Background: string = "Customize PDFs background with colors or images"
+        case .HeaderAndFooter: string = "Customize PDFs header & footer or add page numbers"
+        case .BatesCode: string = "Easily retrieval indexing legal documents by Bates Numbers"
+//        case .Print: string = "Divide large PDF page(s) into multiple smaller pages"
+//        case .Print: string = "Print multiple PDF pages on a single sheet of paper"
+//        case .Print: string = "Print a multipage document as a booklet"
+        case .Batch: string = "Batch convert, compress, secure, watermark PDFs"
+        case .FileCompare: string = "Compare the differences between two files"
+        default: string = ""
+        }
+            
+        return string
+    }
+    
+    func iconImage() -> NSImage {
+        var string = ""
+        
+        switch self.type {
+        case .ConvertPDF: string = "KMImageNameUXIconHomeQuicktoolConvertNor"
+        case .PDFToWord: string = "KMImageNameUXIconHomeQuicktoolWordNor"
+        case .PDFToExcel: string = "KMImageNameUXIconHomeQuicktoolExcelNor"
+        case .PDFToPPT: string = "KMImageNameUXIconHomeQuicktoolPPTNor"
+        case .ImageToPDF: string = "KMImageNameUXIconHomeQuicktoolPdftoimgNor"
+        case .OCR: string = "KMImageNameUXIconHomeQuicktoolOcrNor"
+        case .PageEdit: string = "KMImageNameUXIconHomeQuicktoolPageeditNor"
+        case .MergePDF: string = "KMImageNameUXIconHomeQuicktoolMergeNor"
+        case .BreakUp: string = "KMImageNameUXIconHomeQuicktoolSplitNor"
+        case .Insert: string = "KMImageNameUXIconHomeQuicktoolInsertNor"
+        case .Compression: string = "KMImageNameUXIconHomeQuicktoolComprison"
+        case .Security: string = "KMImageNameUXIconHomeQuicktoolSafeNor"
+        case .Watermark: string = "KMImageNameUXIconHomeQuicktoolWatermarkNor"
+        case .Background: string = "KMImageNameUXIconHomeQuicktoolBackgroundNor"
+        case .HeaderAndFooter: string = "KMImageNameUXIconHomeQuicktoolHeaderandfooterNor"
+        case .BatesCode: string = "KMImageNameUXIconHomeQuicktoolBatesNor"
+//        case .Print: string = "KMImageNameUXIconHomeQuicktoolPosterNor"
+//        case .Print: string = "KMImageNameUXIconHomeQuicktoolMultipageNor"
+//        case .Print: string = "KMImageNameUXIconHomeQuicktoolBookNor"
+        case .Batch: string = "KMImageNameUXIconHomeQuicktoolBatchNor"
+        case .FileCompare: string = "KMHomeQuickToolsItemTypePDFComparison"
+        default: string = ""
+        }
+            
+        return NSImage(named: string) ?? NSImage()
+    }
+}
+
+

+ 123 - 0
PDF Office/PDF Master/Class/Home/View/HomeContentView/QucikTools/View/KMQucikToolCollectionViewItem.swift

@@ -0,0 +1,123 @@
+//
+//  KMQucikToolCollectionViewItem.swift
+//  PDF Master
+//
+//  Created by lizhe on 2023/10/27.
+//
+
+import Cocoa
+
+class KMQucikToolCollectionViewItem: NSCollectionViewItem {
+    @IBOutlet weak var contentBox: KMBox!
+    @IBOutlet weak var iconImageView: NSImageView!
+    @IBOutlet weak var titleLabel: NSTextField!
+    @IBOutlet weak var subTitleLabel: NSTextField!
+    
+    @IBOutlet weak var handleView: NSView!
+    @IBOutlet weak var addBox: KMBox!
+    @IBOutlet weak var addButton: KMButton!
+    @IBOutlet weak var removeBox: KMBox!
+    @IBOutlet weak var removeButton: KMButton!
+    
+    @IBOutlet weak var tagView: NSView!
+    @IBOutlet weak var tagLabel: NSTextField!
+    
+    
+    var model: KMQucikToolsModel? {
+        didSet {
+            self.reloadData()
+        }
+    }
+    override func viewDidLoad() {
+        super.viewDidLoad()
+        // Do view setup here.
+        self.setup()
+    }
+    
+    override func viewDidLayout() {
+        self.view.addTrackingRect(self.view.bounds, owner: self, userData: nil, assumeInside: false)
+    }
+    
+    func setup() {
+        self.tagView.isHidden = true
+        
+        self.handleView.isHidden = true
+        self.addBox.borderColor = KMAppearance.Layout.w70Color()
+        self.addBox.borderWidth = 1.0
+        
+        self.addButton.title = "+" + NSLocalizedString("Add", comment: "")
+        self.addButton.contentTintColor = KMAppearance.Layout.w0Color()
+        
+        self.addBox.moveCallback = { [unowned self] mouseEntered, mouseBox in
+            if mouseEntered {
+                self.addButton.backgroundColor(KMAppearance.Status.preColor())
+            } else {
+                self.addButton.backgroundColor(NSColor.clear)
+            }
+        }
+
+        self.removeBox.borderColor = KMAppearance.Layout.w70Color()
+        self.removeBox.borderWidth = 1.0
+        
+        self.removeButton.title = "+" + NSLocalizedString("Remove", comment: "")
+        self.removeButton.contentTintColor = KMAppearance.Layout.w0Color()
+        self.removeButton.backgroundColor(KMAppearance.Status.preColor())
+        
+        self.removeBox.moveCallback = { [unowned self] mouseEntered, mouseBox in
+            if mouseEntered {
+                self.removeButton.backgroundColor(KMAppearance.Status.preColor())
+            } else {
+                self.removeButton.backgroundColor(NSColor.clear)
+            }
+        }
+        
+        self.contentBox.borderColor = KMAppearance.Interactive.s0Color()
+        self.contentBox.borderWidth = 1.0;
+        self.titleLabel.textColor = KMAppearance.Layout.h0Color()
+        self.subTitleLabel.textColor = KMAppearance.Layout.h1Color()
+        self.contentBox.fillColor = KMAppearance.Layout.l1Color()
+        self.contentBox.moveCallback = { [unowned self] mouseEntered, mouseBox in
+            if (mouseEntered) {
+//                if (blockSelf.mouseMoveCallback) {
+//                    blockSelf.mouseMoveCallback(YES);
+//                }
+            } else {
+//                if (blockSelf.mouseMoveCallback) {
+//                    blockSelf.mouseMoveCallback(NO);
+//                }
+            }
+        }
+        
+        self.tagView.backgroundColor(NSColor(red: 0.0/255.0, green: 207.0/255.0, blue: 133.0/255.0, alpha: 1))
+        self.tagView.layer?.masksToBounds = true
+        self.tagView.layer?.cornerRadius = 8
+    }
+    
+    func reloadData() {
+        guard let model = model else { return }
+        
+        self.titleLabel.stringValue = model.titleString()
+        self.subTitleLabel.stringValue = model.subTitleString()
+        self.iconImageView.image = model.iconImage()
+        
+    }
+    
+    @IBAction func removeButtonAction(_ sender: Any) {
+        
+    }
+    @IBAction func addButtonAction(_ sender: Any) {
+        
+    }
+    
+}
+
+extension KMQucikToolCollectionViewItem {
+    override func mouseEntered(with event: NSEvent) {
+        self.view.backgroundColor(NSColor.green)
+    }
+    
+    override func mouseExited(with event: NSEvent) {
+        self.view.backgroundColor(NSColor.red)
+    }
+    
+}

+ 204 - 0
PDF Office/PDF Master/Class/Home/View/HomeContentView/QucikTools/View/KMQucikToolCollectionViewItem.xib

@@ -0,0 +1,204 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22155" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
+    <dependencies>
+        <deployment identifier="macosx"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22155"/>
+        <capability name="Named colors" minToolsVersion="9.0"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <customObject id="-2" userLabel="File's Owner" customClass="KMQucikToolCollectionViewItem" customModule="PDF_Master" customModuleProvider="target">
+            <connections>
+                <outlet property="addBox" destination="WpY-hX-Iuh" id="fMG-vu-eRc"/>
+                <outlet property="addButton" destination="Sfr-Rz-iNv" id="t4A-h4-K0f"/>
+                <outlet property="contentBox" destination="Mqk-nf-F6P" id="NYS-b5-WXO"/>
+                <outlet property="handleView" destination="5hE-EB-Fbu" id="26F-NC-WO7"/>
+                <outlet property="iconImageView" destination="Vlz-sL-oSP" id="B0h-Nl-Kpf"/>
+                <outlet property="removeBox" destination="4I9-UP-8io" id="MX1-8C-cop"/>
+                <outlet property="removeButton" destination="HWd-oT-cNf" id="ZKr-wg-jc0"/>
+                <outlet property="subTitleLabel" destination="xUh-Dj-kJH" id="Tpg-Qr-ffJ"/>
+                <outlet property="tagLabel" destination="E0R-9e-vEN" id="bAB-No-8Yn"/>
+                <outlet property="tagView" destination="MKg-Pm-wMc" id="dRm-b8-PGC"/>
+                <outlet property="titleLabel" destination="CuI-0G-xl6" id="Isf-Kn-kGP"/>
+                <outlet property="view" destination="Hz6-mo-xeY" id="0bl-1N-x8E"/>
+            </connections>
+        </customObject>
+        <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
+        <customObject id="-3" userLabel="Application" customClass="NSObject"/>
+        <customView id="Hz6-mo-xeY">
+            <rect key="frame" x="0.0" y="0.0" width="216" height="96"/>
+            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
+            <subviews>
+                <box boxType="custom" borderWidth="0.0" translatesAutoresizingMaskIntoConstraints="NO" id="Mqk-nf-F6P" customClass="KMBox" customModule="PDF_Master" customModuleProvider="target">
+                    <rect key="frame" x="0.0" y="0.0" width="216" height="96"/>
+                    <view key="contentView" id="bYU-P3-vtp">
+                        <rect key="frame" x="0.0" y="0.0" width="216" height="96"/>
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                        <subviews>
+                            <view translatesAutoresizingMaskIntoConstraints="NO" id="B7V-zv-Z6E">
+                                <rect key="frame" x="0.0" y="0.0" width="216" height="96"/>
+                                <subviews>
+                                    <imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="Vlz-sL-oSP">
+                                        <rect key="frame" x="16" y="56" width="20" height="20"/>
+                                        <constraints>
+                                            <constraint firstAttribute="height" constant="20" id="FfB-eG-3tH"/>
+                                            <constraint firstAttribute="width" constant="20" id="ZYz-CL-Mkm"/>
+                                        </constraints>
+                                        <imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="KMImageNameHomeBackground" id="5wv-kB-Bkg"/>
+                                    </imageView>
+                                    <textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="CuI-0G-xl6">
+                                        <rect key="frame" x="42" y="57" width="42" height="17"/>
+                                        <textFieldCell key="cell" lineBreakMode="clipping" title="Label" id="wMS-Vz-yLV">
+                                            <font key="font" metaFont="systemBold" size="14"/>
+                                            <color key="textColor" name="KMGray6Color"/>
+                                            <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
+                                        </textFieldCell>
+                                    </textField>
+                                    <textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="xUh-Dj-kJH">
+                                        <rect key="frame" x="42" y="19" width="160" height="34"/>
+                                        <constraints>
+                                            <constraint firstAttribute="height" constant="34" id="gc3-Ff-Nhi"/>
+                                        </constraints>
+                                        <textFieldCell key="cell" title="Label" id="ynF-CO-E0E">
+                                            <font key="font" metaFont="cellTitle"/>
+                                            <color key="textColor" name="KMGrayColor"/>
+                                            <color key="backgroundColor" name="KMGray2Color"/>
+                                        </textFieldCell>
+                                    </textField>
+                                    <customView fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="MKg-Pm-wMc">
+                                        <rect key="frame" x="180" y="80" width="44" height="24"/>
+                                        <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
+                                        <subviews>
+                                            <textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="E0R-9e-vEN">
+                                                <rect key="frame" x="0.0" y="0.0" width="36" height="14"/>
+                                                <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
+                                                <textFieldCell key="cell" lineBreakMode="clipping" alignment="center" title="New" id="LoG-mu-nCH">
+                                                    <font key="font" metaFont="miniSystemBold"/>
+                                                    <color key="textColor" name="KMWhiteColor"/>
+                                                    <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
+                                                </textFieldCell>
+                                            </textField>
+                                        </subviews>
+                                    </customView>
+                                    <customView translatesAutoresizingMaskIntoConstraints="NO" id="5hE-EB-Fbu">
+                                        <rect key="frame" x="16" y="8" width="184" height="44"/>
+                                        <subviews>
+                                            <box boxType="custom" borderWidth="0.0" cornerRadius="1" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="4I9-UP-8io" customClass="KMBox" customModule="PDF_Master" customModuleProvider="target">
+                                                <rect key="frame" x="96" y="10" width="88" height="24"/>
+                                                <view key="contentView" id="xxV-Ig-q6L">
+                                                    <rect key="frame" x="0.0" y="0.0" width="88" height="24"/>
+                                                    <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                                                    <subviews>
+                                                        <button translatesAutoresizingMaskIntoConstraints="NO" id="HWd-oT-cNf" customClass="KMButton">
+                                                            <rect key="frame" x="0.0" y="0.0" width="88" height="24"/>
+                                                            <buttonCell key="cell" type="square" title="- Remove" bezelStyle="shadowlessSquare" alignment="center" imageScaling="proportionallyUpOrDown" inset="2" id="lIK-U7-kOI">
+                                                                <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
+                                                                <font key="font" metaFont="system"/>
+                                                            </buttonCell>
+                                                            <connections>
+                                                                <action selector="removeButtonAction:" target="-2" id="dBj-wp-gqD"/>
+                                                            </connections>
+                                                        </button>
+                                                    </subviews>
+                                                    <constraints>
+                                                        <constraint firstItem="HWd-oT-cNf" firstAttribute="leading" secondItem="xxV-Ig-q6L" secondAttribute="leading" id="1vi-ws-tgb"/>
+                                                        <constraint firstAttribute="trailing" secondItem="HWd-oT-cNf" secondAttribute="trailing" id="7Wj-x2-AL1"/>
+                                                        <constraint firstAttribute="bottom" secondItem="HWd-oT-cNf" secondAttribute="bottom" id="hge-ov-hqL"/>
+                                                        <constraint firstItem="HWd-oT-cNf" firstAttribute="top" secondItem="xxV-Ig-q6L" secondAttribute="top" id="yMa-2W-bm2"/>
+                                                    </constraints>
+                                                </view>
+                                                <constraints>
+                                                    <constraint firstAttribute="height" constant="24" id="ZZ8-sN-RHF"/>
+                                                    <constraint firstAttribute="width" constant="88" id="mSV-Jb-zUY"/>
+                                                </constraints>
+                                                <color key="fillColor" white="1" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                                            </box>
+                                            <box boxType="custom" borderWidth="0.0" cornerRadius="1" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="WpY-hX-Iuh" customClass="KMBox" customModule="PDF_Master" customModuleProvider="target">
+                                                <rect key="frame" x="0.0" y="10" width="88" height="24"/>
+                                                <view key="contentView" id="G5Y-6x-Ziw">
+                                                    <rect key="frame" x="0.0" y="0.0" width="88" height="24"/>
+                                                    <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                                                    <subviews>
+                                                        <button translatesAutoresizingMaskIntoConstraints="NO" id="Sfr-Rz-iNv" customClass="KMButton">
+                                                            <rect key="frame" x="0.0" y="0.0" width="88" height="24"/>
+                                                            <buttonCell key="cell" type="square" title="+ Add" bezelStyle="shadowlessSquare" alignment="center" imageScaling="proportionallyUpOrDown" inset="2" id="ION-oS-3z4">
+                                                                <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
+                                                                <font key="font" metaFont="system"/>
+                                                            </buttonCell>
+                                                            <connections>
+                                                                <action selector="addButtonAction:" target="-2" id="gN0-OC-odq"/>
+                                                            </connections>
+                                                        </button>
+                                                    </subviews>
+                                                    <constraints>
+                                                        <constraint firstAttribute="trailing" secondItem="Sfr-Rz-iNv" secondAttribute="trailing" id="9Tw-Za-Sz7"/>
+                                                        <constraint firstItem="Sfr-Rz-iNv" firstAttribute="leading" secondItem="G5Y-6x-Ziw" secondAttribute="leading" id="FlI-ZO-GLr"/>
+                                                        <constraint firstItem="Sfr-Rz-iNv" firstAttribute="top" secondItem="G5Y-6x-Ziw" secondAttribute="top" id="Rmu-2s-nSn"/>
+                                                        <constraint firstAttribute="bottom" secondItem="Sfr-Rz-iNv" secondAttribute="bottom" id="vsw-nH-T6p"/>
+                                                    </constraints>
+                                                </view>
+                                                <constraints>
+                                                    <constraint firstAttribute="height" constant="24" id="L9o-vl-BZL"/>
+                                                    <constraint firstAttribute="width" constant="88" id="lQZ-xc-ZE5"/>
+                                                </constraints>
+                                                <color key="fillColor" white="1" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                                            </box>
+                                        </subviews>
+                                        <constraints>
+                                            <constraint firstAttribute="trailing" secondItem="4I9-UP-8io" secondAttribute="trailing" id="H7I-ef-a1Z"/>
+                                            <constraint firstItem="WpY-hX-Iuh" firstAttribute="centerY" secondItem="5hE-EB-Fbu" secondAttribute="centerY" id="PCT-YL-AFj"/>
+                                            <constraint firstItem="4I9-UP-8io" firstAttribute="leading" secondItem="WpY-hX-Iuh" secondAttribute="trailing" constant="8" id="chG-Dz-V3u"/>
+                                            <constraint firstItem="4I9-UP-8io" firstAttribute="centerY" secondItem="WpY-hX-Iuh" secondAttribute="centerY" id="hCY-iE-6l4"/>
+                                            <constraint firstItem="WpY-hX-Iuh" firstAttribute="leading" secondItem="5hE-EB-Fbu" secondAttribute="leading" id="hH9-RV-mUU"/>
+                                        </constraints>
+                                    </customView>
+                                </subviews>
+                                <constraints>
+                                    <constraint firstAttribute="bottom" secondItem="5hE-EB-Fbu" secondAttribute="bottom" constant="8" id="D7T-JK-rEj"/>
+                                    <constraint firstItem="xUh-Dj-kJH" firstAttribute="leading" secondItem="CuI-0G-xl6" secondAttribute="leading" id="N72-QY-RBz"/>
+                                    <constraint firstItem="CuI-0G-xl6" firstAttribute="leading" secondItem="Vlz-sL-oSP" secondAttribute="trailing" constant="8" id="WfY-mk-msC"/>
+                                    <constraint firstItem="CuI-0G-xl6" firstAttribute="top" secondItem="B7V-zv-Z6E" secondAttribute="top" constant="22" id="YjZ-Fj-3Oa"/>
+                                    <constraint firstItem="5hE-EB-Fbu" firstAttribute="leading" secondItem="B7V-zv-Z6E" secondAttribute="leading" constant="16" id="Z1n-qt-ohg"/>
+                                    <constraint firstItem="xUh-Dj-kJH" firstAttribute="top" secondItem="CuI-0G-xl6" secondAttribute="bottom" constant="4" id="bxk-x0-9pl"/>
+                                    <constraint firstAttribute="trailing" secondItem="5hE-EB-Fbu" secondAttribute="trailing" constant="16" id="fM1-OU-rRd"/>
+                                    <constraint firstItem="5hE-EB-Fbu" firstAttribute="top" secondItem="Vlz-sL-oSP" secondAttribute="bottom" constant="4" id="kxS-do-AqU"/>
+                                    <constraint firstItem="Vlz-sL-oSP" firstAttribute="top" secondItem="B7V-zv-Z6E" secondAttribute="top" constant="20" id="pxK-L8-ix9"/>
+                                    <constraint firstItem="Vlz-sL-oSP" firstAttribute="leading" secondItem="B7V-zv-Z6E" secondAttribute="leading" constant="16" id="s3q-BH-Q5c"/>
+                                    <constraint firstAttribute="trailing" secondItem="xUh-Dj-kJH" secondAttribute="trailing" constant="16" id="zX8-gf-kxj"/>
+                                </constraints>
+                            </view>
+                        </subviews>
+                        <constraints>
+                            <constraint firstAttribute="bottom" secondItem="B7V-zv-Z6E" secondAttribute="bottom" id="RMC-p6-6zB"/>
+                            <constraint firstItem="B7V-zv-Z6E" firstAttribute="leading" secondItem="bYU-P3-vtp" secondAttribute="leading" id="gnz-eK-PvV"/>
+                            <constraint firstAttribute="trailing" secondItem="B7V-zv-Z6E" secondAttribute="trailing" id="om2-p7-jaY"/>
+                            <constraint firstItem="B7V-zv-Z6E" firstAttribute="top" secondItem="bYU-P3-vtp" secondAttribute="top" id="ueL-23-WOe"/>
+                        </constraints>
+                    </view>
+                </box>
+            </subviews>
+            <constraints>
+                <constraint firstAttribute="bottom" secondItem="Mqk-nf-F6P" secondAttribute="bottom" id="Ryz-Ce-hvn"/>
+                <constraint firstAttribute="trailing" secondItem="Mqk-nf-F6P" secondAttribute="trailing" id="SZx-GQ-4io"/>
+                <constraint firstItem="Mqk-nf-F6P" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" id="fiI-MU-6go"/>
+                <constraint firstItem="Mqk-nf-F6P" firstAttribute="top" secondItem="Hz6-mo-xeY" secondAttribute="top" id="rFA-23-wjT"/>
+            </constraints>
+            <point key="canvasLocation" x="-160" y="64"/>
+        </customView>
+    </objects>
+    <resources>
+        <image name="KMImageNameHomeBackground" width="40" height="40"/>
+        <namedColor name="KMGray2Color">
+            <color red="0.96078431372549022" green="0.96470588235294119" blue="0.98039215686274506" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+        </namedColor>
+        <namedColor name="KMGray6Color">
+            <color red="0.396078431372549" green="0.41176470588235292" blue="0.4392156862745098" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+        </namedColor>
+        <namedColor name="KMGrayColor">
+            <color red="0.32899999618530273" green="0.32400000095367432" blue="0.4779999852180481" alpha="0.33000001311302185" colorSpace="custom" customColorSpace="sRGB"/>
+        </namedColor>
+        <namedColor name="KMWhiteColor">
+            <color red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+        </namedColor>
+    </resources>
+</document>

+ 1 - 1
PDF Office/PDF Master/Class/Home/ViewController/KMFastToolCollectionViewItem.swift

@@ -7,7 +7,7 @@
 
 import Cocoa
 
-public enum DataNavigationViewButtonActionType : Int {
+public enum DataNavigationViewButtonActionType : Int, CaseIterable {
     case Batch = 0      // 批量处理
     case ConvertPDF     // 转换PDF
     case ImageToPDF     // 图片转PDF

+ 5 - 5
PDF Office/PDF Master/Class/Home/ViewController/KMFastToolCollectionViewItem.xib

@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="21701" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22155" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
     <dependencies>
         <deployment identifier="macosx"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21701"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22155"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
     <objects>
@@ -43,7 +43,7 @@
                                 </constraints>
                                 <imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="KMHomeFastToolBatch" id="nx5-26-1QI"/>
                             </imageView>
-                            <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="qVZ-dA-Abp">
+                            <textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="qVZ-dA-Abp">
                                 <rect key="frame" x="58" y="71" width="156" height="19"/>
                                 <textFieldCell key="cell" lineBreakMode="clipping" title="Label" id="kCy-le-pux">
                                     <font key="font" metaFont="system" size="16"/>
@@ -51,7 +51,7 @@
                                     <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
                                 </textFieldCell>
                             </textField>
-                            <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Mun-eL-flY">
+                            <textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Mun-eL-flY">
                                 <rect key="frame" x="14" y="14" width="200" height="40"/>
                                 <constraints>
                                     <constraint firstAttribute="height" constant="40" id="DYh-wg-zW1"/>
@@ -68,7 +68,7 @@
                                     <rect key="frame" x="0.0" y="0.0" width="33" height="14"/>
                                     <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                                     <subviews>
-                                        <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="5R2-cg-5CN">
+                                        <textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="5R2-cg-5CN">
                                             <rect key="frame" x="-2" y="-1" width="37" height="16"/>
                                             <textFieldCell key="cell" lineBreakMode="clipping" alignment="center" title="add" id="wp5-o2-BpP">
                                                 <font key="font" usesAppearanceFont="YES"/>

+ 9 - 8
PDF Office/PDF Master/Class/Home/ViewController/KMHistoryFileCollectionViewItem.xib

@@ -1,7 +1,8 @@
 <?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">
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22155" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
     <dependencies>
-        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21507"/>
+        <deployment identifier="macosx"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22155"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
     <objects>
@@ -39,14 +40,14 @@
                                         </imageView>
                                         <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="aI1-x1-Rrt">
                                             <rect key="frame" x="203" y="155" width="16" height="22"/>
-                                            <constraints>
-                                                <constraint firstAttribute="width" constant="16" id="GvL-SF-NNB"/>
-                                                <constraint firstAttribute="height" constant="16" id="je1-2J-vPy"/>
-                                            </constraints>
                                             <buttonCell key="cell" type="bevel" title="Button" bezelStyle="rounded" image="NSActionTemplate" imagePosition="only" alignment="center" imageScaling="proportionallyDown" inset="2" id="xih-IJ-6Lu">
                                                 <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
                                                 <font key="font" metaFont="system"/>
                                             </buttonCell>
+                                            <constraints>
+                                                <constraint firstAttribute="width" constant="16" id="GvL-SF-NNB"/>
+                                                <constraint firstAttribute="height" constant="16" id="je1-2J-vPy"/>
+                                            </constraints>
                                             <connections>
                                                 <action selector="favoriteButtonAction:" target="-2" id="Woj-0j-TND"/>
                                             </connections>
@@ -66,7 +67,7 @@
                                     <constraint firstAttribute="height" constant="180" id="w3o-wZ-CNv"/>
                                 </constraints>
                             </box>
-                            <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="lue-CR-EiO">
+                            <textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="lue-CR-EiO">
                                 <rect key="frame" x="-2" y="68" width="232" height="16"/>
                                 <textFieldCell key="cell" truncatesLastVisibleLine="YES" alignment="center" title="文档名称" id="qE9-hu-gK4">
                                     <font key="font" usesAppearanceFont="YES"/>
@@ -98,6 +99,6 @@
         </customView>
     </objects>
     <resources>
-        <image name="NSActionTemplate" width="15" height="15"/>
+        <image name="NSActionTemplate" width="20" height="20"/>
     </resources>
 </document>

+ 6 - 6
PDF Office/PDF Master/Class/Home/ViewController/KMHomeFastToolViewController.xib

@@ -1,8 +1,8 @@
 <?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">
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22155" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
     <dependencies>
         <deployment identifier="macosx"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21507"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22155"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
     <objects>
@@ -31,7 +31,7 @@
                         <rect key="frame" x="0.0" y="0.0" width="66" height="28"/>
                         <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                         <subviews>
-                            <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="oSa-X8-Fv6">
+                            <textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="oSa-X8-Fv6">
                                 <rect key="frame" x="-2" y="5" width="70" height="19"/>
                                 <textFieldCell key="cell" lineBreakMode="clipping" title="快捷工具" id="3bM-rD-uSs">
                                     <font key="font" metaFont="system" size="16"/>
@@ -84,11 +84,11 @@
                             <scrollView wantsLayer="YES" borderType="none" horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" hasVerticalScroller="NO" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="uso-UI-yCw">
                                 <rect key="frame" x="0.0" y="0.0" width="662" height="328"/>
                                 <clipView key="contentView" drawsBackground="NO" copiesOnScroll="NO" id="5Kk-ea-dV6">
-                                    <rect key="frame" x="0.0" y="0.0" width="662" height="328"/>
+                                    <rect key="frame" x="0.0" y="0.0" width="662" height="313"/>
                                     <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                                     <subviews>
                                         <collectionView selectable="YES" id="uRS-jl-d4p" customClass="KMFastToolCollectionView" customModule="PDF_Master" customModuleProvider="target">
-                                            <rect key="frame" x="0.0" y="0.0" width="662" height="328"/>
+                                            <rect key="frame" x="0.0" y="0.0" width="662" height="313"/>
                                             <autoresizingMask key="autoresizingMask" heightSizable="YES"/>
                                             <collectionViewFlowLayout key="collectionViewLayout" minimumInteritemSpacing="10" minimumLineSpacing="10" scrollDirection="horizontal" id="ISw-7m-91E">
                                                 <size key="itemSize" width="50" height="50"/>
@@ -103,7 +103,7 @@
                                     <color key="backgroundColor" red="1" green="0.99843658091226151" blue="0.99619259258638859" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
                                 </clipView>
                                 <scroller key="horizontalScroller" wantsLayer="YES" verticalHuggingPriority="750" horizontal="YES" id="sRD-Yg-vn1" customClass="KMToolSetScroller" customModule="PDF_Master" customModuleProvider="target">
-                                    <rect key="frame" x="0.0" y="312" width="662" height="16"/>
+                                    <rect key="frame" x="0.0" y="313" width="662" height="15"/>
                                     <autoresizingMask key="autoresizingMask"/>
                                 </scroller>
                                 <scroller key="verticalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" doubleValue="1" horizontal="NO" id="lpk-Q5-DdG">

+ 13 - 13
PDF Office/PDF Master/Class/Home/ViewController/KMHomeHistoryFileViewController.xib

@@ -1,8 +1,8 @@
 <?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">
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22155" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
     <dependencies>
         <deployment identifier="macosx"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21507"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22155"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
     <objects>
@@ -56,7 +56,7 @@
                                             </constraints>
                                             <imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" id="KOq-0P-sP7"/>
                                         </imageView>
-                                        <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="itC-bM-NsD">
+                                        <textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="itC-bM-NsD">
                                             <rect key="frame" x="-2" y="18" width="665" height="16"/>
                                             <textFieldCell key="cell" alignment="center" title="Label" id="U1g-Yg-acv">
                                                 <font key="font" metaFont="system"/>
@@ -64,7 +64,7 @@
                                                 <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
                                             </textFieldCell>
                                         </textField>
-                                        <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="TPr-pg-J3o">
+                                        <textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="TPr-pg-J3o">
                                             <rect key="frame" x="-2" y="0.0" width="665" height="16"/>
                                             <textFieldCell key="cell" alignment="center" title="Label" id="LXV-F0-Kpc">
                                                 <font key="font" metaFont="system"/>
@@ -131,7 +131,7 @@
                         <rect key="frame" x="0.0" y="0.0" width="54" height="28"/>
                         <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                         <subviews>
-                            <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Gz5-CK-8t7">
+                            <textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Gz5-CK-8t7">
                                 <rect key="frame" x="-2" y="6" width="58" height="16"/>
                                 <textFieldCell key="cell" lineBreakMode="clipping" title="最近打开" id="9hO-pC-qyS">
                                     <font key="font" usesAppearanceFont="YES"/>
@@ -307,7 +307,7 @@
                                                                                 </constraints>
                                                                                 <imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" id="gl5-8t-bO5"/>
                                                                             </imageView>
-                                                                            <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="puB-4O-CjH">
+                                                                            <textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="puB-4O-CjH">
                                                                                 <rect key="frame" x="449" y="30" width="110" height="16"/>
                                                                                 <constraints>
                                                                                     <constraint firstAttribute="width" constant="106" id="7NU-ee-KGa"/>
@@ -318,7 +318,7 @@
                                                                                     <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
                                                                                 </textFieldCell>
                                                                             </textField>
-                                                                            <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="vh7-Qm-ZYX">
+                                                                            <textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="vh7-Qm-ZYX">
                                                                                 <rect key="frame" x="173" y="30" width="264" height="16"/>
                                                                                 <constraints>
                                                                                     <constraint firstAttribute="width" constant="260" id="0N6-Kd-s2c"/>
@@ -331,14 +331,14 @@
                                                                             </textField>
                                                                             <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="LlT-U5-9ck">
                                                                                 <rect key="frame" x="573" y="30" width="16" height="16"/>
-                                                                                <constraints>
-                                                                                    <constraint firstAttribute="width" constant="16" id="onN-E5-GUa"/>
-                                                                                    <constraint firstAttribute="height" constant="16" id="py5-ca-3rH"/>
-                                                                                </constraints>
                                                                                 <buttonCell key="cell" type="bevel" title="Button" bezelStyle="rounded" image="icon_btn_more_false_false" imagePosition="only" alignment="center" imageScaling="proportionallyDown" inset="2" id="TvJ-sI-i3v">
                                                                                     <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
                                                                                     <font key="font" metaFont="system"/>
                                                                                 </buttonCell>
+                                                                                <constraints>
+                                                                                    <constraint firstAttribute="width" constant="16" id="onN-E5-GUa"/>
+                                                                                    <constraint firstAttribute="height" constant="16" id="py5-ca-3rH"/>
+                                                                                </constraints>
                                                                                 <connections>
                                                                                     <action selector="moreButtonAction:" target="kZK-Bs-0PF" id="KgU-oC-kf8"/>
                                                                                 </connections>
@@ -346,7 +346,7 @@
                                                                             <customView translatesAutoresizingMaskIntoConstraints="NO" id="5Mc-aq-fMe">
                                                                                 <rect key="frame" x="68" y="25" width="89" height="26"/>
                                                                                 <subviews>
-                                                                                    <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="91U-Kg-YfD">
+                                                                                    <textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="91U-Kg-YfD">
                                                                                         <rect key="frame" x="-2" y="2" width="93" height="22"/>
                                                                                         <constraints>
                                                                                             <constraint firstAttribute="height" constant="22" id="RnG-se-20f"/>
@@ -357,7 +357,7 @@
                                                                                             <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
                                                                                         </textFieldCell>
                                                                                     </textField>
-                                                                                    <textField hidden="YES" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="yBF-Ah-dXA">
+                                                                                    <textField hidden="YES" focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="yBF-Ah-dXA">
                                                                                         <rect key="frame" x="-2" y="0.0" width="93" height="1"/>
                                                                                         <constraints>
                                                                                             <constraint firstAttribute="height" constant="1" id="YG3-8v-oqS"/>

+ 6 - 0
PDF Office/PDF Master/Class/Home/ViewController/KMHomeViewController.swift

@@ -60,6 +60,8 @@ import Cocoa
     
     @IBOutlet weak var creatPDFView: KMCreatPDFView!
     
+    //HomeContentView
+    @IBOutlet weak var homeContentView: KMHomeContentView!
     //广告 互推
     @IBOutlet weak var advertisementTableView: KMAdvertisementTableView!
     @IBOutlet weak var advertisementTableViewHeightConstraint: NSLayoutConstraint!
@@ -189,6 +191,10 @@ import Cocoa
         self.creatPDFView.creatPDFAction = { [unowned self] view, sender in
             self.creatPDFAction(sender)
         }
+        
+        self.homeContentView.historyDidSelect = { [unowned self] view, url in
+            self.openFile(withFilePath: url)
+        }
     }
     
     // MARK: Init

+ 9 - 1
PDF Office/PDF Master/Class/Home/ViewController/KMHomeViewController.xib

@@ -31,6 +31,7 @@
                 <outlet property="dragView" destination="3Ej-3j-QZ3" id="KI9-gS-ovH"/>
                 <outlet property="fastToolViewController" destination="O3f-x2-y6f" id="QUu-yY-afK"/>
                 <outlet property="historyFileViewController" destination="UcW-Sh-zFW" id="4rg-j2-0qB"/>
+                <outlet property="homeContentView" destination="gve-l2-Bcq" id="5SL-s0-RBk"/>
                 <outlet property="homeRightScrollViewView" destination="Fsd-Oz-v7c" id="AOG-NU-G8N"/>
                 <outlet property="homeSplitView" destination="yVp-SB-ljO" id="zSV-aW-5He"/>
                 <outlet property="leftBox" destination="ndG-c5-lCg" id="Gx0-kb-H6N"/>
@@ -323,7 +324,7 @@ Gw
                                 <rect key="frame" x="0.0" y="0.0" width="803" height="820"/>
                                 <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                                 <subviews>
-                                    <scrollView borderType="none" autohidesScrollers="YES" horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" usesPredominantAxisScrolling="NO" horizontalScrollElasticity="none" verticalScrollElasticity="none" translatesAutoresizingMaskIntoConstraints="NO" id="Fsd-Oz-v7c">
+                                    <scrollView hidden="YES" borderType="none" autohidesScrollers="YES" horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" usesPredominantAxisScrolling="NO" horizontalScrollElasticity="none" verticalScrollElasticity="none" translatesAutoresizingMaskIntoConstraints="NO" id="Fsd-Oz-v7c">
                                         <rect key="frame" x="0.0" y="0.0" width="803" height="820"/>
                                         <clipView key="contentView" drawsBackground="NO" id="4Wb-9e-EKY">
                                             <rect key="frame" x="0.0" y="0.0" width="803" height="820"/>
@@ -387,9 +388,16 @@ Gw
                                             <autoresizingMask key="autoresizingMask"/>
                                         </scroller>
                                     </scrollView>
+                                    <customView translatesAutoresizingMaskIntoConstraints="NO" id="gve-l2-Bcq" customClass="KMHomeContentView" customModule="PDF_Master" customModuleProvider="target">
+                                        <rect key="frame" x="0.0" y="0.0" width="803" height="820"/>
+                                    </customView>
                                 </subviews>
                                 <constraints>
+                                    <constraint firstAttribute="trailing" secondItem="gve-l2-Bcq" secondAttribute="trailing" id="1fY-PK-HV3"/>
+                                    <constraint firstItem="gve-l2-Bcq" firstAttribute="leading" secondItem="GVB-Xu-zsZ" secondAttribute="leading" id="2Kb-Ah-fD1"/>
                                     <constraint firstItem="Fsd-Oz-v7c" firstAttribute="top" secondItem="GVB-Xu-zsZ" secondAttribute="top" id="87S-Rb-bey"/>
+                                    <constraint firstItem="gve-l2-Bcq" firstAttribute="top" secondItem="GVB-Xu-zsZ" secondAttribute="top" id="UW2-JT-Fef"/>
+                                    <constraint firstAttribute="bottom" secondItem="gve-l2-Bcq" secondAttribute="bottom" id="dMX-bL-bAs"/>
                                     <constraint firstAttribute="bottom" secondItem="Fsd-Oz-v7c" secondAttribute="bottom" id="jKH-5n-L9g"/>
                                     <constraint firstItem="Fsd-Oz-v7c" firstAttribute="leading" secondItem="GVB-Xu-zsZ" secondAttribute="leading" id="v17-bP-0x9"/>
                                     <constraint firstAttribute="trailing" secondItem="Fsd-Oz-v7c" secondAttribute="trailing" id="xDo-M4-zHj"/>

+ 11 - 10
PDF Office/PDF Master/Class/Home/WindowController/KMAITranslationConfirmWindowController.xib

@@ -1,7 +1,8 @@
 <?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">
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22155" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
     <dependencies>
-        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21507"/>
+        <deployment identifier="macosx"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22155"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
     <objects>
@@ -49,7 +50,7 @@
                                         <rect key="frame" x="1" y="1" width="76" height="26"/>
                                         <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                                         <subviews>
-                                            <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="deL-QF-z0s">
+                                            <textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="deL-QF-z0s">
                                                 <rect key="frame" x="20" y="5" width="37" height="16"/>
                                                 <textFieldCell key="cell" lineBreakMode="clipping" title="Label" id="FIx-7a-CCI">
                                                     <font key="font" usesAppearanceFont="YES"/>
@@ -88,7 +89,7 @@
                                         <rect key="frame" x="1" y="1" width="76" height="26"/>
                                         <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                                         <subviews>
-                                            <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="nFO-mt-ZB4">
+                                            <textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="nFO-mt-ZB4">
                                                 <rect key="frame" x="20" y="5" width="37" height="16"/>
                                                 <textFieldCell key="cell" lineBreakMode="clipping" title="Label" id="UTP-2e-VlX">
                                                     <font key="font" usesAppearanceFont="YES"/>
@@ -138,7 +139,7 @@
                     <customView translatesAutoresizingMaskIntoConstraints="NO" id="iMz-Q5-D6R">
                         <rect key="frame" x="16" y="226" width="596" height="50"/>
                         <subviews>
-                            <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="aq8-Ah-UWm">
+                            <textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="aq8-Ah-UWm">
                                 <rect key="frame" x="-2" y="17" width="600" height="16"/>
                                 <textFieldCell key="cell" alignment="left" title="Label" id="F7x-HZ-dOf">
                                     <font key="font" usesAppearanceFont="YES"/>
@@ -167,7 +168,7 @@
                             <customView translatesAutoresizingMaskIntoConstraints="NO" id="wV9-Le-UHj">
                                 <rect key="frame" x="122" y="0.0" width="474" height="162"/>
                                 <subviews>
-                                    <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="zlV-ti-gJ9">
+                                    <textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="zlV-ti-gJ9">
                                         <rect key="frame" x="-2" y="146" width="478" height="16"/>
                                         <textFieldCell key="cell" lineBreakMode="clipping" title="Label" id="ken-B3-K7v">
                                             <font key="font" usesAppearanceFont="YES"/>
@@ -181,7 +182,7 @@
                                             <rect key="frame" x="1" y="1" width="219" height="30"/>
                                             <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                                             <subviews>
-                                                <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Rva-eU-GRw">
+                                                <textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Rva-eU-GRw">
                                                     <rect key="frame" x="6" y="7" width="189" height="16"/>
                                                     <textFieldCell key="cell" lineBreakMode="clipping" title="Label" id="0g8-wy-2we">
                                                         <font key="font" usesAppearanceFont="YES"/>
@@ -246,7 +247,7 @@
                                                     </constraints>
                                                     <imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="icon_btn_arrow_gray_down_s_norm_false" id="8cp-o3-LWj"/>
                                                 </imageView>
-                                                <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="nfg-7P-9zD">
+                                                <textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="nfg-7P-9zD">
                                                     <rect key="frame" x="6" y="7" width="189" height="16"/>
                                                     <textFieldCell key="cell" lineBreakMode="clipping" title="Label" id="CJ2-nQ-Ths">
                                                         <font key="font" usesAppearanceFont="YES"/>
@@ -292,7 +293,7 @@
                                                 </constraints>
                                                 <imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="image_btn_tips" id="yV6-OA-rAL"/>
                                             </imageView>
-                                            <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="7Ui-Xy-UA6">
+                                            <textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="7Ui-Xy-UA6">
                                                 <rect key="frame" x="18" y="2" width="458" height="16"/>
                                                 <textFieldCell key="cell" lineBreakMode="clipping" title="Label" id="ao3-xG-chl">
                                                     <font key="font" metaFont="system"/>
@@ -321,7 +322,7 @@
                                                 </constraints>
                                                 <imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="image_btn_tips" id="Eu3-jj-OHz"/>
                                             </imageView>
-                                            <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="pdX-rR-ESN">
+                                            <textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="pdX-rR-ESN">
                                                 <rect key="frame" x="18" y="0.0" width="458" height="70"/>
                                                 <textFieldCell key="cell" title="Label" id="t5Z-wu-5ot">
                                                     <font key="font" metaFont="system"/>

+ 29 - 28
PDF Office/PDF Master/Class/Home/WindowController/KMAITranslationWindowController.xib

@@ -1,7 +1,8 @@
 <?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">
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22155" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
     <dependencies>
-        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21507"/>
+        <deployment identifier="macosx"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22155"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
     <objects>
@@ -44,7 +45,7 @@
                 <rect key="frame" x="0.0" y="0.0" width="588" height="343"/>
                 <autoresizingMask key="autoresizingMask"/>
                 <subviews>
-                    <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="0Om-aJ-sAu">
+                    <textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="0Om-aJ-sAu">
                         <rect key="frame" x="14" y="256" width="154" height="16"/>
                         <constraints>
                             <constraint firstAttribute="width" constant="150" id="enB-Az-ZLZ"/>
@@ -69,7 +70,7 @@
                             <rect key="frame" x="1" y="1" width="177" height="38"/>
                             <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                             <subviews>
-                                <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="WqQ-Zq-YmZ">
+                                <textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="WqQ-Zq-YmZ">
                                     <rect key="frame" x="14" y="11" width="133" height="16"/>
                                     <textFieldCell key="cell" lineBreakMode="clipping" title="Label" id="UG2-nF-ECS">
                                         <font key="font" usesAppearanceFont="YES"/>
@@ -126,7 +127,7 @@
                                     </constraints>
                                     <imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="icon_btn_arrow_gray_down_s_norm_false" id="VHi-NG-0v5"/>
                                 </imageView>
-                                <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="CSz-xA-SxI">
+                                <textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="CSz-xA-SxI">
                                     <rect key="frame" x="14" y="11" width="133" height="16"/>
                                     <textFieldCell key="cell" lineBreakMode="clipping" title="Label" id="l7v-Rp-PN4">
                                         <font key="font" usesAppearanceFont="YES"/>
@@ -167,7 +168,7 @@
                             <rect key="frame" x="1" y="1" width="268" height="178"/>
                             <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                             <subviews>
-                                <textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="hdM-Q0-JDl">
+                                <textField focusRingType="none" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="hdM-Q0-JDl">
                                     <rect key="frame" x="18" y="16" width="232" height="146"/>
                                     <textFieldCell key="cell" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" id="hLa-1M-WD4">
                                         <font key="font" metaFont="system"/>
@@ -178,7 +179,7 @@
                                         <outlet property="delegate" destination="-2" id="rAU-a1-LDX"/>
                                     </connections>
                                 </textField>
-                                <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="roT-Vm-vRn">
+                                <textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="roT-Vm-vRn">
                                     <rect key="frame" x="221" y="8" width="37" height="16"/>
                                     <textFieldCell key="cell" lineBreakMode="clipping" title="Label" id="BCa-6w-gQj">
                                         <font key="font" usesAppearanceFont="YES"/>
@@ -252,7 +253,7 @@
                                             </constraints>
                                             <imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" id="sao-NL-irT"/>
                                         </imageView>
-                                        <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="sSR-RP-4JK">
+                                        <textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="sSR-RP-4JK">
                                             <rect key="frame" x="18" y="146" width="236" height="16"/>
                                             <textFieldCell key="cell" title="Label" id="5Hn-wR-mC6">
                                                 <font key="font" metaFont="system"/>
@@ -295,7 +296,7 @@
                             <rect key="frame" x="0.0" y="0.0" width="97" height="24"/>
                             <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                             <subviews>
-                                <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="GAn-bi-jA2">
+                                <textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="GAn-bi-jA2">
                                     <rect key="frame" x="30" y="4" width="37" height="16"/>
                                     <textFieldCell key="cell" lineBreakMode="clipping" title="Label" id="bX0-0T-yRv">
                                         <font key="font" usesAppearanceFont="YES"/>
@@ -334,7 +335,7 @@
                             <rect key="frame" x="0.0" y="0.0" width="97" height="24"/>
                             <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                             <subviews>
-                                <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="p7M-Ry-WqB">
+                                <textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="p7M-Ry-WqB">
                                     <rect key="frame" x="30" y="4" width="37" height="16"/>
                                     <textFieldCell key="cell" lineBreakMode="clipping" title="Label" id="Jr1-ms-0zG">
                                         <font key="font" usesAppearanceFont="YES"/>
@@ -373,7 +374,7 @@
                             <rect key="frame" x="0.0" y="0.0" width="588" height="50"/>
                             <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                             <subviews>
-                                <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="f5X-7w-lzl">
+                                <textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="f5X-7w-lzl">
                                     <rect key="frame" x="98" y="17" width="37" height="16"/>
                                     <textFieldCell key="cell" lineBreakMode="clipping" title="Label" id="fbW-8e-acd">
                                         <font key="font" usesAppearanceFont="YES"/>
@@ -381,16 +382,16 @@
                                         <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
                                     </textFieldCell>
                                 </textField>
-                                <button verticalHuggingPriority="750" imageHugsTitle="YES" translatesAutoresizingMaskIntoConstraints="NO" id="YZR-Hn-fi0">
+                                <button imageHugsTitle="YES" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="YZR-Hn-fi0">
                                     <rect key="frame" x="137" y="17" width="16" height="16"/>
-                                    <constraints>
-                                        <constraint firstAttribute="height" constant="16" id="ZnO-ex-r7r"/>
-                                        <constraint firstAttribute="width" constant="16" id="zSz-ja-uLb"/>
-                                    </constraints>
                                     <buttonCell key="cell" type="bevel" bezelStyle="rounded" image="image_btn_tips" imagePosition="only" alignment="center" imageScaling="proportionallyDown" inset="2" id="ZYQ-5T-eyl">
                                         <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
                                         <font key="font" metaFont="system"/>
                                     </buttonCell>
+                                    <constraints>
+                                        <constraint firstAttribute="height" constant="16" id="ZnO-ex-r7r"/>
+                                        <constraint firstAttribute="width" constant="16" id="zSz-ja-uLb"/>
+                                    </constraints>
                                     <connections>
                                         <action selector="tipsButtonAction:" target="-2" id="uEQ-Q1-e4g"/>
                                     </connections>
@@ -411,39 +412,39 @@
                                         </box>
                                         <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="ZOC-Aw-6KM">
                                             <rect key="frame" x="16" y="14" width="12" height="12"/>
-                                            <constraints>
-                                                <constraint firstAttribute="height" constant="12" id="a4H-40-9Uj"/>
-                                                <constraint firstAttribute="width" constant="12" id="vkQ-6b-9SB"/>
-                                            </constraints>
                                             <buttonCell key="cell" type="square" bezelStyle="shadowlessSquare" image="icon_btn_window_close" imagePosition="only" alignment="center" imageScaling="proportionallyDown" inset="2" id="xpR-Cp-ha8">
                                                 <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
                                                 <font key="font" metaFont="system"/>
                                             </buttonCell>
+                                            <constraints>
+                                                <constraint firstAttribute="height" constant="12" id="a4H-40-9Uj"/>
+                                                <constraint firstAttribute="width" constant="12" id="vkQ-6b-9SB"/>
+                                            </constraints>
                                             <connections>
                                                 <action selector="closeButtonAction:" target="-2" id="6Ai-Bp-mkK"/>
                                             </connections>
                                         </button>
                                         <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="cad-Hf-ffb">
                                             <rect key="frame" x="36" y="14" width="12" height="12"/>
-                                            <constraints>
-                                                <constraint firstAttribute="height" constant="12" id="TBm-QM-cwh"/>
-                                                <constraint firstAttribute="width" constant="12" id="Zx7-ky-pv7"/>
-                                            </constraints>
                                             <buttonCell key="cell" type="square" bezelStyle="shadowlessSquare" image="icon_groping_default" imagePosition="only" alignment="center" imageScaling="proportionallyDown" inset="2" id="4rY-Hh-ylK">
                                                 <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
                                                 <font key="font" metaFont="system"/>
                                             </buttonCell>
+                                            <constraints>
+                                                <constraint firstAttribute="height" constant="12" id="TBm-QM-cwh"/>
+                                                <constraint firstAttribute="width" constant="12" id="Zx7-ky-pv7"/>
+                                            </constraints>
                                         </button>
                                         <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="IxO-9g-nPH">
                                             <rect key="frame" x="56" y="14" width="12" height="12"/>
-                                            <constraints>
-                                                <constraint firstAttribute="height" constant="12" id="6ma-3Z-P0K"/>
-                                                <constraint firstAttribute="width" constant="12" id="joB-Lk-3dV"/>
-                                            </constraints>
                                             <buttonCell key="cell" type="square" bezelStyle="shadowlessSquare" image="icon_groping_default" imagePosition="only" alignment="center" imageScaling="proportionallyDown" inset="2" id="Vab-Th-pen">
                                                 <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
                                                 <font key="font" metaFont="system"/>
                                             </buttonCell>
+                                            <constraints>
+                                                <constraint firstAttribute="height" constant="12" id="6ma-3Z-P0K"/>
+                                                <constraint firstAttribute="width" constant="12" id="joB-Lk-3dV"/>
+                                            </constraints>
                                         </button>
                                     </subviews>
                                     <constraints>

+ 4 - 3
PDF Office/PDF Master/Class/Home/WindowController/KMHistoryFileDeleteWindowController.xib

@@ -1,7 +1,8 @@
 <?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">
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22155" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
     <dependencies>
-        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21507"/>
+        <deployment identifier="macosx"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22155"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
     <objects>
@@ -24,7 +25,7 @@
                 <rect key="frame" x="0.0" y="0.0" width="260" height="213"/>
                 <autoresizingMask key="autoresizingMask"/>
                 <subviews>
-                    <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="pp4-jZ-PBy">
+                    <textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="pp4-jZ-PBy">
                         <rect key="frame" x="14" y="93" width="232" height="16"/>
                         <constraints>
                             <constraint firstAttribute="width" constant="228" id="SGg-Fg-WbD"/>

+ 1 - 1
PDF Office/PDF Master/Class/Home/WindowController/KMURLToPDFWindowController/KMURLToPDFWindowController.xib

@@ -261,7 +261,7 @@ Gw
             <connections>
                 <outlet property="delegate" destination="-2" id="0bl-1N-AYu"/>
             </connections>
-            <point key="canvasLocation" x="311" y="255.5"/>
+            <point key="canvasLocation" x="698" y="201"/>
         </window>
     </objects>
 </document>

+ 6 - 0
PDF Office/PDF Master/Class/KMAdvertisement/Source/KMAdvertisement.xcassets/Contents.json

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

+ 23 - 0
PDF Office/PDF Master/Class/KMAdvertisement/Source/KMAdvertisement.xcassets/ad_cancel_button00.imageset/Contents.json

@@ -0,0 +1,23 @@
+{
+  "images" : [
+    {
+      "filename" : "ad_cancel_button00.png",
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "filename" : "ad_cancel_button00@2x.png",
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "filename" : "ad_cancel_button00@3x.png",
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
PDF Office/PDF Master/Class/KMAdvertisement/Source/KMAdvertisement.xcassets/ad_cancel_button00.imageset/ad_cancel_button00.png


BIN
PDF Office/PDF Master/Class/KMAdvertisement/Source/KMAdvertisement.xcassets/ad_cancel_button00.imageset/ad_cancel_button00@2x.png


BIN
PDF Office/PDF Master/Class/KMAdvertisement/Source/KMAdvertisement.xcassets/ad_cancel_button00.imageset/ad_cancel_button00@3x.png


+ 1 - 1
PDF Office/PDF Master/Class/KMAdvertisement/View/Tableview/KMAdvertisementTableView.swift

@@ -89,7 +89,7 @@ typealias KMAdvertisementTableViewDidSelect = (_ view: KMAdvertisementTableView,
         //注册cell
         self.collectionView.register(KMAdvertisementCollectionViewItem.self, forItemWithIdentifier: NSUserInterfaceItemIdentifier(rawValue: "KMAdvertisementCollectionViewItem"))
         
-        self.backgroundColor(KMAppearance.Layout.l0Color())
+//        self.backgroundColor(KMAppearance.Layout.l0Color())
     }
     
     func reloadData() {

+ 2 - 2
PDF Office/PDF Master/Class/KMAdvertisement/View/View/KMAdvertisementShowView.swift

@@ -53,7 +53,7 @@ class KMAdvertisementShowView: NSView {
     }
     
     func setup() {
-        self.backgroundColor(NSColor.black)
+//        self.backgroundColor(NSColor.black)
     }
     
     func reloadData() {
@@ -66,6 +66,6 @@ class KMAdvertisementShowView: NSView {
     }
     
     @IBAction func closeButtonAction(_ sender: Any) {
-        
+        self.removeFromSuperview()
     }
 }

+ 4 - 4
PDF Office/PDF Master/Class/KMLightMember/Controller/ComparativeTable/View/ComparativeView/KMComparativeOutlineView.xib

@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="21701" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22155" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
     <dependencies>
         <deployment identifier="macosx"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21701"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22155"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
     <objects>
@@ -70,7 +70,7 @@
                         <customView translatesAutoresizingMaskIntoConstraints="NO" id="Day-pV-XEE">
                             <rect key="frame" x="646" y="16" width="126" height="22"/>
                             <subviews>
-                                <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="1Wx-Ri-paS">
+                                <textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="1Wx-Ri-paS">
                                     <rect key="frame" x="28" y="3" width="70" height="16"/>
                                     <textFieldCell key="cell" lineBreakMode="clipping" title="Registered" id="tEL-FU-hD1">
                                         <font key="font" usesAppearanceFont="YES"/>
@@ -89,7 +89,7 @@
                         <customView translatesAutoresizingMaskIntoConstraints="NO" id="IbW-xH-P0o">
                             <rect key="frame" x="520" y="16" width="126" height="22"/>
                             <subviews>
-                                <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="v3A-gL-7XA">
+                                <textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="v3A-gL-7XA">
                                     <rect key="frame" x="22" y="3" width="83" height="16"/>
                                     <textFieldCell key="cell" lineBreakMode="clipping" title="Unregistered" id="kIf-38-Jua">
                                         <font key="font" usesAppearanceFont="YES"/>

+ 6 - 6
PDF Office/PDF Master/Class/KMLightMember/Controller/ComparativeTable/View/ComparativeView/View/KMComparativeOutlineCell.xib

@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="21701" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22155" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
     <dependencies>
         <deployment identifier="macosx"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21701"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22155"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
     <objects>
@@ -24,7 +24,7 @@
             <rect key="frame" x="0.0" y="0.0" width="784" height="44"/>
             <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
             <subviews>
-                <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="u22-yU-gpo">
+                <textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="u22-yU-gpo">
                     <rect key="frame" x="6" y="14" width="394" height="16"/>
                     <textFieldCell key="cell" lineBreakMode="clipping" title="Label" id="Oah-fo-Tas">
                         <font key="font" usesAppearanceFont="YES"/>
@@ -43,7 +43,7 @@
                             </constraints>
                             <imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="icon_comparative_hook" id="gbd-gH-Kp4"/>
                         </imageView>
-                        <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="NrT-Ja-To6">
+                        <textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="NrT-Ja-To6">
                             <rect key="frame" x="6" y="15" width="114" height="16"/>
                             <textFieldCell key="cell" lineBreakMode="clipping" alignment="center" title="Label" id="rII-xy-11h">
                                 <font key="font" metaFont="system"/>
@@ -74,7 +74,7 @@
                             </constraints>
                             <imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="icon_comparative_hook" id="zYa-4Q-cE2"/>
                         </imageView>
-                        <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Jzd-Mg-rfa">
+                        <textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Jzd-Mg-rfa">
                             <rect key="frame" x="6" y="15" width="114" height="16"/>
                             <textFieldCell key="cell" alignment="center" title="Label" id="46S-yl-Zwl">
                                 <font key="font" metaFont="system"/>
@@ -105,7 +105,7 @@
                             </constraints>
                             <imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="icon_comparative_hook" id="IYc-dA-3hY"/>
                         </imageView>
-                        <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="kLh-ev-nDz">
+                        <textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="kLh-ev-nDz">
                             <rect key="frame" x="6" y="15" width="114" height="16"/>
                             <textFieldCell key="cell" lineBreakMode="clipping" alignment="center" title="Label" id="oTb-sT-L9u">
                                 <font key="font" metaFont="system"/>

+ 7 - 7
PDF Office/PDF Master/Class/KMLightMember/Controller/ComparativeTable/View/KMComparativeView/KMComparativeView.xib

@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22146" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22155" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
     <dependencies>
         <deployment identifier="macosx"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22146"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22155"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
     <objects>
@@ -79,7 +79,7 @@
                             <rect key="frame" x="40" y="20" width="727" height="20"/>
                             <subviews>
                                 <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="rP2-sO-AA6">
-                                    <rect key="frame" x="384" y="2" width="107" height="16"/>
+                                    <rect key="frame" x="384" y="2" width="106" height="16"/>
                                     <buttonCell key="cell" type="square" title="Terms of Service" bezelStyle="shadowlessSquare" alignment="center" imageScaling="proportionallyDown" inset="2" id="ply-Hb-Jcv">
                                         <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
                                         <font key="font" metaFont="system"/>
@@ -96,7 +96,7 @@
                                     </constraints>
                                 </customView>
                                 <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="hY1-Tk-GCi">
-                                    <rect key="frame" x="254" y="2" width="89" height="16"/>
+                                    <rect key="frame" x="255" y="2" width="88" height="16"/>
                                     <buttonCell key="cell" type="square" title="Privacy Policy" bezelStyle="shadowlessSquare" alignment="center" imageScaling="proportionallyDown" inset="2" id="Z32-Nt-dbF">
                                         <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
                                         <font key="font" metaFont="system"/>
@@ -127,8 +127,8 @@
                                     </constraints>
                                     <imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="Upgrade your plan" id="Qxe-i0-Wsc"/>
                                 </imageView>
-                                <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="MnS-Io-H7L">
-                                    <rect key="frame" x="82" y="8" width="117" height="16"/>
+                                <textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="MnS-Io-H7L">
+                                    <rect key="frame" x="82" y="8" width="116" height="16"/>
                                     <textFieldCell key="cell" lineBreakMode="clipping" title="Upgrade your plan" id="YKh-hc-g1N">
                                         <font key="font" metaFont="system"/>
                                         <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
@@ -146,7 +146,7 @@
                                     </connections>
                                 </button>
                                 <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="t36-hD-ZhM">
-                                    <rect key="frame" x="205" y="8" width="16" height="16"/>
+                                    <rect key="frame" x="204" y="8" width="16" height="16"/>
                                     <buttonCell key="cell" type="square" bezelStyle="shadowlessSquare" image="icon_info" imagePosition="only" alignment="center" imageScaling="proportionallyDown" inset="2" id="bFX-Ce-vIG">
                                         <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
                                         <font key="font" metaFont="system"/>

+ 2 - 2
PDF Office/PDF Master/Class/KMLightMember/Controller/ComparativeTable/View/KMComparativeView/View/KMComparativeViewCollectionItem.xib

@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22146" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22155" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
     <dependencies>
         <deployment identifier="macosx"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22146"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22155"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
     <objects>

+ 3 - 3
PDF Office/PDF Master/Class/KMLightMember/Controller/ComparativeTable/View/KMComparativeView/View/KMComparativeViewCollectionItemItem.xib

@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22146" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22155" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
     <dependencies>
         <deployment identifier="macosx"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22146"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22155"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
     <objects>
@@ -27,7 +27,7 @@
                     </constraints>
                     <imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" id="2Ns-FZ-peU"/>
                 </imageView>
-                <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="77S-IT-dI0">
+                <textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="77S-IT-dI0">
                     <rect key="frame" x="22" y="14" width="264" height="16"/>
                     <textFieldCell key="cell" title="Label" id="6Xk-Wh-SL6">
                         <font key="font" metaFont="system"/>

+ 2 - 2
PDF Office/PDF Master/Class/PDFWindowController/Side/LeftSide/Thumbnail/KMThumbnailViewController.xib

@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22146" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22155" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
     <dependencies>
         <deployment identifier="macosx"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22146"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22155"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
     <objects>

+ 2 - 2
PDF Office/PDF Master/Class/PDFWindowController/Toolbar/KMToolbarItemView.swift

@@ -403,8 +403,8 @@ extension KMToolbarItemView {
         sourcesRect.size = sender.convert(sourcesRect.size, to: nil)
         sourcesRect.origin.y -= 20
         sourcesRect.size.height += 20
-        self.window?.setPopover(self.popOver)
-        self.window?.setSourcesRect(sourcesRect)
+        self.window?.km_setPopover(self.popOver)
+        self.window?.km_setSourcesRect(sourcesRect)
         
         self.popOver?.show(relativeTo: CGRectInset(self.bounds, 0, 5), of: self, preferredEdge: .maxY)
     }