Browse Source

【BOTA】大纲新增删除undo / redo

lizhe 2 years ago
parent
commit
afca4d8cb5

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

@@ -30,8 +30,8 @@ class KMAnnotationTableRowView: NSTableRowView {
         if self.box == nil {
             var rect = self.bounds
             rect.origin.x = self.bounds.origin.x + 8.0
-            rect.origin.y = self.bounds.origin.y + 2
-            rect.size.height = self.bounds.size.height - 4
+            rect.origin.y = self.bounds.origin.y + 8.0
+            rect.size.height = self.bounds.size.height - 16.0
             rect.size.width = self.bounds.size.width - 16.0
             
             self.box?.wantsLayer = true

+ 121 - 49
PDF Office/PDF Office/Class/PDFWindowController/Side/LeftSide/Outline/KMOutlineViewController.swift

@@ -31,6 +31,9 @@ class KMOutlineViewController: NSViewController,NSMenuItemValidation {
     var renamePDFOutline : CPDFOutline!
     let moreMenu = NSMenu()
     
+    //undo redo
+    private var undoRedoManager: UndoManager = UndoManager()
+    
     func dealloc() {
         
         NotificationCenter.default.removeObserver(self)
@@ -245,14 +248,12 @@ class KMOutlineViewController: NSViewController,NSMenuItemValidation {
         if selectedRowIndexes.count == 0 {
             __NSBeep()
         } else {
-            var selectedPDFOutlineArr = [CPDFOutline]();
+            var outlineItems: [KMOutlineItem] = []
             for index in selectedRowIndexes {
-                var outline : CPDFOutline = self.outlineView.item(atRow: index) as! CPDFOutline
-                selectedPDFOutlineArr.append(outline)
-            }
-            for tOutline in selectedPDFOutlineArr {
-                self.removePDFOutline(outline: tOutline, toIndex: NSInteger(tOutline.index), atParent: tOutline.parent)
+                var outline: CPDFOutline = self.outlineView.item(atRow: index) as! CPDFOutline
+                outlineItems.append(KMOutlineItem(toIndex: index, outline: outline, parent: outline.parent))
             }
+            self.deleteOutline(outlineItems: outlineItems)
         }
         
     }
@@ -341,19 +342,6 @@ class KMOutlineViewController: NSViewController,NSMenuItemValidation {
         self.renameTextField.becomeFirstResponder()
     }
     
-    func renamePDFOutline(outline : CPDFOutline! , label:String) {
-        self.renameTextField.isEditable = false
-        if outline.label == label {
-            return
-        }
-        outline.label = label
-        self.outlineView.reloadData()
-        
-        var indexSet = IndexSet()
-        indexSet.insert(self.outlineView.row(forItem: outline))
-        self.outlineView.selectRowIndexes(indexSet, byExtendingSelection: false)
-    }
-    
     func movePDFOutline(outline : CPDFOutline! , toIndex index : NSInteger , atParent parent : CPDFOutline!) {
         outline.removeFromParent()
         parent.insertChild(outline, at: UInt(index))
@@ -395,7 +383,9 @@ class KMOutlineViewController: NSViewController,NSMenuItemValidation {
             let outline = parent?.insertChild(at: UInt(index))
             outline?.label = string
             outline?.destination = self.listView.currentDestination
-            self.addPDFOutline(outline: outline, toIndex: index, atParent: parent)
+            
+            let outlineItem = KMOutlineItem(toIndex: index, outline: outline!, parent: parent!)
+            self.addOutline(outlineItems: [outlineItem])
         } else {
             __NSBeep()
         }
@@ -412,8 +402,8 @@ class KMOutlineViewController: NSViewController,NSMenuItemValidation {
             if tPage < 0 {
                 continue
             }
-            var page = self.listView.document.page(at: UInt(tPage))!
-            var tDict : [String : CPDFPage] = ["\(i)":page]
+            let page = self.listView.document.page(at: UInt(tPage))!
+            let tDict : [String : CPDFPage] = ["\(i)":page]
             arr.append(tDict)
         }
         DispatchQueue.global(qos: .utility).async{
@@ -461,38 +451,26 @@ class KMOutlineViewController: NSViewController,NSMenuItemValidation {
         self.outlineView.reloadData()
     }
     
-    func addPDFOutlineToIndex(index:NSInteger, atParent parent:CPDFOutline!) {
+    func addPDFOutlineToIndex(index: NSInteger, atParent parent: CPDFOutline!) {
         let currentPageIndex = self.listView.currentPageIndex
-        var outline = parent.insertChild(at: UInt(index))
-        outline?.label =  "\(NSLocalizedString("Page", comment: ""))\(currentPageIndex+1)"
+        
+        var destination: CPDFDestination
         let des = self.listView.currentDestination
         if "\(des?.point.x ?? 0)" != "nan" {
-            outline?.destination = self.listView.currentDestination
+            destination = self.listView.currentDestination
         } else {
-            let destination : CPDFDestination = CPDFDestination(document: self.listView.document, pageIndex: currentPageIndex, at: CGPoint(x: 0, y: 0), zoom: self.listView.scaleFactor)
-            outline?.destination = destination
+            destination = CPDFDestination(document: self.listView.document, pageIndex: currentPageIndex, at: CGPoint(x: 0, y: 0), zoom: self.listView.scaleFactor)
         }
-        self.addPDFOutline(outline:outline,toIndex: index,atParent: parent)
-    }
-    
-    func addPDFOutline(outline:CPDFOutline? , toIndex index : NSInteger , atParent parent : CPDFOutline!) {
-        self.view.window?.makeFirstResponder(self.outlineView)
-        if outline?.parent == nil {
-            parent.insertChild(outline, at: UInt(index))
-        }
-        self.outlineView.reloadData()
-        self.outlineView.expandItem(parent)
-        let indexSet : IndexSet = [self.outlineView.row(forItem: outline)]
-        self.outlineView.selectRowIndexes(indexSet, byExtendingSelection: false)
-        if(self.outlineView.selectedRow >= 0) {
-            self.renameOutlineWithRow(row: self.outlineView.selectedRow)
-        }
-        if Thread.current.isMainThread {
-            self.outlineView.scrollToVisible(self.outlineView.rect(ofRow: index))
-        } else {
-            DispatchQueue.main.async {
-                self.outlineView.scrollToVisible(self.outlineView.rect(ofRow: index))
-            }
+        
+        var outline = parent.insertChild(at: UInt(index))
+        outline?.destination = destination
+        
+        let label = "\(NSLocalizedString("Page", comment: ""))\(currentPageIndex + 1)"
+        outline?.label = label
+        
+        if outline != nil {
+            let outlineItem = KMOutlineItem(toIndex: index, outline: outline!, parent: parent)
+            self.addOutline(outlineItems: [outlineItem])
         }
     }
     
@@ -807,3 +785,97 @@ extension KMOutlineViewController : NSPopoverDelegate {
         }
     }
 }
+
+//MARK: undoRedo
+extension KMOutlineViewController {
+    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 renamePDFOutline(outline: CPDFOutline!, label: String) {
+        self.renameTextField.isEditable = false
+        if outline.label == label {
+            return
+        }
+        let temp: String = outline.label
+        outline.label = label
+        self.outlineView.reloadData()
+        
+        var indexSet = IndexSet()
+        indexSet.insert(self.outlineView.row(forItem: outline))
+        self.outlineView.selectRowIndexes(indexSet, byExtendingSelection: false)
+        
+        self.undoRedoManager.registerUndo(withTarget: self) { [unowned self] targetType in
+            self.renamePDFOutline(outline: outline, label: temp)
+        }
+    }
+    
+    func deleteOutline(outlineItems: [KMOutlineItem]) {
+        for outlineItem in outlineItems {
+            outlineItem.outline.removeFromParent()
+            self.outlineView.reloadData()
+            self.outlineView.expandItem(parent)
+        }
+
+        self.undoRedoManager.registerUndo(withTarget: self) { targetType in
+            self.addOutline(outlineItems: outlineItems)
+        }
+    }
+    
+    func addOutline(outlineItems: [KMOutlineItem]) {
+        self.view.window?.makeFirstResponder(self.outlineView)
+        for outlineItem in outlineItems {
+            if outlineItem.outline.parent == nil {
+                outlineItem.parent.insertChild(outlineItem.outline, at: UInt(outlineItem.toIndex))
+            }
+            self.outlineView.reloadData()
+            self.outlineView.expandItem(outlineItem.parent)
+        }
+        
+        if outlineItems.count == 1 {
+            let outlineItem: KMOutlineItem = outlineItems.first!
+            let indexSet : IndexSet = [self.outlineView.row(forItem: outlineItem.outline)]
+            self.outlineView.selectRowIndexes(indexSet, byExtendingSelection: false)
+            if(self.outlineView.selectedRow >= 0) {
+                self.renameOutlineWithRow(row: self.outlineView.selectedRow)
+            }
+            if Thread.current.isMainThread {
+                self.outlineView.scrollToVisible(self.outlineView.rect(ofRow: outlineItem.toIndex))
+            } else {
+                DispatchQueue.main.async {
+                    self.outlineView.scrollToVisible(self.outlineView.rect(ofRow: outlineItem.toIndex))
+                }
+            }
+        }
+        
+        self.undoRedoManager.registerUndo(withTarget: self) { targetType in
+            self.deleteOutline(outlineItems: outlineItems)
+        }
+    }
+    
+    @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 KMOutlineItem {
+        var toIndex: Int
+        var outline: CPDFOutline
+        var parent: CPDFOutline
+    }
+}