Browse Source

【综合】BOTA 搜索大纲,结果与内容不匹配(已修复)

tangchao 1 year ago
parent
commit
9df5363812

+ 1 - 0
PDF Office/PDF Master/Class/PDFWindowController/Side/LeftSide/KMLeftSideViewController+Thumbnail.swift

@@ -129,6 +129,7 @@ extension KMLeftSideViewController {
         
         //        [thumbnailTableView registerForDraggedTypes:@[KPDFThumbnailLocalForDraggedTypes,NSFilenamesPboardType]];
         self.thumbnailTableView.registerForDraggedTypes([.localDraggedTypes, .fileURL,.string,.pdf])
+        self.thumbnailTableView.registerForDraggedTypes(NSFilePromiseReceiver.readableDraggedTypes.map { NSPasteboard.PasteboardType($0) })
         self.thumbnailTableView.setDraggingSourceOperationMask(.every, forLocal: false)
     }
     

+ 192 - 13
PDF Office/PDF Master/Class/PDFWindowController/Side/LeftSide/KMLeftSideViewController.swift

@@ -267,6 +267,15 @@ class KMLeftSideViewController: KMSideViewController {
     
     var updatingOutlineSelection = false
     
+    fileprivate var dragFilePath: String?
+    var dragFlag = false
+    var filePromiseQueue: OperationQueue = {
+        let queue = OperationQueue()
+        return queue
+    }()
+    var dragIn = false
+    var dragedIndexPaths: [Int] = []
+    
     override func loadView() {
         super.loadView()
         
@@ -1181,7 +1190,6 @@ extension KMLeftSideViewController {
             }
             return subHas
         }
-        return false
     }
 }
 
@@ -1680,6 +1688,7 @@ extension KMLeftSideViewController: NSTableViewDelegate, NSTableViewDataSource {
                     pboard.declareTypes([.tiff, .filePromise], owner: self)
                 }
                 pboard.setData(tiffData, forType: .tiff)
+                // kPasteboardTypeFileURLPromise
                 pboard.setPropertyList([fileExt], forType: .filePromise)
 
                 return true
@@ -1699,6 +1708,89 @@ extension KMLeftSideViewController: NSTableViewDelegate, NSTableViewDataSource {
         return false
     }
     
+//    func tableView(_ tableView: NSTableView, pasteboardWriterForRow row: Int) -> NSPasteboardWriting? {
+//        var provider: NSFilePromiseProvider?
+//
+//         创建数据提供者
+//        let fileExtension = "pdf"
+//        if #available(macOS 11.0, *) {
+//            let typeIdentifier = UTType(filenameExtension: fileExtension)
+//            provider = KMFilePromiseProvider(fileType: typeIdentifier!.identifier, delegate: self)
+//        } else {
+//            let typeIdentifier =
+//                  UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, fileExtension as CFString, nil)
+//            provider = KMFilePromiseProvider(fileType: typeIdentifier!.takeRetainedValue() as String, delegate: self)
+//        }
+//
+//        // 记录拖拽索引
+//        self.dragedIndexPaths.append(row)
+//        do {
+//            if let _url = self.listView.document?.documentURL {
+//                let data = try NSKeyedArchiver.archivedData(withRootObject: row, requiringSecureCoding: false)
+//                provider!.userInfo = [KMFilePromiseProvider.UserInfoKeys.urlKey: _url,
+//                                      KMFilePromiseProvider.UserInfoKeys.indexPathKey: data]
+//            } else {
+//                let data = try NSKeyedArchiver.archivedData(withRootObject: row, requiringSecureCoding: false)
+//                provider!.userInfo = [KMFilePromiseProvider.UserInfoKeys.indexPathKey: data]
+//            }
+//        } catch {
+//            fatalError("failed to archive indexPath to pasteboard")
+//        }
+//        return provider
+//    }
+    
+    func tableView(_ tableView: NSTableView, draggingSession session: NSDraggingSession, willBeginAt screenPoint: NSPoint, forRowIndexes rowIndexes: IndexSet) {
+//        if self.isNeedMarkerLine {
+//            self.markBeginIndexes = collectionView.selectionIndexes
+//        }
+        
+        // 将拖拽的page插入临时路径(文档)
+        var indexs = IndexSet()
+        for indexpath in self.dragedIndexPaths {
+            indexs.insert(indexpath)
+        }
+        // 清空临时数据
+        if let _path = self.dragTempFilePath, FileManager.default.fileExists(atPath: _path) {
+            try?FileManager.default.removeItem(atPath: _path)
+        }
+            
+        // 重置拖拽标识
+        self.dragFlag = false
+        if (indexs.count > 0) {
+            let document = CPDFDocument()
+            document?.importPages(indexs, from: self.listView.document, at: 0)
+            if let data = self.dragTempFloderPath, !FileManager.default.fileExists(atPath: data) {
+                try?FileManager.default.createDirectory(atPath: data, withIntermediateDirectories: false)
+            }
+            if let data = self.dragTempFilePath, !FileManager.default.fileExists(atPath: data) {
+                FileManager.default.createFile(atPath: data, contents: nil)
+            }
+            
+            if let data = self.dragTempFilePath {
+                document?.write(to: URL(fileURLWithPath: data))
+            }
+            self.dragFilePath = self.dragTempFilePath
+        }
+    }
+    
+    func tableView(_ tableView: NSTableView, draggingSession session: NSDraggingSession, endedAt screenPoint: NSPoint, operation: NSDragOperation) {
+        if (!self.dragIn) {
+//            var indexpaths = Set<IndexPath>()
+//            for indexpath in self.dragedIndexPaths {
+//                indexpaths.insert(indexpath)
+//            }
+            // 清空数据
+            self.dragedIndexPaths.removeAll()
+            // 刷新数据
+//            self.reloadData()
+            // 重新选中数据
+//            self.selectionIndexPaths = indexpaths
+        } else {
+            Swift.debugPrint("拖入文件 或 本地拖拽")
+        }
+        self.dragIn = false
+    }
+    
     @objc dynamic func tableView(_ aTableView: NSTableView, deleteRowsWithIndexes rowIndexes: IndexSet) {
         if IAPProductsManager.default().isAvailableAllFunction() == false {
             KMPurchaseCompareWindowController.sharedInstance().showWindow(nil)
@@ -1904,6 +1996,75 @@ extension KMLeftSideViewController: NSTableViewDelegate, NSTableViewDataSource {
      */
 }
 
+// MARK: - NSFilePromiseProviderDelegate
+
+extension KMLeftSideViewController: NSFilePromiseProviderDelegate {
+    func filePromiseProvider(_ filePromiseProvider: NSFilePromiseProvider, fileNameForType fileType: String) -> String {
+        var fileName: String = "Untitle"
+        if let _string = self.listView?.document?.documentURL.deletingPathExtension().lastPathComponent {
+            fileName = _string
+        }
+        fileName.append(" pages")
+        var indexs = IndexSet()
+        for indexpath in self.dragedIndexPaths {
+            indexs.insert(indexpath)
+        }
+        fileName.append(" ")
+        fileName.append(KMPageRangeTools.newParseSelectedIndexs(selectedIndex: indexs.sorted()))
+        fileName.append(".pdf")
+        
+        return fileName
+    }
+    
+    func filePromiseProvider(_ filePromiseProvider: NSFilePromiseProvider,
+                             writePromiseTo url: URL,
+                             completionHandler: @escaping (Error?) -> Void) {
+        do {
+            /** Copy the file to the location provided to you. You always do a copy, not a move.
+             It's important you call the completion handler.
+             */
+            if let _urlString = self.dragFilePath, !self.dragFlag {
+                self.dragFlag = true
+//                if let should = self.delegate?.thumbnailView?(thumbanView: self, shouldPasteboardWriterForItemAt: IndexPath(item: 0, section: 0)), !should {
+//                    completionHandler(nil)
+//                    return
+//                }
+                
+                try FileManager.default.copyItem(at: URL(fileURLWithPath: _urlString), to: url)
+            }
+            
+            completionHandler(nil)
+        } catch let error {
+            OperationQueue.main.addOperation {
+                self.presentError(error, modalFor: self.view.window!,
+                                  delegate: nil, didPresent: nil, contextInfo: nil)
+            }
+            completionHandler(error)
+        }
+    }
+    
+    /** You should provide a non main operation queue (e.g. one you create) via this function.
+     This way you don't stall the main thread while writing the promise file.
+     */
+    func operationQueue(for filePromiseProvider: NSFilePromiseProvider) -> OperationQueue {
+        return self.filePromiseQueue
+    }
+    
+}
+
+extension KMLeftSideViewController {
+    var dragTempFloderPath: String? {
+        get {
+            return NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.applicationSupportDirectory, FileManager.SearchPathDomainMask.userDomainMask, true).last?.stringByAppendingPathComponent(Bundle.main.bundleIdentifier!).stringByAppendingPathComponent("KMPDFThumbnailView_Drag_Temp")
+        }
+    }
+    var dragTempFilePath: String? {
+        get {
+            return self.dragTempFloderPath?.stringByAppendingPathComponent("drag_tmp.pdf")
+        }
+    }
+}
+
 // MARK: - NSOutlineViewDelegate, NSOutlineViewDataSource
 
 /*
@@ -2248,7 +2409,22 @@ extension KMLeftSideViewController: NSOutlineViewDelegate, NSOutlineViewDataSour
                 if let data = item as? String, data == "Bookmarks" {
                     return array[index]
                 } else if item is CPDFOutline {
-                    return (item as! CPDFOutline).child(at: UInt(index))
+                    let child = item as! CPDFOutline
+//                    if child.numberOfChildren == 0 {
+//                        return 0
+//                    }
+                    var array: [CPDFOutline] = []
+                    for i in 0 ..< child.numberOfChildren {
+                        if let _child = child.child(at: i) {
+                            if self._hasContainString(self.outlineSearchField.stringValue, rootOutline: _child) {
+//                                num += 1
+                                array.append(_child)
+                            }
+                        }
+                    }
+                    
+//                    return (item as! CPDFOutline).child(at: UInt(index))
+                    return array[index]
                 } else if item is CPDFBookmark {
                     return ""
                 }
@@ -2380,17 +2556,20 @@ extension KMLeftSideViewController: NSOutlineViewDelegate, NSOutlineViewDataSour
                 if (self.isSearchOutlineMode) {
 //                    NSString *roughString = [[ol label] stringByCollapsingWhitespaceAndNewlinesAndRemovingSurroundingWhitespaceAndNewlines];
                     let roughString = title
-//                    NSArray *arr = [self allRangeOfRoughString:roughString searchString:self.leftSideController.outlineSearchField.stringValue];
-//                    NSMutableAttributedString *attributeString = [[[NSMutableAttributedString alloc] initWithString:roughString] autorelease];
-//
-//                    for (NSUInteger i = 0; i <arr.count ; i++) {
-//                        NSValue * rangeValue = arr[i];
-//                        NSRange range = rangeValue.rangeValue;
-//                        range.location += i * self.leftSideController.outlineSearchField.stringValue.length;
-//                        [attributeString addAttribute:NSFontAttributeName value:[NSFont boldSystemFontOfSize:13] range:range];
-//                    }
-//                    cell.tocLabel.attributedStringValue = attributeString;
-                    cell.tocLabel.stringValue = title
+                    var attributeString = NSMutableAttributedString(string: roughString)
+                    let searchString = self.outlineSearchField.stringValue
+                    var _roughString = roughString
+                    var _searchString = searchString
+                    if self.outlineIgnoreCaseFlag {
+                        _roughString = _roughString.lowercased()
+                        _searchString = _searchString.lowercased()
+                    }
+                    
+                    let ranges = _roughString.ranges(of: _searchString)
+                    for range in ranges.nsRnage {
+                        attributeString.addAttribute(.font, value: NSFont.boldSystemFont(ofSize: 13), range: range)
+                    }
+                    cell.tocLabel.attributedStringValue = attributeString
                 } else {
                     cell.tocLabel.stringValue = title
                 }