123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807 |
- //
- // KMOutlineViewController.swift
- // PDF Office
- //
- // Created by lxy on 2022/10/10.
- //
- import Cocoa
- class KMOutlineViewController: NSViewController,NSMenuItemValidation {
-
- @IBOutlet var contendView: NSView!
- @IBOutlet weak var outlineView: NSOutlineView!
-
- @IBOutlet weak var topView: NSView!
- @IBOutlet weak var titleLabel: NSTextField!
-
- @IBOutlet weak var addButton: NSButton!
- @IBOutlet weak var moreButton: NSButton!
- @IBOutlet var topSepline: NSView!
-
- @IBOutlet weak var emptyView: NSView!
- @IBOutlet weak var bigTipLabel: NSTextField!
- @IBOutlet weak var tipLabel: NSTextField!
-
- var dragPDFOutline : CPDFOutline!
- var renameTextField : NSTextField!
- var listView : CPDFListView!
- var renamePDFOutline : CPDFOutline!
- let moreMenu = NSMenu()
-
- func dealloc() {
-
- NotificationCenter.default.removeObserver(self)
- }
-
- override func viewDidLoad() {
- super.viewDidLoad()
-
- self.emptyView.wantsLayer = true
- // self.emptyView.layer?.backgroundColor = NSColor.red.cgColor
-
- self.outlineView.registerForDraggedTypes([NSPasteboard.PasteboardType(rawValue: "kKMPDFViewOutlineDragDataType")])
- self.outlineView.doubleAction = #selector(outlineViewDoubleAction)
- self.outlineView.target = self
- self.outlineView.allowsMultipleSelection = true
- self.outlineView.selectionHighlightStyle = NSTableView.SelectionHighlightStyle.none;
-
- self.addOutlineMenu()
- self.titleLabel.stringValue = NSLocalizedString("Outline", comment: "")
- self.topView.wantsLayer = true
- // self.topView.layer?.backgroundColor = NSColor.cl.cgColor
- // self.outlineView.backgroundColor = NSColor.white
-
- self.refreshUI()
-
- self.initNotification()
-
- }
-
- func refreshUI() {
- self.contendView.wantsLayer = true
- self.contendView.layer?.backgroundColor = NSColor(hex: "#F7F8FA").cgColor
-
- self.topSepline.wantsLayer = true
- self.topSepline.layer?.backgroundColor = NSColor(red: 0, green: 0, blue: 0, alpha: 0.1).cgColor
-
- self.titleLabel.textColor = NSColor(hex: "#252629")
-
- self.bigTipLabel.font = NSFont.SFProTextRegular(14.0)
- self.bigTipLabel.textColor = NSColor(hex: "#616469")
- self.bigTipLabel.stringValue = NSLocalizedString("No Outlines", comment: "")
-
-
- let title = NSLocalizedString("To create an outline, please right-click on the selected page and choose \"Add Outline\", or click \"Add\" in the upper right corner.", comment: "")
- let paragraphStyle = NSMutableParagraphStyle()
- paragraphStyle.lineHeightMultiple = 1.32
- paragraphStyle.alignment = .center
- self.tipLabel.attributedStringValue = NSMutableAttributedString(string: title, attributes: [NSAttributedString.Key.paragraphStyle: paragraphStyle, .foregroundColor : NSColor(hex: "#94989C")])
-
-
- self.addButton.toolTip = NSLocalizedString("Add Outline", comment: "")
- self.moreButton.toolTip = NSLocalizedString("More", comment: "")
-
- }
-
- private func addOutlineMenu(){
- let menus : NSMenu = NSMenu(title: "")
- let addItem = self.menuItemWithTitle(title: NSLocalizedString("Add Item", comment: ""), action: #selector(addItemAction))
- let addChildItem = self.menuItemWithTitle(title: NSLocalizedString("Add Sub-Item", comment: ""), action: #selector(addChildItemAction))
- let addHigherItem = self.menuItemWithTitle(title: NSLocalizedString("Add A Higher Level", comment: ""), action: #selector(addHigherItemAction))
- let deleteItem = self.menuItemWithTitle(title: NSLocalizedString("Delete", comment: ""), action: #selector(deleteItemAction))
- // let editItem = self.menuItemWithTitle(title: NSLocalizedString("Edit", comment: ""), action: #selector(editItemAction))
- let renameItem = self.menuItemWithTitle(title: NSLocalizedString("Rename", comment: ""), action: #selector(renameItemAction))
- let changeItem = self.menuItemWithTitle(title: NSLocalizedString("Change Destination", comment: ""), action: #selector(changeItemAction))
- let promoteItem = self.menuItemWithTitle(title: NSLocalizedString("Promote", comment: ""), action: #selector(promoteItemAction))
- let demoteItem = self.menuItemWithTitle(title: NSLocalizedString("Demote", comment: ""), action: #selector(demoteItemAction))
- menus.addItem(addItem)
- menus.addItem(addChildItem)
- menus.addItem(addHigherItem)
- menus.addItem(NSMenuItem.separator())
- menus.addItem(deleteItem)
- menus.addItem(NSMenuItem.separator())
- // menus.addItem(editItem)
- menus.addItem(renameItem)
- menus.addItem(changeItem)
- menus.addItem(NSMenuItem.separator())
- menus.addItem(promoteItem)
- menus.addItem(demoteItem)
- self.outlineView.menu = menus
-
- moreMenu.addItem(withTitle: NSLocalizedString("Expand All", comment: ""), action: #selector(toc_expandAllComments), target: self, tag: 0)
- moreMenu.addItem(withTitle: NSLocalizedString("Collapse All", comment: ""), action: #selector(toc_expandAllComments), target: self, tag: 1)
- moreMenu.addItem(withTitle: NSLocalizedString("Remove All Outlines", comment: ""), action: #selector(toc_expandAllComments), target: self, tag: 2)
- }
-
- func initNotification() {
- NotificationCenter.default.addObserver(self, selector: #selector(KMPDFViewCurrentPageDidChangedNotification), name: NSNotification.Name.init(rawValue: "KMPDFViewCurrentPageDidChanged"), object: nil)
-
-
- }
- //MARK: Public Method
- @objc func outlineViewDoubleAction() {
- if(self.outlineView.clickedRow >= 0) {
- self.renameItemAction()
- } else {
- __NSBeep()
- }
- }
-
- @IBAction func addNewOutline(_ sender: Any) {
- self.addItemAction()
- }
-
- @IBAction func moreButton_click(_ sender: NSButton) {
- 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)
- }
-
-
- @IBAction func escButtonAction(_ sender: Any) {
- self.outlineView.deselectAll(nil)
- }
-
- /// 右键菜单
-
- @objc private func toc_expandAllComments(item:NSMenuItem) {
- if item.tag == 0 {
- self.outlineView.reloadData()
- self.outlineView.expandItem(nil, expandChildren: true)
- } else if item.tag == 1 {
- self.outlineView.reloadData()
- self.outlineView.collapseItem(nil, collapseChildren: true)
- } else if item.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.removeAllOutline()
- }
- }
- }
-
- @objc private func removeAllOutline() {
- var selectedPDFOutlineArr = [CPDFOutline]();
- for index in 0 ... self.listView.document.outlineRoot().numberOfChildren-1 {
- let outline : CPDFOutline = self.listView.document.outlineRoot().child(at: index)
- selectedPDFOutlineArr.append(outline)
- }
- for tOutline in selectedPDFOutlineArr {
- self.removePDFOutline(outline: tOutline, toIndex: NSInteger(tOutline.index), atParent: tOutline.parent)
- }
- }
-
- @objc private func addItemAction() {
- let selectRowIndexs = self.selectedRowIndexs()
- if (selectRowIndexs.count == 0) {
- var lastPDFOuline : CPDFOutline = CPDFOutline()
- if(self.outlineView.numberOfRows == 0) {
- lastPDFOuline = self.listView.document.setNewOutlineRoot()
- } else {
- lastPDFOuline = self.outlineView.item(atRow: self.outlineView.numberOfRows - 1) as! CPDFOutline
- }
- var rootPDFOutline : CPDFOutline!
- if(lastPDFOuline != nil) {
- while ((lastPDFOuline.parent) != nil) {
- lastPDFOuline = lastPDFOuline.parent
- }
- rootPDFOutline = lastPDFOuline
- } else {
- rootPDFOutline = self.listView.document.outlineRoot()
- if(rootPDFOutline == nil) {
- rootPDFOutline = self.listView.document.setNewOutlineRoot()
- }
- }
- let index = rootPDFOutline.numberOfChildren
- self.addPDFOutlineToIndex(index: NSInteger(index), atParent: rootPDFOutline)
- } else {
- let currentPDFOutline : CPDFOutline = self.outlineView.item(atRow: selectRowIndexs.last ?? 0) as! CPDFOutline
- let parent = currentPDFOutline.parent
- let index = currentPDFOutline.index + 1
- self.addPDFOutlineToIndex(index: NSInteger(index), atParent: parent)
- }
- }
-
- @objc func addChildItemAction() {
- let selectedRowIndexes : IndexSet! = self.selectedRowIndexs()
- if selectedRowIndexes.count == 0 {
- __NSBeep()
- } else {
- let parent = self.outlineView.item(atRow: selectedRowIndexes.last!) as! CPDFOutline
- let index = parent.numberOfChildren
- self.addPDFOutlineToIndex(index: NSInteger(index), atParent: parent)
- }
- }
-
- @objc func addHigherItemAction() {
- let selectedRowIndexes : IndexSet! = self.selectedRowIndexs()
- if selectedRowIndexes.count == 0 {
- __NSBeep()
- } else {
- let currentPDFOutline = self.outlineView.item(atRow: selectedRowIndexes.last!) as! CPDFOutline
- var parent = currentPDFOutline.parent
- let index = NSInteger(parent!.index) + 1
- parent = parent?.parent
- if parent != nil {
- self.addPDFOutlineToIndex(index: index, atParent: parent)
- } else {
- __NSBeep()
- }
- }
- }
-
- @objc func deleteItemAction() {
- let selectedRowIndexes : IndexSet! = self.selectedRowIndexs()
- if selectedRowIndexes.count == 0 {
- __NSBeep()
- } else {
- var selectedPDFOutlineArr = [CPDFOutline]();
- for index in selectedRowIndexes {
- var outline : CPDFOutline = self.outlineView.item(atRow: index) as! CPDFOutline
- selectedPDFOutlineArr.append(outline)
- }
- for tOutline in selectedPDFOutlineArr {
- self.removePDFOutline(outline: tOutline, toIndex: NSInteger(tOutline.index), atParent: tOutline.parent)
- }
- }
-
- }
-
- @objc func editItemAction() {
- if self.outlineView.clickedRow >= 0 {
- let cell = self.outlineView.rowView(atRow: self.outlineView.clickedRow, makeIfNecessary: true)
- let outline = self.outlineView.item(atRow: self.outlineView.clickedRow)
- let outlineEditViewController = KMOutlineEditViewController.init(outline: outline as! CPDFOutline, document: self.listView)
- let popover = NSPopover()
- popover.delegate = self
- popover.contentViewController = outlineEditViewController
- popover.animates = true
- popover.behavior = .transient
- popover.show(relativeTo: cell!.bounds, of: cell!, preferredEdge: .minX)
- } else {
- __NSBeep()
- }
- }
-
- @objc func renameItemAction() {
- if self.outlineView.clickedRow >= 0 {
- self.renameOutlineWithRow(row: self.outlineView.clickedRow)
- } else {
- __NSBeep()
- }
- }
-
- @objc func changeItemAction() {
- if self.outlineView.clickedRow >= 0 {
- let outline = self.outlineView.item(atRow: self.outlineView.clickedRow)
- let alter = NSAlert()
- alter.alertStyle = NSAlert.Style.informational
- alter.messageText = NSLocalizedString("Are you sure you want to set the target location of the selected outline to the current page?", comment: "")
- alter.addButton(withTitle: NSLocalizedString("Yes", comment:""))
- alter.addButton(withTitle: NSLocalizedString("No", comment:""))
- let modlres = alter.runModal()
- if modlres == NSApplication.ModalResponse.alertFirstButtonReturn {
- self.setPDFOutline(outline: outline as? CPDFOutline, destination: self.listView.currentDestination)
- }
- } else {
- __NSBeep()
- }
- }
-
- @objc func promoteItemAction() {
- if self.outlineView.clickedRow >= 0 {
- let outline = self.outlineView.item(atRow: self.outlineView.clickedRow) as! CPDFOutline
- var parent = outline.parent
- let index = NSInteger(parent!.index) + 1
- parent = parent?.parent
- if parent != nil {
- self.movePDFOutline(outline: outline, toIndex: index, atParent: parent)
- } else {
- __NSBeep()
- }
- } else {
- __NSBeep()
- }
- }
-
- @objc func demoteItemAction() {
- if self.outlineView.clickedRow >= 0 {
- let outline = self.outlineView.item(atRow: self.outlineView.clickedRow) as! CPDFOutline
- var parent = outline.parent
- let newParent = parent?.child(at: UInt(outline.index - 1))
- let index = newParent?.numberOfChildren
- if(index != nil) {
- self.movePDFOutline(outline: outline, toIndex: NSInteger(index ?? 0), atParent: newParent)
- } else {
- __NSBeep()
- }
- } else {
- __NSBeep()
- }
- }
-
- //MARK: - Outline
-
- func renameOutlineWithRow(row:NSInteger) {
- self.renamePDFOutline = self.outlineView.item(atRow: row) as? CPDFOutline
- let cell : KMOutlineCellView = self.outlineView.view(atColumn: 0, row: row, makeIfNecessary: true) as! KMOutlineCellView
- self.renameTextField = cell.titleTextField
- self.renameTextField.delegate = self
- self.renameTextField.isEditable = true
- self.renameTextField.becomeFirstResponder()
- }
-
- func renamePDFOutline(outline : CPDFOutline! , label:String) {
- self.renameTextField.isEditable = false
- if outline.label == label {
- return
- }
- outline.label = label
- self.outlineView.reloadData()
-
- var indexSet = IndexSet()
- indexSet.insert(self.outlineView.row(forItem: outline))
- self.outlineView.selectRowIndexes(indexSet, byExtendingSelection: false)
- }
-
- func movePDFOutline(outline : CPDFOutline! , toIndex index : NSInteger , atParent parent : CPDFOutline!) {
- outline.removeFromParent()
- parent.insertChild(outline, at: UInt(index))
- self.outlineView.reloadData()
- self.outlineView.expandItem(parent)
- }
-
- func addPDFOutlineCurrentSelections() {
- var string : String = ""
- for currentSelection in self.listView.currentSelection.selectionsByLine {
- if string.count == 0 {
- string = "\(string)+\("\n")"
- string = "\(string)+\(String(describing: currentSelection.string()))"
- } else {
- string = currentSelection.string()
- }
- }
-
- var parent : CPDFOutline?
- var index : Int = 0
- let selectRowIndexes = self.selectedRowIndexs()
- if selectRowIndexes.count == 0 {
- var lastOutline = self.outlineView.item(atRow: self.outlineView.numberOfRows - 1) as? CPDFOutline
- if lastOutline != nil {
- while ((lastOutline?.parent) != nil) {
- lastOutline = lastOutline?.parent
- }
- parent = lastOutline
- } else {
- parent = self.listView.document.outlineRoot()
- if parent == nil {
- parent = self.listView.document.setNewOutlineRoot()
- }
- }
- index = Int(parent?.numberOfChildren ?? 0)
- } else {
- let currentPDFOutline = self.outlineView.item(atRow: selectRowIndexes.last ?? 0) as! CPDFOutline
- parent = currentPDFOutline.parent
- index = Int(currentPDFOutline.index + 1)
- }
- if parent != nil {
- let outline = parent?.insertChild(at: UInt(index))
- outline?.label = string
- outline?.destination = self.listView.currentDestination
- self.addPDFOutline(outline: outline, toIndex: index, atParent: parent)
- } else {
- __NSBeep()
- }
- }
-
- func updateOutlineSelection() {
- let currentPageIndex = self.listView.currentPageIndex
- let currentPage : CPDFPage = self.listView.document.page(at: UInt(currentPageIndex))
- let numRows = self.outlineView.numberOfRows
- var arr = [[String : CPDFPage]]()
- for i in 0..<numRows {
- let tPDFOutline = self.outlineView.item(atRow: i) as! CPDFOutline
- let tPage = tPDFOutline.destination.pageIndex
- if tPage < 0 {
- continue
- }
- var page = self.listView.document.page(at: UInt(tPage))!
- var tDict : [String : CPDFPage] = ["\(i)":page]
- arr.append(tDict)
- }
- DispatchQueue.global(qos: .utility).async{
- var hasExistInOutlineView = false
- var selectIndex = 0
- for (index,value) in arr.enumerated() {
- let dict : [String : CPDFPage] = value
- let page: CPDFPage = dict.values.first ?? CPDFPage()
- let index = Int(index)
- if page.isEqual(currentPage) {
- selectIndex = index
- hasExistInOutlineView = true
- break
- }
- }
- DispatchQueue.main.async {
- if !hasExistInOutlineView {
- self.outlineView.deselectRow(self.outlineView.selectedRow)
- } else {
- self.outlineView.selectRowIndexes([selectIndex], byExtendingSelection: false)
- self.outlineView.scrollRowToVisible(selectIndex)
- }
- }
- }
- }
-
- //MARK: - Accessors
-
- func menuItemWithTitle(title:String, action:Selector?) -> NSMenuItem {
- let menuItem = NSMenuItem.init(title: title as String, action: action, keyEquivalent: "")
- menuItem.target = self
- return menuItem
- }
-
- func selectedRowIndexs() -> IndexSet {
- let clickRow = self.outlineView.clickedRow
- var selectedRowIndexs = self.outlineView.selectedRowIndexes
- if(clickRow != -1 && !selectedRowIndexs.contains(clickRow)) {
- selectedRowIndexs = [clickRow]
- }
- return selectedRowIndexs
- }
-
- func reloadData() {
- self.outlineView.reloadData()
- }
-
- func addPDFOutlineToIndex(index:NSInteger, atParent parent:CPDFOutline!) {
- let currentPageIndex = self.listView.currentPageIndex
- var outline = parent.insertChild(at: UInt(index))
- outline?.label = "\(NSLocalizedString("Page", comment: ""))\(currentPageIndex+1)"
- let des = self.listView.currentDestination
- if "\(des?.point.x ?? 0)" != "nan" {
- outline?.destination = self.listView.currentDestination
- } else {
- let destination : CPDFDestination = CPDFDestination(document: self.listView.document, pageIndex: currentPageIndex, at: CGPoint(x: 0, y: 0), zoom: self.listView.scaleFactor)
- outline?.destination = destination
- }
- self.addPDFOutline(outline:outline,toIndex: index,atParent: parent)
- }
-
- func addPDFOutline(outline:CPDFOutline? , toIndex index : NSInteger , atParent parent : CPDFOutline!) {
- self.view.window?.makeFirstResponder(self.outlineView)
- if outline?.parent == nil {
- parent.insertChild(outline, at: UInt(index))
- }
- self.outlineView.reloadData()
- self.outlineView.expandItem(parent)
- let indexSet : IndexSet = [self.outlineView.row(forItem: outline)]
- self.outlineView.selectRowIndexes(indexSet, byExtendingSelection: false)
- if(self.outlineView.selectedRow >= 0) {
- self.renameOutlineWithRow(row: self.outlineView.selectedRow)
- }
- if Thread.current.isMainThread {
- self.outlineView.scrollToVisible(self.outlineView.rect(ofRow: index))
- } else {
- DispatchQueue.main.async {
- self.outlineView.scrollToVisible(self.outlineView.rect(ofRow: index))
- }
- }
- }
-
- func removePDFOutline(outline:CPDFOutline! , toIndex index : NSInteger , atParent parent : CPDFOutline!) {
- outline.removeFromParent()
- self.outlineView.reloadData()
- self.outlineView.expandItem(parent)
- }
-
- func setPDFOutline(outline:CPDFOutline! , destination : CPDFDestination!) {
- outline.destination = destination
- self.outlineView.reloadData()
- }
-
- func editOutlineUI(editVC : KMOutlineEditViewController!) {
- if editVC.pageButton.state == NSControl.StateValue.on {
- let index = Int(editVC.outlineTargetPageIndexTextField.stringValue)!
- if editVC.originalDestination.pageIndex != index {
- let page = editVC.pdfView.document.page(at: UInt(index))
- if page != nil {
- let destination = CPDFDestination.init(document: editVC.pdfView.document, pageIndex: index)
- editVC.outline.destination = destination
- } else {
- __NSBeep()
- }
- }
- } else if editVC.urlButton.state == NSControl.StateValue.on {
- if editVC.originalURLString != editVC.outlineURLTextField.stringValue {
- var urlString = editVC.outlineURLTextField.stringValue
- let tLowerUrl = urlString.lowercased()
- if !tLowerUrl.hasPrefix("https://") && !tLowerUrl.hasPrefix("pf]://") && !urlString.hasPrefix("https://") &&
- urlString.lengthOfBytes(using: String.Encoding(rawValue: String.Encoding.utf16.rawValue)) > 0 {
- urlString = "http://\(urlString)"
- }
- let action = CPDFURLAction.init(url: urlString)
- editVC.outline.action = action
- }
- } else if editVC.mailButton.state == NSControl.StateValue.on {
- var mailString = editVC.mailAddressTextField.stringValue
- let tLowerStr = mailString.lowercased()
- if !tLowerStr.hasPrefix("mailto:") {
- mailString = "mailto:\(mailString)"
- }
- if mailString != editVC.originalURLString {
- var action = CPDFURLAction.init(url: mailString)
- if action?.url == nil {
- action = CPDFURLAction.init(url: "mailto:")
- }
- editVC.outline.action = action
- }
- }
- // self.mainWindowController.document?.undo()
- if editVC.outlineNameTextView.string != editVC.originalLabel {
- self.renamePDFOutline(outline: editVC.outline, label: editVC.outlineNameTextView.string)
- }
- }
-
- //MARK: NSMenuItemValidation
-
- func validateMenuItem(_ menuItem: NSMenuItem) -> Bool {
- let action = menuItem.action
- if action == #selector(addItemAction) ||
- action == #selector(addChildItemAction) ||
- action == #selector(addHigherItemAction) ||
- action == #selector(deleteItemAction) ||
- action == #selector(editItemAction) ||
- action == #selector(changeItemAction) ||
- action == #selector(renameItemAction) ||
- action == #selector(promoteItemAction) ||
- action == #selector(demoteItemAction) {
- if self.outlineView.selectedRowIndexes.count > 1 {
- if action == #selector(deleteItemAction) {
- return true
- }
- return false
- } else if self.outlineView.selectedRowIndexes.count > 0 {
- if action == #selector(addChildItemAction) || action == #selector(changeItemAction) {
- return true
- }
- }
- if self.outlineView.clickedRow == -1 {
- if action == #selector(addItemAction) {
- return true
- } else {
- return false
- }
- } else {
- let outline : CPDFOutline = self.outlineView.item(atRow: self.outlineView.clickedRow) as! CPDFOutline
- if outline.index > 0 {
- if action == #selector(demoteItemAction) {
- return true
- }
- } else {
- if action == #selector(demoteItemAction) {
- return false
- }
- }
-
- let parentOutline = outline.parent
- let grandparentOutline = parentOutline?.parent
- if grandparentOutline != nil {
- if action == #selector(addHigherItemAction) {
- return true
- } else if action == #selector(promoteItemAction) {
- return true
- }
- } else {
- if action == #selector(addHigherItemAction) {
- return false
- } else if action == #selector(promoteItemAction) {
- return false
- }
- }
- }
- return true
- }
- return true
- }
-
-
- //MARK: Noti
- @objc func KMPDFViewCurrentPageDidChangedNotification(notification: NSNotification) {
- let pdfdocument : CPDFDocument = notification.object as! CPDFDocument
- if pdfdocument.isEqual(self.listView.document) {
- self.updateOutlineSelection()
- }
- }
-
- }
- //MARK: NSOutlineViewDataSource,NSOutlineViewDelegate
- extension KMOutlineViewController : NSOutlineViewDataSource,NSOutlineViewDelegate {
- func outlineView(_ outlineView: NSOutlineView, numberOfChildrenOfItem item: Any?) -> Int {
- var rootOutline = self.listView.document.outlineRoot()
- if rootOutline == nil {
- rootOutline = CPDFOutline()
- }
- var newItem : CPDFOutline = item as? CPDFOutline ?? rootOutline!
- if(newItem.numberOfChildren == 0) { //无数据时的图
- self.emptyView.isHidden = false
- } else {
- self.emptyView.isHidden = true
- }
- return Int(newItem.numberOfChildren)
- }
-
- func outlineView(_ outlineView: NSOutlineView, child index: Int, ofItem item: Any?) -> Any {
- var newItem : CPDFOutline = item as? CPDFOutline ?? self.listView.document.outlineRoot()
- var child : CPDFOutline? = newItem.child(at: UInt(index))
- return child ?? CPDFOutline()
- }
-
- func outlineView(_ outlineView: NSOutlineView, isItemExpandable item: Any) -> Bool {
- var newItem : CPDFOutline = item as? CPDFOutline ?? self.listView.document.outlineRoot()
- return newItem.numberOfChildren > 0
- }
-
- func outlineView(_ outlineView: NSOutlineView, viewFor tableColumn: NSTableColumn?, item: Any) -> NSView? {
- let cell : KMOutlineCellView = outlineView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "KMOutlineCellView"), owner: self) as! KMOutlineCellView
- let outline : CPDFOutline? = item as? CPDFOutline
- cell.titleTextField.stringValue = outline?.label ?? ""
- var destination = outline?.destination
- if destination == nil {
- let action = outline?.action
- if (action != nil) && (action is CPDFGoToAction) {
- destination = (action as? CPDFGoToAction)?.destination()
- }
- }
- if destination != nil {
- cell.pageTextField.stringValue = "\((destination?.pageIndex ?? 0)+1)"
- } else {
- cell.pageTextField.stringValue = ""
- }
-
- let font : NSFont = NSFont.systemFont(ofSize: CGFloat(UserDefaults.standard.float(forKey: "SKOfficeTableFontSize")))
- if (font != nil) {
- cell.titleTextField.font = NSFont.init(name: cell.titleTextField.font!.fontName, size: font.pointSize)
- cell.pageTextField.font = NSFont.init(name: cell.pageTextField.font!.fontName, size: font.pointSize)
- }
-
- return cell
- }
-
- func outlineView(_ outlineView: NSOutlineView, rowViewForItem item: Any) -> NSTableRowView? {
- let rowView = KMOutlineRowView()
- rowView.selectionHighlightStyle = NSTableView.SelectionHighlightStyle.none;
- return rowView
- }
-
- func outlineView(_ outlineView: NSOutlineView, heightOfRowByItem item: Any) -> CGFloat {
- let font : NSFont = NSFont.systemFont(ofSize: CGFloat(UserDefaults.standard.float(forKey: "SKOfficeTableFontSize")))
- return 27 + font.pointSize
- }
-
- func outlineView(_ outlineView: NSOutlineView, shouldSelectItem item: Any) -> Bool {
- return true
- }
-
- func outlineViewSelectionDidChange(_ notification: Notification) {
- if self.outlineView.selectedRowIndexes.count == 0 {
- return
- }
-
- if self.self.outlineView.selectedRowIndexes.count > 1 {
-
- } else {
- let outline : CPDFOutline = self.outlineView .item(atRow:self.outlineView.selectedRow) as! CPDFOutline
- if outline.destination != nil {
- self.listView.go(to: outline.destination)
- } else if outline.action != nil {
- self.listView.perform(outline.action)
- }
- }
- }
-
- func outlineView(_ outlineView: NSOutlineView, writeItems items: [Any], to pasteboard: NSPasteboard) -> Bool {
- if self.outlineView.selectedRowIndexes.count > 1 {
- return true
- }
-
- self.dragPDFOutline = items.first as? CPDFOutline
-
- let indexSet = [self.outlineView.clickedRow]
- let indexSetData : Data = NSKeyedArchiver.archivedData(withRootObject: indexSet) as Data
- pasteboard.declareTypes([NSPasteboard.PasteboardType(rawValue: "kKMPDFViewOutlineDragDataType")], owner: self)
- pasteboard.setData(indexSetData, forType: NSPasteboard.PasteboardType(rawValue: NSPasteboard.PasteboardType.RawValue("kKMPDFViewOutlineDragDataType")))
- return true
- }
-
- func outlineView(_ outlineView: NSOutlineView, validateDrop info: NSDraggingInfo, proposedItem item: Any?, proposedChildIndex index: Int) -> NSDragOperation {
- var dragOperation = NSDragOperation.init(rawValue: 0)
- if index > 0 {
- dragOperation = NSDragOperation.move
- }
- return dragOperation
- }
-
- func outlineView(_ outlineView: NSOutlineView, acceptDrop info: NSDraggingInfo, item: Any?, childIndex index: Int) -> Bool {
- if ((self.dragPDFOutline == nil) || (index < 0)) {
- return false
- }
- var outline : CPDFOutline = CPDFOutline()
- if item != nil {
- outline = item as! CPDFOutline
- }
- if outline.parent == nil {
- var root = self.dragPDFOutline
- while root?.parent != nil {
- root = root?.parent
- }
- if self.dragPDFOutline.parent.isEqual(root) {
- if self.dragPDFOutline.index > index {
- self.movePDFOutline(outline: self.dragPDFOutline, toIndex: index, atParent: root)
- } else {
- self.movePDFOutline(outline: self.dragPDFOutline, toIndex: index - 1, atParent: root)
- }
- } else {
- self.movePDFOutline(outline: self.dragPDFOutline, toIndex: index, atParent: root)
- }
- } else {
- if self.dragPDFOutline.parent.isEqual(item) {
- if self.dragPDFOutline.index != 0 {
- if self.dragPDFOutline.index > index {
- self.movePDFOutline(outline: self.dragPDFOutline, toIndex: index, atParent: outline)
- } else {
- self.movePDFOutline(outline: self.dragPDFOutline, toIndex: index - 1, atParent: outline)
- }
- } else {
- return false
- }
- } else {
- var tOutline = outline
- var isContains = false
- while (tOutline != nil && tOutline.parent != nil) {
- if tOutline.isEqual(self.dragPDFOutline) {
- isContains = true
- break
- }
- tOutline = tOutline.parent
- }
- if isContains == false {
- self.movePDFOutline(outline: self.dragPDFOutline, toIndex: index, atParent: outline)
- }
- }
- }
-
- return true
- }
-
- }
- // MARK - NSTextFieldDelegate
- extension KMOutlineViewController : NSTextFieldDelegate {
- func controlTextDidEndEditing(_ obj: Notification) {
- if (self.renameTextField.isEqual(obj.object)) {
- let textField : NSTextField = obj.object as! NSTextField
- self.renamePDFOutline(outline: self.renamePDFOutline, label: textField.stringValue)
- }
- }
- }
- // MARK - NSPopoverDelegate
- extension KMOutlineViewController : NSPopoverDelegate {
- func popoverWillClose(_ notification: Notification) {
- let popover : NSPopover = notification.object as! NSPopover
- if popover.contentViewController!.isKind(of: KMOutlineEditViewController.self) {
-
- }
- }
- }
|