123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811 |
- //
- // KMAnnotationViewController.swift
- // PDF Reader Pro
- //
- // Created by lxy on 2022/10/10.
- //
- import Cocoa
- enum KMAnnotationViewShowType: Int {
- case none
- case hidden
- }
- class KMAnnotationViewController: KMSideViewController {
- @IBOutlet weak var topView: NSView!
- @IBOutlet weak var filtrateButton: NSButton!
- @IBOutlet weak var moreButton: NSButton!
- @IBOutlet weak var markupTitleLabel: NSTextField!
- @IBOutlet weak var emptyView: NSView!
- @IBOutlet weak var bigTipLabel: NSTextField!
- @IBOutlet weak var tipLabel: NSTextField!
-
- @IBOutlet weak var annotationOutlineView: KMAnnotationOutlineView!
-
- var annotations: [KMBOTAAnnotationSection] = [] {
- didSet {
- self.annotationOutlineView.inputData = annotations
- self.updateExtempViewState()
- }
- }
- var screenAnnotations: [KMBOTAAnnotationSection] = [] {
- didSet {
- self.annotations = screenAnnotations
- }
- }
-
- //注释状态
- var annotationShowState: KMAnnotationViewShowType = .none {
- didSet {
- self.reloadData()
- }
- }
-
- var allAnnotations: [CPDFAnnotation] = []
-
- //localEvent
- var localEvent: Bool = false
-
-
- deinit {
- KMPrint("KMAnnotationViewController")
- self.removeNotification()
- }
- //MARK: View
-
- override func viewDidLoad() {
- super.viewDidLoad()
-
- self.setup()
- self.updateUI()
- self.updateLanguage()
- self.addNotification()
- self.reloadData()
- }
-
- func setup() {
- self.view.wantsLayer = true
- self.view.layer?.backgroundColor = NSColor.km_init(hex: "#F7F8FA").cgColor
-
- self.emptyView.backgroundColor(NSColor.km_init(hex: "#F7F8FA"))
-
- self.topView.wantsLayer = true
- self.topView.layer?.backgroundColor = NSColor.clear.cgColor
-
- self.annotationOutlineView.outlineView.doubleAction = #selector(tableViewDoubleAction)
- self.annotationOutlineView.delegate = self
- }
-
- func updateUI() {
- self.markupTitleLabel.font = NSFont.SFProTextSemiboldFont(14.0)
- self.markupTitleLabel.textColor = NSColor.km_init(hex: "#252629")
-
- self.bigTipLabel.font = NSFont.SFProTextRegularFont(14.0)
- self.bigTipLabel.textColor = NSColor.km_init(hex: "#616469")
-
- if self.annotationShowState == .none {
-
- } else {
- self.bigTipLabel.font = NSFont.SFProTextRegularFont(12.0)
- self.bigTipLabel.textColor = NSColor.km_init(hex: "#94989C")
- }
- }
-
- func updateLanguage() {
- self.markupTitleLabel.stringValue = NSLocalizedString("Annotation", comment: "")
-
- self.filtrateButton.toolTip = NSLocalizedString("Sort", comment: "")
- self.moreButton.toolTip = NSLocalizedString("More", comment: "")
-
- if self.annotationShowState == .none {
- self.bigTipLabel.stringValue = NSLocalizedString("No Annotations", comment: "")
-
- let title = NSLocalizedString("All annotations will be displayed here.", comment: "")
- let paragraphStyle = NSMutableParagraphStyle()
- paragraphStyle.lineHeightMultiple = 1.32
- paragraphStyle.alignment = .center
- self.tipLabel.attributedStringValue = NSMutableAttributedString(string: title, attributes: [NSAttributedString.Key.paragraphStyle: paragraphStyle, .foregroundColor : NSColor.km_init(hex: "#94989C"), NSAttributedString.Key.font: NSFont.SFProTextRegularFont(12)])
- } else {
- self.bigTipLabel.stringValue = NSLocalizedString("The Annotations are hidden", comment: "")
- self.tipLabel.stringValue = ""
- }
- }
-
- func addNotification() {
- NotificationCenter.default.addObserver(self, selector: #selector(documentPageCountChangedNotification), name: NSNotification.Name.init(rawValue: "CPDFDocumentPageCountChangedNotification"), object: nil)
- NotificationCenter.default.addObserver(self, selector: #selector(CPDFListViewActiveAnnotationsChangeNotification), name: NSNotification.Name.init(rawValue: "CPDFListViewActiveAnnotationsChangeNotification"), object: nil)
- NotificationCenter.default.addObserver(self, selector: #selector(CPDFListViewAnnotationsAttributeHasChangeNotification), name: NSNotification.Name.init(rawValue: "CPDFListViewAnnotationsAttributeHasChangeNotification"), object: nil)
- NotificationCenter.default.addObserver(self, selector: #selector(reloadDataAfter), name: NSNotification.Name.init(rawValue: "CPDFPageDidAddAnnotationNotification"), object: nil)
- NotificationCenter.default.addObserver(self, selector: #selector(reloadDataAfter), name: NSNotification.Name.init(rawValue: "CPDFPageDidRemoveAnnotationNotification"), object: nil)
- }
-
- func removeNotification() {
- NotificationCenter.default.removeObserver(self)
- }
-
- public func clear() {
- self.annotations.removeAll()
- self.annotationOutlineView.reloadData()
- }
- }
- //MARK: Data
- extension KMAnnotationViewController {
- @objc public func reloadData() {
- // self.reloadAnnotation()
- // self.annotationSort(sortArray: [])
- }
-
- func reloadAnnotation() {
- if self.listView != nil {
- var dataArray: [KMBOTAAnnotationSection] = []
- var annotationArray: [CPDFAnnotation] = []
- for i in 0 ..< self.pageCount() {
- var annotationItemArray: [KMBOTAAnnotationItem] = []
- let page = self.pdfDocument()?.page(at: UInt(i))
- let types = ["Highlight","Underline","Strikeout","Freehand","FreeText","Note","Square","Circle","Line","Stamp","Arrow","Image","Redact","Sign"]
- var pageAnnotations: [CPDFAnnotation] = KMOCToolClass.filterAnnotation(annotations: page!.annotations,types: types) as! [CPDFAnnotation]
- //添加签名注释
- for annotation in page!.annotations {
- if annotation.isKind(of: CPDFSignatureAnnotation.self) {
- pageAnnotations.append(annotation)
- }
- }
-
- for annotation in pageAnnotations {
- if annotation.annotationShouldDisplay() == false {
- pageAnnotations.removeObject(annotation)
- }
- }
- //转换所有annotation类型
- let section = KMBOTAAnnotationSection()
- for annotation in pageAnnotations {
- let item = KMBOTAAnnotationItem()
- item.section = section
- item.annotation = annotation
- item.index = Int(annotation.page.pageIndex())
- annotationItemArray.append(item)
- }
-
- if annotationItemArray.count != 0 {
- section.annotations = annotationItemArray
- section.page = page
- section.isItemExpanded = true
- dataArray.append(section)
- }
-
- //添加所有annotation 用于筛选
- annotationArray += pageAnnotations
- }
-
- //转换对象,用于数据显示
- self.annotations = dataArray
- self.allAnnotations = annotationArray
-
- if self.annotations.count < 1 {
- self.filtrateButton.isEnabled = false
- } else {
- self.filtrateButton.isEnabled = true
- }
- }
- }
-
- func annotationSort(sortArray:[[Any]]) {
- if self.listView != nil {
- var typeArr: [Any] = []
- var colorArr: [Any] = []
- var authorArr: [Any] = []
-
- let sud = UserDefaults.standard
- let typeData = sud.object(forKey: "KMNoteOutlineFilterSelectArray_Type" + (self.pdfDocument()?.documentURL.path ?? "")) as? Data
- if typeData != nil {
- typeArr = NSKeyedUnarchiver.unarchiveObject(with: typeData!) as! [Any]
- }
-
- let colorData = sud.object(forKey: "KMNoteOutlineFilterSelectArray_Color" + (self.pdfDocument()?.documentURL.path ?? "")) as? Data
- if colorData != nil {
- colorArr = NSKeyedUnarchiver.unarchiveObject(with: colorData!) as! [Any]
- }
-
- let authorData = sud.object(forKey: "KMNoteOutlineFilterSelectArray_Author" + (self.pdfDocument()?.documentURL.path ?? "")) as? Data
- if authorData != nil {
- authorArr = NSKeyedUnarchiver.unarchiveObject(with: authorData!) as! [Any]
- }
-
- if typeArr.count == 0 && colorArr.count == 0 && authorArr.count == 0 {
- self.filtrateButton.image = NSImage(named: "KMImageNameAnnotationsFiltrate")
- self.reloadAnnotation()
- } else {
- self.filtrateButton.image = NSImage(named: "icon_annotation_screening_select")
- var dataArray: [KMBOTAAnnotationSection] = []
- for i in 0 ..< self.pageCount() {
- var annotationItemArray: [KMBOTAAnnotationItem] = []
- let page = self.listView?.document?.page(at: UInt(i))
- if page!.annotations.count > 0 {
- var filterAnnotations: [CPDFAnnotation] = page!.annotations
- if typeArr.count > 0 {
- filterAnnotations = (KMOCToolClass.filterAnnotation(annotations: filterAnnotations, types: typeArr) as! [CPDFAnnotation])
- }
- if (colorArr.count > 0) {
- filterAnnotations = (KMOCToolClass.filterAnnotation(annotations: filterAnnotations,colors: colorArr) as! [CPDFAnnotation])
- }
- if (authorArr.count > 0) {
- filterAnnotations = (KMOCToolClass.filterAnnotation(annotations: filterAnnotations,authors: authorArr) as! [CPDFAnnotation])
- }
-
- let section = KMBOTAAnnotationSection()
- for annotation in filterAnnotations {
- let item = KMBOTAAnnotationItem()
- item.section = section
- item.annotation = annotation
- item.index = Int(page!.pageIndex())
- annotationItemArray.append(item)
- }
-
- if annotationItemArray.count != 0 {
- section.annotations = annotationItemArray
- section.page = page
- section.isItemExpanded = true
- dataArray.append(section)
- }
- }
- }
-
- self.annotations = dataArray
- }
- }
- }
- }
- //MARK: reloadData
- extension KMAnnotationViewController {
- func updateExtempViewState() {
- if self.emptyView != nil {
- var hidden = false
- if self.annotationOutlineView.outlineView.numberOfRows != 0 {
- hidden = true
- }
- self.emptyView.isHidden = hidden
- self.annotationOutlineView.isHidden = !hidden
- //刷新
- self.updateUI()
- self.updateLanguage()
- }
- }
- }
- //MARK: Notification
- extension KMAnnotationViewController {
- @objc public func reloadDataAfter() {
- if !localEvent {
- let rect = self.annotationOutlineView.outlineView.visibleRect
- self.reloadData()
- self.annotationOutlineView.outlineView.scrollToVisible(rect)
- }
- // localEvent = false
- }
- @objc func documentPageCountChangedNotification(notification: NSNotification) {
- if notification.object is CPDFDocument {
- let pdfdocument : CPDFDocument = notification.object as! CPDFDocument
- if pdfdocument.isEqual(self.listView?.document) {
- if !localEvent {
- self.reloadData()
- }
- // localEvent = false
- }
- }
- }
- @objc func CPDFListViewActiveAnnotationsChangeNotification(notification: NSNotification) {
- if notification.object is CPDFListView {
- let listView : CPDFListView = notification.object as! CPDFListView
- if listView.isEqual(self.listView) {
- if self.listView?.activeAnnotations.count == 0 {
- self.escButtonAction(Any.self)
- } else {
- if !localEvent {
- let tempAnnotations : [CPDFAnnotation] = self.listView?.activeAnnotations as! [CPDFAnnotation]
- var indexset = IndexSet()
- for annotation in tempAnnotations {
- if self.annotations.count > 0 {
- for section in self.annotations {
- for item in section.annotations! {
- if item.annotation == annotation {
- let index = self.annotationOutlineView.outlineView.row(forItem: item)
- indexset.insert(index)
- }
- }
- }
- }
- }
- if indexset.count != 0 && indexset.first != -1 {
- self.annotationOutlineView.outlineView.selectRowIndexes(indexset, byExtendingSelection: false)
- self.annotationOutlineView.didSelectItem(view: nil, event: NSEvent(), isNeedDelegate: false)
- }
- }
- // localEvent = false
- }
- }
- }
- }
- @objc func CPDFListViewAnnotationsAttributeHasChangeNotification(notification: NSNotification) {
- if notification.object != nil {
- let dic = notification.object as? NSDictionary
- if dic?["keyPath"] as! String != CPDFAnnotationBoundsKey &&
- dic?["keyPath"] as! String != CPDFAnnotationStartPointKey &&
- dic?["keyPath"] as! String != CPDFAnnotationEndPointKey{
- if dic?["object"] is CPDFAnnotation {
- let annotation : CPDFAnnotation = dic?["object"] as? CPDFAnnotation ?? CPDFAnnotation()
- for section in self.annotations {
- for (_, item) in section.annotations!.enumerated() {
- if item.annotation == annotation {
- let row = self.annotationOutlineView.outlineView.row(forItem: item)
- let indexSet = IndexSet.init(integer: row)
- self.annotationOutlineView.outlineView.noteHeightOfRows(withIndexesChanged: indexSet)
- self.annotationOutlineView.outlineView.reloadItem(item)
- break
- }
- }
- }
- }
- }
- }
- }
- }
- //MARK: Action
- extension KMAnnotationViewController {
- @IBAction func tableViewDoubleAction(_ sender: Any) {
- if self.annotationOutlineView.selectItems.count > 1 {
- return
- }
- let selectedRow = self.annotationOutlineView.outlineView.selectedRow
- if selectedRow >= 0 {
- let annotationItem = self.annotationOutlineView.outlineView.item(atRow: selectedRow)
- if (annotationItem is KMBOTAAnnotationItem) {
- let annotation = (annotationItem as! KMBOTAAnnotationItem).annotation
- self.listView?.go(to: annotation!.bounds, on: annotation!.page, animated: true)
- }
- }
- }
- @IBAction func moreButtonAction(_ sender: NSButton) {
- self.addMoreMenu(sender: sender)
- }
- @IBAction func filtrateButtonAction(_ sender: NSButton) {
- let menu = NSMenu()
- let annotationScreenView = KMAnnotationScreenCollectionView(frame: CGRect(x: 0, y: 0, width: 304, height: 296))
- annotationScreenView.path = self.listView?.document.documentURL.path ?? ""
- annotationScreenView.annotations = self.allAnnotations
- annotationScreenView.applyAction = { [unowned self] (view, typeArray, colorArray, authArray) in
- menu.cancelTracking()
- self.annotationSort(sortArray: [typeArray, colorArray, authArray])
- }
-
- annotationScreenView.cancelAction = { [unowned self] view in
- menu.cancelTracking()
- }
-
- let item = menu.addItem(withTitle: "", action: nil, keyEquivalent: "")
- item.target = self
- // item.representedObject = filterVC
- item.view = annotationScreenView
- menu.popUp(positioning: nil, at: CGPoint(x: -130, y: 30), in: sender)
- }
- @IBAction func deleteButtonAction(_ sender: Any) {
- let alert = NSAlert()
- alert.alertStyle = .critical
- alert.messageText = NSLocalizedString("This will permanently remove all annotations. Are you sure to continue?", comment: "")
- alert.informativeText = NSLocalizedString("You cannot undo this operation.", comment: "")
- alert.addButton(withTitle: NSLocalizedString("Yes", comment: ""))
- alert.addButton(withTitle: NSLocalizedString("No", comment: ""))
- alert.beginSheetModal(for: self.view.window!, completionHandler: { result in
- if result == .OK {
- for i in 0 ..< self.pageCount() {
- let page = self.listView?.document?.page(at: UInt(i))
- page?.removeAllAnnotations()
- }
- // let undoManager : UndoManager = self.mainWindowController.document?.undoManager ?? UndoManager()
- // undoManager.setActionName("")
- self.listView?.updateActiveAnnotations([CPDFAnnotation()])
- self.listView?.setNeedsDisplayForVisiblePages()
- self.reloadData()
- }
- })
- }
- //
- @IBAction func flattenButtonAction(_ sender: NSMenuItem) {
- let selects = sender.representedObject as! NSIndexSet
- var indexs : [Int] = []
- for index in selects {
- indexs.append(index)
- }
- if selects.count == 1 {
- let index = selects.firstIndex
- let annotationItem: KMBOTAAnnotationItem = self.annotationOutlineView.outlineView.item(atRow: index) as! KMBOTAAnnotationItem
- if annotationItem.annotation != nil {
- if annotationItem.annotation!.contents?.lengthOfBytes(using: String.Encoding(rawValue: String.Encoding.utf16.rawValue)) ?? 0 > 0 {
- var content: String = annotationItem.annotation!.contents!
- let item: CPDFMarkupAnnotation = annotationItem.annotation! as? CPDFMarkupAnnotation ?? CPDFMarkupAnnotation()
- if item.markupText() != nil {
- KMPrint(item.markupText() as Any)
- content = content + "\n" + item.markupText()
- }
- let pasteBoard = NSPasteboard.general
- pasteBoard.clearContents()
- pasteBoard.setString(content, forType: .string)
- }
- }
- }
- }
- //
- @IBAction func exportItemAction(_ sender: Any) {
- let panel = NSSavePanel()
- panel.nameFieldStringValue = "\(NSLocalizedString("Untitled", comment: "")).xfdf"
- panel.isExtensionHidden = true
- let response = panel.runModal()
- if response == .OK {
- let url = panel.url
- let result = self.listView?.document.exportAnnotation(toXFDFPath: url!.path) ?? false
- if result {
- // NSWorkspace.shared.openFile(url!.path.deletingLastPathComponent)
- // NSWorkspace.shared.open(url!)
-
- let filePath = url!.path // 要打开的文件路径
- let fileURL = URL(fileURLWithPath: filePath)
- let fileDirectoryURL = fileURL.deletingLastPathComponent() // 获取文件所在的文件夹路径
- NSWorkspace.shared.activateFileViewerSelecting([fileDirectoryURL])
- }
- }
- }
- //
- @IBAction func importItemAction(_ sender: Any) {
- let panel = NSOpenPanel()
- panel.allowsMultipleSelection = false
- panel.allowedFileTypes = ["xfdf"]
- panel.beginSheetModal(for: NSApp.mainWindow!) { response in
- if response == .OK {
- let openPath = panel.url?.path
- let result = self.listView?.document.importAnnotation(fromXFDFPath: openPath!) ?? false
- if result {
- self.listView?.setNeedsDisplayAnnotationViewForVisiblePages()
- self.reloadData()
- }
- }
- }
- }
- //
- @IBAction func deleteItemAction(_ sender: NSMenuItem) {
- let selects = sender.representedObject as! NSIndexSet
- var indexs : [KMBOTAAnnotationItem] = []
- for index in selects {
- if self.annotationOutlineView.outlineView.item(atRow: index) is KMBOTAAnnotationItem {
- let annotationItem: KMBOTAAnnotationItem = self.annotationOutlineView.outlineView.item(atRow: index) as! KMBOTAAnnotationItem
- annotationItem.index = index
- indexs.append(annotationItem)
- }
- }
- indexs.sort(){$0.index! > $1.index!}
- self.deleteAnnotations(annotationItems: indexs)
- }
- //
- @IBAction func deleteAllAnonationAction(_ sender: NSMenuItem) {
- let alter = NSAlert()
- alter.alertStyle = NSAlert.Style.informational
- alter.messageText = NSLocalizedString("This will permanently remove all annotations. Are you sure to continue?", comment: "")
- alter.addButton(withTitle: NSLocalizedString("Yes", comment:""))
- alter.addButton(withTitle: NSLocalizedString("No", comment:""))
- let modlres = alter.runModal()
- if modlres == NSApplication.ModalResponse.alertFirstButtonReturn {
- // for i in 0 ..< self.listView.document.pageCount {
- // let page = self.listView.document.page(at: i)
- // for annotation in page!.annotations {
- // page?.removeAnnotation(annotation)
- //
- // }
- // }
- // self.listView.setNeedsDisplayForVisiblePages()
- // self.reloadData()
- var indexs : [KMBOTAAnnotationItem] = []
- for section in self.annotations {
- indexs.append(contentsOf: section.annotations!)
- }
- indexs.sort(){$0.index! > $1.index!}
- self.deleteAnnotations(annotationItems: indexs)
- }
- }
- //
- @IBAction func escButtonAction(_ sender: Any) {
- self.cancelSelect()
- }
- //
- func cancelSelect() {
- self.annotationOutlineView.cancelSelect()
- }
- //
- func selectItem(index: Int) {
- self.annotationOutlineView.outlineView.selectRowIndexes(IndexSet(integer: index), byExtendingSelection: false)
- self.annotationOutlineView.didSelectItem(view: nil, event: NSEvent(), isNeedDelegate: false)
- }
- func updateListViewData(annotationItems: [KMBOTAAnnotationItem]) {
- if annotationItems.count > 0 {
- if annotationItems.count == 1 {
- let annotationItem = annotationItems.first!
- if annotationItem.annotation != nil {
- self.listView?.go(to: annotationItem.annotation!.bounds, on: annotationItem.annotation!.page, animated: true)
- }
- }
-
- var annotations: [CPDFAnnotation] = []
- for item in annotationItems {
- if item.annotation != nil {
- annotations.append(item.annotation!)
- }
- }
- self.listView?.updateActiveAnnotations(annotations)
- self.listView?.setNeedsDisplayAnnotationViewForVisiblePages()
- }
- }
- }
- extension KMAnnotationViewController: KMAnnotationOutlineViewDelegate {
- func annotationOutlineView(_ outlineView: KMAnnotationOutlineView, rightMouseDownDidSelectView: NSView, evnet: NSEvent) {
- self.addRightMenuItem(view: rightMouseDownDidSelectView, event: evnet)
- }
-
- func annotationOutlineView(_ outlineView: KMAnnotationOutlineView, didReloadData: KMBOTAOutlineItem) {
-
- }
-
- func annotationOutlineView(_ outlineView: KMAnnotationOutlineView, didSelectItem: [KMBOTAAnnotationItem]) {
- self.localEvent = true
- self.updateListViewData(annotationItems: didSelectItem)
- self.localEvent = false
- }
- }
- //MARK: Menu
- extension KMAnnotationViewController : NSMenuDelegate, NSMenuItemValidation {
- @objc private func expandAllComments(sender:NSMenuItem) {
- self.annotationOutlineView.expandAllComments(item: sender)
- }
-
- @objc private func collapseAllComments(sender:NSMenuItem) {
- self.annotationOutlineView.collapseAllComments(item: sender)
- }
-
- // @objc private func expandAllComments(sender:NSMenuItem) {
- // if sender.tag == 0 {
- // self.annotationOutlineView.expandAllComments(item: sender)
- // } else if sender.tag == 1 {
- // self.annotationOutlineView.collapseAllComments(item: sender)
- // } else if sender.tag == 2 {
- // let alter = NSAlert()
- // alter.alertStyle = NSAlert.Style.informational
- // alter.messageText = NSLocalizedString("This will permanently remove all outlines. Are you sure to continue?", comment: "")
- // alter.addButton(withTitle: NSLocalizedString("Yes", comment:""))
- // alter.addButton(withTitle: NSLocalizedString("No", comment:""))
- // let modlres = alter.runModal()
- // if modlres == NSApplication.ModalResponse.alertFirstButtonReturn {
- // self.deleteAllAnonationAction(sender)
- // }
- // }
- // }
- func addRightMenuItem(view: NSView, event: NSEvent) {
- let menu = NSMenu()
- menu.delegate = self
- let selectedRowIndexes = self.annotationOutlineView.outlineView.selectedRowIndexes
- var menuItem = NSMenuItem()
- if selectedRowIndexes.count == 1 {
- let item: KMBOTAAnnotationItem = self.annotationOutlineView.outlineView.item(atRow: selectedRowIndexes.first!) as! KMBOTAAnnotationItem
- if item.annotation != nil {
- if item.annotation!.contents != nil {
- if item.annotation!.contents.count > 0 {
- menuItem = menu.addItem(withTitle: NSLocalizedString("Copy Text", comment: ""), action: #selector(flattenButtonAction), target: self)!
- menuItem.representedObject = selectedRowIndexes
- menu.addItem(NSMenuItem.separator())
- }
- }
- }
- }
- menuItem = menu.addItem(withTitle: NSLocalizedString("Export Annotation", comment: ""), action: #selector(exportItemAction), target: self)!
- if self.annotationOutlineView.selectItems.count == 1 {
- menuItem = menu.addItem(withTitle: NSLocalizedString("Import Annotation", comment: ""), action: #selector(importItemAction), target: self)!
- }
- menu.addItem(NSMenuItem.separator())
- menuItem = menu.addItem(withTitle: NSLocalizedString("Delete", comment: ""), action: #selector(deleteItemAction), target: self)!
- menuItem.representedObject = selectedRowIndexes
- menu.addItem(NSMenuItem.separator())
-
- let point = view.convert(event.locationInWindow, from: nil)
- menu.popUp(positioning: nil, at: point, in: view)
- }
-
- func addMoreMenu(sender: NSView) {
- let moreMenu = NSMenu()
- _ = moreMenu.addItem(withTitle: NSLocalizedString("Expand All", comment: ""), action: #selector(expandAllComments), target: self, tag: 0)
- _ = moreMenu.addItem(withTitle: NSLocalizedString("Collapse All", comment: ""), action: #selector(collapseAllComments), target: self, tag: 1)
- // let soreItem = moreMenu.addItem(withTitle: NSLocalizedString("Sort", comment: ""), action: nil, target: self)
- // let soreMenu = NSMenu()
- // soreMenu.addItem(withTitle: NSLocalizedString("Page", comment: ""), action: #selector(expandAllComments), target: self, tag: 0)
- // soreMenu.addItem(withTitle: NSLocalizedString("Chronologically - ascending", comment: ""), action: #selector(expandAllComments), target: self, tag: 1)
- // soreMenu.addItem(withTitle: NSLocalizedString("Chronologically - reverse", comment: ""), action: #selector(expandAllComments), target: self, tag: 0)
- // soreItem?.submenu = soreMenu
- _ = moreMenu.addItem(withTitle: NSLocalizedString("Import Annotations", comment: ""), action: #selector(importItemAction), target: self)
- _ = moreMenu.addItem(withTitle: NSLocalizedString("Export Annotations to XFDF", comment: ""), action: #selector(exportItemAction), target: self)
- _ = moreMenu.addItem(withTitle: NSLocalizedString("Remove All Annotations", comment: ""), action: #selector(deleteAllAnonationAction), target: self)
- let rect = sender.convert(sender.bounds, to: self.view)
- moreMenu.popUp(positioning: nil, at: NSPoint(x: rect.origin.x, y: rect.origin.y-10), in: self.view)
- }
-
- func validateMenuItem(_ menuItem: NSMenuItem) -> Bool {
- let action = menuItem.action
- if (action == #selector(undo)) {
- return self.listView?.undoManager?.canUndo ?? false
- }
- if (action == #selector(redo)) {
- return self.listView?.undoManager?.canRedo ?? false
- }
- if (action == #selector(flattenButtonAction)) {
- if self.annotationOutlineView.selectItems.count != 1 {
- return false
- }
- }
- if (action == #selector(deleteAllAnonationAction)) {
- if self.annotations.count == 0 {
- return false
- }
- }
-
- if action == #selector(exportItemAction) {
- if self.annotations.count == 0 {
- return false
- }
- }
-
- if action == #selector(exportItemAction) {
- if self.annotations.count == 0 {
- return false
- }
- }
-
- if (action == #selector(expandAllComments)) {
- var canExpand = false
- for row in 0..<self.annotationOutlineView.outlineView.numberOfRows {
- // 检查当前项目是否可以展开
- let item = self.annotationOutlineView.outlineView.item(atRow: row)
- if self.annotationOutlineView.outlineView.isExpandable(item) {
- if !self.annotationOutlineView.outlineView.isItemExpanded(item) {
- canExpand = true
- break
- }
- }
- }
- return canExpand
- }
-
- if (action == #selector(collapseAllComments)) {
- var canCollapse = false
- for row in 0..<self.annotationOutlineView.outlineView.numberOfRows {
- let item = self.annotationOutlineView.outlineView.item(atRow: row)
- if self.annotationOutlineView.outlineView.isExpandable(item) {
- if self.annotationOutlineView.outlineView.isItemExpanded(item) {
- canCollapse = true
- break
- }
- }
- }
- return canCollapse
- }
-
- return true
- }
- }
- //MARK: undo Redo
- extension KMAnnotationViewController {
- func deleteAnnotations(annotationItems: [KMBOTAAnnotationItem]) {
- self.removeNotification()
- self.localEvent = true
-
- var removeAnnotations: [Any] = []
- var tempAnnotations: [KMBOTAAnnotationItem] = []
- for annotationItem in annotationItems {
- let annotation = annotationItem.annotation
- annotationItem.index = annotationItem.section?.annotations?.firstIndex(of: annotationItem)
- let page = annotation?.page
- if ((page?.annotations.contains(annotation!)) != nil) {
- page?.removeAnnotation(annotation)
- annotationItem.section?.annotations?.removeObject(annotationItem)
- } else {
- KMPrint("不存在")
- }
-
- if let data = self.listView?.activeAnnotations.contains(annotation!), data {
- removeAnnotations.append(annotation!)
- }
-
- if annotation != nil {
- tempAnnotations.append(annotationItem)
- }
- }
-
- if removeAnnotations.count != 0 {
- self.listView?.activeAnnotations.remove(removeAnnotations)
- }
- self.listView?.setNeedsDisplayForVisiblePages()
-
- self.annotationOutlineView.reloadData(expandItemType: .none)
- self.updateExtempViewState()
- self.listView?.undoManager?.registerUndo(withTarget: self) { [unowned self] targetType in
- self.addAnnotations(annotationItems: tempAnnotations)
- }
-
- self.addNotification()
- self.localEvent = false
- }
-
- func addAnnotations(annotationItems: [KMBOTAAnnotationItem]) {
- self.removeNotification()
- self.localEvent = true
-
- var tempAnnotationItems: [KMBOTAAnnotationItem] = annotationItems
- tempAnnotationItems.sort(){$0.index ?? 0 < $1.index ?? 0}
-
- for annotationItem in tempAnnotationItems {
- if !annotationItem.annotation!.page.annotations.contains(annotationItem.annotation!) {
- annotationItem.annotation?.page.addAnnotation(annotationItem.annotation!)
- annotationItem.section?.annotations?.insert(annotationItem, at: annotationItem.index ?? 0)
- }
- }
-
- self.listView?.setNeedsDisplayForVisiblePages()
- self.annotationOutlineView.reloadData(expandItemType: .none)
-
- if tempAnnotationItems.count != 0 {
- let row = self.annotationOutlineView.outlineView.row(forItem: tempAnnotationItems.last)
- self.annotationOutlineView.outlineView.scrollRowToVisible(row)
- }
-
- self.updateExtempViewState()
-
- let tempAnnotations: [KMBOTAAnnotationItem] = tempAnnotationItems
- self.listView?.undoManager?.registerUndo(withTarget: self) { [unowned self] targetType in
- self.deleteAnnotations(annotationItems: tempAnnotations)
- }
-
- self.addNotification()
- self.localEvent = false
- }
-
- @IBAction func undo(_ sender: Any) {
- if (self.listView?.undoManager?.canUndo ?? false) {
- self.listView?.undoManager?.undo()
- }
- }
-
- @IBAction func redo(_ sender: Any) {
- if (self.listView?.undoManager?.canRedo ?? false) {
- self.listView?.undoManager?.redo()
- }
- }
- }
|