|
@@ -7,60 +7,72 @@
|
|
|
|
|
|
import Cocoa
|
|
|
|
|
|
+private let kLabel = NSUserInterfaceItemIdentifier("label")
|
|
|
+private let kFile = NSUserInterfaceItemIdentifier("file")
|
|
|
+private let kPage = NSUserInterfaceItemIdentifier("page")
|
|
|
+
|
|
|
+let kTextWithIconStringKey = "string";
|
|
|
+let kTextWithIconImageKey = "image";
|
|
|
+
|
|
|
let kBookmarksToolbarIdentifier = "BookmarksToolbarIdentifier"
|
|
|
let kBookmarksNewFolderToolbarItemIdentifier = "BookmarksNewFolderToolbarItemIdentifier"
|
|
|
let kBookmarksNewSeparatorToolbarItemIdentifier = "BookmarksNewSeparatorToolbarItemIdentifier"
|
|
|
let kBookmarksDeleteToolbarItemIdentifier = "BookmarksDeleteToolbarItemIdentifier"
|
|
|
|
|
|
+let kPasteboardTypeBookmarkRows = NSPasteboard.PasteboardType(rawValue: "pasteboard.bookmarkrows")
|
|
|
class KMBookmarkController: NSWindowController {
|
|
|
|
|
|
- @IBOutlet weak var outlineView: NSOutlineView!
|
|
|
+ @IBOutlet weak var outlineView: KMCustomOutlineView!
|
|
|
+
|
|
|
+ var draggedBookmarks: [KMBookmark] = []
|
|
|
+ var recentDocuments: [[String: Any]] {
|
|
|
+ get {
|
|
|
+ return KMBookmarkManager.manager.recentDocuments
|
|
|
+ }
|
|
|
+
|
|
|
+ set {
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ var bookmarkRoot: KMRootBookmark {
|
|
|
+ get {
|
|
|
+ return KMBookmarkManager.manager.rootBookmark
|
|
|
+ }
|
|
|
+ set {
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
var toolbarItems: [String: NSToolbarItem] = [:]
|
|
|
override func windowDidLoad() {
|
|
|
super.windowDidLoad()
|
|
|
setupToolbar()
|
|
|
|
|
|
-// if let window = self.window, window.responds(to: #selector(setter: NSWindow.tabbingMode)) {
|
|
|
-// window.tabbingMode = .disallowed
|
|
|
-// }
|
|
|
-
|
|
|
-// windowFrameAutosaveName = SKBookmarksWindowFrameAutosaveName
|
|
|
-
|
|
|
-// window?.autorecalculatesContentBorderThickness = false
|
|
|
-// if UserDefaults.standard.bool(forKey: SKShowBookmarkStatusBarKey) == false {
|
|
|
-// toggleStatusBar(nil)
|
|
|
-// } else {
|
|
|
-// window?.setContentBorderThickness(22.0, for: .minY)
|
|
|
-// }
|
|
|
-
|
|
|
-// outlineView.setTypeSelectHelper(SKTypeSelectHelper.typeSelectHelper())
|
|
|
-
|
|
|
-// outlineView.registerForDraggedTypes([SKPasteboardTypeBookmarkRows, kUTTypeFileURL as String, NSFilenamesPboardType])
|
|
|
-
|
|
|
-// outlineView.doubleAction = #selector(doubleClickBookmark(_:))
|
|
|
-
|
|
|
-// outlineView.supportsQuickLook = true
|
|
|
+ outlineView.delegate = self
|
|
|
+ outlineView.dataSource = self
|
|
|
+ outlineView.registerForDraggedTypes([kPasteboardTypeBookmarkRows, .fileURL, .string])
|
|
|
+ outlineView.doubleAction = #selector(doubleClickBookmark(_:))
|
|
|
}
|
|
|
|
|
|
-// func updateStatus() {
|
|
|
-// let row = outlineView.selectedRow
|
|
|
-// var message = ""
|
|
|
-// if row != -1 {
|
|
|
-// if let bookmark = outlineView.item(atRow: row) as? KMBookmark {
|
|
|
-// switch bookmark.bookmarkType {
|
|
|
-// case .bookmark:
|
|
|
-// message = bookmark.fileURL?.path ?? ""
|
|
|
-// case .folder:
|
|
|
-// let count = bookmark.children.count
|
|
|
-// message = count == 1 ? NSLocalizedString("1 item", comment: "Bookmark folder description") : String(format: NSLocalizedString("%ld items", comment: "Bookmark folder description"), count)
|
|
|
-// default:
|
|
|
-// break
|
|
|
-// }
|
|
|
-// }
|
|
|
-// }
|
|
|
-//// statusBar.leftStringValue = message
|
|
|
-// }
|
|
|
+ func updateStatus() {
|
|
|
+ let row = outlineView.selectedRow
|
|
|
+ var message = ""
|
|
|
+ if row != -1 {
|
|
|
+ if let bookmark = outlineView.item(atRow: row) as? KMBookmark {
|
|
|
+ switch bookmark.bookmarkType {
|
|
|
+ case .bookmark:
|
|
|
+ message = bookmark.fileURL?.path ?? ""
|
|
|
+ case .folder:
|
|
|
+ let count = bookmark.children.count
|
|
|
+ message = count == 1 ? NSLocalizedString("1 item", comment: "Bookmark folder description") : String(format: NSLocalizedString("%ld items", comment: "Bookmark folder description"), count)
|
|
|
+ default:
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+// statusBar.leftStringValue = message
|
|
|
+ }
|
|
|
//
|
|
|
static func showBookmarkController() -> KMBookmarkController {
|
|
|
let controller = KMBookmarkController.init(windowNibName: "KMBookmarkController")
|
|
@@ -71,23 +83,21 @@ class KMBookmarkController: NSWindowController {
|
|
|
//
|
|
|
//
|
|
|
// //MARK: Recent Documents
|
|
|
-// func recentDocumentInfo(at fileURL: URL) -> [String: Any]? {
|
|
|
-// let path = fileURL.path
|
|
|
-// for info in recentDocuments as! [[String: Any]] {
|
|
|
+ func recentDocumentInfo(at fileURL: URL) -> [String: Any]? {
|
|
|
+ let path = fileURL.path
|
|
|
+ for info in recentDocuments {
|
|
|
// if let aliasData = info[ALIASDATA_KEY] as? Data,
|
|
|
// let alias = SKAlias(aliasData),
|
|
|
// alias.fileURLNoUI?.path.caseInsensitiveCompare(path) == .orderedSame {
|
|
|
// return info
|
|
|
// }
|
|
|
-// }
|
|
|
-// return nil
|
|
|
-// }
|
|
|
+ }
|
|
|
+ return nil
|
|
|
+ }
|
|
|
//
|
|
|
-// func addRecentDocument(for fileURL: URL, pageIndex: UInt, scaleFactor factor: CGFloat, snapshots setups: [Any]?) {
|
|
|
-// guard let fileURL = fileURL else { return }
|
|
|
-//
|
|
|
+ func addRecentDocument(for fileURL: URL, pageIndex: UInt, scaleFactor factor: CGFloat, snapshots setups: [Any]?) {
|
|
|
// if let info = recentDocumentInfo(at: fileURL) {
|
|
|
-// recentDocuments.removeObject(identicalTo: info)
|
|
|
+// recentDocuments.removeObject(info)
|
|
|
// }
|
|
|
//
|
|
|
// if let alias = SKAlias(url: fileURL) {
|
|
@@ -103,7 +113,7 @@ class KMBookmarkController: NSWindowController {
|
|
|
// recentDocuments.removeLastObject()
|
|
|
// }
|
|
|
// }
|
|
|
-// }
|
|
|
+ }
|
|
|
//
|
|
|
// func pageIndex(forRecentDocumentAt fileURL: URL) -> UInt {
|
|
|
// guard let fileURL = fileURL else { return UInt.max }
|
|
@@ -130,7 +140,7 @@ class KMBookmarkController: NSWindowController {
|
|
|
// }
|
|
|
//
|
|
|
// //MARK: Bookmarks support
|
|
|
- func getInsertionFolder(_ bookmarkPtr: inout KMBookmark?, childIndex indexPtr: inout UInt) {
|
|
|
+ func getInsertionFolder(_ bookmarkPtr: inout KMBookmark?, childIndex indexPtr: inout Int) {
|
|
|
let rowIndex = outlineView.clickedRow
|
|
|
var indexes = outlineView.selectedRowIndexes
|
|
|
if rowIndex != -1 && !indexes.contains(rowIndex) {
|
|
@@ -154,22 +164,22 @@ class KMBookmarkController: NSWindowController {
|
|
|
}
|
|
|
|
|
|
bookmarkPtr = item
|
|
|
- indexPtr = UInt(idx)
|
|
|
+ indexPtr = idx
|
|
|
+ }
|
|
|
+
|
|
|
+ @IBAction func openBookmark(_ sender: Any) {
|
|
|
+ if let bookmark = (sender as AnyObject).representedObject as? KMBookmark {
|
|
|
+ bookmark.open()
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @IBAction func doubleClickBookmark(_ sender: Any) {
|
|
|
+ let row = outlineView.clickedRow
|
|
|
+ if let bm = (row != -1 ? outlineView.item(atRow: row) : nil) as? KMBookmark,
|
|
|
+ [KMBookmarkType.bookmark, .session].contains(bm.bookmarkType) {
|
|
|
+ bm.open()
|
|
|
+ }
|
|
|
}
|
|
|
-//
|
|
|
-// @IBAction func openBookmark(_ sender: Any) {
|
|
|
-// if let bookmark = (sender as AnyObject).representedObject as? SKBookmark {
|
|
|
-// bookmark.open()
|
|
|
-// }
|
|
|
-// }
|
|
|
-//
|
|
|
-// @IBAction func doubleClickBookmark(_ sender: Any) {
|
|
|
-// let row = outlineView.clickedRow
|
|
|
-// if let bm = (row != -1 ? outlineView.item(atRow: row) : nil) as? SKBookmark,
|
|
|
-// [SKBookmarkType.bookmark, .session].contains(bm.bookmarkType) {
|
|
|
-// bm.open()
|
|
|
-// }
|
|
|
-// }
|
|
|
|
|
|
|
|
|
func deleteBookmarks(bookmarks: [KMBookmark]) {
|
|
@@ -183,7 +193,7 @@ class KMBookmarkController: NSWindowController {
|
|
|
@IBAction func insertBookmarkFolder(_ sender: Any) {
|
|
|
let folder = KMFolderBookmark.folderBookmark(label: NSLocalizedString("Folder", comment: "default folder name"))
|
|
|
var item: KMBookmark?
|
|
|
- var idx: UInt = 0
|
|
|
+ var idx: Int = 0
|
|
|
|
|
|
getInsertionFolder(&item, childIndex: &idx)
|
|
|
item?.insert(child: folder, atIndex: idx)
|
|
@@ -196,7 +206,7 @@ class KMBookmarkController: NSWindowController {
|
|
|
@IBAction func insertBookmarkSeparator(_ sender: Any) {
|
|
|
let separator = KMSeparatorBookmark()
|
|
|
var item: KMBookmark?
|
|
|
- var idx: UInt = 0
|
|
|
+ var idx: Int = 0
|
|
|
|
|
|
getInsertionFolder(&item, childIndex: &idx)
|
|
|
item?.insert(child: separator, atIndex: idx)
|
|
@@ -204,37 +214,37 @@ class KMBookmarkController: NSWindowController {
|
|
|
let row = outlineView.row(forItem: separator)
|
|
|
outlineView.selectRowIndexes(IndexSet(integer: row), byExtendingSelection: false)
|
|
|
}
|
|
|
-//
|
|
|
-// @IBAction func addBookmark(_ sender: Any) {
|
|
|
-// let openPanel = NSOpenPanel()
|
|
|
-// var types = [String]()
|
|
|
-// for docClass in NSDocumentController.shared.documentClassNames {
|
|
|
-// if let docClass = NSClassFromString(docClass) as? NSDocument.Type {
|
|
|
-// types += docClass.readableTypes
|
|
|
-// }
|
|
|
-// }
|
|
|
-// openPanel.allowsMultipleSelection = true
|
|
|
-// openPanel.canChooseDirectories = true
|
|
|
-// openPanel.allowedFileTypes = types
|
|
|
-// openPanel.beginSheetModal(for: self.window!) { (result) in
|
|
|
-// guard result == .OK else { return }
|
|
|
-// let newBookmarks = SKBookmark.bookmarks(forURLs: openPanel.urls)
|
|
|
-// if !newBookmarks.isEmpty {
|
|
|
-// var item: SKBookmark?
|
|
|
-// var index: UInt = 0
|
|
|
-// self.getInsertionFolder(&item, childIndex: &index)
|
|
|
-// var indexes = IndexSet(integersIn: Int(index)..<Int(index + UInt(newBookmarks.count)))
|
|
|
-// item?.mutableArrayValue(forKey: "children").insert(newBookmarks, at: indexes)
|
|
|
-// if item == self.bookmarkRoot || self.outlineView.isItemExpanded(item) {
|
|
|
-// if item != self.bookmarkRoot {
|
|
|
-// indexes.shift(startingAt: 0, by: self.outlineView.row(forItem: item)! + 1)
|
|
|
-// }
|
|
|
-// self.outlineView.selectRowIndexes(indexes, byExtendingSelection: false)
|
|
|
-// }
|
|
|
-// }
|
|
|
-// }
|
|
|
-// }
|
|
|
-//
|
|
|
+
|
|
|
+ @IBAction func addBookmark(_ sender: Any) {
|
|
|
+ let openPanel = NSOpenPanel()
|
|
|
+ var types = [String]()
|
|
|
+ for docClass in NSDocumentController.shared.documentClassNames {
|
|
|
+ if let docClass = NSClassFromString(docClass) as? NSDocument.Type {
|
|
|
+ types += docClass.readableTypes
|
|
|
+ }
|
|
|
+ }
|
|
|
+ openPanel.allowsMultipleSelection = true
|
|
|
+ openPanel.canChooseDirectories = true
|
|
|
+ openPanel.allowedFileTypes = types
|
|
|
+ openPanel.beginSheetModal(for: self.window!) { (result) in
|
|
|
+ guard result == .OK else { return }
|
|
|
+ let newBookmarks = KMBookmark.bookmarks(urls: openPanel.urls)
|
|
|
+ if newBookmarks != nil {
|
|
|
+ var item: KMBookmark?
|
|
|
+ var index: Int = 0
|
|
|
+ self.getInsertionFolder(&item, childIndex: &index)
|
|
|
+ var indexes = IndexSet(integersIn: Int(index)..<Int(index + newBookmarks.count))
|
|
|
+ item?.mutableArrayValue(forKey: "children").insert(newBookmarks, at: indexes)
|
|
|
+ if item == self.bookmarkRoot || self.outlineView.isItemExpanded(item) {
|
|
|
+ if item != self.bookmarkRoot {
|
|
|
+ indexes.shift(startingAt: 0, by: self.outlineView.row(forItem: item) + 1)
|
|
|
+ }
|
|
|
+ self.outlineView.selectRowIndexes(indexes, byExtendingSelection: false)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
@IBAction func deleteBookmark(_ sender: Any) {
|
|
|
self.deleteBookmarks(bookmarks: [])
|
|
|
}
|
|
@@ -255,7 +265,7 @@ class KMBookmarkController: NSWindowController {
|
|
|
// }
|
|
|
//
|
|
|
// @IBAction func deleteBookmarks(_ sender: Any) {
|
|
|
-// guard let items = clickedBookmarks() as? [SKBookmark] else { return }
|
|
|
+// guard let items = clickedBookmarks() as? [KMBookmark] else { return }
|
|
|
// for item in items.reversed() {
|
|
|
// if let parent = item.parent, let itemIndex = parent.children.index(of: item) {
|
|
|
// parent.removeObject(fromChildrenAtIndex: itemIndex)
|
|
@@ -264,7 +274,7 @@ class KMBookmarkController: NSWindowController {
|
|
|
// }
|
|
|
//
|
|
|
// @IBAction func openBookmarks(_ sender: Any) {
|
|
|
-// guard let items = clickedBookmarks() as? [SKBookmark] else { return }
|
|
|
+// guard let items = clickedBookmarks() as? [KMBookmark] else { return }
|
|
|
// for item in items.reversed() {
|
|
|
// item.open()
|
|
|
// }
|
|
@@ -282,7 +292,7 @@ class KMBookmarkController: NSWindowController {
|
|
|
//
|
|
|
// // MARK: - NSMenu delegate methods
|
|
|
//
|
|
|
-// func addItemForBookmark(_ bookmark: SKBookmark, toMenu menu: NSMenu, isFolder: Bool, isAlternate: Bool) {
|
|
|
+// func addItemForBookmark(_ bookmark: KMBookmark, toMenu menu: NSMenu, isFolder: Bool, isAlternate: Bool) {
|
|
|
// var item: NSMenuItem?
|
|
|
// if isFolder {
|
|
|
// item = menu.addItem(withSubmenuAndTitle: bookmark.label)
|
|
@@ -313,7 +323,7 @@ class KMBookmarkController: NSWindowController {
|
|
|
// menu.addItem(withTitle: NSLocalizedString("New Folder", comment: "Menu item title"), action: #selector(insertBookmarkFolder(_:)), target: self)
|
|
|
// menu.addItem(withTitle: NSLocalizedString("New Separator", comment: "Menu item title"), action: #selector(insertBookmarkSeparator(_:)), target: self)
|
|
|
// } else {
|
|
|
-// guard let supermenu = menu.supermenu, let idx = supermenu.indexOfItem(withSubmenu: menu), let bm = (supermenu == NSApp.mainMenu) ? bookmarkRoot : supermenu.item(at: idx)?.representedObject as? SKBookmark else { return }
|
|
|
+// guard let supermenu = menu.supermenu, let idx = supermenu.indexOfItem(withSubmenu: menu), let bm = (supermenu == NSApp.mainMenu) ? bookmarkRoot : supermenu.item(at: idx)?.representedObject as? KMBookmark else { return }
|
|
|
//
|
|
|
// let bookmarks = bm.children
|
|
|
// var i = menu.numberOfItems
|
|
@@ -422,11 +432,11 @@ class KMBookmarkController: NSWindowController {
|
|
|
// func endPreviewPanelControl(_ panel: QLPreviewPanel) {
|
|
|
// }
|
|
|
//
|
|
|
-// func previewItems() -> [SKBookmark] {
|
|
|
-// var items = [SKBookmark]()
|
|
|
+// func previewItems() -> [KMBookmark] {
|
|
|
+// var items = [KMBookmark]()
|
|
|
//
|
|
|
// outlineView.selectedRowIndexes.enumerated().forEach { (idx, _) in
|
|
|
-// if let item = outlineView.item(atRow: idx) as? SKBookmark {
|
|
|
+// if let item = outlineView.item(atRow: idx) as? KMBookmark {
|
|
|
// if item.bookmarkType == .bookmark {
|
|
|
// items.append(item)
|
|
|
// } else if item.bookmarkType == .session {
|
|
@@ -447,12 +457,12 @@ class KMBookmarkController: NSWindowController {
|
|
|
//
|
|
|
// func previewPanel(_ panel: QLPreviewPanel, sourceFrameOnScreenForPreviewItem item: QLPreviewItem) -> NSRect {
|
|
|
// var item = item
|
|
|
-// if let parent = (item as? SKBookmark)?.parent, parent.bookmarkType == .session {
|
|
|
+// if let parent = (item as? KMBookmark)?.parent, parent.bookmarkType == .session {
|
|
|
// item = parent
|
|
|
// }
|
|
|
// let row = outlineView.row(forItem: item)
|
|
|
// var iconRect = NSZeroRect
|
|
|
-// if let item = item as? SKBookmark, row != -1 {
|
|
|
+// if let item = item as? KMBookmark, row != -1 {
|
|
|
// let cell = outlineView.preparedCell(atColumn: 0, row: row) as? SKTextWithIconCell
|
|
|
// iconRect = cell?.iconRect(forBounds: outlineView.frameOfCell(atColumn: 0, row: row)) ?? NSZeroRect
|
|
|
// if outlineView.visibleRect.intersects(iconRect) {
|
|
@@ -466,10 +476,10 @@ class KMBookmarkController: NSWindowController {
|
|
|
//
|
|
|
// func previewPanel(_ panel: QLPreviewPanel, transitionImageForPreviewItem item: QLPreviewItem, contentRect: UnsafeMutablePointer<NSRect>) -> NSImage? {
|
|
|
// var item = item
|
|
|
-// if let parent = (item as? SKBookmark)?.parent, parent.bookmarkType == .session {
|
|
|
+// if let parent = (item as? KMBookmark)?.parent, parent.bookmarkType == .session {
|
|
|
// item = parent
|
|
|
// }
|
|
|
-// return (item as? SKBookmark)?.icon
|
|
|
+// return (item as? KMBookmark)?.icon
|
|
|
// }
|
|
|
//
|
|
|
// func previewPanel(_ panel: QLPreviewPanel, handle event: NSEvent) -> Bool {
|
|
@@ -486,295 +496,310 @@ class KMBookmarkController: NSWindowController {
|
|
|
extension KMBookmarkController: NSOutlineViewDelegate, NSOutlineViewDataSource {
|
|
|
//MARK: NSOutlineViewDataSource
|
|
|
|
|
|
- func minimumCoverForBookmarks(_ items: [KMBookmark]) -> [KMBookmark] {
|
|
|
- var lastBm: KMBookmark?
|
|
|
- var minimalCover = [KMBookmark]()
|
|
|
+ func minimumCoverForBookmarks(_ items: [KMBookmark]) -> [KMBookmark] {
|
|
|
+ var lastBm: KMBookmark?
|
|
|
+ var minimalCover = [KMBookmark]()
|
|
|
+
|
|
|
+ for bm in items {
|
|
|
+ if lastBm != nil && !(bm.isDescendant(of: lastBm!)) {
|
|
|
+ minimalCover.append(bm)
|
|
|
+ lastBm = bm
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return minimalCover
|
|
|
+ }
|
|
|
|
|
|
- for bm in items {
|
|
|
- if lastBm != nil && !(bm.isDescendant(of: lastBm!)) {
|
|
|
- minimalCover.append(bm)
|
|
|
- lastBm = bm
|
|
|
+ func outlineView(_ ov: NSOutlineView, numberOfChildrenOfItem item: Any?) -> Int {
|
|
|
+ let bookmark = item as? KMBookmark ?? bookmarkRoot
|
|
|
+ return bookmark.bookmarkType == .folder ? bookmark.children.count : 0
|
|
|
+ }
|
|
|
+
|
|
|
+ func outlineView(_ ov: NSOutlineView, isItemExpandable item: Any) -> Bool {
|
|
|
+ let bookmark = item as! KMBookmark
|
|
|
+ return bookmark.bookmarkType == .folder
|
|
|
+ }
|
|
|
+
|
|
|
+ func outlineView(_ ov: NSOutlineView, child index: Int, ofItem item: Any?) -> Any {
|
|
|
+ let bookmark = (item as? KMBookmark) ?? bookmarkRoot
|
|
|
+ return bookmark.objectOfChidren(index: index)
|
|
|
+ }
|
|
|
+
|
|
|
+ func outlineView(_ ov: NSOutlineView, objectValueFor tableColumn: NSTableColumn?, byItem item: Any?) -> Any? {
|
|
|
+ guard let column = tableColumn else { return nil }
|
|
|
+ guard let bm = item as? KMBookmark else { return nil }
|
|
|
+ let tcID = column.identifier
|
|
|
+
|
|
|
+ switch tcID {
|
|
|
+ case kLabel:
|
|
|
+ return [kTextWithIconStringKey: bm.label, kTextWithIconImageKey: bm.icon]
|
|
|
+ case kFile:
|
|
|
+ if bm.bookmarkType == .folder || bm.bookmarkType == .session {
|
|
|
+ let count = bm.children.count
|
|
|
+ return count == 1 ? NSLocalizedString("1 item", comment: "Bookmark folder description") : String.localizedStringWithFormat(NSLocalizedString("%ld items", comment: "Bookmark folder description"), count)
|
|
|
+ } else {
|
|
|
+ return bm.fileURL?.path ?? ""
|
|
|
+ }
|
|
|
+ case kPage:
|
|
|
+ return bm.pageNumber
|
|
|
+ default:
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ func outlineView(_ ov: NSOutlineView, setObjectValue object: Any?, for tableColumn: NSTableColumn?, byItem item: Any?) {
|
|
|
+ guard let column = tableColumn else { return }
|
|
|
+ guard let bm = item as? KMBookmark else { return }
|
|
|
+ let tcID = column.identifier
|
|
|
+
|
|
|
+ switch tcID {
|
|
|
+ case kLabel:
|
|
|
+ if let newLabel = (object as? [String: Any])?[kTextWithIconStringKey] as? String, newLabel != bm.label {
|
|
|
+ bm.label = newLabel
|
|
|
+ }
|
|
|
+ case kPage:
|
|
|
+ if let newPageNumber = object as? Int, newPageNumber != bm.pageNumber.intValue {
|
|
|
+ bm.pageNumber = newPageNumber as NSNumber
|
|
|
+ }
|
|
|
+ default:
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ func outlineView(_ ov: NSOutlineView, writeItems items: [Any], to pboard: NSPasteboard) -> Bool {
|
|
|
+ draggedBookmarks = minimumCoverForBookmarks(items as! [KMBookmark])
|
|
|
+ pboard.clearContents()
|
|
|
+ pboard.setData(Data(), forType: kPasteboardTypeBookmarkRows)
|
|
|
+ return true
|
|
|
+ }
|
|
|
+
|
|
|
+ func outlineView(_ ov: NSOutlineView, validateDrop info: NSDraggingInfo, proposedItem item: Any?, proposedChildIndex index: Int) -> NSDragOperation {
|
|
|
+ guard index != NSOutlineViewDropOnItemIndex else { return [] }
|
|
|
+
|
|
|
+ let pboard = info.draggingPasteboard
|
|
|
+
|
|
|
+ if pboard.canReadItem(withDataConformingToTypes: [kPasteboardTypeBookmarkRows.rawValue]) && info.draggingSource as? NSOutlineView == ov {
|
|
|
+ return .move
|
|
|
+ } else if NSURL.canReadFileURL(from: pboard) {
|
|
|
+ return .every
|
|
|
+ }
|
|
|
+ return []
|
|
|
+ }
|
|
|
+
|
|
|
+ func outlineView(_ ov: NSOutlineView, acceptDrop info: NSDraggingInfo, item: Any?, childIndex index: Int) -> Bool {
|
|
|
+ let pboard = info.draggingPasteboard
|
|
|
+
|
|
|
+ if pboard.canReadItem(withDataConformingToTypes: [kPasteboardTypeBookmarkRows.rawValue]) && info.draggingSource as? NSOutlineView == ov {
|
|
|
+ var movedBookmarks = [KMBookmark]()
|
|
|
+ var indexes = IndexSet()
|
|
|
+ var insertionIndex = index
|
|
|
+
|
|
|
+ let targetItem = item as? KMBookmark ?? bookmarkRoot
|
|
|
+
|
|
|
+ for bookmark in draggedBookmarks {
|
|
|
+ guard let parent = bookmark.parent else { continue }
|
|
|
+ guard let bookmarkIndex = parent.children.firstIndex(of: bookmark) else { continue }
|
|
|
+
|
|
|
+ if targetItem == parent {
|
|
|
+ if insertionIndex > bookmarkIndex {
|
|
|
+ insertionIndex -= 1
|
|
|
+ }
|
|
|
+ if insertionIndex == bookmarkIndex {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ }
|
|
|
+ parent.removeObjectFromChildren(index: bookmarkIndex)
|
|
|
+ targetItem.insert(child: bookmark, atIndex: insertionIndex)
|
|
|
+ movedBookmarks.append(bookmark)
|
|
|
+ insertionIndex += 1
|
|
|
+ }
|
|
|
+
|
|
|
+ for bookmark in movedBookmarks {
|
|
|
+ let row = ov.row(forItem: bookmark)
|
|
|
+ if row != -1 {
|
|
|
+ indexes.insert(row)
|
|
|
}
|
|
|
}
|
|
|
- return minimalCover
|
|
|
+ if !indexes.isEmpty {
|
|
|
+ ov.selectRowIndexes(indexes, byExtendingSelection: false)
|
|
|
+ }
|
|
|
+ return true
|
|
|
+ } else {
|
|
|
+ let urls = NSURL.readFileURLs(from: pboard)
|
|
|
+
|
|
|
+ let newBookmarks = KMBookmark.bookmarks(urls: urls)
|
|
|
+ if !newBookmarks.isEmpty {
|
|
|
+ var indexes = IndexSet(integersIn: index..<(index + newBookmarks.count))
|
|
|
+ (item as? KMBookmark ?? bookmarkRoot).mutableArrayValue(forKey: "children").insert(newBookmarks, at: indexes)
|
|
|
+ if (item as? KMBookmark ?? bookmarkRoot) === bookmarkRoot || ov.isItemExpanded(item) {
|
|
|
+ if (item as? KMBookmark ?? bookmarkRoot) !== bookmarkRoot {
|
|
|
+ indexes.shift(startingAt: 0, by: ov.row(forItem: item) + 1)
|
|
|
+ }
|
|
|
+ ov.selectRowIndexes(indexes, byExtendingSelection: false)
|
|
|
+ }
|
|
|
+ return true
|
|
|
+ }
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ func outlineView(_ ov: NSOutlineView, dragEndedWith operation: NSDragOperation) {
|
|
|
+ draggedBookmarks.removeAll()
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ // MARK: NSOutlineViewDelegate
|
|
|
+
|
|
|
+ func outlineView(_ ov: NSOutlineView, dataCellFor tableColumn: NSTableColumn?, item: Any) -> Any? {
|
|
|
+ if tableColumn == nil {
|
|
|
+ return (item as? KMBookmark)?.bookmarkType == .separator ? KMSeparatorCell() : nil
|
|
|
}
|
|
|
- //
|
|
|
- // func outlineView(_ ov: NSOutlineView, numberOfChildrenOfItem item: Any?) -> Int {
|
|
|
- // let bookmark = item as? SKBookmark ?? bookmarkRoot
|
|
|
- // return bookmark.bookmarkType == .folder ? bookmark.countOfChildren : 0
|
|
|
- // }
|
|
|
- //
|
|
|
- // func outlineView(_ ov: NSOutlineView, isItemExpandable item: Any) -> Bool {
|
|
|
- // let bookmark = item as! SKBookmark
|
|
|
- // return bookmark.bookmarkType == .folder
|
|
|
- // }
|
|
|
- //
|
|
|
- // func outlineView(_ ov: NSOutlineView, child index: Int, ofItem item: Any?) -> Any {
|
|
|
- // let bookmark = (item as? SKBookmark) ?? bookmarkRoot
|
|
|
- // return bookmark.objectInChildren(at: index)!
|
|
|
- // }
|
|
|
- //
|
|
|
- // func outlineView(_ ov: NSOutlineView, objectValueFor tableColumn: NSTableColumn?, byItem item: Any?) -> Any? {
|
|
|
- // guard let column = tableColumn, let tcID = column.identifier else { return nil }
|
|
|
- // guard let bm = item as? SKBookmark else { return nil }
|
|
|
- //
|
|
|
- // switch tcID {
|
|
|
- // case LABEL_COLUMNID:
|
|
|
- // return [SKTextWithIconStringKey: bm.label, SKTextWithIconImageKey: bm.icon]
|
|
|
- // case FILE_COLUMNID:
|
|
|
- // if bm.bookmarkType == .folder || bm.bookmarkType == .session {
|
|
|
- // let count = bm.countOfChildren
|
|
|
- // return count == 1 ? NSLocalizedString("1 item", comment: "Bookmark folder description") : String.localizedStringWithFormat(NSLocalizedString("%ld items", comment: "Bookmark folder description"), count)
|
|
|
- // } else {
|
|
|
- // return bm.fileURL?.path ?? ""
|
|
|
- // }
|
|
|
- // case PAGE_COLUMNID:
|
|
|
- // return bm.pageNumber
|
|
|
- // default:
|
|
|
- // return nil
|
|
|
- // }
|
|
|
- // }
|
|
|
- //
|
|
|
- // func outlineView(_ ov: NSOutlineView, setObjectValue object: Any?, for tableColumn: NSTableColumn?, byItem item: Any?) {
|
|
|
- // guard let column = tableColumn, let tcID = column.identifier else { return }
|
|
|
- // guard let bm = item as? SKBookmark else { return }
|
|
|
- //
|
|
|
- // switch tcID {
|
|
|
- // case LABEL_COLUMNID:
|
|
|
- // if let newLabel = (object as? [String: Any])?[SKTextWithIconStringKey] as? String, newLabel != bm.label {
|
|
|
- // bm.label = newLabel
|
|
|
- // }
|
|
|
- // case PAGE_COLUMNID:
|
|
|
- // if let newPageNumber = object as? Int, newPageNumber != bm.pageNumber {
|
|
|
- // bm.pageNumber = newPageNumber
|
|
|
- // }
|
|
|
- // default:
|
|
|
- // break
|
|
|
- // }
|
|
|
- // }
|
|
|
- //
|
|
|
- // func outlineView(_ ov: NSOutlineView, writeItems items: [Any], to pboard: NSPasteboard) -> Bool {
|
|
|
- // draggedBookmarks = minimumCoverForBookmarks(items as! [SKBookmark])
|
|
|
- // pboard.clearContents()
|
|
|
- // pboard.setData(Data(), forType: SKPasteboardTypeBookmarkRows)
|
|
|
- // return true
|
|
|
- // }
|
|
|
- //
|
|
|
- // func outlineView(_ ov: NSOutlineView, validateDrop info: NSDraggingInfo, proposedItem item: Any?, proposedChildIndex index: Int) -> NSDragOperation {
|
|
|
- // guard index != NSOutlineViewDropOnItemIndex else { return .none }
|
|
|
- // guard let pboard = info.draggingPasteboard else { return .none }
|
|
|
- //
|
|
|
- // if pboard.canReadItem(withDataConformingToTypes: [SKPasteboardTypeBookmarkRows]) && info.draggingSource as? NSOutlineView == ov {
|
|
|
- // return .move
|
|
|
- // } else if NSURL.canReadFileURL(from: pboard) {
|
|
|
- // return .every
|
|
|
- // }
|
|
|
- // return .none
|
|
|
- // }
|
|
|
- //
|
|
|
- // func outlineView(_ ov: NSOutlineView, acceptDrop info: NSDraggingInfo, item: Any?, childIndex index: Int) -> Bool {
|
|
|
- // guard let pboard = info.draggingPasteboard else { return false }
|
|
|
- //
|
|
|
- // if pboard.canReadItem(withDataConformingToTypes: [SKPasteboardTypeBookmarkRows]) && info.draggingSource as? NSOutlineView == ov {
|
|
|
- // var movedBookmarks = [SKBookmark]()
|
|
|
- // var indexes = IndexSet()
|
|
|
- // var insertionIndex = index
|
|
|
- //
|
|
|
- // let targetItem = item as? SKBookmark ?? bookmarkRoot
|
|
|
- //
|
|
|
- // for bookmark in draggedBookmarks {
|
|
|
- // guard let parent = bookmark.parent else { continue }
|
|
|
- // guard let bookmarkIndex = parent.children.firstIndex(of: bookmark) else { continue }
|
|
|
- //
|
|
|
- // if targetItem == parent {
|
|
|
- // if insertionIndex > bookmarkIndex {
|
|
|
- // insertionIndex -= 1
|
|
|
- // }
|
|
|
- // if insertionIndex == bookmarkIndex {
|
|
|
- // continue
|
|
|
- // }
|
|
|
- // }
|
|
|
- // parent.removeObjectFromChildren(at: bookmarkIndex)
|
|
|
- // targetItem.insertObject(bookmark, inChildrenAtIndex: insertionIndex)
|
|
|
- // movedBookmarks.append(bookmark)
|
|
|
- // insertionIndex += 1
|
|
|
- // }
|
|
|
- //
|
|
|
- // for bookmark in movedBookmarks {
|
|
|
- // let row = ov.row(forItem: bookmark)
|
|
|
- // if row != -1 {
|
|
|
- // indexes.insert(row)
|
|
|
- // }
|
|
|
- // }
|
|
|
- // if !indexes.isEmpty {
|
|
|
- // ov.selectRowIndexes(indexes, byExtendingSelection: false)
|
|
|
- // }
|
|
|
- // return true
|
|
|
- // } else {
|
|
|
- // guard let urls = NSURL.readFileURLs(from: pboard) else { return false }
|
|
|
- //
|
|
|
- // let newBookmarks = SKBookmark.bookmarks(for: urls)
|
|
|
- // if !newBookmarks.isEmpty {
|
|
|
- // let indexes = IndexSet(integersIn: index..<(index + newBookmarks.count))
|
|
|
- // (item as? SKBookmark ?? bookmarkRoot).mutableArrayValue(forKey: "children").insert(newBookmarks, at: indexes)
|
|
|
- // if item === bookmarkRoot || ov.isItemExpanded(item) {
|
|
|
- // if item !== bookmarkRoot {
|
|
|
- // indexes.shift(startingAt: 0, by: ov.row(forItem: item) + 1)
|
|
|
- // }
|
|
|
- // ov.selectRowIndexes(indexes, byExtendingSelection: false)
|
|
|
- // }
|
|
|
- // return true
|
|
|
- // }
|
|
|
- // return false
|
|
|
- // }
|
|
|
- // }
|
|
|
- //
|
|
|
- // func outlineView(_ ov: NSOutlineView, dragEndedWith operation: NSDragOperation) {
|
|
|
- // draggedBookmarks = nil
|
|
|
- // }
|
|
|
+ return tableColumn?.dataCell(forRow: ov.row(forItem: item))
|
|
|
+ }
|
|
|
|
|
|
+ func outlineView(_ ov: NSOutlineView, willDisplayCell cell: Any, for tableColumn: NSTableColumn?, item: Any) {
|
|
|
+ guard let column = tableColumn else { return }
|
|
|
+ guard let cell = cell as? NSCell else { return }
|
|
|
+
|
|
|
+ if column.identifier == kFile {
|
|
|
+ if let bm = item as? KMBookmark {
|
|
|
+// if bm.bookmarkType == .folder || bm.bookmarkType == .session {
|
|
|
+// cell.textColor = .disabledControlTextColor
|
|
|
+// } else {
|
|
|
+// cell.textColor = .controlTextColor
|
|
|
+// }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ func outlineView(_ ov: NSOutlineView, shouldEdit tableColumn: NSTableColumn?, item: Any) -> Bool {
|
|
|
+ guard let column = tableColumn else { return false }
|
|
|
+ guard let bm = item as? KMBookmark else { return false }
|
|
|
+
|
|
|
+ let tcID = column.identifier
|
|
|
+ switch tcID {
|
|
|
+ case kLabel:
|
|
|
+ return bm.bookmarkType != .separator
|
|
|
+ case kPage:
|
|
|
+ return bm.pageIndex != NSNotFound
|
|
|
+ default:
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ func outlineView(_ ov: NSOutlineView, toolTipFor cell: NSCell, rect: UnsafeMutablePointer<NSRect>, tableColumn tc: NSTableColumn?, item: Any, mouseLocation: NSPoint) -> String {
|
|
|
+ guard let column = tc else { return "" }
|
|
|
+ guard let bm = item as? KMBookmark else { return "" }
|
|
|
+
|
|
|
+ let tcID = column.identifier
|
|
|
+ switch tcID {
|
|
|
+ case kLabel:
|
|
|
+ return bm.label
|
|
|
+ case kFile:
|
|
|
+ if bm.bookmarkType == .session {
|
|
|
+ return ""
|
|
|
+// return bm.children.map { $0.path ?? "" }.joined(separator: "\n")
|
|
|
+ } else if bm.bookmarkType == .folder {
|
|
|
+ let count = bm.children.count
|
|
|
+ return count == 1 ? NSLocalizedString("1 item", comment: "Bookmark folder description") : String.localizedStringWithFormat(NSLocalizedString("%ld items", comment: "Bookmark folder description"), count)
|
|
|
+ } else {
|
|
|
+ return bm.fileURL?.path ?? ""
|
|
|
+ }
|
|
|
+ case kPage:
|
|
|
+ return bm.pageNumber.stringValue
|
|
|
+ default:
|
|
|
+ return ""
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ func outlineViewSelectionDidChange(_ notification: Notification) {
|
|
|
+ updateStatus()
|
|
|
+ if QLPreviewPanel.sharedPreviewPanelExists(), let previewPanel = QLPreviewPanel.shared(), previewPanel.isVisible, previewPanel.dataSource === self {
|
|
|
+ previewPanel.reloadData()
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ func outlineView(_ ov: NSOutlineView, deleteItems items: [Any]) {
|
|
|
+ for item in minimumCoverForBookmarks(items as! [KMBookmark]).reversed() {
|
|
|
+ guard let parent = item.parent, let itemIndex = parent.children.firstIndex(of: item) else { continue }
|
|
|
+ parent.removeObjectFromChildren(index: itemIndex)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ func outlineView(_ ov: NSOutlineView, canDeleteItems items: [Any]) -> Bool {
|
|
|
+ return !items.isEmpty
|
|
|
+ }
|
|
|
+
|
|
|
+ func outlineView(_ ov: NSOutlineView, copyItems items: [Any]) {
|
|
|
+ var urls = [URL]()
|
|
|
+ addBookmarkURLsToArray(minimumCoverForBookmarks(items as! [KMBookmark]), &urls)
|
|
|
+ if !urls.isEmpty {
|
|
|
+ let pboard = NSPasteboard.general
|
|
|
+ pboard.clearContents()
|
|
|
+ pboard.writeObjects(urls as [NSPasteboardWriting])
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ func outlineView(_ ov: NSOutlineView, canCopyItems items: [Any]) -> Bool {
|
|
|
+ return !items.isEmpty
|
|
|
+ }
|
|
|
+
|
|
|
+ func outlineView(_ ov: NSOutlineView, pasteFromPasteboard pboard: NSPasteboard) {
|
|
|
+ let urls = NSURL.readFileURLs(from: pboard)
|
|
|
+
|
|
|
+ let newBookmarks = KMBookmark.bookmarks(urls: urls)
|
|
|
+ if !newBookmarks.isEmpty {
|
|
|
+ var item: KMBookmark?
|
|
|
+ var anIndex = 0
|
|
|
+ getInsertionFolder(&item, childIndex: &anIndex)
|
|
|
+ var indexes = IndexSet(integersIn: anIndex..<(anIndex + newBookmarks.count))
|
|
|
+ (item ?? bookmarkRoot).mutableArrayValue(forKey: "children").insert(newBookmarks, at: indexes)
|
|
|
+ if item === bookmarkRoot || ov.isItemExpanded(item) {
|
|
|
+ if item !== bookmarkRoot {
|
|
|
+ indexes.shift(startingAt: 0, by: ov.row(forItem: item) + 1)
|
|
|
+ }
|
|
|
+ ov.selectRowIndexes(indexes, byExtendingSelection: false)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ func outlineView(_ ov: NSOutlineView, canPasteFromPasteboard pboard: NSPasteboard) -> Bool {
|
|
|
+ return NSURL.canReadFileURL(from: pboard)
|
|
|
+ }
|
|
|
+
|
|
|
+ func outlineView(_ ov: NSOutlineView, typeSelectHelperSelectionStrings typeSelectHelper: SKTypeSelectHelper) -> [String] {
|
|
|
+ let count = ov.numberOfRows
|
|
|
+ var labels = [String]()
|
|
|
+ for i in 0..<count {
|
|
|
+ if let label = ov.item(atRow: i) {
|
|
|
+ labels.append(label as! String)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return labels
|
|
|
+ }
|
|
|
+
|
|
|
+// func outlineView(_ ov: NSOutlineView, typeSelectHelper typeSelectHelper: SKTypeSelectHelper, didFailToFindMatchForSearchString searchString: String) {
|
|
|
+// statusBar.setLeftStringValue(String.localizedStringWithFormat(NSLocalizedString("No match: \"%@\"", comment: "Status message"), searchString))
|
|
|
+// }
|
|
|
+//
|
|
|
+// func outlineView(_ ov: NSOutlineView, typeSelectHelper typeSelectHelper: SKTypeSelectHelper, updateSearchString searchString: String?) {
|
|
|
+// if let searchString = searchString {
|
|
|
+// statusBar.setLeftStringValue(String.localizedStringWithFormat(NSLocalizedString("Finding: \"%@\"", comment: "Status message"), searchString))
|
|
|
+// } else {
|
|
|
+// updateStatus()
|
|
|
+// }
|
|
|
+// }
|
|
|
|
|
|
- //MARK: NSOutlineViewDelegate
|
|
|
- //
|
|
|
- // func outlineView(_ ov: NSOutlineView, dataCellFor tableColumn: NSTableColumn?, item: Any) -> Any? {
|
|
|
- // if tableColumn == nil {
|
|
|
- // return (item as? SKBookmark)?.bookmarkType == .separator ? SKSeparatorCell() : nil
|
|
|
- // }
|
|
|
- // return tableColumn?.dataCell(forRow: ov.row(forItem: item))
|
|
|
- // }
|
|
|
- //
|
|
|
- // func outlineView(_ ov: NSOutlineView, willDisplayCell cell: Any, for tableColumn: NSTableColumn?, item: Any) {
|
|
|
- // guard let column = tableColumn else { return }
|
|
|
- //
|
|
|
- // if column.identifier == FILE_COLUMNID {
|
|
|
- // if let bm = item as? SKBookmark {
|
|
|
- // if bm.bookmarkType == .folder || bm.bookmarkType == .session {
|
|
|
- // (cell as? NSCell)?.textColor = .disabledControlTextColor
|
|
|
- // } else {
|
|
|
- // (cell as? NSCell)?.textColor = .controlTextColor
|
|
|
- // }
|
|
|
- // }
|
|
|
- // }
|
|
|
- // }
|
|
|
- //
|
|
|
- // func outlineView(_ ov: NSOutlineView, shouldEditTableColumn tableColumn: NSTableColumn?, item: Any) -> Bool {
|
|
|
- // guard let column = tableColumn, let tcID = column.identifier else { return false }
|
|
|
- // guard let bm = item as? SKBookmark else { return false }
|
|
|
- //
|
|
|
- // switch tcID {
|
|
|
- // case LABEL_COLUMNID:
|
|
|
- // return bm.bookmarkType != .separator
|
|
|
- // case PAGE_COLUMNID:
|
|
|
- // return bm.pageIndex != NSNotFound
|
|
|
- // default:
|
|
|
- // return false
|
|
|
- // }
|
|
|
- // }
|
|
|
- //
|
|
|
- // func outlineView(_ ov: NSOutlineView, toolTipFor cell: NSCell, rect: UnsafeMutablePointer<NSRect>, tableColumn tc: NSTableColumn?, item: Any, mouseLocation: NSPoint) -> String {
|
|
|
- // guard let column = tc, let tcID = column.identifier else { return "" }
|
|
|
- // guard let bm = item as? SKBookmark else { return "" }
|
|
|
- //
|
|
|
- // switch tcID {
|
|
|
- // case LABEL_COLUMNID:
|
|
|
- // return bm.label
|
|
|
- // case FILE_COLUMNID:
|
|
|
- // if bm.bookmarkType == .session {
|
|
|
- // return bm.children.map { $0.path ?? "" }.joined(separator: "\n")
|
|
|
- // } else if bm.bookmarkType == .folder {
|
|
|
- // let count = bm.countOfChildren
|
|
|
- // return count == 1 ? NSLocalizedString("1 item", comment: "Bookmark folder description") : String.localizedStringWithFormat(NSLocalizedString("%ld items", comment: "Bookmark folder description"), count)
|
|
|
- // } else {
|
|
|
- // return bm.fileURL?.path ?? ""
|
|
|
- // }
|
|
|
- // case PAGE_COLUMNID:
|
|
|
- // return bm.pageNumber?.stringValue ?? ""
|
|
|
- // default:
|
|
|
- // return ""
|
|
|
- // }
|
|
|
- // }
|
|
|
- //
|
|
|
- // func outlineViewSelectionDidChange(_ notification: Notification) {
|
|
|
- // updateStatus()
|
|
|
- // if QLPreviewPanel.sharedPreviewPanelExists(), let previewPanel = QLPreviewPanel.shared() as? QLPreviewPanel, previewPanel.isVisible, previewPanel.dataSource === self {
|
|
|
- // previewPanel.reloadData()
|
|
|
- // }
|
|
|
- // }
|
|
|
- //
|
|
|
- // func outlineView(_ ov: NSOutlineView, deleteItems items: [Any]) {
|
|
|
- // for item in minimumCoverForBookmarks(items as! [SKBookmark]).reversed() {
|
|
|
- // guard let parent = item.parent, let itemIndex = parent.children.firstIndex(of: item) else { continue }
|
|
|
- // parent.removeObjectFromChildren(at: itemIndex)
|
|
|
- // }
|
|
|
- // }
|
|
|
- //
|
|
|
- // func outlineView(_ ov: NSOutlineView, canDeleteItems items: [Any]) -> Bool {
|
|
|
- // return !items.isEmpty
|
|
|
- // }
|
|
|
- //
|
|
|
- // func outlineView(_ ov: NSOutlineView, copyItems items: [Any]) {
|
|
|
- // var urls = [URL]()
|
|
|
- // addBookmarkURLsToArray(minimumCoverForBookmarks(items as! [SKBookmark]), urls)
|
|
|
- // if !urls.isEmpty {
|
|
|
- // let pboard = NSPasteboard.general
|
|
|
- // pboard.clearContents()
|
|
|
- // pboard.writeObjects(urls as [NSPasteboardWriting])
|
|
|
- // } else {
|
|
|
- // NSBeep()
|
|
|
- // }
|
|
|
- // }
|
|
|
- //
|
|
|
- // func outlineView(_ ov: NSOutlineView, canCopyItems items: [Any]) -> Bool {
|
|
|
- // return !items.isEmpty
|
|
|
- // }
|
|
|
- //
|
|
|
- // func outlineView(_ ov: NSOutlineView, pasteFromPasteboard pboard: NSPasteboard) {
|
|
|
- // guard let urls = NSURL.readFileURLs(from: pboard), !urls.isEmpty else { NSBeep(); return }
|
|
|
- //
|
|
|
- // let newBookmarks = SKBookmark.bookmarks(for: urls)
|
|
|
- // if !newBookmarks.isEmpty {
|
|
|
- // var item: SKBookmark?
|
|
|
- // var anIndex = 0
|
|
|
- // getInsertionFolder(&item, childIndex: &anIndex)
|
|
|
- // let indexes = IndexSet(integersIn: anIndex..<(anIndex + newBookmarks.count))
|
|
|
- // (item ?? bookmarkRoot).mutableArrayValue(forKey: "children").insert(newBookmarks, at: indexes)
|
|
|
- // if item === bookmarkRoot || ov.isItemExpanded(item) {
|
|
|
- // if item !== bookmarkRoot {
|
|
|
- // indexes.shift(startingAt: 0, by: ov.row(forItem: item) + 1)
|
|
|
- // }
|
|
|
- // ov.selectRowIndexes(indexes, byExtendingSelection: false)
|
|
|
- // }
|
|
|
- // } else {
|
|
|
- // NSBeep()
|
|
|
- // }
|
|
|
- // }
|
|
|
- //
|
|
|
- // func outlineView(_ ov: NSOutlineView, canPasteFromPasteboard pboard: NSPasteboard) -> Bool {
|
|
|
- // return NSURL.canReadFileURL(from: pboard)
|
|
|
- // }
|
|
|
- //
|
|
|
- // func outlineView(_ ov: NSOutlineView, typeSelectHelperSelectionStrings typeSelectHelper: SKTypeSelectHelper) -> [String] {
|
|
|
- // let count = ov.numberOfRows
|
|
|
- // var labels = [String]()
|
|
|
- // for i in 0..<count {
|
|
|
- // if let label = ov.item(atRow: i) as? SKBookmark?.label {
|
|
|
- // labels.append(label)
|
|
|
- // }
|
|
|
- // }
|
|
|
- // return labels
|
|
|
- // }
|
|
|
- //
|
|
|
- // func outlineView(_ ov: NSOutlineView, typeSelectHelper typeSelectHelper: SKTypeSelectHelper, didFailToFindMatchForSearchString searchString: String) {
|
|
|
- // statusBar.setLeftStringValue(String.localizedStringWithFormat(NSLocalizedString("No match: \"%@\"", comment: "Status message"), searchString))
|
|
|
- // }
|
|
|
- //
|
|
|
- // func outlineView(_ ov: NSOutlineView, typeSelectHelper typeSelectHelper: SKTypeSelectHelper, updateSearchString searchString: String?) {
|
|
|
- // if let searchString = searchString {
|
|
|
- // statusBar.setLeftStringValue(String.localizedStringWithFormat(NSLocalizedString("Finding: \"%@\"", comment: "Status message"), searchString))
|
|
|
- // } else {
|
|
|
- // updateStatus()
|
|
|
- // }
|
|
|
- // }
|
|
|
+ func addBookmarkURLsToArray(_ items: [KMBookmark], _ array: inout [URL]) {
|
|
|
+ for bm in items {
|
|
|
+ if bm.bookmarkType == .bookmark {
|
|
|
+ if let url = bm.fileURL {
|
|
|
+ array.append(url)
|
|
|
+ }
|
|
|
+ } else if bm.bookmarkType != .separator {
|
|
|
+ addBookmarkURLsToArray(bm.children, &array)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
}
|
|
|
|
|
@@ -830,3 +855,24 @@ extension KMBookmarkController: NSMenuDelegate, NSMenuItemValidation {
|
|
|
return true
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+extension NSURL {
|
|
|
+ static func canReadFileURL(from pboard: NSPasteboard) -> Bool {
|
|
|
+ let canReadFileURLsOnly = [NSPasteboard.ReadingOptionKey.urlReadingFileURLsOnly: true]
|
|
|
+ let canReadClasses = [NSURL.self]
|
|
|
+
|
|
|
+ return pboard.canReadObject(forClasses: canReadClasses, options: canReadFileURLsOnly) ||
|
|
|
+ pboard.canReadItem(withDataConformingToTypes: [NSPasteboard.PasteboardType.fileURL.rawValue])
|
|
|
+ }
|
|
|
+
|
|
|
+ static func readFileURLs(from pboard: NSPasteboard) -> [URL] {
|
|
|
+ if let fileURLs = pboard.readObjects(forClasses: [NSURL.self], options: [.urlReadingFileURLsOnly: true]) as? [URL], !fileURLs.isEmpty {
|
|
|
+ return fileURLs
|
|
|
+ } else if ((pboard.types?.contains(.fileURL)) != nil) {
|
|
|
+ if let filenames = pboard.propertyList(forType: .fileURL) as? [String] {
|
|
|
+ return filenames.compactMap { URL(fileURLWithPath: $0) }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return []
|
|
|
+ }
|
|
|
+}
|