Browse Source

【BOTA】undo/redo 注释、书签 完善

lizhe 2 years ago
parent
commit
dc82941219
30 changed files with 2159 additions and 112 deletions
  1. 8 0
      PDF Office/PDF Office.xcodeproj/project.pbxproj
  2. 97 17
      PDF Office/PDF Office.xcodeproj/xcuserdata/lizhe.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
  3. 167 32
      PDF Office/PDF Office/Class/PDFWindowController/Side/LeftSide/Annotation/KMAnnotationViewController.swift
  4. 3 3
      PDF Office/PDF Office/Class/PDFWindowController/Side/LeftSide/Annotation/View/KMAnnotationTableRowView.swift
  5. 6 0
      PDF Office/PDF Office/Class/PDFWindowController/Side/LeftSide/BOTA.xcassets/Contents.json
  6. 21 0
      PDF Office/PDF Office/Class/PDFWindowController/Side/LeftSide/BOTA.xcassets/Selected=false-1.imageset/Contents.json
  7. 184 0
      PDF Office/PDF Office/Class/PDFWindowController/Side/LeftSide/BOTA.xcassets/Selected=false-1.imageset/Selected=false-1.pdf
  8. 21 0
      PDF Office/PDF Office/Class/PDFWindowController/Side/LeftSide/BOTA.xcassets/Selected=false-2.imageset/Contents.json
  9. 93 0
      PDF Office/PDF Office/Class/PDFWindowController/Side/LeftSide/BOTA.xcassets/Selected=false-2.imageset/Selected=false-2.pdf
  10. 21 0
      PDF Office/PDF Office/Class/PDFWindowController/Side/LeftSide/BOTA.xcassets/Selected=false.imageset/Contents.json
  11. 192 0
      PDF Office/PDF Office/Class/PDFWindowController/Side/LeftSide/BOTA.xcassets/Selected=false.imageset/Selected=false.pdf
  12. 21 0
      PDF Office/PDF Office/Class/PDFWindowController/Side/LeftSide/BOTA.xcassets/Selected=true-1.imageset/Contents.json
  13. 204 0
      PDF Office/PDF Office/Class/PDFWindowController/Side/LeftSide/BOTA.xcassets/Selected=true-1.imageset/Selected=true-1.pdf
  14. 21 0
      PDF Office/PDF Office/Class/PDFWindowController/Side/LeftSide/BOTA.xcassets/Selected=true-2.imageset/Contents.json
  15. 93 0
      PDF Office/PDF Office/Class/PDFWindowController/Side/LeftSide/BOTA.xcassets/Selected=true-2.imageset/Selected=true-2.pdf
  16. 21 0
      PDF Office/PDF Office/Class/PDFWindowController/Side/LeftSide/BOTA.xcassets/Selected=true.imageset/Contents.json
  17. 206 0
      PDF Office/PDF Office/Class/PDFWindowController/Side/LeftSide/BOTA.xcassets/Selected=true.imageset/Selected=true.pdf
  18. 21 0
      PDF Office/PDF Office/Class/PDFWindowController/Side/LeftSide/BOTA.xcassets/state=false, Type=Default.imageset/Contents.json
  19. 93 0
      PDF Office/PDF Office/Class/PDFWindowController/Side/LeftSide/BOTA.xcassets/state=false, Type=Default.imageset/state=false, Type=Default.pdf
  20. 21 0
      PDF Office/PDF Office/Class/PDFWindowController/Side/LeftSide/BOTA.xcassets/state=true, Type=arrow.imageset/Contents.json
  21. 78 0
      PDF Office/PDF Office/Class/PDFWindowController/Side/LeftSide/BOTA.xcassets/state=true, Type=arrow.imageset/state=true, Type=arrow.pdf
  22. 21 0
      PDF Office/PDF Office/Class/PDFWindowController/Side/LeftSide/BOTA.xcassets/state=true, Type=cricle.imageset/Contents.json
  23. 77 0
      PDF Office/PDF Office/Class/PDFWindowController/Side/LeftSide/BOTA.xcassets/state=true, Type=cricle.imageset/state=true, Type=cricle.pdf
  24. 21 0
      PDF Office/PDF Office/Class/PDFWindowController/Side/LeftSide/BOTA.xcassets/state=true, Type=line.imageset/Contents.json
  25. 71 0
      PDF Office/PDF Office/Class/PDFWindowController/Side/LeftSide/BOTA.xcassets/state=true, Type=line.imageset/state=true, Type=line.pdf
  26. 21 0
      PDF Office/PDF Office/Class/PDFWindowController/Side/LeftSide/BOTA.xcassets/state=true, Type=rectangle.imageset/Contents.json
  27. 81 0
      PDF Office/PDF Office/Class/PDFWindowController/Side/LeftSide/BOTA.xcassets/state=true, Type=rectangle.imageset/state=true, Type=rectangle.pdf
  28. 21 0
      PDF Office/PDF Office/Class/PDFWindowController/Side/LeftSide/BOTA.xcassets/text.imageset/Contents.json
  29. 89 0
      PDF Office/PDF Office/Class/PDFWindowController/Side/LeftSide/BOTA.xcassets/text.imageset/text.pdf
  30. 165 60
      PDF Office/PDF Office/Class/PDFWindowController/Side/LeftSide/BookMarks/KMBookMarkViewController.swift

+ 8 - 0
PDF Office/PDF Office.xcodeproj/project.pbxproj

@@ -1484,6 +1484,9 @@
 		ADCFFC0229C004AD007D3657 /* KMBookMarkTableRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADCFFC0129C004AD007D3657 /* KMBookMarkTableRowView.swift */; };
 		ADCFFC0329C004AD007D3657 /* KMBookMarkTableRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADCFFC0129C004AD007D3657 /* KMBookMarkTableRowView.swift */; };
 		ADCFFC0429C004AD007D3657 /* KMBookMarkTableRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADCFFC0129C004AD007D3657 /* KMBookMarkTableRowView.swift */; };
+		ADCFFC0629C04617007D3657 /* BOTA.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = ADCFFC0529C04617007D3657 /* BOTA.xcassets */; };
+		ADCFFC0729C04617007D3657 /* BOTA.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = ADCFFC0529C04617007D3657 /* BOTA.xcassets */; };
+		ADCFFC0829C04617007D3657 /* BOTA.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = ADCFFC0529C04617007D3657 /* BOTA.xcassets */; };
 		ADD1B6A529416FE800C3FFF7 /* KMOCRPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADD1B6A429416FE800C3FFF7 /* KMOCRPresenter.swift */; };
 		ADD1B6A629416FE800C3FFF7 /* KMOCRPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADD1B6A429416FE800C3FFF7 /* KMOCRPresenter.swift */; };
 		ADD1B6A729416FE800C3FFF7 /* KMOCRPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADD1B6A429416FE800C3FFF7 /* KMOCRPresenter.swift */; };
@@ -3667,6 +3670,7 @@
 		ADCB9969292C65EE00B51A03 /* KMGOCROperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KMGOCROperation.m; sourceTree = "<group>"; };
 		ADCB996A292C65EE00B51A03 /* KMGOCRManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KMGOCRManager.h; sourceTree = "<group>"; };
 		ADCFFC0129C004AD007D3657 /* KMBookMarkTableRowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMBookMarkTableRowView.swift; sourceTree = "<group>"; };
+		ADCFFC0529C04617007D3657 /* BOTA.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = BOTA.xcassets; sourceTree = "<group>"; };
 		ADD1B6A429416FE800C3FFF7 /* KMOCRPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMOCRPresenter.swift; sourceTree = "<group>"; };
 		ADD1B6A92941E97F00C3FFF7 /* KMPrintWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMPrintWindowController.swift; sourceTree = "<group>"; };
 		ADD1B6AA2941E97F00C3FFF7 /* KMPrintWindowController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = KMPrintWindowController.xib; sourceTree = "<group>"; };
@@ -4623,6 +4627,7 @@
 		899700EE28F40308009AF911 /* LeftSide */ = {
 			isa = PBXGroup;
 			children = (
+				ADCFFC0529C04617007D3657 /* BOTA.xcassets */,
 				8942F7BE2923670F00389627 /* KMBOTAManagerClass.swift */,
 				8997011D28F41AB8009AF911 /* KMLeftSideViewController.swift */,
 				8997011E28F41AB8009AF911 /* KMLeftSideViewController.xib */,
@@ -8439,6 +8444,7 @@
 				BBAFC84D298519F700D0648E /* KMSavePanelAccessoryController.xib in Resources */,
 				F3A9DC81294309D80074E5D2 /* CPDFListEditAnnotationViewController.xib in Resources */,
 				AD0FA50629A8E61B00EDEB50 /* KMLightMemberAlertView.xib in Resources */,
+				ADCFFC0629C04617007D3657 /* BOTA.xcassets in Resources */,
 				89E4E7852967BF5A002DBA6F /* KMCustomizeStampViewController.xib in Resources */,
 				F359917B292B7B8A000D25DE /* InitialUserDefaults.plist in Resources */,
 				BB8F455A295AA1270037EA22 /* KMHeaderFooterPropertyInfoController.xib in Resources */,
@@ -8790,6 +8796,7 @@
 				9F8539FA2947137500DF644E /* newtab_p.pdf in Resources */,
 				9FBA0EF228FFC716001117AF /* KMHomeFastToolViewController.xib in Resources */,
 				ADB1FE2C297006DF00ED072D /* KMBatchWindowController.xib in Resources */,
+				ADCFFC0729C04617007D3657 /* BOTA.xcassets in Resources */,
 				ADC075D429875F6A006C752F /* KMBatchConverPDFExcelView.xib in Resources */,
 				AD4B4551294072B90076FA14 /* KMOCRWindowController.xib in Resources */,
 				ADBC2D3B299F0A5A006280C8 /* KMPrintHelpViewController.xib in Resources */,
@@ -9146,6 +9153,7 @@
 				89316827296D73CC0073EA59 /* KMSignatureAnnotationViewController.xib in Resources */,
 				BB24D4AC2977BE6700041659 /* KMRedactConfirmWindowController.xib in Resources */,
 				BB8B17382907B64D001C5EA5 /* CipherTextView.xib in Resources */,
+				ADCFFC0829C04617007D3657 /* BOTA.xcassets in Resources */,
 				8931684E296E436B0073EA59 /* KMSignatureWindowController.xib in Resources */,
 				ADBC2D00299CA6C7006280C8 /* KMPrintDuplexPrintingSetView.xib in Resources */,
 				BB51074429A61B4100978662 /* ProgressSheet.xib in Resources */,

+ 97 - 17
PDF Office/PDF Office.xcodeproj/xcuserdata/lizhe.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist

@@ -568,7 +568,7 @@
                   endingColumnNumber = "9223372036854775807"
                   startingLineNumber = "110"
                   endingLineNumber = "110"
-                  offsetFromSymbolStart = "136">
+                  offsetFromSymbolStart = "208">
                </Location>
                <Location
                   uuid = "DF4DEFF7-844C-478B-A7AE-F924608F4C76 - be1aa5fb8c646c1f"
@@ -598,7 +598,7 @@
                   endingColumnNumber = "9223372036854775807"
                   startingLineNumber = "110"
                   endingLineNumber = "110"
-                  offsetFromSymbolStart = "136">
+                  offsetFromSymbolStart = "208">
                </Location>
                <Location
                   uuid = "DF4DEFF7-844C-478B-A7AE-F924608F4C76 - 646f0dcd318367a0"
@@ -1206,7 +1206,7 @@
             endingColumnNumber = "9223372036854775807"
             startingLineNumber = "128"
             endingLineNumber = "128"
-            landmarkName = "dragPages(_:_:)"
+            landmarkName = "dragPagesForDescSort(_:_:)"
             landmarkType = "7">
          </BreakpointContent>
       </BreakpointProxy>
@@ -2148,10 +2148,42 @@
             filePath = "PDF Office/Class/PDFWindowController/Side/LeftSide/Annotation/KMAnnotationViewController.swift"
             startingColumnNumber = "9223372036854775807"
             endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "332"
-            endingLineNumber = "332"
-            landmarkName = "escButtonAction(_:)"
+            startingLineNumber = "337"
+            endingLineNumber = "337"
+            landmarkName = "PDFViewActiveAnnotationDidChangeNotification(notification:)"
             landmarkType = "7">
+            <Locations>
+               <Location
+                  uuid = "F4C9D987-7AEF-4051-AAA6-97D06F357BC3 - 421fb2a8eca9384c"
+                  shouldBeEnabled = "Yes"
+                  ignoreCount = "0"
+                  continueAfterRunningActions = "No"
+                  symbolName = "PDF_Office.KMAnnotationViewController.PDFViewActiveAnnotationDidChangeNotification(notification: __C.NSNotification) -&gt; ()"
+                  moduleName = "PDF Office"
+                  usesParentBreakpointCondition = "Yes"
+                  urlString = "file:///Volumes/Data/Company/kdan/Projects/PDF%20Office/PDF%20Office/PDF%20Office/Class/PDFWindowController/Side/LeftSide/Annotation/KMAnnotationViewController.swift"
+                  startingColumnNumber = "9223372036854775807"
+                  endingColumnNumber = "9223372036854775807"
+                  startingLineNumber = "337"
+                  endingLineNumber = "337"
+                  offsetFromSymbolStart = "1404">
+               </Location>
+               <Location
+                  uuid = "F4C9D987-7AEF-4051-AAA6-97D06F357BC3 - 421fb2a8eca9384c"
+                  shouldBeEnabled = "Yes"
+                  ignoreCount = "0"
+                  continueAfterRunningActions = "No"
+                  symbolName = "PDF_Office.KMAnnotationViewController.PDFViewActiveAnnotationDidChangeNotification(notification: __C.NSNotification) -&gt; ()"
+                  moduleName = "PDF Office"
+                  usesParentBreakpointCondition = "Yes"
+                  urlString = "file:///Volumes/Data/Company/kdan/Projects/PDF%20Office/PDF%20Office/PDF%20Office/Class/PDFWindowController/Side/LeftSide/Annotation/KMAnnotationViewController.swift"
+                  startingColumnNumber = "9223372036854775807"
+                  endingColumnNumber = "9223372036854775807"
+                  startingLineNumber = "337"
+                  endingLineNumber = "337"
+                  offsetFromSymbolStart = "1500">
+               </Location>
+            </Locations>
          </BreakpointContent>
       </BreakpointProxy>
       <BreakpointProxy
@@ -2164,9 +2196,9 @@
             filePath = "PDF Office/Class/PDFWindowController/Side/LeftSide/Annotation/KMAnnotationViewController.swift"
             startingColumnNumber = "9223372036854775807"
             endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "298"
-            endingLineNumber = "298"
-            landmarkName = "deleteItemAction(_:)"
+            startingLineNumber = "302"
+            endingLineNumber = "302"
+            landmarkName = "importItemAction(_:)"
             landmarkType = "7">
          </BreakpointContent>
       </BreakpointProxy>
@@ -2180,25 +2212,73 @@
             filePath = "PDF Office/Class/PDFWindowController/Side/LeftSide/Annotation/KMAnnotationViewController.swift"
             startingColumnNumber = "9223372036854775807"
             endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "340"
-            endingLineNumber = "340"
-            landmarkName = "tableView(tableView:deleteRowsWithIndexes:)"
+            startingLineNumber = "345"
+            endingLineNumber = "345"
+            landmarkName = "KMAnnotationViewController"
+            landmarkType = "3">
+         </BreakpointContent>
+      </BreakpointProxy>
+      <BreakpointProxy
+         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
+         <BreakpointContent
+            uuid = "CD5ED08D-EEB0-4E64-A098-A44CE83F1349"
+            shouldBeEnabled = "Yes"
+            ignoreCount = "0"
+            continueAfterRunningActions = "No"
+            filePath = "PDF Office/Class/PDFWindowController/Side/LeftSide/BookMarks/KMBookMarkViewController.swift"
+            startingColumnNumber = "9223372036854775807"
+            endingColumnNumber = "9223372036854775807"
+            startingLineNumber = "353"
+            endingLineNumber = "353"
+            landmarkName = "deleteBookMark(bookMarks:)"
             landmarkType = "7">
          </BreakpointContent>
       </BreakpointProxy>
       <BreakpointProxy
          BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
          <BreakpointContent
-            uuid = "ECFC9998-2142-4FBC-93FA-ACCFA6A0DA5E"
+            uuid = "8638ECC5-11BA-4CD8-83BE-AF20337B1D16"
             shouldBeEnabled = "Yes"
             ignoreCount = "0"
             continueAfterRunningActions = "No"
-            filePath = "PDF Office/Class/PDFWindowController/Side/LeftSide/Annotation/View/KMAnnotationTableRowView.swift"
+            filePath = "PDF Office/Class/PDFWindowController/Side/LeftSide/BookMarks/KMBookMarkViewController.swift"
             startingColumnNumber = "9223372036854775807"
             endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "22"
-            endingLineNumber = "22"
-            landmarkName = "drawSelection(in:)"
+            startingLineNumber = "370"
+            endingLineNumber = "370"
+            landmarkName = "addBookMark(bookMarks:)"
+            landmarkType = "7">
+         </BreakpointContent>
+      </BreakpointProxy>
+      <BreakpointProxy
+         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
+         <BreakpointContent
+            uuid = "F1FB2687-EC5B-424F-BEA5-B667AFCB7BC7"
+            shouldBeEnabled = "Yes"
+            ignoreCount = "0"
+            continueAfterRunningActions = "No"
+            filePath = "PDF Office/Class/PDFWindowController/Side/LeftSide/BookMarks/KMBookMarkViewController.swift"
+            startingColumnNumber = "9223372036854775807"
+            endingColumnNumber = "9223372036854775807"
+            startingLineNumber = "403"
+            endingLineNumber = "403"
+            landmarkName = "validateMenuItem(_:)"
+            landmarkType = "7">
+         </BreakpointContent>
+      </BreakpointProxy>
+      <BreakpointProxy
+         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
+         <BreakpointContent
+            uuid = "DB9F4AA6-947F-4725-BB3D-B4590D5C3E8B"
+            shouldBeEnabled = "Yes"
+            ignoreCount = "0"
+            continueAfterRunningActions = "No"
+            filePath = "PDF Office/Class/PDFWindowController/Side/LeftSide/Annotation/KMAnnotationViewController.swift"
+            startingColumnNumber = "9223372036854775807"
+            endingColumnNumber = "9223372036854775807"
+            startingLineNumber = "575"
+            endingLineNumber = "575"
+            landmarkName = "deleteAnnotations(rowIndexs:)"
             landmarkType = "7">
          </BreakpointContent>
       </BreakpointProxy>

+ 167 - 32
PDF Office/PDF Office/Class/PDFWindowController/Side/LeftSide/Annotation/KMAnnotationViewController.swift

@@ -25,6 +25,10 @@ class KMAnnotationViewController: KMSideViewController {
     
     var allAnnotations : [Any] = [Any]()
     let moreMenu = NSMenu()
+    
+    //undo redo
+    private var undoRedoManager: UndoManager = UndoManager()
+    
     //MARK: View
         
     override func viewDidLoad() {
@@ -304,12 +308,13 @@ class KMAnnotationViewController: KMSideViewController {
     
     @IBAction func deleteItemAction(_ sender: NSMenuItem) {
         let selects = sender.representedObject as! NSIndexSet
-        var indexs : [Int] = []
+        var indexs : [KMAnnotationItem] = []
         for index in selects {
-            indexs.append(index)
+            indexs.append(KMAnnotationItem(annoation: CPDFAnnotation(), index: index))
         }
-        indexs.sort(){$0 > $1}
-        self.tableView(tableView: self.tableView, deleteRowsWithIndexes: indexs)
+        indexs.sort(){$0.index > $1.index}
+        
+        self.deleteAnnotations(annotationItems: indexs)
     }
     
     @IBAction func deleteAllAnonationAction(_ sender: NSMenuItem) {
@@ -346,31 +351,31 @@ class KMAnnotationViewController: KMSideViewController {
         return true
     }
 
-    private func tableView(tableView:NSTableView, deleteRowsWithIndexes rowindexs : [Int]) {
-        var removeAnnotations: [Any] = []
-        for index in rowindexs {
-            if index < self.annotations.count {
-                let annotation = self.annotations[index] as? CPDFAnnotation
-                let page = annotation?.page
-                if ((page?.annotations.contains(annotation!)) != nil) {
-                    page?.removeAnnotation(annotation!)
-                } else {
-                    print("不存在")
-                }
-                
-                if self.listView.activeAnnotations.contains(annotation) {
-                    removeAnnotations.append(annotation)
-                }
-            }
-        }
-        
-        if removeAnnotations.count != 0 {
-            self.listView.activeAnnotations.remove(removeAnnotations)
-            self.listView.setNeedsDisplayForVisiblePages()
-        }
-        self.reloadData()
-        self.selectedRowIndexs = []
-    }
+//    private func tableView(tableView:NSTableView, deleteRowsWithIndexes rowindexs : [Int]) {
+//        var removeAnnotations: [Any] = []
+//        for index in rowindexs {
+//            if index < self.annotations.count {
+//                let annotation = self.annotations[index] as? CPDFAnnotation
+//                let page = annotation?.page
+//                if ((page?.annotations.contains(annotation!)) != nil) {
+//                    page?.removeAnnotation(annotation!)
+//                } else {
+//                    print("不存在")
+//                }
+//
+//                if self.listView.activeAnnotations.contains(annotation) {
+//                    removeAnnotations.append(annotation)
+//                }
+//            }
+//        }
+//
+//        if removeAnnotations.count != 0 {
+//            self.listView.activeAnnotations.remove(removeAnnotations)
+//            self.listView.setNeedsDisplayForVisiblePages()
+//        }
+//        self.reloadData()
+//        self.selectedRowIndexs = []
+//    }
     
 }
 
@@ -477,10 +482,10 @@ extension KMAnnotationViewController: NSTableViewDelegate,NSTableViewDataSource
     func tableViewSelectionDidChange(_ notification: Notification) {
         for index in self.selectedRowIndexs {
             if self.tableView.selectedRowIndexes.contains(index) {
-                let rowView: KMAnnotationTableRowView = self.tableView.rowView(atRow: index, makeIfNecessary: false) as! KMAnnotationTableRowView
+                guard let rowView: KMAnnotationTableRowView = self.tableView.rowView(atRow: index, makeIfNecessary: false) as? KMAnnotationTableRowView else { return  }
                 rowView.itemSelect = true
             } else {
-                let rowView: KMAnnotationTableRowView = self.tableView.rowView(atRow: index, makeIfNecessary: false) as! KMAnnotationTableRowView
+                guard let rowView: KMAnnotationTableRowView = self.tableView.rowView(atRow: index, makeIfNecessary: false) as? KMAnnotationTableRowView else { return  }
                 rowView.itemSelect = false
             }
         }
@@ -512,7 +517,26 @@ extension KMAnnotationViewController: NSTableViewDelegate,NSTableViewDataSource
     
 }
 
-extension KMAnnotationViewController : NSMenuDelegate {
+extension KMAnnotationViewController : NSMenuDelegate, NSMenuItemValidation {
+    func validateMenuItem(_ menuItem: NSMenuItem) -> Bool {
+        let action = menuItem.action
+        if (action == #selector(undo)) {
+            return self.undoRedoManager.canUndo
+        }
+        if (action == #selector(redo)) {
+            return self.undoRedoManager.canRedo
+        }
+        
+        if (action == #selector(flattenButtonAction) ||
+            action == #selector(exportItemAction) ||
+            action == #selector(importItemAction)) {
+            if self.tableView.selectedRowIndexes.count != 1 {
+                return false
+            }
+        }
+        return true
+    }
+    
     func menuNeedsUpdate(_ menu: NSMenu) {
         menu.removeAllItems()
         var selectedRowIndexes = self.tableView.selectedRowIndexes
@@ -534,6 +558,7 @@ extension KMAnnotationViewController : NSMenuDelegate {
             item = menu.addItem(withTitle: NSLocalizedString("Export Annotation", comment: ""), action: #selector(exportItemAction), target: self)
             item = menu.addItem(withTitle: NSLocalizedString("Import Annotation", comment: ""), action: #selector(importItemAction), target: self)
             menu.addItem(NSMenuItem.separator())
+
             if self.tableView(tableView: self.tableView, canDeleteRowsWithIndexes: selectedRowIndexes) {
                 item = menu.addItem(withTitle: NSLocalizedString("Delete", comment: ""), action: #selector(deleteItemAction), target: self)
                 item.representedObject = selectedRowIndexes
@@ -543,3 +568,113 @@ extension KMAnnotationViewController : NSMenuDelegate {
         }
     }
 }
+
+//MARK: undo Redo
+extension KMAnnotationViewController {
+    func deleteAnnotations(annotationItems: [KMAnnotationItem]) {
+        var removeAnnotations: [Any] = []
+        var tempAnnotations: [KMAnnotationItem] = []
+        for annotationItem in annotationItems {
+            if annotationItem.index < self.annotations.count {
+                let annotation = self.annotations[annotationItem.index] as? CPDFAnnotation
+                let page = annotation?.page
+                if ((page?.annotations.contains(annotation!)) != nil) {
+                    page?.removeAnnotation(annotation!)
+                } else {
+                    print("不存在")
+                }
+                
+                if self.listView.activeAnnotations.contains(annotation) {
+                    removeAnnotations.append(annotation)
+                }
+                
+                if annotation != nil {
+                    tempAnnotations.append(KMAnnotationItem(annoation: annotation!, index: annotationItem.index))
+                }
+            }
+        }
+        
+        if removeAnnotations.count != 0 {
+            self.listView.activeAnnotations.remove(removeAnnotations)
+            self.listView.setNeedsDisplayForVisiblePages()
+        }
+        self.reloadData()
+        self.tableView.deselectAll(nil)
+        self.selectedRowIndexs = []
+        
+        self.undoRedoManager.registerUndo(withTarget: self) { targetType in
+            self.addAnnotations(annotationItems: tempAnnotations)
+        }
+    }
+    
+    func addAnnotations(annotationItems: [KMAnnotationItem]) {
+        for annotationItem in annotationItems {
+            if !annotationItem.annoation.page.annotations.contains(annotationItem.annoation) {
+                annotationItem.annoation.page.addAnnotation(annotationItem.annoation)
+            }
+            if !self.listView.activeAnnotations.contains(annotationItem.annoation) {
+                self.listView.activeAnnotations.add(annotationItem.annoation)
+            }
+        }
+        
+        self.listView.setNeedsDisplayForVisiblePages()
+        self.reloadData()
+        
+        self.undoRedoManager.registerUndo(withTarget: self) { targetType in
+            self.deleteAnnotations(annotationItems: annotationItems)
+        }
+    }
+//    func tableView(tableView:NSTableView, deleteRowsWithIndexes rowindexs : [Int]) {
+//        var removeAnnotations: [Any] = []
+//        for index in rowindexs {
+//            if index < self.annotations.count {
+//                let annotation = self.annotations[index] as? CPDFAnnotation
+//                let page = annotation?.page
+//                if ((page?.annotations.contains(annotation!)) != nil) {
+//                    page?.removeAnnotation(annotation!)
+//                } else {
+//                    print("不存在")
+//                }
+//
+//                if self.listView.activeAnnotations.contains(annotation) {
+//                    removeAnnotations.append(annotation)
+//                }
+//            }
+//        }
+//
+//        if removeAnnotations.count != 0 {
+//            self.listView.activeAnnotations.remove(removeAnnotations)
+//            self.listView.setNeedsDisplayForVisiblePages()
+//        }
+//        self.reloadData()
+//        self.selectedRowIndexs = []
+//    }
+//    func changeLocation(oldBookMark: KMBookMark, newBookMark: KMBookMark) {
+//        self.listView.document.removeBookmark(forPageIndex: oldBookMark.index)
+//        self.listView.document.addBookmark(newBookMark.label, forPageIndex: newBookMark.index)
+//
+//        self.reloadData()
+//        self.listView.setNeedsDisplayForVisiblePages()
+//
+//        self.undoRedoManager.registerUndo(withTarget: self) { [unowned self] targetType in
+//            self.changeLocation(oldBookMark: newBookMark, newBookMark: oldBookMark)
+//        }
+//    }
+    
+    @IBAction func undo(_ sender: Any) {
+        if (self.undoRedoManager.canUndo) {
+            self.undoRedoManager.undo()
+        }
+    }
+    
+    @IBAction func redo(_ sender: Any) {
+        if (self.undoRedoManager.canRedo) {
+            self.undoRedoManager.redo()
+        }
+    }
+    
+    struct KMAnnotationItem {
+        var annoation: CPDFAnnotation
+        var index: Int
+    }
+}

+ 3 - 3
PDF Office/PDF Office/Class/PDFWindowController/Side/LeftSide/Annotation/View/KMAnnotationTableRowView.swift

@@ -37,7 +37,7 @@ class KMAnnotationTableRowView: NSTableRowView {
             self.box?.wantsLayer = true
             self.box = KMBox(frame: rect)
             self.box?.borderWidth = 1
-            self.box?.borderColor = NSColor(hex: "#CED0D4")
+            self.box?.borderColor = NSColor(hex: "#EDEEF0")
             self.box?.layer?.cornerRadius = 4
             self.box?.boxType = .custom
             self.addSubview(self.box!, positioned: NSWindow.OrderingMode.below, relativeTo: self)
@@ -57,9 +57,9 @@ class KMAnnotationTableRowView: NSTableRowView {
         self.itemSelect = true
     }
     
-    func drawView(_ color: NSColor = NSColor(hex: "#CED0D4", alpha: 0.6)) {
+    func drawView(_ color: NSColor = NSColor(hex: "#EDEEF0")) {
         if hover || itemSelect {
-            self.box?.backgroundColor(NSColor(hex: "#CED0D4", alpha: 0.6))
+            self.box?.backgroundColor(NSColor(hex: "#EDEEF0"))
             self.box?.borderWidth = 1
             self.box?.layer?.cornerRadius = 4
         } else {

+ 6 - 0
PDF Office/PDF Office/Class/PDFWindowController/Side/LeftSide/BOTA.xcassets/Contents.json

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

+ 21 - 0
PDF Office/PDF Office/Class/PDFWindowController/Side/LeftSide/BOTA.xcassets/Selected=false-1.imageset/Contents.json

@@ -0,0 +1,21 @@
+{
+  "images" : [
+    {
+      "filename" : "Selected=false-1.pdf",
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

+ 184 - 0
PDF Office/PDF Office/Class/PDFWindowController/Side/LeftSide/BOTA.xcassets/Selected=false-1.imageset/Selected=false-1.pdf

@@ -0,0 +1,184 @@
+%PDF-1.7
+
+1 0 obj
+  << >>
+endobj
+
+2 0 obj
+  << /Length 3 0 R >>
+stream
+/DeviceRGB CS
+/DeviceRGB cs
+q
+2.041667 18.000000 m
+1.466370 18.000000 1.000000 17.533630 1.000000 16.958332 c
+1.000000 5.041667 l
+1.000000 4.466371 1.466369 4.000000 2.041666 4.000000 c
+4.333252 4.000000 l
+4.333252 1.828411 l
+4.333252 1.445248 4.733045 1.193249 5.078732 1.358517 c
+10.603924 4.000000 l
+17.958334 4.000000 l
+18.533630 4.000000 19.000000 4.466371 19.000000 5.041667 c
+19.000000 16.958334 l
+19.000000 17.533630 18.533630 18.000000 17.958334 18.000000 c
+2.041667 18.000000 l
+h
+W*
+n
+q
+1.000000 0.000000 -0.000000 1.000000 1.000000 1.193253 cm
+0.152941 0.235294 0.384314 scn
+3.333252 2.806747 m
+5.333252 2.806747 l
+5.333252 4.806747 l
+3.333252 4.806747 l
+3.333252 2.806747 l
+h
+4.078732 0.165264 m
+3.216087 1.969660 l
+3.216081 1.969657 l
+4.078732 0.165264 l
+h
+9.603924 2.806747 m
+9.603924 4.806747 l
+9.150425 4.806747 l
+8.741279 4.611143 l
+9.603924 2.806747 l
+h
+2.000000 15.765080 m
+2.000000 15.235808 1.570940 14.806747 1.041667 14.806747 c
+1.041667 18.806747 l
+-0.638200 18.806747 -2.000000 17.444946 -2.000000 15.765080 c
+2.000000 15.765080 l
+h
+2.000000 3.848414 m
+2.000000 15.765080 l
+-2.000000 15.765080 l
+-2.000000 3.848414 l
+2.000000 3.848414 l
+h
+1.041666 4.806747 m
+1.570942 4.806747 2.000000 4.377685 2.000000 3.848414 c
+-2.000000 3.848414 l
+-2.000000 2.168551 -0.638203 0.806747 1.041666 0.806747 c
+1.041666 4.806747 l
+h
+3.333252 4.806747 m
+1.041666 4.806747 l
+1.041666 0.806747 l
+3.333252 0.806747 l
+3.333252 4.806747 l
+h
+5.333252 0.635159 m
+5.333252 2.806747 l
+1.333252 2.806747 l
+1.333252 0.635159 l
+5.333252 0.635159 l
+h
+3.216081 1.969657 m
+4.197843 2.439021 5.333252 1.723334 5.333252 0.635159 c
+1.333252 0.635159 l
+1.333252 -1.219343 3.268246 -2.439030 4.941384 -1.639128 c
+3.216081 1.969657 l
+h
+8.741279 4.611143 m
+3.216087 1.969660 l
+4.941378 -1.639132 l
+10.466569 1.002352 l
+8.741279 4.611143 l
+h
+16.958334 4.806747 m
+9.603924 4.806747 l
+9.603924 0.806747 l
+16.958334 0.806747 l
+16.958334 4.806747 l
+h
+16.000000 3.848414 m
+16.000000 4.377686 16.429058 4.806747 16.958334 4.806747 c
+16.958334 0.806747 l
+18.638203 0.806747 20.000000 2.168550 20.000000 3.848414 c
+16.000000 3.848414 l
+h
+16.000000 15.765080 m
+16.000000 3.848414 l
+20.000000 3.848414 l
+20.000000 15.765080 l
+16.000000 15.765080 l
+h
+16.958334 14.806747 m
+16.429060 14.806747 16.000000 15.235809 16.000000 15.765080 c
+20.000000 15.765080 l
+20.000000 17.444946 18.638201 18.806747 16.958334 18.806747 c
+16.958334 14.806747 l
+h
+1.041667 14.806747 m
+16.958334 14.806747 l
+16.958334 18.806747 l
+1.041667 18.806747 l
+1.041667 14.806747 l
+h
+f
+n
+Q
+Q
+q
+1.000000 0.000000 -0.000000 1.000000 5.000000 10.000000 cm
+0.580392 0.596078 0.611765 scn
+0.000000 2.000000 m
+10.000000 2.000000 l
+10.000000 0.000000 l
+0.000000 0.000000 l
+0.000000 2.000000 l
+h
+f
+n
+Q
+
+endstream
+endobj
+
+3 0 obj
+  2735
+endobj
+
+4 0 obj
+  << /Annots []
+     /Type /Page
+     /MediaBox [ 0.000000 0.000000 20.000000 20.000000 ]
+     /Resources 1 0 R
+     /Contents 2 0 R
+     /Parent 5 0 R
+  >>
+endobj
+
+5 0 obj
+  << /Kids [ 4 0 R ]
+     /Count 1
+     /Type /Pages
+  >>
+endobj
+
+6 0 obj
+  << /Pages 5 0 R
+     /Type /Catalog
+  >>
+endobj
+
+xref
+0 7
+0000000000 65535 f
+0000000010 00000 n
+0000000034 00000 n
+0000002825 00000 n
+0000002848 00000 n
+0000003021 00000 n
+0000003095 00000 n
+trailer
+<< /ID [ (some) (id) ]
+   /Root 6 0 R
+   /Size 7
+>>
+startxref
+3154
+%%EOF

+ 21 - 0
PDF Office/PDF Office/Class/PDFWindowController/Side/LeftSide/BOTA.xcassets/Selected=false-2.imageset/Contents.json

@@ -0,0 +1,21 @@
+{
+  "images" : [
+    {
+      "filename" : "Selected=false-2.pdf",
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

+ 93 - 0
PDF Office/PDF Office/Class/PDFWindowController/Side/LeftSide/BOTA.xcassets/Selected=false-2.imageset/Selected=false-2.pdf

@@ -0,0 +1,93 @@
+%PDF-1.7
+
+1 0 obj
+  << >>
+endobj
+
+2 0 obj
+  << /Length 3 0 R >>
+stream
+/DeviceRGB CS
+/DeviceRGB cs
+q
+1.000000 0.000000 -0.000000 1.000000 2.000000 1.000000 cm
+0.580392 0.596078 0.611765 scn
+0.000000 2.000000 m
+16.000000 2.000000 l
+16.000000 0.000000 l
+0.000000 0.000000 l
+0.000000 2.000000 l
+h
+f
+n
+Q
+q
+1.000000 0.000000 -0.000000 1.000000 3.416992 4.000000 cm
+0.152941 0.235294 0.384314 scn
+0.000000 0.000000 m
+2.409668 0.000000 l
+3.752930 3.999023 l
+9.413086 3.999023 l
+10.746094 0.000000 l
+13.166016 0.000000 l
+7.823730 14.796387 l
+5.342285 14.796387 l
+0.000000 0.000000 l
+h
+6.490723 12.202148 m
+6.665039 12.202148 l
+8.797852 5.844727 l
+4.368164 5.844727 l
+6.490723 12.202148 l
+h
+f
+n
+Q
+
+endstream
+endobj
+
+3 0 obj
+  617
+endobj
+
+4 0 obj
+  << /Annots []
+     /Type /Page
+     /MediaBox [ 0.000000 0.000000 20.000000 20.000000 ]
+     /Resources 1 0 R
+     /Contents 2 0 R
+     /Parent 5 0 R
+  >>
+endobj
+
+5 0 obj
+  << /Kids [ 4 0 R ]
+     /Count 1
+     /Type /Pages
+  >>
+endobj
+
+6 0 obj
+  << /Pages 5 0 R
+     /Type /Catalog
+  >>
+endobj
+
+xref
+0 7
+0000000000 65535 f
+0000000010 00000 n
+0000000034 00000 n
+0000000707 00000 n
+0000000729 00000 n
+0000000902 00000 n
+0000000976 00000 n
+trailer
+<< /ID [ (some) (id) ]
+   /Root 6 0 R
+   /Size 7
+>>
+startxref
+1035
+%%EOF

+ 21 - 0
PDF Office/PDF Office/Class/PDFWindowController/Side/LeftSide/BOTA.xcassets/Selected=false.imageset/Contents.json

@@ -0,0 +1,21 @@
+{
+  "images" : [
+    {
+      "filename" : "Selected=false.pdf",
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

+ 192 - 0
PDF Office/PDF Office/Class/PDFWindowController/Side/LeftSide/BOTA.xcassets/Selected=false.imageset/Selected=false.pdf

@@ -0,0 +1,192 @@
+%PDF-1.7
+
+1 0 obj
+  << >>
+endobj
+
+2 0 obj
+  << /Length 3 0 R >>
+stream
+/DeviceRGB CS
+/DeviceRGB cs
+q
+1.000000 0.000000 -0.000000 1.000000 9.205078 1.309967 cm
+0.580392 0.596078 0.611765 scn
+1.337829 12.982912 m
+4.284108 10.036634 l
+5.698321 11.450848 l
+2.752043 14.397125 l
+1.337829 12.982912 l
+h
+1.589872 -0.000008 m
+1.940015 0.458776 2.620985 1.232450 3.410989 1.880281 c
+4.119463 2.461255 4.769785 2.819295 5.273334 2.914431 c
+5.291575 2.876014 5.311550 2.832054 5.334268 2.780822 c
+5.345603 2.755259 5.357949 2.726993 5.371247 2.696548 c
+5.445678 2.526135 5.549946 2.287414 5.673930 2.071715 c
+5.825007 1.808882 6.057231 1.481894 6.426745 1.243800 c
+7.048737 0.843023 7.722315 0.698536 8.399425 0.886684 c
+9.019408 1.058960 9.500440 1.473501 9.866200 1.873436 c
+8.390337 3.223187 l
+8.123163 2.931050 7.951880 2.838101 7.863971 2.813674 c
+7.830671 2.804421 7.801699 2.802466 7.762929 2.809775 c
+7.719535 2.817957 7.637245 2.843257 7.511451 2.924104 c
+7.511404 2.924149 7.511301 2.924237 7.511143 2.924373 c
+7.507285 2.927697 7.470598 2.959306 7.407891 3.068399 c
+7.343350 3.180683 7.290606 3.300673 7.215896 3.470633 c
+7.162586 3.591533 l
+7.077521 3.783371 6.939738 4.091660 6.730415 4.347923 c
+6.490758 4.641325 6.095506 4.940019 5.528466 4.940019 c
+4.256920 4.940019 3.031205 4.155316 2.142797 3.426789 c
+1.209448 2.661410 0.423604 1.768416 0.000000 1.213379 c
+1.589872 -0.000008 l
+h
+f*
+n
+Q
+q
+13.370755 19.373409 m
+13.858910 19.861565 14.650367 19.861565 15.138522 19.373409 c
+18.232115 16.279818 l
+18.720270 15.791662 18.720270 15.000206 18.232115 14.512051 c
+6.799492 3.079430 l
+6.595525 2.875462 6.327289 2.748312 6.040272 2.719545 c
+2.602069 2.374933 l
+1.815976 2.296143 1.154847 2.957272 1.233638 3.743364 c
+1.578249 7.181568 l
+1.607016 7.468585 1.734166 7.736820 1.938133 7.940788 c
+13.370755 19.373409 l
+h
+W*
+n
+q
+0.707107 -0.707107 0.707107 0.707107 0.069183 6.071838 cm
+0.152941 0.235294 0.384314 scn
+4.405127 -0.823086 m
+2.856924 0.443037 l
+4.405127 -0.823086 l
+h
+2.469873 -0.823086 m
+4.018076 0.443037 l
+2.469873 -0.823086 l
+h
+0.282373 1.851768 m
+-1.265830 0.585646 l
+0.282373 1.851768 l
+h
+6.592627 1.851768 m
+8.140830 0.585646 l
+6.592627 1.851768 l
+h
+1.250000 18.061264 m
+5.625000 18.061264 l
+5.625000 22.061264 l
+1.250000 22.061264 l
+1.250000 18.061264 l
+h
+4.875000 18.811264 m
+4.875000 2.643095 l
+8.875000 2.643095 l
+8.875000 18.811264 l
+4.875000 18.811264 l
+h
+2.000000 2.643095 m
+2.000000 18.811264 l
+-2.000000 18.811264 l
+-2.000000 2.643095 l
+2.000000 2.643095 l
+h
+5.044424 3.117891 m
+2.856924 0.443037 l
+5.953330 -2.089209 l
+8.140830 0.585646 l
+5.044424 3.117891 l
+h
+4.018076 0.443037 m
+1.830576 3.117891 l
+-1.265830 0.585646 l
+0.921670 -2.089209 l
+4.018076 0.443037 l
+h
+2.856924 0.443037 m
+3.157007 0.809977 3.717993 0.809977 4.018076 0.443037 c
+0.921670 -2.089209 l
+2.222029 -3.679276 4.652971 -3.679276 5.953330 -2.089209 c
+2.856924 0.443037 l
+h
+-2.000000 2.643095 m
+-2.000000 1.893112 -1.740616 1.166210 -1.265830 0.585646 c
+1.830576 3.117891 l
+1.940142 2.983915 2.000000 2.816168 2.000000 2.643095 c
+-2.000000 2.643095 l
+h
+4.875000 2.643095 m
+4.875000 2.816168 4.934858 2.983915 5.044424 3.117891 c
+8.140830 0.585646 l
+8.615616 1.166210 8.875000 1.893112 8.875000 2.643095 c
+4.875000 2.643095 l
+h
+5.625000 18.061264 m
+5.210786 18.061264 4.875000 18.397051 4.875000 18.811264 c
+8.875000 18.811264 l
+8.875000 20.606190 7.419925 22.061264 5.625000 22.061264 c
+5.625000 18.061264 l
+h
+1.250000 22.061264 m
+-0.544927 22.061264 -2.000000 20.606188 -2.000000 18.811264 c
+2.000000 18.811264 l
+2.000000 18.397051 1.664215 18.061264 1.250000 18.061264 c
+1.250000 22.061264 l
+h
+f
+n
+Q
+Q
+
+endstream
+endobj
+
+3 0 obj
+  3529
+endobj
+
+4 0 obj
+  << /Annots []
+     /Type /Page
+     /MediaBox [ 0.000000 0.000000 20.000000 20.000000 ]
+     /Resources 1 0 R
+     /Contents 2 0 R
+     /Parent 5 0 R
+  >>
+endobj
+
+5 0 obj
+  << /Kids [ 4 0 R ]
+     /Count 1
+     /Type /Pages
+  >>
+endobj
+
+6 0 obj
+  << /Pages 5 0 R
+     /Type /Catalog
+  >>
+endobj
+
+xref
+0 7
+0000000000 65535 f
+0000000010 00000 n
+0000000034 00000 n
+0000003619 00000 n
+0000003642 00000 n
+0000003815 00000 n
+0000003889 00000 n
+trailer
+<< /ID [ (some) (id) ]
+   /Root 6 0 R
+   /Size 7
+>>
+startxref
+3948
+%%EOF

+ 21 - 0
PDF Office/PDF Office/Class/PDFWindowController/Side/LeftSide/BOTA.xcassets/Selected=true-1.imageset/Contents.json

@@ -0,0 +1,21 @@
+{
+  "images" : [
+    {
+      "filename" : "Selected=true-1.pdf",
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

+ 204 - 0
PDF Office/PDF Office/Class/PDFWindowController/Side/LeftSide/BOTA.xcassets/Selected=true-1.imageset/Selected=true-1.pdf

@@ -0,0 +1,204 @@
+%PDF-1.7
+
+1 0 obj
+  << >>
+endobj
+
+2 0 obj
+  << /Length 3 0 R >>
+stream
+/DeviceRGB CS
+/DeviceRGB cs
+q
+q
+1.000000 0.000000 -0.000000 1.000000 1.000000 1.224686 cm
+1.000000 0.894118 0.603922 scn
+1.041667 16.775314 m
+0.466370 16.775314 0.000000 16.308945 0.000000 15.733647 c
+0.000000 3.816981 l
+0.000000 3.241685 0.466369 2.775314 1.041666 2.775314 c
+3.333252 2.775314 l
+3.333252 0.644346 l
+3.333252 0.251421 3.751747 -0.000002 4.098657 0.184507 c
+8.969840 2.775314 l
+16.958334 2.775314 l
+17.533630 2.775314 18.000000 3.241685 18.000000 3.816981 c
+18.000000 15.733647 l
+18.000000 16.308945 17.533630 16.775314 16.958334 16.775314 c
+1.041667 16.775314 l
+h
+f*
+n
+Q
+2.041667 18.000000 m
+1.466370 18.000000 1.000000 17.533630 1.000000 16.958332 c
+1.000000 5.041667 l
+1.000000 4.466371 1.466369 4.000000 2.041666 4.000000 c
+4.333252 4.000000 l
+4.333252 1.869032 l
+4.333252 1.476107 4.751747 1.224684 5.098657 1.409193 c
+9.969840 4.000000 l
+17.958334 4.000000 l
+18.533630 4.000000 19.000000 4.466371 19.000000 5.041667 c
+19.000000 16.958334 l
+19.000000 17.533630 18.533630 18.000000 17.958334 18.000000 c
+2.041667 18.000000 l
+h
+W*
+n
+q
+1.000000 0.000000 -0.000000 1.000000 1.000000 1.224686 cm
+0.152941 0.235294 0.384314 scn
+3.333252 2.775314 m
+5.333252 2.775314 l
+5.333252 4.775314 l
+3.333252 4.775314 l
+3.333252 2.775314 l
+h
+4.098657 0.184507 m
+3.159501 1.950290 l
+3.159500 1.950289 l
+4.098657 0.184507 l
+h
+8.969840 2.775314 m
+8.969840 4.775314 l
+8.471056 4.775314 l
+8.030684 4.541097 l
+8.969840 2.775314 l
+h
+2.000000 15.733647 m
+2.000000 15.204375 1.570940 14.775314 1.041667 14.775314 c
+1.041667 18.775314 l
+-0.638200 18.775314 -2.000000 17.413513 -2.000000 15.733647 c
+2.000000 15.733647 l
+h
+2.000000 3.816981 m
+2.000000 15.733647 l
+-2.000000 15.733647 l
+-2.000000 3.816981 l
+2.000000 3.816981 l
+h
+1.041666 4.775314 m
+1.570942 4.775314 2.000000 4.346251 2.000000 3.816981 c
+-2.000000 3.816981 l
+-2.000000 2.137118 -0.638203 0.775314 1.041666 0.775314 c
+1.041666 4.775314 l
+h
+3.333252 4.775314 m
+1.041666 4.775314 l
+1.041666 0.775314 l
+3.333252 0.775314 l
+3.333252 4.775314 l
+h
+5.333252 0.644346 m
+5.333252 2.775314 l
+1.333252 2.775314 l
+1.333252 0.644346 l
+5.333252 0.644346 l
+h
+3.159500 1.950289 m
+4.144726 2.474296 5.333252 1.760254 5.333252 0.644346 c
+1.333252 0.644346 l
+1.333252 -1.257412 3.358768 -2.474300 5.037814 -1.581274 c
+3.159500 1.950289 l
+h
+8.030684 4.541097 m
+3.159501 1.950290 l
+5.037813 -1.581274 l
+9.908996 1.009532 l
+8.030684 4.541097 l
+h
+16.958334 4.775314 m
+8.969840 4.775314 l
+8.969840 0.775314 l
+16.958334 0.775314 l
+16.958334 4.775314 l
+h
+16.000000 3.816981 m
+16.000000 4.346252 16.429058 4.775314 16.958334 4.775314 c
+16.958334 0.775314 l
+18.638203 0.775314 20.000000 2.137117 20.000000 3.816981 c
+16.000000 3.816981 l
+h
+16.000000 15.733647 m
+16.000000 3.816981 l
+20.000000 3.816981 l
+20.000000 15.733647 l
+16.000000 15.733647 l
+h
+16.958334 14.775314 m
+16.429060 14.775314 16.000000 15.204376 16.000000 15.733647 c
+20.000000 15.733647 l
+20.000000 17.413513 18.638201 18.775314 16.958334 18.775314 c
+16.958334 14.775314 l
+h
+1.041667 14.775314 m
+16.958334 14.775314 l
+16.958334 18.775314 l
+1.041667 18.775314 l
+1.041667 14.775314 l
+h
+f
+n
+Q
+Q
+q
+1.000000 0.000000 -0.000000 1.000000 5.000000 10.000000 cm
+0.152941 0.235294 0.384314 scn
+0.000000 2.000000 m
+10.000000 2.000000 l
+10.000000 0.000000 l
+0.000000 0.000000 l
+0.000000 2.000000 l
+h
+f
+n
+Q
+
+endstream
+endobj
+
+3 0 obj
+  3291
+endobj
+
+4 0 obj
+  << /Annots []
+     /Type /Page
+     /MediaBox [ 0.000000 0.000000 20.000000 20.000000 ]
+     /Resources 1 0 R
+     /Contents 2 0 R
+     /Parent 5 0 R
+  >>
+endobj
+
+5 0 obj
+  << /Kids [ 4 0 R ]
+     /Count 1
+     /Type /Pages
+  >>
+endobj
+
+6 0 obj
+  << /Pages 5 0 R
+     /Type /Catalog
+  >>
+endobj
+
+xref
+0 7
+0000000000 65535 f
+0000000010 00000 n
+0000000034 00000 n
+0000003381 00000 n
+0000003404 00000 n
+0000003577 00000 n
+0000003651 00000 n
+trailer
+<< /ID [ (some) (id) ]
+   /Root 6 0 R
+   /Size 7
+>>
+startxref
+3710
+%%EOF

+ 21 - 0
PDF Office/PDF Office/Class/PDFWindowController/Side/LeftSide/BOTA.xcassets/Selected=true-2.imageset/Contents.json

@@ -0,0 +1,21 @@
+{
+  "images" : [
+    {
+      "filename" : "Selected=true-2.pdf",
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

+ 93 - 0
PDF Office/PDF Office/Class/PDFWindowController/Side/LeftSide/BOTA.xcassets/Selected=true-2.imageset/Selected=true-2.pdf

@@ -0,0 +1,93 @@
+%PDF-1.7
+
+1 0 obj
+  << >>
+endobj
+
+2 0 obj
+  << /Length 3 0 R >>
+stream
+/DeviceRGB CS
+/DeviceRGB cs
+q
+1.000000 0.000000 -0.000000 1.000000 2.000000 1.000000 cm
+0.954167 0.274323 0.355904 scn
+0.000000 2.000000 m
+16.000000 2.000000 l
+16.000000 0.000000 l
+0.000000 0.000000 l
+0.000000 2.000000 l
+h
+f
+n
+Q
+q
+1.000000 0.000000 -0.000000 1.000000 3.416992 4.000000 cm
+0.152941 0.235294 0.384314 scn
+0.000000 0.000000 m
+2.409668 0.000000 l
+3.752930 3.999023 l
+9.413086 3.999023 l
+10.746094 0.000000 l
+13.166016 0.000000 l
+7.823730 14.796387 l
+5.342285 14.796387 l
+0.000000 0.000000 l
+h
+6.490723 12.202148 m
+6.665039 12.202148 l
+8.797852 5.844727 l
+4.368164 5.844727 l
+6.490723 12.202148 l
+h
+f
+n
+Q
+
+endstream
+endobj
+
+3 0 obj
+  617
+endobj
+
+4 0 obj
+  << /Annots []
+     /Type /Page
+     /MediaBox [ 0.000000 0.000000 20.000000 20.000000 ]
+     /Resources 1 0 R
+     /Contents 2 0 R
+     /Parent 5 0 R
+  >>
+endobj
+
+5 0 obj
+  << /Kids [ 4 0 R ]
+     /Count 1
+     /Type /Pages
+  >>
+endobj
+
+6 0 obj
+  << /Pages 5 0 R
+     /Type /Catalog
+  >>
+endobj
+
+xref
+0 7
+0000000000 65535 f
+0000000010 00000 n
+0000000034 00000 n
+0000000707 00000 n
+0000000729 00000 n
+0000000902 00000 n
+0000000976 00000 n
+trailer
+<< /ID [ (some) (id) ]
+   /Root 6 0 R
+   /Size 7
+>>
+startxref
+1035
+%%EOF

+ 21 - 0
PDF Office/PDF Office/Class/PDFWindowController/Side/LeftSide/BOTA.xcassets/Selected=true.imageset/Contents.json

@@ -0,0 +1,21 @@
+{
+  "images" : [
+    {
+      "filename" : "Selected=true.pdf",
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

+ 206 - 0
PDF Office/PDF Office/Class/PDFWindowController/Side/LeftSide/BOTA.xcassets/Selected=true.imageset/Selected=true.pdf

@@ -0,0 +1,206 @@
+%PDF-1.7
+
+1 0 obj
+  << >>
+endobj
+
+2 0 obj
+  << /Length 3 0 R >>
+stream
+/DeviceRGB CS
+/DeviceRGB cs
+q
+0.707107 -0.707107 0.707107 0.707107 8.166679 11.916679 cm
+0.152941 0.235294 0.384314 scn
+0.000000 3.360474 m
+4.166667 3.360474 l
+4.166667 5.360474 l
+0.000000 5.360474 l
+0.000000 3.360474 l
+h
+f
+n
+Q
+q
+1.000000 0.000000 -0.000000 1.000000 10.000000 0.309967 cm
+0.954167 0.274323 0.355904 scn
+4.733530 3.940033 m
+4.526470 3.940033 4.401204 4.064764 4.386534 4.082723 c
+4.385662 4.083791 4.389812 4.078805 4.398578 4.065072 c
+4.407308 4.051395 4.418799 4.031903 4.433210 4.004867 c
+4.463343 3.948332 4.496449 3.877545 4.539331 3.780836 c
+4.614114 3.612185 4.732859 3.325964 4.878994 3.071729 c
+5.030071 2.808896 5.262295 2.481909 5.631809 2.243814 c
+6.715093 3.925033 l
+6.724627 3.918890 6.686865 3.939829 6.612955 4.068414 c
+6.534102 4.205596 6.472857 4.354284 6.367650 4.591547 c
+6.282585 4.783385 6.144802 5.091673 5.935479 5.347938 c
+5.695822 5.641339 5.300570 5.940033 4.733530 5.940033 c
+4.733530 3.940033 l
+h
+0.794936 1.000006 m
+1.145079 1.458791 1.826049 2.232464 2.616053 2.880295 c
+3.450998 3.564980 4.205174 3.940033 4.733530 3.940033 c
+4.733530 5.940033 l
+3.461984 5.940033 2.236269 5.155331 1.347861 4.426804 c
+0.414512 3.661424 -0.371332 2.768431 -0.794936 2.213393 c
+0.794936 1.000006 l
+h
+5.631809 2.243814 m
+6.253800 1.843038 6.927379 1.698550 7.604488 1.886699 c
+8.224472 2.058974 8.705503 2.473516 9.071264 2.873450 c
+7.595401 4.223202 l
+7.328227 3.931065 7.156944 3.838116 7.069035 3.813689 c
+7.035735 3.804435 7.006763 3.802481 6.967993 3.809790 c
+6.924436 3.818002 6.841689 3.843462 6.715093 3.925033 c
+5.631809 2.243814 l
+h
+f
+n
+Q
+q
+13.370755 19.373409 m
+13.858910 19.861565 14.650367 19.861565 15.138522 19.373409 c
+18.232115 16.279818 l
+18.720270 15.791662 18.720270 15.000206 18.232115 14.512051 c
+6.799492 3.079430 l
+6.595525 2.875462 6.327289 2.748312 6.040272 2.719545 c
+2.602069 2.374933 l
+1.815976 2.296143 1.154847 2.957272 1.233638 3.743364 c
+1.578249 7.181568 l
+1.607016 7.468585 1.734166 7.736820 1.938133 7.940788 c
+13.370755 19.373409 l
+h
+W*
+n
+q
+0.707107 -0.707107 0.707107 0.707107 0.069183 6.071838 cm
+0.152941 0.235294 0.384314 scn
+4.405127 -0.823086 m
+2.856924 0.443037 l
+4.405127 -0.823086 l
+h
+2.469873 -0.823086 m
+4.018076 0.443037 l
+2.469873 -0.823086 l
+h
+0.282373 1.851768 m
+-1.265830 0.585646 l
+0.282373 1.851768 l
+h
+6.592627 1.851768 m
+8.140830 0.585646 l
+6.592627 1.851768 l
+h
+1.250000 18.061264 m
+5.625000 18.061264 l
+5.625000 22.061264 l
+1.250000 22.061264 l
+1.250000 18.061264 l
+h
+4.875000 18.811264 m
+4.875000 2.643095 l
+8.875000 2.643095 l
+8.875000 18.811264 l
+4.875000 18.811264 l
+h
+2.000000 2.643095 m
+2.000000 18.811264 l
+-2.000000 18.811264 l
+-2.000000 2.643095 l
+2.000000 2.643095 l
+h
+5.044424 3.117891 m
+2.856924 0.443037 l
+5.953330 -2.089209 l
+8.140830 0.585646 l
+5.044424 3.117891 l
+h
+4.018076 0.443037 m
+1.830576 3.117891 l
+-1.265830 0.585646 l
+0.921670 -2.089209 l
+4.018076 0.443037 l
+h
+2.856924 0.443037 m
+3.157007 0.809977 3.717993 0.809977 4.018076 0.443037 c
+0.921670 -2.089209 l
+2.222029 -3.679276 4.652971 -3.679276 5.953330 -2.089209 c
+2.856924 0.443037 l
+h
+-2.000000 2.643095 m
+-2.000000 1.893112 -1.740616 1.166210 -1.265830 0.585646 c
+1.830576 3.117891 l
+1.940142 2.983915 2.000000 2.816168 2.000000 2.643095 c
+-2.000000 2.643095 l
+h
+4.875000 2.643095 m
+4.875000 2.816168 4.934858 2.983915 5.044424 3.117891 c
+8.140830 0.585646 l
+8.615616 1.166210 8.875000 1.893112 8.875000 2.643095 c
+4.875000 2.643095 l
+h
+5.625000 18.061264 m
+5.210786 18.061264 4.875000 18.397051 4.875000 18.811264 c
+8.875000 18.811264 l
+8.875000 20.606190 7.419925 22.061264 5.625000 22.061264 c
+5.625000 18.061264 l
+h
+1.250000 22.061264 m
+-0.544927 22.061264 -2.000000 20.606188 -2.000000 18.811264 c
+2.000000 18.811264 l
+2.000000 18.397051 1.664215 18.061264 1.250000 18.061264 c
+1.250000 22.061264 l
+h
+f
+n
+Q
+Q
+
+endstream
+endobj
+
+3 0 obj
+  3782
+endobj
+
+4 0 obj
+  << /Annots []
+     /Type /Page
+     /MediaBox [ 0.000000 0.000000 20.000000 20.000000 ]
+     /Resources 1 0 R
+     /Contents 2 0 R
+     /Parent 5 0 R
+  >>
+endobj
+
+5 0 obj
+  << /Kids [ 4 0 R ]
+     /Count 1
+     /Type /Pages
+  >>
+endobj
+
+6 0 obj
+  << /Pages 5 0 R
+     /Type /Catalog
+  >>
+endobj
+
+xref
+0 7
+0000000000 65535 f
+0000000010 00000 n
+0000000034 00000 n
+0000003872 00000 n
+0000003895 00000 n
+0000004068 00000 n
+0000004142 00000 n
+trailer
+<< /ID [ (some) (id) ]
+   /Root 6 0 R
+   /Size 7
+>>
+startxref
+4201
+%%EOF

+ 21 - 0
PDF Office/PDF Office/Class/PDFWindowController/Side/LeftSide/BOTA.xcassets/state=false, Type=Default.imageset/Contents.json

@@ -0,0 +1,21 @@
+{
+  "images" : [
+    {
+      "filename" : "state=false, Type=Default.pdf",
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

+ 93 - 0
PDF Office/PDF Office/Class/PDFWindowController/Side/LeftSide/BOTA.xcassets/state=false, Type=Default.imageset/state=false, Type=Default.pdf

@@ -0,0 +1,93 @@
+%PDF-1.7
+
+1 0 obj
+  << >>
+endobj
+
+2 0 obj
+  << /Length 3 0 R >>
+stream
+/DeviceRGB CS
+/DeviceRGB cs
+q
+1.000000 0.000000 -0.000000 1.000000 1.000000 0.000000 cm
+0.152941 0.235294 0.384314 scn
+2.250000 19.000000 m
+1.007359 19.000000 0.000000 17.992640 0.000000 16.750000 c
+0.000000 8.250000 l
+0.000000 7.007358 1.007362 6.000000 2.250001 6.000000 c
+5.070889 6.000000 l
+5.556118 2.607706 8.473528 0.000000 12.000000 0.000000 c
+15.865993 0.000000 19.000000 3.134007 19.000000 7.000000 c
+19.000000 10.526472 16.392294 13.443882 13.000000 13.929111 c
+13.000000 16.750000 l
+13.000000 17.992641 11.992641 19.000000 10.750000 19.000000 c
+2.250000 19.000000 l
+h
+11.000000 13.929111 m
+11.000000 16.750000 l
+11.000000 16.888071 10.888071 17.000000 10.750000 17.000000 c
+2.250000 17.000000 l
+2.111929 17.000000 2.000000 16.888071 2.000000 16.750000 c
+2.000000 8.250000 l
+2.000000 8.111930 2.111928 8.000000 2.250001 8.000000 c
+5.070889 8.000000 l
+5.509402 11.065691 7.934309 13.490599 11.000000 13.929111 c
+h
+17.000000 7.000000 m
+17.000000 4.238576 14.761424 2.000000 12.000000 2.000000 c
+9.238577 2.000000 7.000000 4.238576 7.000000 7.000000 c
+7.000000 9.761423 9.238577 12.000000 12.000000 12.000000 c
+14.761424 12.000000 17.000000 9.761423 17.000000 7.000000 c
+h
+f*
+n
+Q
+
+endstream
+endobj
+
+3 0 obj
+  1188
+endobj
+
+4 0 obj
+  << /Annots []
+     /Type /Page
+     /MediaBox [ 0.000000 0.000000 20.000000 20.000000 ]
+     /Resources 1 0 R
+     /Contents 2 0 R
+     /Parent 5 0 R
+  >>
+endobj
+
+5 0 obj
+  << /Kids [ 4 0 R ]
+     /Count 1
+     /Type /Pages
+  >>
+endobj
+
+6 0 obj
+  << /Pages 5 0 R
+     /Type /Catalog
+  >>
+endobj
+
+xref
+0 7
+0000000000 65535 f
+0000000010 00000 n
+0000000034 00000 n
+0000001278 00000 n
+0000001301 00000 n
+0000001474 00000 n
+0000001548 00000 n
+trailer
+<< /ID [ (some) (id) ]
+   /Root 6 0 R
+   /Size 7
+>>
+startxref
+1607
+%%EOF

+ 21 - 0
PDF Office/PDF Office/Class/PDFWindowController/Side/LeftSide/BOTA.xcassets/state=true, Type=arrow.imageset/Contents.json

@@ -0,0 +1,21 @@
+{
+  "images" : [
+    {
+      "filename" : "state=true, Type=arrow.pdf",
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

+ 78 - 0
PDF Office/PDF Office/Class/PDFWindowController/Side/LeftSide/BOTA.xcassets/state=true, Type=arrow.imageset/state=true, Type=arrow.pdf

@@ -0,0 +1,78 @@
+%PDF-1.7
+
+1 0 obj
+  << >>
+endobj
+
+2 0 obj
+  << /Length 3 0 R >>
+stream
+/DeviceRGB CS
+/DeviceRGB cs
+q
+1.000000 0.000000 -0.000000 1.000000 1.292969 1.292892 cm
+0.954167 0.274323 0.355904 scn
+13.292893 14.707108 m
+8.707107 14.707108 l
+8.707107 16.707108 l
+15.707107 16.707108 l
+16.707108 16.707108 l
+16.707108 15.707108 l
+16.707108 8.707108 l
+14.707107 8.707108 l
+14.707107 13.292894 l
+1.414214 0.000000 l
+0.000000 1.414214 l
+13.292893 14.707108 l
+h
+f*
+n
+Q
+
+endstream
+endobj
+
+3 0 obj
+  384
+endobj
+
+4 0 obj
+  << /Annots []
+     /Type /Page
+     /MediaBox [ 0.000000 0.000000 20.000000 20.000000 ]
+     /Resources 1 0 R
+     /Contents 2 0 R
+     /Parent 5 0 R
+  >>
+endobj
+
+5 0 obj
+  << /Kids [ 4 0 R ]
+     /Count 1
+     /Type /Pages
+  >>
+endobj
+
+6 0 obj
+  << /Pages 5 0 R
+     /Type /Catalog
+  >>
+endobj
+
+xref
+0 7
+0000000000 65535 f
+0000000010 00000 n
+0000000034 00000 n
+0000000474 00000 n
+0000000496 00000 n
+0000000669 00000 n
+0000000743 00000 n
+trailer
+<< /ID [ (some) (id) ]
+   /Root 6 0 R
+   /Size 7
+>>
+startxref
+802
+%%EOF

+ 21 - 0
PDF Office/PDF Office/Class/PDFWindowController/Side/LeftSide/BOTA.xcassets/state=true, Type=cricle.imageset/Contents.json

@@ -0,0 +1,21 @@
+{
+  "images" : [
+    {
+      "filename" : "state=true, Type=cricle.pdf",
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

+ 77 - 0
PDF Office/PDF Office/Class/PDFWindowController/Side/LeftSide/BOTA.xcassets/state=true, Type=cricle.imageset/state=true, Type=cricle.pdf

@@ -0,0 +1,77 @@
+%PDF-1.7
+
+1 0 obj
+  << >>
+endobj
+
+2 0 obj
+  << /Length 3 0 R >>
+stream
+/DeviceRGB CS
+/DeviceRGB cs
+q
+1.000000 0.000000 -0.000000 1.000000 1.000000 1.000000 cm
+0.954167 0.274323 0.355904 scn
+9.000000 2.000000 m
+12.865993 2.000000 16.000000 5.134007 16.000000 9.000000 c
+16.000000 12.865993 12.865993 16.000000 9.000000 16.000000 c
+5.134007 16.000000 2.000000 12.865993 2.000000 9.000000 c
+2.000000 5.134007 5.134007 2.000000 9.000000 2.000000 c
+h
+9.000000 0.000000 m
+13.970563 0.000000 18.000000 4.029437 18.000000 9.000000 c
+18.000000 13.970563 13.970563 18.000000 9.000000 18.000000 c
+4.029437 18.000000 0.000000 13.970563 0.000000 9.000000 c
+0.000000 4.029437 4.029437 0.000000 9.000000 0.000000 c
+h
+f*
+n
+Q
+
+endstream
+endobj
+
+3 0 obj
+  638
+endobj
+
+4 0 obj
+  << /Annots []
+     /Type /Page
+     /MediaBox [ 0.000000 0.000000 20.000000 20.000000 ]
+     /Resources 1 0 R
+     /Contents 2 0 R
+     /Parent 5 0 R
+  >>
+endobj
+
+5 0 obj
+  << /Kids [ 4 0 R ]
+     /Count 1
+     /Type /Pages
+  >>
+endobj
+
+6 0 obj
+  << /Pages 5 0 R
+     /Type /Catalog
+  >>
+endobj
+
+xref
+0 7
+0000000000 65535 f
+0000000010 00000 n
+0000000034 00000 n
+0000000728 00000 n
+0000000750 00000 n
+0000000923 00000 n
+0000000997 00000 n
+trailer
+<< /ID [ (some) (id) ]
+   /Root 6 0 R
+   /Size 7
+>>
+startxref
+1056
+%%EOF

+ 21 - 0
PDF Office/PDF Office/Class/PDFWindowController/Side/LeftSide/BOTA.xcassets/state=true, Type=line.imageset/Contents.json

@@ -0,0 +1,21 @@
+{
+  "images" : [
+    {
+      "filename" : "state=true, Type=line.pdf",
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

+ 71 - 0
PDF Office/PDF Office/Class/PDFWindowController/Side/LeftSide/BOTA.xcassets/state=true, Type=line.imageset/state=true, Type=line.pdf

@@ -0,0 +1,71 @@
+%PDF-1.7
+
+1 0 obj
+  << >>
+endobj
+
+2 0 obj
+  << /Length 3 0 R >>
+stream
+/DeviceRGB CS
+/DeviceRGB cs
+q
+1.000000 0.000000 -0.000000 1.000000 1.292969 1.292877 cm
+0.954167 0.274323 0.355904 scn
+17.414215 16.000002 m
+1.414214 0.000000 l
+0.000000 1.414215 l
+16.000000 17.414215 l
+17.414215 16.000002 l
+h
+f*
+n
+Q
+
+endstream
+endobj
+
+3 0 obj
+  234
+endobj
+
+4 0 obj
+  << /Annots []
+     /Type /Page
+     /MediaBox [ 0.000000 0.000000 20.000000 20.000000 ]
+     /Resources 1 0 R
+     /Contents 2 0 R
+     /Parent 5 0 R
+  >>
+endobj
+
+5 0 obj
+  << /Kids [ 4 0 R ]
+     /Count 1
+     /Type /Pages
+  >>
+endobj
+
+6 0 obj
+  << /Pages 5 0 R
+     /Type /Catalog
+  >>
+endobj
+
+xref
+0 7
+0000000000 65535 f
+0000000010 00000 n
+0000000034 00000 n
+0000000324 00000 n
+0000000346 00000 n
+0000000519 00000 n
+0000000593 00000 n
+trailer
+<< /ID [ (some) (id) ]
+   /Root 6 0 R
+   /Size 7
+>>
+startxref
+652
+%%EOF

+ 21 - 0
PDF Office/PDF Office/Class/PDFWindowController/Side/LeftSide/BOTA.xcassets/state=true, Type=rectangle.imageset/Contents.json

@@ -0,0 +1,21 @@
+{
+  "images" : [
+    {
+      "filename" : "state=true, Type=rectangle.pdf",
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

+ 81 - 0
PDF Office/PDF Office/Class/PDFWindowController/Side/LeftSide/BOTA.xcassets/state=true, Type=rectangle.imageset/state=true, Type=rectangle.pdf

@@ -0,0 +1,81 @@
+%PDF-1.7
+
+1 0 obj
+  << >>
+endobj
+
+2 0 obj
+  << /Length 3 0 R >>
+stream
+/DeviceRGB CS
+/DeviceRGB cs
+q
+1.000000 0.000000 -0.000000 1.000000 1.000000 1.000000 cm
+0.954167 0.274323 0.355904 scn
+16.000000 16.000000 m
+2.000000 16.000000 l
+2.000000 2.000000 l
+16.000000 2.000000 l
+16.000000 16.000000 l
+h
+2.000000 18.000000 m
+0.895431 18.000000 0.000000 17.104570 0.000000 16.000000 c
+0.000000 2.000000 l
+0.000000 0.895430 0.895430 0.000000 2.000000 0.000000 c
+16.000000 0.000000 l
+17.104570 0.000000 18.000000 0.895430 18.000000 2.000000 c
+18.000000 16.000000 l
+18.000000 17.104568 17.104570 18.000000 16.000000 18.000000 c
+2.000000 18.000000 l
+h
+f*
+n
+Q
+
+endstream
+endobj
+
+3 0 obj
+  577
+endobj
+
+4 0 obj
+  << /Annots []
+     /Type /Page
+     /MediaBox [ 0.000000 0.000000 20.000000 20.000000 ]
+     /Resources 1 0 R
+     /Contents 2 0 R
+     /Parent 5 0 R
+  >>
+endobj
+
+5 0 obj
+  << /Kids [ 4 0 R ]
+     /Count 1
+     /Type /Pages
+  >>
+endobj
+
+6 0 obj
+  << /Pages 5 0 R
+     /Type /Catalog
+  >>
+endobj
+
+xref
+0 7
+0000000000 65535 f
+0000000010 00000 n
+0000000034 00000 n
+0000000667 00000 n
+0000000689 00000 n
+0000000862 00000 n
+0000000936 00000 n
+trailer
+<< /ID [ (some) (id) ]
+   /Root 6 0 R
+   /Size 7
+>>
+startxref
+995
+%%EOF

+ 21 - 0
PDF Office/PDF Office/Class/PDFWindowController/Side/LeftSide/BOTA.xcassets/text.imageset/Contents.json

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

+ 89 - 0
PDF Office/PDF Office/Class/PDFWindowController/Side/LeftSide/BOTA.xcassets/text.imageset/text.pdf

@@ -0,0 +1,89 @@
+%PDF-1.7
+
+1 0 obj
+  << >>
+endobj
+
+2 0 obj
+  << /Length 3 0 R >>
+stream
+/DeviceRGB CS
+/DeviceRGB cs
+q
+1.000000 0.000000 -0.000000 1.000000 2.000000 2.000000 cm
+0.152941 0.235294 0.384314 scn
+0.000000 15.000000 m
+0.000000 15.552285 0.447715 16.000000 1.000000 16.000000 c
+7.000000 16.000000 l
+9.000000 16.000000 l
+15.000000 16.000000 l
+15.552285 16.000000 16.000000 15.552285 16.000000 15.000000 c
+16.000000 11.000000 l
+14.000000 11.000000 l
+14.000000 14.000000 l
+9.000000 14.000000 l
+9.000001 2.000000 l
+11.000000 2.000000 l
+11.000000 0.000000 l
+9.000001 0.000000 l
+7.000000 0.000000 l
+5.000000 0.000000 l
+5.000000 2.000000 l
+7.000000 2.000000 l
+7.000000 14.000000 l
+2.000000 14.000000 l
+2.000000 11.000000 l
+0.000000 11.000000 l
+0.000000 15.000000 l
+h
+f*
+n
+Q
+
+endstream
+endobj
+
+3 0 obj
+  688
+endobj
+
+4 0 obj
+  << /Annots []
+     /Type /Page
+     /MediaBox [ 0.000000 0.000000 20.000000 20.000000 ]
+     /Resources 1 0 R
+     /Contents 2 0 R
+     /Parent 5 0 R
+  >>
+endobj
+
+5 0 obj
+  << /Kids [ 4 0 R ]
+     /Count 1
+     /Type /Pages
+  >>
+endobj
+
+6 0 obj
+  << /Pages 5 0 R
+     /Type /Catalog
+  >>
+endobj
+
+xref
+0 7
+0000000000 65535 f
+0000000010 00000 n
+0000000034 00000 n
+0000000778 00000 n
+0000000800 00000 n
+0000000973 00000 n
+0000001047 00000 n
+trailer
+<< /ID [ (some) (id) ]
+   /Root 6 0 R
+   /Size 7
+>>
+startxref
+1106
+%%EOF

+ 165 - 60
PDF Office/PDF Office/Class/PDFWindowController/Side/LeftSide/BookMarks/KMBookMarkViewController.swift

@@ -29,6 +29,9 @@ class KMBookMarkViewController: NSViewController, NSTextFieldDelegate,NSMenuItem
     
     var selectedRowIndexs : IndexSet = []
     
+    //undo redo
+    private var undoRedoManager: UndoManager = UndoManager()
+    
     func dealloc() {
         NotificationCenter.default.removeObserver(self)
     }
@@ -142,13 +145,9 @@ class KMBookMarkViewController: NSViewController, NSTextFieldDelegate,NSMenuItem
     }
     
     @IBAction func addBookmarkAction(_ sender: Any) {
-        
-        
         if self.listView.document.bookmark(forPageIndex: UInt(self.listView.currentPageIndex)) == nil {
             let label = "\(NSLocalizedString("Page", comment:"")) \(self.listView.currentPageIndex + 1)"
-            self.listView.document.addBookmark(label, forPageIndex: UInt(self.listView.currentPageIndex))
-            self.listView.setNeedsDisplayForVisiblePages()
-            self.addBookMarkAndEdit(newBookMark: self.listView.document.bookmark(forPageIndex: UInt(self.listView.currentPageIndex)))
+            self.addBookMark(bookMarks: [KMBookMark(label: label, index: UInt(self.listView.currentPageIndex))])
         } else {
             let alter = NSAlert()
             alter.alertStyle = NSAlert.Style.informational
@@ -180,11 +179,8 @@ class KMBookMarkViewController: NSViewController, NSTextFieldDelegate,NSMenuItem
             alter.addButton(withTitle: NSLocalizedString("NO", comment:""))
             let modlres = alter.runModal()
             if modlres == NSApplication.ModalResponse.alertFirstButtonReturn {
-                self.listView.document.removeBookmark(forPageIndex:UInt(item.pageIndex))
-                self.listView.document.addBookmark(item.label, forPageIndex: UInt(self.listView.currentPageIndex))
-                
-                self.reloadData()
-                self.listView.setNeedsDisplayForVisiblePages()
+                self.changeLocation(oldBookMark: KMBookMark(label: item.label, index: UInt(item.pageIndex)),
+                                    newBookMark: KMBookMark(label: item.label, index: UInt(self.listView.currentPageIndex)))
             }
         } else {
             __NSBeep()
@@ -193,14 +189,12 @@ class KMBookMarkViewController: NSViewController, NSTextFieldDelegate,NSMenuItem
     
     @objc func deleteBookAction() {
         if self.bookTableView.clickedRow >= 0 {
+            var bookMarks:[KMBookMark] = []
             for index in self.bookTableView.selectedRowIndexes {
                 let item = self.dataSource[index]
-                if self.listView.document.removeBookmark(forPageIndex:UInt(item.pageIndex)) {
-                    print("删除标签成功")
-                }
+                bookMarks.append(KMBookMark(label: item.label, index: UInt(item.pageIndex)))
             }
-            self.listView.setNeedsDisplayForVisiblePages()
-            self.reloadData()
+            self.deleteBookMark(bookMarks: bookMarks)
         } else {
             __NSBeep()
         }
@@ -215,18 +209,6 @@ class KMBookMarkViewController: NSViewController, NSTextFieldDelegate,NSMenuItem
         self.renameTextField.becomeFirstResponder()
     }
     
-    func renamePDFBook(bookmark : CPDFBookmark! , label:String) {
-        if bookmark.label == label {
-            return
-        }
-        bookmark.label = label
-        self.reloadData()
-        
-        var indexSet = IndexSet()
-        indexSet.insert(self.bookTableView.row(for: self.renameCellView))
-        self.bookTableView.selectRowIndexes(indexSet, byExtendingSelection: false)
-    }
-    
     //MARK: Noti
     @objc func KMPDFViewCurrentPageDidChangedNotification(notification: NSNotification) {
 //        let pdfdocument : CPDFDocument = notification.object as! CPDFDocument
@@ -257,31 +239,31 @@ class KMBookMarkViewController: NSViewController, NSTextFieldDelegate,NSMenuItem
     
     //MARK: NSMenuItemValidation
     
-    func validateMenuItem(_ menuItem: NSMenuItem) -> Bool {
-        let action = menuItem.action
-        if action == #selector(renameBookAction) ||
-            action == #selector(changeLocationAction) ||
-            action == #selector(deleteBookAction) {
-            if self.bookTableView.selectedRowIndexes.count > 1 {
-                if action == #selector(changeLocationAction) {
-                    return false
-                } else if action == #selector(renameBookAction) {
-                    return false
-                }
-            } else {
-                if self.bookTableView.clickedRow > -1 {
-                    if action == #selector(changeLocationAction) {
-    //                    if self.listView.document.bookmark(forPageIndex: UInt(self.listView.currentPageIndex)) != nil {
-    //                        return false
-    //                    }
-                    }
-                } else {
-                    return false
-                }
-            }
-        }
-        return true
-    }
+//    func validateMenuItem(_ menuItem: NSMenuItem) -> Bool {
+//        let action = menuItem.action
+//        if action == #selector(renameBookAction) ||
+//            action == #selector(changeLocationAction) ||
+//            action == #selector(deleteBookAction) {
+//            if self.bookTableView.selectedRowIndexes.count > 1 {
+//                if action == #selector(changeLocationAction) {
+//                    return false
+//                } else if action == #selector(renameBookAction) {
+//                    return false
+//                }
+//            } else {
+//                if self.bookTableView.clickedRow > -1 {
+//                    if action == #selector(changeLocationAction) {
+//    //                    if self.listView.document.bookmark(forPageIndex: UInt(self.listView.currentPageIndex)) != nil {
+//    //                        return false
+//    //                    }
+//                    }
+//                } else {
+//                    return false
+//                }
+//            }
+//        }
+//        return true
+//    }
     
 }
 
@@ -312,14 +294,16 @@ extension KMBookMarkViewController : NSTableViewDelegate,NSTableViewDataSource {
     
     func tableViewSelectionDidChange(_ notification: Notification) {
         for index in self.selectedRowIndexs {
-            if self.bookTableView.selectedRowIndexes.contains(index) {
-                guard let rowView: KMBookMarkTableRowView  = self.bookTableView.rowView(atRow: index, makeIfNecessary: false) as? KMBookMarkTableRowView else { return }
-                
-                rowView.itemSelect = true
-            } else {
-                guard let rowView: KMBookMarkTableRowView  = self.bookTableView.rowView(atRow: index, makeIfNecessary: false) as? KMBookMarkTableRowView else { return }
-                
-                rowView.itemSelect = false
+            if index < self.bookTableView.numberOfRows {
+                if self.bookTableView.selectedRowIndexes.contains(index) {
+                    guard let rowView: KMBookMarkTableRowView  = self.bookTableView.rowView(atRow: index, makeIfNecessary: false) as? KMBookMarkTableRowView else { return }
+                    
+                    rowView.itemSelect = true
+                } else {
+                    guard let rowView: KMBookMarkTableRowView  = self.bookTableView.rowView(atRow: index, makeIfNecessary: false) as? KMBookMarkTableRowView else { return }
+                    
+                    rowView.itemSelect = false
+                }
             }
         }
         
@@ -332,4 +316,125 @@ extension KMBookMarkViewController : NSTableViewDelegate,NSTableViewDataSource {
     }
 }
 
+//MARK: undoRedo
+extension KMBookMarkViewController {
+    func changeLocation(oldBookMark: KMBookMark, newBookMark: KMBookMark) {
+        self.listView.document.removeBookmark(forPageIndex: oldBookMark.index)
+        self.listView.document.addBookmark(newBookMark.label, forPageIndex: newBookMark.index)
+        
+        self.reloadData()
+        self.listView.setNeedsDisplayForVisiblePages()
+        
+        self.undoRedoManager.registerUndo(withTarget: self) { [unowned self] targetType in
+            self.changeLocation(oldBookMark: newBookMark, newBookMark: oldBookMark)
+        }
+    }
+    
+    func renamePDFBook(bookmark : CPDFBookmark! , label:String) {
+        if bookmark.label == label {
+            return
+        }
+        let temp = bookmark.label
+        
+        bookmark.label = label
+        self.reloadData()
+        
+        var indexSet = IndexSet()
+        indexSet.insert(self.bookTableView.row(for: self.renameCellView))
+        self.bookTableView.selectRowIndexes(indexSet, byExtendingSelection: false)
+        
+        self.undoRedoManager.registerUndo(withTarget: self) { [unowned self] targetType in
+            bookmark.label = label
+            self.renamePDFBook(bookmark: bookmark, label: temp ?? bookmark.label)
+        }
+    }
+    
+    func deleteBookMark(bookMarks: [KMBookMark]) {
+        for bookMark in bookMarks {
+            if self.listView.document.removeBookmark(forPageIndex: bookMark.index) {
+                print("删除标签成功")
+            }
+        }
+        self.listView.setNeedsDisplayForVisiblePages()
+        self.reloadData()
+        
+        //undo redo
+        var saveBooks:[KMBookMark] = bookMarks
+        self.undoRedoManager.registerUndo(withTarget: self) { [unowned self] targetType in
+            saveBooks.sort(){$0.index > $1.index}
+            self.addBookMark(bookMarks: bookMarks)
+        }
+    }
+    
+    func addBookMark(bookMarks: [KMBookMark]) {
+        for bookMark in bookMarks {
+            self.listView.document.addBookmark(bookMark.label, forPageIndex: UInt(bookMark.index))
+        }
+        self.listView.setNeedsDisplayForVisiblePages()
+        self.reloadData()
+        
+        if bookMarks.count == 1 {
+            self.addBookMarkAndEdit(newBookMark: self.listView.document.bookmark(forPageIndex: UInt(bookMarks.first!.index)))
+        }
+        
+        //undo redo
+        var saveBooks:[KMBookMark] = bookMarks
+        self.undoRedoManager.registerUndo(withTarget: self) { [unowned self] targetType in
+            saveBooks.sort(){$0.index > $1.index}
+            self.deleteBookMark(bookMarks: saveBooks)
+        }
+    }
+    
+    @IBAction func undo(_ sender: Any) {
+        if (self.undoRedoManager.canUndo) {
+            self.undoRedoManager.undo()
+        }
+    }
+    
+    @IBAction func redo(_ sender: Any) {
+        if (self.undoRedoManager.canRedo) {
+            self.undoRedoManager.redo()
+        }
+    }
+}
 
+extension KMBookMarkViewController : NSMenuDelegate {
+    func validateMenuItem(_ menuItem: NSMenuItem) -> Bool {
+        let action = menuItem.action
+        if (action == #selector(undo)) {
+            return self.undoRedoManager.canUndo
+        }
+        if (action == #selector(redo)) {
+            return self.undoRedoManager.canRedo
+        }
+        
+        if action == #selector(renameBookAction) ||
+            action == #selector(changeLocationAction) ||
+            action == #selector(deleteBookAction) {
+            if self.bookTableView.selectedRowIndexes.count > 1 {
+                if action == #selector(changeLocationAction) {
+                    return false
+                } else if action == #selector(renameBookAction) {
+                    return false
+                }
+            } else {
+                if self.bookTableView.clickedRow > -1 {
+                    if action == #selector(changeLocationAction) {
+                        //                    if self.listView.document.bookmark(forPageIndex: UInt(self.listView.currentPageIndex)) != nil {
+                        //                        return false
+                        //                    }
+                    }
+                } else {
+                    return false
+                }
+            }
+        }
+        return true
+    }
+}
+
+
+struct KMBookMark {
+    var label: String
+    var index: UInt
+}