KMAnnotationSelectLinkViewController.swift 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634
  1. //
  2. // KMAnnotationSelectLinkViewController.swift
  3. // PDF Reader Pro
  4. //
  5. // Created by wanjun on 2023/11/23.
  6. //
  7. import Cocoa
  8. let URLPlaceholder = "https://www.pdfreaderpro.com"
  9. let EmailPlaceholder = "support@pdfreaderpro.com"
  10. enum KMAnnotationLinkType: UInt {
  11. case page = 0
  12. case url
  13. case email
  14. }
  15. @objcMembers class KMAnnotationSelectLinkViewController: NSViewController, NSTextFieldDelegate {
  16. var _annotations: [CPDFAnnotation]?
  17. var pdfDocument: CPDFDocument?
  18. weak var _pdfview: CPDFListView?
  19. @IBOutlet var linkPageBox: KMBox!
  20. @IBOutlet var linkPageImageView: NSImageView!
  21. @IBOutlet var linkPageLabel: NSTextField!
  22. @IBOutlet var linkUrlBox: KMBox!
  23. @IBOutlet var linkUrlImageView: NSImageView!
  24. @IBOutlet var linkUrlLabel: NSTextField!
  25. @IBOutlet var linkEmailBox: KMBox!
  26. @IBOutlet var linkEmailImageView: NSImageView!
  27. @IBOutlet var linkEmailLabel: NSTextField!
  28. @IBOutlet var contentBox: NSBox!
  29. @IBOutlet var contentBoxLayoutConstraint: NSLayoutConstraint!
  30. @IBOutlet var pageView: NSView!
  31. @IBOutlet var pageLabel: NSTextField!
  32. @IBOutlet var inputPageTextField: NSTextField!
  33. @IBOutlet var allPageLabel: NSTextField!
  34. @IBOutlet var urlView: NSView!
  35. @IBOutlet var urlLabel: NSTextField!
  36. @IBOutlet var inputUrlTextField: NSTextField!
  37. @IBOutlet var goButton: NSButton!
  38. @IBOutlet var errorLabel: NSTextField!
  39. var annotation: CPDFLinkAnnotation?
  40. var _linkType: KMAnnotationLinkType = .page
  41. var mouseDownBox: KMBox?
  42. var pageRecord: String?
  43. var urlRecord: String?
  44. var emailRecord: String?
  45. var startPage: String?
  46. var isGo: Bool = false
  47. // MARK: Init Methods
  48. deinit {
  49. NotificationCenter.default.removeObserver(self)
  50. inputUrlTextField.delegate = nil
  51. inputPageTextField.delegate = nil
  52. }
  53. override func viewDidLoad() {
  54. super.viewDidLoad()
  55. // Do view setup here.
  56. pageRecord = ""
  57. urlRecord = ""
  58. emailRecord = ""
  59. linkPageLabel.stringValue = NSLocalizedString("Go To Page", comment: "")
  60. linkPageLabel.toolTip = NSLocalizedString("Go To Page", comment: "")
  61. linkPageLabel.textColor = KMAppearance.Layout.h1Color()
  62. linkUrlLabel.stringValue = NSLocalizedString("Hyperlink", comment: "")
  63. linkUrlLabel.toolTip = NSLocalizedString("Hyperlink", comment: "")
  64. linkUrlLabel.textColor = KMAppearance.Layout.h1Color()
  65. linkEmailLabel.stringValue = NSLocalizedString("Email", comment: "")
  66. linkEmailLabel.toolTip = NSLocalizedString("Email", comment: "")
  67. linkEmailLabel.textColor = KMAppearance.Layout.h1Color()
  68. errorLabel.stringValue = NSLocalizedString("Page number out of range", comment: "")
  69. errorLabel.textColor = KMAppearance.Status.errColor()
  70. let boxArr: [KMBox] = [linkPageBox, linkUrlBox, linkEmailBox]
  71. for box in boxArr {
  72. box.moveCallback = { [weak self] mouseEntered, mouseBox in
  73. guard let self = self else { return }
  74. if mouseEntered {
  75. if self.mouseDownBox != mouseBox {
  76. if box == self.linkPageBox {
  77. self.linkPageBox.fillColor = KMAppearance.Status.selColor()
  78. self.linkPageImageView.image = NSImage(named: "KMImageNameUXIconPropertybarLinkPageSel")
  79. self.linkPageLabel.textColor = KMAppearance.Layout.h0Color()
  80. } else if box == self.linkUrlBox {
  81. self.linkUrlBox.fillColor = KMAppearance.Status.selColor()
  82. self.linkUrlImageView.image = NSImage(named: "KMImageNameUXIconPropertybarLinkUrlSel")
  83. self.linkUrlLabel.textColor = KMAppearance.Layout.h0Color()
  84. } else if box == self.linkEmailBox {
  85. self.linkEmailBox.fillColor = KMAppearance.Status.selColor()
  86. self.linkEmailImageView.image = NSImage(named: "KMImageNameUXIconPropertybarLinkEmailSel")
  87. self.linkEmailLabel.textColor = KMAppearance.Layout.h0Color()
  88. }
  89. }
  90. } else {
  91. if self.mouseDownBox != mouseBox {
  92. box.fillColor = NSColor.clear
  93. if box == self.linkPageBox {
  94. self.linkPageImageView.image = NSImage(named: "KMImageNameUXIconPropertybarLinkPage")
  95. self.linkPageLabel.textColor = KMAppearance.Layout.h1Color()
  96. } else if box == self.linkUrlBox {
  97. self.linkUrlImageView.image = NSImage(named: "KMImageNameUXIconPropertybarLinkUrl")
  98. self.linkUrlLabel.textColor = KMAppearance.Layout.h1Color()
  99. } else if box == self.linkEmailBox {
  100. self.linkEmailImageView.image = NSImage(named: "KMImageNameUXIconPropertybarLinkEmail")
  101. self.linkEmailLabel.textColor = KMAppearance.Layout.h1Color()
  102. }
  103. }
  104. }
  105. }
  106. box.downCallback = { [weak self] downEntered, mouseBox, event in
  107. guard let self = self else { return }
  108. if downEntered {
  109. if !IAPProductsManager.default().isAvailableAllFunction() {
  110. if mouseBox == self.linkUrlBox || mouseBox == self.linkEmailBox {
  111. KMPurchaseCompareWindowController.sharedInstance().showWindow(nil)
  112. return
  113. }
  114. }
  115. if self.mouseDownBox == mouseBox {
  116. return
  117. }
  118. var mouseDownInt = 0
  119. if mouseBox == self.linkPageBox {
  120. self.inputPageTextField.stringValue = ""
  121. self.linkType = .page
  122. mouseDownInt = 0
  123. } else if mouseBox == self.linkUrlBox {
  124. self.inputUrlTextField.stringValue = ""
  125. self.linkType = .url
  126. mouseDownInt = 1
  127. } else if mouseBox == self.linkEmailBox {
  128. self.inputUrlTextField.stringValue = ""
  129. self.linkType = .email
  130. mouseDownInt = 2
  131. }
  132. UserDefaults.standard.set(mouseDownInt, forKey: "kmLinkSelectIndex")
  133. UserDefaults.standard.synchronize()
  134. self.mouseDownBox = mouseBox
  135. }
  136. }
  137. }
  138. isGo = true
  139. pageLabel.stringValue = NSLocalizedString("Page Number:", comment: "")
  140. pageLabel.textColor = KMAppearance.Layout.h1Color()
  141. allPageLabel.textColor = KMAppearance.Layout.h2Color()
  142. goButton.title = NSLocalizedString("Go", tableName: "MainMenu", comment: "")
  143. goButton.setTitleColor(KMAppearance.Layout.w0Color())
  144. goButton.wantsLayer = true
  145. goButton.layer?.backgroundColor = KMAppearance.Interactive.m0Color().cgColor
  146. goButton.setTitleColor(KMAppearance.Layout.w0Color())
  147. inputPageTextField.backgroundColor = KMAppearance.Layout.l1Color()
  148. inputUrlTextField.backgroundColor = KMAppearance.Layout.l1Color()
  149. inputPageTextField.wantsLayer = true
  150. inputUrlTextField.wantsLayer = true
  151. inputPageTextField.layer?.borderWidth = 1.0
  152. inputUrlTextField.layer?.borderWidth = 1.0
  153. inputPageTextField.layer?.borderColor = KMAppearance.Interactive.a0Color().cgColor
  154. inputUrlTextField.layer?.borderColor = KMAppearance.Interactive.a0Color().cgColor
  155. inputPageTextField.layer?.cornerRadius = 1.0
  156. inputUrlTextField.layer?.cornerRadius = 1.0
  157. inputUrlTextField.inputContext?.allowedInputSourceLocales = [NSAllRomanInputSourcesLocaleIdentifier]
  158. if annotation?.url() != nil {
  159. if let scheme = annotation?.url().fileURL.scheme {
  160. if scheme == "mailto" {
  161. linkType = .email
  162. mouseDownBox = linkEmailBox
  163. } else {
  164. linkType = .url
  165. mouseDownBox = linkUrlBox
  166. }
  167. }
  168. } else {
  169. linkType = .page
  170. mouseDownBox = linkPageBox
  171. }
  172. }
  173. override func viewDidAppear() {
  174. super.viewDidAppear()
  175. inputPageTextField.delegate = self
  176. inputUrlTextField.delegate = self
  177. if let url = annotation?.url {
  178. inputUrlTextField.becomeFirstResponder()
  179. } else {
  180. inputPageTextField.becomeFirstResponder()
  181. }
  182. }
  183. // MARK: Get & Set
  184. var linkType: KMAnnotationLinkType {
  185. set {
  186. _linkType = newValue
  187. contentBoxLayoutConstraint.constant = 46.0
  188. switch _linkType {
  189. case .page:
  190. contentBoxLayoutConstraint.constant = 24.0
  191. createLinkPageView()
  192. contentBox.contentView = pageView
  193. inputPageTextField.becomeFirstResponder()
  194. case .url:
  195. createLinkURLView()
  196. contentBox.contentView = urlView
  197. inputUrlTextField.becomeFirstResponder()
  198. case .email:
  199. createLinkEmailView()
  200. contentBox.contentView = urlView
  201. inputUrlTextField.becomeFirstResponder()
  202. default:
  203. break
  204. }
  205. }
  206. get {
  207. return _linkType
  208. }
  209. }
  210. weak var pdfview: CPDFListView? {
  211. set {
  212. _pdfview = newValue
  213. // startPage = _pdfview?.currentPage().label
  214. self.startPage = "\((self._pdfview?.currentPage().pageIndex() ?? 1)+1)"
  215. }
  216. get {
  217. return _pdfview
  218. }
  219. }
  220. var annotations: [CPDFAnnotation]? {
  221. set {
  222. _annotations = newValue
  223. annotation = _annotations?.first as? CPDFLinkAnnotation
  224. }
  225. get {
  226. return _annotations
  227. }
  228. }
  229. // MARK: Private
  230. func getURLViewHeightLayoutConstraint() -> CGFloat {
  231. return urlLabel.frame.height + 4 + inputUrlTextField.frame.height
  232. }
  233. func getPageViewHeightLayoutConstraint() -> CGFloat {
  234. return inputPageTextField.frame.height
  235. }
  236. func createLinkPageView() {
  237. annotationLinkSelectBox(linkPageBox)
  238. inputPageTextField.formatter = TextFieldFormatter()
  239. if pdfDocument!.pageCount > 1 {
  240. inputPageTextField.placeholderString = "1-\(pdfDocument!.pageCount)"
  241. } else {
  242. inputPageTextField.placeholderString = "1"
  243. }
  244. allPageLabel.stringValue = "/\(pdfDocument!.pageCount)"
  245. if let destination = annotation?.destination() {
  246. if let page = destination.page() {
  247. let pageIndex = page.document?.index(for: page) ?? 0
  248. inputPageTextField.stringValue = "\(pageIndex + 1)"
  249. pageRecord = "\(pageIndex + 1)"
  250. }
  251. }
  252. if inputPageTextField.stringValue.isEmpty {
  253. inputPageTextField.stringValue = pageRecord!
  254. }
  255. let pageFloat = Float(inputPageTextField.stringValue) ?? 0
  256. if pageFloat < 1 || UInt(pageFloat) > self.pdfDocument!.pageCount {
  257. goButton.layer!.backgroundColor = KMAppearance.Interactive.m0Color().withAlphaComponent(0.4).cgColor
  258. goButton.setTitleColor(KMAppearance.Layout.w0Color().withAlphaComponent(0.4))
  259. } else {
  260. goButton.layer!.backgroundColor = KMAppearance.Interactive.m0Color().cgColor
  261. goButton.setTitleColor(KMAppearance.Layout.w0Color())
  262. }
  263. }
  264. func createLinkURLView() {
  265. annotationLinkSelectBox(linkUrlBox)
  266. urlLabel.stringValue = NSLocalizedString("URL:", comment: "")
  267. urlLabel.textColor = KMAppearance.Layout.h1Color()
  268. inputUrlTextField.placeholderString = "https://www.pdfreaderpro.com"
  269. if let annotationURL = annotation?.url() {
  270. var urlString = annotationURL.fileURL.absoluteString
  271. if urlString.hasPrefix("http://") {
  272. urlString = String(urlString.suffix(from: urlString.index(urlString.startIndex, offsetBy: 7)))
  273. } else if urlString.hasPrefix("https://") {
  274. urlString = String(urlString.suffix(from: urlString.index(urlString.startIndex, offsetBy: 8)))
  275. }
  276. inputUrlTextField.stringValue = urlString
  277. urlRecord = urlString
  278. }
  279. if inputUrlTextField.stringValue.isEmpty {
  280. inputUrlTextField.stringValue = urlRecord!
  281. }
  282. if urlRecord!.isEmpty {
  283. goButton.layer!.backgroundColor = KMAppearance.Interactive.m0Color().cgColor
  284. goButton.setTitleColor(KMAppearance.Layout.w0Color())
  285. } else {
  286. goButton.layer!.backgroundColor = KMAppearance.Interactive.m0Color().withAlphaComponent(0.4).cgColor
  287. goButton.setTitleColor(KMAppearance.Layout.w0Color().withAlphaComponent(0.4))
  288. }
  289. }
  290. func createLinkEmailView() {
  291. annotationLinkSelectBox(linkEmailBox)
  292. urlLabel.stringValue = NSLocalizedString("Email:", comment: "")
  293. urlLabel.textColor = KMAppearance.Layout.h1Color()
  294. inputUrlTextField.placeholderString = "support@pdfreaderpro.com"
  295. let urlString = annotation?.url() ?? ""
  296. if urlString.fileURL.scheme == "mailto" {
  297. if let urlString = annotation?.url().fileURL.absoluteString, urlString.hasPrefix("mailto:") {
  298. let trimmedString = String(urlString.suffix(from: urlString.index(urlString.startIndex, offsetBy: 7)))
  299. inputUrlTextField.stringValue = trimmedString
  300. emailRecord = trimmedString
  301. }
  302. if inputUrlTextField.stringValue.count > 0 {
  303. inputUrlTextField.stringValue = emailRecord!
  304. }
  305. }
  306. if emailRecord!.count > 0 {
  307. goButton.layer?.backgroundColor = KMAppearance.Interactive.m0Color().cgColor
  308. goButton.setTitleColor(KMAppearance.Layout.w0Color())
  309. } else {
  310. goButton.layer?.backgroundColor = KMAppearance.Interactive.m0Color().withAlphaComponent(0.4).cgColor
  311. goButton.setTitleColor(KMAppearance.Layout.w0Color().withAlphaComponent(0.4))
  312. }
  313. }
  314. func isValidateEmail(_ email: String) -> Bool {
  315. let emailRegex = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}"
  316. let emailTest = NSPredicate(format: "SELF MATCHES %@", emailRegex)
  317. return emailTest.evaluate(with: email)
  318. }
  319. func judgeWebURL(_ urlString: String) -> String {
  320. var modifiedURLString = urlString
  321. if !modifiedURLString.hasPrefix("http://") && !modifiedURLString.hasPrefix("https://") {
  322. modifiedURLString = "https://" + modifiedURLString
  323. }
  324. if modifiedURLString == "https://" {
  325. modifiedURLString = ""
  326. }
  327. return modifiedURLString
  328. }
  329. func judgeEmailURL(_ urlString: String) -> String {
  330. var modifiedURLString = urlString
  331. if !modifiedURLString.hasPrefix("mailto:") {
  332. modifiedURLString = "mailto:" + modifiedURLString
  333. }
  334. if modifiedURLString == "mailto:" {
  335. modifiedURLString = ""
  336. }
  337. return modifiedURLString
  338. }
  339. func annotationLinkSelectBox(_ box: KMBox) {
  340. if box.isEqual(linkPageBox) {
  341. linkPageBox.fillColor = KMAppearance.Status.selColor()
  342. linkUrlBox.fillColor = NSColor.clear
  343. linkEmailBox.fillColor = NSColor.clear
  344. linkPageImageView.image = NSImage(named: "KMImageNameUXIconPropertybarLinkPageSel")
  345. linkUrlImageView.image = NSImage(named: "KMImageNameUXIconPropertybarLinkUrl")
  346. linkEmailImageView.image = NSImage(named: "KMImageNameUXIconPropertybarLinkEmail")
  347. linkPageLabel.textColor = KMAppearance.Layout.h0Color()
  348. linkUrlLabel.textColor = KMAppearance.Layout.h1Color()
  349. linkEmailLabel.textColor = KMAppearance.Layout.h1Color()
  350. if let dexPage = Int(pageRecord!), pageRecord!.count >= 1 {
  351. if dexPage < 1 || dexPage > self.pdfDocument!.pageCount {
  352. errorLabel.isHidden = false
  353. } else {
  354. errorLabel.isHidden = true
  355. }
  356. }
  357. } else if box.isEqual(linkUrlBox) {
  358. linkUrlBox.fillColor = KMAppearance.Status.selColor()
  359. linkPageBox.fillColor = NSColor.clear
  360. linkEmailBox.fillColor = NSColor.clear
  361. linkPageImageView.image = NSImage(named: "KMImageNameUXIconPropertybarLinkPage")
  362. linkUrlImageView.image = NSImage(named: "KMImageNameUXIconPropertybarLinkUrlSel")
  363. linkEmailImageView.image = NSImage(named: "KMImageNameUXIconPropertybarLinkEmail")
  364. linkUrlLabel.textColor = KMAppearance.Layout.h0Color()
  365. linkPageLabel.textColor = KMAppearance.Layout.h1Color()
  366. linkEmailLabel.textColor = KMAppearance.Layout.h1Color()
  367. errorLabel.isHidden = true
  368. } else if box.isEqual(linkEmailBox) {
  369. linkEmailBox.fillColor = KMAppearance.Status.selColor()
  370. linkPageBox.fillColor = NSColor.clear
  371. linkUrlBox.fillColor = NSColor.clear
  372. linkPageImageView.image = NSImage(named: "KMImageNameUXIconPropertybarLinkPage")
  373. linkUrlImageView.image = NSImage(named: "KMImageNameUXIconPropertybarLinkUrl")
  374. linkEmailImageView.image = NSImage(named: "KMImageNameUXIconPropertybarLinkEmailSel")
  375. linkEmailLabel.textColor = KMAppearance.Layout.h0Color()
  376. linkPageLabel.textColor = KMAppearance.Layout.h1Color()
  377. linkUrlLabel.textColor = KMAppearance.Layout.h1Color()
  378. errorLabel.isHidden = true
  379. }
  380. }
  381. // MARK: Public Method
  382. // MARK: Action
  383. @IBAction func goButtonAction(_ sender: Any) {
  384. if linkType == .page {
  385. let pageFloat = Float(inputPageTextField.stringValue)
  386. if pageFloat! < 1 || UInt(pageFloat!) > self.pdfDocument!.pageCount {
  387. return
  388. }
  389. } else if linkType == .url {
  390. if urlRecord!.count <= 0 {
  391. return
  392. }
  393. } else if linkType == .email {
  394. if emailRecord!.count <= 0 {
  395. return
  396. }
  397. }
  398. goButton.layer?.backgroundColor = KMAppearance.Interactive.m0Color().cgColor
  399. Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(timered(_:)), userInfo: nil, repeats: false)
  400. switch linkType {
  401. case .page:
  402. guard let activeAnnotation = pdfview?.activeAnnotation as? CPDFLinkAnnotation else { return }
  403. activeAnnotation.setURL(nil)
  404. let dexPage: Int
  405. if isGo {
  406. isGo = false
  407. dexPage = Int(inputPageTextField.stringValue) ?? 0
  408. goButton.title = NSLocalizedString("Go Back", comment: "Tool tip message")
  409. } else {
  410. isGo = true
  411. dexPage = Int(startPage!) ?? 0
  412. goButton.title = NSLocalizedString("Go", tableName: "MainMenu", comment: "")
  413. }
  414. goButton.setTitleColor(KMAppearance.Layout.w0Color())
  415. guard dexPage >= 1 && dexPage <= pdfDocument!.pageCount else {
  416. let alert = NSAlert()
  417. alert.alertStyle = .critical
  418. alert.messageText = NSLocalizedString("Invalid page range or the page number is out of range. Please try again.", comment: "")
  419. alert.runModal()
  420. return
  421. }
  422. let goPage = Int(inputPageTextField.stringValue) ?? 0
  423. if let page = pdfDocument!.page(at: UInt(goPage - 1)) {
  424. let bounds = page.bounds(for: .cropBox)
  425. let destination = CPDFDestination(page: page, at: NSPoint(x: 0, y: bounds.size.height))
  426. (pdfview?.activeAnnotation as! CPDFLinkAnnotation as CPDFLinkAnnotation).setDestination(destination)
  427. pdfview!.needsDisplay = true
  428. }
  429. if let page = pdfDocument!.page(at: UInt(dexPage - 1)) {
  430. let bounds = page.bounds(for: .cropBox)
  431. let dest = CPDFDestination(page: page, at: NSPoint(x: 0, y: bounds.size.height))
  432. pdfview!.go(to: dest)
  433. }
  434. case .url:
  435. guard let activeAnnotation = pdfview?.activeAnnotation as? CPDFLinkAnnotation else { return }
  436. activeAnnotation.setDestination(nil)
  437. let linkUrlPath = judgeWebURL(inputUrlTextField.stringValue)
  438. activeAnnotation.setURL(linkUrlPath)
  439. pdfview!.needsDisplay = true
  440. if let url = (pdfview?.activeAnnotation as! CPDFLinkAnnotation).url() {
  441. NSWorkspace.shared.open(URL(string: url)!)
  442. }
  443. case .email:
  444. guard let activeAnnotation = pdfview?.activeAnnotation as? CPDFLinkAnnotation else { return }
  445. activeAnnotation.setDestination(nil)
  446. if !isValidateEmail(inputUrlTextField.stringValue) {
  447. let alert = NSAlert()
  448. alert.alertStyle = .critical
  449. alert.messageText = NSLocalizedString("Invalid Email. Please try again.", comment: "")
  450. alert.runModal()
  451. return
  452. }
  453. let linkUrlPath = judgeEmailURL(inputUrlTextField.stringValue)
  454. activeAnnotation.setURL(linkUrlPath)
  455. pdfview!.needsDisplay = true
  456. if let url = (pdfview?.activeAnnotation as! CPDFLinkAnnotation).url() {
  457. NSWorkspace.shared.open(URL(string: url)!)
  458. }
  459. default:
  460. break
  461. }
  462. }
  463. @objc func timered(_ timer: Timer) {
  464. goButton.layer!.backgroundColor = KMAppearance.Interactive.m0Color().cgColor
  465. goButton.setTitleColor(KMAppearance.Layout.w0Color())
  466. }
  467. // MARK: NSTextFieldDelegate Methods
  468. @objc func controlTextDidChange(_ notification: Notification) {
  469. guard let textField = notification.object as? NSTextField else { return }
  470. if mouseDownBox!.isEqual(linkPageBox) {
  471. pageRecord = textField.stringValue
  472. } else if mouseDownBox!.isEqual(linkUrlBox) {
  473. urlRecord = textField.stringValue
  474. } else if mouseDownBox!.isEqual(linkEmailBox) {
  475. emailRecord = textField.stringValue
  476. }
  477. if linkType == KMAnnotationLinkType.page {
  478. (pdfview?.activeAnnotation as? CPDFLinkAnnotation)?.setURL(nil)
  479. let dexPage = Int(inputPageTextField.stringValue) ?? 0
  480. if (dexPage < 1 || dexPage > pdfDocument!.pageCount) && pageRecord!.count > 0 {
  481. goButton.layer!.backgroundColor = KMAppearance.Interactive.m0Color().withAlphaComponent(0.4).cgColor
  482. goButton.setTitleColor(KMAppearance.Layout.w0Color().withAlphaComponent(0.4))
  483. errorLabel.isHidden = false
  484. return
  485. } else if pageRecord!.count > 0 {
  486. goButton.layer!.backgroundColor = KMAppearance.Interactive.m0Color().cgColor
  487. goButton.setTitleColor(KMAppearance.Layout.w0Color())
  488. errorLabel.isHidden = true
  489. } else {
  490. goButton.layer!.backgroundColor = KMAppearance.Interactive.m0Color().withAlphaComponent(0.4).cgColor
  491. goButton.setTitleColor(KMAppearance.Layout.w0Color().withAlphaComponent(0.4))
  492. }
  493. let pageIndex = UInt(max(dexPage-1, 0))
  494. let page = pdfDocument!.page(at: pageIndex)
  495. let bounds = page?.bounds(for: .cropBox) ?? .zero
  496. let destination = CPDFDestination(page: page, at: NSMakePoint(0, bounds.size.height))
  497. (pdfview?.activeAnnotation as? CPDFLinkAnnotation)?.setDestination(destination)
  498. pdfview?.setNeedsDisplay(pdfview!.visibleRect)
  499. } else if linkType == KMAnnotationLinkType.url {
  500. (pdfview?.activeAnnotation as? CPDFLinkAnnotation)?.setDestination(nil)
  501. let linkUrlPath: String = judgeWebURL(urlRecord!)
  502. if linkUrlPath == "" {
  503. (pdfview?.activeAnnotation as? CPDFLinkAnnotation)?.setURL(nil)
  504. } else {
  505. (pdfview?.activeAnnotation as? CPDFLinkAnnotation)?.setURL(linkUrlPath)
  506. }
  507. if urlRecord!.count > 0 {
  508. goButton.layer!.backgroundColor = KMAppearance.Interactive.m0Color().cgColor
  509. goButton.setTitleColor(KMAppearance.Layout.w0Color())
  510. } else {
  511. goButton.layer!.backgroundColor = KMAppearance.Interactive.m0Color().withAlphaComponent(0.4).cgColor
  512. goButton.setTitleColor(KMAppearance.Layout.w0Color().withAlphaComponent(0.4))
  513. }
  514. pdfview!.setNeedsDisplay(pdfview!.visibleRect)
  515. } else if linkType == KMAnnotationLinkType.email {
  516. (pdfview?.activeAnnotation as? CPDFLinkAnnotation)?.setDestination(nil)
  517. let linkUrlPath: String = judgeEmailURL(emailRecord!)
  518. if linkUrlPath == "" {
  519. (pdfview?.activeAnnotation as? CPDFLinkAnnotation)?.setURL(nil)
  520. } else {
  521. (pdfview?.activeAnnotation as? CPDFLinkAnnotation)?.setURL(linkUrlPath)
  522. }
  523. if emailRecord!.count > 0 {
  524. goButton.layer!.backgroundColor = KMAppearance.Interactive.m0Color().cgColor
  525. goButton.setTitleColor(KMAppearance.Layout.w0Color())
  526. } else {
  527. goButton.layer!.backgroundColor = KMAppearance.Interactive.m0Color().withAlphaComponent(0.4).cgColor
  528. goButton.setTitleColor(KMAppearance.Layout.w0Color().withAlphaComponent(0.4))
  529. }
  530. pdfview?.setNeedsDisplay(pdfview!.visibleRect)
  531. }
  532. }
  533. }