KMLinkViewController.swift 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. //
  2. // KMLinkViewController.swift
  3. // PDF Reader Pro
  4. //
  5. // Created by Niehaoyu on 2024/10/18.
  6. //
  7. import Cocoa
  8. import KMComponentLibrary
  9. @objc public enum PDFLinkType: Int, CaseIterable{
  10. case Page = 0 //
  11. case Web //
  12. case Email //
  13. }
  14. @objc public enum PDFLinkPopupType: Int, CaseIterable{
  15. case None = 0 //默认类型
  16. case Page //
  17. case Web //
  18. case Email //
  19. case MultiSelect //Popup弹窗
  20. }
  21. /**
  22. 未选中注释:修改默认添加类型。
  23. 选中注释:
  24. - 切换类型:判断类型->修改显示信息。
  25. - 输入文字:修改跳转内容。
  26. */
  27. //MARK: - KMLinkViewController
  28. @objcMembers class KMLinkViewController: NSViewController {
  29. @IBOutlet var contendBox: NSBox!
  30. @IBOutlet var infoContendView: NSView!
  31. @IBOutlet var tabsBGView: NSView!
  32. @IBOutlet var tabsView: ComponentTabs!
  33. @IBOutlet var typeContendView: NSView!
  34. @IBOutlet var linkPageView: KMLinkPageView!
  35. @IBOutlet var linkEmailView: KMLinkEmailView!
  36. @IBOutlet var linkWebView: KMLinkWebView!
  37. @IBOutlet var emptyContendView: ComponentEmpty!
  38. private weak var _pdfView: CPDFListView? = nil
  39. private var annotations: [CPDFLinkAnnotation] = []
  40. private var current_Annotation: CPDFLinkAnnotation? = nil
  41. var multiController: KMNAlignmentController = KMNAlignmentController.init() //注释多选界面
  42. let pageProperty = ComponentTabsProperty(tabsType: .underline_Fill, state: .normal, showIcon: false, title: NSLocalizedString("Page", comment: ""))
  43. let webProperty = ComponentTabsProperty(tabsType: .underline_Fill, state: .normal, showIcon: false, title: NSLocalizedString("Web", comment: ""))
  44. let emailProperty = ComponentTabsProperty(tabsType: .underline_Fill, state: .normal, showIcon: false, title: NSLocalizedString("Email", comment: ""))
  45. public override func viewDidLoad() {
  46. super.viewDidLoad()
  47. // Do view setup here.
  48. setUpUI()
  49. }
  50. func setUpUI() {
  51. contendBox.fillColor = ComponentLibrary.shared.getComponentColorFromKey("colorBg/layout-middle")
  52. tabsView.updateItemProperty([pageProperty, webProperty, emailProperty])
  53. tabsView.delegate = self
  54. linkPageView.delegate = self
  55. linkWebView.delegate = self
  56. linkEmailView.delegate = self
  57. multiController.delegate = self
  58. emptyContendView.properties = ComponentEmptyProperty(emptyType: .noLink,
  59. text: KMLocalizedString("Add Link"),
  60. subText: KMLocalizedString("Select an area or text on the page to add a link."))
  61. }
  62. //MARK: - Setter
  63. var pdfLinkType: PDFLinkType = .Page {
  64. didSet {
  65. view.window?.makeFirstResponder(nil)
  66. }
  67. }
  68. weak var pdfView: CPDFListView? {
  69. get {
  70. return _pdfView
  71. }
  72. set {
  73. _pdfView = newValue
  74. }
  75. }
  76. //MARK: - func
  77. public func reloadData() {
  78. guard let pdfView = self.pdfView else {
  79. return
  80. }
  81. typeContendView.isHidden = true
  82. emptyContendView.isHidden = true
  83. multiController.view.isHidden = true
  84. tabsBGView.isHidden = false
  85. let pdfAnnotations: [CPDFAnnotation] = pdfView.activeAnnotations as? [CPDFAnnotation] ?? []
  86. var linkAnnotations: [CPDFLinkAnnotation] = []
  87. for annotation in pdfAnnotations {
  88. if annotation is CPDFLinkAnnotation {
  89. linkAnnotations.append((annotation as! CPDFLinkAnnotation))
  90. }
  91. }
  92. annotations = linkAnnotations
  93. current_Annotation = nil
  94. if annotations.count == 0 {
  95. emptyContendView.isHidden = false
  96. } else if annotations.count == 1 {
  97. current_Annotation = annotations.first
  98. multiController.view.isHidden = true
  99. typeContendView.isHidden = false
  100. linkPageView.isHidden = true
  101. linkEmailView.isHidden = true
  102. linkWebView.isHidden = true
  103. if let url = current_Annotation?.url() {
  104. if url.hasPrefix("mailto:") {
  105. pdfLinkType = .Email
  106. } else {
  107. pdfLinkType = .Web
  108. }
  109. } else if let _ = current_Annotation?.destination() {
  110. pdfLinkType = .Page
  111. }
  112. if pdfLinkType == .Page {
  113. linkPageView.isHidden = false
  114. linkPageView.pdfView = pdfView
  115. linkPageView.annotation = current_Annotation
  116. linkPageView.reloadData()
  117. } else if pdfLinkType == .Web {
  118. linkWebView.isHidden = false
  119. linkWebView.annotation = current_Annotation
  120. } else if pdfLinkType == .Email {
  121. linkEmailView.isHidden = false
  122. linkEmailView.annotation = current_Annotation
  123. }
  124. } else {
  125. multiController.view.frame = CGRectMake((CGRectGetWidth(infoContendView.frame) - 232)/2, CGRectGetHeight(infoContendView.frame)-112, 232, 112)
  126. multiController.view.autoresizingMask = [.width, .maxYMargin]
  127. infoContendView.addSubview(multiController.view)
  128. multiController.view.isHidden = false
  129. tabsBGView.isHidden = true
  130. if annotations.count > 2 {
  131. multiController.aligHorizontalXButton.properties.isDisabled = false
  132. multiController.aligVerticalYButton.properties.isDisabled = false
  133. } else {
  134. multiController.aligHorizontalXButton.properties.isDisabled = true
  135. multiController.aligVerticalYButton.properties.isDisabled = true
  136. }
  137. multiController.aligHorizontalXButton.reloadData()
  138. multiController.aligVerticalYButton.reloadData()
  139. }
  140. pageProperty.state = .normal
  141. webProperty.state = .normal
  142. emailProperty.state = .normal
  143. if pdfLinkType == .Page {
  144. pageProperty.state = .pressed
  145. } else if pdfLinkType == .Web {
  146. webProperty.state = .pressed
  147. } else if pdfLinkType == .Email {
  148. emailProperty.state = .pressed
  149. }
  150. tabsView.refreshItems()
  151. }
  152. func pdfLinkTypeChanged() {
  153. guard let _ = current_Annotation else {
  154. return
  155. }
  156. linkPageView.isHidden = true
  157. linkEmailView.isHidden = true
  158. linkWebView.isHidden = true
  159. if pdfLinkType == .Page {
  160. linkPageView.isHidden = false
  161. linkPageView.reloadData()
  162. } else if pdfLinkType == .Web {
  163. linkWebView.isHidden = false
  164. linkWebView.annotation = current_Annotation
  165. if let url = current_Annotation?.url() {
  166. if url.hasPrefix("mailto:") == true {
  167. linkWebView.inputTextarea.properties.text = ""
  168. linkWebView.inputTextarea.reloadData()
  169. }
  170. }
  171. } else if pdfLinkType == .Email {
  172. linkEmailView.isHidden = false
  173. linkEmailView.annotation = current_Annotation
  174. if let url = current_Annotation?.url() {
  175. if url.hasPrefix("mailto:") == false {
  176. linkEmailView.inputTextarea.properties.text = ""
  177. linkEmailView.inputTextarea.reloadData()
  178. }
  179. }
  180. }
  181. }
  182. //MARK: - MouseEvent
  183. public override func mouseUp(with event: NSEvent) {
  184. super.mouseUp(with: event)
  185. }
  186. }
  187. //MARK: - ComponentTabsDelegate
  188. extension KMLinkViewController: ComponentTabsDelegate {
  189. public func componentTabsDidSelected(_ view: ComponentTabs, _ property: ComponentTabsProperty) {
  190. if property == pageProperty {
  191. pdfLinkType = .Page
  192. } else if property == webProperty {
  193. pdfLinkType = .Web
  194. } else if property == emailProperty {
  195. pdfLinkType = .Email
  196. }
  197. if let annotation = current_Annotation {
  198. pdfLinkTypeChanged()
  199. }
  200. CPDFLinkAnnotation.updateDefault_AddLinkType(pdfLinkType.rawValue)
  201. }
  202. }
  203. //MARK: - KMLinkPageViewDelegate
  204. extension KMLinkViewController: KMLinkPageViewDelegate {
  205. func kmLinkPageViewDidGoToPage(_ view: KMLinkPageView, _ pageIndex: Int) {
  206. if let _ = pdfView?.document.page(at: UInt(pageIndex-1)) {
  207. pdfView?.go(toPageIndex: pageIndex-1, animated: false)
  208. }
  209. }
  210. func kmLinkPageViewDidChangeDestination(_ view: KMLinkPageView, _ pageIndex: Int) {
  211. guard let activiteAnno = current_Annotation else {
  212. return
  213. }
  214. activiteAnno.setURL(nil)
  215. if let page = pdfView?.document.page(at: UInt(pageIndex-1)) {
  216. let bounds = page.bounds(for: .cropBox)
  217. let destination = CPDFDestination(page: page, at: NSPoint(x: 0, y: bounds.size.height))
  218. activiteAnno.setDestination(destination)
  219. }
  220. if let _ = pdfView?.document.page(at: UInt(pageIndex-1)) {
  221. pdfView?.go(toPageIndex: pageIndex-1, animated: false)
  222. }
  223. }
  224. }
  225. //MARK: - KMLinkPageViewDelegate
  226. extension KMLinkViewController: KMLinkWebViewDelegate {
  227. func kmLinkWebViewDidGo(_ view: KMLinkWebView, _ webString: String) {
  228. guard let activeAnnotation = current_Annotation else {
  229. return
  230. }
  231. activeAnnotation.setDestination(nil)
  232. let linkUrlPath = KMNTools.judgeWebURL(webString)
  233. activeAnnotation.setURL(linkUrlPath)
  234. if let url = activeAnnotation.url() {
  235. if let data = URL(string: url) {
  236. NSWorkspace.shared.open(data)
  237. }
  238. }
  239. }
  240. }
  241. //MARK: - KMLinkEmailViewDelegate
  242. extension KMLinkViewController: KMLinkEmailViewDelegate {
  243. func kmLinkEmailViewDidGo(_ view: KMLinkEmailView, _ emailString: String) {
  244. guard let activeAnnotation = current_Annotation else {
  245. return
  246. }
  247. if !KMNTools.isValidateEmail(emailString) {
  248. let alert = NSAlert()
  249. alert.alertStyle = .critical
  250. alert.messageText = NSLocalizedString("Invalid Email. Please try again.", comment: "")
  251. alert.runModal()
  252. return
  253. }
  254. activeAnnotation.setDestination(nil)
  255. let linkUrlPath = KMNTools.judgeEmailURL(emailString)
  256. activeAnnotation.setURL(linkUrlPath)
  257. if let url = activeAnnotation.url() {
  258. NSWorkspace.shared.open(URL(string: url)!)
  259. }
  260. }
  261. }
  262. //MARK: - KMNAlignmentControllerDelegate
  263. extension KMLinkViewController: KMNAlignmentControllerDelegate {
  264. func alignmentControllerDidClick(_ controller: KMNAlignmentController, _ alignmentType: KMPDFActiveFormsAlignType) {
  265. pdfView?.change(annotations, alignmentType: alignmentType)
  266. pdfView?.setNeedsDisplayForVisiblePages()
  267. }
  268. }
  269. //MARK: - KMLinkViewController Class Method
  270. extension KMLinkViewController {
  271. }