// // KMLeftSideViewController+Action.swift // PDF Reader Pro // // Created by tangchao on 2023/12/22. // import Foundation // MARK: - Action extension KMLeftSideViewController { @IBAction func leftSideViewMoreButtonAction(_ sender: AnyObject?) { let button = sender as? NSButton let tag = button?.tag ?? 0 if (tag == 300) { var selectedRow = 0 if (self.snapshotTableView.selectedRow >= 0) { selectedRow = self.snapshotTableView.selectedRow; } else { return } let model = self.snapshots[selectedRow] let controller = model.windowC let menu = NSMenu() let itemExport = menu.addItem(title: KMLocalizedString("Export", "Menu item title"), action: nil, target: self) let subMenu = NSMenu() var t = subMenu.addItem(title: KMLocalizedString("PNG", "Menu item title"), action: #selector(menuItemClick_ExportPNG), target: self) t?.representedObject = controller t = subMenu.addItem(title: KMLocalizedString("JPG", "Menu item title"), action: #selector(menuItemClick_ExportJPG), target: self) t?.representedObject = controller t = subMenu.addItem(title: KMLocalizedString("PDF", "Menu item title"), action: #selector(menuItemClick_ExportPDF), target: self) t?.representedObject = controller itemExport?.submenu = subMenu let itemPrint = menu.addItem(title: KMLocalizedString("Print", "Menu item title"), action: #selector(menuItemClick_Print), target: self) itemPrint?.representedObject = controller menu.addItem(.separator()) let itemSelectAll = menu.addItem(title: KMLocalizedString("Select All", "Menu item title"), action: #selector(menuItemClick_SelectAll), target: self) itemSelectAll?.representedObject = controller menu.addItem(.separator()) let itemDeleteAllSnapshot = menu.addItem(title: KMLocalizedString("Delete All Snapshots", "Menu item title"), action: #selector(deleteAllSnapshot), target: self) itemDeleteAllSnapshot?.representedObject = controller // NSMenu.popUpContextMenu(menu, with: NSApp.currentEvent!, for: sender as! NSButton) } else if (tag == 302) { let menu = NSMenu() let expandAllCommentsItem = menu.addItem(title: KMLocalizedString("Expand All", nil), action: #selector(toc_expandAllComments), target: self) expandAllCommentsItem?.representedObject = self.tocOutlineView let foldAllCommentsItem = menu.addItem(title: KMLocalizedString("Collapse All", nil), action: #selector(toc_foldAllComments), target: self) expandAllCommentsItem?.representedObject = self.tocOutlineView let item = self.listView.document.outlineRoot() var num = 0 for i in 0 ..< Int(item?.numberOfChildren ?? 0) { let outline = item?.child(at: UInt(i)) if self.tocOutlineView.isItemExpanded(outline) { num += 1 } } if let cnt = item?.numberOfChildren, cnt > 0 && num == 0 { self.tocType = .fold } else if let cnt = item?.numberOfChildren, cnt > 0 && num == cnt { self.tocType = .unfold } else { self.tocType = .none } if (self.tocType == .unfold) { expandAllCommentsItem?.state = .on foldAllCommentsItem?.state = .off } else if (self.tocType == .fold) { expandAllCommentsItem?.state = .off foldAllCommentsItem?.state = .on } else { expandAllCommentsItem?.state = .off foldAllCommentsItem?.state = .off } let removeEntryItem = menu.addItem(title: KMLocalizedString("Remove All Outlines", nil), action: #selector(leftSideEmptyAnnotationClick_DeleteOutline), target: self) removeEntryItem?.representedObject = self.tocOutlineView NSMenu.popUpContextMenu(menu, with: NSApp.currentEvent!, for: sender as! NSButton) } else if (tag == 304) { let menu = NSMenu() let object = KMPopupMenuObject() object.menuTag = 1001 menu.delegate = object object.enterControllerCallback = { [weak self] isEnter in if (isEnter) { self?.moreButtonLayer?.isHidden = false } else { self?.moreButtonLayer?.isHidden = true } } let expandAllCommentsItem = menu.addItem(title: KMLocalizedString("Expand All", nil), action: #selector(note_expandAllComments), target: self) expandAllCommentsItem?.representedObject = self.noteOutlineView let foldAllCommentsItem = menu.addItem(title: KMLocalizedString("Collapse All", nil), action: #selector(note_foldAllComments), target: self) foldAllCommentsItem?.representedObject = self.noteOutlineView if (self.foldType == .unfold) { expandAllCommentsItem?.state = .on foldAllCommentsItem?.state = .off } else if (self.foldType == .fold) { expandAllCommentsItem?.state = .off foldAllCommentsItem?.state = .on } else { expandAllCommentsItem?.state = .off foldAllCommentsItem?.state = .off } let showAnnotationItem = menu.addItem(title: KMLocalizedString("Show Note", nil), action: nil, target: self) let subMenu = NSMenu() var t = subMenu.addItem(title: KMLocalizedString("Page", nil), action: #selector(noteShowNoteAction), target: self) let pageKey = self.noteTypeDict[Self.Key.noteFilterPage] as? Bool ?? false if pageKey { t?.state = .off } else { t?.state = .on } t?.representedObject = self.noteOutlineView t?.tag = 101 t = subMenu.addItem(title: KMLocalizedString("Time", nil) , action: #selector(noteShowNoteAction), target: self) let timeKey = self.noteTypeDict[Self.Key.noteFilterTime] as? Bool ?? false if timeKey { t?.state = .off } else { t?.state = .on } t?.representedObject = self.noteOutlineView t?.tag = 102 t = subMenu.addItem(title: KMLocalizedString("Author", nil) , action: #selector(noteShowNoteAction), target: self) let authorKey = self.noteTypeDict[Self.Key.noteFilterAuther] as? Bool ?? false if authorKey { t?.state = .off } else { t?.state = .on } t?.representedObject = self.noteOutlineView t?.tag = 103 showAnnotationItem?.submenu = subMenu menu.addItem(.separator()) let exportAnnotationsItem = menu.addItem(title: NSLocalizedString("Export Annotations…", comment: ""), action: nil, target: self) let subMenu2 = NSMenu() var t2 = subMenu2.addItem(title: NSLocalizedString("PDF", comment: "Menu item title"), action: #selector(exportAnnotationNotes), target: self) t2?.representedObject = self.noteOutlineView t2?.tag = 0 t2 = subMenu2.addItem(title: NSLocalizedString("PDF Bundle", comment: "Menu item title"), action: #selector(exportAnnotationNotes), target: self) t2?.representedObject = self.noteOutlineView t2?.tag = 1 t2 = subMenu2.addItem(title: NSLocalizedString("PDF Reader Pro Edition Notes", comment: "Menu item title"), action: #selector(exportAnnotationNotes), target: self) t2?.representedObject = self.noteOutlineView t2?.tag = 2 t2 = subMenu2.addItem(title: NSLocalizedString("Notes as Text", comment: "Menu item title"), action: #selector(exportAnnotationNotes), target: self) t2?.representedObject = self.noteOutlineView t2?.tag = 3 t2 = subMenu2.addItem(title: NSLocalizedString("Notes as RTF", comment: "Menu item title"), action: #selector(exportAnnotationNotes), target: self) t2?.representedObject = self.noteOutlineView t2?.tag = 4 t2 = subMenu2.addItem(title: NSLocalizedString("Notes as RTFD", comment: "Menu item title"), action: #selector(exportAnnotationNotes), target: self) t2?.representedObject = self.noteOutlineView t2?.tag = 5 t2 = subMenu2.addItem(title: NSLocalizedString("Notes as FDF", comment: "Menu item title"), action: #selector(exportAnnotationNotes), target: self) t2?.representedObject = self.noteOutlineView t2?.tag = 6 exportAnnotationsItem?.submenu = subMenu2 menu.addItem(.separator()) let removeAllAnnotationsItem = menu.addItem(title: NSLocalizedString("Remove All Annotations", comment: ""), action: #selector(leftSideEmptyAnnotationClick_DeleteAnnotation), target: self) removeAllAnnotationsItem?.representedObject = self.noteOutlineView NSMenu.popUpContextMenu(menu, with: NSApp.currentEvent!, for: button!, with: nil) } } func searchFieldChangeAction(_ editContent: String) { if self.findState == .note { // if (mwcFlags.findState == SKFindStateNote) self.updateNoteFilterPredicate() } else { self.updateSnapshotFilterPredicate() } if editContent.count > 0 { let findPboard = NSPasteboard(name: .find) findPboard.clearContents() findPboard.writeObjects([editContent as NSPasteboardWriting]) } } @IBAction func search(_ sender: NSSearchField) { if sender.stringValue.isEmpty { self.applySearchTableHeader("") } self.delegate?.searchAction?(searchString: sender.stringValue, isCase: self.mwcFlags.caseInsensitiveSearch == 1) } } // MARK: - Double Action extension KMLeftSideViewController { @objc func toggleSelectedSnapshots(_ sender: AnyObject?) { let indexs = self.snapshotTableView.selectedRowIndexes if indexs.isEmpty { return } let model = self.snapshots[indexs.last!] let windowC = model.windowC if let data = windowC?.window?.isVisible, data { windowC?.miniaturize() } else { windowC?.deminiaturize() } var rowIndexSet = IndexSet() let row = self.snapshotTableView.selectedRow if row >= 0 && row < self.snapshots.count { rowIndexSet.insert(row) } var columnIndexSet = IndexSet() columnIndexSet.insert(0) self.snapshotTableView.reloadData(forRowIndexes: rowIndexSet, columnIndexes: columnIndexSet) } // MARK: - KMInterfaceThemeChangedProtocol override func interfaceThemeDidChanged(_ appearance: NSAppearance.Name) { super.interfaceThemeDidChanged(appearance) self.updateViewColor() self.leftView.interfaceThemeDidChanged(appearance) } } // MARK: - NSMenuDelegate extension KMLeftSideViewController: NSMenuDelegate { func menuNeedsUpdate(_ menu: NSMenu) { if menu.isEqual(to: self.tocOutlineView.menu) { menu.removeAllItems() _ = menu.addItem(withTitle: NSLocalizedString("Add Item", comment: ""), action: #selector(outlineContextMenuItemClicked_AddEntry), target: self, tag: KMOutlineViewMenuItemTag.addEntry.rawValue) _ = menu.addItem(withTitle: NSLocalizedString("Add Sub-Item", comment: ""), action: #selector(outlineContextMenuItemClicked_AddChildEntry), target: self, tag: KMOutlineViewMenuItemTag.addChild.rawValue) _ = menu.addItem(withTitle: NSLocalizedString("Add To A Higher Level", comment: ""), action: #selector(outlineContextMenuItemClicked_AddAuntEntry), target: self, tag: KMOutlineViewMenuItemTag.addAunt.rawValue) menu.addItem(.separator()) _ = menu.addItem(withTitle: NSLocalizedString("Delete", comment: ""), action: #selector(outlineContextMenuItemClicked_RemoveEntry), target: self, tag: KMOutlineViewMenuItemTag.remove.rawValue) menu.addItem(.separator()) _ = menu.addItem(withTitle: NSLocalizedString("Edit", comment: ""), action: #selector(outlineContextMenuItemClicked_Edit), target: self, tag: KMOutlineViewMenuItemTag.edit.rawValue) _ = menu.addItem(withTitle: NSLocalizedString("Change Destination", comment: ""), action: #selector(outlineContextMenuItemClicked_SetDestination), target: self, tag: KMOutlineViewMenuItemTag.setDestination.rawValue) _ = menu.addItem(withTitle: NSLocalizedString("Rename", comment: ""), action: #selector(outlineContextMenuItemClicked_Rename), target: self, tag: KMOutlineViewMenuItemTag.rename.rawValue) menu.addItem(.separator()) _ = menu.addItem(withTitle: NSLocalizedString("Promote", comment: ""), action: #selector(outlineContextMenuItemClicked_Promote), target: self, tag: KMOutlineViewMenuItemTag.promote.rawValue) _ = menu.addItem(withTitle: NSLocalizedString("Demote", comment: ""), action: #selector(outlineContextMenuItemClicked_Demote), target: self, tag: KMOutlineViewMenuItemTag.demote.rawValue) return } var item: NSMenuItem? menu.removeAllItems() if menu.isEqual(to: self.thumbnailTableView.menu) { let row = self.thumbnailTableView.clickedRow if self.listView.document.documentURL == nil || self.thumbnailTableView.selectedRowIndexes.contains(row) == false{ return } if (row != -1 && self.listView.document.isLocked == false) { if(self.thumbnailTableView.selectedRowIndexes.count == self.listView.document.pageCount) { item = menu.addItem(title: KMLocalizedString("Cut", "Menu item title"), action: nil, target: self) } else { item = menu.addItem(title: KMLocalizedString("Cut", "Menu item title"), action: #selector(cutPage), target: self) } item?.representedObject = IndexSet(integer: row) item = menu.addItem(title: KMLocalizedString("Copy", "Menu item title"), action: #selector(copyPage), target: self) item?.representedObject = IndexSet(integer: row) if (self.copyPages.count > 0) { item = menu.addItem(title: KMLocalizedString("Paste", "Menu item title"), action: #selector(pastePage), target: self) }else{ item = menu.addItem(title: KMLocalizedString("Paste", "Menu item title"), action: nil, target: self) } item?.representedObject = IndexSet(integer: row) menu.addItem(.separator()) if(self.thumbnailTableView.selectedRowIndexes.count == self.listView.document.pageCount) { item = menu.addItem(title: KMLocalizedString("Delete", "Menu item title"), action: nil, target: self) } else { item = menu.addItem(title: KMLocalizedString("Delete", "Menu item title"), action: #selector(deletePage), target: self) } item?.representedObject = IndexSet(integer: row) menu.addItem(.separator()) item = menu.addItem(title: KMLocalizedString("Rotate", "Menu item title"), action: #selector(rotatePageMenuAction), target: self) item?.representedObject = IndexSet(integer: row) item = menu.addItem(title: KMLocalizedString("Insert", "Menu item title"), action: nil, target: self) let subMenu = NSMenu() _ = subMenu.addItem(title: KMLocalizedString("Blank Page", "Menu item title"), action: #selector(quickInsert), target: self) _ = subMenu.addItem(title: KMLocalizedString("Blank Page - Custom...", "Menu item title"), action: #selector(insert), target: self) _ = subMenu.addItem(title: KMLocalizedString("From PDF", "Menu item title"), action: #selector(insertPDF), target: self) item?.submenu = subMenu item?.representedObject = IndexSet(integer: row) item = menu.addItem(title: KMLocalizedString("Extract", "Menu item title"), action: #selector(extractPage), target: self) item?.representedObject = IndexSet(integer: row) item = menu.addItem(title: KMLocalizedString("Page Edit", "Menu item title"), action: #selector(pageEdit), target: self) menu.addItem(.separator()) var displayStr = "" if (self.isDisplayPageSize) { displayStr = KMLocalizedString("Hide Page Size", "Menu item title") } else { displayStr = KMLocalizedString("Display Page Size", "Menu item title") } item = menu.addItem(title: displayStr, action: #selector(displayPageSize), target: self) item?.representedObject = IndexSet(integer: row) if let doct = self.listView?.document { item = menu.addItem(title: KMLocalizedString("Share", "Menu item title"), action: nil, target: self) var tName = self.fileNameWithSelectedPages(self.thumbnailTableView.selectedRowIndexes) if (tName.count > 50) { tName = tName.substring(to: 50) } item?.submenu = NSSharingServicePicker.menu(forSharingItems: [doct.documentURL as Any], subjectContext: tName, withTarget: self, selector: #selector(sharePage), serviceDelegate: nil) } } } else if menu.isEqual(to: self.findTableView.menu) { var rowIndexes = self.findTableView.selectedRowIndexes let row = self.findTableView.clickedRow if (row != -1) { if rowIndexes.contains(row) == false { rowIndexes = IndexSet(integer: row) } var selections: [CPDFSelection] = [] for (i, data) in self.searchResults.enumerated() { if rowIndexes.contains(i) { selections.append(data.selection) } } if self.listView.hideNotes == false && self.listView.allowsNotes() { item = menu.addItem(withTitle: KMLocalizedString("Add New Circle", "Menu item title"), action: #selector(addAnnotationsForSelections), target: self, tag: CAnnotationType.circle.rawValue) item?.representedObject = selections item = menu.addItem(withTitle: KMLocalizedString("Add New Rectangle", "Menu item title"), action: #selector(addAnnotationsForSelections), target: self, tag: CAnnotationType.square.rawValue) item?.representedObject = selections item = menu.addItem(withTitle: KMLocalizedString("Add New Highlight", "Menu item title"), action: #selector(addAnnotationsForSelections), target: self, tag: CAnnotationType.highlight.rawValue) item?.representedObject = selections item = menu.addItem(withTitle: KMLocalizedString("Add New Underline", "Menu item title"), action: #selector(addAnnotationsForSelections), target: self, tag: CAnnotationType.underline.rawValue) item?.representedObject = selections item = menu.addItem(withTitle: KMLocalizedString("Add New Strikethrough", "Menu item title"), action: #selector(addAnnotationsForSelections), target: self, tag: CAnnotationType.strikeOut.rawValue) item?.representedObject = selections } } } else if menu.isEqual(to: self.groupedFindTableView.menu) { var rowIndexes = self.groupedFindTableView.selectedRowIndexes let row = self.groupedFindTableView.clickedRow if (row != -1) { if rowIndexes.contains(row) == false { rowIndexes = IndexSet(integer: row) } // NSArray *selections = [[[leftSideController.groupedFindArrayController arrangedObjects] objectsAtIndexes:rowIndexes] valueForKeyPath:@"@unionOfArrays.matches"]; var selections: [CPDFSelection] = [] for (i, data) in self.groupSearchResults.enumerated() { if rowIndexes.contains(i) { for searchM in data.datas { selections.append(searchM.selection) } } } item = menu.addItem(title: KMLocalizedString("Select", "Menu item title"), action: #selector(selectSelections), target: self) item?.representedObject = selections menu.addItem(.separator()) if self.listView.hideNotes == false && self.listView.allowsNotes() { item = menu.addItem(withTitle: KMLocalizedString("Add New Circle", "Menu item title"), action: #selector(addAnnotationsForSelections), target: self, tag: CAnnotationType.circle.rawValue) item?.representedObject = selections item = menu.addItem(withTitle: KMLocalizedString("Add New Rectangle", "Menu item title"), action: #selector(addAnnotationsForSelections), target: self, tag: CAnnotationType.square.rawValue) item?.representedObject = selections item = menu.addItem(withTitle: KMLocalizedString("Add New Highlight", "Menu item title"), action: #selector(addAnnotationsForSelections), target: self, tag: CAnnotationType.highlight.rawValue) item?.representedObject = selections item = menu.addItem(withTitle: KMLocalizedString("Add New Underline", "Menu item title"), action: #selector(addAnnotationsForSelections), target: self, tag: CAnnotationType.underline.rawValue) item?.representedObject = selections item = menu.addItem(withTitle: KMLocalizedString("Add New Strikethrough", "Menu item title"), action: #selector(addAnnotationsForSelections), target: self, tag: CAnnotationType.strikeOut.rawValue) item?.representedObject = selections } } } else if menu.isEqual(to: self.snapshotTableView.menu) { let row = self.snapshotTableView.clickedRow if (row != -1) { let model = self.snapshots[row] let controller = model.windowC if let data = controller?.window?.isVisible, data { item = menu.addItem(title: KMLocalizedString("Hide", "Menu item title"), action: #selector(hideSnapshot), target: self) item?.representedObject = controller } else { item = menu.addItem(title: KMLocalizedString("Show", "Menu item title"), action: #selector(showSnapshot), target: self) item?.representedObject = controller } menu.addItem(.separator()) item = menu.addItem(title: KMLocalizedString("Export", "Menu item title"), action: nil, target: self) let subMenu = NSMenu() var t = subMenu.addItem(title: KMLocalizedString("PNG", "Menu item title"), action: #selector(menuItemClick_ExportPNG), target: self) t?.representedObject = controller t = subMenu.addItem(title: KMLocalizedString("JPG", "Menu item title"), action: #selector(menuItemClick_ExportJPG), target: self) t?.representedObject = controller t = subMenu.addItem(title: KMLocalizedString("PDF", "Menu item title"), action: #selector(menuItemClick_ExportPDF), target: self) t?.representedObject = controller item?.submenu = subMenu item = menu.addItem(title: KMLocalizedString("Print", "Menu item title"), action: #selector(menuItemClick_Print), target: self) item?.representedObject = controller menu.addItem(.separator()) item = menu.addItem(title: KMLocalizedString("Copy", "Menu item title"), action: #selector(menuItemClick_Copy), target: self) item?.representedObject = controller menu.addItem(.separator()) item = menu.addItem(title: KMLocalizedString("Delete", "Menu item title"), action: #selector(deleteSnapshot), target: self) item?.representedObject = controller item = menu.addItem(title: KMLocalizedString("Delete All Snapshots", "Menu item title"), action: #selector(deleteAllSnapshot), target: self) item?.representedObject = controller } } else if menu.isEqual(to: self.noteOutlineView.menu) { var items: NSArray? var rowIndexes = self.noteOutlineView.selectedRowIndexes let row = self.noteOutlineView.clickedRow if (row != -1) { if rowIndexes.contains(row) == false { rowIndexes = IndexSet(integer: row) } items = self.noteOutlineView.itemsAtRowIndexes(rowIndexes) as NSArray // PDFAnnotation *foldNote = (PDFAnnotation *)notes[row]; // let foldNote = self.allAnnotations[row] guard let foldNote = self.fetchNote(for: row) else { return } var isFold = true if self.allFoldNotes.contains(foldNote) { isFold = false } item = menu.addItem(title: KMLocalizedString("Expand", nil), action: #selector(unfoldNoteAction), target: self) if (isFold) { item?.state = .off } else { item?.state = .on } item?.representedObject = items item = menu.addItem(title: KMLocalizedString("Collapse", nil), action: #selector(foldNoteAction), target: self) if (isFold) { item?.state = .on } else { item?.state = .off } item?.representedObject = items menu.addItem(.separator()) if self.listView.hideNotes == false && (items?.count ?? 0) == 1 { let annotation = self.noteItems(items!).lastObject as? CPDFAnnotation if let data = annotation?.isEditable(), data { if annotation?.type == nil { if annotation!.isNote() { // [NSLocalizedString(@"Edit", @"Menu item title") stringByAppendingEllipsis] item = menu.addItem(title: KMLocalizedString("Edit", "Menu item title"), action: #selector(editNoteTextFromTable), target: self) item?.representedObject = annotation } } else if let data = self.noteOutlineView.tableColumn(withIdentifier: NSUserInterfaceItemIdentifier("note"))?.isHidden, data { // [NSLocalizedString(@"Edit", @"Menu item title") stringByAppendingEllipsis] item = menu.addItem(title: KMLocalizedString("Edit", "Menu item title"), action: #selector(editThisAnnotation), target: self) item?.representedObject = annotation } else { item = menu.addItem(title: KMLocalizedString("Edit", "Menu item title"), action: #selector(editNoteFromTable), target: self) item?.representedObject = annotation item = menu.addItem(title: KMLocalizedString("Edit", "Menu item title"), action: #selector(editThisAnnotation), target: self) item?.representedObject = annotation item?.keyEquivalentModifierMask = [.option] item?.isAlternate = true } } } if menu.numberOfItems > 0 { item = menu.addItem(title: NSLocalizedString("Export Annotations…", tableName: "MainMenu", comment: "Menu item title"), action: #selector(exportAnnotationNotes), target: self) let subMenu = NSMenu() item?.submenu = subMenu item = subMenu.addItem(title: NSLocalizedString("PDF", tableName: "MainMenu", comment: "Menu item title"), action: #selector(exportAnnotationNotes), target: self) item?.tag = 0 item = subMenu.addItem(title: NSLocalizedString("PDF Bundle", tableName: "MainMenu", comment: "Menu item title"), action: #selector(exportAnnotationNotes), target: self) item?.tag = 1 item = subMenu.addItem(title: NSLocalizedString("PDF Reader Pro Edition Notes", tableName: "MainMenu", comment: "Menu item title"), action: #selector(exportAnnotationNotes), target: self) item?.tag = 2 item = subMenu.addItem(title: NSLocalizedString("Notes as Texts", tableName: "MainMenu", comment: "Menu item title"), action: #selector(exportAnnotationNotes), target: self) item?.tag = 3 item = subMenu.addItem(title: NSLocalizedString("Notes as RTF", tableName: "MainMenu", comment: "Menu item title"), action: #selector(exportAnnotationNotes), target: self) item?.tag = 4 item = subMenu.addItem(title: NSLocalizedString("Notes as RTFD", tableName: "MainMenu", comment: "Menu item title"), action: #selector(exportAnnotationNotes), target: self) item?.tag = 5 item = subMenu.addItem(title: NSLocalizedString("Notes as FDF", tableName: "MainMenu", comment: "Menu item title"), action: #selector(exportAnnotationNotes), target: self) item?.tag = 6 menu.addItem(.separator()) if self.outlineView(self.noteOutlineView, canDeleteItems: items as! [Any]) { item = menu.addItem(title: KMLocalizedString("Delete", "Menu item title"), action: #selector(deleteNotes), target: self) item?.representedObject = items } item = menu.addItem(title: NSLocalizedString("Remove All Annotations", tableName: "MainMenu", comment: "Menu item title"), action: #selector(removeAllAnnotations), target: self) } } else { let subMenu = NSMenu() item?.submenu = subMenu item = subMenu.addItem(title: NSLocalizedString("PDF", tableName: "MainMenu", comment: "Menu item title"), action: #selector(exportAnnotationNotes), target: self) item?.tag = 0 item = subMenu.addItem(title: NSLocalizedString("PDF Bundle", tableName: "MainMenu", comment: "Menu item title"), action: #selector(exportAnnotationNotes), target: self) item?.tag = 1 item = subMenu.addItem(title: NSLocalizedString("PDF Reader Pro Edition Notes", tableName: "MainMenu", comment: "Menu item title"), action: #selector(exportAnnotationNotes), target: self) item?.tag = 2 item = subMenu.addItem(title: NSLocalizedString("Notes as Texts", tableName: "MainMenu", comment: "Menu item title"), action: #selector(exportAnnotationNotes), target: self) item?.tag = 3 item = subMenu.addItem(title: NSLocalizedString("Notes as RTF", tableName: "MainMenu", comment: "Menu item title"), action: #selector(exportAnnotationNotes), target: self) item?.tag = 4 item = subMenu.addItem(title: NSLocalizedString("Notes as RTFD", tableName: "MainMenu", comment: "Menu item title"), action: #selector(exportAnnotationNotes), target: self) item?.tag = 5 item = subMenu.addItem(title: NSLocalizedString("Notes as FDF", tableName: "MainMenu", comment: "Menu item title"), action: #selector(exportAnnotationNotes), target: self) item?.tag = 6 item = menu.addItem(title: NSLocalizedString("Remove All Annotations", tableName: "MainMenu", comment: "Menu item title"), action: #selector(removeAllAnnotations), target: self) } } } } // MARK: - NSMenuItemValidation extension KMLeftSideViewController: NSMenuItemValidation { func validateMenuItem(_ menuItem: NSMenuItem) -> Bool { if (self.listView.document == nil || self.listView.document!.isLocked) { return false } let action = menuItem.action // if (self.isCompareMode) { // return NO; // } // if (action == @selector(createNewNote:)) { // BOOL isMarkup = [menuItem tag] == SKHighlightNote || [menuItem tag] == SKUnderlineNote || [menuItem tag] == SKStrikeOutNote; // isMarkup = NO; // return [self interactionMode] != SKPresentationMode && [[self pdfDocument] allowsNotes] && ([pdfView toolMode] == SKTextToolMode || [pdfView toolMode] == SKNoteToolMode) && [pdfView hideNotes] == NO && (isMarkup == NO || [[pdfView currentSelection] hasCharacters]); // } else if (action == @selector(editNote:)) { // PDFAnnotation *annotation = [pdfView activeAnnotation]; // return [self interactionMode] != SKPresentationMode && [annotation isSkimNote] && ([annotation isEditable]); // } else if (action == @selector(alignLeft:) || action == @selector(alignRight:) || action == @selector(alignCenter:)) { // PDFAnnotation *annotation = [pdfView activeAnnotation]; // return [self interactionMode] != SKPresentationMode && [annotation isSkimNote] && ([annotation isEditable]) && [annotation respondsToSelector:@selector(setAlignment:)]; // } else if (action == @selector(toggleHideNotes:)) { // if ([pdfView hideNotes]) // [menuItem setTitle:NSLocalizedString(@"Show Notes", @"Menu item title")]; // else // [menuItem setTitle:NSLocalizedString(@"Hide Notes", @"Menu item title")]; // return YES; // } else if (action == @selector(changeDisplaySinglePages:)) { // [menuItem setState:([pdfView displayMode] & kPDFDisplayTwoUp) == (PDFDisplayMode)[menuItem tag] ? NSOnState : NSOffState]; // return [self interactionMode] != SKPresentationMode && [[self pdfDocument] isLocked] == NO; // } else if (action == @selector(changeDisplayContinuous:)) { // [menuItem setState:([pdfView displayMode] & kPDFDisplaySinglePageContinuous) == (PDFDisplayMode)[menuItem tag] ? NSOnState : NSOffState]; // return [self interactionMode] != SKPresentationMode && [[self pdfDocument] isLocked] == NO; // } else if (action == @selector(changeDisplayMode:)) { // [menuItem setState:[pdfView displayMode] == (PDFDisplayMode)[menuItem tag] ? NSOnState : NSOffState]; // return [self interactionMode] != SKPresentationMode && [[self pdfDocument] isLocked] == NO; // } else if (action == @selector(toggleDisplayAsBook:)) { // [menuItem setState:[pdfView displaysAsBook] ? NSOnState : NSOffState]; // return [self interactionMode] != SKPresentationMode && [[self pdfDocument] isLocked] == NO && ([pdfView displayMode] == kPDFDisplayTwoUp || [pdfView displayMode] == kPDFDisplayTwoUpContinuous); // } else if (action == @selector(toggleDisplayPageBreaks:)) { // [menuItem setState:[pdfView displaysPageBreaks] ? NSOnState : NSOffState]; // return [self interactionMode] != SKPresentationMode && [[self pdfDocument] isLocked] == NO; // } else if (action == @selector(changeDisplayBox:)) { // [menuItem setState:[pdfView displayBox] == (PDFDisplayBox)[menuItem tag] ? NSOnState : NSOffState]; // return [self interactionMode] != SKPresentationMode && [[self pdfDocument] isLocked] == NO; // } else if (action == @selector(delete:) || action == @selector(copy:) || action == @selector(cut:) || action == @selector(paste:) || action == @selector(alternatePaste:) || action == @selector(pasteAsPlainText:) || action == @selector(deselectAll:) || action == @selector(changeAnnotationMode:) || action == @selector(changeToolMode:) || action == @selector(changeToolMode:)) { // return [pdfView validateMenuItem:menuItem]; // } else // if (action == @selector(doGoToNextPage:)) { // return [pdfView canGoToNextPage]; // } else if (action == @selector(doGoToPreviousPage:) ) { // return [pdfView canGoToPreviousPage]; // } else if (action == @selector(doGoToFirstPage:)) { // return [pdfView canGoToFirstPage]; // } else if (action == @selector(doGoToLastPage:)) { // return [pdfView canGoToLastPage]; // } else if (action == @selector(doGoToPage:)) { // return [[self pdfDocument] isLocked] == NO; // } else if (action == @selector(allGoToNextPage:)) { // return [[allMainDocumentPDFViews() valueForKeyPath:@"@min.canGoToNextPage"] boolValue]; // } else if (action == @selector(allGoToPreviousPage:)) { // return [[allMainDocumentPDFViews() valueForKeyPath:@"@min.canGoToPreviousPage"] boolValue]; // } else if (action == @selector(allGoToFirstPage:)) { // return [[allMainDocumentPDFViews() valueForKeyPath:@"@min.canGoToFirstPage"] boolValue]; // } else if (action == @selector(allGoToLastPage:)) { // return [[allMainDocumentPDFViews() valueForKeyPath:@"@min.canGoToLastPage"] boolValue]; // } else if (action == @selector(doGoBack:)) { // return [pdfView canGoBack]; // } else if (action == @selector(doGoForward:)) { // return [pdfView canGoForward]; // } else if (action == @selector(goToMarkedPage:)) { // if (beforeMarkedPageIndex != NSNotFound) { // [menuItem setTitle:NSLocalizedString(@"Jump Back From Marked Page", @"Menu item title")]; // return YES; // } else { // [menuItem setTitle:NSLocalizedString(@"Go To Marked Page", @"Menu item title")]; // return markedPageIndex != NSNotFound && markedPageIndex != [[pdfView currentPage] pageIndex]; // } // } else if (action == @selector(markPage:)) { // return [[self pdfDocument] isLocked] == NO; // } else if (action == @selector(doZoomIn:)) { // return [self interactionMode] != SKPresentationMode && [pdfView canZoomIn]; // } else if (action == @selector(doZoomOut:)) { // return [self interactionMode] != SKPresentationMode && [pdfView canZoomOut]; // } else if (action == @selector(doZoomToActualSize:)) { // return [[self pdfDocument] isLocked] == NO && ([pdfView autoScales] || fabs([pdfView scaleFactor] - 1.0 ) > 0.01); // } else if (action == @selector(doZoomToPhysicalSize:)) { // return [self interactionMode] != SKPresentationMode && [[self pdfDocument] isLocked] == NO && ([pdfView autoScales] || fabs([pdfView physicalScaleFactor] - 1.0 ) > 0.01); // } else if (action == @selector(doMarqueeZoomTool:)) { // return [self interactionMode] != SKPresentationMode && [[self pdfDocument] isLocked] == NO; // } else if (action == @selector(doZoomToFit:)) { // return [self interactionMode] != SKPresentationMode && [[self pdfDocument] isLocked] == NO && [pdfView autoScales] == NO; // } else if (action == @selector(alternateZoomToFit:)) { // PDFDisplayMode displayMode = [pdfView displayMode]; // if (displayMode == kPDFDisplaySinglePage || displayMode == kPDFDisplayTwoUp) { // [menuItem setTitle:NSLocalizedString(@"Zoom To Width", @"Menu item title")]; // } else { // [menuItem setTitle:NSLocalizedString(@"Zoom To Height", @"Menu item title")]; // } // return [self interactionMode] != SKPresentationMode && [[self pdfDocument] isLocked] == NO; // } else // if (action == @selector(doAutoScale:)) { // return [[self pdfDocument] isLocked] == NO && [pdfView autoScales] == NO; // } else if (action == @selector(toggleAutoScale:)) { // [menuItem setState:[pdfView autoScales] ? NSOnState : NSOffState]; // return [[self pdfDocument] isLocked] == NO; // } else if (action == @selector(rotateRight:) || action == @selector(rotateLeft:) || action == @selector(rotateAllRight:) || action == @selector(rotateAllLeft:)) { // return [[self pdfDocument] isLocked] == NO; // } else if (action == @selector(cropAll:) || action == @selector(crop:) || action == @selector(autoCropAll:) || action == @selector(smartAutoCropAll:)) { // return [self interactionMode] != SKPresentationMode && [[self pdfDocument] isLocked] == NO; // } else if (action == @selector(autoSelectContent:)) { // return [self interactionMode] != SKPresentationMode && [[self pdfDocument] isLocked] == NO && [pdfView toolMode] == SKSelectToolMode; // } else if (action == @selector(takeSnapshot:)) { // return [[self pdfDocument] isLocked] == NO; // } else if (action == @selector(changeLeftSidePaneState:)) { // [menuItem setState:mwcFlags.leftSidePaneState == (SKLeftSidePaneState)[menuItem tag] ? (([leftSideController.findTableView window] || [leftSideController.groupedFindTableView window]) ? NSMixedState : NSOnState) : NSOffState]; // return (SKLeftSidePaneState)[menuItem tag] == SKSidePaneStateThumbnail || [[pdfView document] outlineRoot]; // } else if (action == @selector(changeRightSidePaneState:)) { // [menuItem setState:mwcFlags.rightSidePaneState == (SKRightSidePaneState)[menuItem tag] ? NSOnState : NSOffState]; // return [self interactionMode] != SKPresentationMode; // } // // else if (action == @selector(toggleSplitPDF:)) { // // if ([(NSView *)secondaryPdfView window]) // // [menuItem setTitle:NSLocalizedString(@"Hide Split PDF", @"Menu item title")]; // // else // // [menuItem setTitle:NSLocalizedString(@"Show Split PDF", @"Menu item title")]; // // return [self interactionMode] != SKPresentationMode; // // } // else // if (action == @selector(toggleStatusBar:)) { // if ([statusBar isVisible]) // [menuItem setTitle:NSLocalizedString(@"Hide Status Bar", @"Menu item title")]; // else // [menuItem setTitle:NSLocalizedString(@"Show Status Bar", @"Menu item title")]; // return [self interactionMode] == SKNormalMode || [self interactionMode] == SKFullScreenMode; // } else if (action == @selector(searchPDF:)) { // return [self interactionMode] != SKPresentationMode; // } else if (action == @selector(toggleFullscreen:)) { // if ([self interactionMode] == SKFullScreenMode || [self interactionMode] == SKLegacyFullScreenMode) // [menuItem setTitle:NSLocalizedString(@"Exit Full Screen", @"Menu item title")]; // else // [menuItem setTitle:NSLocalizedString(@"Full Screen", @"Menu item title")]; // return [self canEnterFullscreen] || [self canExitFullscreen]; // } else if (action == @selector(togglePresentation:)) { // if ([self interactionMode] == SKPresentationMode) // [menuItem setTitle:NSLocalizedString(@"Exit Presentation", @"Menu item title")]; // else // [menuItem setTitle:NSLocalizedString(@"Presentation", @"Menu item title")]; // return [self canEnterPresentation] || [self canExitPresentation]; // } else if (action == @selector(getInfo:)) { // return [self interactionMode] != SKPresentationMode; // } else if (action == @selector(performFit:)) { // return [self interactionMode] == SKNormalMode && [[self pdfDocument] isLocked] == NO; // } else if (action == @selector(password:)) { // return [self interactionMode] != SKPresentationMode && [[self pdfDocument] permissionsStatus] != kPDFDocumentPermissionsOwner; // } else if (action == @selector(toggleReadingBar:)) { // if ([[self pdfView] hasReadingBar]) // [menuItem setTitle:NSLocalizedString(@"Hide Reading Bar", @"Menu item title")]; // else // [menuItem setTitle:NSLocalizedString(@"Show Reading Bar", @"Menu item title")]; // return [self interactionMode] != SKPresentationMode && [[self pdfDocument] isLocked] == NO; // } else // if (action == @selector(savePDFSettingToDefaults:)) { // if ([self interactionMode] == SKFullScreenMode || [self interactionMode] == SKLegacyFullScreenMode) // [menuItem setTitle:NSLocalizedString(@"Use Current View Settings as Default for Full Screen", @"Menu item title")]; // else // [menuItem setTitle:NSLocalizedString(@"Use Current View Settings as Default", @"Menu item title")]; // return [self interactionMode] != SKPresentationMode && [[self pdfDocument] isLocked] == NO; // } else if (action == @selector(chooseTransition:)) { // return [[self pdfDocument] pageCount] > 1; // } else if (action == #selector(toggleCaseInsensitiveSearch)) { let state = KMDataManager.ud_integer(forKey: SKCaseInsensitiveSearchKey) menuItem.state = state == 1 ? .on : .off return true } else if (action == #selector(toggleWholeWordSearch)) { menuItem.state = self.mwcFlags.wholeWordSearch == 1 ? .on : .off return true } else if action == #selector(toggleCaseInsensitiveNoteSearch) { menuItem.state = self.caseInsensitiveNoteSearch ? .on : .off return true } // else if (action == @selector(toggleAutoResizeNoteRows:)) { // [menuItem setState:mwcFlags.autoResizeNoteRows ? NSOnState : NSOffState]; // return YES; // } else if (action == @selector(performFindPanelAction:)) { // if ([self interactionMode] == SKPresentationMode) // return NO; // switch ([menuItem tag]) { // case NSFindPanelActionShowFindPanel: // return YES; // case NSFindPanelActionNext: // case NSFindPanelActionPrevious: // return YES; // case NSFindPanelActionSetFindString: // return [[[self pdfView] currentSelection] hasCharacters]; // default: // return NO; // } // } else // if (action == @selector(highlightFormFiled:)) { // BOOL highlightFormFiled = [[NSUserDefaults standardUserDefaults] boolForKey:@"kPDFViewHighlightFormFiledKey"]; // [menuItem setState:highlightFormFiled ? NSOnState : NSOffState]; // return YES; // } else if (action == @selector(highlightLinks:)) { // BOOL highlightLinks = [[NSUserDefaults standardUserDefaults] boolForKey:@"kPDFViewHighlightLinksKey"]; // [menuItem setState:highlightLinks ? NSOnState : NSOffState]; // return YES; // } else if (action == @selector(link:)) { // return ([self.pdfView toolMode] == SKTextToolMode || [self.pdfView toolMode] == SKNoteToolMode) && [self.pdfView hideNotes] == NO && [self.pdfView.document isLocked] == NO; // return ([self.pdfView toolMode] == SKTextToolMode || [self.pdfView toolMode] == SKNoteToolMode) && [self.pdfView hideNotes] == NO && [self.pdfView.document isLocked] == NO && [[self.pdfView currentSelection] hasCharacters]; // } else if (action == @selector(deletePage:)) { // return self.pdfView.document.pageCount > 1 ? YES : NO; // } else if (action == @selector(themesColor:)){ // if (KMPDFViewModeNormal== self.pdfView.viewMode) { // [menuItem setState:(menuItem.tag == 0)?NSOnState:NSOffState]; // } else if (KMPDFViewModeSoft == self.pdfView.viewMode){ // [menuItem setState:(menuItem.tag == 1)?NSOnState:NSOffState]; // } else if (KMPDFViewModeNight == self.pdfView.viewMode){ // [menuItem setState:(menuItem.tag == 2)?NSOnState:NSOffState]; // } else if (KMPDFViewModeGreen == self.pdfView.viewMode){ // [menuItem setState:(menuItem.tag == 3)?NSOnState:NSOffState]; // } else if (KMPDFViewModeThemes1 == self.pdfView.viewMode){ // [menuItem setState:(menuItem.tag == 4)?NSOnState:NSOffState]; // } else if (KMPDFViewModeThemes2 == self.pdfView.viewMode){ // [menuItem setState:(menuItem.tag == 5)?NSOnState:NSOffState]; // } else if (KMPDFViewModeThemes3 == self.pdfView.viewMode){ // [menuItem setState:(menuItem.tag == 6)?NSOnState:NSOffState]; // } else if (KMPDFViewModeThemes4 == self.pdfView.viewMode){ // [menuItem setState:(menuItem.tag == 7)?NSOnState:NSOffState]; // } // // else { // // [menuItem setState:(menuItem.tag == 4)?NSOnState:NSOffState]; // // } // NSData * data = [[NSUserDefaults standardUserDefaults] objectForKey:@"kKMPDFViewModeThemesArray"] ? : nil; // NSInteger themesCount; // if (data) { // NSArray * appArray = [NSKeyedUnarchiver unarchiveObjectWithData:data]; // NSMutableArray * mutableArray = [NSMutableArray arrayWithArray:appArray]; // themesCount = [menuItem tag] - mutableArray.count; // } else { // themesCount = [menuItem tag] - 4; // } // if (themesCount >= 0) { // menuItem.hidden = YES; // return NO; // } else { // menuItem.hidden = NO; // return YES; // } // } else if (action == #selector(outlineContextMenuItemClicked_AddEntry) || action == #selector(outlineContextMenuItemClicked_AddChildEntry) || action == #selector(outlineContextMenuItemClicked_AddAuntEntry) || action == #selector(outlineContextMenuItemClicked_RemoveEntry) || action == #selector(outlineContextMenuItemClicked_Edit) || action == #selector(outlineContextMenuItemClicked_SetDestination) || action == #selector(outlineContextMenuItemClicked_Rename) || action == #selector(outlineContextMenuItemClicked_Promote) || action == #selector(outlineContextMenuItemClicked_Demote)) { if let data = self.listView.document?.isLocked, data { return false } if (self.isSearchOutlineMode) { if (action == #selector(outlineContextMenuItemClicked_AddEntry) || action == #selector(outlineContextMenuItemClicked_AddChildEntry) || action == #selector(outlineContextMenuItemClicked_AddAuntEntry) || action == #selector(outlineContextMenuItemClicked_Edit) || action == #selector(outlineContextMenuItemClicked_Rename) ) { return false } } if (self.tocOutlineView.selectedRowIndexes.count > 1) { if (menuItem.tag == KMOutlineViewMenuItemTag.remove.rawValue) { return true } return false } else if (self.tocOutlineView.selectedRowIndexes.count > 0) { if (action == #selector(outlineContextMenuItemClicked_AddChildEntry) || action == #selector(outlineContextMenuItemClicked_SetDestination)) { return true } } if (self.tocOutlineView.clickedRow == -1) { if (action == #selector(outlineContextMenuItemClicked_AddEntry)) { return true } else { return false } } else { let clickedOutline = self.tocOutlineView.item(atRow: self.tocOutlineView.clickedRow) as? CPDFOutline if let data = clickedOutline?.index, data > 0 { if (action == #selector(outlineContextMenuItemClicked_Demote)) { return true } } else { if (action == #selector(outlineContextMenuItemClicked_Demote)) { return false } } let parentOutLine = clickedOutline?.parent let grandparentOutLine = parentOutLine?.parent //if clicked PDFOutline 's parent exist if (grandparentOutLine != nil) { //and title is equla "add_AuntOutlineKey" if (action == #selector(outlineContextMenuItemClicked_AddAuntEntry)) { return true } else if (action == #selector(outlineContextMenuItemClicked_Promote)){ return true } } else { if (action == #selector(outlineContextMenuItemClicked_AddAuntEntry)) { return false }else if (action == #selector(outlineContextMenuItemClicked_Promote)){ return false } } } return true } // else // if ([menuItem action] == @selector(toggleEncryptFilePanel:)) { // [menuItem setTitle:NSLocalizedString(@"Set Passwords", @"Menu item title")]; // NSURL *fileURL = [self.pdfView.document documentURL]; // if (!fileURL) { // return YES; // } // PDFDocument *pdfDoc = [[[PDFDocument alloc] initWithURL:fileURL] autorelease]; // // if ([pdfDoc isLocked]) { // [menuItem setTitle:NSLocalizedString(@"Remove Security", @"Menu item title")]; // } // } else if (action == @selector(toggleToolbarShow:)) { // NSToolbar *toolbar = [self.window toolbar]; // if ([toolbar isVisible]) // [menuItem setTitle:NSLocalizedString(@"Hide Toolbar", @"Menu item title")]; // else // [menuItem setTitle:NSLocalizedString(@"Show Toolbar", @"Menu item title")]; // return YES; // } else if (action == @selector(readMode:)) { // menuItem.state = self.isReadMode ? NSControlStateValueOn : NSControlStateValueOff; // return YES; // } else if (action == @selector(addForm:)) { // return YES; else if action == #selector(toggleOutlineCaseInsensitiveSearch) { menuItem.state = self.outlineIgnoreCaseFlag ? .on : .off return true } // } else if (action == @selector(note_expandAllComments:) || // action == @selector(note_foldAllComments:) || // action == @selector(exportAnnotationNotes:) || // action == @selector(leftSideEmptyAnnotationClick_DeleteAnnotation:) || // action == @selector(removeAllAnnotations:)) { // if (@available(macOS 10.13, *)) { // if (notes.count == 0) { // return NO; // } else { // return YES; // } // } else { // if (action == @selector(note_expandAllComments:) || // action == @selector(note_foldAllComments:)) { // return NO; // } // } // } else if (action == #selector(unfoldNoteAction) || action == #selector(foldNoteAction)) { let row = self.noteOutlineView.clickedRow // NSArray *noteArr = [rightSideController.noteArrayController arrangedObjects]; // PDFAnnotation *foldNote = (PDFAnnotation *)noteArr[row]; // let foldNote = self.allAnnotations[row] let foldNote = self.fetchNote(for: row) // SKNPDFAnnotationNote if foldNote is CPDFMarkupAnnotation || foldNote is CPDFTextAnnotation { return true } else { return false } } else if (action == #selector(menuItemClick_ExportPNG) || action == #selector(menuItemClick_ExportJPG) || action == #selector(menuItemClick_ExportPDF)) { if (self.snapshotTableView.selectedRow == -1 ) { return false } else { return true } } // else if (action == @selector(editNoteFromTable:)) { // NSInteger row = [rightSideController.noteOutlineView clickedRow]; // NSArray * noteArr = [rightSideController.noteArrayController arrangedObjects]; // PDFAnnotation *foldNote = (PDFAnnotation *)noteArr[row]; // if (@available(macOS 10.13, *)) { // if ([foldNote.widgetFieldType isEqualToString:PDFAnnotationWidgetSubtypeSignature]) { // return NO; // } // } // if ([foldNote isKindOfClass:[PDFAnnotationStamp class]] || // [foldNote isKindOfClass:[KMAnnotationStamp class]]) { // return NO; // } else { // return YES; // } // } else if (action == #selector(menuItemClick_SelectAll)) { menuItem.state = self.snapshotListIsAllSelected() ? .on : .off return true } // else if (action == @selector(leftSideEmptyAnnotationClick_DeleteOutline:)) { // PDFOutline * item = [[pdfView document] outlineRoot]; // if (self.isSearchOutlineMode) { // NSInteger num = 0; // for (NSUInteger i = 0; i < [item numberOfChildren]; i++) { // PDFOutline *outline = [item childAtIndex:i]; // if ([self hasContainString:self.leftSideController.outlineSearchField.stringValue rootOutline:outline]) { // num ++; // } // } // if (num > 0) // return YES; // else // return NO; // } else { // if ([item numberOfChildren] > 0) // return YES; // else // return NO; // } // } return true } } // MARK: - NSPopoverDelegate extension KMLeftSideViewController: NSPopoverDelegate { func popoverWillClose(_ notification: Notification) { guard let popover = notification.object as? NSPopover else { return } if let vc = popover.contentViewController as? KMOutlineEditViewController { self.editOutlineUI(vc) self.tocOutlineView.reloadData() } } } // MARK: - NSSearchFieldDelegate 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 self.snapshotSearchField.isEqual(to: obj.object) { let searchString = self.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]; self.searchSnapshots.removeAll() if searchString.isEmpty { self.isSearchSnapshotMode = false self.searchSnapshots = self.snapshots.filter({ model in let data = model.windowC?.string.contains(searchString) ?? false return data }) } else { self.isSearchSnapshotMode = true } var snapshots = self.searchSnapshots if self.isSearchSnapshotMode == false { snapshots = self.snapshots } Task { @MainActor in self.updataLeftSideSnapView() self.snapshotTableView.reloadData() } if (snapshots.count > 0) { self.leftSideEmptyVC.outlineSearchView.removeFromSuperview() } else { let view = self.snapshotTableView.enclosingScrollView let 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 = [.minXMargin, .maxXMargin, .minYMargin, .maxYMargin] self.snapshotTableView.enclosingScrollView?.documentView?.addSubview(self.leftSideEmptyVC.outlineSearchView) } } } } // MARK: - NSTextFieldDelegate extension KMLeftSideViewController: NSTextFieldDelegate { func controlTextDidBeginEditing(_ obj: Notification) { if self.noteOutlineView.isEqual(to: obj.object) { // if (mwcFlags.isEditingTable == NO && mwcFlags.isEditingPDF == NO) // [[self document] objectDidBeginEditing:self]; // mwcFlags.isEditingTable = YES; } } func controlTextDidEndEditing(_ obj: Notification) { if self.noteOutlineView.isEqual(to: obj.object) { // if (mwcFlags.isEditingTable && mwcFlags.isEditingPDF == NO) // [[self document] objectDidEndEditing:self]; // mwcFlags.isEditingTable = NO; } else if let data = self.renamePDFOutlineTextField?.isEqual(to: obj.object), data { let textField = obj.object as! NSTextField if let editPDFOutline = self.renamePDFOutline { if self.isRenameNoteOutline == false { if textField.stringValue == editPDFOutline.label { return } } self.renamePDFOutline(editPDFOutline, label: textField.stringValue) self.updateSelectRowHeight() self.tocOutlineView.reloadData() } } } } // MARK: - Menu Item Actions extension KMLeftSideViewController { @objc func toggleCaseInsensitiveNoteSearch(_ sender: AnyObject?) { self.caseInsensitiveNoteSearch = !self.caseInsensitiveNoteSearch if self.searchField.stringValue.isEmpty == false { self.searchNotes(self.searchField) } KMDataManager.ud_set(self.caseInsensitiveNoteSearch, forKey: SKCaseInsensitiveNoteSearchKey) } @objc func searchNotes(_ sender: AnyObject?) { self.noteSearchMode = false if self.findState == .note { if self.noteSearchField.isEqual(to: sender) { self.noteSearchMode = true } self.updateNoteFilterPredicate() } else { self.updateSnapshotFilterPredicate() } let textfield = sender as? NSSearchField if let data = textfield?.stringValue.isEmpty, data == false { let findPboard = NSPasteboard(name: .find) findPboard.clearContents() // findPboard.writeObjects([textfield!.stringValue]) } } func updateSnapshotFilterPredicate() { let searchString = self.snapshotSearchField.stringValue self.searchSnapshots.removeAll() if self.findState == .snapshot && searchString.isEmpty == false { self.searchSnapshots = self.snapshots.filter({ model in let data = model.windowC?.string.contains(searchString) ?? false return data }) } Task { @MainActor in self.updataLeftSideSnapView() self.snapshotTableView.reloadData() } } func snapshotListIsAllSelected() -> Bool { if self.snapshots.isEmpty { return false } for model in self.snapshots { if model.isSelected == false { return false } } return true } }