|
@@ -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
|
|
|
}
|