|
@@ -298,7 +298,12 @@ class KMLeftSideViewController: KMSideViewController {
|
|
|
// [noteOutlineView setTypeSelectHelper:[SKTypeSelectHelper typeSelectHelperWithMatchOption:SKSubstringMatch]];
|
|
|
self.noteOutlineView.indentationPerLevel = 0
|
|
|
// [noteOutlineView registerForDraggedTypes:[NSColor readableTypesForPasteboard:[NSPasteboard pasteboardWithName:NSDragPboard]]];
|
|
|
+ self.noteOutlineView.target = self
|
|
|
+ self.noteOutlineView.doubleAction = #selector(selectSelectedNote)
|
|
|
|
|
|
+ self.tocOutlineView.menu = NSMenu()
|
|
|
+ self.tocOutlineView.menu?.delegate = self
|
|
|
+ self.outlineSearchField.delegate = self
|
|
|
self.snapshotSearchField.backgroundColor = KMAppearance.Layout.l_1Color()
|
|
|
self.outlineSearchField.backgroundColor = KMAppearance.Layout.l_1Color()
|
|
|
self.noteSearchField.backgroundColor = KMAppearance.Layout.l_1Color()
|
|
@@ -413,6 +418,7 @@ class KMLeftSideViewController: KMSideViewController {
|
|
|
self.noteDoneButton.isHidden = true
|
|
|
|
|
|
self.noteSearchButton.toolTip = KMLocalizedString("Search", nil)
|
|
|
+ self.noteSearchField.delegate = self
|
|
|
self.noteSearchField.isHidden = true
|
|
|
self.noteSearchField.endEditCallBack = { [unowned self] isEndEdit in
|
|
|
if (isEndEdit) {
|
|
@@ -959,8 +965,8 @@ class KMLeftSideViewController: KMSideViewController {
|
|
|
for (i, label) in pageLabels.enumerated() {
|
|
|
let firstPage = self.listView.document.page(at: UInt(i))
|
|
|
let size = NSMakeSize(self.thumbnailCacheSize, self.thumbnailCacheSize)
|
|
|
- let pageImage = firstPage!.thumbnail(of: size)
|
|
|
- let thumbnail = KMThumbnail(image: pageImage, label: label, pageIndex: i)
|
|
|
+// let pageImage = firstPage!.thumbnail(of: size)
|
|
|
+ let thumbnail = KMThumbnail(image: nil, label: label, pageIndex: i)
|
|
|
// thumbnail.delegate = self
|
|
|
thumbnail.dirty = true
|
|
|
self.thumbnails.append(thumbnail)
|
|
@@ -1366,7 +1372,7 @@ class KMLeftSideViewController: KMSideViewController {
|
|
|
self.outlineSearchField.becomeFirstResponder()
|
|
|
}
|
|
|
|
|
|
- @objc func outlineContextMenuItemClicked_AddEntry(_ sender: NSMenuItem) {
|
|
|
+// @objc func outlineContextMenuItemClicked_AddEntry(_ sender: NSMenuItem) {
|
|
|
// NSMutableArray *PDFOutlineArray = [[NSMutableArray new] autorelease];
|
|
|
// NSIndexSet *rowSet = [self selectedRowIndexes] ;
|
|
|
//
|
|
@@ -1410,7 +1416,7 @@ class KMLeftSideViewController: KMSideViewController {
|
|
|
// [self.leftSideController.tocOutlineView deselectRow:currentIndex+1];
|
|
|
//
|
|
|
// }
|
|
|
- }
|
|
|
+// }
|
|
|
|
|
|
@IBAction func toc_expandAllComments(_ sender: AnyObject?) {
|
|
|
if (self.tocType == .unfold) {
|
|
@@ -1432,17 +1438,18 @@ class KMLeftSideViewController: KMSideViewController {
|
|
|
|
|
|
@objc func leftSideEmptyAnnotationClick_DeleteOutline(_ sender: AnyObject?) {
|
|
|
KMPrint("leftSideEmptyAnnotationClick_DeleteOutline")
|
|
|
-// NSAlert *alert = [[NSAlert alloc] init];
|
|
|
-// [alert setAlertStyle:NSAlertStyleCritical];
|
|
|
-// [alert setMessageText:@""];
|
|
|
-// [alert setInformativeText:NSLocalizedString(@"This will permanently remove all outlines. Are you sure to continue?", nil)];
|
|
|
-// [alert addButtonWithTitle:NSLocalizedString(@"Yes", nil)];
|
|
|
-// [alert addButtonWithTitle:NSLocalizedString(@"No", nil)];
|
|
|
-// NSModalResponse response = [alert runModal];
|
|
|
-// if (response == NSAlertFirstButtonReturn) {
|
|
|
-// PDFOutline * item = [[pdfView document] outlineRoot];
|
|
|
-// [self removeAllOutline:item];
|
|
|
-// }
|
|
|
+ let alert = NSAlert()
|
|
|
+ alert.alertStyle = .critical
|
|
|
+ alert.messageText = ""
|
|
|
+ alert.informativeText = KMLocalizedString("This will permanently remove all outlines. Are you sure to continue?", nil)
|
|
|
+ alert.addButton(withTitle: KMLocalizedString("Yes", nil))
|
|
|
+ alert.addButton(withTitle: KMLocalizedString("No", nil))
|
|
|
+ let response = alert.runModal()
|
|
|
+ if response == .alertFirstButtonReturn {
|
|
|
+ if let item = self.listView.document.outlineRoot() {
|
|
|
+ self.removeAllOutline(item)
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
@IBAction func thumbnailSizeScaling(_ sender: NSButton) {
|
|
@@ -1456,8 +1463,14 @@ class KMLeftSideViewController: KMSideViewController {
|
|
|
}
|
|
|
if (tag == 0) { // thumbnail Zoom In
|
|
|
scaling += 0.1
|
|
|
+ if scaling >= 2.2 {
|
|
|
+ return
|
|
|
+ }
|
|
|
} else if (tag == 1) { // thumbnail Zoom Out
|
|
|
scaling -= 0.1
|
|
|
+ if scaling <= 0.4 {
|
|
|
+ return
|
|
|
+ }
|
|
|
}
|
|
|
sud.setValue(scaling, forKey: "KMThumbnailSizeScalingKey")
|
|
|
|
|
@@ -1605,6 +1618,95 @@ class KMLeftSideViewController: KMSideViewController {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ func showSearchOutlineBlankState(_ toShowState: Bool) {
|
|
|
+ if (toShowState) {
|
|
|
+ self.leftSideEmptyVC.outlineSearchView.frame = CGRectMake((self.tocOutlineView.enclosingScrollView!.documentView!.frame.size.width - self.leftSideEmptyVC.outlineSearchView.bounds.size.width)/2.0, (self.tocOutlineView.enclosingScrollView!.documentView!.frame.size.height - self.leftSideEmptyVC.outlineSearchView.bounds.size.height)/2.0, self.leftSideEmptyVC.outlineSearchView.bounds.size.width, self.leftSideEmptyVC.outlineSearchView.bounds.size.height);
|
|
|
+ self.tocOutlineView.enclosingScrollView?.documentView?.addSubview(self.leftSideEmptyVC.outlineSearchView)
|
|
|
+ self.leftSideEmptyVC.outlineSearchView.autoresizingMask = [.minXMargin, .maxXMargin, .minYMargin, .maxYMargin]
|
|
|
+ } else {
|
|
|
+ self.leftSideEmptyVC.outlineSearchView.removeFromSuperview()
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+// func allRangeOfRoughString(_ roughString: String, searchString: String) -> [NSRange] {
|
|
|
+//
|
|
|
+// }
|
|
|
+
|
|
|
+ func removeAllOutline(_ outline: CPDFOutline) {
|
|
|
+ let ol = CPDFOutline()
|
|
|
+ self.listView.document.setOutlineRoot(ol)
|
|
|
+
|
|
|
+ for i in 0 ..< self.listView.document.pageCount {
|
|
|
+ self.listView.document.removeBookmark(forPageIndex: i)
|
|
|
+ }
|
|
|
+ self.listView.layoutDocumentView()
|
|
|
+ DispatchQueue.main.async {
|
|
|
+ self.tocOutlineView.reloadData()
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ func updateNoteFilterPredicate() {
|
|
|
+ //注释筛选
|
|
|
+ // [rightSideController.noteArrayController setFilterPredicate:[noteTypeSheetController filterPredicateForSearchString:[rightSideController.searchField stringValue] caseInsensitive:mwcFlags.caseInsensitiveNoteSearch]];
|
|
|
+
|
|
|
+// NSPredicate *predicate = [noteTypeSheetController filterPredicateForSearchString:[rightSideController.searchField stringValue] caseInsensitive:mwcFlags.caseInsensitiveNoteSearch];
|
|
|
+// [self loadAnnotationSortData:[NSArray arrayWithObjects:predicate, nil]];
|
|
|
+// [rightSideController.noteOutlineView reloadData];
|
|
|
+ }
|
|
|
+
|
|
|
+ @objc func selectSelectedNote(_ sender: AnyObject?) {
|
|
|
+ if self.listView.hideNotes == false {
|
|
|
+ let selectedNotes = self.selectedNotes()
|
|
|
+ if selectedNotes.count == 1 {
|
|
|
+ let annotation = selectedNotes.last!
|
|
|
+ self.listView.go(to: annotation.bounds, on: annotation.page, animated: true)
|
|
|
+
|
|
|
+// [pdfView scrollAnnotationToVisible:annotation];
|
|
|
+// [pdfView setActiveAnnotation:annotation];
|
|
|
+
|
|
|
+ self.listView.updateActiveAnnotations([annotation])
|
|
|
+ self.listView.setNeedsDisplayAnnotationViewForVisiblePages()
|
|
|
+// }
|
|
|
+
|
|
|
+ }
|
|
|
+// NSInteger column = [sender clickedColumn];
|
|
|
+// if (column != -1) {
|
|
|
+// NSString *colID = [[[sender tableColumns] objectAtIndex:column] identifier];
|
|
|
+//
|
|
|
+// if ([colID isEqualToString:@"color"]){
|
|
|
+// for (PDFAnnotation *annotation in self.pdfView.activeAnnotations) {
|
|
|
+// if (![annotation isKindOfClass:[PDFAnnotationChoiceWidget class]] &&
|
|
|
+// ![annotation isKindOfClass:[PDFAnnotationButtonWidget class]] &&
|
|
|
+// ![annotation isKindOfClass:[PDFAnnotationTextWidget class]]) {
|
|
|
+// [[NSColorPanel sharedColorPanel] orderFront:nil];
|
|
|
+// break;
|
|
|
+// }
|
|
|
+//
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ func selectedNotes() -> [CPDFAnnotation] {
|
|
|
+ var selectedNotes: [CPDFAnnotation] = []
|
|
|
+ let rowIndexes = self.noteOutlineView.selectedRowIndexes
|
|
|
+ for row in rowIndexes {
|
|
|
+ let item = self.noteOutlineView.item(atRow: row)
|
|
|
+ if item is KMBOTAAnnotationItem {
|
|
|
+ if let anno = (item as! KMBOTAAnnotationItem).annotation {
|
|
|
+ // if anno.type == nil {
|
|
|
+ // item = [(SKNoteText *)item note];
|
|
|
+ // }
|
|
|
+ if selectedNotes.contains(anno) == false {
|
|
|
+ selectedNotes.append(anno)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return selectedNotes
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
// MARK: - KMBotaTableViewDelegate
|
|
@@ -1992,19 +2094,25 @@ extension KMLeftSideViewController {
|
|
|
}
|
|
|
|
|
|
private func _hasContainString(_ searchString: String, rootOutline outline: CPDFOutline) -> Bool {
|
|
|
+ let label_low = outline.label.lowercased()
|
|
|
+ let searchString_low = searchString.lowercased()
|
|
|
+ if label_low.contains(searchString_low) {
|
|
|
// if ([outline.label rangeOfString:searchString options:self.outlineIgnoreCaseFlag?NSCaseInsensitiveSearch:0].location != NSNotFound){
|
|
|
-// return YES;
|
|
|
-// } else {
|
|
|
-// BOOL subHas = NO;
|
|
|
-// for (NSUInteger i = 0; i < outline.numberOfChildren; i ++) {
|
|
|
-// PDFOutline *subOutline = [outline childAtIndex:i];
|
|
|
-// subHas = [self hasContainString:searchString rootOutline:subOutline];
|
|
|
-// if (subHas) {
|
|
|
-// break;
|
|
|
-// }
|
|
|
-// }
|
|
|
-// return subHas;
|
|
|
-// }
|
|
|
+ return true
|
|
|
+ } else {
|
|
|
+ var subHas = false
|
|
|
+ for i in 0 ..< outline.numberOfChildren {
|
|
|
+ if let subOutline = outline.child(at: i) {
|
|
|
+ subHas = self._hasContainString(searchString, rootOutline: subOutline)
|
|
|
+ } else {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ if (subHas) {
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return subHas
|
|
|
+ }
|
|
|
return false
|
|
|
}
|
|
|
}
|
|
@@ -2111,7 +2219,8 @@ extension KMLeftSideViewController: NSTableViewDelegate, NSTableViewDataSource {
|
|
|
func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat {
|
|
|
if tableView.isEqual(to: self.thumbnailTableView) {
|
|
|
let scaling = UserDefaults.standard.float(forKey: "KMThumbnailSizeScalingKey")
|
|
|
- let thumbnailSize = self.thumbnails[row].size
|
|
|
+// let thumbnailSize = self.thumbnails[row].size
|
|
|
+ let thumbnailSize = NSMakeSize(self.thumbnailCacheSize, self.thumbnailCacheSize)
|
|
|
|
|
|
let newScaling: CGFloat = scaling.cgFloat + 0.1
|
|
|
let newThumbnailHeight = thumbnailSize.width * newScaling
|
|
@@ -2971,74 +3080,96 @@ extension KMLeftSideViewController: NSOutlineViewDelegate, NSOutlineViewDataSour
|
|
|
func outlineView(_ outlineView: NSOutlineView, numberOfChildrenOfItem item: Any?) -> Int {
|
|
|
if outlineView.isEqual(to: self.tocOutlineView) {
|
|
|
let isLocked = self.listView.document?.isLocked ?? true
|
|
|
- if item == nil && isLocked == false {
|
|
|
- var item = self.listView.document.outlineRoot()
|
|
|
- if let data = item?.numberOfChildren, data == 0 && !self.isSearchOutlineMode {
|
|
|
- let view = self.tocOutlineView.enclosingScrollView!
|
|
|
- let emptyVcSize = self.leftSideEmptyVC.emptyOutlineView.frame.size
|
|
|
-//
|
|
|
- self.leftSideEmptyVC.emptyOutlineView.frame = NSMakeRect((view.frame.size.width-emptyVcSize.width)/2.0,(view.frame.size.height-emptyVcSize.height)/2.0, emptyVcSize.width, emptyVcSize.height)
|
|
|
-
|
|
|
- self.leftSideEmptyVC.emptyOutlineView.autoresizingMask = [.minXMargin, .maxXMargin, .minYMargin, .maxYMargin]
|
|
|
- self.tocOutlineView.enclosingScrollView?.documentView?.addSubview(self.leftSideEmptyVC.emptyOutlineView)
|
|
|
- self.leftSideEmptyVC.deleteOutlineBtn.isEnabled = false
|
|
|
+ if isLocked { // 文档不存在 或 已加锁
|
|
|
+ return 0
|
|
|
+ }
|
|
|
+ if item == nil { // 第一层
|
|
|
+ // 获取根
|
|
|
+ guard let outline = self.listView.document.outlineRoot() else {
|
|
|
+ return 0
|
|
|
+ }
|
|
|
+ if outline.numberOfChildren == 0 {
|
|
|
+ return 0
|
|
|
+ }
|
|
|
+
|
|
|
+ if self.isSearchOutlineMode { // 是否为搜索模块
|
|
|
+ if self._hasContainString(self.outlineSearchField.stringValue, rootOutline: outline) {
|
|
|
+ self.showSearchOutlineBlankState(false)
|
|
|
+ } else {
|
|
|
+ self.showSearchOutlineBlankState(true)
|
|
|
+ return 0
|
|
|
+ }
|
|
|
} else {
|
|
|
- self.leftSideEmptyVC.emptyOutlineView.removeFromSuperview()
|
|
|
- self.leftSideEmptyVC.deleteOutlineBtn.isEnabled = true
|
|
|
+ if outline.numberOfChildren > 0 { // 有数据
|
|
|
+ self.leftSideEmptyVC.emptyOutlineView.removeFromSuperview()
|
|
|
+ self.leftSideEmptyVC.deleteOutlineBtn.isEnabled = true
|
|
|
+ } else { // 没有数据
|
|
|
+ let view = self.tocOutlineView.enclosingScrollView!
|
|
|
+ let emptyVcSize = self.leftSideEmptyVC.emptyOutlineView.frame.size
|
|
|
+ //
|
|
|
+ self.leftSideEmptyVC.emptyOutlineView.frame = NSMakeRect((view.frame.size.width-emptyVcSize.width)/2.0,(view.frame.size.height-emptyVcSize.height)/2.0, emptyVcSize.width, emptyVcSize.height)
|
|
|
+ self.leftSideEmptyVC.emptyOutlineView.autoresizingMask = [.minXMargin, .maxXMargin, .minYMargin, .maxYMargin]
|
|
|
+ self.tocOutlineView.enclosingScrollView?.documentView?.addSubview(self.leftSideEmptyVC.emptyOutlineView)
|
|
|
+ self.leftSideEmptyVC.deleteOutlineBtn.isEnabled = false
|
|
|
+ return 0
|
|
|
+ }
|
|
|
}
|
|
|
- if let data = item?.numberOfChildren, data > 0 {
|
|
|
+
|
|
|
+ // 搜索按钮
|
|
|
+ if outline.numberOfChildren > 0 {
|
|
|
self.outlineSearchButton.isEnabled = true
|
|
|
} else {
|
|
|
self.outlineSearchButton.isEnabled = false
|
|
|
}
|
|
|
|
|
|
if (self.isSearchOutlineMode) {
|
|
|
- if self._hasContainString(self.outlineSearchField.stringValue, rootOutline: item!) {
|
|
|
-// [self showSearchOutlineBlankState:NO];
|
|
|
- } else {
|
|
|
-// [self showSearchOutlineBlankState:YES];
|
|
|
+ var num = 0
|
|
|
+ for i in 0 ..< outline.numberOfChildren {
|
|
|
+ if let child = outline.child(at: i) {
|
|
|
+ if self._hasContainString(self.outlineSearchField.stringValue, rootOutline: child) {
|
|
|
+ num += 1
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return num
|
|
|
+ } else {
|
|
|
+ let array = self.listView.document.bookmarks() ?? [CPDFBookmark]()
|
|
|
+ var bookmarkNum = 0
|
|
|
+ if array.isEmpty == false {
|
|
|
+ bookmarkNum = 1
|
|
|
}
|
|
|
+ return Int(outline.numberOfChildren) + bookmarkNum
|
|
|
}
|
|
|
-
|
|
|
- let array = self.listView.document.bookmarks() ?? [CPDFBookmark]()
|
|
|
-// var bookMarks: [KMBookMarkItem] = []
|
|
|
-// for bookMark in array {
|
|
|
-// let item = KMBookMarkItem()
|
|
|
-// item.bookMark = bookMark
|
|
|
-// item.index = UInt(bookMark.pageIndex)
|
|
|
-// item.label = bookMark.label
|
|
|
-// bookMarks.append(item)
|
|
|
-// }
|
|
|
- var bookmarkNum = 0
|
|
|
- if array.isEmpty == false {
|
|
|
- bookmarkNum = 1
|
|
|
+ } else { // 第二层 +
|
|
|
+ if self.isSearchOutlineMode {
|
|
|
+ if let data = item as? String, data == "Bookmarks" { // 书签group
|
|
|
+ return 0
|
|
|
+ } else if item is CPDFOutline { // 大纲
|
|
|
+ let child = item as! CPDFOutline
|
|
|
+ if child.numberOfChildren == 0 {
|
|
|
+ return 0
|
|
|
+ }
|
|
|
+ var num = 0
|
|
|
+ for i in 0 ..< child.numberOfChildren {
|
|
|
+ if let _child = child.child(at: i) {
|
|
|
+ if self._hasContainString(self.outlineSearchField.stringValue, rootOutline: _child) {
|
|
|
+ num += 1
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return num
|
|
|
+ } else if item is CPDFBookmark { // 书签
|
|
|
+ return 0
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if let data = item as? String, data == "Bookmarks" { // 书签group
|
|
|
+ return (self.listView.document?.bookmarks().count) ?? 0
|
|
|
+ } else if item is CPDFOutline { // 大纲
|
|
|
+ return Int((item as? CPDFOutline)?.numberOfChildren ?? 0)
|
|
|
+ } else if item is CPDFBookmark { // 书签
|
|
|
+ return 0
|
|
|
+ }
|
|
|
}
|
|
|
- return Int(item?.numberOfChildren ?? 0) + bookmarkNum
|
|
|
- }
|
|
|
- if (self.isSearchOutlineMode) {
|
|
|
-// var num = 0
|
|
|
-// for (NSUInteger i = 0; i < [(PDFOutline *)item numberOfChildren]; i++) {
|
|
|
-// PDFOutline *outline = [(PDFOutline *)item childAtIndex:i];
|
|
|
-// if ([self hasContainString:self.leftSideController.outlineSearchField.stringValue rootOutline:outline]) {
|
|
|
-// num ++;
|
|
|
-// }
|
|
|
-// }
|
|
|
-// return num;
|
|
|
- } else {
|
|
|
-// return [(PDFOutline *)item numberOfChildren];
|
|
|
- }
|
|
|
-// if item is CPDFBookmark {
|
|
|
-// return 0
|
|
|
-// }
|
|
|
-// return Int((item as? CPDFOutline)?.numberOfChildren ?? 0)
|
|
|
- let array = self.listView.document?.bookmarks() ?? [CPDFBookmark]()
|
|
|
- if let data = item as? String, data == "Bookmarks" {
|
|
|
- return array.count
|
|
|
- } else if item is CPDFOutline {
|
|
|
-// return Int(item?.numberOfChildren ?? 0)
|
|
|
- return Int((item as? CPDFOutline)?.numberOfChildren ?? 0)
|
|
|
- } else if item is CPDFBookmark {
|
|
|
- return 0
|
|
|
}
|
|
|
} else if outlineView.isEqual(to: self.noteOutlineView) {
|
|
|
var count = 0
|
|
@@ -3094,21 +3225,46 @@ extension KMLeftSideViewController: NSOutlineViewDelegate, NSOutlineViewDataSour
|
|
|
|
|
|
func outlineView(_ outlineView: NSOutlineView, child index: Int, ofItem item: Any?) -> Any {
|
|
|
if outlineView.isEqual(to: self.tocOutlineView) {
|
|
|
+ let isLocked = self.listView.document?.isLocked ?? true
|
|
|
+ if isLocked { // 文档不存在 或 已加锁
|
|
|
+ return ""
|
|
|
+ }
|
|
|
+
|
|
|
let array = self.listView.document.bookmarks() ?? [CPDFBookmark]()
|
|
|
var bookmarkNum = 0
|
|
|
if array.isEmpty == false {
|
|
|
bookmarkNum = 1
|
|
|
}
|
|
|
-
|
|
|
- if item == nil && self.listView.document.isLocked == false {
|
|
|
- if index == 0 && bookmarkNum == 1 {
|
|
|
- return "Bookmarks"
|
|
|
+ if item == nil {
|
|
|
+ if self.isSearchOutlineMode {
|
|
|
+ guard let outline = self.listView.document.outlineRoot() else {
|
|
|
+ return ""
|
|
|
+ }
|
|
|
+ if outline.numberOfChildren == 0 {
|
|
|
+ return ""
|
|
|
+ }
|
|
|
+ var array: [CPDFOutline] = []
|
|
|
+ for i in 0 ..< outline.numberOfChildren {
|
|
|
+ if let child = outline.child(at: i) {
|
|
|
+ if self._hasContainString(self.outlineSearchField.stringValue, rootOutline: child) {
|
|
|
+ array.append(child)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if index < array.count {
|
|
|
+ return array[index]
|
|
|
+ }
|
|
|
+ return ""
|
|
|
} else {
|
|
|
- var _index = bookmarkNum == 1 ? index-1 : index
|
|
|
- var _item: CPDFOutline?
|
|
|
- _item = self.listView.document.outlineRoot()
|
|
|
- var obj = _item?.child(at: UInt(_index))
|
|
|
- return obj as Any
|
|
|
+ if index == 0 && bookmarkNum == 1 {
|
|
|
+ return "Bookmarks"
|
|
|
+ } else {
|
|
|
+ var _index = bookmarkNum == 1 ? index-1 : index
|
|
|
+ let outline = self.listView.document.outlineRoot()
|
|
|
+ var obj = outline?.child(at: UInt(_index))
|
|
|
+ return obj as Any
|
|
|
+ }
|
|
|
}
|
|
|
} else {
|
|
|
if let data = item as? String, data == "Bookmarks" {
|
|
@@ -3116,23 +3272,9 @@ extension KMLeftSideViewController: NSOutlineViewDelegate, NSOutlineViewDataSour
|
|
|
} else if item is CPDFOutline {
|
|
|
return (item as! CPDFOutline).child(at: UInt(index))
|
|
|
} else if item is CPDFBookmark {
|
|
|
-// return nil?
|
|
|
+ return ""
|
|
|
}
|
|
|
}
|
|
|
-// var obj = _item?.child(at: UInt(index))
|
|
|
-// if (self.isSearchOutlineMode) {
|
|
|
-// NSMutableArray *array = [NSMutableArray array];
|
|
|
-// for (NSUInteger i = 0; i < [(PDFOutline *)item numberOfChildren]; i ++) {
|
|
|
-// PDFOutline *subOutline = [(PDFOutline *)item childAtIndex:i];
|
|
|
-// if ([self hasContainString:self.leftSideController.outlineSearchField.stringValue rootOutline:subOutline]) {
|
|
|
-// [array addObject:subOutline];
|
|
|
-// }
|
|
|
-// }
|
|
|
-// return [array objectAtIndex:anIndex];
|
|
|
-// } else {
|
|
|
-// return obj;
|
|
|
-// }
|
|
|
-// return obj as Any
|
|
|
} else if outlineView.isEqual(to: self.noteOutlineView) {
|
|
|
// if (item == nil)
|
|
|
// {
|
|
@@ -3242,17 +3384,21 @@ extension KMLeftSideViewController: NSOutlineViewDelegate, NSOutlineViewDataSour
|
|
|
let tcID = tableColumn?.identifier.rawValue
|
|
|
|
|
|
var title = ""
|
|
|
+ var pageLabel = ""
|
|
|
if let data = item as? String, data == "Bookmarks" {
|
|
|
title = NSLocalizedString("Bookmarks", comment: "")
|
|
|
} else if item is CPDFOutline {
|
|
|
title = (item as! CPDFOutline).label
|
|
|
+ pageLabel = "\(((item as! CPDFOutline).destination?.pageIndex ?? 0) + 1)"
|
|
|
} else if item is CPDFBookmark {
|
|
|
title = (item as! CPDFBookmark).label
|
|
|
+ pageLabel = "\((item as! CPDFBookmark).pageIndex + 1)"
|
|
|
}
|
|
|
|
|
|
if tcID == LABEL_COLUMNID {
|
|
|
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];
|
|
|
//
|
|
@@ -3263,11 +3409,11 @@ extension KMLeftSideViewController: NSOutlineViewDelegate, NSOutlineViewDataSour
|
|
|
// [attributeString addAttribute:NSFontAttributeName value:[NSFont boldSystemFontOfSize:13] range:range];
|
|
|
// }
|
|
|
// cell.tocLabel.attributedStringValue = attributeString;
|
|
|
+ cell.tocLabel.stringValue = title
|
|
|
} else {
|
|
|
cell.tocLabel.stringValue = title
|
|
|
}
|
|
|
- // TODO: 不确定是哪个字段
|
|
|
- cell.pageLabel.stringValue = ""
|
|
|
+ cell.pageLabel.stringValue = pageLabel
|
|
|
}
|
|
|
// else if([tcID isEqualToString:PAGE_COLUMNID]) {
|
|
|
// cell.pageLabel.stringValue = [ol pageLabel];
|
|
@@ -3386,6 +3532,15 @@ extension KMLeftSideViewController: NSOutlineViewDelegate, NSOutlineViewDataSour
|
|
|
noteType = SKNSignatureString
|
|
|
} else if note.isKind(of: CPDFInkAnnotation.self) {
|
|
|
noteType = SKNInkString
|
|
|
+ } else if note.isKind(of: CPDFMarkupAnnotation.self) {
|
|
|
+ let anno = note as! CPDFMarkupAnnotation
|
|
|
+ if anno.markupType() == .highlight {
|
|
|
+ noteType = SKNHighlightString
|
|
|
+ } else if anno.markupType() == .underline {
|
|
|
+ noteType = SKNUnderlineString
|
|
|
+ } else if anno.markupType() == .strikeOut {
|
|
|
+ noteType = SKNStrikeOutString
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
cell.typeImageView.image = imageView.noteTypeImage(withType: noteType, color: noteColor ?? .red)
|
|
@@ -3615,15 +3770,26 @@ extension KMLeftSideViewController: NSOutlineViewDelegate, NSOutlineViewDataSour
|
|
|
|
|
|
func outlineView(_ outlineView: NSOutlineView, rowViewForItem item: Any) -> NSTableRowView? {
|
|
|
if outlineView.isEqual(self.tocOutlineView) {
|
|
|
- let itemView = KMCustomTableRowView()
|
|
|
+ let itemView = KMBotaTableRowView()
|
|
|
return itemView
|
|
|
} else if outlineView.isEqual(self.noteOutlineView) {
|
|
|
- let itemView = KMCustomTableRowView()
|
|
|
+ let itemView = KMBotaTableRowView()
|
|
|
return itemView;
|
|
|
}
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
+ func outlineViewSelectionDidChange(_ notification: Notification) {
|
|
|
+ if self.tocOutlineView.isEqual(to: notification.object) {
|
|
|
+// if ([[notification object] isEqual:leftSideController.tocOutlineView] && (mwcFlags.updatingOutlineSelection == 0)){
|
|
|
+// mwcFlags.updatingOutlineSelection = 1;
|
|
|
+ self.goToSelectedOutlineItem(nil)
|
|
|
+// mwcFlags.updatingOutlineSelection = 0;
|
|
|
+// if ([self interactionMode] == SKPresentationMode && [[NSUserDefaults standardUserDefaults] boolForKey:SKAutoHidePresentationContentsKey])
|
|
|
+// [self hideLeftSideWindow];
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
/*
|
|
|
#pragma mark NSOutlineView datasource protocol
|
|
|
|
|
@@ -3817,17 +3983,6 @@ extension KMLeftSideViewController: NSOutlineViewDelegate, NSOutlineViewDataSour
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- - (void)outlineViewSelectionDidChange:(NSNotification *)notification{
|
|
|
- // Get the destination associated with the search result list. Tell the PDFView to go there.
|
|
|
- if ([[notification object] isEqual:leftSideController.tocOutlineView] && (mwcFlags.updatingOutlineSelection == 0)){
|
|
|
- mwcFlags.updatingOutlineSelection = 1;
|
|
|
- [self goToSelectedOutlineItem:nil];
|
|
|
- mwcFlags.updatingOutlineSelection = 0;
|
|
|
- if ([self interactionMode] == SKPresentationMode && [[NSUserDefaults standardUserDefaults] boolForKey:SKAutoHidePresentationContentsKey])
|
|
|
- [self hideLeftSideWindow];
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- (NSString *)outlineView:(NSOutlineView *)ov toolTipForCell:(NSCell *)cell rect:(NSRectPointer)rect tableColumn:(NSTableColumn *)tableColumn item:(id)item mouseLocation:(NSPoint)mouseLocation {
|
|
|
if ([ov isEqual:rightSideController.noteOutlineView] &&
|
|
|
(tableColumn == nil || [[tableColumn identifier] isEqualToString:NOTE_COLUMNID])) {
|
|
@@ -4144,12 +4299,65 @@ extension KMLeftSideViewController: KMNoteOutlineViewDelegate {
|
|
|
}
|
|
|
|
|
|
extension KMLeftSideViewController: NSSearchFieldDelegate {
|
|
|
-
|
|
|
+ func controlTextDidChange(_ obj: Notification) {
|
|
|
+ if self.outlineSearchField.isEqual(to: obj.object) {
|
|
|
+ if (self.outlineSearchField.stringValue.isEmpty == false) {
|
|
|
+ self.isSearchOutlineMode = true
|
|
|
+
|
|
|
+ self.tocOutlineView.reloadData()
|
|
|
+ self.tocOutlineView.expandItem(nil, expandChildren: true)
|
|
|
+ self.tocType = .unfold
|
|
|
+ } else {
|
|
|
+ self.isSearchOutlineMode = false
|
|
|
+ self.showSearchOutlineBlankState(false)
|
|
|
+ self.tocOutlineView.reloadData()
|
|
|
+ }
|
|
|
+ // self.leftSideEmptyVC.addOutlineBtn.enabled = !self.isSearchOutlineMode;
|
|
|
+ self.outlineAddButton.isEnabled = !self.isSearchOutlineMode
|
|
|
+ }
|
|
|
+// else if ([obj.object isEqual:self.leftSideController.snapshotSearchField]) {
|
|
|
+// NSString *searchString = [self.leftSideController.snapshotSearchField stringValue];
|
|
|
+// NSPredicate *filterPredicate = nil;
|
|
|
+// if ([searchString length] > 0) {
|
|
|
+// NSExpression *lhs = [NSExpression expressionForConstantValue:searchString];
|
|
|
+// NSExpression *rhs = [NSExpression expressionForKeyPath:@"string"];
|
|
|
+// NSUInteger options = NSDiacriticInsensitivePredicateOption;
|
|
|
+// if (mwcFlags.caseInsensitiveNoteSearch)
|
|
|
+// options |= NSCaseInsensitivePredicateOption;
|
|
|
+// filterPredicate = [NSComparisonPredicate predicateWithLeftExpression:lhs rightExpression:rhs modifier:NSDirectPredicateModifier type:NSInPredicateOperatorType options:options];
|
|
|
+// }
|
|
|
+// [rightSideController.snapshotArrayController setFilterPredicate:filterPredicate];
|
|
|
+//
|
|
|
+// NSArray * snapshots = [rightSideController.snapshotArrayController arrangedObjects];
|
|
|
+// if (snapshots.count > 0) {
|
|
|
+// [self.leftSideEmptyVC.outlineSearchView removeFromSuperview];
|
|
|
+// } else {
|
|
|
+// NSView *view = rightSideController.snapshotTableView.enclosingScrollView;
|
|
|
+// CGSize emptyVcSize = self.leftSideEmptyVC.outlineSearchView.frame.size;
|
|
|
+// self.leftSideEmptyVC.outlineSearchView.frame = NSMakeRect((view.frame.size.width-emptyVcSize.width)/2.0,(view.frame.size.height-emptyVcSize.height)/2.0, emptyVcSize.width, emptyVcSize.height);
|
|
|
+// self.leftSideEmptyVC.outlineSearchView.autoresizingMask = NSViewMinXMargin | NSViewMaxXMargin| NSViewMaxYMargin | NSViewMinYMargin;
|
|
|
+// [rightSideController.snapshotTableView.enclosingScrollView.documentView addSubview:self.leftSideEmptyVC.outlineSearchView];
|
|
|
+// }
|
|
|
+// }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
extension KMLeftSideViewController: NSMenuDelegate {
|
|
|
func menuNeedsUpdate(_ menu: NSMenu) {
|
|
|
if menu.isEqual(to: self.tocOutlineView.menu) {
|
|
|
+ menu.removeAllItems()
|
|
|
+ var item = menu.addItem(withTitle: NSLocalizedString("Add Item", comment: ""), action: #selector(outlineContextMenuItemClicked_AddEntry), target: self, tag: 1)
|
|
|
+ item = menu.addItem(withTitle: NSLocalizedString("Add Sub-Item", comment: ""), action: #selector(outlineContextMenuItemClicked_AddChildEntry), target: self, tag: 2)
|
|
|
+ item = menu.addItem(withTitle: NSLocalizedString("Add To A Higher Level", comment: ""), action: #selector(outlineContextMenuItemClicked_AddAuntEntry), target: self, tag: 3)
|
|
|
+ menu.addItem(.separator())
|
|
|
+ item = menu.addItem(withTitle: NSLocalizedString("Delete", comment: ""), action: #selector(outlineContextMenuItemClicked_RemoveEntry), target: self, tag: 4)
|
|
|
+ menu.addItem(.separator())
|
|
|
+ item = menu.addItem(withTitle: NSLocalizedString("Edit", comment: ""), action: #selector(outlineContextMenuItemClicked_Edit), target: self, tag: 5)
|
|
|
+ item = menu.addItem(withTitle: NSLocalizedString("Change Destination", comment: ""), action: #selector(outlineContextMenuItemClicked_SetDestination), target: self, tag: 6)
|
|
|
+ item = menu.addItem(withTitle: NSLocalizedString("Rename", comment: ""), action: #selector(outlineContextMenuItemClicked_Rename), target: self, tag: 7)
|
|
|
+ menu.addItem(.separator())
|
|
|
+ item = menu.addItem(withTitle: NSLocalizedString("Promote", comment: ""), action: #selector(outlineContextMenuItemClicked_Promote), target: self, tag: 8)
|
|
|
+ item = menu.addItem(withTitle: NSLocalizedString("Demote", comment: ""), action: #selector(outlineContextMenuItemClicked_Demote), target: self, tag: 9)
|
|
|
return
|
|
|
}
|
|
|
var item: NSMenuItem?
|
|
@@ -4559,7 +4767,17 @@ extension KMLeftSideViewController {
|
|
|
}
|
|
|
|
|
|
@objc func searchNotes(_ sender: AnyObject?) {
|
|
|
- KMPrint("KMLeftSideViewController-searchNotes...")
|
|
|
+ if self.findState == .note {
|
|
|
+ // if (mwcFlags.findState == SKFindStateNote)
|
|
|
+// [self updateNoteFilterPredicate];
|
|
|
+ }
|
|
|
+// else
|
|
|
+// [self updateSnapshotFilterPredicate];
|
|
|
+// if ([[sender stringValue] length]) {
|
|
|
+// NSPasteboard *findPboard = [NSPasteboard pasteboardWithName:NSPasteboardNameFind];
|
|
|
+// [findPboard clearContents];
|
|
|
+// [findPboard writeObjects:[NSArray arrayWithObjects:[sender stringValue], nil]];
|
|
|
+// }
|
|
|
}
|
|
|
|
|
|
@objc func toggleSelectedSnapshots(_ sender: AnyObject?) {
|
|
@@ -4570,6 +4788,42 @@ extension KMLeftSideViewController {
|
|
|
KMPrint("KMLeftSideViewController-toggleOutlineCaseInsensitiveSearch...")
|
|
|
}
|
|
|
|
|
|
+ @objc func outlineContextMenuItemClicked_AddEntry(_ sender: AnyObject?) {
|
|
|
+ KMPrint("KMLeftSideViewController-outlineContextMenuItemClicked_AddEntry...")
|
|
|
+ }
|
|
|
+
|
|
|
+ @objc func outlineContextMenuItemClicked_AddChildEntry(_ sender: AnyObject?) {
|
|
|
+ KMPrint("KMLeftSideViewController-outlineContextMenuItemClicked_AddChildEntry...")
|
|
|
+ }
|
|
|
+
|
|
|
+ @objc func outlineContextMenuItemClicked_AddAuntEntry(_ sender: AnyObject?) {
|
|
|
+ KMPrint("KMLeftSideViewController-outlineContextMenuItemClicked_AddAuntEntry...")
|
|
|
+ }
|
|
|
+
|
|
|
+ @objc func outlineContextMenuItemClicked_RemoveEntry(_ sender: AnyObject?) {
|
|
|
+ KMPrint("KMLeftSideViewController-outlineContextMenuItemClicked_RemoveEntry...")
|
|
|
+ }
|
|
|
+
|
|
|
+ @objc func outlineContextMenuItemClicked_Edit(_ sender: AnyObject?) {
|
|
|
+ KMPrint("KMLeftSideViewController-outlineContextMenuItemClicked_Edit...")
|
|
|
+ }
|
|
|
+
|
|
|
+ @objc func outlineContextMenuItemClicked_SetDestination(_ sender: AnyObject?) {
|
|
|
+ KMPrint("KMLeftSideViewController-outlineContextMenuItemClicked_SetDestination...")
|
|
|
+ }
|
|
|
+
|
|
|
+ @objc func outlineContextMenuItemClicked_Rename(_ sender: AnyObject?) {
|
|
|
+ KMPrint("KMLeftSideViewController-outlineContextMenuItemClicked_Rename...")
|
|
|
+ }
|
|
|
+
|
|
|
+ @objc func outlineContextMenuItemClicked_Promote(_ sender: AnyObject?) {
|
|
|
+ KMPrint("KMLeftSideViewController-outlineContextMenuItemClicked_Promote...")
|
|
|
+ }
|
|
|
+
|
|
|
+ @objc func outlineContextMenuItemClicked_Demote(_ sender: AnyObject?) {
|
|
|
+ KMPrint("KMLeftSideViewController-outlineContextMenuItemClicked_Demote...")
|
|
|
+ }
|
|
|
+
|
|
|
private func _tableView(_ tv: NSTableView, cutRowsWithIndexes rowIndexes: IndexSet) {
|
|
|
// if tv.isEqual(to: self.thumbnailTableView) {
|
|
|
// self._copysPages.removeAll()
|
|
@@ -4588,15 +4842,21 @@ extension KMLeftSideViewController {
|
|
|
|
|
|
extension KMLeftSideViewController {
|
|
|
@objc func goToSelectedOutlineItem(_ sender: AnyObject?) {
|
|
|
- KMPrint("KMLeftSideViewController-goToSelectedOutlineItem...")
|
|
|
-// PDFOutline *outlineItem = [leftSideController.tocOutlineView itemAtRow:[leftSideController.tocOutlineView selectedRow]];
|
|
|
-// NSOutlineView *outline = (NSOutlineView *)leftSideController.tocOutlineView;
|
|
|
-// if (outline.selectedRowIndexes.count == 1) {
|
|
|
-// if ([outlineItem destination])
|
|
|
-// [pdfView goToDestination:[outlineItem destination]];
|
|
|
-// else if ([outlineItem action])
|
|
|
-// [pdfView performAction:[outlineItem action]];
|
|
|
-// }
|
|
|
+ let outlineItem = self.tocOutlineView.item(atRow: self.tocOutlineView.selectedRow)
|
|
|
+ let outline = self.tocOutlineView
|
|
|
+ if let cnt = outline?.selectedRowIndexes.count, cnt == 1 {
|
|
|
+ if outlineItem is CPDFOutline {
|
|
|
+ let outline = (outlineItem as! CPDFOutline)
|
|
|
+ if let des = outline.destination {
|
|
|
+ self.listView.go(to: des)
|
|
|
+ } else if let action = outline.action {
|
|
|
+ self.listView.perform(action)
|
|
|
+ }
|
|
|
+ } else if outlineItem is CPDFBookmark {
|
|
|
+ let bookmark = outlineItem as! CPDFBookmark
|
|
|
+ self.listView.go(toPageIndex: bookmark.pageIndex, animated: true)
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
@objc func goToSelectedFindResults(_ sender: AnyObject?) {
|